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