MediaCodec.cpp revision d7ed649cfeff62680b8edb4cb86ce239116d8c8b
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::getInputBuffers(Vector<sp<ABuffer> > *buffers) const { 614 sp<AMessage> msg = new AMessage(kWhatGetBuffers, this); 615 msg->setInt32("portIndex", kPortIndexInput); 616 msg->setPointer("buffers", buffers); 617 618 sp<AMessage> response; 619 return PostAndAwaitResponse(msg, &response); 620} 621 622status_t MediaCodec::getOutputBuffers(Vector<sp<ABuffer> > *buffers) const { 623 sp<AMessage> msg = new AMessage(kWhatGetBuffers, this); 624 msg->setInt32("portIndex", kPortIndexOutput); 625 msg->setPointer("buffers", buffers); 626 627 sp<AMessage> response; 628 return PostAndAwaitResponse(msg, &response); 629} 630 631status_t MediaCodec::getOutputBuffer(size_t index, sp<ABuffer> *buffer) { 632 sp<AMessage> format; 633 return getBufferAndFormat(kPortIndexOutput, index, buffer, &format); 634} 635 636status_t MediaCodec::getOutputFormat(size_t index, sp<AMessage> *format) { 637 sp<ABuffer> buffer; 638 return getBufferAndFormat(kPortIndexOutput, index, &buffer, format); 639} 640 641status_t MediaCodec::getInputBuffer(size_t index, sp<ABuffer> *buffer) { 642 sp<AMessage> format; 643 return getBufferAndFormat(kPortIndexInput, index, buffer, &format); 644} 645 646bool MediaCodec::isExecuting() const { 647 return mState == STARTED || mState == FLUSHED; 648} 649 650status_t MediaCodec::getBufferAndFormat( 651 size_t portIndex, size_t index, 652 sp<ABuffer> *buffer, sp<AMessage> *format) { 653 // use mutex instead of a context switch 654 655 buffer->clear(); 656 format->clear(); 657 if (!isExecuting()) { 658 return INVALID_OPERATION; 659 } 660 661 // we do not want mPortBuffers to change during this section 662 // we also don't want mOwnedByClient to change during this 663 Mutex::Autolock al(mBufferLock); 664 Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 665 if (index < buffers->size()) { 666 const BufferInfo &info = buffers->itemAt(index); 667 if (info.mOwnedByClient) { 668 // by the time buffers array is initialized, crypto is set 669 if (portIndex == kPortIndexInput && mCrypto != NULL) { 670 *buffer = info.mEncryptedData; 671 } else { 672 *buffer = info.mData; 673 } 674 *format = info.mFormat; 675 } 676 } 677 return OK; 678} 679 680status_t MediaCodec::flush() { 681 sp<AMessage> msg = new AMessage(kWhatFlush, this); 682 683 sp<AMessage> response; 684 return PostAndAwaitResponse(msg, &response); 685} 686 687status_t MediaCodec::requestIDRFrame() { 688 (new AMessage(kWhatRequestIDRFrame, this))->post(); 689 690 return OK; 691} 692 693void MediaCodec::requestActivityNotification(const sp<AMessage> ¬ify) { 694 sp<AMessage> msg = new AMessage(kWhatRequestActivityNotification, this); 695 msg->setMessage("notify", notify); 696 msg->post(); 697} 698 699//////////////////////////////////////////////////////////////////////////////// 700 701void MediaCodec::cancelPendingDequeueOperations() { 702 if (mFlags & kFlagDequeueInputPending) { 703 PostReplyWithError(mDequeueInputReplyID, INVALID_OPERATION); 704 705 ++mDequeueInputTimeoutGeneration; 706 mDequeueInputReplyID = 0; 707 mFlags &= ~kFlagDequeueInputPending; 708 } 709 710 if (mFlags & kFlagDequeueOutputPending) { 711 PostReplyWithError(mDequeueOutputReplyID, INVALID_OPERATION); 712 713 ++mDequeueOutputTimeoutGeneration; 714 mDequeueOutputReplyID = 0; 715 mFlags &= ~kFlagDequeueOutputPending; 716 } 717} 718 719bool MediaCodec::handleDequeueInputBuffer(const sp<AReplyToken> &replyID, bool newRequest) { 720 if (!isExecuting() || (mFlags & kFlagIsAsync) 721 || (newRequest && (mFlags & kFlagDequeueInputPending))) { 722 PostReplyWithError(replyID, INVALID_OPERATION); 723 return true; 724 } else if (mFlags & kFlagStickyError) { 725 PostReplyWithError(replyID, getStickyError()); 726 return true; 727 } 728 729 ssize_t index = dequeuePortBuffer(kPortIndexInput); 730 731 if (index < 0) { 732 CHECK_EQ(index, -EAGAIN); 733 return false; 734 } 735 736 sp<AMessage> response = new AMessage; 737 response->setSize("index", index); 738 response->postReply(replyID); 739 740 return true; 741} 742 743bool MediaCodec::handleDequeueOutputBuffer(const sp<AReplyToken> &replyID, bool newRequest) { 744 sp<AMessage> response = new AMessage; 745 746 if (!isExecuting() || (mFlags & kFlagIsAsync) 747 || (newRequest && (mFlags & kFlagDequeueOutputPending))) { 748 response->setInt32("err", INVALID_OPERATION); 749 } else if (mFlags & kFlagStickyError) { 750 response->setInt32("err", getStickyError()); 751 } else if (mFlags & kFlagOutputBuffersChanged) { 752 response->setInt32("err", INFO_OUTPUT_BUFFERS_CHANGED); 753 mFlags &= ~kFlagOutputBuffersChanged; 754 } else if (mFlags & kFlagOutputFormatChanged) { 755 response->setInt32("err", INFO_FORMAT_CHANGED); 756 mFlags &= ~kFlagOutputFormatChanged; 757 } else { 758 ssize_t index = dequeuePortBuffer(kPortIndexOutput); 759 760 if (index < 0) { 761 CHECK_EQ(index, -EAGAIN); 762 return false; 763 } 764 765 const sp<ABuffer> &buffer = 766 mPortBuffers[kPortIndexOutput].itemAt(index).mData; 767 768 response->setSize("index", index); 769 response->setSize("offset", buffer->offset()); 770 response->setSize("size", buffer->size()); 771 772 int64_t timeUs; 773 CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 774 775 response->setInt64("timeUs", timeUs); 776 777 int32_t omxFlags; 778 CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags)); 779 780 uint32_t flags = 0; 781 if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) { 782 flags |= BUFFER_FLAG_SYNCFRAME; 783 } 784 if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) { 785 flags |= BUFFER_FLAG_CODECCONFIG; 786 } 787 if (omxFlags & OMX_BUFFERFLAG_EOS) { 788 flags |= BUFFER_FLAG_EOS; 789 } 790 791 response->setInt32("flags", flags); 792 } 793 794 response->postReply(replyID); 795 796 return true; 797} 798 799void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { 800 switch (msg->what()) { 801 case kWhatCodecNotify: 802 { 803 int32_t what; 804 CHECK(msg->findInt32("what", &what)); 805 806 switch (what) { 807 case CodecBase::kWhatError: 808 { 809 int32_t err, actionCode; 810 CHECK(msg->findInt32("err", &err)); 811 CHECK(msg->findInt32("actionCode", &actionCode)); 812 813 ALOGE("Codec reported err %#x, actionCode %d, while in state %d", 814 err, actionCode, mState); 815 if (err == DEAD_OBJECT) { 816 mFlags |= kFlagSawMediaServerDie; 817 mFlags &= ~kFlagIsComponentAllocated; 818 } 819 820 bool sendErrorResponse = true; 821 822 switch (mState) { 823 case INITIALIZING: 824 { 825 setState(UNINITIALIZED); 826 break; 827 } 828 829 case CONFIGURING: 830 { 831 setState(actionCode == ACTION_CODE_FATAL ? 832 UNINITIALIZED : INITIALIZED); 833 break; 834 } 835 836 case STARTING: 837 { 838 setState(actionCode == ACTION_CODE_FATAL ? 839 UNINITIALIZED : CONFIGURED); 840 break; 841 } 842 843 case STOPPING: 844 case RELEASING: 845 { 846 // Ignore the error, assuming we'll still get 847 // the shutdown complete notification. 848 849 sendErrorResponse = false; 850 851 if (mFlags & kFlagSawMediaServerDie) { 852 // MediaServer died, there definitely won't 853 // be a shutdown complete notification after 854 // all. 855 856 // note that we're directly going from 857 // STOPPING->UNINITIALIZED, instead of the 858 // usual STOPPING->INITIALIZED state. 859 setState(UNINITIALIZED); 860 if (mState == RELEASING) { 861 mComponentName.clear(); 862 } 863 (new AMessage)->postReply(mReplyID); 864 } 865 break; 866 } 867 868 case FLUSHING: 869 { 870 if (actionCode == ACTION_CODE_FATAL) { 871 setState(UNINITIALIZED); 872 } else { 873 setState( 874 (mFlags & kFlagIsAsync) ? FLUSHED : STARTED); 875 } 876 break; 877 } 878 879 case FLUSHED: 880 case STARTED: 881 { 882 sendErrorResponse = false; 883 884 setStickyError(err); 885 postActivityNotificationIfPossible(); 886 887 cancelPendingDequeueOperations(); 888 889 if (mFlags & kFlagIsAsync) { 890 onError(err, actionCode); 891 } 892 switch (actionCode) { 893 case ACTION_CODE_TRANSIENT: 894 break; 895 case ACTION_CODE_RECOVERABLE: 896 setState(INITIALIZED); 897 break; 898 default: 899 setState(UNINITIALIZED); 900 break; 901 } 902 break; 903 } 904 905 default: 906 { 907 sendErrorResponse = false; 908 909 setStickyError(err); 910 postActivityNotificationIfPossible(); 911 912 // actionCode in an uninitialized state is always fatal. 913 if (mState == UNINITIALIZED) { 914 actionCode = ACTION_CODE_FATAL; 915 } 916 if (mFlags & kFlagIsAsync) { 917 onError(err, actionCode); 918 } 919 switch (actionCode) { 920 case ACTION_CODE_TRANSIENT: 921 break; 922 case ACTION_CODE_RECOVERABLE: 923 setState(INITIALIZED); 924 break; 925 default: 926 setState(UNINITIALIZED); 927 break; 928 } 929 break; 930 } 931 } 932 933 if (sendErrorResponse) { 934 PostReplyWithError(mReplyID, err); 935 } 936 break; 937 } 938 939 case CodecBase::kWhatComponentAllocated: 940 { 941 CHECK_EQ(mState, INITIALIZING); 942 setState(INITIALIZED); 943 mFlags |= kFlagIsComponentAllocated; 944 945 CHECK(msg->findString("componentName", &mComponentName)); 946 947 if (mComponentName.startsWith("OMX.google.")) { 948 mFlags |= kFlagUsesSoftwareRenderer; 949 } else { 950 mFlags &= ~kFlagUsesSoftwareRenderer; 951 } 952 953 if (mComponentName.endsWith(".secure")) { 954 mFlags |= kFlagIsSecure; 955 } else { 956 mFlags &= ~kFlagIsSecure; 957 } 958 959 (new AMessage)->postReply(mReplyID); 960 break; 961 } 962 963 case CodecBase::kWhatComponentConfigured: 964 { 965 CHECK_EQ(mState, CONFIGURING); 966 967 // reset input surface flag 968 mHaveInputSurface = false; 969 970 CHECK(msg->findMessage("input-format", &mInputFormat)); 971 CHECK(msg->findMessage("output-format", &mOutputFormat)); 972 973 int32_t usingSwRenderer; 974 if (mOutputFormat->findInt32("using-sw-renderer", &usingSwRenderer) 975 && usingSwRenderer) { 976 mFlags |= kFlagUsesSoftwareRenderer; 977 } 978 setState(CONFIGURED); 979 (new AMessage)->postReply(mReplyID); 980 break; 981 } 982 983 case CodecBase::kWhatInputSurfaceCreated: 984 { 985 // response to initiateCreateInputSurface() 986 status_t err = NO_ERROR; 987 sp<AMessage> response = new AMessage(); 988 if (!msg->findInt32("err", &err)) { 989 sp<RefBase> obj; 990 msg->findObject("input-surface", &obj); 991 CHECK(obj != NULL); 992 response->setObject("input-surface", obj); 993 mHaveInputSurface = true; 994 } else { 995 response->setInt32("err", err); 996 } 997 response->postReply(mReplyID); 998 break; 999 } 1000 1001 case CodecBase::kWhatSignaledInputEOS: 1002 { 1003 // response to signalEndOfInputStream() 1004 sp<AMessage> response = new AMessage(); 1005 status_t err; 1006 if (msg->findInt32("err", &err)) { 1007 response->setInt32("err", err); 1008 } 1009 response->postReply(mReplyID); 1010 break; 1011 } 1012 1013 1014 case CodecBase::kWhatBuffersAllocated: 1015 { 1016 Mutex::Autolock al(mBufferLock); 1017 int32_t portIndex; 1018 CHECK(msg->findInt32("portIndex", &portIndex)); 1019 1020 ALOGV("%s buffers allocated", 1021 portIndex == kPortIndexInput ? "input" : "output"); 1022 1023 CHECK(portIndex == kPortIndexInput 1024 || portIndex == kPortIndexOutput); 1025 1026 mPortBuffers[portIndex].clear(); 1027 1028 Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 1029 1030 sp<RefBase> obj; 1031 CHECK(msg->findObject("portDesc", &obj)); 1032 1033 sp<CodecBase::PortDescription> portDesc = 1034 static_cast<CodecBase::PortDescription *>(obj.get()); 1035 1036 size_t numBuffers = portDesc->countBuffers(); 1037 1038 size_t totalSize = 0; 1039 for (size_t i = 0; i < numBuffers; ++i) { 1040 if (portIndex == kPortIndexInput && mCrypto != NULL) { 1041 totalSize += portDesc->bufferAt(i)->capacity(); 1042 } 1043 } 1044 1045 if (totalSize) { 1046 mDealer = new MemoryDealer(totalSize, "MediaCodec"); 1047 } 1048 1049 for (size_t i = 0; i < numBuffers; ++i) { 1050 BufferInfo info; 1051 info.mBufferID = portDesc->bufferIDAt(i); 1052 info.mOwnedByClient = false; 1053 info.mData = portDesc->bufferAt(i); 1054 1055 if (portIndex == kPortIndexInput && mCrypto != NULL) { 1056 sp<IMemory> mem = mDealer->allocate(info.mData->capacity()); 1057 info.mEncryptedData = 1058 new ABuffer(mem->pointer(), info.mData->capacity()); 1059 info.mSharedEncryptedBuffer = mem; 1060 } 1061 1062 buffers->push_back(info); 1063 } 1064 1065 if (portIndex == kPortIndexOutput) { 1066 if (mState == STARTING) { 1067 // We're always allocating output buffers after 1068 // allocating input buffers, so this is a good 1069 // indication that now all buffers are allocated. 1070 setState(STARTED); 1071 (new AMessage)->postReply(mReplyID); 1072 } else { 1073 mFlags |= kFlagOutputBuffersChanged; 1074 postActivityNotificationIfPossible(); 1075 } 1076 } 1077 break; 1078 } 1079 1080 case CodecBase::kWhatOutputFormatChanged: 1081 { 1082 ALOGV("codec output format changed"); 1083 1084 if (mSoftRenderer == NULL && 1085 mNativeWindow != NULL && 1086 (mFlags & kFlagUsesSoftwareRenderer)) { 1087 AString mime; 1088 CHECK(msg->findString("mime", &mime)); 1089 1090 if (mime.startsWithIgnoreCase("video/")) { 1091 mSoftRenderer = new SoftwareRenderer(mNativeWindow); 1092 } 1093 } 1094 1095 mOutputFormat = msg; 1096 1097 if (mFlags & kFlagIsEncoder) { 1098 // Before we announce the format change we should 1099 // collect codec specific data and amend the output 1100 // format as necessary. 1101 mFlags |= kFlagGatherCodecSpecificData; 1102 } else if (mFlags & kFlagIsAsync) { 1103 onOutputFormatChanged(); 1104 } else { 1105 mFlags |= kFlagOutputFormatChanged; 1106 postActivityNotificationIfPossible(); 1107 } 1108 1109 // Notify mCrypto of video resolution changes 1110 if (mCrypto != NULL) { 1111 int32_t left, top, right, bottom, width, height; 1112 if (mOutputFormat->findRect("crop", &left, &top, &right, &bottom)) { 1113 mCrypto->notifyResolution(right - left + 1, bottom - top + 1); 1114 } else if (mOutputFormat->findInt32("width", &width) 1115 && mOutputFormat->findInt32("height", &height)) { 1116 mCrypto->notifyResolution(width, height); 1117 } 1118 } 1119 1120 break; 1121 } 1122 1123 case CodecBase::kWhatFillThisBuffer: 1124 { 1125 /* size_t index = */updateBuffers(kPortIndexInput, msg); 1126 1127 if (mState == FLUSHING 1128 || mState == STOPPING 1129 || mState == RELEASING) { 1130 returnBuffersToCodecOnPort(kPortIndexInput); 1131 break; 1132 } 1133 1134 if (!mCSD.empty()) { 1135 ssize_t index = dequeuePortBuffer(kPortIndexInput); 1136 CHECK_GE(index, 0); 1137 1138 // If codec specific data had been specified as 1139 // part of the format in the call to configure and 1140 // if there's more csd left, we submit it here 1141 // clients only get access to input buffers once 1142 // this data has been exhausted. 1143 1144 status_t err = queueCSDInputBuffer(index); 1145 1146 if (err != OK) { 1147 ALOGE("queueCSDInputBuffer failed w/ error %d", 1148 err); 1149 1150 setStickyError(err); 1151 postActivityNotificationIfPossible(); 1152 1153 cancelPendingDequeueOperations(); 1154 } 1155 break; 1156 } 1157 1158 if (mFlags & kFlagIsAsync) { 1159 if (!mHaveInputSurface) { 1160 onInputBufferAvailable(); 1161 } 1162 } else if (mFlags & kFlagDequeueInputPending) { 1163 CHECK(handleDequeueInputBuffer(mDequeueInputReplyID)); 1164 1165 ++mDequeueInputTimeoutGeneration; 1166 mFlags &= ~kFlagDequeueInputPending; 1167 mDequeueInputReplyID = 0; 1168 } else { 1169 postActivityNotificationIfPossible(); 1170 } 1171 break; 1172 } 1173 1174 case CodecBase::kWhatDrainThisBuffer: 1175 { 1176 /* size_t index = */updateBuffers(kPortIndexOutput, msg); 1177 1178 if (mState == FLUSHING 1179 || mState == STOPPING 1180 || mState == RELEASING) { 1181 returnBuffersToCodecOnPort(kPortIndexOutput); 1182 break; 1183 } 1184 1185 sp<ABuffer> buffer; 1186 CHECK(msg->findBuffer("buffer", &buffer)); 1187 1188 int32_t omxFlags; 1189 CHECK(msg->findInt32("flags", &omxFlags)); 1190 1191 buffer->meta()->setInt32("omxFlags", omxFlags); 1192 1193 if (mFlags & kFlagGatherCodecSpecificData) { 1194 // This is the very first output buffer after a 1195 // format change was signalled, it'll either contain 1196 // the one piece of codec specific data we can expect 1197 // or there won't be codec specific data. 1198 if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) { 1199 status_t err = 1200 amendOutputFormatWithCodecSpecificData(buffer); 1201 1202 if (err != OK) { 1203 ALOGE("Codec spit out malformed codec " 1204 "specific data!"); 1205 } 1206 } 1207 1208 mFlags &= ~kFlagGatherCodecSpecificData; 1209 if (mFlags & kFlagIsAsync) { 1210 onOutputFormatChanged(); 1211 } else { 1212 mFlags |= kFlagOutputFormatChanged; 1213 } 1214 } 1215 1216 if (mFlags & kFlagIsAsync) { 1217 onOutputBufferAvailable(); 1218 } else if (mFlags & kFlagDequeueOutputPending) { 1219 CHECK(handleDequeueOutputBuffer(mDequeueOutputReplyID)); 1220 1221 ++mDequeueOutputTimeoutGeneration; 1222 mFlags &= ~kFlagDequeueOutputPending; 1223 mDequeueOutputReplyID = 0; 1224 } else { 1225 postActivityNotificationIfPossible(); 1226 } 1227 1228 break; 1229 } 1230 1231 case CodecBase::kWhatEOS: 1232 { 1233 // We already notify the client of this by using the 1234 // corresponding flag in "onOutputBufferReady". 1235 break; 1236 } 1237 1238 case CodecBase::kWhatShutdownCompleted: 1239 { 1240 if (mState == STOPPING) { 1241 setState(INITIALIZED); 1242 } else { 1243 CHECK_EQ(mState, RELEASING); 1244 setState(UNINITIALIZED); 1245 mComponentName.clear(); 1246 } 1247 mFlags &= ~kFlagIsComponentAllocated; 1248 1249 (new AMessage)->postReply(mReplyID); 1250 break; 1251 } 1252 1253 case CodecBase::kWhatFlushCompleted: 1254 { 1255 if (mState != FLUSHING) { 1256 ALOGW("received FlushCompleted message in state %d", 1257 mState); 1258 break; 1259 } 1260 1261 if (mFlags & kFlagIsAsync) { 1262 setState(FLUSHED); 1263 } else { 1264 setState(STARTED); 1265 mCodec->signalResume(); 1266 } 1267 1268 (new AMessage)->postReply(mReplyID); 1269 break; 1270 } 1271 1272 default: 1273 TRESPASS(); 1274 } 1275 break; 1276 } 1277 1278 case kWhatInit: 1279 { 1280 sp<AReplyToken> replyID; 1281 CHECK(msg->senderAwaitsResponse(&replyID)); 1282 1283 if (mState != UNINITIALIZED) { 1284 PostReplyWithError(replyID, INVALID_OPERATION); 1285 break; 1286 } 1287 1288 mReplyID = replyID; 1289 setState(INITIALIZING); 1290 1291 AString name; 1292 CHECK(msg->findString("name", &name)); 1293 1294 int32_t nameIsType; 1295 int32_t encoder = false; 1296 CHECK(msg->findInt32("nameIsType", &nameIsType)); 1297 if (nameIsType) { 1298 CHECK(msg->findInt32("encoder", &encoder)); 1299 } 1300 1301 sp<AMessage> format = new AMessage; 1302 1303 if (nameIsType) { 1304 format->setString("mime", name.c_str()); 1305 format->setInt32("encoder", encoder); 1306 } else { 1307 format->setString("componentName", name.c_str()); 1308 } 1309 1310 mCodec->initiateAllocateComponent(format); 1311 break; 1312 } 1313 1314 case kWhatSetCallback: 1315 { 1316 sp<AReplyToken> replyID; 1317 CHECK(msg->senderAwaitsResponse(&replyID)); 1318 1319 if (mState == UNINITIALIZED 1320 || mState == INITIALIZING 1321 || isExecuting()) { 1322 // callback can't be set after codec is executing, 1323 // or before it's initialized (as the callback 1324 // will be cleared when it goes to INITIALIZED) 1325 PostReplyWithError(replyID, INVALID_OPERATION); 1326 break; 1327 } 1328 1329 sp<AMessage> callback; 1330 CHECK(msg->findMessage("callback", &callback)); 1331 1332 mCallback = callback; 1333 1334 if (mCallback != NULL) { 1335 ALOGI("MediaCodec will operate in async mode"); 1336 mFlags |= kFlagIsAsync; 1337 } else { 1338 mFlags &= ~kFlagIsAsync; 1339 } 1340 1341 sp<AMessage> response = new AMessage; 1342 response->postReply(replyID); 1343 break; 1344 } 1345 1346 case kWhatConfigure: 1347 { 1348 sp<AReplyToken> replyID; 1349 CHECK(msg->senderAwaitsResponse(&replyID)); 1350 1351 if (mState != INITIALIZED) { 1352 PostReplyWithError(replyID, INVALID_OPERATION); 1353 break; 1354 } 1355 1356 sp<RefBase> obj; 1357 if (!msg->findObject("native-window", &obj)) { 1358 obj.clear(); 1359 } 1360 1361 sp<AMessage> format; 1362 CHECK(msg->findMessage("format", &format)); 1363 1364 if (obj != NULL) { 1365 format->setObject("native-window", obj); 1366 1367 status_t err = setNativeWindow( 1368 static_cast<NativeWindowWrapper *>(obj.get()) 1369 ->getSurfaceTextureClient()); 1370 1371 if (err != OK) { 1372 PostReplyWithError(replyID, err); 1373 break; 1374 } 1375 } else { 1376 setNativeWindow(NULL); 1377 } 1378 1379 mReplyID = replyID; 1380 setState(CONFIGURING); 1381 1382 void *crypto; 1383 if (!msg->findPointer("crypto", &crypto)) { 1384 crypto = NULL; 1385 } 1386 1387 mCrypto = static_cast<ICrypto *>(crypto); 1388 1389 uint32_t flags; 1390 CHECK(msg->findInt32("flags", (int32_t *)&flags)); 1391 1392 if (flags & CONFIGURE_FLAG_ENCODE) { 1393 format->setInt32("encoder", true); 1394 mFlags |= kFlagIsEncoder; 1395 } 1396 1397 extractCSD(format); 1398 1399 mCodec->initiateConfigureComponent(format); 1400 break; 1401 } 1402 1403 case kWhatCreateInputSurface: 1404 { 1405 sp<AReplyToken> replyID; 1406 CHECK(msg->senderAwaitsResponse(&replyID)); 1407 1408 // Must be configured, but can't have been started yet. 1409 if (mState != CONFIGURED) { 1410 PostReplyWithError(replyID, INVALID_OPERATION); 1411 break; 1412 } 1413 1414 mReplyID = replyID; 1415 mCodec->initiateCreateInputSurface(); 1416 break; 1417 } 1418 1419 case kWhatStart: 1420 { 1421 sp<AReplyToken> replyID; 1422 CHECK(msg->senderAwaitsResponse(&replyID)); 1423 1424 if (mState == FLUSHED) { 1425 setState(STARTED); 1426 mCodec->signalResume(); 1427 PostReplyWithError(replyID, OK); 1428 break; 1429 } else if (mState != CONFIGURED) { 1430 PostReplyWithError(replyID, INVALID_OPERATION); 1431 break; 1432 } 1433 1434 mReplyID = replyID; 1435 setState(STARTING); 1436 1437 mCodec->initiateStart(); 1438 break; 1439 } 1440 1441 case kWhatStop: 1442 case kWhatRelease: 1443 { 1444 State targetState = 1445 (msg->what() == kWhatStop) ? INITIALIZED : UNINITIALIZED; 1446 1447 sp<AReplyToken> replyID; 1448 CHECK(msg->senderAwaitsResponse(&replyID)); 1449 1450 if (!((mFlags & kFlagIsComponentAllocated) && targetState == UNINITIALIZED) // See 1 1451 && mState != INITIALIZED 1452 && mState != CONFIGURED && !isExecuting()) { 1453 // 1) Permit release to shut down the component if allocated. 1454 // 1455 // 2) We may be in "UNINITIALIZED" state already and 1456 // also shutdown the encoder/decoder without the 1457 // client being aware of this if media server died while 1458 // we were being stopped. The client would assume that 1459 // after stop() returned, it would be safe to call release() 1460 // and it should be in this case, no harm to allow a release() 1461 // if we're already uninitialized. 1462 sp<AMessage> response = new AMessage; 1463 status_t err = mState == targetState ? OK : INVALID_OPERATION; 1464 response->setInt32("err", err); 1465 if (err == OK && targetState == UNINITIALIZED) { 1466 mComponentName.clear(); 1467 } 1468 response->postReply(replyID); 1469 break; 1470 } 1471 1472 if (mFlags & kFlagSawMediaServerDie) { 1473 // It's dead, Jim. Don't expect initiateShutdown to yield 1474 // any useful results now... 1475 setState(UNINITIALIZED); 1476 if (targetState == UNINITIALIZED) { 1477 mComponentName.clear(); 1478 } 1479 (new AMessage)->postReply(replyID); 1480 break; 1481 } 1482 1483 mReplyID = replyID; 1484 setState(msg->what() == kWhatStop ? STOPPING : RELEASING); 1485 1486 mCodec->initiateShutdown( 1487 msg->what() == kWhatStop /* keepComponentAllocated */); 1488 1489 returnBuffersToCodec(); 1490 break; 1491 } 1492 1493 case kWhatDequeueInputBuffer: 1494 { 1495 sp<AReplyToken> replyID; 1496 CHECK(msg->senderAwaitsResponse(&replyID)); 1497 1498 if (mFlags & kFlagIsAsync) { 1499 ALOGE("dequeueOutputBuffer can't be used in async mode"); 1500 PostReplyWithError(replyID, INVALID_OPERATION); 1501 break; 1502 } 1503 1504 if (mHaveInputSurface) { 1505 ALOGE("dequeueInputBuffer can't be used with input surface"); 1506 PostReplyWithError(replyID, INVALID_OPERATION); 1507 break; 1508 } 1509 1510 if (handleDequeueInputBuffer(replyID, true /* new request */)) { 1511 break; 1512 } 1513 1514 int64_t timeoutUs; 1515 CHECK(msg->findInt64("timeoutUs", &timeoutUs)); 1516 1517 if (timeoutUs == 0ll) { 1518 PostReplyWithError(replyID, -EAGAIN); 1519 break; 1520 } 1521 1522 mFlags |= kFlagDequeueInputPending; 1523 mDequeueInputReplyID = replyID; 1524 1525 if (timeoutUs > 0ll) { 1526 sp<AMessage> timeoutMsg = 1527 new AMessage(kWhatDequeueInputTimedOut, this); 1528 timeoutMsg->setInt32( 1529 "generation", ++mDequeueInputTimeoutGeneration); 1530 timeoutMsg->post(timeoutUs); 1531 } 1532 break; 1533 } 1534 1535 case kWhatDequeueInputTimedOut: 1536 { 1537 int32_t generation; 1538 CHECK(msg->findInt32("generation", &generation)); 1539 1540 if (generation != mDequeueInputTimeoutGeneration) { 1541 // Obsolete 1542 break; 1543 } 1544 1545 CHECK(mFlags & kFlagDequeueInputPending); 1546 1547 PostReplyWithError(mDequeueInputReplyID, -EAGAIN); 1548 1549 mFlags &= ~kFlagDequeueInputPending; 1550 mDequeueInputReplyID = 0; 1551 break; 1552 } 1553 1554 case kWhatQueueInputBuffer: 1555 { 1556 sp<AReplyToken> replyID; 1557 CHECK(msg->senderAwaitsResponse(&replyID)); 1558 1559 if (!isExecuting()) { 1560 PostReplyWithError(replyID, INVALID_OPERATION); 1561 break; 1562 } else if (mFlags & kFlagStickyError) { 1563 PostReplyWithError(replyID, getStickyError()); 1564 break; 1565 } 1566 1567 status_t err = onQueueInputBuffer(msg); 1568 1569 PostReplyWithError(replyID, err); 1570 break; 1571 } 1572 1573 case kWhatDequeueOutputBuffer: 1574 { 1575 sp<AReplyToken> replyID; 1576 CHECK(msg->senderAwaitsResponse(&replyID)); 1577 1578 if (mFlags & kFlagIsAsync) { 1579 ALOGE("dequeueOutputBuffer can't be used in async mode"); 1580 PostReplyWithError(replyID, INVALID_OPERATION); 1581 break; 1582 } 1583 1584 if (handleDequeueOutputBuffer(replyID, true /* new request */)) { 1585 break; 1586 } 1587 1588 int64_t timeoutUs; 1589 CHECK(msg->findInt64("timeoutUs", &timeoutUs)); 1590 1591 if (timeoutUs == 0ll) { 1592 PostReplyWithError(replyID, -EAGAIN); 1593 break; 1594 } 1595 1596 mFlags |= kFlagDequeueOutputPending; 1597 mDequeueOutputReplyID = replyID; 1598 1599 if (timeoutUs > 0ll) { 1600 sp<AMessage> timeoutMsg = 1601 new AMessage(kWhatDequeueOutputTimedOut, this); 1602 timeoutMsg->setInt32( 1603 "generation", ++mDequeueOutputTimeoutGeneration); 1604 timeoutMsg->post(timeoutUs); 1605 } 1606 break; 1607 } 1608 1609 case kWhatDequeueOutputTimedOut: 1610 { 1611 int32_t generation; 1612 CHECK(msg->findInt32("generation", &generation)); 1613 1614 if (generation != mDequeueOutputTimeoutGeneration) { 1615 // Obsolete 1616 break; 1617 } 1618 1619 CHECK(mFlags & kFlagDequeueOutputPending); 1620 1621 PostReplyWithError(mDequeueOutputReplyID, -EAGAIN); 1622 1623 mFlags &= ~kFlagDequeueOutputPending; 1624 mDequeueOutputReplyID = 0; 1625 break; 1626 } 1627 1628 case kWhatReleaseOutputBuffer: 1629 { 1630 sp<AReplyToken> replyID; 1631 CHECK(msg->senderAwaitsResponse(&replyID)); 1632 1633 if (!isExecuting()) { 1634 PostReplyWithError(replyID, INVALID_OPERATION); 1635 break; 1636 } else if (mFlags & kFlagStickyError) { 1637 PostReplyWithError(replyID, getStickyError()); 1638 break; 1639 } 1640 1641 status_t err = onReleaseOutputBuffer(msg); 1642 1643 PostReplyWithError(replyID, err); 1644 break; 1645 } 1646 1647 case kWhatSignalEndOfInputStream: 1648 { 1649 sp<AReplyToken> replyID; 1650 CHECK(msg->senderAwaitsResponse(&replyID)); 1651 1652 if (!isExecuting()) { 1653 PostReplyWithError(replyID, INVALID_OPERATION); 1654 break; 1655 } else if (mFlags & kFlagStickyError) { 1656 PostReplyWithError(replyID, getStickyError()); 1657 break; 1658 } 1659 1660 mReplyID = replyID; 1661 mCodec->signalEndOfInputStream(); 1662 break; 1663 } 1664 1665 case kWhatGetBuffers: 1666 { 1667 sp<AReplyToken> replyID; 1668 CHECK(msg->senderAwaitsResponse(&replyID)); 1669 1670 if (!isExecuting() || (mFlags & kFlagIsAsync)) { 1671 PostReplyWithError(replyID, INVALID_OPERATION); 1672 break; 1673 } else if (mFlags & kFlagStickyError) { 1674 PostReplyWithError(replyID, getStickyError()); 1675 break; 1676 } 1677 1678 int32_t portIndex; 1679 CHECK(msg->findInt32("portIndex", &portIndex)); 1680 1681 Vector<sp<ABuffer> > *dstBuffers; 1682 CHECK(msg->findPointer("buffers", (void **)&dstBuffers)); 1683 1684 dstBuffers->clear(); 1685 const Vector<BufferInfo> &srcBuffers = mPortBuffers[portIndex]; 1686 1687 for (size_t i = 0; i < srcBuffers.size(); ++i) { 1688 const BufferInfo &info = srcBuffers.itemAt(i); 1689 1690 dstBuffers->push_back( 1691 (portIndex == kPortIndexInput && mCrypto != NULL) 1692 ? info.mEncryptedData : info.mData); 1693 } 1694 1695 (new AMessage)->postReply(replyID); 1696 break; 1697 } 1698 1699 case kWhatFlush: 1700 { 1701 sp<AReplyToken> replyID; 1702 CHECK(msg->senderAwaitsResponse(&replyID)); 1703 1704 if (!isExecuting()) { 1705 PostReplyWithError(replyID, INVALID_OPERATION); 1706 break; 1707 } else if (mFlags & kFlagStickyError) { 1708 PostReplyWithError(replyID, getStickyError()); 1709 break; 1710 } 1711 1712 mReplyID = replyID; 1713 // TODO: skip flushing if already FLUSHED 1714 setState(FLUSHING); 1715 1716 mCodec->signalFlush(); 1717 returnBuffersToCodec(); 1718 break; 1719 } 1720 1721 case kWhatGetInputFormat: 1722 case kWhatGetOutputFormat: 1723 { 1724 sp<AMessage> format = 1725 (msg->what() == kWhatGetOutputFormat ? mOutputFormat : mInputFormat); 1726 1727 sp<AReplyToken> replyID; 1728 CHECK(msg->senderAwaitsResponse(&replyID)); 1729 1730 if ((mState != CONFIGURED && mState != STARTING && 1731 mState != STARTED && mState != FLUSHING && 1732 mState != FLUSHED) 1733 || format == NULL) { 1734 PostReplyWithError(replyID, INVALID_OPERATION); 1735 break; 1736 } else if (mFlags & kFlagStickyError) { 1737 PostReplyWithError(replyID, getStickyError()); 1738 break; 1739 } 1740 1741 sp<AMessage> response = new AMessage; 1742 response->setMessage("format", format); 1743 response->postReply(replyID); 1744 break; 1745 } 1746 1747 case kWhatRequestIDRFrame: 1748 { 1749 mCodec->signalRequestIDRFrame(); 1750 break; 1751 } 1752 1753 case kWhatRequestActivityNotification: 1754 { 1755 CHECK(mActivityNotify == NULL); 1756 CHECK(msg->findMessage("notify", &mActivityNotify)); 1757 1758 postActivityNotificationIfPossible(); 1759 break; 1760 } 1761 1762 case kWhatGetName: 1763 { 1764 sp<AReplyToken> replyID; 1765 CHECK(msg->senderAwaitsResponse(&replyID)); 1766 1767 if (mComponentName.empty()) { 1768 PostReplyWithError(replyID, INVALID_OPERATION); 1769 break; 1770 } 1771 1772 sp<AMessage> response = new AMessage; 1773 response->setString("name", mComponentName.c_str()); 1774 response->postReply(replyID); 1775 break; 1776 } 1777 1778 case kWhatSetParameters: 1779 { 1780 sp<AReplyToken> replyID; 1781 CHECK(msg->senderAwaitsResponse(&replyID)); 1782 1783 sp<AMessage> params; 1784 CHECK(msg->findMessage("params", ¶ms)); 1785 1786 status_t err = onSetParameters(params); 1787 1788 PostReplyWithError(replyID, err); 1789 break; 1790 } 1791 1792 default: 1793 TRESPASS(); 1794 } 1795} 1796 1797void MediaCodec::extractCSD(const sp<AMessage> &format) { 1798 mCSD.clear(); 1799 1800 size_t i = 0; 1801 for (;;) { 1802 sp<ABuffer> csd; 1803 if (!format->findBuffer(AStringPrintf("csd-%u", i).c_str(), &csd)) { 1804 break; 1805 } 1806 1807 mCSD.push_back(csd); 1808 ++i; 1809 } 1810 1811 ALOGV("Found %zu pieces of codec specific data.", mCSD.size()); 1812} 1813 1814status_t MediaCodec::queueCSDInputBuffer(size_t bufferIndex) { 1815 CHECK(!mCSD.empty()); 1816 1817 const BufferInfo *info = 1818 &mPortBuffers[kPortIndexInput].itemAt(bufferIndex); 1819 1820 sp<ABuffer> csd = *mCSD.begin(); 1821 mCSD.erase(mCSD.begin()); 1822 1823 const sp<ABuffer> &codecInputData = 1824 (mCrypto != NULL) ? info->mEncryptedData : info->mData; 1825 1826 if (csd->size() > codecInputData->capacity()) { 1827 return -EINVAL; 1828 } 1829 1830 memcpy(codecInputData->data(), csd->data(), csd->size()); 1831 1832 AString errorDetailMsg; 1833 1834 sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this); 1835 msg->setSize("index", bufferIndex); 1836 msg->setSize("offset", 0); 1837 msg->setSize("size", csd->size()); 1838 msg->setInt64("timeUs", 0ll); 1839 msg->setInt32("flags", BUFFER_FLAG_CODECCONFIG); 1840 msg->setPointer("errorDetailMsg", &errorDetailMsg); 1841 1842 return onQueueInputBuffer(msg); 1843} 1844 1845void MediaCodec::setState(State newState) { 1846 if (newState == INITIALIZED || newState == UNINITIALIZED) { 1847 delete mSoftRenderer; 1848 mSoftRenderer = NULL; 1849 1850 mCrypto.clear(); 1851 setNativeWindow(NULL); 1852 1853 mInputFormat.clear(); 1854 mOutputFormat.clear(); 1855 mFlags &= ~kFlagOutputFormatChanged; 1856 mFlags &= ~kFlagOutputBuffersChanged; 1857 mFlags &= ~kFlagStickyError; 1858 mFlags &= ~kFlagIsEncoder; 1859 mFlags &= ~kFlagGatherCodecSpecificData; 1860 mFlags &= ~kFlagIsAsync; 1861 mStickyError = OK; 1862 1863 mActivityNotify.clear(); 1864 mCallback.clear(); 1865 } 1866 1867 if (newState == UNINITIALIZED) { 1868 // return any straggling buffers, e.g. if we got here on an error 1869 returnBuffersToCodec(); 1870 1871 // The component is gone, mediaserver's probably back up already 1872 // but should definitely be back up should we try to instantiate 1873 // another component.. and the cycle continues. 1874 mFlags &= ~kFlagSawMediaServerDie; 1875 } 1876 1877 mState = newState; 1878 1879 cancelPendingDequeueOperations(); 1880 1881 updateBatteryStat(); 1882} 1883 1884void MediaCodec::returnBuffersToCodec() { 1885 returnBuffersToCodecOnPort(kPortIndexInput); 1886 returnBuffersToCodecOnPort(kPortIndexOutput); 1887} 1888 1889void MediaCodec::returnBuffersToCodecOnPort(int32_t portIndex) { 1890 CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 1891 Mutex::Autolock al(mBufferLock); 1892 1893 Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 1894 1895 for (size_t i = 0; i < buffers->size(); ++i) { 1896 BufferInfo *info = &buffers->editItemAt(i); 1897 1898 if (info->mNotify != NULL) { 1899 sp<AMessage> msg = info->mNotify; 1900 info->mNotify = NULL; 1901 info->mOwnedByClient = false; 1902 1903 if (portIndex == kPortIndexInput) { 1904 /* no error, just returning buffers */ 1905 msg->setInt32("err", OK); 1906 } 1907 msg->post(); 1908 } 1909 } 1910 1911 mAvailPortBuffers[portIndex].clear(); 1912} 1913 1914size_t MediaCodec::updateBuffers( 1915 int32_t portIndex, const sp<AMessage> &msg) { 1916 CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 1917 1918 uint32_t bufferID; 1919 CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID)); 1920 1921 Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 1922 1923 for (size_t i = 0; i < buffers->size(); ++i) { 1924 BufferInfo *info = &buffers->editItemAt(i); 1925 1926 if (info->mBufferID == bufferID) { 1927 CHECK(info->mNotify == NULL); 1928 CHECK(msg->findMessage("reply", &info->mNotify)); 1929 1930 info->mFormat = 1931 (portIndex == kPortIndexInput) ? mInputFormat : mOutputFormat; 1932 mAvailPortBuffers[portIndex].push_back(i); 1933 1934 return i; 1935 } 1936 } 1937 1938 TRESPASS(); 1939 1940 return 0; 1941} 1942 1943status_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) { 1944 size_t index; 1945 size_t offset; 1946 size_t size; 1947 int64_t timeUs; 1948 uint32_t flags; 1949 CHECK(msg->findSize("index", &index)); 1950 CHECK(msg->findSize("offset", &offset)); 1951 CHECK(msg->findInt64("timeUs", &timeUs)); 1952 CHECK(msg->findInt32("flags", (int32_t *)&flags)); 1953 1954 const CryptoPlugin::SubSample *subSamples; 1955 size_t numSubSamples; 1956 const uint8_t *key; 1957 const uint8_t *iv; 1958 CryptoPlugin::Mode mode = CryptoPlugin::kMode_Unencrypted; 1959 1960 // We allow the simpler queueInputBuffer API to be used even in 1961 // secure mode, by fabricating a single unencrypted subSample. 1962 CryptoPlugin::SubSample ss; 1963 1964 if (msg->findSize("size", &size)) { 1965 if (mCrypto != NULL) { 1966 ss.mNumBytesOfClearData = size; 1967 ss.mNumBytesOfEncryptedData = 0; 1968 1969 subSamples = &ss; 1970 numSubSamples = 1; 1971 key = NULL; 1972 iv = NULL; 1973 } 1974 } else { 1975 if (mCrypto == NULL) { 1976 return -EINVAL; 1977 } 1978 1979 CHECK(msg->findPointer("subSamples", (void **)&subSamples)); 1980 CHECK(msg->findSize("numSubSamples", &numSubSamples)); 1981 CHECK(msg->findPointer("key", (void **)&key)); 1982 CHECK(msg->findPointer("iv", (void **)&iv)); 1983 1984 int32_t tmp; 1985 CHECK(msg->findInt32("mode", &tmp)); 1986 1987 mode = (CryptoPlugin::Mode)tmp; 1988 1989 size = 0; 1990 for (size_t i = 0; i < numSubSamples; ++i) { 1991 size += subSamples[i].mNumBytesOfClearData; 1992 size += subSamples[i].mNumBytesOfEncryptedData; 1993 } 1994 } 1995 1996 if (index >= mPortBuffers[kPortIndexInput].size()) { 1997 return -ERANGE; 1998 } 1999 2000 BufferInfo *info = &mPortBuffers[kPortIndexInput].editItemAt(index); 2001 2002 if (info->mNotify == NULL || !info->mOwnedByClient) { 2003 return -EACCES; 2004 } 2005 2006 if (offset + size > info->mData->capacity()) { 2007 return -EINVAL; 2008 } 2009 2010 sp<AMessage> reply = info->mNotify; 2011 info->mData->setRange(offset, size); 2012 info->mData->meta()->setInt64("timeUs", timeUs); 2013 2014 if (flags & BUFFER_FLAG_EOS) { 2015 info->mData->meta()->setInt32("eos", true); 2016 } 2017 2018 if (flags & BUFFER_FLAG_CODECCONFIG) { 2019 info->mData->meta()->setInt32("csd", true); 2020 } 2021 2022 if (mCrypto != NULL) { 2023 if (size > info->mEncryptedData->capacity()) { 2024 return -ERANGE; 2025 } 2026 2027 AString *errorDetailMsg; 2028 CHECK(msg->findPointer("errorDetailMsg", (void **)&errorDetailMsg)); 2029 2030 ssize_t result = mCrypto->decrypt( 2031 (mFlags & kFlagIsSecure) != 0, 2032 key, 2033 iv, 2034 mode, 2035 info->mSharedEncryptedBuffer, 2036 offset, 2037 subSamples, 2038 numSubSamples, 2039 info->mData->base(), 2040 errorDetailMsg); 2041 2042 if (result < 0) { 2043 return result; 2044 } 2045 2046 info->mData->setRange(0, result); 2047 } 2048 2049 // synchronization boundary for getBufferAndFormat 2050 { 2051 Mutex::Autolock al(mBufferLock); 2052 info->mOwnedByClient = false; 2053 } 2054 reply->setBuffer("buffer", info->mData); 2055 reply->post(); 2056 2057 info->mNotify = NULL; 2058 2059 return OK; 2060} 2061 2062status_t MediaCodec::onReleaseOutputBuffer(const sp<AMessage> &msg) { 2063 size_t index; 2064 CHECK(msg->findSize("index", &index)); 2065 2066 int32_t render; 2067 if (!msg->findInt32("render", &render)) { 2068 render = 0; 2069 } 2070 2071 if (!isExecuting()) { 2072 return -EINVAL; 2073 } 2074 2075 if (index >= mPortBuffers[kPortIndexOutput].size()) { 2076 return -ERANGE; 2077 } 2078 2079 BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index); 2080 2081 if (info->mNotify == NULL || !info->mOwnedByClient) { 2082 return -EACCES; 2083 } 2084 2085 // synchronization boundary for getBufferAndFormat 2086 { 2087 Mutex::Autolock al(mBufferLock); 2088 info->mOwnedByClient = false; 2089 } 2090 2091 if (render && info->mData != NULL && info->mData->size() != 0) { 2092 info->mNotify->setInt32("render", true); 2093 2094 int64_t timestampNs = 0; 2095 if (msg->findInt64("timestampNs", ×tampNs)) { 2096 info->mNotify->setInt64("timestampNs", timestampNs); 2097 } else { 2098 // TODO: it seems like we should use the timestamp 2099 // in the (media)buffer as it potentially came from 2100 // an input surface, but we did not propagate it prior to 2101 // API 20. Perhaps check for target SDK version. 2102#if 0 2103 if (info->mData->meta()->findInt64("timeUs", ×tampNs)) { 2104 ALOGV("using buffer PTS of %" PRId64, timestampNs); 2105 timestampNs *= 1000; 2106 } 2107#endif 2108 } 2109 2110 if (mSoftRenderer != NULL) { 2111 mSoftRenderer->render( 2112 info->mData->data(), info->mData->size(), 2113 timestampNs, NULL, info->mFormat); 2114 } 2115 } 2116 2117 info->mNotify->post(); 2118 info->mNotify = NULL; 2119 2120 return OK; 2121} 2122 2123ssize_t MediaCodec::dequeuePortBuffer(int32_t portIndex) { 2124 CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 2125 2126 List<size_t> *availBuffers = &mAvailPortBuffers[portIndex]; 2127 2128 if (availBuffers->empty()) { 2129 return -EAGAIN; 2130 } 2131 2132 size_t index = *availBuffers->begin(); 2133 availBuffers->erase(availBuffers->begin()); 2134 2135 BufferInfo *info = &mPortBuffers[portIndex].editItemAt(index); 2136 CHECK(!info->mOwnedByClient); 2137 { 2138 Mutex::Autolock al(mBufferLock); 2139 info->mOwnedByClient = true; 2140 2141 // set image-data 2142 if (info->mFormat != NULL) { 2143 sp<ABuffer> imageData; 2144 if (info->mFormat->findBuffer("image-data", &imageData)) { 2145 info->mData->meta()->setBuffer("image-data", imageData); 2146 } 2147 int32_t left, top, right, bottom; 2148 if (info->mFormat->findRect("crop", &left, &top, &right, &bottom)) { 2149 info->mData->meta()->setRect("crop-rect", left, top, right, bottom); 2150 } 2151 } 2152 } 2153 2154 return index; 2155} 2156 2157status_t MediaCodec::setNativeWindow( 2158 const sp<Surface> &surfaceTextureClient) { 2159 status_t err; 2160 2161 if (mNativeWindow != NULL) { 2162 err = native_window_api_disconnect( 2163 mNativeWindow.get(), NATIVE_WINDOW_API_MEDIA); 2164 2165 if (err != OK) { 2166 ALOGW("native_window_api_disconnect returned an error: %s (%d)", 2167 strerror(-err), err); 2168 } 2169 2170 mNativeWindow.clear(); 2171 } 2172 2173 if (surfaceTextureClient != NULL) { 2174 err = native_window_api_connect( 2175 surfaceTextureClient.get(), NATIVE_WINDOW_API_MEDIA); 2176 2177 if (err != OK) { 2178 ALOGE("native_window_api_connect returned an error: %s (%d)", 2179 strerror(-err), err); 2180 2181 return err; 2182 } 2183 2184 mNativeWindow = surfaceTextureClient; 2185 } 2186 2187 return OK; 2188} 2189 2190void MediaCodec::onInputBufferAvailable() { 2191 int32_t index; 2192 while ((index = dequeuePortBuffer(kPortIndexInput)) >= 0) { 2193 sp<AMessage> msg = mCallback->dup(); 2194 msg->setInt32("callbackID", CB_INPUT_AVAILABLE); 2195 msg->setInt32("index", index); 2196 msg->post(); 2197 } 2198} 2199 2200void MediaCodec::onOutputBufferAvailable() { 2201 int32_t index; 2202 while ((index = dequeuePortBuffer(kPortIndexOutput)) >= 0) { 2203 const sp<ABuffer> &buffer = 2204 mPortBuffers[kPortIndexOutput].itemAt(index).mData; 2205 sp<AMessage> msg = mCallback->dup(); 2206 msg->setInt32("callbackID", CB_OUTPUT_AVAILABLE); 2207 msg->setInt32("index", index); 2208 msg->setSize("offset", buffer->offset()); 2209 msg->setSize("size", buffer->size()); 2210 2211 int64_t timeUs; 2212 CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 2213 2214 msg->setInt64("timeUs", timeUs); 2215 2216 int32_t omxFlags; 2217 CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags)); 2218 2219 uint32_t flags = 0; 2220 if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) { 2221 flags |= BUFFER_FLAG_SYNCFRAME; 2222 } 2223 if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) { 2224 flags |= BUFFER_FLAG_CODECCONFIG; 2225 } 2226 if (omxFlags & OMX_BUFFERFLAG_EOS) { 2227 flags |= BUFFER_FLAG_EOS; 2228 } 2229 2230 msg->setInt32("flags", flags); 2231 2232 msg->post(); 2233 } 2234} 2235 2236void MediaCodec::onError(status_t err, int32_t actionCode, const char *detail) { 2237 if (mCallback != NULL) { 2238 sp<AMessage> msg = mCallback->dup(); 2239 msg->setInt32("callbackID", CB_ERROR); 2240 msg->setInt32("err", err); 2241 msg->setInt32("actionCode", actionCode); 2242 2243 if (detail != NULL) { 2244 msg->setString("detail", detail); 2245 } 2246 2247 msg->post(); 2248 } 2249} 2250 2251void MediaCodec::onOutputFormatChanged() { 2252 if (mCallback != NULL) { 2253 sp<AMessage> msg = mCallback->dup(); 2254 msg->setInt32("callbackID", CB_OUTPUT_FORMAT_CHANGED); 2255 msg->setMessage("format", mOutputFormat); 2256 msg->post(); 2257 } 2258} 2259 2260 2261void MediaCodec::postActivityNotificationIfPossible() { 2262 if (mActivityNotify == NULL) { 2263 return; 2264 } 2265 2266 bool isErrorOrOutputChanged = 2267 (mFlags & (kFlagStickyError 2268 | kFlagOutputBuffersChanged 2269 | kFlagOutputFormatChanged)); 2270 2271 if (isErrorOrOutputChanged 2272 || !mAvailPortBuffers[kPortIndexInput].empty() 2273 || !mAvailPortBuffers[kPortIndexOutput].empty()) { 2274 mActivityNotify->setInt32("input-buffers", 2275 mAvailPortBuffers[kPortIndexInput].size()); 2276 2277 if (isErrorOrOutputChanged) { 2278 // we want consumer to dequeue as many times as it can 2279 mActivityNotify->setInt32("output-buffers", INT32_MAX); 2280 } else { 2281 mActivityNotify->setInt32("output-buffers", 2282 mAvailPortBuffers[kPortIndexOutput].size()); 2283 } 2284 mActivityNotify->post(); 2285 mActivityNotify.clear(); 2286 } 2287} 2288 2289status_t MediaCodec::setParameters(const sp<AMessage> ¶ms) { 2290 sp<AMessage> msg = new AMessage(kWhatSetParameters, this); 2291 msg->setMessage("params", params); 2292 2293 sp<AMessage> response; 2294 return PostAndAwaitResponse(msg, &response); 2295} 2296 2297status_t MediaCodec::onSetParameters(const sp<AMessage> ¶ms) { 2298 mCodec->signalSetParameters(params); 2299 2300 return OK; 2301} 2302 2303status_t MediaCodec::amendOutputFormatWithCodecSpecificData( 2304 const sp<ABuffer> &buffer) { 2305 AString mime; 2306 CHECK(mOutputFormat->findString("mime", &mime)); 2307 2308 if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)) { 2309 // Codec specific data should be SPS and PPS in a single buffer, 2310 // each prefixed by a startcode (0x00 0x00 0x00 0x01). 2311 // We separate the two and put them into the output format 2312 // under the keys "csd-0" and "csd-1". 2313 2314 unsigned csdIndex = 0; 2315 2316 const uint8_t *data = buffer->data(); 2317 size_t size = buffer->size(); 2318 2319 const uint8_t *nalStart; 2320 size_t nalSize; 2321 while (getNextNALUnit(&data, &size, &nalStart, &nalSize, true) == OK) { 2322 sp<ABuffer> csd = new ABuffer(nalSize + 4); 2323 memcpy(csd->data(), "\x00\x00\x00\x01", 4); 2324 memcpy(csd->data() + 4, nalStart, nalSize); 2325 2326 mOutputFormat->setBuffer( 2327 AStringPrintf("csd-%u", csdIndex).c_str(), csd); 2328 2329 ++csdIndex; 2330 } 2331 2332 if (csdIndex != 2) { 2333 return ERROR_MALFORMED; 2334 } 2335 } else { 2336 // For everything else we just stash the codec specific data into 2337 // the output format as a single piece of csd under "csd-0". 2338 mOutputFormat->setBuffer("csd-0", buffer); 2339 } 2340 2341 return OK; 2342} 2343 2344void MediaCodec::updateBatteryStat() { 2345 if (mState == CONFIGURED && !mBatteryStatNotified) { 2346 AString mime; 2347 CHECK(mOutputFormat != NULL && 2348 mOutputFormat->findString("mime", &mime)); 2349 2350 mIsVideo = mime.startsWithIgnoreCase("video/"); 2351 2352 BatteryNotifier& notifier(BatteryNotifier::getInstance()); 2353 2354 if (mIsVideo) { 2355 notifier.noteStartVideo(); 2356 } else { 2357 notifier.noteStartAudio(); 2358 } 2359 2360 mBatteryStatNotified = true; 2361 } else if (mState == UNINITIALIZED && mBatteryStatNotified) { 2362 BatteryNotifier& notifier(BatteryNotifier::getInstance()); 2363 2364 if (mIsVideo) { 2365 notifier.noteStopVideo(); 2366 } else { 2367 notifier.noteStopAudio(); 2368 } 2369 2370 mBatteryStatNotified = false; 2371 } 2372} 2373 2374} // namespace android 2375