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

Live DASH playback fails if Period@start changes #3457

Closed
noamtamim opened this issue Nov 14, 2017 · 11 comments
Closed

Live DASH playback fails if Period@start changes #3457

noamtamim opened this issue Nov 14, 2017 · 11 comments
Assignees

Comments

@noamtamim
Copy link
Contributor

Issue description

A DASH live stream fails to play in ExoPlayer due to what seems like timing issues. The log is shown below.

The first frame is shown, but playback does not continue.

For reference, it also doesn't work in ShakaPlayer, but it does work in bitmovin and dash.js web players.

Reproduction steps

Add the URL to media.exolist.json in ExoPlayer's demo app. No DRM setup is required.

Link to test content

Will be sent in email.

Version of ExoPlayer being used

r2.5.4 (with gradle changes to support Android Studio 3.0.0).

Device(s) and version(s) of Android being used

Nexus 5X, Android 8.0.0.

A full bug report captured from the device

I don't think the full ADB bugreport is relevant, but here's the logcat:

11-14 14:08:10.870 2163-2163/com.google.android.exoplayer2.demo I/ExoPlayerImpl: Init bbc4cad [ExoPlayerLib/2.5.4] [bullhead, Nexus 5X, LGE, 26]
11-14 14:08:10.873 2163-2163/com.google.android.exoplayer2.demo D/EventLogger: state [0.00, true, I]
11-14 14:08:10.884 2163-2163/com.google.android.exoplayer2.demo D/EventLogger: state [0.02, true, B]
11-14 14:08:10.973 2163-2191/com.google.android.exoplayer2.demo D/OpenGLRenderer: endAllActiveAnimators on 0x791622cc00 (ExpandableListView) with handle 0x792d8e67a0
11-14 14:08:11.307 2163-2163/com.google.android.exoplayer2.demo D/EventLogger: sourceInfo [periodCount=1, windowCount=1
11-14 14:08:11.307 2163-2163/com.google.android.exoplayer2.demo D/EventLogger:   period [?]
11-14 14:08:11.308 2163-2163/com.google.android.exoplayer2.demo D/EventLogger:   window [29.98, true, true]
11-14 14:08:11.308 2163-2163/com.google.android.exoplayer2.demo D/EventLogger: ]
11-14 14:08:11.315 2163-2168/com.google.android.exoplayer2.demo I/zygote64: Do full code cache collection, code=251KB, data=192KB
11-14 14:08:11.316 2163-2168/com.google.android.exoplayer2.demo I/zygote64: After code cache collection, code=249KB, data=154KB
11-14 14:08:11.323 2163-2163/com.google.android.exoplayer2.demo D/EventLogger: loading [true]
11-14 14:08:11.335 2163-2163/com.google.android.exoplayer2.demo D/EventLogger: Tracks [
11-14 14:08:11.335 2163-2163/com.google.android.exoplayer2.demo D/EventLogger:   Renderer:0 [
11-14 14:08:11.336 2163-2163/com.google.android.exoplayer2.demo D/EventLogger:     Group:0, adaptive_supported=YES [
11-14 14:08:11.336 2163-2163/com.google.android.exoplayer2.demo D/EventLogger:       [X] Track:0, id=v0_273, mimeType=video/avc, bitrate=1600000, res=960x540, fps=25.0, supported=YES
11-14 14:08:11.336 2163-2163/com.google.android.exoplayer2.demo D/EventLogger:       [X] Track:1, id=v1_273, mimeType=video/avc, bitrate=1100000, res=854x480, fps=25.0, supported=YES
11-14 14:08:11.336 2163-2163/com.google.android.exoplayer2.demo D/EventLogger:       [X] Track:2, id=v2_273, mimeType=video/avc, bitrate=600000, res=640x360, fps=25.0, supported=YES
11-14 14:08:11.336 2163-2163/com.google.android.exoplayer2.demo D/EventLogger:       [X] Track:3, id=v3_273, mimeType=video/avc, bitrate=300000, res=480x270, fps=25.0, supported=YES
11-14 14:08:11.336 2163-2163/com.google.android.exoplayer2.demo D/EventLogger:     ]
11-14 14:08:11.337 2163-2163/com.google.android.exoplayer2.demo D/EventLogger:   ]
11-14 14:08:11.337 2163-2163/com.google.android.exoplayer2.demo D/EventLogger:   Renderer:1 [
11-14 14:08:11.337 2163-2163/com.google.android.exoplayer2.demo D/EventLogger:     Group:0, adaptive_supported=N/A [
11-14 14:08:11.337 2163-2163/com.google.android.exoplayer2.demo D/EventLogger:       [X] Track:0, id=v3_546, mimeType=audio/mp4a-latm, bitrate=64000, channels=2, sample_rate=24000, language=rus, supported=YES
11-14 14:08:11.337 2163-2163/com.google.android.exoplayer2.demo D/EventLogger:     ]
11-14 14:08:11.337 2163-2163/com.google.android.exoplayer2.demo D/EventLogger:     Group:1, adaptive_supported=N/A [
11-14 14:08:11.337 2163-2163/com.google.android.exoplayer2.demo D/EventLogger:       [ ] Track:0, id=v3_819, mimeType=audio/mp4a-latm, bitrate=32000, channels=2, sample_rate=24000, language=rus, supported=YES
11-14 14:08:11.337 2163-2163/com.google.android.exoplayer2.demo D/EventLogger:     ]
11-14 14:08:11.337 2163-2163/com.google.android.exoplayer2.demo D/EventLogger:   ]
11-14 14:08:11.337 2163-2163/com.google.android.exoplayer2.demo D/EventLogger: ]
11-14 14:08:11.339 2163-2163/com.google.android.exoplayer2.demo D/EventLogger: videoEnabled [0.47]
11-14 14:08:11.339 2163-2163/com.google.android.exoplayer2.demo D/EventLogger: audioEnabled [0.47]
11-14 14:08:11.919 2163-2163/com.google.android.exoplayer2.demo D/EventLogger: audioDecoderInitialized [1.05, OMX.google.aac.decoder]
11-14 14:08:11.921 2163-2163/com.google.android.exoplayer2.demo D/EventLogger: audioFormatChanged [1.05, id=v3_546, mimeType=audio/mp4a-latm, bitrate=64000, channels=2, sample_rate=24000, language=und]
11-14 14:08:12.054 2163-2295/com.google.android.exoplayer2.demo D/SurfaceUtils: connecting to surface 0x7912a17010, reason connectToSurface
11-14 14:08:12.054 2163-2295/com.google.android.exoplayer2.demo I/MediaCodec: [OMX.qcom.video.decoder.avc] setting surface generation to 2214914
11-14 14:08:12.055 2163-2295/com.google.android.exoplayer2.demo D/SurfaceUtils: disconnecting from surface 0x7912a17010, reason connectToSurface(reconnect)
11-14 14:08:12.055 2163-2295/com.google.android.exoplayer2.demo D/SurfaceUtils: connecting to surface 0x7912a17010, reason connectToSurface(reconnect)
11-14 14:08:12.091 2163-2296/com.google.android.exoplayer2.demo D/SurfaceUtils: set up nativeWindow 0x7912a17010 for 640x360, color 0x7fa30c04, rotation 0, usage 0x42002900
11-14 14:08:12.102 2163-2163/com.google.android.exoplayer2.demo D/EventLogger: videoDecoderInitialized [1.23, OMX.qcom.video.decoder.avc]
11-14 14:08:12.103 2163-2163/com.google.android.exoplayer2.demo D/EventLogger: videoFormatChanged [1.23, id=v2_273, mimeType=video/avc, bitrate=600000, res=640x360, fps=25.0]
11-14 14:08:12.128 2163-2296/com.google.android.exoplayer2.demo D/SurfaceUtils: set up nativeWindow 0x7912a17010 for 640x368, color 0x7fa30c04, rotation 0, usage 0x42002900
11-14 14:08:12.186 2163-2163/com.google.android.exoplayer2.demo D/EventLogger: videoSizeChanged [640, 360]
11-14 14:08:12.187 2163-2163/com.google.android.exoplayer2.demo D/EventLogger: renderedFirstFrame [Surface(name=null)/@0x6007bcf]
11-14 14:08:12.570 2163-2287/com.google.android.exoplayer2.demo D/AudioTrack: Client defaulted notificationFrames to 6000 for frameCount 12000
11-14 14:08:12.575 2163-2163/com.google.android.exoplayer2.demo D/EventLogger: audioSessionId [1393]
11-14 14:08:13.166 2163-2168/com.google.android.exoplayer2.demo I/zygote64: Do partial code cache collection, code=251KB, data=165KB
11-14 14:08:13.167 2163-2168/com.google.android.exoplayer2.demo I/zygote64: After code cache collection, code=251KB, data=165KB
11-14 14:08:13.167 2163-2168/com.google.android.exoplayer2.demo I/zygote64: Increasing code cache capacity to 1024KB
11-14 14:08:13.205 2163-2163/com.google.android.exoplayer2.demo D/EventLogger: state [2.34, true, R]
11-14 14:08:13.295 2163-2163/com.google.android.exoplayer2.demo D/EventLogger: sourceInfo [periodCount=1, windowCount=1
11-14 14:08:13.295 2163-2163/com.google.android.exoplayer2.demo D/EventLogger:   period [?]
11-14 14:08:13.296 2163-2163/com.google.android.exoplayer2.demo D/EventLogger:   window [29.97, true, true]
11-14 14:08:13.296 2163-2163/com.google.android.exoplayer2.demo D/EventLogger: ]
11-14 14:08:13.313 2163-2295/com.google.android.exoplayer2.demo D/SurfaceUtils: disconnecting from surface 0x7912a17010, reason disconnectFromSurface
11-14 14:08:13.315 2163-2163/com.google.android.exoplayer2.demo D/EventLogger: state [2.45, true, E]
11-14 14:08:13.327 2163-2163/com.google.android.exoplayer2.demo D/EventLogger: videoDisabled [2.46]
11-14 14:08:13.331 2163-2163/com.google.android.exoplayer2.demo D/EventLogger: audioDisabled [2.46]
11-14 14:08:13.332 2163-2163/com.google.android.exoplayer2.demo D/EventLogger: loading [false]
11-14 14:08:15.309 2163-2163/com.google.android.exoplayer2.demo D/EventLogger: sourceInfo [periodCount=1, windowCount=1
11-14 14:08:15.310 2163-2163/com.google.android.exoplayer2.demo D/EventLogger:   period [?]
11-14 14:08:15.311 2163-2163/com.google.android.exoplayer2.demo D/EventLogger:   window [29.97, true, true]
11-14 14:08:15.311 2163-2163/com.google.android.exoplayer2.demo D/EventLogger: ]
11-14 14:08:17.157 2163-2163/com.google.android.exoplayer2.demo D/EventLogger: sourceInfo [periodCount=1, windowCount=1
11-14 14:08:17.157 2163-2163/com.google.android.exoplayer2.demo D/EventLogger:   period [?]
11-14 14:08:17.158 2163-2163/com.google.android.exoplayer2.demo D/EventLogger:   window [29.96, true, true]
11-14 14:08:17.159 2163-2163/com.google.android.exoplayer2.demo D/EventLogger: ]
11-14 14:08:19.301 2163-2163/com.google.android.exoplayer2.demo D/EventLogger: sourceInfo [periodCount=1, windowCount=1
11-14 14:08:19.301 2163-2163/com.google.android.exoplayer2.demo D/EventLogger:   period [?]
11-14 14:08:19.302 2163-2163/com.google.android.exoplayer2.demo D/EventLogger:   window [28.03, true, true]
11-14 14:08:19.302 2163-2163/com.google.android.exoplayer2.demo D/EventLogger: ]
11-14 14:08:21.264 2163-2163/com.google.android.exoplayer2.demo D/EventLogger: state [10.40, false, E]
11-14 14:08:21.433 2163-2163/com.google.android.exoplayer2.demo D/EventLogger: sourceInfo [periodCount=1, windowCount=1
11-14 14:08:21.434 2163-2163/com.google.android.exoplayer2.demo D/EventLogger:   period [?]
11-14 14:08:21.434 2163-2163/com.google.android.exoplayer2.demo D/EventLogger:   window [28.00, true, true]
11-14 14:08:21.434 2163-2163/com.google.android.exoplayer2.demo D/EventLogger: ]
11-14 14:08:23.301 2163-2163/com.google.android.exoplayer2.demo D/EventLogger: sourceInfo [periodCount=1, windowCount=1
11-14 14:08:23.301 2163-2163/com.google.android.exoplayer2.demo D/EventLogger:   period [?]
11-14 14:08:23.302 2163-2163/com.google.android.exoplayer2.demo D/EventLogger:   window [29.99, true, true]
11-14 14:08:23.302 2163-2163/com.google.android.exoplayer2.demo D/EventLogger: ]
11-14 14:08:25.137 2163-2163/com.google.android.exoplayer2.demo D/EventLogger: sourceInfo [periodCount=1, windowCount=1
11-14 14:08:25.138 2163-2163/com.google.android.exoplayer2.demo D/EventLogger:   period [?]
11-14 14:08:25.139 2163-2163/com.google.android.exoplayer2.demo D/EventLogger:   window [29.99, true, true]
11-14 14:08:25.139 2163-2163/com.google.android.exoplayer2.demo D/EventLogger: ]
11-14 14:08:27.279 2163-2163/com.google.android.exoplayer2.demo D/EventLogger: sourceInfo [periodCount=1, windowCount=1
11-14 14:08:27.279 2163-2163/com.google.android.exoplayer2.demo D/EventLogger:   period [?]
11-14 14:08:27.280 2163-2163/com.google.android.exoplayer2.demo D/EventLogger:   window [28.01, true, true]
11-14 14:08:27.280 2163-2163/com.google.android.exoplayer2.demo D/EventLogger: ]
11-14 14:08:29.443 2163-2163/com.google.android.exoplayer2.demo D/EventLogger: sourceInfo [periodCount=1, windowCount=1
11-14 14:08:29.443 2163-2163/com.google.android.exoplayer2.demo D/EventLogger:   period [?]
11-14 14:08:29.445 2163-2163/com.google.android.exoplayer2.demo D/EventLogger:   window [28.02, true, true]
11-14 14:08:29.445 2163-2163/com.google.android.exoplayer2.demo D/EventLogger: ]
11-14 14:08:31.292 2163-2163/com.google.android.exoplayer2.demo D/EventLogger: sourceInfo [periodCount=1, windowCount=1
11-14 14:08:31.292 2163-2163/com.google.android.exoplayer2.demo D/EventLogger:   period [?]
11-14 14:08:31.293 2163-2163/com.google.android.exoplayer2.demo D/EventLogger:   window [28.02, true, true]
11-14 14:08:31.293 2163-2163/com.google.android.exoplayer2.demo D/EventLogger: ]
11-14 14:08:33.429 2163-2163/com.google.android.exoplayer2.demo D/EventLogger: sourceInfo [periodCount=1, windowCount=1
11-14 14:08:33.429 2163-2163/com.google.android.exoplayer2.demo D/EventLogger:   period [?]
11-14 14:08:33.430 2163-2163/com.google.android.exoplayer2.demo D/EventLogger:   window [28.03, true, true]
11-14 14:08:33.430 2163-2163/com.google.android.exoplayer2.demo D/EventLogger: ]
11-14 14:08:35.281 2163-2163/com.google.android.exoplayer2.demo D/EventLogger: sourceInfo [periodCount=1, windowCount=1
11-14 14:08:35.282 2163-2163/com.google.android.exoplayer2.demo D/EventLogger:   period [?]
11-14 14:08:35.283 2163-2163/com.google.android.exoplayer2.demo D/EventLogger:   window [28.04, true, true]
11-14 14:08:35.283 2163-2163/com.google.android.exoplayer2.demo D/EventLogger: ]
11-14 14:08:37.121 2163-2163/com.google.android.exoplayer2.demo D/EventLogger: sourceInfo [periodCount=1, windowCount=1
11-14 14:08:37.121 2163-2163/com.google.android.exoplayer2.demo D/EventLogger:   period [?]
11-14 14:08:37.122 2163-2163/com.google.android.exoplayer2.demo D/EventLogger:   window [28.04, true, true]
11-14 14:08:37.122 2163-2163/com.google.android.exoplayer2.demo D/EventLogger: ]
11-14 14:08:39.274 2163-2163/com.google.android.exoplayer2.demo D/EventLogger: sourceInfo [periodCount=1, windowCount=1
11-14 14:08:39.274 2163-2163/com.google.android.exoplayer2.demo D/EventLogger:   period [?]
11-14 14:08:39.275 2163-2163/com.google.android.exoplayer2.demo D/EventLogger:   window [28.00, true, true]
11-14 14:08:39.275 2163-2163/com.google.android.exoplayer2.demo D/EventLogger: ]
11-14 14:08:41.427 2163-2163/com.google.android.exoplayer2.demo D/EventLogger: sourceInfo [periodCount=1, windowCount=1
11-14 14:08:41.427 2163-2163/com.google.android.exoplayer2.demo D/EventLogger:   period [?]
11-14 14:08:41.428 2163-2163/com.google.android.exoplayer2.demo D/EventLogger:   window [28.01, true, true]
11-14 14:08:41.428 2163-2163/com.google.android.exoplayer2.demo D/EventLogger: ]
@ojw28
Copy link
Contributor

