/*
 * Copyright (C) 2012 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 android.media;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;
import android.graphics.ImageFormat;
import android.graphics.Rect;
import android.graphics.SurfaceTexture;
import android.media.MediaCodecInfo.CodecCapabilities;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IHwBinder;
import android.os.Looper;
import android.os.Message;
import android.os.PersistableBundle;
import android.view.Surface;

import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.ReadOnlyBufferException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 MediaCodec class can be used to access low-level media codecs, i.e. encoder/decoder components.
 It is part of the Android low-level multimedia support infrastructure (normally used together
 with {@link MediaExtractor}, {@link MediaSync}, {@link MediaMuxer}, {@link MediaCrypto},
 {@link MediaDrm}, {@link Image}, {@link Surface}, and {@link AudioTrack}.)
 <p>
 <center><object style="width: 540px; height: 205px;" type="image/svg+xml"
   data="../../../images/media/mediacodec_buffers.svg"><img
   src="../../../images/media/mediacodec_buffers.png" style="width: 540px; height: 205px"
   alt="MediaCodec buffer flow diagram"></object></center>
 <p>
 In broad terms, a codec processes input data to generate output data. It processes data
 asynchronously and uses a set of input and output buffers. At a simplistic level, you request
 (or receive) an empty input buffer, fill it up with data and send it to the codec for
 processing. The codec uses up the data and transforms it into one of its empty output buffers.
 Finally, you request (or receive) a filled output buffer, consume its contents and release it
 back to the codec.

 <h3>Data Types</h3>
 <p>
 Codecs operate on three kinds of data: compressed data, raw audio data and raw video data.
 All three kinds of data can be processed using {@link ByteBuffer ByteBuffers}, but you should use
 a {@link Surface} for raw video data to improve codec performance. Surface uses native video
 buffers without mapping or copying them to ByteBuffers; thus, it is much more efficient.
 You normally cannot access the raw video data when using a Surface, but you can use the
 {@link ImageReader} class to access unsecured decoded (raw) video frames. This may still be more
 efficient than using ByteBuffers, as some native buffers may be mapped into {@linkplain
 ByteBuffer#isDirect direct} ByteBuffers. When using ByteBuffer mode, you can access raw video
 frames using the {@link Image} class and {@link #getInputImage getInput}/{@link #getOutputImage
 OutputImage(int)}.

 <h4>Compressed Buffers</h4>
 <p>
 Input buffers (for decoders) and output buffers (for encoders) contain compressed data according
 to the {@linkplain MediaFormat#KEY_MIME format's type}. For video types this is normally a single
 compressed video frame. For audio data this is normally a single access unit (an encoded audio
 segment typically containing a few milliseconds of audio as dictated by the format type), but
 this requirement is slightly relaxed in that a buffer may contain multiple encoded access units
 of audio. In either case, buffers do not start or end on arbitrary byte boundaries, but rather on
 frame/access unit boundaries unless they are flagged with {@link #BUFFER_FLAG_PARTIAL_FRAME}.

 <h4>Raw Audio Buffers</h4>
 <p>
 Raw audio buffers contain entire frames of PCM audio data, which is one sample for each channel
 in channel order. Each PCM audio sample is either a 16 bit signed integer or a float,
 in native byte order.
 Raw audio buffers in the float PCM encoding are only possible
 if the MediaFormat's {@linkplain MediaFormat#KEY_PCM_ENCODING}
 is set to {@linkplain AudioFormat#ENCODING_PCM_FLOAT} during MediaCodec
 {@link #configure configure(&hellip;)}
 and confirmed by {@link #getOutputFormat} for decoders
 or {@link #getInputFormat} for encoders.
 A sample method to check for float PCM in the MediaFormat is as follows:

 <pre class=prettyprint>
 static boolean isPcmFloat(MediaFormat format) {
   return format.getInteger(MediaFormat.KEY_PCM_ENCODING, AudioFormat.ENCODING_PCM_16BIT)
       == AudioFormat.ENCODING_PCM_FLOAT;
 }</pre>

 In order to extract, in a short array,
 one channel of a buffer containing 16 bit signed integer audio data,
 the following code may be used:

 <pre class=prettyprint>
 // Assumes the buffer PCM encoding is 16 bit.
 short[] getSamplesForChannel(MediaCodec codec, int bufferId, int channelIx) {
   ByteBuffer outputBuffer = codec.getOutputBuffer(bufferId);
   MediaFormat format = codec.getOutputFormat(bufferId);
   ShortBuffer samples = outputBuffer.order(ByteOrder.nativeOrder()).asShortBuffer();
   int numChannels = format.getInteger(MediaFormat.KEY_CHANNEL_COUNT);
   if (channelIx &lt; 0 || channelIx &gt;= numChannels) {
     return null;
   }
   short[] res = new short[samples.remaining() / numChannels];
   for (int i = 0; i &lt; res.length; ++i) {
     res[i] = samples.get(i * numChannels + channelIx);
   }
   return res;
 }</pre>

 <h4>Raw Video Buffers</h4>
 <p>
 In ByteBuffer mode video buffers are laid out according to their {@linkplain
 MediaFormat#KEY_COLOR_FORMAT color format}. You can get the supported color formats as an array
 from {@link #getCodecInfo}{@code .}{@link MediaCodecInfo#getCapabilitiesForType
 getCapabilitiesForType(&hellip;)}{@code .}{@link CodecCapabilities#colorFormats colorFormats}.
 Video codecs may support three kinds of color formats:
 <ul>
 <li><strong>native raw video format:</strong> This is marked by {@link
 CodecCapabilities#COLOR_FormatSurface} and it can be used with an input or output Surface.</li>
 <li><strong>flexible YUV buffers</strong> (such as {@link
 CodecCapabilities#COLOR_FormatYUV420Flexible}): These can be used with an input/output Surface,
 as well as in ByteBuffer mode, by using {@link #getInputImage getInput}/{@link #getOutputImage
 OutputImage(int)}.</li>
 <li><strong>other, specific formats:</strong> These are normally only supported in ByteBuffer
 mode. Some color formats are vendor specific. Others are defined in {@link CodecCapabilities}.
 For color formats that are equivalent to a flexible format, you can still use {@link
 #getInputImage getInput}/{@link #getOutputImage OutputImage(int)}.</li>
 </ul>
 <p>
 All video codecs support flexible YUV 4:2:0 buffers since {@link
 android.os.Build.VERSION_CODES#LOLLIPOP_MR1}.

 <h4>Accessing Raw Video ByteBuffers on Older Devices</h4>
 <p>
 Prior to {@link android.os.Build.VERSION_CODES#LOLLIPOP} and {@link Image} support, you need to
 use the {@link MediaFormat#KEY_STRIDE} and {@link MediaFormat#KEY_SLICE_HEIGHT} output format
 values to understand the layout of the raw output buffers.
 <p class=note>
 Note that on some devices the slice-height is advertised as 0. This could mean either that the
 slice-height is the same as the frame height, or that the slice-height is the frame height
 aligned to some value (usually a power of 2). Unfortunately, there is no standard and simple way
 to tell the actual slice height in this case. Furthermore, the vertical stride of the {@code U}
 plane in planar formats is also not specified or defined, though usually it is half of the slice
 height.
 <p>
 The {@link MediaFormat#KEY_WIDTH} and {@link MediaFormat#KEY_HEIGHT} keys specify the size of the
 video frames; however, for most encondings the video (picture) only occupies a portion of the
 video frame. This is represented by the 'crop rectangle'.
 <p>
 You need to use the following keys to get the crop rectangle of raw output images from the
 {@linkplain #getOutputFormat output format}. If these keys are not present, the video occupies the
 entire video frame.The crop rectangle is understood in the context of the output frame
 <em>before</em> applying any {@linkplain MediaFormat#KEY_ROTATION rotation}.
 <table style="width: 0%">
  <thead>
   <tr>
    <th>Format Key</th>
    <th>Type</th>
    <th>Description</th>
   </tr>
  </thead>
  <tbody>
   <tr>
    <td>{@code "crop-left"}</td>
    <td>Integer</td>
    <td>The left-coordinate (x) of the crop rectangle</td>
   </tr><tr>
    <td>{@code "crop-top"}</td>
    <td>Integer</td>
    <td>The top-coordinate (y) of the crop rectangle</td>
   </tr><tr>
    <td>{@code "crop-right"}</td>
    <td>Integer</td>
    <td>The right-coordinate (x) <strong>MINUS 1</strong> of the crop rectangle</td>
   </tr><tr>
    <td>{@code "crop-bottom"}</td>
    <td>Integer</td>
    <td>The bottom-coordinate (y) <strong>MINUS 1</strong> of the crop rectangle</td>
   </tr><tr>
    <td colspan=3>
     The right and bottom coordinates can be understood as the coordinates of the right-most
     valid column/bottom-most valid row of the cropped output image.
    </td>
   </tr>
  </tbody>
 </table>
 <p>
 The size of the video frame (before rotation) can be calculated as such:
 <pre class=prettyprint>
 MediaFormat format = decoder.getOutputFormat(&hellip;);
 int width = format.getInteger(MediaFormat.KEY_WIDTH);
 if (format.containsKey("crop-left") && format.containsKey("crop-right")) {
     width = format.getInteger("crop-right") + 1 - format.getInteger("crop-left");
 }
 int height = format.getInteger(MediaFormat.KEY_HEIGHT);
 if (format.containsKey("crop-top") && format.containsKey("crop-bottom")) {
     height = format.getInteger("crop-bottom") + 1 - format.getInteger("crop-top");
 }
 </pre>
 <p class=note>
 Also note that the meaning of {@link BufferInfo#offset BufferInfo.offset} was not consistent across
 devices. On some devices the offset pointed to the top-left pixel of the crop rectangle, while on
 most devices it pointed to the top-left pixel of the entire frame.

 <h3>States</h3>
 <p>
 During its life a codec conceptually exists in one of three states: Stopped, Executing or
 Released. The Stopped collective state is actually the conglomeration of three states:
 Uninitialized, Configured and Error, whereas the Executing state conceptually progresses through
 three sub-states: Flushed, Running and End-of-Stream.
 <p>
 <center><object style="width: 516px; height: 353px;" type="image/svg+xml"
   data="../../../images/media/mediacodec_states.svg"><img
   src="../../../images/media/mediacodec_states.png" style="width: 519px; height: 356px"
   alt="MediaCodec state diagram"></object></center>
 <p>
 When you create a codec using one of the factory methods, the codec is in the Uninitialized
 state. First, you need to configure it via {@link #configure configure(&hellip;)}, which brings
 it to the Configured state, then call {@link #start} to move it to the Executing state. In this
 state you can process data through the buffer queue manipulation described above.
 <p>
 The Executing state has three sub-states: Flushed, Running and End-of-Stream. Immediately after
 {@link #start} the codec is in the Flushed sub-state, where it holds all the buffers. As soon
 as the first input buffer is dequeued, the codec moves to the Running sub-state, where it spends
 most of its life. When you queue an input buffer with the {@linkplain #BUFFER_FLAG_END_OF_STREAM
 end-of-stream marker}, the codec transitions to the End-of-Stream sub-state. In this state the
 codec no longer accepts further input buffers, but still generates output buffers until the
 end-of-stream is reached on the output. You can move back to the Flushed sub-state at any time
 while in the Executing state using {@link #flush}.
 <p>
 Call {@link #stop} to return the codec to the Uninitialized state, whereupon it may be configured
 again. When you are done using a codec, you must release it by calling {@link #release}.
 <p>
 On rare occasions the codec may encounter an error and move to the Error state. This is
 communicated using an invalid return value from a queuing operation, or sometimes via an
 exception. Call {@link #reset} to make the codec usable again. You can call it from any state to
 move the codec back to the Uninitialized state. Otherwise, call {@link #release} to move to the
 terminal Released state.

 <h3>Creation</h3>
 <p>
 Use {@link MediaCodecList} to create a MediaCodec for a specific {@link MediaFormat}. When
 decoding a file or a stream, you can get the desired format from {@link
 MediaExtractor#getTrackFormat MediaExtractor.getTrackFormat}. Inject any specific features that
 you want to add using {@link MediaFormat#setFeatureEnabled MediaFormat.setFeatureEnabled}, then
 call {@link MediaCodecList#findDecoderForFormat MediaCodecList.findDecoderForFormat} to get the
 name of a codec that can handle that specific media format. Finally, create the codec using
 {@link #createByCodecName}.
 <p class=note>
 <strong>Note:</strong> On {@link android.os.Build.VERSION_CODES#LOLLIPOP}, the format to
 {@code MediaCodecList.findDecoder}/{@code EncoderForFormat} must not contain a {@linkplain
 MediaFormat#KEY_FRAME_RATE frame rate}. Use
 <code class=prettyprint>format.setString(MediaFormat.KEY_FRAME_RATE, null)</code>
 to clear any existing frame rate setting in the format.
 <p>
 You can also create the preferred codec for a specific MIME type using {@link
 #createDecoderByType createDecoder}/{@link #createEncoderByType EncoderByType(String)}.
 This, however, cannot be used to inject features, and may create a codec that cannot handle the
 specific desired media format.

 <h4>Creating secure decoders</h4>
 <p>
 On versions {@link android.os.Build.VERSION_CODES#KITKAT_WATCH} and earlier, secure codecs might
 not be listed in {@link MediaCodecList}, but may still be available on the system. Secure codecs
 that exist can be instantiated by name only, by appending {@code ".secure"} to the name of a
 regular codec (the name of all secure codecs must end in {@code ".secure"}.) {@link
 #createByCodecName} will throw an {@code IOException} if the codec is not present on the system.
 <p>
 From {@link android.os.Build.VERSION_CODES#LOLLIPOP} onwards, you should use the {@link
 CodecCapabilities#FEATURE_SecurePlayback} feature in the media format to create a secure decoder.

 <h3>Initialization</h3>
 <p>
 After creating the codec, you can set a callback using {@link #setCallback setCallback} if you
 want to process data asynchronously. Then, {@linkplain #configure configure} the codec using the
 specific media format. This is when you can specify the output {@link Surface} for video
 producers &ndash; codecs that generate raw video data (e.g. video decoders). This is also when
 you can set the decryption parameters for secure codecs (see {@link MediaCrypto}). Finally, since
 some codecs can operate in multiple modes, you must specify whether you want it to work as a
 decoder or an encoder.
 <p>
 Since {@link android.os.Build.VERSION_CODES#LOLLIPOP}, you can query the resulting input and
 output format in the Configured state. You can use this to verify the resulting configuration,
 e.g. color formats, before starting the codec.
 <p>
 If you want to process raw input video buffers natively with a video consumer &ndash; a codec
 that processes raw video input, such as a video encoder &ndash; create a destination Surface for
 your input data using {@link #createInputSurface} after configuration. Alternately, set up the
 codec to use a previously created {@linkplain #createPersistentInputSurface persistent input
 surface} by calling {@link #setInputSurface}.

 <h4 id=CSD><a name="CSD"></a>Codec-specific Data</h4>
 <p>
 Some formats, notably AAC audio and MPEG4, H.264 and H.265 video formats require the actual data
 to be prefixed by a number of buffers containing setup data, or codec specific data. When
 processing such compressed formats, this data must be submitted to the codec after {@link
 #start} and before any frame data. Such data must be marked using the flag {@link
 #BUFFER_FLAG_CODEC_CONFIG} in a call to {@link #queueInputBuffer queueInputBuffer}.
 <p>
 Codec-specific data can also be included in the format passed to {@link #configure configure} in
 ByteBuffer entries with keys "csd-0", "csd-1", etc. These keys are always included in the track
 {@link MediaFormat} obtained from the {@link MediaExtractor#getTrackFormat MediaExtractor}.
 Codec-specific data in the format is automatically submitted to the codec upon {@link #start};
 you <strong>MUST NOT</strong> submit this data explicitly. If the format did not contain codec
 specific data, you can choose to submit it using the specified number of buffers in the correct
 order, according to the format requirements. In case of H.264 AVC, you can also concatenate all
 codec-specific data and submit it as a single codec-config buffer.
 <p>
 Android uses the following codec-specific data buffers. These are also required to be set in
 the track format for proper {@link MediaMuxer} track configuration. Each parameter set and the
 codec-specific-data sections marked with (<sup>*</sup>) must start with a start code of
 {@code "\x00\x00\x00\x01"}.
 <p>
 <style>td.NA { background: #ccc; } .mid > tr > td { vertical-align: middle; }</style>
 <table>
  <thead>
   <th>Format</th>
   <th>CSD buffer #0</th>
   <th>CSD buffer #1</th>
   <th>CSD buffer #2</th>
  </thead>
  <tbody class=mid>
   <tr>
    <td>AAC</td>
    <td>Decoder-specific information from ESDS<sup>*</sup></td>
    <td class=NA>Not Used</td>
    <td class=NA>Not Used</td>
   </tr>
   <tr>
    <td>VORBIS</td>
    <td>Identification header</td>
    <td>Setup header</td>
    <td class=NA>Not Used</td>
   </tr>
   <tr>
    <td>OPUS</td>
    <td>Identification header</td>
    <td>Pre-skip in nanosecs<br>
        (unsigned 64-bit {@linkplain ByteOrder#nativeOrder native-order} integer.)<br>
        This overrides the pre-skip value in the identification header.</td>
    <td>Seek Pre-roll in nanosecs<br>
        (unsigned 64-bit {@linkplain ByteOrder#nativeOrder native-order} integer.)</td>
   </tr>
   <tr>
    <td>FLAC</td>
    <td>"fLaC", the FLAC stream marker in ASCII,<br>
        followed by the STREAMINFO block (the mandatory metadata block),<br>
        optionally followed by any number of other metadata blocks</td>
    <td class=NA>Not Used</td>
    <td class=NA>Not Used</td>
   </tr>
   <tr>
    <td>MPEG-4</td>
    <td>Decoder-specific information from ESDS<sup>*</sup></td>
    <td class=NA>Not Used</td>
    <td class=NA>Not Used</td>
   </tr>
   <tr>
    <td>H.264 AVC</td>
    <td>SPS (Sequence Parameter Sets<sup>*</sup>)</td>
    <td>PPS (Picture Parameter Sets<sup>*</sup>)</td>
    <td class=NA>Not Used</td>
   </tr>
   <tr>
    <td>H.265 HEVC</td>
    <td>VPS (Video Parameter Sets<sup>*</sup>) +<br>
     SPS (Sequence Parameter Sets<sup>*</sup>) +<br>
     PPS (Picture Parameter Sets<sup>*</sup>)</td>
    <td class=NA>Not Used</td>
    <td class=NA>Not Used</td>
   </tr>
   <tr>
    <td>VP9</td>
    <td>VP9 <a href="http://wiki.webmproject.org/vp9-codecprivate">CodecPrivate</a> Data
        (optional)</td>
    <td class=NA>Not Used</td>
    <td class=NA>Not Used</td>
   </tr>
  </tbody>
 </table>

 <p class=note>
 <strong>Note:</strong> care must be taken if the codec is flushed immediately or shortly
 after start, before any output buffer or output format change has been returned, as the codec
 specific data may be lost during the flush. You must resubmit the data using buffers marked with
 {@link #BUFFER_FLAG_CODEC_CONFIG} after such flush to ensure proper codec operation.
 <p>
 Encoders (or codecs that generate compressed data) will create and return the codec specific data
 before any valid output buffer in output buffers marked with the {@linkplain
 #BUFFER_FLAG_CODEC_CONFIG codec-config flag}. Buffers containing codec-specific-data have no
 meaningful timestamps.

 <h3>Data Processing</h3>
 <p>
 Each codec maintains a set of input and output buffers that are referred to by a buffer-ID in
 API calls. After a successful call to {@link #start} the client "owns" neither input nor output
 buffers. In synchronous mode, call {@link #dequeueInputBuffer dequeueInput}/{@link
 #dequeueOutputBuffer OutputBuffer(&hellip;)} to obtain (get ownership of) an input or output
 buffer from the codec. In asynchronous mode, you will automatically receive available buffers via
 the {@link Callback#onInputBufferAvailable MediaCodec.Callback.onInput}/{@link
 Callback#onOutputBufferAvailable OutputBufferAvailable(&hellip;)} callbacks.
 <p>
 Upon obtaining an input buffer, fill it with data and submit it to the codec using {@link
 #queueInputBuffer queueInputBuffer} &ndash; or {@link #queueSecureInputBuffer
 queueSecureInputBuffer} if using decryption. Do not submit multiple input buffers with the same
 timestamp (unless it is <a href="#CSD">codec-specific data</a> marked as such).
 <p>
 The codec in turn will return a read-only output buffer via the {@link
 Callback#onOutputBufferAvailable onOutputBufferAvailable} callback in asynchronous mode, or in
 response to a {@link #dequeueOutputBuffer dequeueOutputBuffer} call in synchronous mode. After the
 output buffer has been processed, call one of the {@link #releaseOutputBuffer
 releaseOutputBuffer} methods to return the buffer to the codec.
 <p>
 While you are not required to resubmit/release buffers immediately to the codec, holding onto
 input and/or output buffers may stall the codec, and this behavior is device dependent.
 <strong>Specifically, it is possible that a codec may hold off on generating output buffers until
 <em>all</em> outstanding buffers have been released/resubmitted.</strong> Therefore, try to
 hold onto to available buffers as little as possible.
 <p>
 Depending on the API version, you can process data in three ways:
 <table>
  <thead>
   <tr>
    <th>Processing Mode</th>
    <th>API version <= 20<br>Jelly Bean/KitKat</th>
    <th>API version >= 21<br>Lollipop and later</th>
   </tr>
  </thead>
  <tbody>
   <tr>
    <td>Synchronous API using buffer arrays</td>
    <td>Supported</td>
    <td>Deprecated</td>
   </tr>
   <tr>
    <td>Synchronous API using buffers</td>
    <td class=NA>Not Available</td>
    <td>Supported</td>
   </tr>
   <tr>
    <td>Asynchronous API using buffers</td>
    <td class=NA>Not Available</td>
    <td>Supported</td>
   </tr>
  </tbody>
 </table>

 <h4>Asynchronous Processing using Buffers</h4>
 <p>
 Since {@link android.os.Build.VERSION_CODES#LOLLIPOP}, the preferred method is to process data
 asynchronously by setting a callback before calling {@link #configure configure}. Asynchronous
 mode changes the state transitions slightly, because you must call {@link #start} after {@link
 #flush} to transition the codec to the Running sub-state and start receiving input buffers.
 Similarly, upon an initial call to {@code start} the codec will move directly to the Running
 sub-state and start passing available input buffers via the callback.
 <p>
 <center><object style="width: 516px; height: 353px;" type="image/svg+xml"
   data="../../../images/media/mediacodec_async_states.svg"><img
   src="../../../images/media/mediacodec_async_states.png" style="width: 516px; height: 353px"
   alt="MediaCodec state diagram for asynchronous operation"></object></center>
 <p>
 MediaCodec is typically used like this in asynchronous mode:
 <pre class=prettyprint>
 MediaCodec codec = MediaCodec.createByCodecName(name);
 MediaFormat mOutputFormat; // member variable
 codec.setCallback(new MediaCodec.Callback() {
   {@literal @Override}
   void onInputBufferAvailable(MediaCodec mc, int inputBufferId) {
     ByteBuffer inputBuffer = codec.getInputBuffer(inputBufferId);
     // fill inputBuffer with valid data
     &hellip;
     codec.queueInputBuffer(inputBufferId, &hellip;);
   }

   {@literal @Override}
   void onOutputBufferAvailable(MediaCodec mc, int outputBufferId, &hellip;) {
     ByteBuffer outputBuffer = codec.getOutputBuffer(outputBufferId);
     MediaFormat bufferFormat = codec.getOutputFormat(outputBufferId); // option A
     // bufferFormat is equivalent to mOutputFormat
     // outputBuffer is ready to be processed or rendered.
     &hellip;
     codec.releaseOutputBuffer(outputBufferId, &hellip;);
   }

   {@literal @Override}
   void onOutputFormatChanged(MediaCodec mc, MediaFormat format) {
     // Subsequent data will conform to new format.
     // Can ignore if using getOutputFormat(outputBufferId)
     mOutputFormat = format; // option B
   }

   {@literal @Override}
   void onError(&hellip;) {
     &hellip;
   }
 });
 codec.configure(format, &hellip;);
 mOutputFormat = codec.getOutputFormat(); // option B
 codec.start();
 // wait for processing to complete
 codec.stop();
 codec.release();</pre>

 <h4>Synchronous Processing using Buffers</h4>
 <p>
 Since {@link android.os.Build.VERSION_CODES#LOLLIPOP}, you should retrieve input and output
 buffers using {@link #getInputBuffer getInput}/{@link #getOutputBuffer OutputBuffer(int)} and/or
 {@link #getInputImage getInput}/{@link #getOutputImage OutputImage(int)} even when using the
 codec in synchronous mode. This allows certain optimizations by the framework, e.g. when
 processing dynamic content. This optimization is disabled if you call {@link #getInputBuffers
 getInput}/{@link #getOutputBuffers OutputBuffers()}.

 <p class=note>
 <strong>Note:</strong> do not mix the methods of using buffers and buffer arrays at the same
 time. Specifically, only call {@code getInput}/{@code OutputBuffers} directly after {@link
 #start} or after having dequeued an output buffer ID with the value of {@link
 #INFO_OUTPUT_FORMAT_CHANGED}.
 <p>
 MediaCodec is typically used like this in synchronous mode:
 <pre>
 MediaCodec codec = MediaCodec.createByCodecName(name);
 codec.configure(format, &hellip;);
 MediaFormat outputFormat = codec.getOutputFormat(); // option B
 codec.start();
 for (;;) {
   int inputBufferId = codec.dequeueInputBuffer(timeoutUs);
   if (inputBufferId &gt;= 0) {
     ByteBuffer inputBuffer = codec.getInputBuffer(&hellip;);
     // fill inputBuffer with valid data
     &hellip;
     codec.queueInputBuffer(inputBufferId, &hellip;);
   }
   int outputBufferId = codec.dequeueOutputBuffer(&hellip;);
   if (outputBufferId &gt;= 0) {
     ByteBuffer outputBuffer = codec.getOutputBuffer(outputBufferId);
     MediaFormat bufferFormat = codec.getOutputFormat(outputBufferId); // option A
     // bufferFormat is identical to outputFormat
     // outputBuffer is ready to be processed or rendered.
     &hellip;
     codec.releaseOutputBuffer(outputBufferId, &hellip;);
   } else if (outputBufferId == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
     // Subsequent data will conform to new format.
     // Can ignore if using getOutputFormat(outputBufferId)
     outputFormat = codec.getOutputFormat(); // option B
   }
 }
 codec.stop();
 codec.release();</pre>

 <h4>Synchronous Processing using Buffer Arrays (deprecated)</h4>
 <p>
 In versions {@link android.os.Build.VERSION_CODES#KITKAT_WATCH} and before, the set of input and
 output buffers are represented by the {@code ByteBuffer[]} arrays. After a successful call to
 {@link #start}, retrieve the buffer arrays using {@link #getInputBuffers getInput}/{@link
 #getOutputBuffers OutputBuffers()}. Use the buffer ID-s as indices into these arrays (when
 non-negative), as demonstrated in the sample below. Note that there is no inherent correlation
 between the size of the arrays and the number of input and output buffers used by the system,
 although the array size provides an upper bound.
 <pre>
 MediaCodec codec = MediaCodec.createByCodecName(name);
 codec.configure(format, &hellip;);
 codec.start();
 ByteBuffer[] inputBuffers = codec.getInputBuffers();
 ByteBuffer[] outputBuffers = codec.getOutputBuffers();
 for (;;) {
   int inputBufferId = codec.dequeueInputBuffer(&hellip;);
   if (inputBufferId &gt;= 0) {
     // fill inputBuffers[inputBufferId] with valid data
     &hellip;
     codec.queueInputBuffer(inputBufferId, &hellip;);
   }
   int outputBufferId = codec.dequeueOutputBuffer(&hellip;);
   if (outputBufferId &gt;= 0) {
     // outputBuffers[outputBufferId] is ready to be processed or rendered.
     &hellip;
     codec.releaseOutputBuffer(outputBufferId, &hellip;);
   } else if (outputBufferId == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
     outputBuffers = codec.getOutputBuffers();
   } else if (outputBufferId == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
     // Subsequent data will conform to new format.
     MediaFormat format = codec.getOutputFormat();
   }
 }
 codec.stop();
 codec.release();</pre>

 <h4>End-of-stream Handling</h4>
 <p>
 When you reach the end of the input data, you must signal it to the codec by specifying the
 {@link #BUFFER_FLAG_END_OF_STREAM} flag in the call to {@link #queueInputBuffer
 queueInputBuffer}. You can do this on the last valid input buffer, or by submitting an additional
 empty input buffer with the end-of-stream flag set. If using an empty buffer, the timestamp will
 be ignored.
 <p>
 The codec will continue to return output buffers until it eventually signals the end of the
 output stream by specifying the same end-of-stream flag in the {@link BufferInfo} set in {@link
 #dequeueOutputBuffer dequeueOutputBuffer} or returned via {@link Callback#onOutputBufferAvailable
 onOutputBufferAvailable}. This can be set on the last valid output buffer, or on an empty buffer
 after the last valid output buffer. The timestamp of such empty buffer should be ignored.
 <p>
 Do not submit additional input buffers after signaling the end of the input stream, unless the
 codec has been flushed, or stopped and restarted.

 <h4>Using an Output Surface</h4>
 <p>
 The data processing is nearly identical to the ByteBuffer mode when using an output {@link
 Surface}; however, the output buffers will not be accessible, and are represented as {@code null}
 values. E.g. {@link #getOutputBuffer getOutputBuffer}/{@link #getOutputImage Image(int)} will
 return {@code null} and {@link #getOutputBuffers} will return an array containing only {@code
 null}-s.
 <p>
 When using an output Surface, you can select whether or not to render each output buffer on the
 surface. You have three choices:
 <ul>
 <li><strong>Do not render the buffer:</strong> Call {@link #releaseOutputBuffer(int, boolean)
 releaseOutputBuffer(bufferId, false)}.</li>
 <li><strong>Render the buffer with the default timestamp:</strong> Call {@link
 #releaseOutputBuffer(int, boolean) releaseOutputBuffer(bufferId, true)}.</li>
 <li><strong>Render the buffer with a specific timestamp:</strong> Call {@link
 #releaseOutputBuffer(int, long) releaseOutputBuffer(bufferId, timestamp)}.</li>
 </ul>
 <p>
 Since {@link android.os.Build.VERSION_CODES#M}, the default timestamp is the {@linkplain
 BufferInfo#presentationTimeUs presentation timestamp} of the buffer (converted to nanoseconds).
 It was not defined prior to that.
 <p>
 Also since {@link android.os.Build.VERSION_CODES#M}, you can change the output Surface
 dynamically using {@link #setOutputSurface setOutputSurface}.
 <p>
 When rendering output to a Surface, the Surface may be configured to drop excessive frames (that
 are not consumed by the Surface in a timely manner). Or it may be configured to not drop excessive
 frames. In the latter mode if the Surface is not consuming output frames fast enough, it will
 eventually block the decoder. Prior to {@link android.os.Build.VERSION_CODES#Q} the exact behavior
 was undefined, with the exception that View surfaces (SuerfaceView or TextureView) always dropped
 excessive frames. Since {@link android.os.Build.VERSION_CODES#Q} the default behavior is to drop
 excessive frames. Applications can opt out of this behavior for non-View surfaces (such as
 ImageReader or SurfaceTexture) by targeting SDK {@link android.os.Build.VERSION_CODES#Q} and
 setting the key {@code "allow-frame-drop"} to {@code 0} in their configure format.

 <h4>Transformations When Rendering onto Surface</h4>

 If the codec is configured into Surface mode, any crop rectangle, {@linkplain
 MediaFormat#KEY_ROTATION rotation} and {@linkplain #setVideoScalingMode video scaling
 mode} will be automatically applied with one exception:
 <p class=note>
 Prior to the {@link android.os.Build.VERSION_CODES#M} release, software decoders may not
 have applied the rotation when being rendered onto a Surface. Unfortunately, there is no standard
 and simple way to identify software decoders, or if they apply the rotation other than by trying
 it out.
 <p>
 There are also some caveats.
 <p class=note>
 Note that the pixel aspect ratio is not considered when displaying the output onto the
 Surface. This means that if you are using {@link #VIDEO_SCALING_MODE_SCALE_TO_FIT} mode, you
 must position the output Surface so that it has the proper final display aspect ratio. Conversely,
 you can only use {@link #VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING} mode for content with
 square pixels (pixel aspect ratio or 1:1).
 <p class=note>
 Note also that as of {@link android.os.Build.VERSION_CODES#N} release, {@link
 #VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING} mode may not work correctly for videos rotated
 by 90 or 270 degrees.
 <p class=note>
 When setting the video scaling mode, note that it must be reset after each time the output
 buffers change. Since the {@link #INFO_OUTPUT_BUFFERS_CHANGED} event is deprecated, you can
 do this after each time the output format changes.

 <h4>Using an Input Surface</h4>
 <p>
 When using an input Surface, there are no accessible input buffers, as buffers are automatically
 passed from the input surface to the codec. Calling {@link #dequeueInputBuffer
 dequeueInputBuffer} will throw an {@code IllegalStateException}, and {@link #getInputBuffers}
 returns a bogus {@code ByteBuffer[]} array that <strong>MUST NOT</strong> be written into.
 <p>
 Call {@link #signalEndOfInputStream} to signal end-of-stream. The input surface will stop
 submitting data to the codec immediately after this call.
 <p>

 <h3>Seeking &amp; Adaptive Playback Support</h3>
 <p>
 Video decoders (and in general codecs that consume compressed video data) behave differently
 regarding seek and format change whether or not they support and are configured for adaptive
 playback. You can check if a decoder supports {@linkplain
 CodecCapabilities#FEATURE_AdaptivePlayback adaptive playback} via {@link
 CodecCapabilities#isFeatureSupported CodecCapabilities.isFeatureSupported(String)}. Adaptive
 playback support for video decoders is only activated if you configure the codec to decode onto a
 {@link Surface}.

 <h4 id=KeyFrames><a name="KeyFrames"></a>Stream Boundary and Key Frames</h4>
 <p>
 It is important that the input data after {@link #start} or {@link #flush} starts at a suitable
 stream boundary: the first frame must a key frame. A <em>key frame</em> can be decoded
 completely on its own (for most codecs this means an I-frame), and no frames that are to be
 displayed after a key frame refer to frames before the key frame.
 <p>
 The following table summarizes suitable key frames for various video formats.
 <table>
  <thead>
   <tr>
    <th>Format</th>
    <th>Suitable key frame</th>
   </tr>
  </thead>
  <tbody class=mid>
   <tr>
    <td>VP9/VP8</td>
    <td>a suitable intraframe where no subsequent frames refer to frames prior to this frame.<br>
      <i>(There is no specific name for such key frame.)</i></td>
   </tr>
   <tr>
    <td>H.265 HEVC</td>
    <td>IDR or CRA</td>
   </tr>
   <tr>
    <td>H.264 AVC</td>
    <td>IDR</td>
   </tr>
   <tr>
    <td>MPEG-4<br>H.263<br>MPEG-2</td>
    <td>a suitable I-frame where no subsequent frames refer to frames prior to this frame.<br>
      <i>(There is no specific name for such key frame.)</td>
   </tr>
  </tbody>
 </table>

 <h4>For decoders that do not support adaptive playback (including when not decoding onto a
 Surface)</h4>
 <p>
 In order to start decoding data that is not adjacent to previously submitted data (i.e. after a
 seek) you <strong>MUST</strong> flush the decoder. Since all output buffers are immediately
 revoked at the point of the flush, you may want to first signal then wait for the end-of-stream
 before you call {@code flush}. It is important that the input data after a flush starts at a
 suitable stream boundary/key frame.
 <p class=note>
 <strong>Note:</strong> the format of the data submitted after a flush must not change; {@link
 #flush} does not support format discontinuities; for that, a full {@link #stop} - {@link
 #configure configure(&hellip;)} - {@link #start} cycle is necessary.

 <p class=note>
 <strong>Also note:</strong> if you flush the codec too soon after {@link #start} &ndash;
 generally, before the first output buffer or output format change is received &ndash; you
 will need to resubmit the codec-specific-data to the codec. See the <a
 href="#CSD">codec-specific-data section</a> for more info.

 <h4>For decoders that support and are configured for adaptive playback</h4>
 <p>
 In order to start decoding data that is not adjacent to previously submitted data (i.e. after a
 seek) it is <em>not necessary</em> to flush the decoder; however, input data after the
 discontinuity must start at a suitable stream boundary/key frame.
 <p>
 For some video formats - namely H.264, H.265, VP8 and VP9 - it is also possible to change the
 picture size or configuration mid-stream. To do this you must package the entire new
 codec-specific configuration data together with the key frame into a single buffer (including
 any start codes), and submit it as a <strong>regular</strong> input buffer.
 <p>
 You will receive an {@link #INFO_OUTPUT_FORMAT_CHANGED} return value from {@link
 #dequeueOutputBuffer dequeueOutputBuffer} or a {@link Callback#onOutputBufferAvailable
 onOutputFormatChanged} callback just after the picture-size change takes place and before any
 frames with the new size have been returned.
 <p class=note>
 <strong>Note:</strong> just as the case for codec-specific data, be careful when calling
 {@link #flush} shortly after you have changed the picture size. If you have not received
 confirmation of the picture size change, you will need to repeat the request for the new picture
 size.

 <h3>Error handling</h3>
 <p>
 The factory methods {@link #createByCodecName createByCodecName} and {@link #createDecoderByType
 createDecoder}/{@link #createEncoderByType EncoderByType} throw {@code IOException} on failure
 which you must catch or declare to pass up. MediaCodec methods throw {@code
 IllegalStateException} when the method is called from a codec state that does not allow it; this
 is typically due to incorrect application API usage. Methods involving secure buffers may throw
 {@link CryptoException}, which has further error information obtainable from {@link
 CryptoException#getErrorCode}.
 <p>
 Internal codec errors result in a {@link CodecException}, which may be due to media content
 corruption, hardware failure, resource exhaustion, and so forth, even when the application is
 correctly using the API. The recommended action when receiving a {@code CodecException}
 can be determined by calling {@link CodecException#isRecoverable} and {@link
 CodecException#isTransient}:
 <ul>
 <li><strong>recoverable errors:</strong> If {@code isRecoverable()} returns true, then call
 {@link #stop}, {@link #configure configure(&hellip;)}, and {@link #start} to recover.</li>
 <li><strong>transient errors:</strong> If {@code isTransient()} returns true, then resources are
 temporarily unavailable and the method may be retried at a later time.</li>
 <li><strong>fatal errors:</strong> If both {@code isRecoverable()} and {@code isTransient()}
 return false, then the {@code CodecException} is fatal and the codec must be {@linkplain #reset
 reset} or {@linkplain #release released}.</li>
 </ul>
 <p>
 Both {@code isRecoverable()} and {@code isTransient()} do not return true at the same time.

 <h2 id=History><a name="History"></a>Valid API Calls and API History</h2>
 <p>
 This sections summarizes the valid API calls in each state and the API history of the MediaCodec
 class. For API version numbers, see {@link android.os.Build.VERSION_CODES}.

 <style>
 .api > tr > th, .api > tr > td { text-align: center; padding: 4px 4px; }
 .api > tr > th     { vertical-align: bottom; }
 .api > tr > td     { vertical-align: middle; }
 .sml > tr > th, .sml > tr > td { text-align: center; padding: 2px 4px; }
 .fn { text-align: left; }
 .fn > code > a { font: 14px/19px Roboto Condensed, sans-serif; }
 .deg45 {
   white-space: nowrap; background: none; border: none; vertical-align: bottom;
   width: 30px; height: 83px;
 }
 .deg45 > div {
   transform: skew(-45deg, 0deg) translate(1px, -67px);
   transform-origin: bottom left 0;
   width: 30px; height: 20px;
 }
 .deg45 > div > div { border: 1px solid #ddd; background: #999; height: 90px; width: 42px; }
 .deg45 > div > div > div { transform: skew(45deg, 0deg) translate(-55px, 55px) rotate(-45deg); }
 </style>

 <table align="right" style="width: 0%">
  <thead>
   <tr><th>Symbol</th><th>Meaning</th></tr>
  </thead>
  <tbody class=sml>
   <tr><td>&#9679;</td><td>Supported</td></tr>
   <tr><td>&#8277;</td><td>Semantics changed</td></tr>
   <tr><td>&#9675;</td><td>Experimental support</td></tr>
   <tr><td>[ ]</td><td>Deprecated</td></tr>
   <tr><td>&#9099;</td><td>Restricted to surface input mode</td></tr>
   <tr><td>&#9094;</td><td>Restricted to surface output mode</td></tr>
   <tr><td>&#9639;</td><td>Restricted to ByteBuffer input mode</td></tr>
   <tr><td>&#8617;</td><td>Restricted to synchronous mode</td></tr>
   <tr><td>&#8644;</td><td>Restricted to asynchronous mode</td></tr>
   <tr><td>( )</td><td>Can be called, but shouldn't</td></tr>
  </tbody>
 </table>

 <table style="width: 100%;">
  <thead class=api>
   <tr>
    <th class=deg45><div><div style="background:#4285f4"><div>Uninitialized</div></div></div></th>
    <th class=deg45><div><div style="background:#f4b400"><div>Configured</div></div></div></th>
    <th class=deg45><div><div style="background:#e67c73"><div>Flushed</div></div></div></th>
    <th class=deg45><div><div style="background:#0f9d58"><div>Running</div></div></div></th>
    <th class=deg45><div><div style="background:#f7cb4d"><div>End of Stream</div></div></div></th>
    <th class=deg45><div><div style="background:#db4437"><div>Error</div></div></div></th>
    <th class=deg45><div><div style="background:#666"><div>Released</div></div></div></th>
    <th></th>
    <th colspan="8">SDK Version</th>
   </tr>
   <tr>
    <th colspan="7">State</th>
    <th>Method</th>
    <th>16</th>
    <th>17</th>
    <th>18</th>
    <th>19</th>
    <th>20</th>
    <th>21</th>
    <th>22</th>
    <th>23</th>
   </tr>
  </thead>
  <tbody class=api>
   <tr>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td class=fn>{@link #createByCodecName createByCodecName}</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
   </tr>
   <tr>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td class=fn>{@link #createDecoderByType createDecoderByType}</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
   </tr>
   <tr>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td class=fn>{@link #createEncoderByType createEncoderByType}</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
   </tr>
   <tr>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td class=fn>{@link #createPersistentInputSurface createPersistentInputSurface}</td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td>&#9679;</td>
   </tr>
   <tr>
    <td>16+</td>
    <td>-</td>
    <td>-</td>
    <td>-</td>
    <td>-</td>
    <td>-</td>
    <td>-</td>
    <td class=fn>{@link #configure configure}</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#8277;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
   </tr>
   <tr>
    <td>-</td>
    <td>18+</td>
    <td>-</td>
    <td>-</td>
    <td>-</td>
    <td>-</td>
    <td>-</td>
    <td class=fn>{@link #createInputSurface createInputSurface}</td>
    <td></td>
    <td></td>
    <td>&#9099;</td>
    <td>&#9099;</td>
    <td>&#9099;</td>
    <td>&#9099;</td>
    <td>&#9099;</td>
    <td>&#9099;</td>
   </tr>
   <tr>
    <td>-</td>
    <td>-</td>
    <td>16+</td>
    <td>16+</td>
    <td>(16+)</td>
    <td>-</td>
    <td>-</td>
    <td class=fn>{@link #dequeueInputBuffer dequeueInputBuffer}</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9639;</td>
    <td>&#9639;</td>
    <td>&#9639;</td>
    <td>&#8277;&#9639;&#8617;</td>
    <td>&#9639;&#8617;</td>
    <td>&#9639;&#8617;</td>
   </tr>
   <tr>
    <td>-</td>
    <td>-</td>
    <td>16+</td>
    <td>16+</td>
    <td>16+</td>
    <td>-</td>
    <td>-</td>
    <td class=fn>{@link #dequeueOutputBuffer dequeueOutputBuffer}</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#8277;&#8617;</td>
    <td>&#8617;</td>
    <td>&#8617;</td>
   </tr>
   <tr>
    <td>-</td>
    <td>-</td>
    <td>16+</td>
    <td>16+</td>
    <td>16+</td>
    <td>-</td>
    <td>-</td>
    <td class=fn>{@link #flush flush}</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
   </tr>
   <tr>
    <td>18+</td>
    <td>18+</td>
    <td>18+</td>
    <td>18+</td>
    <td>18+</td>
    <td>18+</td>
    <td>-</td>
    <td class=fn>{@link #getCodecInfo getCodecInfo}</td>
    <td></td>
    <td></td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
   </tr>
   <tr>
    <td>-</td>
    <td>-</td>
    <td>(21+)</td>
    <td>21+</td>
    <td>(21+)</td>
    <td>-</td>
    <td>-</td>
    <td class=fn>{@link #getInputBuffer getInputBuffer}</td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
   </tr>
   <tr>
    <td>-</td>
    <td>-</td>
    <td>16+</td>
    <td>(16+)</td>
    <td>(16+)</td>
    <td>-</td>
    <td>-</td>
    <td class=fn>{@link #getInputBuffers getInputBuffers}</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>[&#8277;&#8617;]</td>
    <td>[&#8617;]</td>
    <td>[&#8617;]</td>
   </tr>
   <tr>
    <td>-</td>
    <td>21+</td>
    <td>(21+)</td>
    <td>(21+)</td>
    <td>(21+)</td>
    <td>-</td>
    <td>-</td>
    <td class=fn>{@link #getInputFormat getInputFormat}</td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
   </tr>
   <tr>
    <td>-</td>
    <td>-</td>
    <td>(21+)</td>
    <td>21+</td>
    <td>(21+)</td>
    <td>-</td>
    <td>-</td>
    <td class=fn>{@link #getInputImage getInputImage}</td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td>&#9675;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
   </tr>
   <tr>
    <td>18+</td>
    <td>18+</td>
    <td>18+</td>
    <td>18+</td>
    <td>18+</td>
    <td>18+</td>
    <td>-</td>
    <td class=fn>{@link #getName getName}</td>
    <td></td>
    <td></td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
   </tr>
   <tr>
    <td>-</td>
    <td>-</td>
    <td>(21+)</td>
    <td>21+</td>
    <td>21+</td>
    <td>-</td>
    <td>-</td>
    <td class=fn>{@link #getOutputBuffer getOutputBuffer}</td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
   </tr>
   <tr>
    <td>-</td>
    <td>-</td>
    <td>16+</td>
    <td>16+</td>
    <td>16+</td>
    <td>-</td>
    <td>-</td>
    <td class=fn>{@link #getOutputBuffers getOutputBuffers}</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>[&#8277;&#8617;]</td>
    <td>[&#8617;]</td>
    <td>[&#8617;]</td>
   </tr>
   <tr>
    <td>-</td>
    <td>21+</td>
    <td>16+</td>
    <td>16+</td>
    <td>16+</td>
    <td>-</td>
    <td>-</td>
    <td class=fn>{@link #getOutputFormat()}</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
   </tr>
   <tr>
    <td>-</td>
    <td>-</td>
    <td>(21+)</td>
    <td>21+</td>
    <td>21+</td>
    <td>-</td>
    <td>-</td>
    <td class=fn>{@link #getOutputFormat(int)}</td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
   </tr>
   <tr>
    <td>-</td>
    <td>-</td>
    <td>(21+)</td>
    <td>21+</td>
    <td>21+</td>
    <td>-</td>
    <td>-</td>
    <td class=fn>{@link #getOutputImage getOutputImage}</td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td>&#9675;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
   </tr>
   <tr>
    <td>-</td>
    <td>-</td>
    <td>-</td>
    <td>16+</td>
    <td>(16+)</td>
    <td>-</td>
    <td>-</td>
    <td class=fn>{@link #queueInputBuffer queueInputBuffer}</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#8277;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
   </tr>
   <tr>
    <td>-</td>
    <td>-</td>
    <td>-</td>
    <td>16+</td>
    <td>(16+)</td>
    <td>-</td>
    <td>-</td>
    <td class=fn>{@link #queueSecureInputBuffer queueSecureInputBuffer}</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#8277;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
   </tr>
   <tr>
    <td>16+</td>
    <td>16+</td>
    <td>16+</td>
    <td>16+</td>
    <td>16+</td>
    <td>16+</td>
    <td>16+</td>
    <td class=fn>{@link #release release}</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
   </tr>
   <tr>
    <td>-</td>
    <td>-</td>
    <td>-</td>
    <td>16+</td>
    <td>16+</td>
    <td>-</td>
    <td>-</td>
    <td class=fn>{@link #releaseOutputBuffer(int, boolean)}</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#8277;</td>
    <td>&#9679;</td>
    <td>&#8277;</td>
   </tr>
   <tr>
    <td>-</td>
    <td>-</td>
    <td>-</td>
    <td>21+</td>
    <td>21+</td>
    <td>-</td>
    <td>-</td>
    <td class=fn>{@link #releaseOutputBuffer(int, long)}</td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td>&#9094;</td>
    <td>&#9094;</td>
    <td>&#9094;</td>
   </tr>
   <tr>
    <td>21+</td>
    <td>21+</td>
    <td>21+</td>
    <td>21+</td>
    <td>21+</td>
    <td>21+</td>
    <td>-</td>
    <td class=fn>{@link #reset reset}</td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
   </tr>
   <tr>
    <td>21+</td>
    <td>-</td>
    <td>-</td>
    <td>-</td>
    <td>-</td>
    <td>-</td>
    <td>-</td>
    <td class=fn>{@link #setCallback(Callback) setCallback}</td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>{@link #setCallback(Callback, Handler) &#8277;}</td>
   </tr>
   <tr>
    <td>-</td>
    <td>23+</td>
    <td>-</td>
    <td>-</td>
    <td>-</td>
    <td>-</td>
    <td>-</td>
    <td class=fn>{@link #setInputSurface setInputSurface}</td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td>&#9099;</td>
   </tr>
   <tr>
    <td>23+</td>
    <td>23+</td>
    <td>23+</td>
    <td>23+</td>
    <td>23+</td>
    <td>(23+)</td>
    <td>(23+)</td>
    <td class=fn>{@link #setOnFrameRenderedListener setOnFrameRenderedListener}</td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td>&#9675; &#9094;</td>
   </tr>
   <tr>
    <td>-</td>
    <td>23+</td>
    <td>23+</td>
    <td>23+</td>
    <td>23+</td>
    <td>-</td>
    <td>-</td>
    <td class=fn>{@link #setOutputSurface setOutputSurface}</td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td>&#9094;</td>
   </tr>
   <tr>
    <td>19+</td>
    <td>19+</td>
    <td>19+</td>
    <td>19+</td>
    <td>19+</td>
    <td>(19+)</td>
    <td>-</td>
    <td class=fn>{@link #setParameters setParameters}</td>
    <td></td>
    <td></td>
    <td></td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
   </tr>
   <tr>
    <td>-</td>
    <td>(16+)</td>
    <td>(16+)</td>
    <td>16+</td>
    <td>(16+)</td>
    <td>(16+)</td>
    <td>-</td>
    <td class=fn>{@link #setVideoScalingMode setVideoScalingMode}</td>
    <td>&#9094;</td>
    <td>&#9094;</td>
    <td>&#9094;</td>
    <td>&#9094;</td>
    <td>&#9094;</td>
    <td>&#9094;</td>
    <td>&#9094;</td>
    <td>&#9094;</td>
   </tr>
   <tr>
    <td>(29+)</td>
    <td>29+</td>
    <td>29+</td>
    <td>29+</td>
    <td>(29+)</td>
    <td>(29+)</td>
    <td>-</td>
    <td class=fn>{@link #setAudioPresentation setAudioPresentation}</td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
   </tr>
   <tr>
    <td>-</td>
    <td>-</td>
    <td>18+</td>
    <td>18+</td>
    <td>-</td>
    <td>-</td>
    <td>-</td>
    <td class=fn>{@link #signalEndOfInputStream signalEndOfInputStream}</td>
    <td></td>
    <td></td>
    <td>&#9099;</td>
    <td>&#9099;</td>
    <td>&#9099;</td>
    <td>&#9099;</td>
    <td>&#9099;</td>
    <td>&#9099;</td>
   </tr>
   <tr>
    <td>-</td>
    <td>16+</td>
    <td>21+(&#8644;)</td>
    <td>-</td>
    <td>-</td>
    <td>-</td>
    <td>-</td>
    <td class=fn>{@link #start start}</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#8277;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
   </tr>
   <tr>
    <td>-</td>
    <td>-</td>
    <td>16+</td>
    <td>16+</td>
    <td>16+</td>
    <td>-</td>
    <td>-</td>
    <td class=fn>{@link #stop stop}</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
    <td>&#9679;</td>
   </tr>
  </tbody>
 </table>
 */
