2 * Copyright (C) 2017 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #define LOG_TAG "media_omx_hidl_video_dec_test"
18 #include <android-base/logging.h>
20 #include <android/hardware/graphics/allocator/2.0/IAllocator.h>
21 #include <android/hardware/graphics/mapper/2.0/IMapper.h>
22 #include <android/hardware/graphics/mapper/2.0/types.h>
23 #include <android/hardware/media/omx/1.0/IOmx.h>
24 #include <android/hardware/media/omx/1.0/IOmxNode.h>
25 #include <android/hardware/media/omx/1.0/IOmxObserver.h>
26 #include <android/hardware/media/omx/1.0/types.h>
27 #include <android/hidl/allocator/1.0/IAllocator.h>
28 #include <android/hidl/memory/1.0/IMapper.h>
29 #include <android/hidl/memory/1.0/IMemory.h>
30 #include <cutils/atomic.h>
32 using ::android::hardware::graphics::common::V1_0::BufferUsage;
33 using ::android::hardware::graphics::common::V1_0::PixelFormat;
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;
49 #include <VtsHalHidlTargetTestBase.h>
51 #include <media/hardware/HardwareAPI.h>
52 #include <media_hidl_test_common.h>
53 #include <media_video_hidl_test_common.h>
56 // A class for test environment setup
57 class ComponentTestEnvironment : public ::testing::Environment {
59 virtual void SetUp() {}
60 virtual void TearDown() {}
62 ComponentTestEnvironment() : instance("default"), res("/sdcard/media/") {}
64 void setInstance(const char* _instance) { instance = _instance; }
66 void setComponent(const char* _component) { component = _component; }
68 void setRole(const char* _role) { role = _role; }
70 void setRes(const char* _res) { res = _res; }
72 const hidl_string getInstance() const { return instance; }
74 const hidl_string getComponent() const { return component; }
76 const hidl_string getRole() const { return role; }
78 const hidl_string getRes() const { return res; }
80 int initFromOptions(int argc, char** argv) {
81 static struct option options[] = {
82 {"instance", required_argument, 0, 'I'},
83 {"component", required_argument, 0, 'C'},
84 {"role", required_argument, 0, 'R'},
85 {"res", required_argument, 0, 'P'},
90 int c = getopt_long(argc, argv, "I:C:R:P:", options, &index);
100 setComponent(optarg);
115 "unrecognized option: %s\n\n"
116 "usage: %s <gtest options> <test options>\n\n"
117 "test options are:\n\n"
118 "-I, --instance: HAL instance to test\n"
119 "-C, --component: OMX component to test\n"
120 "-R, --role: OMX component Role\n"
121 "-P, --res: Resource files directory location\n",
122 argv[optind ?: 1], argv[0]);
129 hidl_string instance;
130 hidl_string component;
135 static ComponentTestEnvironment* gEnv = nullptr;
137 // video decoder test fixture class
138 class VideoDecHidlTest : public ::testing::VtsHalHidlTargetTestBase {
140 typedef ::testing::VtsHalHidlTargetTestBase Super;
142 ::std::string getTestCaseInfo() const override {
143 return ::std::string() +
144 "Component: " + gEnv->getComponent().c_str() + " | " +
145 "Role: " + gEnv->getRole().c_str() + " | " +
146 "Instance: " + gEnv->getInstance().c_str() + " | " +
147 "Res: " + gEnv->getRes().c_str();
150 virtual void SetUp() override {
153 android::hardware::media::omx::V1_0::Status status;
154 omx = Super::getService<IOmx>(gEnv->getInstance());
155 ASSERT_NE(omx, nullptr);
157 new CodecObserver([this](Message msg, const BufferInfo* buffer) {
158 handleMessage(msg, buffer);
160 ASSERT_NE(observer, nullptr);
161 if (strncmp(gEnv->getComponent().c_str(), "OMX.", 4) != 0)
163 EXPECT_TRUE(omx->allocateNode(
164 gEnv->getComponent(), observer,
165 [&](android::hardware::media::omx::V1_0::Status _s,
166 sp<IOmxNode> const& _nl) {
171 ASSERT_NE(omxNode, nullptr);
172 ASSERT_NE(gEnv->getRole().empty(), true) << "Invalid Component Role";
173 struct StringToName {
175 standardComp CompName;
177 const StringToName kStringToName[] = {
178 {"h263", h263}, {"avc", avc}, {"mpeg2", mpeg2}, {"mpeg4", mpeg4},
179 {"hevc", hevc}, {"vp8", vp8}, {"vp9", vp9},
181 const size_t kNumStringToName =
182 sizeof(kStringToName) / sizeof(kStringToName[0]);
184 char substring[OMX_MAX_STRINGNAME_SIZE];
185 strcpy(substring, gEnv->getRole().c_str());
186 pch = strchr(substring, '.');
187 ASSERT_NE(pch, nullptr);
188 compName = unknown_comp;
189 for (size_t i = 0; i < kNumStringToName; ++i) {
190 if (!strcasecmp(pch + 1, kStringToName[i].Name)) {
191 compName = kStringToName[i].CompName;
195 if (compName == unknown_comp) disableTest = true;
196 struct CompToCompression {
197 standardComp CompName;
198 OMX_VIDEO_CODINGTYPE eCompressionFormat;
200 static const CompToCompression kCompToCompression[] = {
201 {h263, OMX_VIDEO_CodingH263}, {avc, OMX_VIDEO_CodingAVC},
202 {mpeg2, OMX_VIDEO_CodingMPEG2}, {mpeg4, OMX_VIDEO_CodingMPEG4},
203 {hevc, OMX_VIDEO_CodingHEVC}, {vp8, OMX_VIDEO_CodingVP8},
204 {vp9, OMX_VIDEO_CodingVP9},
206 static const size_t kNumCompToCompression =
207 sizeof(kCompToCompression) / sizeof(kCompToCompression[0]);
209 for (i = 0; i < kNumCompToCompression; ++i) {
210 if (kCompToCompression[i].CompName == compName) {
211 eCompressionFormat = kCompToCompression[i].eCompressionFormat;
215 if (i == kNumCompToCompression) disableTest = true;
216 portMode[0] = portMode[1] = PortMode::PRESET_BYTE_BUFFER;
220 timestampDevTest = false;
222 size_t suffixLen = strlen(".secure");
223 if (strlen(gEnv->getComponent().c_str()) >= suffixLen) {
225 !strcmp(gEnv->getComponent().c_str() +
226 strlen(gEnv->getComponent().c_str()) - suffixLen,
229 if (isSecure) disableTest = true;
230 if (disableTest) std::cout << "[ ] Warning ! Test Disabled\n";
233 virtual void TearDown() override {
234 if (omxNode != nullptr) {
235 EXPECT_TRUE((omxNode->freeNode()).isOk());
241 // callback function to process messages received by onMessages() from IL
243 void handleMessage(Message msg, const BufferInfo* buffer) {
245 if (msg.type == Message::Type::FILL_BUFFER_DONE) {
246 if (msg.data.extendedBufferData.flags & OMX_BUFFERFLAG_EOS) {
249 if (msg.data.extendedBufferData.rangeLength != 0) {
251 // For decoder components current timestamp always exceeds
252 // previous timestamp
253 EXPECT_GE(msg.data.extendedBufferData.timestampUs, timestampUs);
254 timestampUs = msg.data.extendedBufferData.timestampUs;
255 // Test if current timestamp is among the list of queued
257 if (timestampDevTest) {
259 android::List<uint64_t>::iterator it =
260 timestampUslist.begin();
261 while (it != timestampUslist.end()) {
262 if (*it == timestampUs) {
263 timestampUslist.erase(it);
269 if (tsHit == false) {
270 if (timestampUslist.empty() == false) {
271 EXPECT_EQ(tsHit, true)
272 << "TimeStamp not recognized";
275 << "[ ] Warning ! Received non-zero "
276 "output / TimeStamp not recognized \n";
280 #define WRITE_OUTPUT 0
282 static int count = 0;
285 ofp = fopen("out.bin", "ab");
287 ofp = fopen("out.bin", "wb");
288 if (ofp != nullptr &&
289 portMode[1] == PortMode::PRESET_BYTE_BUFFER) {
290 fwrite(static_cast<void*>(buffer->mMemory->getPointer()),
292 msg.data.extendedBufferData.rangeLength, ofp);
313 sp<CodecObserver> observer;
314 sp<IOmxNode> omxNode;
315 standardComp compName;
316 OMX_VIDEO_CODINGTYPE eCompressionFormat;
318 PortMode portMode[2];
320 uint32_t framesReceived;
321 uint64_t timestampUs;
322 ::android::List<uint64_t> timestampUslist;
323 bool timestampDevTest;
327 static void description(const std::string& description) {
328 RecordProperty("description", description);
332 // Set Default port param.
333 void setDefaultPortParam(sp<IOmxNode> omxNode, OMX_U32 portIndex,
334 OMX_VIDEO_CODINGTYPE eCompressionFormat,
335 OMX_COLOR_FORMATTYPE eColorFormat,
336 OMX_U32 nFrameWidth = 352, OMX_U32 nFrameHeight = 288,
337 OMX_U32 nBitrate = 0,
338 OMX_U32 xFramerate = (24U << 16)) {
339 switch ((int)eCompressionFormat) {
340 case OMX_VIDEO_CodingUnused:
341 setupRAWPort(omxNode, portIndex, nFrameWidth, nFrameHeight,
342 nBitrate, xFramerate, eColorFormat);
349 // In decoder components, often the input port parameters get updated upon
350 // parsing the header of elementary stream. Client needs to collect this
351 // information to reconfigure other ports that share data with this input
353 void getInputChannelInfo(sp<IOmxNode> omxNode, OMX_U32 kPortIndexInput,
354 uint32_t* nFrameWidth, uint32_t* nFrameHeight,
355 uint32_t* xFramerate) {
356 android::hardware::media::omx::V1_0::Status status;
359 *xFramerate = (24U << 16);
361 OMX_PARAM_PORTDEFINITIONTYPE portDef;
362 status = getPortParam(omxNode, OMX_IndexParamPortDefinition,
363 kPortIndexInput, &portDef);
364 EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
365 if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
366 *nFrameWidth = portDef.format.video.nFrameWidth;
367 *nFrameHeight = portDef.format.video.nFrameHeight;
368 *xFramerate = portDef.format.video.xFramerate;
372 // LookUpTable of clips and metadata for component testing
373 void GetURLForComponent(VideoDecHidlTest::standardComp comp, char* mURL,
376 VideoDecHidlTest::standardComp comp;
380 static const CompToURL kCompToURL[] = {
381 {VideoDecHidlTest::standardComp::avc,
382 "bbb_avc_1920x1080_5000kbps_30fps.h264",
383 "bbb_avc_1920x1080_5000kbps_30fps.info"},
384 {VideoDecHidlTest::standardComp::hevc,
385 "bbb_hevc_640x360_1600kbps_30fps.hevc",
386 "bbb_hevc_640x360_1600kbps_30fps.info"},
387 {VideoDecHidlTest::standardComp::mpeg2,
388 "bbb_mpeg2_176x144_105kbps_25fps.m2v",
389 "bbb_mpeg2_176x144_105kbps_25fps.info"},
390 {VideoDecHidlTest::standardComp::h263,
391 "bbb_h263_352x288_300kbps_12fps.h263",
392 "bbb_h263_352x288_300kbps_12fps.info"},
393 {VideoDecHidlTest::standardComp::mpeg4,
394 "bbb_mpeg4_1280x720_1000kbps_25fps.m4v",
395 "bbb_mpeg4_1280x720_1000kbps_25fps.info"},
396 {VideoDecHidlTest::standardComp::vp8, "bbb_vp8_640x360_2mbps_30fps.vp8",
397 "bbb_vp8_640x360_2mbps_30fps.info"},
398 {VideoDecHidlTest::standardComp::vp9,
399 "bbb_vp9_640x360_1600kbps_30fps.vp9",
400 "bbb_vp9_640x360_1600kbps_30fps.info"},
403 for (size_t i = 0; i < sizeof(kCompToURL) / sizeof(kCompToURL[0]); ++i) {
404 if (kCompToURL[i].comp == comp) {
405 strcat(mURL, kCompToURL[i].mURL);
406 strcat(info, kCompToURL[i].info);
412 void allocateGraphicBuffers(sp<IOmxNode> omxNode, OMX_U32 portIndex,
413 android::Vector<BufferInfo>* buffArray,
414 uint32_t nFrameWidth, uint32_t nFrameHeight,
415 int32_t* nStride, int format, uint32_t count) {
416 android::hardware::media::omx::V1_0::Status status;
417 sp<android::hardware::graphics::allocator::V2_0::IAllocator> allocator =
418 android::hardware::graphics::allocator::V2_0::IAllocator::getService();
419 ASSERT_NE(nullptr, allocator.get());
421 sp<android::hardware::graphics::mapper::V2_0::IMapper> mapper =
422 android::hardware::graphics::mapper::V2_0::IMapper::getService();
423 ASSERT_NE(mapper.get(), nullptr);
425 android::hardware::graphics::mapper::V2_0::IMapper::BufferDescriptorInfo
429 descriptorInfo.width = nFrameWidth;
430 descriptorInfo.height = nFrameHeight;
431 descriptorInfo.layerCount = 1;
432 descriptorInfo.format = static_cast<PixelFormat>(format);
433 descriptorInfo.usage = static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN);
434 omxNode->getGraphicBufferUsage(
436 [&status, &usage](android::hardware::media::omx::V1_0::Status _s,
441 if (status == android::hardware::media::omx::V1_0::Status::OK) {
442 descriptorInfo.usage |= usage;
445 ::android::hardware::hidl_vec<uint32_t> descriptor;
446 android::hardware::graphics::mapper::V2_0::Error error;
447 mapper->createDescriptor(
448 descriptorInfo, [&error, &descriptor](
449 android::hardware::graphics::mapper::V2_0::Error _s,
450 ::android::hardware::hidl_vec<uint32_t> _n1) {
454 EXPECT_EQ(error, android::hardware::graphics::mapper::V2_0::Error::NONE);
456 EXPECT_EQ(buffArray->size(), count);
458 static volatile int32_t nextId = 0;
459 uint64_t id = static_cast<uint64_t>(getpid()) << 32;
462 [&](android::hardware::graphics::mapper::V2_0::Error _s, uint32_t _n1,
463 const ::android::hardware::hidl_vec<
464 ::android::hardware::hidl_handle>& _n2) {
465 ASSERT_EQ(android::hardware::graphics::mapper::V2_0::Error::NONE,
468 ASSERT_EQ(count, _n2.size());
469 for (uint32_t i = 0; i < count; i++) {
470 buffArray->editItemAt(i).omxBuffer.nativeHandle = _n2[i];
471 buffArray->editItemAt(i).omxBuffer.attr.anwBuffer.width =
473 buffArray->editItemAt(i).omxBuffer.attr.anwBuffer.height =
475 buffArray->editItemAt(i).omxBuffer.attr.anwBuffer.stride = _n1;
476 buffArray->editItemAt(i).omxBuffer.attr.anwBuffer.format =
477 descriptorInfo.format;
478 buffArray->editItemAt(i).omxBuffer.attr.anwBuffer.usage =
479 descriptorInfo.usage;
480 buffArray->editItemAt(i).omxBuffer.attr.anwBuffer.layerCount =
481 descriptorInfo.layerCount;
482 buffArray->editItemAt(i).omxBuffer.attr.anwBuffer.id =
483 id | static_cast<uint32_t>(android_atomic_inc(&nextId));
488 // port settings reconfiguration during runtime. reconfigures frame dimensions
489 void portReconfiguration(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
490 android::Vector<BufferInfo>* iBuffer,
491 android::Vector<BufferInfo>* oBuffer,
492 OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput,
493 Message msg, PortMode oPortMode, void* args) {
494 android::hardware::media::omx::V1_0::Status status;
497 if (msg.data.eventData.event == OMX_EventPortSettingsChanged) {
498 ASSERT_EQ(msg.data.eventData.data1, kPortIndexOutput);
499 if (msg.data.eventData.data2 == OMX_IndexParamPortDefinition ||
500 msg.data.eventData.data2 == 0) {
501 status = omxNode->sendCommand(
502 toRawCommandType(OMX_CommandPortDisable), kPortIndexOutput);
503 ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
505 status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer,
508 android::hardware::media::omx::V1_0::Status::TIMED_OUT) {
509 for (size_t i = 0; i < oBuffer->size(); ++i) {
510 // test if client got all its buffers back
511 EXPECT_EQ((*oBuffer)[i].owner, client);
514 omxNode->freeBuffer(kPortIndexOutput, (*oBuffer)[i].id);
516 android::hardware::media::omx::V1_0::Status::OK);
518 status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
521 android::hardware::media::omx::V1_0::Status::OK);
522 ASSERT_EQ(msg.type, Message::Type::EVENT);
523 ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
524 ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortDisable);
525 ASSERT_EQ(msg.data.eventData.data2, kPortIndexOutput);
528 uint32_t nFrameWidth, nFrameHeight, xFramerate;
529 getInputChannelInfo(omxNode, kPortIndexInput, &nFrameWidth,
530 &nFrameHeight, &xFramerate);
531 // get configured color format
532 OMX_PARAM_PORTDEFINITIONTYPE portDef;
533 status = getPortParam(omxNode, OMX_IndexParamPortDefinition,
534 kPortIndexOutput, &portDef);
535 setDefaultPortParam(omxNode, kPortIndexOutput,
536 OMX_VIDEO_CodingUnused,
537 portDef.format.video.eColorFormat,
538 nFrameWidth, nFrameHeight, 0, xFramerate);
540 // If you can disable a port, then you should be able to
543 status = omxNode->sendCommand(
544 toRawCommandType(OMX_CommandPortEnable), kPortIndexOutput);
546 android::hardware::media::omx::V1_0::Status::OK);
548 // do not enable the port until all the buffers are supplied
549 status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
553 android::hardware::media::omx::V1_0::Status::TIMED_OUT);
555 allocatePortBuffers(omxNode, oBuffer, kPortIndexOutput,
557 if (oPortMode != PortMode::PRESET_BYTE_BUFFER) {
558 OMX_PARAM_PORTDEFINITIONTYPE portDef;
560 status = getPortParam(omxNode, OMX_IndexParamPortDefinition,
561 kPortIndexOutput, &portDef);
564 ::android::hardware::media::omx::V1_0::Status::OK);
565 allocateGraphicBuffers(omxNode, kPortIndexOutput, oBuffer,
566 portDef.format.video.nFrameWidth,
567 portDef.format.video.nFrameHeight,
568 &portDef.format.video.nStride,
569 portDef.format.video.eColorFormat,
570 portDef.nBufferCountActual);
572 status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
575 android::hardware::media::omx::V1_0::Status::OK);
576 ASSERT_EQ(msg.type, Message::Type::EVENT);
577 ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortEnable);
578 ASSERT_EQ(msg.data.eventData.data2, kPortIndexOutput);
580 // dispatch output buffers
581 for (size_t i = 0; i < oBuffer->size(); i++) {
582 dispatchOutputBuffer(omxNode, oBuffer, i, oPortMode);
587 } else if (msg.data.eventData.data2 ==
588 OMX_IndexConfigCommonOutputCrop) {
589 std::cout << "[ ] Warning ! OMX_EventPortSettingsChanged/ "
590 "OMX_IndexConfigCommonOutputCrop not handled \n";
591 } else if (msg.data.eventData.data2 == OMX_IndexVendorStartUnused + 3) {
592 std::cout << "[ ] Warning ! OMX_EventPortSettingsChanged/ "
593 "kDescribeColorAspectsIndex not handled \n";
595 } else if (msg.data.eventData.event == OMX_EventError) {
596 std::cout << "[ ] Warning ! OMX_EventError/ "
597 "Decode Frame Call might be failed \n";
600 // something unexpected happened
605 // blocking call to ensures application to Wait till all the inputs are consumed
606 void waitOnInputConsumption(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
607 android::Vector<BufferInfo>* iBuffer,
608 android::Vector<BufferInfo>* oBuffer,
609 OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput,
610 PortMode oPortMode) {
611 android::hardware::media::omx::V1_0::Status status;
613 int timeOut = TIMEOUT_COUNTER_Q;
618 observer->dequeueMessage(&msg, DEFAULT_TIMEOUT_Q, iBuffer, oBuffer);
619 if (status == android::hardware::media::omx::V1_0::Status::OK) {
620 EXPECT_EQ(msg.type, Message::Type::EVENT);
621 portReconfiguration(omxNode, observer, iBuffer, oBuffer,
622 kPortIndexInput, kPortIndexOutput, msg,
625 // status == TIMED_OUT, it could be due to process time being large
626 // than DEFAULT_TIMEOUT or component needs output buffers to start
628 for (; i < iBuffer->size(); i++) {
629 if ((*iBuffer)[i].owner != client) break;
631 if (i == iBuffer->size()) break;
633 // Dispatch an output buffer assuming outQueue.empty() is true
635 if ((index = getEmptyBufferID(oBuffer)) < oBuffer->size()) {
636 dispatchOutputBuffer(omxNode, oBuffer, index, oPortMode);
637 timeOut = TIMEOUT_COUNTER_Q;
643 void decodeNFrames(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
644 android::Vector<BufferInfo>* iBuffer,
645 android::Vector<BufferInfo>* oBuffer,
646 OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput,
647 std::ifstream& eleStream, android::Vector<FrameData>* Info,
648 int offset, int range, PortMode oPortMode,
649 bool signalEOS = true) {
650 android::hardware::media::omx::V1_0::Status status;
653 // dispatch output buffers
654 for (size_t i = 0; i < oBuffer->size(); i++) {
655 dispatchOutputBuffer(omxNode, oBuffer, i, oPortMode);
657 // dispatch input buffers
659 int frameID = offset;
660 for (size_t i = 0; (i < iBuffer->size()) && (frameID < (int)Info->size()) &&
661 (frameID < (offset + range));
663 char* ipBuffer = static_cast<char*>(
664 static_cast<void*>((*iBuffer)[i].mMemory->getPointer()));
665 ASSERT_LE((*Info)[frameID].bytesCount,
666 static_cast<int>((*iBuffer)[i].mMemory->getSize()));
667 eleStream.read(ipBuffer, (*Info)[frameID].bytesCount);
668 ASSERT_EQ(eleStream.gcount(), (*Info)[frameID].bytesCount);
669 flags = (*Info)[frameID].flags;
670 if (signalEOS && ((frameID == (int)Info->size() - 1) ||
671 (frameID == (offset + range - 1))))
672 flags |= OMX_BUFFERFLAG_EOS;
673 dispatchInputBuffer(omxNode, iBuffer, i, (*Info)[frameID].bytesCount,
674 flags, (*Info)[frameID].timestamp);
678 int timeOut = TIMEOUT_COUNTER_Q;
679 bool iQueued, oQueued;
681 iQueued = oQueued = false;
683 observer->dequeueMessage(&msg, DEFAULT_TIMEOUT_Q, iBuffer, oBuffer);
685 // Port Reconfiguration
686 if (status == android::hardware::media::omx::V1_0::Status::OK &&
687 msg.type == Message::Type::EVENT) {
688 portReconfiguration(omxNode, observer, iBuffer, oBuffer,
689 kPortIndexInput, kPortIndexOutput, msg,
693 if (frameID == (int)Info->size() || frameID == (offset + range)) break;
695 // Dispatch input buffer
697 if ((index = getEmptyBufferID(iBuffer)) < iBuffer->size()) {
698 char* ipBuffer = static_cast<char*>(
699 static_cast<void*>((*iBuffer)[index].mMemory->getPointer()));
700 ASSERT_LE((*Info)[frameID].bytesCount,
701 static_cast<int>((*iBuffer)[index].mMemory->getSize()));
702 eleStream.read(ipBuffer, (*Info)[frameID].bytesCount);
703 ASSERT_EQ(eleStream.gcount(), (*Info)[frameID].bytesCount);
704 flags = (*Info)[frameID].flags;
705 if (signalEOS && ((frameID == (int)Info->size() - 1) ||
706 (frameID == (offset + range - 1))))
707 flags |= OMX_BUFFERFLAG_EOS;
708 dispatchInputBuffer(omxNode, iBuffer, index,
709 (*Info)[frameID].bytesCount, flags,
710 (*Info)[frameID].timestamp);
714 if ((index = getEmptyBufferID(oBuffer)) < oBuffer->size()) {
715 dispatchOutputBuffer(omxNode, oBuffer, index, oPortMode);
718 if (iQueued || oQueued)
719 timeOut = TIMEOUT_COUNTER_Q;
723 EXPECT_TRUE(false) << "Wait on Input/Output is found indefinite";
729 // DescribeColorFormatParams Copy Constructor (Borrowed from OMXUtils.cpp)
730 android::DescribeColorFormatParams::DescribeColorFormatParams(
731 const android::DescribeColorFormat2Params& params) {
732 eColorFormat = params.eColorFormat;
733 nFrameWidth = params.nFrameWidth;
734 nFrameHeight = params.nFrameHeight;
735 nStride = params.nStride;
736 nSliceHeight = params.nSliceHeight;
737 bUsingNativeBuffers = params.bUsingNativeBuffers;
740 bool isColorFormatFlexibleYUV(sp<IOmxNode> omxNode,
741 OMX_COLOR_FORMATTYPE eColorFormat) {
742 android::hardware::media::omx::V1_0::Status status;
743 unsigned int index = OMX_IndexMax, index2 = OMX_IndexMax;
744 omxNode->getExtensionIndex(
745 "OMX.google.android.index.describeColorFormat",
746 [&index](android::hardware::media::omx::V1_0::Status _s,
748 if (_s == ::android::hardware::media::omx::V1_0::Status::OK)
751 omxNode->getExtensionIndex(
752 "OMX.google.android.index.describeColorFormat2",
753 [&index2](android::hardware::media::omx::V1_0::Status _s,
755 if (_s == ::android::hardware::media::omx::V1_0::Status::OK)
759 android::DescribeColorFormat2Params describeParams;
760 describeParams.eColorFormat = eColorFormat;
761 describeParams.nFrameWidth = 128;
762 describeParams.nFrameHeight = 128;
763 describeParams.nStride = 128;
764 describeParams.nSliceHeight = 128;
765 describeParams.bUsingNativeBuffers = OMX_FALSE;
766 if (index != OMX_IndexMax) {
767 android::DescribeColorFormatParams describeParamsV1(describeParams);
768 status = getParam(omxNode, static_cast<OMX_INDEXTYPE>(index),
770 if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
771 android::MediaImage& img = describeParamsV1.sMediaImage;
772 if (img.mType == android::MediaImage::MEDIA_IMAGE_TYPE_YUV) {
773 if (img.mNumPlanes == 3 &&
774 img.mPlane[img.Y].mHorizSubsampling == 1 &&
775 img.mPlane[img.Y].mVertSubsampling == 1) {
776 if (img.mPlane[img.U].mHorizSubsampling == 2 &&
777 img.mPlane[img.U].mVertSubsampling == 2 &&
778 img.mPlane[img.V].mHorizSubsampling == 2 &&
779 img.mPlane[img.V].mVertSubsampling == 2) {
780 if (img.mBitDepth <= 8) {
787 } else if (index2 != OMX_IndexMax) {
788 status = getParam(omxNode, static_cast<OMX_INDEXTYPE>(index2),
790 android::MediaImage2& img = describeParams.sMediaImage;
791 if (img.mType == android::MediaImage2::MEDIA_IMAGE_TYPE_YUV) {
792 if (img.mNumPlanes == 3 &&
793 img.mPlane[img.Y].mHorizSubsampling == 1 &&
794 img.mPlane[img.Y].mVertSubsampling == 1) {
795 if (img.mPlane[img.U].mHorizSubsampling == 2 &&
796 img.mPlane[img.U].mVertSubsampling == 2 &&
797 img.mPlane[img.V].mHorizSubsampling == 2 &&
798 img.mPlane[img.V].mVertSubsampling == 2) {
799 if (img.mBitDepth <= 8) {
809 // get default color format for output port
810 void getDefaultColorFormat(sp<IOmxNode> omxNode, OMX_U32 kPortIndexOutput,
812 OMX_COLOR_FORMATTYPE* eColorFormat) {
813 android::hardware::media::omx::V1_0::Status status;
814 OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat;
815 *eColorFormat = OMX_COLOR_FormatUnused;
816 portFormat.nIndex = 0;
818 status = getPortParam(omxNode, OMX_IndexParamVideoPortFormat,
819 kPortIndexOutput, &portFormat);
820 if (status != ::android::hardware::media::omx::V1_0::Status::OK) break;
821 EXPECT_EQ(portFormat.eCompressionFormat, OMX_VIDEO_CodingUnused);
822 if (oPortMode != PortMode::PRESET_BYTE_BUFFER) {
823 *eColorFormat = portFormat.eColorFormat;
826 if (isColorFormatFlexibleYUV(omxNode, portFormat.eColorFormat)) {
827 *eColorFormat = portFormat.eColorFormat;
830 if (OMX_COLOR_FormatYUV420SemiPlanar == portFormat.eColorFormat ||
831 OMX_COLOR_FormatYUV420Planar == portFormat.eColorFormat) {
832 *eColorFormat = portFormat.eColorFormat;
839 // set component role
840 TEST_F(VideoDecHidlTest, SetRole) {
841 description("Test Set Component Role");
842 if (disableTest) return;
843 android::hardware::media::omx::V1_0::Status status;
844 status = setRole(omxNode, gEnv->getRole().c_str());
845 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
848 // port format enumeration
849 TEST_F(VideoDecHidlTest, EnumeratePortFormat) {
850 description("Test Component on Mandatory Port Parameters (Port Format)");
851 if (disableTest) return;
852 android::hardware::media::omx::V1_0::Status status;
853 uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
854 OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatYUV420Planar;
855 OMX_U32 xFramerate = (24U << 16);
856 status = setRole(omxNode, gEnv->getRole().c_str());
857 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
858 OMX_PORT_PARAM_TYPE params;
859 status = getParam(omxNode, OMX_IndexParamVideoInit, ¶ms);
860 if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
861 ASSERT_EQ(params.nPorts, 2U);
862 kPortIndexInput = params.nStartPortNumber;
863 kPortIndexOutput = kPortIndexInput + 1;
865 status = setVideoPortFormat(omxNode, kPortIndexInput, eCompressionFormat,
866 OMX_COLOR_FormatUnused, 0U);
867 EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
869 setVideoPortFormat(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
870 eColorFormat, xFramerate);
871 EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
874 // test port settings reconfiguration, elementary stream decode and timestamp
876 TEST_F(VideoDecHidlTest, DecodeTest) {
877 description("Tests Port Reconfiguration, Decode and timestamp deviation");
878 if (disableTest) return;
879 android::hardware::media::omx::V1_0::Status status;
880 uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
881 status = setRole(omxNode, gEnv->getRole().c_str());
882 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
883 OMX_PORT_PARAM_TYPE params;
884 status = getParam(omxNode, OMX_IndexParamVideoInit, ¶ms);
885 if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
886 ASSERT_EQ(params.nPorts, 2U);
887 kPortIndexInput = params.nStartPortNumber;
888 kPortIndexOutput = kPortIndexInput + 1;
890 char mURL[512], info[512];
891 strcpy(mURL, gEnv->getRes().c_str());
892 strcpy(info, gEnv->getRes().c_str());
893 GetURLForComponent(compName, mURL, info);
895 std::ifstream eleStream, eleInfo;
898 ASSERT_EQ(eleInfo.is_open(), true);
899 android::Vector<FrameData> Info;
900 int bytesCount = 0, maxBytesCount = 0;
902 uint32_t timestamp = 0;
903 timestampDevTest = true;
905 if (!(eleInfo >> bytesCount)) break;
907 eleInfo >> timestamp;
908 Info.push_back({bytesCount, flags, timestamp});
909 if (timestampDevTest && (flags != OMX_BUFFERFLAG_CODECCONFIG))
910 timestampUslist.push_back(timestamp);
911 if (maxBytesCount < bytesCount) maxBytesCount = bytesCount;
915 // As the frame sizes are known ahead, use it to configure i/p buffer size
916 maxBytesCount = ALIGN_POWER_OF_TWO(maxBytesCount, 10);
917 status = setPortBufferSize(omxNode, kPortIndexInput, maxBytesCount);
918 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
921 portMode[0] = PortMode::PRESET_BYTE_BUFFER;
922 portMode[1] = PortMode::DYNAMIC_ANW_BUFFER;
923 status = omxNode->setPortMode(kPortIndexInput, portMode[0]);
924 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
925 status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
926 if (status != ::android::hardware::media::omx::V1_0::Status::OK) {
927 portMode[1] = PortMode::PRESET_BYTE_BUFFER;
928 status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
929 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
933 uint32_t nFrameWidth, nFrameHeight, xFramerate;
934 getInputChannelInfo(omxNode, kPortIndexInput, &nFrameWidth, &nFrameHeight,
936 // get default color format
937 OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatUnused;
938 getDefaultColorFormat(omxNode, kPortIndexOutput, portMode[1],
940 ASSERT_NE(eColorFormat, OMX_COLOR_FormatUnused);
942 setVideoPortFormat(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
943 eColorFormat, xFramerate);
944 EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
945 setDefaultPortParam(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
946 eColorFormat, nFrameWidth, nFrameHeight, 0, xFramerate);
948 // disabling adaptive playback.
949 omxNode->prepareForAdaptivePlayback(kPortIndexOutput, false, 1920, 1080);
951 android::Vector<BufferInfo> iBuffer, oBuffer;
954 changeStateLoadedtoIdle(omxNode, observer, &iBuffer, &oBuffer,
955 kPortIndexInput, kPortIndexOutput, portMode);
956 // set state to executing
957 changeStateIdletoExecute(omxNode, observer);
959 if (portMode[1] != PortMode::PRESET_BYTE_BUFFER) {
960 OMX_PARAM_PORTDEFINITIONTYPE portDef;
962 status = getPortParam(omxNode, OMX_IndexParamPortDefinition,
963 kPortIndexOutput, &portDef);
964 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
965 allocateGraphicBuffers(
966 omxNode, kPortIndexOutput, &oBuffer,
967 portDef.format.video.nFrameWidth, portDef.format.video.nFrameHeight,
968 &portDef.format.video.nStride, portDef.format.video.eColorFormat,
969 portDef.nBufferCountActual);
972 // Port Reconfiguration
973 eleStream.open(mURL, std::ifstream::binary);
974 ASSERT_EQ(eleStream.is_open(), true);
975 decodeNFrames(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
976 kPortIndexOutput, eleStream, &Info, 0, (int)Info.size(),
979 waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer,
980 kPortIndexInput, kPortIndexOutput, portMode[1]);
981 testEOS(omxNode, observer, &iBuffer, &oBuffer, false, eosFlag, portMode,
982 portReconfiguration, kPortIndexInput, kPortIndexOutput, nullptr);
983 if (timestampDevTest) EXPECT_EQ(timestampUslist.empty(), true);
985 changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer);
986 // set state to executing
987 changeStateIdletoLoaded(omxNode, observer, &iBuffer, &oBuffer,
988 kPortIndexInput, kPortIndexOutput);
991 // end of sequence test
992 TEST_F(VideoDecHidlTest, EOSTest_M) {
993 description("Test End of stream monkeying");
994 if (disableTest) return;
995 android::hardware::media::omx::V1_0::Status status;
996 uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
997 status = setRole(omxNode, gEnv->getRole().c_str());
998 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
999 OMX_PORT_PARAM_TYPE params;
1000 status = getParam(omxNode, OMX_IndexParamVideoInit, ¶ms);
1001 if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
1002 ASSERT_EQ(params.nPorts, 2U);
1003 kPortIndexInput = params.nStartPortNumber;
1004 kPortIndexOutput = kPortIndexInput + 1;
1008 status = omxNode->setPortMode(kPortIndexInput, portMode[0]);
1009 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1010 status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
1011 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1014 uint32_t nFrameWidth, nFrameHeight, xFramerate;
1015 getInputChannelInfo(omxNode, kPortIndexInput, &nFrameWidth, &nFrameHeight,
1017 // get default color format
1018 OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatUnused;
1019 getDefaultColorFormat(omxNode, kPortIndexOutput, portMode[1],
1021 ASSERT_NE(eColorFormat, OMX_COLOR_FormatUnused);
1023 setVideoPortFormat(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
1024 eColorFormat, xFramerate);
1025 EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1026 setDefaultPortParam(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
1027 eColorFormat, nFrameWidth, nFrameHeight, 0, xFramerate);
1029 android::Vector<BufferInfo> iBuffer, oBuffer;
1031 // set state to idle
1032 changeStateLoadedtoIdle(omxNode, observer, &iBuffer, &oBuffer,
1033 kPortIndexInput, kPortIndexOutput, portMode);
1034 // set state to executing
1035 changeStateIdletoExecute(omxNode, observer);
1037 // request EOS at the start
1038 testEOS(omxNode, observer, &iBuffer, &oBuffer, true, eosFlag, portMode,
1039 portReconfiguration, kPortIndexInput, kPortIndexOutput, nullptr);
1040 flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
1042 EXPECT_GE(framesReceived, 0U);
1046 // set state to idle
1047 changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer);
1048 // set state to executing
1049 changeStateIdletoLoaded(omxNode, observer, &iBuffer, &oBuffer,
1050 kPortIndexInput, kPortIndexOutput);
1053 // end of sequence test
1054 TEST_F(VideoDecHidlTest, ThumbnailTest) {
1055 description("Test Request for thumbnail");
1056 if (disableTest) return;
1057 android::hardware::media::omx::V1_0::Status status;
1058 uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
1059 status = setRole(omxNode, gEnv->getRole().c_str());
1060 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1061 OMX_PORT_PARAM_TYPE params;
1062 status = getParam(omxNode, OMX_IndexParamVideoInit, ¶ms);
1063 if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
1064 ASSERT_EQ(params.nPorts, 2U);
1065 kPortIndexInput = params.nStartPortNumber;
1066 kPortIndexOutput = kPortIndexInput + 1;
1068 char mURL[512], info[512];
1069 strcpy(mURL, gEnv->getRes().c_str());
1070 strcpy(info, gEnv->getRes().c_str());
1071 GetURLForComponent(compName, mURL, info);
1073 std::ifstream eleStream, eleInfo;
1076 ASSERT_EQ(eleInfo.is_open(), true);
1077 android::Vector<FrameData> Info;
1078 int bytesCount = 0, maxBytesCount = 0;
1080 uint32_t timestamp = 0;
1082 if (!(eleInfo >> bytesCount)) break;
1084 eleInfo >> timestamp;
1085 Info.push_back({bytesCount, flags, timestamp});
1086 if (maxBytesCount < bytesCount) maxBytesCount = bytesCount;
1090 // As the frame sizes are known ahead, use it to configure i/p buffer size
1091 maxBytesCount = ALIGN_POWER_OF_TWO(maxBytesCount, 10);
1092 status = setPortBufferSize(omxNode, kPortIndexInput, maxBytesCount);
1093 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1096 status = omxNode->setPortMode(kPortIndexInput, portMode[0]);
1097 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1098 status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
1099 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1102 uint32_t nFrameWidth, nFrameHeight, xFramerate;
1103 getInputChannelInfo(omxNode, kPortIndexInput, &nFrameWidth, &nFrameHeight,
1105 // get default color format
1106 OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatUnused;
1107 getDefaultColorFormat(omxNode, kPortIndexOutput, portMode[1],
1109 ASSERT_NE(eColorFormat, OMX_COLOR_FormatUnused);
1111 setVideoPortFormat(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
1112 eColorFormat, xFramerate);
1113 EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1114 setDefaultPortParam(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
1115 eColorFormat, nFrameWidth, nFrameHeight, 0, xFramerate);
1117 android::Vector<BufferInfo> iBuffer, oBuffer;
1119 // set state to idle
1120 changeStateLoadedtoIdle(omxNode, observer, &iBuffer, &oBuffer,
1121 kPortIndexInput, kPortIndexOutput, portMode);
1122 // set state to executing
1123 changeStateIdletoExecute(omxNode, observer);
1125 // request EOS for thumbnail
1127 while (!(Info[i].flags & OMX_BUFFERFLAG_SYNCFRAME)) i++;
1128 eleStream.open(mURL, std::ifstream::binary);
1129 ASSERT_EQ(eleStream.is_open(), true);
1130 decodeNFrames(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
1131 kPortIndexOutput, eleStream, &Info, 0, i + 1, portMode[1]);
1133 waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer,
1134 kPortIndexInput, kPortIndexOutput, portMode[1]);
1135 testEOS(omxNode, observer, &iBuffer, &oBuffer, false, eosFlag, portMode,
1136 portReconfiguration, kPortIndexInput, kPortIndexOutput, nullptr);
1137 flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
1139 EXPECT_GE(framesReceived, 1U);
1143 eleStream.open(mURL, std::ifstream::binary);
1144 ASSERT_EQ(eleStream.is_open(), true);
1145 decodeNFrames(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
1146 kPortIndexOutput, eleStream, &Info, 0, i + 1, portMode[1],
1149 waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer,
1150 kPortIndexInput, kPortIndexOutput, portMode[1]);
1151 testEOS(omxNode, observer, &iBuffer, &oBuffer, true, eosFlag, portMode,
1152 portReconfiguration, kPortIndexInput, kPortIndexOutput, nullptr);
1153 flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
1155 EXPECT_GE(framesReceived, 1U);
1159 // set state to idle
1160 changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer);
1161 // set state to executing
1162 changeStateIdletoLoaded(omxNode, observer, &iBuffer, &oBuffer,
1163 kPortIndexInput, kPortIndexOutput);
1166 // end of sequence test
1167 TEST_F(VideoDecHidlTest, SimpleEOSTest) {
1168 description("Test End of stream");
1169 if (disableTest) return;
1170 android::hardware::media::omx::V1_0::Status status;
1171 uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
1172 status = setRole(omxNode, gEnv->getRole().c_str());
1173 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1174 OMX_PORT_PARAM_TYPE params;
1175 status = getParam(omxNode, OMX_IndexParamVideoInit, ¶ms);
1176 if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
1177 ASSERT_EQ(params.nPorts, 2U);
1178 kPortIndexInput = params.nStartPortNumber;
1179 kPortIndexOutput = kPortIndexInput + 1;
1181 char mURL[512], info[512];
1182 strcpy(mURL, gEnv->getRes().c_str());
1183 strcpy(info, gEnv->getRes().c_str());
1184 GetURLForComponent(compName, mURL, info);
1186 std::ifstream eleStream, eleInfo;
1189 ASSERT_EQ(eleInfo.is_open(), true);
1190 android::Vector<FrameData> Info;
1191 int bytesCount = 0, maxBytesCount = 0;
1193 uint32_t timestamp = 0;
1195 if (!(eleInfo >> bytesCount)) break;
1197 eleInfo >> timestamp;
1198 Info.push_back({bytesCount, flags, timestamp});
1199 if (maxBytesCount < bytesCount) maxBytesCount = bytesCount;
1203 // As the frame sizes are known ahead, use it to configure i/p buffer size
1204 maxBytesCount = ALIGN_POWER_OF_TWO(maxBytesCount, 10);
1205 status = setPortBufferSize(omxNode, kPortIndexInput, maxBytesCount);
1206 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1209 status = omxNode->setPortMode(kPortIndexInput, portMode[0]);
1210 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1211 status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
1212 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1215 uint32_t nFrameWidth, nFrameHeight, xFramerate;
1216 getInputChannelInfo(omxNode, kPortIndexInput, &nFrameWidth, &nFrameHeight,
1218 // get default color format
1219 OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatUnused;
1220 getDefaultColorFormat(omxNode, kPortIndexOutput, portMode[1],
1222 ASSERT_NE(eColorFormat, OMX_COLOR_FormatUnused);
1224 setVideoPortFormat(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
1225 eColorFormat, xFramerate);
1226 EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1227 setDefaultPortParam(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
1228 eColorFormat, nFrameWidth, nFrameHeight, 0, xFramerate);
1230 android::Vector<BufferInfo> iBuffer, oBuffer;
1232 // set state to idle
1233 changeStateLoadedtoIdle(omxNode, observer, &iBuffer, &oBuffer,
1234 kPortIndexInput, kPortIndexOutput, portMode);
1235 // set state to executing
1236 changeStateIdletoExecute(omxNode, observer);
1238 // request EOS at the end
1239 eleStream.open(mURL, std::ifstream::binary);
1240 ASSERT_EQ(eleStream.is_open(), true);
1241 decodeNFrames(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
1242 kPortIndexOutput, eleStream, &Info, 0, (int)Info.size(),
1243 portMode[1], false);
1245 waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer,
1246 kPortIndexInput, kPortIndexOutput, portMode[1]);
1247 testEOS(omxNode, observer, &iBuffer, &oBuffer, true, eosFlag, portMode,
1248 portReconfiguration, kPortIndexInput, kPortIndexOutput, nullptr);
1249 flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
1254 // set state to idle
1255 changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer);
1256 // set state to executing
1257 changeStateIdletoLoaded(omxNode, observer, &iBuffer, &oBuffer,
1258 kPortIndexInput, kPortIndexOutput);
1261 // test input/output port flush
1262 TEST_F(VideoDecHidlTest, FlushTest) {
1263 description("Test Flush");
1264 if (disableTest) return;
1265 android::hardware::media::omx::V1_0::Status status;
1266 uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
1267 status = setRole(omxNode, gEnv->getRole().c_str());
1268 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1269 OMX_PORT_PARAM_TYPE params;
1270 status = getParam(omxNode, OMX_IndexParamVideoInit, ¶ms);
1271 if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
1272 ASSERT_EQ(params.nPorts, 2U);
1273 kPortIndexInput = params.nStartPortNumber;
1274 kPortIndexOutput = kPortIndexInput + 1;
1276 char mURL[512], info[512];
1277 strcpy(mURL, gEnv->getRes().c_str());
1278 strcpy(info, gEnv->getRes().c_str());
1279 GetURLForComponent(compName, mURL, info);
1281 std::ifstream eleStream, eleInfo;
1284 ASSERT_EQ(eleInfo.is_open(), true);
1285 android::Vector<FrameData> Info;
1286 int bytesCount = 0, maxBytesCount = 0;
1288 uint32_t timestamp = 0;
1290 if (!(eleInfo >> bytesCount)) break;
1292 eleInfo >> timestamp;
1293 Info.push_back({bytesCount, flags, timestamp});
1294 if (maxBytesCount < bytesCount) maxBytesCount = bytesCount;
1298 // As the frame sizes are known ahead, use it to configure i/p buffer size
1299 maxBytesCount = ALIGN_POWER_OF_TWO(maxBytesCount, 10);
1300 status = setPortBufferSize(omxNode, kPortIndexInput, maxBytesCount);
1301 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1304 status = omxNode->setPortMode(kPortIndexInput, portMode[0]);
1305 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1306 status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
1307 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1310 uint32_t nFrameWidth, nFrameHeight, xFramerate;
1311 getInputChannelInfo(omxNode, kPortIndexInput, &nFrameWidth, &nFrameHeight,
1313 // get default color format
1314 OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatUnused;
1315 getDefaultColorFormat(omxNode, kPortIndexOutput, portMode[1],
1317 ASSERT_NE(eColorFormat, OMX_COLOR_FormatUnused);
1319 setVideoPortFormat(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
1320 eColorFormat, xFramerate);
1321 EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1322 setDefaultPortParam(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
1323 eColorFormat, nFrameWidth, nFrameHeight, 0, xFramerate);
1325 android::Vector<BufferInfo> iBuffer, oBuffer;
1327 // set state to idle
1328 changeStateLoadedtoIdle(omxNode, observer, &iBuffer, &oBuffer,
1329 kPortIndexInput, kPortIndexOutput, portMode);
1330 // set state to executing
1331 changeStateIdletoExecute(omxNode, observer);
1333 // Decode 128 frames and flush. here 128 is chosen to ensure there is a key
1334 // frame after this so that the below section can be convered for all
1337 eleStream.open(mURL, std::ifstream::binary);
1338 ASSERT_EQ(eleStream.is_open(), true);
1339 decodeNFrames(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
1340 kPortIndexOutput, eleStream, &Info, 0, nFrames, portMode[1],
1342 flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
1346 // Seek to next key frame and start decoding till the end
1347 int index = nFrames;
1348 bool keyFrame = false;
1349 while (index < (int)Info.size()) {
1350 if ((Info[index].flags & OMX_BUFFERFLAG_SYNCFRAME) ==
1351 OMX_BUFFERFLAG_SYNCFRAME) {
1352 timestampUs = Info[index - 1].timestamp;
1356 eleStream.ignore(Info[index].bytesCount);
1360 decodeNFrames(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
1361 kPortIndexOutput, eleStream, &Info, index,
1362 Info.size() - index, portMode[1], false);
1365 flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
1369 // set state to idle
1370 changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer);
1371 // set state to executing
1372 changeStateIdletoLoaded(omxNode, observer, &iBuffer, &oBuffer,
1373 kPortIndexInput, kPortIndexOutput);
1376 int main(int argc, char** argv) {
1377 gEnv = new ComponentTestEnvironment();
1378 ::testing::AddGlobalTestEnvironment(gEnv);
1379 ::testing::InitGoogleTest(&argc, argv);
1380 int status = gEnv->initFromOptions(argc, argv);
1382 status = RUN_ALL_TESTS();
1383 ALOGI("Test result = %d", status);