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