[FFmpeg-trac] #8522(avformat:new): DASH start segment number calculation is wrong for fragment_duration mode

FFmpeg trac at avcodec.org
Wed Feb 12 19:42:09 EET 2020


#8522: DASH start segment number calculation is wrong for fragment_duration mode
----------------------------------+-------------------------------------
             Reporter:  onitake   |                     Type:  defect
               Status:  new       |                 Priority:  important
            Component:  avformat  |                  Version:  4.2
             Keywords:  dash mpd  |               Blocked By:
             Blocking:            |  Reproduced by developer:  0
Analyzed by developer:  0         |
----------------------------------+-------------------------------------
 Summary of the bug:

 When playing an MPEG-DASH live stream in fragment_duration, the
 calculation of the first segment is incorrect, which can result in a
 significant offset.

 In a test (as outlined below) with timescale=48000 and duration=288000, I
 can observe an offset of 3 days in the future. This will clearly not work,
 as it's very unlikely that live stream segments are produced 3 days in
 advance.


 How to reproduce:

 This is a private test stream and cannot be published here, unfortunately.
 The anonymized DASH manifest is attached.

 {{{
 % ffmpeg -v verbose -re -i https://<REDACTED>/dash.mpd -c:a copy -c:v copy
 -f mpegts -y live.ts

 ffmpeg version 4.2.2-1 Copyright (c) 2000-2019 the FFmpeg developers
   built with gcc 9 (Debian 9.2.1-24)
 }}}


 Observations:

 With this manifest, there is an offset of several days between the
 segments that are requested by ffmpeg and what is available on the
 streaming CDN.

 When I ran a test on Monday (when the stream was set up), I ended up with
 a request for segment 263604602, while the DASH-IF reference player
 (https://reference.dashif.org/dash.js/v2.9.1/samples/dash-if-reference-
 player/index.html) requested segment 263557058, which is correct and
 works.

 I ran the same test today and got 263605211 on ffmpeg and 263588024 on the
 DASH-IF player.


 Source of the issue:

 The issue lies in how the first segment number is calculated in dashdec.c:

 {{{
     if (c->is_live) {
         // ...
         } else if (pls->fragment_duration){
             // ...
             } else if (c->publish_time > 0 && !c->availability_start_time)
 {
                 if (c->min_buffer_time) {
                     num = pls->first_seq_no + (((c->publish_time +
 pls->fragment_duration) - c->suggested_presentation_delay) *
 pls->fragment_timescale) / pls->fragment_duration - c->min_buffer_time;
                 } else {
                     num = pls->first_seq_no + (((c->publish_time -
 c->time_shift_buffer_depth + pls->fragment_duration) -
 c->suggested_presentation_delay) * pls->fragment_timescale) /
 pls->fragment_duration;
                 }
 }}}

 Here, the fragment duration in timescale units is added to the first
 segment number, which is in seconds, not timescale units.
 The resulting time offset is then scaled to the segment number by
 multiplying with the timescale and dividing by the fragment duration in
 timescale units.
 The end result is that fragment_duration * fragment_timescale /
 fragment_duration = fragment_timescale is added to the segment number,
 which doesn't make much sense.

 In my case (where first_seq_no=0, timescale=48000 and duration=288000),
 this results in a shift of 48000 segment numbers, which corresponds to
 288000 seconds here, and that is 3.333 days, as I originally observed
 during my first tests.

 Furthermore, I'm almost 100% certain that the publish time is not relevant
 to the segment number in any way for live streams. Only the current time
 and the availability_start_time should be used.
 If I remove the fragment_timescale shift, I still end up with incorrect
 segment numbers, because they are now relative to the publish time.
 At least, it looks like the DASH-IF reference player seems to ignore the
 publish time and only loads segments relative to the availability start
 time.

 The specification describes the publishTime attribute as follows:

 > specifies the wall-clock time when the MPD was
 > generated and published at the origin server. MPDs with
 > a later value of @publishTime shall be an update as
 > defined in 5.4 to MPDs with earlier @publishTime.

 As a test, I removed the whole special casing for 'c->publish_time > 0 &&
 !c->availability_start_time' and now my stream works correctly.


 Addendum:

 I will try to obtain permission to publish this stream publicly, but I
 cannot do that at the moment.

--
Ticket URL: <https://trac.ffmpeg.org/ticket/8522>
FFmpeg <https://ffmpeg.org>
FFmpeg issue tracker


More information about the FFmpeg-trac mailing list