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 virtual void SetUp() override {
142 android::hardware::media::omx::V1_0::Status status;
143 omx = ::testing::VtsHalHidlTargetTestBase::getService<IOmx>(
144 gEnv->getInstance());
145 ASSERT_NE(omx, nullptr);
147 new CodecObserver([this](Message msg, const BufferInfo* buffer) {
148 handleMessage(msg, buffer);
150 ASSERT_NE(observer, nullptr);
151 if (strncmp(gEnv->getComponent().c_str(), "OMX.", 4) != 0)
153 EXPECT_TRUE(omx->allocateNode(
154 gEnv->getComponent(), observer,
155 [&](android::hardware::media::omx::V1_0::Status _s,
156 sp<IOmxNode> const& _nl) {
161 ASSERT_NE(omxNode, nullptr);
162 ASSERT_NE(gEnv->getRole().empty(), true) << "Invalid Component Role";
163 struct StringToName {
165 standardComp CompName;
167 const StringToName kStringToName[] = {
168 {"h263", h263}, {"avc", avc}, {"mpeg2", mpeg2}, {"mpeg4", mpeg4},
169 {"hevc", hevc}, {"vp8", vp8}, {"vp9", vp9},
171 const size_t kNumStringToName =
172 sizeof(kStringToName) / sizeof(kStringToName[0]);
174 char substring[OMX_MAX_STRINGNAME_SIZE];
175 strcpy(substring, gEnv->getRole().c_str());
176 pch = strchr(substring, '.');
177 ASSERT_NE(pch, nullptr);
178 compName = unknown_comp;
179 for (size_t i = 0; i < kNumStringToName; ++i) {
180 if (!strcasecmp(pch + 1, kStringToName[i].Name)) {
181 compName = kStringToName[i].CompName;
185 if (compName == unknown_comp) disableTest = true;
186 struct CompToCompression {
187 standardComp CompName;
188 OMX_VIDEO_CODINGTYPE eCompressionFormat;
190 static const CompToCompression kCompToCompression[] = {
191 {h263, OMX_VIDEO_CodingH263}, {avc, OMX_VIDEO_CodingAVC},
192 {mpeg2, OMX_VIDEO_CodingMPEG2}, {mpeg4, OMX_VIDEO_CodingMPEG4},
193 {hevc, OMX_VIDEO_CodingHEVC}, {vp8, OMX_VIDEO_CodingVP8},
194 {vp9, OMX_VIDEO_CodingVP9},
196 static const size_t kNumCompToCompression =
197 sizeof(kCompToCompression) / sizeof(kCompToCompression[0]);
199 for (i = 0; i < kNumCompToCompression; ++i) {
200 if (kCompToCompression[i].CompName == compName) {
201 eCompressionFormat = kCompToCompression[i].eCompressionFormat;
205 if (i == kNumCompToCompression) disableTest = true;
206 portMode[0] = portMode[1] = PortMode::PRESET_BYTE_BUFFER;
210 timestampDevTest = false;
212 size_t suffixLen = strlen(".secure");
213 if (strlen(gEnv->getComponent().c_str()) >= suffixLen) {
215 !strcmp(gEnv->getComponent().c_str() +
216 strlen(gEnv->getComponent().c_str()) - suffixLen,
219 if (isSecure) disableTest = true;
220 if (disableTest) std::cout << "[ ] Warning ! Test Disabled\n";
223 virtual void TearDown() override {
224 if (omxNode != nullptr) {
225 EXPECT_TRUE((omxNode->freeNode()).isOk());
230 // callback function to process messages received by onMessages() from IL
232 void handleMessage(Message msg, const BufferInfo* buffer) {
234 if (msg.type == Message::Type::FILL_BUFFER_DONE) {
235 if (msg.data.extendedBufferData.flags & OMX_BUFFERFLAG_EOS) {
238 if (msg.data.extendedBufferData.rangeLength != 0) {
240 // For decoder components current timestamp always exceeds
241 // previous timestamp
242 EXPECT_GE(msg.data.extendedBufferData.timestampUs, timestampUs);
243 timestampUs = msg.data.extendedBufferData.timestampUs;
244 // Test if current timestamp is among the list of queued
246 if (timestampDevTest) {
248 android::List<uint64_t>::iterator it =
249 timestampUslist.begin();
250 while (it != timestampUslist.end()) {
251 if (*it == timestampUs) {
252 timestampUslist.erase(it);
258 if (tsHit == false) {
259 if (timestampUslist.empty() == false) {
260 EXPECT_EQ(tsHit, true)
261 << "TimeStamp not recognized";
264 << "[ ] Warning ! Received non-zero "
265 "output / TimeStamp not recognized \n";
269 #define WRITE_OUTPUT 0
271 static int count = 0;
274 ofp = fopen("out.bin", "ab");
276 ofp = fopen("out.bin", "wb");
277 if (ofp != nullptr &&
278 portMode[1] == PortMode::PRESET_BYTE_BUFFER) {
279 fwrite(static_cast<void*>(buffer->mMemory->getPointer()),
281 msg.data.extendedBufferData.rangeLength, ofp);
302 sp<CodecObserver> observer;
303 sp<IOmxNode> omxNode;
304 standardComp compName;
305 OMX_VIDEO_CODINGTYPE eCompressionFormat;
307 PortMode portMode[2];
309 uint32_t framesReceived;
310 uint64_t timestampUs;
311 ::android::List<uint64_t> timestampUslist;
312 bool timestampDevTest;
316 static void description(const std::string& description) {
317 RecordProperty("description", description);
321 // Set Default port param.
322 void setDefaultPortParam(sp<IOmxNode> omxNode, OMX_U32 portIndex,
323 OMX_VIDEO_CODINGTYPE eCompressionFormat,
324 OMX_COLOR_FORMATTYPE eColorFormat,
325 OMX_U32 nFrameWidth = 352, OMX_U32 nFrameHeight = 288,
326 OMX_U32 nBitrate = 0,
327 OMX_U32 xFramerate = (24U << 16)) {
328 switch ((int)eCompressionFormat) {
329 case OMX_VIDEO_CodingUnused:
330 setupRAWPort(omxNode, portIndex, nFrameWidth, nFrameHeight,
331 nBitrate, xFramerate, eColorFormat);
338 // In decoder components, often the input port parameters get updated upon
339 // parsing the header of elementary stream. Client needs to collect this
340 // information to reconfigure other ports that share data with this input
342 void getInputChannelInfo(sp<IOmxNode> omxNode, OMX_U32 kPortIndexInput,
343 uint32_t* nFrameWidth, uint32_t* nFrameHeight,
344 uint32_t* xFramerate) {
345 android::hardware::media::omx::V1_0::Status status;
348 *xFramerate = (24U << 16);
350 OMX_PARAM_PORTDEFINITIONTYPE portDef;
351 status = getPortParam(omxNode, OMX_IndexParamPortDefinition,
352 kPortIndexInput, &portDef);
353 EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
354 if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
355 *nFrameWidth = portDef.format.video.nFrameWidth;
356 *nFrameHeight = portDef.format.video.nFrameHeight;
357 *xFramerate = portDef.format.video.xFramerate;
361 // LookUpTable of clips and metadata for component testing
362 void GetURLForComponent(VideoDecHidlTest::standardComp comp, char* mURL,
365 VideoDecHidlTest::standardComp comp;
369 static const CompToURL kCompToURL[] = {
370 {VideoDecHidlTest::standardComp::avc,
371 "bbb_avc_1920x1080_5000kbps_30fps.h264",
372 "bbb_avc_1920x1080_5000kbps_30fps.info"},
373 {VideoDecHidlTest::standardComp::hevc,
374 "bbb_hevc_640x360_1600kbps_30fps.hevc",
375 "bbb_hevc_640x360_1600kbps_30fps.info"},
376 {VideoDecHidlTest::standardComp::mpeg2,
377 "bbb_mpeg2_176x144_105kbps_25fps.m2v",
378 "bbb_mpeg2_176x144_105kbps_25fps.info"},
379 {VideoDecHidlTest::standardComp::h263,
380 "bbb_h263_352x288_300kbps_12fps.h263",
381 "bbb_h263_352x288_300kbps_12fps.info"},
382 {VideoDecHidlTest::standardComp::mpeg4,
383 "bbb_mpeg4_1280x720_1000kbps_25fps.m4v",
384 "bbb_mpeg4_1280x720_1000kbps_25fps.info"},
385 {VideoDecHidlTest::standardComp::vp8, "bbb_vp8_640x360_2mbps_30fps.vp8",
386 "bbb_vp8_640x360_2mbps_30fps.info"},
387 {VideoDecHidlTest::standardComp::vp9,
388 "bbb_vp9_640x360_1600kbps_30fps.vp9",
389 "bbb_vp9_640x360_1600kbps_30fps.info"},
392 for (size_t i = 0; i < sizeof(kCompToURL) / sizeof(kCompToURL[0]); ++i) {
393 if (kCompToURL[i].comp == comp) {
394 strcat(mURL, kCompToURL[i].mURL);
395 strcat(info, kCompToURL[i].info);
401 void allocateGraphicBuffers(sp<IOmxNode> omxNode, OMX_U32 portIndex,
402 android::Vector<BufferInfo>* buffArray,
403 uint32_t nFrameWidth, uint32_t nFrameHeight,
404 int32_t* nStride, int format, uint32_t count) {
405 android::hardware::media::omx::V1_0::Status status;
406 sp<android::hardware::graphics::allocator::V2_0::IAllocator> allocator =
407 android::hardware::graphics::allocator::V2_0::IAllocator::getService();
408 ASSERT_NE(nullptr, allocator.get());
410 sp<android::hardware::graphics::mapper::V2_0::IMapper> mapper =
411 android::hardware::graphics::mapper::V2_0::IMapper::getService();
412 ASSERT_NE(mapper.get(), nullptr);
414 android::hardware::graphics::mapper::V2_0::IMapper::BufferDescriptorInfo
418 descriptorInfo.width = nFrameWidth;
419 descriptorInfo.height = nFrameHeight;
420 descriptorInfo.layerCount = 1;
421 descriptorInfo.format = static_cast<PixelFormat>(format);
422 descriptorInfo.usage = static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN);
423 omxNode->getGraphicBufferUsage(
425 [&status, &usage](android::hardware::media::omx::V1_0::Status _s,
430 if (status == android::hardware::media::omx::V1_0::Status::OK) {
431 descriptorInfo.usage |= usage;
434 ::android::hardware::hidl_vec<uint32_t> descriptor;
435 android::hardware::graphics::mapper::V2_0::Error error;
436 mapper->createDescriptor(
437 descriptorInfo, [&error, &descriptor](
438 android::hardware::graphics::mapper::V2_0::Error _s,
439 ::android::hardware::hidl_vec<uint32_t> _n1) {
443 EXPECT_EQ(error, android::hardware::graphics::mapper::V2_0::Error::NONE);
445 EXPECT_EQ(buffArray->size(), count);
447 static volatile int32_t nextId = 0;
448 uint64_t id = static_cast<uint64_t>(getpid()) << 32;
451 [&](android::hardware::graphics::mapper::V2_0::Error _s, uint32_t _n1,
452 const ::android::hardware::hidl_vec<
453 ::android::hardware::hidl_handle>& _n2) {
454 ASSERT_EQ(android::hardware::graphics::mapper::V2_0::Error::NONE,
457 ASSERT_EQ(count, _n2.size());
458 for (uint32_t i = 0; i < count; i++) {
459 buffArray->editItemAt(i).omxBuffer.nativeHandle = _n2[i];
460 buffArray->editItemAt(i).omxBuffer.attr.anwBuffer.width =
462 buffArray->editItemAt(i).omxBuffer.attr.anwBuffer.height =
464 buffArray->editItemAt(i).omxBuffer.attr.anwBuffer.stride = _n1;
465 buffArray->editItemAt(i).omxBuffer.attr.anwBuffer.format =
466 descriptorInfo.format;
467 buffArray->editItemAt(i).omxBuffer.attr.anwBuffer.usage =
468 descriptorInfo.usage;
469 buffArray->editItemAt(i).omxBuffer.attr.anwBuffer.layerCount =
470 descriptorInfo.layerCount;
471 buffArray->editItemAt(i).omxBuffer.attr.anwBuffer.id =
472 id | static_cast<uint32_t>(android_atomic_inc(&nextId));
477 // port settings reconfiguration during runtime. reconfigures frame dimensions
478 void portReconfiguration(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
479 android::Vector<BufferInfo>* iBuffer,
480 android::Vector<BufferInfo>* oBuffer,
481 OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput,
482 Message msg, PortMode oPortMode, void* args) {
483 android::hardware::media::omx::V1_0::Status status;
486 if (msg.data.eventData.event == OMX_EventPortSettingsChanged) {
487 ASSERT_EQ(msg.data.eventData.data1, kPortIndexOutput);
488 if (msg.data.eventData.data2 == OMX_IndexParamPortDefinition ||
489 msg.data.eventData.data2 == 0) {
490 status = omxNode->sendCommand(
491 toRawCommandType(OMX_CommandPortDisable), kPortIndexOutput);
492 ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
494 status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer,
497 android::hardware::media::omx::V1_0::Status::TIMED_OUT) {
498 for (size_t i = 0; i < oBuffer->size(); ++i) {
499 // test if client got all its buffers back
500 EXPECT_EQ((*oBuffer)[i].owner, client);
503 omxNode->freeBuffer(kPortIndexOutput, (*oBuffer)[i].id);
505 android::hardware::media::omx::V1_0::Status::OK);
507 status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
510 android::hardware::media::omx::V1_0::Status::OK);
511 ASSERT_EQ(msg.type, Message::Type::EVENT);
512 ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
513 ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortDisable);
514 ASSERT_EQ(msg.data.eventData.data2, kPortIndexOutput);
517 uint32_t nFrameWidth, nFrameHeight, xFramerate;
518 getInputChannelInfo(omxNode, kPortIndexInput, &nFrameWidth,
519 &nFrameHeight, &xFramerate);
520 // get configured color format
521 OMX_PARAM_PORTDEFINITIONTYPE portDef;
522 status = getPortParam(omxNode, OMX_IndexParamPortDefinition,
523 kPortIndexOutput, &portDef);
524 setDefaultPortParam(omxNode, kPortIndexOutput,
525 OMX_VIDEO_CodingUnused,
526 portDef.format.video.eColorFormat,
527 nFrameWidth, nFrameHeight, 0, xFramerate);
529 // If you can disable a port, then you should be able to
532 status = omxNode->sendCommand(
533 toRawCommandType(OMX_CommandPortEnable), kPortIndexOutput);
535 android::hardware::media::omx::V1_0::Status::OK);
537 // do not enable the port until all the buffers are supplied
538 status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
542 android::hardware::media::omx::V1_0::Status::TIMED_OUT);
544 allocatePortBuffers(omxNode, oBuffer, kPortIndexOutput,
546 if (oPortMode != PortMode::PRESET_BYTE_BUFFER) {
547 OMX_PARAM_PORTDEFINITIONTYPE portDef;
549 status = getPortParam(omxNode, OMX_IndexParamPortDefinition,
550 kPortIndexOutput, &portDef);
553 ::android::hardware::media::omx::V1_0::Status::OK);
554 allocateGraphicBuffers(omxNode, kPortIndexOutput, oBuffer,
555 portDef.format.video.nFrameWidth,
556 portDef.format.video.nFrameHeight,
557 &portDef.format.video.nStride,
558 portDef.format.video.eColorFormat,
559 portDef.nBufferCountActual);
561 status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
564 android::hardware::media::omx::V1_0::Status::OK);
565 ASSERT_EQ(msg.type, Message::Type::EVENT);
566 ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortEnable);
567 ASSERT_EQ(msg.data.eventData.data2, kPortIndexOutput);
569 // dispatch output buffers
570 for (size_t i = 0; i < oBuffer->size(); i++) {
571 dispatchOutputBuffer(omxNode, oBuffer, i, oPortMode);
576 } else if (msg.data.eventData.data2 ==
577 OMX_IndexConfigCommonOutputCrop) {
578 std::cout << "[ ] Warning ! OMX_EventPortSettingsChanged/ "
579 "OMX_IndexConfigCommonOutputCrop not handled \n";
580 } else if (msg.data.eventData.data2 == OMX_IndexVendorStartUnused + 3) {
581 std::cout << "[ ] Warning ! OMX_EventPortSettingsChanged/ "
582 "kDescribeColorAspectsIndex not handled \n";
584 } else if (msg.data.eventData.event == OMX_EventError) {
585 std::cout << "[ ] Warning ! OMX_EventError/ "
586 "Decode Frame Call might be failed \n";
589 // something unexpected happened
594 // blocking call to ensures application to Wait till all the inputs are consumed
595 void waitOnInputConsumption(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
596 android::Vector<BufferInfo>* iBuffer,
597 android::Vector<BufferInfo>* oBuffer,
598 OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput,
599 PortMode oPortMode) {
600 android::hardware::media::omx::V1_0::Status status;
602 int timeOut = TIMEOUT_COUNTER;
607 observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
608 if (status == android::hardware::media::omx::V1_0::Status::OK) {
609 EXPECT_EQ(msg.type, Message::Type::EVENT);
610 portReconfiguration(omxNode, observer, iBuffer, oBuffer,
611 kPortIndexInput, kPortIndexOutput, msg,
614 // status == TIMED_OUT, it could be due to process time being large
615 // than DEFAULT_TIMEOUT or component needs output buffers to start
617 for (; i < iBuffer->size(); i++) {
618 if ((*iBuffer)[i].owner != client) break;
620 if (i == iBuffer->size()) break;
622 // Dispatch an output buffer assuming outQueue.empty() is true
624 if ((index = getEmptyBufferID(oBuffer)) < oBuffer->size()) {
625 dispatchOutputBuffer(omxNode, oBuffer, index, oPortMode);
632 void decodeNFrames(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
633 android::Vector<BufferInfo>* iBuffer,
634 android::Vector<BufferInfo>* oBuffer,
635 OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput,
636 std::ifstream& eleStream, android::Vector<FrameData>* Info,
637 int offset, int range, PortMode oPortMode,
638 bool signalEOS = true) {
639 android::hardware::media::omx::V1_0::Status status;
642 // dispatch output buffers
643 for (size_t i = 0; i < oBuffer->size(); i++) {
644 dispatchOutputBuffer(omxNode, oBuffer, i, oPortMode);
646 // dispatch input buffers
648 int frameID = offset;
649 for (size_t i = 0; (i < iBuffer->size()) && (frameID < (int)Info->size()) &&
650 (frameID < (offset + range));
652 char* ipBuffer = static_cast<char*>(
653 static_cast<void*>((*iBuffer)[i].mMemory->getPointer()));
654 ASSERT_LE((*Info)[frameID].bytesCount,
655 static_cast<int>((*iBuffer)[i].mMemory->getSize()));
656 eleStream.read(ipBuffer, (*Info)[frameID].bytesCount);
657 ASSERT_EQ(eleStream.gcount(), (*Info)[frameID].bytesCount);
658 flags = (*Info)[frameID].flags;
659 if (signalEOS && ((frameID == (int)Info->size() - 1) ||
660 (frameID == (offset + range - 1))))
661 flags |= OMX_BUFFERFLAG_EOS;
662 dispatchInputBuffer(omxNode, iBuffer, i, (*Info)[frameID].bytesCount,
663 flags, (*Info)[frameID].timestamp);
667 int timeOut = TIMEOUT_COUNTER;
671 observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
673 // Port Reconfiguration
674 if (status == android::hardware::media::omx::V1_0::Status::OK &&
675 msg.type == Message::Type::EVENT) {
676 portReconfiguration(omxNode, observer, iBuffer, oBuffer,
677 kPortIndexInput, kPortIndexOutput, msg,
681 if (frameID == (int)Info->size() || frameID == (offset + range)) break;
683 // Dispatch input buffer
685 if ((index = getEmptyBufferID(iBuffer)) < iBuffer->size()) {
686 char* ipBuffer = static_cast<char*>(
687 static_cast<void*>((*iBuffer)[index].mMemory->getPointer()));
688 ASSERT_LE((*Info)[frameID].bytesCount,
689 static_cast<int>((*iBuffer)[index].mMemory->getSize()));
690 eleStream.read(ipBuffer, (*Info)[frameID].bytesCount);
691 ASSERT_EQ(eleStream.gcount(), (*Info)[frameID].bytesCount);
692 flags = (*Info)[frameID].flags;
693 if (signalEOS && ((frameID == (int)Info->size() - 1) ||
694 (frameID == (offset + range - 1))))
695 flags |= OMX_BUFFERFLAG_EOS;
696 dispatchInputBuffer(omxNode, iBuffer, index,
697 (*Info)[frameID].bytesCount, flags,
698 (*Info)[frameID].timestamp);
703 if ((index = getEmptyBufferID(oBuffer)) < oBuffer->size()) {
704 dispatchOutputBuffer(omxNode, oBuffer, index, oPortMode);
711 timeOut = TIMEOUT_COUNTER;
713 EXPECT_TRUE(false) << "Wait on Input/Output is found indefinite";
719 // DescribeColorFormatParams Copy Constructor (Borrowed from OMXUtils.cpp)
720 android::DescribeColorFormatParams::DescribeColorFormatParams(
721 const android::DescribeColorFormat2Params& params) {
722 eColorFormat = params.eColorFormat;
723 nFrameWidth = params.nFrameWidth;
724 nFrameHeight = params.nFrameHeight;
725 nStride = params.nStride;
726 nSliceHeight = params.nSliceHeight;
727 bUsingNativeBuffers = params.bUsingNativeBuffers;
730 bool isColorFormatFlexibleYUV(sp<IOmxNode> omxNode,
731 OMX_COLOR_FORMATTYPE eColorFormat) {
732 android::hardware::media::omx::V1_0::Status status;
733 unsigned int index = OMX_IndexMax, index2 = OMX_IndexMax;
734 omxNode->getExtensionIndex(
735 "OMX.google.android.index.describeColorFormat",
736 [&index](android::hardware::media::omx::V1_0::Status _s,
738 if (_s == ::android::hardware::media::omx::V1_0::Status::OK)
741 omxNode->getExtensionIndex(
742 "OMX.google.android.index.describeColorFormat2",
743 [&index2](android::hardware::media::omx::V1_0::Status _s,
745 if (_s == ::android::hardware::media::omx::V1_0::Status::OK)
749 android::DescribeColorFormat2Params describeParams;
750 describeParams.eColorFormat = eColorFormat;
751 describeParams.nFrameWidth = 128;
752 describeParams.nFrameHeight = 128;
753 describeParams.nStride = 128;
754 describeParams.nSliceHeight = 128;
755 describeParams.bUsingNativeBuffers = OMX_FALSE;
756 if (index != OMX_IndexMax) {
757 android::DescribeColorFormatParams describeParamsV1(describeParams);
758 status = getParam(omxNode, static_cast<OMX_INDEXTYPE>(index),
760 if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
761 android::MediaImage& img = describeParamsV1.sMediaImage;
762 if (img.mType == android::MediaImage::MEDIA_IMAGE_TYPE_YUV) {
763 if (img.mNumPlanes == 3 &&
764 img.mPlane[img.Y].mHorizSubsampling == 1 &&
765 img.mPlane[img.Y].mVertSubsampling == 1) {
766 if (img.mPlane[img.U].mHorizSubsampling == 2 &&
767 img.mPlane[img.U].mVertSubsampling == 2 &&
768 img.mPlane[img.V].mHorizSubsampling == 2 &&
769 img.mPlane[img.V].mVertSubsampling == 2) {
770 if (img.mBitDepth <= 8) {
777 } else if (index2 != OMX_IndexMax) {
778 status = getParam(omxNode, static_cast<OMX_INDEXTYPE>(index2),
780 android::MediaImage2& img = describeParams.sMediaImage;
781 if (img.mType == android::MediaImage2::MEDIA_IMAGE_TYPE_YUV) {
782 if (img.mNumPlanes == 3 &&
783 img.mPlane[img.Y].mHorizSubsampling == 1 &&
784 img.mPlane[img.Y].mVertSubsampling == 1) {
785 if (img.mPlane[img.U].mHorizSubsampling == 2 &&
786 img.mPlane[img.U].mVertSubsampling == 2 &&
787 img.mPlane[img.V].mHorizSubsampling == 2 &&
788 img.mPlane[img.V].mVertSubsampling == 2) {
789 if (img.mBitDepth <= 8) {
799 // get default color format for output port
800 void getDefaultColorFormat(sp<IOmxNode> omxNode, OMX_U32 kPortIndexOutput,
802 OMX_COLOR_FORMATTYPE* eColorFormat) {
803 android::hardware::media::omx::V1_0::Status status;
804 OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat;
805 *eColorFormat = OMX_COLOR_FormatUnused;
806 portFormat.nIndex = 0;
808 status = getPortParam(omxNode, OMX_IndexParamVideoPortFormat,
809 kPortIndexOutput, &portFormat);
810 if (status != ::android::hardware::media::omx::V1_0::Status::OK) break;
811 EXPECT_EQ(portFormat.eCompressionFormat, OMX_VIDEO_CodingUnused);
812 if (oPortMode != PortMode::PRESET_BYTE_BUFFER) {
813 *eColorFormat = portFormat.eColorFormat;
816 if (isColorFormatFlexibleYUV(omxNode, portFormat.eColorFormat)) {
817 *eColorFormat = portFormat.eColorFormat;
820 if (OMX_COLOR_FormatYUV420SemiPlanar == portFormat.eColorFormat ||
821 OMX_COLOR_FormatYUV420Planar == portFormat.eColorFormat) {
822 *eColorFormat = portFormat.eColorFormat;
829 // set component role
830 TEST_F(VideoDecHidlTest, SetRole) {
831 description("Test Set Component Role");
832 if (disableTest) return;
833 android::hardware::media::omx::V1_0::Status status;
834 status = setRole(omxNode, gEnv->getRole().c_str());
835 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
838 // port format enumeration
839 TEST_F(VideoDecHidlTest, EnumeratePortFormat) {
840 description("Test Component on Mandatory Port Parameters (Port Format)");
841 if (disableTest) return;
842 android::hardware::media::omx::V1_0::Status status;
843 uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
844 OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatYUV420Planar;
845 OMX_U32 xFramerate = (24U << 16);
846 status = setRole(omxNode, gEnv->getRole().c_str());
847 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
848 OMX_PORT_PARAM_TYPE params;
849 status = getParam(omxNode, OMX_IndexParamVideoInit, ¶ms);
850 if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
851 ASSERT_EQ(params.nPorts, 2U);
852 kPortIndexInput = params.nStartPortNumber;
853 kPortIndexOutput = kPortIndexInput + 1;
855 status = setVideoPortFormat(omxNode, kPortIndexInput, eCompressionFormat,
856 OMX_COLOR_FormatUnused, 0U);
857 EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
859 setVideoPortFormat(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
860 eColorFormat, xFramerate);
861 EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
864 // test port settings reconfiguration, elementary stream decode and timestamp
866 TEST_F(VideoDecHidlTest, DecodeTest) {
867 description("Tests Port Reconfiguration, Decode and timestamp deviation");
868 if (disableTest) return;
869 android::hardware::media::omx::V1_0::Status status;
870 uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
871 status = setRole(omxNode, gEnv->getRole().c_str());
872 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
873 OMX_PORT_PARAM_TYPE params;
874 status = getParam(omxNode, OMX_IndexParamVideoInit, ¶ms);
875 if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
876 ASSERT_EQ(params.nPorts, 2U);
877 kPortIndexInput = params.nStartPortNumber;
878 kPortIndexOutput = kPortIndexInput + 1;
880 char mURL[512], info[512];
881 strcpy(mURL, gEnv->getRes().c_str());
882 strcpy(info, gEnv->getRes().c_str());
883 GetURLForComponent(compName, mURL, info);
885 std::ifstream eleStream, eleInfo;
888 ASSERT_EQ(eleInfo.is_open(), true);
889 android::Vector<FrameData> Info;
890 int bytesCount = 0, maxBytesCount = 0;
892 uint32_t timestamp = 0;
893 timestampDevTest = true;
895 if (!(eleInfo >> bytesCount)) break;
897 eleInfo >> timestamp;
898 Info.push_back({bytesCount, flags, timestamp});
899 if (flags != OMX_BUFFERFLAG_CODECCONFIG)
900 timestampUslist.push_back(timestamp);
901 if (maxBytesCount < bytesCount) maxBytesCount = bytesCount;
905 // As the frame sizes are known ahead, use it to configure i/p buffer size
906 maxBytesCount = ALIGN_POWER_OF_TWO(maxBytesCount, 10);
907 status = setPortBufferSize(omxNode, kPortIndexInput, maxBytesCount);
908 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
911 portMode[0] = PortMode::PRESET_BYTE_BUFFER;
912 portMode[1] = PortMode::DYNAMIC_ANW_BUFFER;
913 status = omxNode->setPortMode(kPortIndexInput, portMode[0]);
914 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
915 status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
916 if (status != ::android::hardware::media::omx::V1_0::Status::OK) {
917 portMode[1] = PortMode::PRESET_BYTE_BUFFER;
918 status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
919 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
923 uint32_t nFrameWidth, nFrameHeight, xFramerate;
924 getInputChannelInfo(omxNode, kPortIndexInput, &nFrameWidth, &nFrameHeight,
926 // get default color format
927 OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatUnused;
928 getDefaultColorFormat(omxNode, kPortIndexOutput, portMode[1],
930 ASSERT_NE(eColorFormat, OMX_COLOR_FormatUnused);
932 setVideoPortFormat(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
933 eColorFormat, xFramerate);
934 EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
935 setDefaultPortParam(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
936 eColorFormat, nFrameWidth, nFrameHeight, 0, xFramerate);
938 // disabling adaptive playback.
939 omxNode->prepareForAdaptivePlayback(kPortIndexOutput, false, 1920, 1080);
941 android::Vector<BufferInfo> iBuffer, oBuffer;
944 changeStateLoadedtoIdle(omxNode, observer, &iBuffer, &oBuffer,
945 kPortIndexInput, kPortIndexOutput, portMode);
946 // set state to executing
947 changeStateIdletoExecute(omxNode, observer);
949 if (portMode[1] != PortMode::PRESET_BYTE_BUFFER) {
950 OMX_PARAM_PORTDEFINITIONTYPE portDef;
952 status = getPortParam(omxNode, OMX_IndexParamPortDefinition,
953 kPortIndexOutput, &portDef);
954 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
955 allocateGraphicBuffers(
956 omxNode, kPortIndexOutput, &oBuffer,
957 portDef.format.video.nFrameWidth, portDef.format.video.nFrameHeight,
958 &portDef.format.video.nStride, portDef.format.video.eColorFormat,
959 portDef.nBufferCountActual);
962 // Port Reconfiguration
963 eleStream.open(mURL, std::ifstream::binary);
964 ASSERT_EQ(eleStream.is_open(), true);
965 decodeNFrames(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
966 kPortIndexOutput, eleStream, &Info, 0, (int)Info.size(),
969 waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer,
970 kPortIndexInput, kPortIndexOutput, portMode[1]);
971 testEOS(omxNode, observer, &iBuffer, &oBuffer, false, eosFlag, portMode,
972 portReconfiguration, kPortIndexInput, kPortIndexOutput, nullptr);
973 EXPECT_EQ(timestampUslist.empty(), true);
975 changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer);
976 // set state to executing
977 changeStateIdletoLoaded(omxNode, observer, &iBuffer, &oBuffer,
978 kPortIndexInput, kPortIndexOutput);
981 // end of sequence test
982 TEST_F(VideoDecHidlTest, EOSTest_M) {
983 description("Test End of stream monkeying");
984 if (disableTest) return;
985 android::hardware::media::omx::V1_0::Status status;
986 uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
987 status = setRole(omxNode, gEnv->getRole().c_str());
988 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
989 OMX_PORT_PARAM_TYPE params;
990 status = getParam(omxNode, OMX_IndexParamVideoInit, ¶ms);
991 if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
992 ASSERT_EQ(params.nPorts, 2U);
993 kPortIndexInput = params.nStartPortNumber;
994 kPortIndexOutput = kPortIndexInput + 1;
998 status = omxNode->setPortMode(kPortIndexInput, portMode[0]);
999 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1000 status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
1001 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1004 uint32_t nFrameWidth, nFrameHeight, xFramerate;
1005 getInputChannelInfo(omxNode, kPortIndexInput, &nFrameWidth, &nFrameHeight,
1007 // get default color format
1008 OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatUnused;
1009 getDefaultColorFormat(omxNode, kPortIndexOutput, portMode[1],
1011 ASSERT_NE(eColorFormat, OMX_COLOR_FormatUnused);
1013 setVideoPortFormat(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
1014 eColorFormat, xFramerate);
1015 EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1016 setDefaultPortParam(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
1017 eColorFormat, nFrameWidth, nFrameHeight, 0, xFramerate);
1019 android::Vector<BufferInfo> iBuffer, oBuffer;
1021 // set state to idle
1022 changeStateLoadedtoIdle(omxNode, observer, &iBuffer, &oBuffer,
1023 kPortIndexInput, kPortIndexOutput, portMode);
1024 // set state to executing
1025 changeStateIdletoExecute(omxNode, observer);
1027 // request EOS at the start
1028 testEOS(omxNode, observer, &iBuffer, &oBuffer, true, eosFlag, portMode,
1029 portReconfiguration, kPortIndexInput, kPortIndexOutput, nullptr);
1030 flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
1032 EXPECT_GE(framesReceived, 0U);
1036 // set state to idle
1037 changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer);
1038 // set state to executing
1039 changeStateIdletoLoaded(omxNode, observer, &iBuffer, &oBuffer,
1040 kPortIndexInput, kPortIndexOutput);
1043 // end of sequence test
1044 TEST_F(VideoDecHidlTest, ThumbnailTest) {
1045 description("Test Request for thumbnail");
1046 if (disableTest) return;
1047 android::hardware::media::omx::V1_0::Status status;
1048 uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
1049 status = setRole(omxNode, gEnv->getRole().c_str());
1050 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1051 OMX_PORT_PARAM_TYPE params;
1052 status = getParam(omxNode, OMX_IndexParamVideoInit, ¶ms);
1053 if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
1054 ASSERT_EQ(params.nPorts, 2U);
1055 kPortIndexInput = params.nStartPortNumber;
1056 kPortIndexOutput = kPortIndexInput + 1;
1058 char mURL[512], info[512];
1059 strcpy(mURL, gEnv->getRes().c_str());
1060 strcpy(info, gEnv->getRes().c_str());
1061 GetURLForComponent(compName, mURL, info);
1063 std::ifstream eleStream, eleInfo;
1066 ASSERT_EQ(eleInfo.is_open(), true);
1067 android::Vector<FrameData> Info;
1068 int bytesCount = 0, maxBytesCount = 0;
1070 uint32_t timestamp = 0;
1072 if (!(eleInfo >> bytesCount)) break;
1074 eleInfo >> timestamp;
1075 Info.push_back({bytesCount, flags, timestamp});
1076 if (maxBytesCount < bytesCount) maxBytesCount = bytesCount;
1080 // As the frame sizes are known ahead, use it to configure i/p buffer size
1081 maxBytesCount = ALIGN_POWER_OF_TWO(maxBytesCount, 10);
1082 status = setPortBufferSize(omxNode, kPortIndexInput, maxBytesCount);
1083 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1086 status = omxNode->setPortMode(kPortIndexInput, portMode[0]);
1087 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1088 status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
1089 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1092 uint32_t nFrameWidth, nFrameHeight, xFramerate;
1093 getInputChannelInfo(omxNode, kPortIndexInput, &nFrameWidth, &nFrameHeight,
1095 // get default color format
1096 OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatUnused;
1097 getDefaultColorFormat(omxNode, kPortIndexOutput, portMode[1],
1099 ASSERT_NE(eColorFormat, OMX_COLOR_FormatUnused);
1101 setVideoPortFormat(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
1102 eColorFormat, xFramerate);
1103 EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1104 setDefaultPortParam(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
1105 eColorFormat, nFrameWidth, nFrameHeight, 0, xFramerate);
1107 android::Vector<BufferInfo> iBuffer, oBuffer;
1109 // set state to idle
1110 changeStateLoadedtoIdle(omxNode, observer, &iBuffer, &oBuffer,
1111 kPortIndexInput, kPortIndexOutput, portMode);
1112 // set state to executing
1113 changeStateIdletoExecute(omxNode, observer);
1115 // request EOS for thumbnail
1117 while (!(Info[i].flags & OMX_BUFFERFLAG_SYNCFRAME)) i++;
1118 eleStream.open(mURL, std::ifstream::binary);
1119 ASSERT_EQ(eleStream.is_open(), true);
1120 decodeNFrames(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
1121 kPortIndexOutput, eleStream, &Info, 0, i + 1, portMode[1]);
1123 waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer,
1124 kPortIndexInput, kPortIndexOutput, portMode[1]);
1125 testEOS(omxNode, observer, &iBuffer, &oBuffer, false, eosFlag, portMode,
1126 portReconfiguration, kPortIndexInput, kPortIndexOutput, nullptr);
1127 flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
1129 EXPECT_GE(framesReceived, 1U);
1133 eleStream.open(mURL, std::ifstream::binary);
1134 ASSERT_EQ(eleStream.is_open(), true);
1135 decodeNFrames(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
1136 kPortIndexOutput, eleStream, &Info, 0, i + 1, portMode[1],
1139 waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer,
1140 kPortIndexInput, kPortIndexOutput, portMode[1]);
1141 testEOS(omxNode, observer, &iBuffer, &oBuffer, true, eosFlag, portMode,
1142 portReconfiguration, kPortIndexInput, kPortIndexOutput, nullptr);
1143 flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
1145 EXPECT_GE(framesReceived, 1U);
1149 // set state to idle
1150 changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer);
1151 // set state to executing
1152 changeStateIdletoLoaded(omxNode, observer, &iBuffer, &oBuffer,
1153 kPortIndexInput, kPortIndexOutput);
1156 // end of sequence test
1157 TEST_F(VideoDecHidlTest, SimpleEOSTest) {
1158 description("Test End of stream");
1159 if (disableTest) return;
1160 android::hardware::media::omx::V1_0::Status status;
1161 uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
1162 status = setRole(omxNode, gEnv->getRole().c_str());
1163 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1164 OMX_PORT_PARAM_TYPE params;
1165 status = getParam(omxNode, OMX_IndexParamVideoInit, ¶ms);
1166 if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
1167 ASSERT_EQ(params.nPorts, 2U);
1168 kPortIndexInput = params.nStartPortNumber;
1169 kPortIndexOutput = kPortIndexInput + 1;
1171 char mURL[512], info[512];
1172 strcpy(mURL, gEnv->getRes().c_str());
1173 strcpy(info, gEnv->getRes().c_str());
1174 GetURLForComponent(compName, mURL, info);
1176 std::ifstream eleStream, eleInfo;
1179 ASSERT_EQ(eleInfo.is_open(), true);
1180 android::Vector<FrameData> Info;
1181 int bytesCount = 0, maxBytesCount = 0;
1183 uint32_t timestamp = 0;
1185 if (!(eleInfo >> bytesCount)) break;
1187 eleInfo >> timestamp;
1188 Info.push_back({bytesCount, flags, timestamp});
1189 if (maxBytesCount < bytesCount) maxBytesCount = bytesCount;
1193 // As the frame sizes are known ahead, use it to configure i/p buffer size
1194 maxBytesCount = ALIGN_POWER_OF_TWO(maxBytesCount, 10);
1195 status = setPortBufferSize(omxNode, kPortIndexInput, maxBytesCount);
1196 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1199 status = omxNode->setPortMode(kPortIndexInput, portMode[0]);
1200 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1201 status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
1202 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1205 uint32_t nFrameWidth, nFrameHeight, xFramerate;
1206 getInputChannelInfo(omxNode, kPortIndexInput, &nFrameWidth, &nFrameHeight,
1208 // get default color format
1209 OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatUnused;
1210 getDefaultColorFormat(omxNode, kPortIndexOutput, portMode[1],
1212 ASSERT_NE(eColorFormat, OMX_COLOR_FormatUnused);
1214 setVideoPortFormat(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
1215 eColorFormat, xFramerate);
1216 EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1217 setDefaultPortParam(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
1218 eColorFormat, nFrameWidth, nFrameHeight, 0, xFramerate);
1220 android::Vector<BufferInfo> iBuffer, oBuffer;
1222 // set state to idle
1223 changeStateLoadedtoIdle(omxNode, observer, &iBuffer, &oBuffer,
1224 kPortIndexInput, kPortIndexOutput, portMode);
1225 // set state to executing
1226 changeStateIdletoExecute(omxNode, observer);
1228 // request EOS at the end
1229 eleStream.open(mURL, std::ifstream::binary);
1230 ASSERT_EQ(eleStream.is_open(), true);
1231 decodeNFrames(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
1232 kPortIndexOutput, eleStream, &Info, 0, (int)Info.size(),
1233 portMode[1], false);
1235 waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer,
1236 kPortIndexInput, kPortIndexOutput, portMode[1]);
1237 testEOS(omxNode, observer, &iBuffer, &oBuffer, true, eosFlag, portMode,
1238 portReconfiguration, kPortIndexInput, kPortIndexOutput, nullptr);
1239 flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
1244 // set state to idle
1245 changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer);
1246 // set state to executing
1247 changeStateIdletoLoaded(omxNode, observer, &iBuffer, &oBuffer,
1248 kPortIndexInput, kPortIndexOutput);
1251 // test input/output port flush
1252 TEST_F(VideoDecHidlTest, FlushTest) {
1253 description("Test Flush");
1254 if (disableTest) return;
1255 android::hardware::media::omx::V1_0::Status status;
1256 uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
1257 status = setRole(omxNode, gEnv->getRole().c_str());
1258 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1259 OMX_PORT_PARAM_TYPE params;
1260 status = getParam(omxNode, OMX_IndexParamVideoInit, ¶ms);
1261 if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
1262 ASSERT_EQ(params.nPorts, 2U);
1263 kPortIndexInput = params.nStartPortNumber;
1264 kPortIndexOutput = kPortIndexInput + 1;
1266 char mURL[512], info[512];
1267 strcpy(mURL, gEnv->getRes().c_str());
1268 strcpy(info, gEnv->getRes().c_str());
1269 GetURLForComponent(compName, mURL, info);
1271 std::ifstream eleStream, eleInfo;
1274 ASSERT_EQ(eleInfo.is_open(), true);
1275 android::Vector<FrameData> Info;
1276 int bytesCount = 0, maxBytesCount = 0;
1278 uint32_t timestamp = 0;
1280 if (!(eleInfo >> bytesCount)) break;
1282 eleInfo >> timestamp;
1283 Info.push_back({bytesCount, flags, timestamp});
1284 if (maxBytesCount < bytesCount) maxBytesCount = bytesCount;
1288 // As the frame sizes are known ahead, use it to configure i/p buffer size
1289 maxBytesCount = ALIGN_POWER_OF_TWO(maxBytesCount, 10);
1290 status = setPortBufferSize(omxNode, kPortIndexInput, maxBytesCount);
1291 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1294 status = omxNode->setPortMode(kPortIndexInput, portMode[0]);
1295 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1296 status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
1297 ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1300 uint32_t nFrameWidth, nFrameHeight, xFramerate;
1301 getInputChannelInfo(omxNode, kPortIndexInput, &nFrameWidth, &nFrameHeight,
1303 // get default color format
1304 OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatUnused;
1305 getDefaultColorFormat(omxNode, kPortIndexOutput, portMode[1],
1307 ASSERT_NE(eColorFormat, OMX_COLOR_FormatUnused);
1309 setVideoPortFormat(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
1310 eColorFormat, xFramerate);
1311 EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
1312 setDefaultPortParam(omxNode, kPortIndexOutput, OMX_VIDEO_CodingUnused,
1313 eColorFormat, nFrameWidth, nFrameHeight, 0, xFramerate);
1315 android::Vector<BufferInfo> iBuffer, oBuffer;
1317 // set state to idle
1318 changeStateLoadedtoIdle(omxNode, observer, &iBuffer, &oBuffer,
1319 kPortIndexInput, kPortIndexOutput, portMode);
1320 // set state to executing
1321 changeStateIdletoExecute(omxNode, observer);
1323 // Decode 128 frames and flush. here 128 is chosen to ensure there is a key
1324 // frame after this so that the below section can be convered for all
1327 eleStream.open(mURL, std::ifstream::binary);
1328 ASSERT_EQ(eleStream.is_open(), true);
1329 decodeNFrames(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
1330 kPortIndexOutput, eleStream, &Info, 0, nFrames, portMode[1],
1332 // Note: Assumes 200 ms is enough to end any decode call that started
1333 flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
1334 kPortIndexOutput, 200000);
1337 // Seek to next key frame and start decoding till the end
1338 int index = nFrames;
1339 bool keyFrame = false;
1340 while (index < (int)Info.size()) {
1341 if ((Info[index].flags & OMX_BUFFERFLAG_SYNCFRAME) ==
1342 OMX_BUFFERFLAG_SYNCFRAME) {
1343 timestampUs = Info[index - 1].timestamp;
1347 eleStream.ignore(Info[index].bytesCount);
1351 decodeNFrames(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
1352 kPortIndexOutput, eleStream, &Info, index,
1353 Info.size() - index, portMode[1], false);
1355 // Note: Assumes 200 ms is enough to end any decode call that started
1357 flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
1358 kPortIndexOutput, 200000);
1361 // set state to idle
1362 changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer);
1363 // set state to executing
1364 changeStateIdletoLoaded(omxNode, observer, &iBuffer, &oBuffer,
1365 kPortIndexInput, kPortIndexOutput);
1368 int main(int argc, char** argv) {
1369 gEnv = new ComponentTestEnvironment();
1370 ::testing::AddGlobalTestEnvironment(gEnv);
1371 ::testing::InitGoogleTest(&argc, argv);
1372 int status = gEnv->initFromOptions(argc, argv);
1374 status = RUN_ALL_TESTS();
1375 ALOGI("Test result = %d", status);