Commit ed1de000 by ibaker Committed by Oliver Woodman

Unwrap all nested IntDef values

This seems to work with R8 but interact badly with ProGuard.

issue:#6771
PiperOrigin-RevId: 286215262
parent 8b0f5b0a
...@@ -102,7 +102,7 @@ public class DefaultRenderersFactory implements RenderersFactory { ...@@ -102,7 +102,7 @@ public class DefaultRenderersFactory implements RenderersFactory {
extensionRendererMode = EXTENSION_RENDERER_MODE_OFF; extensionRendererMode = EXTENSION_RENDERER_MODE_OFF;
allowedVideoJoiningTimeMs = DEFAULT_ALLOWED_VIDEO_JOINING_TIME_MS; allowedVideoJoiningTimeMs = DEFAULT_ALLOWED_VIDEO_JOINING_TIME_MS;
mediaCodecSelector = MediaCodecSelector.DEFAULT; mediaCodecSelector = MediaCodecSelector.DEFAULT;
mediaCodecOperationMode = MediaCodecRenderer.MediaCodecOperationMode.SYNCHRONOUS; mediaCodecOperationMode = MediaCodecRenderer.OPERATION_MODE_SYNCHRONOUS;
} }
/** /**
......
...@@ -41,12 +41,12 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -41,12 +41,12 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
/* package */ final class DedicatedThreadAsyncMediaCodecAdapter extends MediaCodec.Callback /* package */ final class DedicatedThreadAsyncMediaCodecAdapter extends MediaCodec.Callback
implements MediaCodecAdapter { implements MediaCodecAdapter {
@IntDef({State.CREATED, State.STARTED, State.SHUT_DOWN}) @IntDef({STATE_CREATED, STATE_STARTED, STATE_SHUT_DOWN})
private @interface State { private @interface State {}
int CREATED = 0;
int STARTED = 1; private static final int STATE_CREATED = 0;
int SHUT_DOWN = 2; private static final int STATE_STARTED = 1;
} private static final int STATE_SHUT_DOWN = 2;
private final MediaCodecAsyncCallback mediaCodecAsyncCallback; private final MediaCodecAsyncCallback mediaCodecAsyncCallback;
private final MediaCodec codec; private final MediaCodec codec;
...@@ -76,7 +76,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -76,7 +76,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
mediaCodecAsyncCallback = new MediaCodecAsyncCallback(); mediaCodecAsyncCallback = new MediaCodecAsyncCallback();
this.codec = codec; this.codec = codec;
this.handlerThread = handlerThread; this.handlerThread = handlerThread;
state = State.CREATED; state = STATE_CREATED;
onCodecStart = codec::start; onCodecStart = codec::start;
} }
...@@ -90,17 +90,17 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -90,17 +90,17 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
* @throws IllegalStateException If this method has been called already. * @throws IllegalStateException If this method has been called already.
*/ */
public synchronized void start() { public synchronized void start() {
Assertions.checkState(state == State.CREATED); Assertions.checkState(state == STATE_CREATED);
handlerThread.start(); handlerThread.start();
handler = new Handler(handlerThread.getLooper()); handler = new Handler(handlerThread.getLooper());
codec.setCallback(this, handler); codec.setCallback(this, handler);
state = State.STARTED; state = STATE_STARTED;
} }
@Override @Override
public synchronized int dequeueInputBufferIndex() { public synchronized int dequeueInputBufferIndex() {
Assertions.checkState(state == State.STARTED); Assertions.checkState(state == STATE_STARTED);
if (isFlushing()) { if (isFlushing()) {
return MediaCodec.INFO_TRY_AGAIN_LATER; return MediaCodec.INFO_TRY_AGAIN_LATER;
...@@ -112,7 +112,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -112,7 +112,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
@Override @Override
public synchronized int dequeueOutputBufferIndex(MediaCodec.BufferInfo bufferInfo) { public synchronized int dequeueOutputBufferIndex(MediaCodec.BufferInfo bufferInfo) {
Assertions.checkState(state == State.STARTED); Assertions.checkState(state == STATE_STARTED);
if (isFlushing()) { if (isFlushing()) {
return MediaCodec.INFO_TRY_AGAIN_LATER; return MediaCodec.INFO_TRY_AGAIN_LATER;
...@@ -124,14 +124,14 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -124,14 +124,14 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
@Override @Override
public synchronized MediaFormat getOutputFormat() { public synchronized MediaFormat getOutputFormat() {
Assertions.checkState(state == State.STARTED); Assertions.checkState(state == STATE_STARTED);
return mediaCodecAsyncCallback.getOutputFormat(); return mediaCodecAsyncCallback.getOutputFormat();
} }
@Override @Override
public synchronized void flush() { public synchronized void flush() {
Assertions.checkState(state == State.STARTED); Assertions.checkState(state == STATE_STARTED);
codec.flush(); codec.flush();
++pendingFlushCount; ++pendingFlushCount;
...@@ -140,12 +140,12 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -140,12 +140,12 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
@Override @Override
public synchronized void shutdown() { public synchronized void shutdown() {
if (state == State.STARTED) { if (state == STATE_STARTED) {
handlerThread.quit(); handlerThread.quit();
mediaCodecAsyncCallback.flush(); mediaCodecAsyncCallback.flush();
} }
state = State.SHUT_DOWN; state = STATE_SHUT_DOWN;
} }
@Override @Override
...@@ -182,7 +182,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -182,7 +182,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
} }
private synchronized void onFlushCompleted() { private synchronized void onFlushCompleted() {
if (state != State.STARTED) { if (state != STATE_STARTED) {
// The adapter has been shutdown. // The adapter has been shutdown.
return; return;
} }
......
...@@ -61,8 +61,46 @@ import java.util.List; ...@@ -61,8 +61,46 @@ import java.util.List;
public abstract class MediaCodecRenderer extends BaseRenderer { public abstract class MediaCodecRenderer extends BaseRenderer {
/** /**
* Thrown when a failure occurs instantiating a decoder. * The modes to operate the {@link MediaCodec}.
*
* <p>Allowed values:
*
* <ul>
* <li>{@link #OPERATION_MODE_SYNCHRONOUS}
* <li>{@link #OPERATION_MODE_ASYNCHRONOUS_PLAYBACK_THREAD}
* <li>{@link #OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD}
* <li>{@link #OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD_MULTI_LOCK}
* </ul>
*/
@Documented
@Retention(RetentionPolicy.SOURCE)
@IntDef({
OPERATION_MODE_SYNCHRONOUS,
OPERATION_MODE_ASYNCHRONOUS_PLAYBACK_THREAD,
OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD,
OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD_MULTI_LOCK
})
public @interface MediaCodecOperationMode {}
/** Operates the {@link MediaCodec} in synchronous mode. */
public static final int OPERATION_MODE_SYNCHRONOUS = 0;
/**
* Operates the {@link MediaCodec} in asynchronous mode and routes {@link MediaCodec.Callback}
* callbacks to the playback Thread.
*/
public static final int OPERATION_MODE_ASYNCHRONOUS_PLAYBACK_THREAD = 1;
/**
* Operates the {@link MediaCodec} in asynchronous mode and routes {@link MediaCodec.Callback}
* callbacks to a dedicated Thread.
*/ */
public static final int OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD = 2;
/**
* Operates the {@link MediaCodec} in asynchronous mode and routes {@link MediaCodec.Callback}
* callbacks to a dedicated Thread. Uses granular locking for input and output buffers.
*/
public static final int OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD_MULTI_LOCK = 3;
/** Thrown when a failure occurs instantiating a decoder. */
public static class DecoderInitializationException extends Exception { public static class DecoderInitializationException extends Exception {
private static final int CUSTOM_ERROR_CODE_BASE = -50000; private static final int CUSTOM_ERROR_CODE_BASE = -50000;
...@@ -191,36 +229,6 @@ public abstract class MediaCodecRenderer extends BaseRenderer { ...@@ -191,36 +229,6 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
} }
} }
/** The modes to operate the {@link MediaCodec}. */
@Documented
@Retention(RetentionPolicy.SOURCE)
@IntDef({
MediaCodecOperationMode.SYNCHRONOUS,
MediaCodecOperationMode.ASYNCHRONOUS_PLAYBACK_THREAD,
MediaCodecOperationMode.ASYNCHRONOUS_DEDICATED_THREAD,
MediaCodecOperationMode.ASYNCHRONOUS_DEDICATED_THREAD_MULTI_LOCK
})
public @interface MediaCodecOperationMode {
/** Operates the {@link MediaCodec} in synchronous mode. */
int SYNCHRONOUS = 0;
/**
* Operates the {@link MediaCodec} in asynchronous mode and routes {@link MediaCodec.Callback}
* callbacks to the playback Thread.
*/
int ASYNCHRONOUS_PLAYBACK_THREAD = 1;
/**
* Operates the {@link MediaCodec} in asynchronous mode and routes {@link MediaCodec.Callback}
* callbacks to a dedicated Thread.
*/
int ASYNCHRONOUS_DEDICATED_THREAD = 2;
/**
* Operates the {@link MediaCodec} in asynchronous mode and routes {@link MediaCodec.Callback}
* callbacks to a dedicated Thread. Uses granular locking for input and output buffers.
*/
int ASYNCHRONOUS_DEDICATED_THREAD_MULTI_LOCK = 3;
}
/** Indicates no codec operating rate should be set. */ /** Indicates no codec operating rate should be set. */
protected static final float CODEC_OPERATING_RATE_UNSET = -1; protected static final float CODEC_OPERATING_RATE_UNSET = -1;
...@@ -447,7 +455,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer { ...@@ -447,7 +455,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
outputBufferInfo = new MediaCodec.BufferInfo(); outputBufferInfo = new MediaCodec.BufferInfo();
rendererOperatingRate = 1f; rendererOperatingRate = 1f;
renderTimeLimitMs = C.TIME_UNSET; renderTimeLimitMs = C.TIME_UNSET;
mediaCodecOperationMode = MediaCodecOperationMode.SYNCHRONOUS; mediaCodecOperationMode = OPERATION_MODE_SYNCHRONOUS;
resetCodecStateForRelease(); resetCodecStateForRelease();
} }
...@@ -473,23 +481,24 @@ public abstract class MediaCodecRenderer extends BaseRenderer { ...@@ -473,23 +481,24 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
* *
* @param mode The mode of the MediaCodec. The supported modes are: * @param mode The mode of the MediaCodec. The supported modes are:
* <ul> * <ul>
* <li>{@link MediaCodecOperationMode#SYNCHRONOUS}: The {@link MediaCodec} will operate in * <li>{@link MediaCodecRenderer#OPERATION_MODE_SYNCHRONOUS}: The {@link MediaCodec} will
* synchronous mode. * operate in synchronous mode.
* <li>{@link MediaCodecOperationMode#ASYNCHRONOUS_PLAYBACK_THREAD}: The {@link MediaCodec} * <li>{@link MediaCodecRenderer#OPERATION_MODE_ASYNCHRONOUS_PLAYBACK_THREAD}: The {@link
* will operate in asynchronous mode and {@link MediaCodec.Callback} callbacks will be * MediaCodec} will operate in asynchronous mode and {@link MediaCodec.Callback}
* routed to the Playback Thread. This mode requires API level &ge; 21; if the API level * callbacks will be routed to the Playback Thread. This mode requires API level &ge;
* is &le; 20, the operation mode will be set to {@link * 21; if the API level is &le; 20, the operation mode will be set to {@link
* MediaCodecOperationMode#SYNCHRONOUS}. * MediaCodecRenderer#OPERATION_MODE_SYNCHRONOUS}.
* <li>{@link MediaCodecOperationMode#ASYNCHRONOUS_DEDICATED_THREAD}: The {@link MediaCodec} * <li>{@link MediaCodecRenderer#OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD}: The {@link
* will operate in asynchronous mode and {@link MediaCodec.Callback} callbacks will be * MediaCodec} will operate in asynchronous mode and {@link MediaCodec.Callback}
* routed to a dedicated Thread. This mode requires API level &ge; 23; if the API level * callbacks will be routed to a dedicated Thread. This mode requires API level &ge; 23;
* is &le; 22, the operation mode will be set to {@link * if the API level is &le; 22, the operation mode will be set to {@link
* MediaCodecOperationMode#SYNCHRONOUS}. * MediaCodecRenderer#OPERATION_MODE_SYNCHRONOUS}.
* <li>{@link MediaCodecOperationMode#ASYNCHRONOUS_DEDICATED_THREAD_MULTI_LOCK}: Same as * <li>{@link MediaCodecRenderer#OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD_MULTI_LOCK}:
* {@link MediaCodecOperationMode#ASYNCHRONOUS_DEDICATED_THREAD} but it will internally * Same as {@link MediaCodecRenderer#OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD} but
* use a finer grained locking mechanism for increased performance. * it will internally use a finer grained locking mechanism for increased performance.
* </ul> * </ul>
* By default, the operation mode is set to {@link MediaCodecOperationMode#SYNCHRONOUS}. * By default, the operation mode is set to {@link
* MediaCodecRenderer#OPERATION_MODE_SYNCHRONOUS}.
*/ */
public void experimental_setMediaCodecOperationMode(@MediaCodecOperationMode int mode) { public void experimental_setMediaCodecOperationMode(@MediaCodecOperationMode int mode) {
mediaCodecOperationMode = mode; mediaCodecOperationMode = mode;
...@@ -980,15 +989,14 @@ public abstract class MediaCodecRenderer extends BaseRenderer { ...@@ -980,15 +989,14 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
codecInitializingTimestamp = SystemClock.elapsedRealtime(); codecInitializingTimestamp = SystemClock.elapsedRealtime();
TraceUtil.beginSection("createCodec:" + codecName); TraceUtil.beginSection("createCodec:" + codecName);
codec = MediaCodec.createByCodecName(codecName); codec = MediaCodec.createByCodecName(codecName);
if (mediaCodecOperationMode == MediaCodecOperationMode.ASYNCHRONOUS_PLAYBACK_THREAD if (mediaCodecOperationMode == OPERATION_MODE_ASYNCHRONOUS_PLAYBACK_THREAD
&& Util.SDK_INT >= 21) { && Util.SDK_INT >= 21) {
codecAdapter = new AsynchronousMediaCodecAdapter(codec); codecAdapter = new AsynchronousMediaCodecAdapter(codec);
} else if (mediaCodecOperationMode == MediaCodecOperationMode.ASYNCHRONOUS_DEDICATED_THREAD } else if (mediaCodecOperationMode == OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD
&& Util.SDK_INT >= 23) { && Util.SDK_INT >= 23) {
codecAdapter = new DedicatedThreadAsyncMediaCodecAdapter(codec, getTrackType()); codecAdapter = new DedicatedThreadAsyncMediaCodecAdapter(codec, getTrackType());
((DedicatedThreadAsyncMediaCodecAdapter) codecAdapter).start(); ((DedicatedThreadAsyncMediaCodecAdapter) codecAdapter).start();
} else if (mediaCodecOperationMode } else if (mediaCodecOperationMode == OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD_MULTI_LOCK
== MediaCodecOperationMode.ASYNCHRONOUS_DEDICATED_THREAD_MULTI_LOCK
&& Util.SDK_INT >= 23) { && Util.SDK_INT >= 23) {
codecAdapter = new MultiLockAsynchMediaCodecAdapter(codec, getTrackType()); codecAdapter = new MultiLockAsynchMediaCodecAdapter(codec, getTrackType());
((MultiLockAsynchMediaCodecAdapter) codecAdapter).start(); ((MultiLockAsynchMediaCodecAdapter) codecAdapter).start();
......
...@@ -54,12 +54,12 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -54,12 +54,12 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
/* package */ final class MultiLockAsynchMediaCodecAdapter extends MediaCodec.Callback /* package */ final class MultiLockAsynchMediaCodecAdapter extends MediaCodec.Callback
implements MediaCodecAdapter { implements MediaCodecAdapter {
@IntDef({State.CREATED, State.STARTED, State.SHUT_DOWN}) @IntDef({STATE_CREATED, STATE_STARTED, STATE_SHUT_DOWN})
private @interface State { private @interface State {}
int CREATED = 0;
int STARTED = 1; private static final int STATE_CREATED = 0;
int SHUT_DOWN = 2; private static final int STATE_STARTED = 1;
} private static final int STATE_SHUT_DOWN = 2;
private final MediaCodec codec; private final MediaCodec codec;
private final Object inputBufferLock; private final Object inputBufferLock;
...@@ -112,7 +112,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -112,7 +112,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
bufferInfos = new ArrayDeque<>(); bufferInfos = new ArrayDeque<>();
formats = new ArrayDeque<>(); formats = new ArrayDeque<>();
codecException = null; codecException = null;
state = State.CREATED; state = STATE_CREATED;
this.handlerThread = handlerThread; this.handlerThread = handlerThread;
onCodecStart = codec::start; onCodecStart = codec::start;
} }
...@@ -128,19 +128,19 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -128,19 +128,19 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
*/ */
public void start() { public void start() {
synchronized (objectStateLock) { synchronized (objectStateLock) {
Assertions.checkState(state == State.CREATED); Assertions.checkState(state == STATE_CREATED);
handlerThread.start(); handlerThread.start();
handler = new Handler(handlerThread.getLooper()); handler = new Handler(handlerThread.getLooper());
codec.setCallback(this, handler); codec.setCallback(this, handler);
state = State.STARTED; state = STATE_STARTED;
} }
} }
@Override @Override
public int dequeueInputBufferIndex() { public int dequeueInputBufferIndex() {
synchronized (objectStateLock) { synchronized (objectStateLock) {
Assertions.checkState(state == State.STARTED); Assertions.checkState(state == STATE_STARTED);
if (isFlushing()) { if (isFlushing()) {
return MediaCodec.INFO_TRY_AGAIN_LATER; return MediaCodec.INFO_TRY_AGAIN_LATER;
...@@ -154,7 +154,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -154,7 +154,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
@Override @Override
public int dequeueOutputBufferIndex(MediaCodec.BufferInfo bufferInfo) { public int dequeueOutputBufferIndex(MediaCodec.BufferInfo bufferInfo) {
synchronized (objectStateLock) { synchronized (objectStateLock) {
Assertions.checkState(state == State.STARTED); Assertions.checkState(state == STATE_STARTED);
if (isFlushing()) { if (isFlushing()) {
return MediaCodec.INFO_TRY_AGAIN_LATER; return MediaCodec.INFO_TRY_AGAIN_LATER;
...@@ -168,7 +168,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -168,7 +168,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
@Override @Override
public MediaFormat getOutputFormat() { public MediaFormat getOutputFormat() {
synchronized (objectStateLock) { synchronized (objectStateLock) {
Assertions.checkState(state == State.STARTED); Assertions.checkState(state == STATE_STARTED);
if (currentFormat == null) { if (currentFormat == null) {
throw new IllegalStateException(); throw new IllegalStateException();
...@@ -181,7 +181,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -181,7 +181,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
@Override @Override
public void flush() { public void flush() {
synchronized (objectStateLock) { synchronized (objectStateLock) {
Assertions.checkState(state == State.STARTED); Assertions.checkState(state == STATE_STARTED);
codec.flush(); codec.flush();
pendingFlush++; pendingFlush++;
...@@ -192,10 +192,10 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -192,10 +192,10 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
@Override @Override
public void shutdown() { public void shutdown() {
synchronized (objectStateLock) { synchronized (objectStateLock) {
if (state == State.STARTED) { if (state == STATE_STARTED) {
handlerThread.quit(); handlerThread.quit();
} }
state = State.SHUT_DOWN; state = STATE_SHUT_DOWN;
} }
} }
...@@ -289,7 +289,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -289,7 +289,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
private void onFlushComplete() { private void onFlushComplete() {
synchronized (objectStateLock) { synchronized (objectStateLock) {
if (state == State.SHUT_DOWN) { if (state == STATE_SHUT_DOWN) {
return; return;
} }
......
...@@ -300,12 +300,12 @@ public final class SsaDecoder extends SimpleSubtitleDecoder { ...@@ -300,12 +300,12 @@ public final class SsaDecoder extends SimpleSubtitleDecoder {
float screenWidth, float screenWidth,
float screenHeight) { float screenHeight) {
@SsaStyle.SsaAlignment int alignment; @SsaStyle.SsaAlignment int alignment;
if (styleOverrides.alignment != SsaStyle.SsaAlignment.UNKNOWN) { if (styleOverrides.alignment != SsaStyle.SSA_ALIGNMENT_UNKNOWN) {
alignment = styleOverrides.alignment; alignment = styleOverrides.alignment;
} else if (style != null) { } else if (style != null) {
alignment = style.alignment; alignment = style.alignment;
} else { } else {
alignment = SsaStyle.SsaAlignment.UNKNOWN; alignment = SsaStyle.SSA_ALIGNMENT_UNKNOWN;
} }
@Cue.AnchorType int positionAnchor = toPositionAnchor(alignment); @Cue.AnchorType int positionAnchor = toPositionAnchor(alignment);
@Cue.AnchorType int lineAnchor = toLineAnchor(alignment); @Cue.AnchorType int lineAnchor = toLineAnchor(alignment);
...@@ -337,19 +337,19 @@ public final class SsaDecoder extends SimpleSubtitleDecoder { ...@@ -337,19 +337,19 @@ public final class SsaDecoder extends SimpleSubtitleDecoder {
@Nullable @Nullable
private static Layout.Alignment toTextAlignment(@SsaStyle.SsaAlignment int alignment) { private static Layout.Alignment toTextAlignment(@SsaStyle.SsaAlignment int alignment) {
switch (alignment) { switch (alignment) {
case SsaStyle.SsaAlignment.BOTTOM_LEFT: case SsaStyle.SSA_ALIGNMENT_BOTTOM_LEFT:
case SsaStyle.SsaAlignment.MIDDLE_LEFT: case SsaStyle.SSA_ALIGNMENT_MIDDLE_LEFT:
case SsaStyle.SsaAlignment.TOP_LEFT: case SsaStyle.SSA_ALIGNMENT_TOP_LEFT:
return Layout.Alignment.ALIGN_NORMAL; return Layout.Alignment.ALIGN_NORMAL;
case SsaStyle.SsaAlignment.BOTTOM_CENTER: case SsaStyle.SSA_ALIGNMENT_BOTTOM_CENTER:
case SsaStyle.SsaAlignment.MIDDLE_CENTER: case SsaStyle.SSA_ALIGNMENT_MIDDLE_CENTER:
case SsaStyle.SsaAlignment.TOP_CENTER: case SsaStyle.SSA_ALIGNMENT_TOP_CENTER:
return Layout.Alignment.ALIGN_CENTER; return Layout.Alignment.ALIGN_CENTER;
case SsaStyle.SsaAlignment.BOTTOM_RIGHT: case SsaStyle.SSA_ALIGNMENT_BOTTOM_RIGHT:
case SsaStyle.SsaAlignment.MIDDLE_RIGHT: case SsaStyle.SSA_ALIGNMENT_MIDDLE_RIGHT:
case SsaStyle.SsaAlignment.TOP_RIGHT: case SsaStyle.SSA_ALIGNMENT_TOP_RIGHT:
return Layout.Alignment.ALIGN_OPPOSITE; return Layout.Alignment.ALIGN_OPPOSITE;
case SsaStyle.SsaAlignment.UNKNOWN: case SsaStyle.SSA_ALIGNMENT_UNKNOWN:
return null; return null;
default: default:
Log.w(TAG, "Unknown alignment: " + alignment); Log.w(TAG, "Unknown alignment: " + alignment);
...@@ -360,19 +360,19 @@ public final class SsaDecoder extends SimpleSubtitleDecoder { ...@@ -360,19 +360,19 @@ public final class SsaDecoder extends SimpleSubtitleDecoder {
@Cue.AnchorType @Cue.AnchorType
private static int toLineAnchor(@SsaStyle.SsaAlignment int alignment) { private static int toLineAnchor(@SsaStyle.SsaAlignment int alignment) {
switch (alignment) { switch (alignment) {
case SsaStyle.SsaAlignment.BOTTOM_LEFT: case SsaStyle.SSA_ALIGNMENT_BOTTOM_LEFT:
case SsaStyle.SsaAlignment.BOTTOM_CENTER: case SsaStyle.SSA_ALIGNMENT_BOTTOM_CENTER:
case SsaStyle.SsaAlignment.BOTTOM_RIGHT: case SsaStyle.SSA_ALIGNMENT_BOTTOM_RIGHT:
return Cue.ANCHOR_TYPE_END; return Cue.ANCHOR_TYPE_END;
case SsaStyle.SsaAlignment.MIDDLE_LEFT: case SsaStyle.SSA_ALIGNMENT_MIDDLE_LEFT:
case SsaStyle.SsaAlignment.MIDDLE_CENTER: case SsaStyle.SSA_ALIGNMENT_MIDDLE_CENTER:
case SsaStyle.SsaAlignment.MIDDLE_RIGHT: case SsaStyle.SSA_ALIGNMENT_MIDDLE_RIGHT:
return Cue.ANCHOR_TYPE_MIDDLE; return Cue.ANCHOR_TYPE_MIDDLE;
case SsaStyle.SsaAlignment.TOP_LEFT: case SsaStyle.SSA_ALIGNMENT_TOP_LEFT:
case SsaStyle.SsaAlignment.TOP_CENTER: case SsaStyle.SSA_ALIGNMENT_TOP_CENTER:
case SsaStyle.SsaAlignment.TOP_RIGHT: case SsaStyle.SSA_ALIGNMENT_TOP_RIGHT:
return Cue.ANCHOR_TYPE_START; return Cue.ANCHOR_TYPE_START;
case SsaStyle.SsaAlignment.UNKNOWN: case SsaStyle.SSA_ALIGNMENT_UNKNOWN:
return Cue.TYPE_UNSET; return Cue.TYPE_UNSET;
default: default:
Log.w(TAG, "Unknown alignment: " + alignment); Log.w(TAG, "Unknown alignment: " + alignment);
...@@ -383,19 +383,19 @@ public final class SsaDecoder extends SimpleSubtitleDecoder { ...@@ -383,19 +383,19 @@ public final class SsaDecoder extends SimpleSubtitleDecoder {
@Cue.AnchorType @Cue.AnchorType
private static int toPositionAnchor(@SsaStyle.SsaAlignment int alignment) { private static int toPositionAnchor(@SsaStyle.SsaAlignment int alignment) {
switch (alignment) { switch (alignment) {
case SsaStyle.SsaAlignment.BOTTOM_LEFT: case SsaStyle.SSA_ALIGNMENT_BOTTOM_LEFT:
case SsaStyle.SsaAlignment.MIDDLE_LEFT: case SsaStyle.SSA_ALIGNMENT_MIDDLE_LEFT:
case SsaStyle.SsaAlignment.TOP_LEFT: case SsaStyle.SSA_ALIGNMENT_TOP_LEFT:
return Cue.ANCHOR_TYPE_START; return Cue.ANCHOR_TYPE_START;
case SsaStyle.SsaAlignment.BOTTOM_CENTER: case SsaStyle.SSA_ALIGNMENT_BOTTOM_CENTER:
case SsaStyle.SsaAlignment.MIDDLE_CENTER: case SsaStyle.SSA_ALIGNMENT_MIDDLE_CENTER:
case SsaStyle.SsaAlignment.TOP_CENTER: case SsaStyle.SSA_ALIGNMENT_TOP_CENTER:
return Cue.ANCHOR_TYPE_MIDDLE; return Cue.ANCHOR_TYPE_MIDDLE;
case SsaStyle.SsaAlignment.BOTTOM_RIGHT: case SsaStyle.SSA_ALIGNMENT_BOTTOM_RIGHT:
case SsaStyle.SsaAlignment.MIDDLE_RIGHT: case SsaStyle.SSA_ALIGNMENT_MIDDLE_RIGHT:
case SsaStyle.SsaAlignment.TOP_RIGHT: case SsaStyle.SSA_ALIGNMENT_TOP_RIGHT:
return Cue.ANCHOR_TYPE_END; return Cue.ANCHOR_TYPE_END;
case SsaStyle.SsaAlignment.UNKNOWN: case SsaStyle.SSA_ALIGNMENT_UNKNOWN:
return Cue.TYPE_UNSET; return Cue.TYPE_UNSET;
default: default:
Log.w(TAG, "Unknown alignment: " + alignment); Log.w(TAG, "Unknown alignment: " + alignment);
......
...@@ -37,6 +37,52 @@ import java.util.regex.Pattern; ...@@ -37,6 +37,52 @@ import java.util.regex.Pattern;
private static final String TAG = "SsaStyle"; private static final String TAG = "SsaStyle";
/**
* The SSA/ASS alignments.
*
* <p>Allowed values:
*
* <ul>
* <li>{@link #SSA_ALIGNMENT_UNKNOWN}
* <li>{@link #SSA_ALIGNMENT_BOTTOM_LEFT}
* <li>{@link #SSA_ALIGNMENT_BOTTOM_CENTER}
* <li>{@link #SSA_ALIGNMENT_BOTTOM_RIGHT}
* <li>{@link #SSA_ALIGNMENT_MIDDLE_LEFT}
* <li>{@link #SSA_ALIGNMENT_MIDDLE_CENTER}
* <li>{@link #SSA_ALIGNMENT_MIDDLE_RIGHT}
* <li>{@link #SSA_ALIGNMENT_TOP_LEFT}
* <li>{@link #SSA_ALIGNMENT_TOP_CENTER}
* <li>{@link #SSA_ALIGNMENT_TOP_RIGHT}
* </ul>
*/
@IntDef({
SSA_ALIGNMENT_UNKNOWN,
SSA_ALIGNMENT_BOTTOM_LEFT,
SSA_ALIGNMENT_BOTTOM_CENTER,
SSA_ALIGNMENT_BOTTOM_RIGHT,
SSA_ALIGNMENT_MIDDLE_LEFT,
SSA_ALIGNMENT_MIDDLE_CENTER,
SSA_ALIGNMENT_MIDDLE_RIGHT,
SSA_ALIGNMENT_TOP_LEFT,
SSA_ALIGNMENT_TOP_CENTER,
SSA_ALIGNMENT_TOP_RIGHT,
})
@Documented
@Retention(SOURCE)
public @interface SsaAlignment {}
// The numbering follows the ASS (v4+) spec (i.e. the points on the number pad).
public static final int SSA_ALIGNMENT_UNKNOWN = -1;
public static final int SSA_ALIGNMENT_BOTTOM_LEFT = 1;
public static final int SSA_ALIGNMENT_BOTTOM_CENTER = 2;
public static final int SSA_ALIGNMENT_BOTTOM_RIGHT = 3;
public static final int SSA_ALIGNMENT_MIDDLE_LEFT = 4;
public static final int SSA_ALIGNMENT_MIDDLE_CENTER = 5;
public static final int SSA_ALIGNMENT_MIDDLE_RIGHT = 6;
public static final int SSA_ALIGNMENT_TOP_LEFT = 7;
public static final int SSA_ALIGNMENT_TOP_CENTER = 8;
public static final int SSA_ALIGNMENT_TOP_RIGHT = 9;
public final String name; public final String name;
@SsaAlignment public final int alignment; @SsaAlignment public final int alignment;
...@@ -77,22 +123,22 @@ import java.util.regex.Pattern; ...@@ -77,22 +123,22 @@ import java.util.regex.Pattern;
// Swallow the exception and return UNKNOWN below. // Swallow the exception and return UNKNOWN below.
} }
Log.w(TAG, "Ignoring unknown alignment: " + alignmentStr); Log.w(TAG, "Ignoring unknown alignment: " + alignmentStr);
return SsaAlignment.UNKNOWN; return SSA_ALIGNMENT_UNKNOWN;
} }
private static boolean isValidAlignment(@SsaAlignment int alignment) { private static boolean isValidAlignment(@SsaAlignment int alignment) {
switch (alignment) { switch (alignment) {
case SsaAlignment.BOTTOM_CENTER: case SSA_ALIGNMENT_BOTTOM_CENTER:
case SsaAlignment.BOTTOM_LEFT: case SSA_ALIGNMENT_BOTTOM_LEFT:
case SsaAlignment.BOTTOM_RIGHT: case SSA_ALIGNMENT_BOTTOM_RIGHT:
case SsaAlignment.MIDDLE_CENTER: case SSA_ALIGNMENT_MIDDLE_CENTER:
case SsaAlignment.MIDDLE_LEFT: case SSA_ALIGNMENT_MIDDLE_LEFT:
case SsaAlignment.MIDDLE_RIGHT: case SSA_ALIGNMENT_MIDDLE_RIGHT:
case SsaAlignment.TOP_CENTER: case SSA_ALIGNMENT_TOP_CENTER:
case SsaAlignment.TOP_LEFT: case SSA_ALIGNMENT_TOP_LEFT:
case SsaAlignment.TOP_RIGHT: case SSA_ALIGNMENT_TOP_RIGHT:
return true; return true;
case SsaAlignment.UNKNOWN: case SSA_ALIGNMENT_UNKNOWN:
default: default:
return false; return false;
} }
...@@ -177,7 +223,7 @@ import java.util.regex.Pattern; ...@@ -177,7 +223,7 @@ import java.util.regex.Pattern;
} }
public static Overrides parseFromDialogue(String text) { public static Overrides parseFromDialogue(String text) {
@SsaAlignment int alignment = SsaAlignment.UNKNOWN; @SsaAlignment int alignment = SSA_ALIGNMENT_UNKNOWN;
PointF position = null; PointF position = null;
Matcher matcher = BRACES_PATTERN.matcher(text); Matcher matcher = BRACES_PATTERN.matcher(text);
while (matcher.find()) { while (matcher.find()) {
...@@ -192,7 +238,7 @@ import java.util.regex.Pattern; ...@@ -192,7 +238,7 @@ import java.util.regex.Pattern;
} }
try { try {
@SsaAlignment int parsedAlignment = parseAlignmentOverride(braceContents); @SsaAlignment int parsedAlignment = parseAlignmentOverride(braceContents);
if (parsedAlignment != SsaAlignment.UNKNOWN) { if (parsedAlignment != SSA_ALIGNMENT_UNKNOWN) {
alignment = parsedAlignment; alignment = parsedAlignment;
} }
} catch (RuntimeException e) { } catch (RuntimeException e) {
...@@ -249,36 +295,7 @@ import java.util.regex.Pattern; ...@@ -249,36 +295,7 @@ import java.util.regex.Pattern;
@SsaAlignment @SsaAlignment
private static int parseAlignmentOverride(String braceContents) { private static int parseAlignmentOverride(String braceContents) {
Matcher matcher = ALIGNMENT_OVERRIDE_PATTERN.matcher(braceContents); Matcher matcher = ALIGNMENT_OVERRIDE_PATTERN.matcher(braceContents);
return matcher.find() ? parseAlignment(matcher.group(1)) : SsaAlignment.UNKNOWN; return matcher.find() ? parseAlignment(matcher.group(1)) : SSA_ALIGNMENT_UNKNOWN;
} }
} }
/** The SSA/ASS alignments. */
@IntDef({
SsaAlignment.UNKNOWN,
SsaAlignment.BOTTOM_LEFT,
SsaAlignment.BOTTOM_CENTER,
SsaAlignment.BOTTOM_RIGHT,
SsaAlignment.MIDDLE_LEFT,
SsaAlignment.MIDDLE_CENTER,
SsaAlignment.MIDDLE_RIGHT,
SsaAlignment.TOP_LEFT,
SsaAlignment.TOP_CENTER,
SsaAlignment.TOP_RIGHT,
})
@Documented
@Retention(SOURCE)
/* package */ @interface SsaAlignment {
// The numbering follows the ASS (v4+) spec (i.e. the points on the number pad).
int UNKNOWN = -1;
int BOTTOM_LEFT = 1;
int BOTTOM_CENTER = 2;
int BOTTOM_RIGHT = 3;
int MIDDLE_LEFT = 4;
int MIDDLE_CENTER = 5;
int MIDDLE_RIGHT = 6;
int TOP_LEFT = 7;
int TOP_CENTER = 8;
int TOP_RIGHT = 9;
}
} }
...@@ -75,7 +75,7 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper ...@@ -75,7 +75,7 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper
private final TimestampAdjusterProvider timestampAdjusterProvider; private final TimestampAdjusterProvider timestampAdjusterProvider;
private final CompositeSequenceableLoaderFactory compositeSequenceableLoaderFactory; private final CompositeSequenceableLoaderFactory compositeSequenceableLoaderFactory;
private final boolean allowChunklessPreparation; private final boolean allowChunklessPreparation;
private final @HlsMetadataType int metadataType; private final @HlsMediaSource.MetadataType int metadataType;
private final boolean useSessionKeys; private final boolean useSessionKeys;
@Nullable private Callback callback; @Nullable private Callback callback;
...@@ -118,7 +118,7 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper ...@@ -118,7 +118,7 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper
Allocator allocator, Allocator allocator,
CompositeSequenceableLoaderFactory compositeSequenceableLoaderFactory, CompositeSequenceableLoaderFactory compositeSequenceableLoaderFactory,
boolean allowChunklessPreparation, boolean allowChunklessPreparation,
@HlsMetadataType int metadataType, @HlsMediaSource.MetadataType int metadataType,
boolean useSessionKeys) { boolean useSessionKeys) {
this.extractorFactory = extractorFactory; this.extractorFactory = extractorFactory;
this.playlistTracker = playlistTracker; this.playlistTracker = playlistTracker;
......
...@@ -15,8 +15,11 @@ ...@@ -15,8 +15,11 @@
*/ */
package com.google.android.exoplayer2.source.hls; package com.google.android.exoplayer2.source.hls;
import static java.lang.annotation.RetentionPolicy.SOURCE;
import android.net.Uri; import android.net.Uri;
import android.os.Handler; import android.os.Handler;
import androidx.annotation.IntDef;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlayerLibraryInfo; import com.google.android.exoplayer2.ExoPlayerLibraryInfo;
...@@ -47,6 +50,8 @@ import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy; ...@@ -47,6 +50,8 @@ import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy;
import com.google.android.exoplayer2.upstream.TransferListener; import com.google.android.exoplayer2.upstream.TransferListener;
import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Assertions;
import java.io.IOException; import java.io.IOException;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.util.List; import java.util.List;
/** An HLS {@link MediaSource}. */ /** An HLS {@link MediaSource}. */
...@@ -57,6 +62,28 @@ public final class HlsMediaSource extends BaseMediaSource ...@@ -57,6 +62,28 @@ public final class HlsMediaSource extends BaseMediaSource
ExoPlayerLibraryInfo.registerModule("goog.exo.hls"); ExoPlayerLibraryInfo.registerModule("goog.exo.hls");
} }
/**
* The types of metadata that can be extracted from HLS streams.
*
* <p>Allowed values:
*
* <ul>
* <li>{@link #METADATA_TYPE_ID3}
* <li>{@link #METADATA_TYPE_EMSG}
* </ul>
*
* <p>See {@link Factory#setMetadataType(int)}.
*/
@Documented
@Retention(SOURCE)
@IntDef({METADATA_TYPE_ID3, METADATA_TYPE_EMSG})
public @interface MetadataType {}
/** Type for ID3 metadata in HLS streams. */
public static final int METADATA_TYPE_ID3 = 1;
/** Type for ESMG metadata in HLS streams. */
public static final int METADATA_TYPE_EMSG = 3;
/** Factory for {@link HlsMediaSource}s. */ /** Factory for {@link HlsMediaSource}s. */
public static final class Factory implements MediaSourceFactory { public static final class Factory implements MediaSourceFactory {
...@@ -70,7 +97,7 @@ public final class HlsMediaSource extends BaseMediaSource ...@@ -70,7 +97,7 @@ public final class HlsMediaSource extends BaseMediaSource
private DrmSessionManager<?> drmSessionManager; private DrmSessionManager<?> drmSessionManager;
private LoadErrorHandlingPolicy loadErrorHandlingPolicy; private LoadErrorHandlingPolicy loadErrorHandlingPolicy;
private boolean allowChunklessPreparation; private boolean allowChunklessPreparation;
@HlsMetadataType private int metadataType; @MetadataType private int metadataType;
private boolean useSessionKeys; private boolean useSessionKeys;
private boolean isCreateCalled; private boolean isCreateCalled;
@Nullable private Object tag; @Nullable private Object tag;
...@@ -100,7 +127,7 @@ public final class HlsMediaSource extends BaseMediaSource ...@@ -100,7 +127,7 @@ public final class HlsMediaSource extends BaseMediaSource
drmSessionManager = DrmSessionManager.getDummyDrmSessionManager(); drmSessionManager = DrmSessionManager.getDummyDrmSessionManager();
loadErrorHandlingPolicy = new DefaultLoadErrorHandlingPolicy(); loadErrorHandlingPolicy = new DefaultLoadErrorHandlingPolicy();
compositeSequenceableLoaderFactory = new DefaultCompositeSequenceableLoaderFactory(); compositeSequenceableLoaderFactory = new DefaultCompositeSequenceableLoaderFactory();
metadataType = HlsMetadataType.ID3; metadataType = METADATA_TYPE_ID3;
} }
/** /**
...@@ -232,24 +259,24 @@ public final class HlsMediaSource extends BaseMediaSource ...@@ -232,24 +259,24 @@ public final class HlsMediaSource extends BaseMediaSource
/** /**
* Sets the type of metadata to extract from the HLS source (defaults to {@link * Sets the type of metadata to extract from the HLS source (defaults to {@link
* HlsMetadataType#ID3}). * #METADATA_TYPE_ID3}).
* *
* <p>HLS supports in-band ID3 in both TS and fMP4 streams, but in the fMP4 case the data is * <p>HLS supports in-band ID3 in both TS and fMP4 streams, but in the fMP4 case the data is
* wrapped in an EMSG box [<a href="https://aomediacodec.github.io/av1-id3/">spec</a>]. * wrapped in an EMSG box [<a href="https://aomediacodec.github.io/av1-id3/">spec</a>].
* *
* <p>If this is set to {@link HlsMetadataType#ID3} then raw ID3 metadata of will be extracted * <p>If this is set to {@link #METADATA_TYPE_ID3} then raw ID3 metadata of will be extracted
* from TS sources. From fMP4 streams EMSGs containing metadata of this type (in the variant * from TS sources. From fMP4 streams EMSGs containing metadata of this type (in the variant
* stream only) will be unwrapped to expose the inner data. All other in-band metadata will be * stream only) will be unwrapped to expose the inner data. All other in-band metadata will be
* dropped. * dropped.
* *
* <p>If this is set to {@link HlsMetadataType#EMSG} then all EMSG data from the fMP4 variant * <p>If this is set to {@link #METADATA_TYPE_EMSG} then all EMSG data from the fMP4 variant
* stream will be extracted. No metadata will be extracted from TS streams, since they don't * stream will be extracted. No metadata will be extracted from TS streams, since they don't
* support EMSG. * support EMSG.
* *
* @param metadataType The type of metadata to extract. * @param metadataType The type of metadata to extract.
* @return This factory, for convenience. * @return This factory, for convenience.
*/ */
public Factory setMetadataType(@HlsMetadataType int metadataType) { public Factory setMetadataType(@MetadataType int metadataType) {
Assertions.checkState(!isCreateCalled); Assertions.checkState(!isCreateCalled);
this.metadataType = metadataType; this.metadataType = metadataType;
return this; return this;
...@@ -348,7 +375,7 @@ public final class HlsMediaSource extends BaseMediaSource ...@@ -348,7 +375,7 @@ public final class HlsMediaSource extends BaseMediaSource
private final DrmSessionManager<?> drmSessionManager; private final DrmSessionManager<?> drmSessionManager;
private final LoadErrorHandlingPolicy loadErrorHandlingPolicy; private final LoadErrorHandlingPolicy loadErrorHandlingPolicy;
private final boolean allowChunklessPreparation; private final boolean allowChunklessPreparation;
private final @HlsMetadataType int metadataType; private final @MetadataType int metadataType;
private final boolean useSessionKeys; private final boolean useSessionKeys;
private final HlsPlaylistTracker playlistTracker; private final HlsPlaylistTracker playlistTracker;
@Nullable private final Object tag; @Nullable private final Object tag;
...@@ -364,7 +391,7 @@ public final class HlsMediaSource extends BaseMediaSource ...@@ -364,7 +391,7 @@ public final class HlsMediaSource extends BaseMediaSource
LoadErrorHandlingPolicy loadErrorHandlingPolicy, LoadErrorHandlingPolicy loadErrorHandlingPolicy,
HlsPlaylistTracker playlistTracker, HlsPlaylistTracker playlistTracker,
boolean allowChunklessPreparation, boolean allowChunklessPreparation,
@HlsMetadataType int metadataType, @MetadataType int metadataType,
boolean useSessionKeys, boolean useSessionKeys,
@Nullable Object tag) { @Nullable Object tag) {
this.manifestUri = manifestUri; this.manifestUri = manifestUri;
......
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.google.android.exoplayer2.source.hls;
import static java.lang.annotation.RetentionPolicy.SOURCE;
import androidx.annotation.IntDef;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
/**
* The types of metadata that can be extracted from HLS streams.
*
* <p>See {@link HlsMediaSource.Factory#setMetadataType(int)}.
*/
@Documented
@Retention(SOURCE)
@IntDef({HlsMetadataType.ID3, HlsMetadataType.EMSG})
public @interface HlsMetadataType {
/** Type for ID3 metadata in HLS streams. */
int ID3 = 1;
/** Type for ESMG metadata in HLS streams. */
int EMSG = 3;
}
...@@ -116,7 +116,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull; ...@@ -116,7 +116,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
private final LoadErrorHandlingPolicy loadErrorHandlingPolicy; private final LoadErrorHandlingPolicy loadErrorHandlingPolicy;
private final Loader loader; private final Loader loader;
private final EventDispatcher eventDispatcher; private final EventDispatcher eventDispatcher;
private final @HlsMetadataType int metadataType; private final @HlsMediaSource.MetadataType int metadataType;
private final HlsChunkSource.HlsChunkHolder nextChunkHolder; private final HlsChunkSource.HlsChunkHolder nextChunkHolder;
private final ArrayList<HlsMediaChunk> mediaChunks; private final ArrayList<HlsMediaChunk> mediaChunks;
private final List<HlsMediaChunk> readOnlyMediaChunks; private final List<HlsMediaChunk> readOnlyMediaChunks;
...@@ -190,7 +190,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull; ...@@ -190,7 +190,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
DrmSessionManager<?> drmSessionManager, DrmSessionManager<?> drmSessionManager,
LoadErrorHandlingPolicy loadErrorHandlingPolicy, LoadErrorHandlingPolicy loadErrorHandlingPolicy,
EventDispatcher eventDispatcher, EventDispatcher eventDispatcher,
@HlsMetadataType int metadataType) { @HlsMediaSource.MetadataType int metadataType) {
this.trackType = trackType; this.trackType = trackType;
this.callback = callback; this.callback = callback;
this.chunkSource = chunkSource; this.chunkSource = chunkSource;
...@@ -1362,14 +1362,15 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull; ...@@ -1362,14 +1362,15 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
private byte[] buffer; private byte[] buffer;
private int bufferPosition; private int bufferPosition;
public EmsgUnwrappingTrackOutput(TrackOutput delegate, @HlsMetadataType int metadataType) { public EmsgUnwrappingTrackOutput(
TrackOutput delegate, @HlsMediaSource.MetadataType int metadataType) {
this.emsgDecoder = new EventMessageDecoder(); this.emsgDecoder = new EventMessageDecoder();
this.delegate = delegate; this.delegate = delegate;
switch (metadataType) { switch (metadataType) {
case HlsMetadataType.ID3: case HlsMediaSource.METADATA_TYPE_ID3:
delegateFormat = ID3_FORMAT; delegateFormat = ID3_FORMAT;
break; break;
case HlsMetadataType.EMSG: case HlsMediaSource.METADATA_TYPE_EMSG:
delegateFormat = EMSG_FORMAT; delegateFormat = EMSG_FORMAT;
break; break;
default: default:
......
...@@ -92,7 +92,7 @@ public final class HlsMediaPeriodTest { ...@@ -92,7 +92,7 @@ public final class HlsMediaPeriodTest {
mock(Allocator.class), mock(Allocator.class),
mock(CompositeSequenceableLoaderFactory.class), mock(CompositeSequenceableLoaderFactory.class),
/* allowChunklessPreparation =*/ true, /* allowChunklessPreparation =*/ true,
HlsMetadataType.ID3, HlsMediaSource.METADATA_TYPE_ID3,
/* useSessionKeys= */ false); /* useSessionKeys= */ false);
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment