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