[FFmpeg-devel] [PATCH] Apple Quicktime fix

Alexey Eromenko al4321 at gmail.com
Tue Oct 11 21:39:57 EEST 2016


On Tue, Oct 11, 2016 at 8:29 PM, Josh de Kock <josh at itanimul.li> wrote:
> On 11/10/2016 18:24, Alexey Eromenko wrote:
>>
>> ---
>>  libavformat/movenc.c | 14 +++++++++-----
>>  1 file changed, 9 insertions(+), 5 deletions(-)
>>
>> diff --git a/libavformat/movenc.c b/libavformat/movenc.c
>> index 8b4aa5f..0e2fc55 100644
>> --- a/libavformat/movenc.c
>> +++ b/libavformat/movenc.c
>> @@ -5666,16 +5666,20 @@ static int mov_write_header(AVFormatContext *s)
>>                  while(track->timescale < 10000)
>>                      track->timescale *= 2;
>>              }
>> +            if (track->timescale > 100000 &&
>> (!mov->video_track_timescale)) {
>
> As I said before, having this as 'default' behaviour would interfere with
> large, but correct timescales. This should only be a suggestion to the user.
>

This happens only for very high timescale from source video, and it
seems to work on Apple QuickTime/iTunes, WMP and VLC.
For the vast majority videos (99%+), I _do not_ touch the timebase.
And when I do touch, I give a WARNING to the user.
Plus I offer to override this decision via a parameter.
It should be stable and regression-free for most of our users.
Is there any downside for this approach ?

>> +                unsigned int timescale_new = (unsigned
>> int)((double)(st->time_base.den)
>> +                * 1000 / (double)(st->time_base.num));
>
> You surely don't need all these casts.

Unless I'm guaranteed to get int64 on ALL platforms, I don't see
how-to write this code without casts to double-float. Int32 will
over-flow, even unsigned.
I can do the multiply after the division, but afraid of losing precision.
And since this is not a real-time code anyway, I consider this an
"okay" trade-off.
Feel free to replace it with a better alternative.

>> +                av_log(s, AV_LOG_WARNING,
>> +                       "WARNING codec timebase is very high. If duration
>> is too long,\n"
>> +                       "file may not be playable by Apple Quicktime.
>> Auto-setting\n"
>> +                       "a shorter timebase %u instead of %d.\n",
>> timescale_new, track->timescale);
>> +                track->timescale = timescale_new;
>> +            }
>>              if (st->codecpar->width > 65535 || st->codecpar->height >
>> 65535) {
>>                  av_log(s, AV_LOG_ERROR, "Resolution %dx%d too large for
>> mov/mp4\n", st->codecpar->width, st->codecpar->height);
>>                  ret = AVERROR(EINVAL);
>>                  goto error;
>>              }
>> -            if (track->mode == MODE_MOV && track->timescale > 100000)
>> -                av_log(s, AV_LOG_WARNING,
>> -                       "WARNING codec timebase is very high. If duration
>> is too long,\n"
>> -                       "file may not be playable by quicktime. Specify a
>> shorter timebase\n"
>> -                       "or choose different container.\n");
>
> Keep the logic in the same place please.

Logically timescale part 1 and timescale part 2 belong together, so I
grouped them together.

            if (mov->video_track_timescale) {
                track->timescale = mov->video_track_timescale;
            } else {
and
            if (track->timescale > 100000) {
                unsigned int timescale_new = (unsigned
int)((double)(st->time_base.den)


Feel free to modify my code and commit, after we reach some rough
consensus on the matters.
-- 
-Alexey Eromenko "Technologov"


More information about the ffmpeg-devel mailing list