Chinaunix首页 | 论坛 | 博客
  • 博客访问: 7894076
  • 博文数量: 701
  • 博客积分: 2150
  • 博客等级: 上尉
  • 技术积分: 13233
  • 用 户 组: 普通用户
  • 注册时间: 2011-06-29 16:28
个人简介

天行健,君子以自强不息!

文章分类

全部博文(701)

文章存档

2019年(2)

2018年(12)

2017年(76)

2016年(120)

2015年(178)

2014年(129)

2013年(123)

2012年(61)

分类: 高性能计算

2015-11-20 14:17:03

基于ffmpeg SDK  build by ffmpepv2.4.3
闲言少述,直接上代码


/*
 * \File
 *    yuv2h264.c
 * \Desc
 *    输入YUV420文件,编码生成h.264的文件
 * \Author
 *    Hank
 */

点击(此处)折叠或打开

  1. #include <math.h>


  2. #include <libavutil/opt.h>
  3. #include <libavcodec/avcodec.h>
  4. #include <libavutil/channel_layout.h>
  5. #include <libavutil/common.h>
  6. #include <libavutil/imgutils.h>
  7. #include <libavutil/mathematics.h>
  8. #include <libavutil/samplefmt.h>


  9. #define INBUF_SIZE 4096
  10. #define AUDIO_INBUF_SIZE 20480
  11. #define AUDIO_REFILL_THRESH 4096


  12. /*
  13.  * Video encoding example
  14.  */
  15. static void video_encode(const char *inputfilename, const char *outputfilename, int codec_id)
  16. {
  17.     AVCodec *codec;
  18.     AVCodecContext *c= NULL;
  19.     int i, ret, got_output;
  20.     int in_size, picture_size;
  21.     uint8_t *picture_buf;
  22.     FILE *f_in, *f_out;
  23.     AVFrame *frame;
  24.     AVPacket pkt;
  25.     uint8_t endcode[] = { 0, 0, 1, 0xb7 };


  26.     printf("Encode video file %s\n", outputfilename);


  27.     /* find the mpeg1 video encoder */
  28.     codec = avcodec_find_encoder(codec_id);
  29.     if (!codec) {
  30.         fprintf(stderr, "Codec not found\n");
  31.         exit(1);
  32.     }


  33.     c = avcodec_alloc_context3(codec);
  34.     if (!c) {
  35.         fprintf(stderr, "Could not allocate video codec context\n");
  36.         exit(1);
  37.     }


  38.     /* put sample parameters */
  39.     c->bit_rate = 400000;
  40.     /* resolution must be a multiple of two */
  41.     c->width = 352;
  42.     c->height = 288;
  43.     /* frames per second */
  44.     c->time_base = (AVRational){1,25};
  45.     /* emit one intra frame every ten frames
  46.      * check frame pict_type before passing frame
  47.      * to encoder, if frame->pict_type is AV_PICTURE_TYPE_I
  48.      * then gop_size is ignored and the output of encoder
  49.      * will always be I frame irrespective to gop_size
  50.      */
  51.     c->gop_size = 10;
  52.     c->max_b_frames = 1;
  53.     c->pix_fmt = AV_PIX_FMT_YUV420P;


  54.     if (codec_id == AV_CODEC_ID_H264)
  55.         av_opt_set(c->priv_data, "preset", "slow", 0);


  56.     /* open it */
  57.     if (avcodec_open2(c, codec, NULL) < 0) {
  58.         fprintf(stderr, "Could not open codec\n");
  59.         exit(1);
  60.     }


  61.     f_in = fopen(inputfilename, "rb+");
  62.     if (!f_in){
  63.         fprintf(stderr, "Could not open %s\n", inputfilename);
  64.         exit(1);
  65.     }


  66.     f_out = fopen(outputfilename, "wb");
  67.     if (!f_out) {
  68.         fprintf(stderr, "Could not open %s\n", outputfilename);
  69.         exit(1);
  70.     }


  71.     frame = av_frame_alloc();
  72.     if (!frame) {
  73.         fprintf(stderr, "Could not allocate video frame\n");
  74.         exit(1);
  75.     }
  76.     frame->format = c->pix_fmt;
  77.     frame->width = c->width;
  78.     frame->height = c->height;
  79.     frame->linesize[0] = c->width;
  80.     frame->linesize[1] = c->width / 2;
  81.     frame->linesize[2] = c->width / 2;


  82.     /* the image can be allocated by any means and av_image_alloc() is
  83.      * just the most convenient way if av_malloc() is to be used */
  84.     ret = av_image_alloc(frame->data, frame->linesize, c->width, c->height,
  85.                          c->pix_fmt, 12);
  86.     if (ret < 0) {
  87.         fprintf(stderr, "Could not allocate raw picture buffer\n");
  88.         exit(1);
  89.     }
  90.     picture_size = c->width * c->height;
  91.     picture_buf = (uint8_t *)malloc((picture_size * 3) / 2); //size for YUV420
  92.     frame->data[0] = picture_buf;
  93.     frame->data[1] = frame->data[0] + picture_size;
  94.     frame->data[2] = frame->data[1] + picture_size / 4;


  95.     /* encode 1 second of video */
  96.     for (;;) {
  97.         av_init_packet(&pkt);
  98.         pkt.data = NULL; // packet data will be allocated by the encoder
  99.         pkt.size = 0;


  100.         fflush(stdout);




  101.         /* prepare a dummy image */
  102.         memset(picture_buf, 0, sizeof(char)*(picture_size*3)/2);
  103.         in_size = fread(picture_buf, sizeof(char), (picture_size *3)/2, f_in);


  104.         /* End of the input file */
  105.         if (in_size != picture_size*3/2)
  106.           break;


  107.         av_log(NULL, AV_LOG_DEBUG, "Read %d bytes from inputfile\n", in_size);
  108.         frame->data[0] = picture_buf;
  109.         frame->data[1] = frame->data[0] + picture_size;
  110.         frame->data[2] = frame->data[1] + picture_size / 4;


  111.         frame->pts = i++;


  112.         /* encode the image */
  113.         ret = avcodec_encode_video2(c, &pkt, frame, &got_output);
  114.         if (ret < 0) {
  115.             fprintf(stderr, "Error encoding frame\n");
  116.             exit(1);
  117.         }


  118.         if (got_output) {
  119.             printf("Write frame %3d (size=%5d)\n", i, pkt.size);
  120.             fwrite(pkt.data, 1, pkt.size, f_out);


  121.             av_free_packet(&pkt);
  122.         }
  123.     }


  124.     /* get the delayed frames */
  125.     for (got_output = 1; got_output; i++) {
  126.         fflush(stdout);


  127.         ret = avcodec_encode_video2(c, &pkt, NULL, &got_output);
  128.         if (ret < 0) {
  129.             fprintf(stderr, "Error encoding frame\n");
  130.             exit(1);
  131.         }
  132.         if (got_output) {
  133.             printf("Write frame %3d (size=%5d)\n", i, pkt.size);
  134.             fwrite(pkt.data, 1, pkt.size, f_out);
  135.             av_free_packet(&pkt);
  136.         }
  137.     }


  138.     /* add sequence end code to have a real mpeg file */
  139.     fwrite(endcode, 1, sizeof(endcode), f_out);
  140.     fclose(f_in);
  141.     fclose(f_out);


  142.     avcodec_close(c);
  143.     av_free(c);
  144.     av_freep(&frame->data[0]);
  145.     av_frame_free(&frame);
  146.     printf("\n");
  147. }




  148. int main(int argc, char **argv)
  149. {
  150.     /* register all the codecs */
  151.     avcodec_register_all();


  152.     if (argc != 3) {
  153.         av_log(NULL, AV_LOG_ERROR, "Usage: %s \n", argv[0]);
  154.         return 1;
  155.     }


  156.     video_encode(argv[1] ,argv[2], AV_CODEC_ID_H264);


  157.     return 0;
  158. }

