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