/******************
程序功能:
将视频帧存储为bmp位图
******************/
#include <Windows.h>
extern "C"
{
#include "libavformat\avformat.h"
#include "libswscale\swscale.h"
};
//将一帧视频画面保存为24位bmp文件
void VideoFrameToBmp(AVFrame *pFrameBGR,int bmp_width,int bmp_height,char* bmp_file)
{
BITMAPFILEHEADER bmpheader;
bmpheader.bfType = 0x4d42;
bmpheader.bfReserved1 = 0;
bmpheader.bfReserved2 = 0;
bmpheader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
bmpheader.bfSize = bmpheader.bfOffBits + bmp_width*bmp_height*24/8;
BITMAPINFOHEADER bmpinfo;
bmpinfo.biSize = sizeof(BITMAPINFOHEADER);
bmpinfo.biWidth = bmp_width;
bmpinfo.biHeight = bmp_height;
bmpinfo.biPlanes = 1;
bmpinfo.biBitCount = 24;
bmpinfo.biCompression = BI_RGB;
bmpinfo.biSizeImage = (bmp_width*24+31)/32*4*bmp_height;
bmpinfo.biXPelsPerMeter = 100;
bmpinfo.biYPelsPerMeter = 100;
bmpinfo.biClrUsed = 0;
bmpinfo.biClrImportant = 0;
FILE* fp = fopen(bmp_file,"wb+");
if(fp == NULL)
return ;
fwrite(&bmpheader,sizeof(bmpheader),1,fp);
fwrite(&bmpinfo,sizeof(bmpinfo),1,fp);
fwrite(pFrameBGR->data[0],bmp_width*bmp_height*24/8,1,fp);
fclose(fp);
}
int main()
{
//注册所有支持的文件格式以及编解码器
av_register_all();
//AVFormatContext保存文件格式信息,如流的个数以及流数据等
AVFormatContext *pFormatContext = NULL;
//打开一个文件,读其文件头,并不会填充流信息
if(avformat_open_input(&pFormatContext,"test.ts",NULL,NULL) != 0)
return -1;
//获取文件流信息,读取AVPacket,并确定文件中所有的流信息,设置pFormatContext->streams指向文件中的流,但此函数并不会改变文件指针,读取的AVPacket会给后面的解码进行处理
if(avformat_find_stream_info(pFormatContext,NULL) < 0)
{
avformat_close_input(&pFormatContext);
return -2;
}
//帮助函数:输出文件信息
av_dump_format(pFormatContext,-1,"test.ts",0);
//现在pFormatContext->streams中已经有所有流了,遍历它找到第一条视频流的索引
int VideoIndex = -1;
for(int i=0;i<pFormatContext->nb_streams;i++)
{
if(pFormatContext->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
{
VideoIndex = i;
break;
}
}
if(VideoIndex == -1)
{
avformat_close_input(&pFormatContext);
return -3;
}
//AVCodecContext保存了相应流的详细编码信息,比如视频的宽、高,编码类型等
AVCodecContext *pCodecContext;
pCodecContext = pFormatContext->streams[VideoIndex]->codec;
//pCodec:真正的编解码器
AVCodec *pCodec;
pCodec = avcodec_find_decoder(pCodecContext->codec_id);
if(pCodec == NULL)
{
avformat_close_input(&pFormatContext);
return -4;
}
//通过找到的这条视频流的编解码信息打开相应的解码器
if(avcodec_open2(pCodecContext,pCodec,NULL) < 0)
{
avformat_close_input(&pFormatContext);
return -5;
}
//AVFrame用于保存数据帧的数据结构,这里分别是保存颜色转换前后的两帧图像
AVFrame *pFrame,*pFrameBGR;
//给即将解码的图片分配内存空间,因为最后会将图像写成 24-bits BGR 的 bmp文件,因此这里需要两个AVFrame
pFrame = avcodec_alloc_frame();
pFrameBGR = avcodec_alloc_frame();
if((pFrame == NULL) || (pFrameBGR == NULL))
{
avcodec_close(pCodecContext);
avformat_close_input(&pFormatContext);
return -6;
}
//调用avpicture_get_size,根据 pCodecCtx 中原始图像的宽高计算 BGR24 格式的图像需要占用的空间大小,这是为了之后给 pFrameBGR 分配空间
int PictureSize = avpicture_get_size(PIX_FMT_BGR24,pCodecContext->width,pCodecContext->height);
//申请上面计算大小的内存空间
uint8_t* buf = (uint8_t *)av_malloc(PictureSize);
//调用avpicture_fill,将 pFrameBGR 跟 buf 指向的内存关联起来
avpicture_fill((AVPicture *)pFrameBGR,buf,PIX_FMT_BGR24,pCodecContext->width,pCodecContext->height);
//解码得到图像后,有可能不是 RGB24 格式,需要用 sws_scale 来转换,用 sws_getContext 得到转换上下文,用 sws_scale 将图形从解码后的格式转换为 BGR24
struct SwsContext *pSwsContext = NULL;
pSwsContext = sws_getContext(pCodecContext->width,pCodecContext->height,pCodecContext->pix_fmt,pCodecContext->width,pCodecContext->height,PIX_FMT_BGR24,SWS_BICUBIC,NULL,NULL,NULL);
int j = 0,frameFinished = 0;
//解析文件时会将音、视频帧读入到AVPacket中
AVPacket pPacket;
//从文件中读取一个AVPacket,对于视频来说,一个AVPacket里面包含一帧图像数据,音频可能包含多个帧(当音频帧长度固定时)
while(av_read_frame(pFormatContext,&pPacket) >= 0)
{
//判断AVPacket中读到的这一帧,是否是视频帧
if(pPacket.stream_index == VideoIndex)
{
//解码AVPacket中的帧,有时候解码器并不能从一个AVPacket中解码得到一帧图像数据,因此会设置frameFinished,如果已经得到下一帧图像则设置frameFinished非零,否则为零
avcodec_decode_video2(pCodecContext,pFrame,&frameFinished,&pPacket);
//判断 pFrame 中是否已经得到解码的图像
if(frameFinished)
{
//反转图像 ,否则生成的图像是上下颠倒的
pFrame->data[0] += pFrame->linesize[0]*(pCodecContext->height-1);
pFrame->linesize[0] *= -1;
pFrame->data[1] += pFrame->linesize[1]*(pCodecContext->height/2-1);
pFrame->linesize[1] *= -1;
pFrame->data[2] += pFrame->linesize[2]*(pCodecContext->height/2-1);
pFrame->linesize[2] *= -1;
//转换图像格式,将解压出来的YUV420P的图像转换为BRG24的图像
sws_scale(pSwsContext,(const uint8_t* const*)pFrame->data,pFrame->linesize,0,pCodecContext->height,pFrameBGR->data,pFrameBGR->linesize);
if(j++ < 10)
{
char* filename = new char[128];
sprintf_s(filename,128,"%s_%d.bmp","视频画面",j);
VideoFrameToBmp(pFrameBGR,pCodecContext->width,pCodecContext->height,filename);
delete [] filename;
}
else
break;
}
av_free_packet(&pPacket);
}
}
sws_freeContext(pSwsContext);
av_free(buf);
av_free(pFrameBGR);
av_free(pFrame);
avcodec_close(pCodecContext);
avformat_close_input(&pFormatContext);
return 0;
}
没有合适的资源?快使用搜索试试~ 我知道了~
FFmpeg_10_视频帧存储为bmp位图
共161个文件
h:98个
tlog:30个
lib:8个
需积分: 26 14 下载量 69 浏览量
2015-08-06
10:30:30
上传
评论
收藏 35.98MB ZIP 举报
温馨提示
FFmpeg系列,之前有发过一部分,但并未系列总结性将功能展现,目前按序号,将常用的发上来,VC2010环境下
资源推荐
资源详情
资源评论
收起资源包目录
FFmpeg_10_视频帧存储为bmp位图 (161个子文件)
FFmpeg.cpp 6KB
avcodec-56.dll 21.33MB
avformat-56.dll 5.73MB
avutil-54.dll 482KB
swscale-3.dll 442KB
swresample-1.dll 275KB
FFmpeg.exe 31KB
FFmpeg.vcxproj.filters 955B
avcodec.h 178KB
avformat.h 103KB
avfilter.h 56KB
opt.h 37KB
pixfmt.h 34KB
frame.h 24KB
avio.h 22KB
swresample.h 20KB
intreadwrite.h 18KB
avdevice.h 18KB
pixdesc.h 15KB
mem.h 14KB
common.h 14KB
old_pix_fmts.h 14KB
avstring.h 13KB
swscale.h 12KB
log.h 10KB
old_codec_ids.h 10KB
samplefmt.h 10KB
buffer.h 10KB
channel_layout.h 9KB
avutil.h 8KB
imgutils.h 8KB
_mingw.h 8KB
vdpau.h 8KB
dict.h 8KB
bprint.h 8KB
parseutils.h 7KB
buffersink.h 7KB
version.h 6KB
xvmc.h 6KB
vda.h 6KB
stdint.h 6KB
inttypes.h 6KB
error.h 5KB
timecode.h 5KB
eval.h 5KB
mathematics.h 5KB
fifo.h 5KB
cpu.h 5KB
buffersrc.h 5KB
audio_fifo.h 4KB
rational.h 4KB
attributes.h 4KB
version.h 4KB
vaapi.h 4KB
dv_profile.h 4KB
stereo3d.h 4KB
hash.h 4KB
asrc_abuffer.h 3KB
downmix_info.h 3KB
display.h 3KB
threadmessage.h 3KB
avfft.h 3KB
postprocess.h 3KB
version.h 3KB
hmac.h 3KB
bswap.h 3KB
crc.h 3KB
timestamp.h 3KB
cast5.h 2KB
d3d11va.h 2KB
file.h 2KB
version.h 2KB
avcodec.h 2KB
dxva2.h 2KB
vorbis_parser.h 2KB
blowfish.h 2KB
twofish.h 2KB
camellia.h 2KB
avassert.h 2KB
base64.h 2KB
pixelutils.h 2KB
lzo.h 2KB
sha512.h 2KB
ripemd.h 2KB
version.h 2KB
lfg.h 2KB
md5.h 2KB
sha.h 2KB
xtea.h 2KB
version.h 2KB
aes.h 2KB
time.h 2KB
intfloat.h 2KB
version.h 2KB
version.h 2KB
replaygain.h 2KB
adler32.h 2KB
motion_vector.h 2KB
random_seed.h 1KB
murmur3.h 1KB
共 161 条
- 1
- 2
资源评论
黄忻
- 粉丝: 27
- 资源: 108
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功