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