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