Android Guides | Samples

Android.Media.MediaCodec Class

MediaCodec class can be used to access low-level media codecs, i.e. encoder/decoder components.

See Also: MediaCodec

Syntax

[Android.Runtime.Register("android/media/MediaCodec", DoNotGenerateAcw=true)]
public sealed class MediaCodec : Object

Remarks

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 MediaExtractor, MediaSync, MediaMuxer, MediaCrypto, MediaDrm, Image, Surface, and AudioTrack.)

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 ByteBuffer, but you should use a 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 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 Java.Nio.ByteBuffer.isDirect() ByteBuffers. When using ByteBuffer mode, you can access raw video frames using the Image class and MediaCodec.GetInputImage(Int32)/MediaCodec.GetOutputImage(Int32).

Compressed Buffers

Input buffers (for decoders) and output buffers (for encoders) contain compressed data according to the MediaFormat.KeyMime. 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 AudioFormat.ENCODING_PCM_16BIT.

Raw Video Buffers

In ByteBuffer mode video buffers are laid out according to their MediaFormat.KeyColorFormat. You can get the supported color formats as an array from MediaCodec.CodecInfo.MediaCodecInfo.GetCapabilitiesForType(String).NoType:android/media/MediaCodecInfo$CodecCapabilities;Href=../../../reference/android/media/MediaCodecInfo.CodecCapabilities.html#colorFormats. Video codecs may support three kinds of color formats:

All video codecs support flexible YUV 4:2:0 buffers since VERSION_CODES.Lollipop.

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.

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 MediaCodec.Configure(MediaFormat,Surface,Surface,Surface), which brings it to the Configured state, then call MediaCodec.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 MediaCodec.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 MediaCodec.BufferFlagEndOfStream, 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 MediaCodec.Flush.

Call MediaCodec.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 MediaCodec.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 MediaCodec.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 MediaCodec.Release to move to the terminal Released state.

Creation

Use MediaCodecList to create a MediaCodec for a specific MediaFormat. When decoding a file or a stream, you can get the desired format from MediaExtractor.GetTrackFormat(Int32). Inject any specific features that you want to add using MediaFormat.SetFeatureEnabled(String,Boolean), then call MediaCodecList.FindDecoderForFormat(MediaFormat) to get the name of a codec that can handle that specific media format. Finally, create the codec using MediaCodec.CreateByCodecName(String).

