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_component_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_hidl_test_common.h> 50 51 // A class for test environment setup 52 class ComponentTestEnvironment : public ::testing::Environment { 53 public: 54 virtual void SetUp() {} 55 virtual void TearDown() {} 56 57 ComponentTestEnvironment() : instance("default") {} 58 59 void setInstance(const char* _instance) { instance = _instance; } 60 61 void setComponent(const char* _component) { component = _component; } 62 63 void setRole(const char* _role) { role = _role; } 64 65 const hidl_string getInstance() const { return instance; } 66 67 const hidl_string getComponent() const { return component; } 68 69 const hidl_string getRole() const { return role; } 70 71 int initFromOptions(int argc, char** argv) { 72 static struct option options[] = { 73 {"instance", required_argument, 0, 'I'}, 74 {"component", required_argument, 0, 'C'}, 75 {"role", required_argument, 0, 'R'}, 76 {0, 0, 0, 0}}; 77 78 while (true) { 79 int index = 0; 80 int c = getopt_long(argc, argv, "I:C:R:", options, &index); 81 if (c == -1) { 82 break; 83 } 84 85 switch (c) { 86 case 'I': 87 setInstance(optarg); 88 break; 89 case 'C': 90 setComponent(optarg); 91 break; 92 case 'R': 93 setRole(optarg); 94 break; 95 case '?': 96 break; 97 } 98 } 99 100 if (optind < argc) { 101 fprintf(stderr, 102 "unrecognized option: %s\n\n" 103 "usage: %s <gtest options> <test options>\n\n" 104 "test options are:\n\n" 105 "-I, --instance: HAL instance to test\n" 106 "-C, --component: OMX component to test\n" 107 "-R, --Role: OMX component Role\n", 108 argv[optind ?: 1], argv[0]); 109 return 2; 110 } 111 return 0; 112 } 113 114 private: 115 hidl_string instance; 116 hidl_string component; 117 hidl_string role; 118 }; 119 120 static ComponentTestEnvironment* gEnv = nullptr; 121 122 // generic component test fixture class 123 class ComponentHidlTest : public ::testing::VtsHalHidlTargetTestBase { 124 private: 125 typedef ::testing::VtsHalHidlTargetTestBase Super; 126 public: 127 ::std::string getTestCaseInfo() const override { 128 return ::std::string() + 129 "Component: " + gEnv->getComponent().c_str() + " | " + 130 "Role: " + gEnv->getRole().c_str() + " | " + 131 "Instance: " + gEnv->getInstance().c_str(); 132 } 133 134 virtual void SetUp() override { 135 Super::SetUp(); 136 disableTest = false; 137 android::hardware::media::omx::V1_0::Status status; 138 omx = Super::getService<IOmx>(gEnv->getInstance()); 139 ASSERT_NE(omx, nullptr); 140 observer = new CodecObserver(nullptr); 141 ASSERT_NE(observer, nullptr); 142 if (strncmp(gEnv->getComponent().c_str(), "OMX.", 4) != 0) 143 disableTest = true; 144 EXPECT_TRUE(omx->allocateNode( 145 gEnv->getComponent(), observer, 146 [&](android::hardware::media::omx::V1_0::Status _s, 147 sp<IOmxNode> const& _nl) { 148 status = _s; 149 this->omxNode = _nl; 150 }) 151 .isOk()); 152 ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK); 153 ASSERT_NE(omxNode, nullptr); 154 ASSERT_NE(gEnv->getRole().empty(), true) << "Invalid Component Role"; 155 struct StringToClass { 156 const char* Class; 157 standardCompClass CompClass; 158 }; 159 const StringToClass kStringToClass[] = { 160 {"audio_decoder", audio_decoder}, 161 {"audio_encoder", audio_encoder}, 162 {"video_decoder", video_decoder}, 163 {"video_encoder", video_encoder}, 164 }; 165 const size_t kNumStringToClass = 166 sizeof(kStringToClass) / sizeof(kStringToClass[0]); 167 const char* pch; 168 char substring[OMX_MAX_STRINGNAME_SIZE]; 169 strcpy(substring, gEnv->getRole().c_str()); 170 pch = strchr(substring, '.'); 171 ASSERT_NE(pch, nullptr) << "Invalid Component Role"; 172 substring[pch - substring] = '\0'; 173 compClass = unknown_class; 174 for (size_t i = 0; i < kNumStringToClass; ++i) { 175 if (!strcasecmp(substring, kStringToClass[i].Class)) { 176 compClass = kStringToClass[i].CompClass; 177 break; 178 } 179 } 180 if (compClass == unknown_class) disableTest = true; 181 isSecure = false; 182 size_t suffixLen = strlen(".secure"); 183 if (strlen(gEnv->getComponent().c_str()) >= suffixLen) { 184 isSecure = 185 !strcmp(gEnv->getComponent().c_str() + 186 strlen(gEnv->getComponent().c_str()) - suffixLen, 187 ".secure"); 188 } 189 if (disableTest) std::cout << "[ WARN ] Test Disabled \n"; 190 } 191 192 virtual void TearDown() override { 193 if (omxNode != nullptr) { 194 // If you have encountered a fatal failure, it is possible that 195 // freeNode() will not go through. Instead of hanging the app. 196 // let it pass through and report errors 197 if (::testing::Test::HasFatalFailure()) return; 198 EXPECT_TRUE((omxNode->freeNode()).isOk()); 199 omxNode = nullptr; 200 } 201 Super::TearDown(); 202 } 203 204 enum standardCompClass { 205 audio_decoder, 206 audio_encoder, 207 video_decoder, 208 video_encoder, 209 unknown_class, 210 }; 211 212 sp<IOmx> omx; 213 sp<CodecObserver> observer; 214 sp<IOmxNode> omxNode; 215 standardCompClass compClass; 216 bool isSecure; 217 bool disableTest; 218 219 protected: 220 static void description(const std::string& description) { 221 RecordProperty("description", description); 222 } 223 }; 224 225 void initPortMode(PortMode* pm, bool isSecure, 226 ComponentHidlTest::standardCompClass compClass) { 227 pm[0] = PortMode::PRESET_BYTE_BUFFER; 228 pm[1] = PortMode::PRESET_BYTE_BUFFER; 229 if (isSecure) { 230 switch (compClass) { 231 case ComponentHidlTest::video_decoder: 232 pm[0] = PortMode::PRESET_SECURE_BUFFER; 233 break; 234 case ComponentHidlTest::video_encoder: 235 pm[1] = PortMode::PRESET_SECURE_BUFFER; 236 break; 237 default: 238 break; 239 } 240 } 241 } 242 243 // test dispatch message API call 244 TEST_F(ComponentHidlTest, dispatchMsg) { 245 description("test dispatch message API call"); 246 if (disableTest) return; 247 android::hardware::media::omx::V1_0::Status status; 248 Message msgin, msgout; 249 250 msgin.type = Message::Type::EVENT; 251 msgin.data.eventData.event = OMX_EventError; 252 msgin.data.eventData.data1 = 0xdeaf; 253 msgin.data.eventData.data2 = 0xd00d; 254 msgin.data.eventData.data3 = 0x01ce; 255 msgin.data.eventData.data4 = 0xfa11; 256 status = omxNode->dispatchMessage(msgin); 257 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK); 258 status = observer->dequeueMessage(&msgout, DEFAULT_TIMEOUT); 259 EXPECT_EQ(status, android::hardware::media::omx::V1_0::Status::OK); 260 EXPECT_EQ(msgout.type, msgin.type); 261 EXPECT_EQ(msgout.data.eventData.event, msgin.data.eventData.event); 262 EXPECT_EQ(msgout.data.eventData.data1, msgin.data.eventData.data1); 263 EXPECT_EQ(msgout.data.eventData.data2, msgin.data.eventData.data2); 264 EXPECT_EQ(msgout.data.eventData.data3, msgin.data.eventData.data3); 265 EXPECT_EQ(msgout.data.eventData.data4, msgin.data.eventData.data4); 266 } 267 268 // set component role 269 TEST_F(ComponentHidlTest, SetRole) { 270 description("Test Set Component Role"); 271 if (disableTest) return; 272 android::hardware::media::omx::V1_0::Status status; 273 status = setRole(omxNode, gEnv->getRole().c_str()); 274 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK); 275 } 276 277 // port indices enumeration 278 TEST_F(ComponentHidlTest, DISABLED_GetPortIndices) { 279 description("Test Component on Mandatory Port Parameters (Port Indices)"); 280 if (disableTest) return; 281 android::hardware::media::omx::V1_0::Status status; 282 OMX_PORT_PARAM_TYPE params; 283 284 status = setRole(omxNode, gEnv->getRole().c_str()); 285 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK); 286 287 // Get Number of Ports and their Indices for all Domains 288 // (Audio/Video/Image/Other) 289 // All standard OMX components shall support following OMX Index types 290 status = getParam(omxNode, OMX_IndexParamAudioInit, ¶ms); 291 EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK); 292 status = getParam(omxNode, OMX_IndexParamVideoInit, ¶ms); 293 EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK); 294 status = getParam(omxNode, OMX_IndexParamImageInit, ¶ms); 295 EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK); 296 status = getParam(omxNode, OMX_IndexParamOtherInit, ¶ms); 297 EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK); 298 } 299 300 // port format enumeration 301 TEST_F(ComponentHidlTest, EnumeratePortFormat) { 302 description("Test Component on Mandatory Port Parameters (Port Format)"); 303 if (disableTest) return; 304 android::hardware::media::omx::V1_0::Status status; 305 uint32_t kPortIndexInput = 0, kPortIndexOutput = 1; 306 307 status = setRole(omxNode, gEnv->getRole().c_str()); 308 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK); 309 OMX_PORT_PARAM_TYPE params; 310 if (compClass == audio_decoder || compClass == audio_encoder) { 311 status = getParam(omxNode, OMX_IndexParamAudioInit, ¶ms); 312 } else { 313 status = getParam(omxNode, OMX_IndexParamVideoInit, ¶ms); 314 } 315 if (status == ::android::hardware::media::omx::V1_0::Status::OK) { 316 ASSERT_EQ(params.nPorts, 2U); 317 kPortIndexInput = params.nStartPortNumber; 318 kPortIndexOutput = kPortIndexInput + 1; 319 } 320 321 OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatYUV420Planar; 322 OMX_U32 xFramerate = 24U << 16; 323 324 // Enumerate Port Format 325 if (compClass == audio_encoder) { 326 status = 327 setAudioPortFormat(omxNode, kPortIndexInput, OMX_AUDIO_CodingPCM); 328 EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK); 329 status = setAudioPortFormat(omxNode, kPortIndexOutput, 330 OMX_AUDIO_CodingAutoDetect); 331 EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK); 332 } else if (compClass == audio_decoder) { 333 status = setAudioPortFormat(omxNode, kPortIndexInput, 334 OMX_AUDIO_CodingAutoDetect); 335 EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK); 336 status = 337 setAudioPortFormat(omxNode, kPortIndexOutput, OMX_AUDIO_CodingPCM); 338 EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK); 339 } else if (compClass == video_encoder) { 340 status = 341 setVideoPortFormat(omxNode, kPortIndexInput, OMX_VIDEO_CodingUnused, 342 eColorFormat, xFramerate); 343 EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK); 344 status = setVideoPortFormat(omxNode, kPortIndexOutput, 345 OMX_VIDEO_CodingAutoDetect, 346 OMX_COLOR_FormatUnused, 0U); 347 EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK); 348 } else { 349 status = setVideoPortFormat(omxNode, kPortIndexInput, 350 OMX_VIDEO_CodingAutoDetect, 351 OMX_COLOR_FormatUnused, 0U); 352 EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK); 353 status = setVideoPortFormat(omxNode, kPortIndexOutput, 354 OMX_VIDEO_CodingUnused, eColorFormat, 355 xFramerate); 356 EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK); 357 } 358 } 359 360 // get/set default port settings of a component 361 TEST_F(ComponentHidlTest, DISABLED_SetDefaultPortParams) { 362 description( 363 "Test Component on Mandatory Port Parameters (Port Definition)"); 364 if (disableTest) return; 365 android::hardware::media::omx::V1_0::Status status; 366 uint32_t kPortIndexInput = 0, kPortIndexOutput = 1; 367 368 status = setRole(omxNode, gEnv->getRole().c_str()); 369 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK); 370 OMX_PORT_PARAM_TYPE params; 371 if (compClass == audio_decoder || compClass == audio_encoder) { 372 status = getParam(omxNode, OMX_IndexParamAudioInit, ¶ms); 373 } else { 374 status = getParam(omxNode, OMX_IndexParamVideoInit, ¶ms); 375 } 376 if (status == ::android::hardware::media::omx::V1_0::Status::OK) { 377 ASSERT_EQ(params.nPorts, 2U); 378 kPortIndexInput = params.nStartPortNumber; 379 kPortIndexOutput = kPortIndexInput + 1; 380 } 381 382 for (size_t i = kPortIndexInput; i <= kPortIndexOutput; i++) { 383 OMX_PARAM_PORTDEFINITIONTYPE portDef; 384 status = 385 getPortParam(omxNode, OMX_IndexParamPortDefinition, i, &portDef); 386 EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK); 387 if (status == android::hardware::media::omx::V1_0::Status::OK) { 388 EXPECT_EQ(portDef.eDir, i - kPortIndexInput); // OMX_DirInput 389 EXPECT_EQ(portDef.bEnabled, OMX_TRUE); 390 EXPECT_EQ(portDef.bPopulated, OMX_FALSE); 391 EXPECT_GE(portDef.nBufferCountMin, 1U); 392 EXPECT_GE(portDef.nBufferCountActual, portDef.nBufferCountMin); 393 if (compClass == audio_encoder || compClass == audio_decoder) { 394 EXPECT_EQ(portDef.eDomain, OMX_PortDomainAudio); 395 } else if (compClass == video_encoder || 396 compClass == video_decoder) { 397 EXPECT_EQ(portDef.eDomain, OMX_PortDomainVideo); 398 } 399 OMX_PARAM_PORTDEFINITIONTYPE mirror = portDef; 400 401 // nBufferCountActual >= nBufferCountMin 402 portDef.nBufferCountActual = portDef.nBufferCountMin - 1; 403 status = setPortParam(omxNode, OMX_IndexParamPortDefinition, i, 404 &portDef); 405 EXPECT_NE(status, 406 ::android::hardware::media::omx::V1_0::Status::OK); 407 408 // Port Direction - Read Only 409 portDef = mirror; 410 portDef.eDir = static_cast<OMX_DIRTYPE>(RANDOM_INDEX); 411 setPortParam(omxNode, OMX_IndexParamPortDefinition, i, &portDef); 412 getPortParam(omxNode, OMX_IndexParamPortDefinition, i, &portDef); 413 if (portDef.eDir != mirror.eDir) { 414 std::cerr << "[ ERROR ] port direction has to be read only " 415 "but is changeable \n"; 416 } 417 EXPECT_EQ(portDef.eDir, mirror.eDir); 418 setPortParam(omxNode, OMX_IndexParamPortDefinition, i, &mirror); 419 420 // Port Min BufferCount - Read Only 421 portDef = mirror; 422 portDef.nBufferCountMin += 1; 423 setPortParam(omxNode, OMX_IndexParamPortDefinition, i, &portDef); 424 getPortParam(omxNode, OMX_IndexParamPortDefinition, i, &portDef); 425 if (portDef.nBufferCountMin != mirror.nBufferCountMin) { 426 std::cerr << "[ ERROR ] port Min BufferCount has to be " 427 "read only but is changeable \n"; 428 } 429 EXPECT_EQ(portDef.nBufferCountMin, mirror.nBufferCountMin); 430 setPortParam(omxNode, OMX_IndexParamPortDefinition, i, &mirror); 431 432 // Port Actual BufferCount 433 portDef = mirror; 434 portDef.nBufferCountActual += 1; 435 status = setPortParam(omxNode, OMX_IndexParamPortDefinition, i, 436 &portDef); 437 if (status == ::android::hardware::media::omx::V1_0::Status::OK) { 438 status = getPortParam(omxNode, OMX_IndexParamPortDefinition, i, 439 &portDef); 440 EXPECT_EQ(portDef.nBufferCountActual, 441 mirror.nBufferCountActual + 1); 442 } 443 setPortParam(omxNode, OMX_IndexParamPortDefinition, i, &mirror); 444 445 // Port BufferSize is although read only as per OMX-IL 1.2, android 446 // doesnt abide by this. 447 // Decrease buffer size 448 portDef = mirror; 449 OMX_U32 nBufferSize = portDef.nBufferSize >> 1; 450 if (nBufferSize != 0) { 451 if (!strncmp(gEnv->getComponent().c_str(), "OMX.google.", 11)) { 452 portDef.nBufferSize = nBufferSize; 453 } else { 454 // Probable alignment requirements of vendor component 455 portDef.nBufferSize = ALIGN_POWER_OF_TWO(nBufferSize, 12); 456 nBufferSize = portDef.nBufferSize; 457 } 458 } else { 459 ASSERT_TRUE(false) << "Unexpected buffer size"; 460 } 461 setPortParam(omxNode, OMX_IndexParamPortDefinition, i, &portDef); 462 getPortParam(omxNode, OMX_IndexParamPortDefinition, i, &portDef); 463 // SPECIAL CASE: For video decoder, allow configuration of input 464 // buffer size even if it is less than minimum requirement and 465 // similarly for encoder allow configuration of output port buffer 466 // size. 467 if ((compClass == video_encoder && i == kPortIndexOutput) || 468 (compClass == video_decoder && i == kPortIndexInput)) { 469 double dev = (portDef.nBufferSize / (double)nBufferSize); 470 dev -= 1; 471 if (dev < 0 || dev > 0.1) { 472 std::cerr << "[ ERROR ] port buffer size deviation " 473 "larger than expected \n"; 474 } 475 } else { 476 EXPECT_EQ(portDef.nBufferSize, mirror.nBufferSize); 477 } 478 setPortParam(omxNode, OMX_IndexParamPortDefinition, i, &mirror); 479 480 // Increase buffer size 481 portDef = mirror; 482 portDef.nBufferSize = mirror.nBufferSize << 1; 483 setPortParam(omxNode, OMX_IndexParamPortDefinition, i, &portDef); 484 getPortParam(omxNode, OMX_IndexParamPortDefinition, i, &portDef); 485 EXPECT_EQ(portDef.nBufferSize, (mirror.nBufferSize << 1)); 486 } 487 } 488 } 489 490 // populate port test 491 TEST_F(ComponentHidlTest, DISABLED_PopulatePort) { 492 description("Verify bPopulated field of a component port"); 493 if (disableTest || isSecure) return; 494 android::hardware::media::omx::V1_0::Status status; 495 OMX_U32 portBase = 0; 496 497 status = setRole(omxNode, gEnv->getRole().c_str()); 498 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK); 499 OMX_PORT_PARAM_TYPE params; 500 if (compClass == audio_decoder || compClass == audio_encoder) { 501 status = getParam(omxNode, OMX_IndexParamAudioInit, ¶ms); 502 } else { 503 status = getParam(omxNode, OMX_IndexParamVideoInit, ¶ms); 504 } 505 if (status == ::android::hardware::media::omx::V1_0::Status::OK) { 506 ASSERT_EQ(params.nPorts, 2U); 507 portBase = params.nStartPortNumber; 508 } 509 510 // set state to idle 511 status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet), 512 OMX_StateIdle); 513 ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK); 514 515 OMX_PARAM_PORTDEFINITIONTYPE portDef; 516 status = 517 getPortParam(omxNode, OMX_IndexParamPortDefinition, portBase, &portDef); 518 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK); 519 ASSERT_EQ(portDef.bPopulated, OMX_FALSE); 520 521 android::Vector<BufferInfo> pBuffer; 522 pBuffer.clear(); 523 uint32_t nBufferSize = portDef.nBufferSize >> 1; 524 525 for (size_t i = 0; i < portDef.nBufferCountActual; i++) { 526 BufferInfo buffer; 527 ASSERT_NO_FATAL_FAILURE(allocateBuffer(omxNode, &buffer, portBase, 528 nBufferSize, 529 PortMode::PRESET_BYTE_BUFFER)); 530 pBuffer.push(buffer); 531 } 532 533 status = 534 getPortParam(omxNode, OMX_IndexParamPortDefinition, portBase, &portDef); 535 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK); 536 // A port is populated when all of the buffers indicated by 537 // nBufferCountActual with a size of at least nBufferSizehave been 538 // allocated on the port. 539 ASSERT_EQ(portDef.bPopulated, OMX_FALSE); 540 } 541 542 // Flush test 543 TEST_F(ComponentHidlTest, Flush) { 544 description("Test Flush"); 545 if (disableTest) return; 546 android::hardware::media::omx::V1_0::Status status; 547 uint32_t kPortIndexInput = 0, kPortIndexOutput = 1; 548 Message msg; 549 550 status = setRole(omxNode, gEnv->getRole().c_str()); 551 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK); 552 OMX_PORT_PARAM_TYPE params; 553 if (compClass == audio_decoder || compClass == audio_encoder) { 554 status = getParam(omxNode, OMX_IndexParamAudioInit, ¶ms); 555 } else { 556 status = getParam(omxNode, OMX_IndexParamVideoInit, ¶ms); 557 } 558 if (status == ::android::hardware::media::omx::V1_0::Status::OK) { 559 ASSERT_EQ(params.nPorts, 2U); 560 kPortIndexInput = params.nStartPortNumber; 561 kPortIndexOutput = kPortIndexInput + 1; 562 } 563 564 android::Vector<BufferInfo> iBuffer, oBuffer; 565 566 // set port mode 567 PortMode portMode[2]; 568 initPortMode(portMode, isSecure, compClass); 569 status = omxNode->setPortMode(kPortIndexInput, portMode[0]); 570 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK); 571 status = omxNode->setPortMode(kPortIndexOutput, portMode[1]); 572 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK); 573 574 // set state to idle 575 ASSERT_NO_FATAL_FAILURE( 576 changeStateLoadedtoIdle(omxNode, observer, &iBuffer, &oBuffer, 577 kPortIndexInput, kPortIndexOutput, portMode)); 578 // set state to executing 579 ASSERT_NO_FATAL_FAILURE(changeStateIdletoExecute(omxNode, observer)); 580 // dispatch buffers 581 for (size_t i = 0; i < oBuffer.size(); i++) { 582 ASSERT_NO_FATAL_FAILURE( 583 dispatchOutputBuffer(omxNode, &oBuffer, i, portMode[1])); 584 } 585 // flush port 586 ASSERT_NO_FATAL_FAILURE(flushPorts(omxNode, observer, &iBuffer, &oBuffer, 587 kPortIndexInput, kPortIndexOutput)); 588 #if 0 589 // TODO: Sending empty input buffers is slightly tricky. 590 // Components sometimes process input buffers even when output buffers are 591 // not dispatched. For instance Parsing sequence header does not require 592 // output buffers. In such instances sending 0 size input buffers might 593 // make component to send error events. so lets skip this aspect of testing. 594 // dispatch buffers 595 for (size_t i = 0; i < iBuffer.size(); i++) { 596 ASSERT_NO_FATAL_FAILURE( 597 dispatchInputBuffer(omxNode, &iBuffer, i, 0, 0, 0, portMode[0])); 598 } 599 // flush ports 600 ASSERT_NO_FATAL_FAILURE(flushPorts(omxNode, observer, &iBuffer, &oBuffer, 601 kPortIndexInput, kPortIndexOutput)); 602 #endif 603 604 // set state to idle 605 ASSERT_NO_FATAL_FAILURE( 606 changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer)); 607 // set state to loaded 608 ASSERT_NO_FATAL_FAILURE(changeStateIdletoLoaded(omxNode, observer, &iBuffer, 609 &oBuffer, kPortIndexInput, 610 kPortIndexOutput)); 611 } 612 613 // Flush test - monkeying 614 TEST_F(ComponentHidlTest, Flush_M) { 615 description("Test Flush monkeying"); 616 if (disableTest) return; 617 android::hardware::media::omx::V1_0::Status status; 618 uint32_t kPortIndexInput = 0, kPortIndexOutput = 1; 619 Message msg; 620 621 status = setRole(omxNode, gEnv->getRole().c_str()); 622 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK); 623 OMX_PORT_PARAM_TYPE params; 624 if (compClass == audio_decoder || compClass == audio_encoder) { 625 status = getParam(omxNode, OMX_IndexParamAudioInit, ¶ms); 626 } else { 627 status = getParam(omxNode, OMX_IndexParamVideoInit, ¶ms); 628 } 629 if (status == ::android::hardware::media::omx::V1_0::Status::OK) { 630 ASSERT_EQ(params.nPorts, 2U); 631 kPortIndexInput = params.nStartPortNumber; 632 kPortIndexOutput = kPortIndexInput + 1; 633 } 634 635 android::Vector<BufferInfo> iBuffer, oBuffer; 636 637 // set port mode 638 PortMode portMode[2]; 639 initPortMode(portMode, isSecure, compClass); 640 status = omxNode->setPortMode(kPortIndexInput, portMode[0]); 641 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK); 642 status = omxNode->setPortMode(kPortIndexOutput, portMode[1]); 643 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK); 644 645 // // Flush all ports ; receive error OMX_ErrorIncorrectStateOperation 646 // status = omxNode->sendCommand(toRawCommandType(OMX_CommandFlush), 647 // OMX_ALL); 648 // ASSERT_NE(status, android::hardware::media::omx::V1_0::Status::OK); 649 650 // set state to idle 651 ASSERT_NO_FATAL_FAILURE( 652 changeStateLoadedtoIdle(omxNode, observer, &iBuffer, &oBuffer, 653 kPortIndexInput, kPortIndexOutput, portMode)); 654 655 // // Flush all ports ; receive error OMX_ErrorIncorrectStateOperation 656 // status = omxNode->sendCommand(toRawCommandType(OMX_CommandFlush), 657 // OMX_ALL); 658 // ASSERT_NE(status, android::hardware::media::omx::V1_0::Status::OK); 659 660 // set state to executing 661 ASSERT_NO_FATAL_FAILURE(changeStateIdletoExecute(omxNode, observer)); 662 663 // dispatch buffers 664 for (size_t i = 0; i < oBuffer.size(); i++) { 665 ASSERT_NO_FATAL_FAILURE( 666 dispatchOutputBuffer(omxNode, &oBuffer, i, portMode[1])); 667 } 668 669 // // flush invalid port, expecting OMX_ErrorBadPortIndex 670 // status = omxNode->sendCommand(toRawCommandType(OMX_CommandFlush), 671 // RANDOM_INDEX); 672 // ASSERT_NE(status, android::hardware::media::omx::V1_0::Status::OK); 673 674 // Flush all ports 675 status = omxNode->sendCommand(toRawCommandType(OMX_CommandFlush), OMX_ALL); 676 ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK); 677 678 for (int j = 0; j < 2; j++) { 679 status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT_PE, &iBuffer, 680 &oBuffer); 681 ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK); 682 ASSERT_EQ(msg.type, Message::Type::EVENT); 683 ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete); 684 ASSERT_EQ(msg.data.eventData.data1, OMX_CommandFlush); 685 if (msg.data.eventData.data2 == kPortIndexInput) { 686 // test if client got all its buffers back 687 for (size_t i = 0; i < iBuffer.size(); ++i) { 688 EXPECT_EQ(iBuffer[i].owner, client); 689 } 690 } else if (msg.data.eventData.data2 == kPortIndexOutput) { 691 // test if client got all its buffers back 692 for (size_t i = 0; i < oBuffer.size(); ++i) { 693 EXPECT_EQ(oBuffer[i].owner, client); 694 } 695 } else { 696 EXPECT_TRUE(false) << "Bad port Index"; 697 } 698 } 699 700 // SPECIAL CASE: When OMX_ALL is used as argument, Android OMX Core sends 701 // an additional flush event with argument OMX_ALL. This we believe is 702 // not recognized by OMX-IL Spec. So read this event and ignore it 703 status = 704 observer->dequeueMessage(&msg, DEFAULT_TIMEOUT_PE, &iBuffer, &oBuffer); 705 if (status == android::hardware::media::omx::V1_0::Status::OK) { 706 ASSERT_EQ(msg.type, Message::Type::EVENT); 707 ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete); 708 ASSERT_EQ(msg.data.eventData.data1, OMX_CommandFlush); 709 ASSERT_EQ(msg.data.eventData.data2, OMX_ALL); 710 } 711 712 // set state to idle 713 ASSERT_NO_FATAL_FAILURE( 714 changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer)); 715 // set state to loaded 716 ASSERT_NO_FATAL_FAILURE(changeStateIdletoLoaded(omxNode, observer, &iBuffer, 717 &oBuffer, kPortIndexInput, 718 kPortIndexOutput)); 719 } 720 721 // test port mode configuration when the component is in various states 722 TEST_F(ComponentHidlTest, PortModeConfig) { 723 description("Test Port Mode Configuration"); 724 if (disableTest) return; 725 android::hardware::media::omx::V1_0::Status status; 726 uint32_t kPortIndexInput = 0, kPortIndexOutput = 1; 727 Message msg; 728 729 status = setRole(omxNode, gEnv->getRole().c_str()); 730 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK); 731 OMX_PORT_PARAM_TYPE params; 732 if (compClass == audio_decoder || compClass == audio_encoder) { 733 status = getParam(omxNode, OMX_IndexParamAudioInit, ¶ms); 734 } else { 735 status = getParam(omxNode, OMX_IndexParamVideoInit, ¶ms); 736 } 737 if (status == ::android::hardware::media::omx::V1_0::Status::OK) { 738 ASSERT_EQ(params.nPorts, 2U); 739 kPortIndexInput = params.nStartPortNumber; 740 kPortIndexOutput = kPortIndexInput + 1; 741 } 742 743 android::Vector<BufferInfo> iBuffer, oBuffer; 744 745 // set port mode 746 PortMode portMode[2]; 747 initPortMode(portMode, isSecure, compClass); 748 status = omxNode->setPortMode(kPortIndexInput, portMode[0]); 749 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK); 750 status = omxNode->setPortMode(kPortIndexOutput, portMode[1]); 751 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK); 752 753 // set state to idle 754 ASSERT_NO_FATAL_FAILURE( 755 changeStateLoadedtoIdle(omxNode, observer, &iBuffer, &oBuffer, 756 kPortIndexInput, kPortIndexOutput, portMode)); 757 // Only Allow Port Mode configuration in loaded state 758 status = omxNode->setPortMode(kPortIndexInput, portMode[0]); 759 EXPECT_NE(status, ::android::hardware::media::omx::V1_0::Status::OK); 760 status = omxNode->setPortMode(kPortIndexOutput, portMode[1]); 761 EXPECT_NE(status, ::android::hardware::media::omx::V1_0::Status::OK); 762 763 // set state to executing 764 ASSERT_NO_FATAL_FAILURE(changeStateIdletoExecute(omxNode, observer)); 765 // Only Allow Port Mode configuration in loaded state 766 status = omxNode->setPortMode(kPortIndexInput, portMode[0]); 767 EXPECT_NE(status, ::android::hardware::media::omx::V1_0::Status::OK); 768 status = omxNode->setPortMode(kPortIndexOutput, portMode[1]); 769 EXPECT_NE(status, ::android::hardware::media::omx::V1_0::Status::OK); 770 771 // set state to idle 772 ASSERT_NO_FATAL_FAILURE( 773 changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer)); 774 // set state to loaded 775 ASSERT_NO_FATAL_FAILURE(changeStateIdletoLoaded(omxNode, observer, &iBuffer, 776 &oBuffer, kPortIndexInput, 777 kPortIndexOutput)); 778 779 status = omxNode->setPortMode(kPortIndexInput, portMode[0]); 780 EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK); 781 status = omxNode->setPortMode(kPortIndexOutput, portMode[1]); 782 EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK); 783 } 784 785 // state transitions test 786 TEST_F(ComponentHidlTest, StateTransitions) { 787 description("Test State Transitions Loaded<->Idle<->Execute"); 788 if (disableTest) return; 789 android::hardware::media::omx::V1_0::Status status; 790 uint32_t kPortIndexInput = 0, kPortIndexOutput = 1; 791 OMX_U32 portBase = 0; 792 Message msg; 793 status = setRole(omxNode, gEnv->getRole().c_str()); 794 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK); 795 OMX_PORT_PARAM_TYPE params; 796 if (compClass == audio_decoder || compClass == audio_encoder) { 797 status = getParam(omxNode, OMX_IndexParamAudioInit, ¶ms); 798 } else { 799 status = getParam(omxNode, OMX_IndexParamVideoInit, ¶ms); 800 } 801 if (status == ::android::hardware::media::omx::V1_0::Status::OK) { 802 ASSERT_EQ(params.nPorts, 2U); 803 portBase = params.nStartPortNumber; 804 } 805 kPortIndexInput = portBase; 806 kPortIndexOutput = portBase + 1; 807 808 android::Vector<BufferInfo> pBuffer[2]; 809 810 // set port mode 811 PortMode portMode[2]; 812 initPortMode(portMode, isSecure, compClass); 813 status = omxNode->setPortMode(kPortIndexInput, portMode[0]); 814 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK); 815 status = omxNode->setPortMode(kPortIndexOutput, portMode[1]); 816 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK); 817 818 // set state to idle 819 status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet), 820 OMX_StateIdle); 821 ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK); 822 823 for (size_t j = portBase; j < portBase + 2; j++) { 824 pBuffer[j - portBase].clear(); 825 826 OMX_PARAM_PORTDEFINITIONTYPE def; 827 status = getPortParam(omxNode, OMX_IndexParamPortDefinition, j, &def); 828 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK); 829 830 for (size_t i = 0; i < def.nBufferCountActual; i++) { 831 // Dont switch states until the ports are populated 832 status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, 833 &pBuffer[0], &pBuffer[1]); 834 ASSERT_EQ(status, 835 android::hardware::media::omx::V1_0::Status::TIMED_OUT); 836 837 BufferInfo buffer; 838 ASSERT_NO_FATAL_FAILURE(allocateBuffer( 839 omxNode, &buffer, j, def.nBufferSize, portMode[j - portBase])); 840 pBuffer[j - portBase].push(buffer); 841 } 842 } 843 844 // As the ports are populated, check if the state transition is complete 845 status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &pBuffer[0], 846 &pBuffer[1]); 847 ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK); 848 ASSERT_EQ(msg.type, Message::Type::EVENT); 849 ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete); 850 ASSERT_EQ(msg.data.eventData.data1, OMX_CommandStateSet); 851 ASSERT_EQ(msg.data.eventData.data2, OMX_StateIdle); 852 853 // set state to executing 854 ASSERT_NO_FATAL_FAILURE(changeStateIdletoExecute(omxNode, observer)); 855 // dispatch buffers 856 for (size_t i = 0; i < pBuffer[1].size(); i++) { 857 ASSERT_NO_FATAL_FAILURE( 858 dispatchOutputBuffer(omxNode, &pBuffer[1], i, portMode[1])); 859 } 860 // set state to idle 861 ASSERT_NO_FATAL_FAILURE( 862 changeStateExecutetoIdle(omxNode, observer, &pBuffer[0], &pBuffer[1])); 863 #if 0 864 // set state to executing 865 ASSERT_NO_FATAL_FAILURE(changeStateIdletoExecute(omxNode, observer)); 866 // TODO: Sending empty input buffers is slightly tricky. 867 // dispatch buffers 868 for (size_t i = 0; i < pBuffer[0].size(); i++) { 869 ASSERT_NO_FATAL_FAILURE( 870 dispatchInputBuffer(omxNode, &pBuffer[0], i, 0, 0, 0, portMode[0])); 871 } 872 // set state to idle 873 ASSERT_NO_FATAL_FAILURE( 874 changeStateExecutetoIdle(omxNode, observer, &pBuffer[0], &pBuffer[1])); 875 #endif 876 877 // set state to loaded 878 status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet), 879 OMX_StateLoaded); 880 ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK); 881 882 for (size_t j = portBase; j < portBase + 2; j++) { 883 for (size_t i = 0; i < pBuffer[j].size(); ++i) { 884 // Dont switch states until the ports are populated 885 status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, 886 &pBuffer[0], &pBuffer[1]); 887 ASSERT_EQ(status, 888 android::hardware::media::omx::V1_0::Status::TIMED_OUT); 889 890 status = omxNode->freeBuffer(j, pBuffer[j][i].id); 891 ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK); 892 } 893 } 894 895 status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &pBuffer[0], 896 &pBuffer[1]); 897 ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK); 898 ASSERT_EQ(msg.type, Message::Type::EVENT); 899 ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete); 900 ASSERT_EQ(msg.data.eventData.data1, OMX_CommandStateSet); 901 ASSERT_EQ(msg.data.eventData.data2, OMX_StateLoaded); 902 } 903 904 // state transitions test - monkeying 905 TEST_F(ComponentHidlTest, DISABLED_StateTransitions_M) { 906 description("Test State Transitions monkeying"); 907 if (disableTest || isSecure) return; 908 android::hardware::media::omx::V1_0::Status status; 909 uint32_t kPortIndexInput = 0, kPortIndexOutput = 1; 910 Message msg; 911 912 status = setRole(omxNode, gEnv->getRole().c_str()); 913 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK); 914 OMX_PORT_PARAM_TYPE params; 915 if (compClass == audio_decoder || compClass == audio_encoder) { 916 status = getParam(omxNode, OMX_IndexParamAudioInit, ¶ms); 917 } else { 918 status = getParam(omxNode, OMX_IndexParamVideoInit, ¶ms); 919 } 920 if (status == ::android::hardware::media::omx::V1_0::Status::OK) { 921 ASSERT_EQ(params.nPorts, 2U); 922 kPortIndexInput = params.nStartPortNumber; 923 kPortIndexOutput = kPortIndexInput + 1; 924 } 925 926 android::Vector<BufferInfo> iBuffer, oBuffer; 927 928 // set state to loaded ; receive error OMX_ErrorSameState 929 status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet), 930 OMX_StateLoaded); 931 EXPECT_NE(status, android::hardware::media::omx::V1_0::Status::OK); 932 933 // set state to executing ; receive error OMX_ErrorIncorrectStateTransition 934 status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet), 935 OMX_StateExecuting); 936 EXPECT_NE(status, android::hardware::media::omx::V1_0::Status::OK); 937 938 // set state to idle 939 ASSERT_NO_FATAL_FAILURE(changeStateLoadedtoIdle(omxNode, observer, &iBuffer, 940 &oBuffer, kPortIndexInput, 941 kPortIndexOutput)); 942 943 // set state to idle ; receive error OMX_ErrorSameState 944 status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet), 945 OMX_StateIdle); 946 EXPECT_NE(status, android::hardware::media::omx::V1_0::Status::OK); 947 948 // set state to executing 949 ASSERT_NO_FATAL_FAILURE(changeStateIdletoExecute(omxNode, observer)); 950 951 // set state to executing ; receive error OMX_ErrorSameState 952 status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet), 953 OMX_StateExecuting); 954 EXPECT_NE(status, android::hardware::media::omx::V1_0::Status::OK); 955 956 // set state to Loaded ; receive error OMX_ErrorIncorrectStateTransition 957 status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet), 958 OMX_StateLoaded); 959 EXPECT_NE(status, android::hardware::media::omx::V1_0::Status::OK); 960 961 // set state to idle 962 ASSERT_NO_FATAL_FAILURE( 963 changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer)); 964 // set state to loaded 965 ASSERT_NO_FATAL_FAILURE(changeStateIdletoLoaded(omxNode, observer, &iBuffer, 966 &oBuffer, kPortIndexInput, 967 kPortIndexOutput)); 968 } 969 970 // port enable disable test 971 TEST_F(ComponentHidlTest, DISABLED_PortEnableDisable_Loaded) { 972 description("Test Port Enable and Disable (Component State :: Loaded)"); 973 if (disableTest) return; 974 android::hardware::media::omx::V1_0::Status status; 975 OMX_U32 portBase = 0; 976 Message msg; 977 status = setRole(omxNode, gEnv->getRole().c_str()); 978 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK); 979 OMX_PORT_PARAM_TYPE params; 980 if (compClass == audio_decoder || compClass == audio_encoder) { 981 status = getParam(omxNode, OMX_IndexParamAudioInit, ¶ms); 982 } else { 983 status = getParam(omxNode, OMX_IndexParamVideoInit, ¶ms); 984 } 985 if (status == ::android::hardware::media::omx::V1_0::Status::OK) { 986 ASSERT_EQ(params.nPorts, 2U); 987 portBase = params.nStartPortNumber; 988 } 989 990 for (size_t i = portBase; i < portBase + 2; i++) { 991 status = 992 omxNode->sendCommand(toRawCommandType(OMX_CommandPortDisable), i); 993 ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK); 994 status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT); 995 ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK); 996 ASSERT_EQ(msg.type, Message::Type::EVENT); 997 if (msg.data.eventData.event == OMX_EventCmdComplete) { 998 ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortDisable); 999 ASSERT_EQ(msg.data.eventData.data2, i); 1000 // If you can disable a port, then you should be able to enable it 1001 // as well 1002 status = omxNode->sendCommand( 1003 toRawCommandType(OMX_CommandPortEnable), i); 1004 ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK); 1005 status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT); 1006 ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK); 1007 ASSERT_EQ(msg.type, Message::Type::EVENT); 1008 ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortEnable); 1009 ASSERT_EQ(msg.data.eventData.data2, i); 1010 } else if (msg.data.eventData.event == OMX_EventError) { 1011 ALOGE("Port %d Disabling failed with error %d", (int)i, 1012 (int)msg.data.eventData.event); 1013 } else { 1014 // something unexpected happened 1015 ASSERT_TRUE(false); 1016 } 1017 } 1018 } 1019 1020 // port enable disable test 1021 TEST_F(ComponentHidlTest, PortEnableDisable_Idle) { 1022 description("Test Port Enable and Disable (Component State :: Idle)"); 1023 if (disableTest) return; 1024 android::hardware::media::omx::V1_0::Status status; 1025 uint32_t kPortIndexInput = 0, kPortIndexOutput = 1; 1026 OMX_U32 portBase = 0; 1027 Message msg; 1028 status = setRole(omxNode, gEnv->getRole().c_str()); 1029 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK); 1030 OMX_PORT_PARAM_TYPE params; 1031 if (compClass == audio_decoder || compClass == audio_encoder) { 1032 status = getParam(omxNode, OMX_IndexParamAudioInit, ¶ms); 1033 } else { 1034 status = getParam(omxNode, OMX_IndexParamVideoInit, ¶ms); 1035 } 1036 if (status == ::android::hardware::media::omx::V1_0::Status::OK) { 1037 ASSERT_EQ(params.nPorts, 2U); 1038 portBase = params.nStartPortNumber; 1039 } 1040 kPortIndexInput = portBase; 1041 kPortIndexOutput = portBase + 1; 1042 1043 // Component State :: Idle 1044 android::Vector<BufferInfo> pBuffer[2]; 1045 1046 // set port mode 1047 PortMode portMode[2]; 1048 initPortMode(portMode, isSecure, compClass); 1049 status = omxNode->setPortMode(kPortIndexInput, portMode[0]); 1050 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK); 1051 status = omxNode->setPortMode(kPortIndexOutput, portMode[1]); 1052 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK); 1053 1054 // set state to idle 1055 ASSERT_NO_FATAL_FAILURE( 1056 changeStateLoadedtoIdle(omxNode, observer, &pBuffer[0], &pBuffer[1], 1057 kPortIndexInput, kPortIndexOutput, portMode)); 1058 for (size_t i = portBase; i < portBase + 2; i++) { 1059 status = 1060 omxNode->sendCommand(toRawCommandType(OMX_CommandPortDisable), i); 1061 ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK); 1062 1063 status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &pBuffer[0], 1064 &pBuffer[1]); 1065 if (status == android::hardware::media::omx::V1_0::Status::OK) { 1066 ASSERT_EQ(msg.type, Message::Type::EVENT); 1067 if (msg.data.eventData.event == OMX_EventCmdComplete) { 1068 // do not disable the port until all the buffers are freed 1069 ASSERT_TRUE(false); 1070 } else if (msg.data.eventData.event == OMX_EventError) { 1071 ALOGE("Port %d Disabling failed with error %d", (int)i, 1072 (int)msg.data.eventData.event); 1073 } else { 1074 // something unexpected happened 1075 ASSERT_TRUE(false); 1076 } 1077 } else if (status == 1078 android::hardware::media::omx::V1_0::Status::TIMED_OUT) { 1079 for (size_t j = 0; j < pBuffer[i - portBase].size(); ++j) { 1080 status = omxNode->freeBuffer(i, pBuffer[i - portBase][j].id); 1081 ASSERT_EQ(status, 1082 android::hardware::media::omx::V1_0::Status::OK); 1083 } 1084 1085 status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, 1086 &pBuffer[0], &pBuffer[1]); 1087 ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK); 1088 ASSERT_EQ(msg.type, Message::Type::EVENT); 1089 ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete); 1090 ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortDisable); 1091 ASSERT_EQ(msg.data.eventData.data2, i); 1092 1093 // If you can disable a port, then you should be able to enable it 1094 // as well 1095 status = omxNode->sendCommand( 1096 toRawCommandType(OMX_CommandPortEnable), i); 1097 ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK); 1098 1099 // do not enable the port until all the buffers are supplied 1100 status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, 1101 &pBuffer[0], &pBuffer[1]); 1102 ASSERT_EQ(status, 1103 android::hardware::media::omx::V1_0::Status::TIMED_OUT); 1104 1105 ASSERT_NO_FATAL_FAILURE(allocatePortBuffers( 1106 omxNode, &pBuffer[i - portBase], i, portMode[i - portBase])); 1107 status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, 1108 &pBuffer[0], &pBuffer[1]); 1109 ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK); 1110 ASSERT_EQ(msg.type, Message::Type::EVENT); 1111 ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortEnable); 1112 ASSERT_EQ(msg.data.eventData.data2, i); 1113 } else { 1114 // something unexpected happened 1115 ASSERT_TRUE(false); 1116 } 1117 } 1118 1119 // set state to Loaded 1120 ASSERT_NO_FATAL_FAILURE( 1121 changeStateIdletoLoaded(omxNode, observer, &pBuffer[0], &pBuffer[1], 1122 kPortIndexInput, kPortIndexOutput)); 1123 } 1124 1125 // port enable disable test 1126 TEST_F(ComponentHidlTest, PortEnableDisable_Execute) { 1127 description("Test Port Enable and Disable (Component State :: Execute)"); 1128 if (disableTest) return; 1129 android::hardware::media::omx::V1_0::Status status; 1130 uint32_t kPortIndexInput = 0, kPortIndexOutput = 1; 1131 OMX_U32 portBase = 0; 1132 Message msg; 1133 status = setRole(omxNode, gEnv->getRole().c_str()); 1134 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK); 1135 OMX_PORT_PARAM_TYPE params; 1136 if (compClass == audio_decoder || compClass == audio_encoder) { 1137 status = getParam(omxNode, OMX_IndexParamAudioInit, ¶ms); 1138 } else { 1139 status = getParam(omxNode, OMX_IndexParamVideoInit, ¶ms); 1140 } 1141 if (status == ::android::hardware::media::omx::V1_0::Status::OK) { 1142 ASSERT_EQ(params.nPorts, 2U); 1143 portBase = params.nStartPortNumber; 1144 } 1145 kPortIndexInput = portBase; 1146 kPortIndexOutput = portBase + 1; 1147 1148 // Component State :: Idle 1149 android::Vector<BufferInfo> pBuffer[2]; 1150 1151 // set port mode 1152 PortMode portMode[2]; 1153 initPortMode(portMode, isSecure, compClass); 1154 status = omxNode->setPortMode(kPortIndexInput, portMode[0]); 1155 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK); 1156 status = omxNode->setPortMode(kPortIndexOutput, portMode[1]); 1157 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK); 1158 1159 // set state to idle 1160 ASSERT_NO_FATAL_FAILURE( 1161 changeStateLoadedtoIdle(omxNode, observer, &pBuffer[0], &pBuffer[1], 1162 kPortIndexInput, kPortIndexOutput, portMode)); 1163 // set state to executing 1164 ASSERT_NO_FATAL_FAILURE(changeStateIdletoExecute(omxNode, observer)); 1165 // dispatch buffers 1166 for (size_t i = 0; i < pBuffer[1].size(); i++) { 1167 ASSERT_NO_FATAL_FAILURE( 1168 dispatchOutputBuffer(omxNode, &pBuffer[1], i, portMode[1])); 1169 } 1170 1171 for (size_t i = portBase; i < portBase + 2; i++) { 1172 status = 1173 omxNode->sendCommand(toRawCommandType(OMX_CommandPortDisable), i); 1174 ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK); 1175 1176 status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &pBuffer[0], 1177 &pBuffer[1]); 1178 if (status == android::hardware::media::omx::V1_0::Status::OK) { 1179 ASSERT_EQ(msg.type, Message::Type::EVENT); 1180 if (msg.data.eventData.event == OMX_EventCmdComplete) { 1181 // do not disable the port until all the buffers are freed 1182 ASSERT_TRUE(false); 1183 } else if (msg.data.eventData.event == OMX_EventError) { 1184 ALOGE("Port %d Disabling failed with error %d", (int)i, 1185 (int)msg.data.eventData.event); 1186 } else { 1187 // something unexpected happened 1188 ASSERT_TRUE(false); 1189 } 1190 } else if (status == 1191 android::hardware::media::omx::V1_0::Status::TIMED_OUT) { 1192 for (size_t j = 0; j < pBuffer[i - portBase].size(); ++j) { 1193 // test if client got all its buffers back 1194 EXPECT_EQ(pBuffer[i - portBase][j].owner, client); 1195 // free the buffers 1196 status = omxNode->freeBuffer(i, pBuffer[i - portBase][j].id); 1197 ASSERT_EQ(status, 1198 android::hardware::media::omx::V1_0::Status::OK); 1199 } 1200 1201 status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, 1202 &pBuffer[0], &pBuffer[1]); 1203 ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK); 1204 ASSERT_EQ(msg.type, Message::Type::EVENT); 1205 ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete); 1206 ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortDisable); 1207 ASSERT_EQ(msg.data.eventData.data2, i); 1208 1209 // If you can disable a port, then you should be able to enable it 1210 // as well 1211 status = omxNode->sendCommand( 1212 toRawCommandType(OMX_CommandPortEnable), i); 1213 ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK); 1214 1215 // do not enable the port until all the buffers are supplied 1216 status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, 1217 &pBuffer[0], &pBuffer[1]); 1218 ASSERT_EQ(status, 1219 android::hardware::media::omx::V1_0::Status::TIMED_OUT); 1220 1221 ASSERT_NO_FATAL_FAILURE(allocatePortBuffers( 1222 omxNode, &pBuffer[i - portBase], i, portMode[i - portBase])); 1223 status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, 1224 &pBuffer[0], &pBuffer[1]); 1225 ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK); 1226 ASSERT_EQ(msg.type, Message::Type::EVENT); 1227 ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortEnable); 1228 ASSERT_EQ(msg.data.eventData.data2, i); 1229 } else { 1230 // something unexpected happened 1231 ASSERT_TRUE(false); 1232 } 1233 } 1234 1235 // set state to idle 1236 ASSERT_NO_FATAL_FAILURE( 1237 changeStateExecutetoIdle(omxNode, observer, &pBuffer[0], &pBuffer[1])); 1238 // set state to loaded 1239 ASSERT_NO_FATAL_FAILURE( 1240 changeStateIdletoLoaded(omxNode, observer, &pBuffer[0], &pBuffer[1], 1241 kPortIndexInput, kPortIndexOutput)); 1242 } 1243 1244 // port enable disable test - monkeying 1245 TEST_F(ComponentHidlTest, DISABLED_PortEnableDisable_M) { 1246 description( 1247 "Test Port Enable and Disable Monkeying (Component State :: Loaded)"); 1248 if (disableTest || isSecure) return; 1249 android::hardware::media::omx::V1_0::Status status; 1250 OMX_U32 portBase = 0; 1251 Message msg; 1252 status = setRole(omxNode, gEnv->getRole().c_str()); 1253 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK); 1254 OMX_PORT_PARAM_TYPE params; 1255 if (compClass == audio_decoder || compClass == audio_encoder) { 1256 status = getParam(omxNode, OMX_IndexParamAudioInit, ¶ms); 1257 } else { 1258 status = getParam(omxNode, OMX_IndexParamVideoInit, ¶ms); 1259 } 1260 if (status == ::android::hardware::media::omx::V1_0::Status::OK) { 1261 ASSERT_EQ(params.nPorts, 2U); 1262 portBase = params.nStartPortNumber; 1263 } 1264 1265 // disable invalid port, expecting OMX_ErrorBadPortIndex 1266 status = omxNode->sendCommand(toRawCommandType(OMX_CommandPortDisable), 1267 RANDOM_INDEX); 1268 ASSERT_NE(status, android::hardware::media::omx::V1_0::Status::OK); 1269 1270 // enable invalid port, expecting OMX_ErrorBadPortIndex 1271 status = omxNode->sendCommand(toRawCommandType(OMX_CommandPortEnable), 1272 RANDOM_INDEX); 1273 ASSERT_NE(status, android::hardware::media::omx::V1_0::Status::OK); 1274 1275 // disable all ports 1276 status = 1277 omxNode->sendCommand(toRawCommandType(OMX_CommandPortDisable), OMX_ALL); 1278 ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK); 1279 for (size_t i = 0; i < 2; i++) { 1280 status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT); 1281 ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK); 1282 ASSERT_EQ(msg.type, Message::Type::EVENT); 1283 if (msg.data.eventData.event == OMX_EventCmdComplete) { 1284 ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortDisable); 1285 if (msg.data.eventData.data2 != portBase || 1286 msg.data.eventData.data2 != portBase + 1) 1287 EXPECT_TRUE(false); 1288 } else if (msg.data.eventData.event == OMX_EventError) { 1289 ALOGE("Port %d Disabling failed with error %d", (int)i, 1290 (int)msg.data.eventData.event); 1291 } else { 1292 // something unexpected happened 1293 ASSERT_TRUE(false); 1294 } 1295 } 1296 1297 // enable all ports 1298 status = 1299 omxNode->sendCommand(toRawCommandType(OMX_CommandPortEnable), OMX_ALL); 1300 ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK); 1301 for (size_t i = 0; i < 2; i++) { 1302 status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT); 1303 ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK); 1304 ASSERT_EQ(msg.type, Message::Type::EVENT); 1305 if (msg.data.eventData.event == OMX_EventCmdComplete) { 1306 ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortEnable); 1307 if (msg.data.eventData.data2 != portBase || 1308 msg.data.eventData.data2 != portBase + 1) 1309 EXPECT_TRUE(false); 1310 } else if (msg.data.eventData.event == OMX_EventError) { 1311 ALOGE("Port %d Enabling failed with error %d", (int)i, 1312 (int)msg.data.eventData.event); 1313 } else { 1314 // something unexpected happened 1315 ASSERT_TRUE(false); 1316 } 1317 } 1318 } 1319 1320 int main(int argc, char** argv) { 1321 gEnv = new ComponentTestEnvironment(); 1322 ::testing::AddGlobalTestEnvironment(gEnv); 1323 ::testing::InitGoogleTest(&argc, argv); 1324 int status = gEnv->initFromOptions(argc, argv); 1325 if (status == 0) { 1326 status = RUN_ALL_TESTS(); 1327 ALOGI("Test result = %d", status); 1328 } 1329 return status; 1330 } 1331