• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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@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 
addElementList(SEC_OMX_RM_COMPONENT_LIST ** ppList,OMX_COMPONENTTYPE * pOMXComponent)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 
removeElementList(SEC_OMX_RM_COMPONENT_LIST ** ppList,OMX_COMPONENTTYPE * pOMXComponent)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 
searchLowPriority(SEC_OMX_RM_COMPONENT_LIST * RMComp_list,int inComp_priority,SEC_OMX_RM_COMPONENT_LIST ** outLowComp)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 
removeComponent(OMX_COMPONENTTYPE * pOMXComponent)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 
SEC_OMX_ResourceManager_Init()185 OMX_ERRORTYPE SEC_OMX_ResourceManager_Init()
186 {
187     FunctionIn();
188     SEC_OSAL_MutexCreate(&ghVideoRMComponentListMutex);
189     FunctionOut();
190     return OMX_ErrorNone;
191 }
192 
SEC_OMX_ResourceManager_Deinit()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 
SEC_OMX_Get_Resource(OMX_COMPONENTTYPE * pOMXComponent)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 
SEC_OMX_Release_Resource(OMX_COMPONENTTYPE * pOMXComponent)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 
SEC_OMX_In_WaitForResource(OMX_COMPONENTTYPE * pOMXComponent)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 
SEC_OMX_Out_WaitForResource(OMX_COMPONENTTYPE * pOMXComponent)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