• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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