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