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