Align Decoder(Audio|Video)Renderer decoder re-use logic

- Fix DecoderAudioRenderer to re-init codec if the DRM session changes.
- Add canKeepCodec to DecoderVideoRenderer. Previously it was assumed
  that the decoder could be re-used, but this will not be true in all
  cases for FfmpegVideoRenderer.

Issue: #7079
PiperOrigin-RevId: 309935278
This commit is contained in:
olly 2020-05-05 14:37:41 +01:00 committed by Oliver Woodman
parent 2e81186a33
commit ee14fe7adf
6 changed files with 40 additions and 7 deletions

View File

@ -162,4 +162,9 @@ public class Libgav1VideoRenderer extends DecoderVideoRenderer {
decoder.setOutputMode(outputMode); decoder.setOutputMode(outputMode);
} }
} }
@Override
protected boolean canKeepCodec(Format oldFormat, Format newFormat) {
return true;
}
} }

View File

@ -56,7 +56,8 @@ public final class FfmpegLibrary {
} }
/** Returns the version of the underlying library if available, or null otherwise. */ /** Returns the version of the underlying library if available, or null otherwise. */
public static @Nullable String getVersion() { @Nullable
public static String getVersion() {
return isAvailable() ? ffmpegGetVersion() : null; return isAvailable() ? ffmpegGetVersion() : null;
} }
@ -69,7 +70,7 @@ public final class FfmpegLibrary {
if (!isAvailable()) { if (!isAvailable()) {
return false; return false;
} }
String codecName = getCodecName(mimeType); @Nullable String codecName = getCodecName(mimeType);
if (codecName == null) { if (codecName == null) {
return false; return false;
} }
@ -84,7 +85,8 @@ public final class FfmpegLibrary {
* Returns the name of the FFmpeg decoder that could be used to decode the format, or {@code null} * Returns the name of the FFmpeg decoder that could be used to decode the format, or {@code null}
* if it's unsupported. * if it's unsupported.
*/ */
/* package */ static @Nullable String getCodecName(String mimeType) { @Nullable
/* package */ static String getCodecName(String mimeType) {
switch (mimeType) { switch (mimeType) {
case MimeTypes.AUDIO_AAC: case MimeTypes.AUDIO_AAC:
return "aac"; return "aac";

View File

@ -24,6 +24,7 @@ import com.google.android.exoplayer2.RendererCapabilities;
import com.google.android.exoplayer2.decoder.Decoder; import com.google.android.exoplayer2.decoder.Decoder;
import com.google.android.exoplayer2.drm.ExoMediaCrypto; import com.google.android.exoplayer2.drm.ExoMediaCrypto;
import com.google.android.exoplayer2.util.TraceUtil; import com.google.android.exoplayer2.util.TraceUtil;
import com.google.android.exoplayer2.util.Util;
import com.google.android.exoplayer2.video.DecoderVideoRenderer; import com.google.android.exoplayer2.video.DecoderVideoRenderer;
import com.google.android.exoplayer2.video.VideoDecoderInputBuffer; import com.google.android.exoplayer2.video.VideoDecoderInputBuffer;
import com.google.android.exoplayer2.video.VideoDecoderOutputBuffer; import com.google.android.exoplayer2.video.VideoDecoderOutputBuffer;
@ -113,4 +114,9 @@ public final class FfmpegVideoRenderer extends DecoderVideoRenderer {
} }
*/ */
} }
@Override
protected boolean canKeepCodec(Format oldFormat, Format newFormat) {
return Util.areEqual(oldFormat.sampleMimeType, newFormat.sampleMimeType);
}
} }

View File

@ -168,4 +168,9 @@ public class LibvpxVideoRenderer extends DecoderVideoRenderer {
decoder.setOutputMode(outputMode); decoder.setOutputMode(outputMode);
} }
} }
@Override
protected boolean canKeepCodec(Format oldFormat, Format newFormat) {
return true;
}
} }

View File

@ -323,7 +323,7 @@ public abstract class DecoderAudioRenderer extends BaseRenderer implements Media
* *
* @param oldFormat The previous format. * @param oldFormat The previous format.
* @param newFormat The new format. * @param newFormat The new format.
* @return True if the existing decoder can be kept. * @return Whether the existing decoder can be kept.
*/ */
protected boolean canKeepCodec(Format oldFormat, Format newFormat) { protected boolean canKeepCodec(Format oldFormat, Format newFormat) {
return false; return false;
@ -643,7 +643,9 @@ public abstract class DecoderAudioRenderer extends BaseRenderer implements Media
Format oldFormat = inputFormat; Format oldFormat = inputFormat;
inputFormat = newFormat; inputFormat = newFormat;
if (!canKeepCodec(oldFormat, inputFormat)) { if (decoder == null) {
maybeInitDecoder();
} else if (sourceDrmSession != decoderDrmSession || !canKeepCodec(oldFormat, inputFormat)) {
if (decoderReceivedBuffers) { if (decoderReceivedBuffers) {
// Signal end of stream and wait for any final output buffers before re-initialization. // Signal end of stream and wait for any final output buffers before re-initialization.
decoderReinitializationState = REINITIALIZATION_STATE_SIGNAL_END_OF_STREAM; decoderReinitializationState = REINITIALIZATION_STATE_SIGNAL_END_OF_STREAM;
@ -657,7 +659,6 @@ public abstract class DecoderAudioRenderer extends BaseRenderer implements Media
encoderDelay = inputFormat.encoderDelay; encoderDelay = inputFormat.encoderDelay;
encoderPadding = inputFormat.encoderPadding; encoderPadding = inputFormat.encoderPadding;
eventDispatcher.inputFormatChanged(inputFormat); eventDispatcher.inputFormatChanged(inputFormat);
} }

View File

@ -379,9 +379,12 @@ public abstract class DecoderVideoRenderer extends BaseRenderer {
waitingForFirstSampleInFormat = true; waitingForFirstSampleInFormat = true;
Format newFormat = Assertions.checkNotNull(formatHolder.format); Format newFormat = Assertions.checkNotNull(formatHolder.format);
setSourceDrmSession(formatHolder.drmSession); setSourceDrmSession(formatHolder.drmSession);
Format oldFormat = inputFormat;
inputFormat = newFormat; inputFormat = newFormat;
if (sourceDrmSession != decoderDrmSession) { if (decoder == null) {
maybeInitDecoder();
} else if (sourceDrmSession != decoderDrmSession || !canKeepCodec(oldFormat, inputFormat)) {
if (decoderReceivedBuffers) { if (decoderReceivedBuffers) {
// Signal end of stream and wait for any final output buffers before re-initialization. // Signal end of stream and wait for any final output buffers before re-initialization.
decoderReinitializationState = REINITIALIZATION_STATE_SIGNAL_END_OF_STREAM; decoderReinitializationState = REINITIALIZATION_STATE_SIGNAL_END_OF_STREAM;
@ -640,6 +643,17 @@ public abstract class DecoderVideoRenderer extends BaseRenderer {
*/ */
protected abstract void setDecoderOutputMode(@C.VideoOutputMode int outputMode); protected abstract void setDecoderOutputMode(@C.VideoOutputMode int outputMode);
/**
* Returns whether the existing decoder can be kept for a new format.
*
* @param oldFormat The previous format.
* @param newFormat The new format.
* @return Whether the existing decoder can be kept.
*/
protected boolean canKeepCodec(Format oldFormat, Format newFormat) {
return false;
}
// Internal methods. // Internal methods.
private void setSourceDrmSession(@Nullable DrmSession session) { private void setSourceDrmSession(@Nullable DrmSession session) {