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