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