`

使用FFmpeg类库实现YUV视频序列编码为视频

 
阅读更多

搞视频处理的朋友肯定比较熟悉YUV视频序列,很多测试库提供的视频数据都是YUV视频序列,我们这里就用用YUV视频序列来做视频。关于YUV视频序列,我就不多讲了,可以看书学习,通常的视频序列都是YUV420格式的。

步骤也就那几步,添加视频流,打开编码器,开辟相应的内存空间,然后就可以打开YUV序列逐帧写入数据了,so easy!记得最后要做好文件的关闭和内存的释放,因为FFmpeg是c风格的(不知道新版本是否是c++风格的),这些工作都需要自己做好啊。过多的说明是没用的,直接上代码:

这里我补充一下,大多数的视频格式好像只支持YUV格式的视频帧AVFrame,我试图直接把RGB的视频序列直接编码到视频这条路好像走不通,都需要把RGB的视频帧再转成YUV视频帧才行,不知道高手有没有其他高见。

 

[cpp]view plaincopy
 
  1. #include<stdio.h>
  2. #include<string.h>
  3. extern"C"
  4. {
  5. #include<libavcodec\avcodec.h>
  6. #include<libavformat\avformat.h>
  7. #include<libswscale\swscale.h>
  8. };
  9. voidmain(intargc,char**argv)
  10. {
  11. AVFormatContext*oc;
  12. AVOutputFormat*fmt;
  13. AVStream*video_st;
  14. doublevideo_pts;
  15. uint8_t*video_outbuf;
  16. uint8_t*picture_buf;
  17. AVFrame*picture;
  18. //AVFrame*pictureRGB;
  19. intsize;
  20. intret;
  21. intvideo_outbuf_size;
  22. FILE*fin=fopen("akiyo_qcif.yuv","rb");//视频源文件
  23. constchar*filename="test.mpg";
  24. //constchar*filename;
  25. //filename=argv[1];
  26. av_register_all();
  27. //avcodec_init();//初始化codec库
  28. //avcodec_register_all();//注册编码器
  29. fmt=guess_format(NULL,filename,NULL);
  30. oc=av_alloc_format_context();
  31. oc->oformat=fmt;
  32. snprintf(oc->filename,sizeof(oc->filename),"%s",filename);
  33. video_st=NULL;
  34. if(fmt->video_codec!=CODEC_ID_NONE)
  35. {
  36. AVCodecContext*c;
  37. video_st=av_new_stream(oc,0);
  38. c=video_st->codec;
  39. c->codec_id=fmt->video_codec;
  40. c->codec_type=CODEC_TYPE_VIDEO;
  41. c->bit_rate=400000;
  42. c->width=176;
  43. c->height=144;
  44. c->time_base.num=1;
  45. c->time_base.den=25;
  46. c->gop_size=12;
  47. c->pix_fmt=PIX_FMT_YUV420P;
  48. if(c->codec_id==CODEC_ID_MPEG2VIDEO)
  49. {
  50. c->max_b_frames=2;
  51. }
  52. if(c->codec_id==CODEC_ID_MPEG1VIDEO)
  53. {
  54. c->mb_decision=2;
  55. }
  56. if(!strcmp(oc->oformat->name,"mp4")||!strcmp(oc->oformat->name,"mov")||!strcmp(oc->oformat->name,"3gp"))
  57. {
  58. c->flags|=CODEC_FLAG_GLOBAL_HEADER;
  59. }
  60. }
  61. if(av_set_parameters(oc,NULL)<0)
  62. {
  63. return;
  64. }
  65. dump_format(oc,0,filename,1);
  66. if(video_st)
  67. {
  68. AVCodecContext*c;
  69. AVCodec*codec;
  70. c=video_st->codec;
  71. codec=avcodec_find_encoder(c->codec_id);
  72. if(!codec)
  73. {
  74. return;
  75. }
  76. if(avcodec_open(c,codec)<0)
  77. {
  78. return;
  79. }
  80. if(!(oc->oformat->flags&AVFMT_RAWPICTURE))
  81. {
  82. video_outbuf_size=200000;
  83. video_outbuf=(uint8_t*)av_malloc(video_outbuf_size);
  84. }
  85. picture=avcodec_alloc_frame();
  86. size=avpicture_get_size(c->pix_fmt,c->width,c->height);
  87. picture_buf=(uint8_t*)av_malloc(size);
  88. if(!picture_buf)
  89. {
  90. av_free(picture);
  91. }
  92. avpicture_fill((AVPicture*)picture,picture_buf,c->pix_fmt,c->width,c->height);
  93. }
  94. if(!(fmt->flags&AVFMT_NOFILE))
  95. {
  96. if(url_fopen(&oc->pb,filename,URL_WRONLY)<0)
  97. {
  98. return;
  99. }
  100. }
  101. av_write_header(oc);
  102. for(inti=0;i<300;i++)
  103. {
  104. if(video_st)
  105. {
  106. video_pts=(double)(video_st->pts.val*video_st->time_base.num/video_st->time_base.den);
  107. }
  108. else
  109. {
  110. video_pts=0.0;
  111. }
  112. if(!video_st/*||video_pts>=5.0*/)
  113. {
  114. break;
  115. }
  116. AVCodecContext*c;
  117. c=video_st->codec;
  118. size=c->width*c->height;
  119. if(fread(picture_buf,1,size*3/2,fin)<0)
  120. {
  121. break;
  122. }
  123. picture->data[0]=picture_buf;//亮度
  124. picture->data[1]=picture_buf+size;//色度
  125. picture->data[2]=picture_buf+size*5/4;//色度
  126. //如果是rgb序列,可能需要如下代码
  127. //SwsContext*img_convert_ctx;
  128. //img_convert_ctx=sws_getContext(c->width,c->height,PIX_FMT_RGB24,c->width,c->height,c->pix_fmt,SWS_BICUBIC,NULL,NULL,NULL);
  129. //sws_scale(img_convert_ctx,pictureRGB->data,pictureRGB->linesize,0,c->height,picture->data,picture->linesize);
  130. if(oc->oformat->flags&AVFMT_RAWPICTURE)
  131. {
  132. AVPacketpkt;
  133. av_init_packet(&pkt);
  134. pkt.flags|=PKT_FLAG_KEY;
  135. pkt.stream_index=video_st->index;
  136. pkt.data=(uint8_t*)picture;
  137. pkt.size=sizeof(AVPicture);
  138. ret=av_write_frame(oc,&pkt);
  139. }
  140. else
  141. {
  142. intout_size=avcodec_encode_video(c,video_outbuf,video_outbuf_size,picture);
  143. if(out_size>0)
  144. {
  145. AVPacketpkt;
  146. av_init_packet(&pkt);
  147. pkt.pts=av_rescale_q(c->coded_frame->pts,c->time_base,video_st->time_base);
  148. if(c->coded_frame->key_frame)
  149. {
  150. pkt.flags|=PKT_FLAG_KEY;
  151. }
  152. pkt.stream_index=video_st->index;
  153. pkt.data=video_outbuf;
  154. pkt.size=out_size;
  155. ret=av_write_frame(oc,&pkt);
  156. }
  157. }
  158. }
  159. if(video_st)
  160. {
  161. avcodec_close(video_st->codec);
  162. //av_free(picture->data[0]);
  163. av_free(picture);
  164. av_free(video_outbuf);
  165. //av_free(picture_buf);
  166. }
  167. av_write_trailer(oc);
  168. for(inti=0;i<oc->nb_streams;i++)
  169. {
  170. av_freep(&oc->streams[i]->codec);
  171. av_freep(&oc->streams[i]);
  172. }
  173. if(!(fmt->flags&AVFMT_NOFILE))
  174. {
  175. url_fclose(oc->pb);
  176. }
  177. av_free(oc);
  178. }

 

原文地址:http://blog.csdn.net/yang_xian521/article/details/7698742

分享到:
评论

相关推荐

    FFmpeg将YUV视频序列编码为视频

    在提供的压缩包文件“YUV2Video”中,可能包含了一个实现上述过程的示例程序或脚本,你可以通过阅读和运行它来更好地理解FFmpeg将YUV视频序列编码为视频文件的具体步骤。在实践中,这将涉及到C或C++编程,对编译和...

    最简单的基于FFMPEG的视频编码器(YUV编码为HEVC H 265 )

    升级后编码器实现了YUV420P像素数据编码为H.265码流。 尽管该视频编码器的代码十分简单,但是几乎包含了使用FFMPEG编码一个视频所有必备的API。十分适合FFmpeg的初学者。 工程基于VC2010。 使用了2014.9.16编译的...

    计算两个YUV视频序列的PSNR

    计算两个视频YUV序列的PSNR,可用于压缩后得到的视频与原始视频进行质量对比。

    最简单的基于FFMPEG的视频编码器(修正)

    该视频编码器实现了YUV420P像素数据编码为H.264码流 尽管该视频编码器的代码十分简单,但是几乎包含了使用FFMPEG编码一个视频所有必备的API。十分适合FFmpeg的初学者。 工程基于VC2010。 使用了2014.5.6版本的...

    [免费]FFmpeg实现YUV420P视频序列转RGB24视频序列(VC2010).rar

    在这个项目中,我们关注的是如何使用FFmpeg将YUV420P格式的视频序列转换为RGB24格式的视频序列,这在视频处理和编解码领域是常见的需求。 YUV420P是一种常见的视频色彩空间格式,它以4:2:0的采样率存储图像数据,即...

    FFmpeg实现YUV420P视频序列转RGB24视频序列(VC2010)

    在这个场景中,我们关注的是如何使用FFmpeg库在C++环境下,将YUV420P视频序列转换为RGB24视频序列,具体操作在Visual Studio 2010(VC2010)下进行。 YUV420P是一种常见的视频色彩空间,它以一种节省带宽的方式存储...

    ffmpeg库实现jpeg图像转yuv格式数据源码

    在本项目中,我们将重点讨论如何使用FFmpeg库将JPEG图像转换为不同类型的YUV格式数据。 首先,我们需要了解JPEG和YUV的基本概念。JPEG是一种广泛使用的有损图像压缩标准,而YUV是视频编码中常见的颜色空间,尤其在...

    使用FFmpeg将RGB格式图片或视频转换为YUV格式

    VC2008项目打包,使用FFmpeg版本为2.2.2 win32bit /* *将RGB转换为YUV420P * *码术 codemanship *http://blog.csdn.net/codemanship *微信公众号: codemanship *本程序实现了RGB像素数据转换为YUV像素数据 *是最简单...

    Android平台的FFmpeg类库

    FFmpeg是一个开源项目,它包含了各种音视频处理的工具和库,被广泛应用于音视频的编码、解码、转码、流媒体处理等场景。在Android平台上,FFmpeg的运用可以极大地增强应用的多媒体处理能力,例如实现视频剪辑、音频...

    VC中使用ffmpeg类库,可用

    很多播放器都使用了ffmpeg这个类库来编解码 使用LIB和DLL实现ffmpeg的相关功能函数

    ffmpeg视频解码成YUV,JPG

    在这个场景中,我们主要关注的是如何使用FFmpeg将视频解码为YUV格式,以及将YUV数据转化为JPEG图片。下面我们将详细介绍这两个过程。 1. **FFmpeg视频解码** 视频文件通常是以压缩格式存储的,如MP4、AVI或MKV等。...

    找了很久的FFMPEG的类库

    GebVideoFFMPEG-master这个项目则可能是开发者为了方便分享和学习FFmpeg而创建的一个实例,其中包含了使用FFmpeg进行视频处理的具体实现。如果你对此感兴趣,可以通过解压并研究该项目的源代码,进一步了解FFmpeg的...

    最简单的基于FFMPEG的视频编码器

    该视频编码器实现了YUV420P像素数据编码为H.264码流 尽管该视频编码器的代码十分简单,但是几乎包含了使用FFMPEG编码一个视频所有必备的API。十分适合FFmpeg的初学者。 工程基于VC2010。 使用了2014.5.6版本的...

    ffmpeg YUV编码成h264

    这个程序可能包括解析YUV数据、初始化FFmpeg上下文、编码视频帧以及将编码结果写入输出文件等功能。通过阅读和理解这段代码,你可以更深入地了解FFmpeg如何进行视频编码。 需要注意的是,实际操作时还需要考虑线程...

    FFmpeg-YUV2AVI

    FFmpeg-YUV2AVI 是一个使用 FFmpeg 库将 YUV 格式的视频数据转换为 AVI 格式视频的源代码项目。这个项目主要适用于开发者,特别是那些需要处理视频编码和解码的程序员。FFmpeg 是一个开源的、跨平台的多媒体处理框架...

    ffmpeg3.4.1 将YUV数据封装成Mp4文件

    在FFmpeg中,你可以使用C++ API来实现各种功能,包括将YUV数据封装成MP4文件。标题提到的"ffmpeg3.4.1 将YUV数据封装成Mp4文件",涉及到的关键步骤包括初始化、编码和反初始化。以下是对这些过程的详细解释: 1. **...

    mpeg4.zip_ffmpeg_ffmpeg mpeg4_ffmpeg yuv编码_mpeg4

    MPEG-4是一种高效且灵活的视频编码标准,它不仅可以编码视频,还可以包含音频、字幕、交互式内容等。MPEG-4编码器通过使用运动补偿、熵编码、可变块大小编码等技术来减少视频数据量,从而实现高质量的视频压缩。 4...

    FFmpeg解码MP4分别播放YUV视频和PCM音频

    在本文中,我们将深入探讨如何使用FFmpeg解码MP4文件,并分别播放其中的YUV视频和PCM音频。 MP4是一种广泛应用的多媒体容器格式,它可以包含多种音视频编码的数据。FFmpeg支持对MP4格式的文件进行解码,提取出原始...

    ffmpeg将YUV文件编码到常见视频文件格式

    在本主题中,我们将深入探讨如何利用FFmpeg将YUV文件编码成常见的视频文件格式,如AVI、FLV、MP4、RM、VOB、WebM和WMV等,这些格式广泛应用于视频编解码测试。 首先,了解YUV格式:YUV是一种常见的颜色空间,主要...

    FFMPEG_YUV转H264_编码_本地文件

    FFMPEG_YUV转H264_编码_本地文件

Global site tag (gtag.js) - Google Analytics