After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 776200 - dashdemux: Always parsing sidx for On-Demand profile
dashdemux: Always parsing sidx for On-Demand profile
Status: RESOLVED FIXED
Product: GStreamer
Classification: Platform
Component: gst-plugins-bad
git master
Other Linux
: Normal normal
: git master
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2016-12-17 07:35 UTC by Seungha Yang
Modified: 2017-03-15 11:28 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
dash: Split gst_isoff_sidx_parser_add_buffer() function (6.89 KB, patch)
2016-12-17 07:41 UTC, Seungha Yang
committed Details | Review
dashdemux: Always parsing sidx for On-Demand profile (4.17 KB, patch)
2016-12-17 07:41 UTC, Seungha Yang
none Details | Review
dashdemux: Always parsing sidx for On-Demand profile (4.38 KB, patch)
2016-12-20 03:00 UTC, Seungha Yang
committed Details | Review
dashdemux: Advance subfragment only if any (1.91 KB, patch)
2017-03-13 09:34 UTC, Seungha Yang
committed Details | Review
dashdemux: Exception handle in _sidx_seek() (1.29 KB, patch)
2017-03-15 03:25 UTC, Seungha Yang
committed Details | Review
dashdemux: Two depth seeking for On-Demand profile (2.63 KB, patch)
2017-03-15 03:25 UTC, Seungha Yang
committed Details | Review
dashdemux: Reset SIDX related variables per fragment (1.00 KB, patch)
2017-03-15 03:26 UTC, Seungha Yang
committed Details | Review
dashdemux: Do not advace subfragment after pending SIDX seek done (2.32 KB, patch)
2017-03-15 03:27 UTC, Seungha Yang
committed Details | Review
dashdemux: Drain buffer at the end of subfragment (2.14 KB, patch)
2017-03-15 03:27 UTC, Seungha Yang
committed Details | Review

Description Seungha Yang 2016-12-17 07:35:52 UTC
The indexRange attribute is optional and if it's not present, we should
extract the sidx box from incoming buffers.
Comment 1 Seungha Yang 2016-12-17 07:41:33 UTC
Created attachment 342109 [details] [review]
dash: Split gst_isoff_sidx_parser_add_buffer() function

To parsing sidx box itself with isobmff parser,
split gst_isoff_sidx_parser_add_buffer() into two parts.
Comment 2 Seungha Yang 2016-12-17 07:41:55 UTC
Created attachment 342110 [details] [review]
dashdemux: Always parsing sidx for On-Demand profile
Comment 3 Seungha Yang 2016-12-17 07:44:11 UTC
Some on-demand profile MPDs have no indexRange attribute. Spec. is saying that is optional.

http://dash.akamaized.net/dash264/TestCasesMCA/dolby/4/1/ChID_voices_71_384_448_768_ddp.mpd
Comment 4 Sebastian Dröge (slomo) 2016-12-19 09:07:30 UTC
Review of attachment 342110 [details] [review]:

Looks generally good, thanks

::: ext/dash/gstdashdemux.c
@@ +706,3 @@
+      stream->is_isobmff =
+          gst_structure_has_name (s, "video/quicktime") ||
+          gst_structure_has_name (s, "audio/x-m4a");

audio/x-m4a is generally isobmff, so only considering this for ondemand profile seems weird. While it's then unused for audio currently, this might change later and cause problems here

@@ +1166,2 @@
     stream->fragment.uri = fragment.uri;
