1
votes

Using libavcodec 57.107.100, I have some code to encode frames into H.264 and I'm working on tweaking the settings to prep resulting videos to be streamed with DASH, which requires consistent keyframe timings. So I'm setting the GOP to 4x the framerate and setting the keyint_min to the same as the GOP so that I can guarantee that the keyframe interval lines up with the 4 second segment boundaries.

I'm using the following code to build the AVCodec and AVCodecContext:

AVCodec* codec = NULL;
codec = avcodec_find_encoder_by_name("libx264");
AVCodecContext* avcodec_context = avcodec_alloc_context3(codec);
context->bit_rate = 200000;
context->height = 640;
context->width = 480;
context->keyint_min = 100;
context->gop_size = 100;
context->qmax = 31;
context->qmin = 2;
context->pix_fmt = AV_PIX_FMT_YUV420P;
context->time_base = (AVRational) {1, 25};

Clearly, the keyint_min is 100 here, yet when I execute my program, the stderr output from libavcodec says this when the encoding starts:

[libx264 @ 0x5577bde61f20] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 BMI2 
AVX2
[libx264 @ 0x5577bde61f20] profile High, level 3.0
[libx264 @ 0x5577bde61f20] 264 - core 152 r2854 e9a5903 - H.264/MPEG-4 AVC codec - Copyleft 2003-2017 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=12 lookahead_threads=2 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=100 keyint_min=51 scenecut=40 intra_refresh=0 rc_lookahead=40 rc=abr mbtree=1 bitrate=200 ratetol=1.0 qcomp=0.60 qpmin=2 qpmax=31 qpstep=4 ip_ratio=1.40 aq=1:1.00

For emphasis, in the third line of that blurb, the encoder says keyint=100 keyint_min=51. So obviously my GOP is being set correctly at 100, but the keyint_min is not being respected. Since the FFMPEG docs are pretty difficult to approach, I haven't been able to find an answer to this. Does anyone know what I'm missing?

1

1 Answers

2
votes

The x264 encoder will clamp keyint_min to keyint/2+1

Pass an option directly to x264 to avoid premature IDR frames

e.g.

av_opt_set(context->priv_data, "x264opts", "no-scenecut", 0);

or

context->scenechange_threshold = 0;