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.graphics.ImageFormat;
20import android.graphics.Rect;
21import android.media.Image;
22import android.media.Image.Plane;
23import android.media.MediaCodecInfo;
24import android.media.MediaCodecList;
25import android.media.MediaCrypto;
26import android.media.MediaFormat;
27import android.os.Bundle;
28import android.os.Handler;
29import android.os.Looper;
30import android.os.Message;
31import android.view.Surface;
32
33import java.io.IOException;
34import java.nio.ByteBuffer;
35import java.nio.ReadOnlyBufferException;
36import java.util.Arrays;
37import java.util.HashMap;
38import java.util.Map;
39
40/**
41 * MediaCodec class can be used to access low-level media codec, i.e.
42 * encoder/decoder components.
43 *
44 * <p>MediaCodec is generally used like this:
45 * <pre>
46 * MediaCodec codec = MediaCodec.createDecoderByType(type);
47 * codec.configure(format, ...);
48 * codec.start();
49 *
50 * // if API level <= 20, get input and output buffer arrays here
51 * ByteBuffer[] inputBuffers = codec.getInputBuffers();
52 * ByteBuffer[] outputBuffers = codec.getOutputBuffers();
53 * for (;;) {
54 *   int inputBufferIndex = codec.dequeueInputBuffer(timeoutUs);
55 *   if (inputBufferIndex &gt;= 0) {
56 *     // if API level >= 21, get input buffer here
57 *     ByteBuffer inputBuffer = codec.getInputBuffer(inputBufferIndex);
58 *     // fill inputBuffers[inputBufferIndex] with valid data
59 *     ...
60 *     codec.queueInputBuffer(inputBufferIndex, ...);
61 *   }
62 *
63 *   int outputBufferIndex = codec.dequeueOutputBuffer(timeoutUs);
64 *   if (outputBufferIndex &gt;= 0) {
65 *     // if API level >= 21, get output buffer here
66 *     ByteBuffer outputBuffer = codec.getOutputBuffer(outputBufferIndex);
67 *     // outputBuffer is ready to be processed or rendered.
68 *     ...
69 *     codec.releaseOutputBuffer(outputBufferIndex, ...);
70 *   } else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
71 *     // no needed to handle if API level >= 21 and using getOutputBuffer(int)
72 *     outputBuffers = codec.getOutputBuffers();
73 *   } else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
74 *     // Subsequent data will conform to new format.
75 *     // can ignore if API level >= 21 and using getOutputFormat(outputBufferIndex)
76 *     MediaFormat format = codec.getOutputFormat();
77 *     ...
78 *   }
79 * }
80 * codec.stop();
81 * codec.release();
82 * codec = null;
83 * </pre>
84 *
85 * Each codec maintains a number of input and output buffers that are
86 * referred to by index in API calls.
87 * <p>
88 * For API levels 20 and below:
89 * The contents of these buffers are represented by the ByteBuffer[] arrays
90 * accessible through {@link #getInputBuffers} and {@link #getOutputBuffers}.
91 * <p>
92 * After a successful call to {@link #start} the client "owns" neither
93 * input nor output buffers, subsequent calls to {@link #dequeueInputBuffer}
94 * and {@link #dequeueOutputBuffer} then transfer ownership from the codec
95 * to the client.<p>
96 * The client is not required to resubmit/release buffers immediately
97 * to the codec, the sample code above simply does this for simplicity's sake.
98 * Nonetheless, it is possible that a codec may hold off on generating
99 * output buffers until all outstanding buffers have been
100 * released/resubmitted.
101 * <p>
102 * Once the client has an input buffer available it can fill it with data
103 * and submit it it to the codec via a call to {@link #queueInputBuffer}.
104 * Do not submit multiple input buffers with the same timestamp (unless
105 * it is codec-specific data marked as such using the flag
106 * {@link #BUFFER_FLAG_CODEC_CONFIG}).
107 * <p>
108 * The codec in turn will return an output buffer to the client in response
109 * to {@link #dequeueOutputBuffer}. After the output buffer has been processed
110 * a call to {@link #releaseOutputBuffer} will return it to the codec.
111 * If a video surface has been provided in the call to {@link #configure},
112 * {@link #releaseOutputBuffer} optionally allows rendering of the buffer
113 * to the surface.<p>
114 *
115 * Input buffers (for decoders) and Output buffers (for encoders) contain
116 * encoded data according to the format's type. For video types this data
117 * is all the encoded data representing a single moment in time, for audio
118 * data this is slightly relaxed in that a buffer may contain multiple
119 * encoded frames of audio. In either case, buffers do not start and end on
120 * arbitrary byte boundaries, this is not a stream of bytes, it's a stream
121 * of access units.<p>
122 *
123 * Most formats also require the actual data to be prefixed by a number
124 * of buffers containing setup data, or codec specific data, i.e. the
125 * first few buffers submitted to the codec object after starting it must
126 * be codec specific data marked as such using the flag {@link #BUFFER_FLAG_CODEC_CONFIG}
127 * in a call to {@link #queueInputBuffer}.
128 * <p>
129 * Codec specific data included in the format passed to {@link #configure}
130 * (in ByteBuffer entries with keys "csd-0", "csd-1", ...) is automatically
131 * submitted to the codec, this data MUST NOT be submitted explicitly by the
132 * client.
133 * <p>
134 * Once the client reaches the end of the input data it signals the end of
135 * the input stream by specifying a flag of {@link #BUFFER_FLAG_END_OF_STREAM} in the call to
136 * {@link #queueInputBuffer}. The codec will continue to return output buffers
137 * until it eventually signals the end of the output stream by specifying
138 * the same flag ({@link #BUFFER_FLAG_END_OF_STREAM}) on the BufferInfo returned in
139 * {@link #dequeueOutputBuffer}.  Do not submit additional input buffers after
140 * signaling the end of the input stream, unless the codec has been flushed,
141 * or stopped and restarted.
142 * <p>
143 * <h3>Seeking &amp; Adaptive Playback Support</h3>
144 *
145 * You can check if a decoder supports adaptive playback via {@link
146 * MediaCodecInfo.CodecCapabilities#isFeatureSupported}.  Adaptive playback
147 * is only supported if you configure the codec to decode onto a {@link
148 * android.view.Surface}.
149 *
150 * <h4>For decoders that do not support adaptive playback (including
151 * when not decoding onto a Surface)</h4>
152 *
153 * In order to start decoding data that's not adjacent to previously submitted
154 * data (i.e. after a seek) <em>one must</em> {@link #flush} the decoder.
155 * Any input or output buffers the client may own at the point of the flush are
156 * immediately revoked, i.e. after a call to {@link #flush} the client does not
157 * own any buffers anymore.
158 * <p>
159 * It is important that the input data after a flush starts at a suitable
160 * stream boundary.  The first frame must be able to be decoded completely on
161 * its own (for most codecs this means an I-frame), and that no frames should
162 * refer to frames before that first new frame.
163 * Note that the format of the data submitted after a flush must not change,
164 * flush does not support format discontinuities,
165 * for this a full {@link #stop}, {@link #configure configure()}, {@link #start}
166 * cycle is necessary.
167 *
168 * <h4>For decoders that support adaptive playback</h4>
169 *
170 * In order to start decoding data that's not adjacent to previously submitted
171 * data (i.e. after a seek) it is <em>not necessary</em> to {@link #flush} the
172 * decoder.
173 * <p>
174 * It is still important that the input data after the discontinuity starts
175 * at a suitable stream boundary (e.g. I-frame), and that no new frames refer
176 * to frames before the first frame of the new input data segment.
177 * <p>
178 * For some video formats it is also possible to change the picture size
179 * mid-stream.  To do this for H.264, the new Sequence Parameter Set (SPS) and
180 * Picture Parameter Set (PPS) values must be packaged together with an
181 * Instantaneous Decoder Refresh (IDR) frame in a single buffer, which then
182 * can be enqueued as a regular input buffer.
183 * The client will receive an {@link #INFO_OUTPUT_FORMAT_CHANGED} return
184 * value from {@link #dequeueOutputBuffer dequeueOutputBuffer()} or
185 * {@link Callback#onOutputBufferAvailable onOutputBufferAvailable()}
186 * just after the picture-size change takes place and before any
187 * frames with the new size have been returned.
188 * <p>
189 * Be careful when calling {@link #flush} shortly after you have changed
190 * the picture size.  If you have not received confirmation of the picture
191 * size change, you will need to repeat the request for the new picture size.
192 * E.g. for H.264 you will need to prepend the PPS/SPS to the new IDR
193 * frame to ensure that the codec receives the picture size change request.
194 *
195 * <h3>States and error handling</h3>
196 *
197 * <p> During its life, a codec conceptually exists in one of the following states:
198 * Initialized, Configured, Executing, Error, Uninitialized, (omitting transitory states
199 * between them). When created by one of the factory methods,
200 * the codec is in the Initialized state; {@link #configure} brings it to the
201 * Configured state; {@link #start} brings it to the Executing state.
202 * In the Executing state, decoding or encoding occurs through the buffer queue
203 * manipulation described above. The method {@link #stop}
204 * returns the codec to the Initialized state, whereupon it may be configured again,
205 * and {@link #release} brings the codec to the terminal Uninitialized state.  When
206 * a codec error occurs, the codec moves to the Error state.  Use {@link #reset} to
207 * bring the codec back to the Initialized state, or {@link #release} to move it
208 * to the Uninitialized state.
209 *
210 * <p> The factory methods
211 * {@link #createByCodecName},
212 * {@link #createDecoderByType},
213 * and {@link #createEncoderByType}
214 * throw {@link java.io.IOException} on failure which
215 * the caller must catch or declare to pass up.
216 * MediaCodec methods throw {@link java.lang.IllegalStateException}
217 * when the method is called from a codec state that does not allow it;
218 * this is typically due to incorrect application API usage.
219 * Methods involving secure buffers may throw
220 * {@link MediaCodec.CryptoException#MediaCodec.CryptoException}, which
221 * has further error information obtainable from {@link MediaCodec.CryptoException#getErrorCode}.
222 *
223 * <p> Internal codec errors result in a {@link MediaCodec.CodecException},
224 * which may be due to media content corruption, hardware failure, resource exhaustion,
225 * and so forth, even when the application is correctly using the API.
226 * The recommended action when receiving a {@link MediaCodec.CodecException} can be determined by
227 * calling {@link MediaCodec.CodecException#isRecoverable} and
228 * {@link MediaCodec.CodecException#isTransient}.
229 * If {@link MediaCodec.CodecException#isRecoverable} returns true,
230 * then a {@link #stop}, {@link #configure}, and {@link #start} can be performed to recover.
231 * If {@link MediaCodec.CodecException#isTransient} returns true,
232 * then resources are temporarily unavailable and the method may be retried at a later time.
233 * If both {@link MediaCodec.CodecException#isRecoverable}
234 * and {@link MediaCodec.CodecException#isTransient} return false,
235 * then the {@link MediaCodec.CodecException} is fatal and the codec must be
236 * {@link #reset reset} or {@link #release released}.
237 * Both {@link MediaCodec.CodecException#isRecoverable} and
238 * {@link MediaCodec.CodecException#isTransient} do not return true at the same time.
239 */
240final public class MediaCodec {
241    /**
242     * Per buffer metadata includes an offset and size specifying
243     * the range of valid data in the associated codec (output) buffer.
244     */
245    public final static class BufferInfo {
246        /**
247         * Update the buffer metadata information.
248         *
249         * @param newOffset the start-offset of the data in the buffer.
250         * @param newSize   the amount of data (in bytes) in the buffer.
251         * @param newTimeUs the presentation timestamp in microseconds.
252         * @param newFlags  buffer flags associated with the buffer.  This
253         * should be a combination of  {@link #BUFFER_FLAG_KEY_FRAME} and
254         * {@link #BUFFER_FLAG_END_OF_STREAM}.
255         */
256        public void set(
257                int newOffset, int newSize, long newTimeUs, int newFlags) {
258            offset = newOffset;
259            size = newSize;
260            presentationTimeUs = newTimeUs;
261            flags = newFlags;
262        }
263
264        /**
265         * The start-offset of the data in the buffer.
266         */
267        public int offset;
268
269        /**
270         * The amount of data (in bytes) in the buffer.  If this is {@code 0},
271         * the buffer has no data in it and can be discarded.  The only
272         * use of a 0-size buffer is to carry the end-of-stream marker.
273         */
274        public int size;
275
276        /**
277         * The presentation timestamp in microseconds for the buffer.
278         * This is derived from the presentation timestamp passed in
279         * with the corresponding input buffer.  This should be ignored for
280         * a 0-sized buffer.
281         */
282        public long presentationTimeUs;
283
284        /**
285         * Buffer flags associated with the buffer.  A combination of
286         * {@link #BUFFER_FLAG_KEY_FRAME} and {@link #BUFFER_FLAG_END_OF_STREAM}.
287         *
288         * <p>Encoded buffers that are key frames are marked with
289         * {@link #BUFFER_FLAG_KEY_FRAME}.
290         *
291         * <p>The last output buffer corresponding to the input buffer
292         * marked with {@link #BUFFER_FLAG_END_OF_STREAM} will also be marked
293         * with {@link #BUFFER_FLAG_END_OF_STREAM}. In some cases this could
294         * be an empty buffer, whose sole purpose is to carry the end-of-stream
295         * marker.
296         */
297        public int flags;
298    };
299
300    // The follow flag constants MUST stay in sync with their equivalents
301    // in MediaCodec.h !
302
303    /**
304     * This indicates that the (encoded) buffer marked as such contains
305     * the data for a key frame.
306     *
307     * @deprecated Use {@link #BUFFER_FLAG_KEY_FRAME} instead.
308     */
309    public static final int BUFFER_FLAG_SYNC_FRAME = 1;
310
311    /**
312     * This indicates that the (encoded) buffer marked as such contains
313     * the data for a key frame.
314     */
315    public static final int BUFFER_FLAG_KEY_FRAME = 1;
316
317    /**
318     * This indicated that the buffer marked as such contains codec
319     * initialization / codec specific data instead of media data.
320     */
321    public static final int BUFFER_FLAG_CODEC_CONFIG = 2;
322
323    /**
324     * This signals the end of stream, i.e. no buffers will be available
325     * after this, unless of course, {@link #flush} follows.
326     */
327    public static final int BUFFER_FLAG_END_OF_STREAM = 4;
328
329    private EventHandler mEventHandler;
330    private Callback mCallback;
331
332    private static final int EVENT_CALLBACK = 1;
333    private static final int EVENT_SET_CALLBACK = 2;
334
335    private static final int CB_INPUT_AVAILABLE = 1;
336    private static final int CB_OUTPUT_AVAILABLE = 2;
337    private static final int CB_ERROR = 3;
338    private static final int CB_OUTPUT_FORMAT_CHANGE = 4;
339
340    private class EventHandler extends Handler {
341        private MediaCodec mCodec;
342
343        public EventHandler(MediaCodec codec, Looper looper) {
344            super(looper);
345            mCodec = codec;
346        }
347
348        @Override
349        public void handleMessage(Message msg) {
350            switch (msg.what) {
351                case EVENT_CALLBACK:
352                {
353                    handleCallback(msg);
354                    break;
355                }
356                case EVENT_SET_CALLBACK:
357                {
358                    mCallback = (MediaCodec.Callback) msg.obj;
359                    break;
360                }
361                default:
362                {
363                    break;
364                }
365            }
366        }
367
368        private void handleCallback(Message msg) {
369            if (mCallback == null) {
370                return;
371            }
372
373            switch (msg.arg1) {
374                case CB_INPUT_AVAILABLE:
375                {
376                    int index = msg.arg2;
377                    synchronized(mBufferLock) {
378                        validateInputByteBuffer(mCachedInputBuffers, index);
379                    }
380                    mCallback.onInputBufferAvailable(mCodec, index);
381                    break;
382                }
383
384                case CB_OUTPUT_AVAILABLE:
385                {
386                    int index = msg.arg2;
387                    BufferInfo info = (MediaCodec.BufferInfo) msg.obj;
388                    synchronized(mBufferLock) {
389                        validateOutputByteBuffer(mCachedOutputBuffers, index, info);
390                    }
391                    mCallback.onOutputBufferAvailable(
392                            mCodec, index, info);
393                    break;
394                }
395
396                case CB_ERROR:
397                {
398                    mCallback.onError(mCodec, (MediaCodec.CodecException) msg.obj);
399                    break;
400                }
401
402                case CB_OUTPUT_FORMAT_CHANGE:
403                {
404                    mCallback.onOutputFormatChanged(mCodec,
405                            new MediaFormat((Map<String, Object>) msg.obj));
406                    break;
407                }
408
409                default:
410                {
411                    break;
412                }
413            }
414        }
415    }
416
417    /**
418     * Instantiate a decoder supporting input data of the given mime type.
419     *
420     * The following is a partial list of defined mime types and their semantics:
421     * <ul>
422     * <li>"video/x-vnd.on2.vp8" - VP8 video (i.e. video in .webm)
423     * <li>"video/x-vnd.on2.vp9" - VP9 video (i.e. video in .webm)
424     * <li>"video/avc" - H.264/AVC video
425     * <li>"video/hevc" - H.265/HEVC video
426     * <li>"video/mp4v-es" - MPEG4 video
427     * <li>"video/3gpp" - H.263 video
428     * <li>"audio/3gpp" - AMR narrowband audio
429     * <li>"audio/amr-wb" - AMR wideband audio
430     * <li>"audio/mpeg" - MPEG1/2 audio layer III
431     * <li>"audio/mp4a-latm" - AAC audio (note, this is raw AAC packets, not packaged in LATM!)
432     * <li>"audio/vorbis" - vorbis audio
433     * <li>"audio/g711-alaw" - G.711 alaw audio
434     * <li>"audio/g711-mlaw" - G.711 ulaw audio
435     * </ul>
436     *
437     * @param type The mime type of the input data.
438     * @throws IOException if the codec cannot be created.
439     * @throws IllegalArgumentException if type is not a valid mime type.
440     * @throws NullPointerException if type is null.
441     */
442    public static MediaCodec createDecoderByType(String type)
443            throws IOException {
444        return new MediaCodec(type, true /* nameIsType */, false /* encoder */);
445    }
446
447    /**
448     * Instantiate an encoder supporting output data of the given mime type.
449     * @param type The desired mime type of the output data.
450     * @throws IOException if the codec cannot be created.
451     * @throws IllegalArgumentException if type is not a valid mime type.
452     * @throws NullPointerException if type is null.
453     */
454    public static MediaCodec createEncoderByType(String type)
455            throws IOException {
456        return new MediaCodec(type, true /* nameIsType */, true /* encoder */);
457    }
458
459    /**
460     * If you know the exact name of the component you want to instantiate
461     * use this method to instantiate it. Use with caution.
462     * Likely to be used with information obtained from {@link android.media.MediaCodecList}
463     * @param name The name of the codec to be instantiated.
464     * @throws IOException if the codec cannot be created.
465     * @throws IllegalArgumentException if name is not valid.
466     * @throws NullPointerException if name is null.
467     */
468    public static MediaCodec createByCodecName(String name)
469            throws IOException {
470        return new MediaCodec(
471                name, false /* nameIsType */, false /* unused */);
472    }
473
474    private MediaCodec(
475            String name, boolean nameIsType, boolean encoder) {
476        Looper looper;
477        if ((looper = Looper.myLooper()) != null) {
478            mEventHandler = new EventHandler(this, looper);
479        } else if ((looper = Looper.getMainLooper()) != null) {
480            mEventHandler = new EventHandler(this, looper);
481        } else {
482            mEventHandler = null;
483        }
484        mBufferLock = new Object();
485
486        native_setup(name, nameIsType, encoder);
487    }
488
489    @Override
490    protected void finalize() {
491        native_finalize();
492    }
493
494    /**
495     * Returns the codec to its initial (Initialized) state.
496     *
497     * Call this if an {@link MediaCodec.CodecException#isRecoverable unrecoverable}
498     * error has occured to reset the codec to its initial state after creation.
499     *
500     * @throws CodecException if an unrecoverable error has occured and the codec
501     * could not be reset.
502     * @throws IllegalStateException if in the Uninitialized state.
503     */
504    public final void reset() {
505        freeAllTrackedBuffers(); // free buffers first
506        native_reset();
507    }
508
509    private native final void native_reset();
510
511    /**
512     * Make sure you call this when you're done to free up any opened
513     * component instance instead of relying on the garbage collector
514     * to do this for you at some point in the future.
515     */
516    public final void release() {
517        freeAllTrackedBuffers(); // free buffers first
518        native_release();
519    }
520
521    private native final void native_release();
522
523    /**
524     * If this codec is to be used as an encoder, pass this flag.
525     */
526    public static final int CONFIGURE_FLAG_ENCODE = 1;
527
528    /**
529     * Configures a component.
530     *
531     * @param format The format of the input data (decoder) or the desired
532     *               format of the output data (encoder).
533     * @param surface Specify a surface on which to render the output of this
534     *                decoder.
535     * @param crypto  Specify a crypto object to facilitate secure decryption
536     *                of the media data.
537     * @param flags   Specify {@link #CONFIGURE_FLAG_ENCODE} to configure the
538     *                component as an encoder.
539     * @throws IllegalArgumentException if the surface has been released (or is invalid),
540     * or the format is unacceptable (e.g. missing a mandatory key),
541     * or the flags are not set properly
542     * (e.g. missing {@link #CONFIGURE_FLAG_ENCODE} for an encoder).
543     * @throws IllegalStateException if not in the Initialized state.
544     */
545    public void configure(
546            MediaFormat format,
547            Surface surface, MediaCrypto crypto, int flags) {
548        Map<String, Object> formatMap = format.getMap();
549
550        String[] keys = null;
551        Object[] values = null;
552
553        if (format != null) {
554            keys = new String[formatMap.size()];
555            values = new Object[formatMap.size()];
556
557            int i = 0;
558            for (Map.Entry<String, Object> entry: formatMap.entrySet()) {
559                if (entry.getKey().equals(MediaFormat.KEY_AUDIO_SESSION_ID)) {
560                    int sessionId = 0;
561                    try {
562                        sessionId = (Integer)entry.getValue();
563                    }
564                    catch (Exception e) {
565                        throw new IllegalArgumentException("Wrong Session ID Parameter!");
566                    }
567                    keys[i] = "audio-hw-sync";
568                    values[i] = AudioSystem.getAudioHwSyncForSession(sessionId);
569                } else {
570                    keys[i] = entry.getKey();
571                    values[i] = entry.getValue();
572                }
573                ++i;
574            }
575        }
576
577        native_configure(keys, values, surface, crypto, flags);
578    }
579
580    private native final void native_setCallback(Callback cb);
581
582    private native final void native_configure(
583            String[] keys, Object[] values,
584            Surface surface, MediaCrypto crypto, int flags);
585
586    /**
587     * Requests a Surface to use as the input to an encoder, in place of input buffers.  This
588     * may only be called after {@link #configure} and before {@link #start}.
589     * <p>
590     * The application is responsible for calling release() on the Surface when
591     * done.
592     * <p>
593     * The Surface must be rendered with a hardware-accelerated API, such as OpenGL ES.
594     * {@link android.view.Surface#lockCanvas(android.graphics.Rect)} may fail or produce
595     * unexpected results.
596     * @throws IllegalStateException if not in the Configured state.
597     */
598    public native final Surface createInputSurface();
599
600    /**
601     * After successfully configuring the component, call {@code start}.
602     * <p>
603     * Call {@code start} also if the codec is configured in asynchronous mode,
604     * and it has just been flushed, to resume requesting input buffers.
605     * @throws IllegalStateException if not in the Configured state
606     *         or just after {@link #flush} for a codec that is configured
607     *         in asynchronous mode.
608     * @throws MediaCodec.CodecException upon codec error. Note that some codec errors
609     * for start may be attributed to future method calls.
610     */
611    public final void start() {
612        native_start();
613        synchronized(mBufferLock) {
614            cacheBuffers(true /* input */);
615            cacheBuffers(false /* input */);
616        }
617    }
618    private native final void native_start();
619
620    /**
621     * Finish the decode/encode session, note that the codec instance
622     * remains active and ready to be {@link #start}ed again.
623     * To ensure that it is available to other client call {@link #release}
624     * and don't just rely on garbage collection to eventually do this for you.
625     * @throws IllegalStateException if in the Uninitialized state.
626     */
627    public final void stop() {
628        native_stop();
629        freeAllTrackedBuffers();
630
631        if (mEventHandler != null) {
632            mEventHandler.removeMessages(EVENT_CALLBACK);
633            mEventHandler.removeMessages(EVENT_SET_CALLBACK);
634        }
635    }
636
637    private native final void native_stop();
638
639    /**
640     * Flush both input and output ports of the component, all indices
641     * previously returned in calls to {@link #dequeueInputBuffer} and
642     * {@link #dequeueOutputBuffer} become invalid.
643     * <p>
644     * If codec is configured in asynchronous mode, call {@link #start}
645     * after {@code flush} has returned to resume codec operations. The
646     * codec will not request input buffers until this has happened.
647     * <p>
648     * If codec is configured in synchronous mode, codec will resume
649     * automatically if an input surface was created.  Otherwise, it
650     * will resume when {@link #dequeueInputBuffer} is called.
651     *
652     * @throws IllegalStateException if not in the Executing state.
653     * @throws MediaCodec.CodecException upon codec error.
654     */
655    public final void flush() {
656        synchronized(mBufferLock) {
657            invalidateByteBuffers(mCachedInputBuffers);
658            invalidateByteBuffers(mCachedOutputBuffers);
659            mDequeuedInputBuffers.clear();
660            mDequeuedOutputBuffers.clear();
661        }
662        native_flush();
663    }
664
665    private native final void native_flush();
666
667    /**
668     * Thrown when an internal codec error occurs.
669     */
670    public final static class CodecException extends IllegalStateException {
671        CodecException(int errorCode, int actionCode, String detailMessage) {
672            super(detailMessage);
673            mErrorCode = errorCode;
674            mActionCode = actionCode;
675
676            // TODO get this from codec
677            final String sign = errorCode < 0 ? "neg_" : "";
678            mDiagnosticInfo =
679                "android.media.MediaCodec.error_" + sign + Math.abs(errorCode);
680        }
681
682        /**
683         * Returns true if the codec exception is a transient issue,
684         * perhaps due to resource constraints, and that the method
685         * (or encoding/decoding) may be retried at a later time.
686         */
687        public boolean isTransient() {
688            return mActionCode == ACTION_TRANSIENT;
689        }
690
691        /**
692         * Returns true if the codec cannot proceed further,
693         * but can be recovered by stopping, configuring,
694         * and starting again.
695         */
696        public boolean isRecoverable() {
697            return mActionCode == ACTION_RECOVERABLE;
698        }
699
700        /**
701         * Retrieve the error code associated with a CodecException.
702         * This is opaque diagnostic information and may depend on
703         * hardware or API level.
704         *
705         * @hide
706         */
707        public int getErrorCode() {
708            return mErrorCode;
709        }
710
711        /**
712         * Retrieve a developer-readable diagnostic information string
713         * associated with the exception. Do not show this to end-users,
714         * since this string will not be localized or generally
715         * comprehensible to end-users.
716         */
717        public String getDiagnosticInfo() {
718            return mDiagnosticInfo;
719        }
720
721        /* Must be in sync with android_media_MediaCodec.cpp */
722        private final static int ACTION_TRANSIENT = 1;
723        private final static int ACTION_RECOVERABLE = 2;
724
725        private final String mDiagnosticInfo;
726        private final int mErrorCode;
727        private final int mActionCode;
728    }
729
730    /**
731     * Thrown when a crypto error occurs while queueing a secure input buffer.
732     */
733    public final static class CryptoException extends RuntimeException {
734        public CryptoException(int errorCode, String detailMessage) {
735            super(detailMessage);
736            mErrorCode = errorCode;
737        }
738
739        /**
740         * This indicates that no key has been set to perform the requested
741         * decrypt operation.  The operation can be retried after adding
742         * a decryption key.
743         */
744        public static final int ERROR_NO_KEY = 1;
745
746        /**
747         * This indicates that the key used for decryption is no longer
748         * valid due to license term expiration.  The operation can be retried
749         * after updating the expired keys.
750         */
751        public static final int ERROR_KEY_EXPIRED = 2;
752
753        /**
754         * This indicates that a required crypto resource was not able to be
755         * allocated while attempting the requested operation.  The operation
756         * can be retried if the app is able to release resources.
757         */
758        public static final int ERROR_RESOURCE_BUSY = 3;
759
760        /**
761         * This indicates that the output protection levels supported by the
762         * device are not sufficient to meet the requirements set by the
763         * content owner in the license policy.
764         */
765        public static final int ERROR_INSUFFICIENT_OUTPUT_PROTECTION = 4;
766
767        /**
768         * Retrieve the error code associated with a CryptoException
769         */
770        public int getErrorCode() {
771            return mErrorCode;
772        }
773
774        private int mErrorCode;
775    }
776
777    /**
778     * After filling a range of the input buffer at the specified index
779     * submit it to the component. Once an input buffer is queued to
780     * the codec, it MUST NOT be used until it is later retrieved by
781     * {@link #getInputBuffer} in response to a {@link #dequeueInputBuffer}
782     * return value or a {@link Callback#onInputBufferAvailable}
783     * callback.
784     * <p>
785     * Many decoders require the actual compressed data stream to be
786     * preceded by "codec specific data", i.e. setup data used to initialize
787     * the codec such as PPS/SPS in the case of AVC video or code tables
788     * in the case of vorbis audio.
789     * The class {@link android.media.MediaExtractor} provides codec
790     * specific data as part of
791     * the returned track format in entries named "csd-0", "csd-1" ...
792     * <p>
793     * These buffers can be submitted directly after {@link #start} or
794     * {@link #flush} by specifying the flag {@link
795     * #BUFFER_FLAG_CODEC_CONFIG}.  However, if you configure the
796     * codec with a {@link MediaFormat} containing these keys, they
797     * will be automatically submitted by MediaCodec directly after
798     * start.  Therefore, the use of {@link
799     * #BUFFER_FLAG_CODEC_CONFIG} flag is discouraged and is
800     * recommended only for advanced users.
801     * <p>
802     * To indicate that this is the final piece of input data (or rather that
803     * no more input data follows unless the decoder is subsequently flushed)
804     * specify the flag {@link #BUFFER_FLAG_END_OF_STREAM}.
805     *
806     * @param index The index of a client-owned input buffer previously returned
807     *              in a call to {@link #dequeueInputBuffer}.
808     * @param offset The byte offset into the input buffer at which the data starts.
809     * @param size The number of bytes of valid input data.
810     * @param presentationTimeUs The presentation timestamp in microseconds for this
811     *                           buffer. This is normally the media time at which this
812     *                           buffer should be presented (rendered).
813     * @param flags A bitmask of flags
814     *              {@link #BUFFER_FLAG_CODEC_CONFIG} and {@link #BUFFER_FLAG_END_OF_STREAM}.
815     *              While not prohibited, most codecs do not use the
816     *              {@link #BUFFER_FLAG_KEY_FRAME} flag for input buffers.
817     * @throws IllegalStateException if not in the Executing state.
818     * @throws MediaCodec.CodecException upon codec error.
819     * @throws CryptoException if a crypto object has been specified in
820     *         {@link #configure}
821     */
822    public final void queueInputBuffer(
823            int index,
824            int offset, int size, long presentationTimeUs, int flags)
825        throws CryptoException {
826        synchronized(mBufferLock) {
827            invalidateByteBuffer(mCachedInputBuffers, index);
828            mDequeuedInputBuffers.remove(index);
829        }
830        try {
831            native_queueInputBuffer(
832                    index, offset, size, presentationTimeUs, flags);
833        } catch (CryptoException | IllegalStateException e) {
834            revalidateByteBuffer(mCachedInputBuffers, index);
835            throw e;
836        }
837    }
838
839    private native final void native_queueInputBuffer(
840            int index,
841            int offset, int size, long presentationTimeUs, int flags)
842        throws CryptoException;
843
844    // The following mode constants MUST stay in sync with their equivalents
845    // in media/hardware/CryptoAPI.h !
846    public static final int CRYPTO_MODE_UNENCRYPTED = 0;
847    public static final int CRYPTO_MODE_AES_CTR     = 1;
848
849    /**
850     * Metadata describing the structure of a (at least partially) encrypted
851     * input sample.
852     * A buffer's data is considered to be partitioned into "subSamples",
853     * each subSample starts with a (potentially empty) run of plain,
854     * unencrypted bytes followed by a (also potentially empty) run of
855     * encrypted bytes.
856     * numBytesOfClearData can be null to indicate that all data is encrypted.
857     * This information encapsulates per-sample metadata as outlined in
858     * ISO/IEC FDIS 23001-7:2011 "Common encryption in ISO base media file format files".
859     */
860    public final static class CryptoInfo {
861        public void set(
862                int newNumSubSamples,
863                int[] newNumBytesOfClearData,
864                int[] newNumBytesOfEncryptedData,
865                byte[] newKey,
866                byte[] newIV,
867                int newMode) {
868            numSubSamples = newNumSubSamples;
869            numBytesOfClearData = newNumBytesOfClearData;
870            numBytesOfEncryptedData = newNumBytesOfEncryptedData;
871            key = newKey;
872            iv = newIV;
873            mode = newMode;
874        }
875
876        /**
877         * The number of subSamples that make up the buffer's contents.
878         */
879        public int numSubSamples;
880        /**
881         * The number of leading unencrypted bytes in each subSample.
882         */
883        public int[] numBytesOfClearData;
884        /**
885         * The number of trailing encrypted bytes in each subSample.
886         */
887        public int[] numBytesOfEncryptedData;
888        /**
889         * A 16-byte opaque key
890         */
891        public byte[] key;
892        /**
893         * A 16-byte initialization vector
894         */
895        public byte[] iv;
896        /**
897         * The type of encryption that has been applied,
898         * see {@link #CRYPTO_MODE_UNENCRYPTED} and {@link #CRYPTO_MODE_AES_CTR}.
899         */
900        public int mode;
901
902        @Override
903        public String toString() {
904            StringBuilder builder = new StringBuilder();
905            builder.append(numSubSamples + " subsamples, key [");
906            String hexdigits = "0123456789abcdef";
907            for (int i = 0; i < key.length; i++) {
908                builder.append(hexdigits.charAt((key[i] & 0xf0) >> 4));
909                builder.append(hexdigits.charAt(key[i] & 0x0f));
910            }
911            builder.append("], iv [");
912            for (int i = 0; i < key.length; i++) {
913                builder.append(hexdigits.charAt((iv[i] & 0xf0) >> 4));
914                builder.append(hexdigits.charAt(iv[i] & 0x0f));
915            }
916            builder.append("], clear ");
917            builder.append(Arrays.toString(numBytesOfClearData));
918            builder.append(", encrypted ");
919            builder.append(Arrays.toString(numBytesOfEncryptedData));
920            return builder.toString();
921        }
922    };
923
924    /**
925     * Similar to {@link #queueInputBuffer} but submits a buffer that is
926     * potentially encrypted.
927     * @param index The index of a client-owned input buffer previously returned
928     *              in a call to {@link #dequeueInputBuffer}.
929     * @param offset The byte offset into the input buffer at which the data starts.
930     * @param info Metadata required to facilitate decryption, the object can be
931     *             reused immediately after this call returns.
932     * @param presentationTimeUs The presentation timestamp in microseconds for this
933     *                           buffer. This is normally the media time at which this
934     *                           buffer should be presented (rendered).
935     * @param flags A bitmask of flags
936     *              {@link #BUFFER_FLAG_CODEC_CONFIG} and {@link #BUFFER_FLAG_END_OF_STREAM}.
937     *              While not prohibited, most codecs do not use the
938     *              {@link #BUFFER_FLAG_KEY_FRAME} flag for input buffers.
939     * @throws IllegalStateException if not in the Executing state.
940     * @throws MediaCodec.CodecException upon codec error.
941     * @throws CryptoException if an error occurs while attempting to decrypt the buffer.
942     *              An error code associated with the exception helps identify the
943     *              reason for the failure.
944     */
945    public final void queueSecureInputBuffer(
946            int index,
947            int offset,
948            CryptoInfo info,
949            long presentationTimeUs,
950            int flags) throws CryptoException {
951        synchronized(mBufferLock) {
952            invalidateByteBuffer(mCachedInputBuffers, index);
953            mDequeuedInputBuffers.remove(index);
954        }
955        try {
956            native_queueSecureInputBuffer(
957                    index, offset, info, presentationTimeUs, flags);
958        } catch (CryptoException | IllegalStateException e) {
959            revalidateByteBuffer(mCachedInputBuffers, index);
960            throw e;
961        }
962    }
963
964    private native final void native_queueSecureInputBuffer(
965            int index,
966            int offset,
967            CryptoInfo info,
968            long presentationTimeUs,
969            int flags) throws CryptoException;
970
971    /**
972     * Returns the index of an input buffer to be filled with valid data
973     * or -1 if no such buffer is currently available.
974     * This method will return immediately if timeoutUs == 0, wait indefinitely
975     * for the availability of an input buffer if timeoutUs &lt; 0 or wait up
976     * to "timeoutUs" microseconds if timeoutUs &gt; 0.
977     * @param timeoutUs The timeout in microseconds, a negative timeout indicates "infinite".
978     * @throws IllegalStateException if not in the Executing state,
979     *         or codec is configured in asynchronous mode.
980     * @throws MediaCodec.CodecException upon codec error.
981     */
982    public final int dequeueInputBuffer(long timeoutUs) {
983        int res = native_dequeueInputBuffer(timeoutUs);
984        if (res >= 0) {
985            synchronized(mBufferLock) {
986                validateInputByteBuffer(mCachedInputBuffers, res);
987            }
988        }
989        return res;
990    }
991
992    private native final int native_dequeueInputBuffer(long timeoutUs);
993
994    /**
995     * If a non-negative timeout had been specified in the call
996     * to {@link #dequeueOutputBuffer}, indicates that the call timed out.
997     */
998    public static final int INFO_TRY_AGAIN_LATER        = -1;
999
1000    /**
1001     * The output format has changed, subsequent data will follow the new
1002     * format. {@link #getOutputFormat()} returns the new format.  Note, that
1003     * you can also use the new {@link #getOutputFormat(int)} method to
1004     * get the format for a specific output buffer.  This frees you from
1005     * having to track output format changes.
1006     */
1007    public static final int INFO_OUTPUT_FORMAT_CHANGED  = -2;
1008
1009    /**
1010     * The output buffers have changed, the client must refer to the new
1011     * set of output buffers returned by {@link #getOutputBuffers} from
1012     * this point on.
1013     *
1014     * @deprecated This return value can be ignored as {@link
1015     * #getOutputBuffers} has been deprecated.  Client should
1016     * request a current buffer using on of the get-buffer or
1017     * get-image methods each time one has been dequeued.
1018     */
1019    public static final int INFO_OUTPUT_BUFFERS_CHANGED = -3;
1020
1021    /**
1022     * Dequeue an output buffer, block at most "timeoutUs" microseconds.
1023     * Returns the index of an output buffer that has been successfully
1024     * decoded or one of the INFO_* constants below.
1025     * @param info Will be filled with buffer meta data.
1026     * @param timeoutUs The timeout in microseconds, a negative timeout indicates "infinite".
1027     * @throws IllegalStateException if not in the Executing state,
1028     *         or codec is configured in asynchronous mode.
1029     * @throws MediaCodec.CodecException upon codec error.
1030     */
1031    public final int dequeueOutputBuffer(
1032            BufferInfo info, long timeoutUs) {
1033        int res = native_dequeueOutputBuffer(info, timeoutUs);
1034        synchronized(mBufferLock) {
1035            if (res == INFO_OUTPUT_BUFFERS_CHANGED) {
1036                cacheBuffers(false /* input */);
1037            } else if (res >= 0) {
1038                validateOutputByteBuffer(mCachedOutputBuffers, res, info);
1039            }
1040        }
1041        return res;
1042    }
1043
1044    private native final int native_dequeueOutputBuffer(
1045            BufferInfo info, long timeoutUs);
1046
1047    /**
1048     * If you are done with a buffer, use this call to return the buffer to
1049     * the codec. If you previously specified a surface when configuring this
1050     * video decoder you can optionally render the buffer.
1051     *
1052     * Once an output buffer is released to the codec, it MUST NOT
1053     * be used until it is later retrieved by {@link #getOutputBuffer} in response
1054     * to a {@link #dequeueOutputBuffer} return value or a
1055     * {@link Callback#onOutputBufferAvailable} callback.
1056     *
1057     * @param index The index of a client-owned output buffer previously returned
1058     *              from a call to {@link #dequeueOutputBuffer}.
1059     * @param render If a valid surface was specified when configuring the codec,
1060     *               passing true renders this output buffer to the surface.
1061     * @throws IllegalStateException if not in the Executing state.
1062     * @throws MediaCodec.CodecException upon codec error.
1063     */
1064    public final void releaseOutputBuffer(int index, boolean render) {
1065        synchronized(mBufferLock) {
1066            invalidateByteBuffer(mCachedOutputBuffers, index);
1067            mDequeuedOutputBuffers.remove(index);
1068        }
1069        releaseOutputBuffer(index, render, false /* updatePTS */, 0 /* dummy */);
1070    }
1071
1072    /**
1073     * If you are done with a buffer, use this call to update its surface timestamp
1074     * and return it to the codec to render it on the output surface. If you
1075     * have not specified an output surface when configuring this video codec,
1076     * this call will simply return the buffer to the codec.<p>
1077     *
1078     * The timestamp may have special meaning depending on the destination surface.
1079     *
1080     * <table>
1081     * <tr><th>SurfaceView specifics</th></tr>
1082     * <tr><td>
1083     * If you render your buffer on a {@link android.view.SurfaceView},
1084     * you can use the timestamp to render the buffer at a specific time (at the
1085     * VSYNC at or after the buffer timestamp).  For this to work, the timestamp
1086     * needs to be <i>reasonably close</i> to the current {@link System#nanoTime}.
1087     * Currently, this is set as within one (1) second. A few notes:
1088     *
1089     * <ul>
1090     * <li>the buffer will not be returned to the codec until the timestamp
1091     * has passed and the buffer is no longer used by the {@link android.view.Surface}.
1092     * <li>buffers are processed sequentially, so you may block subsequent buffers to
1093     * be displayed on the {@link android.view.Surface}.  This is important if you
1094     * want to react to user action, e.g. stop the video or seek.
1095     * <li>if multiple buffers are sent to the {@link android.view.Surface} to be
1096     * rendered at the same VSYNC, the last one will be shown, and the other ones
1097     * will be dropped.
1098     * <li>if the timestamp is <em>not</em> "reasonably close" to the current system
1099     * time, the {@link android.view.Surface} will ignore the timestamp, and
1100     * display the buffer at the earliest feasible time.  In this mode it will not
1101     * drop frames.
1102     * <li>for best performance and quality, call this method when you are about
1103     * two VSYNCs' time before the desired render time.  For 60Hz displays, this is
1104     * about 33 msec.
1105     * </ul>
1106     * </td></tr>
1107     * </table>
1108     *
1109     * Once an output buffer is released to the codec, it MUST NOT
1110     * be used until it is later retrieved by {@link #getOutputBuffer} in response
1111     * to a {@link #dequeueOutputBuffer} return value or a
1112     * {@link Callback#onOutputBufferAvailable} callback.
1113     *
1114     * @param index The index of a client-owned output buffer previously returned
1115     *              from a call to {@link #dequeueOutputBuffer}.
1116     * @param renderTimestampNs The timestamp to associate with this buffer when
1117     *              it is sent to the Surface.
1118     * @throws IllegalStateException if not in the Executing state.
1119     * @throws MediaCodec.CodecException upon codec error.
1120     */
1121    public final void releaseOutputBuffer(int index, long renderTimestampNs) {
1122        synchronized(mBufferLock) {
1123            invalidateByteBuffer(mCachedOutputBuffers, index);
1124            mDequeuedOutputBuffers.remove(index);
1125        }
1126        releaseOutputBuffer(
1127                index, true /* render */, true /* updatePTS */, renderTimestampNs);
1128    }
1129
1130    private native final void releaseOutputBuffer(
1131            int index, boolean render, boolean updatePTS, long timeNs);
1132
1133    /**
1134     * Signals end-of-stream on input.  Equivalent to submitting an empty buffer with
1135     * {@link #BUFFER_FLAG_END_OF_STREAM} set.  This may only be used with
1136     * encoders receiving input from a Surface created by {@link #createInputSurface}.
1137     * @throws IllegalStateException if not in the Executing state.
1138     * @throws MediaCodec.CodecException upon codec error.
1139     */
1140    public native final void signalEndOfInputStream();
1141
1142    /**
1143     * Call this after dequeueOutputBuffer signals a format change by returning
1144     * {@link #INFO_OUTPUT_FORMAT_CHANGED}.
1145     * You can also call this after {@link #configure} returns
1146     * successfully to get the output format initially configured
1147     * for the codec.  Do this to determine what optional
1148     * configuration parameters were supported by the codec.
1149     *
1150     * @throws IllegalStateException if not in the Executing or
1151     *                               Configured state.
1152     * @throws MediaCodec.CodecException upon codec error.
1153     */
1154    public final MediaFormat getOutputFormat() {
1155        return new MediaFormat(getFormatNative(false /* input */));
1156    }
1157
1158    /**
1159     * Call this after {@link #configure} returns successfully to
1160     * get the input format accepted by the codec. Do this to
1161     * determine what optional configuration parameters were
1162     * supported by the codec.
1163     *
1164     * @throws IllegalStateException if not in the Executing or
1165     *                               Configured state.
1166     * @throws MediaCodec.CodecException upon codec error.
1167     */
1168    public final MediaFormat getInputFormat() {
1169        return new MediaFormat(getFormatNative(true /* input */));
1170    }
1171
1172    /**
1173     * Returns the output format for a specific output buffer.
1174     *
1175     * @param index The index of a client-owned input buffer previously
1176     *              returned from a call to {@link #dequeueInputBuffer}.
1177     *
1178     * @return the format for the output buffer, or null if the index
1179     * is not a dequeued output buffer.
1180     */
1181    public final MediaFormat getOutputFormat(int index) {
1182        return new MediaFormat(getOutputFormatNative(index));
1183    }
1184
1185    private native final Map<String, Object> getFormatNative(boolean input);
1186
1187    private native final Map<String, Object> getOutputFormatNative(int index);
1188
1189    // used to track dequeued buffers
1190    private static class BufferMap {
1191        // various returned representations of the codec buffer
1192        private static class CodecBuffer {
1193            private Image mImage;
1194            private ByteBuffer mByteBuffer;
1195
1196            public void free() {
1197                if (mByteBuffer != null) {
1198                    // all of our ByteBuffers are direct
1199                    java.nio.NioUtils.freeDirectBuffer(mByteBuffer);
1200                    mByteBuffer = null;
1201                }
1202                if (mImage != null) {
1203                    mImage.close();
1204                    mImage = null;
1205                }
1206            }
1207
1208            public void setImage(Image image) {
1209                free();
1210                mImage = image;
1211            }
1212
1213            public void setByteBuffer(ByteBuffer buffer) {
1214                free();
1215                mByteBuffer = buffer;
1216            }
1217        }
1218
1219        private final Map<Integer, CodecBuffer> mMap =
1220            new HashMap<Integer, CodecBuffer>();
1221
1222        public void remove(int index) {
1223            CodecBuffer buffer = mMap.get(index);
1224            if (buffer != null) {
1225                buffer.free();
1226                mMap.remove(index);
1227            }
1228        }
1229
1230        public void put(int index, ByteBuffer newBuffer) {
1231            CodecBuffer buffer = mMap.get(index);
1232            if (buffer == null) { // likely
1233                buffer = new CodecBuffer();
1234                mMap.put(index, buffer);
1235            }
1236            buffer.setByteBuffer(newBuffer);
1237        }
1238
1239        public void put(int index, Image newImage) {
1240            CodecBuffer buffer = mMap.get(index);
1241            if (buffer == null) { // likely
1242                buffer = new CodecBuffer();
1243                mMap.put(index, buffer);
1244            }
1245            buffer.setImage(newImage);
1246        }
1247
1248        public void clear() {
1249            for (CodecBuffer buffer: mMap.values()) {
1250                buffer.free();
1251            }
1252            mMap.clear();
1253        }
1254    }
1255
1256    private ByteBuffer[] mCachedInputBuffers;
1257    private ByteBuffer[] mCachedOutputBuffers;
1258    private final BufferMap mDequeuedInputBuffers = new BufferMap();
1259    private final BufferMap mDequeuedOutputBuffers = new BufferMap();
1260    final private Object mBufferLock;
1261
1262    private final void invalidateByteBuffer(
1263            ByteBuffer[] buffers, int index) {
1264        if (buffers != null && index >= 0 && index < buffers.length) {
1265            ByteBuffer buffer = buffers[index];
1266            if (buffer != null) {
1267                buffer.setAccessible(false);
1268            }
1269        }
1270    }
1271
1272    private final void validateInputByteBuffer(
1273            ByteBuffer[] buffers, int index) {
1274        if (buffers != null && index >= 0 && index < buffers.length) {
1275            ByteBuffer buffer = buffers[index];
1276            if (buffer != null) {
1277                buffer.setAccessible(true);
1278                buffer.clear();
1279            }
1280        }
1281    }
1282
1283    private final void revalidateByteBuffer(
1284            ByteBuffer[] buffers, int index) {
1285        synchronized(mBufferLock) {
1286            if (buffers != null && index >= 0 && index < buffers.length) {
1287                ByteBuffer buffer = buffers[index];
1288                if (buffer != null) {
1289                    buffer.setAccessible(true);
1290                }
1291            }
1292        }
1293    }
1294
1295    private final void validateOutputByteBuffer(
1296            ByteBuffer[] buffers, int index, BufferInfo info) {
1297        if (buffers != null && index >= 0 && index < buffers.length) {
1298            ByteBuffer buffer = buffers[index];
1299            if (buffer != null) {
1300                buffer.setAccessible(true);
1301                buffer.limit(info.offset + info.size).position(info.offset);
1302            }
1303        }
1304    }
1305
1306    private final void invalidateByteBuffers(ByteBuffer[] buffers) {
1307        if (buffers != null) {
1308            for (ByteBuffer buffer: buffers) {
1309                if (buffer != null) {
1310                    buffer.setAccessible(false);
1311                }
1312            }
1313        }
1314    }
1315
1316    private final void freeByteBuffer(ByteBuffer buffer) {
1317        if (buffer != null /* && buffer.isDirect() */) {
1318            // all of our ByteBuffers are direct
1319            java.nio.NioUtils.freeDirectBuffer(buffer);
1320        }
1321    }
1322
1323    private final void freeByteBuffers(ByteBuffer[] buffers) {
1324        if (buffers != null) {
1325            for (ByteBuffer buffer: buffers) {
1326                freeByteBuffer(buffer);
1327            }
1328        }
1329    }
1330
1331    private final void freeAllTrackedBuffers() {
1332        synchronized(mBufferLock) {
1333            freeByteBuffers(mCachedInputBuffers);
1334            freeByteBuffers(mCachedOutputBuffers);
1335            mCachedInputBuffers = null;
1336            mCachedOutputBuffers = null;
1337            mDequeuedInputBuffers.clear();
1338            mDequeuedOutputBuffers.clear();
1339        }
1340    }
1341
1342    private final void cacheBuffers(boolean input) {
1343        ByteBuffer[] buffers = null;
1344        try {
1345            buffers = getBuffers(input);
1346            invalidateByteBuffers(buffers);
1347        } catch (IllegalStateException e) {
1348            // we don't get buffers in async mode
1349        }
1350        if (input) {
1351            mCachedInputBuffers = buffers;
1352        } else {
1353            mCachedOutputBuffers = buffers;
1354        }
1355    }
1356
1357    /**
1358     * Retrieve the set of input buffers.  Call this after start()
1359     * returns. After calling this method, any ByteBuffers
1360     * previously returned by an earlier call to this method MUST no
1361     * longer be used.
1362     *
1363     * @deprecated Use the new {@link #getInputBuffer} method instead
1364     * each time an input buffer is dequeued.
1365     *
1366     * <b>Note:</b>As of API 21, dequeued input buffers are
1367     * automatically {@link java.nio.Buffer#clear cleared}.
1368     *
1369     * @throws IllegalStateException if not in the Executing state,
1370     *         or codec is configured in asynchronous mode.
1371     * @throws MediaCodec.CodecException upon codec error.
1372     */
1373    public ByteBuffer[] getInputBuffers() {
1374        if (mCachedInputBuffers == null) {
1375            throw new IllegalStateException();
1376        }
1377        // FIXME: check codec status
1378        return mCachedInputBuffers;
1379    }
1380
1381    /**
1382     * Retrieve the set of output buffers.  Call this after start()
1383     * returns and whenever dequeueOutputBuffer signals an output
1384     * buffer change by returning {@link
1385     * #INFO_OUTPUT_BUFFERS_CHANGED}. After calling this method, any
1386     * ByteBuffers previously returned by an earlier call to this
1387     * method MUST no longer be used.
1388     *
1389     * @deprecated Use the new {@link #getOutputBuffer} method instead
1390     * each time an output buffer is dequeued.  This method is not
1391     * supported if codec is configured in asynchronous mode.
1392     *
1393     * <b>Note:</b>As of API 21, the position and limit of output
1394     * buffers that are dequeued will be set to the valid data
1395     * range.
1396     *
1397     * @throws IllegalStateException if not in the Executing state,
1398     *         or codec is configured in asynchronous mode.
1399     * @throws MediaCodec.CodecException upon codec error.
1400     */
1401    public ByteBuffer[] getOutputBuffers() {
1402        if (mCachedOutputBuffers == null) {
1403            throw new IllegalStateException();
1404        }
1405        // FIXME: check codec status
1406        return mCachedOutputBuffers;
1407    }
1408
1409    /**
1410     * Returns a {@link java.nio.Buffer#clear cleared}, writable ByteBuffer
1411     * object for a dequeued input buffer index to contain the input data.
1412     *
1413     * After calling this method any ByteBuffer or Image object
1414     * previously returned for the same input index MUST no longer
1415     * be used.
1416     *
1417     * @param index The index of a client-owned input buffer previously
1418     *              returned from a call to {@link #dequeueInputBuffer},
1419     *              or received via an onInputBufferAvailable callback.
1420     *
1421     * @return the input buffer, or null if the index is not a dequeued
1422     * input buffer, or if the codec is configured for surface input.
1423     *
1424     * @throws IllegalStateException if not in the Executing state.
1425     * @throws MediaCodec.CodecException upon codec error.
1426     */
1427    public ByteBuffer getInputBuffer(int index) {
1428        ByteBuffer newBuffer = getBuffer(true /* input */, index);
1429        synchronized(mBufferLock) {
1430            invalidateByteBuffer(mCachedInputBuffers, index);
1431            mDequeuedInputBuffers.put(index, newBuffer);
1432        }
1433        return newBuffer;
1434    }
1435
1436    /**
1437     * Returns a writable Image object for a dequeued input buffer
1438     * index to contain the raw input video frame.
1439     *
1440     * After calling this method any ByteBuffer or Image object
1441     * previously returned for the same input index MUST no longer
1442     * be used.
1443     *
1444     * @param index The index of a client-owned input buffer previously
1445     *              returned from a call to {@link #dequeueInputBuffer},
1446     *              or received via an onInputBufferAvailable callback.
1447     *
1448     * @return the input image, or null if the index is not a
1449     * dequeued input buffer, or not a ByteBuffer that contains a
1450     * raw image.
1451     *
1452     * @throws IllegalStateException if not in the Executing state.
1453     * @throws MediaCodec.CodecException upon codec error.
1454     */
1455    public Image getInputImage(int index) {
1456        Image newImage = getImage(true /* input */, index);
1457        synchronized(mBufferLock) {
1458            invalidateByteBuffer(mCachedInputBuffers, index);
1459            mDequeuedInputBuffers.put(index, newImage);
1460        }
1461        return newImage;
1462    }
1463
1464    /**
1465     * Returns a read-only ByteBuffer for a dequeued output buffer
1466     * index. The position and limit of the returned buffer are set
1467     * to the valid output data.
1468     *
1469     * After calling this method, any ByteBuffer or Image object
1470     * previously returned for the same output index MUST no longer
1471     * be used.
1472     *
1473     * @param index The index of a client-owned output buffer previously
1474     *              returned from a call to {@link #dequeueOutputBuffer},
1475     *              or received via an onOutputBufferAvailable callback.
1476     *
1477     * @return the output buffer, or null if the index is not a dequeued
1478     * output buffer, or the codec is configured with an output surface.
1479     *
1480     * @throws IllegalStateException if not in the Executing state.
1481     * @throws MediaCodec.CodecException upon codec error.
1482     */
1483    public ByteBuffer getOutputBuffer(int index) {
1484        ByteBuffer newBuffer = getBuffer(false /* input */, index);
1485        synchronized(mBufferLock) {
1486            invalidateByteBuffer(mCachedOutputBuffers, index);
1487            mDequeuedOutputBuffers.put(index, newBuffer);
1488        }
1489        return newBuffer;
1490    }
1491
1492    /**
1493     * Returns a read-only Image object for a dequeued output buffer
1494     * index that contains the raw video frame.
1495     *
1496     * After calling this method, any ByteBuffer or Image object previously
1497     * returned for the same output index MUST no longer be used.
1498     *
1499     * @param index The index of a client-owned output buffer previously
1500     *              returned from a call to {@link #dequeueOutputBuffer},
1501     *              or received via an onOutputBufferAvailable callback.
1502     *
1503     * @return the output image, or null if the index is not a
1504     * dequeued output buffer, not a raw video frame, or if the codec
1505     * was configured with an output surface.
1506     *
1507     * @throws IllegalStateException if not in the Executing state.
1508     * @throws MediaCodec.CodecException upon codec error.
1509     */
1510    public Image getOutputImage(int index) {
1511        Image newImage = getImage(false /* input */, index);
1512        synchronized(mBufferLock) {
1513            invalidateByteBuffer(mCachedOutputBuffers, index);
1514            mDequeuedOutputBuffers.put(index, newImage);
1515        }
1516        return newImage;
1517    }
1518
1519    /**
1520     * The content is scaled to the surface dimensions
1521     */
1522    public static final int VIDEO_SCALING_MODE_SCALE_TO_FIT               = 1;
1523
1524    /**
1525     * The content is scaled, maintaining its aspect ratio, the whole
1526     * surface area is used, content may be cropped
1527     */
1528    public static final int VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING = 2;
1529
1530    /**
1531     * If a surface has been specified in a previous call to {@link #configure}
1532     * specifies the scaling mode to use. The default is "scale to fit".
1533     * @throws IllegalArgumentException if mode is not recognized.
1534     * @throws IllegalStateException if in the Uninitialized state.
1535     */
1536    public native final void setVideoScalingMode(int mode);
1537
1538    /**
1539     * Get the component name. If the codec was created by createDecoderByType
1540     * or createEncoderByType, what component is chosen is not known beforehand.
1541     * @throws IllegalStateException if in the Uninitialized state.
1542     */
1543    public native final String getName();
1544
1545    /**
1546     * Change a video encoder's target bitrate on the fly. The value is an
1547     * Integer object containing the new bitrate in bps.
1548     */
1549    public static final String PARAMETER_KEY_VIDEO_BITRATE = "video-bitrate";
1550
1551    /**
1552     * Temporarily suspend/resume encoding of input data. While suspended
1553     * input data is effectively discarded instead of being fed into the
1554     * encoder. This parameter really only makes sense to use with an encoder
1555     * in "surface-input" mode, as the client code has no control over the
1556     * input-side of the encoder in that case.
1557     * The value is an Integer object containing the value 1 to suspend
1558     * or the value 0 to resume.
1559     */
1560    public static final String PARAMETER_KEY_SUSPEND = "drop-input-frames";
1561
1562    /**
1563     * Request that the encoder produce a sync frame "soon".
1564     * Provide an Integer with the value 0.
1565     */
1566    public static final String PARAMETER_KEY_REQUEST_SYNC_FRAME = "request-sync";
1567
1568    /**
1569     * Communicate additional parameter changes to the component instance.
1570     * @throws IllegalStateException if in the Uninitialized state.
1571     */
1572    public final void setParameters(Bundle params) {
1573        if (params == null) {
1574            return;
1575        }
1576
1577        String[] keys = new String[params.size()];
1578        Object[] values = new Object[params.size()];
1579
1580        int i = 0;
1581        for (final String key: params.keySet()) {
1582            keys[i] = key;
1583            values[i] = params.get(key);
1584            ++i;
1585        }
1586
1587        setParameters(keys, values);
1588    }
1589
1590    /**
1591     * Sets an asynchronous callback for actionable MediaCodec events.
1592     *
1593     * If the client intends to use the component in asynchronous mode,
1594     * a valid callback should be provided before {@link #configure} is called.
1595     *
1596     * When asynchronous callback is enabled, the client should not call
1597     * {@link #getInputBuffers}, {@link #getOutputBuffers},
1598     * {@link #dequeueInputBuffer(long)} or {@link #dequeueOutputBuffer(BufferInfo, long)}.
1599     * <p>
1600     * Also, {@link #flush} behaves differently in asynchronous mode.  After calling
1601     * {@code flush}, you must call {@link #start} to "resume" receiving input buffers,
1602     * even if an input surface was created.
1603     *
1604     * @param cb The callback that will run.
1605     */
1606    public void setCallback(/* MediaCodec. */ Callback cb) {
1607        if (mEventHandler != null) {
1608            // set java callback on handler
1609            Message msg = mEventHandler.obtainMessage(EVENT_SET_CALLBACK, 0, 0, cb);
1610            mEventHandler.sendMessage(msg);
1611
1612            // set native handler here, don't post to handler because
1613            // it may cause the callback to be delayed and set in a wrong state,
1614            // and MediaCodec is already doing it on looper.
1615            native_setCallback(cb);
1616        }
1617    }
1618
1619    /**
1620     * MediaCodec callback interface. Used to notify the user asynchronously
1621     * of various MediaCodec events.
1622     */
1623    public static abstract class Callback {
1624        /**
1625         * Called when an input buffer becomes available.
1626         *
1627         * @param codec The MediaCodec object.
1628         * @param index The index of the available input buffer.
1629         */
1630        public abstract void onInputBufferAvailable(MediaCodec codec, int index);
1631
1632        /**
1633         * Called when an output buffer becomes available.
1634         *
1635         * @param codec The MediaCodec object.
1636         * @param index The index of the available output buffer.
1637         * @param info Info regarding the available output buffer {@link MediaCodec.BufferInfo}.
1638         */
1639        public abstract void onOutputBufferAvailable(MediaCodec codec, int index, BufferInfo info);
1640
1641        /**
1642         * Called when the MediaCodec encountered an error
1643         *
1644         * @param codec The MediaCodec object.
1645         * @param e The {@link MediaCodec.CodecException} object describing the error.
1646         */
1647        public abstract void onError(MediaCodec codec, CodecException e);
1648
1649        /**
1650         * Called when the output format has changed
1651         *
1652         * @param codec The MediaCodec object.
1653         * @param format The new output format.
1654         */
1655        public abstract void onOutputFormatChanged(MediaCodec codec, MediaFormat format);
1656    }
1657
1658    private void postEventFromNative(
1659            int what, int arg1, int arg2, Object obj) {
1660        if (mEventHandler != null) {
1661            Message msg = mEventHandler.obtainMessage(what, arg1, arg2, obj);
1662            mEventHandler.sendMessage(msg);
1663        }
1664    }
1665
1666    private native final void setParameters(String[] keys, Object[] values);
1667
1668    /**
1669     * Get the codec info. If the codec was created by createDecoderByType
1670     * or createEncoderByType, what component is chosen is not known beforehand,
1671     * and thus the caller does not have the MediaCodecInfo.
1672     * @throws IllegalStateException if in the Uninitialized state.
1673     */
1674    public MediaCodecInfo getCodecInfo() {
1675        return MediaCodecList.getInfoFor(getName());
1676    }
1677
1678    private native final ByteBuffer[] getBuffers(boolean input);
1679
1680    private native final ByteBuffer getBuffer(boolean input, int index);
1681
1682    private native final Image getImage(boolean input, int index);
1683
1684    private static native final void native_init();
1685
1686    private native final void native_setup(
1687            String name, boolean nameIsType, boolean encoder);
1688
1689    private native final void native_finalize();
1690
1691    static {
1692        System.loadLibrary("media_jni");
1693        native_init();
1694    }
1695
1696    private long mNativeContext;
1697
1698    /** @hide */
1699    public static class MediaImage extends Image {
1700        private final boolean mIsReadOnly;
1701        private boolean mIsValid;
1702        private final int mWidth;
1703        private final int mHeight;
1704        private final int mFormat;
1705        private long mTimestamp;
1706        private final Plane[] mPlanes;
1707        private final ByteBuffer mBuffer;
1708        private final ByteBuffer mInfo;
1709        private final int mXOffset;
1710        private final int mYOffset;
1711
1712        private final static int TYPE_YUV = 1;
1713
1714        public int getFormat() {
1715            checkValid();
1716            return mFormat;
1717        }
1718
1719        public int getHeight() {
1720            checkValid();
1721            return mHeight;
1722        }
1723
1724        public int getWidth() {
1725            checkValid();
1726            return mWidth;
1727        }
1728
1729        public long getTimestamp() {
1730            checkValid();
1731            return mTimestamp;
1732        }
1733
1734        public Plane[] getPlanes() {
1735            checkValid();
1736            return Arrays.copyOf(mPlanes, mPlanes.length);
1737        }
1738
1739        public void close() {
1740            if (mIsValid) {
1741                java.nio.NioUtils.freeDirectBuffer(mBuffer);
1742                mIsValid = false;
1743            }
1744        }
1745
1746        /**
1747         * Set the crop rectangle associated with this frame.
1748         * <p>
1749         * The crop rectangle specifies the region of valid pixels in the image,
1750         * using coordinates in the largest-resolution plane.
1751         */
1752        public void setCropRect(Rect cropRect) {
1753            if (mIsReadOnly) {
1754                throw new ReadOnlyBufferException();
1755            }
1756            super.setCropRect(cropRect);
1757        }
1758
1759        private void checkValid() {
1760            if (!mIsValid) {
1761                throw new IllegalStateException("Image is already released");
1762            }
1763        }
1764
1765        private int readInt(ByteBuffer buffer, boolean asLong) {
1766            if (asLong) {
1767                return (int)buffer.getLong();
1768            } else {
1769                return buffer.getInt();
1770            }
1771        }
1772
1773        public MediaImage(
1774                ByteBuffer buffer, ByteBuffer info, boolean readOnly,
1775                long timestamp, int xOffset, int yOffset, Rect cropRect) {
1776            mFormat = ImageFormat.YUV_420_888;
1777            mTimestamp = timestamp;
1778            mIsValid = true;
1779            mIsReadOnly = buffer.isReadOnly();
1780            mBuffer = buffer.duplicate();
1781
1782            // save offsets and info
1783            mXOffset = xOffset;
1784            mYOffset = yOffset;
1785            mInfo = info;
1786
1787            // read media-info.  the size of media info can be 80 or 156/160 depending on
1788            // whether it was created on a 32- or 64-bit process.  See MediaImage
1789            if (info.remaining() == 80 || info.remaining() == 156 || info.remaining() == 160) {
1790                boolean sizeIsLong = info.remaining() != 80;
1791                int type = readInt(info, info.remaining() == 160);
1792                if (type != TYPE_YUV) {
1793                    throw new UnsupportedOperationException("unsupported type: " + type);
1794                }
1795                int numPlanes = readInt(info, sizeIsLong);
1796                if (numPlanes != 3) {
1797                    throw new RuntimeException("unexpected number of planes: " + numPlanes);
1798                }
1799                mWidth = readInt(info, sizeIsLong);
1800                mHeight = readInt(info, sizeIsLong);
1801                if (mWidth < 1 || mHeight < 1) {
1802                    throw new UnsupportedOperationException(
1803                            "unsupported size: " + mWidth + "x" + mHeight);
1804                }
1805                int bitDepth = readInt(info, sizeIsLong);
1806                if (bitDepth != 8) {
1807                    throw new UnsupportedOperationException("unsupported bit depth: " + bitDepth);
1808                }
1809                mPlanes = new MediaPlane[numPlanes];
1810                for (int ix = 0; ix < numPlanes; ix++) {
1811                    int planeOffset = readInt(info, sizeIsLong);
1812                    int colInc = readInt(info, sizeIsLong);
1813                    int rowInc = readInt(info, sizeIsLong);
1814                    int horiz = readInt(info, sizeIsLong);
1815                    int vert = readInt(info, sizeIsLong);
1816                    if (horiz != vert || horiz != (ix == 0 ? 1 : 2)) {
1817                        throw new UnsupportedOperationException("unexpected subsampling: "
1818                                + horiz + "x" + vert + " on plane " + ix);
1819                    }
1820
1821                    buffer.clear();
1822                    buffer.position(mBuffer.position() + planeOffset
1823                            + (xOffset / horiz) * colInc + (yOffset / vert) * rowInc);
1824                    buffer.limit(buffer.position() + Utils.divUp(bitDepth, 8)
1825                            + (mHeight / vert - 1) * rowInc + (mWidth / horiz - 1) * colInc);
1826                    mPlanes[ix] = new MediaPlane(buffer.slice(), rowInc, colInc);
1827                }
1828            } else {
1829                throw new UnsupportedOperationException(
1830                        "unsupported info length: " + info.remaining());
1831            }
1832
1833            if (cropRect == null) {
1834                cropRect = new Rect(0, 0, mWidth, mHeight);
1835            }
1836            cropRect.offset(-xOffset, -yOffset);
1837            super.setCropRect(cropRect);
1838        }
1839
1840        private class MediaPlane extends Plane {
1841            public MediaPlane(ByteBuffer buffer, int rowInc, int colInc) {
1842                mData = buffer;
1843                mRowInc = rowInc;
1844                mColInc = colInc;
1845            }
1846
1847            @Override
1848            public int getRowStride() {
1849                checkValid();
1850                return mRowInc;
1851            }
1852
1853            @Override
1854            public int getPixelStride() {
1855                checkValid();
1856                return mColInc;
1857            }
1858
1859            @Override
1860            public ByteBuffer getBuffer() {
1861                checkValid();
1862                return mData;
1863            }
1864
1865            private final int mRowInc;
1866            private final int mColInc;
1867            private final ByteBuffer mData;
1868        }
1869    }
1870}
1871