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