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