ACodec.cpp revision b6ac8e2ce3574160714fd3c0c6d6b5fbf6c8eeab
1/* 2 * Copyright (C) 2010 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 "ACodec" 19 20#include <media/stagefright/ACodec.h> 21 22#include <binder/MemoryDealer.h> 23 24#include <media/stagefright/foundation/hexdump.h> 25#include <media/stagefright/foundation/ABuffer.h> 26#include <media/stagefright/foundation/ADebug.h> 27#include <media/stagefright/foundation/AMessage.h> 28 29#include <media/stagefright/BufferProducerWrapper.h> 30#include <media/stagefright/MediaCodecList.h> 31#include <media/stagefright/MediaDefs.h> 32#include <media/stagefright/NativeWindowWrapper.h> 33#include <media/stagefright/OMXClient.h> 34#include <media/stagefright/OMXCodec.h> 35 36#include <media/hardware/HardwareAPI.h> 37 38#include <OMX_Component.h> 39 40#include "include/avc_utils.h" 41 42namespace android { 43 44template<class T> 45static void InitOMXParams(T *params) { 46 params->nSize = sizeof(T); 47 params->nVersion.s.nVersionMajor = 1; 48 params->nVersion.s.nVersionMinor = 0; 49 params->nVersion.s.nRevision = 0; 50 params->nVersion.s.nStep = 0; 51} 52 53struct CodecObserver : public BnOMXObserver { 54 CodecObserver() {} 55 56 void setNotificationMessage(const sp<AMessage> &msg) { 57 mNotify = msg; 58 } 59 60 // from IOMXObserver 61 virtual void onMessage(const omx_message &omx_msg) { 62 sp<AMessage> msg = mNotify->dup(); 63 64 msg->setInt32("type", omx_msg.type); 65 msg->setPointer("node", omx_msg.node); 66 67 switch (omx_msg.type) { 68 case omx_message::EVENT: 69 { 70 msg->setInt32("event", omx_msg.u.event_data.event); 71 msg->setInt32("data1", omx_msg.u.event_data.data1); 72 msg->setInt32("data2", omx_msg.u.event_data.data2); 73 break; 74 } 75 76 case omx_message::EMPTY_BUFFER_DONE: 77 { 78 msg->setPointer("buffer", omx_msg.u.buffer_data.buffer); 79 break; 80 } 81 82 case omx_message::FILL_BUFFER_DONE: 83 { 84 msg->setPointer( 85 "buffer", omx_msg.u.extended_buffer_data.buffer); 86 msg->setInt32( 87 "range_offset", 88 omx_msg.u.extended_buffer_data.range_offset); 89 msg->setInt32( 90 "range_length", 91 omx_msg.u.extended_buffer_data.range_length); 92 msg->setInt32( 93 "flags", 94 omx_msg.u.extended_buffer_data.flags); 95 msg->setInt64( 96 "timestamp", 97 omx_msg.u.extended_buffer_data.timestamp); 98 msg->setPointer( 99 "platform_private", 100 omx_msg.u.extended_buffer_data.platform_private); 101 msg->setPointer( 102 "data_ptr", 103 omx_msg.u.extended_buffer_data.data_ptr); 104 break; 105 } 106 107 default: 108 TRESPASS(); 109 break; 110 } 111 112 msg->post(); 113 } 114 115protected: 116 virtual ~CodecObserver() {} 117 118private: 119 sp<AMessage> mNotify; 120 121 DISALLOW_EVIL_CONSTRUCTORS(CodecObserver); 122}; 123 124//////////////////////////////////////////////////////////////////////////////// 125 126struct ACodec::BaseState : public AState { 127 BaseState(ACodec *codec, const sp<AState> &parentState = NULL); 128 129protected: 130 enum PortMode { 131 KEEP_BUFFERS, 132 RESUBMIT_BUFFERS, 133 FREE_BUFFERS, 134 }; 135 136 ACodec *mCodec; 137 138 virtual PortMode getPortMode(OMX_U32 portIndex); 139 140 virtual bool onMessageReceived(const sp<AMessage> &msg); 141 142 virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 143 144 virtual void onOutputBufferDrained(const sp<AMessage> &msg); 145 virtual void onInputBufferFilled(const sp<AMessage> &msg); 146 147 void postFillThisBuffer(BufferInfo *info); 148 149private: 150 bool onOMXMessage(const sp<AMessage> &msg); 151 152 bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID); 153 154 bool onOMXFillBufferDone( 155 IOMX::buffer_id bufferID, 156 size_t rangeOffset, size_t rangeLength, 157 OMX_U32 flags, 158 int64_t timeUs, 159 void *platformPrivate, 160 void *dataPtr); 161 162 void getMoreInputDataIfPossible(); 163 164 DISALLOW_EVIL_CONSTRUCTORS(BaseState); 165}; 166 167//////////////////////////////////////////////////////////////////////////////// 168 169struct ACodec::DeathNotifier : public IBinder::DeathRecipient { 170 DeathNotifier(const sp<AMessage> ¬ify) 171 : mNotify(notify) { 172 } 173 174 virtual void binderDied(const wp<IBinder> &) { 175 mNotify->post(); 176 } 177 178protected: 179 virtual ~DeathNotifier() {} 180 181private: 182 sp<AMessage> mNotify; 183 184 DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier); 185}; 186 187struct ACodec::UninitializedState : public ACodec::BaseState { 188 UninitializedState(ACodec *codec); 189 190protected: 191 virtual bool onMessageReceived(const sp<AMessage> &msg); 192 virtual void stateEntered(); 193 194private: 195 void onSetup(const sp<AMessage> &msg); 196 bool onAllocateComponent(const sp<AMessage> &msg); 197 198 sp<DeathNotifier> mDeathNotifier; 199 200 DISALLOW_EVIL_CONSTRUCTORS(UninitializedState); 201}; 202 203//////////////////////////////////////////////////////////////////////////////// 204 205struct ACodec::LoadedState : public ACodec::BaseState { 206 LoadedState(ACodec *codec); 207 208protected: 209 virtual bool onMessageReceived(const sp<AMessage> &msg); 210 virtual void stateEntered(); 211 212private: 213 friend struct ACodec::UninitializedState; 214 215 bool onConfigureComponent(const sp<AMessage> &msg); 216 void onCreateInputSurface(const sp<AMessage> &msg); 217 void onStart(); 218 void onShutdown(bool keepComponentAllocated); 219 220 DISALLOW_EVIL_CONSTRUCTORS(LoadedState); 221}; 222 223//////////////////////////////////////////////////////////////////////////////// 224 225struct ACodec::LoadedToIdleState : public ACodec::BaseState { 226 LoadedToIdleState(ACodec *codec); 227 228protected: 229 virtual bool onMessageReceived(const sp<AMessage> &msg); 230 virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 231 virtual void stateEntered(); 232 233private: 234 status_t allocateBuffers(); 235 236 DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState); 237}; 238 239//////////////////////////////////////////////////////////////////////////////// 240 241struct ACodec::IdleToExecutingState : public ACodec::BaseState { 242 IdleToExecutingState(ACodec *codec); 243 244protected: 245 virtual bool onMessageReceived(const sp<AMessage> &msg); 246 virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 247 virtual void stateEntered(); 248 249private: 250 DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState); 251}; 252 253//////////////////////////////////////////////////////////////////////////////// 254 255struct ACodec::ExecutingState : public ACodec::BaseState { 256 ExecutingState(ACodec *codec); 257 258 void submitOutputBuffers(); 259 260 // Submit output buffers to the decoder, submit input buffers to client 261 // to fill with data. 262 void resume(); 263 264 // Returns true iff input and output buffers are in play. 265 bool active() const { return mActive; } 266 267protected: 268 virtual PortMode getPortMode(OMX_U32 portIndex); 269 virtual bool onMessageReceived(const sp<AMessage> &msg); 270 virtual void stateEntered(); 271 272 virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 273 274private: 275 bool mActive; 276 277 DISALLOW_EVIL_CONSTRUCTORS(ExecutingState); 278}; 279 280//////////////////////////////////////////////////////////////////////////////// 281 282struct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState { 283 OutputPortSettingsChangedState(ACodec *codec); 284 285protected: 286 virtual PortMode getPortMode(OMX_U32 portIndex); 287 virtual bool onMessageReceived(const sp<AMessage> &msg); 288 virtual void stateEntered(); 289 290 virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 291 292private: 293 DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState); 294}; 295 296//////////////////////////////////////////////////////////////////////////////// 297 298struct ACodec::ExecutingToIdleState : public ACodec::BaseState { 299 ExecutingToIdleState(ACodec *codec); 300 301protected: 302 virtual bool onMessageReceived(const sp<AMessage> &msg); 303 virtual void stateEntered(); 304 305 virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 306 307 virtual void onOutputBufferDrained(const sp<AMessage> &msg); 308 virtual void onInputBufferFilled(const sp<AMessage> &msg); 309 310private: 311 void changeStateIfWeOwnAllBuffers(); 312 313 bool mComponentNowIdle; 314 315 DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState); 316}; 317 318//////////////////////////////////////////////////////////////////////////////// 319 320struct ACodec::IdleToLoadedState : public ACodec::BaseState { 321 IdleToLoadedState(ACodec *codec); 322 323protected: 324 virtual bool onMessageReceived(const sp<AMessage> &msg); 325 virtual void stateEntered(); 326 327 virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 328 329private: 330 DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState); 331}; 332 333//////////////////////////////////////////////////////////////////////////////// 334 335struct ACodec::FlushingState : public ACodec::BaseState { 336 FlushingState(ACodec *codec); 337 338protected: 339 virtual bool onMessageReceived(const sp<AMessage> &msg); 340 virtual void stateEntered(); 341 342 virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); 343 344 virtual void onOutputBufferDrained(const sp<AMessage> &msg); 345 virtual void onInputBufferFilled(const sp<AMessage> &msg); 346 347private: 348 bool mFlushComplete[2]; 349 350 void changeStateIfWeOwnAllBuffers(); 351 352 DISALLOW_EVIL_CONSTRUCTORS(FlushingState); 353}; 354 355//////////////////////////////////////////////////////////////////////////////// 356 357ACodec::ACodec() 358 : mQuirks(0), 359 mNode(NULL), 360 mSentFormat(false), 361 mIsEncoder(false), 362 mShutdownInProgress(false), 363 mEncoderDelay(0), 364 mEncoderPadding(0), 365 mChannelMaskPresent(false), 366 mChannelMask(0) { 367 mUninitializedState = new UninitializedState(this); 368 mLoadedState = new LoadedState(this); 369 mLoadedToIdleState = new LoadedToIdleState(this); 370 mIdleToExecutingState = new IdleToExecutingState(this); 371 mExecutingState = new ExecutingState(this); 372 373 mOutputPortSettingsChangedState = 374 new OutputPortSettingsChangedState(this); 375 376 mExecutingToIdleState = new ExecutingToIdleState(this); 377 mIdleToLoadedState = new IdleToLoadedState(this); 378 mFlushingState = new FlushingState(this); 379 380 mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false; 381 mInputEOSResult = OK; 382 383 changeState(mUninitializedState); 384} 385 386ACodec::~ACodec() { 387} 388 389void ACodec::setNotificationMessage(const sp<AMessage> &msg) { 390 mNotify = msg; 391} 392 393void ACodec::initiateSetup(const sp<AMessage> &msg) { 394 msg->setWhat(kWhatSetup); 395 msg->setTarget(id()); 396 msg->post(); 397} 398 399void ACodec::signalSetParameters(const sp<AMessage> ¶ms) { 400 sp<AMessage> msg = new AMessage(kWhatSetParameters, id()); 401 msg->setMessage("params", params); 402 msg->post(); 403} 404 405void ACodec::initiateAllocateComponent(const sp<AMessage> &msg) { 406 msg->setWhat(kWhatAllocateComponent); 407 msg->setTarget(id()); 408 msg->post(); 409} 410 411void ACodec::initiateConfigureComponent(const sp<AMessage> &msg) { 412 msg->setWhat(kWhatConfigureComponent); 413 msg->setTarget(id()); 414 msg->post(); 415} 416 417void ACodec::initiateCreateInputSurface() { 418 (new AMessage(kWhatCreateInputSurface, id()))->post(); 419} 420 421void ACodec::signalEndOfInputStream() { 422 (new AMessage(kWhatSignalEndOfInputStream, id()))->post(); 423} 424 425void ACodec::initiateStart() { 426 (new AMessage(kWhatStart, id()))->post(); 427} 428 429void ACodec::signalFlush() { 430 ALOGV("[%s] signalFlush", mComponentName.c_str()); 431 (new AMessage(kWhatFlush, id()))->post(); 432} 433 434void ACodec::signalResume() { 435 (new AMessage(kWhatResume, id()))->post(); 436} 437 438void ACodec::initiateShutdown(bool keepComponentAllocated) { 439 sp<AMessage> msg = new AMessage(kWhatShutdown, id()); 440 msg->setInt32("keepComponentAllocated", keepComponentAllocated); 441 msg->post(); 442} 443 444void ACodec::signalRequestIDRFrame() { 445 (new AMessage(kWhatRequestIDRFrame, id()))->post(); 446} 447 448status_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) { 449 CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 450 451 CHECK(mDealer[portIndex] == NULL); 452 CHECK(mBuffers[portIndex].isEmpty()); 453 454 status_t err; 455 if (mNativeWindow != NULL && portIndex == kPortIndexOutput) { 456 err = allocateOutputBuffersFromNativeWindow(); 457 } else { 458 OMX_PARAM_PORTDEFINITIONTYPE def; 459 InitOMXParams(&def); 460 def.nPortIndex = portIndex; 461 462 err = mOMX->getParameter( 463 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 464 465 if (err == OK) { 466 ALOGV("[%s] Allocating %lu buffers of size %lu on %s port", 467 mComponentName.c_str(), 468 def.nBufferCountActual, def.nBufferSize, 469 portIndex == kPortIndexInput ? "input" : "output"); 470 471 size_t totalSize = def.nBufferCountActual * def.nBufferSize; 472 mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec"); 473 474 for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) { 475 sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize); 476 CHECK(mem.get() != NULL); 477 478 BufferInfo info; 479 info.mStatus = BufferInfo::OWNED_BY_US; 480 481 uint32_t requiresAllocateBufferBit = 482 (portIndex == kPortIndexInput) 483 ? OMXCodec::kRequiresAllocateBufferOnInputPorts 484 : OMXCodec::kRequiresAllocateBufferOnOutputPorts; 485 486 if (portIndex == kPortIndexInput && (mFlags & kFlagIsSecure)) { 487 mem.clear(); 488 489 void *ptr; 490 err = mOMX->allocateBuffer( 491 mNode, portIndex, def.nBufferSize, &info.mBufferID, 492 &ptr); 493 494 info.mData = new ABuffer(ptr, def.nBufferSize); 495 } else if (mQuirks & requiresAllocateBufferBit) { 496 err = mOMX->allocateBufferWithBackup( 497 mNode, portIndex, mem, &info.mBufferID); 498 } else { 499 err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID); 500 } 501 502 if (mem != NULL) { 503 info.mData = new ABuffer(mem->pointer(), def.nBufferSize); 504 } 505 506 mBuffers[portIndex].push(info); 507 } 508 } 509 } 510 511 if (err != OK) { 512 return err; 513 } 514 515 sp<AMessage> notify = mNotify->dup(); 516 notify->setInt32("what", ACodec::kWhatBuffersAllocated); 517 518 notify->setInt32("portIndex", portIndex); 519 520 sp<PortDescription> desc = new PortDescription; 521 522 for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) { 523 const BufferInfo &info = mBuffers[portIndex][i]; 524 525 desc->addBuffer(info.mBufferID, info.mData); 526 } 527 528 notify->setObject("portDesc", desc); 529 notify->post(); 530 531 return OK; 532} 533 534status_t ACodec::allocateOutputBuffersFromNativeWindow() { 535 OMX_PARAM_PORTDEFINITIONTYPE def; 536 InitOMXParams(&def); 537 def.nPortIndex = kPortIndexOutput; 538 539 status_t err = mOMX->getParameter( 540 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 541 542 if (err != OK) { 543 return err; 544 } 545 546 err = native_window_set_buffers_geometry( 547 mNativeWindow.get(), 548 def.format.video.nFrameWidth, 549 def.format.video.nFrameHeight, 550 def.format.video.eColorFormat); 551 552 if (err != 0) { 553 ALOGE("native_window_set_buffers_geometry failed: %s (%d)", 554 strerror(-err), -err); 555 return err; 556 } 557 558 // Set up the native window. 559 OMX_U32 usage = 0; 560 err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage); 561 if (err != 0) { 562 ALOGW("querying usage flags from OMX IL component failed: %d", err); 563 // XXX: Currently this error is logged, but not fatal. 564 usage = 0; 565 } 566 567 if (mFlags & kFlagIsSecure) { 568 usage |= GRALLOC_USAGE_PROTECTED; 569 } 570 571 // Make sure to check whether either Stagefright or the video decoder 572 // requested protected buffers. 573 if (usage & GRALLOC_USAGE_PROTECTED) { 574 // Verify that the ANativeWindow sends images directly to 575 // SurfaceFlinger. 576 int queuesToNativeWindow = 0; 577 err = mNativeWindow->query( 578 mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER, 579 &queuesToNativeWindow); 580 if (err != 0) { 581 ALOGE("error authenticating native window: %d", err); 582 return err; 583 } 584 if (queuesToNativeWindow != 1) { 585 ALOGE("native window could not be authenticated"); 586 return PERMISSION_DENIED; 587 } 588 } 589 590 err = native_window_set_usage( 591 mNativeWindow.get(), 592 usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP); 593 594 if (err != 0) { 595 ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err); 596 return err; 597 } 598 599 int minUndequeuedBufs = 0; 600 err = mNativeWindow->query( 601 mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, 602 &minUndequeuedBufs); 603 604 if (err != 0) { 605 ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)", 606 strerror(-err), -err); 607 return err; 608 } 609 610 // XXX: Is this the right logic to use? It's not clear to me what the OMX 611 // buffer counts refer to - how do they account for the renderer holding on 612 // to buffers? 613 if (def.nBufferCountActual < def.nBufferCountMin + minUndequeuedBufs) { 614 OMX_U32 newBufferCount = def.nBufferCountMin + minUndequeuedBufs; 615 def.nBufferCountActual = newBufferCount; 616 err = mOMX->setParameter( 617 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 618 619 if (err != OK) { 620 ALOGE("[%s] setting nBufferCountActual to %lu failed: %d", 621 mComponentName.c_str(), newBufferCount, err); 622 return err; 623 } 624 } 625 626 err = native_window_set_buffer_count( 627 mNativeWindow.get(), def.nBufferCountActual); 628 629 if (err != 0) { 630 ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err), 631 -err); 632 return err; 633 } 634 635 ALOGV("[%s] Allocating %lu buffers from a native window of size %lu on " 636 "output port", 637 mComponentName.c_str(), def.nBufferCountActual, def.nBufferSize); 638 639 // Dequeue buffers and send them to OMX 640 for (OMX_U32 i = 0; i < def.nBufferCountActual; i++) { 641 ANativeWindowBuffer *buf; 642 err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf); 643 if (err != 0) { 644 ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err); 645 break; 646 } 647 648 sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false)); 649 BufferInfo info; 650 info.mStatus = BufferInfo::OWNED_BY_US; 651 info.mData = new ABuffer(NULL /* data */, def.nBufferSize /* capacity */); 652 info.mGraphicBuffer = graphicBuffer; 653 mBuffers[kPortIndexOutput].push(info); 654 655 IOMX::buffer_id bufferId; 656 err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer, 657 &bufferId); 658 if (err != 0) { 659 ALOGE("registering GraphicBuffer %lu with OMX IL component failed: " 660 "%d", i, err); 661 break; 662 } 663 664 mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId; 665 666 ALOGV("[%s] Registered graphic buffer with ID %p (pointer = %p)", 667 mComponentName.c_str(), 668 bufferId, graphicBuffer.get()); 669 } 670 671 OMX_U32 cancelStart; 672 OMX_U32 cancelEnd; 673 674 if (err != 0) { 675 // If an error occurred while dequeuing we need to cancel any buffers 676 // that were dequeued. 677 cancelStart = 0; 678 cancelEnd = mBuffers[kPortIndexOutput].size(); 679 } else { 680 // Return the last two buffers to the native window. 681 cancelStart = def.nBufferCountActual - minUndequeuedBufs; 682 cancelEnd = def.nBufferCountActual; 683 } 684 685 for (OMX_U32 i = cancelStart; i < cancelEnd; i++) { 686 BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i); 687 cancelBufferToNativeWindow(info); 688 } 689 690 return err; 691} 692 693status_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) { 694 CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US); 695 696 ALOGV("[%s] Calling cancelBuffer on buffer %p", 697 mComponentName.c_str(), info->mBufferID); 698 699 int err = mNativeWindow->cancelBuffer( 700 mNativeWindow.get(), info->mGraphicBuffer.get(), -1); 701 702 CHECK_EQ(err, 0); 703 704 info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW; 705 706 return OK; 707} 708 709ACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() { 710 ANativeWindowBuffer *buf; 711 int fenceFd = -1; 712 if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) { 713 ALOGE("dequeueBuffer failed."); 714 return NULL; 715 } 716 717 for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) { 718 BufferInfo *info = 719 &mBuffers[kPortIndexOutput].editItemAt(i); 720 721 if (info->mGraphicBuffer->handle == buf->handle) { 722 CHECK_EQ((int)info->mStatus, 723 (int)BufferInfo::OWNED_BY_NATIVE_WINDOW); 724 725 info->mStatus = BufferInfo::OWNED_BY_US; 726 727 return info; 728 } 729 } 730 731 TRESPASS(); 732 733 return NULL; 734} 735 736status_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) { 737 for (size_t i = mBuffers[portIndex].size(); i-- > 0;) { 738 CHECK_EQ((status_t)OK, freeBuffer(portIndex, i)); 739 } 740 741 mDealer[portIndex].clear(); 742 743 return OK; 744} 745 746status_t ACodec::freeOutputBuffersNotOwnedByComponent() { 747 for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) { 748 BufferInfo *info = 749 &mBuffers[kPortIndexOutput].editItemAt(i); 750 751 if (info->mStatus != 752 BufferInfo::OWNED_BY_COMPONENT) { 753 // We shouldn't have sent out any buffers to the client at this 754 // point. 755 CHECK_NE((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM); 756 757 CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i)); 758 } 759 } 760 761 return OK; 762} 763 764status_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) { 765 BufferInfo *info = &mBuffers[portIndex].editItemAt(i); 766 767 CHECK(info->mStatus == BufferInfo::OWNED_BY_US 768 || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW); 769 770 if (portIndex == kPortIndexOutput && mNativeWindow != NULL 771 && info->mStatus == BufferInfo::OWNED_BY_US) { 772 CHECK_EQ((status_t)OK, cancelBufferToNativeWindow(info)); 773 } 774 775 CHECK_EQ(mOMX->freeBuffer( 776 mNode, portIndex, info->mBufferID), 777 (status_t)OK); 778 779 mBuffers[portIndex].removeAt(i); 780 781 return OK; 782} 783 784ACodec::BufferInfo *ACodec::findBufferByID( 785 uint32_t portIndex, IOMX::buffer_id bufferID, 786 ssize_t *index) { 787 for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) { 788 BufferInfo *info = &mBuffers[portIndex].editItemAt(i); 789 790 if (info->mBufferID == bufferID) { 791 if (index != NULL) { 792 *index = i; 793 } 794 return info; 795 } 796 } 797 798 TRESPASS(); 799 800 return NULL; 801} 802 803status_t ACodec::setComponentRole( 804 bool isEncoder, const char *mime) { 805 struct MimeToRole { 806 const char *mime; 807 const char *decoderRole; 808 const char *encoderRole; 809 }; 810 811 static const MimeToRole kMimeToRole[] = { 812 { MEDIA_MIMETYPE_AUDIO_MPEG, 813 "audio_decoder.mp3", "audio_encoder.mp3" }, 814 { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I, 815 "audio_decoder.mp1", "audio_encoder.mp1" }, 816 { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II, 817 "audio_decoder.mp2", "audio_encoder.mp2" }, 818 { MEDIA_MIMETYPE_AUDIO_AMR_NB, 819 "audio_decoder.amrnb", "audio_encoder.amrnb" }, 820 { MEDIA_MIMETYPE_AUDIO_AMR_WB, 821 "audio_decoder.amrwb", "audio_encoder.amrwb" }, 822 { MEDIA_MIMETYPE_AUDIO_AAC, 823 "audio_decoder.aac", "audio_encoder.aac" }, 824 { MEDIA_MIMETYPE_AUDIO_VORBIS, 825 "audio_decoder.vorbis", "audio_encoder.vorbis" }, 826 { MEDIA_MIMETYPE_AUDIO_G711_MLAW, 827 "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" }, 828 { MEDIA_MIMETYPE_AUDIO_G711_ALAW, 829 "audio_decoder.g711alaw", "audio_encoder.g711alaw" }, 830 { MEDIA_MIMETYPE_VIDEO_AVC, 831 "video_decoder.avc", "video_encoder.avc" }, 832 { MEDIA_MIMETYPE_VIDEO_MPEG4, 833 "video_decoder.mpeg4", "video_encoder.mpeg4" }, 834 { MEDIA_MIMETYPE_VIDEO_H263, 835 "video_decoder.h263", "video_encoder.h263" }, 836 { MEDIA_MIMETYPE_VIDEO_VPX, 837 "video_decoder.vpx", "video_encoder.vpx" }, 838 { MEDIA_MIMETYPE_AUDIO_RAW, 839 "audio_decoder.raw", "audio_encoder.raw" }, 840 { MEDIA_MIMETYPE_AUDIO_FLAC, 841 "audio_decoder.flac", "audio_encoder.flac" }, 842 { MEDIA_MIMETYPE_AUDIO_MSGSM, 843 "audio_decoder.gsm", "audio_encoder.gsm" }, 844 }; 845 846 static const size_t kNumMimeToRole = 847 sizeof(kMimeToRole) / sizeof(kMimeToRole[0]); 848 849 size_t i; 850 for (i = 0; i < kNumMimeToRole; ++i) { 851 if (!strcasecmp(mime, kMimeToRole[i].mime)) { 852 break; 853 } 854 } 855 856 if (i == kNumMimeToRole) { 857 return ERROR_UNSUPPORTED; 858 } 859 860 const char *role = 861 isEncoder ? kMimeToRole[i].encoderRole 862 : kMimeToRole[i].decoderRole; 863 864 if (role != NULL) { 865 OMX_PARAM_COMPONENTROLETYPE roleParams; 866 InitOMXParams(&roleParams); 867 868 strncpy((char *)roleParams.cRole, 869 role, OMX_MAX_STRINGNAME_SIZE - 1); 870 871 roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0'; 872 873 status_t err = mOMX->setParameter( 874 mNode, OMX_IndexParamStandardComponentRole, 875 &roleParams, sizeof(roleParams)); 876 877 if (err != OK) { 878 ALOGW("[%s] Failed to set standard component role '%s'.", 879 mComponentName.c_str(), role); 880 881 return err; 882 } 883 } 884 885 return OK; 886} 887 888status_t ACodec::configureCodec( 889 const char *mime, const sp<AMessage> &msg) { 890 int32_t encoder; 891 if (!msg->findInt32("encoder", &encoder)) { 892 encoder = false; 893 } 894 895 mIsEncoder = encoder; 896 897 status_t err = setComponentRole(encoder /* isEncoder */, mime); 898 899 if (err != OK) { 900 return err; 901 } 902 903 int32_t bitRate = 0; 904 // FLAC encoder doesn't need a bitrate, other encoders do 905 if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC) 906 && !msg->findInt32("bitrate", &bitRate)) { 907 return INVALID_OPERATION; 908 } 909 910 int32_t storeMeta; 911 if (encoder 912 && msg->findInt32("store-metadata-in-buffers", &storeMeta) 913 && storeMeta != 0) { 914 err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE); 915 916 if (err != OK) { 917 ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d", 918 mComponentName.c_str(), err); 919 920 return err; 921 } 922 } 923 924 int32_t prependSPSPPS; 925 if (encoder 926 && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS) 927 && prependSPSPPS != 0) { 928 OMX_INDEXTYPE index; 929 err = mOMX->getExtensionIndex( 930 mNode, 931 "OMX.google.android.index.prependSPSPPSToIDRFrames", 932 &index); 933 934 if (err == OK) { 935 PrependSPSPPSToIDRFramesParams params; 936 InitOMXParams(¶ms); 937 params.bEnable = OMX_TRUE; 938 939 err = mOMX->setParameter( 940 mNode, index, ¶ms, sizeof(params)); 941 } 942 943 if (err != OK) { 944 ALOGE("Encoder could not be configured to emit SPS/PPS before " 945 "IDR frames. (err %d)", err); 946 947 return err; 948 } 949 } 950 951 if (!strncasecmp(mime, "video/", 6)) { 952 if (encoder) { 953 err = setupVideoEncoder(mime, msg); 954 } else { 955 int32_t width, height; 956 if (!msg->findInt32("width", &width) 957 || !msg->findInt32("height", &height)) { 958 err = INVALID_OPERATION; 959 } else { 960 err = setupVideoDecoder(mime, width, height); 961 } 962 } 963 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) { 964 int32_t numChannels, sampleRate; 965 if (!msg->findInt32("channel-count", &numChannels) 966 || !msg->findInt32("sample-rate", &sampleRate)) { 967 // Since we did not always check for these, leave them optional 968 // and have the decoder figure it all out. 969 err = OK; 970 } else { 971 err = setupRawAudioFormat( 972 encoder ? kPortIndexInput : kPortIndexOutput, 973 sampleRate, 974 numChannels); 975 } 976 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) { 977 int32_t numChannels, sampleRate; 978 if (!msg->findInt32("channel-count", &numChannels) 979 || !msg->findInt32("sample-rate", &sampleRate)) { 980 err = INVALID_OPERATION; 981 } else { 982 int32_t isADTS, aacProfile; 983 if (!msg->findInt32("is-adts", &isADTS)) { 984 isADTS = 0; 985 } 986 if (!msg->findInt32("aac-profile", &aacProfile)) { 987 aacProfile = OMX_AUDIO_AACObjectNull; 988 } 989 990 err = setupAACCodec( 991 encoder, numChannels, sampleRate, bitRate, aacProfile, 992 isADTS != 0); 993 } 994 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) { 995 err = setupAMRCodec(encoder, false /* isWAMR */, bitRate); 996 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) { 997 err = setupAMRCodec(encoder, true /* isWAMR */, bitRate); 998 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW) 999 || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) { 1000 // These are PCM-like formats with a fixed sample rate but 1001 // a variable number of channels. 1002 1003 int32_t numChannels; 1004 if (!msg->findInt32("channel-count", &numChannels)) { 1005 err = INVALID_OPERATION; 1006 } else { 1007 err = setupG711Codec(encoder, numChannels); 1008 } 1009 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) { 1010 int32_t numChannels, sampleRate, compressionLevel = -1; 1011 if (encoder && 1012 (!msg->findInt32("channel-count", &numChannels) 1013 || !msg->findInt32("sample-rate", &sampleRate))) { 1014 ALOGE("missing channel count or sample rate for FLAC encoder"); 1015 err = INVALID_OPERATION; 1016 } else { 1017 if (encoder) { 1018 if (!msg->findInt32( 1019 "flac-compression-level", &compressionLevel)) { 1020 compressionLevel = 5;// default FLAC compression level 1021 } else if (compressionLevel < 0) { 1022 ALOGW("compression level %d outside [0..8] range, " 1023 "using 0", 1024 compressionLevel); 1025 compressionLevel = 0; 1026 } else if (compressionLevel > 8) { 1027 ALOGW("compression level %d outside [0..8] range, " 1028 "using 8", 1029 compressionLevel); 1030 compressionLevel = 8; 1031 } 1032 } 1033 err = setupFlacCodec( 1034 encoder, numChannels, sampleRate, compressionLevel); 1035 } 1036 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) { 1037 int32_t numChannels, sampleRate; 1038 if (encoder 1039 || !msg->findInt32("channel-count", &numChannels) 1040 || !msg->findInt32("sample-rate", &sampleRate)) { 1041 err = INVALID_OPERATION; 1042 } else { 1043 err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels); 1044 } 1045 } 1046 1047 if (err != OK) { 1048 return err; 1049 } 1050 1051 if (!msg->findInt32("encoder-delay", &mEncoderDelay)) { 1052 mEncoderDelay = 0; 1053 } 1054 1055 if (!msg->findInt32("encoder-padding", &mEncoderPadding)) { 1056 mEncoderPadding = 0; 1057 } 1058 1059 if (msg->findInt32("channel-mask", &mChannelMask)) { 1060 mChannelMaskPresent = true; 1061 } else { 1062 mChannelMaskPresent = false; 1063 } 1064 1065 int32_t maxInputSize; 1066 if (msg->findInt32("max-input-size", &maxInputSize)) { 1067 err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize); 1068 } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) { 1069 err = setMinBufferSize(kPortIndexInput, 8192); // XXX 1070 } 1071 1072 return err; 1073} 1074 1075status_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) { 1076 OMX_PARAM_PORTDEFINITIONTYPE def; 1077 InitOMXParams(&def); 1078 def.nPortIndex = portIndex; 1079 1080 status_t err = mOMX->getParameter( 1081 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1082 1083 if (err != OK) { 1084 return err; 1085 } 1086 1087 if (def.nBufferSize >= size) { 1088 return OK; 1089 } 1090 1091 def.nBufferSize = size; 1092 1093 err = mOMX->setParameter( 1094 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1095 1096 if (err != OK) { 1097 return err; 1098 } 1099 1100 err = mOMX->getParameter( 1101 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1102 1103 if (err != OK) { 1104 return err; 1105 } 1106 1107 CHECK(def.nBufferSize >= size); 1108 1109 return OK; 1110} 1111 1112status_t ACodec::selectAudioPortFormat( 1113 OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) { 1114 OMX_AUDIO_PARAM_PORTFORMATTYPE format; 1115 InitOMXParams(&format); 1116 1117 format.nPortIndex = portIndex; 1118 for (OMX_U32 index = 0;; ++index) { 1119 format.nIndex = index; 1120 1121 status_t err = mOMX->getParameter( 1122 mNode, OMX_IndexParamAudioPortFormat, 1123 &format, sizeof(format)); 1124 1125 if (err != OK) { 1126 return err; 1127 } 1128 1129 if (format.eEncoding == desiredFormat) { 1130 break; 1131 } 1132 } 1133 1134 return mOMX->setParameter( 1135 mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format)); 1136} 1137 1138status_t ACodec::setupAACCodec( 1139 bool encoder, int32_t numChannels, int32_t sampleRate, 1140 int32_t bitRate, int32_t aacProfile, bool isADTS) { 1141 if (encoder && isADTS) { 1142 return -EINVAL; 1143 } 1144 1145 status_t err = setupRawAudioFormat( 1146 encoder ? kPortIndexInput : kPortIndexOutput, 1147 sampleRate, 1148 numChannels); 1149 1150 if (err != OK) { 1151 return err; 1152 } 1153 1154 if (encoder) { 1155 err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC); 1156 1157 if (err != OK) { 1158 return err; 1159 } 1160 1161 OMX_PARAM_PORTDEFINITIONTYPE def; 1162 InitOMXParams(&def); 1163 def.nPortIndex = kPortIndexOutput; 1164 1165 err = mOMX->getParameter( 1166 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1167 1168 if (err != OK) { 1169 return err; 1170 } 1171 1172 def.format.audio.bFlagErrorConcealment = OMX_TRUE; 1173 def.format.audio.eEncoding = OMX_AUDIO_CodingAAC; 1174 1175 err = mOMX->setParameter( 1176 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1177 1178 if (err != OK) { 1179 return err; 1180 } 1181 1182 OMX_AUDIO_PARAM_AACPROFILETYPE profile; 1183 InitOMXParams(&profile); 1184 profile.nPortIndex = kPortIndexOutput; 1185 1186 err = mOMX->getParameter( 1187 mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile)); 1188 1189 if (err != OK) { 1190 return err; 1191 } 1192 1193 profile.nChannels = numChannels; 1194 1195 profile.eChannelMode = 1196 (numChannels == 1) 1197 ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo; 1198 1199 profile.nSampleRate = sampleRate; 1200 profile.nBitRate = bitRate; 1201 profile.nAudioBandWidth = 0; 1202 profile.nFrameLength = 0; 1203 profile.nAACtools = OMX_AUDIO_AACToolAll; 1204 profile.nAACERtools = OMX_AUDIO_AACERNone; 1205 profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile; 1206 profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF; 1207 1208 err = mOMX->setParameter( 1209 mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile)); 1210 1211 if (err != OK) { 1212 return err; 1213 } 1214 1215 return err; 1216 } 1217 1218 OMX_AUDIO_PARAM_AACPROFILETYPE profile; 1219 InitOMXParams(&profile); 1220 profile.nPortIndex = kPortIndexInput; 1221 1222 err = mOMX->getParameter( 1223 mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile)); 1224 1225 if (err != OK) { 1226 return err; 1227 } 1228 1229 profile.nChannels = numChannels; 1230 profile.nSampleRate = sampleRate; 1231 1232 profile.eAACStreamFormat = 1233 isADTS 1234 ? OMX_AUDIO_AACStreamFormatMP4ADTS 1235 : OMX_AUDIO_AACStreamFormatMP4FF; 1236 1237 return mOMX->setParameter( 1238 mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile)); 1239} 1240 1241static OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate( 1242 bool isAMRWB, int32_t bps) { 1243 if (isAMRWB) { 1244 if (bps <= 6600) { 1245 return OMX_AUDIO_AMRBandModeWB0; 1246 } else if (bps <= 8850) { 1247 return OMX_AUDIO_AMRBandModeWB1; 1248 } else if (bps <= 12650) { 1249 return OMX_AUDIO_AMRBandModeWB2; 1250 } else if (bps <= 14250) { 1251 return OMX_AUDIO_AMRBandModeWB3; 1252 } else if (bps <= 15850) { 1253 return OMX_AUDIO_AMRBandModeWB4; 1254 } else if (bps <= 18250) { 1255 return OMX_AUDIO_AMRBandModeWB5; 1256 } else if (bps <= 19850) { 1257 return OMX_AUDIO_AMRBandModeWB6; 1258 } else if (bps <= 23050) { 1259 return OMX_AUDIO_AMRBandModeWB7; 1260 } 1261 1262 // 23850 bps 1263 return OMX_AUDIO_AMRBandModeWB8; 1264 } else { // AMRNB 1265 if (bps <= 4750) { 1266 return OMX_AUDIO_AMRBandModeNB0; 1267 } else if (bps <= 5150) { 1268 return OMX_AUDIO_AMRBandModeNB1; 1269 } else if (bps <= 5900) { 1270 return OMX_AUDIO_AMRBandModeNB2; 1271 } else if (bps <= 6700) { 1272 return OMX_AUDIO_AMRBandModeNB3; 1273 } else if (bps <= 7400) { 1274 return OMX_AUDIO_AMRBandModeNB4; 1275 } else if (bps <= 7950) { 1276 return OMX_AUDIO_AMRBandModeNB5; 1277 } else if (bps <= 10200) { 1278 return OMX_AUDIO_AMRBandModeNB6; 1279 } 1280 1281 // 12200 bps 1282 return OMX_AUDIO_AMRBandModeNB7; 1283 } 1284} 1285 1286status_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) { 1287 OMX_AUDIO_PARAM_AMRTYPE def; 1288 InitOMXParams(&def); 1289 def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput; 1290 1291 status_t err = 1292 mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def)); 1293 1294 if (err != OK) { 1295 return err; 1296 } 1297 1298 def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF; 1299 def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate); 1300 1301 err = mOMX->setParameter( 1302 mNode, OMX_IndexParamAudioAmr, &def, sizeof(def)); 1303 1304 if (err != OK) { 1305 return err; 1306 } 1307 1308 return setupRawAudioFormat( 1309 encoder ? kPortIndexInput : kPortIndexOutput, 1310 isWAMR ? 16000 : 8000 /* sampleRate */, 1311 1 /* numChannels */); 1312} 1313 1314status_t ACodec::setupG711Codec(bool encoder, int32_t numChannels) { 1315 CHECK(!encoder); // XXX TODO 1316 1317 return setupRawAudioFormat( 1318 kPortIndexInput, 8000 /* sampleRate */, numChannels); 1319} 1320 1321status_t ACodec::setupFlacCodec( 1322 bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) { 1323 1324 if (encoder) { 1325 OMX_AUDIO_PARAM_FLACTYPE def; 1326 InitOMXParams(&def); 1327 def.nPortIndex = kPortIndexOutput; 1328 1329 // configure compression level 1330 status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def)); 1331 if (err != OK) { 1332 ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err); 1333 return err; 1334 } 1335 def.nCompressionLevel = compressionLevel; 1336 err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def)); 1337 if (err != OK) { 1338 ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err); 1339 return err; 1340 } 1341 } 1342 1343 return setupRawAudioFormat( 1344 encoder ? kPortIndexInput : kPortIndexOutput, 1345 sampleRate, 1346 numChannels); 1347} 1348 1349status_t ACodec::setupRawAudioFormat( 1350 OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) { 1351 OMX_PARAM_PORTDEFINITIONTYPE def; 1352 InitOMXParams(&def); 1353 def.nPortIndex = portIndex; 1354 1355 status_t err = mOMX->getParameter( 1356 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1357 1358 if (err != OK) { 1359 return err; 1360 } 1361 1362 def.format.audio.eEncoding = OMX_AUDIO_CodingPCM; 1363 1364 err = mOMX->setParameter( 1365 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1366 1367 if (err != OK) { 1368 return err; 1369 } 1370 1371 OMX_AUDIO_PARAM_PCMMODETYPE pcmParams; 1372 InitOMXParams(&pcmParams); 1373 pcmParams.nPortIndex = portIndex; 1374 1375 err = mOMX->getParameter( 1376 mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams)); 1377 1378 if (err != OK) { 1379 return err; 1380 } 1381 1382 pcmParams.nChannels = numChannels; 1383 pcmParams.eNumData = OMX_NumericalDataSigned; 1384 pcmParams.bInterleaved = OMX_TRUE; 1385 pcmParams.nBitPerSample = 16; 1386 pcmParams.nSamplingRate = sampleRate; 1387 pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear; 1388 1389 if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) { 1390 return OMX_ErrorNone; 1391 } 1392 1393 return mOMX->setParameter( 1394 mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams)); 1395} 1396 1397status_t ACodec::setVideoPortFormatType( 1398 OMX_U32 portIndex, 1399 OMX_VIDEO_CODINGTYPE compressionFormat, 1400 OMX_COLOR_FORMATTYPE colorFormat) { 1401 OMX_VIDEO_PARAM_PORTFORMATTYPE format; 1402 InitOMXParams(&format); 1403 format.nPortIndex = portIndex; 1404 format.nIndex = 0; 1405 bool found = false; 1406 1407 OMX_U32 index = 0; 1408 for (;;) { 1409 format.nIndex = index; 1410 status_t err = mOMX->getParameter( 1411 mNode, OMX_IndexParamVideoPortFormat, 1412 &format, sizeof(format)); 1413 1414 if (err != OK) { 1415 return err; 1416 } 1417 1418 // The following assertion is violated by TI's video decoder. 1419 // CHECK_EQ(format.nIndex, index); 1420 1421 if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) { 1422 if (portIndex == kPortIndexInput 1423 && colorFormat == format.eColorFormat) { 1424 // eCompressionFormat does not seem right. 1425 found = true; 1426 break; 1427 } 1428 if (portIndex == kPortIndexOutput 1429 && compressionFormat == format.eCompressionFormat) { 1430 // eColorFormat does not seem right. 1431 found = true; 1432 break; 1433 } 1434 } 1435 1436 if (format.eCompressionFormat == compressionFormat 1437 && format.eColorFormat == colorFormat) { 1438 found = true; 1439 break; 1440 } 1441 1442 ++index; 1443 } 1444 1445 if (!found) { 1446 return UNKNOWN_ERROR; 1447 } 1448 1449 status_t err = mOMX->setParameter( 1450 mNode, OMX_IndexParamVideoPortFormat, 1451 &format, sizeof(format)); 1452 1453 return err; 1454} 1455 1456status_t ACodec::setSupportedOutputFormat() { 1457 OMX_VIDEO_PARAM_PORTFORMATTYPE format; 1458 InitOMXParams(&format); 1459 format.nPortIndex = kPortIndexOutput; 1460 format.nIndex = 0; 1461 1462 status_t err = mOMX->getParameter( 1463 mNode, OMX_IndexParamVideoPortFormat, 1464 &format, sizeof(format)); 1465 CHECK_EQ(err, (status_t)OK); 1466 CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused); 1467 1468 return mOMX->setParameter( 1469 mNode, OMX_IndexParamVideoPortFormat, 1470 &format, sizeof(format)); 1471} 1472 1473static const struct VideoCodingMapEntry { 1474 const char *mMime; 1475 OMX_VIDEO_CODINGTYPE mVideoCodingType; 1476} kVideoCodingMapEntry[] = { 1477 { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC }, 1478 { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 }, 1479 { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 }, 1480 { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 }, 1481 { MEDIA_MIMETYPE_VIDEO_VPX, OMX_VIDEO_CodingVPX }, 1482}; 1483 1484static status_t GetVideoCodingTypeFromMime( 1485 const char *mime, OMX_VIDEO_CODINGTYPE *codingType) { 1486 for (size_t i = 0; 1487 i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]); 1488 ++i) { 1489 if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) { 1490 *codingType = kVideoCodingMapEntry[i].mVideoCodingType; 1491 return OK; 1492 } 1493 } 1494 1495 *codingType = OMX_VIDEO_CodingUnused; 1496 1497 return ERROR_UNSUPPORTED; 1498} 1499 1500static status_t GetMimeTypeForVideoCoding( 1501 OMX_VIDEO_CODINGTYPE codingType, AString *mime) { 1502 for (size_t i = 0; 1503 i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]); 1504 ++i) { 1505 if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) { 1506 *mime = kVideoCodingMapEntry[i].mMime; 1507 return OK; 1508 } 1509 } 1510 1511 mime->clear(); 1512 1513 return ERROR_UNSUPPORTED; 1514} 1515 1516status_t ACodec::setupVideoDecoder( 1517 const char *mime, int32_t width, int32_t height) { 1518 OMX_VIDEO_CODINGTYPE compressionFormat; 1519 status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat); 1520 1521 if (err != OK) { 1522 return err; 1523 } 1524 1525 err = setVideoPortFormatType( 1526 kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused); 1527 1528 if (err != OK) { 1529 return err; 1530 } 1531 1532 err = setSupportedOutputFormat(); 1533 1534 if (err != OK) { 1535 return err; 1536 } 1537 1538 err = setVideoFormatOnPort( 1539 kPortIndexInput, width, height, compressionFormat); 1540 1541 if (err != OK) { 1542 return err; 1543 } 1544 1545 err = setVideoFormatOnPort( 1546 kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused); 1547 1548 if (err != OK) { 1549 return err; 1550 } 1551 1552 return OK; 1553} 1554 1555status_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) { 1556 int32_t tmp; 1557 if (!msg->findInt32("color-format", &tmp)) { 1558 return INVALID_OPERATION; 1559 } 1560 1561 OMX_COLOR_FORMATTYPE colorFormat = 1562 static_cast<OMX_COLOR_FORMATTYPE>(tmp); 1563 1564 status_t err = setVideoPortFormatType( 1565 kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat); 1566 1567 if (err != OK) { 1568 ALOGE("[%s] does not support color format %d", 1569 mComponentName.c_str(), colorFormat); 1570 1571 return err; 1572 } 1573 1574 /* Input port configuration */ 1575 1576 OMX_PARAM_PORTDEFINITIONTYPE def; 1577 InitOMXParams(&def); 1578 1579 OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video; 1580 1581 def.nPortIndex = kPortIndexInput; 1582 1583 err = mOMX->getParameter( 1584 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1585 1586 if (err != OK) { 1587 return err; 1588 } 1589 1590 int32_t width, height, bitrate; 1591 if (!msg->findInt32("width", &width) 1592 || !msg->findInt32("height", &height) 1593 || !msg->findInt32("bitrate", &bitrate)) { 1594 return INVALID_OPERATION; 1595 } 1596 1597 video_def->nFrameWidth = width; 1598 video_def->nFrameHeight = height; 1599 1600 int32_t stride; 1601 if (!msg->findInt32("stride", &stride)) { 1602 stride = width; 1603 } 1604 1605 video_def->nStride = stride; 1606 1607 int32_t sliceHeight; 1608 if (!msg->findInt32("slice-height", &sliceHeight)) { 1609 sliceHeight = height; 1610 } 1611 1612 video_def->nSliceHeight = sliceHeight; 1613 1614 def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2; 1615 1616 float frameRate; 1617 if (!msg->findFloat("frame-rate", &frameRate)) { 1618 int32_t tmp; 1619 if (!msg->findInt32("frame-rate", &tmp)) { 1620 return INVALID_OPERATION; 1621 } 1622 frameRate = (float)tmp; 1623 } 1624 1625 video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f); 1626 video_def->eCompressionFormat = OMX_VIDEO_CodingUnused; 1627 video_def->eColorFormat = colorFormat; 1628 1629 err = mOMX->setParameter( 1630 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1631 1632 if (err != OK) { 1633 ALOGE("[%s] failed to set input port definition parameters.", 1634 mComponentName.c_str()); 1635 1636 return err; 1637 } 1638 1639 /* Output port configuration */ 1640 1641 OMX_VIDEO_CODINGTYPE compressionFormat; 1642 err = GetVideoCodingTypeFromMime(mime, &compressionFormat); 1643 1644 if (err != OK) { 1645 return err; 1646 } 1647 1648 err = setVideoPortFormatType( 1649 kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused); 1650 1651 if (err != OK) { 1652 ALOGE("[%s] does not support compression format %d", 1653 mComponentName.c_str(), compressionFormat); 1654 1655 return err; 1656 } 1657 1658 def.nPortIndex = kPortIndexOutput; 1659 1660 err = mOMX->getParameter( 1661 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1662 1663 if (err != OK) { 1664 return err; 1665 } 1666 1667 video_def->nFrameWidth = width; 1668 video_def->nFrameHeight = height; 1669 video_def->xFramerate = 0; 1670 video_def->nBitrate = bitrate; 1671 video_def->eCompressionFormat = compressionFormat; 1672 video_def->eColorFormat = OMX_COLOR_FormatUnused; 1673 1674 err = mOMX->setParameter( 1675 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 1676 1677 if (err != OK) { 1678 ALOGE("[%s] failed to set output port definition parameters.", 1679 mComponentName.c_str()); 1680 1681 return err; 1682 } 1683 1684 switch (compressionFormat) { 1685 case OMX_VIDEO_CodingMPEG4: 1686 err = setupMPEG4EncoderParameters(msg); 1687 break; 1688 1689 case OMX_VIDEO_CodingH263: 1690 err = setupH263EncoderParameters(msg); 1691 break; 1692 1693 case OMX_VIDEO_CodingAVC: 1694 err = setupAVCEncoderParameters(msg); 1695 break; 1696 1697 default: 1698 break; 1699 } 1700 1701 ALOGI("setupVideoEncoder succeeded"); 1702 1703 return err; 1704} 1705 1706status_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) { 1707 OMX_VIDEO_PARAM_INTRAREFRESHTYPE params; 1708 InitOMXParams(¶ms); 1709 params.nPortIndex = kPortIndexOutput; 1710 1711 params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode); 1712 1713 if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic || 1714 params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) { 1715 int32_t mbs; 1716 if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) { 1717 return INVALID_OPERATION; 1718 } 1719 params.nCirMBs = mbs; 1720 } 1721 1722 if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive || 1723 params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) { 1724 int32_t mbs; 1725 if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) { 1726 return INVALID_OPERATION; 1727 } 1728 params.nAirMBs = mbs; 1729 1730 int32_t ref; 1731 if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) { 1732 return INVALID_OPERATION; 1733 } 1734 params.nAirRef = ref; 1735 } 1736 1737 status_t err = mOMX->setParameter( 1738 mNode, OMX_IndexParamVideoIntraRefresh, 1739 ¶ms, sizeof(params)); 1740 return err; 1741} 1742 1743static OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) { 1744 if (iFramesInterval < 0) { 1745 return 0xFFFFFFFF; 1746 } else if (iFramesInterval == 0) { 1747 return 0; 1748 } 1749 OMX_U32 ret = frameRate * iFramesInterval; 1750 CHECK(ret > 1); 1751 return ret; 1752} 1753 1754static OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) { 1755 int32_t tmp; 1756 if (!msg->findInt32("bitrate-mode", &tmp)) { 1757 return OMX_Video_ControlRateVariable; 1758 } 1759 1760 return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp); 1761} 1762 1763status_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) { 1764 int32_t bitrate, iFrameInterval; 1765 if (!msg->findInt32("bitrate", &bitrate) 1766 || !msg->findInt32("i-frame-interval", &iFrameInterval)) { 1767 return INVALID_OPERATION; 1768 } 1769 1770 OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg); 1771 1772 float frameRate; 1773 if (!msg->findFloat("frame-rate", &frameRate)) { 1774 int32_t tmp; 1775 if (!msg->findInt32("frame-rate", &tmp)) { 1776 return INVALID_OPERATION; 1777 } 1778 frameRate = (float)tmp; 1779 } 1780 1781 OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type; 1782 InitOMXParams(&mpeg4type); 1783 mpeg4type.nPortIndex = kPortIndexOutput; 1784 1785 status_t err = mOMX->getParameter( 1786 mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type)); 1787 1788 if (err != OK) { 1789 return err; 1790 } 1791 1792 mpeg4type.nSliceHeaderSpacing = 0; 1793 mpeg4type.bSVH = OMX_FALSE; 1794 mpeg4type.bGov = OMX_FALSE; 1795 1796 mpeg4type.nAllowedPictureTypes = 1797 OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP; 1798 1799 mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate); 1800 if (mpeg4type.nPFrames == 0) { 1801 mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI; 1802 } 1803 mpeg4type.nBFrames = 0; 1804 mpeg4type.nIDCVLCThreshold = 0; 1805 mpeg4type.bACPred = OMX_TRUE; 1806 mpeg4type.nMaxPacketSize = 256; 1807 mpeg4type.nTimeIncRes = 1000; 1808 mpeg4type.nHeaderExtension = 0; 1809 mpeg4type.bReversibleVLC = OMX_FALSE; 1810 1811 int32_t profile; 1812 if (msg->findInt32("profile", &profile)) { 1813 int32_t level; 1814 if (!msg->findInt32("level", &level)) { 1815 return INVALID_OPERATION; 1816 } 1817 1818 err = verifySupportForProfileAndLevel(profile, level); 1819 1820 if (err != OK) { 1821 return err; 1822 } 1823 1824 mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile); 1825 mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level); 1826 } 1827 1828 err = mOMX->setParameter( 1829 mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type)); 1830 1831 if (err != OK) { 1832 return err; 1833 } 1834 1835 err = configureBitrate(bitrate, bitrateMode); 1836 1837 if (err != OK) { 1838 return err; 1839 } 1840 1841 return setupErrorCorrectionParameters(); 1842} 1843 1844status_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) { 1845 int32_t bitrate, iFrameInterval; 1846 if (!msg->findInt32("bitrate", &bitrate) 1847 || !msg->findInt32("i-frame-interval", &iFrameInterval)) { 1848 return INVALID_OPERATION; 1849 } 1850 1851 OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg); 1852 1853 float frameRate; 1854 if (!msg->findFloat("frame-rate", &frameRate)) { 1855 int32_t tmp; 1856 if (!msg->findInt32("frame-rate", &tmp)) { 1857 return INVALID_OPERATION; 1858 } 1859 frameRate = (float)tmp; 1860 } 1861 1862 OMX_VIDEO_PARAM_H263TYPE h263type; 1863 InitOMXParams(&h263type); 1864 h263type.nPortIndex = kPortIndexOutput; 1865 1866 status_t err = mOMX->getParameter( 1867 mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type)); 1868 1869 if (err != OK) { 1870 return err; 1871 } 1872 1873 h263type.nAllowedPictureTypes = 1874 OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP; 1875 1876 h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate); 1877 if (h263type.nPFrames == 0) { 1878 h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI; 1879 } 1880 h263type.nBFrames = 0; 1881 1882 int32_t profile; 1883 if (msg->findInt32("profile", &profile)) { 1884 int32_t level; 1885 if (!msg->findInt32("level", &level)) { 1886 return INVALID_OPERATION; 1887 } 1888 1889 err = verifySupportForProfileAndLevel(profile, level); 1890 1891 if (err != OK) { 1892 return err; 1893 } 1894 1895 h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile); 1896 h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level); 1897 } 1898 1899 h263type.bPLUSPTYPEAllowed = OMX_FALSE; 1900 h263type.bForceRoundingTypeToZero = OMX_FALSE; 1901 h263type.nPictureHeaderRepetition = 0; 1902 h263type.nGOBHeaderInterval = 0; 1903 1904 err = mOMX->setParameter( 1905 mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type)); 1906 1907 if (err != OK) { 1908 return err; 1909 } 1910 1911 err = configureBitrate(bitrate, bitrateMode); 1912 1913 if (err != OK) { 1914 return err; 1915 } 1916 1917 return setupErrorCorrectionParameters(); 1918} 1919 1920status_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) { 1921 int32_t bitrate, iFrameInterval; 1922 if (!msg->findInt32("bitrate", &bitrate) 1923 || !msg->findInt32("i-frame-interval", &iFrameInterval)) { 1924 return INVALID_OPERATION; 1925 } 1926 1927 OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg); 1928 1929 float frameRate; 1930 if (!msg->findFloat("frame-rate", &frameRate)) { 1931 int32_t tmp; 1932 if (!msg->findInt32("frame-rate", &tmp)) { 1933 return INVALID_OPERATION; 1934 } 1935 frameRate = (float)tmp; 1936 } 1937 1938 status_t err = OK; 1939 int32_t intraRefreshMode = 0; 1940 if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) { 1941 err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode); 1942 if (err != OK) { 1943 ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x", 1944 err, intraRefreshMode); 1945 return err; 1946 } 1947 } 1948 1949 OMX_VIDEO_PARAM_AVCTYPE h264type; 1950 InitOMXParams(&h264type); 1951 h264type.nPortIndex = kPortIndexOutput; 1952 1953 err = mOMX->getParameter( 1954 mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type)); 1955 1956 if (err != OK) { 1957 return err; 1958 } 1959 1960 h264type.nAllowedPictureTypes = 1961 OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP; 1962 1963 int32_t profile; 1964 if (msg->findInt32("profile", &profile)) { 1965 int32_t level; 1966 if (!msg->findInt32("level", &level)) { 1967 return INVALID_OPERATION; 1968 } 1969 1970 err = verifySupportForProfileAndLevel(profile, level); 1971 1972 if (err != OK) { 1973 return err; 1974 } 1975 1976 h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile); 1977 h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level); 1978 } 1979 1980 // XXX 1981 if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) { 1982 ALOGW("Use baseline profile instead of %d for AVC recording", 1983 h264type.eProfile); 1984 h264type.eProfile = OMX_VIDEO_AVCProfileBaseline; 1985 } 1986 1987 if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) { 1988 h264type.nSliceHeaderSpacing = 0; 1989 h264type.bUseHadamard = OMX_TRUE; 1990 h264type.nRefFrames = 1; 1991 h264type.nBFrames = 0; 1992 h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate); 1993 if (h264type.nPFrames == 0) { 1994 h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI; 1995 } 1996 h264type.nRefIdx10ActiveMinus1 = 0; 1997 h264type.nRefIdx11ActiveMinus1 = 0; 1998 h264type.bEntropyCodingCABAC = OMX_FALSE; 1999 h264type.bWeightedPPrediction = OMX_FALSE; 2000 h264type.bconstIpred = OMX_FALSE; 2001 h264type.bDirect8x8Inference = OMX_FALSE; 2002 h264type.bDirectSpatialTemporal = OMX_FALSE; 2003 h264type.nCabacInitIdc = 0; 2004 } 2005 2006 if (h264type.nBFrames != 0) { 2007 h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB; 2008 } 2009 2010 h264type.bEnableUEP = OMX_FALSE; 2011 h264type.bEnableFMO = OMX_FALSE; 2012 h264type.bEnableASO = OMX_FALSE; 2013 h264type.bEnableRS = OMX_FALSE; 2014 h264type.bFrameMBsOnly = OMX_TRUE; 2015 h264type.bMBAFF = OMX_FALSE; 2016 h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable; 2017 2018 err = mOMX->setParameter( 2019 mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type)); 2020 2021 if (err != OK) { 2022 return err; 2023 } 2024 2025 return configureBitrate(bitrate, bitrateMode); 2026} 2027 2028status_t ACodec::verifySupportForProfileAndLevel( 2029 int32_t profile, int32_t level) { 2030 OMX_VIDEO_PARAM_PROFILELEVELTYPE params; 2031 InitOMXParams(¶ms); 2032 params.nPortIndex = kPortIndexOutput; 2033 2034 for (params.nProfileIndex = 0;; ++params.nProfileIndex) { 2035 status_t err = mOMX->getParameter( 2036 mNode, 2037 OMX_IndexParamVideoProfileLevelQuerySupported, 2038 ¶ms, 2039 sizeof(params)); 2040 2041 if (err != OK) { 2042 return err; 2043 } 2044 2045 int32_t supportedProfile = static_cast<int32_t>(params.eProfile); 2046 int32_t supportedLevel = static_cast<int32_t>(params.eLevel); 2047 2048 if (profile == supportedProfile && level <= supportedLevel) { 2049 return OK; 2050 } 2051 } 2052} 2053 2054status_t ACodec::configureBitrate( 2055 int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) { 2056 OMX_VIDEO_PARAM_BITRATETYPE bitrateType; 2057 InitOMXParams(&bitrateType); 2058 bitrateType.nPortIndex = kPortIndexOutput; 2059 2060 status_t err = mOMX->getParameter( 2061 mNode, OMX_IndexParamVideoBitrate, 2062 &bitrateType, sizeof(bitrateType)); 2063 2064 if (err != OK) { 2065 return err; 2066 } 2067 2068 bitrateType.eControlRate = bitrateMode; 2069 bitrateType.nTargetBitrate = bitrate; 2070 2071 return mOMX->setParameter( 2072 mNode, OMX_IndexParamVideoBitrate, 2073 &bitrateType, sizeof(bitrateType)); 2074} 2075 2076status_t ACodec::setupErrorCorrectionParameters() { 2077 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType; 2078 InitOMXParams(&errorCorrectionType); 2079 errorCorrectionType.nPortIndex = kPortIndexOutput; 2080 2081 status_t err = mOMX->getParameter( 2082 mNode, OMX_IndexParamVideoErrorCorrection, 2083 &errorCorrectionType, sizeof(errorCorrectionType)); 2084 2085 if (err != OK) { 2086 return OK; // Optional feature. Ignore this failure 2087 } 2088 2089 errorCorrectionType.bEnableHEC = OMX_FALSE; 2090 errorCorrectionType.bEnableResync = OMX_TRUE; 2091 errorCorrectionType.nResynchMarkerSpacing = 256; 2092 errorCorrectionType.bEnableDataPartitioning = OMX_FALSE; 2093 errorCorrectionType.bEnableRVLC = OMX_FALSE; 2094 2095 return mOMX->setParameter( 2096 mNode, OMX_IndexParamVideoErrorCorrection, 2097 &errorCorrectionType, sizeof(errorCorrectionType)); 2098} 2099 2100status_t ACodec::setVideoFormatOnPort( 2101 OMX_U32 portIndex, 2102 int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat) { 2103 OMX_PARAM_PORTDEFINITIONTYPE def; 2104 InitOMXParams(&def); 2105 def.nPortIndex = portIndex; 2106 2107 OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video; 2108 2109 status_t err = mOMX->getParameter( 2110 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2111 2112 CHECK_EQ(err, (status_t)OK); 2113 2114 if (portIndex == kPortIndexInput) { 2115 // XXX Need a (much) better heuristic to compute input buffer sizes. 2116 const size_t X = 64 * 1024; 2117 if (def.nBufferSize < X) { 2118 def.nBufferSize = X; 2119 } 2120 } 2121 2122 CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo); 2123 2124 video_def->nFrameWidth = width; 2125 video_def->nFrameHeight = height; 2126 2127 if (portIndex == kPortIndexInput) { 2128 video_def->eCompressionFormat = compressionFormat; 2129 video_def->eColorFormat = OMX_COLOR_FormatUnused; 2130 } 2131 2132 err = mOMX->setParameter( 2133 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); 2134 2135 return err; 2136} 2137 2138status_t ACodec::initNativeWindow() { 2139 if (mNativeWindow != NULL) { 2140 return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE); 2141 } 2142 2143 mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE); 2144 return OK; 2145} 2146 2147size_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const { 2148 size_t n = 0; 2149 2150 for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) { 2151 const BufferInfo &info = mBuffers[portIndex].itemAt(i); 2152 2153 if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) { 2154 ++n; 2155 } 2156 } 2157 2158 return n; 2159} 2160 2161size_t ACodec::countBuffersOwnedByNativeWindow() const { 2162 size_t n = 0; 2163 2164 for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) { 2165 const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i); 2166 2167 if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 2168 ++n; 2169 } 2170 } 2171 2172 return n; 2173} 2174 2175void ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() { 2176 if (mNativeWindow == NULL) { 2177 return; 2178 } 2179 2180 int minUndequeuedBufs = 0; 2181 status_t err = mNativeWindow->query( 2182 mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, 2183 &minUndequeuedBufs); 2184 2185 if (err != OK) { 2186 ALOGE("[%s] NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)", 2187 mComponentName.c_str(), strerror(-err), -err); 2188 2189 minUndequeuedBufs = 0; 2190 } 2191 2192 while (countBuffersOwnedByNativeWindow() > (size_t)minUndequeuedBufs 2193 && dequeueBufferFromNativeWindow() != NULL) { 2194 } 2195} 2196 2197bool ACodec::allYourBuffersAreBelongToUs( 2198 OMX_U32 portIndex) { 2199 for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) { 2200 BufferInfo *info = &mBuffers[portIndex].editItemAt(i); 2201 2202 if (info->mStatus != BufferInfo::OWNED_BY_US 2203 && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) { 2204 ALOGV("[%s] Buffer %p on port %ld still has status %d", 2205 mComponentName.c_str(), 2206 info->mBufferID, portIndex, info->mStatus); 2207 return false; 2208 } 2209 } 2210 2211 return true; 2212} 2213 2214bool ACodec::allYourBuffersAreBelongToUs() { 2215 return allYourBuffersAreBelongToUs(kPortIndexInput) 2216 && allYourBuffersAreBelongToUs(kPortIndexOutput); 2217} 2218 2219void ACodec::deferMessage(const sp<AMessage> &msg) { 2220 bool wasEmptyBefore = mDeferredQueue.empty(); 2221 mDeferredQueue.push_back(msg); 2222} 2223 2224void ACodec::processDeferredMessages() { 2225 List<sp<AMessage> > queue = mDeferredQueue; 2226 mDeferredQueue.clear(); 2227 2228 List<sp<AMessage> >::iterator it = queue.begin(); 2229 while (it != queue.end()) { 2230 onMessageReceived(*it++); 2231 } 2232} 2233 2234void ACodec::sendFormatChange() { 2235 sp<AMessage> notify = mNotify->dup(); 2236 notify->setInt32("what", kWhatOutputFormatChanged); 2237 2238 OMX_PARAM_PORTDEFINITIONTYPE def; 2239 InitOMXParams(&def); 2240 def.nPortIndex = kPortIndexOutput; 2241 2242 CHECK_EQ(mOMX->getParameter( 2243 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)), 2244 (status_t)OK); 2245 2246 CHECK_EQ((int)def.eDir, (int)OMX_DirOutput); 2247 2248 switch (def.eDomain) { 2249 case OMX_PortDomainVideo: 2250 { 2251 OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video; 2252 2253 AString mime; 2254 if (!mIsEncoder) { 2255 notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW); 2256 } else if (GetMimeTypeForVideoCoding( 2257 videoDef->eCompressionFormat, &mime) != OK) { 2258 notify->setString("mime", "application/octet-stream"); 2259 } else { 2260 notify->setString("mime", mime.c_str()); 2261 } 2262 2263 notify->setInt32("width", videoDef->nFrameWidth); 2264 notify->setInt32("height", videoDef->nFrameHeight); 2265 2266 if (!mIsEncoder) { 2267 notify->setInt32("stride", videoDef->nStride); 2268 notify->setInt32("slice-height", videoDef->nSliceHeight); 2269 notify->setInt32("color-format", videoDef->eColorFormat); 2270 2271 OMX_CONFIG_RECTTYPE rect; 2272 InitOMXParams(&rect); 2273 rect.nPortIndex = kPortIndexOutput; 2274 2275 if (mOMX->getConfig( 2276 mNode, OMX_IndexConfigCommonOutputCrop, 2277 &rect, sizeof(rect)) != OK) { 2278 rect.nLeft = 0; 2279 rect.nTop = 0; 2280 rect.nWidth = videoDef->nFrameWidth; 2281 rect.nHeight = videoDef->nFrameHeight; 2282 } 2283 2284 CHECK_GE(rect.nLeft, 0); 2285 CHECK_GE(rect.nTop, 0); 2286 CHECK_GE(rect.nWidth, 0u); 2287 CHECK_GE(rect.nHeight, 0u); 2288 CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth); 2289 CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight); 2290 2291 notify->setRect( 2292 "crop", 2293 rect.nLeft, 2294 rect.nTop, 2295 rect.nLeft + rect.nWidth - 1, 2296 rect.nTop + rect.nHeight - 1); 2297 2298 if (mNativeWindow != NULL) { 2299 android_native_rect_t crop; 2300 crop.left = rect.nLeft; 2301 crop.top = rect.nTop; 2302 crop.right = rect.nLeft + rect.nWidth; 2303 crop.bottom = rect.nTop + rect.nHeight; 2304 2305 CHECK_EQ(0, native_window_set_crop( 2306 mNativeWindow.get(), &crop)); 2307 } 2308 } 2309 break; 2310 } 2311 2312 case OMX_PortDomainAudio: 2313 { 2314 OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio; 2315 2316 switch (audioDef->eEncoding) { 2317 case OMX_AUDIO_CodingPCM: 2318 { 2319 OMX_AUDIO_PARAM_PCMMODETYPE params; 2320 InitOMXParams(¶ms); 2321 params.nPortIndex = kPortIndexOutput; 2322 2323 CHECK_EQ(mOMX->getParameter( 2324 mNode, OMX_IndexParamAudioPcm, 2325 ¶ms, sizeof(params)), 2326 (status_t)OK); 2327 2328 CHECK(params.nChannels == 1 || params.bInterleaved); 2329 CHECK_EQ(params.nBitPerSample, 16u); 2330 CHECK_EQ((int)params.eNumData, (int)OMX_NumericalDataSigned); 2331 CHECK_EQ((int)params.ePCMMode, (int)OMX_AUDIO_PCMModeLinear); 2332 2333 notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW); 2334 notify->setInt32("channel-count", params.nChannels); 2335 notify->setInt32("sample-rate", params.nSamplingRate); 2336 if (mEncoderDelay + mEncoderPadding) { 2337 size_t frameSize = params.nChannels * sizeof(int16_t); 2338 if (mSkipCutBuffer != NULL) { 2339 size_t prevbufsize = mSkipCutBuffer->size(); 2340 if (prevbufsize != 0) { 2341 ALOGW("Replacing SkipCutBuffer holding %d bytes", prevbufsize); 2342 } 2343 } 2344 mSkipCutBuffer = new SkipCutBuffer(mEncoderDelay * frameSize, 2345 mEncoderPadding * frameSize); 2346 } 2347 2348 if (mChannelMaskPresent) { 2349 notify->setInt32("channel-mask", mChannelMask); 2350 } 2351 break; 2352 } 2353 2354 case OMX_AUDIO_CodingAAC: 2355 { 2356 OMX_AUDIO_PARAM_AACPROFILETYPE params; 2357 InitOMXParams(¶ms); 2358 params.nPortIndex = kPortIndexOutput; 2359 2360 CHECK_EQ(mOMX->getParameter( 2361 mNode, OMX_IndexParamAudioAac, 2362 ¶ms, sizeof(params)), 2363 (status_t)OK); 2364 2365 notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC); 2366 notify->setInt32("channel-count", params.nChannels); 2367 notify->setInt32("sample-rate", params.nSampleRate); 2368 break; 2369 } 2370 2371 case OMX_AUDIO_CodingAMR: 2372 { 2373 OMX_AUDIO_PARAM_AMRTYPE params; 2374 InitOMXParams(¶ms); 2375 params.nPortIndex = kPortIndexOutput; 2376 2377 CHECK_EQ(mOMX->getParameter( 2378 mNode, OMX_IndexParamAudioAmr, 2379 ¶ms, sizeof(params)), 2380 (status_t)OK); 2381 2382 notify->setInt32("channel-count", 1); 2383 if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) { 2384 notify->setString( 2385 "mime", MEDIA_MIMETYPE_AUDIO_AMR_WB); 2386 2387 notify->setInt32("sample-rate", 16000); 2388 } else { 2389 notify->setString( 2390 "mime", MEDIA_MIMETYPE_AUDIO_AMR_NB); 2391 2392 notify->setInt32("sample-rate", 8000); 2393 } 2394 break; 2395 } 2396 2397 case OMX_AUDIO_CodingFLAC: 2398 { 2399 OMX_AUDIO_PARAM_FLACTYPE params; 2400 InitOMXParams(¶ms); 2401 params.nPortIndex = kPortIndexOutput; 2402 2403 CHECK_EQ(mOMX->getParameter( 2404 mNode, OMX_IndexParamAudioFlac, 2405 ¶ms, sizeof(params)), 2406 (status_t)OK); 2407 2408 notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC); 2409 notify->setInt32("channel-count", params.nChannels); 2410 notify->setInt32("sample-rate", params.nSampleRate); 2411 break; 2412 } 2413 2414 default: 2415 TRESPASS(); 2416 } 2417 break; 2418 } 2419 2420 default: 2421 TRESPASS(); 2422 } 2423 2424 notify->post(); 2425 2426 mSentFormat = true; 2427} 2428 2429void ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) { 2430 sp<AMessage> notify = mNotify->dup(); 2431 notify->setInt32("what", ACodec::kWhatError); 2432 notify->setInt32("omx-error", error); 2433 notify->setInt32("err", internalError); 2434 notify->post(); 2435} 2436 2437status_t ACodec::pushBlankBuffersToNativeWindow() { 2438 status_t err = NO_ERROR; 2439 ANativeWindowBuffer* anb = NULL; 2440 int numBufs = 0; 2441 int minUndequeuedBufs = 0; 2442 2443 // We need to reconnect to the ANativeWindow as a CPU client to ensure that 2444 // no frames get dropped by SurfaceFlinger assuming that these are video 2445 // frames. 2446 err = native_window_api_disconnect(mNativeWindow.get(), 2447 NATIVE_WINDOW_API_MEDIA); 2448 if (err != NO_ERROR) { 2449 ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)", 2450 strerror(-err), -err); 2451 return err; 2452 } 2453 2454 err = native_window_api_connect(mNativeWindow.get(), 2455 NATIVE_WINDOW_API_CPU); 2456 if (err != NO_ERROR) { 2457 ALOGE("error pushing blank frames: api_connect failed: %s (%d)", 2458 strerror(-err), -err); 2459 return err; 2460 } 2461 2462 err = native_window_set_buffers_geometry(mNativeWindow.get(), 1, 1, 2463 HAL_PIXEL_FORMAT_RGBX_8888); 2464 if (err != NO_ERROR) { 2465 ALOGE("error pushing blank frames: set_buffers_geometry failed: %s (%d)", 2466 strerror(-err), -err); 2467 goto error; 2468 } 2469 2470 err = native_window_set_usage(mNativeWindow.get(), 2471 GRALLOC_USAGE_SW_WRITE_OFTEN); 2472 if (err != NO_ERROR) { 2473 ALOGE("error pushing blank frames: set_usage failed: %s (%d)", 2474 strerror(-err), -err); 2475 goto error; 2476 } 2477 2478 err = mNativeWindow->query(mNativeWindow.get(), 2479 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs); 2480 if (err != NO_ERROR) { 2481 ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query " 2482 "failed: %s (%d)", strerror(-err), -err); 2483 goto error; 2484 } 2485 2486 numBufs = minUndequeuedBufs + 1; 2487 err = native_window_set_buffer_count(mNativeWindow.get(), numBufs); 2488 if (err != NO_ERROR) { 2489 ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)", 2490 strerror(-err), -err); 2491 goto error; 2492 } 2493 2494 // We push numBufs + 1 buffers to ensure that we've drawn into the same 2495 // buffer twice. This should guarantee that the buffer has been displayed 2496 // on the screen and then been replaced, so an previous video frames are 2497 // guaranteed NOT to be currently displayed. 2498 for (int i = 0; i < numBufs + 1; i++) { 2499 int fenceFd = -1; 2500 err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb); 2501 if (err != NO_ERROR) { 2502 ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)", 2503 strerror(-err), -err); 2504 goto error; 2505 } 2506 2507 sp<GraphicBuffer> buf(new GraphicBuffer(anb, false)); 2508 2509 // Fill the buffer with the a 1x1 checkerboard pattern ;) 2510 uint32_t* img = NULL; 2511 err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img)); 2512 if (err != NO_ERROR) { 2513 ALOGE("error pushing blank frames: lock failed: %s (%d)", 2514 strerror(-err), -err); 2515 goto error; 2516 } 2517 2518 *img = 0; 2519 2520 err = buf->unlock(); 2521 if (err != NO_ERROR) { 2522 ALOGE("error pushing blank frames: unlock failed: %s (%d)", 2523 strerror(-err), -err); 2524 goto error; 2525 } 2526 2527 err = mNativeWindow->queueBuffer(mNativeWindow.get(), 2528 buf->getNativeBuffer(), -1); 2529 if (err != NO_ERROR) { 2530 ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)", 2531 strerror(-err), -err); 2532 goto error; 2533 } 2534 2535 anb = NULL; 2536 } 2537 2538error: 2539 2540 if (err != NO_ERROR) { 2541 // Clean up after an error. 2542 if (anb != NULL) { 2543 mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1); 2544 } 2545 2546 native_window_api_disconnect(mNativeWindow.get(), 2547 NATIVE_WINDOW_API_CPU); 2548 native_window_api_connect(mNativeWindow.get(), 2549 NATIVE_WINDOW_API_MEDIA); 2550 2551 return err; 2552 } else { 2553 // Clean up after success. 2554 err = native_window_api_disconnect(mNativeWindow.get(), 2555 NATIVE_WINDOW_API_CPU); 2556 if (err != NO_ERROR) { 2557 ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)", 2558 strerror(-err), -err); 2559 return err; 2560 } 2561 2562 err = native_window_api_connect(mNativeWindow.get(), 2563 NATIVE_WINDOW_API_MEDIA); 2564 if (err != NO_ERROR) { 2565 ALOGE("error pushing blank frames: api_connect failed: %s (%d)", 2566 strerror(-err), -err); 2567 return err; 2568 } 2569 2570 return NO_ERROR; 2571 } 2572} 2573 2574//////////////////////////////////////////////////////////////////////////////// 2575 2576ACodec::PortDescription::PortDescription() { 2577} 2578 2579status_t ACodec::requestIDRFrame() { 2580 if (!mIsEncoder) { 2581 return ERROR_UNSUPPORTED; 2582 } 2583 2584 OMX_CONFIG_INTRAREFRESHVOPTYPE params; 2585 InitOMXParams(¶ms); 2586 2587 params.nPortIndex = kPortIndexOutput; 2588 params.IntraRefreshVOP = OMX_TRUE; 2589 2590 return mOMX->setConfig( 2591 mNode, 2592 OMX_IndexConfigVideoIntraVOPRefresh, 2593 ¶ms, 2594 sizeof(params)); 2595} 2596 2597void ACodec::PortDescription::addBuffer( 2598 IOMX::buffer_id id, const sp<ABuffer> &buffer) { 2599 mBufferIDs.push_back(id); 2600 mBuffers.push_back(buffer); 2601} 2602 2603size_t ACodec::PortDescription::countBuffers() { 2604 return mBufferIDs.size(); 2605} 2606 2607IOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const { 2608 return mBufferIDs.itemAt(index); 2609} 2610 2611sp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const { 2612 return mBuffers.itemAt(index); 2613} 2614 2615//////////////////////////////////////////////////////////////////////////////// 2616 2617ACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState) 2618 : AState(parentState), 2619 mCodec(codec) { 2620} 2621 2622ACodec::BaseState::PortMode ACodec::BaseState::getPortMode(OMX_U32 portIndex) { 2623 return KEEP_BUFFERS; 2624} 2625 2626bool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) { 2627 switch (msg->what()) { 2628 case kWhatInputBufferFilled: 2629 { 2630 onInputBufferFilled(msg); 2631 break; 2632 } 2633 2634 case kWhatOutputBufferDrained: 2635 { 2636 onOutputBufferDrained(msg); 2637 break; 2638 } 2639 2640 case ACodec::kWhatOMXMessage: 2641 { 2642 return onOMXMessage(msg); 2643 } 2644 2645 case ACodec::kWhatCreateInputSurface: 2646 case ACodec::kWhatSignalEndOfInputStream: 2647 { 2648 ALOGE("Message 0x%x was not handled", msg->what()); 2649 mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION); 2650 return true; 2651 } 2652 2653 case ACodec::kWhatOMXDied: 2654 { 2655 ALOGE("OMX/mediaserver died, signalling error!"); 2656 mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT); 2657 break; 2658 } 2659 2660 default: 2661 return false; 2662 } 2663 2664 return true; 2665} 2666 2667bool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) { 2668 int32_t type; 2669 CHECK(msg->findInt32("type", &type)); 2670 2671 IOMX::node_id nodeID; 2672 CHECK(msg->findPointer("node", &nodeID)); 2673 CHECK_EQ(nodeID, mCodec->mNode); 2674 2675 switch (type) { 2676 case omx_message::EVENT: 2677 { 2678 int32_t event, data1, data2; 2679 CHECK(msg->findInt32("event", &event)); 2680 CHECK(msg->findInt32("data1", &data1)); 2681 CHECK(msg->findInt32("data2", &data2)); 2682 2683 if (event == OMX_EventCmdComplete 2684 && data1 == OMX_CommandFlush 2685 && data2 == (int32_t)OMX_ALL) { 2686 // Use of this notification is not consistent across 2687 // implementations. We'll drop this notification and rely 2688 // on flush-complete notifications on the individual port 2689 // indices instead. 2690 2691 return true; 2692 } 2693 2694 return onOMXEvent( 2695 static_cast<OMX_EVENTTYPE>(event), 2696 static_cast<OMX_U32>(data1), 2697 static_cast<OMX_U32>(data2)); 2698 } 2699 2700 case omx_message::EMPTY_BUFFER_DONE: 2701 { 2702 IOMX::buffer_id bufferID; 2703 CHECK(msg->findPointer("buffer", &bufferID)); 2704 2705 return onOMXEmptyBufferDone(bufferID); 2706 } 2707 2708 case omx_message::FILL_BUFFER_DONE: 2709 { 2710 IOMX::buffer_id bufferID; 2711 CHECK(msg->findPointer("buffer", &bufferID)); 2712 2713 int32_t rangeOffset, rangeLength, flags; 2714 int64_t timeUs; 2715 void *platformPrivate; 2716 void *dataPtr; 2717 2718 CHECK(msg->findInt32("range_offset", &rangeOffset)); 2719 CHECK(msg->findInt32("range_length", &rangeLength)); 2720 CHECK(msg->findInt32("flags", &flags)); 2721 CHECK(msg->findInt64("timestamp", &timeUs)); 2722 CHECK(msg->findPointer("platform_private", &platformPrivate)); 2723 CHECK(msg->findPointer("data_ptr", &dataPtr)); 2724 2725 return onOMXFillBufferDone( 2726 bufferID, 2727 (size_t)rangeOffset, (size_t)rangeLength, 2728 (OMX_U32)flags, 2729 timeUs, 2730 platformPrivate, 2731 dataPtr); 2732 } 2733 2734 default: 2735 TRESPASS(); 2736 break; 2737 } 2738} 2739 2740bool ACodec::BaseState::onOMXEvent( 2741 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 2742 if (event != OMX_EventError) { 2743 ALOGV("[%s] EVENT(%d, 0x%08lx, 0x%08lx)", 2744 mCodec->mComponentName.c_str(), event, data1, data2); 2745 2746 return false; 2747 } 2748 2749 ALOGE("[%s] ERROR(0x%08lx)", mCodec->mComponentName.c_str(), data1); 2750 2751 mCodec->signalError((OMX_ERRORTYPE)data1); 2752 2753 return true; 2754} 2755 2756bool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) { 2757 ALOGV("[%s] onOMXEmptyBufferDone %p", 2758 mCodec->mComponentName.c_str(), bufferID); 2759 2760 BufferInfo *info = 2761 mCodec->findBufferByID(kPortIndexInput, bufferID); 2762 2763 CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT); 2764 info->mStatus = BufferInfo::OWNED_BY_US; 2765 2766 const sp<AMessage> &bufferMeta = info->mData->meta(); 2767 void *mediaBuffer; 2768 if (bufferMeta->findPointer("mediaBuffer", &mediaBuffer) 2769 && mediaBuffer != NULL) { 2770 // We're in "store-metadata-in-buffers" mode, the underlying 2771 // OMX component had access to data that's implicitly refcounted 2772 // by this "mediaBuffer" object. Now that the OMX component has 2773 // told us that it's done with the input buffer, we can decrement 2774 // the mediaBuffer's reference count. 2775 2776 ALOGV("releasing mbuf %p", mediaBuffer); 2777 2778 ((MediaBuffer *)mediaBuffer)->release(); 2779 mediaBuffer = NULL; 2780 2781 bufferMeta->setPointer("mediaBuffer", NULL); 2782 } 2783 2784 PortMode mode = getPortMode(kPortIndexInput); 2785 2786 switch (mode) { 2787 case KEEP_BUFFERS: 2788 break; 2789 2790 case RESUBMIT_BUFFERS: 2791 postFillThisBuffer(info); 2792 break; 2793 2794 default: 2795 { 2796 CHECK_EQ((int)mode, (int)FREE_BUFFERS); 2797 TRESPASS(); // Not currently used 2798 break; 2799 } 2800 } 2801 2802 return true; 2803} 2804 2805void ACodec::BaseState::postFillThisBuffer(BufferInfo *info) { 2806 if (mCodec->mPortEOS[kPortIndexInput]) { 2807 return; 2808 } 2809 2810 CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US); 2811 2812 sp<AMessage> notify = mCodec->mNotify->dup(); 2813 notify->setInt32("what", ACodec::kWhatFillThisBuffer); 2814 notify->setPointer("buffer-id", info->mBufferID); 2815 2816 info->mData->meta()->clear(); 2817 notify->setBuffer("buffer", info->mData); 2818 2819 sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec->id()); 2820 reply->setPointer("buffer-id", info->mBufferID); 2821 2822 notify->setMessage("reply", reply); 2823 2824 notify->post(); 2825 2826 info->mStatus = BufferInfo::OWNED_BY_UPSTREAM; 2827} 2828 2829void ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) { 2830 IOMX::buffer_id bufferID; 2831 CHECK(msg->findPointer("buffer-id", &bufferID)); 2832 2833 sp<ABuffer> buffer; 2834 int32_t err = OK; 2835 bool eos = false; 2836 2837 if (!msg->findBuffer("buffer", &buffer)) { 2838 CHECK(msg->findInt32("err", &err)); 2839 2840 ALOGV("[%s] saw error %d instead of an input buffer", 2841 mCodec->mComponentName.c_str(), err); 2842 2843 buffer.clear(); 2844 2845 eos = true; 2846 } 2847 2848 int32_t tmp; 2849 if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) { 2850 eos = true; 2851 err = ERROR_END_OF_STREAM; 2852 } 2853 2854 BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID); 2855 CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM); 2856 2857 info->mStatus = BufferInfo::OWNED_BY_US; 2858 2859 PortMode mode = getPortMode(kPortIndexInput); 2860 2861 switch (mode) { 2862 case KEEP_BUFFERS: 2863 { 2864 if (eos) { 2865 if (!mCodec->mPortEOS[kPortIndexInput]) { 2866 mCodec->mPortEOS[kPortIndexInput] = true; 2867 mCodec->mInputEOSResult = err; 2868 } 2869 } 2870 break; 2871 } 2872 2873 case RESUBMIT_BUFFERS: 2874 { 2875 if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) { 2876 int64_t timeUs; 2877 CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 2878 2879 OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME; 2880 2881 int32_t isCSD; 2882 if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) { 2883 flags |= OMX_BUFFERFLAG_CODECCONFIG; 2884 } 2885 2886 if (eos) { 2887 flags |= OMX_BUFFERFLAG_EOS; 2888 } 2889 2890 if (buffer != info->mData) { 2891 ALOGV("[%s] Needs to copy input data for buffer %p. (%p != %p)", 2892 mCodec->mComponentName.c_str(), 2893 bufferID, 2894 buffer.get(), info->mData.get()); 2895 2896 CHECK_LE(buffer->size(), info->mData->capacity()); 2897 memcpy(info->mData->data(), buffer->data(), buffer->size()); 2898 } 2899 2900 if (flags & OMX_BUFFERFLAG_CODECCONFIG) { 2901 ALOGV("[%s] calling emptyBuffer %p w/ codec specific data", 2902 mCodec->mComponentName.c_str(), bufferID); 2903 } else if (flags & OMX_BUFFERFLAG_EOS) { 2904 ALOGV("[%s] calling emptyBuffer %p w/ EOS", 2905 mCodec->mComponentName.c_str(), bufferID); 2906 } else { 2907#if TRACK_BUFFER_TIMING 2908 ALOGI("[%s] calling emptyBuffer %p w/ time %lld us", 2909 mCodec->mComponentName.c_str(), bufferID, timeUs); 2910#else 2911 ALOGV("[%s] calling emptyBuffer %p w/ time %lld us", 2912 mCodec->mComponentName.c_str(), bufferID, timeUs); 2913#endif 2914 } 2915 2916#if TRACK_BUFFER_TIMING 2917 ACodec::BufferStats stats; 2918 stats.mEmptyBufferTimeUs = ALooper::GetNowUs(); 2919 stats.mFillBufferDoneTimeUs = -1ll; 2920 mCodec->mBufferStats.add(timeUs, stats); 2921#endif 2922 2923 CHECK_EQ(mCodec->mOMX->emptyBuffer( 2924 mCodec->mNode, 2925 bufferID, 2926 0, 2927 buffer->size(), 2928 flags, 2929 timeUs), 2930 (status_t)OK); 2931 2932 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 2933 2934 if (!eos) { 2935 getMoreInputDataIfPossible(); 2936 } else { 2937 ALOGV("[%s] Signalled EOS on the input port", 2938 mCodec->mComponentName.c_str()); 2939 2940 mCodec->mPortEOS[kPortIndexInput] = true; 2941 mCodec->mInputEOSResult = err; 2942 } 2943 } else if (!mCodec->mPortEOS[kPortIndexInput]) { 2944 if (err != ERROR_END_OF_STREAM) { 2945 ALOGV("[%s] Signalling EOS on the input port " 2946 "due to error %d", 2947 mCodec->mComponentName.c_str(), err); 2948 } else { 2949 ALOGV("[%s] Signalling EOS on the input port", 2950 mCodec->mComponentName.c_str()); 2951 } 2952 2953 ALOGV("[%s] calling emptyBuffer %p signalling EOS", 2954 mCodec->mComponentName.c_str(), bufferID); 2955 2956 CHECK_EQ(mCodec->mOMX->emptyBuffer( 2957 mCodec->mNode, 2958 bufferID, 2959 0, 2960 0, 2961 OMX_BUFFERFLAG_EOS, 2962 0), 2963 (status_t)OK); 2964 2965 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 2966 2967 mCodec->mPortEOS[kPortIndexInput] = true; 2968 mCodec->mInputEOSResult = err; 2969 } 2970 break; 2971 2972 default: 2973 CHECK_EQ((int)mode, (int)FREE_BUFFERS); 2974 break; 2975 } 2976 } 2977} 2978 2979void ACodec::BaseState::getMoreInputDataIfPossible() { 2980 if (mCodec->mPortEOS[kPortIndexInput]) { 2981 return; 2982 } 2983 2984 BufferInfo *eligible = NULL; 2985 2986 for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) { 2987 BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i); 2988 2989#if 0 2990 if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) { 2991 // There's already a "read" pending. 2992 return; 2993 } 2994#endif 2995 2996 if (info->mStatus == BufferInfo::OWNED_BY_US) { 2997 eligible = info; 2998 } 2999 } 3000 3001 if (eligible == NULL) { 3002 return; 3003 } 3004 3005 postFillThisBuffer(eligible); 3006} 3007 3008bool ACodec::BaseState::onOMXFillBufferDone( 3009 IOMX::buffer_id bufferID, 3010 size_t rangeOffset, size_t rangeLength, 3011 OMX_U32 flags, 3012 int64_t timeUs, 3013 void *platformPrivate, 3014 void *dataPtr) { 3015 ALOGV("[%s] onOMXFillBufferDone %p time %lld us, flags = 0x%08lx", 3016 mCodec->mComponentName.c_str(), bufferID, timeUs, flags); 3017 3018 ssize_t index; 3019 3020#if TRACK_BUFFER_TIMING 3021 index = mCodec->mBufferStats.indexOfKey(timeUs); 3022 if (index >= 0) { 3023 ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index); 3024 stats->mFillBufferDoneTimeUs = ALooper::GetNowUs(); 3025 3026 ALOGI("frame PTS %lld: %lld", 3027 timeUs, 3028 stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs); 3029 3030 mCodec->mBufferStats.removeItemsAt(index); 3031 stats = NULL; 3032 } 3033#endif 3034 3035 BufferInfo *info = 3036 mCodec->findBufferByID(kPortIndexOutput, bufferID, &index); 3037 3038 CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT); 3039 3040 info->mStatus = BufferInfo::OWNED_BY_US; 3041 3042 PortMode mode = getPortMode(kPortIndexOutput); 3043 3044 switch (mode) { 3045 case KEEP_BUFFERS: 3046 break; 3047 3048 case RESUBMIT_BUFFERS: 3049 { 3050 if (rangeLength == 0 && !(flags & OMX_BUFFERFLAG_EOS)) { 3051 ALOGV("[%s] calling fillBuffer %p", 3052 mCodec->mComponentName.c_str(), info->mBufferID); 3053 3054 CHECK_EQ(mCodec->mOMX->fillBuffer( 3055 mCodec->mNode, info->mBufferID), 3056 (status_t)OK); 3057 3058 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 3059 break; 3060 } 3061 3062 if (!mCodec->mSentFormat) { 3063 mCodec->sendFormatChange(); 3064 } 3065 3066 info->mData->setRange(rangeOffset, rangeLength); 3067#if 0 3068 if (mCodec->mNativeWindow == NULL) { 3069 if (IsIDR(info->mData)) { 3070 ALOGI("IDR frame"); 3071 } 3072 } 3073#endif 3074 3075 if (mCodec->mSkipCutBuffer != NULL) { 3076 mCodec->mSkipCutBuffer->submit(info->mData); 3077 } 3078 info->mData->meta()->setInt64("timeUs", timeUs); 3079 3080 sp<AMessage> notify = mCodec->mNotify->dup(); 3081 notify->setInt32("what", ACodec::kWhatDrainThisBuffer); 3082 notify->setPointer("buffer-id", info->mBufferID); 3083 notify->setBuffer("buffer", info->mData); 3084 notify->setInt32("flags", flags); 3085 3086 sp<AMessage> reply = 3087 new AMessage(kWhatOutputBufferDrained, mCodec->id()); 3088 3089 reply->setPointer("buffer-id", info->mBufferID); 3090 3091 notify->setMessage("reply", reply); 3092 3093 notify->post(); 3094 3095 info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM; 3096 3097 if (flags & OMX_BUFFERFLAG_EOS) { 3098 ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str()); 3099 3100 sp<AMessage> notify = mCodec->mNotify->dup(); 3101 notify->setInt32("what", ACodec::kWhatEOS); 3102 notify->setInt32("err", mCodec->mInputEOSResult); 3103 notify->post(); 3104 3105 mCodec->mPortEOS[kPortIndexOutput] = true; 3106 } 3107 break; 3108 } 3109 3110 default: 3111 { 3112 CHECK_EQ((int)mode, (int)FREE_BUFFERS); 3113 3114 CHECK_EQ((status_t)OK, 3115 mCodec->freeBuffer(kPortIndexOutput, index)); 3116 break; 3117 } 3118 } 3119 3120 return true; 3121} 3122 3123void ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) { 3124 IOMX::buffer_id bufferID; 3125 CHECK(msg->findPointer("buffer-id", &bufferID)); 3126 3127 ssize_t index; 3128 BufferInfo *info = 3129 mCodec->findBufferByID(kPortIndexOutput, bufferID, &index); 3130 CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM); 3131 3132 int32_t render; 3133 if (mCodec->mNativeWindow != NULL 3134 && msg->findInt32("render", &render) && render != 0 3135 && (info->mData == NULL || info->mData->size() != 0)) { 3136 // The client wants this buffer to be rendered. 3137 3138 status_t err; 3139 if ((err = mCodec->mNativeWindow->queueBuffer( 3140 mCodec->mNativeWindow.get(), 3141 info->mGraphicBuffer.get(), -1)) == OK) { 3142 info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW; 3143 } else { 3144 mCodec->signalError(OMX_ErrorUndefined, err); 3145 info->mStatus = BufferInfo::OWNED_BY_US; 3146 } 3147 } else { 3148 info->mStatus = BufferInfo::OWNED_BY_US; 3149 } 3150 3151 PortMode mode = getPortMode(kPortIndexOutput); 3152 3153 switch (mode) { 3154 case KEEP_BUFFERS: 3155 { 3156 // XXX fishy, revisit!!! What about the FREE_BUFFERS case below? 3157 3158 if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 3159 // We cannot resubmit the buffer we just rendered, dequeue 3160 // the spare instead. 3161 3162 info = mCodec->dequeueBufferFromNativeWindow(); 3163 } 3164 break; 3165 } 3166 3167 case RESUBMIT_BUFFERS: 3168 { 3169 if (!mCodec->mPortEOS[kPortIndexOutput]) { 3170 if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 3171 // We cannot resubmit the buffer we just rendered, dequeue 3172 // the spare instead. 3173 3174 info = mCodec->dequeueBufferFromNativeWindow(); 3175 } 3176 3177 if (info != NULL) { 3178 ALOGV("[%s] calling fillBuffer %p", 3179 mCodec->mComponentName.c_str(), info->mBufferID); 3180 3181 CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID), 3182 (status_t)OK); 3183 3184 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 3185 } 3186 } 3187 break; 3188 } 3189 3190 default: 3191 { 3192 CHECK_EQ((int)mode, (int)FREE_BUFFERS); 3193 3194 CHECK_EQ((status_t)OK, 3195 mCodec->freeBuffer(kPortIndexOutput, index)); 3196 break; 3197 } 3198 } 3199} 3200 3201//////////////////////////////////////////////////////////////////////////////// 3202 3203ACodec::UninitializedState::UninitializedState(ACodec *codec) 3204 : BaseState(codec) { 3205} 3206 3207void ACodec::UninitializedState::stateEntered() { 3208 ALOGV("Now uninitialized"); 3209 3210 if (mDeathNotifier != NULL) { 3211 mCodec->mOMX->asBinder()->unlinkToDeath(mDeathNotifier); 3212 mDeathNotifier.clear(); 3213 } 3214 3215 mCodec->mNativeWindow.clear(); 3216 mCodec->mNode = NULL; 3217 mCodec->mOMX.clear(); 3218 mCodec->mQuirks = 0; 3219 mCodec->mFlags = 0; 3220 mCodec->mComponentName.clear(); 3221} 3222 3223bool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) { 3224 bool handled = false; 3225 3226 switch (msg->what()) { 3227 case ACodec::kWhatSetup: 3228 { 3229 onSetup(msg); 3230 3231 handled = true; 3232 break; 3233 } 3234 3235 case ACodec::kWhatAllocateComponent: 3236 { 3237 onAllocateComponent(msg); 3238 handled = true; 3239 break; 3240 } 3241 3242 case ACodec::kWhatShutdown: 3243 { 3244 int32_t keepComponentAllocated; 3245 CHECK(msg->findInt32( 3246 "keepComponentAllocated", &keepComponentAllocated)); 3247 CHECK(!keepComponentAllocated); 3248 3249 sp<AMessage> notify = mCodec->mNotify->dup(); 3250 notify->setInt32("what", ACodec::kWhatShutdownCompleted); 3251 notify->post(); 3252 3253 handled = true; 3254 break; 3255 } 3256 3257 case ACodec::kWhatFlush: 3258 { 3259 sp<AMessage> notify = mCodec->mNotify->dup(); 3260 notify->setInt32("what", ACodec::kWhatFlushCompleted); 3261 notify->post(); 3262 3263 handled = true; 3264 break; 3265 } 3266 3267 default: 3268 return BaseState::onMessageReceived(msg); 3269 } 3270 3271 return handled; 3272} 3273 3274void ACodec::UninitializedState::onSetup( 3275 const sp<AMessage> &msg) { 3276 if (onAllocateComponent(msg) 3277 && mCodec->mLoadedState->onConfigureComponent(msg)) { 3278 mCodec->mLoadedState->onStart(); 3279 } 3280} 3281 3282bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) { 3283 ALOGV("onAllocateComponent"); 3284 3285 CHECK(mCodec->mNode == NULL); 3286 3287 OMXClient client; 3288 CHECK_EQ(client.connect(), (status_t)OK); 3289 3290 sp<IOMX> omx = client.interface(); 3291 3292 sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec->id()); 3293 3294 mDeathNotifier = new DeathNotifier(notify); 3295 if (omx->asBinder()->linkToDeath(mDeathNotifier) != OK) { 3296 // This was a local binder, if it dies so do we, we won't care 3297 // about any notifications in the afterlife. 3298 mDeathNotifier.clear(); 3299 } 3300 3301 Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs; 3302 3303 AString mime; 3304 3305 AString componentName; 3306 uint32_t quirks = 0; 3307 if (msg->findString("componentName", &componentName)) { 3308 ssize_t index = matchingCodecs.add(); 3309 OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index); 3310 entry->mName = String8(componentName.c_str()); 3311 3312 if (!OMXCodec::findCodecQuirks( 3313 componentName.c_str(), &entry->mQuirks)) { 3314 entry->mQuirks = 0; 3315 } 3316 } else { 3317 CHECK(msg->findString("mime", &mime)); 3318 3319 int32_t encoder; 3320 if (!msg->findInt32("encoder", &encoder)) { 3321 encoder = false; 3322 } 3323 3324 OMXCodec::findMatchingCodecs( 3325 mime.c_str(), 3326 encoder, // createEncoder 3327 NULL, // matchComponentName 3328 0, // flags 3329 &matchingCodecs); 3330 } 3331 3332 sp<CodecObserver> observer = new CodecObserver; 3333 IOMX::node_id node = NULL; 3334 3335 for (size_t matchIndex = 0; matchIndex < matchingCodecs.size(); 3336 ++matchIndex) { 3337 componentName = matchingCodecs.itemAt(matchIndex).mName.string(); 3338 quirks = matchingCodecs.itemAt(matchIndex).mQuirks; 3339 3340 pid_t tid = androidGetTid(); 3341 int prevPriority = androidGetThreadPriority(tid); 3342 androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND); 3343 status_t err = omx->allocateNode(componentName.c_str(), observer, &node); 3344 androidSetThreadPriority(tid, prevPriority); 3345 3346 if (err == OK) { 3347 break; 3348 } 3349 3350 node = NULL; 3351 } 3352 3353 if (node == NULL) { 3354 if (!mime.empty()) { 3355 ALOGE("Unable to instantiate a decoder for type '%s'.", 3356 mime.c_str()); 3357 } else { 3358 ALOGE("Unable to instantiate decoder '%s'.", componentName.c_str()); 3359 } 3360 3361 mCodec->signalError(OMX_ErrorComponentNotFound); 3362 return false; 3363 } 3364 3365 notify = new AMessage(kWhatOMXMessage, mCodec->id()); 3366 observer->setNotificationMessage(notify); 3367 3368 mCodec->mComponentName = componentName; 3369 mCodec->mFlags = 0; 3370 3371 if (componentName.endsWith(".secure")) { 3372 mCodec->mFlags |= kFlagIsSecure; 3373 } 3374 3375 mCodec->mQuirks = quirks; 3376 mCodec->mOMX = omx; 3377 mCodec->mNode = node; 3378 3379 { 3380 sp<AMessage> notify = mCodec->mNotify->dup(); 3381 notify->setInt32("what", ACodec::kWhatComponentAllocated); 3382 notify->setString("componentName", mCodec->mComponentName.c_str()); 3383 notify->post(); 3384 } 3385 3386 mCodec->changeState(mCodec->mLoadedState); 3387 3388 return true; 3389} 3390 3391//////////////////////////////////////////////////////////////////////////////// 3392 3393ACodec::LoadedState::LoadedState(ACodec *codec) 3394 : BaseState(codec) { 3395} 3396 3397void ACodec::LoadedState::stateEntered() { 3398 ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str()); 3399 3400 mCodec->mPortEOS[kPortIndexInput] = 3401 mCodec->mPortEOS[kPortIndexOutput] = false; 3402 3403 mCodec->mInputEOSResult = OK; 3404 3405 if (mCodec->mShutdownInProgress) { 3406 bool keepComponentAllocated = mCodec->mKeepComponentAllocated; 3407 3408 mCodec->mShutdownInProgress = false; 3409 mCodec->mKeepComponentAllocated = false; 3410 3411 onShutdown(keepComponentAllocated); 3412 } 3413} 3414 3415void ACodec::LoadedState::onShutdown(bool keepComponentAllocated) { 3416 if (!keepComponentAllocated) { 3417 CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK); 3418 3419 mCodec->changeState(mCodec->mUninitializedState); 3420 } 3421 3422 sp<AMessage> notify = mCodec->mNotify->dup(); 3423 notify->setInt32("what", ACodec::kWhatShutdownCompleted); 3424 notify->post(); 3425} 3426 3427bool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) { 3428 bool handled = false; 3429 3430 switch (msg->what()) { 3431 case ACodec::kWhatConfigureComponent: 3432 { 3433 onConfigureComponent(msg); 3434 handled = true; 3435 break; 3436 } 3437 3438 case ACodec::kWhatCreateInputSurface: 3439 { 3440 onCreateInputSurface(msg); 3441 handled = true; 3442 break; 3443 } 3444 3445 case ACodec::kWhatStart: 3446 { 3447 onStart(); 3448 handled = true; 3449 break; 3450 } 3451 3452 case ACodec::kWhatShutdown: 3453 { 3454 int32_t keepComponentAllocated; 3455 CHECK(msg->findInt32( 3456 "keepComponentAllocated", &keepComponentAllocated)); 3457 3458 onShutdown(keepComponentAllocated); 3459 3460 handled = true; 3461 break; 3462 } 3463 3464 case ACodec::kWhatFlush: 3465 { 3466 sp<AMessage> notify = mCodec->mNotify->dup(); 3467 notify->setInt32("what", ACodec::kWhatFlushCompleted); 3468 notify->post(); 3469 3470 handled = true; 3471 break; 3472 } 3473 3474 default: 3475 return BaseState::onMessageReceived(msg); 3476 } 3477 3478 return handled; 3479} 3480 3481bool ACodec::LoadedState::onConfigureComponent( 3482 const sp<AMessage> &msg) { 3483 ALOGV("onConfigureComponent"); 3484 3485 CHECK(mCodec->mNode != NULL); 3486 3487 AString mime; 3488 CHECK(msg->findString("mime", &mime)); 3489 3490 status_t err = mCodec->configureCodec(mime.c_str(), msg); 3491 3492 if (err != OK) { 3493 ALOGE("[%s] configureCodec returning error %d", 3494 mCodec->mComponentName.c_str(), err); 3495 3496 mCodec->signalError(OMX_ErrorUndefined, err); 3497 return false; 3498 } 3499 3500 sp<RefBase> obj; 3501 if (msg->findObject("native-window", &obj) 3502 && strncmp("OMX.google.", mCodec->mComponentName.c_str(), 11)) { 3503 sp<NativeWindowWrapper> nativeWindow( 3504 static_cast<NativeWindowWrapper *>(obj.get())); 3505 CHECK(nativeWindow != NULL); 3506 mCodec->mNativeWindow = nativeWindow->getNativeWindow(); 3507 3508 native_window_set_scaling_mode( 3509 mCodec->mNativeWindow.get(), 3510 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW); 3511 } 3512 CHECK_EQ((status_t)OK, mCodec->initNativeWindow()); 3513 3514 { 3515 sp<AMessage> notify = mCodec->mNotify->dup(); 3516 notify->setInt32("what", ACodec::kWhatComponentConfigured); 3517 notify->post(); 3518 } 3519 3520 return true; 3521} 3522 3523void ACodec::LoadedState::onCreateInputSurface( 3524 const sp<AMessage> &msg) { 3525 ALOGV("onCreateInputSurface"); 3526 3527 sp<AMessage> notify = mCodec->mNotify->dup(); 3528 notify->setInt32("what", ACodec::kWhatInputSurfaceCreated); 3529 3530 sp<IGraphicBufferProducer> bufferProducer; 3531 status_t err; 3532 3533 err = mCodec->mOMX->createInputSurface(mCodec->mNode, kPortIndexInput, 3534 &bufferProducer); 3535 if (err == OK) { 3536 notify->setObject("input-surface", 3537 new BufferProducerWrapper(bufferProducer)); 3538 } else { 3539 // Can't use mCodec->signalError() here -- MediaCodec won't forward 3540 // the error through because it's in the "configured" state. We 3541 // send a kWhatInputSurfaceCreated with an error value instead. 3542 ALOGE("[%s] onCreateInputSurface returning error %d", 3543 mCodec->mComponentName.c_str(), err); 3544 notify->setInt32("err", err); 3545 } 3546 notify->post(); 3547} 3548 3549void ACodec::LoadedState::onStart() { 3550 ALOGV("onStart"); 3551 3552 CHECK_EQ(mCodec->mOMX->sendCommand( 3553 mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle), 3554 (status_t)OK); 3555 3556 mCodec->changeState(mCodec->mLoadedToIdleState); 3557} 3558 3559//////////////////////////////////////////////////////////////////////////////// 3560 3561ACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec) 3562 : BaseState(codec) { 3563} 3564 3565void ACodec::LoadedToIdleState::stateEntered() { 3566 ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str()); 3567 3568 status_t err; 3569 if ((err = allocateBuffers()) != OK) { 3570 ALOGE("Failed to allocate buffers after transitioning to IDLE state " 3571 "(error 0x%08x)", 3572 err); 3573 3574 mCodec->signalError(OMX_ErrorUndefined, err); 3575 3576 mCodec->changeState(mCodec->mLoadedState); 3577 } 3578} 3579 3580status_t ACodec::LoadedToIdleState::allocateBuffers() { 3581 status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput); 3582 3583 if (err != OK) { 3584 return err; 3585 } 3586 3587 return mCodec->allocateBuffersOnPort(kPortIndexOutput); 3588} 3589 3590bool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) { 3591 switch (msg->what()) { 3592 case kWhatShutdown: 3593 { 3594 mCodec->deferMessage(msg); 3595 return true; 3596 } 3597 3598 case kWhatSignalEndOfInputStream: 3599 { 3600 mCodec->onSignalEndOfInputStream(); 3601 return true; 3602 } 3603 3604 case kWhatResume: 3605 { 3606 // We'll be active soon enough. 3607 return true; 3608 } 3609 3610 case kWhatFlush: 3611 { 3612 // We haven't even started yet, so we're flushed alright... 3613 sp<AMessage> notify = mCodec->mNotify->dup(); 3614 notify->setInt32("what", ACodec::kWhatFlushCompleted); 3615 notify->post(); 3616 return true; 3617 } 3618 3619 default: 3620 return BaseState::onMessageReceived(msg); 3621 } 3622} 3623 3624bool ACodec::LoadedToIdleState::onOMXEvent( 3625 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 3626 switch (event) { 3627 case OMX_EventCmdComplete: 3628 { 3629 CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet); 3630 CHECK_EQ(data2, (OMX_U32)OMX_StateIdle); 3631 3632 CHECK_EQ(mCodec->mOMX->sendCommand( 3633 mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting), 3634 (status_t)OK); 3635 3636 mCodec->changeState(mCodec->mIdleToExecutingState); 3637 3638 return true; 3639 } 3640 3641 default: 3642 return BaseState::onOMXEvent(event, data1, data2); 3643 } 3644} 3645 3646//////////////////////////////////////////////////////////////////////////////// 3647 3648ACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec) 3649 : BaseState(codec) { 3650} 3651 3652void ACodec::IdleToExecutingState::stateEntered() { 3653 ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str()); 3654} 3655 3656bool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) { 3657 switch (msg->what()) { 3658 case kWhatShutdown: 3659 { 3660 mCodec->deferMessage(msg); 3661 return true; 3662 } 3663 3664 case kWhatResume: 3665 { 3666 // We'll be active soon enough. 3667 return true; 3668 } 3669 3670 case kWhatFlush: 3671 { 3672 // We haven't even started yet, so we're flushed alright... 3673 sp<AMessage> notify = mCodec->mNotify->dup(); 3674 notify->setInt32("what", ACodec::kWhatFlushCompleted); 3675 notify->post(); 3676 3677 return true; 3678 } 3679 3680 case kWhatSignalEndOfInputStream: 3681 { 3682 mCodec->onSignalEndOfInputStream(); 3683 return true; 3684 } 3685 3686 default: 3687 return BaseState::onMessageReceived(msg); 3688 } 3689} 3690 3691bool ACodec::IdleToExecutingState::onOMXEvent( 3692 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 3693 switch (event) { 3694 case OMX_EventCmdComplete: 3695 { 3696 CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet); 3697 CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting); 3698 3699 mCodec->mExecutingState->resume(); 3700 mCodec->changeState(mCodec->mExecutingState); 3701 3702 return true; 3703 } 3704 3705 default: 3706 return BaseState::onOMXEvent(event, data1, data2); 3707 } 3708} 3709 3710//////////////////////////////////////////////////////////////////////////////// 3711 3712ACodec::ExecutingState::ExecutingState(ACodec *codec) 3713 : BaseState(codec), 3714 mActive(false) { 3715} 3716 3717ACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode( 3718 OMX_U32 portIndex) { 3719 return RESUBMIT_BUFFERS; 3720} 3721 3722void ACodec::ExecutingState::submitOutputBuffers() { 3723 for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) { 3724 BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i); 3725 3726 if (mCodec->mNativeWindow != NULL) { 3727 CHECK(info->mStatus == BufferInfo::OWNED_BY_US 3728 || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW); 3729 3730 if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) { 3731 continue; 3732 } 3733 } else { 3734 CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US); 3735 } 3736 3737 ALOGV("[%s] calling fillBuffer %p", 3738 mCodec->mComponentName.c_str(), info->mBufferID); 3739 3740 CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID), 3741 (status_t)OK); 3742 3743 info->mStatus = BufferInfo::OWNED_BY_COMPONENT; 3744 } 3745} 3746 3747void ACodec::ExecutingState::resume() { 3748 if (mActive) { 3749 ALOGV("[%s] We're already active, no need to resume.", 3750 mCodec->mComponentName.c_str()); 3751 3752 return; 3753 } 3754 3755 submitOutputBuffers(); 3756 3757 // Post the first input buffer. 3758 CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u); 3759 BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(0); 3760 3761 postFillThisBuffer(info); 3762 3763 mActive = true; 3764} 3765 3766void ACodec::ExecutingState::stateEntered() { 3767 ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str()); 3768 3769 mCodec->processDeferredMessages(); 3770} 3771 3772bool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) { 3773 bool handled = false; 3774 3775 switch (msg->what()) { 3776 case kWhatShutdown: 3777 { 3778 int32_t keepComponentAllocated; 3779 CHECK(msg->findInt32( 3780 "keepComponentAllocated", &keepComponentAllocated)); 3781 3782 mCodec->mShutdownInProgress = true; 3783 mCodec->mKeepComponentAllocated = keepComponentAllocated; 3784 3785 mActive = false; 3786 3787 CHECK_EQ(mCodec->mOMX->sendCommand( 3788 mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle), 3789 (status_t)OK); 3790 3791 mCodec->changeState(mCodec->mExecutingToIdleState); 3792 3793 handled = true; 3794 break; 3795 } 3796 3797 case kWhatFlush: 3798 { 3799 ALOGV("[%s] ExecutingState flushing now " 3800 "(codec owns %d/%d input, %d/%d output).", 3801 mCodec->mComponentName.c_str(), 3802 mCodec->countBuffersOwnedByComponent(kPortIndexInput), 3803 mCodec->mBuffers[kPortIndexInput].size(), 3804 mCodec->countBuffersOwnedByComponent(kPortIndexOutput), 3805 mCodec->mBuffers[kPortIndexOutput].size()); 3806 3807 mActive = false; 3808 3809 CHECK_EQ(mCodec->mOMX->sendCommand( 3810 mCodec->mNode, OMX_CommandFlush, OMX_ALL), 3811 (status_t)OK); 3812 3813 mCodec->changeState(mCodec->mFlushingState); 3814 handled = true; 3815 break; 3816 } 3817 3818 case kWhatResume: 3819 { 3820 resume(); 3821 3822 handled = true; 3823 break; 3824 } 3825 3826 case kWhatRequestIDRFrame: 3827 { 3828 status_t err = mCodec->requestIDRFrame(); 3829 if (err != OK) { 3830 ALOGW("Requesting an IDR frame failed."); 3831 } 3832 3833 handled = true; 3834 break; 3835 } 3836 3837 case kWhatSetParameters: 3838 { 3839 sp<AMessage> params; 3840 CHECK(msg->findMessage("params", ¶ms)); 3841 3842 status_t err = mCodec->setParameters(params); 3843 3844 sp<AMessage> reply; 3845 if (msg->findMessage("reply", &reply)) { 3846 reply->setInt32("err", err); 3847 reply->post(); 3848 } 3849 3850 handled = true; 3851 break; 3852 } 3853 3854 case ACodec::kWhatSignalEndOfInputStream: 3855 { 3856 mCodec->onSignalEndOfInputStream(); 3857 handled = true; 3858 break; 3859 } 3860 3861 default: 3862 handled = BaseState::onMessageReceived(msg); 3863 break; 3864 } 3865 3866 return handled; 3867} 3868 3869status_t ACodec::setParameters(const sp<AMessage> ¶ms) { 3870 int32_t videoBitrate; 3871 if (params->findInt32("videoBitrate", &videoBitrate)) { 3872 OMX_VIDEO_CONFIG_BITRATETYPE configParams; 3873 InitOMXParams(&configParams); 3874 configParams.nPortIndex = kPortIndexOutput; 3875 configParams.nEncodeBitrate = videoBitrate; 3876 3877 status_t err = mOMX->setConfig( 3878 mNode, 3879 OMX_IndexConfigVideoBitrate, 3880 &configParams, 3881 sizeof(configParams)); 3882 3883 if (err != OK) { 3884 ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d", 3885 videoBitrate, err); 3886 3887 return err; 3888 } 3889 } 3890 3891 return OK; 3892} 3893 3894void ACodec::onSignalEndOfInputStream() { 3895 sp<AMessage> notify = mNotify->dup(); 3896 notify->setInt32("what", ACodec::kWhatSignaledInputEOS); 3897 3898 status_t err = mOMX->signalEndOfInputStream(mNode); 3899 if (err != OK) { 3900 notify->setInt32("err", err); 3901 } 3902 notify->post(); 3903} 3904 3905bool ACodec::ExecutingState::onOMXEvent( 3906 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 3907 switch (event) { 3908 case OMX_EventPortSettingsChanged: 3909 { 3910 CHECK_EQ(data1, (OMX_U32)kPortIndexOutput); 3911 3912 if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) { 3913 CHECK_EQ(mCodec->mOMX->sendCommand( 3914 mCodec->mNode, 3915 OMX_CommandPortDisable, kPortIndexOutput), 3916 (status_t)OK); 3917 3918 mCodec->freeOutputBuffersNotOwnedByComponent(); 3919 3920 mCodec->changeState(mCodec->mOutputPortSettingsChangedState); 3921 } else if (data2 == OMX_IndexConfigCommonOutputCrop) { 3922 mCodec->mSentFormat = false; 3923 } else { 3924 ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08lx", 3925 mCodec->mComponentName.c_str(), data2); 3926 } 3927 3928 return true; 3929 } 3930 3931 case OMX_EventBufferFlag: 3932 { 3933 return true; 3934 } 3935 3936 default: 3937 return BaseState::onOMXEvent(event, data1, data2); 3938 } 3939} 3940 3941//////////////////////////////////////////////////////////////////////////////// 3942 3943ACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState( 3944 ACodec *codec) 3945 : BaseState(codec) { 3946} 3947 3948ACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode( 3949 OMX_U32 portIndex) { 3950 if (portIndex == kPortIndexOutput) { 3951 return FREE_BUFFERS; 3952 } 3953 3954 CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput); 3955 3956 return RESUBMIT_BUFFERS; 3957} 3958 3959bool ACodec::OutputPortSettingsChangedState::onMessageReceived( 3960 const sp<AMessage> &msg) { 3961 bool handled = false; 3962 3963 switch (msg->what()) { 3964 case kWhatFlush: 3965 case kWhatShutdown: 3966 case kWhatResume: 3967 { 3968 if (msg->what() == kWhatResume) { 3969 ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str()); 3970 } 3971 3972 mCodec->deferMessage(msg); 3973 handled = true; 3974 break; 3975 } 3976 3977 default: 3978 handled = BaseState::onMessageReceived(msg); 3979 break; 3980 } 3981 3982 return handled; 3983} 3984 3985void ACodec::OutputPortSettingsChangedState::stateEntered() { 3986 ALOGV("[%s] Now handling output port settings change", 3987 mCodec->mComponentName.c_str()); 3988} 3989 3990bool ACodec::OutputPortSettingsChangedState::onOMXEvent( 3991 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 3992 switch (event) { 3993 case OMX_EventCmdComplete: 3994 { 3995 if (data1 == (OMX_U32)OMX_CommandPortDisable) { 3996 CHECK_EQ(data2, (OMX_U32)kPortIndexOutput); 3997 3998 ALOGV("[%s] Output port now disabled.", 3999 mCodec->mComponentName.c_str()); 4000 4001 CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty()); 4002 mCodec->mDealer[kPortIndexOutput].clear(); 4003 4004 CHECK_EQ(mCodec->mOMX->sendCommand( 4005 mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput), 4006 (status_t)OK); 4007 4008 status_t err; 4009 if ((err = mCodec->allocateBuffersOnPort( 4010 kPortIndexOutput)) != OK) { 4011 ALOGE("Failed to allocate output port buffers after " 4012 "port reconfiguration (error 0x%08x)", 4013 err); 4014 4015 mCodec->signalError(OMX_ErrorUndefined, err); 4016 4017 // This is technically not correct, but appears to be 4018 // the only way to free the component instance. 4019 // Controlled transitioning from excecuting->idle 4020 // and idle->loaded seem impossible probably because 4021 // the output port never finishes re-enabling. 4022 mCodec->mShutdownInProgress = true; 4023 mCodec->mKeepComponentAllocated = false; 4024 mCodec->changeState(mCodec->mLoadedState); 4025 } 4026 4027 return true; 4028 } else if (data1 == (OMX_U32)OMX_CommandPortEnable) { 4029 CHECK_EQ(data2, (OMX_U32)kPortIndexOutput); 4030 4031 mCodec->mSentFormat = false; 4032 4033 ALOGV("[%s] Output port now reenabled.", 4034 mCodec->mComponentName.c_str()); 4035 4036 if (mCodec->mExecutingState->active()) { 4037 mCodec->mExecutingState->submitOutputBuffers(); 4038 } 4039 4040 mCodec->changeState(mCodec->mExecutingState); 4041 4042 return true; 4043 } 4044 4045 return false; 4046 } 4047 4048 default: 4049 return false; 4050 } 4051} 4052 4053//////////////////////////////////////////////////////////////////////////////// 4054 4055ACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec) 4056 : BaseState(codec), 4057 mComponentNowIdle(false) { 4058} 4059 4060bool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) { 4061 bool handled = false; 4062 4063 switch (msg->what()) { 4064 case kWhatFlush: 4065 { 4066 // Don't send me a flush request if you previously wanted me 4067 // to shutdown. 4068 TRESPASS(); 4069 break; 4070 } 4071 4072 case kWhatShutdown: 4073 { 4074 // We're already doing that... 4075 4076 handled = true; 4077 break; 4078 } 4079 4080 default: 4081 handled = BaseState::onMessageReceived(msg); 4082 break; 4083 } 4084 4085 return handled; 4086} 4087 4088void ACodec::ExecutingToIdleState::stateEntered() { 4089 ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str()); 4090 4091 mComponentNowIdle = false; 4092 mCodec->mSentFormat = false; 4093} 4094 4095bool ACodec::ExecutingToIdleState::onOMXEvent( 4096 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 4097 switch (event) { 4098 case OMX_EventCmdComplete: 4099 { 4100 CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet); 4101 CHECK_EQ(data2, (OMX_U32)OMX_StateIdle); 4102 4103 mComponentNowIdle = true; 4104 4105 changeStateIfWeOwnAllBuffers(); 4106 4107 return true; 4108 } 4109 4110 case OMX_EventPortSettingsChanged: 4111 case OMX_EventBufferFlag: 4112 { 4113 // We're shutting down and don't care about this anymore. 4114 return true; 4115 } 4116 4117 default: 4118 return BaseState::onOMXEvent(event, data1, data2); 4119 } 4120} 4121 4122void ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() { 4123 if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) { 4124 CHECK_EQ(mCodec->mOMX->sendCommand( 4125 mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded), 4126 (status_t)OK); 4127 4128 CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK); 4129 CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK); 4130 4131 if (mCodec->mFlags & kFlagIsSecure && mCodec->mNativeWindow != NULL) { 4132 // We push enough 1x1 blank buffers to ensure that one of 4133 // them has made it to the display. This allows the OMX 4134 // component teardown to zero out any protected buffers 4135 // without the risk of scanning out one of those buffers. 4136 mCodec->pushBlankBuffersToNativeWindow(); 4137 } 4138 4139 mCodec->changeState(mCodec->mIdleToLoadedState); 4140 } 4141} 4142 4143void ACodec::ExecutingToIdleState::onInputBufferFilled( 4144 const sp<AMessage> &msg) { 4145 BaseState::onInputBufferFilled(msg); 4146 4147 changeStateIfWeOwnAllBuffers(); 4148} 4149 4150void ACodec::ExecutingToIdleState::onOutputBufferDrained( 4151 const sp<AMessage> &msg) { 4152 BaseState::onOutputBufferDrained(msg); 4153 4154 changeStateIfWeOwnAllBuffers(); 4155} 4156 4157//////////////////////////////////////////////////////////////////////////////// 4158 4159ACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec) 4160 : BaseState(codec) { 4161} 4162 4163bool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) { 4164 bool handled = false; 4165 4166 switch (msg->what()) { 4167 case kWhatShutdown: 4168 { 4169 // We're already doing that... 4170 4171 handled = true; 4172 break; 4173 } 4174 4175 case kWhatFlush: 4176 { 4177 // Don't send me a flush request if you previously wanted me 4178 // to shutdown. 4179 TRESPASS(); 4180 break; 4181 } 4182 4183 default: 4184 handled = BaseState::onMessageReceived(msg); 4185 break; 4186 } 4187 4188 return handled; 4189} 4190 4191void ACodec::IdleToLoadedState::stateEntered() { 4192 ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str()); 4193} 4194 4195bool ACodec::IdleToLoadedState::onOMXEvent( 4196 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 4197 switch (event) { 4198 case OMX_EventCmdComplete: 4199 { 4200 CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet); 4201 CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded); 4202 4203 mCodec->changeState(mCodec->mLoadedState); 4204 4205 return true; 4206 } 4207 4208 default: 4209 return BaseState::onOMXEvent(event, data1, data2); 4210 } 4211} 4212 4213//////////////////////////////////////////////////////////////////////////////// 4214 4215ACodec::FlushingState::FlushingState(ACodec *codec) 4216 : BaseState(codec) { 4217} 4218 4219void ACodec::FlushingState::stateEntered() { 4220 ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str()); 4221 4222 mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false; 4223} 4224 4225bool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) { 4226 bool handled = false; 4227 4228 switch (msg->what()) { 4229 case kWhatShutdown: 4230 { 4231 mCodec->deferMessage(msg); 4232 break; 4233 } 4234 4235 case kWhatFlush: 4236 { 4237 // We're already doing this right now. 4238 handled = true; 4239 break; 4240 } 4241 4242 default: 4243 handled = BaseState::onMessageReceived(msg); 4244 break; 4245 } 4246 4247 return handled; 4248} 4249 4250bool ACodec::FlushingState::onOMXEvent( 4251 OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { 4252 ALOGV("[%s] FlushingState onOMXEvent(%d,%ld)", 4253 mCodec->mComponentName.c_str(), event, data1); 4254 4255 switch (event) { 4256 case OMX_EventCmdComplete: 4257 { 4258 CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush); 4259 4260 if (data2 == kPortIndexInput || data2 == kPortIndexOutput) { 4261 CHECK(!mFlushComplete[data2]); 4262 mFlushComplete[data2] = true; 4263 4264 if (mFlushComplete[kPortIndexInput] 4265 && mFlushComplete[kPortIndexOutput]) { 4266 changeStateIfWeOwnAllBuffers(); 4267 } 4268 } else { 4269 CHECK_EQ(data2, OMX_ALL); 4270 CHECK(mFlushComplete[kPortIndexInput]); 4271 CHECK(mFlushComplete[kPortIndexOutput]); 4272 4273 changeStateIfWeOwnAllBuffers(); 4274 } 4275 4276 return true; 4277 } 4278 4279 case OMX_EventPortSettingsChanged: 4280 { 4281 sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id()); 4282 msg->setInt32("type", omx_message::EVENT); 4283 msg->setPointer("node", mCodec->mNode); 4284 msg->setInt32("event", event); 4285 msg->setInt32("data1", data1); 4286 msg->setInt32("data2", data2); 4287 4288 ALOGV("[%s] Deferring OMX_EventPortSettingsChanged", 4289 mCodec->mComponentName.c_str()); 4290 4291 mCodec->deferMessage(msg); 4292 4293 return true; 4294 } 4295 4296 default: 4297 return BaseState::onOMXEvent(event, data1, data2); 4298 } 4299 4300 return true; 4301} 4302 4303void ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) { 4304 BaseState::onOutputBufferDrained(msg); 4305 4306 changeStateIfWeOwnAllBuffers(); 4307} 4308 4309void ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) { 4310 BaseState::onInputBufferFilled(msg); 4311 4312 changeStateIfWeOwnAllBuffers(); 4313} 4314 4315void ACodec::FlushingState::changeStateIfWeOwnAllBuffers() { 4316 if (mFlushComplete[kPortIndexInput] 4317 && mFlushComplete[kPortIndexOutput] 4318 && mCodec->allYourBuffersAreBelongToUs()) { 4319 // We now own all buffers except possibly those still queued with 4320 // the native window for rendering. Let's get those back as well. 4321 mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs(); 4322 4323 sp<AMessage> notify = mCodec->mNotify->dup(); 4324 notify->setInt32("what", ACodec::kWhatFlushCompleted); 4325 notify->post(); 4326 4327 mCodec->mPortEOS[kPortIndexInput] = 4328 mCodec->mPortEOS[kPortIndexOutput] = false; 4329 4330 mCodec->mInputEOSResult = OK; 4331 4332 if (mCodec->mSkipCutBuffer != NULL) { 4333 mCodec->mSkipCutBuffer->clear(); 4334 } 4335 4336 mCodec->changeState(mCodec->mExecutingState); 4337 } 4338} 4339 4340} // namespace android 4341