1 /*
2 * Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
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 #ifndef __HI_BUFFER_H__
17 #define __HI_BUFFER_H__
18
19 #include "hi_math.h"
20 #include "hi_type.h"
21 #include "hi_common.h"
22 #include "hi_comm_video.h"
23
24 #ifdef __cplusplus
25 #if __cplusplus
26 extern "C" {
27 #endif
28 #endif /* __cplusplus */
29
30 #define HI_MAXINUM_LIMIT 100000
31
COMMON_GetPicBufferConfig(HI_U32 u32Width,HI_U32 u32Height,PIXEL_FORMAT_E enPixelFormat,DATA_BITWIDTH_E enBitWidth,COMPRESS_MODE_E enCmpMode,HI_U32 u32Align,VB_CAL_CONFIG_S * pstCalConfig)32 __inline static HI_VOID COMMON_GetPicBufferConfig(HI_U32 u32Width, HI_U32 u32Height,
33 PIXEL_FORMAT_E enPixelFormat, DATA_BITWIDTH_E enBitWidth,
34 COMPRESS_MODE_E enCmpMode, HI_U32 u32Align, VB_CAL_CONFIG_S *pstCalConfig)
35 {
36 HI_U32 u32BitWidth = 0;
37 HI_U32 u32HeadStride = 0;
38 HI_U32 u32VBSize = 0;
39 HI_U32 u32HeadSize = 0;
40 HI_U32 u32AlignHeight;
41 HI_U32 u32MainStride = 0;
42 HI_U32 u32MainSize = 0;
43 HI_U32 u32ExtStride = 0;
44 HI_U32 u32ExtSize = 0;
45 HI_U32 u32ExtYSize = 0;
46 HI_U32 u32HeadYSize = 0;
47 HI_U32 u32YSize = 0;
48
49 if ((u32Width > HI_MAXINUM_LIMIT) || (u32Height > HI_MAXINUM_LIMIT)) {
50 pstCalConfig->u32VBSize = 0;
51 }
52
53 /* u32Align: 0 is automatic mode, alignment size following system. Non-0 for specified alignment size */
54 if (u32Align == 0) {
55 u32Align = DEFAULT_ALIGN;
56 } else if (u32Align > MAX_ALIGN) {
57 u32Align = MAX_ALIGN;
58 } else {
59 u32Align = (HI_ALIGN_UP(u32Align, DEFAULT_ALIGN));
60 }
61
62 switch (enBitWidth) {
63 case DATA_BITWIDTH_8: {
64 u32BitWidth = 8;
65 break;
66 }
67 case DATA_BITWIDTH_16: {
68 u32BitWidth = 16;
69 break;
70 }
71 default: {
72 u32BitWidth = 0;
73 break;
74 }
75 }
76
77 u32AlignHeight = HI_ALIGN_UP(u32Height, 2);
78
79 if (enCmpMode == COMPRESS_MODE_NONE) {
80 u32MainStride = HI_ALIGN_UP((u32Width * u32BitWidth + 7) >> 3, u32Align);
81 u32YSize = u32MainStride * u32AlignHeight;
82
83 if ((PIXEL_FORMAT_YVU_SEMIPLANAR_420 == enPixelFormat) || (PIXEL_FORMAT_YUV_SEMIPLANAR_420 == enPixelFormat)) {
84 u32MainSize = (u32MainStride * u32AlignHeight * 3) >> 1;
85 } else if (PIXEL_FORMAT_YVU_SEMIPLANAR_422 == enPixelFormat ||
86 PIXEL_FORMAT_YUV_SEMIPLANAR_422 == enPixelFormat) {
87 u32MainSize = u32MainStride * u32AlignHeight * 2;
88 } else if ((enPixelFormat == PIXEL_FORMAT_YUV_400) || (PIXEL_FORMAT_S16C1 == enPixelFormat)) {
89 u32MainSize = u32MainStride * u32AlignHeight;
90 } else {
91 u32MainSize = u32MainStride * u32AlignHeight * 3;
92 }
93
94 u32VBSize = u32MainSize;
95 } else {
96 if (u32Width <= 4096) {
97 u32HeadStride = 16;
98 } else if (u32Width <= 8192) {
99 u32HeadStride = 32;
100 } else {
101 u32HeadStride = 64;
102 }
103
104 if (u32BitWidth == 8) {
105 u32MainStride = HI_ALIGN_UP(u32Width, u32Align);
106 u32HeadYSize = u32HeadStride * u32AlignHeight;
107 u32YSize = u32MainStride * u32AlignHeight;
108
109 if ((PIXEL_FORMAT_YVU_SEMIPLANAR_420 == enPixelFormat) ||
110 (PIXEL_FORMAT_YUV_SEMIPLANAR_420 == enPixelFormat)) {
111 u32HeadSize = (u32HeadStride * u32AlignHeight * 3) >> 1;
112 u32MainSize = (u32MainStride * u32AlignHeight * 3) >> 1;
113 } else if (PIXEL_FORMAT_YVU_SEMIPLANAR_422 == enPixelFormat ||
114 PIXEL_FORMAT_YUV_SEMIPLANAR_422 == enPixelFormat) {
115 u32HeadSize = u32HeadStride * u32AlignHeight * 2;
116 u32MainSize = u32MainStride * u32AlignHeight * 2;
117 } else if (enPixelFormat == PIXEL_FORMAT_YUV_400) {
118 u32HeadSize = u32HeadStride * u32AlignHeight;
119 u32MainSize = u32MainStride * u32AlignHeight;
120 } else {
121 u32HeadSize = u32HeadStride * u32AlignHeight * 3;
122 u32MainSize = u32MainStride * u32AlignHeight * 3;
123 }
124 } else {
125 u32VBSize = 0;
126 u32HeadYSize = 0;
127 u32HeadSize = 0;
128 u32HeadStride = 0;
129 u32MainStride = 0;
130 u32YSize = 0;
131 u32MainSize = 0;
132 u32ExtStride = 0;
133 u32ExtYSize = 0;
134 }
135
136 u32HeadSize = HI_ALIGN_UP(u32HeadSize, u32Align);
137
138 u32VBSize = u32HeadSize + u32MainSize + u32ExtSize;
139 }
140
141 pstCalConfig->u32VBSize = u32VBSize;
142 pstCalConfig->u32HeadYSize = u32HeadYSize;
143 pstCalConfig->u32HeadSize = u32HeadSize;
144 pstCalConfig->u32HeadStride = u32HeadStride;
145 pstCalConfig->u32MainStride = u32MainStride;
146 pstCalConfig->u32MainYSize = u32YSize;
147 pstCalConfig->u32MainSize = u32MainSize;
148 pstCalConfig->u32ExtStride = u32ExtStride;
149 pstCalConfig->u32ExtYSize = u32ExtYSize;
150
151 return;
152 }
153
COMMON_GetPicBufferSize(HI_U32 u32Width,HI_U32 u32Height,PIXEL_FORMAT_E enPixelFormat,DATA_BITWIDTH_E enBitWidth,COMPRESS_MODE_E enCmpMode,HI_U32 u32Align)154 __inline static HI_U32 COMMON_GetPicBufferSize(HI_U32 u32Width, HI_U32 u32Height,
155 PIXEL_FORMAT_E enPixelFormat,
156 DATA_BITWIDTH_E enBitWidth, COMPRESS_MODE_E enCmpMode, HI_U32 u32Align)
157 {
158 VB_CAL_CONFIG_S stCalConfig;
159
160 COMMON_GetPicBufferConfig(u32Width, u32Height, enPixelFormat, enBitWidth, enCmpMode, u32Align, &stCalConfig);
161
162 return stCalConfig.u32VBSize;
163 }
164
VI_GetRawBufferSizeEx(HI_U32 u32Width,HI_U32 u32Height,PIXEL_FORMAT_E enPixelFormat,COMPRESS_MODE_E enCmpMode,HI_U32 u32CmpRatio,HI_U32 u32Align)165 __inline static HI_U32 VI_GetRawBufferSizeEx(HI_U32 u32Width, HI_U32 u32Height,
166 PIXEL_FORMAT_E enPixelFormat,
167 COMPRESS_MODE_E enCmpMode, HI_U32 u32CmpRatio, HI_U32 u32Align)
168 {
169 HI_U32 u32BitWidth;
170 HI_U32 u32Size = 0;
171 HI_U32 u32Stride = 0;
172 HI_U32 u32RawCmpRatio = 1600;
173
174 if ((u32Width > HI_MAXINUM_LIMIT) || (u32Height > HI_MAXINUM_LIMIT)) {
175 return 0;
176 }
177
178 if (enCmpMode == COMPRESS_MODE_LINE) {
179 u32RawCmpRatio = 1600;
180 } else if (enCmpMode == COMPRESS_MODE_FRAME) {
181 if (u32CmpRatio == 0) {
182 u32RawCmpRatio = 2000;
183 } else {
184 u32RawCmpRatio = u32CmpRatio;
185 }
186 }
187
188 /* u32Align: 0 is automatic mode, alignment size following system. Non-0 for specified alignment size */
189 if (u32Align == 0) {
190 u32Align = DEFAULT_ALIGN;
191 } else if (u32Align > MAX_ALIGN) {
192 u32Align = MAX_ALIGN;
193 } else {
194 u32Align = (HI_ALIGN_UP(u32Align, DEFAULT_ALIGN));
195 }
196
197 switch (enPixelFormat) {
198 case PIXEL_FORMAT_RGB_BAYER_8BPP: {
199 u32BitWidth = 8;
200 break;
201 }
202
203 case PIXEL_FORMAT_RGB_BAYER_10BPP: {
204 u32BitWidth = 10;
205 break;
206 }
207
208 case PIXEL_FORMAT_RGB_BAYER_12BPP: {
209 u32BitWidth = 12;
210 break;
211 }
212
213 case PIXEL_FORMAT_RGB_BAYER_14BPP: {
214 u32BitWidth = 14;
215 break;
216 }
217
218 case PIXEL_FORMAT_RGB_BAYER_16BPP: {
219 u32BitWidth = 16;
220 break;
221 }
222
223 default: {
224 u32BitWidth = 0;
225 break;
226 }
227 }
228
229 if (enCmpMode == COMPRESS_MODE_NONE) {
230 u32Stride = HI_ALIGN_UP(HI_ALIGN_UP(u32Width * u32BitWidth, 8) / 8, u32Align);
231 u32Size = u32Stride * u32Height;
232 } else if (enCmpMode == COMPRESS_MODE_LINE) {
233 HI_U32 u32Tmp;
234 u32Tmp = HI_ALIGN_UP((16 + u32Width * u32BitWidth * 1000UL / u32RawCmpRatio + 8192 + 127) / 128, 2);
235 u32Stride = HI_ALIGN_UP(u32Tmp * 16, u32Align);
236 u32Size = u32Stride * u32Height;
237 } else if (enCmpMode == COMPRESS_MODE_FRAME) {
238 u32Size = HI_ALIGN_UP(u32Height * u32Width * u32BitWidth * 1000UL / (u32RawCmpRatio * 8), u32Align);
239 }
240
241 return u32Size;
242 }
243
VI_GetRawBufferSize(HI_U32 u32Width,HI_U32 u32Height,PIXEL_FORMAT_E enPixelFormat,COMPRESS_MODE_E enCmpMode,HI_U32 u32Align)244 __inline static HI_U32 VI_GetRawBufferSize(HI_U32 u32Width, HI_U32 u32Height,
245 PIXEL_FORMAT_E enPixelFormat, COMPRESS_MODE_E enCmpMode, HI_U32 u32Align)
246 {
247 return VI_GetRawBufferSizeEx(u32Width, u32Height, enPixelFormat, enCmpMode, 0, u32Align);
248 }
249
VDEC_GetPicBufferSize(PAYLOAD_TYPE_E enType,HI_U32 u32Width,HI_U32 u32Height,PIXEL_FORMAT_E enPixelFormat,DATA_BITWIDTH_E enBitWidth,HI_U32 u32Align)250 __inline static HI_U32 VDEC_GetPicBufferSize(PAYLOAD_TYPE_E enType, HI_U32 u32Width,
251 HI_U32 u32Height, __attribute__((unused))PIXEL_FORMAT_E enPixelFormat,
252 __attribute__((unused))DATA_BITWIDTH_E enBitWidth,
253 __attribute__((unused))HI_U32 u32Align)
254 {
255 HI_U32 u32AlignWidth, u32AlignHeight;
256 HI_U32 u32Size = 0;
257
258 if ((u32Width > HI_MAXINUM_LIMIT) || (u32Height > HI_MAXINUM_LIMIT)) {
259 return 0;
260 }
261
262 if (enType == PT_H264) {
263 u32AlignWidth = HI_ALIGN_UP(u32Width, H264D_ALIGN_W);
264 u32AlignHeight = HI_ALIGN_UP(u32Height, H264D_ALIGN_H);
265 u32Size = ((u32AlignWidth * u32AlignHeight) * 3) >> 1;
266 } else if (enType == PT_H265) {
267 u32AlignWidth = HI_ALIGN_UP(u32Width, H265D_ALIGN_W);
268 u32AlignHeight = HI_ALIGN_UP(u32Height, H265D_ALIGN_H);
269 u32Size = ((u32AlignWidth * u32AlignHeight) * 3) >> 1;
270 } else if ((enType == PT_JPEG) || (enType == PT_MJPEG)) {
271 /* for PIXEL_FORMAT_YVU_SEMIPLANAR_420 */
272 u32AlignWidth = HI_ALIGN_UP(u32Width, JPEGD_ALIGN_W);
273 u32AlignHeight = HI_ALIGN_UP(u32Height, JPEGD_ALIGN_H);
274 u32Size = (u32AlignWidth * u32AlignHeight * 3) >> 1;
275 } else {
276 u32Size = 0;
277 }
278
279 return u32Size;
280 }
281
VDEC_GetTmvBufferSize(PAYLOAD_TYPE_E enType,HI_U32 u32Width,HI_U32 u32Height)282 __inline static HI_U32 VDEC_GetTmvBufferSize(PAYLOAD_TYPE_E enType, HI_U32 u32Width, HI_U32 u32Height)
283 {
284 HI_U32 WidthInMb, HeightInMb;
285 HI_U32 ColMbSize;
286 HI_U32 u32Size = 0;
287
288 if ((u32Width > HI_MAXINUM_LIMIT) || (u32Height > HI_MAXINUM_LIMIT)) {
289 return 0;
290 }
291
292 if (enType == PT_H264) {
293 WidthInMb = HI_ALIGN_UP(u32Width, 16) >> 4;
294 HeightInMb = HI_ALIGN_UP(u32Height, 16) >> 4;
295 ColMbSize = 16 * 4;
296 u32Size = HI_ALIGN_UP((ColMbSize * WidthInMb * HeightInMb), 128);
297 } else if (enType == PT_H265) {
298 WidthInMb = HI_ALIGN_UP(u32Width, 64) >> 4;
299 HeightInMb = HI_ALIGN_UP(u32Height, 64) >> 4;
300 ColMbSize = 4 * 4;
301 u32Size = HI_ALIGN_UP((ColMbSize * WidthInMb * HeightInMb), 128);
302 } else {
303 u32Size = 0;
304 }
305
306 return u32Size;
307 }
308
VENC_GetRefPicInfoBufferSize(PAYLOAD_TYPE_E enType,HI_U32 u32Width,HI_U32 u32Height,HI_U32 u32Align)309 __inline static HI_U32 VENC_GetRefPicInfoBufferSize(PAYLOAD_TYPE_E enType, HI_U32 u32Width, HI_U32 u32Height,
310 __attribute__((unused))HI_U32 u32Align)
311 {
312 HI_U32 u32Size;
313 HI_U32 u32AlignWidth, u32AlignHeight;
314 HI_U32 u32TmvSize, u32PmeSize, u32PmeInfoSize;
315
316 if ((u32Width > HI_MAXINUM_LIMIT) || (u32Height > HI_MAXINUM_LIMIT)) {
317 return 0;
318 }
319
320 if (enType == PT_H265) {
321 u32AlignWidth = HI_ALIGN_UP(u32Width, 64) >> 6;
322 u32AlignHeight = HI_ALIGN_UP(u32Height, 64) >> 6;
323
324 u32TmvSize = (u32AlignWidth * u32AlignHeight) << 8;
325 u32PmeSize = (u32AlignWidth << 4) * (u32AlignHeight << 4);
326
327 u32AlignWidth = HI_ALIGN_UP(u32Width, 1024) >> 10;
328 u32AlignHeight = HI_ALIGN_UP(u32Height, 64) >> 6;
329 u32PmeInfoSize = (u32AlignWidth * u32AlignHeight) << 5;
330
331 u32Size = u32TmvSize + u32PmeSize + u32PmeInfoSize;
332 } else if (enType == PT_H264) {
333 u32AlignWidth = HI_ALIGN_UP(u32Width, 16) >> 4;
334 u32AlignHeight = HI_ALIGN_UP(u32Height, 16) >> 4;
335 u32TmvSize = (u32AlignWidth * u32AlignHeight) << 5;
336
337 u32AlignWidth = HI_ALIGN_UP(u32Width, 64) >> 6;
338 u32AlignHeight = HI_ALIGN_UP(u32Height, 64) >> 6;
339 u32PmeSize = (u32AlignWidth << 4) * (u32AlignHeight << 4);
340
341 u32AlignWidth = HI_ALIGN_UP(u32Width, 4096) >> 12;
342 u32AlignHeight = HI_ALIGN_UP(u32Height, 16) >> 4;
343 u32PmeInfoSize = (u32AlignWidth * u32AlignHeight) << 5;
344
345 u32Size = u32TmvSize + u32PmeSize + u32PmeInfoSize;
346 } else {
347 u32Size = 0;
348 }
349 return u32Size;
350 }
351
VENC_GetRefBufferSize(PAYLOAD_TYPE_E enType,HI_U32 u32Width,HI_U32 u32Height,DATA_BITWIDTH_E enBitWidth,HI_U32 u32Align)352 __inline static HI_U32 VENC_GetRefBufferSize(PAYLOAD_TYPE_E enType, HI_U32 u32Width, HI_U32 u32Height,
353 DATA_BITWIDTH_E enBitWidth, __attribute__((unused))HI_U32 u32Align)
354 {
355 HI_U32 u32Size = 0;
356 HI_U32 u32AlignWidth, u32AlignHeight, u32BitWidth;
357 HI_U32 u32YHeaderSize, u32CHeaderSize, u32YSize, u32CSize;
358
359 if ((u32Width > HI_MAXINUM_LIMIT) || (u32Height > HI_MAXINUM_LIMIT)) {
360 return 0;
361 }
362
363 if (enBitWidth == DATA_BITWIDTH_8) {
364 u32BitWidth = 8;
365 } else {
366 return 0;
367 }
368
369 if (enType == PT_H265) {
370 u32AlignWidth = HI_ALIGN_UP(u32Width, 128);
371 u32AlignHeight = HI_ALIGN_UP(u32Height, 64) >> 6;
372
373 u32YHeaderSize = u32AlignWidth / 64 * 32 * u32AlignHeight;
374 u32CHeaderSize = u32YHeaderSize;
375
376 u32AlignWidth = HI_ALIGN_UP(u32Width, 64);
377 u32AlignHeight = HI_ALIGN_UP(u32Height, 16);
378 u32YSize = (u32AlignWidth * u32AlignHeight * u32BitWidth) >> 3;
379 u32CSize = u32YSize >> 1;
380
381 u32Size = u32YHeaderSize + u32CHeaderSize + u32YSize + u32CSize;
382 } else if (enType == PT_H264) {
383 u32AlignWidth = HI_ALIGN_UP(u32Width, 512);
384 u32AlignHeight = HI_ALIGN_UP(u32Height, 16) >> 4;
385 u32YHeaderSize = ((u32AlignWidth >> 8) << 4) * u32AlignHeight;
386 u32CHeaderSize = u32YHeaderSize;
387
388 u32AlignWidth = HI_ALIGN_UP(u32Width, 64);
389 u32AlignHeight = HI_ALIGN_UP(u32Height, 16);
390 u32YSize = u32AlignWidth * u32AlignHeight;
391 u32CSize = u32YSize >> 1;
392
393 u32Size = u32YHeaderSize + u32CHeaderSize + u32YSize + u32CSize;
394 } else {
395 u32Size = 0;
396 }
397
398 return u32Size;
399 }
400
VENC_GetQpmapSizeStride(HI_U32 u32Width)401 __inline static HI_U32 VENC_GetQpmapSizeStride(HI_U32 u32Width)
402 {
403 if (u32Width > HI_MAXINUM_LIMIT) {
404 return 0;
405 }
406
407 return DIV_UP(u32Width, 512) * 32;
408 }
409
VENC_GetQpmapSize(HI_U32 u32Width,HI_U32 u32Height)410 __inline static HI_U32 VENC_GetQpmapSize(HI_U32 u32Width, HI_U32 u32Height)
411 {
412 HI_U32 u32Stride, u32AlignHeight;
413
414 if ((u32Width > HI_MAXINUM_LIMIT) || (u32Height > HI_MAXINUM_LIMIT)) {
415 return 0;
416 }
417
418 u32Stride = VENC_GetQpmapSizeStride(u32Width);
419 u32AlignHeight = DIV_UP(u32Height, 16);
420
421 return u32Stride * u32AlignHeight;
422 }
423
VENC_GetSkipWeightSizeStride(PAYLOAD_TYPE_E enType,HI_U32 u32Width)424 __inline static HI_U32 VENC_GetSkipWeightSizeStride(PAYLOAD_TYPE_E enType, HI_U32 u32Width)
425 {
426 HI_U32 u32Stride;
427
428 if (u32Width > HI_MAXINUM_LIMIT) {
429 return 0;
430 }
431
432 if (enType == PT_H265) {
433 u32Stride = DIV_UP(u32Width, 2048) * 16;
434 } else if (enType == PT_H264) {
435 u32Stride = DIV_UP(u32Width, 512) * 16;
436 } else {
437 u32Stride = 0;
438 }
439
440 return u32Stride;
441 }
VENC_GetSkipWeightSize(PAYLOAD_TYPE_E enType,HI_U32 u32Width,HI_U32 u32Height)442 __inline static HI_U32 VENC_GetSkipWeightSize(PAYLOAD_TYPE_E enType, HI_U32 u32Width, HI_U32 u32Height)
443 {
444 HI_U32 u32Stride, u32AlignHeight;
445
446 if ((u32Width > HI_MAXINUM_LIMIT) || (u32Height > HI_MAXINUM_LIMIT)) {
447 return 0;
448 }
449
450 u32Stride = VENC_GetSkipWeightSizeStride(enType, u32Width);
451
452 if (enType == PT_H265) {
453 u32AlignHeight = DIV_UP(u32Height, 64);
454 } else if (enType == PT_H264) {
455 u32AlignHeight = DIV_UP(u32Height, 16);
456 } else {
457 u32AlignHeight = 0;
458 }
459
460 return u32Stride * u32AlignHeight;
461 }
462
463 #ifdef __cplusplus
464 #if __cplusplus
465 }
466 #endif
467 #endif /* __cplusplus */
468
469 #endif /* __HI_BUFFER_H__ */
470
471