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:
parent
2e81186a33
commit
ee14fe7adf
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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";
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user