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 #ifdef __LP64__
     21 #define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
     22 #endif
     23 
     24 #include <inttypes.h>
     25 #include <utils/Trace.h>
     26 
     27 #include <media/stagefright/ACodec.h>
     28 
     29 #include <binder/MemoryDealer.h>
     30 
     31 #include <media/stagefright/foundation/hexdump.h>
     32 #include <media/stagefright/foundation/ABuffer.h>
     33 #include <media/stagefright/foundation/ADebug.h>
     34 #include <media/stagefright/foundation/AMessage.h>
     35 #include <media/stagefright/foundation/AUtils.h>
     36 
     37 #include <media/stagefright/BufferProducerWrapper.h>
     38 #include <media/stagefright/MediaCodecList.h>
     39 #include <media/stagefright/MediaDefs.h>
     40 #include <media/stagefright/NativeWindowWrapper.h>
     41 #include <media/stagefright/OMXClient.h>
     42 #include <media/stagefright/OMXCodec.h>
     43 
     44 #include <media/hardware/HardwareAPI.h>
     45 
     46 #include <OMX_AudioExt.h>
     47 #include <OMX_VideoExt.h>
     48 #include <OMX_Component.h>
     49 #include <OMX_IndexExt.h>
     50 
     51 #include "include/avc_utils.h"
     52 
     53 namespace android {
     54 
     55 // OMX errors are directly mapped into status_t range if
     56 // there is no corresponding MediaError status code.
     57 // Use the statusFromOMXError(int32_t omxError) function.
     58 //
     59 // Currently this is a direct map.
     60 // See frameworks/native/include/media/openmax/OMX_Core.h
     61 //
     62 // Vendor OMX errors     from 0x90000000 - 0x9000FFFF
     63 // Extension OMX errors  from 0x8F000000 - 0x90000000
     64 // Standard OMX errors   from 0x80001000 - 0x80001024 (0x80001024 current)
     65 //
     66 
     67 // returns true if err is a recognized OMX error code.
     68 // as OMX error is OMX_S32, this is an int32_t type
     69 static inline bool isOMXError(int32_t err) {
     70     return (ERROR_CODEC_MIN <= err && err <= ERROR_CODEC_MAX);
     71 }
     72 
     73 // converts an OMX error to a status_t
     74 static inline status_t statusFromOMXError(int32_t omxError) {
     75     switch (omxError) {
     76     case OMX_ErrorInvalidComponentName:
     77     case OMX_ErrorComponentNotFound:
     78         return NAME_NOT_FOUND; // can trigger illegal argument error for provided names.
     79     default:
     80         return isOMXError(omxError) ? omxError : 0; // no translation required
     81     }
     82 }
     83 
     84 // checks and converts status_t to a non-side-effect status_t
     85 static inline status_t makeNoSideEffectStatus(status_t err) {
     86     switch (err) {
     87     // the following errors have side effects and may come
     88     // from other code modules. Remap for safety reasons.
     89     case INVALID_OPERATION:
     90     case DEAD_OBJECT:
     91         return UNKNOWN_ERROR;
     92     default:
     93         return err;
     94     }
     95 }
     96 
     97 template<class T>
     98 static void InitOMXParams(T *params) {
     99     params->nSize = sizeof(T);
    100     params->nVersion.s.nVersionMajor = 1;
    101     params->nVersion.s.nVersionMinor = 0;
    102     params->nVersion.s.nRevision = 0;
    103     params->nVersion.s.nStep = 0;
    104 }
    105 
    106 struct CodecObserver : public BnOMXObserver {
    107     CodecObserver() {}
    108 
    109     void setNotificationMessage(const sp<AMessage> &msg) {
    110         mNotify = msg;
    111     }
    112 
    113     // from IOMXObserver
    114     virtual void onMessage(const omx_message &omx_msg) {
    115         sp<AMessage> msg = mNotify->dup();
    116 
    117         msg->setInt32("type", omx_msg.type);
    118         msg->setInt32("node", omx_msg.node);
    119 
    120         switch (omx_msg.type) {
    121             case omx_message::EVENT:
    122             {
    123                 msg->setInt32("event", omx_msg.u.event_data.event);
    124                 msg->setInt32("data1", omx_msg.u.event_data.data1);
    125                 msg->setInt32("data2", omx_msg.u.event_data.data2);
    126                 break;
    127             }
    128 
    129             case omx_message::EMPTY_BUFFER_DONE:
    130             {
    131                 msg->setInt32("buffer", omx_msg.u.buffer_data.buffer);
    132                 break;
    133             }
    134 
    135             case omx_message::FILL_BUFFER_DONE:
    136             {
    137                 msg->setInt32(
    138                         "buffer", omx_msg.u.extended_buffer_data.buffer);
    139                 msg->setInt32(
    140                         "range_offset",
    141                         omx_msg.u.extended_buffer_data.range_offset);
    142                 msg->setInt32(
    143                         "range_length",
    144                         omx_msg.u.extended_buffer_data.range_length);
    145                 msg->setInt32(
    146                         "flags",
    147                         omx_msg.u.extended_buffer_data.flags);
    148                 msg->setInt64(
    149                         "timestamp",
    150                         omx_msg.u.extended_buffer_data.timestamp);
    151                 break;
    152             }
    153 
    154             default:
    155                 TRESPASS();
    156                 break;
    157         }
    158 
    159         msg->post();
    160     }
    161 
    162 protected:
    163     virtual ~CodecObserver() {}
    164 
    165 private:
    166     sp<AMessage> mNotify;
    167 
    168     DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
    169 };
    170 
    171 ////////////////////////////////////////////////////////////////////////////////
    172 
    173 struct ACodec::BaseState : public AState {
    174     BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
    175 
    176 protected:
    177     enum PortMode {
    178         KEEP_BUFFERS,
    179         RESUBMIT_BUFFERS,
    180         FREE_BUFFERS,
    181     };
    182 
    183     ACodec *mCodec;
    184 
    185     virtual PortMode getPortMode(OMX_U32 portIndex);
    186 
    187     virtual bool onMessageReceived(const sp<AMessage> &msg);
    188 
    189     virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
    190 
    191     virtual void onOutputBufferDrained(const sp<AMessage> &msg);
    192     virtual void onInputBufferFilled(const sp<AMessage> &msg);
    193 
    194     void postFillThisBuffer(BufferInfo *info);
    195 
    196 private:
    197     bool onOMXMessage(const sp<AMessage> &msg);
    198 
    199     bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID);
    200 
    201     bool onOMXFillBufferDone(
    202             IOMX::buffer_id bufferID,
    203             size_t rangeOffset, size_t rangeLength,
    204             OMX_U32 flags,
    205             int64_t timeUs);
    206 
    207     void getMoreInputDataIfPossible();
    208 
    209     DISALLOW_EVIL_CONSTRUCTORS(BaseState);
    210 };
    211 
    212 ////////////////////////////////////////////////////////////////////////////////
    213 
    214 struct ACodec::DeathNotifier : public IBinder::DeathRecipient {
    215     DeathNotifier(const sp<AMessage> &notify)
    216         : mNotify(notify) {
    217     }
    218 
    219     virtual void binderDied(const wp<IBinder> &) {
    220         mNotify->post();
    221     }
    222 
    223 protected:
    224     virtual ~DeathNotifier() {}
    225 
    226 private:
    227     sp<AMessage> mNotify;
    228 
    229     DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier);
    230 };
    231 
    232 struct ACodec::UninitializedState : public ACodec::BaseState {
    233     UninitializedState(ACodec *codec);
    234 
    235 protected:
    236     virtual bool onMessageReceived(const sp<AMessage> &msg);
    237     virtual void stateEntered();
    238 
    239 private:
    240     void onSetup(const sp<AMessage> &msg);
    241     bool onAllocateComponent(const sp<AMessage> &msg);
    242 
    243     sp<DeathNotifier> mDeathNotifier;
    244 
    245     DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
    246 };
    247 
    248 ////////////////////////////////////////////////////////////////////////////////
    249 
    250 struct ACodec::LoadedState : public ACodec::BaseState {
    251     LoadedState(ACodec *codec);
    252 
    253 protected:
    254     virtual bool onMessageReceived(const sp<AMessage> &msg);
    255     virtual void stateEntered();
    256 
    257 private:
    258     friend struct ACodec::UninitializedState;
    259 
    260     bool onConfigureComponent(const sp<AMessage> &msg);
    261     void onCreateInputSurface(const sp<AMessage> &msg);
    262     void onStart();
    263     void onShutdown(bool keepComponentAllocated);
    264 
    265     DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
    266 };
    267 
    268 ////////////////////////////////////////////////////////////////////////////////
    269 
    270 struct ACodec::LoadedToIdleState : public ACodec::BaseState {
    271     LoadedToIdleState(ACodec *codec);
    272 
    273 protected:
    274     virtual bool onMessageReceived(const sp<AMessage> &msg);
    275     virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
    276     virtual void stateEntered();
    277 
    278 private:
    279     status_t allocateBuffers();
    280 
    281     DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
    282 };
    283 
    284 ////////////////////////////////////////////////////////////////////////////////
    285 
    286 struct ACodec::IdleToExecutingState : public ACodec::BaseState {
    287     IdleToExecutingState(ACodec *codec);
    288 
    289 protected:
    290     virtual bool onMessageReceived(const sp<AMessage> &msg);
    291     virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
    292     virtual void stateEntered();
    293 
    294 private:
    295     DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
    296 };
    297 
    298 ////////////////////////////////////////////////////////////////////////////////
    299 
    300 struct ACodec::ExecutingState : public ACodec::BaseState {
    301     ExecutingState(ACodec *codec);
    302 
    303     void submitRegularOutputBuffers();
    304     void submitOutputMetaBuffers();
    305     void submitOutputBuffers();
    306 
    307     // Submit output buffers to the decoder, submit input buffers to client
    308     // to fill with data.
    309     void resume();
    310 
    311     // Returns true iff input and output buffers are in play.
    312     bool active() const { return mActive; }
    313 
    314 protected:
    315     virtual PortMode getPortMode(OMX_U32 portIndex);
    316     virtual bool onMessageReceived(const sp<AMessage> &msg);
    317     virtual void stateEntered();
    318 
    319     virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
    320 
    321 private:
    322     bool mActive;
    323 
    324     DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
    325 };
    326 
    327 ////////////////////////////////////////////////////////////////////////////////
    328 
    329 struct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
    330     OutputPortSettingsChangedState(ACodec *codec);
    331 
    332 protected:
    333     virtual PortMode getPortMode(OMX_U32 portIndex);
    334     virtual bool onMessageReceived(const sp<AMessage> &msg);
    335     virtual void stateEntered();
    336 
    337     virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
    338 
    339 private:
    340     DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
    341 };
    342 
    343 ////////////////////////////////////////////////////////////////////////////////
    344 
    345 struct ACodec::ExecutingToIdleState : public ACodec::BaseState {
    346     ExecutingToIdleState(ACodec *codec);
    347 
    348 protected:
    349     virtual bool onMessageReceived(const sp<AMessage> &msg);
    350     virtual void stateEntered();
    351 
    352     virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
    353 
    354     virtual void onOutputBufferDrained(const sp<AMessage> &msg);
    355     virtual void onInputBufferFilled(const sp<AMessage> &msg);
    356 
    357 private:
    358     void changeStateIfWeOwnAllBuffers();
    359 
    360     bool mComponentNowIdle;
    361 
    362     DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
    363 };
    364 
    365 ////////////////////////////////////////////////////////////////////////////////
    366 
    367 struct ACodec::IdleToLoadedState : public ACodec::BaseState {
    368     IdleToLoadedState(ACodec *codec);
    369 
    370 protected:
    371     virtual bool onMessageReceived(const sp<AMessage> &msg);
    372     virtual void stateEntered();
    373 
    374     virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
    375 
    376 private:
    377     DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
    378 };
    379 
    380 ////////////////////////////////////////////////////////////////////////////////
    381 
    382 struct ACodec::FlushingState : public ACodec::BaseState {
    383     FlushingState(ACodec *codec);
    384 
    385 protected:
    386     virtual bool onMessageReceived(const sp<AMessage> &msg);
    387     virtual void stateEntered();
    388 
    389     virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
    390 
    391     virtual void onOutputBufferDrained(const sp<AMessage> &msg);
    392     virtual void onInputBufferFilled(const sp<AMessage> &msg);
    393 
    394 private:
    395     bool mFlushComplete[2];
    396 
    397     void changeStateIfWeOwnAllBuffers();
    398 
    399     DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
    400 };
    401 
    402 ////////////////////////////////////////////////////////////////////////////////
    403 
    404 ACodec::ACodec()
    405     : mQuirks(0),
    406       mNode(0),
    407       mSentFormat(false),
    408       mIsEncoder(false),
    409       mUseMetadataOnEncoderOutput(false),
    410       mShutdownInProgress(false),
    411       mExplicitShutdown(false),
    412       mEncoderDelay(0),
    413       mEncoderPadding(0),
    414       mRotationDegrees(0),
    415       mChannelMaskPresent(false),
    416       mChannelMask(0),
    417       mDequeueCounter(0),
    418       mStoreMetaDataInOutputBuffers(false),
    419       mMetaDataBuffersToSubmit(0),
    420       mRepeatFrameDelayUs(-1ll),
    421       mMaxPtsGapUs(-1ll),
    422       mTimePerFrameUs(-1ll),
    423       mTimePerCaptureUs(-1ll),
    424       mCreateInputBuffersSuspended(false),
    425       mTunneled(false) {
    426     mUninitializedState = new UninitializedState(this);
    427     mLoadedState = new LoadedState(this);
    428     mLoadedToIdleState = new LoadedToIdleState(this);
    429     mIdleToExecutingState = new IdleToExecutingState(this);
    430     mExecutingState = new ExecutingState(this);
    431 
    432     mOutputPortSettingsChangedState =
    433         new OutputPortSettingsChangedState(this);
    434 
    435     mExecutingToIdleState = new ExecutingToIdleState(this);
    436     mIdleToLoadedState = new IdleToLoadedState(this);
    437     mFlushingState = new FlushingState(this);
    438 
    439     mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
    440     mInputEOSResult = OK;
    441 
    442     changeState(mUninitializedState);
    443 }
    444 
    445 ACodec::~ACodec() {
    446 }
    447 
    448 void ACodec::setNotificationMessage(const sp<AMessage> &msg) {
    449     mNotify = msg;
    450 }
    451 
    452 void ACodec::initiateSetup(const sp<AMessage> &msg) {
    453     msg->setWhat(kWhatSetup);
    454     msg->setTarget(id());
    455     msg->post();
    456 }
    457 
    458 void ACodec::signalSetParameters(const sp<AMessage> &params) {
    459     sp<AMessage> msg = new AMessage(kWhatSetParameters, id());
    460     msg->setMessage("params", params);
    461     msg->post();
    462 }
    463 
    464 void ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
    465     msg->setWhat(kWhatAllocateComponent);
    466     msg->setTarget(id());
    467     msg->post();
    468 }
    469 
    470 void ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
    471     msg->setWhat(kWhatConfigureComponent);
    472     msg->setTarget(id());
    473     msg->post();
    474 }
    475 
    476 void ACodec::initiateCreateInputSurface() {
    477     (new AMessage(kWhatCreateInputSurface, id()))->post();
    478 }
    479 
    480 void ACodec::signalEndOfInputStream() {
    481     (new AMessage(kWhatSignalEndOfInputStream, id()))->post();
    482 }
    483 
    484 void ACodec::initiateStart() {
    485     (new AMessage(kWhatStart, id()))->post();
    486 }
    487 
    488 void ACodec::signalFlush() {
    489     ALOGV("[%s] signalFlush", mComponentName.c_str());
    490     (new AMessage(kWhatFlush, id()))->post();
    491 }
    492 
    493 void ACodec::signalResume() {
    494     (new AMessage(kWhatResume, id()))->post();
    495 }
    496 
    497 void ACodec::initiateShutdown(bool keepComponentAllocated) {
    498     sp<AMessage> msg = new AMessage(kWhatShutdown, id());
    499     msg->setInt32("keepComponentAllocated", keepComponentAllocated);
    500     msg->post();
    501     if (!keepComponentAllocated) {
    502         // ensure shutdown completes in 3 seconds
    503         (new AMessage(kWhatReleaseCodecInstance, id()))->post(3000000);
    504     }
    505 }
    506 
    507 void ACodec::signalRequestIDRFrame() {
    508     (new AMessage(kWhatRequestIDRFrame, id()))->post();
    509 }
    510 
    511 // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
    512 // Some codecs may return input buffers before having them processed.
    513 // This causes a halt if we already signaled an EOS on the input
    514 // port.  For now keep submitting an output buffer if there was an
    515 // EOS on the input port, but not yet on the output port.
    516 void ACodec::signalSubmitOutputMetaDataBufferIfEOS_workaround() {
    517     if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] &&
    518             mMetaDataBuffersToSubmit > 0) {
    519         (new AMessage(kWhatSubmitOutputMetaDataBufferIfEOS, id()))->post();
    520     }
    521 }
    522 
    523 status_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
    524     CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
    525 
    526     CHECK(mDealer[portIndex] == NULL);
    527     CHECK(mBuffers[portIndex].isEmpty());
    528 
    529     status_t err;
    530     if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
    531         if (mStoreMetaDataInOutputBuffers) {
    532             err = allocateOutputMetaDataBuffers();
    533         } else {
    534             err = allocateOutputBuffersFromNativeWindow();
    535         }
    536     } else {
    537         OMX_PARAM_PORTDEFINITIONTYPE def;
    538         InitOMXParams(&def);
    539         def.nPortIndex = portIndex;
    540 
    541         err = mOMX->getParameter(
    542                 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
    543 
    544         if (err == OK) {
    545             ALOGV("[%s] Allocating %u buffers of size %u on %s port",
    546                     mComponentName.c_str(),
    547                     def.nBufferCountActual, def.nBufferSize,
    548                     portIndex == kPortIndexInput ? "input" : "output");
    549 
    550             size_t totalSize = def.nBufferCountActual * def.nBufferSize;
    551             mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
    552 
    553             for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
    554                 sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
    555                 CHECK(mem.get() != NULL);
    556 
    557                 BufferInfo info;
    558                 info.mStatus = BufferInfo::OWNED_BY_US;
    559 
    560                 uint32_t requiresAllocateBufferBit =
    561                     (portIndex == kPortIndexInput)
    562                         ? OMXCodec::kRequiresAllocateBufferOnInputPorts
    563                         : OMXCodec::kRequiresAllocateBufferOnOutputPorts;
    564 
    565                 if ((portIndex == kPortIndexInput && (mFlags & kFlagIsSecure))
    566                         || mUseMetadataOnEncoderOutput) {
    567                     mem.clear();
    568 
    569                     void *ptr;
    570                     err = mOMX->allocateBuffer(
    571                             mNode, portIndex, def.nBufferSize, &info.mBufferID,
    572                             &ptr);
    573 
    574                     int32_t bufSize = mUseMetadataOnEncoderOutput ?
    575                             (4 + sizeof(buffer_handle_t)) : def.nBufferSize;
    576 
    577                     info.mData = new ABuffer(ptr, bufSize);
    578                 } else if (mQuirks & requiresAllocateBufferBit) {
    579                     err = mOMX->allocateBufferWithBackup(
    580                             mNode, portIndex, mem, &info.mBufferID);
    581                 } else {
    582                     err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID);
    583                 }
    584 
    585                 if (mem != NULL) {
    586                     info.mData = new ABuffer(mem->pointer(), def.nBufferSize);
    587                 }
    588 
    589                 mBuffers[portIndex].push(info);
    590             }
    591         }
    592     }
    593 
    594     if (err != OK) {
    595         return err;
    596     }
    597 
    598     sp<AMessage> notify = mNotify->dup();
    599     notify->setInt32("what", CodecBase::kWhatBuffersAllocated);
    600 
    601     notify->setInt32("portIndex", portIndex);
    602 
    603     sp<PortDescription> desc = new PortDescription;
    604 
    605     for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
    606         const BufferInfo &info = mBuffers[portIndex][i];
    607 
    608         desc->addBuffer(info.mBufferID, info.mData);
    609     }
    610 
    611     notify->setObject("portDesc", desc);
    612     notify->post();
    613 
    614     return OK;
    615 }
    616 
    617 status_t ACodec::configureOutputBuffersFromNativeWindow(
    618         OMX_U32 *bufferCount, OMX_U32 *bufferSize,
    619         OMX_U32 *minUndequeuedBuffers) {
    620     OMX_PARAM_PORTDEFINITIONTYPE def;
    621     InitOMXParams(&def);
    622     def.nPortIndex = kPortIndexOutput;
    623 
    624     status_t err = mOMX->getParameter(
    625             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
    626 
    627     if (err != OK) {
    628         return err;
    629     }
    630 
    631     err = native_window_set_buffers_geometry(
    632             mNativeWindow.get(),
    633             def.format.video.nFrameWidth,
    634             def.format.video.nFrameHeight,
    635             def.format.video.eColorFormat);
    636 
    637     if (err != 0) {
    638         ALOGE("native_window_set_buffers_geometry failed: %s (%d)",
    639                 strerror(-err), -err);
    640         return err;
    641     }
    642 
    643     if (mRotationDegrees != 0) {
    644         uint32_t transform = 0;
    645         switch (mRotationDegrees) {
    646             case 0: transform = 0; break;
    647             case 90: transform = HAL_TRANSFORM_ROT_90; break;
    648             case 180: transform = HAL_TRANSFORM_ROT_180; break;
    649             case 270: transform = HAL_TRANSFORM_ROT_270; break;
    650             default: transform = 0; break;
    651         }
    652 
    653         if (transform > 0) {
    654             err = native_window_set_buffers_transform(
    655                     mNativeWindow.get(), transform);
    656             if (err != 0) {
    657                 ALOGE("native_window_set_buffers_transform failed: %s (%d)",
    658                         strerror(-err), -err);
    659                 return err;
    660             }
    661         }
    662     }
    663 
    664     // Set up the native window.
    665     OMX_U32 usage = 0;
    666     err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
    667     if (err != 0) {
    668         ALOGW("querying usage flags from OMX IL component failed: %d", err);
    669         // XXX: Currently this error is logged, but not fatal.
    670         usage = 0;
    671     }
    672 
    673     if (mFlags & kFlagIsSecure) {
    674         usage |= GRALLOC_USAGE_PROTECTED;
    675     }
    676 
    677     // Make sure to check whether either Stagefright or the video decoder
    678     // requested protected buffers.
    679     if (usage & GRALLOC_USAGE_PROTECTED) {
    680         // Verify that the ANativeWindow sends images directly to
    681         // SurfaceFlinger.
    682         int queuesToNativeWindow = 0;
    683         err = mNativeWindow->query(
    684                 mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
    685                 &queuesToNativeWindow);
    686         if (err != 0) {
    687             ALOGE("error authenticating native window: %d", err);
    688             return err;
    689         }
    690         if (queuesToNativeWindow != 1) {
    691             ALOGE("native window could not be authenticated");
    692             return PERMISSION_DENIED;
    693         }
    694     }
    695 
    696     err = native_window_set_usage(
    697             mNativeWindow.get(),
    698             usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
    699 
    700     if (err != 0) {
    701         ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
    702         return err;
    703     }
    704 
    705     // Exits here for tunneled video playback codecs -- i.e. skips native window
    706     // buffer allocation step as this is managed by the tunneled OMX omponent
    707     // itself and explicitly sets def.nBufferCountActual to 0.
    708     if (mTunneled) {
    709         ALOGV("Tunneled Playback: skipping native window buffer allocation.");
    710         def.nBufferCountActual = 0;
    711         err = mOMX->setParameter(
    712                 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
    713 
    714         *minUndequeuedBuffers = 0;
    715         *bufferCount = 0;
    716         *bufferSize = 0;
    717         return err;
    718     }
    719 
    720     *minUndequeuedBuffers = 0;
    721     err = mNativeWindow->query(
    722             mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
    723             (int *)minUndequeuedBuffers);
    724 
    725     if (err != 0) {
    726         ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
    727                 strerror(-err), -err);
    728         return err;
    729     }
    730 
    731     // FIXME: assume that surface is controlled by app (native window
    732     // returns the number for the case when surface is not controlled by app)
    733     // FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported
    734     // For now, try to allocate 1 more buffer, but don't fail if unsuccessful
    735 
    736     // Use conservative allocation while also trying to reduce starvation
    737     //
    738     // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the
    739     //    minimum needed for the consumer to be able to work
    740     // 2. try to allocate two (2) additional buffers to reduce starvation from
    741     //    the consumer
    742     //    plus an extra buffer to account for incorrect minUndequeuedBufs
    743     for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) {
    744         OMX_U32 newBufferCount =
    745             def.nBufferCountMin + *minUndequeuedBuffers + extraBuffers;
    746         def.nBufferCountActual = newBufferCount;
    747         err = mOMX->setParameter(
    748                 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
    749 
    750         if (err == OK) {
    751             *minUndequeuedBuffers += extraBuffers;
    752             break;
    753         }
    754 
    755         ALOGW("[%s] setting nBufferCountActual to %u failed: %d",
    756                 mComponentName.c_str(), newBufferCount, err);
    757         /* exit condition */
    758         if (extraBuffers == 0) {
    759             return err;
    760         }
    761     }
    762 
    763     err = native_window_set_buffer_count(
    764             mNativeWindow.get(), def.nBufferCountActual);
    765 
    766     if (err != 0) {
    767         ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
    768                 -err);
    769         return err;
    770     }
    771 
    772     *bufferCount = def.nBufferCountActual;
    773     *bufferSize =  def.nBufferSize;
    774     return err;
    775 }
    776 
    777 status_t ACodec::allocateOutputBuffersFromNativeWindow() {
    778     OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
    779     status_t err = configureOutputBuffersFromNativeWindow(
    780             &bufferCount, &bufferSize, &minUndequeuedBuffers);
    781     if (err != 0)
    782         return err;
    783     mNumUndequeuedBuffers = minUndequeuedBuffers;
    784 
    785     ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
    786          "output port",
    787          mComponentName.c_str(), bufferCount, bufferSize);
    788 
    789     // Dequeue buffers and send them to OMX
    790     for (OMX_U32 i = 0; i < bufferCount; i++) {
    791         ANativeWindowBuffer *buf;
    792         err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
    793         if (err != 0) {
    794             ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
    795             break;
    796         }
    797 
    798         sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
    799         BufferInfo info;
    800         info.mStatus = BufferInfo::OWNED_BY_US;
    801         info.mData = new ABuffer(NULL /* data */, bufferSize /* capacity */);
    802         info.mGraphicBuffer = graphicBuffer;
    803         mBuffers[kPortIndexOutput].push(info);
    804 
    805         IOMX::buffer_id bufferId;
    806         err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
    807                 &bufferId);
    808         if (err != 0) {
    809             ALOGE("registering GraphicBuffer %u with OMX IL component failed: "
    810                  "%d", i, err);
    811             break;
    812         }
    813 
    814         mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
    815 
    816         ALOGV("[%s] Registered graphic buffer with ID %u (pointer = %p)",
    817              mComponentName.c_str(),
    818              bufferId, graphicBuffer.get());
    819     }
    820 
    821     OMX_U32 cancelStart;
    822     OMX_U32 cancelEnd;
    823 
    824     if (err != 0) {
    825         // If an error occurred while dequeuing we need to cancel any buffers
    826         // that were dequeued.
    827         cancelStart = 0;
    828         cancelEnd = mBuffers[kPortIndexOutput].size();
    829     } else {
    830         // Return the required minimum undequeued buffers to the native window.
    831         cancelStart = bufferCount - minUndequeuedBuffers;
    832         cancelEnd = bufferCount;
    833     }
    834 
    835     for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
    836         BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
    837         status_t error = cancelBufferToNativeWindow(info);
    838         if (err == 0) {
    839             err = error;
    840         }
    841     }
    842 
    843     return err;
    844 }
    845 
    846 status_t ACodec::allocateOutputMetaDataBuffers() {
    847     OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
    848     status_t err = configureOutputBuffersFromNativeWindow(
    849             &bufferCount, &bufferSize, &minUndequeuedBuffers);
    850     if (err != 0)
    851         return err;
    852     mNumUndequeuedBuffers = minUndequeuedBuffers;
    853 
    854     ALOGV("[%s] Allocating %u meta buffers on output port",
    855          mComponentName.c_str(), bufferCount);
    856 
    857     size_t totalSize = bufferCount * 8;
    858     mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec");
    859 
    860     // Dequeue buffers and send them to OMX
    861     for (OMX_U32 i = 0; i < bufferCount; i++) {
    862         BufferInfo info;
    863         info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
    864         info.mGraphicBuffer = NULL;
    865         info.mDequeuedAt = mDequeueCounter;
    866 
    867         sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(
    868                 sizeof(struct VideoDecoderOutputMetaData));
    869         CHECK(mem.get() != NULL);
    870         info.mData = new ABuffer(mem->pointer(), mem->size());
    871 
    872         // we use useBuffer for metadata regardless of quirks
    873         err = mOMX->useBuffer(
    874                 mNode, kPortIndexOutput, mem, &info.mBufferID);
    875 
    876         mBuffers[kPortIndexOutput].push(info);
    877 
    878         ALOGV("[%s] allocated meta buffer with ID %u (pointer = %p)",
    879              mComponentName.c_str(), info.mBufferID, mem->pointer());
    880     }
    881 
    882     mMetaDataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
    883     return err;
    884 }
    885 
    886 status_t ACodec::submitOutputMetaDataBuffer() {
    887     CHECK(mStoreMetaDataInOutputBuffers);
    888     if (mMetaDataBuffersToSubmit == 0)
    889         return OK;
    890 
    891     BufferInfo *info = dequeueBufferFromNativeWindow();
    892     if (info == NULL)
    893         return ERROR_IO;
    894 
    895     ALOGV("[%s] submitting output meta buffer ID %u for graphic buffer %p",
    896           mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
    897 
    898     --mMetaDataBuffersToSubmit;
    899     CHECK_EQ(mOMX->fillBuffer(mNode, info->mBufferID),
    900              (status_t)OK);
    901 
    902     info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
    903     return OK;
    904 }
    905 
    906 status_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
    907     CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
    908 
    909     ALOGV("[%s] Calling cancelBuffer on buffer %u",
    910          mComponentName.c_str(), info->mBufferID);
    911 
    912     int err = mNativeWindow->cancelBuffer(
    913         mNativeWindow.get(), info->mGraphicBuffer.get(), -1);
    914 
    915     ALOGW_IF(err != 0, "[%s] can not return buffer %u to native window",
    916             mComponentName.c_str(), info->mBufferID);
    917 
    918     info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
    919 
    920     return err;
    921 }
    922 
    923 ACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
    924     ANativeWindowBuffer *buf;
    925     int fenceFd = -1;
    926     CHECK(mNativeWindow.get() != NULL);
    927 
    928     if (mTunneled) {
    929         ALOGW("dequeueBufferFromNativeWindow() should not be called in tunnel"
    930               " video playback mode mode!");
    931         return NULL;
    932     }
    933 
    934     if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) {
    935         ALOGE("dequeueBuffer failed.");
    936         return NULL;
    937     }
    938 
    939     BufferInfo *oldest = NULL;
    940     for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
    941         BufferInfo *info =
    942             &mBuffers[kPortIndexOutput].editItemAt(i);
    943 
    944         if (info->mGraphicBuffer != NULL &&
    945             info->mGraphicBuffer->handle == buf->handle) {
    946             CHECK_EQ((int)info->mStatus,
    947                      (int)BufferInfo::OWNED_BY_NATIVE_WINDOW);
    948 
    949             info->mStatus = BufferInfo::OWNED_BY_US;
    950 
    951             return info;
    952         }
    953 
    954         if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
    955             (oldest == NULL ||
    956              // avoid potential issues from counter rolling over
    957              mDequeueCounter - info->mDequeuedAt >
    958                     mDequeueCounter - oldest->mDequeuedAt)) {
    959             oldest = info;
    960         }
    961     }
    962 
    963     if (oldest) {
    964         CHECK(mStoreMetaDataInOutputBuffers);
    965 
    966         // discard buffer in LRU info and replace with new buffer
    967         oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
    968         oldest->mStatus = BufferInfo::OWNED_BY_US;
    969 
    970         mOMX->updateGraphicBufferInMeta(
    971                 mNode, kPortIndexOutput, oldest->mGraphicBuffer,
    972                 oldest->mBufferID);
    973 
    974         VideoDecoderOutputMetaData *metaData =
    975             reinterpret_cast<VideoDecoderOutputMetaData *>(
    976                     oldest->mData->base());
    977         CHECK_EQ(metaData->eType, kMetadataBufferTypeGrallocSource);
    978 
    979         ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
    980                 oldest - &mBuffers[kPortIndexOutput][0],
    981                 mDequeueCounter - oldest->mDequeuedAt,
    982                 metaData->pHandle,
    983                 oldest->mGraphicBuffer->handle, oldest->mData->base());
    984 
    985         return oldest;
    986     }
    987 
    988     TRESPASS();
    989 
    990     return NULL;
    991 }
    992 
    993 status_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
    994     for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
    995         CHECK_EQ((status_t)OK, freeBuffer(portIndex, i));
    996     }
    997 
    998     mDealer[portIndex].clear();
    999 
   1000     return OK;
   1001 }
   1002 
   1003 status_t ACodec::freeOutputBuffersNotOwnedByComponent() {
   1004     for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
   1005         BufferInfo *info =
   1006             &mBuffers[kPortIndexOutput].editItemAt(i);
   1007 
   1008         // At this time some buffers may still be with the component
   1009         // or being drained.
   1010         if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
   1011             info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
   1012             CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i));
   1013         }
   1014     }
   1015 
   1016     return OK;
   1017 }
   1018 
   1019 status_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
   1020     BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
   1021 
   1022     CHECK(info->mStatus == BufferInfo::OWNED_BY_US
   1023             || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
   1024 
   1025     if (portIndex == kPortIndexOutput && mNativeWindow != NULL
   1026             && info->mStatus == BufferInfo::OWNED_BY_US) {
   1027         cancelBufferToNativeWindow(info);
   1028     }
   1029 
   1030     CHECK_EQ(mOMX->freeBuffer(
   1031                 mNode, portIndex, info->mBufferID),
   1032              (status_t)OK);
   1033 
   1034     mBuffers[portIndex].removeAt(i);
   1035 
   1036     return OK;
   1037 }
   1038 
   1039 ACodec::BufferInfo *ACodec::findBufferByID(
   1040         uint32_t portIndex, IOMX::buffer_id bufferID,
   1041         ssize_t *index) {
   1042     for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
   1043         BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
   1044 
   1045         if (info->mBufferID == bufferID) {
   1046             if (index != NULL) {
   1047                 *index = i;
   1048             }
   1049             return info;
   1050         }
   1051     }
   1052 
   1053     TRESPASS();
   1054 
   1055     return NULL;
   1056 }
   1057 
   1058 status_t ACodec::setComponentRole(
   1059         bool isEncoder, const char *mime) {
   1060     struct MimeToRole {
   1061         const char *mime;
   1062         const char *decoderRole;
   1063         const char *encoderRole;
   1064     };
   1065 
   1066     static const MimeToRole kMimeToRole[] = {
   1067         { MEDIA_MIMETYPE_AUDIO_MPEG,
   1068             "audio_decoder.mp3", "audio_encoder.mp3" },
   1069         { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
   1070             "audio_decoder.mp1", "audio_encoder.mp1" },
   1071         { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
   1072             "audio_decoder.mp2", "audio_encoder.mp2" },
   1073         { MEDIA_MIMETYPE_AUDIO_AMR_NB,
   1074             "audio_decoder.amrnb", "audio_encoder.amrnb" },
   1075         { MEDIA_MIMETYPE_AUDIO_AMR_WB,
   1076             "audio_decoder.amrwb", "audio_encoder.amrwb" },
   1077         { MEDIA_MIMETYPE_AUDIO_AAC,
   1078             "audio_decoder.aac", "audio_encoder.aac" },
   1079         { MEDIA_MIMETYPE_AUDIO_VORBIS,
   1080             "audio_decoder.vorbis", "audio_encoder.vorbis" },
   1081         { MEDIA_MIMETYPE_AUDIO_OPUS,
   1082             "audio_decoder.opus", "audio_encoder.opus" },
   1083         { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
   1084             "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
   1085         { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
   1086             "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
   1087         { MEDIA_MIMETYPE_VIDEO_AVC,
   1088             "video_decoder.avc", "video_encoder.avc" },
   1089         { MEDIA_MIMETYPE_VIDEO_HEVC,
   1090             "video_decoder.hevc", "video_encoder.hevc" },
   1091         { MEDIA_MIMETYPE_VIDEO_MPEG4,
   1092             "video_decoder.mpeg4", "video_encoder.mpeg4" },
   1093         { MEDIA_MIMETYPE_VIDEO_H263,
   1094             "video_decoder.h263", "video_encoder.h263" },
   1095         { MEDIA_MIMETYPE_VIDEO_VP8,
   1096             "video_decoder.vp8", "video_encoder.vp8" },
   1097         { MEDIA_MIMETYPE_VIDEO_VP9,
   1098             "video_decoder.vp9", "video_encoder.vp9" },
   1099         { MEDIA_MIMETYPE_AUDIO_RAW,
   1100             "audio_decoder.raw", "audio_encoder.raw" },
   1101         { MEDIA_MIMETYPE_AUDIO_FLAC,
   1102             "audio_decoder.flac", "audio_encoder.flac" },
   1103         { MEDIA_MIMETYPE_AUDIO_MSGSM,
   1104             "audio_decoder.gsm", "audio_encoder.gsm" },
   1105         { MEDIA_MIMETYPE_VIDEO_MPEG2,
   1106             "video_decoder.mpeg2", "video_encoder.mpeg2" },
   1107         { MEDIA_MIMETYPE_AUDIO_AC3,
   1108             "audio_decoder.ac3", "audio_encoder.ac3" },
   1109     };
   1110 
   1111     static const size_t kNumMimeToRole =
   1112         sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
   1113 
   1114     size_t i;
   1115     for (i = 0; i < kNumMimeToRole; ++i) {
   1116         if (!strcasecmp(mime, kMimeToRole[i].mime)) {
   1117             break;
   1118         }
   1119     }
   1120 
   1121     if (i == kNumMimeToRole) {
   1122         return ERROR_UNSUPPORTED;
   1123     }
   1124 
   1125     const char *role =
   1126         isEncoder ? kMimeToRole[i].encoderRole
   1127                   : kMimeToRole[i].decoderRole;
   1128 
   1129     if (role != NULL) {
   1130         OMX_PARAM_COMPONENTROLETYPE roleParams;
   1131         InitOMXParams(&roleParams);
   1132 
   1133         strncpy((char *)roleParams.cRole,
   1134                 role, OMX_MAX_STRINGNAME_SIZE - 1);
   1135 
   1136         roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
   1137 
   1138         status_t err = mOMX->setParameter(
   1139                 mNode, OMX_IndexParamStandardComponentRole,
   1140                 &roleParams, sizeof(roleParams));
   1141 
   1142         if (err != OK) {
   1143             ALOGW("[%s] Failed to set standard component role '%s'.",
   1144                  mComponentName.c_str(), role);
   1145 
   1146             return err;
   1147         }
   1148     }
   1149 
   1150     return OK;
   1151 }
   1152 
   1153 status_t ACodec::configureCodec(
   1154         const char *mime, const sp<AMessage> &msg) {
   1155     int32_t encoder;
   1156     if (!msg->findInt32("encoder", &encoder)) {
   1157         encoder = false;
   1158     }
   1159 
   1160     sp<AMessage> inputFormat = new AMessage();
   1161     sp<AMessage> outputFormat = new AMessage();
   1162 
   1163     mIsEncoder = encoder;
   1164 
   1165     status_t err = setComponentRole(encoder /* isEncoder */, mime);
   1166 
   1167     if (err != OK) {
   1168         return err;
   1169     }
   1170 
   1171     int32_t bitRate = 0;
   1172     // FLAC encoder doesn't need a bitrate, other encoders do
   1173     if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
   1174             && !msg->findInt32("bitrate", &bitRate)) {
   1175         return INVALID_OPERATION;
   1176     }
   1177 
   1178     int32_t storeMeta;
   1179     if (encoder
   1180             && msg->findInt32("store-metadata-in-buffers", &storeMeta)
   1181             && storeMeta != 0) {
   1182         err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
   1183 
   1184         if (err != OK) {
   1185               ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
   1186                     mComponentName.c_str(), err);
   1187 
   1188               return err;
   1189           }
   1190       }
   1191 
   1192     int32_t prependSPSPPS = 0;
   1193     if (encoder
   1194             && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
   1195             && prependSPSPPS != 0) {
   1196         OMX_INDEXTYPE index;
   1197         err = mOMX->getExtensionIndex(
   1198                 mNode,
   1199                 "OMX.google.android.index.prependSPSPPSToIDRFrames",
   1200                 &index);
   1201 
   1202         if (err == OK) {
   1203             PrependSPSPPSToIDRFramesParams params;
   1204             InitOMXParams(&params);
   1205             params.bEnable = OMX_TRUE;
   1206 
   1207             err = mOMX->setParameter(
   1208                     mNode, index, &params, sizeof(params));
   1209         }
   1210 
   1211         if (err != OK) {
   1212             ALOGE("Encoder could not be configured to emit SPS/PPS before "
   1213                   "IDR frames. (err %d)", err);
   1214 
   1215             return err;
   1216         }
   1217     }
   1218 
   1219     // Only enable metadata mode on encoder output if encoder can prepend
   1220     // sps/pps to idr frames, since in metadata mode the bitstream is in an
   1221     // opaque handle, to which we don't have access.
   1222     int32_t video = !strncasecmp(mime, "video/", 6);
   1223     if (encoder && video) {
   1224         OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
   1225             && msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
   1226             && storeMeta != 0);
   1227 
   1228         err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable);
   1229 
   1230         if (err != OK) {
   1231             ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
   1232                 mComponentName.c_str(), err);
   1233             mUseMetadataOnEncoderOutput = 0;
   1234         } else {
   1235             mUseMetadataOnEncoderOutput = enable;
   1236         }
   1237 
   1238         if (!msg->findInt64(
   1239                     "repeat-previous-frame-after",
   1240                     &mRepeatFrameDelayUs)) {
   1241             mRepeatFrameDelayUs = -1ll;
   1242         }
   1243 
   1244         if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) {
   1245             mMaxPtsGapUs = -1ll;
   1246         }
   1247 
   1248         if (!msg->findInt64("time-lapse", &mTimePerCaptureUs)) {
   1249             mTimePerCaptureUs = -1ll;
   1250         }
   1251 
   1252         if (!msg->findInt32(
   1253                     "create-input-buffers-suspended",
   1254                     (int32_t*)&mCreateInputBuffersSuspended)) {
   1255             mCreateInputBuffersSuspended = false;
   1256         }
   1257     }
   1258 
   1259     sp<RefBase> obj;
   1260     int32_t haveNativeWindow = msg->findObject("native-window", &obj) &&
   1261         obj != NULL;
   1262     mStoreMetaDataInOutputBuffers = false;
   1263     if (video && !encoder) {
   1264         inputFormat->setInt32("adaptive-playback", false);
   1265     }
   1266     if (!encoder && video && haveNativeWindow) {
   1267         sp<NativeWindowWrapper> windowWrapper(
   1268                 static_cast<NativeWindowWrapper *>(obj.get()));
   1269         sp<ANativeWindow> nativeWindow = windowWrapper->getNativeWindow();
   1270 
   1271         int32_t tunneled;
   1272         if (msg->findInt32("feature-tunneled-playback", &tunneled) &&
   1273             tunneled != 0) {
   1274             ALOGI("Configuring TUNNELED video playback.");
   1275             mTunneled = true;
   1276 
   1277             int32_t audioHwSync = 0;
   1278             if (!msg->findInt32("audio-hw-sync", &audioHwSync)) {
   1279                 ALOGW("No Audio HW Sync provided for video tunnel");
   1280             }
   1281             err = configureTunneledVideoPlayback(audioHwSync, nativeWindow);
   1282             if (err != OK) {
   1283                 ALOGE("configureTunneledVideoPlayback(%d,%p) failed!",
   1284                         audioHwSync, nativeWindow.get());
   1285                 return err;
   1286             }
   1287 
   1288             inputFormat->setInt32("adaptive-playback", true);
   1289         } else {
   1290             ALOGV("Configuring CPU controlled video playback.");
   1291             mTunneled = false;
   1292 
   1293             // Always try to enable dynamic output buffers on native surface
   1294             err = mOMX->storeMetaDataInBuffers(
   1295                     mNode, kPortIndexOutput, OMX_TRUE);
   1296             if (err != OK) {
   1297                 ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
   1298                         mComponentName.c_str(), err);
   1299 
   1300                 // if adaptive playback has been requested, try JB fallback
   1301                 // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
   1302                 // LARGE MEMORY REQUIREMENT
   1303 
   1304                 // we will not do adaptive playback on software accessed
   1305                 // surfaces as they never had to respond to changes in the
   1306                 // crop window, and we don't trust that they will be able to.
   1307                 int usageBits = 0;
   1308                 bool canDoAdaptivePlayback;
   1309 
   1310                 if (nativeWindow->query(
   1311                         nativeWindow.get(),
   1312                         NATIVE_WINDOW_CONSUMER_USAGE_BITS,
   1313                         &usageBits) != OK) {
   1314                     canDoAdaptivePlayback = false;
   1315                 } else {
   1316                     canDoAdaptivePlayback =
   1317                         (usageBits &
   1318                                 (GRALLOC_USAGE_SW_READ_MASK |
   1319                                  GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
   1320                 }
   1321 
   1322                 int32_t maxWidth = 0, maxHeight = 0;
   1323                 if (canDoAdaptivePlayback &&
   1324                         msg->findInt32("max-width", &maxWidth) &&
   1325                         msg->findInt32("max-height", &maxHeight)) {
   1326                     ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)",
   1327                             mComponentName.c_str(), maxWidth, maxHeight);
   1328 
   1329                     err = mOMX->prepareForAdaptivePlayback(
   1330                             mNode, kPortIndexOutput, OMX_TRUE, maxWidth,
   1331                             maxHeight);
   1332                     ALOGW_IF(err != OK,
   1333                             "[%s] prepareForAdaptivePlayback failed w/ err %d",
   1334                             mComponentName.c_str(), err);
   1335 
   1336                     if (err == OK) {
   1337                         inputFormat->setInt32("max-width", maxWidth);
   1338                         inputFormat->setInt32("max-height", maxHeight);
   1339                         inputFormat->setInt32("adaptive-playback", true);
   1340                     }
   1341                 }
   1342                 // allow failure
   1343                 err = OK;
   1344             } else {
   1345                 ALOGV("[%s] storeMetaDataInBuffers succeeded",
   1346                         mComponentName.c_str());
   1347                 mStoreMetaDataInOutputBuffers = true;
   1348                 inputFormat->setInt32("adaptive-playback", true);
   1349             }
   1350 
   1351             int32_t push;
   1352             if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
   1353                     && push != 0) {
   1354                 mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
   1355             }
   1356         }
   1357 
   1358         int32_t rotationDegrees;
   1359         if (msg->findInt32("rotation-degrees", &rotationDegrees)) {
   1360             mRotationDegrees = rotationDegrees;
   1361         } else {
   1362             mRotationDegrees = 0;
   1363         }
   1364     }
   1365 
   1366     if (video) {
   1367         if (encoder) {
   1368             err = setupVideoEncoder(mime, msg);
   1369         } else {
   1370             err = setupVideoDecoder(mime, msg);
   1371         }
   1372     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
   1373         int32_t numChannels, sampleRate;
   1374         if (!msg->findInt32("channel-count", &numChannels)
   1375                 || !msg->findInt32("sample-rate", &sampleRate)) {
   1376             // Since we did not always check for these, leave them optional
   1377             // and have the decoder figure it all out.
   1378             err = OK;
   1379         } else {
   1380             err = setupRawAudioFormat(
   1381                     encoder ? kPortIndexInput : kPortIndexOutput,
   1382                     sampleRate,
   1383                     numChannels);
   1384         }
   1385     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
   1386         int32_t numChannels, sampleRate;
   1387         if (!msg->findInt32("channel-count", &numChannels)
   1388                 || !msg->findInt32("sample-rate", &sampleRate)) {
   1389             err = INVALID_OPERATION;
   1390         } else {
   1391             int32_t isADTS, aacProfile;
   1392             int32_t sbrMode;
   1393             int32_t maxOutputChannelCount;
   1394             int32_t pcmLimiterEnable;
   1395             drcParams_t drc;
   1396             if (!msg->findInt32("is-adts", &isADTS)) {
   1397                 isADTS = 0;
   1398             }
   1399             if (!msg->findInt32("aac-profile", &aacProfile)) {
   1400                 aacProfile = OMX_AUDIO_AACObjectNull;
   1401             }
   1402             if (!msg->findInt32("aac-sbr-mode", &sbrMode)) {
   1403                 sbrMode = -1;
   1404             }
   1405 
   1406             if (!msg->findInt32("aac-max-output-channel_count", &maxOutputChannelCount)) {
   1407                 maxOutputChannelCount = -1;
   1408             }
   1409             if (!msg->findInt32("aac-pcm-limiter-enable", &pcmLimiterEnable)) {
   1410                 // value is unknown
   1411                 pcmLimiterEnable = -1;
   1412             }
   1413             if (!msg->findInt32("aac-encoded-target-level", &drc.encodedTargetLevel)) {
   1414                 // value is unknown
   1415                 drc.encodedTargetLevel = -1;
   1416             }
   1417             if (!msg->findInt32("aac-drc-cut-level", &drc.drcCut)) {
   1418                 // value is unknown
   1419                 drc.drcCut = -1;
   1420             }
   1421             if (!msg->findInt32("aac-drc-boost-level", &drc.drcBoost)) {
   1422                 // value is unknown
   1423                 drc.drcBoost = -1;
   1424             }
   1425             if (!msg->findInt32("aac-drc-heavy-compression", &drc.heavyCompression)) {
   1426                 // value is unknown
   1427                 drc.heavyCompression = -1;
   1428             }
   1429             if (!msg->findInt32("aac-target-ref-level", &drc.targetRefLevel)) {
   1430                 // value is unknown
   1431                 drc.targetRefLevel = -1;
   1432             }
   1433 
   1434             err = setupAACCodec(
   1435                     encoder, numChannels, sampleRate, bitRate, aacProfile,
   1436                     isADTS != 0, sbrMode, maxOutputChannelCount, drc,
   1437                     pcmLimiterEnable);
   1438         }
   1439     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
   1440         err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
   1441     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
   1442         err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
   1443     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
   1444             || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
   1445         // These are PCM-like formats with a fixed sample rate but
   1446         // a variable number of channels.
   1447 
   1448         int32_t numChannels;
   1449         if (!msg->findInt32("channel-count", &numChannels)) {
   1450             err = INVALID_OPERATION;
   1451         } else {
   1452             err = setupG711Codec(encoder, numChannels);
   1453         }
   1454     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
   1455         int32_t numChannels, sampleRate, compressionLevel = -1;
   1456         if (encoder &&
   1457                 (!msg->findInt32("channel-count", &numChannels)
   1458                         || !msg->findInt32("sample-rate", &sampleRate))) {
   1459             ALOGE("missing channel count or sample rate for FLAC encoder");
   1460             err = INVALID_OPERATION;
   1461         } else {
   1462             if (encoder) {
   1463                 if (!msg->findInt32(
   1464                             "complexity", &compressionLevel) &&
   1465                     !msg->findInt32(
   1466                             "flac-compression-level", &compressionLevel)) {
   1467                     compressionLevel = 5; // default FLAC compression level
   1468                 } else if (compressionLevel < 0) {
   1469                     ALOGW("compression level %d outside [0..8] range, "
   1470                           "using 0",
   1471                           compressionLevel);
   1472                     compressionLevel = 0;
   1473                 } else if (compressionLevel > 8) {
   1474                     ALOGW("compression level %d outside [0..8] range, "
   1475                           "using 8",
   1476                           compressionLevel);
   1477                     compressionLevel = 8;
   1478                 }
   1479             }
   1480             err = setupFlacCodec(
   1481                     encoder, numChannels, sampleRate, compressionLevel);
   1482         }
   1483     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
   1484         int32_t numChannels, sampleRate;
   1485         if (encoder
   1486                 || !msg->findInt32("channel-count", &numChannels)
   1487                 || !msg->findInt32("sample-rate", &sampleRate)) {
   1488             err = INVALID_OPERATION;
   1489         } else {
   1490             err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
   1491         }
   1492     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
   1493         int32_t numChannels;
   1494         int32_t sampleRate;
   1495         if (!msg->findInt32("channel-count", &numChannels)
   1496                 || !msg->findInt32("sample-rate", &sampleRate)) {
   1497             err = INVALID_OPERATION;
   1498         } else {
   1499             err = setupAC3Codec(encoder, numChannels, sampleRate);
   1500         }
   1501     }
   1502 
   1503     if (err != OK) {
   1504         return err;
   1505     }
   1506 
   1507     if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
   1508         mEncoderDelay = 0;
   1509     }
   1510 
   1511     if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
   1512         mEncoderPadding = 0;
   1513     }
   1514 
   1515     if (msg->findInt32("channel-mask", &mChannelMask)) {
   1516         mChannelMaskPresent = true;
   1517     } else {
   1518         mChannelMaskPresent = false;
   1519     }
   1520 
   1521     int32_t maxInputSize;
   1522     if (msg->findInt32("max-input-size", &maxInputSize)) {
   1523         err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
   1524     } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
   1525         err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
   1526     }
   1527 
   1528     CHECK_EQ(getPortFormat(kPortIndexInput, inputFormat), (status_t)OK);
   1529     CHECK_EQ(getPortFormat(kPortIndexOutput, outputFormat), (status_t)OK);
   1530     mInputFormat = inputFormat;
   1531     mOutputFormat = outputFormat;
   1532 
   1533     return err;
   1534 }
   1535 
   1536 status_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
   1537     OMX_PARAM_PORTDEFINITIONTYPE def;
   1538     InitOMXParams(&def);
   1539     def.nPortIndex = portIndex;
   1540 
   1541     status_t err = mOMX->getParameter(
   1542             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
   1543 
   1544     if (err != OK) {
   1545         return err;
   1546     }
   1547 
   1548     if (def.nBufferSize >= size) {
   1549         return OK;
   1550     }
   1551 
   1552     def.nBufferSize = size;
   1553 
   1554     err = mOMX->setParameter(
   1555             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
   1556 
   1557     if (err != OK) {
   1558         return err;
   1559     }
   1560 
   1561     err = mOMX->getParameter(
   1562             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
   1563 
   1564     if (err != OK) {
   1565         return err;
   1566     }
   1567 
   1568     CHECK(def.nBufferSize >= size);
   1569 
   1570     return OK;
   1571 }
   1572 
   1573 status_t ACodec::selectAudioPortFormat(
   1574         OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
   1575     OMX_AUDIO_PARAM_PORTFORMATTYPE format;
   1576     InitOMXParams(&format);
   1577 
   1578     format.nPortIndex = portIndex;
   1579     for (OMX_U32 index = 0;; ++index) {
   1580         format.nIndex = index;
   1581 
   1582         status_t err = mOMX->getParameter(
   1583                 mNode, OMX_IndexParamAudioPortFormat,
   1584                 &format, sizeof(format));
   1585 
   1586         if (err != OK) {
   1587             return err;
   1588         }
   1589 
   1590         if (format.eEncoding == desiredFormat) {
   1591             break;
   1592         }
   1593     }
   1594 
   1595     return mOMX->setParameter(
   1596             mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
   1597 }
   1598 
   1599 status_t ACodec::setupAACCodec(
   1600         bool encoder, int32_t numChannels, int32_t sampleRate,
   1601         int32_t bitRate, int32_t aacProfile, bool isADTS, int32_t sbrMode,
   1602         int32_t maxOutputChannelCount, const drcParams_t& drc,
   1603         int32_t pcmLimiterEnable) {
   1604     if (encoder && isADTS) {
   1605         return -EINVAL;
   1606     }
   1607 
   1608     status_t err = setupRawAudioFormat(
   1609             encoder ? kPortIndexInput : kPortIndexOutput,
   1610             sampleRate,
   1611             numChannels);
   1612 
   1613     if (err != OK) {
   1614         return err;
   1615     }
   1616 
   1617     if (encoder) {
   1618         err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
   1619 
   1620         if (err != OK) {
   1621             return err;
   1622         }
   1623 
   1624         OMX_PARAM_PORTDEFINITIONTYPE def;
   1625         InitOMXParams(&def);
   1626         def.nPortIndex = kPortIndexOutput;
   1627 
   1628         err = mOMX->getParameter(
   1629                 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
   1630 
   1631         if (err != OK) {
   1632             return err;
   1633         }
   1634 
   1635         def.format.audio.bFlagErrorConcealment = OMX_TRUE;
   1636         def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
   1637 
   1638         err = mOMX->setParameter(
   1639                 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
   1640 
   1641         if (err != OK) {
   1642             return err;
   1643         }
   1644 
   1645         OMX_AUDIO_PARAM_AACPROFILETYPE profile;
   1646         InitOMXParams(&profile);
   1647         profile.nPortIndex = kPortIndexOutput;
   1648 
   1649         err = mOMX->getParameter(
   1650                 mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
   1651 
   1652         if (err != OK) {
   1653             return err;
   1654         }
   1655 
   1656         profile.nChannels = numChannels;
   1657 
   1658         profile.eChannelMode =
   1659             (numChannels == 1)
   1660                 ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
   1661 
   1662         profile.nSampleRate = sampleRate;
   1663         profile.nBitRate = bitRate;
   1664         profile.nAudioBandWidth = 0;
   1665         profile.nFrameLength = 0;
   1666         profile.nAACtools = OMX_AUDIO_AACToolAll;
   1667         profile.nAACERtools = OMX_AUDIO_AACERNone;
   1668         profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
   1669         profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
   1670         switch (sbrMode) {
   1671         case 0:
   1672             // disable sbr
   1673             profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
   1674             profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
   1675             break;
   1676         case 1:
   1677             // enable single-rate sbr
   1678             profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
   1679             profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
   1680             break;
   1681         case 2:
   1682             // enable dual-rate sbr
   1683             profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
   1684             profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
   1685             break;
   1686         case -1:
   1687             // enable both modes -> the codec will decide which mode should be used
   1688             profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
   1689             profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
   1690             break;
   1691         default:
   1692             // unsupported sbr mode
   1693             return BAD_VALUE;
   1694         }
   1695 
   1696 
   1697         err = mOMX->setParameter(
   1698                 mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
   1699 
   1700         if (err != OK) {
   1701             return err;
   1702         }
   1703 
   1704         return err;
   1705     }
   1706 
   1707     OMX_AUDIO_PARAM_AACPROFILETYPE profile;
   1708     InitOMXParams(&profile);
   1709     profile.nPortIndex = kPortIndexInput;
   1710 
   1711     err = mOMX->getParameter(
   1712             mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
   1713 
   1714     if (err != OK) {
   1715         return err;
   1716     }
   1717 
   1718     profile.nChannels = numChannels;
   1719     profile.nSampleRate = sampleRate;
   1720 
   1721     profile.eAACStreamFormat =
   1722         isADTS
   1723             ? OMX_AUDIO_AACStreamFormatMP4ADTS
   1724             : OMX_AUDIO_AACStreamFormatMP4FF;
   1725 
   1726     OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE presentation;
   1727     presentation.nMaxOutputChannels = maxOutputChannelCount;
   1728     presentation.nDrcCut = drc.drcCut;
   1729     presentation.nDrcBoost = drc.drcBoost;
   1730     presentation.nHeavyCompression = drc.heavyCompression;
   1731     presentation.nTargetReferenceLevel = drc.targetRefLevel;
   1732     presentation.nEncodedTargetLevel = drc.encodedTargetLevel;
   1733     presentation.nPCMLimiterEnable = pcmLimiterEnable;
   1734 
   1735     status_t res = mOMX->setParameter(mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
   1736     if (res == OK) {
   1737         // optional parameters, will not cause configuration failure
   1738         mOMX->setParameter(mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacPresentation,
   1739                 &presentation, sizeof(presentation));
   1740     } else {
   1741         ALOGW("did not set AudioAndroidAacPresentation due to error %d when setting AudioAac", res);
   1742     }
   1743     return res;
   1744 }
   1745 
   1746 status_t ACodec::setupAC3Codec(
   1747         bool encoder, int32_t numChannels, int32_t sampleRate) {
   1748     status_t err = setupRawAudioFormat(
   1749             encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
   1750 
   1751     if (err != OK) {
   1752         return err;
   1753     }
   1754 
   1755     if (encoder) {
   1756         ALOGW("AC3 encoding is not supported.");
   1757         return INVALID_OPERATION;
   1758     }
   1759 
   1760     OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
   1761     InitOMXParams(&def);
   1762     def.nPortIndex = kPortIndexInput;
   1763 
   1764     err = mOMX->getParameter(
   1765             mNode,
   1766             (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
   1767             &def,
   1768             sizeof(def));
   1769 
   1770     if (err != OK) {
   1771         return err;
   1772     }
   1773 
   1774     def.nChannels = numChannels;
   1775     def.nSampleRate = sampleRate;
   1776 
   1777     return mOMX->setParameter(
   1778             mNode,
   1779             (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
   1780             &def,
   1781             sizeof(def));
   1782 }
   1783 
   1784 static OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
   1785         bool isAMRWB, int32_t bps) {
   1786     if (isAMRWB) {
   1787         if (bps <= 6600) {
   1788             return OMX_AUDIO_AMRBandModeWB0;
   1789         } else if (bps <= 8850) {
   1790             return OMX_AUDIO_AMRBandModeWB1;
   1791         } else if (bps <= 12650) {
   1792             return OMX_AUDIO_AMRBandModeWB2;
   1793         } else if (bps <= 14250) {
   1794             return OMX_AUDIO_AMRBandModeWB3;
   1795         } else if (bps <= 15850) {
   1796             return OMX_AUDIO_AMRBandModeWB4;
   1797         } else if (bps <= 18250) {
   1798             return OMX_AUDIO_AMRBandModeWB5;
   1799         } else if (bps <= 19850) {
   1800             return OMX_AUDIO_AMRBandModeWB6;
   1801         } else if (bps <= 23050) {
   1802             return OMX_AUDIO_AMRBandModeWB7;
   1803         }
   1804 
   1805         // 23850 bps
   1806         return OMX_AUDIO_AMRBandModeWB8;
   1807     } else {  // AMRNB
   1808         if (bps <= 4750) {
   1809             return OMX_AUDIO_AMRBandModeNB0;
   1810         } else if (bps <= 5150) {
   1811             return OMX_AUDIO_AMRBandModeNB1;
   1812         } else if (bps <= 5900) {
   1813             return OMX_AUDIO_AMRBandModeNB2;
   1814         } else if (bps <= 6700) {
   1815             return OMX_AUDIO_AMRBandModeNB3;
   1816         } else if (bps <= 7400) {
   1817             return OMX_AUDIO_AMRBandModeNB4;
   1818         } else if (bps <= 7950) {
   1819             return OMX_AUDIO_AMRBandModeNB5;
   1820         } else if (bps <= 10200) {
   1821             return OMX_AUDIO_AMRBandModeNB6;
   1822         }
   1823 
   1824         // 12200 bps
   1825         return OMX_AUDIO_AMRBandModeNB7;
   1826     }
   1827 }
   1828 
   1829 status_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
   1830     OMX_AUDIO_PARAM_AMRTYPE def;
   1831     InitOMXParams(&def);
   1832     def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
   1833 
   1834     status_t err =
   1835         mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
   1836 
   1837     if (err != OK) {
   1838         return err;
   1839     }
   1840 
   1841     def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
   1842     def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
   1843 
   1844     err = mOMX->setParameter(
   1845             mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
   1846 
   1847     if (err != OK) {
   1848         return err;
   1849     }
   1850 
   1851     return setupRawAudioFormat(
   1852             encoder ? kPortIndexInput : kPortIndexOutput,
   1853             isWAMR ? 16000 : 8000 /* sampleRate */,
   1854             1 /* numChannels */);
   1855 }
   1856 
   1857 status_t ACodec::setupG711Codec(bool encoder, int32_t numChannels) {
   1858     CHECK(!encoder);  // XXX TODO
   1859 
   1860     return setupRawAudioFormat(
   1861             kPortIndexInput, 8000 /* sampleRate */, numChannels);
   1862 }
   1863 
   1864 status_t ACodec::setupFlacCodec(
   1865         bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
   1866 
   1867     if (encoder) {
   1868         OMX_AUDIO_PARAM_FLACTYPE def;
   1869         InitOMXParams(&def);
   1870         def.nPortIndex = kPortIndexOutput;
   1871 
   1872         // configure compression level
   1873         status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
   1874         if (err != OK) {
   1875             ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
   1876             return err;
   1877         }
   1878         def.nCompressionLevel = compressionLevel;
   1879         err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
   1880         if (err != OK) {
   1881             ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
   1882             return err;
   1883         }
   1884     }
   1885 
   1886     return setupRawAudioFormat(
   1887             encoder ? kPortIndexInput : kPortIndexOutput,
   1888             sampleRate,
   1889             numChannels);
   1890 }
   1891 
   1892 status_t ACodec::setupRawAudioFormat(
   1893         OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
   1894     OMX_PARAM_PORTDEFINITIONTYPE def;
   1895     InitOMXParams(&def);
   1896     def.nPortIndex = portIndex;
   1897 
   1898     status_t err = mOMX->getParameter(
   1899             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
   1900 
   1901     if (err != OK) {
   1902         return err;
   1903     }
   1904 
   1905     def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
   1906 
   1907     err = mOMX->setParameter(
   1908             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
   1909 
   1910     if (err != OK) {
   1911         return err;
   1912     }
   1913 
   1914     OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
   1915     InitOMXParams(&pcmParams);
   1916     pcmParams.nPortIndex = portIndex;
   1917 
   1918     err = mOMX->getParameter(
   1919             mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
   1920 
   1921     if (err != OK) {
   1922         return err;
   1923     }
   1924 
   1925     pcmParams.nChannels = numChannels;
   1926     pcmParams.eNumData = OMX_NumericalDataSigned;
   1927     pcmParams.bInterleaved = OMX_TRUE;
   1928     pcmParams.nBitPerSample = 16;
   1929     pcmParams.nSamplingRate = sampleRate;
   1930     pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
   1931 
   1932     if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
   1933         return OMX_ErrorNone;
   1934     }
   1935 
   1936     return mOMX->setParameter(
   1937             mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
   1938 }
   1939 
   1940 status_t ACodec::configureTunneledVideoPlayback(
   1941         int32_t audioHwSync, const sp<ANativeWindow> &nativeWindow) {
   1942     native_handle_t* sidebandHandle;
   1943 
   1944     status_t err = mOMX->configureVideoTunnelMode(
   1945             mNode, kPortIndexOutput, OMX_TRUE, audioHwSync, &sidebandHandle);
   1946     if (err != OK) {
   1947         ALOGE("configureVideoTunnelMode failed! (err %d).", err);
   1948         return err;
   1949     }
   1950 
   1951     err = native_window_set_sideband_stream(nativeWindow.get(), sidebandHandle);
   1952     if (err != OK) {
   1953         ALOGE("native_window_set_sideband_stream(%p) failed! (err %d).",
   1954                 sidebandHandle, err);
   1955         return err;
   1956     }
   1957 
   1958     return OK;
   1959 }
   1960 
   1961 status_t ACodec::setVideoPortFormatType(
   1962         OMX_U32 portIndex,
   1963         OMX_VIDEO_CODINGTYPE compressionFormat,
   1964         OMX_COLOR_FORMATTYPE colorFormat) {
   1965     OMX_VIDEO_PARAM_PORTFORMATTYPE format;
   1966     InitOMXParams(&format);
   1967     format.nPortIndex = portIndex;
   1968     format.nIndex = 0;
   1969     bool found = false;
   1970 
   1971     OMX_U32 index = 0;
   1972     for (;;) {
   1973         format.nIndex = index;
   1974         status_t err = mOMX->getParameter(
   1975                 mNode, OMX_IndexParamVideoPortFormat,
   1976                 &format, sizeof(format));
   1977 
   1978         if (err != OK) {
   1979             return err;
   1980         }
   1981 
   1982         // substitute back flexible color format to codec supported format
   1983         OMX_U32 flexibleEquivalent;
   1984         if (compressionFormat == OMX_VIDEO_CodingUnused &&
   1985                 isFlexibleColorFormat(
   1986                         mOMX, mNode, format.eColorFormat, &flexibleEquivalent) &&
   1987                 colorFormat == flexibleEquivalent) {
   1988             ALOGI("[%s] using color format %#x in place of %#x",
   1989                     mComponentName.c_str(), format.eColorFormat, colorFormat);
   1990             colorFormat = format.eColorFormat;
   1991         }
   1992 
   1993         // The following assertion is violated by TI's video decoder.
   1994         // CHECK_EQ(format.nIndex, index);
   1995 
   1996         if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
   1997             if (portIndex == kPortIndexInput
   1998                     && colorFormat == format.eColorFormat) {
   1999                 // eCompressionFormat does not seem right.
   2000                 found = true;
   2001                 break;
   2002             }
   2003             if (portIndex == kPortIndexOutput
   2004                     && compressionFormat == format.eCompressionFormat) {
   2005                 // eColorFormat does not seem right.
   2006                 found = true;
   2007                 break;
   2008             }
   2009         }
   2010 
   2011         if (format.eCompressionFormat == compressionFormat
   2012             && format.eColorFormat == colorFormat) {
   2013             found = true;
   2014             break;
   2015         }
   2016 
   2017         ++index;
   2018     }
   2019 
   2020     if (!found) {
   2021         return UNKNOWN_ERROR;
   2022     }
   2023 
   2024     status_t err = mOMX->setParameter(
   2025             mNode, OMX_IndexParamVideoPortFormat,
   2026             &format, sizeof(format));
   2027 
   2028     return err;
   2029 }
   2030 
   2031 status_t ACodec::setSupportedOutputFormat() {
   2032     OMX_VIDEO_PARAM_PORTFORMATTYPE format;
   2033     InitOMXParams(&format);
   2034     format.nPortIndex = kPortIndexOutput;
   2035     format.nIndex = 0;
   2036 
   2037     status_t err = mOMX->getParameter(
   2038             mNode, OMX_IndexParamVideoPortFormat,
   2039             &format, sizeof(format));
   2040     CHECK_EQ(err, (status_t)OK);
   2041     CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused);
   2042 
   2043     return mOMX->setParameter(
   2044             mNode, OMX_IndexParamVideoPortFormat,
   2045             &format, sizeof(format));
   2046 }
   2047 
   2048 static const struct VideoCodingMapEntry {
   2049     const char *mMime;
   2050     OMX_VIDEO_CODINGTYPE mVideoCodingType;
   2051 } kVideoCodingMapEntry[] = {
   2052     { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
   2053     { MEDIA_MIMETYPE_VIDEO_HEVC, OMX_VIDEO_CodingHEVC },
   2054     { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
   2055     { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
   2056     { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
   2057     { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
   2058     { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
   2059 };
   2060 
   2061 static status_t GetVideoCodingTypeFromMime(
   2062         const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
   2063     for (size_t i = 0;
   2064          i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
   2065          ++i) {
   2066         if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
   2067             *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
   2068             return OK;
   2069         }
   2070     }
   2071 
   2072     *codingType = OMX_VIDEO_CodingUnused;
   2073 
   2074     return ERROR_UNSUPPORTED;
   2075 }
   2076 
   2077 static status_t GetMimeTypeForVideoCoding(
   2078         OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
   2079     for (size_t i = 0;
   2080          i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
   2081          ++i) {
   2082         if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
   2083             *mime = kVideoCodingMapEntry[i].mMime;
   2084             return OK;
   2085         }
   2086     }
   2087 
   2088     mime->clear();
   2089 
   2090     return ERROR_UNSUPPORTED;
   2091 }
   2092 
   2093 status_t ACodec::setupVideoDecoder(
   2094         const char *mime, const sp<AMessage> &msg) {
   2095     int32_t width, height;
   2096     if (!msg->findInt32("width", &width)
   2097             || !msg->findInt32("height", &height)) {
   2098         return INVALID_OPERATION;
   2099     }
   2100 
   2101     OMX_VIDEO_CODINGTYPE compressionFormat;
   2102     status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
   2103 
   2104     if (err != OK) {
   2105         return err;
   2106     }
   2107 
   2108     err = setVideoPortFormatType(
   2109             kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
   2110 
   2111     if (err != OK) {
   2112         return err;
   2113     }
   2114 
   2115     int32_t tmp;
   2116     if (msg->findInt32("color-format", &tmp)) {
   2117         OMX_COLOR_FORMATTYPE colorFormat =
   2118             static_cast<OMX_COLOR_FORMATTYPE>(tmp);
   2119         err = setVideoPortFormatType(
   2120                 kPortIndexOutput, OMX_VIDEO_CodingUnused, colorFormat);
   2121         if (err != OK) {
   2122             ALOGW("[%s] does not support color format %d",
   2123                   mComponentName.c_str(), colorFormat);
   2124             err = setSupportedOutputFormat();
   2125         }
   2126     } else {
   2127         err = setSupportedOutputFormat();
   2128     }
   2129 
   2130     if (err != OK) {
   2131         return err;
   2132     }
   2133 
   2134     err = setVideoFormatOnPort(
   2135             kPortIndexInput, width, height, compressionFormat);
   2136 
   2137     if (err != OK) {
   2138         return err;
   2139     }
   2140 
   2141     err = setVideoFormatOnPort(
   2142             kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
   2143 
   2144     if (err != OK) {
   2145         return err;
   2146     }
   2147 
   2148     return OK;
   2149 }
   2150 
   2151 status_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
   2152     int32_t tmp;
   2153     if (!msg->findInt32("color-format", &tmp)) {
   2154         return INVALID_OPERATION;
   2155     }
   2156 
   2157     OMX_COLOR_FORMATTYPE colorFormat =
   2158         static_cast<OMX_COLOR_FORMATTYPE>(tmp);
   2159 
   2160     status_t err = setVideoPortFormatType(
   2161             kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
   2162 
   2163     if (err != OK) {
   2164         ALOGE("[%s] does not support color format %d",
   2165               mComponentName.c_str(), colorFormat);
   2166 
   2167         return err;
   2168     }
   2169 
   2170     /* Input port configuration */
   2171 
   2172     OMX_PARAM_PORTDEFINITIONTYPE def;
   2173     InitOMXParams(&def);
   2174 
   2175     OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
   2176 
   2177     def.nPortIndex = kPortIndexInput;
   2178 
   2179     err = mOMX->getParameter(
   2180             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
   2181 
   2182     if (err != OK) {
   2183         return err;
   2184     }
   2185 
   2186     int32_t width, height, bitrate;
   2187     if (!msg->findInt32("width", &width)
   2188             || !msg->findInt32("height", &height)
   2189             || !msg->findInt32("bitrate", &bitrate)) {
   2190         return INVALID_OPERATION;
   2191     }
   2192 
   2193     video_def->nFrameWidth = width;
   2194     video_def->nFrameHeight = height;
   2195 
   2196     int32_t stride;
   2197     if (!msg->findInt32("stride", &stride)) {
   2198         stride = width;
   2199     }
   2200 
   2201     video_def->nStride = stride;
   2202 
   2203     int32_t sliceHeight;
   2204     if (!msg->findInt32("slice-height", &sliceHeight)) {
   2205         sliceHeight = height;
   2206     }
   2207 
   2208     video_def->nSliceHeight = sliceHeight;
   2209 
   2210     def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
   2211 
   2212     float frameRate;
   2213     if (!msg->findFloat("frame-rate", &frameRate)) {
   2214         int32_t tmp;
   2215         if (!msg->findInt32("frame-rate", &tmp)) {
   2216             return INVALID_OPERATION;
   2217         }
   2218         frameRate = (float)tmp;
   2219         mTimePerFrameUs = (int64_t) (1000000.0f / frameRate);
   2220     }
   2221 
   2222     video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
   2223     video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
   2224     video_def->eColorFormat = colorFormat;
   2225 
   2226     err = mOMX->setParameter(
   2227             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
   2228 
   2229     if (err != OK) {
   2230         ALOGE("[%s] failed to set input port definition parameters.",
   2231               mComponentName.c_str());
   2232 
   2233         return err;
   2234     }
   2235 
   2236     /* Output port configuration */
   2237 
   2238     OMX_VIDEO_CODINGTYPE compressionFormat;
   2239     err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
   2240 
   2241     if (err != OK) {
   2242         return err;
   2243     }
   2244 
   2245     err = setVideoPortFormatType(
   2246             kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
   2247 
   2248     if (err != OK) {
   2249         ALOGE("[%s] does not support compression format %d",
   2250              mComponentName.c_str(), compressionFormat);
   2251 
   2252         return err;
   2253     }
   2254 
   2255     def.nPortIndex = kPortIndexOutput;
   2256 
   2257     err = mOMX->getParameter(
   2258             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
   2259 
   2260     if (err != OK) {
   2261         return err;
   2262     }
   2263 
   2264     video_def->nFrameWidth = width;
   2265     video_def->nFrameHeight = height;
   2266     video_def->xFramerate = 0;
   2267     video_def->nBitrate = bitrate;
   2268     video_def->eCompressionFormat = compressionFormat;
   2269     video_def->eColorFormat = OMX_COLOR_FormatUnused;
   2270 
   2271     err = mOMX->setParameter(
   2272             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
   2273 
   2274     if (err != OK) {
   2275         ALOGE("[%s] failed to set output port definition parameters.",
   2276               mComponentName.c_str());
   2277 
   2278         return err;
   2279     }
   2280 
   2281     switch (compressionFormat) {
   2282         case OMX_VIDEO_CodingMPEG4:
   2283             err = setupMPEG4EncoderParameters(msg);
   2284             break;
   2285 
   2286         case OMX_VIDEO_CodingH263:
   2287             err = setupH263EncoderParameters(msg);
   2288             break;
   2289 
   2290         case OMX_VIDEO_CodingAVC:
   2291             err = setupAVCEncoderParameters(msg);
   2292             break;
   2293 
   2294         case OMX_VIDEO_CodingHEVC:
   2295             err = setupHEVCEncoderParameters(msg);
   2296             break;
   2297 
   2298         case OMX_VIDEO_CodingVP8:
   2299         case OMX_VIDEO_CodingVP9:
   2300             err = setupVPXEncoderParameters(msg);
   2301             break;
   2302 
   2303         default:
   2304             break;
   2305     }
   2306 
   2307     ALOGI("setupVideoEncoder succeeded");
   2308 
   2309     return err;
   2310 }
   2311 
   2312 status_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
   2313     OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
   2314     InitOMXParams(&params);
   2315     params.nPortIndex = kPortIndexOutput;
   2316 
   2317     params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
   2318 
   2319     if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
   2320             params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
   2321         int32_t mbs;
   2322         if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
   2323             return INVALID_OPERATION;
   2324         }
   2325         params.nCirMBs = mbs;
   2326     }
   2327 
   2328     if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
   2329             params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
   2330         int32_t mbs;
   2331         if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
   2332             return INVALID_OPERATION;
   2333         }
   2334         params.nAirMBs = mbs;
   2335 
   2336         int32_t ref;
   2337         if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
   2338             return INVALID_OPERATION;
   2339         }
   2340         params.nAirRef = ref;
   2341     }
   2342 
   2343     status_t err = mOMX->setParameter(
   2344             mNode, OMX_IndexParamVideoIntraRefresh,
   2345             &params, sizeof(params));
   2346     return err;
   2347 }
   2348 
   2349 static OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
   2350     if (iFramesInterval < 0) {
   2351         return 0xFFFFFFFF;
   2352     } else if (iFramesInterval == 0) {
   2353         return 0;
   2354     }
   2355     OMX_U32 ret = frameRate * iFramesInterval;
   2356     return ret;
   2357 }
   2358 
   2359 static OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
   2360     int32_t tmp;
   2361     if (!msg->findInt32("bitrate-mode", &tmp)) {
   2362         return OMX_Video_ControlRateVariable;
   2363     }
   2364 
   2365     return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
   2366 }
   2367 
   2368 status_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
   2369     int32_t bitrate, iFrameInterval;
   2370     if (!msg->findInt32("bitrate", &bitrate)
   2371             || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
   2372         return INVALID_OPERATION;
   2373     }
   2374 
   2375     OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
   2376 
   2377     float frameRate;
   2378     if (!msg->findFloat("frame-rate", &frameRate)) {
   2379         int32_t tmp;
   2380         if (!msg->findInt32("frame-rate", &tmp)) {
   2381             return INVALID_OPERATION;
   2382         }
   2383         frameRate = (float)tmp;
   2384     }
   2385 
   2386     OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
   2387     InitOMXParams(&mpeg4type);
   2388     mpeg4type.nPortIndex = kPortIndexOutput;
   2389 
   2390     status_t err = mOMX->getParameter(
   2391             mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
   2392 
   2393     if (err != OK) {
   2394         return err;
   2395     }
   2396 
   2397     mpeg4type.nSliceHeaderSpacing = 0;
   2398     mpeg4type.bSVH = OMX_FALSE;
   2399     mpeg4type.bGov = OMX_FALSE;
   2400 
   2401     mpeg4type.nAllowedPictureTypes =
   2402         OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
   2403 
   2404     mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
   2405     if (mpeg4type.nPFrames == 0) {
   2406         mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
   2407     }
   2408     mpeg4type.nBFrames = 0;
   2409     mpeg4type.nIDCVLCThreshold = 0;
   2410     mpeg4type.bACPred = OMX_TRUE;
   2411     mpeg4type.nMaxPacketSize = 256;
   2412     mpeg4type.nTimeIncRes = 1000;
   2413     mpeg4type.nHeaderExtension = 0;
   2414     mpeg4type.bReversibleVLC = OMX_FALSE;
   2415 
   2416     int32_t profile;
   2417     if (msg->findInt32("profile", &profile)) {
   2418         int32_t level;
   2419         if (!msg->findInt32("level", &level)) {
   2420             return INVALID_OPERATION;
   2421         }
   2422 
   2423         err = verifySupportForProfileAndLevel(profile, level);
   2424 
   2425         if (err != OK) {
   2426             return err;
   2427         }
   2428 
   2429         mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
   2430         mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
   2431     }
   2432 
   2433     err = mOMX->setParameter(
   2434             mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
   2435 
   2436     if (err != OK) {
   2437         return err;
   2438     }
   2439 
   2440     err = configureBitrate(bitrate, bitrateMode);
   2441 
   2442     if (err != OK) {
   2443         return err;
   2444     }
   2445 
   2446     return setupErrorCorrectionParameters();
   2447 }
   2448 
   2449 status_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
   2450     int32_t bitrate, iFrameInterval;
   2451     if (!msg->findInt32("bitrate", &bitrate)
   2452             || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
   2453         return INVALID_OPERATION;
   2454     }
   2455 
   2456     OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
   2457 
   2458     float frameRate;
   2459     if (!msg->findFloat("frame-rate", &frameRate)) {
   2460         int32_t tmp;
   2461         if (!msg->findInt32("frame-rate", &tmp)) {
   2462             return INVALID_OPERATION;
   2463         }
   2464         frameRate = (float)tmp;
   2465     }
   2466 
   2467     OMX_VIDEO_PARAM_H263TYPE h263type;
   2468     InitOMXParams(&h263type);
   2469     h263type.nPortIndex = kPortIndexOutput;
   2470 
   2471     status_t err = mOMX->getParameter(
   2472             mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
   2473 
   2474     if (err != OK) {
   2475         return err;
   2476     }
   2477 
   2478     h263type.nAllowedPictureTypes =
   2479         OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
   2480 
   2481     h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
   2482     if (h263type.nPFrames == 0) {
   2483         h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
   2484     }
   2485     h263type.nBFrames = 0;
   2486 
   2487     int32_t profile;
   2488     if (msg->findInt32("profile", &profile)) {
   2489         int32_t level;
   2490         if (!msg->findInt32("level", &level)) {
   2491             return INVALID_OPERATION;
   2492         }
   2493 
   2494         err = verifySupportForProfileAndLevel(profile, level);
   2495 
   2496         if (err != OK) {
   2497             return err;
   2498         }
   2499 
   2500         h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
   2501         h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
   2502     }
   2503 
   2504     h263type.bPLUSPTYPEAllowed = OMX_FALSE;
   2505     h263type.bForceRoundingTypeToZero = OMX_FALSE;
   2506     h263type.nPictureHeaderRepetition = 0;
   2507     h263type.nGOBHeaderInterval = 0;
   2508 
   2509     err = mOMX->setParameter(
   2510             mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
   2511 
   2512     if (err != OK) {
   2513         return err;
   2514     }
   2515 
   2516     err = configureBitrate(bitrate, bitrateMode);
   2517 
   2518     if (err != OK) {
   2519         return err;
   2520     }
   2521 
   2522     return setupErrorCorrectionParameters();
   2523 }
   2524 
   2525 // static
   2526 int /* OMX_VIDEO_AVCLEVELTYPE */ ACodec::getAVCLevelFor(
   2527         int width, int height, int rate, int bitrate,
   2528         OMX_VIDEO_AVCPROFILETYPE profile) {
   2529     // convert bitrate to main/baseline profile kbps equivalent
   2530     switch (profile) {
   2531         case OMX_VIDEO_AVCProfileHigh10:
   2532             bitrate = divUp(bitrate, 3000); break;
   2533         case OMX_VIDEO_AVCProfileHigh:
   2534             bitrate = divUp(bitrate, 1250); break;
   2535         default:
   2536             bitrate = divUp(bitrate, 1000); break;
   2537     }
   2538 
   2539     // convert size and rate to MBs
   2540     width = divUp(width, 16);
   2541     height = divUp(height, 16);
   2542     int mbs = width * height;
   2543     rate *= mbs;
   2544     int maxDimension = max(width, height);
   2545 
   2546     static const int limits[][5] = {
   2547         /*   MBps     MB   dim  bitrate        level */
   2548         {    1485,    99,  28,     64, OMX_VIDEO_AVCLevel1  },
   2549         {    1485,    99,  28,    128, OMX_VIDEO_AVCLevel1b },
   2550         {    3000,   396,  56,    192, OMX_VIDEO_AVCLevel11 },
   2551         {    6000,   396,  56,    384, OMX_VIDEO_AVCLevel12 },
   2552         {   11880,   396,  56,    768, OMX_VIDEO_AVCLevel13 },
   2553         {   11880,   396,  56,   2000, OMX_VIDEO_AVCLevel2  },
   2554         {   19800,   792,  79,   4000, OMX_VIDEO_AVCLevel21 },
   2555         {   20250,  1620, 113,   4000, OMX_VIDEO_AVCLevel22 },
   2556         {   40500,  1620, 113,  10000, OMX_VIDEO_AVCLevel3  },
   2557         {  108000,  3600, 169,  14000, OMX_VIDEO_AVCLevel31 },
   2558         {  216000,  5120, 202,  20000, OMX_VIDEO_AVCLevel32 },
   2559         {  245760,  8192, 256,  20000, OMX_VIDEO_AVCLevel4  },
   2560         {  245760,  8192, 256,  50000, OMX_VIDEO_AVCLevel41 },
   2561         {  522240,  8704, 263,  50000, OMX_VIDEO_AVCLevel42 },
   2562         {  589824, 22080, 420, 135000, OMX_VIDEO_AVCLevel5  },
   2563         {  983040, 36864, 543, 240000, OMX_VIDEO_AVCLevel51 },
   2564         { 2073600, 36864, 543, 240000, OMX_VIDEO_AVCLevel52 },
   2565     };
   2566 
   2567     for (size_t i = 0; i < ARRAY_SIZE(limits); i++) {
   2568         const int (&limit)[5] = limits[i];
   2569         if (rate <= limit[0] && mbs <= limit[1] && maxDimension <= limit[2]
   2570                 && bitrate <= limit[3]) {
   2571             return limit[4];
   2572         }
   2573     }
   2574     return 0;
   2575 }
   2576 
   2577 status_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
   2578     int32_t bitrate, iFrameInterval;
   2579     if (!msg->findInt32("bitrate", &bitrate)
   2580             || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
   2581         return INVALID_OPERATION;
   2582     }
   2583 
   2584     OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
   2585 
   2586     float frameRate;
   2587     if (!msg->findFloat("frame-rate", &frameRate)) {
   2588         int32_t tmp;
   2589         if (!msg->findInt32("frame-rate", &tmp)) {
   2590             return INVALID_OPERATION;
   2591         }
   2592         frameRate = (float)tmp;
   2593     }
   2594 
   2595     status_t err = OK;
   2596     int32_t intraRefreshMode = 0;
   2597     if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
   2598         err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
   2599         if (err != OK) {
   2600             ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
   2601                     err, intraRefreshMode);
   2602             return err;
   2603         }
   2604     }
   2605 
   2606     OMX_VIDEO_PARAM_AVCTYPE h264type;
   2607     InitOMXParams(&h264type);
   2608     h264type.nPortIndex = kPortIndexOutput;
   2609 
   2610     err = mOMX->getParameter(
   2611             mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
   2612 
   2613     if (err != OK) {
   2614         return err;
   2615     }
   2616 
   2617     h264type.nAllowedPictureTypes =
   2618         OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
   2619 
   2620     int32_t profile;
   2621     if (msg->findInt32("profile", &profile)) {
   2622         int32_t level;
   2623         if (!msg->findInt32("level", &level)) {
   2624             return INVALID_OPERATION;
   2625         }
   2626 
   2627         err = verifySupportForProfileAndLevel(profile, level);
   2628 
   2629         if (err != OK) {
   2630             return err;
   2631         }
   2632 
   2633         h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
   2634         h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
   2635     }
   2636 
   2637     // XXX
   2638     if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
   2639         ALOGW("Use baseline profile instead of %d for AVC recording",
   2640             h264type.eProfile);
   2641         h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
   2642     }
   2643 
   2644     if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
   2645         h264type.nSliceHeaderSpacing = 0;
   2646         h264type.bUseHadamard = OMX_TRUE;
   2647         h264type.nRefFrames = 1;
   2648         h264type.nBFrames = 0;
   2649         h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
   2650         if (h264type.nPFrames == 0) {
   2651             h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
   2652         }
   2653         h264type.nRefIdx10ActiveMinus1 = 0;
   2654         h264type.nRefIdx11ActiveMinus1 = 0;
   2655         h264type.bEntropyCodingCABAC = OMX_FALSE;
   2656         h264type.bWeightedPPrediction = OMX_FALSE;
   2657         h264type.bconstIpred = OMX_FALSE;
   2658         h264type.bDirect8x8Inference = OMX_FALSE;
   2659         h264type.bDirectSpatialTemporal = OMX_FALSE;
   2660         h264type.nCabacInitIdc = 0;
   2661     }
   2662 
   2663     if (h264type.nBFrames != 0) {
   2664         h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
   2665     }
   2666 
   2667     h264type.bEnableUEP = OMX_FALSE;
   2668     h264type.bEnableFMO = OMX_FALSE;
   2669     h264type.bEnableASO = OMX_FALSE;
   2670     h264type.bEnableRS = OMX_FALSE;
   2671     h264type.bFrameMBsOnly = OMX_TRUE;
   2672     h264type.bMBAFF = OMX_FALSE;
   2673     h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
   2674 
   2675     err = mOMX->setParameter(
   2676             mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
   2677 
   2678     if (err != OK) {
   2679         return err;
   2680     }
   2681 
   2682     return configureBitrate(bitrate, bitrateMode);
   2683 }
   2684 
   2685 status_t ACodec::setupHEVCEncoderParameters(const sp<AMessage> &msg) {
   2686     int32_t bitrate, iFrameInterval;
   2687     if (!msg->findInt32("bitrate", &bitrate)
   2688             || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
   2689         return INVALID_OPERATION;
   2690     }
   2691 
   2692     OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
   2693 
   2694     float frameRate;
   2695     if (!msg->findFloat("frame-rate", &frameRate)) {
   2696         int32_t tmp;
   2697         if (!msg->findInt32("frame-rate", &tmp)) {
   2698             return INVALID_OPERATION;
   2699         }
   2700         frameRate = (float)tmp;
   2701     }
   2702 
   2703     OMX_VIDEO_PARAM_HEVCTYPE hevcType;
   2704     InitOMXParams(&hevcType);
   2705     hevcType.nPortIndex = kPortIndexOutput;
   2706 
   2707     status_t err = OK;
   2708     err = mOMX->getParameter(
   2709             mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
   2710     if (err != OK) {
   2711         return err;
   2712     }
   2713 
   2714     int32_t profile;
   2715     if (msg->findInt32("profile", &profile)) {
   2716         int32_t level;
   2717         if (!msg->findInt32("level", &level)) {
   2718             return INVALID_OPERATION;
   2719         }
   2720 
   2721         err = verifySupportForProfileAndLevel(profile, level);
   2722         if (err != OK) {
   2723             return err;
   2724         }
   2725 
   2726         hevcType.eProfile = static_cast<OMX_VIDEO_HEVCPROFILETYPE>(profile);
   2727         hevcType.eLevel = static_cast<OMX_VIDEO_HEVCLEVELTYPE>(level);
   2728     }
   2729 
   2730     // TODO: Need OMX structure definition for setting iFrameInterval
   2731 
   2732     err = mOMX->setParameter(
   2733             mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
   2734     if (err != OK) {
   2735         return err;
   2736     }
   2737 
   2738     return configureBitrate(bitrate, bitrateMode);
   2739 }
   2740 
   2741 status_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg) {
   2742     int32_t bitrate;
   2743     int32_t iFrameInterval = 0;
   2744     size_t tsLayers = 0;
   2745     OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE pattern =
   2746         OMX_VIDEO_VPXTemporalLayerPatternNone;
   2747     static const uint32_t kVp8LayerRateAlloction
   2748         [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS]
   2749         [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] = {
   2750         {100, 100, 100},  // 1 layer
   2751         { 60, 100, 100},  // 2 layers {60%, 40%}
   2752         { 40,  60, 100},  // 3 layers {40%, 20%, 40%}
   2753     };
   2754     if (!msg->findInt32("bitrate", &bitrate)) {
   2755         return INVALID_OPERATION;
   2756     }
   2757     msg->findInt32("i-frame-interval", &iFrameInterval);
   2758 
   2759     OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
   2760 
   2761     float frameRate;
   2762     if (!msg->findFloat("frame-rate", &frameRate)) {
   2763         int32_t tmp;
   2764         if (!msg->findInt32("frame-rate", &tmp)) {
   2765             return INVALID_OPERATION;
   2766         }
   2767         frameRate = (float)tmp;
   2768     }
   2769 
   2770     AString tsSchema;
   2771     if (msg->findString("ts-schema", &tsSchema)) {
   2772         if (tsSchema == "webrtc.vp8.1-layer") {
   2773             pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
   2774             tsLayers = 1;
   2775         } else if (tsSchema == "webrtc.vp8.2-layer") {
   2776             pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
   2777             tsLayers = 2;
   2778         } else if (tsSchema == "webrtc.vp8.3-layer") {
   2779             pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
   2780             tsLayers = 3;
   2781         } else {
   2782             ALOGW("Unsupported ts-schema [%s]", tsSchema.c_str());
   2783         }
   2784     }
   2785 
   2786     OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
   2787     InitOMXParams(&vp8type);
   2788     vp8type.nPortIndex = kPortIndexOutput;
   2789     status_t err = mOMX->getParameter(
   2790             mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
   2791             &vp8type, sizeof(vp8type));
   2792 
   2793     if (err == OK) {
   2794         if (iFrameInterval > 0) {
   2795             vp8type.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate);
   2796         }
   2797         vp8type.eTemporalPattern = pattern;
   2798         vp8type.nTemporalLayerCount = tsLayers;
   2799         if (tsLayers > 0) {
   2800             for (size_t i = 0; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) {
   2801                 vp8type.nTemporalLayerBitrateRatio[i] =
   2802                     kVp8LayerRateAlloction[tsLayers - 1][i];
   2803             }
   2804         }
   2805         if (bitrateMode == OMX_Video_ControlRateConstant) {
   2806             vp8type.nMinQuantizer = 2;
   2807             vp8type.nMaxQuantizer = 63;
   2808         }
   2809 
   2810         err = mOMX->setParameter(
   2811                 mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
   2812                 &vp8type, sizeof(vp8type));
   2813         if (err != OK) {
   2814             ALOGW("Extended VP8 parameters set failed: %d", err);
   2815         }
   2816     }
   2817 
   2818     return configureBitrate(bitrate, bitrateMode);
   2819 }
   2820 
   2821 status_t ACodec::verifySupportForProfileAndLevel(
   2822         int32_t profile, int32_t level) {
   2823     OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
   2824     InitOMXParams(&params);
   2825     params.nPortIndex = kPortIndexOutput;
   2826 
   2827     for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
   2828         status_t err = mOMX->getParameter(
   2829                 mNode,
   2830                 OMX_IndexParamVideoProfileLevelQuerySupported,
   2831                 &params,
   2832                 sizeof(params));
   2833 
   2834         if (err != OK) {
   2835             return err;
   2836         }
   2837 
   2838         int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
   2839         int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
   2840 
   2841         if (profile == supportedProfile && level <= supportedLevel) {
   2842             return OK;
   2843         }
   2844     }
   2845 }
   2846 
   2847 status_t ACodec::configureBitrate(
   2848         int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
   2849     OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
   2850     InitOMXParams(&bitrateType);
   2851     bitrateType.nPortIndex = kPortIndexOutput;
   2852 
   2853     status_t err = mOMX->getParameter(
   2854             mNode, OMX_IndexParamVideoBitrate,
   2855             &bitrateType, sizeof(bitrateType));
   2856 
   2857     if (err != OK) {
   2858         return err;
   2859     }
   2860 
   2861     bitrateType.eControlRate = bitrateMode;
   2862     bitrateType.nTargetBitrate = bitrate;
   2863 
   2864     return mOMX->setParameter(
   2865             mNode, OMX_IndexParamVideoBitrate,
   2866             &bitrateType, sizeof(bitrateType));
   2867 }
   2868 
   2869 status_t ACodec::setupErrorCorrectionParameters() {
   2870     OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
   2871     InitOMXParams(&errorCorrectionType);
   2872     errorCorrectionType.nPortIndex = kPortIndexOutput;
   2873 
   2874     status_t err = mOMX->getParameter(
   2875             mNode, OMX_IndexParamVideoErrorCorrection,
   2876             &errorCorrectionType, sizeof(errorCorrectionType));
   2877 
   2878     if (err != OK) {
   2879         return OK;  // Optional feature. Ignore this failure
   2880     }
   2881 
   2882     errorCorrectionType.bEnableHEC = OMX_FALSE;
   2883     errorCorrectionType.bEnableResync = OMX_TRUE;
   2884     errorCorrectionType.nResynchMarkerSpacing = 256;
   2885     errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
   2886     errorCorrectionType.bEnableRVLC = OMX_FALSE;
   2887 
   2888     return mOMX->setParameter(
   2889             mNode, OMX_IndexParamVideoErrorCorrection,
   2890             &errorCorrectionType, sizeof(errorCorrectionType));
   2891 }
   2892 
   2893 status_t ACodec::setVideoFormatOnPort(
   2894         OMX_U32 portIndex,
   2895         int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat) {
   2896     OMX_PARAM_PORTDEFINITIONTYPE def;
   2897     InitOMXParams(&def);
   2898     def.nPortIndex = portIndex;
   2899 
   2900     OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
   2901 
   2902     status_t err = mOMX->getParameter(
   2903             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
   2904 
   2905     CHECK_EQ(err, (status_t)OK);
   2906 
   2907     if (portIndex == kPortIndexInput) {
   2908         // XXX Need a (much) better heuristic to compute input buffer sizes.
   2909         const size_t X = 64 * 1024;
   2910         if (def.nBufferSize < X) {
   2911             def.nBufferSize = X;
   2912         }
   2913     }
   2914 
   2915     CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
   2916 
   2917     video_def->nFrameWidth = width;
   2918     video_def->nFrameHeight = height;
   2919 
   2920     if (portIndex == kPortIndexInput) {
   2921         video_def->eCompressionFormat = compressionFormat;
   2922         video_def->eColorFormat = OMX_COLOR_FormatUnused;
   2923     }
   2924 
   2925     err = mOMX->setParameter(
   2926             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
   2927 
   2928     return err;
   2929 }
   2930 
   2931 status_t ACodec::initNativeWindow() {
   2932     if (mNativeWindow != NULL) {
   2933         return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
   2934     }
   2935 
   2936     mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
   2937     return OK;
   2938 }
   2939 
   2940 size_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
   2941     size_t n = 0;
   2942 
   2943     for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
   2944         const BufferInfo &info = mBuffers[portIndex].itemAt(i);
   2945 
   2946         if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
   2947             ++n;
   2948         }
   2949     }
   2950 
   2951     return n;
   2952 }
   2953 
   2954 size_t ACodec::countBuffersOwnedByNativeWindow() const {
   2955     size_t n = 0;
   2956 
   2957     for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
   2958         const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
   2959 
   2960         if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
   2961             ++n;
   2962         }
   2963     }
   2964 
   2965     return n;
   2966 }
   2967 
   2968 void ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
   2969     if (mNativeWindow == NULL) {
   2970         return;
   2971     }
   2972 
   2973     while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers
   2974             && dequeueBufferFromNativeWindow() != NULL) {
   2975         // these buffers will be submitted as regular buffers; account for this
   2976         if (mStoreMetaDataInOutputBuffers && mMetaDataBuffersToSubmit > 0) {
   2977             --mMetaDataBuffersToSubmit;
   2978         }
   2979     }
   2980 }
   2981 
   2982 bool ACodec::allYourBuffersAreBelongToUs(
   2983         OMX_U32 portIndex) {
   2984     for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
   2985         BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
   2986 
   2987         if (info->mStatus != BufferInfo::OWNED_BY_US
   2988                 && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
   2989             ALOGV("[%s] Buffer %u on port %u still has status %d",
   2990                     mComponentName.c_str(),
   2991                     info->mBufferID, portIndex, info->mStatus);
   2992             return false;
   2993         }
   2994     }
   2995 
   2996     return true;
   2997 }
   2998 
   2999 bool ACodec::allYourBuffersAreBelongToUs() {
   3000     return allYourBuffersAreBelongToUs(kPortIndexInput)
   3001         && allYourBuffersAreBelongToUs(kPortIndexOutput);
   3002 }
   3003 
   3004 void ACodec::deferMessage(const sp<AMessage> &msg) {
   3005     bool wasEmptyBefore = mDeferredQueue.empty();
   3006     mDeferredQueue.push_back(msg);
   3007 }
   3008 
   3009 void ACodec::processDeferredMessages() {
   3010     List<sp<AMessage> > queue = mDeferredQueue;
   3011     mDeferredQueue.clear();
   3012 
   3013     List<sp<AMessage> >::iterator it = queue.begin();
   3014     while (it != queue.end()) {
   3015         onMessageReceived(*it++);
   3016     }
   3017 }
   3018 
   3019 // static
   3020 bool ACodec::describeDefaultColorFormat(DescribeColorFormatParams &params) {
   3021     MediaImage &image = params.sMediaImage;
   3022     memset(&image, 0, sizeof(image));
   3023 
   3024     image.mType = MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
   3025     image.mNumPlanes = 0;
   3026 
   3027     const OMX_COLOR_FORMATTYPE fmt = params.eColorFormat;
   3028     image.mWidth = params.nFrameWidth;
   3029     image.mHeight = params.nFrameHeight;
   3030 
   3031     // only supporting YUV420
   3032     if (fmt != OMX_COLOR_FormatYUV420Planar &&
   3033         fmt != OMX_COLOR_FormatYUV420PackedPlanar &&
   3034         fmt != OMX_COLOR_FormatYUV420SemiPlanar &&
   3035         fmt != OMX_COLOR_FormatYUV420PackedSemiPlanar) {
   3036         ALOGW("do not know color format 0x%x = %d", fmt, fmt);
   3037         return false;
   3038     }
   3039 
   3040     // TEMPORARY FIX for some vendors that advertise sliceHeight as 0
   3041     if (params.nStride != 0 && params.nSliceHeight == 0) {
   3042         ALOGW("using sliceHeight=%u instead of what codec advertised (=0)",
   3043                 params.nFrameHeight);
   3044         params.nSliceHeight = params.nFrameHeight;
   3045     }
   3046 
   3047     // we need stride and slice-height to be non-zero
   3048     if (params.nStride == 0 || params.nSliceHeight == 0) {
   3049         ALOGW("cannot describe color format 0x%x = %d with stride=%u and sliceHeight=%u",
   3050                 fmt, fmt, params.nStride, params.nSliceHeight);
   3051         return false;
   3052     }
   3053 
   3054     // set-up YUV format
   3055     image.mType = MediaImage::MEDIA_IMAGE_TYPE_YUV;
   3056     image.mNumPlanes = 3;
   3057     image.mBitDepth = 8;
   3058     image.mPlane[image.Y].mOffset = 0;
   3059     image.mPlane[image.Y].mColInc = 1;
   3060     image.mPlane[image.Y].mRowInc = params.nStride;
   3061     image.mPlane[image.Y].mHorizSubsampling = 1;
   3062     image.mPlane[image.Y].mVertSubsampling = 1;
   3063 
   3064     switch (fmt) {
   3065         case OMX_COLOR_FormatYUV420Planar: // used for YV12
   3066         case OMX_COLOR_FormatYUV420PackedPlanar:
   3067             image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
   3068             image.mPlane[image.U].mColInc = 1;
   3069             image.mPlane[image.U].mRowInc = params.nStride / 2;
   3070             image.mPlane[image.U].mHorizSubsampling = 2;
   3071             image.mPlane[image.U].mVertSubsampling = 2;
   3072 
   3073             image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset
   3074                     + (params.nStride * params.nSliceHeight / 4);
   3075             image.mPlane[image.V].mColInc = 1;
   3076             image.mPlane[image.V].mRowInc = params.nStride / 2;
   3077             image.mPlane[image.V].mHorizSubsampling = 2;
   3078             image.mPlane[image.V].mVertSubsampling = 2;
   3079             break;
   3080 
   3081         case OMX_COLOR_FormatYUV420SemiPlanar:
   3082             // FIXME: NV21 for sw-encoder, NV12 for decoder and hw-encoder
   3083         case OMX_COLOR_FormatYUV420PackedSemiPlanar:
   3084             // NV12
   3085             image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
   3086             image.mPlane[image.U].mColInc = 2;
   3087             image.mPlane[image.U].mRowInc = params.nStride;
   3088             image.mPlane[image.U].mHorizSubsampling = 2;
   3089             image.mPlane[image.U].mVertSubsampling = 2;
   3090 
   3091             image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset + 1;
   3092             image.mPlane[image.V].mColInc = 2;
   3093             image.mPlane[image.V].mRowInc = params.nStride;
   3094             image.mPlane[image.V].mHorizSubsampling = 2;
   3095             image.mPlane[image.V].mVertSubsampling = 2;
   3096             break;
   3097 
   3098         default:
   3099             TRESPASS();
   3100     }
   3101     return true;
   3102 }
   3103 
   3104 // static
   3105 bool ACodec::describeColorFormat(
   3106         const sp<IOMX> &omx, IOMX::node_id node,
   3107         DescribeColorFormatParams &describeParams)
   3108 {
   3109     OMX_INDEXTYPE describeColorFormatIndex;
   3110     if (omx->getExtensionIndex(
   3111             node, "OMX.google.android.index.describeColorFormat",
   3112             &describeColorFormatIndex) != OK ||
   3113         omx->getParameter(
   3114             node, describeColorFormatIndex,
   3115             &describeParams, sizeof(describeParams)) != OK) {
   3116         return describeDefaultColorFormat(describeParams);
   3117     }
   3118     return describeParams.sMediaImage.mType !=
   3119             MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
   3120 }
   3121 
   3122 // static
   3123 bool ACodec::isFlexibleColorFormat(
   3124          const sp<IOMX> &omx, IOMX::node_id node,
   3125          uint32_t colorFormat, OMX_U32 *flexibleEquivalent) {
   3126     DescribeColorFormatParams describeParams;
   3127     InitOMXParams(&describeParams);
   3128     describeParams.eColorFormat = (OMX_COLOR_FORMATTYPE)colorFormat;
   3129     // reasonable dummy values
   3130     describeParams.nFrameWidth = 128;
   3131     describeParams.nFrameHeight = 128;
   3132     describeParams.nStride = 128;
   3133     describeParams.nSliceHeight = 128;
   3134 
   3135     CHECK(flexibleEquivalent != NULL);
   3136 
   3137     if (!describeColorFormat(omx, node, describeParams)) {
   3138         return false;
   3139     }
   3140 
   3141     const MediaImage &img = describeParams.sMediaImage;
   3142     if (img.mType == MediaImage::MEDIA_IMAGE_TYPE_YUV) {
   3143         if (img.mNumPlanes != 3 ||
   3144             img.mPlane[img.Y].mHorizSubsampling != 1 ||
   3145             img.mPlane[img.Y].mVertSubsampling != 1) {
   3146             return false;
   3147         }
   3148 
   3149         // YUV 420
   3150         if (img.mPlane[img.U].mHorizSubsampling == 2
   3151                 && img.mPlane[img.U].mVertSubsampling == 2
   3152                 && img.mPlane[img.V].mHorizSubsampling == 2
   3153                 && img.mPlane[img.V].mVertSubsampling == 2) {
   3154             // possible flexible YUV420 format
   3155             if (img.mBitDepth <= 8) {
   3156                *flexibleEquivalent = OMX_COLOR_FormatYUV420Flexible;
   3157                return true;
   3158             }
   3159         }
   3160     }
   3161     return false;
   3162 }
   3163 
   3164 status_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify) {
   3165     // TODO: catch errors an return them instead of using CHECK
   3166     OMX_PARAM_PORTDEFINITIONTYPE def;
   3167     InitOMXParams(&def);
   3168     def.nPortIndex = portIndex;
   3169 
   3170     CHECK_EQ(mOMX->getParameter(
   3171                 mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)),
   3172              (status_t)OK);
   3173 
   3174     CHECK_EQ((int)def.eDir,
   3175             (int)(portIndex == kPortIndexOutput ? OMX_DirOutput : OMX_DirInput));
   3176 
   3177     switch (def.eDomain) {
   3178         case OMX_PortDomainVideo:
   3179         {
   3180             OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
   3181             switch ((int)videoDef->eCompressionFormat) {
   3182                 case OMX_VIDEO_CodingUnused:
   3183                 {
   3184                     CHECK(mIsEncoder ^ (portIndex == kPortIndexOutput));
   3185                     notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
   3186 
   3187                     notify->setInt32("stride", videoDef->nStride);
   3188                     notify->setInt32("slice-height", videoDef->nSliceHeight);
   3189                     notify->setInt32("color-format", videoDef->eColorFormat);
   3190 
   3191                     DescribeColorFormatParams describeParams;
   3192                     InitOMXParams(&describeParams);
   3193                     describeParams.eColorFormat = videoDef->eColorFormat;
   3194                     describeParams.nFrameWidth = videoDef->nFrameWidth;
   3195                     describeParams.nFrameHeight = videoDef->nFrameHeight;
   3196                     describeParams.nStride = videoDef->nStride;
   3197                     describeParams.nSliceHeight = videoDef->nSliceHeight;
   3198 
   3199                     if (describeColorFormat(mOMX, mNode, describeParams)) {
   3200                         notify->setBuffer(
   3201                                 "image-data",
   3202                                 ABuffer::CreateAsCopy(
   3203                                         &describeParams.sMediaImage,
   3204                                         sizeof(describeParams.sMediaImage)));
   3205                     }
   3206 
   3207                     if (portIndex != kPortIndexOutput) {
   3208                         // TODO: also get input crop
   3209                         break;
   3210                     }
   3211 
   3212                     OMX_CONFIG_RECTTYPE rect;
   3213                     InitOMXParams(&rect);
   3214                     rect.nPortIndex = portIndex;
   3215 
   3216                     if (mOMX->getConfig(
   3217                                 mNode,
   3218                                 (portIndex == kPortIndexOutput ?
   3219                                         OMX_IndexConfigCommonOutputCrop :
   3220                                         OMX_IndexConfigCommonInputCrop),
   3221                                 &rect, sizeof(rect)) != OK) {
   3222                         rect.nLeft = 0;
   3223                         rect.nTop = 0;
   3224                         rect.nWidth = videoDef->nFrameWidth;
   3225                         rect.nHeight = videoDef->nFrameHeight;
   3226                     }
   3227 
   3228                     CHECK_GE(rect.nLeft, 0);
   3229                     CHECK_GE(rect.nTop, 0);
   3230                     CHECK_GE(rect.nWidth, 0u);
   3231                     CHECK_GE(rect.nHeight, 0u);
   3232                     CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth);
   3233                     CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight);
   3234 
   3235                     notify->setRect(
   3236                             "crop",
   3237                             rect.nLeft,
   3238                             rect.nTop,
   3239                             rect.nLeft + rect.nWidth - 1,
   3240                             rect.nTop + rect.nHeight - 1);
   3241 
   3242                     break;
   3243                 }
   3244 
   3245                 case OMX_VIDEO_CodingVP8:
   3246                 case OMX_VIDEO_CodingVP9:
   3247                 {
   3248                     OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
   3249                     InitOMXParams(&vp8type);
   3250                     vp8type.nPortIndex = kPortIndexOutput;
   3251                     status_t err = mOMX->getParameter(
   3252                             mNode,
   3253                             (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
   3254                             &vp8type,
   3255                             sizeof(vp8type));
   3256 
   3257                     if (err == OK) {
   3258                         AString tsSchema = "none";
   3259                         if (vp8type.eTemporalPattern
   3260                                 == OMX_VIDEO_VPXTemporalLayerPatternWebRTC) {
   3261                             switch (vp8type.nTemporalLayerCount) {
   3262                                 case 1:
   3263                                 {
   3264                                     tsSchema = "webrtc.vp8.1-layer";
   3265                                     break;
   3266                                 }
   3267                                 case 2:
   3268                                 {
   3269                                     tsSchema = "webrtc.vp8.2-layer";
   3270                                     break;
   3271                                 }
   3272                                 case 3:
   3273                                 {
   3274                                     tsSchema = "webrtc.vp8.3-layer";
   3275                                     break;
   3276                                 }
   3277                                 default:
   3278                                 {
   3279                                     break;
   3280                                 }
   3281                             }
   3282                         }
   3283                         notify->setString("ts-schema", tsSchema);
   3284                     }
   3285                     // Fall through to set up mime.
   3286                 }
   3287 
   3288                 default:
   3289                 {
   3290                     CHECK(mIsEncoder ^ (portIndex == kPortIndexInput));
   3291                     AString mime;
   3292                     if (GetMimeTypeForVideoCoding(
   3293                         videoDef->eCompressionFormat, &mime) != OK) {
   3294                         notify->setString("mime", "application/octet-stream");
   3295                     } else {
   3296                         notify->setString("mime", mime.c_str());
   3297                     }
   3298                     break;
   3299                 }
   3300             }
   3301 
   3302             notify->setInt32("width", videoDef->nFrameWidth);
   3303             notify->setInt32("height", videoDef->nFrameHeight);
   3304             break;
   3305         }
   3306 
   3307         case OMX_PortDomainAudio:
   3308         {
   3309             OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
   3310 
   3311             switch ((int)audioDef->eEncoding) {
   3312                 case OMX_AUDIO_CodingPCM:
   3313                 {
   3314                     OMX_AUDIO_PARAM_PCMMODETYPE params;
   3315                     InitOMXParams(&params);
   3316                     params.nPortIndex = portIndex;
   3317 
   3318                     CHECK_EQ(mOMX->getParameter(
   3319                                 mNode, OMX_IndexParamAudioPcm,
   3320                                 &params, sizeof(params)),
   3321                              (status_t)OK);
   3322 
   3323                     CHECK_GT(params.nChannels, 0);
   3324                     CHECK(params.nChannels == 1 || params.bInterleaved);
   3325                     CHECK_EQ(params.nBitPerSample, 16u);
   3326 
   3327                     CHECK_EQ((int)params.eNumData,
   3328                              (int)OMX_NumericalDataSigned);
   3329 
   3330                     CHECK_EQ((int)params.ePCMMode,
   3331                              (int)OMX_AUDIO_PCMModeLinear);
   3332 
   3333                     notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
   3334                     notify->setInt32("channel-count", params.nChannels);
   3335                     notify->setInt32("sample-rate", params.nSamplingRate);
   3336 
   3337                     if (mChannelMaskPresent) {
   3338                         notify->setInt32("channel-mask", mChannelMask);
   3339                     }
   3340                     break;
   3341                 }
   3342 
   3343                 case OMX_AUDIO_CodingAAC:
   3344                 {
   3345                     OMX_AUDIO_PARAM_AACPROFILETYPE params;
   3346                     InitOMXParams(&params);
   3347                     params.nPortIndex = portIndex;
   3348 
   3349                     CHECK_EQ(mOMX->getParameter(
   3350                                 mNode, OMX_IndexParamAudioAac,
   3351                                 &params, sizeof(params)),
   3352                              (status_t)OK);
   3353 
   3354                     notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
   3355                     notify->setInt32("channel-count", params.nChannels);
   3356                     notify->setInt32("sample-rate", params.nSampleRate);
   3357                     break;
   3358                 }
   3359 
   3360                 case OMX_AUDIO_CodingAMR:
   3361                 {
   3362                     OMX_AUDIO_PARAM_AMRTYPE params;
   3363                     InitOMXParams(&params);
   3364                     params.nPortIndex = portIndex;
   3365 
   3366                     CHECK_EQ(mOMX->getParameter(
   3367                                 mNode, OMX_IndexParamAudioAmr,
   3368                                 &params, sizeof(params)),
   3369                              (status_t)OK);
   3370 
   3371                     notify->setInt32("channel-count", 1);
   3372                     if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
   3373                         notify->setString(
   3374                                 "mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
   3375 
   3376                         notify->setInt32("sample-rate", 16000);
   3377                     } else {
   3378                         notify->setString(
   3379                                 "mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
   3380 
   3381                         notify->setInt32("sample-rate", 8000);
   3382                     }
   3383                     break;
   3384                 }
   3385 
   3386                 case OMX_AUDIO_CodingFLAC:
   3387                 {
   3388                     OMX_AUDIO_PARAM_FLACTYPE params;
   3389                     InitOMXParams(&params);
   3390                     params.nPortIndex = portIndex;
   3391 
   3392                     CHECK_EQ(mOMX->getParameter(
   3393                                 mNode, OMX_IndexParamAudioFlac,
   3394                                 &params, sizeof(params)),
   3395                              (status_t)OK);
   3396 
   3397                     notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
   3398                     notify->setInt32("channel-count", params.nChannels);
   3399                     notify->setInt32("sample-rate", params.nSampleRate);
   3400                     break;
   3401                 }
   3402 
   3403                 case OMX_AUDIO_CodingMP3:
   3404                 {
   3405                     OMX_AUDIO_PARAM_MP3TYPE params;
   3406                     InitOMXParams(&params);
   3407                     params.nPortIndex = portIndex;
   3408 
   3409                     CHECK_EQ(mOMX->getParameter(
   3410                                 mNode, OMX_IndexParamAudioMp3,
   3411                                 &params, sizeof(params)),
   3412                              (status_t)OK);
   3413 
   3414                     notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MPEG);
   3415                     notify->setInt32("channel-count", params.nChannels);
   3416                     notify->setInt32("sample-rate", params.nSampleRate);
   3417                     break;
   3418                 }
   3419 
   3420                 case OMX_AUDIO_CodingVORBIS:
   3421                 {
   3422                     OMX_AUDIO_PARAM_VORBISTYPE params;
   3423                     InitOMXParams(&params);
   3424                     params.nPortIndex = portIndex;
   3425 
   3426                     CHECK_EQ(mOMX->getParameter(
   3427                                 mNode, OMX_IndexParamAudioVorbis,
   3428                                 &params, sizeof(params)),
   3429                              (status_t)OK);
   3430 
   3431                     notify->setString("mime", MEDIA_MIMETYPE_AUDIO_VORBIS);
   3432                     notify->setInt32("channel-count", params.nChannels);
   3433                     notify->setInt32("sample-rate", params.nSampleRate);
   3434                     break;
   3435                 }
   3436 
   3437                 case OMX_AUDIO_CodingAndroidAC3:
   3438                 {
   3439                     OMX_AUDIO_PARAM_ANDROID_AC3TYPE params;
   3440                     InitOMXParams(&params);
   3441                     params.nPortIndex = portIndex;
   3442 
   3443                     CHECK_EQ((status_t)OK, mOMX->getParameter(
   3444                             mNode,
   3445                             (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
   3446                             &params,
   3447                             sizeof(params)));
   3448 
   3449                     notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3);
   3450                     notify->setInt32("channel-count", params.nChannels);
   3451                     notify->setInt32("sample-rate", params.nSampleRate);
   3452                     break;
   3453                 }
   3454 
   3455                 case OMX_AUDIO_CodingAndroidOPUS:
   3456                 {
   3457                     OMX_AUDIO_PARAM_ANDROID_OPUSTYPE params;
   3458                     InitOMXParams(&params);
   3459                     params.nPortIndex = portIndex;
   3460 
   3461                     CHECK_EQ((status_t)OK, mOMX->getParameter(
   3462                             mNode,
   3463                             (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
   3464                             &params,
   3465                             sizeof(params)));
   3466 
   3467                     notify->setString("mime", MEDIA_MIMETYPE_AUDIO_OPUS);
   3468                     notify->setInt32("channel-count", params.nChannels);
   3469                     notify->setInt32("sample-rate", params.nSampleRate);
   3470                     break;
   3471                 }
   3472 
   3473                 case OMX_AUDIO_CodingG711:
   3474                 {
   3475                     OMX_AUDIO_PARAM_PCMMODETYPE params;
   3476                     InitOMXParams(&params);
   3477                     params.nPortIndex = portIndex;
   3478 
   3479                     CHECK_EQ((status_t)OK, mOMX->getParameter(
   3480                             mNode,
   3481                             (OMX_INDEXTYPE)OMX_IndexParamAudioPcm,
   3482                             &params,
   3483                             sizeof(params)));
   3484 
   3485                     const char *mime = NULL;
   3486                     if (params.ePCMMode == OMX_AUDIO_PCMModeMULaw) {
   3487                         mime = MEDIA_MIMETYPE_AUDIO_G711_MLAW;
   3488                     } else if (params.ePCMMode == OMX_AUDIO_PCMModeALaw) {
   3489                         mime = MEDIA_MIMETYPE_AUDIO_G711_ALAW;
   3490                     } else { // params.ePCMMode == OMX_AUDIO_PCMModeLinear
   3491                         mime = MEDIA_MIMETYPE_AUDIO_RAW;
   3492                     }
   3493                     notify->setString("mime", mime);
   3494                     notify->setInt32("channel-count", params.nChannels);
   3495                     notify->setInt32("sample-rate", params.nSamplingRate);
   3496                     break;
   3497                 }
   3498 
   3499                 default:
   3500                     ALOGE("UNKNOWN AUDIO CODING: %d\n", audioDef->eEncoding);
   3501                     TRESPASS();
   3502             }
   3503             break;
   3504         }
   3505 
   3506         default:
   3507             TRESPASS();
   3508     }
   3509 
   3510     return OK;
   3511 }
   3512 
   3513 void ACodec::sendFormatChange(const sp<AMessage> &reply) {
   3514     sp<AMessage> notify = mNotify->dup();
   3515     notify->setInt32("what", kWhatOutputFormatChanged);
   3516 
   3517     CHECK_EQ(getPortFormat(kPortIndexOutput, notify), (status_t)OK);
   3518 
   3519     AString mime;
   3520     CHECK(notify->findString("mime", &mime));
   3521 
   3522     int32_t left, top, right, bottom;
   3523     if (mime == MEDIA_MIMETYPE_VIDEO_RAW &&
   3524         mNativeWindow != NULL &&
   3525         notify->findRect("crop", &left, &top, &right, &bottom)) {
   3526         // notify renderer of the crop change
   3527         // NOTE: native window uses extended right-bottom coordinate
   3528         reply->setRect("crop", left, top, right + 1, bottom + 1);
   3529     } else if (mime == MEDIA_MIMETYPE_AUDIO_RAW &&
   3530                (mEncoderDelay || mEncoderPadding)) {
   3531         int32_t channelCount;
   3532         CHECK(notify->findInt32("channel-count", &channelCount));
   3533         size_t frameSize = channelCount * sizeof(int16_t);
   3534         if (mSkipCutBuffer != NULL) {
   3535             size_t prevbufsize = mSkipCutBuffer->size();
   3536             if (prevbufsize != 0) {
   3537                 ALOGW("Replacing SkipCutBuffer holding %d "
   3538                       "bytes",
   3539                       prevbufsize);
   3540             }
   3541         }
   3542         mSkipCutBuffer = new SkipCutBuffer(
   3543                 mEncoderDelay * frameSize,
   3544                 mEncoderPadding * frameSize);
   3545     }
   3546 
   3547     notify->post();
   3548 
   3549     mSentFormat = true;
   3550 }
   3551 
   3552 void ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
   3553     sp<AMessage> notify = mNotify->dup();
   3554     notify->setInt32("what", CodecBase::kWhatError);
   3555     ALOGE("signalError(omxError %#x, internalError %d)", error, internalError);
   3556 
   3557     if (internalError == UNKNOWN_ERROR) { // find better error code
   3558         const status_t omxStatus = statusFromOMXError(error);
   3559         if (omxStatus != 0) {
   3560             internalError = omxStatus;
   3561         } else {
   3562             ALOGW("Invalid OMX error %#x", error);
   3563         }
   3564     }
   3565     notify->setInt32("err", internalError);
   3566     notify->setInt32("actionCode", ACTION_CODE_FATAL); // could translate from OMX error.
   3567     notify->post();
   3568 }
   3569 
   3570 status_t ACodec::pushBlankBuffersToNativeWindow() {
   3571     status_t err = NO_ERROR;
   3572     ANativeWindowBuffer* anb = NULL;
   3573     int numBufs = 0;
   3574     int minUndequeuedBufs = 0;
   3575 
   3576     // We need to reconnect to the ANativeWindow as a CPU client to ensure that
   3577     // no frames get dropped by SurfaceFlinger assuming that these are video
   3578     // frames.
   3579     err = native_window_api_disconnect(mNativeWindow.get(),
   3580             NATIVE_WINDOW_API_MEDIA);
   3581     if (err != NO_ERROR) {
   3582         ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
   3583                 strerror(-err), -err);
   3584         return err;
   3585     }
   3586 
   3587     err = native_window_api_connect(mNativeWindow.get(),
   3588             NATIVE_WINDOW_API_CPU);
   3589     if (err != NO_ERROR) {
   3590         ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
   3591                 strerror(-err), -err);
   3592         return err;
   3593     }
   3594 
   3595     err = native_window_set_buffers_geometry(mNativeWindow.get(), 1, 1,
   3596             HAL_PIXEL_FORMAT_RGBX_8888);
   3597     if (err != NO_ERROR) {
   3598         ALOGE("error pushing blank frames: set_buffers_geometry failed: %s (%d)",
   3599                 strerror(-err), -err);
   3600         goto error;
   3601     }
   3602 
   3603     err = native_window_set_scaling_mode(mNativeWindow.get(),
   3604                 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
   3605     if (err != NO_ERROR) {
   3606         ALOGE("error pushing blank_frames: set_scaling_mode failed: %s (%d)",
   3607               strerror(-err), -err);
   3608         goto error;
   3609     }
   3610 
   3611     err = native_window_set_usage(mNativeWindow.get(),
   3612             GRALLOC_USAGE_SW_WRITE_OFTEN);
   3613     if (err != NO_ERROR) {
   3614         ALOGE("error pushing blank frames: set_usage failed: %s (%d)",
   3615                 strerror(-err), -err);
   3616         goto error;
   3617     }
   3618 
   3619     err = mNativeWindow->query(mNativeWindow.get(),
   3620             NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
   3621     if (err != NO_ERROR) {
   3622         ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query "
   3623                 "failed: %s (%d)", strerror(-err), -err);
   3624         goto error;
   3625     }
   3626 
   3627     numBufs = minUndequeuedBufs + 1;
   3628     err = native_window_set_buffer_count(mNativeWindow.get(), numBufs);
   3629     if (err != NO_ERROR) {
   3630         ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)",
   3631                 strerror(-err), -err);
   3632         goto error;
   3633     }
   3634 
   3635     // We  push numBufs + 1 buffers to ensure that we've drawn into the same
   3636     // buffer twice.  This should guarantee that the buffer has been displayed
   3637     // on the screen and then been replaced, so an previous video frames are
   3638     // guaranteed NOT to be currently displayed.
   3639     for (int i = 0; i < numBufs + 1; i++) {
   3640         int fenceFd = -1;
   3641         err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb);
   3642         if (err != NO_ERROR) {
   3643             ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
   3644                     strerror(-err), -err);
   3645             goto error;
   3646         }
   3647 
   3648         sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
   3649 
   3650         // Fill the buffer with the a 1x1 checkerboard pattern ;)
   3651         uint32_t* img = NULL;
   3652         err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
   3653         if (err != NO_ERROR) {
   3654             ALOGE("error pushing blank frames: lock failed: %s (%d)",
   3655                     strerror(-err), -err);
   3656             goto error;
   3657         }
   3658 
   3659         *img = 0;
   3660 
   3661         err = buf->unlock();
   3662         if (err != NO_ERROR) {
   3663             ALOGE("error pushing blank frames: unlock failed: %s (%d)",
   3664                     strerror(-err), -err);
   3665             goto error;
   3666         }
   3667 
   3668         err = mNativeWindow->queueBuffer(mNativeWindow.get(),
   3669                 buf->getNativeBuffer(), -1);
   3670         if (err != NO_ERROR) {
   3671             ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
   3672                     strerror(-err), -err);
   3673             goto error;
   3674         }
   3675 
   3676         anb = NULL;
   3677     }
   3678 
   3679 error:
   3680 
   3681     if (err != NO_ERROR) {
   3682         // Clean up after an error.
   3683         if (anb != NULL) {
   3684             mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1);
   3685         }
   3686 
   3687         native_window_api_disconnect(mNativeWindow.get(),
   3688                 NATIVE_WINDOW_API_CPU);
   3689         native_window_api_connect(mNativeWindow.get(),
   3690                 NATIVE_WINDOW_API_MEDIA);
   3691 
   3692         return err;
   3693     } else {
   3694         // Clean up after success.
   3695         err = native_window_api_disconnect(mNativeWindow.get(),
   3696                 NATIVE_WINDOW_API_CPU);
   3697         if (err != NO_ERROR) {
   3698             ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
   3699                     strerror(-err), -err);
   3700             return err;
   3701         }
   3702 
   3703         err = native_window_api_connect(mNativeWindow.get(),
   3704                 NATIVE_WINDOW_API_MEDIA);
   3705         if (err != NO_ERROR) {
   3706             ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
   3707                     strerror(-err), -err);
   3708             return err;
   3709         }
   3710 
   3711         return NO_ERROR;
   3712     }
   3713 }
   3714 
   3715 ////////////////////////////////////////////////////////////////////////////////
   3716 
   3717 ACodec::PortDescription::PortDescription() {
   3718 }
   3719 
   3720 status_t ACodec::requestIDRFrame() {
   3721     if (!mIsEncoder) {
   3722         return ERROR_UNSUPPORTED;
   3723     }
   3724 
   3725     OMX_CONFIG_INTRAREFRESHVOPTYPE params;
   3726     InitOMXParams(&params);
   3727 
   3728     params.nPortIndex = kPortIndexOutput;
   3729     params.IntraRefreshVOP = OMX_TRUE;
   3730 
   3731     return mOMX->setConfig(
   3732             mNode,
   3733             OMX_IndexConfigVideoIntraVOPRefresh,
   3734             &params,
   3735             sizeof(params));
   3736 }
   3737 
   3738 void ACodec::PortDescription::addBuffer(
   3739         IOMX::buffer_id id, const sp<ABuffer> &buffer) {
   3740     mBufferIDs.push_back(id);
   3741     mBuffers.push_back(buffer);
   3742 }
   3743 
   3744 size_t ACodec::PortDescription::countBuffers() {
   3745     return mBufferIDs.size();
   3746 }
   3747 
   3748 IOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
   3749     return mBufferIDs.itemAt(index);
   3750 }
   3751 
   3752 sp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
   3753     return mBuffers.itemAt(index);
   3754 }
   3755 
   3756 ////////////////////////////////////////////////////////////////////////////////
   3757 
   3758 ACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
   3759     : AState(parentState),
   3760       mCodec(codec) {
   3761 }
   3762 
   3763 ACodec::BaseState::PortMode ACodec::BaseState::getPortMode(
   3764         OMX_U32 /* portIndex */) {
   3765     return KEEP_BUFFERS;
   3766 }
   3767 
   3768 bool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
   3769     switch (msg->what()) {
   3770         case kWhatInputBufferFilled:
   3771         {
   3772             onInputBufferFilled(msg);
   3773             break;
   3774         }
   3775 
   3776         case kWhatOutputBufferDrained:
   3777         {
   3778             onOutputBufferDrained(msg);
   3779             break;
   3780         }
   3781 
   3782         case ACodec::kWhatOMXMessage:
   3783         {
   3784             return onOMXMessage(msg);
   3785         }
   3786 
   3787         case ACodec::kWhatCreateInputSurface:
   3788         case ACodec::kWhatSignalEndOfInputStream:
   3789         {
   3790             // This may result in an app illegal state exception.
   3791             ALOGE("Message 0x%x was not handled", msg->what());
   3792             mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
   3793             return true;
   3794         }
   3795 
   3796         case ACodec::kWhatOMXDied:
   3797         {
   3798             // This will result in kFlagSawMediaServerDie handling in MediaCodec.
   3799             ALOGE("OMX/mediaserver died, signalling error!");
   3800             mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
   3801             break;
   3802         }
   3803 
   3804         case ACodec::kWhatReleaseCodecInstance:
   3805         {
   3806             ALOGI("[%s] forcing the release of codec",
   3807                     mCodec->mComponentName.c_str());
   3808             status_t err = mCodec->mOMX->freeNode(mCodec->mNode);
   3809             ALOGE_IF("[%s] failed to release codec instance: err=%d",
   3810                        mCodec->mComponentName.c_str(), err);
   3811             sp<AMessage> notify = mCodec->mNotify->dup();
   3812             notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
   3813             notify->post();
   3814             break;
   3815         }
   3816 
   3817         default:
   3818             return false;
   3819     }
   3820 
   3821     return true;
   3822 }
   3823 
   3824 bool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
   3825     int32_t type;
   3826     CHECK(msg->findInt32("type", &type));
   3827 
   3828     // there is a possibility that this is an outstanding message for a
   3829     // codec that we have already destroyed
   3830     if (mCodec->mNode == NULL) {
   3831         ALOGI("ignoring message as already freed component: %s",
   3832                 msg->debugString().c_str());
   3833         return true;
   3834     }
   3835 
   3836     IOMX::node_id nodeID;
   3837     CHECK(msg->findInt32("node", (int32_t*)&nodeID));
   3838     CHECK_EQ(nodeID, mCodec->mNode);
   3839 
   3840     switch (type) {
   3841         case omx_message::EVENT:
   3842         {
   3843             int32_t event, data1, data2;
   3844             CHECK(msg->findInt32("event", &event));
   3845             CHECK(msg->findInt32("data1", &data1));
   3846             CHECK(msg->findInt32("data2", &data2));
   3847 
   3848             if (event == OMX_EventCmdComplete
   3849                     && data1 == OMX_CommandFlush
   3850                     && data2 == (int32_t)OMX_ALL) {
   3851                 // Use of this notification is not consistent across
   3852                 // implementations. We'll drop this notification and rely
   3853                 // on flush-complete notifications on the individual port
   3854                 // indices instead.
   3855 
   3856                 return true;
   3857             }
   3858 
   3859             return onOMXEvent(
   3860                     static_cast<OMX_EVENTTYPE>(event),
   3861                     static_cast<OMX_U32>(data1),
   3862                     static_cast<OMX_U32>(data2));
   3863         }
   3864 
   3865         case omx_message::EMPTY_BUFFER_DONE:
   3866         {
   3867             IOMX::buffer_id bufferID;
   3868             CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
   3869 
   3870             return onOMXEmptyBufferDone(bufferID);
   3871         }
   3872 
   3873         case omx_message::FILL_BUFFER_DONE:
   3874         {
   3875             IOMX::buffer_id bufferID;
   3876             CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
   3877 
   3878             int32_t rangeOffset, rangeLength, flags;
   3879             int64_t timeUs;
   3880 
   3881             CHECK(msg->findInt32("range_offset", &rangeOffset));
   3882             CHECK(msg->findInt32("range_length", &rangeLength));
   3883             CHECK(msg->findInt32("flags", &flags));
   3884             CHECK(msg->findInt64("timestamp", &timeUs));
   3885 
   3886             return onOMXFillBufferDone(
   3887                     bufferID,
   3888                     (size_t)rangeOffset, (size_t)rangeLength,
   3889                     (OMX_U32)flags,
   3890                     timeUs);
   3891         }
   3892 
   3893         default:
   3894             TRESPASS();
   3895             break;
   3896     }
   3897 }
   3898 
   3899 bool ACodec::BaseState::onOMXEvent(
   3900         OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
   3901     if (event != OMX_EventError) {
   3902         ALOGV("[%s] EVENT(%d, 0x%08lx, 0x%08lx)",
   3903              mCodec->mComponentName.c_str(), event, data1, data2);
   3904 
   3905         return false;
   3906     }
   3907 
   3908     ALOGE("[%s] ERROR(0x%08lx)", mCodec->mComponentName.c_str(), data1);
   3909 
   3910     // verify OMX component sends back an error we expect.
   3911     OMX_ERRORTYPE omxError = (OMX_ERRORTYPE)data1;
   3912     if (!isOMXError(omxError)) {
   3913         ALOGW("Invalid OMX error %#x", omxError);
   3914         omxError = OMX_ErrorUndefined;
   3915     }
   3916     mCodec->signalError(omxError);
   3917 
   3918     return true;
   3919 }
   3920 
   3921 bool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
   3922     ALOGV("[%s] onOMXEmptyBufferDone %p",
   3923          mCodec->mComponentName.c_str(), bufferID);
   3924 
   3925     BufferInfo *info =
   3926         mCodec->findBufferByID(kPortIndexInput, bufferID);
   3927 
   3928     CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
   3929     info->mStatus = BufferInfo::OWNED_BY_US;
   3930 
   3931     // We're in "store-metadata-in-buffers" mode, the underlying
   3932     // OMX component had access to data that's implicitly refcounted
   3933     // by this "MediaBuffer" object. Now that the OMX component has
   3934     // told us that it's done with the input buffer, we can decrement
   3935     // the mediaBuffer's reference count.
   3936     info->mData->setMediaBufferBase(NULL);
   3937 
   3938     PortMode mode = getPortMode(kPortIndexInput);
   3939 
   3940     switch (mode) {
   3941         case KEEP_BUFFERS:
   3942             break;
   3943 
   3944         case RESUBMIT_BUFFERS:
   3945             postFillThisBuffer(info);
   3946             break;
   3947 
   3948         default:
   3949         {
   3950             CHECK_EQ((int)mode, (int)FREE_BUFFERS);
   3951             TRESPASS();  // Not currently used
   3952             break;
   3953         }
   3954     }
   3955 
   3956     return true;
   3957 }
   3958 
   3959 void ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
   3960     if (mCodec->mPortEOS[kPortIndexInput]) {
   3961         return;
   3962     }
   3963 
   3964     CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
   3965 
   3966     sp<AMessage> notify = mCodec->mNotify->dup();
   3967     notify->setInt32("what", CodecBase::kWhatFillThisBuffer);
   3968     notify->setInt32("buffer-id", info->mBufferID);
   3969 
   3970     info->mData->meta()->clear();
   3971     notify->setBuffer("buffer", info->mData);
   3972 
   3973     sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec->id());
   3974     reply->setInt32("buffer-id", info->mBufferID);
   3975 
   3976     notify->setMessage("reply", reply);
   3977 
   3978     notify->post();
   3979 
   3980     info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
   3981 }
   3982 
   3983 void ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
   3984     IOMX::buffer_id bufferID;
   3985     CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
   3986     sp<ABuffer> buffer;
   3987     int32_t err = OK;
   3988     bool eos = false;
   3989     PortMode mode = getPortMode(kPortIndexInput);
   3990 
   3991     if (!msg->findBuffer("buffer", &buffer)) {
   3992         /* these are unfilled buffers returned by client */
   3993         CHECK(msg->findInt32("err", &err));
   3994 
   3995         if (err == OK) {
   3996             /* buffers with no errors are returned on MediaCodec.flush */
   3997             mode = KEEP_BUFFERS;
   3998         } else {
   3999             ALOGV("[%s] saw error %d instead of an input buffer",
   4000                  mCodec->mComponentName.c_str(), err);
   4001             eos = true;
   4002         }
   4003 
   4004         buffer.clear();
   4005     }
   4006 
   4007     int32_t tmp;
   4008     if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
   4009         eos = true;
   4010         err = ERROR_END_OF_STREAM;
   4011     }
   4012 
   4013     BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
   4014     CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM);
   4015 
   4016     info->mStatus = BufferInfo::OWNED_BY_US;
   4017 
   4018     switch (mode) {
   4019         case KEEP_BUFFERS:
   4020         {
   4021             if (eos) {
   4022                 if (!mCodec->mPortEOS[kPortIndexInput]) {
   4023                     mCodec->mPortEOS[kPortIndexInput] = true;
   4024                     mCodec->mInputEOSResult = err;
   4025                 }
   4026             }
   4027             break;
   4028         }
   4029 
   4030         case RESUBMIT_BUFFERS:
   4031         {
   4032             if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
   4033                 int64_t timeUs;
   4034                 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
   4035 
   4036                 OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
   4037 
   4038                 int32_t isCSD;
   4039                 if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
   4040                     flags |= OMX_BUFFERFLAG_CODECCONFIG;
   4041                 }
   4042 
   4043                 if (eos) {
   4044                     flags |= OMX_BUFFERFLAG_EOS;
   4045                 }
   4046 
   4047                 if (buffer != info->mData) {
   4048                     ALOGV("[%s] Needs to copy input data for buffer %p. (%p != %p)",
   4049                          mCodec->mComponentName.c_str(),
   4050                          bufferID,
   4051                          buffer.get(), info->mData.get());
   4052 
   4053                     CHECK_LE(buffer->size(), info->mData->capacity());
   4054                     memcpy(info->mData->data(), buffer->data(), buffer->size());
   4055                 }
   4056 
   4057                 if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
   4058                     ALOGV("[%s] calling emptyBuffer %p w/ codec specific data",
   4059                          mCodec->mComponentName.c_str(), bufferID);
   4060                 } else if (flags & OMX_BUFFERFLAG_EOS) {
   4061                     ALOGV("[%s] calling emptyBuffer %p w/ EOS",
   4062                          mCodec->mComponentName.c_str(), bufferID);
   4063                 } else {
   4064 #if TRACK_BUFFER_TIMING
   4065                     ALOGI("[%s] calling emptyBuffer %p w/ time %lld us",
   4066                          mCodec->mComponentName.c_str(), bufferID, timeUs);
   4067 #else
   4068                     ALOGV("[%s] calling emptyBuffer %p w/ time %lld us",
   4069                          mCodec->mComponentName.c_str(), bufferID, timeUs);
   4070 #endif
   4071                 }
   4072 
   4073 #if TRACK_BUFFER_TIMING
   4074                 ACodec::BufferStats stats;
   4075                 stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
   4076                 stats.mFillBufferDoneTimeUs = -1ll;
   4077                 mCodec->mBufferStats.add(timeUs, stats);
   4078 #endif
   4079 
   4080                 if (mCodec->mStoreMetaDataInOutputBuffers) {
   4081                     // try to submit an output buffer for each input buffer
   4082                     PortMode outputMode = getPortMode(kPortIndexOutput);
   4083 
   4084                     ALOGV("MetaDataBuffersToSubmit=%u portMode=%s",
   4085                             mCodec->mMetaDataBuffersToSubmit,
   4086                             (outputMode == FREE_BUFFERS ? "FREE" :
   4087                              outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
   4088                     if (outputMode == RESUBMIT_BUFFERS) {
   4089                         mCodec->submitOutputMetaDataBuffer();
   4090                     }
   4091                 }
   4092 
   4093                 CHECK_EQ(mCodec->mOMX->emptyBuffer(
   4094                             mCodec->mNode,
   4095                             bufferID,
   4096                             0,
   4097                             buffer->size(),
   4098                             flags,
   4099                             timeUs),
   4100                          (status_t)OK);
   4101 
   4102                 info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
   4103 
   4104                 if (!eos) {
   4105                     getMoreInputDataIfPossible();
   4106                 } else {
   4107                     ALOGV("[%s] Signalled EOS on the input port",
   4108                          mCodec->mComponentName.c_str());
   4109 
   4110                     mCodec->mPortEOS[kPortIndexInput] = true;
   4111                     mCodec->mInputEOSResult = err;
   4112                 }
   4113             } else if (!mCodec->mPortEOS[kPortIndexInput]) {
   4114                 if (err != ERROR_END_OF_STREAM) {
   4115                     ALOGV("[%s] Signalling EOS on the input port "
   4116                          "due to error %d",
   4117                          mCodec->mComponentName.c_str(), err);
   4118                 } else {
   4119                     ALOGV("[%s] Signalling EOS on the input port",
   4120                          mCodec->mComponentName.c_str());
   4121                 }
   4122 
   4123                 ALOGV("[%s] calling emptyBuffer %p signalling EOS",
   4124                      mCodec->mComponentName.c_str(), bufferID);
   4125 
   4126                 CHECK_EQ(mCodec->mOMX->emptyBuffer(
   4127                             mCodec->mNode,
   4128                             bufferID,
   4129                             0,
   4130                             0,
   4131                             OMX_BUFFERFLAG_EOS,
   4132                             0),
   4133                          (status_t)OK);
   4134 
   4135                 info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
   4136 
   4137                 mCodec->mPortEOS[kPortIndexInput] = true;
   4138                 mCodec->mInputEOSResult = err;
   4139             }
   4140             break;
   4141         }
   4142 
   4143         default:
   4144             CHECK_EQ((int)mode, (int)FREE_BUFFERS);
   4145             break;
   4146     }
   4147 }
   4148 
   4149 void ACodec::BaseState::getMoreInputDataIfPossible() {
   4150     if (mCodec->mPortEOS[kPortIndexInput]) {
   4151         return;
   4152     }
   4153 
   4154     BufferInfo *eligible = NULL;
   4155 
   4156     for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
   4157         BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
   4158 
   4159 #if 0
   4160         if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
   4161             // There's already a "read" pending.
   4162             return;
   4163         }
   4164 #endif
   4165 
   4166         if (info->mStatus == BufferInfo::OWNED_BY_US) {
   4167             eligible = info;
   4168         }
   4169     }
   4170 
   4171     if (eligible == NULL) {
   4172         return;
   4173     }
   4174 
   4175     postFillThisBuffer(eligible);
   4176 }
   4177 
   4178 bool ACodec::BaseState::onOMXFillBufferDone(
   4179         IOMX::buffer_id bufferID,
   4180         size_t rangeOffset, size_t rangeLength,
   4181         OMX_U32 flags,
   4182         int64_t timeUs) {
   4183     ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x",
   4184          mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
   4185 
   4186     ssize_t index;
   4187 
   4188 #if TRACK_BUFFER_TIMING
   4189     index = mCodec->mBufferStats.indexOfKey(timeUs);
   4190     if (index >= 0) {
   4191         ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
   4192         stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
   4193 
   4194         ALOGI("frame PTS %lld: %lld",
   4195                 timeUs,
   4196                 stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
   4197 
   4198         mCodec->mBufferStats.removeItemsAt(index);
   4199         stats = NULL;
   4200     }
   4201 #endif
   4202 
   4203     BufferInfo *info =
   4204         mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
   4205 
   4206     CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
   4207 
   4208     info->mDequeuedAt = ++mCodec->mDequeueCounter;
   4209     info->mStatus = BufferInfo::OWNED_BY_US;
   4210 
   4211     PortMode mode = getPortMode(kPortIndexOutput);
   4212 
   4213     switch (mode) {
   4214         case KEEP_BUFFERS:
   4215             break;
   4216 
   4217         case RESUBMIT_BUFFERS:
   4218         {
   4219             if (rangeLength == 0 && !(flags & OMX_BUFFERFLAG_EOS)) {
   4220                 ALOGV("[%s] calling fillBuffer %u",
   4221                      mCodec->mComponentName.c_str(), info->mBufferID);
   4222 
   4223                 CHECK_EQ(mCodec->mOMX->fillBuffer(
   4224                             mCodec->mNode, info->mBufferID),
   4225                          (status_t)OK);
   4226 
   4227                 info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
   4228                 break;
   4229             }
   4230 
   4231             sp<AMessage> reply =
   4232                 new AMessage(kWhatOutputBufferDrained, mCodec->id());
   4233 
   4234             if (!mCodec->mSentFormat && rangeLength > 0) {
   4235                 mCodec->sendFormatChange(reply);
   4236             }
   4237 
   4238             if (mCodec->mUseMetadataOnEncoderOutput) {
   4239                 native_handle_t* handle =
   4240                         *(native_handle_t**)(info->mData->data() + 4);
   4241                 info->mData->meta()->setPointer("handle", handle);
   4242                 info->mData->meta()->setInt32("rangeOffset", rangeOffset);
   4243                 info->mData->meta()->setInt32("rangeLength", rangeLength);
   4244             } else {
   4245                 info->mData->setRange(rangeOffset, rangeLength);
   4246             }
   4247 #if 0
   4248             if (mCodec->mNativeWindow == NULL) {
   4249                 if (IsIDR(info->mData)) {
   4250                     ALOGI("IDR frame");
   4251                 }
   4252             }
   4253 #endif
   4254 
   4255             if (mCodec->mSkipCutBuffer != NULL) {
   4256                 mCodec->mSkipCutBuffer->submit(info->mData);
   4257             }
   4258             info->mData->meta()->setInt64("timeUs", timeUs);
   4259 
   4260             sp<AMessage> notify = mCodec->mNotify->dup();
   4261             notify->setInt32("what", CodecBase::kWhatDrainThisBuffer);
   4262             notify->setInt32("buffer-id", info->mBufferID);
   4263             notify->setBuffer("buffer", info->mData);
   4264             notify->setInt32("flags", flags);
   4265 
   4266             reply->setInt32("buffer-id", info->mBufferID);
   4267 
   4268             notify->setMessage("reply", reply);
   4269 
   4270             notify->post();
   4271 
   4272             info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
   4273 
   4274             if (flags & OMX_BUFFERFLAG_EOS) {
   4275                 ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
   4276 
   4277                 sp<AMessage> notify = mCodec->mNotify->dup();
   4278                 notify->setInt32("what", CodecBase::kWhatEOS);
   4279                 notify->setInt32("err", mCodec->mInputEOSResult);
   4280                 notify->post();
   4281 
   4282                 mCodec->mPortEOS[kPortIndexOutput] = true;
   4283             }
   4284             break;
   4285         }
   4286 
   4287         default:
   4288         {
   4289             CHECK_EQ((int)mode, (int)FREE_BUFFERS);
   4290 
   4291             CHECK_EQ((status_t)OK,
   4292                      mCodec->freeBuffer(kPortIndexOutput, index));
   4293             break;
   4294         }
   4295     }
   4296 
   4297     return true;
   4298 }
   4299 
   4300 void ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
   4301     IOMX::buffer_id bufferID;
   4302     CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
   4303     ssize_t index;
   4304     BufferInfo *info =
   4305         mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
   4306     CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
   4307 
   4308     android_native_rect_t crop;
   4309     if (msg->findRect("crop",
   4310             &crop.left, &crop.top, &crop.right, &crop.bottom)) {
   4311         CHECK_EQ(0, native_window_set_crop(
   4312                 mCodec->mNativeWindow.get(), &crop));
   4313     }
   4314 
   4315     int32_t render;
   4316     if (mCodec->mNativeWindow != NULL
   4317             && msg->findInt32("render", &render) && render != 0
   4318             && info->mData != NULL && info->mData->size() != 0) {
   4319         ATRACE_NAME("render");
   4320         // The client wants this buffer to be rendered.
   4321 
   4322         int64_t timestampNs = 0;
   4323         if (!msg->findInt64("timestampNs", &timestampNs)) {
   4324             // TODO: it seems like we should use the timestamp
   4325             // in the (media)buffer as it potentially came from
   4326             // an input surface, but we did not propagate it prior to
   4327             // API 20.  Perhaps check for target SDK version.
   4328 #if 0
   4329             if (info->mData->meta()->findInt64("timeUs", &timestampNs)) {
   4330                 ALOGV("using buffer PTS of %" PRId64, timestampNs);
   4331                 timestampNs *= 1000;
   4332             }
   4333 #endif
   4334         }
   4335 
   4336         status_t err;
   4337         err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs);
   4338         if (err != OK) {
   4339             ALOGW("failed to set buffer timestamp: %d", err);
   4340         }
   4341 
   4342         if ((err = mCodec->mNativeWindow->queueBuffer(
   4343                     mCodec->mNativeWindow.get(),
   4344                     info->mGraphicBuffer.get(), -1)) == OK) {
   4345             info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
   4346         } else {
   4347             mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
   4348             info->mStatus = BufferInfo::OWNED_BY_US;
   4349         }
   4350     } else {
   4351         if (mCodec->mNativeWindow != NULL &&
   4352             (info->mData == NULL || info->mData->size() != 0)) {
   4353             ATRACE_NAME("frame-drop");
   4354         }
   4355         info->mStatus = BufferInfo::OWNED_BY_US;
   4356     }
   4357 
   4358     PortMode mode = getPortMode(kPortIndexOutput);
   4359 
   4360     switch (mode) {
   4361         case KEEP_BUFFERS:
   4362         {
   4363             // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
   4364 
   4365             if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
   4366                 // We cannot resubmit the buffer we just rendered, dequeue
   4367                 // the spare instead.
   4368 
   4369                 info = mCodec->dequeueBufferFromNativeWindow();
   4370             }
   4371             break;
   4372         }
   4373 
   4374         case RESUBMIT_BUFFERS:
   4375         {
   4376             if (!mCodec->mPortEOS[kPortIndexOutput]) {
   4377                 if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
   4378                     // We cannot resubmit the buffer we just rendered, dequeue
   4379                     // the spare instead.
   4380 
   4381                     info = mCodec->dequeueBufferFromNativeWindow();
   4382                 }
   4383 
   4384                 if (info != NULL) {
   4385                     ALOGV("[%s] calling fillBuffer %u",
   4386                          mCodec->mComponentName.c_str(), info->mBufferID);
   4387 
   4388                     CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
   4389                              (status_t)OK);
   4390 
   4391                     info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
   4392                 }
   4393             }
   4394             break;
   4395         }
   4396 
   4397         default:
   4398         {
   4399             CHECK_EQ((int)mode, (int)FREE_BUFFERS);
   4400 
   4401             CHECK_EQ((status_t)OK,
   4402                      mCodec->freeBuffer(kPortIndexOutput, index));
   4403             break;
   4404         }
   4405     }
   4406 }
   4407 
   4408 ////////////////////////////////////////////////////////////////////////////////
   4409 
   4410 ACodec::UninitializedState::UninitializedState(ACodec *codec)
   4411     : BaseState(codec) {
   4412 }
   4413 
   4414 void ACodec::UninitializedState::stateEntered() {
   4415     ALOGV("Now uninitialized");
   4416 
   4417     if (mDeathNotifier != NULL) {
   4418         mCodec->mOMX->asBinder()->unlinkToDeath(mDeathNotifier);
   4419         mDeathNotifier.clear();
   4420     }
   4421 
   4422     mCodec->mNativeWindow.clear();
   4423     mCodec->mNode = NULL;
   4424     mCodec->mOMX.clear();
   4425     mCodec->mQuirks = 0;
   4426     mCodec->mFlags = 0;
   4427     mCodec->mUseMetadataOnEncoderOutput = 0;
   4428     mCodec->mComponentName.clear();
   4429 }
   4430 
   4431 bool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
   4432     bool handled = false;
   4433 
   4434     switch (msg->what()) {
   4435         case ACodec::kWhatSetup:
   4436         {
   4437             onSetup(msg);
   4438 
   4439             handled = true;
   4440             break;
   4441         }
   4442 
   4443         case ACodec::kWhatAllocateComponent:
   4444         {
   4445             onAllocateComponent(msg);
   4446             handled = true;
   4447             break;
   4448         }
   4449 
   4450         case ACodec::kWhatShutdown:
   4451         {
   4452             int32_t keepComponentAllocated;
   4453             CHECK(msg->findInt32(
   4454                         "keepComponentAllocated", &keepComponentAllocated));
   4455             ALOGW_IF(keepComponentAllocated,
   4456                      "cannot keep component allocated on shutdown in Uninitialized state");
   4457 
   4458             sp<AMessage> notify = mCodec->mNotify->dup();
   4459             notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
   4460             notify->post();
   4461 
   4462             handled = true;
   4463             break;
   4464         }
   4465 
   4466         case ACodec::kWhatFlush:
   4467         {
   4468             sp<AMessage> notify = mCodec->mNotify->dup();
   4469             notify->setInt32("what", CodecBase::kWhatFlushCompleted);
   4470             notify->post();
   4471 
   4472             handled = true;
   4473             break;
   4474         }
   4475 
   4476         case ACodec::kWhatReleaseCodecInstance:
   4477         {
   4478             // nothing to do, as we have already signaled shutdown
   4479             handled = true;
   4480             break;
   4481         }
   4482 
   4483         default:
   4484             return BaseState::onMessageReceived(msg);
   4485     }
   4486 
   4487     return handled;
   4488 }
   4489 
   4490 void ACodec::UninitializedState::onSetup(
   4491         const sp<AMessage> &msg) {
   4492     if (onAllocateComponent(msg)
   4493             && mCodec->mLoadedState->onConfigureComponent(msg)) {
   4494         mCodec->mLoadedState->onStart();
   4495     }
   4496 }
   4497 
   4498 bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
   4499     ALOGV("onAllocateComponent");
   4500 
   4501     CHECK(mCodec->mNode == NULL);
   4502 
   4503     OMXClient client;
   4504     CHECK_EQ(client.connect(), (status_t)OK);
   4505 
   4506     sp<IOMX> omx = client.interface();
   4507 
   4508     sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec->id());
   4509 
   4510     mDeathNotifier = new DeathNotifier(notify);
   4511     if (omx->asBinder()->linkToDeath(mDeathNotifier) != OK) {
   4512         // This was a local binder, if it dies so do we, we won't care
   4513         // about any notifications in the afterlife.
   4514         mDeathNotifier.clear();
   4515     }
   4516 
   4517     Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
   4518 
   4519     AString mime;
   4520 
   4521     AString componentName;
   4522     uint32_t quirks = 0;
   4523     int32_t encoder = false;
   4524     if (msg->findString("componentName", &componentName)) {
   4525         ssize_t index = matchingCodecs.add();
   4526         OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
   4527         entry->mName = String8(componentName.c_str());
   4528 
   4529         if (!OMXCodec::findCodecQuirks(
   4530                     componentName.c_str(), &entry->mQuirks)) {
   4531             entry->mQuirks = 0;
   4532         }
   4533     } else {
   4534         CHECK(msg->findString("mime", &mime));
   4535 
   4536         if (!msg->findInt32("encoder", &encoder)) {
   4537             encoder = false;
   4538         }
   4539 
   4540         OMXCodec::findMatchingCodecs(
   4541                 mime.c_str(),
   4542                 encoder, // createEncoder
   4543                 NULL,  // matchComponentName
   4544                 0,     // flags
   4545                 &matchingCodecs);
   4546     }
   4547 
   4548     sp<CodecObserver> observer = new CodecObserver;
   4549     IOMX::node_id node = NULL;
   4550 
   4551     for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
   4552             ++matchIndex) {
   4553         componentName = matchingCodecs.itemAt(matchIndex).mName.string();
   4554         quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
   4555 
   4556         pid_t tid = androidGetTid();
   4557         int prevPriority = androidGetThreadPriority(tid);
   4558         androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
   4559         status_t err = omx->allocateNode(componentName.c_str(), observer, &node);
   4560         androidSetThreadPriority(tid, prevPriority);
   4561 
   4562         if (err == OK) {
   4563             break;
   4564         } else {
   4565             ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str());
   4566         }
   4567 
   4568         node = NULL;
   4569     }
   4570 
   4571     if (node == NULL) {
   4572         if (!mime.empty()) {
   4573             ALOGE("Unable to instantiate a %scoder for type '%s'.",
   4574                     encoder ? "en" : "de", mime.c_str());
   4575         } else {
   4576             ALOGE("Unable to instantiate codec '%s'.", componentName.c_str());
   4577         }
   4578 
   4579         mCodec->signalError(OMX_ErrorComponentNotFound);
   4580         return false;
   4581     }
   4582 
   4583     notify = new AMessage(kWhatOMXMessage, mCodec->id());
   4584     observer->setNotificationMessage(notify);
   4585 
   4586     mCodec->mComponentName = componentName;
   4587     mCodec->mFlags = 0;
   4588 
   4589     if (componentName.endsWith(".secure")) {
   4590         mCodec->mFlags |= kFlagIsSecure;
   4591         mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
   4592     }
   4593 
   4594     mCodec->mQuirks = quirks;
   4595     mCodec->mOMX = omx;
   4596     mCodec->mNode = node;
   4597 
   4598     {
   4599         sp<AMessage> notify = mCodec->mNotify->dup();
   4600         notify->setInt32("what", CodecBase::kWhatComponentAllocated);
   4601         notify->setString("componentName", mCodec->mComponentName.c_str());
   4602         notify->post();
   4603     }
   4604 
   4605     mCodec->changeState(mCodec->mLoadedState);
   4606 
   4607     return true;
   4608 }
   4609 
   4610 ////////////////////////////////////////////////////////////////////////////////
   4611 
   4612 ACodec::LoadedState::LoadedState(ACodec *codec)
   4613     : BaseState(codec) {
   4614 }
   4615 
   4616 void ACodec::LoadedState::stateEntered() {
   4617     ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
   4618 
   4619     mCodec->mPortEOS[kPortIndexInput] =
   4620         mCodec->mPortEOS[kPortIndexOutput] = false;
   4621 
   4622     mCodec->mInputEOSResult = OK;
   4623 
   4624     mCodec->mDequeueCounter = 0;
   4625     mCodec->mMetaDataBuffersToSubmit = 0;
   4626     mCodec->mRepeatFrameDelayUs = -1ll;
   4627     mCodec->mInputFormat.clear();
   4628     mCodec->mOutputFormat.clear();
   4629 
   4630     if (mCodec->mShutdownInProgress) {
   4631         bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
   4632 
   4633         mCodec->mShutdownInProgress = false;
   4634         mCodec->mKeepComponentAllocated = false;
   4635 
   4636         onShutdown(keepComponentAllocated);
   4637     }
   4638     mCodec->mExplicitShutdown = false;
   4639 
   4640     mCodec->processDeferredMessages();
   4641 }
   4642 
   4643 void ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
   4644     if (!keepComponentAllocated) {
   4645         CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
   4646 
   4647         mCodec->changeState(mCodec->mUninitializedState);
   4648     }
   4649 
   4650     if (mCodec->mExplicitShutdown) {
   4651         sp<AMessage> notify = mCodec->mNotify->dup();
   4652         notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
   4653         notify->post();
   4654         mCodec->mExplicitShutdown = false;
   4655     }
   4656 }
   4657 
   4658 bool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
   4659     bool handled = false;
   4660 
   4661     switch (msg->what()) {
   4662         case ACodec::kWhatConfigureComponent:
   4663         {
   4664             onConfigureComponent(msg);
   4665             handled = true;
   4666             break;
   4667         }
   4668 
   4669         case ACodec::kWhatCreateInputSurface:
   4670         {
   4671             onCreateInputSurface(msg);
   4672             handled = true;
   4673             break;
   4674         }
   4675 
   4676         case ACodec::kWhatStart:
   4677         {
   4678             onStart();
   4679             handled = true;
   4680             break;
   4681         }
   4682 
   4683         case ACodec::kWhatShutdown:
   4684         {
   4685             int32_t keepComponentAllocated;
   4686             CHECK(msg->findInt32(
   4687                         "keepComponentAllocated", &keepComponentAllocated));
   4688 
   4689             mCodec->mExplicitShutdown = true;
   4690             onShutdown(keepComponentAllocated);
   4691 
   4692             handled = true;
   4693             break;
   4694         }
   4695 
   4696         case ACodec::kWhatFlush:
   4697         {
   4698             sp<AMessage> notify = mCodec->mNotify->dup();
   4699             notify->setInt32("what", CodecBase::kWhatFlushCompleted);
   4700             notify->post();
   4701 
   4702             handled = true;
   4703             break;
   4704         }
   4705 
   4706         default:
   4707             return BaseState::onMessageReceived(msg);
   4708     }
   4709 
   4710     return handled;
   4711 }
   4712 
   4713 bool ACodec::LoadedState::onConfigureComponent(
   4714         const sp<AMessage> &msg) {
   4715     ALOGV("onConfigureComponent");
   4716 
   4717     CHECK(mCodec->mNode != NULL);
   4718 
   4719     AString mime;
   4720     CHECK(msg->findString("mime", &mime));
   4721 
   4722     status_t err = mCodec->configureCodec(mime.c_str(), msg);
   4723 
   4724     if (err != OK) {
   4725         ALOGE("[%s] configureCodec returning error %d",
   4726               mCodec->mComponentName.c_str(), err);
   4727 
   4728         mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
   4729         return false;
   4730     }
   4731 
   4732     sp<RefBase> obj;
   4733     if (msg->findObject("native-window", &obj)
   4734             && strncmp("OMX.google.", mCodec->mComponentName.c_str(), 11)) {
   4735         sp<NativeWindowWrapper> nativeWindow(
   4736                 static_cast<NativeWindowWrapper *>(obj.get()));
   4737         CHECK(nativeWindow != NULL);
   4738         mCodec->mNativeWindow = nativeWindow->getNativeWindow();
   4739 
   4740         native_window_set_scaling_mode(
   4741                 mCodec->mNativeWindow.get(),
   4742                 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
   4743     }
   4744     CHECK_EQ((status_t)OK, mCodec->initNativeWindow());
   4745 
   4746     {
   4747         sp<AMessage> notify = mCodec->mNotify->dup();
   4748         notify->setInt32("what", CodecBase::kWhatComponentConfigured);
   4749         notify->setMessage("input-format", mCodec->mInputFormat);
   4750         notify->setMessage("output-format", mCodec->mOutputFormat);
   4751         notify->post();
   4752     }
   4753 
   4754     return true;
   4755 }
   4756 
   4757 void ACodec::LoadedState::onCreateInputSurface(
   4758         const sp<AMessage> & /* msg */) {
   4759     ALOGV("onCreateInputSurface");
   4760 
   4761     sp<AMessage> notify = mCodec->mNotify->dup();
   4762     notify->setInt32("what", CodecBase::kWhatInputSurfaceCreated);
   4763 
   4764     sp<IGraphicBufferProducer> bufferProducer;
   4765     status_t err;
   4766 
   4767     err = mCodec->mOMX->createInputSurface(mCodec->mNode, kPortIndexInput,
   4768             &bufferProducer);
   4769 
   4770     if (err == OK && mCodec->mRepeatFrameDelayUs > 0ll) {
   4771         err = mCodec->mOMX->setInternalOption(
   4772                 mCodec->mNode,
   4773                 kPortIndexInput,
   4774                 IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY,
   4775                 &mCodec->mRepeatFrameDelayUs,
   4776                 sizeof(mCodec->mRepeatFrameDelayUs));
   4777 
   4778         if (err != OK) {
   4779             ALOGE("[%s] Unable to configure option to repeat previous "
   4780                   "frames (err %d)",
   4781                   mCodec->mComponentName.c_str(),
   4782                   err);
   4783         }
   4784     }
   4785 
   4786     if (err == OK && mCodec->mMaxPtsGapUs > 0ll) {
   4787         err = mCodec->mOMX->setInternalOption(
   4788                 mCodec->mNode,
   4789                 kPortIndexInput,
   4790                 IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP,
   4791                 &mCodec->mMaxPtsGapUs,
   4792                 sizeof(mCodec->mMaxPtsGapUs));
   4793 
   4794         if (err != OK) {
   4795             ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
   4796                     mCodec->mComponentName.c_str(),
   4797                     err);
   4798         }
   4799     }
   4800 
   4801     if (err == OK && mCodec->mTimePerCaptureUs > 0ll
   4802             && mCodec->mTimePerFrameUs > 0ll) {
   4803         int64_t timeLapse[2];
   4804         timeLapse[0] = mCodec->mTimePerFrameUs;
   4805         timeLapse[1] = mCodec->mTimePerCaptureUs;
   4806         err = mCodec->mOMX->setInternalOption(
   4807                 mCodec->mNode,
   4808                 kPortIndexInput,
   4809                 IOMX::INTERNAL_OPTION_TIME_LAPSE,
   4810                 &timeLapse[0],
   4811                 sizeof(timeLapse));
   4812 
   4813         if (err != OK) {
   4814             ALOGE("[%s] Unable to configure time lapse (err %d)",
   4815                     mCodec->mComponentName.c_str(),
   4816                     err);
   4817         }
   4818     }
   4819 
   4820     if (err == OK && mCodec->mCreateInputBuffersSuspended) {
   4821         bool suspend = true;
   4822         err = mCodec->mOMX->setInternalOption(
   4823                 mCodec->mNode,
   4824                 kPortIndexInput,
   4825                 IOMX::INTERNAL_OPTION_SUSPEND,
   4826                 &suspend,
   4827                 sizeof(suspend));
   4828 
   4829         if (err != OK) {
   4830             ALOGE("[%s] Unable to configure option to suspend (err %d)",
   4831                   mCodec->mComponentName.c_str(),
   4832                   err);
   4833         }
   4834     }
   4835 
   4836     if (err == OK) {
   4837         notify->setObject("input-surface",
   4838                 new BufferProducerWrapper(bufferProducer));
   4839     } else {
   4840         // Can't use mCodec->signalError() here -- MediaCodec won't forward
   4841         // the error through because it's in the "configured" state.  We
   4842         // send a kWhatInputSurfaceCreated with an error value instead.
   4843         ALOGE("[%s] onCreateInputSurface returning error %d",
   4844                 mCodec->mComponentName.c_str(), err);
   4845         notify->setInt32("err", err);
   4846     }
   4847     notify->post();
   4848 }
   4849 
   4850 void ACodec::LoadedState::onStart() {
   4851     ALOGV("onStart");
   4852 
   4853     CHECK_EQ(mCodec->mOMX->sendCommand(
   4854                 mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
   4855              (status_t)OK);
   4856 
   4857     mCodec->changeState(mCodec->mLoadedToIdleState);
   4858 }
   4859 
   4860 ////////////////////////////////////////////////////////////////////////////////
   4861 
   4862 ACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
   4863     : BaseState(codec) {
   4864 }
   4865 
   4866 void ACodec::LoadedToIdleState::stateEntered() {
   4867     ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
   4868 
   4869     status_t err;
   4870     if ((err = allocateBuffers()) != OK) {
   4871         ALOGE("Failed to allocate buffers after transitioning to IDLE state "
   4872              "(error 0x%08x)",
   4873              err);
   4874 
   4875         mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
   4876 
   4877         mCodec->changeState(mCodec->mLoadedState);
   4878     }
   4879 }
   4880 
   4881 status_t ACodec::LoadedToIdleState::allocateBuffers() {
   4882     status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
   4883 
   4884     if (err != OK) {
   4885         return err;
   4886     }
   4887 
   4888     return mCodec->allocateBuffersOnPort(kPortIndexOutput);
   4889 }
   4890 
   4891 bool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
   4892     switch (msg->what()) {
   4893         case kWhatSetParameters:
   4894         case kWhatShutdown:
   4895         {
   4896             mCodec->deferMessage(msg);
   4897             return true;
   4898         }
   4899 
   4900         case kWhatSignalEndOfInputStream:
   4901         {
   4902             mCodec->onSignalEndOfInputStream();
   4903             return true;
   4904         }
   4905 
   4906         case kWhatResume:
   4907         {
   4908             // We'll be active soon enough.
   4909             return true;
   4910         }
   4911 
   4912         case kWhatFlush:
   4913         {
   4914             // We haven't even started yet, so we're flushed alright...
   4915             sp<AMessage> notify = mCodec->mNotify->dup();
   4916             notify->setInt32("what", CodecBase::kWhatFlushCompleted);
   4917             notify->post();
   4918             return true;
   4919         }
   4920 
   4921         default:
   4922             return BaseState::onMessageReceived(msg);
   4923     }
   4924 }
   4925 
   4926 bool ACodec::LoadedToIdleState::onOMXEvent(
   4927         OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
   4928     switch (event) {
   4929         case OMX_EventCmdComplete:
   4930         {
   4931             CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
   4932             CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
   4933 
   4934             CHECK_EQ(mCodec->mOMX->sendCommand(
   4935                         mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting),
   4936                      (status_t)OK);
   4937 
   4938             mCodec->changeState(mCodec->mIdleToExecutingState);
   4939 
   4940             return true;
   4941         }
   4942 
   4943         default:
   4944             return BaseState::onOMXEvent(event, data1, data2);
   4945     }
   4946 }
   4947 
   4948 ////////////////////////////////////////////////////////////////////////////////
   4949 
   4950 ACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
   4951     : BaseState(codec) {
   4952 }
   4953 
   4954 void ACodec::IdleToExecutingState::stateEntered() {
   4955     ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
   4956 }
   4957 
   4958 bool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
   4959     switch (msg->what()) {
   4960         case kWhatSetParameters:
   4961         case kWhatShutdown:
   4962         {
   4963             mCodec->deferMessage(msg);
   4964             return true;
   4965         }
   4966 
   4967         case kWhatResume:
   4968         {
   4969             // We'll be active soon enough.
   4970             return true;
   4971         }
   4972 
   4973         case kWhatFlush:
   4974         {
   4975             // We haven't even started yet, so we're flushed alright...
   4976             sp<AMessage> notify = mCodec->mNotify->dup();
   4977             notify->setInt32("what", CodecBase::kWhatFlushCompleted);
   4978             notify->post();
   4979 
   4980             return true;
   4981         }
   4982 
   4983         case kWhatSignalEndOfInputStream:
   4984         {
   4985             mCodec->onSignalEndOfInputStream();
   4986             return true;
   4987         }
   4988 
   4989         default:
   4990             return BaseState::onMessageReceived(msg);
   4991     }
   4992 }
   4993 
   4994 bool ACodec::IdleToExecutingState::onOMXEvent(
   4995         OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
   4996     switch (event) {
   4997         case OMX_EventCmdComplete:
   4998         {
   4999             CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
   5000             CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting);
   5001 
   5002             mCodec->mExecutingState->resume();
   5003             mCodec->changeState(mCodec->mExecutingState);
   5004 
   5005             return true;
   5006         }
   5007 
   5008         default:
   5009             return BaseState::onOMXEvent(event, data1, data2);
   5010     }
   5011 }
   5012 
   5013 ////////////////////////////////////////////////////////////////////////////////
   5014 
   5015 ACodec::ExecutingState::ExecutingState(ACodec *codec)
   5016     : BaseState(codec),
   5017       mActive(false) {
   5018 }
   5019 
   5020 ACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
   5021         OMX_U32 /* portIndex */) {
   5022     return RESUBMIT_BUFFERS;
   5023 }
   5024 
   5025 void ACodec::ExecutingState::submitOutputMetaBuffers() {
   5026     // submit as many buffers as there are input buffers with the codec
   5027     // in case we are in port reconfiguring
   5028     for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
   5029         BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
   5030 
   5031         if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
   5032             if (mCodec->submitOutputMetaDataBuffer() != OK)
   5033                 break;
   5034         }
   5035     }
   5036 
   5037     // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
   5038     mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
   5039 }
   5040 
   5041 void ACodec::ExecutingState::submitRegularOutputBuffers() {
   5042     for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
   5043         BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
   5044 
   5045         if (mCodec->mNativeWindow != NULL) {
   5046             CHECK(info->mStatus == BufferInfo::OWNED_BY_US
   5047                     || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
   5048 
   5049             if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
   5050                 continue;
   5051             }
   5052         } else {
   5053             CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
   5054         }
   5055 
   5056         ALOGV("[%s] calling fillBuffer %p",
   5057              mCodec->mComponentName.c_str(), info->mBufferID);
   5058 
   5059         CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
   5060                  (status_t)OK);
   5061 
   5062         info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
   5063     }
   5064 }
   5065 
   5066 void ACodec::ExecutingState::submitOutputBuffers() {
   5067     submitRegularOutputBuffers();
   5068     if (mCodec->mStoreMetaDataInOutputBuffers) {
   5069         submitOutputMetaBuffers();
   5070     }
   5071 }
   5072 
   5073 void ACodec::ExecutingState::resume() {
   5074     if (mActive) {
   5075         ALOGV("[%s] We're already active, no need to resume.",
   5076              mCodec->mComponentName.c_str());
   5077 
   5078         return;
   5079     }
   5080 
   5081     submitOutputBuffers();
   5082 
   5083     // Post all available input buffers
   5084     CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u);
   5085     for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) {
   5086         BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
   5087         if (info->mStatus == BufferInfo::OWNED_BY_US) {
   5088             postFillThisBuffer(info);
   5089         }
   5090     }
   5091 
   5092     mActive = true;
   5093 }
   5094 
   5095 void ACodec::ExecutingState::stateEntered() {
   5096     ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
   5097 
   5098     mCodec->processDeferredMessages();
   5099 }
   5100 
   5101 bool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
   5102     bool handled = false;
   5103 
   5104     switch (msg->what()) {
   5105         case kWhatShutdown:
   5106         {
   5107             int32_t keepComponentAllocated;
   5108             CHECK(msg->findInt32(
   5109                         "keepComponentAllocated", &keepComponentAllocated));
   5110 
   5111             mCodec->mShutdownInProgress = true;
   5112             mCodec->mExplicitShutdown = true;
   5113             mCodec->mKeepComponentAllocated = keepComponentAllocated;
   5114 
   5115             mActive = false;
   5116 
   5117             CHECK_EQ(mCodec->mOMX->sendCommand(
   5118                         mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
   5119                      (status_t)OK);
   5120 
   5121             mCodec->changeState(mCodec->mExecutingToIdleState);
   5122 
   5123             handled = true;
   5124             break;
   5125         }
   5126 
   5127         case kWhatFlush:
   5128         {
   5129             ALOGV("[%s] ExecutingState flushing now "
   5130                  "(codec owns %d/%d input, %d/%d output).",
   5131                     mCodec->mComponentName.c_str(),
   5132                     mCodec->countBuffersOwnedByComponent(kPortIndexInput),
   5133                     mCodec->mBuffers[kPortIndexInput].size(),
   5134                     mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
   5135                     mCodec->mBuffers[kPortIndexOutput].size());
   5136 
   5137             mActive = false;
   5138 
   5139             CHECK_EQ(mCodec->mOMX->sendCommand(
   5140                         mCodec->mNode, OMX_CommandFlush, OMX_ALL),
   5141                      (status_t)OK);
   5142 
   5143             mCodec->changeState(mCodec->mFlushingState);
   5144             handled = true;
   5145             break;
   5146         }
   5147 
   5148         case kWhatResume:
   5149         {
   5150             resume();
   5151 
   5152             handled = true;
   5153             break;
   5154         }
   5155 
   5156         case kWhatRequestIDRFrame:
   5157         {
   5158             status_t err = mCodec->requestIDRFrame();
   5159             if (err != OK) {
   5160                 ALOGW("Requesting an IDR frame failed.");
   5161             }
   5162 
   5163             handled = true;
   5164             break;
   5165         }
   5166 
   5167         case kWhatSetParameters:
   5168         {
   5169             sp<AMessage> params;
   5170             CHECK(msg->findMessage("params", &params));
   5171 
   5172             status_t err = mCodec->setParameters(params);
   5173 
   5174             sp<AMessage> reply;
   5175             if (msg->findMessage("reply", &reply)) {
   5176                 reply->setInt32("err", err);
   5177                 reply->post();
   5178             }
   5179 
   5180             handled = true;
   5181             break;
   5182         }
   5183 
   5184         case ACodec::kWhatSignalEndOfInputStream:
   5185         {
   5186             mCodec->onSignalEndOfInputStream();
   5187             handled = true;
   5188             break;
   5189         }
   5190 
   5191         // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
   5192         case kWhatSubmitOutputMetaDataBufferIfEOS:
   5193         {
   5194             if (mCodec->mPortEOS[kPortIndexInput] &&
   5195                     !mCodec->mPortEOS[kPortIndexOutput]) {
   5196                 status_t err = mCodec->submitOutputMetaDataBuffer();
   5197                 if (err == OK) {
   5198                     mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
   5199                 }
   5200             }
   5201             return true;
   5202         }
   5203 
   5204         default:
   5205             handled = BaseState::onMessageReceived(msg);
   5206             break;
   5207     }
   5208 
   5209     return handled;
   5210 }
   5211 
   5212 status_t ACodec::setParameters(const sp<AMessage> &params) {
   5213     int32_t videoBitrate;
   5214     if (params->findInt32("video-bitrate", &videoBitrate)) {
   5215         OMX_VIDEO_CONFIG_BITRATETYPE configParams;
   5216         InitOMXParams(&configParams);
   5217         configParams.nPortIndex = kPortIndexOutput;
   5218         configParams.nEncodeBitrate = videoBitrate;
   5219 
   5220         status_t err = mOMX->setConfig(
   5221                 mNode,
   5222                 OMX_IndexConfigVideoBitrate,
   5223                 &configParams,
   5224                 sizeof(configParams));
   5225 
   5226         if (err != OK) {
   5227             ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
   5228                    videoBitrate, err);
   5229 
   5230             return err;
   5231         }
   5232     }
   5233 
   5234     int64_t skipFramesBeforeUs;
   5235     if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
   5236         status_t err =
   5237             mOMX->setInternalOption(
   5238                      mNode,
   5239                      kPortIndexInput,
   5240                      IOMX::INTERNAL_OPTION_START_TIME,
   5241                      &skipFramesBeforeUs,
   5242                      sizeof(skipFramesBeforeUs));
   5243 
   5244         if (err != OK) {
   5245             ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err);
   5246             return err;
   5247         }
   5248     }
   5249 
   5250     int32_t dropInputFrames;
   5251     if (params->findInt32("drop-input-frames", &dropInputFrames)) {
   5252         bool suspend = dropInputFrames != 0;
   5253 
   5254         status_t err =
   5255             mOMX->setInternalOption(
   5256                      mNode,
   5257                      kPortIndexInput,
   5258                      IOMX::INTERNAL_OPTION_SUSPEND,
   5259                      &suspend,
   5260                      sizeof(suspend));
   5261 
   5262         if (err != OK) {
   5263             ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
   5264             return err;
   5265         }
   5266     }
   5267 
   5268     int32_t dummy;
   5269     if (params->findInt32("request-sync", &dummy)) {
   5270         status_t err = requestIDRFrame();
   5271 
   5272         if (err != OK) {
   5273             ALOGE("Requesting a sync frame failed w/ err %d", err);
   5274             return err;
   5275         }
   5276     }
   5277 
   5278     return OK;
   5279 }
   5280 
   5281 void ACodec::onSignalEndOfInputStream() {
   5282     sp<AMessage> notify = mNotify->dup();
   5283     notify->setInt32("what", CodecBase::kWhatSignaledInputEOS);
   5284 
   5285     status_t err = mOMX->signalEndOfInputStream(mNode);
   5286     if (err != OK) {
   5287         notify->setInt32("err", err);
   5288     }
   5289     notify->post();
   5290 }
   5291 
   5292 bool ACodec::ExecutingState::onOMXEvent(
   5293         OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
   5294     switch (event) {
   5295         case OMX_EventPortSettingsChanged:
   5296         {
   5297             CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
   5298 
   5299             if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
   5300                 mCodec->mMetaDataBuffersToSubmit = 0;
   5301                 CHECK_EQ(mCodec->mOMX->sendCommand(
   5302                             mCodec->mNode,
   5303                             OMX_CommandPortDisable, kPortIndexOutput),
   5304                          (status_t)OK);
   5305 
   5306                 mCodec->freeOutputBuffersNotOwnedByComponent();
   5307 
   5308                 mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
   5309             } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
   5310                 mCodec->mSentFormat = false;
   5311             } else {
   5312                 ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08lx",
   5313                      mCodec->mComponentName.c_str(), data2);
   5314             }
   5315 
   5316             return true;
   5317         }
   5318 
   5319         case OMX_EventBufferFlag:
   5320         {
   5321             return true;
   5322         }
   5323 
   5324         default:
   5325             return BaseState::onOMXEvent(event, data1, data2);
   5326     }
   5327 }
   5328 
   5329 ////////////////////////////////////////////////////////////////////////////////
   5330 
   5331 ACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
   5332         ACodec *codec)
   5333     : BaseState(codec) {
   5334 }
   5335 
   5336 ACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
   5337         OMX_U32 portIndex) {
   5338     if (portIndex == kPortIndexOutput) {
   5339         return FREE_BUFFERS;
   5340     }
   5341 
   5342     CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
   5343 
   5344     return RESUBMIT_BUFFERS;
   5345 }
   5346 
   5347 bool ACodec::OutputPortSettingsChangedState::onMessageReceived(
   5348         const sp<AMessage> &msg) {
   5349     bool handled = false;
   5350 
   5351     switch (msg->what()) {
   5352         case kWhatFlush:
   5353         case kWhatShutdown:
   5354         case kWhatResume:
   5355         {
   5356             if (msg->what() == kWhatResume) {
   5357                 ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
   5358             }
   5359 
   5360             mCodec->deferMessage(msg);
   5361             handled = true;
   5362             break;
   5363         }
   5364 
   5365         default:
   5366             handled = BaseState::onMessageReceived(msg);
   5367             break;
   5368     }
   5369 
   5370     return handled;
   5371 }
   5372 
   5373 void ACodec::OutputPortSettingsChangedState::stateEntered() {
   5374     ALOGV("[%s] Now handling output port settings change",
   5375          mCodec->mComponentName.c_str());
   5376 }
   5377 
   5378 bool ACodec::OutputPortSettingsChangedState::onOMXEvent(
   5379         OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
   5380     switch (event) {
   5381         case OMX_EventCmdComplete:
   5382         {
   5383             if (data1 == (OMX_U32)OMX_CommandPortDisable) {
   5384                 CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
   5385 
   5386                 ALOGV("[%s] Output port now disabled.",
   5387                         mCodec->mComponentName.c_str());
   5388 
   5389                 CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty());
   5390                 mCodec->mDealer[kPortIndexOutput].clear();
   5391 
   5392                 CHECK_EQ(mCodec->mOMX->sendCommand(
   5393                             mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput),
   5394                          (status_t)OK);
   5395 
   5396                 status_t err;
   5397                 if ((err = mCodec->allocateBuffersOnPort(
   5398                                 kPortIndexOutput)) != OK) {
   5399                     ALOGE("Failed to allocate output port buffers after "
   5400                          "port reconfiguration (error 0x%08x)",
   5401                          err);
   5402 
   5403                     mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
   5404 
   5405                     // This is technically not correct, but appears to be
   5406                     // the only way to free the component instance.
   5407                     // Controlled transitioning from excecuting->idle
   5408                     // and idle->loaded seem impossible probably because
   5409                     // the output port never finishes re-enabling.
   5410                     mCodec->mShutdownInProgress = true;
   5411                     mCodec->mKeepComponentAllocated = false;
   5412                     mCodec->changeState(mCodec->mLoadedState);
   5413                 }
   5414 
   5415                 return true;
   5416             } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
   5417                 CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
   5418 
   5419                 mCodec->mSentFormat = false;
   5420 
   5421                 ALOGV("[%s] Output port now reenabled.",
   5422                         mCodec->mComponentName.c_str());
   5423 
   5424                 if (mCodec->mExecutingState->active()) {
   5425                     mCodec->mExecutingState->submitOutputBuffers();
   5426                 }
   5427 
   5428                 mCodec->changeState(mCodec->mExecutingState);
   5429 
   5430                 return true;
   5431             }
   5432 
   5433             return false;
   5434         }
   5435 
   5436         default:
   5437             return false;
   5438     }
   5439 }
   5440 
   5441 ////////////////////////////////////////////////////////////////////////////////
   5442 
   5443 ACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
   5444     : BaseState(codec),
   5445       mComponentNowIdle(false) {
   5446 }
   5447 
   5448 bool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
   5449     bool handled = false;
   5450 
   5451     switch (msg->what()) {
   5452         case kWhatFlush:
   5453         {
   5454             // Don't send me a flush request if you previously wanted me
   5455             // to shutdown.
   5456             TRESPASS();
   5457             break;
   5458         }
   5459 
   5460         case kWhatShutdown:
   5461         {
   5462             // We're already doing that...
   5463 
   5464             handled = true;
   5465             break;
   5466         }
   5467 
   5468         default:
   5469             handled = BaseState::onMessageReceived(msg);
   5470             break;
   5471     }
   5472 
   5473     return handled;
   5474 }
   5475 
   5476 void ACodec::ExecutingToIdleState::stateEntered() {
   5477     ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
   5478 
   5479     mComponentNowIdle = false;
   5480     mCodec->mSentFormat = false;
   5481 }
   5482 
   5483 bool ACodec::ExecutingToIdleState::onOMXEvent(
   5484         OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
   5485     switch (event) {
   5486         case OMX_EventCmdComplete:
   5487         {
   5488             CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
   5489             CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
   5490 
   5491             mComponentNowIdle = true;
   5492 
   5493             changeStateIfWeOwnAllBuffers();
   5494 
   5495             return true;
   5496         }
   5497 
   5498         case OMX_EventPortSettingsChanged:
   5499         case OMX_EventBufferFlag:
   5500         {
   5501             // We're shutting down and don't care about this anymore.
   5502             return true;
   5503         }
   5504 
   5505         default:
   5506             return BaseState::onOMXEvent(event, data1, data2);
   5507     }
   5508 }
   5509 
   5510 void ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
   5511     if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
   5512         CHECK_EQ(mCodec->mOMX->sendCommand(
   5513                     mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded),
   5514                  (status_t)OK);
   5515 
   5516         CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK);
   5517         CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK);
   5518 
   5519         if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
   5520                 && mCodec->mNativeWindow != NULL) {
   5521             // We push enough 1x1 blank buffers to ensure that one of
   5522             // them has made it to the display.  This allows the OMX
   5523             // component teardown to zero out any protected buffers
   5524             // without the risk of scanning out one of those buffers.
   5525             mCodec->pushBlankBuffersToNativeWindow();
   5526         }
   5527 
   5528         mCodec->changeState(mCodec->mIdleToLoadedState);
   5529     }
   5530 }
   5531 
   5532 void ACodec::ExecutingToIdleState::onInputBufferFilled(
   5533         const sp<AMessage> &msg) {
   5534     BaseState::onInputBufferFilled(msg);
   5535 
   5536     changeStateIfWeOwnAllBuffers();
   5537 }
   5538 
   5539 void ACodec::ExecutingToIdleState::onOutputBufferDrained(
   5540         const sp<AMessage> &msg) {
   5541     BaseState::onOutputBufferDrained(msg);
   5542 
   5543     changeStateIfWeOwnAllBuffers();
   5544 }
   5545 
   5546 ////////////////////////////////////////////////////////////////////////////////
   5547 
   5548 ACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
   5549     : BaseState(codec) {
   5550 }
   5551 
   5552 bool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
   5553     bool handled = false;
   5554 
   5555     switch (msg->what()) {
   5556         case kWhatShutdown:
   5557         {
   5558             // We're already doing that...
   5559 
   5560             handled = true;
   5561             break;
   5562         }
   5563 
   5564         case kWhatFlush:
   5565         {
   5566             // Don't send me a flush request if you previously wanted me
   5567             // to shutdown.
   5568             TRESPASS();
   5569             break;
   5570         }
   5571 
   5572         default:
   5573             handled = BaseState::onMessageReceived(msg);
   5574             break;
   5575     }
   5576 
   5577     return handled;
   5578 }
   5579 
   5580 void ACodec::IdleToLoadedState::stateEntered() {
   5581     ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
   5582 }
   5583 
   5584 bool ACodec::IdleToLoadedState::onOMXEvent(
   5585         OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
   5586     switch (event) {
   5587         case OMX_EventCmdComplete:
   5588         {
   5589             CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
   5590             CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
   5591 
   5592             mCodec->changeState(mCodec->mLoadedState);
   5593 
   5594             return true;
   5595         }
   5596 
   5597         default:
   5598             return BaseState::onOMXEvent(event, data1, data2);
   5599     }
   5600 }
   5601 
   5602 ////////////////////////////////////////////////////////////////////////////////
   5603 
   5604 ACodec::FlushingState::FlushingState(ACodec *codec)
   5605     : BaseState(codec) {
   5606 }
   5607 
   5608 void ACodec::FlushingState::stateEntered() {
   5609     ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
   5610 
   5611     mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
   5612 }
   5613 
   5614 bool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
   5615     bool handled = false;
   5616 
   5617     switch (msg->what()) {
   5618         case kWhatShutdown:
   5619         {
   5620             mCodec->deferMessage(msg);
   5621             break;
   5622         }
   5623 
   5624         case kWhatFlush:
   5625         {
   5626             // We're already doing this right now.
   5627             handled = true;
   5628             break;
   5629         }
   5630 
   5631         default:
   5632             handled = BaseState::onMessageReceived(msg);
   5633             break;
   5634     }
   5635 
   5636     return handled;
   5637 }
   5638 
   5639 bool ACodec::FlushingState::onOMXEvent(
   5640         OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
   5641     ALOGV("[%s] FlushingState onOMXEvent(%d,%ld)",
   5642             mCodec->mComponentName.c_str(), event, data1);
   5643 
   5644     switch (event) {
   5645         case OMX_EventCmdComplete:
   5646         {
   5647             CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush);
   5648 
   5649             if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
   5650                 CHECK(!mFlushComplete[data2]);
   5651                 mFlushComplete[data2] = true;
   5652 
   5653                 if (mFlushComplete[kPortIndexInput]
   5654                         && mFlushComplete[kPortIndexOutput]) {
   5655                     changeStateIfWeOwnAllBuffers();
   5656                 }
   5657             } else {
   5658                 CHECK_EQ(data2, OMX_ALL);
   5659                 CHECK(mFlushComplete[kPortIndexInput]);
   5660                 CHECK(mFlushComplete[kPortIndexOutput]);
   5661 
   5662                 changeStateIfWeOwnAllBuffers();
   5663             }
   5664 
   5665             return true;
   5666         }
   5667 
   5668         case OMX_EventPortSettingsChanged:
   5669         {
   5670             sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id());
   5671             msg->setInt32("type", omx_message::EVENT);
   5672             msg->setInt32("node", mCodec->mNode);
   5673             msg->setInt32("event", event);
   5674             msg->setInt32("data1", data1);
   5675             msg->setInt32("data2", data2);
   5676 
   5677             ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
   5678                  mCodec->mComponentName.c_str());
   5679 
   5680             mCodec->deferMessage(msg);
   5681 
   5682             return true;
   5683         }
   5684 
   5685         default:
   5686             return BaseState::onOMXEvent(event, data1, data2);
   5687     }
   5688 
   5689     return true;
   5690 }
   5691 
   5692 void ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
   5693     BaseState::onOutputBufferDrained(msg);
   5694 
   5695     changeStateIfWeOwnAllBuffers();
   5696 }
   5697 
   5698 void ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
   5699     BaseState::onInputBufferFilled(msg);
   5700 
   5701     changeStateIfWeOwnAllBuffers();
   5702 }
   5703 
   5704 void ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
   5705     if (mFlushComplete[kPortIndexInput]
   5706             && mFlushComplete[kPortIndexOutput]
   5707             && mCodec->allYourBuffersAreBelongToUs()) {
   5708         // We now own all buffers except possibly those still queued with
   5709         // the native window for rendering. Let's get those back as well.
   5710         mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
   5711 
   5712         sp<AMessage> notify = mCodec->mNotify->dup();
   5713         notify->setInt32("what", CodecBase::kWhatFlushCompleted);
   5714         notify->post();
   5715 
   5716         mCodec->mPortEOS[kPortIndexInput] =
   5717             mCodec->mPortEOS[kPortIndexOutput] = false;
   5718 
   5719         mCodec->mInputEOSResult = OK;
   5720 
   5721         if (mCodec->mSkipCutBuffer != NULL) {
   5722             mCodec->mSkipCutBuffer->clear();
   5723         }
   5724 
   5725         mCodec->changeState(mCodec->mExecutingState);
   5726     }
   5727 }
   5728 
   5729 }  // namespace android
   5730