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