ojw28 commented Nov 15, 2017

The media does not seem to be spec compliant. In particular, I think that:

  1. The "start" attribute of the period should not be increasing each time the manifest is refreshed. The fact that not all of the media from the period is available any more does not change when the period started.
  2. The "presentationTimeOffset" attributes should not be increasing each time the manifest is refreshed either. This is likely being done to compensate for the initial error of increasing the "start" attribute.

Fixing these issues should allow the content to play successfully across all players.

@itaykinnrot
Copy link
Contributor

thanks @ojw28 we'll check it!

@noamtamim
Copy link
Contributor Author

Hi @ojw28
We looked at the standard: http://dashif.org/w/2015/04/DASH-IF-IOP-v3.0.pdf

It says:
“In order to make the MPD joining friendly and to remove data that is available in the past,
any segments that have fallen out of the time shift buffer may no longer be announced
in the MPD. In this case, the Period start may be moved by changing one or both,
MPD@availabilityStartTime and Period@start. However, this requires that the
@startNumber, @presentationTimeOffset and S values need to be updated such
that the Segment Information according to section 4.3.2.2.6 is not modified over an MPD update.”

Please check this again.

@ojw28
Copy link
Contributor

ojw28 commented Nov 16, 2017

Thanks for the reference. I think we might need to discuss this with the DASH-IF authors. I can't think of a good reason for needing to change Period@start, and if there isn't a good reason then I don't see why it should be allowed as an optional thing. It would just be one more thing for clients to have to deal with for no benefit. It's also quite confusing. Note that it's not required to adjust Period@start to remove data or make the MPD joining friendly.

