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