final public class MediaCodec {
    /**
     * Per buffer metadata includes an offset and size specifying
     * the range of valid data in the associated codec (output) buffer.
     */
    public final static class BufferInfo {
        /**
         * Update the buffer metadata information.
         *
         * @param newOffset the start-offset of the data in the buffer.
         * @param newSize   the amount of data (in bytes) in the buffer.
         * @param newTimeUs the presentation timestamp in microseconds.
         * @param newFlags  buffer flags associated with the buffer.  This
         * should be a combination of  {@link #BUFFER_FLAG_KEY_FRAME} and
         * {@link #BUFFER_FLAG_END_OF_STREAM}.
         */
        public void set(
                int newOffset, int newSize, long newTimeUs, @BufferFlag int newFlags) {
            offset = newOffset;
            size = newSize;
            presentationTimeUs = newTimeUs;
            flags = newFlags;
        }

        /**
         * The start-offset of the data in the buffer.
         */
        public int offset;

        /**
         * The amount of data (in bytes) in the buffer.  If this is {@code 0},
         * the buffer has no data in it and can be discarded.  The only
         * use of a 0-size buffer is to carry the end-of-stream marker.
         */
        public int size;

        /**
         * The presentation timestamp in microseconds for the buffer.
         * This is derived from the presentation timestamp passed in
         * with the corresponding input buffer.  This should be ignored for
         * a 0-sized buffer.
         */
        public long presentationTimeUs;

