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 "util_define.h"
17 #include <fstream>
18 #include <string>
19 #include <string_view>
20 #include <sstream>
21 #include <iostream>
22 #include <vector>
23 #include <memory>
24 #include <cstdlib>
25 #include "securec.h"
26 #include "vpe_log.h"
27
28 namespace OHOS {
29 namespace Media {
30 namespace VideoProcessingEngine {
31 using namespace std;
32 constexpr int32_t STRIDE = 2;
33
ReadFileYuv42016(std::string yuvFilePath,sptr<SurfaceBuffer> & buffer,int width,int height)34 void ReadFileYuv42016(std::string yuvFilePath, sptr<SurfaceBuffer> &buffer, int width, int height)
35 {
36 unique_ptr<ifstream> yuvFile = make_unique<ifstream>();
37 CHECK_AND_RETURN_LOG(yuvFile != nullptr, "Fatal: No memory");
38 yuvFile->open(yuvFilePath, ios::in | ios::binary);
39 yuvFile->seekg(0, ios::beg);
40 long ySize = static_cast<long>(width) * static_cast<long>(height);
41 long uvSize = ySize / 4;
42 uint16_t *yBuffer = new uint16_t[ySize + STRIDE * uvSize];
43 uint16_t *uBuffer = new uint16_t[uvSize];
44 uint16_t *vBuffer = new uint16_t[uvSize];
45 yuvFile->read(reinterpret_cast<char *>(yBuffer), ySize * sizeof(uint16_t));
46 yuvFile->read(reinterpret_cast<char *>(uBuffer), uvSize * sizeof(uint16_t));
47 yuvFile->read(reinterpret_cast<char *>(vBuffer), uvSize * sizeof(uint16_t));
48
49 errno_t ret = memcpy_s(reinterpret_cast<char *>(buffer->GetVirAddr()), (ySize + uvSize * STRIDE) * sizeof(uint16_t),
50 yBuffer, (ySize + uvSize * STRIDE) * sizeof(uint16_t));
51 if (ret != EOK) {
52 printf("memcpy_s failed, err = %d\n", ret);
53 }
54 delete[] yBuffer;
55 delete[] uBuffer;
56 delete[] vBuffer;
57 yuvFile->close();
58 }
59
ReadFileYuv42010ToNv1216(std::string yuvFilePath,sptr<SurfaceBuffer> & buffer,int width,int height)60 void ReadFileYuv42010ToNv1216(std::string yuvFilePath, sptr<SurfaceBuffer> &buffer, int width, int height)
61 {
62 unique_ptr<ifstream> yuvFile = make_unique<ifstream>();
63 CHECK_AND_RETURN_LOG(yuvFile != nullptr, "Fatal: No memory");
64 yuvFile->open(yuvFilePath, ios::in | ios::binary);
65 yuvFile->seekg(0, ios::beg);
66 long ySize = static_cast<long>(width) * static_cast<long>(height);
67 long uvSize = ySize / 4;
68 uint16_t *yBuffer = new uint16_t[ySize + STRIDE * uvSize];
69 uint16_t *uBuffer = new uint16_t[uvSize];
70 uint16_t *vBuffer = new uint16_t[uvSize];
71 yuvFile->read(reinterpret_cast<char *>(yBuffer), ySize * sizeof(uint16_t));
72 yuvFile->read(reinterpret_cast<char *>(uBuffer), uvSize * sizeof(uint16_t));
73 yuvFile->read(reinterpret_cast<char *>(vBuffer), uvSize * sizeof(uint16_t));
74
75 int num10To16 = 6;
76 int numTwo = 2;
77 uint16_t *uvBufferPtr = &yBuffer[ySize];
78 for (int i = 0; i < ySize; i++) {
79 yBuffer[i] = yBuffer[i] << num10To16;
80 }
81 for (int j = 0; j < uvSize; j++) {
82 uvBufferPtr[numTwo * j] = uBuffer[j] << num10To16;
83 uvBufferPtr[numTwo * j + 1] = vBuffer[j] << num10To16;
84 }
85
86 errno_t ret = memcpy_s(reinterpret_cast<char *>(buffer->GetVirAddr()), (ySize + uvSize * STRIDE) * sizeof(uint16_t),
87 yBuffer, (ySize + uvSize * STRIDE) * sizeof(uint16_t));
88 if (ret != EOK) {
89 printf("memcpy_s failed, err = %d\n", ret);
90 }
91 delete[] yBuffer;
92 delete[] uBuffer;
93 delete[] vBuffer;
94 yuvFile->close();
95 }
96
ReadInputFile(std::string yuvFilePath,sptr<SurfaceBuffer> & buffer,int frameSize)97 void ReadInputFile(std::string yuvFilePath, sptr<SurfaceBuffer> &buffer, int frameSize)
98 {
99 unique_ptr<ifstream> yuvFile = make_unique<ifstream>();
100 CHECK_AND_RETURN_LOG(yuvFile != nullptr, "Fatal: No memory");
101 yuvFile->open(yuvFilePath, ios::in | ios::binary);
102 yuvFile->seekg(0, ios::beg);
103 yuvFile->read(reinterpret_cast<char *>(buffer->GetVirAddr()), frameSize);
104 yuvFile->close();
105 }
106
SaveMetaDataToBin(int frameId,const char * fileName,unsigned char * metadataPayload,int metadataPayloadSize)107 static void SaveMetaDataToBin(int frameId, const char *fileName, unsigned char *metadataPayload,
108 int metadataPayloadSize)
109 {
110 FILE *fileOut = nullptr;
111 if (frameId == 0) {
112 fileOut = fopen(fileName, "wb");
113 } else {
114 fileOut = fopen(fileName, "ab+");
115 }
116 if (fileOut == nullptr) {
117 printf("open file[%s] Error:%s!", fileName, "error");
118 return;
119 }
120
121 uint32_t mdLen = static_cast<uint32_t>(metadataPayloadSize);
122 int len = fwrite(&mdLen, sizeof(uint32_t), 1, fileOut);
123 if (len != 1) {
124 printf("write file Error:%s with mdLen!", fileName);
125 }
126 len = fwrite(metadataPayload, sizeof(uint8_t), metadataPayloadSize, fileOut);
127 if (len != metadataPayloadSize) {
128 printf("write file Error:%s!", fileName);
129 }
130 int fcloseResult = fclose(fileOut);
131 if (fcloseResult != 0) {
132 printf("fclose Error:%s!", fileName);
133 }
134 }
135
SaveMetadataFromSurBuffer(const sptr<SurfaceBuffer> & input,int frame,const string & metadataBin)136 void SaveMetadataFromSurBuffer(const sptr<SurfaceBuffer> &input, int frame, const string &metadataBin)
137 {
138 std::vector<uint8_t> inMetaData;
139 input->GetMetadata(ATTRKEY_HDR_DYNAMIC_METADATA, inMetaData);
140 unsigned char *metaData = inMetaData.data();
141 uint32_t meteDataLength = inMetaData.size();
142 printf("frame=%d, imeteDataLength_demo = %u\n", frame, meteDataLength);
143 SaveMetaDataToBin(frame, metadataBin.c_str(), metaData, meteDataLength);
144 }
145
WriteOutFile(int frame,const string & outYuvFileName,const sptr<SurfaceBuffer> & output,int frameSize)146 void WriteOutFile(int frame, const string &outYuvFileName, const sptr<SurfaceBuffer> &output, int frameSize)
147 {
148 std::unique_ptr<std::ofstream> outputYuv;
149 if (frame == 0) {
150 outputYuv =
151 std::make_unique<std::ofstream>(outYuvFileName.c_str(), std::ios::binary | std::ios::out | std::ios::trunc);
152 } else {
153 outputYuv = std::make_unique<std::ofstream>(outYuvFileName.c_str(), std::ios::binary | std::ios::app);
154 }
155 outputYuv->write(static_cast<const char *>(output->GetVirAddr()), frameSize);
156 }
157
158
GetPixFmtString(GraphicPixelFormat pixfmt)159 std::string GetPixFmtString(GraphicPixelFormat pixfmt)
160 {
161 switch (pixfmt) {
162 case GRAPHIC_PIXEL_FMT_YCBCR_P010:
163 return "nv12_10";
164 case GRAPHIC_PIXEL_FMT_YCRCB_P010:
165 return "nv21_10";
166 case GRAPHIC_PIXEL_FMT_RGBA_1010102:
167 return "rgba1010102";
168 default:
169 return "none";
170 }
171 }
172
GetColspcStringPrimaries(CM_ColorSpaceInfo colorSpaceInfo)173 std::string GetColspcStringPrimaries(CM_ColorSpaceInfo colorSpaceInfo)
174 {
175 std::string str = "";
176 switch (colorSpaceInfo.primaries) {
177 case COLORPRIMARIES_BT709:
178 str = "_709";
179 break;
180 case COLORPRIMARIES_BT601_P:
181 str = "_601p";
182 break;
183 case COLORPRIMARIES_BT601_N:
184 str = "_601n";
185 break;
186 case COLORPRIMARIES_BT2020:
187 str = "_2020";
188 break;
189 default:
190 str = "_none";
191 break;
192 }
193 return str;
194 }
GetColspcStringTrans(CM_ColorSpaceInfo colorSpaceInfo)195 std::string GetColspcStringTrans(CM_ColorSpaceInfo colorSpaceInfo)
196 {
197 std::string str = "";
198 switch (colorSpaceInfo.transfunc) {
199 case TRANSFUNC_BT709:
200 str = "_709";
201 break;
202 case TRANSFUNC_SRGB:
203 str = "_srgb";
204 break;
205 case TRANSFUNC_LINEAR:
206 str = "_linear";
207 break;
208 case TRANSFUNC_PQ:
209 str = "_pq";
210 break;
211 case TRANSFUNC_HLG:
212 str = "_hlg";
213 break;
214 case TRANSFUNC_ADOBERGB:
215 str = "_adobergb";
216 break;
217 case TRANSFUNC_GAMMA2_2:
218 str = "_gamma22";
219 break;
220 case TRANSFUNC_GAMMA2_4:
221 str = "_gamma24";
222 break;
223 default:
224 str = "_none";
225 break;
226 }
227 return str;
228 }
GetColspcStringRange(CM_ColorSpaceInfo colorSpaceInfo)229 std::string GetColspcStringRange(CM_ColorSpaceInfo colorSpaceInfo)
230 {
231 std::string str = "";
232 switch (colorSpaceInfo.range) {
233 case RANGE_FULL:
234 str = "_full";
235 break;
236 case RANGE_LIMITED:
237 str = "_limited";
238 break;
239 default:
240 str = "_none";
241 break;
242 }
243 return str;
244 }
GetColspcString(CM_ColorSpaceInfo colorSpaceInfo)245 std::string GetColspcString(CM_ColorSpaceInfo colorSpaceInfo)
246 {
247 std::string str = "";
248 std::string strPrima = GetColspcStringPrimaries(colorSpaceInfo);
249 str = strPrima;
250 std::string strTrans = GetColspcStringTrans(colorSpaceInfo);
251 str += strTrans;
252 std::string strRange = GetColspcStringRange(colorSpaceInfo);
253 str += strRange;
254 return str;
255 }
256
GetMetadataString(CM_HDR_Metadata_Type metaType)257 std::string GetMetadataString(CM_HDR_Metadata_Type metaType)
258 {
259 switch (metaType) {
260 case CM_VIDEO_HLG:
261 return "_vHlg";
262 case CM_VIDEO_HDR10:
263 return "_vHdr10";
264 case CM_VIDEO_HDR_VIVID:
265 return "_vHdrVivid";
266 case CM_IMAGE_HDR_VIVID_DUAL:
267 return "_iHdrVividD";
268 case CM_IMAGE_HDR_VIVID_SINGLE:
269 return "_iHdrVividS";
270 case CM_IMAGE_HDR_ISO_DUAL:
271 return "_iHdrIsoD";
272 case CM_IMAGE_HDR_ISO_SINGLE:
273 return "_iHdrIsoS";
274 default:
275 return "none";
276 }
277 }
278
GetOutFileName(const string & baseName,const ParameterBase & param)279 std::string GetOutFileName(const string &baseName, const ParameterBase ¶m)
280 {
281 string outputName = "";
282 outputName = baseName + "_iFmt" + GetPixFmtString(param.inPixFmt) + "_iCol" + GetColspcString(param.inColspcInfo) +
283 "_iMetaT" + GetMetadataString(param.inMetaType) + "_oFmt" + GetPixFmtString(param.outPixFmt) + "_oCol" +
284 GetColspcString(param.outColspcInfo) + "_oMeta" + GetMetadataString(param.outMetaType) + ".yuv";
285 return outputName;
286 }
287
SetMeatadata(sptr<SurfaceBuffer> & buffer,uint32_t value)288 void SetMeatadata(sptr<SurfaceBuffer> &buffer, uint32_t value)
289 {
290 std::vector<uint8_t> metadata;
291 metadata.resize(sizeof(value));
292 errno_t ret = memcpy_s(metadata.data(), metadata.size(), &value, sizeof(value));
293 if (ret != EOK) {
294 printf("memcpy_s failed, err = %d\n", ret);
295 return;
296 }
297 uint32_t err = buffer->SetMetadata(ATTRKEY_HDR_METADATA_TYPE, metadata);
298 printf("Buffer set metadata type, ret: %u\n", err);
299 }
SetMeatadata(sptr<SurfaceBuffer> & buffer,const CM_ColorSpaceInfo & colorspaceInfo)300 void SetMeatadata(sptr<SurfaceBuffer> &buffer, const CM_ColorSpaceInfo &colorspaceInfo)
301 {
302 std::vector<uint8_t> metadata;
303 metadata.resize(sizeof(CM_ColorSpaceInfo));
304 errno_t ret = memcpy_s(metadata.data(), metadata.size(), &colorspaceInfo, sizeof(CM_ColorSpaceInfo));
305 if (ret != EOK) {
306 printf("memcpy_s failed, err = %d\n", ret);
307 return;
308 }
309 uint32_t err = buffer->SetMetadata(ATTRKEY_COLORSPACE_INFO, metadata);
310 printf("Buffer set colorspace info, ret: %u\n", err);
311 }
SetMeatadata(sptr<SurfaceBuffer> & buffer,int key,const float & data)312 void SetMeatadata(sptr<SurfaceBuffer> &buffer, int key, const float &data)
313 {
314 std::vector<uint8_t> metadata;
315 metadata.resize(sizeof(float));
316 errno_t ret = memcpy_s(metadata.data(), metadata.size(), &data, sizeof(float));
317 if (ret != EOK) {
318 printf("memcpy_s failed, err = %d\n", ret);
319 return;
320 }
321 uint32_t err = buffer->SetMetadata(key, metadata);
322 printf("Buffer set colorspace info, ret: %u\n", err);
323 }
SetMeatadata(sptr<SurfaceBuffer> & buffer,int key,const int & data)324 void SetMeatadata(sptr<SurfaceBuffer> &buffer, int key, const int &data)
325 {
326 std::vector<uint8_t> metadata;
327 metadata.resize(sizeof(int));
328 errno_t ret = memcpy_s(metadata.data(), metadata.size(), &data, sizeof(int));
329 if (ret != EOK) {
330 printf("memcpy_s failed, err = %d\n", ret);
331 return;
332 }
333 uint32_t err = buffer->SetMetadata(key, metadata);
334 printf("Buffer set colorspace info, ret: %u\n", err);
335 }
SetMeatadata(sptr<SurfaceBuffer> & buffer,std::unique_ptr<std::ifstream> & metadataFile)336 void SetMeatadata(sptr<SurfaceBuffer> &buffer, std::unique_ptr<std::ifstream> &metadataFile)
337 {
338 if (!metadataFile->is_open()) {
339 printf("Metadata file is not open\n");
340 return;
341 }
342
343 std::vector<uint8_t> metadata;
344 uint32_t metadataSize = 0;
345
346 metadataFile->read(reinterpret_cast<char *>(&metadataSize), sizeof(uint32_t));
347 if (metadataSize == 0) {
348 printf("Read metadata failed, get a size: %u\n", metadataSize);
349 return;
350 }
351 metadata.resize(metadataSize);
352 metadataFile->read(reinterpret_cast<char *>(metadata.data()), metadataSize);
353
354 // Dump metadata
355 for (size_t idx = 0; idx < metadata.size(); idx++) {
356 uint32_t data =
357 (metadata[idx] << 24) + (metadata[idx + 1] << 16) + (metadata[idx + 2] << 8) + (metadata[idx + 3]);
358 (void)data;
359 }
360
361 int32_t err = buffer->SetMetadata(ATTRKEY_HDR_DYNAMIC_METADATA, metadata);
362 printf("Buffer hdr dynamic metadata type, ret: %d\n", err);
363 }
CreateSurfaceBuffer(uint32_t pixelFormat,int32_t width,int32_t height)364 sptr<SurfaceBuffer> CreateSurfaceBuffer(uint32_t pixelFormat, int32_t width, int32_t height)
365 {
366 auto buffer = SurfaceBuffer::Create();
367 if (nullptr == buffer) {
368 printf("Create surface buffer failed\n");
369 return nullptr;
370 }
371 BufferRequestConfig inputCfg;
372 inputCfg.width = width;
373 inputCfg.height = height;
374 inputCfg.strideAlignment = width;
375 inputCfg.usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE
376 | BUFFER_USAGE_HW_RENDER | BUFFER_USAGE_HW_TEXTURE | BUFFER_USAGE_MEM_MMZ_CACHE;
377 inputCfg.format = pixelFormat;
378 inputCfg.timeout = 0;
379 GSError err = buffer->Alloc(inputCfg);
380 if (GSERROR_OK != err) {
381 printf("Alloc surface buffer failed\n");
382 return nullptr;
383 }
384 return buffer;
385 }
386 } // namespace VideoProcessingEngine
387 } // namespace Media
388 } // namespace OHOS
389