|
1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include "transition.h" |
|
20 #include <openmax/il/khronos/v1_x/OMX_Component.h> |
|
21 |
|
22 void CloseSupplierRelations(TAny* aPtr) |
|
23 { |
|
24 RSupplierRelations& links = *reinterpret_cast<RSupplierRelations*>(aPtr); |
|
25 for(TInt i = 0, count = links.Count(); i < count; i++) |
|
26 { |
|
27 links[i].Close(); |
|
28 } |
|
29 links.Close(); |
|
30 } |
|
31 |
|
32 /** |
|
33 * Finds a transition order in which no component is transitioned until all components it suppliers to have been transitioned. |
|
34 * If no such order exists (this happens if and only if a cyclic buffer supply chain exists in the graph), this method leaves |
|
35 * with KErrNotFound. |
|
36 * |
|
37 * The result of this algorithm is appropriate for transitioning components from the Loaded state to the Idle state without incurring |
|
38 * errors calling OMX_UseBuffer. For transitions Executing->Idle and Executing->Paused, the reverse order can be used. |
|
39 * |
|
40 * @leave KErrNoMemory |
|
41 * @leave KErrNotFound iff a transition order for the graph does not exist |
|
42 * @leave KErrArgument if aOrder passed in is not empty |
|
43 */ |
|
44 void FindTransitionOrderL(const RSupplierRelations& aSupplierRelations, RArray<TInt>& aOrder) |
|
45 { |
|
46 if(aOrder.Count() > 0) |
|
47 { |
|
48 User::Leave(KErrArgument); |
|
49 } |
|
50 |
|
51 TInt numComponents = aSupplierRelations.Count(); |
|
52 TInt numPendingComponents = numComponents; |
|
53 RArray<TBool> pendingComponents; |
|
54 CleanupClosePushL(pendingComponents); |
|
55 for(TInt i = 0; i < numComponents; i++) |
|
56 { |
|
57 pendingComponents.AppendL(ETrue); |
|
58 } |
|
59 |
|
60 while(numPendingComponents > 0) |
|
61 { |
|
62 TInt nextComponent = KErrNotFound; |
|
63 for(TInt i = 0; i < numComponents && nextComponent == KErrNotFound; i++) |
|
64 { |
|
65 // try each component not yet transitioned |
|
66 if(pendingComponents[i]) |
|
67 { |
|
68 // have all this component's non-supplier peers been transitioned? |
|
69 nextComponent = i; |
|
70 for(TInt j = 0, numSupplied = aSupplierRelations[i].Count(); j < numSupplied && nextComponent != KErrNotFound; j++) |
|
71 { |
|
72 if(pendingComponents[aSupplierRelations[i][j]]) |
|
73 { |
|
74 // no, this component can't transition yet |
|
75 nextComponent = KErrNotFound; |
|
76 } |
|
77 } |
|
78 } |
|
79 } |
|
80 // couldn't find a component to transition? so no solution |
|
81 if(nextComponent == KErrNotFound) |
|
82 { |
|
83 aOrder.Reset(); |
|
84 User::Leave(KErrNotFound); |
|
85 } |
|
86 |
|
87 // this component can transition |
|
88 aOrder.AppendL(nextComponent); |
|
89 pendingComponents[nextComponent] = EFalse; |
|
90 numPendingComponents--; |
|
91 } |
|
92 |
|
93 CleanupStack::PopAndDestroy(&pendingComponents); |
|
94 } |