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