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:
parent
a3a3b5be0b
commit
cbe99ec475
@ -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).
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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.
|
||||||
*
|
*
|
||||||
|
@ -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
|
@ -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();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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>
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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>
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
@ -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,
|
Loading…
x
Reference in New Issue
Block a user