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