Home | History | Annotate | Download | only in audio
      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_audio_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_audio_hidl_test_common.h>
     50 #include <media_hidl_test_common.h>
     51 #include <fstream>
     52 
     53 static ComponentTestEnvironment* gEnv = nullptr;
     54 
     55 // audio decoder test fixture class
     56 class AudioDecHidlTest : public ::testing::VtsHalHidlTargetTestBase {
     57    private:
     58     typedef ::testing::VtsHalHidlTargetTestBase Super;
     59    public:
     60     ::std::string getTestCaseInfo() const override {
     61         return ::std::string() +
     62                 "Component: " + gEnv->getComponent().c_str() + " | " +
     63                 "Role: " + gEnv->getRole().c_str() + " | " +
     64                 "Instance: " + gEnv->getInstance().c_str() + " | " +
     65                 "Res: " + gEnv->getRes().c_str();
     66     }
     67 
     68     virtual void SetUp() override {
     69         Super::SetUp();
     70         disableTest = false;
     71         android::hardware::media::omx::V1_0::Status status;
     72         omx = Super::getService<IOmx>(gEnv->getInstance());
     73         ASSERT_NE(omx, nullptr);
     74         observer =
     75             new CodecObserver([this](Message msg, const BufferInfo* buffer) {
     76                 handleMessage(msg, buffer);
     77             });
     78         ASSERT_NE(observer, nullptr);
     79         if (strncmp(gEnv->getComponent().c_str(), "OMX.", 4) != 0)
     80             disableTest = true;
     81         EXPECT_TRUE(omx->allocateNode(
     82                            gEnv->getComponent(), observer,
     83                            [&](android::hardware::media::omx::V1_0::Status _s,
     84                                sp<IOmxNode> const& _nl) {
     85                                status = _s;
     86                                this->omxNode = _nl;
     87                            })
     88                         .isOk());
     89         if (status == android::hardware::media::omx::V1_0::Status::NAME_NOT_FOUND) {
     90             disableTest = true;
     91             std::cout << "[   WARN   ] Test Disabled, component not present\n";
     92             return;
     93         }
     94         ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
     95         ASSERT_NE(omxNode, nullptr);
     96         ASSERT_NE(gEnv->getRole().empty(), true) << "Invalid Component Role";
     97         struct StringToName {
     98             const char* Name;
     99             standardComp CompName;
    100         };
    101         const StringToName kStringToName[] = {
    102             {"mp3", mp3}, {"amrnb", amrnb},       {"amrwb", amrwb},
    103             {"aac", aac}, {"vorbis", vorbis},     {"opus", opus},
    104             {"pcm", pcm}, {"g711alaw", g711alaw}, {"g711mlaw", g711mlaw},
    105             {"gsm", gsm}, {"raw", raw},           {"flac", flac},
    106         };
    107         const size_t kNumStringToName =
    108             sizeof(kStringToName) / sizeof(kStringToName[0]);
    109         const char* pch;
    110         char substring[OMX_MAX_STRINGNAME_SIZE];
    111         strcpy(substring, gEnv->getRole().c_str());
    112         pch = strchr(substring, '.');
    113         ASSERT_NE(pch, nullptr);
    114         compName = unknown_comp;
    115         for (size_t i = 0; i < kNumStringToName; ++i) {
    116             if (!strcasecmp(pch + 1, kStringToName[i].Name)) {
    117                 compName = kStringToName[i].CompName;
    118                 break;
    119             }
    120         }
    121         if (compName == unknown_comp) disableTest = true;
    122         struct CompToCoding {
    123             standardComp CompName;
    124             OMX_AUDIO_CODINGTYPE eEncoding;
    125         };
    126         static const CompToCoding kCompToCoding[] = {
    127             {mp3, OMX_AUDIO_CodingMP3},
    128             {amrnb, OMX_AUDIO_CodingAMR},
    129             {amrwb, OMX_AUDIO_CodingAMR},
    130             {aac, OMX_AUDIO_CodingAAC},
    131             {vorbis, OMX_AUDIO_CodingVORBIS},
    132             {pcm, OMX_AUDIO_CodingPCM},
    133             {opus, (OMX_AUDIO_CODINGTYPE)OMX_AUDIO_CodingAndroidOPUS},
    134             {g711alaw, OMX_AUDIO_CodingG711},
    135             {g711mlaw, OMX_AUDIO_CodingG711},
    136             {gsm, OMX_AUDIO_CodingGSMFR},
    137             {raw, OMX_AUDIO_CodingPCM},
    138             {flac, OMX_AUDIO_CodingFLAC},
    139         };
    140         static const size_t kNumCompToCoding =
    141             sizeof(kCompToCoding) / sizeof(kCompToCoding[0]);
    142         size_t i;
    143         for (i = 0; i < kNumCompToCoding; ++i) {
    144             if (kCompToCoding[i].CompName == compName) {
    145                 eEncoding = kCompToCoding[i].eEncoding;
    146                 break;
    147             }
    148         }
    149         if (i == kNumCompToCoding) disableTest = true;
    150         eosFlag = false;
    151         framesReceived = 0;
    152         timestampUs = 0;
    153         timestampDevTest = false;
    154         if (disableTest) std::cout << "[   WARN   ] Test Disabled \n";
    155     }
    156 
    157     virtual void TearDown() override {
    158         if (omxNode != nullptr) {
    159             // If you have encountered a fatal failure, it is possible that
    160             // freeNode() will not go through. Instead of hanging the app.
    161             // let it pass through and report errors
    162             if (::testing::Test::HasFatalFailure()) return;
    163             EXPECT_TRUE((omxNode->freeNode()).isOk());
    164             omxNode = nullptr;
    165         }
    166         Super::TearDown();
    167     }
    168 
    169     // callback function to process messages received by onMessages() from IL
    170     // client.
    171     void handleMessage(Message msg, const BufferInfo* buffer) {
    172         (void)buffer;
    173         if (msg.type == Message::Type::FILL_BUFFER_DONE) {
    174             if (msg.data.extendedBufferData.flags & OMX_BUFFERFLAG_EOS) {
    175                 eosFlag = true;
    176             }
    177             if (msg.data.extendedBufferData.rangeLength != 0) {
    178                 framesReceived += 1;
    179                 // For decoder components current timestamp always exceeds
    180                 // previous timestamp
    181                 EXPECT_GE(msg.data.extendedBufferData.timestampUs, timestampUs);
    182                 timestampUs = msg.data.extendedBufferData.timestampUs;
    183                 // Test if current timestamp is among the list of queued
    184                 // timestamps
    185                 if (timestampDevTest) {
    186                     bool tsHit = false;
    187                     android::List<uint64_t>::iterator it =
    188                         timestampUslist.begin();
    189                     while (it != timestampUslist.end()) {
    190                         if (*it == timestampUs) {
    191                             timestampUslist.erase(it);
    192                             tsHit = true;
    193                             break;
    194                         }
    195                         it++;
    196                     }
    197                     if (tsHit == false) {
    198                         if (timestampUslist.empty() == false) {
    199                             EXPECT_EQ(tsHit, true)
    200                                 << "TimeStamp not recognized";
    201                         } else {
    202                             std::cout << "[   INFO   ] Received non-zero "
    203                                          "output / TimeStamp not recognized \n";
    204                         }
    205                     }
    206                 }
    207 #define WRITE_OUTPUT 0
    208 #if WRITE_OUTPUT
    209                 static int count = 0;
    210                 FILE* ofp = nullptr;
    211                 if (count)
    212                     ofp = fopen("out.bin", "ab");
    213                 else
    214                     ofp = fopen("out.bin", "wb");
    215                 if (ofp != nullptr) {
    216                     fwrite(static_cast<void*>(buffer->mMemory->getPointer()),
    217                            sizeof(char),
    218                            msg.data.extendedBufferData.rangeLength, ofp);
    219                     fclose(ofp);
    220                     count++;
    221                 }
    222 #endif
    223             }
    224         }
    225     }
    226 
    227     enum standardComp {
    228         mp3,
    229         amrnb,
    230         amrwb,
    231         aac,
    232         vorbis,
    233         opus,
    234         pcm,
    235         g711alaw,
    236         g711mlaw,
    237         gsm,
    238         raw,
    239         flac,
    240         unknown_comp,
    241     };
    242 
    243     sp<IOmx> omx;
    244     sp<CodecObserver> observer;
    245     sp<IOmxNode> omxNode;
    246     standardComp compName;
    247     OMX_AUDIO_CODINGTYPE eEncoding;
    248     bool disableTest;
    249     bool eosFlag;
    250     uint32_t framesReceived;
    251     uint64_t timestampUs;
    252     ::android::List<uint64_t> timestampUslist;
    253     bool timestampDevTest;
    254 
    255    protected:
    256     static void description(const std::string& description) {
    257         RecordProperty("description", description);
    258     }
    259 };
    260 
    261 // Set Default port param.
    262 void setDefaultPortParam(
    263     sp<IOmxNode> omxNode, OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE eEncoding,
    264     int32_t nChannels = 2, int32_t nSampleRate = 44100,
    265     OMX_AUDIO_PCMMODETYPE ePCMMode = OMX_AUDIO_PCMModeLinear,
    266     OMX_NUMERICALDATATYPE eNumData = OMX_NumericalDataSigned,
    267     int32_t nBitPerSample = 16) {
    268     android::hardware::media::omx::V1_0::Status status;
    269 
    270     OMX_PARAM_PORTDEFINITIONTYPE portDef;
    271     status = getPortParam(omxNode, OMX_IndexParamPortDefinition, portIndex,
    272                           &portDef);
    273     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
    274 
    275     portDef.format.audio.bFlagErrorConcealment = OMX_TRUE;
    276     portDef.format.audio.eEncoding = eEncoding;
    277     status = setPortParam(omxNode, OMX_IndexParamPortDefinition, portIndex,
    278                           &portDef);
    279     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
    280 
    281     switch ((int)eEncoding) {
    282         case OMX_AUDIO_CodingPCM:
    283             setupPCMPort(omxNode, portIndex, nChannels, eNumData, nBitPerSample,
    284                          nSampleRate, ePCMMode);
    285             break;
    286         case OMX_AUDIO_CodingAAC:
    287             setupAACPort(omxNode, portIndex, OMX_AUDIO_AACObjectNull,
    288                          OMX_AUDIO_AACStreamFormatMP4FF, nChannels, 0,
    289                          nSampleRate);
    290         default:
    291             break;
    292     }
    293 }
    294 
    295 // In decoder components, often the input port parameters get updated upon
    296 // parsing the header of elementary stream. Client needs to collect this
    297 // information to reconfigure other ports that share data with this input
    298 // port.
    299 void getInputChannelInfo(sp<IOmxNode> omxNode, OMX_U32 kPortIndexInput,
    300                          OMX_AUDIO_CODINGTYPE eEncoding, int32_t* nChannels,
    301                          int32_t* nSampleRate) {
    302     android::hardware::media::omx::V1_0::Status status;
    303     *nChannels = 0;
    304     *nSampleRate = 0;
    305 
    306     switch ((int)eEncoding) {
    307         case OMX_AUDIO_CodingGSMFR:
    308         case OMX_AUDIO_CodingG711:
    309         case OMX_AUDIO_CodingPCM: {
    310             OMX_AUDIO_PARAM_PCMMODETYPE param;
    311             status = getPortParam(omxNode, OMX_IndexParamAudioPcm,
    312                                   kPortIndexInput, &param);
    313             ASSERT_EQ(status,
    314                       ::android::hardware::media::omx::V1_0::Status::OK);
    315             *nChannels = param.nChannels;
    316             *nSampleRate = param.nSamplingRate;
    317             break;
    318         }
    319         case OMX_AUDIO_CodingMP3: {
    320             OMX_AUDIO_PARAM_MP3TYPE param;
    321             status = getPortParam(omxNode, OMX_IndexParamAudioMp3,
    322                                   kPortIndexInput, &param);
    323             ASSERT_EQ(status,
    324                       ::android::hardware::media::omx::V1_0::Status::OK);
    325             *nChannels = param.nChannels;
    326             *nSampleRate = param.nSampleRate;
    327             break;
    328         }
    329         case OMX_AUDIO_CodingAndroidOPUS: {
    330             OMX_AUDIO_PARAM_ANDROID_OPUSTYPE param;
    331             status = getPortParam(omxNode,
    332                                   (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
    333                                   kPortIndexInput, &param);
    334             ASSERT_EQ(status,
    335                       ::android::hardware::media::omx::V1_0::Status::OK);
    336             *nChannels = param.nChannels;
    337             *nSampleRate = param.nSampleRate;
    338             break;
    339         }
    340         case OMX_AUDIO_CodingVORBIS: {
    341             OMX_AUDIO_PARAM_VORBISTYPE param;
    342             status = getPortParam(omxNode, OMX_IndexParamAudioVorbis,
    343                                   kPortIndexInput, &param);
    344             ASSERT_EQ(status,
    345                       ::android::hardware::media::omx::V1_0::Status::OK);
    346             *nChannels = param.nChannels;
    347             *nSampleRate = param.nSampleRate;
    348             break;
    349         }
    350         case OMX_AUDIO_CodingAMR: {
    351             OMX_AUDIO_PARAM_AMRTYPE param;
    352             status = getPortParam(omxNode, OMX_IndexParamAudioAmr,
    353                                   kPortIndexInput, &param);
    354             ASSERT_EQ(status,
    355                       ::android::hardware::media::omx::V1_0::Status::OK);
    356             *nChannels = param.nChannels;
    357             // NOTE: For amrnb sample rate is 8k and amrwb sample rate is 16k.
    358             // There is no nSampleRate field in OMX_AUDIO_PARAM_AMRTYPE. Just
    359             // return 8k to avoid returning uninit variable.
    360             *nSampleRate = 8000;
    361             break;
    362         }
    363         case OMX_AUDIO_CodingAAC: {
    364             OMX_AUDIO_PARAM_AACPROFILETYPE param;
    365             status = getPortParam(omxNode, OMX_IndexParamAudioAac,
    366                                   kPortIndexInput, &param);
    367             ASSERT_EQ(status,
    368                       ::android::hardware::media::omx::V1_0::Status::OK);
    369             *nChannels = param.nChannels;
    370             *nSampleRate = param.nSampleRate;
    371             break;
    372         }
    373         case OMX_AUDIO_CodingFLAC: {
    374             OMX_AUDIO_PARAM_FLACTYPE param;
    375             status = getPortParam(omxNode, OMX_IndexParamAudioFlac,
    376                                   kPortIndexInput, &param);
    377             ASSERT_EQ(status,
    378                       ::android::hardware::media::omx::V1_0::Status::OK);
    379             *nChannels = param.nChannels;
    380             *nSampleRate = param.nSampleRate;
    381             break;
    382         }
    383         default:
    384             ASSERT_TRUE(false);
    385             break;
    386     }
    387 }
    388 
    389 // LookUpTable of clips and metadata for component testing
    390 void GetURLForComponent(AudioDecHidlTest::standardComp comp, char* mURL,
    391                         char* info) {
    392     struct CompToURL {
    393         AudioDecHidlTest::standardComp comp;
    394         const char* mURL;
    395         const char* info;
    396     };
    397     static const CompToURL kCompToURL[] = {
    398         {AudioDecHidlTest::standardComp::mp3,
    399          "bbb_mp3_stereo_192kbps_48000hz.mp3",
    400          "bbb_mp3_stereo_192kbps_48000hz.info"},
    401         {AudioDecHidlTest::standardComp::aac,
    402          "bbb_aac_stereo_128kbps_48000hz.aac",
    403          "bbb_aac_stereo_128kbps_48000hz.info"},
    404         {AudioDecHidlTest::standardComp::amrnb,
    405          "sine_amrnb_1ch_12kbps_8000hz.amrnb",
    406          "sine_amrnb_1ch_12kbps_8000hz.info"},
    407         {AudioDecHidlTest::standardComp::amrwb,
    408          "bbb_amrwb_1ch_14kbps_16000hz.amrwb",
    409          "bbb_amrwb_1ch_14kbps_16000hz.info"},
    410         {AudioDecHidlTest::standardComp::vorbis,
    411          "bbb_vorbis_stereo_128kbps_48000hz.vorbis",
    412          "bbb_vorbis_stereo_128kbps_48000hz.info"},
    413         {AudioDecHidlTest::standardComp::opus,
    414          "bbb_opus_stereo_128kbps_48000hz.opus",
    415          "bbb_opus_stereo_128kbps_48000hz.info"},
    416         {AudioDecHidlTest::standardComp::g711alaw, "bbb_g711alaw_1ch_8khz.raw",
    417          "bbb_g711alaw_1ch_8khz.info"},
    418         {AudioDecHidlTest::standardComp::g711mlaw, "bbb_g711mulaw_1ch_8khz.raw",
    419          "bbb_g711mulaw_1ch_8khz.info"},
    420         {AudioDecHidlTest::standardComp::gsm, "bbb_gsm_1ch_8khz_13kbps.raw",
    421          "bbb_gsm_1ch_8khz_13kbps.info"},
    422         {AudioDecHidlTest::standardComp::raw, "bbb_raw_1ch_8khz_s32le.raw",
    423          "bbb_raw_1ch_8khz_s32le.info"},
    424         {AudioDecHidlTest::standardComp::flac,
    425          "bbb_flac_stereo_680kbps_48000hz.flac",
    426          "bbb_flac_stereo_680kbps_48000hz.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);
    432             strcat(info, kCompToURL[i].info);
    433             return;
    434         }
    435     }
    436 }
    437 
    438 // port settings reconfiguration during runtime. reconfigures sample rate and
    439 // number
    440 typedef struct {
    441     OMX_AUDIO_CODINGTYPE eEncoding;
    442     AudioDecHidlTest::standardComp comp;
    443 } packedArgs;
    444 void portReconfiguration(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
    445                          android::Vector<BufferInfo>* iBuffer,
    446                          android::Vector<BufferInfo>* oBuffer,
    447                          OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput,
    448                          Message msg, PortMode oPortMode, void* args) {
    449     android::hardware::media::omx::V1_0::Status status;
    450     packedArgs* audioArgs = static_cast<packedArgs*>(args);
    451     OMX_AUDIO_CODINGTYPE eEncoding = audioArgs->eEncoding;
    452     AudioDecHidlTest::standardComp comp = audioArgs->comp;
    453     (void)oPortMode;
    454 
    455     if (msg.data.eventData.event == OMX_EventPortSettingsChanged) {
    456         ASSERT_EQ(msg.data.eventData.data1, kPortIndexOutput);
    457 
    458         status = omxNode->sendCommand(toRawCommandType(OMX_CommandPortDisable),
    459                                       kPortIndexOutput);
    460         ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
    461 
    462         status =
    463             observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
    464         if (status == android::hardware::media::omx::V1_0::Status::TIMED_OUT) {
    465             for (size_t i = 0; i < oBuffer->size(); ++i) {
    466                 // test if client got all its buffers back
    467                 EXPECT_EQ((*oBuffer)[i].owner, client);
    468                 // free the buffers
    469                 status =
    470                     omxNode->freeBuffer(kPortIndexOutput, (*oBuffer)[i].id);
    471                 ASSERT_EQ(status,
    472                           android::hardware::media::omx::V1_0::Status::OK);
    473             }
    474             status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer,
    475                                               oBuffer);
    476             ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
    477             ASSERT_EQ(msg.type, Message::Type::EVENT);
    478             ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
    479             ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortDisable);
    480             ASSERT_EQ(msg.data.eventData.data2, kPortIndexOutput);
    481 
    482             // set Port Params
    483             int32_t nChannels;
    484             int32_t nSampleRate;
    485             ASSERT_NO_FATAL_FAILURE(getInputChannelInfo(
    486                 omxNode, kPortIndexInput, eEncoding, &nChannels, &nSampleRate));
    487             // Configure output port
    488             // SPECIAL CASE: Soft Vorbis, Opus and Raw Decoders do not offer way
    489             // to configure output PCM port. The port undergoes auto
    490             // configuration internally basing on parsed elementary stream
    491             // information.
    492             if (comp != AudioDecHidlTest::standardComp::vorbis &&
    493                 comp != AudioDecHidlTest::standardComp::opus &&
    494                 comp != AudioDecHidlTest::standardComp::raw) {
    495                 setDefaultPortParam(omxNode, kPortIndexOutput,
    496                                     OMX_AUDIO_CodingPCM, nChannels,
    497                                     nSampleRate);
    498             }
    499 
    500             // If you can disable a port, then you should be able to enable it
    501             // as well
    502             status = omxNode->sendCommand(
    503                 toRawCommandType(OMX_CommandPortEnable), kPortIndexOutput);
    504             ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
    505 
    506             // do not enable the port until all the buffers are supplied
    507             status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer,
    508                                               oBuffer);
    509             ASSERT_EQ(status,
    510                       android::hardware::media::omx::V1_0::Status::TIMED_OUT);
    511 
    512             ASSERT_NO_FATAL_FAILURE(
    513                 allocatePortBuffers(omxNode, oBuffer, kPortIndexOutput));
    514             status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer,
    515                                               oBuffer);
    516             ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
    517             ASSERT_EQ(msg.type, Message::Type::EVENT);
    518             ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortEnable);
    519             ASSERT_EQ(msg.data.eventData.data2, kPortIndexOutput);
    520 
    521             // dispatch output buffers
    522             for (size_t i = 0; i < oBuffer->size(); i++) {
    523                 ASSERT_NO_FATAL_FAILURE(
    524                     dispatchOutputBuffer(omxNode, oBuffer, i));
    525             }
    526         } else {
    527             ASSERT_TRUE(false);
    528         }
    529     } else {
    530         ASSERT_TRUE(false);
    531     }
    532 }
    533 
    534 // blocking call to ensures application to Wait till all the inputs are consumed
    535 void waitOnInputConsumption(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
    536                             android::Vector<BufferInfo>* iBuffer,
    537                             android::Vector<BufferInfo>* oBuffer,
    538                             OMX_AUDIO_CODINGTYPE eEncoding,
    539                             OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput,
    540                             AudioDecHidlTest::standardComp comp) {
    541     android::hardware::media::omx::V1_0::Status status;
    542     Message msg;
    543     int timeOut = TIMEOUT_COUNTER_Q;
    544 
    545     while (timeOut--) {
    546         size_t i = 0;
    547         status =
    548             observer->dequeueMessage(&msg, DEFAULT_TIMEOUT_Q, iBuffer, oBuffer);
    549         if (status == android::hardware::media::omx::V1_0::Status::OK) {
    550             ASSERT_EQ(msg.type, Message::Type::EVENT);
    551             packedArgs audioArgs = {eEncoding, comp};
    552             ASSERT_NO_FATAL_FAILURE(
    553                 portReconfiguration(omxNode, observer, iBuffer, oBuffer,
    554                                     kPortIndexInput, kPortIndexOutput, msg,
    555                                     PortMode::PRESET_BYTE_BUFFER, &audioArgs));
    556         }
    557         // status == TIMED_OUT, it could be due to process time being large
    558         // than DEFAULT_TIMEOUT or component needs output buffers to start
    559         // processing.
    560         for (; i < iBuffer->size(); i++) {
    561             if ((*iBuffer)[i].owner != client) break;
    562         }
    563         if (i == iBuffer->size()) break;
    564 
    565         // Dispatch an output buffer assuming outQueue.empty() is true
    566         size_t index;
    567         if ((index = getEmptyBufferID(oBuffer)) < oBuffer->size()) {
    568             ASSERT_NO_FATAL_FAILURE(
    569                 dispatchOutputBuffer(omxNode, oBuffer, index));
    570             timeOut = TIMEOUT_COUNTER_Q;
    571         }
    572     }
    573 }
    574 
    575 // Decode N Frames
    576 void decodeNFrames(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
    577                    android::Vector<BufferInfo>* iBuffer,
    578                    android::Vector<BufferInfo>* oBuffer,
    579                    OMX_AUDIO_CODINGTYPE eEncoding, OMX_U32 kPortIndexInput,
    580                    OMX_U32 kPortIndexOutput, std::ifstream& eleStream,
    581                    android::Vector<FrameData>* Info, int offset, int range,
    582                    AudioDecHidlTest::standardComp comp, bool signalEOS = true) {
    583     android::hardware::media::omx::V1_0::Status status;
    584     Message msg;
    585     size_t index;
    586     uint32_t flags = 0;
    587     int frameID = offset;
    588     int timeOut = TIMEOUT_COUNTER_Q;
    589     bool iQueued, oQueued;
    590 
    591     while (1) {
    592         iQueued = oQueued = false;
    593         status =
    594             observer->dequeueMessage(&msg, DEFAULT_TIMEOUT_Q, iBuffer, oBuffer);
    595         // Port Reconfiguration
    596         if (status == android::hardware::media::omx::V1_0::Status::OK &&
    597             msg.type == Message::Type::EVENT) {
    598             packedArgs audioArgs = {eEncoding, comp};
    599             ASSERT_NO_FATAL_FAILURE(
    600                 portReconfiguration(omxNode, observer, iBuffer, oBuffer,
    601                                     kPortIndexInput, kPortIndexOutput, msg,
    602                                     PortMode::PRESET_BYTE_BUFFER, &audioArgs));
    603         }
    604 
    605         if (frameID == (int)Info->size() || frameID == (offset + range)) break;
    606 
    607         // Dispatch input buffer
    608         if ((index = getEmptyBufferID(iBuffer)) < iBuffer->size()) {
    609             char* ipBuffer = static_cast<char*>(
    610                 static_cast<void*>((*iBuffer)[index].mMemory->getPointer()));
    611             ASSERT_LE((*Info)[frameID].bytesCount,
    612                       static_cast<int>((*iBuffer)[index].mMemory->getSize()));
    613             eleStream.read(ipBuffer, (*Info)[frameID].bytesCount);
    614             ASSERT_EQ(eleStream.gcount(), (*Info)[frameID].bytesCount);
    615             flags = (*Info)[frameID].flags;
    616             // Indicate to omx core that the buffer contains a full frame worth
    617             // of data
    618             flags |= OMX_BUFFERFLAG_ENDOFFRAME;
    619             // Indicate the omx core that this is the last buffer it needs to
    620             // process
    621             if (signalEOS && ((frameID == (int)Info->size() - 1) ||
    622                               (frameID == (offset + range - 1))))
    623                 flags |= OMX_BUFFERFLAG_EOS;
    624             ASSERT_NO_FATAL_FAILURE(dispatchInputBuffer(
    625                 omxNode, iBuffer, index, (*Info)[frameID].bytesCount, flags,
    626                 (*Info)[frameID].timestamp));
    627             frameID++;
    628             iQueued = true;
    629         }
    630         // Dispatch output buffer
    631         if ((index = getEmptyBufferID(oBuffer)) < oBuffer->size()) {
    632             ASSERT_NO_FATAL_FAILURE(
    633                 dispatchOutputBuffer(omxNode, oBuffer, index));
    634             oQueued = true;
    635         }
    636         // Reset Counters when either input or output buffer is dispatched
    637         if (iQueued || oQueued)
    638             timeOut = TIMEOUT_COUNTER_Q;
    639         else
    640             timeOut--;
    641         if (timeOut == 0) {
    642             ASSERT_TRUE(false) << "Wait on Input/Output is found indefinite";
    643         }
    644     }
    645 }
    646 
    647 // set component role
    648 TEST_F(AudioDecHidlTest, SetRole) {
    649     description("Test Set Component Role");
    650     if (disableTest) return;
    651     android::hardware::media::omx::V1_0::Status status;
    652     status = setRole(omxNode, gEnv->getRole().c_str());
    653     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
    654 }
    655 
    656 // port format enumeration
    657 TEST_F(AudioDecHidlTest, EnumeratePortFormat) {
    658     description("Test Component on Mandatory Port Parameters (Port Format)");
    659     if (disableTest) return;
    660     android::hardware::media::omx::V1_0::Status status;
    661     uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
    662     status = setRole(omxNode, gEnv->getRole().c_str());
    663     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
    664     OMX_PORT_PARAM_TYPE params;
    665     status = getParam(omxNode, OMX_IndexParamAudioInit, &params);
    666     if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
    667         ASSERT_EQ(params.nPorts, 2U);
    668         kPortIndexInput = params.nStartPortNumber;
    669         kPortIndexOutput = kPortIndexInput + 1;
    670     }
    671     status = setAudioPortFormat(omxNode, kPortIndexInput, eEncoding);
    672     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
    673     status = setAudioPortFormat(omxNode, kPortIndexOutput, OMX_AUDIO_CodingPCM);
    674     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
    675 }
    676 
    677 // test port settings reconfiguration, elementary stream decode and timestamp
    678 // deviation
    679 TEST_F(AudioDecHidlTest, DecodeTest) {
    680     description("Tests Port Reconfiguration, Decode and timestamp deviation");
    681     if (disableTest) return;
    682     android::hardware::media::omx::V1_0::Status status;
    683     uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
    684     status = setRole(omxNode, gEnv->getRole().c_str());
    685     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
    686     OMX_PORT_PARAM_TYPE params;
    687     status = getParam(omxNode, OMX_IndexParamAudioInit, &params);
    688     if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
    689         ASSERT_EQ(params.nPorts, 2U);
    690         kPortIndexInput = params.nStartPortNumber;
    691         kPortIndexOutput = kPortIndexInput + 1;
    692     }
    693     char mURL[512], info[512];
    694     strcpy(mURL, gEnv->getRes().c_str());
    695     strcpy(info, gEnv->getRes().c_str());
    696     GetURLForComponent(compName, mURL, info);
    697 
    698     std::ifstream eleStream, eleInfo;
    699 
    700     eleInfo.open(info);
    701     ASSERT_EQ(eleInfo.is_open(), true);
    702     android::Vector<FrameData> Info;
    703     int bytesCount = 0;
    704     uint32_t flags = 0;
    705     uint32_t timestamp = 0;
    706     timestampDevTest = false;
    707     while (1) {
    708         if (!(eleInfo >> bytesCount)) break;
    709         eleInfo >> flags;
    710         eleInfo >> timestamp;
    711         Info.push_back({bytesCount, flags, timestamp});
    712         if (timestampDevTest && (flags != OMX_BUFFERFLAG_CODECCONFIG))
    713             timestampUslist.push_back(timestamp);
    714     }
    715     eleInfo.close();
    716 
    717     int32_t nChannels, nSampleRate;
    718     // Configure input port
    719     setDefaultPortParam(omxNode, kPortIndexInput, eEncoding);
    720     if (compName == raw)
    721         setDefaultPortParam(omxNode, kPortIndexInput, eEncoding, 1, 8000,
    722                             OMX_AUDIO_PCMModeLinear, OMX_NumericalDataSigned,
    723                             32);
    724     ASSERT_NO_FATAL_FAILURE(getInputChannelInfo(
    725         omxNode, kPortIndexInput, eEncoding, &nChannels, &nSampleRate));
    726     // Configure output port
    727     // SPECIAL CASE: Soft Vorbis, Opus and Raw Decoders do not offer way to
    728     // configure output PCM port. The port undergoes auto configuration
    729     // internally basing on parsed elementary stream information.
    730     if (compName != vorbis && compName != opus && compName != raw) {
    731         setDefaultPortParam(omxNode, kPortIndexOutput, OMX_AUDIO_CodingPCM,
    732                             nChannels, nSampleRate);
    733     }
    734 
    735     android::Vector<BufferInfo> iBuffer, oBuffer;
    736 
    737     // set state to idle
    738     ASSERT_NO_FATAL_FAILURE(changeStateLoadedtoIdle(omxNode, observer, &iBuffer,
    739                                                     &oBuffer, kPortIndexInput,
    740                                                     kPortIndexOutput));
    741     // set state to executing
    742     ASSERT_NO_FATAL_FAILURE(changeStateIdletoExecute(omxNode, observer));
    743     // Port Reconfiguration
    744     eleStream.open(mURL, std::ifstream::binary);
    745     ASSERT_EQ(eleStream.is_open(), true);
    746     ASSERT_NO_FATAL_FAILURE(decodeNFrames(
    747         omxNode, observer, &iBuffer, &oBuffer, eEncoding, kPortIndexInput,
    748         kPortIndexOutput, eleStream, &Info, 0, (int)Info.size(), compName));
    749     eleStream.close();
    750     ASSERT_NO_FATAL_FAILURE(
    751         waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer, eEncoding,
    752                                kPortIndexInput, kPortIndexOutput, compName));
    753     packedArgs audioArgs = {eEncoding, compName};
    754     ASSERT_NO_FATAL_FAILURE(testEOS(
    755         omxNode, observer, &iBuffer, &oBuffer, false, eosFlag, nullptr,
    756         portReconfiguration, kPortIndexInput, kPortIndexOutput, &audioArgs));
    757     if (timestampDevTest) EXPECT_EQ(timestampUslist.empty(), true);
    758     // set state to idle
    759     ASSERT_NO_FATAL_FAILURE(
    760         changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer));
    761     // set state to executing
    762     ASSERT_NO_FATAL_FAILURE(changeStateIdletoLoaded(omxNode, observer, &iBuffer,
    763                                                     &oBuffer, kPortIndexInput,
    764                                                     kPortIndexOutput));
    765 }
    766 
    767 // end of sequence test
    768 TEST_F(AudioDecHidlTest, EOSTest_M) {
    769     description("Test end of stream monkeying");
    770     if (disableTest) return;
    771     android::hardware::media::omx::V1_0::Status status;
    772     uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
    773     status = setRole(omxNode, gEnv->getRole().c_str());
    774     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
    775     OMX_PORT_PARAM_TYPE params;
    776     status = getParam(omxNode, OMX_IndexParamAudioInit, &params);
    777     if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
    778         ASSERT_EQ(params.nPorts, 2U);
    779         kPortIndexInput = params.nStartPortNumber;
    780         kPortIndexOutput = kPortIndexInput + 1;
    781     }
    782 
    783     int32_t nChannels, nSampleRate;
    784     // Configure input port
    785     setDefaultPortParam(omxNode, kPortIndexInput, eEncoding);
    786     if (compName == raw)
    787         setDefaultPortParam(omxNode, kPortIndexInput, eEncoding, 1, 8000,
    788                             OMX_AUDIO_PCMModeLinear, OMX_NumericalDataSigned,
    789                             32);
    790     ASSERT_NO_FATAL_FAILURE(getInputChannelInfo(
    791         omxNode, kPortIndexInput, eEncoding, &nChannels, &nSampleRate));
    792     // Configure output port
    793     // SPECIAL CASE: Soft Vorbis, Opus and Raw Decoders do not offer way to
    794     // configure output PCM port. The port undergoes auto configuration
    795     // internally basing on parsed elementary stream information.
    796     if (compName != vorbis && compName != opus && compName != raw) {
    797         setDefaultPortParam(omxNode, kPortIndexOutput, OMX_AUDIO_CodingPCM,
    798                             nChannels, nSampleRate);
    799     }
    800 
    801     android::Vector<BufferInfo> iBuffer, oBuffer;
    802 
    803     // set state to idle
    804     ASSERT_NO_FATAL_FAILURE(changeStateLoadedtoIdle(omxNode, observer, &iBuffer,
    805                                                     &oBuffer, kPortIndexInput,
    806                                                     kPortIndexOutput));
    807     // set state to executing
    808     ASSERT_NO_FATAL_FAILURE(changeStateIdletoExecute(omxNode, observer));
    809 
    810     // request EOS at the start
    811     packedArgs audioArgs = {eEncoding, compName};
    812     ASSERT_NO_FATAL_FAILURE(testEOS(
    813         omxNode, observer, &iBuffer, &oBuffer, true, eosFlag, nullptr,
    814         portReconfiguration, kPortIndexInput, kPortIndexOutput, &audioArgs));
    815     ASSERT_NO_FATAL_FAILURE(flushPorts(omxNode, observer, &iBuffer, &oBuffer,
    816                                        kPortIndexInput, kPortIndexOutput));
    817     EXPECT_GE(framesReceived, 0U);
    818     framesReceived = 0;
    819     timestampUs = 0;
    820 
    821     // set state to idle
    822     ASSERT_NO_FATAL_FAILURE(
    823         changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer));
    824 
    825     // set state to executing
    826     ASSERT_NO_FATAL_FAILURE(changeStateIdletoLoaded(omxNode, observer, &iBuffer,
    827                                                     &oBuffer, kPortIndexInput,
    828                                                     kPortIndexOutput));
    829 }
    830 
    831 // end of sequence test
    832 TEST_F(AudioDecHidlTest, ThumbnailTest) {
    833     description("Test Request for thumbnail");
    834     if (disableTest) return;
    835     android::hardware::media::omx::V1_0::Status status;
    836     uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
    837     status = setRole(omxNode, gEnv->getRole().c_str());
    838     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
    839     OMX_PORT_PARAM_TYPE params;
    840     status = getParam(omxNode, OMX_IndexParamAudioInit, &params);
    841     if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
    842         ASSERT_EQ(params.nPorts, 2U);
    843         kPortIndexInput = params.nStartPortNumber;
    844         kPortIndexOutput = kPortIndexInput + 1;
    845     }
    846     char mURL[512], info[512];
    847     strcpy(mURL, gEnv->getRes().c_str());
    848     strcpy(info, gEnv->getRes().c_str());
    849     GetURLForComponent(compName, mURL, info);
    850 
    851     std::ifstream eleStream, eleInfo;
    852 
    853     eleInfo.open(info);
    854     ASSERT_EQ(eleInfo.is_open(), true);
    855     android::Vector<FrameData> Info;
    856     int bytesCount = 0;
    857     uint32_t flags = 0;
    858     uint32_t timestamp = 0;
    859     while (1) {
    860         if (!(eleInfo >> bytesCount)) break;
    861         eleInfo >> flags;
    862         eleInfo >> timestamp;
    863         Info.push_back({bytesCount, flags, timestamp});
    864     }
    865     eleInfo.close();
    866 
    867     int32_t nChannels, nSampleRate;
    868     // Configure input port
    869     setDefaultPortParam(omxNode, kPortIndexInput, eEncoding);
    870     if (compName == raw)
    871         setDefaultPortParam(omxNode, kPortIndexInput, eEncoding, 1, 8000,
    872                             OMX_AUDIO_PCMModeLinear, OMX_NumericalDataSigned,
    873                             32);
    874     ASSERT_NO_FATAL_FAILURE(getInputChannelInfo(
    875         omxNode, kPortIndexInput, eEncoding, &nChannels, &nSampleRate));
    876     // Configure output port
    877     // SPECIAL CASE: Soft Vorbis, Opus and Raw Decoders do not offer way to
    878     // configure output PCM port. The port undergoes auto configuration
    879     // internally basing on parsed elementary stream information.
    880     if (compName != vorbis && compName != opus && compName != raw) {
    881         setDefaultPortParam(omxNode, kPortIndexOutput, OMX_AUDIO_CodingPCM,
    882                             nChannels, nSampleRate);
    883     }
    884 
    885     android::Vector<BufferInfo> iBuffer, oBuffer;
    886 
    887     // set state to idle
    888     ASSERT_NO_FATAL_FAILURE(changeStateLoadedtoIdle(omxNode, observer, &iBuffer,
    889                                                     &oBuffer, kPortIndexInput,
    890                                                     kPortIndexOutput));
    891     // set state to executing
    892     ASSERT_NO_FATAL_FAILURE(changeStateIdletoExecute(omxNode, observer));
    893 
    894     // request EOS for thumbnail
    895     // signal EOS flag with last frame
    896     size_t i = 0;
    897     while (!(Info[i].flags & OMX_BUFFERFLAG_SYNCFRAME)) i++;
    898     eleStream.open(mURL, std::ifstream::binary);
    899     ASSERT_EQ(eleStream.is_open(), true);
    900     ASSERT_NO_FATAL_FAILURE(decodeNFrames(
    901         omxNode, observer, &iBuffer, &oBuffer, eEncoding, kPortIndexInput,
    902         kPortIndexOutput, eleStream, &Info, 0, i + 1, compName));
    903     eleStream.close();
    904     ASSERT_NO_FATAL_FAILURE(
    905         waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer, eEncoding,
    906                                kPortIndexInput, kPortIndexOutput, compName));
    907     packedArgs audioArgs = {eEncoding, compName};
    908     ASSERT_NO_FATAL_FAILURE(testEOS(
    909         omxNode, observer, &iBuffer, &oBuffer, false, eosFlag, nullptr,
    910         portReconfiguration, kPortIndexInput, kPortIndexOutput, &audioArgs));
    911     ASSERT_NO_FATAL_FAILURE(flushPorts(omxNode, observer, &iBuffer, &oBuffer,
    912                                        kPortIndexInput, kPortIndexOutput));
    913     EXPECT_GE(framesReceived, 1U);
    914     framesReceived = 0;
    915     timestampUs = 0;
    916 
    917     // signal EOS flag after last frame
    918     eleStream.open(mURL, std::ifstream::binary);
    919     ASSERT_EQ(eleStream.is_open(), true);
    920     ASSERT_NO_FATAL_FAILURE(decodeNFrames(
    921         omxNode, observer, &iBuffer, &oBuffer, eEncoding, kPortIndexInput,
    922         kPortIndexOutput, eleStream, &Info, 0, i + 1, compName, false));
    923     eleStream.close();
    924     ASSERT_NO_FATAL_FAILURE(
    925         waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer, eEncoding,
    926                                kPortIndexInput, kPortIndexOutput, compName));
    927     ASSERT_NO_FATAL_FAILURE(testEOS(
    928         omxNode, observer, &iBuffer, &oBuffer, true, eosFlag, nullptr,
    929         portReconfiguration, kPortIndexInput, kPortIndexOutput, &audioArgs));
    930     ASSERT_NO_FATAL_FAILURE(flushPorts(omxNode, observer, &iBuffer, &oBuffer,
    931                                        kPortIndexInput, kPortIndexOutput));
    932     EXPECT_GE(framesReceived, 1U);
    933     framesReceived = 0;
    934     timestampUs = 0;
    935 
    936     // set state to idle
    937     ASSERT_NO_FATAL_FAILURE(
    938         changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer));
    939     // set state to executing
    940     ASSERT_NO_FATAL_FAILURE(changeStateIdletoLoaded(omxNode, observer, &iBuffer,
    941                                                     &oBuffer, kPortIndexInput,
    942                                                     kPortIndexOutput));
    943 }
    944 
    945 // end of sequence test
    946 TEST_F(AudioDecHidlTest, SimpleEOSTest) {
    947     description("Test end of stream");
    948     if (disableTest) return;
    949     android::hardware::media::omx::V1_0::Status status;
    950     uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
    951     status = setRole(omxNode, gEnv->getRole().c_str());
    952     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
    953     OMX_PORT_PARAM_TYPE params;
    954     status = getParam(omxNode, OMX_IndexParamAudioInit, &params);
    955     if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
    956         ASSERT_EQ(params.nPorts, 2U);
    957         kPortIndexInput = params.nStartPortNumber;
    958         kPortIndexOutput = kPortIndexInput + 1;
    959     }
    960     char mURL[512], info[512];
    961     strcpy(mURL, gEnv->getRes().c_str());
    962     strcpy(info, gEnv->getRes().c_str());
    963     GetURLForComponent(compName, mURL, info);
    964 
    965     std::ifstream eleStream, eleInfo;
    966 
    967     eleInfo.open(info);
    968     ASSERT_EQ(eleInfo.is_open(), true);
    969     android::Vector<FrameData> Info;
    970     int bytesCount = 0;
    971     uint32_t flags = 0;
    972     uint32_t timestamp = 0;
    973     while (1) {
    974         if (!(eleInfo >> bytesCount)) break;
    975         eleInfo >> flags;
    976         eleInfo >> timestamp;
    977         Info.push_back({bytesCount, flags, timestamp});
    978     }
    979     eleInfo.close();
    980 
    981     int32_t nChannels, nSampleRate;
    982     // Configure input port
    983     setDefaultPortParam(omxNode, kPortIndexInput, eEncoding);
    984     if (compName == raw)
    985         setDefaultPortParam(omxNode, kPortIndexInput, eEncoding, 1, 8000,
    986                             OMX_AUDIO_PCMModeLinear, OMX_NumericalDataSigned,
    987                             32);
    988     ASSERT_NO_FATAL_FAILURE(getInputChannelInfo(
    989         omxNode, kPortIndexInput, eEncoding, &nChannels, &nSampleRate));
    990     // Configure output port
    991     // SPECIAL CASE: Soft Vorbis, Opus and Raw Decoders do not offer way to
    992     // configure output PCM port. The port undergoes auto configuration
    993     // internally basing on parsed elementary stream information.
    994     if (compName != vorbis && compName != opus && compName != raw) {
    995         setDefaultPortParam(omxNode, kPortIndexOutput, OMX_AUDIO_CodingPCM,
    996                             nChannels, nSampleRate);
    997     }
    998 
    999     android::Vector<BufferInfo> iBuffer, oBuffer;
   1000 
   1001     // set state to idle
   1002     ASSERT_NO_FATAL_FAILURE(changeStateLoadedtoIdle(omxNode, observer, &iBuffer,
   1003                                                     &oBuffer, kPortIndexInput,
   1004                                                     kPortIndexOutput));
   1005     // set state to executing
   1006     ASSERT_NO_FATAL_FAILURE(changeStateIdletoExecute(omxNode, observer));
   1007 
   1008     // request EOS at the end
   1009     eleStream.open(mURL, std::ifstream::binary);
   1010     ASSERT_EQ(eleStream.is_open(), true);
   1011     ASSERT_NO_FATAL_FAILURE(decodeNFrames(omxNode, observer, &iBuffer, &oBuffer,
   1012                                           eEncoding, kPortIndexInput,
   1013                                           kPortIndexOutput, eleStream, &Info, 0,
   1014                                           (int)Info.size(), compName, false));
   1015     eleStream.close();
   1016     ASSERT_NO_FATAL_FAILURE(
   1017         waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer, eEncoding,
   1018                                kPortIndexInput, kPortIndexOutput, compName));
   1019     packedArgs audioArgs = {eEncoding, compName};
   1020     ASSERT_NO_FATAL_FAILURE(testEOS(
   1021         omxNode, observer, &iBuffer, &oBuffer, true, eosFlag, nullptr,
   1022         portReconfiguration, kPortIndexInput, kPortIndexOutput, &audioArgs));
   1023     ASSERT_NO_FATAL_FAILURE(flushPorts(omxNode, observer, &iBuffer, &oBuffer,
   1024                                        kPortIndexInput, kPortIndexOutput));
   1025     framesReceived = 0;
   1026     timestampUs = 0;
   1027 
   1028     // set state to idle
   1029     ASSERT_NO_FATAL_FAILURE(
   1030         changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer));
   1031     // set state to executing
   1032     ASSERT_NO_FATAL_FAILURE(changeStateIdletoLoaded(omxNode, observer, &iBuffer,
   1033                                                     &oBuffer, kPortIndexInput,
   1034                                                     kPortIndexOutput));
   1035 }
   1036 
   1037 // test input/output port flush
   1038 TEST_F(AudioDecHidlTest, FlushTest) {
   1039     description("Test Flush");
   1040     if (disableTest) return;
   1041     android::hardware::media::omx::V1_0::Status status;
   1042     uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
   1043     status = setRole(omxNode, gEnv->getRole().c_str());
   1044     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
   1045     OMX_PORT_PARAM_TYPE params;
   1046     status = getParam(omxNode, OMX_IndexParamAudioInit, &params);
   1047     if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
   1048         ASSERT_EQ(params.nPorts, 2U);
   1049         kPortIndexInput = params.nStartPortNumber;
   1050         kPortIndexOutput = kPortIndexInput + 1;
   1051     }
   1052     char mURL[512], info[512];
   1053     strcpy(mURL, gEnv->getRes().c_str());
   1054     strcpy(info, gEnv->getRes().c_str());
   1055     GetURLForComponent(compName, mURL, info);
   1056 
   1057     std::ifstream eleStream, eleInfo;
   1058 
   1059     eleInfo.open(info);
   1060     ASSERT_EQ(eleInfo.is_open(), true);
   1061     android::Vector<FrameData> Info;
   1062     int bytesCount = 0;
   1063     uint32_t flags = 0;
   1064     uint32_t timestamp = 0;
   1065     while (1) {
   1066         if (!(eleInfo >> bytesCount)) break;
   1067         eleInfo >> flags;
   1068         eleInfo >> timestamp;
   1069         Info.push_back({bytesCount, flags, timestamp});
   1070     }
   1071     eleInfo.close();
   1072 
   1073     int32_t nChannels, nSampleRate;
   1074     // Configure input port
   1075     setDefaultPortParam(omxNode, kPortIndexInput, eEncoding);
   1076     if (compName == raw)
   1077         setDefaultPortParam(omxNode, kPortIndexInput, eEncoding, 1, 8000,
   1078                             OMX_AUDIO_PCMModeLinear, OMX_NumericalDataSigned,
   1079                             32);
   1080     ASSERT_NO_FATAL_FAILURE(getInputChannelInfo(
   1081         omxNode, kPortIndexInput, eEncoding, &nChannels, &nSampleRate));
   1082     // Configure output port
   1083     // SPECIAL CASE: Soft Vorbis, Opus and Raw Decoders do not offer way to
   1084     // configure output PCM port. The port undergoes auto configuration
   1085     // internally basing on parsed elementary stream information.
   1086     if (compName != vorbis && compName != opus && compName != raw) {
   1087         setDefaultPortParam(omxNode, kPortIndexOutput, OMX_AUDIO_CodingPCM,
   1088                             nChannels, nSampleRate);
   1089     }
   1090 
   1091     android::Vector<BufferInfo> iBuffer, oBuffer;
   1092 
   1093     // set state to idle
   1094     ASSERT_NO_FATAL_FAILURE(changeStateLoadedtoIdle(omxNode, observer, &iBuffer,
   1095                                                     &oBuffer, kPortIndexInput,
   1096                                                     kPortIndexOutput));
   1097     // set state to executing
   1098     ASSERT_NO_FATAL_FAILURE(changeStateIdletoExecute(omxNode, observer));
   1099 
   1100     // Decode 128 frames and flush. here 128 is chosen to ensure there is a key
   1101     // frame after this so that the below section can be convered for all
   1102     // components
   1103     int nFrames = 128;
   1104     eleStream.open(mURL, std::ifstream::binary);
   1105     ASSERT_EQ(eleStream.is_open(), true);
   1106     ASSERT_NO_FATAL_FAILURE(decodeNFrames(
   1107         omxNode, observer, &iBuffer, &oBuffer, eEncoding, kPortIndexInput,
   1108         kPortIndexOutput, eleStream, &Info, 0, nFrames, compName, false));
   1109     ASSERT_NO_FATAL_FAILURE(flushPorts(omxNode, observer, &iBuffer, &oBuffer,
   1110                                        kPortIndexInput, kPortIndexOutput));
   1111     framesReceived = 0;
   1112 
   1113     // Seek to next key frame and start decoding till the end
   1114     int index = nFrames;
   1115     bool keyFrame = false;
   1116     while (index < (int)Info.size()) {
   1117         if ((Info[index].flags & OMX_BUFFERFLAG_SYNCFRAME) ==
   1118             OMX_BUFFERFLAG_SYNCFRAME) {
   1119             timestampUs = Info[index - 1].timestamp;
   1120             keyFrame = true;
   1121             break;
   1122         }
   1123         eleStream.ignore(Info[index].bytesCount);
   1124         index++;
   1125     }
   1126     if (keyFrame) {
   1127         ASSERT_NO_FATAL_FAILURE(
   1128             decodeNFrames(omxNode, observer, &iBuffer, &oBuffer, eEncoding,
   1129                           kPortIndexInput, kPortIndexOutput, eleStream, &Info,
   1130                           index, Info.size() - index, compName, false));
   1131     }
   1132     ASSERT_NO_FATAL_FAILURE(flushPorts(omxNode, observer, &iBuffer, &oBuffer,
   1133                                        kPortIndexInput, kPortIndexOutput));
   1134     framesReceived = 0;
   1135 
   1136     // set state to idle
   1137     ASSERT_NO_FATAL_FAILURE(
   1138         changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer));
   1139     // set state to executing
   1140     ASSERT_NO_FATAL_FAILURE(changeStateIdletoLoaded(omxNode, observer, &iBuffer,
   1141                                                     &oBuffer, kPortIndexInput,
   1142                                                     kPortIndexOutput));
   1143 }
   1144 
   1145 int main(int argc, char** argv) {
   1146     gEnv = new ComponentTestEnvironment();
   1147     ::testing::AddGlobalTestEnvironment(gEnv);
   1148     ::testing::InitGoogleTest(&argc, argv);
   1149     gEnv->init(&argc, argv);
   1150     int status = gEnv->initFromOptions(argc, argv);
   1151     if (status == 0) {
   1152         status = RUN_ALL_TESTS();
   1153         ALOGI("Test result = %d", status);
   1154     }
   1155     return status;
   1156 }
   1157