diff --git a/library/core/src/main/java/com/google/android/exoplayer2/DefaultRenderersFactory.java b/library/core/src/main/java/com/google/android/exoplayer2/DefaultRenderersFactory.java index 97ad6613e3..f54794216b 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/DefaultRenderersFactory.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/DefaultRenderersFactory.java @@ -102,7 +102,7 @@ public class DefaultRenderersFactory implements RenderersFactory { extensionRendererMode = EXTENSION_RENDERER_MODE_OFF; allowedVideoJoiningTimeMs = DEFAULT_ALLOWED_VIDEO_JOINING_TIME_MS; mediaCodecSelector = MediaCodecSelector.DEFAULT; - mediaCodecOperationMode = MediaCodecRenderer.MediaCodecOperationMode.SYNCHRONOUS; + mediaCodecOperationMode = MediaCodecRenderer.OPERATION_MODE_SYNCHRONOUS; } /** diff --git a/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/DedicatedThreadAsyncMediaCodecAdapter.java b/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/DedicatedThreadAsyncMediaCodecAdapter.java index d6e4e84525..bad21f91f8 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/DedicatedThreadAsyncMediaCodecAdapter.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/DedicatedThreadAsyncMediaCodecAdapter.java @@ -41,12 +41,12 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; /* package */ final class DedicatedThreadAsyncMediaCodecAdapter extends MediaCodec.Callback implements MediaCodecAdapter { - @IntDef({State.CREATED, State.STARTED, State.SHUT_DOWN}) - private @interface State { - int CREATED = 0; - int STARTED = 1; - int SHUT_DOWN = 2; - } + @IntDef({STATE_CREATED, STATE_STARTED, STATE_SHUT_DOWN}) + private @interface State {} + + private static final int STATE_CREATED = 0; + private static final int STATE_STARTED = 1; + private static final int STATE_SHUT_DOWN = 2; private final MediaCodecAsyncCallback mediaCodecAsyncCallback; private final MediaCodec codec; @@ -76,7 +76,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; mediaCodecAsyncCallback = new MediaCodecAsyncCallback(); this.codec = codec; this.handlerThread = handlerThread; - state = State.CREATED; + state = STATE_CREATED; onCodecStart = codec::start; } @@ -90,17 +90,17 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; * @throws IllegalStateException If this method has been called already. */ public synchronized void start() { - Assertions.checkState(state == State.CREATED); + Assertions.checkState(state == STATE_CREATED); handlerThread.start(); handler = new Handler(handlerThread.getLooper()); codec.setCallback(this, handler); - state = State.STARTED; + state = STATE_STARTED; } @Override public synchronized int dequeueInputBufferIndex() { - Assertions.checkState(state == State.STARTED); + Assertions.checkState(state == STATE_STARTED); if (isFlushing()) { return MediaCodec.INFO_TRY_AGAIN_LATER; @@ -112,7 +112,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; @Override public synchronized int dequeueOutputBufferIndex(MediaCodec.BufferInfo bufferInfo) { - Assertions.checkState(state == State.STARTED); + Assertions.checkState(state == STATE_STARTED); if (isFlushing()) { return MediaCodec.INFO_TRY_AGAIN_LATER; @@ -124,14 +124,14 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; @Override public synchronized MediaFormat getOutputFormat() { - Assertions.checkState(state == State.STARTED); + Assertions.checkState(state == STATE_STARTED); return mediaCodecAsyncCallback.getOutputFormat(); } @Override public synchronized void flush() { - Assertions.checkState(state == State.STARTED); + Assertions.checkState(state == STATE_STARTED); codec.flush(); ++pendingFlushCount; @@ -140,12 +140,12 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; @Override public synchronized void shutdown() { - if (state == State.STARTED) { + if (state == STATE_STARTED) { handlerThread.quit(); mediaCodecAsyncCallback.flush(); } - state = State.SHUT_DOWN; + state = STATE_SHUT_DOWN; } @Override @@ -182,7 +182,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; } private synchronized void onFlushCompleted() { - if (state != State.STARTED) { + if (state != STATE_STARTED) { // The adapter has been shutdown. return; } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecRenderer.java b/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecRenderer.java index 953ffbe546..48a415ec7f 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecRenderer.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecRenderer.java @@ -61,8 +61,46 @@ import java.util.List; public abstract class MediaCodecRenderer extends BaseRenderer { /** - * Thrown when a failure occurs instantiating a decoder. + * The modes to operate the {@link MediaCodec}. + * + *

Allowed values: + * + *

*/ + @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 { private static final int CUSTOM_ERROR_CODE_BASE = -50000; @@ -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. */ protected static final float CODEC_OPERATING_RATE_UNSET = -1; @@ -447,7 +455,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer { outputBufferInfo = new MediaCodec.BufferInfo(); rendererOperatingRate = 1f; renderTimeLimitMs = C.TIME_UNSET; - mediaCodecOperationMode = MediaCodecOperationMode.SYNCHRONOUS; + mediaCodecOperationMode = OPERATION_MODE_SYNCHRONOUS; resetCodecStateForRelease(); } @@ -473,23 +481,24 @@ public abstract class MediaCodecRenderer extends BaseRenderer { * * @param mode The mode of the MediaCodec. The supported modes are: * - * 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) { mediaCodecOperationMode = mode; @@ -980,15 +989,14 @@ public abstract class MediaCodecRenderer extends BaseRenderer { codecInitializingTimestamp = SystemClock.elapsedRealtime(); TraceUtil.beginSection("createCodec:" + codecName); codec = MediaCodec.createByCodecName(codecName); - if (mediaCodecOperationMode == MediaCodecOperationMode.ASYNCHRONOUS_PLAYBACK_THREAD + if (mediaCodecOperationMode == OPERATION_MODE_ASYNCHRONOUS_PLAYBACK_THREAD && Util.SDK_INT >= 21) { codecAdapter = new AsynchronousMediaCodecAdapter(codec); - } else if (mediaCodecOperationMode == MediaCodecOperationMode.ASYNCHRONOUS_DEDICATED_THREAD + } else if (mediaCodecOperationMode == OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD && Util.SDK_INT >= 23) { codecAdapter = new DedicatedThreadAsyncMediaCodecAdapter(codec, getTrackType()); ((DedicatedThreadAsyncMediaCodecAdapter) codecAdapter).start(); - } else if (mediaCodecOperationMode - == MediaCodecOperationMode.ASYNCHRONOUS_DEDICATED_THREAD_MULTI_LOCK + } else if (mediaCodecOperationMode == OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD_MULTI_LOCK && Util.SDK_INT >= 23) { codecAdapter = new MultiLockAsynchMediaCodecAdapter(codec, getTrackType()); ((MultiLockAsynchMediaCodecAdapter) codecAdapter).start(); diff --git a/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MultiLockAsynchMediaCodecAdapter.java b/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MultiLockAsynchMediaCodecAdapter.java index 2fa40545d5..7d00d15947 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MultiLockAsynchMediaCodecAdapter.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MultiLockAsynchMediaCodecAdapter.java @@ -54,12 +54,12 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; /* package */ final class MultiLockAsynchMediaCodecAdapter extends MediaCodec.Callback implements MediaCodecAdapter { - @IntDef({State.CREATED, State.STARTED, State.SHUT_DOWN}) - private @interface State { - int CREATED = 0; - int STARTED = 1; - int SHUT_DOWN = 2; - } + @IntDef({STATE_CREATED, STATE_STARTED, STATE_SHUT_DOWN}) + private @interface State {} + + private static final int STATE_CREATED = 0; + private static final int STATE_STARTED = 1; + private static final int STATE_SHUT_DOWN = 2; private final MediaCodec codec; private final Object inputBufferLock; @@ -112,7 +112,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; bufferInfos = new ArrayDeque<>(); formats = new ArrayDeque<>(); codecException = null; - state = State.CREATED; + state = STATE_CREATED; this.handlerThread = handlerThread; onCodecStart = codec::start; } @@ -128,19 +128,19 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; */ public void start() { synchronized (objectStateLock) { - Assertions.checkState(state == State.CREATED); + Assertions.checkState(state == STATE_CREATED); handlerThread.start(); handler = new Handler(handlerThread.getLooper()); codec.setCallback(this, handler); - state = State.STARTED; + state = STATE_STARTED; } } @Override public int dequeueInputBufferIndex() { synchronized (objectStateLock) { - Assertions.checkState(state == State.STARTED); + Assertions.checkState(state == STATE_STARTED); if (isFlushing()) { return MediaCodec.INFO_TRY_AGAIN_LATER; @@ -154,7 +154,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; @Override public int dequeueOutputBufferIndex(MediaCodec.BufferInfo bufferInfo) { synchronized (objectStateLock) { - Assertions.checkState(state == State.STARTED); + Assertions.checkState(state == STATE_STARTED); if (isFlushing()) { return MediaCodec.INFO_TRY_AGAIN_LATER; @@ -168,7 +168,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; @Override public MediaFormat getOutputFormat() { synchronized (objectStateLock) { - Assertions.checkState(state == State.STARTED); + Assertions.checkState(state == STATE_STARTED); if (currentFormat == null) { throw new IllegalStateException(); @@ -181,7 +181,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; @Override public void flush() { synchronized (objectStateLock) { - Assertions.checkState(state == State.STARTED); + Assertions.checkState(state == STATE_STARTED); codec.flush(); pendingFlush++; @@ -192,10 +192,10 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; @Override public void shutdown() { synchronized (objectStateLock) { - if (state == State.STARTED) { + if (state == STATE_STARTED) { handlerThread.quit(); } - state = State.SHUT_DOWN; + state = STATE_SHUT_DOWN; } } @@ -289,7 +289,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; private void onFlushComplete() { synchronized (objectStateLock) { - if (state == State.SHUT_DOWN) { + if (state == STATE_SHUT_DOWN) { return; } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/text/ssa/SsaDecoder.java b/library/core/src/main/java/com/google/android/exoplayer2/text/ssa/SsaDecoder.java index 917ac8e36e..eef9d2eec1 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/text/ssa/SsaDecoder.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/text/ssa/SsaDecoder.java @@ -300,12 +300,12 @@ public final class SsaDecoder extends SimpleSubtitleDecoder { float screenWidth, float screenHeight) { @SsaStyle.SsaAlignment int alignment; - if (styleOverrides.alignment != SsaStyle.SsaAlignment.UNKNOWN) { + if (styleOverrides.alignment != SsaStyle.SSA_ALIGNMENT_UNKNOWN) { alignment = styleOverrides.alignment; } else if (style != null) { alignment = style.alignment; } else { - alignment = SsaStyle.SsaAlignment.UNKNOWN; + alignment = SsaStyle.SSA_ALIGNMENT_UNKNOWN; } @Cue.AnchorType int positionAnchor = toPositionAnchor(alignment); @Cue.AnchorType int lineAnchor = toLineAnchor(alignment); @@ -337,19 +337,19 @@ public final class SsaDecoder extends SimpleSubtitleDecoder { @Nullable private static Layout.Alignment toTextAlignment(@SsaStyle.SsaAlignment int alignment) { switch (alignment) { - case SsaStyle.SsaAlignment.BOTTOM_LEFT: - case SsaStyle.SsaAlignment.MIDDLE_LEFT: - case SsaStyle.SsaAlignment.TOP_LEFT: + case SsaStyle.SSA_ALIGNMENT_BOTTOM_LEFT: + case SsaStyle.SSA_ALIGNMENT_MIDDLE_LEFT: + case SsaStyle.SSA_ALIGNMENT_TOP_LEFT: return Layout.Alignment.ALIGN_NORMAL; - case SsaStyle.SsaAlignment.BOTTOM_CENTER: - case SsaStyle.SsaAlignment.MIDDLE_CENTER: - case SsaStyle.SsaAlignment.TOP_CENTER: + case SsaStyle.SSA_ALIGNMENT_BOTTOM_CENTER: + case SsaStyle.SSA_ALIGNMENT_MIDDLE_CENTER: + case SsaStyle.SSA_ALIGNMENT_TOP_CENTER: return Layout.Alignment.ALIGN_CENTER; - case SsaStyle.SsaAlignment.BOTTOM_RIGHT: - case SsaStyle.SsaAlignment.MIDDLE_RIGHT: - case SsaStyle.SsaAlignment.TOP_RIGHT: + case SsaStyle.SSA_ALIGNMENT_BOTTOM_RIGHT: + case SsaStyle.SSA_ALIGNMENT_MIDDLE_RIGHT: + case SsaStyle.SSA_ALIGNMENT_TOP_RIGHT: return Layout.Alignment.ALIGN_OPPOSITE; - case SsaStyle.SsaAlignment.UNKNOWN: + case SsaStyle.SSA_ALIGNMENT_UNKNOWN: return null; default: Log.w(TAG, "Unknown alignment: " + alignment); @@ -360,19 +360,19 @@ public final class SsaDecoder extends SimpleSubtitleDecoder { @Cue.AnchorType private static int toLineAnchor(@SsaStyle.SsaAlignment int alignment) { switch (alignment) { - case SsaStyle.SsaAlignment.BOTTOM_LEFT: - case SsaStyle.SsaAlignment.BOTTOM_CENTER: - case SsaStyle.SsaAlignment.BOTTOM_RIGHT: + case SsaStyle.SSA_ALIGNMENT_BOTTOM_LEFT: + case SsaStyle.SSA_ALIGNMENT_BOTTOM_CENTER: + case SsaStyle.SSA_ALIGNMENT_BOTTOM_RIGHT: return Cue.ANCHOR_TYPE_END; - case SsaStyle.SsaAlignment.MIDDLE_LEFT: - case SsaStyle.SsaAlignment.MIDDLE_CENTER: - case SsaStyle.SsaAlignment.MIDDLE_RIGHT: + case SsaStyle.SSA_ALIGNMENT_MIDDLE_LEFT: + case SsaStyle.SSA_ALIGNMENT_MIDDLE_CENTER: + case SsaStyle.SSA_ALIGNMENT_MIDDLE_RIGHT: return Cue.ANCHOR_TYPE_MIDDLE; - case SsaStyle.SsaAlignment.TOP_LEFT: - case SsaStyle.SsaAlignment.TOP_CENTER: - case SsaStyle.SsaAlignment.TOP_RIGHT: + case SsaStyle.SSA_ALIGNMENT_TOP_LEFT: + case SsaStyle.SSA_ALIGNMENT_TOP_CENTER: + case SsaStyle.SSA_ALIGNMENT_TOP_RIGHT: return Cue.ANCHOR_TYPE_START; - case SsaStyle.SsaAlignment.UNKNOWN: + case SsaStyle.SSA_ALIGNMENT_UNKNOWN: return Cue.TYPE_UNSET; default: Log.w(TAG, "Unknown alignment: " + alignment); @@ -383,19 +383,19 @@ public final class SsaDecoder extends SimpleSubtitleDecoder { @Cue.AnchorType private static int toPositionAnchor(@SsaStyle.SsaAlignment int alignment) { switch (alignment) { - case SsaStyle.SsaAlignment.BOTTOM_LEFT: - case SsaStyle.SsaAlignment.MIDDLE_LEFT: - case SsaStyle.SsaAlignment.TOP_LEFT: + case SsaStyle.SSA_ALIGNMENT_BOTTOM_LEFT: + case SsaStyle.SSA_ALIGNMENT_MIDDLE_LEFT: + case SsaStyle.SSA_ALIGNMENT_TOP_LEFT: return Cue.ANCHOR_TYPE_START; - case SsaStyle.SsaAlignment.BOTTOM_CENTER: - case SsaStyle.SsaAlignment.MIDDLE_CENTER: - case SsaStyle.SsaAlignment.TOP_CENTER: + case SsaStyle.SSA_ALIGNMENT_BOTTOM_CENTER: + case SsaStyle.SSA_ALIGNMENT_MIDDLE_CENTER: + case SsaStyle.SSA_ALIGNMENT_TOP_CENTER: return Cue.ANCHOR_TYPE_MIDDLE; - case SsaStyle.SsaAlignment.BOTTOM_RIGHT: - case SsaStyle.SsaAlignment.MIDDLE_RIGHT: - case SsaStyle.SsaAlignment.TOP_RIGHT: + case SsaStyle.SSA_ALIGNMENT_BOTTOM_RIGHT: + case SsaStyle.SSA_ALIGNMENT_MIDDLE_RIGHT: + case SsaStyle.SSA_ALIGNMENT_TOP_RIGHT: return Cue.ANCHOR_TYPE_END; - case SsaStyle.SsaAlignment.UNKNOWN: + case SsaStyle.SSA_ALIGNMENT_UNKNOWN: return Cue.TYPE_UNSET; default: Log.w(TAG, "Unknown alignment: " + alignment); diff --git a/library/core/src/main/java/com/google/android/exoplayer2/text/ssa/SsaStyle.java b/library/core/src/main/java/com/google/android/exoplayer2/text/ssa/SsaStyle.java index e8070976e7..fd2cb036b7 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/text/ssa/SsaStyle.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/text/ssa/SsaStyle.java @@ -37,6 +37,52 @@ import java.util.regex.Pattern; private static final String TAG = "SsaStyle"; + /** + * The SSA/ASS alignments. + * + *

Allowed values: + * + *

+ */ + @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; @SsaAlignment public final int alignment; @@ -77,22 +123,22 @@ import java.util.regex.Pattern; // Swallow the exception and return UNKNOWN below. } Log.w(TAG, "Ignoring unknown alignment: " + alignmentStr); - return SsaAlignment.UNKNOWN; + return SSA_ALIGNMENT_UNKNOWN; } private static boolean isValidAlignment(@SsaAlignment int alignment) { switch (alignment) { - case SsaAlignment.BOTTOM_CENTER: - case SsaAlignment.BOTTOM_LEFT: - case SsaAlignment.BOTTOM_RIGHT: - case SsaAlignment.MIDDLE_CENTER: - case SsaAlignment.MIDDLE_LEFT: - case SsaAlignment.MIDDLE_RIGHT: - case SsaAlignment.TOP_CENTER: - case SsaAlignment.TOP_LEFT: - case SsaAlignment.TOP_RIGHT: + case SSA_ALIGNMENT_BOTTOM_CENTER: + case SSA_ALIGNMENT_BOTTOM_LEFT: + case SSA_ALIGNMENT_BOTTOM_RIGHT: + case SSA_ALIGNMENT_MIDDLE_CENTER: + case SSA_ALIGNMENT_MIDDLE_LEFT: + case SSA_ALIGNMENT_MIDDLE_RIGHT: + case SSA_ALIGNMENT_TOP_CENTER: + case SSA_ALIGNMENT_TOP_LEFT: + case SSA_ALIGNMENT_TOP_RIGHT: return true; - case SsaAlignment.UNKNOWN: + case SSA_ALIGNMENT_UNKNOWN: default: return false; } @@ -177,7 +223,7 @@ import java.util.regex.Pattern; } public static Overrides parseFromDialogue(String text) { - @SsaAlignment int alignment = SsaAlignment.UNKNOWN; + @SsaAlignment int alignment = SSA_ALIGNMENT_UNKNOWN; PointF position = null; Matcher matcher = BRACES_PATTERN.matcher(text); while (matcher.find()) { @@ -192,7 +238,7 @@ import java.util.regex.Pattern; } try { @SsaAlignment int parsedAlignment = parseAlignmentOverride(braceContents); - if (parsedAlignment != SsaAlignment.UNKNOWN) { + if (parsedAlignment != SSA_ALIGNMENT_UNKNOWN) { alignment = parsedAlignment; } } catch (RuntimeException e) { @@ -249,36 +295,7 @@ import java.util.regex.Pattern; @SsaAlignment private static int parseAlignmentOverride(String 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; - } } diff --git a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaPeriod.java b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaPeriod.java index f74d9b0b0c..3b723af435 100644 --- a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaPeriod.java +++ b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaPeriod.java @@ -75,7 +75,7 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper private final TimestampAdjusterProvider timestampAdjusterProvider; private final CompositeSequenceableLoaderFactory compositeSequenceableLoaderFactory; private final boolean allowChunklessPreparation; - private final @HlsMetadataType int metadataType; + private final @HlsMediaSource.MetadataType int metadataType; private final boolean useSessionKeys; @Nullable private Callback callback; @@ -118,7 +118,7 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper Allocator allocator, CompositeSequenceableLoaderFactory compositeSequenceableLoaderFactory, boolean allowChunklessPreparation, - @HlsMetadataType int metadataType, + @HlsMediaSource.MetadataType int metadataType, boolean useSessionKeys) { this.extractorFactory = extractorFactory; this.playlistTracker = playlistTracker; diff --git a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaSource.java b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaSource.java index 411eb448be..8e08fb8fb2 100644 --- a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaSource.java +++ b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaSource.java @@ -15,8 +15,11 @@ */ package com.google.android.exoplayer2.source.hls; +import static java.lang.annotation.RetentionPolicy.SOURCE; + import android.net.Uri; import android.os.Handler; +import androidx.annotation.IntDef; import androidx.annotation.Nullable; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.ExoPlayerLibraryInfo; @@ -47,6 +50,8 @@ import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy; import com.google.android.exoplayer2.upstream.TransferListener; import com.google.android.exoplayer2.util.Assertions; import java.io.IOException; +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; import java.util.List; /** An HLS {@link MediaSource}. */ @@ -57,6 +62,28 @@ public final class HlsMediaSource extends BaseMediaSource ExoPlayerLibraryInfo.registerModule("goog.exo.hls"); } + /** + * The types of metadata that can be extracted from HLS streams. + * + *

Allowed values: + * + *

+ * + *

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. */ public static final class Factory implements MediaSourceFactory { @@ -70,7 +97,7 @@ public final class HlsMediaSource extends BaseMediaSource private DrmSessionManager drmSessionManager; private LoadErrorHandlingPolicy loadErrorHandlingPolicy; private boolean allowChunklessPreparation; - @HlsMetadataType private int metadataType; + @MetadataType private int metadataType; private boolean useSessionKeys; private boolean isCreateCalled; @Nullable private Object tag; @@ -100,7 +127,7 @@ public final class HlsMediaSource extends BaseMediaSource drmSessionManager = DrmSessionManager.getDummyDrmSessionManager(); loadErrorHandlingPolicy = new DefaultLoadErrorHandlingPolicy(); compositeSequenceableLoaderFactory = new DefaultCompositeSequenceableLoaderFactory(); - metadataType = HlsMetadataType.ID3; + metadataType = METADATA_TYPE_ID3; } /** @@ -232,24 +259,24 @@ public final class HlsMediaSource extends BaseMediaSource /** * Sets the type of metadata to extract from the HLS source (defaults to {@link - * HlsMetadataType#ID3}). + * #METADATA_TYPE_ID3}). * *

HLS supports in-band ID3 in both TS and fMP4 streams, but in the fMP4 case the data is * wrapped in an EMSG box [spec]. * - *

If this is set to {@link HlsMetadataType#ID3} then raw ID3 metadata of will be extracted + *

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 * stream only) will be unwrapped to expose the inner data. All other in-band metadata will be * dropped. * - *

If this is set to {@link HlsMetadataType#EMSG} then all EMSG data from the fMP4 variant + *

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 * support EMSG. * * @param metadataType The type of metadata to extract. * @return This factory, for convenience. */ - public Factory setMetadataType(@HlsMetadataType int metadataType) { + public Factory setMetadataType(@MetadataType int metadataType) { Assertions.checkState(!isCreateCalled); this.metadataType = metadataType; return this; @@ -348,7 +375,7 @@ public final class HlsMediaSource extends BaseMediaSource private final DrmSessionManager drmSessionManager; private final LoadErrorHandlingPolicy loadErrorHandlingPolicy; private final boolean allowChunklessPreparation; - private final @HlsMetadataType int metadataType; + private final @MetadataType int metadataType; private final boolean useSessionKeys; private final HlsPlaylistTracker playlistTracker; @Nullable private final Object tag; @@ -364,7 +391,7 @@ public final class HlsMediaSource extends BaseMediaSource LoadErrorHandlingPolicy loadErrorHandlingPolicy, HlsPlaylistTracker playlistTracker, boolean allowChunklessPreparation, - @HlsMetadataType int metadataType, + @MetadataType int metadataType, boolean useSessionKeys, @Nullable Object tag) { this.manifestUri = manifestUri; diff --git a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMetadataType.java b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMetadataType.java deleted file mode 100644 index 8fb6c220cf..0000000000 --- a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMetadataType.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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. - * - *

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; -} diff --git a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java index d99bb817c1..8aedb6a545 100644 --- a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java +++ b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java @@ -116,7 +116,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull; private final LoadErrorHandlingPolicy loadErrorHandlingPolicy; private final Loader loader; private final EventDispatcher eventDispatcher; - private final @HlsMetadataType int metadataType; + private final @HlsMediaSource.MetadataType int metadataType; private final HlsChunkSource.HlsChunkHolder nextChunkHolder; private final ArrayList mediaChunks; private final List readOnlyMediaChunks; @@ -190,7 +190,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull; DrmSessionManager drmSessionManager, LoadErrorHandlingPolicy loadErrorHandlingPolicy, EventDispatcher eventDispatcher, - @HlsMetadataType int metadataType) { + @HlsMediaSource.MetadataType int metadataType) { this.trackType = trackType; this.callback = callback; this.chunkSource = chunkSource; @@ -1362,14 +1362,15 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull; private byte[] buffer; private int bufferPosition; - public EmsgUnwrappingTrackOutput(TrackOutput delegate, @HlsMetadataType int metadataType) { + public EmsgUnwrappingTrackOutput( + TrackOutput delegate, @HlsMediaSource.MetadataType int metadataType) { this.emsgDecoder = new EventMessageDecoder(); this.delegate = delegate; switch (metadataType) { - case HlsMetadataType.ID3: + case HlsMediaSource.METADATA_TYPE_ID3: delegateFormat = ID3_FORMAT; break; - case HlsMetadataType.EMSG: + case HlsMediaSource.METADATA_TYPE_EMSG: delegateFormat = EMSG_FORMAT; break; default: diff --git a/library/hls/src/test/java/com/google/android/exoplayer2/source/hls/HlsMediaPeriodTest.java b/library/hls/src/test/java/com/google/android/exoplayer2/source/hls/HlsMediaPeriodTest.java index 73ef11bda9..820c39c197 100644 --- a/library/hls/src/test/java/com/google/android/exoplayer2/source/hls/HlsMediaPeriodTest.java +++ b/library/hls/src/test/java/com/google/android/exoplayer2/source/hls/HlsMediaPeriodTest.java @@ -92,7 +92,7 @@ public final class HlsMediaPeriodTest { mock(Allocator.class), mock(CompositeSequenceableLoaderFactory.class), /* allowChunklessPreparation =*/ true, - HlsMetadataType.ID3, + HlsMediaSource.METADATA_TYPE_ID3, /* useSessionKeys= */ false); };