FFmpeg_编译支持h264编码的ffmpeg,并验证

系统环境:ubuntu16.04
FFmpeg:4.1
x264:http://download.videolan.org/x264/snapshots/
nasm:2.13.03
yasm:1.3.0

一、编译nasm、yasm
在第一次编译ffmpeg和x264时,分别报了yasm和nasm相关的错误,解决办法就是编译安装相关库或者在编译ffmpeg和x264库时禁用,编译方法如下:
1、进入源文件目录,执行
./configure --prefix=/usr/local/ffmpeg_build/yasm
make
make install
2、进入源文件目录,执行
./configure --prefix=/usr/local/ffmpeg_build/nasm
make
make install
注意:需要在.bashrc中添加export PATH=$PATH:/usr/local/ffmpeg_build/yasm/bin:/usr/local/ffmpeg_build/nasm/bin
二、编译x264
首先进入x264的source目录,配置如下:
./configure --prefix=/usr/local/ffmpeg_build/x264 --enable-shared --enable-static
然后:
make
sudo make install
三、编译ffmpeg
./configure --prefix=/usr/local/ffmpeg_build/ffmpeg --enable-gpl --enable-version3 --enable-nonfree --enable-pthreads --enable-libx264 --enable-shared --extra-cflags=-I/usr/local/ffmpeg_build/x264/include --extra-ldflags=-L/usr/local/ffmpeg_build/x264/lib
make
sudo make install

测试代码基本来自于雷霄骅前辈(使用ffmpeg版本不同,yuv视频格式不同等)

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>

#include "libavdevice/avdevice.h"
#include "libavutil/pixfmt.h"
#include "libswscale/swscale.h"
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libavutil/time.h"
#include "libswresample/swresample.h" 
#include<stdio.h>

#define OUTWIDTH 640
#define OUTHEIGHT 480
#define FPS 25
#define AV_CODEC_FLAG_GLOBAL_HEADER   (1 << 22)
#define CODEC_FLAG_GLOBAL_HEADER AV_CODEC_FLAG_GLOBAL_HEADER

