From 466507eb1cba89fe137c825ed84cf4116cf32c02 Mon Sep 17 00:00:00 2001 From: Lajos Molnar Date: Fri, 22 May 2015 09:35:58 -0700 Subject: [PATCH] media: Update MediaCodec class description Bug: 11990465 Bug: 11019199 Bug: 11990564 Bug: 10672559 Change-Id: I22533dec98fb878ca87876c9ebc0fe59f4bfe995 --- docs/html/images/media/mediacodec_async_states.png | Bin 0 -> 46985 bytes docs/html/images/media/mediacodec_async_states.svg | 151 ++ docs/html/images/media/mediacodec_buffers.png | Bin 0 -> 21356 bytes docs/html/images/media/mediacodec_buffers.svg | 102 ++ docs/html/images/media/mediacodec_states.png | Bin 0 -> 45707 bytes docs/html/images/media/mediacodec_states.svg | 150 ++ media/java/android/media/MediaCodec.java | 1516 +++++++++++++++++--- 7 files changed, 1713 insertions(+), 206 deletions(-) create mode 100644 docs/html/images/media/mediacodec_async_states.png create mode 100644 docs/html/images/media/mediacodec_async_states.svg create mode 100644 docs/html/images/media/mediacodec_buffers.png create mode 100644 docs/html/images/media/mediacodec_buffers.svg create mode 100644 docs/html/images/media/mediacodec_states.png create mode 100644 docs/html/images/media/mediacodec_states.svg diff --git a/docs/html/images/media/mediacodec_async_states.png b/docs/html/images/media/mediacodec_async_states.png new file mode 100644 index 0000000000000000000000000000000000000000..c21f5c05d3bce879dfc3b1727c9e8991d142995e GIT binary patch literal 46985 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MediaCodec state diagram for asynchronous operation + + + + + + + + + + + + + Ex + ecuting + + + + St + opped + + + flush + + + star + t + + + star + t + + + st + op + + + err + or + … + + + r + eset + + + r + eset + + + r + eset + + + confi + gur + e + + + + Confi + gur + ed + + + + + Running + + + + Uninitializ + ed + + + + Err + or + + + + + Flushed + + + + + End of Str + eam + + + + + + + + queueInputBuffer + (EOS) + + + + Released + + + r + elease + + + + diff --git a/docs/html/images/media/mediacodec_buffers.png b/docs/html/images/media/mediacodec_buffers.png new file mode 100644 index 0000000000000000000000000000000000000000..f17f4aca3e66e1824ec3f326ab7df45de2d7ad78 GIT binary patch literal 21356 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 literal 0 HcmV?d00001 diff --git a/docs/html/images/media/mediacodec_buffers.svg b/docs/html/images/media/mediacodec_buffers.svg new file mode 100644 index 000000000000..fa121ee89b68 --- /dev/null +++ b/docs/html/images/media/mediacodec_buffers.svg @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + + + + + + + + MediaCodec buffer flow diagram + + + + + Client + + + + Codec + + + + + + + + + + + + empty input buff + ers + + + + Client + + + + + + + + + + + + + + + + + + + + + fi + lled input buff + ers + + + fi + lled output buff + ers + + + discar + ded + output buff + ers + + + client pr + o + vides + input data + + + client consumes + output data + + + input + + + output + + + + diff --git a/docs/html/images/media/mediacodec_states.png b/docs/html/images/media/mediacodec_states.png new file mode 100644 index 0000000000000000000000000000000000000000..a34b613b276a9b819fb5fe0656f1081020225c65 GIT binary patch literal 45707 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 literal 0 HcmV?d00001 diff --git a/docs/html/images/media/mediacodec_states.svg b/docs/html/images/media/mediacodec_states.svg new file mode 100644 index 000000000000..81646fd9b4c1 --- /dev/null +++ b/docs/html/images/media/mediacodec_states.svg @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MediaCodec state diagram + + + + + + + + + + + + + Ex + ecuting + + + + St + opped + + + flush + + + dequeueInputBuffer + + + star + t + + + st + op + + + err + or + … + + + r + eset + + + r + eset + + + r + eset + + + confi + gur + e + + + + Confi + gur + ed + + + + + Running + + + + Uninitializ + ed + + + + Err + or + + + + + Flushed + + + + + End of Str + eam + + + + + + + + queueInputBuffer + (EOS) + + + + Released + + + r + elease + + + + diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java index 6f28bf66ee34..eec4960701d2 100644 --- a/media/java/android/media/MediaCodec.java +++ b/media/java/android/media/MediaCodec.java @@ -23,6 +23,7 @@ import android.graphics.ImageFormat; import android.graphics.Rect; import android.media.Image; import android.media.MediaCodecInfo; +import android.media.MediaCodecInfo.CodecCapabilities; import android.media.MediaCodecList; import android.media.MediaCrypto; import android.media.MediaFormat; @@ -42,204 +43,1307 @@ import java.util.HashMap; import java.util.Map; /** - * MediaCodec class can be used to access low-level media codec, i.e. - * encoder/decoder components. - * - *

MediaCodec is generally used like this: - *

- * MediaCodec codec = MediaCodec.createDecoderByType(type);
- * codec.configure(format, ...);
- * codec.start();
- *
- * // if API level <= 20, get input and output buffer arrays here
- * ByteBuffer[] inputBuffers = codec.getInputBuffers();
- * ByteBuffer[] outputBuffers = codec.getOutputBuffers();
- * for (;;) {
- *   int inputBufferIndex = codec.dequeueInputBuffer(timeoutUs);
- *   if (inputBufferIndex >= 0) {
- *     // if API level >= 21, get input buffer here
- *     ByteBuffer inputBuffer = codec.getInputBuffer(inputBufferIndex);
- *     // fill inputBuffers[inputBufferIndex] with valid data
- *     ...
- *     codec.queueInputBuffer(inputBufferIndex, ...);
- *   }
- *
- *   int outputBufferIndex = codec.dequeueOutputBuffer(timeoutUs);
- *   if (outputBufferIndex >= 0) {
- *     // if API level >= 21, get output buffer here
- *     ByteBuffer outputBuffer = codec.getOutputBuffer(outputBufferIndex);
- *     // outputBuffer is ready to be processed or rendered.
- *     ...
- *     codec.releaseOutputBuffer(outputBufferIndex, ...);
- *   } else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
- *     // no needed to handle if API level >= 21 and using getOutputBuffer(int)
- *     outputBuffers = codec.getOutputBuffers();
- *   } else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
- *     // Subsequent data will conform to new format.
- *     // can ignore if API level >= 21 and using getOutputFormat(outputBufferIndex)
- *     MediaFormat format = codec.getOutputFormat();
- *     ...
- *   }
- * }
- * codec.stop();
- * codec.release();
- * codec = null;
- * 
- * - * Each codec maintains a number of input and output buffers that are - * referred to by index in API calls. - *

- * For API levels 20 and below: - * The contents of these buffers are represented by the ByteBuffer[] arrays - * accessible through {@link #getInputBuffers} and {@link #getOutputBuffers}. - *

- * After a successful call to {@link #start} the client "owns" neither - * input nor output buffers, subsequent calls to {@link #dequeueInputBuffer} - * and {@link #dequeueOutputBuffer} then transfer ownership from the codec - * to the client.

- * The client is not required to resubmit/release buffers immediately - * to the codec, the sample code above simply does this for simplicity's sake. - * Nonetheless, it is possible that a codec may hold off on generating - * output buffers until all outstanding buffers have been - * released/resubmitted. - *

- * Once the client has an input buffer available it can fill it with data - * and submit it it to the codec via a call to {@link #queueInputBuffer}. - * Do not submit multiple input buffers with the same timestamp (unless - * it is codec-specific data marked as such using the flag - * {@link #BUFFER_FLAG_CODEC_CONFIG}). - *

- * The codec in turn will return an output buffer to the client in response - * to {@link #dequeueOutputBuffer}. After the output buffer has been processed - * a call to {@link #releaseOutputBuffer} will return it to the codec. - * If a video surface has been provided in the call to {@link #configure}, - * {@link #releaseOutputBuffer} optionally allows rendering of the buffer - * to the surface.

- * - * Input buffers (for decoders) and Output buffers (for encoders) contain - * encoded data according to the format's type. For video types this data - * is all the encoded data representing a single moment in time, for audio - * data this is slightly relaxed in that a buffer may contain multiple - * encoded frames of audio. In either case, buffers do not start and end on - * arbitrary byte boundaries, this is not a stream of bytes, it's a stream - * of access units.

- * - * Most formats also require the actual data to be prefixed by a number - * of buffers containing setup data, or codec specific data, i.e. the - * first few buffers submitted to the codec object after starting it must - * be codec specific data marked as such using the flag {@link #BUFFER_FLAG_CODEC_CONFIG} - * in a call to {@link #queueInputBuffer}. - *

- * Codec specific data included in the format passed to {@link #configure} - * (in ByteBuffer entries with keys "csd-0", "csd-1", ...) is automatically - * submitted to the codec, this data MUST NOT be submitted explicitly by the - * client. - *

- * Once the client reaches the end of the input data it signals the end of - * the input stream by specifying a flag of {@link #BUFFER_FLAG_END_OF_STREAM} in the call to - * {@link #queueInputBuffer}. The codec will continue to return output buffers - * until it eventually signals the end of the output stream by specifying - * the same flag ({@link #BUFFER_FLAG_END_OF_STREAM}) on the BufferInfo returned in - * {@link #dequeueOutputBuffer}. Do not submit additional input buffers after - * signaling the end of the input stream, unless the codec has been flushed, - * or stopped and restarted. - *

- *

Seeking & Adaptive Playback Support

- * - * You can check if a decoder supports adaptive playback via {@link - * MediaCodecInfo.CodecCapabilities#isFeatureSupported}. Adaptive playback - * is only supported if you configure the codec to decode onto a {@link - * android.view.Surface}. - * - *

For decoders that do not support adaptive playback (including - * when not decoding onto a Surface)

- * - * In order to start decoding data that's not adjacent to previously submitted - * data (i.e. after a seek) one must {@link #flush} the decoder. - * Any input or output buffers the client may own at the point of the flush are - * immediately revoked, i.e. after a call to {@link #flush} the client does not - * own any buffers anymore. - *

- * It is important that the input data after a flush starts at a suitable - * stream boundary. The first frame must be able to be decoded completely on - * its own (for most codecs this means an I-frame), and that no frames should - * refer to frames before that first new frame. - * Note that the format of the data submitted after a flush must not change, - * flush does not support format discontinuities, - * for this a full {@link #stop}, {@link #configure configure()}, {@link #start} - * cycle is necessary. - * - *

For decoders that support adaptive playback

- * - * In order to start decoding data that's not adjacent to previously submitted - * data (i.e. after a seek) it is not necessary to {@link #flush} the - * decoder. - *

- * It is still important that the input data after the discontinuity starts - * at a suitable stream boundary (e.g. I-frame), and that no new frames refer - * to frames before the first frame of the new input data segment. - *

- * For some video formats it is also possible to change the picture size - * mid-stream. To do this for H.264, the new Sequence Parameter Set (SPS) and - * Picture Parameter Set (PPS) values must be packaged together with an - * Instantaneous Decoder Refresh (IDR) frame in a single buffer, which then - * can be enqueued as a regular input buffer. - * The client will receive an {@link #INFO_OUTPUT_FORMAT_CHANGED} return - * value from {@link #dequeueOutputBuffer dequeueOutputBuffer()} or - * {@link Callback#onOutputBufferAvailable onOutputBufferAvailable()} - * just after the picture-size change takes place and before any - * frames with the new size have been returned. - *

- * 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. - * E.g. for H.264 you will need to prepend the PPS/SPS to the new IDR - * frame to ensure that the codec receives the picture size change request. - * - *

States and error handling

- * - *

During its life, a codec conceptually exists in one of the following states: - * Initialized, Configured, Executing, Error, Uninitialized, (omitting transitory states - * between them). When created by one of the factory methods, - * the codec is in the Initialized state; {@link #configure} brings it to the - * Configured state; {@link #start} brings it to the Executing state. - * In the Executing state, decoding or encoding occurs through the buffer queue - * manipulation described above. The method {@link #stop} - * returns the codec to the Initialized state, whereupon it may be configured again, - * and {@link #release} brings the codec to the terminal Uninitialized state. When - * a codec error occurs, the codec moves to the Error state. Use {@link #reset} to - * bring the codec back to the Initialized state, or {@link #release} to move it - * to the Uninitialized state. - * - *

The factory methods - * {@link #createByCodecName}, - * {@link #createDecoderByType}, - * and {@link #createEncoderByType} - * throw {@link java.io.IOException} on failure which - * the caller must catch or declare to pass up. - * MediaCodec methods throw {@link java.lang.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 MediaCodec.CryptoException#MediaCodec.CryptoException}, which - * has further error information obtainable from {@link MediaCodec.CryptoException#getErrorCode}. - * - *

Internal codec errors result in a {@link MediaCodec.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 {@link MediaCodec.CodecException} can be determined by - * calling {@link MediaCodec.CodecException#isRecoverable} and - * {@link MediaCodec.CodecException#isTransient}. - * If {@link MediaCodec.CodecException#isRecoverable} returns true, - * then a {@link #stop}, {@link #configure}, and {@link #start} can be performed to recover. - * If {@link MediaCodec.CodecException#isTransient} returns true, - * then resources are temporarily unavailable and the method may be retried at a later time. - * If both {@link MediaCodec.CodecException#isRecoverable} - * and {@link MediaCodec.CodecException#isTransient} return false, - * then the {@link MediaCodec.CodecException} is fatal and the codec must be - * {@link #reset reset} or {@link #release released}. - * Both {@link MediaCodec.CodecException#isRecoverable} and - * {@link MediaCodec.CodecException#isTransient} do not return true at the same time. + 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}.) +

+

MediaCodec buffer flow diagram
+

+ 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. + +

Data Types

+

+ 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)}. + +

Compressed Buffers

+

+ 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 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. + +

Raw Audio Buffers

+

+ Raw audio buffers contain entire frames of PCM audio data, which is one sample for each channel + in channel order. Each sample is a {@linkplain AudioFormat#ENCODING_PCM_16BIT 16-bit signed + integer in native byte order}. + +

+ 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 = formet.getInteger(MediaFormat.KEY_CHANNEL_COUNT);
+   if (channelIx < 0 || channelIx >= numChannels) {
+     return null;
+   }
+   short[] res = new short[samples.remaining() / numChannels];
+   for (int i = 0; i < res.length; ++i) {
+     res[i] = samples.get(i * numChannels + channelIx);
+   }
+   return res;
+ }
+ +

Raw Video Buffers

+

+ 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(…)}{@code .}{@link CodecCapabilities#colorFormats colorFormats}. + Video codecs may support three kinds of color formats: +

    +
  • native raw video format: This is marked by {@link + CodecCapabilities#COLOR_FormatSurface} and it can be used with an input or output Surface.
  • +
  • flexible YUV buffers (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)}.
  • +
  • other, specific formats: 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)}.
  • +
+

+ All video codecs support flexible YUV 4:2:0 buffers since {@link + android.os.Build.VERSION_CODES#LOLLIPOP_MR1}. + +

States

+

+ 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. +

+

MediaCodec state diagram
+

+ 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(…)}, 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. +

+ 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}. +

+ 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}. +

+ 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. + +

Creation

+

+ 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}. +

+ Note: 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 + format.setString(MediaFormat.KEY_FRAME_RATE, null) + to clear any existing frame rate setting in the format. +

+ 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. + +

Creating secure decoders

+

+ 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. +

+ 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. + +

Initialization

+

+ 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 – 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. +

+ 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. +

+ If you want to process raw input video buffers natively with a video consumer – a codec + that processes raw video input, such as a video encoder – 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}. + +

Codec-specific Data

+

+ 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}. +

+ 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 MUST NOT 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. Alternately, you can concatenate all codec-specific + data and submit it as a single codec-config buffer. +

+ 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 + codec-specific-data must start with a start code of {@code "\x00\x00\x00\x01"}. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FormatCSD buffer #0CSD buffer #1
AACDecoder-specific information from ESDSNot Used
MPEG-4Decoder-specific information from ESDSNot Used
H.264 AVCSPS (Sequence Parameter Sets)PPS (Picture Parameter Sets)
H.265 HEVCVPS (Video Parameter Sets) +
+ SPS (Sequence Parameter Sets) +
+ PPS (Picture Parameter Sets)
Not Used
+ +

+ Note: 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. +

+ 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. + +

Data Processing

+

+ 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(…)} 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(…)} callbacks. +

+ Upon obtaining an input buffer, fill it with data and submit it to the codec using {@link + #queueInputBuffer queueInputBuffer} – or {@link #queueSecureInputBuffer + queueSecureInputBuffer} if using decryption. Do not submit multiple input buffers with the same + timestamp (unless it is codec-specific data marked as such). +

+ 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 dequeuOutputBuffer} 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. +

+ 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. E.g. it + is possible that a codec may hold off on generating output buffers until all outstanding buffers + have been released/resubmitted. Therefore, try to hold onto to available buffers as little as + possible. +

+ Depending on the API version, you can process data in three ways: + + + + + + + + + + + + + + + + + + + + + + + + + +
Processing ModeAPI version <= 20
Jelly Bean/KitKat
API version >= 21
Lollipop and later
Synchronous API using buffer arraysSupportedDeprecated
Synchronous API using buffersNot AvailableSupported
Asynchronous API using buffersNot AvailableSupported
+ +

Asynchronous Processing using Buffers

+

+ 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. +

+

MediaCodec state diagram for asynchronous operation
+

+ MediaCodec is typically used like this in asynchronous mode: +

+ MediaCodec codec = MediaCodec.createCodecByName(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
+     …
+     codec.queueInputBuffer(inputBufferId, …);
+   }
+
+   {@literal @Override}
+   void onOutputBufferAvailable(MediaCodec mc, int outputBufferId, …) {
+     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.
+     …
+     codec.releaseOutputBuffer(outputBufferId, …);
+   }
+
+   {@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(…) {
+     …
+   }
+ });
+ codec.configure(format, …);
+ mOutputFormat = codec.getOutputFormat(); // option B
+ codec.start();
+ // wait for processing to complete
+ codec.stop();
+ codec.release();
+ +

Synchronous Processing using Buffers

+

+ 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()}. + +

+ Note: 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}. +

+ MediaCodec is typically used like this in synchronous mode: +

+ MediaCodec codec = MediaCodec.createCodecByName(name);
+ codec.configure(format, …);
+ MediaFormat outputFormat = codec.getOutputFormat(); // option B
+ codec.start();
+ for (;;) {
+   int inputBufferId = codec.dequeueInputBuffer(timeoutUs);
+   if (inputBufferId >= 0) {
+     ByteBuffer inputBuffer = codec.getInputBuffer(…);
+     // fill inputBuffer with valid data
+     …
+     codec.queueInputBuffer(inputBufferId, …);
+   }
+   int outputBufferId = codec.dequeueOutputBuffer(…);
+   if (outputBufferId >= 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.
+     …
+     codec.releaseOutputBuffer(outputBufferId, …);
+   } 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();
+ +

Synchronous Processing using Buffer Arrays (deprecated)

+

+ 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. +

+ MediaCodec codec = MediaCodec.createCodecByName(name);
+ codec.configure(format, …);
+ codec.start();
+ ByteBuffer[] inputBuffers = codec.getInputBuffers();
+ ByteBuffer[] outputBuffers = codec.getOutputBuffers();
+ for (;;) {
+   int inputBufferId = codec.dequeueInputBuffer(…);
+   if (inputBufferId >= 0) {
+     // fill inputBuffers[inputBufferId] with valid data
+     …
+     codec.queueInputBuffer(inputBufferId, …);
+   }
+   int outputBufferId = codec.dequeueOutputBuffer(…);
+   if (outputBufferId >= 0) {
+     // outputBuffers[outputBufferId] is ready to be processed or rendered.
+     …
+     codec.releaseOutputBuffer(outputBufferId, …);
+   } 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();
+ +

End-of-stream Handling

+

+ 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. +

+ 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. +

+ Do not submit additional input buffers after signaling the end of the input stream, unless the + codec has been flushed, or stopped and restarted. + +

Using an Output Surface

+

+ 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. +

+ When using an output Surface, you can select whether or not to render each output buffer on the + surface. You have three choices: +

    +
  • Do not render the buffer: Call {@link #releaseOutputBuffer(int, boolean) + releaseOutputBuffer(bufferId, false)}.
  • +
  • Render the buffer with the default timestamp: Call {@link + #releaseOutputBuffer(int, boolean) releaseOutputBuffer(bufferId, true)}.
  • +
  • Render the buffer with a specific timestamp: Call {@link + #releaseOutputBuffer(int, long) releaseOutputBuffer(bufferId, timestamp)}.
  • +
+

+ Since {@link android.os.Build.VERSION_CODES#MNC}, the default timestamp is the {@linkplain + BufferInfo#presentationTimeUs presentation timestamp} of the buffer (converted to nanoseconds). + It was not defined prior to that. +

+ Also since {@link android.os.Build.VERSION_CODES#MNC}, you can change the output Surface + dynamically using {@link #setOutputSurface setOutputSurface}. + +

Using an Input Surface

+

+ 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 MUST NOT be written into. +

+ Call {@link #signalEndOfInputStream} to signal end-of-stream. The input surface will stop + submitting data to the codec immediately after this call. +

+ +

Seeking & Adaptive Playback Support

+

+ 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}. + +

Stream Boundary and Key Frames

+

+ 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 key frame 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. +

+ The following table summarizes suitable key frames for various video formats. + + + + + + + + + + + + + + + + + + + + + + + + + +
FormatSuitable key frame
VP9/VP8a suitable intraframe where no subsequent frames refer to frames prior to this frame.
+ (There is no specific name for such key frame.)
H.265 HEVCIDR or CRA
H.264 AVCIDR
MPEG-4
H.263
MPEG-2
a suitable I-frame where no subsequent frames refer to frames prior to this frame.
+ (There is no specific name for such key frame.)
+ +

For decoders that do not support adaptive playback (including when not decoding onto a + Surface)

+

+ In order to start decoding data that is not adjacent to previously submitted data (i.e. after a + seek) you MUST 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. +

+ Note: 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(…)} - {@link #start} cycle is necessary. + +

+ Also note: if you flush the codec too soon after {@link #start} – + generally, before the first output buffer or output format change is received – you + will need to resubmit the codec-specific-data to the codec. See the codec-specific-data section for more info. + +

For decoders that support and are configured for adaptive playback

+

+ In order to start decoding data that is not adjacent to previously submitted data (i.e. after a + seek) it is not necessary to flush the decoder; however, input data after the + discontinuity must start at a suitable stream boundary/key frame. +

+ 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 regular input buffer. +

+ 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. +

+ Note: 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. + +

Error handling

+

+ 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}. +

+ 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}: +

    +
  • recoverable errors: If {@code isRecoverable()} returns true, then call + {@link #stop}, {@link #configure configure(…)}, and {@link #start} to recover.
  • +
  • transient errors: If {@code isTransient()} returns true, then resources are + temporarily unavailable and the method may be retried at a later time.
  • +
  • fatal errors: 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}.
  • +
+

+ Both {@code isRecoverable()} and {@code isTransient()} do not return true at the same time. + +

Valid API Calls and API History

+

+ 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}. + + + + + + + + + + + + + + + + + + + +
SymbolMeaning
Supported
Semantics changed
Experimental support
[ ]Deprecated
Restricted to surface input mode
Restricted to surface output mode
Restricted to ByteBuffer input mode
Restricted to synchronous mode
Restricted to asynchronous mode
( )Can be called, but shouldn't
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Uninitialized
Configured
Flushed
Running
End of Stream
Error
Released
SDK Version
StateMethod1617181920212223
{@link #createByCodecName createByCodecName}
{@link #createDecoderByType createDecoderByType}
{@link #createEncoderByType createEncoderByType}
{@link #createPersistentInputSurface createPersistentInputSurface}
16+------{@link #configure configure}
-18+-----{@link #createInputSurface createInputSurface}
--16+16+(16+)--{@link #dequeueInputBuffer dequeueInputBuffer}⁕▧↩▧↩▧↩
--16+16+16+--{@link #dequeueOutputBuffer dequeueOutputBuffer}⁕↩
--16+16+16+--{@link #flush flush}
18+18+18+18+18+18+-{@link #getCodecInfo getCodecInfo}
--(21+)21+(21+)--{@link #getInputBuffer getInputBuffer}
--16+(16+)(16+)--{@link #getInputBuffers getInputBuffers}[⁕↩][↩][↩]
-21+(21+)(21+)(21+)--{@link #getInputFormat getInputFormat}
--(21+)21+(21+)--{@link #getInputImage getInputImage}
18+18+18+18+18+18+-{@link #getName getName}
--(21+)21+21+--{@link #getOutputBuffer getOutputBuffer}
--16+16+16+--{@link #getOutputBuffers getOutputBuffers}[⁕↩][↩][↩]
-21+16+16+16+--{@link #getOutputFormat()}
--(21+)21+21+--{@link #getOutputFormat(int)}
--(21+)21+21+--{@link #getOutputImage getOutputImage}
---16+(16+)--{@link #queueInputBuffer queueInputBuffer}
---16+(16+)--{@link #queueSecureInputBuffer queueSecureInputBuffer}
16+16+16+16+16+16+16+{@link #release release}
---16+16+--{@link #releaseOutputBuffer(int, boolean)}
---21+21+--{@link #releaseOutputBuffer(int, long)}
21+21+21+21+21+21+-{@link #reset reset}
21+------{@link #setCallback(Callback) setCallback}{@link #setCallback(Callback, Handler) ⁕}
-23+-----{@link #setInputSurface setInputSurface}
23+23+23+23+23+(23+)(23+){@link #setOnFrameRenderedListener setOnFrameRenderedListener}○ ⎆
-23+23+23+23+--{@link #setOutputSurface setOutputSurface}
19+19+19+19+19+(19+)-{@link #setParameters setParameters}
-16+16+16+16+(16+)-{@link #setVideoScalingMode setVideoScalingMode}
--18+18+---{@link #signalEndOfInputStream signalEndOfInputStream}
-16+21+(⇄)----{@link #start start}
--16+16+16+--{@link #stop stop}
*/ final public class MediaCodec { /** @@ -548,14 +1652,14 @@ final public class MediaCodec { } /** - * Returns the codec to its initial (Initialized) state. + * 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 Uninitialized state. + * @throws IllegalStateException if in the Released state. */ public final void reset() { freeAllTrackedBuffers(); // free buffers first @@ -607,7 +1711,7 @@ final public class MediaCodec { * 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 Initialized state. + * @throws IllegalStateException if not in the Uninitialized state. * @throws CryptoException upon DRM error. * @throws CodecException upon codec error. */ @@ -765,7 +1869,7 @@ final public class MediaCodec { * 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 Uninitialized state. + * @throws IllegalStateException if in the Released state. */ public final void stop() { native_stop(); @@ -1771,14 +2875,14 @@ final public class MediaCodec { * 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". * @throws IllegalArgumentException if mode is not recognized. - * @throws IllegalStateException if in the Uninitialized state. + * @throws IllegalStateException if in the Released state. */ public native final void setVideoScalingMode(@VideoScalingMode int mode); /** * Get the component name. If the codec was created by createDecoderByType * or createEncoderByType, what component is chosen is not known beforehand. - * @throws IllegalStateException if in the Uninitialized state. + * @throws IllegalStateException if in the Released state. */ @NonNull public native final String getName(); @@ -1811,7 +2915,7 @@ final public class MediaCodec { * Note: Some of these parameter changes may silently fail to apply. * * @param params The bundle of parameters to set. - * @throws IllegalStateException if in the Uninitialized state. + * @throws IllegalStateException if in the Released state. */ public final void setParameters(@Nullable Bundle params) { if (params == null) { @@ -2025,7 +3129,7 @@ final public class MediaCodec { * 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 Uninitialized state. + * @throws IllegalStateException if in the Released state. */ @NonNull public MediaCodecInfo getCodecInfo() { -- 2.11.0