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