Note: On VERSION_CODES.Lollipop, the format to MediaCodecList.findDecoder/EncoderForFormat must not contain a MediaFormat.KeyFrameRate. 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 MediaCodec.CreateDecoderByType(String)/MediaCodec.CreateEncoderByType(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 Build+VERSION_CODES.KitKat and earlier, secure codecs might not be listed in MediaCodecList, but may still be available on the system. Secure codecs that exist can be instantiated by name only, by appending ".secure" to the name of a regular codec (the name of all secure codecs must end in ".secure".) MediaCodec.CreateByCodecName(String) will throw an IOException if the codec is not present on the system.

From VERSION_CODES.Lollipop onwards, you should use the NoType:android/media/MediaCodecInfo$CodecCapabilities;Href=../../../reference/android/media/MediaCodecInfo.CodecCapabilities.html#FEATURE_SecurePlayback feature in the media format to create a secure decoder.

Initialization

After creating the codec, you can set a callback using MediaCodec.SetCallback(.Callback) if you want to process data asynchronously. Then, MediaCodec.Configure(MediaFormat,Surface,Surface,Surface) the codec using the specific media format. This is when you can specify the output 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 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 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 MediaCodec.CreateInputSurface after configuration. Alternately, set up the codec to use a previously created MediaCodec.CreatePersistentInputSurface by calling MediaCodec.SetInputSurface(Surface).

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 MediaCodec.Start and before any frame data. Such data must be marked using the flag MediaCodec.BufferFlagCodecConfig in a call to MediaCodec.QueueInputBuffer(Int32,Int32,Int32,Int32,Int32).

Codec-specific data can also be included in the format passed to MediaCodec.Configure(MediaFormat,Surface,Surface,Surface) in ByteBuffer entries with keys "csd-0", "csd-1", etc. These keys are always included in the track MediaFormat obtained from the MediaExtractor.GetTrackFormat(Int32). Codec-specific data in the format is automatically submitted to the codec upon MediaCodec.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 MediaMuxer track configuration. Each parameter set and the codec-specific-data sections marked with (*) must start with a start code of "\x00\x00\x00\x01".

FormatCSD buffer #0CSD buffer #1CSD buffer #2
AACDecoder-specific information from ESDS*Not UsedNot Used
VORBISIdentification headerSetup headerNot Used
OPUSIdentification headerPre-skip in nanosecs
(unsigned 64-bit ByteOrder.NativeOrder integer.)
This overrides the pre-skip value in the identification header.
Seek Pre-roll in nanosecs
(unsigned 64-bit ByteOrder.NativeOrder integer.)
MPEG-4Decoder-specific information from ESDS*Not UsedNot Used
H.264 AVCSPS (Sequence Parameter Sets*)PPS (Picture Parameter Sets*)Not Used
H.265 HEVCVPS (Video Parameter Sets*) +
SPS (Sequence Parameter Sets*) +
PPS (Picture Parameter Sets*)
Not UsedNot 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 MediaCodec.BufferFlagCodecConfig 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 MediaCodec.BufferFlagCodecConfig. 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 MediaCodec.Start the client "owns" neither input nor output buffers. In synchronous mode, call MediaCodec.DequeueInputBuffer(Int64)/MediaCodec.DequeueOutputBuffer(.BufferInfo, System.Int64) to obtain (get ownership of) an input or output buffer from the codec. In asynchronous mode, you will automatically receive available buffers via the NoType:android/media/MediaCodec$Callback;Href=../../../reference/android/media/MediaCodec.Callback.html#onInputBufferAvailable(android.media.MediaCodec, int)/NoType:android/media/MediaCodec$Callback;Href=../../../reference/android/media/MediaCodec.Callback.html#onOutputBufferAvailable(android.media.MediaCodec, int, android.media.MediaCodec.BufferInfo) callbacks.

Upon obtaining an input buffer, fill it with data and submit it to the codec using MediaCodec.QueueInputBuffer(Int32,Int32,Int32,Int32,Int32) – or MediaCodec.QueueSecureInputBuffer(Int32,Int32,Int32,Int32,Int32) if using decryption. Do not submit multiple input buffers with the same timestamp (unless it is marked as such).

The codec in turn will return a read-only output buffer via the NoType:android/media/MediaCodec$Callback;Href=../../../reference/android/media/MediaCodec.Callback.html#onOutputBufferAvailable(android.media.MediaCodec, int, android.media.MediaCodec.BufferInfo) callback in asynchronous mode, or in response to a MediaCodec.DequeueOutputBuffer(.BufferInfo, System.Int64) call in synchronous mode. After the output buffer has been processed, call one of the MediaCodec.ReleaseOutputBuffer(Int32,Boolean) 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. Specifically, 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 VERSION_CODES.Lollipop, the preferred method is to process data asynchronously by setting a callback before calling MediaCodec.Configure(MediaFormat,Surface,Surface,Surface). Asynchronous mode changes the state transitions slightly, because you must call MediaCodec.Start after MediaCodec.Flush to transition the codec to the Running sub-state and start receiving input buffers. Similarly, upon an initial call to start the codec will move directly to the Running sub-state and start passing available input buffers via the callback.

MediaCodec is typically used like this in asynchronous mode:

Synchronous Processing using Buffers

Since VERSION_CODES.Lollipop, you should retrieve input and output buffers using MediaCodec.GetInputBuffer(Int32)/MediaCodec.GetOutputBuffer(Int32) and/or MediaCodec.GetInputImage(Int32)/MediaCodec.GetOutputImage(Int32) 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 MediaCodec.GetInputBuffers/MediaCodec.GetOutputBuffers.

Note: do not mix the methods of using buffers and buffer arrays at the same time. Specifically, only call getInput/OutputBuffers directly after MediaCodec.Start or after having dequeued an output buffer ID with the value of MediaCodec.InfoOutputFormatChanged.

MediaCodec is typically used like this in synchronous mode:

Synchronous Processing using Buffer Arrays (deprecated)

In versions Build+VERSION_CODES.KitKat and before, the set of input and output buffers are represented by the ByteBuffer[] arrays. After a successful call to MediaCodec.Start, retrieve the buffer arrays using MediaCodec.GetInputBuffers/MediaCodec.GetOutputBuffers. 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.

End-of-stream Handling

When you reach the end of the input data, you must signal it to the codec by specifying the MediaCodec.BufferFlagEndOfStream flag in the call to MediaCodec.QueueInputBuffer(Int32,Int32,Int32,Int32,Int32). 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 NoType:android/media/MediaCodec$BufferInfo;Href=../../../reference/android/media/MediaCodec.BufferInfo.html set in MediaCodec.DequeueOutputBuffer(.BufferInfo, System.Int64) or returned via NoType:android/media/MediaCodec$Callback;Href=../../../reference/android/media/MediaCodec.Callback.html#onOutputBufferAvailable(android.media.MediaCodec, int, android.media.MediaCodec.BufferInfo). 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 Surface; however, the output buffers will not be accessible, and are represented as null values. E.g. MediaCodec.GetOutputBuffer(Int32)/MediaCodec.GetOutputImage(Int32) will return null and MediaCodec.GetOutputBuffers will return an array containing only 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:

Since NoType:android/os/Build$VERSION_CODES;Href=../../../reference/android/os/Build.VERSION_CODES.html#M, the default timestamp is the NoType:android/media/MediaCodec$BufferInfo;Href=../../../reference/android/media/MediaCodec.BufferInfo.html#presentationTimeUs of the buffer (converted to nanoseconds). It was not defined prior to that.

Also since NoType:android/os/Build$VERSION_CODES;Href=../../../reference/android/os/Build.VERSION_CODES.html#M, you can change the output Surface dynamically using MediaCodec.SetOutputSurface(Surface).

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 MediaCodec.DequeueInputBuffer(Int64) will throw an IllegalStateException, and MediaCodec.GetInputBuffers returns a bogus ByteBuffer[] array that MUST NOT be written into.

Call MediaCodec.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 NoType:android/media/MediaCodecInfo$CodecCapabilities;Href=../../../reference/android/media/MediaCodecInfo.CodecCapabilities.html#FEATURE_AdaptivePlayback via NoType:android/media/MediaCodecInfo$CodecCapabilities;Href=../../../reference/android/media/MediaCodecInfo.CodecCapabilities.html#isFeatureSupported(java.lang.String). Adaptive playback support for video decoders is only activated if you configure the codec to decode onto a Surface.

Stream Boundary and Key Frames

It is important that the input data after MediaCodec.Start or MediaCodec.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 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; MediaCodec.Flush does not support format discontinuities; for that, a full MediaCodec.Stop - MediaCodec.Configure(MediaFormat,Surface,Surface,Surface) - MediaCodec.Start cycle is necessary.

Also note: if you flush the codec too soon after MediaCodec.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 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 MediaCodec.InfoOutputFormatChanged return value from MediaCodec.DequeueOutputBuffer(.BufferInfo, System.Int64) or a NoType:android/media/MediaCodec$Callback;Href=../../../reference/android/media/MediaCodec.Callback.html#onOutputBufferAvailable(android.media.MediaCodec, int, android.media.MediaCodec.BufferInfo) 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 MediaCodec.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 MediaCodec.CreateByCodecName(String) and MediaCodec.CreateDecoderByType(String)/MediaCodec.CreateEncoderByType(String) throw IOException on failure which you must catch or declare to pass up. MediaCodec methods throw 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 NoType:android/media/MediaCodec$CryptoException;Href=../../../reference/android/media/MediaCodec.CryptoException.html, which has further error information obtainable from NoType:android/media/MediaCodec$CryptoException;Href=../../../reference/android/media/MediaCodec.CryptoException.html#getErrorCode().

Internal codec errors result in a NoType:android/media/MediaCodec$CodecException;Href=../../../reference/android/media/MediaCodec.CodecException.html, 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 CodecException can be determined by calling NoType:android/media/MediaCodec$CodecException;Href=../../../reference/android/media/MediaCodec.CodecException.html#isRecoverable() and NoType:android/media/MediaCodec$CodecException;Href=../../../reference/android/media/MediaCodec.CodecException.html#isTransient():

Both isRecoverable() and 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 NoType:android/os/Build$VERSION_CODES;Href=../../../reference/android/os/Build.VERSION_CODES.html.

SymbolMeaning
&#9679;Supported
&#8277;Semantics changed
&#9675;Experimental support
[ ]Deprecated
&#9099;Restricted to surface input mode
&#9094;Restricted to surface output mode
&#9639;Restricted to ByteBuffer input mode
&#8617;Restricted to synchronous mode
&#8644;Restricted to asynchronous mode
( )Can be called, but shouldn't
UninitializedConfiguredFlushedRunningEnd of StreamErrorReleasedSDK Version
StateMethod1617181920212223
MediaCodec.CreateByCodecName(String)&#9679;&#9679;&#9679;&#9679;&#9679;&#9679;&#9679;&#9679;
MediaCodec.CreateDecoderByType(String)&#9679;&#9679;&#9679;&#9679;&#9679;&#9679;&#9679;&#9679;
MediaCodec.CreateEncoderByType(String)&#9679;&#9679;&#9679;&#9679;&#9679;&#9679;&#9679;&#9679;
MediaCodec.CreatePersistentInputSurface&#9679;
16+------MediaCodec.Configure(MediaFormat,Surface,Surface,Surface)&#9679;&#9679;&#9679;&#9679;&#9679;&#8277;&#9679;&#9679;
-18+-----MediaCodec.CreateInputSurface&#9099;&#9099;&#9099;&#9099;&#9099;&#9099;
--16+16+(16+)--MediaCodec.DequeueInputBuffer(Int64)&#9679;&#9679;&#9639;&#9639;&#9639;&#8277;&#9639;&#8617;&#9639;&#8617;&#9639;&#8617;
--16+16+16+--MediaCodec.DequeueOutputBuffer(.BufferInfo, System.Int64)&#9679;&#9679;&#9679;&#9679;&#9679;&#8277;&#8617;&#8617;&#8617;
--16+16+16+--MediaCodec.Flush&#9679;&#9679;&#9679;&#9679;&#9679;&#9679;&#9679;&#9679;
18+18+18+18+18+18+-MediaCodec.CodecInfo&#9679;&#9679;&#9679;&#9679;&#9679;&#9679;
--(21+)21+(21+)--MediaCodec.GetInputBuffer(Int32)&#9679;&#9679;&#9679;
--16+(16+)(16+)--MediaCodec.GetInputBuffers&#9679;&#9679;&#9679;&#9679;&#9679;[&#8277;&#8617;][&#8617;][&#8617;]
-21+(21+)(21+)(21+)--MediaCodec.InputFormat&#9679;&#9679;&#9679;
--(21+)21+(21+)--MediaCodec.GetInputImage(Int32)&#9675;&#9679;&#9679;
18+18+18+18+18+18+-MediaCodec.Name&#9679;&#9679;&#9679;&#9679;&#9679;&#9679;
--(21+)21+21+--MediaCodec.GetOutputBuffer(Int32)&#9679;&#9679;&#9679;
--16+16+16+--MediaCodec.GetOutputBuffers&#9679;&#9679;&#9679;&#9679;&#9679;[&#8277;&#8617;][&#8617;][&#8617;]
-21+16+16+16+--MediaCodec.OutputFormat&#9679;&#9679;&#9679;&#9679;&#9679;&#9679;&#9679;&#9679;
--(21+)21+21+--MediaCodec.GetOutputFormat(Int32)&#9679;&#9679;&#9679;
--(21+)21+21+--MediaCodec.GetOutputImage(Int32)&#9675;&#9679;&#9679;
---16+(16+)--MediaCodec.QueueInputBuffer(Int32,Int32,Int32,Int32,Int32)&#9679;&#9679;&#9679;&#9679;&#9679;&#8277;&#9679;&#9679;
---16+(16+)--MediaCodec.QueueSecureInputBuffer(Int32,Int32,Int32,Int32,Int32)&#9679;&#9679;&#9679;&#9679;&#9679;&#8277;&#9679;&#9679;
16+16+16+16+16+16+16+MediaCodec.Release&#9679;&#9679;&#9679;&#9679;&#9679;&#9679;&#9679;&#9679;
---16+16+--MediaCodec.ReleaseOutputBuffer(Int32,Boolean)&#9679;&#9679;&#9679;&#9679;&#9679;&#8277;&#9679;&#8277;
---21+21+--MediaCodec.ReleaseOutputBuffer(Int32,Int64)&#9094;&#9094;&#9094;
21+21+21+21+21+21+-MediaCodec.Reset&#9679;&#9679;&#9679;
21+------MediaCodec.SetCallback(.Callback)&#9679;&#9679;MediaCodec.SetCallback(.Callback, Android.OS.Handler)
-23+-----MediaCodec.SetInputSurface(Surface)&#9099;
23+23+23+23+23+(23+)(23+)MediaCodec.SetOnFrameRenderedListener(.IOnFrameRenderedListener, Android.OS.Handler)&#9675; &#9094;
-23+23+23+23+--MediaCodec.SetOutputSurface(Surface)&#9094;
19+19+19+19+19+(19+)-MediaCodec.SetParameters(Bundle)&#9679;&#9679;&#9679;&#9679;&#9679;
-16+16+16+16+(16+)-MediaCodec.SetVideoScalingMode(VideoScalingMode)&#9094;&#9094;&#9094;&#9094;&#9094;&#9094;&#9094;&#9094;
--18+18+---MediaCodec.SignalEndOfInputStream&#9099;&#9099;&#9099;&#9099;&#9099;&#9099;
-16+21+(&#8644;)----MediaCodec.Start&#9679;&#9679;&#9679;&#9679;&#9679;&#8277;&#9679;&#9679;
--16+16+16+--MediaCodec.Stop&#9679;&#9679;&#9679;&#9679;&#9679;&#9679;&#9679;&#9679;

[Android Documentation]

Requirements

Namespace: Android.Media
Assembly: Mono.Android (in Mono.Android.dll)
Assembly Versions: 0.0.0.0
Since: Added in API level 16

The members of Android.Media.MediaCodec are listed below.

See Also: Object

Public Fields

const
BufferFlagCodecConfigMediaCodecBufferFlags (2). This indicated that the buffer marked as such contains codec initialization / codec specific data instead of media data.
const
BufferFlagEndOfStreamMediaCodecBufferFlags (4). This signals the end of stream, i.e. no buffers will be available after this, unless of course, MediaCodec.Flush follows.
const
BufferFlagKeyFrameMediaCodecBufferFlags (1). This indicates that the (encoded) buffer marked as such contains the data for a key frame.
const
BufferFlagSyncFrameMediaCodecBufferFlags (1). This indicates that the (encoded) buffer marked as such contains the data for a key frame.
const
ConfigureFlagEncodeMediaCodecConfigFlags (1). If this codec is to be used as an encoder, pass this flag.
const
CryptoModeAesCtrMediaCodecCryptoMode (1).
const
CryptoModeUnencryptedMediaCodecCryptoMode (0).
const
InfoOutputBuffersChangedMediaCodecInfoState (-3). The output buffers have changed, the client must refer to the new set of output buffers returned by MediaCodec.GetOutputBuffers from this point on.
const
InfoOutputFormatChangedMediaCodecInfoState (-2). The output format has changed, subsequent data will follow the new format.
const
InfoTryAgainLaterMediaCodecInfoState (-1). If a non-negative timeout had been specified in the call to MediaCodec.DequeueOutputBuffer(.BufferInfo, System.Int64), indicates that the call timed out.
const
ParameterKeyRequestSyncFrameString. Request that the encoder produce a sync frame "soon".
const
ParameterKeySuspendString. Temporarily suspend/resume encoding of input data.
const
ParameterKeyVideoBitrateString. Change a video encoder's target bitrate on the fly.
const
VideoScalingModeScaleToFitVideoScalingMode (1). The content is scaled to the surface dimensions
const
VideoScalingModeScaleToFitWithCroppingVideoScalingMode (2). The content is scaled, maintaining its aspect ratio, the whole surface area is used, content may be cropped

Public Properties

[read-only]
CodecInfoMediaCodecInfo. Get the codec info.
[read-only]
InputFormatMediaFormat. Call this after MediaCodec.Configure(MediaFormat,Surface,Surface,Surface) returns successfully to get the input format accepted by the codec.
[read-only]
NameString. Get the component name.
[read-only]
OutputFormatMediaFormat. Call this after dequeueOutputBuffer signals a format change by returning MediaCodec.InfoOutputFormatChanged.

Protected Properties

[read-only]
override
ThresholdClassIntPtr. This API supports the Mono for Android infrastructure and is not intended to be used directly from your code.
[read-only]
override
ThresholdTypeType. This API supports the Mono for Android infrastructure and is not intended to be used directly from your code.

Public Methods

Configure(MediaFormat, Surface, MediaCrypto, MediaCodecConfigFlags)
Configures a component.
static
CreateByCodecName(String) : MediaCodec
If you know the exact name of the component you want to instantiate use this method to instantiate it.
static
CreateDecoderByType(String) : MediaCodec
Instantiate the preferred decoder supporting input data of the given mime type.
static
CreateEncoderByType(String) : MediaCodec
Instantiate the preferred encoder supporting output data of the given mime type.
CreateInputSurface() : Surface
Requests a Surface to use as the input to an encoder, in place of input buffers.
DequeueInputBuffer(Int64) : Int32
Returns the index of an input buffer to be filled with valid data or -1 if no such buffer is currently available.
DequeueOutputBuffer(MediaCodec+BufferInfo, Int64) : Int32
Dequeue an output buffer, block at most "timeoutUs" microseconds.
Flush()
Flush both input and output ports of the component.
GetInputBuffer(Int32) : ByteBuffer
Returns a Buffer.Clear, writable ByteBuffer object for a dequeued input buffer index to contain the input data.
GetInputBuffers() : ByteBuffer[]
Retrieve the set of input buffers.
GetInputImage(Int32) : Image
Returns a writable Image object for a dequeued input buffer index to contain the raw input video frame.
GetOutputBuffer(Int32) : ByteBuffer
Returns a read-only ByteBuffer for a dequeued output buffer index.
GetOutputBuffers() : ByteBuffer[]
Retrieve the set of output buffers.
GetOutputFormat(Int32) : MediaFormat
Returns the output format for a specific output buffer.
GetOutputImage(Int32) : Image
Returns a read-only Image object for a dequeued output buffer index that contains the raw video frame.
QueueInputBuffer(Int32, Int32, Int32, Int64, MediaCodecBufferFlags)
After filling a range of the input buffer at the specified index submit it to the component.
QueueSecureInputBuffer(Int32, Int32, MediaCodec+CryptoInfo, Int64, MediaCodecBufferFlags)
Similar to MediaCodec.QueueInputBuffer(Int32,Int32,Int32,Int32,Int32) but submits a buffer that is potentially encrypted.
Release()
Free up resources used by the codec instance.
ReleaseOutputBuffer(Int32, Boolean)
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.
ReleaseOutputBuffer(Int32, Int64)
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.
Reset()
Returns the codec to its initial (Uninitialized) state.
SetCallback(MediaCodec+Callback)
Sets an asynchronous callback for actionable MediaCodec events on the default looper.
SetParameters(Bundle)
Communicate additional parameter changes to the component instance.
SetVideoScalingMode(VideoScalingMode)
If a surface has been specified in a previous call to MediaCodec.Configure(MediaFormat,Surface,Surface,Surface) specifies the scaling mode to use.
SignalEndOfInputStream()
Signals end-of-stream on input.
Start()
After successfully configuring the component, call start.
Stop()
Finish the decode/encode session, note that the codec instance remains active and ready to be MediaCodec.Started again.