Skip to content

Commit afa6ceb

Browse files
committed
media: Clarify MediaCodec and CodecCapabilities documentation
Bug: 21932760 Bug: 22847191 Change-Id: Iacd24099a98c73fe4fb50226564690aa9b01c772
1 parent 5cca30a commit afa6ceb

3 files changed

Lines changed: 144 additions & 38 deletions

File tree

media/java/android/media/MediaCodec.java

Lines changed: 106 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import android.annotation.Nullable;
2222
import android.graphics.ImageFormat;
2323
import android.graphics.Rect;
24+
import android.graphics.SurfaceTexture;
2425
import android.media.MediaCodecInfo.CodecCapabilities;
2526
import android.os.Bundle;
2627
import android.os.Handler;
@@ -32,6 +33,7 @@
3233
import java.lang.annotation.Retention;
3334
import java.lang.annotation.RetentionPolicy;
3435
import java.nio.ByteBuffer;
36+
import java.nio.ByteOrder;
3537
import java.nio.ReadOnlyBufferException;
3638
import java.util.Arrays;
3739
import java.util.HashMap;
@@ -228,37 +230,58 @@ you can set the decryption parameters for secure codecs (see {@link MediaCrypto}
228230
data and submit it as a single codec-config buffer.
229231
<p>
230232
Android uses the following codec-specific data buffers. These are also required to be set in
231-
the track format for proper {@link MediaMuxer} track configuration. Each parameter set and
232-
codec-specific-data must start with a start code of {@code "\x00\x00\x00\x01"}.
233+
the track format for proper {@link MediaMuxer} track configuration. Each parameter set and the
234+
codec-specific-data sections marked with (<sup>*</sup>) must start with a start code of
235+
{@code "\x00\x00\x00\x01"}.
233236
<p>
234237
<style>td.NA { background: #ccc; } .mid > tr > td { vertical-align: middle; }</style>
235238
<table>
236239
<thead>
237240
<th>Format</th>
238241
<th>CSD buffer #0</th>
239242
<th>CSD buffer #1</th>
243+
<th>CSD buffer #2</th>
240244
</thead>
241245
<tbody class=mid>
242246
<tr>
243247
<td>AAC</td>
244-
<td>Decoder-specific information from ESDS</td>
248+
<td>Decoder-specific information from ESDS<sup>*</sup></td>
245249
<td class=NA>Not Used</td>
250+
<td class=NA>Not Used</td>
251+
</tr>
252+
<tr>
253+
<td>VORBIS</td>
254+
<td>Identification header</td>
255+
<td>Setup header</td>
256+
<td class=NA>Not Used</td>
257+
</tr>
258+
<tr>
259+
<td>OPUS</td>
260+
<td>Identification header</td>
261+
<td>Pre-skip in nanosecs<br>
262+
(unsigned 64-bit {@linkplain ByteOrder#nativeOrder native-order} integer.)<br>
263+
This overrides the pre-skip value in the identification header.</td>
264+
<td>Seek Pre-roll in nanosecs<br>
265+
(unsigned 64-bit {@linkplain ByteOrder#nativeOrder native-order} integer.)</td>
246266
</tr>
247267
<tr>
248268
<td>MPEG-4</td>
249-
<td>Decoder-specific information from ESDS</td>
269+
<td>Decoder-specific information from ESDS<sup>*</sup></td>
270+
<td class=NA>Not Used</td>
250271
<td class=NA>Not Used</td>
251272
</tr>
252273
<tr>
253274
<td>H.264 AVC</td>
254-
<td>SPS (Sequence Parameter Sets)</td>
255-
<td>PPS (Picture Parameter Sets)</td>
275+
<td>SPS (Sequence Parameter Sets<sup>*</sup>)</td>
276+
<td>PPS (Picture Parameter Sets<sup>*</sup>)</td>
277+
<td class=NA>Not Used</td>
256278
</tr>
257279
<tr>
258280
<td>H.265 HEVC</td>
259-
<td>VPS (Video Parameter Sets) +<br>
260-
SPS (Sequence Parameter Sets) +<br>
261-
PPS (Picture Parameter Sets)</td>
281+
<td>VPS (Video Parameter Sets<sup>*</sup>) +<br>
282+
SPS (Sequence Parameter Sets<sup>*</sup>) +<br>
283+
PPS (Picture Parameter Sets<sup>*</sup>)</td>
284+
<td class=NA>Not Used</td>
262285
<td class=NA>Not Used</td>
263286
</tr>
264287
</tbody>
@@ -297,10 +320,10 @@ you can set the decryption parameters for secure codecs (see {@link MediaCrypto}
297320
releaseOutputBuffer} methods to return the buffer to the codec.
298321
<p>
299322
While you are not required to resubmit/release buffers immediately to the codec, holding onto
300-
input and/or output buffers may stall the codec, and this behavior is device dependent. E.g. it
301-
is possible that a codec may hold off on generating output buffers until all outstanding buffers
302-
have been released/resubmitted. Therefore, try to hold onto to available buffers as little as
303-
possible.
323+
input and/or output buffers may stall the codec, and this behavior is device dependent.
324+
<strong>Specifically, it is possible that a codec may hold off on generating output buffers until
325+
<em>all</em> outstanding buffers have been released/resubmitted.</strong> Therefore, try to
326+
hold onto to available buffers as little as possible.
304327
<p>
305328
Depending on the API version, you can process data in three ways:
306329
<table>
@@ -346,7 +369,7 @@ you can set the decryption parameters for secure codecs (see {@link MediaCrypto}
346369
<p>
347370
MediaCodec is typically used like this in asynchronous mode:
348371
<pre class=prettyprint>
349-
MediaCodec codec = MediaCodec.createCodecByName(name);
372+
MediaCodec codec = MediaCodec.createByCodecName(name);
350373
MediaFormat mOutputFormat; // member variable
351374
codec.setCallback(new MediaCodec.Callback() {
352375
{@literal @Override}
@@ -403,7 +426,7 @@ void onOutputFormatChanged(MediaCodec mc, MediaFormat format) {
403426
<p>
404427
MediaCodec is typically used like this in synchronous mode:
405428
<pre>
406-
MediaCodec codec = MediaCodec.createCodecByName(name);
429+
MediaCodec codec = MediaCodec.createByCodecName(name);
407430
codec.configure(format, &hellip;);
408431
MediaFormat outputFormat = codec.getOutputFormat(); // option B
409432
codec.start();
@@ -442,7 +465,7 @@ <h4>Synchronous Processing using Buffer Arrays (deprecated)</h4>
442465
between the size of the arrays and the number of input and output buffers used by the system,
443466
although the array size provides an upper bound.
444467
<pre>
445-
MediaCodec codec = MediaCodec.createCodecByName(name);
468+
MediaCodec codec = MediaCodec.createByCodecName(name);
446469
codec.configure(format, &hellip;);
447470
codec.start();
448471
ByteBuffer[] inputBuffers = codec.getInputBuffers();
@@ -643,10 +666,10 @@ In order to start decoding data that is not adjacent to previously submitted dat
643666
class. For API version numbers, see {@link android.os.Build.VERSION_CODES}.
644667
645668
<style>
646-
.api > tr > th, td { text-align: center; padding: 4px 4px; }
669+
.api > tr > th, .api > tr > td { text-align: center; padding: 4px 4px; }
647670
.api > tr > th { vertical-align: bottom; }
648671
.api > tr > td { vertical-align: middle; }
649-
.sml > tr > th, td { text-align: center; padding: 2px 4px; }
672+
.sml > tr > th, .sml > tr > td { text-align: center; padding: 2px 4px; }
650673
.fn { text-align: left; }
651674
.fn > code > a { font: 14px/19px Roboto Condensed, sans-serif; }
652675
.deg45 {
@@ -1561,7 +1584,7 @@ private void handleCallback(@NonNull Message msg) {
15611584
private boolean mHasSurface = false;
15621585

15631586
/**
1564-
* Instantiate a decoder supporting input data of the given mime type.
1587+
* Instantiate the preferred decoder supporting input data of the given mime type.
15651588
*
15661589
* The following is a partial list of defined mime types and their semantics:
15671590
* <ul>
@@ -1580,6 +1603,10 @@ private void handleCallback(@NonNull Message msg) {
15801603
* <li>"audio/g711-mlaw" - G.711 ulaw audio
15811604
* </ul>
15821605
*
1606+
* <strong>Note:</strong> It is preferred to use {@link MediaCodecList#findDecoderForFormat}
1607+
* and {@link #createByCodecName} to ensure that the resulting codec can handle a
1608+
* given format.
1609+
*
15831610
* @param type The mime type of the input data.
15841611
* @throws IOException if the codec cannot be created.
15851612
* @throws IllegalArgumentException if type is not a valid mime type.
@@ -1592,7 +1619,12 @@ public static MediaCodec createDecoderByType(@NonNull String type)
15921619
}
15931620

15941621
/**
1595-
* Instantiate an encoder supporting output data of the given mime type.
1622+
* Instantiate the preferred encoder supporting output data of the given mime type.
1623+
*
1624+
* <strong>Note:</strong> It is preferred to use {@link MediaCodecList#findEncoderForFormat}
1625+
* and {@link #createByCodecName} to ensure that the resulting codec can handle a
1626+
* given format.
1627+
*
15961628
* @param type The desired mime type of the output data.
15971629
* @throws IOException if the codec cannot be created.
15981630
* @throws IllegalArgumentException if type is not a valid mime type.
@@ -1661,6 +1693,8 @@ public final void reset() {
16611693
private native final void native_reset();
16621694

16631695
/**
1696+
* Free up resources used by the codec instance.
1697+
*
16641698
* Make sure you call this when you're done to free up any opened
16651699
* component instance instead of relying on the garbage collector
16661700
* to do this for you at some point in the future.
@@ -1881,17 +1915,25 @@ public final void stop() {
18811915
private native final void native_stop();
18821916

18831917
/**
1884-
* Flush both input and output ports of the component, all indices
1885-
* previously returned in calls to {@link #dequeueInputBuffer} and
1886-
* {@link #dequeueOutputBuffer} become invalid.
1918+
* Flush both input and output ports of the component.
18871919
* <p>
1888-
* If codec is configured in asynchronous mode, call {@link #start}
1889-
* after {@code flush} has returned to resume codec operations. The
1890-
* codec will not request input buffers until this has happened.
1920+
* Upon return, all indices previously returned in calls to {@link #dequeueInputBuffer
1921+
* dequeueInputBuffer} and {@link #dequeueOutputBuffer dequeueOutputBuffer} &mdash; or obtained
1922+
* via {@link Callback#onInputBufferAvailable onInputBufferAvailable} or
1923+
* {@link Callback#onOutputBufferAvailable onOutputBufferAvailable} callbacks &mdash; become
1924+
* invalid, and all buffers are owned by the codec.
18911925
* <p>
1892-
* If codec is configured in synchronous mode, codec will resume
1893-
* automatically if an input surface was created. Otherwise, it
1894-
* will resume when {@link #dequeueInputBuffer} is called.
1926+
* If the codec is configured in asynchronous mode, call {@link #start}
1927+
* after {@code flush} has returned to resume codec operations. The codec
1928+
* will not request input buffers until this has happened.
1929+
* <strong>Note, however, that there may still be outstanding {@code onOutputBufferAvailable}
1930+
* callbacks that were not handled prior to calling {@code flush}.
1931+
* The indices returned via these callbacks also become invalid upon calling {@code flush} and
1932+
* should be discarded.</strong>
1933+
* <p>
1934+
* If the codec is configured in synchronous mode, codec will resume
1935+
* automatically if it is configured with an input surface. Otherwise, it
1936+
* will resume when {@link #dequeueInputBuffer dequeueInputBuffer} is called.
18951937
*
18961938
* @throws IllegalStateException if not in the Executing state.
18971939
* @throws MediaCodec.CodecException upon codec error.
@@ -2082,14 +2124,26 @@ public int getErrorCode() {
20822124
* To indicate that this is the final piece of input data (or rather that
20832125
* no more input data follows unless the decoder is subsequently flushed)
20842126
* specify the flag {@link #BUFFER_FLAG_END_OF_STREAM}.
2127+
* <p class=note>
2128+
* <strong>Note:</strong> Prior to {@link android.os.Build.VERSION_CODES#M},
2129+
* {@code presentationTimeUs} was not propagated to the frame timestamp of (rendered)
2130+
* Surface output buffers, and the resulting frame timestamp was undefined.
2131+
* Use {@link #releaseOutputBuffer(int, long)} to ensure a specific frame timestamp is set.
2132+
* Similarly, since frame timestamps can be used by the destination surface for rendering
2133+
* synchronization, <strong>care must be taken to normalize presentationTimeUs so as to not be
2134+
* mistaken for a system time. (See {@linkplain #releaseOutputBuffer(int, long)
2135+
* SurfaceView specifics}).</strong>
20852136
*
20862137
* @param index The index of a client-owned input buffer previously returned
20872138
* in a call to {@link #dequeueInputBuffer}.
20882139
* @param offset The byte offset into the input buffer at which the data starts.
20892140
* @param size The number of bytes of valid input data.
20902141
* @param presentationTimeUs The presentation timestamp in microseconds for this
20912142
* buffer. This is normally the media time at which this
2092-
* buffer should be presented (rendered).
2143+
* buffer should be presented (rendered). When using an output
2144+
* surface, this will be propagated as the {@link
2145+
* SurfaceTexture#getTimestamp timestamp} for the frame (after
2146+
* conversion to nanoseconds).
20932147
* @param flags A bitmask of flags
20942148
* {@link #BUFFER_FLAG_CODEC_CONFIG} and {@link #BUFFER_FLAG_END_OF_STREAM}.
20952149
* While not prohibited, most codecs do not use the
@@ -2202,8 +2256,10 @@ public String toString() {
22022256
};
22032257

22042258
/**
2205-
* Similar to {@link #queueInputBuffer} but submits a buffer that is
2259+
* Similar to {@link #queueInputBuffer queueInputBuffer} but submits a buffer that is
22062260
* potentially encrypted.
2261+
* <strong>Check out further notes at {@link #queueInputBuffer queueInputBuffer}.</strong>
2262+
*
22072263
* @param index The index of a client-owned input buffer previously returned
22082264
* in a call to {@link #dequeueInputBuffer}.
22092265
* @param offset The byte offset into the input buffer at which the data starts.
@@ -2310,7 +2366,7 @@ public final int dequeueInputBuffer(long timeoutUs) {
23102366
/**
23112367
* Dequeue an output buffer, block at most "timeoutUs" microseconds.
23122368
* Returns the index of an output buffer that has been successfully
2313-
* decoded or one of the INFO_* constants below.
2369+
* decoded or one of the INFO_* constants.
23142370
* @param info Will be filled with buffer meta data.
23152371
* @param timeoutUs The timeout in microseconds, a negative timeout indicates "infinite".
23162372
* @throws IllegalStateException if not in the Executing state,
@@ -2338,9 +2394,11 @@ private native final int native_dequeueOutputBuffer(
23382394
@NonNull BufferInfo info, long timeoutUs);
23392395

23402396
/**
2341-
* If you are done with a buffer, use this call to return the buffer to
2342-
* the codec. If you previously specified a surface when configuring this
2343-
* video decoder you can optionally render the buffer.
2397+
* If you are done with a buffer, use this call to return the buffer to the codec
2398+
* or to render it on the output surface. If you configured the codec with an
2399+
* output surface, setting {@code render} to {@code true} will first send the buffer
2400+
* to that output surface. The surface will release the buffer back to the codec once
2401+
* it is no longer used/displayed.
23442402
*
23452403
* Once an output buffer is released to the codec, it MUST NOT
23462404
* be used until it is later retrieved by {@link #getOutputBuffer} in response
@@ -2674,6 +2732,8 @@ private final void cacheBuffers(boolean input) {
26742732
* <b>Note:</b> As of API 21, dequeued input buffers are
26752733
* automatically {@link java.nio.Buffer#clear cleared}.
26762734
*
2735+
* <em>Do not use this method if using an input surface.</em>
2736+
*
26772737
* @throws IllegalStateException if not in the Executing state,
26782738
* or codec is configured in asynchronous mode.
26792739
* @throws MediaCodec.CodecException upon codec error.
@@ -2703,6 +2763,8 @@ public ByteBuffer[] getInputBuffers() {
27032763
* buffers that are dequeued will be set to the valid data
27042764
* range.
27052765
*
2766+
* <em>Do not use this method if using an output surface.</em>
2767+
*
27062768
* @throws IllegalStateException if not in the Executing state,
27072769
* or codec is configured in asynchronous mode.
27082770
* @throws MediaCodec.CodecException upon codec error.
@@ -2988,6 +3050,10 @@ public interface OnFrameRenderedListener {
29883050

29893051
/**
29903052
* Called when an output frame has rendered on the output surface.
3053+
* <p>
3054+
* <strong>Note:</strong> This callback is for informational purposes only: to get precise
3055+
* render timing samples, and can be significantly delayed and batched. Some frames may have
3056+
* been rendered even if there was no callback generated.
29913057
*
29923058
* @param codec the MediaCodec instance
29933059
* @param presentationTimeUs the presentation time (media time) of the frame rendered.
@@ -3004,10 +3070,14 @@ public void onFrameRendered(
30043070
}
30053071

30063072
/**
3007-
* Register a callback to be invoked when an output frame is rendered on the output surface.
3073+
* Registers a callback to be invoked when an output frame is rendered on the output surface.
30083074
* <p>
30093075
* This method can be called in any codec state, but will only have an effect in the
30103076
* Executing state for codecs that render buffers to the output surface.
3077+
* <p>
3078+
* <strong>Note:</strong> This callback is for informational purposes only: to get precise
3079+
* render timing samples, and can be significantly delayed and batched. Some frames may have
3080+
* been rendered even if there was no callback generated.
30113081
*
30123082
* @param listener the callback that will be run
30133083
* @param handler the callback will be run on the handler's thread. If {@code null},

media/java/android/media/MediaCodecInfo.java

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,14 @@ public boolean isRegular() {
525525

526526
/**
527527
* Query whether codec supports a given {@link MediaFormat}.
528+
*
529+
* <p class=note>
530+
* <strong>Note:</strong> On {@link android.os.Build.VERSION_CODES#LOLLIPOP},
531+
* {@code format} must not contain a {@linkplain MediaFormat#KEY_FRAME_RATE
532+
* frame rate}. Use
533+
* <code class=prettyprint>format.setString(MediaFormat.KEY_FRAME_RATE, null)</code>
534+
* to clear any existing frame rate setting in the format.
535+
*
528536
* @param format media format with optional feature directives.
529537
* @throws IllegalArgumentException if format is not a valid media format.
530538
* @return whether the codec capabilities support the given format
@@ -1230,8 +1238,22 @@ private Range<Double> estimateFrameRatesFor(int width, int height) {
12301238
* May return {@code null}, if the codec did not publish any measurement
12311239
* data.
12321240
* <p>
1233-
* This is a performance estimate, based on full-speed decoding
1234-
* and encoding measurements of common video sizes supported by the codec.
1241+
* This is a performance estimate provided by the device manufacturer
1242+
* based on full-speed decoding and encoding measurements in various configurations
1243+
* of common video sizes supported by the codec. As such it should only be used to
1244+
* compare individual codecs on the device. The value is not suitable for comparing
1245+
* different devices or even different android releases for the same device.
1246+
* <p>
1247+
* The returned range corresponds to the fastest frame rates achieved in the tested
1248+
* configurations. It is interpolated from the nearest frame size(s) tested. Codec
1249+
* performance is severely impacted by other activity on the device, and can vary
1250+
* significantly.
1251+
* <p class=note>
1252+
* Use this method in cases where only codec performance matters, e.g. to evaluate if
1253+
* a codec has any chance of meeting a performance target. Codecs are listed
1254+
* in {@link MediaCodecList} in the preferred order as defined by the device
1255+
* manufacturer. As such, applications should use the first suitable codec in the
1256+
* list to achieve the best balance between power use and performance.
12351257
*
12361258
* @param width the width of the video
12371259
* @param height the height of the video

0 commit comments

Comments
 (0)