1/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.media;
18
19import android.media.MediaCodecInfo;
20import android.media.MediaCodecList;
21import android.media.MediaCrypto;
22import android.media.MediaFormat;
23import android.os.Bundle;
24import android.view.Surface;
25
26import java.nio.ByteBuffer;
27import java.util.Arrays;
28import java.util.Map;
29
30/**
31 * MediaCodec class can be used to access low-level media codec, i.e.
32 * encoder/decoder components.
33 *
34 * <p>MediaCodec is generally used like this:
35 * <pre>
36 * MediaCodec codec = MediaCodec.createDecoderByType(type);
37 * codec.configure(format, ...);
38 * codec.start();
39 * ByteBuffer[] inputBuffers = codec.getInputBuffers();
40 * ByteBuffer[] outputBuffers = codec.getOutputBuffers();
41 * for (;;) {
42 *   int inputBufferIndex = codec.dequeueInputBuffer(timeoutUs);
43 *   if (inputBufferIndex &gt;= 0) {
44 *     // fill inputBuffers[inputBufferIndex] with valid data
45 *     ...
46 *     codec.queueInputBuffer(inputBufferIndex, ...);
47 *   }
48 *
49 *   int outputBufferIndex = codec.dequeueOutputBuffer(timeoutUs);
50 *   if (outputBufferIndex &gt;= 0) {
51 *     // outputBuffer is ready to be processed or rendered.
52 *     ...
53 *     codec.releaseOutputBuffer(outputBufferIndex, ...);
54 *   } else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
55 *     outputBuffers = codec.getOutputBuffers();
56 *   } else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
57 *     // Subsequent data will conform to new format.
58 *     MediaFormat format = codec.getOutputFormat();
59 *     ...
60 *   }
61 * }
62 * codec.stop();
63 * codec.release();
64 * codec = null;
65 * </pre>
66 *
67 * Each codec maintains a number of input and output buffers that are
68 * referred to by index in API calls.
69 * The contents of these buffers is represented by the ByteBuffer[] arrays
70 * accessible through getInputBuffers() and getOutputBuffers().
71 *
72 * After a successful call to {@link #start} the client "owns" neither
73 * input nor output buffers, subsequent calls to {@link #dequeueInputBuffer}
74 * and {@link #dequeueOutputBuffer} then transfer ownership from the codec
75 * to the client.<p>
76 * The client is not required to resubmit/release buffers immediately
77 * to the codec, the sample code above simply does this for simplicity's sake.<p>
78 * Once the client has an input buffer available it can fill it with data
79 * and submit it it to the codec via a call to {@link #queueInputBuffer}.<p>
80 * The codec in turn will return an output buffer to the client in response
81 * to {@link #dequeueOutputBuffer}. After the output buffer has been processed
82 * a call to {@link #releaseOutputBuffer} will return it to the codec.
83 * If a video surface has been provided in the call to {@link #configure},
84 * {@link #releaseOutputBuffer} optionally allows rendering of the buffer
85 * to the surface.<p>
86 *
87 * Input buffers (for decoders) and Output buffers (for encoders) contain
88 * encoded data according to the format's type. For video types this data
89 * is all the encoded data representing a single moment in time, for audio
90 * data this is slightly relaxed in that a buffer may contain multiple
91 * encoded frames of audio. In either case, buffers do not start and end on
92 * arbitrary byte boundaries, this is not a stream of bytes, it's a stream
93 * of access units.<p>
94 *
95 * Most formats also require the actual data to be prefixed by a number
96 * of buffers containing setup data, or codec specific data, i.e. the
97 * first few buffers submitted to the codec object after starting it must
98 * be codec specific data marked as such using the flag {@link #BUFFER_FLAG_CODEC_CONFIG}
99 * in a call to {@link #queueInputBuffer}.
100 *
101 * Codec specific data included in the format passed to {@link #configure}
102 * (in ByteBuffer entries with keys "csd-0", "csd-1", ...) is automatically
103 * submitted to the codec, this data MUST NOT be submitted explicitly by the
104 * client.
105 *
106 * Once the client reaches the end of the input data it signals the end of
107 * the input stream by specifying a flag of {@link #BUFFER_FLAG_END_OF_STREAM} in the call to
108 * {@link #queueInputBuffer}. The codec will continue to return output buffers
109 * until it eventually signals the end of the output stream by specifying
110 * the same flag ({@link #BUFFER_FLAG_END_OF_STREAM}) on the BufferInfo returned in
111 * {@link #dequeueOutputBuffer}.
112 *
113 * In order to start decoding data that's not adjacent to previously submitted
114 * data (i.e. after a seek) it is necessary to {@link #flush} the decoder.
115 * Any input or output buffers the client may own at the point of the flush are
116 * immediately revoked, i.e. after a call to {@link #flush} the client does not
117 * own any buffers anymore.
118 * Note that the format of the data submitted after a flush must not change,
119 * flush does not support format discontinuities,
120 * for this a full stop(), configure(), start() cycle is necessary.
121 *
122 */
123final public class MediaCodec {
124    /**
125     * Per buffer metadata includes an offset and size specifying
126     * the range of valid data in the associated codec buffer.
127     */
128    public final static class BufferInfo {
129        public void set(
130                int newOffset, int newSize, long newTimeUs, int newFlags) {
131            offset = newOffset;
132            size = newSize;
133            presentationTimeUs = newTimeUs;
134            flags = newFlags;
135        }
136
137        public int offset;
138        public int size;
139        public long presentationTimeUs;
140        public int flags;
141    };
142
143    // The follow flag constants MUST stay in sync with their equivalents
144    // in MediaCodec.h !
145
146    /**
147     * This indicates that the buffer marked as such contains the data
148     * for a sync frame.
149     */
150    public static final int BUFFER_FLAG_SYNC_FRAME   = 1;
151
152    /**
153     * This indicated that the buffer marked as such contains codec
154     * initialization / codec specific data instead of media data.
155     */
156    public static final int BUFFER_FLAG_CODEC_CONFIG = 2;
157
158    /**
159     * This signals the end of stream, i.e. no buffers will be available
160     * after this, unless of course, {@link #flush} follows.
161     */
162    public static final int BUFFER_FLAG_END_OF_STREAM         = 4;
163
164    /**
165     * Instantiate a decoder supporting input data of the given mime type.
166     *
167     * The following is a partial list of defined mime types and their semantics:
168     * <ul>
169     * <li>"video/x-vnd.on2.vp8" - VP8 video (i.e. video in .webm)
170     * <li>"video/x-vnd.on2.vp9" - VP9 video (i.e. video in .webm)
171     * <li>"video/avc" - H.264/AVC video
172     * <li>"video/mp4v-es" - MPEG4 video
173     * <li>"video/3gpp" - H.263 video
174     * <li>"audio/3gpp" - AMR narrowband audio
175     * <li>"audio/amr-wb" - AMR wideband audio
176     * <li>"audio/mpeg" - MPEG1/2 audio layer III
177     * <li>"audio/mp4a-latm" - AAC audio (note, this is raw AAC packets, not packaged in LATM!)
178     * <li>"audio/vorbis" - vorbis audio
179     * <li>"audio/g711-alaw" - G.711 alaw audio
180     * <li>"audio/g711-mlaw" - G.711 ulaw audio
181     * </ul>
182     *
183     * @param type The mime type of the input data.
184     */
185    public static MediaCodec createDecoderByType(String type) {
186        return new MediaCodec(type, true /* nameIsType */, false /* encoder */);
187    }
188
189    /**
190     * Instantiate an encoder supporting output data of the given mime type.
191     * @param type The desired mime type of the output data.
192     */
193    public static MediaCodec createEncoderByType(String type) {
194        return new MediaCodec(type, true /* nameIsType */, true /* encoder */);
195    }
196
197    /**
198     * If you know the exact name of the component you want to instantiate
199     * use this method to instantiate it. Use with caution.
200     * Likely to be used with information obtained from {@link android.media.MediaCodecList}
201     * @param name The name of the codec to be instantiated.
202     */
203    public static MediaCodec createByCodecName(String name) {
204        return new MediaCodec(
205                name, false /* nameIsType */, false /* unused */);
206    }
207
208    private MediaCodec(
209            String name, boolean nameIsType, boolean encoder) {
210        native_setup(name, nameIsType, encoder);
211    }
212
213    @Override
214    protected void finalize() {
215        native_finalize();
216    }
217
218    /**
219     * Make sure you call this when you're done to free up any opened
220     * component instance instead of relying on the garbage collector
221     * to do this for you at some point in the future.
222     */
223    public native final void release();
224
225    /**
226     * If this codec is to be used as an encoder, pass this flag.
227     */
228    public static final int CONFIGURE_FLAG_ENCODE = 1;
229
230    /**
231     * Configures a component.
232     *
233     * @param format The format of the input data (decoder) or the desired
234     *               format of the output data (encoder).
235     * @param surface Specify a surface on which to render the output of this
236     *                decoder.
237     * @param crypto  Specify a crypto object to facilitate secure decryption
238     *                of the media data.
239     * @param flags   Specify {@link #CONFIGURE_FLAG_ENCODE} to configure the
240     *                component as an encoder.
241     */
242    public void configure(
243            MediaFormat format,
244            Surface surface, MediaCrypto crypto, int flags) {
245        Map<String, Object> formatMap = format.getMap();
246
247        String[] keys = null;
248        Object[] values = null;
249
250        if (format != null) {
251            keys = new String[formatMap.size()];
252            values = new Object[formatMap.size()];
253
254            int i = 0;
255            for (Map.Entry<String, Object> entry: formatMap.entrySet()) {
256                keys[i] = entry.getKey();
257                values[i] = entry.getValue();
258                ++i;
259            }
260        }
261
262        native_configure(keys, values, surface, crypto, flags);
263    }
264
265    private native final void native_configure(
266            String[] keys, Object[] values,
267            Surface surface, MediaCrypto crypto, int flags);
268
269    /**
270     * Requests a Surface to use as the input to an encoder, in place of input buffers.  This
271     * may only be called after {@link #configure} and before {@link #start}.
272     * <p>
273     * The application is responsible for calling release() on the Surface when
274     * done.
275     */
276    public native final Surface createInputSurface();
277
278    /**
279     * After successfully configuring the component, call start. On return
280     * you can query the component for its input/output buffers.
281     */
282    public native final void start();
283
284    /**
285     * Finish the decode/encode session, note that the codec instance
286     * remains active and ready to be {@link #start}ed again.
287     * To ensure that it is available to other client call {@link #release}
288     * and don't just rely on garbage collection to eventually do this for you.
289     */
290    public native final void stop();
291
292    /**
293     * Flush both input and output ports of the component, all indices
294     * previously returned in calls to {@link #dequeueInputBuffer} and
295     * {@link #dequeueOutputBuffer} become invalid.
296     */
297    public native final void flush();
298
299    /**
300     * Thrown when a crypto error occurs while queueing a secure input buffer.
301     */
302    public final static class CryptoException extends RuntimeException {
303        public CryptoException(int errorCode, String detailMessage) {
304            super(detailMessage);
305            mErrorCode = errorCode;
306        }
307
308        /**
309         * This indicates that no key has been set to perform the requested
310         * decrypt operation.
311         */
312        public static final int ERROR_NO_KEY = 1;
313
314        /**
315         * This indicates that the key used for decryption is no longer
316         * valid due to license term expiration.
317         */
318        public static final int ERROR_KEY_EXPIRED = 2;
319
320        /**
321         * This indicates that a required crypto resource was not able to be
322         * allocated while attempting the requested operation.
323         */
324        public static final int ERROR_RESOURCE_BUSY = 3;
325
326        /**
327         * Retrieve the error code associated with a CryptoException
328         */
329        public int getErrorCode() {
330            return mErrorCode;
331        }
332
333        private int mErrorCode;
334    }
335
336    /**
337     * After filling a range of the input buffer at the specified index
338     * submit it to the component.
339     *
340     * Many decoders require the actual compressed data stream to be
341     * preceded by "codec specific data", i.e. setup data used to initialize
342     * the codec such as PPS/SPS in the case of AVC video or code tables
343     * in the case of vorbis audio.
344     * The class {@link android.media.MediaExtractor} provides codec
345     * specific data as part of
346     * the returned track format in entries named "csd-0", "csd-1" ...
347     *
348     * These buffers should be submitted using the flag {@link #BUFFER_FLAG_CODEC_CONFIG}.
349     *
350     * To indicate that this is the final piece of input data (or rather that
351     * no more input data follows unless the decoder is subsequently flushed)
352     * specify the flag {@link #BUFFER_FLAG_END_OF_STREAM}.
353     *
354     * @param index The index of a client-owned input buffer previously returned
355     *              in a call to {@link #dequeueInputBuffer}.
356     * @param offset The byte offset into the input buffer at which the data starts.
357     * @param size The number of bytes of valid input data.
358     * @param presentationTimeUs The time at which this buffer should be rendered.
359     * @param flags A bitmask of flags {@link #BUFFER_FLAG_SYNC_FRAME},
360     *              {@link #BUFFER_FLAG_CODEC_CONFIG} or {@link #BUFFER_FLAG_END_OF_STREAM}.
361     * @throws CryptoException if a crypto object has been specified in
362     *         {@link #configure}
363     */
364    public native final void queueInputBuffer(
365            int index,
366            int offset, int size, long presentationTimeUs, int flags)
367        throws CryptoException;
368
369    // The following mode constants MUST stay in sync with their equivalents
370    // in media/hardware/CryptoAPI.h !
371    public static final int CRYPTO_MODE_UNENCRYPTED = 0;
372    public static final int CRYPTO_MODE_AES_CTR     = 1;
373
374    /**
375     * Metadata describing the structure of a (at least partially) encrypted
376     * input sample.
377     * A buffer's data is considered to be partitioned into "subSamples",
378     * each subSample starts with a (potentially empty) run of plain,
379     * unencrypted bytes followed by a (also potentially empty) run of
380     * encrypted bytes.
381     * numBytesOfClearData can be null to indicate that all data is encrypted.
382     * This information encapsulates per-sample metadata as outlined in
383     * ISO/IEC FDIS 23001-7:2011 "Common encryption in ISO base media file format files".
384     */
385    public final static class CryptoInfo {
386        public void set(
387                int newNumSubSamples,
388                int[] newNumBytesOfClearData,
389                int[] newNumBytesOfEncryptedData,
390                byte[] newKey,
391                byte[] newIV,
392                int newMode) {
393            numSubSamples = newNumSubSamples;
394            numBytesOfClearData = newNumBytesOfClearData;
395            numBytesOfEncryptedData = newNumBytesOfEncryptedData;
396            key = newKey;
397            iv = newIV;
398            mode = newMode;
399        }
400
401        /**
402         * The number of subSamples that make up the buffer's contents.
403         */
404        public int numSubSamples;
405        /**
406         * The number of leading unencrypted bytes in each subSample.
407         */
408        public int[] numBytesOfClearData;
409        /**
410         * The number of trailing encrypted bytes in each subSample.
411         */
412        public int[] numBytesOfEncryptedData;
413        /**
414         * A 16-byte opaque key
415         */
416        public byte[] key;
417        /**
418         * A 16-byte initialization vector
419         */
420        public byte[] iv;
421        /**
422         * The type of encryption that has been applied,
423         * see {@link #CRYPTO_MODE_UNENCRYPTED} and {@link #CRYPTO_MODE_AES_CTR}.
424         */
425        public int mode;
426
427        @Override
428        public String toString() {
429            StringBuilder builder = new StringBuilder();
430            builder.append(numSubSamples + " subsamples, key [");
431            String hexdigits = "0123456789abcdef";
432            for (int i = 0; i < key.length; i++) {
433                builder.append(hexdigits.charAt((key[i] & 0xf0) >> 4));
434                builder.append(hexdigits.charAt(key[i] & 0x0f));
435            }
436            builder.append("], iv [");
437            for (int i = 0; i < key.length; i++) {
438                builder.append(hexdigits.charAt((iv[i] & 0xf0) >> 4));
439                builder.append(hexdigits.charAt(iv[i] & 0x0f));
440            }
441            builder.append("], clear ");
442            builder.append(Arrays.toString(numBytesOfClearData));
443            builder.append(", encrypted ");
444            builder.append(Arrays.toString(numBytesOfEncryptedData));
445            return builder.toString();
446        }
447    };
448
449    /**
450     * Similar to {@link #queueInputBuffer} but submits a buffer that is
451     * potentially encrypted.
452     * @param index The index of a client-owned input buffer previously returned
453     *              in a call to {@link #dequeueInputBuffer}.
454     * @param offset The byte offset into the input buffer at which the data starts.
455     * @param info Metadata required to facilitate decryption, the object can be
456     *             reused immediately after this call returns.
457     * @param presentationTimeUs The time at which this buffer should be rendered.
458     * @param flags A bitmask of flags {@link #BUFFER_FLAG_SYNC_FRAME},
459     *              {@link #BUFFER_FLAG_CODEC_CONFIG} or {@link #BUFFER_FLAG_END_OF_STREAM}.
460     * @throws CryptoException if an error occurs while attempting to decrypt the buffer.
461     *              An error code associated with the exception helps identify the
462     *              reason for the failure.
463     */
464    public native final void queueSecureInputBuffer(
465            int index,
466            int offset,
467            CryptoInfo info,
468            long presentationTimeUs,
469            int flags) throws CryptoException;
470
471    /**
472     * Returns the index of an input buffer to be filled with valid data
473     * or -1 if no such buffer is currently available.
474     * This method will return immediately if timeoutUs == 0, wait indefinitely
475     * for the availability of an input buffer if timeoutUs &lt; 0 or wait up
476     * to "timeoutUs" microseconds if timeoutUs &gt; 0.
477     * @param timeoutUs The timeout in microseconds, a negative timeout indicates "infinite".
478     */
479    public native final int dequeueInputBuffer(long timeoutUs);
480
481    /**
482     * If a non-negative timeout had been specified in the call
483     * to {@link #dequeueOutputBuffer}, indicates that the call timed out.
484     */
485    public static final int INFO_TRY_AGAIN_LATER        = -1;
486
487    /**
488     * The output format has changed, subsequent data will follow the new
489     * format. {@link #getOutputFormat} returns the new format.
490     */
491    public static final int INFO_OUTPUT_FORMAT_CHANGED  = -2;
492
493    /**
494     * The output buffers have changed, the client must refer to the new
495     * set of output buffers returned by {@link #getOutputBuffers} from
496     * this point on.
497     */
498    public static final int INFO_OUTPUT_BUFFERS_CHANGED = -3;
499
500    /**
501     * Dequeue an output buffer, block at most "timeoutUs" microseconds.
502     * Returns the index of an output buffer that has been successfully
503     * decoded or one of the INFO_* constants below.
504     * @param info Will be filled with buffer meta data.
505     * @param timeoutUs The timeout in microseconds, a negative timeout indicates "infinite".
506     */
507    public native final int dequeueOutputBuffer(
508            BufferInfo info, long timeoutUs);
509
510    /**
511     * If you are done with a buffer, use this call to return the buffer to
512     * the codec. If you previously specified a surface when configuring this
513     * video decoder you can optionally render the buffer.
514     * @param index The index of a client-owned output buffer previously returned
515     *              in a call to {@link #dequeueOutputBuffer}.
516     * @param render If a valid surface was specified when configuring the codec,
517     *               passing true renders this output buffer to the surface.
518     */
519    public native final void releaseOutputBuffer(int index, boolean render);
520
521    /**
522     * Signals end-of-stream on input.  Equivalent to submitting an empty buffer with
523     * {@link #BUFFER_FLAG_END_OF_STREAM} set.  This may only be used with
524     * encoders receiving input from a Surface created by {@link #createInputSurface}.
525     */
526    public native final void signalEndOfInputStream();
527
528    /**
529     * Call this after dequeueOutputBuffer signals a format change by returning
530     * {@link #INFO_OUTPUT_FORMAT_CHANGED}
531     */
532    public final MediaFormat getOutputFormat() {
533        return new MediaFormat(getOutputFormatNative());
534    }
535
536    private native final Map<String, Object> getOutputFormatNative();
537
538    /**
539     * Call this after start() returns.
540     */
541    public ByteBuffer[] getInputBuffers() {
542        return getBuffers(true /* input */);
543    }
544
545    /**
546     * Call this after start() returns and whenever dequeueOutputBuffer
547     * signals an output buffer change by returning
548     * {@link #INFO_OUTPUT_BUFFERS_CHANGED}
549     */
550    public ByteBuffer[] getOutputBuffers() {
551        return getBuffers(false /* input */);
552    }
553
554    /**
555     * The content is scaled to the surface dimensions
556     */
557    public static final int VIDEO_SCALING_MODE_SCALE_TO_FIT               = 1;
558
559    /**
560     * The content is scaled, maintaining its aspect ratio, the whole
561     * surface area is used, content may be cropped
562     */
563    public static final int VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING = 2;
564
565    /**
566     * If a surface has been specified in a previous call to {@link #configure}
567     * specifies the scaling mode to use. The default is "scale to fit".
568     */
569    public native final void setVideoScalingMode(int mode);
570
571    /**
572     * Get the component name. If the codec was created by createDecoderByType
573     * or createEncoderByType, what component is chosen is not known beforehand.
574     */
575    public native final String getName();
576
577    /**
578     * Change a video encoder's target bitrate on the fly. The value is an
579     * Integer object containing the new bitrate in bps.
580     */
581    public static final String PARAMETER_KEY_VIDEO_BITRATE = "video-bitrate";
582
583    /**
584     * Temporarily suspend/resume encoding of input data. While suspended
585     * input data is effectively discarded instead of being fed into the
586     * encoder. This parameter really only makes sense to use with an encoder
587     * in "surface-input" mode, as the client code has no control over the
588     * input-side of the encoder in that case.
589     * The value is an Integer object containing the value 1 to suspend
590     * or the value 0 to resume.
591     */
592    public static final String PARAMETER_KEY_SUSPEND = "drop-input-frames";
593
594    /**
595     * Request that the encoder produce a sync frame "soon".
596     * Provide an Integer with the value 0.
597     */
598    public static final String PARAMETER_KEY_REQUEST_SYNC_FRAME = "request-sync";
599
600    /**
601     * Communicate additional parameter changes to the component instance.
602     */
603    public final void setParameters(Bundle params) {
604        if (params == null) {
605            return;
606        }
607
608        String[] keys = new String[params.size()];
609        Object[] values = new Object[params.size()];
610
611        int i = 0;
612        for (final String key: params.keySet()) {
613            keys[i] = key;
614            values[i] = params.get(key);
615            ++i;
616        }
617
618        setParameters(keys, values);
619    }
620
621    private native final void setParameters(String[] keys, Object[] values);
622
623    /**
624     * Get the codec info. If the codec was created by createDecoderByType
625     * or createEncoderByType, what component is chosen is not known beforehand,
626     * and thus the caller does not have the MediaCodecInfo.
627     */
628    public MediaCodecInfo getCodecInfo() {
629        return MediaCodecList.getCodecInfoAt(
630                   MediaCodecList.findCodecByName(getName()));
631    }
632
633    private native final ByteBuffer[] getBuffers(boolean input);
634
635    private static native final void native_init();
636
637    private native final void native_setup(
638            String name, boolean nameIsType, boolean encoder);
639
640    private native final void native_finalize();
641
642    static {
643        System.loadLibrary("media_jni");
644        native_init();
645    }
646
647    private int mNativeContext;
648}
649