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