2. 动态链接库的编译命令
编译命令:
$ gcc yuv2h264.c -g -Wall -o  yuv2h264  -I/opt/PJT_transcode_in_jdh/ffmpeg/install/include 
-L/opt/PJT_transcode_in_jdh/ffmpeg/install/lib -lavformat -lavdevice -lavcodec  -lavutil -lavfilter 
-pthread -ldl -lswscale -lbz2 -lfaac -lx264 -lz -lm 


3. 静态链接库的编码命令
$ gcc yuv2h264.c -static -g -Wall -o yuv2h264 -I/opt/PJT_transcode_in_jdh/ffmpeg/install/include 
-L/opt/PJT_transcode_in_jdh/ffmpeg/install/lib -lavformat -lavdevice -lavcodec  -lavutil -lavfilter 
-pthread -ldl -lswscale -lbz2 -lfaac -lx264 -lz -lm




/opt/PJT_transcode_in_jdh/ffmpeg/install/lib/libavcodec.a(opusdec.o): In function `opus_decode_flush':
/opt/PJT_transcode_in_jdh/ffmpeg/ffmpeg-2.4.3/libavcodec/opusdec.c:557: undefined reference to `swr_close'
/opt/PJT_transcode_in_jdh/ffmpeg/install/lib/libavcodec.a(opusdec.o): In function `opus_decode_close':
/opt/PJT_transcode_in_jdh/ffmpeg/ffmpeg-2.4.3/libavcodec/opusdec.c:579: undefined reference to `swr_free'
/opt/PJT_transcode_in_jdh/ffmpeg/install/lib/libavcodec.a(opusdec.o): In function `opus_decode_init':
/opt/PJT_transcode_in_jdh/ffmpeg/ffmpeg-2.4.3/libavcodec/opusdec.c:629: undefined reference to `swr_alloc'
/opt/PJT_transcode_in_jdh/ffmpeg/install/lib/libavcodec.a(opusdec.o): In function `opus_decode_subpacket':
/opt/PJT_transcode_in_jdh/ffmpeg/ffmpeg-2.4.3/libavcodec/opusdec.c:376: undefined reference to `swr_is_initialized'
/opt/PJT_transcode_in_jdh/ffmpeg/install/lib/libavcodec.a(opusdec.o): In function `opus_decode_frame':
/opt/PJT_transcode_in_jdh/ffmpeg/ffmpeg-2.4.3/libavcodec/opusdec.c:222: undefined reference to `swr_is_initialized'
/opt/PJT_transcode_in_jdh/ffmpeg/install/lib/libavcodec.a(opusdec.o): In function `opus_init_resample':
/opt/PJT_transcode_in_jdh/ffmpeg/ffmpeg-2.4.3/libavcodec/opusdec.c:163: undefined reference to `swr_init'
/opt/PJT_transcode_in_jdh/ffmpeg/ffmpeg-2.4.3/libavcodec/opusdec.c:169: undefined reference to `swr_convert'
/opt/PJT_transcode_in_jdh/ffmpeg/install/lib/libavcodec.a(opusdec.o): In function `opus_decode_frame':
/opt/PJT_transcode_in_jdh/ffmpeg/ffmpeg-2.4.3/libavcodec/opusdec.c:236: undefined reference to `swr_convert'
/opt/PJT_transcode_in_jdh/ffmpeg/install/lib/libavcodec.a(opusdec.o): In function `opus_flush_resample':
/opt/PJT_transcode_in_jdh/ffmpeg/ffmpeg-2.4.3/libavcodec/opusdec.c:117: undefined reference to `swr_convert'
/opt/PJT_transcode_in_jdh/ffmpeg/install/lib/libavcodec.a(opusdec.o): In function `opus_decode_subpacket':
/opt/PJT_transcode_in_jdh/ffmpeg/ffmpeg-2.4.3/libavcodec/opusdec.c:408: undefined reference to `swr_close'
/opt/PJT_transcode_in_jdh/ffmpeg/install/lib/libavutil.a(time.o): In function `av_gettime_relative':
/opt/PJT_transcode_in_jdh/ffmpeg/ffmpeg-2.4.3/libavutil/time.c:60: undefined reference to `clock_gettime'
collect2: ld returned 1 exit status


需要添加libswresampe库:
$ gcc yuv2h264.c -static -g -Wall -o yuv2h264 -I/opt/PJT_transcode_in_jdh/ffmpeg/install/include 
-L/opt/PJT_transcode_in_jdh/ffmpeg/install/lib -lavformat -lavdevice -lavcodec  -lavutil -lavfilter 
-pthread -ldl -lswscale -lbz2 -lfaac -lx264 -lz -lm -lswresample 
   
/opt/PJT_transcode_in_jdh/ffmpeg/install/lib/libavutil.a(time.o): In function `av_gettime_relative':
/opt/PJT_transcode_in_jdh/ffmpeg/ffmpeg-2.4.3/libavutil/time.c:60: undefined reference to `clock_gettime'
collect2: ld returned 1 exit status


需要添加lrt
$ gcc yuv2h264.c -static -g -Wall -o yuv2h264 -I/opt/PJT_transcode_in_jdh/ffmpeg/install/include 
-L/opt/PJT_transcode_in_jdh/ffmpeg/install/lib -lavformat -lavdevice -lavcodec  -lavutil -lavfilter 
-pthread -ldl -lswscale -lbz2 -lfaac -lx264 -lz -lm  -lswresample -lrt
阅读(843) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~