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