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/Surface.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/BufferProducerWrapper.h> 34 #include <media/stagefright/MediaCodecList.h> 35 #include <media/stagefright/MediaDefs.h> 36 #include <media/stagefright/MediaErrors.h> 37 #include <media/stagefright/MetaData.h> 38 #include <media/stagefright/NativeWindowWrapper.h> 39 40 #include "include/avc_utils.h" 41 42 namespace android { 43 44 // static 45 sp<MediaCodec> MediaCodec::CreateByType( 46 const sp<ALooper> &looper, const char *mime, bool encoder) { 47 sp<MediaCodec> codec = new MediaCodec(looper); 48 if (codec->init(mime, true /* nameIsType */, encoder) != OK) { 49 return NULL; 50 } 51 52 return codec; 53 } 54 55 // static 56 sp<MediaCodec> MediaCodec::CreateByComponentName( 57 const sp<ALooper> &looper, const char *name) { 58 sp<MediaCodec> codec = new MediaCodec(looper); 59 if (codec->init(name, false /* nameIsType */, false /* encoder */) != OK) { 60 return NULL; 61 } 62 63 return codec; 64 } 65 66 MediaCodec::MediaCodec(const sp<ALooper> &looper) 67 : mState(UNINITIALIZED), 68 mLooper(looper), 69 mCodec(new ACodec), 70 mReplyID(0), 71 mFlags(0), 72 mSoftRenderer(NULL), 73 mDequeueInputTimeoutGeneration(0), 74 mDequeueInputReplyID(0), 75 mDequeueOutputTimeoutGeneration(0), 76 mDequeueOutputReplyID(0), 77 mHaveInputSurface(false) { 78 } 79 80 MediaCodec::~MediaCodec() { 81 CHECK_EQ(mState, UNINITIALIZED); 82 } 83 84 // static 85 status_t MediaCodec::PostAndAwaitResponse( 86 const sp<AMessage> &msg, sp<AMessage> *response) { 87 status_t err = msg->postAndAwaitResponse(response); 88 89 if (err != OK) { 90 return err; 91 } 92 93 if (!(*response)->findInt32("err", &err)) { 94 err = OK; 95 } 96 97 return err; 98 } 99 100 status_t MediaCodec::init(const char *name, bool nameIsType, bool encoder) { 101 // Current video decoders do not return from OMX_FillThisBuffer 102 // quickly, violating the OpenMAX specs, until that is remedied 103 // we need to invest in an extra looper to free the main event 104 // queue. 105 bool needDedicatedLooper = false; 106 if (nameIsType && !strncasecmp(name, "video/", 6)) { 107 needDedicatedLooper = true; 108 } else { 109 AString tmp = name; 110 if (tmp.endsWith(".secure")) { 111 tmp.erase(tmp.size() - 7, 7); 112 } 113 const MediaCodecList *mcl = MediaCodecList::getInstance(); 114 ssize_t codecIdx = mcl->findCodecByName(tmp.c_str()); 115 if (codecIdx >= 0) { 116 Vector<AString> types; 117 if (mcl->getSupportedTypes(codecIdx, &types) == OK) { 118 for (int i = 0; i < types.size(); i++) { 119 if (types[i].startsWith("video/")) { 120 needDedicatedLooper = true; 121 break; 122 } 123 } 124 } 125 } 126 } 127 128 if (needDedicatedLooper) { 129 if (mCodecLooper == NULL) { 130 mCodecLooper = new ALooper; 131 mCodecLooper->setName("CodecLooper"); 132 mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO); 133 } 134 135 mCodecLooper->registerHandler(mCodec); 136 } else { 137 mLooper->registerHandler(mCodec); 138 } 139 140 mLooper->registerHandler(this); 141 142 mCodec->setNotificationMessage(new AMessage(kWhatCodecNotify, id())); 143 144 sp<AMessage> msg = new AMessage(kWhatInit, id()); 145 msg->setString("name", name); 146 msg->setInt32("nameIsType", nameIsType); 147 148 if (nameIsType) { 149 msg->setInt32("encoder", encoder); 150 } 151 152 sp<AMessage> response; 153 return PostAndAwaitResponse(msg, &response); 154 } 155 156 status_t MediaCodec::configure( 157 const sp<AMessage> &format, 158 const sp<Surface> &nativeWindow, 159 const sp<ICrypto> &crypto, 160 uint32_t flags) { 161 sp<AMessage> msg = new AMessage(kWhatConfigure, id()); 162 163 msg->setMessage("format", format); 164 msg->setInt32("flags", flags); 165 166 if (nativeWindow != NULL) { 167 msg->setObject( 168 "native-window", 169 new NativeWindowWrapper(nativeWindow)); 170 } 171 172 if (crypto != NULL) { 173 msg->setPointer("crypto", crypto.get()); 174 } 175 176 sp<AMessage> response; 177 return PostAndAwaitResponse(msg, &response); 178 } 179 180 status_t MediaCodec::createInputSurface( 181 sp<IGraphicBufferProducer>* bufferProducer) { 182 sp<AMessage> msg = new AMessage(kWhatCreateInputSurface, id()); 183 184 sp<AMessage> response; 185 status_t err = PostAndAwaitResponse(msg, &response); 186 if (err == NO_ERROR) { 187 // unwrap the sp<IGraphicBufferProducer> 188 sp<RefBase> obj; 189 bool found = response->findObject("input-surface", &obj); 190 CHECK(found); 191 sp<BufferProducerWrapper> wrapper( 192 static_cast<BufferProducerWrapper*>(obj.get())); 193 *bufferProducer = wrapper->getBufferProducer(); 194 } else { 195 ALOGW("createInputSurface failed, err=%d", err); 196 } 197 return err; 198 } 199 200 status_t MediaCodec::start() { 201 sp<AMessage> msg = new AMessage(kWhatStart, id()); 202 203 sp<AMessage> response; 204 return PostAndAwaitResponse(msg, &response); 205 } 206 207 status_t MediaCodec::stop() { 208 sp<AMessage> msg = new AMessage(kWhatStop, id()); 209 210 sp<AMessage> response; 211 return PostAndAwaitResponse(msg, &response); 212 } 213 214 status_t MediaCodec::release() { 215 sp<AMessage> msg = new AMessage(kWhatRelease, id()); 216 217 sp<AMessage> response; 218 return PostAndAwaitResponse(msg, &response); 219 } 220 221 status_t MediaCodec::queueInputBuffer( 222 size_t index, 223 size_t offset, 224 size_t size, 225 int64_t presentationTimeUs, 226 uint32_t flags, 227 AString *errorDetailMsg) { 228 if (errorDetailMsg != NULL) { 229 errorDetailMsg->clear(); 230 } 231 232 sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, id()); 233 msg->setSize("index", index); 234 msg->setSize("offset", offset); 235 msg->setSize("size", size); 236 msg->setInt64("timeUs", presentationTimeUs); 237 msg->setInt32("flags", flags); 238 msg->setPointer("errorDetailMsg", errorDetailMsg); 239 240 sp<AMessage> response; 241 return PostAndAwaitResponse(msg, &response); 242 } 243 244 status_t MediaCodec::queueSecureInputBuffer( 245 size_t index, 246 size_t offset, 247 const CryptoPlugin::SubSample *subSamples, 248 size_t numSubSamples, 249 const uint8_t key[16], 250 const uint8_t iv[16], 251 CryptoPlugin::Mode mode, 252 int64_t presentationTimeUs, 253 uint32_t flags, 254 AString *errorDetailMsg) { 255 if (errorDetailMsg != NULL) { 256 errorDetailMsg->clear(); 257 } 258 259 sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, id()); 260 msg->setSize("index", index); 261 msg->setSize("offset", offset); 262 msg->setPointer("subSamples", (void *)subSamples); 263 msg->setSize("numSubSamples", numSubSamples); 264 msg->setPointer("key", (void *)key); 265 msg->setPointer("iv", (void *)iv); 266 msg->setInt32("mode", mode); 267 msg->setInt64("timeUs", presentationTimeUs); 268 msg->setInt32("flags", flags); 269 msg->setPointer("errorDetailMsg", errorDetailMsg); 270 271 sp<AMessage> response; 272 status_t err = PostAndAwaitResponse(msg, &response); 273 274 return err; 275 } 276 277 status_t MediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) { 278 sp<AMessage> msg = new AMessage(kWhatDequeueInputBuffer, id()); 279 msg->setInt64("timeoutUs", timeoutUs); 280 281 sp<AMessage> response; 282 status_t err; 283 if ((err = PostAndAwaitResponse(msg, &response)) != OK) { 284 return err; 285 } 286 287 CHECK(response->findSize("index", index)); 288 289 return OK; 290 } 291 292 status_t MediaCodec::dequeueOutputBuffer( 293 size_t *index, 294 size_t *offset, 295 size_t *size, 296 int64_t *presentationTimeUs, 297 uint32_t *flags, 298 int64_t timeoutUs) { 299 sp<AMessage> msg = new AMessage(kWhatDequeueOutputBuffer, id()); 300 msg->setInt64("timeoutUs", timeoutUs); 301 302 sp<AMessage> response; 303 status_t err; 304 if ((err = PostAndAwaitResponse(msg, &response)) != OK) { 305 return err; 306 } 307 308 CHECK(response->findSize("index", index)); 309 CHECK(response->findSize("offset", offset)); 310 CHECK(response->findSize("size", size)); 311 CHECK(response->findInt64("timeUs", presentationTimeUs)); 312 CHECK(response->findInt32("flags", (int32_t *)flags)); 313 314 return OK; 315 } 316 317 status_t MediaCodec::renderOutputBufferAndRelease(size_t index) { 318 sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, id()); 319 msg->setSize("index", index); 320 msg->setInt32("render", true); 321 322 sp<AMessage> response; 323 return PostAndAwaitResponse(msg, &response); 324 } 325 326 status_t MediaCodec::releaseOutputBuffer(size_t index) { 327 sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, id()); 328 msg->setSize("index", index); 329 330 sp<AMessage> response; 331 return PostAndAwaitResponse(msg, &response); 332 } 333 334 status_t MediaCodec::signalEndOfInputStream() { 335 sp<AMessage> msg = new AMessage(kWhatSignalEndOfInputStream, id()); 336 337 sp<AMessage> response; 338 return PostAndAwaitResponse(msg, &response); 339 } 340 341 status_t MediaCodec::getOutputFormat(sp<AMessage> *format) const { 342 sp<AMessage> msg = new AMessage(kWhatGetOutputFormat, id()); 343 344 sp<AMessage> response; 345 status_t err; 346 if ((err = PostAndAwaitResponse(msg, &response)) != OK) { 347 return err; 348 } 349 350 CHECK(response->findMessage("format", format)); 351 352 return OK; 353 } 354 355 status_t MediaCodec::getName(AString *name) const { 356 sp<AMessage> msg = new AMessage(kWhatGetName, id()); 357 358 sp<AMessage> response; 359 status_t err; 360 if ((err = PostAndAwaitResponse(msg, &response)) != OK) { 361 return err; 362 } 363 364 CHECK(response->findString("name", name)); 365 366 return OK; 367 } 368 369 status_t MediaCodec::getInputBuffers(Vector<sp<ABuffer> > *buffers) const { 370 sp<AMessage> msg = new AMessage(kWhatGetBuffers, id()); 371 msg->setInt32("portIndex", kPortIndexInput); 372 msg->setPointer("buffers", buffers); 373 374 sp<AMessage> response; 375 return PostAndAwaitResponse(msg, &response); 376 } 377 378 status_t MediaCodec::getOutputBuffers(Vector<sp<ABuffer> > *buffers) const { 379 sp<AMessage> msg = new AMessage(kWhatGetBuffers, id()); 380 msg->setInt32("portIndex", kPortIndexOutput); 381 msg->setPointer("buffers", buffers); 382 383 sp<AMessage> response; 384 return PostAndAwaitResponse(msg, &response); 385 } 386 387 status_t MediaCodec::flush() { 388 sp<AMessage> msg = new AMessage(kWhatFlush, id()); 389 390 sp<AMessage> response; 391 return PostAndAwaitResponse(msg, &response); 392 } 393 394 status_t MediaCodec::requestIDRFrame() { 395 (new AMessage(kWhatRequestIDRFrame, id()))->post(); 396 397 return OK; 398 } 399 400 void MediaCodec::requestActivityNotification(const sp<AMessage> ¬ify) { 401 sp<AMessage> msg = new AMessage(kWhatRequestActivityNotification, id()); 402 msg->setMessage("notify", notify); 403 msg->post(); 404 } 405 406 //////////////////////////////////////////////////////////////////////////////// 407 408 void MediaCodec::cancelPendingDequeueOperations() { 409 if (mFlags & kFlagDequeueInputPending) { 410 sp<AMessage> response = new AMessage; 411 response->setInt32("err", INVALID_OPERATION); 412 response->postReply(mDequeueInputReplyID); 413 414 ++mDequeueInputTimeoutGeneration; 415 mDequeueInputReplyID = 0; 416 mFlags &= ~kFlagDequeueInputPending; 417 } 418 419 if (mFlags & kFlagDequeueOutputPending) { 420 sp<AMessage> response = new AMessage; 421 response->setInt32("err", INVALID_OPERATION); 422 response->postReply(mDequeueOutputReplyID); 423 424 ++mDequeueOutputTimeoutGeneration; 425 mDequeueOutputReplyID = 0; 426 mFlags &= ~kFlagDequeueOutputPending; 427 } 428 } 429 430 bool MediaCodec::handleDequeueInputBuffer(uint32_t replyID, bool newRequest) { 431 if (mState != STARTED 432 || (mFlags & kFlagStickyError) 433 || (newRequest && (mFlags & kFlagDequeueInputPending))) { 434 sp<AMessage> response = new AMessage; 435 response->setInt32("err", INVALID_OPERATION); 436 437 response->postReply(replyID); 438 439 return true; 440 } 441 442 ssize_t index = dequeuePortBuffer(kPortIndexInput); 443 444 if (index < 0) { 445 CHECK_EQ(index, -EAGAIN); 446 return false; 447 } 448 449 sp<AMessage> response = new AMessage; 450 response->setSize("index", index); 451 response->postReply(replyID); 452 453 return true; 454 } 455 456 bool MediaCodec::handleDequeueOutputBuffer(uint32_t replyID, bool newRequest) { 457 sp<AMessage> response = new AMessage; 458 459 if (mState != STARTED 460 || (mFlags & kFlagStickyError) 461 || (newRequest && (mFlags & kFlagDequeueOutputPending))) { 462 response->setInt32("err", INVALID_OPERATION); 463 } else if (mFlags & kFlagOutputBuffersChanged) { 464 response->setInt32("err", INFO_OUTPUT_BUFFERS_CHANGED); 465 mFlags &= ~kFlagOutputBuffersChanged; 466 } else if (mFlags & kFlagOutputFormatChanged) { 467 response->setInt32("err", INFO_FORMAT_CHANGED); 468 mFlags &= ~kFlagOutputFormatChanged; 469 } else { 470 ssize_t index = dequeuePortBuffer(kPortIndexOutput); 471 472 if (index < 0) { 473 CHECK_EQ(index, -EAGAIN); 474 return false; 475 } 476 477 const sp<ABuffer> &buffer = 478 mPortBuffers[kPortIndexOutput].itemAt(index).mData; 479 480 response->setSize("index", index); 481 response->setSize("offset", buffer->offset()); 482 response->setSize("size", buffer->size()); 483 484 int64_t timeUs; 485 CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 486 487 response->setInt64("timeUs", timeUs); 488 489 int32_t omxFlags; 490 CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags)); 491 492 uint32_t flags = 0; 493 if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) { 494 flags |= BUFFER_FLAG_SYNCFRAME; 495 } 496 if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) { 497 flags |= BUFFER_FLAG_CODECCONFIG; 498 } 499 if (omxFlags & OMX_BUFFERFLAG_EOS) { 500 flags |= BUFFER_FLAG_EOS; 501 } 502 503 response->setInt32("flags", flags); 504 } 505 506 response->postReply(replyID); 507 508 return true; 509 } 510 511 void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { 512 switch (msg->what()) { 513 case kWhatCodecNotify: 514 { 515 int32_t what; 516 CHECK(msg->findInt32("what", &what)); 517 518 switch (what) { 519 case ACodec::kWhatError: 520 { 521 int32_t omxError, internalError; 522 CHECK(msg->findInt32("omx-error", &omxError)); 523 CHECK(msg->findInt32("err", &internalError)); 524 525 ALOGE("Codec reported an error. " 526 "(omx error 0x%08x, internalError %d)", 527 omxError, internalError); 528 529 if (omxError == OMX_ErrorResourcesLost 530 && internalError == DEAD_OBJECT) { 531 mFlags |= kFlagSawMediaServerDie; 532 } 533 534 bool sendErrorReponse = true; 535 536 switch (mState) { 537 case INITIALIZING: 538 { 539 setState(UNINITIALIZED); 540 break; 541 } 542 543 case CONFIGURING: 544 { 545 setState(INITIALIZED); 546 break; 547 } 548 549 case STARTING: 550 { 551 setState(CONFIGURED); 552 break; 553 } 554 555 case STOPPING: 556 case RELEASING: 557 { 558 // Ignore the error, assuming we'll still get 559 // the shutdown complete notification. 560 561 sendErrorReponse = false; 562 563 if (mFlags & kFlagSawMediaServerDie) { 564 // MediaServer died, there definitely won't 565 // be a shutdown complete notification after 566 // all. 567 568 // note that we're directly going from 569 // STOPPING->UNINITIALIZED, instead of the 570 // usual STOPPING->INITIALIZED state. 571 setState(UNINITIALIZED); 572 573 (new AMessage)->postReply(mReplyID); 574 } 575 break; 576 } 577 578 case FLUSHING: 579 { 580 setState(STARTED); 581 break; 582 } 583 584 case STARTED: 585 { 586 sendErrorReponse = false; 587 588 mFlags |= kFlagStickyError; 589 postActivityNotificationIfPossible(); 590 591 cancelPendingDequeueOperations(); 592 break; 593 } 594 595 default: 596 { 597 sendErrorReponse = false; 598 599 mFlags |= kFlagStickyError; 600 postActivityNotificationIfPossible(); 601 break; 602 } 603 } 604 605 if (sendErrorReponse) { 606 sp<AMessage> response = new AMessage; 607 response->setInt32("err", UNKNOWN_ERROR); 608 609 response->postReply(mReplyID); 610 } 611 break; 612 } 613 614 case ACodec::kWhatComponentAllocated: 615 { 616 CHECK_EQ(mState, INITIALIZING); 617 setState(INITIALIZED); 618 619 CHECK(msg->findString("componentName", &mComponentName)); 620 621 if (mComponentName.startsWith("OMX.google.")) { 622 mFlags |= kFlagIsSoftwareCodec; 623 } else { 624 mFlags &= ~kFlagIsSoftwareCodec; 625 } 626 627 if (mComponentName.endsWith(".secure")) { 628 mFlags |= kFlagIsSecure; 629 } else { 630 mFlags &= ~kFlagIsSecure; 631 } 632 633 (new AMessage)->postReply(mReplyID); 634 break; 635 } 636 637 case ACodec::kWhatComponentConfigured: 638 { 639 CHECK_EQ(mState, CONFIGURING); 640 setState(CONFIGURED); 641 642 // reset input surface flag 643 mHaveInputSurface = false; 644 645 (new AMessage)->postReply(mReplyID); 646 break; 647 } 648 649 case ACodec::kWhatInputSurfaceCreated: 650 { 651 // response to ACodec::kWhatCreateInputSurface 652 status_t err = NO_ERROR; 653 sp<AMessage> response = new AMessage(); 654 if (!msg->findInt32("err", &err)) { 655 sp<RefBase> obj; 656 msg->findObject("input-surface", &obj); 657 CHECK(obj != NULL); 658 response->setObject("input-surface", obj); 659 mHaveInputSurface = true; 660 } else { 661 response->setInt32("err", err); 662 } 663 response->postReply(mReplyID); 664 break; 665 } 666 667 case ACodec::kWhatSignaledInputEOS: 668 { 669 // response to ACodec::kWhatSignalEndOfInputStream 670 sp<AMessage> response = new AMessage(); 671 status_t err; 672 if (msg->findInt32("err", &err)) { 673 response->setInt32("err", err); 674 } 675 response->postReply(mReplyID); 676 break; 677 } 678 679 680 case ACodec::kWhatBuffersAllocated: 681 { 682 int32_t portIndex; 683 CHECK(msg->findInt32("portIndex", &portIndex)); 684 685 ALOGV("%s buffers allocated", 686 portIndex == kPortIndexInput ? "input" : "output"); 687 688 CHECK(portIndex == kPortIndexInput 689 || portIndex == kPortIndexOutput); 690 691 mPortBuffers[portIndex].clear(); 692 693 Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 694 695 sp<RefBase> obj; 696 CHECK(msg->findObject("portDesc", &obj)); 697 698 sp<ACodec::PortDescription> portDesc = 699 static_cast<ACodec::PortDescription *>(obj.get()); 700 701 size_t numBuffers = portDesc->countBuffers(); 702 703 for (size_t i = 0; i < numBuffers; ++i) { 704 BufferInfo info; 705 info.mBufferID = portDesc->bufferIDAt(i); 706 info.mOwnedByClient = false; 707 info.mData = portDesc->bufferAt(i); 708 709 if (portIndex == kPortIndexInput && mCrypto != NULL) { 710 info.mEncryptedData = 711 new ABuffer(info.mData->capacity()); 712 } 713 714 buffers->push_back(info); 715 } 716 717 if (portIndex == kPortIndexOutput) { 718 if (mState == STARTING) { 719 // We're always allocating output buffers after 720 // allocating input buffers, so this is a good 721 // indication that now all buffers are allocated. 722 setState(STARTED); 723 (new AMessage)->postReply(mReplyID); 724 } else { 725 mFlags |= kFlagOutputBuffersChanged; 726 postActivityNotificationIfPossible(); 727 } 728 } 729 break; 730 } 731 732 case ACodec::kWhatOutputFormatChanged: 733 { 734 ALOGV("codec output format changed"); 735 736 if ((mFlags & kFlagIsSoftwareCodec) 737 && mNativeWindow != NULL) { 738 AString mime; 739 CHECK(msg->findString("mime", &mime)); 740 741 if (!strncasecmp("video/", mime.c_str(), 6)) { 742 delete mSoftRenderer; 743 mSoftRenderer = NULL; 744 745 int32_t width, height; 746 CHECK(msg->findInt32("width", &width)); 747 CHECK(msg->findInt32("height", &height)); 748 749 int32_t colorFormat; 750 CHECK(msg->findInt32( 751 "color-format", &colorFormat)); 752 753 sp<MetaData> meta = new MetaData; 754 meta->setInt32(kKeyWidth, width); 755 meta->setInt32(kKeyHeight, height); 756 meta->setInt32(kKeyColorFormat, colorFormat); 757 758 mSoftRenderer = 759 new SoftwareRenderer(mNativeWindow, meta); 760 } 761 } 762 763 mOutputFormat = msg; 764 765 if (mFlags & kFlagIsEncoder) { 766 // Before we announce the format change we should 767 // collect codec specific data and amend the output 768 // format as necessary. 769 mFlags |= kFlagGatherCodecSpecificData; 770 } else { 771 mFlags |= kFlagOutputFormatChanged; 772 postActivityNotificationIfPossible(); 773 } 774 break; 775 } 776 777 case ACodec::kWhatFillThisBuffer: 778 { 779 /* size_t index = */updateBuffers(kPortIndexInput, msg); 780 781 if (mState == FLUSHING 782 || mState == STOPPING 783 || mState == RELEASING) { 784 returnBuffersToCodecOnPort(kPortIndexInput); 785 break; 786 } 787 788 if (!mCSD.empty()) { 789 ssize_t index = dequeuePortBuffer(kPortIndexInput); 790 CHECK_GE(index, 0); 791 792 // If codec specific data had been specified as 793 // part of the format in the call to configure and 794 // if there's more csd left, we submit it here 795 // clients only get access to input buffers once 796 // this data has been exhausted. 797 798 status_t err = queueCSDInputBuffer(index); 799 800 if (err != OK) { 801 ALOGE("queueCSDInputBuffer failed w/ error %d", 802 err); 803 804 mFlags |= kFlagStickyError; 805 postActivityNotificationIfPossible(); 806 807 cancelPendingDequeueOperations(); 808 } 809 break; 810 } 811 812 if (mFlags & kFlagDequeueInputPending) { 813 CHECK(handleDequeueInputBuffer(mDequeueInputReplyID)); 814 815 ++mDequeueInputTimeoutGeneration; 816 mFlags &= ~kFlagDequeueInputPending; 817 mDequeueInputReplyID = 0; 818 } else { 819 postActivityNotificationIfPossible(); 820 } 821 break; 822 } 823 824 case ACodec::kWhatDrainThisBuffer: 825 { 826 /* size_t index = */updateBuffers(kPortIndexOutput, msg); 827 828 if (mState == FLUSHING 829 || mState == STOPPING 830 || mState == RELEASING) { 831 returnBuffersToCodecOnPort(kPortIndexOutput); 832 break; 833 } 834 835 sp<ABuffer> buffer; 836 CHECK(msg->findBuffer("buffer", &buffer)); 837 838 int32_t omxFlags; 839 CHECK(msg->findInt32("flags", &omxFlags)); 840 841 buffer->meta()->setInt32("omxFlags", omxFlags); 842 843 if (mFlags & kFlagGatherCodecSpecificData) { 844 // This is the very first output buffer after a 845 // format change was signalled, it'll either contain 846 // the one piece of codec specific data we can expect 847 // or there won't be codec specific data. 848 if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) { 849 status_t err = 850 amendOutputFormatWithCodecSpecificData(buffer); 851 852 if (err != OK) { 853 ALOGE("Codec spit out malformed codec " 854 "specific data!"); 855 } 856 } 857 858 mFlags &= ~kFlagGatherCodecSpecificData; 859 mFlags |= kFlagOutputFormatChanged; 860 } 861 862 if (mFlags & kFlagDequeueOutputPending) { 863 CHECK(handleDequeueOutputBuffer(mDequeueOutputReplyID)); 864 865 ++mDequeueOutputTimeoutGeneration; 866 mFlags &= ~kFlagDequeueOutputPending; 867 mDequeueOutputReplyID = 0; 868 } else { 869 postActivityNotificationIfPossible(); 870 } 871 872 break; 873 } 874 875 case ACodec::kWhatEOS: 876 { 877 // We already notify the client of this by using the 878 // corresponding flag in "onOutputBufferReady". 879 break; 880 } 881 882 case ACodec::kWhatShutdownCompleted: 883 { 884 if (mState == STOPPING) { 885 setState(INITIALIZED); 886 } else { 887 CHECK_EQ(mState, RELEASING); 888 setState(UNINITIALIZED); 889 } 890 891 (new AMessage)->postReply(mReplyID); 892 break; 893 } 894 895 case ACodec::kWhatFlushCompleted: 896 { 897 CHECK_EQ(mState, FLUSHING); 898 setState(STARTED); 899 900 mCodec->signalResume(); 901 902 (new AMessage)->postReply(mReplyID); 903 break; 904 } 905 906 default: 907 TRESPASS(); 908 } 909 break; 910 } 911 912 case kWhatInit: 913 { 914 uint32_t replyID; 915 CHECK(msg->senderAwaitsResponse(&replyID)); 916 917 if (mState != UNINITIALIZED) { 918 sp<AMessage> response = new AMessage; 919 response->setInt32("err", INVALID_OPERATION); 920 921 response->postReply(replyID); 922 break; 923 } 924 925 mReplyID = replyID; 926 setState(INITIALIZING); 927 928 AString name; 929 CHECK(msg->findString("name", &name)); 930 931 int32_t nameIsType; 932 int32_t encoder = false; 933 CHECK(msg->findInt32("nameIsType", &nameIsType)); 934 if (nameIsType) { 935 CHECK(msg->findInt32("encoder", &encoder)); 936 } 937 938 sp<AMessage> format = new AMessage; 939 940 if (nameIsType) { 941 format->setString("mime", name.c_str()); 942 format->setInt32("encoder", encoder); 943 } else { 944 format->setString("componentName", name.c_str()); 945 } 946 947 mCodec->initiateAllocateComponent(format); 948 break; 949 } 950 951 case kWhatConfigure: 952 { 953 uint32_t replyID; 954 CHECK(msg->senderAwaitsResponse(&replyID)); 955 956 if (mState != INITIALIZED) { 957 sp<AMessage> response = new AMessage; 958 response->setInt32("err", INVALID_OPERATION); 959 960 response->postReply(replyID); 961 break; 962 } 963 964 sp<RefBase> obj; 965 if (!msg->findObject("native-window", &obj)) { 966 obj.clear(); 967 } 968 969 sp<AMessage> format; 970 CHECK(msg->findMessage("format", &format)); 971 972 if (obj != NULL) { 973 format->setObject("native-window", obj); 974 975 status_t err = setNativeWindow( 976 static_cast<NativeWindowWrapper *>(obj.get()) 977 ->getSurfaceTextureClient()); 978 979 if (err != OK) { 980 sp<AMessage> response = new AMessage; 981 response->setInt32("err", err); 982 983 response->postReply(replyID); 984 break; 985 } 986 } else { 987 setNativeWindow(NULL); 988 } 989 990 mReplyID = replyID; 991 setState(CONFIGURING); 992 993 void *crypto; 994 if (!msg->findPointer("crypto", &crypto)) { 995 crypto = NULL; 996 } 997 998 mCrypto = static_cast<ICrypto *>(crypto); 999 1000 uint32_t flags; 1001 CHECK(msg->findInt32("flags", (int32_t *)&flags)); 1002 1003 if (flags & CONFIGURE_FLAG_ENCODE) { 1004 format->setInt32("encoder", true); 1005 mFlags |= kFlagIsEncoder; 1006 } 1007 1008 extractCSD(format); 1009 1010 mCodec->initiateConfigureComponent(format); 1011 break; 1012 } 1013 1014 case kWhatCreateInputSurface: 1015 { 1016 uint32_t replyID; 1017 CHECK(msg->senderAwaitsResponse(&replyID)); 1018 1019 // Must be configured, but can't have been started yet. 1020 if (mState != CONFIGURED) { 1021 sp<AMessage> response = new AMessage; 1022 response->setInt32("err", INVALID_OPERATION); 1023 1024 response->postReply(replyID); 1025 break; 1026 } 1027 1028 mReplyID = replyID; 1029 mCodec->initiateCreateInputSurface(); 1030 break; 1031 } 1032 1033 case kWhatStart: 1034 { 1035 uint32_t replyID; 1036 CHECK(msg->senderAwaitsResponse(&replyID)); 1037 1038 if (mState != CONFIGURED) { 1039 sp<AMessage> response = new AMessage; 1040 response->setInt32("err", INVALID_OPERATION); 1041 1042 response->postReply(replyID); 1043 break; 1044 } 1045 1046 mReplyID = replyID; 1047 setState(STARTING); 1048 1049 mCodec->initiateStart(); 1050 break; 1051 } 1052 1053 case kWhatStop: 1054 case kWhatRelease: 1055 { 1056 State targetState = 1057 (msg->what() == kWhatStop) ? INITIALIZED : UNINITIALIZED; 1058 1059 uint32_t replyID; 1060 CHECK(msg->senderAwaitsResponse(&replyID)); 1061 1062 if (mState != INITIALIZED 1063 && mState != CONFIGURED && mState != STARTED) { 1064 // We may be in "UNINITIALIZED" state already without the 1065 // client being aware of this if media server died while 1066 // we were being stopped. The client would assume that 1067 // after stop() returned, it would be safe to call release() 1068 // and it should be in this case, no harm to allow a release() 1069 // if we're already uninitialized. 1070 // Similarly stopping a stopped MediaCodec should be benign. 1071 sp<AMessage> response = new AMessage; 1072 response->setInt32( 1073 "err", 1074 mState == targetState ? OK : INVALID_OPERATION); 1075 1076 response->postReply(replyID); 1077 break; 1078 } 1079 1080 if (mFlags & kFlagSawMediaServerDie) { 1081 // It's dead, Jim. Don't expect initiateShutdown to yield 1082 // any useful results now... 1083 setState(UNINITIALIZED); 1084 (new AMessage)->postReply(replyID); 1085 break; 1086 } 1087 1088 mReplyID = replyID; 1089 setState(msg->what() == kWhatStop ? STOPPING : RELEASING); 1090 1091 mCodec->initiateShutdown( 1092 msg->what() == kWhatStop /* keepComponentAllocated */); 1093 1094 returnBuffersToCodec(); 1095 break; 1096 } 1097 1098 case kWhatDequeueInputBuffer: 1099 { 1100 uint32_t replyID; 1101 CHECK(msg->senderAwaitsResponse(&replyID)); 1102 1103 if (mHaveInputSurface) { 1104 ALOGE("dequeueInputBuffer can't be used with input surface"); 1105 sp<AMessage> response = new AMessage; 1106 response->setInt32("err", INVALID_OPERATION); 1107 response->postReply(replyID); 1108 break; 1109 } 1110 1111 if (handleDequeueInputBuffer(replyID, true /* new request */)) { 1112 break; 1113 } 1114 1115 int64_t timeoutUs; 1116 CHECK(msg->findInt64("timeoutUs", &timeoutUs)); 1117 1118 if (timeoutUs == 0ll) { 1119 sp<AMessage> response = new AMessage; 1120 response->setInt32("err", -EAGAIN); 1121 response->postReply(replyID); 1122 break; 1123 } 1124 1125 mFlags |= kFlagDequeueInputPending; 1126 mDequeueInputReplyID = replyID; 1127 1128 if (timeoutUs > 0ll) { 1129 sp<AMessage> timeoutMsg = 1130 new AMessage(kWhatDequeueInputTimedOut, id()); 1131 timeoutMsg->setInt32( 1132 "generation", ++mDequeueInputTimeoutGeneration); 1133 timeoutMsg->post(timeoutUs); 1134 } 1135 break; 1136 } 1137 1138 case kWhatDequeueInputTimedOut: 1139 { 1140 int32_t generation; 1141 CHECK(msg->findInt32("generation", &generation)); 1142 1143 if (generation != mDequeueInputTimeoutGeneration) { 1144 // Obsolete 1145 break; 1146 } 1147 1148 CHECK(mFlags & kFlagDequeueInputPending); 1149 1150 sp<AMessage> response = new AMessage; 1151 response->setInt32("err", -EAGAIN); 1152 response->postReply(mDequeueInputReplyID); 1153 1154 mFlags &= ~kFlagDequeueInputPending; 1155 mDequeueInputReplyID = 0; 1156 break; 1157 } 1158 1159 case kWhatQueueInputBuffer: 1160 { 1161 uint32_t replyID; 1162 CHECK(msg->senderAwaitsResponse(&replyID)); 1163 1164 if (mState != STARTED || (mFlags & kFlagStickyError)) { 1165 sp<AMessage> response = new AMessage; 1166 response->setInt32("err", INVALID_OPERATION); 1167 1168 response->postReply(replyID); 1169 break; 1170 } 1171 1172 status_t err = onQueueInputBuffer(msg); 1173 1174 sp<AMessage> response = new AMessage; 1175 response->setInt32("err", err); 1176 response->postReply(replyID); 1177 break; 1178 } 1179 1180 case kWhatDequeueOutputBuffer: 1181 { 1182 uint32_t replyID; 1183 CHECK(msg->senderAwaitsResponse(&replyID)); 1184 1185 if (handleDequeueOutputBuffer(replyID, true /* new request */)) { 1186 break; 1187 } 1188 1189 int64_t timeoutUs; 1190 CHECK(msg->findInt64("timeoutUs", &timeoutUs)); 1191 1192 if (timeoutUs == 0ll) { 1193 sp<AMessage> response = new AMessage; 1194 response->setInt32("err", -EAGAIN); 1195 response->postReply(replyID); 1196 break; 1197 } 1198 1199 mFlags |= kFlagDequeueOutputPending; 1200 mDequeueOutputReplyID = replyID; 1201 1202 if (timeoutUs > 0ll) { 1203 sp<AMessage> timeoutMsg = 1204 new AMessage(kWhatDequeueOutputTimedOut, id()); 1205 timeoutMsg->setInt32( 1206 "generation", ++mDequeueOutputTimeoutGeneration); 1207 timeoutMsg->post(timeoutUs); 1208 } 1209 break; 1210 } 1211 1212 case kWhatDequeueOutputTimedOut: 1213 { 1214 int32_t generation; 1215 CHECK(msg->findInt32("generation", &generation)); 1216 1217 if (generation != mDequeueOutputTimeoutGeneration) { 1218 // Obsolete 1219 break; 1220 } 1221 1222 CHECK(mFlags & kFlagDequeueOutputPending); 1223 1224 sp<AMessage> response = new AMessage; 1225 response->setInt32("err", -EAGAIN); 1226 response->postReply(mDequeueOutputReplyID); 1227 1228 mFlags &= ~kFlagDequeueOutputPending; 1229 mDequeueOutputReplyID = 0; 1230 break; 1231 } 1232 1233 case kWhatReleaseOutputBuffer: 1234 { 1235 uint32_t replyID; 1236 CHECK(msg->senderAwaitsResponse(&replyID)); 1237 1238 if (mState != STARTED || (mFlags & kFlagStickyError)) { 1239 sp<AMessage> response = new AMessage; 1240 response->setInt32("err", INVALID_OPERATION); 1241 1242 response->postReply(replyID); 1243 break; 1244 } 1245 1246 status_t err = onReleaseOutputBuffer(msg); 1247 1248 sp<AMessage> response = new AMessage; 1249 response->setInt32("err", err); 1250 response->postReply(replyID); 1251 break; 1252 } 1253 1254 case kWhatSignalEndOfInputStream: 1255 { 1256 uint32_t replyID; 1257 CHECK(msg->senderAwaitsResponse(&replyID)); 1258 1259 if (mState != STARTED || (mFlags & kFlagStickyError)) { 1260 sp<AMessage> response = new AMessage; 1261 response->setInt32("err", INVALID_OPERATION); 1262 1263 response->postReply(replyID); 1264 break; 1265 } 1266 1267 mReplyID = replyID; 1268 mCodec->signalEndOfInputStream(); 1269 break; 1270 } 1271 1272 case kWhatGetBuffers: 1273 { 1274 uint32_t replyID; 1275 CHECK(msg->senderAwaitsResponse(&replyID)); 1276 1277 if (mState != STARTED || (mFlags & kFlagStickyError)) { 1278 sp<AMessage> response = new AMessage; 1279 response->setInt32("err", INVALID_OPERATION); 1280 1281 response->postReply(replyID); 1282 break; 1283 } 1284 1285 int32_t portIndex; 1286 CHECK(msg->findInt32("portIndex", &portIndex)); 1287 1288 Vector<sp<ABuffer> > *dstBuffers; 1289 CHECK(msg->findPointer("buffers", (void **)&dstBuffers)); 1290 1291 dstBuffers->clear(); 1292 const Vector<BufferInfo> &srcBuffers = mPortBuffers[portIndex]; 1293 1294 for (size_t i = 0; i < srcBuffers.size(); ++i) { 1295 const BufferInfo &info = srcBuffers.itemAt(i); 1296 1297 dstBuffers->push_back( 1298 (portIndex == kPortIndexInput && mCrypto != NULL) 1299 ? info.mEncryptedData : info.mData); 1300 } 1301 1302 (new AMessage)->postReply(replyID); 1303 break; 1304 } 1305 1306 case kWhatFlush: 1307 { 1308 uint32_t replyID; 1309 CHECK(msg->senderAwaitsResponse(&replyID)); 1310 1311 if (mState != STARTED || (mFlags & kFlagStickyError)) { 1312 sp<AMessage> response = new AMessage; 1313 response->setInt32("err", INVALID_OPERATION); 1314 1315 response->postReply(replyID); 1316 break; 1317 } 1318 1319 mReplyID = replyID; 1320 setState(FLUSHING); 1321 1322 mCodec->signalFlush(); 1323 returnBuffersToCodec(); 1324 break; 1325 } 1326 1327 case kWhatGetOutputFormat: 1328 { 1329 uint32_t replyID; 1330 CHECK(msg->senderAwaitsResponse(&replyID)); 1331 1332 if ((mState != STARTED && mState != FLUSHING) 1333 || (mFlags & kFlagStickyError) 1334 || mOutputFormat == NULL) { 1335 sp<AMessage> response = new AMessage; 1336 response->setInt32("err", INVALID_OPERATION); 1337 1338 response->postReply(replyID); 1339 break; 1340 } 1341 1342 sp<AMessage> response = new AMessage; 1343 response->setMessage("format", mOutputFormat); 1344 response->postReply(replyID); 1345 break; 1346 } 1347 1348 case kWhatRequestIDRFrame: 1349 { 1350 mCodec->signalRequestIDRFrame(); 1351 break; 1352 } 1353 1354 case kWhatRequestActivityNotification: 1355 { 1356 CHECK(mActivityNotify == NULL); 1357 CHECK(msg->findMessage("notify", &mActivityNotify)); 1358 1359 postActivityNotificationIfPossible(); 1360 break; 1361 } 1362 1363 case kWhatGetName: 1364 { 1365 uint32_t replyID; 1366 CHECK(msg->senderAwaitsResponse(&replyID)); 1367 1368 if (mComponentName.empty()) { 1369 sp<AMessage> response = new AMessage; 1370 response->setInt32("err", INVALID_OPERATION); 1371 1372 response->postReply(replyID); 1373 break; 1374 } 1375 1376 sp<AMessage> response = new AMessage; 1377 response->setString("name", mComponentName.c_str()); 1378 response->postReply(replyID); 1379 break; 1380 } 1381 1382 case kWhatSetParameters: 1383 { 1384 uint32_t replyID; 1385 CHECK(msg->senderAwaitsResponse(&replyID)); 1386 1387 sp<AMessage> params; 1388 CHECK(msg->findMessage("params", ¶ms)); 1389 1390 status_t err = onSetParameters(params); 1391 1392 sp<AMessage> response = new AMessage; 1393 response->setInt32("err", err); 1394 1395 response->postReply(replyID); 1396 break; 1397 } 1398 1399 default: 1400 TRESPASS(); 1401 } 1402 } 1403 1404 void MediaCodec::extractCSD(const sp<AMessage> &format) { 1405 mCSD.clear(); 1406 1407 size_t i = 0; 1408 for (;;) { 1409 sp<ABuffer> csd; 1410 if (!format->findBuffer(StringPrintf("csd-%u", i).c_str(), &csd)) { 1411 break; 1412 } 1413 1414 mCSD.push_back(csd); 1415 ++i; 1416 } 1417 1418 ALOGV("Found %u pieces of codec specific data.", mCSD.size()); 1419 } 1420 1421 status_t MediaCodec::queueCSDInputBuffer(size_t bufferIndex) { 1422 CHECK(!mCSD.empty()); 1423 1424 BufferInfo *info = 1425 &mPortBuffers[kPortIndexInput].editItemAt(bufferIndex); 1426 1427 sp<ABuffer> csd = *mCSD.begin(); 1428 mCSD.erase(mCSD.begin()); 1429 1430 const sp<ABuffer> &codecInputData = 1431 (mCrypto != NULL) ? info->mEncryptedData : info->mData; 1432 1433 if (csd->size() > codecInputData->capacity()) { 1434 return -EINVAL; 1435 } 1436 1437 memcpy(codecInputData->data(), csd->data(), csd->size()); 1438 1439 AString errorDetailMsg; 1440 1441 sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, id()); 1442 msg->setSize("index", bufferIndex); 1443 msg->setSize("offset", 0); 1444 msg->setSize("size", csd->size()); 1445 msg->setInt64("timeUs", 0ll); 1446 msg->setInt32("flags", BUFFER_FLAG_CODECCONFIG); 1447 msg->setPointer("errorDetailMsg", &errorDetailMsg); 1448 1449 return onQueueInputBuffer(msg); 1450 } 1451 1452 void MediaCodec::setState(State newState) { 1453 if (newState == INITIALIZED || newState == UNINITIALIZED) { 1454 delete mSoftRenderer; 1455 mSoftRenderer = NULL; 1456 1457 mCrypto.clear(); 1458 setNativeWindow(NULL); 1459 1460 mOutputFormat.clear(); 1461 mFlags &= ~kFlagOutputFormatChanged; 1462 mFlags &= ~kFlagOutputBuffersChanged; 1463 mFlags &= ~kFlagStickyError; 1464 mFlags &= ~kFlagIsEncoder; 1465 mFlags &= ~kFlagGatherCodecSpecificData; 1466 1467 mActivityNotify.clear(); 1468 } 1469 1470 if (newState == UNINITIALIZED) { 1471 mComponentName.clear(); 1472 1473 // The component is gone, mediaserver's probably back up already 1474 // but should definitely be back up should we try to instantiate 1475 // another component.. and the cycle continues. 1476 mFlags &= ~kFlagSawMediaServerDie; 1477 } 1478 1479 mState = newState; 1480 1481 cancelPendingDequeueOperations(); 1482 } 1483 1484 void MediaCodec::returnBuffersToCodec() { 1485 returnBuffersToCodecOnPort(kPortIndexInput); 1486 returnBuffersToCodecOnPort(kPortIndexOutput); 1487 } 1488 1489 void MediaCodec::returnBuffersToCodecOnPort(int32_t portIndex) { 1490 CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 1491 1492 Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 1493 1494 for (size_t i = 0; i < buffers->size(); ++i) { 1495 BufferInfo *info = &buffers->editItemAt(i); 1496 1497 if (info->mNotify != NULL) { 1498 sp<AMessage> msg = info->mNotify; 1499 info->mNotify = NULL; 1500 info->mOwnedByClient = false; 1501 1502 if (portIndex == kPortIndexInput) { 1503 /* no error, just returning buffers */ 1504 msg->setInt32("err", OK); 1505 } 1506 msg->post(); 1507 } 1508 } 1509 1510 mAvailPortBuffers[portIndex].clear(); 1511 } 1512 1513 size_t MediaCodec::updateBuffers( 1514 int32_t portIndex, const sp<AMessage> &msg) { 1515 CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 1516 1517 void *bufferID; 1518 CHECK(msg->findPointer("buffer-id", &bufferID)); 1519 1520 Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 1521 1522 for (size_t i = 0; i < buffers->size(); ++i) { 1523 BufferInfo *info = &buffers->editItemAt(i); 1524 1525 if (info->mBufferID == bufferID) { 1526 CHECK(info->mNotify == NULL); 1527 CHECK(msg->findMessage("reply", &info->mNotify)); 1528 1529 mAvailPortBuffers[portIndex].push_back(i); 1530 1531 return i; 1532 } 1533 } 1534 1535 TRESPASS(); 1536 1537 return 0; 1538 } 1539 1540 status_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) { 1541 size_t index; 1542 size_t offset; 1543 size_t size; 1544 int64_t timeUs; 1545 uint32_t flags; 1546 CHECK(msg->findSize("index", &index)); 1547 CHECK(msg->findSize("offset", &offset)); 1548 CHECK(msg->findInt64("timeUs", &timeUs)); 1549 CHECK(msg->findInt32("flags", (int32_t *)&flags)); 1550 1551 const CryptoPlugin::SubSample *subSamples; 1552 size_t numSubSamples; 1553 const uint8_t *key; 1554 const uint8_t *iv; 1555 CryptoPlugin::Mode mode = CryptoPlugin::kMode_Unencrypted; 1556 1557 // We allow the simpler queueInputBuffer API to be used even in 1558 // secure mode, by fabricating a single unencrypted subSample. 1559 CryptoPlugin::SubSample ss; 1560 1561 if (msg->findSize("size", &size)) { 1562 if (mCrypto != NULL) { 1563 ss.mNumBytesOfClearData = size; 1564 ss.mNumBytesOfEncryptedData = 0; 1565 1566 subSamples = &ss; 1567 numSubSamples = 1; 1568 key = NULL; 1569 iv = NULL; 1570 } 1571 } else { 1572 if (mCrypto == NULL) { 1573 return -EINVAL; 1574 } 1575 1576 CHECK(msg->findPointer("subSamples", (void **)&subSamples)); 1577 CHECK(msg->findSize("numSubSamples", &numSubSamples)); 1578 CHECK(msg->findPointer("key", (void **)&key)); 1579 CHECK(msg->findPointer("iv", (void **)&iv)); 1580 1581 int32_t tmp; 1582 CHECK(msg->findInt32("mode", &tmp)); 1583 1584 mode = (CryptoPlugin::Mode)tmp; 1585 1586 size = 0; 1587 for (size_t i = 0; i < numSubSamples; ++i) { 1588 size += subSamples[i].mNumBytesOfClearData; 1589 size += subSamples[i].mNumBytesOfEncryptedData; 1590 } 1591 } 1592 1593 if (index >= mPortBuffers[kPortIndexInput].size()) { 1594 return -ERANGE; 1595 } 1596 1597 BufferInfo *info = &mPortBuffers[kPortIndexInput].editItemAt(index); 1598 1599 if (info->mNotify == NULL || !info->mOwnedByClient) { 1600 return -EACCES; 1601 } 1602 1603 if (offset + size > info->mData->capacity()) { 1604 return -EINVAL; 1605 } 1606 1607 sp<AMessage> reply = info->mNotify; 1608 info->mData->setRange(offset, size); 1609 info->mData->meta()->setInt64("timeUs", timeUs); 1610 1611 if (flags & BUFFER_FLAG_EOS) { 1612 info->mData->meta()->setInt32("eos", true); 1613 } 1614 1615 if (flags & BUFFER_FLAG_CODECCONFIG) { 1616 info->mData->meta()->setInt32("csd", true); 1617 } 1618 1619 if (mCrypto != NULL) { 1620 if (size > info->mEncryptedData->capacity()) { 1621 return -ERANGE; 1622 } 1623 1624 AString *errorDetailMsg; 1625 CHECK(msg->findPointer("errorDetailMsg", (void **)&errorDetailMsg)); 1626 1627 ssize_t result = mCrypto->decrypt( 1628 (mFlags & kFlagIsSecure) != 0, 1629 key, 1630 iv, 1631 mode, 1632 info->mEncryptedData->base() + offset, 1633 subSamples, 1634 numSubSamples, 1635 info->mData->base(), 1636 errorDetailMsg); 1637 1638 if (result < 0) { 1639 return result; 1640 } 1641 1642 info->mData->setRange(0, result); 1643 } 1644 1645 reply->setBuffer("buffer", info->mData); 1646 reply->post(); 1647 1648 info->mNotify = NULL; 1649 info->mOwnedByClient = false; 1650 1651 return OK; 1652 } 1653 1654 status_t MediaCodec::onReleaseOutputBuffer(const sp<AMessage> &msg) { 1655 size_t index; 1656 CHECK(msg->findSize("index", &index)); 1657 1658 int32_t render; 1659 if (!msg->findInt32("render", &render)) { 1660 render = 0; 1661 } 1662 1663 if (mState != STARTED) { 1664 return -EINVAL; 1665 } 1666 1667 if (index >= mPortBuffers[kPortIndexOutput].size()) { 1668 return -ERANGE; 1669 } 1670 1671 BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index); 1672 1673 if (info->mNotify == NULL || !info->mOwnedByClient) { 1674 return -EACCES; 1675 } 1676 1677 if (render && (info->mData == NULL || info->mData->size() != 0)) { 1678 info->mNotify->setInt32("render", true); 1679 1680 if (mSoftRenderer != NULL) { 1681 mSoftRenderer->render( 1682 info->mData->data(), info->mData->size(), NULL); 1683 } 1684 } 1685 1686 info->mNotify->post(); 1687 info->mNotify = NULL; 1688 info->mOwnedByClient = false; 1689 1690 return OK; 1691 } 1692 1693 ssize_t MediaCodec::dequeuePortBuffer(int32_t portIndex) { 1694 CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 1695 1696 List<size_t> *availBuffers = &mAvailPortBuffers[portIndex]; 1697 1698 if (availBuffers->empty()) { 1699 return -EAGAIN; 1700 } 1701 1702 size_t index = *availBuffers->begin(); 1703 availBuffers->erase(availBuffers->begin()); 1704 1705 BufferInfo *info = &mPortBuffers[portIndex].editItemAt(index); 1706 CHECK(!info->mOwnedByClient); 1707 info->mOwnedByClient = true; 1708 1709 return index; 1710 } 1711 1712 status_t MediaCodec::setNativeWindow( 1713 const sp<Surface> &surfaceTextureClient) { 1714 status_t err; 1715 1716 if (mNativeWindow != NULL) { 1717 err = native_window_api_disconnect( 1718 mNativeWindow.get(), NATIVE_WINDOW_API_MEDIA); 1719 1720 if (err != OK) { 1721 ALOGW("native_window_api_disconnect returned an error: %s (%d)", 1722 strerror(-err), err); 1723 } 1724 1725 mNativeWindow.clear(); 1726 } 1727 1728 if (surfaceTextureClient != NULL) { 1729 err = native_window_api_connect( 1730 surfaceTextureClient.get(), NATIVE_WINDOW_API_MEDIA); 1731 1732 if (err != OK) { 1733 ALOGE("native_window_api_connect returned an error: %s (%d)", 1734 strerror(-err), err); 1735 1736 return err; 1737 } 1738 1739 mNativeWindow = surfaceTextureClient; 1740 } 1741 1742 return OK; 1743 } 1744 1745 void MediaCodec::postActivityNotificationIfPossible() { 1746 if (mActivityNotify == NULL) { 1747 return; 1748 } 1749 1750 if ((mFlags & (kFlagStickyError 1751 | kFlagOutputBuffersChanged 1752 | kFlagOutputFormatChanged)) 1753 || !mAvailPortBuffers[kPortIndexInput].empty() 1754 || !mAvailPortBuffers[kPortIndexOutput].empty()) { 1755 mActivityNotify->post(); 1756 mActivityNotify.clear(); 1757 } 1758 } 1759 1760 status_t MediaCodec::setParameters(const sp<AMessage> ¶ms) { 1761 sp<AMessage> msg = new AMessage(kWhatSetParameters, id()); 1762 msg->setMessage("params", params); 1763 1764 sp<AMessage> response; 1765 return PostAndAwaitResponse(msg, &response); 1766 } 1767 1768 status_t MediaCodec::onSetParameters(const sp<AMessage> ¶ms) { 1769 mCodec->signalSetParameters(params); 1770 1771 return OK; 1772 } 1773 1774 status_t MediaCodec::amendOutputFormatWithCodecSpecificData( 1775 const sp<ABuffer> &buffer) { 1776 AString mime; 1777 CHECK(mOutputFormat->findString("mime", &mime)); 1778 1779 if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)) { 1780 // Codec specific data should be SPS and PPS in a single buffer, 1781 // each prefixed by a startcode (0x00 0x00 0x00 0x01). 1782 // We separate the two and put them into the output format 1783 // under the keys "csd-0" and "csd-1". 1784 1785 unsigned csdIndex = 0; 1786 1787 const uint8_t *data = buffer->data(); 1788 size_t size = buffer->size(); 1789 1790 const uint8_t *nalStart; 1791 size_t nalSize; 1792 while (getNextNALUnit(&data, &size, &nalStart, &nalSize, true) == OK) { 1793 sp<ABuffer> csd = new ABuffer(nalSize + 4); 1794 memcpy(csd->data(), "\x00\x00\x00\x01", 4); 1795 memcpy(csd->data() + 4, nalStart, nalSize); 1796 1797 mOutputFormat->setBuffer( 1798 StringPrintf("csd-%u", csdIndex).c_str(), csd); 1799 1800 ++csdIndex; 1801 } 1802 1803 if (csdIndex != 2) { 1804 return ERROR_MALFORMED; 1805 } 1806 } else { 1807 // For everything else we just stash the codec specific data into 1808 // the output format as a single piece of csd under "csd-0". 1809 mOutputFormat->setBuffer("csd-0", buffer); 1810 } 1811 1812 return OK; 1813 } 1814 1815 } // namespace android 1816