OSDN Git Service

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