您的位置:首页 > 运维架构

ffmpeg解码+opencv显示

2015-07-09 12:51 363 查看


ffmpeg 解码h264,并OPENCV显示

(2013-12-18 10:31:01)


转载▼

#include "stdafx.h"

#pragma comment(lib, "avcodec.lib ")
#pragma comment(lib, "avformat.lib ")
#pragma comment(lib, "avutil.lib ")
#pragma comment(lib, "avdevice.lib ")
#pragma comment(lib, "avfilter.lib ")
#pragma comment(lib, "postproc.lib ")
#pragma comment(lib, "swresample.lib")
#pragma comment(lib, "swscale.lib ")
#pragma comment(lib, "libmysql.lib ")
#pragma comment(lib, "opencv_highgui243d.lib")
#pragma comment(lib, "opencv_core243d.lib ")

int _tmain(int argc, _TCHAR* argv[])
{
***Frame *pFrame = NULL,*pFrameRGB = NULL;
***FormatContext *pFormatCtx = NULL;
int i=0, videoindex=0;
***CodecContext *pCodecCtx = NULL;
***Codec *pCodec = NULL;
char filepath[]="opencv.h264";
IplImage* pCVFrame = NULL;
int nFrame = 0;
uint8_t *out_bufferRGB;
int ret, got_picture;
static struct SwsContext *img_convert_ctx = NULL;
int y_size = 0;
***Packet *packet = NULL;

//ffmpeg注册复用器,编码器等的函数av_register_all()。
//该函数在所有基于ffmpeg的应用程序中几乎都是第一个被调用的。只有调用了该函数,才能使用复用器,编码器等。
av_register_all();

//需要播放网络视频
avformat_network_init();

pFormatCtx = avformat_alloc_context();

//打开视频文件
if(avformat_open_input(&pFormatCtx,filepath,NULL,NULL)!=0)
{
printf("无法打开文件\n");
return -1;
}

//查找文件的流信息
if(av_find_stream_info(pFormatCtx)<0)
{
printf("Couldn't find stream information.\n");
return -1;
}

cvNamedWindow("decode");

//遍历文件的各个流,找到第一个视频流,并记录该流的编码信息
videoindex=-1;
for(i=0; inb_streams; i++)
{
if(pFormatCtx->streams[i]->codec->codec_type==***MEDIA_TYPE_VIDEO)
{
videoindex=i;
break;
}
}
if(videoindex==-1)
{
printf("Didn't find a video stream.\n");
return -1;
}
pCodecCtx=pFormatCtx->streams[videoindex]->codec;

//在库里面查找支持该格式的解码器
pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
if(pCodec==NULL)
{
printf("Codec not found.\n");
return -1;
}

//打开解码器
if(avcodec_open(pCodecCtx, pCodec)<0)
{
printf("Could not open codec.\n");
return -1;
}

//分配一个帧指针,指向解码后的原始帧
pFrame=avcodec_alloc_frame();

//分配一个帧指针,指向存放转换成RGB后的帧
pFrameRGB = avcodec_alloc_frame();

//给pFrameRGB帧加上分配的内存;
out_bufferRGB=new uint8_t[avpicture_get_size(PIX_FMT_BGR24, pCodecCtx->width, pCodecCtx->height)];
avpicture_fill((***Picture *)pFrameRGB, out_bufferRGB, PIX_FMT_BGR24, pCodecCtx->width, pCodecCtx->height);

y_size = pCodecCtx->width * pCodecCtx->height;

//分配帧内存
packet=(***Packet *)malloc(sizeof(***Packet));
av_new_packet(packet, y_size);

//输出一下信息-----------------------------
printf("文件信息-----------------------------------------\n");
av_dump_format(pFormatCtx,0,filepath,0);//av_dump_format只是个调试函数,输出文件的音、视频流的基本信息了,帧率、分辨率、音频采样等等
printf("-------------------------------------------------\n");

//av_read_frame 读取一个帧(到最后帧则break)
while(av_read_frame(pFormatCtx, packet)>=0)
{
if(packet->stream_index==videoindex)
{
//解码一个帧
ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet);
if(ret < 0)
{
printf("解码错误\n");
return -1;
}
if(got_picture)
{
printf("帧号: %d \n",nFrame);
nFrame++;

//根据编码信息设置渲染格式
img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, PIX_FMT_BGR24, SWS_BICUBIC, NULL, NULL, NULL);

//----------------------opencv
if (NULL == pCVFrame)
{
pCVFrame=cvCreateImage(cvSize(pCodecCtx->width, pCodecCtx->height),8,3);
}

if(img_convert_ctx != NULL)
{
sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
memcpy(pCVFrame->imageData,out_bufferRGB,pCodecCtx->width*pCodecCtx->height*24/8);
pCVFrame->widthStep=pCodecCtx->width*3; //4096
pCVFrame->origin=0;

cvShowImage("decode",pCVFrame);//显示
//cvReleaseImage( &pCVFrame ); //释放图像

//如果不设置由于这是个循环,会导致看不到显示出来的图像
if( cvWaitKey(20) >= 0 )
break;
}

}
}
}


ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet);
if(got_picture)
{
printf("最后一帧 %d\n", nFrame);
nFrame++;

//根据编码信息设置渲染格式
img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL);

//----------------------opencv
if (NULL == pCVFrame)
{
pCVFrame=cvCreateImage(cvSize(pCodecCtx->width, pCodecCtx->height),8,3);
}

if(img_convert_ctx != NULL)
{
sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
memcpy(pCVFrame->imageData,out_bufferRGB,pCodecCtx->width*pCodecCtx->height*24/8);
pCVFrame->widthStep=pCodecCtx->width*3; //4096
pCVFrame->origin=0;

cvShowImage("decode",pCVFrame);//显示
cvWaitKey(20);
}
}

//释放本次读取的帧内存
av_free_packet(packet);

cvReleaseImage( &pCVFrame ); //释放图像
delete[] out_bufferRGB;
av_free(pFrameRGB);
avcodec_close(pCodecCtx);
avformat_close_input(&pFormatCtx);

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: