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