MediaCodec.cpp revision 5b8987e7de9d04b09153f329c680d2316cdb44ec
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 37namespace android { 38 39// static 40sp<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 51sp<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 61MediaCodec::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 73MediaCodec::~MediaCodec() { 74 CHECK_EQ(mState, UNINITIALIZED); 75} 76 77// static 78status_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 93status_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 133status_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 157status_t MediaCodec::start() { 158 sp<AMessage> msg = new AMessage(kWhatStart, id()); 159 160 sp<AMessage> response; 161 return PostAndAwaitResponse(msg, &response); 162} 163 164status_t MediaCodec::stop() { 165 sp<AMessage> msg = new AMessage(kWhatStop, id()); 166 167 sp<AMessage> response; 168 return PostAndAwaitResponse(msg, &response); 169} 170 171status_t MediaCodec::release() { 172 sp<AMessage> msg = new AMessage(kWhatRelease, id()); 173 174 sp<AMessage> response; 175 return PostAndAwaitResponse(msg, &response); 176} 177 178status_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 201status_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 234status_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 249status_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 274status_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 283status_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 291status_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 305status_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 314status_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 323status_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 332void 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 354bool 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 380bool 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 435void 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 for (size_t i = 0;; ++i) { 566 AString name = StringPrintf("buffer-id_%d", i); 567 568 void *bufferID; 569 if (!msg->findPointer(name.c_str(), &bufferID)) { 570 break; 571 } 572 573 name = StringPrintf("data_%d", i); 574 575 BufferInfo info; 576 info.mBufferID = bufferID; 577 info.mOwnedByClient = false; 578 CHECK(msg->findBuffer(name.c_str(), &info.mData)); 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 (mFlags & kFlagDequeueInputPending) { 650 CHECK(handleDequeueInputBuffer(mDequeueInputReplyID)); 651 652 ++mDequeueInputTimeoutGeneration; 653 mFlags &= ~kFlagDequeueInputPending; 654 mDequeueInputReplyID = 0; 655 } 656 break; 657 } 658 659 case ACodec::kWhatDrainThisBuffer: 660 { 661 /* size_t index = */updateBuffers(kPortIndexOutput, msg); 662 663 if (mState == FLUSHING 664 || mState == STOPPING 665 || mState == RELEASING) { 666 returnBuffersToCodecOnPort(kPortIndexOutput); 667 break; 668 } 669 670 sp<ABuffer> buffer; 671 CHECK(msg->findBuffer("buffer", &buffer)); 672 673 int32_t omxFlags; 674 CHECK(msg->findInt32("flags", &omxFlags)); 675 676 buffer->meta()->setInt32("omxFlags", omxFlags); 677 678 if (mFlags & kFlagDequeueOutputPending) { 679 CHECK(handleDequeueOutputBuffer(mDequeueOutputReplyID)); 680 681 ++mDequeueOutputTimeoutGeneration; 682 mFlags &= ~kFlagDequeueOutputPending; 683 mDequeueOutputReplyID = 0; 684 } 685 break; 686 } 687 688 case ACodec::kWhatEOS: 689 { 690 // We already notify the client of this by using the 691 // corresponding flag in "onOutputBufferReady". 692 break; 693 } 694 695 case ACodec::kWhatShutdownCompleted: 696 { 697 if (mState == STOPPING) { 698 setState(INITIALIZED); 699 } else { 700 CHECK_EQ(mState, RELEASING); 701 setState(UNINITIALIZED); 702 } 703 704 (new AMessage)->postReply(mReplyID); 705 break; 706 } 707 708 case ACodec::kWhatFlushCompleted: 709 { 710 CHECK_EQ(mState, FLUSHING); 711 setState(STARTED); 712 713 mCodec->signalResume(); 714 715 (new AMessage)->postReply(mReplyID); 716 break; 717 } 718 719 default: 720 TRESPASS(); 721 } 722 break; 723 } 724 725 case kWhatInit: 726 { 727 uint32_t replyID; 728 CHECK(msg->senderAwaitsResponse(&replyID)); 729 730 if (mState != UNINITIALIZED) { 731 sp<AMessage> response = new AMessage; 732 response->setInt32("err", INVALID_OPERATION); 733 734 response->postReply(replyID); 735 break; 736 } 737 738 mReplyID = replyID; 739 setState(INITIALIZING); 740 741 AString name; 742 CHECK(msg->findString("name", &name)); 743 744 int32_t nameIsType; 745 int32_t encoder = false; 746 CHECK(msg->findInt32("nameIsType", &nameIsType)); 747 if (nameIsType) { 748 CHECK(msg->findInt32("encoder", &encoder)); 749 } 750 751 sp<AMessage> format = new AMessage; 752 753 if (nameIsType) { 754 format->setString("mime", name.c_str()); 755 format->setInt32("encoder", encoder); 756 } else { 757 format->setString("componentName", name.c_str()); 758 } 759 760 mCodec->initiateAllocateComponent(format); 761 break; 762 } 763 764 case kWhatConfigure: 765 { 766 uint32_t replyID; 767 CHECK(msg->senderAwaitsResponse(&replyID)); 768 769 if (mState != INITIALIZED) { 770 sp<AMessage> response = new AMessage; 771 response->setInt32("err", INVALID_OPERATION); 772 773 response->postReply(replyID); 774 break; 775 } 776 777 mReplyID = replyID; 778 setState(CONFIGURING); 779 780 sp<RefBase> obj; 781 if (!msg->findObject("native-window", &obj)) { 782 obj.clear(); 783 } 784 785 sp<AMessage> format; 786 CHECK(msg->findMessage("format", &format)); 787 788 if (obj != NULL) { 789 format->setObject("native-window", obj); 790 791 if (mFlags & kFlagIsSoftwareCodec) { 792 mNativeWindow = 793 static_cast<NativeWindowWrapper *>(obj.get()) 794 ->getSurfaceTextureClient(); 795 } 796 } else { 797 mNativeWindow.clear(); 798 } 799 800 void *crypto; 801 if (!msg->findPointer("crypto", &crypto)) { 802 crypto = NULL; 803 } 804 805 mCrypto = static_cast<ICrypto *>(crypto); 806 807 uint32_t flags; 808 CHECK(msg->findInt32("flags", (int32_t *)&flags)); 809 810 if (flags & CONFIGURE_FLAG_ENCODE) { 811 format->setInt32("encoder", true); 812 } 813 814 mCodec->initiateConfigureComponent(format); 815 break; 816 } 817 818 case kWhatStart: 819 { 820 uint32_t replyID; 821 CHECK(msg->senderAwaitsResponse(&replyID)); 822 823 if (mState != CONFIGURED) { 824 sp<AMessage> response = new AMessage; 825 response->setInt32("err", INVALID_OPERATION); 826 827 response->postReply(replyID); 828 break; 829 } 830 831 mReplyID = replyID; 832 setState(STARTING); 833 834 mCodec->initiateStart(); 835 break; 836 } 837 838 case kWhatStop: 839 { 840 uint32_t replyID; 841 CHECK(msg->senderAwaitsResponse(&replyID)); 842 843 if (mState != INITIALIZED 844 && mState != CONFIGURED && mState != STARTED) { 845 sp<AMessage> response = new AMessage; 846 response->setInt32("err", INVALID_OPERATION); 847 848 response->postReply(replyID); 849 break; 850 } 851 852 mReplyID = replyID; 853 setState(STOPPING); 854 855 mCodec->initiateShutdown(true /* keepComponentAllocated */); 856 returnBuffersToCodec(); 857 break; 858 } 859 860 case kWhatRelease: 861 { 862 uint32_t replyID; 863 CHECK(msg->senderAwaitsResponse(&replyID)); 864 865 if (mState != INITIALIZED 866 && mState != CONFIGURED && mState != STARTED) { 867 sp<AMessage> response = new AMessage; 868 response->setInt32("err", INVALID_OPERATION); 869 870 response->postReply(replyID); 871 break; 872 } 873 874 mReplyID = replyID; 875 setState(RELEASING); 876 877 mCodec->initiateShutdown(); 878 returnBuffersToCodec(); 879 break; 880 } 881 882 case kWhatDequeueInputBuffer: 883 { 884 uint32_t replyID; 885 CHECK(msg->senderAwaitsResponse(&replyID)); 886 887 if (handleDequeueInputBuffer(replyID, true /* new request */)) { 888 break; 889 } 890 891 int64_t timeoutUs; 892 CHECK(msg->findInt64("timeoutUs", &timeoutUs)); 893 894 if (timeoutUs == 0ll) { 895 sp<AMessage> response = new AMessage; 896 response->setInt32("err", -EAGAIN); 897 response->postReply(replyID); 898 break; 899 } 900 901 mFlags |= kFlagDequeueInputPending; 902 mDequeueInputReplyID = replyID; 903 904 if (timeoutUs > 0ll) { 905 sp<AMessage> timeoutMsg = 906 new AMessage(kWhatDequeueInputTimedOut, id()); 907 timeoutMsg->setInt32( 908 "generation", ++mDequeueInputTimeoutGeneration); 909 timeoutMsg->post(timeoutUs); 910 } 911 break; 912 } 913 914 case kWhatDequeueInputTimedOut: 915 { 916 int32_t generation; 917 CHECK(msg->findInt32("generation", &generation)); 918 919 if (generation != mDequeueInputTimeoutGeneration) { 920 // Obsolete 921 break; 922 } 923 924 CHECK(mFlags & kFlagDequeueInputPending); 925 926 sp<AMessage> response = new AMessage; 927 response->setInt32("err", -EAGAIN); 928 response->postReply(mDequeueInputReplyID); 929 930 mFlags &= ~kFlagDequeueInputPending; 931 mDequeueInputReplyID = 0; 932 break; 933 } 934 935 case kWhatQueueInputBuffer: 936 { 937 uint32_t replyID; 938 CHECK(msg->senderAwaitsResponse(&replyID)); 939 940 if (mState != STARTED || (mFlags & kFlagStickyError)) { 941 sp<AMessage> response = new AMessage; 942 response->setInt32("err", INVALID_OPERATION); 943 944 response->postReply(replyID); 945 break; 946 } 947 948 status_t err = onQueueInputBuffer(msg); 949 950 sp<AMessage> response = new AMessage; 951 response->setInt32("err", err); 952 response->postReply(replyID); 953 break; 954 } 955 956 case kWhatDequeueOutputBuffer: 957 { 958 uint32_t replyID; 959 CHECK(msg->senderAwaitsResponse(&replyID)); 960 961 if (handleDequeueOutputBuffer(replyID, true /* new request */)) { 962 break; 963 } 964 965 int64_t timeoutUs; 966 CHECK(msg->findInt64("timeoutUs", &timeoutUs)); 967 968 if (timeoutUs == 0ll) { 969 sp<AMessage> response = new AMessage; 970 response->setInt32("err", -EAGAIN); 971 response->postReply(replyID); 972 break; 973 } 974 975 mFlags |= kFlagDequeueOutputPending; 976 mDequeueOutputReplyID = replyID; 977 978 if (timeoutUs > 0ll) { 979 sp<AMessage> timeoutMsg = 980 new AMessage(kWhatDequeueOutputTimedOut, id()); 981 timeoutMsg->setInt32( 982 "generation", ++mDequeueOutputTimeoutGeneration); 983 timeoutMsg->post(timeoutUs); 984 } 985 break; 986 } 987 988 case kWhatDequeueOutputTimedOut: 989 { 990 int32_t generation; 991 CHECK(msg->findInt32("generation", &generation)); 992 993 if (generation != mDequeueOutputTimeoutGeneration) { 994 // Obsolete 995 break; 996 } 997 998 CHECK(mFlags & kFlagDequeueOutputPending); 999 1000 sp<AMessage> response = new AMessage; 1001 response->setInt32("err", -EAGAIN); 1002 response->postReply(mDequeueOutputReplyID); 1003 1004 mFlags &= ~kFlagDequeueOutputPending; 1005 mDequeueOutputReplyID = 0; 1006 break; 1007 } 1008 1009 case kWhatReleaseOutputBuffer: 1010 { 1011 uint32_t replyID; 1012 CHECK(msg->senderAwaitsResponse(&replyID)); 1013 1014 if (mState != STARTED || (mFlags & kFlagStickyError)) { 1015 sp<AMessage> response = new AMessage; 1016 response->setInt32("err", INVALID_OPERATION); 1017 1018 response->postReply(replyID); 1019 break; 1020 } 1021 1022 status_t err = onReleaseOutputBuffer(msg); 1023 1024 sp<AMessage> response = new AMessage; 1025 response->setInt32("err", err); 1026 response->postReply(replyID); 1027 break; 1028 } 1029 1030 case kWhatGetBuffers: 1031 { 1032 uint32_t replyID; 1033 CHECK(msg->senderAwaitsResponse(&replyID)); 1034 1035 if (mState != STARTED || (mFlags & kFlagStickyError)) { 1036 sp<AMessage> response = new AMessage; 1037 response->setInt32("err", INVALID_OPERATION); 1038 1039 response->postReply(replyID); 1040 break; 1041 } 1042 1043 int32_t portIndex; 1044 CHECK(msg->findInt32("portIndex", &portIndex)); 1045 1046 Vector<sp<ABuffer> > *dstBuffers; 1047 CHECK(msg->findPointer("buffers", (void **)&dstBuffers)); 1048 1049 dstBuffers->clear(); 1050 const Vector<BufferInfo> &srcBuffers = mPortBuffers[portIndex]; 1051 1052 for (size_t i = 0; i < srcBuffers.size(); ++i) { 1053 const BufferInfo &info = srcBuffers.itemAt(i); 1054 1055 dstBuffers->push_back( 1056 (portIndex == kPortIndexInput && mCrypto != NULL) 1057 ? info.mEncryptedData : info.mData); 1058 } 1059 1060 (new AMessage)->postReply(replyID); 1061 break; 1062 } 1063 1064 case kWhatFlush: 1065 { 1066 uint32_t replyID; 1067 CHECK(msg->senderAwaitsResponse(&replyID)); 1068 1069 if (mState != STARTED || (mFlags & kFlagStickyError)) { 1070 sp<AMessage> response = new AMessage; 1071 response->setInt32("err", INVALID_OPERATION); 1072 1073 response->postReply(replyID); 1074 break; 1075 } 1076 1077 mReplyID = replyID; 1078 setState(FLUSHING); 1079 1080 mCodec->signalFlush(); 1081 returnBuffersToCodec(); 1082 break; 1083 } 1084 1085 case kWhatGetOutputFormat: 1086 { 1087 uint32_t replyID; 1088 CHECK(msg->senderAwaitsResponse(&replyID)); 1089 1090 if ((mState != STARTED && mState != FLUSHING) 1091 || (mFlags & kFlagStickyError)) { 1092 sp<AMessage> response = new AMessage; 1093 response->setInt32("err", INVALID_OPERATION); 1094 1095 response->postReply(replyID); 1096 break; 1097 } 1098 1099 sp<AMessage> response = new AMessage; 1100 response->setMessage("format", mOutputFormat); 1101 response->postReply(replyID); 1102 break; 1103 } 1104 1105 default: 1106 TRESPASS(); 1107 } 1108} 1109 1110void MediaCodec::setState(State newState) { 1111 if (newState == INITIALIZED) { 1112 delete mSoftRenderer; 1113 mSoftRenderer = NULL; 1114 1115 mCrypto.clear(); 1116 mNativeWindow.clear(); 1117 1118 mOutputFormat.clear(); 1119 mFlags &= ~kFlagOutputFormatChanged; 1120 mFlags &= ~kFlagOutputBuffersChanged; 1121 mFlags &= ~kFlagStickyError; 1122 } 1123 1124 mState = newState; 1125 1126 cancelPendingDequeueOperations(); 1127} 1128 1129void MediaCodec::returnBuffersToCodec() { 1130 returnBuffersToCodecOnPort(kPortIndexInput); 1131 returnBuffersToCodecOnPort(kPortIndexOutput); 1132} 1133 1134void MediaCodec::returnBuffersToCodecOnPort(int32_t portIndex) { 1135 CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 1136 1137 Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 1138 1139 for (size_t i = 0; i < buffers->size(); ++i) { 1140 BufferInfo *info = &buffers->editItemAt(i); 1141 1142 if (info->mNotify != NULL) { 1143 sp<AMessage> msg = info->mNotify; 1144 info->mNotify = NULL; 1145 info->mOwnedByClient = false; 1146 1147 if (portIndex == kPortIndexInput) { 1148 msg->setInt32("err", ERROR_END_OF_STREAM); 1149 } 1150 msg->post(); 1151 } 1152 } 1153 1154 mAvailPortBuffers[portIndex].clear(); 1155} 1156 1157size_t MediaCodec::updateBuffers( 1158 int32_t portIndex, const sp<AMessage> &msg) { 1159 CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 1160 1161 void *bufferID; 1162 CHECK(msg->findPointer("buffer-id", &bufferID)); 1163 1164 Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 1165 1166 for (size_t i = 0; i < buffers->size(); ++i) { 1167 BufferInfo *info = &buffers->editItemAt(i); 1168 1169 if (info->mBufferID == bufferID) { 1170 CHECK(info->mNotify == NULL); 1171 CHECK(msg->findMessage("reply", &info->mNotify)); 1172 1173 mAvailPortBuffers[portIndex].push_back(i); 1174 1175 return i; 1176 } 1177 } 1178 1179 TRESPASS(); 1180 1181 return 0; 1182} 1183 1184status_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) { 1185 size_t index; 1186 size_t offset; 1187 size_t size; 1188 int64_t timeUs; 1189 uint32_t flags; 1190 CHECK(msg->findSize("index", &index)); 1191 CHECK(msg->findSize("offset", &offset)); 1192 CHECK(msg->findInt64("timeUs", &timeUs)); 1193 CHECK(msg->findInt32("flags", (int32_t *)&flags)); 1194 1195 const CryptoPlugin::SubSample *subSamples; 1196 size_t numSubSamples; 1197 const uint8_t *key; 1198 const uint8_t *iv; 1199 CryptoPlugin::Mode mode = CryptoPlugin::kMode_Unencrypted; 1200 1201 // We allow the simpler queueInputBuffer API to be used even in 1202 // secure mode, by fabricating a single unencrypted subSample. 1203 CryptoPlugin::SubSample ss; 1204 1205 if (msg->findSize("size", &size)) { 1206 if (mCrypto != NULL) { 1207 ss.mNumBytesOfClearData = size; 1208 ss.mNumBytesOfEncryptedData = 0; 1209 1210 subSamples = &ss; 1211 numSubSamples = 1; 1212 key = NULL; 1213 iv = NULL; 1214 } 1215 } else { 1216 if (mCrypto == NULL) { 1217 return -EINVAL; 1218 } 1219 1220 CHECK(msg->findPointer("subSamples", (void **)&subSamples)); 1221 CHECK(msg->findSize("numSubSamples", &numSubSamples)); 1222 CHECK(msg->findPointer("key", (void **)&key)); 1223 CHECK(msg->findPointer("iv", (void **)&iv)); 1224 1225 int32_t tmp; 1226 CHECK(msg->findInt32("mode", &tmp)); 1227 1228 mode = (CryptoPlugin::Mode)tmp; 1229 1230 size = 0; 1231 for (size_t i = 0; i < numSubSamples; ++i) { 1232 size += subSamples[i].mNumBytesOfClearData; 1233 size += subSamples[i].mNumBytesOfEncryptedData; 1234 } 1235 } 1236 1237 if (index >= mPortBuffers[kPortIndexInput].size()) { 1238 return -ERANGE; 1239 } 1240 1241 BufferInfo *info = &mPortBuffers[kPortIndexInput].editItemAt(index); 1242 1243 if (info->mNotify == NULL || !info->mOwnedByClient) { 1244 return -EACCES; 1245 } 1246 1247 if (offset + size > info->mData->capacity()) { 1248 return -EINVAL; 1249 } 1250 1251 sp<AMessage> reply = info->mNotify; 1252 info->mData->setRange(offset, size); 1253 info->mData->meta()->setInt64("timeUs", timeUs); 1254 1255 if (flags & BUFFER_FLAG_EOS) { 1256 info->mData->meta()->setInt32("eos", true); 1257 } 1258 1259 if (flags & BUFFER_FLAG_CODECCONFIG) { 1260 info->mData->meta()->setInt32("csd", true); 1261 } 1262 1263 if (mCrypto != NULL) { 1264 if (size > info->mEncryptedData->capacity()) { 1265 return -ERANGE; 1266 } 1267 1268 AString *errorDetailMsg; 1269 CHECK(msg->findPointer("errorDetailMsg", (void **)&errorDetailMsg)); 1270 1271 status_t err = mCrypto->decrypt( 1272 (mFlags & kFlagIsSecure) != 0, 1273 key, 1274 iv, 1275 mode, 1276 info->mEncryptedData->base() + offset, 1277 subSamples, 1278 numSubSamples, 1279 info->mData->base(), 1280 errorDetailMsg); 1281 1282 if (err != OK) { 1283 return err; 1284 } 1285 1286 info->mData->setRange(0, size); 1287 } 1288 1289 reply->setBuffer("buffer", info->mData); 1290 reply->post(); 1291 1292 info->mNotify = NULL; 1293 info->mOwnedByClient = false; 1294 1295 return OK; 1296} 1297 1298status_t MediaCodec::onReleaseOutputBuffer(const sp<AMessage> &msg) { 1299 size_t index; 1300 CHECK(msg->findSize("index", &index)); 1301 1302 int32_t render; 1303 if (!msg->findInt32("render", &render)) { 1304 render = 0; 1305 } 1306 1307 if (mState != STARTED) { 1308 return -EINVAL; 1309 } 1310 1311 if (index >= mPortBuffers[kPortIndexOutput].size()) { 1312 return -ERANGE; 1313 } 1314 1315 BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index); 1316 1317 if (info->mNotify == NULL || !info->mOwnedByClient) { 1318 return -EACCES; 1319 } 1320 1321 if (render) { 1322 info->mNotify->setInt32("render", true); 1323 1324 if (mSoftRenderer != NULL) { 1325 mSoftRenderer->render( 1326 info->mData->data(), info->mData->size(), NULL); 1327 } 1328 } 1329 1330 info->mNotify->post(); 1331 info->mNotify = NULL; 1332 info->mOwnedByClient = false; 1333 1334 return OK; 1335} 1336 1337ssize_t MediaCodec::dequeuePortBuffer(int32_t portIndex) { 1338 CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 1339 1340 List<size_t> *availBuffers = &mAvailPortBuffers[portIndex]; 1341 1342 if (availBuffers->empty()) { 1343 return -EAGAIN; 1344 } 1345 1346 size_t index = *availBuffers->begin(); 1347 availBuffers->erase(availBuffers->begin()); 1348 1349 BufferInfo *info = &mPortBuffers[portIndex].editItemAt(index); 1350 CHECK(!info->mOwnedByClient); 1351 info->mOwnedByClient = true; 1352 1353 return index; 1354} 1355 1356} // namespace android 1357