MediaCodec.cpp revision 3b2847fa5506dc265d2e46f067bfbb66ae209f74
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/SecureBuffer.h" 23#include "include/SharedMemoryBuffer.h" 24#include "include/SoftwareRenderer.h" 25 26#include <android/media/IDescrambler.h> 27#include <binder/IMemory.h> 28#include <binder/IPCThreadState.h> 29#include <binder/IServiceManager.h> 30#include <binder/MemoryDealer.h> 31#include <gui/BufferQueue.h> 32#include <gui/Surface.h> 33#include <media/ICrypto.h> 34#include <media/IOMX.h> 35#include <media/IResourceManagerService.h> 36#include <media/MediaCodecBuffer.h> 37#include <media/MediaAnalyticsItem.h> 38#include <media/stagefright/foundation/ABuffer.h> 39#include <media/stagefright/foundation/ADebug.h> 40#include <media/stagefright/foundation/AMessage.h> 41#include <media/stagefright/foundation/AString.h> 42#include <media/stagefright/foundation/AUtils.h> 43#include <media/stagefright/foundation/hexdump.h> 44#include <media/stagefright/ACodec.h> 45#include <media/stagefright/BufferProducerWrapper.h> 46#include <media/stagefright/MediaCodec.h> 47#include <media/stagefright/MediaCodecList.h> 48#include <media/stagefright/MediaDefs.h> 49#include <media/stagefright/MediaErrors.h> 50#include <media/stagefright/MediaFilter.h> 51#include <media/stagefright/MetaData.h> 52#include <media/stagefright/OMXClient.h> 53#include <media/stagefright/PersistentSurface.h> 54#include <media/stagefright/SurfaceUtils.h> 55#include <mediautils/BatteryNotifier.h> 56#include <private/android_filesystem_config.h> 57#include <utils/Log.h> 58#include <utils/Singleton.h> 59 60namespace android { 61 62// key for media statistics 63static const char *kCodecKeyName = "codec"; 64// attrs for media statistics 65static const char *kCodecCodec = "codec"; /* e.g. OMX.google.aac.decoder */ 66static const char *kCodecMime = "mime"; /* e.g. audio/mime */ 67static const char *kCodecMode = "mode"; /* audio, video */ 68static const char *kCodecSecure = "secure"; /* 0, 1 */ 69 70 71 72static int64_t getId(const sp<IResourceManagerClient> &client) { 73 return (int64_t) client.get(); 74} 75 76static bool isResourceError(status_t err) { 77 return (err == NO_MEMORY); 78} 79 80static const int kMaxRetry = 2; 81static const int kMaxReclaimWaitTimeInUs = 500000; // 0.5s 82static const int kNumBuffersAlign = 16; 83 84//////////////////////////////////////////////////////////////////////////////// 85 86struct ResourceManagerClient : public BnResourceManagerClient { 87 explicit ResourceManagerClient(MediaCodec* codec) : mMediaCodec(codec) {} 88 89 virtual bool reclaimResource() { 90 sp<MediaCodec> codec = mMediaCodec.promote(); 91 if (codec == NULL) { 92 // codec is already gone. 93 return true; 94 } 95 status_t err = codec->reclaim(); 96 if (err == WOULD_BLOCK) { 97 ALOGD("Wait for the client to release codec."); 98 usleep(kMaxReclaimWaitTimeInUs); 99 ALOGD("Try to reclaim again."); 100 err = codec->reclaim(true /* force */); 101 } 102 if (err != OK) { 103 ALOGW("ResourceManagerClient failed to release codec with err %d", err); 104 } 105 return (err == OK); 106 } 107 108 virtual String8 getName() { 109 String8 ret; 110 sp<MediaCodec> codec = mMediaCodec.promote(); 111 if (codec == NULL) { 112 // codec is already gone. 113 return ret; 114 } 115 116 AString name; 117 if (codec->getName(&name) == OK) { 118 ret.setTo(name.c_str()); 119 } 120 return ret; 121 } 122 123protected: 124 virtual ~ResourceManagerClient() {} 125 126private: 127 wp<MediaCodec> mMediaCodec; 128 129 DISALLOW_EVIL_CONSTRUCTORS(ResourceManagerClient); 130}; 131 132MediaCodec::ResourceManagerServiceProxy::ResourceManagerServiceProxy(pid_t pid) 133 : mPid(pid) { 134 if (mPid == MediaCodec::kNoPid) { 135 mPid = IPCThreadState::self()->getCallingPid(); 136 } 137} 138 139MediaCodec::ResourceManagerServiceProxy::~ResourceManagerServiceProxy() { 140 if (mService != NULL) { 141 IInterface::asBinder(mService)->unlinkToDeath(this); 142 } 143} 144 145void MediaCodec::ResourceManagerServiceProxy::init() { 146 sp<IServiceManager> sm = defaultServiceManager(); 147 sp<IBinder> binder = sm->getService(String16("media.resource_manager")); 148 mService = interface_cast<IResourceManagerService>(binder); 149 if (mService == NULL) { 150 ALOGE("Failed to get ResourceManagerService"); 151 return; 152 } 153 IInterface::asBinder(mService)->linkToDeath(this); 154} 155 156void MediaCodec::ResourceManagerServiceProxy::binderDied(const wp<IBinder>& /*who*/) { 157 ALOGW("ResourceManagerService died."); 158 Mutex::Autolock _l(mLock); 159 mService.clear(); 160} 161 162void MediaCodec::ResourceManagerServiceProxy::addResource( 163 int64_t clientId, 164 const sp<IResourceManagerClient> &client, 165 const Vector<MediaResource> &resources) { 166 Mutex::Autolock _l(mLock); 167 if (mService == NULL) { 168 return; 169 } 170 mService->addResource(mPid, clientId, client, resources); 171} 172 173void MediaCodec::ResourceManagerServiceProxy::removeResource(int64_t clientId) { 174 Mutex::Autolock _l(mLock); 175 if (mService == NULL) { 176 return; 177 } 178 mService->removeResource(mPid, clientId); 179} 180 181bool MediaCodec::ResourceManagerServiceProxy::reclaimResource( 182 const Vector<MediaResource> &resources) { 183 Mutex::Autolock _l(mLock); 184 if (mService == NULL) { 185 return false; 186 } 187 return mService->reclaimResource(mPid, resources); 188} 189 190//////////////////////////////////////////////////////////////////////////////// 191 192MediaCodec::BufferInfo::BufferInfo() : mOwnedByClient(false) {} 193 194//////////////////////////////////////////////////////////////////////////////// 195 196namespace { 197 198enum { 199 kWhatFillThisBuffer = 'fill', 200 kWhatDrainThisBuffer = 'drai', 201 kWhatEOS = 'eos ', 202 kWhatStartCompleted = 'Scom', 203 kWhatStopCompleted = 'scom', 204 kWhatReleaseCompleted = 'rcom', 205 kWhatFlushCompleted = 'fcom', 206 kWhatError = 'erro', 207 kWhatComponentAllocated = 'cAll', 208 kWhatComponentConfigured = 'cCon', 209 kWhatInputSurfaceCreated = 'isfc', 210 kWhatInputSurfaceAccepted = 'isfa', 211 kWhatSignaledInputEOS = 'seos', 212 kWhatOutputFramesRendered = 'outR', 213 kWhatOutputBuffersChanged = 'outC', 214}; 215 216class BufferCallback : public CodecBase::BufferCallback { 217public: 218 explicit BufferCallback(const sp<AMessage> ¬ify); 219 virtual ~BufferCallback() = default; 220 221 virtual void onInputBufferAvailable( 222 size_t index, const sp<MediaCodecBuffer> &buffer) override; 223 virtual void onOutputBufferAvailable( 224 size_t index, const sp<MediaCodecBuffer> &buffer) override; 225private: 226 const sp<AMessage> mNotify; 227}; 228 229BufferCallback::BufferCallback(const sp<AMessage> ¬ify) 230 : mNotify(notify) {} 231 232void BufferCallback::onInputBufferAvailable( 233 size_t index, const sp<MediaCodecBuffer> &buffer) { 234 sp<AMessage> notify(mNotify->dup()); 235 notify->setInt32("what", kWhatFillThisBuffer); 236 notify->setSize("index", index); 237 notify->setObject("buffer", buffer); 238 notify->post(); 239} 240 241void BufferCallback::onOutputBufferAvailable( 242 size_t index, const sp<MediaCodecBuffer> &buffer) { 243 sp<AMessage> notify(mNotify->dup()); 244 notify->setInt32("what", kWhatDrainThisBuffer); 245 notify->setSize("index", index); 246 notify->setObject("buffer", buffer); 247 notify->post(); 248} 249 250class CodecCallback : public CodecBase::CodecCallback { 251public: 252 explicit CodecCallback(const sp<AMessage> ¬ify); 253 virtual ~CodecCallback() = default; 254 255 virtual void onEos(status_t err) override; 256 virtual void onStartCompleted() override; 257 virtual void onStopCompleted() override; 258 virtual void onReleaseCompleted() override; 259 virtual void onFlushCompleted() override; 260 virtual void onError(status_t err, enum ActionCode actionCode) override; 261 virtual void onComponentAllocated(const char *componentName) override; 262 virtual void onComponentConfigured( 263 const sp<AMessage> &inputFormat, const sp<AMessage> &outputFormat) override; 264 virtual void onInputSurfaceCreated( 265 const sp<AMessage> &inputFormat, 266 const sp<AMessage> &outputFormat, 267 const sp<BufferProducerWrapper> &inputSurface) override; 268 virtual void onInputSurfaceCreationFailed(status_t err) override; 269 virtual void onInputSurfaceAccepted( 270 const sp<AMessage> &inputFormat, 271 const sp<AMessage> &outputFormat) override; 272 virtual void onInputSurfaceDeclined(status_t err) override; 273 virtual void onSignaledInputEOS(status_t err) override; 274 virtual void onOutputFramesRendered(const std::list<FrameRenderTracker::Info> &done) override; 275 virtual void onOutputBuffersChanged() override; 276private: 277 const sp<AMessage> mNotify; 278}; 279 280CodecCallback::CodecCallback(const sp<AMessage> ¬ify) : mNotify(notify) {} 281 282void CodecCallback::onEos(status_t err) { 283 sp<AMessage> notify(mNotify->dup()); 284 notify->setInt32("what", kWhatEOS); 285 notify->setInt32("err", err); 286 notify->post(); 287} 288 289void CodecCallback::onStartCompleted() { 290 sp<AMessage> notify(mNotify->dup()); 291 notify->setInt32("what", kWhatStartCompleted); 292 notify->post(); 293} 294 295void CodecCallback::onStopCompleted() { 296 sp<AMessage> notify(mNotify->dup()); 297 notify->setInt32("what", kWhatStopCompleted); 298 notify->post(); 299} 300 301void CodecCallback::onReleaseCompleted() { 302 sp<AMessage> notify(mNotify->dup()); 303 notify->setInt32("what", kWhatReleaseCompleted); 304 notify->post(); 305} 306 307void CodecCallback::onFlushCompleted() { 308 sp<AMessage> notify(mNotify->dup()); 309 notify->setInt32("what", kWhatFlushCompleted); 310 notify->post(); 311} 312 313void CodecCallback::onError(status_t err, enum ActionCode actionCode) { 314 sp<AMessage> notify(mNotify->dup()); 315 notify->setInt32("what", kWhatError); 316 notify->setInt32("err", err); 317 notify->setInt32("actionCode", actionCode); 318 notify->post(); 319} 320 321void CodecCallback::onComponentAllocated(const char *componentName) { 322 sp<AMessage> notify(mNotify->dup()); 323 notify->setInt32("what", kWhatComponentAllocated); 324 notify->setString("componentName", componentName); 325 notify->post(); 326} 327 328void CodecCallback::onComponentConfigured( 329 const sp<AMessage> &inputFormat, const sp<AMessage> &outputFormat) { 330 sp<AMessage> notify(mNotify->dup()); 331 notify->setInt32("what", kWhatComponentConfigured); 332 notify->setMessage("input-format", inputFormat); 333 notify->setMessage("output-format", outputFormat); 334 notify->post(); 335} 336 337void CodecCallback::onInputSurfaceCreated( 338 const sp<AMessage> &inputFormat, 339 const sp<AMessage> &outputFormat, 340 const sp<BufferProducerWrapper> &inputSurface) { 341 sp<AMessage> notify(mNotify->dup()); 342 notify->setInt32("what", kWhatInputSurfaceCreated); 343 notify->setMessage("input-format", inputFormat); 344 notify->setMessage("output-format", outputFormat); 345 notify->setObject("input-surface", inputSurface); 346 notify->post(); 347} 348 349void CodecCallback::onInputSurfaceCreationFailed(status_t err) { 350 sp<AMessage> notify(mNotify->dup()); 351 notify->setInt32("what", kWhatInputSurfaceCreated); 352 notify->setInt32("err", err); 353 notify->post(); 354} 355 356void CodecCallback::onInputSurfaceAccepted( 357 const sp<AMessage> &inputFormat, 358 const sp<AMessage> &outputFormat) { 359 sp<AMessage> notify(mNotify->dup()); 360 notify->setInt32("what", kWhatInputSurfaceAccepted); 361 notify->setMessage("input-format", inputFormat); 362 notify->setMessage("output-format", outputFormat); 363 notify->post(); 364} 365 366void CodecCallback::onInputSurfaceDeclined(status_t err) { 367 sp<AMessage> notify(mNotify->dup()); 368 notify->setInt32("what", kWhatInputSurfaceAccepted); 369 notify->setInt32("err", err); 370 notify->post(); 371} 372 373void CodecCallback::onSignaledInputEOS(status_t err) { 374 sp<AMessage> notify(mNotify->dup()); 375 notify->setInt32("what", kWhatSignaledInputEOS); 376 if (err != OK) { 377 notify->setInt32("err", err); 378 } 379 notify->post(); 380} 381 382void CodecCallback::onOutputFramesRendered(const std::list<FrameRenderTracker::Info> &done) { 383 sp<AMessage> notify(mNotify->dup()); 384 notify->setInt32("what", kWhatOutputFramesRendered); 385 if (MediaCodec::CreateFramesRenderedMessage(done, notify)) { 386 notify->post(); 387 } 388} 389 390void CodecCallback::onOutputBuffersChanged() { 391 sp<AMessage> notify(mNotify->dup()); 392 notify->setInt32("what", kWhatOutputBuffersChanged); 393 notify->post(); 394} 395 396} // namespace 397 398//////////////////////////////////////////////////////////////////////////////// 399 400// static 401sp<MediaCodec> MediaCodec::CreateByType( 402 const sp<ALooper> &looper, const AString &mime, bool encoder, status_t *err, pid_t pid, 403 uid_t uid) { 404 sp<MediaCodec> codec = new MediaCodec(looper, pid, uid); 405 406 const status_t ret = codec->init(mime, true /* nameIsType */, encoder); 407 if (err != NULL) { 408 *err = ret; 409 } 410 return ret == OK ? codec : NULL; // NULL deallocates codec. 411} 412 413// static 414sp<MediaCodec> MediaCodec::CreateByComponentName( 415 const sp<ALooper> &looper, const AString &name, status_t *err, pid_t pid, uid_t uid) { 416 sp<MediaCodec> codec = new MediaCodec(looper, pid, uid); 417 418 const status_t ret = codec->init(name, false /* nameIsType */, false /* encoder */); 419 if (err != NULL) { 420 *err = ret; 421 } 422 return ret == OK ? codec : NULL; // NULL deallocates codec. 423} 424 425// static 426status_t MediaCodec::QueryCapabilities( 427 const AString &name, const AString &mime, bool isEncoder, 428 sp<MediaCodecInfo::Capabilities> *caps /* nonnull */) { 429 // TRICKY: this method is used by MediaCodecList/Info during its 430 // initialization. As such, we cannot create a MediaCodec instance 431 // because that requires an initialized MediaCodecList. 432 433 sp<CodecBase> codec = GetCodecBase(name); 434 if (codec == NULL) { 435 return NAME_NOT_FOUND; 436 } 437 438 return codec->queryCapabilities(name, mime, isEncoder, caps); 439} 440 441// static 442sp<PersistentSurface> MediaCodec::CreatePersistentInputSurface() { 443 OMXClient client; 444 if (client.connect() != OK) { 445 ALOGE("Failed to connect to OMX to create persistent input surface."); 446 return NULL; 447 } 448 449 sp<IOMX> omx = client.interface(); 450 451 sp<IGraphicBufferProducer> bufferProducer; 452 sp<IGraphicBufferSource> bufferSource; 453 454 status_t err = omx->createInputSurface(&bufferProducer, &bufferSource); 455 456 if (err != OK) { 457 ALOGE("Failed to create persistent input surface."); 458 return NULL; 459 } 460 461 return new PersistentSurface(bufferProducer, bufferSource); 462} 463 464MediaCodec::MediaCodec(const sp<ALooper> &looper, pid_t pid, uid_t uid) 465 : mState(UNINITIALIZED), 466 mReleasedByResourceManager(false), 467 mLooper(looper), 468 mCodec(NULL), 469 mReplyID(0), 470 mFlags(0), 471 mStickyError(OK), 472 mSoftRenderer(NULL), 473 mResourceManagerClient(new ResourceManagerClient(this)), 474 mResourceManagerService(new ResourceManagerServiceProxy(pid)), 475 mBatteryStatNotified(false), 476 mIsVideo(false), 477 mVideoWidth(0), 478 mVideoHeight(0), 479 mRotationDegrees(0), 480 mDequeueInputTimeoutGeneration(0), 481 mDequeueInputReplyID(0), 482 mDequeueOutputTimeoutGeneration(0), 483 mDequeueOutputReplyID(0), 484 mHaveInputSurface(false), 485 mHavePendingInputBuffers(false) { 486 if (uid == kNoUid) { 487 mUid = IPCThreadState::self()->getCallingUid(); 488 } else { 489 mUid = uid; 490 } 491 // set up our new record, get a sessionID, put it into the in-progress list 492 mAnalyticsItem = new MediaAnalyticsItem(kCodecKeyName); 493 if (mAnalyticsItem != NULL) { 494 (void) mAnalyticsItem->generateSessionID(); 495 // don't record it yet; only at the end, when we have decided that we have 496 // data worth writing (e.g. .count() > 0) 497 } 498} 499 500MediaCodec::~MediaCodec() { 501 CHECK_EQ(mState, UNINITIALIZED); 502 mResourceManagerService->removeResource(getId(mResourceManagerClient)); 503 504 if (mAnalyticsItem != NULL ) { 505 if (mAnalyticsItem->count() > 0) { 506 mAnalyticsItem->setFinalized(true); 507 mAnalyticsItem->selfrecord(); 508 } 509 delete mAnalyticsItem; 510 mAnalyticsItem = NULL; 511 } 512} 513 514// static 515status_t MediaCodec::PostAndAwaitResponse( 516 const sp<AMessage> &msg, sp<AMessage> *response) { 517 status_t err = msg->postAndAwaitResponse(response); 518 519 if (err != OK) { 520 return err; 521 } 522 523 if (!(*response)->findInt32("err", &err)) { 524 err = OK; 525 } 526 527 return err; 528} 529 530void MediaCodec::PostReplyWithError(const sp<AReplyToken> &replyID, int32_t err) { 531 int32_t finalErr = err; 532 if (mReleasedByResourceManager) { 533 // override the err code if MediaCodec has been released by ResourceManager. 534 finalErr = DEAD_OBJECT; 535 } 536 537 sp<AMessage> response = new AMessage; 538 response->setInt32("err", finalErr); 539 response->postReply(replyID); 540} 541 542//static 543sp<CodecBase> MediaCodec::GetCodecBase(const AString &name, bool nameIsType) { 544 // at this time only ACodec specifies a mime type. 545 if (nameIsType || name.startsWithIgnoreCase("omx.")) { 546 return new ACodec; 547 } else if (name.startsWithIgnoreCase("android.filter.")) { 548 return new MediaFilter; 549 } else { 550 return NULL; 551 } 552} 553 554status_t MediaCodec::init(const AString &name, bool nameIsType, bool encoder) { 555 mResourceManagerService->init(); 556 557 // save init parameters for reset 558 mInitName = name; 559 mInitNameIsType = nameIsType; 560 mInitIsEncoder = encoder; 561 562 // Current video decoders do not return from OMX_FillThisBuffer 563 // quickly, violating the OpenMAX specs, until that is remedied 564 // we need to invest in an extra looper to free the main event 565 // queue. 566 567 mCodec = GetCodecBase(name, nameIsType); 568 if (mCodec == NULL) { 569 return NAME_NOT_FOUND; 570 } 571 572 bool secureCodec = false; 573 if (nameIsType && !strncasecmp(name.c_str(), "video/", 6)) { 574 mIsVideo = true; 575 } else { 576 AString tmp = name; 577 if (tmp.endsWith(".secure")) { 578 secureCodec = true; 579 tmp.erase(tmp.size() - 7, 7); 580 } 581 const sp<IMediaCodecList> mcl = MediaCodecList::getInstance(); 582 if (mcl == NULL) { 583 mCodec = NULL; // remove the codec. 584 return NO_INIT; // if called from Java should raise IOException 585 } 586 ssize_t codecIdx = mcl->findCodecByName(tmp.c_str()); 587 if (codecIdx >= 0) { 588 const sp<MediaCodecInfo> info = mcl->getCodecInfo(codecIdx); 589 Vector<AString> mimes; 590 info->getSupportedMimes(&mimes); 591 for (size_t i = 0; i < mimes.size(); i++) { 592 if (mimes[i].startsWith("video/")) { 593 mIsVideo = true; 594 break; 595 } 596 } 597 } 598 } 599 600 if (mIsVideo) { 601 // video codec needs dedicated looper 602 if (mCodecLooper == NULL) { 603 mCodecLooper = new ALooper; 604 mCodecLooper->setName("CodecLooper"); 605 mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO); 606 } 607 608 mCodecLooper->registerHandler(mCodec); 609 } else { 610 mLooper->registerHandler(mCodec); 611 } 612 613 mLooper->registerHandler(this); 614 615 mCodec->setCallback( 616 std::unique_ptr<CodecBase::CodecCallback>( 617 new CodecCallback(new AMessage(kWhatCodecNotify, this)))); 618 mBufferChannel = mCodec->getBufferChannel(); 619 mBufferChannel->setCallback( 620 std::unique_ptr<CodecBase::BufferCallback>( 621 new BufferCallback(new AMessage(kWhatCodecNotify, this)))); 622 623 sp<AMessage> msg = new AMessage(kWhatInit, this); 624 msg->setString("name", name); 625 msg->setInt32("nameIsType", nameIsType); 626 627 if (nameIsType) { 628 msg->setInt32("encoder", encoder); 629 } 630 631 if (mAnalyticsItem != NULL) { 632 if (nameIsType) { 633 // name is the mime type 634 mAnalyticsItem->setCString(kCodecMime, name.c_str()); 635 } else { 636 mAnalyticsItem->setCString(kCodecCodec, name.c_str()); 637 } 638 mAnalyticsItem->setCString(kCodecMode, mIsVideo ? "video" : "audio"); 639 //mAnalyticsItem->setInt32("type", nameIsType); 640 if (nameIsType) 641 mAnalyticsItem->setInt32("encoder", encoder); 642 } 643 644 status_t err; 645 Vector<MediaResource> resources; 646 MediaResource::Type type = 647 secureCodec ? MediaResource::kSecureCodec : MediaResource::kNonSecureCodec; 648 MediaResource::SubType subtype = 649 mIsVideo ? MediaResource::kVideoCodec : MediaResource::kAudioCodec; 650 resources.push_back(MediaResource(type, subtype, 1)); 651 for (int i = 0; i <= kMaxRetry; ++i) { 652 if (i > 0) { 653 // Don't try to reclaim resource for the first time. 654 if (!mResourceManagerService->reclaimResource(resources)) { 655 break; 656 } 657 } 658 659 sp<AMessage> response; 660 err = PostAndAwaitResponse(msg, &response); 661 if (!isResourceError(err)) { 662 break; 663 } 664 } 665 return err; 666} 667 668status_t MediaCodec::setCallback(const sp<AMessage> &callback) { 669 sp<AMessage> msg = new AMessage(kWhatSetCallback, this); 670 msg->setMessage("callback", callback); 671 672 sp<AMessage> response; 673 return PostAndAwaitResponse(msg, &response); 674} 675 676status_t MediaCodec::setOnFrameRenderedNotification(const sp<AMessage> ¬ify) { 677 sp<AMessage> msg = new AMessage(kWhatSetNotification, this); 678 msg->setMessage("on-frame-rendered", notify); 679 return msg->post(); 680} 681 682status_t MediaCodec::configure( 683 const sp<AMessage> &format, 684 const sp<Surface> &nativeWindow, 685 const sp<ICrypto> &crypto, 686 uint32_t flags) { 687 return configure(format, nativeWindow, crypto, NULL, flags); 688} 689 690status_t MediaCodec::configure( 691 const sp<AMessage> &format, 692 const sp<Surface> &surface, 693 const sp<ICrypto> &crypto, 694 const sp<IDescrambler> &descrambler, 695 uint32_t flags) { 696 sp<AMessage> msg = new AMessage(kWhatConfigure, this); 697 698 if (mIsVideo) { 699 format->findInt32("width", &mVideoWidth); 700 format->findInt32("height", &mVideoHeight); 701 if (!format->findInt32("rotation-degrees", &mRotationDegrees)) { 702 mRotationDegrees = 0; 703 } 704 705 if (mAnalyticsItem != NULL) { 706 mAnalyticsItem->setInt32("width", mVideoWidth); 707 mAnalyticsItem->setInt32("height", mVideoHeight); 708 mAnalyticsItem->setInt32("rotation", mRotationDegrees); 709 } 710 711 // Prevent possible integer overflow in downstream code. 712 if (mInitIsEncoder 713 && (uint64_t)mVideoWidth * mVideoHeight > (uint64_t)INT32_MAX / 4) { 714 ALOGE("buffer size is too big, width=%d, height=%d", mVideoWidth, mVideoHeight); 715 return BAD_VALUE; 716 } 717 } 718 719 msg->setMessage("format", format); 720 msg->setInt32("flags", flags); 721 msg->setObject("surface", surface); 722 723 if (crypto != NULL || descrambler != NULL) { 724 if (crypto != NULL) { 725 msg->setPointer("crypto", crypto.get()); 726 } else { 727 msg->setPointer("descrambler", descrambler.get()); 728 } 729 if (mAnalyticsItem != NULL) { 730 // XXX: save indication that it's crypto in some way... 731 mAnalyticsItem->setInt32("crypto", 1); 732 } 733 } 734 735 // save msg for reset 736 mConfigureMsg = msg; 737 738 status_t err; 739 Vector<MediaResource> resources; 740 MediaResource::Type type = (mFlags & kFlagIsSecure) ? 741 MediaResource::kSecureCodec : MediaResource::kNonSecureCodec; 742 MediaResource::SubType subtype = 743 mIsVideo ? MediaResource::kVideoCodec : MediaResource::kAudioCodec; 744 resources.push_back(MediaResource(type, subtype, 1)); 745 // Don't know the buffer size at this point, but it's fine to use 1 because 746 // the reclaimResource call doesn't consider the requester's buffer size for now. 747 resources.push_back(MediaResource(MediaResource::kGraphicMemory, 1)); 748 for (int i = 0; i <= kMaxRetry; ++i) { 749 if (i > 0) { 750 // Don't try to reclaim resource for the first time. 751 if (!mResourceManagerService->reclaimResource(resources)) { 752 break; 753 } 754 } 755 756 sp<AMessage> response; 757 err = PostAndAwaitResponse(msg, &response); 758 if (err != OK && err != INVALID_OPERATION) { 759 // MediaCodec now set state to UNINITIALIZED upon any fatal error. 760 // To maintain backward-compatibility, do a reset() to put codec 761 // back into INITIALIZED state. 762 // But don't reset if the err is INVALID_OPERATION, which means 763 // the configure failure is due to wrong state. 764 765 ALOGE("configure failed with err 0x%08x, resetting...", err); 766 reset(); 767 } 768 if (!isResourceError(err)) { 769 break; 770 } 771 } 772 return err; 773} 774 775status_t MediaCodec::releaseCrypto() 776{ 777 ALOGV("releaseCrypto"); 778 779 sp<AMessage> msg = new AMessage(kWhatDrmReleaseCrypto, this); 780 781 sp<AMessage> response; 782 status_t status = msg->postAndAwaitResponse(&response); 783 784 if (status == OK && response != NULL) { 785 CHECK(response->findInt32("status", &status)); 786 ALOGV("releaseCrypto ret: %d ", status); 787 } 788 else { 789 ALOGE("releaseCrypto err: %d", status); 790 } 791 792 return status; 793} 794 795void MediaCodec::onReleaseCrypto(const sp<AMessage>& msg) 796{ 797 status_t status = INVALID_OPERATION; 798 if (mCrypto != NULL) { 799 ALOGV("onReleaseCrypto: mCrypto: %p (%d)", mCrypto.get(), mCrypto->getStrongCount()); 800 mBufferChannel->setCrypto(NULL); 801 // TODO change to ALOGV 802 ALOGD("onReleaseCrypto: [before clear] mCrypto: %p (%d)", 803 mCrypto.get(), mCrypto->getStrongCount()); 804 mCrypto.clear(); 805 806 status = OK; 807 } 808 else { 809 ALOGW("onReleaseCrypto: No mCrypto. err: %d", status); 810 } 811 812 sp<AMessage> response = new AMessage; 813 response->setInt32("status", status); 814 815 sp<AReplyToken> replyID; 816 CHECK(msg->senderAwaitsResponse(&replyID)); 817 response->postReply(replyID); 818} 819 820status_t MediaCodec::setInputSurface( 821 const sp<PersistentSurface> &surface) { 822 sp<AMessage> msg = new AMessage(kWhatSetInputSurface, this); 823 msg->setObject("input-surface", surface.get()); 824 825 sp<AMessage> response; 826 return PostAndAwaitResponse(msg, &response); 827} 828 829status_t MediaCodec::setSurface(const sp<Surface> &surface) { 830 sp<AMessage> msg = new AMessage(kWhatSetSurface, this); 831 msg->setObject("surface", surface); 832 833 sp<AMessage> response; 834 return PostAndAwaitResponse(msg, &response); 835} 836 837status_t MediaCodec::createInputSurface( 838 sp<IGraphicBufferProducer>* bufferProducer) { 839 sp<AMessage> msg = new AMessage(kWhatCreateInputSurface, this); 840 841 sp<AMessage> response; 842 status_t err = PostAndAwaitResponse(msg, &response); 843 if (err == NO_ERROR) { 844 // unwrap the sp<IGraphicBufferProducer> 845 sp<RefBase> obj; 846 bool found = response->findObject("input-surface", &obj); 847 CHECK(found); 848 sp<BufferProducerWrapper> wrapper( 849 static_cast<BufferProducerWrapper*>(obj.get())); 850 *bufferProducer = wrapper->getBufferProducer(); 851 } else { 852 ALOGW("createInputSurface failed, err=%d", err); 853 } 854 return err; 855} 856 857uint64_t MediaCodec::getGraphicBufferSize() { 858 if (!mIsVideo) { 859 return 0; 860 } 861 862 uint64_t size = 0; 863 size_t portNum = sizeof(mPortBuffers) / sizeof((mPortBuffers)[0]); 864 for (size_t i = 0; i < portNum; ++i) { 865 // TODO: this is just an estimation, we should get the real buffer size from ACodec. 866 size += mPortBuffers[i].size() * mVideoWidth * mVideoHeight * 3 / 2; 867 } 868 return size; 869} 870 871void MediaCodec::addResource( 872 MediaResource::Type type, MediaResource::SubType subtype, uint64_t value) { 873 Vector<MediaResource> resources; 874 resources.push_back(MediaResource(type, subtype, value)); 875 mResourceManagerService->addResource( 876 getId(mResourceManagerClient), mResourceManagerClient, resources); 877} 878 879status_t MediaCodec::start() { 880 sp<AMessage> msg = new AMessage(kWhatStart, this); 881 882 status_t err; 883 Vector<MediaResource> resources; 884 MediaResource::Type type = (mFlags & kFlagIsSecure) ? 885 MediaResource::kSecureCodec : MediaResource::kNonSecureCodec; 886 MediaResource::SubType subtype = 887 mIsVideo ? MediaResource::kVideoCodec : MediaResource::kAudioCodec; 888 resources.push_back(MediaResource(type, subtype, 1)); 889 // Don't know the buffer size at this point, but it's fine to use 1 because 890 // the reclaimResource call doesn't consider the requester's buffer size for now. 891 resources.push_back(MediaResource(MediaResource::kGraphicMemory, 1)); 892 for (int i = 0; i <= kMaxRetry; ++i) { 893 if (i > 0) { 894 // Don't try to reclaim resource for the first time. 895 if (!mResourceManagerService->reclaimResource(resources)) { 896 break; 897 } 898 // Recover codec from previous error before retry start. 899 err = reset(); 900 if (err != OK) { 901 ALOGE("retrying start: failed to reset codec"); 902 break; 903 } 904 sp<AMessage> response; 905 err = PostAndAwaitResponse(mConfigureMsg, &response); 906 if (err != OK) { 907 ALOGE("retrying start: failed to configure codec"); 908 break; 909 } 910 } 911 912 sp<AMessage> response; 913 err = PostAndAwaitResponse(msg, &response); 914 if (!isResourceError(err)) { 915 break; 916 } 917 } 918 return err; 919} 920 921status_t MediaCodec::stop() { 922 sp<AMessage> msg = new AMessage(kWhatStop, this); 923 924 sp<AMessage> response; 925 return PostAndAwaitResponse(msg, &response); 926} 927 928bool MediaCodec::hasPendingBuffer(int portIndex) { 929 return std::any_of( 930 mPortBuffers[portIndex].begin(), mPortBuffers[portIndex].end(), 931 [](const BufferInfo &info) { return info.mOwnedByClient; }); 932} 933 934bool MediaCodec::hasPendingBuffer() { 935 return hasPendingBuffer(kPortIndexInput) || hasPendingBuffer(kPortIndexOutput); 936} 937 938status_t MediaCodec::reclaim(bool force) { 939 ALOGD("MediaCodec::reclaim(%p) %s", this, mInitName.c_str()); 940 sp<AMessage> msg = new AMessage(kWhatRelease, this); 941 msg->setInt32("reclaimed", 1); 942 msg->setInt32("force", force ? 1 : 0); 943 944 sp<AMessage> response; 945 status_t ret = PostAndAwaitResponse(msg, &response); 946 if (ret == -ENOENT) { 947 ALOGD("MediaCodec looper is gone, skip reclaim"); 948 ret = OK; 949 } 950 return ret; 951} 952 953status_t MediaCodec::release() { 954 sp<AMessage> msg = new AMessage(kWhatRelease, this); 955 956 sp<AMessage> response; 957 return PostAndAwaitResponse(msg, &response); 958} 959 960status_t MediaCodec::reset() { 961 /* When external-facing MediaCodec object is created, 962 it is already initialized. Thus, reset is essentially 963 release() followed by init(), plus clearing the state */ 964 965 status_t err = release(); 966 967 // unregister handlers 968 if (mCodec != NULL) { 969 if (mCodecLooper != NULL) { 970 mCodecLooper->unregisterHandler(mCodec->id()); 971 } else { 972 mLooper->unregisterHandler(mCodec->id()); 973 } 974 mCodec = NULL; 975 } 976 mLooper->unregisterHandler(id()); 977 978 mFlags = 0; // clear all flags 979 mStickyError = OK; 980 981 // reset state not reset by setState(UNINITIALIZED) 982 mReplyID = 0; 983 mDequeueInputReplyID = 0; 984 mDequeueOutputReplyID = 0; 985 mDequeueInputTimeoutGeneration = 0; 986 mDequeueOutputTimeoutGeneration = 0; 987 mHaveInputSurface = false; 988 989 if (err == OK) { 990 err = init(mInitName, mInitNameIsType, mInitIsEncoder); 991 } 992 return err; 993} 994 995status_t MediaCodec::queueInputBuffer( 996 size_t index, 997 size_t offset, 998 size_t size, 999 int64_t presentationTimeUs, 1000 uint32_t flags, 1001 AString *errorDetailMsg) { 1002 if (errorDetailMsg != NULL) { 1003 errorDetailMsg->clear(); 1004 } 1005 1006 sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this); 1007 msg->setSize("index", index); 1008 msg->setSize("offset", offset); 1009 msg->setSize("size", size); 1010 msg->setInt64("timeUs", presentationTimeUs); 1011 msg->setInt32("flags", flags); 1012 msg->setPointer("errorDetailMsg", errorDetailMsg); 1013 1014 sp<AMessage> response; 1015 return PostAndAwaitResponse(msg, &response); 1016} 1017 1018status_t MediaCodec::queueSecureInputBuffer( 1019 size_t index, 1020 size_t offset, 1021 const CryptoPlugin::SubSample *subSamples, 1022 size_t numSubSamples, 1023 const uint8_t key[16], 1024 const uint8_t iv[16], 1025 CryptoPlugin::Mode mode, 1026 const CryptoPlugin::Pattern &pattern, 1027 int64_t presentationTimeUs, 1028 uint32_t flags, 1029 AString *errorDetailMsg) { 1030 if (errorDetailMsg != NULL) { 1031 errorDetailMsg->clear(); 1032 } 1033 1034 sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this); 1035 msg->setSize("index", index); 1036 msg->setSize("offset", offset); 1037 msg->setPointer("subSamples", (void *)subSamples); 1038 msg->setSize("numSubSamples", numSubSamples); 1039 msg->setPointer("key", (void *)key); 1040 msg->setPointer("iv", (void *)iv); 1041 msg->setInt32("mode", mode); 1042 msg->setInt32("encryptBlocks", pattern.mEncryptBlocks); 1043 msg->setInt32("skipBlocks", pattern.mSkipBlocks); 1044 msg->setInt64("timeUs", presentationTimeUs); 1045 msg->setInt32("flags", flags); 1046 msg->setPointer("errorDetailMsg", errorDetailMsg); 1047 1048 sp<AMessage> response; 1049 status_t err = PostAndAwaitResponse(msg, &response); 1050 1051 return err; 1052} 1053 1054status_t MediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) { 1055 sp<AMessage> msg = new AMessage(kWhatDequeueInputBuffer, this); 1056 msg->setInt64("timeoutUs", timeoutUs); 1057 1058 sp<AMessage> response; 1059 status_t err; 1060 if ((err = PostAndAwaitResponse(msg, &response)) != OK) { 1061 return err; 1062 } 1063 1064 CHECK(response->findSize("index", index)); 1065 1066 return OK; 1067} 1068 1069status_t MediaCodec::dequeueOutputBuffer( 1070 size_t *index, 1071 size_t *offset, 1072 size_t *size, 1073 int64_t *presentationTimeUs, 1074 uint32_t *flags, 1075 int64_t timeoutUs) { 1076 sp<AMessage> msg = new AMessage(kWhatDequeueOutputBuffer, this); 1077 msg->setInt64("timeoutUs", timeoutUs); 1078 1079 sp<AMessage> response; 1080 status_t err; 1081 if ((err = PostAndAwaitResponse(msg, &response)) != OK) { 1082 return err; 1083 } 1084 1085 CHECK(response->findSize("index", index)); 1086 CHECK(response->findSize("offset", offset)); 1087 CHECK(response->findSize("size", size)); 1088 CHECK(response->findInt64("timeUs", presentationTimeUs)); 1089 CHECK(response->findInt32("flags", (int32_t *)flags)); 1090 1091 return OK; 1092} 1093 1094status_t MediaCodec::renderOutputBufferAndRelease(size_t index) { 1095 sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, this); 1096 msg->setSize("index", index); 1097 msg->setInt32("render", true); 1098 1099 sp<AMessage> response; 1100 return PostAndAwaitResponse(msg, &response); 1101} 1102 1103status_t MediaCodec::renderOutputBufferAndRelease(size_t index, int64_t timestampNs) { 1104 sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, this); 1105 msg->setSize("index", index); 1106 msg->setInt32("render", true); 1107 msg->setInt64("timestampNs", timestampNs); 1108 1109 sp<AMessage> response; 1110 return PostAndAwaitResponse(msg, &response); 1111} 1112 1113status_t MediaCodec::releaseOutputBuffer(size_t index) { 1114 sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, this); 1115 msg->setSize("index", index); 1116 1117 sp<AMessage> response; 1118 return PostAndAwaitResponse(msg, &response); 1119} 1120 1121status_t MediaCodec::signalEndOfInputStream() { 1122 sp<AMessage> msg = new AMessage(kWhatSignalEndOfInputStream, this); 1123 1124 sp<AMessage> response; 1125 return PostAndAwaitResponse(msg, &response); 1126} 1127 1128status_t MediaCodec::getOutputFormat(sp<AMessage> *format) const { 1129 sp<AMessage> msg = new AMessage(kWhatGetOutputFormat, this); 1130 1131 sp<AMessage> response; 1132 status_t err; 1133 if ((err = PostAndAwaitResponse(msg, &response)) != OK) { 1134 return err; 1135 } 1136 1137 CHECK(response->findMessage("format", format)); 1138 1139 return OK; 1140} 1141 1142status_t MediaCodec::getInputFormat(sp<AMessage> *format) const { 1143 sp<AMessage> msg = new AMessage(kWhatGetInputFormat, this); 1144 1145 sp<AMessage> response; 1146 status_t err; 1147 if ((err = PostAndAwaitResponse(msg, &response)) != OK) { 1148 return err; 1149 } 1150 1151 CHECK(response->findMessage("format", format)); 1152 1153 return OK; 1154} 1155 1156status_t MediaCodec::getName(AString *name) const { 1157 sp<AMessage> msg = new AMessage(kWhatGetName, this); 1158 1159 sp<AMessage> response; 1160 status_t err; 1161 if ((err = PostAndAwaitResponse(msg, &response)) != OK) { 1162 return err; 1163 } 1164 1165 CHECK(response->findString("name", name)); 1166 1167 return OK; 1168} 1169 1170status_t MediaCodec::getMetrics(Parcel *reply) { 1171 1172 // shouldn't happen, but be safe 1173 if (mAnalyticsItem == NULL) { 1174 return UNKNOWN_ERROR; 1175 } 1176 1177 // XXX: go get current values for whatever in-flight data we want 1178 1179 // send it back to the caller. 1180 mAnalyticsItem->writeToParcel(reply); 1181 1182 return OK; 1183} 1184 1185status_t MediaCodec::getInputBuffers(Vector<sp<MediaCodecBuffer> > *buffers) const { 1186 sp<AMessage> msg = new AMessage(kWhatGetBuffers, this); 1187 msg->setInt32("portIndex", kPortIndexInput); 1188 msg->setPointer("buffers", buffers); 1189 1190 sp<AMessage> response; 1191 return PostAndAwaitResponse(msg, &response); 1192} 1193 1194status_t MediaCodec::getOutputBuffers(Vector<sp<MediaCodecBuffer> > *buffers) const { 1195 sp<AMessage> msg = new AMessage(kWhatGetBuffers, this); 1196 msg->setInt32("portIndex", kPortIndexOutput); 1197 msg->setPointer("buffers", buffers); 1198 1199 sp<AMessage> response; 1200 return PostAndAwaitResponse(msg, &response); 1201} 1202 1203status_t MediaCodec::getOutputBuffer(size_t index, sp<MediaCodecBuffer> *buffer) { 1204 sp<AMessage> format; 1205 return getBufferAndFormat(kPortIndexOutput, index, buffer, &format); 1206} 1207 1208status_t MediaCodec::getOutputFormat(size_t index, sp<AMessage> *format) { 1209 sp<MediaCodecBuffer> buffer; 1210 return getBufferAndFormat(kPortIndexOutput, index, &buffer, format); 1211} 1212 1213status_t MediaCodec::getInputBuffer(size_t index, sp<MediaCodecBuffer> *buffer) { 1214 sp<AMessage> format; 1215 return getBufferAndFormat(kPortIndexInput, index, buffer, &format); 1216} 1217 1218bool MediaCodec::isExecuting() const { 1219 return mState == STARTED || mState == FLUSHED; 1220} 1221 1222status_t MediaCodec::getBufferAndFormat( 1223 size_t portIndex, size_t index, 1224 sp<MediaCodecBuffer> *buffer, sp<AMessage> *format) { 1225 // use mutex instead of a context switch 1226 if (mReleasedByResourceManager) { 1227 ALOGE("getBufferAndFormat - resource already released"); 1228 return DEAD_OBJECT; 1229 } 1230 1231 if (buffer == NULL) { 1232 ALOGE("getBufferAndFormat - null MediaCodecBuffer"); 1233 return INVALID_OPERATION; 1234 } 1235 1236 if (format == NULL) { 1237 ALOGE("getBufferAndFormat - null AMessage"); 1238 return INVALID_OPERATION; 1239 } 1240 1241 buffer->clear(); 1242 format->clear(); 1243 1244 if (!isExecuting()) { 1245 ALOGE("getBufferAndFormat - not executing"); 1246 return INVALID_OPERATION; 1247 } 1248 1249 // we do not want mPortBuffers to change during this section 1250 // we also don't want mOwnedByClient to change during this 1251 Mutex::Autolock al(mBufferLock); 1252 1253 std::vector<BufferInfo> &buffers = mPortBuffers[portIndex]; 1254 if (index >= buffers.size()) { 1255 ALOGE("getBufferAndFormat - trying to get buffer with " 1256 "bad index (index=%zu buffer_size=%zu)", index, buffers.size()); 1257 return INVALID_OPERATION; 1258 } 1259 1260 const BufferInfo &info = buffers[index]; 1261 if (!info.mOwnedByClient) { 1262 ALOGE("getBufferAndFormat - invalid operation " 1263 "(the index %zu is not owned by client)", index); 1264 return INVALID_OPERATION; 1265 } 1266 1267 *buffer = info.mData; 1268 *format = info.mData->format(); 1269 1270 return OK; 1271} 1272 1273status_t MediaCodec::flush() { 1274 sp<AMessage> msg = new AMessage(kWhatFlush, this); 1275 1276 sp<AMessage> response; 1277 return PostAndAwaitResponse(msg, &response); 1278} 1279 1280status_t MediaCodec::requestIDRFrame() { 1281 (new AMessage(kWhatRequestIDRFrame, this))->post(); 1282 1283 return OK; 1284} 1285 1286void MediaCodec::requestActivityNotification(const sp<AMessage> ¬ify) { 1287 sp<AMessage> msg = new AMessage(kWhatRequestActivityNotification, this); 1288 msg->setMessage("notify", notify); 1289 msg->post(); 1290} 1291 1292//////////////////////////////////////////////////////////////////////////////// 1293 1294void MediaCodec::cancelPendingDequeueOperations() { 1295 if (mFlags & kFlagDequeueInputPending) { 1296 PostReplyWithError(mDequeueInputReplyID, INVALID_OPERATION); 1297 1298 ++mDequeueInputTimeoutGeneration; 1299 mDequeueInputReplyID = 0; 1300 mFlags &= ~kFlagDequeueInputPending; 1301 } 1302 1303 if (mFlags & kFlagDequeueOutputPending) { 1304 PostReplyWithError(mDequeueOutputReplyID, INVALID_OPERATION); 1305 1306 ++mDequeueOutputTimeoutGeneration; 1307 mDequeueOutputReplyID = 0; 1308 mFlags &= ~kFlagDequeueOutputPending; 1309 } 1310} 1311 1312bool MediaCodec::handleDequeueInputBuffer(const sp<AReplyToken> &replyID, bool newRequest) { 1313 if (!isExecuting() || (mFlags & kFlagIsAsync) 1314 || (newRequest && (mFlags & kFlagDequeueInputPending))) { 1315 PostReplyWithError(replyID, INVALID_OPERATION); 1316 return true; 1317 } else if (mFlags & kFlagStickyError) { 1318 PostReplyWithError(replyID, getStickyError()); 1319 return true; 1320 } 1321 1322 ssize_t index = dequeuePortBuffer(kPortIndexInput); 1323 1324 if (index < 0) { 1325 CHECK_EQ(index, -EAGAIN); 1326 return false; 1327 } 1328 1329 sp<AMessage> response = new AMessage; 1330 response->setSize("index", index); 1331 response->postReply(replyID); 1332 1333 return true; 1334} 1335 1336bool MediaCodec::handleDequeueOutputBuffer(const sp<AReplyToken> &replyID, bool newRequest) { 1337 if (!isExecuting() || (mFlags & kFlagIsAsync) 1338 || (newRequest && (mFlags & kFlagDequeueOutputPending))) { 1339 PostReplyWithError(replyID, INVALID_OPERATION); 1340 } else if (mFlags & kFlagStickyError) { 1341 PostReplyWithError(replyID, getStickyError()); 1342 } else if (mFlags & kFlagOutputBuffersChanged) { 1343 PostReplyWithError(replyID, INFO_OUTPUT_BUFFERS_CHANGED); 1344 mFlags &= ~kFlagOutputBuffersChanged; 1345 } else if (mFlags & kFlagOutputFormatChanged) { 1346 PostReplyWithError(replyID, INFO_FORMAT_CHANGED); 1347 mFlags &= ~kFlagOutputFormatChanged; 1348 } else { 1349 sp<AMessage> response = new AMessage; 1350 ssize_t index = dequeuePortBuffer(kPortIndexOutput); 1351 1352 if (index < 0) { 1353 CHECK_EQ(index, -EAGAIN); 1354 return false; 1355 } 1356 1357 const sp<MediaCodecBuffer> &buffer = 1358 mPortBuffers[kPortIndexOutput][index].mData; 1359 1360 response->setSize("index", index); 1361 response->setSize("offset", buffer->offset()); 1362 response->setSize("size", buffer->size()); 1363 1364 int64_t timeUs; 1365 CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 1366 1367 response->setInt64("timeUs", timeUs); 1368 1369 int32_t flags; 1370 CHECK(buffer->meta()->findInt32("flags", &flags)); 1371 1372 response->setInt32("flags", flags); 1373 response->postReply(replyID); 1374 } 1375 1376 return true; 1377} 1378 1379void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { 1380 switch (msg->what()) { 1381 case kWhatCodecNotify: 1382 { 1383 int32_t what; 1384 CHECK(msg->findInt32("what", &what)); 1385 1386 switch (what) { 1387 case kWhatError: 1388 { 1389 int32_t err, actionCode; 1390 CHECK(msg->findInt32("err", &err)); 1391 CHECK(msg->findInt32("actionCode", &actionCode)); 1392 1393 ALOGE("Codec reported err %#x, actionCode %d, while in state %d", 1394 err, actionCode, mState); 1395 if (err == DEAD_OBJECT) { 1396 mFlags |= kFlagSawMediaServerDie; 1397 mFlags &= ~kFlagIsComponentAllocated; 1398 } 1399 1400 bool sendErrorResponse = true; 1401 1402 switch (mState) { 1403 case INITIALIZING: 1404 { 1405 setState(UNINITIALIZED); 1406 break; 1407 } 1408 1409 case CONFIGURING: 1410 { 1411 setState(actionCode == ACTION_CODE_FATAL ? 1412 UNINITIALIZED : INITIALIZED); 1413 break; 1414 } 1415 1416 case STARTING: 1417 { 1418 setState(actionCode == ACTION_CODE_FATAL ? 1419 UNINITIALIZED : CONFIGURED); 1420 break; 1421 } 1422 1423 case RELEASING: 1424 { 1425 // Ignore the error, assuming we'll still get 1426 // the shutdown complete notification. If we 1427 // don't, we'll timeout and force release. 1428 sendErrorResponse = false; 1429 } 1430 // fall-thru 1431 case STOPPING: 1432 { 1433 if (mFlags & kFlagSawMediaServerDie) { 1434 // MediaServer died, there definitely won't 1435 // be a shutdown complete notification after 1436 // all. 1437 1438 // note that we're directly going from 1439 // STOPPING->UNINITIALIZED, instead of the 1440 // usual STOPPING->INITIALIZED state. 1441 setState(UNINITIALIZED); 1442 if (mState == RELEASING) { 1443 mComponentName.clear(); 1444 } 1445 (new AMessage)->postReply(mReplyID); 1446 sendErrorResponse = false; 1447 } 1448 break; 1449 } 1450 1451 case FLUSHING: 1452 { 1453 if (actionCode == ACTION_CODE_FATAL) { 1454 setState(UNINITIALIZED); 1455 } else { 1456 setState( 1457 (mFlags & kFlagIsAsync) ? FLUSHED : STARTED); 1458 } 1459 break; 1460 } 1461 1462 case FLUSHED: 1463 case STARTED: 1464 { 1465 sendErrorResponse = false; 1466 1467 setStickyError(err); 1468 postActivityNotificationIfPossible(); 1469 1470 cancelPendingDequeueOperations(); 1471 1472 if (mFlags & kFlagIsAsync) { 1473 onError(err, actionCode); 1474 } 1475 switch (actionCode) { 1476 case ACTION_CODE_TRANSIENT: 1477 break; 1478 case ACTION_CODE_RECOVERABLE: 1479 setState(INITIALIZED); 1480 break; 1481 default: 1482 setState(UNINITIALIZED); 1483 break; 1484 } 1485 break; 1486 } 1487 1488 default: 1489 { 1490 sendErrorResponse = false; 1491 1492 setStickyError(err); 1493 postActivityNotificationIfPossible(); 1494 1495 // actionCode in an uninitialized state is always fatal. 1496 if (mState == UNINITIALIZED) { 1497 actionCode = ACTION_CODE_FATAL; 1498 } 1499 if (mFlags & kFlagIsAsync) { 1500 onError(err, actionCode); 1501 } 1502 switch (actionCode) { 1503 case ACTION_CODE_TRANSIENT: 1504 break; 1505 case ACTION_CODE_RECOVERABLE: 1506 setState(INITIALIZED); 1507 break; 1508 default: 1509 setState(UNINITIALIZED); 1510 break; 1511 } 1512 break; 1513 } 1514 } 1515 1516 if (sendErrorResponse) { 1517 PostReplyWithError(mReplyID, err); 1518 } 1519 break; 1520 } 1521 1522 case kWhatComponentAllocated: 1523 { 1524 CHECK_EQ(mState, INITIALIZING); 1525 setState(INITIALIZED); 1526 mFlags |= kFlagIsComponentAllocated; 1527 1528 CHECK(msg->findString("componentName", &mComponentName)); 1529 1530 if (mComponentName.c_str()) { 1531 mAnalyticsItem->setCString(kCodecCodec, mComponentName.c_str()); 1532 } 1533 1534 if (mComponentName.startsWith("OMX.google.")) { 1535 mFlags |= kFlagUsesSoftwareRenderer; 1536 } else { 1537 mFlags &= ~kFlagUsesSoftwareRenderer; 1538 } 1539 1540 MediaResource::Type resourceType; 1541 if (mComponentName.endsWith(".secure")) { 1542 mFlags |= kFlagIsSecure; 1543 resourceType = MediaResource::kSecureCodec; 1544 mAnalyticsItem->setInt32(kCodecSecure, 1); 1545 } else { 1546 mFlags &= ~kFlagIsSecure; 1547 resourceType = MediaResource::kNonSecureCodec; 1548 mAnalyticsItem->setInt32(kCodecSecure, 0); 1549 } 1550 1551 if (mIsVideo) { 1552 // audio codec is currently ignored. 1553 addResource(resourceType, MediaResource::kVideoCodec, 1); 1554 } 1555 1556 (new AMessage)->postReply(mReplyID); 1557 break; 1558 } 1559 1560 case kWhatComponentConfigured: 1561 { 1562 if (mState == UNINITIALIZED || mState == INITIALIZED) { 1563 // In case a kWhatError message came in and replied with error, 1564 // we log a warning and ignore. 1565 ALOGW("configure interrupted by error, current state %d", mState); 1566 break; 1567 } 1568 CHECK_EQ(mState, CONFIGURING); 1569 1570 // reset input surface flag 1571 mHaveInputSurface = false; 1572 1573 CHECK(msg->findMessage("input-format", &mInputFormat)); 1574 CHECK(msg->findMessage("output-format", &mOutputFormat)); 1575 ALOGV("[%s] configured as input format: %s, output format: %s", 1576 mComponentName.c_str(), 1577 mInputFormat->debugString(4).c_str(), 1578 mOutputFormat->debugString(4).c_str()); 1579 int32_t usingSwRenderer; 1580 if (mOutputFormat->findInt32("using-sw-renderer", &usingSwRenderer) 1581 && usingSwRenderer) { 1582 mFlags |= kFlagUsesSoftwareRenderer; 1583 } 1584 setState(CONFIGURED); 1585 (new AMessage)->postReply(mReplyID); 1586 break; 1587 } 1588 1589 case kWhatInputSurfaceCreated: 1590 { 1591 // response to initiateCreateInputSurface() 1592 status_t err = NO_ERROR; 1593 sp<AMessage> response = new AMessage; 1594 if (!msg->findInt32("err", &err)) { 1595 sp<RefBase> obj; 1596 msg->findObject("input-surface", &obj); 1597 CHECK(msg->findMessage("input-format", &mInputFormat)); 1598 CHECK(msg->findMessage("output-format", &mOutputFormat)); 1599 ALOGV("[%s] input surface created as input format: %s, output format: %s", 1600 mComponentName.c_str(), 1601 mInputFormat->debugString(4).c_str(), 1602 mOutputFormat->debugString(4).c_str()); 1603 CHECK(obj != NULL); 1604 response->setObject("input-surface", obj); 1605 mHaveInputSurface = true; 1606 } else { 1607 response->setInt32("err", err); 1608 } 1609 response->postReply(mReplyID); 1610 break; 1611 } 1612 1613 case kWhatInputSurfaceAccepted: 1614 { 1615 // response to initiateSetInputSurface() 1616 status_t err = NO_ERROR; 1617 sp<AMessage> response = new AMessage(); 1618 if (!msg->findInt32("err", &err)) { 1619 CHECK(msg->findMessage("input-format", &mInputFormat)); 1620 CHECK(msg->findMessage("output-format", &mOutputFormat)); 1621 mHaveInputSurface = true; 1622 } else { 1623 response->setInt32("err", err); 1624 } 1625 response->postReply(mReplyID); 1626 break; 1627 } 1628 1629 case kWhatSignaledInputEOS: 1630 { 1631 // response to signalEndOfInputStream() 1632 sp<AMessage> response = new AMessage; 1633 status_t err; 1634 if (msg->findInt32("err", &err)) { 1635 response->setInt32("err", err); 1636 } 1637 response->postReply(mReplyID); 1638 break; 1639 } 1640 1641 case kWhatStartCompleted: 1642 { 1643 CHECK_EQ(mState, STARTING); 1644 if (mIsVideo) { 1645 addResource( 1646 MediaResource::kGraphicMemory, 1647 MediaResource::kUnspecifiedSubType, 1648 getGraphicBufferSize()); 1649 } 1650 setState(STARTED); 1651 (new AMessage)->postReply(mReplyID); 1652 break; 1653 } 1654 1655 case kWhatOutputBuffersChanged: 1656 { 1657 mFlags |= kFlagOutputBuffersChanged; 1658 postActivityNotificationIfPossible(); 1659 break; 1660 } 1661 1662 case kWhatOutputFramesRendered: 1663 { 1664 // ignore these in all states except running, and check that we have a 1665 // notification set 1666 if (mState == STARTED && mOnFrameRenderedNotification != NULL) { 1667 sp<AMessage> notify = mOnFrameRenderedNotification->dup(); 1668 notify->setMessage("data", msg); 1669 notify->post(); 1670 } 1671 break; 1672 } 1673 1674 case kWhatFillThisBuffer: 1675 { 1676 /* size_t index = */updateBuffers(kPortIndexInput, msg); 1677 1678 if (mState == FLUSHING 1679 || mState == STOPPING 1680 || mState == RELEASING) { 1681 returnBuffersToCodecOnPort(kPortIndexInput); 1682 break; 1683 } 1684 1685 if (!mCSD.empty()) { 1686 ssize_t index = dequeuePortBuffer(kPortIndexInput); 1687 CHECK_GE(index, 0); 1688 1689 // If codec specific data had been specified as 1690 // part of the format in the call to configure and 1691 // if there's more csd left, we submit it here 1692 // clients only get access to input buffers once 1693 // this data has been exhausted. 1694 1695 status_t err = queueCSDInputBuffer(index); 1696 1697 if (err != OK) { 1698 ALOGE("queueCSDInputBuffer failed w/ error %d", 1699 err); 1700 1701 setStickyError(err); 1702 postActivityNotificationIfPossible(); 1703 1704 cancelPendingDequeueOperations(); 1705 } 1706 break; 1707 } 1708 1709 if (mFlags & kFlagIsAsync) { 1710 if (!mHaveInputSurface) { 1711 if (mState == FLUSHED) { 1712 mHavePendingInputBuffers = true; 1713 } else { 1714 onInputBufferAvailable(); 1715 } 1716 } 1717 } else if (mFlags & kFlagDequeueInputPending) { 1718 CHECK(handleDequeueInputBuffer(mDequeueInputReplyID)); 1719 1720 ++mDequeueInputTimeoutGeneration; 1721 mFlags &= ~kFlagDequeueInputPending; 1722 mDequeueInputReplyID = 0; 1723 } else { 1724 postActivityNotificationIfPossible(); 1725 } 1726 break; 1727 } 1728 1729 case kWhatDrainThisBuffer: 1730 { 1731 /* size_t index = */updateBuffers(kPortIndexOutput, msg); 1732 1733 if (mState == FLUSHING 1734 || mState == STOPPING 1735 || mState == RELEASING) { 1736 returnBuffersToCodecOnPort(kPortIndexOutput); 1737 break; 1738 } 1739 1740 sp<RefBase> obj; 1741 CHECK(msg->findObject("buffer", &obj)); 1742 sp<MediaCodecBuffer> buffer = static_cast<MediaCodecBuffer *>(obj.get()); 1743 1744 if (mOutputFormat != buffer->format()) { 1745 mOutputFormat = buffer->format(); 1746 ALOGV("[%s] output format changed to: %s", 1747 mComponentName.c_str(), mOutputFormat->debugString(4).c_str()); 1748 1749 if (mSoftRenderer == NULL && 1750 mSurface != NULL && 1751 (mFlags & kFlagUsesSoftwareRenderer)) { 1752 AString mime; 1753 CHECK(mOutputFormat->findString("mime", &mime)); 1754 1755 // TODO: propagate color aspects to software renderer to allow better 1756 // color conversion to RGB. For now, just mark dataspace for YUV 1757 // rendering. 1758 int32_t dataSpace; 1759 if (mOutputFormat->findInt32("android._dataspace", &dataSpace)) { 1760 ALOGD("[%s] setting dataspace on output surface to #%x", 1761 mComponentName.c_str(), dataSpace); 1762 int err = native_window_set_buffers_data_space( 1763 mSurface.get(), (android_dataspace)dataSpace); 1764 ALOGW_IF(err != 0, "failed to set dataspace on surface (%d)", err); 1765 } 1766 1767 if (mime.startsWithIgnoreCase("video/")) { 1768 mSoftRenderer = new SoftwareRenderer(mSurface, mRotationDegrees); 1769 } 1770 } 1771 1772 if (mFlags & kFlagIsEncoder) { 1773 // Before we announce the format change we should 1774 // collect codec specific data and amend the output 1775 // format as necessary. 1776 int32_t flags = 0; 1777 (void) buffer->meta()->findInt32("flags", &flags); 1778 if (flags & BUFFER_FLAG_CODECCONFIG) { 1779 status_t err = 1780 amendOutputFormatWithCodecSpecificData(buffer); 1781 1782 if (err != OK) { 1783 ALOGE("Codec spit out malformed codec " 1784 "specific data!"); 1785 } 1786 } 1787 } 1788 1789 if (mFlags & kFlagIsAsync) { 1790 onOutputFormatChanged(); 1791 } else { 1792 mFlags |= kFlagOutputFormatChanged; 1793 postActivityNotificationIfPossible(); 1794 } 1795 1796 // Notify mCrypto of video resolution changes 1797 if (mCrypto != NULL) { 1798 int32_t left, top, right, bottom, width, height; 1799 if (mOutputFormat->findRect("crop", &left, &top, &right, &bottom)) { 1800 mCrypto->notifyResolution(right - left + 1, bottom - top + 1); 1801 } else if (mOutputFormat->findInt32("width", &width) 1802 && mOutputFormat->findInt32("height", &height)) { 1803 mCrypto->notifyResolution(width, height); 1804 } 1805 } 1806 } 1807 1808 if (mFlags & kFlagIsAsync) { 1809 onOutputBufferAvailable(); 1810 } else if (mFlags & kFlagDequeueOutputPending) { 1811 CHECK(handleDequeueOutputBuffer(mDequeueOutputReplyID)); 1812 1813 ++mDequeueOutputTimeoutGeneration; 1814 mFlags &= ~kFlagDequeueOutputPending; 1815 mDequeueOutputReplyID = 0; 1816 } else { 1817 postActivityNotificationIfPossible(); 1818 } 1819 1820 break; 1821 } 1822 1823 case kWhatEOS: 1824 { 1825 // We already notify the client of this by using the 1826 // corresponding flag in "onOutputBufferReady". 1827 break; 1828 } 1829 1830 case kWhatStopCompleted: 1831 { 1832 if (mState != STOPPING) { 1833 ALOGW("Received kWhatStopCompleted in state %d", mState); 1834 break; 1835 } 1836 setState(INITIALIZED); 1837 (new AMessage)->postReply(mReplyID); 1838 break; 1839 } 1840 1841 case kWhatReleaseCompleted: 1842 { 1843 if (mState != RELEASING) { 1844 ALOGW("Received kWhatReleaseCompleted in state %d", mState); 1845 break; 1846 } 1847 setState(UNINITIALIZED); 1848 mComponentName.clear(); 1849 1850 mFlags &= ~kFlagIsComponentAllocated; 1851 1852 mResourceManagerService->removeResource(getId(mResourceManagerClient)); 1853 1854 (new AMessage)->postReply(mReplyID); 1855 break; 1856 } 1857 1858 case kWhatFlushCompleted: 1859 { 1860 if (mState != FLUSHING) { 1861 ALOGW("received FlushCompleted message in state %d", 1862 mState); 1863 break; 1864 } 1865 1866 if (mFlags & kFlagIsAsync) { 1867 setState(FLUSHED); 1868 } else { 1869 setState(STARTED); 1870 mCodec->signalResume(); 1871 } 1872 1873 (new AMessage)->postReply(mReplyID); 1874 break; 1875 } 1876 1877 default: 1878 TRESPASS(); 1879 } 1880 break; 1881 } 1882 1883 case kWhatInit: 1884 { 1885 sp<AReplyToken> replyID; 1886 CHECK(msg->senderAwaitsResponse(&replyID)); 1887 1888 if (mState != UNINITIALIZED) { 1889 PostReplyWithError(replyID, INVALID_OPERATION); 1890 break; 1891 } 1892 1893 mReplyID = replyID; 1894 setState(INITIALIZING); 1895 1896 AString name; 1897 CHECK(msg->findString("name", &name)); 1898 1899 int32_t nameIsType; 1900 int32_t encoder = false; 1901 CHECK(msg->findInt32("nameIsType", &nameIsType)); 1902 if (nameIsType) { 1903 CHECK(msg->findInt32("encoder", &encoder)); 1904 } 1905 1906 sp<AMessage> format = new AMessage; 1907 1908 if (nameIsType) { 1909 format->setString("mime", name.c_str()); 1910 format->setInt32("encoder", encoder); 1911 } else { 1912 format->setString("componentName", name.c_str()); 1913 } 1914 1915 mCodec->initiateAllocateComponent(format); 1916 break; 1917 } 1918 1919 case kWhatSetNotification: 1920 { 1921 sp<AMessage> notify; 1922 if (msg->findMessage("on-frame-rendered", ¬ify)) { 1923 mOnFrameRenderedNotification = notify; 1924 } 1925 break; 1926 } 1927 1928 case kWhatSetCallback: 1929 { 1930 sp<AReplyToken> replyID; 1931 CHECK(msg->senderAwaitsResponse(&replyID)); 1932 1933 if (mState == UNINITIALIZED 1934 || mState == INITIALIZING 1935 || isExecuting()) { 1936 // callback can't be set after codec is executing, 1937 // or before it's initialized (as the callback 1938 // will be cleared when it goes to INITIALIZED) 1939 PostReplyWithError(replyID, INVALID_OPERATION); 1940 break; 1941 } 1942 1943 sp<AMessage> callback; 1944 CHECK(msg->findMessage("callback", &callback)); 1945 1946 mCallback = callback; 1947 1948 if (mCallback != NULL) { 1949 ALOGI("MediaCodec will operate in async mode"); 1950 mFlags |= kFlagIsAsync; 1951 } else { 1952 mFlags &= ~kFlagIsAsync; 1953 } 1954 1955 sp<AMessage> response = new AMessage; 1956 response->postReply(replyID); 1957 break; 1958 } 1959 1960 case kWhatConfigure: 1961 { 1962 sp<AReplyToken> replyID; 1963 CHECK(msg->senderAwaitsResponse(&replyID)); 1964 1965 if (mState != INITIALIZED) { 1966 PostReplyWithError(replyID, INVALID_OPERATION); 1967 break; 1968 } 1969 1970 sp<RefBase> obj; 1971 CHECK(msg->findObject("surface", &obj)); 1972 1973 sp<AMessage> format; 1974 CHECK(msg->findMessage("format", &format)); 1975 1976 int32_t push; 1977 if (msg->findInt32("push-blank-buffers-on-shutdown", &push) && push != 0) { 1978 mFlags |= kFlagPushBlankBuffersOnShutdown; 1979 } 1980 1981 if (obj != NULL) { 1982 format->setObject("native-window", obj); 1983 status_t err = handleSetSurface(static_cast<Surface *>(obj.get())); 1984 if (err != OK) { 1985 PostReplyWithError(replyID, err); 1986 break; 1987 } 1988 } else { 1989 handleSetSurface(NULL); 1990 } 1991 1992 mReplyID = replyID; 1993 setState(CONFIGURING); 1994 1995 void *crypto; 1996 if (!msg->findPointer("crypto", &crypto)) { 1997 crypto = NULL; 1998 } 1999 2000 ALOGV("kWhatConfigure: Old mCrypto: %p (%d)", 2001 mCrypto.get(), (mCrypto != NULL ? mCrypto->getStrongCount() : 0)); 2002 2003 mCrypto = static_cast<ICrypto *>(crypto); 2004 mBufferChannel->setCrypto(mCrypto); 2005 2006 ALOGV("kWhatConfigure: New mCrypto: %p (%d)", 2007 mCrypto.get(), (mCrypto != NULL ? mCrypto->getStrongCount() : 0)); 2008 2009 void *descrambler; 2010 if (!msg->findPointer("descrambler", &descrambler)) { 2011 descrambler = NULL; 2012 } 2013 2014 mDescrambler = static_cast<IDescrambler *>(descrambler); 2015 mBufferChannel->setDescrambler(mDescrambler); 2016 2017 uint32_t flags; 2018 CHECK(msg->findInt32("flags", (int32_t *)&flags)); 2019 2020 if (flags & CONFIGURE_FLAG_ENCODE) { 2021 format->setInt32("encoder", true); 2022 mFlags |= kFlagIsEncoder; 2023 } 2024 2025 extractCSD(format); 2026 2027 mCodec->initiateConfigureComponent(format); 2028 break; 2029 } 2030 2031 case kWhatSetSurface: 2032 { 2033 sp<AReplyToken> replyID; 2034 CHECK(msg->senderAwaitsResponse(&replyID)); 2035 2036 status_t err = OK; 2037 2038 switch (mState) { 2039 case CONFIGURED: 2040 case STARTED: 2041 case FLUSHED: 2042 { 2043 sp<RefBase> obj; 2044 (void)msg->findObject("surface", &obj); 2045 sp<Surface> surface = static_cast<Surface *>(obj.get()); 2046 if (mSurface == NULL) { 2047 // do not support setting surface if it was not set 2048 err = INVALID_OPERATION; 2049 } else if (obj == NULL) { 2050 // do not support unsetting surface 2051 err = BAD_VALUE; 2052 } else { 2053 err = connectToSurface(surface); 2054 if (err == ALREADY_EXISTS) { 2055 // reconnecting to same surface 2056 err = OK; 2057 } else { 2058 if (err == OK) { 2059 if (mFlags & kFlagUsesSoftwareRenderer) { 2060 if (mSoftRenderer != NULL 2061 && (mFlags & kFlagPushBlankBuffersOnShutdown)) { 2062 pushBlankBuffersToNativeWindow(mSurface.get()); 2063 } 2064 mSoftRenderer = new SoftwareRenderer(surface); 2065 // TODO: check if this was successful 2066 } else { 2067 err = mCodec->setSurface(surface); 2068 } 2069 } 2070 if (err == OK) { 2071 (void)disconnectFromSurface(); 2072 mSurface = surface; 2073 } 2074 } 2075 } 2076 break; 2077 } 2078 2079 default: 2080 err = INVALID_OPERATION; 2081 break; 2082 } 2083 2084 PostReplyWithError(replyID, err); 2085 break; 2086 } 2087 2088 case kWhatCreateInputSurface: 2089 case kWhatSetInputSurface: 2090 { 2091 sp<AReplyToken> replyID; 2092 CHECK(msg->senderAwaitsResponse(&replyID)); 2093 2094 // Must be configured, but can't have been started yet. 2095 if (mState != CONFIGURED) { 2096 PostReplyWithError(replyID, INVALID_OPERATION); 2097 break; 2098 } 2099 2100 mReplyID = replyID; 2101 if (msg->what() == kWhatCreateInputSurface) { 2102 mCodec->initiateCreateInputSurface(); 2103 } else { 2104 sp<RefBase> obj; 2105 CHECK(msg->findObject("input-surface", &obj)); 2106 2107 mCodec->initiateSetInputSurface( 2108 static_cast<PersistentSurface *>(obj.get())); 2109 } 2110 break; 2111 } 2112 case kWhatStart: 2113 { 2114 sp<AReplyToken> replyID; 2115 CHECK(msg->senderAwaitsResponse(&replyID)); 2116 2117 if (mState == FLUSHED) { 2118 setState(STARTED); 2119 if (mHavePendingInputBuffers) { 2120 onInputBufferAvailable(); 2121 mHavePendingInputBuffers = false; 2122 } 2123 mCodec->signalResume(); 2124 PostReplyWithError(replyID, OK); 2125 break; 2126 } else if (mState != CONFIGURED) { 2127 PostReplyWithError(replyID, INVALID_OPERATION); 2128 break; 2129 } 2130 2131 mReplyID = replyID; 2132 setState(STARTING); 2133 2134 mCodec->initiateStart(); 2135 break; 2136 } 2137 2138 case kWhatStop: 2139 case kWhatRelease: 2140 { 2141 State targetState = 2142 (msg->what() == kWhatStop) ? INITIALIZED : UNINITIALIZED; 2143 2144 sp<AReplyToken> replyID; 2145 CHECK(msg->senderAwaitsResponse(&replyID)); 2146 2147 // already stopped/released 2148 if (mState == UNINITIALIZED && mReleasedByResourceManager) { 2149 sp<AMessage> response = new AMessage; 2150 response->setInt32("err", OK); 2151 response->postReply(replyID); 2152 break; 2153 } 2154 2155 int32_t reclaimed = 0; 2156 msg->findInt32("reclaimed", &reclaimed); 2157 if (reclaimed) { 2158 mReleasedByResourceManager = true; 2159 2160 int32_t force = 0; 2161 msg->findInt32("force", &force); 2162 if (!force && hasPendingBuffer()) { 2163 ALOGW("Can't reclaim codec right now due to pending buffers."); 2164 2165 // return WOULD_BLOCK to ask resource manager to retry later. 2166 sp<AMessage> response = new AMessage; 2167 response->setInt32("err", WOULD_BLOCK); 2168 response->postReply(replyID); 2169 2170 // notify the async client 2171 if (mFlags & kFlagIsAsync) { 2172 onError(DEAD_OBJECT, ACTION_CODE_FATAL); 2173 } 2174 break; 2175 } 2176 } 2177 2178 bool isReleasingAllocatedComponent = 2179 (mFlags & kFlagIsComponentAllocated) && targetState == UNINITIALIZED; 2180 if (!isReleasingAllocatedComponent // See 1 2181 && mState != INITIALIZED 2182 && mState != CONFIGURED && !isExecuting()) { 2183 // 1) Permit release to shut down the component if allocated. 2184 // 2185 // 2) We may be in "UNINITIALIZED" state already and 2186 // also shutdown the encoder/decoder without the 2187 // client being aware of this if media server died while 2188 // we were being stopped. The client would assume that 2189 // after stop() returned, it would be safe to call release() 2190 // and it should be in this case, no harm to allow a release() 2191 // if we're already uninitialized. 2192 sp<AMessage> response = new AMessage; 2193 // TODO: we shouldn't throw an exception for stop/release. Change this to wait until 2194 // the previous stop/release completes and then reply with OK. 2195 status_t err = mState == targetState ? OK : INVALID_OPERATION; 2196 response->setInt32("err", err); 2197 if (err == OK && targetState == UNINITIALIZED) { 2198 mComponentName.clear(); 2199 } 2200 response->postReply(replyID); 2201 break; 2202 } 2203 2204 // If we're flushing, or we're stopping but received a release 2205 // request, post the reply for the pending call first, and consider 2206 // it done. The reply token will be replaced after this, and we'll 2207 // no longer be able to reply. 2208 if (mState == FLUSHING || mState == STOPPING) { 2209 (new AMessage)->postReply(mReplyID); 2210 } 2211 2212 if (mFlags & kFlagSawMediaServerDie) { 2213 // It's dead, Jim. Don't expect initiateShutdown to yield 2214 // any useful results now... 2215 setState(UNINITIALIZED); 2216 if (targetState == UNINITIALIZED) { 2217 mComponentName.clear(); 2218 } 2219 (new AMessage)->postReply(replyID); 2220 break; 2221 } 2222 2223 // If we already have an error, component may not be able to 2224 // complete the shutdown properly. If we're stopping, post the 2225 // reply now with an error to unblock the client, client can 2226 // release after the failure (instead of ANR). 2227 if (msg->what() == kWhatStop && (mFlags & kFlagStickyError)) { 2228 PostReplyWithError(replyID, getStickyError()); 2229 break; 2230 } 2231 2232 mReplyID = replyID; 2233 setState(msg->what() == kWhatStop ? STOPPING : RELEASING); 2234 2235 mCodec->initiateShutdown( 2236 msg->what() == kWhatStop /* keepComponentAllocated */); 2237 2238 returnBuffersToCodec(reclaimed); 2239 2240 if (mSoftRenderer != NULL && (mFlags & kFlagPushBlankBuffersOnShutdown)) { 2241 pushBlankBuffersToNativeWindow(mSurface.get()); 2242 } 2243 2244 break; 2245 } 2246 2247 case kWhatDequeueInputBuffer: 2248 { 2249 sp<AReplyToken> replyID; 2250 CHECK(msg->senderAwaitsResponse(&replyID)); 2251 2252 if (mFlags & kFlagIsAsync) { 2253 ALOGE("dequeueOutputBuffer can't be used in async mode"); 2254 PostReplyWithError(replyID, INVALID_OPERATION); 2255 break; 2256 } 2257 2258 if (mHaveInputSurface) { 2259 ALOGE("dequeueInputBuffer can't be used with input surface"); 2260 PostReplyWithError(replyID, INVALID_OPERATION); 2261 break; 2262 } 2263 2264 if (handleDequeueInputBuffer(replyID, true /* new request */)) { 2265 break; 2266 } 2267 2268 int64_t timeoutUs; 2269 CHECK(msg->findInt64("timeoutUs", &timeoutUs)); 2270 2271 if (timeoutUs == 0ll) { 2272 PostReplyWithError(replyID, -EAGAIN); 2273 break; 2274 } 2275 2276 mFlags |= kFlagDequeueInputPending; 2277 mDequeueInputReplyID = replyID; 2278 2279 if (timeoutUs > 0ll) { 2280 sp<AMessage> timeoutMsg = 2281 new AMessage(kWhatDequeueInputTimedOut, this); 2282 timeoutMsg->setInt32( 2283 "generation", ++mDequeueInputTimeoutGeneration); 2284 timeoutMsg->post(timeoutUs); 2285 } 2286 break; 2287 } 2288 2289 case kWhatDequeueInputTimedOut: 2290 { 2291 int32_t generation; 2292 CHECK(msg->findInt32("generation", &generation)); 2293 2294 if (generation != mDequeueInputTimeoutGeneration) { 2295 // Obsolete 2296 break; 2297 } 2298 2299 CHECK(mFlags & kFlagDequeueInputPending); 2300 2301 PostReplyWithError(mDequeueInputReplyID, -EAGAIN); 2302 2303 mFlags &= ~kFlagDequeueInputPending; 2304 mDequeueInputReplyID = 0; 2305 break; 2306 } 2307 2308 case kWhatQueueInputBuffer: 2309 { 2310 sp<AReplyToken> replyID; 2311 CHECK(msg->senderAwaitsResponse(&replyID)); 2312 2313 if (!isExecuting()) { 2314 PostReplyWithError(replyID, INVALID_OPERATION); 2315 break; 2316 } else if (mFlags & kFlagStickyError) { 2317 PostReplyWithError(replyID, getStickyError()); 2318 break; 2319 } 2320 2321 status_t err = onQueueInputBuffer(msg); 2322 2323 PostReplyWithError(replyID, err); 2324 break; 2325 } 2326 2327 case kWhatDequeueOutputBuffer: 2328 { 2329 sp<AReplyToken> replyID; 2330 CHECK(msg->senderAwaitsResponse(&replyID)); 2331 2332 if (mFlags & kFlagIsAsync) { 2333 ALOGE("dequeueOutputBuffer can't be used in async mode"); 2334 PostReplyWithError(replyID, INVALID_OPERATION); 2335 break; 2336 } 2337 2338 if (handleDequeueOutputBuffer(replyID, true /* new request */)) { 2339 break; 2340 } 2341 2342 int64_t timeoutUs; 2343 CHECK(msg->findInt64("timeoutUs", &timeoutUs)); 2344 2345 if (timeoutUs == 0ll) { 2346 PostReplyWithError(replyID, -EAGAIN); 2347 break; 2348 } 2349 2350 mFlags |= kFlagDequeueOutputPending; 2351 mDequeueOutputReplyID = replyID; 2352 2353 if (timeoutUs > 0ll) { 2354 sp<AMessage> timeoutMsg = 2355 new AMessage(kWhatDequeueOutputTimedOut, this); 2356 timeoutMsg->setInt32( 2357 "generation", ++mDequeueOutputTimeoutGeneration); 2358 timeoutMsg->post(timeoutUs); 2359 } 2360 break; 2361 } 2362 2363 case kWhatDequeueOutputTimedOut: 2364 { 2365 int32_t generation; 2366 CHECK(msg->findInt32("generation", &generation)); 2367 2368 if (generation != mDequeueOutputTimeoutGeneration) { 2369 // Obsolete 2370 break; 2371 } 2372 2373 CHECK(mFlags & kFlagDequeueOutputPending); 2374 2375 PostReplyWithError(mDequeueOutputReplyID, -EAGAIN); 2376 2377 mFlags &= ~kFlagDequeueOutputPending; 2378 mDequeueOutputReplyID = 0; 2379 break; 2380 } 2381 2382 case kWhatReleaseOutputBuffer: 2383 { 2384 sp<AReplyToken> replyID; 2385 CHECK(msg->senderAwaitsResponse(&replyID)); 2386 2387 if (!isExecuting()) { 2388 PostReplyWithError(replyID, INVALID_OPERATION); 2389 break; 2390 } else if (mFlags & kFlagStickyError) { 2391 PostReplyWithError(replyID, getStickyError()); 2392 break; 2393 } 2394 2395 status_t err = onReleaseOutputBuffer(msg); 2396 2397 PostReplyWithError(replyID, err); 2398 break; 2399 } 2400 2401 case kWhatSignalEndOfInputStream: 2402 { 2403 sp<AReplyToken> replyID; 2404 CHECK(msg->senderAwaitsResponse(&replyID)); 2405 2406 if (!isExecuting() || !mHaveInputSurface) { 2407 PostReplyWithError(replyID, INVALID_OPERATION); 2408 break; 2409 } else if (mFlags & kFlagStickyError) { 2410 PostReplyWithError(replyID, getStickyError()); 2411 break; 2412 } 2413 2414 mReplyID = replyID; 2415 mCodec->signalEndOfInputStream(); 2416 break; 2417 } 2418 2419 case kWhatGetBuffers: 2420 { 2421 sp<AReplyToken> replyID; 2422 CHECK(msg->senderAwaitsResponse(&replyID)); 2423 if (!isExecuting() || (mFlags & kFlagIsAsync)) { 2424 PostReplyWithError(replyID, INVALID_OPERATION); 2425 break; 2426 } else if (mFlags & kFlagStickyError) { 2427 PostReplyWithError(replyID, getStickyError()); 2428 break; 2429 } 2430 2431 int32_t portIndex; 2432 CHECK(msg->findInt32("portIndex", &portIndex)); 2433 2434 Vector<sp<MediaCodecBuffer> > *dstBuffers; 2435 CHECK(msg->findPointer("buffers", (void **)&dstBuffers)); 2436 2437 dstBuffers->clear(); 2438 // If we're using input surface (either non-persistent created by 2439 // createInputSurface(), or persistent set by setInputSurface()), 2440 // give the client an empty input buffers array. 2441 if (portIndex != kPortIndexInput || !mHaveInputSurface) { 2442 if (portIndex == kPortIndexInput) { 2443 mBufferChannel->getInputBufferArray(dstBuffers); 2444 } else { 2445 mBufferChannel->getOutputBufferArray(dstBuffers); 2446 } 2447 } 2448 2449 (new AMessage)->postReply(replyID); 2450 break; 2451 } 2452 2453 case kWhatFlush: 2454 { 2455 sp<AReplyToken> replyID; 2456 CHECK(msg->senderAwaitsResponse(&replyID)); 2457 2458 if (!isExecuting()) { 2459 PostReplyWithError(replyID, INVALID_OPERATION); 2460 break; 2461 } else if (mFlags & kFlagStickyError) { 2462 PostReplyWithError(replyID, getStickyError()); 2463 break; 2464 } 2465 2466 mReplyID = replyID; 2467 // TODO: skip flushing if already FLUSHED 2468 setState(FLUSHING); 2469 2470 mCodec->signalFlush(); 2471 returnBuffersToCodec(); 2472 break; 2473 } 2474 2475 case kWhatGetInputFormat: 2476 case kWhatGetOutputFormat: 2477 { 2478 sp<AMessage> format = 2479 (msg->what() == kWhatGetOutputFormat ? mOutputFormat : mInputFormat); 2480 2481 sp<AReplyToken> replyID; 2482 CHECK(msg->senderAwaitsResponse(&replyID)); 2483 2484 if ((mState != CONFIGURED && mState != STARTING && 2485 mState != STARTED && mState != FLUSHING && 2486 mState != FLUSHED) 2487 || format == NULL) { 2488 PostReplyWithError(replyID, INVALID_OPERATION); 2489 break; 2490 } else if (mFlags & kFlagStickyError) { 2491 PostReplyWithError(replyID, getStickyError()); 2492 break; 2493 } 2494 2495 sp<AMessage> response = new AMessage; 2496 response->setMessage("format", format); 2497 response->postReply(replyID); 2498 break; 2499 } 2500 2501 case kWhatRequestIDRFrame: 2502 { 2503 mCodec->signalRequestIDRFrame(); 2504 break; 2505 } 2506 2507 case kWhatRequestActivityNotification: 2508 { 2509 CHECK(mActivityNotify == NULL); 2510 CHECK(msg->findMessage("notify", &mActivityNotify)); 2511 2512 postActivityNotificationIfPossible(); 2513 break; 2514 } 2515 2516 case kWhatGetName: 2517 { 2518 sp<AReplyToken> replyID; 2519 CHECK(msg->senderAwaitsResponse(&replyID)); 2520 2521 if (mComponentName.empty()) { 2522 PostReplyWithError(replyID, INVALID_OPERATION); 2523 break; 2524 } 2525 2526 sp<AMessage> response = new AMessage; 2527 response->setString("name", mComponentName.c_str()); 2528 response->postReply(replyID); 2529 break; 2530 } 2531 2532 case kWhatSetParameters: 2533 { 2534 sp<AReplyToken> replyID; 2535 CHECK(msg->senderAwaitsResponse(&replyID)); 2536 2537 sp<AMessage> params; 2538 CHECK(msg->findMessage("params", ¶ms)); 2539 2540 status_t err = onSetParameters(params); 2541 2542 PostReplyWithError(replyID, err); 2543 break; 2544 } 2545 2546 case kWhatDrmReleaseCrypto: 2547 { 2548 onReleaseCrypto(msg); 2549 break; 2550 } 2551 2552 default: 2553 TRESPASS(); 2554 } 2555} 2556 2557void MediaCodec::extractCSD(const sp<AMessage> &format) { 2558 mCSD.clear(); 2559 2560 size_t i = 0; 2561 for (;;) { 2562 sp<ABuffer> csd; 2563 if (!format->findBuffer(AStringPrintf("csd-%u", i).c_str(), &csd)) { 2564 break; 2565 } 2566 if (csd->size() == 0) { 2567 ALOGW("csd-%zu size is 0", i); 2568 } 2569 2570 mCSD.push_back(csd); 2571 ++i; 2572 } 2573 2574 ALOGV("Found %zu pieces of codec specific data.", mCSD.size()); 2575} 2576 2577status_t MediaCodec::queueCSDInputBuffer(size_t bufferIndex) { 2578 CHECK(!mCSD.empty()); 2579 2580 const BufferInfo &info = mPortBuffers[kPortIndexInput][bufferIndex]; 2581 2582 sp<ABuffer> csd = *mCSD.begin(); 2583 mCSD.erase(mCSD.begin()); 2584 2585 const sp<MediaCodecBuffer> &codecInputData = info.mData; 2586 2587 if (csd->size() > codecInputData->capacity()) { 2588 return -EINVAL; 2589 } 2590 2591 memcpy(codecInputData->data(), csd->data(), csd->size()); 2592 2593 AString errorDetailMsg; 2594 2595 sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this); 2596 msg->setSize("index", bufferIndex); 2597 msg->setSize("offset", 0); 2598 msg->setSize("size", csd->size()); 2599 msg->setInt64("timeUs", 0ll); 2600 msg->setInt32("flags", BUFFER_FLAG_CODECCONFIG); 2601 msg->setPointer("errorDetailMsg", &errorDetailMsg); 2602 2603 return onQueueInputBuffer(msg); 2604} 2605 2606void MediaCodec::setState(State newState) { 2607 if (newState == INITIALIZED || newState == UNINITIALIZED) { 2608 delete mSoftRenderer; 2609 mSoftRenderer = NULL; 2610 2611 if ( mCrypto != NULL ) { 2612 ALOGV("setState: ~mCrypto: %p (%d)", 2613 mCrypto.get(), (mCrypto != NULL ? mCrypto->getStrongCount() : 0)); 2614 } 2615 mCrypto.clear(); 2616 mDescrambler.clear(); 2617 handleSetSurface(NULL); 2618 2619 mInputFormat.clear(); 2620 mOutputFormat.clear(); 2621 mFlags &= ~kFlagOutputFormatChanged; 2622 mFlags &= ~kFlagOutputBuffersChanged; 2623 mFlags &= ~kFlagStickyError; 2624 mFlags &= ~kFlagIsEncoder; 2625 mFlags &= ~kFlagIsAsync; 2626 mStickyError = OK; 2627 2628 mActivityNotify.clear(); 2629 mCallback.clear(); 2630 } 2631 2632 if (newState == UNINITIALIZED) { 2633 // return any straggling buffers, e.g. if we got here on an error 2634 returnBuffersToCodec(); 2635 2636 // The component is gone, mediaserver's probably back up already 2637 // but should definitely be back up should we try to instantiate 2638 // another component.. and the cycle continues. 2639 mFlags &= ~kFlagSawMediaServerDie; 2640 } 2641 2642 mState = newState; 2643 2644 cancelPendingDequeueOperations(); 2645 2646 updateBatteryStat(); 2647} 2648 2649void MediaCodec::returnBuffersToCodec(bool isReclaim) { 2650 returnBuffersToCodecOnPort(kPortIndexInput, isReclaim); 2651 returnBuffersToCodecOnPort(kPortIndexOutput, isReclaim); 2652} 2653 2654void MediaCodec::returnBuffersToCodecOnPort(int32_t portIndex, bool isReclaim) { 2655 CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 2656 Mutex::Autolock al(mBufferLock); 2657 2658 for (size_t i = 0; i < mPortBuffers[portIndex].size(); ++i) { 2659 BufferInfo *info = &mPortBuffers[portIndex][i]; 2660 2661 if (info->mData != nullptr) { 2662 sp<MediaCodecBuffer> buffer = info->mData; 2663 if (isReclaim && info->mOwnedByClient) { 2664 ALOGD("port %d buffer %zu still owned by client when codec is reclaimed", 2665 portIndex, i); 2666 } else { 2667 info->mOwnedByClient = false; 2668 info->mData.clear(); 2669 } 2670 mBufferChannel->discardBuffer(buffer); 2671 } 2672 } 2673 2674 mAvailPortBuffers[portIndex].clear(); 2675} 2676 2677size_t MediaCodec::updateBuffers( 2678 int32_t portIndex, const sp<AMessage> &msg) { 2679 CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 2680 size_t index; 2681 CHECK(msg->findSize("index", &index)); 2682 sp<RefBase> obj; 2683 CHECK(msg->findObject("buffer", &obj)); 2684 sp<MediaCodecBuffer> buffer = static_cast<MediaCodecBuffer *>(obj.get()); 2685 2686 { 2687 Mutex::Autolock al(mBufferLock); 2688 if (mPortBuffers[portIndex].size() <= index) { 2689 mPortBuffers[portIndex].resize(align(index + 1, kNumBuffersAlign)); 2690 } 2691 mPortBuffers[portIndex][index].mData = buffer; 2692 } 2693 mAvailPortBuffers[portIndex].push_back(index); 2694 2695 return index; 2696} 2697 2698status_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) { 2699 size_t index; 2700 size_t offset; 2701 size_t size; 2702 int64_t timeUs; 2703 uint32_t flags; 2704 CHECK(msg->findSize("index", &index)); 2705 CHECK(msg->findSize("offset", &offset)); 2706 CHECK(msg->findInt64("timeUs", &timeUs)); 2707 CHECK(msg->findInt32("flags", (int32_t *)&flags)); 2708 2709 const CryptoPlugin::SubSample *subSamples; 2710 size_t numSubSamples; 2711 const uint8_t *key; 2712 const uint8_t *iv; 2713 CryptoPlugin::Mode mode = CryptoPlugin::kMode_Unencrypted; 2714 2715 // We allow the simpler queueInputBuffer API to be used even in 2716 // secure mode, by fabricating a single unencrypted subSample. 2717 CryptoPlugin::SubSample ss; 2718 CryptoPlugin::Pattern pattern; 2719 2720 if (msg->findSize("size", &size)) { 2721 if (hasCryptoOrDescrambler()) { 2722 ss.mNumBytesOfClearData = size; 2723 ss.mNumBytesOfEncryptedData = 0; 2724 2725 subSamples = &ss; 2726 numSubSamples = 1; 2727 key = NULL; 2728 iv = NULL; 2729 pattern.mEncryptBlocks = 0; 2730 pattern.mSkipBlocks = 0; 2731 } 2732 } else { 2733 if (!hasCryptoOrDescrambler()) { 2734 ALOGE("[%s] queuing secure buffer without mCrypto or mDescrambler!", 2735 mComponentName.c_str()); 2736 return -EINVAL; 2737 } 2738 2739 CHECK(msg->findPointer("subSamples", (void **)&subSamples)); 2740 CHECK(msg->findSize("numSubSamples", &numSubSamples)); 2741 CHECK(msg->findPointer("key", (void **)&key)); 2742 CHECK(msg->findPointer("iv", (void **)&iv)); 2743 CHECK(msg->findInt32("encryptBlocks", (int32_t *)&pattern.mEncryptBlocks)); 2744 CHECK(msg->findInt32("skipBlocks", (int32_t *)&pattern.mSkipBlocks)); 2745 2746 int32_t tmp; 2747 CHECK(msg->findInt32("mode", &tmp)); 2748 2749 mode = (CryptoPlugin::Mode)tmp; 2750 2751 size = 0; 2752 for (size_t i = 0; i < numSubSamples; ++i) { 2753 size += subSamples[i].mNumBytesOfClearData; 2754 size += subSamples[i].mNumBytesOfEncryptedData; 2755 } 2756 } 2757 2758 if (index >= mPortBuffers[kPortIndexInput].size()) { 2759 return -ERANGE; 2760 } 2761 2762 BufferInfo *info = &mPortBuffers[kPortIndexInput][index]; 2763 2764 if (info->mData == nullptr || !info->mOwnedByClient) { 2765 return -EACCES; 2766 } 2767 2768 if (offset + size > info->mData->capacity()) { 2769 return -EINVAL; 2770 } 2771 2772 info->mData->setRange(offset, size); 2773 info->mData->meta()->setInt64("timeUs", timeUs); 2774 if (flags & BUFFER_FLAG_EOS) { 2775 info->mData->meta()->setInt32("eos", true); 2776 } 2777 2778 if (flags & BUFFER_FLAG_CODECCONFIG) { 2779 info->mData->meta()->setInt32("csd", true); 2780 } 2781 2782 sp<MediaCodecBuffer> buffer = info->mData; 2783 status_t err = OK; 2784 if (hasCryptoOrDescrambler()) { 2785 AString *errorDetailMsg; 2786 CHECK(msg->findPointer("errorDetailMsg", (void **)&errorDetailMsg)); 2787 2788 err = mBufferChannel->queueSecureInputBuffer( 2789 buffer, 2790 (mFlags & kFlagIsSecure), 2791 key, 2792 iv, 2793 mode, 2794 pattern, 2795 subSamples, 2796 numSubSamples, 2797 errorDetailMsg); 2798 } else { 2799 err = mBufferChannel->queueInputBuffer(buffer); 2800 } 2801 2802 if (err == OK) { 2803 // synchronization boundary for getBufferAndFormat 2804 Mutex::Autolock al(mBufferLock); 2805 info->mOwnedByClient = false; 2806 info->mData.clear(); 2807 } 2808 2809 return err; 2810} 2811 2812//static 2813size_t MediaCodec::CreateFramesRenderedMessage( 2814 const std::list<FrameRenderTracker::Info> &done, sp<AMessage> &msg) { 2815 size_t index = 0; 2816 2817 for (std::list<FrameRenderTracker::Info>::const_iterator it = done.cbegin(); 2818 it != done.cend(); ++it) { 2819 if (it->getRenderTimeNs() < 0) { 2820 continue; // dropped frame from tracking 2821 } 2822 msg->setInt64(AStringPrintf("%zu-media-time-us", index).c_str(), it->getMediaTimeUs()); 2823 msg->setInt64(AStringPrintf("%zu-system-nano", index).c_str(), it->getRenderTimeNs()); 2824 ++index; 2825 } 2826 return index; 2827} 2828 2829status_t MediaCodec::onReleaseOutputBuffer(const sp<AMessage> &msg) { 2830 size_t index; 2831 CHECK(msg->findSize("index", &index)); 2832 2833 int32_t render; 2834 if (!msg->findInt32("render", &render)) { 2835 render = 0; 2836 } 2837 2838 if (!isExecuting()) { 2839 return -EINVAL; 2840 } 2841 2842 if (index >= mPortBuffers[kPortIndexOutput].size()) { 2843 return -ERANGE; 2844 } 2845 2846 BufferInfo *info = &mPortBuffers[kPortIndexOutput][index]; 2847 2848 if (info->mData == nullptr || !info->mOwnedByClient) { 2849 return -EACCES; 2850 } 2851 2852 // synchronization boundary for getBufferAndFormat 2853 sp<MediaCodecBuffer> buffer; 2854 { 2855 Mutex::Autolock al(mBufferLock); 2856 info->mOwnedByClient = false; 2857 buffer = info->mData; 2858 info->mData.clear(); 2859 } 2860 2861 if (render && buffer->size() != 0) { 2862 int64_t mediaTimeUs = -1; 2863 buffer->meta()->findInt64("timeUs", &mediaTimeUs); 2864 2865 int64_t renderTimeNs = 0; 2866 if (!msg->findInt64("timestampNs", &renderTimeNs)) { 2867 // use media timestamp if client did not request a specific render timestamp 2868 ALOGV("using buffer PTS of %lld", (long long)mediaTimeUs); 2869 renderTimeNs = mediaTimeUs * 1000; 2870 } 2871 2872 if (mSoftRenderer != NULL) { 2873 std::list<FrameRenderTracker::Info> doneFrames = mSoftRenderer->render( 2874 buffer->data(), buffer->size(), 2875 mediaTimeUs, renderTimeNs, NULL, buffer->format()); 2876 2877 // if we are running, notify rendered frames 2878 if (!doneFrames.empty() && mState == STARTED && mOnFrameRenderedNotification != NULL) { 2879 sp<AMessage> notify = mOnFrameRenderedNotification->dup(); 2880 sp<AMessage> data = new AMessage; 2881 if (CreateFramesRenderedMessage(doneFrames, data)) { 2882 notify->setMessage("data", data); 2883 notify->post(); 2884 } 2885 } 2886 } 2887 mBufferChannel->renderOutputBuffer(buffer, renderTimeNs); 2888 } else { 2889 mBufferChannel->discardBuffer(buffer); 2890 } 2891 2892 return OK; 2893} 2894 2895ssize_t MediaCodec::dequeuePortBuffer(int32_t portIndex) { 2896 CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 2897 2898 List<size_t> *availBuffers = &mAvailPortBuffers[portIndex]; 2899 2900 if (availBuffers->empty()) { 2901 return -EAGAIN; 2902 } 2903 2904 size_t index = *availBuffers->begin(); 2905 availBuffers->erase(availBuffers->begin()); 2906 2907 BufferInfo *info = &mPortBuffers[portIndex][index]; 2908 CHECK(!info->mOwnedByClient); 2909 { 2910 Mutex::Autolock al(mBufferLock); 2911 info->mOwnedByClient = true; 2912 2913 // set image-data 2914 if (info->mData->format() != NULL) { 2915 sp<ABuffer> imageData; 2916 if (info->mData->format()->findBuffer("image-data", &imageData)) { 2917 info->mData->meta()->setBuffer("image-data", imageData); 2918 } 2919 int32_t left, top, right, bottom; 2920 if (info->mData->format()->findRect("crop", &left, &top, &right, &bottom)) { 2921 info->mData->meta()->setRect("crop-rect", left, top, right, bottom); 2922 } 2923 } 2924 } 2925 2926 return index; 2927} 2928 2929status_t MediaCodec::connectToSurface(const sp<Surface> &surface) { 2930 status_t err = OK; 2931 if (surface != NULL) { 2932 uint64_t oldId, newId; 2933 if (mSurface != NULL 2934 && surface->getUniqueId(&newId) == NO_ERROR 2935 && mSurface->getUniqueId(&oldId) == NO_ERROR 2936 && newId == oldId) { 2937 ALOGI("[%s] connecting to the same surface. Nothing to do.", mComponentName.c_str()); 2938 return ALREADY_EXISTS; 2939 } 2940 2941 err = nativeWindowConnect(surface.get(), "connectToSurface"); 2942 if (err == OK) { 2943 // Require a fresh set of buffers after each connect by using a unique generation 2944 // number. Rely on the fact that max supported process id by Linux is 2^22. 2945 // PID is never 0 so we don't have to worry that we use the default generation of 0. 2946 // TODO: come up with a unique scheme if other producers also set the generation number. 2947 static uint32_t mSurfaceGeneration = 0; 2948 uint32_t generation = (getpid() << 10) | (++mSurfaceGeneration & ((1 << 10) - 1)); 2949 surface->setGenerationNumber(generation); 2950 ALOGI("[%s] setting surface generation to %u", mComponentName.c_str(), generation); 2951 2952 // HACK: clear any free buffers. Remove when connect will automatically do this. 2953 // This is needed as the consumer may be holding onto stale frames that it can reattach 2954 // to this surface after disconnect/connect, and those free frames would inherit the new 2955 // generation number. Disconnecting after setting a unique generation prevents this. 2956 nativeWindowDisconnect(surface.get(), "connectToSurface(reconnect)"); 2957 err = nativeWindowConnect(surface.get(), "connectToSurface(reconnect)"); 2958 } 2959 2960 if (err != OK) { 2961 ALOGE("nativeWindowConnect returned an error: %s (%d)", strerror(-err), err); 2962 } 2963 } 2964 // do not return ALREADY_EXISTS unless surfaces are the same 2965 return err == ALREADY_EXISTS ? BAD_VALUE : err; 2966} 2967 2968status_t MediaCodec::disconnectFromSurface() { 2969 status_t err = OK; 2970 if (mSurface != NULL) { 2971 // Resetting generation is not technically needed, but there is no need to keep it either 2972 mSurface->setGenerationNumber(0); 2973 err = nativeWindowDisconnect(mSurface.get(), "disconnectFromSurface"); 2974 if (err != OK) { 2975 ALOGW("nativeWindowDisconnect returned an error: %s (%d)", strerror(-err), err); 2976 } 2977 // assume disconnected even on error 2978 mSurface.clear(); 2979 } 2980 return err; 2981} 2982 2983status_t MediaCodec::handleSetSurface(const sp<Surface> &surface) { 2984 status_t err = OK; 2985 if (mSurface != NULL) { 2986 (void)disconnectFromSurface(); 2987 } 2988 if (surface != NULL) { 2989 err = connectToSurface(surface); 2990 if (err == OK) { 2991 mSurface = surface; 2992 } 2993 } 2994 return err; 2995} 2996 2997void MediaCodec::onInputBufferAvailable() { 2998 int32_t index; 2999 while ((index = dequeuePortBuffer(kPortIndexInput)) >= 0) { 3000 sp<AMessage> msg = mCallback->dup(); 3001 msg->setInt32("callbackID", CB_INPUT_AVAILABLE); 3002 msg->setInt32("index", index); 3003 msg->post(); 3004 } 3005} 3006 3007void MediaCodec::onOutputBufferAvailable() { 3008 int32_t index; 3009 while ((index = dequeuePortBuffer(kPortIndexOutput)) >= 0) { 3010 const sp<MediaCodecBuffer> &buffer = 3011 mPortBuffers[kPortIndexOutput][index].mData; 3012 sp<AMessage> msg = mCallback->dup(); 3013 msg->setInt32("callbackID", CB_OUTPUT_AVAILABLE); 3014 msg->setInt32("index", index); 3015 msg->setSize("offset", buffer->offset()); 3016 msg->setSize("size", buffer->size()); 3017 3018 int64_t timeUs; 3019 CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 3020 3021 msg->setInt64("timeUs", timeUs); 3022 3023 int32_t flags; 3024 CHECK(buffer->meta()->findInt32("flags", &flags)); 3025 3026 msg->setInt32("flags", flags); 3027 3028 msg->post(); 3029 } 3030} 3031 3032void MediaCodec::onError(status_t err, int32_t actionCode, const char *detail) { 3033 if (mCallback != NULL) { 3034 sp<AMessage> msg = mCallback->dup(); 3035 msg->setInt32("callbackID", CB_ERROR); 3036 msg->setInt32("err", err); 3037 msg->setInt32("actionCode", actionCode); 3038 3039 if (detail != NULL) { 3040 msg->setString("detail", detail); 3041 } 3042 3043 msg->post(); 3044 } 3045} 3046 3047void MediaCodec::onOutputFormatChanged() { 3048 if (mCallback != NULL) { 3049 sp<AMessage> msg = mCallback->dup(); 3050 msg->setInt32("callbackID", CB_OUTPUT_FORMAT_CHANGED); 3051 msg->setMessage("format", mOutputFormat); 3052 msg->post(); 3053 } 3054} 3055 3056void MediaCodec::postActivityNotificationIfPossible() { 3057 if (mActivityNotify == NULL) { 3058 return; 3059 } 3060 3061 bool isErrorOrOutputChanged = 3062 (mFlags & (kFlagStickyError 3063 | kFlagOutputBuffersChanged 3064 | kFlagOutputFormatChanged)); 3065 3066 if (isErrorOrOutputChanged 3067 || !mAvailPortBuffers[kPortIndexInput].empty() 3068 || !mAvailPortBuffers[kPortIndexOutput].empty()) { 3069 mActivityNotify->setInt32("input-buffers", 3070 mAvailPortBuffers[kPortIndexInput].size()); 3071 3072 if (isErrorOrOutputChanged) { 3073 // we want consumer to dequeue as many times as it can 3074 mActivityNotify->setInt32("output-buffers", INT32_MAX); 3075 } else { 3076 mActivityNotify->setInt32("output-buffers", 3077 mAvailPortBuffers[kPortIndexOutput].size()); 3078 } 3079 mActivityNotify->post(); 3080 mActivityNotify.clear(); 3081 } 3082} 3083 3084status_t MediaCodec::setParameters(const sp<AMessage> ¶ms) { 3085 sp<AMessage> msg = new AMessage(kWhatSetParameters, this); 3086 msg->setMessage("params", params); 3087 3088 sp<AMessage> response; 3089 return PostAndAwaitResponse(msg, &response); 3090} 3091 3092status_t MediaCodec::onSetParameters(const sp<AMessage> ¶ms) { 3093 mCodec->signalSetParameters(params); 3094 3095 return OK; 3096} 3097 3098status_t MediaCodec::amendOutputFormatWithCodecSpecificData( 3099 const sp<MediaCodecBuffer> &buffer) { 3100 AString mime; 3101 CHECK(mOutputFormat->findString("mime", &mime)); 3102 3103 if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)) { 3104 // Codec specific data should be SPS and PPS in a single buffer, 3105 // each prefixed by a startcode (0x00 0x00 0x00 0x01). 3106 // We separate the two and put them into the output format 3107 // under the keys "csd-0" and "csd-1". 3108 3109 unsigned csdIndex = 0; 3110 3111 const uint8_t *data = buffer->data(); 3112 size_t size = buffer->size(); 3113 3114 const uint8_t *nalStart; 3115 size_t nalSize; 3116 while (getNextNALUnit(&data, &size, &nalStart, &nalSize, true) == OK) { 3117 sp<ABuffer> csd = new ABuffer(nalSize + 4); 3118 memcpy(csd->data(), "\x00\x00\x00\x01", 4); 3119 memcpy(csd->data() + 4, nalStart, nalSize); 3120 3121 mOutputFormat->setBuffer( 3122 AStringPrintf("csd-%u", csdIndex).c_str(), csd); 3123 3124 ++csdIndex; 3125 } 3126 3127 if (csdIndex != 2) { 3128 return ERROR_MALFORMED; 3129 } 3130 } else { 3131 // For everything else we just stash the codec specific data into 3132 // the output format as a single piece of csd under "csd-0". 3133 sp<ABuffer> csd = new ABuffer(buffer->size()); 3134 memcpy(csd->data(), buffer->data(), buffer->size()); 3135 csd->setRange(0, buffer->size()); 3136 mOutputFormat->setBuffer("csd-0", csd); 3137 } 3138 3139 return OK; 3140} 3141 3142void MediaCodec::updateBatteryStat() { 3143 if (!mIsVideo) { 3144 return; 3145 } 3146 3147 if (mState == CONFIGURED && !mBatteryStatNotified) { 3148 BatteryNotifier::getInstance().noteStartVideo(mUid); 3149 mBatteryStatNotified = true; 3150 } else if (mState == UNINITIALIZED && mBatteryStatNotified) { 3151 BatteryNotifier::getInstance().noteStopVideo(mUid); 3152 mBatteryStatNotified = false; 3153 } 3154} 3155 3156} // namespace android 3157