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