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