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_dec_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/media/omx/1.0/IOmx.h>
     25 #include <android/hardware/media/omx/1.0/IOmxNode.h>
     26 #include <android/hardware/media/omx/1.0/IOmxObserver.h>
     27 #include <android/hardware/media/omx/1.0/types.h>
     28 #include <android/hidl/allocator/1.0/IAllocator.h>
     29 #include <android/hidl/memory/1.0/IMapper.h>
     30 #include <android/hidl/memory/1.0/IMemory.h>
     31 
     32 using ::android::hardware::media::omx::V1_0::IOmx;
     33 using ::android::hardware::media::omx::V1_0::IOmxObserver;
     34 using ::android::hardware::media::omx::V1_0::IOmxNode;
     35 using ::android::hardware::media::omx::V1_0::Message;
     36 using ::android::hardware::media::omx::V1_0::CodecBuffer;
     37 using ::android::hardware::media::omx::V1_0::PortMode;
     38 using ::android::hidl::allocator::V1_0::IAllocator;
     39 using ::android::hidl::memory::V1_0::IMemory;
     40 using ::android::hidl::memory::V1_0::IMapper;
     41 using ::android::hardware::Return;
     42 using ::android::hardware::Void;
     43 using ::android::hardware::hidl_vec;
     44 using ::android::hardware::hidl_string;
     45 using ::android::sp;
     46 
     47 #include <VtsHalHidlTargetTestBase.h>
     48 #include <getopt.h>
     49 #include <media/hardware/HardwareAPI.h>
     50 #include <media_hidl_test_common.h>
     51 #include <media_video_hidl_test_common.h>
     52 #include <fstream>
     53 
     54 static ComponentTestEnvironment* gEnv = nullptr;
     55 
     56 // video decoder test fixture class
     57 class VideoDecHidlTest : public ::testing::VtsHalHidlTargetTestBase {
     58    private:
     59     typedef ::testing::VtsHalHidlTargetTestBase Super;
     60    public:
     61     ::std::string getTestCaseInfo() const override {
     62         return ::std::string() +
     63                 "Component: " + gEnv->getComponent().c_str() + " | " +
     64                 "Role: " + gEnv->getRole().c_str() + " | " +
     65                 "Instance: " + gEnv->getInstance().c_str() + " | " +
     66                 "Res: " + gEnv->getRes().c_str();
     67     }
     68 
     69     virtual void SetUp() override {
     70         Super::SetUp();
     71         disableTest = false;
     72         android::hardware::media::omx::V1_0::Status status;
     73         omx = Super::getService<IOmx>(gEnv->getInstance());
     74         ASSERT_NE(omx, nullptr);
     75         observer =
     76             new CodecObserver([this](Message msg, const BufferInfo* buffer) {
     77                 handleMessage(msg, buffer);
     78             });
     79         ASSERT_NE(observer, nullptr);
     80         if (strncmp(gEnv->getComponent().c_str(), "OMX.", 4) != 0)
     81             disableTest = true;
     82         EXPECT_TRUE(omx->allocateNode(
     83                            gEnv->getComponent(), observer,
     84                            [&](android::hardware::media::omx::V1_0::Status _s,
     85                                sp<IOmxNode> const& _nl) {
     86                                status = _s;
     87                                this->omxNode = _nl;
     88                            })
     89                         .isOk());
     90         if (status == android::hardware::media::omx::V1_0::Status::NAME_NOT_FOUND) {
     91             disableTest = true;
     92             std::cout << "[   WARN   ] Test Disabled, component not present\n";
     93             return;
     94         }
     95         ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
     96         ASSERT_NE(omxNode, nullptr);
     97         ASSERT_NE(gEnv->getRole().empty(), true) << "Invalid Component Role";
     98         struct StringToName {
     99             const char* Name;
    100             standardComp CompName;
    101         };
    102         const StringToName kStringToName[] = {
    103             {"h263", h263}, {"avc", avc}, {"mpeg2", mpeg2}, {"mpeg4", mpeg4},
    104             {"hevc", hevc}, {"vp8", vp8}, {"vp9", vp9},
    105         };
    106         const size_t kNumStringToName =
    107             sizeof(kStringToName) / sizeof(kStringToName[0]);
    108         const char* pch;
    109         char substring[OMX_MAX_STRINGNAME_SIZE];
    110         strcpy(substring, gEnv->getRole().c_str());
    111         pch = strchr(substring, '.');
    112         ASSERT_NE(pch, nullptr);
    113         compName = unknown_comp;
    114         for (size_t i = 0; i < kNumStringToName; ++i) {
    115             if (!strcasecmp(pch + 1, kStringToName[i].Name)) {
    116                 compName = kStringToName[i].CompName;
    117                 break;
    118             }
    119         }
    120         if (compName == unknown_comp) disableTest = true;
    121         struct CompToCompression {
    122             standardComp CompName;
    123             OMX_VIDEO_CODINGTYPE eCompressionFormat;
    124         };
    125         static const CompToCompression kCompToCompression[] = {
    126             {h263, OMX_VIDEO_CodingH263},   {avc, OMX_VIDEO_CodingAVC},
    127             {mpeg2, OMX_VIDEO_CodingMPEG2}, {mpeg4, OMX_VIDEO_CodingMPEG4},
    128             {hevc, OMX_VIDEO_CodingHEVC},   {vp8, OMX_VIDEO_CodingVP8},
    129             {vp9, OMX_VIDEO_CodingVP9},
    130         };
    131         static const size_t kNumCompToCompression =
    132             sizeof(kCompToCompression) / sizeof(kCompToCompression[0]);
    133         size_t i;
    134         for (i = 0; i < kNumCompToCompression; ++i) {
    135             if (kCompToCompression[i].CompName == compName) {
    136                 eCompressionFormat = kCompToCompression[i].eCompressionFormat;
    137                 break;
    138             }
    139         }
    140         if (i == kNumCompToCompression) disableTest = true;
    141         portMode[0] = portMode[1] = PortMode::PRESET_BYTE_BUFFER;
    142         eosFlag = false;
    143         framesReceived = 0;
    144         timestampUs = 0;
    145         timestampDevTest = false;
    146         isSecure = false;
    147         portSettingsChange = false;
    148         size_t suffixLen = strlen(".secure");
    149         if (strlen(gEnv->getComponent().c_str()) >= suffixLen) {
    150             isSecure =
    151                 !strcmp(gEnv->getComponent().c_str() +
    152                             strlen(gEnv->getComponent().c_str()) - suffixLen,
    153                         ".secure");
    154         }
    155         if (isSecure) disableTest = true;
    156         if (disableTest) std::cout << "[   WARN   ] Test Disabled \n";
    157     }
    158 
    159     virtual void TearDown() override {
    160         if (omxNode != nullptr) {
    161             // If you have encountered a fatal failure, it is possible that
    162             // freeNode() will not go through. Instead of hanging the app.
    163             // let it pass through and report errors
    164             if (::testing::Test::HasFatalFailure()) return;
    165             EXPECT_TRUE((omxNode->freeNode()).isOk());
    166             omxNode = nullptr;
    167         }
    168         Super::TearDown();
    169     }
    170 
    171     // callback function to process messages received by onMessages() from IL
    172     // client.
    173     void handleMessage(Message msg, const BufferInfo* buffer) {
    174         (void)buffer;
    175         if (msg.type == Message::Type::FILL_BUFFER_DONE) {
    176             if (msg.data.extendedBufferData.flags & OMX_BUFFERFLAG_EOS) {
    177                 eosFlag = true;
    178             }
    179             if (msg.data.extendedBufferData.rangeLength != 0) {
    180                 framesReceived += 1;
    181                 // For decoder components current timestamp always exceeds
    182                 // previous timestamp
    183                 EXPECT_GE(msg.data.extendedBufferData.timestampUs, timestampUs);
    184                 timestampUs = msg.data.extendedBufferData.timestampUs;
    185                 // Test if current timestamp is among the list of queued
    186                 // timestamps
    187                 if (timestampDevTest) {
    188                     bool tsHit = false;
    189                     android::List<uint64_t>::iterator it =
    190                         timestampUslist.begin();
    191                     while (it != timestampUslist.end()) {
    192                         if (*it == timestampUs) {
    193                             timestampUslist.erase(it);
    194                             tsHit = true;
    195                             break;
    196                         }
    197                         it++;
    198                     }
    199                     if (tsHit == false) {
    200                         if (timestampUslist.empty() == false) {
    201                             EXPECT_EQ(tsHit, true)
    202                                 << "TimeStamp not recognized";
    203                         } else {
    204                             std::cout << "[   INFO   ] Received non-zero "
    205                                          "output / TimeStamp not recognized \n";
    206                         }
    207                     }
    208                 }
    209 #define WRITE_OUTPUT 0
    210 #if WRITE_OUTPUT
    211                 static int count = 0;
    212                 FILE* ofp = nullptr;
    213                 if (count)
    214                     ofp = fopen("out.bin", "ab");
    215                 else
    216                     ofp = fopen("out.bin", "wb");
    217                 if (ofp != nullptr &&
    218                     portMode[1] == PortMode::PRESET_BYTE_BUFFER) {
    219                     fwrite(static_cast<void*>(buffer->mMemory->getPointer()),
    220                            sizeof(char),
    221                            msg.data.extendedBufferData.rangeLength, ofp);
    222                     fclose(ofp);
    223                     count++;
    224                 }
    225 #endif
    226             }
    227         } else if (msg.type == Message::Type::EVENT) {
    228             if (msg.data.eventData.event == OMX_EventPortSettingsChanged) {
    229                 if ((msg.data.eventData.data2 == OMX_IndexParamPortDefinition ||
    230                      msg.data.eventData.data2 == 0)) {
    231                     portSettingsChange = true;
    232                 }
    233             }
    234         }
    235     }
    236 
    237     enum standardComp {
    238         h263,
    239         avc,
    240         mpeg2,
    241         mpeg4,
    242         hevc,
    243         vp8,
    244         vp9,
    245         unknown_comp,
    246     };
    247 
    248     sp<IOmx> omx;
    249     sp<CodecObserver> observer;
    250     sp<IOmxNode> omxNode;
    251     standardComp compName;
    252     OMX_VIDEO_CODINGTYPE eCompressionFormat;
    253     bool disableTest;
    254     PortMode portMode[2];
    255     bool eosFlag;
    256     uint32_t framesReceived;
    257     uint64_t timestampUs;
    258     ::android::List<uint64_t> timestampUslist;
    259     bool timestampDevTest;
    260     bool isSecure;
    261     bool portSettingsChange;
    262 
    263    protected:
    264     static void description(const std::string& description) {
    265         RecordProperty("description", description);
    266     }
    267 };
    268 
    269 // Set Default port param.
    270 void setDefaultPortParam(sp<IOmxNode> omxNode, OMX_U32 portIndex,
    271                          OMX_VIDEO_CODINGTYPE eCompressionFormat,
    272                          OMX_COLOR_FORMATTYPE eColorFormat,
    273                          OMX_U32 nFrameWidth = 352, OMX_U32 nFrameHeight = 288,
    274                          OMX_U32 nBitrate = 0,
    275                          OMX_U32 xFramerate = (24U << 16)) {
    276     switch ((int)eCompressionFormat) {
    277         case OMX_VIDEO_CodingUnused:
    278             setupRAWPort(omxNode, portIndex, nFrameWidth, nFrameHeight,
    279                          nBitrate, xFramerate, eColorFormat);
    280             break;
    281         default:
    282             break;
    283     }
    284 }
    285 
    286 // In decoder components, often the input port parameters get updated upon
    287 // parsing the header of elementary stream. Client needs to collect this
    288 // information to reconfigure other ports that share data with this input
    289 // port.
    290 void getInputChannelInfo(sp<IOmxNode> omxNode, OMX_U32 kPortIndexInput,
    291                          uint32_t* nFrameWidth, uint32_t* nFrameHeight,
    292                          uint32_t* xFramerate) {
    293     android::hardware::media::omx::V1_0::Status status;
    294     *nFrameWidth = 352;
    295     *nFrameHeight = 288;
    296     *xFramerate = (24U << 16);
    297 
    298     OMX_PARAM_PORTDEFINITIONTYPE portDef;
    299     status = getPortParam(omxNode, OMX_IndexParamPortDefinition,
    300                           kPortIndexInput, &portDef);
    301     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
    302     if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
    303         *nFrameWidth = portDef.format.video.nFrameWidth;
    304         *nFrameHeight = portDef.format.video.nFrameHeight;
    305         *xFramerate = portDef.format.video.xFramerate;
    306     }
    307 }
    308 
    309 // number of elementary streams per component
    310 #define STREAM_COUNT 2
    311 // LookUpTable of clips and metadata for component testing
    312 void GetURLForComponent(VideoDecHidlTest::standardComp comp, char* mURL,
    313                         char* info, size_t streamIndex = 1) {
    314     struct CompToURL {
    315         VideoDecHidlTest::standardComp comp;
    316         const char mURL[STREAM_COUNT][512];
    317         const char info[STREAM_COUNT][512];
    318     };
    319     ASSERT_TRUE(streamIndex < STREAM_COUNT);
    320 
    321     static const CompToURL kCompToURL[] = {
    322         {VideoDecHidlTest::standardComp::avc,
    323          {"bbb_avc_176x144_300kbps_60fps.h264",
    324           "bbb_avc_640x360_768kbps_30fps.h264"},
    325          {"bbb_avc_176x144_300kbps_60fps.info",
    326           "bbb_avc_640x360_768kbps_30fps.info"}},
    327         {VideoDecHidlTest::standardComp::hevc,
    328          {"bbb_hevc_176x144_176kbps_60fps.hevc",
    329           "bbb_hevc_640x360_1600kbps_30fps.hevc"},
    330          {"bbb_hevc_176x144_176kbps_60fps.info",
    331           "bbb_hevc_640x360_1600kbps_30fps.info"}},
    332         {VideoDecHidlTest::standardComp::mpeg2,
    333          {"bbb_mpeg2_176x144_105kbps_25fps.m2v",
    334           "bbb_mpeg2_352x288_1mbps_60fps.m2v"},
    335          {"bbb_mpeg2_176x144_105kbps_25fps.info",
    336           "bbb_mpeg2_352x288_1mbps_60fps.info"}},
    337         {VideoDecHidlTest::standardComp::h263,
    338          {"", "bbb_h263_352x288_300kbps_12fps.h263"},
    339          {"", "bbb_h263_352x288_300kbps_12fps.info"}},
    340         {VideoDecHidlTest::standardComp::mpeg4,
    341          {"", "bbb_mpeg4_352x288_512kbps_30fps.m4v"},
    342          {"", "bbb_mpeg4_352x288_512kbps_30fps.info"}},
    343         {VideoDecHidlTest::standardComp::vp8,
    344          {"bbb_vp8_176x144_240kbps_60fps.vp8",
    345           "bbb_vp8_640x360_2mbps_30fps.vp8"},
    346          {"bbb_vp8_176x144_240kbps_60fps.info",
    347           "bbb_vp8_640x360_2mbps_30fps.info"}},
    348         {VideoDecHidlTest::standardComp::vp9,
    349          {"bbb_vp9_176x144_285kbps_60fps.vp9",
    350           "bbb_vp9_640x360_1600kbps_30fps.vp9"},
    351          {"bbb_vp9_176x144_285kbps_60fps.info",
    352           "bbb_vp9_640x360_1600kbps_30fps.info"}},
    353     };
    354 
    355     for (size_t i = 0; i < sizeof(kCompToURL) / sizeof(kCompToURL[0]); ++i) {
    356         if (kCompToURL[i].comp == comp) {
    357             strcat(mURL, kCompToURL[i].mURL[streamIndex]);
    358             strcat(info, kCompToURL[i].info[streamIndex]);
    359             return;
    360         }
    361     }
    362 }
    363 
    364 // port settings reconfiguration during runtime. reconfigures frame dimensions
    365 void portReconfiguration(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
    366                          android::Vector<BufferInfo>* iBuffer,
    367                          android::Vector<BufferInfo>* oBuffer,
    368                          OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput,
    369                          Message msg, PortMode oPortMode, void* args) {
    370     android::hardware::media::omx::V1_0::Status status;
    371     (void)args;
    372 
    373     if (msg.data.eventData.event == OMX_EventPortSettingsChanged) {
    374         ASSERT_EQ(msg.data.eventData.data1, kPortIndexOutput);
    375         if (msg.data.eventData.data2 == OMX_IndexParamPortDefinition ||
    376             msg.data.eventData.data2 == 0) {
    377             // Components can send various kinds of port settings changed events
    378             // all at once. Before committing to a full port reconfiguration,
    379             // defer any events waiting in the queue to be addressed to a later
    380             // point.
    381             android::List<Message> msgQueueDefer;
    382             while (1) {
    383                 status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
    384                                                   iBuffer, oBuffer);
    385                 if (status !=
    386                     android::hardware::media::omx::V1_0::Status::TIMED_OUT) {
    387                     msgQueueDefer.push_back(msg);
    388                     continue;
    389                 } else
    390                     break;
    391             }
    392             status = omxNode->sendCommand(
    393                 toRawCommandType(OMX_CommandPortDisable), kPortIndexOutput);
    394             ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
    395 
    396             status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer,
    397                                               oBuffer);
    398             if (status ==
    399                 android::hardware::media::omx::V1_0::Status::TIMED_OUT) {
    400                 for (size_t i = 0; i < oBuffer->size(); ++i) {
    401                     // test if client got all its buffers back
    402                     EXPECT_EQ((*oBuffer)[i].owner, client);
    403                     // free the buffers
    404                     status =
    405                         omxNode->freeBuffer(kPortIndexOutput, (*oBuffer)[i].id);
    406                     ASSERT_EQ(status,
    407                               android::hardware::media::omx::V1_0::Status::OK);
    408                 }
    409                 status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
    410                                                   iBuffer, oBuffer);
    411                 ASSERT_EQ(status,
    412                           android::hardware::media::omx::V1_0::Status::OK);
    413                 ASSERT_EQ(msg.type, Message::Type::EVENT);
    414                 ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
    415                 ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortDisable);
    416                 ASSERT_EQ(msg.data.eventData.data2, kPortIndexOutput);
    417 
    418                 // set Port Params
    419                 uint32_t nFrameWidth, nFrameHeight, xFramerate;
    420                 getInputChannelInfo(omxNode, kPortIndexInput, &nFrameWidth,
    421                                     &nFrameHeight, &xFramerate);
    422                 // get configured color format
    423                 OMX_PARAM_PORTDEFINITIONTYPE portDef;
    424                 status = getPortParam(omxNode, OMX_IndexParamPortDefinition,
    425                                       kPortIndexOutput, &portDef);
    426                 setDefaultPortParam(omxNode, kPortIndexOutput,
    427                                     OMX_VIDEO_CodingUnused,
    428                                     portDef.format.video.eColorFormat,
    429                                     nFrameWidth, nFrameHeight, 0, xFramerate);
    430 
    431                 // If you can disable a port, then you should be able to
    432                 // enable it as well
    433                 status = omxNode->sendCommand(
    434                     toRawCommandType(OMX_CommandPortEnable), kPortIndexOutput);
    435                 ASSERT_EQ(status,
    436                           android::hardware::media::omx::V1_0::Status::OK);
    437 
    438                 // do not enable the port until all the buffers are supplied
    439                 status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
    440                                                   iBuffer, oBuffer);
    441                 ASSERT_EQ(
    442                     status,
    443                     android::hardware::media::omx::V1_0::Status::TIMED_OUT);
    444 
    445                 ASSERT_NO_FATAL_FAILURE(allocatePortBuffers(
    446                     omxNode, oBuffer, kPortIndexOutput, oPortMode, true));
    447                 status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
    448                                                   iBuffer, oBuffer);
    449                 ASSERT_EQ(status,
    450                           android::hardware::media::omx::V1_0::Status::OK);
    451                 ASSERT_EQ(msg.type, Message::Type::EVENT);
    452                 ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortEnable);
    453                 ASSERT_EQ(msg.data.eventData.data2, kPortIndexOutput);
    454 
    455                 // Push back deferred messages to the list
    456                 android::List<Message>::iterator it = msgQueueDefer.begin();
    457                 while (it != msgQueueDefer.end()) {
    458                     status = omxNode->dispatchMessage(*it);
    459                     ASSERT_EQ(
    460                         status,
    461                         ::android::hardware::media::omx::V1_0::Status::OK);
    462                     it++;
    463                 }
    464 
    465                 // dispatch output buffers
    466                 for (size_t i = 0; i < oBuffer->size(); i++) {
    467                     ASSERT_NO_FATAL_FAILURE(
    468                         dispatchOutputBuffer(omxNode, oBuffer, i, oPortMode));
    469                 }
    470             } else {
    471                 ASSERT_TRUE(false);
    472             }
    473         } else if (msg.data.eventData.data2 ==
    474                    OMX_IndexConfigCommonOutputCrop) {
    475             std::cout << "[   INFO   ] OMX_EventPortSettingsChanged/ "
    476                          "OMX_IndexConfigCommonOutputCrop not handled \n";
    477         } else if (msg.data.eventData.data2 == OMX_IndexVendorStartUnused + 3) {
    478             std::cout << "[   INFO   ] OMX_EventPortSettingsChanged/ "
    479                          "kDescribeColorAspectsIndex not handled \n";
    480         }
    481     } else if (msg.data.eventData.event == OMX_EventError) {
    482         std::cerr << "[   ERROR   ] OMX_EventError/ "
    483                      "Decode Frame Call might be failed \n";
    484         ASSERT_TRUE(false);
    485     } else {
    486         // something unexpected happened
    487         ASSERT_TRUE(false);
    488     }
    489 }
    490 
    491 // blocking call to ensures application to Wait till all the inputs are consumed
    492 void waitOnInputConsumption(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
    493                             android::Vector<BufferInfo>* iBuffer,
    494                             android::Vector<BufferInfo>* oBuffer,
    495                             OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput,
    496                             PortMode oPortMode) {
    497     android::hardware::media::omx::V1_0::Status status;
    498     Message msg;
    499     int timeOut = TIMEOUT_COUNTER_Q;
    500 
    501     while (timeOut--) {
    502         size_t i = 0;
    503         status =
    504             observer->dequeueMessage(&msg, DEFAULT_TIMEOUT_Q, iBuffer, oBuffer);
    505         if (status == android::hardware::media::omx::V1_0::Status::OK) {
    506             ASSERT_EQ(msg.type, Message::Type::EVENT);
    507             ASSERT_NO_FATAL_FAILURE(portReconfiguration(
    508                 omxNode, observer, iBuffer, oBuffer, kPortIndexInput,
    509                 kPortIndexOutput, msg, oPortMode, nullptr));
    510         }
    511         // status == TIMED_OUT, it could be due to process time being large
    512         // than DEFAULT_TIMEOUT or component needs output buffers to start
    513         // processing.
    514         for (; i < iBuffer->size(); i++) {
    515             if ((*iBuffer)[i].owner != client) break;
    516         }
    517         if (i == iBuffer->size()) break;
    518 
    519         // Dispatch an output buffer assuming outQueue.empty() is true
    520         size_t index;
    521         if ((index = getEmptyBufferID(oBuffer)) < oBuffer->size()) {
    522             ASSERT_NO_FATAL_FAILURE(
    523                 dispatchOutputBuffer(omxNode, oBuffer, index, oPortMode));
    524             timeOut = TIMEOUT_COUNTER_Q;
    525         }
    526     }
    527 }
    528 
    529 // Decode N Frames
    530 void decodeNFrames(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
    531                    android::Vector<BufferInfo>* iBuffer,
    532                    android::Vector<BufferInfo>* oBuffer,
    533                    OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput,
    534                    std::ifstream& eleStream, android::Vector<FrameData>* Info,
    535                    int offset, int range, PortMode oPortMode,
    536                    bool signalEOS = true) {
    537     android::hardware::media::omx::V1_0::Status status;
    538     Message msg;
    539     size_t index;
    540     uint32_t flags = 0;
    541     int frameID = offset;
    542     int timeOut = TIMEOUT_COUNTER_Q;
    543     bool iQueued, oQueued;
    544 
    545     while (1) {
    546         iQueued = oQueued = false;
    547         status =
    548             observer->dequeueMessage(&msg, DEFAULT_TIMEOUT_Q, iBuffer, oBuffer);
    549         // Port Reconfiguration
    550         if (status == android::hardware::media::omx::V1_0::Status::OK &&
    551             msg.type == Message::Type::EVENT) {
    552             ASSERT_NO_FATAL_FAILURE(portReconfiguration(
    553                 omxNode, observer, iBuffer, oBuffer, kPortIndexInput,
    554                 kPortIndexOutput, msg, oPortMode, nullptr));
    555         }
    556 
    557         if (frameID == (int)Info->size() || frameID == (offset + range)) break;
    558 
    559         // Dispatch input buffer
    560         if ((index = getEmptyBufferID(iBuffer)) < iBuffer->size()) {
    561             char* ipBuffer = static_cast<char*>(
    562                 static_cast<void*>((*iBuffer)[index].mMemory->getPointer()));
    563             ASSERT_LE((*Info)[frameID].bytesCount,
    564                       static_cast<int>((*iBuffer)[index].mMemory->getSize()));
    565             eleStream.read(ipBuffer, (*Info)[frameID].bytesCount);
    566             ASSERT_EQ(eleStream.gcount(), (*Info)[frameID].bytesCount);
    567             flags = (*Info)[frameID].flags;
    568             // Indicate to omx core that the buffer contains a full frame worth
    569             // of data
    570             flags |= OMX_BUFFERFLAG_ENDOFFRAME;
    571             // Indicate the omx core that this is the last buffer it needs to
    572             // process
    573             if (signalEOS && ((frameID == (int)Info->size() - 1) ||
    574                               (frameID == (offset + range - 1))))
    575                 flags |= OMX_BUFFERFLAG_EOS;
    576             ASSERT_NO_FATAL_FAILURE(dispatchInputBuffer(
    577                 omxNode, iBuffer, index, (*Info)[frameID].bytesCount, flags,
    578                 (*Info)[frameID].timestamp));
    579             frameID++;
    580             iQueued = true;
    581         }
    582         // Dispatch output buffer
    583         if ((index = getEmptyBufferID(oBuffer)) < oBuffer->size()) {
    584             ASSERT_NO_FATAL_FAILURE(
    585                 dispatchOutputBuffer(omxNode, oBuffer, index, oPortMode));
    586             oQueued = true;
    587         }
    588         // Reset Counters when either input or output buffer is dispatched
    589         if (iQueued || oQueued)
    590             timeOut = TIMEOUT_COUNTER_Q;
    591         else
    592             timeOut--;
    593         if (timeOut == 0) {
    594             ASSERT_TRUE(false) << "Wait on Input/Output is found indefinite";
    595         }
    596     }
    597 }
    598 
    599 // DescribeColorFormatParams Copy Constructor (Borrowed from OMXUtils.cpp)
    600 android::DescribeColorFormatParams::DescribeColorFormatParams(
    601     const android::DescribeColorFormat2Params& params) {
    602     eColorFormat = params.eColorFormat;
    603     nFrameWidth = params.nFrameWidth;
    604     nFrameHeight = params.nFrameHeight;
    605     nStride = params.nStride;
    606     nSliceHeight = params.nSliceHeight;
    607     bUsingNativeBuffers = params.bUsingNativeBuffers;
    608 };
    609 
    610 bool isColorFormatFlexibleYUV(sp<IOmxNode> omxNode,
    611                               OMX_COLOR_FORMATTYPE eColorFormat) {
    612     android::hardware::media::omx::V1_0::Status status;
    613     unsigned int index = OMX_IndexMax, index2 = OMX_IndexMax;
    614     omxNode->getExtensionIndex(
    615         "OMX.google.android.index.describeColorFormat",
    616         [&index](android::hardware::media::omx::V1_0::Status _s,
    617                           unsigned int _nl) {
    618             if (_s == ::android::hardware::media::omx::V1_0::Status::OK)
    619                 index = _nl;
    620         });
    621     omxNode->getExtensionIndex(
    622         "OMX.google.android.index.describeColorFormat2",
    623         [&index2](android::hardware::media::omx::V1_0::Status _s,
    624                            unsigned int _nl) {
    625             if (_s == ::android::hardware::media::omx::V1_0::Status::OK)
    626                 index2 = _nl;
    627         });
    628 
    629     android::DescribeColorFormat2Params describeParams;
    630     describeParams.eColorFormat = eColorFormat;
    631     describeParams.nFrameWidth = 128;
    632     describeParams.nFrameHeight = 128;
    633     describeParams.nStride = 128;
    634     describeParams.nSliceHeight = 128;
    635     describeParams.bUsingNativeBuffers = OMX_FALSE;
    636     if (index != OMX_IndexMax) {
    637         android::DescribeColorFormatParams describeParamsV1(describeParams);
    638         status = getParam(omxNode, static_cast<OMX_INDEXTYPE>(index),
    639                           &describeParamsV1);
    640         if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
    641             android::MediaImage& img = describeParamsV1.sMediaImage;
    642             if (img.mType == android::MediaImage::MEDIA_IMAGE_TYPE_YUV) {
    643                 if (img.mNumPlanes == 3 &&
    644                     img.mPlane[img.Y].mHorizSubsampling == 1 &&
    645                     img.mPlane[img.Y].mVertSubsampling == 1) {
    646                     if (img.mPlane[img.U].mHorizSubsampling == 2 &&
    647                         img.mPlane[img.U].mVertSubsampling == 2 &&
    648                         img.mPlane[img.V].mHorizSubsampling == 2 &&
    649                         img.mPlane[img.V].mVertSubsampling == 2) {
    650                         if (img.mBitDepth <= 8) {
    651                             return true;
    652                         }
    653                     }
    654                 }
    655             }
    656         }
    657     } else if (index2 != OMX_IndexMax) {
    658         status = getParam(omxNode, static_cast<OMX_INDEXTYPE>(index2),
    659                           &describeParams);
    660         android::MediaImage2& img = describeParams.sMediaImage;
    661         if (img.mType == android::MediaImage2::MEDIA_IMAGE_TYPE_YUV) {
    662             if (img.mNumPlanes == 3 &&
    663                 img.mPlane[img.Y].mHorizSubsampling == 1 &&
    664                 img.mPlane[img.Y].mVertSubsampling == 1) {
    665                 if (img.mPlane[img.U].mHorizSubsampling == 2 &&
    666                     img.mPlane[img.U].mVertSubsampling == 2 &&
    667                     img.mPlane[img.V].mHorizSubsampling == 2 &&
    668                     img.mPlane[img.V].mVertSubsampling == 2) {
    669                     if (img.mBitDepth <= 8) {
    670                         return true;
    671                     }
    672                 }
    673             }
    674         }
    675     }
    676     return false;
    677 }
    678 
    679 // get default color format for output port
    680 void getDefaultColorFormat(sp<IOmxNode> omxNode, OMX_U32 kPortIndexOutput,
    681                            PortMode oPortMode,
    682                            OMX_COLOR_FORMATTYPE* eColorFormat) {
    683     android::hardware::media::omx::V1_0::Status status;
    684     OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat;
    685     *eColorFormat = OMX_COLOR_FormatUnused;
    686     portFormat.nIndex = 0;
    687     while (portFormat.nIndex < 512) {
    688         status = getPortParam(omxNode, OMX_IndexParamVideoPortFormat,
    689                               kPortIndexOutput, &portFormat);
    690         if (status != ::android::hardware::media::omx::V1_0::Status::OK) break;
    691         EXPECT_EQ(portFormat.eCompressionFormat, OMX_VIDEO_CodingUnused);
    692         if (oPortMode != PortMode::PRESET_BYTE_BUFFER) {
    693             *eColorFormat = portFormat.eColorFormat;
    694             break;
    695         }
    696         if (isColorFormatFlexibleYUV(omxNode, portFormat.eColorFormat)) {
    697             *eColorFormat = portFormat.eColorFormat;
    698             break;
    699         }
    700         if (OMX_COLOR_FormatYUV420SemiPlanar == portFormat.eColorFormat ||
    701             OMX_COLOR_FormatYUV420Planar == portFormat.eColorFormat ||
    702             OMX_COLOR_FormatYUV420PackedPlanar == portFormat.eColorFormat ||
    703             OMX_COLOR_FormatYUV420PackedSemiPlanar == portFormat.eColorFormat) {
    704             *eColorFormat = portFormat.eColorFormat;
    705             break;
    706         }
    707         portFormat.nIndex++;
    708     }
    709 }
    710 
    711 // set component role
    712 TEST_F(VideoDecHidlTest, SetRole) {
    713     description("Test Set Component Role");
    714     if (disableTest) return;
    715     android::hardware::media::omx::V1_0::Status status;
    716     status = setRole(omxNode, gEnv->getRole().c_str());
    717     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
    718 }
    719 
    720 // port format enumeration
    721 TEST_F(VideoDecHidlTest, EnumeratePortFormat) {
    722     description("Test Component on Mandatory Port Parameters (Port Format)");
    723     if (disableTest) return;
    724     android::hardware::media::omx::V1_0::Status status;
    725     uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
    726     OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatYUV420Planar;
    727     OMX_U32 xFramerate = (24U << 16);
    728     status = setRole(omxNode, gEnv->getRole().c_str());
    729     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
    730     OMX_PORT_PARAM_TYPE params;
    731     status = getParam(omxNode, OMX_IndexParamVideoInit, &params);
    732     if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
    733         ASSERT_EQ(params.nPorts, 2U);
    734         kPortIndexInput = params.nStartPortNumber;
    735         kPortIndexOutput = kPortIndexInput + 1;
    736     }
    737     status = setVideoPortFormat(omxNode, kPortIndexInput, eCompressionFormat,
    738                                 OMX_COLOR_FormatUnused, 0U);
    739     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
    740     status =
    741         setVideoPortFormat(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
    742                            eColorFormat, xFramerate);
    743     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
    744 }
    745 
    746 // test port settings reconfiguration, elementary stream decode and timestamp
    747 // deviation
    748 TEST_F(VideoDecHidlTest, DecodeTest) {
    749     description("Tests Port Reconfiguration, Decode and timestamp deviation");
    750     if (disableTest) return;
    751     android::hardware::media::omx::V1_0::Status status;
    752     uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
    753     status = setRole(omxNode, gEnv->getRole().c_str());
    754     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
    755     OMX_PORT_PARAM_TYPE params;
    756     status = getParam(omxNode, OMX_IndexParamVideoInit, &params);
    757     if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
    758         ASSERT_EQ(params.nPorts, 2U);
    759         kPortIndexInput = params.nStartPortNumber;
    760         kPortIndexOutput = kPortIndexInput + 1;
    761     }
    762     char mURL[512], info[512];
    763     strcpy(mURL, gEnv->getRes().c_str());
    764     strcpy(info, gEnv->getRes().c_str());
    765     GetURLForComponent(compName, mURL, info);
    766 
    767     std::ifstream eleStream, eleInfo;
    768 
    769     eleInfo.open(info);
    770     ASSERT_EQ(eleInfo.is_open(), true);
    771     android::Vector<FrameData> Info;
    772     int bytesCount = 0, maxBytesCount = 0;
    773     uint32_t flags = 0;
    774     uint32_t timestamp = 0;
    775     timestampDevTest = true;
    776     while (1) {
    777         if (!(eleInfo >> bytesCount)) break;
    778         eleInfo >> flags;
    779         eleInfo >> timestamp;
    780         Info.push_back({bytesCount, flags, timestamp});
    781         if (timestampDevTest && (flags != OMX_BUFFERFLAG_CODECCONFIG))
    782             timestampUslist.push_back(timestamp);
    783         if (maxBytesCount < bytesCount) maxBytesCount = bytesCount;
    784     }
    785     eleInfo.close();
    786 
    787     // As the frame sizes are known ahead, use it to configure i/p buffer size
    788     maxBytesCount = ALIGN_POWER_OF_TWO(maxBytesCount, 10);
    789     status = setPortBufferSize(omxNode, kPortIndexInput, maxBytesCount);
    790     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
    791 
    792     // set port mode
    793     portMode[0] = PortMode::PRESET_BYTE_BUFFER;
    794     portMode[1] = PortMode::DYNAMIC_ANW_BUFFER;
    795     status = omxNode->setPortMode(kPortIndexInput, portMode[0]);
    796     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
    797     status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
    798     if (status != ::android::hardware::media::omx::V1_0::Status::OK) {
    799         portMode[1] = PortMode::PRESET_BYTE_BUFFER;
    800         status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
    801         ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
    802     }
    803 
    804     // set Port Params
    805     uint32_t nFrameWidth, nFrameHeight, xFramerate;
    806     getInputChannelInfo(omxNode, kPortIndexInput, &nFrameWidth, &nFrameHeight,
    807                         &xFramerate);
    808     // get default color format
    809     OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatUnused;
    810     getDefaultColorFormat(omxNode, kPortIndexOutput, portMode[1],
    811                           &eColorFormat);
    812     ASSERT_NE(eColorFormat, OMX_COLOR_FormatUnused);
    813     status =
    814         setVideoPortFormat(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
    815                            eColorFormat, xFramerate);
    816     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
    817     setDefaultPortParam(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
    818                         eColorFormat, nFrameWidth, nFrameHeight, 0, xFramerate);
    819 
    820     android::Vector<BufferInfo> iBuffer, oBuffer;
    821 
    822     // set state to idle
    823     ASSERT_NO_FATAL_FAILURE(changeStateLoadedtoIdle(
    824         omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
    825         kPortIndexOutput, portMode, true));
    826     // set state to executing
    827     ASSERT_NO_FATAL_FAILURE(changeStateIdletoExecute(omxNode, observer));
    828 
    829     // Port Reconfiguration
    830     eleStream.open(mURL, std::ifstream::binary);
    831     ASSERT_EQ(eleStream.is_open(), true);
    832     ASSERT_NO_FATAL_FAILURE(decodeNFrames(
    833         omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
    834         kPortIndexOutput, eleStream, &Info, 0, (int)Info.size(), portMode[1]));
    835     eleStream.close();
    836     ASSERT_NO_FATAL_FAILURE(
    837         waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer,
    838                                kPortIndexInput, kPortIndexOutput, portMode[1]));
    839     ASSERT_NO_FATAL_FAILURE(testEOS(
    840         omxNode, observer, &iBuffer, &oBuffer, false, eosFlag, portMode,
    841         portReconfiguration, kPortIndexInput, kPortIndexOutput, nullptr));
    842     if (timestampDevTest) EXPECT_EQ(timestampUslist.empty(), true);
    843     // set state to idle
    844     ASSERT_NO_FATAL_FAILURE(
    845         changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer));
    846     // set state to executing
    847     ASSERT_NO_FATAL_FAILURE(changeStateIdletoLoaded(omxNode, observer, &iBuffer,
    848                                                     &oBuffer, kPortIndexInput,
    849                                                     kPortIndexOutput));
    850 }
    851 
    852 // Test for adaptive playback support
    853 TEST_F(VideoDecHidlTest, AdaptivePlaybackTest) {
    854     description("Tests for Adaptive Playback support");
    855     if (disableTest) return;
    856     if (!(compName == avc || compName == hevc || compName == vp8 ||
    857           compName == vp9 || compName == mpeg2))
    858         return;
    859     android::hardware::media::omx::V1_0::Status status;
    860     uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
    861     status = setRole(omxNode, gEnv->getRole().c_str());
    862     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
    863     OMX_PORT_PARAM_TYPE params;
    864     status = getParam(omxNode, OMX_IndexParamVideoInit, &params);
    865     if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
    866         ASSERT_EQ(params.nPorts, 2U);
    867         kPortIndexInput = params.nStartPortNumber;
    868         kPortIndexOutput = kPortIndexInput + 1;
    869     }
    870 
    871     // set port mode
    872     portMode[0] = PortMode::PRESET_BYTE_BUFFER;
    873     portMode[1] = PortMode::DYNAMIC_ANW_BUFFER;
    874     status = omxNode->setPortMode(kPortIndexInput, portMode[0]);
    875     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
    876     status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
    877     if (status != ::android::hardware::media::omx::V1_0::Status::OK) {
    878         portMode[1] = PortMode::PRESET_BYTE_BUFFER;
    879         status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
    880         ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
    881     }
    882 
    883     // prepare for adaptive playback
    884     uint32_t adaptiveMaxWidth = 320;
    885     uint32_t adaptiveMaxHeight = 240;
    886     status = omxNode->prepareForAdaptivePlayback(
    887         kPortIndexOutput, true, adaptiveMaxWidth, adaptiveMaxHeight);
    888     if (strncmp(gEnv->getComponent().c_str(), "OMX.google.", 11) == 0) {
    889         // SoftOMX Decoders donot support graphic buffer modes. So for them
    890         // support for adaptive play back is mandatory in Byte Buffer mode
    891         ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
    892     } else {
    893         // for vendor codecs, support for adaptive play back is optional
    894         // in byte buffer mode.
    895         if (portMode[1] == PortMode::PRESET_BYTE_BUFFER) return;
    896         if (status != ::android::hardware::media::omx::V1_0::Status::OK) return;
    897     }
    898 
    899     // TODO: Handle this better !!!
    900     // Without the knowledge of the maximum resolution of the frame to be
    901     // decoded it is not possible to choose the size of the input buffer.
    902     // The value below is based on the info. files of clips in res folder.
    903     status = setPortBufferSize(omxNode, kPortIndexInput, 482304);
    904     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
    905 
    906     // set Port Params
    907     uint32_t nFrameWidth, nFrameHeight, xFramerate;
    908     getInputChannelInfo(omxNode, kPortIndexInput, &nFrameWidth, &nFrameHeight,
    909                         &xFramerate);
    910     // get default color format
    911     OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatUnused;
    912     getDefaultColorFormat(omxNode, kPortIndexOutput, portMode[1],
    913                           &eColorFormat);
    914     ASSERT_NE(eColorFormat, OMX_COLOR_FormatUnused);
    915     status =
    916         setVideoPortFormat(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
    917                            eColorFormat, xFramerate);
    918     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
    919     setDefaultPortParam(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
    920                         eColorFormat, nFrameWidth, nFrameHeight, 0, xFramerate);
    921 
    922     android::Vector<BufferInfo> iBuffer, oBuffer;
    923 
    924     // set state to idle
    925     ASSERT_NO_FATAL_FAILURE(changeStateLoadedtoIdle(
    926         omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
    927         kPortIndexOutput, portMode, true));
    928     // set state to executing
    929     ASSERT_NO_FATAL_FAILURE(changeStateIdletoExecute(omxNode, observer));
    930 
    931     timestampDevTest = true;
    932     uint32_t timestampOffset = 0;
    933     for (uint32_t i = 0; i < STREAM_COUNT * 2; i++) {
    934         std::ifstream eleStream, eleInfo;
    935         char mURL[512], info[512];
    936         android::Vector<FrameData> Info;
    937         strcpy(mURL, gEnv->getRes().c_str());
    938         strcpy(info, gEnv->getRes().c_str());
    939         GetURLForComponent(compName, mURL, info, i % STREAM_COUNT);
    940         eleInfo.open(info);
    941         ASSERT_EQ(eleInfo.is_open(), true);
    942         int bytesCount = 0;
    943         uint32_t flags = 0;
    944         uint32_t timestamp = 0;
    945         uint32_t timestampMax = 0;
    946         while (1) {
    947             if (!(eleInfo >> bytesCount)) break;
    948             eleInfo >> flags;
    949             eleInfo >> timestamp;
    950             timestamp += timestampOffset;
    951             Info.push_back({bytesCount, flags, timestamp});
    952             if (timestampDevTest && (flags != OMX_BUFFERFLAG_CODECCONFIG))
    953                 timestampUslist.push_back(timestamp);
    954             if (timestampMax < timestamp) timestampMax = timestamp;
    955         }
    956         timestampOffset = timestampMax;
    957         eleInfo.close();
    958 
    959         // Port Reconfiguration
    960         eleStream.open(mURL, std::ifstream::binary);
    961         ASSERT_EQ(eleStream.is_open(), true);
    962         ASSERT_NO_FATAL_FAILURE(
    963             decodeNFrames(omxNode, observer, &iBuffer, &oBuffer,
    964                           kPortIndexInput, kPortIndexOutput, eleStream, &Info,
    965                           0, (int)Info.size(), portMode[1], false));
    966         eleStream.close();
    967 
    968         getInputChannelInfo(omxNode, kPortIndexInput, &nFrameWidth,
    969                             &nFrameHeight, &xFramerate);
    970         if ((nFrameWidth > adaptiveMaxWidth) ||
    971             (nFrameHeight > adaptiveMaxHeight)) {
    972             if (nFrameWidth > adaptiveMaxWidth) adaptiveMaxWidth = nFrameWidth;
    973             if (nFrameHeight > adaptiveMaxHeight)
    974                 adaptiveMaxHeight = nFrameHeight;
    975             EXPECT_TRUE(portSettingsChange);
    976         } else {
    977             // In DynamicANW Buffer mode, its ok to do a complete
    978             // reconfiguration even if a partial reconfiguration is sufficient.
    979             if (portMode[1] != PortMode::DYNAMIC_ANW_BUFFER)
    980                 EXPECT_FALSE(portSettingsChange);
    981         }
    982         portSettingsChange = false;
    983     }
    984     ASSERT_NO_FATAL_FAILURE(
    985         waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer,
    986                                kPortIndexInput, kPortIndexOutput, portMode[1]));
    987     ASSERT_NO_FATAL_FAILURE(testEOS(
    988         omxNode, observer, &iBuffer, &oBuffer, true, eosFlag, portMode,
    989         portReconfiguration, kPortIndexInput, kPortIndexOutput, nullptr));
    990     if (timestampDevTest) EXPECT_EQ(timestampUslist.empty(), true);
    991     // set state to idle
    992     ASSERT_NO_FATAL_FAILURE(
    993         changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer));
    994     // set state to executing
    995     ASSERT_NO_FATAL_FAILURE(changeStateIdletoLoaded(omxNode, observer, &iBuffer,
    996                                                     &oBuffer, kPortIndexInput,
    997                                                     kPortIndexOutput));
    998 }
    999 
   1000 // end of sequence test
   1001 TEST_F(VideoDecHidlTest, EOSTest_M) {
   1002     description("Test End of stream monkeying");
   1003     if (disableTest) return;
   1004     android::hardware::media::omx::V1_0::Status status;
   1005     uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
   1006     status = setRole(omxNode, gEnv->getRole().c_str());
   1007     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1008     OMX_PORT_PARAM_TYPE params;
   1009     status = getParam(omxNode, OMX_IndexParamVideoInit, &params);
   1010     if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
   1011         ASSERT_EQ(params.nPorts, 2U);
   1012         kPortIndexInput = params.nStartPortNumber;
   1013         kPortIndexOutput = kPortIndexInput + 1;
   1014     }
   1015 
   1016     // set port mode
   1017     status = omxNode->setPortMode(kPortIndexInput, portMode[0]);
   1018     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1019     status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
   1020     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1021 
   1022     // set Port Params
   1023     uint32_t nFrameWidth, nFrameHeight, xFramerate;
   1024     getInputChannelInfo(omxNode, kPortIndexInput, &nFrameWidth, &nFrameHeight,
   1025                         &xFramerate);
   1026     // get default color format
   1027     OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatUnused;
   1028     getDefaultColorFormat(omxNode, kPortIndexOutput, portMode[1],
   1029                           &eColorFormat);
   1030     ASSERT_NE(eColorFormat, OMX_COLOR_FormatUnused);
   1031     status =
   1032         setVideoPortFormat(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
   1033                            eColorFormat, xFramerate);
   1034     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1035     setDefaultPortParam(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
   1036                         eColorFormat, nFrameWidth, nFrameHeight, 0, xFramerate);
   1037 
   1038     android::Vector<BufferInfo> iBuffer, oBuffer;
   1039 
   1040     // set state to idle
   1041     ASSERT_NO_FATAL_FAILURE(changeStateLoadedtoIdle(
   1042         omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
   1043         kPortIndexOutput, portMode, true));
   1044     // set state to executing
   1045     ASSERT_NO_FATAL_FAILURE(changeStateIdletoExecute(omxNode, observer));
   1046 
   1047     // request EOS at the start
   1048     ASSERT_NO_FATAL_FAILURE(testEOS(
   1049         omxNode, observer, &iBuffer, &oBuffer, true, eosFlag, portMode,
   1050         portReconfiguration, kPortIndexInput, kPortIndexOutput, nullptr));
   1051     ASSERT_NO_FATAL_FAILURE(flushPorts(omxNode, observer, &iBuffer, &oBuffer,
   1052                                        kPortIndexInput, kPortIndexOutput));
   1053     EXPECT_GE(framesReceived, 0U);
   1054     framesReceived = 0;
   1055     timestampUs = 0;
   1056 
   1057     // set state to idle
   1058     ASSERT_NO_FATAL_FAILURE(
   1059         changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer));
   1060     // set state to executing
   1061     ASSERT_NO_FATAL_FAILURE(changeStateIdletoLoaded(omxNode, observer, &iBuffer,
   1062                                                     &oBuffer, kPortIndexInput,
   1063                                                     kPortIndexOutput));
   1064 }
   1065 
   1066 // end of sequence test
   1067 TEST_F(VideoDecHidlTest, ThumbnailTest) {
   1068     description("Test Request for thumbnail");
   1069     if (disableTest) return;
   1070     android::hardware::media::omx::V1_0::Status status;
   1071     uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
   1072     status = setRole(omxNode, gEnv->getRole().c_str());
   1073     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1074     OMX_PORT_PARAM_TYPE params;
   1075     status = getParam(omxNode, OMX_IndexParamVideoInit, &params);
   1076     if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
   1077         ASSERT_EQ(params.nPorts, 2U);
   1078         kPortIndexInput = params.nStartPortNumber;
   1079         kPortIndexOutput = kPortIndexInput + 1;
   1080     }
   1081     char mURL[512], info[512];
   1082     strcpy(mURL, gEnv->getRes().c_str());
   1083     strcpy(info, gEnv->getRes().c_str());
   1084     GetURLForComponent(compName, mURL, info);
   1085 
   1086     std::ifstream eleStream, eleInfo;
   1087 
   1088     eleInfo.open(info);
   1089     ASSERT_EQ(eleInfo.is_open(), true);
   1090     android::Vector<FrameData> Info;
   1091     int bytesCount = 0, maxBytesCount = 0;
   1092     uint32_t flags = 0;
   1093     uint32_t timestamp = 0;
   1094     while (1) {
   1095         if (!(eleInfo >> bytesCount)) break;
   1096         eleInfo >> flags;
   1097         eleInfo >> timestamp;
   1098         Info.push_back({bytesCount, flags, timestamp});
   1099         if (maxBytesCount < bytesCount) maxBytesCount = bytesCount;
   1100     }
   1101     eleInfo.close();
   1102 
   1103     // As the frame sizes are known ahead, use it to configure i/p buffer size
   1104     maxBytesCount = ALIGN_POWER_OF_TWO(maxBytesCount, 10);
   1105     status = setPortBufferSize(omxNode, kPortIndexInput, maxBytesCount);
   1106     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1107 
   1108     // set port mode
   1109     status = omxNode->setPortMode(kPortIndexInput, portMode[0]);
   1110     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1111     status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
   1112     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1113 
   1114     // set Port Params
   1115     uint32_t nFrameWidth, nFrameHeight, xFramerate;
   1116     getInputChannelInfo(omxNode, kPortIndexInput, &nFrameWidth, &nFrameHeight,
   1117                         &xFramerate);
   1118     // get default color format
   1119     OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatUnused;
   1120     getDefaultColorFormat(omxNode, kPortIndexOutput, portMode[1],
   1121                           &eColorFormat);
   1122     ASSERT_NE(eColorFormat, OMX_COLOR_FormatUnused);
   1123     status =
   1124         setVideoPortFormat(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
   1125                            eColorFormat, xFramerate);
   1126     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1127     setDefaultPortParam(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
   1128                         eColorFormat, nFrameWidth, nFrameHeight, 0, xFramerate);
   1129 
   1130     android::Vector<BufferInfo> iBuffer, oBuffer;
   1131 
   1132     // set state to idle
   1133     ASSERT_NO_FATAL_FAILURE(changeStateLoadedtoIdle(
   1134         omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
   1135         kPortIndexOutput, portMode, true));
   1136     // set state to executing
   1137     ASSERT_NO_FATAL_FAILURE(changeStateIdletoExecute(omxNode, observer));
   1138 
   1139     // request EOS for thumbnail
   1140     size_t i = 0;
   1141     while (!(Info[i].flags & OMX_BUFFERFLAG_SYNCFRAME)) i++;
   1142     eleStream.open(mURL, std::ifstream::binary);
   1143     ASSERT_EQ(eleStream.is_open(), true);
   1144     ASSERT_NO_FATAL_FAILURE(decodeNFrames(
   1145         omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
   1146         kPortIndexOutput, eleStream, &Info, 0, i + 1, portMode[1]));
   1147     eleStream.close();
   1148     ASSERT_NO_FATAL_FAILURE(
   1149         waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer,
   1150                                kPortIndexInput, kPortIndexOutput, portMode[1]));
   1151     ASSERT_NO_FATAL_FAILURE(testEOS(
   1152         omxNode, observer, &iBuffer, &oBuffer, false, eosFlag, portMode,
   1153         portReconfiguration, kPortIndexInput, kPortIndexOutput, nullptr));
   1154     ASSERT_NO_FATAL_FAILURE(flushPorts(omxNode, observer, &iBuffer, &oBuffer,
   1155                                        kPortIndexInput, kPortIndexOutput));
   1156     EXPECT_GE(framesReceived, 1U);
   1157     framesReceived = 0;
   1158     timestampUs = 0;
   1159 
   1160     eleStream.open(mURL, std::ifstream::binary);
   1161     ASSERT_EQ(eleStream.is_open(), true);
   1162     ASSERT_NO_FATAL_FAILURE(decodeNFrames(
   1163         omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
   1164         kPortIndexOutput, eleStream, &Info, 0, i + 1, portMode[1], false));
   1165     eleStream.close();
   1166     ASSERT_NO_FATAL_FAILURE(
   1167         waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer,
   1168                                kPortIndexInput, kPortIndexOutput, portMode[1]));
   1169     ASSERT_NO_FATAL_FAILURE(testEOS(
   1170         omxNode, observer, &iBuffer, &oBuffer, true, eosFlag, portMode,
   1171         portReconfiguration, kPortIndexInput, kPortIndexOutput, nullptr));
   1172     ASSERT_NO_FATAL_FAILURE(flushPorts(omxNode, observer, &iBuffer, &oBuffer,
   1173                                        kPortIndexInput, kPortIndexOutput));
   1174     EXPECT_GE(framesReceived, 1U);
   1175     framesReceived = 0;
   1176     timestampUs = 0;
   1177 
   1178     // set state to idle
   1179     ASSERT_NO_FATAL_FAILURE(
   1180         changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer));
   1181     // set state to executing
   1182     ASSERT_NO_FATAL_FAILURE(changeStateIdletoLoaded(omxNode, observer, &iBuffer,
   1183                                                     &oBuffer, kPortIndexInput,
   1184                                                     kPortIndexOutput));
   1185 }
   1186 
   1187 // end of sequence test
   1188 TEST_F(VideoDecHidlTest, SimpleEOSTest) {
   1189     description("Test End of stream");
   1190     if (disableTest) return;
   1191     android::hardware::media::omx::V1_0::Status status;
   1192     uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
   1193     status = setRole(omxNode, gEnv->getRole().c_str());
   1194     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1195     OMX_PORT_PARAM_TYPE params;
   1196     status = getParam(omxNode, OMX_IndexParamVideoInit, &params);
   1197     if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
   1198         ASSERT_EQ(params.nPorts, 2U);
   1199         kPortIndexInput = params.nStartPortNumber;
   1200         kPortIndexOutput = kPortIndexInput + 1;
   1201     }
   1202     char mURL[512], info[512];
   1203     strcpy(mURL, gEnv->getRes().c_str());
   1204     strcpy(info, gEnv->getRes().c_str());
   1205     GetURLForComponent(compName, mURL, info);
   1206 
   1207     std::ifstream eleStream, eleInfo;
   1208 
   1209     eleInfo.open(info);
   1210     ASSERT_EQ(eleInfo.is_open(), true);
   1211     android::Vector<FrameData> Info;
   1212     int bytesCount = 0, maxBytesCount = 0;
   1213     uint32_t flags = 0;
   1214     uint32_t timestamp = 0;
   1215     while (1) {
   1216         if (!(eleInfo >> bytesCount)) break;
   1217         eleInfo >> flags;
   1218         eleInfo >> timestamp;
   1219         Info.push_back({bytesCount, flags, timestamp});
   1220         if (maxBytesCount < bytesCount) maxBytesCount = bytesCount;
   1221     }
   1222     eleInfo.close();
   1223 
   1224     // As the frame sizes are known ahead, use it to configure i/p buffer size
   1225     maxBytesCount = ALIGN_POWER_OF_TWO(maxBytesCount, 10);
   1226     status = setPortBufferSize(omxNode, kPortIndexInput, maxBytesCount);
   1227     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1228 
   1229     // set port mode
   1230     portMode[0] = PortMode::PRESET_BYTE_BUFFER;
   1231     portMode[1] = PortMode::PRESET_ANW_BUFFER;
   1232     status = omxNode->setPortMode(kPortIndexInput, portMode[0]);
   1233     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1234     status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
   1235     if (status != ::android::hardware::media::omx::V1_0::Status::OK) {
   1236         portMode[1] = PortMode::PRESET_BYTE_BUFFER;
   1237         status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
   1238         ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1239     }
   1240 
   1241     // set Port Params
   1242     uint32_t nFrameWidth, nFrameHeight, xFramerate;
   1243     getInputChannelInfo(omxNode, kPortIndexInput, &nFrameWidth, &nFrameHeight,
   1244                         &xFramerate);
   1245     // get default color format
   1246     OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatUnused;
   1247     getDefaultColorFormat(omxNode, kPortIndexOutput, portMode[1],
   1248                           &eColorFormat);
   1249     ASSERT_NE(eColorFormat, OMX_COLOR_FormatUnused);
   1250     status =
   1251         setVideoPortFormat(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
   1252                            eColorFormat, xFramerate);
   1253     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1254     setDefaultPortParam(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
   1255                         eColorFormat, nFrameWidth, nFrameHeight, 0, xFramerate);
   1256 
   1257     android::Vector<BufferInfo> iBuffer, oBuffer;
   1258 
   1259     // set state to idle
   1260     ASSERT_NO_FATAL_FAILURE(changeStateLoadedtoIdle(
   1261         omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
   1262         kPortIndexOutput, portMode, true));
   1263     // set state to executing
   1264     ASSERT_NO_FATAL_FAILURE(changeStateIdletoExecute(omxNode, observer));
   1265 
   1266     // request EOS at the end
   1267     eleStream.open(mURL, std::ifstream::binary);
   1268     ASSERT_EQ(eleStream.is_open(), true);
   1269     ASSERT_NO_FATAL_FAILURE(decodeNFrames(omxNode, observer, &iBuffer, &oBuffer,
   1270                                           kPortIndexInput, kPortIndexOutput,
   1271                                           eleStream, &Info, 0, (int)Info.size(),
   1272                                           portMode[1], false));
   1273     eleStream.close();
   1274     ASSERT_NO_FATAL_FAILURE(
   1275         waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer,
   1276                                kPortIndexInput, kPortIndexOutput, portMode[1]));
   1277     ASSERT_NO_FATAL_FAILURE(testEOS(
   1278         omxNode, observer, &iBuffer, &oBuffer, true, eosFlag, portMode,
   1279         portReconfiguration, kPortIndexInput, kPortIndexOutput, nullptr));
   1280     ASSERT_NO_FATAL_FAILURE(flushPorts(omxNode, observer, &iBuffer, &oBuffer,
   1281                                        kPortIndexInput, kPortIndexOutput));
   1282     framesReceived = 0;
   1283     timestampUs = 0;
   1284 
   1285     // set state to idle
   1286     ASSERT_NO_FATAL_FAILURE(
   1287         changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer));
   1288     // set state to executing
   1289     ASSERT_NO_FATAL_FAILURE(changeStateIdletoLoaded(omxNode, observer, &iBuffer,
   1290                                                     &oBuffer, kPortIndexInput,
   1291                                                     kPortIndexOutput));
   1292 }
   1293 
   1294 // test input/output port flush
   1295 TEST_F(VideoDecHidlTest, FlushTest) {
   1296     description("Test Flush");
   1297     if (disableTest) return;
   1298     android::hardware::media::omx::V1_0::Status status;
   1299     uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
   1300     status = setRole(omxNode, gEnv->getRole().c_str());
   1301     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1302     OMX_PORT_PARAM_TYPE params;
   1303     status = getParam(omxNode, OMX_IndexParamVideoInit, &params);
   1304     if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
   1305         ASSERT_EQ(params.nPorts, 2U);
   1306         kPortIndexInput = params.nStartPortNumber;
   1307         kPortIndexOutput = kPortIndexInput + 1;
   1308     }
   1309     char mURL[512], info[512];
   1310     strcpy(mURL, gEnv->getRes().c_str());
   1311     strcpy(info, gEnv->getRes().c_str());
   1312     GetURLForComponent(compName, mURL, info);
   1313 
   1314     std::ifstream eleStream, eleInfo;
   1315 
   1316     eleInfo.open(info);
   1317     ASSERT_EQ(eleInfo.is_open(), true);
   1318     android::Vector<FrameData> Info;
   1319     int bytesCount = 0, maxBytesCount = 0;
   1320     uint32_t flags = 0;
   1321     uint32_t timestamp = 0;
   1322     while (1) {
   1323         if (!(eleInfo >> bytesCount)) break;
   1324         eleInfo >> flags;
   1325         eleInfo >> timestamp;
   1326         Info.push_back({bytesCount, flags, timestamp});
   1327         if (maxBytesCount < bytesCount) maxBytesCount = bytesCount;
   1328     }
   1329     eleInfo.close();
   1330 
   1331     // As the frame sizes are known ahead, use it to configure i/p buffer size
   1332     maxBytesCount = ALIGN_POWER_OF_TWO(maxBytesCount, 10);
   1333     status = setPortBufferSize(omxNode, kPortIndexInput, maxBytesCount);
   1334     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1335 
   1336     // set port mode
   1337     status = omxNode->setPortMode(kPortIndexInput, portMode[0]);
   1338     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1339     status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
   1340     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1341 
   1342     // set Port Params
   1343     uint32_t nFrameWidth, nFrameHeight, xFramerate;
   1344     getInputChannelInfo(omxNode, kPortIndexInput, &nFrameWidth, &nFrameHeight,
   1345                         &xFramerate);
   1346     // get default color format
   1347     OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatUnused;
   1348     getDefaultColorFormat(omxNode, kPortIndexOutput, portMode[1],
   1349                           &eColorFormat);
   1350     ASSERT_NE(eColorFormat, OMX_COLOR_FormatUnused);
   1351     status =
   1352         setVideoPortFormat(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
   1353                            eColorFormat, xFramerate);
   1354     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1355     setDefaultPortParam(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
   1356                         eColorFormat, nFrameWidth, nFrameHeight, 0, xFramerate);
   1357 
   1358     android::Vector<BufferInfo> iBuffer, oBuffer;
   1359 
   1360     // set state to idle
   1361     ASSERT_NO_FATAL_FAILURE(changeStateLoadedtoIdle(
   1362         omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
   1363         kPortIndexOutput, portMode, true));
   1364     // set state to executing
   1365     ASSERT_NO_FATAL_FAILURE(changeStateIdletoExecute(omxNode, observer));
   1366 
   1367     // Decode 128 frames and flush. here 128 is chosen to ensure there is a key
   1368     // frame after this so that the below section can be convered for all
   1369     // components
   1370     int nFrames = 128;
   1371     eleStream.open(mURL, std::ifstream::binary);
   1372     ASSERT_EQ(eleStream.is_open(), true);
   1373     ASSERT_NO_FATAL_FAILURE(decodeNFrames(
   1374         omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
   1375         kPortIndexOutput, eleStream, &Info, 0, nFrames, portMode[1], false));
   1376     ASSERT_NO_FATAL_FAILURE(flushPorts(omxNode, observer, &iBuffer, &oBuffer,
   1377                                        kPortIndexInput, kPortIndexOutput));
   1378     framesReceived = 0;
   1379 
   1380     // Seek to next key frame and start decoding till the end
   1381     int index = nFrames;
   1382     bool keyFrame = false;
   1383     while (index < (int)Info.size()) {
   1384         if ((Info[index].flags & OMX_BUFFERFLAG_SYNCFRAME) ==
   1385             OMX_BUFFERFLAG_SYNCFRAME) {
   1386             timestampUs = Info[index - 1].timestamp;
   1387             keyFrame = true;
   1388             break;
   1389         }
   1390         eleStream.ignore(Info[index].bytesCount);
   1391         index++;
   1392     }
   1393     if (keyFrame) {
   1394         ASSERT_NO_FATAL_FAILURE(
   1395             decodeNFrames(omxNode, observer, &iBuffer, &oBuffer,
   1396                           kPortIndexInput, kPortIndexOutput, eleStream, &Info,
   1397                           index, Info.size() - index, portMode[1], false));
   1398     }
   1399     eleStream.close();
   1400     ASSERT_NO_FATAL_FAILURE(flushPorts(omxNode, observer, &iBuffer, &oBuffer,
   1401                                        kPortIndexInput, kPortIndexOutput));
   1402     framesReceived = 0;
   1403 
   1404     // set state to idle
   1405     ASSERT_NO_FATAL_FAILURE(
   1406         changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer));
   1407     // set state to executing
   1408     ASSERT_NO_FATAL_FAILURE(changeStateIdletoLoaded(omxNode, observer, &iBuffer,
   1409                                                     &oBuffer, kPortIndexInput,
   1410                                                     kPortIndexOutput));
   1411 }
   1412 
   1413 int main(int argc, char** argv) {
   1414     gEnv = new ComponentTestEnvironment();
   1415     ::testing::AddGlobalTestEnvironment(gEnv);
   1416     ::testing::InitGoogleTest(&argc, argv);
   1417     gEnv->init(&argc, argv);
   1418     int status = gEnv->initFromOptions(argc, argv);
   1419     if (status == 0) {
   1420         status = RUN_ALL_TESTS();
   1421         ALOGI("Test result = %d", status);
   1422     }
   1423     return status;
   1424 }
   1425