        /**
         * Buffer flags associated with the buffer.  A combination of
         * {@link #BUFFER_FLAG_KEY_FRAME} and {@link #BUFFER_FLAG_END_OF_STREAM}.
         *
         * <p>Encoded buffers that are key frames are marked with
         * {@link #BUFFER_FLAG_KEY_FRAME}.
         *
         * <p>The last output buffer corresponding to the input buffer
         * marked with {@link #BUFFER_FLAG_END_OF_STREAM} will also be marked
         * with {@link #BUFFER_FLAG_END_OF_STREAM}. In some cases this could
         * be an empty buffer, whose sole purpose is to carry the end-of-stream
         * marker.
         */
        @BufferFlag
        public int flags;

        /** @hide */
        @NonNull
        public BufferInfo dup() {
            BufferInfo copy = new BufferInfo();
            copy.set(offset, size, presentationTimeUs, flags);
            return copy;
        }
    };

    // The follow flag constants MUST stay in sync with their equivalents
    // in MediaCodec.h !

    /**
     * This indicates that the (encoded) buffer marked as such contains
     * the data for a key frame.
     *
     * @deprecated Use {@link #BUFFER_FLAG_KEY_FRAME} instead.
     */
    public static final int BUFFER_FLAG_SYNC_FRAME = 1;

