[Libav-user] Configuring mp4 muxer to not recalculate time_base to an absurd timescale value

Corey Taylor corey.taylor.fl at gmail.com
Sat Jan 6 07:31:53 EET 2018


I encountered an unusual issue while upgrading from the ffmpeg 2.5 av
libraries to 3.x (currently trying with 3.4.1) and am running into
this on Windows using an msys2 mingw64 build from source.

As I'm not sure exactly what would be helpful since it's not a command
line issue, I'll just describe it and see what someone would like to
know.

We have a had a fairly simple, working setup to capture our 3d engine
output to mp4 files.  We decided to upgrade past the 3.x release and
update to the new API avcodec_send_frame/avcodec_receive_packet and so
on.

I went through the updated (thank you!) examples to make sure we are
using the recommended API for setup and so on.  Not a whole lot has
changed apart from some new ref counting and filter use.

The issue I am running into is after setting the stream's time_base
(essentially as before) to 1/30 for a 30fps video, we call
avformat_write_header and start recording a video which seems to go
normally until the codec is flushed and the file written.  After
playing back, I see that the framerate is always this absurd value of
15360 and most video players play the video back as fast as possible.

I figured it was a configuration issue, but could not find any issue
with how we simply set the time_base, and there seemed no real
difference between the old API or the examples.  After adding some
extra logging to libavformat, I traced it down to occurring in the mp4
muxer init callback:

libavformat/mov_enc.c
mov_init()

Here, for a video stream, it calculates a "timescale" based on the
original stream time_base denominator value.

        if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
           <snip>

           if (mov->video_track_timescale) {
                track->timescale = mov->video_track_timescale;
            } else {
                track->timescale = st->time_base.den;
                while(track->timescale < 10000)
                    track->timescale *= 2;

And then after that, it sets the pts info with this calculated timescale.

        avpriv_set_pts_info(st, 64, 1, track->timescale);

So, from the above code it take 30 and multiplies it by 2 up to 15360
and then sets the time_base to 1/15360.

I cannot understand what configuration is meant to control this. I
assume this scaling is to make some sort of finer granularity in the
timestamps, but it seems to only scale the denominator.

Is a time_base of 1/30 not valid?  Form the examples and documentation
that state a fixed framerate stream should be 1/framerate with pts
duration of 1 this seems expected.

corey


More information about the Libav-user mailing list