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