用x264和ffmpeg将YUV编码为.h264(2)

二、ffmpeg 将YUV编码为.h264

1.下载安装ffmpeg

./configure --enable-libx264 --enable-gpl --enable-shared
make 
make install

2.用安装好的ffmpeg用命令将YUV编码为.h264

ffmpeg -s 480x272 -i ds_480x272.yuv -r 25 -vcodec libx264 ds2.h264 

yuv文件:

https://github.com/leixiaohua1020/simplest_ffmpeg_video_encoder/blob/master/ds_480x272.yuv

3.用C语言代码调用ffmpeg接口将YUV编码为.h264

编译命令:编译之前,执行下ldconfig命令,把libx264库更新到系统库路径;

gcc simplest_ffmpeg_video_encoder_pure.cpp -g -o sffmpegencoder -I /usr/local/include -L /usr/local/lib -lavformat -lavcodec -lavutil

代码如下

simplest_ffmpeg_video_encoder_pure.cpp

 
  1. /*

  2. * Simplest FFmpeg Video Encoder Pure

  3. *

  4. * Lei Xiaohua

  5. * [email protected]

  6. * Communication University of China / Digital TV Technology

  7. * http://blog.csdn.net/leixiaohua1020

  8. *

  9.  
  10. * This software encode YUV420P data to video bitstream

  11. * (Such as H.264, H.265, VP8, MPEG2 etc).

  12. * It only uses libavcodec to encode video (without libavformat)

  13. * It's the simplest video encoding software based on FFmpeg.

  14. * Suitable for beginner of FFmpeg

  15. *

  16. *

  17. * modify: openswc

  18. * build:

  19. * gcc simplest_ffmpeg_video_encoder_pure.cpp -g -o sffmpegencoder -I /usr/local/include -L /usr/local/lib -lavformat -lavcodec -lavutil

  20. * before use sffmpegencoder: you need to excute the following command: su root; ldconfig;

  21. * or there is an error:

  22. * ./sffmpegencoder: error while loading shared libraries: libavcodec.so.57: cannot open shared object file: No such file or directory

  23. */

  24.  
  25.  
  26. #include <stdio.h>

  27.  
  28. #define __STDC_CONSTANT_MACROS

  29.  
  30. #ifdef _WIN32

  31. //Windows

  32. extern "C"

  33. {

  34. #include "libavutil/opt.h"

  35. #include "libavcodec/avcodec.h"

  36. #include "libavutil/imgutils.h"

  37. };

  38. #else

  39. //Linux...

  40. #ifdef __cplusplus

  41. extern "C"

  42. {

  43. #endif

  44. #include <libavutil/opt.h>

  45. #include <libavcodec/avcodec.h>

  46. #include <libavutil/imgutils.h>

  47. #ifdef __cplusplus

  48. };

  49. #endif

  50. #endif

  51.  
  52. //test different codec

  53. #define TEST_H264 1

  54. #define TEST_HEVC 0

  55.  
  56.  
  57. int main(int argc, char* argv[])

  58. {

  59. AVCodec *pCodec;

  60. AVCodecContext *pCodecCtx= NULL;

  61. int i, ret, got_output;

  62. FILE *fp_in;

  63. FILE *fp_out;

  64. AVFrame *pFrame;

  65. AVPacket pkt;

  66. int y_size;

  67. int framecnt=0;

  68.  
  69. char filename_in[]="../ds_480x272.yuv";

  70.  
  71. #if TEST_HEVC

  72. AVCodecID codec_id=AV_CODEC_ID_HEVC;

  73. char filename_out[]="ds.hevc";

  74. #else

  75. AVCodecID codec_id=AV_CODEC_ID_H264;

  76. char filename_out[]="ds.h264";

  77. #endif

  78.  
  79.  
  80. int in_w=480,in_h=272;

  81. int framenum=100;

  82.  
  83. avcodec_register_all();

  84.  
  85. pCodec = avcodec_find_encoder(codec_id);

  86. if (!pCodec) {

  87. printf("Codec not found\n");

  88. return -1;

  89. }

  90. pCodecCtx = avcodec_alloc_context3(pCodec);

  91. if (!pCodecCtx) {

  92. printf("Could not allocate video codec context\n");

  93. return -1;

  94. }

  95. pCodecCtx->bit_rate = 400000;

  96. pCodecCtx->width = in_w;

  97. pCodecCtx->height = in_h;

  98. pCodecCtx->time_base.num=1;

  99. pCodecCtx->time_base.den=25;

  100. pCodecCtx->gop_size = 10;

  101. pCodecCtx->max_b_frames = 1;

  102. pCodecCtx->pix_fmt = AV_PIX_FMT_YUV420P;

  103.  
  104. if (codec_id == AV_CODEC_ID_H264)

  105. av_opt_set(pCodecCtx->priv_data, "preset", "slow", 0);

  106.  
  107. if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) {

  108. printf("Could not open codec\n");

  109. return -1;

  110. }

  111.  
  112. pFrame = av_frame_alloc();

  113. if (!pFrame) {

  114. printf("Could not allocate video frame\n");

  115. return -1;

  116. }

  117. pFrame->format = pCodecCtx->pix_fmt;

  118. pFrame->width = pCodecCtx->width;

  119. pFrame->height = pCodecCtx->height;

  120.  
  121. ret = av_image_alloc(pFrame->data, pFrame->linesize, pCodecCtx->width, pCodecCtx->height,

  122. pCodecCtx->pix_fmt, 16);

  123. if (ret < 0) {

  124. printf("Could not allocate raw picture buffer\n");

  125. return -1;

  126. }

  127. //Input raw data

  128. fp_in = fopen(filename_in, "rb");

  129. if (!fp_in) {

  130. printf("Could not open %s\n", filename_in);

  131. return -1;

  132. }

  133. //Output bitstream

  134. fp_out = fopen(filename_out, "wb");

  135. if (!fp_out) {

  136. printf("Could not open %s\n", filename_out);

  137. return -1;

  138. }

  139.  
  140. y_size = pCodecCtx->width * pCodecCtx->height;

  141. //Encode

  142. for (i = 0; i < framenum; i++) {

  143. av_init_packet(&pkt);

  144. pkt.data = NULL; // packet data will be allocated by the encoder

  145. pkt.size = 0;

  146. //Read raw YUV data

  147. if (fread(pFrame->data[0],1,y_size,fp_in)<= 0|| // Y

  148. fread(pFrame->data[1],1,y_size/4,fp_in)<= 0|| // U

  149. fread(pFrame->data[2],1,y_size/4,fp_in)<= 0){ // V

  150. return -1;

  151. }else if(feof(fp_in)){

  152. break;

  153. }

  154.  
  155. pFrame->pts = i;

  156. /* encode the image */

  157. ret = avcodec_encode_video2(pCodecCtx, &pkt, pFrame, &got_output);

  158. if (ret < 0) {

  159. printf("Error encoding frame\n");

  160. return -1;

  161. }

  162. if (got_output) {

  163. printf("Succeed to encode frame: %5d\tsize:%5d\n",framecnt,pkt.size);

  164. framecnt++;

  165. fwrite(pkt.data, 1, pkt.size, fp_out);

  166. av_free_packet(&pkt);

  167. }

  168. }

  169. //Flush Encoder

  170. for (got_output = 1; got_output; i++) {

  171. ret = avcodec_encode_video2(pCodecCtx, &pkt, NULL, &got_output);

  172. if (ret < 0) {

  173. printf("Error encoding frame\n");

  174. return -1;

  175. }

  176. if (got_output) {

  177. printf("Flush Encoder: Succeed to encode 1 frame!\tsize:%5d\n",pkt.size);

  178. fwrite(pkt.data, 1, pkt.size, fp_out);

  179. av_free_packet(&pkt);

  180. }

  181. }

  182.  
  183. fclose(fp_out);

  184. avcodec_close(pCodecCtx);

  185. av_free(pCodecCtx);

  186. av_freep(&pFrame->data[0]);

  187. av_frame_free(&pFrame);

  188.  
  189. return 0;

  190. }

猜你喜欢

转载自blog.csdn.net/weixin_37897683/article/details/81267683