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

ExoPlayer2 crashes when fetching a Dash manifest with no SegmentTimeline items (yet) #1865

Closed
aletorrado opened this issue Sep 27, 2016 · 9 comments
Labels

Comments

@aletorrado
Copy link

When doing a live broadcast, and the transmission just started, the Dash manifest may have an empty SegmentTimeline (while the first chunk is getting filled). ExoPlayer2 crashes on that moment.

This is the manifest I'm testing:

<?xml version="1.0" encoding="utf-8"?>
<MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="urn:mpeg:dash:schema:mpd:2011"
    xmlns:xlink="http://www.w3.org/1999/xlink"
    xsi:schemaLocation="urn:mpeg:DASH:schema:MPD:2011 http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-DASH_schema_files/DASH-MPD.xsd"
    profiles="urn:mpeg:dash:profile:isoff-live:2011"
    type="dynamic"
    minimumUpdatePeriod="PT0S"
    suggestedPresentationDelay="PT0S"
    publishTime="2016-09-27T16:48:01"
    timeShiftBufferDepth="PT0.0S"
    minBufferTime="PT0.0S">
    <ProgramInformation>
    </ProgramInformation>
    <Period start="PT0.0S">
        <AdaptationSet contentType="video" segmentAlignment="true" bitstreamSwitching="true" frameRate="90000/1">
            <Representation id="0" mimeType="video/mp4" codecs="avc1.640034" bandwidth="1000000" width="1280" height="720" frameRate="90000/1">
                <SegmentTemplate timescale="90000" initialization="init-stream$RepresentationID$.m4s" media="chunk-stream$RepresentationID$-$Number%05d$.m4s" startNumber="1">
                    <SegmentTimeline>
                    </SegmentTimeline>
                </SegmentTemplate>
            </Representation>
        </AdaptationSet>
        <AdaptationSet contentType="audio" segmentAlignment="true" bitstreamSwitching="true">
            <Representation id="1" mimeType="audio/mp4" codecs="mp4a.40.2" bandwidth="128000" audioSamplingRate="44100">
                <AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2" />
                <SegmentTemplate timescale="44100" initialization="init-stream$RepresentationID$.m4s" media="chunk-stream$RepresentationID$-$Number%05d$.m4s" startNumber="1">
                    <SegmentTimeline>
                    </SegmentTimeline>
                </SegmentTemplate>
            </Representation>
        </AdaptationSet>
    </Period>
</MPD>

And here is an example of the stack trace I'm getting:

java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
      at java.util.ArrayList.get(ArrayList.java:411)
      at com.google.android.exoplayer2.source.dash.manifest.SegmentBase$MultiSegmentBase.getSegmentTimeUs(SegmentBase.java:190)
      at com.google.android.exoplayer2.source.dash.manifest.Representation$MultiSegmentRepresentation.getTimeUs(Representation.java:257)
      at com.google.android.exoplayer2.source.dash.DashMediaSource$PeriodSeekInfo.createPeriodSeekInfo(DashMediaSource.java:493)
      at com.google.android.exoplayer2.source.dash.DashMediaSource.processManifest(DashMediaSource.java:359)
      at com.google.android.exoplayer2.source.dash.DashMediaSource.processManifestAndScheduleRefresh(DashMediaSource.java:341)
      at com.google.android.exoplayer2.source.dash.DashMediaSource.onManifestLoadCompleted(DashMediaSource.java:251)
      at com.google.android.exoplayer2.source.dash.DashMediaSource$ManifestCallback.onLoadCompleted(DashMediaSource.java:589)
      at com.google.android.exoplayer2.source.dash.DashMediaSource$ManifestCallback.onLoadCompleted(DashMediaSource.java:583)
@ojw28 ojw28 added the bug label Sep 27, 2016
@luckcoolla
Copy link

luckcoolla commented Oct 13, 2016

+1 for the issue fix. I've faced it using exo player 2.0.1, but I saw it previously on 1.x too.

manifest:

<?xml version="1.0"?>
<MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:mpeg:dash:schema:mpd:2011" xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-DASH_schema_files/DASH-MPD.xsd" profiles="urn:mpeg:dash:profile:isoff-live:2011,urn:com:dashif:dash264" minBufferTime="PT10S" type="dynamic" minimumUpdatePeriod="PT2S" availabilityStartTime="2015-01-01T00:00:00Z" publishTime="2016-10-12T12:47:43Z" timeShiftBufferDepth="PT10800S">
 <Period id="0" start="PT0S">
  <AdaptationSet group="0" segmentAlignment="true" mimeType="video/mp4" minBandwidth="200000" maxBandwidth="5000000" startWithSAP="1" minWidth="480" maxWidth="1280" minHeight="270" maxHeight="720">
   <SegmentTemplate timescale="90000" initialization="$RepresentationID$-init" media="$RepresentationID$-$Time$">
    <SegmentTimeline/>
   </SegmentTemplate>
   <Representation id="710848012" bandwidth="200000" codecs="avc3.42E015" width="480" height="270"/>
   <Representation id="168120601" bandwidth="600000" codecs="avc3.42E01E" width="640" height="360"/>
   <Representation id="1124323237" bandwidth="1500000" codecs="avc3.4D401F" width="960" height="540"/>
   <Representation id="1516321653" bandwidth="3000000" codecs="avc3.64001F" width="1280" height="720"/>
   <Representation id="1709241829" bandwidth="5000000" codecs="avc3.640020" width="1280" height="720"/>
  </AdaptationSet>
  <AdaptationSet group="1" segmentAlignment="true" mimeType="audio/mp4" minBandwidth="128000" maxBandwidth="128000" startWithSAP="1" lang="nor">
   <SegmentTemplate timescale="90000" initialization="$RepresentationID$-init" media="$RepresentationID$-$Time$">
    <SegmentTimeline/>
   </SegmentTemplate>
   <Representation id="909201945" bandwidth="128000" codecs="mp4a.40.2" audioSamplingRate="48000"/>
  </AdaptationSet>
 </Period>
