diff options
author | Scott Lobdell <slobdell@google.com> | 2021-03-29 16:12:49 +0000 |
---|---|---|
committer | Scott Lobdell <slobdell@google.com> | 2021-04-02 22:35:29 +0000 |
commit | 21cdef883cc867db55340b25d5c95e19b12ab383 (patch) | |
tree | 93d1444ebe783f53f5f0ae2647592723b27b3fb8 /media/java/android/media/MediaCodec.java | |
parent | 7deab3736bb5f3a92be8ac820096926dce2366ad (diff) | |
parent | d1d45f856fdf68835f5b42eacecab44e6dfa8545 (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.java | 245 |
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; } |