ffmpeg7将h264编码的视频流保存为BMP或者JPEG图片.docx
- 文档编号:6208752
- 上传时间:2023-01-04
- 格式:DOCX
- 页数:4
- 大小:17.04KB
ffmpeg7将h264编码的视频流保存为BMP或者JPEG图片.docx
《ffmpeg7将h264编码的视频流保存为BMP或者JPEG图片.docx》由会员分享,可在线阅读,更多相关《ffmpeg7将h264编码的视频流保存为BMP或者JPEG图片.docx(4页珍藏版)》请在冰豆网上搜索。
ffmpeg7将h264编码的视频流保存为BMP或者JPEG图片
ffmpeg(7):
将h264编码的视频流保存为BMP或者JPEG图片
ffmpeg(7):
将h264编码的视频流保存为BMP或者JPEG图片2015-07-0316:
09
4603人阅读
评论(8)
收藏
举报分类:
音视频(20)ffmpeg(12)版权声明:
本文为博主原创文章,未经博主允许不得转载。
目录(?
)[+]
一般我们知道播放视频流的时候是有截图功能的。
所以我想是否可以将视频流保存为BMP或者JPEG参考:
1.最简单的基于FFMPEG的图像编码器(YUV编码为JPEG)
http:
//blog.csdn.NET/leixiaohua1020/article/details/253461472.视频帧保存为BMP
[cpp]viewplaincopyprint?
#define__STDC_CONSTANT_MACROS#ifdef_WIN32//Windowsextern"C"{#include"libavcodec/avcodec.h"#include"libavformat/avformat.h"#include"libswscale/swscale.h"#include"SDL.h"};#else//Linux...#ifdef__cplusplusextern"C"{#endif#include<libavcodec/avcodec.h>#include<libavformat/avformat.h>#include<libswscale/swscale.h>#include<SDL2/SDL.h>#ifdef__cplusplus};#endif#endif[cpp]viewplaincopyprint?
[cpp]viewplaincopyprint?
//保存BMP文件的函数voidSaveAsBMP(AVFrame*pFrameRGB,intwidth,intheight,intindex,intbpp){charbuf[5]={0};BITMAPFILEHEADERbmpheader;BITMAPINFOHEADERbmpinfo;FILE*fp;char*filename=newchar[255];//文件存放路径,根据自己的修改sprintf_s(filename,255,"%s%d.bmp","E:
/temp/",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);}[cpp]viewplaincopyprint?
DWORDWork_Save2BMP(){intvideoStream=-1;AVCodecContext*pCodecCtx;AVFormatContext*pFormatCtx;AVCodec*pCodec;AVFrame*pFrame,*pFrameRGB;structSwsContext*pSwsCtx;constchar*filename="bigbuckbunny_480x272.h264";AVPacketpacket;intframeFinished;intPictureSize;uint8_t*outBuff;//注册编解码器av_register_all();//初始化网络模块avformat_network_init();//分配AVFormatContextpFormatCtx=avformat_alloc_context();//打开视频文件if(avformat_open_input(&pFormatCtx,filename,NULL,NULL)!
=0){printf("avopeninputfilefailed!
\n");exit
(1);}//获取流信息if(avformat_find_stream_info(pFormatCtx,NULL)<0){printf("avfindstreaminfofailed!
\n");exit
(1);}//获取视频流for(inti=0;i<pFormatCtx->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);}//打开解码器if(avcodec_open2(pCodecCtx,pCodec,NULL)<0){printf("avcodeopenfailed!
\n");exit
(1);}//为每帧图像分配内存pFrame=avcodec_alloc_frame();pFrameRGB=avcodec_alloc_frame();if((pFrame==NULL)||(pFrameRGB==NULL)){printf("avcodecallocframefailed!
\n");exit
(1);}//确定图片尺寸PictureSize=avpicture_get_size(PIX_FMT_BGR24,pCodecCtx->width,pCodecCtx->height);outBuff=(uint8_t*)av_malloc(PictureSize);if(outBuff==NULL){printf("avmallocfailed!
\n");exit
(1);}avpicture_fill((AVPicture*)pFrameRGB,outBuff,PIX_FMT_BGR24,pCodecCtx->width,pCodecCtx->height);//设置图像转换上下文pSwsCtx=sws_getContext(pCodecCtx->width,pCodecCtx->height,pCodecCtx->pix_fmt,pCodecCtx->width,pCodecCtx->height,PIX_FMT_BGR24,SWS_BICUBIC,NULL,NULL,NULL);inti=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);SaveAsBMP(pFrameRGB,pCodecCtx->width,pCodecCtx->height,i++,24);}}else{inta=2;intb=a;}av_free_packet(&packet);}sws_freeContext(pSwsCtx);av_free(pFrame);av_free(pFrameRGB);avcodec_close(pCodecCtx);avformat_close_input(&pFormatCtx);return0;}其实总结起来就几点,
打开视频文件,将里面的每一帧取出来,并将其转换为RGB格式。
H264---(解码)-->YUV420---(转码).-->RGB---(保存)--->BMP视频帧保存为JPEG
保存为JPEG和BMP有点类似,但是也有区别,具体流程是:
H264---(解码)-->YUV420---(转码).---(保存)--->JPEG[cpp]viewplaincopyprint?
#define__STDC_CONSTANT_MACROS#ifdef_WIN32//Windowsextern"C"{#include"libavcodec/avcodec.h"#include"libavformat/avformat.h"#include"libswscale/swscale.h"#include"SDL.h"};#else//Linux...#ifdef__cplusplusextern"C"{#endif#include<libavcodec/avcodec.h>#include<libavformat/avformat.h>#include<libswscale/swscale.h>#include<SDL2/SDL.h>#ifdef__cplusplus};#endif#endif[cpp]viewplaincopyprint?
/***将AVFrame(YUV420格式)保存为JPEG格式的图片**@paramwidthYUV420的宽*@paramheightYUV42的高**/intMyWriteJPEG(AVFrame*pFrame,intwidth,intheight,intiIndex){//输出文件路径charout_file[MAX_PATH]={0};sprintf_s(out_file,sizeof(out_file),"%s%d.jpg","E:
/temp/",iIndex);//分配AVFormatContext对象AVFormatContext*pFormatCtx=avformat_alloc_context();//设置输出文件格式pFormatCtx->oformat=av_guess_format("mjpeg",NULL,NULL);//创建并初始化一个和该url相关的AVIOContextif(avio_open(&pFormatCtx->pb,out_file,AVIO_FLAG_READ_WRITE)<0){printf("Couldn'topenoutputfile.");return-1;}//构建一个新streamAVStream*pAVStream=avformat_new_stream(pFormatCtx,0);if(pAVStream==NULL){return-1;}//设置该stream的信息AVCodecContext*pCodecCtx=pAVStream->codec;pCodecCtx->codec_id=pFormatCtx->oformat->video_codec;pCodecCtx->codec_type=AVMEDIA_TYPE_VIDEO;pCodecCtx->pix_fmt=PIX_FMT_YUVJ420P;pCodecCtx->width=width;pCodecCtx->height=height;pCodecCtx->time_base.num=1;pCodecCtx->time_base.den=25;//BeginOutputsomeinformationav_dump_format(pFormatCtx,0,out_file,1);//EndOutputsomeinformation//查找解码器AVCodec*pCodec=avcodec_find_encoder(pCodecCtx->codec_id);if(!
pCodec){printf("Codecnotfound.");return-1;}//设置pCodecCtx的解码器为pCodecif(avcodec_open2(pCodecCtx,pCodec,NULL)<0){printf("Couldnotopencodec.");return-1;}//WriteHeaderavformat_write_header(pFormatCtx,NULL);inty_size=pCodecCtx->width*pCodecCtx->height;//Encode//给AVPacket分配足够大的空间AVPacketpkt;av_new_packet(&pkt,y_size*3);//intgot_picture=0;intret=avcodec_encode_video2(pCodecCtx,&pkt,pFrame,&got_picture);if(ret<0){printf("EncodeError.\n");return-1;}if(got_picture==1){//pkt.stream_index=pAVStream->index;ret=av_write_frame(pFormatCtx,&pkt);}av_free_packet(&pkt);//WriteTrailerav_write_trailer(pFormatCtx);printf("EncodeSuccessful.\n");if(pAVStream){avcodec_close(pAVStream->codec);}avio_close(pFormatCtx->pb);avformat_free_context(pFormatCtx);return0;}[cpp]viewplaincopyprint?
DWORDWork_Save2JPG(){intvideoStream=-1;AVCodecContext*pCodecCtx;AVFormatContext*pFormatCtx;AVCodec*pCodec;AVFrame*pFrame,*pFrameRGB;structSwsContext*pSwsCtx;constchar*filename="bigbuckbunny_480x272.h264";AVPacketpacket;intframeFinished;intPictureSize;uint8_t*outBuff;//注册编解码器av_register_all();//初始化网络模块avformat_network_init();//分配AVFormatContextpFormatCtx=avformat_alloc_context();//打开视频文件if(avformat_open_input(&pFormatCtx,filename,NULL,NULL)!
=0){printf("avopeninputfilefailed!
\n");exit
(1);}//获取流信息if(avformat_find_stream_info(pFormatCtx,NULL)<0){printf("avfindstreaminfofailed!
\n");exit
(1);}//获取视频流for(inti=0;i<pFormatCtx->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);}//打开解码器if(avcodec_open2(pCodecCtx,pCodec,NULL)<0){printf("avcodeopenfailed!
\n");exit
(1);}//为每帧图像分配内存pFrame=avcodec_alloc_frame();pFrameRGB=avcodec_alloc_frame();if((pFrame==NULL)||(pFrameRGB==NULL)){printf("avcodecallocframefailed!
\n");exit
(1);}//确定图片尺寸PictureSize=avpicture_get_size(PIX_FMT_YUVJ420P,pCodecCtx->width,pCodecCtx->height);outBuff=(uint8_t*)av_malloc(PictureSize);if(outBuff==NULL){printf("avmallocfailed!
\n");exit
(1);}avpicture_fill((AVPicture*)pFrameRGB,outBuff,PIX_FMT_YUVJ420P,pCodecCtx->width,pCodecCtx->height);//设置图像转换上下文pSwsCtx=sws_getContext(pCodecCtx->width,pCodecCtx->height,pCodecCtx->pix_fmt,pCodecCtx->width,pCodecCtx->height,PIX_FMT_YUVJ420P,SWS_BICUBIC,NULL,NULL,NULL);inti=0;while(av_read_frame(pFormatCtx,&packet)>=0){if(packet.stream_index==videoStream){avcodec_decode_video2(pCodecCtx,pFrame,&frameFinished,&packet);if(frameFinished){//保存为jpeg时不需要反转图像staticboolb1=true;if(b1){MyWriteJPEG(pFrame,pCodecCtx->width,pCodecCtx-&
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- ffmpeg7 h264 编码 视频 保存 BMP 或者 JPEG 图片