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