搞视频处理的朋友肯定比较熟悉YUV视频序列,很多测试库提供的视频数据都是YUV视频序列,我们这里就用用YUV视频序列来做视频。关于YUV视频序列,我就不多讲了,可以看书学习,通常的视频序列都是YUV420格式的。
步骤也就那几步,添加视频流,打开编码器,开辟相应的内存空间,然后就可以打开YUV序列逐帧写入数据了,so easy!记得最后要做好文件的关闭和内存的释放,因为FFmpeg是c风格的(不知道新版本是否是c++风格的),这些工作都需要自己做好啊。过多的说明是没用的,直接上代码:
这里我补充一下,大多数的视频格式好像只支持YUV格式的视频帧AVFrame,我试图直接把RGB的视频序列直接编码到视频这条路好像走不通,都需要把RGB的视频帧再转成YUV视频帧才行,不知道高手有没有其他高见。
-
#include<stdio.h>
-
#include<string.h>
-
-
extern"C"
-
{
-
#include<libavcodec\avcodec.h>
-
#include<libavformat\avformat.h>
-
#include<libswscale\swscale.h>
-
};
-
-
voidmain(intargc,char**argv)
-
{
-
AVFormatContext*oc;
-
AVOutputFormat*fmt;
-
AVStream*video_st;
-
doublevideo_pts;
-
uint8_t*video_outbuf;
-
uint8_t*picture_buf;
-
AVFrame*picture;
-
-
intsize;
-
intret;
-
intvideo_outbuf_size;
-
-
FILE*fin=fopen("akiyo_qcif.yuv","rb");
-
-
constchar*filename="test.mpg";
-
-
-
-
av_register_all();
-
-
-
-
-
fmt=guess_format(NULL,filename,NULL);
-
oc=av_alloc_format_context();
-
oc->oformat=fmt;
-
snprintf(oc->filename,sizeof(oc->filename),"%s",filename);
-
-
video_st=NULL;
-
if(fmt->video_codec!=CODEC_ID_NONE)
-
{
-
AVCodecContext*c;
-
video_st=av_new_stream(oc,0);
-
c=video_st->codec;
-
c->codec_id=fmt->video_codec;
-
c->codec_type=CODEC_TYPE_VIDEO;
-
c->bit_rate=400000;
-
c->width=176;
-
c->height=144;
-
c->time_base.num=1;
-
c->time_base.den=25;
-
c->gop_size=12;
-
c->pix_fmt=PIX_FMT_YUV420P;
-
if(c->codec_id==CODEC_ID_MPEG2VIDEO)
-
{
-
c->max_b_frames=2;
-
}
-
if(c->codec_id==CODEC_ID_MPEG1VIDEO)
-
{
-
c->mb_decision=2;
-
}
-
if(!strcmp(oc->oformat->name,"mp4")||!strcmp(oc->oformat->name,"mov")||!strcmp(oc->oformat->name,"3gp"))
-
{
-
c->flags|=CODEC_FLAG_GLOBAL_HEADER;
-
}
-
}
-
-
if(av_set_parameters(oc,NULL)<0)
-
{
-
return;
-
}
-
-
dump_format(oc,0,filename,1);
-
if(video_st)
-
{
-
AVCodecContext*c;
-
AVCodec*codec;
-
c=video_st->codec;
-
codec=avcodec_find_encoder(c->codec_id);
-
if(!codec)
-
{
-
return;
-
}
-
if(avcodec_open(c,codec)<0)
-
{
-
return;
-
}
-
if(!(oc->oformat->flags&AVFMT_RAWPICTURE))
-
{
-
video_outbuf_size=200000;
-
video_outbuf=(uint8_t*)av_malloc(video_outbuf_size);
-
}
-
picture=avcodec_alloc_frame();
-
size=avpicture_get_size(c->pix_fmt,c->width,c->height);
-
picture_buf=(uint8_t*)av_malloc(size);
-
if(!picture_buf)
-
{
-
av_free(picture);
-
}
-
avpicture_fill((AVPicture*)picture,picture_buf,c->pix_fmt,c->width,c->height);
-
}
-
-
if(!(fmt->flags&AVFMT_NOFILE))
-
{
-
if(url_fopen(&oc->pb,filename,URL_WRONLY)<0)
-
{
-
return;
-
}
-
}
-
av_write_header(oc);
-
-
for(inti=0;i<300;i++)
-
{
-
if(video_st)
-
{
-
video_pts=(double)(video_st->pts.val*video_st->time_base.num/video_st->time_base.den);
-
}
-
else
-
{
-
video_pts=0.0;
-
}
-
if(!video_st)
-
{
-
break;
-
}
-
AVCodecContext*c;
-
c=video_st->codec;
-
size=c->width*c->height;
-
-
if(fread(picture_buf,1,size*3/2,fin)<0)
-
{
-
break;
-
}
-
-
picture->data[0]=picture_buf;
-
picture->data[1]=picture_buf+size;
-
picture->data[2]=picture_buf+size*5/4;
-
-
-
-
-
-
-
if(oc->oformat->flags&AVFMT_RAWPICTURE)
-
{
-
AVPacketpkt;
-
av_init_packet(&pkt);
-
pkt.flags|=PKT_FLAG_KEY;
-
pkt.stream_index=video_st->index;
-
pkt.data=(uint8_t*)picture;
-
pkt.size=sizeof(AVPicture);
-
ret=av_write_frame(oc,&pkt);
-
}
-
else
-
{
-
intout_size=avcodec_encode_video(c,video_outbuf,video_outbuf_size,picture);
-
if(out_size>0)
-
{
-
AVPacketpkt;
-
av_init_packet(&pkt);
-
pkt.pts=av_rescale_q(c->coded_frame->pts,c->time_base,video_st->time_base);
-
if(c->coded_frame->key_frame)
-
{
-
pkt.flags|=PKT_FLAG_KEY;
-
}
-
pkt.stream_index=video_st->index;
-
pkt.data=video_outbuf;
-
pkt.size=out_size;
-
ret=av_write_frame(oc,&pkt);
-
}
-
}
-
}
-
-
if(video_st)
-
{
-
avcodec_close(video_st->codec);
-
-
av_free(picture);
-
av_free(video_outbuf);
-
-
}
-
av_write_trailer(oc);
-
for(inti=0;i<oc->nb_streams;i++)
-
{
-
av_freep(&oc->streams[i]->codec);
-
av_freep(&oc->streams[i]);
-
}
-
if(!(fmt->flags&AVFMT_NOFILE))
-
{
-
url_fclose(oc->pb);
-
}
-
av_free(oc);
-
}
原文地址:http://blog.csdn.net/yang_xian521/article/details/7698742
分享到:
相关推荐
对应的详细介绍http://blog.csdn.net/yang_xian521/article/details/7698742 利用FFmpeg SDK,将YUV视频序列编码为视频文件
升级后编码器实现了YUV420P像素数据编码为H.265码流。 尽管该视频编码器的代码十分简单,但是几乎包含了使用FFMPEG编码一个视频所有必备的API。十分适合FFmpeg的初学者。 工程基于VC2010。 使用了2014.9.16编译的...
该视频编码器实现了YUV420P像素数据编码为H.264码流 尽管该视频编码器的代码十分简单,但是几乎包含了使用FFMPEG编码一个视频所有必备的API。十分适合FFmpeg的初学者。 工程基于VC2010。 使用了2014.5.6版本的...
计算两个视频YUV序列的PSNR,可用于压缩后得到的视频与原始视频进行质量对比。
源码通过ffmpeg库实现将jpeg图像转换为yuv420,yuv422,yuv444,rgb24等格式数据
FFmpeg实现YUV420P视频序列转RGB24视频序列(VC2010),参考这方面的大牛代码,基本没修改什么,只是在主要地方添加了注释,另外在包里面放了相关文件的播放器工具
FFmpeg实现YUV420P视频序列转RGB24视频序列(VC2010),参考这方面的大牛代码,基本没修改什么,只是在主要地方添加了注释,另外在包里面放了相关文件的播放器工具.
很多播放器都使用了ffmpeg这个类库来编解码 使用LIB和DLL实现ffmpeg的相关功能函数
VC2008项目打包,使用FFmpeg版本为2.2.2 win32bit /* *将RGB转换为YUV420P * *码术 codemanship *http://blog.csdn.net/codemanship *微信公众号: codemanship *本程序实现了RGB像素数据转换为YUV像素数据 *是最简单...
该视频编码器实现了YUV420P像素数据编码为H.264码流 尽管该视频编码器的代码十分简单,但是几乎包含了使用FFMPEG编码一个视频所有必备的API。十分适合FFmpeg的初学者。 工程基于VC2010。 使用了2014.5.6版本的...
使用ffmpeg将YUV文件编码到常见视频文件格式,这些视频文件可以用来作为视频编解码测试文件
FFMPEG_YUV转H264_编码_本地文件
在Ubuntu下编译好的FFmpeg类适用于安卓平台,希望对大家能用
这是在linux环境下编译好的FFmpeg类库和头文件,适用于Android的音视频开发。 在编译过程中,NDK和FFmpeg的版本需要对应起来,否则编译过程中可能失败。这里编译过程中采用的版本为`android-ndk-r15c-linux-x86_64....
ffmpeg YUV编码成h264
编译好的ffmpeg类库文件,32位版本,输出版本号为 ffmpeg version N-99305-gbc0e776 Copyright (c) 2000-2020 the FFmpeg developers built with 用于 x86 的 Microsoft (R) C/C++ 优化编译器 19.27.29112 版 包含...
该图像编码器实现了YUV420P的数据编码为JPEG图片。 尽管该图像编码器的代码十分简单,但是几乎包含了使用FFMPEG编码一个图像所有必备的API。十分适合FFmpeg的初学者。 使用了2014.5.6版本的FFmpeg类库。
封装了ffmpeg api 只调用三个函数,初始化,反初始化,编码生成Mp4 , 方便工程嵌入
很久才找到的,宝贝呀,供大家分享。