Home | History | Annotate | Download | only in common
      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_OMX_Resourcemanager.c
     20  * @brief
     21  * @author     SeungBeom Kim (sbcrux.kim (at) samsung.com)
     22  * @version    1.0
     23  * @history
     24  *    2010.7.15 : Create
     25  */
     26 
     27 #include <stdio.h>
     28 #include <stdlib.h>
     29 #include <string.h>
     30 
     31 #include "SEC_OMX_Resourcemanager.h"
     32 #include "SEC_OMX_Basecomponent.h"
     33 
     34 #undef  SEC_LOG_TAG
     35 #define SEC_LOG_TAG    "SEC_RM"
     36 #define SEC_LOG_OFF
     37 #include "SEC_OSAL_Log.h"
     38 
     39 
     40 #define MAX_RESOURCE_VIDEO 4
     41 
     42 /* Max allowable video scheduler component instance */
     43 static SEC_OMX_RM_COMPONENT_LIST *gpVideoRMComponentList = NULL;
     44 static SEC_OMX_RM_COMPONENT_LIST *gpVideoRMWaitingList = NULL;
     45 static OMX_HANDLETYPE ghVideoRMComponentListMutex = NULL;
     46 
     47 
     48 OMX_ERRORTYPE addElementList(SEC_OMX_RM_COMPONENT_LIST **ppList, OMX_COMPONENTTYPE *pOMXComponent)
     49 {
     50     OMX_ERRORTYPE              ret = OMX_ErrorNone;
     51     SEC_OMX_RM_COMPONENT_LIST *pTempComp = NULL;
     52     SEC_OMX_BASECOMPONENT     *pSECComponent = NULL;
     53 
     54     pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
     55     if (*ppList != NULL) {
     56         pTempComp = *ppList;
     57         while (pTempComp->pNext != NULL) {
     58             pTempComp = pTempComp->pNext;
     59         }
     60         pTempComp->pNext = (SEC_OMX_RM_COMPONENT_LIST *)SEC_OSAL_Malloc(sizeof(SEC_OMX_RM_COMPONENT_LIST));
     61         if (pTempComp->pNext == NULL) {
     62             ret = OMX_ErrorInsufficientResources;
     63             goto EXIT;
     64         }
     65         ((SEC_OMX_RM_COMPONENT_LIST *)(pTempComp->pNext))->pNext = NULL;
     66         ((SEC_OMX_RM_COMPONENT_LIST *)(pTempComp->pNext))->pOMXStandComp = pOMXComponent;
     67         ((SEC_OMX_RM_COMPONENT_LIST *)(pTempComp->pNext))->groupPriority = pSECComponent->compPriority.nGroupPriority;
     68         goto EXIT;
     69     } else {
     70         *ppList = (SEC_OMX_RM_COMPONENT_LIST *)SEC_OSAL_Malloc(sizeof(SEC_OMX_RM_COMPONENT_LIST));
     71         if (*ppList == NULL) {
     72             ret = OMX_ErrorInsufficientResources;
     73             goto EXIT;
     74         }
     75         pTempComp = *ppList;
     76         pTempComp->pNext = NULL;
     77         pTempComp->pOMXStandComp = pOMXComponent;
     78         pTempComp->groupPriority = pSECComponent->compPriority.nGroupPriority;
     79     }
     80 
     81 EXIT:
     82     return ret;
     83 }
     84 
     85 OMX_ERRORTYPE removeElementList(SEC_OMX_RM_COMPONENT_LIST **ppList, OMX_COMPONENTTYPE *pOMXComponent)
     86 {
     87     OMX_ERRORTYPE              ret = OMX_ErrorNone;
     88     SEC_OMX_RM_COMPONENT_LIST *pCurrComp = NULL;
     89     SEC_OMX_RM_COMPONENT_LIST *pPrevComp = NULL;
     90     OMX_BOOL                   bDetectComp = OMX_FALSE;
     91 
     92     if (*ppList == NULL) {
     93         ret = OMX_ErrorUndefined;
     94         goto EXIT;
     95     }
     96 
     97     pCurrComp = *ppList;
     98     while (pCurrComp != NULL) {
     99         if (pCurrComp->pOMXStandComp == pOMXComponent) {
    100             if (*ppList == pCurrComp) {
    101                 *ppList = pCurrComp->pNext;
    102                 SEC_OSAL_Free(pCurrComp);
    103             } else {
    104                 pPrevComp->pNext = pCurrComp->pNext;
    105                 SEC_OSAL_Free(pCurrComp);
    106             }
    107             bDetectComp = OMX_TRUE;
    108             break;
    109         } else {
    110             pPrevComp = pCurrComp;
    111             pCurrComp = pCurrComp->pNext;
    112         }
    113     }
    114 
    115     if (bDetectComp == OMX_FALSE)
    116         ret = OMX_ErrorComponentNotFound;
    117     else
    118         ret = OMX_ErrorNone;
    119 
    120 EXIT:
    121     return ret;
    122 }
    123 
    124 int searchLowPriority(SEC_OMX_RM_COMPONENT_LIST *RMComp_list, int inComp_priority, SEC_OMX_RM_COMPONENT_LIST **outLowComp)
    125 {
    126     int ret = 0;
    127     SEC_OMX_RM_COMPONENT_LIST *pTempComp = NULL;
    128     SEC_OMX_RM_COMPONENT_LIST *pCandidateComp = NULL;
    129 
    130     if (RMComp_list == NULL)
    131         ret = -1;
    132 
    133     pTempComp = RMComp_list;
    134     *outLowComp = 0;
    135 
    136     while (pTempComp != NULL) {
    137         if (pTempComp->groupPriority > inComp_priority) {
    138             if (pCandidateComp != NULL) {
    139                 if (pCandidateComp->groupPriority < pTempComp->groupPriority)
    140                     pCandidateComp = pTempComp;
    141             } else {
    142                 pCandidateComp = pTempComp;
    143             }
    144         }
    145 
    146         pTempComp = pTempComp->pNext;
    147     }
    148 
    149     *outLowComp = pCandidateComp;
    150     if (pCandidateComp == NULL)
    151         ret = 0;
    152     else
    153         ret = 1;
    154 
    155 EXIT:
    156     return ret;
    157 }
    158 
    159 OMX_ERRORTYPE removeComponent(OMX_COMPONENTTYPE *pOMXComponent)
    160 {
    161     OMX_ERRORTYPE          ret = OMX_ErrorNone;
    162     SEC_OMX_BASECOMPONENT *pSECComponent = NULL;
    163 
    164     pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
    165     if (pSECComponent->currentState == OMX_StateIdle) {
    166         (*(pSECComponent->pCallbacks->EventHandler))
    167             (pOMXComponent, pSECComponent->callbackData,
    168             OMX_EventError, OMX_ErrorResourcesLost, 0, NULL);
    169         ret = OMX_SendCommand(pOMXComponent, OMX_CommandStateSet, OMX_StateLoaded, NULL);
    170         if (ret != OMX_ErrorNone) {
    171             ret = OMX_ErrorUndefined;
    172             goto EXIT;
    173         }
    174     } else if ((pSECComponent->currentState == OMX_StateExecuting) || (pSECComponent->currentState == OMX_StatePause)) {
    175         /* Todo */
    176     }
    177 
    178     ret = OMX_ErrorNone;
    179 
    180 EXIT:
    181     return ret;
    182 }
    183 
    184 
    185 OMX_ERRORTYPE SEC_OMX_ResourceManager_Init()
    186 {
    187     FunctionIn();
    188     SEC_OSAL_MutexCreate(&ghVideoRMComponentListMutex);
    189     FunctionOut();
    190     return OMX_ErrorNone;
    191 }
    192 
    193 OMX_ERRORTYPE SEC_OMX_ResourceManager_Deinit()
    194 {
    195     OMX_ERRORTYPE ret = OMX_ErrorNone;
    196     SEC_OMX_RM_COMPONENT_LIST *pCurrComponent;
    197     SEC_OMX_RM_COMPONENT_LIST *pNextComponent;
    198 
    199     FunctionIn();
    200 
    201     SEC_OSAL_MutexLock(ghVideoRMComponentListMutex);
    202 
    203     if (gpVideoRMComponentList) {
    204         pCurrComponent = gpVideoRMComponentList;
    205         while (pCurrComponent != NULL) {
    206             pNextComponent = pCurrComponent->pNext;
    207             SEC_OSAL_Free(pCurrComponent);
    208             pCurrComponent = pNextComponent;
    209         }
    210         gpVideoRMComponentList = NULL;
    211     }
    212 
    213     if (gpVideoRMWaitingList) {
    214         pCurrComponent = gpVideoRMWaitingList;
    215         while (pCurrComponent != NULL) {
    216             pNextComponent = pCurrComponent->pNext;
    217             SEC_OSAL_Free(pCurrComponent);
    218             pCurrComponent = pNextComponent;
    219         }
    220         gpVideoRMWaitingList = NULL;
    221     }
    222     SEC_OSAL_MutexUnlock(ghVideoRMComponentListMutex);
    223 
    224     SEC_OSAL_MutexTerminate(ghVideoRMComponentListMutex);
    225     ghVideoRMComponentListMutex = NULL;
    226 
    227     ret = OMX_ErrorNone;
    228 EXIT:
    229     FunctionOut();
    230 
    231     return ret;
    232 }
    233 
    234 OMX_ERRORTYPE SEC_OMX_Get_Resource(OMX_COMPONENTTYPE *pOMXComponent)
    235 {
    236     OMX_ERRORTYPE              ret = OMX_ErrorNone;
    237     SEC_OMX_BASECOMPONENT     *pSECComponent = NULL;
    238     SEC_OMX_RM_COMPONENT_LIST *pComponentTemp = NULL;
    239     SEC_OMX_RM_COMPONENT_LIST *pComponentCandidate = NULL;
    240     int numElem = 0;
    241     int lowCompDetect = 0;
    242 
    243     FunctionIn();
    244 
    245     SEC_OSAL_MutexLock(ghVideoRMComponentListMutex);
    246 
    247     pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
    248     pComponentTemp = gpVideoRMComponentList;
    249     if (pSECComponent->codecType == HW_VIDEO_CODEC) {
    250         if (pComponentTemp != NULL) {
    251             while (pComponentTemp) {
    252                 numElem++;
    253                 pComponentTemp = pComponentTemp->pNext;
    254             }
    255         } else {
    256             numElem = 0;
    257         }
    258         if (numElem >= MAX_RESOURCE_VIDEO) {
    259             lowCompDetect = searchLowPriority(gpVideoRMComponentList, pSECComponent->compPriority.nGroupPriority, &pComponentCandidate);
    260             if (lowCompDetect <= 0) {
    261                 ret = OMX_ErrorInsufficientResources;
    262                 goto EXIT;
    263             } else {
    264                 ret = removeComponent(pComponentCandidate->pOMXStandComp);
    265                 if (ret != OMX_ErrorNone) {
    266                     ret = OMX_ErrorInsufficientResources;
    267                     goto EXIT;
    268                 } else {
    269                     ret = removeElementList(&gpVideoRMComponentList, pComponentCandidate->pOMXStandComp);
    270                     ret = addElementList(&gpVideoRMComponentList, pOMXComponent);
    271                     if (ret != OMX_ErrorNone) {
    272                         ret = OMX_ErrorInsufficientResources;
    273                         goto EXIT;
    274                     }
    275                 }
    276             }
    277         } else {
    278             ret = addElementList(&gpVideoRMComponentList, pOMXComponent);
    279             if (ret != OMX_ErrorNone) {
    280                 ret = OMX_ErrorInsufficientResources;
    281                 goto EXIT;
    282             }
    283         }
    284     }
    285     ret = OMX_ErrorNone;
    286 
    287 EXIT:
    288 
    289     SEC_OSAL_MutexUnlock(ghVideoRMComponentListMutex);
    290 
    291     FunctionOut();
    292 
    293     return ret;
    294 }
    295 
    296 OMX_ERRORTYPE SEC_OMX_Release_Resource(OMX_COMPONENTTYPE *pOMXComponent)
    297 {
    298     OMX_ERRORTYPE              ret = OMX_ErrorNone;
    299     SEC_OMX_BASECOMPONENT     *pSECComponent = NULL;
    300     SEC_OMX_RM_COMPONENT_LIST *pComponentTemp = NULL;
    301     OMX_COMPONENTTYPE         *pOMXWaitComponent = NULL;
    302     int numElem = 0;
    303 
    304     FunctionIn();
    305 
    306     SEC_OSAL_MutexLock(ghVideoRMComponentListMutex);
    307 
    308     pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
    309     pComponentTemp = gpVideoRMWaitingList;
    310     if (pSECComponent->codecType == HW_VIDEO_CODEC) {
    311         if (gpVideoRMComponentList == NULL) {
    312             ret = OMX_ErrorUndefined;
    313             goto EXIT;
    314         }
    315 
    316         ret = removeElementList(&gpVideoRMComponentList, pOMXComponent);
    317         if (ret != OMX_ErrorNone) {
    318             ret = OMX_ErrorUndefined;
    319             goto EXIT;
    320         }
    321         while (pComponentTemp) {
    322             numElem++;
    323             pComponentTemp = pComponentTemp->pNext;
    324         }
    325         if (numElem > 0) {
    326             pOMXWaitComponent = gpVideoRMWaitingList->pOMXStandComp;
    327             removeElementList(&gpVideoRMWaitingList, pOMXWaitComponent);
    328             ret = OMX_SendCommand(pOMXWaitComponent, OMX_CommandStateSet, OMX_StateIdle, NULL);
    329             if (ret != OMX_ErrorNone) {
    330                 goto EXIT;
    331             }
    332         }
    333     }
    334 
    335 EXIT:
    336 
    337     SEC_OSAL_MutexUnlock(ghVideoRMComponentListMutex);
    338 
    339     FunctionOut();
    340 
    341     return ret;
    342 }
    343 
    344 OMX_ERRORTYPE SEC_OMX_In_WaitForResource(OMX_COMPONENTTYPE *pOMXComponent)
    345 {
    346     OMX_ERRORTYPE          ret = OMX_ErrorNone;
    347     SEC_OMX_BASECOMPONENT *pSECComponent = NULL;
    348 
    349     FunctionIn();
    350 
    351     SEC_OSAL_MutexLock(ghVideoRMComponentListMutex);
    352 
    353     pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
    354     if (pSECComponent->codecType == HW_VIDEO_CODEC)
    355         ret = addElementList(&gpVideoRMWaitingList, pOMXComponent);
    356 
    357     SEC_OSAL_MutexUnlock(ghVideoRMComponentListMutex);
    358 
    359     FunctionOut();
    360 
    361     return ret;
    362 }
    363 
    364 OMX_ERRORTYPE SEC_OMX_Out_WaitForResource(OMX_COMPONENTTYPE *pOMXComponent)
    365 {
    366     OMX_ERRORTYPE          ret = OMX_ErrorNone;
    367     SEC_OMX_BASECOMPONENT *pSECComponent = NULL;
    368 
    369     FunctionIn();
    370 
    371     SEC_OSAL_MutexLock(ghVideoRMComponentListMutex);
    372 
    373     pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
    374     if (pSECComponent->codecType == HW_VIDEO_CODEC)
    375         ret = removeElementList(&gpVideoRMWaitingList, pOMXComponent);
    376 
    377     SEC_OSAL_MutexUnlock(ghVideoRMComponentListMutex);
    378 
    379     FunctionOut();
    380 
    381     return ret;
    382 }
    383 
    384