int flush_encoder(AVFormatContext *fmt_ctx, unsigned int stream_index)
{
  int ret;
  int got_frame;
  AVPacket enc_pkt;
  if (!(fmt_ctx->streams[stream_index]->codec->codec->capabilities &
      AV_CODEC_CAP_DELAY))
      return 0;
  while (1) {
      enc_pkt.data = NULL;
      enc_pkt.size = 0;
      av_init_packet(&enc_pkt);
      ret = avcodec_encode_video2 (fmt_ctx->streams[stream_index]->codec, &enc_pkt,
        NULL, &got_frame);
      av_frame_free(NULL);
      if (ret < 0)
          break;
      if (!got_frame){
          ret=0;
          break;
      }
      printf("Flush Encoder: Succeed to encode 1 frame!\tsize:%5d\n",enc_pkt.size);
      /* mux encoded frame */
      ret = av_write_frame(fmt_ctx, &enc_pkt);
      if (ret < 0)
          break;
  }
  return ret;
}

 
int main()
{
    AVFormatContext *     pFormatCtx = NULL;
    AVCodecContext *      pVCodecCtx = NULL;
    AVCodec *             pVCodec = NULL;
    AVCodec *             pVCodecEn = NULL;
    AVCodecContext *      pACodecCtx = NULL;
    AVCodec *             pACodec = NULL;
    AVFrame  *            pFrame = NULL;
    AVPacket              packet;
    AVPacket              pkt;
    AVStream *            pAVstream = NULL;
    AVCodecContext *      pVCodecCtxEn = NULL;
    enum AVPixelFormat    pixFormat = 0;
    struct SwsContext *   pSwsCtx = NULL;
    unsigned char*        out_buffer_rgb;

    int videoindex = -1;
    int audioindex = 0;
    int sampleRate = 0;
    int sampleSize = 0;
    int channel = 0;
    int gotPicture = 0;
    int i = 0;
    int ret = 0;
    int framecnt = 0;

    enum AVPixelFormat dst_pix_fmt = AV_PIX_FMT_YUV422P;
    const char *dst_size = NULL;  
    const char *src_size = NULL;  
    uint8_t *src_data[4];   
    uint8_t *dst_data[4];  
    int src_linesize[4];  
    int dst_linesize[4];  
    int src_bufsize = 0;  
    int dst_bufsize = 0;  
    int src_w = 0;  
    int src_h = 0;  
    int dst_w = 0;
    int dst_h = 0;
    int got_output = 0;
    int picture_size = 0;
    uint8_t *picture_buf;


    FILE *in_file = fopen("out_plant.yuv", "rb");       //Input raw YUV data
    int in_w=640,in_h=480;                              //Input data's width and height
    int framenum=200;                                   //Frames to encode
    const char* out_file = "out_plant.h264";

    av_register_all();
    pFormatCtx = avformat_alloc_context();
    pFormatCtx->oformat = av_guess_format(NULL, out_file, NULL);

    //(1)register device
    avdevice_register_all();

    //Open output URL
    if (avio_open(&pFormatCtx->pb,out_file, AVIO_FLAG_READ_WRITE) < 0){
      printf("Failed to open output file! \n");
      return -1;
    }
    
    //(b)init AVSteam
    pAVstream = avformat_new_stream(pFormatCtx, pVCodecEn);
    if(pAVstream == NULL)
        printf("Create stream error!");
    //pAVstream->id = pFormatCtx->nb_streams - 1;

    //(c)set AVCodecContext param
    pVCodecCtxEn = pAVstream->codec;
    avcodec_get_context_defaults3(pVCodecCtxEn, pVCodecEn);
    pVCodecCtxEn->codec_id  = AV_CODEC_ID_H264;
    pVCodecCtxEn->width     = OUTWIDTH;
    pVCodecCtxEn->height    = OUTHEIGHT;
    pVCodecCtxEn->time_base.den = FPS; //分母
    pVCodecCtxEn->time_base.num = 1;  //分子
    pVCodecCtxEn->pix_fmt    = AV_PIX_FMT_YUV422P;
    pVCodecCtxEn->codec_type = AVMEDIA_TYPE_VIDEO;

    pVCodecCtxEn->me_range = 16;
    pVCodecCtxEn->max_qdiff = 4;
    pVCodecCtxEn->qcompress = 0.6; 
    pVCodecCtxEn->qmin = 10;
    pVCodecCtxEn->qmax = 51;
    //Optional Param
    pVCodecCtxEn->max_b_frames=3;

    if(pFormatCtx->oformat->flags & AVFMT_GLOBALHEADER)
        pVCodecCtxEn->flags|= CODEC_FLAG_GLOBAL_HEADER;

    //(d)set AVOptions param
    av_opt_set(pVCodecCtxEn->priv_data, "preset", "slow", 0);
    av_opt_set(pVCodecCtxEn->priv_data, "tune","zerolatency",0);
    av_opt_set(pVCodecCtxEn->priv_data, "x264opts","crf=26:vbv-maxrate=728:vbv-bufsize=3640:keyint=25",0);
    avcodec_parameters_from_context(pAVstream->codecpar, pVCodecCtxEn);

    //Show some Information
    av_dump_format(pFormatCtx, 0, out_file, 1);

    if(pFrame == NULL)
      pFrame = av_frame_alloc();

    picture_size = avpicture_get_size(pVCodecCtxEn->pix_fmt, pVCodecCtxEn->width, pVCodecCtxEn->height);
    picture_buf = (uint8_t *)av_malloc(picture_size);
    avpicture_fill((AVPicture *)pFrame, picture_buf, pVCodecCtxEn->pix_fmt, pVCodecCtxEn->width, pVCodecCtxEn->height);

    //(e)打开编码器
    pVCodecEn = avcodec_find_encoder(AV_CODEC_ID_H264);
    if(pVCodecEn == NULL)
        printf("Find encoder error!");
    avcodec_open2(pVCodecCtxEn, pVCodecEn, NULL);

    //写入数据流的头部
    avformat_write_header(pFormatCtx, NULL);    
    av_new_packet(&pkt,picture_size);
 
    int y_size = pVCodecCtxEn->width * pVCodecCtxEn->height;

    //(5)get one frame
    for (int i=0; i<framenum; i++){
        //Read raw YUV data
        if (fread(picture_buf, 1, y_size*2, in_file) <= 0){
            printf("Failed to read raw data! \n");
            return -1;
        }else if(feof(in_file)){
            break;
        }
        pFrame->data[0] = picture_buf;              // Y
        pFrame->data[1] = picture_buf+ y_size;      // U 
        pFrame->data[2] = picture_buf+ y_size*3/2;  // V

        //PTS
        //pFrame->pts=i;
        pFrame->pts=i*(pAVstream->time_base.den)/((pAVstream->time_base.num)*25);
        pFrame->format = pVCodecCtxEn->pix_fmt;
        pFrame->width = pVCodecCtxEn->width;
        pFrame->height =  pVCodecCtxEn->height;
        int got_picture=0;
        //Encode
        int ret = avcodec_encode_video2(pVCodecCtxEn, &pkt,pFrame, &got_picture);
        if(ret < 0){
          printf("Failed to encode! \n");
          return -1;
        }
        if (got_picture==1){
          printf("Succeed to encode frame: %5d\tsize:%5d\n",framecnt,pkt.size);
          framecnt++;
          pkt.stream_index = pAVstream->index;
          ret = av_write_frame(pFormatCtx, &pkt);
          av_free_packet(&pkt);
        }
    }

    //Flush Encoder
    ret = flush_encoder(pFormatCtx,0);
    if (ret < 0) {
      printf("Flushing encoder failed\n");
      return -1;
    }

    //Write file trailer
    av_write_trailer(pFormatCtx);

    //Clean
    if (pAVstream){
      avcodec_close(pAVstream->codec);
      av_free(pFrame);
      av_free(picture_buf);
    }
    avio_close(pFormatCtx->pb);
    avformat_free_context(pFormatCtx);

    fclose(in_file);
        
    return 0;  
}