In the meantime, I would still advise changing the way your manifests update to be as I described above. It would be inline with how manifest updates occur in most of the other live streams I've seen, I think, and I suspect it will make your streams compatible with a wider range of clients.

@sandersaares
Copy link

In this case, the Period start may be moved by changing one or both, MPD@availabilityStartTime and Period@start

It appears to me that the first part of the statement directly contradicts DASH 8.4.2 which says:

When the MPD is updated, the value of MPD@availabilityStartTime shall be the same in the original and the updated MPD

While AST does not appear to be relevant in case of the content in question here, it does serve as additional evidence that this part of the guidelines might deserve a review.

@ojw28 ojw28 changed the title Live DASH playback fails Live DASH playback fails if Period@start changes Nov 16, 2017
@ojw28
Copy link
Contributor

ojw28 commented Nov 17, 2017

  • Thanks for the comment :)! I'll file a review request and add a reference to it from here for tracking.
  • As an additional point, I think allowing the period start time to change can make it impossible to work out whether a period in an updated manifest is the same one as in the previous manifest. In particular, this can occur if there's no overlap between the media in the two manifests (note that Period@id is optional in the DASH spec, and so cannot be relied upon to identify that the period is the same). This is admittedly an edge case, since during normal playback you'd always expect there to be overlap between successive manifests, but either way things are much easier if you can just use Period@start to match a period in the updated manifest to one in the previous one.