</MPD>

logs from the test device:

10-12 15:47:02.839 14091-14091/com.example.devnew D/VideoPlayerManagerImpl: preparePlayer() called, uri: http://nonvalid.mpd?abs_begin=2016-10-12T124900Z
10-12 15:47:02.839 14091-14091/com.example.devnew I/ExoPlayerImpl: Init 2.0.1
10-12 15:47:02.844 14091-14091/com.example.devnew D/PlayerErrorListener: start [0]
10-12 15:47:02.844 14091-14091/com.example.devnew D/VideoPlayerManagerImpl: #preparePlayer()#player.setSurface(..)
10-12 15:47:02.969 14091-14091/com.example.devnew D/EventLogger: droppedFrames [230.15, 2]
10-12 15:47:02.969 14091-14091/com.example.devnew D/EventLogger: videoDisabled [230.15]
10-12 15:47:02.974 14091-14091/com.example.devnew D/EventLogger: audioDisabled [230.15]
10-12 15:47:02.974 14091-14091/com.example.devnew D/VideoPlayerManagerImpl: playWhenReady=false, playbackState=buffering
10-12 15:47:02.974 14091-14091/com.example.devnew D/EventLogger: state [0.13, false, B]
10-12 15:47:02.989 14091-14091/com.example.devnew D/com.example.devnew.player.PlayerWrap: onBufferingStatusChanged, isBuffering = true
10-12 15:47:03.169 14091-14242/com.example.devnew D/dalvikvm: GC_FOR_ALLOC freed 3091K, 13% free 65319K/74900K, paused 56ms, total 57ms
10-12 15:47:03.184 14091-14242/com.example.devnew I/dalvikvm-heap: Grow heap (frag case) to 72.709MB for 8294416-byte allocation
10-12 15:47:03.229 14091-14242/com.example.devnew D/dalvikvm: GC_FOR_ALLOC freed 24552K, 42% free 48867K/83004K, paused 45ms, total 45ms
10-12 15:47:03.419 14091-18104/com.example.devnew E/AndroidRuntime: FATAL EXCEPTION: ExoPlayerImplInternal:Handler
                                                                         Process: com.example.devnew, PID: 14091
                                                                         java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0
                                                                             at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
                                                                             at java.util.ArrayList.get(ArrayList.java:308)
                                                                             at com.google.android.exoplayer2.source.dash.manifest.SegmentBase$MultiSegmentBase.getSegmentTimeUs(SegmentBase.java:190)
                                                                             at com.google.android.exoplayer2.source.dash.manifest.Representation$MultiSegmentRepresentation.getTimeUs(Representation.java:257)
                                                                             at com.google.android.exoplayer2.source.dash.DashMediaSource$PeriodSeekInfo.createPeriodSeekInfo(DashMediaSource.java:491)
                                                                             at com.google.android.exoplayer2.source.dash.DashMediaSource.processManifest(DashMediaSource.java:357)
                                                                             at com.google.android.exoplayer2.source.dash.DashMediaSource.processManifestAndScheduleRefresh(DashMediaSource.java:339)
                                                                             at com.google.android.exoplayer2.source.dash.DashMediaSource.onManifestLoadCompleted(DashMediaSource.java:249)
                                                                             at com.google.android.exoplayer2.source.dash.DashMediaSource$ManifestCallback.onLoadCompleted(DashMediaSource.java:587)
                                                                             at com.google.android.exoplayer2.source.dash.DashMediaSource$ManifestCallback.onLoadCompleted(DashMediaSource.java:581)
                                                                             at com.google.android.exoplayer2.upstream.Loader$LoadTask.handleMessage(Loader.java:355)
                                                                             at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                             at android.os.Looper.loop(Looper.java:146)
                                                                             at android.os.HandlerThread.run(HandlerThread.java:61)
                                                                             at com.google.android.exoplayer2.util.PriorityHandlerThread.run(PriorityHandlerThread.java:40)

@PavelGP
Copy link

PavelGP commented Oct 18, 2016

+1

@luckcoolla
Copy link

I see the issue in the latest 2.0.3 version

@luckcoolla
Copy link

I'm thinking how to implement some temporary workaround.
Both MultiSegmentBase and SegmentTemplate should check index before call "segmentTimeline.get(index)", if index is wrong - to work as segmentTimeline is null.

I'll try the approach

@luckcoolla
Copy link

well, I've added simple check
xmlSegmentTimelineNodes.item(0).hasChildNodes()
waiting for your fix

@bernhardpflug
Copy link

+1

jschamburger pushed a commit to jschamburger/ExoPlayer that referenced this issue Feb 14, 2017
ojw28 added a commit that referenced this issue Feb 15, 2017
Issue: #1865

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=147613244
@ojw28
Copy link
Contributor

ojw28 commented Feb 15, 2017

I think this should be fixed in dev-v2 now, but please give it a try and verify. Thanks!

@jschamburger
Copy link

Working great for me! The player shows a black screen (state buffering) until segments are available and then it starts playing. 👍

@ojw28
Copy link
Contributor

ojw28 commented Feb 16, 2017

Great; thanks for verifying!

@google google locked and limited conversation to collaborators Jun 28, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

6 participants