Opened 3 years ago

Last modified 3 years ago

#9440 new defect

dash muxer does not support all framerates in no-timeline mode

Reported by: Gregory Beauregard Owned by:
Priority: normal Component: undetermined
Version: git-master Keywords: dash
Cc: Blocked By:
Blocking: Reproduced by developer: no
Analyzed by developer: no

Description (last modified by Gregory Beauregard)

Summary of the bug: ffmpeg's dash muxer is not compatible with all framerates in no-timeline mode because the segmentation duration option -seg_duration accepts input as a duration which is accurate to an integral number of microseconds, but this is not sufficient to make all framerates usable with the dash muxer.

In DASH it is required that the segment duration be specified very accurately when use_template is enabled and use_timeline is disabled in order to get the modern templated playlists. In particular, submicrosecond errors result in the stream failing to play after a couple segments with e.g. dash.js. The DASH spec provides the timebase so that in the mpd the segment duration is effectively specified as a rational number. This allows the segment duration to be an exact multiple of the 1/framerate.

Currently, ffmpeg accepts a "duration" field for the -seg_duration option of the dash muxer that it converts into an integer number of microseconds and a timebase of 1000000 meaning that the ffmpeg DASH muxer in modes without a timeline is only compatible with segment durations that can be represented exactly as an integer number of microseconds.

Not all framerates in the wild have any reasonable segment duration that can be represented exactly with an integer number of microseconds, meaning that ffmpeg's dash muxer does not support these framerates in no-timeline mode.

To demonstrate this, consider the slightly uncommon framerate 23.976 (2997/125). In order to have a truncating float representation, the segment duration (=GOP_SIZE/framerate) must, at minimum, have a reduced fraction representation with only factors of 2 and 5 in the denominator. Because the GOP_SIZE is an integer and 2997 has no factors of 2 or 5, the GOP_SIZE must at minimum have 2997 as a factor in order to be compatible with ffmpeg's DASH muxer (the GOP size must have factors that cancel out everything that's not a factor of 2 or 5). If this minimum value is chosen, the segment duration would be 2997/23.976=125 seconds. So the ffmpeg DASH muxer is unusable in no-timeline mode with framerates of 23.976 and segment lengths under 125 seconds (a length too long for streaming). Note in addition to this, to be compatible with the DASH muxer the reduced fraction representation of the segment length must have a denominator <=10^6 due to the microseconds used, but that's not relevant to see the failure here.

How to reproduce:
Generate a DASH playlist with use_template enabled and use_timeline disabled using a file with a framerate of 23.976 (2997/125). dash.js will not be able to play more than a couple segments without going out of sync and failing to load the stream.

Change History (12)

comment:1 by Gregory Beauregard, 3 years ago

To fix ffmpeg's DASH muxer to allow all framerates we can modify the -seg_duration and -frag_duration options to accept a RATIONAL or AV_OPT_TYPE_VIDEO_RATE instead of a duration to match how it's specified in the mpd.

Last edited 3 years ago by Gregory Beauregard (previous) (diff)

comment:2 by Gregory Beauregard, 3 years ago

Description: modified (diff)

comment:3 by Gregory Beauregard, 3 years ago

Description: modified (diff)

comment:4 by Gregory Beauregard, 3 years ago

Description: modified (diff)

comment:5 by Gregory Beauregard, 3 years ago

Description: modified (diff)

comment:6 by Gregory Beauregard, 3 years ago

Description: modified (diff)

comment:7 by Gregory Beauregard, 3 years ago

cf. the above to 24000/1001; this fraction is reduced, and the only non 2/5 factor in the numerator is a single 3 with the remaining factors <=10^6, so segment durations that are usable in (-use_timeline 0) ffmpeg for this framerate are only restricted to be a multiple of 3/(24000/1001)=0.125125 seconds, which allow plenty of usable segment lengths (unlike the entirely unusable 23.976 framerate)

Last edited 3 years ago by Gregory Beauregard (previous) (diff)

comment:8 by Gregory Beauregard, 3 years ago

Version: unspecifiedgit-master

comment:9 by Gregory Beauregard, 3 years ago

See also the frag_duration option of the dash muxer that needs changed at the same time (to AV_OPT_TYPE_VIDEO_RATE?)

comment:10 by Gregory Beauregard, 3 years ago

Description: modified (diff)

comment:11 by Gregory Beauregard, 3 years ago

Summary: timeline-free dash muxing not possible with all frameratesdash muxer does not support all framerates without a timeline

comment:12 by Gregory Beauregard, 3 years ago

Summary: dash muxer does not support all framerates without a timelinedash muxer does not support all framerates in no-timeline mode
Note: See TracTickets for help on using tickets.