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:
getTestCaseInfo() const58 ::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
SetUp()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
TearDown()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:
description(const std::string & description)156 static void description(const std::string& description) {
157 RecordProperty("description", description);
158 }
159 };
160
initPortMode(PortMode * pm,bool isSecure,ComponentHidlTest::standardCompClass compClass)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
TEST_F(ComponentHidlTest,dispatchMsg)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
TEST_F(ComponentHidlTest,SetRole)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
TEST_F(ComponentHidlTest,DISABLED_GetPortIndices)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
TEST_F(ComponentHidlTest,EnumeratePortFormat)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
TEST_F(ComponentHidlTest,DISABLED_SetDefaultPortParams)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
TEST_F(ComponentHidlTest,DISABLED_PopulatePort)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
TEST_F(ComponentHidlTest,Flush)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
TEST_F(ComponentHidlTest,Flush_M)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
TEST_F(ComponentHidlTest,PortModeConfig)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
TEST_F(ComponentHidlTest,StateTransitions)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
TEST_F(ComponentHidlTest,DISABLED_StateTransitions_M)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
TEST_F(ComponentHidlTest,DISABLED_PortEnableDisable_Loaded)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
TEST_F(ComponentHidlTest,PortEnableDisable_Idle)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
TEST_F(ComponentHidlTest,PortEnableDisable_Execute)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
TEST_F(ComponentHidlTest,DISABLED_PortEnableDisable_M)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
main(int argc,char ** argv)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