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