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 17 package android.media; 18 19 import android.graphics.ImageFormat; 20 import android.graphics.Rect; 21 import android.media.Image; 22 import android.media.Image.Plane; 23 import android.media.MediaCodecInfo; 24 import android.media.MediaCodecList; 25 import android.media.MediaCrypto; 26 import android.media.MediaFormat; 27 import android.os.Bundle; 28 import android.os.Handler; 29 import android.os.Looper; 30 import android.os.Message; 31 import android.view.Surface; 32 33 import java.io.IOException; 34 import java.nio.ByteBuffer; 35 import java.nio.ReadOnlyBufferException; 36 import java.util.Arrays; 37 import java.util.HashMap; 38 import 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 >= 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 >= 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 & 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 */ 240 final 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 < 0 or wait up 976 * to "timeoutUs" microseconds if timeoutUs > 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