1 /*
2 *
3 * Copyright 2013 Rockchip Electronics 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 Rockchip_OMX_Resourcemanager.c
20 * @brief
21 * @author csy (csy@rock-chips.com)
22 * @version 1.0.0
23 * @history
24 * 2013.11.26 : Create
25 */
26 #undef ROCKCHIP_LOG_TAG
27 #define ROCKCHIP_LOG_TAG "omx_res"
28
29 #include "Rockchip_OMX_Resourcemanager.h"
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include "Rockchip_OMX_Basecomponent.h"
34 #include "Rockchip_OSAL_Memory.h"
35 #include "Rockchip_OSAL_Mutex.h"
36 #include "Rockchip_OSAL_Log.h"
37
38 #define MAX_RESOURCE_VIDEO_DEC 6
39 #define MAX_RESOURCE_VIDEO_ENC 4
40
41 /* Max allowable video scheduler component instance */
42 static ROCKCHIP_OMX_RM_COMPONENT_LIST *gpVideoDecRMComponentList = NULL;
43 static ROCKCHIP_OMX_RM_COMPONENT_LIST *gpVideoDecRMWaitingList = NULL;
44 static ROCKCHIP_OMX_RM_COMPONENT_LIST *gpVideoEncRMComponentList = NULL;
45 static ROCKCHIP_OMX_RM_COMPONENT_LIST *gpVideoEncRMWaitingList = NULL;
46 static OMX_HANDLETYPE ghVideoRMComponentListMutex = NULL;
47
48
addElementList(ROCKCHIP_OMX_RM_COMPONENT_LIST ** ppList,OMX_COMPONENTTYPE * pOMXComponent)49 OMX_ERRORTYPE addElementList(ROCKCHIP_OMX_RM_COMPONENT_LIST **ppList, OMX_COMPONENTTYPE *pOMXComponent)
50 {
51 OMX_ERRORTYPE ret = OMX_ErrorNone;
52 ROCKCHIP_OMX_RM_COMPONENT_LIST *pTempComp = NULL;
53 ROCKCHIP_OMX_BASECOMPONENT *pRockchipComponent = NULL;
54
55 pRockchipComponent = (ROCKCHIP_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
56 if (*ppList != NULL) {
57 pTempComp = *ppList;
58 while (pTempComp->pNext != NULL) {
59 pTempComp = pTempComp->pNext;
60 }
61 pTempComp->pNext =
62 (ROCKCHIP_OMX_RM_COMPONENT_LIST *)Rockchip_OSAL_Malloc(sizeof(ROCKCHIP_OMX_RM_COMPONENT_LIST));
63 if (pTempComp->pNext == NULL) {
64 ret = OMX_ErrorInsufficientResources;
65 goto EXIT;
66 }
67 ((ROCKCHIP_OMX_RM_COMPONENT_LIST *)(pTempComp->pNext))->pNext = NULL;
68 ((ROCKCHIP_OMX_RM_COMPONENT_LIST *)(pTempComp->pNext))->pOMXStandComp = pOMXComponent;
69 ((ROCKCHIP_OMX_RM_COMPONENT_LIST *)(pTempComp->pNext))->groupPriority =
70 pRockchipComponent->compPriority.nGroupPriority;
71 goto EXIT;
72 } else {
73 *ppList = (ROCKCHIP_OMX_RM_COMPONENT_LIST *)Rockchip_OSAL_Malloc(sizeof(ROCKCHIP_OMX_RM_COMPONENT_LIST));
74 if (*ppList == NULL) {
75 ret = OMX_ErrorInsufficientResources;
76 goto EXIT;
77 }
78 pTempComp = *ppList;
79 pTempComp->pNext = NULL;
80 pTempComp->pOMXStandComp = pOMXComponent;
81 pTempComp->groupPriority = pRockchipComponent->compPriority.nGroupPriority;
82 }
83
84 EXIT:
85 return ret;
86 }
87
removeElementList(ROCKCHIP_OMX_RM_COMPONENT_LIST ** ppList,OMX_COMPONENTTYPE * pOMXComponent)88 OMX_ERRORTYPE removeElementList(ROCKCHIP_OMX_RM_COMPONENT_LIST **ppList, OMX_COMPONENTTYPE *pOMXComponent)
89 {
90 OMX_ERRORTYPE ret = OMX_ErrorNone;
91 ROCKCHIP_OMX_RM_COMPONENT_LIST *pCurrComp = NULL;
92 ROCKCHIP_OMX_RM_COMPONENT_LIST *pPrevComp = NULL;
93 OMX_BOOL bDetectComp = OMX_FALSE;
94
95 if (*ppList == NULL) {
96 ret = OMX_ErrorUndefined;
97 goto EXIT;
98 }
99
100 pCurrComp = *ppList;
101 while (pCurrComp != NULL) {
102 if (pCurrComp->pOMXStandComp == pOMXComponent) {
103 if (*ppList == pCurrComp) {
104 *ppList = pCurrComp->pNext;
105 Rockchip_OSAL_Free(pCurrComp);
106 } else {
107 if (pPrevComp != NULL) {
108 pPrevComp->pNext = pCurrComp->pNext;
109 }
110 Rockchip_OSAL_Free(pCurrComp);
111 }
112 bDetectComp = OMX_TRUE;
113 break;
114 } else {
115 pPrevComp = pCurrComp;
116 pCurrComp = pCurrComp->pNext;
117 }
118 }
119
120 if (bDetectComp == OMX_FALSE)
121 ret = OMX_ErrorComponentNotFound;
122 else
123 ret = OMX_ErrorNone;
124
125 EXIT:
126 return ret;
127 }
128
searchLowPriority(ROCKCHIP_OMX_RM_COMPONENT_LIST * RMComp_list,OMX_U32 inComp_priority,ROCKCHIP_OMX_RM_COMPONENT_LIST ** outLowComp)129 int searchLowPriority(ROCKCHIP_OMX_RM_COMPONENT_LIST *RMComp_list,
130 OMX_U32 inComp_priority, ROCKCHIP_OMX_RM_COMPONENT_LIST **outLowComp)
131 {
132 int ret = 0;
133 ROCKCHIP_OMX_RM_COMPONENT_LIST *pTempComp = NULL;
134 ROCKCHIP_OMX_RM_COMPONENT_LIST *pCandidateComp = NULL;
135
136 if (RMComp_list == NULL) {
137 ret = -1;
138 omx_err("component list is NULL!");
139 goto EXIT;
140 }
141
142 pTempComp = RMComp_list;
143 *outLowComp = 0;
144
145 while (pTempComp != NULL) {
146 if (pTempComp->groupPriority > inComp_priority) {
147 if (pCandidateComp != NULL) {
148 if (pCandidateComp->groupPriority < pTempComp->groupPriority)
149 pCandidateComp = pTempComp;
150 } else {
151 pCandidateComp = pTempComp;
152 }
153 }
154
155 pTempComp = pTempComp->pNext;
156 }
157
158 *outLowComp = pCandidateComp;
159 if (pCandidateComp == NULL) {
160 ret = 0;
161 } else {
162 ret = 1;
163 }
164
165 EXIT:
166 return ret;
167 }
168
removeComponent(OMX_COMPONENTTYPE * pOMXComponent)169 OMX_ERRORTYPE removeComponent(OMX_COMPONENTTYPE *pOMXComponent)
170 {
171 OMX_ERRORTYPE ret = OMX_ErrorNone;
172 ROCKCHIP_OMX_BASECOMPONENT *pRockchipComponent = NULL;
173
174 pRockchipComponent = (ROCKCHIP_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
175 if (pRockchipComponent->currentState == OMX_StateIdle) {
176 (*(pRockchipComponent->pCallbacks->EventHandler))
177 (pOMXComponent, pRockchipComponent->callbackData,
178 OMX_EventError, OMX_ErrorResourcesLost, 0, NULL);
179 ret = OMX_SendCommand(pOMXComponent, OMX_CommandStateSet, OMX_StateLoaded, NULL);
180 if (ret != OMX_ErrorNone) {
181 ret = OMX_ErrorUndefined;
182 goto EXIT;
183 }
184 } else if ((pRockchipComponent->currentState == OMX_StateExecuting) ||
185 (pRockchipComponent->currentState == OMX_StatePause)) {
186 /* Todo */
187 }
188
189 ret = OMX_ErrorNone;
190
191 EXIT:
192 return ret;
193 }
194
195
Rockchip_OMX_ResourceManager_Init()196 OMX_ERRORTYPE Rockchip_OMX_ResourceManager_Init()
197 {
198 OMX_ERRORTYPE ret = OMX_ErrorNone;
199
200 FunctionIn();
201 ret = Rockchip_OSAL_MutexCreate(&ghVideoRMComponentListMutex);
202 omx_trace("Rockchip_OSAL_MutexCreate ghVideoRMComponentListMutex %p", ghVideoRMComponentListMutex);
203 FunctionOut();
204
205 return ret;
206 }
207
Rockchip_OMX_ResourceManager_Deinit()208 OMX_ERRORTYPE Rockchip_OMX_ResourceManager_Deinit()
209 {
210 OMX_ERRORTYPE ret = OMX_ErrorNone;
211 ROCKCHIP_OMX_RM_COMPONENT_LIST *pCurrComponent;
212 ROCKCHIP_OMX_RM_COMPONENT_LIST *pNextComponent;
213
214 FunctionIn();
215
216 omx_trace("ghVideoRMComponentListMutex lock in %p", ghVideoRMComponentListMutex);
217 Rockchip_OSAL_MutexLock(ghVideoRMComponentListMutex);
218
219 if (gpVideoDecRMComponentList) {
220 pCurrComponent = gpVideoDecRMComponentList;
221 while (pCurrComponent != NULL) {
222 pNextComponent = pCurrComponent->pNext;
223 Rockchip_OSAL_Free(pCurrComponent);
224 pCurrComponent = pNextComponent;
225 }
226 gpVideoDecRMComponentList = NULL;
227 }
228 if (gpVideoDecRMWaitingList) {
229 pCurrComponent = gpVideoDecRMWaitingList;
230 while (pCurrComponent != NULL) {
231 pNextComponent = pCurrComponent->pNext;
232 Rockchip_OSAL_Free(pCurrComponent);
233 pCurrComponent = pNextComponent;
234 }
235 gpVideoDecRMWaitingList = NULL;
236 }
237
238 if (gpVideoEncRMComponentList) {
239 pCurrComponent = gpVideoEncRMComponentList;
240 while (pCurrComponent != NULL) {
241 pNextComponent = pCurrComponent->pNext;
242 Rockchip_OSAL_Free(pCurrComponent);
243 pCurrComponent = pNextComponent;
244 }
245 gpVideoEncRMComponentList = NULL;
246 }
247 if (gpVideoEncRMWaitingList) {
248 pCurrComponent = gpVideoEncRMWaitingList;
249 while (pCurrComponent != NULL) {
250 pNextComponent = pCurrComponent->pNext;
251 Rockchip_OSAL_Free(pCurrComponent);
252 pCurrComponent = pNextComponent;
253 }
254 gpVideoEncRMWaitingList = NULL;
255 }
256
257 Rockchip_OSAL_MutexUnlock(ghVideoRMComponentListMutex);
258
259 omx_trace("Rockchip_OSAL_MutexTerminate ghVideoRMComponentListMutex lock in %p", ghVideoRMComponentListMutex);
260 Rockchip_OSAL_MutexTerminate(ghVideoRMComponentListMutex);
261 ghVideoRMComponentListMutex = NULL;
262
263 ret = OMX_ErrorNone;
264 goto EXIT;
265 EXIT:
266 FunctionOut();
267
268 return ret;
269 }
Rockchip_OMX_Check_Resource(OMX_COMPONENTTYPE * pOMXComponent)270 OMX_ERRORTYPE Rockchip_OMX_Check_Resource(OMX_COMPONENTTYPE *pOMXComponent)
271 {
272 OMX_ERRORTYPE ret = OMX_ErrorNone;
273 ROCKCHIP_OMX_BASECOMPONENT *pRockchipComponent = NULL;
274 ROCKCHIP_OMX_RM_COMPONENT_LIST *pComponentTemp = NULL;
275 ROCKCHIP_OMX_RM_COMPONENT_LIST *pComponentCandidate = NULL;
276 int numElem = 0;
277 int lowCompDetect = 0;
278
279 FunctionIn();
280
281 Rockchip_OSAL_MutexLock(ghVideoRMComponentListMutex);
282
283 pRockchipComponent = (ROCKCHIP_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
284
285 if (pRockchipComponent->codecType == HW_VIDEO_DEC_CODEC) {
286 pComponentTemp = gpVideoDecRMComponentList;
287 if (pComponentTemp != NULL) {
288 while (pComponentTemp) {
289 numElem++;
290 pComponentTemp = pComponentTemp->pNext;
291 }
292 } else {
293 numElem = 0;
294 }
295 if (numElem >= MAX_RESOURCE_VIDEO_DEC) {
296 lowCompDetect = searchLowPriority(gpVideoDecRMComponentList,
297 pRockchipComponent->compPriority.nGroupPriority, &pComponentCandidate);
298 if (lowCompDetect <= 0) {
299 ret = OMX_ErrorInsufficientResources;
300 }
301 }
302 } else if (pRockchipComponent->codecType == HW_VIDEO_ENC_CODEC) {
303 pComponentTemp = gpVideoEncRMComponentList;
304 if (pComponentTemp != NULL) {
305 while (pComponentTemp) {
306 numElem++;
307 pComponentTemp = pComponentTemp->pNext;
308 }
309 } else {
310 numElem = 0;
311 }
312 if (numElem >= MAX_RESOURCE_VIDEO_ENC) {
313 lowCompDetect = searchLowPriority(gpVideoEncRMComponentList,
314 pRockchipComponent->compPriority.nGroupPriority, &pComponentCandidate);
315 if (lowCompDetect <= 0) {
316 ret = OMX_ErrorInsufficientResources;
317 }
318 }
319 }
320 Rockchip_OSAL_MutexUnlock(ghVideoRMComponentListMutex);
321 return ret;
322 }
323
Rockchip_OMX_Get_Resource(OMX_COMPONENTTYPE * pOMXComponent)324 OMX_ERRORTYPE Rockchip_OMX_Get_Resource(OMX_COMPONENTTYPE *pOMXComponent)
325 {
326 OMX_ERRORTYPE ret = OMX_ErrorNone;
327 ROCKCHIP_OMX_BASECOMPONENT *pRockchipComponent = NULL;
328 ROCKCHIP_OMX_RM_COMPONENT_LIST *pComponentTemp = NULL;
329 ROCKCHIP_OMX_RM_COMPONENT_LIST *pComponentCandidate = NULL;
330 int numElem = 0;
331 int lowCompDetect = 0;
332
333 FunctionIn();
334
335 Rockchip_OSAL_MutexLock(ghVideoRMComponentListMutex);
336
337 pRockchipComponent = (ROCKCHIP_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
338
339 if (pRockchipComponent->codecType == HW_VIDEO_DEC_CODEC) {
340 pComponentTemp = gpVideoDecRMComponentList;
341 if (pComponentTemp != NULL) {
342 while (pComponentTemp) {
343 numElem++;
344 pComponentTemp = pComponentTemp->pNext;
345 }
346 } else {
347 numElem = 0;
348 }
349 if (numElem >= MAX_RESOURCE_VIDEO_DEC) {
350 lowCompDetect = searchLowPriority(gpVideoDecRMComponentList,
351 pRockchipComponent->compPriority.nGroupPriority, &pComponentCandidate);
352 if (lowCompDetect <= 0) {
353 ret = OMX_ErrorInsufficientResources;
354 goto EXIT;
355 } else {
356 ret = removeComponent(pComponentCandidate->pOMXStandComp);
357 if (ret != OMX_ErrorNone) {
358 ret = OMX_ErrorInsufficientResources;
359 goto EXIT;
360 } else {
361 ret = removeElementList(&gpVideoDecRMComponentList, pComponentCandidate->pOMXStandComp);
362 ret = addElementList(&gpVideoDecRMComponentList, pOMXComponent);
363 if (ret != OMX_ErrorNone) {
364 ret = OMX_ErrorInsufficientResources;
365 goto EXIT;
366 }
367 }
368 }
369 } else {
370 ret = addElementList(&gpVideoDecRMComponentList, pOMXComponent);
371 if (ret != OMX_ErrorNone) {
372 ret = OMX_ErrorInsufficientResources;
373 goto EXIT;
374 }
375 }
376 } else if (pRockchipComponent->codecType == HW_VIDEO_ENC_CODEC) {
377 pComponentTemp = gpVideoEncRMComponentList;
378 if (pComponentTemp != NULL) {
379 while (pComponentTemp) {
380 numElem++;
381 pComponentTemp = pComponentTemp->pNext;
382 }
383 } else {
384 numElem = 0;
385 }
386 if (numElem >= MAX_RESOURCE_VIDEO_ENC) {
387 lowCompDetect = searchLowPriority(gpVideoEncRMComponentList,
388 pRockchipComponent->compPriority.nGroupPriority, &pComponentCandidate);
389 if (lowCompDetect <= 0) {
390 ret = OMX_ErrorInsufficientResources;
391 goto EXIT;
392 } else {
393 ret = removeComponent(pComponentCandidate->pOMXStandComp);
394 if (ret != OMX_ErrorNone) {
395 ret = OMX_ErrorInsufficientResources;
396 goto EXIT;
397 } else {
398 ret = removeElementList(&gpVideoEncRMComponentList, pComponentCandidate->pOMXStandComp);
399 ret = addElementList(&gpVideoEncRMComponentList, pOMXComponent);
400 if (ret != OMX_ErrorNone) {
401 ret = OMX_ErrorInsufficientResources;
402 goto EXIT;
403 }
404 }
405 }
406 } else {
407 ret = addElementList(&gpVideoEncRMComponentList, pOMXComponent);
408 if (ret != OMX_ErrorNone) {
409 ret = OMX_ErrorInsufficientResources;
410 goto EXIT;
411 }
412 }
413 }
414 ret = OMX_ErrorNone;
415
416 EXIT:
417
418 Rockchip_OSAL_MutexUnlock(ghVideoRMComponentListMutex);
419
420 FunctionOut();
421
422 return ret;
423 }
424
Rockchip_OMX_Release_Resource(OMX_COMPONENTTYPE * pOMXComponent)425 OMX_ERRORTYPE Rockchip_OMX_Release_Resource(OMX_COMPONENTTYPE *pOMXComponent)
426 {
427 OMX_ERRORTYPE ret = OMX_ErrorNone;
428 ROCKCHIP_OMX_BASECOMPONENT *pRockchipComponent = NULL;
429 ROCKCHIP_OMX_RM_COMPONENT_LIST *pComponentTemp = NULL;
430 OMX_COMPONENTTYPE *pOMXWaitComponent = NULL;
431 int numElem = 0;
432
433 FunctionIn();
434
435 Rockchip_OSAL_MutexLock(ghVideoRMComponentListMutex);
436
437 pRockchipComponent = (ROCKCHIP_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
438
439 if (pRockchipComponent->codecType == HW_VIDEO_DEC_CODEC) {
440 pComponentTemp = gpVideoDecRMWaitingList;
441 if (gpVideoDecRMComponentList == NULL) {
442 ret = OMX_ErrorUndefined;
443 goto EXIT;
444 }
445
446 ret = removeElementList(&gpVideoDecRMComponentList, pOMXComponent);
447 if (ret != OMX_ErrorNone) {
448 ret = OMX_ErrorUndefined;
449 goto EXIT;
450 }
451 while (pComponentTemp) {
452 numElem++;
453 pComponentTemp = pComponentTemp->pNext;
454 }
455 if (numElem > 0) {
456 pOMXWaitComponent = gpVideoDecRMWaitingList->pOMXStandComp;
457 removeElementList(&gpVideoDecRMWaitingList, pOMXWaitComponent);
458 ret = OMX_SendCommand(pOMXWaitComponent, OMX_CommandStateSet, OMX_StateIdle, NULL);
459 if (ret != OMX_ErrorNone) {
460 goto EXIT;
461 }
462 }
463 } else if (pRockchipComponent->codecType == HW_VIDEO_ENC_CODEC) {
464 pComponentTemp = gpVideoEncRMWaitingList;
465 if (gpVideoEncRMComponentList == NULL) {
466 ret = OMX_ErrorUndefined;
467 goto EXIT;
468 }
469
470 ret = removeElementList(&gpVideoEncRMComponentList, pOMXComponent);
471 if (ret != OMX_ErrorNone) {
472 ret = OMX_ErrorUndefined;
473 goto EXIT;
474 }
475 while (pComponentTemp) {
476 numElem++;
477 pComponentTemp = pComponentTemp->pNext;
478 }
479 if (numElem > 0) {
480 pOMXWaitComponent = gpVideoEncRMWaitingList->pOMXStandComp;
481 removeElementList(&gpVideoEncRMWaitingList, pOMXWaitComponent);
482 ret = OMX_SendCommand(pOMXWaitComponent, OMX_CommandStateSet, OMX_StateIdle, NULL);
483 if (ret != OMX_ErrorNone) {
484 goto EXIT;
485 }
486 }
487 }
488
489 EXIT:
490
491 Rockchip_OSAL_MutexUnlock(ghVideoRMComponentListMutex);
492
493 FunctionOut();
494
495 return ret;
496 }
497
Rockchip_OMX_In_WaitForResource(OMX_COMPONENTTYPE * pOMXComponent)498 OMX_ERRORTYPE Rockchip_OMX_In_WaitForResource(OMX_COMPONENTTYPE *pOMXComponent)
499 {
500 OMX_ERRORTYPE ret = OMX_ErrorNone;
501 ROCKCHIP_OMX_BASECOMPONENT *pRockchipComponent = NULL;
502
503 FunctionIn();
504
505 Rockchip_OSAL_MutexLock(ghVideoRMComponentListMutex);
506
507 pRockchipComponent = (ROCKCHIP_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
508 if (pRockchipComponent->codecType == HW_VIDEO_DEC_CODEC)
509 ret = addElementList(&gpVideoDecRMWaitingList, pOMXComponent);
510 else if (pRockchipComponent->codecType == HW_VIDEO_ENC_CODEC)
511 ret = addElementList(&gpVideoEncRMWaitingList, pOMXComponent);
512
513 Rockchip_OSAL_MutexUnlock(ghVideoRMComponentListMutex);
514
515 FunctionOut();
516
517 return ret;
518 }
519
Rockchip_OMX_Out_WaitForResource(OMX_COMPONENTTYPE * pOMXComponent)520 OMX_ERRORTYPE Rockchip_OMX_Out_WaitForResource(OMX_COMPONENTTYPE *pOMXComponent)
521 {
522 OMX_ERRORTYPE ret = OMX_ErrorNone;
523 ROCKCHIP_OMX_BASECOMPONENT *pRockchipComponent = NULL;
524
525 FunctionIn();
526
527 Rockchip_OSAL_MutexLock(ghVideoRMComponentListMutex);
528
529 pRockchipComponent = (ROCKCHIP_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
530 if (pRockchipComponent->codecType == HW_VIDEO_DEC_CODEC)
531 ret = removeElementList(&gpVideoDecRMWaitingList, pOMXComponent);
532 else if (pRockchipComponent->codecType == HW_VIDEO_ENC_CODEC)
533 ret = removeElementList(&gpVideoEncRMWaitingList, pOMXComponent);
534
535 Rockchip_OSAL_MutexUnlock(ghVideoRMComponentListMutex);
536
537 FunctionOut();
538
539 return ret;
540 }