[FFmpeg-user] Frame counting is too slow

Peter White peter.white at posteo.net
Tue Mar 9 17:27:14 EET 2021


Hi all,

as a follow-up to this discussion:
https://ffmpeg.org/pipermail/ffmpeg-user/2021-March/052358.html

I would like to ask, if frame counting with ffprobe can be made faster.
The way it done now is obviously by decoding every single frame and
afterwards incrementing the counter. See how slow this example runs:

time ffprobe -count_frames -select_streams v:0 -show_entries stream=nb_read_frames -of default=nokey=1:noprint_wrappers=1 input.mkv
ffprobe version n4.3.1-221-gd08bcbffff Copyright (c) 2007-2021 the FFmpeg developers
  built with AMD clang version 11.0.0 (CLANG: AOCC_2.3.0-Build#85 2020_11_10) (based on LLVM Mirror.Version.11.0.0)
  configuration: --cc='ccache clang' --cxx='ccache clang++' --objcc='ccache clang' --dep-cc='ccache clang' --extra-cflags='-march=native' --extra-cxxflags='-march=native' --extra-objcflags='-march=native' --enable-hardcoded-tables --enable-shared --enable-gpl --enable-version3 --enable-nonfree --disable-runtime-cpudetect --enable-libx264 --enable-libx265 --enable-libvorbis --enable-gnutls --enable-opengl --enable-libopus --enable-libfreetype --enable-libfontconfig --enable-libfribidi --enable-libsoxr --enable-libzvbi --enable-libmp3lame --enable-ladspa --enable-lv2 --enable-libbs2b --enable-libdrm --enable-libvpx --enable-libbluray
  libavutil      56. 51.100 / 56. 51.100
  libavcodec     58. 91.100 / 58. 91.100
  libavformat    58. 45.100 / 58. 45.100
  libavdevice    58. 10.100 / 58. 10.100
  libavfilter     7. 85.100 /  7. 85.100
  libswscale      5.  7.100 /  5.  7.100
  libswresample   3.  7.100 /  3.  7.100
  libpostproc    55.  7.100 / 55.  7.100
Input #0, matroska,webm, from 'input.mkv':
  Metadata:
    creation_time   : 2021-02-16T19:59:37.000000Z
    ENCODER         : Lavf58.45.100
  Duration: 00:21:40.91, start: -0.007000, bitrate: 1319 kb/s
    Chapter #0:0: start 0.000000, end 432.557000
    Metadata:
      title           : 00:00:00.000
    Chapter #0:1: start 432.557000, end 866.824000
    Metadata:
      title           : 00:07:12.557
    Chapter #0:2: start 866.824000, end 1267.475000
    Metadata:
      title           : 00:14:26.824
    Chapter #0:3: start 1267.475000, end 1300.906000
    Metadata:
      title           : 00:21:07.475
    Stream #0:0: Video: hevc (Main 10), yuv420p10le(tv, bt709), 768x432 [SAR 1:1 DAR 16:9], 23.98 fps, 23.98 tbr, 1k tbn, 23.98 tbc (default)
    Metadata:
      BPS-eng         : 1021384
      DURATION-eng    : 00:21:40.716000000
      NUMBER_OF_FRAMES-eng: 31186
      NUMBER_OF_BYTES-eng: 166066371
      _STATISTICS_WRITING_APP-eng: mkvmerge v45.0.0 ('Heaven in Pennies') 64-bit
      _STATISTICS_WRITING_DATE_UTC-eng: 2021-02-16 19:59:37
      _STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
    Stream #0:1(eng): Audio: opus, 48000 Hz, 5.1, fltp (default)
    Metadata:
      title           : English
      ENCODER         : Lavc58.91.100 libopus
      BPS-eng         : 230805
      DURATION-eng    : 00:21:40.760000000
      NUMBER_OF_FRAMES-eng: 65039
      NUMBER_OF_BYTES-eng: 37527832
      _STATISTICS_WRITING_APP-eng: mkvmerge v45.0.0 ('Heaven in Pennies') 64-bit
      _STATISTICS_WRITING_DATE_UTC-eng: 2021-02-16 19:59:37
      _STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
    Stream #0:2(eng): Audio: aac (HE-AAC), 48000 Hz, stereo, fltp
    Metadata:
      title           : English
      BPS-eng         : 63925
      DURATION-eng    : 00:21:40.906000000
      NUMBER_OF_FRAMES-eng: 30490
      NUMBER_OF_BYTES-eng: 10395117
      _STATISTICS_WRITING_APP-eng: mkvmerge v45.0.0 ('Heaven in Pennies') 64-bit
      _STATISTICS_WRITING_DATE_UTC-eng: 2021-02-16 19:59:37
      _STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
    Stream #0:3(eng): Subtitle: subrip
    Metadata:
      title           : English
      BPS-eng         : 72
      DURATION-eng    : 00:21:36.169000000
      NUMBER_OF_FRAMES-eng: 370
      NUMBER_OF_BYTES-eng: 11676
      _STATISTICS_WRITING_APP-eng: mkvmerge v45.0.0 ('Heaven in Pennies') 64-bit
      _STATISTICS_WRITING_DATE_UTC-eng: 2021-02-16 19:59:37
      _STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
31186
ffprobe -count_frames -select_streams v:0 -show_entries stream=nb_read_frames  55,01s user 0,10s system 99% cpu 55,182 total

And apparently ffprobe only uses one CPU core by default as opposed to
ffmpeg; see the 99% load. This machine has 8 threads, hence is capable
of 800%, theoretically. But that is just an aside.

But why do the frames need to be decoded for counting? That seems
excessive for such a supposedly mundane task. In the mentioned
discussion I inadvertently suggested counting packets instead by using
ffmpeg's copy codec with the null device as a target and looking at the
number of frames in the stats line. This way the operation finishes
almost immediately. Then I learned, that the equivalent ffprobe command
is this:
ffprobe -count_packets -select_streams v:0 -show_entries stream=nb_read_packets -of default=nokey=1:noprint_wrappers=1 input.mkv

It takes but a blink of an eye to finish. There is a catch, though,
since packets are not frames, there might be some scenario in which the
number of packets is greater than the number of frames.

Isn't there a way to count frames by some kind of dummy decoder, which
just increments a counter instead of decoding?


Peter


More information about the ffmpeg-user mailing list