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 #ifdef __LP64__ 19 #define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS 20 #endif 21 22 #include <android-base/logging.h> 23 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> 31 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; 46 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> 52 53 static ComponentTestEnvironment* gEnv = nullptr; 54 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 } 67 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 } 156 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 } 168 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 } 226 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 }; 242 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; 254 255 protected: 256 static void description(const std::string& description) { 257 RecordProperty("description", description); 258 } 259 }; 260 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; 269 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); 274 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); 280 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 } 294 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; 305 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 } 388 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 }; 428 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 } 437 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; 454 455 if (msg.data.eventData.event == OMX_EventPortSettingsChanged) { 456 ASSERT_EQ(msg.data.eventData.data1, kPortIndexOutput); 457 458 status = omxNode->sendCommand(toRawCommandType(OMX_CommandPortDisable), 459 kPortIndexOutput); 460 ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK); 461 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); 481 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 } 499 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); 505 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); 511 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); 520 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 } 533 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; 544 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; 564 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 } 574 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; 590 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 } 604 605 if (frameID == (int)Info->size() || frameID == (offset + range)) break; 606 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 } 646 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 } 655 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 } 676 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); 697 698 std::ifstream eleStream, eleInfo; 699 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(); 716 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 } 734 735 android::Vector<BufferInfo> iBuffer, oBuffer; 736 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 } 766 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 } 782 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 } 800 801 android::Vector<BufferInfo> iBuffer, oBuffer; 802 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)); 809 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; 820 821 // set state to idle 822 ASSERT_NO_FATAL_FAILURE( 823 changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer)); 824 825 // set state to executing 826 ASSERT_NO_FATAL_FAILURE(changeStateIdletoLoaded(omxNode, observer, &iBuffer, 827 &oBuffer, kPortIndexInput, 828 kPortIndexOutput)); 829 } 830 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); 850 851 std::ifstream eleStream, eleInfo; 852 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(); 866 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 } 884 885 android::Vector<BufferInfo> iBuffer, oBuffer; 886 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)); 893 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; 916 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; 935 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 } 944 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); 964 965 std::ifstream eleStream, eleInfo; 966 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(); 980 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 } 998 999 android::Vector<BufferInfo> iBuffer, oBuffer; 1000 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)); 1007 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; 1027 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 } 1036 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); 1056 1057 std::ifstream eleStream, eleInfo; 1058 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(); 1072 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 } 1090 1091 android::Vector<BufferInfo> iBuffer, oBuffer; 1092 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)); 1099 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; 1112 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; 1135 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 } 1144 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 } 1157