[FFmpeg-devel] About guess_correct_pts / AVFrame.best_effort_timestamp

Alexander Strange astrange
Fri Feb 18 04:39:35 CET 2011


2011/2/16 M?ns Rullg?rd <mans at mansr.com>:
> Jean-Daniel Dupas <devlists at shadowlab.org> writes:
>
>> Le 16 f?vr. 2011 ? 16:40, M?ns Rullg?rd a ?crit :
>>
>>> Nicolas George <nicolas.george at normalesup.org> writes:
>>>
>>>> L'octidi 28 pluvi?se, an CCXIX, Luca Barbato a ?crit :
>>>>> Transcoding results in a foo.mp4 with the correct timing? (shouldn't)
>>>>
>>>> With:
>>>>
>>>> ./ffmpeg -i hellsing-h264-blocking.mkv t.mp4
>>>>
>>>> I get:
>>>>
>>>> pts_time=0.000000 ?dts_time=0.000000 ? ? ? ?(time_base = 1/24000)
>>>> pts_time=0.041708 ?dts_time=0.041708
>>>> pts_time=0.083417 ?dts_time=0.083417
>>>> pts_time=0.125125 ?dts_time=0.125125
>>>> pts_time=0.166833 ?dts_time=0.166833
>>>> pts_time=0.208542 ?dts_time=0.208542
>>>> pts_time=0.250250 ?dts_time=0.250250
>>>> pts_time=0.291958 ?dts_time=0.291958
>>>> pts_time=0.333667 ?dts_time=0.333667
>>>> pts_time=0.375375 ?dts_time=0.375375
>>>>
>>>> while the original had:
>>>>
>>>> pts_time=0.000000 ?dts_time=0.000000 ? ? ? ?(time_base = 1/1000)
>>>> pts_time=0.042000 ?dts_time=N/A
>>>> pts_time=0.084000 ?dts_time=0.084000
>>>> pts_time=0.125000 ?dts_time=0.125000
>>>> pts_time=0.167000 ?dts_time=0.167000
>>>> pts_time=0.209000 ?dts_time=0.042000
>>>> pts_time=0.251000 ?dts_time=0.209000
>>>> pts_time=0.292000 ?dts_time=0.251000
>>>> pts_time=0.334000 ?dts_time=0.334000
>>>> pts_time=0.376000 ?dts_time=0.292000
>>>>
>>>> I think these timestamps are completely valid.
>>>
>>> How did you obtain those timestamps? ?Whatever the answer, they are
>>> different from the original. ?They should not be.
>
> Altering the time base is an error too.

This is a feature of ffmpeg.c when encoding/stream copying. When
creating the output stream, it used the codec timebase instead of the
container's stream timebase.

ffmpeg.c:2139:
            if(!copy_tb &&
av_q2d(icodec->time_base)*icodec->ticks_per_frame >
av_q2d(ist->st->time_base) && av_q2d(ist->st->time_base) < 1.0/500){
                codec->time_base = icodec->time_base;
                codec->time_base.num *= icodec->ticks_per_frame;
                av_reduce(&codec->time_base.num, &codec->time_base.den,
                          codec->time_base.num, codec->time_base.den, INT_MAX);
            }else
                codec->time_base = ist->st->time_base;

movenc.c:2121:
            track->timescale = st->codec->time_base.den;

This is absolutely the right thing to do to this file. Being mkv, it
has a terrible container timebase (1/1000) because timestamps are
stored as decimals instead of fractions. But the original codec
timebase (1/24000) is okay.

Since NTSC-origin times are always multiples of 120fps/1.001, the
rounding errors in mkv actually make CFR streams VFR, which makes it
impossible to copy back into PS or AVI.

A similar problem affects AVI/FLV because the muxing programs store
fps as a float, and when they write it as a fraction it gets rounded
strangely. Perian and FFMS2 have code to recover these back to a
multiple of 120fps. It's safe, but has no effect on playback except to
make the x264 stderr cleaner.

Anyway it doesn't have much to do with this thread, but I think it
wasn't hard to find the answer.



More information about the ffmpeg-devel mailing list