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