summaryrefslogtreecommitdiff
path: root/media/java/android/media/MediaCodec.java
diff options
context:
space:
mode:
authorScott Lobdell <slobdell@google.com>2021-03-29 16:12:49 +0000
committerScott Lobdell <slobdell@google.com>2021-04-02 22:35:29 +0000
commit21cdef883cc867db55340b25d5c95e19b12ab383 (patch)
tree93d1444ebe783f53f5f0ae2647592723b27b3fb8 /media/java/android/media/MediaCodec.java
parent7deab3736bb5f3a92be8ac820096926dce2366ad (diff)
parentd1d45f856fdf68835f5b42eacecab44e6dfa8545 (diff)
Merge SP1A.210329.001
Change-Id: I1e21c5890b5b2e2f2855f09960bc8eec8aa922bf
Diffstat (limited to 'media/java/android/media/MediaCodec.java')
-rw-r--r--media/java/android/media/MediaCodec.java245
1 files changed, 227 insertions, 18 deletions
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index cf31e4141a6d..b51777c3135a 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -25,7 +25,6 @@ import android.graphics.Rect;
import android.graphics.SurfaceTexture;
import android.hardware.HardwareBuffer;
import android.media.MediaCodecInfo.CodecCapabilities;
-import android.media.metrics.PlaybackComponent;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
@@ -46,6 +45,7 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
@@ -1539,7 +1539,7 @@ import java.util.concurrent.locks.ReentrantLock;
</tbody>
</table>
*/
-final public class MediaCodec implements PlaybackComponent {
+final public class MediaCodec {
/**
* Per buffer metadata includes an offset and size specifying
@@ -1674,9 +1674,11 @@ final public class MediaCodec implements PlaybackComponent {
public @interface BufferFlag {}
private EventHandler mEventHandler;
+ private EventHandler mOnFirstTunnelFrameReadyHandler;
private EventHandler mOnFrameRenderedHandler;
private EventHandler mCallbackHandler;
private Callback mCallback;
+ private OnFirstTunnelFrameReadyListener mOnFirstTunnelFrameReadyListener;
private OnFrameRenderedListener mOnFrameRenderedListener;
private final Object mListenerLock = new Object();
private MediaCodecInfo mCodecInfo;
@@ -1687,6 +1689,7 @@ final public class MediaCodec implements PlaybackComponent {
private static final int EVENT_CALLBACK = 1;
private static final int EVENT_SET_CALLBACK = 2;
private static final int EVENT_FRAME_RENDERED = 3;
+ private static final int EVENT_FIRST_TUNNEL_FRAME_READY = 4;
private static final int CB_INPUT_AVAILABLE = 1;
private static final int CB_OUTPUT_AVAILABLE = 2;
@@ -1694,22 +1697,6 @@ final public class MediaCodec implements PlaybackComponent {
private static final int CB_OUTPUT_FORMAT_CHANGE = 4;
- /**
- * @hide
- */
- @Override
- public void setPlaybackId(@NonNull String playbackId) {
- // TODO: add a native method to pass the ID to the native code for logging.
- mPlaybackId = playbackId;
- }
- /**
- * @hide
- */
- @Override
- public String getPlaybackId() {
- return mPlaybackId;
- }
-
private class EventHandler extends Handler {
private MediaCodec mCodec;
@@ -1748,6 +1735,16 @@ final public class MediaCodec implements PlaybackComponent {
mCodec, (long)mediaTimeUs, (long)systemNano);
}
break;
+ case EVENT_FIRST_TUNNEL_FRAME_READY:
+ OnFirstTunnelFrameReadyListener onFirstTunnelFrameReadyListener;
+ synchronized (mListenerLock) {
+ onFirstTunnelFrameReadyListener = mOnFirstTunnelFrameReadyListener;
+ }
+ if (onFirstTunnelFrameReadyListener == null) {
+ break;
+ }
+ onFirstTunnelFrameReadyListener.onFirstTunnelFrameReady(mCodec);
+ break;
default:
{
break;
@@ -1923,6 +1920,7 @@ final public class MediaCodec implements PlaybackComponent {
mEventHandler = null;
}
mCallbackHandler = mEventHandler;
+ mOnFirstTunnelFrameReadyHandler = mEventHandler;
mOnFrameRenderedHandler = mEventHandler;
mBufferLock = new Object();
@@ -2277,6 +2275,9 @@ final public class MediaCodec implements PlaybackComponent {
mCallbackHandler.removeMessages(EVENT_SET_CALLBACK);
mCallbackHandler.removeMessages(EVENT_CALLBACK);
}
+ if (mOnFirstTunnelFrameReadyHandler != null) {
+ mOnFirstTunnelFrameReadyHandler.removeMessages(EVENT_FIRST_TUNNEL_FRAME_READY);
+ }
if (mOnFrameRenderedHandler != null) {
mOnFrameRenderedHandler.removeMessages(EVENT_FRAME_RENDERED);
}
@@ -4447,6 +4448,41 @@ final public class MediaCodec implements PlaybackComponent {
MediaFormat.KEY_LOW_LATENCY;
/**
+ * Control video peek of the first frame when a codec is configured for tunnel mode with
+ * {@link MediaFormat#KEY_AUDIO_SESSION_ID} while the {@link AudioTrack} is paused.
+ *<p>
+ * When disabled (1) after a {@link #flush} or {@link #start}, (2) while the corresponding
+ * {@link AudioTrack} is paused and (3) before any buffers are queued, the first frame is not to
+ * be rendered until either this parameter is enabled or the corresponding {@link AudioTrack}
+ * has begun playback. Once the frame is decoded and ready to be rendered,
+ * {@link OnFirstTunnelFrameReadyListener#onFirstTunnelFrameReady} is called but the frame is
+ * not rendered. The surface continues to show the previously-rendered content, or black if the
+ * surface is new. A subsequent call to {@link AudioTrack#play} renders this frame and triggers
+ * a callback to {@link OnFrameRenderedListener#onFrameRendered}, and video playback begins.
+ *<p>
+ * <b>Note</b>: To clear any previously rendered content and show black, configure the
+ * MediaCodec with {@code KEY_PUSH_BLANK_BUFFERS_ON_STOP(1)}, and call {@link #stop} before
+ * pushing new video frames to the codec.
+ *<p>
+ * When enabled (1) after a {@link #flush} or {@link #start} and (2) while the corresponding
+ * {@link AudioTrack} is paused, the first frame is rendered as soon as it is decoded, or
+ * immediately, if it has already been decoded. If not already decoded, when the frame is
+ * decoded and ready to be rendered,
+ * {@link OnFirstTunnelFrameReadyListener#onFirstTunnelFrameReady} is called. The frame is then
+ * immediately rendered and {@link OnFrameRenderedListener#onFrameRendered} is subsequently
+ * called.
+ *<p>
+ * The value is an Integer object containing the value 1 to enable or the value 0 to disable.
+ *<p>
+ * The default for this parameter is <b>enabled</b>. Once a frame has been rendered, changing
+ * this parameter has no effect until a subsequent {@link #flush} or
+ * {@link #stop}/{@link #start}.
+ *
+ * @see #setParameters(Bundle)
+ */
+ public static final String PARAMETER_KEY_TUNNEL_PEEK = "tunnel-peek";
+
+ /**
* Communicate additional parameter changes to the component instance.
* <b>Note:</b> Some of these parameter changes may silently fail to apply.
*
@@ -4545,6 +4581,55 @@ final public class MediaCodec implements PlaybackComponent {
}
/**
+ * Listener to be called when the first output frame has been decoded
+ * and is ready to be rendered for a codec configured for tunnel mode with
+ * {@code KEY_AUDIO_SESSION_ID}.
+ *
+ * @see MediaCodec#setOnFirstTunnelFrameReadyListener
+ */
+ public interface OnFirstTunnelFrameReadyListener {
+
+ /**
+ * Called when the first output frame has been decoded and is ready to be
+ * rendered.
+ */
+ void onFirstTunnelFrameReady(@NonNull MediaCodec codec);
+ }
+
+ /**
+ * Registers a callback to be invoked when the first output frame has been decoded
+ * and is ready to be rendered on a codec configured for tunnel mode with {@code
+ * KEY_AUDIO_SESSION_ID}.
+ *
+ * @param handler the callback will be run on the handler's thread. If {@code
+ * null}, the callback will be run on the default thread, which is the looper from
+ * which the codec was created, or a new thread if there was none.
+ *
+ * @param listener the callback that will be run. If {@code null}, clears any registered
+ * listener.
+ */
+ public void setOnFirstTunnelFrameReadyListener(
+ @Nullable Handler handler, @Nullable OnFirstTunnelFrameReadyListener listener) {
+ synchronized (mListenerLock) {
+ mOnFirstTunnelFrameReadyListener = listener;
+ if (listener != null) {
+ EventHandler newHandler = getEventHandlerOn(
+ handler,
+ mOnFirstTunnelFrameReadyHandler);
+ if (newHandler != mOnFirstTunnelFrameReadyHandler) {
+ mOnFirstTunnelFrameReadyHandler.removeMessages(EVENT_FIRST_TUNNEL_FRAME_READY);
+ }
+ mOnFirstTunnelFrameReadyHandler = newHandler;
+ } else if (mOnFirstTunnelFrameReadyHandler != null) {
+ mOnFirstTunnelFrameReadyHandler.removeMessages(EVENT_FIRST_TUNNEL_FRAME_READY);
+ }
+ native_enableOnFirstTunnelFrameReadyListener(listener != null);
+ }
+ }
+
+ private native void native_enableOnFirstTunnelFrameReadyListener(boolean enable);
+
+ /**
* Listener to be called when an output frame has rendered on the output surface
*
* @see MediaCodec#setOnFrameRenderedListener
@@ -4606,6 +4691,128 @@ final public class MediaCodec implements PlaybackComponent {
private native void native_enableOnFrameRenderedListener(boolean enable);
+ /**
+ * Returns a list of vendor parameter names.
+ * <p>
+ * This method can be called in any codec state except for released state.
+ *
+ * @return a list containing supported vendor parameters; an empty
+ * list if no vendor parameters are supported. The order of the
+ * parameters is arbitrary.
+ * @throws IllegalStateException if in the Released state.
+ */
+ @NonNull
+ public List<String> getSupportedVendorParameters() {
+ return native_getSupportedVendorParameters();
+ }
+
+ @NonNull
+ private native List<String> native_getSupportedVendorParameters();
+
+ /**
+ * Contains description of a parameter.
+ */
+ public static class ParameterDescriptor {
+ private ParameterDescriptor() {}
+
+ /**
+ * Returns the name of the parameter.
+ */
+ @NonNull
+ public String getName() {
+ return mName;
+ }
+
+ /**
+ * Returns the type of the parameter.
+ * {@link MediaFormat#TYPE_NULL} is never returned.
+ */
+ @MediaFormat.Type
+ public int getType() {
+ return mType;
+ }
+
+ private String mName;
+ private @MediaFormat.Type int mType;
+ }
+
+ /**
+ * Describe a parameter with the name.
+ * <p>
+ * This method can be called in any codec state except for released state.
+ *
+ * @param name name of the parameter to describe, typically one from
+ * {@link #getSupportedVendorParameters}.
+ * @return {@link ParameterDescriptor} object that describes the parameter.
+ * {@code null} if unrecognized / not able to describe.
+ * @throws IllegalStateException if in the Released state.
+ */
+ @Nullable
+ public ParameterDescriptor getParameterDescriptor(@NonNull String name) {
+ return native_getParameterDescriptor(name);
+ }
+
+ @Nullable
+ private native ParameterDescriptor native_getParameterDescriptor(@NonNull String name);
+
+ /**
+ * Subscribe to vendor parameters, so that changes to these parameters generate
+ * output format change event.
+ * <p>
+ * Unrecognized parameter names or standard (non-vendor) parameter names will be ignored.
+ * {@link #reset} also resets the list of subscribed parameters.
+ * If a parameter in {@code names} is already subscribed, it will remain subscribed.
+ * <p>
+ * This method can be called in any codec state except for released state. When called in
+ * running state with newly subscribed parameters, it takes effect no later than the
+ * processing of the subsequently queued buffer. For the new parameters, the codec will generate
+ * output format change event.
+ * <p>
+ * Note that any vendor parameters set in a {@link #configure} or
+ * {@link #setParameters} call are automatically subscribed.
+ * <p>
+ * See also {@link #INFO_OUTPUT_FORMAT_CHANGED} or {@link Callback#onOutputFormatChanged}
+ * for output format change events.
+ *
+ * @param names names of the vendor parameters to subscribe. This may be an empty list,
+ * and in that case this method will not change the list of subscribed parameters.
+ * @throws IllegalStateException if in the Released state.
+ */
+ public void subscribeToVendorParameters(@NonNull List<String> names) {
+ native_subscribeToVendorParameters(names);
+ }
+
+ private native void native_subscribeToVendorParameters(@NonNull List<String> names);
+
+ /**
+ * Unsubscribe from vendor parameters, so that changes to these parameters
+ * no longer generate output format change event.
+ * <p>
+ * Unrecognized parameter names, standard (non-vendor) parameter names will be ignored.
+ * {@link #reset} also resets the list of subscribed parameters.
+ * If a parameter in {@code names} is already unsubscribed, it will remain unsubscribed.
+ * <p>
+ * This method can be called in any codec state except for released state. When called in
+ * running state with newly unsubscribed parameters, it takes effect no later than the
+ * processing of the subsequently queued buffer.
+ * <p>
+ * Note that any vendor parameters set in a {@link #configure} or
+ * {@link #setParameters} call are automatically subscribed, and with this method
+ * they can be unsubscribed.
+ * <p>
+ * See also {@link #INFO_OUTPUT_FORMAT_CHANGED} or {@link Callback#onOutputFormatChanged}
+ * for output format change events.
+ *
+ * @param names names of the vendor parameters to unsubscribe. This may be an empty list,
+ * and in that case this method will not change the list of subscribed parameters.
+ * @throws IllegalStateException if in the Released state.
+ */
+ public void unsubscribeFromVendorParameters(@NonNull List<String> names) {
+ native_unsubscribeFromVendorParameters(names);
+ }
+
+ private native void native_unsubscribeFromVendorParameters(@NonNull List<String> names);
+
private EventHandler getEventHandlerOn(
@Nullable Handler handler, @NonNull EventHandler lastHandler) {
if (handler == null) {
@@ -4667,6 +4874,8 @@ final public class MediaCodec implements PlaybackComponent {
EventHandler handler = mEventHandler;
if (what == EVENT_CALLBACK) {
handler = mCallbackHandler;
+ } else if (what == EVENT_FIRST_TUNNEL_FRAME_READY) {
+ handler = mOnFirstTunnelFrameReadyHandler;
} else if (what == EVENT_FRAME_RENDERED) {
handler = mOnFrameRenderedHandler;
}