1

I have a video clip I want to get the positions of all keyframes from. To achieve this, I tried running various ffmpeg/ffprobe commands, but all of them return similar output. From first 20 seconds of the video I always get keyframes at:

frame,0.000000
frame,3.000000
frame,5.000000
frame,6.416667
frame,10.000000
frame,15.000000
frame,19.041667

All of those also have the is_key value set to 1. The problem is, that the 'real' keyframes are only at intervals of 5. So of those above, the working keyframes are:

frame,0.000000
frame,5.000000
frame,10.000000
frame,15.000000

but if I try actually using other ones to, for instance, -c copy a part of video out, ffmpeg actually skips the non-idr keyframes and copies from previous keyframe to the point I requested.

Also in Avidemux if I load the file into it, the option 'jump to next/previous keyframe' only jumps between the keyframes at interval of 5.

How can I get ffmpeg/ffprobe to only return information about the usable keyframes, without knowing the file beforehand?

link to the file I worked on (it's big, but it's the only one I have right now)

https://drive.google.com/open?id=1aV3BLCrxNMhZX4uSBJzoiuNUhSm9CFap

full log output

ffprobe -loglevev verbose -skip_frame nokey -select_streams v -show_entries frame=key_frame,pkt_pts_time -of" csv=print_section=1 -read_intervals 0%+20 srcFile.mp4

ffprobe version n4.0-39-gda39990 Copyright (c) 2007-2018 the FFmpeg developers
  built with gcc 4.9.x (GCC) 20150123 (prerelease)
  configuration: --target-os=linux --cross-prefix=/root/bravobit/ffmpeg-android/toolchain-android/bin/arm-linux-androideabi- --arch=arm --cpu=cortex-a8 --enable-runtime-cpudetect --sysroot=/root/bravobit/ffmpeg-android/toolchain-android/sysroot --enable-pic --enable-libx264 --enable-ffprobe --enable-libopus --enable-libvorbis --enable-libfdk-aac --enable-libfreetype --enable-libfribidi --enable-libmp3lame --enable-fontconfig --enable-libvpx --enable-libass --enable-yasm --enable-pthreads --disable-debug --enable-version3 --enable-hardcoded-tables --disable-ffplay --disable-linux-perf --disable-doc --disable-shared --enable-static --enable-runtime-cpudetect --enable-nonfree --enable-network --enable-avresample --enable-avformat --enable-avcodec --enable-indev=lavfi --enable-hwaccels --enable-ffmpeg --enable-zlib --enable-gpl --enable-small --enable-nonfree --pkg-config=pkg-config --pkg-config-flags=--static --prefix=/root/bravobit/ffmpeg-android/build/armeabi-v7a --extra-cflags='-I/root/bravobit/ffmpeg-android/toolchain-android/include -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fno-strict-overflow -fstack-protector-all' --extra-ldflags='-L/root/bravobit/ffmpeg-android/toolchain-android/lib -Wl,-z,relro -Wl,-z,now -pie' --extra-cxxflags=
  libavutil      56. 14.100 / 56. 14.100
  libavcodec     58. 18.100 / 58. 18.100
  libavformat    58. 12.100 / 58. 12.100
  libavdevice    58.  3.100 / 58.  3.100
  libavfilter     7. 16.100 /  7. 16.100
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  1.100 /  5.  1.100
  libswresample   3.  1.100 /  3.  1.100
  libpostproc    55.  1.100 / 55.  1.100
Adding 'key_frame' to the entries to show in section 'frame'
Adding 'pkt_pts_time' to the entries to show in section 'frame'
Parsed log interval id:0 start:0 end:+20
[h264 @ 0xe9fa9380] Reinit context to 1280x720, pix_fmt: yuv420p
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/storage/emulated/0/Movies/Capture/bobross.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: isommp42
    creation_time   : 2016-08-22T05:06:42.000000Z
  Duration: 10:00:27.90, start: 0.000000, bitrate: 1127 kb/s
    Stream #0:0(und): Video: h264, 1 reference frame (avc1 / 0x31637661), yuv420p(left), 1280x720 [SAR 1:1 DAR 16:9], 997 kb/s, 24 fps, 24 tbr, 90k tbn, 48 tbc (default)
    Metadata:
      creation_time   : 2016-08-22T05:06:42.000000Z
      handler_name    : ISO Media file produced by Google Inc.
    Stream #0:1(und): Audio: aac (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 125 kb/s (default)
    Metadata:
      creation_time   : 2016-08-22T05:06:42.000000Z
      handler_name    : ISO Media file produced by Google Inc.
Processing read interval id:0 start:0 end:+20
Seeking to read interval start point 0
[h264 @ 0xe9fa9e00] Reinit context to 1280x720, pix_fmt: yuv420p
ffprobe version n4.0-39-gda39990 Copyright (c) 2007-2018 the FFmpeg developers
  built with gcc 4.9.x (GCC) 20150123 (prerelease)
  configuration: --target-os=linux --cross-prefix=/root/bravobit/ffmpeg-android/toolchain-android/bin/arm-linux-androideabi- --arch=arm --cpu=cortex-a8 --enable-runtime-cpudetect --sysroot=/root/bravobit/ffmpeg-android/toolchain-android/sysroot --enable-pic --enable-libx264 --enable-ffprobe --enable-libopus --enable-libvorbis --enable-libfdk-aac --enable-libfreetype --enable-libfribidi --enable-libmp3lame --enable-fontconfig --enable-libvpx --enable-libass --enable-yasm --enable-pthreads --disable-debug --enable-version3 --enable-hardcoded-tables --disable-ffplay --disable-linux-perf --disable-doc --disable-shared --enable-static --enable-runtime-cpudetect --enable-nonfree --enable-network --enable-avresample --enable-avformat --enable-avcodec --enable-indev=lavfi --enable-hwaccels --enable-ffmpeg --enable-zlib --enable-gpl --enable-small --enable-nonfree --pkg-config=pkg-config --pkg-config-flags=--static --prefix=/root/bravobit/ffmpeg-android/build/armeabi-v7a --extra-cflags='-I/root/bravobit/ffmpeg-android/toolchain-android/include -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fno-strict-overflow -fstack-protector-all' --extra-ldflags='-L/root/bravobit/ffmpeg-android/toolchain-android/lib -Wl,-z,relro -Wl,-z,now -pie' --extra-cxxflags=
  libavutil      56. 14.100 / 56. 14.100
  libavcodec     58. 18.100 / 58. 18.100
  libavformat    58. 12.100 / 58. 12.100
  libavdevice    58.  3.100 / 58.  3.100
  libavfilter     7. 16.100 /  7. 16.100
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  1.100 /  5.  1.100
  libswresample   3.  1.100 /  3.  1.100
  libpostproc    55.  1.100 / 55.  1.100
