Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
SDK
/
exoplayer
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
a2f10399
authored
Jul 21, 2015
by
Oliver Woodman
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Improve error propagation
parent
5df6854f
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
344 additions
and
298 deletions
extensions/opus/src/main/java/com/google/android/exoplayer/ext/opus/LibopusAudioTrackRenderer.java
extensions/vp9/src/main/java/com/google/android/exoplayer/ext/vp9/LibvpxVideoTrackRenderer.java
library/src/main/java/com/google/android/exoplayer/DummyTrackRenderer.java
library/src/main/java/com/google/android/exoplayer/ExoPlayerImplInternal.java
library/src/main/java/com/google/android/exoplayer/FrameworkSampleSource.java
library/src/main/java/com/google/android/exoplayer/MediaCodecTrackRenderer.java
library/src/main/java/com/google/android/exoplayer/SampleSource.java
library/src/main/java/com/google/android/exoplayer/TrackRenderer.java
library/src/main/java/com/google/android/exoplayer/chunk/ChunkSampleSource.java
library/src/main/java/com/google/android/exoplayer/chunk/ChunkSource.java
library/src/main/java/com/google/android/exoplayer/chunk/MultiTrackChunkSource.java
library/src/main/java/com/google/android/exoplayer/chunk/SingleSampleChunkSource.java
library/src/main/java/com/google/android/exoplayer/dash/DashChunkSource.java
library/src/main/java/com/google/android/exoplayer/extractor/ExtractorSampleSource.java
library/src/main/java/com/google/android/exoplayer/hls/HlsSampleSource.java
library/src/main/java/com/google/android/exoplayer/metadata/MetadataTrackRenderer.java
library/src/main/java/com/google/android/exoplayer/smoothstreaming/SmoothStreamingChunkSource.java
library/src/main/java/com/google/android/exoplayer/text/TextTrackRenderer.java
library/src/main/java/com/google/android/exoplayer/text/eia608/Eia608TrackRenderer.java
library/src/main/java/com/google/android/exoplayer/util/ManifestFetcher.java
extensions/opus/src/main/java/com/google/android/exoplayer/ext/opus/LibopusAudioTrackRenderer.java
View file @
a2f10399
...
...
@@ -126,24 +126,19 @@ public class LibopusAudioTrackRenderer extends TrackRenderer implements MediaClo
}
@Override
protected
int
doPrepare
(
long
positionUs
)
throws
ExoPlaybackException
{
try
{
boolean
sourcePrepared
=
source
.
prepare
(
positionUs
);
if
(!
sourcePrepared
)
{
return
TrackRenderer
.
STATE_UNPREPARED
;
}
}
catch
(
IOException
e
)
{
throw
new
ExoPlaybackException
(
e
);
protected
int
doPrepare
(
long
positionUs
)
{
boolean
sourcePrepared
=
source
.
prepare
(
positionUs
);
if
(!
sourcePrepared
)
{
return
TrackRenderer
.
STATE_UNPREPARED
;
}
for
(
int
i
=
0
;
i
<
source
.
getTrackCount
()
;
i
++)
{
int
trackCount
=
source
.
getTrackCount
();
for
(
int
i
=
0
;
i
<
trackCount
;
i
++)
{
if
(
source
.
getTrackInfo
(
i
).
mimeType
.
equalsIgnoreCase
(
MimeTypes
.
AUDIO_OPUS
)
||
source
.
getTrackInfo
(
i
).
mimeType
.
equalsIgnoreCase
(
MimeTypes
.
AUDIO_WEBM
))
{
trackIndex
=
i
;
return
TrackRenderer
.
STATE_PREPARED
;
}
}
return
TrackRenderer
.
STATE_IGNORE
;
}
...
...
@@ -152,42 +147,49 @@ public class LibopusAudioTrackRenderer extends TrackRenderer implements MediaClo
if
(
outputStreamEnded
)
{
return
;
}
try
{
sourceIsReady
=
source
.
continueBuffering
(
trackIndex
,
positionUs
);
checkForDiscontinuity
();
if
(
format
==
null
)
{
readFormat
();
}
else
{
// Create the decoder.
if
(
decoder
==
null
)
{
// For opus, the format can contain upto 3 entries in initializationData in the following
// exact order:
// 1) Opus Header Information (required)
// 2) Codec Delay in nanoseconds (required if Seek Preroll is present)
// 3) Seek Preroll in nanoseconds (required if Codec Delay is present)
List
<
byte
[]>
initializationData
=
format
.
initializationData
;
if
(
initializationData
.
size
()
<
1
)
{
throw
new
ExoPlaybackException
(
"Missing initialization data"
);
}
long
codecDelayNs
=
-
1
;
long
seekPreRollNs
=
-
1
;
if
(
initializationData
.
size
()
==
3
)
{
if
(
initializationData
.
get
(
1
).
length
!=
Long
.
SIZE
||
initializationData
.
get
(
2
).
length
!=
Long
.
SIZE
)
{
throw
new
ExoPlaybackException
(
"Invalid Codec Delay or Seek Preroll"
);
}
codecDelayNs
=
ByteBuffer
.
wrap
(
initializationData
.
get
(
1
)).
getLong
();
seekPreRollNs
=
ByteBuffer
.
wrap
(
initializationData
.
get
(
2
)).
getLong
();
}
decoder
=
new
OpusDecoderWrapper
(
initializationData
.
get
(
0
),
codecDelayNs
,
seekPreRollNs
);
decoder
.
start
();
}
renderBuffer
();
sourceIsReady
=
source
.
continueBuffering
(
trackIndex
,
positionUs
);
checkForDiscontinuity
();
// Try and read a format if we don't have one already.
if
(
format
==
null
&&
!
readFormat
(
positionUs
))
{
// We can't make progress without one.
return
;
}
// Queue input buffers.
while
(
feedInputBuffer
())
{}
// If we don't have a decoder yet, we need to instantiate one.
if
(
decoder
==
null
)
{
// For opus, the format can contain upto 3 entries in initializationData in the following
// exact order:
// 1) Opus Header Information (required)
// 2) Codec Delay in nanoseconds (required if Seek Preroll is present)
// 3) Seek Preroll in nanoseconds (required if Codec Delay is present)
List
<
byte
[]>
initializationData
=
format
.
initializationData
;
if
(
initializationData
.
size
()
<
1
)
{
throw
new
ExoPlaybackException
(
"Missing initialization data"
);
}
long
codecDelayNs
=
-
1
;
long
seekPreRollNs
=
-
1
;
if
(
initializationData
.
size
()
==
3
)
{
if
(
initializationData
.
get
(
1
).
length
!=
Long
.
SIZE
||
initializationData
.
get
(
2
).
length
!=
Long
.
SIZE
)
{
throw
new
ExoPlaybackException
(
"Invalid Codec Delay or Seek Preroll"
);
}
codecDelayNs
=
ByteBuffer
.
wrap
(
initializationData
.
get
(
1
)).
getLong
();
seekPreRollNs
=
ByteBuffer
.
wrap
(
initializationData
.
get
(
2
)).
getLong
();
}
try
{
decoder
=
new
OpusDecoderWrapper
(
initializationData
.
get
(
0
),
codecDelayNs
,
seekPreRollNs
);
}
catch
(
OpusDecoderException
e
)
{
notifyDecoderError
(
e
);
throw
new
ExoPlaybackException
(
e
);
}
decoder
.
start
();
}
// Rendering loop.
try
{
renderBuffer
();
while
(
feedInputBuffer
())
{}
}
catch
(
AudioTrack
.
InitializationException
e
)
{
notifyAudioTrackInitializationError
(
e
);
throw
new
ExoPlaybackException
(
e
);
...
...
@@ -197,8 +199,6 @@ public class LibopusAudioTrackRenderer extends TrackRenderer implements MediaClo
}
catch
(
OpusDecoderException
e
)
{
notifyDecoderError
(
e
);
throw
new
ExoPlaybackException
(
e
);
}
catch
(
IOException
e
)
{
throw
new
ExoPlaybackException
(
e
);
}
}
...
...
@@ -249,7 +249,7 @@ public class LibopusAudioTrackRenderer extends TrackRenderer implements MediaClo
}
}
private
boolean
feedInputBuffer
()
throws
IOException
,
OpusDecoderException
{
private
boolean
feedInputBuffer
()
throws
OpusDecoderException
{
if
(
inputStreamEnded
)
{
return
false
;
}
...
...
@@ -291,7 +291,7 @@ public class LibopusAudioTrackRenderer extends TrackRenderer implements MediaClo
return
true
;
}
private
void
checkForDiscontinuity
()
throws
IOException
{
private
void
checkForDiscontinuity
()
{
if
(
decoder
==
null
)
{
return
;
}
...
...
@@ -394,12 +394,23 @@ public class LibopusAudioTrackRenderer extends TrackRenderer implements MediaClo
}
}
private
void
readFormat
()
throws
IOException
{
int
result
=
source
.
readData
(
trackIndex
,
currentPositionUs
,
formatHolder
,
null
,
false
);
@Override
protected
void
maybeThrowError
()
throws
ExoPlaybackException
{
try
{
source
.
maybeThrowError
();
}
catch
(
IOException
e
)
{
throw
new
ExoPlaybackException
(
e
);
}
}
private
boolean
readFormat
(
long
positionUs
)
{
int
result
=
source
.
readData
(
trackIndex
,
positionUs
,
formatHolder
,
null
,
false
);
if
(
result
==
SampleSource
.
FORMAT_READ
)
{
format
=
formatHolder
.
format
;
audioTrack
.
reconfigure
(
format
.
getFrameworkMediaFormatV16
());
return
true
;
}
return
false
;
}
@Override
...
...
extensions/vp9/src/main/java/com/google/android/exoplayer/ext/vp9/LibvpxVideoTrackRenderer.java
View file @
a2f10399
...
...
@@ -153,23 +153,18 @@ public class LibvpxVideoTrackRenderer extends TrackRenderer {
@Override
protected
int
doPrepare
(
long
positionUs
)
throws
ExoPlaybackException
{
try
{
boolean
sourcePrepared
=
source
.
prepare
(
positionUs
);
if
(!
sourcePrepared
)
{
return
TrackRenderer
.
STATE_UNPREPARED
;
}
}
catch
(
IOException
e
)
{
throw
new
ExoPlaybackException
(
e
);
boolean
sourcePrepared
=
source
.
prepare
(
positionUs
);
if
(!
sourcePrepared
)
{
return
TrackRenderer
.
STATE_UNPREPARED
;
}
for
(
int
i
=
0
;
i
<
source
.
getTrackCount
()
;
i
++)
{
int
trackCount
=
source
.
getTrackCount
();
for
(
int
i
=
0
;
i
<
trackCount
;
i
++)
{
if
(
source
.
getTrackInfo
(
i
).
mimeType
.
equalsIgnoreCase
(
MimeTypes
.
VIDEO_VP9
)
||
source
.
getTrackInfo
(
i
).
mimeType
.
equalsIgnoreCase
(
MimeTypes
.
VIDEO_WEBM
))
{
trackIndex
=
i
;
return
TrackRenderer
.
STATE_PREPARED
;
}
}
return
TrackRenderer
.
STATE_IGNORE
;
}
...
...
@@ -178,28 +173,29 @@ public class LibvpxVideoTrackRenderer extends TrackRenderer {
if
(
outputStreamEnded
)
{
return
;
}
try
{
sourceIsReady
=
source
.
continueBuffering
(
trackIndex
,
positionUs
);
checkForDiscontinuity
(
positionUs
);
if
(
format
==
null
)
{
readFormat
(
positionUs
);
}
else
{
// TODO: Add support for dynamic switching between one type of surface to another.
// Create the decoder.
if
(
decoder
==
null
)
{
decoder
=
new
VpxDecoderWrapper
(
outputRgb
);
decoder
.
start
();
}
processOutputBuffer
(
positionUs
,
elapsedRealtimeUs
);
sourceIsReady
=
source
.
continueBuffering
(
trackIndex
,
positionUs
);
checkForDiscontinuity
(
positionUs
);
// Queue input buffers.
while
(
feedInputBuffer
(
positionUs
))
{}
}
// Try and read a format if we don't have one already.
if
(
format
==
null
&&
!
readFormat
(
positionUs
))
{
// We can't make progress without one.
return
;
}
// If we don't have a decoder yet, we need to instantiate one.
// TODO: Add support for dynamic switching between one type of surface to another.
if
(
decoder
==
null
)
{
decoder
=
new
VpxDecoderWrapper
(
outputRgb
);
decoder
.
start
();
}
// Rendering loop.
try
{
processOutputBuffer
(
positionUs
,
elapsedRealtimeUs
);
while
(
feedInputBuffer
(
positionUs
))
{}
}
catch
(
VpxDecoderException
e
)
{
notifyDecoderError
(
e
);
throw
new
ExoPlaybackException
(
e
);
}
catch
(
IOException
e
)
{
throw
new
ExoPlaybackException
(
e
);
}
}
...
...
@@ -294,7 +290,7 @@ public class LibvpxVideoTrackRenderer extends TrackRenderer {
surface
.
unlockCanvasAndPost
(
canvas
);
}
private
boolean
feedInputBuffer
(
long
positionUs
)
throws
IOException
,
VpxDecoderException
{
private
boolean
feedInputBuffer
(
long
positionUs
)
throws
VpxDecoderException
{
if
(
inputStreamEnded
)
{
return
false
;
}
...
...
@@ -334,7 +330,7 @@ public class LibvpxVideoTrackRenderer extends TrackRenderer {
return
true
;
}
private
void
checkForDiscontinuity
(
long
positionUs
)
throws
IOException
{
private
void
checkForDiscontinuity
(
long
positionUs
)
{
if
(
decoder
==
null
)
{
return
;
}
...
...
@@ -417,11 +413,22 @@ public class LibvpxVideoTrackRenderer extends TrackRenderer {
source
.
disable
(
trackIndex
);
}
private
void
readFormat
(
long
positionUs
)
throws
IOException
{
@Override
protected
void
maybeThrowError
()
throws
ExoPlaybackException
{
try
{
source
.
maybeThrowError
();
}
catch
(
IOException
e
)
{
throw
new
ExoPlaybackException
(
e
);
}
}
private
boolean
readFormat
(
long
positionUs
)
{
int
result
=
source
.
readData
(
trackIndex
,
positionUs
,
formatHolder
,
null
,
false
);
if
(
result
==
SampleSource
.
FORMAT_READ
)
{
format
=
formatHolder
.
format
;
return
true
;
}
return
false
;
}
@Override
...
...
library/src/main/java/com/google/android/exoplayer/DummyTrackRenderer.java
View file @
a2f10399
...
...
@@ -25,7 +25,7 @@ package com.google.android.exoplayer;
public
class
DummyTrackRenderer
extends
TrackRenderer
{
@Override
protected
int
doPrepare
(
long
positionUs
)
throws
ExoPlaybackException
{
protected
int
doPrepare
(
long
positionUs
)
{
return
STATE_IGNORE
;
}
...
...
@@ -50,6 +50,11 @@ public class DummyTrackRenderer extends TrackRenderer {
}
@Override
protected
void
maybeThrowError
()
{
throw
new
IllegalStateException
();
}
@Override
protected
long
getDurationUs
()
{
throw
new
IllegalStateException
();
}
...
...
library/src/main/java/com/google/android/exoplayer/ExoPlayerImplInternal.java
View file @
a2f10399
...
...
@@ -266,10 +266,12 @@ import java.util.List;
private
void
incrementalPrepareInternal
()
throws
ExoPlaybackException
{
long
operationStartTimeMs
=
SystemClock
.
elapsedRealtime
();
boolean
prepared
=
true
;
for
(
int
i
=
0
;
i
<
renderers
.
length
;
i
++)
{
if
(
renderers
[
i
].
getState
()
==
TrackRenderer
.
STATE_UNPREPARED
)
{
int
state
=
renderers
[
i
].
prepare
(
positionUs
);
for
(
int
rendererIndex
=
0
;
rendererIndex
<
renderers
.
length
;
rendererIndex
++)
{
TrackRenderer
renderer
=
renderers
[
rendererIndex
];
if
(
renderer
.
getState
()
==
TrackRenderer
.
STATE_UNPREPARED
)
{
int
state
=
renderer
.
prepare
(
positionUs
);
if
(
state
==
TrackRenderer
.
STATE_UNPREPARED
)
{
renderer
.
maybeThrowError
();
prepared
=
false
;
}
}
...
...
@@ -414,7 +416,14 @@ import java.util.List;
// invocation of this method.
renderer
.
doSomeWork
(
positionUs
,
elapsedRealtimeUs
);
allRenderersEnded
=
allRenderersEnded
&&
renderer
.
isEnded
();
allRenderersReadyOrEnded
=
allRenderersReadyOrEnded
&&
rendererReadyOrEnded
(
renderer
);
// Determine whether the renderer is ready (or ended). If it's not, throw an error that's
// preventing the renderer from making progress, if such an error exists.
boolean
rendererReadyOrEnded
=
rendererReadyOrEnded
(
renderer
);
if
(!
rendererReadyOrEnded
)
{
renderer
.
maybeThrowError
();
}
allRenderersReadyOrEnded
=
allRenderersReadyOrEnded
&&
rendererReadyOrEnded
;
if
(
bufferedPositionUs
==
TrackRenderer
.
UNKNOWN_TIME_US
)
{
// We've already encountered a track for which the buffered position is unknown. Hence the
...
...
library/src/main/java/com/google/android/exoplayer/FrameworkSampleSource.java
View file @
a2f10399
...
...
@@ -76,6 +76,7 @@ public final class FrameworkSampleSource implements SampleSource, SampleSourceRe
private
final
long
fileDescriptorOffset
;
private
final
long
fileDescriptorLength
;
private
IOException
preparationError
;
private
MediaExtractor
extractor
;
private
TrackInfo
[]
trackInfos
;
private
boolean
prepared
;
...
...
@@ -128,13 +129,22 @@ public final class FrameworkSampleSource implements SampleSource, SampleSourceRe
}
@Override
public
boolean
prepare
(
long
positionUs
)
throws
IOException
{
public
boolean
prepare
(
long
positionUs
)
{
if
(!
prepared
)
{
if
(
preparationError
!=
null
)
{
return
false
;
}
extractor
=
new
MediaExtractor
();
if
(
context
!=
null
)
{
extractor
.
setDataSource
(
context
,
uri
,
headers
);
}
else
{
extractor
.
setDataSource
(
fileDescriptor
,
fileDescriptorOffset
,
fileDescriptorLength
);
try
{
if
(
context
!=
null
)
{
extractor
.
setDataSource
(
context
,
uri
,
headers
);
}
else
{
extractor
.
setDataSource
(
fileDescriptor
,
fileDescriptorOffset
,
fileDescriptorLength
);
}
}
catch
(
IOException
e
)
{
preparationError
=
e
;
return
false
;
}
trackStates
=
new
int
[
extractor
.
getTrackCount
()];
...
...
@@ -233,6 +243,13 @@ public final class FrameworkSampleSource implements SampleSource, SampleSourceRe
}
@Override
public
void
maybeThrowError
()
throws
IOException
{
if
(
preparationError
!=
null
)
{
throw
preparationError
;
}
}
@Override
public
void
seekToUs
(
long
positionUs
)
{
Assertions
.
checkState
(
prepared
);
seekToUsInternal
(
positionUs
,
false
);
...
...
library/src/main/java/com/google/android/exoplayer/MediaCodecTrackRenderer.java
View file @
a2f10399
...
...
@@ -245,17 +245,13 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
}
@Override
protected
int
doPrepare
(
long
positionUs
)
throws
ExoPlaybackException
{
try
{
boolean
sourcePrepared
=
source
.
prepare
(
positionUs
);
if
(!
sourcePrepared
)
{
return
TrackRenderer
.
STATE_UNPREPARED
;
}
}
catch
(
IOException
e
)
{
throw
new
ExoPlaybackException
(
e
);
protected
int
doPrepare
(
long
positionUs
)
{
boolean
sourcePrepared
=
source
.
prepare
(
positionUs
);
if
(!
sourcePrepared
)
{
return
TrackRenderer
.
STATE_UNPREPARED
;
}
for
(
int
i
=
0
;
i
<
source
.
getTrackCount
()
;
i
++)
{
int
trackCount
=
source
.
getTrackCount
();
for
(
int
i
=
0
;
i
<
trackCount
;
i
++)
{
// TODO: Right now this is getting the mime types of the container format
// (e.g. audio/mp4 and video/mp4 for fragmented mp4). It needs to be getting the mime types
// of the actual samples (e.g. audio/mp4a-latm and video/avc).
...
...
@@ -264,7 +260,6 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
return
TrackRenderer
.
STATE_PREPARED
;
}
}
return
TrackRenderer
.
STATE_IGNORE
;
}
...
...
@@ -489,39 +484,35 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
@Override
protected
void
doSomeWork
(
long
positionUs
,
long
elapsedRealtimeUs
)
throws
ExoPlaybackException
{
try
{
sourceState
=
source
.
continueBuffering
(
trackIndex
,
positionUs
)
?
(
sourceState
==
SOURCE_STATE_NOT_READY
?
SOURCE_STATE_READY
:
sourceState
)
:
SOURCE_STATE_NOT_READY
;
checkForDiscontinuity
(
positionUs
);
if
(
format
==
null
)
{
readFormat
(
positionUs
);
}
if
(
codec
==
null
&&
shouldInitCodec
())
{
maybeInitCodec
();
}
if
(
codec
!=
null
)
{
TraceUtil
.
beginSection
(
"drainAndFeed"
);
while
(
drainOutputBuffer
(
positionUs
,
elapsedRealtimeUs
))
{}
if
(
feedInputBuffer
(
positionUs
,
true
))
{
while
(
feedInputBuffer
(
positionUs
,
false
))
{}
}
TraceUtil
.
endSection
();
sourceState
=
source
.
continueBuffering
(
trackIndex
,
positionUs
)
?
(
sourceState
==
SOURCE_STATE_NOT_READY
?
SOURCE_STATE_READY
:
sourceState
)
:
SOURCE_STATE_NOT_READY
;
checkForDiscontinuity
(
positionUs
);
if
(
format
==
null
)
{
readFormat
(
positionUs
);
}
if
(
codec
==
null
&&
shouldInitCodec
())
{
maybeInitCodec
();
}
if
(
codec
!=
null
)
{
TraceUtil
.
beginSection
(
"drainAndFeed"
);
while
(
drainOutputBuffer
(
positionUs
,
elapsedRealtimeUs
))
{}
if
(
feedInputBuffer
(
positionUs
,
true
))
{
while
(
feedInputBuffer
(
positionUs
,
false
))
{}
}
codecCounters
.
ensureUpdated
();
}
catch
(
IOException
e
)
{
throw
new
ExoPlaybackException
(
e
);
TraceUtil
.
endSection
();
}
codecCounters
.
ensureUpdated
();
}
private
void
readFormat
(
long
positionUs
)
throws
IOException
,
ExoPlaybackException
{
private
void
readFormat
(
long
positionUs
)
throws
ExoPlaybackException
{
int
result
=
source
.
readData
(
trackIndex
,
positionUs
,
formatHolder
,
sampleHolder
,
false
);
if
(
result
==
SampleSource
.
FORMAT_READ
)
{
onInputFormatChanged
(
formatHolder
);
}
}
private
void
checkForDiscontinuity
(
long
positionUs
)
throws
IOException
,
ExoPlaybackException
{
private
void
checkForDiscontinuity
(
long
positionUs
)
throws
ExoPlaybackException
{
if
(
codec
==
null
)
{
return
;
}
...
...
@@ -560,11 +551,9 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
* @param firstFeed True if this is the first call to this method from the current invocation of
* {@link #doSomeWork(long, long)}. False otherwise.
* @return True if it may be possible to feed more input data. False otherwise.
* @throws IOException If an error occurs reading data from the upstream source.
* @throws ExoPlaybackException If an error occurs feeding the input buffer.
*/
private
boolean
feedInputBuffer
(
long
positionUs
,
boolean
firstFeed
)
throws
IOException
,
ExoPlaybackException
{
private
boolean
feedInputBuffer
(
long
positionUs
,
boolean
firstFeed
)
throws
ExoPlaybackException
{
if
(
inputStreamEnded
||
codecReinitializationState
==
REINITIALIZATION_STATE_WAIT_END_OF_STREAM
)
{
// The input stream has ended, or we need to re-initialize the codec but are still waiting
...
...
@@ -786,6 +775,15 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
}
@Override
protected
void
maybeThrowError
()
throws
ExoPlaybackException
{
try
{
source
.
maybeThrowError
();
}
catch
(
IOException
e
)
{
throw
new
ExoPlaybackException
(
e
);
}
}
@Override
protected
boolean
isEnded
()
{
return
outputStreamEnded
;
}
...
...
library/src/main/java/com/google/android/exoplayer/SampleSource.java
View file @
a2f10399
...
...
@@ -76,9 +76,8 @@ public interface SampleSource {
*
* @param positionUs The player's current playback position.
* @return True if the source was prepared successfully, false otherwise.
* @throws IOException If an error occurred preparing the source.
*/
public
boolean
prepare
(
long
positionUs
)
throws
IOException
;
public
boolean
prepare
(
long
positionUs
);
/**
* Returns the number of tracks exposed by the source.
...
...
@@ -117,15 +116,22 @@ public interface SampleSource {
public
void
disable
(
int
track
);
/**
* If the source is currently having difficulty preparing or loading samples, then this method
* throws the underlying error. Otherwise does nothing.
*
* @throws IOException The underlying error.
*/
public
void
maybeThrowError
()
throws
IOException
;
/**
* Indicates to the source that it should still be buffering data for the specified track.
*
* @param track The track to continue buffering.
* @param positionUs The current playback position.
* @return True if the track has available samples, or if the end of the stream has been
* reached. False if more data needs to be buffered for samples to become available.
* @throws IOException If an error occurred reading from the source.
*/
public
boolean
continueBuffering
(
int
track
,
long
positionUs
)
throws
IOException
;
public
boolean
continueBuffering
(
int
track
,
long
positionUs
);
/**
* Attempts to read either a sample, a new format or or a discontinuity from the source.
...
...
@@ -147,10 +153,9 @@ public interface SampleSource {
* {@link #DISCONTINUITY_READ} or {@link #NOTHING_READ} can be returned.
* @return The result, which can be {@link #SAMPLE_READ}, {@link #FORMAT_READ},
* {@link #DISCONTINUITY_READ}, {@link #NOTHING_READ} or {@link #END_OF_STREAM}.
* @throws IOException If an error occurred reading from the source.
*/
public
int
readData
(
int
track
,
long
positionUs
,
MediaFormatHolder
formatHolder
,
SampleHolder
sampleHolder
,
boolean
onlyReadDiscontinuity
)
throws
IOException
;
SampleHolder
sampleHolder
,
boolean
onlyReadDiscontinuity
);
/**
* Seeks to the specified time in microseconds.
...
...
library/src/main/java/com/google/android/exoplayer/TrackRenderer.java
View file @
a2f10399
...
...
@@ -107,6 +107,7 @@ public abstract class TrackRenderer implements ExoPlayerComponent {
*
* @param positionUs The player's current playback position.
* @return The current state (one of the STATE_* constants), for convenience.
* @throws ExoPlaybackException If an error occurs.
*/
/* package */
final
int
prepare
(
long
positionUs
)
throws
ExoPlaybackException
{
Assertions
.
checkState
(
state
==
TrackRenderer
.
STATE_UNPREPARED
);
...
...
@@ -139,6 +140,7 @@ public abstract class TrackRenderer implements ExoPlayerComponent {
* @param joining Whether this renderer is being enabled to join an ongoing playback. If true
* then {@link #start} must be called immediately after this method returns (unless a
* {@link ExoPlaybackException} is thrown).
* @throws ExoPlaybackException If an error occurs.
*/
/* package */
final
void
enable
(
long
positionUs
,
boolean
joining
)
throws
ExoPlaybackException
{
Assertions
.
checkState
(
state
==
TrackRenderer
.
STATE_PREPARED
);
...
...
@@ -164,6 +166,8 @@ public abstract class TrackRenderer implements ExoPlayerComponent {
/**
* Starts the renderer, meaning that calls to {@link #doSomeWork(long, long)} will cause the
* track to be rendered.
*
* @throws ExoPlaybackException If an error occurs.
*/
/* package */
final
void
start
()
throws
ExoPlaybackException
{
Assertions
.
checkState
(
state
==
TrackRenderer
.
STATE_ENABLED
);
...
...
@@ -184,6 +188,8 @@ public abstract class TrackRenderer implements ExoPlayerComponent {
/**
* Stops the renderer.
*
* @throws ExoPlaybackException If an error occurs.
*/
/* package */
final
void
stop
()
throws
ExoPlaybackException
{
Assertions
.
checkState
(
state
==
TrackRenderer
.
STATE_STARTED
);
...
...
@@ -204,6 +210,8 @@ public abstract class TrackRenderer implements ExoPlayerComponent {
/**
* Disable the renderer.
*
* @throws ExoPlaybackException If an error occurs.
*/
/* package */
final
void
disable
()
throws
ExoPlaybackException
{
Assertions
.
checkState
(
state
==
TrackRenderer
.
STATE_ENABLED
);
...
...
@@ -224,6 +232,8 @@ public abstract class TrackRenderer implements ExoPlayerComponent {
/**
* Releases the renderer.
*
* @throws ExoPlaybackException If an error occurs.
*/
/* package */
final
void
release
()
throws
ExoPlaybackException
{
Assertions
.
checkState
(
state
!=
TrackRenderer
.
STATE_ENABLED
...
...
@@ -298,6 +308,15 @@ public abstract class TrackRenderer implements ExoPlayerComponent {
throws
ExoPlaybackException
;
/**
* Throws an error that's preventing the renderer from making progress or buffering more data at
* this point in time.
*
* @throws ExoPlaybackException An error that's preventing the renderer from making progress or
* buffering more data.
*/
protected
abstract
void
maybeThrowError
()
throws
ExoPlaybackException
;
/**
* Returns the duration of the media being rendered.
* <p>
* This method may be called when the renderer is in the following states:
...
...
library/src/main/java/com/google/android/exoplayer/chunk/ChunkSampleSource.java
View file @
a2f10399
...
...
@@ -188,23 +188,18 @@ public class ChunkSampleSource implements SampleSource, SampleSourceReader, Load
}
@Override
public
boolean
continueBuffering
(
int
track
,
long
positionUs
)
throws
IOException
{
public
boolean
continueBuffering
(
int
track
,
long
positionUs
)
{
Assertions
.
checkState
(
state
==
STATE_ENABLED
);
Assertions
.
checkState
(
track
==
0
);
downstreamPositionUs
=
positionUs
;
chunkSource
.
continueBuffering
(
positionUs
);
updateLoadControl
();
boolean
haveSamples
=
!
sampleQueue
.
isEmpty
();
if
(!
haveSamples
)
{
maybeThrowLoadableException
();
}
return
loadingFinished
||
haveSamples
;
return
loadingFinished
||
!
sampleQueue
.
isEmpty
();
}
@Override
public
int
readData
(
int
track
,
long
positionUs
,
MediaFormatHolder
formatHolder
,
SampleHolder
sampleHolder
,
boolean
onlyReadDiscontinuity
)
throws
IOException
{
SampleHolder
sampleHolder
,
boolean
onlyReadDiscontinuity
)
{
Assertions
.
checkState
(
state
==
STATE_ENABLED
);
Assertions
.
checkState
(
track
==
0
);
downstreamPositionUs
=
positionUs
;
...
...
@@ -219,7 +214,6 @@ public class ChunkSampleSource implements SampleSource, SampleSourceReader, Load
}
if
(
isPendingReset
())
{
maybeThrowLoadableException
();
return
NOTHING_READ
;
}
...
...
@@ -252,7 +246,6 @@ public class ChunkSampleSource implements SampleSource, SampleSourceReader, Load
if
(
loadingFinished
)
{
return
END_OF_STREAM
;
}
maybeThrowLoadableException
();
return
NOTHING_READ
;
}
...
...
@@ -263,7 +256,6 @@ public class ChunkSampleSource implements SampleSource, SampleSourceReader, Load
return
SAMPLE_READ
;
}
maybeThrowLoadableException
();
return
NOTHING_READ
;
}
...
...
@@ -295,15 +287,12 @@ public class ChunkSampleSource implements SampleSource, SampleSourceReader, Load
pendingDiscontinuity
=
true
;
}
private
void
maybeThrowLoadableException
()
throws
IOException
{
@Override
public
void
maybeThrowError
()
throws
IOException
{
if
(
currentLoadableException
!=
null
&&
currentLoadableExceptionCount
>
minLoadableRetryCount
)
{
throw
currentLoadableException
;
}
if
(
sampleQueue
.
isEmpty
()
&&
currentLoadableHolder
.
chunk
==
null
)
{
IOException
chunkSourceException
=
chunkSource
.
getError
();
if
(
chunkSourceException
!=
null
)
{
throw
chunkSourceException
;
}
}
else
if
(
currentLoadableHolder
.
chunk
==
null
)
{
chunkSource
.
maybeThrowError
();
}
}
...
...
library/src/main/java/com/google/android/exoplayer/chunk/ChunkSource.java
View file @
a2f10399
...
...
@@ -94,13 +94,12 @@ public interface ChunkSource {
long
playbackPositionUs
,
ChunkOperationHolder
out
);
/**
* If the {@link ChunkSource} is currently unable to provide chunks through
* {@link ChunkSource#getChunkOperation}, then this method returns the underlying cause. Returns
* null otherwise.
* If the source is currently having difficulty providing chunks, then this method throws the
* underlying error. Otherwise does nothing.
*
* @
return An {@link IOException}, or null
.
* @
throws IOException The underlying error
.
*/
IOException
getError
()
;
void
maybeThrowError
()
throws
IOException
;
/**
* Invoked when the {@link ChunkSampleSource} has finished loading a chunk obtained from this
...
...
library/src/main/java/com/google/android/exoplayer/chunk/MultiTrackChunkSource.java
View file @
a2f10399
...
...
@@ -89,8 +89,8 @@ public class MultiTrackChunkSource implements ChunkSource, ExoPlayerComponent {
}
@Override
public
IOException
getError
()
{
return
null
;
public
void
maybeThrowError
()
throws
IOException
{
selectedSource
.
maybeThrowError
()
;
}
@Override
...
...
library/src/main/java/com/google/android/exoplayer/chunk/SingleSampleChunkSource.java
View file @
a2f10399
...
...
@@ -21,7 +21,6 @@ import com.google.android.exoplayer.TrackInfo;
import
com.google.android.exoplayer.upstream.DataSource
;
import
com.google.android.exoplayer.upstream.DataSpec
;
import
java.io.IOException
;
import
java.util.List
;
/**
...
...
@@ -94,8 +93,8 @@ public class SingleSampleChunkSource implements ChunkSource {
}
@Override
public
IOException
get
Error
()
{
return
null
;
public
void
maybeThrow
Error
()
{
// Do nothing.
}
@Override
...
...
library/src/main/java/com/google/android/exoplayer/dash/DashChunkSource.java
View file @
a2f10399
...
...
@@ -514,9 +514,12 @@ public class DashChunkSource implements ChunkSource {
}
@Override
public
IOException
getError
()
{
return
fatalError
!=
null
?
fatalError
:
(
manifestFetcher
!=
null
?
manifestFetcher
.
getError
()
:
null
);
public
void
maybeThrowError
()
throws
IOException
{
if
(
fatalError
!=
null
)
{
throw
fatalError
;
}
else
if
(
manifestFetcher
!=
null
)
{
manifestFetcher
.
maybeThrowError
();
}
}
@Override
...
...
library/src/main/java/com/google/android/exoplayer/extractor/ExtractorSampleSource.java
View file @
a2f10399
...
...
@@ -172,7 +172,7 @@ public class ExtractorSampleSource implements SampleSource, SampleSourceReader,
}
@Override
public
boolean
prepare
(
long
positionUs
)
throws
IOException
{
public
boolean
prepare
(
long
positionUs
)
{
if
(
prepared
)
{
return
true
;
}
...
...
@@ -198,10 +198,9 @@ public class ExtractorSampleSource implements SampleSource, SampleSourceReader,
}
prepared
=
true
;
return
true
;
}
else
{
maybeThrowLoadableException
();
return
false
;
}
return
false
;
}
@Override
...
...
@@ -246,7 +245,7 @@ public class ExtractorSampleSource implements SampleSource, SampleSourceReader,
}
@Override
public
boolean
continueBuffering
(
int
track
,
long
playbackPositionUs
)
throws
IOException
{
public
boolean
continueBuffering
(
int
track
,
long
playbackPositionUs
)
{
Assertions
.
checkState
(
prepared
);
Assertions
.
checkState
(
trackEnabledStates
[
track
]);
downstreamPositionUs
=
playbackPositionUs
;
...
...
@@ -258,16 +257,12 @@ public class ExtractorSampleSource implements SampleSource, SampleSourceReader,
if
(
isPendingReset
())
{
return
false
;
}
if
(
sampleQueues
.
valueAt
(
track
).
isEmpty
())
{
maybeThrowLoadableException
();
return
false
;
}
return
true
;
return
!
sampleQueues
.
valueAt
(
track
).
isEmpty
();
}
@Override
public
int
readData
(
int
track
,
long
playbackPositionUs
,
MediaFormatHolder
formatHolder
,
SampleHolder
sampleHolder
,
boolean
onlyReadDiscontinuity
)
throws
IOException
{
SampleHolder
sampleHolder
,
boolean
onlyReadDiscontinuity
)
{
downstreamPositionUs
=
playbackPositionUs
;
if
(
pendingDiscontinuities
[
track
])
{
...
...
@@ -276,7 +271,6 @@ public class ExtractorSampleSource implements SampleSource, SampleSourceReader,
}
if
(
onlyReadDiscontinuity
||
isPendingReset
())
{
maybeThrowLoadableException
();
return
NOTHING_READ
;
}
...
...
@@ -304,11 +298,28 @@ public class ExtractorSampleSource implements SampleSource, SampleSourceReader,
return
END_OF_STREAM
;
}
maybeThrowLoadableException
();
return
NOTHING_READ
;
}
@Override
public
void
maybeThrowError
()
throws
IOException
{
if
(
currentLoadableException
==
null
)
{
return
;
}
int
minLoadableRetryCountForMedia
;
if
(
minLoadableRetryCount
!=
MIN_RETRY_COUNT_DEFAULT_FOR_MEDIA
)
{
minLoadableRetryCountForMedia
=
minLoadableRetryCount
;
}
else
{
minLoadableRetryCountForMedia
=
seekMap
!=
null
&&
!
seekMap
.
isSeekable
()
?
DEFAULT_MIN_LOADABLE_RETRY_COUNT_LIVE
:
DEFAULT_MIN_LOADABLE_RETRY_COUNT_ON_DEMAND
;
}
if
(
currentLoadableExceptionCount
>
minLoadableRetryCountForMedia
)
{
throw
currentLoadableException
;
}
}
@Override
public
void
seekToUs
(
long
positionUs
)
{
Assertions
.
checkState
(
prepared
);
Assertions
.
checkState
(
enabledTrackCount
>
0
);
...
...
@@ -496,23 +507,6 @@ public class ExtractorSampleSource implements SampleSource, SampleSourceReader,
loader
.
startLoading
(
loadable
,
this
);
}
private
void
maybeThrowLoadableException
()
throws
IOException
{
if
(
currentLoadableException
==
null
)
{
return
;
}
int
minLoadableRetryCountForMedia
;
if
(
minLoadableRetryCount
!=
MIN_RETRY_COUNT_DEFAULT_FOR_MEDIA
)
{
minLoadableRetryCountForMedia
=
minLoadableRetryCount
;
}
else
{
minLoadableRetryCountForMedia
=
seekMap
!=
null
&&
!
seekMap
.
isSeekable
()
?
DEFAULT_MIN_LOADABLE_RETRY_COUNT_LIVE
:
DEFAULT_MIN_LOADABLE_RETRY_COUNT_ON_DEMAND
;
}
if
(
currentLoadableExceptionCount
>
minLoadableRetryCountForMedia
)
{
throw
currentLoadableException
;
}
}
private
ExtractingLoadable
createLoadableFromStart
()
{
return
new
ExtractingLoadable
(
uri
,
dataSource
,
extractor
,
allocator
,
requestedBufferSize
,
0
);
}
...
...
library/src/main/java/com/google/android/exoplayer/hls/HlsSampleSource.java
View file @
a2f10399
...
...
@@ -125,7 +125,7 @@ public class HlsSampleSource implements SampleSource, SampleSourceReader, Loader
}
@Override
public
boolean
prepare
(
long
positionUs
)
throws
IOException
{
public
boolean
prepare
(
long
positionUs
)
{
if
(
prepared
)
{
return
true
;
}
...
...
@@ -162,7 +162,6 @@ public class HlsSampleSource implements SampleSource, SampleSourceReader, Loader
downstreamPositionUs
=
positionUs
;
}
maybeStartLoading
();
maybeThrowLoadableException
();
return
false
;
}
...
...
@@ -218,7 +217,7 @@ public class HlsSampleSource implements SampleSource, SampleSourceReader, Loader
}
@Override
public
boolean
continueBuffering
(
int
track
,
long
playbackPositionUs
)
throws
IOException
{
public
boolean
continueBuffering
(
int
track
,
long
playbackPositionUs
)
{
Assertions
.
checkState
(
prepared
);
Assertions
.
checkState
(
trackEnabledStates
[
track
]);
downstreamPositionUs
=
playbackPositionUs
;
...
...
@@ -232,7 +231,6 @@ public class HlsSampleSource implements SampleSource, SampleSourceReader, Loader
if
(
isPendingReset
()
||
extractors
.
isEmpty
())
{
return
false
;
}
for
(
int
extractorIndex
=
0
;
extractorIndex
<
extractors
.
size
();
extractorIndex
++)
{
HlsExtractorWrapper
extractor
=
extractors
.
get
(
extractorIndex
);
if
(!
extractor
.
isPrepared
())
{
...
...
@@ -242,13 +240,12 @@ public class HlsSampleSource implements SampleSource, SampleSourceReader, Loader
return
true
;
}
}
maybeThrowLoadableException
();
return
false
;
}
@Override
public
int
readData
(
int
track
,
long
playbackPositionUs
,
MediaFormatHolder
formatHolder
,
SampleHolder
sampleHolder
,
boolean
onlyReadDiscontinuity
)
throws
IOException
{
SampleHolder
sampleHolder
,
boolean
onlyReadDiscontinuity
)
{
Assertions
.
checkState
(
prepared
);
downstreamPositionUs
=
playbackPositionUs
;
...
...
@@ -262,13 +259,11 @@ public class HlsSampleSource implements SampleSource, SampleSourceReader, Loader
}
if
(
isPendingReset
())
{
maybeThrowLoadableException
();
return
NOTHING_READ
;
}
HlsExtractorWrapper
extractor
=
getCurrentExtractor
();
if
(!
extractor
.
isPrepared
())
{
maybeThrowLoadableException
();
return
NOTHING_READ
;
}
...
...
@@ -290,7 +285,6 @@ public class HlsSampleSource implements SampleSource, SampleSourceReader, Loader
// next one for the current read.
extractor
=
extractors
.
get
(++
extractorIndex
);
if
(!
extractor
.
isPrepared
())
{
maybeThrowLoadableException
();
return
NOTHING_READ
;
}
}
...
...
@@ -313,11 +307,17 @@ public class HlsSampleSource implements SampleSource, SampleSourceReader, Loader
return
END_OF_STREAM
;
}
maybeThrowLoadableException
();
return
NOTHING_READ
;
}
@Override
public
void
maybeThrowError
()
throws
IOException
{
if
(
currentLoadableException
!=
null
&&
currentLoadableExceptionCount
>
minLoadableRetryCount
)
{
throw
currentLoadableException
;
}
}
@Override
public
void
seekToUs
(
long
positionUs
)
{
Assertions
.
checkState
(
prepared
);
Assertions
.
checkState
(
enabledTrackCount
>
0
);
...
...
@@ -361,6 +361,8 @@ public class HlsSampleSource implements SampleSource, SampleSourceReader, Loader
}
}
// Loader.Callback implementation.
@Override
public
void
onLoadCompleted
(
Loadable
loadable
)
{
Assertions
.
checkState
(
loadable
==
currentLoadable
);
...
...
@@ -412,6 +414,8 @@ public class HlsSampleSource implements SampleSource, SampleSourceReader, Loader
maybeStartLoading
();
}
// Internal stuff.
/**
* Gets the current extractor from which samples should be read.
* <p>
...
...
@@ -455,12 +459,6 @@ public class HlsSampleSource implements SampleSource, SampleSourceReader, Loader
return
false
;
}
private
void
maybeThrowLoadableException
()
throws
IOException
{
if
(
currentLoadableException
!=
null
&&
currentLoadableExceptionCount
>
minLoadableRetryCount
)
{
throw
currentLoadableException
;
}
}
private
void
restartFrom
(
long
positionUs
)
{
pendingResetPositionUs
=
positionUs
;
loadingFinished
=
false
;
...
...
library/src/main/java/com/google/android/exoplayer/metadata/MetadataTrackRenderer.java
View file @
a2f10399
...
...
@@ -90,16 +90,13 @@ public class MetadataTrackRenderer<T> extends TrackRenderer implements Callback
}
@Override
protected
int
doPrepare
(
long
positionUs
)
throws
ExoPlaybackException
{
try
{
boolean
sourcePrepared
=
source
.
prepare
(
positionUs
);
if
(!
sourcePrepared
)
{
return
TrackRenderer
.
STATE_UNPREPARED
;
}
}
catch
(
IOException
e
)
{
throw
new
ExoPlaybackException
(
e
);
protected
int
doPrepare
(
long
positionUs
)
{
boolean
sourcePrepared
=
source
.
prepare
(
positionUs
);
if
(!
sourcePrepared
)
{
return
TrackRenderer
.
STATE_UNPREPARED
;
}
for
(
int
i
=
0
;
i
<
source
.
getTrackCount
();
i
++)
{
int
trackCount
=
source
.
getTrackCount
();
for
(
int
i
=
0
;
i
<
trackCount
;
i
++)
{
if
(
metadataParser
.
canParse
(
source
.
getTrackInfo
(
i
).
mimeType
))
{
trackIndex
=
i
;
return
TrackRenderer
.
STATE_PREPARED
;
...
...
@@ -128,29 +125,21 @@ public class MetadataTrackRenderer<T> extends TrackRenderer implements Callback
@Override
protected
void
doSomeWork
(
long
positionUs
,
long
elapsedRealtimeUs
)
throws
ExoPlaybackException
{
try
{
source
.
continueBuffering
(
trackIndex
,
positionUs
);
}
catch
(
IOException
e
)
{
// TODO: This should be propagated, but in the current design propagation may occur too
// early. See [Internal b/22291244].
// throw new ExoPlaybackException(e);
}
source
.
continueBuffering
(
trackIndex
,
positionUs
);
if
(!
inputStreamEnded
&&
pendingMetadata
==
null
)
{
try
{
int
result
=
source
.
readData
(
trackIndex
,
positionUs
,
formatHolder
,
sampleHolder
,
false
);
if
(
result
==
SampleSource
.
SAMPLE_READ
)
{
pendingMetadataTimestamp
=
sampleHolder
.
timeUs
;
pendingMetadata
=
metadataParser
.
parse
(
sampleHolder
.
data
.
array
(),
sampleHolder
.
size
);
try
{
pendingMetadata
=
metadataParser
.
parse
(
sampleHolder
.
data
.
array
(),
sampleHolder
.
size
);
}
catch
(
IOException
e
)
{
throw
new
ExoPlaybackException
(
e
);
}
sampleHolder
.
data
.
clear
();
}
else
if
(
result
==
SampleSource
.
END_OF_STREAM
)
{
inputStreamEnded
=
true
;
}
}
catch
(
IOException
e
)
{
// TODO: This should be propagated, but in the current design propagation may occur too
// early. See [Internal b/22291244].
// throw new ExoPlaybackException(e);
}
}
if
(
pendingMetadata
!=
null
&&
pendingMetadataTimestamp
<=
positionUs
)
{
...
...
@@ -160,6 +149,15 @@ public class MetadataTrackRenderer<T> extends TrackRenderer implements Callback
}
@Override
protected
void
maybeThrowError
()
throws
ExoPlaybackException
{
try
{
source
.
maybeThrowError
();
}
catch
(
IOException
e
)
{
throw
new
ExoPlaybackException
(
e
);
}
}
@Override
protected
void
onDisabled
()
{
pendingMetadata
=
null
;
source
.
disable
(
trackIndex
);
...
...
library/src/main/java/com/google/android/exoplayer/smoothstreaming/SmoothStreamingChunkSource.java
View file @
a2f10399
...
...
@@ -324,9 +324,12 @@ public class SmoothStreamingChunkSource implements ChunkSource {
}
@Override
public
IOException
getError
()
{
return
fatalError
!=
null
?
fatalError
:
(
manifestFetcher
!=
null
?
manifestFetcher
.
getError
()
:
null
);
public
void
maybeThrowError
()
throws
IOException
{
if
(
fatalError
!=
null
)
{
throw
fatalError
;
}
else
{
manifestFetcher
.
maybeThrowError
();
}
}
@Override
...
...
library/src/main/java/com/google/android/exoplayer/text/TextTrackRenderer.java
View file @
a2f10399
...
...
@@ -151,17 +151,14 @@ public class TextTrackRenderer extends TrackRenderer implements Callback {
}
@Override
protected
int
doPrepare
(
long
positionUs
)
throws
ExoPlaybackException
{
try
{
boolean
sourcePrepared
=
source
.
prepare
(
positionUs
);
if
(!
sourcePrepared
)
{
return
TrackRenderer
.
STATE_UNPREPARED
;
}
}
catch
(
IOException
e
)
{
throw
new
ExoPlaybackException
(
e
);
protected
int
doPrepare
(
long
positionUs
)
{
boolean
sourcePrepared
=
source
.
prepare
(
positionUs
);
if
(!
sourcePrepared
)
{
return
TrackRenderer
.
STATE_UNPREPARED
;
}
int
trackCount
=
source
.
getTrackCount
();
for
(
int
i
=
0
;
i
<
subtitleParsers
.
length
;
i
++)
{
for
(
int
j
=
0
;
j
<
source
.
getTrackCount
()
;
j
++)
{
for
(
int
j
=
0
;
j
<
trackCount
;
j
++)
{
if
(
subtitleParsers
[
i
].
canParse
(
source
.
getTrackInfo
(
j
).
mimeType
))
{
parserIndex
=
i
;
trackIndex
=
j
;
...
...
@@ -197,11 +194,7 @@ public class TextTrackRenderer extends TrackRenderer implements Callback {
@Override
protected
void
doSomeWork
(
long
positionUs
,
long
elapsedRealtimeUs
)
throws
ExoPlaybackException
{
try
{
source
.
continueBuffering
(
trackIndex
,
positionUs
);
}
catch
(
IOException
e
)
{
throw
new
ExoPlaybackException
(
e
);
}
source
.
continueBuffering
(
trackIndex
,
positionUs
);
if
(
nextSubtitle
==
null
)
{
try
{
...
...
@@ -240,17 +233,13 @@ public class TextTrackRenderer extends TrackRenderer implements Callback {
if
(!
inputStreamEnded
&&
nextSubtitle
==
null
&&
!
parserHelper
.
isParsing
())
{
// Try and read the next subtitle from the source.
try
{
SampleHolder
sampleHolder
=
parserHelper
.
getSampleHolder
();
sampleHolder
.
clearData
();
int
result
=
source
.
readData
(
trackIndex
,
positionUs
,
formatHolder
,
sampleHolder
,
false
);
if
(
result
==
SampleSource
.
SAMPLE_READ
)
{
parserHelper
.
startParseOperation
();
}
else
if
(
result
==
SampleSource
.
END_OF_STREAM
)
{
inputStreamEnded
=
true
;
}
}
catch
(
IOException
e
)
{
throw
new
ExoPlaybackException
(
e
);
SampleHolder
sampleHolder
=
parserHelper
.
getSampleHolder
();
sampleHolder
.
clearData
();
int
result
=
source
.
readData
(
trackIndex
,
positionUs
,
formatHolder
,
sampleHolder
,
false
);
if
(
result
==
SampleSource
.
SAMPLE_READ
)
{
parserHelper
.
startParseOperation
();
}
else
if
(
result
==
SampleSource
.
END_OF_STREAM
)
{
inputStreamEnded
=
true
;
}
}
}
...
...
@@ -272,6 +261,15 @@ public class TextTrackRenderer extends TrackRenderer implements Callback {
}
@Override
protected
void
maybeThrowError
()
throws
ExoPlaybackException
{
try
{
source
.
maybeThrowError
();
}
catch
(
IOException
e
)
{
throw
new
ExoPlaybackException
(
e
);
}
}
@Override
protected
long
getDurationUs
()
{
return
source
.
getTrackInfo
(
trackIndex
).
durationUs
;
}
...
...
library/src/main/java/com/google/android/exoplayer/text/eia608/Eia608TrackRenderer.java
View file @
a2f10399
...
...
@@ -92,16 +92,13 @@ public class Eia608TrackRenderer extends TrackRenderer implements Callback {
}
@Override
protected
int
doPrepare
(
long
positionUs
)
throws
ExoPlaybackException
{
try
{
boolean
sourcePrepared
=
source
.
prepare
(
positionUs
);
if
(!
sourcePrepared
)
{
return
TrackRenderer
.
STATE_UNPREPARED
;
}
}
catch
(
IOException
e
)
{
throw
new
ExoPlaybackException
(
e
);
protected
int
doPrepare
(
long
positionUs
)
{
boolean
sourcePrepared
=
source
.
prepare
(
positionUs
);
if
(!
sourcePrepared
)
{
return
TrackRenderer
.
STATE_UNPREPARED
;
}
for
(
int
i
=
0
;
i
<
source
.
getTrackCount
();
i
++)
{
int
trackCount
=
source
.
getTrackCount
();
for
(
int
i
=
0
;
i
<
trackCount
;
i
++)
{
if
(
eia608Parser
.
canParse
(
source
.
getTrackInfo
(
i
).
mimeType
))
{
trackIndex
=
i
;
return
TrackRenderer
.
STATE_PREPARED
;
...
...
@@ -133,13 +130,7 @@ public class Eia608TrackRenderer extends TrackRenderer implements Callback {
@Override
protected
void
doSomeWork
(
long
positionUs
,
long
elapsedRealtimeUs
)
throws
ExoPlaybackException
{
try
{
source
.
continueBuffering
(
trackIndex
,
positionUs
);
}
catch
(
IOException
e
)
{
// TODO: This should be propagated, but in the current design propagation may occur too
// early. See [Internal b/22291244].
// throw new ExoPlaybackException(e);
}
source
.
continueBuffering
(
trackIndex
,
positionUs
);
if
(
isSamplePending
())
{
maybeParsePendingSample
(
positionUs
);
...
...
@@ -147,17 +138,11 @@ public class Eia608TrackRenderer extends TrackRenderer implements Callback {
int
result
=
inputStreamEnded
?
SampleSource
.
END_OF_STREAM
:
SampleSource
.
SAMPLE_READ
;
while
(!
isSamplePending
()
&&
result
==
SampleSource
.
SAMPLE_READ
)
{
try
{
result
=
source
.
readData
(
trackIndex
,
positionUs
,
formatHolder
,
sampleHolder
,
false
);
if
(
result
==
SampleSource
.
SAMPLE_READ
)
{
maybeParsePendingSample
(
positionUs
);
}
else
if
(
result
==
SampleSource
.
END_OF_STREAM
)
{
inputStreamEnded
=
true
;
}
}
catch
(
IOException
e
)
{
// TODO: This should be propagated, but in the current design propagation may occur too
// early. See [Internal b/22291244].
// throw new ExoPlaybackException(e);
result
=
source
.
readData
(
trackIndex
,
positionUs
,
formatHolder
,
sampleHolder
,
false
);
if
(
result
==
SampleSource
.
SAMPLE_READ
)
{
maybeParsePendingSample
(
positionUs
);
}
else
if
(
result
==
SampleSource
.
END_OF_STREAM
)
{
inputStreamEnded
=
true
;
}
}
...
...
@@ -182,6 +167,15 @@ public class Eia608TrackRenderer extends TrackRenderer implements Callback {
}
@Override
protected
void
maybeThrowError
()
throws
ExoPlaybackException
{
try
{
source
.
maybeThrowError
();
}
catch
(
IOException
e
)
{
throw
new
ExoPlaybackException
(
e
);
}
}
@Override
protected
long
getDurationUs
()
{
return
source
.
getTrackInfo
(
trackIndex
).
durationUs
;
}
...
...
library/src/main/java/com/google/android/exoplayer/util/ManifestFetcher.java
View file @
a2f10399
...
...
@@ -186,17 +186,17 @@ public class ManifestFetcher<T> implements Loader.Callback {
}
/**
*
Gets the error that affected the most recent attempt to load the manifest, or null if the
* most recent attempt was successful.
*
Throws the error that affected the most recent attempt to load the manifest. Does nothing if
*
the
most recent attempt was successful.
*
* @
return The error, or null if the most recent attempt was successful
.
* @
throws IOException The error that affected the most recent attempt to load the manifest
.
*/
public
IOException
getError
()
{
if
(
loadExceptionCount
<=
1
)
{
// Don't report an exception until at least 1 retry attempt has been made.
return
null
;
public
void
maybeThrowError
()
throws
IOException
{
// Don't throw an exception until at least 1 retry attempt has been made.
if
(
loadException
==
null
||
loadExceptionCount
<=
1
)
{
return
;
}
return
loadException
;
throw
loadException
;
}
/**
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment