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