blob: 9fe3ac10a6a9ca5d5511682b6af7281d110ecf9f [file] [log] [blame]
Andreas Huber88572f72012-02-21 11:47:18 -08001/*
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
Martin Storsjo93077a22012-09-25 11:55:25 +030019import android.media.MediaCodecInfo;
20import android.media.MediaCodecList;
Andreas Huber07ea4262012-04-11 12:21:20 -070021import android.media.MediaCrypto;
Andreas Huber60d610b2012-05-02 16:06:09 -070022import android.media.MediaFormat;
Lajos Molnar8a390212013-09-17 18:58:14 -070023import android.os.Bundle;
Andreas Huberaba67132013-10-22 12:40:01 -070024import android.os.Handler;
25import android.os.Looper;
26import android.os.Message;
Andreas Huber88572f72012-02-21 11:47:18 -080027import android.view.Surface;
Lajos Molnar8a390212013-09-17 18:58:14 -070028
Andy Hung83511d22014-01-16 10:10:38 -080029import java.io.IOException;
Andreas Huber88572f72012-02-21 11:47:18 -080030import java.nio.ByteBuffer;
Marco Nelissene20a6d52013-04-08 14:28:55 -070031import java.util.Arrays;
Andreas Huber88572f72012-02-21 11:47:18 -080032import java.util.Map;
33
34/**
35 * MediaCodec class can be used to access low-level media codec, i.e.
36 * encoder/decoder components.
Andreas Huber07ea4262012-04-11 12:21:20 -070037 *
38 * <p>MediaCodec is generally used like this:
39 * <pre>
40 * MediaCodec codec = MediaCodec.createDecoderByType(type);
41 * codec.configure(format, ...);
42 * codec.start();
43 * ByteBuffer[] inputBuffers = codec.getInputBuffers();
44 * ByteBuffer[] outputBuffers = codec.getOutputBuffers();
Andreas Huber07ea4262012-04-11 12:21:20 -070045 * for (;;) {
46 * int inputBufferIndex = codec.dequeueInputBuffer(timeoutUs);
47 * if (inputBufferIndex &gt;= 0) {
48 * // fill inputBuffers[inputBufferIndex] with valid data
49 * ...
50 * codec.queueInputBuffer(inputBufferIndex, ...);
51 * }
52 *
53 * int outputBufferIndex = codec.dequeueOutputBuffer(timeoutUs);
54 * if (outputBufferIndex &gt;= 0) {
55 * // outputBuffer is ready to be processed or rendered.
56 * ...
57 * codec.releaseOutputBuffer(outputBufferIndex, ...);
58 * } else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
59 * outputBuffers = codec.getOutputBuffers();
60 * } else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
61 * // Subsequent data will conform to new format.
Martin Storsjob529e4c2012-07-13 12:57:13 +030062 * MediaFormat format = codec.getOutputFormat();
Andreas Huber07ea4262012-04-11 12:21:20 -070063 * ...
64 * }
65 * }
66 * codec.stop();
67 * codec.release();
68 * codec = null;
69 * </pre>
70 *
71 * Each codec maintains a number of input and output buffers that are
72 * referred to by index in API calls.
Andy Hung83511d22014-01-16 10:10:38 -080073 * The contents of these buffers are represented by the ByteBuffer[] arrays
74 * accessible through {@link #getInputBuffers} and {@link #getOutputBuffers}.
Andreas Huber07ea4262012-04-11 12:21:20 -070075 *
76 * After a successful call to {@link #start} the client "owns" neither
77 * input nor output buffers, subsequent calls to {@link #dequeueInputBuffer}
78 * and {@link #dequeueOutputBuffer} then transfer ownership from the codec
79 * to the client.<p>
80 * The client is not required to resubmit/release buffers immediately
81 * to the codec, the sample code above simply does this for simplicity's sake.<p>
82 * Once the client has an input buffer available it can fill it with data
83 * and submit it it to the codec via a call to {@link #queueInputBuffer}.<p>
84 * The codec in turn will return an output buffer to the client in response
85 * to {@link #dequeueOutputBuffer}. After the output buffer has been processed
86 * a call to {@link #releaseOutputBuffer} will return it to the codec.
87 * If a video surface has been provided in the call to {@link #configure},
88 * {@link #releaseOutputBuffer} optionally allows rendering of the buffer
89 * to the surface.<p>
90 *
91 * Input buffers (for decoders) and Output buffers (for encoders) contain
92 * encoded data according to the format's type. For video types this data
93 * is all the encoded data representing a single moment in time, for audio
94 * data this is slightly relaxed in that a buffer may contain multiple
95 * encoded frames of audio. In either case, buffers do not start and end on
96 * arbitrary byte boundaries, this is not a stream of bytes, it's a stream
97 * of access units.<p>
98 *
99 * Most formats also require the actual data to be prefixed by a number
100 * of buffers containing setup data, or codec specific data, i.e. the
101 * first few buffers submitted to the codec object after starting it must
Andreas Huber60d610b2012-05-02 16:06:09 -0700102 * be codec specific data marked as such using the flag {@link #BUFFER_FLAG_CODEC_CONFIG}
Andreas Huber07ea4262012-04-11 12:21:20 -0700103 * in a call to {@link #queueInputBuffer}.
104 *
Andreas Huber8aa735f2012-05-08 11:33:12 -0700105 * Codec specific data included in the format passed to {@link #configure}
106 * (in ByteBuffer entries with keys "csd-0", "csd-1", ...) is automatically
107 * submitted to the codec, this data MUST NOT be submitted explicitly by the
108 * client.
109 *
Andreas Huber07ea4262012-04-11 12:21:20 -0700110 * Once the client reaches the end of the input data it signals the end of
Andreas Huber60d610b2012-05-02 16:06:09 -0700111 * the input stream by specifying a flag of {@link #BUFFER_FLAG_END_OF_STREAM} in the call to
Andreas Huber07ea4262012-04-11 12:21:20 -0700112 * {@link #queueInputBuffer}. The codec will continue to return output buffers
113 * until it eventually signals the end of the output stream by specifying
Andreas Huber60d610b2012-05-02 16:06:09 -0700114 * the same flag ({@link #BUFFER_FLAG_END_OF_STREAM}) on the BufferInfo returned in
Andreas Huber07ea4262012-04-11 12:21:20 -0700115 * {@link #dequeueOutputBuffer}.
116 *
117 * In order to start decoding data that's not adjacent to previously submitted
118 * data (i.e. after a seek) it is necessary to {@link #flush} the decoder.
119 * Any input or output buffers the client may own at the point of the flush are
120 * immediately revoked, i.e. after a call to {@link #flush} the client does not
121 * own any buffers anymore.
122 * Note that the format of the data submitted after a flush must not change,
123 * flush does not support format discontinuities,
Andy Hung83511d22014-01-16 10:10:38 -0800124 * for this a full {@link #stop}, {@link #configure}, {@link #start}
125 * cycle is necessary.
126 *
127 * <p> The factory methods
128 * {@link #createByCodecName},
129 * {@link #createDecoderByType},
130 * and {@link #createEncoderByType}
131 * throw {@link java.io.IOException} on failure which
132 * the caller must catch or declare to pass up.
133 * Other methods will throw {@link java.lang.IllegalStateException}
134 * if the codec is in an Uninitialized, Invalid, or Error state (e.g. not
135 * initialized properly). Exceptions are thrown elsewhere as noted. </p>
Andreas Huber07ea4262012-04-11 12:21:20 -0700136 *
Andreas Huber60d610b2012-05-02 16:06:09 -0700137 */
Andreas Huber8240d922012-04-04 14:06:32 -0700138final public class MediaCodec {
Andreas Huber60d610b2012-05-02 16:06:09 -0700139 /**
140 * Per buffer metadata includes an offset and size specifying
141 * the range of valid data in the associated codec buffer.
142 */
Andreas Huber88572f72012-02-21 11:47:18 -0800143 public final static class BufferInfo {
144 public void set(
Andreas Huber07ea4262012-04-11 12:21:20 -0700145 int newOffset, int newSize, long newTimeUs, int newFlags) {
146 offset = newOffset;
147 size = newSize;
148 presentationTimeUs = newTimeUs;
149 flags = newFlags;
Andreas Huber88572f72012-02-21 11:47:18 -0800150 }
151
Andreas Huber07ea4262012-04-11 12:21:20 -0700152 public int offset;
153 public int size;
154 public long presentationTimeUs;
155 public int flags;
Andreas Huber88572f72012-02-21 11:47:18 -0800156 };
157
Andreas Huber9e6bcce2012-04-06 12:14:47 -0700158 // The follow flag constants MUST stay in sync with their equivalents
159 // in MediaCodec.h !
Andreas Huber07ea4262012-04-11 12:21:20 -0700160
Andreas Huber60d610b2012-05-02 16:06:09 -0700161 /**
162 * This indicates that the buffer marked as such contains the data
163 * for a sync frame.
164 */
165 public static final int BUFFER_FLAG_SYNC_FRAME = 1;
Andreas Huber07ea4262012-04-11 12:21:20 -0700166
Andreas Huber60d610b2012-05-02 16:06:09 -0700167 /**
168 * This indicated that the buffer marked as such contains codec
169 * initialization / codec specific data instead of media data.
170 */
171 public static final int BUFFER_FLAG_CODEC_CONFIG = 2;
Andreas Huber07ea4262012-04-11 12:21:20 -0700172
Andreas Huber60d610b2012-05-02 16:06:09 -0700173 /**
174 * This signals the end of stream, i.e. no buffers will be available
175 * after this, unless of course, {@link #flush} follows.
176 */
177 public static final int BUFFER_FLAG_END_OF_STREAM = 4;
Andreas Huber9e6bcce2012-04-06 12:14:47 -0700178
Andreas Huberaba67132013-10-22 12:40:01 -0700179 private EventHandler mEventHandler;
Andreas Huber329eec52014-01-27 16:30:09 -0800180 private volatile NotificationCallback mNotificationCallback;
Andreas Huberaba67132013-10-22 12:40:01 -0700181
182 static final int EVENT_NOTIFY = 1;
183
184 private class EventHandler extends Handler {
185 private MediaCodec mCodec;
186
187 public EventHandler(MediaCodec codec, Looper looper) {
188 super(looper);
189 mCodec = codec;
190 }
191
192 @Override
193 public void handleMessage(Message msg) {
194 switch (msg.what) {
195 case EVENT_NOTIFY:
196 {
Andreas Huber329eec52014-01-27 16:30:09 -0800197 NotificationCallback cb = mNotificationCallback;
198 if (cb != null) {
199 cb.onCodecNotify(mCodec);
Andreas Huberaba67132013-10-22 12:40:01 -0700200 }
201 break;
202 }
203 }
204 }
205 }
206
Andreas Huber60d610b2012-05-02 16:06:09 -0700207 /**
208 * Instantiate a decoder supporting input data of the given mime type.
Andreas Huber68b1a6e2012-06-25 13:53:43 -0700209 *
210 * The following is a partial list of defined mime types and their semantics:
211 * <ul>
hkuang63a64732013-06-25 17:26:54 -0700212 * <li>"video/x-vnd.on2.vp8" - VP8 video (i.e. video in .webm)
213 * <li>"video/x-vnd.on2.vp9" - VP9 video (i.e. video in .webm)
Andreas Huber68b1a6e2012-06-25 13:53:43 -0700214 * <li>"video/avc" - H.264/AVC video
215 * <li>"video/mp4v-es" - MPEG4 video
216 * <li>"video/3gpp" - H.263 video
217 * <li>"audio/3gpp" - AMR narrowband audio
218 * <li>"audio/amr-wb" - AMR wideband audio
219 * <li>"audio/mpeg" - MPEG1/2 audio layer III
Martin Storsjod2aaff52013-02-26 14:03:47 +0200220 * <li>"audio/mp4a-latm" - AAC audio (note, this is raw AAC packets, not packaged in LATM!)
Andreas Huber68b1a6e2012-06-25 13:53:43 -0700221 * <li>"audio/vorbis" - vorbis audio
222 * <li>"audio/g711-alaw" - G.711 alaw audio
223 * <li>"audio/g711-mlaw" - G.711 ulaw audio
224 * </ul>
225 *
Andreas Huber60d610b2012-05-02 16:06:09 -0700226 * @param type The mime type of the input data.
Andy Hung83511d22014-01-16 10:10:38 -0800227 * @throws IOException if the codec cannot be created.
228 * @throws IllegalArgumentException if type is null.
Andreas Huber60d610b2012-05-02 16:06:09 -0700229 */
Andy Hung83511d22014-01-16 10:10:38 -0800230 public static MediaCodec createDecoderByType(String type)
231 throws IOException {
Andreas Huber07ea4262012-04-11 12:21:20 -0700232 return new MediaCodec(type, true /* nameIsType */, false /* encoder */);
233 }
234
Andreas Huber60d610b2012-05-02 16:06:09 -0700235 /**
236 * Instantiate an encoder supporting output data of the given mime type.
237 * @param type The desired mime type of the output data.
Andy Hung83511d22014-01-16 10:10:38 -0800238 * @throws IOException if the codec cannot be created.
239 * @throws IllegalArgumentException if type is null.
Andreas Huber60d610b2012-05-02 16:06:09 -0700240 */
Andy Hung83511d22014-01-16 10:10:38 -0800241 public static MediaCodec createEncoderByType(String type)
242 throws IOException {
Andreas Huber07ea4262012-04-11 12:21:20 -0700243 return new MediaCodec(type, true /* nameIsType */, true /* encoder */);
Andreas Huber88572f72012-02-21 11:47:18 -0800244 }
245
Andreas Huber60d610b2012-05-02 16:06:09 -0700246 /**
247 * If you know the exact name of the component you want to instantiate
248 * use this method to instantiate it. Use with caution.
249 * Likely to be used with information obtained from {@link android.media.MediaCodecList}
250 * @param name The name of the codec to be instantiated.
Andy Hung83511d22014-01-16 10:10:38 -0800251 * @throws IOException if the codec cannot be created.
252 * @throws IllegalArgumentException if name is null.
Andreas Huber60d610b2012-05-02 16:06:09 -0700253 */
Andy Hung83511d22014-01-16 10:10:38 -0800254 public static MediaCodec createByCodecName(String name)
255 throws IOException {
Andreas Huber88572f72012-02-21 11:47:18 -0800256 return new MediaCodec(
257 name, false /* nameIsType */, false /* unused */);
258 }
259
260 private MediaCodec(
261 String name, boolean nameIsType, boolean encoder) {
Andreas Huberaba67132013-10-22 12:40:01 -0700262 Looper looper;
263 if ((looper = Looper.myLooper()) != null) {
264 mEventHandler = new EventHandler(this, looper);
265 } else if ((looper = Looper.getMainLooper()) != null) {
266 mEventHandler = new EventHandler(this, looper);
267 } else {
268 mEventHandler = null;
269 }
270
Andreas Huber88572f72012-02-21 11:47:18 -0800271 native_setup(name, nameIsType, encoder);
272 }
273
274 @Override
275 protected void finalize() {
276 native_finalize();
277 }
278
Andreas Huber60d610b2012-05-02 16:06:09 -0700279 /**
280 * Make sure you call this when you're done to free up any opened
281 * component instance instead of relying on the garbage collector
282 * to do this for you at some point in the future.
283 */
Andreas Huber88572f72012-02-21 11:47:18 -0800284 public native final void release();
285
Andreas Huber60d610b2012-05-02 16:06:09 -0700286 /**
287 * If this codec is to be used as an encoder, pass this flag.
288 */
289 public static final int CONFIGURE_FLAG_ENCODE = 1;
Andreas Huber88572f72012-02-21 11:47:18 -0800290
Andreas Huber60d610b2012-05-02 16:06:09 -0700291 /**
292 * Configures a component.
Andreas Huber88572f72012-02-21 11:47:18 -0800293 *
Andreas Huber60d610b2012-05-02 16:06:09 -0700294 * @param format The format of the input data (decoder) or the desired
295 * format of the output data (encoder).
296 * @param surface Specify a surface on which to render the output of this
297 * decoder.
298 * @param crypto Specify a crypto object to facilitate secure decryption
299 * of the media data.
300 * @param flags Specify {@link #CONFIGURE_FLAG_ENCODE} to configure the
301 * component as an encoder.
302 */
Andreas Huber88572f72012-02-21 11:47:18 -0800303 public void configure(
Andreas Huber60d610b2012-05-02 16:06:09 -0700304 MediaFormat format,
Andreas Huber07ea4262012-04-11 12:21:20 -0700305 Surface surface, MediaCrypto crypto, int flags) {
Andreas Huber60d610b2012-05-02 16:06:09 -0700306 Map<String, Object> formatMap = format.getMap();
307
Andreas Huber88572f72012-02-21 11:47:18 -0800308 String[] keys = null;
309 Object[] values = null;
310
311 if (format != null) {
Andreas Huber60d610b2012-05-02 16:06:09 -0700312 keys = new String[formatMap.size()];
313 values = new Object[formatMap.size()];
Andreas Huber88572f72012-02-21 11:47:18 -0800314
315 int i = 0;
Andreas Huber60d610b2012-05-02 16:06:09 -0700316 for (Map.Entry<String, Object> entry: formatMap.entrySet()) {
Andreas Huber88572f72012-02-21 11:47:18 -0800317 keys[i] = entry.getKey();
318 values[i] = entry.getValue();
319 ++i;
320 }
321 }
322
Andreas Huber8240d922012-04-04 14:06:32 -0700323 native_configure(keys, values, surface, crypto, flags);
Andreas Huber88572f72012-02-21 11:47:18 -0800324 }
325
326 private native final void native_configure(
Andreas Huber8240d922012-04-04 14:06:32 -0700327 String[] keys, Object[] values,
Andreas Huber07ea4262012-04-11 12:21:20 -0700328 Surface surface, MediaCrypto crypto, int flags);
Andreas Huber88572f72012-02-21 11:47:18 -0800329
Andreas Huber60d610b2012-05-02 16:06:09 -0700330 /**
Andy McFadden47a2db42013-03-07 17:56:40 -0800331 * Requests a Surface to use as the input to an encoder, in place of input buffers. This
332 * may only be called after {@link #configure} and before {@link #start}.
Andy McFadden2621e402013-02-19 07:29:21 -0800333 * <p>
334 * The application is responsible for calling release() on the Surface when
335 * done.
Andy McFadden2621e402013-02-19 07:29:21 -0800336 */
337 public native final Surface createInputSurface();
338
339 /**
Andreas Huber60d610b2012-05-02 16:06:09 -0700340 * After successfully configuring the component, call start. On return
341 * you can query the component for its input/output buffers.
342 */
Andreas Huber88572f72012-02-21 11:47:18 -0800343 public native final void start();
344
Andreas Huber60d610b2012-05-02 16:06:09 -0700345 /**
346 * Finish the decode/encode session, note that the codec instance
347 * remains active and ready to be {@link #start}ed again.
348 * To ensure that it is available to other client call {@link #release}
349 * and don't just rely on garbage collection to eventually do this for you.
350 */
Andreas Huberaba67132013-10-22 12:40:01 -0700351 public final void stop() {
352 native_stop();
353
354 if (mEventHandler != null) {
355 mEventHandler.removeMessages(EVENT_NOTIFY);
356 }
357 }
358
359 private native final void native_stop();
Andreas Huber88572f72012-02-21 11:47:18 -0800360
Andreas Huber60d610b2012-05-02 16:06:09 -0700361 /**
362 * Flush both input and output ports of the component, all indices
363 * previously returned in calls to {@link #dequeueInputBuffer} and
364 * {@link #dequeueOutputBuffer} become invalid.
365 */
Andreas Huber88572f72012-02-21 11:47:18 -0800366 public native final void flush();
367
Jeff Tinkerb6f0f962013-09-13 15:32:08 -0700368 /**
369 * Thrown when a crypto error occurs while queueing a secure input buffer.
370 */
Andreas Huberbfc56f42012-04-19 12:47:07 -0700371 public final static class CryptoException extends RuntimeException {
372 public CryptoException(int errorCode, String detailMessage) {
373 super(detailMessage);
374 mErrorCode = errorCode;
375 }
376
Jeff Tinker3ed38262013-08-02 23:24:51 -0700377 /**
378 * This indicates that no key has been set to perform the requested
379 * decrypt operation.
380 */
381 public static final int ERROR_NO_KEY = 1;
382
383 /**
384 * This indicates that the key used for decryption is no longer
385 * valid due to license term expiration.
386 */
387 public static final int ERROR_KEY_EXPIRED = 2;
388
389 /**
390 * This indicates that a required crypto resource was not able to be
391 * allocated while attempting the requested operation.
392 */
393 public static final int ERROR_RESOURCE_BUSY = 3;
394
Jeff Tinkerb6f0f962013-09-13 15:32:08 -0700395 /**
396 * Retrieve the error code associated with a CryptoException
397 */
Andreas Huberbfc56f42012-04-19 12:47:07 -0700398 public int getErrorCode() {
399 return mErrorCode;
400 }
401
402 private int mErrorCode;
403 }
404
Andreas Huber60d610b2012-05-02 16:06:09 -0700405 /**
406 * After filling a range of the input buffer at the specified index
407 * submit it to the component.
Andreas Huberc52b9802012-03-12 14:04:01 -0700408 *
Andreas Huber60d610b2012-05-02 16:06:09 -0700409 * Many decoders require the actual compressed data stream to be
410 * preceded by "codec specific data", i.e. setup data used to initialize
411 * the codec such as PPS/SPS in the case of AVC video or code tables
412 * in the case of vorbis audio.
413 * The class {@link android.media.MediaExtractor} provides codec
414 * specific data as part of
415 * the returned track format in entries named "csd-0", "csd-1" ...
Andreas Huberc52b9802012-03-12 14:04:01 -0700416 *
Andreas Huber60d610b2012-05-02 16:06:09 -0700417 * These buffers should be submitted using the flag {@link #BUFFER_FLAG_CODEC_CONFIG}.
Andreas Huberc52b9802012-03-12 14:04:01 -0700418 *
Andreas Huber60d610b2012-05-02 16:06:09 -0700419 * To indicate that this is the final piece of input data (or rather that
420 * no more input data follows unless the decoder is subsequently flushed)
421 * specify the flag {@link #BUFFER_FLAG_END_OF_STREAM}.
Andreas Huber07ea4262012-04-11 12:21:20 -0700422 *
Andreas Huber60d610b2012-05-02 16:06:09 -0700423 * @param index The index of a client-owned input buffer previously returned
424 * in a call to {@link #dequeueInputBuffer}.
425 * @param offset The byte offset into the input buffer at which the data starts.
426 * @param size The number of bytes of valid input data.
427 * @param presentationTimeUs The time at which this buffer should be rendered.
428 * @param flags A bitmask of flags {@link #BUFFER_FLAG_SYNC_FRAME},
429 * {@link #BUFFER_FLAG_CODEC_CONFIG} or {@link #BUFFER_FLAG_END_OF_STREAM}.
430 * @throws CryptoException if a crypto object has been specified in
431 * {@link #configure}
432 */
Andreas Huber88572f72012-02-21 11:47:18 -0800433 public native final void queueInputBuffer(
434 int index,
Andreas Huberbfc56f42012-04-19 12:47:07 -0700435 int offset, int size, long presentationTimeUs, int flags)
436 throws CryptoException;
Andreas Huber88572f72012-02-21 11:47:18 -0800437
Andreas Huber60d610b2012-05-02 16:06:09 -0700438 // The following mode constants MUST stay in sync with their equivalents
439 // in media/hardware/CryptoAPI.h !
440 public static final int CRYPTO_MODE_UNENCRYPTED = 0;
441 public static final int CRYPTO_MODE_AES_CTR = 1;
442
443 /**
444 * Metadata describing the structure of a (at least partially) encrypted
445 * input sample.
446 * A buffer's data is considered to be partitioned into "subSamples",
447 * each subSample starts with a (potentially empty) run of plain,
448 * unencrypted bytes followed by a (also potentially empty) run of
449 * encrypted bytes.
450 * numBytesOfClearData can be null to indicate that all data is encrypted.
451 * This information encapsulates per-sample metadata as outlined in
452 * ISO/IEC FDIS 23001-7:2011 "Common encryption in ISO base media file format files".
453 */
Andreas Huber91befdc2012-04-18 12:19:51 -0700454 public final static class CryptoInfo {
455 public void set(
456 int newNumSubSamples,
457 int[] newNumBytesOfClearData,
458 int[] newNumBytesOfEncryptedData,
459 byte[] newKey,
460 byte[] newIV,
461 int newMode) {
462 numSubSamples = newNumSubSamples;
463 numBytesOfClearData = newNumBytesOfClearData;
464 numBytesOfEncryptedData = newNumBytesOfEncryptedData;
465 key = newKey;
466 iv = newIV;
467 mode = newMode;
468 }
469
Andreas Huber60d610b2012-05-02 16:06:09 -0700470 /**
471 * The number of subSamples that make up the buffer's contents.
472 */
Andreas Huber91befdc2012-04-18 12:19:51 -0700473 public int numSubSamples;
Andreas Huber60d610b2012-05-02 16:06:09 -0700474 /**
475 * The number of leading unencrypted bytes in each subSample.
476 */
Andreas Huber91befdc2012-04-18 12:19:51 -0700477 public int[] numBytesOfClearData;
Andreas Huber60d610b2012-05-02 16:06:09 -0700478 /**
479 * The number of trailing encrypted bytes in each subSample.
480 */
Andreas Huber91befdc2012-04-18 12:19:51 -0700481 public int[] numBytesOfEncryptedData;
Andreas Huber60d610b2012-05-02 16:06:09 -0700482 /**
483 * A 16-byte opaque key
484 */
Andreas Huber91befdc2012-04-18 12:19:51 -0700485 public byte[] key;
Andreas Huber60d610b2012-05-02 16:06:09 -0700486 /**
487 * A 16-byte initialization vector
488 */
Andreas Huber91befdc2012-04-18 12:19:51 -0700489 public byte[] iv;
Andreas Huber60d610b2012-05-02 16:06:09 -0700490 /**
491 * The type of encryption that has been applied,
492 * see {@link #CRYPTO_MODE_UNENCRYPTED} and {@link #CRYPTO_MODE_AES_CTR}.
493 */
Andreas Huber91befdc2012-04-18 12:19:51 -0700494 public int mode;
Marco Nelissene20a6d52013-04-08 14:28:55 -0700495
496 @Override
497 public String toString() {
498 StringBuilder builder = new StringBuilder();
499 builder.append(numSubSamples + " subsamples, key [");
500 String hexdigits = "0123456789abcdef";
501 for (int i = 0; i < key.length; i++) {
502 builder.append(hexdigits.charAt((key[i] & 0xf0) >> 4));
503 builder.append(hexdigits.charAt(key[i] & 0x0f));
504 }
505 builder.append("], iv [");
506 for (int i = 0; i < key.length; i++) {
507 builder.append(hexdigits.charAt((iv[i] & 0xf0) >> 4));
508 builder.append(hexdigits.charAt(iv[i] & 0x0f));
509 }
510 builder.append("], clear ");
511 builder.append(Arrays.toString(numBytesOfClearData));
512 builder.append(", encrypted ");
513 builder.append(Arrays.toString(numBytesOfEncryptedData));
514 return builder.toString();
515 }
Andreas Huber91befdc2012-04-18 12:19:51 -0700516 };
517
Andreas Huber60d610b2012-05-02 16:06:09 -0700518 /**
519 * Similar to {@link #queueInputBuffer} but submits a buffer that is
520 * potentially encrypted.
521 * @param index The index of a client-owned input buffer previously returned
522 * in a call to {@link #dequeueInputBuffer}.
523 * @param offset The byte offset into the input buffer at which the data starts.
524 * @param info Metadata required to facilitate decryption, the object can be
525 * reused immediately after this call returns.
526 * @param presentationTimeUs The time at which this buffer should be rendered.
527 * @param flags A bitmask of flags {@link #BUFFER_FLAG_SYNC_FRAME},
528 * {@link #BUFFER_FLAG_CODEC_CONFIG} or {@link #BUFFER_FLAG_END_OF_STREAM}.
Jeff Tinkerb6f0f962013-09-13 15:32:08 -0700529 * @throws CryptoException if an error occurs while attempting to decrypt the buffer.
530 * An error code associated with the exception helps identify the
531 * reason for the failure.
Andreas Huber9e6bcce2012-04-06 12:14:47 -0700532 */
533 public native final void queueSecureInputBuffer(
534 int index,
535 int offset,
Andreas Huber91befdc2012-04-18 12:19:51 -0700536 CryptoInfo info,
Andreas Huber9e6bcce2012-04-06 12:14:47 -0700537 long presentationTimeUs,
Andreas Huberbfc56f42012-04-19 12:47:07 -0700538 int flags) throws CryptoException;
Andreas Huber9e6bcce2012-04-06 12:14:47 -0700539
Andreas Huber60d610b2012-05-02 16:06:09 -0700540 /**
541 * Returns the index of an input buffer to be filled with valid data
542 * or -1 if no such buffer is currently available.
543 * This method will return immediately if timeoutUs == 0, wait indefinitely
544 * for the availability of an input buffer if timeoutUs &lt; 0 or wait up
545 * to "timeoutUs" microseconds if timeoutUs &gt; 0.
546 * @param timeoutUs The timeout in microseconds, a negative timeout indicates "infinite".
547 */
Andreas Huber88572f72012-02-21 11:47:18 -0800548 public native final int dequeueInputBuffer(long timeoutUs);
549
Andreas Huber60d610b2012-05-02 16:06:09 -0700550 /**
551 * If a non-negative timeout had been specified in the call
Andreas Huber07ea4262012-04-11 12:21:20 -0700552 * to {@link #dequeueOutputBuffer}, indicates that the call timed out.
Andreas Huber60d610b2012-05-02 16:06:09 -0700553 */
Andreas Huber88572f72012-02-21 11:47:18 -0800554 public static final int INFO_TRY_AGAIN_LATER = -1;
Andreas Huber07ea4262012-04-11 12:21:20 -0700555
Andreas Huber60d610b2012-05-02 16:06:09 -0700556 /**
557 * The output format has changed, subsequent data will follow the new
558 * format. {@link #getOutputFormat} returns the new format.
559 */
Andreas Huber88572f72012-02-21 11:47:18 -0800560 public static final int INFO_OUTPUT_FORMAT_CHANGED = -2;
Andreas Huber07ea4262012-04-11 12:21:20 -0700561
Andreas Huber60d610b2012-05-02 16:06:09 -0700562 /**
563 * The output buffers have changed, the client must refer to the new
564 * set of output buffers returned by {@link #getOutputBuffers} from
565 * this point on.
566 */
Andreas Huber88572f72012-02-21 11:47:18 -0800567 public static final int INFO_OUTPUT_BUFFERS_CHANGED = -3;
568
Andreas Huber60d610b2012-05-02 16:06:09 -0700569 /**
570 * Dequeue an output buffer, block at most "timeoutUs" microseconds.
571 * Returns the index of an output buffer that has been successfully
572 * decoded or one of the INFO_* constants below.
573 * @param info Will be filled with buffer meta data.
574 * @param timeoutUs The timeout in microseconds, a negative timeout indicates "infinite".
575 */
Andreas Huber88572f72012-02-21 11:47:18 -0800576 public native final int dequeueOutputBuffer(
577 BufferInfo info, long timeoutUs);
578
Andreas Huber60d610b2012-05-02 16:06:09 -0700579 /**
580 * If you are done with a buffer, use this call to return the buffer to
581 * the codec. If you previously specified a surface when configuring this
582 * video decoder you can optionally render the buffer.
583 * @param index The index of a client-owned output buffer previously returned
584 * in a call to {@link #dequeueOutputBuffer}.
585 * @param render If a valid surface was specified when configuring the codec,
586 * passing true renders this output buffer to the surface.
587 */
Andreas Huber88572f72012-02-21 11:47:18 -0800588 public native final void releaseOutputBuffer(int index, boolean render);
589
Andreas Huber60d610b2012-05-02 16:06:09 -0700590 /**
Andy McFadden2621e402013-02-19 07:29:21 -0800591 * Signals end-of-stream on input. Equivalent to submitting an empty buffer with
592 * {@link #BUFFER_FLAG_END_OF_STREAM} set. This may only be used with
593 * encoders receiving input from a Surface created by {@link #createInputSurface}.
Andy McFadden2621e402013-02-19 07:29:21 -0800594 */
595 public native final void signalEndOfInputStream();
596
597 /**
Andreas Huber60d610b2012-05-02 16:06:09 -0700598 * Call this after dequeueOutputBuffer signals a format change by returning
599 * {@link #INFO_OUTPUT_FORMAT_CHANGED}
Andreas Huber88572f72012-02-21 11:47:18 -0800600 */
Andreas Huber60d610b2012-05-02 16:06:09 -0700601 public final MediaFormat getOutputFormat() {
602 return new MediaFormat(getOutputFormatNative());
603 }
Andreas Huber88572f72012-02-21 11:47:18 -0800604
Andreas Huber60d610b2012-05-02 16:06:09 -0700605 private native final Map<String, Object> getOutputFormatNative();
606
607 /**
608 * Call this after start() returns.
Andreas Huberc52b9802012-03-12 14:04:01 -0700609 */
610 public ByteBuffer[] getInputBuffers() {
611 return getBuffers(true /* input */);
612 }
613
Andreas Huber60d610b2012-05-02 16:06:09 -0700614 /**
615 * Call this after start() returns and whenever dequeueOutputBuffer
616 * signals an output buffer change by returning
617 * {@link #INFO_OUTPUT_BUFFERS_CHANGED}
Andreas Huber88572f72012-02-21 11:47:18 -0800618 */
Andreas Huberc52b9802012-03-12 14:04:01 -0700619 public ByteBuffer[] getOutputBuffers() {
620 return getBuffers(false /* input */);
621 }
622
Andreas Huber60d610b2012-05-02 16:06:09 -0700623 /**
624 * The content is scaled to the surface dimensions
625 */
Andreas Huber48dc91b2012-05-01 11:50:30 -0700626 public static final int VIDEO_SCALING_MODE_SCALE_TO_FIT = 1;
Andreas Huberb12a5392012-04-30 14:18:33 -0700627
Andreas Huber60d610b2012-05-02 16:06:09 -0700628 /**
629 * The content is scaled, maintaining its aspect ratio, the whole
630 * surface area is used, content may be cropped
631 */
Andreas Huberb12a5392012-04-30 14:18:33 -0700632 public static final int VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING = 2;
633
Andreas Huber60d610b2012-05-02 16:06:09 -0700634 /**
635 * If a surface has been specified in a previous call to {@link #configure}
636 * specifies the scaling mode to use. The default is "scale to fit".
637 */
Andreas Huberb12a5392012-04-30 14:18:33 -0700638 public native final void setVideoScalingMode(int mode);
639
Martin Storsjo056ef2e2012-09-25 11:53:04 +0300640 /**
641 * Get the component name. If the codec was created by createDecoderByType
642 * or createEncoderByType, what component is chosen is not known beforehand.
643 */
644 public native final String getName();
645
Martin Storsjo93077a22012-09-25 11:55:25 +0300646 /**
Andreas Huber226065b2013-08-12 10:14:11 -0700647 * Change a video encoder's target bitrate on the fly. The value is an
648 * Integer object containing the new bitrate in bps.
649 */
Lajos Molnar8a390212013-09-17 18:58:14 -0700650 public static final String PARAMETER_KEY_VIDEO_BITRATE = "video-bitrate";
Andreas Huber226065b2013-08-12 10:14:11 -0700651
652 /**
653 * Temporarily suspend/resume encoding of input data. While suspended
654 * input data is effectively discarded instead of being fed into the
655 * encoder. This parameter really only makes sense to use with an encoder
656 * in "surface-input" mode, as the client code has no control over the
657 * input-side of the encoder in that case.
658 * The value is an Integer object containing the value 1 to suspend
659 * or the value 0 to resume.
660 */
661 public static final String PARAMETER_KEY_SUSPEND = "drop-input-frames";
662
663 /**
664 * Request that the encoder produce a sync frame "soon".
665 * Provide an Integer with the value 0.
666 */
667 public static final String PARAMETER_KEY_REQUEST_SYNC_FRAME = "request-sync";
668
669 /**
670 * Communicate additional parameter changes to the component instance.
671 */
Lajos Molnar8a390212013-09-17 18:58:14 -0700672 public final void setParameters(Bundle params) {
Andreas Huber226065b2013-08-12 10:14:11 -0700673 if (params == null) {
674 return;
675 }
676
677 String[] keys = new String[params.size()];
678 Object[] values = new Object[params.size()];
679
680 int i = 0;
Lajos Molnar8a390212013-09-17 18:58:14 -0700681 for (final String key: params.keySet()) {
682 keys[i] = key;
683 values[i] = params.get(key);
Andreas Huber226065b2013-08-12 10:14:11 -0700684 ++i;
685 }
686
687 setParameters(keys, values);
688 }
689
Andreas Huberaba67132013-10-22 12:40:01 -0700690 public void setNotificationCallback(NotificationCallback cb) {
691 mNotificationCallback = cb;
692 }
693
694 public interface NotificationCallback {
695 void onCodecNotify(MediaCodec codec);
696 }
697
698 private void postEventFromNative(
699 int what, int arg1, int arg2, Object obj) {
700 if (mEventHandler != null) {
701 Message msg = mEventHandler.obtainMessage(what, arg1, arg2, obj);
702 mEventHandler.sendMessage(msg);
703 }
704 }
705
Andreas Huber226065b2013-08-12 10:14:11 -0700706 private native final void setParameters(String[] keys, Object[] values);
707
708 /**
Martin Storsjo93077a22012-09-25 11:55:25 +0300709 * Get the codec info. If the codec was created by createDecoderByType
710 * or createEncoderByType, what component is chosen is not known beforehand,
711 * and thus the caller does not have the MediaCodecInfo.
712 */
713 public MediaCodecInfo getCodecInfo() {
714 return MediaCodecList.getCodecInfoAt(
715 MediaCodecList.findCodecByName(getName()));
716 }
717
Andreas Huberc52b9802012-03-12 14:04:01 -0700718 private native final ByteBuffer[] getBuffers(boolean input);
Andreas Huber88572f72012-02-21 11:47:18 -0800719
720 private static native final void native_init();
721
722 private native final void native_setup(
723 String name, boolean nameIsType, boolean encoder);
724
725 private native final void native_finalize();
726
727 static {
728 System.loadLibrary("media_jni");
729 native_init();
730 }
731
Ashok Bhat075e9a12014-01-06 13:45:09 +0000732 private long mNativeContext;
Andreas Huber88572f72012-02-21 11:47:18 -0800733}