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