Skip to content

Commit

Permalink
Fix bypass mode when the stream is empty
Browse files Browse the repository at this point in the history
Issue: #8374
PiperOrigin-RevId: 348792965
  • Loading branch information
ojw28 authored and icbaker committed Jan 11, 2021
1 parent 858fa26 commit ca287ba
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 31 deletions.
2 changes: 2 additions & 0 deletions RELEASENOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
* Core library:
* Fix playback issues after seeking during an ad
([#8349](https://github.com/google/ExoPlayer/issues/8349)).
* Fix `MediaCodecRenderer` issue where empty streams would fail to play in
bypass mode ([#8374](https://github.com/google/ExoPlayer/issues/8374)).
* UI:
* Fix issue where pop-up menus belonging to `StyledPlayerControlView`
would not be dismissed when tapping outside of the menu area or pressing
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,26 +153,26 @@ private boolean canBatch(DecoderInputBuffer accessUnit) {
}

private void putAccessUnit(DecoderInputBuffer accessUnit) {
@Nullable ByteBuffer accessUnitData = accessUnit.data;
if (accessUnitData != null) {
accessUnit.flip();
ensureSpaceForWrite(accessUnitData.remaining());
this.data.put(accessUnitData);
}

if (accessUnit.isEndOfStream()) {
setFlags(C.BUFFER_FLAG_END_OF_STREAM);
}
if (accessUnit.isDecodeOnly()) {
setFlags(C.BUFFER_FLAG_DECODE_ONLY);
}
if (accessUnit.isKeyFrame()) {
setFlags(C.BUFFER_FLAG_KEY_FRAME);
}
accessUnitCount++;
timeUs = accessUnit.timeUs;
if (accessUnitCount == 1) { // First read of the buffer
firstAccessUnitTimeUs = timeUs;
} else {
timeUs = accessUnit.timeUs;
if (accessUnit.isDecodeOnly()) {
setFlags(C.BUFFER_FLAG_DECODE_ONLY);
}
if (accessUnit.isKeyFrame()) {
setFlags(C.BUFFER_FLAG_KEY_FRAME);
}
@Nullable ByteBuffer accessUnitData = accessUnit.data;
if (accessUnitData != null) {
accessUnit.flip();
ensureSpaceForWrite(accessUnitData.remaining());
this.data.put(accessUnitData);
}
accessUnitCount++;
if (accessUnitCount == 1) {
firstAccessUnitTimeUs = timeUs;
}
}
accessUnit.clear();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,11 @@ public MediaCodecRenderer(
outputStreamStartPositionUs = C.TIME_UNSET;
outputStreamOffsetUs = C.TIME_UNSET;
bypassBatchBuffer = new BatchBuffer();
bypassBatchBuffer.ensureSpaceForWrite(/* length= */ 0);
// MediaCodec outputs audio buffers in native endian:
// https://developer.android.com/reference/android/media/MediaCodec#raw-audio-buffers
// and code called from MediaCodecAudioRenderer.processOutputBuffer expects this endianness.
bypassBatchBuffer.data.order(ByteOrder.nativeOrder());
resetCodecStateForRelease();
}

Expand Down Expand Up @@ -2134,15 +2139,15 @@ private FrameworkMediaCrypto getFrameworkMediaCrypto(DrmSession drmSession)
* iteration of the rendering loop.
* @param elapsedRealtimeUs {@link SystemClock#elapsedRealtime()} in microseconds, measured at the
* start of the current iteration of the rendering loop.
* @return If more buffers are ready to be rendered.
* @return Whether immediately calling this method again will make more progress.
* @throws ExoPlaybackException If an error occurred while processing a buffer or handling a
* format change.
*/
private boolean bypassRender(long positionUs, long elapsedRealtimeUs)
throws ExoPlaybackException {
BatchBuffer batchBuffer = bypassBatchBuffer;

// Let's process the pending buffer if any.
// Process any data in the batch buffer.
checkState(!outputStreamEnded);
if (!batchBuffer.isEmpty()) { // Optimisation: Do not process buffer if empty.
if (processOutputBuffer(
Expand All @@ -2157,12 +2162,13 @@ private boolean bypassRender(long positionUs, long elapsedRealtimeUs)
batchBuffer.isDecodeOnly(),
batchBuffer.isEndOfStream(),
outputFormat)) {
// Buffer completely processed
onProcessedOutputBuffer(batchBuffer.getLastAccessUnitTimeUs());
} else {
return false; // Could not process buffer, let's try later.
// Could not process the whole buffer. Try again later.
return false;
}
}
// Process the end of stream, if it has been reached.
if (batchBuffer.isEndOfStream()) {
outputStreamEnded = true;
return false;
Expand Down Expand Up @@ -2197,19 +2203,17 @@ private boolean bypassRender(long positionUs, long elapsedRealtimeUs)
onInputFormatChanged(formatHolder);
}

boolean haveDataToProcess = false;
if (batchBuffer.isEndOfStream()) {
inputStreamEnded = true;
haveDataToProcess = true;
}

if (batchBuffer.isEmpty()) {
return false; // The buffer could not be filled, there is nothing more to do.
if (!batchBuffer.isEmpty()) {
batchBuffer.flip();
haveDataToProcess = true;
}
batchBuffer.flip(); // Buffer at least partially full, it can now be processed.
// MediaCodec outputs buffers in native endian:
// https://developer.android.com/reference/android/media/MediaCodec#raw-audio-buffers
// and code called from processOutputBuffer expects this endianness.
batchBuffer.data.order(ByteOrder.nativeOrder());
return true;

return haveDataToProcess;
}

/**
Expand Down

0 comments on commit ca287ba

Please sign in to comment.