Skip to content

Commit

Permalink
Align Decoder(Audio|Video)Renderer decoder re-use logic
Browse files Browse the repository at this point in the history
- 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
  • Loading branch information
ojw28 committed May 5, 2020
1 parent 2e81186 commit ee14fe7
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -162,4 +162,9 @@ protected void setDecoderOutputMode(@C.VideoOutputMode int outputMode) {
decoder.setOutputMode(outputMode);
}
}

@Override
protected boolean canKeepCodec(Format oldFormat, Format newFormat) {
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ public static boolean isAvailable() {
}

/** 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;
}

Expand All @@ -69,7 +70,7 @@ public static boolean supportsFormat(String mimeType) {
if (!isAvailable()) {
return false;
}
String codecName = getCodecName(mimeType);
@Nullable String codecName = getCodecName(mimeType);
if (codecName == null) {
return false;
}
Expand All @@ -84,7 +85,8 @@ public static boolean supportsFormat(String mimeType) {
* Returns the name of the FFmpeg decoder that could be used to decode the format, or {@code null}
* if it's unsupported.
*/
/* package */ static @Nullable String getCodecName(String mimeType) {
@Nullable
/* package */ static String getCodecName(String mimeType) {
switch (mimeType) {
case MimeTypes.AUDIO_AAC:
return "aac";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import com.google.android.exoplayer2.decoder.Decoder;
import com.google.android.exoplayer2.drm.ExoMediaCrypto;
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.VideoDecoderInputBuffer;
import com.google.android.exoplayer2.video.VideoDecoderOutputBuffer;
Expand Down Expand Up @@ -113,4 +114,9 @@ protected void setDecoderOutputMode(@C.VideoOutputMode int outputMode) {
}
*/
}

@Override
protected boolean canKeepCodec(Format oldFormat, Format newFormat) {
return Util.areEqual(oldFormat.sampleMimeType, newFormat.sampleMimeType);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -168,4 +168,9 @@ protected void setDecoderOutputMode(@C.VideoOutputMode int outputMode) {
decoder.setOutputMode(outputMode);
}
}

@Override
protected boolean canKeepCodec(Format oldFormat, Format newFormat) {
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ protected void onAudioTrackSkipSilenceEnabledChanged(boolean skipSilenceEnabled)
*
* @param oldFormat The previous 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) {
return false;
Expand Down Expand Up @@ -643,7 +643,9 @@ private void onInputFormatChanged(FormatHolder formatHolder) throws ExoPlaybackE
Format oldFormat = inputFormat;
inputFormat = newFormat;

if (!canKeepCodec(oldFormat, inputFormat)) {
if (decoder == null) {
maybeInitDecoder();
} else if (sourceDrmSession != decoderDrmSession || !canKeepCodec(oldFormat, inputFormat)) {
if (decoderReceivedBuffers) {
// Signal end of stream and wait for any final output buffers before re-initialization.
decoderReinitializationState = REINITIALIZATION_STATE_SIGNAL_END_OF_STREAM;
Expand All @@ -657,7 +659,6 @@ private void onInputFormatChanged(FormatHolder formatHolder) throws ExoPlaybackE

encoderDelay = inputFormat.encoderDelay;
encoderPadding = inputFormat.encoderPadding;

eventDispatcher.inputFormatChanged(inputFormat);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -379,9 +379,12 @@ protected void onInputFormatChanged(FormatHolder formatHolder) throws ExoPlaybac
waitingForFirstSampleInFormat = true;
Format newFormat = Assertions.checkNotNull(formatHolder.format);
setSourceDrmSession(formatHolder.drmSession);
Format oldFormat = inputFormat;
inputFormat = newFormat;

if (sourceDrmSession != decoderDrmSession) {
if (decoder == null) {
maybeInitDecoder();
} else if (sourceDrmSession != decoderDrmSession || !canKeepCodec(oldFormat, inputFormat)) {
if (decoderReceivedBuffers) {
// Signal end of stream and wait for any final output buffers before re-initialization.
decoderReinitializationState = REINITIALIZATION_STATE_SIGNAL_END_OF_STREAM;
Expand Down Expand Up @@ -640,6 +643,17 @@ protected final void setOutputBufferRenderer(
*/
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.

private void setSourceDrmSession(@Nullable DrmSession session) {
Expand Down

0 comments on commit ee14fe7

Please sign in to comment.