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