Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RC2_v2.0.0] Inconsistent behavior with SegmentTimeline live stream #1141

Closed
lexaknyazev opened this issue Feb 6, 2016 · 18 comments
Closed
Labels
Milestone

Comments

@lexaknyazev
Copy link
Contributor

Looks like dash.js tries to get segments prior to proper initialization:

Conditions:

  1. Live presentation with SegmentTimeline.
  2. timeShiftBufferDepth is not present.

Firefox 44, Chrome 48

  • Start Event Controller
  • Getting the request for video time : 93610.58831111112
  • Index for video time 93610.58831111112 is 9441
  • Initialization finished loading
  • BufferController.onAppended
    • ScheduleController.onBytesAppended
    • ScheduleController.validate
    • ScheduleController.getRequiredFragmentCount
    • ScheduleController.getNextFragment
  • NextFragmentRequestRule.execute
    • scheduleController.getSeekTarget() == NaN
    • time = 0
  • Getting the request for video time : 0
  • SegmentTimeline: 0 / 93660.2025888889
  • Native video element event: loadedmetadata
  • PlaybackController.initialStart

After that, player plays the very first segment and stops while infinitely downloading new segments from live edge.

IE11, Edge

  • Start Event Controller
  • Getting the request for video time : 93610.58831111112
  • Index for video time 93610.58831111112 is 9441
  • Initialization finished loading
  • No appended events here
  • Native video element event: loadedmetadata
  • PlaybackController.initialStart

Everything plays as expected.

@lexaknyazev
Copy link
Contributor Author

More investigation on order of events after appending init segment:

Firefox 44, Chrome 48
  1. SourceBuffer.updateend
  2. VideoElement.loadedmetadata
IE11, Edge
  1. VideoElement.loadedmetadata
  2. SourceBuffer.updateend

@dsparacio
Copy link
Contributor

Which version. We believe this was addressed in Dev branch version 2.0.
Sorry didn't see the title! let me look closer.

@dsparacio
Copy link
Contributor

What stream are you testing? I only have this one live test stream with DVR window.
http://vm2.dashif.org/livesim-dev/segtimeline_1/testpic_2s/Manifest.mpd
This may have to be a known issue for 2.0.

@lexaknyazev
Copy link
Contributor Author

Stream is not public (I can send you a link), manifest at the moment:

<?xml version="1.0" encoding="UTF-8"?>
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" id="test"
     profiles="urn:mpeg:dash:profile:isoff-live:2011" type="dynamic"
     availabilityStartTime="2016-02-08T15:25:35.705592"
     publishTime="2016-02-08T15:25:35.704812" minimumUpdatePeriod="PT0S"
     minBufferTime="PT10S">
    <Period id="1" start="PT0S">
        <BaseURL>Period1/</BaseURL>
        <AdaptationSet mimeType="video/mp4" segmentAlignment="true">
            <SegmentTemplate timescale="90000"
                             media="$RepresentationID$/$Number$.m4v"
                             initialization="$RepresentationID$/init.m4v">
                <SegmentTimeline>
                    <S d="453323"/>
                    <S t="453323" d="865375" r="2041"/>
                </SegmentTimeline>
            </SegmentTemplate>
            <Representation width="1920" height="1080" codecs="avc1.4d002a"
                            id="Video1080" bandwidth="3000000">
                <InbandEventStream schemeIdUri="urn:mpeg:dash:event:2012"
                                   value="1"/>
            </Representation>
        </AdaptationSet>
    </Period>
</MPD>

@wilaw
Copy link
Member

wilaw commented Feb 8, 2016

The minimumUpdatePeriod for this manifest is declared as 0s. This is valid syntax and it declares that it should reload the manifest with each new segment that it retrieves. However, most players set up an interval timer to reload the manifest and hard code this to the value of minimumUpdatePeriod, which would be pretty fatal in this case.

Does dash.js handle minimumUpdatePeriod = 0s correctly?