+    /* If mpd does not specify indexRagne (i.e., null index_uri),

Typo

@@ +2439,3 @@
 
+  if (dashdemux->allow_trickmode_key_units ||
+      gst_mpd_client_has_isoff_ondemand_profile (dashdemux->client)) {

&& !SIDX (dashstream)->entries maybe?
Comment 5 Seungha Yang 2016-12-20 03:00:35 UTC
Created attachment 342244 [details] [review]
dashdemux: Always parsing sidx for On-Demand profile
Comment 6 Seungha Yang 2016-12-20 03:06:15 UTC
(In reply to Sebastian Dröge (slomo) from comment #4)
> Review of attachment 342110 [details] [review] [review]:
> 
> Looks generally good, thanks
> 
> ::: ext/dash/gstdashdemux.c
> @@ +706,3 @@
> +      stream->is_isobmff =
> +          gst_structure_has_name (s, "video/quicktime") ||
> +          gst_structure_has_name (s, "audio/x-m4a");
> 
> audio/x-m4a is generally isobmff, so only considering this for ondemand
> profile seems weird. While it's then unused for audio currently, this might
> change later and cause problems here

I modified the condition there.

> @@ +2439,3 @@
>  
> +  if (dashdemux->allow_trickmode_key_units ||
> +      gst_mpd_client_has_isoff_ondemand_profile (dashdemux->client)) {
> 
> && !SIDX (dashstream)->entries maybe?

Checking GST_ISOFF_SIDX_PARSER_FINISHED seems to be more straightforward and readable :)
Comment 7 Sebastian Dröge (slomo) 2016-12-20 10:56:35 UTC
Attachment 342109 [details] pushed as dfa300c - dash: Split gst_isoff_sidx_parser_add_buffer() function
Attachment 342244 [details] pushed as 124e386 - dashdemux: Always parsing sidx for On-Demand profile
Comment 8 Sebastian Dröge (slomo) 2017-03-03 18:52:34 UTC
(In reply to Seungha Yang from comment #3)
> Some on-demand profile MPDs have no indexRange attribute. Spec. is saying
> that is optional.

While the spec says that it's optional, it says that if the value is not given then it's "unknown" (for SegmentBase) or there is no index table (for SegmentList).

I don't see how that means that we should parse any sidx that we might find while parsing the segment and assume that it is valid for the whole media segment.


In my case I have a stream here that contains a SegmentList without index, and the SegmentList works as an index (it has the offsets of each fragment). However at the beginning of each fragment, there is a sidx that only describes the following moof. We're now parsing each of them one after another and have incomplete/unexpected information in the sidx index, which then causes infinite loops during parsing.

I'd revert these commits again unless you disagree, if anything we will have to do something more clever here than just blindly parsing any sidx that we might see somewhere.
Comment 9 Sebastian Dröge (slomo) 2017-03-03 20:48:17 UTC
We would need to accumulate the SIDX at least, and then make sure to set the current index to the correct value. This can probably be done based on the earliest_presentation_time.

The code right now replaces each SIDX with the new one, and just increments the current index (and then it usually points after the end of the SIDX array...)
Comment 10 Seungha Yang 2017-03-05 05:16:40 UTC
(In reply to Sebastian Dröge (slomo) from comment #8)
> (In reply to Seungha Yang from comment #3)

If your concern is the combination of sidx + SegmentList, I have a solution for it, actually (although I've never reported it on bugzilla), there are that kinds of streams in my private test contents. Can you provide your content? If possible, I'd like to report new patch for it.

Anyway, My idea is first find parent segment by SegmentList, and then do refinement using SIDX.
Comment 11 Seungha Yang 2017-03-05 05:29:58 UTC
Oops, my private contents are sidx + SegmentTemplate, sorry. But, it does not much differ to SegmentList anyway.
Comment 12 Sebastian Dröge (slomo) 2017-03-05 08:50:11 UTC
I don't think I can share my stream unfortunately, but if you can provide a patch that works for your content with SegmentTemplate then I can test it on mine and fix up anything that is missing.


(In reply to Seungha Yang from comment #10)
> Anyway, My idea is first find parent segment by SegmentList, and then do
> refinement using SIDX.

You mean first of all you go via the SegmentList/Template, and then inside a segment specified by that you would then search by SIDX? That should work, yes.

However you need to ensure that you handle the SIDX themselves correctly. In my case there is exactly one SIDX in front of each segment that contains exactly one entry (for the following segment). So you would have to accumulate all SIDX from past segments here (or always parse again when switching segments?).

Also I think there's nothing that forbids for example something like my case, but the SIDX actually contains information about the previous, next and following segment. Or about the next and all previous segments. This has to be all considered when parsing the SIDX to get a coherent view.
Comment 13 Seungha Yang 2017-03-05 11:39:17 UTC
(In reply to Sebastian Dröge (slomo) from comment #12)
> I don't think I can share my stream unfortunately, but if you can provide a
> patch that works for your content with SegmentTemplate then I can test it on
> mine and fix up anything that is missing.
Then, can you provide only MPD to me? (or only some part of it to figure out hierarchy of xml doc.) 
 
> Also I think there's nothing that forbids for example something like my
> case, but the SIDX actually contains information about the previous, next
> and following segment. Or about the next and all previous segments. This has
> to be all considered when parsing the SIDX to get a coherent view.

I'm a little bit confused by the terminology "Segment". Although I need to study the spec more, It does not seem to make sense that a SIDX has any information about outside of the "Segment" which SIDX belongs to. But it should include only the "Subsegment" information which SIDX belongs to, IMHO. In this context, your stream makes sense because each SIDX contains "Subsegment" index of which the SIDX belongs to.

In summary, it's still questionable that whether accumulating or searching prev/next "Segment" is necessary when parsing SIDX...
Comment 14 Sebastian Dröge (slomo) 2017-03-05 12:16:15 UTC
(In reply to Seungha Yang from comment #13)
> (In reply to Sebastian Dröge (slomo) from comment #12)
> > I don't think I can share my stream unfortunately, but if you can provide a
> > patch that works for your content with SegmentTemplate then I can test it on
> > mine and fix up anything that is missing.
> Then, can you provide only MPD to me? (or only some part of it to figure out
> hierarchy of xml doc.) 

It's basically

<MPD>
<Period>
<AdaptationSet>
<Representation>
<BaseURL>
<SegmentList>
<Initialization />
<SegmentURL mediaRange="..." />
<SegmentURL mediaRange="..." />
...

and the same repeated for other AdaptationSets


> > Also I think there's nothing that forbids for example something like my
> > case, but the SIDX actually contains information about the previous, next
> > and following segment. Or about the next and all previous segments. This has
> > to be all considered when parsing the SIDX to get a coherent view.
> 
> I'm a little bit confused by the terminology "Segment". Although I need to
> study the spec more, It does not seem to make sense that a SIDX has any
> information about outside of the "Segment" which SIDX belongs to. But it
> should include only the "Subsegment" information which SIDX belongs to,
> IMHO. In this context, your stream makes sense because each SIDX contains
> "Subsegment" index of which the SIDX belongs to.
> 
> In summary, it's still questionable that whether accumulating or searching
> prev/next "Segment" is necessary when parsing SIDX...

It might not be *necessary* but it should be handled in a useful way without breaking :)

If I remember the MP4 spec correctly, the content of the SIDX seems to be allowed to be basically anything. And at least the case of having entries in there further away then just the next fragment exists (e.g. in your stream), and the case where it only contains the next fragment and there's a new one before each fragment (e.g. my stream).

Both seem valid cases of fragmented MP4 streams. Mine seems to require some kind of accumulation of the SIDX (so you can get a "map" of the fragments outside the current fragment), although the same information is also available in the MPD at the DASH level (each SegmentURL is a byte-range into a single URL).
It could be equally possible that e.g. at the DASH level you have one "segment", but this points to a fragmented MP4 with two fragments (moof)... and either a SIDX with both at the beginning, or a SIDX with each one entry in front of each fragment.

I don't think it is necessary to support all theoretically possible combinations at this point, but we should at least handle them in a way that does not involve crashing or further breakage than needed. 


What do you think? I think as a first step it would be useful to just handle it like following: whenever a SIDX is found, you only parse that one and forget all others you saw before. The SIDX index is then updated according to the current offset so that we're not at the beginning of the SIDX but at the SIDX entry that represents what will now follow. If there is no entry that we can correlated to the fragment that follows, we just ignore the whole SIDX (which then possibly breaks seeking but not playback otherwise).
Comment 15 Seungha Yang 2017-03-05 13:37:45 UTC
(In reply to Sebastian Dröge (slomo) from comment #14)
Thanks for your detailed suggestion :)
Anyway, I guess your problem might be a bug of Attachment 342244 [details], I just found it. I'll update it soon.

About your suggestion, Can you confirm following is correct understanding?
Each SegmentURL shares the same url but only mediaRange is different.
> <MPD>
> <Period>
> <AdaptationSet>
> <Representation>
> <BaseURL>
> <SegmentList>
> <Initialization />
--> Let's call this "Segment1"
> <SegmentURL mediaRange="..." />  --> SIDX1 in front of moof, and only one entry for Segment1
--> Let's call this "Segment2"
> <SegmentURL mediaRange="..." />  --> SIDX2 in front of moof, and only one entry for Segment2
> ...

If my understanding is correct, I'm still confused why accumulation of SIDX might be necessary.... because SIDX1 belongs only to "Segment1"
Maybe, if your concern is the *possible* case that information of "Segment2" is informed not only by "SIDX2" but also by "SIDX1". 
If so, what we should do in this case is, ensuring/checking whether each SIDX.entries is inside of corresponding "Segment" or not. In other words, if some SIDX entries are outside of the corresponding "Segment", then just ignore it, although I'd like to think this case as *wrongly* encoded stream issue though :)

> What do you think? I think as a first step it would be useful to just handle
> it like following: whenever a SIDX is found, you only parse that one and
> forget all others you saw before. The SIDX index is then updated according
> to the current offset so that we're not at the beginning of the SIDX but at
> the SIDX entry that represents what will now follow. If there is no entry
> that we can correlated to the fragment that follows, we just ignore the
> whole SIDX (which then possibly breaks seeking but not playback otherwise).

"whole SIDX" is meaning the whole SIDX in the MPD? Isn't it enough that ignoring SIDX for the corresponding "Segment"?
Comment 16 Sebastian Dröge (slomo) 2017-03-05 14:35:29 UTC
(In reply to Seungha Yang from comment #15)
> (In reply to Sebastian Dröge (slomo) from comment #14)
> Thanks for your detailed suggestion :)
> Anyway, I guess your problem might be a bug of Attachment 342244 [details],
> I just found it. I'll update it soon.
> 
> About your suggestion, Can you confirm following is correct understanding?
> Each SegmentURL shares the same url but only mediaRange is different.
> > <MPD>
> > <Period>
> > <AdaptationSet>
> > <Representation>
> > <BaseURL>
> > <SegmentList>
> > <Initialization />
> --> Let's call this "Segment1"
> > <SegmentURL mediaRange="..." />  --> SIDX1 in front of moof, and only one entry for Segment1
> --> Let's call this "Segment2"
> > <SegmentURL mediaRange="..." />  --> SIDX2 in front of moof, and only one entry for Segment2
> > ...
> 
> If my understanding is correct

Your understanding is correct, yes

> I'm still confused why accumulation of SIDX
> might be necessary.... because SIDX1 belongs only to "Segment1"

For my stream yes, but there seems to be nothing that forbids something else. We need to at least check for these cases and handle them gracefully instead of e.g. crashing (currently things crash / use invalid memory on my stream already, which is not acceptable of course :) )

> Maybe, if your concern is the *possible* case that information of "Segment2"
> is informed not only by "SIDX2" but also by "SIDX1". 
> If so, what we should do in this case is, ensuring/checking whether each
> SIDX.entries is inside of corresponding "Segment" or not. In other words, if
> some SIDX entries are outside of the corresponding "Segment", then just
> ignore it, although I'd like to think this case as *wrongly* encoded stream
> issue though :)

I don't think it's invalid. But yes, I agree otherwise

> > What do you think? I think as a first step it would be useful to just handle
> > it like following: whenever a SIDX is found, you only parse that one and
> > forget all others you saw before. The SIDX index is then updated according
> > to the current offset so that we're not at the beginning of the SIDX but at
> > the SIDX entry that represents what will now follow. If there is no entry
> > that we can correlated to the fragment that follows, we just ignore the
> > whole SIDX (which then possibly breaks seeking but not playback otherwise).
> 
> "whole SIDX" is meaning the whole SIDX in the MPD? Isn't it enough that
> ignoring SIDX for the corresponding "Segment"?

The whole SIDX of that segment, so yes what you said :)
Comment 17 Seungha Yang 2017-03-05 23:09:58 UTC
Thanks. everything becomes clear now.
I'll update a patch to fix SIDX bug first, then will report another patch for sanity checking as much as possible :)
Comment 18 Sebastian Dröge (slomo) 2017-03-06 17:37:20 UTC
The way how seeking is done with the SIDX, it also seems to assume to have information about *all* fragments in the SIDX. Not just the current one. So if we only ever have the current one in there (as for my stream), SIDX based seeking would not know what to do.
Comment 19 Seungha Yang 2017-03-07 01:12:16 UTC
(In reply to Sebastian Dröge (slomo) from comment #18)
> The way how seeking is done with the SIDX, it also seems to assume to have
> information about *all* fragments in the SIDX. Not just the current one. So
> if we only ever have the current one in there (as for my stream), SIDX based
> seeking would not know what to do.
==> From my view point for SIDX, it is used to know how "a Segment" is divided into "Subsegments"
So, we can just ignore the SIDX in your case, since the SIDX only contains only *one* subsegment information.


ISOBMFF is saying that
"Each Segment Index box documents how a (sub)segment is divided into one or more  subsegments (which may themselves be further subdivided using Segment Index boxes).	
In that context, my understanding about SIDX is, the coverage of SIDX is varying depending on how the "Segment" is defined.
For example, in case of usual On-Demand profile with SegmentBase, I'd like to say there is only one "Segment" in each media stream. And, the *one* "Segment" is divided into "Subsegments" by SIDX (which has full list of "Subsegments"). And, SegmentList/SegmentTemplate cases, each list of url-defined, byte-ranged or template fragment is a "Segment". And, each "fragment" might be subdivided into "Subsegment" if there is SIDX. So, we can seek to more precise position using the SIDX.
So, the my conclusion about SIDX based seeking is,
we should 2 step seeking if SIDX is there. The first is MPD based (which defines top level "Segment" division) and the last is refinement a "Segment" using SIDX (if there). So, we can just concentrate on the current "Segment", and if any SIDX entries which pointing outside of the "Segment" can be ignored.
Comment 20 Sebastian Dröge (slomo) 2017-03-07 06:23:51 UTC
(In reply to Seungha Yang from comment #19)
> (In reply to Sebastian Dröge (slomo) from comment #18)
> > The way how seeking is done with the SIDX, it also seems to assume to have
> > information about *all* fragments in the SIDX. Not just the current one. So
> > if we only ever have the current one in there (as for my stream), SIDX based
> > seeking would not know what to do.
> ==> From my view point for SIDX, it is used to know how "a Segment" is
> divided into "Subsegments"
> So, we can just ignore the SIDX in your case, since the SIDX only contains
> only *one* subsegment information.

Yes, correct

> ISOBMFF is saying that
> [...]
> So, the my conclusion about SIDX based seeking is,
> we should 2 step seeking if SIDX is there. The first is MPD based (which
> defines top level "Segment" division) and the last is refinement a "Segment"
> using SIDX (if there). So, we can just concentrate on the current "Segment",
> and if any SIDX entries which pointing outside of the "Segment" can be
> ignored.

Correct, that is also my understanding but not how the code does it right now. Which is what I wanted to point out above. The code assumes that if isobmff-ondemand (i.e. sidx), then we only have to look into the sidx for seeking.

See gst_dash_demux_stream_seek() which always returns if sidx after seeking based on the sidx (even if the target position is not in the sidx and we need to go to the code below that block where segments are switched).

So that has to be changed too here
Comment 21 Sebastian Dröge (slomo) 2017-03-13 09:28:55 UTC
Hi Seungha, did you already make any progress on this or need to discuss anything about the implementation? Let me know :)
Comment 22 Seungha Yang 2017-03-13 09:34:47 UTC
Created attachment 347815 [details] [review]
dashdemux: Advance subfragment only if any

SIDX based playback is not restricted to SegmentBase, but it possible
with SegmentList/SegmentTemplate. In the latter case, each fragment
has its own SIDX box and might be subdivided into subfragment.
So, demux should not assume that the end of subfragment is the end
of stream. Moreover, should try advance subfragment only if there
are remaining subfragments.
Comment 23 Seungha Yang 2017-03-13 09:38:13 UTC
(In reply to Sebastian Dröge (slomo) from comment #21)
> Hi Seungha, did you already make any progress on this or need to discuss
> anything about the implementation? Let me know :)

Sorry for late implementation... I hope attachment 347815 [details] [review] can fix normal playback of yours. But there are still some bugs on seeking and end of fragment handling. I'm keeping working on it.
Comment 24 Sebastian Dröge (slomo) 2017-03-14 17:13:17 UTC
Review of attachment 347815 [details] [review]:

::: ext/dash/gstdashdemux.c
@@ +2749,3 @@
                 && (GST_ADAPTIVE_DEMUX (stream->demux)->
                     segment.flags & GST_SEGMENT_FLAG_TRICKMODE_KEY_UNITS))
+            && advance && gst_dash_demux_stream_has_next_subfragment (stream)) {

Unfortunately this does not solve anything. It doesn't advance here, then loops and tries to get 0 bytes (sidx_end_offset - dash_stream->sidx_current_offset) from the adapter forever
Comment 25 Sebastian Dröge (slomo) 2017-03-14 17:15:51 UTC
commit a9c34fb9e3b6cfd494decd107b744d39cd1dc791
Author: Seungha Yang <sh.yang@lge.com>
Date:   Tue Mar 7 21:56:03 2017 +0900

    dashdemux: Advance subfragment only if any exist
    
    SIDX based playback is not restricted to SegmentBase, but it possible
    with SegmentList/SegmentTemplate. In the latter case, each fragment
    has its own SIDX box and might be subdivided into subfragment.
    So, demux should not assume that the end of subfragment is the end
    of stream. Moreover, should try advance subfragment only if there
    are remaining subfragments.
    
    With additional fixes by Sebastian Dröge <sebastian@centricular.com>
    
    https://bugzilla.gnome.org/show_bug.cgi?id=776200
Comment 26 Seungha Yang 2017-03-15 00:03:15 UTC
(In reply to Sebastian Dröge (slomo) from comment #24)
> Review of attachment 347815 [details] [review] [review]:
> 
> Unfortunately this does not solve anything. It doesn't advance here, then
> loops and tries to get 0 bytes (sidx_end_offset -
> dash_stream->sidx_current_offset) from the adapter forever

OK, I can also reproduce it by using my test streams.
Comment 27 Seungha Yang 2017-03-15 03:25:06 UTC
Created attachment 347973 [details] [review]
dashdemux: Exception handle in _sidx_seek()

If target seek position is outside of the range of sidx entries,
binary search returns NULL pointer.
Comment 28 Seungha Yang 2017-03-15 03:25:50 UTC
Created attachment 347974 [details] [review]
dashdemux: Two depth seeking for On-Demand profile

Try to find fragment using MPD first, then do refinement to find
target subframgnet using SIDX if possible. Note that, if target fragment
was moved from the previously activated one, we should assume that
the last SIDX is invalid for new fragment.
Comment 29 Seungha Yang 2017-03-15 03:26:21 UTC
Created attachment 347975 [details] [review]
dashdemux: Reset SIDX related variables per fragment

SIDX's base offset (i.e., byte offset of SIDX + sidx.first_offset)
mostly vary as per fragment. Also, target SIDX index must be zero for the
new fragment.
Comment 30 Seungha Yang 2017-03-15 03:27:10 UTC
Created attachment 347976 [details] [review]
dashdemux: Do not advace subfragment after pending SIDX seek done

If a MPD is On-Demand profile and no index described, demux will terminate
download loop after parsing inband SIDX with flow return custom-success.
At this moment, SIDX index is excat target position, but finish_fragment()
might cause re-advancing subfragment depending on MPD structure.
Comment 31 Seungha Yang 2017-03-15 03:27:41 UTC
Created attachment 347977 [details] [review]
dashdemux: Drain buffer at the end of subfragment

Some of streams such as below have tailing boxes at the end of subfragment.
http://dash.akamaized.net/dash264/TestCases/1a/netflix/exMPD_BIP_TC1.mpd
Comment 32 Sebastian Dröge (slomo) 2017-03-15 08:40:16 UTC
Thanks, these patches look all good and I'll push them together with some additional changes I have locally here once I'm finished with them (there are some invalid memory accesses in relation to the sidx index).
Comment 33 Sebastian Dröge (slomo) 2017-03-15 11:27:53 UTC
Attachment 347973 [details] pushed as ad015ce - dashdemux: Exception handle in _sidx_seek()
Attachment 347974 [details] pushed as a599067 - dashdemux: Two depth seeking for On-Demand profile
Attachment 347975 [details] pushed as b65e6db - dashdemux: Reset SIDX related variables per fragment
Attachment 347976 [details] pushed as 42a38b6 - dashdemux: Do not advace subfragment after pending SIDX seek done
Attachment 347977 [details] pushed as 644192a - dashdemux: Drain buffer at the end of subfragment