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