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