执行过程及结果(共编码200帧图像):

muyangren@muyangren-N85-87HP6:~/projectdir/ffmpeg/ffmpeg_toh264$ ./ffmpeg_toh264 
Output #0, h264, to 'out_plant.h264':
    Stream #0:0: Video: h264, yuv422p, 640x480, q=10-51, 128 kb/s, 25 tbc
[libx264 @ 0x82e200] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2
[libx264 @ 0x82e200] profile High 4:2:2, level 3.0, 4:2:2, 8-bit
Succeed to encode frame:     0	size: 8221
Succeed to encode frame:     1	size: 9006
Succeed to encode frame:     2	size: 1764
Succeed to encode frame:     3	size:  464
Succeed to encode frame:     4	size:  514
Succeed to encode frame:     5	size:36064
Succeed to encode frame:     6	size: 3285
Succeed to encode frame:     7	size: 2481
Succeed to encode frame:     8	size: 5131
Succeed to encode frame:     9	size:30492
Succeed to encode frame:    10	size:16233
Succeed to encode frame:    11	size:10406
Succeed to encode frame:    12	size:10084
Succeed to encode frame:    13	size:104457
Succeed to encode frame:    14	size:81313
Succeed to encode frame:    15	size:70437
Succeed to encode frame:    16	size:70868
Succeed to encode frame:    17	size:121538
Succeed to encode frame:    18	size:96800
Succeed to encode frame:    19	size:77992
Succeed to encode frame:    20	size:95682
Succeed to encode frame:    21	size:98927
Succeed to encode frame:    22	size:108962
Succeed to encode frame:    23	size:100945
Succeed to encode frame:    24	size:99991
Succeed to encode frame:    25	size:120900
Succeed to encode frame:    26	size:107744
Succeed to encode frame:    27	size:100738
Succeed to encode frame:    28	size:101717
Succeed to encode frame:    29	size:122759
Succeed to encode frame:    30	size:110856
Succeed to encode frame:    31	size:101093
Succeed to encode frame:    32	size:99972
Succeed to encode frame:    33	size:132027
Succeed to encode frame:    34	size:104074
Succeed to encode frame:    35	size:99740
Succeed to encode frame:    36	size:99362
Succeed to encode frame:    37	size:122959
Succeed to encode frame:    38	size:110299
Succeed to encode frame:    39	size:100714
Succeed to encode frame:    40	size:101045
Succeed to encode frame:    41	size:122487
Succeed to encode frame:    42	size:110026
Succeed to encode frame:    43	size:99191
Succeed to encode frame:    44	size:100115
Succeed to encode frame:    45	size:131804
Succeed to encode frame:    46	size:111281
Succeed to encode frame:    47	size:99628
Succeed to encode frame:    48	size:99923
Succeed to encode frame:    49	size:122581
Succeed to encode frame:    50	size:109921
Succeed to encode frame:    51	size:101580
Succeed to encode frame:    52	size:101668
Succeed to encode frame:    53	size:122770
Succeed to encode frame:    54	size:110749
Succeed to encode frame:    55	size:101419
Succeed to encode frame:    56	size:100875
Succeed to encode frame:    57	size:132096
Succeed to encode frame:    58	size:108970
Succeed to encode frame:    59	size:99827
Succeed to encode frame:    60	size:102186
Succeed to encode frame:    61	size:118839
Succeed to encode frame:    62	size:106438
Succeed to encode frame:    63	size:101507
Succeed to encode frame:    64	size:97485
Succeed to encode frame:    65	size:121102
Succeed to encode frame:    66	size:113450
Succeed to encode frame:    67	size:100217
Succeed to encode frame:    68	size:101289
Succeed to encode frame:    69	size:132923
Succeed to encode frame:    70	size:108032
Succeed to encode frame:    71	size:101016
Succeed to encode frame:    72	size:98123
Succeed to encode frame:    73	size:121372
Succeed to encode frame:    74	size:110457
Succeed to encode frame:    75	size:98263
Succeed to encode frame:    76	size:100309
Succeed to encode frame:    77	size:122598
Succeed to encode frame:    78	size:105808
Succeed to encode frame:    79	size:101203
Succeed to encode frame:    80	size:99721
Succeed to encode frame:    81	size:133043
Succeed to encode frame:    82	size:108716
Succeed to encode frame:    83	size:100727
Succeed to encode frame:    84	size:99229
Succeed to encode frame:    85	size:120559
Succeed to encode frame:    86	size:109741
Succeed to encode frame:    87	size:98506
Succeed to encode frame:    88	size:99125
Succeed to encode frame:    89	size:118353
Succeed to encode frame:    90	size:111846
Succeed to encode frame:    91	size:101565
Succeed to encode frame:    92	size:102864
Succeed to encode frame:    93	size:133425
Succeed to encode frame:    94	size:106613
Succeed to encode frame:    95	size:99064
Succeed to encode frame:    96	size:101341
Succeed to encode frame:    97	size:118688
Succeed to encode frame:    98	size:110149
Succeed to encode frame:    99	size:100259
Succeed to encode frame:   100	size:102103
Succeed to encode frame:   101	size:116659
Succeed to encode frame:   102	size:101508
Succeed to encode frame:   103	size:96535
Succeed to encode frame:   104	size:95929
Succeed to encode frame:   105	size:126513
Succeed to encode frame:   106	size:103438
Succeed to encode frame:   107	size:96130
Succeed to encode frame:   108	size:98043
Succeed to encode frame:   109	size:116981
Succeed to encode frame:   110	size:106913
Succeed to encode frame:   111	size:99902
Succeed to encode frame:   112	size:98440
Succeed to encode frame:   113	size:116805
Succeed to encode frame:   114	size:106101
Succeed to encode frame:   115	size:100754
Succeed to encode frame:   116	size:101055
Succeed to encode frame:   117	size:125945
Succeed to encode frame:   118	size:104980
Succeed to encode frame:   119	size:99646
Succeed to encode frame:   120	size:99337
Succeed to encode frame:   121	size:115403
Succeed to encode frame:   122	size:107429
Succeed to encode frame:   123	size:100735
Succeed to encode frame:   124	size:100003
Succeed to encode frame:   125	size:118311
Succeed to encode frame:   126	size:109707
Succeed to encode frame:   127	size:99798
Succeed to encode frame:   128	size:105469
Succeed to encode frame:   129	size:138952
Succeed to encode frame:   130	size:125012
Succeed to encode frame:   131	size:119121
Succeed to encode frame:   132	size:119369
Succeed to encode frame:   133	size:134233
Succeed to encode frame:   134	size:123969
Succeed to encode frame:   135	size:118485
Succeed to encode frame:   136	size:113174
Succeed to encode frame:   137	size:131688
Succeed to encode frame:   138	size:119397
Succeed to encode frame:   139	size:113753
Succeed to encode frame:   140	size:109263
Succeed to encode frame:   141	size:137466
Succeed to encode frame:   142	size:120664
Succeed to encode frame:   143	size:110717
Succeed to encode frame:   144	size:110870
Succeed to encode frame:   145	size:131404
Succeed to encode frame:   146	size:122188
Succeed to encode frame:   147	size:113175
Succeed to encode frame:   148	size:113295
Succeed to encode frame:   149	size:127729
Succeed to encode frame:   150	size:119558
Succeed to encode frame:   151	size:112632
Succeed to encode frame:   152	size:112992
Succeed to encode frame:   153	size:132495
Succeed to encode frame:   154	size:114782
Succeed to encode frame:   155	size:111014
Succeed to encode frame:   156	size:109319
Succeed to encode frame:   157	size:121903
Succeed to encode frame:   158	size:112150
Succeed to encode frame:   159	size:109138
Succeed to encode frame:   160	size:107309
Succeed to encode frame:   161	size:122856
Succeed to encode frame:   162	size:111643
Succeed to encode frame:   163	size:106370
Succeed to encode frame:   164	size:107580
Succeed to encode frame:   165	size:135754
Succeed to encode frame:   166	size:119013
Succeed to encode frame:   167	size:111259
Succeed to encode frame:   168	size:109008
Succeed to encode frame:   169	size:126156
Succeed to encode frame:   170	size:118951
Succeed to encode frame:   171	size:108586
Succeed to encode frame:   172	size:112581
Succeed to encode frame:   173	size:122728
Succeed to encode frame:   174	size:117275
Succeed to encode frame:   175	size:111313
Succeed to encode frame:   176	size:109611
Succeed to encode frame:   177	size:126414
Succeed to encode frame:   178	size:113918
Succeed to encode frame:   179	size:109472
Succeed to encode frame:   180	size:109342
Succeed to encode frame:   181	size:125230
Succeed to encode frame:   182	size:115638
Succeed to encode frame:   183	size:109199
Succeed to encode frame:   184	size:111231
Succeed to encode frame:   185	size:126982
Succeed to encode frame:   186	size:118327
Flush Encoder: Succeed to encode 1 frame!	size:111735
Flush Encoder: Succeed to encode 1 frame!	size:113697
Flush Encoder: Succeed to encode 1 frame!	size:132893
Flush Encoder: Succeed to encode 1 frame!	size:110890
Flush Encoder: Succeed to encode 1 frame!	size:107830
Flush Encoder: Succeed to encode 1 frame!	size:108678
Flush Encoder: Succeed to encode 1 frame!	size:126643
Flush Encoder: Succeed to encode 1 frame!	size:115959
Flush Encoder: Succeed to encode 1 frame!	size:113816
Flush Encoder: Succeed to encode 1 frame!	size:108753
Flush Encoder: Succeed to encode 1 frame!	size:115985
Flush Encoder: Succeed to encode 1 frame!	size:118184
Flush Encoder: Succeed to encode 1 frame!	size:112657
[libx264 @ 0x82e200] frame I:17    Avg QP:12.11  size:117023
[libx264 @ 0x82e200] frame P:34    Avg QP:10.79  size:116021
[libx264 @ 0x82e200] frame B:149   Avg QP:11.46  size: 99926
[libx264 @ 0x82e200] consecutive B-frames:  0.5%  0.0%  1.5% 98.0%
[libx264 @ 0x82e200] mb I  I16..4:  8.2% 45.3% 46.5%
[libx264 @ 0x82e200] mb P  I16..4:  5.3% 34.0% 24.1%  P16..4: 16.3% 12.0%  6.2%  0.0%  0.0%    skip: 2.2%
[libx264 @ 0x82e200] mb B  I16..4:  2.5% 22.4% 13.3%  B16..8: 21.5% 13.2%  4.8%  direct:16.9%  skip: 5.4%  L0:20.5% L1:21.5% BI:58.1%
[libx264 @ 0x82e200] final ratefactor: -10.58
[libx264 @ 0x82e200] 8x8 transform intra:55.2% inter:23.0%
[libx264 @ 0x82e200] coded y,uvDC,uvAC intra: 98.3% 98.3% 97.8% inter: 77.2% 88.6% 86.3%
[libx264 @ 0x82e200] i16 v,h,dc,p: 10%  3% 13% 74%
[libx264 @ 0x82e200] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 12% 10% 22%  7% 10% 10% 10%  8% 10%
[libx264 @ 0x82e200] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu:  9% 11% 13%  9% 13% 11% 16%  8% 11%
[libx264 @ 0x82e200] i8c dc,h,v,p: 80%  2%  4% 13%
[libx264 @ 0x82e200] Weighted P-Frames: Y:17.6% UV:14.7%
[libx264 @ 0x82e200] kb/s:5.78

使用ffplay播放,编码得到的x264文件:
在这里插入图片描述
支持x264编码的ffmpeg相关源码包,上传资源为:ffmpeg_with_x264.tar.gz

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值