    /**
     * This indicates that the (encoded) buffer marked as such contains
     * the data for a key frame.
     */
    public static final int BUFFER_FLAG_KEY_FRAME = 1;

    /**
     * This indicated that the buffer marked as such contains codec
     * initialization / codec specific data instead of media data.
     */
    public static final int BUFFER_FLAG_CODEC_CONFIG = 2;

    /**
     * This signals the end of stream, i.e. no buffers will be available
     * after this, unless of course, {@link #flush} follows.
     */
    public static final int BUFFER_FLAG_END_OF_STREAM = 4;

    /**
     * This indicates that the buffer only contains part of a frame,
     * and the decoder should batch the data until a buffer without
     * this flag appears before decoding the frame.
     */
    public static final int BUFFER_FLAG_PARTIAL_FRAME = 8;

    /**
     * This indicates that the buffer contains non-media data for the
     * muxer to process.
     *
     * All muxer data should start with a FOURCC header that determines the type of data.
     *
     * For example, when it contains Exif data sent to a MediaMuxer track of
     * {@link MediaFormat#MIMETYPE_IMAGE_ANDROID_HEIC} type, the data must start with
     * Exif header ("Exif\0\0"), followed by the TIFF header (See JEITA CP-3451C Section 4.5.2.)
     *
     * @hide
     */
    public static final int BUFFER_FLAG_MUXER_DATA = 16;

