Home | History | Annotate | Download | only in sec_osal
      1 /*
      2  *
      3  * Copyright 2010 Samsung Electronics S.LSI Co. LTD
      4  *
      5  * Licensed under the Apache License, Version 2.0 (the "License");
      6  * you may not use this file except in compliance with the License.
      7  * You may obtain a copy of the License at
      8  *
      9  *      http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  */
     17 
     18 /*
     19  * @file        SEC_OSAL_Buffer.c
     20  * @brief
     21  * @author      SeungBeom Kim (sbcrux.kim (at) samsung.com)
     22  *              Jinsung Yang (jsgood.yang (at) samsung.com)
     23  * @version     1.0.2
     24  * @history
     25  *   2011.5.15 : Create
     26  */
     27 
     28 #ifdef __cplusplus
     29 extern "C" {
     30 #endif
     31 
     32 #include <stdio.h>
     33 #include <stdlib.h>
     34 #include <string.h>
     35 
     36 #include "SEC_OMX_Def.h"
     37 #include "SEC_OMX_Macros.h"
     38 #include "SEC_OSAL_Memory.h"
     39 #include "SEC_OSAL_Semaphore.h"
     40 #include "SEC_OSAL_Buffer.h"
     41 #include "SEC_OMX_Basecomponent.h"
     42 
     43 #define SEC_LOG_OFF
     44 #include "SEC_OSAL_Log.h"
     45 
     46 #ifdef __cplusplus
     47 }
     48 #endif
     49 
     50 #include <ui/GraphicBuffer.h>
     51 #include <ui/GraphicBufferMapper.h>
     52 #include <ui/Rect.h>
     53 #include <HardwareAPI.h>
     54 #include <hardware/hardware.h>
     55 #include <MetadataBufferType.h>
     56 #include "hal_public.h"
     57 
     58 #define HAL_PIXEL_FORMAT_C110_NV12          0x100
     59 
     60 using namespace android;
     61 
     62 
     63 struct AndroidNativeBuffersParams {
     64     OMX_U32 nSize;
     65     OMX_VERSIONTYPE nVersion;
     66     OMX_U32 nPortIndex;
     67 };
     68 
     69 #ifdef USE_ANDROID_EXTENSION
     70 OMX_ERRORTYPE checkVersionANB(OMX_PTR ComponentParameterStructure)
     71 {
     72     OMX_ERRORTYPE ret = OMX_ErrorNone;
     73     OMX_VERSIONTYPE* version = NULL;
     74 
     75 
     76     AndroidNativeBuffersParams *pANBP;
     77     pANBP = (AndroidNativeBuffersParams *)ComponentParameterStructure;
     78 
     79     version = (OMX_VERSIONTYPE*)((char*)pANBP + sizeof(OMX_U32));
     80     if (*((OMX_U32*)pANBP) <= sizeof(AndroidNativeBuffersParams)) {
     81         ret = OMX_ErrorBadParameter;
     82         goto EXIT;
     83     }
     84     if (version->s.nVersionMajor != VERSIONMAJOR_NUMBER ||
     85         version->s.nVersionMinor != VERSIONMINOR_NUMBER) {
     86         ret = OMX_ErrorVersionMismatch;
     87         goto EXIT;
     88     }
     89 
     90     ret = OMX_ErrorNone;
     91 
     92 EXIT:
     93     return ret;
     94 }
     95 
     96 OMX_U32 checkPortIndexANB(OMX_PTR ComponentParameterStructure)
     97 {
     98     AndroidNativeBuffersParams *pANBP;
     99     pANBP = (AndroidNativeBuffersParams *)ComponentParameterStructure;
    100 
    101     return pANBP->nPortIndex;
    102 }
    103 
    104 OMX_U32 getMetadataBufferType(const uint8_t *ptr)
    105 {
    106     OMX_U32 type = *(OMX_U32 *) ptr;
    107     SEC_OSAL_Log(SEC_LOG_TRACE, "getMetadataBufferType: %ld", type);
    108     return type;
    109 }
    110 
    111 OMX_U32 getVADDRfromANB(OMX_PTR pUnreadableBuffer, OMX_U32 Width, OMX_U32 Height, void *pVirAddrs[])
    112 {
    113     OMX_U32 ret = 0;
    114     android_native_buffer_t *buf;
    115     void *readableBuffer;
    116     GraphicBufferMapper &mapper = GraphicBufferMapper::get();
    117     Rect bounds(Width, Height);
    118 
    119     FunctionIn();
    120 
    121     buf = (android_native_buffer_t *)pUnreadableBuffer;
    122     SEC_OSAL_Log(SEC_LOG_TRACE, "pUnreadableBuffer:0x%x, buf:0x%x, buf->handle:0x%x",
    123                                 pUnreadableBuffer, buf, buf->handle);
    124 
    125     ret = mapper.lock(buf->handle, GRALLOC_USAGE_SW_WRITE_OFTEN, bounds, pVirAddrs);
    126     if (ret != 0) {
    127         SEC_OSAL_Log(SEC_LOG_ERROR, "mapper.lock Error, Error code:%d", ret);
    128     }
    129     FunctionOut();
    130 
    131     return ret;
    132 }
    133 
    134 OMX_U32 putVADDRtoANB(OMX_PTR pUnreadableBuffer)
    135 {
    136     android_native_buffer_t *buf;
    137     void *readableBuffer;
    138     int ret = 0;
    139     GraphicBufferMapper &mapper = GraphicBufferMapper::get();
    140 
    141     FunctionIn();
    142 
    143     buf = (android_native_buffer_t *)pUnreadableBuffer;
    144 
    145     FunctionOut();
    146 
    147     return mapper.unlock(buf->handle);
    148 }
    149 
    150 OMX_ERRORTYPE enableAndroidNativeBuffer(OMX_HANDLETYPE hComponent, OMX_PTR ComponentParameterStructure)
    151 {
    152     OMX_ERRORTYPE          ret = OMX_ErrorNone;
    153     OMX_COMPONENTTYPE     *pOMXComponent = NULL;
    154     SEC_OMX_BASECOMPONENT *pSECComponent = NULL;
    155     SEC_OMX_BASEPORT      *pSECPort = NULL;
    156 
    157     EnableAndroidNativeBuffersParams *peanbp;
    158 
    159     FunctionIn();
    160 
    161     if (hComponent == NULL) {
    162         ret = OMX_ErrorBadParameter;
    163         goto EXIT;
    164     }
    165     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
    166     if (pOMXComponent->pComponentPrivate == NULL) {
    167         ret = OMX_ErrorBadParameter;
    168         goto EXIT;
    169     }
    170     pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
    171     peanbp = (EnableAndroidNativeBuffersParams *)ComponentParameterStructure;
    172     pSECPort = &pSECComponent->pSECPort[peanbp->nPortIndex];
    173 
    174     if (peanbp->enable == OMX_FALSE) {
    175         SEC_OSAL_Log(SEC_LOG_TRACE, "disable AndroidNativeBuffer");
    176         pSECPort->bUseAndroidNativeBuffer = OMX_FALSE;
    177     } else {
    178         SEC_OSAL_Log(SEC_LOG_TRACE, "enable AndroidNativeBuffer");
    179         pSECPort->bUseAndroidNativeBuffer = OMX_TRUE;
    180         pSECPort->portDefinition.format.video.eColorFormat = (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatANBYUV420SemiPlanar;
    181     }
    182 
    183     ret = OMX_ErrorNone;
    184 
    185 EXIT:
    186     FunctionOut();
    187 
    188     return ret;
    189 }
    190 
    191 OMX_ERRORTYPE getAndroidNativeBuffer(OMX_HANDLETYPE hComponent, OMX_PTR ComponentParameterStructure)
    192 {
    193     OMX_ERRORTYPE          ret = OMX_ErrorNone;
    194     OMX_COMPONENTTYPE     *pOMXComponent = NULL;
    195     SEC_OMX_BASECOMPONENT *pSECComponent = NULL;
    196     SEC_OMX_BASEPORT      *pSECPort = NULL;
    197 
    198     GetAndroidNativeBufferUsageParams *pganbp;
    199 
    200     FunctionIn();
    201 
    202     pganbp = (GetAndroidNativeBufferUsageParams *)ComponentParameterStructure;
    203 
    204     pganbp->nUsage = GRALLOC_USAGE_SW_WRITE_OFTEN;
    205 
    206     ret = OMX_ErrorNone;
    207 
    208 EXIT:
    209     FunctionOut();
    210 
    211     return ret;
    212 }
    213 
    214 OMX_ERRORTYPE UseBufferANB(
    215     OMX_IN OMX_HANDLETYPE            hComponent,
    216     OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr,
    217     OMX_IN OMX_U32                   nPortIndex,
    218     OMX_IN OMX_PTR                   pAppPrivate,
    219     OMX_IN OMX_U32                   nSizeBytes,
    220     OMX_IN OMX_U8                   *pBuffer)
    221 {
    222     OMX_ERRORTYPE          ret = OMX_ErrorNone;
    223     OMX_COMPONENTTYPE     *pOMXComponent = NULL;
    224     SEC_OMX_BASECOMPONENT *pSECComponent = NULL;
    225     SEC_OMX_BASEPORT      *pSECPort = NULL;
    226     OMX_BUFFERHEADERTYPE  *temp_bufferHeader = NULL;
    227     int                    i = 0;
    228 
    229     FunctionIn();
    230 
    231     if (hComponent == NULL) {
    232         ret = OMX_ErrorBadParameter;
    233         goto EXIT;
    234     }
    235     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
    236     if (pOMXComponent->pComponentPrivate == NULL) {
    237         ret = OMX_ErrorBadParameter;
    238         goto EXIT;
    239     }
    240     pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
    241 
    242     pSECPort = &pSECComponent->pSECPort[nPortIndex];
    243     if (nPortIndex >= pSECComponent->portParam.nPorts) {
    244         ret = OMX_ErrorBadPortIndex;
    245         goto EXIT;
    246     }
    247     if (pSECPort->portState != OMX_StateIdle) {
    248         ret = OMX_ErrorIncorrectStateOperation;
    249         goto EXIT;
    250     }
    251 
    252     if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) {
    253         ret = OMX_ErrorBadPortIndex;
    254         goto EXIT;
    255     }
    256 
    257     temp_bufferHeader = (OMX_BUFFERHEADERTYPE *)SEC_OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE));
    258     if (temp_bufferHeader == NULL) {
    259         ret = OMX_ErrorInsufficientResources;
    260         goto EXIT;
    261     }
    262     SEC_OSAL_Memset(temp_bufferHeader, 0, sizeof(OMX_BUFFERHEADERTYPE));
    263 
    264     for (i = 0; i < pSECPort->portDefinition.nBufferCountActual; i++) {
    265         if (pSECPort->bufferStateAllocate[i] == BUFFER_STATE_FREE) {
    266             pSECPort->bufferHeader[i] = temp_bufferHeader;
    267             pSECPort->bufferStateAllocate[i] = (BUFFER_STATE_ASSIGNED | HEADER_STATE_ALLOCATED);
    268             INIT_SET_SIZE_VERSION(temp_bufferHeader, OMX_BUFFERHEADERTYPE);
    269             temp_bufferHeader->pBuffer        = pBuffer;
    270             temp_bufferHeader->nAllocLen      = nSizeBytes;
    271             temp_bufferHeader->pAppPrivate    = pAppPrivate;
    272             if (nPortIndex == INPUT_PORT_INDEX)
    273                 temp_bufferHeader->nInputPortIndex = INPUT_PORT_INDEX;
    274             else
    275                 temp_bufferHeader->nOutputPortIndex = OUTPUT_PORT_INDEX;
    276 
    277             pSECPort->assignedBufferNum++;
    278             if (pSECPort->assignedBufferNum == pSECPort->portDefinition.nBufferCountActual) {
    279                 pSECPort->portDefinition.bPopulated = OMX_TRUE;
    280                 /* SEC_OSAL_MutexLock(pSECComponent->compMutex); */
    281                 SEC_OSAL_SemaphorePost(pSECPort->loadedResource);
    282                 /* SEC_OSAL_MutexUnlock(pSECComponent->compMutex); */
    283             }
    284             *ppBufferHdr = temp_bufferHeader;
    285             ret = OMX_ErrorNone;
    286             goto EXIT;
    287         }
    288     }
    289 
    290     SEC_OSAL_Free(temp_bufferHeader);
    291     ret = OMX_ErrorInsufficientResources;
    292 
    293 EXIT:
    294     FunctionOut();
    295 
    296     return ret;
    297 }
    298 
    299 OMX_ERRORTYPE useAndroidNativeBuffer(OMX_HANDLETYPE hComponent, OMX_PTR ComponentParameterStructure)
    300 {
    301     OMX_ERRORTYPE          ret = OMX_ErrorNone;
    302     OMX_COMPONENTTYPE     *pOMXComponent = NULL;
    303     SEC_OMX_BASECOMPONENT *pSECComponent = NULL;
    304     SEC_OMX_BASEPORT      *pSECPort = NULL;
    305     OMX_U32                frameSize = 0;
    306     OMX_U32                bufWidth, bufHeight;
    307     UseAndroidNativeBufferParams *puanbp;
    308 
    309     FunctionIn();
    310 
    311     puanbp = (UseAndroidNativeBufferParams *)ComponentParameterStructure;
    312 
    313     OMX_PTR buffer = (void *)puanbp->nativeBuffer.get();
    314     android_native_buffer_t *buf = (android_native_buffer_t *)buffer;
    315     bufWidth = ((buf->width + 15) / 16) * 16;
    316     bufHeight = ((buf->height + 15) / 16) * 16;
    317     frameSize = (bufWidth * bufHeight * 3) / 2;
    318     SEC_OSAL_Log(SEC_LOG_TRACE, "buffer:0x%x, buf:0x%x, buf->handle:0x%x", buffer, buf, buf->handle);
    319 
    320     ret = UseBufferANB(hComponent, puanbp->bufferHeader, puanbp->nPortIndex,
    321                        puanbp->pAppPrivate, frameSize, (OMX_U8 *)buffer);
    322 
    323 EXIT:
    324     FunctionOut();
    325 
    326     return ret;
    327 }
    328 
    329 OMX_ERRORTYPE enableStoreMetaDataInBuffers(OMX_HANDLETYPE hComponent, OMX_PTR ComponentParameterStructure)
    330 {
    331     OMX_ERRORTYPE          ret = OMX_ErrorNone;
    332     OMX_COMPONENTTYPE     *pOMXComponent = NULL;
    333     SEC_OMX_BASECOMPONENT *pSECComponent = NULL;
    334     SEC_OMX_BASEPORT      *pSECPort = NULL;
    335 
    336     StoreMetaDataInBuffersParams *pStoreMetaData;
    337 
    338     FunctionIn();
    339 
    340     if (hComponent == NULL) {
    341         ret = OMX_ErrorBadParameter;
    342         goto EXIT;
    343     }
    344     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
    345     if (pOMXComponent->pComponentPrivate == NULL) {
    346         ret = OMX_ErrorBadParameter;
    347         goto EXIT;
    348     }
    349     pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
    350     pStoreMetaData = (StoreMetaDataInBuffersParams*)ComponentParameterStructure;
    351     pSECPort = &pSECComponent->pSECPort[pStoreMetaData->nPortIndex];
    352 
    353     if (pStoreMetaData->bStoreMetaData == OMX_FALSE) {
    354         SEC_OSAL_Log(SEC_LOG_TRACE, "disable StoreMetaDataInBuffers");
    355         pSECPort->bStoreMetaDataInBuffer = OMX_FALSE;
    356     } else {
    357         SEC_OSAL_Log(SEC_LOG_TRACE, "enable StoreMetaDataInBuffers");
    358         pSECPort->bStoreMetaDataInBuffer = OMX_TRUE;
    359     }
    360 
    361 EXIT:
    362     FunctionOut();
    363 
    364     return ret;
    365 }
    366 
    367 OMX_BOOL isMetadataBufferTypeGrallocSource(OMX_BYTE pInputDataBuffer)
    368 {
    369     OMX_U32 type = getMetadataBufferType(pInputDataBuffer);
    370 
    371     if (type == kMetadataBufferTypeGrallocSource)
    372         return OMX_TRUE;
    373     else
    374         return OMX_FALSE;
    375 }
    376 
    377 OMX_ERRORTYPE preprocessMetaDataInBuffers(OMX_HANDLETYPE hComponent, OMX_BYTE pInputDataBuffer, BUFFER_ADDRESS_INFO *pInputInfo)
    378 {
    379     OMX_ERRORTYPE          ret = OMX_ErrorNone;
    380     OMX_COMPONENTTYPE     *pOMXComponent = NULL;
    381     SEC_OMX_BASECOMPONENT *pSECComponent = NULL;
    382     SEC_OMX_BASEPORT      *pSECPort = NULL;
    383     OMX_U32                type = 0;
    384 
    385     FunctionIn();
    386 
    387     if (hComponent == NULL) {
    388         ret = OMX_ErrorBadParameter;
    389         goto EXIT;
    390     }
    391     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
    392     if (pOMXComponent->pComponentPrivate == NULL) {
    393         ret = OMX_ErrorBadParameter;
    394         goto EXIT;
    395     }
    396     pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
    397     pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX];
    398 
    399     type = getMetadataBufferType(pInputDataBuffer);
    400     if (type == kMetadataBufferTypeCameraSource) {
    401         SEC_OSAL_Memcpy(&pInputInfo->YPhyAddr, pInputDataBuffer + 4, sizeof(void *));
    402         SEC_OSAL_Memcpy(&pInputInfo->CPhyAddr, pInputDataBuffer + 4 + sizeof(void *), sizeof(void *));
    403     } else if (type == kMetadataBufferTypeGrallocSource){
    404         IMG_gralloc_module_public_t *module = (IMG_gralloc_module_public_t *)pSECPort->pIMGGrallocModule;
    405         OMX_PTR pUnreadableBuffer = NULL;
    406         OMX_PTR pReadableBuffer = NULL;
    407         OMX_PTR pVirAddrs[3];
    408         int err = 0;
    409 
    410         pVirAddrs[0] = pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.YVirAddr;
    411         pVirAddrs[1] = pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.CVirAddr;
    412         pVirAddrs[2] = NULL;
    413 
    414         if (module == NULL) {
    415             err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t **)&module);
    416             if(err) {
    417                 SEC_OSAL_Log(SEC_LOG_ERROR, "hw_get_module failed (err=%d)\n", err);
    418                 ret = OMX_ErrorUndefined;
    419                 goto EXIT;
    420             }
    421             pSECPort->pIMGGrallocModule = (OMX_PTR)module;
    422         }
    423 
    424         /**************************************/
    425         /*     IMG CSC RGB to NV12            */
    426         /**************************************/
    427         buffer_handle_t buf = *((buffer_handle_t *) (pInputDataBuffer + 4));
    428         SEC_OSAL_Log(SEC_LOG_TRACE, "buffer handle %p)\n", buf);
    429         err = module->Blit(module, buf, pVirAddrs, HAL_PIXEL_FORMAT_C110_NV12);
    430         if(err) {
    431             SEC_OSAL_Log(SEC_LOG_ERROR, "module->Blit() failed (err=%d)\n", err);
    432             ret = OMX_ErrorUndefined;
    433             goto EXIT;
    434         }
    435 
    436         pInputInfo->YPhyAddr = pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.YPhyAddr;
    437         pInputInfo->CPhyAddr = pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.CPhyAddr;
    438     } else {
    439         ret = OMX_ErrorNotImplemented;
    440         goto EXIT;
    441     }
    442 
    443 EXIT:
    444     FunctionOut();
    445 
    446     return ret;
    447 }
    448 
    449 #endif
    450