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