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