MediaCodec.cpp revision 4b75a9c8b93a90749bc5d22912ad0d96c12f4ecf
1/* 2 * Copyright 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//#define LOG_NDEBUG 0 18#define LOG_TAG "MediaCodec" 19#include <utils/Log.h> 20 21#include <media/stagefright/MediaCodec.h> 22 23#include "include/SoftwareRenderer.h" 24 25#include <gui/SurfaceTextureClient.h> 26#include <media/ICrypto.h> 27#include <media/stagefright/foundation/ABuffer.h> 28#include <media/stagefright/foundation/ADebug.h> 29#include <media/stagefright/foundation/AMessage.h> 30#include <media/stagefright/foundation/hexdump.h> 31#include <media/stagefright/ACodec.h> 32#include <media/stagefright/MediaErrors.h> 33#include <media/stagefright/MetaData.h> 34#include <media/stagefright/NativeWindowWrapper.h> 35 36namespace android { 37 38// static 39sp<MediaCodec> MediaCodec::CreateByType( 40 const sp<ALooper> &looper, const char *mime, bool encoder) { 41 sp<MediaCodec> codec = new MediaCodec(looper); 42 if (codec->init(mime, true /* nameIsType */, encoder) != OK) { 43 return NULL; 44 } 45 46 return codec; 47} 48 49// static 50sp<MediaCodec> MediaCodec::CreateByComponentName( 51 const sp<ALooper> &looper, const char *name) { 52 sp<MediaCodec> codec = new MediaCodec(looper); 53 if (codec->init(name, false /* nameIsType */, false /* encoder */) != OK) { 54 return NULL; 55 } 56 57 return codec; 58} 59 60MediaCodec::MediaCodec(const sp<ALooper> &looper) 61 : mState(UNINITIALIZED), 62 mLooper(looper), 63 mCodec(new ACodec), 64 mFlags(0), 65 mSoftRenderer(NULL), 66 mDequeueInputTimeoutGeneration(0), 67 mDequeueInputReplyID(0), 68 mDequeueOutputTimeoutGeneration(0), 69 mDequeueOutputReplyID(0) { 70} 71 72MediaCodec::~MediaCodec() { 73 CHECK_EQ(mState, UNINITIALIZED); 74} 75 76// static 77status_t MediaCodec::PostAndAwaitResponse( 78 const sp<AMessage> &msg, sp<AMessage> *response) { 79 status_t err = msg->postAndAwaitResponse(response); 80 81 if (err != OK) { 82 return err; 83 } 84 85 if (!(*response)->findInt32("err", &err)) { 86 err = OK; 87 } 88 89 return err; 90} 91 92status_t MediaCodec::init(const char *name, bool nameIsType, bool encoder) { 93 // Current video decoders do not return from OMX_FillThisBuffer 94 // quickly, violating the OpenMAX specs, until that is remedied 95 // we need to invest in an extra looper to free the main event 96 // queue. 97 bool needDedicatedLooper = false; 98 if (nameIsType && !strncasecmp(name, "video/", 6)) { 99 needDedicatedLooper = true; 100 } else if (!nameIsType && !strncmp(name, "OMX.TI.DUCATI1.VIDEO.", 21)) { 101 needDedicatedLooper = true; 102 } 103 104 if (needDedicatedLooper) { 105 if (mCodecLooper == NULL) { 106 mCodecLooper = new ALooper; 107 mCodecLooper->setName("CodecLooper"); 108 mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO); 109 } 110 111 mCodecLooper->registerHandler(mCodec); 112 } else { 113 mLooper->registerHandler(mCodec); 114 } 115 116 mLooper->registerHandler(this); 117 118 mCodec->setNotificationMessage(new AMessage(kWhatCodecNotify, id())); 119 120 sp<AMessage> msg = new AMessage(kWhatInit, id()); 121 msg->setString("name", name); 122 msg->setInt32("nameIsType", nameIsType); 123 124 if (nameIsType) { 125 msg->setInt32("encoder", encoder); 126 } 127 128 sp<AMessage> response; 129 return PostAndAwaitResponse(msg, &response); 130} 131 132status_t MediaCodec::configure( 133 const sp<AMessage> &format, 134 const sp<SurfaceTextureClient> &nativeWindow, 135 const sp<ICrypto> &crypto, 136 uint32_t flags) { 137 sp<AMessage> msg = new AMessage(kWhatConfigure, id()); 138 139 msg->setMessage("format", format); 140 msg->setInt32("flags", flags); 141 142 if (nativeWindow != NULL) { 143 msg->setObject( 144 "native-window", 145 new NativeWindowWrapper(nativeWindow)); 146 } 147 148 if (crypto != NULL) { 149 msg->setPointer("crypto", crypto.get()); 150 } 151 152 sp<AMessage> response; 153 return PostAndAwaitResponse(msg, &response); 154} 155 156status_t MediaCodec::start() { 157 sp<AMessage> msg = new AMessage(kWhatStart, id()); 158 159 sp<AMessage> response; 160 return PostAndAwaitResponse(msg, &response); 161} 162 163status_t MediaCodec::stop() { 164 sp<AMessage> msg = new AMessage(kWhatStop, id()); 165 166 sp<AMessage> response; 167 return PostAndAwaitResponse(msg, &response); 168} 169 170status_t MediaCodec::release() { 171 sp<AMessage> msg = new AMessage(kWhatRelease, id()); 172 173 sp<AMessage> response; 174 return PostAndAwaitResponse(msg, &response); 175} 176 177status_t MediaCodec::queueInputBuffer( 178 size_t index, 179 size_t offset, 180 size_t size, 181 int64_t presentationTimeUs, 182 uint32_t flags) { 183 sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, id()); 184 msg->setSize("index", index); 185 msg->setSize("offset", offset); 186 msg->setSize("size", size); 187 msg->setInt64("timeUs", presentationTimeUs); 188 msg->setInt32("flags", flags); 189 190 sp<AMessage> response; 191 return PostAndAwaitResponse(msg, &response); 192} 193 194status_t MediaCodec::queueSecureInputBuffer( 195 size_t index, 196 size_t offset, 197 const CryptoPlugin::SubSample *subSamples, 198 size_t numSubSamples, 199 const uint8_t key[16], 200 const uint8_t iv[16], 201 CryptoPlugin::Mode mode, 202 int64_t presentationTimeUs, 203 uint32_t flags) { 204 sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, id()); 205 msg->setSize("index", index); 206 msg->setSize("offset", offset); 207 msg->setPointer("subSamples", (void *)subSamples); 208 msg->setSize("numSubSamples", numSubSamples); 209 msg->setPointer("key", (void *)key); 210 msg->setPointer("iv", (void *)iv); 211 msg->setInt32("mode", mode); 212 msg->setInt64("timeUs", presentationTimeUs); 213 msg->setInt32("flags", flags); 214 215 sp<AMessage> response; 216 return PostAndAwaitResponse(msg, &response); 217} 218 219status_t MediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) { 220 sp<AMessage> msg = new AMessage(kWhatDequeueInputBuffer, id()); 221 msg->setInt64("timeoutUs", timeoutUs); 222 223 sp<AMessage> response; 224 status_t err; 225 if ((err = PostAndAwaitResponse(msg, &response)) != OK) { 226 return err; 227 } 228 229 CHECK(response->findSize("index", index)); 230 231 return OK; 232} 233 234status_t MediaCodec::dequeueOutputBuffer( 235 size_t *index, 236 size_t *offset, 237 size_t *size, 238 int64_t *presentationTimeUs, 239 uint32_t *flags, 240 int64_t timeoutUs) { 241 sp<AMessage> msg = new AMessage(kWhatDequeueOutputBuffer, id()); 242 msg->setInt64("timeoutUs", timeoutUs); 243 244 sp<AMessage> response; 245 status_t err; 246 if ((err = PostAndAwaitResponse(msg, &response)) != OK) { 247 return err; 248 } 249 250 CHECK(response->findSize("index", index)); 251 CHECK(response->findSize("offset", offset)); 252 CHECK(response->findSize("size", size)); 253 CHECK(response->findInt64("timeUs", presentationTimeUs)); 254 CHECK(response->findInt32("flags", (int32_t *)flags)); 255 256 return OK; 257} 258 259status_t MediaCodec::renderOutputBufferAndRelease(size_t index) { 260 sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, id()); 261 msg->setSize("index", index); 262 msg->setInt32("render", true); 263 264 sp<AMessage> response; 265 return PostAndAwaitResponse(msg, &response); 266} 267 268status_t MediaCodec::releaseOutputBuffer(size_t index) { 269 sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, id()); 270 msg->setSize("index", index); 271 272 sp<AMessage> response; 273 return PostAndAwaitResponse(msg, &response); 274} 275 276status_t MediaCodec::getOutputFormat(sp<AMessage> *format) const { 277 sp<AMessage> msg = new AMessage(kWhatGetOutputFormat, id()); 278 279 sp<AMessage> response; 280 status_t err; 281 if ((err = PostAndAwaitResponse(msg, &response)) != OK) { 282 return err; 283 } 284 285 CHECK(response->findMessage("format", format)); 286 287 return OK; 288} 289 290status_t MediaCodec::getInputBuffers(Vector<sp<ABuffer> > *buffers) const { 291 sp<AMessage> msg = new AMessage(kWhatGetBuffers, id()); 292 msg->setInt32("portIndex", kPortIndexInput); 293 msg->setPointer("buffers", buffers); 294 295 sp<AMessage> response; 296 return PostAndAwaitResponse(msg, &response); 297} 298 299status_t MediaCodec::getOutputBuffers(Vector<sp<ABuffer> > *buffers) const { 300 sp<AMessage> msg = new AMessage(kWhatGetBuffers, id()); 301 msg->setInt32("portIndex", kPortIndexOutput); 302 msg->setPointer("buffers", buffers); 303 304 sp<AMessage> response; 305 return PostAndAwaitResponse(msg, &response); 306} 307 308status_t MediaCodec::flush() { 309 sp<AMessage> msg = new AMessage(kWhatFlush, id()); 310 311 sp<AMessage> response; 312 return PostAndAwaitResponse(msg, &response); 313} 314 315//////////////////////////////////////////////////////////////////////////////// 316 317void MediaCodec::cancelPendingDequeueOperations() { 318 if (mFlags & kFlagDequeueInputPending) { 319 sp<AMessage> response = new AMessage; 320 response->setInt32("err", INVALID_OPERATION); 321 response->postReply(mDequeueInputReplyID); 322 323 ++mDequeueInputTimeoutGeneration; 324 mDequeueInputReplyID = 0; 325 mFlags &= ~kFlagDequeueInputPending; 326 } 327 328 if (mFlags & kFlagDequeueOutputPending) { 329 sp<AMessage> response = new AMessage; 330 response->setInt32("err", INVALID_OPERATION); 331 response->postReply(mDequeueOutputReplyID); 332 333 ++mDequeueOutputTimeoutGeneration; 334 mDequeueOutputReplyID = 0; 335 mFlags &= ~kFlagDequeueOutputPending; 336 } 337} 338 339bool MediaCodec::handleDequeueInputBuffer(uint32_t replyID, bool newRequest) { 340 if (mState != STARTED 341 || (mFlags & kFlagStickyError) 342 || (newRequest && (mFlags & kFlagDequeueInputPending))) { 343 sp<AMessage> response = new AMessage; 344 response->setInt32("err", INVALID_OPERATION); 345 346 response->postReply(replyID); 347 348 return true; 349 } 350 351 ssize_t index = dequeuePortBuffer(kPortIndexInput); 352 353 if (index < 0) { 354 CHECK_EQ(index, -EAGAIN); 355 return false; 356 } 357 358 sp<AMessage> response = new AMessage; 359 response->setSize("index", index); 360 response->postReply(replyID); 361 362 return true; 363} 364 365bool MediaCodec::handleDequeueOutputBuffer(uint32_t replyID, bool newRequest) { 366 sp<AMessage> response = new AMessage; 367 368 if (mState != STARTED 369 || (mFlags & kFlagStickyError) 370 || (newRequest && (mFlags & kFlagDequeueOutputPending))) { 371 response->setInt32("err", INVALID_OPERATION); 372 } else if (mFlags & kFlagOutputBuffersChanged) { 373 response->setInt32("err", INFO_OUTPUT_BUFFERS_CHANGED); 374 mFlags &= ~kFlagOutputBuffersChanged; 375 } else if (mFlags & kFlagOutputFormatChanged) { 376 response->setInt32("err", INFO_FORMAT_CHANGED); 377 mFlags &= ~kFlagOutputFormatChanged; 378 } else { 379 ssize_t index = dequeuePortBuffer(kPortIndexOutput); 380 381 if (index < 0) { 382 CHECK_EQ(index, -EAGAIN); 383 return false; 384 } 385 386 const sp<ABuffer> &buffer = 387 mPortBuffers[kPortIndexOutput].itemAt(index).mData; 388 389 response->setSize("index", index); 390 response->setSize("offset", buffer->offset()); 391 response->setSize("size", buffer->size()); 392 393 int64_t timeUs; 394 CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 395 396 response->setInt64("timeUs", timeUs); 397 398 int32_t omxFlags; 399 CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags)); 400 401 uint32_t flags = 0; 402 if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) { 403 flags |= BUFFER_FLAG_SYNCFRAME; 404 } 405 if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) { 406 flags |= BUFFER_FLAG_CODECCONFIG; 407 } 408 if (omxFlags & OMX_BUFFERFLAG_EOS) { 409 flags |= BUFFER_FLAG_EOS; 410 } 411 412 response->setInt32("flags", flags); 413 } 414 415 response->postReply(replyID); 416 417 return true; 418} 419 420void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { 421 switch (msg->what()) { 422 case kWhatCodecNotify: 423 { 424 int32_t what; 425 CHECK(msg->findInt32("what", &what)); 426 427 switch (what) { 428 case ACodec::kWhatError: 429 { 430 int32_t omxError, internalError; 431 CHECK(msg->findInt32("omx-error", &omxError)); 432 CHECK(msg->findInt32("err", &internalError)); 433 434 ALOGE("Codec reported an error. " 435 "(omx error 0x%08x, internalError %d)", 436 omxError, internalError); 437 438 bool sendErrorReponse = true; 439 440 switch (mState) { 441 case INITIALIZING: 442 { 443 setState(UNINITIALIZED); 444 break; 445 } 446 447 case CONFIGURING: 448 { 449 setState(INITIALIZED); 450 break; 451 } 452 453 case STARTING: 454 { 455 setState(CONFIGURED); 456 break; 457 } 458 459 case STOPPING: 460 case RELEASING: 461 { 462 // Ignore the error, assuming we'll still get 463 // the shutdown complete notification. 464 465 sendErrorReponse = false; 466 break; 467 } 468 469 case FLUSHING: 470 { 471 setState(STARTED); 472 break; 473 } 474 475 case STARTED: 476 { 477 sendErrorReponse = false; 478 479 mFlags |= kFlagStickyError; 480 481 cancelPendingDequeueOperations(); 482 break; 483 } 484 485 default: 486 { 487 sendErrorReponse = false; 488 489 mFlags |= kFlagStickyError; 490 break; 491 } 492 } 493 494 if (sendErrorReponse) { 495 sp<AMessage> response = new AMessage; 496 response->setInt32("err", UNKNOWN_ERROR); 497 498 response->postReply(mReplyID); 499 } 500 break; 501 } 502 503 case ACodec::kWhatComponentAllocated: 504 { 505 CHECK_EQ(mState, INITIALIZING); 506 setState(INITIALIZED); 507 508 AString componentName; 509 CHECK(msg->findString("componentName", &componentName)); 510 511 if (componentName.startsWith("OMX.google.")) { 512 mFlags |= kFlagIsSoftwareCodec; 513 } else { 514 mFlags &= ~kFlagIsSoftwareCodec; 515 } 516 517 if (componentName.endsWith(".secure")) { 518 mFlags |= kFlagIsSecure; 519 } else { 520 mFlags &= ~kFlagIsSecure; 521 } 522 523 (new AMessage)->postReply(mReplyID); 524 break; 525 } 526 527 case ACodec::kWhatComponentConfigured: 528 { 529 CHECK_EQ(mState, CONFIGURING); 530 setState(CONFIGURED); 531 532 (new AMessage)->postReply(mReplyID); 533 break; 534 } 535 536 case ACodec::kWhatBuffersAllocated: 537 { 538 int32_t portIndex; 539 CHECK(msg->findInt32("portIndex", &portIndex)); 540 541 ALOGV("%s buffers allocated", 542 portIndex == kPortIndexInput ? "input" : "output"); 543 544 CHECK(portIndex == kPortIndexInput 545 || portIndex == kPortIndexOutput); 546 547 mPortBuffers[portIndex].clear(); 548 549 Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 550 for (size_t i = 0;; ++i) { 551 AString name = StringPrintf("buffer-id_%d", i); 552 553 void *bufferID; 554 if (!msg->findPointer(name.c_str(), &bufferID)) { 555 break; 556 } 557 558 name = StringPrintf("data_%d", i); 559 560 BufferInfo info; 561 info.mBufferID = bufferID; 562 info.mOwnedByClient = false; 563 CHECK(msg->findBuffer(name.c_str(), &info.mData)); 564 565 if (portIndex == kPortIndexInput && mCrypto != NULL) { 566 info.mEncryptedData = 567 new ABuffer(info.mData->capacity()); 568 } 569 570 buffers->push_back(info); 571 } 572 573 if (portIndex == kPortIndexOutput) { 574 if (mState == STARTING) { 575 // We're always allocating output buffers after 576 // allocating input buffers, so this is a good 577 // indication that now all buffers are allocated. 578 setState(STARTED); 579 (new AMessage)->postReply(mReplyID); 580 } else { 581 mFlags |= kFlagOutputBuffersChanged; 582 } 583 } 584 break; 585 } 586 587 case ACodec::kWhatOutputFormatChanged: 588 { 589 ALOGV("codec output format changed"); 590 591 if ((mFlags & kFlagIsSoftwareCodec) 592 && mNativeWindow != NULL) { 593 AString mime; 594 CHECK(msg->findString("mime", &mime)); 595 596 if (!strncasecmp("video/", mime.c_str(), 6)) { 597 delete mSoftRenderer; 598 mSoftRenderer = NULL; 599 600 int32_t width, height; 601 CHECK(msg->findInt32("width", &width)); 602 CHECK(msg->findInt32("height", &height)); 603 604 int32_t colorFormat; 605 CHECK(msg->findInt32( 606 "color-format", &colorFormat)); 607 608 sp<MetaData> meta = new MetaData; 609 meta->setInt32(kKeyWidth, width); 610 meta->setInt32(kKeyHeight, height); 611 meta->setInt32(kKeyColorFormat, colorFormat); 612 613 mSoftRenderer = 614 new SoftwareRenderer(mNativeWindow, meta); 615 } 616 } 617 618 mOutputFormat = msg; 619 mFlags |= kFlagOutputFormatChanged; 620 break; 621 } 622 623 case ACodec::kWhatFillThisBuffer: 624 { 625 /* size_t index = */updateBuffers(kPortIndexInput, msg); 626 627 if (mState == FLUSHING 628 || mState == STOPPING 629 || mState == RELEASING) { 630 returnBuffersToCodecOnPort(kPortIndexInput); 631 break; 632 } 633 634 if (mFlags & kFlagDequeueInputPending) { 635 CHECK(handleDequeueInputBuffer(mDequeueInputReplyID)); 636 637 ++mDequeueInputTimeoutGeneration; 638 mFlags &= ~kFlagDequeueInputPending; 639 mDequeueInputReplyID = 0; 640 } 641 break; 642 } 643 644 case ACodec::kWhatDrainThisBuffer: 645 { 646 /* size_t index = */updateBuffers(kPortIndexOutput, msg); 647 648 if (mState == FLUSHING 649 || mState == STOPPING 650 || mState == RELEASING) { 651 returnBuffersToCodecOnPort(kPortIndexOutput); 652 break; 653 } 654 655 sp<ABuffer> buffer; 656 CHECK(msg->findBuffer("buffer", &buffer)); 657 658 int32_t omxFlags; 659 CHECK(msg->findInt32("flags", &omxFlags)); 660 661 buffer->meta()->setInt32("omxFlags", omxFlags); 662 663 if (mFlags & kFlagDequeueOutputPending) { 664 CHECK(handleDequeueOutputBuffer(mDequeueOutputReplyID)); 665 666 ++mDequeueOutputTimeoutGeneration; 667 mFlags &= ~kFlagDequeueOutputPending; 668 mDequeueOutputReplyID = 0; 669 } 670 break; 671 } 672 673 case ACodec::kWhatEOS: 674 { 675 // We already notify the client of this by using the 676 // corresponding flag in "onOutputBufferReady". 677 break; 678 } 679 680 case ACodec::kWhatShutdownCompleted: 681 { 682 if (mState == STOPPING) { 683 setState(INITIALIZED); 684 } else { 685 CHECK_EQ(mState, RELEASING); 686 setState(UNINITIALIZED); 687 } 688 689 (new AMessage)->postReply(mReplyID); 690 break; 691 } 692 693 case ACodec::kWhatFlushCompleted: 694 { 695 CHECK_EQ(mState, FLUSHING); 696 setState(STARTED); 697 698 mCodec->signalResume(); 699 700 (new AMessage)->postReply(mReplyID); 701 break; 702 } 703 704 default: 705 TRESPASS(); 706 } 707 break; 708 } 709 710 case kWhatInit: 711 { 712 uint32_t replyID; 713 CHECK(msg->senderAwaitsResponse(&replyID)); 714 715 if (mState != UNINITIALIZED) { 716 sp<AMessage> response = new AMessage; 717 response->setInt32("err", INVALID_OPERATION); 718 719 response->postReply(replyID); 720 break; 721 } 722 723 mReplyID = replyID; 724 setState(INITIALIZING); 725 726 AString name; 727 CHECK(msg->findString("name", &name)); 728 729 int32_t nameIsType; 730 int32_t encoder = false; 731 CHECK(msg->findInt32("nameIsType", &nameIsType)); 732 if (nameIsType) { 733 CHECK(msg->findInt32("encoder", &encoder)); 734 } 735 736 sp<AMessage> format = new AMessage; 737 738 if (nameIsType) { 739 format->setString("mime", name.c_str()); 740 format->setInt32("encoder", encoder); 741 } else { 742 format->setString("componentName", name.c_str()); 743 } 744 745 mCodec->initiateAllocateComponent(format); 746 break; 747 } 748 749 case kWhatConfigure: 750 { 751 uint32_t replyID; 752 CHECK(msg->senderAwaitsResponse(&replyID)); 753 754 if (mState != INITIALIZED) { 755 sp<AMessage> response = new AMessage; 756 response->setInt32("err", INVALID_OPERATION); 757 758 response->postReply(replyID); 759 break; 760 } 761 762 mReplyID = replyID; 763 setState(CONFIGURING); 764 765 sp<RefBase> obj; 766 if (!msg->findObject("native-window", &obj)) { 767 obj.clear(); 768 } 769 770 sp<AMessage> format; 771 CHECK(msg->findMessage("format", &format)); 772 773 if (obj != NULL) { 774 format->setObject("native-window", obj); 775 776 if (mFlags & kFlagIsSoftwareCodec) { 777 mNativeWindow = 778 static_cast<NativeWindowWrapper *>(obj.get()) 779 ->getSurfaceTextureClient(); 780 } 781 } else { 782 mNativeWindow.clear(); 783 } 784 785 void *crypto; 786 if (!msg->findPointer("crypto", &crypto)) { 787 crypto = NULL; 788 } 789 790 mCrypto = static_cast<ICrypto *>(crypto); 791 792 uint32_t flags; 793 CHECK(msg->findInt32("flags", (int32_t *)&flags)); 794 795 if (flags & CONFIGURE_FLAG_ENCODE) { 796 format->setInt32("encoder", true); 797 } 798 799 mCodec->initiateConfigureComponent(format); 800 break; 801 } 802 803 case kWhatStart: 804 { 805 uint32_t replyID; 806 CHECK(msg->senderAwaitsResponse(&replyID)); 807 808 if (mState != CONFIGURED) { 809 sp<AMessage> response = new AMessage; 810 response->setInt32("err", INVALID_OPERATION); 811 812 response->postReply(replyID); 813 break; 814 } 815 816 mReplyID = replyID; 817 setState(STARTING); 818 819 mCodec->initiateStart(); 820 break; 821 } 822 823 case kWhatStop: 824 { 825 uint32_t replyID; 826 CHECK(msg->senderAwaitsResponse(&replyID)); 827 828 if (mState != INITIALIZED 829 && mState != CONFIGURED && mState != STARTED) { 830 sp<AMessage> response = new AMessage; 831 response->setInt32("err", INVALID_OPERATION); 832 833 response->postReply(replyID); 834 break; 835 } 836 837 mReplyID = replyID; 838 setState(STOPPING); 839 840 mCodec->initiateShutdown(true /* keepComponentAllocated */); 841 returnBuffersToCodec(); 842 break; 843 } 844 845 case kWhatRelease: 846 { 847 uint32_t replyID; 848 CHECK(msg->senderAwaitsResponse(&replyID)); 849 850 if (mState != INITIALIZED 851 && mState != CONFIGURED && mState != STARTED) { 852 sp<AMessage> response = new AMessage; 853 response->setInt32("err", INVALID_OPERATION); 854 855 response->postReply(replyID); 856 break; 857 } 858 859 mReplyID = replyID; 860 setState(RELEASING); 861 862 mCodec->initiateShutdown(); 863 returnBuffersToCodec(); 864 break; 865 } 866 867 case kWhatDequeueInputBuffer: 868 { 869 uint32_t replyID; 870 CHECK(msg->senderAwaitsResponse(&replyID)); 871 872 if (handleDequeueInputBuffer(replyID, true /* new request */)) { 873 break; 874 } 875 876 int64_t timeoutUs; 877 CHECK(msg->findInt64("timeoutUs", &timeoutUs)); 878 879 if (timeoutUs == 0ll) { 880 sp<AMessage> response = new AMessage; 881 response->setInt32("err", -EAGAIN); 882 response->postReply(replyID); 883 break; 884 } 885 886 mFlags |= kFlagDequeueInputPending; 887 mDequeueInputReplyID = replyID; 888 889 if (timeoutUs > 0ll) { 890 sp<AMessage> timeoutMsg = 891 new AMessage(kWhatDequeueInputTimedOut, id()); 892 timeoutMsg->setInt32( 893 "generation", ++mDequeueInputTimeoutGeneration); 894 timeoutMsg->post(timeoutUs); 895 } 896 break; 897 } 898 899 case kWhatDequeueInputTimedOut: 900 { 901 int32_t generation; 902 CHECK(msg->findInt32("generation", &generation)); 903 904 if (generation != mDequeueInputTimeoutGeneration) { 905 // Obsolete 906 break; 907 } 908 909 CHECK(mFlags & kFlagDequeueInputPending); 910 911 sp<AMessage> response = new AMessage; 912 response->setInt32("err", -EAGAIN); 913 response->postReply(mDequeueInputReplyID); 914 915 mFlags &= ~kFlagDequeueInputPending; 916 mDequeueInputReplyID = 0; 917 break; 918 } 919 920 case kWhatQueueInputBuffer: 921 { 922 uint32_t replyID; 923 CHECK(msg->senderAwaitsResponse(&replyID)); 924 925 if (mState != STARTED || (mFlags & kFlagStickyError)) { 926 sp<AMessage> response = new AMessage; 927 response->setInt32("err", INVALID_OPERATION); 928 929 response->postReply(replyID); 930 break; 931 } 932 933 status_t err = onQueueInputBuffer(msg); 934 935 sp<AMessage> response = new AMessage; 936 response->setInt32("err", err); 937 response->postReply(replyID); 938 break; 939 } 940 941 case kWhatDequeueOutputBuffer: 942 { 943 uint32_t replyID; 944 CHECK(msg->senderAwaitsResponse(&replyID)); 945 946 if (handleDequeueOutputBuffer(replyID, true /* new request */)) { 947 break; 948 } 949 950 int64_t timeoutUs; 951 CHECK(msg->findInt64("timeoutUs", &timeoutUs)); 952 953 if (timeoutUs == 0ll) { 954 sp<AMessage> response = new AMessage; 955 response->setInt32("err", -EAGAIN); 956 response->postReply(replyID); 957 break; 958 } 959 960 mFlags |= kFlagDequeueOutputPending; 961 mDequeueOutputReplyID = replyID; 962 963 if (timeoutUs > 0ll) { 964 sp<AMessage> timeoutMsg = 965 new AMessage(kWhatDequeueOutputTimedOut, id()); 966 timeoutMsg->setInt32( 967 "generation", ++mDequeueOutputTimeoutGeneration); 968 timeoutMsg->post(timeoutUs); 969 } 970 break; 971 } 972 973 case kWhatDequeueOutputTimedOut: 974 { 975 int32_t generation; 976 CHECK(msg->findInt32("generation", &generation)); 977 978 if (generation != mDequeueOutputTimeoutGeneration) { 979 // Obsolete 980 break; 981 } 982 983 CHECK(mFlags & kFlagDequeueOutputPending); 984 985 sp<AMessage> response = new AMessage; 986 response->setInt32("err", -EAGAIN); 987 response->postReply(mDequeueOutputReplyID); 988 989 mFlags &= ~kFlagDequeueOutputPending; 990 mDequeueOutputReplyID = 0; 991 break; 992 } 993 994 case kWhatReleaseOutputBuffer: 995 { 996 uint32_t replyID; 997 CHECK(msg->senderAwaitsResponse(&replyID)); 998 999 if (mState != STARTED || (mFlags & kFlagStickyError)) { 1000 sp<AMessage> response = new AMessage; 1001 response->setInt32("err", INVALID_OPERATION); 1002 1003 response->postReply(replyID); 1004 break; 1005 } 1006 1007 status_t err = onReleaseOutputBuffer(msg); 1008 1009 sp<AMessage> response = new AMessage; 1010 response->setInt32("err", err); 1011 response->postReply(replyID); 1012 break; 1013 } 1014 1015 case kWhatGetBuffers: 1016 { 1017 uint32_t replyID; 1018 CHECK(msg->senderAwaitsResponse(&replyID)); 1019 1020 if (mState != STARTED || (mFlags & kFlagStickyError)) { 1021 sp<AMessage> response = new AMessage; 1022 response->setInt32("err", INVALID_OPERATION); 1023 1024 response->postReply(replyID); 1025 break; 1026 } 1027 1028 int32_t portIndex; 1029 CHECK(msg->findInt32("portIndex", &portIndex)); 1030 1031 Vector<sp<ABuffer> > *dstBuffers; 1032 CHECK(msg->findPointer("buffers", (void **)&dstBuffers)); 1033 1034 dstBuffers->clear(); 1035 const Vector<BufferInfo> &srcBuffers = mPortBuffers[portIndex]; 1036 1037 for (size_t i = 0; i < srcBuffers.size(); ++i) { 1038 const BufferInfo &info = srcBuffers.itemAt(i); 1039 1040 dstBuffers->push_back( 1041 (portIndex == kPortIndexInput && mCrypto != NULL) 1042 ? info.mEncryptedData : info.mData); 1043 } 1044 1045 (new AMessage)->postReply(replyID); 1046 break; 1047 } 1048 1049 case kWhatFlush: 1050 { 1051 uint32_t replyID; 1052 CHECK(msg->senderAwaitsResponse(&replyID)); 1053 1054 if (mState != STARTED || (mFlags & kFlagStickyError)) { 1055 sp<AMessage> response = new AMessage; 1056 response->setInt32("err", INVALID_OPERATION); 1057 1058 response->postReply(replyID); 1059 break; 1060 } 1061 1062 mReplyID = replyID; 1063 setState(FLUSHING); 1064 1065 mCodec->signalFlush(); 1066 returnBuffersToCodec(); 1067 break; 1068 } 1069 1070 case kWhatGetOutputFormat: 1071 { 1072 uint32_t replyID; 1073 CHECK(msg->senderAwaitsResponse(&replyID)); 1074 1075 if ((mState != STARTED && mState != FLUSHING) 1076 || (mFlags & kFlagStickyError)) { 1077 sp<AMessage> response = new AMessage; 1078 response->setInt32("err", INVALID_OPERATION); 1079 1080 response->postReply(replyID); 1081 break; 1082 } 1083 1084 sp<AMessage> response = new AMessage; 1085 response->setMessage("format", mOutputFormat); 1086 response->postReply(replyID); 1087 break; 1088 } 1089 1090 default: 1091 TRESPASS(); 1092 } 1093} 1094 1095void MediaCodec::setState(State newState) { 1096 if (newState == INITIALIZED) { 1097 delete mSoftRenderer; 1098 mSoftRenderer = NULL; 1099 1100 mCrypto.clear(); 1101 mNativeWindow.clear(); 1102 1103 mOutputFormat.clear(); 1104 mFlags &= ~kFlagOutputFormatChanged; 1105 mFlags &= ~kFlagOutputBuffersChanged; 1106 mFlags &= ~kFlagStickyError; 1107 } 1108 1109 mState = newState; 1110 1111 cancelPendingDequeueOperations(); 1112} 1113 1114void MediaCodec::returnBuffersToCodec() { 1115 returnBuffersToCodecOnPort(kPortIndexInput); 1116 returnBuffersToCodecOnPort(kPortIndexOutput); 1117} 1118 1119void MediaCodec::returnBuffersToCodecOnPort(int32_t portIndex) { 1120 CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 1121 1122 Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 1123 1124 for (size_t i = 0; i < buffers->size(); ++i) { 1125 BufferInfo *info = &buffers->editItemAt(i); 1126 1127 if (info->mNotify != NULL) { 1128 sp<AMessage> msg = info->mNotify; 1129 info->mNotify = NULL; 1130 info->mOwnedByClient = false; 1131 1132 if (portIndex == kPortIndexInput) { 1133 msg->setInt32("err", ERROR_END_OF_STREAM); 1134 } 1135 msg->post(); 1136 } 1137 } 1138 1139 mAvailPortBuffers[portIndex].clear(); 1140} 1141 1142size_t MediaCodec::updateBuffers( 1143 int32_t portIndex, const sp<AMessage> &msg) { 1144 CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 1145 1146 void *bufferID; 1147 CHECK(msg->findPointer("buffer-id", &bufferID)); 1148 1149 Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 1150 1151 for (size_t i = 0; i < buffers->size(); ++i) { 1152 BufferInfo *info = &buffers->editItemAt(i); 1153 1154 if (info->mBufferID == bufferID) { 1155 CHECK(info->mNotify == NULL); 1156 CHECK(msg->findMessage("reply", &info->mNotify)); 1157 1158 mAvailPortBuffers[portIndex].push_back(i); 1159 1160 return i; 1161 } 1162 } 1163 1164 TRESPASS(); 1165 1166 return 0; 1167} 1168 1169status_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) { 1170 size_t index; 1171 size_t offset; 1172 size_t size; 1173 int64_t timeUs; 1174 uint32_t flags; 1175 CHECK(msg->findSize("index", &index)); 1176 CHECK(msg->findSize("offset", &offset)); 1177 CHECK(msg->findInt64("timeUs", &timeUs)); 1178 CHECK(msg->findInt32("flags", (int32_t *)&flags)); 1179 1180 const CryptoPlugin::SubSample *subSamples; 1181 size_t numSubSamples; 1182 const uint8_t *key; 1183 const uint8_t *iv; 1184 CryptoPlugin::Mode mode = CryptoPlugin::kMode_Unencrypted; 1185 1186 // We allow the simpler queueInputBuffer API to be used even in 1187 // secure mode, by fabricating a single unencrypted subSample. 1188 CryptoPlugin::SubSample ss; 1189 1190 if (msg->findSize("size", &size)) { 1191 if (mCrypto != NULL) { 1192 ss.mNumBytesOfClearData = size; 1193 ss.mNumBytesOfEncryptedData = 0; 1194 1195 subSamples = &ss; 1196 numSubSamples = 1; 1197 key = NULL; 1198 iv = NULL; 1199 } 1200 } else { 1201 if (mCrypto == NULL) { 1202 return -EINVAL; 1203 } 1204 1205 CHECK(msg->findPointer("subSamples", (void **)&subSamples)); 1206 CHECK(msg->findSize("numSubSamples", &numSubSamples)); 1207 CHECK(msg->findPointer("key", (void **)&key)); 1208 CHECK(msg->findPointer("iv", (void **)&iv)); 1209 1210 int32_t tmp; 1211 CHECK(msg->findInt32("mode", &tmp)); 1212 1213 mode = (CryptoPlugin::Mode)tmp; 1214 1215 size = 0; 1216 for (size_t i = 0; i < numSubSamples; ++i) { 1217 size += subSamples[i].mNumBytesOfClearData; 1218 size += subSamples[i].mNumBytesOfEncryptedData; 1219 } 1220 } 1221 1222 if (index >= mPortBuffers[kPortIndexInput].size()) { 1223 return -ERANGE; 1224 } 1225 1226 BufferInfo *info = &mPortBuffers[kPortIndexInput].editItemAt(index); 1227 1228 if (info->mNotify == NULL || !info->mOwnedByClient) { 1229 return -EACCES; 1230 } 1231 1232 if (offset + size > info->mData->capacity()) { 1233 return -EINVAL; 1234 } 1235 1236 sp<AMessage> reply = info->mNotify; 1237 info->mNotify = NULL; 1238 info->mOwnedByClient = false; 1239 1240 info->mData->setRange(offset, size); 1241 info->mData->meta()->setInt64("timeUs", timeUs); 1242 1243 if (flags & BUFFER_FLAG_EOS) { 1244 info->mData->meta()->setInt32("eos", true); 1245 } 1246 1247 if (flags & BUFFER_FLAG_CODECCONFIG) { 1248 info->mData->meta()->setInt32("csd", true); 1249 } 1250 1251 if (mCrypto != NULL) { 1252 if (size > info->mEncryptedData->capacity()) { 1253 return -ERANGE; 1254 } 1255 1256 status_t err = mCrypto->decrypt( 1257 (mFlags & kFlagIsSecure) != 0, 1258 key, 1259 iv, 1260 mode, 1261 info->mEncryptedData->base() + offset, 1262 subSamples, 1263 numSubSamples, 1264 info->mData->base()); 1265 1266 if (err != OK) { 1267 return err; 1268 } 1269 1270 info->mData->setRange(0, size); 1271 } 1272 1273 reply->setBuffer("buffer", info->mData); 1274 reply->post(); 1275 1276 return OK; 1277} 1278 1279status_t MediaCodec::onReleaseOutputBuffer(const sp<AMessage> &msg) { 1280 size_t index; 1281 CHECK(msg->findSize("index", &index)); 1282 1283 int32_t render; 1284 if (!msg->findInt32("render", &render)) { 1285 render = 0; 1286 } 1287 1288 if (mState != STARTED) { 1289 return -EINVAL; 1290 } 1291 1292 if (index >= mPortBuffers[kPortIndexOutput].size()) { 1293 return -ERANGE; 1294 } 1295 1296 BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index); 1297 1298 if (info->mNotify == NULL || !info->mOwnedByClient) { 1299 return -EACCES; 1300 } 1301 1302 if (render) { 1303 info->mNotify->setInt32("render", true); 1304 1305 if (mSoftRenderer != NULL) { 1306 mSoftRenderer->render( 1307 info->mData->data(), info->mData->size(), NULL); 1308 } 1309 } 1310 1311 info->mNotify->post(); 1312 info->mNotify = NULL; 1313 info->mOwnedByClient = false; 1314 1315 return OK; 1316} 1317 1318ssize_t MediaCodec::dequeuePortBuffer(int32_t portIndex) { 1319 CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 1320 1321 List<size_t> *availBuffers = &mAvailPortBuffers[portIndex]; 1322 1323 if (availBuffers->empty()) { 1324 return -EAGAIN; 1325 } 1326 1327 size_t index = *availBuffers->begin(); 1328 availBuffers->erase(availBuffers->begin()); 1329 1330 BufferInfo *info = &mPortBuffers[portIndex].editItemAt(index); 1331 CHECK(!info->mOwnedByClient); 1332 info->mOwnedByClient = true; 1333 1334 return index; 1335} 1336 1337} // namespace android 1338