1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <gtest/gtest.h>
17 #include <cstdint>
18 #include <string_view>
19 #include <fstream>
20 #include "iostream"
21 #include "securec.h"
22 #include "vpe_trace.h"
23 #include "vpe_log.h"
24 #include "video_refreshrate_prediction.h"
25 #include "v2_0/buffer_handle_meta_key_type.h"
26 #include "v1_2/display_composer_type.h"
27
28 using namespace std;
29 using namespace testing::ext;
30
31 namespace {
32 const std::string MV_FILE = "3840x1608.pmv";
33 const std::string UT_PROCESS_NAME = "video_variable_refreshrate_unit_test";
34 } // namespace
35
36 namespace OHOS {
37 namespace Media {
38 namespace VideoProcessingEngine {
39
40 class VideoVariableRefreshRateUnitTest : public testing::Test {
41 public:
42 static void SetUpTestCase(void);
43 static void TearDownTestCase(void);
44 void SetUp();
45 void TearDown();
46 };
47
SetUpTestCase(void)48 void VideoVariableRefreshRateUnitTest::SetUpTestCase(void)
49 {
50 cout << "[VideoVariableRefreshRateUnitTest SetUpTestCase]: success!" << endl;
51 }
52
TearDownTestCase(void)53 void VideoVariableRefreshRateUnitTest::TearDownTestCase(void)
54 {
55 cout << "[VideoVariableRefreshRateUnitTest TearDownTestCase]: " << endl;
56 }
57
SetUp(void)58 void VideoVariableRefreshRateUnitTest::SetUp(void)
59 {
60 cout << "[VideoVariableRefreshRateUnitTest SetUp]: SetUp!!!" << endl;
61 }
62
TearDown(void)63 void VideoVariableRefreshRateUnitTest::TearDown(void)
64 {
65 cout << "[VideoVariableRefreshRateUnitTest TearDown]: over!!!" << endl;
66 }
67
CalculateMaxMvBufferSize(uint32_t width,uint32_t height)68 uint32_t CalculateMaxMvBufferSize(uint32_t width, uint32_t height)
69 {
70 uint32_t align = 64;
71 uint32_t multCoef = 1;
72 uint32_t diviCoef = 4;
73 uint32_t offset = 256;
74 uint32_t mvWidth = (width + align - 1) & (~(align - 1));
75 uint32_t mvHeight = (height + align - 1) & (~(align - 1));
76 return mvWidth * mvHeight * multCoef / diviCoef + offset;
77 }
78
CreateSurfaceBuffer(uint32_t pixelFormat,int32_t width,int32_t height,uint8_t * mvBuffer,int32_t mvLength)79 sptr<SurfaceBuffer> CreateSurfaceBuffer(uint32_t pixelFormat, int32_t width, int32_t height, uint8_t *mvBuffer,
80 int32_t mvLength)
81 {
82 auto buffer = SurfaceBuffer::Create();
83 if (nullptr == buffer) {
84 printf("Create surface buffer failed\n");
85 return nullptr;
86 }
87 BufferRequestConfig inputCfg;
88 inputCfg.width = width;
89 inputCfg.height = height;
90 inputCfg.strideAlignment = width;
91 inputCfg.usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_HW_RENDER
92 | BUFFER_USAGE_HW_TEXTURE | HDI::Display::Composer::V1_2::HBM_USE_VIDEO_DEC_MV;
93 inputCfg.format = pixelFormat;
94 inputCfg.timeout = 0;
95 GSError err = buffer->Alloc(inputCfg);
96 if (GSERROR_OK != err) {
97 printf("Alloc surface buffer failed\n");
98 return nullptr;
99 }
100 using namespace HDI::Display::Graphic::Common;
101 std::vector<uint8_t> vec;
102 V2_0::BlobDataType data;
103 int32_t ret = buffer->GetMetadata(V2_0::ATTRKEY_VIDEO_DECODER_MV, vec);
104 CHECK_AND_RETURN_RET_LOG(ret == GSERROR_OK && (vec.size() == sizeof(V2_0::BlobDataType)),
105 nullptr, "VRR got decode mv type from handle failed");
106 ret = memcpy_s(&data, sizeof(V2_0::BlobDataType), vec.data(), vec.size());
107 if (ret != 0) {
108 printf("Alloc motion vector failed\n");
109 return nullptr;
110 }
111 ret = memcpy_s((void *)(data.vaddr + data.offset), mvLength, mvBuffer, mvLength);
112 if (ret != 0) {
113 printf("Set motion vector failed\n");
114 return nullptr;
115 }
116 printf("Alloc surface buffer with motion vecotr success\n");
117 return buffer;
118 }
119
120 HWTEST_F(VideoVariableRefreshRateUnitTest, VideoVariableRefreshRate_init_01, TestSize.Level1)
121 {
122 auto vrrPredictor = OHOS::Media::VideoProcessingEngine::VideoRefreshRatePrediction::Create();
123 VPEAlgoErrCode ret = vrrPredictor->CheckVRRSupport(UT_PROCESS_NAME);
124 EXPECT_NE(ret, VPE_ALGO_ERR_OK);
125 }
126
127 HWTEST_F(VideoVariableRefreshRateUnitTest, VideoVariableRefreshRate_init_02, TestSize.Level1)
128 {
129 VideoRefreshRatePredictionHandle *vrrHandle = VideoRefreshRatePredictionCreate();
130 int32_t ret = VideoRefreshRatePredictionCheckSupport(vrrHandle, UT_PROCESS_NAME.c_str());
131 VideoRefreshRatePredictionDestroy(vrrHandle);
132 EXPECT_NE(ret, VPE_ALGO_ERR_OK);
133 }
134
135 HWTEST_F(VideoVariableRefreshRateUnitTest, VideoVariableRefreshRate_implProcess_01, TestSize.Level1)
136 {
137 VPEAlgoErrCode ret = VPE_ALGO_ERR_OK;
138 int32_t width = 3840;
139 int32_t height = 1608;
140 auto vrrPredictor = OHOS::Media::VideoProcessingEngine::VideoRefreshRatePrediction::Create();
141 int mvLength = CalculateMaxMvBufferSize(width, height);
142 uint8_t *mvBuffer = (uint8_t *)malloc(mvLength);
143 sptr<SurfaceBuffer> inputFrame = CreateSurfaceBuffer(GRAPHIC_PIXEL_FMT_RGBA_8888,
144 width, height, mvBuffer, mvLength);
145 ret = vrrPredictor->Process(inputFrame, 60, MOTIONVECTOR_TYPE_HEVC);
146 EXPECT_EQ(ret, VPE_ALGO_ERR_OK);
147 free(mvBuffer);
148 }
149
150 HWTEST_F(VideoVariableRefreshRateUnitTest, VideoVariableRefreshRate_implProcess_02, TestSize.Level1)
151 {
152 VPEAlgoErrCode ret = VPE_ALGO_ERR_OK;
153 int32_t width = 3840;
154 int32_t height = 1608;
155 auto vrrPredictor = OHOS::Media::VideoProcessingEngine::VideoRefreshRatePrediction::Create();
156 int mvLength = CalculateMaxMvBufferSize(width, height);
157 uint8_t *mvBuffer = (uint8_t *)malloc(mvLength);
158 FILE *fp = fopen(MV_FILE.c_str(), "rb");
159 if (fp == nullptr) {
160 printf("open motion vector file [%s] fail!\n", MV_FILE.c_str());
161 return;
162 }
163 int frameIndex = 0;
164 while (1) {
165 int readCnt = fread(mvBuffer, 1, mvLength, fp);
166 if (readCnt < mvLength) {
167 break;
168 }
169 sptr<SurfaceBuffer> inputFrame = CreateSurfaceBuffer(GRAPHIC_PIXEL_FMT_RGBA_8888,
170 width, height, mvBuffer, mvLength);
171 ret = vrrPredictor->Process(inputFrame, 60, MOTIONVECTOR_TYPE_HEVC);
172 EXPECT_EQ(ret, VPE_ALGO_ERR_OK);
173 frameIndex++;
174 }
175 free(mvBuffer);
176 fclose(fp);
177 EXPECT_EQ(ret, VPE_ALGO_ERR_OK);
178 }
179
180 HWTEST_F(VideoVariableRefreshRateUnitTest, VideoVariableRefreshRate_implProcess_03, TestSize.Level1)
181 {
182 int32_t width = 3840;
183 int32_t height = 1608;
184 VideoRefreshRatePredictionHandle *vrrHandle = VideoRefreshRatePredictionCreate();
185 int32_t ret = VideoRefreshRatePredictionCheckSupport(vrrHandle, UT_PROCESS_NAME.c_str());
186 int mvLength = CalculateMaxMvBufferSize(width, height);
187 uint8_t *mvBuffer = (uint8_t *)malloc(mvLength);
188 sptr<SurfaceBuffer> inputFrame = CreateSurfaceBuffer(GRAPHIC_PIXEL_FMT_RGBA_8888,
189 width, height, mvBuffer, mvLength);
190 VideoRefreshRatePredictionProcess(vrrHandle, inputFrame->SurfaceBufferToNativeBuffer(), 60, MOTIONVECTOR_TYPE_HEVC);
191 VideoRefreshRatePredictionDestroy(vrrHandle);
192 free(mvBuffer);
193 EXPECT_NE(ret, VPE_ALGO_ERR_OK);
194 }
195
196 } // namespace VideoProcessingEngine
197 } // namespace Media
198 } // namespace OHOS