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