使用FFMPEG将YUV编码为H.264

43 篇文章 0 订阅

本文介绍一个如何使用FFmpeg实现YUV420P的像素数据编码为H.264的压缩编码数据。

项目十分简单,没有多少代码在其中。弄清楚了该项目的代码也就基本弄清楚了FFMPEG的编码流程。

本程序使用的FFmpeg版本为2.2.2(版本较新),开发平台为VC2008(VC2010估计很多人都用不了)。

相关配置已经完成,只需下载源码运行即可。

下面直接上代码:

 

 
  1. /*

  2. *将YUV420P进行H264编码压缩

  3. *码术 codemanship

  4. *邮箱: f.chen1989@gmail.com

  5. *http://blog.csdn.net/codemanship

  6. *微信公众号: codemanship

  7. *本程序实现了YUV420P的像素数据编码为H.264的压缩编码数据

  8. *是最简单的FFmpeg视频编码方面的教程。

  9. *通过学习本例子可以了解FFmpeg的图片压缩过程。

  10. */

  11. #ifndef INT64_C

  12. #define INT64_C

  13. #define UINT64_C

  14. #endif

  15. extern "C"

  16. {

  17. #include "libavcodec/avcodec.h"

  18. #include "libavutil/imgutils.h"

  19. #include "libavutil/parseutils.h"

  20. #include "libswscale/swscale.h"

  21. #include "libavformat/avformat.h"

  22. };

  23. #pragma comment(lib,"avcodec.lib")

  24. #pragma comment(lib,"avformat.lib")

  25. #pragma comment(lib,"swscale.lib")

  26. #pragma comment(lib,"avutil.lib")

  27.  
  28. #define FrameCount 50

  29. static void fill_yuv_image(uint8_t *data[4], int linesize[4],

  30. int width, int height, int frame_index)

  31. {

  32. int x, y;

  33.  
  34. /* Y */

  35. for (y = 0; y < height; y++)

  36. for (x = 0; x < width; x++)

  37. data[0][y * linesize[0] + x] = x + y + frame_index * 3;

  38.  
  39. /* Cb and Cr */

  40. for (y = 0; y < height / 2; y++) {

  41. for (x = 0; x < width / 2; x++) {

  42. data[1][y * linesize[1] + x] = 128 + y + frame_index * 2;

  43. data[2][y * linesize[2] + x] = 64 + x + frame_index * 5;

  44. }

  45. }

  46. }

  47.  
  48.  
  49.  
  50. int main(int argc, char **argv)

  51. {

  52. AVFormatContext* pFormatCtx;

  53. AVOutputFormat* fmt;

  54. AVStream* video_st;

  55. AVCodecContext* pCodecCtx;

  56. AVCodec* pCodec;

  57. AVFrame* srcFrame;

  58. int size;

  59.  
  60. int width=640,height=480;

  61. const char* outfilename = "out_640x480.h264";

  62.  
  63. av_register_all();

  64. pFormatCtx = avformat_alloc_context();

  65. fmt = av_guess_format(NULL, outfilename, NULL);

  66. pFormatCtx->oformat = fmt;

  67.  
  68. if (avio_open(&pFormatCtx->pb,outfilename, AVIO_FLAG_READ_WRITE) < 0)

  69. {

  70. printf("open file failed.");

  71. exit(1);

  72. }

  73.  
  74. video_st = av_new_stream(pFormatCtx, 0);

  75. if (video_st==NULL)

  76. {

  77. exit(1);

  78. }

  79. pCodecCtx = video_st->codec;

  80. pCodecCtx->codec_id = fmt->video_codec;

  81. pCodecCtx->codec_type = AVMEDIA_TYPE_VIDEO;

  82. pCodecCtx->pix_fmt = PIX_FMT_YUV420P;

  83. pCodecCtx->width = width;

  84. pCodecCtx->height = height;

  85. pCodecCtx->time_base.num = 1;

  86. pCodecCtx->time_base.den = 25;

  87. pCodecCtx->bit_rate = 40000;

  88. pCodecCtx->gop_size=10;

  89. pCodecCtx->qmin = 10;

  90. pCodecCtx->qmax = 30;

  91.  
  92. //输出格式信息

  93. av_dump_format(pFormatCtx, 0, outfilename, 1);

  94.  
  95. pCodec = avcodec_find_encoder(pCodecCtx->codec_id);

  96. if (!pCodec)

  97. {

  98. fprintf(stderr, "Codec not found\n");

  99. exit(1);

  100. }

  101. //设置X264编码的参数,减小延迟

  102. AVDictionary *opts = NULL;

  103. av_dict_set(&opts, "profile", "baseline", 0);

  104. av_dict_set(&opts, "preset", "fast", 0);

  105. av_dict_set(&opts, "tune", "zerolatency", 0);

  106. if (avcodec_open2(pCodecCtx, pCodec,&opts) < 0)

  107. {

  108. fprintf(stderr, "Could not open codec\n");

  109. exit(1);

  110. }

  111. srcFrame = av_frame_alloc();

  112. size = avpicture_get_size(pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height);

  113. /* allocate source and destination image buffers */

  114. if ((av_image_alloc(srcFrame->data, srcFrame->linesize,

  115. width, height, PIX_FMT_YUV420P, 16)) < 0) {

  116. fprintf(stderr, "Could not allocate source image\n");

  117. exit(1);

  118. }

  119. //写文件头

  120. avformat_write_header(pFormatCtx,NULL);

  121.  
  122. AVPacket pkt;

  123. int y_size = pCodecCtx->width * pCodecCtx->height;

  124. av_new_packet(&pkt,y_size*3);

  125.  
  126. for (int i=0; i<FrameCount; i++){

  127. /* generate synthetic video */

  128. fill_yuv_image(srcFrame->data,srcFrame->linesize,width,height,i);

  129. /*设置pts*/

  130. srcFrame->pts=i;

  131. int got_picture=0;

  132. /*编码*/

  133. int ret = avcodec_encode_video2(pCodecCtx, &pkt,srcFrame, &got_picture);

  134. if(ret < 0)

  135. {

  136. fprintf(stderr, "Error encoding frame\n");

  137. return -1;

  138. }

  139. if (got_picture==1)

  140. {

  141. printf("Write frame %3d (size=%5d)\n", i, pkt.size);

  142. pkt.stream_index = video_st->index;

  143. ret = av_write_frame(pFormatCtx, &pkt);

  144. av_free_packet(&pkt);

  145. }

  146. }

  147.  
  148. //写文件尾

  149. av_write_trailer(pFormatCtx);

  150. //清理

  151. if (video_st)

  152. {

  153. avcodec_close(video_st->codec);

  154. av_freep(srcFrame);

  155. }

  156. avio_close(pFormatCtx->pb);

  157. avformat_free_context(pFormatCtx);

  158. return 0;

  159. }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: FFmpeg是一款流媒体处理的工具,支持多种视频编码格式,其中也包括YUV编码。H.265是一种高效的视频编码格式,可以将视频文件的大小压缩至原来的一半。 要将YUV编码的视频文件换为H.265编码,需要进行以下步骤: 1. 通过FFmpeg获取原始视频的YUV数据。 2. 将YUV数据进行处理,将其换为H.265编码格式。此处需要使用x265编码器,以实现高质量的视频编码。 3. 将处理后的H.265编码数据化为保存为视频文件。 在使用FFmpeg进行YUV编码为H.265的操作时,需要注意以下几点: 1. YUV数据的格式应该符合编码器的要求,否则将无法进行编码。 2. 编码参数的选择对于编码质量和压缩率都有很大影响,需要注意对应的参数设置。 3. H.265编码是比较耗时的操作,需要足够的计算机性能支持。 通过上述步骤,我们可以将YUV格式的视频文件换为高效的H.265格式,实现更好的视频质量和更小的视频文件大小。 ### 回答2: FFmpeg是一个跨平台的音视频处理,其中也包括了对YUV数据的处理和编码功能。而H.265是一种高效的视频编码标准,能够提供更好的视频质量和更小的文件大小。因此,将YUV数据编码为H.265对于提高视频编码的效率和质量非常重要。 在FFmpeg中,可以使用x265编码器来将YUV数据编码为H.265。首先,需要将YUV数据加载到FFmpeg中,并设置相应的编码器参数。然后,使用x265编码器对YUV数据进行压缩编码,并输出为H.265视频文件格式。 具体步骤如下: 1. 使用FFmpeg加载YUV数据,可以通过命令行输入以下命令: ffmpeg -s:v widthxheight -pix_fmt yuv420p -i input.yuv 其中,width和height分别表示YUV数据的宽度和高度,input.yuvYUV数据的文件名。 2. 设置编码器参数,可以通过命令行指定编码器的参数,例如: ffmpeg -c:v libx265 -preset medium -x265-params keyint=60 -b:v 2M output.mp4 其中,-c:v表示指定使用x265编码器,-preset medium表示设置为中等压缩质量,-x265-params keyint=60表示设置关键帧间隔为60,-b:v 2M表示设置输出视频的比特率为2M,output.mp4表示输出为H.265视频文件。 3. 进行YUV编码,可以使用以下命令实现: ffmpeg -i input.yuv -c:v libx265 -preset medium -x265-params keyint=60 -b:v 2M output.mp4 其中,-i input.yuv表示输入YUV数据文件,-c:v libx265表示指定使用x265编码器进行编码,后续参数同上。 通过以上步骤,就可以将YUV数据编码为H.265格式的视频文件,从而利用H.265标准的高效性能优势来提高视频编码的效率和质量。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值