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