[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