Message ID | 20161011190639.79085-1-josh@itanimul.li |
---|---|
State | Changes Requested |
Headers | show |
On Tue, Oct 11, 2016 at 08:06:39PM +0100, Josh de Kock wrote: > Fixes ticket #5882. While it doesn't automatically set the timescale > for the user as that would destroy data without prompt, it will tell > the user how they could set the timescale (as this is mostly likely > what they want). > > Signed-off-by: Josh de Kock <josh@itanimul.li> > --- > > >Would it be useful to print the max duration? > I'm not entirely sure, open to suggestions though. > > libavformat/movenc.c | 9 +++++++-- > 1 file changed, 7 insertions(+), 2 deletions(-) > > diff --git a/libavformat/movenc.c b/libavformat/movenc.c > index d7c7158..6bada25 100644 > --- a/libavformat/movenc.c > +++ b/libavformat/movenc.c > @@ -5677,11 +5677,16 @@ static int mov_write_header(AVFormatContext *s) > ret = AVERROR(EINVAL); > goto error; > } > - if (track->mode == MODE_MOV && track->timescale > 100000) > + if (track->mode == MODE_MOV && track->timescale > 100000) { > + /* NOTE: forcing setting the suggested timescale manually means ffmpeg won't destroy > + * timestamps without explicit instruction. */ > + unsigned int suggested = (unsigned int)av_rescale(st->time_base.den, 1000, st->time_base.num); > 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"); > + "or choose different container. Using -video_track_timescale %d\n" > + "may fix this issue.\n", suggested); maybe a -max_timescale parameter would be usefull users could with that limit teh value without having to do something per file [...]
Le decadi 20 vendémiaire, an CCXXV, Josh de Kock a écrit : > Fixes ticket #5882. While it doesn't automatically set the timescale > for the user as that would destroy data without prompt, it will tell > the user how they could set the timescale (as this is mostly likely > what they want). > > Signed-off-by: Josh de Kock <josh@itanimul.li> > --- > > >Would it be useful to print the max duration? > I'm not entirely sure, open to suggestions though. > > libavformat/movenc.c | 9 +++++++-- > 1 file changed, 7 insertions(+), 2 deletions(-) > > diff --git a/libavformat/movenc.c b/libavformat/movenc.c > index d7c7158..6bada25 100644 > --- a/libavformat/movenc.c > +++ b/libavformat/movenc.c > @@ -5677,11 +5677,16 @@ static int mov_write_header(AVFormatContext *s) > ret = AVERROR(EINVAL); > goto error; > } > - if (track->mode == MODE_MOV && track->timescale > 100000) > + if (track->mode == MODE_MOV && track->timescale > 100000) { > + /* NOTE: forcing setting the suggested timescale manually means ffmpeg won't destroy > + * timestamps without explicit instruction. */ > + unsigned int suggested = (unsigned int)av_rescale(st->time_base.den, 1000, st->time_base.num); > 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"); > + "or choose different container. Using -video_track_timescale %d\n" Nit: the leading dash is specific to the command-line tools. At the library level, the option is named just "video_track_timescale". > + "may fix this issue.\n", suggested); > + } > if (track->mode == MODE_MOV && > track->par->codec_id == AV_CODEC_ID_RAWVIDEO && > track->tag == MKTAG('r','a','w',' ')) { Regards,
2016-10-11 21:06 GMT+02:00 Josh de Kock <josh@itanimul.li>: > Fixes ticket #5882. I don't object but I don't think it is correct. > While it doesn't automatically set the timescale > for the user as that would destroy data without prompt, it will tell > the user how they could set the timescale (as this is mostly likely > what they want). > > Signed-off-by: Josh de Kock <josh@itanimul.li> > --- > >>Would it be useful to print the max duration? > I'm not entirely sure, open to suggestions though. > > libavformat/movenc.c | 9 +++++++-- > 1 file changed, 7 insertions(+), 2 deletions(-) > > diff --git a/libavformat/movenc.c b/libavformat/movenc.c > index d7c7158..6bada25 100644 > --- a/libavformat/movenc.c > +++ b/libavformat/movenc.c > @@ -5677,11 +5677,16 @@ static int mov_write_header(AVFormatContext *s) > ret = AVERROR(EINVAL); > goto error; > } > - if (track->mode == MODE_MOV && track->timescale > 100000) > + if (track->mode == MODE_MOV && track->timescale > 100000) { > + /* NOTE: forcing setting the suggested timescale manually means ffmpeg won't destroy > + * timestamps without explicit instruction. */ > + unsigned int suggested = (unsigned int)av_rescale(st->time_base.den, 1000, st->time_base.num); If we go this way (I am not completely convinced about it), we definitely need a heuristic that suggests 24000 for 10000000/417083 fps and 30000 if applicable. > 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"); > + "or choose different container. Using -video_track_timescale %d\n" > + "may fix this issue.\n", suggested); I believe this should also suggest to "force a sane framerate" as an alternative. Suggesting video_track_timescale is very useful, thank you! Carl Eugen
On 12/10/16 11:04, Carl Eugen Hoyos wrote: > 2016-10-11 21:06 GMT+02:00 Josh de Kock <josh@itanimul.li>: >> Fixes ticket #5882. > > I don't object but I don't think it is correct. > >> While it doesn't automatically set the timescale >> for the user as that would destroy data without prompt, it will tell >> the user how they could set the timescale (as this is mostly likely >> what they want). >> >> Signed-off-by: Josh de Kock <josh@itanimul.li> >> --- >> >>> Would it be useful to print the max duration? >> I'm not entirely sure, open to suggestions though. >> >> libavformat/movenc.c | 9 +++++++-- >> 1 file changed, 7 insertions(+), 2 deletions(-) >> >> diff --git a/libavformat/movenc.c b/libavformat/movenc.c >> index d7c7158..6bada25 100644 >> --- a/libavformat/movenc.c >> +++ b/libavformat/movenc.c >> @@ -5677,11 +5677,16 @@ static int mov_write_header(AVFormatContext *s) >> ret = AVERROR(EINVAL); >> goto error; >> } >> - if (track->mode == MODE_MOV && track->timescale > 100000) >> + if (track->mode == MODE_MOV && track->timescale > 100000) { >> + /* NOTE: forcing setting the suggested timescale manually means ffmpeg won't destroy >> + * timestamps without explicit instruction. */ > >> + unsigned int suggested = (unsigned int)av_rescale(st->time_base.den, 1000, st->time_base.num); > > If we go this way (I am not completely convinced about it), we definitely need > a heuristic that suggests 24000 for 10000000/417083 fps and 30000 if applicable. How about the approach in the test program below? This makes the whole timebase fraction; the suggested timescale would then be the denominator of that. (It is currently just a program linked with lavu, I could make it into a patch if someone else thinks this might actually be a good idea. It would need better error handling and some thoughts about overflow, too.) It shows that we can do significantly better in the 417083/10000000 case than any of the currently-suggested approaches (divide by 1000, guess 1/24 or 1001/24000): $ ./a.out 417083 10000000 100000 3715/89071 $ bc -l 417083/10000000 .04170830000000000000 3715/89071 .04170830012012888594 417/10000 .04170000000000000000 1/24 .04166666666666666666 1001/24000 .04170833333333333333 (The suggested timescale value would be 89071.) --- #include <stdio.h> #include "libavutil/rational.h" AVRational av_rational_reduce(AVRational qi, int max_den) { AVRational qc = qi; AVRational q0 = { 0, 1 }; AVRational q1 = { 1, 0 }; AVRational q2; int a, t, k; if (qc.den <= max_den) return qc; while (1) { a = qc.num / qc.den; q2.num = q0.num + a * q1.num; q2.den = q0.den + a * q1.den; if (q2.den > max_den) break; q0 = q1; q1 = q2; t = qc.num; qc.num = qc.den; qc.den = t - a * qc.den; } k = (max_den - q0.den) / q1.den; q2.num = q0.num + k * q1.num; q2.den = q0.den + k * q1.den; if (av_nearer_q(qi, q1, q2) >= 0) return q1; else return q2; } int main(int argc, char **argv) { AVRational ri, ro; int max; sscanf(argv[1], "%d", &ri.num); sscanf(argv[2], "%d", &ri.den); sscanf(argv[3], "%d", &max); ro = av_rational_reduce(ri, max); printf("%d/%d\n", ro.num, ro.den); return 0; }
On Wed, Oct 12, 2016 at 01:44:52PM +0100, Mark Thompson wrote: > On 12/10/16 11:04, Carl Eugen Hoyos wrote: > > 2016-10-11 21:06 GMT+02:00 Josh de Kock <josh@itanimul.li>: > >> Fixes ticket #5882. > > > > I don't object but I don't think it is correct. > > > >> While it doesn't automatically set the timescale > >> for the user as that would destroy data without prompt, it will tell > >> the user how they could set the timescale (as this is mostly likely > >> what they want). > >> > >> Signed-off-by: Josh de Kock <josh@itanimul.li> > >> --- > >> > >>> Would it be useful to print the max duration? > >> I'm not entirely sure, open to suggestions though. > >> > >> libavformat/movenc.c | 9 +++++++-- > >> 1 file changed, 7 insertions(+), 2 deletions(-) > >> > >> diff --git a/libavformat/movenc.c b/libavformat/movenc.c > >> index d7c7158..6bada25 100644 > >> --- a/libavformat/movenc.c > >> +++ b/libavformat/movenc.c > >> @@ -5677,11 +5677,16 @@ static int mov_write_header(AVFormatContext *s) > >> ret = AVERROR(EINVAL); > >> goto error; > >> } > >> - if (track->mode == MODE_MOV && track->timescale > 100000) > >> + if (track->mode == MODE_MOV && track->timescale > 100000) { > >> + /* NOTE: forcing setting the suggested timescale manually means ffmpeg won't destroy > >> + * timestamps without explicit instruction. */ > > > >> + unsigned int suggested = (unsigned int)av_rescale(st->time_base.den, 1000, st->time_base.num); > > > > If we go this way (I am not completely convinced about it), we definitely need > > a heuristic that suggests 24000 for 10000000/417083 fps and 30000 if applicable. > > How about the approach in the test program below? This makes the whole timebase > fraction; the suggested timescale would then be the denominator of that. (It is > currently just a program linked with lavu, I could make it into a patch if > someone else thinks this might actually be a good idea. It would need better > error handling and some thoughts about overflow, too.) > > It shows that we can do significantly better in the 417083/10000000 case than > any of the currently-suggested approaches (divide by 1000, guess 1/24 or > 1001/24000): > > $ ./a.out 417083 10000000 100000 > 3715/89071 > $ bc -l > 417083/10000000 > .04170830000000000000 > 3715/89071 > .04170830012012888594 > 417/10000 > .04170000000000000000 > 1/24 > .04166666666666666666 > 1001/24000 > .04170833333333333333 > > (The suggested timescale value would be 89071.) > > --- > > #include <stdio.h> > > #include "libavutil/rational.h" > > AVRational av_rational_reduce(AVRational qi, int max_den) why dont you use av_reduce() directly ? [...]
On 12/10/16 13:44, Mark Thompson wrote: > How about the approach in the test program below? This makes the whole timebase > fraction; the suggested timescale would then be the denominator of that. (It is > currently just a program linked with lavu, I could make it into a patch if > someone else thinks this might actually be a good idea. It would need better > error handling and some thoughts about overflow, too.) > > It shows that we can do significantly better in the 417083/10000000 case than > any of the currently-suggested approaches (divide by 1000, guess 1/24 or > 1001/24000): It may be too much. We only know of 3 video files, which don't play on the Apple player. We don't know how they got produced, what produced them, what caused them to have this deviation, if it was done intentionally or by accident, nor do we know why Apple chooses to deviate in their playback from other players, why exactly it fails and where else it fails apart from these 3 files. We really only know about 3 files, which could have already been fixed with the help of ffmpeg and without applying any patches to it. So I wouldn't take it this too far. Patches are supposed to be simple and one should try to make then even simpler, so say the rules of the project.
On 12/10/16 14:35, Michael Niedermayer wrote:
> why dont you use av_reduce() directly ?
Because I didn't know it existed. That would indeed be better (it appears to be
doing the same thing with continued fraction). The sentiment behind a suggested
patch is equivalent.
- Mark
On 12/10/16 14:38, Sven C. Dack wrote: > > It may be too much. We only know of 3 video files, which don't play on the > Apple player. We don't know how they got produced, what produced them, what > caused them to have this deviation, if it was done intentionally or by > accident, nor do we know why Apple chooses to deviate in their playback from > other players, why exactly it fails and where else it fails apart from these 3 > files. We really only know about 3 files, which could have already been fixed > with the help of ffmpeg and without applying any patches to it. So I wouldn't > take it this too far. Patches are supposed to be simple and one should try to > make then even simpler, so say the rules of the project. That said, I believe that Alex has already produced his 3 files and can now play them on his Apple player, all with the help of ffmpeg and the use of the right command option. So the fix isn't actually needed any longer.
diff --git a/libavformat/movenc.c b/libavformat/movenc.c index d7c7158..6bada25 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -5677,11 +5677,16 @@ static int mov_write_header(AVFormatContext *s) ret = AVERROR(EINVAL); goto error; } - if (track->mode == MODE_MOV && track->timescale > 100000) + if (track->mode == MODE_MOV && track->timescale > 100000) { + /* NOTE: forcing setting the suggested timescale manually means ffmpeg won't destroy + * timestamps without explicit instruction. */ + unsigned int suggested = (unsigned int)av_rescale(st->time_base.den, 1000, st->time_base.num); 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"); + "or choose different container. Using -video_track_timescale %d\n" + "may fix this issue.\n", suggested); + } if (track->mode == MODE_MOV && track->par->codec_id == AV_CODEC_ID_RAWVIDEO && track->tag == MKTAG('r','a','w',' ')) {