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_video_dec_test"
18 #ifdef __LP64__
19 #define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
20 #endif
21
22 #include <android-base/logging.h>
23
24 #include <android/hardware/media/omx/1.0/IOmx.h>
25 #include <android/hardware/media/omx/1.0/IOmxNode.h>
26 #include <android/hardware/media/omx/1.0/IOmxObserver.h>
27 #include <android/hardware/media/omx/1.0/types.h>
28 #include <android/hidl/allocator/1.0/IAllocator.h>
29 #include <android/hidl/memory/1.0/IMapper.h>
30 #include <android/hidl/memory/1.0/IMemory.h>
31 #include <gtest/gtest.h>
32 #include <hidl/GtestPrinter.h>
33
34 using ::android::hardware::media::omx::V1_0::IOmx;
35 using ::android::hardware::media::omx::V1_0::IOmxObserver;
36 using ::android::hardware::media::omx::V1_0::IOmxNode;
37 using ::android::hardware::media::omx::V1_0::Message;
38 using ::android::hardware::media::omx::V1_0::CodecBuffer;
39 using ::android::hardware::media::omx::V1_0::PortMode;
40 using ::android::hidl::allocator::V1_0::IAllocator;
41 using ::android::hidl::memory::V1_0::IMemory;
42 using ::android::hidl::memory::V1_0::IMapper;
43 using ::android::hardware::Return;
44 using ::android::hardware::Void;
45 using ::android::hardware::hidl_vec;
46 using ::android::hardware::hidl_string;
47 using ::android::sp;
48
49 #include <getopt.h>
50 #include <media/hardware/HardwareAPI.h>
51 #include <media_video_hidl_test_common.h>
52 #include <fstream>
53
54 // Resource directory
55 std::string sResourceDir = "";
56
57 // video decoder test fixture class
58 class VideoDecHidlTest
59 : public ::testing::TestWithParam<std::tuple<std::string, std::string, std::string>> {
60 public:
getTestCaseInfo() const61 ::std::string getTestCaseInfo() const {
62 return ::std::string() + "Component: " + component_ + " | " + "Role: " + role_ + " | " +
63 "Instance: " + instance_ + " | " + "Res: " + sResourceDir;
64 }
65
SetUp()66 virtual void SetUp() override {
67 instance_ = std::get<0>(GetParam());
68 component_ = std::get<1>(GetParam());
69 role_ = std::get<2>(GetParam());
70 ASSERT_NE(sResourceDir.empty(), true);
71
72 disableTest = false;
73 android::hardware::media::omx::V1_0::Status status;
74 omx = IOmx::getService(instance_);
75 ASSERT_NE(omx, nullptr);
76 observer =
77 new CodecObserver([this](Message msg, const BufferInfo* buffer) {
78 handleMessage(msg, buffer);
79 });
80 ASSERT_NE(observer, nullptr);
81 if (component_.find("OMX.") != 0) disableTest = true;
82 EXPECT_TRUE(omx->allocateNode(component_, observer,
83 [&](android::hardware::media::omx::V1_0::Status _s,
84 sp<IOmxNode> const& _nl) {
85 status = _s;
86 this->omxNode = _nl;
87 })
88 .isOk());
89 if (status == android::hardware::media::omx::V1_0::Status::NAME_NOT_FOUND) {
90 disableTest = true;
91 std::cout << "[ WARN ] Test Disabled, component not present\n";
92 return;
93 }
94 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
95 ASSERT_NE(omxNode, nullptr);
96 ASSERT_NE(role_.empty(), true) << "Invalid Component Role";
97 struct StringToName {
98 const char* Name;
99 standardComp CompName;
100 };
101 const StringToName kStringToName[] = {
102 {"h263", h263}, {"avc", avc}, {"mpeg2", mpeg2}, {"mpeg4", mpeg4},
103 {"hevc", hevc}, {"vp8", vp8}, {"vp9", vp9},
104 };
105 const size_t kNumStringToName =
106 sizeof(kStringToName) / sizeof(kStringToName[0]);
107 const char* pch;
108 char substring[OMX_MAX_STRINGNAME_SIZE];
109 strcpy(substring, role_.c_str());
110 pch = strchr(substring, '.');
111 ASSERT_NE(pch, nullptr);
112 compName = unknown_comp;
113 for (size_t i = 0; i < kNumStringToName; ++i) {
114 if (!strcasecmp(pch + 1, kStringToName[i].Name)) {
115 compName = kStringToName[i].CompName;
116 break;
117 }
118 }
119 if (compName == unknown_comp) disableTest = true;
120 struct CompToCompression {
121 standardComp CompName;
122 OMX_VIDEO_CODINGTYPE eCompressionFormat;
123 };
124 static const CompToCompression kCompToCompression[] = {
125 {h263, OMX_VIDEO_CodingH263}, {avc, OMX_VIDEO_CodingAVC},
126 {mpeg2, OMX_VIDEO_CodingMPEG2}, {mpeg4, OMX_VIDEO_CodingMPEG4},
127 {hevc, OMX_VIDEO_CodingHEVC}, {vp8, OMX_VIDEO_CodingVP8},
128 {vp9, OMX_VIDEO_CodingVP9},
129 };
130 static const size_t kNumCompToCompression =
131 sizeof(kCompToCompression) / sizeof(kCompToCompression[0]);
132 size_t i;
133 for (i = 0; i < kNumCompToCompression; ++i) {
134 if (kCompToCompression[i].CompName == compName) {
135 eCompressionFormat = kCompToCompression[i].eCompressionFormat;
136 break;
137 }
138 }
139 if (i == kNumCompToCompression) disableTest = true;
140 portMode[0] = portMode[1] = PortMode::PRESET_BYTE_BUFFER;
141 eosFlag = false;
142 framesReceived = 0;
143 timestampUs = 0;
144 timestampDevTest = false;
145 isSecure = false;
146 portSettingsChange = false;
147 size_t suffixLen = strlen(".secure");
148 if (component_.rfind(".secure") == component_.length() - suffixLen) {
149 isSecure = true;
150 }
151 if (isSecure) disableTest = true;
152 omxNode->configureVideoTunnelMode(
153 1, OMX_TRUE, 0,
154 [&](android::hardware::media::omx::V1_0::Status _s,
155 const ::android::hardware::hidl_handle& sidebandHandle) {
156 (void)sidebandHandle;
157 if (_s == android::hardware::media::omx::V1_0::Status::OK)
158 this->disableTest = true;
159 });
160 if (disableTest) std::cout << "[ WARN ] Test Disabled \n";
161 // NOTES: secure and tunneled components are not covered in these tests.
162 // we are disabling tests for them
163 }
164
TearDown()165 virtual void TearDown() override {
166 if (omxNode != nullptr) {
167 // If you have encountered a fatal failure, it is possible that
168 // freeNode() will not go through. Instead of hanging the app.
169 // let it pass through and report errors
170 if (::testing::Test::HasFatalFailure()) return;
171 EXPECT_TRUE((omxNode->freeNode()).isOk());
172 omxNode = nullptr;
173 }
174 }
175
176 // callback function to process messages received by onMessages() from IL
177 // client.
handleMessage(Message msg,const BufferInfo * buffer)178 void handleMessage(Message msg, const BufferInfo* buffer) {
179 (void)buffer;
180 if (msg.type == Message::Type::FILL_BUFFER_DONE) {
181 if (msg.data.extendedBufferData.flags & OMX_BUFFERFLAG_EOS) {
182 eosFlag = true;
183 }
184 if (msg.data.extendedBufferData.rangeLength != 0) {
185 framesReceived += 1;
186 // For decoder components current timestamp always exceeds
187 // previous timestamp
188 EXPECT_GE(msg.data.extendedBufferData.timestampUs, timestampUs);
189 timestampUs = msg.data.extendedBufferData.timestampUs;
190 // Test if current timestamp is among the list of queued
191 // timestamps
192 if (timestampDevTest) {
193 bool tsHit = false;
194 android::List<uint64_t>::iterator it =
195 timestampUslist.begin();
196 while (it != timestampUslist.end()) {
197 if (*it == timestampUs) {
198 timestampUslist.erase(it);
199 tsHit = true;
200 break;
201 }
202 it++;
203 }
204 if (tsHit == false) {
205 if (timestampUslist.empty() == false) {
206 EXPECT_EQ(tsHit, true)
207 << "TimeStamp not recognized";
208 } else {
209 std::cout << "[ INFO ] Received non-zero "
210 "output / TimeStamp not recognized \n";
211 }
212 }
213 }
214 #define WRITE_OUTPUT 0
215 #if WRITE_OUTPUT
216 static int count = 0;
217 FILE* ofp = nullptr;
218 if (count)
219 ofp = fopen("out.bin", "ab");
220 else
221 ofp = fopen("out.bin", "wb");
222 if (ofp != nullptr &&
223 portMode[1] == PortMode::PRESET_BYTE_BUFFER) {
224 fwrite(static_cast<void*>(buffer->mMemory->getPointer()),
225 sizeof(char),
226 msg.data.extendedBufferData.rangeLength, ofp);
227 fclose(ofp);
228 count++;
229 }
230 #endif
231 }
232 } else if (msg.type == Message::Type::EVENT) {
233 if (msg.data.eventData.event == OMX_EventPortSettingsChanged) {
234 if ((msg.data.eventData.data2 == OMX_IndexParamPortDefinition ||
235 msg.data.eventData.data2 == 0)) {
236 portSettingsChange = true;
237 }
238 }
239 }
240 }
241
242 enum standardComp {
243 h263,
244 avc,
245 mpeg2,
246 mpeg4,
247 hevc,
248 vp8,
249 vp9,
250 unknown_comp,
251 };
252
253 std::string component_;
254 std::string role_;
255 std::string instance_;
256
257 sp<IOmx> omx;
258 sp<CodecObserver> observer;
259 sp<IOmxNode> omxNode;
260 standardComp compName;
261 OMX_VIDEO_CODINGTYPE eCompressionFormat;
262 bool disableTest;
263 PortMode portMode[2];
264 bool eosFlag;
265 uint32_t framesReceived;
266 uint64_t timestampUs;
267 ::android::List<uint64_t> timestampUslist;
268 bool timestampDevTest;
269 bool isSecure;
270 bool portSettingsChange;
271
272 protected:
description(const std::string & description)273 static void description(const std::string& description) {
274 RecordProperty("description", description);
275 }
276 };
277
278 // Set Default port param.
setDefaultPortParam(sp<IOmxNode> omxNode,OMX_U32 portIndex,OMX_VIDEO_CODINGTYPE eCompressionFormat,OMX_COLOR_FORMATTYPE eColorFormat,OMX_U32 nFrameWidth=352,OMX_U32 nFrameHeight=288,OMX_U32 nBitrate=0,OMX_U32 xFramerate=(24U<<16))279 void setDefaultPortParam(sp<IOmxNode> omxNode, OMX_U32 portIndex,
280 OMX_VIDEO_CODINGTYPE eCompressionFormat,
281 OMX_COLOR_FORMATTYPE eColorFormat,
282 OMX_U32 nFrameWidth = 352, OMX_U32 nFrameHeight = 288,
283 OMX_U32 nBitrate = 0,
284 OMX_U32 xFramerate = (24U << 16)) {
285 switch ((int)eCompressionFormat) {
286 case OMX_VIDEO_CodingUnused:
287 setupRAWPort(omxNode, portIndex, nFrameWidth, nFrameHeight,
288 nBitrate, xFramerate, eColorFormat);
289 break;
290 default:
291 break;
292 }
293 }
294
295 // In decoder components, often the input port parameters get updated upon
296 // parsing the header of elementary stream. Client needs to collect this
297 // information to reconfigure other ports that share data with this input
298 // port.
getInputChannelInfo(sp<IOmxNode> omxNode,OMX_U32 kPortIndexInput,uint32_t * nFrameWidth,uint32_t * nFrameHeight,uint32_t * xFramerate)299 void getInputChannelInfo(sp<IOmxNode> omxNode, OMX_U32 kPortIndexInput,
300 uint32_t* nFrameWidth, uint32_t* nFrameHeight,
301 uint32_t* xFramerate) {
302 android::hardware::media::omx::V1_0::Status status;
303 *nFrameWidth = 352;
304 *nFrameHeight = 288;
305 *xFramerate = (24U << 16);
306
307 OMX_PARAM_PORTDEFINITIONTYPE portDef;
308 status = getPortParam(omxNode, OMX_IndexParamPortDefinition,
309 kPortIndexInput, &portDef);
310 EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
311 if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
312 *nFrameWidth = portDef.format.video.nFrameWidth;
313 *nFrameHeight = portDef.format.video.nFrameHeight;
314 *xFramerate = portDef.format.video.xFramerate;
315 }
316 }
317
318 // number of elementary streams per component
319 #define STREAM_COUNT 2
320 // LookUpTable of clips and metadata for component testing
GetURLForComponent(VideoDecHidlTest::standardComp comp,char * mURL,char * info,size_t streamIndex=1)321 void GetURLForComponent(VideoDecHidlTest::standardComp comp, char* mURL,
322 char* info, size_t streamIndex = 1) {
323 struct CompToURL {
324 VideoDecHidlTest::standardComp comp;
325 const char mURL[STREAM_COUNT][512];
326 const char info[STREAM_COUNT][512];
327 };
328 ASSERT_TRUE(streamIndex < STREAM_COUNT);
329
330 static const CompToURL kCompToURL[] = {
331 {VideoDecHidlTest::standardComp::avc,
332 {"bbb_avc_176x144_300kbps_60fps.h264",
333 "bbb_avc_640x360_768kbps_30fps.h264"},
334 {"bbb_avc_176x144_300kbps_60fps.info",
335 "bbb_avc_640x360_768kbps_30fps.info"}},
336 {VideoDecHidlTest::standardComp::hevc,
337 {"bbb_hevc_176x144_176kbps_60fps.hevc",
338 "bbb_hevc_640x360_1600kbps_30fps.hevc"},
339 {"bbb_hevc_176x144_176kbps_60fps.info",
340 "bbb_hevc_640x360_1600kbps_30fps.info"}},
341 {VideoDecHidlTest::standardComp::mpeg2,
342 {"bbb_mpeg2_176x144_105kbps_25fps.m2v",
343 "bbb_mpeg2_352x288_1mbps_60fps.m2v"},
344 {"bbb_mpeg2_176x144_105kbps_25fps.info",
345 "bbb_mpeg2_352x288_1mbps_60fps.info"}},
346 {VideoDecHidlTest::standardComp::h263,
347 {"", "bbb_h263_352x288_300kbps_12fps.h263"},
348 {"", "bbb_h263_352x288_300kbps_12fps.info"}},
349 {VideoDecHidlTest::standardComp::mpeg4,
350 {"", "bbb_mpeg4_352x288_512kbps_30fps.m4v"},
351 {"", "bbb_mpeg4_352x288_512kbps_30fps.info"}},
352 {VideoDecHidlTest::standardComp::vp8,
353 {"bbb_vp8_176x144_240kbps_60fps.vp8",
354 "bbb_vp8_640x360_2mbps_30fps.vp8"},
355 {"bbb_vp8_176x144_240kbps_60fps.info",
356 "bbb_vp8_640x360_2mbps_30fps.info"}},
357 {VideoDecHidlTest::standardComp::vp9,
358 {"bbb_vp9_176x144_285kbps_60fps.vp9",
359 "bbb_vp9_640x360_1600kbps_30fps.vp9"},
360 {"bbb_vp9_176x144_285kbps_60fps.info",
361 "bbb_vp9_640x360_1600kbps_30fps.info"}},
362 };
363
364 for (size_t i = 0; i < sizeof(kCompToURL) / sizeof(kCompToURL[0]); ++i) {
365 if (kCompToURL[i].comp == comp) {
366 strcat(mURL, kCompToURL[i].mURL[streamIndex]);
367 strcat(info, kCompToURL[i].info[streamIndex]);
368 return;
369 }
370 }
371 }
372
373 // port settings reconfiguration during runtime. reconfigures frame dimensions
portReconfiguration(sp<IOmxNode> omxNode,sp<CodecObserver> observer,android::Vector<BufferInfo> * iBuffer,android::Vector<BufferInfo> * oBuffer,OMX_U32 kPortIndexInput,OMX_U32 kPortIndexOutput,Message msg,PortMode oPortMode,void * args)374 void portReconfiguration(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
375 android::Vector<BufferInfo>* iBuffer,
376 android::Vector<BufferInfo>* oBuffer,
377 OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput,
378 Message msg, PortMode oPortMode, void* args) {
379 android::hardware::media::omx::V1_0::Status status;
380 (void)args;
381
382 if (msg.data.eventData.event == OMX_EventPortSettingsChanged) {
383 ASSERT_EQ(msg.data.eventData.data1, kPortIndexOutput);
384 if (msg.data.eventData.data2 == OMX_IndexParamPortDefinition ||
385 msg.data.eventData.data2 == 0) {
386 // Components can send various kinds of port settings changed events
387 // all at once. Before committing to a full port reconfiguration,
388 // defer any events waiting in the queue to be addressed to a later
389 // point.
390 android::List<Message> msgQueueDefer;
391 while (1) {
392 status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
393 iBuffer, oBuffer);
394 if (status !=
395 android::hardware::media::omx::V1_0::Status::TIMED_OUT) {
396 msgQueueDefer.push_back(msg);
397 continue;
398 } else
399 break;
400 }
401 status = omxNode->sendCommand(
402 toRawCommandType(OMX_CommandPortDisable), kPortIndexOutput);
403 ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
404
405 status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer,
406 oBuffer);
407 if (status ==
408 android::hardware::media::omx::V1_0::Status::TIMED_OUT) {
409 for (size_t i = 0; i < oBuffer->size(); ++i) {
410 // test if client got all its buffers back
411 EXPECT_EQ((*oBuffer)[i].owner, client);
412 // free the buffers
413 status =
414 omxNode->freeBuffer(kPortIndexOutput, (*oBuffer)[i].id);
415 ASSERT_EQ(status,
416 android::hardware::media::omx::V1_0::Status::OK);
417 }
418 status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
419 iBuffer, oBuffer);
420 ASSERT_EQ(status,
421 android::hardware::media::omx::V1_0::Status::OK);
422 ASSERT_EQ(msg.type, Message::Type::EVENT);
423 ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
424 ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortDisable);
425 ASSERT_EQ(msg.data.eventData.data2, kPortIndexOutput);
426
427 // set Port Params
428 uint32_t nFrameWidth, nFrameHeight, xFramerate;
429 getInputChannelInfo(omxNode, kPortIndexInput, &nFrameWidth,
430 &nFrameHeight, &xFramerate);
431 // get configured color format
432 OMX_PARAM_PORTDEFINITIONTYPE portDef;
433 status = getPortParam(omxNode, OMX_IndexParamPortDefinition,
434 kPortIndexOutput, &portDef);
435 setDefaultPortParam(omxNode, kPortIndexOutput,
436 OMX_VIDEO_CodingUnused,
437 portDef.format.video.eColorFormat,
438 nFrameWidth, nFrameHeight, 0, xFramerate);
439
440 // If you can disable a port, then you should be able to
441 // enable it as well
442 status = omxNode->sendCommand(
443 toRawCommandType(OMX_CommandPortEnable), kPortIndexOutput);
444 ASSERT_EQ(status,
445 android::hardware::media::omx::V1_0::Status::OK);
446
447 // do not enable the port until all the buffers are supplied
448 status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
449 iBuffer, oBuffer);
450 ASSERT_EQ(
451 status,
452 android::hardware::media::omx::V1_0::Status::TIMED_OUT);
453
454 ASSERT_NO_FATAL_FAILURE(freePortBuffers(oBuffer, oPortMode, true));
455 ASSERT_NO_FATAL_FAILURE(allocatePortBuffers(
456 omxNode, oBuffer, kPortIndexOutput, oPortMode, true));
457 status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
458 iBuffer, oBuffer);
459 ASSERT_EQ(status,
460 android::hardware::media::omx::V1_0::Status::OK);
461 ASSERT_EQ(msg.type, Message::Type::EVENT);
462 ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortEnable);
463 ASSERT_EQ(msg.data.eventData.data2, kPortIndexOutput);
464
465 // Push back deferred messages to the list
466 android::List<Message>::iterator it = msgQueueDefer.begin();
467 while (it != msgQueueDefer.end()) {
468 status = omxNode->dispatchMessage(*it);
469 ASSERT_EQ(
470 status,
471 ::android::hardware::media::omx::V1_0::Status::OK);
472 it++;
473 }
474
475 // dispatch output buffers
476 for (size_t i = 0; i < oBuffer->size(); i++) {
477 ASSERT_NO_FATAL_FAILURE(
478 dispatchOutputBuffer(omxNode, oBuffer, i, oPortMode));
479 }
480 } else {
481 ASSERT_TRUE(false);
482 }
483 } else if (msg.data.eventData.data2 ==
484 OMX_IndexConfigCommonOutputCrop) {
485 std::cout << "[ INFO ] OMX_EventPortSettingsChanged/ "
486 "OMX_IndexConfigCommonOutputCrop not handled \n";
487 } else if (msg.data.eventData.data2 == OMX_IndexVendorStartUnused + 3) {
488 std::cout << "[ INFO ] OMX_EventPortSettingsChanged/ "
489 "kDescribeColorAspectsIndex not handled \n";
490 }
491 } else if (msg.data.eventData.event == OMX_EventError) {
492 std::cerr << "[ ERROR ] OMX_EventError/ "
493 "Decode Frame Call might be failed \n";
494 ASSERT_TRUE(false);
495 } else {
496 // something unexpected happened
497 ASSERT_TRUE(false);
498 }
499 }
500
501 // blocking call to ensures application to Wait till all the inputs are consumed
waitOnInputConsumption(sp<IOmxNode> omxNode,sp<CodecObserver> observer,android::Vector<BufferInfo> * iBuffer,android::Vector<BufferInfo> * oBuffer,OMX_U32 kPortIndexInput,OMX_U32 kPortIndexOutput,PortMode oPortMode)502 void waitOnInputConsumption(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
503 android::Vector<BufferInfo>* iBuffer,
504 android::Vector<BufferInfo>* oBuffer,
505 OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput,
506 PortMode oPortMode) {
507 android::hardware::media::omx::V1_0::Status status;
508 Message msg;
509 int timeOut = TIMEOUT_COUNTER_Q;
510
511 while (timeOut--) {
512 size_t i = 0;
513 status =
514 observer->dequeueMessage(&msg, DEFAULT_TIMEOUT_Q, iBuffer, oBuffer);
515 if (status == android::hardware::media::omx::V1_0::Status::OK) {
516 ASSERT_EQ(msg.type, Message::Type::EVENT);
517 ASSERT_NO_FATAL_FAILURE(portReconfiguration(
518 omxNode, observer, iBuffer, oBuffer, kPortIndexInput,
519 kPortIndexOutput, msg, oPortMode, nullptr));
520 }
521 // status == TIMED_OUT, it could be due to process time being large
522 // than DEFAULT_TIMEOUT or component needs output buffers to start
523 // processing.
524 for (; i < iBuffer->size(); i++) {
525 if ((*iBuffer)[i].owner != client) break;
526 }
527 if (i == iBuffer->size()) break;
528
529 // Dispatch an output buffer assuming outQueue.empty() is true
530 size_t index;
531 if ((index = getEmptyBufferID(oBuffer)) < oBuffer->size()) {
532 ASSERT_NO_FATAL_FAILURE(
533 dispatchOutputBuffer(omxNode, oBuffer, index, oPortMode));
534 timeOut = TIMEOUT_COUNTER_Q;
535 }
536 }
537 }
538
539 // Decode N Frames
decodeNFrames(sp<IOmxNode> omxNode,sp<CodecObserver> observer,android::Vector<BufferInfo> * iBuffer,android::Vector<BufferInfo> * oBuffer,OMX_U32 kPortIndexInput,OMX_U32 kPortIndexOutput,std::ifstream & eleStream,android::Vector<FrameData> * Info,int offset,int range,PortMode oPortMode,bool signalEOS=true)540 void decodeNFrames(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
541 android::Vector<BufferInfo>* iBuffer,
542 android::Vector<BufferInfo>* oBuffer,
543 OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput,
544 std::ifstream& eleStream, android::Vector<FrameData>* Info,
545 int offset, int range, PortMode oPortMode,
546 bool signalEOS = true) {
547 android::hardware::media::omx::V1_0::Status status;
548 Message msg;
549 size_t index;
550 uint32_t flags = 0;
551 int frameID = offset;
552 int timeOut = TIMEOUT_COUNTER_Q;
553 bool iQueued, oQueued;
554
555 while (1) {
556 iQueued = oQueued = false;
557 status =
558 observer->dequeueMessage(&msg, DEFAULT_TIMEOUT_Q, iBuffer, oBuffer);
559 // Port Reconfiguration
560 if (status == android::hardware::media::omx::V1_0::Status::OK &&
561 msg.type == Message::Type::EVENT) {
562 ASSERT_NO_FATAL_FAILURE(portReconfiguration(
563 omxNode, observer, iBuffer, oBuffer, kPortIndexInput,
564 kPortIndexOutput, msg, oPortMode, nullptr));
565 }
566
567 if (frameID == (int)Info->size() || frameID == (offset + range)) break;
568
569 // Dispatch input buffer
570 if ((index = getEmptyBufferID(iBuffer)) < iBuffer->size()) {
571 char* ipBuffer = static_cast<char*>(
572 static_cast<void*>((*iBuffer)[index].mMemory->getPointer()));
573 ASSERT_LE((*Info)[frameID].bytesCount,
574 static_cast<int>((*iBuffer)[index].mMemory->getSize()));
575 eleStream.read(ipBuffer, (*Info)[frameID].bytesCount);
576 ASSERT_EQ(eleStream.gcount(), (*Info)[frameID].bytesCount);
577 flags = (*Info)[frameID].flags;
578 // Indicate to omx core that the buffer contains a full frame worth
579 // of data
580 flags |= OMX_BUFFERFLAG_ENDOFFRAME;
581 // Indicate the omx core that this is the last buffer it needs to
582 // process
583 if (signalEOS && ((frameID == (int)Info->size() - 1) ||
584 (frameID == (offset + range - 1))))
585 flags |= OMX_BUFFERFLAG_EOS;
586 ASSERT_NO_FATAL_FAILURE(dispatchInputBuffer(
587 omxNode, iBuffer, index, (*Info)[frameID].bytesCount, flags,
588 (*Info)[frameID].timestamp));
589 frameID++;
590 iQueued = true;
591 }
592 // Dispatch output buffer
593 if ((index = getEmptyBufferID(oBuffer)) < oBuffer->size()) {
594 ASSERT_NO_FATAL_FAILURE(
595 dispatchOutputBuffer(omxNode, oBuffer, index, oPortMode));
596 oQueued = true;
597 }
598 // Reset Counters when either input or output buffer is dispatched
599 if (iQueued || oQueued)
600 timeOut = TIMEOUT_COUNTER_Q;
601 else
602 timeOut--;
603 if (timeOut == 0) {
604 ASSERT_TRUE(false) << "Wait on Input/Output is found indefinite";
605 }
606 }
607 }
608
609 // DescribeColorFormatParams Copy Constructor (Borrowed from OMXUtils.cpp)
DescribeColorFormatParams(const android::DescribeColorFormat2Params & params)610 android::DescribeColorFormatParams::DescribeColorFormatParams(
611 const android::DescribeColorFormat2Params& params) {
612 eColorFormat = params.eColorFormat;
613 nFrameWidth = params.nFrameWidth;
614 nFrameHeight = params.nFrameHeight;
615 nStride = params.nStride;
616 nSliceHeight = params.nSliceHeight;
617 bUsingNativeBuffers = params.bUsingNativeBuffers;
618 };
619
isColorFormatFlexibleYUV(sp<IOmxNode> omxNode,OMX_COLOR_FORMATTYPE eColorFormat)620 bool isColorFormatFlexibleYUV(sp<IOmxNode> omxNode,
621 OMX_COLOR_FORMATTYPE eColorFormat) {
622 android::hardware::media::omx::V1_0::Status status;
623 unsigned int index = OMX_IndexMax, index2 = OMX_IndexMax;
624 omxNode->getExtensionIndex(
625 "OMX.google.android.index.describeColorFormat",
626 [&index](android::hardware::media::omx::V1_0::Status _s,
627 unsigned int _nl) {
628 if (_s == ::android::hardware::media::omx::V1_0::Status::OK)
629 index = _nl;
630 });
631 omxNode->getExtensionIndex(
632 "OMX.google.android.index.describeColorFormat2",
633 [&index2](android::hardware::media::omx::V1_0::Status _s,
634 unsigned int _nl) {
635 if (_s == ::android::hardware::media::omx::V1_0::Status::OK)
636 index2 = _nl;
637 });
638
639 android::DescribeColorFormat2Params describeParams;
640 describeParams.eColorFormat = eColorFormat;
641 describeParams.nFrameWidth = 128;
642 describeParams.nFrameHeight = 128;
643 describeParams.nStride = 128;
644 describeParams.nSliceHeight = 128;
645 describeParams.bUsingNativeBuffers = OMX_FALSE;
646 if (index != OMX_IndexMax) {
647 android::DescribeColorFormatParams describeParamsV1(describeParams);
648 status = getParam(omxNode, static_cast<OMX_INDEXTYPE>(index),
649 &describeParamsV1);
650 if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
651 android::MediaImage& img = describeParamsV1.sMediaImage;
652 if (img.mType == android::MediaImage::MEDIA_IMAGE_TYPE_YUV) {
653 if (img.mNumPlanes == 3 &&
654 img.mPlane[img.Y].mHorizSubsampling == 1 &&
655 img.mPlane[img.Y].mVertSubsampling == 1) {
656 if (img.mPlane[img.U].mHorizSubsampling == 2 &&
657 img.mPlane[img.U].mVertSubsampling == 2 &&
658 img.mPlane[img.V].mHorizSubsampling == 2 &&
659 img.mPlane[img.V].mVertSubsampling == 2) {
660 if (img.mBitDepth <= 8) {
661 return true;
662 }
663 }
664 }
665 }
666 }
667 } else if (index2 != OMX_IndexMax) {
668 status = getParam(omxNode, static_cast<OMX_INDEXTYPE>(index2),
669 &describeParams);
670 android::MediaImage2& img = describeParams.sMediaImage;
671 if (img.mType == android::MediaImage2::MEDIA_IMAGE_TYPE_YUV) {
672 if (img.mNumPlanes == 3 &&
673 img.mPlane[img.Y].mHorizSubsampling == 1 &&
674 img.mPlane[img.Y].mVertSubsampling == 1) {
675 if (img.mPlane[img.U].mHorizSubsampling == 2 &&
676 img.mPlane[img.U].mVertSubsampling == 2 &&
677 img.mPlane[img.V].mHorizSubsampling == 2 &&
678 img.mPlane[img.V].mVertSubsampling == 2) {
679 if (img.mBitDepth <= 8) {
680 return true;
681 }
682 }
683 }
684 }
685 }
686 return false;
687 }
688
689 // get default color format for output port
getDefaultColorFormat(sp<IOmxNode> omxNode,OMX_U32 kPortIndexOutput,PortMode oPortMode,OMX_COLOR_FORMATTYPE * eColorFormat)690 void getDefaultColorFormat(sp<IOmxNode> omxNode, OMX_U32 kPortIndexOutput,
691 PortMode oPortMode,
692 OMX_COLOR_FORMATTYPE* eColorFormat) {
693 android::hardware::media::omx::V1_0::Status status;
694 OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat;
695 *eColorFormat = OMX_COLOR_FormatUnused;
696 portFormat.nIndex = 0;
697 while (portFormat.nIndex < 512) {
698 status = getPortParam(omxNode, OMX_IndexParamVideoPortFormat,
699 kPortIndexOutput, &portFormat);
700 if (status != ::android::hardware::media::omx::V1_0::Status::OK) break;
701 EXPECT_EQ(portFormat.eCompressionFormat, OMX_VIDEO_CodingUnused);
702 if (oPortMode != PortMode::PRESET_BYTE_BUFFER) {
703 *eColorFormat = portFormat.eColorFormat;
704 break;
705 }
706 if (isColorFormatFlexibleYUV(omxNode, portFormat.eColorFormat)) {
707 *eColorFormat = portFormat.eColorFormat;
708 break;
709 }
710 if (OMX_COLOR_FormatYUV420SemiPlanar == portFormat.eColorFormat ||
711 OMX_COLOR_FormatYUV420Planar == portFormat.eColorFormat ||
712 OMX_COLOR_FormatYUV420PackedPlanar == portFormat.eColorFormat ||
713 OMX_COLOR_FormatYUV420PackedSemiPlanar == portFormat.eColorFormat) {
714 *eColorFormat = portFormat.eColorFormat;
715 break;
716 }
717 portFormat.nIndex++;
718 }
719 }
720
721 // set component role
TEST_P(VideoDecHidlTest,SetRole)722 TEST_P(VideoDecHidlTest, SetRole) {
723 description("Test Set Component Role");
724 if (disableTest) return;
725 android::hardware::media::omx::V1_0::Status status;
726 status = setRole(omxNode, role_);
727 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
728 }
729
730 // port format enumeration
TEST_P(VideoDecHidlTest,EnumeratePortFormat)731 TEST_P(VideoDecHidlTest, EnumeratePortFormat) {
732 description("Test Component on Mandatory Port Parameters (Port Format)");
733 if (disableTest) return;
734 android::hardware::media::omx::V1_0::Status status;
735 uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
736 OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatYUV420Planar;
737 OMX_U32 xFramerate = (24U << 16);
738 status = setRole(omxNode, role_);
739 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
740 OMX_PORT_PARAM_TYPE params;
741 status = getParam(omxNode, OMX_IndexParamVideoInit, ¶ms);
742 if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
743 ASSERT_EQ(params.nPorts, 2U);
744 kPortIndexInput = params.nStartPortNumber;
745 kPortIndexOutput = kPortIndexInput + 1;
746 }
747 status = setVideoPortFormat(omxNode, kPortIndexInput, eCompressionFormat,
748 OMX_COLOR_FormatUnused, 0U);
749 EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
750 status =
751 setVideoPortFormat(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
752 eColorFormat, xFramerate);
753 EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
754 }
755
756 // test port settings reconfiguration, elementary stream decode and timestamp
757 // deviation
TEST_P(VideoDecHidlTest,DecodeTest)758 TEST_P(VideoDecHidlTest, DecodeTest) {
759 description("Tests Port Reconfiguration, Decode and timestamp deviation");
760 if (disableTest) return;
761 android::hardware::media::omx::V1_0::Status status;
762 uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
763 status = setRole(omxNode, role_);
764 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
765 OMX_PORT_PARAM_TYPE params;
766 status = getParam(omxNode, OMX_IndexParamVideoInit, ¶ms);
767 if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
768 ASSERT_EQ(params.nPorts, 2U);
769 kPortIndexInput = params.nStartPortNumber;
770 kPortIndexOutput = kPortIndexInput + 1;
771 }
772 char mURL[512], info[512];
773 strcpy(mURL, sResourceDir.c_str());
774 strcpy(info, sResourceDir.c_str());
775 GetURLForComponent(compName, mURL, info);
776
777 std::ifstream eleStream, eleInfo;
778
779 eleInfo.open(info);
780 ASSERT_EQ(eleInfo.is_open(), true);
781 android::Vector<FrameData> Info;
782 int bytesCount = 0, maxBytesCount = 0;
783 uint32_t flags = 0;
784 uint32_t timestamp = 0;
785 timestampDevTest = true;
786 while (1) {
787 if (!(eleInfo >> bytesCount)) break;
788 eleInfo >> flags;
789 eleInfo >> timestamp;
790 Info.push_back({bytesCount, flags, timestamp});
791 if (timestampDevTest && (flags != OMX_BUFFERFLAG_CODECCONFIG))
792 timestampUslist.push_back(timestamp);
793 if (maxBytesCount < bytesCount) maxBytesCount = bytesCount;
794 }
795 eleInfo.close();
796
797 // As the frame sizes are known ahead, use it to configure i/p buffer size
798 maxBytesCount = ALIGN_POWER_OF_TWO(maxBytesCount, 10);
799 status = setPortBufferSize(omxNode, kPortIndexInput, maxBytesCount);
800 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
801
802 // set port mode
803 portMode[0] = PortMode::PRESET_BYTE_BUFFER;
804 portMode[1] = PortMode::DYNAMIC_ANW_BUFFER;
805 status = omxNode->setPortMode(kPortIndexInput, portMode[0]);
806 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
807 status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
808 if (status != ::android::hardware::media::omx::V1_0::Status::OK) {
809 portMode[1] = PortMode::PRESET_BYTE_BUFFER;
810 status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
811 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
812 }
813
814 // set Port Params
815 uint32_t nFrameWidth, nFrameHeight, xFramerate;
816 getInputChannelInfo(omxNode, kPortIndexInput, &nFrameWidth, &nFrameHeight,
817 &xFramerate);
818 // get default color format
819 OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatUnused;
820 getDefaultColorFormat(omxNode, kPortIndexOutput, portMode[1],
821 &eColorFormat);
822 ASSERT_NE(eColorFormat, OMX_COLOR_FormatUnused);
823 status =
824 setVideoPortFormat(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
825 eColorFormat, xFramerate);
826 EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
827 setDefaultPortParam(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
828 eColorFormat, nFrameWidth, nFrameHeight, 0, xFramerate);
829
830 android::Vector<BufferInfo> iBuffer, oBuffer;
831
832 // set state to idle
833 ASSERT_NO_FATAL_FAILURE(changeStateLoadedtoIdle(
834 omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
835 kPortIndexOutput, portMode, true));
836 // set state to executing
837 ASSERT_NO_FATAL_FAILURE(changeStateIdletoExecute(omxNode, observer));
838
839 // Port Reconfiguration
840 eleStream.open(mURL, std::ifstream::binary);
841 ASSERT_EQ(eleStream.is_open(), true);
842 ASSERT_NO_FATAL_FAILURE(decodeNFrames(
843 omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
844 kPortIndexOutput, eleStream, &Info, 0, (int)Info.size(), portMode[1]));
845 eleStream.close();
846 ASSERT_NO_FATAL_FAILURE(
847 waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer,
848 kPortIndexInput, kPortIndexOutput, portMode[1]));
849 ASSERT_NO_FATAL_FAILURE(testEOS(
850 omxNode, observer, &iBuffer, &oBuffer, false, eosFlag, portMode,
851 portReconfiguration, kPortIndexInput, kPortIndexOutput, nullptr));
852 if (timestampDevTest) EXPECT_EQ(timestampUslist.empty(), true);
853 // set state to idle
854 ASSERT_NO_FATAL_FAILURE(
855 changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer));
856 // set state to executing
857 ASSERT_NO_FATAL_FAILURE(changeStateIdletoLoaded(omxNode, observer, &iBuffer, &oBuffer,
858 kPortIndexInput, kPortIndexOutput, portMode,
859 true));
860 }
861
862 // Test for adaptive playback support
TEST_P(VideoDecHidlTest,AdaptivePlaybackTest)863 TEST_P(VideoDecHidlTest, AdaptivePlaybackTest) {
864 description("Tests for Adaptive Playback support");
865 if (disableTest) return;
866 if (!(compName == avc || compName == hevc || compName == vp8 ||
867 compName == vp9 || compName == mpeg2))
868 return;
869 android::hardware::media::omx::V1_0::Status status;
870 uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
871 status = setRole(omxNode, role_);
872 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
873 OMX_PORT_PARAM_TYPE params;
874 status = getParam(omxNode, OMX_IndexParamVideoInit, ¶ms);
875 if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
876 ASSERT_EQ(params.nPorts, 2U);
877 kPortIndexInput = params.nStartPortNumber;
878 kPortIndexOutput = kPortIndexInput + 1;
879 }
880
881 // set port mode
882 portMode[0] = PortMode::PRESET_BYTE_BUFFER;
883 portMode[1] = PortMode::DYNAMIC_ANW_BUFFER;
884 status = omxNode->setPortMode(kPortIndexInput, portMode[0]);
885 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
886 status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
887 if (status != ::android::hardware::media::omx::V1_0::Status::OK) {
888 portMode[1] = PortMode::PRESET_BYTE_BUFFER;
889 status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
890 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
891 }
892
893 // prepare for adaptive playback
894 uint32_t adaptiveMaxWidth = 320;
895 uint32_t adaptiveMaxHeight = 240;
896 status = omxNode->prepareForAdaptivePlayback(
897 kPortIndexOutput, true, adaptiveMaxWidth, adaptiveMaxHeight);
898 if (component_.find("OMX.google.") == 0) {
899 // SoftOMX Decoders donot support graphic buffer modes. So for them
900 // support for adaptive play back is mandatory in Byte Buffer mode
901 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
902 } else {
903 // for vendor codecs, support for adaptive play back is optional
904 // in byte buffer mode.
905 if (portMode[1] == PortMode::PRESET_BYTE_BUFFER) return;
906 if (status != ::android::hardware::media::omx::V1_0::Status::OK) return;
907 }
908
909 // TODO: Handle this better !!!
910 // Without the knowledge of the maximum resolution of the frame to be
911 // decoded it is not possible to choose the size of the input buffer.
912 // The value below is based on the info. files of clips in res folder.
913 status = setPortBufferSize(omxNode, kPortIndexInput, 482304);
914 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
915
916 // set Port Params
917 uint32_t nFrameWidth, nFrameHeight, xFramerate;
918 getInputChannelInfo(omxNode, kPortIndexInput, &nFrameWidth, &nFrameHeight,
919 &xFramerate);
920 // get default color format
921 OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatUnused;
922 getDefaultColorFormat(omxNode, kPortIndexOutput, portMode[1],
923 &eColorFormat);
924 ASSERT_NE(eColorFormat, OMX_COLOR_FormatUnused);
925 status =
926 setVideoPortFormat(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
927 eColorFormat, xFramerate);
928 EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
929 setDefaultPortParam(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
930 eColorFormat, nFrameWidth, nFrameHeight, 0, xFramerate);
931
932 android::Vector<BufferInfo> iBuffer, oBuffer;
933
934 // set state to idle
935 ASSERT_NO_FATAL_FAILURE(changeStateLoadedtoIdle(
936 omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
937 kPortIndexOutput, portMode, true));
938 // set state to executing
939 ASSERT_NO_FATAL_FAILURE(changeStateIdletoExecute(omxNode, observer));
940
941 timestampDevTest = true;
942 uint32_t timestampOffset = 0;
943 for (uint32_t i = 0; i < STREAM_COUNT * 2; i++) {
944 std::ifstream eleStream, eleInfo;
945 char mURL[512], info[512];
946 android::Vector<FrameData> Info;
947 strcpy(mURL, sResourceDir.c_str());
948 strcpy(info, sResourceDir.c_str());
949 GetURLForComponent(compName, mURL, info, i % STREAM_COUNT);
950 eleInfo.open(info);
951 ASSERT_EQ(eleInfo.is_open(), true);
952 int bytesCount = 0;
953 uint32_t flags = 0;
954 uint32_t timestamp = 0;
955 uint32_t timestampMax = 0;
956 while (1) {
957 if (!(eleInfo >> bytesCount)) break;
958 eleInfo >> flags;
959 eleInfo >> timestamp;
960 timestamp += timestampOffset;
961 Info.push_back({bytesCount, flags, timestamp});
962 if (timestampDevTest && (flags != OMX_BUFFERFLAG_CODECCONFIG))
963 timestampUslist.push_back(timestamp);
964 if (timestampMax < timestamp) timestampMax = timestamp;
965 }
966 timestampOffset = timestampMax;
967 eleInfo.close();
968
969 // Port Reconfiguration
970 eleStream.open(mURL, std::ifstream::binary);
971 ASSERT_EQ(eleStream.is_open(), true);
972 ASSERT_NO_FATAL_FAILURE(
973 decodeNFrames(omxNode, observer, &iBuffer, &oBuffer,
974 kPortIndexInput, kPortIndexOutput, eleStream, &Info,
975 0, (int)Info.size(), portMode[1], false));
976 eleStream.close();
977
978 getInputChannelInfo(omxNode, kPortIndexInput, &nFrameWidth,
979 &nFrameHeight, &xFramerate);
980 if ((nFrameWidth > adaptiveMaxWidth) ||
981 (nFrameHeight > adaptiveMaxHeight)) {
982 if (nFrameWidth > adaptiveMaxWidth) adaptiveMaxWidth = nFrameWidth;
983 if (nFrameHeight > adaptiveMaxHeight)
984 adaptiveMaxHeight = nFrameHeight;
985 EXPECT_TRUE(portSettingsChange);
986 } else {
987 // In DynamicANW Buffer mode, its ok to do a complete
988 // reconfiguration even if a partial reconfiguration is sufficient.
989 if (portMode[1] != PortMode::DYNAMIC_ANW_BUFFER)
990 EXPECT_FALSE(portSettingsChange);
991 }
992 portSettingsChange = false;
993 }
994 ASSERT_NO_FATAL_FAILURE(
995 waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer,
996 kPortIndexInput, kPortIndexOutput, portMode[1]));
997 ASSERT_NO_FATAL_FAILURE(testEOS(
998 omxNode, observer, &iBuffer, &oBuffer, true, eosFlag, portMode,
999 portReconfiguration, kPortIndexInput, kPortIndexOutput, nullptr));
1000 if (timestampDevTest) EXPECT_EQ(timestampUslist.empty(), true);
1001 // set state to idle
1002 ASSERT_NO_FATAL_FAILURE(
1003 changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer));
1004 // set state to executing
1005 ASSERT_NO_FATAL_FAILURE(changeStateIdletoLoaded(omxNode, observer, &iBuffer, &oBuffer,
1006 kPortIndexInput, kPortIndexOutput, portMode,
1007 true));
1008 }
1009
1010 // end of sequence test
TEST_P(VideoDecHidlTest,EOSTest_M)1011 TEST_P(VideoDecHidlTest, EOSTest_M) {
1012 description("Test End of stream monkeying");
1013 if (disableTest) return;
1014 android::hardware::media::omx::V1_0::Status status;
1015 uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
1016 status = setRole(omxNode, role_);
1017 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1018 OMX_PORT_PARAM_TYPE params;
1019 status = getParam(omxNode, OMX_IndexParamVideoInit, ¶ms);
1020 if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
1021 ASSERT_EQ(params.nPorts, 2U);
1022 kPortIndexInput = params.nStartPortNumber;
1023 kPortIndexOutput = kPortIndexInput + 1;
1024 }
1025
1026 // set port mode
1027 status = omxNode->setPortMode(kPortIndexInput, portMode[0]);
1028 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1029 status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
1030 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1031
1032 // set Port Params
1033 uint32_t nFrameWidth, nFrameHeight, xFramerate;
1034 getInputChannelInfo(omxNode, kPortIndexInput, &nFrameWidth, &nFrameHeight,
1035 &xFramerate);
1036 // get default color format
1037 OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatUnused;
1038 getDefaultColorFormat(omxNode, kPortIndexOutput, portMode[1],
1039 &eColorFormat);
1040 ASSERT_NE(eColorFormat, OMX_COLOR_FormatUnused);
1041 status =
1042 setVideoPortFormat(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
1043 eColorFormat, xFramerate);
1044 EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1045 setDefaultPortParam(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
1046 eColorFormat, nFrameWidth, nFrameHeight, 0, xFramerate);
1047
1048 android::Vector<BufferInfo> iBuffer, oBuffer;
1049
1050 // set state to idle
1051 ASSERT_NO_FATAL_FAILURE(changeStateLoadedtoIdle(
1052 omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
1053 kPortIndexOutput, portMode, true));
1054 // set state to executing
1055 ASSERT_NO_FATAL_FAILURE(changeStateIdletoExecute(omxNode, observer));
1056
1057 // request EOS at the start
1058 ASSERT_NO_FATAL_FAILURE(testEOS(
1059 omxNode, observer, &iBuffer, &oBuffer, true, eosFlag, portMode,
1060 portReconfiguration, kPortIndexInput, kPortIndexOutput, nullptr));
1061 ASSERT_NO_FATAL_FAILURE(flushPorts(omxNode, observer, &iBuffer, &oBuffer,
1062 kPortIndexInput, kPortIndexOutput));
1063 EXPECT_GE(framesReceived, 0U);
1064 framesReceived = 0;
1065 timestampUs = 0;
1066
1067 // set state to idle
1068 ASSERT_NO_FATAL_FAILURE(
1069 changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer));
1070 // set state to executing
1071 ASSERT_NO_FATAL_FAILURE(changeStateIdletoLoaded(omxNode, observer, &iBuffer, &oBuffer,
1072 kPortIndexInput, kPortIndexOutput, portMode,
1073 true));
1074 }
1075
1076 // end of sequence test
TEST_P(VideoDecHidlTest,ThumbnailTest)1077 TEST_P(VideoDecHidlTest, ThumbnailTest) {
1078 description("Test Request for thumbnail");
1079 if (disableTest) return;
1080 android::hardware::media::omx::V1_0::Status status;
1081 uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
1082 status = setRole(omxNode, role_);
1083 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1084 OMX_PORT_PARAM_TYPE params;
1085 status = getParam(omxNode, OMX_IndexParamVideoInit, ¶ms);
1086 if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
1087 ASSERT_EQ(params.nPorts, 2U);
1088 kPortIndexInput = params.nStartPortNumber;
1089 kPortIndexOutput = kPortIndexInput + 1;
1090 }
1091 char mURL[512], info[512];
1092 strcpy(mURL, sResourceDir.c_str());
1093 strcpy(info, sResourceDir.c_str());
1094 GetURLForComponent(compName, mURL, info);
1095
1096 std::ifstream eleStream, eleInfo;
1097
1098 eleInfo.open(info);
1099 ASSERT_EQ(eleInfo.is_open(), true);
1100 android::Vector<FrameData> Info;
1101 int bytesCount = 0, maxBytesCount = 0;
1102 uint32_t flags = 0;
1103 uint32_t timestamp = 0;
1104 while (1) {
1105 if (!(eleInfo >> bytesCount)) break;
1106 eleInfo >> flags;
1107 eleInfo >> timestamp;
1108 Info.push_back({bytesCount, flags, timestamp});
1109 if (maxBytesCount < bytesCount) maxBytesCount = bytesCount;
1110 }
1111 eleInfo.close();
1112
1113 // As the frame sizes are known ahead, use it to configure i/p buffer size
1114 maxBytesCount = ALIGN_POWER_OF_TWO(maxBytesCount, 10);
1115 status = setPortBufferSize(omxNode, kPortIndexInput, maxBytesCount);
1116 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1117
1118 // set port mode
1119 status = omxNode->setPortMode(kPortIndexInput, portMode[0]);
1120 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1121 status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
1122 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1123
1124 // set Port Params
1125 uint32_t nFrameWidth, nFrameHeight, xFramerate;
1126 getInputChannelInfo(omxNode, kPortIndexInput, &nFrameWidth, &nFrameHeight,
1127 &xFramerate);
1128 // get default color format
1129 OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatUnused;
1130 getDefaultColorFormat(omxNode, kPortIndexOutput, portMode[1],
1131 &eColorFormat);
1132 ASSERT_NE(eColorFormat, OMX_COLOR_FormatUnused);
1133 status =
1134 setVideoPortFormat(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
1135 eColorFormat, xFramerate);
1136 EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1137 setDefaultPortParam(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
1138 eColorFormat, nFrameWidth, nFrameHeight, 0, xFramerate);
1139
1140 android::Vector<BufferInfo> iBuffer, oBuffer;
1141
1142 // set state to idle
1143 ASSERT_NO_FATAL_FAILURE(changeStateLoadedtoIdle(
1144 omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
1145 kPortIndexOutput, portMode, true));
1146 // set state to executing
1147 ASSERT_NO_FATAL_FAILURE(changeStateIdletoExecute(omxNode, observer));
1148
1149 // request EOS for thumbnail
1150 size_t i = 0;
1151 while (!(Info[i].flags & OMX_BUFFERFLAG_SYNCFRAME)) i++;
1152 eleStream.open(mURL, std::ifstream::binary);
1153 ASSERT_EQ(eleStream.is_open(), true);
1154 ASSERT_NO_FATAL_FAILURE(decodeNFrames(
1155 omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
1156 kPortIndexOutput, eleStream, &Info, 0, i + 1, portMode[1]));
1157 eleStream.close();
1158 ASSERT_NO_FATAL_FAILURE(
1159 waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer,
1160 kPortIndexInput, kPortIndexOutput, portMode[1]));
1161 ASSERT_NO_FATAL_FAILURE(testEOS(
1162 omxNode, observer, &iBuffer, &oBuffer, false, eosFlag, portMode,
1163 portReconfiguration, kPortIndexInput, kPortIndexOutput, nullptr));
1164 ASSERT_NO_FATAL_FAILURE(flushPorts(omxNode, observer, &iBuffer, &oBuffer,
1165 kPortIndexInput, kPortIndexOutput));
1166 EXPECT_GE(framesReceived, 1U);
1167 framesReceived = 0;
1168 timestampUs = 0;
1169
1170 eleStream.open(mURL, std::ifstream::binary);
1171 ASSERT_EQ(eleStream.is_open(), true);
1172 ASSERT_NO_FATAL_FAILURE(decodeNFrames(
1173 omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
1174 kPortIndexOutput, eleStream, &Info, 0, i + 1, portMode[1], false));
1175 eleStream.close();
1176 ASSERT_NO_FATAL_FAILURE(
1177 waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer,
1178 kPortIndexInput, kPortIndexOutput, portMode[1]));
1179 ASSERT_NO_FATAL_FAILURE(testEOS(
1180 omxNode, observer, &iBuffer, &oBuffer, true, eosFlag, portMode,
1181 portReconfiguration, kPortIndexInput, kPortIndexOutput, nullptr));
1182 ASSERT_NO_FATAL_FAILURE(flushPorts(omxNode, observer, &iBuffer, &oBuffer,
1183 kPortIndexInput, kPortIndexOutput));
1184 EXPECT_GE(framesReceived, 1U);
1185 framesReceived = 0;
1186 timestampUs = 0;
1187
1188 // set state to idle
1189 ASSERT_NO_FATAL_FAILURE(
1190 changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer));
1191 // set state to executing
1192 ASSERT_NO_FATAL_FAILURE(changeStateIdletoLoaded(omxNode, observer, &iBuffer, &oBuffer,
1193 kPortIndexInput, kPortIndexOutput, portMode,
1194 true));
1195 }
1196
1197 // end of sequence test
TEST_P(VideoDecHidlTest,SimpleEOSTest)1198 TEST_P(VideoDecHidlTest, SimpleEOSTest) {
1199 description("Test End of stream");
1200 if (disableTest) return;
1201 android::hardware::media::omx::V1_0::Status status;
1202 uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
1203 status = setRole(omxNode, role_);
1204 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1205 OMX_PORT_PARAM_TYPE params;
1206 status = getParam(omxNode, OMX_IndexParamVideoInit, ¶ms);
1207 if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
1208 ASSERT_EQ(params.nPorts, 2U);
1209 kPortIndexInput = params.nStartPortNumber;
1210 kPortIndexOutput = kPortIndexInput + 1;
1211 }
1212 char mURL[512], info[512];
1213 strcpy(mURL, sResourceDir.c_str());
1214 strcpy(info, sResourceDir.c_str());
1215 GetURLForComponent(compName, mURL, info);
1216
1217 std::ifstream eleStream, eleInfo;
1218
1219 eleInfo.open(info);
1220 ASSERT_EQ(eleInfo.is_open(), true);
1221 android::Vector<FrameData> Info;
1222 int bytesCount = 0, maxBytesCount = 0;
1223 uint32_t flags = 0;
1224 uint32_t timestamp = 0;
1225 while (1) {
1226 if (!(eleInfo >> bytesCount)) break;
1227 eleInfo >> flags;
1228 eleInfo >> timestamp;
1229 Info.push_back({bytesCount, flags, timestamp});
1230 if (maxBytesCount < bytesCount) maxBytesCount = bytesCount;
1231 }
1232 eleInfo.close();
1233
1234 // As the frame sizes are known ahead, use it to configure i/p buffer size
1235 maxBytesCount = ALIGN_POWER_OF_TWO(maxBytesCount, 10);
1236 status = setPortBufferSize(omxNode, kPortIndexInput, maxBytesCount);
1237 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1238
1239 // set port mode
1240 portMode[0] = PortMode::PRESET_BYTE_BUFFER;
1241 portMode[1] = PortMode::PRESET_ANW_BUFFER;
1242 status = omxNode->setPortMode(kPortIndexInput, portMode[0]);
1243 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1244 status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
1245 if (status != ::android::hardware::media::omx::V1_0::Status::OK) {
1246 portMode[1] = PortMode::PRESET_BYTE_BUFFER;
1247 status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
1248 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1249 }
1250
1251 // set Port Params
1252 uint32_t nFrameWidth, nFrameHeight, xFramerate;
1253 getInputChannelInfo(omxNode, kPortIndexInput, &nFrameWidth, &nFrameHeight,
1254 &xFramerate);
1255 // get default color format
1256 OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatUnused;
1257 getDefaultColorFormat(omxNode, kPortIndexOutput, portMode[1],
1258 &eColorFormat);
1259 ASSERT_NE(eColorFormat, OMX_COLOR_FormatUnused);
1260 status =
1261 setVideoPortFormat(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
1262 eColorFormat, xFramerate);
1263 EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1264 setDefaultPortParam(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
1265 eColorFormat, nFrameWidth, nFrameHeight, 0, xFramerate);
1266
1267 android::Vector<BufferInfo> iBuffer, oBuffer;
1268
1269 // set state to idle
1270 ASSERT_NO_FATAL_FAILURE(changeStateLoadedtoIdle(
1271 omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
1272 kPortIndexOutput, portMode, true));
1273 // set state to executing
1274 ASSERT_NO_FATAL_FAILURE(changeStateIdletoExecute(omxNode, observer));
1275
1276 // request EOS at the end
1277 eleStream.open(mURL, std::ifstream::binary);
1278 ASSERT_EQ(eleStream.is_open(), true);
1279 ASSERT_NO_FATAL_FAILURE(decodeNFrames(omxNode, observer, &iBuffer, &oBuffer,
1280 kPortIndexInput, kPortIndexOutput,
1281 eleStream, &Info, 0, (int)Info.size(),
1282 portMode[1], false));
1283 eleStream.close();
1284 ASSERT_NO_FATAL_FAILURE(
1285 waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer,
1286 kPortIndexInput, kPortIndexOutput, portMode[1]));
1287 ASSERT_NO_FATAL_FAILURE(testEOS(
1288 omxNode, observer, &iBuffer, &oBuffer, true, eosFlag, portMode,
1289 portReconfiguration, kPortIndexInput, kPortIndexOutput, nullptr));
1290 ASSERT_NO_FATAL_FAILURE(flushPorts(omxNode, observer, &iBuffer, &oBuffer,
1291 kPortIndexInput, kPortIndexOutput));
1292 framesReceived = 0;
1293 timestampUs = 0;
1294
1295 // set state to idle
1296 ASSERT_NO_FATAL_FAILURE(
1297 changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer));
1298 // set state to executing
1299 ASSERT_NO_FATAL_FAILURE(changeStateIdletoLoaded(omxNode, observer, &iBuffer, &oBuffer,
1300 kPortIndexInput, kPortIndexOutput, portMode,
1301 true));
1302 }
1303
1304 // test input/output port flush
TEST_P(VideoDecHidlTest,FlushTest)1305 TEST_P(VideoDecHidlTest, FlushTest) {
1306 description("Test Flush");
1307 if (disableTest) return;
1308 android::hardware::media::omx::V1_0::Status status;
1309 uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
1310 status = setRole(omxNode, role_);
1311 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1312 OMX_PORT_PARAM_TYPE params;
1313 status = getParam(omxNode, OMX_IndexParamVideoInit, ¶ms);
1314 if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
1315 ASSERT_EQ(params.nPorts, 2U);
1316 kPortIndexInput = params.nStartPortNumber;
1317 kPortIndexOutput = kPortIndexInput + 1;
1318 }
1319 char mURL[512], info[512];
1320 strcpy(mURL, sResourceDir.c_str());
1321 strcpy(info, sResourceDir.c_str());
1322 GetURLForComponent(compName, mURL, info);
1323
1324 std::ifstream eleStream, eleInfo;
1325
1326 eleInfo.open(info);
1327 ASSERT_EQ(eleInfo.is_open(), true);
1328 android::Vector<FrameData> Info;
1329 int bytesCount = 0, maxBytesCount = 0;
1330 uint32_t flags = 0;
1331 uint32_t timestamp = 0;
1332 while (1) {
1333 if (!(eleInfo >> bytesCount)) break;
1334 eleInfo >> flags;
1335 eleInfo >> timestamp;
1336 Info.push_back({bytesCount, flags, timestamp});
1337 if (maxBytesCount < bytesCount) maxBytesCount = bytesCount;
1338 }
1339 eleInfo.close();
1340
1341 // As the frame sizes are known ahead, use it to configure i/p buffer size
1342 maxBytesCount = ALIGN_POWER_OF_TWO(maxBytesCount, 10);
1343 status = setPortBufferSize(omxNode, kPortIndexInput, maxBytesCount);
1344 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1345
1346 // set port mode
1347 status = omxNode->setPortMode(kPortIndexInput, portMode[0]);
1348 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1349 status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
1350 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1351
1352 // set Port Params
1353 uint32_t nFrameWidth, nFrameHeight, xFramerate;
1354 getInputChannelInfo(omxNode, kPortIndexInput, &nFrameWidth, &nFrameHeight,
1355 &xFramerate);
1356 // get default color format
1357 OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatUnused;
1358 getDefaultColorFormat(omxNode, kPortIndexOutput, portMode[1],
1359 &eColorFormat);
1360 ASSERT_NE(eColorFormat, OMX_COLOR_FormatUnused);
1361 status =
1362 setVideoPortFormat(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
1363 eColorFormat, xFramerate);
1364 EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1365 setDefaultPortParam(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
1366 eColorFormat, nFrameWidth, nFrameHeight, 0, xFramerate);
1367
1368 android::Vector<BufferInfo> iBuffer, oBuffer;
1369
1370 // set state to idle
1371 ASSERT_NO_FATAL_FAILURE(changeStateLoadedtoIdle(
1372 omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
1373 kPortIndexOutput, portMode, true));
1374 // set state to executing
1375 ASSERT_NO_FATAL_FAILURE(changeStateIdletoExecute(omxNode, observer));
1376
1377 // Decode 128 frames and flush. here 128 is chosen to ensure there is a key
1378 // frame after this so that the below section can be convered for all
1379 // components
1380 int nFrames = 128;
1381 eleStream.open(mURL, std::ifstream::binary);
1382 ASSERT_EQ(eleStream.is_open(), true);
1383 ASSERT_NO_FATAL_FAILURE(decodeNFrames(
1384 omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
1385 kPortIndexOutput, eleStream, &Info, 0, nFrames, portMode[1], false));
1386 ASSERT_NO_FATAL_FAILURE(flushPorts(omxNode, observer, &iBuffer, &oBuffer,
1387 kPortIndexInput, kPortIndexOutput));
1388 framesReceived = 0;
1389
1390 // Seek to next key frame and start decoding till the end
1391 int index = nFrames;
1392 bool keyFrame = false;
1393 while (index < (int)Info.size()) {
1394 if ((Info[index].flags & OMX_BUFFERFLAG_SYNCFRAME) ==
1395 OMX_BUFFERFLAG_SYNCFRAME) {
1396 timestampUs = Info[index - 1].timestamp;
1397 keyFrame = true;
1398 break;
1399 }
1400 eleStream.ignore(Info[index].bytesCount);
1401 index++;
1402 }
1403 if (keyFrame) {
1404 ASSERT_NO_FATAL_FAILURE(
1405 decodeNFrames(omxNode, observer, &iBuffer, &oBuffer,
1406 kPortIndexInput, kPortIndexOutput, eleStream, &Info,
1407 index, Info.size() - index, portMode[1], false));
1408 }
1409 eleStream.close();
1410 ASSERT_NO_FATAL_FAILURE(flushPorts(omxNode, observer, &iBuffer, &oBuffer,
1411 kPortIndexInput, kPortIndexOutput));
1412 framesReceived = 0;
1413
1414 // set state to idle
1415 ASSERT_NO_FATAL_FAILURE(
1416 changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer));
1417 // set state to executing
1418 ASSERT_NO_FATAL_FAILURE(changeStateIdletoLoaded(omxNode, observer, &iBuffer, &oBuffer,
1419 kPortIndexInput, kPortIndexOutput, portMode,
1420 true));
1421 }
1422
1423 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VideoDecHidlTest);
1424 INSTANTIATE_TEST_SUITE_P(PerInstance, VideoDecHidlTest, testing::ValuesIn(kTestParameters),
1425 android::hardware::PrintInstanceTupleNameToString<>);
1426
main(int argc,char ** argv)1427 int main(int argc, char** argv) {
1428 kTestParameters = getTestParameters("video_decoder");
1429 ::testing::InitGoogleTest(&argc, argv);
1430
1431 // Set the resource directory based on command line args.
1432 // Test will fail to set up if the argument is not set.
1433 for (int i = 1; i < argc; i++) {
1434 if (strcmp(argv[i], "-P") == 0 && i < argc - 1) {
1435 sResourceDir = argv[i + 1];
1436 break;
1437 }
1438 }
1439
1440 return RUN_ALL_TESTS();
1441 }