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