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