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:
SetUp()52 virtual void SetUp() {}
TearDown()53 virtual void TearDown() {}
54
ComponentTestEnvironment()55 ComponentTestEnvironment() : instance("default"), res("/sdcard/media/") {}
56
setInstance(const char * _instance)57 void setInstance(const char* _instance) { instance = _instance; }
58
setComponent(const char * _component)59 void setComponent(const char* _component) { component = _component; }
60
setRole(const char * _role)61 void setRole(const char* _role) { role = _role; }
62
setRes(const char * _res)63 void setRes(const char* _res) { res = _res; }
64
getInstance() const65 const hidl_string getInstance() const { return instance; }
66
getComponent() const67 const hidl_string getComponent() const { return component; }
68
getRole() const69 const hidl_string getRole() const { return role; }
70
getRes() const71 const hidl_string getRes() const { return res; }
72
initFromOptions(int argc,char ** argv)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:
SetUp()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
TearDown()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.
handleMessage(Message msg,const BufferInfo * buffer)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:
description(const std::string & description)309 static void description(const std::string& description) {
310 RecordProperty("description", description);
311 }
312 };
313
314 // Set Default port param.
setDefaultPortParam(sp<IOmxNode> omxNode,OMX_U32 portIndex,OMX_AUDIO_CODINGTYPE eEncoding,int32_t nChannels=2,int32_t nSampleRate=44100,OMX_AUDIO_PCMMODETYPE ePCMMode=OMX_AUDIO_PCMModeLinear,OMX_NUMERICALDATATYPE eNumData=OMX_NumericalDataSigned,int32_t nBitPerSample=16)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.
getInputChannelInfo(sp<IOmxNode> omxNode,OMX_U32 kPortIndexInput,OMX_AUDIO_CODINGTYPE eEncoding,int32_t * nChannels,int32_t * nSampleRate)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, ¶m);
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, ¶m);
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, ¶m);
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, ¶m);
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, ¶m);
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, ¶m);
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
GetURLForComponent(AudioDecHidlTest::standardComp comp,char * mURL,char * info)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
portReconfiguration(sp<IOmxNode> omxNode,sp<CodecObserver> observer,android::Vector<BufferInfo> * iBuffer,android::Vector<BufferInfo> * oBuffer,OMX_AUDIO_CODINGTYPE eEncoding,OMX_U32 kPortIndexInput,OMX_U32 kPortIndexOutput,Message msg,AudioDecHidlTest::standardComp comp=AudioDecHidlTest::standardComp::unknown_comp)477 void portReconfiguration(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
478 android::Vector<BufferInfo>* iBuffer,
479 android::Vector<BufferInfo>* oBuffer,
480 OMX_AUDIO_CODINGTYPE eEncoding,
481 OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput,
482 Message msg,
483 AudioDecHidlTest::standardComp comp =
484 AudioDecHidlTest::standardComp::unknown_comp) {
485 android::hardware::media::omx::V1_0::Status status;
486
487 if (msg.data.eventData.event == OMX_EventPortSettingsChanged) {
488 ASSERT_EQ(msg.data.eventData.data1, kPortIndexOutput);
489
490 status = omxNode->sendCommand(toRawCommandType(OMX_CommandPortDisable),
491 kPortIndexOutput);
492 ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
493
494 status =
495 observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
496 if (status == android::hardware::media::omx::V1_0::Status::TIMED_OUT) {
497 for (size_t i = 0; i < oBuffer->size(); ++i) {
498 // test if client got all its buffers back
499 EXPECT_EQ((*oBuffer)[i].owner, client);
500 // free the buffers
501 status =
502 omxNode->freeBuffer(kPortIndexOutput, (*oBuffer)[i].id);
503 ASSERT_EQ(status,
504 android::hardware::media::omx::V1_0::Status::OK);
505 }
506 status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer,
507 oBuffer);
508 ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
509 ASSERT_EQ(msg.type, Message::Type::EVENT);
510 ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
511 ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortDisable);
512 ASSERT_EQ(msg.data.eventData.data2, kPortIndexOutput);
513
514 // set Port Params
515 int32_t nChannels;
516 int32_t nSampleRate;
517 getInputChannelInfo(omxNode, kPortIndexInput, eEncoding, &nChannels,
518 &nSampleRate);
519 // Configure output port
520 // SPECIAL CASE: Soft Vorbis, Opus and Raw Decoders do not offer way
521 // to
522 // configure output PCM port. The port undergoes auto configuration
523 // internally basing on parsed elementary stream information.
524 if (comp != AudioDecHidlTest::standardComp::vorbis &&
525 comp != AudioDecHidlTest::standardComp::opus &&
526 comp != AudioDecHidlTest::standardComp::raw) {
527 setDefaultPortParam(omxNode, kPortIndexOutput,
528 OMX_AUDIO_CodingPCM, nChannels,
529 nSampleRate);
530 }
531
532 // If you can disable a port, then you should be able to
533 // enable
534 // it as well
535 status = omxNode->sendCommand(
536 toRawCommandType(OMX_CommandPortEnable), kPortIndexOutput);
537 ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
538
539 // do not enable the port until all the buffers are supplied
540 status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer,
541 oBuffer);
542 ASSERT_EQ(status,
543 android::hardware::media::omx::V1_0::Status::TIMED_OUT);
544
545 allocatePortBuffers(omxNode, oBuffer, kPortIndexOutput);
546 status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer,
547 oBuffer);
548 ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
549 ASSERT_EQ(msg.type, Message::Type::EVENT);
550 ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortEnable);
551 ASSERT_EQ(msg.data.eventData.data2, kPortIndexOutput);
552
553 // dispatch output buffers
554 for (size_t i = 0; i < oBuffer->size(); i++) {
555 dispatchOutputBuffer(omxNode, oBuffer, i);
556 }
557 } else {
558 ASSERT_TRUE(false);
559 }
560 } else {
561 EXPECT_TRUE(false);
562 return;
563 }
564 }
565
566 // blocking call to ensures application to Wait till all the inputs are consumed
waitOnInputConsumption(sp<IOmxNode> omxNode,sp<CodecObserver> observer,android::Vector<BufferInfo> * iBuffer,android::Vector<BufferInfo> * oBuffer,OMX_AUDIO_CODINGTYPE eEncoding,OMX_U32 kPortIndexInput,OMX_U32 kPortIndexOutput)567 void waitOnInputConsumption(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
568 android::Vector<BufferInfo>* iBuffer,
569 android::Vector<BufferInfo>* oBuffer,
570 OMX_AUDIO_CODINGTYPE eEncoding,
571 OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput) {
572 android::hardware::media::omx::V1_0::Status status;
573 Message msg;
574 int timeOut = TIMEOUT_COUNTER;
575
576 while (timeOut--) {
577 size_t i = 0;
578 status =
579 observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
580 if (status == android::hardware::media::omx::V1_0::Status::OK) {
581 EXPECT_EQ(msg.type, Message::Type::EVENT);
582 portReconfiguration(omxNode, observer, iBuffer, oBuffer, eEncoding,
583 kPortIndexInput, kPortIndexOutput, msg);
584 }
585 // status == TIMED_OUT, it could be due to process time being large
586 // than DEFAULT_TIMEOUT or component needs output buffers to start
587 // processing.
588 for (; i < iBuffer->size(); i++) {
589 if ((*iBuffer)[i].owner != client) break;
590 }
591 if (i == iBuffer->size()) break;
592
593 // Dispatch an output buffer assuming outQueue.empty() is true
594 size_t index;
595 if ((index = getEmptyBufferID(oBuffer)) < oBuffer->size()) {
596 dispatchOutputBuffer(omxNode, oBuffer, index);
597 }
598 timeOut--;
599 }
600 }
601
602 // Decode N Frames
decodeNFrames(sp<IOmxNode> omxNode,sp<CodecObserver> observer,android::Vector<BufferInfo> * iBuffer,android::Vector<BufferInfo> * oBuffer,OMX_AUDIO_CODINGTYPE eEncoding,OMX_U32 kPortIndexInput,OMX_U32 kPortIndexOutput,std::ifstream & eleStream,android::Vector<FrameData> * Info,int offset,int range,AudioDecHidlTest::standardComp comp,bool signalEOS=true)603 void decodeNFrames(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
604 android::Vector<BufferInfo>* iBuffer,
605 android::Vector<BufferInfo>* oBuffer,
606 OMX_AUDIO_CODINGTYPE eEncoding, OMX_U32 kPortIndexInput,
607 OMX_U32 kPortIndexOutput, std::ifstream& eleStream,
608 android::Vector<FrameData>* Info, int offset, int range,
609 AudioDecHidlTest::standardComp comp, bool signalEOS = true) {
610 android::hardware::media::omx::V1_0::Status status;
611 Message msg;
612
613 // dispatch output buffers
614 for (size_t i = 0; i < oBuffer->size(); i++) {
615 dispatchOutputBuffer(omxNode, oBuffer, i);
616 }
617 // dispatch input buffers
618 uint32_t flags = 0;
619 int frameID = offset;
620 for (size_t i = 0; (i < iBuffer->size()) && (frameID < (int)Info->size()) &&
621 (frameID < (offset + range));
622 i++) {
623 char* ipBuffer = static_cast<char*>(
624 static_cast<void*>((*iBuffer)[i].mMemory->getPointer()));
625 ASSERT_LE((*Info)[frameID].bytesCount,
626 static_cast<int>((*iBuffer)[i].mMemory->getSize()));
627 eleStream.read(ipBuffer, (*Info)[frameID].bytesCount);
628 ASSERT_EQ(eleStream.gcount(), (*Info)[frameID].bytesCount);
629 flags = (*Info)[frameID].flags;
630 if (signalEOS && ((frameID == (int)Info->size() - 1) ||
631 (frameID == (offset + range - 1))))
632 flags |= OMX_BUFFERFLAG_EOS;
633 dispatchInputBuffer(omxNode, iBuffer, i, (*Info)[frameID].bytesCount,
634 flags, (*Info)[frameID].timestamp);
635 frameID++;
636 }
637
638 int timeOut = TIMEOUT_COUNTER;
639 bool stall = false;
640 while (1) {
641 status =
642 observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
643
644 // Port Reconfiguration
645 if (status == android::hardware::media::omx::V1_0::Status::OK &&
646 msg.type == Message::Type::EVENT) {
647 portReconfiguration(omxNode, observer, iBuffer, oBuffer, eEncoding,
648 kPortIndexInput, kPortIndexOutput, msg, comp);
649 }
650
651 if (frameID == (int)Info->size() || frameID == (offset + range)) break;
652
653 // Dispatch input buffer
654 size_t index = 0;
655 if ((index = getEmptyBufferID(iBuffer)) < iBuffer->size()) {
656 char* ipBuffer = static_cast<char*>(
657 static_cast<void*>((*iBuffer)[index].mMemory->getPointer()));
658 ASSERT_LE((*Info)[frameID].bytesCount,
659 static_cast<int>((*iBuffer)[index].mMemory->getSize()));
660 eleStream.read(ipBuffer, (*Info)[frameID].bytesCount);
661 ASSERT_EQ(eleStream.gcount(), (*Info)[frameID].bytesCount);
662 flags = (*Info)[frameID].flags;
663 if (signalEOS && ((frameID == (int)Info->size() - 1) ||
664 (frameID == (offset + range - 1))))
665 flags |= OMX_BUFFERFLAG_EOS;
666 dispatchInputBuffer(omxNode, iBuffer, index,
667 (*Info)[frameID].bytesCount, flags,
668 (*Info)[frameID].timestamp);
669 frameID++;
670 stall = false;
671 } else
672 stall = true;
673 if ((index = getEmptyBufferID(oBuffer)) < oBuffer->size()) {
674 dispatchOutputBuffer(omxNode, oBuffer, index);
675 stall = false;
676 } else
677 stall = true;
678 if (stall)
679 timeOut--;
680 else
681 timeOut = TIMEOUT_COUNTER;
682 if (timeOut == 0) {
683 EXPECT_TRUE(false) << "Wait on Input/Output is found indefinite";
684 break;
685 }
686 }
687 }
688
689 // set component role
TEST_F(AudioDecHidlTest,SetRole)690 TEST_F(AudioDecHidlTest, SetRole) {
691 description("Test Set Component Role");
692 if (disableTest) return;
693 android::hardware::media::omx::V1_0::Status status;
694 status = setRole(omxNode, gEnv->getRole().c_str());
695 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
696 }
697
698 // port format enumeration
TEST_F(AudioDecHidlTest,DISABLED_EnumeratePortFormat)699 TEST_F(AudioDecHidlTest, DISABLED_EnumeratePortFormat) {
700 description("Test Component on Mandatory Port Parameters (Port Format)");
701 if (disableTest) return;
702 android::hardware::media::omx::V1_0::Status status;
703 uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
704 status = setRole(omxNode, gEnv->getRole().c_str());
705 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
706 OMX_PORT_PARAM_TYPE params;
707 status = getParam(omxNode, OMX_IndexParamAudioInit, ¶ms);
708 if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
709 ASSERT_EQ(params.nPorts, 2U);
710 kPortIndexInput = params.nStartPortNumber;
711 kPortIndexOutput = kPortIndexInput + 1;
712 }
713 status = setAudioPortFormat(omxNode, kPortIndexInput, eEncoding);
714 EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
715 status = setAudioPortFormat(omxNode, kPortIndexOutput, OMX_AUDIO_CodingPCM);
716 EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
717 }
718
719 // test port settings reconfiguration, elementary stream decode and timestamp
720 // deviation
TEST_F(AudioDecHidlTest,DecodeTest)721 TEST_F(AudioDecHidlTest, DecodeTest) {
722 description("Tests Port Reconfiguration, Decode and timestamp deviation");
723 if (disableTest) return;
724 android::hardware::media::omx::V1_0::Status status;
725 uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
726 status = setRole(omxNode, gEnv->getRole().c_str());
727 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
728 OMX_PORT_PARAM_TYPE params;
729 status = getParam(omxNode, OMX_IndexParamAudioInit, ¶ms);
730 if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
731 ASSERT_EQ(params.nPorts, 2U);
732 kPortIndexInput = params.nStartPortNumber;
733 kPortIndexOutput = kPortIndexInput + 1;
734 }
735 char mURL[512], info[512];
736 strcpy(mURL, gEnv->getRes().c_str());
737 strcpy(info, gEnv->getRes().c_str());
738 GetURLForComponent(compName, mURL, info);
739
740 std::ifstream eleStream, eleInfo;
741
742 eleInfo.open(info);
743 ASSERT_EQ(eleInfo.is_open(), true);
744 android::Vector<FrameData> Info;
745 int bytesCount = 0;
746 uint32_t flags = 0;
747 uint32_t timestamp = 0;
748 timestampDevTest = true;
749 while (1) {
750 if (!(eleInfo >> bytesCount)) break;
751 eleInfo >> flags;
752 eleInfo >> timestamp;
753 Info.push_back({bytesCount, flags, timestamp});
754 if (flags != OMX_BUFFERFLAG_CODECCONFIG)
755 timestampUslist.push_back(timestamp);
756 }
757 eleInfo.close();
758
759 int32_t nChannels, nSampleRate;
760 // Configure input port
761 setDefaultPortParam(omxNode, kPortIndexInput, eEncoding);
762 if (compName == raw)
763 setDefaultPortParam(omxNode, kPortIndexInput, eEncoding, 1, 8000,
764 OMX_AUDIO_PCMModeLinear, OMX_NumericalDataSigned,
765 32);
766 getInputChannelInfo(omxNode, kPortIndexInput, eEncoding, &nChannels,
767 &nSampleRate);
768 // Configure output port
769 // SPECIAL CASE: Soft Vorbis, Opus and Raw Decoders do not offer way to
770 // configure output PCM port. The port undergoes auto configuration
771 // internally basing on parsed elementary stream information.
772 if (compName != vorbis && compName != opus && compName != raw) {
773 setDefaultPortParam(omxNode, kPortIndexOutput, OMX_AUDIO_CodingPCM,
774 nChannels, nSampleRate);
775 }
776
777 android::Vector<BufferInfo> iBuffer, oBuffer;
778
779 // set state to idle
780 changeStateLoadedtoIdle(omxNode, observer, &iBuffer, &oBuffer,
781 kPortIndexInput, kPortIndexOutput);
782 // set state to executing
783 changeStateIdletoExecute(omxNode, observer);
784 // Port Reconfiguration
785 eleStream.open(mURL, std::ifstream::binary);
786 ASSERT_EQ(eleStream.is_open(), true);
787 decodeNFrames(omxNode, observer, &iBuffer, &oBuffer, eEncoding,
788 kPortIndexInput, kPortIndexOutput, eleStream, &Info, 0,
789 (int)Info.size(), compName);
790 eleStream.close();
791 waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer, eEncoding,
792 kPortIndexInput, kPortIndexOutput);
793 testEOS(omxNode, observer, &iBuffer, &oBuffer, false, eosFlag);
794 EXPECT_EQ(timestampUslist.empty(), true);
795 // set state to idle
796 changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer);
797 // set state to executing
798 changeStateIdletoLoaded(omxNode, observer, &iBuffer, &oBuffer,
799 kPortIndexInput, kPortIndexOutput);
800 }
801
802 // end of sequence test
803 // SPECIAL CASE; Sending Empty input EOS buffer is not supported across all
804 // components. For instance soft vorbis and soft opus expects CSD buffers at
805 // the start. Disabling this test for now. We shall revisit this at a later
806 // stage
TEST_F(AudioDecHidlTest,DISABLED_EOSTest_M)807 TEST_F(AudioDecHidlTest, DISABLED_EOSTest_M) {
808 description("Test end of stream monkeying");
809 if (disableTest) return;
810 android::hardware::media::omx::V1_0::Status status;
811 uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
812 status = setRole(omxNode, gEnv->getRole().c_str());
813 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
814 OMX_PORT_PARAM_TYPE params;
815 status = getParam(omxNode, OMX_IndexParamAudioInit, ¶ms);
816 if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
817 ASSERT_EQ(params.nPorts, 2U);
818 kPortIndexInput = params.nStartPortNumber;
819 kPortIndexOutput = kPortIndexInput + 1;
820 }
821
822 int32_t nChannels, nSampleRate;
823 // Configure input port
824 setDefaultPortParam(omxNode, kPortIndexInput, eEncoding);
825 if (compName == raw)
826 setDefaultPortParam(omxNode, kPortIndexInput, eEncoding, 1, 8000,
827 OMX_AUDIO_PCMModeLinear, OMX_NumericalDataSigned,
828 32);
829 getInputChannelInfo(omxNode, kPortIndexInput, eEncoding, &nChannels,
830 &nSampleRate);
831 // Configure output port
832 // SPECIAL CASE: Soft Vorbis, Opus and Raw Decoders do not offer way to
833 // configure output PCM port. The port undergoes auto configuration
834 // internally basing on parsed elementary stream information.
835 if (compName != vorbis && compName != opus && compName != raw) {
836 setDefaultPortParam(omxNode, kPortIndexOutput, OMX_AUDIO_CodingPCM,
837 nChannels, nSampleRate);
838 }
839
840 android::Vector<BufferInfo> iBuffer, oBuffer;
841
842 // set state to idle
843 changeStateLoadedtoIdle(omxNode, observer, &iBuffer, &oBuffer,
844 kPortIndexInput, kPortIndexOutput);
845 // set state to executing
846 changeStateIdletoExecute(omxNode, observer);
847
848 // request EOS at the start
849 testEOS(omxNode, observer, &iBuffer, &oBuffer, true, eosFlag);
850 flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
851 kPortIndexOutput);
852 EXPECT_GE(framesReceived, 0U);
853 framesReceived = 0;
854 timestampUs = 0;
855
856 // set state to idle
857 changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer);
858 // set state to executing
859 changeStateIdletoLoaded(omxNode, observer, &iBuffer, &oBuffer,
860 kPortIndexInput, kPortIndexOutput);
861 }
862
863 // end of sequence test
TEST_F(AudioDecHidlTest,ThumbnailTest)864 TEST_F(AudioDecHidlTest, ThumbnailTest) {
865 description("Test Request for thumbnail");
866 if (disableTest) return;
867 android::hardware::media::omx::V1_0::Status status;
868 uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
869 status = setRole(omxNode, gEnv->getRole().c_str());
870 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
871 OMX_PORT_PARAM_TYPE params;
872 status = getParam(omxNode, OMX_IndexParamAudioInit, ¶ms);
873 if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
874 ASSERT_EQ(params.nPorts, 2U);
875 kPortIndexInput = params.nStartPortNumber;
876 kPortIndexOutput = kPortIndexInput + 1;
877 }
878 char mURL[512], info[512];
879 strcpy(mURL, gEnv->getRes().c_str());
880 strcpy(info, gEnv->getRes().c_str());
881 GetURLForComponent(compName, mURL, info);
882
883 std::ifstream eleStream, eleInfo;
884
885 eleInfo.open(info);
886 ASSERT_EQ(eleInfo.is_open(), true);
887 android::Vector<FrameData> Info;
888 int bytesCount = 0;
889 uint32_t flags = 0;
890 uint32_t timestamp = 0;
891 while (1) {
892 if (!(eleInfo >> bytesCount)) break;
893 eleInfo >> flags;
894 eleInfo >> timestamp;
895 Info.push_back({bytesCount, flags, timestamp});
896 }
897 eleInfo.close();
898
899 int32_t nChannels, nSampleRate;
900 // Configure input port
901 setDefaultPortParam(omxNode, kPortIndexInput, eEncoding);
902 if (compName == raw)
903 setDefaultPortParam(omxNode, kPortIndexInput, eEncoding, 1, 8000,
904 OMX_AUDIO_PCMModeLinear, OMX_NumericalDataSigned,
905 32);
906 getInputChannelInfo(omxNode, kPortIndexInput, eEncoding, &nChannels,
907 &nSampleRate);
908 // Configure output port
909 // SPECIAL CASE: Soft Vorbis, Opus and Raw Decoders do not offer way to
910 // configure output PCM port. The port undergoes auto configuration
911 // internally basing on parsed elementary stream information.
912 if (compName != vorbis && compName != opus && compName != raw) {
913 setDefaultPortParam(omxNode, kPortIndexOutput, OMX_AUDIO_CodingPCM,
914 nChannels, nSampleRate);
915 }
916
917 android::Vector<BufferInfo> iBuffer, oBuffer;
918
919 // set state to idle
920 changeStateLoadedtoIdle(omxNode, observer, &iBuffer, &oBuffer,
921 kPortIndexInput, kPortIndexOutput);
922 // set state to executing
923 changeStateIdletoExecute(omxNode, observer);
924
925 // request EOS for thumbnail
926 // signal EOS flag with last frame
927 size_t i = 0;
928 while (!(Info[i].flags & OMX_BUFFERFLAG_SYNCFRAME)) i++;
929 eleStream.open(mURL, std::ifstream::binary);
930 ASSERT_EQ(eleStream.is_open(), true);
931 decodeNFrames(omxNode, observer, &iBuffer, &oBuffer, eEncoding,
932 kPortIndexInput, kPortIndexOutput, eleStream, &Info, 0, i + 1,
933 compName);
934 eleStream.close();
935 waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer, eEncoding,
936 kPortIndexInput, kPortIndexOutput);
937 testEOS(omxNode, observer, &iBuffer, &oBuffer, false, eosFlag);
938 flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
939 kPortIndexOutput);
940 EXPECT_GE(framesReceived, 1U);
941 framesReceived = 0;
942 timestampUs = 0;
943
944 // signal EOS flag after last frame
945 eleStream.open(mURL, std::ifstream::binary);
946 ASSERT_EQ(eleStream.is_open(), true);
947 decodeNFrames(omxNode, observer, &iBuffer, &oBuffer, eEncoding,
948 kPortIndexInput, kPortIndexOutput, eleStream, &Info, 0, i + 1,
949 compName, false);
950 eleStream.close();
951 waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer, eEncoding,
952 kPortIndexInput, kPortIndexOutput);
953 testEOS(omxNode, observer, &iBuffer, &oBuffer, true, eosFlag);
954 flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
955 kPortIndexOutput);
956 EXPECT_GE(framesReceived, 1U);
957 framesReceived = 0;
958 timestampUs = 0;
959
960 // set state to idle
961 changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer);
962 // set state to executing
963 changeStateIdletoLoaded(omxNode, observer, &iBuffer, &oBuffer,
964 kPortIndexInput, kPortIndexOutput);
965 }
966
967 // end of sequence test
TEST_F(AudioDecHidlTest,SimpleEOSTest)968 TEST_F(AudioDecHidlTest, SimpleEOSTest) {
969 description("Test end of stream");
970 if (disableTest) return;
971 android::hardware::media::omx::V1_0::Status status;
972 uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
973 status = setRole(omxNode, gEnv->getRole().c_str());
974 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
975 OMX_PORT_PARAM_TYPE params;
976 status = getParam(omxNode, OMX_IndexParamAudioInit, ¶ms);
977 if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
978 ASSERT_EQ(params.nPorts, 2U);
979 kPortIndexInput = params.nStartPortNumber;
980 kPortIndexOutput = kPortIndexInput + 1;
981 }
982 char mURL[512], info[512];
983 strcpy(mURL, gEnv->getRes().c_str());
984 strcpy(info, gEnv->getRes().c_str());
985 GetURLForComponent(compName, mURL, info);
986
987 std::ifstream eleStream, eleInfo;
988
989 eleInfo.open(info);
990 ASSERT_EQ(eleInfo.is_open(), true);
991 android::Vector<FrameData> Info;
992 int bytesCount = 0;
993 uint32_t flags = 0;
994 uint32_t timestamp = 0;
995 while (1) {
996 if (!(eleInfo >> bytesCount)) break;
997 eleInfo >> flags;
998 eleInfo >> timestamp;
999 Info.push_back({bytesCount, flags, timestamp});
1000 }
1001 eleInfo.close();
1002
1003 int32_t nChannels, nSampleRate;
1004 // Configure input port
1005 setDefaultPortParam(omxNode, kPortIndexInput, eEncoding);
1006 if (compName == raw)
1007 setDefaultPortParam(omxNode, kPortIndexInput, eEncoding, 1, 8000,
1008 OMX_AUDIO_PCMModeLinear, OMX_NumericalDataSigned,
1009 32);
1010 getInputChannelInfo(omxNode, kPortIndexInput, eEncoding, &nChannels,
1011 &nSampleRate);
1012 // Configure output port
1013 // SPECIAL CASE: Soft Vorbis, Opus and Raw Decoders do not offer way to
1014 // configure output PCM port. The port undergoes auto configuration
1015 // internally basing on parsed elementary stream information.
1016 if (compName != vorbis && compName != opus && compName != raw) {
1017 setDefaultPortParam(omxNode, kPortIndexOutput, OMX_AUDIO_CodingPCM,
1018 nChannels, nSampleRate);
1019 }
1020
1021 android::Vector<BufferInfo> iBuffer, oBuffer;
1022
1023 // set state to idle
1024 changeStateLoadedtoIdle(omxNode, observer, &iBuffer, &oBuffer,
1025 kPortIndexInput, kPortIndexOutput);
1026 // set state to executing
1027 changeStateIdletoExecute(omxNode, observer);
1028
1029 // request EOS at the end
1030 eleStream.open(mURL, std::ifstream::binary);
1031 ASSERT_EQ(eleStream.is_open(), true);
1032 decodeNFrames(omxNode, observer, &iBuffer, &oBuffer, eEncoding,
1033 kPortIndexInput, kPortIndexOutput, eleStream, &Info, 0,
1034 (int)Info.size(), compName, false);
1035 eleStream.close();
1036 waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer, eEncoding,
1037 kPortIndexInput, kPortIndexOutput);
1038 testEOS(omxNode, observer, &iBuffer, &oBuffer, true, eosFlag);
1039 flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
1040 kPortIndexOutput);
1041 framesReceived = 0;
1042 timestampUs = 0;
1043
1044 // set state to idle
1045 changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer);
1046 // set state to executing
1047 changeStateIdletoLoaded(omxNode, observer, &iBuffer, &oBuffer,
1048 kPortIndexInput, kPortIndexOutput);
1049 }
1050
1051 // test input/output port flush
TEST_F(AudioDecHidlTest,FlushTest)1052 TEST_F(AudioDecHidlTest, FlushTest) {
1053 description("Test Flush");
1054 if (disableTest) return;
1055 android::hardware::media::omx::V1_0::Status status;
1056 uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
1057 status = setRole(omxNode, gEnv->getRole().c_str());
1058 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1059 OMX_PORT_PARAM_TYPE params;
1060 status = getParam(omxNode, OMX_IndexParamAudioInit, ¶ms);
1061 if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
1062 ASSERT_EQ(params.nPorts, 2U);
1063 kPortIndexInput = params.nStartPortNumber;
1064 kPortIndexOutput = kPortIndexInput + 1;
1065 }
1066 char mURL[512], info[512];
1067 strcpy(mURL, gEnv->getRes().c_str());
1068 strcpy(info, gEnv->getRes().c_str());
1069 GetURLForComponent(compName, mURL, info);
1070
1071 std::ifstream eleStream, eleInfo;
1072
1073 eleInfo.open(info);
1074 ASSERT_EQ(eleInfo.is_open(), true);
1075 android::Vector<FrameData> Info;
1076 int bytesCount = 0;
1077 uint32_t flags = 0;
1078 uint32_t timestamp = 0;
1079 while (1) {
1080 if (!(eleInfo >> bytesCount)) break;
1081 eleInfo >> flags;
1082 eleInfo >> timestamp;
1083 Info.push_back({bytesCount, flags, timestamp});
1084 }
1085 eleInfo.close();
1086
1087 int32_t nChannels, nSampleRate;
1088 // Configure input port
1089 setDefaultPortParam(omxNode, kPortIndexInput, eEncoding);
1090 if (compName == raw)
1091 setDefaultPortParam(omxNode, kPortIndexInput, eEncoding, 1, 8000,
1092 OMX_AUDIO_PCMModeLinear, OMX_NumericalDataSigned,
1093 32);
1094 getInputChannelInfo(omxNode, kPortIndexInput, eEncoding, &nChannels,
1095 &nSampleRate);
1096 // Configure output port
1097 // SPECIAL CASE: Soft Vorbis, Opus and Raw Decoders do not offer way to
1098 // configure output PCM port. The port undergoes auto configuration
1099 // internally basing on parsed elementary stream information.
1100 if (compName != vorbis && compName != opus && compName != raw) {
1101 setDefaultPortParam(omxNode, kPortIndexOutput, OMX_AUDIO_CodingPCM,
1102 nChannels, nSampleRate);
1103 }
1104
1105 android::Vector<BufferInfo> iBuffer, oBuffer;
1106
1107 // set state to idle
1108 changeStateLoadedtoIdle(omxNode, observer, &iBuffer, &oBuffer,
1109 kPortIndexInput, kPortIndexOutput);
1110 // set state to executing
1111 changeStateIdletoExecute(omxNode, observer);
1112
1113 // Decode 128 frames and flush. here 128 is chosen to ensure there is a key
1114 // frame after this so that the below section can be convered for all
1115 // components
1116 int nFrames = 128;
1117 eleStream.open(mURL, std::ifstream::binary);
1118 ASSERT_EQ(eleStream.is_open(), true);
1119 decodeNFrames(omxNode, observer, &iBuffer, &oBuffer, eEncoding,
1120 kPortIndexInput, kPortIndexOutput, eleStream, &Info, 0,
1121 nFrames, compName, false);
1122 // Note: Assumes 200 ms is enough to end any decode call that started
1123 flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
1124 kPortIndexOutput, 200000);
1125 framesReceived = 0;
1126
1127 // Seek to next key frame and start decoding till the end
1128 int index = nFrames;
1129 bool keyFrame = false;
1130 while (index < (int)Info.size()) {
1131 if ((Info[index].flags & OMX_BUFFERFLAG_SYNCFRAME) ==
1132 OMX_BUFFERFLAG_SYNCFRAME) {
1133 timestampUs = Info[index - 1].timestamp;
1134 keyFrame = true;
1135 break;
1136 }
1137 eleStream.ignore(Info[index].bytesCount);
1138 index++;
1139 }
1140 if (keyFrame) {
1141 decodeNFrames(omxNode, observer, &iBuffer, &oBuffer, eEncoding,
1142 kPortIndexInput, kPortIndexOutput, eleStream, &Info,
1143 index, Info.size() - index, compName, false);
1144 }
1145 // Note: Assumes 200 ms is enough to end any decode call that started
1146 flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
1147 kPortIndexOutput, 200000);
1148 framesReceived = 0;
1149
1150 // set state to idle
1151 changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer);
1152 // set state to executing
1153 changeStateIdletoLoaded(omxNode, observer, &iBuffer, &oBuffer,
1154 kPortIndexInput, kPortIndexOutput);
1155 }
1156
main(int argc,char ** argv)1157 int main(int argc, char** argv) {
1158 gEnv = new ComponentTestEnvironment();
1159 ::testing::AddGlobalTestEnvironment(gEnv);
1160 ::testing::InitGoogleTest(&argc, argv);
1161 int status = gEnv->initFromOptions(argc, argv);
1162 if (status == 0) {
1163 status = RUN_ALL_TESTS();
1164 ALOGI("Test result = %d", status);
1165 }
1166 return status;
1167 }
1168