    /** @hide */
    @IntDef(
        flag = true,
        value = {
            BUFFER_FLAG_SYNC_FRAME,
            BUFFER_FLAG_KEY_FRAME,
            BUFFER_FLAG_CODEC_CONFIG,
            BUFFER_FLAG_END_OF_STREAM,
            BUFFER_FLAG_PARTIAL_FRAME,
            BUFFER_FLAG_MUXER_DATA,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface BufferFlag {}

    private EventHandler mEventHandler;
    private EventHandler mOnFrameRenderedHandler;
    private EventHandler mCallbackHandler;
    private Callback mCallback;
    private OnFrameRenderedListener mOnFrameRenderedListener;
    private final Object mListenerLock = new Object();
    private MediaCodecInfo mCodecInfo;
    private final Object mCodecInfoLock = new Object();
    private MediaCrypto mCrypto;

    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 CB_INPUT_AVAILABLE = 1;
    private static final int CB_OUTPUT_AVAILABLE = 2;
    private static final int CB_ERROR = 3;
    private static final int CB_OUTPUT_FORMAT_CHANGE = 4;

    private class EventHandler extends Handler {
        private MediaCodec mCodec;

        public EventHandler(@NonNull MediaCodec codec, @NonNull Looper looper) {
            super(looper);
            mCodec = codec;
        }

        @Override
        public void handleMessage(@NonNull Message msg) {
            switch (msg.what) {
                case EVENT_CALLBACK:
                {
                    handleCallback(msg);
                    break;
                }
                case EVENT_SET_CALLBACK:
                {
                    mCallback = (MediaCodec.Callback) msg.obj;
                    break;
                }
                case EVENT_FRAME_RENDERED:
                    Map<String, Object> map = (Map<String, Object>)msg.obj;
                    for (int i = 0; ; ++i) {
                        Object mediaTimeUs = map.get(i + "-media-time-us");
                        Object systemNano = map.get(i + "-system-nano");
                        OnFrameRenderedListener onFrameRenderedListener;
                        synchronized (mListenerLock) {
                            onFrameRenderedListener = mOnFrameRenderedListener;
                        }
                        if (mediaTimeUs == null || systemNano == null
                                || onFrameRenderedListener == null) {
                            break;
                        }
                        onFrameRenderedListener.onFrameRendered(
                                mCodec, (long)mediaTimeUs, (long)systemNano);
                    }
                    break;
                default:
                {
                    break;
                }
            }
        }

        private void handleCallback(@NonNull Message msg) {
            if (mCallback == null) {
                return;
            }

            switch (msg.arg1) {
                case CB_INPUT_AVAILABLE:
                {
                    int index = msg.arg2;
                    synchronized(mBufferLock) {
                        validateInputByteBuffer(mCachedInputBuffers, index);
                    }
                    mCallback.onInputBufferAvailable(mCodec, index);
                    break;
                }

                case CB_OUTPUT_AVAILABLE:
                {
                    int index = msg.arg2;
                    BufferInfo info = (MediaCodec.BufferInfo) msg.obj;
                    synchronized(mBufferLock) {
                        validateOutputByteBuffer(mCachedOutputBuffers, index, info);
                    }
                    mCallback.onOutputBufferAvailable(
                            mCodec, index, info);
                    break;
                }

                case CB_ERROR:
                {
                    mCallback.onError(mCodec, (MediaCodec.CodecException) msg.obj);
                    break;
                }

                case CB_OUTPUT_FORMAT_CHANGE:
                {
                    mCallback.onOutputFormatChanged(mCodec,
                            new MediaFormat((Map<String, Object>) msg.obj));
                    break;
                }

                default:
                {
                    break;
                }
            }
        }
    }

    private boolean mHasSurface = false;

    /**
     * Instantiate the preferred decoder supporting input data of the given mime type.
     *
     * The following is a partial list of defined mime types and their semantics:
     * <ul>
     * <li>"video/x-vnd.on2.vp8" - VP8 video (i.e. video in .webm)
     * <li>"video/x-vnd.on2.vp9" - VP9 video (i.e. video in .webm)
     * <li>"video/avc" - H.264/AVC video
     * <li>"video/hevc" - H.265/HEVC video
     * <li>"video/mp4v-es" - MPEG4 video
     * <li>"video/3gpp" - H.263 video
     * <li>"audio/3gpp" - AMR narrowband audio
     * <li>"audio/amr-wb" - AMR wideband audio
     * <li>"audio/mpeg" - MPEG1/2 audio layer III
     * <li>"audio/mp4a-latm" - AAC audio (note, this is raw AAC packets, not packaged in LATM!)
     * <li>"audio/vorbis" - vorbis audio
     * <li>"audio/g711-alaw" - G.711 alaw audio
     * <li>"audio/g711-mlaw" - G.711 ulaw audio
     * </ul>
     *
     * <strong>Note:</strong> It is preferred to use {@link MediaCodecList#findDecoderForFormat}
     * and {@link #createByCodecName} to ensure that the resulting codec can handle a
     * given format.
     *
     * @param type The mime type of the input data.
     * @throws IOException if the codec cannot be created.
     * @throws IllegalArgumentException if type is not a valid mime type.
     * @throws NullPointerException if type is null.
     */
    @NonNull
    public static MediaCodec createDecoderByType(@NonNull String type)
            throws IOException {
        return new MediaCodec(type, true /* nameIsType */, false /* encoder */);
    }

    /**
     * Instantiate the preferred encoder supporting output data of the given mime type.
     *
     * <strong>Note:</strong> It is preferred to use {@link MediaCodecList#findEncoderForFormat}
     * and {@link #createByCodecName} to ensure that the resulting codec can handle a
     * given format.
     *
     * @param type The desired mime type of the output data.
     * @throws IOException if the codec cannot be created.
     * @throws IllegalArgumentException if type is not a valid mime type.
     * @throws NullPointerException if type is null.
     */
    @NonNull
    public static MediaCodec createEncoderByType(@NonNull String type)
            throws IOException {
        return new MediaCodec(type, true /* nameIsType */, true /* encoder */);
    }

    /**
     * If you know the exact name of the component you want to instantiate
     * use this method to instantiate it. Use with caution.
     * Likely to be used with information obtained from {@link android.media.MediaCodecList}
     * @param name The name of the codec to be instantiated.
     * @throws IOException if the codec cannot be created.
     * @throws IllegalArgumentException if name is not valid.
     * @throws NullPointerException if name is null.
     */
    @NonNull
    public static MediaCodec createByCodecName(@NonNull String name)
            throws IOException {
        return new MediaCodec(
                name, false /* nameIsType */, false /* unused */);
    }

    private MediaCodec(
            @NonNull String name, boolean nameIsType, boolean encoder) {
        Looper looper;
        if ((looper = Looper.myLooper()) != null) {
            mEventHandler = new EventHandler(this, looper);
        } else if ((looper = Looper.getMainLooper()) != null) {
            mEventHandler = new EventHandler(this, looper);
        } else {
            mEventHandler = null;
        }
        mCallbackHandler = mEventHandler;
        mOnFrameRenderedHandler = mEventHandler;

        mBufferLock = new Object();

        // save name used at creation
        mNameAtCreation = nameIsType ? null : name;

        native_setup(name, nameIsType, encoder);
    }

    private String mNameAtCreation;

    @Override
    protected void finalize() {
        native_finalize();
        mCrypto = null;
    }

    /**
     * Returns the codec to its initial (Uninitialized) state.
     *
     * Call this if an {@link MediaCodec.CodecException#isRecoverable unrecoverable}
     * error has occured to reset the codec to its initial state after creation.
     *
     * @throws CodecException if an unrecoverable error has occured and the codec
     * could not be reset.
     * @throws IllegalStateException if in the Released state.
     */
    public final void reset() {
        freeAllTrackedBuffers(); // free buffers first
        native_reset();
        mCrypto = null;
    }

    private native final void native_reset();

    /**
     * Free up resources used by the codec instance.
     *
     * Make sure you call this when you're done to free up any opened
     * component instance instead of relying on the garbage collector
     * to do this for you at some point in the future.
     */
    public final void release() {
        freeAllTrackedBuffers(); // free buffers first
        native_release();
        mCrypto = null;
    }

    private native final void native_release();

    /**
     * If this codec is to be used as an encoder, pass this flag.
     */
    public static final int CONFIGURE_FLAG_ENCODE = 1;

    /** @hide */
    @IntDef(flag = true, value = { CONFIGURE_FLAG_ENCODE })
    @Retention(RetentionPolicy.SOURCE)
    public @interface ConfigureFlag {}

    /**
     * Configures a component.
     *
     * @param format The format of the input data (decoder) or the desired
     *               format of the output data (encoder). Passing {@code null}
     *               as {@code format} is equivalent to passing an
     *               {@link MediaFormat#MediaFormat an empty mediaformat}.
     * @param surface Specify a surface on which to render the output of this
     *                decoder. Pass {@code null} as {@code surface} if the
     *                codec does not generate raw video output (e.g. not a video
     *                decoder) and/or if you want to configure the codec for
     *                {@link ByteBuffer} output.
     * @param crypto  Specify a crypto object to facilitate secure decryption
     *                of the media data. Pass {@code null} as {@code crypto} for
     *                non-secure codecs.
     *                Please note that {@link MediaCodec} does NOT take ownership
     *                of the {@link MediaCrypto} object; it is the application's
     *                responsibility to properly cleanup the {@link MediaCrypto} object
     *                when not in use.
     * @param flags   Specify {@link #CONFIGURE_FLAG_ENCODE} to configure the
     *                component as an encoder.
     * @throws IllegalArgumentException if the surface has been released (or is invalid),
     * or the format is unacceptable (e.g. missing a mandatory key),
     * or the flags are not set properly
     * (e.g. missing {@link #CONFIGURE_FLAG_ENCODE} for an encoder).
     * @throws IllegalStateException if not in the Uninitialized state.
     * @throws CryptoException upon DRM error.
     * @throws CodecException upon codec error.
     */
    public void configure(
            @Nullable MediaFormat format,
            @Nullable Surface surface, @Nullable MediaCrypto crypto,
            @ConfigureFlag int flags) {
        configure(format, surface, crypto, null, flags);
    }

    /**
     * Configure a component to be used with a descrambler.
     * @param format The format of the input data (decoder) or the desired
     *               format of the output data (encoder). Passing {@code null}
     *               as {@code format} is equivalent to passing an
     *               {@link MediaFormat#MediaFormat an empty mediaformat}.
     * @param surface Specify a surface on which to render the output of this
     *                decoder. Pass {@code null} as {@code surface} if the
     *                codec does not generate raw video output (e.g. not a video
     *                decoder) and/or if you want to configure the codec for
     *                {@link ByteBuffer} output.
     * @param flags   Specify {@link #CONFIGURE_FLAG_ENCODE} to configure the
     *                component as an encoder.
     * @param descrambler Specify a descrambler object to facilitate secure
     *                descrambling of the media data, or null for non-secure codecs.
     * @throws IllegalArgumentException if the surface has been released (or is invalid),
     * or the format is unacceptable (e.g. missing a mandatory key),
     * or the flags are not set properly
     * (e.g. missing {@link #CONFIGURE_FLAG_ENCODE} for an encoder).
     * @throws IllegalStateException if not in the Uninitialized state.
     * @throws CryptoException upon DRM error.
     * @throws CodecException upon codec error.
     */
    public void configure(
            @Nullable MediaFormat format, @Nullable Surface surface,
            @ConfigureFlag int flags, @Nullable MediaDescrambler descrambler) {
        configure(format, surface, null,
                descrambler != null ? descrambler.getBinder() : null, flags);
    }

    private void configure(
            @Nullable MediaFormat format, @Nullable Surface surface,
            @Nullable MediaCrypto crypto, @Nullable IHwBinder descramblerBinder,
            @ConfigureFlag int flags) {
        if (crypto != null && descramblerBinder != null) {
            throw new IllegalArgumentException("Can't use crypto and descrambler together!");
        }

        String[] keys = null;
        Object[] values = null;

        if (format != null) {
            Map<String, Object> formatMap = format.getMap();
            keys = new String[formatMap.size()];
            values = new Object[formatMap.size()];

            int i = 0;
            for (Map.Entry<String, Object> entry: formatMap.entrySet()) {
                if (entry.getKey().equals(MediaFormat.KEY_AUDIO_SESSION_ID)) {
                    int sessionId = 0;
                    try {
                        sessionId = (Integer)entry.getValue();
                    }
                    catch (Exception e) {
                        throw new IllegalArgumentException("Wrong Session ID Parameter!");
                    }
                    keys[i] = "audio-hw-sync";
                    values[i] = AudioSystem.getAudioHwSyncForSession(sessionId);
                } else {
                    keys[i] = entry.getKey();
                    values[i] = entry.getValue();
                }
                ++i;
            }
        }

        mHasSurface = surface != null;
        mCrypto = crypto;

        native_configure(keys, values, surface, crypto, descramblerBinder, flags);
    }

    /**
     *  Dynamically sets the output surface of a codec.
     *  <p>
     *  This can only be used if the codec was configured with an output surface.  The
     *  new output surface should have a compatible usage type to the original output surface.
     *  E.g. codecs may not support switching from a SurfaceTexture (GPU readable) output
     *  to ImageReader (software readable) output.
     *  @param surface the output surface to use. It must not be {@code null}.
     *  @throws IllegalStateException if the codec does not support setting the output
     *            surface in the current state.
     *  @throws IllegalArgumentException if the new surface is not of a suitable type for the codec.
     */
    public void setOutputSurface(@NonNull Surface surface) {
        if (!mHasSurface) {
            throw new IllegalStateException("codec was not configured for an output surface");
        }
        native_setSurface(surface);
    }

    private native void native_setSurface(@NonNull Surface surface);

    /**
     * Create a persistent input surface that can be used with codecs that normally have an input
     * surface, such as video encoders. A persistent input can be reused by subsequent
     * {@link MediaCodec} or {@link MediaRecorder} instances, but can only be used by at
     * most one codec or recorder instance concurrently.
     * <p>
     * The application is responsible for calling release() on the Surface when done.
     *
     * @return an input surface that can be used with {@link #setInputSurface}.
     */
    @NonNull
    public static Surface createPersistentInputSurface() {
        return native_createPersistentInputSurface();
    }

    static class PersistentSurface extends Surface {
        @SuppressWarnings("unused")
        PersistentSurface() {} // used by native

        @Override
        public void release() {
            native_releasePersistentInputSurface(this);
            super.release();
        }

        private long mPersistentObject;
    };

    /**
     * Configures the codec (e.g. encoder) to use a persistent input surface in place of input
     * buffers.  This may only be called after {@link #configure} and before {@link #start}, in
     * lieu of {@link #createInputSurface}.
     * @param surface a persistent input surface created by {@link #createPersistentInputSurface}
     * @throws IllegalStateException if not in the Configured state or does not require an input
     *           surface.
     * @throws IllegalArgumentException if the surface was not created by
     *           {@link #createPersistentInputSurface}.
     */
    public void setInputSurface(@NonNull Surface surface) {
        if (!(surface instanceof PersistentSurface)) {
            throw new IllegalArgumentException("not a PersistentSurface");
        }
        native_setInputSurface(surface);
    }

    @NonNull
    private static native final PersistentSurface native_createPersistentInputSurface();
    private static native final void native_releasePersistentInputSurface(@NonNull Surface surface);
    private native final void native_setInputSurface(@NonNull Surface surface);

    private native final void native_setCallback(@Nullable Callback cb);

    private native final void native_configure(
            @Nullable String[] keys, @Nullable Object[] values,
            @Nullable Surface surface, @Nullable MediaCrypto crypto,
            @Nullable IHwBinder descramblerBinder, @ConfigureFlag int flags);

    /**
     * Requests a Surface to use as the input to an encoder, in place of input buffers.  This
     * may only be called after {@link #configure} and before {@link #start}.
     * <p>
     * The application is responsible for calling release() on the Surface when
     * done.
     * <p>
     * The Surface must be rendered with a hardware-accelerated API, such as OpenGL ES.
     * {@link android.view.Surface#lockCanvas(android.graphics.Rect)} may fail or produce
     * unexpected results.
     * @throws IllegalStateException if not in the Configured state.
     */
    @NonNull
    public native final Surface createInputSurface();

    /**
     * After successfully configuring the component, call {@code start}.
     * <p>
     * Call {@code start} also if the codec is configured in asynchronous mode,
     * and it has just been flushed, to resume requesting input buffers.
     * @throws IllegalStateException if not in the Configured state
     *         or just after {@link #flush} for a codec that is configured
     *         in asynchronous mode.
     * @throws MediaCodec.CodecException upon codec error. Note that some codec errors
     * for start may be attributed to future method calls.
     */
    public final void start() {
        native_start();
        synchronized(mBufferLock) {
            cacheBuffers(true /* input */);
            cacheBuffers(false /* input */);
        }
    }
    private native final void native_start();

    /**
     * Finish the decode/encode session, note that the codec instance
     * remains active and ready to be {@link #start}ed again.
     * To ensure that it is available to other client call {@link #release}
     * and don't just rely on garbage collection to eventually do this for you.
     * @throws IllegalStateException if in the Released state.
     */
    public final void stop() {
        native_stop();
        freeAllTrackedBuffers();

        synchronized (mListenerLock) {
            if (mCallbackHandler != null) {
                mCallbackHandler.removeMessages(EVENT_SET_CALLBACK);
                mCallbackHandler.removeMessages(EVENT_CALLBACK);
            }
            if (mOnFrameRenderedHandler != null) {
                mOnFrameRenderedHandler.removeMessages(EVENT_FRAME_RENDERED);
            }
        }
    }

    private native final void native_stop();

    /**
     * Flush both input and output ports of the component.
     * <p>
     * Upon return, all indices previously returned in calls to {@link #dequeueInputBuffer
     * dequeueInputBuffer} and {@link #dequeueOutputBuffer dequeueOutputBuffer} &mdash; or obtained
     * via {@link Callback#onInputBufferAvailable onInputBufferAvailable} or
     * {@link Callback#onOutputBufferAvailable onOutputBufferAvailable} callbacks &mdash; become
     * invalid, and all buffers are owned by the codec.
     * <p>
     * If the codec is configured in asynchronous mode, call {@link #start}
     * after {@code flush} has returned to resume codec operations. The codec
     * will not request input buffers until this has happened.
     * <strong>Note, however, that there may still be outstanding {@code onOutputBufferAvailable}
     * callbacks that were not handled prior to calling {@code flush}.
     * The indices returned via these callbacks also become invalid upon calling {@code flush} and
     * should be discarded.</strong>
     * <p>
     * If the codec is configured in synchronous mode, codec will resume
     * automatically if it is configured with an input surface.  Otherwise, it
     * will resume when {@link #dequeueInputBuffer dequeueInputBuffer} is called.
     *
     * @throws IllegalStateException if not in the Executing state.
     * @throws MediaCodec.CodecException upon codec error.
     */
    public final void flush() {
        synchronized(mBufferLock) {
            invalidateByteBuffers(mCachedInputBuffers);
            invalidateByteBuffers(mCachedOutputBuffers);
            mDequeuedInputBuffers.clear();
            mDequeuedOutputBuffers.clear();
        }
        native_flush();
    }

    private native final void native_flush();

    /**
     * Thrown when an internal codec error occurs.
     */
    public final static class CodecException extends IllegalStateException {
        @UnsupportedAppUsage
        CodecException(int errorCode, int actionCode, @Nullable String detailMessage) {
            super(detailMessage);
            mErrorCode = errorCode;
            mActionCode = actionCode;

            // TODO get this from codec
            final String sign = errorCode < 0 ? "neg_" : "";
            mDiagnosticInfo =
                "android.media.MediaCodec.error_" + sign + Math.abs(errorCode);
        }

        /**
         * Returns true if the codec exception is a transient issue,
         * perhaps due to resource constraints, and that the method
         * (or encoding/decoding) may be retried at a later time.
         */
        public boolean isTransient() {
            return mActionCode == ACTION_TRANSIENT;
        }

        /**
         * Returns true if the codec cannot proceed further,
         * but can be recovered by stopping, configuring,
         * and starting again.
         */
        public boolean isRecoverable() {
            return mActionCode == ACTION_RECOVERABLE;
        }

        /**
         * Retrieve the error code associated with a CodecException
         */
        public int getErrorCode() {
            return mErrorCode;
        }

        /**
         * Retrieve a developer-readable diagnostic information string
         * associated with the exception. Do not show this to end-users,
         * since this string will not be localized or generally
         * comprehensible to end-users.
         */
        public @NonNull String getDiagnosticInfo() {
            return mDiagnosticInfo;
        }

        /**
         * This indicates required resource was not able to be allocated.
         */
        public static final int ERROR_INSUFFICIENT_RESOURCE = 1100;

        /**
         * This indicates the resource manager reclaimed the media resource used by the codec.
         * <p>
         * With this exception, the codec must be released, as it has moved to terminal state.
         */
        public static final int ERROR_RECLAIMED = 1101;

        /** @hide */
        @IntDef({
            ERROR_INSUFFICIENT_RESOURCE,
            ERROR_RECLAIMED,
        })
        @Retention(RetentionPolicy.SOURCE)
        public @interface ReasonCode {}

        /* Must be in sync with android_media_MediaCodec.cpp */
        private final static int ACTION_TRANSIENT = 1;
        private final static int ACTION_RECOVERABLE = 2;

        private final String mDiagnosticInfo;
        private final int mErrorCode;
        private final int mActionCode;
    }

    /**
     * Thrown when a crypto error occurs while queueing a secure input buffer.
     */
    public final static class CryptoException extends RuntimeException {
        public CryptoException(int errorCode, @Nullable String detailMessage) {
            super(detailMessage);
            mErrorCode = errorCode;
        }

        /**
         * This indicates that the requested key was not found when trying to
         * perform a decrypt operation.  The operation can be retried after adding
         * the correct decryption key.
         */
        public static final int ERROR_NO_KEY = 1;

        /**
         * This indicates that the key used for decryption is no longer
         * valid due to license term expiration.  The operation can be retried
         * after updating the expired keys.
         */
        public static final int ERROR_KEY_EXPIRED = 2;

        /**
         * This indicates that a required crypto resource was not able to be
         * allocated while attempting the requested operation.  The operation
         * can be retried if the app is able to release resources.
         */
        public static final int ERROR_RESOURCE_BUSY = 3;

        /**
         * This indicates that the output protection levels supported by the
         * device are not sufficient to meet the requirements set by the
         * content owner in the license policy.
         */
        public static final int ERROR_INSUFFICIENT_OUTPUT_PROTECTION = 4;

        /**
         * This indicates that decryption was attempted on a session that is
         * not opened, which could be due to a failure to open the session,
         * closing the session prematurely, or the session being reclaimed
         * by the resource manager.
         */
        public static final int ERROR_SESSION_NOT_OPENED = 5;

        /**
         * This indicates that an operation was attempted that could not be
         * supported by the crypto system of the device in its current
         * configuration.  It may occur when the license policy requires
         * device security features that aren't supported by the device,
         * or due to an internal error in the crypto system that prevents
         * the specified security policy from being met.
         */
        public static final int ERROR_UNSUPPORTED_OPERATION = 6;

        /**
         * This indicates that the security level of the device is not
         * sufficient to meet the requirements set by the content owner
         * in the license policy.
         */
        public static final int ERROR_INSUFFICIENT_SECURITY = 7;

        /**
         * This indicates that the video frame being decrypted exceeds
         * the size of the device's protected output buffers. When
         * encountering this error the app should try playing content
         * of a lower resolution.
         */
        public static final int ERROR_FRAME_TOO_LARGE = 8;

        /**
         * This error indicates that session state has been
         * invalidated. It can occur on devices that are not capable
         * of retaining crypto session state across device
         * suspend/resume. The session must be closed and a new
         * session opened to resume operation.
         */
        public static final int ERROR_LOST_STATE = 9;

        /** @hide */
        @IntDef({
            ERROR_NO_KEY,
            ERROR_KEY_EXPIRED,
            ERROR_RESOURCE_BUSY,
            ERROR_INSUFFICIENT_OUTPUT_PROTECTION,
            ERROR_SESSION_NOT_OPENED,
            ERROR_UNSUPPORTED_OPERATION,
            ERROR_INSUFFICIENT_SECURITY,
            ERROR_FRAME_TOO_LARGE,
            ERROR_LOST_STATE
        })
        @Retention(RetentionPolicy.SOURCE)
        public @interface CryptoErrorCode {}

        /**
         * Retrieve the error code associated with a CryptoException
         */
        @CryptoErrorCode
        public int getErrorCode() {
            return mErrorCode;
        }

        private int mErrorCode;
    }

    /**
     * After filling a range of the input buffer at the specified index
     * submit it to the component. Once an input buffer is queued to
     * the codec, it MUST NOT be used until it is later retrieved by
     * {@link #getInputBuffer} in response to a {@link #dequeueInputBuffer}
     * return value or a {@link Callback#onInputBufferAvailable}
     * callback.
     * <p>
     * Many decoders require the actual compressed data stream to be
     * preceded by "codec specific data", i.e. setup data used to initialize
     * the codec such as PPS/SPS in the case of AVC video or code tables
     * in the case of vorbis audio.
     * The class {@link android.media.MediaExtractor} provides codec
     * specific data as part of
     * the returned track format in entries named "csd-0", "csd-1" ...
     * <p>
     * These buffers can be submitted directly after {@link #start} or
     * {@link #flush} by specifying the flag {@link
     * #BUFFER_FLAG_CODEC_CONFIG}.  However, if you configure the
     * codec with a {@link MediaFormat} containing these keys, they
     * will be automatically submitted by MediaCodec directly after
     * start.  Therefore, the use of {@link
     * #BUFFER_FLAG_CODEC_CONFIG} flag is discouraged and is
     * recommended only for advanced users.
     * <p>
     * To indicate that this is the final piece of input data (or rather that
     * no more input data follows unless the decoder is subsequently flushed)
     * specify the flag {@link #BUFFER_FLAG_END_OF_STREAM}.
     * <p class=note>
     * <strong>Note:</strong> Prior to {@link android.os.Build.VERSION_CODES#M},
     * {@code presentationTimeUs} was not propagated to the frame timestamp of (rendered)
     * Surface output buffers, and the resulting frame timestamp was undefined.
     * Use {@link #releaseOutputBuffer(int, long)} to ensure a specific frame timestamp is set.
     * Similarly, since frame timestamps can be used by the destination surface for rendering
     * synchronization, <strong>care must be taken to normalize presentationTimeUs so as to not be
     * mistaken for a system time. (See {@linkplain #releaseOutputBuffer(int, long)
     * SurfaceView specifics}).</strong>
     *
     * @param index The index of a client-owned input buffer previously returned
     *              in a call to {@link #dequeueInputBuffer}.
     * @param offset The byte offset into the input buffer at which the data starts.
     * @param size The number of bytes of valid input data.
     * @param presentationTimeUs The presentation timestamp in microseconds for this
     *                           buffer. This is normally the media time at which this
     *                           buffer should be presented (rendered). When using an output
     *                           surface, this will be propagated as the {@link
     *                           SurfaceTexture#getTimestamp timestamp} for the frame (after
     *                           conversion to nanoseconds).
     * @param flags A bitmask of flags
     *              {@link #BUFFER_FLAG_CODEC_CONFIG} and {@link #BUFFER_FLAG_END_OF_STREAM}.
     *              While not prohibited, most codecs do not use the
     *              {@link #BUFFER_FLAG_KEY_FRAME} flag for input buffers.
     * @throws IllegalStateException if not in the Executing state.
     * @throws MediaCodec.CodecException upon codec error.
     * @throws CryptoException if a crypto object has been specified in
     *         {@link #configure}
     */
    public final void queueInputBuffer(
            int index,
            int offset, int size, long presentationTimeUs, int flags)
        throws CryptoException {
        synchronized(mBufferLock) {
            invalidateByteBuffer(mCachedInputBuffers, index);
            mDequeuedInputBuffers.remove(index);
        }
        try {
            native_queueInputBuffer(
                    index, offset, size, presentationTimeUs, flags);
        } catch (CryptoException | IllegalStateException e) {
            revalidateByteBuffer(mCachedInputBuffers, index);
            throw e;
        }
    }

    private native final void native_queueInputBuffer(
            int index,
            int offset, int size, long presentationTimeUs, int flags)
        throws CryptoException;

    public static final int CRYPTO_MODE_UNENCRYPTED = 0;
    public static final int CRYPTO_MODE_AES_CTR     = 1;
    public static final int CRYPTO_MODE_AES_CBC     = 2;

    /**
     * Metadata describing the structure of an encrypted input sample.
     * <p>
     * A buffer's data is considered to be partitioned into "subSamples". Each subSample starts with
     * a run of plain, unencrypted bytes followed by a run of encrypted bytes. Either of these runs
     * may be empty. If pattern encryption applies, each of the encrypted runs is encrypted only
     * partly, according to a repeating pattern of "encrypt" and "skip" blocks.
     * {@link #numBytesOfClearData} can be null to indicate that all data is encrypted, and
     * {@link #numBytesOfEncryptedData} can be null to indicate that all data is clear. At least one
     * of {@link #numBytesOfClearData} and {@link #numBytesOfEncryptedData} must be non-null.
     * <p>
     * This information encapsulates per-sample metadata as outlined in ISO/IEC FDIS 23001-7:2016
     * "Common encryption in ISO base media file format files".
     * <p>
     * <h3>ISO-CENC Schemes</h3>
     * ISO/IEC FDIS 23001-7:2016 defines four possible schemes by which media may be encrypted,
     * corresponding to each possible combination of an AES mode with the presence or absence of
     * patterned encryption.
     *
     * <table style="width: 0%">
     *   <thead>
     *     <tr>
     *       <th>&nbsp;</th>
     *       <th>AES-CTR</th>
     *       <th>AES-CBC</th>
     *     </tr>
     *   </thead>
     *   <tbody>
     *     <tr>
     *       <th>Without Patterns</th>
     *       <td>cenc</td>
     *       <td>cbc1</td>
     *     </tr><tr>
     *       <th>With Patterns</th>
     *       <td>cens</td>
     *       <td>cbcs</td>
     *     </tr>
     *   </tbody>
     * </table>
     *
     * For {@code CryptoInfo}, the scheme is selected implicitly by the combination of the
     * {@link #mode} field and the value set with {@link #setPattern}. For the pattern, setting the
     * pattern to all zeroes (that is, both {@code blocksToEncrypt} and {@code blocksToSkip} are
     * zero) is interpreted as turning patterns off completely. A scheme that does not use patterns
     * will be selected, either cenc or cbc1. Setting the pattern to any nonzero value will choose
     * one of the pattern-supporting schemes, cens or cbcs. The default pattern if
     * {@link #setPattern} is never called is all zeroes.
     * <p>
     * <h4>HLS SAMPLE-AES Audio</h4>
     * HLS SAMPLE-AES audio is encrypted in a manner compatible with the cbcs scheme, except that it
     * does not use patterned encryption. However, if {@link #setPattern} is used to set the pattern
     * to all zeroes, this will be interpreted as selecting the cbc1 scheme. The cbc1 scheme cannot
     * successfully decrypt HLS SAMPLE-AES audio because of differences in how the IVs are handled.
     * For this reason, it is recommended that a pattern of {@code 1} encrypted block and {@code 0}
     * skip blocks be used with HLS SAMPLE-AES audio. This will trigger decryption to use cbcs mode
     * while still decrypting every block.
     */
    public final static class CryptoInfo {
        /**
         * The number of subSamples that make up the buffer's contents.
         */
        public int numSubSamples;
        /**
         * The number of leading unencrypted bytes in each subSample. If null, all bytes are treated
         * as encrypted and {@link #numBytesOfEncryptedData} must be specified.
         */
        public int[] numBytesOfClearData;
        /**
         * The number of trailing encrypted bytes in each subSample. If null, all bytes are treated
         * as clear and {@link #numBytesOfClearData} must be specified.
         */
        public int[] numBytesOfEncryptedData;
        /**
         * A 16-byte key id
         */
        public byte[] key;
        /**
         * A 16-byte initialization vector
         */
        public byte[] iv;
        /**
         * The type of encryption that has been applied,
         * see {@link #CRYPTO_MODE_UNENCRYPTED}, {@link #CRYPTO_MODE_AES_CTR}
         * and {@link #CRYPTO_MODE_AES_CBC}
         */
        public int mode;

        /**
         * Metadata describing an encryption pattern for the protected bytes in a subsample.  An
         * encryption pattern consists of a repeating sequence of crypto blocks comprised of a
         * number of encrypted blocks followed by a number of unencrypted, or skipped, blocks.
         */
        public final static class Pattern {
            /**
             * Number of blocks to be encrypted in the pattern. If both this and
             * {@link #mSkipBlocks} are zero, pattern encryption is inoperative.
             */
            private int mEncryptBlocks;

            /**
             * Number of blocks to be skipped (left clear) in the pattern. If both this and
             * {@link #mEncryptBlocks} are zero, pattern encryption is inoperative.
             */
            private int mSkipBlocks;

            /**
             * Construct a sample encryption pattern given the number of blocks to encrypt and skip
             * in the pattern. If both parameters are zero, pattern encryption is inoperative.
             */
            public Pattern(int blocksToEncrypt, int blocksToSkip) {
                set(blocksToEncrypt, blocksToSkip);
            }

            /**
             * Set the number of blocks to encrypt and skip in a sample encryption pattern. If both
             * parameters are zero, pattern encryption is inoperative.
             */
            public void set(int blocksToEncrypt, int blocksToSkip) {
                mEncryptBlocks = blocksToEncrypt;
                mSkipBlocks = blocksToSkip;
            }

            /**
             * Return the number of blocks to skip in a sample encryption pattern.
             */
            public int getSkipBlocks() {
                return mSkipBlocks;
            }

            /**
             * Return the number of blocks to encrypt in a sample encryption pattern.
             */
            public int getEncryptBlocks() {
                return mEncryptBlocks;
            }
        };

        private final Pattern zeroPattern = new Pattern(0, 0);

        /**
         * The pattern applicable to the protected data in each subsample.
         */
        private Pattern pattern;

        /**
         * Set the subsample count, clear/encrypted sizes, key, IV and mode fields of
         * a {@link MediaCodec.CryptoInfo} instance.
         */
        public void set(
                int newNumSubSamples,
                @NonNull int[] newNumBytesOfClearData,
                @NonNull int[] newNumBytesOfEncryptedData,
                @NonNull byte[] newKey,
                @NonNull byte[] newIV,
                int newMode) {
            numSubSamples = newNumSubSamples;
            numBytesOfClearData = newNumBytesOfClearData;
            numBytesOfEncryptedData = newNumBytesOfEncryptedData;
            key = newKey;
            iv = newIV;
            mode = newMode;
            pattern = zeroPattern;
        }

        /**
         * Set the encryption pattern on a {@link MediaCodec.CryptoInfo} instance.
         * See {@link MediaCodec.CryptoInfo.Pattern}.
         */
        public void setPattern(Pattern newPattern) {
            pattern = newPattern;
        }

        private void setPattern(int blocksToEncrypt, int blocksToSkip) {
            pattern = new Pattern(blocksToEncrypt, blocksToSkip);
        }

        @Override
        public String toString() {
            StringBuilder builder = new StringBuilder();
            builder.append(numSubSamples + " subsamples, key [");
            String hexdigits = "0123456789abcdef";
            for (int i = 0; i < key.length; i++) {
                builder.append(hexdigits.charAt((key[i] & 0xf0) >> 4));
                builder.append(hexdigits.charAt(key[i] & 0x0f));
            }
            builder.append("], iv [");
            for (int i = 0; i < key.length; i++) {
                builder.append(hexdigits.charAt((iv[i] & 0xf0) >> 4));
                builder.append(hexdigits.charAt(iv[i] & 0x0f));
            }
            builder.append("], clear ");
            builder.append(Arrays.toString(numBytesOfClearData));
            builder.append(", encrypted ");
            builder.append(Arrays.toString(numBytesOfEncryptedData));
            return builder.toString();
        }
    };

    /**
     * Similar to {@link #queueInputBuffer queueInputBuffer} but submits a buffer that is
     * potentially encrypted.
     * <strong>Check out further notes at {@link #queueInputBuffer queueInputBuffer}.</strong>
     *
     * @param index The index of a client-owned input buffer previously returned
     *              in a call to {@link #dequeueInputBuffer}.
     * @param offset The byte offset into the input buffer at which the data starts.
     * @param info Metadata required to facilitate decryption, the object can be
     *             reused immediately after this call returns.
     * @param presentationTimeUs The presentation timestamp in microseconds for this
     *                           buffer. This is normally the media time at which this
     *                           buffer should be presented (rendered).
     * @param flags A bitmask of flags
     *              {@link #BUFFER_FLAG_CODEC_CONFIG} and {@link #BUFFER_FLAG_END_OF_STREAM}.
     *              While not prohibited, most codecs do not use the
     *              {@link #BUFFER_FLAG_KEY_FRAME} flag for input buffers.
     * @throws IllegalStateException if not in the Executing state.
     * @throws MediaCodec.CodecException upon codec error.
     * @throws CryptoException if an error occurs while attempting to decrypt the buffer.
     *              An error code associated with the exception helps identify the
     *              reason for the failure.
     */
    public final void queueSecureInputBuffer(
            int index,
            int offset,
            @NonNull CryptoInfo info,
            long presentationTimeUs,
            int flags) throws CryptoException {
        synchronized(mBufferLock) {
            invalidateByteBuffer(mCachedInputBuffers, index);
            mDequeuedInputBuffers.remove(index);
        }
        try {
            native_queueSecureInputBuffer(
                    index, offset, info, presentationTimeUs, flags);
        } catch (CryptoException | IllegalStateException e) {
            revalidateByteBuffer(mCachedInputBuffers, index);
            throw e;
        }
    }

    private native final void native_queueSecureInputBuffer(
            int index,
            int offset,
            @NonNull CryptoInfo info,
            long presentationTimeUs,
            int flags) throws CryptoException;

    /**
     * Returns the index of an input buffer to be filled with valid data
     * or -1 if no such buffer is currently available.
     * This method will return immediately if timeoutUs == 0, wait indefinitely
     * for the availability of an input buffer if timeoutUs &lt; 0 or wait up
     * to "timeoutUs" microseconds if timeoutUs &gt; 0.
     * @param timeoutUs The timeout in microseconds, a negative timeout indicates "infinite".
     * @throws IllegalStateException if not in the Executing state,
     *         or codec is configured in asynchronous mode.
     * @throws MediaCodec.CodecException upon codec error.
     */
    public final int dequeueInputBuffer(long timeoutUs) {
        int res = native_dequeueInputBuffer(timeoutUs);
        if (res >= 0) {
            synchronized(mBufferLock) {
                validateInputByteBuffer(mCachedInputBuffers, res);
            }
        }
        return res;
    }

    private native final int native_dequeueInputBuffer(long timeoutUs);

    /**
     * If a non-negative timeout had been specified in the call
     * to {@link #dequeueOutputBuffer}, indicates that the call timed out.
     */
    public static final int INFO_TRY_AGAIN_LATER        = -1;

    /**
     * The output format has changed, subsequent data will follow the new
     * format. {@link #getOutputFormat()} returns the new format.  Note, that
     * you can also use the new {@link #getOutputFormat(int)} method to
     * get the format for a specific output buffer.  This frees you from
     * having to track output format changes.
     */
    public static final int INFO_OUTPUT_FORMAT_CHANGED  = -2;

    /**
     * The output buffers have changed, the client must refer to the new
     * set of output buffers returned by {@link #getOutputBuffers} from
     * this point on.
     *
     * <p>Additionally, this event signals that the video scaling mode
     * may have been reset to the default.</p>
     *
     * @deprecated This return value can be ignored as {@link
     * #getOutputBuffers} has been deprecated.  Client should
     * request a current buffer using on of the get-buffer or
     * get-image methods each time one has been dequeued.
     */
    public static final int INFO_OUTPUT_BUFFERS_CHANGED = -3;

    /** @hide */
    @IntDef({
        INFO_TRY_AGAIN_LATER,
        INFO_OUTPUT_FORMAT_CHANGED,
        INFO_OUTPUT_BUFFERS_CHANGED,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface OutputBufferInfo {}

    /**
     * Dequeue an output buffer, block at most "timeoutUs" microseconds.
     * Returns the index of an output buffer that has been successfully
     * decoded or one of the INFO_* constants.
     * @param info Will be filled with buffer meta data.
     * @param timeoutUs The timeout in microseconds, a negative timeout indicates "infinite".
     * @throws IllegalStateException if not in the Executing state,
     *         or codec is configured in asynchronous mode.
     * @throws MediaCodec.CodecException upon codec error.
     */
    @OutputBufferInfo
    public final int dequeueOutputBuffer(
            @NonNull BufferInfo info, long timeoutUs) {
        int res = native_dequeueOutputBuffer(info, timeoutUs);
        synchronized(mBufferLock) {
            if (res == INFO_OUTPUT_BUFFERS_CHANGED) {
                cacheBuffers(false /* input */);
            } else if (res >= 0) {
                validateOutputByteBuffer(mCachedOutputBuffers, res, info);
                if (mHasSurface) {
                    mDequeuedOutputInfos.put(res, info.dup());
                }
            }
        }
        return res;
    }

    private native final int native_dequeueOutputBuffer(
            @NonNull BufferInfo info, long timeoutUs);

    /**
     * If you are done with a buffer, use this call to return the buffer to the codec
     * or to render it on the output surface. If you configured the codec with an
     * output surface, setting {@code render} to {@code true} will first send the buffer
     * to that output surface. The surface will release the buffer back to the codec once
     * it is no longer used/displayed.
     *
     * Once an output buffer is released to the codec, it MUST NOT
     * be used until it is later retrieved by {@link #getOutputBuffer} in response
     * to a {@link #dequeueOutputBuffer} return value or a
     * {@link Callback#onOutputBufferAvailable} callback.
     *
     * @param index The index of a client-owned output buffer previously returned
     *              from a call to {@link #dequeueOutputBuffer}.
     * @param render If a valid surface was specified when configuring the codec,
     *               passing true renders this output buffer to the surface.
     * @throws IllegalStateException if not in the Executing state.
     * @throws MediaCodec.CodecException upon codec error.
     */
    public final void releaseOutputBuffer(int index, boolean render) {
        BufferInfo info = null;
        synchronized(mBufferLock) {
            invalidateByteBuffer(mCachedOutputBuffers, index);
            mDequeuedOutputBuffers.remove(index);
            if (mHasSurface) {
                info = mDequeuedOutputInfos.remove(index);
            }
        }
        releaseOutputBuffer(index, render, false /* updatePTS */, 0 /* dummy */);
    }

    /**
     * If you are done with a buffer, use this call to update its surface timestamp
     * and return it to the codec to render it on the output surface. If you
     * have not specified an output surface when configuring this video codec,
     * this call will simply return the buffer to the codec.<p>
     *
     * The timestamp may have special meaning depending on the destination surface.
     *
     * <table>
     * <tr><th>SurfaceView specifics</th></tr>
     * <tr><td>
     * If you render your buffer on a {@link android.view.SurfaceView},
     * you can use the timestamp to render the buffer at a specific time (at the
     * VSYNC at or after the buffer timestamp).  For this to work, the timestamp
     * needs to be <i>reasonably close</i> to the current {@link System#nanoTime}.
     * Currently, this is set as within one (1) second. A few notes:
     *
     * <ul>
     * <li>the buffer will not be returned to the codec until the timestamp
     * has passed and the buffer is no longer used by the {@link android.view.Surface}.
     * <li>buffers are processed sequentially, so you may block subsequent buffers to
     * be displayed on the {@link android.view.Surface}.  This is important if you
     * want to react to user action, e.g. stop the video or seek.
     * <li>if multiple buffers are sent to the {@link android.view.Surface} to be
     * rendered at the same VSYNC, the last one will be shown, and the other ones
     * will be dropped.
     * <li>if the timestamp is <em>not</em> "reasonably close" to the current system
     * time, the {@link android.view.Surface} will ignore the timestamp, and
     * display the buffer at the earliest feasible time.  In this mode it will not
     * drop frames.
     * <li>for best performance and quality, call this method when you are about
     * two VSYNCs' time before the desired render time.  For 60Hz displays, this is
     * about 33 msec.
     * </ul>
     * </td></tr>
     * </table>
     *
     * Once an output buffer is released to the codec, it MUST NOT
     * be used until it is later retrieved by {@link #getOutputBuffer} in response
     * to a {@link #dequeueOutputBuffer} return value or a
     * {@link Callback#onOutputBufferAvailable} callback.
     *
     * @param index The index of a client-owned output buffer previously returned
     *              from a call to {@link #dequeueOutputBuffer}.
     * @param renderTimestampNs The timestamp to associate with this buffer when
     *              it is sent to the Surface.
     * @throws IllegalStateException if not in the Executing state.
     * @throws MediaCodec.CodecException upon codec error.
     */
    public final void releaseOutputBuffer(int index, long renderTimestampNs) {
        BufferInfo info = null;
        synchronized(mBufferLock) {
            invalidateByteBuffer(mCachedOutputBuffers, index);
            mDequeuedOutputBuffers.remove(index);
            if (mHasSurface) {
                info = mDequeuedOutputInfos.remove(index);
            }
        }
        releaseOutputBuffer(
                index, true /* render */, true /* updatePTS */, renderTimestampNs);
    }

    @UnsupportedAppUsage
    private native final void releaseOutputBuffer(
            int index, boolean render, boolean updatePTS, long timeNs);

    /**
     * Signals end-of-stream on input.  Equivalent to submitting an empty buffer with
     * {@link #BUFFER_FLAG_END_OF_STREAM} set.  This may only be used with
     * encoders receiving input from a Surface created by {@link #createInputSurface}.
     * @throws IllegalStateException if not in the Executing state.
     * @throws MediaCodec.CodecException upon codec error.
     */
    public native final void signalEndOfInputStream();

    /**
     * Call this after dequeueOutputBuffer signals a format change by returning
     * {@link #INFO_OUTPUT_FORMAT_CHANGED}.
     * You can also call this after {@link #configure} returns
     * successfully to get the output format initially configured
     * for the codec.  Do this to determine what optional
     * configuration parameters were supported by the codec.
     *
     * @throws IllegalStateException if not in the Executing or
     *                               Configured state.
     * @throws MediaCodec.CodecException upon codec error.
     */
    @NonNull
    public final MediaFormat getOutputFormat() {
        return new MediaFormat(getFormatNative(false /* input */));
    }

    /**
     * Call this after {@link #configure} returns successfully to
     * get the input format accepted by the codec. Do this to
     * determine what optional configuration parameters were
     * supported by the codec.
     *
     * @throws IllegalStateException if not in the Executing or
     *                               Configured state.
     * @throws MediaCodec.CodecException upon codec error.
     */
    @NonNull
    public final MediaFormat getInputFormat() {
        return new MediaFormat(getFormatNative(true /* input */));
    }

    /**
     * Returns the output format for a specific output buffer.
     *
     * @param index The index of a client-owned input buffer previously
     *              returned from a call to {@link #dequeueInputBuffer}.
     *
     * @return the format for the output buffer, or null if the index
     * is not a dequeued output buffer.
     */
    @NonNull
    public final MediaFormat getOutputFormat(int index) {
        return new MediaFormat(getOutputFormatNative(index));
    }

    @NonNull
    private native final Map<String, Object> getFormatNative(boolean input);

    @NonNull
    private native final Map<String, Object> getOutputFormatNative(int index);

    // used to track dequeued buffers
    private static class BufferMap {
        // various returned representations of the codec buffer
        private static class CodecBuffer {
            private Image mImage;
            private ByteBuffer mByteBuffer;

            public void free() {
                if (mByteBuffer != null) {
                    // all of our ByteBuffers are direct
                    java.nio.NioUtils.freeDirectBuffer(mByteBuffer);
                    mByteBuffer = null;
                }
                if (mImage != null) {
                    mImage.close();
                    mImage = null;
                }
            }

            public void setImage(@Nullable Image image) {
                free();
                mImage = image;
            }

            public void setByteBuffer(@Nullable ByteBuffer buffer) {
                free();
                mByteBuffer = buffer;
            }
        }

        private final Map<Integer, CodecBuffer> mMap =
            new HashMap<Integer, CodecBuffer>();

        public void remove(int index) {
            CodecBuffer buffer = mMap.get(index);
            if (buffer != null) {
                buffer.free();
                mMap.remove(index);
            }
        }

        public void put(int index, @Nullable ByteBuffer newBuffer) {
            CodecBuffer buffer = mMap.get(index);
            if (buffer == null) { // likely
                buffer = new CodecBuffer();
                mMap.put(index, buffer);
            }
            buffer.setByteBuffer(newBuffer);
        }

        public void put(int index, @Nullable Image newImage) {
            CodecBuffer buffer = mMap.get(index);
            if (buffer == null) { // likely
                buffer = new CodecBuffer();
                mMap.put(index, buffer);
            }
            buffer.setImage(newImage);
        }

        public void clear() {
            for (CodecBuffer buffer: mMap.values()) {
                buffer.free();
            }
            mMap.clear();
        }
    }

    private ByteBuffer[] mCachedInputBuffers;
    private ByteBuffer[] mCachedOutputBuffers;
    private final BufferMap mDequeuedInputBuffers = new BufferMap();
    private final BufferMap mDequeuedOutputBuffers = new BufferMap();
    private final Map<Integer, BufferInfo> mDequeuedOutputInfos =
        new HashMap<Integer, BufferInfo>();
    final private Object mBufferLock;

    private final void invalidateByteBuffer(
            @Nullable ByteBuffer[] buffers, int index) {
        if (buffers != null && index >= 0 && index < buffers.length) {
            ByteBuffer buffer = buffers[index];
            if (buffer != null) {
                buffer.setAccessible(false);
            }
        }
    }

    private final void validateInputByteBuffer(
            @Nullable ByteBuffer[] buffers, int index) {
        if (buffers != null && index >= 0 && index < buffers.length) {
            ByteBuffer buffer = buffers[index];
            if (buffer != null) {
                buffer.setAccessible(true);
                buffer.clear();
            }
        }
    }

    private final void revalidateByteBuffer(
            @Nullable ByteBuffer[] buffers, int index) {
        synchronized(mBufferLock) {
            if (buffers != null && index >= 0 && index < buffers.length) {
                ByteBuffer buffer = buffers[index];
                if (buffer != null) {
                    buffer.setAccessible(true);
                }
            }
        }
    }

    private final void validateOutputByteBuffer(
            @Nullable ByteBuffer[] buffers, int index, @NonNull BufferInfo info) {
        if (buffers != null && index >= 0 && index < buffers.length) {
            ByteBuffer buffer = buffers[index];
            if (buffer != null) {
                buffer.setAccessible(true);
                buffer.limit(info.offset + info.size).position(info.offset);
            }
        }
    }

    private final void invalidateByteBuffers(@Nullable ByteBuffer[] buffers) {
        if (buffers != null) {
            for (ByteBuffer buffer: buffers) {
                if (buffer != null) {
                    buffer.setAccessible(false);
                }
            }
        }
    }

    private final void freeByteBuffer(@Nullable ByteBuffer buffer) {
        if (buffer != null /* && buffer.isDirect() */) {
            // all of our ByteBuffers are direct
            java.nio.NioUtils.freeDirectBuffer(buffer);
        }
    }

    private final void freeByteBuffers(@Nullable ByteBuffer[] buffers) {
        if (buffers != null) {
            for (ByteBuffer buffer: buffers) {
                freeByteBuffer(buffer);
            }
        }
    }

    private final void freeAllTrackedBuffers() {
        synchronized(mBufferLock) {
            freeByteBuffers(mCachedInputBuffers);
            freeByteBuffers(mCachedOutputBuffers);
            mCachedInputBuffers = null;
            mCachedOutputBuffers = null;
            mDequeuedInputBuffers.clear();
            mDequeuedOutputBuffers.clear();
        }
    }

    private final void cacheBuffers(boolean input) {
        ByteBuffer[] buffers = null;
        try {
            buffers = getBuffers(input);
            invalidateByteBuffers(buffers);
        } catch (IllegalStateException e) {
            // we don't get buffers in async mode
        }
        if (input) {
            mCachedInputBuffers = buffers;
        } else {
            mCachedOutputBuffers = buffers;
        }
    }

    /**
     * Retrieve the set of input buffers.  Call this after start()
     * returns. After calling this method, any ByteBuffers
     * previously returned by an earlier call to this method MUST no
     * longer be used.
     *
     * @deprecated Use the new {@link #getInputBuffer} method instead
     * each time an input buffer is dequeued.
     *
     * <b>Note:</b> As of API 21, dequeued input buffers are
     * automatically {@link java.nio.Buffer#clear cleared}.
     *
     * <em>Do not use this method if using an input surface.</em>
     *
     * @throws IllegalStateException if not in the Executing state,
     *         or codec is configured in asynchronous mode.
     * @throws MediaCodec.CodecException upon codec error.
     */
    @NonNull
    public ByteBuffer[] getInputBuffers() {
        if (mCachedInputBuffers == null) {
            throw new IllegalStateException();
        }
        // FIXME: check codec status
        return mCachedInputBuffers;
    }

    /**
     * Retrieve the set of output buffers.  Call this after start()
     * returns and whenever dequeueOutputBuffer signals an output
     * buffer change by returning {@link
     * #INFO_OUTPUT_BUFFERS_CHANGED}. After calling this method, any
     * ByteBuffers previously returned by an earlier call to this
     * method MUST no longer be used.
     *
     * @deprecated Use the new {@link #getOutputBuffer} method instead
     * each time an output buffer is dequeued.  This method is not
     * supported if codec is configured in asynchronous mode.
     *
     * <b>Note:</b> As of API 21, the position and limit of output
     * buffers that are dequeued will be set to the valid data
     * range.
     *
     * <em>Do not use this method if using an output surface.</em>
     *
     * @throws IllegalStateException if not in the Executing state,
     *         or codec is configured in asynchronous mode.
     * @throws MediaCodec.CodecException upon codec error.
     */
    @NonNull
    public ByteBuffer[] getOutputBuffers() {
        if (mCachedOutputBuffers == null) {
            throw new IllegalStateException();
        }
        // FIXME: check codec status
        return mCachedOutputBuffers;
    }

    /**
     * Returns a {@link java.nio.Buffer#clear cleared}, writable ByteBuffer
     * object for a dequeued input buffer index to contain the input data.
     *
     * After calling this method any ByteBuffer or Image object
     * previously returned for the same input index MUST no longer
     * be used.
     *
     * @param index The index of a client-owned input buffer previously
     *              returned from a call to {@link #dequeueInputBuffer},
     *              or received via an onInputBufferAvailable callback.
     *
     * @return the input buffer, or null if the index is not a dequeued
     * input buffer, or if the codec is configured for surface input.
     *
     * @throws IllegalStateException if not in the Executing state.
     * @throws MediaCodec.CodecException upon codec error.
     */
    @Nullable
    public ByteBuffer getInputBuffer(int index) {
        ByteBuffer newBuffer = getBuffer(true /* input */, index);
        synchronized(mBufferLock) {
            invalidateByteBuffer(mCachedInputBuffers, index);
            mDequeuedInputBuffers.put(index, newBuffer);
        }
        return newBuffer;
    }

    /**
     * Returns a writable Image object for a dequeued input buffer
     * index to contain the raw input video frame.
     *
     * After calling this method any ByteBuffer or Image object
     * previously returned for the same input index MUST no longer
     * be used.
     *
     * @param index The index of a client-owned input buffer previously
     *              returned from a call to {@link #dequeueInputBuffer},
     *              or received via an onInputBufferAvailable callback.
     *
     * @return the input image, or null if the index is not a
     * dequeued input buffer, or not a ByteBuffer that contains a
     * raw image.
     *
     * @throws IllegalStateException if not in the Executing state.
     * @throws MediaCodec.CodecException upon codec error.
     */
    @Nullable
    public Image getInputImage(int index) {
        Image newImage = getImage(true /* input */, index);
        synchronized(mBufferLock) {
            invalidateByteBuffer(mCachedInputBuffers, index);
            mDequeuedInputBuffers.put(index, newImage);
        }
        return newImage;
    }

    /**
     * Returns a read-only ByteBuffer for a dequeued output buffer
     * index. The position and limit of the returned buffer are set
     * to the valid output data.
     *
     * After calling this method, any ByteBuffer or Image object
     * previously returned for the same output index MUST no longer
     * be used.
     *
     * @param index The index of a client-owned output buffer previously
     *              returned from a call to {@link #dequeueOutputBuffer},
     *              or received via an onOutputBufferAvailable callback.
     *
     * @return the output buffer, or null if the index is not a dequeued
     * output buffer, or the codec is configured with an output surface.
     *
     * @throws IllegalStateException if not in the Executing state.
     * @throws MediaCodec.CodecException upon codec error.
     */
    @Nullable
    public ByteBuffer getOutputBuffer(int index) {
        ByteBuffer newBuffer = getBuffer(false /* input */, index);
        synchronized(mBufferLock) {
            invalidateByteBuffer(mCachedOutputBuffers, index);
            mDequeuedOutputBuffers.put(index, newBuffer);
        }
        return newBuffer;
    }

    /**
     * Returns a read-only Image object for a dequeued output buffer
     * index that contains the raw video frame.
     *
     * After calling this method, any ByteBuffer or Image object previously
     * returned for the same output index MUST no longer be used.
     *
     * @param index The index of a client-owned output buffer previously
     *              returned from a call to {@link #dequeueOutputBuffer},
     *              or received via an onOutputBufferAvailable callback.
     *
     * @return the output image, or null if the index is not a
     * dequeued output buffer, not a raw video frame, or if the codec
     * was configured with an output surface.
     *
     * @throws IllegalStateException if not in the Executing state.
     * @throws MediaCodec.CodecException upon codec error.
     */
    @Nullable
    public Image getOutputImage(int index) {
        Image newImage = getImage(false /* input */, index);
        synchronized(mBufferLock) {
            invalidateByteBuffer(mCachedOutputBuffers, index);
            mDequeuedOutputBuffers.put(index, newImage);
        }
        return newImage;
    }

    /**
     * The content is scaled to the surface dimensions
     */
    public static final int VIDEO_SCALING_MODE_SCALE_TO_FIT               = 1;

    /**
     * The content is scaled, maintaining its aspect ratio, the whole
     * surface area is used, content may be cropped.
     * <p class=note>
     * This mode is only suitable for content with 1:1 pixel aspect ratio as you cannot
     * configure the pixel aspect ratio for a {@link Surface}.
     * <p class=note>
     * As of {@link android.os.Build.VERSION_CODES#N} release, this mode may not work if
     * the video is {@linkplain MediaFormat#KEY_ROTATION rotated} by 90 or 270 degrees.
     */
    public static final int VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING = 2;

    /** @hide */
    @IntDef({
        VIDEO_SCALING_MODE_SCALE_TO_FIT,
        VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface VideoScalingMode {}

    /**
     * If a surface has been specified in a previous call to {@link #configure}
     * specifies the scaling mode to use. The default is "scale to fit".
     * <p class=note>
     * The scaling mode may be reset to the <strong>default</strong> each time an
     * {@link #INFO_OUTPUT_BUFFERS_CHANGED} event is received from the codec; therefore, the client
     * must call this method after every buffer change event (and before the first output buffer is
     * released for rendering) to ensure consistent scaling mode.
     * <p class=note>
     * Since the {@link #INFO_OUTPUT_BUFFERS_CHANGED} event is deprecated, this can also be done
     * after each {@link #INFO_OUTPUT_FORMAT_CHANGED} event.
     *
     * @throws IllegalArgumentException if mode is not recognized.
     * @throws IllegalStateException if in the Released state.
     */
    public native final void setVideoScalingMode(@VideoScalingMode int mode);

    /**
     * Sets the audio presentation.
     * @param presentation see {@link AudioPresentation}. In particular, id should be set.
     */
    public void setAudioPresentation(@NonNull AudioPresentation presentation) {
        if (presentation == null) {
            throw new NullPointerException("audio presentation is null");
        }
        native_setAudioPresentation(presentation.getPresentationId(), presentation.getProgramId());
    }

    private native void native_setAudioPresentation(int presentationId, int programId);

    /**
     * Retrieve the codec name.
     *
     * If the codec was created by createDecoderByType or createEncoderByType, what component is
     * chosen is not known beforehand. This method returns the name of the codec that was
     * selected by the platform.
     *
     * <strong>Note:</strong> Implementations may provide multiple aliases (codec
     * names) for the same underlying codec, any of which can be used to instantiate the same
     * underlying codec in {@link MediaCodec#createByCodecName}. This method returns the
     * name used to create the codec in this case.
     *
     * @throws IllegalStateException if in the Released state.
     */
    @NonNull
    public final String getName() {
        // get canonical name to handle exception
        String canonicalName = getCanonicalName();
        return mNameAtCreation != null ? mNameAtCreation : canonicalName;
    }

    /**
     * Retrieve the underlying codec name.
     *
     * This method is similar to {@link #getName}, except that it returns the underlying component
     * name even if an alias was used to create this MediaCodec object by name,
     *
     * @throws IllegalStateException if in the Released state.
     */
    @NonNull
    public native final String getCanonicalName();

    /**
     *  Return Metrics data about the current codec instance.
     *
     * @return a {@link PersistableBundle} containing the set of attributes and values
     * available for the media being handled by this instance of MediaCodec
     * The attributes are descibed in {@link MetricsConstants}.
     *
     * Additional vendor-specific fields may also be present in
     * the return value.
     */
    public PersistableBundle getMetrics() {
        PersistableBundle bundle = native_getMetrics();
        return bundle;
    }

    private native PersistableBundle native_getMetrics();

    /**
     * Change a video encoder's target bitrate on the fly. The value is an
     * Integer object containing the new bitrate in bps.
     *
     * @see #setParameters(Bundle)
     */
    public static final String PARAMETER_KEY_VIDEO_BITRATE = "video-bitrate";

    /**
     * Temporarily suspend/resume encoding of input data. While suspended
     * input data is effectively discarded instead of being fed into the
     * encoder. This parameter really only makes sense to use with an encoder
     * in "surface-input" mode, as the client code has no control over the
     * input-side of the encoder in that case.
     * The value is an Integer object containing the value 1 to suspend
     * or the value 0 to resume.
     *
     * @see #setParameters(Bundle)
     */
    public static final String PARAMETER_KEY_SUSPEND = "drop-input-frames";

    /**
     * When {@link #PARAMETER_KEY_SUSPEND} is present, the client can also
     * optionally use this key to specify the timestamp (in micro-second)
     * at which the suspend/resume operation takes effect.
     *
     * Note that the specified timestamp must be greater than or equal to the
     * timestamp of any previously queued suspend/resume operations.
     *
     * The value is a long int, indicating the timestamp to suspend/resume.
     *
     * @see #setParameters(Bundle)
     */
    public static final String PARAMETER_KEY_SUSPEND_TIME = "drop-start-time-us";

    /**
     * Specify an offset (in micro-second) to be added on top of the timestamps
     * onward. A typical use case is to apply an adjust to the timestamps after
     * a period of pause by the user.
     *
     * This parameter can only be used on an encoder in "surface-input" mode.
     *
     * The value is a long int, indicating the timestamp offset to be applied.
     *
     * @see #setParameters(Bundle)
     */
    public static final String PARAMETER_KEY_OFFSET_TIME = "time-offset-us";

    /**
     * Request that the encoder produce a sync frame "soon".
     * Provide an Integer with the value 0.
     *
     * @see #setParameters(Bundle)
     */
    public static final String PARAMETER_KEY_REQUEST_SYNC_FRAME = "request-sync";

    /**
     * Set the HDR10+ metadata on the next queued input frame.
     *
     * Provide a byte array of data that's conforming to the
     * user_data_registered_itu_t_t35() syntax of SEI message for ST 2094-40.
     *<p>
     * For decoders:
     *<p>
     * When a decoder is configured for one of the HDR10+ profiles that uses
     * out-of-band metadata (such as {@link
     * MediaCodecInfo.CodecProfileLevel#VP9Profile2HDR10Plus} or {@link
     * MediaCodecInfo.CodecProfileLevel#VP9Profile3HDR10Plus}), this
     * parameter sets the HDR10+ metadata on the next input buffer queued
     * to the decoder. A decoder supporting these profiles must propagate
     * the metadata to the format of the output buffer corresponding to this
     * particular input buffer (under key {@link MediaFormat#KEY_HDR10_PLUS_INFO}).
     * The metadata should be applied to that output buffer and the buffers
     * following it (in display order), until the next output buffer (in
     * display order) upon which an HDR10+ metadata is set.
     *<p>
     * This parameter shouldn't be set if the decoder is not configured for
     * an HDR10+ profile that uses out-of-band metadata. In particular,
     * it shouldn't be set for HDR10+ profiles that uses in-band metadata
     * where the metadata is embedded in the input buffers, for example
     * {@link MediaCodecInfo.CodecProfileLevel#HEVCProfileMain10HDR10Plus}.
     *<p>
     * For encoders:
     *<p>
     * When an encoder is configured for one of the HDR10+ profiles and the
     * operates in byte buffer input mode (instead of surface input mode),
     * this parameter sets the HDR10+ metadata on the next input buffer queued
     * to the encoder. For the HDR10+ profiles that uses out-of-band metadata
     * (such as {@link MediaCodecInfo.CodecProfileLevel#VP9Profile2HDR10Plus},
     * or {@link MediaCodecInfo.CodecProfileLevel#VP9Profile3HDR10Plus}),
     * the metadata must be propagated to the format of the output buffer
     * corresponding to this particular input buffer (under key {@link
     * MediaFormat#KEY_HDR10_PLUS_INFO}). For the HDR10+ profiles that uses
     * in-band metadata (such as {@link
     * MediaCodecInfo.CodecProfileLevel#HEVCProfileMain10HDR10Plus}), the
     * metadata info must be embedded in the corresponding output buffer itself.
     *<p>
     * This parameter shouldn't be set if the encoder is not configured for
     * an HDR10+ profile, or if it's operating in surface input mode.
     *<p>
     *
     * @see MediaFormat#KEY_HDR10_PLUS_INFO
     */
    public static final String PARAMETER_KEY_HDR10_PLUS_INFO = MediaFormat.KEY_HDR10_PLUS_INFO;

    /**
     * Communicate additional parameter changes to the component instance.
     * <b>Note:</b> Some of these parameter changes may silently fail to apply.
     *
     * @param params The bundle of parameters to set.
     * @throws IllegalStateException if in the Released state.
     */
    public final void setParameters(@Nullable Bundle params) {
        if (params == null) {
            return;
        }

        String[] keys = new String[params.size()];
        Object[] values = new Object[params.size()];

        int i = 0;
        for (final String key: params.keySet()) {
            keys[i] = key;
            Object value = params.get(key);

            // Bundle's byte array is a byte[], JNI layer only takes ByteBuffer
            if (value instanceof byte[]) {
                values[i] = ByteBuffer.wrap((byte[])value);
            } else {
                values[i] = value;
            }
            ++i;
        }

        setParameters(keys, values);
    }

    /**
     * Sets an asynchronous callback for actionable MediaCodec events.
     *
     * If the client intends to use the component in asynchronous mode,
     * a valid callback should be provided before {@link #configure} is called.
     *
     * When asynchronous callback is enabled, the client should not call
     * {@link #getInputBuffers}, {@link #getOutputBuffers},
     * {@link #dequeueInputBuffer(long)} or {@link #dequeueOutputBuffer(BufferInfo, long)}.
     * <p>
     * Also, {@link #flush} behaves differently in asynchronous mode.  After calling
     * {@code flush}, you must call {@link #start} to "resume" receiving input buffers,
     * even if an input surface was created.
     *
     * @param cb The callback that will run.  Use {@code null} to clear a previously
     *           set callback (before {@link #configure configure} is called and run
     *           in synchronous mode).
     * @param handler Callbacks will happen on the handler's thread. If {@code null},
     *           callbacks are done on the default thread (the caller's thread or the
     *           main thread.)
     */
    public void setCallback(@Nullable /* MediaCodec. */ Callback cb, @Nullable Handler handler) {
        if (cb != null) {
            synchronized (mListenerLock) {
                EventHandler newHandler = getEventHandlerOn(handler, mCallbackHandler);
                // NOTE: there are no callbacks on the handler at this time, but check anyways
                // even if we were to extend this to be callable dynamically, it must
                // be called when codec is flushed, so no messages are pending.
                if (newHandler != mCallbackHandler) {
                    mCallbackHandler.removeMessages(EVENT_SET_CALLBACK);
                    mCallbackHandler.removeMessages(EVENT_CALLBACK);
                    mCallbackHandler = newHandler;
                }
            }
        } else if (mCallbackHandler != null) {
            mCallbackHandler.removeMessages(EVENT_SET_CALLBACK);
            mCallbackHandler.removeMessages(EVENT_CALLBACK);
        }

        if (mCallbackHandler != null) {
            // set java callback on main handler
            Message msg = mCallbackHandler.obtainMessage(EVENT_SET_CALLBACK, 0, 0, cb);
            mCallbackHandler.sendMessage(msg);

            // set native handler here, don't post to handler because
            // it may cause the callback to be delayed and set in a wrong state.
            // Note that native codec may start sending events to the callback
            // handler after this returns.
            native_setCallback(cb);
        }
    }

    /**
     * Sets an asynchronous callback for actionable MediaCodec events on the default
     * looper.
     * <p>
     * Same as {@link #setCallback(Callback, Handler)} with handler set to null.
     * @param cb The callback that will run.  Use {@code null} to clear a previously
     *           set callback (before {@link #configure configure} is called and run
     *           in synchronous mode).
     * @see #setCallback(Callback, Handler)
     */
    public void setCallback(@Nullable /* MediaCodec. */ Callback cb) {
        setCallback(cb, null /* handler */);
    }

    /**
     * Listener to be called when an output frame has rendered on the output surface
     *
     * @see MediaCodec#setOnFrameRenderedListener
     */
    public interface OnFrameRenderedListener {

        /**
         * Called when an output frame has rendered on the output surface.
         * <p>
         * <strong>Note:</strong> This callback is for informational purposes only: to get precise
         * render timing samples, and can be significantly delayed and batched. Some frames may have
         * been rendered even if there was no callback generated.
         *
         * @param codec the MediaCodec instance
         * @param presentationTimeUs the presentation time (media time) of the frame rendered.
         *          This is usually the same as specified in {@link #queueInputBuffer}; however,
         *          some codecs may alter the media time by applying some time-based transformation,
         *          such as frame rate conversion. In that case, presentation time corresponds
         *          to the actual output frame rendered.
         * @param nanoTime The system time when the frame was rendered.
         *
         * @see System#nanoTime
         */
        public void onFrameRendered(
                @NonNull MediaCodec codec, long presentationTimeUs, long nanoTime);
    }

    /**
     * Registers a callback to be invoked when an output frame is rendered on the output surface.
     * <p>
     * This method can be called in any codec state, but will only have an effect in the
     * Executing state for codecs that render buffers to the output surface.
     * <p>
     * <strong>Note:</strong> This callback is for informational purposes only: to get precise
     * render timing samples, and can be significantly delayed and batched. Some frames may have
     * been rendered even if there was no callback generated.
     *
     * @param listener the callback that will be run
     * @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.
     */
    public void setOnFrameRenderedListener(
            @Nullable OnFrameRenderedListener listener, @Nullable Handler handler) {
        synchronized (mListenerLock) {
            mOnFrameRenderedListener = listener;
            if (listener != null) {
                EventHandler newHandler = getEventHandlerOn(handler, mOnFrameRenderedHandler);
                if (newHandler != mOnFrameRenderedHandler) {
                    mOnFrameRenderedHandler.removeMessages(EVENT_FRAME_RENDERED);
                }
                mOnFrameRenderedHandler = newHandler;
            } else if (mOnFrameRenderedHandler != null) {
                mOnFrameRenderedHandler.removeMessages(EVENT_FRAME_RENDERED);
            }
            native_enableOnFrameRenderedListener(listener != null);
        }
    }

    private native void native_enableOnFrameRenderedListener(boolean enable);

    private EventHandler getEventHandlerOn(
            @Nullable Handler handler, @NonNull EventHandler lastHandler) {
        if (handler == null) {
            return mEventHandler;
        } else {
            Looper looper = handler.getLooper();
            if (lastHandler.getLooper() == looper) {
                return lastHandler;
            } else {
                return new EventHandler(this, looper);
            }
        }
    }

    /**
     * MediaCodec callback interface. Used to notify the user asynchronously
     * of various MediaCodec events.
     */
    public static abstract class Callback {
        /**
         * Called when an input buffer becomes available.
         *
         * @param codec The MediaCodec object.
         * @param index The index of the available input buffer.
         */
        public abstract void onInputBufferAvailable(@NonNull MediaCodec codec, int index);

        /**
         * Called when an output buffer becomes available.
         *
         * @param codec The MediaCodec object.
         * @param index The index of the available output buffer.
         * @param info Info regarding the available output buffer {@link MediaCodec.BufferInfo}.
         */
        public abstract void onOutputBufferAvailable(
                @NonNull MediaCodec codec, int index, @NonNull BufferInfo info);

        /**
         * Called when the MediaCodec encountered an error
         *
         * @param codec The MediaCodec object.
         * @param e The {@link MediaCodec.CodecException} object describing the error.
         */
        public abstract void onError(@NonNull MediaCodec codec, @NonNull CodecException e);

        /**
         * Called when the output format has changed
         *
         * @param codec The MediaCodec object.
         * @param format The new output format.
         */
        public abstract void onOutputFormatChanged(
                @NonNull MediaCodec codec, @NonNull MediaFormat format);
    }

    private void postEventFromNative(
            int what, int arg1, int arg2, @Nullable Object obj) {
        synchronized (mListenerLock) {
            EventHandler handler = mEventHandler;
            if (what == EVENT_CALLBACK) {
                handler = mCallbackHandler;
            } else if (what == EVENT_FRAME_RENDERED) {
                handler = mOnFrameRenderedHandler;
            }
            if (handler != null) {
                Message msg = handler.obtainMessage(what, arg1, arg2, obj);
                handler.sendMessage(msg);
            }
        }
    }

    @UnsupportedAppUsage
    private native final void setParameters(@NonNull String[] keys, @NonNull Object[] values);

    /**
     * Get the codec info. If the codec was created by createDecoderByType
     * or createEncoderByType, what component is chosen is not known beforehand,
     * and thus the caller does not have the MediaCodecInfo.
     * @throws IllegalStateException if in the Released state.
     */
    @NonNull
    public MediaCodecInfo getCodecInfo() {
        // Get the codec name first. If the codec is already released,
        // IllegalStateException will be thrown here.
        String name = getName();
        synchronized (mCodecInfoLock) {
            if (mCodecInfo == null) {
                // Get the codec info for this codec itself first. Only initialize
                // the full codec list if this somehow fails because it can be slow.
                mCodecInfo = getOwnCodecInfo();
                if (mCodecInfo == null) {
                    mCodecInfo = MediaCodecList.getInfoFor(name);
                }
            }
            return mCodecInfo;
        }
    }

    @NonNull
    private native final MediaCodecInfo getOwnCodecInfo();

    @NonNull
    @UnsupportedAppUsage
    private native final ByteBuffer[] getBuffers(boolean input);

    @Nullable
    private native final ByteBuffer getBuffer(boolean input, int index);

    @Nullable
    private native final Image getImage(boolean input, int index);

    private static native final void native_init();

    private native final void native_setup(
            @NonNull String name, boolean nameIsType, boolean encoder);

    private native final void native_finalize();

    static {
        System.loadLibrary("media_jni");
        native_init();
    }

    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    private long mNativeContext = 0;
    private final Lock mNativeContextLock = new ReentrantLock();

    private final long lockAndGetContext() {
        mNativeContextLock.lock();
        return mNativeContext;
    }

    private final void setAndUnlockContext(long context) {
        mNativeContext = context;
        mNativeContextLock.unlock();
    }

    /** @hide */
    public static class MediaImage extends Image {
        private final boolean mIsReadOnly;
        private final int mWidth;
        private final int mHeight;
        private final int mFormat;
        private long mTimestamp;
        private final Plane[] mPlanes;
        private final ByteBuffer mBuffer;
        private final ByteBuffer mInfo;
        private final int mXOffset;
        private final int mYOffset;

        private final static int TYPE_YUV = 1;

        private final int mTransform = 0; //Default no transform
        private final int mScalingMode = 0; //Default frozen scaling mode

        @Override
        public int getFormat() {
            throwISEIfImageIsInvalid();
            return mFormat;
        }

        @Override
        public int getHeight() {
            throwISEIfImageIsInvalid();
            return mHeight;
        }

        @Override
        public int getWidth() {
            throwISEIfImageIsInvalid();
            return mWidth;
        }

        @Override
        public int getTransform() {
            throwISEIfImageIsInvalid();
            return mTransform;
        }

        @Override
        public int getScalingMode() {
            throwISEIfImageIsInvalid();
            return mScalingMode;
        }

        @Override
        public long getTimestamp() {
            throwISEIfImageIsInvalid();
            return mTimestamp;
        }

        @Override
        @NonNull
        public Plane[] getPlanes() {
            throwISEIfImageIsInvalid();
            return Arrays.copyOf(mPlanes, mPlanes.length);
        }

        @Override
        public void close() {
            if (mIsImageValid) {
                java.nio.NioUtils.freeDirectBuffer(mBuffer);
                mIsImageValid = false;
            }
        }

        /**
         * Set the crop rectangle associated with this frame.
         * <p>
         * The crop rectangle specifies the region of valid pixels in the image,
         * using coordinates in the largest-resolution plane.
         */
        @Override
        public void setCropRect(@Nullable Rect cropRect) {
            if (mIsReadOnly) {
                throw new ReadOnlyBufferException();
            }
            super.setCropRect(cropRect);
        }


        public MediaImage(
                @NonNull ByteBuffer buffer, @NonNull ByteBuffer info, boolean readOnly,
                long timestamp, int xOffset, int yOffset, @Nullable Rect cropRect) {
            mFormat = ImageFormat.YUV_420_888;
            mTimestamp = timestamp;
            mIsImageValid = true;
            mIsReadOnly = buffer.isReadOnly();
            mBuffer = buffer.duplicate();

            // save offsets and info
            mXOffset = xOffset;
            mYOffset = yOffset;
            mInfo = info;

            // read media-info.  See MediaImage2
            if (info.remaining() == 104) {
                int type = info.getInt();
                if (type != TYPE_YUV) {
                    throw new UnsupportedOperationException("unsupported type: " + type);
                }
                int numPlanes = info.getInt();
                if (numPlanes != 3) {
                    throw new RuntimeException("unexpected number of planes: " + numPlanes);
                }
                mWidth = info.getInt();
                mHeight = info.getInt();
                if (mWidth < 1 || mHeight < 1) {
                    throw new UnsupportedOperationException(
                            "unsupported size: " + mWidth + "x" + mHeight);
                }
                int bitDepth = info.getInt();
                if (bitDepth != 8) {
                    throw new UnsupportedOperationException("unsupported bit depth: " + bitDepth);
                }
                int bitDepthAllocated = info.getInt();
                if (bitDepthAllocated != 8) {
                    throw new UnsupportedOperationException(
                            "unsupported allocated bit depth: " + bitDepthAllocated);
                }
                mPlanes = new MediaPlane[numPlanes];
                for (int ix = 0; ix < numPlanes; ix++) {
                    int planeOffset = info.getInt();
                    int colInc = info.getInt();
                    int rowInc = info.getInt();
                    int horiz = info.getInt();
                    int vert = info.getInt();
                    if (horiz != vert || horiz != (ix == 0 ? 1 : 2)) {
                        throw new UnsupportedOperationException("unexpected subsampling: "
                                + horiz + "x" + vert + " on plane " + ix);
                    }
                    if (colInc < 1 || rowInc < 1) {
                        throw new UnsupportedOperationException("unexpected strides: "
                                + colInc + " pixel, " + rowInc + " row on plane " + ix);
                    }

                    buffer.clear();
                    buffer.position(mBuffer.position() + planeOffset
                            + (xOffset / horiz) * colInc + (yOffset / vert) * rowInc);
                    buffer.limit(buffer.position() + Utils.divUp(bitDepth, 8)
                            + (mHeight / vert - 1) * rowInc + (mWidth / horiz - 1) * colInc);
                    mPlanes[ix] = new MediaPlane(buffer.slice(), rowInc, colInc);
                }
            } else {
                throw new UnsupportedOperationException(
                        "unsupported info length: " + info.remaining());
            }

            if (cropRect == null) {
                cropRect = new Rect(0, 0, mWidth, mHeight);
            }
            cropRect.offset(-xOffset, -yOffset);
            super.setCropRect(cropRect);
        }

        private class MediaPlane extends Plane {
            public MediaPlane(@NonNull ByteBuffer buffer, int rowInc, int colInc) {
                mData = buffer;
                mRowInc = rowInc;
                mColInc = colInc;
            }

            @Override
            public int getRowStride() {
                throwISEIfImageIsInvalid();
                return mRowInc;
            }

            @Override
            public int getPixelStride() {
                throwISEIfImageIsInvalid();
                return mColInc;
            }

            @Override
            @NonNull
            public ByteBuffer getBuffer() {
                throwISEIfImageIsInvalid();
                return mData;
            }

            private final int mRowInc;
            private final int mColInc;
            private final ByteBuffer mData;
        }
    }

    public final static class MetricsConstants
    {
        private MetricsConstants() {}

        /**
         * Key to extract the codec being used
         * from the {@link MediaCodec#getMetrics} return value.
         * The value is a String.
         */
        public static final String CODEC = "android.media.mediacodec.codec";

        /**
         * Key to extract the MIME type
         * from the {@link MediaCodec#getMetrics} return value.
         * The value is a String.
         */
        public static final String MIME_TYPE = "android.media.mediacodec.mime";

        /**
         * Key to extract what the codec mode
         * from the {@link MediaCodec#getMetrics} return value.
         * The value is a String. Values will be one of the constants
         * {@link #MODE_AUDIO} or {@link #MODE_VIDEO}.
         */
        public static final String MODE = "android.media.mediacodec.mode";

        /**
         * The value returned for the key {@link #MODE} when the
         * codec is a audio codec.
         */
        public static final String MODE_AUDIO = "audio";

        /**
         * The value returned for the key {@link #MODE} when the
         * codec is a video codec.
         */
        public static final String MODE_VIDEO = "video";

        /**
         * Key to extract the flag indicating whether the codec is running
         * as an encoder or decoder from the {@link MediaCodec#getMetrics} return value.
         * The value is an integer.
         * A 0 indicates decoder; 1 indicates encoder.
         */
        public static final String ENCODER = "android.media.mediacodec.encoder";

        /**
         * Key to extract the flag indicating whether the codec is running
         * in secure (DRM) mode from the {@link MediaCodec#getMetrics} return value.
         * The value is an integer.
         */
        public static final String SECURE = "android.media.mediacodec.secure";

        /**
         * Key to extract the width (in pixels) of the video track
         * from the {@link MediaCodec#getMetrics} return value.
         * The value is an integer.
         */
        public static final String WIDTH = "android.media.mediacodec.width";

        /**
         * Key to extract the height (in pixels) of the video track
         * from the {@link MediaCodec#getMetrics} return value.
         * The value is an integer.
         */
        public static final String HEIGHT = "android.media.mediacodec.height";

        /**
         * Key to extract the rotation (in degrees) to properly orient the video
         * from the {@link MediaCodec#getMetrics} return.
         * The value is a integer.
         */
        public static final String ROTATION = "android.media.mediacodec.rotation";

    }
}