Also , question for @lexaknyazev - isn't the SegmentTimeline info you are providing unused? The media template media="$RepresentationID$/$Number$.m4v" uses $Number$ substitution, not $Time. So the player is going use a default starting number of 1 and then build all its media URLs without referring to the SegmentTimeline info. I guess it can extract the default segment duration from that, but it would be much cleaner to provide that explicitly as a segmentTemplate attribute:

<SegmentTemplate timescale="90000"
                             media="$RepresentationID$/$Number$.m4v"
                             initialization="$RepresentationID$/init.m4v"
                             duration="865375">
</SegmentTemplate>

You could then set minimumUpdatePeriod="PT0S" to a more reasonable value like 30s, to avoid the encoder to constantly having to push new manifests and all clients from constantly having to retrieve them. In fact, since you are signalling inband events, there is no really no reason to reload the manifest at all and you could omit minimumUpdatePeriod entirely and have each client load the manifest exactly once.

@lexaknyazev
Copy link
Contributor Author

@wilaw

  1. minimumUpdatePeriod="PT0S" is used for leveraging InbandEventStream-based manifest updates (emsg boxes, afaik v2.1 target). dash.js has currently 2 seconds minimum limit.
    From DASH IF IOP v3.2, 4.5.1.1, Table 12: "MPD@minimumUpdatePeriod recommended/mandate to be set to 0 to indicate that frequent DASH events may occur".
  2. SegmentTimeline is used because there is a possibility of unequal segment durations and/or gaps in timeline.

@lexaknyazev
Copy link
Contributor Author

Just found an extremely dirty hack (it almost certainly breaks something somewhere) to make this stream work across all four browsers:

Index: src/streaming/controllers/ScheduleController.js
===================================================================
--- src/streaming/controllers/ScheduleController.js (revision 0b9edbc48905b0a05317f5a6ffa97201335c0758)
+++ src/streaming/controllers/ScheduleController.js (revision )
@@ -294,6 +294,7 @@
     }

     function onBytesAppended(e) {
+        if (isNaN(e.startTime)) return;
         if (e.sender.getStreamProcessor() !== streamProcessor) return;

         validate();

@dsparacio
Copy link
Contributor

@lexaknyazev that may not be extremely dirty and may be what we need but let me play around with it and see if I can come up with something better.

@lexaknyazev
Copy link
Contributor Author

AFAIR it was breaking static manifest playback, so I've changed that line to:

if (isDynamic && isNaN(e.startTime) && isNaN(seekTarget)) return;

@dsparacio
Copy link
Contributor

thanks for that update Ill check this out more in a bit.

@lexaknyazev
Copy link
Contributor Author

Seems to be fixed with #1242.

@dsparacio
Copy link
Contributor

@lexaknyazev wow great!. Nice side effect! I am also thinking this may fix a couple other related issues. - Have you tested enough to say your issue is fixed and we can close?

@lexaknyazev
Copy link
Contributor Author

Sadly, it is no more than a side effect: dash.js seeks to the correct live position after that PR but it still downloads the very first segment on Chrome and Firefox because of events order (see above):

[657686] Buffered Range: 0 - 18.36 
[657687] Buffered Range: 13444.82 - 13514.82

@dsparacio
Copy link
Contributor

OK thats good info. What ill do is reproduce it, add your fix line in, see result and then think if there is a cleaner way. I am not opposed to your fix we have a few of these blockers in place already for stuff like this. Again thanks for the quick response.

@dsparacio
Copy link
Contributor

@lexaknyazev regarding timeShiftBufferDepth is not present - I thought it had to be present with a value of more than 0 but I am not sure if this is the case but wanted to bring this up. I will check spec when I have a second....

@lexaknyazev
Copy link
Contributor Author

Specs on MPD@timeShiftBufferDepth:
ISO/IEC 23009-1:2014, p.20: "When not present, the value is infinite"
DASH IF IOP v3.2, p.27: "optional, but recommended"

@dsparacio
Copy link
Contributor

thanks you got to it before I did.

@lexaknyazev
Copy link
Contributor Author

Solved after #1278.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants