1 /*
2 * Copyright (C) 2021 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)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)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)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
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
705 OMX_ERRORTYPE Rkvpu_ComputeDecBufferCount(
706 OMX_HANDLETYPE hComponent)
707 {
708 OMX_ERRORTYPE ret = OMX_ErrorNone;
709 OMX_COMPONENTTYPE *pOMXComponent = nullptr;
710 ROCKCHIP_OMX_BASECOMPONENT *pRockchipComponent = nullptr;
711 RKVPU_OMX_VIDEODEC_COMPONENT *pVideoDec = nullptr;
712 ROCKCHIP_OMX_BASEPORT *pInputRockchipPort = nullptr;
713 ROCKCHIP_OMX_BASEPORT *pOutputRockchipPort = nullptr;
714 OMX_U32 nValue = 0;
715 OMX_BOOL nLowMemMode = OMX_FALSE;
716 OMX_U32 nTotalMemSize = 0;
717 OMX_U32 nMaxBufferCount = 0;
718 OMX_U32 nMaxLowMemBufferCount = 0;
719 OMX_U32 nBufferSize = 0;
720 OMX_U32 nRefFrameNum = 0;
721
722 FunctionIn();
723
724 char pValue[128 + 1]; // 128:array length
725
726 if (hComponent == nullptr) {
727 omx_err("omx component is nullptr");
728 ret = OMX_ErrorBadParameter;
729 goto EXIT;
730 }
731 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
732 ret = Rockchip_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
733 if (ret != OMX_ErrorNone) {
734 omx_err("omx component version check failed!");
735 goto EXIT;
736 }
737
738 if (pOMXComponent->pComponentPrivate == nullptr) {
739 omx_err("omx component private is nullptr!");
740 ret = OMX_ErrorBadParameter;
741 goto EXIT;
742 }
743 pRockchipComponent = (ROCKCHIP_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
744
745 pVideoDec = (RKVPU_OMX_VIDEODEC_COMPONENT *)pRockchipComponent->hComponentHandle;
746 if (pVideoDec == nullptr) {
747 omx_err("video decode component is nullptr!");
748 ret = OMX_ErrorBadParameter;
749 goto EXIT;
750 }
751
752 if (pRockchipComponent->currentState == OMX_StateInvalid) {
753 omx_err("current state is invalid!");
754 ret = OMX_ErrorInvalidState;
755 goto EXIT;
756 }
757
758 pInputRockchipPort = &pRockchipComponent->pRockchipPort[INPUT_PORT_INDEX];
759 pOutputRockchipPort = &pRockchipComponent->pRockchipPort[OUTPUT_PORT_INDEX];
760 nBufferSize = pOutputRockchipPort->portDefinition.nBufferSize;
761
762 if (!Rockchip_OSAL_GetEnvU32("sys.video.maxMemCapacity", &nValue, 0) && (nValue > 0)) {
763 omx_info("use low memory mode, set low mem : %d MB", nValue);
764 nTotalMemSize = nValue * 1024 * 1024;
765 nLowMemMode = OMX_TRUE;
766 }
767
768 if (nLowMemMode) {
769 pInputRockchipPort->portDefinition.nBufferCountActual = 3;
770 pInputRockchipPort->portDefinition.nBufferCountMin = 3;
771 #ifdef AVS80
772 pVideoDec->nMinUnDequeBufferCount = 3;
773 #else
774 pVideoDec->nMinUnDequeBufferCount = 4;
775 #endif
776 } else {
777 pInputRockchipPort->portDefinition.nBufferCountActual = MAX_VIDEO_INPUTBUFFER_NUM;
778 pInputRockchipPort->portDefinition.nBufferCountMin = MAX_VIDEO_INPUTBUFFER_NUM;
779 pVideoDec->nMinUnDequeBufferCount = 4;
780 }
781
782 if (BUFFER_COPY == pOutputRockchipPort->bufferProcessType) {
783 nMaxBufferCount = pInputRockchipPort->portDefinition.nBufferCountActual;
784 pVideoDec->nMinUnDequeBufferCount = 0;
785 } else {
786 OMX_BOOL isSecure = OMX_FALSE;
787 // for gts exo test
788 Rockchip_OSAL_Memset(pValue, 0, sizeof(pValue));
789 if (!Rockchip_OSAL_GetEnvStr("cts_gts.exo.gts", pValue, nullptr) && !strcasecmp(pValue, "true")) {
790 omx_info("This is gts exo test. pValue: %s", pValue);
791 nRefFrameNum = 7;
792 } else {
793 nRefFrameNum = Rockchip_OSAL_CalculateTotalRefFrames(
794 pVideoDec->codecId,
795 pInputRockchipPort->portDefinition.format.video.nFrameWidth,
796 pInputRockchipPort->portDefinition.format.video.nFrameHeight,
797 isSecure);
798 }
799 if (pVideoDec->nDpbSize > 0) {
800 nRefFrameNum = pVideoDec->nDpbSize;
801 }
802 if ((pInputRockchipPort->portDefinition.format.video.nFrameWidth
803 * pInputRockchipPort->portDefinition.format.video.nFrameHeight > 1920 * 1088)
804 || isSecure || access("/dev/iep", F_OK) == -1) {
805 nMaxBufferCount = nRefFrameNum + pVideoDec->nMinUnDequeBufferCount + 1;
806 } else {
807 /* if width * height < 2304 * 1088, need consider IEP */
808 nMaxBufferCount = nRefFrameNum + pVideoDec->nMinUnDequeBufferCount + 1 + DEFAULT_IEP_OUTPUT_BUFFER_COUNT;
809 }
810
811 if (nLowMemMode) {
812 nMaxLowMemBufferCount = nTotalMemSize / nBufferSize;
813 if (nMaxLowMemBufferCount > 23) {
814 nMaxLowMemBufferCount = 23;
815 }
816 nMaxBufferCount = (nMaxLowMemBufferCount < nMaxBufferCount) ? nMaxLowMemBufferCount : nMaxBufferCount;
817 }
818 }
819
820 if (pOutputRockchipPort->portDefinition.nBufferCountActual < nMaxBufferCount)
821 pOutputRockchipPort->portDefinition.nBufferCountActual = nMaxBufferCount;
822 pOutputRockchipPort->portDefinition.nBufferCountMin = nMaxBufferCount - pVideoDec->nMinUnDequeBufferCount;
823
824 omx_info("input nBufferSize: %d, width: %d, height: %d, minBufferCount: %d, bufferCount: %d",
825 pInputRockchipPort->portDefinition.nBufferSize,
826 pInputRockchipPort->portDefinition.format.video.nFrameWidth,
827 pInputRockchipPort->portDefinition.format.video.nFrameHeight,
828 pInputRockchipPort->portDefinition.nBufferCountMin,
829 pInputRockchipPort->portDefinition.nBufferCountActual);
830
831 omx_info("output nBufferSize: %d, width: %d, height: %d, minBufferCount: %d, bufferCount: %d buffer type: %d",
832 pOutputRockchipPort->portDefinition.nBufferSize,
833 pOutputRockchipPort->portDefinition.format.video.nFrameWidth,
834 pOutputRockchipPort->portDefinition.format.video.nFrameHeight,
835 pOutputRockchipPort->portDefinition.nBufferCountMin,
836 pOutputRockchipPort->portDefinition.nBufferCountActual,
837 pOutputRockchipPort->bufferProcessType);
838
839 EXIT:
840 FunctionOut();
841
842 return ret;
843 }
844
845 OMX_U32 Rockchip_OSAL_CalculateTotalRefFrames(
846 OMX_VIDEO_CODINGTYPE codecId,
847 OMX_U32 width,
848 OMX_U32 height,
849 OMX_BOOL isSecure)
850 {
851 OMX_U32 nRefFramesNum = 0;
852 switch (codecId) {
853 case OMX_VIDEO_CodingAVC: {
854 /* used level 5.1 MaxDpbMbs */
855 nRefFramesNum = 184320 / ((width / 16) * (height / 16)); /* 184320:frame number,
856 16:frame number */
857 if (nRefFramesNum > 16) { // 16:frame number
858 /* max refs frame number is 16 */
859 nRefFramesNum = 16; // 16:frame number
860 } else if (nRefFramesNum < 6) { // 6:frame number
861 nRefFramesNum = 6; // 6:frame number
862 }
863 } break;
864 case CODEC_OMX_VIDEO_CodingHEVC: {
865 /* use 4K refs frame Num to computate others */
866 nRefFramesNum = 4096 * 2160 * 6 / (width * height); /* 4096:Resolution size,
867 2160:Resolution size, 6:frame number */
868 if (nRefFramesNum > 16) {
869 /* max refs frame number is 16 */
870 nRefFramesNum = 16;
871 } else if (nRefFramesNum < 6) {
872 /* min refs frame number is 6 */
873 nRefFramesNum = 6;
874 }
875 } break;
876 case OMX_VIDEO_CodingVP9: {
877 nRefFramesNum = 4096 * 2176 * 4 / (width * height);/* 4096:Resolution size,
878 2176:Resolution size, 4:frame number */
879 if (nRefFramesNum > 8) { // 8:frame number
880 nRefFramesNum = 8; // 8:frame number
881 } else if (nRefFramesNum < 4) { // 4:frame number
882 nRefFramesNum = 4; // 4:frame number
883 }
884 } break;
885 default: {
886 nRefFramesNum = 8;
887 } break;
888 }
889
890 /*
891 * for SVP, Usually it is streaming video, and secure buffering
892 * is smaller, so buffer allocation is less.
893 */
894 if (isSecure && ((width * height) > 1280 * 768)) { /* 1280:Resolution size, 768:Resolution size */
895 nRefFramesNum = nRefFramesNum > 9 ? 9 : nRefFramesNum;
896 }
897
898 return nRefFramesNum;
899 }
900
901 #ifdef __cplusplus
902 }
903 #endif