Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to encode h.264 with libavcodec/x264?

Tags:

I am attempting to encode video using libavcodec/libavformat. Audio works great, but when I try to encode video I get the following errors:

[libx264 @ 0x10182a000]broken ffmpeg default settings detected   [libx264 @ 0x10182a000]use an encoding preset (vpre)   

easy to fix using the command line ffmpeg, but I am trying to do this in C. my options are

AVStream *pVideoOutStream = av_new_stream(pOutFormatCtx, 0);   AVCodecContext *pVideoOutCodecCtx  = pVideoOutStream->codec;    pVideoOutCodecCtx->codec_id        = CODEC_ID_H264;     pVideoOutCodecCtx->codec_type      = CODEC_TYPE_VIDEO;   pVideoOutCodecCtx->bit_rate        = pVideoInCodecCtx->bit_rate;   pVideoOutCodecCtx->width           = pVideoInCodecCtx->width;     pVideoOutCodecCtx->height          = pVideoInCodecCtx->height;   pVideoOutCodecCtx->pix_fmt         = pVideoInCodecCtx->pix_fmt;     pVideoOutCodecCtx->sample_rate     = pVideoInCodecCtx->sample_rate;     pVideoOutCodecCtx->gop_size        = 30;   

but avcodec_open() fails.

What other values do I need to set to make x264 happy?

like image 385
szatmary Avatar asked Aug 24 '10 01:08

szatmary


People also ask

Is x264 the same as H 264?

x264 is a free software library and application for encoding video streams into the H. 264/MPEG-4 AVC compression format, and is released under the terms of the GNU GPL.

How do I encode a video in H 264?

At the bottom, open drop-down menu beside Output Format and choose the desired output format from the Video tab. Then, to the video resolution, click the edit icon to open the Setting window. Here choose H264 from Encoder tab under the Video option and click Create.

What is x264 video codec?

x264 is a free and open-source software library and a command-line utility developed by VideoLAN for encoding video streams into the H. 264/MPEG-4 AVC video coding format. It is released under the terms of the GNU General Public License.


2 Answers

Don't forget to use x264 private options. You can always set a profile:

av_dict_set(&This->opts, "vprofile", "baseline", 0) 

Or set the lowest encoding latency:

av_dict_set(&This->opts, "tune", "zerolatency", 0); 

Or select a preset:

av_dict_set(&This->opts, "preset","ultrafast",0); 

Before opening a codec

avcodec_open2(This->context, This->codec, &This->opts) 
like image 200
Sergey Skopus Avatar answered Oct 20 '22 15:10

Sergey Skopus


The following is how to interpret the ffmpeg's x264 presets.

Unfortunately I don't know of an easy way to import the presets like ffmpeg does. You can lookup the x264 preset values which are all stored in /usr/local/share/ffmpeg/libx264-{name}.ffpreset, where {name} is specified for ffmpeg as the -vpre {name} command-line argument. So typically ffmpeg would include libx264-medium.ffpreset and then libx264-main.ffpreset, specified as ffmpeg -vpre medium -vpre main

You can lookup all the options (as defined in the libx264-{name}.ffpreset files) to get their structure names by looking in the libavcodec/options.c file, which can be found in the ffmpeg SVN repositories.

Here's how the medium and main presets would be translated into C code:

// libx264-medium.ffpreset preset ctx->coder_type = 1;  // coder = 1 ctx->flags|=CODEC_FLAG_LOOP_FILTER;   // flags=+loop ctx->me_cmp|= 1;  // cmp=+chroma, where CHROMA = 1 ctx->partitions|=X264_PART_I8X8+X264_PART_I4X4+X264_PART_P8X8+X264_PART_B8X8; // partitions=+parti8x8+parti4x4+partp8x8+partb8x8 ctx->me_method=ME_HEX;    // me_method=hex ctx->me_subpel_quality = 7;   // subq=7 ctx->me_range = 16;   // me_range=16 ctx->gop_size = 250;  // g=250 ctx->keyint_min = 25; // keyint_min=25 ctx->scenechange_threshold = 40;  // sc_threshold=40 ctx->i_quant_factor = 0.71; // i_qfactor=0.71 ctx->b_frame_strategy = 1;  // b_strategy=1 ctx->qcompress = 0.6; // qcomp=0.6 ctx->qmin = 10;   // qmin=10 ctx->qmax = 51;   // qmax=51 ctx->max_qdiff = 4;   // qdiff=4 ctx->max_b_frames = 3;    // bf=3 ctx->refs = 3;    // refs=3 ctx->directpred = 1;  // directpred=1 ctx->trellis = 1; // trellis=1 ctx->flags2|=CODEC_FLAG2_BPYRAMID+CODEC_FLAG2_MIXED_REFS+CODEC_FLAG2_WPRED+CODEC_FLAG2_8X8DCT+CODEC_FLAG2_FASTPSKIP;  // flags2=+bpyramid+mixed_refs+wpred+dct8x8+fastpskip ctx->weighted_p_pred = 2; // wpredp=2  // libx264-main.ffpreset preset ctx->flags2|=CODEC_FLAG2_8X8DCT;c->flags2^=CODEC_FLAG2_8X8DCT;    // flags2=-dct8x8 

You'll have to look at the ffmpeg source code if you want to parse those presets automatically.

I hope that the information I just gave would help you out a bit more :)

like image 34
Pada Avatar answered Oct 20 '22 15:10

Pada