Re-add "waiting for keyframe" logic in MediaCodecRenderer

This is a partial revert of 0a2bacb7b7. I've added a comment
explaining why the code path is necessary after all, to avoid
future confusion.

PiperOrigin-RevId: 319822696
This commit is contained in:
olly 2020-07-06 19:43:00 +01:00 committed by kim-vde
parent 93b5b947db
commit 6cf15de7e9
3 changed files with 42 additions and 24 deletions

View file

@ -1318,6 +1318,21 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
return false;
}
// This logic is required for cases where the decoder needs to be flushed or re-instantiated
// during normal consumption of samples from the source (i.e., without a corresponding
// Renderer.enable or Renderer.resetPosition call). This is necessary for certain legacy and
// workaround behaviors, for example when switching the output Surface on API levels prior to
// the introduction of MediaCodec.setOutputSurface.
if (!codecReceivedBuffers && !buffer.isKeyFrame()) {
buffer.clear();
if (codecReconfigurationState == RECONFIGURATION_STATE_QUEUE_PENDING) {
// The buffer we just cleared contained reconfiguration data. We need to re-write this data
// into a subsequent buffer (if there is one).
codecReconfigurationState = RECONFIGURATION_STATE_WRITE_PENDING;
}
return true;
}
boolean bufferEncrypted = buffer.isEncrypted();
if (bufferEncrypted) {
buffer.cryptoInfo.increaseClearDataFirstSubSampleBy(adaptiveReconfigurationBytes);

View file

@ -115,13 +115,13 @@ public class MediaCodecAudioRendererTest {
/* eventDispatcher= */ null,
/* initialFormat= */ AUDIO_AAC,
ImmutableList.of(
oneByteSample(/* timeUs= */ 0),
oneByteSample(/* timeUs= */ 50),
oneByteSample(/* timeUs= */ 100),
oneByteSample(/* timeUs= */ 0, C.BUFFER_FLAG_KEY_FRAME),
oneByteSample(/* timeUs= */ 50, C.BUFFER_FLAG_KEY_FRAME),
oneByteSample(/* timeUs= */ 100, C.BUFFER_FLAG_KEY_FRAME),
format(changedFormat),
oneByteSample(/* timeUs= */ 150),
oneByteSample(/* timeUs= */ 200),
oneByteSample(/* timeUs= */ 250),
oneByteSample(/* timeUs= */ 150, C.BUFFER_FLAG_KEY_FRAME),
oneByteSample(/* timeUs= */ 200, C.BUFFER_FLAG_KEY_FRAME),
oneByteSample(/* timeUs= */ 250, C.BUFFER_FLAG_KEY_FRAME),
END_OF_STREAM_ITEM));
mediaCodecAudioRenderer.enable(
@ -162,13 +162,13 @@ public class MediaCodecAudioRendererTest {
/* eventDispatcher= */ null,
/* initialFormat= */ AUDIO_AAC,
ImmutableList.of(
oneByteSample(/* timeUs= */ 0),
oneByteSample(/* timeUs= */ 50),
oneByteSample(/* timeUs= */ 100),
oneByteSample(/* timeUs= */ 0, C.BUFFER_FLAG_KEY_FRAME),
oneByteSample(/* timeUs= */ 50, C.BUFFER_FLAG_KEY_FRAME),
oneByteSample(/* timeUs= */ 100, C.BUFFER_FLAG_KEY_FRAME),
format(changedFormat),
oneByteSample(/* timeUs= */ 150),
oneByteSample(/* timeUs= */ 200),
oneByteSample(/* timeUs= */ 250),
oneByteSample(/* timeUs= */ 150, C.BUFFER_FLAG_KEY_FRAME),
oneByteSample(/* timeUs= */ 200, C.BUFFER_FLAG_KEY_FRAME),
oneByteSample(/* timeUs= */ 250, C.BUFFER_FLAG_KEY_FRAME),
END_OF_STREAM_ITEM));
mediaCodecAudioRenderer.enable(
@ -228,7 +228,8 @@ public class MediaCodecAudioRendererTest {
DrmSessionManager.DUMMY,
/* eventDispatcher= */ null,
/* initialFormat= */ AUDIO_AAC,
ImmutableList.of(oneByteSample(/* timeUs= */ 0), END_OF_STREAM_ITEM));
ImmutableList.of(
oneByteSample(/* timeUs= */ 0, C.BUFFER_FLAG_KEY_FRAME), END_OF_STREAM_ITEM));
exceptionThrowingRenderer.enable(
RendererConfiguration.DEFAULT,

View file

@ -133,7 +133,7 @@ public class MediaCodecVideoRendererTest {
/* eventDispatcher= */ null,
/* initialFormat= */ VIDEO_H264,
ImmutableList.of(
oneByteSample(/* timeUs= */ 0), // First buffer.
oneByteSample(/* timeUs= */ 0, C.BUFFER_FLAG_KEY_FRAME), // First buffer.
oneByteSample(/* timeUs= */ 50_000), // Late buffer.
oneByteSample(/* timeUs= */ 100_000), // Last buffer.
FakeSampleStreamItem.END_OF_STREAM_ITEM));
@ -169,7 +169,8 @@ public class MediaCodecVideoRendererTest {
/* eventDispatcher= */ null,
/* initialFormat= */ VIDEO_H264,
ImmutableList.of(
oneByteSample(/* timeUs= */ 0), FakeSampleStreamItem.END_OF_STREAM_ITEM)),
oneByteSample(/* timeUs= */ 0, C.BUFFER_FLAG_KEY_FRAME),
FakeSampleStreamItem.END_OF_STREAM_ITEM)),
/* positionUs= */ 0,
/* joining= */ false,
/* mayRenderStartOfStream= */ true,
@ -204,7 +205,7 @@ public class MediaCodecVideoRendererTest {
DrmSessionManager.DUMMY,
/* eventDispatcher= */ null,
/* initialFormat= */ pAsp1,
ImmutableList.of(oneByteSample(/* timeUs= */ 0)));
ImmutableList.of(oneByteSample(/* timeUs= */ 0, C.BUFFER_FLAG_KEY_FRAME)));
mediaCodecVideoRenderer.enable(
RendererConfiguration.DEFAULT,
@ -248,7 +249,7 @@ public class MediaCodecVideoRendererTest {
DrmSessionManager.DUMMY,
/* eventDispatcher= */ null,
/* initialFormat= */ VIDEO_H264,
ImmutableList.of(oneByteSample(/* timeUs= */ 0)));
ImmutableList.of(oneByteSample(/* timeUs= */ 0, C.BUFFER_FLAG_KEY_FRAME)));
mediaCodecVideoRenderer.enable(
RendererConfiguration.DEFAULT,
new Format[] {VIDEO_H264},
@ -262,7 +263,8 @@ public class MediaCodecVideoRendererTest {
mediaCodecVideoRenderer.render(/* positionUs= */ 0, SystemClock.elapsedRealtime() * 1000);
mediaCodecVideoRenderer.resetPosition(0);
mediaCodecVideoRenderer.setCurrentStreamFinal();
fakeSampleStream.addFakeSampleStreamItem(oneByteSample(/* timeUs= */ 0));
fakeSampleStream.addFakeSampleStreamItem(
oneByteSample(/* timeUs= */ 0, C.BUFFER_FLAG_KEY_FRAME));
fakeSampleStream.addFakeSampleStreamItem(FakeSampleStreamItem.END_OF_STREAM_ITEM);
int positionUs = 10;
do {
@ -280,7 +282,7 @@ public class MediaCodecVideoRendererTest {
DrmSessionManager.DUMMY,
/* eventDispatcher= */ null,
/* initialFormat= */ VIDEO_H264,
ImmutableList.of(oneByteSample(/* timeUs= */ 0)));
ImmutableList.of(oneByteSample(/* timeUs= */ 0, C.BUFFER_FLAG_KEY_FRAME)));
mediaCodecVideoRenderer.enable(
RendererConfiguration.DEFAULT,
@ -329,7 +331,7 @@ public class MediaCodecVideoRendererTest {
DrmSessionManager.DUMMY,
/* eventDispatcher= */ null,
/* initialFormat= */ VIDEO_H264,
ImmutableList.of(oneByteSample(/* timeUs= */ 0)));
ImmutableList.of(oneByteSample(/* timeUs= */ 0, C.BUFFER_FLAG_KEY_FRAME)));
mediaCodecVideoRenderer.enable(
RendererConfiguration.DEFAULT,
@ -445,16 +447,16 @@ public class MediaCodecVideoRendererTest {
/* eventDispatcher= */ null,
/* initialFormat= */ mp4Uhd,
ImmutableList.of(
oneByteSample(/* timeUs= */ 0),
oneByteSample(/* timeUs= */ 0, C.BUFFER_FLAG_KEY_FRAME),
format(VIDEO_H264),
oneByteSample(/* timeUs= */ 50),
oneByteSample(/* timeUs= */ 50, C.BUFFER_FLAG_KEY_FRAME),
oneByteSample(/* timeUs= */ 100),
format(mp4Uhd),
oneByteSample(/* timeUs= */ 150),
oneByteSample(/* timeUs= */ 150, C.BUFFER_FLAG_KEY_FRAME),
oneByteSample(/* timeUs= */ 200),
oneByteSample(/* timeUs= */ 250),
format(VIDEO_H264),
oneByteSample(/* timeUs= */ 300),
oneByteSample(/* timeUs= */ 300, C.BUFFER_FLAG_KEY_FRAME),
FakeSampleStreamItem.END_OF_STREAM_ITEM));
mediaCodecVideoRenderer.enable(