ffmpeg视频解码完整教程

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

FFmpeg简明教程本教程只针对windows64/32+vs2010环境配置第一步:配环境1.打开ffmpeg官网中编译好的windows版本位windows系统和32位系统各有三个版本分别为Static版本,Share版本,Dev版本;在这里建议无论是32位还是64位系统都直接配置32位的ffmpeg版本,除非你vs2010选择的是x64编译器。将32位版本Share版本和Dev下载,解压。在Dev里面主要是一些头文件和lib,在share版本里主要是dll文件。2.打开vs2010,新建一个win32控制台程序。选择项目-》属性-》c++目录,分别在包含目录和库目录中打开dev版本中的include和lib(指的是你解压dev保存的位置,在里面找到include和lib)3项目-》属性-》链接器-》输入-》依赖项中填写avcodec.libavformat.libavutil.libavdevice.libavfilter.libpostproc.libswresample.libswscale.lib保存即可。第二步:视频解码,此处是一个完整的视频解码工程,从解码到存储,在vs2010上可以运行,如果编译不成功,可考虑是否是环境配错了。1.定义一些解码变量unsignedinti=0,videoStream=-1;AVCodecContext*pCodecCtx;AVFormatContext*pFormatCtx;AVCodec*pCodec;AVFrame*pFrame,*pFrameRGB;structSwsContext*pSwsCtx;//打开视频的路径,可以根据自己的要求修改constchar*filename=E:/视频浓缩测试视频/421-20141018100000-20141018105959-2956390.ts;AVPacketpacket;intframeFinished;intPictureSize;uint8_t*buf;2.注册解码器//注册编解码器av_register_all();avformat_network_init();//这里是分配一块内存,保存视频的属性信息pFormatCtx=avformat_alloc_context();3.打开视频文件//打开视频文件if(avformat_open_input(&pFormatCtx,filename,NULL,NULL)!=0){printf(avopeninputfilefailed!\n);exit(1);}4.获取流信息//获取流信息if(avformat_find_stream_info(pFormatCtx,NULL)0){printf(avfindstreaminfofailed!\n);exit(1);}5.获取流信息并找到对应解码器//获取视频流for(i=0;ipFormatCtx-nb_streams;i++)if(pFormatCtx-streams[i]-codec-codec_type==AVMEDIA_TYPE_VIDEO){videoStream=i;break;}if(videoStream==-1){printf(findvideostreamfailed!\n);exit(1);}pCodecCtx=pFormatCtx-streams[videoStream]-codec;pCodec=avcodec_find_decoder(pCodecCtx-codec_id);if(pCodec==NULL){printf(avcodefinddecoderfailed!\n);exit(1);}6打开解码器//打开解码器if(avcodec_open2(pCodecCtx,pCodec,NULL)0){printf(avcodeopenfailed!\n);exit(1);}7.为一帧图像分配内存//为每帧图像分配内存pFrame=avcodec_alloc_frame();pFrameRGB=avcodec_alloc_frame();if((pFrame==NULL)||(pFrameRGB==NULL)){printf(avcodecallocframefailed!\n);exit(1);}8.获得帧图片大小//获得帧图大小PictureSize=avpicture_get_size(PIX_FMT_BGR24,pCodecCtx-width,pCodecCtx-height);buf=(uint8_t*)av_malloc(PictureSize);if(buf==NULL){printf(avmallocfailed!\n);exit(1);}avpicture_fill((AVPicture*)pFrameRGB,buf,PIX_FMT_BGR24,pCodecCtx-width,pCodecCtx-height);9.转换图像上下文//设置图像转换上下文pSwsCtx=sws_getContext(pCodecCtx-width,pCodecCtx-height,pCodecCtx-pix_fmt,pCodecCtx-width,pCodecCtx-height,PIX_FMT_BGR24,SWS_BICUBIC,NULL,NULL,NULL);10.真正解码开始,解码图像并保存i=0;while(av_read_frame(pFormatCtx,&packet)=0){if(packet.stream_index==videoStream){//真正解码avcodec_decode_video2(pCodecCtx,pFrame,&frameFinished,&packet);if(frameFinished){//反转图像,否则生成的图像是上下调到的pFrame-data[0]+=pFrame-linesize[0]*(pCodecCtx-height-1);pFrame-linesize[0]*=-1;pFrame-data[1]+=pFrame-linesize[1]*(pCodecCtx-height/2-1);pFrame-linesize[1]*=-1;pFrame-data[2]+=pFrame-linesize[2]*(pCodecCtx-height/2-1);pFrame-linesize[2]*=-1;//转换图像格式,将解压出来的YUV420P的图像转换为BRG24的图像sws_scale(pSwsCtx,pFrame-data,pFrame-linesize,0,pCodecCtx-height,pFrameRGB-data,pFrameRGB-linesize);//保存为bmp图SaveAsBMP(pFrameRGB,pCodecCtx-width,pCodecCtx-height,i,24);i++;}av_free_packet(&packet);}}11.保存bmp函数定义//定义BMP文件头#ifndef_WINGDI_#define_WINGDI_typedefstructtagBITMAPFILEHEADER{WORDbfType;DWORDbfSize;WORDbfReserved1;WORDbfReserved2;DWORDbfOffBits;}BITMAPFILEHEADER,FAR*LPBITMAPFILEHEADER,*PBITMAPFILEHEADER;typedefstructtagBITMAPINFOHEADER{DWORDbiSize;LONGbiWidth;LONGbiHeight;WORDbiPlanes;WORDbiBitCount;DWORDbiCompression;DWORDbiSizeImage;LONGbiXPelsPerMeter;LONGbiYPelsPerMeter;DWORDbiClrUsed;DWORDbiClrImportant;}BITMAPINFOHEADER,FAR*LPBITMAPINFOHEADER,*PBITMAPINFOHEADER;#endif//保存BMP文件的函数voidSaveAsBMP(AVFrame*pFrameRGB,intwidth,intheight,intindex,intbpp){charbuf[5]={0};//bmp头BITMAPFILEHEADERbmpheader;BITMAPINFOHEADERbmpinfo;FILE*fp;char*filename=newchar[255];//文件存放路径,根据自己的修改sprintf_s(filename,255,%s_%d.bmp,D:/Debug/filename,index);if((fp=fopen(filename,wb+))==NULL){printf(openfilefailed!\n);return;}bmpheader.bfType=0x4d42;bmpheader.bfReserved1=0;bmpheader.bfReserved2=0;bmpheader.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);bmpheader.bfSize=bmpheader.bfOffBits+width*height*bpp/8;bmpinfo.biSize=sizeof(BITMAPINFOHEADER);bmpinfo.biWidth=width;bmpinfo.biHeight=height;bmpinfo.biPlanes=1;bmpinfo.biBitCount=bpp;bmpinfo.biCompression=BI_RGB;bmpinfo.biSizeImage=(width*bpp+31)/32*4*height;bmpinfo.biXPelsPerMeter=100;bmpinfo.biYPelsPerMeter=100;bmpinfo.biClrUsed=0;bmpinfo.biClrImportant=0;fwrite(&bmpheader,sizeof(bmpheader),1,fp);fwrite(&bmpinfo,sizeof(bmpinfo),1,fp);fwrite(pFrameRGB-data[0],width*height*bpp/8,1,fp);fclose(fp);}12.释放sws_freeContext(pSwsCtx);av_free(pFrame);av_free(pFrameRGB);avcodec_close(pCodecCtx);avformat_close_input(&pFormatCtx);return0;}Ffmpeg视频解码是一个比较固定化的东西,可以说只要按照上面步骤走下来,就可以解任何一种只要是ffmpeg支持的格式。附完整代码://ffmpeg1.0shipinjiemabmp.cpp:定义控制台应用程序的入口点。//#includestdafx.h#includewindows.h#includestdio.h#includestdlib.h#includestring.h#pragmaonceexternC{#includelibavcodec/avcodec.h#includelibavdevice/avdevice.h#includelibavfilter/avfilter.h#includelibswscale/swscale.h#includelibswresample/swresample.h#includelibavformat/avforma

1 / 13
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功