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