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