@ojw28
Copy link
Contributor

ojw28 commented Nov 17, 2017

DASH-IF question filed here: Dash-Industry-Forum/DASH-IF-IOP#160

@sandersaares
Copy link

sandersaares commented Nov 21, 2017

note that Period@id is optional in the DASH spec, and so cannot be relied upon to identify that the period is the same

Based on my reading, this attribute is only optional for static manifests, so it could actually be used to determine period identity in case of dynamic manifests.

Here's the relevant snippet from DASH spec:

If the MPD@type is "dynamic", then this attribute shall be present and shall not change in case the MPD is updated.

@ojw28
Copy link
Contributor

ojw28 commented Nov 21, 2017

Ah, thanks, that's good to know!

@ojw28
Copy link
Contributor

ojw28 commented Feb 26, 2018

Marking as wontfix for now on the assumption that the DASH-IF guidelines will be amended.

@ojw28
Copy link
Contributor

ojw28 commented Apr 9, 2018

DASH IF guidelines v4.2 has been amended to prevent the type of manifest update described here. In 4.4.3.3:

MPD@availabilityStartTime and Period@start shall not be changed over MPD updates.

Closing this. Thanks!

@ojw28 ojw28 closed this as completed Apr 9, 2018
@google google locked and limited conversation to collaborators Aug 10, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants