[FFmpeg-user] Frame counting is too slow

Peter White peter.white at posteo.net
Tue Mar 9 23:17:00 EET 2021


On Tue, Mar 09, 2021 at 04:43:54PM +0100, Paul B Mahol wrote:
> patch welcome

After I have had a look at ffprobe.c I noticed, that there seems to be
nothing that can be done there other than basically cheating by actually
counting packets instead of frames, which would never get accepted, me
reckons.
Then I took a look at avcodec.h to get some initial bearings just to be
overwhelmed by its size. :)

Before I spend anymore time on this, can somebody please tell me, if
what I proposed is actually possible? I am starting to think that it
cannot be done.

Is this a correct, though simplified, definition of "frame" in avcodec.h
terms?:
A frame is what the decoder returns in avcodec_receive_frame().

If that is true, then I cannot see, how to work around that without
breaking something.

Or am I looking at it wrong?

> On Tue, Mar 9, 2021 at 4:27 PM Peter White <peter.white at posteo.net> wrote:
> 
> > 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
> > _______________________________________________
> > ffmpeg-user mailing list
> > ffmpeg-user at ffmpeg.org
> > https://ffmpeg.org/mailman/listinfo/ffmpeg-user
> >
> > To unsubscribe, visit link above, or email
> > ffmpeg-user-request at ffmpeg.org with subject "unsubscribe".
> _______________________________________________
> ffmpeg-user mailing list
> ffmpeg-user at ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-user
> 
> To unsubscribe, visit link above, or email
> ffmpeg-user-request at ffmpeg.org with subject "unsubscribe".


More information about the ffmpeg-user mailing list