Commit 3ce57ae2 by christosts Committed by Oliver Woodman

Remove dropped MediaCodecAdadpters

Delete the AsynchronousMediaCodecAdapter, the
MultiLockAsyncMediaCodecAdapter and their tests.

PiperOrigin-RevId: 315694296
parent 95b61eb8
/*
* 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.mediacodec;
import android.media.MediaCodec;
import android.media.MediaFormat;
import android.os.Handler;
import android.os.Looper;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.annotation.VisibleForTesting;
import com.google.android.exoplayer2.decoder.CryptoInfo;
import com.google.android.exoplayer2.util.Assertions;
/**
* A {@link MediaCodecAdapter} that operates the {@link MediaCodec} in asynchronous mode.
*
* <p>The AsynchronousMediaCodecAdapter routes callbacks to the current thread's {@link Looper}
* obtained via {@link Looper#myLooper()}
*/
@RequiresApi(21)
/* package */ final class AsynchronousMediaCodecAdapter implements MediaCodecAdapter {
private final MediaCodecAsyncCallback mediaCodecAsyncCallback;
private final Handler handler;
private final MediaCodec codec;
@Nullable private IllegalStateException internalException;
private boolean flushing;
private Runnable codecStartRunnable;
/**
* Create a new {@code AsynchronousMediaCodecAdapter}.
*
* @param codec The {@link MediaCodec} to wrap.
*/
public AsynchronousMediaCodecAdapter(MediaCodec codec) {
this(codec, Assertions.checkNotNull(Looper.myLooper()));
}
@VisibleForTesting
/* package */ AsynchronousMediaCodecAdapter(MediaCodec codec, Looper looper) {
mediaCodecAsyncCallback = new MediaCodecAsyncCallback();
handler = new Handler(looper);
this.codec = codec;
this.codec.setCallback(mediaCodecAsyncCallback);
codecStartRunnable = codec::start;
}
@Override
public void start() {
codecStartRunnable.run();
}
@Override
public void queueInputBuffer(
int index, int offset, int size, long presentationTimeUs, int flags) {
codec.queueInputBuffer(index, offset, size, presentationTimeUs, flags);
}
@Override
public void queueSecureInputBuffer(
int index, int offset, CryptoInfo info, long presentationTimeUs, int flags) {
codec.queueSecureInputBuffer(
index, offset, info.getFrameworkCryptoInfo(), presentationTimeUs, flags);
}
@Override
public int dequeueInputBufferIndex() {
if (flushing) {
return MediaCodec.INFO_TRY_AGAIN_LATER;
} else {
maybeThrowException();
return mediaCodecAsyncCallback.dequeueInputBufferIndex();
}
}
@Override
public int dequeueOutputBufferIndex(MediaCodec.BufferInfo bufferInfo) {
if (flushing) {
return MediaCodec.INFO_TRY_AGAIN_LATER;
} else {
maybeThrowException();
return mediaCodecAsyncCallback.dequeueOutputBufferIndex(bufferInfo);
}
}
@Override
public MediaFormat getOutputFormat() {
return mediaCodecAsyncCallback.getOutputFormat();
}
@Override
public void flush() {
clearPendingFlushState();
flushing = true;
codec.flush();
handler.post(this::onCompleteFlush);
}
@Override
public void shutdown() {
clearPendingFlushState();
}
@VisibleForTesting
/* package */ MediaCodec.Callback getMediaCodecCallback() {
return mediaCodecAsyncCallback;
}
private void onCompleteFlush() {
flushing = false;
mediaCodecAsyncCallback.flush();
try {
codecStartRunnable.run();
} catch (IllegalStateException e) {
// Catch IllegalStateException directly so that we don't have to wrap it.
internalException = e;
} catch (Exception e) {
internalException = new IllegalStateException(e);
}
}
@VisibleForTesting
/* package */ void setCodecStartRunnable(Runnable codecStartRunnable) {
this.codecStartRunnable = codecStartRunnable;
}
private void maybeThrowException() throws IllegalStateException {
maybeThrowInternalException();
mediaCodecAsyncCallback.maybeThrowMediaCodecException();
}
private void maybeThrowInternalException() {
if (internalException != null) {
IllegalStateException e = internalException;
internalException = null;
throw e;
}
}
/** Clear state related to pending flush events. */
private void clearPendingFlushState() {
handler.removeCallbacksAndMessages(null);
internalException = null;
}
}
...@@ -73,11 +73,8 @@ public abstract class MediaCodecRenderer extends BaseRenderer { ...@@ -73,11 +73,8 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
* *
* <ul> * <ul>
* <li>{@link #OPERATION_MODE_SYNCHRONOUS} * <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}
* <li>{@link #OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD_MULTI_LOCK}
* <li>{@link #OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD_ASYNCHRONOUS_QUEUEING} * <li>{@link #OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD_ASYNCHRONOUS_QUEUEING}
* <li>{@link #OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD_MULTI_LOCK_ASYNCHRONOUS_QUEUEING}
* </ul> * </ul>
*/ */
@Documented @Documented
...@@ -85,42 +82,27 @@ public abstract class MediaCodecRenderer extends BaseRenderer { ...@@ -85,42 +82,27 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
@Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE}) @Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE})
@IntDef({ @IntDef({
OPERATION_MODE_SYNCHRONOUS, OPERATION_MODE_SYNCHRONOUS,
OPERATION_MODE_ASYNCHRONOUS_PLAYBACK_THREAD,
OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD, OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD,
OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD_MULTI_LOCK,
OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD_ASYNCHRONOUS_QUEUEING, OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD_ASYNCHRONOUS_QUEUEING,
OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD_MULTI_LOCK_ASYNCHRONOUS_QUEUEING
}) })
public @interface MediaCodecOperationMode {} public @interface MediaCodecOperationMode {}
// TODO: Refactor these constants once internal evaluation completed.
// Do not assign values 1, 3 and 5 to a new operation mode until the evaluation is completed,
// otherwise existing clients may operate one of the dropped modes.
// [Internal ref: b/132684114]
/** Operates the {@link MediaCodec} in synchronous mode. */ /** Operates the {@link MediaCodec} in synchronous mode. */
public static final int OPERATION_MODE_SYNCHRONOUS = 0; public static final int OPERATION_MODE_SYNCHRONOUS = 0;
/** /**
* Operates the {@link MediaCodec} in asynchronous mode and routes {@link MediaCodec.Callback} * 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. * callbacks to a dedicated thread.
*/ */
public static final int OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD = 2; 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;
/**
* Same as {@link #OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD}, and offloads queueing to another * Same as {@link #OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD}, and offloads queueing to another
* thread. * thread.
*/ */
public static final int OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD_ASYNCHRONOUS_QUEUEING = 4; public static final int OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD_ASYNCHRONOUS_QUEUEING = 4;
/**
* Same as {@link #OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD_MULTI_LOCK}, and offloads queueing
* to another thread.
*/
public static final int
OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD_MULTI_LOCK_ASYNCHRONOUS_QUEUEING = 5;
/** Thrown when a failure occurs instantiating a decoder. */ /** Thrown when a failure occurs instantiating a decoder. */
public static class DecoderInitializationException extends Exception { public static class DecoderInitializationException extends Exception {
...@@ -488,25 +470,13 @@ public abstract class MediaCodecRenderer extends BaseRenderer { ...@@ -488,25 +470,13 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
* <ul> * <ul>
* <li>{@link #OPERATION_MODE_SYNCHRONOUS}: The {@link MediaCodec} will operate in * <li>{@link #OPERATION_MODE_SYNCHRONOUS}: The {@link MediaCodec} will operate in
* synchronous mode. * synchronous mode.
* <li>{@link #OPERATION_MODE_ASYNCHRONOUS_PLAYBACK_THREAD}: The {@link MediaCodec} will
* operate in asynchronous mode and {@link MediaCodec.Callback} callbacks will be routed
* to the playback thread. This mode requires API level &ge; 21; if the API level is
* &le; 20, the operation mode will be set to {@link
* MediaCodecRenderer#OPERATION_MODE_SYNCHRONOUS}.
* <li>{@link #OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD}: The {@link MediaCodec} will * <li>{@link #OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD}: The {@link MediaCodec} will
* operate in asynchronous mode and {@link MediaCodec.Callback} callbacks will be routed * operate in asynchronous mode and {@link MediaCodec.Callback} callbacks will be routed
* to a dedicated thread. This mode requires API level &ge; 23; if the API level is &le; * to a dedicated thread. This mode requires API level &ge; 23; if the API level is &le;
* 22, the operation mode will be set to {@link #OPERATION_MODE_SYNCHRONOUS}. * 22, the operation mode will be set to {@link #OPERATION_MODE_SYNCHRONOUS}.
* <li>{@link #OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD_MULTI_LOCK}: Same as {@link
* #OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD} and, in addition, input buffers will
* submitted to the {@link MediaCodec} in a separate thread.
* <li>{@link #OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD_ASYNCHRONOUS_QUEUEING}: Same as * <li>{@link #OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD_ASYNCHRONOUS_QUEUEING}: Same as
* {@link #OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD} and, in addition, input buffers * {@link #OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD} and, in addition, input buffers
* will be submitted to the {@link MediaCodec} in a separate thread. * will be submitted to the {@link MediaCodec} in a separate thread.
* <li>{@link
* #OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD_MULTI_LOCK_ASYNCHRONOUS_QUEUEING}: Same
* as {@link #OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD_MULTI_LOCK} and, in addition,
* input buffers will be submitted to the {@link MediaCodec} in a separate thread.
* </ul> * </ul>
* By default, the operation mode is set to {@link * By default, the operation mode is set to {@link
* MediaCodecRenderer#OPERATION_MODE_SYNCHRONOUS}. * MediaCodecRenderer#OPERATION_MODE_SYNCHRONOUS}.
...@@ -1103,27 +1073,15 @@ public abstract class MediaCodecRenderer extends BaseRenderer { ...@@ -1103,27 +1073,15 @@ 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 == OPERATION_MODE_ASYNCHRONOUS_PLAYBACK_THREAD if (mediaCodecOperationMode == OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD
&& Util.SDK_INT >= 21) {
codecAdapter = new AsynchronousMediaCodecAdapter(codec);
} 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());
} else if (mediaCodecOperationMode == OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD_MULTI_LOCK
&& Util.SDK_INT >= 23) {
codecAdapter = new MultiLockAsyncMediaCodecAdapter(codec, getTrackType());
} else if (mediaCodecOperationMode } else if (mediaCodecOperationMode
== OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD_ASYNCHRONOUS_QUEUEING == OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD_ASYNCHRONOUS_QUEUEING
&& Util.SDK_INT >= 23) { && Util.SDK_INT >= 23) {
codecAdapter = codecAdapter =
new DedicatedThreadAsyncMediaCodecAdapter( new DedicatedThreadAsyncMediaCodecAdapter(
codec, /* enableAsynchronousQueueing= */ true, getTrackType()); codec, /* enableAsynchronousQueueing= */ true, getTrackType());
} else if (mediaCodecOperationMode
== OPERATION_MODE_ASYNCHRONOUS_DEDICATED_THREAD_MULTI_LOCK_ASYNCHRONOUS_QUEUEING
&& Util.SDK_INT >= 23) {
codecAdapter =
new MultiLockAsyncMediaCodecAdapter(
codec, /* enableAsynchronousQueueing= */ true, getTrackType());
} else { } else {
codecAdapter = new SynchronousMediaCodecAdapter(codec); codecAdapter = new SynchronousMediaCodecAdapter(codec);
} }
......
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