OpenMAXBellagio 0.9.3
omx_reference_resource_manager.c
Go to the documentation of this file.
00001 
00028 #include <string.h>
00029 #include "omx_reference_resource_manager.h"
00030 #include "base/omx_base_component.h"
00031 #include "queue.h"
00032 
00036 static int globalTimestamp = 0;
00037 
00042 OMX_ERRORTYPE RM_Init() {
00043     int i;
00044     DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00045     globalIndex = 0;
00046     listOfcomponentRegistered = calloc(1, sizeof(struct NameIndexType) * MAX_COMPONENTS_TYPES_HANDLED);
00047     for (i = 0; i<MAX_COMPONENTS_TYPES_HANDLED; i++) {
00048         listOfcomponentRegistered[i].index = -1;
00049         listOfcomponentRegistered[i].component_name = NULL;
00050     }
00051     globalComponentList = malloc(sizeof(ComponentListType*) * MAX_COMPONENTS_TYPES_HANDLED);
00052     globalWaitingComponentList = malloc(sizeof(ComponentListType*) * MAX_COMPONENTS_TYPES_HANDLED);
00053     memset(globalComponentList, '\0', sizeof(ComponentListType*) * MAX_COMPONENTS_TYPES_HANDLED);
00054     memset(globalWaitingComponentList, '\0', sizeof(ComponentListType*) * MAX_COMPONENTS_TYPES_HANDLED);
00055     DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s\n", __func__);
00056     return OMX_ErrorNone;
00057 }
00058 
00062 OMX_ERRORTYPE RM_RegisterComponent(char *name, int max_components) {
00063     int i = 0;
00064     DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00065     while (listOfcomponentRegistered[i].component_name != NULL) {
00066         if (!strcmp(listOfcomponentRegistered[i].component_name, name)) {
00067             DEBUG(DEB_LEV_FUNCTION_NAME, "In %s component already registered\n", __func__);
00068             return OMX_ErrorNone;
00069         }
00070         i++;
00071     }
00072     listOfcomponentRegistered[i].component_name = calloc(1, OMX_MAX_STRINGNAME_SIZE);
00073     if (listOfcomponentRegistered[i].component_name == NULL) {
00074         return OMX_ErrorInsufficientResources;
00075     }
00076     strcpy(listOfcomponentRegistered[i].component_name, name);
00077     listOfcomponentRegistered[i].component_name[strlen(name)] = '\0';
00078     listOfcomponentRegistered[i].index = globalIndex;
00079     listOfcomponentRegistered[i].max_components = max_components;
00080     globalIndex++;
00081     DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s\n", __func__);
00082     return OMX_ErrorNone;
00083 }
00084 
00093 OMX_ERRORTYPE RM_Deinit() {
00094     int i = 0;
00095     DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00096     while(globalComponentList[i] != NULL) {
00097         clearList(&globalComponentList[i]);
00098         clearList(&globalWaitingComponentList[i]);
00099         i++;
00100     }
00101     DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s\n", __func__);
00102     return OMX_ErrorNone;
00103 }
00104 
00109 OMX_ERRORTYPE addElemToList(ComponentListType **list, OMX_COMPONENTTYPE *openmaxStandComp, int index, OMX_BOOL bIsWaiting) {
00110     ComponentListType *componentTemp;
00111     ComponentListType *componentNext;
00112     omx_base_component_PrivateType* omx_base_component_Private;
00113     DEBUG(DEB_LEV_FUNCTION_NAME, "In %s is waiting %i\n", __func__, bIsWaiting);
00114     omx_base_component_Private = (omx_base_component_PrivateType*)openmaxStandComp->pComponentPrivate;
00115     if (!*list) {
00116         *list = malloc(sizeof(ComponentListType));
00117         if (!bIsWaiting) {
00118             globalComponentList[index] = *list;
00119         } else {
00120             globalWaitingComponentList[index] = *list;
00121         }
00122         if (!*list) {
00123             DEBUG(DEB_LEV_ERR, "In %s OMX_ErrorInsufficientResources\n", __func__);
00124             return OMX_ErrorInsufficientResources;
00125         }
00126         (*list)->openmaxStandComp = openmaxStandComp;
00127         (*list)->timestamp = globalTimestamp;
00128         globalTimestamp++;
00129         (*list)->nGroupPriority = omx_base_component_Private->nGroupPriority;
00130         (*list)->next = NULL;
00131         DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s\n", __func__);
00132         return OMX_ErrorNone;
00133     }
00134     componentTemp = *list;
00135     while(componentTemp->next) {
00136         componentTemp = componentTemp->next;
00137     }
00138     componentNext = malloc(sizeof(ComponentListType));
00139     if (!componentNext) {
00140         DEBUG(DEB_LEV_ERR, "In %s OMX_ErrorInsufficientResources\n", __func__);
00141         return OMX_ErrorInsufficientResources;
00142     }
00143     componentTemp->next = componentNext;
00144     componentNext->next = NULL;
00145     componentNext->openmaxStandComp = openmaxStandComp;
00146     componentNext->timestamp = globalTimestamp;
00147     globalTimestamp++;
00148     componentNext->nGroupPriority = omx_base_component_Private->nGroupPriority;
00149     DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s\n", __func__);
00150     return OMX_ErrorNone;
00151 }
00152 
00157 OMX_ERRORTYPE removeElemFromList(ComponentListType **list, OMX_COMPONENTTYPE *openmaxStandComp) {
00158     ComponentListType *componentTemp;
00159     ComponentListType *componentPrev;
00160     OMX_BOOL bFound = OMX_FALSE;
00161 
00162     DEBUG(DEB_LEV_FUNCTION_NAME, "In %s list %p\n", __func__, *list);
00163     if (!*list) {
00164         DEBUG(DEB_LEV_ERR, "In %s, the resource manager is not initialized\n", __func__);
00165         return OMX_ErrorUndefined;
00166     }
00167     componentTemp = *list;
00168     componentPrev = *list;
00169     while(componentTemp) {
00170         if (componentTemp->openmaxStandComp == openmaxStandComp) {
00171             if (componentTemp == *list) {
00172                 *list = (*list)->next;
00173                 free(componentTemp);
00174             } else {
00175                 componentPrev->next = componentTemp->next;
00176                 free(componentTemp);
00177             }
00178              bFound = OMX_TRUE;
00179              break;
00180         } else {
00181             if (componentTemp != *list) {
00182                 componentPrev = componentPrev->next;
00183             }
00184             componentTemp = componentTemp->next;
00185         }
00186     }
00187     if(!bFound) {
00188         DEBUG(DEB_LEV_ERR, "In %s, the specified component does not exist\n", __func__);
00189         return OMX_ErrorComponentNotFound;
00190     }
00191     DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s\n", __func__);
00192     return OMX_ErrorNone;
00193 
00194 }
00195 
00196 
00202 int numElemInList(ComponentListType *list) {
00203     ComponentListType *componentTemp;
00204     int numElem = 0;
00205     DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00206     if (!list) {
00207         DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s, no list no elements\n", __func__);
00208         return 0;
00209     }
00210     componentTemp = list;
00211     while(componentTemp) {
00212         numElem++;
00213         componentTemp = componentTemp->next;
00214     }
00215     DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s\n", __func__);
00216     return numElem;
00217 }
00218 
00223 OMX_ERRORTYPE clearList(ComponentListType **list) {
00224     ComponentListType *componentTemp;
00225     ComponentListType *componentPrev;
00226     DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00227     if (!*list) {
00228         DEBUG(DEB_LEV_FUNCTION_NAME, "In %s, no list no elements\n", __func__);
00229         return OMX_ErrorNone;
00230     }
00231     componentTemp = *list;
00232     while(componentTemp) {
00233         componentPrev = componentTemp;
00234         componentTemp = componentTemp->next;
00235         free(componentPrev);
00236     }
00237     *list = NULL;
00238     DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s\n", __func__);
00239     return OMX_ErrorNone;
00240 }
00241 
00246 void RM_printList(ComponentListType *list, int viewFlag) {
00247     ComponentListType *componentTemp = list;
00248     omx_base_component_PrivateType* omx_base_component_Private;
00249     int index;
00250 
00251     if (!list) {
00252         printf("The list is empty\n");
00253         return;
00254     }
00255     index = 0;
00256     while (componentTemp) {
00257         omx_base_component_Private = (omx_base_component_PrivateType*)componentTemp->openmaxStandComp->pComponentPrivate;
00258         if ((viewFlag & RM_SHOW_NAME) == RM_SHOW_NAME) {
00259             printf("Name %s ", omx_base_component_Private->name);
00260         }
00261         if ((viewFlag & RM_SHOW_ADDRESS) == RM_SHOW_ADDRESS) {
00262             printf("Address %p ", componentTemp->openmaxStandComp);
00263         }
00264         printf("\n");
00265         index++;
00266         componentTemp = componentTemp->next;
00267     }
00268 }
00269 
00277 int searchLowerPriority(ComponentListType *list, int current_priority, ComponentListType **oldest_component_preemptable) {
00278     ComponentListType *componentTemp;
00279     ComponentListType *componentCandidate;
00280     DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00281     int nComp = 0;
00282     if (!list) {
00283         DEBUG(DEB_LEV_ERR, "In %s no list\n", __func__);
00284         return OMX_ErrorUndefined;
00285     }
00286     componentTemp = list;
00287     componentCandidate = NULL;
00288     while (componentTemp) {
00289         if (componentTemp->nGroupPriority > current_priority) {
00290             nComp++;
00291         }
00292         if (nComp>0) {
00293             if (componentCandidate) {
00294                 if (componentCandidate->timestamp > componentTemp->timestamp) {
00295                     componentCandidate = componentTemp;
00296                 }
00297             } else {
00298                 componentCandidate = componentTemp;
00299             }
00300         }
00301         componentTemp = componentTemp->next;
00302     }
00303     *oldest_component_preemptable = componentCandidate;
00304     DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s\n", __func__);
00305     return nComp;
00306 }
00307 
00312 OMX_ERRORTYPE preemptComponent(OMX_COMPONENTTYPE *openmaxStandComp) {
00313     OMX_ERRORTYPE err;
00314     omx_base_component_PrivateType* omx_base_component_Private = openmaxStandComp->pComponentPrivate;
00315 
00316     DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00317 
00318     if (omx_base_component_Private->state == OMX_StateIdle) {
00319         (*(omx_base_component_Private->callbacks->EventHandler))
00320           (openmaxStandComp, omx_base_component_Private->callbackData,
00321             OMX_EventError, OMX_ErrorResourcesLost, 0, NULL);
00322         err = OMX_SendCommand(openmaxStandComp, OMX_CommandStateSet, OMX_StateLoaded, NULL);
00323         if (err != OMX_ErrorNone) {
00324             DEBUG(DEB_LEV_ERR, "In %s, the state cannot be changed\n", __func__);
00325             return OMX_ErrorUndefined;
00326         }
00327     } else if ((omx_base_component_Private->state == OMX_StateExecuting) || (omx_base_component_Private->state == OMX_StatePause)) {
00328         // TODO fill also this section that cover the preemption of a running component
00329         // send OMX_ErrorResourcesPreempted
00330         // change state to Idle
00331         // send OMX_ErrorResourcesLost
00332         // change state to Loaded
00333     }
00334     DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s\n", __func__);
00335     return OMX_ErrorNone;
00336 }
00337 
00344 OMX_ERRORTYPE RM_getResource(OMX_COMPONENTTYPE *openmaxStandComp) {
00345     ComponentListType *componentCandidate;
00346     omx_base_component_PrivateType* omx_base_component_Private;
00347     int candidates;
00348     OMX_ERRORTYPE err;
00349     int i = 0;
00350     int indexComponent = -1;
00351 
00352     DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00353     omx_base_component_Private = (omx_base_component_PrivateType*)openmaxStandComp->pComponentPrivate;
00354     while(listOfcomponentRegistered[i].component_name != NULL ) {
00355         if (!strcmp(listOfcomponentRegistered[i].component_name, omx_base_component_Private->name)) {
00356             // found component in the list of the resource manager
00357             indexComponent = listOfcomponentRegistered[i].index;
00358             break;
00359         }
00360         i++;
00361     }
00362     if (indexComponent <0) {
00363         // No resource to be handled
00364         DEBUG(DEB_LEV_ERR, "In %s No resource to be handled\n", __func__);
00365         return OMX_ErrorNone;
00366     }
00367     if (numElemInList(globalComponentList[indexComponent]) >= listOfcomponentRegistered[i].max_components) {
00368         candidates = searchLowerPriority(globalComponentList[indexComponent], omx_base_component_Private->nGroupPriority, &componentCandidate);
00369         if (candidates) {
00370             DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s candidates %i winner %p\n", __func__, candidates, componentCandidate->openmaxStandComp);
00371             err = preemptComponent(componentCandidate->openmaxStandComp);
00372             if (err != OMX_ErrorNone) {
00373                 DEBUG(DEB_LEV_ERR, "In %s the component cannot be preempted\n", __func__);
00374                 return OMX_ErrorInsufficientResources;
00375             } else {
00376                 err = removeElemFromList(&globalComponentList[indexComponent], componentCandidate->openmaxStandComp);
00377                 err = addElemToList(&globalComponentList[indexComponent], openmaxStandComp, indexComponent, OMX_FALSE);
00378                 if (err != OMX_ErrorNone) {
00379                     DEBUG(DEB_LEV_ERR, "In %s memory error\n", __func__);
00380                     return OMX_ErrorInsufficientResources;
00381                 }
00382             }
00383         } else {
00384             DEBUG(DEB_LEV_SIMPLE_SEQ, "Out of %s with insufficient resources\n", __func__);
00385             return OMX_ErrorInsufficientResources;
00386         }
00387 
00388     } else {
00389         err = addElemToList(&globalComponentList[indexComponent], openmaxStandComp, indexComponent, OMX_FALSE);
00390     }
00391     DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s\n", __func__);
00392     return OMX_ErrorNone;
00393 }
00394 
00399 OMX_ERRORTYPE RM_releaseResource(OMX_COMPONENTTYPE *openmaxStandComp){
00400     omx_base_component_PrivateType* omx_base_component_Private;
00401     OMX_COMPONENTTYPE *openmaxWaitingComp;
00402     OMX_ERRORTYPE err;
00403 
00404     int i = 0;
00405     int indexComponent = -1;
00406 
00407     DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00408     omx_base_component_Private = (omx_base_component_PrivateType*)openmaxStandComp->pComponentPrivate;
00409 
00410     while(listOfcomponentRegistered[i].component_name != NULL ) {
00411         if (!strcmp(listOfcomponentRegistered[i].component_name, omx_base_component_Private->name)) {
00412             // found component in the list of the resource manager
00413             indexComponent = listOfcomponentRegistered[i].index;
00414             break;
00415         }
00416         i++;
00417     }
00418     if (indexComponent <0) {
00419         // No resource to be handled
00420         DEBUG(DEB_LEV_ERR, "In %s No resource to be handled\n", __func__);
00421         return OMX_ErrorNone;
00422     }
00423     if (!globalComponentList[indexComponent]) {
00424         DEBUG(DEB_LEV_ERR, "In %s, the resource manager is not initialized\n", __func__);
00425         return OMX_ErrorUndefined;
00426     }
00427     err = removeElemFromList(&globalComponentList[indexComponent], openmaxStandComp);
00428     if (err != OMX_ErrorNone) {
00429         DEBUG(DEB_LEV_ERR, "In %s, the resource cannot be released\n", __func__);
00430         return OMX_ErrorUndefined;
00431     }
00432     if(numElemInList(globalWaitingComponentList[indexComponent])) {
00433         openmaxWaitingComp = globalWaitingComponentList[indexComponent]->openmaxStandComp;
00434         removeElemFromList(&globalWaitingComponentList[indexComponent], openmaxWaitingComp);
00435         err = OMX_SendCommand(openmaxWaitingComp, OMX_CommandStateSet, OMX_StateIdle, NULL);
00436         if (err != OMX_ErrorNone) {
00437             DEBUG(DEB_LEV_ERR, "In %s, the state cannot be changed\n", __func__);
00438         }
00439     }
00440 
00441     DEBUG(DEB_LEV_FUNCTION_NAME, "Out of  %s\n", __func__);
00442     return OMX_ErrorNone;
00443 }
00444 
00451 OMX_ERRORTYPE RM_waitForResource(OMX_COMPONENTTYPE *openmaxStandComp) {
00452     omx_base_component_PrivateType* omx_base_component_Private;
00453 
00454     int i = 0;
00455     int indexComponent = -1;
00456 
00457     DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00458     omx_base_component_Private = (omx_base_component_PrivateType*)openmaxStandComp->pComponentPrivate;
00459 
00460     while(listOfcomponentRegistered[i].component_name != NULL ) {
00461         if (!strcmp(listOfcomponentRegistered[i].component_name, omx_base_component_Private->name)) {
00462             // found component in the list of the resource manager
00463             indexComponent = listOfcomponentRegistered[i].index;
00464             break;
00465         }
00466         i++;
00467     }
00468     if (indexComponent <0) {
00469         // No resource to be handled
00470         DEBUG(DEB_LEV_ERR, "In %s No resource to be handled\n", __func__);
00471         return OMX_ErrorNone;
00472     }
00473 
00474     addElemToList(&globalWaitingComponentList[indexComponent], openmaxStandComp, listOfcomponentRegistered[i].index, OMX_TRUE);
00475 
00476     DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s\n", __func__);
00477     return OMX_ErrorNone;
00478 }
00479 
00485 OMX_ERRORTYPE RM_removeFromWaitForResource(OMX_COMPONENTTYPE *openmaxStandComp) {
00486     omx_base_component_PrivateType* omx_base_component_Private;
00487     int i = 0;
00488     int indexComponent = -1;
00489 
00490     DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00491     omx_base_component_Private = (omx_base_component_PrivateType*)openmaxStandComp->pComponentPrivate;
00492 
00493     while(listOfcomponentRegistered[i].component_name != NULL ) {
00494         if (!strcmp(listOfcomponentRegistered[i].component_name, omx_base_component_Private->name)) {
00495             // found component in the list of the resource manager
00496             removeElemFromList(&globalComponentList[indexComponent], openmaxStandComp);
00497             break;
00498         }
00499         i++;
00500     }
00501     if (indexComponent <0) {
00502         // No resource to be handled
00503         DEBUG(DEB_LEV_ERR, "In %s No resource to be handled\n", __func__);
00504         return OMX_ErrorNone;
00505     }
00506     DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s\n", __func__);
00507     return OMX_ErrorNone;
00508 }