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