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