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 #define LOG_TAG "DetailEnhDemo"
17
18 #include <cstdlib>
19 #include <cstdio>
20 #include <ctime>
21 #include <dlfcn.h>
22 #include <fstream>
23 #include <memory>
24 #include <unistd.h>
25 #include <string>
26
27 #include "algorithm_common.h"
28 #include "algorithm_errors.h"
29 #include "graphic_common_c.h"
30 #include "detailEnh_sample.h"
31 #include "detailEnh_sample_define.h"
32 #include "detail_enhancer_image.h"
33
34 using namespace OHOS;
35 using namespace Media;
36 using namespace VideoProcessingEngine;
37
38 namespace {
39 const float SIZE_COEF_YUV420 = 1.5;
40 const float SIZE_COEF_RGBA8888 = 4;
41 const float SIZE_COEF_YUV444 = 3;
42
DetailEnhancerImageCreate()43 std::shared_ptr<DetailEnhancerImage> DetailEnhancerImageCreate()
44 {
45 auto detailEnh = DetailEnhancerImage::Create();
46 if (detailEnh == nullptr) {
47 TEST_LOG("Create Detail enhancer failed");
48 return nullptr;
49 }
50 return detailEnh;
51 }
52
GetFormatName(int32_t format)53 std::string GetFormatName(int32_t format)
54 {
55 std::string formatName = "UNKNOWN";
56 switch (format) {
57 case OHOS::GRAPHIC_PIXEL_FMT_YCBCR_420_SP:
58 formatName = "NV12";
59 break;
60 case OHOS::GRAPHIC_PIXEL_FMT_YCBCR_420_P:
61 formatName = "I420";
62 break;
63 case OHOS::GRAPHIC_PIXEL_FMT_RGBA_8888:
64 formatName = "RGBA";
65 break;
66 case OHOS::GRAPHIC_PIXEL_FMT_BGRA_8888:
67 formatName = "BGRA";
68 break;
69 case OHOS::GRAPHIC_PIXEL_FMT_RGBA_1010102:
70 formatName = "RGBA10";
71 break;
72 default:
73 TEST_LOG("Unknow format!");
74 }
75 return formatName;
76 }
77
GetFileSize(int32_t width,int32_t height,int32_t format)78 int32_t GetFileSize(int32_t width, int32_t height, int32_t format)
79 {
80 int32_t size = width * height;
81 switch (format) {
82 case OHOS::GRAPHIC_PIXEL_FMT_YCBCR_420_SP:
83 case OHOS::GRAPHIC_PIXEL_FMT_YCBCR_420_P:
84 size = size * SIZE_COEF_YUV420;
85 break;
86 case OHOS::GRAPHIC_PIXEL_FMT_RGBA_8888:
87 case OHOS::GRAPHIC_PIXEL_FMT_BGRA_8888:
88 case OHOS::GRAPHIC_PIXEL_FMT_RGBA_1010102:
89 size *= SIZE_COEF_RGBA8888;
90 break;
91 default:
92 TEST_LOG("Unknow format:%d", format);
93 size *= SIZE_COEF_YUV444;
94 break;
95 }
96 return size;
97 }
98
GetImageType(int32_t format)99 int32_t GetImageType(int32_t format)
100 {
101 int32_t imageType = 0;
102 switch (format) {
103 case RGBA:
104 imageType = OHOS::GRAPHIC_PIXEL_FMT_RGBA_8888;
105 break;
106 case BGRA:
107 imageType = OHOS::GRAPHIC_PIXEL_FMT_BGRA_8888;
108 break;
109 case NV12:
110 imageType = OHOS::GRAPHIC_PIXEL_FMT_YCBCR_420_SP;
111 break;
112 case I420:
113 imageType = OHOS::GRAPHIC_PIXEL_FMT_YCBCR_420_P;
114 break;
115 case RGBA1010102:
116 imageType = OHOS::GRAPHIC_PIXEL_FMT_RGBA_1010102;
117 break;
118 default:
119 imageType = OHOS::GRAPHIC_PIXEL_FMT_RGBA_8888;
120 }
121 return imageType;
122 }
123
Process(std::shared_ptr<DetailEnhancerImage> detailEnh,std::string_view inputFile,std::vector<int32_t> inputParam,std::vector<int32_t> outputParam,bool needDump)124 void Process(std::shared_ptr<DetailEnhancerImage> detailEnh, std::string_view inputFile,
125 std::vector<int32_t> inputParam, std::vector<int32_t> outputParam, bool needDump)
126 {
127 if (inputFile == "UNKNOWN") {
128 TEST_LOG("Invalid input");
129 return;
130 }
131 int32_t inputFormat = inputParam[0];
132 int32_t inputWidth = inputParam[1];
133 int32_t inputHeight = inputParam[2];
134 int32_t outputFormat = outputParam[0];
135 int32_t outputWidth = outputParam[1];
136 int32_t outputHeight = outputParam[2];
137 auto input = CreateSurfaceBuffer(inputFormat, inputWidth, inputHeight);
138 TEST_LOG("inputFile:%s", inputFile.data());
139 std::unique_ptr<std::ifstream> yuvFile =
140 std::make_unique<std::ifstream>(inputFile.data(), std::ios::binary | std::ios::in);
141 ReadYuvFile(input, yuvFile, GetFileSize(inputWidth, inputHeight, inputFormat));
142 auto output = CreateSurfaceBuffer(outputFormat, outputWidth, outputHeight);
143 yuvFile->seekg(0);
144 yuvFile->close();
145
146 int32_t ret = detailEnh->Process(input, output);
147 if (ret != VPE_ALGO_ERR_OK) {
148 TEST_LOG("Processed failed");
149 return;
150 }
151 if (needDump) {
152 std::unique_ptr<std::ofstream> outputImage = std::make_unique<std::ofstream>(
153 "/data/test/media/output/" + GetFormatName(inputFormat) + "To" + GetFormatName(outputFormat) + "_" +
154 std::to_string(outputWidth) + "x" + std::to_string(outputHeight) + "_" +
155 std::to_string(output->GetStride()) + ".yuv",
156 std::ios::binary | std::ios::out | std::ios::trunc);
157 outputImage->write(static_cast<const char *>(output->GetVirAddr()), output->GetSize());
158 outputImage->close();
159 }
160 }
161
RunWithSo(sptr<SurfaceBuffer> & input,sptr<SurfaceBuffer> & output,DetailEnhancerLevel level)162 void RunWithSo(sptr<SurfaceBuffer> & input, sptr<SurfaceBuffer> & output, DetailEnhancerLevel level)
163 {
164 void* lib = dlopen("/system/lib64/libvideoprocessingengine.z.so", RTLD_LAZY);
165 if (lib == nullptr) {
166 printf("cannot load vpe lib\n");
167 return;
168 }
169
170 typedef int32_t (*DetailEnhancerCreate)(int32_t*);
171 typedef int32_t (*DetailEnhancerProcessImage)(int32_t,
172 OHNativeWindowBuffer*, OHNativeWindowBuffer*, int32_t);
173 typedef int32_t (*DetailEnhancerDestroy)(int32_t*);
174
175 auto detailEnhCreate = reinterpret_cast<DetailEnhancerCreate>(dlsym(lib, "DetailEnhancerCreate"));
176 auto detailEnhProcessImage =
177 reinterpret_cast<DetailEnhancerProcessImage>(dlsym(lib, "DetailEnhancerProcessImage"));
178 auto detailEnhDestroy = reinterpret_cast<DetailEnhancerDestroy>(dlsym(lib, "DetailEnhancerDestroy"));
179
180 int32_t instanceSrId = -1;
181 int32_t res = detailEnhCreate(&instanceSrId);
182 if (res != 0 || instanceSrId == -1) {
183 TEST_LOG("create failed, res:%d, insta:%d\n", res, instanceSrId);
184 dlclose(lib);
185 return;
186 }
187 if (input == nullptr || output == nullptr) {
188 TEST_LOG("input invalid\n");
189 return;
190 }
191 OHNativeWindowBuffer* srIn = OH_NativeWindow_CreateNativeWindowBufferFromSurfaceBuffer(&input);
192 OHNativeWindowBuffer* srOut = OH_NativeWindow_CreateNativeWindowBufferFromSurfaceBuffer(&output);
193 res = detailEnhProcessImage(instanceSrId, srIn, srOut, static_cast<int>(level));
194 if (res != 0) {
195 TEST_LOG("process failed\n");
196 return;
197 }
198 res = detailEnhDestroy(&instanceSrId);
199 if (res != 0) {
200 TEST_LOG("destroy failed\n");
201 return;
202 }
203 std::unique_ptr<std::ofstream> outputImage = std::make_unique<std::ofstream>(
204 "/data/test/media/output/" + GetFormatName(input->GetFormat()) + "To" + GetFormatName(output->GetFormat()) +
205 "_" + std::to_string(output->GetWidth()) + "x" + std::to_string(output->GetHeight())+ "_" +
206 std::to_string(output->GetStride()) + "_level"+ std::to_string(level) + "externC.yuv",
207 std::ios::binary | std::ios::out | std::ios::trunc);
208 outputImage->write(static_cast<const char *>(output->GetVirAddr()), output->GetSize());
209 outputImage->close();
210 }
211 }
212
main(int argc,char * argv[])213 int32_t main([[maybe_unused]]int argc, char* argv[])
214 {
215 TEST_LOG("USAGE exe inputWidth inputHeight outputWidth outputHeight pixelFormat\
216 checkHightLevel checkSuperLevel checkDlopen needDump processTime enterTime\n");
217 TEST_LOG("format: 5 <---> RGBA8888, 6 <---> NV12, 7 <---> YUV420, 8 <---> BGRA 9 <---> RGBA1010102\n");
218 int32_t inputWidth = atoi(argv[1]);
219 int32_t inputHeight = atoi(argv[2]);
220 int32_t outputWidth = atoi(argv[3]);
221 int32_t outputHeight = atoi(argv[4]);
222 SUPPORT_FORMAT pixelFormat = static_cast<SUPPORT_FORMAT>(atoi(argv[5]));
223 bool checkDlopen = atoi(argv[6]);
224 bool needDump = atoi(argv[7]);
225 int32_t levelToProcess = atoi(argv[8]);
226 std::string inputFilePath = argv[9];
227 int32_t processTime = atoi(argv[10]);
228 int32_t enterTime = atoi(argv[11]);
229
230 if (!checkDlopen) {
231 for (int i = 0; i < enterTime; i++) {
232 auto detailEnh = DetailEnhancerImageCreate();
233 if (detailEnh == nullptr) {
234 printf("detailEnh == nullptr");
235 return -1;
236 }
237 DetailEnhancerParameters param {
238 .uri = "",
239 .level = static_cast<DetailEnhancerLevel>(levelToProcess),
240 .forceEve = 1,
241 };
242 if (detailEnh->SetParameter(param)!= VPE_ALGO_ERR_OK) {
243 printf("Init failed!");
244 return -1;
245 }
246 for (int j = 0; j < processTime; j++) {
247 Process(detailEnh, inputFilePath, { GetImageType(pixelFormat), inputWidth, inputHeight },
248 { GetImageType(pixelFormat), outputWidth, outputHeight }, needDump);
249 }
250 detailEnh = nullptr;
251 }
252 } else {
253 auto input = CreateSurfaceBuffer(GetImageType(pixelFormat), inputWidth, inputHeight);
254 std::string_view inputFile = inputFilePath;
255 std::unique_ptr<std::ifstream> yuvFile =
256 std::make_unique<std::ifstream>(inputFile.data(), std::ios::binary | std::ios::in);
257 ReadYuvFile(input, yuvFile, GetFileSize(inputWidth, inputHeight, GetImageType(pixelFormat)));
258 auto output = CreateSurfaceBuffer(GetImageType(pixelFormat), outputWidth, outputHeight);
259 RunWithSo(input, output, static_cast<DetailEnhancerLevel>(levelToProcess));
260 yuvFile->close();
261 }
262 return 0;
263 }
264