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 26extern "C" { 27#endif 28#endif /* __cplusplus */ 29 30#define HI_MAXINUM_LIMIT 100000 31 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 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 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 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 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 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 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 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 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 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 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} 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