Tighten isReady() up again.
- Bring back requirement for the first video frame to be rendered before isReady returns true, *unless* we've deduced that the upstream source is serving multiple renderers. - Ditto for requiring that the audio track has some buffered data.
This commit is contained in:
parent
98a7573812
commit
a7b88cd6a9
@ -426,7 +426,8 @@ public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean isReady() {
|
protected boolean isReady() {
|
||||||
return super.isReady() || getPendingFrameCount() > 0;
|
return getPendingFrameCount() > 0
|
||||||
|
|| (super.isReady() && getSourceState() == SOURCE_STATE_READY_READ_MAY_FAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -78,6 +78,22 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Value of {@link #sourceState} when the source is not ready.
|
||||||
|
*/
|
||||||
|
protected static final int SOURCE_STATE_NOT_READY = 0;
|
||||||
|
/**
|
||||||
|
* Value of {@link #sourceState} when the source is ready and we're able to read from it.
|
||||||
|
*/
|
||||||
|
protected static final int SOURCE_STATE_READY = 1;
|
||||||
|
/**
|
||||||
|
* Value of {@link #sourceState} when the source is ready but we might not be able to read from
|
||||||
|
* it. We transition to this state when an attempt to read a sample fails despite the source
|
||||||
|
* reporting that samples are available. This can occur when the next sample to be provided by
|
||||||
|
* the source is for another renderer.
|
||||||
|
*/
|
||||||
|
protected static final int SOURCE_STATE_READY_READ_MAY_FAIL = 2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the {@link MediaCodec} is hotswapped (i.e. replaced during playback), this is the period of
|
* If the {@link MediaCodec} is hotswapped (i.e. replaced during playback), this is the period of
|
||||||
* time during which {@link #isReady()} will report true regardless of whether the new codec has
|
* time during which {@link #isReady()} will report true regardless of whether the new codec has
|
||||||
@ -128,7 +144,7 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
|
|||||||
private int codecReconfigurationState;
|
private int codecReconfigurationState;
|
||||||
|
|
||||||
private int trackIndex;
|
private int trackIndex;
|
||||||
private boolean sourceIsReady;
|
private int sourceState;
|
||||||
private boolean inputStreamEnded;
|
private boolean inputStreamEnded;
|
||||||
private boolean outputStreamEnded;
|
private boolean outputStreamEnded;
|
||||||
private boolean waitingForKeys;
|
private boolean waitingForKeys;
|
||||||
@ -202,7 +218,7 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
|
|||||||
@Override
|
@Override
|
||||||
protected void onEnabled(long timeUs, boolean joining) {
|
protected void onEnabled(long timeUs, boolean joining) {
|
||||||
source.enable(trackIndex, timeUs);
|
source.enable(trackIndex, timeUs);
|
||||||
sourceIsReady = false;
|
sourceState = SOURCE_STATE_NOT_READY;
|
||||||
inputStreamEnded = false;
|
inputStreamEnded = false;
|
||||||
outputStreamEnded = false;
|
outputStreamEnded = false;
|
||||||
waitingForKeys = false;
|
waitingForKeys = false;
|
||||||
@ -353,7 +369,7 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
|
|||||||
protected void seekTo(long timeUs) throws ExoPlaybackException {
|
protected void seekTo(long timeUs) throws ExoPlaybackException {
|
||||||
currentPositionUs = timeUs;
|
currentPositionUs = timeUs;
|
||||||
source.seekToUs(timeUs);
|
source.seekToUs(timeUs);
|
||||||
sourceIsReady = false;
|
sourceState = SOURCE_STATE_NOT_READY;
|
||||||
inputStreamEnded = false;
|
inputStreamEnded = false;
|
||||||
outputStreamEnded = false;
|
outputStreamEnded = false;
|
||||||
waitingForKeys = false;
|
waitingForKeys = false;
|
||||||
@ -372,7 +388,9 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
|
|||||||
@Override
|
@Override
|
||||||
protected void doSomeWork(long timeUs) throws ExoPlaybackException {
|
protected void doSomeWork(long timeUs) throws ExoPlaybackException {
|
||||||
try {
|
try {
|
||||||
sourceIsReady = source.continueBuffering(timeUs);
|
sourceState = source.continueBuffering(timeUs)
|
||||||
|
? (sourceState == SOURCE_STATE_NOT_READY ? SOURCE_STATE_READY : sourceState)
|
||||||
|
: SOURCE_STATE_NOT_READY;
|
||||||
checkForDiscontinuity();
|
checkForDiscontinuity();
|
||||||
if (format == null) {
|
if (format == null) {
|
||||||
readFormat();
|
readFormat();
|
||||||
@ -384,7 +402,9 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
|
|||||||
}
|
}
|
||||||
if (codec != null) {
|
if (codec != null) {
|
||||||
while (drainOutputBuffer(timeUs)) {}
|
while (drainOutputBuffer(timeUs)) {}
|
||||||
while (feedInputBuffer()) {}
|
if (feedInputBuffer(true)) {
|
||||||
|
while (feedInputBuffer(false)) {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
codecCounters.ensureUpdated();
|
codecCounters.ensureUpdated();
|
||||||
@ -446,11 +466,13 @@ 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)}. False otherwise.
|
||||||
* @return True if it may be possible to feed more input data. 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 IOException If an error occurs reading data from the upstream source.
|
||||||
* @throws ExoPlaybackException If an error occurs feeding the input buffer.
|
* @throws ExoPlaybackException If an error occurs feeding the input buffer.
|
||||||
*/
|
*/
|
||||||
private boolean feedInputBuffer() throws IOException, ExoPlaybackException {
|
private boolean feedInputBuffer(boolean firstFeed) throws IOException, ExoPlaybackException {
|
||||||
if (inputStreamEnded) {
|
if (inputStreamEnded) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -478,6 +500,9 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
|
|||||||
codecReconfigurationState = RECONFIGURATION_STATE_QUEUE_PENDING;
|
codecReconfigurationState = RECONFIGURATION_STATE_QUEUE_PENDING;
|
||||||
}
|
}
|
||||||
result = source.readData(trackIndex, currentPositionUs, formatHolder, sampleHolder, false);
|
result = source.readData(trackIndex, currentPositionUs, formatHolder, sampleHolder, false);
|
||||||
|
if (firstFeed && sourceState == SOURCE_STATE_READY && result == SampleSource.NOTHING_READ) {
|
||||||
|
sourceState = SOURCE_STATE_READY_READ_MAY_FAIL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result == SampleSource.NOTHING_READ) {
|
if (result == SampleSource.NOTHING_READ) {
|
||||||
@ -646,7 +671,17 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
|
|||||||
@Override
|
@Override
|
||||||
protected boolean isReady() {
|
protected boolean isReady() {
|
||||||
return format != null && !waitingForKeys
|
return format != null && !waitingForKeys
|
||||||
&& (sourceIsReady || outputIndex >= 0 || isWithinHotswapPeriod());
|
&& sourceState != SOURCE_STATE_NOT_READY || outputIndex >= 0 || isWithinHotswapPeriod();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the source state.
|
||||||
|
*
|
||||||
|
* @return One of {@link #SOURCE_STATE_NOT_READY}, {@link #SOURCE_STATE_READY} and
|
||||||
|
* {@link #SOURCE_STATE_READY_READ_MAY_FAIL}.
|
||||||
|
*/
|
||||||
|
protected final int getSourceState() {
|
||||||
|
return sourceState;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isWithinHotswapPeriod() {
|
private boolean isWithinHotswapPeriod() {
|
||||||
|
@ -235,7 +235,8 @@ public class MediaCodecVideoTrackRenderer extends MediaCodecTrackRenderer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean isReady() {
|
protected boolean isReady() {
|
||||||
if (super.isReady()) {
|
if (super.isReady() && (renderedFirstFrame || !codecInitialized()
|
||||||
|
|| getSourceState() == SOURCE_STATE_READY_READ_MAY_FAIL)) {
|
||||||
// Ready. If we were joining then we've now joined, so clear the joining deadline.
|
// Ready. If we were joining then we've now joined, so clear the joining deadline.
|
||||||
joiningDeadlineUs = -1;
|
joiningDeadlineUs = -1;
|
||||||
return true;
|
return true;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user