Make SimpleDecoderXRenderers work with any Decoder implementation

The restriction that these classes only work with SimpleDecoders
is unnecessary. An FfmpegVideoRenderer will not be able to use a
SimpleDecoder, because the SimpleDecoder assumption that each input
buffer can be decoded immediately into a corresponding output is
not true for all video codecs that Ffmpeg supports (e.g., H264 does
not have this property). Generalizing SimpleDecoderVideoRenderer to
DecoderVideoRenderer will allow FfmpegVideoRenderer to still use
the base class, without having to use a SimpleDecoder.

This is a preliminary change toward being able to merge a version
of https://github.com/google/ExoPlayer/pull/7079.

Issue: #2159
PiperOrigin-RevId: 301412344
This commit is contained in:
olly 2020-03-17 18:12:29 +00:00 committed by Oliver Woodman
parent a3a3b5be0b
commit cbe99ec475
23 changed files with 79 additions and 80 deletions

View File

@ -53,6 +53,9 @@
* Add option to `MergingMediaSource` to adjust the time offsets between * Add option to `MergingMediaSource` to adjust the time offsets between
the merged sources the merged sources
([#6103](https://github.com/google/ExoPlayer/issues/6103)). ([#6103](https://github.com/google/ExoPlayer/issues/6103)).
* `SimpleDecoderVideoRenderer` and `SimpleDecoderAudioRenderer` renamed to
`DecoderVideoRenderer` and `DecoderAudioRenderer` respectively, and
generalized to work with `Decoder` rather than `SimpleDecoder`.
* Text: * Text:
* Parse `<ruby>` and `<rt>` tags in WebVTT subtitles (rendering is coming * Parse `<ruby>` and `<rt>` tags in WebVTT subtitles (rendering is coming
later). later).

View File

@ -31,7 +31,7 @@ import com.google.android.exoplayer2.drm.ExoMediaCrypto;
import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.MimeTypes;
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.util.Util;
import com.google.android.exoplayer2.video.SimpleDecoderVideoRenderer; import com.google.android.exoplayer2.video.DecoderVideoRenderer;
import com.google.android.exoplayer2.video.VideoDecoderException; import com.google.android.exoplayer2.video.VideoDecoderException;
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;
@ -52,7 +52,7 @@ import com.google.android.exoplayer2.video.VideoRendererEventListener;
* VideoDecoderOutputBufferRenderer}, or null. * VideoDecoderOutputBufferRenderer}, or null.
* </ul> * </ul>
*/ */
public class Libgav1VideoRenderer extends SimpleDecoderVideoRenderer { public class Libgav1VideoRenderer extends DecoderVideoRenderer {
private static final int DEFAULT_NUM_OF_INPUT_BUFFERS = 4; private static final int DEFAULT_NUM_OF_INPUT_BUFFERS = 4;
private static final int DEFAULT_NUM_OF_OUTPUT_BUFFERS = 4; private static final int DEFAULT_NUM_OF_OUTPUT_BUFFERS = 4;

View File

@ -22,17 +22,15 @@ import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.audio.AudioProcessor; import com.google.android.exoplayer2.audio.AudioProcessor;
import com.google.android.exoplayer2.audio.AudioRendererEventListener; import com.google.android.exoplayer2.audio.AudioRendererEventListener;
import com.google.android.exoplayer2.audio.AudioSink; import com.google.android.exoplayer2.audio.AudioSink;
import com.google.android.exoplayer2.audio.DecoderAudioRenderer;
import com.google.android.exoplayer2.audio.DefaultAudioSink; import com.google.android.exoplayer2.audio.DefaultAudioSink;
import com.google.android.exoplayer2.audio.SimpleDecoderAudioRenderer;
import com.google.android.exoplayer2.drm.ExoMediaCrypto; import com.google.android.exoplayer2.drm.ExoMediaCrypto;
import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.MimeTypes;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull; import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
/** /** Decodes and renders audio using FFmpeg. */
* Decodes and renders audio using FFmpeg. public final class FfmpegAudioRenderer extends DecoderAudioRenderer {
*/
public final class FfmpegAudioRenderer extends SimpleDecoderAudioRenderer {
/** The number of input and output buffers. */ /** The number of input and output buffers. */
private static final int NUM_BUFFERS = 16; private static final int NUM_BUFFERS = 16;

View File

@ -88,7 +88,7 @@ import java.util.List;
@Override @Override
protected SimpleOutputBuffer createOutputBuffer() { protected SimpleOutputBuffer createOutputBuffer() {
return new SimpleOutputBuffer(this); return new SimpleOutputBuffer(this::releaseOutputBuffer);
} }
@Override @Override

View File

@ -85,7 +85,7 @@ import java.util.List;
@Override @Override
protected SimpleOutputBuffer createOutputBuffer() { protected SimpleOutputBuffer createOutputBuffer() {
return new SimpleOutputBuffer(this); return new SimpleOutputBuffer(this::releaseOutputBuffer);
} }
@Override @Override

View File

@ -22,7 +22,7 @@ import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.audio.AudioProcessor; import com.google.android.exoplayer2.audio.AudioProcessor;
import com.google.android.exoplayer2.audio.AudioRendererEventListener; import com.google.android.exoplayer2.audio.AudioRendererEventListener;
import com.google.android.exoplayer2.audio.AudioSink; import com.google.android.exoplayer2.audio.AudioSink;
import com.google.android.exoplayer2.audio.SimpleDecoderAudioRenderer; import com.google.android.exoplayer2.audio.DecoderAudioRenderer;
import com.google.android.exoplayer2.drm.ExoMediaCrypto; import com.google.android.exoplayer2.drm.ExoMediaCrypto;
import com.google.android.exoplayer2.extractor.FlacStreamMetadata; import com.google.android.exoplayer2.extractor.FlacStreamMetadata;
import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Assertions;
@ -32,7 +32,7 @@ import com.google.android.exoplayer2.util.Util;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull; import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
/** Decodes and renders audio using the native Flac decoder. */ /** Decodes and renders audio using the native Flac decoder. */
public final class LibflacAudioRenderer extends SimpleDecoderAudioRenderer { public final class LibflacAudioRenderer extends DecoderAudioRenderer {
private static final int NUM_BUFFERS = 16; private static final int NUM_BUFFERS = 16;

View File

@ -21,12 +21,12 @@ import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.audio.AudioProcessor; import com.google.android.exoplayer2.audio.AudioProcessor;
import com.google.android.exoplayer2.audio.AudioRendererEventListener; import com.google.android.exoplayer2.audio.AudioRendererEventListener;
import com.google.android.exoplayer2.audio.SimpleDecoderAudioRenderer; import com.google.android.exoplayer2.audio.DecoderAudioRenderer;
import com.google.android.exoplayer2.drm.ExoMediaCrypto; import com.google.android.exoplayer2.drm.ExoMediaCrypto;
import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.MimeTypes;
/** Decodes and renders audio using the native Opus decoder. */ /** Decodes and renders audio using the native Opus decoder. */
public class LibopusAudioRenderer extends SimpleDecoderAudioRenderer { public class LibopusAudioRenderer extends DecoderAudioRenderer {
/** The number of input and output buffers. */ /** The number of input and output buffers. */
private static final int NUM_BUFFERS = 16; private static final int NUM_BUFFERS = 16;

View File

@ -148,7 +148,7 @@ import java.util.List;
@Override @Override
protected SimpleOutputBuffer createOutputBuffer() { protected SimpleOutputBuffer createOutputBuffer() {
return new SimpleOutputBuffer(this); return new SimpleOutputBuffer(this::releaseOutputBuffer);
} }
@Override @Override

View File

@ -30,7 +30,7 @@ import com.google.android.exoplayer2.decoder.SimpleDecoder;
import com.google.android.exoplayer2.drm.ExoMediaCrypto; import com.google.android.exoplayer2.drm.ExoMediaCrypto;
import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.MimeTypes;
import com.google.android.exoplayer2.util.TraceUtil; import com.google.android.exoplayer2.util.TraceUtil;
import com.google.android.exoplayer2.video.SimpleDecoderVideoRenderer; import com.google.android.exoplayer2.video.DecoderVideoRenderer;
import com.google.android.exoplayer2.video.VideoDecoderException; import com.google.android.exoplayer2.video.VideoDecoderException;
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;
@ -52,7 +52,7 @@ import com.google.android.exoplayer2.video.VideoRendererEventListener;
* VideoDecoderOutputBufferRenderer}, or null. * VideoDecoderOutputBufferRenderer}, or null.
* </ul> * </ul>
*/ */
public class LibvpxVideoRenderer extends SimpleDecoderVideoRenderer { public class LibvpxVideoRenderer extends DecoderVideoRenderer {
/** The number of input buffers. */ /** The number of input buffers. */
private final int numInputBuffers; private final int numInputBuffers;

View File

@ -32,7 +32,7 @@ public final class VpxOutputBuffer extends VideoDecoderOutputBuffer {
* *
* @param owner Buffer owner. * @param owner Buffer owner.
*/ */
public VpxOutputBuffer(VideoDecoderOutputBuffer.Owner owner) { public VpxOutputBuffer(Owner<VideoDecoderOutputBuffer> owner) {
super(owner); super(owner);
} }
} }

View File

@ -24,7 +24,7 @@ import com.google.android.exoplayer2.audio.AuxEffectInfo;
import com.google.android.exoplayer2.source.SampleStream; import com.google.android.exoplayer2.source.SampleStream;
import com.google.android.exoplayer2.util.MediaClock; import com.google.android.exoplayer2.util.MediaClock;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import com.google.android.exoplayer2.video.SimpleDecoderVideoRenderer; import com.google.android.exoplayer2.video.DecoderVideoRenderer;
import com.google.android.exoplayer2.video.VideoDecoderOutputBufferRenderer; import com.google.android.exoplayer2.video.VideoDecoderOutputBufferRenderer;
import com.google.android.exoplayer2.video.VideoFrameMetadataListener; import com.google.android.exoplayer2.video.VideoFrameMetadataListener;
import com.google.android.exoplayer2.video.spherical.CameraMotionListener; import com.google.android.exoplayer2.video.spherical.CameraMotionListener;
@ -115,7 +115,7 @@ public interface Renderer extends PlayerMessage.Target {
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
int MSG_SET_CAMERA_MOTION_LISTENER = C.MSG_SET_CAMERA_MOTION_LISTENER; int MSG_SET_CAMERA_MOTION_LISTENER = C.MSG_SET_CAMERA_MOTION_LISTENER;
/** /**
* The type of a message that can be passed to a {@link SimpleDecoderVideoRenderer} via {@link * The type of a message that can be passed to a {@link DecoderVideoRenderer} via {@link
* ExoPlayer#createMessage(Target)}. The message payload should be the target {@link * ExoPlayer#createMessage(Target)}. The message payload should be the target {@link
* VideoDecoderOutputBufferRenderer}, or null. * VideoDecoderOutputBufferRenderer}, or null.
* *

View File

@ -29,9 +29,9 @@ import com.google.android.exoplayer2.FormatHolder;
import com.google.android.exoplayer2.PlayerMessage.Target; import com.google.android.exoplayer2.PlayerMessage.Target;
import com.google.android.exoplayer2.RendererCapabilities; import com.google.android.exoplayer2.RendererCapabilities;
import com.google.android.exoplayer2.audio.AudioRendererEventListener.EventDispatcher; import com.google.android.exoplayer2.audio.AudioRendererEventListener.EventDispatcher;
import com.google.android.exoplayer2.decoder.Decoder;
import com.google.android.exoplayer2.decoder.DecoderCounters; import com.google.android.exoplayer2.decoder.DecoderCounters;
import com.google.android.exoplayer2.decoder.DecoderInputBuffer; import com.google.android.exoplayer2.decoder.DecoderInputBuffer;
import com.google.android.exoplayer2.decoder.SimpleDecoder;
import com.google.android.exoplayer2.decoder.SimpleOutputBuffer; import com.google.android.exoplayer2.decoder.SimpleOutputBuffer;
import com.google.android.exoplayer2.drm.DrmSession; import com.google.android.exoplayer2.drm.DrmSession;
import com.google.android.exoplayer2.drm.DrmSession.DrmSessionException; import com.google.android.exoplayer2.drm.DrmSession.DrmSessionException;
@ -47,7 +47,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
/** /**
* Decodes and renders audio using a {@link SimpleDecoder}. * Decodes and renders audio using a {@link Decoder}.
* *
* <p>This renderer accepts the following messages sent via {@link ExoPlayer#createMessage(Target)} * <p>This renderer accepts the following messages sent via {@link ExoPlayer#createMessage(Target)}
* on the playback thread: * on the playback thread:
@ -68,7 +68,7 @@ import java.lang.annotation.RetentionPolicy;
* underlying audio track. * underlying audio track.
* </ul> * </ul>
*/ */
public abstract class SimpleDecoderAudioRenderer extends BaseRenderer implements MediaClock { public abstract class DecoderAudioRenderer extends BaseRenderer implements MediaClock {
@Documented @Documented
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
@ -105,8 +105,7 @@ public abstract class SimpleDecoderAudioRenderer extends BaseRenderer implements
private int encoderPadding; private int encoderPadding;
@Nullable @Nullable
private SimpleDecoder< private Decoder<DecoderInputBuffer, ? extends SimpleOutputBuffer, ? extends AudioDecoderException>
DecoderInputBuffer, ? extends SimpleOutputBuffer, ? extends AudioDecoderException>
decoder; decoder;
@Nullable private DecoderInputBuffer inputBuffer; @Nullable private DecoderInputBuffer inputBuffer;
@ -125,7 +124,7 @@ public abstract class SimpleDecoderAudioRenderer extends BaseRenderer implements
private boolean outputStreamEnded; private boolean outputStreamEnded;
private boolean waitingForKeys; private boolean waitingForKeys;
public SimpleDecoderAudioRenderer() { public DecoderAudioRenderer() {
this(/* eventHandler= */ null, /* eventListener= */ null); this(/* eventHandler= */ null, /* eventListener= */ null);
} }
@ -135,7 +134,7 @@ public abstract class SimpleDecoderAudioRenderer extends BaseRenderer implements
* @param eventListener A listener of events. May be null if delivery of events is not required. * @param eventListener A listener of events. May be null if delivery of events is not required.
* @param audioProcessors Optional {@link AudioProcessor}s that will process audio before output. * @param audioProcessors Optional {@link AudioProcessor}s that will process audio before output.
*/ */
public SimpleDecoderAudioRenderer( public DecoderAudioRenderer(
@Nullable Handler eventHandler, @Nullable Handler eventHandler,
@Nullable AudioRendererEventListener eventListener, @Nullable AudioRendererEventListener eventListener,
AudioProcessor... audioProcessors) { AudioProcessor... audioProcessors) {
@ -154,7 +153,7 @@ public abstract class SimpleDecoderAudioRenderer extends BaseRenderer implements
* default capabilities (no encoded audio passthrough support) should be assumed. * default capabilities (no encoded audio passthrough support) should be assumed.
* @param audioProcessors Optional {@link AudioProcessor}s that will process audio before output. * @param audioProcessors Optional {@link AudioProcessor}s that will process audio before output.
*/ */
public SimpleDecoderAudioRenderer( public DecoderAudioRenderer(
@Nullable Handler eventHandler, @Nullable Handler eventHandler,
@Nullable AudioRendererEventListener eventListener, @Nullable AudioRendererEventListener eventListener,
@Nullable AudioCapabilities audioCapabilities, @Nullable AudioCapabilities audioCapabilities,
@ -168,7 +167,7 @@ public abstract class SimpleDecoderAudioRenderer extends BaseRenderer implements
* @param eventListener A listener of events. May be null if delivery of events is not required. * @param eventListener A listener of events. May be null if delivery of events is not required.
* @param audioSink The sink to which audio will be output. * @param audioSink The sink to which audio will be output.
*/ */
public SimpleDecoderAudioRenderer( public DecoderAudioRenderer(
@Nullable Handler eventHandler, @Nullable Handler eventHandler,
@Nullable AudioRendererEventListener eventListener, @Nullable AudioRendererEventListener eventListener,
AudioSink audioSink) { AudioSink audioSink) {
@ -306,7 +305,7 @@ public abstract class SimpleDecoderAudioRenderer extends BaseRenderer implements
* @return The decoder. * @return The decoder.
* @throws AudioDecoderException If an error occurred creating a suitable decoder. * @throws AudioDecoderException If an error occurred creating a suitable decoder.
*/ */
protected abstract SimpleDecoder< protected abstract Decoder<
DecoderInputBuffer, ? extends SimpleOutputBuffer, ? extends AudioDecoderException> DecoderInputBuffer, ? extends SimpleOutputBuffer, ? extends AudioDecoderException>
createDecoder(Format format, @Nullable ExoMediaCrypto mediaCrypto) createDecoder(Format format, @Nullable ExoMediaCrypto mediaCrypto)
throws AudioDecoderException; throws AudioDecoderException;
@ -689,14 +688,14 @@ public abstract class SimpleDecoderAudioRenderer extends BaseRenderer implements
@Override @Override
public void onAudioSessionId(int audioSessionId) { public void onAudioSessionId(int audioSessionId) {
eventDispatcher.audioSessionId(audioSessionId); eventDispatcher.audioSessionId(audioSessionId);
SimpleDecoderAudioRenderer.this.onAudioSessionId(audioSessionId); DecoderAudioRenderer.this.onAudioSessionId(audioSessionId);
} }
@Override @Override
public void onPositionDiscontinuity() { public void onPositionDiscontinuity() {
onAudioTrackPositionDiscontinuity(); onAudioTrackPositionDiscontinuity();
// We are out of sync so allow currentPositionUs to jump backwards. // We are out of sync so allow currentPositionUs to jump backwards.
SimpleDecoderAudioRenderer.this.allowPositionDiscontinuity = true; DecoderAudioRenderer.this.allowPositionDiscontinuity = true;
} }
@Override @Override

View File

@ -20,6 +20,17 @@ package com.google.android.exoplayer2.decoder;
*/ */
public abstract class OutputBuffer extends Buffer { public abstract class OutputBuffer extends Buffer {
/** Buffer owner. */
public interface Owner<S extends OutputBuffer> {
/**
* Releases the buffer.
*
* @param outputBuffer Output buffer.
*/
void releaseOutputBuffer(S outputBuffer);
}
/** /**
* The presentation timestamp for the buffer, in microseconds. * The presentation timestamp for the buffer, in microseconds.
*/ */
@ -34,5 +45,4 @@ public abstract class OutputBuffer extends Buffer {
* Releases the output buffer for reuse. Must be called when the buffer is no longer needed. * Releases the output buffer for reuse. Must be called when the buffer is no longer needed.
*/ */
public abstract void release(); public abstract void release();
} }

View File

@ -21,7 +21,10 @@ import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Assertions;
import java.util.ArrayDeque; import java.util.ArrayDeque;
/** Base class for {@link Decoder}s that use their own decode thread. */ /**
* Base class for {@link Decoder}s that use their own decode thread and decode each input buffer
* immediately into a corresponding output buffer.
*/
@SuppressWarnings("UngroupedOverloads") @SuppressWarnings("UngroupedOverloads")
public abstract class SimpleDecoder< public abstract class SimpleDecoder<
I extends DecoderInputBuffer, O extends OutputBuffer, E extends Exception> I extends DecoderInputBuffer, O extends OutputBuffer, E extends Exception>

View File

@ -24,11 +24,11 @@ import java.nio.ByteOrder;
*/ */
public class SimpleOutputBuffer extends OutputBuffer { public class SimpleOutputBuffer extends OutputBuffer {
private final SimpleDecoder<?, SimpleOutputBuffer, ?> owner; private final Owner<SimpleOutputBuffer> owner;
@Nullable public ByteBuffer data; @Nullable public ByteBuffer data;
public SimpleOutputBuffer(SimpleDecoder<?, SimpleOutputBuffer, ?> owner) { public SimpleOutputBuffer(Owner<SimpleOutputBuffer> owner) {
this.owner = owner; this.owner = owner;
} }

View File

@ -55,7 +55,7 @@ public abstract class SimpleSubtitleDecoder extends
@Override @Override
protected final SubtitleOutputBuffer createOutputBuffer() { protected final SubtitleOutputBuffer createOutputBuffer() {
return new SimpleSubtitleOutputBuffer(this); return new SimpleSubtitleOutputBuffer(this::releaseOutputBuffer);
} }
@Override @Override
@ -63,11 +63,6 @@ public abstract class SimpleSubtitleDecoder extends
return new SubtitleDecoderException("Unexpected decode error", error); return new SubtitleDecoderException("Unexpected decode error", error);
} }
@Override
protected final void releaseOutputBuffer(SubtitleOutputBuffer buffer) {
super.releaseOutputBuffer(buffer);
}
@SuppressWarnings("ByteBufferBackingArray") @SuppressWarnings("ByteBufferBackingArray")
@Override @Override
@Nullable @Nullable

View File

@ -20,12 +20,10 @@ package com.google.android.exoplayer2.text;
*/ */
/* package */ final class SimpleSubtitleOutputBuffer extends SubtitleOutputBuffer { /* package */ final class SimpleSubtitleOutputBuffer extends SubtitleOutputBuffer {
private final SimpleSubtitleDecoder owner; private final Owner<SubtitleOutputBuffer> owner;
/** /** @param owner The decoder that owns this buffer. */
* @param owner The decoder that owns this buffer. public SimpleSubtitleOutputBuffer(Owner<SubtitleOutputBuffer> owner) {
*/
public SimpleSubtitleOutputBuffer(SimpleSubtitleDecoder owner) {
super(); super();
this.owner = owner; this.owner = owner;
} }

View File

@ -65,9 +65,6 @@ public abstract class SubtitleOutputBuffer extends OutputBuffer implements Subti
return Assertions.checkNotNull(subtitle).getCues(timeUs - subsampleOffsetUs); return Assertions.checkNotNull(subtitle).getCues(timeUs - subsampleOffsetUs);
} }
@Override
public abstract void release();
@Override @Override
public void clear() { public void clear() {
super.clear(); super.clear();

View File

@ -44,6 +44,7 @@ import java.util.PriorityQueue;
private long playbackPositionUs; private long playbackPositionUs;
private long queuedInputBufferCount; private long queuedInputBufferCount;
@SuppressWarnings("nullness:methodref.receiver.bound.invalid")
public CeaDecoder() { public CeaDecoder() {
availableInputBuffers = new ArrayDeque<>(); availableInputBuffers = new ArrayDeque<>();
for (int i = 0; i < NUM_INPUT_BUFFERS; i++) { for (int i = 0; i < NUM_INPUT_BUFFERS; i++) {
@ -51,7 +52,7 @@ import java.util.PriorityQueue;
} }
availableOutputBuffers = new ArrayDeque<>(); availableOutputBuffers = new ArrayDeque<>();
for (int i = 0; i < NUM_OUTPUT_BUFFERS; i++) { for (int i = 0; i < NUM_OUTPUT_BUFFERS; i++) {
availableOutputBuffers.add(new CeaOutputBuffer()); availableOutputBuffers.add(new CeaOutputBuffer(this::releaseOutputBuffer));
} }
queuedInputBuffers = new PriorityQueue<>(); queuedInputBuffers = new PriorityQueue<>();
} }
@ -199,11 +200,17 @@ import java.util.PriorityQueue;
} }
} }
private final class CeaOutputBuffer extends SubtitleOutputBuffer { private static final class CeaOutputBuffer extends SubtitleOutputBuffer {
private Owner<CeaOutputBuffer> owner;
public CeaOutputBuffer(Owner<CeaOutputBuffer> owner) {
this.owner = owner;
}
@Override @Override
public final void release() { public final void release() {
releaseOutputBuffer(this); owner.releaseOutputBuffer(this);
} }
} }
} }

View File

@ -26,9 +26,9 @@ import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlaybackException; import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.FormatHolder; import com.google.android.exoplayer2.FormatHolder;
import com.google.android.exoplayer2.decoder.Decoder;
import com.google.android.exoplayer2.decoder.DecoderCounters; import com.google.android.exoplayer2.decoder.DecoderCounters;
import com.google.android.exoplayer2.decoder.DecoderInputBuffer; import com.google.android.exoplayer2.decoder.DecoderInputBuffer;
import com.google.android.exoplayer2.decoder.SimpleDecoder;
import com.google.android.exoplayer2.drm.DrmSession; import com.google.android.exoplayer2.drm.DrmSession;
import com.google.android.exoplayer2.drm.DrmSession.DrmSessionException; import com.google.android.exoplayer2.drm.DrmSession.DrmSessionException;
import com.google.android.exoplayer2.drm.ExoMediaCrypto; import com.google.android.exoplayer2.drm.ExoMediaCrypto;
@ -41,8 +41,8 @@ import java.lang.annotation.Documented;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
/** Decodes and renders video using a {@link SimpleDecoder}. */ /** Decodes and renders video using a {@link Decoder}. */
public abstract class SimpleDecoderVideoRenderer extends BaseRenderer { public abstract class DecoderVideoRenderer extends BaseRenderer {
/** Decoder reinitialization states. */ /** Decoder reinitialization states. */
@Documented @Documented
@ -76,7 +76,7 @@ public abstract class SimpleDecoderVideoRenderer extends BaseRenderer {
private Format inputFormat; private Format inputFormat;
private Format outputFormat; private Format outputFormat;
private SimpleDecoder< private Decoder<
VideoDecoderInputBuffer, VideoDecoderInputBuffer,
? extends VideoDecoderOutputBuffer, ? extends VideoDecoderOutputBuffer,
? extends VideoDecoderException> ? extends VideoDecoderException>
@ -125,7 +125,7 @@ public abstract class SimpleDecoderVideoRenderer extends BaseRenderer {
* @param maxDroppedFramesToNotify The maximum number of frames that can be dropped between * @param maxDroppedFramesToNotify The maximum number of frames that can be dropped between
* invocations of {@link VideoRendererEventListener#onDroppedFrames(int, long)}. * invocations of {@link VideoRendererEventListener#onDroppedFrames(int, long)}.
*/ */
protected SimpleDecoderVideoRenderer( protected DecoderVideoRenderer(
long allowedJoiningTimeMs, long allowedJoiningTimeMs,
@Nullable Handler eventHandler, @Nullable Handler eventHandler,
@Nullable VideoRendererEventListener eventListener, @Nullable VideoRendererEventListener eventListener,
@ -490,7 +490,7 @@ public abstract class SimpleDecoderVideoRenderer extends BaseRenderer {
* @return The decoder. * @return The decoder.
* @throws VideoDecoderException If an error occurred creating a suitable decoder. * @throws VideoDecoderException If an error occurred creating a suitable decoder.
*/ */
protected abstract SimpleDecoder< protected abstract Decoder<
VideoDecoderInputBuffer, VideoDecoderInputBuffer,
? extends VideoDecoderOutputBuffer, ? extends VideoDecoderOutputBuffer,
? extends VideoDecoderException> ? extends VideoDecoderException>

View File

@ -23,17 +23,6 @@ import java.nio.ByteBuffer;
/** Video decoder output buffer containing video frame data. */ /** Video decoder output buffer containing video frame data. */
public class VideoDecoderOutputBuffer extends OutputBuffer { public class VideoDecoderOutputBuffer extends OutputBuffer {
/** Buffer owner. */
public interface Owner {
/**
* Releases the buffer.
*
* @param outputBuffer Output buffer.
*/
void releaseOutputBuffer(VideoDecoderOutputBuffer outputBuffer);
}
// LINT.IfChange // LINT.IfChange
public static final int COLORSPACE_UNKNOWN = 0; public static final int COLORSPACE_UNKNOWN = 0;
public static final int COLORSPACE_BT601 = 1; public static final int COLORSPACE_BT601 = 1;
@ -68,14 +57,14 @@ public class VideoDecoderOutputBuffer extends OutputBuffer {
*/ */
@Nullable public ByteBuffer supplementalData; @Nullable public ByteBuffer supplementalData;
private final Owner owner; private final Owner<VideoDecoderOutputBuffer> owner;
/** /**
* Creates VideoDecoderOutputBuffer. * Creates VideoDecoderOutputBuffer.
* *
* @param owner Buffer owner. * @param owner Buffer owner.
*/ */
public VideoDecoderOutputBuffer(Owner owner) { public VideoDecoderOutputBuffer(Owner<VideoDecoderOutputBuffer> owner) {
this.owner = owner; this.owner = owner;
} }

View File

@ -42,21 +42,21 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config; import org.robolectric.annotation.Config;
/** Unit test for {@link SimpleDecoderAudioRenderer}. */ /** Unit test for {@link DecoderAudioRenderer}. */
@RunWith(AndroidJUnit4.class) @RunWith(AndroidJUnit4.class)
public class SimpleDecoderAudioRendererTest { public class DecoderAudioRendererTest {
private static final Format FORMAT = private static final Format FORMAT =
new Format.Builder().setSampleMimeType(MimeTypes.AUDIO_RAW).build(); new Format.Builder().setSampleMimeType(MimeTypes.AUDIO_RAW).build();
@Mock private AudioSink mockAudioSink; @Mock private AudioSink mockAudioSink;
private SimpleDecoderAudioRenderer audioRenderer; private DecoderAudioRenderer audioRenderer;
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
audioRenderer = audioRenderer =
new SimpleDecoderAudioRenderer(null, null, mockAudioSink) { new DecoderAudioRenderer(null, null, mockAudioSink) {
@Override @Override
@FormatSupport @FormatSupport
protected int supportsFormatInternal(Format format) { protected int supportsFormatInternal(Format format) {
@ -132,7 +132,7 @@ public class SimpleDecoderAudioRendererTest {
@Override @Override
protected SimpleOutputBuffer createOutputBuffer() { protected SimpleOutputBuffer createOutputBuffer() {
return new SimpleOutputBuffer(this); return new SimpleOutputBuffer(this::releaseOutputBuffer);
} }
@Override @Override

View File

@ -47,10 +47,10 @@ import org.mockito.junit.MockitoRule;
import org.robolectric.annotation.LooperMode; import org.robolectric.annotation.LooperMode;
import org.robolectric.shadows.ShadowLooper; import org.robolectric.shadows.ShadowLooper;
/** Unit test for {@link SimpleDecoderVideoRenderer}. */ /** Unit test for {@link DecoderVideoRenderer}. */
@LooperMode(LooperMode.Mode.PAUSED) @LooperMode(LooperMode.Mode.PAUSED)
@RunWith(AndroidJUnit4.class) @RunWith(AndroidJUnit4.class)
public final class SimpleDecoderVideoRendererTest { public final class DecoderVideoRendererTest {
@Rule public final MockitoRule mockito = MockitoJUnit.rule(); @Rule public final MockitoRule mockito = MockitoJUnit.rule();
private static final Format H264_FORMAT = private static final Format H264_FORMAT =
@ -60,13 +60,13 @@ public final class SimpleDecoderVideoRendererTest {
.setHeight(1080) .setHeight(1080)
.build(); .build();
private SimpleDecoderVideoRenderer renderer; private DecoderVideoRenderer renderer;
@Mock private VideoRendererEventListener eventListener; @Mock private VideoRendererEventListener eventListener;
@Before @Before
public void setUp() { public void setUp() {
renderer = renderer =
new SimpleDecoderVideoRenderer( new DecoderVideoRenderer(
/* allowedJoiningTimeMs= */ 0, /* allowedJoiningTimeMs= */ 0,
new Handler(), new Handler(),
eventListener, eventListener,