ffmpeg7将h264编码的视频流保存为BMP或者JPEG图片Word下载.docx
- 文档编号:19213548
- 上传时间:2023-01-04
- 格式:DOCX
- 页数:4
- 大小:17.04KB
ffmpeg7将h264编码的视频流保存为BMP或者JPEG图片Word下载.docx
《ffmpeg7将h264编码的视频流保存为BMP或者JPEG图片Word下载.docx》由会员分享,可在线阅读,更多相关《ffmpeg7将h264编码的视频流保存为BMP或者JPEG图片Word下载.docx(4页珍藏版)》请在冰豆网上搜索。
libavformat/avformat.h"
libswscale/swscale.h"
SDL.h"
};
#else//Linux...#ifdef__cplusplusextern"
{#endif#include&
lt;
libavcodec/avcodec.h&
gt;
#include&
libavformat/avformat.h&
libswscale/swscale.h&
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(&
amp;
bmpheader,sizeof(bmpheader),1,fp);
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!
exit
(1);
}//获取流信息if(avformat_find_stream_info(pFormatCtx,NULL)&
0){printf("
avfindstreaminfofailed!
}//获取视频流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!
}//寻找解码器pCodecCtx=pFormatCtx-&
streams[videoStream]-&
codec;
pCodec=avcodec_find_decoder(pCodecCtx-&
codec_id);
if(pCodec==NULL){printf("
avcodefinddecoderfailed!
}//打开解码器if(avcodec_open2(pCodecCtx,pCodec,NULL)&
avcodeopenfailed!
}//为每帧图像分配内存pFrame=avcodec_alloc_frame();
pFrameRGB=avcodec_alloc_frame();
if((pFrame==NULL)||(pFrameRGB==NULL)){printf("
avcodecallocframefailed!
}//确定图片尺寸PictureSize=avpicture_get_size(PIX_FMT_BGR24,pCodecCtx-&
width,pCodecCtx-&
height);
outBuff=(uint8_t*)av_malloc(PictureSize);
if(outBuff==NULL){printf("
avmallocfailed!
exit
(1);
}avpicture_fill((AVPicture*)pFrameRGB,outBuff,PIX_FMT_BGR24,pCodecCtx-&
//设置图像转换上下文pSwsCtx=sws_getContext(pCodecCtx-&
height,pCodecCtx-&
pix_fmt,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;
data[1]+=pFrame-&
linesize[1]*(pCodecCtx-&
height/2-1);
linesize[1]*=-1;
data[2]+=pFrame-&
linesize[2]*(pCodecCtx-&
linesize[2]*=-1;
//转换图像格式,将解压出来的YUV420P的图像转换为BRG24的图像sws_scale(pSwsCtx,pFrame-&
data,pFrame-&
linesize,0,pCodecCtx-&
height,pFrameRGB-&
data,pFrameRGB-&
linesize);
SaveAsBMP(pFrameRGB,pCodecCtx-&
height,i++,24);
}}else{inta=2;
intb=a;
}av_free_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有点类似,但是也有区别,具体流程是:
YUV420---(转码).---(保存)---&
JPEG[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"
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-&
pCodecCtx-&
codec_id=pFormatCtx-&
oformat-&
video_codec;
codec_type=AVMEDIA_TYPE_VIDEO;
pix_fmt=PIX_FMT_YUVJ420P;
width=width;
height=height;
time_base.num=1;
time_base.den=25;
//BeginOutputsomeinformationav_dump_format(pFormatCtx,0,out_file,1);
//EndOutputsomeinformation//查找解码器AVCodec*pCodec=avcodec_find_encoder(pCodecCtx-&
if(!
pCodec){printf("
Codecnotfound."
}//设置pCodecCtx的解码器为pCodecif(avcodec_open2(pCodecCtx,pCodec,NULL)&
0){printf("
Couldnotopencodec."
}//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&
EncodeError.\n"
}if(got_picture==1){//pkt.stream_index=pAVStream-&
index;
ret=av_write_frame(pFormatCtx,&
pkt);
//WriteTrailerav_write_trailer(pFormatCtx);
printf("
EncodeSuccessful.\n"
if(pAVStream){avcodec_close(pAVStream-&
codec);
}avio_close(pFormatCtx-&
pb);
avformat_free_context(pFormatCtx);
DWORDWork_Save2JPG(){intvideoStream=-1;
}//确定图片尺寸PictureSize=avpicture_get_size(PIX_FMT_YUVJ420P,pCodecCtx-&
}avpicture_fill((AVPicture*)pFrameRGB,outBuff,PIX_FMT_YUVJ420P,pCodecCtx-&
height,PIX_FMT_YUVJ420P,SWS_BICUBIC,NULL,NULL,NULL);
if(frameFinished){//保存为jpeg时不需要反转图像staticboolb1=true;
if(b1){MyWriteJPEG(pFrame,pCodecCtx-&
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- ffmpeg7 h264 编码 视频 保存 BMP 或者 JPEG 图片