|
1 // Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 |
|
17 /** |
|
18 @file |
|
19 @internalComponent |
|
20 */ |
|
21 |
|
22 #include <mmf/server/mmfbuffer.h> |
|
23 #include <mmf/server/mmfdatabuffer.h> |
|
24 |
|
25 #include "log.h" |
|
26 #include "omxilportimpl.h" |
|
27 #include <openmax/il/common/omxilport.h> |
|
28 #include <openmax/il/common/omxilutil.h> |
|
29 |
|
30 const TInt COmxILPortImpl::KMaxBufferMarksQueueSize; |
|
31 |
|
32 COmxILPortImpl* COmxILPortImpl::NewL(const TOmxILCommonPortData& aCommonPortData, COmxILPort& aPort) |
|
33 { |
|
34 COmxILPortImpl* self = new (ELeave) COmxILPortImpl(aCommonPortData, aPort); |
|
35 return self; |
|
36 } |
|
37 |
|
38 COmxILPortImpl::COmxILPortImpl(const TOmxILCommonPortData& aCommonPortData, COmxILPort& aPort) |
|
39 : |
|
40 iTunnelledComponent(0), |
|
41 iTunnelledPort(0), |
|
42 iBufferHeaders(), |
|
43 iBufferMarks(_FOFF(TBufferMarkInfo, iLink)), |
|
44 iTransitionState(EPortNotTransitioning), |
|
45 iBufferMarkPropagationPortIndex(aCommonPortData.iBufferMarkPropagationPortIndex), |
|
46 aFirstUseBufferHasBeenReceived(OMX_FALSE), |
|
47 iOmxILPort(aPort) |
|
48 { |
|
49 DEBUG_PRINTF(_L8("COmxILPortImpl::COmxILPortImpl")); |
|
50 |
|
51 // Filll in OMX_PARAM_PORTDEFINITIONTYPE |
|
52 iParamPortDefinition.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); |
|
53 iParamPortDefinition.nVersion = aCommonPortData.iOmxVersion; |
|
54 iParamPortDefinition.nPortIndex = aCommonPortData.iPortIndex; |
|
55 iParamPortDefinition.eDir = aCommonPortData.iDirection; |
|
56 iParamPortDefinition.nBufferCountActual = aCommonPortData.iBufferCountMin; |
|
57 iParamPortDefinition.nBufferCountMin = aCommonPortData.iBufferCountMin; |
|
58 iParamPortDefinition.nBufferSize = aCommonPortData.iBufferSizeMin; |
|
59 iParamPortDefinition.bEnabled = OMX_TRUE; |
|
60 iParamPortDefinition.bPopulated = OMX_FALSE; |
|
61 iParamPortDefinition.eDomain = aCommonPortData.iPortDomain; |
|
62 // NOTE: iParamPortDefinition.format must be finished up by concrete ports |
|
63 iParamPortDefinition.bBuffersContiguous = aCommonPortData.iBuffersContiguous; |
|
64 iParamPortDefinition.nBufferAlignment = aCommonPortData.iBufferAlignment; |
|
65 |
|
66 // Fill in OMX_PARAM_BUFFERSUPPLIERTYPE |
|
67 iParamCompBufferSupplier.nSize = sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE); |
|
68 iParamCompBufferSupplier.nVersion = aCommonPortData.iOmxVersion; |
|
69 iParamCompBufferSupplier.nPortIndex = aCommonPortData.iPortIndex; |
|
70 iParamCompBufferSupplier.eBufferSupplier = aCommonPortData.iBufferSupplier; |
|
71 |
|
72 } |
|
73 |
|
74 COmxILPortImpl::~COmxILPortImpl() |
|
75 { |
|
76 DEBUG_PRINTF(_L8("COmxILPortImpl::~COmxILPortImpl")); |
|
77 |
|
78 #ifdef _DEBUG |
|
79 const TInt headerCount = iBufferHeaders.Count(); |
|
80 if (headerCount > 0) |
|
81 { |
|
82 DEBUG_PRINTF(_L8("COmxILPortImpl::~COmxILPortImpl :: ------------------------------- WARNING --------------------------------------- ")); |
|
83 DEBUG_PRINTF2(_L8("COmxILPortImpl::~COmxILPortImpl :: [%d] Buffer headers still exist"), headerCount); |
|
84 DEBUG_PRINTF(_L8("COmxILPortImpl::~COmxILPortImpl :: CleanUpPort() may be used from the most derived port class to delete them")); |
|
85 DEBUG_PRINTF(_L8("COmxILPortImpl::~COmxILPortImpl :: ------------------------------- WARNING --------------------------------------- ")); |
|
86 } |
|
87 #endif |
|
88 |
|
89 iBufferHeaders.Close(); |
|
90 iBufferMarks.ResetAndDestroy(); |
|
91 |
|
92 } |
|
93 |
|
94 OMX_ERRORTYPE |
|
95 COmxILPortImpl::GetParameter(OMX_INDEXTYPE aParamIndex, |
|
96 TAny* apComponentParameterStructure) const |
|
97 { |
|
98 DEBUG_PRINTF(_L8("COmxILPortImpl::GetParameter")); |
|
99 |
|
100 OMX_ERRORTYPE omxRetValue = OMX_ErrorNone; |
|
101 switch(aParamIndex) |
|
102 { |
|
103 case OMX_IndexParamPortDefinition: |
|
104 { |
|
105 if (OMX_ErrorNone != (omxRetValue = |
|
106 TOmxILUtil::CheckOmxStructSizeAndVersion( |
|
107 apComponentParameterStructure, |
|
108 sizeof(OMX_PARAM_PORTDEFINITIONTYPE)))) |
|
109 { |
|
110 return omxRetValue; |
|
111 } |
|
112 |
|
113 OMX_PARAM_PORTDEFINITIONTYPE* pPortDefinition |
|
114 = static_cast<OMX_PARAM_PORTDEFINITIONTYPE*>( |
|
115 apComponentParameterStructure); |
|
116 |
|
117 *pPortDefinition = iParamPortDefinition; |
|
118 } |
|
119 break; |
|
120 |
|
121 case OMX_IndexParamCompBufferSupplier: |
|
122 { |
|
123 if (OMX_ErrorNone != (omxRetValue = |
|
124 TOmxILUtil::CheckOmxStructSizeAndVersion( |
|
125 apComponentParameterStructure, |
|
126 sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE)))) |
|
127 { |
|
128 return omxRetValue; |
|
129 } |
|
130 |
|
131 OMX_PARAM_BUFFERSUPPLIERTYPE* pBufferSupplier |
|
132 = static_cast<OMX_PARAM_BUFFERSUPPLIERTYPE*>( |
|
133 apComponentParameterStructure); |
|
134 |
|
135 pBufferSupplier->eBufferSupplier = |
|
136 iParamCompBufferSupplier.eBufferSupplier; |
|
137 } |
|
138 break; |
|
139 |
|
140 default: |
|
141 { |
|
142 return OMX_ErrorUnsupportedIndex; |
|
143 } |
|
144 }; |
|
145 |
|
146 return OMX_ErrorNone; |
|
147 |
|
148 } |
|
149 |
|
150 OMX_ERRORTYPE |
|
151 COmxILPortImpl::SetParameter(OMX_INDEXTYPE aParamIndex, |
|
152 const TAny* apComponentParameterStructure, |
|
153 TBool& aUpdateProcessingFunction) |
|
154 { |
|
155 DEBUG_PRINTF(_L8("COmxILPortImpl::SetParameter")); |
|
156 |
|
157 aUpdateProcessingFunction = EFalse; |
|
158 |
|
159 |
|
160 if (OMX_TRUE == aFirstUseBufferHasBeenReceived) |
|
161 { |
|
162 DEBUG_PRINTF2(_L8("COmxILPortImpl::SetParameter : PORT [%u] WARNING : port population already initiated, returning OMX_ErrorIncorrectStateOperation"), Index()); |
|
163 // SetParameter is not allowed after the first OMX_UseBuffer has been |
|
164 // received in the port, that is, the population of the port has |
|
165 // already been initiated... |
|
166 return OMX_ErrorIncorrectStateOperation; |
|
167 } |
|
168 |
|
169 OMX_ERRORTYPE omxRetValue = OMX_ErrorNone; |
|
170 |
|
171 switch(aParamIndex) |
|
172 { |
|
173 case OMX_IndexParamPortDefinition: |
|
174 { |
|
175 if (OMX_ErrorNone != (omxRetValue = |
|
176 TOmxILUtil::CheckOmxStructSizeAndVersion( |
|
177 const_cast<OMX_PTR>(apComponentParameterStructure), |
|
178 sizeof(OMX_PARAM_PORTDEFINITIONTYPE)))) |
|
179 { |
|
180 return omxRetValue; |
|
181 } |
|
182 |
|
183 const OMX_PARAM_PORTDEFINITIONTYPE* pPortDefinition |
|
184 = static_cast<const OMX_PARAM_PORTDEFINITIONTYPE*>( |
|
185 apComponentParameterStructure); |
|
186 |
|
187 // Port Format must be set by the concrete port... |
|
188 if (OMX_ErrorNone != |
|
189 (omxRetValue = |
|
190 iOmxILPort.SetFormatInPortDefinition(*pPortDefinition, |
|
191 aUpdateProcessingFunction))) |
|
192 { |
|
193 return omxRetValue; |
|
194 } |
|
195 |
|
196 // Set here only the additional read-write parameters of |
|
197 // OMX_PARAM_PORTDEFINITIONTYPE |
|
198 if (iParamPortDefinition.nBufferCountActual != |
|
199 pPortDefinition->nBufferCountActual) |
|
200 { |
|
201 if (pPortDefinition->nBufferCountActual < |
|
202 iParamPortDefinition.nBufferCountMin) |
|
203 { |
|
204 return OMX_ErrorBadParameter; |
|
205 } |
|
206 DEBUG_PRINTF3(_L8("COmxILPortImpl::SetParameter : old.nBufferCountActual [%u] new.nBufferCountActual [%u]"), |
|
207 iParamPortDefinition.nBufferCountActual, pPortDefinition->nBufferCountActual); |
|
208 iParamPortDefinition.nBufferCountActual = |
|
209 pPortDefinition->nBufferCountActual; |
|
210 aUpdateProcessingFunction = ETrue; |
|
211 } |
|
212 |
|
213 } |
|
214 break; |
|
215 |
|
216 case OMX_IndexParamCompBufferSupplier: |
|
217 { |
|
218 if (OMX_ErrorNone != (omxRetValue = |
|
219 TOmxILUtil::CheckOmxStructSizeAndVersion( |
|
220 const_cast<OMX_PTR>(apComponentParameterStructure), |
|
221 sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE)))) |
|
222 { |
|
223 return omxRetValue; |
|
224 } |
|
225 |
|
226 const OMX_PARAM_BUFFERSUPPLIERTYPE* pBufferSupplier |
|
227 = static_cast<const OMX_PARAM_BUFFERSUPPLIERTYPE*>( |
|
228 apComponentParameterStructure); |
|
229 |
|
230 // OMX_BufferSupplyOutput is the last of the supported values as of |
|
231 // v1.1.1 |
|
232 if (iParamCompBufferSupplier.eBufferSupplier > OMX_BufferSupplyOutput) |
|
233 { |
|
234 return OMX_ErrorBadParameter; |
|
235 } |
|
236 |
|
237 if (iParamCompBufferSupplier.eBufferSupplier != |
|
238 pBufferSupplier->eBufferSupplier) |
|
239 { |
|
240 // The component providing the input port is responsible for |
|
241 // signalling the tunnelled component about the buffer supplier |
|
242 // override... |
|
243 if (iTunnelledComponent && |
|
244 iParamPortDefinition.eDir == OMX_DirInput) |
|
245 { |
|
246 OMX_PARAM_BUFFERSUPPLIERTYPE bufferSupplierType; |
|
247 bufferSupplierType.nSize = sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE); |
|
248 bufferSupplierType.nVersion = iParamPortDefinition.nVersion; |
|
249 bufferSupplierType.nPortIndex = iTunnelledPort; |
|
250 bufferSupplierType.eBufferSupplier = pBufferSupplier->eBufferSupplier; |
|
251 OMX_ERRORTYPE retValue = OMX_ErrorUndefined; |
|
252 if (OMX_ErrorNone != |
|
253 (retValue = |
|
254 OMX_SetParameter(iTunnelledComponent, |
|
255 OMX_IndexParamCompBufferSupplier, |
|
256 &bufferSupplierType)) ) |
|
257 { |
|
258 return retValue; |
|
259 } |
|
260 } |
|
261 DEBUG_PRINTF3(_L8("COmxILPortImpl::SetParameter : old.eBufferSupplier [%u] new.eBufferSupplier [%u]"), |
|
262 iParamCompBufferSupplier.eBufferSupplier, pBufferSupplier->eBufferSupplier); |
|
263 iParamCompBufferSupplier.eBufferSupplier = |
|
264 pBufferSupplier->eBufferSupplier; |
|
265 } |
|
266 |
|
267 } |
|
268 break; |
|
269 default: |
|
270 { |
|
271 return OMX_ErrorUnsupportedIndex; |
|
272 } |
|
273 }; |
|
274 |
|
275 return OMX_ErrorNone; |
|
276 |
|
277 } |
|
278 |
|
279 OMX_ERRORTYPE |
|
280 COmxILPortImpl::PopulateBuffer(OMX_BUFFERHEADERTYPE** appBufferHdr, |
|
281 const OMX_PTR apAppPrivate, |
|
282 OMX_U32 aSizeBytes, |
|
283 OMX_U8* apBuffer, |
|
284 TBool& portPopulationCompleted) |
|
285 { |
|
286 DEBUG_PRINTF3(_L8("COmxILPort::PopulateBuffer : pBuffer[%X] PORT[%u]"), apBuffer, iParamPortDefinition.nPortIndex); |
|
287 portPopulationCompleted = EFalse; |
|
288 |
|
289 if(aSizeBytes < iParamPortDefinition.nBufferSize) |
|
290 { |
|
291 return OMX_ErrorBadParameter; |
|
292 } |
|
293 |
|
294 // Allocate the buffer header... |
|
295 OMX_BUFFERHEADERTYPE* pHeader = new OMX_BUFFERHEADERTYPE; |
|
296 *appBufferHdr = pHeader; |
|
297 if (!pHeader) |
|
298 { |
|
299 return OMX_ErrorInsufficientResources; |
|
300 } |
|
301 |
|
302 DEBUG_PRINTF2(_L8("COmxILPortImpl::PopulateBuffer : BUFFER [%X]"), pHeader); |
|
303 |
|
304 // Here, lets discriminate between apBuffer == 0 (AllocateBuffer) and |
|
305 // apBuffer != 0 (UseBuffer) |
|
306 TUint8* pPortSpecificBuffer = 0; |
|
307 OMX_PTR pPortPrivate = 0; |
|
308 OMX_PTR pPlatformPrivate = 0; |
|
309 OMX_ERRORTYPE portSpecificErr = OMX_ErrorNone; |
|
310 if (apBuffer) |
|
311 { |
|
312 //... (UseBuffer) Do any port-specific wrapping of the received buffer, |
|
313 // if needed by the port.... |
|
314 portSpecificErr = iOmxILPort.DoBufferWrapping(aSizeBytes, |
|
315 apBuffer, |
|
316 pPortPrivate, |
|
317 pPlatformPrivate, |
|
318 apAppPrivate); |
|
319 |
|
320 aFirstUseBufferHasBeenReceived = OMX_TRUE; |
|
321 } |
|
322 else |
|
323 { |
|
324 // ... (AllocateBuffer) Do the port-specific buffer allocation ... |
|
325 portSpecificErr = iOmxILPort.DoBufferAllocation(aSizeBytes, |
|
326 pPortSpecificBuffer, |
|
327 pPortPrivate, |
|
328 pPlatformPrivate, |
|
329 apAppPrivate); |
|
330 } |
|
331 |
|
332 if (OMX_ErrorNone != portSpecificErr) |
|
333 { |
|
334 delete *appBufferHdr; *appBufferHdr = 0; |
|
335 return portSpecificErr; |
|
336 } |
|
337 |
|
338 |
|
339 // Add to local list of buffer headers... |
|
340 if (KErrNone != |
|
341 iBufferHeaders.Append( |
|
342 TBufferInfo(pHeader, |
|
343 (apBuffer ? |
|
344 TBufferInfo::EBufferAway : |
|
345 TBufferInfo::EBufferAtHome), |
|
346 (apBuffer ? |
|
347 TBufferInfo::EBufferNotOwned : |
|
348 TBufferInfo::EBufferOwned), |
|
349 apBuffer, |
|
350 apAppPrivate, |
|
351 pPlatformPrivate, |
|
352 pPortPrivate))) |
|
353 { |
|
354 // Undo custom buffer allocation/wrapping |
|
355 if (apBuffer) |
|
356 { |
|
357 iOmxILPort.DoBufferUnwrapping( |
|
358 apBuffer, |
|
359 pPortPrivate, |
|
360 pPlatformPrivate, |
|
361 apAppPrivate); |
|
362 |
|
363 } |
|
364 else |
|
365 { |
|
366 iOmxILPort.DoBufferDeallocation( |
|
367 pPortSpecificBuffer, |
|
368 pPortPrivate, |
|
369 pPlatformPrivate, |
|
370 apAppPrivate); |
|
371 } |
|
372 delete *appBufferHdr; *appBufferHdr = NULL; |
|
373 return OMX_ErrorInsufficientResources; |
|
374 } |
|
375 |
|
376 |
|
377 // Fill in the header... |
|
378 pHeader->nSize = sizeof(OMX_BUFFERHEADERTYPE); |
|
379 pHeader->nVersion = iParamPortDefinition.nVersion; |
|
380 pHeader->pBuffer = apBuffer ? apBuffer : pPortSpecificBuffer; |
|
381 pHeader->nAllocLen = aSizeBytes; |
|
382 pHeader->nFilledLen = 0; |
|
383 pHeader->nOffset = 0; |
|
384 pHeader->pAppPrivate = apAppPrivate; |
|
385 pHeader->pPlatformPrivate = pPlatformPrivate; |
|
386 pHeader->hMarkTargetComponent = 0; |
|
387 pHeader->pMarkData = 0; |
|
388 pHeader->nTickCount = 0; |
|
389 pHeader->nTimeStamp = 0; |
|
390 pHeader->nFlags = 0; |
|
391 |
|
392 |
|
393 if (OMX_DirInput == iParamPortDefinition.eDir) |
|
394 { |
|
395 pHeader->pInputPortPrivate = pPortPrivate; |
|
396 pHeader->pOutputPortPrivate = 0; |
|
397 pHeader->nInputPortIndex = iParamPortDefinition.nPortIndex; |
|
398 pHeader->nOutputPortIndex = 0; |
|
399 } |
|
400 else |
|
401 { |
|
402 pHeader->pInputPortPrivate = 0; |
|
403 pHeader->pOutputPortPrivate = pPortPrivate; |
|
404 pHeader->nInputPortIndex = 0; |
|
405 pHeader->nOutputPortIndex = iParamPortDefinition.nPortIndex; |
|
406 } |
|
407 |
|
408 if (iParamPortDefinition.nBufferCountActual == iBufferHeaders.Count()) |
|
409 { |
|
410 iParamPortDefinition.bPopulated = OMX_TRUE; |
|
411 portPopulationCompleted = ETrue; |
|
412 } |
|
413 |
|
414 return OMX_ErrorNone; |
|
415 |
|
416 } |
|
417 |
|
418 |
|
419 OMX_ERRORTYPE |
|
420 COmxILPortImpl::FreeBuffer(OMX_BUFFERHEADERTYPE* apBufferHeader, |
|
421 TBool& portDepopulationCompleted) |
|
422 { |
|
423 DEBUG_PRINTF2(_L8("COmxILPortImpl::FreeBuffer : BUFFER [%X]"), apBufferHeader); |
|
424 |
|
425 portDepopulationCompleted = EFalse; |
|
426 |
|
427 TInt headerIndex = 0; |
|
428 if (KErrNotFound == |
|
429 (headerIndex = |
|
430 iBufferHeaders.Find(TBufferInfo(apBufferHeader), |
|
431 TIdentityRelation<TBufferInfo>( |
|
432 &TBufferInfo::Compare)))) |
|
433 { |
|
434 return OMX_ErrorBadParameter; |
|
435 } |
|
436 |
|
437 |
|
438 OMX_PTR pPortPrivate = |
|
439 OMX_DirInput == iParamPortDefinition.eDir ? |
|
440 apBufferHeader->pInputPortPrivate : |
|
441 apBufferHeader->pOutputPortPrivate; |
|
442 |
|
443 if (iBufferHeaders[headerIndex].IsBufferOwned()) |
|
444 { |
|
445 iOmxILPort.DoBufferDeallocation( |
|
446 apBufferHeader->pBuffer, |
|
447 pPortPrivate, |
|
448 apBufferHeader->pPlatformPrivate, |
|
449 apBufferHeader->pAppPrivate); |
|
450 } |
|
451 else |
|
452 { |
|
453 iOmxILPort.DoBufferUnwrapping( |
|
454 apBufferHeader->pBuffer, |
|
455 pPortPrivate, |
|
456 apBufferHeader->pPlatformPrivate, |
|
457 apBufferHeader->pAppPrivate); |
|
458 } |
|
459 |
|
460 delete apBufferHeader; |
|
461 iBufferHeaders.Remove(headerIndex); |
|
462 |
|
463 if (iBufferHeaders.Count() < iParamPortDefinition.nBufferCountActual) |
|
464 { |
|
465 iParamPortDefinition.bPopulated = OMX_FALSE; |
|
466 } |
|
467 |
|
468 if (0 == iBufferHeaders.Count()) |
|
469 { |
|
470 portDepopulationCompleted = ETrue; |
|
471 aFirstUseBufferHasBeenReceived = OMX_FALSE; |
|
472 } |
|
473 |
|
474 return OMX_ErrorNone; |
|
475 |
|
476 } |
|
477 |
|
478 |
|
479 OMX_ERRORTYPE |
|
480 COmxILPortImpl::TunnelRequest(OMX_HANDLETYPE aTunneledComp, |
|
481 OMX_U32 aTunneledPort, |
|
482 OMX_TUNNELSETUPTYPE* apTunnelSetup) |
|
483 { |
|
484 DEBUG_PRINTF(_L8("COmxILPortImpl::TunnelRequest")); |
|
485 |
|
486 // Check whether the tunnel is being torn down |
|
487 if (!aTunneledComp) |
|
488 { |
|
489 // Cancel existing tunnel setup, if any |
|
490 iTunnelledComponent = 0; |
|
491 return OMX_ErrorNone; |
|
492 } |
|
493 |
|
494 // Check that we are receiving a valid tunnel setup structure |
|
495 if (!apTunnelSetup) |
|
496 { |
|
497 return OMX_ErrorBadParameter; |
|
498 } |
|
499 |
|
500 // STEP 0: Retrieve the port definition from the tunnelled component... |
|
501 OMX_PARAM_PORTDEFINITIONTYPE paramPortDef; |
|
502 paramPortDef.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); |
|
503 paramPortDef.nVersion = iParamPortDefinition.nVersion; |
|
504 paramPortDef.nPortIndex = aTunneledPort; |
|
505 if (OMX_ErrorNone != |
|
506 OMX_GetParameter(aTunneledComp, |
|
507 OMX_IndexParamPortDefinition, |
|
508 ¶mPortDef) ) |
|
509 { |
|
510 return OMX_ErrorUndefined; |
|
511 } |
|
512 |
|
513 if (OMX_DirOutput == iParamPortDefinition.eDir) |
|
514 { |
|
515 // OMX_DirOutput |
|
516 // |
|
517 |
|
518 // Step 1: Check that this output port is being tunnelled to an input |
|
519 // port... |
|
520 if (paramPortDef.eDir != OMX_DirInput) |
|
521 { |
|
522 return OMX_ErrorPortsNotCompatible; |
|
523 } |
|
524 |
|
525 // Step 2: Fill in the tunnel setup structure received... |
|
526 apTunnelSetup->nTunnelFlags = 0; |
|
527 apTunnelSetup->eSupplier = iParamCompBufferSupplier.eBufferSupplier; |
|
528 |
|
529 iTunnelledComponent = aTunneledComp; |
|
530 iTunnelledPort = aTunneledPort; |
|
531 } |
|
532 else |
|
533 { |
|
534 // OMX_DirInput |
|
535 // |
|
536 |
|
537 // Check that this input port is being tunnelled to an output |
|
538 // port... |
|
539 if (paramPortDef.eDir != OMX_DirOutput) |
|
540 { |
|
541 return OMX_ErrorPortsNotCompatible; |
|
542 } |
|
543 |
|
544 // Check that there is something consistent in the tunnel setup data |
|
545 // received... |
|
546 if ((apTunnelSetup->eSupplier != OMX_BufferSupplyUnspecified) && |
|
547 (apTunnelSetup->eSupplier != OMX_BufferSupplyInput) && |
|
548 (apTunnelSetup->eSupplier != OMX_BufferSupplyOutput)) |
|
549 { |
|
550 return OMX_ErrorBadParameter; |
|
551 } |
|
552 |
|
553 // Set tunnelled component and port as they will be needed by |
|
554 // IsTunnelledPortCompatible... |
|
555 iTunnelledComponent = aTunneledComp; |
|
556 iTunnelledPort = aTunneledPort; |
|
557 |
|
558 // Check domain-specific parameter compatibility (this is delegated |
|
559 // to derived port classes)... |
|
560 if (!iOmxILPort.IsTunnelledPortCompatible(paramPortDef)) |
|
561 { |
|
562 iTunnelledComponent = 0; |
|
563 return OMX_ErrorPortsNotCompatible; |
|
564 } |
|
565 |
|
566 // Now, try to get to an understanding here...Work out which port will |
|
567 // be buffer supplier... |
|
568 OMX_BUFFERSUPPLIERTYPE bufferSupplierDecision = |
|
569 OMX_BufferSupplyUnspecified; |
|
570 if (apTunnelSetup->nTunnelFlags & OMX_PORTTUNNELFLAG_READONLY || |
|
571 ( (apTunnelSetup->eSupplier == OMX_BufferSupplyInput) && |
|
572 (iParamCompBufferSupplier.eBufferSupplier == |
|
573 OMX_BufferSupplyInput || |
|
574 iParamCompBufferSupplier.eBufferSupplier == |
|
575 OMX_BufferSupplyUnspecified) ) || |
|
576 ( (apTunnelSetup->eSupplier == OMX_BufferSupplyUnspecified) && |
|
577 (iParamCompBufferSupplier.eBufferSupplier == |
|
578 OMX_BufferSupplyInput)) ) |
|
579 { |
|
580 bufferSupplierDecision = OMX_BufferSupplyInput; |
|
581 } |
|
582 else |
|
583 { |
|
584 bufferSupplierDecision = OMX_BufferSupplyOutput; |
|
585 } |
|
586 |
|
587 // Set buffer supplier param in tunnelled port... |
|
588 OMX_PARAM_BUFFERSUPPLIERTYPE bufferSupplierType; |
|
589 bufferSupplierType.nSize = sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE); |
|
590 bufferSupplierType.nVersion = iParamPortDefinition.nVersion; |
|
591 bufferSupplierType.nPortIndex = aTunneledPort; |
|
592 bufferSupplierType.eBufferSupplier = bufferSupplierDecision; |
|
593 if (OMX_ErrorNone != |
|
594 OMX_SetParameter(aTunneledComp, |
|
595 OMX_IndexParamCompBufferSupplier, |
|
596 &bufferSupplierType) ) |
|
597 { |
|
598 iTunnelledComponent = 0; |
|
599 return OMX_ErrorPortsNotCompatible; |
|
600 } |
|
601 |
|
602 apTunnelSetup->eSupplier = bufferSupplierDecision; |
|
603 iParamCompBufferSupplier.eBufferSupplier = bufferSupplierDecision; |
|
604 |
|
605 } |
|
606 |
|
607 return OMX_ErrorNone; |
|
608 |
|
609 } |
|
610 |
|
611 |
|
612 OMX_ERRORTYPE |
|
613 COmxILPortImpl::PopulateTunnel(TBool& portPopulationCompleted) |
|
614 { |
|
615 DEBUG_PRINTF(_L8("COmxILPortImpl::PopulateTunnel")); |
|
616 |
|
617 __ASSERT_DEBUG(iBufferHeaders.Count() == 0, |
|
618 User::Panic(KOmxILPortPanicCategory, 1)); |
|
619 __ASSERT_DEBUG(IsTunnelledAndBufferSupplier(), |
|
620 User::Panic(KOmxILPortPanicCategory, 1)); |
|
621 |
|
622 portPopulationCompleted = EFalse; |
|
623 |
|
624 // STEP 1: Obtain the number of buffers that the tunnelled port requires to |
|
625 // be populated... Retrieve the port definition from the tunnelled |
|
626 // component |
|
627 OMX_PARAM_PORTDEFINITIONTYPE paramPortDef; |
|
628 paramPortDef.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); |
|
629 paramPortDef.nVersion = iParamPortDefinition.nVersion; |
|
630 paramPortDef.nPortIndex = iTunnelledPort; |
|
631 if (OMX_ErrorNone != |
|
632 OMX_GetParameter(iTunnelledComponent, |
|
633 OMX_IndexParamPortDefinition, |
|
634 ¶mPortDef) ) |
|
635 { |
|
636 return OMX_ErrorUndefined; |
|
637 } |
|
638 |
|
639 // Step 2: Both ports must have the same threshold value (number of buffers |
|
640 // to be populated) before completing the transition to |
|
641 // OMX_StateIdle...Otherwise the population process would complete earlier |
|
642 // or never... |
|
643 TUint numOfBuffersToPopulate = iParamPortDefinition.nBufferCountActual; |
|
644 if(paramPortDef.nBufferCountActual != |
|
645 iParamPortDefinition.nBufferCountActual) |
|
646 { |
|
647 numOfBuffersToPopulate = |
|
648 Max(iParamPortDefinition.nBufferCountActual, |
|
649 paramPortDef.nBufferCountActual); |
|
650 if (iParamPortDefinition.nBufferCountActual < |
|
651 numOfBuffersToPopulate) |
|
652 { |
|
653 // Update own buffer count requirements |
|
654 DEBUG_PRINTF3(_L8("COmxILPortImpl::PopulateTunnel : Updated own nBufferCountActual - Old Value [%d] New Value [%d] "), |
|
655 iParamPortDefinition.nBufferCountActual, numOfBuffersToPopulate); |
|
656 iParamPortDefinition.nBufferCountActual = numOfBuffersToPopulate; |
|
657 } |
|
658 else |
|
659 { |
|
660 // Update peer's buffer count requirements |
|
661 DEBUG_PRINTF3(_L8("COmxILPortImpl::PopulateTunnel : Updated peer's nBufferCountActual - Old Value [%d] New Value [%d] "), |
|
662 paramPortDef.nBufferCountActual, numOfBuffersToPopulate); |
|
663 paramPortDef.nBufferCountActual = numOfBuffersToPopulate; |
|
664 if (OMX_ErrorNone != OMX_SetParameter(iTunnelledComponent, |
|
665 OMX_IndexParamPortDefinition, |
|
666 ¶mPortDef)) |
|
667 { |
|
668 DEBUG_PRINTF(_L8("COmxILPortImpl::PopulateTunnel : Error setting nBufferCountActual in tunnelled component ")); |
|
669 return OMX_ErrorUndefined; |
|
670 } |
|
671 } |
|
672 } |
|
673 |
|
674 // STEP 3: Start population of the tunnel... |
|
675 TUint sizeOfBuffersToPopulate = |
|
676 iParamPortDefinition.nBufferSize >= paramPortDef.nBufferSize ? |
|
677 iParamPortDefinition.nBufferSize : |
|
678 paramPortDef.nBufferSize; |
|
679 |
|
680 OMX_BUFFERHEADERTYPE* pHeader = 0; |
|
681 TUint8* pPortSpecificBuffer = 0; |
|
682 OMX_PTR pPortPrivate = 0; |
|
683 OMX_PTR pPlatformPrivate = 0; |
|
684 OMX_ERRORTYPE portSpecificErr = OMX_ErrorNone; |
|
685 for (TUint i=0; i<numOfBuffersToPopulate; i++) |
|
686 { |
|
687 // Allocate the buffer... |
|
688 if (OMX_ErrorNone != |
|
689 (portSpecificErr = iOmxILPort.DoBufferAllocation( |
|
690 sizeOfBuffersToPopulate, |
|
691 pPortSpecificBuffer, |
|
692 pPortPrivate, |
|
693 pPlatformPrivate))) |
|
694 { |
|
695 // There's no point on continuing here... the tunnel will never |
|
696 // be completely populated now... |
|
697 return portSpecificErr; |
|
698 } |
|
699 |
|
700 OMX_ERRORTYPE useBufRes = iOmxILPort.DoOmxUseBuffer(iTunnelledComponent, |
|
701 &pHeader, |
|
702 iTunnelledPort, |
|
703 pPortPrivate, |
|
704 pPlatformPrivate, |
|
705 sizeOfBuffersToPopulate, |
|
706 pPortSpecificBuffer); |
|
707 |
|
708 if ((OMX_ErrorNone != useBufRes) || !pHeader) |
|
709 { |
|
710 iOmxILPort.DoBufferDeallocation( |
|
711 pPortSpecificBuffer, |
|
712 pPortPrivate, |
|
713 pPlatformPrivate); |
|
714 |
|
715 if (pHeader) |
|
716 { |
|
717 switch(useBufRes) |
|
718 { |
|
719 case OMX_ErrorIncorrectStateOperation: |
|
720 { |
|
721 // Here, the tunnelled component is not ready. Probably, |
|
722 // the IL Client has not commanded yet the component to go |
|
723 // to OMX_StateIdle. Out-of-context implementations could |
|
724 // do here a backoff-and-retry procedure. This |
|
725 // implementation can just return and expect that the IL |
|
726 // Client will detect the situation of this component not |
|
727 // transitioning to OMX_StateIdle. |
|
728 DEBUG_PRINTF(_L8("COmxILPortImpl::PopulateTunnel : OMX_ErrorIncorrectStateOperation received from non-supplier component")); |
|
729 } |
|
730 break; |
|
731 }; |
|
732 } |
|
733 |
|
734 if (OMX_ErrorInsufficientResources == useBufRes) |
|
735 { |
|
736 return OMX_ErrorInsufficientResources; |
|
737 } |
|
738 // This is a gotcha. Here there is some problem with the tunnelled |
|
739 // component. If we return the received error, this component may |
|
740 // be sending back some error code that is not allowed in |
|
741 // OMX_SendCommand. Example: The component conformance suite |
|
742 // expects here OMX_ErrorNone if the tunnelled component does not |
|
743 // support OMX_UseBuffer or some other problem. Also, we don't send |
|
744 // and error event here as there's no appropriate error for this |
|
745 // situation (OMX_ErrorPortUnresponsiveDuringAllocation is for |
|
746 // non-supplier ports). Therefore, the IL Client should recover |
|
747 // from this situation after some time by detecting that this |
|
748 // component didn't transition to OMX_StateIdle. |
|
749 |
|
750 return OMX_ErrorNone; |
|
751 } |
|
752 // Fill the data in the received header so we can correctly use it when |
|
753 // the header is at this side of the tunnel... |
|
754 if (OMX_DirInput == iParamPortDefinition.eDir) |
|
755 { |
|
756 pHeader->pInputPortPrivate = pPortPrivate; |
|
757 pHeader->nInputPortIndex = iParamPortDefinition.nPortIndex; |
|
758 } |
|
759 else // OMX_DirOutput == iParamPortDefinition.eDir |
|
760 { |
|
761 pHeader->pOutputPortPrivate = pPortPrivate; |
|
762 pHeader->nOutputPortIndex = iParamPortDefinition.nPortIndex; |
|
763 } |
|
764 |
|
765 // Add to local list of buffer headers... return if not sucessful... |
|
766 if (KErrNone != |
|
767 iBufferHeaders.Append( |
|
768 TBufferInfo(pHeader, |
|
769 TBufferInfo::EBufferAtHome, |
|
770 TBufferInfo::EBufferOwned, |
|
771 pPortSpecificBuffer, |
|
772 0, |
|
773 pPlatformPrivate, |
|
774 pPortPrivate))) |
|
775 { |
|
776 iOmxILPort.DoBufferDeallocation( |
|
777 pPortSpecificBuffer, |
|
778 pPortPrivate, |
|
779 pPlatformPrivate); |
|
780 |
|
781 return OMX_ErrorInsufficientResources; |
|
782 } |
|
783 } |
|
784 |
|
785 iParamPortDefinition.bPopulated = OMX_TRUE; |
|
786 portPopulationCompleted = ETrue; |
|
787 |
|
788 __ASSERT_DEBUG(iBufferHeaders.Count() == |
|
789 iParamPortDefinition.nBufferCountActual, |
|
790 User::Panic(KOmxILPortPanicCategory, 1)); |
|
791 |
|
792 return OMX_ErrorNone; |
|
793 |
|
794 } |
|
795 |
|
796 |
|
797 OMX_ERRORTYPE |
|
798 COmxILPortImpl::FreeTunnel(TBool& portDepopulationCompleted) |
|
799 { |
|
800 DEBUG_PRINTF(_L8("COmxILPortImpl::FreeTunnel")); |
|
801 |
|
802 __ASSERT_DEBUG(iBufferHeaders.Count() == |
|
803 iParamPortDefinition.nBufferCountActual, |
|
804 User::Panic(KOmxILPortPanicCategory, 1)); |
|
805 |
|
806 __ASSERT_DEBUG(IsTunnelledAndBufferSupplier(), |
|
807 User::Panic(KOmxILPortPanicCategory, 1)); |
|
808 |
|
809 const TUint numBuffersToDepopulate = iBufferHeaders.Count(); |
|
810 for (TUint i=0; i<numBuffersToDepopulate; ++i) |
|
811 { |
|
812 OMX_BUFFERHEADERTYPE* pBufferHeader = iBufferHeaders[i].GetHeader(); |
|
813 |
|
814 // Take some things from the header, before it gets deleted by the |
|
815 // tunnelled port... |
|
816 OMX_U8* pBuffer = pBufferHeader->pBuffer; |
|
817 OMX_PTR pPortPrivate = |
|
818 OMX_DirInput == iParamPortDefinition.eDir ? |
|
819 pBufferHeader->pInputPortPrivate : |
|
820 pBufferHeader->pOutputPortPrivate; |
|
821 OMX_PTR pAppPrivate = pBufferHeader->pAppPrivate; |
|
822 OMX_PTR pPlatformPrivate = pBufferHeader->pPlatformPrivate; |
|
823 |
|
824 DEBUG_PRINTF2(_L8("COmxILPortImpl::FreeTunnel : BUFFER [%X]"), iBufferHeaders[i].GetHeader()); |
|
825 |
|
826 OMX_ERRORTYPE freeBufRes = OMX_FreeBuffer( |
|
827 iTunnelledComponent, |
|
828 iTunnelledPort, |
|
829 pBufferHeader); |
|
830 |
|
831 // At this point, the actual buffer header should no longer exist... |
|
832 pBufferHeader = 0; |
|
833 |
|
834 // NOTE that we don't check OMX_FreeBuffer returned error here. If |
|
835 // something wrong happens at the tunnelled component side we'll |
|
836 // continue here and try to free as many buffers as possible.... at |
|
837 // least the state of this component will remain valid.... (we don't |
|
838 // report errors coming from the tunnelled component as that is its |
|
839 // responsibility....) |
|
840 |
|
841 iOmxILPort.DoBufferDeallocation( |
|
842 pBuffer, |
|
843 pPortPrivate, |
|
844 pPlatformPrivate, |
|
845 pAppPrivate); |
|
846 } |
|
847 |
|
848 // Clear the local list of headers. Note that there's no need to delete the |
|
849 // header as these have been allocated by the tunnelled port... |
|
850 |
|
851 iBufferHeaders.Reset(); |
|
852 iParamPortDefinition.bPopulated = OMX_FALSE; |
|
853 portDepopulationCompleted = ETrue; |
|
854 |
|
855 __ASSERT_DEBUG(iBufferHeaders.Count() == 0, |
|
856 User::Panic(KOmxILPortPanicCategory, 1)); |
|
857 |
|
858 return OMX_ErrorNone; |
|
859 |
|
860 } |
|
861 |
|
862 |
|
863 |
|
864 TBool |
|
865 COmxILPortImpl::SetBufferSent(OMX_BUFFERHEADERTYPE* apBufferHeader, |
|
866 TBool& aBufferMarkedWithOwnMark) |
|
867 { |
|
868 DEBUG_PRINTF(_L8("COmxILPortImpl::SetBufferSent")); |
|
869 |
|
870 __ASSERT_DEBUG(apBufferHeader, User::Panic(KOmxILPortPanicCategory, 1)); |
|
871 |
|
872 aBufferMarkedWithOwnMark = EFalse; |
|
873 |
|
874 TInt index = 0; |
|
875 if (KErrNotFound == |
|
876 (index = |
|
877 iBufferHeaders.Find(TBufferInfo(apBufferHeader), |
|
878 TIdentityRelation<TBufferInfo>( |
|
879 &TBufferInfo::Compare)))) |
|
880 { |
|
881 return EFalse; |
|
882 } |
|
883 |
|
884 iBufferHeaders[index].SetBufferAway(); |
|
885 |
|
886 if (!iBufferMarks.IsEmpty()) |
|
887 { |
|
888 // Check for existing marks in the buffer header... |
|
889 if (apBufferHeader->hMarkTargetComponent) |
|
890 { |
|
891 // We queue the mark received within the buffer header if there are |
|
892 // marks already to be delivered... it is mandatory to give a FIFO |
|
893 // preference to the marks received by a port.. |
|
894 if (iBufferMarks.Elements() < KMaxBufferMarksQueueSize) |
|
895 { |
|
896 // The buffer is marked already. Store the current mark at the end |
|
897 // of the buffer mark list... |
|
898 StoreBufferMark(apBufferHeader->hMarkTargetComponent, |
|
899 apBufferHeader->pMarkData); |
|
900 } |
|
901 } |
|
902 |
|
903 // Use the first mark in the queue... |
|
904 TBufferMarkInfo* pMark = iBufferMarks.First(); |
|
905 apBufferHeader->hMarkTargetComponent = pMark->ipMarkTargetComponent; |
|
906 apBufferHeader->pMarkData = pMark->ipMarkData; |
|
907 aBufferMarkedWithOwnMark = pMark->iOwnMark; |
|
908 iBufferMarks.Remove(*pMark); |
|
909 delete pMark; |
|
910 } |
|
911 |
|
912 return ETrue; |
|
913 |
|
914 } |
|
915 |
|
916 TBool |
|
917 COmxILPortImpl::SetBufferReturned(OMX_BUFFERHEADERTYPE* apBufferHeader) |
|
918 { |
|
919 DEBUG_PRINTF(_L8("COmxILPortImpl::SetBufferReturned")); |
|
920 |
|
921 __ASSERT_DEBUG(apBufferHeader, User::Panic(KOmxILPortPanicCategory, 1)); |
|
922 |
|
923 TInt index = 0; |
|
924 if (KErrNotFound == |
|
925 (index = |
|
926 iBufferHeaders.Find(TBufferInfo(apBufferHeader), |
|
927 TIdentityRelation<TBufferInfo>( |
|
928 &TBufferInfo::Compare)))) |
|
929 { |
|
930 return EFalse; |
|
931 } |
|
932 |
|
933 iBufferHeaders[index].SetBufferAtHome(); |
|
934 |
|
935 return ETrue; |
|
936 |
|
937 } |
|
938 |
|
939 void |
|
940 COmxILPortImpl::SetTransitionToEnabled() |
|
941 { |
|
942 DEBUG_PRINTF(_L8("COmxILPortImpl::SetTransitionToEnabled")); |
|
943 |
|
944 iTransitionState = EPortTransitioningToEnabled; |
|
945 iParamPortDefinition.bEnabled = OMX_TRUE; |
|
946 |
|
947 } |
|
948 |
|
949 void |
|
950 COmxILPortImpl::SetTransitionToDisabled() |
|
951 { |
|
952 DEBUG_PRINTF(_L8("COmxILPortImpl::SetTransitionToDisabled")); |
|
953 |
|
954 iTransitionState = EPortTransitioningToDisabled; |
|
955 iParamPortDefinition.bEnabled = OMX_FALSE; |
|
956 |
|
957 } |
|
958 |
|
959 void |
|
960 COmxILPortImpl::SetTransitionToDisabledCompleted() |
|
961 { |
|
962 DEBUG_PRINTF(_L8("COmxILPortImpl::SetTransitionToDisabledCompleted")); |
|
963 |
|
964 iTransitionState = EPortNotTransitioning; |
|
965 iParamPortDefinition.bEnabled = OMX_FALSE; |
|
966 |
|
967 } |
|
968 |
|
969 void |
|
970 COmxILPortImpl::SetTransitionToEnabledCompleted() |
|
971 { |
|
972 DEBUG_PRINTF(_L8("COmxILPortImpl::SetTransitionToEnabledCompleted")); |
|
973 |
|
974 iTransitionState = EPortNotTransitioning; |
|
975 iParamPortDefinition.bEnabled = OMX_TRUE; |
|
976 |
|
977 } |
|
978 |
|
979 OMX_ERRORTYPE |
|
980 COmxILPortImpl::StoreBufferMark(const OMX_MARKTYPE* apMark) |
|
981 { |
|
982 DEBUG_PRINTF(_L8("COmxILPortImpl::StoreBufferMark")); |
|
983 TBufferMarkInfo* pTBufferMarkInfo = new TBufferMarkInfo(apMark); |
|
984 if (!pTBufferMarkInfo) |
|
985 { |
|
986 return OMX_ErrorInsufficientResources; |
|
987 } |
|
988 |
|
989 iBufferMarks.AddLast(*pTBufferMarkInfo); |
|
990 |
|
991 return OMX_ErrorNone; |
|
992 |
|
993 } |
|
994 |
|
995 /** |
|
996 This utility method may be called from the most derived port |
|
997 class' destructor to delete any buffer header and or buffer that may remain |
|
998 allocated in the port. This typically happens when the component is unloaded |
|
999 without being properly transitioned from OMX_StateIdle to OMX_StateLoaded. |
|
1000 |
|
1001 */ |
|
1002 void |
|
1003 COmxILPortImpl::CleanUpPort() |
|
1004 { |
|
1005 |
|
1006 // Do the clean-up here in case something went wrong and the component is |
|
1007 // being unloaded in a failure scenario... |
|
1008 const TInt headerCount = iBufferHeaders.Count(); |
|
1009 if (headerCount > 0) |
|
1010 { |
|
1011 if (!IsTunnelled()) |
|
1012 { |
|
1013 // A non-tunnelled port needs to delete always the header and needs |
|
1014 // to deallocate/unwrap the buffer depending on whether the buffer |
|
1015 // is owned or not... |
|
1016 |
|
1017 RPointerArray<OMX_BUFFERHEADERTYPE> tempHeadersArray; |
|
1018 for (TInt i=0; i<headerCount; ++i) |
|
1019 { |
|
1020 tempHeadersArray.Append(iBufferHeaders[i].GetHeader()); |
|
1021 } |
|
1022 |
|
1023 TBool portDepopulationCompleted = EFalse; |
|
1024 for (TInt i=0; i<headerCount; ++i) |
|
1025 { |
|
1026 // Errors are ignored here ... |
|
1027 FreeBuffer(tempHeadersArray[i], portDepopulationCompleted); |
|
1028 } |
|
1029 tempHeadersArray.Close(); |
|
1030 |
|
1031 } |
|
1032 else |
|
1033 { |
|
1034 if (IsTunnelledAndBufferSupplier()) |
|
1035 { |
|
1036 // A tunnelled supplier only needs to delete the buffers, not |
|
1037 // the buffer headers... Also, we cannot use the pointer to the |
|
1038 // buffer header, as it may not exist anymore... |
|
1039 for (TInt i=0; i<headerCount; ++i) |
|
1040 { |
|
1041 iOmxILPort.DoBufferDeallocation( |
|
1042 iBufferHeaders[i].GetBufferPointer(), |
|
1043 iBufferHeaders[i].GetPortPointer(), |
|
1044 iBufferHeaders[i].GetPlatformPointer(), |
|
1045 iBufferHeaders[i].GetAppPointer()); |
|
1046 } |
|
1047 |
|
1048 } |
|
1049 else |
|
1050 { |
|
1051 // A tunnelled non-supplier needs to remove buffer headers and |
|
1052 // undo the buffer wrapping, if any. We can use FreeBuffer for |
|
1053 // that purpose... |
|
1054 RPointerArray<OMX_BUFFERHEADERTYPE> tempHeadersArray; |
|
1055 for (TInt i=0; i<headerCount; ++i) |
|
1056 { |
|
1057 tempHeadersArray.Append(iBufferHeaders[i].GetHeader()); |
|
1058 } |
|
1059 |
|
1060 TBool portDepopulationCompleted = EFalse; |
|
1061 for (TInt i=0; i<headerCount; ++i) |
|
1062 { |
|
1063 // errors here... |
|
1064 FreeBuffer(tempHeadersArray[i], portDepopulationCompleted); |
|
1065 } |
|
1066 tempHeadersArray.Close(); |
|
1067 } |
|
1068 } |
|
1069 } |
|
1070 |
|
1071 } |
|
1072 |
|
1073 |
|
1074 OMX_ERRORTYPE |
|
1075 COmxILPortImpl::StoreBufferMark(OMX_HANDLETYPE& ipMarkTargetComponent, |
|
1076 OMX_PTR& ipMarkData) |
|
1077 { |
|
1078 DEBUG_PRINTF(_L8("COmxILPortImpl::StoreBufferMark")); |
|
1079 |
|
1080 TBufferMarkInfo* pTBufferMarkInfo = |
|
1081 new TBufferMarkInfo(ipMarkTargetComponent, |
|
1082 ipMarkData, EFalse); |
|
1083 if (!pTBufferMarkInfo) |
|
1084 { |
|
1085 return OMX_ErrorInsufficientResources; |
|
1086 } |
|
1087 |
|
1088 iBufferMarks.AddLast(*pTBufferMarkInfo); |
|
1089 |
|
1090 return OMX_ErrorNone; |
|
1091 |
|
1092 } |
|
1093 |
|
1094 TBool |
|
1095 COmxILPortImpl::HasAllBuffersAtHome() const |
|
1096 { |
|
1097 |
|
1098 __ASSERT_ALWAYS(IsTunnelledAndBufferSupplier(), |
|
1099 User::Panic(KOmxILPortPanicCategory, 1)); |
|
1100 |
|
1101 const TInt headerCount = iBufferHeaders.Count(); |
|
1102 for (TInt i=0; i<headerCount; ++i) |
|
1103 { |
|
1104 if (!iBufferHeaders[i].IsBufferAtHome()) |
|
1105 { |
|
1106 DEBUG_PRINTF(_L8("COmxILPortImpl::HasAllBuffersAtHome : [NO]")); |
|
1107 return EFalse; |
|
1108 } |
|
1109 } |
|
1110 |
|
1111 DEBUG_PRINTF(_L8("COmxILPortImpl::HasAllBuffersAtHome : [YES]")); |
|
1112 return ETrue; |
|
1113 |
|
1114 } |
|
1115 |
|
1116 TBool |
|
1117 COmxILPortImpl::IsBufferAtHome(OMX_BUFFERHEADERTYPE* apBufferHeader) const |
|
1118 { |
|
1119 DEBUG_PRINTF2(_L8("COmxILPortImpl::IsBufferAtHome : [%X]"), apBufferHeader); |
|
1120 |
|
1121 TInt headerIndex = 0; |
|
1122 if (KErrNotFound == |
|
1123 (headerIndex = |
|
1124 iBufferHeaders.Find(TBufferInfo(apBufferHeader), |
|
1125 TIdentityRelation<TBufferInfo>( |
|
1126 &TBufferInfo::Compare)))) |
|
1127 { |
|
1128 User::Panic(KOmxILPortPanicCategory, 1); |
|
1129 } |
|
1130 |
|
1131 DEBUG_PRINTF2(_L8("COmxILPortImpl::IsBufferAtHome : [%s]"), iBufferHeaders[headerIndex].IsBufferAtHome() ? "YES" : "NO"); |
|
1132 |
|
1133 return iBufferHeaders[headerIndex].IsBufferAtHome(); |
|
1134 |
|
1135 } |
|
1136 |
|
1137 TBool |
|
1138 COmxILPortImpl::TBufferInfo::Compare(const TBufferInfo& aBi1, |
|
1139 const TBufferInfo& aBi2) |
|
1140 { |
|
1141 return (aBi1.GetHeader() == aBi2.GetHeader() ? ETrue : EFalse); |
|
1142 } |