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 <gui/Surface.h>
     28 
     29 #include <media/stagefright/ACodec.h>
     30 
     31 #include <binder/MemoryDealer.h>
     32 
     33 #include <media/stagefright/foundation/hexdump.h>
     34 #include <media/stagefright/foundation/ABuffer.h>
     35 #include <media/stagefright/foundation/ADebug.h>
     36 #include <media/stagefright/foundation/AMessage.h>
     37 #include <media/stagefright/foundation/AUtils.h>
     38 
     39 #include <media/stagefright/BufferProducerWrapper.h>
     40 #include <media/stagefright/MediaCodec.h>
     41 #include <media/stagefright/MediaCodecList.h>
     42 #include <media/stagefright/MediaDefs.h>
     43 #include <media/stagefright/OMXClient.h>
     44 #include <media/stagefright/PersistentSurface.h>
     45 #include <media/stagefright/SurfaceUtils.h>
     46 #include <media/hardware/HardwareAPI.h>
     47 #include <media/OMXBuffer.h>
     48 #include <media/omx/1.0/WOmxNode.h>
     49 
     50 #include <hidlmemory/mapping.h>
     51 
     52 #include <media/openmax/OMX_AudioExt.h>
     53 #include <media/openmax/OMX_VideoExt.h>
     54 #include <media/openmax/OMX_Component.h>
     55 #include <media/openmax/OMX_IndexExt.h>
     56 #include <media/openmax/OMX_AsString.h>
     57 
     58 #include "include/avc_utils.h"
     59 #include "include/ACodecBufferChannel.h"
     60 #include "include/DataConverter.h"
     61 #include "include/SecureBuffer.h"
     62 #include "include/SharedMemoryBuffer.h"
     63 #include <media/stagefright/omx/OMXUtils.h>
     64 
     65 namespace android {
     66 
     67 using binder::Status;
     68 
     69 enum {
     70     kMaxIndicesToCheck = 32, // used when enumerating supported formats and profiles
     71 };
     72 
     73 // OMX errors are directly mapped into status_t range if
     74 // there is no corresponding MediaError status code.
     75 // Use the statusFromOMXError(int32_t omxError) function.
     76 //
     77 // Currently this is a direct map.
     78 // See frameworks/native/include/media/openmax/OMX_Core.h
     79 //
     80 // Vendor OMX errors     from 0x90000000 - 0x9000FFFF
     81 // Extension OMX errors  from 0x8F000000 - 0x90000000
     82 // Standard OMX errors   from 0x80001000 - 0x80001024 (0x80001024 current)
     83 //
     84 
     85 // returns true if err is a recognized OMX error code.
     86 // as OMX error is OMX_S32, this is an int32_t type
     87 static inline bool isOMXError(int32_t err) {
     88     return (ERROR_CODEC_MIN <= err && err <= ERROR_CODEC_MAX);
     89 }
     90 
     91 // converts an OMX error to a status_t
     92 static inline status_t statusFromOMXError(int32_t omxError) {
     93     switch (omxError) {
     94     case OMX_ErrorInvalidComponentName:
     95     case OMX_ErrorComponentNotFound:
     96         return NAME_NOT_FOUND; // can trigger illegal argument error for provided names.
     97     default:
     98         return isOMXError(omxError) ? omxError : 0; // no translation required
     99     }
    100 }
    101 
    102 static inline status_t statusFromBinderStatus(const Status &status) {
    103     if (status.isOk()) {
    104         return OK;
    105     }
    106     status_t err;
    107     if ((err = status.serviceSpecificErrorCode()) != OK) {
    108         return err;
    109     }
    110     if ((err = status.transactionError()) != OK) {
    111         return err;
    112     }
    113     // Other exception
    114     return UNKNOWN_ERROR;
    115 }
    116 
    117 // checks and converts status_t to a non-side-effect status_t
    118 static inline status_t makeNoSideEffectStatus(status_t err) {
    119     switch (err) {
    120     // the following errors have side effects and may come
    121     // from other code modules. Remap for safety reasons.
    122     case INVALID_OPERATION:
    123     case DEAD_OBJECT:
    124         return UNKNOWN_ERROR;
    125     default:
    126         return err;
    127     }
    128 }
    129 
    130 struct MessageList : public RefBase {
    131     MessageList() {
    132     }
    133     virtual ~MessageList() {
    134     }
    135     std::list<sp<AMessage> > &getList() { return mList; }
    136 private:
    137     std::list<sp<AMessage> > mList;
    138 
    139     DISALLOW_EVIL_CONSTRUCTORS(MessageList);
    140 };
    141 
    142 static sp<DataConverter> getCopyConverter() {
    143     static pthread_once_t once = PTHREAD_ONCE_INIT; // const-inited
    144     static sp<DataConverter> sCopyConverter;        // zero-inited
    145     pthread_once(&once, [](){ sCopyConverter = new DataConverter(); });
    146     return sCopyConverter;
    147 }
    148 
    149 struct CodecObserver : public BnOMXObserver {
    150     CodecObserver() {}
    151 
    152     void setNotificationMessage(const sp<AMessage> &msg) {
    153         mNotify = msg;
    154     }
    155 
    156     // from IOMXObserver
    157     virtual void onMessages(const std::list<omx_message> &messages) {
    158         if (messages.empty()) {
    159             return;
    160         }
    161 
    162         sp<AMessage> notify = mNotify->dup();
    163         sp<MessageList> msgList = new MessageList();
    164         for (std::list<omx_message>::const_iterator it = messages.cbegin();
    165               it != messages.cend(); ++it) {
    166             const omx_message &omx_msg = *it;
    167 
    168             sp<AMessage> msg = new AMessage;
    169             msg->setInt32("type", omx_msg.type);
    170             switch (omx_msg.type) {
    171                 case omx_message::EVENT:
    172                 {
    173                     msg->setInt32("event", omx_msg.u.event_data.event);
    174                     msg->setInt32("data1", omx_msg.u.event_data.data1);
    175                     msg->setInt32("data2", omx_msg.u.event_data.data2);
    176                     break;
    177                 }
    178 
    179                 case omx_message::EMPTY_BUFFER_DONE:
    180                 {
    181                     msg->setInt32("buffer", omx_msg.u.buffer_data.buffer);
    182                     msg->setInt32("fence_fd", omx_msg.fenceFd);
    183                     break;
    184                 }
    185 
    186                 case omx_message::FILL_BUFFER_DONE:
    187                 {
    188                     msg->setInt32(
    189                             "buffer", omx_msg.u.extended_buffer_data.buffer);
    190                     msg->setInt32(
    191                             "range_offset",
    192                             omx_msg.u.extended_buffer_data.range_offset);
    193                     msg->setInt32(
    194                             "range_length",
    195                             omx_msg.u.extended_buffer_data.range_length);
    196                     msg->setInt32(
    197                             "flags",
    198                             omx_msg.u.extended_buffer_data.flags);
    199                     msg->setInt64(
    200                             "timestamp",
    201                             omx_msg.u.extended_buffer_data.timestamp);
    202                     msg->setInt32(
    203                             "fence_fd", omx_msg.fenceFd);
    204                     break;
    205                 }
    206 
    207                 case omx_message::FRAME_RENDERED:
    208                 {
    209                     msg->setInt64(
    210                             "media_time_us", omx_msg.u.render_data.timestamp);
    211                     msg->setInt64(
    212                             "system_nano", omx_msg.u.render_data.nanoTime);
    213                     break;
    214                 }
    215 
    216                 default:
    217                     ALOGE("Unrecognized message type: %d", omx_msg.type);
    218                     break;
    219             }
    220             msgList->getList().push_back(msg);
    221         }
    222         notify->setObject("messages", msgList);
    223         notify->post();
    224     }
    225 
    226 protected:
    227     virtual ~CodecObserver() {}
    228 
    229 private:
    230     sp<AMessage> mNotify;
    231 
    232     DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
    233 };
    234 
    235 ////////////////////////////////////////////////////////////////////////////////
    236 
    237 struct ACodec::BaseState : public AState {
    238     explicit BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
    239 
    240 protected:
    241     enum PortMode {
    242         KEEP_BUFFERS,
    243         RESUBMIT_BUFFERS,
    244         FREE_BUFFERS,
    245     };
    246 
    247     ACodec *mCodec;
    248 
    249     virtual PortMode getPortMode(OMX_U32 portIndex);
    250 
    251     virtual void stateExited();
    252     virtual bool onMessageReceived(const sp<AMessage> &msg);
    253 
    254     virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
    255 
    256     virtual void onOutputBufferDrained(const sp<AMessage> &msg);
    257     virtual void onInputBufferFilled(const sp<AMessage> &msg);
    258 
    259     void postFillThisBuffer(BufferInfo *info);
    260 
    261 private:
    262     // Handles an OMX message. Returns true iff message was handled.
    263     bool onOMXMessage(const sp<AMessage> &msg);
    264 
    265     // Handles a list of messages. Returns true iff messages were handled.
    266     bool onOMXMessageList(const sp<AMessage> &msg);
    267 
    268     // returns true iff this message is for this component and the component is alive
    269     bool checkOMXMessage(const sp<AMessage> &msg);
    270 
    271     bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID, int fenceFd);
    272 
    273     bool onOMXFillBufferDone(
    274             IOMX::buffer_id bufferID,
    275             size_t rangeOffset, size_t rangeLength,
    276             OMX_U32 flags,
    277             int64_t timeUs,
    278             int fenceFd);
    279 
    280     virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano);
    281 
    282     void getMoreInputDataIfPossible();
    283 
    284     DISALLOW_EVIL_CONSTRUCTORS(BaseState);
    285 };
    286 
    287 ////////////////////////////////////////////////////////////////////////////////
    288 
    289 struct ACodec::DeathNotifier :
    290         public IBinder::DeathRecipient,
    291         public ::android::hardware::hidl_death_recipient {
    292     explicit DeathNotifier(const sp<AMessage> &notify)
    293         : mNotify(notify) {
    294     }
    295 
    296     virtual void binderDied(const wp<IBinder> &) {
    297         mNotify->post();
    298     }
    299 
    300     virtual void serviceDied(
    301             uint64_t /* cookie */,
    302             const wp<::android::hidl::base::V1_0::IBase>& /* who */) {
    303         mNotify->post();
    304     }
    305 
    306 protected:
    307     virtual ~DeathNotifier() {}
    308 
    309 private:
    310     sp<AMessage> mNotify;
    311 
    312     DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier);
    313 };
    314 
    315 struct ACodec::UninitializedState : public ACodec::BaseState {
    316     explicit UninitializedState(ACodec *codec);
    317 
    318 protected:
    319     virtual bool onMessageReceived(const sp<AMessage> &msg);
    320     virtual void stateEntered();
    321 
    322 private:
    323     void onSetup(const sp<AMessage> &msg);
    324     bool onAllocateComponent(const sp<AMessage> &msg);
    325 
    326     sp<DeathNotifier> mDeathNotifier;
    327 
    328     DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
    329 };
    330 
    331 ////////////////////////////////////////////////////////////////////////////////
    332 
    333 struct ACodec::LoadedState : public ACodec::BaseState {
    334     explicit LoadedState(ACodec *codec);
    335 
    336 protected:
    337     virtual bool onMessageReceived(const sp<AMessage> &msg);
    338     virtual void stateEntered();
    339 
    340 private:
    341     friend struct ACodec::UninitializedState;
    342 
    343     bool onConfigureComponent(const sp<AMessage> &msg);
    344     void onCreateInputSurface(const sp<AMessage> &msg);
    345     void onSetInputSurface(const sp<AMessage> &msg);
    346     void onStart();
    347     void onShutdown(bool keepComponentAllocated);
    348 
    349     status_t setupInputSurface();
    350 
    351     DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
    352 };
    353 
    354 ////////////////////////////////////////////////////////////////////////////////
    355 
    356 struct ACodec::LoadedToIdleState : public ACodec::BaseState {
    357     explicit LoadedToIdleState(ACodec *codec);
    358 
    359 protected:
    360     virtual bool onMessageReceived(const sp<AMessage> &msg);
    361     virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
    362     virtual void stateEntered();
    363 
    364 private:
    365     status_t allocateBuffers();
    366 
    367     DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
    368 };
    369 
    370 ////////////////////////////////////////////////////////////////////////////////
    371 
    372 struct ACodec::IdleToExecutingState : public ACodec::BaseState {
    373     explicit IdleToExecutingState(ACodec *codec);
    374 
    375 protected:
    376     virtual bool onMessageReceived(const sp<AMessage> &msg);
    377     virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
    378     virtual void stateEntered();
    379 
    380 private:
    381     DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
    382 };
    383 
    384 ////////////////////////////////////////////////////////////////////////////////
    385 
    386 struct ACodec::ExecutingState : public ACodec::BaseState {
    387     explicit ExecutingState(ACodec *codec);
    388 
    389     void submitRegularOutputBuffers();
    390     void submitOutputMetaBuffers();
    391     void submitOutputBuffers();
    392 
    393     // Submit output buffers to the decoder, submit input buffers to client
    394     // to fill with data.
    395     void resume();
    396 
    397     // Returns true iff input and output buffers are in play.
    398     bool active() const { return mActive; }
    399 
    400 protected:
    401     virtual PortMode getPortMode(OMX_U32 portIndex);
    402     virtual bool onMessageReceived(const sp<AMessage> &msg);
    403     virtual void stateEntered();
    404 
    405     virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
    406     virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano);
    407 
    408 private:
    409     bool mActive;
    410 
    411     DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
    412 };
    413 
    414 ////////////////////////////////////////////////////////////////////////////////
    415 
    416 struct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
    417     explicit OutputPortSettingsChangedState(ACodec *codec);
    418 
    419 protected:
    420     virtual PortMode getPortMode(OMX_U32 portIndex);
    421     virtual bool onMessageReceived(const sp<AMessage> &msg);
    422     virtual void stateEntered();
    423 
    424     virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
    425     virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano);
    426 
    427 private:
    428     DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
    429 };
    430 
    431 ////////////////////////////////////////////////////////////////////////////////
    432 
    433 struct ACodec::ExecutingToIdleState : public ACodec::BaseState {
    434     explicit ExecutingToIdleState(ACodec *codec);
    435 
    436 protected:
    437     virtual bool onMessageReceived(const sp<AMessage> &msg);
    438     virtual void stateEntered();
    439 
    440     virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
    441 
    442     virtual void onOutputBufferDrained(const sp<AMessage> &msg);
    443     virtual void onInputBufferFilled(const sp<AMessage> &msg);
    444 
    445 private:
    446     void changeStateIfWeOwnAllBuffers();
    447 
    448     bool mComponentNowIdle;
    449 
    450     DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
    451 };
    452 
    453 ////////////////////////////////////////////////////////////////////////////////
    454 
    455 struct ACodec::IdleToLoadedState : public ACodec::BaseState {
    456     explicit IdleToLoadedState(ACodec *codec);
    457 
    458 protected:
    459     virtual bool onMessageReceived(const sp<AMessage> &msg);
    460     virtual void stateEntered();
    461 
    462     virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
    463 
    464 private:
    465     DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
    466 };
    467 
    468 ////////////////////////////////////////////////////////////////////////////////
    469 
    470 struct ACodec::FlushingState : public ACodec::BaseState {
    471     explicit FlushingState(ACodec *codec);
    472 
    473 protected:
    474     virtual bool onMessageReceived(const sp<AMessage> &msg);
    475     virtual void stateEntered();
    476 
    477     virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
    478 
    479     virtual void onOutputBufferDrained(const sp<AMessage> &msg);
    480     virtual void onInputBufferFilled(const sp<AMessage> &msg);
    481 
    482 private:
    483     bool mFlushComplete[2];
    484 
    485     void changeStateIfWeOwnAllBuffers();
    486 
    487     DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
    488 };
    489 
    490 ////////////////////////////////////////////////////////////////////////////////
    491 
    492 void ACodec::BufferInfo::setWriteFence(int fenceFd, const char *dbg) {
    493     if (mFenceFd >= 0) {
    494         ALOGW("OVERWRITE OF %s fence %d by write fence %d in %s",
    495                 mIsReadFence ? "read" : "write", mFenceFd, fenceFd, dbg);
    496     }
    497     mFenceFd = fenceFd;
    498     mIsReadFence = false;
    499 }
    500 
    501 void ACodec::BufferInfo::setReadFence(int fenceFd, const char *dbg) {
    502     if (mFenceFd >= 0) {
    503         ALOGW("OVERWRITE OF %s fence %d by read fence %d in %s",
    504                 mIsReadFence ? "read" : "write", mFenceFd, fenceFd, dbg);
    505     }
    506     mFenceFd = fenceFd;
    507     mIsReadFence = true;
    508 }
    509 
    510 void ACodec::BufferInfo::checkWriteFence(const char *dbg) {
    511     if (mFenceFd >= 0 && mIsReadFence) {
    512         ALOGD("REUSING read fence %d as write fence in %s", mFenceFd, dbg);
    513     }
    514 }
    515 
    516 void ACodec::BufferInfo::checkReadFence(const char *dbg) {
    517     if (mFenceFd >= 0 && !mIsReadFence) {
    518         ALOGD("REUSING write fence %d as read fence in %s", mFenceFd, dbg);
    519     }
    520 }
    521 
    522 ////////////////////////////////////////////////////////////////////////////////
    523 
    524 ACodec::ACodec()
    525     : mSampleRate(0),
    526       mNodeGeneration(0),
    527       mUsingNativeWindow(false),
    528       mNativeWindowUsageBits(0),
    529       mLastNativeWindowDataSpace(HAL_DATASPACE_UNKNOWN),
    530       mIsVideo(false),
    531       mIsEncoder(false),
    532       mFatalError(false),
    533       mShutdownInProgress(false),
    534       mExplicitShutdown(false),
    535       mIsLegacyVP9Decoder(false),
    536       mEncoderDelay(0),
    537       mEncoderPadding(0),
    538       mRotationDegrees(0),
    539       mChannelMaskPresent(false),
    540       mChannelMask(0),
    541       mDequeueCounter(0),
    542       mMetadataBuffersToSubmit(0),
    543       mNumUndequeuedBuffers(0),
    544       mRepeatFrameDelayUs(-1ll),
    545       mMaxPtsGapUs(-1ll),
    546       mMaxFps(-1),
    547       mFps(-1.0),
    548       mCaptureFps(-1.0),
    549       mCreateInputBuffersSuspended(false),
    550       mLatency(0),
    551       mTunneled(false),
    552       mDescribeColorAspectsIndex((OMX_INDEXTYPE)0),
    553       mDescribeHDRStaticInfoIndex((OMX_INDEXTYPE)0),
    554       mStateGeneration(0),
    555       mVendorExtensionsStatus(kExtensionsUnchecked) {
    556     mUninitializedState = new UninitializedState(this);
    557     mLoadedState = new LoadedState(this);
    558     mLoadedToIdleState = new LoadedToIdleState(this);
    559     mIdleToExecutingState = new IdleToExecutingState(this);
    560     mExecutingState = new ExecutingState(this);
    561 
    562     mOutputPortSettingsChangedState =
    563         new OutputPortSettingsChangedState(this);
    564 
    565     mExecutingToIdleState = new ExecutingToIdleState(this);
    566     mIdleToLoadedState = new IdleToLoadedState(this);
    567     mFlushingState = new FlushingState(this);
    568 
    569     mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
    570     mInputEOSResult = OK;
    571 
    572     mPortMode[kPortIndexInput] = IOMX::kPortModePresetByteBuffer;
    573     mPortMode[kPortIndexOutput] = IOMX::kPortModePresetByteBuffer;
    574 
    575     memset(&mLastNativeWindowCrop, 0, sizeof(mLastNativeWindowCrop));
    576 
    577     changeState(mUninitializedState);
    578 
    579     mTrebleFlag = false;
    580 }
    581 
    582 ACodec::~ACodec() {
    583 }
    584 
    585 void ACodec::initiateSetup(const sp<AMessage> &msg) {
    586     msg->setWhat(kWhatSetup);
    587     msg->setTarget(this);
    588     msg->post();
    589 }
    590 
    591 std::shared_ptr<BufferChannelBase> ACodec::getBufferChannel() {
    592     if (!mBufferChannel) {
    593         mBufferChannel = std::make_shared<ACodecBufferChannel>(
    594                 new AMessage(kWhatInputBufferFilled, this),
    595                 new AMessage(kWhatOutputBufferDrained, this));
    596     }
    597     return mBufferChannel;
    598 }
    599 
    600 void ACodec::signalSetParameters(const sp<AMessage> &params) {
    601     sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
    602     msg->setMessage("params", params);
    603     msg->post();
    604 }
    605 
    606 void ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
    607     msg->setWhat(kWhatAllocateComponent);
    608     msg->setTarget(this);
    609     msg->post();
    610 }
    611 
    612 void ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
    613     msg->setWhat(kWhatConfigureComponent);
    614     msg->setTarget(this);
    615     msg->post();
    616 }
    617 
    618 status_t ACodec::setSurface(const sp<Surface> &surface) {
    619     sp<AMessage> msg = new AMessage(kWhatSetSurface, this);
    620     msg->setObject("surface", surface);
    621 
    622     sp<AMessage> response;
    623     status_t err = msg->postAndAwaitResponse(&response);
    624 
    625     if (err == OK) {
    626         (void)response->findInt32("err", &err);
    627     }
    628     return err;
    629 }
    630 
    631 void ACodec::initiateCreateInputSurface() {
    632     (new AMessage(kWhatCreateInputSurface, this))->post();
    633 }
    634 
    635 void ACodec::initiateSetInputSurface(
    636         const sp<PersistentSurface> &surface) {
    637     sp<AMessage> msg = new AMessage(kWhatSetInputSurface, this);
    638     msg->setObject("input-surface", surface);
    639     msg->post();
    640 }
    641 
    642 void ACodec::signalEndOfInputStream() {
    643     (new AMessage(kWhatSignalEndOfInputStream, this))->post();
    644 }
    645 
    646 void ACodec::initiateStart() {
    647     (new AMessage(kWhatStart, this))->post();
    648 }
    649 
    650 void ACodec::signalFlush() {
    651     ALOGV("[%s] signalFlush", mComponentName.c_str());
    652     (new AMessage(kWhatFlush, this))->post();
    653 }
    654 
    655 void ACodec::signalResume() {
    656     (new AMessage(kWhatResume, this))->post();
    657 }
    658 
    659 void ACodec::initiateShutdown(bool keepComponentAllocated) {
    660     sp<AMessage> msg = new AMessage(kWhatShutdown, this);
    661     msg->setInt32("keepComponentAllocated", keepComponentAllocated);
    662     msg->post();
    663     if (!keepComponentAllocated) {
    664         // ensure shutdown completes in 3 seconds
    665         (new AMessage(kWhatReleaseCodecInstance, this))->post(3000000);
    666     }
    667 }
    668 
    669 void ACodec::signalRequestIDRFrame() {
    670     (new AMessage(kWhatRequestIDRFrame, this))->post();
    671 }
    672 
    673 // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
    674 // Some codecs may return input buffers before having them processed.
    675 // This causes a halt if we already signaled an EOS on the input
    676 // port.  For now keep submitting an output buffer if there was an
    677 // EOS on the input port, but not yet on the output port.
    678 void ACodec::signalSubmitOutputMetadataBufferIfEOS_workaround() {
    679     if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] &&
    680             mMetadataBuffersToSubmit > 0) {
    681         (new AMessage(kWhatSubmitOutputMetadataBufferIfEOS, this))->post();
    682     }
    683 }
    684 
    685 status_t ACodec::handleSetSurface(const sp<Surface> &surface) {
    686     // allow keeping unset surface
    687     if (surface == NULL) {
    688         if (mNativeWindow != NULL) {
    689             ALOGW("cannot unset a surface");
    690             return INVALID_OPERATION;
    691         }
    692         return OK;
    693     }
    694 
    695     // cannot switch from bytebuffers to surface
    696     if (mNativeWindow == NULL) {
    697         ALOGW("component was not configured with a surface");
    698         return INVALID_OPERATION;
    699     }
    700 
    701     ANativeWindow *nativeWindow = surface.get();
    702     // if we have not yet started the codec, we can simply set the native window
    703     if (mBuffers[kPortIndexInput].size() == 0) {
    704         mNativeWindow = surface;
    705         return OK;
    706     }
    707 
    708     // we do not support changing a tunneled surface after start
    709     if (mTunneled) {
    710         ALOGW("cannot change tunneled surface");
    711         return INVALID_OPERATION;
    712     }
    713 
    714     int usageBits = 0;
    715     // no need to reconnect as we will not dequeue all buffers
    716     status_t err = setupNativeWindowSizeFormatAndUsage(
    717             nativeWindow, &usageBits, !storingMetadataInDecodedBuffers());
    718     if (err != OK) {
    719         return err;
    720     }
    721 
    722     int ignoredFlags = kVideoGrallocUsage;
    723     // New output surface is not allowed to add new usage flag except ignored ones.
    724     if ((usageBits & ~(mNativeWindowUsageBits | ignoredFlags)) != 0) {
    725         ALOGW("cannot change usage from %#x to %#x", mNativeWindowUsageBits, usageBits);
    726         return BAD_VALUE;
    727     }
    728 
    729     // get min undequeued count. We cannot switch to a surface that has a higher
    730     // undequeued count than we allocated.
    731     int minUndequeuedBuffers = 0;
    732     err = nativeWindow->query(
    733             nativeWindow, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
    734             &minUndequeuedBuffers);
    735     if (err != 0) {
    736         ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
    737                 strerror(-err), -err);
    738         return err;
    739     }
    740     if (minUndequeuedBuffers > (int)mNumUndequeuedBuffers) {
    741         ALOGE("new surface holds onto more buffers (%d) than planned for (%zu)",
    742                 minUndequeuedBuffers, mNumUndequeuedBuffers);
    743         return BAD_VALUE;
    744     }
    745 
    746     // we cannot change the number of output buffers while OMX is running
    747     // set up surface to the same count
    748     Vector<BufferInfo> &buffers = mBuffers[kPortIndexOutput];
    749     ALOGV("setting up surface for %zu buffers", buffers.size());
    750 
    751     err = native_window_set_buffer_count(nativeWindow, buffers.size());
    752     if (err != 0) {
    753         ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
    754                 -err);
    755         return err;
    756     }
    757 
    758     // need to enable allocation when attaching
    759     surface->getIGraphicBufferProducer()->allowAllocation(true);
    760 
    761     // for meta data mode, we move dequeud buffers to the new surface.
    762     // for non-meta mode, we must move all registered buffers
    763     for (size_t i = 0; i < buffers.size(); ++i) {
    764         const BufferInfo &info = buffers[i];
    765         // skip undequeued buffers for meta data mode
    766         if (storingMetadataInDecodedBuffers()
    767                 && info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
    768             ALOGV("skipping buffer");
    769             continue;
    770         }
    771         ALOGV("attaching buffer %p", info.mGraphicBuffer->getNativeBuffer());
    772 
    773         err = surface->attachBuffer(info.mGraphicBuffer->getNativeBuffer());
    774         if (err != OK) {
    775             ALOGE("failed to attach buffer %p to the new surface: %s (%d)",
    776                     info.mGraphicBuffer->getNativeBuffer(),
    777                     strerror(-err), -err);
    778             return err;
    779         }
    780     }
    781 
    782     // cancel undequeued buffers to new surface
    783     if (!storingMetadataInDecodedBuffers()) {
    784         for (size_t i = 0; i < buffers.size(); ++i) {
    785             BufferInfo &info = buffers.editItemAt(i);
    786             if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
    787                 ALOGV("canceling buffer %p", info.mGraphicBuffer->getNativeBuffer());
    788                 err = nativeWindow->cancelBuffer(
    789                         nativeWindow, info.mGraphicBuffer->getNativeBuffer(), info.mFenceFd);
    790                 info.mFenceFd = -1;
    791                 if (err != OK) {
    792                     ALOGE("failed to cancel buffer %p to the new surface: %s (%d)",
    793                             info.mGraphicBuffer->getNativeBuffer(),
    794                             strerror(-err), -err);
    795                     return err;
    796                 }
    797             }
    798         }
    799         // disallow further allocation
    800         (void)surface->getIGraphicBufferProducer()->allowAllocation(false);
    801     }
    802 
    803     // push blank buffers to previous window if requested
    804     if (mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown) {
    805         pushBlankBuffersToNativeWindow(mNativeWindow.get());
    806     }
    807 
    808     mNativeWindow = nativeWindow;
    809     mNativeWindowUsageBits = usageBits;
    810     return OK;
    811 }
    812 
    813 status_t ACodec::setPortMode(int32_t portIndex, IOMX::PortMode mode) {
    814     status_t err = mOMXNode->setPortMode(portIndex, mode);
    815     if (err != OK) {
    816         ALOGE("[%s] setPortMode on %s to %s failed w/ err %d",
    817                 mComponentName.c_str(),
    818                 portIndex == kPortIndexInput ? "input" : "output",
    819                 asString(mode),
    820                 err);
    821         return err;
    822     }
    823 
    824     mPortMode[portIndex] = mode;
    825     return OK;
    826 }
    827 
    828 status_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
    829     CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
    830 
    831     if (getTrebleFlag()) {
    832         CHECK(mAllocator[portIndex] == NULL);
    833     } else {
    834         CHECK(mDealer[portIndex] == NULL);
    835     }
    836     CHECK(mBuffers[portIndex].isEmpty());
    837 
    838     status_t err;
    839     if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
    840         if (storingMetadataInDecodedBuffers()) {
    841             err = allocateOutputMetadataBuffers();
    842         } else {
    843             err = allocateOutputBuffersFromNativeWindow();
    844         }
    845     } else {
    846         OMX_PARAM_PORTDEFINITIONTYPE def;
    847         InitOMXParams(&def);
    848         def.nPortIndex = portIndex;
    849 
    850         err = mOMXNode->getParameter(
    851                 OMX_IndexParamPortDefinition, &def, sizeof(def));
    852 
    853         if (err == OK) {
    854             const IOMX::PortMode &mode = mPortMode[portIndex];
    855             size_t bufSize = def.nBufferSize;
    856             // Always allocate VideoNativeMetadata if using ANWBuffer.
    857             // OMX might use gralloc source internally, but we don't share
    858             // metadata buffer with OMX, OMX has its own headers.
    859             if (mode == IOMX::kPortModeDynamicANWBuffer) {
    860                 bufSize = sizeof(VideoNativeMetadata);
    861             } else if (mode == IOMX::kPortModeDynamicNativeHandle) {
    862                 bufSize = sizeof(VideoNativeHandleMetadata);
    863             }
    864 
    865             size_t conversionBufferSize = 0;
    866 
    867             sp<DataConverter> converter = mConverter[portIndex];
    868             if (converter != NULL) {
    869                 // here we assume sane conversions of max 4:1, so result fits in int32
    870                 if (portIndex == kPortIndexInput) {
    871                     conversionBufferSize = converter->sourceSize(bufSize);
    872                 } else {
    873                     conversionBufferSize = converter->targetSize(bufSize);
    874                 }
    875             }
    876 
    877             size_t alignment = MemoryDealer::getAllocationAlignment();
    878 
    879             ALOGV("[%s] Allocating %u buffers of size %zu (from %u using %s) on %s port",
    880                     mComponentName.c_str(),
    881                     def.nBufferCountActual, bufSize, def.nBufferSize, asString(mode),
    882                     portIndex == kPortIndexInput ? "input" : "output");
    883 
    884             // verify buffer sizes to avoid overflow in align()
    885             if (bufSize == 0 || max(bufSize, conversionBufferSize) > kMaxCodecBufferSize) {
    886                 ALOGE("b/22885421");
    887                 return NO_MEMORY;
    888             }
    889 
    890             // don't modify bufSize as OMX may not expect it to increase after negotiation
    891             size_t alignedSize = align(bufSize, alignment);
    892             size_t alignedConvSize = align(conversionBufferSize, alignment);
    893             if (def.nBufferCountActual > SIZE_MAX / (alignedSize + alignedConvSize)) {
    894                 ALOGE("b/22885421");
    895                 return NO_MEMORY;
    896             }
    897 
    898             if (mode != IOMX::kPortModePresetSecureBuffer) {
    899                 if (getTrebleFlag()) {
    900                     mAllocator[portIndex] = TAllocator::getService("ashmem");
    901                     if (mAllocator[portIndex] == nullptr) {
    902                         ALOGE("hidl allocator on port %d is null",
    903                                 (int)portIndex);
    904                         return NO_MEMORY;
    905                     }
    906                 } else {
    907                     size_t totalSize = def.nBufferCountActual *
    908                             (alignedSize + alignedConvSize);
    909                     mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
    910                 }
    911             }
    912 
    913             const sp<AMessage> &format =
    914                     portIndex == kPortIndexInput ? mInputFormat : mOutputFormat;
    915             for (OMX_U32 i = 0; i < def.nBufferCountActual && err == OK; ++i) {
    916                 hidl_memory hidlMemToken;
    917                 sp<TMemory> hidlMem;
    918                 sp<IMemory> mem;
    919 
    920                 BufferInfo info;
    921                 info.mStatus = BufferInfo::OWNED_BY_US;
    922                 info.mFenceFd = -1;
    923                 info.mRenderInfo = NULL;
    924                 info.mGraphicBuffer = NULL;
    925                 info.mNewGraphicBuffer = false;
    926 
    927                 if (mode == IOMX::kPortModePresetSecureBuffer) {
    928                     void *ptr = NULL;
    929                     sp<NativeHandle> native_handle;
    930                     err = mOMXNode->allocateSecureBuffer(
    931                             portIndex, bufSize, &info.mBufferID,
    932                             &ptr, &native_handle);
    933 
    934                     info.mData = (native_handle == NULL)
    935                             ? new SecureBuffer(format, ptr, bufSize)
    936                             : new SecureBuffer(format, native_handle, bufSize);
    937                     info.mCodecData = info.mData;
    938                 } else {
    939                     if (getTrebleFlag()) {
    940                         bool success;
    941                         auto transStatus = mAllocator[portIndex]->allocate(
    942                                 bufSize,
    943                                 [&success, &hidlMemToken](
    944                                         bool s,
    945                                         hidl_memory const& m) {
    946                                     success = s;
    947                                     hidlMemToken = m;
    948                                 });
    949 
    950                         if (!transStatus.isOk()) {
    951                             ALOGE("hidl's AshmemAllocator failed at the "
    952                                     "transport: %s",
    953                                     transStatus.description().c_str());
    954                             return NO_MEMORY;
    955                         }
    956                         if (!success) {
    957                             return NO_MEMORY;
    958                         }
    959                         hidlMem = mapMemory(hidlMemToken);
    960                         if (hidlMem == nullptr) {
    961                             return NO_MEMORY;
    962                         }
    963                         err = mOMXNode->useBuffer(
    964                                 portIndex, hidlMemToken, &info.mBufferID);
    965                     } else {
    966                         mem = mDealer[portIndex]->allocate(bufSize);
    967                         if (mem == NULL || mem->pointer() == NULL) {
    968                             return NO_MEMORY;
    969                         }
    970 
    971                         err = mOMXNode->useBuffer(
    972                                 portIndex, mem, &info.mBufferID);
    973                     }
    974 
    975                     if (mode == IOMX::kPortModeDynamicANWBuffer) {
    976                         VideoNativeMetadata* metaData = (VideoNativeMetadata*)(
    977                                 getTrebleFlag() ?
    978                                 (void*)hidlMem->getPointer() : mem->pointer());
    979                         metaData->nFenceFd = -1;
    980                     }
    981 
    982                     if (getTrebleFlag()) {
    983                         info.mCodecData = new SharedMemoryBuffer(
    984                                 format, hidlMem);
    985                         info.mCodecRef = hidlMem;
    986                     } else {
    987                         info.mCodecData = new SharedMemoryBuffer(
    988                                 format, mem);
    989                         info.mCodecRef = mem;
    990                     }
    991 
    992                     // if we require conversion, allocate conversion buffer for client use;
    993                     // otherwise, reuse codec buffer
    994                     if (mConverter[portIndex] != NULL) {
    995                         CHECK_GT(conversionBufferSize, (size_t)0);
    996                         if (getTrebleFlag()) {
    997                             bool success;
    998                             mAllocator[portIndex]->allocate(
    999                                     conversionBufferSize,
   1000                                     [&success, &hidlMemToken](
   1001                                             bool s,
   1002                                             hidl_memory const& m) {
   1003                                         success = s;
   1004                                         hidlMemToken = m;
   1005                                     });
   1006                             if (!success) {
   1007                                 return NO_MEMORY;
   1008                             }
   1009                             hidlMem = mapMemory(hidlMemToken);
   1010                             if (hidlMem == nullptr) {
   1011                                 return NO_MEMORY;
   1012                             }
   1013                             info.mData = new SharedMemoryBuffer(format, hidlMem);
   1014                             info.mMemRef = hidlMem;
   1015                         } else {
   1016                             mem = mDealer[portIndex]->allocate(
   1017                                     conversionBufferSize);
   1018                             if (mem == NULL|| mem->pointer() == NULL) {
   1019                                 return NO_MEMORY;
   1020                             }
   1021                             info.mData = new SharedMemoryBuffer(format, mem);
   1022                             info.mMemRef = mem;
   1023                         }
   1024                     } else {
   1025                         info.mData = info.mCodecData;
   1026                         info.mMemRef = info.mCodecRef;
   1027                     }
   1028                 }
   1029 
   1030                 mBuffers[portIndex].push(info);
   1031             }
   1032         }
   1033     }
   1034 
   1035     if (err != OK) {
   1036         return err;
   1037     }
   1038 
   1039     std::vector<ACodecBufferChannel::BufferAndId> array(mBuffers[portIndex].size());
   1040     for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
   1041         array[i] = {mBuffers[portIndex][i].mData, mBuffers[portIndex][i].mBufferID};
   1042     }
   1043     if (portIndex == kPortIndexInput) {
   1044         mBufferChannel->setInputBufferArray(array);
   1045     } else if (portIndex == kPortIndexOutput) {
   1046         mBufferChannel->setOutputBufferArray(array);
   1047     } else {
   1048         TRESPASS();
   1049     }
   1050 
   1051     return OK;
   1052 }
   1053 
   1054 status_t ACodec::setupNativeWindowSizeFormatAndUsage(
   1055         ANativeWindow *nativeWindow /* nonnull */, int *finalUsage /* nonnull */,
   1056         bool reconnect) {
   1057     OMX_PARAM_PORTDEFINITIONTYPE def;
   1058     InitOMXParams(&def);
   1059     def.nPortIndex = kPortIndexOutput;
   1060 
   1061     status_t err = mOMXNode->getParameter(
   1062             OMX_IndexParamPortDefinition, &def, sizeof(def));
   1063 
   1064     if (err != OK) {
   1065         return err;
   1066     }
   1067 
   1068     OMX_INDEXTYPE index;
   1069     err = mOMXNode->getExtensionIndex(
   1070             "OMX.google.android.index.AndroidNativeBufferConsumerUsage",
   1071             &index);
   1072 
   1073     if (err != OK) {
   1074         // allow failure
   1075         err = OK;
   1076     } else {
   1077         int usageBits = 0;
   1078         if (nativeWindow->query(
   1079                 nativeWindow,
   1080                 NATIVE_WINDOW_CONSUMER_USAGE_BITS,
   1081                 &usageBits) == OK) {
   1082             OMX_PARAM_U32TYPE params;
   1083             InitOMXParams(&params);
   1084             params.nPortIndex = kPortIndexOutput;
   1085             params.nU32 = (OMX_U32)usageBits;
   1086 
   1087             err = mOMXNode->setParameter(index, &params, sizeof(params));
   1088 
   1089             if (err != OK) {
   1090                 ALOGE("Fail to set AndroidNativeBufferConsumerUsage: %d", err);
   1091                 return err;
   1092             }
   1093         }
   1094     }
   1095 
   1096     OMX_U32 usage = 0;
   1097     err = mOMXNode->getGraphicBufferUsage(kPortIndexOutput, &usage);
   1098     if (err != 0) {
   1099         ALOGW("querying usage flags from OMX IL component failed: %d", err);
   1100         // XXX: Currently this error is logged, but not fatal.
   1101         usage = 0;
   1102     }
   1103     int omxUsage = usage;
   1104 
   1105     if (mFlags & kFlagIsGrallocUsageProtected) {
   1106         usage |= GRALLOC_USAGE_PROTECTED;
   1107     }
   1108 
   1109     usage |= kVideoGrallocUsage;
   1110     *finalUsage = usage;
   1111 
   1112     memset(&mLastNativeWindowCrop, 0, sizeof(mLastNativeWindowCrop));
   1113     mLastNativeWindowDataSpace = HAL_DATASPACE_UNKNOWN;
   1114 
   1115     ALOGV("gralloc usage: %#x(OMX) => %#x(ACodec)", omxUsage, usage);
   1116     return setNativeWindowSizeFormatAndUsage(
   1117             nativeWindow,
   1118             def.format.video.nFrameWidth,
   1119             def.format.video.nFrameHeight,
   1120             def.format.video.eColorFormat,
   1121             mRotationDegrees,
   1122             usage,
   1123             reconnect);
   1124 }
   1125 
   1126 status_t ACodec::configureOutputBuffersFromNativeWindow(
   1127         OMX_U32 *bufferCount, OMX_U32 *bufferSize,
   1128         OMX_U32 *minUndequeuedBuffers, bool preregister) {
   1129 
   1130     OMX_PARAM_PORTDEFINITIONTYPE def;
   1131     InitOMXParams(&def);
   1132     def.nPortIndex = kPortIndexOutput;
   1133 
   1134     status_t err = mOMXNode->getParameter(
   1135             OMX_IndexParamPortDefinition, &def, sizeof(def));
   1136 
   1137     if (err == OK) {
   1138         err = setupNativeWindowSizeFormatAndUsage(
   1139                 mNativeWindow.get(), &mNativeWindowUsageBits,
   1140                 preregister && !mTunneled /* reconnect */);
   1141     }
   1142     if (err != OK) {
   1143         mNativeWindowUsageBits = 0;
   1144         return err;
   1145     }
   1146 
   1147     // Exits here for tunneled video playback codecs -- i.e. skips native window
   1148     // buffer allocation step as this is managed by the tunneled OMX omponent
   1149     // itself and explicitly sets def.nBufferCountActual to 0.
   1150     if (mTunneled) {
   1151         ALOGV("Tunneled Playback: skipping native window buffer allocation.");
   1152         def.nBufferCountActual = 0;
   1153         err = mOMXNode->setParameter(
   1154                 OMX_IndexParamPortDefinition, &def, sizeof(def));
   1155 
   1156         *minUndequeuedBuffers = 0;
   1157         *bufferCount = 0;
   1158         *bufferSize = 0;
   1159         return err;
   1160     }
   1161 
   1162     *minUndequeuedBuffers = 0;
   1163     err = mNativeWindow->query(
   1164             mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
   1165             (int *)minUndequeuedBuffers);
   1166 
   1167     if (err != 0) {
   1168         ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
   1169                 strerror(-err), -err);
   1170         return err;
   1171     }
   1172 
   1173     // FIXME: assume that surface is controlled by app (native window
   1174     // returns the number for the case when surface is not controlled by app)
   1175     // FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported
   1176     // For now, try to allocate 1 more buffer, but don't fail if unsuccessful
   1177 
   1178     // Use conservative allocation while also trying to reduce starvation
   1179     //
   1180     // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the
   1181     //    minimum needed for the consumer to be able to work
   1182     // 2. try to allocate two (2) additional buffers to reduce starvation from
   1183     //    the consumer
   1184     //    plus an extra buffer to account for incorrect minUndequeuedBufs
   1185     for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) {
   1186         OMX_U32 newBufferCount =
   1187             def.nBufferCountMin + *minUndequeuedBuffers + extraBuffers;
   1188         def.nBufferCountActual = newBufferCount;
   1189         err = mOMXNode->setParameter(
   1190                 OMX_IndexParamPortDefinition, &def, sizeof(def));
   1191 
   1192         if (err == OK) {
   1193             *minUndequeuedBuffers += extraBuffers;
   1194             break;
   1195         }
   1196 
   1197         ALOGW("[%s] setting nBufferCountActual to %u failed: %d",
   1198                 mComponentName.c_str(), newBufferCount, err);
   1199         /* exit condition */
   1200         if (extraBuffers == 0) {
   1201             return err;
   1202         }
   1203     }
   1204 
   1205     err = native_window_set_buffer_count(
   1206             mNativeWindow.get(), def.nBufferCountActual);
   1207 
   1208     if (err != 0) {
   1209         ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
   1210                 -err);
   1211         return err;
   1212     }
   1213 
   1214     *bufferCount = def.nBufferCountActual;
   1215     *bufferSize =  def.nBufferSize;
   1216     return err;
   1217 }
   1218 
   1219 status_t ACodec::allocateOutputBuffersFromNativeWindow() {
   1220     // This method only handles the non-metadata mode (or simulating legacy
   1221     // mode with metadata, which is transparent to ACodec).
   1222     CHECK(!storingMetadataInDecodedBuffers());
   1223 
   1224     OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
   1225     status_t err = configureOutputBuffersFromNativeWindow(
   1226             &bufferCount, &bufferSize, &minUndequeuedBuffers, true /* preregister */);
   1227     if (err != 0)
   1228         return err;
   1229     mNumUndequeuedBuffers = minUndequeuedBuffers;
   1230 
   1231     static_cast<Surface*>(mNativeWindow.get())
   1232             ->getIGraphicBufferProducer()->allowAllocation(true);
   1233 
   1234     ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
   1235          "output port",
   1236          mComponentName.c_str(), bufferCount, bufferSize);
   1237 
   1238     // Dequeue buffers and send them to OMX
   1239     for (OMX_U32 i = 0; i < bufferCount; i++) {
   1240         ANativeWindowBuffer *buf;
   1241         int fenceFd;
   1242         err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd);
   1243         if (err != 0) {
   1244             ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
   1245             break;
   1246         }
   1247 
   1248         sp<GraphicBuffer> graphicBuffer(GraphicBuffer::from(buf));
   1249         BufferInfo info;
   1250         info.mStatus = BufferInfo::OWNED_BY_US;
   1251         info.mFenceFd = fenceFd;
   1252         info.mIsReadFence = false;
   1253         info.mRenderInfo = NULL;
   1254         info.mGraphicBuffer = graphicBuffer;
   1255         info.mNewGraphicBuffer = false;
   1256 
   1257         // TODO: We shouln't need to create MediaCodecBuffer. In metadata mode
   1258         //       OMX doesn't use the shared memory buffer, but some code still
   1259         //       access info.mData. Create an ABuffer as a placeholder.
   1260         info.mData = new MediaCodecBuffer(mOutputFormat, new ABuffer(bufferSize));
   1261         info.mCodecData = info.mData;
   1262 
   1263         mBuffers[kPortIndexOutput].push(info);
   1264 
   1265         IOMX::buffer_id bufferId;
   1266         err = mOMXNode->useBuffer(kPortIndexOutput, graphicBuffer, &bufferId);
   1267         if (err != 0) {
   1268             ALOGE("registering GraphicBuffer %u with OMX IL component failed: "
   1269                  "%d", i, err);
   1270             break;
   1271         }
   1272 
   1273         mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
   1274 
   1275         ALOGV("[%s] Registered graphic buffer with ID %u (pointer = %p)",
   1276              mComponentName.c_str(),
   1277              bufferId, graphicBuffer.get());
   1278     }
   1279 
   1280     OMX_U32 cancelStart;
   1281     OMX_U32 cancelEnd;
   1282 
   1283     if (err != OK) {
   1284         // If an error occurred while dequeuing we need to cancel any buffers
   1285         // that were dequeued. Also cancel all if we're in legacy metadata mode.
   1286         cancelStart = 0;
   1287         cancelEnd = mBuffers[kPortIndexOutput].size();
   1288     } else {
   1289         // Return the required minimum undequeued buffers to the native window.
   1290         cancelStart = bufferCount - minUndequeuedBuffers;
   1291         cancelEnd = bufferCount;
   1292     }
   1293 
   1294     for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
   1295         BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
   1296         if (info->mStatus == BufferInfo::OWNED_BY_US) {
   1297             status_t error = cancelBufferToNativeWindow(info);
   1298             if (err == 0) {
   1299                 err = error;
   1300             }
   1301         }
   1302     }
   1303 
   1304     static_cast<Surface*>(mNativeWindow.get())
   1305             ->getIGraphicBufferProducer()->allowAllocation(false);
   1306 
   1307     return err;
   1308 }
   1309 
   1310 status_t ACodec::allocateOutputMetadataBuffers() {
   1311     CHECK(storingMetadataInDecodedBuffers());
   1312 
   1313     OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
   1314     status_t err = configureOutputBuffersFromNativeWindow(
   1315             &bufferCount, &bufferSize, &minUndequeuedBuffers,
   1316             false /* preregister */);
   1317     if (err != OK)
   1318         return err;
   1319     mNumUndequeuedBuffers = minUndequeuedBuffers;
   1320 
   1321     ALOGV("[%s] Allocating %u meta buffers on output port",
   1322          mComponentName.c_str(), bufferCount);
   1323 
   1324     for (OMX_U32 i = 0; i < bufferCount; i++) {
   1325         BufferInfo info;
   1326         info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
   1327         info.mFenceFd = -1;
   1328         info.mRenderInfo = NULL;
   1329         info.mGraphicBuffer = NULL;
   1330         info.mNewGraphicBuffer = false;
   1331         info.mDequeuedAt = mDequeueCounter;
   1332 
   1333         info.mData = new MediaCodecBuffer(mOutputFormat, new ABuffer(bufferSize));
   1334 
   1335         // Initialize fence fd to -1 to avoid warning in freeBuffer().
   1336         ((VideoNativeMetadata *)info.mData->base())->nFenceFd = -1;
   1337 
   1338         info.mCodecData = info.mData;
   1339 
   1340         err = mOMXNode->useBuffer(kPortIndexOutput, OMXBuffer::sPreset, &info.mBufferID);
   1341         mBuffers[kPortIndexOutput].push(info);
   1342 
   1343         ALOGV("[%s] allocated meta buffer with ID %u",
   1344                 mComponentName.c_str(), info.mBufferID);
   1345     }
   1346 
   1347     mMetadataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
   1348     return err;
   1349 }
   1350 
   1351 status_t ACodec::submitOutputMetadataBuffer() {
   1352     CHECK(storingMetadataInDecodedBuffers());
   1353     if (mMetadataBuffersToSubmit == 0)
   1354         return OK;
   1355 
   1356     BufferInfo *info = dequeueBufferFromNativeWindow();
   1357     if (info == NULL) {
   1358         return ERROR_IO;
   1359     }
   1360 
   1361     ALOGV("[%s] submitting output meta buffer ID %u for graphic buffer %p",
   1362           mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer->handle);
   1363 
   1364     --mMetadataBuffersToSubmit;
   1365     info->checkWriteFence("submitOutputMetadataBuffer");
   1366     return fillBuffer(info);
   1367 }
   1368 
   1369 status_t ACodec::waitForFence(int fd, const char *dbg ) {
   1370     status_t res = OK;
   1371     if (fd >= 0) {
   1372         sp<Fence> fence = new Fence(fd);
   1373         res = fence->wait(IOMX::kFenceTimeoutMs);
   1374         ALOGW_IF(res != OK, "FENCE TIMEOUT for %d in %s", fd, dbg);
   1375     }
   1376     return res;
   1377 }
   1378 
   1379 // static
   1380 const char *ACodec::_asString(BufferInfo::Status s) {
   1381     switch (s) {
   1382         case BufferInfo::OWNED_BY_US:            return "OUR";
   1383         case BufferInfo::OWNED_BY_COMPONENT:     return "COMPONENT";
   1384         case BufferInfo::OWNED_BY_UPSTREAM:      return "UPSTREAM";
   1385         case BufferInfo::OWNED_BY_DOWNSTREAM:    return "DOWNSTREAM";
   1386         case BufferInfo::OWNED_BY_NATIVE_WINDOW: return "SURFACE";
   1387         case BufferInfo::UNRECOGNIZED:           return "UNRECOGNIZED";
   1388         default:                                 return "?";
   1389     }
   1390 }
   1391 
   1392 void ACodec::dumpBuffers(OMX_U32 portIndex) {
   1393     CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
   1394     ALOGI("[%s] %s port has %zu buffers:", mComponentName.c_str(),
   1395             portIndex == kPortIndexInput ? "input" : "output", mBuffers[portIndex].size());
   1396     for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
   1397         const BufferInfo &info = mBuffers[portIndex][i];
   1398         ALOGI("  slot %2zu: #%8u %p/%p %s(%d) dequeued:%u",
   1399                 i, info.mBufferID, info.mGraphicBuffer.get(),
   1400                 info.mGraphicBuffer == NULL ? NULL : info.mGraphicBuffer->getNativeBuffer(),
   1401                 _asString(info.mStatus), info.mStatus, info.mDequeuedAt);
   1402     }
   1403 }
   1404 
   1405 status_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
   1406     CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
   1407 
   1408     ALOGV("[%s] Calling cancelBuffer on buffer %u",
   1409          mComponentName.c_str(), info->mBufferID);
   1410 
   1411     info->checkWriteFence("cancelBufferToNativeWindow");
   1412     int err = mNativeWindow->cancelBuffer(
   1413         mNativeWindow.get(), info->mGraphicBuffer.get(), info->mFenceFd);
   1414     info->mFenceFd = -1;
   1415 
   1416     ALOGW_IF(err != 0, "[%s] can not return buffer %u to native window",
   1417             mComponentName.c_str(), info->mBufferID);
   1418     // change ownership even if cancelBuffer fails
   1419     info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
   1420 
   1421     return err;
   1422 }
   1423 
   1424 void ACodec::updateRenderInfoForDequeuedBuffer(
   1425         ANativeWindowBuffer *buf, int fenceFd, BufferInfo *info) {
   1426 
   1427     info->mRenderInfo =
   1428         mRenderTracker.updateInfoForDequeuedBuffer(
   1429                 buf, fenceFd, info - &mBuffers[kPortIndexOutput][0]);
   1430 
   1431     // check for any fences already signaled
   1432     notifyOfRenderedFrames(false /* dropIncomplete */, info->mRenderInfo);
   1433 }
   1434 
   1435 void ACodec::onFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano) {
   1436     if (mRenderTracker.onFrameRendered(mediaTimeUs, systemNano) != OK) {
   1437         mRenderTracker.dumpRenderQueue();
   1438     }
   1439 }
   1440 
   1441 void ACodec::notifyOfRenderedFrames(bool dropIncomplete, FrameRenderTracker::Info *until) {
   1442     std::list<FrameRenderTracker::Info> done =
   1443         mRenderTracker.checkFencesAndGetRenderedFrames(until, dropIncomplete);
   1444 
   1445     // unlink untracked frames
   1446     for (std::list<FrameRenderTracker::Info>::const_iterator it = done.cbegin();
   1447             it != done.cend(); ++it) {
   1448         ssize_t index = it->getIndex();
   1449         if (index >= 0 && (size_t)index < mBuffers[kPortIndexOutput].size()) {
   1450             mBuffers[kPortIndexOutput].editItemAt(index).mRenderInfo = NULL;
   1451         } else if (index >= 0) {
   1452             // THIS SHOULD NEVER HAPPEN
   1453             ALOGE("invalid index %zd in %zu", index, mBuffers[kPortIndexOutput].size());
   1454         }
   1455     }
   1456 
   1457     mCallback->onOutputFramesRendered(done);
   1458 }
   1459 
   1460 ACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
   1461     ANativeWindowBuffer *buf;
   1462     CHECK(mNativeWindow.get() != NULL);
   1463 
   1464     if (mTunneled) {
   1465         ALOGW("dequeueBufferFromNativeWindow() should not be called in tunnel"
   1466               " video playback mode mode!");
   1467         return NULL;
   1468     }
   1469 
   1470     if (mFatalError) {
   1471         ALOGW("not dequeuing from native window due to fatal error");
   1472         return NULL;
   1473     }
   1474 
   1475     int fenceFd = -1;
   1476     do {
   1477         status_t err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd);
   1478         if (err != 0) {
   1479             ALOGE("dequeueBuffer failed: %s(%d).", asString(err), err);
   1480             return NULL;
   1481         }
   1482 
   1483         bool stale = false;
   1484         for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) {
   1485             i--;
   1486             BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
   1487 
   1488             if (info->mGraphicBuffer != NULL &&
   1489                     info->mGraphicBuffer->handle == buf->handle) {
   1490                 // Since consumers can attach buffers to BufferQueues, it is possible
   1491                 // that a known yet stale buffer can return from a surface that we
   1492                 // once used.  We can simply ignore this as we have already dequeued
   1493                 // this buffer properly.  NOTE: this does not eliminate all cases,
   1494                 // e.g. it is possible that we have queued the valid buffer to the
   1495                 // NW, and a stale copy of the same buffer gets dequeued - which will
   1496                 // be treated as the valid buffer by ACodec.
   1497                 if (info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
   1498                     ALOGI("dequeued stale buffer %p. discarding", buf);
   1499                     stale = true;
   1500                     break;
   1501                 }
   1502 
   1503                 ALOGV("dequeued buffer #%u with age %u, graphicBuffer %p",
   1504                         (unsigned)(info - &mBuffers[kPortIndexOutput][0]),
   1505                         mDequeueCounter - info->mDequeuedAt,
   1506                         info->mGraphicBuffer->handle);
   1507 
   1508                 info->mStatus = BufferInfo::OWNED_BY_US;
   1509                 info->setWriteFence(fenceFd, "dequeueBufferFromNativeWindow");
   1510                 updateRenderInfoForDequeuedBuffer(buf, fenceFd, info);
   1511                 return info;
   1512             }
   1513         }
   1514 
   1515         // It is also possible to receive a previously unregistered buffer
   1516         // in non-meta mode. These should be treated as stale buffers. The
   1517         // same is possible in meta mode, in which case, it will be treated
   1518         // as a normal buffer, which is not desirable.
   1519         // TODO: fix this.
   1520         if (!stale && !storingMetadataInDecodedBuffers()) {
   1521             ALOGI("dequeued unrecognized (stale) buffer %p. discarding", buf);
   1522             stale = true;
   1523         }
   1524         if (stale) {
   1525             // TODO: detach stale buffer, but there is no API yet to do it.
   1526             buf = NULL;
   1527         }
   1528     } while (buf == NULL);
   1529 
   1530     // get oldest undequeued buffer
   1531     BufferInfo *oldest = NULL;
   1532     for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) {
   1533         i--;
   1534         BufferInfo *info =
   1535             &mBuffers[kPortIndexOutput].editItemAt(i);
   1536         if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
   1537             (oldest == NULL ||
   1538              // avoid potential issues from counter rolling over
   1539              mDequeueCounter - info->mDequeuedAt >
   1540                     mDequeueCounter - oldest->mDequeuedAt)) {
   1541             oldest = info;
   1542         }
   1543     }
   1544 
   1545     // it is impossible dequeue a buffer when there are no buffers with ANW
   1546     CHECK(oldest != NULL);
   1547     // it is impossible to dequeue an unknown buffer in non-meta mode, as the
   1548     // while loop above does not complete
   1549     CHECK(storingMetadataInDecodedBuffers());
   1550 
   1551     // discard buffer in LRU info and replace with new buffer
   1552     oldest->mGraphicBuffer = GraphicBuffer::from(buf);
   1553     oldest->mNewGraphicBuffer = true;
   1554     oldest->mStatus = BufferInfo::OWNED_BY_US;
   1555     oldest->setWriteFence(fenceFd, "dequeueBufferFromNativeWindow for oldest");
   1556     mRenderTracker.untrackFrame(oldest->mRenderInfo);
   1557     oldest->mRenderInfo = NULL;
   1558 
   1559     ALOGV("replaced oldest buffer #%u with age %u, graphicBuffer %p",
   1560             (unsigned)(oldest - &mBuffers[kPortIndexOutput][0]),
   1561             mDequeueCounter - oldest->mDequeuedAt,
   1562             oldest->mGraphicBuffer->handle);
   1563 
   1564     updateRenderInfoForDequeuedBuffer(buf, fenceFd, oldest);
   1565     return oldest;
   1566 }
   1567 
   1568 status_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
   1569     if (portIndex == kPortIndexInput) {
   1570         mBufferChannel->setInputBufferArray({});
   1571     } else {
   1572         mBufferChannel->setOutputBufferArray({});
   1573     }
   1574 
   1575     status_t err = OK;
   1576     for (size_t i = mBuffers[portIndex].size(); i > 0;) {
   1577         i--;
   1578         status_t err2 = freeBuffer(portIndex, i);
   1579         if (err == OK) {
   1580             err = err2;
   1581         }
   1582     }
   1583 
   1584     if (getTrebleFlag()) {
   1585         mAllocator[portIndex].clear();
   1586     } else {
   1587         mDealer[portIndex].clear();
   1588     }
   1589     return err;
   1590 }
   1591 
   1592 status_t ACodec::freeOutputBuffersNotOwnedByComponent() {
   1593     status_t err = OK;
   1594     for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) {
   1595         i--;
   1596         BufferInfo *info =
   1597             &mBuffers[kPortIndexOutput].editItemAt(i);
   1598 
   1599         // At this time some buffers may still be with the component
   1600         // or being drained.
   1601         if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
   1602             info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
   1603             status_t err2 = freeBuffer(kPortIndexOutput, i);
   1604             if (err == OK) {
   1605                 err = err2;
   1606             }
   1607         }
   1608     }
   1609 
   1610     return err;
   1611 }
   1612 
   1613 status_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
   1614     BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
   1615     status_t err = OK;
   1616 
   1617     // there should not be any fences in the metadata
   1618     if (mPortMode[portIndex] == IOMX::kPortModeDynamicANWBuffer && info->mCodecData != NULL
   1619             && info->mCodecData->size() >= sizeof(VideoNativeMetadata)) {
   1620         int fenceFd = ((VideoNativeMetadata *)info->mCodecData->base())->nFenceFd;
   1621         if (fenceFd >= 0) {
   1622             ALOGW("unreleased fence (%d) in %s metadata buffer %zu",
   1623                     fenceFd, portIndex == kPortIndexInput ? "input" : "output", i);
   1624         }
   1625     }
   1626 
   1627     switch (info->mStatus) {
   1628         case BufferInfo::OWNED_BY_US:
   1629             if (portIndex == kPortIndexOutput && mNativeWindow != NULL) {
   1630                 (void)cancelBufferToNativeWindow(info);
   1631             }
   1632             // fall through
   1633 
   1634         case BufferInfo::OWNED_BY_NATIVE_WINDOW:
   1635             err = mOMXNode->freeBuffer(portIndex, info->mBufferID);
   1636             break;
   1637 
   1638         default:
   1639             ALOGE("trying to free buffer not owned by us or ANW (%d)", info->mStatus);
   1640             err = FAILED_TRANSACTION;
   1641             break;
   1642     }
   1643 
   1644     if (info->mFenceFd >= 0) {
   1645         ::close(info->mFenceFd);
   1646     }
   1647 
   1648     if (portIndex == kPortIndexOutput) {
   1649         mRenderTracker.untrackFrame(info->mRenderInfo, i);
   1650         info->mRenderInfo = NULL;
   1651     }
   1652 
   1653     // remove buffer even if mOMXNode->freeBuffer fails
   1654     mBuffers[portIndex].removeAt(i);
   1655     return err;
   1656 }
   1657 
   1658 ACodec::BufferInfo *ACodec::findBufferByID(
   1659         uint32_t portIndex, IOMX::buffer_id bufferID, ssize_t *index) {
   1660     for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
   1661         BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
   1662 
   1663         if (info->mBufferID == bufferID) {
   1664             if (index != NULL) {
   1665                 *index = i;
   1666             }
   1667             return info;
   1668         }
   1669     }
   1670 
   1671     ALOGE("Could not find buffer with ID %u", bufferID);
   1672     return NULL;
   1673 }
   1674 
   1675 status_t ACodec::fillBuffer(BufferInfo *info) {
   1676     status_t err;
   1677     // Even in dynamic ANW buffer mode, if the graphic buffer is not changing,
   1678     // send sPreset instead of the same graphic buffer, so that OMX server
   1679     // side doesn't update the meta. In theory it should make no difference,
   1680     // however when the same buffer is parcelled again, a new handle could be
   1681     // created on server side, and some decoder doesn't recognize the handle
   1682     // even if it's the same buffer.
   1683     if (!storingMetadataInDecodedBuffers() || !info->mNewGraphicBuffer) {
   1684         err = mOMXNode->fillBuffer(
   1685             info->mBufferID, OMXBuffer::sPreset, info->mFenceFd);
   1686     } else {
   1687         err = mOMXNode->fillBuffer(
   1688             info->mBufferID, info->mGraphicBuffer, info->mFenceFd);
   1689     }
   1690 
   1691     info->mNewGraphicBuffer = false;
   1692     info->mFenceFd = -1;
   1693     if (err == OK) {
   1694         info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
   1695     }
   1696     return err;
   1697 }
   1698 
   1699 status_t ACodec::setComponentRole(
   1700         bool isEncoder, const char *mime) {
   1701     const char *role = GetComponentRole(isEncoder, mime);
   1702     if (role == NULL) {
   1703         return BAD_VALUE;
   1704     }
   1705     status_t err = SetComponentRole(mOMXNode, role);
   1706     if (err != OK) {
   1707         ALOGW("[%s] Failed to set standard component role '%s'.",
   1708              mComponentName.c_str(), role);
   1709     }
   1710     return err;
   1711 }
   1712 
   1713 status_t ACodec::configureCodec(
   1714         const char *mime, const sp<AMessage> &msg) {
   1715     int32_t encoder;
   1716     if (!msg->findInt32("encoder", &encoder)) {
   1717         encoder = false;
   1718     }
   1719 
   1720     sp<AMessage> inputFormat = new AMessage;
   1721     sp<AMessage> outputFormat = new AMessage;
   1722     mConfigFormat = msg;
   1723 
   1724     mIsEncoder = encoder;
   1725 
   1726     mPortMode[kPortIndexInput] = IOMX::kPortModePresetByteBuffer;
   1727     mPortMode[kPortIndexOutput] = IOMX::kPortModePresetByteBuffer;
   1728 
   1729     status_t err = setComponentRole(encoder /* isEncoder */, mime);
   1730 
   1731     if (err != OK) {
   1732         return err;
   1733     }
   1734 
   1735     int32_t bitRate = 0;
   1736     // FLAC encoder doesn't need a bitrate, other encoders do
   1737     if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
   1738             && !msg->findInt32("bitrate", &bitRate)) {
   1739         return INVALID_OPERATION;
   1740     }
   1741 
   1742     // propagate bitrate to the output so that the muxer has it
   1743     if (encoder && msg->findInt32("bitrate", &bitRate)) {
   1744         // Technically ISO spec says that 'bitrate' should be 0 for VBR even though it is the
   1745         // average bitrate. We've been setting both bitrate and max-bitrate to this same value.
   1746         outputFormat->setInt32("bitrate", bitRate);
   1747         outputFormat->setInt32("max-bitrate", bitRate);
   1748     }
   1749 
   1750     int32_t storeMeta;
   1751     if (encoder
   1752             && msg->findInt32("android._input-metadata-buffer-type", &storeMeta)
   1753             && storeMeta != kMetadataBufferTypeInvalid) {
   1754         IOMX::PortMode mode;
   1755         if (storeMeta == kMetadataBufferTypeNativeHandleSource) {
   1756             mode = IOMX::kPortModeDynamicNativeHandle;
   1757         } else if (storeMeta == kMetadataBufferTypeANWBuffer ||
   1758                 storeMeta == kMetadataBufferTypeGrallocSource) {
   1759             mode = IOMX::kPortModeDynamicANWBuffer;
   1760         } else {
   1761             return BAD_VALUE;
   1762         }
   1763         err = setPortMode(kPortIndexInput, mode);
   1764         if (err != OK) {
   1765             return err;
   1766         }
   1767 
   1768         uint32_t usageBits;
   1769         if (mOMXNode->getParameter(
   1770                 (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
   1771                 &usageBits, sizeof(usageBits)) == OK) {
   1772             inputFormat->setInt32(
   1773                     "using-sw-read-often", !!(usageBits & GRALLOC_USAGE_SW_READ_OFTEN));
   1774         }
   1775     }
   1776 
   1777     int32_t prependSPSPPS = 0;
   1778     if (encoder
   1779             && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
   1780             && prependSPSPPS != 0) {
   1781         OMX_INDEXTYPE index;
   1782         err = mOMXNode->getExtensionIndex(
   1783                 "OMX.google.android.index.prependSPSPPSToIDRFrames", &index);
   1784 
   1785         if (err == OK) {
   1786             PrependSPSPPSToIDRFramesParams params;
   1787             InitOMXParams(&params);
   1788             params.bEnable = OMX_TRUE;
   1789 
   1790             err = mOMXNode->setParameter(index, &params, sizeof(params));
   1791         }
   1792 
   1793         if (err != OK) {
   1794             ALOGE("Encoder could not be configured to emit SPS/PPS before "
   1795                   "IDR frames. (err %d)", err);
   1796 
   1797             return err;
   1798         }
   1799     }
   1800 
   1801     // Only enable metadata mode on encoder output if encoder can prepend
   1802     // sps/pps to idr frames, since in metadata mode the bitstream is in an
   1803     // opaque handle, to which we don't have access.
   1804     int32_t video = !strncasecmp(mime, "video/", 6);
   1805     mIsVideo = video;
   1806     if (encoder && video) {
   1807         OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
   1808             && msg->findInt32("android._store-metadata-in-buffers-output", &storeMeta)
   1809             && storeMeta != 0);
   1810         if (mFlags & kFlagIsSecure) {
   1811             enable = OMX_TRUE;
   1812         }
   1813 
   1814         err = setPortMode(kPortIndexOutput, enable ?
   1815                 IOMX::kPortModePresetSecureBuffer : IOMX::kPortModePresetByteBuffer);
   1816         if (err != OK) {
   1817             return err;
   1818         }
   1819 
   1820         if (!msg->findInt64(
   1821                     "repeat-previous-frame-after",
   1822                     &mRepeatFrameDelayUs)) {
   1823             mRepeatFrameDelayUs = -1ll;
   1824         }
   1825 
   1826         // only allow 32-bit value, since we pass it as U32 to OMX.
   1827         if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) {
   1828             mMaxPtsGapUs = -1ll;
   1829         } else if (mMaxPtsGapUs > INT32_MAX || mMaxPtsGapUs < 0) {
   1830             ALOGW("Unsupported value for max pts gap %lld", (long long) mMaxPtsGapUs);
   1831             mMaxPtsGapUs = -1ll;
   1832         }
   1833 
   1834         if (!msg->findFloat("max-fps-to-encoder", &mMaxFps)) {
   1835             mMaxFps = -1;
   1836         }
   1837 
   1838         if (!msg->findDouble("time-lapse-fps", &mCaptureFps)) {
   1839             mCaptureFps = -1.0;
   1840         }
   1841 
   1842         if (!msg->findInt32(
   1843                     "create-input-buffers-suspended",
   1844                     (int32_t*)&mCreateInputBuffersSuspended)) {
   1845             mCreateInputBuffersSuspended = false;
   1846         }
   1847     }
   1848 
   1849     // NOTE: we only use native window for video decoders
   1850     sp<RefBase> obj;
   1851     bool haveNativeWindow = msg->findObject("native-window", &obj)
   1852             && obj != NULL && video && !encoder;
   1853     mUsingNativeWindow = haveNativeWindow;
   1854     if (video && !encoder) {
   1855         inputFormat->setInt32("adaptive-playback", false);
   1856 
   1857         int32_t usageProtected;
   1858         if (msg->findInt32("protected", &usageProtected) && usageProtected) {
   1859             if (!haveNativeWindow) {
   1860                 ALOGE("protected output buffers must be sent to an ANativeWindow");
   1861                 return PERMISSION_DENIED;
   1862             }
   1863             mFlags |= kFlagIsGrallocUsageProtected;
   1864             mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
   1865         }
   1866     }
   1867     if (mFlags & kFlagIsSecure) {
   1868         // use native_handles for secure input buffers
   1869         err = setPortMode(kPortIndexInput, IOMX::kPortModePresetSecureBuffer);
   1870 
   1871         if (err != OK) {
   1872             ALOGI("falling back to non-native_handles");
   1873             setPortMode(kPortIndexInput, IOMX::kPortModePresetByteBuffer);
   1874             err = OK; // ignore error for now
   1875         }
   1876     }
   1877     if (haveNativeWindow) {
   1878         sp<ANativeWindow> nativeWindow =
   1879             static_cast<ANativeWindow *>(static_cast<Surface *>(obj.get()));
   1880 
   1881         // START of temporary support for automatic FRC - THIS WILL BE REMOVED
   1882         int32_t autoFrc;
   1883         if (msg->findInt32("auto-frc", &autoFrc)) {
   1884             bool enabled = autoFrc;
   1885             OMX_CONFIG_BOOLEANTYPE config;
   1886             InitOMXParams(&config);
   1887             config.bEnabled = (OMX_BOOL)enabled;
   1888             status_t temp = mOMXNode->setConfig(
   1889                     (OMX_INDEXTYPE)OMX_IndexConfigAutoFramerateConversion,
   1890                     &config, sizeof(config));
   1891             if (temp == OK) {
   1892                 outputFormat->setInt32("auto-frc", enabled);
   1893             } else if (enabled) {
   1894                 ALOGI("codec does not support requested auto-frc (err %d)", temp);
   1895             }
   1896         }
   1897         // END of temporary support for automatic FRC
   1898 
   1899         int32_t tunneled;
   1900         if (msg->findInt32("feature-tunneled-playback", &tunneled) &&
   1901             tunneled != 0) {
   1902             ALOGI("Configuring TUNNELED video playback.");
   1903             mTunneled = true;
   1904 
   1905             int32_t audioHwSync = 0;
   1906             if (!msg->findInt32("audio-hw-sync", &audioHwSync)) {
   1907                 ALOGW("No Audio HW Sync provided for video tunnel");
   1908             }
   1909             err = configureTunneledVideoPlayback(audioHwSync, nativeWindow);
   1910             if (err != OK) {
   1911                 ALOGE("configureTunneledVideoPlayback(%d,%p) failed!",
   1912                         audioHwSync, nativeWindow.get());
   1913                 return err;
   1914             }
   1915 
   1916             int32_t maxWidth = 0, maxHeight = 0;
   1917             if (msg->findInt32("max-width", &maxWidth) &&
   1918                     msg->findInt32("max-height", &maxHeight)) {
   1919 
   1920                 err = mOMXNode->prepareForAdaptivePlayback(
   1921                         kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
   1922                 if (err != OK) {
   1923                     ALOGW("[%s] prepareForAdaptivePlayback failed w/ err %d",
   1924                             mComponentName.c_str(), err);
   1925                     // allow failure
   1926                     err = OK;
   1927                 } else {
   1928                     inputFormat->setInt32("max-width", maxWidth);
   1929                     inputFormat->setInt32("max-height", maxHeight);
   1930                     inputFormat->setInt32("adaptive-playback", true);
   1931                 }
   1932             }
   1933         } else {
   1934             ALOGV("Configuring CPU controlled video playback.");
   1935             mTunneled = false;
   1936 
   1937             // Explicity reset the sideband handle of the window for
   1938             // non-tunneled video in case the window was previously used
   1939             // for a tunneled video playback.
   1940             err = native_window_set_sideband_stream(nativeWindow.get(), NULL);
   1941             if (err != OK) {
   1942                 ALOGE("set_sideband_stream(NULL) failed! (err %d).", err);
   1943                 return err;
   1944             }
   1945 
   1946             err = setPortMode(kPortIndexOutput, IOMX::kPortModeDynamicANWBuffer);
   1947             if (err != OK) {
   1948                 // if adaptive playback has been requested, try JB fallback
   1949                 // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
   1950                 // LARGE MEMORY REQUIREMENT
   1951 
   1952                 // we will not do adaptive playback on software accessed
   1953                 // surfaces as they never had to respond to changes in the
   1954                 // crop window, and we don't trust that they will be able to.
   1955                 int usageBits = 0;
   1956                 bool canDoAdaptivePlayback;
   1957 
   1958                 if (nativeWindow->query(
   1959                         nativeWindow.get(),
   1960                         NATIVE_WINDOW_CONSUMER_USAGE_BITS,
   1961                         &usageBits) != OK) {
   1962                     canDoAdaptivePlayback = false;
   1963                 } else {
   1964                     canDoAdaptivePlayback =
   1965                         (usageBits &
   1966                                 (GRALLOC_USAGE_SW_READ_MASK |
   1967                                  GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
   1968                 }
   1969 
   1970                 int32_t maxWidth = 0, maxHeight = 0;
   1971                 if (canDoAdaptivePlayback &&
   1972                         msg->findInt32("max-width", &maxWidth) &&
   1973                         msg->findInt32("max-height", &maxHeight)) {
   1974                     ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)",
   1975                             mComponentName.c_str(), maxWidth, maxHeight);
   1976 
   1977                     err = mOMXNode->prepareForAdaptivePlayback(
   1978                             kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
   1979                     ALOGW_IF(err != OK,
   1980                             "[%s] prepareForAdaptivePlayback failed w/ err %d",
   1981                             mComponentName.c_str(), err);
   1982 
   1983                     if (err == OK) {
   1984                         inputFormat->setInt32("max-width", maxWidth);
   1985                         inputFormat->setInt32("max-height", maxHeight);
   1986                         inputFormat->setInt32("adaptive-playback", true);
   1987                     }
   1988                 }
   1989                 // allow failure
   1990                 err = OK;
   1991             } else {
   1992                 ALOGV("[%s] setPortMode on output to %s succeeded",
   1993                         mComponentName.c_str(), asString(IOMX::kPortModeDynamicANWBuffer));
   1994                 CHECK(storingMetadataInDecodedBuffers());
   1995                 inputFormat->setInt32("adaptive-playback", true);
   1996             }
   1997 
   1998             int32_t push;
   1999             if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
   2000                     && push != 0) {
   2001                 mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
   2002             }
   2003         }
   2004 
   2005         int32_t rotationDegrees;
   2006         if (msg->findInt32("rotation-degrees", &rotationDegrees)) {
   2007             mRotationDegrees = rotationDegrees;
   2008         } else {
   2009             mRotationDegrees = 0;
   2010         }
   2011     }
   2012 
   2013     AudioEncoding pcmEncoding = kAudioEncodingPcm16bit;
   2014     (void)msg->findInt32("pcm-encoding", (int32_t*)&pcmEncoding);
   2015     // invalid encodings will default to PCM-16bit in setupRawAudioFormat.
   2016 
   2017     if (video) {
   2018         // determine need for software renderer
   2019         bool usingSwRenderer = false;
   2020         if (haveNativeWindow && mComponentName.startsWith("OMX.google.")) {
   2021             usingSwRenderer = true;
   2022             haveNativeWindow = false;
   2023             (void)setPortMode(kPortIndexOutput, IOMX::kPortModePresetByteBuffer);
   2024         } else if (haveNativeWindow && !storingMetadataInDecodedBuffers()) {
   2025             err = setPortMode(kPortIndexOutput, IOMX::kPortModePresetANWBuffer);
   2026             if (err != OK) {
   2027                 return err;
   2028             }
   2029         }
   2030 
   2031         if (encoder) {
   2032             err = setupVideoEncoder(mime, msg, outputFormat, inputFormat);
   2033         } else {
   2034             err = setupVideoDecoder(mime, msg, haveNativeWindow, usingSwRenderer, outputFormat);
   2035         }
   2036 
   2037         if (err != OK) {
   2038             return err;
   2039         }
   2040 
   2041         if (haveNativeWindow) {
   2042             mNativeWindow = static_cast<Surface *>(obj.get());
   2043 
   2044             // fallback for devices that do not handle flex-YUV for native buffers
   2045             int32_t requestedColorFormat = OMX_COLOR_FormatUnused;
   2046             if (msg->findInt32("color-format", &requestedColorFormat) &&
   2047                     requestedColorFormat == OMX_COLOR_FormatYUV420Flexible) {
   2048                 status_t err = getPortFormat(kPortIndexOutput, outputFormat);
   2049                 if (err != OK) {
   2050                     return err;
   2051                 }
   2052                 int32_t colorFormat = OMX_COLOR_FormatUnused;
   2053                 OMX_U32 flexibleEquivalent = OMX_COLOR_FormatUnused;
   2054                 if (!outputFormat->findInt32("color-format", &colorFormat)) {
   2055                     ALOGE("ouptut port did not have a color format (wrong domain?)");
   2056                     return BAD_VALUE;
   2057                 }
   2058                 ALOGD("[%s] Requested output format %#x and got %#x.",
   2059                         mComponentName.c_str(), requestedColorFormat, colorFormat);
   2060                 if (!IsFlexibleColorFormat(
   2061                         mOMXNode, colorFormat, haveNativeWindow, &flexibleEquivalent)
   2062                         || flexibleEquivalent != (OMX_U32)requestedColorFormat) {
   2063                     // device did not handle flex-YUV request for native window, fall back
   2064                     // to SW renderer
   2065                     ALOGI("[%s] Falling back to software renderer", mComponentName.c_str());
   2066                     mNativeWindow.clear();
   2067                     mNativeWindowUsageBits = 0;
   2068                     haveNativeWindow = false;
   2069                     usingSwRenderer = true;
   2070                     // TODO: implement adaptive-playback support for bytebuffer mode.
   2071                     // This is done by SW codecs, but most HW codecs don't support it.
   2072                     err = setPortMode(kPortIndexOutput, IOMX::kPortModePresetByteBuffer);
   2073                     inputFormat->setInt32("adaptive-playback", false);
   2074                     if (mFlags & kFlagIsGrallocUsageProtected) {
   2075                         // fallback is not supported for protected playback
   2076                         err = PERMISSION_DENIED;
   2077                     } else if (err == OK) {
   2078                         err = setupVideoDecoder(
   2079                                 mime, msg, haveNativeWindow, usingSwRenderer, outputFormat);
   2080                     }
   2081                 }
   2082             }
   2083         }
   2084 
   2085         if (usingSwRenderer) {
   2086             outputFormat->setInt32("using-sw-renderer", 1);
   2087         }
   2088     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
   2089         int32_t numChannels, sampleRate;
   2090         if (!msg->findInt32("channel-count", &numChannels)
   2091                 || !msg->findInt32("sample-rate", &sampleRate)) {
   2092             // Since we did not always check for these, leave them optional
   2093             // and have the decoder figure it all out.
   2094             err = OK;
   2095         } else {
   2096             err = setupRawAudioFormat(
   2097                     encoder ? kPortIndexInput : kPortIndexOutput,
   2098                     sampleRate,
   2099                     numChannels);
   2100         }
   2101     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
   2102         int32_t numChannels, sampleRate;
   2103         if (!msg->findInt32("channel-count", &numChannels)
   2104                 || !msg->findInt32("sample-rate", &sampleRate)) {
   2105             err = INVALID_OPERATION;
   2106         } else {
   2107             int32_t isADTS, aacProfile;
   2108             int32_t sbrMode;
   2109             int32_t maxOutputChannelCount;
   2110             int32_t pcmLimiterEnable;
   2111             drcParams_t drc;
   2112             if (!msg->findInt32("is-adts", &isADTS)) {
   2113                 isADTS = 0;
   2114             }
   2115             if (!msg->findInt32("aac-profile", &aacProfile)) {
   2116                 aacProfile = OMX_AUDIO_AACObjectNull;
   2117             }
   2118             if (!msg->findInt32("aac-sbr-mode", &sbrMode)) {
   2119                 sbrMode = -1;
   2120             }
   2121 
   2122             if (!msg->findInt32("aac-max-output-channel_count", &maxOutputChannelCount)) {
   2123                 maxOutputChannelCount = -1;
   2124             }
   2125             if (!msg->findInt32("aac-pcm-limiter-enable", &pcmLimiterEnable)) {
   2126                 // value is unknown
   2127                 pcmLimiterEnable = -1;
   2128             }
   2129             if (!msg->findInt32("aac-encoded-target-level", &drc.encodedTargetLevel)) {
   2130                 // value is unknown
   2131                 drc.encodedTargetLevel = -1;
   2132             }
   2133             if (!msg->findInt32("aac-drc-cut-level", &drc.drcCut)) {
   2134                 // value is unknown
   2135                 drc.drcCut = -1;
   2136             }
   2137             if (!msg->findInt32("aac-drc-boost-level", &drc.drcBoost)) {
   2138                 // value is unknown
   2139                 drc.drcBoost = -1;
   2140             }
   2141             if (!msg->findInt32("aac-drc-heavy-compression", &drc.heavyCompression)) {
   2142                 // value is unknown
   2143                 drc.heavyCompression = -1;
   2144             }
   2145             if (!msg->findInt32("aac-target-ref-level", &drc.targetRefLevel)) {
   2146                 // value is unknown
   2147                 drc.targetRefLevel = -1;
   2148             }
   2149 
   2150             err = setupAACCodec(
   2151                     encoder, numChannels, sampleRate, bitRate, aacProfile,
   2152                     isADTS != 0, sbrMode, maxOutputChannelCount, drc,
   2153                     pcmLimiterEnable);
   2154         }
   2155     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
   2156         err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
   2157     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
   2158         err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
   2159     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
   2160             || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
   2161         // These are PCM-like formats with a fixed sample rate but
   2162         // a variable number of channels.
   2163 
   2164         int32_t numChannels;
   2165         if (!msg->findInt32("channel-count", &numChannels)) {
   2166             err = INVALID_OPERATION;
   2167         } else {
   2168             int32_t sampleRate;
   2169             if (!msg->findInt32("sample-rate", &sampleRate)) {
   2170                 sampleRate = 8000;
   2171             }
   2172             err = setupG711Codec(encoder, sampleRate, numChannels);
   2173         }
   2174     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
   2175         int32_t numChannels = 0, sampleRate = 0, compressionLevel = -1;
   2176         if (encoder &&
   2177                 (!msg->findInt32("channel-count", &numChannels)
   2178                         || !msg->findInt32("sample-rate", &sampleRate))) {
   2179             ALOGE("missing channel count or sample rate for FLAC encoder");
   2180             err = INVALID_OPERATION;
   2181         } else {
   2182             if (encoder) {
   2183                 if (!msg->findInt32(
   2184                             "complexity", &compressionLevel) &&
   2185                     !msg->findInt32(
   2186                             "flac-compression-level", &compressionLevel)) {
   2187                     compressionLevel = 5; // default FLAC compression level
   2188                 } else if (compressionLevel < 0) {
   2189                     ALOGW("compression level %d outside [0..8] range, "
   2190                           "using 0",
   2191                           compressionLevel);
   2192                     compressionLevel = 0;
   2193                 } else if (compressionLevel > 8) {
   2194                     ALOGW("compression level %d outside [0..8] range, "
   2195                           "using 8",
   2196                           compressionLevel);
   2197                     compressionLevel = 8;
   2198                 }
   2199             }
   2200             err = setupFlacCodec(
   2201                     encoder, numChannels, sampleRate, compressionLevel);
   2202         }
   2203     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
   2204         int32_t numChannels, sampleRate;
   2205         if (encoder
   2206                 || !msg->findInt32("channel-count", &numChannels)
   2207                 || !msg->findInt32("sample-rate", &sampleRate)) {
   2208             err = INVALID_OPERATION;
   2209         } else {
   2210             err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels, pcmEncoding);
   2211         }
   2212     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
   2213         int32_t numChannels;
   2214         int32_t sampleRate;
   2215         if (!msg->findInt32("channel-count", &numChannels)
   2216                 || !msg->findInt32("sample-rate", &sampleRate)) {
   2217             err = INVALID_OPERATION;
   2218         } else {
   2219             err = setupAC3Codec(encoder, numChannels, sampleRate);
   2220         }
   2221     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_EAC3)) {
   2222         int32_t numChannels;
   2223         int32_t sampleRate;
   2224         if (!msg->findInt32("channel-count", &numChannels)
   2225                 || !msg->findInt32("sample-rate", &sampleRate)) {
   2226             err = INVALID_OPERATION;
   2227         } else {
   2228             err = setupEAC3Codec(encoder, numChannels, sampleRate);
   2229         }
   2230     }
   2231 
   2232     if (err != OK) {
   2233         return err;
   2234     }
   2235 
   2236     if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
   2237         mEncoderDelay = 0;
   2238     }
   2239 
   2240     if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
   2241         mEncoderPadding = 0;
   2242     }
   2243 
   2244     if (msg->findInt32("channel-mask", &mChannelMask)) {
   2245         mChannelMaskPresent = true;
   2246     } else {
   2247         mChannelMaskPresent = false;
   2248     }
   2249 
   2250     int32_t maxInputSize;
   2251     if (msg->findInt32("max-input-size", &maxInputSize)) {
   2252         err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
   2253         err = OK; // ignore error
   2254     } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
   2255         err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
   2256         err = OK; // ignore error
   2257     }
   2258 
   2259     int32_t priority;
   2260     if (msg->findInt32("priority", &priority)) {
   2261         err = setPriority(priority);
   2262         err = OK; // ignore error
   2263     }
   2264 
   2265     int32_t rateInt = -1;
   2266     float rateFloat = -1;
   2267     if (!msg->findFloat("operating-rate", &rateFloat)) {
   2268         msg->findInt32("operating-rate", &rateInt);
   2269         rateFloat = (float)rateInt;  // 16MHz (FLINTMAX) is OK for upper bound.
   2270     }
   2271     if (rateFloat > 0) {
   2272         err = setOperatingRate(rateFloat, video);
   2273         err = OK; // ignore errors
   2274     }
   2275 
   2276     if (err == OK) {
   2277         err = setVendorParameters(msg);
   2278         if (err != OK) {
   2279             return err;
   2280         }
   2281     }
   2282 
   2283     // NOTE: both mBaseOutputFormat and mOutputFormat are outputFormat to signal first frame.
   2284     mBaseOutputFormat = outputFormat;
   2285     mLastOutputFormat.clear();
   2286 
   2287     err = getPortFormat(kPortIndexInput, inputFormat);
   2288     if (err == OK) {
   2289         err = getPortFormat(kPortIndexOutput, outputFormat);
   2290         if (err == OK) {
   2291             mInputFormat = inputFormat;
   2292             mOutputFormat = outputFormat;
   2293         }
   2294     }
   2295 
   2296     // create data converters if needed
   2297     if (!video && err == OK) {
   2298         AudioEncoding codecPcmEncoding = kAudioEncodingPcm16bit;
   2299         if (encoder) {
   2300             (void)mInputFormat->findInt32("pcm-encoding", (int32_t*)&codecPcmEncoding);
   2301             mConverter[kPortIndexInput] = AudioConverter::Create(pcmEncoding, codecPcmEncoding);
   2302             if (mConverter[kPortIndexInput] != NULL) {
   2303                 mInputFormat->setInt32("pcm-encoding", pcmEncoding);
   2304             }
   2305         } else {
   2306             (void)mOutputFormat->findInt32("pcm-encoding", (int32_t*)&codecPcmEncoding);
   2307             mConverter[kPortIndexOutput] = AudioConverter::Create(codecPcmEncoding, pcmEncoding);
   2308             if (mConverter[kPortIndexOutput] != NULL) {
   2309                 mOutputFormat->setInt32("pcm-encoding", pcmEncoding);
   2310             }
   2311         }
   2312     }
   2313 
   2314     return err;
   2315 }
   2316 
   2317 status_t ACodec::setLatency(uint32_t latency) {
   2318     OMX_PARAM_U32TYPE config;
   2319     InitOMXParams(&config);
   2320     config.nPortIndex = kPortIndexInput;
   2321     config.nU32 = (OMX_U32)latency;
   2322     status_t err = mOMXNode->setConfig(
   2323             (OMX_INDEXTYPE)OMX_IndexConfigLatency,
   2324             &config, sizeof(config));
   2325     return err;
   2326 }
   2327 
   2328 status_t ACodec::getLatency(uint32_t *latency) {
   2329     OMX_PARAM_U32TYPE config;
   2330     InitOMXParams(&config);
   2331     config.nPortIndex = kPortIndexInput;
   2332     status_t err = mOMXNode->getConfig(
   2333             (OMX_INDEXTYPE)OMX_IndexConfigLatency,
   2334             &config, sizeof(config));
   2335     if (err == OK) {
   2336         *latency = config.nU32;
   2337     }
   2338     return err;
   2339 }
   2340 
   2341 status_t ACodec::setPriority(int32_t priority) {
   2342     if (priority < 0) {
   2343         return BAD_VALUE;
   2344     }
   2345     OMX_PARAM_U32TYPE config;
   2346     InitOMXParams(&config);
   2347     config.nU32 = (OMX_U32)priority;
   2348     status_t temp = mOMXNode->setConfig(
   2349             (OMX_INDEXTYPE)OMX_IndexConfigPriority,
   2350             &config, sizeof(config));
   2351     if (temp != OK) {
   2352         ALOGI("codec does not support config priority (err %d)", temp);
   2353     }
   2354     return OK;
   2355 }
   2356 
   2357 status_t ACodec::setOperatingRate(float rateFloat, bool isVideo) {
   2358     if (rateFloat < 0) {
   2359         return BAD_VALUE;
   2360     }
   2361     OMX_U32 rate;
   2362     if (isVideo) {
   2363         if (rateFloat > 65535) {
   2364             return BAD_VALUE;
   2365         }
   2366         rate = (OMX_U32)(rateFloat * 65536.0f + 0.5f);
   2367     } else {
   2368         if (rateFloat > UINT_MAX) {
   2369             return BAD_VALUE;
   2370         }
   2371         rate = (OMX_U32)(rateFloat);
   2372     }
   2373     OMX_PARAM_U32TYPE config;
   2374     InitOMXParams(&config);
   2375     config.nU32 = rate;
   2376     status_t err = mOMXNode->setConfig(
   2377             (OMX_INDEXTYPE)OMX_IndexConfigOperatingRate,
   2378             &config, sizeof(config));
   2379     if (err != OK) {
   2380         ALOGI("codec does not support config operating rate (err %d)", err);
   2381     }
   2382     return OK;
   2383 }
   2384 
   2385 status_t ACodec::getIntraRefreshPeriod(uint32_t *intraRefreshPeriod) {
   2386     OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params;
   2387     InitOMXParams(&params);
   2388     params.nPortIndex = kPortIndexOutput;
   2389     status_t err = mOMXNode->getConfig(
   2390             (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh, &params, sizeof(params));
   2391     if (err == OK) {
   2392         *intraRefreshPeriod = params.nRefreshPeriod;
   2393         return OK;
   2394     }
   2395 
   2396     // Fallback to query through standard OMX index.
   2397     OMX_VIDEO_PARAM_INTRAREFRESHTYPE refreshParams;
   2398     InitOMXParams(&refreshParams);
   2399     refreshParams.nPortIndex = kPortIndexOutput;
   2400     refreshParams.eRefreshMode = OMX_VIDEO_IntraRefreshCyclic;
   2401     err = mOMXNode->getParameter(
   2402             OMX_IndexParamVideoIntraRefresh, &refreshParams, sizeof(refreshParams));
   2403     if (err != OK || refreshParams.nCirMBs == 0) {
   2404         *intraRefreshPeriod = 0;
   2405         return OK;
   2406     }
   2407 
   2408     // Calculate period based on width and height
   2409     uint32_t width, height;
   2410     OMX_PARAM_PORTDEFINITIONTYPE def;
   2411     InitOMXParams(&def);
   2412     OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
   2413     def.nPortIndex = kPortIndexOutput;
   2414     err = mOMXNode->getParameter(
   2415             OMX_IndexParamPortDefinition, &def, sizeof(def));
   2416     if (err != OK) {
   2417         *intraRefreshPeriod = 0;
   2418         return err;
   2419     }
   2420     width = video_def->nFrameWidth;
   2421     height = video_def->nFrameHeight;
   2422     // Use H.264/AVC MacroBlock size 16x16
   2423     *intraRefreshPeriod = divUp((divUp(width, 16u) * divUp(height, 16u)), refreshParams.nCirMBs);
   2424 
   2425     return OK;
   2426 }
   2427 
   2428 status_t ACodec::setIntraRefreshPeriod(uint32_t intraRefreshPeriod, bool inConfigure) {
   2429     OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params;
   2430     InitOMXParams(&params);
   2431     params.nPortIndex = kPortIndexOutput;
   2432     params.nRefreshPeriod = intraRefreshPeriod;
   2433     status_t err = mOMXNode->setConfig(
   2434             (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh, &params, sizeof(params));
   2435     if (err == OK) {
   2436         return OK;
   2437     }
   2438 
   2439     // Only in configure state, a component could invoke setParameter.
   2440     if (!inConfigure) {
   2441         return INVALID_OPERATION;
   2442     } else {
   2443         ALOGI("[%s] try falling back to Cyclic", mComponentName.c_str());
   2444     }
   2445 
   2446     OMX_VIDEO_PARAM_INTRAREFRESHTYPE refreshParams;
   2447     InitOMXParams(&refreshParams);
   2448     refreshParams.nPortIndex = kPortIndexOutput;
   2449     refreshParams.eRefreshMode = OMX_VIDEO_IntraRefreshCyclic;
   2450 
   2451     if (intraRefreshPeriod == 0) {
   2452         // 0 means disable intra refresh.
   2453         refreshParams.nCirMBs = 0;
   2454     } else {
   2455         // Calculate macroblocks that need to be intra coded base on width and height
   2456         uint32_t width, height;
   2457         OMX_PARAM_PORTDEFINITIONTYPE def;
   2458         InitOMXParams(&def);
   2459         OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
   2460         def.nPortIndex = kPortIndexOutput;
   2461         err = mOMXNode->getParameter(
   2462                 OMX_IndexParamPortDefinition, &def, sizeof(def));
   2463         if (err != OK) {
   2464             return err;
   2465         }
   2466         width = video_def->nFrameWidth;
   2467         height = video_def->nFrameHeight;
   2468         // Use H.264/AVC MacroBlock size 16x16
   2469         refreshParams.nCirMBs = divUp((divUp(width, 16u) * divUp(height, 16u)), intraRefreshPeriod);
   2470     }
   2471 
   2472     err = mOMXNode->setParameter(
   2473             OMX_IndexParamVideoIntraRefresh,
   2474             &refreshParams, sizeof(refreshParams));
   2475     if (err != OK) {
   2476         return err;
   2477     }
   2478 
   2479     return OK;
   2480 }
   2481 
   2482 status_t ACodec::configureTemporalLayers(
   2483         const sp<AMessage> &msg, bool inConfigure, sp<AMessage> &outputFormat) {
   2484     if (!mIsVideo || !mIsEncoder) {
   2485         return INVALID_OPERATION;
   2486     }
   2487 
   2488     AString tsSchema;
   2489     if (!msg->findString("ts-schema", &tsSchema)) {
   2490         return OK;
   2491     }
   2492 
   2493     unsigned int numLayers = 0;
   2494     unsigned int numBLayers = 0;
   2495     int tags;
   2496     char dummy;
   2497     OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE pattern =
   2498         OMX_VIDEO_AndroidTemporalLayeringPatternNone;
   2499     if (sscanf(tsSchema.c_str(), "webrtc.vp8.%u-layer%c", &numLayers, &dummy) == 1
   2500             && numLayers > 0) {
   2501         pattern = OMX_VIDEO_AndroidTemporalLayeringPatternWebRTC;
   2502     } else if ((tags = sscanf(tsSchema.c_str(), "android.generic.%u%c%u%c",
   2503                     &numLayers, &dummy, &numBLayers, &dummy))
   2504             && (tags == 1 || (tags == 3 && dummy == '+'))
   2505             && numLayers > 0 && numLayers < UINT32_MAX - numBLayers) {
   2506         numLayers += numBLayers;
   2507         pattern = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid;
   2508     } else {
   2509         ALOGI("Ignoring unsupported ts-schema [%s]", tsSchema.c_str());
   2510         return BAD_VALUE;
   2511     }
   2512 
   2513     OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE layerParams;
   2514     InitOMXParams(&layerParams);
   2515     layerParams.nPortIndex = kPortIndexOutput;
   2516 
   2517     status_t err = mOMXNode->getParameter(
   2518             (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering,
   2519             &layerParams, sizeof(layerParams));
   2520 
   2521     if (err != OK) {
   2522         return err;
   2523     } else if (!(layerParams.eSupportedPatterns & pattern)) {
   2524         return BAD_VALUE;
   2525     }
   2526 
   2527     numLayers = min(numLayers, layerParams.nLayerCountMax);
   2528     numBLayers = min(numBLayers, layerParams.nBLayerCountMax);
   2529 
   2530     if (!inConfigure) {
   2531         OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE layerConfig;
   2532         InitOMXParams(&layerConfig);
   2533         layerConfig.nPortIndex = kPortIndexOutput;
   2534         layerConfig.ePattern = pattern;
   2535         layerConfig.nPLayerCountActual = numLayers - numBLayers;
   2536         layerConfig.nBLayerCountActual = numBLayers;
   2537         layerConfig.bBitrateRatiosSpecified = OMX_FALSE;
   2538 
   2539         err = mOMXNode->setConfig(
   2540                 (OMX_INDEXTYPE)OMX_IndexConfigAndroidVideoTemporalLayering,
   2541                 &layerConfig, sizeof(layerConfig));
   2542     } else {
   2543         layerParams.ePattern = pattern;
   2544         layerParams.nPLayerCountActual = numLayers - numBLayers;
   2545         layerParams.nBLayerCountActual = numBLayers;
   2546         layerParams.bBitrateRatiosSpecified = OMX_FALSE;
   2547 
   2548         err = mOMXNode->setParameter(
   2549                 (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering,
   2550                 &layerParams, sizeof(layerParams));
   2551     }
   2552 
   2553     AString configSchema;
   2554     if (pattern == OMX_VIDEO_AndroidTemporalLayeringPatternAndroid) {
   2555         configSchema = AStringPrintf("android.generic.%u+%u", numLayers - numBLayers, numBLayers);
   2556     } else if (pattern == OMX_VIDEO_AndroidTemporalLayeringPatternWebRTC) {
   2557         configSchema = AStringPrintf("webrtc.vp8.%u", numLayers);
   2558     }
   2559 
   2560     if (err != OK) {
   2561         ALOGW("Failed to set temporal layers to %s (requested %s)",
   2562                 configSchema.c_str(), tsSchema.c_str());
   2563         return err;
   2564     }
   2565 
   2566     err = mOMXNode->getParameter(
   2567             (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering,
   2568             &layerParams, sizeof(layerParams));
   2569 
   2570     if (err == OK) {
   2571         ALOGD("Temporal layers requested:%s configured:%s got:%s(%u: P=%u, B=%u)",
   2572                 tsSchema.c_str(), configSchema.c_str(),
   2573                 asString(layerParams.ePattern), layerParams.ePattern,
   2574                 layerParams.nPLayerCountActual, layerParams.nBLayerCountActual);
   2575 
   2576         if (outputFormat.get() == mOutputFormat.get()) {
   2577             mOutputFormat = mOutputFormat->dup(); // trigger an output format change event
   2578         }
   2579         // assume we got what we configured
   2580         outputFormat->setString("ts-schema", configSchema);
   2581     }
   2582     return err;
   2583 }
   2584 
   2585 status_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
   2586     OMX_PARAM_PORTDEFINITIONTYPE def;
   2587     InitOMXParams(&def);
   2588     def.nPortIndex = portIndex;
   2589 
   2590     status_t err = mOMXNode->getParameter(
   2591             OMX_IndexParamPortDefinition, &def, sizeof(def));
   2592 
   2593     if (err != OK) {
   2594         return err;
   2595     }
   2596 
   2597     if (def.nBufferSize >= size) {
   2598         return OK;
   2599     }
   2600 
   2601     def.nBufferSize = size;
   2602 
   2603     err = mOMXNode->setParameter(
   2604             OMX_IndexParamPortDefinition, &def, sizeof(def));
   2605 
   2606     if (err != OK) {
   2607         return err;
   2608     }
   2609 
   2610     err = mOMXNode->getParameter(
   2611             OMX_IndexParamPortDefinition, &def, sizeof(def));
   2612 
   2613     if (err != OK) {
   2614         return err;
   2615     }
   2616 
   2617     if (def.nBufferSize < size) {
   2618         ALOGE("failed to set min buffer size to %zu (is still %u)", size, def.nBufferSize);
   2619         return FAILED_TRANSACTION;
   2620     }
   2621 
   2622     return OK;
   2623 }
   2624 
   2625 status_t ACodec::selectAudioPortFormat(
   2626         OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
   2627     OMX_AUDIO_PARAM_PORTFORMATTYPE format;
   2628     InitOMXParams(&format);
   2629 
   2630     format.nPortIndex = portIndex;
   2631     for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
   2632         format.nIndex = index;
   2633         status_t err = mOMXNode->getParameter(
   2634                 OMX_IndexParamAudioPortFormat, &format, sizeof(format));
   2635 
   2636         if (err != OK) {
   2637             return err;
   2638         }
   2639 
   2640         if (format.eEncoding == desiredFormat) {
   2641             break;
   2642         }
   2643 
   2644         if (index == kMaxIndicesToCheck) {
   2645             ALOGW("[%s] stopping checking formats after %u: %s(%x)",
   2646                     mComponentName.c_str(), index,
   2647                     asString(format.eEncoding), format.eEncoding);
   2648             return ERROR_UNSUPPORTED;
   2649         }
   2650     }
   2651 
   2652     return mOMXNode->setParameter(
   2653             OMX_IndexParamAudioPortFormat, &format, sizeof(format));
   2654 }
   2655 
   2656 status_t ACodec::setupAACCodec(
   2657         bool encoder, int32_t numChannels, int32_t sampleRate,
   2658         int32_t bitRate, int32_t aacProfile, bool isADTS, int32_t sbrMode,
   2659         int32_t maxOutputChannelCount, const drcParams_t& drc,
   2660         int32_t pcmLimiterEnable) {
   2661     if (encoder && isADTS) {
   2662         return -EINVAL;
   2663     }
   2664 
   2665     status_t err = setupRawAudioFormat(
   2666             encoder ? kPortIndexInput : kPortIndexOutput,
   2667             sampleRate,
   2668             numChannels);
   2669 
   2670     if (err != OK) {
   2671         return err;
   2672     }
   2673 
   2674     if (encoder) {
   2675         err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
   2676 
   2677         if (err != OK) {
   2678             return err;
   2679         }
   2680 
   2681         OMX_PARAM_PORTDEFINITIONTYPE def;
   2682         InitOMXParams(&def);
   2683         def.nPortIndex = kPortIndexOutput;
   2684 
   2685         err = mOMXNode->getParameter(
   2686                 OMX_IndexParamPortDefinition, &def, sizeof(def));
   2687 
   2688         if (err != OK) {
   2689             return err;
   2690         }
   2691 
   2692         def.format.audio.bFlagErrorConcealment = OMX_TRUE;
   2693         def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
   2694 
   2695         err = mOMXNode->setParameter(
   2696                 OMX_IndexParamPortDefinition, &def, sizeof(def));
   2697 
   2698         if (err != OK) {
   2699             return err;
   2700         }
   2701 
   2702         OMX_AUDIO_PARAM_AACPROFILETYPE profile;
   2703         InitOMXParams(&profile);
   2704         profile.nPortIndex = kPortIndexOutput;
   2705 
   2706         err = mOMXNode->getParameter(
   2707                 OMX_IndexParamAudioAac, &profile, sizeof(profile));
   2708 
   2709         if (err != OK) {
   2710             return err;
   2711         }
   2712 
   2713         profile.nChannels = numChannels;
   2714 
   2715         profile.eChannelMode =
   2716             (numChannels == 1)
   2717                 ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
   2718 
   2719         profile.nSampleRate = sampleRate;
   2720         profile.nBitRate = bitRate;
   2721         profile.nAudioBandWidth = 0;
   2722         profile.nFrameLength = 0;
   2723         profile.nAACtools = OMX_AUDIO_AACToolAll;
   2724         profile.nAACERtools = OMX_AUDIO_AACERNone;
   2725         profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
   2726         profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
   2727         switch (sbrMode) {
   2728         case 0:
   2729             // disable sbr
   2730             profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
   2731             profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
   2732             break;
   2733         case 1:
   2734             // enable single-rate sbr
   2735             profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
   2736             profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
   2737             break;
   2738         case 2:
   2739             // enable dual-rate sbr
   2740             profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
   2741             profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
   2742             break;
   2743         case -1:
   2744             // enable both modes -> the codec will decide which mode should be used
   2745             profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
   2746             profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
   2747             break;
   2748         default:
   2749             // unsupported sbr mode
   2750             return BAD_VALUE;
   2751         }
   2752 
   2753 
   2754         err = mOMXNode->setParameter(
   2755                 OMX_IndexParamAudioAac, &profile, sizeof(profile));
   2756 
   2757         if (err != OK) {
   2758             return err;
   2759         }
   2760 
   2761         return err;
   2762     }
   2763 
   2764     OMX_AUDIO_PARAM_AACPROFILETYPE profile;
   2765     InitOMXParams(&profile);
   2766     profile.nPortIndex = kPortIndexInput;
   2767 
   2768     err = mOMXNode->getParameter(
   2769             OMX_IndexParamAudioAac, &profile, sizeof(profile));
   2770 
   2771     if (err != OK) {
   2772         return err;
   2773     }
   2774 
   2775     profile.nChannels = numChannels;
   2776     profile.nSampleRate = sampleRate;
   2777 
   2778     profile.eAACStreamFormat =
   2779         isADTS
   2780             ? OMX_AUDIO_AACStreamFormatMP4ADTS
   2781             : OMX_AUDIO_AACStreamFormatMP4FF;
   2782 
   2783     OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE presentation;
   2784     InitOMXParams(&presentation);
   2785     presentation.nMaxOutputChannels = maxOutputChannelCount;
   2786     presentation.nDrcCut = drc.drcCut;
   2787     presentation.nDrcBoost = drc.drcBoost;
   2788     presentation.nHeavyCompression = drc.heavyCompression;
   2789     presentation.nTargetReferenceLevel = drc.targetRefLevel;
   2790     presentation.nEncodedTargetLevel = drc.encodedTargetLevel;
   2791     presentation.nPCMLimiterEnable = pcmLimiterEnable;
   2792 
   2793     status_t res = mOMXNode->setParameter(
   2794             OMX_IndexParamAudioAac, &profile, sizeof(profile));
   2795     if (res == OK) {
   2796         // optional parameters, will not cause configuration failure
   2797         mOMXNode->setParameter(
   2798                 (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacPresentation,
   2799                 &presentation, sizeof(presentation));
   2800     } else {
   2801         ALOGW("did not set AudioAndroidAacPresentation due to error %d when setting AudioAac", res);
   2802     }
   2803     mSampleRate = sampleRate;
   2804     return res;
   2805 }
   2806 
   2807 status_t ACodec::setupAC3Codec(
   2808         bool encoder, int32_t numChannels, int32_t sampleRate) {
   2809     status_t err = setupRawAudioFormat(
   2810             encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
   2811 
   2812     if (err != OK) {
   2813         return err;
   2814     }
   2815 
   2816     if (encoder) {
   2817         ALOGW("AC3 encoding is not supported.");
   2818         return INVALID_OPERATION;
   2819     }
   2820 
   2821     OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
   2822     InitOMXParams(&def);
   2823     def.nPortIndex = kPortIndexInput;
   2824 
   2825     err = mOMXNode->getParameter(
   2826             (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3, &def, sizeof(def));
   2827 
   2828     if (err != OK) {
   2829         return err;
   2830     }
   2831 
   2832     def.nChannels = numChannels;
   2833     def.nSampleRate = sampleRate;
   2834 
   2835     return mOMXNode->setParameter(
   2836             (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3, &def, sizeof(def));
   2837 }
   2838 
   2839 status_t ACodec::setupEAC3Codec(
   2840         bool encoder, int32_t numChannels, int32_t sampleRate) {
   2841     status_t err = setupRawAudioFormat(
   2842             encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
   2843 
   2844     if (err != OK) {
   2845         return err;
   2846     }
   2847 
   2848     if (encoder) {
   2849         ALOGW("EAC3 encoding is not supported.");
   2850         return INVALID_OPERATION;
   2851     }
   2852 
   2853     OMX_AUDIO_PARAM_ANDROID_EAC3TYPE def;
   2854     InitOMXParams(&def);
   2855     def.nPortIndex = kPortIndexInput;
   2856 
   2857     err = mOMXNode->getParameter(
   2858             (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3, &def, sizeof(def));
   2859 
   2860     if (err != OK) {
   2861         return err;
   2862     }
   2863 
   2864     def.nChannels = numChannels;
   2865     def.nSampleRate = sampleRate;
   2866 
   2867     return mOMXNode->setParameter(
   2868             (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3, &def, sizeof(def));
   2869 }
   2870 
   2871 static OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
   2872         bool isAMRWB, int32_t bps) {
   2873     if (isAMRWB) {
   2874         if (bps <= 6600) {
   2875             return OMX_AUDIO_AMRBandModeWB0;
   2876         } else if (bps <= 8850) {
   2877             return OMX_AUDIO_AMRBandModeWB1;
   2878         } else if (bps <= 12650) {
   2879             return OMX_AUDIO_AMRBandModeWB2;
   2880         } else if (bps <= 14250) {
   2881             return OMX_AUDIO_AMRBandModeWB3;
   2882         } else if (bps <= 15850) {
   2883             return OMX_AUDIO_AMRBandModeWB4;
   2884         } else if (bps <= 18250) {
   2885             return OMX_AUDIO_AMRBandModeWB5;
   2886         } else if (bps <= 19850) {
   2887             return OMX_AUDIO_AMRBandModeWB6;
   2888         } else if (bps <= 23050) {
   2889             return OMX_AUDIO_AMRBandModeWB7;
   2890         }
   2891 
   2892         // 23850 bps
   2893         return OMX_AUDIO_AMRBandModeWB8;
   2894     } else {  // AMRNB
   2895         if (bps <= 4750) {
   2896             return OMX_AUDIO_AMRBandModeNB0;
   2897         } else if (bps <= 5150) {
   2898             return OMX_AUDIO_AMRBandModeNB1;
   2899         } else if (bps <= 5900) {
   2900             return OMX_AUDIO_AMRBandModeNB2;
   2901         } else if (bps <= 6700) {
   2902             return OMX_AUDIO_AMRBandModeNB3;
   2903         } else if (bps <= 7400) {
   2904             return OMX_AUDIO_AMRBandModeNB4;
   2905         } else if (bps <= 7950) {
   2906             return OMX_AUDIO_AMRBandModeNB5;
   2907         } else if (bps <= 10200) {
   2908             return OMX_AUDIO_AMRBandModeNB6;
   2909         }
   2910 
   2911         // 12200 bps
   2912         return OMX_AUDIO_AMRBandModeNB7;
   2913     }
   2914 }
   2915 
   2916 status_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
   2917     OMX_AUDIO_PARAM_AMRTYPE def;
   2918     InitOMXParams(&def);
   2919     def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
   2920 
   2921     status_t err = mOMXNode->getParameter(
   2922             OMX_IndexParamAudioAmr, &def, sizeof(def));
   2923 
   2924     if (err != OK) {
   2925         return err;
   2926     }
   2927 
   2928     def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
   2929     def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
   2930 
   2931     err = mOMXNode->setParameter(
   2932             OMX_IndexParamAudioAmr, &def, sizeof(def));
   2933 
   2934     if (err != OK) {
   2935         return err;
   2936     }
   2937 
   2938     return setupRawAudioFormat(
   2939             encoder ? kPortIndexInput : kPortIndexOutput,
   2940             isWAMR ? 16000 : 8000 /* sampleRate */,
   2941             1 /* numChannels */);
   2942 }
   2943 
   2944 status_t ACodec::setupG711Codec(bool encoder, int32_t sampleRate, int32_t numChannels) {
   2945     if (encoder) {
   2946         return INVALID_OPERATION;
   2947     }
   2948 
   2949     return setupRawAudioFormat(
   2950             kPortIndexInput, sampleRate, numChannels);
   2951 }
   2952 
   2953 status_t ACodec::setupFlacCodec(
   2954         bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
   2955 
   2956     if (encoder) {
   2957         OMX_AUDIO_PARAM_FLACTYPE def;
   2958         InitOMXParams(&def);
   2959         def.nPortIndex = kPortIndexOutput;
   2960 
   2961         // configure compression level
   2962         status_t err = mOMXNode->getParameter(OMX_IndexParamAudioFlac, &def, sizeof(def));
   2963         if (err != OK) {
   2964             ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
   2965             return err;
   2966         }
   2967         def.nCompressionLevel = compressionLevel;
   2968         err = mOMXNode->setParameter(OMX_IndexParamAudioFlac, &def, sizeof(def));
   2969         if (err != OK) {
   2970             ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
   2971             return err;
   2972         }
   2973     }
   2974 
   2975     return setupRawAudioFormat(
   2976             encoder ? kPortIndexInput : kPortIndexOutput,
   2977             sampleRate,
   2978             numChannels);
   2979 }
   2980 
   2981 status_t ACodec::setupRawAudioFormat(
   2982         OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels, AudioEncoding encoding) {
   2983     OMX_PARAM_PORTDEFINITIONTYPE def;
   2984     InitOMXParams(&def);
   2985     def.nPortIndex = portIndex;
   2986 
   2987     status_t err = mOMXNode->getParameter(
   2988             OMX_IndexParamPortDefinition, &def, sizeof(def));
   2989 
   2990     if (err != OK) {
   2991         return err;
   2992     }
   2993 
   2994     def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
   2995 
   2996     err = mOMXNode->setParameter(
   2997             OMX_IndexParamPortDefinition, &def, sizeof(def));
   2998 
   2999     if (err != OK) {
   3000         return err;
   3001     }
   3002 
   3003     OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
   3004     InitOMXParams(&pcmParams);
   3005     pcmParams.nPortIndex = portIndex;
   3006 
   3007     err = mOMXNode->getParameter(
   3008             OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
   3009 
   3010     if (err != OK) {
   3011         return err;
   3012     }
   3013 
   3014     pcmParams.nChannels = numChannels;
   3015     switch (encoding) {
   3016         case kAudioEncodingPcm8bit:
   3017             pcmParams.eNumData = OMX_NumericalDataUnsigned;
   3018             pcmParams.nBitPerSample = 8;
   3019             break;
   3020         case kAudioEncodingPcmFloat:
   3021             pcmParams.eNumData = OMX_NumericalDataFloat;
   3022             pcmParams.nBitPerSample = 32;
   3023             break;
   3024         case kAudioEncodingPcm16bit:
   3025             pcmParams.eNumData = OMX_NumericalDataSigned;
   3026             pcmParams.nBitPerSample = 16;
   3027             break;
   3028         default:
   3029             return BAD_VALUE;
   3030     }
   3031     pcmParams.bInterleaved = OMX_TRUE;
   3032     pcmParams.nSamplingRate = sampleRate;
   3033     pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
   3034 
   3035     if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
   3036         return OMX_ErrorNone;
   3037     }
   3038 
   3039     err = mOMXNode->setParameter(
   3040             OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
   3041     // if we could not set up raw format to non-16-bit, try with 16-bit
   3042     // NOTE: we will also verify this via readback, in case codec ignores these fields
   3043     if (err != OK && encoding != kAudioEncodingPcm16bit) {
   3044         pcmParams.eNumData = OMX_NumericalDataSigned;
   3045         pcmParams.nBitPerSample = 16;
   3046         err = mOMXNode->setParameter(
   3047                 OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
   3048     }
   3049     return err;
   3050 }
   3051 
   3052 status_t ACodec::configureTunneledVideoPlayback(
   3053         int32_t audioHwSync, const sp<ANativeWindow> &nativeWindow) {
   3054     native_handle_t* sidebandHandle;
   3055 
   3056     status_t err = mOMXNode->configureVideoTunnelMode(
   3057             kPortIndexOutput, OMX_TRUE, audioHwSync, &sidebandHandle);
   3058     if (err != OK) {
   3059         ALOGE("configureVideoTunnelMode failed! (err %d).", err);
   3060         return err;
   3061     }
   3062 
   3063     err = native_window_set_sideband_stream(nativeWindow.get(), sidebandHandle);
   3064     if (err != OK) {
   3065         ALOGE("native_window_set_sideband_stream(%p) failed! (err %d).",
   3066                 sidebandHandle, err);
   3067         return err;
   3068     }
   3069 
   3070     return OK;
   3071 }
   3072 
   3073 status_t ACodec::setVideoPortFormatType(
   3074         OMX_U32 portIndex,
   3075         OMX_VIDEO_CODINGTYPE compressionFormat,
   3076         OMX_COLOR_FORMATTYPE colorFormat,
   3077         bool usingNativeBuffers) {
   3078     OMX_VIDEO_PARAM_PORTFORMATTYPE format;
   3079     InitOMXParams(&format);
   3080     format.nPortIndex = portIndex;
   3081     format.nIndex = 0;
   3082     bool found = false;
   3083 
   3084     for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
   3085         format.nIndex = index;
   3086         status_t err = mOMXNode->getParameter(
   3087                 OMX_IndexParamVideoPortFormat,
   3088                 &format, sizeof(format));
   3089 
   3090         if (err != OK) {
   3091             return err;
   3092         }
   3093 
   3094         // substitute back flexible color format to codec supported format
   3095         OMX_U32 flexibleEquivalent;
   3096         if (compressionFormat == OMX_VIDEO_CodingUnused
   3097                 && IsFlexibleColorFormat(
   3098                         mOMXNode, format.eColorFormat, usingNativeBuffers, &flexibleEquivalent)
   3099                 && colorFormat == flexibleEquivalent) {
   3100             ALOGI("[%s] using color format %#x in place of %#x",
   3101                     mComponentName.c_str(), format.eColorFormat, colorFormat);
   3102             colorFormat = format.eColorFormat;
   3103         }
   3104 
   3105         // The following assertion is violated by TI's video decoder.
   3106         // CHECK_EQ(format.nIndex, index);
   3107 
   3108         if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
   3109             if (portIndex == kPortIndexInput
   3110                     && colorFormat == format.eColorFormat) {
   3111                 // eCompressionFormat does not seem right.
   3112                 found = true;
   3113                 break;
   3114             }
   3115             if (portIndex == kPortIndexOutput
   3116                     && compressionFormat == format.eCompressionFormat) {
   3117                 // eColorFormat does not seem right.
   3118                 found = true;
   3119                 break;
   3120             }
   3121         }
   3122 
   3123         if (format.eCompressionFormat == compressionFormat
   3124             && format.eColorFormat == colorFormat) {
   3125             found = true;
   3126             break;
   3127         }
   3128 
   3129         if (index == kMaxIndicesToCheck) {
   3130             ALOGW("[%s] stopping checking formats after %u: %s(%x)/%s(%x)",
   3131                     mComponentName.c_str(), index,
   3132                     asString(format.eCompressionFormat), format.eCompressionFormat,
   3133                     asString(format.eColorFormat), format.eColorFormat);
   3134         }
   3135     }
   3136 
   3137     if (!found) {
   3138         return UNKNOWN_ERROR;
   3139     }
   3140 
   3141     status_t err = mOMXNode->setParameter(
   3142             OMX_IndexParamVideoPortFormat, &format, sizeof(format));
   3143 
   3144     return err;
   3145 }
   3146 
   3147 // Set optimal output format. OMX component lists output formats in the order
   3148 // of preference, but this got more complicated since the introduction of flexible
   3149 // YUV formats. We support a legacy behavior for applications that do not use
   3150 // surface output, do not specify an output format, but expect a "usable" standard
   3151 // OMX format. SW readable and standard formats must be flex-YUV.
   3152 //
   3153 // Suggested preference order:
   3154 // - optimal format for texture rendering (mediaplayer behavior)
   3155 // - optimal SW readable & texture renderable format (flex-YUV support)
   3156 // - optimal SW readable non-renderable format (flex-YUV bytebuffer support)
   3157 // - legacy "usable" standard formats
   3158 //
   3159 // For legacy support, we prefer a standard format, but will settle for a SW readable
   3160 // flex-YUV format.
   3161 status_t ACodec::setSupportedOutputFormat(bool getLegacyFlexibleFormat) {
   3162     OMX_VIDEO_PARAM_PORTFORMATTYPE format, legacyFormat;
   3163     InitOMXParams(&format);
   3164     format.nPortIndex = kPortIndexOutput;
   3165 
   3166     InitOMXParams(&legacyFormat);
   3167     // this field will change when we find a suitable legacy format
   3168     legacyFormat.eColorFormat = OMX_COLOR_FormatUnused;
   3169 
   3170     for (OMX_U32 index = 0; ; ++index) {
   3171         format.nIndex = index;
   3172         status_t err = mOMXNode->getParameter(
   3173                 OMX_IndexParamVideoPortFormat, &format, sizeof(format));
   3174         if (err != OK) {
   3175             // no more formats, pick legacy format if found
   3176             if (legacyFormat.eColorFormat != OMX_COLOR_FormatUnused) {
   3177                  memcpy(&format, &legacyFormat, sizeof(format));
   3178                  break;
   3179             }
   3180             return err;
   3181         }
   3182         if (format.eCompressionFormat != OMX_VIDEO_CodingUnused) {
   3183             return OMX_ErrorBadParameter;
   3184         }
   3185         if (!getLegacyFlexibleFormat) {
   3186             break;
   3187         }
   3188         // standard formats that were exposed to users before
   3189         if (format.eColorFormat == OMX_COLOR_FormatYUV420Planar
   3190                 || format.eColorFormat == OMX_COLOR_FormatYUV420PackedPlanar
   3191                 || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
   3192                 || format.eColorFormat == OMX_COLOR_FormatYUV420PackedSemiPlanar
   3193                 || format.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) {
   3194             break;
   3195         }
   3196         // find best legacy non-standard format
   3197         OMX_U32 flexibleEquivalent;
   3198         if (legacyFormat.eColorFormat == OMX_COLOR_FormatUnused
   3199                 && IsFlexibleColorFormat(
   3200                         mOMXNode, format.eColorFormat, false /* usingNativeBuffers */,
   3201                         &flexibleEquivalent)
   3202                 && flexibleEquivalent == OMX_COLOR_FormatYUV420Flexible) {
   3203             memcpy(&legacyFormat, &format, sizeof(format));
   3204         }
   3205     }
   3206     return mOMXNode->setParameter(
   3207             OMX_IndexParamVideoPortFormat, &format, sizeof(format));
   3208 }
   3209 
   3210 static const struct VideoCodingMapEntry {
   3211     const char *mMime;
   3212     OMX_VIDEO_CODINGTYPE mVideoCodingType;
   3213 } kVideoCodingMapEntry[] = {
   3214     { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
   3215     { MEDIA_MIMETYPE_VIDEO_HEVC, OMX_VIDEO_CodingHEVC },
   3216     { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
   3217     { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
   3218     { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
   3219     { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
   3220     { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
   3221     { MEDIA_MIMETYPE_VIDEO_DOLBY_VISION, OMX_VIDEO_CodingDolbyVision },
   3222 };
   3223 
   3224 static status_t GetVideoCodingTypeFromMime(
   3225         const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
   3226     for (size_t i = 0;
   3227          i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
   3228          ++i) {
   3229         if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
   3230             *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
   3231             return OK;
   3232         }
   3233     }
   3234 
   3235     *codingType = OMX_VIDEO_CodingUnused;
   3236 
   3237     return ERROR_UNSUPPORTED;
   3238 }
   3239 
   3240 static status_t GetMimeTypeForVideoCoding(
   3241         OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
   3242     for (size_t i = 0;
   3243          i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
   3244          ++i) {
   3245         if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
   3246             *mime = kVideoCodingMapEntry[i].mMime;
   3247             return OK;
   3248         }
   3249     }
   3250 
   3251     mime->clear();
   3252 
   3253     return ERROR_UNSUPPORTED;
   3254 }
   3255 
   3256 status_t ACodec::setPortBufferNum(OMX_U32 portIndex, int bufferNum) {
   3257     OMX_PARAM_PORTDEFINITIONTYPE def;
   3258     InitOMXParams(&def);
   3259     def.nPortIndex = portIndex;
   3260     status_t err;
   3261     ALOGD("Setting [%s] %s port buffer number: %d", mComponentName.c_str(),
   3262             portIndex == kPortIndexInput ? "input" : "output", bufferNum);
   3263     err = mOMXNode->getParameter(
   3264         OMX_IndexParamPortDefinition, &def, sizeof(def));
   3265     if (err != OK) {
   3266         return err;
   3267     }
   3268     def.nBufferCountActual = bufferNum;
   3269     err = mOMXNode->setParameter(
   3270         OMX_IndexParamPortDefinition, &def, sizeof(def));
   3271     if (err != OK) {
   3272         // Component could reject this request.
   3273         ALOGW("Fail to set [%s] %s port buffer number: %d", mComponentName.c_str(),
   3274             portIndex == kPortIndexInput ? "input" : "output", bufferNum);
   3275     }
   3276     return OK;
   3277 }
   3278 
   3279 status_t ACodec::setupVideoDecoder(
   3280         const char *mime, const sp<AMessage> &msg, bool haveNativeWindow,
   3281         bool usingSwRenderer, sp<AMessage> &outputFormat) {
   3282     int32_t width, height;
   3283     if (!msg->findInt32("width", &width)
   3284             || !msg->findInt32("height", &height)) {
   3285         return INVALID_OPERATION;
   3286     }
   3287 
   3288     OMX_VIDEO_CODINGTYPE compressionFormat;
   3289     status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
   3290 
   3291     if (err != OK) {
   3292         return err;
   3293     }
   3294 
   3295     if (compressionFormat == OMX_VIDEO_CodingVP9) {
   3296         OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
   3297         InitOMXParams(&params);
   3298         params.nPortIndex = kPortIndexInput;
   3299         // Check if VP9 decoder advertises supported profiles.
   3300         params.nProfileIndex = 0;
   3301         status_t err = mOMXNode->getParameter(
   3302                 OMX_IndexParamVideoProfileLevelQuerySupported,
   3303                 &params, sizeof(params));
   3304         mIsLegacyVP9Decoder = err != OK;
   3305     }
   3306 
   3307     err = setVideoPortFormatType(
   3308             kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
   3309 
   3310     if (err != OK) {
   3311         return err;
   3312     }
   3313 
   3314     int32_t tmp;
   3315     if (msg->findInt32("color-format", &tmp)) {
   3316         OMX_COLOR_FORMATTYPE colorFormat =
   3317             static_cast<OMX_COLOR_FORMATTYPE>(tmp);
   3318         err = setVideoPortFormatType(
   3319                 kPortIndexOutput, OMX_VIDEO_CodingUnused, colorFormat, haveNativeWindow);
   3320         if (err != OK) {
   3321             ALOGW("[%s] does not support color format %d",
   3322                   mComponentName.c_str(), colorFormat);
   3323             err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
   3324         }
   3325     } else {
   3326         err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
   3327     }
   3328 
   3329     if (err != OK) {
   3330         return err;
   3331     }
   3332 
   3333     // Set the component input buffer number to be |tmp|. If succeed,
   3334     // component will set input port buffer number to be |tmp|. If fail,
   3335     // component will keep the same buffer number as before.
   3336     if (msg->findInt32("android._num-input-buffers", &tmp)) {
   3337         err = setPortBufferNum(kPortIndexInput, tmp);
   3338         if (err != OK)
   3339             return err;
   3340     }
   3341 
   3342     // Set the component output buffer number to be |tmp|. If succeed,
   3343     // component will set output port buffer number to be |tmp|. If fail,
   3344     // component will keep the same buffer number as before.
   3345     if (msg->findInt32("android._num-output-buffers", &tmp)) {
   3346         err = setPortBufferNum(kPortIndexOutput, tmp);
   3347         if (err != OK)
   3348             return err;
   3349     }
   3350 
   3351     int32_t frameRateInt;
   3352     float frameRateFloat;
   3353     if (!msg->findFloat("frame-rate", &frameRateFloat)) {
   3354         if (!msg->findInt32("frame-rate", &frameRateInt)) {
   3355             frameRateInt = -1;
   3356         }
   3357         frameRateFloat = (float)frameRateInt;
   3358     }
   3359 
   3360     err = setVideoFormatOnPort(
   3361             kPortIndexInput, width, height, compressionFormat, frameRateFloat);
   3362 
   3363     if (err != OK) {
   3364         return err;
   3365     }
   3366 
   3367     err = setVideoFormatOnPort(
   3368             kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
   3369 
   3370     if (err != OK) {
   3371         return err;
   3372     }
   3373 
   3374     err = setColorAspectsForVideoDecoder(
   3375             width, height, haveNativeWindow | usingSwRenderer, msg, outputFormat);
   3376     if (err == ERROR_UNSUPPORTED) { // support is optional
   3377         err = OK;
   3378     }
   3379 
   3380     if (err != OK) {
   3381         return err;
   3382     }
   3383 
   3384     err = setHDRStaticInfoForVideoCodec(kPortIndexOutput, msg, outputFormat);
   3385     if (err == ERROR_UNSUPPORTED) { // support is optional
   3386         err = OK;
   3387     }
   3388     return err;
   3389 }
   3390 
   3391 status_t ACodec::initDescribeColorAspectsIndex() {
   3392     status_t err = mOMXNode->getExtensionIndex(
   3393             "OMX.google.android.index.describeColorAspects", &mDescribeColorAspectsIndex);
   3394     if (err != OK) {
   3395         mDescribeColorAspectsIndex = (OMX_INDEXTYPE)0;
   3396     }
   3397     return err;
   3398 }
   3399 
   3400 status_t ACodec::setCodecColorAspects(DescribeColorAspectsParams &params, bool verify) {
   3401     status_t err = ERROR_UNSUPPORTED;
   3402     if (mDescribeColorAspectsIndex) {
   3403         err = mOMXNode->setConfig(mDescribeColorAspectsIndex, &params, sizeof(params));
   3404     }
   3405     ALOGV("[%s] setting color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) err=%d(%s)",
   3406             mComponentName.c_str(),
   3407             params.sAspects.mRange, asString(params.sAspects.mRange),
   3408             params.sAspects.mPrimaries, asString(params.sAspects.mPrimaries),
   3409             params.sAspects.mMatrixCoeffs, asString(params.sAspects.mMatrixCoeffs),
   3410             params.sAspects.mTransfer, asString(params.sAspects.mTransfer),
   3411             err, asString(err));
   3412 
   3413     if (verify && err == OK) {
   3414         err = getCodecColorAspects(params);
   3415     }
   3416 
   3417     ALOGW_IF(err == ERROR_UNSUPPORTED && mDescribeColorAspectsIndex,
   3418             "[%s] setting color aspects failed even though codec advertises support",
   3419             mComponentName.c_str());
   3420     return err;
   3421 }
   3422 
   3423 status_t ACodec::setColorAspectsForVideoDecoder(
   3424         int32_t width, int32_t height, bool usingNativeWindow,
   3425         const sp<AMessage> &configFormat, sp<AMessage> &outputFormat) {
   3426     DescribeColorAspectsParams params;
   3427     InitOMXParams(&params);
   3428     params.nPortIndex = kPortIndexOutput;
   3429 
   3430     getColorAspectsFromFormat(configFormat, params.sAspects);
   3431     if (usingNativeWindow) {
   3432         setDefaultCodecColorAspectsIfNeeded(params.sAspects, width, height);
   3433         // The default aspects will be set back to the output format during the
   3434         // getFormat phase of configure(). Set non-Unspecified values back into the
   3435         // format, in case component does not support this enumeration.
   3436         setColorAspectsIntoFormat(params.sAspects, outputFormat);
   3437     }
   3438 
   3439     (void)initDescribeColorAspectsIndex();
   3440 
   3441     // communicate color aspects to codec
   3442     return setCodecColorAspects(params);
   3443 }
   3444 
   3445 status_t ACodec::getCodecColorAspects(DescribeColorAspectsParams &params) {
   3446     status_t err = ERROR_UNSUPPORTED;
   3447     if (mDescribeColorAspectsIndex) {
   3448         err = mOMXNode->getConfig(mDescribeColorAspectsIndex, &params, sizeof(params));
   3449     }
   3450     ALOGV("[%s] got color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) err=%d(%s)",
   3451             mComponentName.c_str(),
   3452             params.sAspects.mRange, asString(params.sAspects.mRange),
   3453             params.sAspects.mPrimaries, asString(params.sAspects.mPrimaries),
   3454             params.sAspects.mMatrixCoeffs, asString(params.sAspects.mMatrixCoeffs),
   3455             params.sAspects.mTransfer, asString(params.sAspects.mTransfer),
   3456             err, asString(err));
   3457     if (params.bRequestingDataSpace) {
   3458         ALOGV("for dataspace %#x", params.nDataSpace);
   3459     }
   3460     if (err == ERROR_UNSUPPORTED && mDescribeColorAspectsIndex
   3461             && !params.bRequestingDataSpace && !params.bDataSpaceChanged) {
   3462         ALOGW("[%s] getting color aspects failed even though codec advertises support",
   3463                 mComponentName.c_str());
   3464     }
   3465     return err;
   3466 }
   3467 
   3468 status_t ACodec::getInputColorAspectsForVideoEncoder(sp<AMessage> &format) {
   3469     DescribeColorAspectsParams params;
   3470     InitOMXParams(&params);
   3471     params.nPortIndex = kPortIndexInput;
   3472     status_t err = getCodecColorAspects(params);
   3473     if (err == OK) {
   3474         // we only set encoder input aspects if codec supports them
   3475         setColorAspectsIntoFormat(params.sAspects, format, true /* force */);
   3476     }
   3477     return err;
   3478 }
   3479 
   3480 status_t ACodec::getDataSpace(
   3481         DescribeColorAspectsParams &params, android_dataspace *dataSpace /* nonnull */,
   3482         bool tryCodec) {
   3483     status_t err = OK;
   3484     if (tryCodec) {
   3485         // request dataspace guidance from codec.
   3486         params.bRequestingDataSpace = OMX_TRUE;
   3487         err = getCodecColorAspects(params);
   3488         params.bRequestingDataSpace = OMX_FALSE;
   3489         if (err == OK && params.nDataSpace != HAL_DATASPACE_UNKNOWN) {
   3490             *dataSpace = (android_dataspace)params.nDataSpace;
   3491             return err;
   3492         } else if (err == ERROR_UNSUPPORTED) {
   3493             // ignore not-implemented error for dataspace requests
   3494             err = OK;
   3495         }
   3496     }
   3497 
   3498     // this returns legacy versions if available
   3499     *dataSpace = getDataSpaceForColorAspects(params.sAspects, true /* mayexpand */);
   3500     ALOGV("[%s] using color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) "
   3501           "and dataspace %#x",
   3502             mComponentName.c_str(),
   3503             params.sAspects.mRange, asString(params.sAspects.mRange),
   3504             params.sAspects.mPrimaries, asString(params.sAspects.mPrimaries),
   3505             params.sAspects.mMatrixCoeffs, asString(params.sAspects.mMatrixCoeffs),
   3506             params.sAspects.mTransfer, asString(params.sAspects.mTransfer),
   3507             *dataSpace);
   3508     return err;
   3509 }
   3510 
   3511 
   3512 status_t ACodec::getColorAspectsAndDataSpaceForVideoDecoder(
   3513         int32_t width, int32_t height, const sp<AMessage> &configFormat, sp<AMessage> &outputFormat,
   3514         android_dataspace *dataSpace) {
   3515     DescribeColorAspectsParams params;
   3516     InitOMXParams(&params);
   3517     params.nPortIndex = kPortIndexOutput;
   3518 
   3519     // reset default format and get resulting format
   3520     getColorAspectsFromFormat(configFormat, params.sAspects);
   3521     if (dataSpace != NULL) {
   3522         setDefaultCodecColorAspectsIfNeeded(params.sAspects, width, height);
   3523     }
   3524     status_t err = setCodecColorAspects(params, true /* readBack */);
   3525 
   3526     // we always set specified aspects for decoders
   3527     setColorAspectsIntoFormat(params.sAspects, outputFormat);
   3528 
   3529     if (dataSpace != NULL) {
   3530         status_t res = getDataSpace(params, dataSpace, err == OK /* tryCodec */);
   3531         if (err == OK) {
   3532             err = res;
   3533         }
   3534     }
   3535 
   3536     return err;
   3537 }
   3538 
   3539 // initial video encoder setup for bytebuffer mode
   3540 status_t ACodec::setColorAspectsForVideoEncoder(
   3541         const sp<AMessage> &configFormat, sp<AMessage> &outputFormat, sp<AMessage> &inputFormat) {
   3542     // copy config to output format as this is not exposed via getFormat
   3543     copyColorConfig(configFormat, outputFormat);
   3544 
   3545     DescribeColorAspectsParams params;
   3546     InitOMXParams(&params);
   3547     params.nPortIndex = kPortIndexInput;
   3548     getColorAspectsFromFormat(configFormat, params.sAspects);
   3549 
   3550     (void)initDescribeColorAspectsIndex();
   3551 
   3552     int32_t usingRecorder;
   3553     if (configFormat->findInt32("android._using-recorder", &usingRecorder) && usingRecorder) {
   3554         android_dataspace dataSpace = HAL_DATASPACE_BT709;
   3555         int32_t width, height;
   3556         if (configFormat->findInt32("width", &width)
   3557                 && configFormat->findInt32("height", &height)) {
   3558             setDefaultCodecColorAspectsIfNeeded(params.sAspects, width, height);
   3559             status_t err = getDataSpace(
   3560                     params, &dataSpace, mDescribeColorAspectsIndex /* tryCodec */);
   3561             if (err != OK) {
   3562                 return err;
   3563             }
   3564             setColorAspectsIntoFormat(params.sAspects, outputFormat);
   3565         }
   3566         inputFormat->setInt32("android._dataspace", (int32_t)dataSpace);
   3567     }
   3568 
   3569     // communicate color aspects to codec, but do not allow change of the platform aspects
   3570     ColorAspects origAspects = params.sAspects;
   3571     for (int triesLeft = 2; --triesLeft >= 0; ) {
   3572         status_t err = setCodecColorAspects(params, true /* readBack */);
   3573         if (err != OK
   3574                 || !ColorUtils::checkIfAspectsChangedAndUnspecifyThem(
   3575                         params.sAspects, origAspects, true /* usePlatformAspects */)) {
   3576             return err;
   3577         }
   3578         ALOGW_IF(triesLeft == 0, "[%s] Codec repeatedly changed requested ColorAspects.",
   3579                 mComponentName.c_str());
   3580     }
   3581     return OK;
   3582 }
   3583 
   3584 status_t ACodec::setHDRStaticInfoForVideoCodec(
   3585         OMX_U32 portIndex, const sp<AMessage> &configFormat, sp<AMessage> &outputFormat) {
   3586     CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
   3587 
   3588     DescribeHDRStaticInfoParams params;
   3589     InitOMXParams(&params);
   3590     params.nPortIndex = portIndex;
   3591 
   3592     HDRStaticInfo *info = &params.sInfo;
   3593     if (getHDRStaticInfoFromFormat(configFormat, info)) {
   3594         setHDRStaticInfoIntoFormat(params.sInfo, outputFormat);
   3595     }
   3596 
   3597     (void)initDescribeHDRStaticInfoIndex();
   3598 
   3599     // communicate HDR static Info to codec
   3600     return setHDRStaticInfo(params);
   3601 }
   3602 
   3603 // subsequent initial video encoder setup for surface mode
   3604 status_t ACodec::setInitialColorAspectsForVideoEncoderSurfaceAndGetDataSpace(
   3605         android_dataspace *dataSpace /* nonnull */) {
   3606     DescribeColorAspectsParams params;
   3607     InitOMXParams(&params);
   3608     params.nPortIndex = kPortIndexInput;
   3609     ColorAspects &aspects = params.sAspects;
   3610 
   3611     // reset default format and store resulting format into both input and output formats
   3612     getColorAspectsFromFormat(mConfigFormat, aspects);
   3613     int32_t width, height;
   3614     if (mInputFormat->findInt32("width", &width) && mInputFormat->findInt32("height", &height)) {
   3615         setDefaultCodecColorAspectsIfNeeded(aspects, width, height);
   3616     }
   3617     setColorAspectsIntoFormat(aspects, mInputFormat);
   3618     setColorAspectsIntoFormat(aspects, mOutputFormat);
   3619 
   3620     // communicate color aspects to codec, but do not allow any change
   3621     ColorAspects origAspects = aspects;
   3622     status_t err = OK;
   3623     for (int triesLeft = 2; mDescribeColorAspectsIndex && --triesLeft >= 0; ) {
   3624         status_t err = setCodecColorAspects(params, true /* readBack */);
   3625         if (err != OK || !ColorUtils::checkIfAspectsChangedAndUnspecifyThem(aspects, origAspects)) {
   3626             break;
   3627         }
   3628         ALOGW_IF(triesLeft == 0, "[%s] Codec repeatedly changed requested ColorAspects.",
   3629                 mComponentName.c_str());
   3630     }
   3631 
   3632     *dataSpace = HAL_DATASPACE_BT709;
   3633     aspects = origAspects; // restore desired color aspects
   3634     status_t res = getDataSpace(
   3635             params, dataSpace, err == OK && mDescribeColorAspectsIndex /* tryCodec */);
   3636     if (err == OK) {
   3637         err = res;
   3638     }
   3639     mInputFormat->setInt32("android._dataspace", (int32_t)*dataSpace);
   3640     mInputFormat->setBuffer(
   3641             "android._color-aspects", ABuffer::CreateAsCopy(&aspects, sizeof(aspects)));
   3642 
   3643     // update input format with codec supported color aspects (basically set unsupported
   3644     // aspects to Unspecified)
   3645     if (err == OK) {
   3646         (void)getInputColorAspectsForVideoEncoder(mInputFormat);
   3647     }
   3648 
   3649     ALOGV("set default color aspects, updated input format to %s, output format to %s",
   3650             mInputFormat->debugString(4).c_str(), mOutputFormat->debugString(4).c_str());
   3651 
   3652     return err;
   3653 }
   3654 
   3655 status_t ACodec::getHDRStaticInfoForVideoCodec(OMX_U32 portIndex, sp<AMessage> &format) {
   3656     CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
   3657     DescribeHDRStaticInfoParams params;
   3658     InitOMXParams(&params);
   3659     params.nPortIndex = portIndex;
   3660 
   3661     status_t err = getHDRStaticInfo(params);
   3662     if (err == OK) {
   3663         // we only set decodec output HDRStaticInfo if codec supports them
   3664         setHDRStaticInfoIntoFormat(params.sInfo, format);
   3665     }
   3666     return err;
   3667 }
   3668 
   3669 status_t ACodec::initDescribeHDRStaticInfoIndex() {
   3670     status_t err = mOMXNode->getExtensionIndex(
   3671             "OMX.google.android.index.describeHDRStaticInfo", &mDescribeHDRStaticInfoIndex);
   3672     if (err != OK) {
   3673         mDescribeHDRStaticInfoIndex = (OMX_INDEXTYPE)0;
   3674     }
   3675     return err;
   3676 }
   3677 
   3678 status_t ACodec::setHDRStaticInfo(const DescribeHDRStaticInfoParams &params) {
   3679     status_t err = ERROR_UNSUPPORTED;
   3680     if (mDescribeHDRStaticInfoIndex) {
   3681         err = mOMXNode->setConfig(mDescribeHDRStaticInfoIndex, &params, sizeof(params));
   3682     }
   3683 
   3684     const HDRStaticInfo *info = &params.sInfo;
   3685     ALOGV("[%s] setting  HDRStaticInfo (R: %u %u, G: %u %u, B: %u, %u, W: %u, %u, "
   3686             "MaxDispL: %u, MinDispL: %u, MaxContentL: %u, MaxFrameAvgL: %u)",
   3687             mComponentName.c_str(),
   3688             info->sType1.mR.x, info->sType1.mR.y, info->sType1.mG.x, info->sType1.mG.y,
   3689             info->sType1.mB.x, info->sType1.mB.y, info->sType1.mW.x, info->sType1.mW.y,
   3690             info->sType1.mMaxDisplayLuminance, info->sType1.mMinDisplayLuminance,
   3691             info->sType1.mMaxContentLightLevel, info->sType1.mMaxFrameAverageLightLevel);
   3692 
   3693     ALOGW_IF(err == ERROR_UNSUPPORTED && mDescribeHDRStaticInfoIndex,
   3694             "[%s] setting HDRStaticInfo failed even though codec advertises support",
   3695             mComponentName.c_str());
   3696     return err;
   3697 }
   3698 
   3699 status_t ACodec::getHDRStaticInfo(DescribeHDRStaticInfoParams &params) {
   3700     status_t err = ERROR_UNSUPPORTED;
   3701     if (mDescribeHDRStaticInfoIndex) {
   3702         err = mOMXNode->getConfig(mDescribeHDRStaticInfoIndex, &params, sizeof(params));
   3703     }
   3704 
   3705     ALOGW_IF(err == ERROR_UNSUPPORTED && mDescribeHDRStaticInfoIndex,
   3706             "[%s] getting HDRStaticInfo failed even though codec advertises support",
   3707             mComponentName.c_str());
   3708     return err;
   3709 }
   3710 
   3711 status_t ACodec::setupVideoEncoder(
   3712         const char *mime, const sp<AMessage> &msg,
   3713         sp<AMessage> &outputFormat, sp<AMessage> &inputFormat) {
   3714     int32_t tmp;
   3715     if (!msg->findInt32("color-format", &tmp)) {
   3716         return INVALID_OPERATION;
   3717     }
   3718 
   3719     OMX_COLOR_FORMATTYPE colorFormat =
   3720         static_cast<OMX_COLOR_FORMATTYPE>(tmp);
   3721 
   3722     status_t err = setVideoPortFormatType(
   3723             kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
   3724 
   3725     if (err != OK) {
   3726         ALOGE("[%s] does not support color format %d",
   3727               mComponentName.c_str(), colorFormat);
   3728 
   3729         return err;
   3730     }
   3731 
   3732     /* Input port configuration */
   3733 
   3734     OMX_PARAM_PORTDEFINITIONTYPE def;
   3735     InitOMXParams(&def);
   3736 
   3737     OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
   3738 
   3739     def.nPortIndex = kPortIndexInput;
   3740 
   3741     err = mOMXNode->getParameter(
   3742             OMX_IndexParamPortDefinition, &def, sizeof(def));
   3743 
   3744     if (err != OK) {
   3745         return err;
   3746     }
   3747 
   3748     int32_t width, height, bitrate;
   3749     if (!msg->findInt32("width", &width)
   3750             || !msg->findInt32("height", &height)
   3751             || !msg->findInt32("bitrate", &bitrate)) {
   3752         return INVALID_OPERATION;
   3753     }
   3754 
   3755     video_def->nFrameWidth = width;
   3756     video_def->nFrameHeight = height;
   3757 
   3758     int32_t stride;
   3759     if (!msg->findInt32("stride", &stride)) {
   3760         stride = width;
   3761     }
   3762 
   3763     video_def->nStride = stride;
   3764 
   3765     int32_t sliceHeight;
   3766     if (!msg->findInt32("slice-height", &sliceHeight)) {
   3767         sliceHeight = height;
   3768     }
   3769 
   3770     video_def->nSliceHeight = sliceHeight;
   3771 
   3772     def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
   3773 
   3774     float framerate;
   3775     if (!msg->findFloat("frame-rate", &framerate)) {
   3776         int32_t tmp;
   3777         if (!msg->findInt32("frame-rate", &tmp)) {
   3778             return INVALID_OPERATION;
   3779         }
   3780         mFps = (double)tmp;
   3781     } else {
   3782         mFps = (double)framerate;
   3783     }
   3784 
   3785     video_def->xFramerate = (OMX_U32)(mFps * 65536);
   3786     video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
   3787     // this is redundant as it was already set up in setVideoPortFormatType
   3788     // FIXME for now skip this only for flexible YUV formats
   3789     if (colorFormat != OMX_COLOR_FormatYUV420Flexible) {
   3790         video_def->eColorFormat = colorFormat;
   3791     }
   3792 
   3793     err = mOMXNode->setParameter(
   3794             OMX_IndexParamPortDefinition, &def, sizeof(def));
   3795 
   3796     if (err != OK) {
   3797         ALOGE("[%s] failed to set input port definition parameters.",
   3798               mComponentName.c_str());
   3799 
   3800         return err;
   3801     }
   3802 
   3803     /* Output port configuration */
   3804 
   3805     OMX_VIDEO_CODINGTYPE compressionFormat;
   3806     err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
   3807 
   3808     if (err != OK) {
   3809         return err;
   3810     }
   3811 
   3812     err = setVideoPortFormatType(
   3813             kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
   3814 
   3815     if (err != OK) {
   3816         ALOGE("[%s] does not support compression format %d",
   3817              mComponentName.c_str(), compressionFormat);
   3818 
   3819         return err;
   3820     }
   3821 
   3822     def.nPortIndex = kPortIndexOutput;
   3823 
   3824     err = mOMXNode->getParameter(
   3825             OMX_IndexParamPortDefinition, &def, sizeof(def));
   3826 
   3827     if (err != OK) {
   3828         return err;
   3829     }
   3830 
   3831     video_def->nFrameWidth = width;
   3832     video_def->nFrameHeight = height;
   3833     video_def->xFramerate = 0;
   3834     video_def->nBitrate = bitrate;
   3835     video_def->eCompressionFormat = compressionFormat;
   3836     video_def->eColorFormat = OMX_COLOR_FormatUnused;
   3837 
   3838     err = mOMXNode->setParameter(
   3839             OMX_IndexParamPortDefinition, &def, sizeof(def));
   3840 
   3841     if (err != OK) {
   3842         ALOGE("[%s] failed to set output port definition parameters.",
   3843               mComponentName.c_str());
   3844 
   3845         return err;
   3846     }
   3847 
   3848     int32_t intraRefreshPeriod = 0;
   3849     if (msg->findInt32("intra-refresh-period", &intraRefreshPeriod)
   3850             && intraRefreshPeriod >= 0) {
   3851         err = setIntraRefreshPeriod((uint32_t)intraRefreshPeriod, true);
   3852         if (err != OK) {
   3853             ALOGI("[%s] failed setIntraRefreshPeriod. Failure is fine since this key is optional",
   3854                     mComponentName.c_str());
   3855             err = OK;
   3856         }
   3857     }
   3858 
   3859     configureEncoderLatency(msg);
   3860 
   3861     switch (compressionFormat) {
   3862         case OMX_VIDEO_CodingMPEG4:
   3863             err = setupMPEG4EncoderParameters(msg);
   3864             break;
   3865 
   3866         case OMX_VIDEO_CodingH263:
   3867             err = setupH263EncoderParameters(msg);
   3868             break;
   3869 
   3870         case OMX_VIDEO_CodingAVC:
   3871             err = setupAVCEncoderParameters(msg);
   3872             break;
   3873 
   3874         case OMX_VIDEO_CodingHEVC:
   3875             err = setupHEVCEncoderParameters(msg);
   3876             break;
   3877 
   3878         case OMX_VIDEO_CodingVP8:
   3879         case OMX_VIDEO_CodingVP9:
   3880             err = setupVPXEncoderParameters(msg, outputFormat);
   3881             break;
   3882 
   3883         default:
   3884             break;
   3885     }
   3886 
   3887     if (err != OK) {
   3888         return err;
   3889     }
   3890 
   3891     // Set up color aspects on input, but propagate them to the output format, as they will
   3892     // not be read back from encoder.
   3893     err = setColorAspectsForVideoEncoder(msg, outputFormat, inputFormat);
   3894     if (err == ERROR_UNSUPPORTED) {
   3895         ALOGI("[%s] cannot encode color aspects. Ignoring.", mComponentName.c_str());
   3896         err = OK;
   3897     }
   3898 
   3899     if (err != OK) {
   3900         return err;
   3901     }
   3902 
   3903     err = setHDRStaticInfoForVideoCodec(kPortIndexInput, msg, outputFormat);
   3904     if (err == ERROR_UNSUPPORTED) { // support is optional
   3905         ALOGI("[%s] cannot encode HDR static metadata. Ignoring.", mComponentName.c_str());
   3906         err = OK;
   3907     }
   3908 
   3909     if (err != OK) {
   3910         return err;
   3911     }
   3912 
   3913     switch (compressionFormat) {
   3914         case OMX_VIDEO_CodingAVC:
   3915         case OMX_VIDEO_CodingHEVC:
   3916             err = configureTemporalLayers(msg, true /* inConfigure */, outputFormat);
   3917             if (err != OK) {
   3918                 err = OK; // ignore failure
   3919             }
   3920             break;
   3921 
   3922         case OMX_VIDEO_CodingVP8:
   3923         case OMX_VIDEO_CodingVP9:
   3924             // TODO: do we need to support android.generic layering? webrtc layering is
   3925             // already set up in setupVPXEncoderParameters.
   3926             break;
   3927 
   3928         default:
   3929             break;
   3930     }
   3931 
   3932     if (err == OK) {
   3933         ALOGI("setupVideoEncoder succeeded");
   3934     }
   3935 
   3936     return err;
   3937 }
   3938 
   3939 status_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
   3940     OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
   3941     InitOMXParams(&params);
   3942     params.nPortIndex = kPortIndexOutput;
   3943 
   3944     params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
   3945 
   3946     if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
   3947             params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
   3948         int32_t mbs;
   3949         if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
   3950             return INVALID_OPERATION;
   3951         }
   3952         params.nCirMBs = mbs;
   3953     }
   3954 
   3955     if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
   3956             params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
   3957         int32_t mbs;
   3958         if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
   3959             return INVALID_OPERATION;
   3960         }
   3961         params.nAirMBs = mbs;
   3962 
   3963         int32_t ref;
   3964         if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
   3965             return INVALID_OPERATION;
   3966         }
   3967         params.nAirRef = ref;
   3968     }
   3969 
   3970     status_t err = mOMXNode->setParameter(
   3971             OMX_IndexParamVideoIntraRefresh, &params, sizeof(params));
   3972     return err;
   3973 }
   3974 
   3975 static OMX_U32 setPFramesSpacing(
   3976         float iFramesInterval /* seconds */, int32_t frameRate, uint32_t BFramesSpacing = 0) {
   3977     // BFramesSpacing is the number of B frames between I/P frames
   3978     // PFramesSpacing (the value to be returned) is the number of P frames between I frames
   3979     //
   3980     // keyFrameInterval = ((PFramesSpacing + 1) * BFramesSpacing) + PFramesSpacing + 1
   3981     //                                     ^^^                            ^^^        ^^^
   3982     //                              number of B frames                number of P    I frame
   3983     //
   3984     //                  = (PFramesSpacing + 1) * (BFramesSpacing + 1)
   3985     //
   3986     // E.g.
   3987     //      I   P   I  : I-interval: 8, nPFrames 1, nBFrames 3
   3988     //       BBB BBB
   3989 
   3990     if (iFramesInterval < 0) { // just 1 key frame
   3991         return 0xFFFFFFFE; // don't use maxint as key-frame-interval calculation will add 1
   3992     } else if (iFramesInterval == 0) { // just key frames
   3993         return 0;
   3994     }
   3995 
   3996     // round down as key-frame-interval is an upper limit
   3997     uint32_t keyFrameInterval = uint32_t(frameRate * iFramesInterval);
   3998     OMX_U32 ret = keyFrameInterval / (BFramesSpacing + 1);
   3999     return ret > 0 ? ret - 1 : 0;
   4000 }
   4001 
   4002 static OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
   4003     int32_t tmp;
   4004     if (!msg->findInt32("bitrate-mode", &tmp)) {
   4005         return OMX_Video_ControlRateVariable;
   4006     }
   4007 
   4008     return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
   4009 }
   4010 
   4011 status_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
   4012     int32_t bitrate;
   4013     float iFrameInterval;
   4014     if (!msg->findInt32("bitrate", &bitrate)
   4015             || !msg->findAsFloat("i-frame-interval", &iFrameInterval)) {
   4016         return INVALID_OPERATION;
   4017     }
   4018 
   4019     OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
   4020 
   4021     float frameRate;
   4022     if (!msg->findFloat("frame-rate", &frameRate)) {
   4023         int32_t tmp;
   4024         if (!msg->findInt32("frame-rate", &tmp)) {
   4025             return INVALID_OPERATION;
   4026         }
   4027         frameRate = (float)tmp;
   4028     }
   4029 
   4030     OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
   4031     InitOMXParams(&mpeg4type);
   4032     mpeg4type.nPortIndex = kPortIndexOutput;
   4033 
   4034     status_t err = mOMXNode->getParameter(
   4035             OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
   4036 
   4037     if (err != OK) {
   4038         return err;
   4039     }
   4040 
   4041     mpeg4type.nSliceHeaderSpacing = 0;
   4042     mpeg4type.bSVH = OMX_FALSE;
   4043     mpeg4type.bGov = OMX_FALSE;
   4044 
   4045     mpeg4type.nAllowedPictureTypes =
   4046         OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
   4047 
   4048     mpeg4type.nBFrames = 0;
   4049     mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, mpeg4type.nBFrames);
   4050     if (mpeg4type.nPFrames == 0) {
   4051         mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
   4052     }
   4053     mpeg4type.nIDCVLCThreshold = 0;
   4054     mpeg4type.bACPred = OMX_TRUE;
   4055     mpeg4type.nMaxPacketSize = 256;
   4056     mpeg4type.nTimeIncRes = 1000;
   4057     mpeg4type.nHeaderExtension = 0;
   4058     mpeg4type.bReversibleVLC = OMX_FALSE;
   4059 
   4060     int32_t profile;
   4061     if (msg->findInt32("profile", &profile)) {
   4062         int32_t level;
   4063         if (!msg->findInt32("level", &level)) {
   4064             return INVALID_OPERATION;
   4065         }
   4066 
   4067         err = verifySupportForProfileAndLevel(profile, level);
   4068 
   4069         if (err != OK) {
   4070             return err;
   4071         }
   4072 
   4073         mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
   4074         mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
   4075     }
   4076 
   4077     err = mOMXNode->setParameter(
   4078             OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
   4079 
   4080     if (err != OK) {
   4081         return err;
   4082     }
   4083 
   4084     err = configureBitrate(bitrate, bitrateMode);
   4085 
   4086     if (err != OK) {
   4087         return err;
   4088     }
   4089 
   4090     return setupErrorCorrectionParameters();
   4091 }
   4092 
   4093 status_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
   4094     int32_t bitrate;
   4095     float iFrameInterval;
   4096     if (!msg->findInt32("bitrate", &bitrate)
   4097             || !msg->findAsFloat("i-frame-interval", &iFrameInterval)) {
   4098         return INVALID_OPERATION;
   4099     }
   4100 
   4101     OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
   4102 
   4103     float frameRate;
   4104     if (!msg->findFloat("frame-rate", &frameRate)) {
   4105         int32_t tmp;
   4106         if (!msg->findInt32("frame-rate", &tmp)) {
   4107             return INVALID_OPERATION;
   4108         }
   4109         frameRate = (float)tmp;
   4110     }
   4111 
   4112     OMX_VIDEO_PARAM_H263TYPE h263type;
   4113     InitOMXParams(&h263type);
   4114     h263type.nPortIndex = kPortIndexOutput;
   4115 
   4116     status_t err = mOMXNode->getParameter(
   4117             OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
   4118 
   4119     if (err != OK) {
   4120         return err;
   4121     }
   4122 
   4123     h263type.nAllowedPictureTypes =
   4124         OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
   4125 
   4126     h263type.nBFrames = 0;
   4127     h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, h263type.nBFrames);
   4128     if (h263type.nPFrames == 0) {
   4129         h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
   4130     }
   4131 
   4132     int32_t profile;
   4133     if (msg->findInt32("profile", &profile)) {
   4134         int32_t level;
   4135         if (!msg->findInt32("level", &level)) {
   4136             return INVALID_OPERATION;
   4137         }
   4138 
   4139         err = verifySupportForProfileAndLevel(profile, level);
   4140 
   4141         if (err != OK) {
   4142             return err;
   4143         }
   4144 
   4145         h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
   4146         h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
   4147     }
   4148 
   4149     h263type.bPLUSPTYPEAllowed = OMX_FALSE;
   4150     h263type.bForceRoundingTypeToZero = OMX_FALSE;
   4151     h263type.nPictureHeaderRepetition = 0;
   4152     h263type.nGOBHeaderInterval = 0;
   4153 
   4154     err = mOMXNode->setParameter(
   4155             OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
   4156 
   4157     if (err != OK) {
   4158         return err;
   4159     }
   4160 
   4161     err = configureBitrate(bitrate, bitrateMode);
   4162 
   4163     if (err != OK) {
   4164         return err;
   4165     }
   4166 
   4167     return setupErrorCorrectionParameters();
   4168 }
   4169 
   4170 // static
   4171 int /* OMX_VIDEO_AVCLEVELTYPE */ ACodec::getAVCLevelFor(
   4172         int width, int height, int rate, int bitrate,
   4173         OMX_VIDEO_AVCPROFILEEXTTYPE profile) {
   4174     // convert bitrate to main/baseline profile kbps equivalent
   4175     switch ((uint32_t)profile) {
   4176         case OMX_VIDEO_AVCProfileHigh10:
   4177             bitrate = divUp(bitrate, 3000); break;
   4178         case OMX_VIDEO_AVCProfileConstrainedHigh:
   4179         case OMX_VIDEO_AVCProfileHigh:
   4180             bitrate = divUp(bitrate, 1250); break;
   4181         default:
   4182             bitrate = divUp(bitrate, 1000); break;
   4183     }
   4184 
   4185     // convert size and rate to MBs
   4186     width = divUp(width, 16);
   4187     height = divUp(height, 16);
   4188     int mbs = width * height;
   4189     rate *= mbs;
   4190     int maxDimension = max(width, height);
   4191 
   4192     static const int limits[][5] = {
   4193         /*   MBps     MB   dim  bitrate        level */
   4194         {    1485,    99,  28,     64, OMX_VIDEO_AVCLevel1  },
   4195         {    1485,    99,  28,    128, OMX_VIDEO_AVCLevel1b },
   4196         {    3000,   396,  56,    192, OMX_VIDEO_AVCLevel11 },
   4197         {    6000,   396,  56,    384, OMX_VIDEO_AVCLevel12 },
   4198         {   11880,   396,  56,    768, OMX_VIDEO_AVCLevel13 },
   4199         {   11880,   396,  56,   2000, OMX_VIDEO_AVCLevel2  },
   4200         {   19800,   792,  79,   4000, OMX_VIDEO_AVCLevel21 },
   4201         {   20250,  1620, 113,   4000, OMX_VIDEO_AVCLevel22 },
   4202         {   40500,  1620, 113,  10000, OMX_VIDEO_AVCLevel3  },
   4203         {  108000,  3600, 169,  14000, OMX_VIDEO_AVCLevel31 },
   4204         {  216000,  5120, 202,  20000, OMX_VIDEO_AVCLevel32 },
   4205         {  245760,  8192, 256,  20000, OMX_VIDEO_AVCLevel4  },
   4206         {  245760,  8192, 256,  50000, OMX_VIDEO_AVCLevel41 },
   4207         {  522240,  8704, 263,  50000, OMX_VIDEO_AVCLevel42 },
   4208         {  589824, 22080, 420, 135000, OMX_VIDEO_AVCLevel5  },
   4209         {  983040, 36864, 543, 240000, OMX_VIDEO_AVCLevel51 },
   4210         { 2073600, 36864, 543, 240000, OMX_VIDEO_AVCLevel52 },
   4211     };
   4212 
   4213     for (size_t i = 0; i < ARRAY_SIZE(limits); i++) {
   4214         const int (&limit)[5] = limits[i];
   4215         if (rate <= limit[0] && mbs <= limit[1] && maxDimension <= limit[2]
   4216                 && bitrate <= limit[3]) {
   4217             return limit[4];
   4218         }
   4219     }
   4220     return 0;
   4221 }
   4222 
   4223 status_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
   4224     int32_t bitrate;
   4225     float iFrameInterval;
   4226     if (!msg->findInt32("bitrate", &bitrate)
   4227             || !msg->findAsFloat("i-frame-interval", &iFrameInterval)) {
   4228         return INVALID_OPERATION;
   4229     }
   4230 
   4231     OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
   4232 
   4233     float frameRate;
   4234     if (!msg->findFloat("frame-rate", &frameRate)) {
   4235         int32_t tmp;
   4236         if (!msg->findInt32("frame-rate", &tmp)) {
   4237             return INVALID_OPERATION;
   4238         }
   4239         frameRate = (float)tmp;
   4240     }
   4241 
   4242     status_t err = OK;
   4243     int32_t intraRefreshMode = 0;
   4244     if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
   4245         err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
   4246         if (err != OK) {
   4247             ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
   4248                     err, intraRefreshMode);
   4249             return err;
   4250         }
   4251     }
   4252 
   4253     OMX_VIDEO_PARAM_AVCTYPE h264type;
   4254     InitOMXParams(&h264type);
   4255     h264type.nPortIndex = kPortIndexOutput;
   4256 
   4257     err = mOMXNode->getParameter(
   4258             OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
   4259 
   4260     if (err != OK) {
   4261         return err;
   4262     }
   4263 
   4264     h264type.nAllowedPictureTypes =
   4265         OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
   4266 
   4267     int32_t profile;
   4268     if (msg->findInt32("profile", &profile)) {
   4269         int32_t level;
   4270         if (!msg->findInt32("level", &level)) {
   4271             return INVALID_OPERATION;
   4272         }
   4273 
   4274         err = verifySupportForProfileAndLevel(profile, level);
   4275 
   4276         if (err != OK) {
   4277             return err;
   4278         }
   4279 
   4280         h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
   4281         h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
   4282     } else {
   4283         h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
   4284 #if 0   /* DON'T YET DEFAULT TO HIGHEST PROFILE */
   4285         // Use largest supported profile for AVC recording if profile is not specified.
   4286         for (OMX_VIDEO_AVCPROFILETYPE profile : {
   4287                 OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCProfileMain }) {
   4288             if (verifySupportForProfileAndLevel(profile, 0) == OK) {
   4289                 h264type.eProfile = profile;
   4290                 break;
   4291             }
   4292         }
   4293 #endif
   4294     }
   4295 
   4296     ALOGI("setupAVCEncoderParameters with [profile: %s] [level: %s]",
   4297             asString(h264type.eProfile), asString(h264type.eLevel));
   4298 
   4299     if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
   4300         h264type.nSliceHeaderSpacing = 0;
   4301         h264type.bUseHadamard = OMX_TRUE;
   4302         h264type.nRefFrames = 1;
   4303         h264type.nBFrames = 0;
   4304         h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, h264type.nBFrames);
   4305         if (h264type.nPFrames == 0) {
   4306             h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
   4307         }
   4308         h264type.nRefIdx10ActiveMinus1 = 0;
   4309         h264type.nRefIdx11ActiveMinus1 = 0;
   4310         h264type.bEntropyCodingCABAC = OMX_FALSE;
   4311         h264type.bWeightedPPrediction = OMX_FALSE;
   4312         h264type.bconstIpred = OMX_FALSE;
   4313         h264type.bDirect8x8Inference = OMX_FALSE;
   4314         h264type.bDirectSpatialTemporal = OMX_FALSE;
   4315         h264type.nCabacInitIdc = 0;
   4316     } else if (h264type.eProfile == OMX_VIDEO_AVCProfileMain ||
   4317             h264type.eProfile == OMX_VIDEO_AVCProfileHigh) {
   4318         h264type.nSliceHeaderSpacing = 0;
   4319         h264type.bUseHadamard = OMX_TRUE;
   4320         h264type.nRefFrames = 2;
   4321         h264type.nBFrames = mLatency == 0 ? 1 : std::min(1U, mLatency - 1);
   4322 
   4323         // disable B-frames until MPEG4Writer can guarantee finalizing files with B-frames
   4324         h264type.nRefFrames = 1;
   4325         h264type.nBFrames = 0;
   4326 
   4327         h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, h264type.nBFrames);
   4328         h264type.nAllowedPictureTypes =
   4329             OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
   4330         h264type.nRefIdx10ActiveMinus1 = 0;
   4331         h264type.nRefIdx11ActiveMinus1 = 0;
   4332         h264type.bEntropyCodingCABAC = OMX_TRUE;
   4333         h264type.bWeightedPPrediction = OMX_TRUE;
   4334         h264type.bconstIpred = OMX_TRUE;
   4335         h264type.bDirect8x8Inference = OMX_TRUE;
   4336         h264type.bDirectSpatialTemporal = OMX_TRUE;
   4337         h264type.nCabacInitIdc = 1;
   4338     }
   4339 
   4340     if (h264type.nBFrames != 0) {
   4341         h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
   4342     }
   4343 
   4344     h264type.bEnableUEP = OMX_FALSE;
   4345     h264type.bEnableFMO = OMX_FALSE;
   4346     h264type.bEnableASO = OMX_FALSE;
   4347     h264type.bEnableRS = OMX_FALSE;
   4348     h264type.bFrameMBsOnly = OMX_TRUE;
   4349     h264type.bMBAFF = OMX_FALSE;
   4350     h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
   4351 
   4352     err = mOMXNode->setParameter(
   4353             OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
   4354 
   4355     if (err != OK) {
   4356         return err;
   4357     }
   4358 
   4359     // TRICKY: if we are enabling temporal layering as well, some codecs may not support layering
   4360     // when B-frames are enabled. Detect this now so we can disable B frames if temporal layering
   4361     // is preferred.
   4362     AString tsSchema;
   4363     int32_t preferBFrames = (int32_t)false;
   4364     if (msg->findString("ts-schema", &tsSchema)
   4365             && (!msg->findInt32("android._prefer-b-frames", &preferBFrames) || !preferBFrames)) {
   4366         OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE layering;
   4367         InitOMXParams(&layering);
   4368         layering.nPortIndex = kPortIndexOutput;
   4369         if (mOMXNode->getParameter(
   4370                         (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering,
   4371                         &layering, sizeof(layering)) == OK
   4372                 && layering.eSupportedPatterns
   4373                 && layering.nBLayerCountMax == 0) {
   4374             h264type.nBFrames = 0;
   4375             h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, h264type.nBFrames);
   4376             h264type.nAllowedPictureTypes &= ~OMX_VIDEO_PictureTypeB;
   4377             ALOGI("disabling B-frames");
   4378             err = mOMXNode->setParameter(
   4379                     OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
   4380 
   4381             if (err != OK) {
   4382                 return err;
   4383             }
   4384         }
   4385     }
   4386 
   4387     return configureBitrate(bitrate, bitrateMode);
   4388 }
   4389 
   4390 status_t ACodec::setupHEVCEncoderParameters(const sp<AMessage> &msg) {
   4391     int32_t bitrate;
   4392     float iFrameInterval;
   4393     if (!msg->findInt32("bitrate", &bitrate)
   4394             || !msg->findAsFloat("i-frame-interval", &iFrameInterval)) {
   4395         return INVALID_OPERATION;
   4396     }
   4397 
   4398     OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
   4399 
   4400     float frameRate;
   4401     if (!msg->findFloat("frame-rate", &frameRate)) {
   4402         int32_t tmp;
   4403         if (!msg->findInt32("frame-rate", &tmp)) {
   4404             return INVALID_OPERATION;
   4405         }
   4406         frameRate = (float)tmp;
   4407     }
   4408 
   4409     OMX_VIDEO_PARAM_HEVCTYPE hevcType;
   4410     InitOMXParams(&hevcType);
   4411     hevcType.nPortIndex = kPortIndexOutput;
   4412 
   4413     status_t err = OK;
   4414     err = mOMXNode->getParameter(
   4415             (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
   4416     if (err != OK) {
   4417         return err;
   4418     }
   4419 
   4420     int32_t profile;
   4421     if (msg->findInt32("profile", &profile)) {
   4422         int32_t level;
   4423         if (!msg->findInt32("level", &level)) {
   4424             return INVALID_OPERATION;
   4425         }
   4426 
   4427         err = verifySupportForProfileAndLevel(profile, level);
   4428         if (err != OK) {
   4429             return err;
   4430         }
   4431 
   4432         hevcType.eProfile = static_cast<OMX_VIDEO_HEVCPROFILETYPE>(profile);
   4433         hevcType.eLevel = static_cast<OMX_VIDEO_HEVCLEVELTYPE>(level);
   4434     }
   4435     // TODO: finer control?
   4436     hevcType.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate) + 1;
   4437 
   4438     err = mOMXNode->setParameter(
   4439             (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
   4440     if (err != OK) {
   4441         return err;
   4442     }
   4443 
   4444     return configureBitrate(bitrate, bitrateMode);
   4445 }
   4446 
   4447 status_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg, sp<AMessage> &outputFormat) {
   4448     int32_t bitrate;
   4449     float iFrameInterval = 0;
   4450     size_t tsLayers = 0;
   4451     OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE pattern =
   4452         OMX_VIDEO_VPXTemporalLayerPatternNone;
   4453     static const uint32_t kVp8LayerRateAlloction
   4454         [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS]
   4455         [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] = {
   4456         {100, 100, 100},  // 1 layer
   4457         { 60, 100, 100},  // 2 layers {60%, 40%}
   4458         { 40,  60, 100},  // 3 layers {40%, 20%, 40%}
   4459     };
   4460     if (!msg->findInt32("bitrate", &bitrate)) {
   4461         return INVALID_OPERATION;
   4462     }
   4463     msg->findAsFloat("i-frame-interval", &iFrameInterval);
   4464 
   4465     OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
   4466 
   4467     float frameRate;
   4468     if (!msg->findFloat("frame-rate", &frameRate)) {
   4469         int32_t tmp;
   4470         if (!msg->findInt32("frame-rate", &tmp)) {
   4471             return INVALID_OPERATION;
   4472         }
   4473         frameRate = (float)tmp;
   4474     }
   4475 
   4476     AString tsSchema;
   4477     OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE tsType =
   4478         OMX_VIDEO_AndroidTemporalLayeringPatternNone;
   4479 
   4480     if (msg->findString("ts-schema", &tsSchema)) {
   4481         unsigned int numLayers = 0;
   4482         unsigned int numBLayers = 0;
   4483         int tags;
   4484         char dummy;
   4485         if (sscanf(tsSchema.c_str(), "webrtc.vp8.%u-layer%c", &numLayers, &dummy) == 1
   4486                 && numLayers > 0) {
   4487             pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
   4488             tsType = OMX_VIDEO_AndroidTemporalLayeringPatternWebRTC;
   4489             tsLayers = numLayers;
   4490         } else if ((tags = sscanf(tsSchema.c_str(), "android.generic.%u%c%u%c",
   4491                         &numLayers, &dummy, &numBLayers, &dummy))
   4492                 && (tags == 1 || (tags == 3 && dummy == '+'))
   4493                 && numLayers > 0 && numLayers < UINT32_MAX - numBLayers) {
   4494             pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
   4495             // VPX does not have a concept of B-frames, so just count all layers
   4496             tsType = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid;
   4497             tsLayers = numLayers + numBLayers;
   4498         } else {
   4499             ALOGW("Ignoring unsupported ts-schema [%s]", tsSchema.c_str());
   4500         }
   4501         tsLayers = min(tsLayers, (size_t)OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS);
   4502     }
   4503 
   4504     OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
   4505     InitOMXParams(&vp8type);
   4506     vp8type.nPortIndex = kPortIndexOutput;
   4507     status_t err = mOMXNode->getParameter(
   4508             (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
   4509             &vp8type, sizeof(vp8type));
   4510 
   4511     if (err == OK) {
   4512         if (iFrameInterval > 0) {
   4513             vp8type.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate) + 1;
   4514         }
   4515         vp8type.eTemporalPattern = pattern;
   4516         vp8type.nTemporalLayerCount = tsLayers;
   4517         if (tsLayers > 0) {
   4518             for (size_t i = 0; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) {
   4519                 vp8type.nTemporalLayerBitrateRatio[i] =
   4520                     kVp8LayerRateAlloction[tsLayers - 1][i];
   4521             }
   4522         }
   4523         if (bitrateMode == OMX_Video_ControlRateConstant) {
   4524             vp8type.nMinQuantizer = 2;
   4525             vp8type.nMaxQuantizer = 63;
   4526         }
   4527 
   4528         err = mOMXNode->setParameter(
   4529                 (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
   4530                 &vp8type, sizeof(vp8type));
   4531         if (err != OK) {
   4532             ALOGW("Extended VP8 parameters set failed: %d", err);
   4533         } else if (tsType == OMX_VIDEO_AndroidTemporalLayeringPatternWebRTC) {
   4534             // advertise even single layer WebRTC layering, as it is defined
   4535             outputFormat->setString("ts-schema", AStringPrintf("webrtc.vp8.%u-layer", tsLayers));
   4536         } else if (tsLayers > 0) {
   4537             // tsType == OMX_VIDEO_AndroidTemporalLayeringPatternAndroid
   4538             outputFormat->setString("ts-schema", AStringPrintf("android.generic.%u", tsLayers));
   4539         }
   4540     }
   4541 
   4542     return configureBitrate(bitrate, bitrateMode);
   4543 }
   4544 
   4545 status_t ACodec::verifySupportForProfileAndLevel(
   4546         int32_t profile, int32_t level) {
   4547     OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
   4548     InitOMXParams(&params);
   4549     params.nPortIndex = kPortIndexOutput;
   4550 
   4551     for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
   4552         params.nProfileIndex = index;
   4553         status_t err = mOMXNode->getParameter(
   4554                 OMX_IndexParamVideoProfileLevelQuerySupported,
   4555                 &params, sizeof(params));
   4556 
   4557         if (err != OK) {
   4558             return err;
   4559         }
   4560 
   4561         int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
   4562         int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
   4563 
   4564         if (profile == supportedProfile && level <= supportedLevel) {
   4565             return OK;
   4566         }
   4567 
   4568         if (index == kMaxIndicesToCheck) {
   4569             ALOGW("[%s] stopping checking profiles after %u: %x/%x",
   4570                     mComponentName.c_str(), index,
   4571                     params.eProfile, params.eLevel);
   4572         }
   4573     }
   4574     return ERROR_UNSUPPORTED;
   4575 }
   4576 
   4577 status_t ACodec::configureBitrate(
   4578         int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
   4579     OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
   4580     InitOMXParams(&bitrateType);
   4581     bitrateType.nPortIndex = kPortIndexOutput;
   4582 
   4583     status_t err = mOMXNode->getParameter(
   4584             OMX_IndexParamVideoBitrate, &bitrateType, sizeof(bitrateType));
   4585 
   4586     if (err != OK) {
   4587         return err;
   4588     }
   4589 
   4590     bitrateType.eControlRate = bitrateMode;
   4591     bitrateType.nTargetBitrate = bitrate;
   4592 
   4593     return mOMXNode->setParameter(
   4594             OMX_IndexParamVideoBitrate, &bitrateType, sizeof(bitrateType));
   4595 }
   4596 
   4597 void ACodec::configureEncoderLatency(const sp<AMessage> &msg) {
   4598     if (!mIsEncoder || !mIsVideo) {
   4599         return;
   4600     }
   4601 
   4602     int32_t latency = 0, bitrateMode;
   4603     if (msg->findInt32("latency", &latency) && latency > 0) {
   4604         status_t err = setLatency(latency);
   4605         if (err != OK) {
   4606             ALOGW("[%s] failed setLatency. Failure is fine since this key is optional",
   4607                     mComponentName.c_str());
   4608             err = OK;
   4609         } else {
   4610             mLatency = latency;
   4611         }
   4612     } else if ((!msg->findInt32("bitrate-mode", &bitrateMode) &&
   4613             bitrateMode == OMX_Video_ControlRateConstant)) {
   4614         // default the latency to be 1 if latency key is not specified or unsupported and bitrateMode
   4615         // is CBR.
   4616         mLatency = 1;
   4617     }
   4618 }
   4619 
   4620 status_t ACodec::setupErrorCorrectionParameters() {
   4621     OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
   4622     InitOMXParams(&errorCorrectionType);
   4623     errorCorrectionType.nPortIndex = kPortIndexOutput;
   4624 
   4625     status_t err = mOMXNode->getParameter(
   4626             OMX_IndexParamVideoErrorCorrection,
   4627             &errorCorrectionType, sizeof(errorCorrectionType));
   4628 
   4629     if (err != OK) {
   4630         return OK;  // Optional feature. Ignore this failure
   4631     }
   4632 
   4633     errorCorrectionType.bEnableHEC = OMX_FALSE;
   4634     errorCorrectionType.bEnableResync = OMX_TRUE;
   4635     errorCorrectionType.nResynchMarkerSpacing = 256;
   4636     errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
   4637     errorCorrectionType.bEnableRVLC = OMX_FALSE;
   4638 
   4639     return mOMXNode->setParameter(
   4640             OMX_IndexParamVideoErrorCorrection,
   4641             &errorCorrectionType, sizeof(errorCorrectionType));
   4642 }
   4643 
   4644 status_t ACodec::setVideoFormatOnPort(
   4645         OMX_U32 portIndex,
   4646         int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat,
   4647         float frameRate) {
   4648     OMX_PARAM_PORTDEFINITIONTYPE def;
   4649     InitOMXParams(&def);
   4650     def.nPortIndex = portIndex;
   4651 
   4652     OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
   4653 
   4654     status_t err = mOMXNode->getParameter(
   4655             OMX_IndexParamPortDefinition, &def, sizeof(def));
   4656     if (err != OK) {
   4657         return err;
   4658     }
   4659 
   4660     if (portIndex == kPortIndexInput) {
   4661         // XXX Need a (much) better heuristic to compute input buffer sizes.
   4662         const size_t X = 64 * 1024;
   4663         if (def.nBufferSize < X) {
   4664             def.nBufferSize = X;
   4665         }
   4666     }
   4667 
   4668     if (def.eDomain != OMX_PortDomainVideo) {
   4669         ALOGE("expected video port, got %s(%d)", asString(def.eDomain), def.eDomain);
   4670         return FAILED_TRANSACTION;
   4671     }
   4672 
   4673     video_def->nFrameWidth = width;
   4674     video_def->nFrameHeight = height;
   4675 
   4676     if (portIndex == kPortIndexInput) {
   4677         video_def->eCompressionFormat = compressionFormat;
   4678         video_def->eColorFormat = OMX_COLOR_FormatUnused;
   4679         if (frameRate >= 0) {
   4680             video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
   4681         }
   4682     }
   4683 
   4684     err = mOMXNode->setParameter(
   4685             OMX_IndexParamPortDefinition, &def, sizeof(def));
   4686 
   4687     return err;
   4688 }
   4689 
   4690 size_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
   4691     size_t n = 0;
   4692 
   4693     for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
   4694         const BufferInfo &info = mBuffers[portIndex].itemAt(i);
   4695 
   4696         if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
   4697             ++n;
   4698         }
   4699     }
   4700 
   4701     return n;
   4702 }
   4703 
   4704 size_t ACodec::countBuffersOwnedByNativeWindow() const {
   4705     size_t n = 0;
   4706 
   4707     for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
   4708         const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
   4709 
   4710         if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
   4711             ++n;
   4712         }
   4713     }
   4714 
   4715     return n;
   4716 }
   4717 
   4718 void ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
   4719     if (mNativeWindow == NULL) {
   4720         return;
   4721     }
   4722 
   4723     while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers
   4724             && dequeueBufferFromNativeWindow() != NULL) {
   4725         // these buffers will be submitted as regular buffers; account for this
   4726         if (storingMetadataInDecodedBuffers() && mMetadataBuffersToSubmit > 0) {
   4727             --mMetadataBuffersToSubmit;
   4728         }
   4729     }
   4730 }
   4731 
   4732 bool ACodec::allYourBuffersAreBelongToUs(
   4733         OMX_U32 portIndex) {
   4734     for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
   4735         BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
   4736 
   4737         if (info->mStatus != BufferInfo::OWNED_BY_US
   4738                 && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
   4739             ALOGV("[%s] Buffer %u on port %u still has status %d",
   4740                     mComponentName.c_str(),
   4741                     info->mBufferID, portIndex, info->mStatus);
   4742             return false;
   4743         }
   4744     }
   4745 
   4746     return true;
   4747 }
   4748 
   4749 bool ACodec::allYourBuffersAreBelongToUs() {
   4750     return allYourBuffersAreBelongToUs(kPortIndexInput)
   4751         && allYourBuffersAreBelongToUs(kPortIndexOutput);
   4752 }
   4753 
   4754 void ACodec::deferMessage(const sp<AMessage> &msg) {
   4755     mDeferredQueue.push_back(msg);
   4756 }
   4757 
   4758 void ACodec::processDeferredMessages() {
   4759     List<sp<AMessage> > queue = mDeferredQueue;
   4760     mDeferredQueue.clear();
   4761 
   4762     List<sp<AMessage> >::iterator it = queue.begin();
   4763     while (it != queue.end()) {
   4764         onMessageReceived(*it++);
   4765     }
   4766 }
   4767 
   4768 status_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify) {
   4769     const char *niceIndex = portIndex == kPortIndexInput ? "input" : "output";
   4770     OMX_PARAM_PORTDEFINITIONTYPE def;
   4771     InitOMXParams(&def);
   4772     def.nPortIndex = portIndex;
   4773 
   4774     status_t err = mOMXNode->getParameter(OMX_IndexParamPortDefinition, &def, sizeof(def));
   4775     if (err != OK) {
   4776         return err;
   4777     }
   4778 
   4779     if (def.eDir != (portIndex == kPortIndexOutput ? OMX_DirOutput : OMX_DirInput)) {
   4780         ALOGE("unexpected dir: %s(%d) on %s port", asString(def.eDir), def.eDir, niceIndex);
   4781         return BAD_VALUE;
   4782     }
   4783 
   4784     switch (def.eDomain) {
   4785         case OMX_PortDomainVideo:
   4786         {
   4787             OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
   4788             switch ((int)videoDef->eCompressionFormat) {
   4789                 case OMX_VIDEO_CodingUnused:
   4790                 {
   4791                     CHECK(mIsEncoder ^ (portIndex == kPortIndexOutput));
   4792                     notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
   4793 
   4794                     notify->setInt32("stride", videoDef->nStride);
   4795                     notify->setInt32("slice-height", videoDef->nSliceHeight);
   4796                     notify->setInt32("color-format", videoDef->eColorFormat);
   4797 
   4798                     if (mNativeWindow == NULL) {
   4799                         DescribeColorFormat2Params describeParams;
   4800                         InitOMXParams(&describeParams);
   4801                         describeParams.eColorFormat = videoDef->eColorFormat;
   4802                         describeParams.nFrameWidth = videoDef->nFrameWidth;
   4803                         describeParams.nFrameHeight = videoDef->nFrameHeight;
   4804                         describeParams.nStride = videoDef->nStride;
   4805                         describeParams.nSliceHeight = videoDef->nSliceHeight;
   4806                         describeParams.bUsingNativeBuffers = OMX_FALSE;
   4807 
   4808                         if (DescribeColorFormat(mOMXNode, describeParams)) {
   4809                             notify->setBuffer(
   4810                                     "image-data",
   4811                                     ABuffer::CreateAsCopy(
   4812                                             &describeParams.sMediaImage,
   4813                                             sizeof(describeParams.sMediaImage)));
   4814 
   4815                             MediaImage2 &img = describeParams.sMediaImage;
   4816                             MediaImage2::PlaneInfo *plane = img.mPlane;
   4817                             ALOGV("[%s] MediaImage { F(%ux%u) @%u+%d+%d @%u+%d+%d @%u+%d+%d }",
   4818                                     mComponentName.c_str(), img.mWidth, img.mHeight,
   4819                                     plane[0].mOffset, plane[0].mColInc, plane[0].mRowInc,
   4820                                     plane[1].mOffset, plane[1].mColInc, plane[1].mRowInc,
   4821                                     plane[2].mOffset, plane[2].mColInc, plane[2].mRowInc);
   4822                         }
   4823                     }
   4824 
   4825                     int32_t width = (int32_t)videoDef->nFrameWidth;
   4826                     int32_t height = (int32_t)videoDef->nFrameHeight;
   4827 
   4828                     if (portIndex == kPortIndexOutput) {
   4829                         OMX_CONFIG_RECTTYPE rect;
   4830                         InitOMXParams(&rect);
   4831                         rect.nPortIndex = portIndex;
   4832 
   4833                         if (mOMXNode->getConfig(
   4834                                     (portIndex == kPortIndexOutput ?
   4835                                             OMX_IndexConfigCommonOutputCrop :
   4836                                             OMX_IndexConfigCommonInputCrop),
   4837                                     &rect, sizeof(rect)) != OK) {
   4838                             rect.nLeft = 0;
   4839                             rect.nTop = 0;
   4840                             rect.nWidth = videoDef->nFrameWidth;
   4841                             rect.nHeight = videoDef->nFrameHeight;
   4842                         }
   4843 
   4844                         if (rect.nLeft < 0 ||
   4845                             rect.nTop < 0 ||
   4846                             rect.nLeft + rect.nWidth > videoDef->nFrameWidth ||
   4847                             rect.nTop + rect.nHeight > videoDef->nFrameHeight) {
   4848                             ALOGE("Wrong cropped rect (%d, %d, %u, %u) vs. frame (%u, %u)",
   4849                                     rect.nLeft, rect.nTop,
   4850                                     rect.nWidth, rect.nHeight,
   4851                                     videoDef->nFrameWidth, videoDef->nFrameHeight);
   4852                             return BAD_VALUE;
   4853                         }
   4854 
   4855                         notify->setRect(
   4856                                 "crop",
   4857                                 rect.nLeft,
   4858                                 rect.nTop,
   4859                                 rect.nLeft + rect.nWidth - 1,
   4860                                 rect.nTop + rect.nHeight - 1);
   4861 
   4862                         width = rect.nWidth;
   4863                         height = rect.nHeight;
   4864 
   4865                         android_dataspace dataSpace = HAL_DATASPACE_UNKNOWN;
   4866                         (void)getColorAspectsAndDataSpaceForVideoDecoder(
   4867                                 width, height, mConfigFormat, notify,
   4868                                 mUsingNativeWindow ? &dataSpace : NULL);
   4869                         if (mUsingNativeWindow) {
   4870                             notify->setInt32("android._dataspace", dataSpace);
   4871                         }
   4872                         (void)getHDRStaticInfoForVideoCodec(kPortIndexOutput, notify);
   4873                     } else {
   4874                         (void)getInputColorAspectsForVideoEncoder(notify);
   4875                         if (mConfigFormat->contains("hdr-static-info")) {
   4876                             (void)getHDRStaticInfoForVideoCodec(kPortIndexInput, notify);
   4877                         }
   4878                         uint32_t latency = 0;
   4879                         if (mIsEncoder && getLatency(&latency) == OK && latency > 0) {
   4880                             notify->setInt32("latency", latency);
   4881                         }
   4882                     }
   4883 
   4884                     break;
   4885                 }
   4886 
   4887                 case OMX_VIDEO_CodingVP8:
   4888                 case OMX_VIDEO_CodingVP9:
   4889                 {
   4890                     OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
   4891                     InitOMXParams(&vp8type);
   4892                     vp8type.nPortIndex = kPortIndexOutput;
   4893                     status_t err = mOMXNode->getParameter(
   4894                             (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
   4895                             &vp8type,
   4896                             sizeof(vp8type));
   4897 
   4898                     if (err == OK) {
   4899                         if (vp8type.eTemporalPattern == OMX_VIDEO_VPXTemporalLayerPatternWebRTC
   4900                                 && vp8type.nTemporalLayerCount > 0
   4901                                 && vp8type.nTemporalLayerCount
   4902                                         <= OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS) {
   4903                             // advertise as android.generic if we configured for android.generic
   4904                             AString origSchema;
   4905                             if (notify->findString("ts-schema", &origSchema)
   4906                                     && origSchema.startsWith("android.generic")) {
   4907                                 notify->setString("ts-schema", AStringPrintf(
   4908                                         "android.generic.%u", vp8type.nTemporalLayerCount));
   4909                             } else {
   4910                                 notify->setString("ts-schema", AStringPrintf(
   4911                                         "webrtc.vp8.%u-layer", vp8type.nTemporalLayerCount));
   4912                             }
   4913                         }
   4914                     }
   4915                     // Fall through to set up mime.
   4916                 }
   4917 
   4918                 default:
   4919                 {
   4920                     if (mIsEncoder ^ (portIndex == kPortIndexOutput)) {
   4921                         // should be CodingUnused
   4922                         ALOGE("Raw port video compression format is %s(%d)",
   4923                                 asString(videoDef->eCompressionFormat),
   4924                                 videoDef->eCompressionFormat);
   4925                         return BAD_VALUE;
   4926                     }
   4927                     AString mime;
   4928                     if (GetMimeTypeForVideoCoding(
   4929                         videoDef->eCompressionFormat, &mime) != OK) {
   4930                         notify->setString("mime", "application/octet-stream");
   4931                     } else {
   4932                         notify->setString("mime", mime.c_str());
   4933                     }
   4934                     uint32_t intraRefreshPeriod = 0;
   4935                     if (mIsEncoder && getIntraRefreshPeriod(&intraRefreshPeriod) == OK
   4936                             && intraRefreshPeriod > 0) {
   4937                         notify->setInt32("intra-refresh-period", intraRefreshPeriod);
   4938                     }
   4939                     break;
   4940                 }
   4941             }
   4942             notify->setInt32("width", videoDef->nFrameWidth);
   4943             notify->setInt32("height", videoDef->nFrameHeight);
   4944             ALOGV("[%s] %s format is %s", mComponentName.c_str(),
   4945                     portIndex == kPortIndexInput ? "input" : "output",
   4946                     notify->debugString().c_str());
   4947 
   4948             break;
   4949         }
   4950 
   4951         case OMX_PortDomainAudio:
   4952         {
   4953             OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
   4954 
   4955             switch ((int)audioDef->eEncoding) {
   4956                 case OMX_AUDIO_CodingPCM:
   4957                 {
   4958                     OMX_AUDIO_PARAM_PCMMODETYPE params;
   4959                     InitOMXParams(&params);
   4960                     params.nPortIndex = portIndex;
   4961 
   4962                     err = mOMXNode->getParameter(
   4963                             OMX_IndexParamAudioPcm, &params, sizeof(params));
   4964                     if (err != OK) {
   4965                         return err;
   4966                     }
   4967 
   4968                     if (params.nChannels <= 0
   4969                             || (params.nChannels != 1 && !params.bInterleaved)
   4970                             || params.ePCMMode != OMX_AUDIO_PCMModeLinear) {
   4971                         ALOGE("unsupported PCM port: %u channels%s, %u-bit",
   4972                                 params.nChannels,
   4973                                 params.bInterleaved ? " interleaved" : "",
   4974                                 params.nBitPerSample);
   4975                         return FAILED_TRANSACTION;
   4976                     }
   4977 
   4978                     notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
   4979                     notify->setInt32("channel-count", params.nChannels);
   4980                     notify->setInt32("sample-rate", params.nSamplingRate);
   4981 
   4982                     AudioEncoding encoding = kAudioEncodingPcm16bit;
   4983                     if (params.eNumData == OMX_NumericalDataUnsigned
   4984                             && params.nBitPerSample == 8u) {
   4985                         encoding = kAudioEncodingPcm8bit;
   4986                     } else if (params.eNumData == OMX_NumericalDataFloat
   4987                             && params.nBitPerSample == 32u) {
   4988                         encoding = kAudioEncodingPcmFloat;
   4989                     } else if (params.nBitPerSample != 16u
   4990                             || params.eNumData != OMX_NumericalDataSigned) {
   4991                         ALOGE("unsupported PCM port: %s(%d), %s(%d) mode ",
   4992                                 asString(params.eNumData), params.eNumData,
   4993                                 asString(params.ePCMMode), params.ePCMMode);
   4994                         return FAILED_TRANSACTION;
   4995                     }
   4996                     notify->setInt32("pcm-encoding", encoding);
   4997 
   4998                     if (mChannelMaskPresent) {
   4999                         notify->setInt32("channel-mask", mChannelMask);
   5000                     }
   5001                     break;
   5002                 }
   5003 
   5004                 case OMX_AUDIO_CodingAAC:
   5005                 {
   5006                     OMX_AUDIO_PARAM_AACPROFILETYPE params;
   5007                     InitOMXParams(&params);
   5008                     params.nPortIndex = portIndex;
   5009 
   5010                     err = mOMXNode->getParameter(
   5011                             OMX_IndexParamAudioAac, &params, sizeof(params));
   5012                     if (err != OK) {
   5013                         return err;
   5014                     }
   5015 
   5016                     notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
   5017                     notify->setInt32("channel-count", params.nChannels);
   5018                     notify->setInt32("sample-rate", params.nSampleRate);
   5019                     break;
   5020                 }
   5021 
   5022                 case OMX_AUDIO_CodingAMR:
   5023                 {
   5024                     OMX_AUDIO_PARAM_AMRTYPE params;
   5025                     InitOMXParams(&params);
   5026                     params.nPortIndex = portIndex;
   5027 
   5028                     err = mOMXNode->getParameter(
   5029                             OMX_IndexParamAudioAmr, &params, sizeof(params));
   5030                     if (err != OK) {
   5031                         return err;
   5032                     }
   5033 
   5034                     notify->setInt32("channel-count", 1);
   5035                     if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
   5036                         notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
   5037                         notify->setInt32("sample-rate", 16000);
   5038                     } else {
   5039                         notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
   5040                         notify->setInt32("sample-rate", 8000);
   5041                     }
   5042                     break;
   5043                 }
   5044 
   5045                 case OMX_AUDIO_CodingFLAC:
   5046                 {
   5047                     OMX_AUDIO_PARAM_FLACTYPE params;
   5048                     InitOMXParams(&params);
   5049                     params.nPortIndex = portIndex;
   5050 
   5051                     err = mOMXNode->getParameter(
   5052                             OMX_IndexParamAudioFlac, &params, sizeof(params));
   5053                     if (err != OK) {
   5054                         return err;
   5055                     }
   5056 
   5057                     notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
   5058                     notify->setInt32("channel-count", params.nChannels);
   5059                     notify->setInt32("sample-rate", params.nSampleRate);
   5060                     break;
   5061                 }
   5062 
   5063                 case OMX_AUDIO_CodingMP3:
   5064                 {
   5065                     OMX_AUDIO_PARAM_MP3TYPE params;
   5066                     InitOMXParams(&params);
   5067                     params.nPortIndex = portIndex;
   5068 
   5069                     err = mOMXNode->getParameter(
   5070                             OMX_IndexParamAudioMp3, &params, sizeof(params));
   5071                     if (err != OK) {
   5072                         return err;
   5073                     }
   5074 
   5075                     notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MPEG);
   5076                     notify->setInt32("channel-count", params.nChannels);
   5077                     notify->setInt32("sample-rate", params.nSampleRate);
   5078                     break;
   5079                 }
   5080 
   5081                 case OMX_AUDIO_CodingVORBIS:
   5082                 {
   5083                     OMX_AUDIO_PARAM_VORBISTYPE params;
   5084                     InitOMXParams(&params);
   5085                     params.nPortIndex = portIndex;
   5086 
   5087                     err = mOMXNode->getParameter(
   5088                             OMX_IndexParamAudioVorbis, &params, sizeof(params));
   5089                     if (err != OK) {
   5090                         return err;
   5091                     }
   5092 
   5093                     notify->setString("mime", MEDIA_MIMETYPE_AUDIO_VORBIS);
   5094                     notify->setInt32("channel-count", params.nChannels);
   5095                     notify->setInt32("sample-rate", params.nSampleRate);
   5096                     break;
   5097                 }
   5098 
   5099                 case OMX_AUDIO_CodingAndroidAC3:
   5100                 {
   5101                     OMX_AUDIO_PARAM_ANDROID_AC3TYPE params;
   5102                     InitOMXParams(&params);
   5103                     params.nPortIndex = portIndex;
   5104 
   5105                     err = mOMXNode->getParameter(
   5106                             (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
   5107                             &params, sizeof(params));
   5108                     if (err != OK) {
   5109                         return err;
   5110                     }
   5111 
   5112                     notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3);
   5113                     notify->setInt32("channel-count", params.nChannels);
   5114                     notify->setInt32("sample-rate", params.nSampleRate);
   5115                     break;
   5116                 }
   5117 
   5118                 case OMX_AUDIO_CodingAndroidEAC3:
   5119                 {
   5120                     OMX_AUDIO_PARAM_ANDROID_EAC3TYPE params;
   5121                     InitOMXParams(&params);
   5122                     params.nPortIndex = portIndex;
   5123 
   5124                     err = mOMXNode->getParameter(
   5125                             (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
   5126                             &params, sizeof(params));
   5127                     if (err != OK) {
   5128                         return err;
   5129                     }
   5130 
   5131                     notify->setString("mime", MEDIA_MIMETYPE_AUDIO_EAC3);
   5132                     notify->setInt32("channel-count", params.nChannels);
   5133                     notify->setInt32("sample-rate", params.nSampleRate);
   5134                     break;
   5135                 }
   5136 
   5137                 case OMX_AUDIO_CodingAndroidOPUS:
   5138                 {
   5139                     OMX_AUDIO_PARAM_ANDROID_OPUSTYPE params;
   5140                     InitOMXParams(&params);
   5141                     params.nPortIndex = portIndex;
   5142 
   5143                     err = mOMXNode->getParameter(
   5144                             (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
   5145                             &params, sizeof(params));
   5146                     if (err != OK) {
   5147                         return err;
   5148                     }
   5149 
   5150                     notify->setString("mime", MEDIA_MIMETYPE_AUDIO_OPUS);
   5151                     notify->setInt32("channel-count", params.nChannels);
   5152                     notify->setInt32("sample-rate", params.nSampleRate);
   5153                     break;
   5154                 }
   5155 
   5156                 case OMX_AUDIO_CodingG711:
   5157                 {
   5158                     OMX_AUDIO_PARAM_PCMMODETYPE params;
   5159                     InitOMXParams(&params);
   5160                     params.nPortIndex = portIndex;
   5161 
   5162                     err = mOMXNode->getParameter(
   5163                             (OMX_INDEXTYPE)OMX_IndexParamAudioPcm, &params, sizeof(params));
   5164                     if (err != OK) {
   5165                         return err;
   5166                     }
   5167 
   5168                     const char *mime = NULL;
   5169                     if (params.ePCMMode == OMX_AUDIO_PCMModeMULaw) {
   5170                         mime = MEDIA_MIMETYPE_AUDIO_G711_MLAW;
   5171                     } else if (params.ePCMMode == OMX_AUDIO_PCMModeALaw) {
   5172                         mime = MEDIA_MIMETYPE_AUDIO_G711_ALAW;
   5173                     } else { // params.ePCMMode == OMX_AUDIO_PCMModeLinear
   5174                         mime = MEDIA_MIMETYPE_AUDIO_RAW;
   5175                     }
   5176                     notify->setString("mime", mime);
   5177                     notify->setInt32("channel-count", params.nChannels);
   5178                     notify->setInt32("sample-rate", params.nSamplingRate);
   5179                     notify->setInt32("pcm-encoding", kAudioEncodingPcm16bit);
   5180                     break;
   5181                 }
   5182 
   5183                 case OMX_AUDIO_CodingGSMFR:
   5184                 {
   5185                     OMX_AUDIO_PARAM_PCMMODETYPE params;
   5186                     InitOMXParams(&params);
   5187                     params.nPortIndex = portIndex;
   5188 
   5189                     err = mOMXNode->getParameter(
   5190                                 OMX_IndexParamAudioPcm, &params, sizeof(params));
   5191                     if (err != OK) {
   5192                         return err;
   5193                     }
   5194 
   5195                     notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MSGSM);
   5196                     notify->setInt32("channel-count", params.nChannels);
   5197                     notify->setInt32("sample-rate", params.nSamplingRate);
   5198                     break;
   5199                 }
   5200 
   5201                 default:
   5202                     ALOGE("Unsupported audio coding: %s(%d)\n",
   5203                             asString(audioDef->eEncoding), audioDef->eEncoding);
   5204                     return BAD_TYPE;
   5205             }
   5206             break;
   5207         }
   5208 
   5209         default:
   5210             ALOGE("Unsupported domain: %s(%d)", asString(def.eDomain), def.eDomain);
   5211             return BAD_TYPE;
   5212     }
   5213 
   5214     return getVendorParameters(portIndex, notify);
   5215 }
   5216 
   5217 void ACodec::onDataSpaceChanged(android_dataspace dataSpace, const ColorAspects &aspects) {
   5218     // aspects are normally communicated in ColorAspects
   5219     int32_t range, standard, transfer;
   5220     convertCodecColorAspectsToPlatformAspects(aspects, &range, &standard, &transfer);
   5221 
   5222     // if some aspects are unspecified, use dataspace fields
   5223     if (range != 0) {
   5224         range = (dataSpace & HAL_DATASPACE_RANGE_MASK) >> HAL_DATASPACE_RANGE_SHIFT;
   5225     }
   5226     if (standard != 0) {
   5227         standard = (dataSpace & HAL_DATASPACE_STANDARD_MASK) >> HAL_DATASPACE_STANDARD_SHIFT;
   5228     }
   5229     if (transfer != 0) {
   5230         transfer = (dataSpace & HAL_DATASPACE_TRANSFER_MASK) >> HAL_DATASPACE_TRANSFER_SHIFT;
   5231     }
   5232 
   5233     mOutputFormat = mOutputFormat->dup(); // trigger an output format changed event
   5234     if (range != 0) {
   5235         mOutputFormat->setInt32("color-range", range);
   5236     }
   5237     if (standard != 0) {
   5238         mOutputFormat->setInt32("color-standard", standard);
   5239     }
   5240     if (transfer != 0) {
   5241         mOutputFormat->setInt32("color-transfer", transfer);
   5242     }
   5243 
   5244     ALOGD("dataspace changed to %#x (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) "
   5245           "(R:%d(%s), S:%d(%s), T:%d(%s))",
   5246             dataSpace,
   5247             aspects.mRange, asString(aspects.mRange),
   5248             aspects.mPrimaries, asString(aspects.mPrimaries),
   5249             aspects.mMatrixCoeffs, asString(aspects.mMatrixCoeffs),
   5250             aspects.mTransfer, asString(aspects.mTransfer),
   5251             range, asString((ColorRange)range),
   5252             standard, asString((ColorStandard)standard),
   5253             transfer, asString((ColorTransfer)transfer));
   5254 }
   5255 
   5256 void ACodec::onOutputFormatChanged(sp<const AMessage> expectedFormat) {
   5257     // store new output format, at the same time mark that this is no longer the first frame
   5258     mOutputFormat = mBaseOutputFormat->dup();
   5259 
   5260     if (getPortFormat(kPortIndexOutput, mOutputFormat) != OK) {
   5261         ALOGE("[%s] Failed to get port format to send format change", mComponentName.c_str());
   5262         return;
   5263     }
   5264 
   5265     if (expectedFormat != NULL) {
   5266         sp<const AMessage> changes = expectedFormat->changesFrom(mOutputFormat);
   5267         sp<const AMessage> to = mOutputFormat->changesFrom(expectedFormat);
   5268         if (changes->countEntries() != 0 || to->countEntries() != 0) {
   5269             ALOGW("[%s] BAD CODEC: Output format changed unexpectedly from (diff) %s to (diff) %s",
   5270                     mComponentName.c_str(),
   5271                     changes->debugString(4).c_str(), to->debugString(4).c_str());
   5272         }
   5273     }
   5274 
   5275     if (!mIsVideo && !mIsEncoder) {
   5276         AudioEncoding pcmEncoding = kAudioEncodingPcm16bit;
   5277         (void)mConfigFormat->findInt32("pcm-encoding", (int32_t*)&pcmEncoding);
   5278         AudioEncoding codecPcmEncoding = kAudioEncodingPcm16bit;
   5279         (void)mOutputFormat->findInt32("pcm-encoding", (int32_t*)&pcmEncoding);
   5280 
   5281         mConverter[kPortIndexOutput] = AudioConverter::Create(codecPcmEncoding, pcmEncoding);
   5282         if (mConverter[kPortIndexOutput] != NULL) {
   5283             mOutputFormat->setInt32("pcm-encoding", pcmEncoding);
   5284         }
   5285     }
   5286 
   5287     if (mTunneled) {
   5288         sendFormatChange();
   5289     }
   5290 }
   5291 
   5292 void ACodec::sendFormatChange() {
   5293     AString mime;
   5294     CHECK(mOutputFormat->findString("mime", &mime));
   5295 
   5296     if (mime == MEDIA_MIMETYPE_AUDIO_RAW && (mEncoderDelay || mEncoderPadding)) {
   5297         int32_t channelCount, sampleRate;
   5298         CHECK(mOutputFormat->findInt32("channel-count", &channelCount));
   5299         CHECK(mOutputFormat->findInt32("sample-rate", &sampleRate));
   5300         if (mSampleRate != 0 && sampleRate != 0) {
   5301             mEncoderDelay = mEncoderDelay * sampleRate / mSampleRate;
   5302             mEncoderPadding = mEncoderPadding * sampleRate / mSampleRate;
   5303             mSampleRate = sampleRate;
   5304         }
   5305         if (mSkipCutBuffer != NULL) {
   5306             size_t prevbufsize = mSkipCutBuffer->size();
   5307             if (prevbufsize != 0) {
   5308                 ALOGW("Replacing SkipCutBuffer holding %zu bytes", prevbufsize);
   5309             }
   5310         }
   5311         mSkipCutBuffer = new SkipCutBuffer(mEncoderDelay, mEncoderPadding, channelCount);
   5312     }
   5313 
   5314     // mLastOutputFormat is not used when tunneled; doing this just to stay consistent
   5315     mLastOutputFormat = mOutputFormat;
   5316 }
   5317 
   5318 void ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
   5319     ALOGE("signalError(omxError %#x, internalError %d)", error, internalError);
   5320 
   5321     if (internalError == UNKNOWN_ERROR) { // find better error code
   5322         const status_t omxStatus = statusFromOMXError(error);
   5323         if (omxStatus != 0) {
   5324             internalError = omxStatus;
   5325         } else {
   5326             ALOGW("Invalid OMX error %#x", error);
   5327         }
   5328     }
   5329 
   5330     mFatalError = true;
   5331     mCallback->onError(internalError, ACTION_CODE_FATAL);
   5332 }
   5333 
   5334 status_t ACodec::requestIDRFrame() {
   5335     if (!mIsEncoder) {
   5336         return ERROR_UNSUPPORTED;
   5337     }
   5338 
   5339     OMX_CONFIG_INTRAREFRESHVOPTYPE params;
   5340     InitOMXParams(&params);
   5341 
   5342     params.nPortIndex = kPortIndexOutput;
   5343     params.IntraRefreshVOP = OMX_TRUE;
   5344 
   5345     return mOMXNode->setConfig(
   5346             OMX_IndexConfigVideoIntraVOPRefresh,
   5347             &params,
   5348             sizeof(params));
   5349 }
   5350 
   5351 ////////////////////////////////////////////////////////////////////////////////
   5352 
   5353 ACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
   5354     : AState(parentState),
   5355       mCodec(codec) {
   5356 }
   5357 
   5358 ACodec::BaseState::PortMode ACodec::BaseState::getPortMode(
   5359         OMX_U32 /* portIndex */) {
   5360     return KEEP_BUFFERS;
   5361 }
   5362 
   5363 void ACodec::BaseState::stateExited() {
   5364     ++mCodec->mStateGeneration;
   5365 }
   5366 
   5367 bool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
   5368     switch (msg->what()) {
   5369         case kWhatInputBufferFilled:
   5370         {
   5371             onInputBufferFilled(msg);
   5372             break;
   5373         }
   5374 
   5375         case kWhatOutputBufferDrained:
   5376         {
   5377             onOutputBufferDrained(msg);
   5378             break;
   5379         }
   5380 
   5381         case ACodec::kWhatOMXMessageList:
   5382         {
   5383             return checkOMXMessage(msg) ? onOMXMessageList(msg) : true;
   5384         }
   5385 
   5386         case ACodec::kWhatOMXMessageItem:
   5387         {
   5388             // no need to check as we already did it for kWhatOMXMessageList
   5389             return onOMXMessage(msg);
   5390         }
   5391 
   5392         case ACodec::kWhatOMXMessage:
   5393         {
   5394             return checkOMXMessage(msg) ? onOMXMessage(msg) : true;
   5395         }
   5396 
   5397         case ACodec::kWhatSetSurface:
   5398         {
   5399             sp<AReplyToken> replyID;
   5400             CHECK(msg->senderAwaitsResponse(&replyID));
   5401 
   5402             sp<RefBase> obj;
   5403             CHECK(msg->findObject("surface", &obj));
   5404 
   5405             status_t err = mCodec->handleSetSurface(static_cast<Surface *>(obj.get()));
   5406 
   5407             sp<AMessage> response = new AMessage;
   5408             response->setInt32("err", err);
   5409             response->postReply(replyID);
   5410             break;
   5411         }
   5412 
   5413         case ACodec::kWhatCreateInputSurface:
   5414         case ACodec::kWhatSetInputSurface:
   5415         case ACodec::kWhatSignalEndOfInputStream:
   5416         {
   5417             // This may result in an app illegal state exception.
   5418             ALOGE("Message 0x%x was not handled", msg->what());
   5419             mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
   5420             return true;
   5421         }
   5422 
   5423         case ACodec::kWhatOMXDied:
   5424         {
   5425             // This will result in kFlagSawMediaServerDie handling in MediaCodec.
   5426             ALOGE("OMX/mediaserver died, signalling error!");
   5427             mCodec->mGraphicBufferSource.clear();
   5428             mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
   5429             break;
   5430         }
   5431 
   5432         case ACodec::kWhatReleaseCodecInstance:
   5433         {
   5434             ALOGI("[%s] forcing the release of codec",
   5435                     mCodec->mComponentName.c_str());
   5436             status_t err = mCodec->mOMXNode->freeNode();
   5437             ALOGE_IF("[%s] failed to release codec instance: err=%d",
   5438                        mCodec->mComponentName.c_str(), err);
   5439             mCodec->mCallback->onReleaseCompleted();
   5440 
   5441             mCodec->changeState(mCodec->mUninitializedState);
   5442             break;
   5443         }
   5444 
   5445         case ACodec::kWhatForceStateTransition:
   5446         {
   5447             ALOGV("Already transitioned --- ignore");
   5448             break;
   5449         }
   5450 
   5451         default:
   5452             return false;
   5453     }
   5454 
   5455     return true;
   5456 }
   5457 
   5458 bool ACodec::BaseState::checkOMXMessage(const sp<AMessage> &msg) {
   5459     // there is a possibility that this is an outstanding message for a
   5460     // codec that we have already destroyed
   5461     if (mCodec->mOMXNode == NULL) {
   5462         ALOGI("ignoring message as already freed component: %s",
   5463                 msg->debugString().c_str());
   5464         return false;
   5465     }
   5466 
   5467     int32_t generation;
   5468     CHECK(msg->findInt32("generation", (int32_t*)&generation));
   5469     if (generation != mCodec->mNodeGeneration) {
   5470         ALOGW("Unexpected message for component: %s, gen %u, cur %u",
   5471                 msg->debugString().c_str(), generation, mCodec->mNodeGeneration);
   5472         return false;
   5473     }
   5474     return true;
   5475 }
   5476 
   5477 bool ACodec::BaseState::onOMXMessageList(const sp<AMessage> &msg) {
   5478     sp<RefBase> obj;
   5479     CHECK(msg->findObject("messages", &obj));
   5480     sp<MessageList> msgList = static_cast<MessageList *>(obj.get());
   5481 
   5482     bool receivedRenderedEvents = false;
   5483     for (std::list<sp<AMessage>>::const_iterator it = msgList->getList().cbegin();
   5484           it != msgList->getList().cend(); ++it) {
   5485         (*it)->setWhat(ACodec::kWhatOMXMessageItem);
   5486         mCodec->handleMessage(*it);
   5487         int32_t type;
   5488         CHECK((*it)->findInt32("type", &type));
   5489         if (type == omx_message::FRAME_RENDERED) {
   5490             receivedRenderedEvents = true;
   5491         }
   5492     }
   5493 
   5494     if (receivedRenderedEvents) {
   5495         // NOTE: all buffers are rendered in this case
   5496         mCodec->notifyOfRenderedFrames();
   5497     }
   5498     return true;
   5499 }
   5500 
   5501 bool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
   5502     int32_t type;
   5503     CHECK(msg->findInt32("type", &type));
   5504 
   5505     switch (type) {
   5506         case omx_message::EVENT:
   5507         {
   5508             int32_t event, data1, data2;
   5509             CHECK(msg->findInt32("event", &event));
   5510             CHECK(msg->findInt32("data1", &data1));
   5511             CHECK(msg->findInt32("data2", &data2));
   5512 
   5513             if (event == OMX_EventCmdComplete
   5514                     && data1 == OMX_CommandFlush
   5515                     && data2 == (int32_t)OMX_ALL) {
   5516                 // Use of this notification is not consistent across
   5517                 // implementations. We'll drop this notification and rely
   5518                 // on flush-complete notifications on the individual port
   5519                 // indices instead.
   5520 
   5521                 return true;
   5522             }
   5523 
   5524             return onOMXEvent(
   5525                     static_cast<OMX_EVENTTYPE>(event),
   5526                     static_cast<OMX_U32>(data1),
   5527                     static_cast<OMX_U32>(data2));
   5528         }
   5529 
   5530         case omx_message::EMPTY_BUFFER_DONE:
   5531         {
   5532             IOMX::buffer_id bufferID;
   5533             int32_t fenceFd;
   5534 
   5535             CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
   5536             CHECK(msg->findInt32("fence_fd", &fenceFd));
   5537 
   5538             return onOMXEmptyBufferDone(bufferID, fenceFd);
   5539         }
   5540 
   5541         case omx_message::FILL_BUFFER_DONE:
   5542         {
   5543             IOMX::buffer_id bufferID;
   5544             CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
   5545 
   5546             int32_t rangeOffset, rangeLength, flags, fenceFd;
   5547             int64_t timeUs;
   5548 
   5549             CHECK(msg->findInt32("range_offset", &rangeOffset));
   5550             CHECK(msg->findInt32("range_length", &rangeLength));
   5551             CHECK(msg->findInt32("flags", &flags));
   5552             CHECK(msg->findInt64("timestamp", &timeUs));
   5553             CHECK(msg->findInt32("fence_fd", &fenceFd));
   5554 
   5555             return onOMXFillBufferDone(
   5556                     bufferID,
   5557                     (size_t)rangeOffset, (size_t)rangeLength,
   5558                     (OMX_U32)flags,
   5559                     timeUs,
   5560                     fenceFd);
   5561         }
   5562 
   5563         case omx_message::FRAME_RENDERED:
   5564         {
   5565             int64_t mediaTimeUs, systemNano;
   5566 
   5567             CHECK(msg->findInt64("media_time_us", &mediaTimeUs));
   5568             CHECK(msg->findInt64("system_nano", &systemNano));
   5569 
   5570             return onOMXFrameRendered(
   5571                     mediaTimeUs, systemNano);
   5572         }
   5573 
   5574         default:
   5575             ALOGE("Unexpected message type: %d", type);
   5576             return false;
   5577     }
   5578 }
   5579 
   5580 bool ACodec::BaseState::onOMXFrameRendered(
   5581         int64_t mediaTimeUs __unused, nsecs_t systemNano __unused) {
   5582     // ignore outside of Executing and PortSettingsChanged states
   5583     return true;
   5584 }
   5585 
   5586 bool ACodec::BaseState::onOMXEvent(
   5587         OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
   5588     if (event == OMX_EventDataSpaceChanged) {
   5589         ColorAspects aspects = ColorUtils::unpackToColorAspects(data2);
   5590 
   5591         mCodec->onDataSpaceChanged((android_dataspace)data1, aspects);
   5592         return true;
   5593     }
   5594 
   5595     if (event != OMX_EventError) {
   5596         ALOGV("[%s] EVENT(%d, 0x%08x, 0x%08x)",
   5597              mCodec->mComponentName.c_str(), event, data1, data2);
   5598 
   5599         return false;
   5600     }
   5601 
   5602     ALOGE("[%s] ERROR(0x%08x)", mCodec->mComponentName.c_str(), data1);
   5603 
   5604     // verify OMX component sends back an error we expect.
   5605     OMX_ERRORTYPE omxError = (OMX_ERRORTYPE)data1;
   5606     if (!isOMXError(omxError)) {
   5607         ALOGW("Invalid OMX error %#x", omxError);
   5608         omxError = OMX_ErrorUndefined;
   5609     }
   5610     mCodec->signalError(omxError);
   5611 
   5612     return true;
   5613 }
   5614 
   5615 bool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID, int fenceFd) {
   5616     ALOGV("[%s] onOMXEmptyBufferDone %u",
   5617          mCodec->mComponentName.c_str(), bufferID);
   5618 
   5619     BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
   5620     BufferInfo::Status status = BufferInfo::getSafeStatus(info);
   5621     if (status != BufferInfo::OWNED_BY_COMPONENT) {
   5622         ALOGE("Wrong ownership in EBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
   5623         mCodec->dumpBuffers(kPortIndexInput);
   5624         if (fenceFd >= 0) {
   5625             ::close(fenceFd);
   5626         }
   5627         return false;
   5628     }
   5629     info->mStatus = BufferInfo::OWNED_BY_US;
   5630 
   5631     // input buffers cannot take fences, so wait for any fence now
   5632     (void)mCodec->waitForFence(fenceFd, "onOMXEmptyBufferDone");
   5633     fenceFd = -1;
   5634 
   5635     // still save fence for completeness
   5636     info->setWriteFence(fenceFd, "onOMXEmptyBufferDone");
   5637 
   5638     // We're in "store-metadata-in-buffers" mode, the underlying
   5639     // OMX component had access to data that's implicitly refcounted
   5640     // by this "MediaBuffer" object. Now that the OMX component has
   5641     // told us that it's done with the input buffer, we can decrement
   5642     // the mediaBuffer's reference count.
   5643     info->mData->setMediaBufferBase(NULL);
   5644 
   5645     PortMode mode = getPortMode(kPortIndexInput);
   5646 
   5647     switch (mode) {
   5648         case KEEP_BUFFERS:
   5649             break;
   5650 
   5651         case RESUBMIT_BUFFERS:
   5652             postFillThisBuffer(info);
   5653             break;
   5654 
   5655         case FREE_BUFFERS:
   5656         default:
   5657             ALOGE("SHOULD NOT REACH HERE: cannot free empty output buffers");
   5658             return false;
   5659     }
   5660 
   5661     return true;
   5662 }
   5663 
   5664 void ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
   5665     if (mCodec->mPortEOS[kPortIndexInput]) {
   5666         return;
   5667     }
   5668 
   5669     CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
   5670 
   5671     info->mData->setFormat(mCodec->mInputFormat);
   5672     mCodec->mBufferChannel->fillThisBuffer(info->mBufferID);
   5673     info->mData.clear();
   5674     info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
   5675 }
   5676 
   5677 void ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
   5678     IOMX::buffer_id bufferID;
   5679     CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
   5680     sp<MediaCodecBuffer> buffer;
   5681     int32_t err = OK;
   5682     bool eos = false;
   5683     PortMode mode = getPortMode(kPortIndexInput);
   5684     int32_t discarded = 0;
   5685     if (msg->findInt32("discarded", &discarded) && discarded) {
   5686         // these are unfilled buffers returned by client
   5687         // buffers are returned on MediaCodec.flush
   5688         mode = KEEP_BUFFERS;
   5689     }
   5690     sp<RefBase> obj;
   5691     CHECK(msg->findObject("buffer", &obj));
   5692     buffer = static_cast<MediaCodecBuffer *>(obj.get());
   5693 
   5694     int32_t tmp;
   5695     if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
   5696         eos = true;
   5697         err = ERROR_END_OF_STREAM;
   5698     }
   5699 
   5700     BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
   5701     BufferInfo::Status status = BufferInfo::getSafeStatus(info);
   5702     if (status != BufferInfo::OWNED_BY_UPSTREAM) {
   5703         ALOGE("Wrong ownership in IBF: %s(%d) buffer #%u", _asString(status), status, bufferID);
   5704         mCodec->dumpBuffers(kPortIndexInput);
   5705         mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
   5706         return;
   5707     }
   5708 
   5709     info->mStatus = BufferInfo::OWNED_BY_US;
   5710     info->mData = buffer;
   5711 
   5712     switch (mode) {
   5713         case KEEP_BUFFERS:
   5714         {
   5715             if (eos) {
   5716                 if (!mCodec->mPortEOS[kPortIndexInput]) {
   5717                     mCodec->mPortEOS[kPortIndexInput] = true;
   5718                     mCodec->mInputEOSResult = err;
   5719                 }
   5720             }
   5721             break;
   5722         }
   5723 
   5724         case RESUBMIT_BUFFERS:
   5725         {
   5726             if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
   5727                 // Do not send empty input buffer w/o EOS to the component.
   5728                 if (buffer->size() == 0 && !eos) {
   5729                     postFillThisBuffer(info);
   5730                     break;
   5731                 }
   5732 
   5733                 int64_t timeUs;
   5734                 CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
   5735 
   5736                 OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
   5737 
   5738                 int32_t isCSD = 0;
   5739                 if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
   5740                     if (mCodec->mIsLegacyVP9Decoder) {
   5741                         ALOGV("[%s] is legacy VP9 decoder. Ignore %u codec specific data",
   5742                             mCodec->mComponentName.c_str(), bufferID);
   5743                         postFillThisBuffer(info);
   5744                         break;
   5745                     }
   5746                     flags |= OMX_BUFFERFLAG_CODECCONFIG;
   5747                 }
   5748 
   5749                 if (eos) {
   5750                     flags |= OMX_BUFFERFLAG_EOS;
   5751                 }
   5752 
   5753                 size_t size = buffer->size();
   5754                 size_t offset = buffer->offset();
   5755                 if (buffer->base() != info->mCodecData->base()) {
   5756                     ALOGV("[%s] Needs to copy input data for buffer %u. (%p != %p)",
   5757                          mCodec->mComponentName.c_str(),
   5758                          bufferID,
   5759                          buffer->base(), info->mCodecData->base());
   5760 
   5761                     sp<DataConverter> converter = mCodec->mConverter[kPortIndexInput];
   5762                     if (converter == NULL || isCSD) {
   5763                         converter = getCopyConverter();
   5764                     }
   5765                     status_t err = converter->convert(buffer, info->mCodecData);
   5766                     if (err != OK) {
   5767                         mCodec->signalError(OMX_ErrorUndefined, err);
   5768                         return;
   5769                     }
   5770                     size = info->mCodecData->size();
   5771                 } else {
   5772                     info->mCodecData->setRange(offset, size);
   5773                 }
   5774 
   5775                 if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
   5776                     ALOGV("[%s] calling emptyBuffer %u w/ codec specific data",
   5777                          mCodec->mComponentName.c_str(), bufferID);
   5778                 } else if (flags & OMX_BUFFERFLAG_EOS) {
   5779                     ALOGV("[%s] calling emptyBuffer %u w/ EOS",
   5780                          mCodec->mComponentName.c_str(), bufferID);
   5781                 } else {
   5782 #if TRACK_BUFFER_TIMING
   5783                     ALOGI("[%s] calling emptyBuffer %u w/ time %lld us",
   5784                          mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
   5785 #else
   5786                     ALOGV("[%s] calling emptyBuffer %u w/ time %lld us",
   5787                          mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
   5788 #endif
   5789                 }
   5790 
   5791 #if TRACK_BUFFER_TIMING
   5792                 ACodec::BufferStats stats;
   5793                 stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
   5794                 stats.mFillBufferDoneTimeUs = -1ll;
   5795                 mCodec->mBufferStats.add(timeUs, stats);
   5796 #endif
   5797 
   5798                 if (mCodec->storingMetadataInDecodedBuffers()) {
   5799                     // try to submit an output buffer for each input buffer
   5800                     PortMode outputMode = getPortMode(kPortIndexOutput);
   5801 
   5802                     ALOGV("MetadataBuffersToSubmit=%u portMode=%s",
   5803                             mCodec->mMetadataBuffersToSubmit,
   5804                             (outputMode == FREE_BUFFERS ? "FREE" :
   5805                              outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
   5806                     if (outputMode == RESUBMIT_BUFFERS) {
   5807                         mCodec->submitOutputMetadataBuffer();
   5808                     }
   5809                 }
   5810                 info->checkReadFence("onInputBufferFilled");
   5811 
   5812                 status_t err2 = OK;
   5813                 switch (mCodec->mPortMode[kPortIndexInput]) {
   5814                 case IOMX::kPortModePresetByteBuffer:
   5815                 case IOMX::kPortModePresetANWBuffer:
   5816                 case IOMX::kPortModePresetSecureBuffer:
   5817                     {
   5818                         err2 = mCodec->mOMXNode->emptyBuffer(
   5819                             bufferID, info->mCodecData, flags, timeUs, info->mFenceFd);
   5820                     }
   5821                     break;
   5822 #ifndef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
   5823                 case IOMX::kPortModeDynamicNativeHandle:
   5824                     if (info->mCodecData->size() >= sizeof(VideoNativeHandleMetadata)) {
   5825                         VideoNativeHandleMetadata *vnhmd =
   5826                             (VideoNativeHandleMetadata*)info->mCodecData->base();
   5827                         sp<NativeHandle> handle = NativeHandle::create(
   5828                                 vnhmd->pHandle, false /* ownsHandle */);
   5829                         err2 = mCodec->mOMXNode->emptyBuffer(
   5830                             bufferID, handle, flags, timeUs, info->mFenceFd);
   5831                     }
   5832                     break;
   5833                 case IOMX::kPortModeDynamicANWBuffer:
   5834                     if (info->mCodecData->size() >= sizeof(VideoNativeMetadata)) {
   5835                         VideoNativeMetadata *vnmd = (VideoNativeMetadata*)info->mCodecData->base();
   5836                         sp<GraphicBuffer> graphicBuffer = GraphicBuffer::from(vnmd->pBuffer);
   5837                         err2 = mCodec->mOMXNode->emptyBuffer(
   5838                             bufferID, graphicBuffer, flags, timeUs, info->mFenceFd);
   5839                     }
   5840                     break;
   5841 #endif
   5842                 default:
   5843                     ALOGW("Can't marshall %s data in %zu sized buffers in %zu-bit mode",
   5844                             asString(mCodec->mPortMode[kPortIndexInput]),
   5845                             info->mCodecData->size(),
   5846                             sizeof(buffer_handle_t) * 8);
   5847                     err2 = ERROR_UNSUPPORTED;
   5848                     break;
   5849                 }
   5850 
   5851                 info->mFenceFd = -1;
   5852                 if (err2 != OK) {
   5853                     mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2));
   5854                     return;
   5855                 }
   5856                 info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
   5857                 // Hold the reference while component is using the buffer.
   5858                 info->mData = buffer;
   5859 
   5860                 if (!eos && err == OK) {
   5861                     getMoreInputDataIfPossible();
   5862                 } else {
   5863                     ALOGV("[%s] Signalled EOS (%d) on the input port",
   5864                          mCodec->mComponentName.c_str(), err);
   5865 
   5866                     mCodec->mPortEOS[kPortIndexInput] = true;
   5867                     mCodec->mInputEOSResult = err;
   5868                 }
   5869             } else if (!mCodec->mPortEOS[kPortIndexInput]) {
   5870                 if (err != OK && err != ERROR_END_OF_STREAM) {
   5871                     ALOGV("[%s] Signalling EOS on the input port due to error %d",
   5872                          mCodec->mComponentName.c_str(), err);
   5873                 } else {
   5874                     ALOGV("[%s] Signalling EOS on the input port",
   5875                          mCodec->mComponentName.c_str());
   5876                 }
   5877 
   5878                 ALOGV("[%s] calling emptyBuffer %u signalling EOS",
   5879                      mCodec->mComponentName.c_str(), bufferID);
   5880 
   5881                 info->checkReadFence("onInputBufferFilled");
   5882                 status_t err2 = mCodec->mOMXNode->emptyBuffer(
   5883                         bufferID, OMXBuffer::sPreset, OMX_BUFFERFLAG_EOS, 0, info->mFenceFd);
   5884                 info->mFenceFd = -1;
   5885                 if (err2 != OK) {
   5886                     mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2));
   5887                     return;
   5888                 }
   5889                 info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
   5890 
   5891                 mCodec->mPortEOS[kPortIndexInput] = true;
   5892                 mCodec->mInputEOSResult = err;
   5893             }
   5894             break;
   5895         }
   5896 
   5897         case FREE_BUFFERS:
   5898             break;
   5899 
   5900         default:
   5901             ALOGE("invalid port mode: %d", mode);
   5902             break;
   5903     }
   5904 }
   5905 
   5906 void ACodec::BaseState::getMoreInputDataIfPossible() {
   5907     if (mCodec->mPortEOS[kPortIndexInput]) {
   5908         return;
   5909     }
   5910 
   5911     BufferInfo *eligible = NULL;
   5912 
   5913     for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
   5914         BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
   5915 
   5916 #if 0
   5917         if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
   5918             // There's already a "read" pending.
   5919             return;
   5920         }
   5921 #endif
   5922 
   5923         if (info->mStatus == BufferInfo::OWNED_BY_US) {
   5924             eligible = info;
   5925         }
   5926     }
   5927 
   5928     if (eligible == NULL) {
   5929         return;
   5930     }
   5931 
   5932     postFillThisBuffer(eligible);
   5933 }
   5934 
   5935 bool ACodec::BaseState::onOMXFillBufferDone(
   5936         IOMX::buffer_id bufferID,
   5937         size_t rangeOffset, size_t rangeLength,
   5938         OMX_U32 flags,
   5939         int64_t timeUs,
   5940         int fenceFd) {
   5941     ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x",
   5942          mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
   5943 
   5944     ssize_t index;
   5945     status_t err= OK;
   5946 
   5947 #if TRACK_BUFFER_TIMING
   5948     index = mCodec->mBufferStats.indexOfKey(timeUs);
   5949     if (index >= 0) {
   5950         ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
   5951         stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
   5952 
   5953         ALOGI("frame PTS %lld: %lld",
   5954                 timeUs,
   5955                 stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
   5956 
   5957         mCodec->mBufferStats.removeItemsAt(index);
   5958         stats = NULL;
   5959     }
   5960 #endif
   5961 
   5962     BufferInfo *info =
   5963         mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
   5964     BufferInfo::Status status = BufferInfo::getSafeStatus(info);
   5965     if (status != BufferInfo::OWNED_BY_COMPONENT) {
   5966         ALOGE("Wrong ownership in FBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
   5967         mCodec->dumpBuffers(kPortIndexOutput);
   5968         mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
   5969         if (fenceFd >= 0) {
   5970             ::close(fenceFd);
   5971         }
   5972         return true;
   5973     }
   5974 
   5975     info->mDequeuedAt = ++mCodec->mDequeueCounter;
   5976     info->mStatus = BufferInfo::OWNED_BY_US;
   5977 
   5978     if (info->mRenderInfo != NULL) {
   5979         // The fence for an emptied buffer must have signaled, but there still could be queued
   5980         // or out-of-order dequeued buffers in the render queue prior to this buffer. Drop these,
   5981         // as we will soon requeue this buffer to the surface. While in theory we could still keep
   5982         // track of buffers that are requeued to the surface, it is better to add support to the
   5983         // buffer-queue to notify us of released buffers and their fences (in the future).
   5984         mCodec->notifyOfRenderedFrames(true /* dropIncomplete */);
   5985     }
   5986 
   5987     // byte buffers cannot take fences, so wait for any fence now
   5988     if (mCodec->mNativeWindow == NULL) {
   5989         (void)mCodec->waitForFence(fenceFd, "onOMXFillBufferDone");
   5990         fenceFd = -1;
   5991     }
   5992     info->setReadFence(fenceFd, "onOMXFillBufferDone");
   5993 
   5994     PortMode mode = getPortMode(kPortIndexOutput);
   5995 
   5996     switch (mode) {
   5997         case KEEP_BUFFERS:
   5998             break;
   5999 
   6000         case RESUBMIT_BUFFERS:
   6001         {
   6002             if (rangeLength == 0 && (!(flags & OMX_BUFFERFLAG_EOS)
   6003                     || mCodec->mPortEOS[kPortIndexOutput])) {
   6004                 ALOGV("[%s] calling fillBuffer %u",
   6005                      mCodec->mComponentName.c_str(), info->mBufferID);
   6006 
   6007                 err = mCodec->fillBuffer(info);
   6008                 if (err != OK) {
   6009                     mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
   6010                     return true;
   6011                 }
   6012                 break;
   6013             }
   6014 
   6015             sp<MediaCodecBuffer> buffer = info->mData;
   6016 
   6017             if (mCodec->mOutputFormat != mCodec->mLastOutputFormat && rangeLength > 0) {
   6018                 // pretend that output format has changed on the first frame (we used to do this)
   6019                 if (mCodec->mBaseOutputFormat == mCodec->mOutputFormat) {
   6020                     mCodec->onOutputFormatChanged(mCodec->mOutputFormat);
   6021                 }
   6022                 mCodec->sendFormatChange();
   6023             }
   6024             buffer->setFormat(mCodec->mOutputFormat);
   6025 
   6026             if (mCodec->usingSecureBufferOnEncoderOutput()) {
   6027                 native_handle_t *handle = NULL;
   6028                 sp<SecureBuffer> secureBuffer = static_cast<SecureBuffer *>(buffer.get());
   6029                 if (secureBuffer != NULL) {
   6030 #ifdef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
   6031                     // handle is only valid on 32-bit/mediaserver process
   6032                     handle = NULL;
   6033 #else
   6034                     handle = (native_handle_t *)secureBuffer->getDestinationPointer();
   6035 #endif
   6036                 }
   6037                 buffer->meta()->setPointer("handle", handle);
   6038                 buffer->meta()->setInt32("rangeOffset", rangeOffset);
   6039                 buffer->meta()->setInt32("rangeLength", rangeLength);
   6040             } else if (buffer->base() == info->mCodecData->base()) {
   6041                 buffer->setRange(rangeOffset, rangeLength);
   6042             } else {
   6043                 info->mCodecData->setRange(rangeOffset, rangeLength);
   6044                 // in this case we know that mConverter is not null
   6045                 status_t err = mCodec->mConverter[kPortIndexOutput]->convert(
   6046                         info->mCodecData, buffer);
   6047                 if (err != OK) {
   6048                     mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
   6049                     return true;
   6050                 }
   6051             }
   6052 #if 0
   6053             if (mCodec->mNativeWindow == NULL) {
   6054                 if (IsIDR(info->mData)) {
   6055                     ALOGI("IDR frame");
   6056                 }
   6057             }
   6058 #endif
   6059 
   6060             if (mCodec->mSkipCutBuffer != NULL) {
   6061                 mCodec->mSkipCutBuffer->submit(buffer);
   6062             }
   6063             buffer->meta()->setInt64("timeUs", timeUs);
   6064 
   6065             info->mData.clear();
   6066 
   6067             mCodec->mBufferChannel->drainThisBuffer(info->mBufferID, flags);
   6068 
   6069             info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
   6070 
   6071             if (flags & OMX_BUFFERFLAG_EOS) {
   6072                 ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
   6073 
   6074                 mCodec->mCallback->onEos(mCodec->mInputEOSResult);
   6075                 mCodec->mPortEOS[kPortIndexOutput] = true;
   6076             }
   6077             break;
   6078         }
   6079 
   6080         case FREE_BUFFERS:
   6081             err = mCodec->freeBuffer(kPortIndexOutput, index);
   6082             if (err != OK) {
   6083                 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
   6084                 return true;
   6085             }
   6086             break;
   6087 
   6088         default:
   6089             ALOGE("Invalid port mode: %d", mode);
   6090             return false;
   6091     }
   6092 
   6093     return true;
   6094 }
   6095 
   6096 void ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
   6097     IOMX::buffer_id bufferID;
   6098     CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
   6099     sp<RefBase> obj;
   6100     CHECK(msg->findObject("buffer", &obj));
   6101     sp<MediaCodecBuffer> buffer = static_cast<MediaCodecBuffer *>(obj.get());
   6102     int32_t discarded = 0;
   6103     msg->findInt32("discarded", &discarded);
   6104 
   6105     ssize_t index;
   6106     BufferInfo *info = mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
   6107     BufferInfo::Status status = BufferInfo::getSafeStatus(info);
   6108     if (status != BufferInfo::OWNED_BY_DOWNSTREAM) {
   6109         ALOGE("Wrong ownership in OBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
   6110         mCodec->dumpBuffers(kPortIndexOutput);
   6111         mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
   6112         return;
   6113     }
   6114     info->mData = buffer;
   6115     int32_t render;
   6116     if (mCodec->mNativeWindow != NULL
   6117             && msg->findInt32("render", &render) && render != 0
   6118             && !discarded && buffer->size() != 0) {
   6119         ATRACE_NAME("render");
   6120         // The client wants this buffer to be rendered.
   6121 
   6122         android_native_rect_t crop;
   6123         if (buffer->format()->findRect("crop", &crop.left, &crop.top, &crop.right, &crop.bottom)) {
   6124             // NOTE: native window uses extended right-bottom coordinate
   6125             ++crop.right;
   6126             ++crop.bottom;
   6127             if (memcmp(&crop, &mCodec->mLastNativeWindowCrop, sizeof(crop)) != 0) {
   6128                 mCodec->mLastNativeWindowCrop = crop;
   6129                 status_t err = native_window_set_crop(mCodec->mNativeWindow.get(), &crop);
   6130                 ALOGW_IF(err != NO_ERROR, "failed to set crop: %d", err);
   6131             }
   6132         }
   6133 
   6134         int32_t dataSpace;
   6135         if (buffer->format()->findInt32("android._dataspace", &dataSpace)
   6136                 && dataSpace != mCodec->mLastNativeWindowDataSpace) {
   6137             status_t err = native_window_set_buffers_data_space(
   6138                     mCodec->mNativeWindow.get(), (android_dataspace)dataSpace);
   6139             mCodec->mLastNativeWindowDataSpace = dataSpace;
   6140             ALOGW_IF(err != NO_ERROR, "failed to set dataspace: %d", err);
   6141         }
   6142 
   6143         // save buffers sent to the surface so we can get render time when they return
   6144         int64_t mediaTimeUs = -1;
   6145         buffer->meta()->findInt64("timeUs", &mediaTimeUs);
   6146         if (mediaTimeUs >= 0) {
   6147             mCodec->mRenderTracker.onFrameQueued(
   6148                     mediaTimeUs, info->mGraphicBuffer, new Fence(::dup(info->mFenceFd)));
   6149         }
   6150 
   6151         int64_t timestampNs = 0;
   6152         if (!msg->findInt64("timestampNs", &timestampNs)) {
   6153             // use media timestamp if client did not request a specific render timestamp
   6154             if (buffer->meta()->findInt64("timeUs", &timestampNs)) {
   6155                 ALOGV("using buffer PTS of %lld", (long long)timestampNs);
   6156                 timestampNs *= 1000;
   6157             }
   6158         }
   6159 
   6160         status_t err;
   6161         err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs);
   6162         ALOGW_IF(err != NO_ERROR, "failed to set buffer timestamp: %d", err);
   6163 
   6164         info->checkReadFence("onOutputBufferDrained before queueBuffer");
   6165         err = mCodec->mNativeWindow->queueBuffer(
   6166                     mCodec->mNativeWindow.get(), info->mGraphicBuffer.get(), info->mFenceFd);
   6167         info->mFenceFd = -1;
   6168         if (err == OK) {
   6169             info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
   6170         } else {
   6171             ALOGE("queueBuffer failed in onOutputBufferDrained: %d", err);
   6172             mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
   6173             info->mStatus = BufferInfo::OWNED_BY_US;
   6174             // keeping read fence as write fence to avoid clobbering
   6175             info->mIsReadFence = false;
   6176         }
   6177     } else {
   6178         if (mCodec->mNativeWindow != NULL && (discarded || buffer->size() != 0)) {
   6179             // move read fence into write fence to avoid clobbering
   6180             info->mIsReadFence = false;
   6181             ATRACE_NAME("frame-drop");
   6182         }
   6183         info->mStatus = BufferInfo::OWNED_BY_US;
   6184     }
   6185 
   6186     PortMode mode = getPortMode(kPortIndexOutput);
   6187 
   6188     switch (mode) {
   6189         case KEEP_BUFFERS:
   6190         {
   6191             // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
   6192 
   6193             if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
   6194                 // We cannot resubmit the buffer we just rendered, dequeue
   6195                 // the spare instead.
   6196 
   6197                 info = mCodec->dequeueBufferFromNativeWindow();
   6198             }
   6199             break;
   6200         }
   6201 
   6202         case RESUBMIT_BUFFERS:
   6203         {
   6204             if (!mCodec->mPortEOS[kPortIndexOutput]) {
   6205                 if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
   6206                     // We cannot resubmit the buffer we just rendered, dequeue
   6207                     // the spare instead.
   6208 
   6209                     info = mCodec->dequeueBufferFromNativeWindow();
   6210                 }
   6211 
   6212                 if (info != NULL) {
   6213                     ALOGV("[%s] calling fillBuffer %u",
   6214                          mCodec->mComponentName.c_str(), info->mBufferID);
   6215                     info->checkWriteFence("onOutputBufferDrained::RESUBMIT_BUFFERS");
   6216                     status_t err = mCodec->fillBuffer(info);
   6217                     if (err != OK) {
   6218                         mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
   6219                     }
   6220                 }
   6221             }
   6222             break;
   6223         }
   6224 
   6225         case FREE_BUFFERS:
   6226         {
   6227             status_t err = mCodec->freeBuffer(kPortIndexOutput, index);
   6228             if (err != OK) {
   6229                 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
   6230             }
   6231             break;
   6232         }
   6233 
   6234         default:
   6235             ALOGE("Invalid port mode: %d", mode);
   6236             return;
   6237     }
   6238 }
   6239 
   6240 ////////////////////////////////////////////////////////////////////////////////
   6241 
   6242 ACodec::UninitializedState::UninitializedState(ACodec *codec)
   6243     : BaseState(codec) {
   6244 }
   6245 
   6246 void ACodec::UninitializedState::stateEntered() {
   6247     ALOGV("Now uninitialized");
   6248 
   6249     if (mDeathNotifier != NULL) {
   6250         if (mCodec->mOMXNode != NULL) {
   6251             if (mCodec->getTrebleFlag()) {
   6252                 auto tOmxNode = mCodec->mOMXNode->getHalInterface();
   6253                 tOmxNode->unlinkToDeath(mDeathNotifier);
   6254             } else {
   6255                 sp<IBinder> binder = IInterface::asBinder(mCodec->mOMXNode);
   6256                 binder->unlinkToDeath(mDeathNotifier);
   6257             }
   6258         }
   6259         mDeathNotifier.clear();
   6260     }
   6261 
   6262     mCodec->mUsingNativeWindow = false;
   6263     mCodec->mNativeWindow.clear();
   6264     mCodec->mNativeWindowUsageBits = 0;
   6265     mCodec->mOMX.clear();
   6266     mCodec->mOMXNode.clear();
   6267     mCodec->mFlags = 0;
   6268     mCodec->mPortMode[kPortIndexInput] = IOMX::kPortModePresetByteBuffer;
   6269     mCodec->mPortMode[kPortIndexOutput] = IOMX::kPortModePresetByteBuffer;
   6270     mCodec->mConverter[0].clear();
   6271     mCodec->mConverter[1].clear();
   6272     mCodec->mComponentName.clear();
   6273 }
   6274 
   6275 bool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
   6276     bool handled = false;
   6277 
   6278     switch (msg->what()) {
   6279         case ACodec::kWhatSetup:
   6280         {
   6281             onSetup(msg);
   6282 
   6283             handled = true;
   6284             break;
   6285         }
   6286 
   6287         case ACodec::kWhatAllocateComponent:
   6288         {
   6289             onAllocateComponent(msg);
   6290             handled = true;
   6291             break;
   6292         }
   6293 
   6294         case ACodec::kWhatShutdown:
   6295         {
   6296             int32_t keepComponentAllocated;
   6297             CHECK(msg->findInt32(
   6298                         "keepComponentAllocated", &keepComponentAllocated));
   6299             ALOGW_IF(keepComponentAllocated,
   6300                      "cannot keep component allocated on shutdown in Uninitialized state");
   6301             if (keepComponentAllocated) {
   6302                 mCodec->mCallback->onStopCompleted();
   6303             } else {
   6304                 mCodec->mCallback->onReleaseCompleted();
   6305             }
   6306             handled = true;
   6307             break;
   6308         }
   6309 
   6310         case ACodec::kWhatFlush:
   6311         {
   6312             mCodec->mCallback->onFlushCompleted();
   6313             handled = true;
   6314             break;
   6315         }
   6316 
   6317         case ACodec::kWhatReleaseCodecInstance:
   6318         {
   6319             // nothing to do, as we have already signaled shutdown
   6320             handled = true;
   6321             break;
   6322         }
   6323 
   6324         default:
   6325             return BaseState::onMessageReceived(msg);
   6326     }
   6327 
   6328     return handled;
   6329 }
   6330 
   6331 void ACodec::UninitializedState::onSetup(
   6332         const sp<AMessage> &msg) {
   6333     if (onAllocateComponent(msg)
   6334             && mCodec->mLoadedState->onConfigureComponent(msg)) {
   6335         mCodec->mLoadedState->onStart();
   6336     }
   6337 }
   6338 
   6339 bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
   6340     ALOGV("onAllocateComponent");
   6341 
   6342     CHECK(mCodec->mOMXNode == NULL);
   6343 
   6344     sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec);
   6345 
   6346     Vector<AString> matchingCodecs;
   6347     Vector<AString> owners;
   6348 
   6349     AString mime;
   6350 
   6351     AString componentName;
   6352     int32_t encoder = false;
   6353     if (msg->findString("componentName", &componentName)) {
   6354         sp<IMediaCodecList> list = MediaCodecList::getInstance();
   6355         if (list == nullptr) {
   6356             ALOGE("Unable to obtain MediaCodecList while "
   6357                     "attempting to create codec \"%s\"",
   6358                     componentName.c_str());
   6359             mCodec->signalError(OMX_ErrorUndefined, NO_INIT);
   6360             return false;
   6361         }
   6362         ssize_t index = list->findCodecByName(componentName.c_str());
   6363         if (index < 0) {
   6364             ALOGE("Unable to find codec \"%s\"",
   6365                     componentName.c_str());
   6366             mCodec->signalError(OMX_ErrorInvalidComponent, NAME_NOT_FOUND);
   6367             return false;
   6368         }
   6369         sp<MediaCodecInfo> info = list->getCodecInfo(index);
   6370         if (info == nullptr) {
   6371             ALOGE("Unexpected error (index out-of-bound) while "
   6372                     "retrieving information for codec \"%s\"",
   6373                     componentName.c_str());
   6374             mCodec->signalError(OMX_ErrorUndefined, UNKNOWN_ERROR);
   6375             return false;
   6376         }
   6377         matchingCodecs.add(info->getCodecName());
   6378         owners.add(info->getOwnerName() == nullptr ?
   6379                 "default" : info->getOwnerName());
   6380     } else {
   6381         CHECK(msg->findString("mime", &mime));
   6382 
   6383         if (!msg->findInt32("encoder", &encoder)) {
   6384             encoder = false;
   6385         }
   6386 
   6387         MediaCodecList::findMatchingCodecs(
   6388                 mime.c_str(),
   6389                 encoder, // createEncoder
   6390                 0,       // flags
   6391                 &matchingCodecs,
   6392                 &owners);
   6393     }
   6394 
   6395     sp<CodecObserver> observer = new CodecObserver;
   6396     sp<IOMX> omx;
   6397     sp<IOMXNode> omxNode;
   6398 
   6399     status_t err = NAME_NOT_FOUND;
   6400     for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
   6401             ++matchIndex) {
   6402         componentName = matchingCodecs[matchIndex];
   6403 
   6404         OMXClient client;
   6405         bool trebleFlag;
   6406         if (client.connect(owners[matchIndex].c_str(), &trebleFlag) != OK) {
   6407             mCodec->signalError(OMX_ErrorUndefined, NO_INIT);
   6408             return false;
   6409         }
   6410         omx = client.interface();
   6411 
   6412         pid_t tid = gettid();
   6413         int prevPriority = androidGetThreadPriority(tid);
   6414         androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
   6415         err = omx->allocateNode(componentName.c_str(), observer, &omxNode);
   6416         androidSetThreadPriority(tid, prevPriority);
   6417 
   6418         if (err == OK) {
   6419             mCodec->setTrebleFlag(trebleFlag);
   6420             break;
   6421         } else {
   6422             ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str());
   6423         }
   6424 
   6425         omxNode = NULL;
   6426     }
   6427 
   6428     if (omxNode == NULL) {
   6429         if (!mime.empty()) {
   6430             ALOGE("Unable to instantiate a %scoder for type '%s' with err %#x.",
   6431                     encoder ? "en" : "de", mime.c_str(), err);
   6432         } else {
   6433             ALOGE("Unable to instantiate codec '%s' with err %#x.", componentName.c_str(), err);
   6434         }
   6435 
   6436         mCodec->signalError((OMX_ERRORTYPE)err, makeNoSideEffectStatus(err));
   6437         return false;
   6438     }
   6439 
   6440     mDeathNotifier = new DeathNotifier(notify);
   6441     if (mCodec->getTrebleFlag()) {
   6442         auto tOmxNode = omxNode->getHalInterface();
   6443         if (!tOmxNode->linkToDeath(mDeathNotifier, 0)) {
   6444             mDeathNotifier.clear();
   6445         }
   6446     } else {
   6447         if (IInterface::asBinder(omxNode)->linkToDeath(mDeathNotifier) != OK) {
   6448             // This was a local binder, if it dies so do we, we won't care
   6449             // about any notifications in the afterlife.
   6450             mDeathNotifier.clear();
   6451         }
   6452     }
   6453 
   6454     notify = new AMessage(kWhatOMXMessageList, mCodec);
   6455     notify->setInt32("generation", ++mCodec->mNodeGeneration);
   6456     observer->setNotificationMessage(notify);
   6457 
   6458     mCodec->mComponentName = componentName;
   6459     mCodec->mRenderTracker.setComponentName(componentName);
   6460     mCodec->mFlags = 0;
   6461 
   6462     if (componentName.endsWith(".secure")) {
   6463         mCodec->mFlags |= kFlagIsSecure;
   6464         mCodec->mFlags |= kFlagIsGrallocUsageProtected;
   6465         mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
   6466     }
   6467 
   6468     mCodec->mOMX = omx;
   6469     mCodec->mOMXNode = omxNode;
   6470     mCodec->mCallback->onComponentAllocated(mCodec->mComponentName.c_str());
   6471     mCodec->changeState(mCodec->mLoadedState);
   6472 
   6473     return true;
   6474 }
   6475 
   6476 ////////////////////////////////////////////////////////////////////////////////
   6477 
   6478 ACodec::LoadedState::LoadedState(ACodec *codec)
   6479     : BaseState(codec) {
   6480 }
   6481 
   6482 void ACodec::LoadedState::stateEntered() {
   6483     ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
   6484 
   6485     mCodec->mPortEOS[kPortIndexInput] =
   6486         mCodec->mPortEOS[kPortIndexOutput] = false;
   6487 
   6488     mCodec->mInputEOSResult = OK;
   6489 
   6490     mCodec->mDequeueCounter = 0;
   6491     mCodec->mMetadataBuffersToSubmit = 0;
   6492     mCodec->mRepeatFrameDelayUs = -1ll;
   6493     mCodec->mInputFormat.clear();
   6494     mCodec->mOutputFormat.clear();
   6495     mCodec->mBaseOutputFormat.clear();
   6496     mCodec->mGraphicBufferSource.clear();
   6497 
   6498     if (mCodec->mShutdownInProgress) {
   6499         bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
   6500 
   6501         mCodec->mShutdownInProgress = false;
   6502         mCodec->mKeepComponentAllocated = false;
   6503 
   6504         onShutdown(keepComponentAllocated);
   6505     }
   6506     mCodec->mExplicitShutdown = false;
   6507 
   6508     mCodec->processDeferredMessages();
   6509 }
   6510 
   6511 void ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
   6512     if (!keepComponentAllocated) {
   6513         (void)mCodec->mOMXNode->freeNode();
   6514 
   6515         mCodec->changeState(mCodec->mUninitializedState);
   6516     }
   6517 
   6518     if (mCodec->mExplicitShutdown) {
   6519         if (keepComponentAllocated) {
   6520             mCodec->mCallback->onStopCompleted();
   6521         } else {
   6522             mCodec->mCallback->onReleaseCompleted();
   6523         }
   6524         mCodec->mExplicitShutdown = false;
   6525     }
   6526 }
   6527 
   6528 bool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
   6529     bool handled = false;
   6530 
   6531     switch (msg->what()) {
   6532         case ACodec::kWhatConfigureComponent:
   6533         {
   6534             onConfigureComponent(msg);
   6535             handled = true;
   6536             break;
   6537         }
   6538 
   6539         case ACodec::kWhatCreateInputSurface:
   6540         {
   6541             onCreateInputSurface(msg);
   6542             handled = true;
   6543             break;
   6544         }
   6545 
   6546         case ACodec::kWhatSetInputSurface:
   6547         {
   6548             onSetInputSurface(msg);
   6549             handled = true;
   6550             break;
   6551         }
   6552 
   6553         case ACodec::kWhatStart:
   6554         {
   6555             onStart();
   6556             handled = true;
   6557             break;
   6558         }
   6559 
   6560         case ACodec::kWhatShutdown:
   6561         {
   6562             int32_t keepComponentAllocated;
   6563             CHECK(msg->findInt32(
   6564                         "keepComponentAllocated", &keepComponentAllocated));
   6565 
   6566             mCodec->mExplicitShutdown = true;
   6567             onShutdown(keepComponentAllocated);
   6568 
   6569             handled = true;
   6570             break;
   6571         }
   6572 
   6573         case ACodec::kWhatFlush:
   6574         {
   6575             mCodec->mCallback->onFlushCompleted();
   6576             handled = true;
   6577             break;
   6578         }
   6579 
   6580         default:
   6581             return BaseState::onMessageReceived(msg);
   6582     }
   6583 
   6584     return handled;
   6585 }
   6586 
   6587 bool ACodec::LoadedState::onConfigureComponent(
   6588         const sp<AMessage> &msg) {
   6589     ALOGV("onConfigureComponent");
   6590 
   6591     CHECK(mCodec->mOMXNode != NULL);
   6592 
   6593     status_t err = OK;
   6594     AString mime;
   6595     if (!msg->findString("mime", &mime)) {
   6596         err = BAD_VALUE;
   6597     } else {
   6598         err = mCodec->configureCodec(mime.c_str(), msg);
   6599     }
   6600     if (err != OK) {
   6601         ALOGE("[%s] configureCodec returning error %d",
   6602               mCodec->mComponentName.c_str(), err);
   6603 
   6604         mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
   6605         return false;
   6606     }
   6607 
   6608     mCodec->mCallback->onComponentConfigured(mCodec->mInputFormat, mCodec->mOutputFormat);
   6609 
   6610     return true;
   6611 }
   6612 
   6613 status_t ACodec::LoadedState::setupInputSurface() {
   6614     if (mCodec->mGraphicBufferSource == NULL) {
   6615         return BAD_VALUE;
   6616     }
   6617 
   6618     android_dataspace dataSpace;
   6619     status_t err =
   6620         mCodec->setInitialColorAspectsForVideoEncoderSurfaceAndGetDataSpace(&dataSpace);
   6621     if (err != OK) {
   6622         ALOGE("Failed to get default data space");
   6623         return err;
   6624     }
   6625 
   6626     err = statusFromBinderStatus(
   6627             mCodec->mGraphicBufferSource->configure(mCodec->mOMXNode, dataSpace));
   6628     if (err != OK) {
   6629         ALOGE("[%s] Unable to configure for node (err %d)",
   6630               mCodec->mComponentName.c_str(), err);
   6631         return err;
   6632     }
   6633 
   6634     if (mCodec->mRepeatFrameDelayUs > 0ll) {
   6635         err = statusFromBinderStatus(
   6636                 mCodec->mGraphicBufferSource->setRepeatPreviousFrameDelayUs(
   6637                         mCodec->mRepeatFrameDelayUs));
   6638 
   6639         if (err != OK) {
   6640             ALOGE("[%s] Unable to configure option to repeat previous "
   6641                   "frames (err %d)",
   6642                   mCodec->mComponentName.c_str(), err);
   6643             return err;
   6644         }
   6645     }
   6646 
   6647     if (mCodec->mMaxPtsGapUs > 0ll) {
   6648         OMX_PARAM_U32TYPE maxPtsGapParams;
   6649         InitOMXParams(&maxPtsGapParams);
   6650         maxPtsGapParams.nPortIndex = kPortIndexInput;
   6651         maxPtsGapParams.nU32 = (uint32_t) mCodec->mMaxPtsGapUs;
   6652 
   6653         err = mCodec->mOMXNode->setParameter(
   6654                 (OMX_INDEXTYPE)OMX_IndexParamMaxFrameDurationForBitrateControl,
   6655                 &maxPtsGapParams, sizeof(maxPtsGapParams));
   6656 
   6657         if (err != OK) {
   6658             ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
   6659                     mCodec->mComponentName.c_str(), err);
   6660             return err;
   6661         }
   6662     }
   6663 
   6664     if (mCodec->mMaxFps > 0) {
   6665         err = statusFromBinderStatus(
   6666                 mCodec->mGraphicBufferSource->setMaxFps(mCodec->mMaxFps));
   6667 
   6668         if (err != OK) {
   6669             ALOGE("[%s] Unable to configure max fps (err %d)",
   6670                     mCodec->mComponentName.c_str(), err);
   6671             return err;
   6672         }
   6673     }
   6674 
   6675     if (mCodec->mCaptureFps > 0. && mCodec->mFps > 0.) {
   6676         err = statusFromBinderStatus(
   6677                 mCodec->mGraphicBufferSource->setTimeLapseConfig(
   6678                         mCodec->mFps, mCodec->mCaptureFps));
   6679 
   6680         if (err != OK) {
   6681             ALOGE("[%s] Unable to configure time lapse (err %d)",
   6682                     mCodec->mComponentName.c_str(), err);
   6683             return err;
   6684         }
   6685     }
   6686 
   6687     if (mCodec->mCreateInputBuffersSuspended) {
   6688         err = statusFromBinderStatus(
   6689                 mCodec->mGraphicBufferSource->setSuspend(true, -1));
   6690 
   6691         if (err != OK) {
   6692             ALOGE("[%s] Unable to configure option to suspend (err %d)",
   6693                   mCodec->mComponentName.c_str(), err);
   6694             return err;
   6695         }
   6696     }
   6697 
   6698     uint32_t usageBits;
   6699     if (mCodec->mOMXNode->getParameter(
   6700             (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
   6701             &usageBits, sizeof(usageBits)) == OK) {
   6702         mCodec->mInputFormat->setInt32(
   6703                 "using-sw-read-often", !!(usageBits & GRALLOC_USAGE_SW_READ_OFTEN));
   6704     }
   6705 
   6706     sp<ABuffer> colorAspectsBuffer;
   6707     if (mCodec->mInputFormat->findBuffer("android._color-aspects", &colorAspectsBuffer)) {
   6708         if (colorAspectsBuffer->size() != sizeof(ColorAspects)) {
   6709             return INVALID_OPERATION;
   6710         }
   6711 
   6712         err = statusFromBinderStatus(
   6713                 mCodec->mGraphicBufferSource->setColorAspects(ColorUtils::packToU32(
   6714                         *(ColorAspects *)colorAspectsBuffer->base())));
   6715 
   6716         if (err != OK) {
   6717             ALOGE("[%s] Unable to configure color aspects (err %d)",
   6718                   mCodec->mComponentName.c_str(), err);
   6719             return err;
   6720         }
   6721     }
   6722     return OK;
   6723 }
   6724 
   6725 void ACodec::LoadedState::onCreateInputSurface(
   6726         const sp<AMessage> & /* msg */) {
   6727     ALOGV("onCreateInputSurface");
   6728 
   6729     sp<IGraphicBufferProducer> bufferProducer;
   6730     status_t err = mCodec->mOMX->createInputSurface(
   6731             &bufferProducer, &mCodec->mGraphicBufferSource);
   6732 
   6733     if (err == OK) {
   6734         err = setupInputSurface();
   6735     }
   6736 
   6737     if (err == OK) {
   6738         mCodec->mCallback->onInputSurfaceCreated(
   6739                 mCodec->mInputFormat,
   6740                 mCodec->mOutputFormat,
   6741                 new BufferProducerWrapper(bufferProducer));
   6742     } else {
   6743         // Can't use mCodec->signalError() here -- MediaCodec won't forward
   6744         // the error through because it's in the "configured" state.  We
   6745         // send a kWhatInputSurfaceCreated with an error value instead.
   6746         ALOGE("[%s] onCreateInputSurface returning error %d",
   6747                 mCodec->mComponentName.c_str(), err);
   6748         mCodec->mCallback->onInputSurfaceCreationFailed(err);
   6749     }
   6750 }
   6751 
   6752 void ACodec::LoadedState::onSetInputSurface(const sp<AMessage> &msg) {
   6753     ALOGV("onSetInputSurface");
   6754 
   6755     sp<RefBase> obj;
   6756     CHECK(msg->findObject("input-surface", &obj));
   6757     sp<PersistentSurface> surface = static_cast<PersistentSurface *>(obj.get());
   6758     mCodec->mGraphicBufferSource = surface->getBufferSource();
   6759 
   6760     status_t err = setupInputSurface();
   6761 
   6762     if (err == OK) {
   6763         mCodec->mCallback->onInputSurfaceAccepted(
   6764                 mCodec->mInputFormat, mCodec->mOutputFormat);
   6765     } else {
   6766         // Can't use mCodec->signalError() here -- MediaCodec won't forward
   6767         // the error through because it's in the "configured" state.  We
   6768         // send a kWhatInputSurfaceAccepted with an error value instead.
   6769         ALOGE("[%s] onSetInputSurface returning error %d",
   6770                 mCodec->mComponentName.c_str(), err);
   6771         mCodec->mCallback->onInputSurfaceDeclined(err);
   6772     }
   6773 }
   6774 
   6775 void ACodec::LoadedState::onStart() {
   6776     ALOGV("onStart");
   6777 
   6778     status_t err = mCodec->mOMXNode->sendCommand(OMX_CommandStateSet, OMX_StateIdle);
   6779     if (err != OK) {
   6780         mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
   6781     } else {
   6782         mCodec->changeState(mCodec->mLoadedToIdleState);
   6783     }
   6784 }
   6785 
   6786 ////////////////////////////////////////////////////////////////////////////////
   6787 
   6788 ACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
   6789     : BaseState(codec) {
   6790 }
   6791 
   6792 void ACodec::LoadedToIdleState::stateEntered() {
   6793     ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
   6794 
   6795     status_t err;
   6796     if ((err = allocateBuffers()) != OK) {
   6797         ALOGE("Failed to allocate buffers after transitioning to IDLE state "
   6798              "(error 0x%08x)",
   6799              err);
   6800 
   6801         mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
   6802 
   6803         mCodec->mOMXNode->sendCommand(
   6804                 OMX_CommandStateSet, OMX_StateLoaded);
   6805         if (mCodec->allYourBuffersAreBelongToUs(kPortIndexInput)) {
   6806             mCodec->freeBuffersOnPort(kPortIndexInput);
   6807         }
   6808         if (mCodec->allYourBuffersAreBelongToUs(kPortIndexOutput)) {
   6809             mCodec->freeBuffersOnPort(kPortIndexOutput);
   6810         }
   6811 
   6812         mCodec->changeState(mCodec->mLoadedState);
   6813     }
   6814 }
   6815 
   6816 status_t ACodec::LoadedToIdleState::allocateBuffers() {
   6817     status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
   6818     if (err != OK) {
   6819         return err;
   6820     }
   6821 
   6822     err = mCodec->allocateBuffersOnPort(kPortIndexOutput);
   6823     if (err != OK) {
   6824         return err;
   6825     }
   6826 
   6827     mCodec->mCallback->onStartCompleted();
   6828 
   6829     return OK;
   6830 }
   6831 
   6832 bool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
   6833     switch (msg->what()) {
   6834         case kWhatSetParameters:
   6835         case kWhatShutdown:
   6836         {
   6837             mCodec->deferMessage(msg);
   6838             return true;
   6839         }
   6840 
   6841         case kWhatSignalEndOfInputStream:
   6842         {
   6843             mCodec->onSignalEndOfInputStream();
   6844             return true;
   6845         }
   6846 
   6847         case kWhatResume:
   6848         {
   6849             // We'll be active soon enough.
   6850             return true;
   6851         }
   6852 
   6853         case kWhatFlush:
   6854         {
   6855             // We haven't even started yet, so we're flushed alright...
   6856             mCodec->mCallback->onFlushCompleted();
   6857             return true;
   6858         }
   6859 
   6860         default:
   6861             return BaseState::onMessageReceived(msg);
   6862     }
   6863 }
   6864 
   6865 bool ACodec::LoadedToIdleState::onOMXEvent(
   6866         OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
   6867     switch (event) {
   6868         case OMX_EventCmdComplete:
   6869         {
   6870             status_t err = OK;
   6871             if (data1 != (OMX_U32)OMX_CommandStateSet
   6872                     || data2 != (OMX_U32)OMX_StateIdle) {
   6873                 ALOGE("Unexpected command completion in LoadedToIdleState: %s(%u) %s(%u)",
   6874                         asString((OMX_COMMANDTYPE)data1), data1,
   6875                         asString((OMX_STATETYPE)data2), data2);
   6876                 err = FAILED_TRANSACTION;
   6877             }
   6878 
   6879             if (err == OK) {
   6880                 err = mCodec->mOMXNode->sendCommand(
   6881                     OMX_CommandStateSet, OMX_StateExecuting);
   6882             }
   6883 
   6884             if (err != OK) {
   6885                 mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
   6886             } else {
   6887                 mCodec->changeState(mCodec->mIdleToExecutingState);
   6888             }
   6889 
   6890             return true;
   6891         }
   6892 
   6893         default:
   6894             return BaseState::onOMXEvent(event, data1, data2);
   6895     }
   6896 }
   6897 
   6898 ////////////////////////////////////////////////////////////////////////////////
   6899 
   6900 ACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
   6901     : BaseState(codec) {
   6902 }
   6903 
   6904 void ACodec::IdleToExecutingState::stateEntered() {
   6905     ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
   6906 }
   6907 
   6908 bool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
   6909     switch (msg->what()) {
   6910         case kWhatSetParameters:
   6911         case kWhatShutdown:
   6912         {
   6913             mCodec->deferMessage(msg);
   6914             return true;
   6915         }
   6916 
   6917         case kWhatResume:
   6918         {
   6919             // We'll be active soon enough.
   6920             return true;
   6921         }
   6922 
   6923         case kWhatFlush:
   6924         {
   6925             // We haven't even started yet, so we're flushed alright...
   6926             mCodec->mCallback->onFlushCompleted();
   6927             return true;
   6928         }
   6929 
   6930         case kWhatSignalEndOfInputStream:
   6931         {
   6932             mCodec->onSignalEndOfInputStream();
   6933             return true;
   6934         }
   6935 
   6936         default:
   6937             return BaseState::onMessageReceived(msg);
   6938     }
   6939 }
   6940 
   6941 bool ACodec::IdleToExecutingState::onOMXEvent(
   6942         OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
   6943     switch (event) {
   6944         case OMX_EventCmdComplete:
   6945         {
   6946             if (data1 != (OMX_U32)OMX_CommandStateSet
   6947                     || data2 != (OMX_U32)OMX_StateExecuting) {
   6948                 ALOGE("Unexpected command completion in IdleToExecutingState: %s(%u) %s(%u)",
   6949                         asString((OMX_COMMANDTYPE)data1), data1,
   6950                         asString((OMX_STATETYPE)data2), data2);
   6951                 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
   6952                 return true;
   6953             }
   6954 
   6955             mCodec->mExecutingState->resume();
   6956             mCodec->changeState(mCodec->mExecutingState);
   6957 
   6958             return true;
   6959         }
   6960 
   6961         default:
   6962             return BaseState::onOMXEvent(event, data1, data2);
   6963     }
   6964 }
   6965 
   6966 ////////////////////////////////////////////////////////////////////////////////
   6967 
   6968 ACodec::ExecutingState::ExecutingState(ACodec *codec)
   6969     : BaseState(codec),
   6970       mActive(false) {
   6971 }
   6972 
   6973 ACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
   6974         OMX_U32 /* portIndex */) {
   6975     return RESUBMIT_BUFFERS;
   6976 }
   6977 
   6978 void ACodec::ExecutingState::submitOutputMetaBuffers() {
   6979     // submit as many buffers as there are input buffers with the codec
   6980     // in case we are in port reconfiguring
   6981     for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
   6982         BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
   6983 
   6984         if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
   6985             if (mCodec->submitOutputMetadataBuffer() != OK)
   6986                 break;
   6987         }
   6988     }
   6989 
   6990     // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
   6991     mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround();
   6992 }
   6993 
   6994 void ACodec::ExecutingState::submitRegularOutputBuffers() {
   6995     bool failed = false;
   6996     for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
   6997         BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
   6998 
   6999         if (mCodec->mNativeWindow != NULL) {
   7000             if (info->mStatus != BufferInfo::OWNED_BY_US
   7001                     && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
   7002                 ALOGE("buffers should be owned by us or the surface");
   7003                 failed = true;
   7004                 break;
   7005             }
   7006 
   7007             if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
   7008                 continue;
   7009             }
   7010         } else {
   7011             if (info->mStatus != BufferInfo::OWNED_BY_US) {
   7012                 ALOGE("buffers should be owned by us");
   7013                 failed = true;
   7014                 break;
   7015             }
   7016         }
   7017 
   7018         ALOGV("[%s] calling fillBuffer %u", mCodec->mComponentName.c_str(), info->mBufferID);
   7019 
   7020         info->checkWriteFence("submitRegularOutputBuffers");
   7021         status_t err = mCodec->fillBuffer(info);
   7022         if (err != OK) {
   7023             failed = true;
   7024             break;
   7025         }
   7026     }
   7027 
   7028     if (failed) {
   7029         mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
   7030     }
   7031 }
   7032 
   7033 void ACodec::ExecutingState::submitOutputBuffers() {
   7034     submitRegularOutputBuffers();
   7035     if (mCodec->storingMetadataInDecodedBuffers()) {
   7036         submitOutputMetaBuffers();
   7037     }
   7038 }
   7039 
   7040 void ACodec::ExecutingState::resume() {
   7041     if (mActive) {
   7042         ALOGV("[%s] We're already active, no need to resume.", mCodec->mComponentName.c_str());
   7043         return;
   7044     }
   7045 
   7046     submitOutputBuffers();
   7047 
   7048     // Post all available input buffers
   7049     if (mCodec->mBuffers[kPortIndexInput].size() == 0u) {
   7050         ALOGW("[%s] we don't have any input buffers to resume", mCodec->mComponentName.c_str());
   7051     }
   7052 
   7053     for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) {
   7054         BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
   7055         if (info->mStatus == BufferInfo::OWNED_BY_US) {
   7056             postFillThisBuffer(info);
   7057         }
   7058     }
   7059 
   7060     mActive = true;
   7061 }
   7062 
   7063 void ACodec::ExecutingState::stateEntered() {
   7064     ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
   7065     mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC));
   7066     mCodec->processDeferredMessages();
   7067 }
   7068 
   7069 bool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
   7070     bool handled = false;
   7071 
   7072     switch (msg->what()) {
   7073         case kWhatShutdown:
   7074         {
   7075             int32_t keepComponentAllocated;
   7076             CHECK(msg->findInt32(
   7077                         "keepComponentAllocated", &keepComponentAllocated));
   7078 
   7079             mCodec->mShutdownInProgress = true;
   7080             mCodec->mExplicitShutdown = true;
   7081             mCodec->mKeepComponentAllocated = keepComponentAllocated;
   7082 
   7083             mActive = false;
   7084 
   7085             status_t err = mCodec->mOMXNode->sendCommand(
   7086                     OMX_CommandStateSet, OMX_StateIdle);
   7087             if (err != OK) {
   7088                 if (keepComponentAllocated) {
   7089                     mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
   7090                 }
   7091                 // TODO: do some recovery here.
   7092             } else {
   7093                 mCodec->changeState(mCodec->mExecutingToIdleState);
   7094             }
   7095 
   7096             handled = true;
   7097             break;
   7098         }
   7099 
   7100         case kWhatFlush:
   7101         {
   7102             ALOGV("[%s] ExecutingState flushing now "
   7103                  "(codec owns %zu/%zu input, %zu/%zu output).",
   7104                     mCodec->mComponentName.c_str(),
   7105                     mCodec->countBuffersOwnedByComponent(kPortIndexInput),
   7106                     mCodec->mBuffers[kPortIndexInput].size(),
   7107                     mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
   7108                     mCodec->mBuffers[kPortIndexOutput].size());
   7109 
   7110             mActive = false;
   7111 
   7112             status_t err = mCodec->mOMXNode->sendCommand(OMX_CommandFlush, OMX_ALL);
   7113             if (err != OK) {
   7114                 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
   7115             } else {
   7116                 mCodec->changeState(mCodec->mFlushingState);
   7117             }
   7118 
   7119             handled = true;
   7120             break;
   7121         }
   7122 
   7123         case kWhatResume:
   7124         {
   7125             resume();
   7126 
   7127             handled = true;
   7128             break;
   7129         }
   7130 
   7131         case kWhatRequestIDRFrame:
   7132         {
   7133             status_t err = mCodec->requestIDRFrame();
   7134             if (err != OK) {
   7135                 ALOGW("Requesting an IDR frame failed.");
   7136             }
   7137 
   7138             handled = true;
   7139             break;
   7140         }
   7141 
   7142         case kWhatSetParameters:
   7143         {
   7144             sp<AMessage> params;
   7145             CHECK(msg->findMessage("params", &params));
   7146 
   7147             status_t err = mCodec->setParameters(params);
   7148 
   7149             sp<AMessage> reply;
   7150             if (msg->findMessage("reply", &reply)) {
   7151                 reply->setInt32("err", err);
   7152                 reply->post();
   7153             }
   7154 
   7155             handled = true;
   7156             break;
   7157         }
   7158 
   7159         case ACodec::kWhatSignalEndOfInputStream:
   7160         {
   7161             mCodec->onSignalEndOfInputStream();
   7162             handled = true;
   7163             break;
   7164         }
   7165 
   7166         // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
   7167         case kWhatSubmitOutputMetadataBufferIfEOS:
   7168         {
   7169             if (mCodec->mPortEOS[kPortIndexInput] &&
   7170                     !mCodec->mPortEOS[kPortIndexOutput]) {
   7171                 status_t err = mCodec->submitOutputMetadataBuffer();
   7172                 if (err == OK) {
   7173                     mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround();
   7174                 }
   7175             }
   7176             return true;
   7177         }
   7178 
   7179         default:
   7180             handled = BaseState::onMessageReceived(msg);
   7181             break;
   7182     }
   7183 
   7184     return handled;
   7185 }
   7186 
   7187 status_t ACodec::setParameters(const sp<AMessage> &params) {
   7188     int32_t videoBitrate;
   7189     if (params->findInt32("video-bitrate", &videoBitrate)) {
   7190         OMX_VIDEO_CONFIG_BITRATETYPE configParams;
   7191         InitOMXParams(&configParams);
   7192         configParams.nPortIndex = kPortIndexOutput;
   7193         configParams.nEncodeBitrate = videoBitrate;
   7194 
   7195         status_t err = mOMXNode->setConfig(
   7196                 OMX_IndexConfigVideoBitrate,
   7197                 &configParams,
   7198                 sizeof(configParams));
   7199 
   7200         if (err != OK) {
   7201             ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
   7202                    videoBitrate, err);
   7203 
   7204             return err;
   7205         }
   7206     }
   7207 
   7208     int64_t timeOffsetUs;
   7209     if (params->findInt64("time-offset-us", &timeOffsetUs)) {
   7210         if (mGraphicBufferSource == NULL) {
   7211             ALOGE("[%s] Invalid to set input buffer time offset without surface",
   7212                     mComponentName.c_str());
   7213             return INVALID_OPERATION;
   7214         }
   7215 
   7216         status_t err = statusFromBinderStatus(
   7217                 mGraphicBufferSource->setTimeOffsetUs(timeOffsetUs));
   7218 
   7219         if (err != OK) {
   7220             ALOGE("[%s] Unable to set input buffer time offset (err %d)",
   7221                 mComponentName.c_str(),
   7222                 err);
   7223             return err;
   7224         }
   7225     }
   7226 
   7227     int64_t skipFramesBeforeUs;
   7228     if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
   7229         if (mGraphicBufferSource == NULL) {
   7230             ALOGE("[%s] Invalid to set start time without surface",
   7231                     mComponentName.c_str());
   7232             return INVALID_OPERATION;
   7233         }
   7234 
   7235         status_t err = statusFromBinderStatus(
   7236                 mGraphicBufferSource->setStartTimeUs(skipFramesBeforeUs));
   7237 
   7238         if (err != OK) {
   7239             ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err);
   7240             return err;
   7241         }
   7242     }
   7243 
   7244     int32_t dropInputFrames;
   7245     if (params->findInt32("drop-input-frames", &dropInputFrames)) {
   7246         if (mGraphicBufferSource == NULL) {
   7247             ALOGE("[%s] Invalid to set suspend without surface",
   7248                     mComponentName.c_str());
   7249             return INVALID_OPERATION;
   7250         }
   7251 
   7252         int64_t suspendStartTimeUs = -1;
   7253         (void) params->findInt64("drop-start-time-us", &suspendStartTimeUs);
   7254         status_t err = statusFromBinderStatus(
   7255                 mGraphicBufferSource->setSuspend(dropInputFrames != 0, suspendStartTimeUs));
   7256 
   7257         if (err != OK) {
   7258             ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
   7259             return err;
   7260         }
   7261     }
   7262 
   7263     int64_t stopTimeUs;
   7264     if (params->findInt64("stop-time-us", &stopTimeUs)) {
   7265         if (mGraphicBufferSource == NULL) {
   7266             ALOGE("[%s] Invalid to set stop time without surface",
   7267                     mComponentName.c_str());
   7268             return INVALID_OPERATION;
   7269         }
   7270         status_t err = statusFromBinderStatus(
   7271                 mGraphicBufferSource->setStopTimeUs(stopTimeUs));
   7272 
   7273         if (err != OK) {
   7274             ALOGE("Failed to set parameter 'stop-time-us' (err %d)", err);
   7275             return err;
   7276         }
   7277 
   7278         int64_t stopTimeOffsetUs;
   7279         err = statusFromBinderStatus(
   7280                 mGraphicBufferSource->getStopTimeOffsetUs(&stopTimeOffsetUs));
   7281 
   7282         if (err != OK) {
   7283             ALOGE("Failed to get stop time offset (err %d)", err);
   7284             return err;
   7285         }
   7286         mInputFormat->setInt64("android._stop-time-offset-us", stopTimeOffsetUs);
   7287     }
   7288 
   7289     int32_t dummy;
   7290     if (params->findInt32("request-sync", &dummy)) {
   7291         status_t err = requestIDRFrame();
   7292 
   7293         if (err != OK) {
   7294             ALOGE("Requesting a sync frame failed w/ err %d", err);
   7295             return err;
   7296         }
   7297     }
   7298 
   7299     float rate;
   7300     if (params->findFloat("operating-rate", &rate) && rate > 0) {
   7301         status_t err = setOperatingRate(rate, mIsVideo);
   7302         if (err != OK) {
   7303             ALOGE("Failed to set parameter 'operating-rate' (err %d)", err);
   7304             return err;
   7305         }
   7306     }
   7307 
   7308     int32_t intraRefreshPeriod = 0;
   7309     if (params->findInt32("intra-refresh-period", &intraRefreshPeriod)
   7310             && intraRefreshPeriod > 0) {
   7311         status_t err = setIntraRefreshPeriod(intraRefreshPeriod, false);
   7312         if (err != OK) {
   7313             ALOGI("[%s] failed setIntraRefreshPeriod. Failure is fine since this key is optional",
   7314                     mComponentName.c_str());
   7315             err = OK;
   7316         }
   7317     }
   7318 
   7319     int32_t latency = 0;
   7320     if (params->findInt32("latency", &latency) && latency > 0) {
   7321         status_t err = setLatency(latency);
   7322         if (err != OK) {
   7323             ALOGI("[%s] failed setLatency. Failure is fine since this key is optional",
   7324                     mComponentName.c_str());
   7325             err = OK;
   7326         }
   7327     }
   7328 
   7329     status_t err = configureTemporalLayers(params, false /* inConfigure */, mOutputFormat);
   7330     if (err != OK) {
   7331         err = OK; // ignore failure
   7332     }
   7333 
   7334     return setVendorParameters(params);
   7335 }
   7336 
   7337 // Removes trailing tags matching |tag| from |key| (e.g. a settings name). |minLength| specifies
   7338 // the minimum number of characters to keep in |key| (even if it has trailing tags).
   7339 // (Used to remove trailing 'value' tags in settings names, e.g. to normalize
   7340 // 'vendor.settingsX.value' to 'vendor.settingsX')
   7341 static void removeTrailingTags(char *key, size_t minLength, const char *tag) {
   7342     size_t length = strlen(key);
   7343     size_t tagLength = strlen(tag);
   7344     while (length > minLength + tagLength
   7345             && !strcmp(key + length - tagLength, tag)
   7346             && key[length - tagLength - 1] == '.') {
   7347         length -= tagLength + 1;
   7348         key[length] = '\0';
   7349     }
   7350 }
   7351 
   7352 /**
   7353  * Struct encompassing a vendor extension config structure and a potential error status (in case
   7354  * the structure is null). Used to iterate through vendor extensions.
   7355  */
   7356 struct VendorExtension {
   7357     OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *config;  // structure does not own config
   7358     status_t status;
   7359 
   7360     // create based on an error status
   7361     VendorExtension(status_t s_ = NO_INIT) : config(nullptr), status(s_) { }
   7362 
   7363     // create based on a successfully retrieved config structure
   7364     VendorExtension(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *c_) : config(c_), status(OK) { }
   7365 };
   7366 
   7367 // class VendorExtensions;
   7368 /**
   7369  * Forward iterator to enumerate vendor extensions supported by an OMX component.
   7370  */
   7371 class VendorExtensionIterator {
   7372 //private:
   7373     static constexpr size_t kLastIndex = ~(size_t)0; // last index marker
   7374 
   7375     sp<IOMXNode> mNode;                   // component
   7376     size_t mIndex;                        // current android extension index
   7377     std::unique_ptr<uint8_t[]> mBacking;  // current extension's backing
   7378     VendorExtension mCurrent;             // current extension
   7379 
   7380     VendorExtensionIterator(const sp<IOMXNode> &node, size_t index)
   7381         : mNode(node),
   7382           mIndex(index) {
   7383         mCurrent = retrieve();
   7384     }
   7385 
   7386     friend class VendorExtensions;
   7387 
   7388 public:
   7389     // copy constructor
   7390     VendorExtensionIterator(const VendorExtensionIterator &it)
   7391         : VendorExtensionIterator(it.mNode, it.mIndex) { }
   7392 
   7393     // retrieves the current extension pointed to by this iterator
   7394     VendorExtension retrieve() {
   7395         if (mIndex == kLastIndex) {
   7396             return NO_INIT;
   7397         }
   7398 
   7399         // try with one param first, then retry if extension needs more than 1 param
   7400         for (size_t paramSizeUsed = 1;; ) {
   7401             if (paramSizeUsed > OMX_MAX_ANDROID_VENDOR_PARAMCOUNT) {
   7402                 return BAD_VALUE; // this prevents overflow in the following formula
   7403             }
   7404 
   7405             size_t size = sizeof(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE) +
   7406                 (paramSizeUsed - 1) * sizeof(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE::param);
   7407             mBacking.reset(new uint8_t[size]);
   7408             if (!mBacking) {
   7409                 return NO_MEMORY;
   7410             }
   7411 
   7412             OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *config =
   7413                 reinterpret_cast<OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *>(mBacking.get());
   7414 
   7415             InitOMXParams(config);
   7416             config->nSize = size;
   7417             config->nIndex = mIndex;
   7418             config->nParamSizeUsed = paramSizeUsed;
   7419             status_t err = mNode->getConfig(
   7420                     (OMX_INDEXTYPE)OMX_IndexConfigAndroidVendorExtension, config, size);
   7421             if (err == OK && config->nParamCount > paramSizeUsed && paramSizeUsed == 1) {
   7422                 // reallocate if we need a bigger config
   7423                 paramSizeUsed = config->nParamCount;
   7424                 continue;
   7425             } else if (err == NOT_ENOUGH_DATA
   7426                    || (err != OK && mIndex == 0)) {
   7427                 // stop iterator on no-more signal, or if index is not at all supported
   7428                 mIndex = kLastIndex;
   7429                 return NO_INIT;
   7430             } else if (err != OK) {
   7431                 return err;
   7432             } else if (paramSizeUsed != config->nParamSizeUsed) {
   7433                 return BAD_VALUE; // component shall not modify size of nParam
   7434             }
   7435 
   7436             return config;
   7437         }
   7438     }
   7439 
   7440     // returns extension pointed to by this iterator
   7441     VendorExtension operator*() {
   7442         return mCurrent;
   7443     }
   7444 
   7445     // prefix increment: move to next extension
   7446     VendorExtensionIterator &operator++() { // prefix
   7447         if (mIndex != kLastIndex) {
   7448             ++mIndex;
   7449             mCurrent = retrieve();
   7450         }
   7451         return *this;
   7452     }
   7453 
   7454     // iterator equality operators
   7455     bool operator==(const VendorExtensionIterator &o) {
   7456         return mNode == o.mNode && mIndex == o.mIndex;
   7457     }
   7458 
   7459     bool operator!=(const VendorExtensionIterator &o) {
   7460         return !(*this == o);
   7461     }
   7462 };
   7463 
   7464 /**
   7465  * Iterable container for vendor extensions provided by a component
   7466  */
   7467 class VendorExtensions {
   7468 //private:
   7469     sp<IOMXNode> mNode;
   7470 
   7471 public:
   7472     VendorExtensions(const sp<IOMXNode> &node)
   7473         : mNode(node) {
   7474     }
   7475 
   7476     VendorExtensionIterator begin() {
   7477         return VendorExtensionIterator(mNode, 0);
   7478     }
   7479 
   7480     VendorExtensionIterator end() {
   7481         return VendorExtensionIterator(mNode, VendorExtensionIterator::kLastIndex);
   7482     }
   7483 };
   7484 
   7485 status_t ACodec::setVendorParameters(const sp<AMessage> &params) {
   7486     std::map<std::string, std::string> vendorKeys; // maps reduced name to actual name
   7487     constexpr char prefix[] = "vendor.";
   7488     constexpr size_t prefixLength = sizeof(prefix) - 1;
   7489     // longest possible vendor param name
   7490     char reducedKey[OMX_MAX_STRINGNAME_SIZE + OMX_MAX_STRINGVALUE_SIZE];
   7491 
   7492     // identify all vendor keys to speed up search later and to detect vendor keys
   7493     for (size_t i = params->countEntries(); i; --i) {
   7494         AMessage::Type keyType;
   7495         const char* key = params->getEntryNameAt(i - 1, &keyType);
   7496         if (key != nullptr && !strncmp(key, prefix, prefixLength)
   7497                 // it is safe to limit format keys to the max vendor param size as we only
   7498                 // shorten parameter names by removing any trailing 'value' tags, and we
   7499                 // already remove the vendor prefix.
   7500                 && strlen(key + prefixLength) < sizeof(reducedKey)
   7501                 && (keyType == AMessage::kTypeInt32
   7502                         || keyType == AMessage::kTypeInt64
   7503                         || keyType == AMessage::kTypeString)) {
   7504             strcpy(reducedKey, key + prefixLength);
   7505             removeTrailingTags(reducedKey, 0, "value");
   7506             auto existingKey = vendorKeys.find(reducedKey);
   7507             if (existingKey != vendorKeys.end()) {
   7508                 ALOGW("[%s] vendor parameter '%s' aliases parameter '%s'",
   7509                         mComponentName.c_str(), key, existingKey->second.c_str());
   7510                 // ignore for now
   7511             }
   7512             vendorKeys.emplace(reducedKey, key);
   7513         }
   7514     }
   7515 
   7516     // don't bother component if we don't have vendor extensions as they may not have implemented
   7517     // the android vendor extension support, which will lead to unnecessary OMX failure logs.
   7518     if (vendorKeys.empty()) {
   7519         return OK;
   7520     }
   7521 
   7522     char key[sizeof(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE::cName) +
   7523             sizeof(OMX_CONFIG_ANDROID_VENDOR_PARAMTYPE::cKey)];
   7524 
   7525     status_t finalError = OK;
   7526 
   7527     // don't try again if component does not have vendor extensions
   7528     if (mVendorExtensionsStatus == kExtensionsNone) {
   7529         return OK;
   7530     }
   7531 
   7532     for (VendorExtension ext : VendorExtensions(mOMXNode)) {
   7533         OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *config = ext.config;
   7534         if (config == nullptr) {
   7535             return ext.status;
   7536         }
   7537 
   7538         mVendorExtensionsStatus = kExtensionsExist;
   7539 
   7540         config->cName[sizeof(config->cName) - 1] = '\0'; // null-terminate name
   7541         strcpy(key, (const char *)config->cName);
   7542         size_t nameLength = strlen(key);
   7543         key[nameLength] = '.';
   7544 
   7545         // don't set vendor extension if client has not provided any of its parameters
   7546         // or if client simply unsets parameters that are already unset
   7547         bool needToSet = false;
   7548         for (size_t paramIndex = 0; paramIndex < config->nParamCount; ++paramIndex) {
   7549             // null-terminate param key
   7550             config->param[paramIndex].cKey[sizeof(config->param[0].cKey) - 1] = '\0';
   7551             strcpy(key + nameLength + 1, (const char *)config->param[paramIndex].cKey);
   7552             removeTrailingTags(key, nameLength, "value");
   7553             auto existingKey = vendorKeys.find(key);
   7554 
   7555             // don't touch (e.g. change) parameters that are not specified by client
   7556             if (existingKey == vendorKeys.end()) {
   7557                 continue;
   7558             }
   7559 
   7560             bool wasSet = config->param[paramIndex].bSet;
   7561             switch (config->param[paramIndex].eValueType) {
   7562             case OMX_AndroidVendorValueInt32:
   7563             {
   7564                 int32_t value;
   7565                 config->param[paramIndex].bSet =
   7566                     (OMX_BOOL)params->findInt32(existingKey->second.c_str(), &value);
   7567                 if (config->param[paramIndex].bSet) {
   7568                     config->param[paramIndex].nInt32 = value;
   7569                 }
   7570                 break;
   7571             }
   7572             case OMX_AndroidVendorValueInt64:
   7573             {
   7574                 int64_t value;
   7575                 config->param[paramIndex].bSet =
   7576                     (OMX_BOOL)params->findAsInt64(existingKey->second.c_str(), &value);
   7577                 if (config->param[paramIndex].bSet) {
   7578                     config->param[paramIndex].nInt64 = value;
   7579                 }
   7580                 break;
   7581             }
   7582             case OMX_AndroidVendorValueString:
   7583             {
   7584                 AString value;
   7585                 config->param[paramIndex].bSet =
   7586                     (OMX_BOOL)params->findString(existingKey->second.c_str(), &value);
   7587                 if (config->param[paramIndex].bSet) {
   7588                     strncpy((char *)config->param[paramIndex].cString, value.c_str(),
   7589                             sizeof(OMX_CONFIG_ANDROID_VENDOR_PARAMTYPE::cString));
   7590                 }
   7591                 break;
   7592             }
   7593             default:
   7594                 ALOGW("[%s] vendor parameter '%s' is not a supported value",
   7595                         mComponentName.c_str(), key);
   7596                 continue;
   7597             }
   7598             if (config->param[paramIndex].bSet || wasSet) {
   7599                 needToSet = true;
   7600             }
   7601         }
   7602 
   7603         if (needToSet) {
   7604             status_t err = mOMXNode->setConfig(
   7605                     (OMX_INDEXTYPE)OMX_IndexConfigAndroidVendorExtension,
   7606                     config, config->nSize);
   7607             if (err != OK) {
   7608                 key[nameLength] = '\0';
   7609                 ALOGW("[%s] failed to set vendor extension '%s'", mComponentName.c_str(), key);
   7610                 // try to set each extension, and return first failure
   7611                 if (finalError == OK) {
   7612                     finalError = err;
   7613                 }
   7614             }
   7615         }
   7616     }
   7617 
   7618     if (mVendorExtensionsStatus == kExtensionsUnchecked) {
   7619         mVendorExtensionsStatus = kExtensionsNone;
   7620     }
   7621 
   7622     return finalError;
   7623 }
   7624 
   7625 status_t ACodec::getVendorParameters(OMX_U32 portIndex, sp<AMessage> &format) {
   7626     constexpr char prefix[] = "vendor.";
   7627     constexpr size_t prefixLength = sizeof(prefix) - 1;
   7628     char key[sizeof(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE::cName) +
   7629             sizeof(OMX_CONFIG_ANDROID_VENDOR_PARAMTYPE::cKey) + prefixLength];
   7630     strcpy(key, prefix);
   7631 
   7632     // don't try again if component does not have vendor extensions
   7633     if (mVendorExtensionsStatus == kExtensionsNone) {
   7634         return OK;
   7635     }
   7636 
   7637     for (VendorExtension ext : VendorExtensions(mOMXNode)) {
   7638         OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *config = ext.config;
   7639         if (config == nullptr) {
   7640             return ext.status;
   7641         }
   7642 
   7643         mVendorExtensionsStatus = kExtensionsExist;
   7644 
   7645         if (config->eDir != (portIndex == kPortIndexInput ? OMX_DirInput : OMX_DirOutput)) {
   7646             continue;
   7647         }
   7648 
   7649         config->cName[sizeof(config->cName) - 1] = '\0'; // null-terminate name
   7650         strcpy(key + prefixLength, (const char *)config->cName);
   7651         size_t nameLength = strlen(key);
   7652         key[nameLength] = '.';
   7653 
   7654         for (size_t paramIndex = 0; paramIndex < config->nParamCount; ++paramIndex) {
   7655             // null-terminate param key
   7656             config->param[paramIndex].cKey[sizeof(config->param[0].cKey) - 1] = '\0';
   7657             strcpy(key + nameLength + 1, (const char *)config->param[paramIndex].cKey);
   7658             removeTrailingTags(key, nameLength, "value");
   7659             if (config->param[paramIndex].bSet) {
   7660                 switch (config->param[paramIndex].eValueType) {
   7661                 case OMX_AndroidVendorValueInt32:
   7662                 {
   7663                     format->setInt32(key, config->param[paramIndex].nInt32);
   7664                     break;
   7665                 }
   7666                 case OMX_AndroidVendorValueInt64:
   7667                 {
   7668                     format->setInt64(key, config->param[paramIndex].nInt64);
   7669                     break;
   7670                 }
   7671                 case OMX_AndroidVendorValueString:
   7672                 {
   7673                     config->param[paramIndex].cString[OMX_MAX_STRINGVALUE_SIZE - 1] = '\0';
   7674                     format->setString(key, (const char *)config->param[paramIndex].cString);
   7675                     break;
   7676                 }
   7677                 default:
   7678                     ALOGW("vendor parameter %s is not a supported value", key);
   7679                     continue;
   7680                 }
   7681             }
   7682         }
   7683     }
   7684 
   7685     if (mVendorExtensionsStatus == kExtensionsUnchecked) {
   7686         mVendorExtensionsStatus = kExtensionsNone;
   7687     }
   7688 
   7689     return OK;
   7690 }
   7691 
   7692 void ACodec::onSignalEndOfInputStream() {
   7693     status_t err = INVALID_OPERATION;
   7694     if (mGraphicBufferSource != NULL) {
   7695         err = statusFromBinderStatus(mGraphicBufferSource->signalEndOfInputStream());
   7696     }
   7697     mCallback->onSignaledInputEOS(err);
   7698 }
   7699 
   7700 void ACodec::forceStateTransition(int generation) {
   7701     if (generation != mStateGeneration) {
   7702         ALOGV("Ignoring stale force state transition message: #%d (now #%d)",
   7703                 generation, mStateGeneration);
   7704         return;
   7705     }
   7706     ALOGE("State machine stuck");
   7707     // Error must have already been signalled to the client.
   7708 
   7709     // Deferred messages will be handled at LoadedState at the end of the
   7710     // transition.
   7711     mShutdownInProgress = true;
   7712     // No shutdown complete callback at the end of the transition.
   7713     mExplicitShutdown = false;
   7714     mKeepComponentAllocated = true;
   7715 
   7716     status_t err = mOMXNode->sendCommand(OMX_CommandStateSet, OMX_StateIdle);
   7717     if (err != OK) {
   7718         // TODO: do some recovery here.
   7719     } else {
   7720         changeState(mExecutingToIdleState);
   7721     }
   7722 }
   7723 
   7724 bool ACodec::ExecutingState::onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano) {
   7725     mCodec->onFrameRendered(mediaTimeUs, systemNano);
   7726     return true;
   7727 }
   7728 
   7729 bool ACodec::ExecutingState::onOMXEvent(
   7730         OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
   7731     switch (event) {
   7732         case OMX_EventPortSettingsChanged:
   7733         {
   7734             CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
   7735 
   7736             mCodec->onOutputFormatChanged();
   7737 
   7738             if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
   7739                 mCodec->mMetadataBuffersToSubmit = 0;
   7740                 CHECK_EQ(mCodec->mOMXNode->sendCommand(
   7741                             OMX_CommandPortDisable, kPortIndexOutput),
   7742                          (status_t)OK);
   7743 
   7744                 mCodec->freeOutputBuffersNotOwnedByComponent();
   7745 
   7746                 mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
   7747             } else if (data2 != OMX_IndexConfigCommonOutputCrop
   7748                     && data2 != OMX_IndexConfigAndroidIntraRefresh) {
   7749                 ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08x",
   7750                      mCodec->mComponentName.c_str(), data2);
   7751             }
   7752 
   7753             return true;
   7754         }
   7755 
   7756         case OMX_EventBufferFlag:
   7757         {
   7758             return true;
   7759         }
   7760 
   7761         default:
   7762             return BaseState::onOMXEvent(event, data1, data2);
   7763     }
   7764 }
   7765 
   7766 ////////////////////////////////////////////////////////////////////////////////
   7767 
   7768 ACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
   7769         ACodec *codec)
   7770     : BaseState(codec) {
   7771 }
   7772 
   7773 ACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
   7774         OMX_U32 portIndex) {
   7775     if (portIndex == kPortIndexOutput) {
   7776         return FREE_BUFFERS;
   7777     }
   7778 
   7779     CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
   7780 
   7781     return RESUBMIT_BUFFERS;
   7782 }
   7783 
   7784 bool ACodec::OutputPortSettingsChangedState::onMessageReceived(
   7785         const sp<AMessage> &msg) {
   7786     bool handled = false;
   7787 
   7788     switch (msg->what()) {
   7789         case kWhatFlush:
   7790         case kWhatShutdown: {
   7791             if (mCodec->mFatalError) {
   7792                 sp<AMessage> msg = new AMessage(ACodec::kWhatForceStateTransition, mCodec);
   7793                 msg->setInt32("generation", mCodec->mStateGeneration);
   7794                 msg->post(3000000);
   7795             }
   7796             // fall-through
   7797         }
   7798         case kWhatResume:
   7799         case kWhatSetParameters:
   7800         {
   7801             if (msg->what() == kWhatResume) {
   7802                 ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
   7803             }
   7804 
   7805             mCodec->deferMessage(msg);
   7806             handled = true;
   7807             break;
   7808         }
   7809 
   7810         case kWhatForceStateTransition:
   7811         {
   7812             int32_t generation = 0;
   7813             CHECK(msg->findInt32("generation", &generation));
   7814             mCodec->forceStateTransition(generation);
   7815 
   7816             handled = true;
   7817             break;
   7818         }
   7819 
   7820         default:
   7821             handled = BaseState::onMessageReceived(msg);
   7822             break;
   7823     }
   7824 
   7825     return handled;
   7826 }
   7827 
   7828 void ACodec::OutputPortSettingsChangedState::stateEntered() {
   7829     ALOGV("[%s] Now handling output port settings change",
   7830          mCodec->mComponentName.c_str());
   7831 }
   7832 
   7833 bool ACodec::OutputPortSettingsChangedState::onOMXFrameRendered(
   7834         int64_t mediaTimeUs, nsecs_t systemNano) {
   7835     mCodec->onFrameRendered(mediaTimeUs, systemNano);
   7836     return true;
   7837 }
   7838 
   7839 bool ACodec::OutputPortSettingsChangedState::onOMXEvent(
   7840         OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
   7841     switch (event) {
   7842         case OMX_EventCmdComplete:
   7843         {
   7844             if (data1 == (OMX_U32)OMX_CommandPortDisable) {
   7845                 if (data2 != (OMX_U32)kPortIndexOutput) {
   7846                     ALOGW("ignoring EventCmdComplete CommandPortDisable for port %u", data2);
   7847                     return false;
   7848                 }
   7849 
   7850                 ALOGV("[%s] Output port now disabled.", mCodec->mComponentName.c_str());
   7851 
   7852                 status_t err = OK;
   7853                 if (!mCodec->mBuffers[kPortIndexOutput].isEmpty()) {
   7854                     ALOGE("disabled port should be empty, but has %zu buffers",
   7855                             mCodec->mBuffers[kPortIndexOutput].size());
   7856                     err = FAILED_TRANSACTION;
   7857                 } else {
   7858                     if (mCodec->getTrebleFlag()) {
   7859                         mCodec->mAllocator[kPortIndexOutput].clear();
   7860                     } else {
   7861                         mCodec->mDealer[kPortIndexOutput].clear();
   7862                     }
   7863                 }
   7864 
   7865                 if (err == OK) {
   7866                     err = mCodec->mOMXNode->sendCommand(
   7867                             OMX_CommandPortEnable, kPortIndexOutput);
   7868                 }
   7869 
   7870                 if (err == OK) {
   7871                     err = mCodec->allocateBuffersOnPort(kPortIndexOutput);
   7872                     ALOGE_IF(err != OK, "Failed to allocate output port buffers after port "
   7873                             "reconfiguration: (%d)", err);
   7874                     mCodec->mCallback->onOutputBuffersChanged();
   7875                 }
   7876 
   7877                 if (err != OK) {
   7878                     mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
   7879                     ALOGE("Error occurred while disabling the output port");
   7880                 }
   7881 
   7882                 return true;
   7883             } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
   7884                 if (data2 != (OMX_U32)kPortIndexOutput) {
   7885                     ALOGW("ignoring EventCmdComplete OMX_CommandPortEnable for port %u", data2);
   7886                     return false;
   7887                 }
   7888 
   7889                 ALOGV("[%s] Output port now reenabled.", mCodec->mComponentName.c_str());
   7890 
   7891                 if (mCodec->mExecutingState->active()) {
   7892                     mCodec->mExecutingState->submitOutputBuffers();
   7893                 }
   7894 
   7895                 mCodec->changeState(mCodec->mExecutingState);
   7896 
   7897                 return true;
   7898             }
   7899 
   7900             return false;
   7901         }
   7902 
   7903         default:
   7904             return BaseState::onOMXEvent(event, data1, data2);
   7905     }
   7906 }
   7907 
   7908 ////////////////////////////////////////////////////////////////////////////////
   7909 
   7910 ACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
   7911     : BaseState(codec),
   7912       mComponentNowIdle(false) {
   7913 }
   7914 
   7915 bool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
   7916     bool handled = false;
   7917 
   7918     switch (msg->what()) {
   7919         case kWhatFlush:
   7920         {
   7921             // Don't send me a flush request if you previously wanted me
   7922             // to shutdown.
   7923             ALOGW("Ignoring flush request in ExecutingToIdleState");
   7924             break;
   7925         }
   7926 
   7927         case kWhatShutdown:
   7928         {
   7929             mCodec->deferMessage(msg);
   7930             handled = true;
   7931             break;
   7932         }
   7933 
   7934         default:
   7935             handled = BaseState::onMessageReceived(msg);
   7936             break;
   7937     }
   7938 
   7939     return handled;
   7940 }
   7941 
   7942 void ACodec::ExecutingToIdleState::stateEntered() {
   7943     ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
   7944 
   7945     mComponentNowIdle = false;
   7946     mCodec->mLastOutputFormat.clear();
   7947 }
   7948 
   7949 bool ACodec::ExecutingToIdleState::onOMXEvent(
   7950         OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
   7951     switch (event) {
   7952         case OMX_EventCmdComplete:
   7953         {
   7954             if (data1 != (OMX_U32)OMX_CommandStateSet
   7955                     || data2 != (OMX_U32)OMX_StateIdle) {
   7956                 ALOGE("Unexpected command completion in ExecutingToIdleState: %s(%u) %s(%u)",
   7957                         asString((OMX_COMMANDTYPE)data1), data1,
   7958                         asString((OMX_STATETYPE)data2), data2);
   7959                 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
   7960                 return true;
   7961             }
   7962 
   7963             mComponentNowIdle = true;
   7964 
   7965             changeStateIfWeOwnAllBuffers();
   7966 
   7967             return true;
   7968         }
   7969 
   7970         case OMX_EventPortSettingsChanged:
   7971         case OMX_EventBufferFlag:
   7972         {
   7973             // We're shutting down and don't care about this anymore.
   7974             return true;
   7975         }
   7976 
   7977         default:
   7978             return BaseState::onOMXEvent(event, data1, data2);
   7979     }
   7980 }
   7981 
   7982 void ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
   7983     if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
   7984         status_t err = mCodec->mOMXNode->sendCommand(
   7985                 OMX_CommandStateSet, OMX_StateLoaded);
   7986         if (err == OK) {
   7987             err = mCodec->freeBuffersOnPort(kPortIndexInput);
   7988             status_t err2 = mCodec->freeBuffersOnPort(kPortIndexOutput);
   7989             if (err == OK) {
   7990                 err = err2;
   7991             }
   7992         }
   7993 
   7994         if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
   7995                 && mCodec->mNativeWindow != NULL) {
   7996             // We push enough 1x1 blank buffers to ensure that one of
   7997             // them has made it to the display.  This allows the OMX
   7998             // component teardown to zero out any protected buffers
   7999             // without the risk of scanning out one of those buffers.
   8000             pushBlankBuffersToNativeWindow(mCodec->mNativeWindow.get());
   8001         }
   8002 
   8003         if (err != OK) {
   8004             mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
   8005             return;
   8006         }
   8007 
   8008         mCodec->changeState(mCodec->mIdleToLoadedState);
   8009     }
   8010 }
   8011 
   8012 void ACodec::ExecutingToIdleState::onInputBufferFilled(
   8013         const sp<AMessage> &msg) {
   8014     BaseState::onInputBufferFilled(msg);
   8015 
   8016     changeStateIfWeOwnAllBuffers();
   8017 }
   8018 
   8019 void ACodec::ExecutingToIdleState::onOutputBufferDrained(
   8020         const sp<AMessage> &msg) {
   8021     BaseState::onOutputBufferDrained(msg);
   8022 
   8023     changeStateIfWeOwnAllBuffers();
   8024 }
   8025 
   8026 ////////////////////////////////////////////////////////////////////////////////
   8027 
   8028 ACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
   8029     : BaseState(codec) {
   8030 }
   8031 
   8032 bool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
   8033     bool handled = false;
   8034 
   8035     switch (msg->what()) {
   8036         case kWhatShutdown:
   8037         {
   8038             mCodec->deferMessage(msg);
   8039             handled = true;
   8040             break;
   8041         }
   8042 
   8043         case kWhatFlush:
   8044         {
   8045             // Don't send me a flush request if you previously wanted me
   8046             // to shutdown.
   8047             ALOGE("Got flush request in IdleToLoadedState");
   8048             break;
   8049         }
   8050 
   8051         default:
   8052             handled = BaseState::onMessageReceived(msg);
   8053             break;
   8054     }
   8055 
   8056     return handled;
   8057 }
   8058 
   8059 void ACodec::IdleToLoadedState::stateEntered() {
   8060     ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
   8061 }
   8062 
   8063 bool ACodec::IdleToLoadedState::onOMXEvent(
   8064         OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
   8065     switch (event) {
   8066         case OMX_EventCmdComplete:
   8067         {
   8068             if (data1 != (OMX_U32)OMX_CommandStateSet
   8069                     || data2 != (OMX_U32)OMX_StateLoaded) {
   8070                 ALOGE("Unexpected command completion in IdleToLoadedState: %s(%u) %s(%u)",
   8071                         asString((OMX_COMMANDTYPE)data1), data1,
   8072                         asString((OMX_STATETYPE)data2), data2);
   8073                 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
   8074                 return true;
   8075             }
   8076 
   8077             mCodec->changeState(mCodec->mLoadedState);
   8078 
   8079             return true;
   8080         }
   8081 
   8082         default:
   8083             return BaseState::onOMXEvent(event, data1, data2);
   8084     }
   8085 }
   8086 
   8087 ////////////////////////////////////////////////////////////////////////////////
   8088 
   8089 ACodec::FlushingState::FlushingState(ACodec *codec)
   8090     : BaseState(codec) {
   8091 }
   8092 
   8093 void ACodec::FlushingState::stateEntered() {
   8094     ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
   8095 
   8096     mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
   8097 }
   8098 
   8099 bool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
   8100     bool handled = false;
   8101 
   8102     switch (msg->what()) {
   8103         case kWhatShutdown:
   8104         {
   8105             mCodec->deferMessage(msg);
   8106             if (mCodec->mFatalError) {
   8107                 sp<AMessage> msg = new AMessage(ACodec::kWhatForceStateTransition, mCodec);
   8108                 msg->setInt32("generation", mCodec->mStateGeneration);
   8109                 msg->post(3000000);
   8110             }
   8111             break;
   8112         }
   8113 
   8114         case kWhatFlush:
   8115         {
   8116             // We're already doing this right now.
   8117             handled = true;
   8118             break;
   8119         }
   8120 
   8121         case kWhatForceStateTransition:
   8122         {
   8123             int32_t generation = 0;
   8124             CHECK(msg->findInt32("generation", &generation));
   8125             mCodec->forceStateTransition(generation);
   8126 
   8127             handled = true;
   8128             break;
   8129         }
   8130 
   8131         default:
   8132             handled = BaseState::onMessageReceived(msg);
   8133             break;
   8134     }
   8135 
   8136     return handled;
   8137 }
   8138 
   8139 bool ACodec::FlushingState::onOMXEvent(
   8140         OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
   8141     ALOGV("[%s] FlushingState onOMXEvent(%u,%d)",
   8142             mCodec->mComponentName.c_str(), event, (OMX_S32)data1);
   8143 
   8144     switch (event) {
   8145         case OMX_EventCmdComplete:
   8146         {
   8147             if (data1 != (OMX_U32)OMX_CommandFlush) {
   8148                 ALOGE("unexpected EventCmdComplete %s(%d) data2:%d in FlushingState",
   8149                         asString((OMX_COMMANDTYPE)data1), data1, data2);
   8150                 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
   8151                 return true;
   8152             }
   8153 
   8154             if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
   8155                 if (mFlushComplete[data2]) {
   8156                     ALOGW("Flush already completed for %s port",
   8157                             data2 == kPortIndexInput ? "input" : "output");
   8158                     return true;
   8159                 }
   8160                 mFlushComplete[data2] = true;
   8161 
   8162                 if (mFlushComplete[kPortIndexInput] && mFlushComplete[kPortIndexOutput]) {
   8163                     changeStateIfWeOwnAllBuffers();
   8164                 }
   8165             } else if (data2 == OMX_ALL) {
   8166                 if (!mFlushComplete[kPortIndexInput] || !mFlushComplete[kPortIndexOutput]) {
   8167                     ALOGW("received flush complete event for OMX_ALL before ports have been"
   8168                             "flushed (%d/%d)",
   8169                             mFlushComplete[kPortIndexInput], mFlushComplete[kPortIndexOutput]);
   8170                     return false;
   8171                 }
   8172 
   8173                 changeStateIfWeOwnAllBuffers();
   8174             } else {
   8175                 ALOGW("data2 not OMX_ALL but %u in EventCmdComplete CommandFlush", data2);
   8176             }
   8177 
   8178             return true;
   8179         }
   8180 
   8181         case OMX_EventPortSettingsChanged:
   8182         {
   8183             sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec);
   8184             msg->setInt32("type", omx_message::EVENT);
   8185             msg->setInt32("generation", mCodec->mNodeGeneration);
   8186             msg->setInt32("event", event);
   8187             msg->setInt32("data1", data1);
   8188             msg->setInt32("data2", data2);
   8189 
   8190             ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
   8191                  mCodec->mComponentName.c_str());
   8192 
   8193             mCodec->deferMessage(msg);
   8194 
   8195             return true;
   8196         }
   8197 
   8198         default:
   8199             return BaseState::onOMXEvent(event, data1, data2);
   8200     }
   8201 
   8202     return true;
   8203 }
   8204 
   8205 void ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
   8206     BaseState::onOutputBufferDrained(msg);
   8207 
   8208     changeStateIfWeOwnAllBuffers();
   8209 }
   8210 
   8211 void ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
   8212     BaseState::onInputBufferFilled(msg);
   8213 
   8214     changeStateIfWeOwnAllBuffers();
   8215 }
   8216 
   8217 void ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
   8218     if (mFlushComplete[kPortIndexInput]
   8219             && mFlushComplete[kPortIndexOutput]
   8220             && mCodec->allYourBuffersAreBelongToUs()) {
   8221         // We now own all buffers except possibly those still queued with
   8222         // the native window for rendering. Let's get those back as well.
   8223         mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
   8224 
   8225         mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC));
   8226 
   8227         mCodec->mCallback->onFlushCompleted();
   8228 
   8229         mCodec->mPortEOS[kPortIndexInput] =
   8230             mCodec->mPortEOS[kPortIndexOutput] = false;
   8231 
   8232         mCodec->mInputEOSResult = OK;
   8233 
   8234         if (mCodec->mSkipCutBuffer != NULL) {
   8235             mCodec->mSkipCutBuffer->clear();
   8236         }
   8237 
   8238         mCodec->changeState(mCodec->mExecutingState);
   8239     }
   8240 }
   8241 
   8242 status_t ACodec::queryCapabilities(
   8243         const char* owner, const char* name, const char* mime, bool isEncoder,
   8244         MediaCodecInfo::CapabilitiesWriter* caps) {
   8245     const char *role = GetComponentRole(isEncoder, mime);
   8246     if (role == NULL) {
   8247         return BAD_VALUE;
   8248     }
   8249 
   8250     OMXClient client;
   8251     status_t err = client.connect(owner);
   8252     if (err != OK) {
   8253         return err;
   8254     }
   8255 
   8256     sp<IOMX> omx = client.interface();
   8257     sp<CodecObserver> observer = new CodecObserver;
   8258     sp<IOMXNode> omxNode;
   8259 
   8260     err = omx->allocateNode(name, observer, &omxNode);
   8261     if (err != OK) {
   8262         client.disconnect();
   8263         return err;
   8264     }
   8265 
   8266     err = SetComponentRole(omxNode, role);
   8267     if (err != OK) {
   8268         omxNode->freeNode();
   8269         client.disconnect();
   8270         return err;
   8271     }
   8272 
   8273     bool isVideo = strncasecmp(mime, "video/", 6) == 0;
   8274 
   8275     if (isVideo) {
   8276         OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
   8277         InitOMXParams(&param);
   8278         param.nPortIndex = isEncoder ? kPortIndexOutput : kPortIndexInput;
   8279 
   8280         for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
   8281             param.nProfileIndex = index;
   8282             status_t err = omxNode->getParameter(
   8283                     OMX_IndexParamVideoProfileLevelQuerySupported,
   8284                     &param, sizeof(param));
   8285             if (err != OK) {
   8286                 break;
   8287             }
   8288             caps->addProfileLevel(param.eProfile, param.eLevel);
   8289 
   8290             // AVC components may not list the constrained profiles explicitly, but
   8291             // decoders that support a profile also support its constrained version.
   8292             // Encoders must explicitly support constrained profiles.
   8293             if (!isEncoder && strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC) == 0) {
   8294                 if (param.eProfile == OMX_VIDEO_AVCProfileHigh) {
   8295                     caps->addProfileLevel(OMX_VIDEO_AVCProfileConstrainedHigh, param.eLevel);
   8296                 } else if (param.eProfile == OMX_VIDEO_AVCProfileBaseline) {
   8297                     caps->addProfileLevel(OMX_VIDEO_AVCProfileConstrainedBaseline, param.eLevel);
   8298                 }
   8299             }
   8300 
   8301             if (index == kMaxIndicesToCheck) {
   8302                 ALOGW("[%s] stopping checking profiles after %u: %x/%x",
   8303                         name, index,
   8304                         param.eProfile, param.eLevel);
   8305             }
   8306         }
   8307 
   8308         // Color format query
   8309         // return colors in the order reported by the OMX component
   8310         // prefix "flexible" standard ones with the flexible equivalent
   8311         OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat;
   8312         InitOMXParams(&portFormat);
   8313         portFormat.nPortIndex = isEncoder ? kPortIndexInput : kPortIndexOutput;
   8314         for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
   8315             portFormat.nIndex = index;
   8316             status_t err = omxNode->getParameter(
   8317                     OMX_IndexParamVideoPortFormat,
   8318                     &portFormat, sizeof(portFormat));
   8319             if (err != OK) {
   8320                 break;
   8321             }
   8322 
   8323             OMX_U32 flexibleEquivalent;
   8324             if (IsFlexibleColorFormat(
   8325                     omxNode, portFormat.eColorFormat, false /* usingNativeWindow */,
   8326                     &flexibleEquivalent)) {
   8327                 caps->addColorFormat(flexibleEquivalent);
   8328             }
   8329             caps->addColorFormat(portFormat.eColorFormat);
   8330 
   8331             if (index == kMaxIndicesToCheck) {
   8332                 ALOGW("[%s] stopping checking formats after %u: %s(%x)",
   8333                         name, index,
   8334                         asString(portFormat.eColorFormat), portFormat.eColorFormat);
   8335             }
   8336         }
   8337     } else if (strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC) == 0) {
   8338         // More audio codecs if they have profiles.
   8339         OMX_AUDIO_PARAM_ANDROID_PROFILETYPE param;
   8340         InitOMXParams(&param);
   8341         param.nPortIndex = isEncoder ? kPortIndexOutput : kPortIndexInput;
   8342         for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
   8343             param.nProfileIndex = index;
   8344             status_t err = omxNode->getParameter(
   8345                     (OMX_INDEXTYPE)OMX_IndexParamAudioProfileQuerySupported,
   8346                     &param, sizeof(param));
   8347             if (err != OK) {
   8348                 break;
   8349             }
   8350             // For audio, level is ignored.
   8351             caps->addProfileLevel(param.eProfile, 0 /* level */);
   8352 
   8353             if (index == kMaxIndicesToCheck) {
   8354                 ALOGW("[%s] stopping checking profiles after %u: %x",
   8355                         name, index,
   8356                         param.eProfile);
   8357             }
   8358         }
   8359 
   8360         // NOTE: Without Android extensions, OMX does not provide a way to query
   8361         // AAC profile support
   8362         if (param.nProfileIndex == 0) {
   8363             ALOGW("component %s doesn't support profile query.", name);
   8364         }
   8365     }
   8366 
   8367     if (isVideo && !isEncoder) {
   8368         native_handle_t *sidebandHandle = NULL;
   8369         if (omxNode->configureVideoTunnelMode(
   8370                 kPortIndexOutput, OMX_TRUE, 0, &sidebandHandle) == OK) {
   8371             // tunneled playback includes adaptive playback
   8372             caps->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsAdaptivePlayback
   8373                     | MediaCodecInfo::Capabilities::kFlagSupportsTunneledPlayback);
   8374         } else if (omxNode->setPortMode(
   8375                 kPortIndexOutput, IOMX::kPortModeDynamicANWBuffer) == OK ||
   8376                 omxNode->prepareForAdaptivePlayback(
   8377                 kPortIndexOutput, OMX_TRUE,
   8378                 1280 /* width */, 720 /* height */) == OK) {
   8379             caps->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsAdaptivePlayback);
   8380         }
   8381     }
   8382 
   8383     if (isVideo && isEncoder) {
   8384         OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params;
   8385         InitOMXParams(&params);
   8386         params.nPortIndex = kPortIndexOutput;
   8387         // TODO: should we verify if fallback is supported?
   8388         if (omxNode->getConfig(
   8389                 (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh,
   8390                 &params, sizeof(params)) == OK) {
   8391             caps->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsIntraRefresh);
   8392         }
   8393     }
   8394 
   8395     omxNode->freeNode();
   8396     client.disconnect();
   8397     return OK;
   8398 }
   8399 
   8400 // These are supposed be equivalent to the logic in
   8401 // "audio_channel_out_mask_from_count".
   8402 //static
   8403 status_t ACodec::getOMXChannelMapping(size_t numChannels, OMX_AUDIO_CHANNELTYPE map[]) {
   8404     switch (numChannels) {
   8405         case 1:
   8406             map[0] = OMX_AUDIO_ChannelCF;
   8407             break;
   8408         case 2:
   8409             map[0] = OMX_AUDIO_ChannelLF;
   8410             map[1] = OMX_AUDIO_ChannelRF;
   8411             break;
   8412         case 3:
   8413             map[0] = OMX_AUDIO_ChannelLF;
   8414             map[1] = OMX_AUDIO_ChannelRF;
   8415             map[2] = OMX_AUDIO_ChannelCF;
   8416             break;
   8417         case 4:
   8418             map[0] = OMX_AUDIO_ChannelLF;
   8419             map[1] = OMX_AUDIO_ChannelRF;
   8420             map[2] = OMX_AUDIO_ChannelLR;
   8421             map[3] = OMX_AUDIO_ChannelRR;
   8422             break;
   8423         case 5:
   8424             map[0] = OMX_AUDIO_ChannelLF;
   8425             map[1] = OMX_AUDIO_ChannelRF;
   8426             map[2] = OMX_AUDIO_ChannelCF;
   8427             map[3] = OMX_AUDIO_ChannelLR;
   8428             map[4] = OMX_AUDIO_ChannelRR;
   8429             break;
   8430         case 6:
   8431             map[0] = OMX_AUDIO_ChannelLF;
   8432             map[1] = OMX_AUDIO_ChannelRF;
   8433             map[2] = OMX_AUDIO_ChannelCF;
   8434             map[3] = OMX_AUDIO_ChannelLFE;
   8435             map[4] = OMX_AUDIO_ChannelLR;
   8436             map[5] = OMX_AUDIO_ChannelRR;
   8437             break;
   8438         case 7:
   8439             map[0] = OMX_AUDIO_ChannelLF;
   8440             map[1] = OMX_AUDIO_ChannelRF;
   8441             map[2] = OMX_AUDIO_ChannelCF;
   8442             map[3] = OMX_AUDIO_ChannelLFE;
   8443             map[4] = OMX_AUDIO_ChannelLR;
   8444             map[5] = OMX_AUDIO_ChannelRR;
   8445             map[6] = OMX_AUDIO_ChannelCS;
   8446             break;
   8447         case 8:
   8448             map[0] = OMX_AUDIO_ChannelLF;
   8449             map[1] = OMX_AUDIO_ChannelRF;
   8450             map[2] = OMX_AUDIO_ChannelCF;
   8451             map[3] = OMX_AUDIO_ChannelLFE;
   8452             map[4] = OMX_AUDIO_ChannelLR;
   8453             map[5] = OMX_AUDIO_ChannelRR;
   8454             map[6] = OMX_AUDIO_ChannelLS;
   8455             map[7] = OMX_AUDIO_ChannelRS;
   8456             break;
   8457         default:
   8458             return -EINVAL;
   8459     }
   8460 
   8461     return OK;
   8462 }
   8463 
   8464 void ACodec::setTrebleFlag(bool trebleFlag) {
   8465     mTrebleFlag = trebleFlag;
   8466 }
   8467 
   8468 bool ACodec::getTrebleFlag() const {
   8469     return mTrebleFlag;
   8470 }
   8471 
   8472 }  // namespace android
   8473