关闭

ffmpeg解码+opencv显示

401人阅读 评论(0) 收藏 举报
分类:



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[])
{
AVFrame *pFrame = NULL,*pFrameRGB = NULL;
AVFormatContext *pFormatCtx  = NULL;
int i=0, videoindex=0;
AVCodecContext *pCodecCtx   = NULL;
AVCodec *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;
AVPacket *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==AVMEDIA_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((AVPicture *)pFrameRGB, out_bufferRGB, PIX_FMT_BGR24, pCodecCtx->width, pCodecCtx->height);

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

//分配帧内存
packet=(AVPacket *)malloc(sizeof(AVPacket));
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;
}




0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:244291次
    • 积分:5451
    • 等级:
    • 排名:第5136名
    • 原创:238篇
    • 转载:337篇
    • 译文:19篇
    • 评论:10条
    在线LaTeX
    最新评论