1 /*
2 * Copyright (C) 2021-2023 HiHope Open Source Organization .
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 /*
17 * @file Rockchip_OSAL_OHOS.cpp
18 * @brief
19 * @author csy(csy@rock-chips.com)
20 * @version 1.0.0
21 * @history
22 * 2013.11.26 : Create
23 */
24 #undef ROCKCHIP_LOG_TAG
25 #define ROCKCHIP_LOG_TAG "omx_osal_OHOS"
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <memory>
30 #include <unistd.h>
31 #include <fcntl.h>
32 #include <sys/ioctl.h>
33 #include <codec_omx_ext.h>
34 #ifdef OHOS_BUFFER_HANDLE
35 #include <display_type.h>
36 #include <buffer_handle.h>
37 #endif
38 #include "Rockchip_OSAL_Mutex.h"
39 #include "Rockchip_OSAL_Semaphore.h"
40 #include "Rockchip_OMX_Baseport.h"
41 #include "Rockchip_OMX_Basecomponent.h"
42 #include "Rockchip_OMX_Macros.h"
43
44 #include "Rkvpu_OMX_Vdec.h"
45 #include "Rkvpu_OMX_Venc.h"
46 #include "Rockchip_OSAL_Log.h"
47 #include "Rockchip_OSAL_Env.h"
48 #include "omx_video_global.h"
49 #include "vpu_api.h"
50 #include "Rockchip_OSAL_OHOS.h"
51 #include "VideoExt.h"
52 #include "IVCommonExt.h"
53
54 enum {
55 kFenceTimeoutMs = 1000
56 };
57
58 #ifdef __cplusplus
59 extern "C" {
60 #endif
61
Get_Video_HorAlign(OMX_VIDEO_CODINGTYPE codecId,OMX_U32 width,OMX_U32 height,OMX_U32 codecProfile)62 OMX_U32 Get_Video_HorAlign(OMX_VIDEO_CODINGTYPE codecId, OMX_U32 width, OMX_U32 height, OMX_U32 codecProfile)
63 {
64 OMX_U32 stride = 0;
65 if (codecId == (OMX_VIDEO_CODINGTYPE)CODEC_OMX_VIDEO_CodingHEVC) {
66 if (codecProfile == CODEC_HEVC_PROFILE_MAIN10 || codecProfile == CODEC_HEVC_PROFILE_MAIN10_HDR10) {
67 // 10:byte alignment, 8:byte alignment, 255:byte alignment, 256:byte alignment
68 stride = (((width * 10 / 8 + 255) & ~(255)) | (256));
69 } else
70 // 255:byte alignment, 256:byte alignment
71 stride = ((width + 255) & (~255)) | (256);
72 } else if (codecId == (OMX_VIDEO_CODINGTYPE)CODEC_OMX_VIDEO_CodingVP9) {
73 #ifdef AVS100
74 // 255:byte alignment, 256:byte alignment
75 stride = ((width + 255) & (~255)) | (256);
76 #else
77 // 127:byte alignment
78 stride = (width + 127) & (~127);
79 #endif
80 } else {
81 if (codecProfile == OMX_VIDEO_AVCProfileHigh10 && codecId == OMX_VIDEO_CodingAVC) {
82 stride = ((width * 10 / 8 + 15) & (~15)); // 10:byte alignment, 8:byte alignment, 15:byte alignment
83 } else
84 stride = ((width + 15) & (~15)); // 15:byte alignment
85 }
86 #ifdef AVS100
87 if (access("/d/mpp_service/rkvdec/aclk", F_OK) == 0 ||
88 access("/proc/mpp_service/rkvdec/aclk", F_OK) == 0) {
89 #else
90 if (access("/dev/rkvdec", 06) == 0) { // 06:operation code
91 #endif
92 if (width > 1920 || height > 1088) { // 1920:Resolution size, 1088:Resolution size
93 if (codecId == OMX_VIDEO_CodingAVC) {
94 if (codecProfile == OMX_VIDEO_AVCProfileHigh10) {
95 // 10:byte alignment, 8:byte alignment, 255:byte alignment, 256:byte alignment
96 stride = (((width * 10 / 8 + 255) & ~(255)) | (256));
97 } else
98 // 255:byte alignment, 256:byte alignment
99 stride = ((width + 255) & (~255)) | (256);
100 }
101 }
102 }
103
104 return stride;
105 }
106
107 OMX_U32 Get_Video_VerAlign(OMX_VIDEO_CODINGTYPE codecId, OMX_U32 height, OMX_U32 codecProfile)
108 {
109 OMX_U32 stride = 0;;
110 if (codecId == (OMX_VIDEO_CODINGTYPE)CODEC_OMX_VIDEO_CodingHEVC) {
111 if (codecProfile == CODEC_HEVC_PROFILE_MAIN10 || codecProfile == CODEC_HEVC_PROFILE_MAIN10_HDR10)
112 stride = (height + 15) & (~15); // 15:byte alignment
113 else
114 stride = (height + 7) & (~7); // 7:byte alignment
115 } else if (codecId == (OMX_VIDEO_CODINGTYPE)CODEC_OMX_VIDEO_CodingVP9) {
116 stride = (height + 63) & (~63); // 63:byte alignment
117 } else {
118 stride = ((height + 15) & (~15)); // 15:byte alignment
119 }
120 return stride;
121 }
122
123 OMX_BOOL Rockchip_OSAL_Check_Use_FBCMode(OMX_VIDEO_CODINGTYPE codecId, int32_t depth,
124 ROCKCHIP_OMX_BASEPORT *pPort)
125 {
126 OMX_BOOL fbcMode = OMX_FALSE;
127 OMX_U32 pValue;
128 OMX_U32 width, height;
129
130 Rockchip_OSAL_GetEnvU32("omx_fbc_disable", &pValue, 0);
131 if (pValue == 1) {
132 return OMX_FALSE;
133 }
134
135 if (pPort->bufferProcessType != BUFFER_SHARE) {
136 return OMX_FALSE;
137 }
138
139 width = pPort->portDefinition.format.video.nFrameWidth;
140 height = pPort->portDefinition.format.video.nFrameHeight;
141
142 #ifdef SUPPORT_AFBC
143 // 10bit force set fbc mode
144 if ((depth == OMX_DEPTH_BIT_10) || ((width * height > 1920 * 1088) // 1920:Resolution size, 1088:Resolution size
145 && (codecId == OMX_VIDEO_CodingAVC
146 || codecId == (OMX_VIDEO_CODINGTYPE)CODEC_OMX_VIDEO_CodingHEVC
147 || codecId == (OMX_VIDEO_CODINGTYPE)CODEC_OMX_VIDEO_CodingVP9))) {
148 fbcMode = OMX_TRUE;
149 }
150 #else
151 (void)codecId;
152 (void)width;
153 (void)height;
154 (void)depth;
155 #endif
156
157 return fbcMode;
158 }
159 OMX_ERRORTYPE Rockchip_OSAL_GetInfoFromMetaData(OMX_IN OMX_BYTE pBuffer,
160 OMX_OUT OMX_PTR *ppBuf)
161 {
162 OMX_ERRORTYPE ret = OMX_ErrorNone;
163 MetadataBufferType type;
164
165 FunctionIn();
166
167 /*
168 * meta data contains the following data format.
169 * payload depends on the MetadataBufferType
170 * --------------------------------------------------------------
171 * | MetadataBufferType | payload |
172 * --------------------------------------------------------------
173 *
174 * If MetadataBufferType is kMetadataBufferTypeCameraSource, then
175 * --------------------------------------------------------------
176 * | kMetadataBufferTypeCameraSource | physical addr. of Y |physical addr. of CbCr |
177 * --------------------------------------------------------------
178 *
179 * If MetadataBufferType is kMetadataBufferTypeGrallocSource, then
180 * --------------------------------------------------------------
181 * | kMetadataBufferTypeGrallocSource | buffer_handle_t |
182 * --------------------------------------------------------------
183 */
184 /* MetadataBufferType */
185 Rockchip_OSAL_Memcpy(&type, pBuffer, sizeof(MetadataBufferType));
186 #ifdef USE_ANW
187 if (type > kMetadataBufferTypeNativeHandleSource) {
188 omx_err("Data passed in with metadata mode does not have type "
189 "kMetadataBufferTypeGrallocSource (%d), has type %ld instead",
190 kMetadataBufferTypeGrallocSource, type);
191 return OMX_ErrorBadParameter;
192 }
193 #else
194 if ((type != kMetadataBufferTypeGrallocSource) && (type != kMetadataBufferTypeCameraSource)) {
195 omx_err("Data passed in with metadata mode does not have type "
196 "kMetadataBufferTypeGrallocSource (%d), has type %ld instead",
197 kMetadataBufferTypeGrallocSource, type);
198 return OMX_ErrorBadParameter;
199 }
200 #endif
201 if (type == kMetadataBufferTypeCameraSource) {
202
203 void *pAddress = nullptr;
204
205 /* Address. of Y */
206 Rockchip_OSAL_Memcpy(&pAddress, pBuffer + sizeof(MetadataBufferType), sizeof(void *));
207 ppBuf[0] = (void *)pAddress;
208
209 /* Address. of CbCr */
210 Rockchip_OSAL_Memcpy(&pAddress, pBuffer + sizeof(MetadataBufferType) + sizeof(void *), sizeof(void *));
211 ppBuf[1] = (void *)pAddress;
212
213 } else if (type == kMetadataBufferTypeGrallocSource) {
214 }
215 #ifdef USE_ANW
216 else if (type == kMetadataBufferTypeANWBuffer) {
217 ANativeWindowBuffer *buffer = nativeMeta.pBuffer;
218 if (buffer != nullptr)
219 ppBuf[0] = (OMX_PTR)buffer->handle;
220 if (nativeMeta.nFenceFd >= 0) {
221 sp<Fence> fence = new Fence(nativeMeta.nFenceFd);
222 nativeMeta.nFenceFd = -1;
223 status_t err = fence->wait(kFenceTimeoutMs);
224 if (err != OK) {
225 omx_err("Timed out waiting on input fence");
226 return OMX_ErrorBadParameter;
227 }
228 }
229 } else if (type == kMetadataBufferTypeNativeHandleSource) {
230 omx_trace("kMetadataBufferTypeNativeHandleSource process in");
231 VideoNativeHandleMetadata &nativehandleMeta = *(VideoNativeHandleMetadata*)pBuffer;
232 ppBuf[0] = (OMX_PTR)nativehandleMeta.pHandle;
233 }
234 #endif
235
236 FunctionOut();
237
238 return ret;
239 }
240
241 OMX_ERRORTYPE Rockchip_OSAL_SetPrependSPSPPSToIDR(
242 OMX_PTR pComponentParameterStructure,
243 OMX_PTR pbPrependSpsPpsToIdr)
244 {
245 OMX_ERRORTYPE ret = OMX_ErrorNone;
246 PrependSPSPPSToIDRFramesParams *pANBParams = (PrependSPSPPSToIDRFramesParams *)pComponentParameterStructure;
247
248 ret = Rockchip_OMX_Check_SizeVersion(pANBParams, sizeof(PrependSPSPPSToIDRFramesParams));
249 if (ret != OMX_ErrorNone) {
250 omx_err("%s: Rockchip_OMX_Check_SizeVersion(PrependSPSPPSToIDRFrames) is failed", __func__);
251 goto EXIT;
252 }
253
254 (*((OMX_BOOL *)pbPrependSpsPpsToIdr)) = pANBParams->bEnable;
255
256 EXIT:
257 return ret;
258 }
259
260 #ifdef OHOS_BUFFER_HANDLE
261 OMX_U32 CodecOmxExtColor2CodecFormat(enum CodecColorFormatExt codecExtColor)
262 {
263 OMX_U32 codecFormat = PIXEL_FMT_BUTT;
264 switch (codecExtColor) {
265 case CODEC_COLOR_FORMAT_RGBA8888:
266 codecFormat = PIXEL_FMT_RGBA_8888;
267 break;
268 default:
269 omx_err("%s: undefined omxColorFormat[%d]", __func__, codecExtColor);
270 break;
271 }
272 return codecFormat;
273 }
274 OMX_U32 Rockchip_OSAL_OmxColorFormat2CodecFormat(OMX_COLOR_FORMATTYPE omxColorFormat)
275 {
276 OMX_U32 codecFormat = PIXEL_FMT_BUTT;
277 switch (omxColorFormat) {
278 case OMX_COLOR_Format16bitRGB565:
279 codecFormat = PIXEL_FMT_RGB_565;
280 break;
281 case OMX_COLOR_Format12bitRGB444:
282 codecFormat = PIXEL_FMT_RGB_444;
283 break;
284 case OMX_COLOR_Format24bitRGB888:
285 codecFormat = PIXEL_FMT_RGB_888;
286 break;
287 case OMX_COLOR_Format16bitBGR565:
288 codecFormat = PIXEL_FMT_BGR_565;
289 break;
290 case OMX_COLOR_Format32bitBGRA8888:
291 codecFormat = PIXEL_FMT_BGRA_8888;
292 break;
293 case OMX_COLOR_FormatYUV422SemiPlanar:
294 codecFormat = PIXEL_FMT_YCBCR_422_SP;
295 break;
296 case OMX_COLOR_FormatYUV420SemiPlanar:
297 codecFormat = PIXEL_FMT_YCBCR_420_SP;
298 break;
299 case OMX_COLOR_FormatYUV422Planar:
300 codecFormat = PIXEL_FMT_YCBCR_422_P;
301 break;
302 case OMX_COLOR_FormatYUV420Planar:
303 codecFormat = PIXEL_FMT_YCBCR_420_P;
304 break;
305 case OMX_COLOR_FormatYCbYCr:
306 codecFormat = PIXEL_FMT_YUYV_422_PKG;
307 break;
308 case OMX_COLOR_FormatCbYCrY:
309 codecFormat = PIXEL_FMT_UYVY_422_PKG;
310 break;
311 case OMX_COLOR_FormatYCrYCb:
312 codecFormat = PIXEL_FMT_YVYU_422_PKG;
313 break;
314 case OMX_COLOR_FormatCrYCbY:
315 codecFormat = PIXEL_FMT_VYUY_422_PKG;
316 break;
317 default:
318 codecFormat = CodecOmxExtColor2CodecFormat((enum CodecColorFormatExt)omxColorFormat);
319 break;
320 }
321 return codecFormat;
322 }
323 OMX_COLOR_FORMATTYPE Rochip_OSAL_CodecFormat2OmxColorFormat(OMX_U32 codecFormat)
324 {
325 OMX_COLOR_FORMATTYPE omxColorFormat = OMX_COLOR_FormatUnused;
326 switch (codecFormat) {
327 case PIXEL_FMT_RGB_565:
328 omxColorFormat = OMX_COLOR_Format16bitRGB565;
329 break;
330 case PIXEL_FMT_RGB_444:
331 omxColorFormat = OMX_COLOR_Format12bitRGB444;
332 break;
333 case PIXEL_FMT_RGB_888:
334 omxColorFormat = OMX_COLOR_Format24bitRGB888;
335 break;
336 case PIXEL_FMT_BGR_565:
337 omxColorFormat = OMX_COLOR_Format16bitBGR565;
338 break;
339 case PIXEL_FMT_BGRA_8888:
340 omxColorFormat = OMX_COLOR_Format32bitBGRA8888;
341 break;
342 case PIXEL_FMT_YCBCR_422_SP:
343 omxColorFormat = OMX_COLOR_FormatYUV422SemiPlanar;
344 break;
345 case PIXEL_FMT_YCBCR_420_SP:
346 omxColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
347 break;
348 case PIXEL_FMT_YCBCR_422_P:
349 omxColorFormat = OMX_COLOR_FormatYUV422Planar;
350 break;
351 case PIXEL_FMT_YCBCR_420_P:
352 omxColorFormat = OMX_COLOR_FormatYUV420Planar;
353 break;
354 case PIXEL_FMT_YUYV_422_PKG:
355 omxColorFormat = OMX_COLOR_FormatYCbYCr;
356 break;
357 case PIXEL_FMT_UYVY_422_PKG:
358 omxColorFormat = OMX_COLOR_FormatCbYCrY;
359 break;
360 case PIXEL_FMT_YVYU_422_PKG:
361 omxColorFormat = OMX_COLOR_FormatYCrYCb;
362 break;
363 case PIXEL_FMT_VYUY_422_PKG:
364 omxColorFormat = OMX_COLOR_FormatCrYCbY;
365 break;
366 case PIXEL_FMT_RGBA_8888:
367 omxColorFormat = (OMX_COLOR_FORMATTYPE)CODEC_COLOR_FORMAT_RGBA8888;
368 break;
369 default:
370 omx_err("%s: undefined codecColorFormat[%d]", __func__, omxColorFormat);
371 break;
372 }
373 return omxColorFormat;
374 }
375 OMX_COLOR_FORMATTYPE Rockchip_OSAL_GetBufferHandleColorFormat(BufferHandle* bufferHandle)
376 {
377 if (bufferHandle == NULL) {
378 omx_err_f("bufferHandle is null");
379 return OMX_COLOR_FormatUnused;
380 }
381 return Rochip_OSAL_CodecFormat2OmxColorFormat(bufferHandle->format);
382 }
383 #endif
384
385 OMX_COLOR_FORMATTYPE Rockchip_OSAL_Hal2OMXPixelFormat(
386 unsigned int hal_format)
387 {
388 OMX_COLOR_FORMATTYPE omx_format;
389 switch (hal_format) {
390 case HAL_PIXEL_FORMAT_YCbCr_422_I:
391 omx_format = OMX_COLOR_FormatYCbYCr;
392 break;
393 case HAL_PIXEL_FORMAT_YV12:
394 omx_format = OMX_COLOR_FormatYUV420Planar;
395 break;
396 case HAL_PIXEL_FORMAT_YCrCb_NV12:
397 omx_format = OMX_COLOR_FormatYUV420SemiPlanar;
398 break;
399 case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
400 omx_format = OMX_COLOR_FormatYUV420SemiPlanar;
401 break;
402 case HAL_PIXEL_FORMAT_YCbCr_420_888:
403 omx_format = (OMX_COLOR_FORMATTYPE)OMX_COLOR_FormatYUV420Flexible;
404 break;
405 case HAL_PIXEL_FORMAT_BGRA_8888:
406 omx_format = OMX_COLOR_Format32bitBGRA8888;
407 break;
408 case HAL_PIXEL_FORMAT_RGBA_8888:
409 case HAL_PIXEL_FORMAT_RGBX_8888:
410 omx_format = OMX_COLOR_Format32bitARGB8888;
411 break;
412 default:
413 omx_format = OMX_COLOR_FormatYUV420Planar;
414 break;
415 }
416 return omx_format;
417 }
418
419 unsigned int Rockchip_OSAL_OMX2HalPixelFormat(
420 OMX_COLOR_FORMATTYPE omx_format)
421 {
422 unsigned int hal_format;
423 switch ((OMX_U32)omx_format) {
424 case OMX_COLOR_FormatYCbYCr:
425 hal_format = HAL_PIXEL_FORMAT_YCbCr_422_I;
426 break;
427 case OMX_COLOR_FormatYUV420Planar:
428 hal_format = HAL_PIXEL_FORMAT_YV12;
429 break;
430 case OMX_COLOR_FormatYUV420SemiPlanar:
431 hal_format = HAL_PIXEL_FORMAT_YCrCb_NV12;
432 break;
433 case OMX_COLOR_FormatYUV420Flexible:
434 hal_format = HAL_PIXEL_FORMAT_YCbCr_420_888;
435 break;
436 case OMX_COLOR_Format32bitARGB8888:
437 hal_format = HAL_PIXEL_FORMAT_RGBA_8888;
438 break;
439 case OMX_COLOR_Format32bitBGRA8888:
440 hal_format = HAL_PIXEL_FORMAT_BGRA_8888;
441 break;
442 default:
443 hal_format = HAL_PIXEL_FORMAT_YV12;
444 break;
445 }
446 return hal_format;
447 }
448
449 OMX_ERRORTYPE Rockchip_OSAL_CommitBuffer(
450 ROCKCHIP_OMX_BASECOMPONENT *pRockchipComponent,
451 OMX_U32 index)
452 {
453 RKVPU_OMX_VIDEODEC_COMPONENT *pVideoDec = (RKVPU_OMX_VIDEODEC_COMPONENT *)pRockchipComponent->hComponentHandle;
454 ROCKCHIP_OMX_BASEPORT *pRockchipPort = &pRockchipComponent->pRockchipPort[OUTPUT_PORT_INDEX];
455 struct vpu_display_mem_pool *pMem_pool = (struct vpu_display_mem_pool*)pVideoDec->vpumem_handle;
456 OMX_U32 width = pRockchipPort->portDefinition.format.video.nStride;
457 OMX_U32 height = pRockchipPort->portDefinition.format.video.nSliceHeight;
458 #if 1 // LOW_VRESION
459 OMX_U32 nBytesize = width * height * 2;
460 #else
461 OMX_U32 nBytesize = width * height * 9 / 5;
462 #endif
463 OMX_S32 dupshared_fd = -1;
464 OMX_BUFFERHEADERTYPE* bufferHeader = pRockchipPort->extendBufferHeader[index].OMXBufferHeader;
465 return OMX_ErrorNone;
466 }
467
468 OMX_ERRORTYPE Rockchip_OSAL_Fd2VpumemPool(ROCKCHIP_OMX_BASECOMPONENT *pRockchipComponent,
469 OMX_BUFFERHEADERTYPE* bufferHeader)
470 {
471 OMX_ERRORTYPE ret = OMX_ErrorNone;
472 ROCKCHIP_OMX_BASEPORT *pRockchipPort = &pRockchipComponent->pRockchipPort[OUTPUT_PORT_INDEX];
473 OMX_U32 i = 0;
474
475 for (i = 0; i < pRockchipPort->portDefinition.nBufferCountActual; i++) {
476 if (pRockchipPort->extendBufferHeader[i].OMXBufferHeader == bufferHeader) {
477 omx_trace("commit bufferHeader 0x%x", bufferHeader);
478 break;
479 }
480 }
481
482 if (!pRockchipPort->extendBufferHeader[i].pRegisterFlag) {
483 ret = Rockchip_OSAL_CommitBuffer(pRockchipComponent, i);
484 if (ret != OMX_ErrorNone) {
485 omx_err("commit buffer error header: %p", bufferHeader);
486 }
487 } else {
488 omx_trace(" free bufferHeader 0x%x", pRockchipPort->extendBufferHeader[i].OMXBufferHeader);
489 if (pRockchipPort->extendBufferHeader[i].pPrivate != nullptr) {
490 Rockchip_OSAL_FreeVpumem(pRockchipPort->extendBufferHeader[i].pPrivate);
491 pRockchipPort->extendBufferHeader[i].pPrivate = nullptr;
492 };
493 }
494 return OMX_ErrorNone;
495 }
496
497 OMX_ERRORTYPE Rockchip_OSAL_resetVpumemPool(ROCKCHIP_OMX_BASECOMPONENT *pRockchipComponent)
498 {
499 RKVPU_OMX_VIDEODEC_COMPONENT *pVideoDec = (RKVPU_OMX_VIDEODEC_COMPONENT *)pRockchipComponent->hComponentHandle;
500 struct vpu_display_mem_pool *pMem_pool = (struct vpu_display_mem_pool*)pVideoDec->vpumem_handle;
501 pMem_pool->reset(pMem_pool);
502 return OMX_ErrorNone;
503 }
504
505 OMX_ERRORTYPE Rockchip_OSAL_FreeVpumem(OMX_IN OMX_PTR pVpuframe)
506 {
507 omx_trace("Rockchip_OSAL_FreeVpumem");
508 VPU_FRAME *pframe = (VPU_FRAME *)pVpuframe;
509 VPUMemLink(&pframe->vpumem);
510 VPUFreeLinear(&pframe->vpumem);
511 Rockchip_OSAL_Free(pframe);
512 return OMX_ErrorNone;
513 }
514
515 OMX_BUFFERHEADERTYPE *Rockchip_OSAL_Fd2OmxBufferHeader(ROCKCHIP_OMX_BASEPORT *pRockchipPort,
516 OMX_IN OMX_S32 fd, OMX_IN OMX_PTR pVpuframe)
517 {
518 OMX_U32 i = 0;
519 for (i = 0; i < pRockchipPort->portDefinition.nBufferCountActual; i++) {
520 if (fd == pRockchipPort->extendBufferHeader[i].buf_fd[0]) {
521 omx_trace(" current fd = 0x%x send to render current header 0x%x",
522 fd, pRockchipPort->extendBufferHeader[i].OMXBufferHeader);
523 if (pRockchipPort->extendBufferHeader[i].pPrivate != nullptr) {
524 omx_trace("This buff alreay send to display ");
525 return nullptr;
526 }
527 if (pVpuframe) {
528 pRockchipPort->extendBufferHeader[i].pPrivate = pVpuframe;
529 } else {
530 omx_trace("vpu_mem point is nullptr may error");
531 }
532 return pRockchipPort->extendBufferHeader[i].OMXBufferHeader;
533 }
534 }
535 return nullptr;
536 }
537
538 OMX_ERRORTYPE Rockchip_OSAL_Openvpumempool(OMX_IN ROCKCHIP_OMX_BASECOMPONENT *pRockchipComponent, OMX_U32 portIndex)
539 {
540 RKVPU_OMX_VIDEODEC_COMPONENT *pVideoDec = (RKVPU_OMX_VIDEODEC_COMPONENT *)pRockchipComponent->hComponentHandle;
541 ROCKCHIP_OMX_BASEPORT *pRockchipPort = &pRockchipComponent->pRockchipPort[portIndex];
542 if (pRockchipPort->bufferProcessType == BUFFER_SHARE) {
543 pVideoDec->vpumem_handle = (void*)open_vpu_memory_pool();
544 if (pVideoDec->vpumem_handle != nullptr) {
545 omx_trace("open_vpu_memory_pool success handle 0x%x", pVideoDec->vpumem_handle);
546 }
547 } else {
548 vpu_display_mem_pool *pool = nullptr;
549 OMX_U32 hor_stride = Get_Video_HorAlign(pVideoDec->codecId,
550 pRockchipPort->portDefinition.format.video.nFrameWidth,
551 pRockchipPort->portDefinition.format.video.nFrameHeight, pVideoDec->codecProfile);
552
553 OMX_U32 ver_stride = Get_Video_VerAlign(pVideoDec->codecId,
554 pRockchipPort->portDefinition.format.video.nFrameHeight, pVideoDec->codecProfile);
555 omx_err("hor_stride %d ver_stride %d", hor_stride, ver_stride);
556 if (0 != create_vpu_memory_pool_allocator(&pool, 8, (hor_stride * ver_stride * 2))) {
557 omx_err("create_vpu_memory_pool_allocator fail");
558 }
559 pVideoDec->vpumem_handle = (void*)(pool);
560 }
561 return OMX_ErrorNone;
562 }
563
564 OMX_ERRORTYPE Rockchip_OSAL_Closevpumempool(OMX_IN ROCKCHIP_OMX_BASECOMPONENT *pRockchipComponent)
565 {
566 RKVPU_OMX_VIDEODEC_COMPONENT *pVideoDec = (RKVPU_OMX_VIDEODEC_COMPONENT *)pRockchipComponent->hComponentHandle;
567 ROCKCHIP_OMX_BASEPORT *pRockchipPort = &pRockchipComponent->pRockchipPort[OUTPUT_PORT_INDEX];
568 if (pRockchipPort->bufferProcessType == BUFFER_SHARE && pVideoDec->vpumem_handle != nullptr) {
569 close_vpu_memory_pool((vpu_display_mem_pool *)pVideoDec->vpumem_handle);
570 pVideoDec->vpumem_handle = nullptr;
571 } else if (pVideoDec->vpumem_handle != nullptr) {
572 release_vpu_memory_pool_allocator((vpu_display_mem_pool*)pVideoDec->vpumem_handle);
573 pVideoDec->vpumem_handle = nullptr;
574 }
575 return OMX_ErrorNone;
576 }
577
578 // DDR Frequency conversion
579 OMX_ERRORTYPE Rockchip_OSAL_PowerControl(
580 ROCKCHIP_OMX_BASECOMPONENT *pRockchipComponent,
581 int32_t width,
582 int32_t height,
583 int32_t mHevc,
584 int32_t frameRate,
585 OMX_BOOL mFlag,
586 int bitDepth)
587 {
588 RKVPU_OMX_VIDEODEC_COMPONENT *pVideoDec = (RKVPU_OMX_VIDEODEC_COMPONENT *)pRockchipComponent->hComponentHandle;
589 OMX_U32 nValue = 0;
590 if (Rockchip_OSAL_GetEnvU32("sf.power.control", &nValue, 0) || nValue <= 0) {
591 omx_info("power control is not set");
592 return OMX_ErrorUndefined;
593 }
594
595 if (pVideoDec->power_fd == -1) {
596 pVideoDec->power_fd = open("/dev/video_state", O_WRONLY);
597 if (pVideoDec->power_fd == -1) {
598 omx_err("power control open /dev/video_state fail!");
599 }
600 }
601
602 if (pVideoDec->power_fd == -1) {
603 pVideoDec->power_fd = open("/sys/class/devfreq/dmc/system_status", O_WRONLY);
604 if (pVideoDec->power_fd == -1) {
605 omx_err("power control open /sys/class/devfreq/dmc/system_status fail");
606 }
607 }
608
609 if (bitDepth <= 0) {
610 bitDepth = 8;
611 }
612
613 char para[200] = {0}; // 200:array length
614 int paraLen = 0;
615 paraLen = sprintf(para, "%d,width=%d,height=%d,ishevc=%d,videoFramerate=%d,streamBitrate=%d",
616 mFlag, width, height, mHevc, frameRate, bitDepth);
617 omx_info(" write: %s", para);
618 if (pVideoDec->power_fd != -1) {
619 write(pVideoDec->power_fd, para, paraLen);
620 if (!mFlag) {
621 close(pVideoDec->power_fd);
622 pVideoDec->power_fd = -1;
623 }
624 }
625
626 return OMX_ErrorNone;
627 }
628
629 OMX_COLOR_FORMATTYPE Rockchip_OSAL_CheckFormat(
630 ROCKCHIP_OMX_BASECOMPONENT *pRockchipComponent,
631 OMX_IN OMX_PTR pVpuframe)
632 {
633 RKVPU_OMX_VIDEODEC_COMPONENT *pVideoDec = (RKVPU_OMX_VIDEODEC_COMPONENT *)pRockchipComponent->hComponentHandle;
634 ROCKCHIP_OMX_BASEPORT *pInputPort = &pRockchipComponent->pRockchipPort[INPUT_PORT_INDEX];
635 ROCKCHIP_OMX_BASEPORT *pOutputPort = &pRockchipComponent->pRockchipPort[OUTPUT_PORT_INDEX];
636 OMX_COLOR_FORMATTYPE eColorFormat = pOutputPort->portDefinition.format.video.eColorFormat;
637 VPU_FRAME *pframe = (VPU_FRAME *)pVpuframe;
638
639 if ((pVideoDec->codecId == (OMX_VIDEO_CODINGTYPE)CODEC_OMX_VIDEO_CodingHEVC && (pframe->OutputWidth != 0x20))
640 || (pframe->ColorType & VPU_OUTPUT_FORMAT_BIT_MASK) == VPU_OUTPUT_FORMAT_BIT_10) { // 10bit
641 OMX_BOOL fbcMode = Rockchip_OSAL_Check_Use_FBCMode(pVideoDec->codecId,
642 (int32_t)OMX_DEPTH_BIT_10, pOutputPort);
643
644 if ((pframe->ColorType & 0xf) == VPU_OUTPUT_FORMAT_YUV422) {
645 if (fbcMode) {
646 eColorFormat = (OMX_COLOR_FORMATTYPE)HAL_PIXEL_FORMAT_Y210;
647 } else {
648 eColorFormat = (OMX_COLOR_FORMATTYPE)HAL_PIXEL_FORMAT_YCbCr_422_SP_10;
649 }
650 } else {
651 if (fbcMode) {
652 eColorFormat = (OMX_COLOR_FORMATTYPE)HAL_PIXEL_FORMAT_YUV420_10BIT_I;
653 } else {
654 eColorFormat = (OMX_COLOR_FORMATTYPE)HAL_PIXEL_FORMAT_YCrCb_NV12_10;
655 }
656 }
657
658 if ((pframe->ColorType & OMX_COLORSPACE_MASK) != 0) {
659 OMX_RK_EXT_COLORSPACE colorSpace =
660 (OMX_RK_EXT_COLORSPACE)((pframe->ColorType & OMX_COLORSPACE_MASK) >> 20); // 20:byte alignment
661 pVideoDec->extColorSpace = colorSpace;
662 omx_trace("extension color space = %d", colorSpace);
663 }
664 if ((pframe->ColorType & OMX_DYNCRANGE_MASK) != 0) {
665 OMX_RK_EXT_DYNCRANGE dyncRange = (OMX_RK_EXT_DYNCRANGE)((pframe->ColorType & OMX_DYNCRANGE_MASK) >> 24);
666 pVideoDec->extDyncRange = dyncRange;
667 }
668
669 if (pVideoDec->bIsPowerControl == OMX_TRUE && pVideoDec->bIs10bit == OMX_FALSE) {
670 Rockchip_OSAL_PowerControl(pRockchipComponent, 3840, 2160, pVideoDec->bIsHevc, /* 3840:Resolution size,
671 2160:Resolution size */
672 pInputPort->portDefinition.format.video.xFramerate,
673 OMX_FALSE,
674 8); // 8:point
675 pVideoDec->bIsPowerControl = OMX_FALSE;
676 }
677
678 if (pframe->FrameWidth > 1920 && pframe->FrameHeight > 1088 // 1920:Resolution size, 1088:Resolution size
679 && pVideoDec->bIsPowerControl == OMX_FALSE) {
680 Rockchip_OSAL_PowerControl(pRockchipComponent, 3840, 2160, pVideoDec->bIsHevc, /* 3840:Resolution size,
681 2160:Resolution size */
682 pInputPort->portDefinition.format.video.xFramerate,
683 OMX_TRUE,
684 10); // 10:point
685 pVideoDec->bIsPowerControl = OMX_TRUE;
686 }
687 pVideoDec->bIs10bit = OMX_TRUE;
688 }
689
690 return eColorFormat;
691 }
692 #ifdef USE_STOREMETADATA
693 #ifdef AVS80
694 OMX_U32 Rockchip_OSAL_GetVideoNativeMetaSize()
695 {
696 return sizeof(VideoNativeMetadata);
697 }
698
699 OMX_U32 Rockchip_OSAL_GetVideoGrallocMetaSize()
700 {
701 return sizeof(VideoGrallocMetadata);
702 }
703 #endif
704 #endif
705 OMX_U32 GetDataSize(OMX_U32 width, OMX_U32 height, OMX_COLOR_FORMATTYPE format)
706 {
707 if (format == OMX_COLOR_FormatYUV420SemiPlanar || format == OMX_COLOR_FormatYUV420Planar)
708 {
709 return width * height * 3 / 2; // 3: byte alignment, 2: byte alignment
710 } else {
711 return width * height * 4; // 4: byte alignment
712 }
713 }
714
715 OMX_ERRORTYPE Rkvpu_ComputeDecBufferCount(
716 OMX_HANDLETYPE hComponent)
717 {
718 OMX_ERRORTYPE ret = OMX_ErrorNone;
719 OMX_COMPONENTTYPE *pOMXComponent = nullptr;
720 ROCKCHIP_OMX_BASECOMPONENT *pRockchipComponent = nullptr;
721 RKVPU_OMX_VIDEODEC_COMPONENT *pVideoDec = nullptr;
722 ROCKCHIP_OMX_BASEPORT *pInputRockchipPort = nullptr;
723 ROCKCHIP_OMX_BASEPORT *pOutputRockchipPort = nullptr;
724 OMX_U32 nValue = 0;
725 OMX_BOOL nLowMemMode = OMX_FALSE;
726 OMX_U32 nTotalMemSize = 0;
727 OMX_U32 nMaxBufferCount = 0;
728 OMX_U32 nMaxLowMemBufferCount = 0;
729 OMX_U32 nBufferSize = 0;
730 OMX_U32 nRefFrameNum = 0;
731
732 FunctionIn();
733
734 char pValue[128 + 1]; // 128:array length
735
736 if (hComponent == nullptr) {
737 omx_err("omx component is nullptr");
738 ret = OMX_ErrorBadParameter;
739 goto EXIT;
740 }
741 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
742 ret = Rockchip_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
743 if (ret != OMX_ErrorNone) {
744 omx_err("omx component version check failed!");
745 goto EXIT;
746 }
747
748 if (pOMXComponent->pComponentPrivate == nullptr) {
749 omx_err("omx component private is nullptr!");
750 ret = OMX_ErrorBadParameter;
751 goto EXIT;
752 }
753 pRockchipComponent = (ROCKCHIP_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
754
755 pVideoDec = (RKVPU_OMX_VIDEODEC_COMPONENT *)pRockchipComponent->hComponentHandle;
756 if (pVideoDec == nullptr) {
757 omx_err("video decode component is nullptr!");
758 ret = OMX_ErrorBadParameter;
759 goto EXIT;
760 }
761
762 if (pRockchipComponent->currentState == OMX_StateInvalid) {
763 omx_err("current state is invalid!");
764 ret = OMX_ErrorInvalidState;
765 goto EXIT;
766 }
767
768 pInputRockchipPort = &pRockchipComponent->pRockchipPort[INPUT_PORT_INDEX];
769 pOutputRockchipPort = &pRockchipComponent->pRockchipPort[OUTPUT_PORT_INDEX];
770 nBufferSize = pOutputRockchipPort->portDefinition.nBufferSize;
771
772 if (!Rockchip_OSAL_GetEnvU32("sys.video.maxMemCapacity", &nValue, 0) && (nValue > 0)) {
773 omx_info("use low memory mode, set low mem : %d MB", nValue);
774 nTotalMemSize = nValue * 1024 * 1024;
775 nLowMemMode = OMX_TRUE;
776 }
777
778 if (nLowMemMode) {
779 pInputRockchipPort->portDefinition.nBufferCountActual = 3;
780 pInputRockchipPort->portDefinition.nBufferCountMin = 3;
781 #ifdef AVS80
782 pVideoDec->nMinUnDequeBufferCount = 3;
783 #else
784 pVideoDec->nMinUnDequeBufferCount = 4;
785 #endif
786 } else {
787 pInputRockchipPort->portDefinition.nBufferCountActual = MAX_VIDEO_INPUTBUFFER_NUM;
788 pInputRockchipPort->portDefinition.nBufferCountMin = MAX_VIDEO_INPUTBUFFER_NUM;
789 pVideoDec->nMinUnDequeBufferCount = 4;
790 }
791
792 if (BUFFER_COPY == pOutputRockchipPort->bufferProcessType) {
793 nMaxBufferCount = pInputRockchipPort->portDefinition.nBufferCountActual;
794 pVideoDec->nMinUnDequeBufferCount = 0;
795 } else {
796 OMX_BOOL isSecure = OMX_FALSE;
797 // for gts exo test
798 Rockchip_OSAL_Memset(pValue, 0, sizeof(pValue));
799 if (!Rockchip_OSAL_GetEnvStr("cts_gts.exo.gts", pValue, sizeof(pValue), nullptr) &&
800 !strcasecmp(pValue, "true")) {
801 omx_info("This is gts exo test. pValue: %s", pValue);
802 nRefFrameNum = 7;
803 } else {
804 nRefFrameNum = Rockchip_OSAL_CalculateTotalRefFrames(
805 pVideoDec->codecId,
806 pInputRockchipPort->portDefinition.format.video.nFrameWidth,
807 pInputRockchipPort->portDefinition.format.video.nFrameHeight,
808 isSecure);
809 }
810 if (pVideoDec->nDpbSize > 0) {
811 nRefFrameNum = pVideoDec->nDpbSize;
812 }
813 if ((pInputRockchipPort->portDefinition.format.video.nFrameWidth
814 * pInputRockchipPort->portDefinition.format.video.nFrameHeight > 1920 * 1088)
815 || isSecure || access("/dev/iep", F_OK) == -1) {
816 nMaxBufferCount = nRefFrameNum + pVideoDec->nMinUnDequeBufferCount + 1;
817 } else {
818 /* if width * height < 2304 * 1088, need consider IEP */
819 nMaxBufferCount = nRefFrameNum + pVideoDec->nMinUnDequeBufferCount + 1 + DEFAULT_IEP_OUTPUT_BUFFER_COUNT;
820 }
821
822 if (nLowMemMode) {
823 nMaxLowMemBufferCount = nTotalMemSize / nBufferSize;
824 if (nMaxLowMemBufferCount > 23) {
825 nMaxLowMemBufferCount = 23;
826 }
827 nMaxBufferCount = (nMaxLowMemBufferCount < nMaxBufferCount) ? nMaxLowMemBufferCount : nMaxBufferCount;
828 }
829 }
830
831 if (pOutputRockchipPort->portDefinition.nBufferCountActual < nMaxBufferCount)
832 pOutputRockchipPort->portDefinition.nBufferCountActual = nMaxBufferCount;
833 pOutputRockchipPort->portDefinition.nBufferCountMin = nMaxBufferCount - pVideoDec->nMinUnDequeBufferCount;
834
835 omx_info("input nBufferSize: %d, width: %d, height: %d, minBufferCount: %d, bufferCount: %d",
836 pInputRockchipPort->portDefinition.nBufferSize,
837 pInputRockchipPort->portDefinition.format.video.nFrameWidth,
838 pInputRockchipPort->portDefinition.format.video.nFrameHeight,
839 pInputRockchipPort->portDefinition.nBufferCountMin,
840 pInputRockchipPort->portDefinition.nBufferCountActual);
841
842 omx_info("output nBufferSize: %d, width: %d, height: %d, minBufferCount: %d, bufferCount: %d buffer type: %d",
843 pOutputRockchipPort->portDefinition.nBufferSize,
844 pOutputRockchipPort->portDefinition.format.video.nFrameWidth,
845 pOutputRockchipPort->portDefinition.format.video.nFrameHeight,
846 pOutputRockchipPort->portDefinition.nBufferCountMin,
847 pOutputRockchipPort->portDefinition.nBufferCountActual,
848 pOutputRockchipPort->bufferProcessType);
849
850 EXIT:
851 FunctionOut();
852
853 return ret;
854 }
855
856 OMX_U32 Rockchip_OSAL_CalculateTotalRefFrames(
857 OMX_VIDEO_CODINGTYPE codecId,
858 OMX_U32 width,
859 OMX_U32 height,
860 OMX_BOOL isSecure)
861 {
862 OMX_U32 nRefFramesNum = 0;
863 switch (codecId) {
864 case OMX_VIDEO_CodingAVC: {
865 /* used level 5.1 MaxDpbMbs */
866 nRefFramesNum = 184320 / ((width / 16) * (height / 16)); /* 184320:frame number,
867 16:frame number */
868 if (nRefFramesNum > 16) { // 16:frame number
869 /* max refs frame number is 16 */
870 nRefFramesNum = 16; // 16:frame number
871 } else if (nRefFramesNum < 6) { // 6:frame number
872 nRefFramesNum = 6; // 6:frame number
873 }
874 } break;
875 case CODEC_OMX_VIDEO_CodingHEVC: {
876 /* use 4K refs frame Num to computate others */
877 nRefFramesNum = 4096 * 2160 * 6 / (width * height); /* 4096:Resolution size,
878 2160:Resolution size, 6:frame number */
879 if (nRefFramesNum > 16) {
880 /* max refs frame number is 16 */
881 nRefFramesNum = 16;
882 } else if (nRefFramesNum < 6) {
883 /* min refs frame number is 6 */
884 nRefFramesNum = 6;
885 }
886 } break;
887 case CODEC_OMX_VIDEO_CodingVP9: {
888 nRefFramesNum = 4096 * 2176 * 4 / (width * height);/* 4096:Resolution size,
889 2176:Resolution size, 4:frame number */
890 if (nRefFramesNum > 8) { // 8:frame number
891 nRefFramesNum = 8; // 8:frame number
892 } else if (nRefFramesNum < 4) { // 4:frame number
893 nRefFramesNum = 4; // 4:frame number
894 }
895 } break;
896 default: {
897 nRefFramesNum = 8;
898 } break;
899 }
900
901 /*
902 * for SVP, Usually it is streaming video, and secure buffering
903 * is smaller, so buffer allocation is less.
904 */
905 if (isSecure && ((width * height) > 1280 * 768)) { /* 1280:Resolution size, 768:Resolution size */
906 nRefFramesNum = nRefFramesNum > 9 ? 9 : nRefFramesNum;
907 }
908
909 return nRefFramesNum;
910 }
911
912 #ifdef __cplusplus
913 }
914 #endif