Adding 'key_frame' to the entries to show in section 'frame'
Adding 'pkt_pts_time' to the entries to show in section 'frame'
Parsed log interval id:0 start:0 end:+20
[h264 @ 0xe9fa9380] Reinit context to 1280x720, pix_fmt: yuv420p
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/storage/emulated/0/Movies/Capture/bobross.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: isommp42
    creation_time   : 2016-08-22T05:06:42.000000Z
  Duration: 10:00:27.90, start: 0.000000, bitrate: 1127 kb/s
    Stream #0:0(und): Video: h264, 1 reference frame (avc1 / 0x31637661), yuv420p(left), 1280x720 [SAR 1:1 DAR 16:9], 997 kb/s, 24 fps, 24 tbr, 90k tbn, 48 tbc (default)
    Metadata:
      creation_time   : 2016-08-22T05:06:42.000000Z
      handler_name    : ISO Media file produced by Google Inc.
    Stream #0:1(und): Audio: aac (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 125 kb/s (default)
    Metadata:
      creation_time   : 2016-08-22T05:06:42.000000Z
      handler_name    : ISO Media file produced by Google Inc.
Processing read interval id:0 start:0 end:+20
Seeking to read interval start point 0
[h264 @ 0xe9fa9e00] Reinit context to 1280x720, pix_fmt: yuv420p
frame,1,0.000000frame,1,3.000000frame,1,5.000000frame,1,6.416667frame,1,10.000000frame,1,15.000000frame,1,19.041667

1 Answer 1

5

The decoder is marking recovery points as keyframes

e.g. take the frame with PTS 3.00s

This is a recovery point* and the packet contains an I-slice (slice_type 7). Furthermore, as recovery_frame_cnt is 0, the decoder can immediately display frames from this point onwards.

Packet: 25021 bytes, pts 270000, dts 266250, duration 3750.
Supplemental Enhancement Information
0           forbidden_zero_bit                                          0 = 0
1           nal_ref_idc                                                00 = 0
3           nal_unit_type                                           00110 = 6
8           last_payload_type_byte                               00000110 = 6
16          last_payload_size_byte                               00000001 = 1
Recovery Point
24          recovery_frame_cnt                                          1 = 0
25          exact_match_flag                                            1 = 1
26          broken_link_flag                                            0 = 0
27          changing_slice_group_idc                                   00 = 0
29          bit_equal_to_one                                            1 = 1
30          bit_equal_to_zero                                           0 = 0
31          bit_equal_to_zero                                           0 = 0
32          rbsp_stop_one_bit                                           1 = 1
33          rbsp_alignment_zero_bit                                     0 = 0
34          rbsp_alignment_zero_bit                                     0 = 0
35          rbsp_alignment_zero_bit                                     0 = 0
36          rbsp_alignment_zero_bit                                     0 = 0
37          rbsp_alignment_zero_bit                                     0 = 0
38          rbsp_alignment_zero_bit                                     0 = 0
39          rbsp_alignment_zero_bit                                     0 = 0
Slice Header
0           forbidden_zero_bit                                          0 = 0
1           nal_ref_idc                                                10 = 2
3           nal_unit_type                                           00001 = 1
8           first_mb_in_slice                                           1 = 0
9           slice_type                                            0001000 = 7
16          pic_parameter_set_id                                        1 = 0
17          frame_num                                                1111 = 15
21          pic_order_cnt_lsb                                       10000 = 16
26          adaptive_ref_pic_marking_mode_flag                          0 = 0
27          slice_qp_delta                                        0001111 = -7
34          disable_deblocking_filter_idc                               1 = 0
35          slice_alpha_c0_offset_div2                                  1 = 0
36          slice_beta_offset_div2                                      1 = 0
37          cabac_alignment_one_bit                                     1 = 1
38          cabac_alignment_one_bit                                     1 = 1
39          cabac_alignment_one_bit                                     1 = 1

*see https://mailman.videolan.org/pipermail/vlc-commits/2010-October/003615.html


If your inputs are MP4s, you can examine the packets to get the IDR key status

ffprobe -loglevel verbose -skip_frame nokey -select_streams v -show_entries packet=pts_time,flags -of csv=print_section=1 -read_intervals 0%+20 srcFile.mp4

For the first 6 seconds, this will show only the frames at 0 and 5.

packet,0.000000,K_
...
packet,3.000000,__
...
packet,5.000000,K_
3
  • Out of curiosity, how did you generate the above table?
    – slhck
    Sep 27, 2021 at 11:20
  • trace_headers bitstream filter.
    – Gyan
    Sep 27, 2021 at 11:51
  • Thanks, I totally forgot about this one.
    – slhck
    Sep 28, 2021 at 12:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.