Adaptive bitrate support

Issue #95 resolved
Former user created an issue

Hi,

We are trying to transcode several renditions using ffmpeg/libx265 that should be used for adaptive streaming (e.g. a 2K rendition and a 4K rendition). For this reason, to enable smooth switching between the different renditions, we'd like to have key frames at fixed intervals (every 2 seconds). According to what we saw, libx265 does not support currently force key frames, so we deferred to disable scenecuts and use keyint to specify the GOP size. This seems to produce key frames whose PTS values are exactly 2 seconds apart (0, 2, 4, etc.), but the DTS values have some kind of jitter that is not constant between the different renditions. We suspect this jitter is causing us flicker during bitrate switches.

Here's an example:

2K rendition: ffmpeg -i /web//content/r71v1/entry/data/354/938/0_q2c0h6lh_0_fjv3m2g6_12.mp4 -c:v libx265 -pix_fmt yuv420p -aspect 1920:1080 -b:v 2000k -s 1920x1080 -r 30 -g 60 -c:a libfdk_aac -b:a 128k -ar 44100 -f mp4 -x265-params keyint=60:min-keyint=1:scenecut=0 -y /web/content/r71v1/entry/data/178/879/0_njeqv2e8_0_123fdkbb_32.mp4

root@pa-reports ~# /web/content/shared/bin/ffmpeg-2.2-bin/ffprobe-2.2.sh -i /web/content/r71v1/entry/data/178/879/0_njeqv2e8_0_123fdkbb_32.mp4 -show_packets -select_streams v 2>/dev/null | grep -e ^flags= -e ^dts | grep -B1 flags=K | grep -v '^-' | grep -v flags | head dts_time=-0.066667 dts_time=1.800000 dts_time=3.866667 dts_time=5.800000 dts_time=7.900000 dts_time=9.800000 dts_time=11.800000 dts_time=13.866667 dts_time=15.800000 dts_time=17.866667

4K rendition: ffmpeg -i /web//content/r71v1/entry/data/354/938/0_q2c0h6lh_0_fjv3m2g6_12.mp4 -c:v libx265 -pix_fmt yuv420p -aspect 3840:2160 -b:v 8000k -s 3840x2160 -r 30 -g 60 -c:a libfdk_aac -b:a 128k -ar 44100 -f mp4 -x265-params keyint=60:min-keyint=1:scenecut=0 -y /web/content/r71v1/entry/data/178/879/0_njeqv2e8_0_pzo6s00u_21.mp4

root@pa-reports ~# /web/content/shared/bin/ffmpeg-2.2-bin/ffprobe-2.2.sh -i /web/content/r71v1/entry/data/178/879/0_njeqv2e8_0_pzo6s00u_21.mp4 -show_packets -select_streams v 2>/dev/null | grep -e ^flags= -e ^dts | grep -B1 flags=K | grep -v '^-' | grep -v flags | head dts_time=-0.066667 dts_time=1.800000 dts_time=3.866667 dts_time=5.800000 dts_time=7.900000 dts_time=9.900000 dts_time=11.866667 dts_time=13.800000 dts_time=15.800000 dts_time=17.933333

notice how the DTS values are not exactly 2 seconds apart, and that they are not the same between the 2 renditions (e.g. 9.9 vs. 9.8)

When we work with libx264 we use -force_key_frames 0,2,4,6... and we get DTS values that are exactly 2 seconds apart and the non-scene-cut key frames are consistent between renditions. e.g.: ffmpeg -threads 1 -i /web//content/r71v1/entry/data/385/684/0_i1uzxuvn_0_4nk79lnm_2.mp4 -c:v libx264 -subq 7 -qcomp 0.6 -qmin 10 -qmax 50 -qdiff 4 -bf 16 -coder 1 -refs 6 -x264opts b-pyramid:weightb:mixed-refs:8x8dct:no-fast-pskip=0 -vprofile high -force_key_frames 0,2,4,6,8,10,12,14,16,18,20,22,24,26,... -pix_fmt yuv420p -b:v 2500k -s 1280x720 -r 25 -g 50 -c:a libfdk_aac -filter_complex 'aresample=async=1:min_hard_comp=0.100000:first_pts=0' -b:a 128k -ar 44100 -ac 2 -map_chapters -1 -map_metadata -1 -f mp4 -flags +loop+mv4 -cmp 256 -partitions +parti4x4+partp8x8+partb8x8 -trellis 1 -refs 6 -me_range 16 -keyint_min 20 -sc_threshold 40 -i_qfactor 0.71 -bt 700k -maxrate 2500k -bufsize 5000k -rc_eq 'blurCplx^(1-qComp)' -vsync 1 -threads 4 -y /web/content/r71v1/entry/data/385/684/0_i1uzxuvn_0_kqycardx_2.mp4

root@pa-reports ~# /web/content/shared/bin/ffmpeg-2.2-bin/ffprobe-2.2.sh -i /web/content/r71v1/entry/data/385/684/0_i1uzxuvn_0_kqycardx_2.mp4 -show_packets -select_streams v 2>/dev/null | grep -e ^flags= -e ^dts | grep -B1 flags=K | grep -v '^-' | grep -v flags | head dts_time=-0.080000 dts_time=1.920000 dts_time=3.200000 dts_time=3.920000 dts_time=5.440000 dts_time=5.920000 dts_time=6.760000 dts_time=7.920000 dts_time=8.960000 dts_time=9.920000

I indented the forced key frames, notice how they are all xx.92. Is there any solution for this ? is the support for force keyframes planned ?

Thanks,

Eran

Comments (7)

  1. Former user Account Deleted

    Thank you for your reply, this setting does indeed solve the problem.

    However, for some reason it didn't work for us with ffmpeg, only worked in CLI mode. We tried with the following ffmpeg command: ~/ffmpeg-2.4.3 -i /web//content/r71v1/entry/data/366/275/0_8ezis03x_0_f22pftdw_12.mp4 -c:v libx265 -pix_fmt yuv420p -aspect 3840:2160 -b:v 800k -s 384x216 -r 30 -g 60 -x265-params keyint=60:min-keyint=1:open-gop=0:scenecut=50:qpfile=aaa.qp -c:a libfdk_aac -b:a 128k -ar 44100 -f mp4 -t 20 -y /web/content/shared/tmp/0_8ezis03x_x265.mp4 And the qpfile parameter had no effect.

    Is there any known issue about this ? is it supposed to work ?

    Thanks,

    Eran

  2. Steve Borho

    Sorry, if you had raised this bug with ffmpeg it would have been fixed sooner. As it is, a patch has just been sent to the ffmpeg ML for it.

  3. Former user Account Deleted

    Btw, any chance you can send a link to the patch discussion in ffmpeg ? we want to try the patch as soon as possible without waiting for them to accept it...

    Thanks,

    Eran

  4. Log in to comment