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