Home | History | Annotate | Download | only in video
      1 /*
      2  * Copyright (C) 2017 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_TAG "media_omx_hidl_video_enc_test"
     18 #ifdef __LP64__
     19 #define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
     20 #endif
     21 
     22 #include <android-base/logging.h>
     23 
     24 #include <android/hardware/graphics/bufferqueue/1.0/IGraphicBufferProducer.h>
     25 #include <android/hardware/graphics/bufferqueue/1.0/IProducerListener.h>
     26 #include <android/hardware/graphics/mapper/2.0/IMapper.h>
     27 #include <android/hardware/graphics/mapper/2.0/types.h>
     28 #include <android/hardware/media/omx/1.0/IGraphicBufferSource.h>
     29 #include <android/hardware/media/omx/1.0/IOmx.h>
     30 #include <android/hardware/media/omx/1.0/IOmxBufferSource.h>
     31 #include <android/hardware/media/omx/1.0/IOmxNode.h>
     32 #include <android/hardware/media/omx/1.0/IOmxObserver.h>
     33 #include <android/hardware/media/omx/1.0/types.h>
     34 #include <android/hidl/allocator/1.0/IAllocator.h>
     35 #include <android/hidl/memory/1.0/IMapper.h>
     36 #include <android/hidl/memory/1.0/IMemory.h>
     37 
     38 using ::android::hardware::graphics::bufferqueue::V1_0::IGraphicBufferProducer;
     39 using ::android::hardware::graphics::bufferqueue::V1_0::IProducerListener;
     40 using ::android::hardware::graphics::common::V1_0::BufferUsage;
     41 using ::android::hardware::graphics::common::V1_0::PixelFormat;
     42 using ::android::hardware::media::omx::V1_0::IGraphicBufferSource;
     43 using ::android::hardware::media::omx::V1_0::IOmxBufferSource;
     44 using ::android::hardware::media::omx::V1_0::IOmx;
     45 using ::android::hardware::media::omx::V1_0::IOmxObserver;
     46 using ::android::hardware::media::omx::V1_0::IOmxNode;
     47 using ::android::hardware::media::omx::V1_0::Message;
     48 using ::android::hardware::media::omx::V1_0::CodecBuffer;
     49 using ::android::hardware::media::omx::V1_0::PortMode;
     50 using ::android::hidl::allocator::V1_0::IAllocator;
     51 using ::android::hidl::memory::V1_0::IMemory;
     52 using ::android::hidl::memory::V1_0::IMapper;
     53 using ::android::hardware::Return;
     54 using ::android::hardware::Void;
     55 using ::android::hardware::hidl_vec;
     56 using ::android::hardware::hidl_string;
     57 using ::android::sp;
     58 
     59 #include <VtsHalHidlTargetTestBase.h>
     60 #include <getopt.h>
     61 #include <media/hardware/HardwareAPI.h>
     62 #include <media_hidl_test_common.h>
     63 #include <media_video_hidl_test_common.h>
     64 #include <system/window.h>
     65 #include <fstream>
     66 
     67 // A class for test environment setup
     68 class ComponentTestEnvironment : public ::testing::Environment {
     69    public:
     70     virtual void SetUp() {}
     71     virtual void TearDown() {}
     72 
     73     ComponentTestEnvironment() : instance("default"), res("/sdcard/media/") {}
     74 
     75     void setInstance(const char* _instance) { instance = _instance; }
     76 
     77     void setComponent(const char* _component) { component = _component; }
     78 
     79     void setRole(const char* _role) { role = _role; }
     80 
     81     void setRes(const char* _res) { res = _res; }
     82 
     83     const hidl_string getInstance() const { return instance; }
     84 
     85     const hidl_string getComponent() const { return component; }
     86 
     87     const hidl_string getRole() const { return role; }
     88 
     89     const hidl_string getRes() const { return res; }
     90 
     91     int initFromOptions(int argc, char** argv) {
     92         static struct option options[] = {
     93             {"instance", required_argument, 0, 'I'},
     94             {"component", required_argument, 0, 'C'},
     95             {"role", required_argument, 0, 'R'},
     96             {"res", required_argument, 0, 'P'},
     97             {0, 0, 0, 0}};
     98 
     99         while (true) {
    100             int index = 0;
    101             int c = getopt_long(argc, argv, "I:C:R:P:", options, &index);
    102             if (c == -1) {
    103                 break;
    104             }
    105 
    106             switch (c) {
    107                 case 'I':
    108                     setInstance(optarg);
    109                     break;
    110                 case 'C':
    111                     setComponent(optarg);
    112                     break;
    113                 case 'R':
    114                     setRole(optarg);
    115                     break;
    116                 case 'P':
    117                     setRes(optarg);
    118                     break;
    119                 case '?':
    120                     break;
    121             }
    122         }
    123 
    124         if (optind < argc) {
    125             fprintf(stderr,
    126                     "unrecognized option: %s\n\n"
    127                     "usage: %s <gtest options> <test options>\n\n"
    128                     "test options are:\n\n"
    129                     "-I, --instance: HAL instance to test\n"
    130                     "-C, --component: OMX component to test\n"
    131                     "-R, --role: OMX component Role\n"
    132                     "-P, --res: Resource files directory location\n",
    133                     argv[optind ?: 1], argv[0]);
    134             return 2;
    135         }
    136         return 0;
    137     }
    138 
    139    private:
    140     hidl_string instance;
    141     hidl_string component;
    142     hidl_string role;
    143     hidl_string res;
    144 };
    145 
    146 static ComponentTestEnvironment* gEnv = nullptr;
    147 
    148 // video encoder test fixture class
    149 class VideoEncHidlTest : public ::testing::VtsHalHidlTargetTestBase {
    150    private:
    151     typedef ::testing::VtsHalHidlTargetTestBase Super;
    152    public:
    153     ::std::string getTestCaseInfo() const override {
    154         return ::std::string() +
    155                 "Component: " + gEnv->getComponent().c_str() + " | " +
    156                 "Role: " + gEnv->getRole().c_str() + " | " +
    157                 "Instance: " + gEnv->getInstance().c_str() + " | " +
    158                 "Res: " + gEnv->getRes().c_str();
    159     }
    160 
    161     virtual void SetUp() override {
    162         Super::SetUp();
    163         disableTest = false;
    164         android::hardware::media::omx::V1_0::Status status;
    165         omx = Super::getService<IOmx>(gEnv->getInstance());
    166         ASSERT_NE(omx, nullptr);
    167         observer =
    168             new CodecObserver([this](Message msg, const BufferInfo* buffer) {
    169                 handleMessage(msg, buffer);
    170             });
    171         ASSERT_NE(observer, nullptr);
    172         if (strncmp(gEnv->getComponent().c_str(), "OMX.", 4) != 0)
    173             disableTest = true;
    174         EXPECT_TRUE(omx->allocateNode(
    175                            gEnv->getComponent(), observer,
    176                            [&](android::hardware::media::omx::V1_0::Status _s,
    177                                sp<IOmxNode> const& _nl) {
    178                                status = _s;
    179                                this->omxNode = _nl;
    180                            })
    181                         .isOk());
    182         ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
    183         ASSERT_NE(omxNode, nullptr);
    184         ASSERT_NE(gEnv->getRole().empty(), true) << "Invalid Component Role";
    185         struct StringToName {
    186             const char* Name;
    187             standardComp CompName;
    188         };
    189         const StringToName kStringToName[] = {
    190             {"h263", h263}, {"avc", avc}, {"mpeg4", mpeg4},
    191             {"hevc", hevc}, {"vp8", vp8}, {"vp9", vp9},
    192         };
    193         const size_t kNumStringToName =
    194             sizeof(kStringToName) / sizeof(kStringToName[0]);
    195         const char* pch;
    196         char substring[OMX_MAX_STRINGNAME_SIZE];
    197         strcpy(substring, gEnv->getRole().c_str());
    198         pch = strchr(substring, '.');
    199         ASSERT_NE(pch, nullptr);
    200         compName = unknown_comp;
    201         for (size_t i = 0; i < kNumStringToName; ++i) {
    202             if (!strcasecmp(pch + 1, kStringToName[i].Name)) {
    203                 compName = kStringToName[i].CompName;
    204                 break;
    205             }
    206         }
    207         if (compName == unknown_comp) disableTest = true;
    208         struct CompToCompression {
    209             standardComp CompName;
    210             OMX_VIDEO_CODINGTYPE eCompressionFormat;
    211         };
    212         static const CompToCompression kCompToCompression[] = {
    213             {h263, OMX_VIDEO_CodingH263},   {avc, OMX_VIDEO_CodingAVC},
    214             {mpeg4, OMX_VIDEO_CodingMPEG4}, {hevc, OMX_VIDEO_CodingHEVC},
    215             {vp8, OMX_VIDEO_CodingVP8},     {vp9, OMX_VIDEO_CodingVP9},
    216         };
    217         static const size_t kNumCompToCompression =
    218             sizeof(kCompToCompression) / sizeof(kCompToCompression[0]);
    219         size_t i;
    220         for (i = 0; i < kNumCompToCompression; ++i) {
    221             if (kCompToCompression[i].CompName == compName) {
    222                 eCompressionFormat = kCompToCompression[i].eCompressionFormat;
    223                 break;
    224             }
    225         }
    226         if (i == kNumCompToCompression) disableTest = true;
    227         eosFlag = false;
    228         prependSPSPPS = false;
    229         timestampDevTest = false;
    230         producer = nullptr;
    231         source = nullptr;
    232         isSecure = false;
    233         size_t suffixLen = strlen(".secure");
    234         if (strlen(gEnv->getComponent().c_str()) >= suffixLen) {
    235             isSecure =
    236                 !strcmp(gEnv->getComponent().c_str() +
    237                             strlen(gEnv->getComponent().c_str()) - suffixLen,
    238                         ".secure");
    239         }
    240         if (isSecure) disableTest = true;
    241         if (disableTest) std::cout << "[   WARN   ] Test Disabled \n";
    242     }
    243 
    244     virtual void TearDown() override {
    245         if (omxNode != nullptr) {
    246             // If you have encountered a fatal failure, it is possible that
    247             // freeNode() will not go through. Instead of hanging the app.
    248             // let it pass through and report errors
    249             if (::testing::Test::HasFatalFailure()) return;
    250             EXPECT_TRUE((omxNode->freeNode()).isOk());
    251             omxNode = nullptr;
    252         }
    253         Super::TearDown();
    254     }
    255 
    256     // callback function to process messages received by onMessages() from IL
    257     // client.
    258     void handleMessage(Message msg, const BufferInfo* buffer) {
    259         (void)buffer;
    260 
    261         if (msg.type == Message::Type::FILL_BUFFER_DONE) {
    262             if (msg.data.extendedBufferData.flags & OMX_BUFFERFLAG_EOS) {
    263                 eosFlag = true;
    264             }
    265             if (msg.data.extendedBufferData.rangeLength != 0) {
    266                 // Test if current timestamp is among the list of queued
    267                 // timestamps
    268                 if (timestampDevTest && ((msg.data.extendedBufferData.flags &
    269                                           OMX_BUFFERFLAG_CODECCONFIG) == 0)) {
    270                     bool tsHit = false;
    271                     android::List<uint64_t>::iterator it =
    272                         timestampUslist.begin();
    273                     while (it != timestampUslist.end()) {
    274                         if (*it == msg.data.extendedBufferData.timestampUs) {
    275                             timestampUslist.erase(it);
    276                             tsHit = true;
    277                             break;
    278                         }
    279                         it++;
    280                     }
    281                     if (tsHit == false) {
    282                         if (timestampUslist.empty() == false) {
    283                             EXPECT_EQ(tsHit, true)
    284                                 << "TimeStamp not recognized";
    285                         } else {
    286                             std::cout << "[   INFO   ] Received non-zero "
    287                                          "output / TimeStamp not recognized \n";
    288                         }
    289                     }
    290                 }
    291 #define WRITE_OUTPUT 0
    292 #if WRITE_OUTPUT
    293                 static int count = 0;
    294                 FILE* ofp = nullptr;
    295                 if (count)
    296                     ofp = fopen("out.bin", "ab");
    297                 else
    298                     ofp = fopen("out.bin", "wb");
    299                 if (ofp != nullptr) {
    300                     fwrite(static_cast<void*>(buffer->mMemory->getPointer()),
    301                            sizeof(char),
    302                            msg.data.extendedBufferData.rangeLength, ofp);
    303                     fclose(ofp);
    304                     count++;
    305                 }
    306 #endif
    307             }
    308         }
    309     }
    310 
    311     enum standardComp {
    312         h263,
    313         avc,
    314         mpeg4,
    315         hevc,
    316         vp8,
    317         vp9,
    318         unknown_comp,
    319     };
    320 
    321     sp<IOmx> omx;
    322     sp<CodecObserver> observer;
    323     sp<IOmxNode> omxNode;
    324     standardComp compName;
    325     OMX_VIDEO_CODINGTYPE eCompressionFormat;
    326     bool disableTest;
    327     bool eosFlag;
    328     bool prependSPSPPS;
    329     ::android::List<uint64_t> timestampUslist;
    330     bool timestampDevTest;
    331     bool isSecure;
    332     sp<IGraphicBufferProducer> producer;
    333     sp<IGraphicBufferSource> source;
    334 
    335    protected:
    336     static void description(const std::string& description) {
    337         RecordProperty("description", description);
    338     }
    339 };
    340 
    341 // CodecProducerListener class
    342 struct CodecProducerListener : public IProducerListener {
    343    public:
    344     CodecProducerListener(int a, int b)
    345         : freeBuffers(a), minUnDequeuedCount(b) {}
    346     virtual ::android::hardware::Return<void> onBufferReleased() override {
    347         android::Mutex::Autolock autoLock(bufferLock);
    348         freeBuffers += 1;
    349         return Void();
    350     }
    351     virtual ::android::hardware::Return<bool> needsReleaseNotify() override {
    352         return true;
    353     }
    354     void reduceCount() {
    355         android::Mutex::Autolock autoLock(bufferLock);
    356         freeBuffers -= 1;
    357         EXPECT_GE(freeBuffers, minUnDequeuedCount);
    358     }
    359 
    360     size_t freeBuffers;
    361     size_t minUnDequeuedCount;
    362     android::Mutex bufferLock;
    363 };
    364 
    365 // Mock IOmxBufferSource class. GraphicBufferSource.cpp in libstagefright/omx/
    366 // implements this class. Below is dummy class introduced to test if callback
    367 // functions are actually being called or not
    368 struct DummyBufferSource : public IOmxBufferSource {
    369    public:
    370     DummyBufferSource(sp<IOmxNode> node) {
    371         callback = 0;
    372         executing = false;
    373         omxNode = node;
    374     }
    375     virtual Return<void> onOmxExecuting();
    376     virtual Return<void> onOmxIdle();
    377     virtual Return<void> onOmxLoaded();
    378     virtual Return<void> onInputBufferAdded(uint32_t buffer);
    379     virtual Return<void> onInputBufferEmptied(
    380         uint32_t buffer, const ::android::hardware::hidl_handle& fence);
    381 
    382     int callback;
    383     bool executing;
    384     sp<IOmxNode> omxNode;
    385     android::Vector<BufferInfo> iBuffer, oBuffer;
    386 };
    387 
    388 Return<void> DummyBufferSource::onOmxExecuting() {
    389     executing = true;
    390     callback |= 0x1;
    391     size_t index;
    392     // Fetch a client owned input buffer and send an EOS
    393     if ((index = getEmptyBufferID(&iBuffer)) < iBuffer.size()) {
    394         android::hardware::media::omx::V1_0::Status status;
    395         CodecBuffer t = iBuffer[index].omxBuffer;
    396         t.type = CodecBuffer::Type::ANW_BUFFER;
    397         native_handle_t* fenceNh = native_handle_create(0, 0);
    398         EXPECT_NE(fenceNh, nullptr);
    399         status = omxNode->emptyBuffer(iBuffer[index].id, t, OMX_BUFFERFLAG_EOS,
    400                                       0, fenceNh);
    401         native_handle_close(fenceNh);
    402         native_handle_delete(fenceNh);
    403         EXPECT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
    404         iBuffer.editItemAt(index).owner = component;
    405     }
    406     return Void();
    407 };
    408 
    409 Return<void> DummyBufferSource::onOmxIdle() {
    410     callback |= 0x2;
    411     executing = false;
    412     return Void();
    413 };
    414 
    415 Return<void> DummyBufferSource::onOmxLoaded() {
    416     callback |= 0x4;
    417     return Void();
    418 };
    419 
    420 Return<void> DummyBufferSource::onInputBufferAdded(uint32_t buffer) {
    421     (void)buffer;
    422     EXPECT_EQ(executing, false);
    423     callback |= 0x8;
    424     return Void();
    425 };
    426 
    427 Return<void> DummyBufferSource::onInputBufferEmptied(
    428     uint32_t buffer, const ::android::hardware::hidl_handle& fence) {
    429     (void)fence;
    430     callback |= 0x10;
    431     size_t i;
    432     for (i = 0; i < iBuffer.size(); i++) {
    433         if (iBuffer[i].id == buffer) {
    434             iBuffer.editItemAt(i).owner = client;
    435             break;
    436         }
    437     }
    438     return Void();
    439 };
    440 
    441 // request VOP refresh
    442 void requestIDR(sp<IOmxNode> omxNode, OMX_U32 portIndex) {
    443     android::hardware::media::omx::V1_0::Status status;
    444     OMX_CONFIG_INTRAREFRESHVOPTYPE param;
    445     param.IntraRefreshVOP = OMX_TRUE;
    446     status = setPortConfig(omxNode, OMX_IndexConfigVideoIntraVOPRefresh,
    447                            portIndex, &param);
    448     if (status != ::android::hardware::media::omx::V1_0::Status::OK)
    449         std::cout << "[   INFO   ] unable to request IDR \n";
    450 }
    451 
    452 // modify bitrate
    453 void changeBitrate(sp<IOmxNode> omxNode, OMX_U32 portIndex, uint32_t nBitrate) {
    454     android::hardware::media::omx::V1_0::Status status;
    455     OMX_VIDEO_CONFIG_BITRATETYPE param;
    456     param.nEncodeBitrate = nBitrate;
    457     status =
    458         setPortConfig(omxNode, OMX_IndexConfigVideoBitrate, portIndex, &param);
    459     if (status != ::android::hardware::media::omx::V1_0::Status::OK)
    460         std::cout << "[   INFO   ] unable to change Bitrate \n";
    461 }
    462 
    463 // modify framerate
    464 Return<android::hardware::media::omx::V1_0::Status> changeFrameRate(
    465     sp<IOmxNode> omxNode, OMX_U32 portIndex, uint32_t xFramerate) {
    466     android::hardware::media::omx::V1_0::Status status;
    467     OMX_CONFIG_FRAMERATETYPE param;
    468     param.xEncodeFramerate = xFramerate;
    469     status = setPortConfig(omxNode, OMX_IndexConfigVideoFramerate, portIndex,
    470                            &param);
    471     if (status != ::android::hardware::media::omx::V1_0::Status::OK)
    472         std::cout << "[   INFO   ] unable to change Framerate \n";
    473     return status;
    474 }
    475 
    476 // modify intra refresh interval
    477 void changeRefreshPeriod(sp<IOmxNode> omxNode, OMX_U32 portIndex,
    478                          uint32_t nRefreshPeriod) {
    479     android::hardware::media::omx::V1_0::Status status;
    480     OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE param;
    481     param.nRefreshPeriod = nRefreshPeriod;
    482     status = setPortConfig(omxNode,
    483                            (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh,
    484                            portIndex, &param);
    485     if (status != ::android::hardware::media::omx::V1_0::Status::OK)
    486         std::cout << "[   INFO   ] unable to change Refresh Period\n";
    487 }
    488 
    489 // set intra refresh interval
    490 void setRefreshPeriod(sp<IOmxNode> omxNode, OMX_U32 portIndex,
    491                       uint32_t nRefreshPeriod) {
    492     android::hardware::media::omx::V1_0::Status status;
    493     OMX_VIDEO_PARAM_INTRAREFRESHTYPE param;
    494     param.eRefreshMode = OMX_VIDEO_IntraRefreshCyclic;
    495     param.nCirMBs = 0;
    496     if (nRefreshPeriod == 0)
    497         param.nCirMBs = 0;
    498     else {
    499         OMX_PARAM_PORTDEFINITIONTYPE portDef;
    500         status = getPortParam(omxNode, OMX_IndexParamPortDefinition, portIndex,
    501                               &portDef);
    502         if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
    503             param.nCirMBs =
    504                 ((portDef.format.video.nFrameWidth + 15) >>
    505                  4 * (portDef.format.video.nFrameHeight + 15) >> 4) /
    506                 nRefreshPeriod;
    507         }
    508     }
    509     status = setPortParam(omxNode, OMX_IndexParamVideoIntraRefresh, portIndex,
    510                           &param);
    511     if (status != ::android::hardware::media::omx::V1_0::Status::OK)
    512         std::cout << "[   INFO   ] unable to set Refresh Period \n";
    513 }
    514 
    515 void setLatency(sp<IOmxNode> omxNode, OMX_U32 portIndex, uint32_t latency) {
    516     android::hardware::media::omx::V1_0::Status status;
    517     OMX_PARAM_U32TYPE param;
    518     param.nU32 = (OMX_U32)latency;
    519     status = setPortConfig(omxNode, (OMX_INDEXTYPE)OMX_IndexConfigLatency,
    520                            portIndex, &param);
    521     if (status != ::android::hardware::media::omx::V1_0::Status::OK)
    522         std::cout << "[   INFO   ] unable to set latency\n";
    523 }
    524 
    525 void getLatency(sp<IOmxNode> omxNode, OMX_U32 portIndex, uint32_t* latency) {
    526     android::hardware::media::omx::V1_0::Status status;
    527     OMX_PARAM_U32TYPE param;
    528     status = getPortConfig(omxNode, (OMX_INDEXTYPE)OMX_IndexConfigLatency,
    529                            portIndex, &param);
    530     if (status != ::android::hardware::media::omx::V1_0::Status::OK)
    531         std::cout << "[   INFO   ] unable to get latency\n";
    532     else
    533         *latency = param.nU32;
    534 }
    535 
    536 // Set Default port param.
    537 void setDefaultPortParam(sp<IOmxNode> omxNode, OMX_U32 portIndex,
    538                          OMX_VIDEO_CODINGTYPE eCompressionFormat,
    539                          OMX_U32 nFrameWidth, OMX_U32 nFrameHeight,
    540                          OMX_U32 nBitrate, OMX_U32 xFramerate) {
    541     android::hardware::media::omx::V1_0::Status status;
    542     OMX_PARAM_PORTDEFINITIONTYPE portDef;
    543     status = getPortParam(omxNode, OMX_IndexParamPortDefinition, portIndex,
    544                           &portDef);
    545     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
    546     portDef.format.video.nFrameWidth = nFrameWidth;
    547     portDef.format.video.nFrameHeight = nFrameHeight;
    548     portDef.format.video.nBitrate = nBitrate;
    549     portDef.format.video.xFramerate = xFramerate;
    550     portDef.format.video.bFlagErrorConcealment = OMX_TRUE;
    551     portDef.format.video.eCompressionFormat = eCompressionFormat;
    552     portDef.format.video.eColorFormat = OMX_COLOR_FormatUnused;
    553     status = setPortParam(omxNode, OMX_IndexParamPortDefinition, portIndex,
    554                           &portDef);
    555     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
    556 
    557     std::vector<int32_t> arrProfile;
    558     std::vector<int32_t> arrLevel;
    559     enumerateProfileAndLevel(omxNode, portIndex, &arrProfile, &arrLevel);
    560     if (arrProfile.empty() == true || arrLevel.empty() == true)
    561         ASSERT_TRUE(false);
    562     int32_t profile = arrProfile[0];
    563     int32_t level = arrLevel[0];
    564 
    565     switch ((int)eCompressionFormat) {
    566         case OMX_VIDEO_CodingAVC:
    567             setupAVCPort(omxNode, portIndex,
    568                          static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile),
    569                          static_cast<OMX_VIDEO_AVCLEVELTYPE>(level),
    570                          xFramerate);
    571             break;
    572         case OMX_VIDEO_CodingHEVC:
    573             setupHEVCPort(omxNode, portIndex,
    574                           static_cast<OMX_VIDEO_HEVCPROFILETYPE>(profile),
    575                           static_cast<OMX_VIDEO_HEVCLEVELTYPE>(level));
    576             break;
    577         case OMX_VIDEO_CodingH263:
    578             setupH263Port(omxNode, portIndex,
    579                           static_cast<OMX_VIDEO_H263PROFILETYPE>(profile),
    580                           static_cast<OMX_VIDEO_H263LEVELTYPE>(level),
    581                           xFramerate);
    582             break;
    583         case OMX_VIDEO_CodingMPEG4:
    584             setupMPEG4Port(omxNode, portIndex,
    585                            static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile),
    586                            static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level),
    587                            xFramerate);
    588             break;
    589         case OMX_VIDEO_CodingVP8:
    590             setupVPXPort(omxNode, portIndex, xFramerate);
    591             setupVP8Port(omxNode, portIndex,
    592                          static_cast<OMX_VIDEO_VP8PROFILETYPE>(profile),
    593                          static_cast<OMX_VIDEO_VP8LEVELTYPE>(level));
    594             break;
    595         case OMX_VIDEO_CodingVP9:
    596             setupVPXPort(omxNode, portIndex, xFramerate);
    597             setupVP9Port(omxNode, portIndex,
    598                          static_cast<OMX_VIDEO_VP9PROFILETYPE>(profile),
    599                          static_cast<OMX_VIDEO_VP9LEVELTYPE>(level));
    600             break;
    601         default:
    602             break;
    603     }
    604 }
    605 
    606 // LookUpTable of clips and metadata for component testing
    607 void GetURLForComponent(char* URL) {
    608     strcat(URL, "bbb_352x288_420p_30fps_32frames.yuv");
    609 }
    610 
    611 // blocking call to ensures application to Wait till all the inputs are consumed
    612 void waitOnInputConsumption(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
    613                             android::Vector<BufferInfo>* iBuffer,
    614                             android::Vector<BufferInfo>* oBuffer,
    615                             bool inputDataIsMeta = false,
    616                             sp<CodecProducerListener> listener = nullptr) {
    617     android::hardware::media::omx::V1_0::Status status;
    618     Message msg;
    619     int timeOut = TIMEOUT_COUNTER_Q;
    620 
    621     while (timeOut--) {
    622         size_t i = 0;
    623         status =
    624             observer->dequeueMessage(&msg, DEFAULT_TIMEOUT_Q, iBuffer, oBuffer);
    625         ASSERT_EQ(status,
    626                   android::hardware::media::omx::V1_0::Status::TIMED_OUT);
    627         // status == TIMED_OUT, it could be due to process time being large
    628         // than DEFAULT_TIMEOUT or component needs output buffers to start
    629         // processing.
    630         if (inputDataIsMeta) {
    631             if (listener->freeBuffers == iBuffer->size()) break;
    632         } else {
    633             for (; i < iBuffer->size(); i++) {
    634                 if ((*iBuffer)[i].owner != client) break;
    635             }
    636             if (i == iBuffer->size()) break;
    637         }
    638 
    639         // Dispatch an output buffer assuming outQueue.empty() is true
    640         size_t index;
    641         if ((index = getEmptyBufferID(oBuffer)) < oBuffer->size()) {
    642             ASSERT_NO_FATAL_FAILURE(
    643                 dispatchOutputBuffer(omxNode, oBuffer, index));
    644             timeOut = TIMEOUT_COUNTER_Q;
    645         }
    646     }
    647 }
    648 
    649 int colorFormatConversion(BufferInfo* buffer, void* buff, PixelFormat format,
    650                           std::ifstream& eleStream) {
    651     sp<android::hardware::graphics::mapper::V2_0::IMapper> mapper =
    652         android::hardware::graphics::mapper::V2_0::IMapper::getService();
    653     EXPECT_NE(mapper.get(), nullptr);
    654     if (mapper.get() == nullptr) return 1;
    655 
    656     android::hardware::hidl_handle fence;
    657     android::hardware::graphics::mapper::V2_0::IMapper::Rect rect;
    658     android::hardware::graphics::mapper::V2_0::YCbCrLayout ycbcrLayout;
    659     android::hardware::graphics::mapper::V2_0::Error error;
    660     rect.left = 0;
    661     rect.top = 0;
    662     rect.width = buffer->omxBuffer.attr.anwBuffer.width;
    663     rect.height = buffer->omxBuffer.attr.anwBuffer.height;
    664 
    665     if (format == PixelFormat::YV12 || format == PixelFormat::YCRCB_420_SP ||
    666         format == PixelFormat::YCBCR_420_888) {
    667         mapper->lockYCbCr(
    668             buff, buffer->omxBuffer.attr.anwBuffer.usage, rect, fence,
    669             [&](android::hardware::graphics::mapper::V2_0::Error _e,
    670                 android::hardware::graphics::mapper::V2_0::YCbCrLayout _n1) {
    671                 error = _e;
    672                 ycbcrLayout = _n1;
    673             });
    674         EXPECT_EQ(error,
    675                   android::hardware::graphics::mapper::V2_0::Error::NONE);
    676         if (error != android::hardware::graphics::mapper::V2_0::Error::NONE)
    677             return 1;
    678 
    679         int size = ((rect.width * rect.height * 3) >> 1);
    680         char* img = new char[size];
    681         if (img == nullptr) return 1;
    682         eleStream.read(img, size);
    683         if (eleStream.gcount() != size) {
    684             delete[] img;
    685             return 1;
    686         }
    687 
    688         char* imgTmp = img;
    689         char* ipBuffer = static_cast<char*>(ycbcrLayout.y);
    690         for (size_t y = rect.height; y > 0; --y) {
    691             memcpy(ipBuffer, imgTmp, rect.width);
    692             ipBuffer += ycbcrLayout.yStride;
    693             imgTmp += rect.width;
    694         }
    695 
    696         if (format == PixelFormat::YV12)
    697             EXPECT_EQ(ycbcrLayout.chromaStep, 1U);
    698         else if (format == PixelFormat::YCRCB_420_SP)
    699             EXPECT_EQ(ycbcrLayout.chromaStep, 2U);
    700 
    701         ipBuffer = static_cast<char*>(ycbcrLayout.cb);
    702         for (size_t y = rect.height >> 1; y > 0; --y) {
    703             for (int32_t x = 0; x < (rect.width >> 1); ++x) {
    704                 ipBuffer[ycbcrLayout.chromaStep * x] = *imgTmp++;
    705             }
    706             ipBuffer += ycbcrLayout.cStride;
    707         }
    708         ipBuffer = static_cast<char*>(ycbcrLayout.cr);
    709         for (size_t y = rect.height >> 1; y > 0; --y) {
    710             for (int32_t x = 0; x < (rect.width >> 1); ++x) {
    711                 ipBuffer[ycbcrLayout.chromaStep * x] = *imgTmp++;
    712             }
    713             ipBuffer += ycbcrLayout.cStride;
    714         }
    715 
    716         delete[] img;
    717 
    718         mapper->unlock(buff,
    719                        [&](android::hardware::graphics::mapper::V2_0::Error _e,
    720                            android::hardware::hidl_handle _n1) {
    721                            error = _e;
    722                            fence = _n1;
    723                        });
    724         EXPECT_EQ(error,
    725                   android::hardware::graphics::mapper::V2_0::Error::NONE);
    726         if (error != android::hardware::graphics::mapper::V2_0::Error::NONE)
    727             return 1;
    728     } else {
    729         void* data;
    730         mapper->lock(buff, buffer->omxBuffer.attr.anwBuffer.usage, rect, fence,
    731                      [&](android::hardware::graphics::mapper::V2_0::Error _e,
    732                          void* _n1) {
    733                          error = _e;
    734                          data = _n1;
    735                      });
    736         EXPECT_EQ(error,
    737                   android::hardware::graphics::mapper::V2_0::Error::NONE);
    738         if (error != android::hardware::graphics::mapper::V2_0::Error::NONE)
    739             return 1;
    740 
    741         if (format == PixelFormat::BGRA_8888) {
    742             char* ipBuffer = static_cast<char*>(data);
    743             for (size_t y = rect.height; y > 0; --y) {
    744                 eleStream.read(ipBuffer, rect.width * 4);
    745                 if (eleStream.gcount() != rect.width * 4) return 1;
    746                 ipBuffer += buffer->omxBuffer.attr.anwBuffer.stride * 4;
    747             }
    748         } else {
    749             EXPECT_TRUE(false) << "un expected pixel format";
    750             return 1;
    751         }
    752 
    753         mapper->unlock(buff,
    754                        [&](android::hardware::graphics::mapper::V2_0::Error _e,
    755                            android::hardware::hidl_handle _n1) {
    756                            error = _e;
    757                            fence = _n1;
    758                        });
    759         EXPECT_EQ(error,
    760                   android::hardware::graphics::mapper::V2_0::Error::NONE);
    761         if (error != android::hardware::graphics::mapper::V2_0::Error::NONE)
    762             return 1;
    763     }
    764 
    765     return 0;
    766 }
    767 
    768 int fillGraphicBuffer(BufferInfo* buffer, PixelFormat format,
    769                       std::ifstream& eleStream) {
    770     sp<android::hardware::graphics::mapper::V2_0::IMapper> mapper =
    771         android::hardware::graphics::mapper::V2_0::IMapper::getService();
    772     EXPECT_NE(mapper.get(), nullptr);
    773     if (mapper.get() == nullptr) return 1;
    774 
    775     void* buff = nullptr;
    776     android::hardware::graphics::mapper::V2_0::Error error;
    777     mapper->importBuffer(
    778         buffer->omxBuffer.nativeHandle,
    779         [&](android::hardware::graphics::mapper::V2_0::Error _e, void* _n1) {
    780             error = _e;
    781             buff = _n1;
    782         });
    783     EXPECT_EQ(error, android::hardware::graphics::mapper::V2_0::Error::NONE);
    784     if (error != android::hardware::graphics::mapper::V2_0::Error::NONE)
    785         return 1;
    786 
    787     if (colorFormatConversion(buffer, buff, format, eleStream)) return 1;
    788 
    789     error = mapper->freeBuffer(buff);
    790     EXPECT_EQ(error, android::hardware::graphics::mapper::V2_0::Error::NONE);
    791     if (error != android::hardware::graphics::mapper::V2_0::Error::NONE)
    792         return 1;
    793 
    794     return 0;
    795 }
    796 
    797 int dispatchGraphicBuffer(sp<IOmxNode> omxNode,
    798                           sp<IGraphicBufferProducer> producer,
    799                           sp<CodecProducerListener> listener,
    800                           android::Vector<BufferInfo>* buffArray,
    801                           OMX_U32 portIndex, std::ifstream& eleStream,
    802                           uint64_t timestamp) {
    803     android::hardware::media::omx::V1_0::Status status;
    804     OMX_PARAM_PORTDEFINITIONTYPE portDef;
    805 
    806     status = getPortParam(omxNode, OMX_IndexParamPortDefinition, portIndex,
    807                           &portDef);
    808     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
    809     if (status != ::android::hardware::media::omx::V1_0::Status::OK) return 1;
    810 
    811     enum {
    812         // A flag returned by dequeueBuffer when the client needs to call
    813         // requestBuffer immediately thereafter.
    814         BUFFER_NEEDS_REALLOCATION = 0x1,
    815         // A flag returned by dequeueBuffer when all mirrored slots should be
    816         // released by the client. This flag should always be processed first.
    817         RELEASE_ALL_BUFFERS = 0x2,
    818     };
    819 
    820     int32_t slot;
    821     int32_t result;
    822     ::android::hardware::hidl_handle fence;
    823     IGraphicBufferProducer::FrameEventHistoryDelta outTimestamps;
    824     ::android::hardware::media::V1_0::AnwBuffer AnwBuffer;
    825     PixelFormat format = PixelFormat::YCBCR_420_888;
    826     producer->dequeueBuffer(
    827         portDef.format.video.nFrameWidth, portDef.format.video.nFrameHeight,
    828         format, BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN,
    829         true, [&](int32_t _s, int32_t const& _n1,
    830                   ::android::hardware::hidl_handle const& _n2,
    831                   IGraphicBufferProducer::FrameEventHistoryDelta const& _n3) {
    832             result = _s;
    833             slot = _n1;
    834             fence = _n2;
    835             outTimestamps = _n3;
    836         });
    837     if (result & BUFFER_NEEDS_REALLOCATION) {
    838         producer->requestBuffer(
    839             slot, [&](int32_t _s,
    840                       ::android::hardware::media::V1_0::AnwBuffer const& _n1) {
    841                 result = _s;
    842                 AnwBuffer = _n1;
    843             });
    844         EXPECT_EQ(result, 0);
    845         if (result != 0) return 1;
    846         size_t i;
    847         for (i = 0; i < buffArray->size(); i++) {
    848             if ((*buffArray)[i].slot == -1) {
    849                 buffArray->editItemAt(i).slot = slot;
    850                 buffArray->editItemAt(i).omxBuffer.nativeHandle =
    851                     AnwBuffer.nativeHandle;
    852                 buffArray->editItemAt(i).omxBuffer.attr.anwBuffer =
    853                     AnwBuffer.attr;
    854                 break;
    855             }
    856         }
    857         EXPECT_NE(i, buffArray->size());
    858         if (i == buffArray->size()) return 1;
    859     }
    860     EXPECT_EQ(result, 0);
    861     if (result != 0) return 1;
    862 
    863     // fill Buffer
    864     BufferInfo buffer;
    865     size_t i;
    866     for (i = 0; i < buffArray->size(); i++) {
    867         if ((*buffArray)[i].slot == slot) {
    868             buffer = (*buffArray)[i];
    869             break;
    870         }
    871     }
    872     EXPECT_NE(i, buffArray->size());
    873     if (i == buffArray->size()) return 1;
    874     if (fillGraphicBuffer(&buffer, format, eleStream)) return 1;
    875 
    876     // queue Buffer
    877     IGraphicBufferProducer::QueueBufferOutput output;
    878     IGraphicBufferProducer::QueueBufferInput input;
    879     android::hardware::media::V1_0::Rect rect;
    880     rect.left = 0;
    881     rect.top = 0;
    882     rect.right = buffer.omxBuffer.attr.anwBuffer.width;
    883     rect.bottom = buffer.omxBuffer.attr.anwBuffer.height;
    884     input.timestamp = timestamp;
    885     input.isAutoTimestamp = false;
    886     input.dataSpace =
    887         android::hardware::graphics::common::V1_0::Dataspace::UNKNOWN;
    888     input.crop = rect;
    889     input.scalingMode = 0;
    890     input.transform = 0;
    891     input.stickyTransform = 0;
    892     input.fence = android::hardware::hidl_handle();
    893     input.surfaceDamage =
    894         android::hardware::hidl_vec<android::hardware::media::V1_0::Rect>{rect};
    895     input.getFrameTimestamps = false;
    896     producer->queueBuffer(
    897         buffer.slot, input,
    898         [&](int32_t _s, const IGraphicBufferProducer::QueueBufferOutput& _n1) {
    899             result = _s;
    900             output = _n1;
    901         });
    902     EXPECT_EQ(result, 0);
    903     if (result != 0) return 1;
    904 
    905     listener->reduceCount();
    906 
    907     return 0;
    908 }
    909 
    910 int fillByteBuffer(sp<IOmxNode> omxNode, char* ipBuffer, OMX_U32 portIndexInput,
    911                    std::ifstream& eleStream) {
    912     android::hardware::media::omx::V1_0::Status status;
    913     OMX_PARAM_PORTDEFINITIONTYPE portDef;
    914     uint32_t i, j;
    915 
    916     status = getPortParam(omxNode, OMX_IndexParamPortDefinition, portIndexInput,
    917                           &portDef);
    918     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
    919 
    920     int size = ((portDef.format.video.nFrameWidth *
    921                  portDef.format.video.nFrameHeight * 3) >>
    922                 1);
    923     char* img = new char[size];
    924     if (img == nullptr) return 1;
    925     eleStream.read(img, size);
    926     if (eleStream.gcount() != size) {
    927         delete[] img;
    928         return 1;
    929     }
    930 
    931     char* Y = ipBuffer;
    932     char* imgTmp = img;
    933     for (j = 0; j < portDef.format.video.nFrameHeight; ++j) {
    934         memcpy(Y, imgTmp, portDef.format.video.nFrameWidth);
    935         Y += portDef.format.video.nStride;
    936         imgTmp += portDef.format.video.nFrameWidth;
    937     }
    938 
    939     if (portDef.format.video.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) {
    940         char* Cb = ipBuffer + (portDef.format.video.nFrameHeight *
    941                                portDef.format.video.nStride);
    942         char* Cr = Cb + 1;
    943         for (j = 0; j<portDef.format.video.nFrameHeight>> 1; ++j) {
    944             for (i = 0; i < (portDef.format.video.nFrameWidth >> 1); ++i) {
    945                 Cb[2 * i] = *imgTmp++;
    946             }
    947             Cb += portDef.format.video.nStride;
    948         }
    949         for (j = 0; j<portDef.format.video.nFrameHeight>> 1; ++j) {
    950             for (i = 0; i < (portDef.format.video.nFrameWidth >> 1); ++i) {
    951                 Cr[2 * i] = *imgTmp++;
    952             }
    953             Cr += portDef.format.video.nStride;
    954         }
    955     } else if (portDef.format.video.eColorFormat ==
    956                OMX_COLOR_FormatYUV420Planar) {
    957         char* Cb = ipBuffer + (portDef.format.video.nFrameHeight *
    958                                portDef.format.video.nStride);
    959         char* Cr = Cb + ((portDef.format.video.nFrameHeight *
    960                           portDef.format.video.nStride) >>
    961                          2);
    962         for (j = 0; j<portDef.format.video.nFrameHeight>> 1; ++j) {
    963             memcpy(Cb, imgTmp, (portDef.format.video.nFrameWidth >> 1));
    964             Cb += (portDef.format.video.nStride >> 1);
    965             imgTmp += (portDef.format.video.nFrameWidth >> 1);
    966         }
    967         for (j = 0; j<portDef.format.video.nFrameHeight>> 1; ++j) {
    968             memcpy(Cr, imgTmp, (portDef.format.video.nFrameWidth >> 1));
    969             Cr += (portDef.format.video.nStride >> 1);
    970             imgTmp += (portDef.format.video.nFrameWidth >> 1);
    971         }
    972     }
    973 
    974     delete[] img;
    975     return 0;
    976 }
    977 
    978 // Encode N Frames
    979 void encodeNFrames(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
    980                    OMX_U32 portIndexInput, OMX_U32 portIndexOutput,
    981                    android::Vector<BufferInfo>* iBuffer,
    982                    android::Vector<BufferInfo>* oBuffer, uint32_t nFrames,
    983                    uint32_t xFramerate, int bytesCount,
    984                    std::ifstream& eleStream,
    985                    ::android::List<uint64_t>* timestampUslist = nullptr,
    986                    bool signalEOS = true, bool inputDataIsMeta = false,
    987                    sp<IGraphicBufferProducer> producer = nullptr,
    988                    sp<CodecProducerListener> listener = nullptr) {
    989     android::hardware::media::omx::V1_0::Status status;
    990     Message msg;
    991     uint64_t timestamp = 0;
    992     uint32_t flags = 0;
    993     int timeOut = TIMEOUT_COUNTER_Q;
    994     bool iQueued, oQueued;
    995 
    996     uint32_t ipCount = 0;
    997     if (ipCount == 0) {
    998         status = changeFrameRate(omxNode, portIndexOutput, (24U << 16));
    999         if (status == ::android::hardware::media::omx::V1_0::Status::OK)
   1000             xFramerate = (24U << 16);
   1001     }
   1002     int32_t timestampIncr = (int)((float)1000000 / (xFramerate >> 16));
   1003     if (inputDataIsMeta) timestampIncr *= 1000;  // timestamp scale: Nano sec
   1004 
   1005     while (1) {
   1006         iQueued = oQueued = false;
   1007         status =
   1008             observer->dequeueMessage(&msg, DEFAULT_TIMEOUT_Q, iBuffer, oBuffer);
   1009         // Port Reconfiguration
   1010         if (status == android::hardware::media::omx::V1_0::Status::OK) {
   1011             ASSERT_EQ(msg.type, Message::Type::EVENT);
   1012             if (msg.data.eventData.event == OMX_EventPortSettingsChanged) {
   1013                 ASSERT_EQ(msg.data.eventData.data1, portIndexOutput);
   1014                 ASSERT_EQ(msg.data.eventData.data2,
   1015                           OMX_IndexConfigAndroidIntraRefresh);
   1016             } else if (msg.data.eventData.event == OMX_EventError) {
   1017                 ASSERT_TRUE(false) << "Received OMX_EventError, not sure why";
   1018             } else if (msg.data.eventData.event == OMX_EventDataSpaceChanged) {
   1019                 // TODO: how am i supposed to respond now?
   1020                 std::cout << "[   INFO   ] OMX_EventDataSpaceChanged \n";
   1021             } else {
   1022                 ASSERT_TRUE(false);
   1023             }
   1024         }
   1025 
   1026         if (nFrames == 0) break;
   1027 
   1028         // Dispatch input buffer
   1029         size_t index = 0;
   1030         if (inputDataIsMeta) {
   1031             if (listener->freeBuffers > listener->minUnDequeuedCount) {
   1032                 if (dispatchGraphicBuffer(omxNode, producer, listener, iBuffer,
   1033                                           portIndexInput, eleStream,
   1034                                           timestamp)) {
   1035                     if (::testing::Test::HasFailure())
   1036                         ASSERT_TRUE(false);
   1037                     else
   1038                         break;
   1039                 }
   1040                 timestamp += timestampIncr;
   1041                 nFrames--;
   1042                 ipCount++;
   1043                 iQueued = true;
   1044             }
   1045         } else {
   1046             if ((index = getEmptyBufferID(iBuffer)) < iBuffer->size()) {
   1047                 char* ipBuffer = static_cast<char*>(static_cast<void*>(
   1048                     (*iBuffer)[index].mMemory->getPointer()));
   1049                 ASSERT_LE(
   1050                     bytesCount,
   1051                     static_cast<int>((*iBuffer)[index].mMemory->getSize()));
   1052                 if (fillByteBuffer(omxNode, ipBuffer, portIndexInput,
   1053                                    eleStream))
   1054                     break;
   1055                 flags = OMX_BUFFERFLAG_ENDOFFRAME;
   1056                 if (signalEOS && (nFrames == 1)) flags |= OMX_BUFFERFLAG_EOS;
   1057                 ASSERT_NO_FATAL_FAILURE(dispatchInputBuffer(
   1058                     omxNode, iBuffer, index, bytesCount, flags, timestamp));
   1059                 if (timestampUslist) timestampUslist->push_back(timestamp);
   1060                 timestamp += timestampIncr;
   1061                 nFrames--;
   1062                 ipCount++;
   1063                 iQueued = true;
   1064             }
   1065         }
   1066         // Dispatch output buffer
   1067         if ((index = getEmptyBufferID(oBuffer)) < oBuffer->size()) {
   1068             ASSERT_NO_FATAL_FAILURE(
   1069                 dispatchOutputBuffer(omxNode, oBuffer, index));
   1070             oQueued = true;
   1071         }
   1072         // Reset Counters when either input or output buffer is dispatched
   1073         if (iQueued || oQueued)
   1074             timeOut = TIMEOUT_COUNTER_Q;
   1075         else
   1076             timeOut--;
   1077         if (timeOut == 0) {
   1078             ASSERT_TRUE(false) << "Wait on Input/Output is found indefinite";
   1079         }
   1080         // Runtime Param Configuration
   1081         if (ipCount == 15) {
   1082             changeBitrate(omxNode, portIndexOutput, 768000);
   1083             requestIDR(omxNode, portIndexOutput);
   1084             changeRefreshPeriod(omxNode, portIndexOutput, 15);
   1085         }
   1086     }
   1087 }
   1088 
   1089 // set component role
   1090 TEST_F(VideoEncHidlTest, SetRole) {
   1091     description("Test Set Component Role");
   1092     if (disableTest) return;
   1093     android::hardware::media::omx::V1_0::Status status;
   1094     status = setRole(omxNode, gEnv->getRole().c_str());
   1095     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1096 }
   1097 
   1098 // port format enumeration
   1099 TEST_F(VideoEncHidlTest, EnumeratePortFormat) {
   1100     description("Test Component on Mandatory Port Parameters (Port Format)");
   1101     if (disableTest) return;
   1102     android::hardware::media::omx::V1_0::Status status;
   1103     uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
   1104     OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatYUV420Planar;
   1105     OMX_U32 xFramerate = (30U << 16);
   1106     status = setRole(omxNode, gEnv->getRole().c_str());
   1107     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1108     OMX_PORT_PARAM_TYPE params;
   1109     status = getParam(omxNode, OMX_IndexParamVideoInit, &params);
   1110     if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
   1111         ASSERT_EQ(params.nPorts, 2U);
   1112         kPortIndexInput = params.nStartPortNumber;
   1113         kPortIndexOutput = kPortIndexInput + 1;
   1114     }
   1115     status =
   1116         setVideoPortFormat(omxNode, kPortIndexInput, OMX_VIDEO_CodingUnused,
   1117                            eColorFormat, xFramerate);
   1118     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1119 
   1120     status = setVideoPortFormat(omxNode, kPortIndexOutput, eCompressionFormat,
   1121                                 OMX_COLOR_FormatUnused, 0U);
   1122     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1123 }
   1124 
   1125 // Test IOmxBufferSource CallBacks
   1126 TEST_F(VideoEncHidlTest, BufferSourceCallBacks) {
   1127     description("Test IOmxBufferSource CallBacks");
   1128     if (disableTest) return;
   1129     android::hardware::media::omx::V1_0::Status status;
   1130     uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
   1131     status = setRole(omxNode, gEnv->getRole().c_str());
   1132     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1133     OMX_PORT_PARAM_TYPE params;
   1134     status = getParam(omxNode, OMX_IndexParamVideoInit, &params);
   1135     if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
   1136         ASSERT_EQ(params.nPorts, 2U);
   1137         kPortIndexInput = params.nStartPortNumber;
   1138         kPortIndexOutput = kPortIndexInput + 1;
   1139     }
   1140 
   1141     // Configure input port
   1142     uint32_t nFrameWidth = 352;
   1143     uint32_t nFrameHeight = 288;
   1144     uint32_t xFramerate = (30U << 16);
   1145     OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatAndroidOpaque;
   1146     setupRAWPort(omxNode, kPortIndexInput, nFrameWidth, nFrameHeight, 0,
   1147                  xFramerate, eColorFormat);
   1148 
   1149     sp<DummyBufferSource> buffersource = new DummyBufferSource(omxNode);
   1150     ASSERT_NE(buffersource, nullptr);
   1151     status = omxNode->setInputSurface(buffersource);
   1152     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1153 
   1154     // set port mode
   1155     PortMode portMode[2];
   1156     portMode[0] = PortMode::DYNAMIC_ANW_BUFFER;
   1157     portMode[1] = PortMode::PRESET_BYTE_BUFFER;
   1158     status = omxNode->setPortMode(kPortIndexInput, portMode[0]);
   1159     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1160     status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
   1161     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1162 
   1163     // set state to idle
   1164     ASSERT_NO_FATAL_FAILURE(changeStateLoadedtoIdle(
   1165         omxNode, observer, &buffersource->iBuffer, &buffersource->oBuffer,
   1166         kPortIndexInput, kPortIndexOutput, portMode));
   1167     // set state to executing
   1168     ASSERT_NO_FATAL_FAILURE(changeStateIdletoExecute(omxNode, observer));
   1169     ASSERT_NO_FATAL_FAILURE(testEOS(omxNode, observer, &buffersource->iBuffer,
   1170                                     &buffersource->oBuffer, false, eosFlag));
   1171     // set state to idle
   1172     ASSERT_NO_FATAL_FAILURE(changeStateExecutetoIdle(
   1173         omxNode, observer, &buffersource->iBuffer, &buffersource->oBuffer));
   1174     // set state to executing
   1175     ASSERT_NO_FATAL_FAILURE(changeStateIdletoLoaded(
   1176         omxNode, observer, &buffersource->iBuffer, &buffersource->oBuffer,
   1177         kPortIndexInput, kPortIndexOutput));
   1178     // test for callbacks
   1179     EXPECT_EQ(buffersource->callback, 31);
   1180 }
   1181 
   1182 // test raw stream encode (input is byte buffers)
   1183 TEST_F(VideoEncHidlTest, EncodeTest) {
   1184     description("Test Encode");
   1185     if (disableTest) return;
   1186     android::hardware::media::omx::V1_0::Status status;
   1187     uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
   1188     status = setRole(omxNode, gEnv->getRole().c_str());
   1189     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1190     OMX_PORT_PARAM_TYPE params;
   1191     status = getParam(omxNode, OMX_IndexParamVideoInit, &params);
   1192     if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
   1193         ASSERT_EQ(params.nPorts, 2U);
   1194         kPortIndexInput = params.nStartPortNumber;
   1195         kPortIndexOutput = kPortIndexInput + 1;
   1196     }
   1197     char mURL[512];
   1198     strcpy(mURL, gEnv->getRes().c_str());
   1199     GetURLForComponent(mURL);
   1200 
   1201     std::ifstream eleStream;
   1202 
   1203     timestampDevTest = true;
   1204 
   1205     // Configure input port
   1206     uint32_t nFrameWidth = 352;
   1207     uint32_t nFrameHeight = 288;
   1208     uint32_t xFramerate = (30U << 16);
   1209     OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatUnused;
   1210     OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat;
   1211     portFormat.nIndex = 0;
   1212     while (1) {
   1213         status = getPortParam(omxNode, OMX_IndexParamVideoPortFormat,
   1214                               kPortIndexInput, &portFormat);
   1215         if (status != ::android::hardware::media::omx::V1_0::Status::OK) break;
   1216         EXPECT_EQ(portFormat.eCompressionFormat, OMX_VIDEO_CodingUnused);
   1217         if (OMX_COLOR_FormatYUV420SemiPlanar == portFormat.eColorFormat ||
   1218             OMX_COLOR_FormatYUV420Planar == portFormat.eColorFormat) {
   1219             eColorFormat = portFormat.eColorFormat;
   1220             break;
   1221         }
   1222         portFormat.nIndex++;
   1223         if (portFormat.nIndex == 512) break;
   1224     }
   1225     ASSERT_NE(eColorFormat, OMX_COLOR_FormatUnused);
   1226     setupRAWPort(omxNode, kPortIndexInput, nFrameWidth, nFrameHeight, 0,
   1227                  xFramerate, eColorFormat);
   1228 
   1229     // Configure output port
   1230     uint32_t nBitRate = 512000;
   1231     ASSERT_NO_FATAL_FAILURE(
   1232         setDefaultPortParam(omxNode, kPortIndexOutput, eCompressionFormat,
   1233                             nFrameWidth, nFrameHeight, nBitRate, xFramerate));
   1234     setRefreshPeriod(omxNode, kPortIndexOutput, 0);
   1235 
   1236     unsigned int index;
   1237     omxNode->getExtensionIndex(
   1238         "OMX.google.android.index.prependSPSPPSToIDRFrames",
   1239         [&status, &index](android::hardware::media::omx::V1_0::Status _s,
   1240                           unsigned int _nl) {
   1241             status = _s;
   1242             index = _nl;
   1243         });
   1244     if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
   1245         android::PrependSPSPPSToIDRFramesParams param;
   1246         param.bEnable = OMX_TRUE;
   1247         status = setParam(omxNode, static_cast<OMX_INDEXTYPE>(index), &param);
   1248     }
   1249     if (status != ::android::hardware::media::omx::V1_0::Status::OK)
   1250         std::cout << "[   INFO   ] unable to prependSPSPPSToIDRFrames\n";
   1251     else
   1252         prependSPSPPS = true;
   1253 
   1254     // set port mode
   1255     PortMode portMode[2];
   1256     portMode[0] = portMode[1] = PortMode::PRESET_BYTE_BUFFER;
   1257     status = omxNode->setPortMode(kPortIndexInput, portMode[0]);
   1258     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1259     status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
   1260     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1261 
   1262     uint32_t latency = 0;
   1263     setLatency(omxNode, kPortIndexInput, latency);
   1264     getLatency(omxNode, kPortIndexInput, &latency);
   1265 
   1266     android::Vector<BufferInfo> iBuffer, oBuffer;
   1267 
   1268     // set state to idle
   1269     ASSERT_NO_FATAL_FAILURE(
   1270         changeStateLoadedtoIdle(omxNode, observer, &iBuffer, &oBuffer,
   1271                                 kPortIndexInput, kPortIndexOutput, portMode));
   1272     // set state to executing
   1273     ASSERT_NO_FATAL_FAILURE(changeStateIdletoExecute(omxNode, observer));
   1274 
   1275     eleStream.open(mURL, std::ifstream::binary);
   1276     ASSERT_EQ(eleStream.is_open(), true);
   1277     ASSERT_NO_FATAL_FAILURE(encodeNFrames(
   1278         omxNode, observer, kPortIndexInput, kPortIndexOutput, &iBuffer,
   1279         &oBuffer, 32, xFramerate, (nFrameWidth * nFrameHeight * 3) >> 1,
   1280         eleStream, &timestampUslist));
   1281     eleStream.close();
   1282     ASSERT_NO_FATAL_FAILURE(
   1283         waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer));
   1284     ASSERT_NO_FATAL_FAILURE(
   1285         testEOS(omxNode, observer, &iBuffer, &oBuffer, false, eosFlag));
   1286     if (timestampDevTest) EXPECT_EQ(timestampUslist.empty(), true);
   1287 
   1288     // set state to idle
   1289     ASSERT_NO_FATAL_FAILURE(
   1290         changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer));
   1291     // set state to executing
   1292     ASSERT_NO_FATAL_FAILURE(changeStateIdletoLoaded(omxNode, observer, &iBuffer,
   1293                                                     &oBuffer, kPortIndexInput,
   1294                                                     kPortIndexOutput));
   1295 }
   1296 
   1297 // test raw stream encode (input is ANW buffers)
   1298 TEST_F(VideoEncHidlTest, EncodeTestBufferMetaModes) {
   1299     description("Test Encode Input buffer metamodes");
   1300     if (disableTest) return;
   1301     android::hardware::media::omx::V1_0::Status status;
   1302     uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
   1303     status = setRole(omxNode, gEnv->getRole().c_str());
   1304     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1305     OMX_PORT_PARAM_TYPE params;
   1306     status = getParam(omxNode, OMX_IndexParamVideoInit, &params);
   1307     if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
   1308         ASSERT_EQ(params.nPorts, 2U);
   1309         kPortIndexInput = params.nStartPortNumber;
   1310         kPortIndexOutput = kPortIndexInput + 1;
   1311     }
   1312 
   1313     // Configure input port
   1314     uint32_t nFrameWidth = 352;
   1315     uint32_t nFrameHeight = 288;
   1316     uint32_t xFramerate = (30U << 16);
   1317     OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatAndroidOpaque;
   1318     setupRAWPort(omxNode, kPortIndexInput, nFrameWidth, nFrameHeight, 0,
   1319                  xFramerate, eColorFormat);
   1320 
   1321     // Configure output port
   1322     uint32_t nBitRate = 512000;
   1323     ASSERT_NO_FATAL_FAILURE(
   1324         setDefaultPortParam(omxNode, kPortIndexOutput, eCompressionFormat,
   1325                             nFrameWidth, nFrameHeight, nBitRate, xFramerate));
   1326     // CreateInputSurface
   1327     EXPECT_TRUE(omx->createInputSurface(
   1328                        [&](android::hardware::media::omx::V1_0::Status _s,
   1329                            sp<IGraphicBufferProducer> const& _nl,
   1330                            sp<IGraphicBufferSource> const& _n2) {
   1331                            status = _s;
   1332                            producer = _nl;
   1333                            source = _n2;
   1334                        })
   1335                     .isOk());
   1336     ASSERT_NE(producer, nullptr);
   1337     ASSERT_NE(source, nullptr);
   1338 
   1339     // setMaxDequeuedBufferCount
   1340     int32_t returnval;
   1341     int32_t value;
   1342     producer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
   1343                     [&returnval, &value](int32_t _s, int32_t _n1) {
   1344                         returnval = _s;
   1345                         value = _n1;
   1346                     });
   1347     ASSERT_EQ(returnval, 0);
   1348     OMX_PARAM_PORTDEFINITIONTYPE portDef;
   1349     status = getPortParam(omxNode, OMX_IndexParamPortDefinition,
   1350                           kPortIndexInput, &portDef);
   1351     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1352     ASSERT_EQ(::android::OK,
   1353               producer->setMaxDequeuedBufferCount(portDef.nBufferCountActual));
   1354 
   1355     // Connect :: Mock Producer Listener
   1356     IGraphicBufferProducer::QueueBufferOutput qbo;
   1357     sp<CodecProducerListener> listener =
   1358         new CodecProducerListener(portDef.nBufferCountActual + value, value);
   1359     producer->connect(
   1360         listener, NATIVE_WINDOW_API_CPU, false,
   1361         [&](int32_t _s, IGraphicBufferProducer::QueueBufferOutput const& _n1) {
   1362             returnval = _s;
   1363             qbo = _n1;
   1364         });
   1365     ASSERT_EQ(returnval, 0);
   1366 
   1367     portDef.nBufferCountActual = portDef.nBufferCountActual + value;
   1368     status = setPortParam(omxNode, OMX_IndexParamPortDefinition,
   1369                           kPortIndexInput, &portDef);
   1370     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1371 
   1372     // Do setInputSurface()
   1373     // enable MetaMode on input port
   1374     status = source->configure(
   1375         omxNode, android::hardware::graphics::common::V1_0::Dataspace::UNKNOWN);
   1376     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1377 
   1378     // set port mode
   1379     PortMode portMode[2];
   1380     portMode[0] = PortMode::DYNAMIC_ANW_BUFFER;
   1381     portMode[1] = PortMode::PRESET_BYTE_BUFFER;
   1382     status = omxNode->setPortMode(kPortIndexInput, portMode[0]);
   1383     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1384     status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
   1385     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1386 
   1387     char mURL[512];
   1388     strcpy(mURL, gEnv->getRes().c_str());
   1389     GetURLForComponent(mURL);
   1390 
   1391     uint32_t latency = 0;
   1392     setLatency(omxNode, kPortIndexInput, latency);
   1393     getLatency(omxNode, kPortIndexInput, &latency);
   1394 
   1395     std::ifstream eleStream;
   1396 
   1397     status = source->setSuspend(false, 0);
   1398     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1399     status = source->setRepeatPreviousFrameDelayUs(100000);
   1400     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1401     status = source->setMaxFps(24.0f);
   1402     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1403     status = source->setTimeLapseConfig(24.0, 24.0);
   1404     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1405     status = source->setTimeOffsetUs(-100);
   1406     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1407     status = source->setStartTimeUs(10);
   1408     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1409     status = source->setStopTimeUs(1000000);
   1410     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1411     ::android::hardware::media::omx::V1_0::ColorAspects aspects;
   1412     aspects.range =
   1413         ::android::hardware::media::omx::V1_0::ColorAspects::Range::UNSPECIFIED;
   1414     aspects.primaries = ::android::hardware::media::omx::V1_0::ColorAspects::
   1415         Primaries::UNSPECIFIED;
   1416     aspects.transfer = ::android::hardware::media::omx::V1_0::ColorAspects::
   1417         Transfer::UNSPECIFIED;
   1418     aspects.matrixCoeffs = ::android::hardware::media::omx::V1_0::ColorAspects::
   1419         MatrixCoeffs::UNSPECIFIED;
   1420     status = source->setColorAspects(aspects);
   1421     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1422     int64_t stopTimeOffsetUs;
   1423     source->getStopTimeOffsetUs(
   1424         [&](android::hardware::media::omx::V1_0::Status _s, int64_t _n1) {
   1425             status = _s;
   1426             stopTimeOffsetUs = _n1;
   1427         });
   1428     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1429 
   1430     android::Vector<BufferInfo> iBuffer, oBuffer;
   1431     // set state to idle
   1432     ASSERT_NO_FATAL_FAILURE(
   1433         changeStateLoadedtoIdle(omxNode, observer, &iBuffer, &oBuffer,
   1434                                 kPortIndexInput, kPortIndexOutput, portMode));
   1435     // set state to executing
   1436     ASSERT_NO_FATAL_FAILURE(changeStateIdletoExecute(omxNode, observer));
   1437 
   1438     eleStream.open(mURL, std::ifstream::binary);
   1439     ASSERT_EQ(eleStream.is_open(), true);
   1440     ASSERT_NO_FATAL_FAILURE(encodeNFrames(
   1441         omxNode, observer, kPortIndexInput, kPortIndexOutput, &iBuffer,
   1442         &oBuffer, 1024, xFramerate, (nFrameWidth * nFrameHeight * 3) >> 1,
   1443         eleStream, nullptr, false, true, producer, listener));
   1444     eleStream.close();
   1445     ASSERT_NO_FATAL_FAILURE(waitOnInputConsumption(omxNode, observer, &iBuffer,
   1446                                                    &oBuffer, true, listener));
   1447     ASSERT_NO_FATAL_FAILURE(
   1448         testEOS(omxNode, observer, &iBuffer, &oBuffer, false, eosFlag));
   1449 
   1450     // set state to idle
   1451     ASSERT_NO_FATAL_FAILURE(
   1452         changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer));
   1453     EXPECT_EQ(portDef.nBufferCountActual, listener->freeBuffers);
   1454     // set state to executing
   1455     ASSERT_NO_FATAL_FAILURE(changeStateIdletoLoaded(omxNode, observer, &iBuffer,
   1456                                                     &oBuffer, kPortIndexInput,
   1457                                                     kPortIndexOutput));
   1458 
   1459     returnval = producer->disconnect(
   1460         NATIVE_WINDOW_API_CPU, IGraphicBufferProducer::DisconnectMode::API);
   1461     ASSERT_EQ(returnval, 0);
   1462 }
   1463 
   1464 // Test end of stream
   1465 TEST_F(VideoEncHidlTest, EncodeTestEOS) {
   1466     description("Test EOS");
   1467     if (disableTest) return;
   1468     android::hardware::media::omx::V1_0::Status status;
   1469     uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
   1470     status = setRole(omxNode, gEnv->getRole().c_str());
   1471     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1472     OMX_PORT_PARAM_TYPE params;
   1473     status = getParam(omxNode, OMX_IndexParamVideoInit, &params);
   1474     if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
   1475         ASSERT_EQ(params.nPorts, 2U);
   1476         kPortIndexInput = params.nStartPortNumber;
   1477         kPortIndexOutput = kPortIndexInput + 1;
   1478     }
   1479 
   1480     // Configure input port
   1481     uint32_t nFrameWidth = 352;
   1482     uint32_t nFrameHeight = 288;
   1483     uint32_t xFramerate = (30U << 16);
   1484     OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatAndroidOpaque;
   1485     setupRAWPort(omxNode, kPortIndexInput, nFrameWidth, nFrameHeight, 0,
   1486                  xFramerate, eColorFormat);
   1487 
   1488     // CreateInputSurface
   1489     EXPECT_TRUE(omx->createInputSurface(
   1490                        [&](android::hardware::media::omx::V1_0::Status _s,
   1491                            sp<IGraphicBufferProducer> const& _nl,
   1492                            sp<IGraphicBufferSource> const& _n2) {
   1493                            status = _s;
   1494                            producer = _nl;
   1495                            source = _n2;
   1496                        })
   1497                     .isOk());
   1498     ASSERT_NE(producer, nullptr);
   1499     ASSERT_NE(source, nullptr);
   1500 
   1501     // setMaxDequeuedBufferCount
   1502     int32_t returnval;
   1503     int32_t value;
   1504     producer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
   1505                     [&returnval, &value](int32_t _s, int32_t _n1) {
   1506                         returnval = _s;
   1507                         value = _n1;
   1508                     });
   1509     ASSERT_EQ(returnval, 0);
   1510     OMX_PARAM_PORTDEFINITIONTYPE portDef;
   1511     status = getPortParam(omxNode, OMX_IndexParamPortDefinition,
   1512                           kPortIndexInput, &portDef);
   1513     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1514     ASSERT_EQ(::android::OK,
   1515               producer->setMaxDequeuedBufferCount(portDef.nBufferCountActual));
   1516 
   1517     // Connect :: Mock Producer Listener
   1518     IGraphicBufferProducer::QueueBufferOutput qbo;
   1519     sp<CodecProducerListener> listener =
   1520         new CodecProducerListener(portDef.nBufferCountActual + value, value);
   1521     producer->connect(
   1522         listener, NATIVE_WINDOW_API_CPU, false,
   1523         [&](int32_t _s, IGraphicBufferProducer::QueueBufferOutput const& _n1) {
   1524             returnval = _s;
   1525             qbo = _n1;
   1526         });
   1527     ASSERT_EQ(returnval, 0);
   1528 
   1529     portDef.nBufferCountActual = portDef.nBufferCountActual + value;
   1530     status = setPortParam(omxNode, OMX_IndexParamPortDefinition,
   1531                           kPortIndexInput, &portDef);
   1532     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1533 
   1534     // Do setInputSurface()
   1535     // enable MetaMode on input port
   1536     status = source->configure(
   1537         omxNode, android::hardware::graphics::common::V1_0::Dataspace::UNKNOWN);
   1538     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1539 
   1540     // set port mode
   1541     PortMode portMode[2];
   1542     portMode[0] = PortMode::DYNAMIC_ANW_BUFFER;
   1543     portMode[1] = PortMode::PRESET_BYTE_BUFFER;
   1544     status = omxNode->setPortMode(kPortIndexInput, portMode[0]);
   1545     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1546     status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
   1547     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1548 
   1549     android::Vector<BufferInfo> iBuffer, oBuffer;
   1550     // set state to idle
   1551     ASSERT_NO_FATAL_FAILURE(
   1552         changeStateLoadedtoIdle(omxNode, observer, &iBuffer, &oBuffer,
   1553                                 kPortIndexInput, kPortIndexOutput, portMode));
   1554     // set state to executing
   1555     ASSERT_NO_FATAL_FAILURE(changeStateIdletoExecute(omxNode, observer));
   1556 
   1557     // send EOS
   1558     status = source->signalEndOfInputStream();
   1559     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1560     ASSERT_NO_FATAL_FAILURE(waitOnInputConsumption(omxNode, observer, &iBuffer,
   1561                                                    &oBuffer, true, listener));
   1562     ASSERT_NO_FATAL_FAILURE(
   1563         testEOS(omxNode, observer, &iBuffer, &oBuffer, false, eosFlag));
   1564 
   1565     // set state to idle
   1566     ASSERT_NO_FATAL_FAILURE(
   1567         changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer));
   1568     EXPECT_EQ(portDef.nBufferCountActual, listener->freeBuffers);
   1569     // set state to executing
   1570     ASSERT_NO_FATAL_FAILURE(changeStateIdletoLoaded(omxNode, observer, &iBuffer,
   1571                                                     &oBuffer, kPortIndexInput,
   1572                                                     kPortIndexOutput));
   1573 
   1574     returnval = producer->disconnect(
   1575         NATIVE_WINDOW_API_CPU, IGraphicBufferProducer::DisconnectMode::API);
   1576     ASSERT_EQ(returnval, 0);
   1577 }
   1578 
   1579 int main(int argc, char** argv) {
   1580     gEnv = new ComponentTestEnvironment();
   1581     ::testing::AddGlobalTestEnvironment(gEnv);
   1582     ::testing::InitGoogleTest(&argc, argv);
   1583     int status = gEnv->initFromOptions(argc, argv);
   1584     if (status == 0) {
   1585         status = RUN_ALL_TESTS();
   1586         ALOGI("Test result = %d", status);
   1587     }
   1588     return status;
   1589 }
   1590