1
2 /*
3 * Copyright (C) Texas Instruments - http://www.ti.com/
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21 /* =============================================================================
22 * Texas Instruments OMAP (TM) Platform Software
23 * (c) Copyright Texas Instruments, Incorporated. All Rights Reserved.
24 *
25 * Use of this software is controlled by the terms and conditions found
26 * in the license agreement under which this software has been supplied.
27 * =========================================================================== */
28 /**
29 * @file OMX_VPP_Utils.c
30 *
31 * This file implements OMX Component for PCM decoder that
32 * is fully compliant with the OMX specification 1.1.
33 *
34 * @path $(CSLPATH)\
35 *
36 * @rev 1.0
37 */
38 /* ----------------------------------------------------------------------------
39 *!
40 *! Revision History
41 *! ===================================
42 *! 13-Dec-2005 mf: Initial Version. Change required per OMAPSWxxxxxxxxx
43 *! to provide _________________.
44 *!
45 *!
46 *! 13-Dec-2005 mf:
47 *! This is newest file
48 * =========================================================================== */
49
50
51 /* ------compilation control switches -------------------------*/
52 /****************************************************************
53 * INCLUDE FILES
54 ****************************************************************/
55 /* ----- system and platform files ----------------------------*/
56
57 #ifdef UNDER_CE
58 #include <windows.h>
59 #include <oaf_osal.h>
60 #include <omx_core.h>
61 #include <stdlib.h>
62 #else
63 #include <unistd.h>
64 #include <sys/types.h>
65 #include <malloc.h>
66 #include <memory.h>
67 #include <sys/types.h>
68 #include <sys/stat.h>
69 #include <fcntl.h>
70 #include <dlfcn.h>
71 #include <sched.h>
72 #include <pthread.h>
73 #endif
74
75 #include <dbapi.h>
76 #include <string.h>
77 #include <stdio.h>
78
79
80 #include "LCML_DspCodec.h"
81 #include "OMX_VPP.h"
82 #include "OMX_VPP_Utils.h"
83 #include "VPPsocket_ti.h"
84 #include "OMX_VPP_CompThread.h"
85 #include <OMX_Component.h>
86 #include "usn.h"
87
88 #ifdef RESOURCE_MANAGER_ENABLED
89 #include <ResourceManagerProxyAPI.h>
90 #endif
91
92 #define OMX_VPP_STRNCPY(dst, src, size) strncpy(dst, src, size)
93 #define OMX_VPP_ITOA(value, buffer) sprintf((char*)buffer, "%d", value);
94 #define OMX_VPP_MAX(x, y) ((x) > (y) ? (x) : (y))
95 #ifdef UNDER_CE
96 HINSTANCE g_hLcmlDllHandle = NULL;
97 #endif
98
99 #ifdef RESOURCE_MANAGER_ENABLED
100 void ResourceManagerCallback(RMPROXY_COMMANDDATATYPE cbData);
101 #endif
102
103 /* ========================================================================== */
104 /**
105 * @
106 *
107 * @param
108 * @param
109 *
110 * @pre
111 *
112 * @post
113 *
114 * @return none
115 */
116 /* ========================================================================== */
VPP_IsValidBuffer(OMX_BUFFERHEADERTYPE * pBufHeader,VPP_COMPONENT_PRIVATE * pComponentPrivate,OMX_U32 pIndex,OMX_U32 * pCount)117 OMX_ERRORTYPE VPP_IsValidBuffer(OMX_BUFFERHEADERTYPE *pBufHeader,
118 VPP_COMPONENT_PRIVATE *pComponentPrivate,
119 OMX_U32 pIndex,
120 OMX_U32 *pCount)
121 {
122 OMX_U32 nCount = 0;
123 OMX_ERRORTYPE eError = OMX_ErrorNone;
124
125 VPP_DPRINT("Entering Valid buffer -- %lu\n ",pIndex);
126
127 while (pComponentPrivate->sCompPorts[pIndex].pVPPBufHeader[nCount].pBufHeader != pBufHeader)
128 {
129 nCount ++;
130 if (nCount >= NUM_OF_VPP_BUFFERS) {
131 OMX_SET_ERROR_BAIL(eError, OMX_ErrorBadParameter);
132 }
133 }
134 *pCount = nCount;
135 VPP_DPRINT("Exiting Valid buffer -- %lu\n ",nCount);
136
137 EXIT:
138 return eError;
139
140 }
141
142
143
VPP_GetPortDefFromBufHeader(OMX_BUFFERHEADERTYPE * pBufHeader,OMX_PARAM_PORTDEFINITIONTYPE ** portDef)144 OMX_ERRORTYPE VPP_GetPortDefFromBufHeader(OMX_BUFFERHEADERTYPE *pBufHeader,
145 OMX_PARAM_PORTDEFINITIONTYPE **portDef )
146 {
147 OMX_ERRORTYPE eError = OMX_ErrorNone;
148
149 if ((pBufHeader->nOutputPortIndex != OMX_VPP_RGB_OUTPUT_PORT) &&
150 (pBufHeader->nOutputPortIndex != OMX_VPP_YUV_OUTPUT_PORT) &&
151 ((pBufHeader->nInputPortIndex == OMX_VPP_INPUT_PORT) ||
152 (pBufHeader->nInputPortIndex == OMX_VPP_INPUT_OVERLAY_PORT ))){ /* input port */
153
154 *portDef = pBufHeader->pInputPortPrivate;
155
156 }
157 else if ((pBufHeader->nOutputPortIndex == OMX_VPP_RGB_OUTPUT_PORT) ||
158 (pBufHeader->nOutputPortIndex == OMX_VPP_YUV_OUTPUT_PORT)){ /* output port */
159
160 *portDef = pBufHeader->pOutputPortPrivate;
161
162 }
163 else {
164 eError = OMX_ErrorBadParameter;
165 }
166
167 return eError;
168 }
169
170
171
VPP_Fill_LCMLInitParams(OMX_HANDLETYPE pComponent,OMX_U16 arr[],LCML_DSP * plcml_Init)172 OMX_ERRORTYPE VPP_Fill_LCMLInitParams(OMX_HANDLETYPE pComponent, OMX_U16 arr[], LCML_DSP *plcml_Init)
173 {
174
175 OMX_ERRORTYPE eError = OMX_ErrorNone;
176 OMX_U32 nIpBuf,nIpBufSize,nOpBuf,nOpBufSize;
177 char valueStr[52]; /*Changed length*/
178 OMX_U32 Input_FrameWidth;
179 OMX_U32 Output_FrameWidth;
180 OMX_U16 OutputRGB_Format;
181 OMX_U16 Input_FrameFormat;
182 OMX_U16 Output_FrameFormat;
183 OMX_U16 Overlay;
184 OMX_U16 Alpha = 0; /*Not implemented at OMX level*/
185 OMX_U16 ParamSize = 0;
186 char * pcSNArgs = NULL;
187 OMX_U8 *pTemp = NULL;
188 int index;
189 VPP_COMPONENT_PRIVATE *pComponentPrivate = NULL;
190 OMX_COMPONENTTYPE *pHandle = (OMX_COMPONENTTYPE *)pComponent;
191
192 if (!pHandle) {
193 eError=OMX_ErrorBadParameter;
194 goto EXIT;
195 }
196
197 pComponentPrivate = (VPP_COMPONENT_PRIVATE *)pHandle->pComponentPrivate;
198
199 VPP_DPRINT("VPP::%d :: Entered Fill_LCMLInitParams\n",__LINE__);
200
201 pComponentPrivate->NumofOutputPort = 0;
202 pComponentPrivate->IsYUVdataout = 0;
203 pComponentPrivate->IsRGBdataout = 0;
204 pComponentPrivate->IsOverlay = 0;
205
206 nIpBuf = pComponentPrivate->sCompPorts[OMX_VPP_INPUT_PORT].pPortDef.nBufferCountMin;
207 nIpBufSize = pComponentPrivate->sCompPorts[OMX_VPP_INPUT_PORT].pPortDef.nBufferSize;
208
209 nOpBuf = OMX_VPP_MAX(pComponentPrivate->sCompPorts[OMX_VPP_RGB_OUTPUT_PORT].pPortDef.nBufferCountMin,
210 pComponentPrivate->sCompPorts[OMX_VPP_YUV_OUTPUT_PORT].pPortDef.nBufferCountMin);
211 nOpBufSize = OMX_VPP_MAX(pComponentPrivate->sCompPorts[OMX_VPP_RGB_OUTPUT_PORT].pPortDef.nBufferSize,
212 pComponentPrivate->sCompPorts[OMX_VPP_YUV_OUTPUT_PORT].pPortDef.nBufferSize);
213
214 plcml_Init->In_BufInfo.nBuffers = nIpBuf;
215 plcml_Init->In_BufInfo.nSize = nIpBufSize;
216 plcml_Init->In_BufInfo.DataTrMethod = DMM_METHOD;
217 plcml_Init->Out_BufInfo.nBuffers = nOpBuf;
218 plcml_Init->Out_BufInfo.nSize = nOpBufSize;
219 plcml_Init->Out_BufInfo.DataTrMethod = DMM_METHOD;
220
221 plcml_Init->DeviceInfo.TypeofDevice = 0;
222 plcml_Init->DeviceInfo.DspStream = NULL;
223 plcml_Init->NodeInfo.nNumOfDLLs = 3;
224 plcml_Init->NodeInfo.AllUUIDs[0].uuid = &VPPNODE_TI_UUID;
225 strcpy ((char *)plcml_Init->NodeInfo.AllUUIDs[0].DllName, VPP_NODE_DLL);
226 plcml_Init->NodeInfo.AllUUIDs[0].eDllType = DLL_NODEOBJECT;
227
228 plcml_Init->NodeInfo.AllUUIDs[1].uuid = &VPPNODE_TI_UUID;
229 strcpy ((char *)plcml_Init->NodeInfo.AllUUIDs[1].DllName, VPP_NODE_DLL);
230 plcml_Init->NodeInfo.AllUUIDs[1].eDllType = DLL_DEPENDENT;
231
232 plcml_Init->NodeInfo.AllUUIDs[2].uuid = (struct DSP_UUID *) &COMMON_TI_UUID;
233 strcpy ((char *)plcml_Init->NodeInfo.AllUUIDs[2].DllName, USN_DLL_NAME);
234 plcml_Init->NodeInfo.AllUUIDs[2].eDllType = DLL_DEPENDENT;
235
236 plcml_Init->SegID = 0;
237 plcml_Init->Timeout = -1;
238 plcml_Init->Alignment = 0;
239 plcml_Init->Priority = 5;
240 VPP_DPRINT("priority is %d\n", plcml_Init->Priority);
241
242 plcml_Init->ProfileID = 0;
243 /*Main input port */
244 arr[0] = 5; /*# of Streams*/
245 arr[1] = 0; /*Stream ID*/
246 arr[2] = 0; /*Stream based input stream*/
247 arr[3] = NUM_OF_VPP_BUFFERS; /*Number of buffers on input stream*/
248 /*Overlay input port*/
249 arr[4] = 1; /*Stream ID*/
250 arr[5] = 0; /*Stream based input stream*/
251 arr[6] = NUM_OF_VPP_BUFFERS; /*Number of buffers on input stream*/
252 /*RGB output port*/
253 arr[7] = 2; /*Stream ID*/
254 arr[8] = 0; /*Stream basedoutput stream for RGB data*/
255 arr[9] = NUM_OF_VPP_BUFFERS; /*Number of buffers on output stream*/
256 /*YUV output port*/
257 arr[10] = 3; /*Stream ID*/
258 arr[11] = 0; /*Stream based output stream for YUV data*/
259 arr[12] = NUM_OF_VPP_BUFFERS; /*Number of buffers on output stream*/
260 /*Alpha input port, Not implemented at OMX level*/
261 arr[13] = 4; /*Stream ID*/
262 arr[14] = 0; /*Stream based input stream*/
263 arr[15] = NUM_OF_VPP_BUFFERS; /*Number of buffers on output stream*/
264
265
266 pcSNArgs = (char *) (arr + 16);
267
268 Input_FrameWidth = pComponentPrivate->sCompPorts[OMX_VPP_INPUT_PORT].pPortDef.format.video.nFrameWidth;
269 Output_FrameWidth = OMX_VPP_MAX(pComponentPrivate->sCompPorts[OMX_VPP_RGB_OUTPUT_PORT].pPortDef.format.video.nFrameWidth,
270 pComponentPrivate->sCompPorts[OMX_VPP_YUV_OUTPUT_PORT].pPortDef.format.video.nFrameWidth);
271 VPP_DPRINT("VPP:: INPPUT WIDTH= in Fill_LCMLInitParams %d\n ",Input_FrameWidth);
272 VPP_DPRINT("VPP:: OUTPUT WIDTH= in Fill_LCMLInitParams %d\n ",Output_FrameWidth);
273
274 /* RGB type for output*/
275 if (pComponentPrivate->sCompPorts[OMX_VPP_RGB_OUTPUT_PORT].pPortDef.bEnabled) {
276 switch (pComponentPrivate->sCompPorts[OMX_VPP_RGB_OUTPUT_PORT].pPortDef.format.video.eColorFormat)
277 {
278 case OMX_COLOR_Format16bitRGB565:
279 OutputRGB_Format = VGPOP_ERGB16_OUT;
280 pComponentPrivate->NumofOutputPort++;
281 pComponentPrivate->IsRGBdataout = 1;
282 break;
283
284 case OMX_COLOR_Format24bitRGB888:
285 OutputRGB_Format = VGPOP_ERGB24_OUT;
286 pComponentPrivate->NumofOutputPort++;
287 pComponentPrivate->IsRGBdataout = 1;
288 break;
289
290 case OMX_COLOR_Format32bitARGB8888:
291 OutputRGB_Format = VGPOP_ERGB32_OUT;
292 pComponentPrivate->NumofOutputPort++;
293 pComponentPrivate->IsRGBdataout = 1;
294 break;
295
296 case OMX_COLOR_Format12bitRGB444:
297 OutputRGB_Format = VGPOP_ERGB12_OUT;
298 pComponentPrivate->NumofOutputPort++;
299 pComponentPrivate->IsRGBdataout = 1;
300 break;
301
302 case OMX_COLOR_Format8bitRGB332:
303 OutputRGB_Format = VGPOP_ERGB8_OUT;
304 pComponentPrivate->NumofOutputPort++;
305 pComponentPrivate->IsRGBdataout = 1;
306 break;
307 case OMX_IndexCustomRGB4ColorFormat:
308 OutputRGB_Format = VGPOP_ERGB4_OUT;
309 pComponentPrivate->NumofOutputPort++;
310 pComponentPrivate->IsRGBdataout = 1;
311 break;
312
313
314 case OMX_COLOR_FormatL8:
315 OutputRGB_Format = VGPOP_EGRAY8_OUT;
316 pComponentPrivate->NumofOutputPort++;
317 pComponentPrivate->IsRGBdataout = 1;
318 break;
319
320 case OMX_COLOR_FormatL4:
321 OutputRGB_Format = VGPOP_EGRAY4_OUT;
322 pComponentPrivate->NumofOutputPort++;
323 pComponentPrivate->IsRGBdataout = 1;
324 break;
325
326 case OMX_COLOR_FormatL2:
327 OutputRGB_Format = VGPOP_EGRAY2_OUT;
328 pComponentPrivate->NumofOutputPort++;
329 pComponentPrivate->IsRGBdataout = 1;
330 break;
331
332 case OMX_COLOR_FormatMonochrome:
333 OutputRGB_Format = VGPOP_EGRAY1_OUT;
334 pComponentPrivate->NumofOutputPort++;
335 pComponentPrivate->IsRGBdataout = 1;
336 break;
337
338 default:
339 OutputRGB_Format = VGPOP_ERGB_NONE;
340 pComponentPrivate->IsRGBdataout = 0;
341 break;
342 }
343 }
344 else {
345 OutputRGB_Format = VGPOP_ERGB_NONE;
346 }
347
348 /* Input frame format*/
349 switch (pComponentPrivate->sCompPorts[OMX_VPP_INPUT_PORT].pPortDef.format.video.eColorFormat)
350 {
351 case OMX_COLOR_FormatYUV420PackedPlanar:
352 Input_FrameFormat = VGPOP_E420_IN;
353 break;
354
355 case OMX_COLOR_FormatCbYCrY:
356 Input_FrameFormat = VGPOP_E422_IN_UY;
357 break;
358 case OMX_COLOR_FormatYCbYCr:
359 Input_FrameFormat = VGPOP_E422_IN_YU;
360 break;
361
362 /*image formats*/
363 case OMX_COLOR_Format16bitRGB565:
364 Input_FrameFormat = VGPOP_ERGB16_IN;
365 break;
366 case OMX_COLOR_Format12bitRGB444:
367 Input_FrameFormat = VGPOP_ERGB12_IN;
368 break;
369 case OMX_COLOR_Format8bitRGB332:
370 Input_FrameFormat = VGPOP_ERGB8_IN;
371 break;
372 case OMX_IndexCustomRGB4ColorFormat:
373 Input_FrameFormat = VGPOP_ERGB4_IN;
374 break;
375 case OMX_COLOR_FormatL8:
376 Input_FrameFormat = VGPOP_EGRAY8_IN;
377 break;
378 case OMX_COLOR_FormatL4:
379 Input_FrameFormat = VGPOP_EGRAY4_IN;
380 break;
381 case OMX_COLOR_FormatL2:
382 Input_FrameFormat = VGPOP_EGRAY2_IN;
383 break;
384 case OMX_COLOR_FormatMonochrome:
385 Input_FrameFormat = VGPOP_EGRAY1_IN;
386 break;
387 case OMX_COLOR_Format24bitRGB888:
388 Input_FrameFormat = VGPOP_ERGB24_IN;
389 break;
390 default:
391 Input_FrameFormat = VGPOP_E420_IN;
392 VPP_DPRINT("%d :: NOT SUPPORTED INPUT FORMAT setting default as 420 planar",__LINE__);
393 break;
394 }
395
396 /* Output YUV frame format*/
397 if (pComponentPrivate->sCompPorts[OMX_VPP_YUV_OUTPUT_PORT].pPortDef.bEnabled) {
398 switch (pComponentPrivate->sCompPorts[OMX_VPP_YUV_OUTPUT_PORT].pPortDef.format.video.eColorFormat)
399 {
400 case OMX_COLOR_FormatYUV420PackedPlanar:
401 Output_FrameFormat = VGPOP_E420_OUT;
402 pComponentPrivate->NumofOutputPort++;
403 pComponentPrivate->IsYUVdataout = 1;
404 break;
405
406 case OMX_COLOR_FormatYCbYCr:
407 Output_FrameFormat = VGPOP_E422_OUT_YU;
408 pComponentPrivate->NumofOutputPort++;
409 pComponentPrivate->IsYUVdataout = 1;
410 break;
411
412 case OMX_COLOR_FormatCbYCrY:
413 Output_FrameFormat = VGPOP_E422_OUT_UY;
414 pComponentPrivate->NumofOutputPort++;
415 pComponentPrivate->IsYUVdataout = 1;
416 break;
417
418 default:
419 Output_FrameFormat = VGPOP_EYUV_NONE;
420 pComponentPrivate->IsYUVdataout=0;
421 break;
422 }
423 }
424 else {
425 Output_FrameFormat = VGPOP_EYUV_NONE;
426 }
427
428 VPP_DPRINT(":: Ports Available in Fill_LCMLInitParams %ld\n ",pComponentPrivate->NumofOutputPort);
429
430 /*for overlay*/
431 if (pComponentPrivate->sCompPorts[OMX_VPP_INPUT_OVERLAY_PORT].pPortDef.bEnabled) {
432 Overlay = 1;
433 pComponentPrivate->IsOverlay = 1 ;
434 VPP_DPRINT("VPP::OVERLAY ENABLED");
435 }
436 else {
437 Overlay = 0;
438 }
439
440 memset(valueStr, 0, sizeof(valueStr));
441 VPP_DPRINT(":%lu:%lu:%u:%u:%u:%d:%d\n",
442 Input_FrameWidth,
443 Output_FrameWidth,
444 OutputRGB_Format,
445 Input_FrameFormat,
446 Output_FrameFormat,
447 Overlay,
448 Alpha);
449 sprintf(valueStr, ":%lu:%lu:%u:%u:%u:%d:%d\n",
450 Input_FrameWidth,
451 Output_FrameWidth,
452 OutputRGB_Format,
453 Input_FrameFormat,
454 Output_FrameFormat,
455 Overlay,
456 Alpha);
457
458 while(valueStr[ParamSize] != '\0'){
459 ParamSize++;
460 }
461 VPP_DPRINT("ParamSize is %d\n", ParamSize);
462
463 /*Copy VPP parameters */
464 pTemp = memcpy(pcSNArgs,valueStr,ParamSize);
465 if(pTemp == NULL){
466 eError = OMX_ErrorUndefined;
467 goto EXIT;
468 }
469
470 if ( (ParamSize % 2) != 0) {
471 index =(ParamSize+1) >> 1;
472 }
473 else {
474 index = ParamSize >> 1; /*Divide by 2*/
475 }
476 index = index + 16; /*Add 16 to the index in order to point to the correct location*/
477
478 arr[index] = END_OF_CR_PHASE_ARGS;
479 plcml_Init->pCrPhArgs = arr;
480
481 VPP_DPRINT("VPP::%d :: Exiting Fill_LCMLInitParams",__LINE__);
482
483 EXIT:
484 return eError;
485 }
486
487
488
489 /* ========================================================================== */
490 /**
491 * @Start_ComponentThread() This function is called by the component to create
492 * the component thread, command pipe, data pipe and LCML Pipe.
493 *
494 * @param pComponent handle for this instance of the component
495 *
496 * @pre
497 *
498 * @post
499 *
500 * @return none
501 */
502 /* ==========================================================================* */
VPP_Start_ComponentThread(OMX_HANDLETYPE pComponent)503 OMX_ERRORTYPE VPP_Start_ComponentThread(OMX_HANDLETYPE pComponent)
504 {
505 OMX_ERRORTYPE eError = OMX_ErrorNone;
506 OMX_COMPONENTTYPE *pHandle = (OMX_COMPONENTTYPE *)pComponent;
507 VPP_COMPONENT_PRIVATE *pComponentPrivate = NULL;
508 #ifdef UNDER_CE
509 pthread_attr_t attr;
510 memset(&attr, 0, sizeof(attr));
511 attr.__inheritsched = PTHREAD_EXPLICIT_SCHED;
512 attr.__schedparam.__sched_priority = OMX_VGPOP_THREAD_PRIORITY;
513 #endif
514
515 VPP_DPRINT("VPP::%d :: Enetering Start_ComponentThread\n", __LINE__);
516
517 pComponentPrivate = (VPP_COMPONENT_PRIVATE *)pHandle->pComponentPrivate;
518
519 /* create the pipe used to send commands to the thread */
520 eError = pipe (pComponentPrivate->cmdPipe);
521 if (eError) {
522 eError = OMX_ErrorContentPipeCreationFailed;
523 goto EXIT;
524 }
525
526 /* create the pipe used to send commands data to the thread */
527 eError = pipe (pComponentPrivate->nCmdDataPipe);
528 if (eError) {
529 eError = OMX_ErrorContentPipeCreationFailed;
530 goto EXIT;
531 }
532
533 /*Create pipe to hold filled input buffers from APP to Component*/
534 eError = pipe(pComponentPrivate->nFilled_iPipe);
535 if (eError) {
536 eError = OMX_ErrorContentPipeCreationFailed;
537 goto EXIT;
538 }
539 /*Create pipe to hold empty output buffers from APP to Component*/
540 eError = pipe(pComponentPrivate->nFree_oPipe);
541 if (eError) {
542 eError = OMX_ErrorContentPipeCreationFailed;
543 goto EXIT;
544 }
545
546 #ifdef UNDER_CE
547 eError = pthread_create (&(pComponentPrivate->ComponentThread),
548 &attr,
549 VPP_ComponentThreadFunc,
550 pComponentPrivate);
551 #else
552 eError = pthread_create (&(pComponentPrivate->ComponentThread),
553 NULL,
554 VPP_ComponentThreadFunc,
555 pComponentPrivate);
556 #endif
557 if (eError || !pComponentPrivate->ComponentThread) {
558 eError = OMX_ErrorInsufficientResources;
559 goto EXIT;
560 }
561
562 #ifdef __PERF_INSTRUMENTATION__
563 PERF_ThreadCreated(pComponentPrivate->pPERF,
564 pComponentPrivate->ComponentThread,
565 PERF_FOURCC('V','P','P','T'));
566 #endif
567
568 VPP_DPRINT ("VPP::%d :: Exiting from Start_ComponentThread\n", __LINE__);
569
570 EXIT:
571 return eError;
572 }
573
574
575 /* ========================================================================== */
576 /**
577 * Free_ComponentResources() This function is called by the component during
578 * de-init to close component thread, Command pipe, data pipe & LCML pipe.
579 *
580 * @param pComponent handle for this instance of the component
581 *
582 * @pre
583 *
584 * @post
585 *
586 * @return none
587 */
588 /* ========================================================================== */
589
VPP_Free_ComponentResources(OMX_HANDLETYPE pComponent)590 OMX_ERRORTYPE VPP_Free_ComponentResources(OMX_HANDLETYPE pComponent)
591 {
592 OMX_COMPONENTTYPE *pHandle = (OMX_COMPONENTTYPE *)pComponent;
593 VPP_COMPONENT_PRIVATE *pComponentPrivate = (VPP_COMPONENT_PRIVATE *) pHandle->pComponentPrivate;
594 OMX_ERRORTYPE eError = OMX_ErrorNone;
595 OMX_ERRORTYPE threadError = OMX_ErrorNone;
596 OMX_ERRORTYPE err = OMX_ErrorNone;
597 OMX_HANDLETYPE pLcmlHandle = pComponentPrivate->pLcmlHandle;
598 OMX_COMMANDTYPE stop = EXIT_COMPONENT_THRD;
599 int i=0;
600
601 #ifdef __PERF_INSTRUMENTATION__
602 PERF_Boundary(pComponentPrivate->pPERF,
603 PERF_BoundaryStart | PERF_BoundaryCleanup);
604 PERF_SendingCommand(pComponentPrivate->pPERF, stop, 0, PERF_ModuleComponent);
605 #endif
606
607 if (pLcmlHandle !=NULL) {
608 VPP_DPRINT (" IN ComponentDeInit calling EMMCodecControlDestroy \n");
609 eError = LCML_ControlCodec(((LCML_DSP_INTERFACE*)pLcmlHandle)->pCodecinterfacehandle, EMMCodecControlDestroy, NULL);
610 if (eError != OMX_ErrorNone) {
611 VPP_DPRINT("%d : Error: in Destroying the codec\n",__LINE__);
612 goto EXIT;
613 }
614 }
615 err = write (pComponentPrivate->cmdPipe[1], &stop, sizeof(OMX_COMMANDTYPE));
616 if (err == -1) {
617 VPP_DPRINT ("%d :: Error in Writing to the cmd pipe In deinit\n", eError);
618 eError = OMX_ErrorHardware;
619 goto EXIT;
620 }
621
622 VPP_DPRINT ("%d :: Free_ComponentResources \n",__LINE__);
623 if(pComponentPrivate->ComponentThread){
624 #ifndef UNDER_CE
625 err = pthread_join (pComponentPrivate->ComponentThread,
626 (void*)&threadError);
627 #else
628 err = oaf_pthread_join (pComponentPrivate->ComponentThread,
629 (void*)&threadError);
630 #endif
631 if (err) {
632 eError = OMX_ErrorHardware;
633 VPP_DPRINT ("VPP::%d :: Error while closing Component Thread\n",__LINE__);
634 }
635 }
636 else{
637 eError = OMX_ErrorUndefined;
638 VPP_DPRINT ("VPP::%d :: Error Component Thread = NULL\n",__LINE__);
639 }
640 for (i=0; i<2; i++) {
641 err = close (pComponentPrivate->cmdPipe[i]);
642 if (err && OMX_ErrorNone == eError) {
643 eError = OMX_ErrorHardware;
644 VPP_DPRINT ("VPP::%d :: Error while closing cmdPipe\n",__LINE__);
645 }
646
647 err = close (pComponentPrivate->nCmdDataPipe[i]);
648 if (err && OMX_ErrorNone == eError) {
649 eError = OMX_ErrorHardware;
650 VPP_DPRINT ("VPP::%d :: Error while closing Command Data Pipe\n",__LINE__);
651 }
652
653 /*close the data pipe handles*/
654 err = close(pComponentPrivate->nFree_oPipe[i]);
655 if (err && OMX_ErrorNone == eError) {
656 eError = OMX_ErrorHardware;
657 VPP_DPRINT ("VPP::%d :: Error while closing Free Output pipe\n",__LINE__);
658 }
659 err = close(pComponentPrivate->nFilled_iPipe[i]);
660 if (err && OMX_ErrorNone == eError) {
661 eError = OMX_ErrorHardware;
662 VPP_DPRINT ("VPP::%d :: Error while closing Filled Input pipe\n",__LINE__);
663 }
664 }
665
666 pthread_mutex_destroy(&pComponentPrivate->vpp_mutex);
667 pthread_cond_destroy(&pComponentPrivate->stop_cond);
668 pthread_mutex_destroy(&pComponentPrivate->buf_mutex);
669
670 #ifdef __PERF_INSTRUMENTATION__
671 PERF_Boundary(pComponentPrivate->pPERF,
672 PERF_BoundaryComplete | PERF_BoundaryCleanup);
673 PERF_Done(pComponentPrivate->pPERF);
674 #endif
675
676 EXIT:
677 /* LinkedList_DisplayAll(&AllocList); */
678 OMX_FREEALL();
679 LinkedList_Destroy(&AllocList);
680
681 VPP_DPRINT ("Exiting Successfully After Freeing All Resources\n");
682 return eError;
683 }
684
685 /* ========================================================================== */
686 /**
687 * @VPP_DisablePort() This function is called by the component when ever it
688 * receives the command from the application
689 *
690 * @param pComponentPrivate Component private data
691 *
692 * @pre
693 *
694 * @post
695 *
696 * @return none
697 */
698 /* ========================================================================== */
VPP_DisablePort(VPP_COMPONENT_PRIVATE * pComponentPrivate,OMX_U32 nParam1)699 OMX_ERRORTYPE VPP_DisablePort (VPP_COMPONENT_PRIVATE* pComponentPrivate, OMX_U32 nParam1)
700 {
701 OMX_ERRORTYPE eError = OMX_ErrorNone;
702 OMX_COMPONENTTYPE* pHandle = NULL;
703
704 if (!pComponentPrivate) {
705 eError = OMX_ErrorBadParameter;
706 goto EXIT;
707 }
708 pHandle = (OMX_COMPONENTTYPE*)pComponentPrivate->pHandle;
709
710
711 if (pComponentPrivate->curState == OMX_StateExecuting || pComponentPrivate->curState == OMX_StatePause) {
712 if (((nParam1 >= 0) && (nParam1 < 4)) || (nParam1 == -1)) {
713 eError = VPP_HandleCommandFlush(pComponentPrivate, nParam1, OMX_FALSE);
714 }
715 }
716
717 EXIT:
718 return eError;
719 }
720
721
722
723 /* ========================================================================== */
724 /**
725 * @VPP_EnablePort() This function is called by the component when ever it
726 * receives the command from the application
727 *
728 * @param pComponentPrivate Component private data
729 *
730 * @pre
731 *
732 * @post
733 *
734 * @return none
735 */
736 /* ========================================================================== */
VPP_EnablePort(VPP_COMPONENT_PRIVATE * pComponentPrivate,OMX_U32 nParam1)737 OMX_ERRORTYPE VPP_EnablePort (VPP_COMPONENT_PRIVATE* pComponentPrivate, OMX_U32 nParam1)
738 {
739 OMX_ERRORTYPE eError = OMX_ErrorNone;
740 OMX_COMPONENTTYPE* pHandle = NULL;
741 int ports;
742 OMX_U32 nTimeout;
743
744 VPP_DPRINT("VPP: Enable port index=%ld",nParam1);
745
746 if (!pComponentPrivate) {
747 eError = OMX_ErrorBadParameter;
748 goto EXIT;
749 }
750 pHandle = (OMX_COMPONENTTYPE*)pComponentPrivate->pHandle;
751
752 if (nParam1 >= 0 && nParam1 < NUM_OF_VPP_PORTS ){
753 /* enable port*/
754 pComponentPrivate->sCompPorts[nParam1].pPortDef.bEnabled = OMX_TRUE;
755 }
756
757 if ( nParam1 == -1) {
758 for (ports = 0; ports < NUM_OF_VPP_PORTS; ports++)
759 {
760 pComponentPrivate->sCompPorts[ports].pPortDef.bEnabled = OMX_TRUE;
761 }
762 }
763
764 nTimeout = 0;
765 while (OMX_TRUE)
766 {
767 if ((nParam1 >= 0 && nParam1 < NUM_OF_VPP_PORTS) &&
768 (pComponentPrivate->curState == OMX_StateLoaded ||
769 pComponentPrivate->sCompPorts[nParam1].pPortDef.bPopulated)) {
770 pComponentPrivate->cbInfo.EventHandler (pHandle,
771 pHandle->pApplicationPrivate,
772 OMX_EventCmdComplete,
773 OMX_CommandPortEnable,
774 nParam1,
775 NULL);
776 break;
777 }
778 else if (nParam1 == -1 &&
779 (pComponentPrivate->curState == OMX_StateLoaded ||
780 (pComponentPrivate->sCompPorts[0].pPortDef.bPopulated &&
781 pComponentPrivate->sCompPorts[1].pPortDef.bPopulated &&
782 pComponentPrivate->sCompPorts[2].pPortDef.bPopulated &&
783 pComponentPrivate->sCompPorts[3].pPortDef.bPopulated))) {
784 for (ports = 0; ports < NUM_OF_VPP_PORTS; ports++) {
785 pComponentPrivate->cbInfo.EventHandler (pHandle,
786 pHandle->pApplicationPrivate,
787 OMX_EventCmdComplete,
788 OMX_CommandPortEnable,
789 ports,
790 NULL);
791 }
792 break;
793 }
794 else if (nTimeout++ > 0xEFFFFFFE) {
795 pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle,
796 pComponentPrivate->pHandle->pApplicationPrivate,
797 OMX_EventError,
798 OMX_ErrorInsufficientResources,
799 OMX_TI_ErrorMajor,
800 "Port Unresponsive - Idle");
801 break;
802 }
803
804 sched_yield();
805 }
806
807 EXIT:
808 return eError;
809 }
810
811 /* ========================================================================== */
812 /**
813 * @VPP_EnablePort() This function is called by the component when ever it
814 * receives the command from the application
815 *
816 * @param pComponentPrivate Component private data
817 *
818 * @pre
819 *
820 * @post
821 *
822 * @return none
823 */
824 /* ========================================================================== */
VPP_HandleCommandFlush(VPP_COMPONENT_PRIVATE * pComponentPrivate,OMX_U32 nParam1,OMX_BOOL return_event)825 OMX_ERRORTYPE VPP_HandleCommandFlush (VPP_COMPONENT_PRIVATE* pComponentPrivate, OMX_U32 nParam1, OMX_BOOL return_event)
826 {
827 OMX_ERRORTYPE eError = OMX_ErrorNone;
828 OMX_COMPONENTTYPE* pHandle = NULL;
829 LCML_DSP_INTERFACE *pLcmlHandle = NULL;
830 OMX_U32 nCount = 0;
831 char *pArgs = "damedesuStr";
832
833
834 OMX_BUFFERHEADERTYPE * pBufHeader;
835 OMX_PARAM_PORTDEFINITIONTYPE *portDef ;
836
837 int nRet;
838 int i;
839 OMX_BOOL bFoundBuffer;
840
841 if (!pComponentPrivate) {
842 eError = OMX_ErrorBadParameter;
843 goto EXIT;
844 }
845 pHandle = (OMX_COMPONENTTYPE*)pComponentPrivate->pHandle;
846
847 VPP_DPRINT("nParam1 %d return_event is %x OMX_FALSE %x\n", nParam1, return_event, OMX_FALSE);
848
849 pLcmlHandle = pComponentPrivate->pLcmlHandle;
850 pComponentPrivate->bDisable = OMX_FALSE;
851 VPP_DPRINT("VPP_UTILS: send STOP as flush\n");
852 eError = LCML_ControlCodec(
853 ((LCML_DSP_INTERFACE*)pLcmlHandle)->pCodecinterfacehandle,
854 MMCodecControlStop,
855 (void *)pArgs);
856 if (eError != OMX_ErrorNone) {
857 VPP_DPRINT("VPP::%d: Error 0x%X Occurred in Codec Stop..\n",__LINE__,eError);
858 goto EXIT;
859 }
860
861 while (pComponentPrivate->bDisable == OMX_FALSE) {
862 sched_yield();
863 }
864
865 eError = LCML_ControlCodec(
866 ((LCML_DSP_INTERFACE*)pLcmlHandle)->pCodecinterfacehandle,
867 EMMCodecControlStart,
868 (void *)pArgs);
869 if (eError != OMX_ErrorNone) {
870 VPP_DPRINT("VPP::%d: Error 0x%X Occurred in Codec Start..\n",__LINE__,eError);
871 goto EXIT;
872 }
873
874 for (i = 0; i < NUM_OF_VPP_PORTS; i ++) {
875 if (return_event == OMX_TRUE) {
876 for (nCount = 0; nCount < NUM_OF_VPP_BUFFERS; nCount ++){
877 if (pComponentPrivate->sCompPorts[i].pVPPBufHeader[nCount].eBufferOwner == VPP_BUFFER_DSP ||
878 pComponentPrivate->sCompPorts[i].pVPPBufHeader[nCount].eBufferOwner == VPP_BUFFER_COMPONENT_IN ||
879 pComponentPrivate->sCompPorts[i].pVPPBufHeader[nCount].eBufferOwner == VPP_BUFFER_COMPONENT_OUT){
880
881 switch (pComponentPrivate->sCompPorts[i].pVPPBufHeader[nCount].eBufferOwner) {
882 case VPP_BUFFER_DSP:
883 pComponentPrivate->sCompPorts[i].pVPPBufHeader[nCount].eBufferOwner = VPP_BUFFER_CLIENT;
884 pComponentPrivate->sCompPorts[i].pVPPBufHeader[nCount].pBufHeader->nFilledLen = 0;
885 /* pComponentPrivate->nInPortOut ++; */
886 #ifdef __PERF_INSTRUMENTATION__
887 PERF_SendingFrame(pComponentPrivate->pPERFcomp,
888 PREF(((OMX_BUFFERHEADERTYPE*) pComponentPrivate->sCompPorts[0].pVPPBufHeader[nCount].pBufHeader), pBuffer),
889 PREF(((OMX_BUFFERHEADERTYPE*) pComponentPrivate->sCompPorts[0].pVPPBufHeader[nCount].pBufHeader), nFilledLen),
890 PERF_ModuleHLMM);
891 #endif
892 if (i == OMX_VPP_INPUT_PORT ||
893 i == OMX_VPP_INPUT_OVERLAY_PORT) {
894 pComponentPrivate->cbInfo.EmptyBufferDone(pComponentPrivate->pHandle,
895 pComponentPrivate->pHandle->pApplicationPrivate,
896 pComponentPrivate->sCompPorts[i].pVPPBufHeader[nCount].pBufHeader);
897 } else if (i == OMX_VPP_RGB_OUTPUT_PORT ||
898 i == OMX_VPP_YUV_OUTPUT_PORT) {
899 pComponentPrivate->cbInfo.FillBufferDone(pComponentPrivate->pHandle,
900 pComponentPrivate->pHandle->pApplicationPrivate,
901 pComponentPrivate->sCompPorts[i].pVPPBufHeader[nCount].pBufHeader);
902 }
903 break;
904 case VPP_BUFFER_COMPONENT_IN:
905 bFoundBuffer = OMX_FALSE;
906
907 while (bFoundBuffer == OMX_FALSE) {
908 if (i == OMX_VPP_INPUT_PORT || i == OMX_VPP_INPUT_OVERLAY_PORT) {
909 nRet = read(pComponentPrivate->nFilled_iPipe[0], &(pBufHeader),sizeof(pBufHeader));
910 if (-1 == nRet) {
911 VPP_DPRINT ("%d :: Error while reading from the pipe\n",__LINE__);
912 }
913 eError = VPP_GetPortDefFromBufHeader(pBufHeader, &portDef);
914
915 if (eError != OMX_ErrorNone) {
916 VPP_DPRINT("VPP:: Got error in _GetPortDefFromBufHeader. Code %x\n", eError);
917 goto EXIT;
918 }
919
920 if (portDef->nPortIndex == i) {
921 pComponentPrivate->sCompPorts[i].pVPPBufHeader[nCount].eBufferOwner = VPP_BUFFER_CLIENT;
922 pComponentPrivate->cbInfo.EmptyBufferDone(pComponentPrivate->pHandle,
923 pComponentPrivate->pHandle->pApplicationPrivate,
924 pBufHeader);
925 bFoundBuffer = OMX_TRUE;
926 }
927 else {
928 write(pComponentPrivate->nFilled_iPipe[1], &(pBufHeader), sizeof(pBufHeader));
929 }
930 }
931 else if (i == OMX_VPP_RGB_OUTPUT_PORT ||i == OMX_VPP_YUV_OUTPUT_PORT) {
932 nRet = read(pComponentPrivate->nFree_oPipe[0], &pBufHeader, sizeof(pBufHeader));
933 if (-1 == nRet) {
934 VPP_DPRINT ("%d :: Error while reading from the pipe\n",__LINE__);
935 }
936 eError = VPP_GetPortDefFromBufHeader(pBufHeader, &portDef);
937 if (eError != OMX_ErrorNone) {
938 VPP_DPRINT("Error in _GetPortDefFromBufHeader. Code %d\n", eError);
939 goto EXIT;
940 }
941 if (portDef->nPortIndex == i) {
942 pComponentPrivate->sCompPorts[i].pVPPBufHeader[nCount].eBufferOwner = VPP_BUFFER_CLIENT;
943 pComponentPrivate->cbInfo.FillBufferDone(pHandle,
944 pHandle->pApplicationPrivate,
945 pBufHeader);
946 bFoundBuffer = OMX_TRUE;
947 }
948 else {
949 write(pComponentPrivate->nFree_oPipe[1],&pBufHeader,sizeof(OMX_BUFFERHEADERTYPE*));
950 }
951 }
952 } /* end of while () */
953 break;
954 case VPP_BUFFER_COMPONENT_OUT:
955 /* since we don't have this queue, there is nothing
956 to flush. Buffers are handled immediately */
957 break;
958 case VPP_BUFFER_CLIENT:
959 case VPP_BUFFER_TUNNEL_COMPONENT:
960 break;
961 }
962 }
963 }
964 pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle,
965 pComponentPrivate->pHandle->pApplicationPrivate,
966 OMX_EventCmdComplete,
967 OMX_CommandFlush,
968 i,
969 NULL);
970 }
971 } /* for (i = 0; i < NUM_OF_VPP_PORTS; i ++) */
972
973 EXIT:
974 return eError;
975 }
976
977
978
979 /* ========================================================================== */
980 /**
981 * @StateToIdle() This function is called by the component when ever it
982 * receives the command from the application
983 *
984 * @param pComponentPrivate Component private data
985 *
986 * @pre
987 *
988 * @post
989 *
990 * @return none
991 */
992 /* ========================================================================== */
VPP_StateToIdle(VPP_COMPONENT_PRIVATE * pComponentPrivate)993 OMX_ERRORTYPE VPP_StateToIdle(VPP_COMPONENT_PRIVATE *pComponentPrivate)
994 {
995 OMX_ERRORTYPE eError = OMX_ErrorNone;
996 OMX_COMPONENTTYPE *pHandle = (OMX_COMPONENTTYPE *) pComponentPrivate->pHandle;
997 OMX_HANDLETYPE pLcmlHandle = pComponentPrivate->pLcmlHandle;
998 OMX_PARAM_PORTDEFINITIONTYPE *pPortDef = NULL;
999 VPP_PORT_TYPE *pPortTp = NULL;
1000 OMX_U8 *pBufferAligned = NULL;
1001 OMX_U8 *pBufferStart = NULL;
1002 char *pArgs = "damedesuStr";
1003 OMX_U32 nTimeout;
1004 OMX_U16 array[100]; /*Used to pass to Fill_LCMLInitParams*/
1005
1006 VPP_DPRINT("VPP::%d: HandleCommand: Cmd Idle \n",__LINE__);
1007 VPP_DPRINT("Current state is %d = %d\n", pComponentPrivate->curState, OMX_StateLoaded);
1008
1009 if (pComponentPrivate->curState == OMX_StateInvalid) {
1010 pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle,
1011 pComponentPrivate->pHandle->pApplicationPrivate,
1012 OMX_EventError,
1013 OMX_ErrorIncorrectStateTransition,
1014 OMX_TI_ErrorSevere,
1015 NULL);
1016 goto EXIT;
1017 }
1018
1019 pComponentPrivate->toState = OMX_StateIdle;
1020
1021 if ((pComponentPrivate->curState == OMX_StateLoaded) ||
1022 (pComponentPrivate->curState == OMX_StateWaitForResources)) { /* from Loaded to Idle */
1023
1024 LCML_CALLBACKTYPE cb;
1025 LCML_DSP *pLcmlDsp;
1026 char *p = "damedesuStr";
1027 int nPortIndex = 0;
1028
1029 #ifdef __PERF_INSTRUMENTATION__
1030 PERF_Boundary(pComponentPrivate->pPERFcomp,
1031 PERF_BoundaryStart | PERF_BoundarySetup);
1032 #endif
1033
1034 VPP_DPRINT("pComponentPrivate->sCompPorts[0].pPortDef.nPortIndex = %d\n", pComponentPrivate->sCompPorts[0].pPortDef.nPortIndex);
1035
1036 pLcmlHandle = (OMX_HANDLETYPE) VPP_GetLCMLHandle(pComponentPrivate);
1037 if (pLcmlHandle == NULL) {
1038 VPP_DPRINT("%d :: LCML Handle is NULL........exiting..\n",__LINE__);
1039 goto EXIT;
1040 }
1041 VPP_DPRINT("%d pComponentPrivate->sCompPorts[0].pPortDef.nPortIndex = %d\n", __LINE__, pComponentPrivate->sCompPorts[0].pPortDef.nPortIndex);
1042
1043 pLcmlDsp = (((LCML_DSP_INTERFACE*)pLcmlHandle)->dspCodec);
1044 VPP_DPRINT("VPP::%d: before init LCML \n",__LINE__);
1045
1046 for (nPortIndex = 0; nPortIndex < NUM_OF_VPP_PORTS; nPortIndex++) {
1047 OMX_U32 nBuf;
1048 pPortTp = &(pComponentPrivate->sCompPorts[nPortIndex]);
1049 pPortDef = &(pComponentPrivate->sCompPorts[nPortIndex].pPortDef);
1050 if ((pPortTp->hTunnelComponent != NULL ) &&
1051 ((pPortTp->eSupplierSetting == OMX_BufferSupplyInput && 2 > nPortIndex) ||
1052 (pPortTp->eSupplierSetting == OMX_BufferSupplyOutput && 2 < nPortIndex))) {
1053
1054 /* assuming i am the supplier */
1055 for (nBuf=0; nBuf< pPortDef->nBufferCountActual; nBuf++) {
1056 OMX_U32 nsize;
1057 OMX_U8 *nbuffer = NULL;
1058
1059 nsize = pPortDef->format.video.nFrameWidth * pPortDef->format.video.nFrameHeight * 2;
1060 OMX_MALLOC(pBufferStart, nsize + 32 + 256);
1061 VPP_DPRINT("allocated pBufferStart with address %p\n", nbuffer);
1062
1063 pBufferAligned = pBufferStart;
1064 while ((((int)pBufferAligned) & 0x1f) != 0)
1065 {
1066 pBufferAligned++;
1067 }
1068 pBufferAligned = ((OMX_U8*)pBufferAligned)+128;
1069 pComponentPrivate->sCompPorts[nPortIndex].pVPPBufHeader[nBuf].pBufferStart = pBufferStart;
1070 nbuffer = pBufferAligned;
1071
1072 #ifdef __PERF_INSTRUMENTATION__
1073 PERF_XferingFrame(pComponentPrivate->pPERFcomp,
1074 nbuffer, nsize,
1075 PERF_ModuleMemory,
1076 PERF_ModuleLLMM);
1077 #endif
1078
1079 eError = OMX_UseBuffer(
1080 pPortTp->hTunnelComponent,
1081 &(pPortTp->pVPPBufHeader[nBuf].pBufHeader),
1082 pPortTp->nTunnelPort,
1083 NULL,
1084 nsize,
1085 nbuffer);
1086
1087 if (pPortTp->eSupplierSetting == OMX_BufferSupplyInput) {
1088 pComponentPrivate->sCompPorts[nPortIndex].pVPPBufHeader[nBuf].pBufHeader->nFilledLen = nsize;
1089 pComponentPrivate->sCompPorts[nPortIndex].pVPPBufHeader[nBuf].pBufHeader->nAllocLen = nsize;
1090 pComponentPrivate->sCompPorts[nPortIndex].pVPPBufHeader[nBuf].nIndex = OMX_VPP_INPUT_PORT;
1091 pComponentPrivate->sCompPorts[nPortIndex].pVPPBufHeader[nBuf].bSelfAllocated = OMX_TRUE;
1092 pComponentPrivate->sCompPorts[nPortIndex].pVPPBufHeader[nBuf].bHolding = OMX_TRUE;
1093 pComponentPrivate->sCompPorts[nPortIndex].nBufSupplier = OMX_TRUE;
1094 pComponentPrivate->sCompPorts[nPortIndex].pVPPBufHeader[nBuf].pBufHeader->pInputPortPrivate = &pComponentPrivate->sCompPorts[OMX_VPP_INPUT_PORT].pPortDef;
1095 pComponentPrivate->sCompPorts[nPortIndex].pPortDef.bPopulated = OMX_TRUE;
1096 pComponentPrivate->sCompPorts[nPortIndex].nBufferCount ++;
1097 }
1098 else {
1099 pComponentPrivate->sCompPorts[nPortIndex].pVPPBufHeader[nBuf].pBufHeader->nFilledLen = nsize;
1100 pComponentPrivate->sCompPorts[nPortIndex].pVPPBufHeader[nBuf].pBufHeader->nAllocLen = nsize;
1101 pComponentPrivate->sCompPorts[nPortIndex].pVPPBufHeader[nBuf].nIndex = nPortIndex;
1102 pComponentPrivate->sCompPorts[nPortIndex].pVPPBufHeader[nBuf].bSelfAllocated = OMX_TRUE;
1103 pComponentPrivate->sCompPorts[nPortIndex].pVPPBufHeader[nBuf].bHolding = OMX_TRUE;
1104 pComponentPrivate->sCompPorts[nPortIndex].nBufSupplier = OMX_TRUE;
1105 pComponentPrivate->sCompPorts[nPortIndex].pVPPBufHeader[nBuf].pBufHeader->pOutputPortPrivate = &pComponentPrivate->sCompPorts[nPortIndex].pPortDef;
1106 pComponentPrivate->sCompPorts[nPortIndex].pPortDef.bPopulated = OMX_TRUE;
1107 pComponentPrivate->sCompPorts[nPortIndex].nBufferCount ++;
1108 }
1109 }
1110 VPP_InitBufferDataPropagation(pComponentPrivate, nPortIndex);
1111 } /* end if I am a supplier */
1112
1113 if (pPortDef->bEnabled == OMX_TRUE) {
1114 nTimeout = 0;
1115
1116 while(1)
1117 {
1118 if(pPortDef->bPopulated) {
1119 break;
1120 }
1121 else if (nTimeout ++ > 0xEFFFFFFE) {
1122 VPP_DPRINT("TimeOut Error ! .. Buffers not allocated in time.\n");
1123 pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle,
1124 pComponentPrivate->pHandle->pApplicationPrivate,
1125 OMX_EventError,
1126 OMX_ErrorPortUnresponsiveDuringDeallocation,
1127 OMX_TI_ErrorSevere,
1128 "Port Unresponsive - Idle");
1129 break;
1130 }
1131
1132 sched_yield();
1133 }
1134 }
1135 } /* end of for loop */
1136 VPP_DPRINT("%d pComponentPrivate->sCompPorts[0].pPortDef.nPortIndex = %d\n", __LINE__, pComponentPrivate->sCompPorts[0].pPortDef.nPortIndex);
1137
1138 eError = VPP_Fill_LCMLInitParams(pHandle,array, pLcmlDsp);
1139 VPP_DPRINT("%d pComponentPrivate->sCompPorts[0].pPortDef.nPortIndex = %d\n", __LINE__, pComponentPrivate->sCompPorts[0].pPortDef.nPortIndex);
1140
1141 if (eError != OMX_ErrorNone) {
1142 VPP_DPRINT("VPP::%d :: Error 0x%X returned from Fill_LCMLInitParams()\n",__LINE__,eError);
1143 goto EXIT;
1144 }
1145
1146 pComponentPrivate->pLcmlHandle = (LCML_DSP_INTERFACE *)pLcmlHandle;
1147 cb.LCML_Callback = (void *) VPP_LCML_Callback;
1148
1149 #ifdef __PERF_INSTRUMENTATION__
1150 pComponentPrivate->lcml_nCntIp = 0;
1151 pComponentPrivate->lcml_nCntOpReceived = 0;
1152 #endif
1153
1154 eError = LCML_InitMMCodec(((LCML_DSP_INTERFACE *)pLcmlHandle)->pCodecinterfacehandle,
1155 p,
1156 &pLcmlHandle,
1157 (void *)p,
1158 &cb);
1159 if (eError != OMX_ErrorNone) {
1160 VPP_DPRINT("%d :: Error 0x%X : InitMMCodec failed...>>>>>> \n",__LINE__,eError);
1161 goto EXIT;
1162 }
1163 VPP_DPRINT("%d pComponentPrivate->sCompPorts[0].pPortDef.nPortIndex = %d\n", __LINE__, pComponentPrivate->sCompPorts[0].pPortDef.nPortIndex);
1164
1165 #ifdef LCML_USE_HASH
1166 #ifdef VPP_USE_HASH
1167 /* Enable Hashing for this component */
1168 VPP_DPRINT("enable hashing\n");
1169 LCML_SetHashingState(((LCML_DSP_INTERFACE *)pLcmlHandle)->pCodecinterfacehandle, OMX_TRUE);
1170 #endif
1171 #endif
1172
1173
1174 #ifdef RESOURCE_MANAGER_ENABLED /* Resource Manager Proxy Calls */
1175 pComponentPrivate->rmproxyCallback.RMPROXY_Callback = (void *)ResourceManagerCallback;
1176 if (pComponentPrivate->curState != OMX_StateWaitForResources) {
1177
1178 eError = RMProxy_NewSendCommand(pHandle, RMProxy_RequestResource, OMX_VPP_COMPONENT, 50, 3456, &(pComponentPrivate->rmproxyCallback));/*50Mhz*/
1179 if (eError != OMX_ErrorNone) {
1180 /* resource is not available, need set state to OMX_StateWaitForResources*/
1181 VPP_DPRINT("Resource is not available\n");
1182
1183 pComponentPrivate->cbInfo.EventHandler(pHandle,
1184 pHandle->pApplicationPrivate,
1185 OMX_EventError,
1186 OMX_ErrorInsufficientResources,
1187 OMX_TI_ErrorSevere,
1188 NULL);
1189 eError = OMX_ErrorNone;
1190 goto EXIT;
1191 }
1192 }
1193 #endif
1194
1195 #ifdef __PERF_INSTRUMENTATION__
1196 PERF_Boundary(pComponentPrivate->pPERFcomp,
1197 PERF_BoundaryComplete | PERF_BoundarySetup);
1198 #endif
1199
1200 VPP_DPRINT("%d pComponentPrivate->sCompPorts[0].pPortDef.nPortIndex = %d\n", __LINE__, pComponentPrivate->sCompPorts[0].pPortDef.nPortIndex);
1201
1202 pComponentPrivate->curState = OMX_StateIdle;
1203
1204 #ifdef RESOURCE_MANAGER_ENABLED
1205 eError = RMProxy_NewSendCommand(pHandle, RMProxy_StateSet, OMX_VPP_COMPONENT, OMX_StateIdle, 3456, NULL);
1206 if (eError != OMX_ErrorNone) {
1207 VPP_DPRINT("Resources not available Loaded ->Idle\n");
1208
1209 pComponentPrivate->cbInfo.EventHandler(pHandle,
1210 pHandle->pApplicationPrivate,
1211 OMX_EventError,
1212 OMX_ErrorInsufficientResources,
1213 OMX_TI_ErrorSevere,
1214 NULL);
1215 goto EXIT;
1216 }
1217
1218 #endif
1219
1220 pComponentPrivate->cbInfo.EventHandler(
1221 pHandle,
1222 pHandle->pApplicationPrivate,
1223 OMX_EventCmdComplete,
1224 OMX_CommandStateSet,
1225 pComponentPrivate->curState,
1226 NULL);
1227
1228 VPP_DPRINT("VPP::%d :: VPP: State has been Set to Idle\n",__LINE__);
1229
1230 }
1231 else if (pComponentPrivate->curState == OMX_StateExecuting ||
1232 pComponentPrivate->curState == OMX_StatePause ) {
1233 int nIndex = 0;
1234 OMX_U32 nCount = 0;
1235
1236 int nFilledInBuf = 0;
1237 int nFreeInBuf = 0;
1238 int nFilledOutBuf = 0;
1239 int nFreeOutBuf = 0;
1240 int kk;
1241
1242 pComponentPrivate->bIsStopping = OMX_TRUE;
1243 pComponentPrivate->toState = OMX_StateIdle;
1244 #ifdef LCML_USE_HASH
1245 /* clear out any mappings that might have accumulated */
1246 eError = LCML_FlushHashes(((LCML_DSP_INTERFACE*)pLcmlHandle)->pCodecinterfacehandle);
1247 if (eError != OMX_ErrorNone) {
1248 VPP_DPRINT("Error occurred in Codec mapping flush!\n");
1249 goto EXIT;
1250 }
1251 #endif
1252 VPP_DPRINT("%d :: In HandleCommand: Stopping the codec\n",__LINE__);
1253
1254 #ifdef __PERF_INSTRUMENTATION__
1255 PERF_Boundary(pComponentPrivate->pPERFcomp,
1256 PERF_BoundaryComplete | PERF_BoundarySteadyState);
1257 /* PERF_SendingCommand(pComponentPrivate->pPERFcomp,
1258 MMCodecControlStop,
1259 (OMX_U32) pArgs,
1260 PERF_ModuleCommonLayer); */
1261 #endif
1262 eError = LCML_ControlCodec(
1263 ((LCML_DSP_INTERFACE*)pLcmlHandle)->pCodecinterfacehandle,
1264 MMCodecControlStop,
1265 (void *)pArgs);
1266 if (eError != OMX_ErrorNone) {
1267 VPP_DPRINT("VPP::%d: Error 0x%X Occurred in Codec Stop..\n",__LINE__,eError);
1268 goto EXIT;
1269 }
1270
1271 pthread_mutex_lock(&pComponentPrivate->vpp_mutex);
1272 while ((pComponentPrivate->ExeToIdleFlag & VPP_DSPSTOP) == 0) {
1273 pthread_cond_wait(&pComponentPrivate->stop_cond, &pComponentPrivate->vpp_mutex);
1274 }
1275 pthread_mutex_unlock(&pComponentPrivate->vpp_mutex);
1276
1277 VPP_DPRINT("VPP_Utils.c: get STOP back from DSP\n");
1278 for( nIndex = 0; nIndex < NUM_OF_VPP_PORTS; nIndex++) {
1279 VPP_DPRINT("port %d is %d (%p)\n", nIndex, pComponentPrivate->sCompPorts[nIndex].pPortDef.bEnabled,pComponentPrivate->sCompPorts[nIndex].hTunnelComponent);
1280
1281 /*if (!(pComponentPrivate->sCompPorts[nIndex].pPortDef.bEnabled == OMX_TRUE)) {
1282 continue;
1283 }*/
1284 if (pComponentPrivate->sCompPorts[nIndex].hTunnelComponent != NULL) {
1285 for (nCount = 0; nCount < pComponentPrivate->sCompPorts[nIndex].nBufferCount; nCount++) {
1286 if (!(pComponentPrivate->sCompPorts[nIndex].pVPPBufHeader[nCount].bSelfAllocated == OMX_TRUE)) {
1287 VPP_DPRINT("VPP return buf to tunneled: %d %d\n",
1288 pComponentPrivate->sCompPorts[nIndex].pVPPBufHeader[nCount].pBufHeader->nFlags,
1289 pComponentPrivate->sCompPorts[nIndex].pVPPBufHeader[nCount].pBufHeader->nFilledLen);
1290 pComponentPrivate->sCompPorts[nIndex].pVPPBufHeader[nCount].pBufHeader->nFlags = OMX_BUFFERFLAG_EOS;
1291 pComponentPrivate->sCompPorts[nIndex].pVPPBufHeader[nCount].pBufHeader->nFilledLen = 0;
1292 if (pComponentPrivate->sCompPorts[nIndex].pPortDef.eDir == OMX_DirOutput) {
1293 VPP_DPRINT("VPP is at output port\n");
1294
1295 #ifdef __PERF_INSTRUMENTATION__
1296 PERF_SendingFrame(pComponentPrivate->pPERFcomp,
1297 pComponentPrivate->sCompPorts[nIndex].pVPPBufHeader[nCount].pBufHeader->pBuffer,
1298 pComponentPrivate->sCompPorts[nIndex].pVPPBufHeader[nCount].pBufHeader->nFilledLen,
1299 PERF_ModuleLLMM);
1300 #endif
1301 if(pComponentPrivate->sCompPorts[nIndex].pVPPBufHeader[nCount].eBufferOwner != VPP_BUFFER_CLIENT){
1302 pComponentPrivate->sCompPorts[nIndex].pVPPBufHeader[nCount].eBufferOwner = VPP_BUFFER_CLIENT;
1303 eError = OMX_EmptyThisBuffer(
1304 pComponentPrivate->sCompPorts[nIndex].hTunnelComponent,
1305 pComponentPrivate->sCompPorts[nIndex].pVPPBufHeader[nCount].pBufHeader);
1306 }
1307 }
1308 else { /* pComponentPrivate->sCompPorts[nIndex].pPortDef.eDir == OMX_DirInput */
1309 VPP_DPRINT("VPP is at input port\n");
1310
1311 #ifdef __PERF_INSTRUMENTATION__
1312 PERF_SendingFrame(pComponentPrivate->pPERFcomp,
1313 pComponentPrivate->sCompPorts[nIndex].pVPPBufHeader[nCount].pBufHeader->pBuffer,
1314 0,
1315 PERF_ModuleLLMM);
1316 #endif
1317
1318 VPP_DPRINT("VPP return buffer to tunnel\n");
1319 if(pComponentPrivate->sCompPorts[nIndex].pVPPBufHeader[nCount].eBufferOwner != VPP_BUFFER_CLIENT){
1320 pComponentPrivate->sCompPorts[nIndex].pVPPBufHeader[nCount].eBufferOwner = VPP_BUFFER_CLIENT;
1321 VPP_DPRINT("VPP_UTILS: call to OMX_FillThisBuffer():: %d\n", __LINE__);
1322 eError = OMX_FillThisBuffer(
1323 pComponentPrivate->sCompPorts[nIndex].hTunnelComponent,
1324 pComponentPrivate->sCompPorts[nIndex].pVPPBufHeader[nCount].pBufHeader);
1325 }
1326 }
1327 }
1328 }
1329 } else { /* pComponentPrivate->sCompPorts[nIndex].hTunnelComponent == NULL */
1330
1331
1332 /* for (nIndex = 0; nIndex < NUM_OF_VPP_PORTS; nIndex ++) { */
1333 VPP_DPRINT("VPP_Utils.c: (%d) %d %p\n", __LINE__, nIndex, pComponentPrivate->sCompPorts[nIndex].hTunnelComponent);
1334 for (nCount = 0; nCount < pComponentPrivate->sCompPorts[nIndex].nBufferCount; nCount++) {
1335 VPP_DPRINT("VPP:: port %d count %d bufHeader %p owner %d\n", nIndex, nCount,
1336 pComponentPrivate->sCompPorts[nIndex].pVPPBufHeader[nCount].pBufHeader,
1337 pComponentPrivate->sCompPorts[nIndex].pVPPBufHeader[nCount].eBufferOwner);
1338 pthread_mutex_lock(&pComponentPrivate->buf_mutex);
1339 if (pComponentPrivate->sCompPorts[nIndex].pVPPBufHeader[nCount].eBufferOwner != VPP_BUFFER_CLIENT) {
1340 if (pComponentPrivate->sCompPorts[nIndex].pVPPBufHeader[nCount].eBufferOwner == VPP_BUFFER_COMPONENT_IN){
1341 if (nIndex == 0 || nIndex == 1) {
1342 nFilledInBuf ++;
1343 } else {
1344 VPP_DPRINT("index %d cnt %d owner %d %p\n", nIndex, nCount,
1345 pComponentPrivate->sCompPorts[nIndex].pVPPBufHeader[nCount].eBufferOwner,
1346 pComponentPrivate->sCompPorts[nIndex].pVPPBufHeader[nCount].pBufHeader);
1347 nFreeOutBuf ++;
1348 }
1349 } else if (pComponentPrivate->sCompPorts[nIndex].pVPPBufHeader[nCount].eBufferOwner == VPP_BUFFER_COMPONENT_OUT){
1350 if (nIndex == 0 || nIndex == 1) {
1351 nFreeInBuf ++;
1352 } else {
1353 nFilledOutBuf ++;
1354 }
1355 } else {
1356 VPP_DPRINT("Buffer %p is in DSP, error!\n", pComponentPrivate->sCompPorts[nIndex].pVPPBufHeader[nCount].pBufHeader);
1357 pComponentPrivate->sCompPorts[nIndex].pVPPBufHeader[nCount].eBufferOwner = VPP_BUFFER_CLIENT;
1358 if (nIndex == 0 || nIndex == 1) {
1359
1360 pComponentPrivate->cbInfo.EmptyBufferDone(
1361 pHandle,
1362 pHandle->pApplicationPrivate,
1363 pComponentPrivate->sCompPorts[nIndex].pVPPBufHeader[nCount].pBufHeader);
1364 } else {
1365 pComponentPrivate->cbInfo.FillBufferDone(
1366 pHandle,
1367 pHandle->pApplicationPrivate,
1368 pComponentPrivate->sCompPorts[nIndex].pVPPBufHeader[nCount].pBufHeader);
1369 }
1370 }
1371 }
1372 pthread_mutex_unlock(&pComponentPrivate->buf_mutex);
1373 }
1374 VPP_DPRINT("nFilledInBuf %d nFreeInBuf %d nFilledOutBuf %d nFreeOutBuf %d\n", nFilledInBuf, nFreeInBuf, nFilledOutBuf, nFreeOutBuf);
1375 }
1376 }
1377
1378 VPP_DPRINT("nFilledInBuf %d nFreeInBuf %d nFilledOutBuf %d nFreeOutBuf %d\n", nFilledInBuf, nFreeInBuf, nFilledOutBuf, nFreeOutBuf);
1379 for (kk = 0; kk < nFilledInBuf; kk ++) {
1380 VPP_Process_FilledInBuf(pComponentPrivate);
1381 }
1382 for (kk = 0; kk < nFreeOutBuf; kk ++) {
1383 VPP_Process_FreeOutBuf(pComponentPrivate);
1384 }
1385 VPP_DPRINT("VPP after loop: nFilledInBuf %d nFreeInBuf %d nFilledOutBuf %d nFreeOutBuf %d\n", nFilledInBuf, nFreeInBuf, nFilledOutBuf, nFreeOutBuf);
1386
1387 for( nIndex = 0; nIndex < NUM_OF_VPP_PORTS; nIndex++) {
1388 VPP_DPRINT("port %d is %d (%p)\n", nIndex, pComponentPrivate->sCompPorts[nIndex].pPortDef.bEnabled,pComponentPrivate->sCompPorts[nIndex].hTunnelComponent);
1389 if (pComponentPrivate->sCompPorts[nIndex].pPortDef.bEnabled == OMX_FALSE) {
1390 continue;
1391 }
1392 if (pComponentPrivate->sCompPorts[nIndex].hTunnelComponent != NULL) {
1393 for (nCount = 0; nCount < pComponentPrivate->sCompPorts[nIndex].nBufferCount; nCount++) {
1394 if (pComponentPrivate->sCompPorts[nIndex].pPortDef.eDir == OMX_DirOutput
1395 && pComponentPrivate->sCompPorts[nIndex].eSupplierSetting == OMX_BufferSupplyOutput) {
1396 VPP_DPRINT("VPP :: pHandle=%p, eBufferOwner= %d, nIndex= %d\n", pComponentPrivate->pHandle, pComponentPrivate->sCompPorts[nIndex].pVPPBufHeader[nCount].eBufferOwner, nIndex);
1397
1398
1399 if(pComponentPrivate->sCompPorts[nIndex].pVPPBufHeader[nCount].eBufferOwner == VPP_BUFFER_DSP) {
1400 pComponentPrivate->sCompPorts[nIndex].pVPPBufHeader[nCount].eBufferOwner = VPP_BUFFER_COMPONENT_OUT;;
1401 }
1402 while((pComponentPrivate->sCompPorts[nIndex].pVPPBufHeader[nCount].eBufferOwner != VPP_BUFFER_COMPONENT_IN) &&
1403 (pComponentPrivate->sCompPorts[nIndex].pVPPBufHeader[nCount].eBufferOwner != VPP_BUFFER_COMPONENT_OUT)){
1404 pComponentPrivate->sCompPorts[nIndex].pVPPBufHeader[nCount].eBufferOwner = VPP_BUFFER_COMPONENT_OUT;
1405 sched_yield();
1406 }
1407 VPP_DPRINT("VPP:: Component have all the buffers, eBufferOwner= %d\n", pComponentPrivate->sCompPorts[nIndex].pVPPBufHeader[nCount].eBufferOwner);
1408 }
1409 else if(pComponentPrivate->sCompPorts[nIndex].pPortDef.eDir == OMX_DirInput
1410 && pComponentPrivate->sCompPorts[nIndex].eSupplierSetting == OMX_BufferSupplyInput) {
1411 VPP_DPRINT("VPP Utils :: pHandle=%p, eBufferOwner= %d, nIndex= %d\n", pComponentPrivate->pHandle, pComponentPrivate->sCompPorts[nIndex].pVPPBufHeader[nCount].eBufferOwner, nIndex);
1412
1413
1414 if(pComponentPrivate->sCompPorts[nIndex].pVPPBufHeader[nCount].eBufferOwner == VPP_BUFFER_DSP) {
1415 pComponentPrivate->sCompPorts[nIndex].pVPPBufHeader[nCount].eBufferOwner = VPP_BUFFER_COMPONENT_OUT;;
1416 }
1417 while((pComponentPrivate->sCompPorts[nIndex].pVPPBufHeader[nCount].eBufferOwner != VPP_BUFFER_COMPONENT_IN) &&
1418 (pComponentPrivate->sCompPorts[nIndex].pVPPBufHeader[nCount].eBufferOwner != VPP_BUFFER_COMPONENT_OUT)){
1419 sched_yield();
1420 }
1421 VPP_DPRINT("VPP Utils:: Component have all the buffers, eBufferOwner= %d\n", pComponentPrivate->sCompPorts[nIndex].pVPPBufHeader[nCount].eBufferOwner);
1422
1423 }
1424 }
1425 }
1426 }
1427
1428 pComponentPrivate->ExeToIdleFlag |= VPP_BUFFERBACK;
1429 if (pComponentPrivate->ExeToIdleFlag == VPP_IDLEREADY) {
1430 pComponentPrivate->curState = OMX_StateIdle;
1431 pComponentPrivate->cbInfo.EventHandler (
1432 pHandle,
1433 pHandle->pApplicationPrivate,
1434 OMX_EventCmdComplete,
1435 OMX_ErrorNone,
1436 OMX_StateIdle,
1437 "NULL");
1438 pComponentPrivate->ExeToIdleFlag = VPP_ZERO;
1439 }
1440 #ifdef RESOURCE_MANAGER_ENABLED
1441
1442 eError = RMProxy_NewSendCommand(pHandle, RMProxy_StateSet, OMX_VPP_COMPONENT, OMX_StateIdle, 3456, NULL);
1443 #endif
1444
1445 }
1446 else {
1447 VPP_DPRINT("%d: Comp: Sending ErrorNotification: Invalid State\n", __LINE__);
1448 pComponentPrivate->cbInfo.EventHandler(
1449 pHandle,
1450 pHandle->pApplicationPrivate,
1451 OMX_EventCmdComplete,
1452 OMX_ErrorInvalidState,
1453 0,
1454 "Invalid State Error from VPP");
1455 }
1456 EXIT:
1457 return eError;
1458 }
1459
1460
1461
1462 /* ========================================================================== */
1463 /**
1464 * @StateToExecuting() This function is called by the component when ever it
1465 * receives the command from the application
1466 *
1467 * @param pComponentPrivate Component private data
1468 *
1469 * @pre
1470 *
1471 * @post
1472 *
1473 * @return none
1474 */
1475 /* ========================================================================== */
VPP_StateToExecuting(VPP_COMPONENT_PRIVATE * pComponentPrivate)1476 OMX_ERRORTYPE VPP_StateToExecuting(VPP_COMPONENT_PRIVATE *pComponentPrivate)
1477 {
1478 OMX_ERRORTYPE eError = OMX_ErrorNone;
1479 OMX_COMPONENTTYPE *pHandle = (OMX_COMPONENTTYPE *) pComponentPrivate->pHandle;
1480 OMX_HANDLETYPE pLcmlHandle = pComponentPrivate->pLcmlHandle;
1481 OMX_BUFFERHEADERTYPE *pBufHdr = NULL;
1482 int i, j;
1483 int nBuf;
1484 char *pArgs = "damedesuStr";
1485
1486
1487 VPP_DPRINT("VPP::%d: HandleCommand: Cmd Executing \n",__LINE__);
1488
1489 if (pComponentPrivate->curState == OMX_StateExecuting) {
1490 VPP_DPRINT("VPP: send OMX_ErrorSameState from OMX_StateInvalid\n");
1491 pComponentPrivate->cbInfo.EventHandler(
1492 pComponentPrivate->pHandle,
1493 pComponentPrivate->pHandle->pApplicationPrivate,
1494 OMX_EventError,
1495 OMX_ErrorSameState,
1496 OMX_TI_ErrorMinor,
1497 NULL);
1498 if (eError != OMX_ErrorNone) {
1499 }
1500 goto EXIT;
1501 }
1502
1503 pComponentPrivate->toState = OMX_StateExecuting;
1504
1505 if (pComponentPrivate->curState == OMX_StateIdle) {/* from Idle to Executing */
1506 OMX_U32 Inputports = 1;
1507 int bufCount;
1508
1509 pComponentPrivate->tVPPIOConf->overlayInputImage = 0;
1510 pComponentPrivate->tVPPIOConf->YUVOutputImage = 0;
1511 pComponentPrivate->tVPPIOConf->RGBOutputImage = 0;
1512
1513 pComponentPrivate->sCompPorts[OMX_VPP_INPUT_PORT].nReturnedBufferCount = pComponentPrivate->sCompPorts[OMX_VPP_INPUT_PORT].nBufferCount; /*usmc*/
1514
1515
1516 if(pComponentPrivate->IsOverlay == OMX_TRUE) {
1517 pComponentPrivate->tVPPIOConf->overlayInputImage = 1;
1518 Inputports =2;
1519 }
1520
1521 if(pComponentPrivate->NumofOutputPort && pComponentPrivate->NumofOutputPort < 2 ) {
1522 if (pComponentPrivate->IsYUVdataout) {
1523 pComponentPrivate->tVPPIOConf->YUVOutputImage = 1;
1524 }
1525 else {
1526 pComponentPrivate->tVPPIOConf->RGBOutputImage = 1;
1527 }
1528 }
1529 else if(pComponentPrivate->NumofOutputPort == 2) {
1530 pComponentPrivate->tVPPIOConf->YUVOutputImage = 1;
1531 pComponentPrivate->tVPPIOConf->RGBOutputImage = 1;
1532 }
1533
1534
1535 VPP_DPRINT("VPP::%d: before START control \n",__LINE__);
1536
1537
1538 eError = LCML_ControlCodec(
1539 ((LCML_DSP_INTERFACE*)pLcmlHandle)->pCodecinterfacehandle,
1540 EMMCodecControlStart,
1541 (void *)pArgs);
1542 if (eError != OMX_ErrorNone) {
1543 VPP_DPRINT("VPP::%d: Error 0x%X Occurred in Codec Start..\n",__LINE__,eError);
1544 goto EXIT;
1545 }
1546
1547 pComponentPrivate->bIsStopping=0;
1548
1549 VPP_DPRINT ("VPP::%d :: Comp :: After LCML_StartCodec function \n",__LINE__);
1550
1551 for( j=0; j<(int)Inputports; j++) {
1552 nBuf =pComponentPrivate->sCompPorts[j].nBufferCount;
1553 VPP_DPRINT ("VPP::Sending Input buffer to Application bufcount=%lu \n",nBuf);
1554
1555 /*TUNNEL HERE */
1556 for (bufCount = 0; bufCount < nBuf; bufCount++) {
1557 pBufHdr = pComponentPrivate->sCompPorts[j].pVPPBufHeader[bufCount].pBufHeader;
1558 if ((pComponentPrivate->sCompPorts[j].hTunnelComponent != NULL) &&
1559 (pComponentPrivate->sCompPorts[j].eSupplierSetting == OMX_BufferSupplyInput)) {
1560 /* VPP owns this buffer */
1561
1562 VPP_DPRINT("VPP: send fillthisbuffer, out index %p, %d\n", pBufHdr, pBufHdr->nOutputPortIndex);
1563
1564 #ifdef __PERF_INSTRUMENTATION__
1565 PERF_SendingFrame(pComponentPrivate->pPERFcomp,
1566 PREF(pBufHdr,pBuffer),
1567 0,
1568 PERF_ModuleLLMM);
1569 #endif
1570
1571 pComponentPrivate->sCompPorts[j].pVPPBufHeader[bufCount].eBufferOwner = VPP_BUFFER_CLIENT;
1572 VPP_DPRINT("VPP_UTILS: call to OMX_FillThisBuffer():: %d\n", __LINE__);
1573 OMX_FillThisBuffer(pComponentPrivate->sCompPorts[j].hTunnelComponent, pBufHdr);
1574 }
1575 }
1576 }
1577
1578 VPP_DPRINT("VPP:: %d:: Ports Available in Fill_LCMLInitParams %ld\n ",__LINE__, pComponentPrivate->NumofOutputPort);
1579
1580 if (pComponentPrivate->IsYUVdataout){
1581 nBuf = pComponentPrivate->sCompPorts[OMX_VPP_YUV_OUTPUT_PORT].nBufferCount;
1582 if ((pComponentPrivate->sCompPorts[OMX_VPP_YUV_OUTPUT_PORT].hTunnelComponent != NULL) &&
1583 (pComponentPrivate->sCompPorts[OMX_VPP_YUV_OUTPUT_PORT].eSupplierSetting == OMX_BufferSupplyOutput)) {
1584 for (i=0; i < nBuf; i++) {
1585 pBufHdr = pComponentPrivate->sCompPorts[OMX_VPP_YUV_OUTPUT_PORT].pVPPBufHeader[i].pBufHeader;
1586
1587 #ifdef __PERF_INSTRUMENTATION__
1588 PERF_SendingFrame(pComponentPrivate->pPERFcomp,
1589 pBufHdr->pBuffer,
1590 pBufHdr->nFilledLen,
1591 PERF_ModuleCommonLayer);
1592 #endif
1593 VPP_DPRINT("LCML_QueueBuffer YUV: %s::%s: %d: VPP\n", __FILE__, __FUNCTION__, __LINE__);
1594 eError = LCML_QueueBuffer(
1595 ((LCML_DSP_INTERFACE*)pLcmlHandle)->pCodecinterfacehandle,
1596 EMMCodecStream3,
1597 pBufHdr->pBuffer,
1598 pBufHdr->nAllocLen,0,
1599 (OMX_U8 *)pComponentPrivate->pOpYUVFrameStatus,
1600 sizeof(GPPToVPPOutputFrameStatus),
1601 (void *)pBufHdr);
1602 if (eError != OMX_ErrorNone) {
1603 VPP_DPRINT("VPP::%d :: Comp:: Error 0x%X While sending the output buffers to Codec\n", __LINE__,eError);
1604 goto EXIT;
1605 }
1606 VPP_DPRINT ("VPP::%d :: Component Sending Output buffer to Codec %p\n",__LINE__, pBufHdr);
1607 }
1608 }
1609 }
1610 else if(pComponentPrivate->IsRGBdataout){
1611 nBuf = pComponentPrivate->sCompPorts[OMX_VPP_RGB_OUTPUT_PORT].nBufferCount;
1612 if ((pComponentPrivate->sCompPorts[OMX_VPP_RGB_OUTPUT_PORT].hTunnelComponent != NULL) &&
1613 (pComponentPrivate->sCompPorts[OMX_VPP_RGB_OUTPUT_PORT].eSupplierSetting == OMX_BufferSupplyOutput)) {
1614 for (i=0; i < nBuf; i++) {
1615 pBufHdr = pComponentPrivate->sCompPorts[OMX_VPP_RGB_OUTPUT_PORT].pVPPBufHeader[i].pBufHeader;
1616
1617 #ifdef __PERF_INSTRUMENTATION__
1618 PERF_SendingFrame(pComponentPrivate->pPERFcomp,
1619 pBufHdr->pBuffer,
1620 pBufHdr->nFilledLen,
1621 PERF_ModuleCommonLayer);
1622 #endif
1623 VPP_DPRINT("LCML_QueueBuffer RGB: %s::%s: %d: VPP\n", __FILE__, __FUNCTION__, __LINE__);
1624 eError = LCML_QueueBuffer(
1625 ((LCML_DSP_INTERFACE*)pLcmlHandle)->pCodecinterfacehandle,
1626 EMMCodecStream2,
1627 pBufHdr->pBuffer,
1628 pBufHdr->nAllocLen,0,
1629 (OMX_U8 *)pComponentPrivate->pOpRGBFrameStatus,
1630 sizeof(GPPToVPPOutputFrameStatus),
1631 (void *)pBufHdr);
1632 if (eError != OMX_ErrorNone) {
1633 VPP_DPRINT("VPP::%d :: Comp:: Error 0x%X While sending the output buffers to Codec\n", __LINE__,eError);
1634 goto EXIT;
1635 }
1636 VPP_DPRINT ("VPP::%d :: Component Sending Output buffer to Codec %p\n",__LINE__, pBufHdr);
1637 }
1638 }
1639 }
1640 else{
1641 eError = OMX_ErrorUndefined;
1642 VPP_DPRINT("VPP:: %d : No Port enable\n");
1643 goto EXIT;
1644 }
1645 }
1646 else if (pComponentPrivate->curState == OMX_StatePause) {
1647 #ifdef RESOURCE_MANAGER_ENABLED
1648 VPP_DPRINT("%d: Comp: Resume Command Came from App\n",__LINE__);
1649 #endif
1650
1651 /* char *pArgs = "damedesuStr";*/
1652 eError = LCML_ControlCodec(
1653 ((LCML_DSP_INTERFACE*)pLcmlHandle)->pCodecinterfacehandle,
1654 EMMCodecControlStart,(void *)pArgs);
1655
1656 if (eError != OMX_ErrorNone) {
1657 VPP_DPRINT ("Error While Resuming the codec\n");
1658 goto EXIT;
1659 }
1660 }
1661 else { /* if current state is not Idle or Pause ... */
1662 pComponentPrivate->cbInfo.EventHandler (
1663 pHandle, pHandle->pApplicationPrivate,
1664 OMX_EventError,
1665 OMX_ErrorIncorrectStateTransition,OMX_TI_ErrorMinor,
1666 "Invalid State from VPP");
1667 VPP_DPRINT("%d :: Error: Invalid State Given by Application\n",__LINE__);
1668 goto EXIT;
1669 }
1670
1671 pComponentPrivate->ExeToIdleFlag = VPP_ZERO;
1672
1673 pComponentPrivate->toState = OMX_StateExecuting;
1674 #ifdef RESOURCE_MANAGER_ENABLED
1675 eError = RMProxy_NewSendCommand(pHandle, RMProxy_StateSet, OMX_VPP_COMPONENT, OMX_StateExecuting, 3456, NULL);
1676 #endif
1677 pComponentPrivate->curState = OMX_StateExecuting;
1678 pComponentPrivate->cbInfo.EventHandler(
1679 pHandle,
1680 pHandle->pApplicationPrivate,
1681 OMX_EventCmdComplete,
1682 OMX_ErrorNone,
1683 OMX_StateExecuting,
1684 NULL);
1685
1686 EXIT:
1687 return eError;
1688 }
1689
1690
1691
1692 /* ========================================================================== */
1693 /**
1694 * @StateToLoaded() This function is called by the component when ever it
1695 * receives the command from the application
1696 *
1697 * @param pComponentPrivate Component private data
1698 *
1699 * @pre
1700 *
1701 * @post
1702 *
1703 * @return none
1704 */
1705 /* ========================================================================== */
VPP_StateToLoaded(VPP_COMPONENT_PRIVATE * pComponentPrivate)1706 OMX_ERRORTYPE VPP_StateToLoaded(VPP_COMPONENT_PRIVATE *pComponentPrivate)
1707 {
1708 OMX_ERRORTYPE eError = OMX_ErrorNone;
1709 OMX_COMPONENTTYPE *pHandle = (OMX_COMPONENTTYPE *) pComponentPrivate->pHandle;
1710 OMX_HANDLETYPE pLcmlHandle = pComponentPrivate->pLcmlHandle;
1711 OMX_PARAM_PORTDEFINITIONTYPE *pPortDef = NULL;
1712 int nPortIndex;
1713 OMX_U32 nTimeout = 0;
1714
1715 VPP_DPRINT("VPP::%d: HandleCommand: Cmd Loaded\n",__LINE__);
1716 VPP_DPRINT("VPP: %d: HandleCommand: Cmd Loaded, current state: %d\n",__LINE__, pComponentPrivate->curState);
1717
1718 if (pComponentPrivate->curState != OMX_StateIdle && pComponentPrivate->curState != OMX_StateWaitForResources ) {
1719 pComponentPrivate->cbInfo.EventHandler (
1720 pHandle,
1721 pHandle->pApplicationPrivate,
1722 OMX_EventError,
1723 OMX_ErrorIncorrectStateTransition,
1724 OMX_TI_ErrorMinor,
1725 "Invalid State from VPP");
1726 VPP_DPRINT("%d :: Error: Invalid State Given by Application\n",__LINE__);
1727 goto EXIT;
1728 }
1729
1730 pComponentPrivate->toState = OMX_StateLoaded;
1731
1732 if (pComponentPrivate->curState == OMX_StateIdle ||
1733 pComponentPrivate->curState == OMX_StateWaitForResources) {
1734
1735 #ifdef __PERF_INSTRUMENTATION__
1736 PERF_Boundary(pComponentPrivate->pPERFcomp,
1737 PERF_BoundaryStart | PERF_BoundaryCleanup);
1738 #endif
1739
1740 #ifdef RESOURCE_MANAGER_ENABLED
1741 if (pComponentPrivate->curState == OMX_StateWaitForResources) {
1742 eError= RMProxy_NewSendCommand(pHandle, RMProxy_CancelWaitForResource, OMX_VPP_COMPONENT, 0, 3456, NULL);
1743 if (eError != OMX_ErrorNone) {
1744 VPP_DPRINT("CancelWaitForResource Failed\n");
1745 pComponentPrivate->cbInfo.EventHandler(pHandle,
1746 pHandle->pApplicationPrivate,
1747 OMX_EventError,
1748 OMX_ErrorUndefined,
1749 OMX_TI_ErrorSevere,
1750 NULL);
1751 goto EXIT;
1752 }
1753 }
1754
1755 if (pComponentPrivate->curState != OMX_StateWaitForResources) {
1756 eError= RMProxy_NewSendCommand(pHandle, RMProxy_FreeResource, OMX_VPP_COMPONENT, 0, 3456, NULL);
1757 if (eError != OMX_ErrorNone) {
1758 VPP_DPRINT("Cannot Free Resources\n");
1759 pComponentPrivate->cbInfo.EventHandler(pHandle,
1760 pHandle->pApplicationPrivate,
1761 OMX_EventError,
1762 OMX_ErrorUndefined,
1763 OMX_TI_ErrorSevere,
1764 NULL);
1765 goto EXIT;
1766 }
1767 }
1768 #endif
1769
1770 if (pLcmlHandle !=NULL) {
1771 VPP_DPRINT("VPP::%d: HandleCommand: : Loaded calling destroy\n",__LINE__);
1772 eError = LCML_ControlCodec(((LCML_DSP_INTERFACE*)pLcmlHandle)->pCodecinterfacehandle,
1773 EMMCodecControlDestroy,
1774 NULL);
1775 #ifdef UNDER_CE
1776 FreeLibrary(g_hLcmlDllHandle);
1777 g_hLcmlDllHandle = NULL;
1778 #else
1779
1780 VPP_DPRINT("VPP: %d\n", __LINE__);
1781 if(pComponentPrivate->pLcmlHandle){
1782 dlclose(pComponentPrivate->pDllHandle);
1783 pComponentPrivate->pLcmlHandle = NULL;
1784 pComponentPrivate->pLCML = NULL;
1785 }
1786
1787 #endif
1788 if (eError != OMX_ErrorNone) {
1789 VPP_DPRINT("VPP::%d : Error 0x%X: in Destroying the codec\n",__LINE__,eError);
1790 goto EXIT;
1791 }
1792 }
1793 VPP_DPRINT("VPP: %d\n", __LINE__);
1794 for(nPortIndex = 0; nPortIndex < NUM_OF_VPP_PORTS; nPortIndex++) {
1795 VPP_DPRINT("VPP free tunneled buf %d %p %x %x\n", nPortIndex,
1796 pComponentPrivate->sCompPorts[nPortIndex].hTunnelComponent,
1797 pComponentPrivate->sCompPorts[nPortIndex].nBufSupplier,
1798 pComponentPrivate->sCompPorts[nPortIndex].pPortDef.bEnabled);
1799
1800 if (pComponentPrivate->sCompPorts[nPortIndex].hTunnelComponent != NULL &&
1801 pComponentPrivate->sCompPorts[nPortIndex].nBufSupplier == OMX_TRUE
1802 /*&& pComponentPrivate->sCompPorts[nPortIndex].pVPPBufHeader[0].bSelfAllocated*/) {
1803 OMX_U32 nBuf;
1804 OMX_U8 *pBufferStart = NULL;
1805 OMX_BUFFERHEADERTYPE *pBufHeader;
1806
1807 for (nBuf=0; nBuf<pComponentPrivate->sCompPorts[nPortIndex].pPortDef.nBufferCountActual; nBuf++) {
1808 VPP_DPRINT("PORT %d is Supplier !! .....\n",nPortIndex);
1809 pBufferStart = pComponentPrivate->sCompPorts[nPortIndex].pVPPBufHeader[nBuf].pBufferStart;
1810 pBufHeader = pComponentPrivate->sCompPorts[nPortIndex].pVPPBufHeader[nBuf].pBufHeader;
1811
1812
1813 #ifdef __PERF_INSTRUMENTATION__
1814 PERF_SendingFrame(pComponentPrivate->pPERFcomp,
1815 PREF(pBufHeader,pBuffer),
1816 PREF(pBufHeader,nAllocLen),
1817 PERF_ModuleLLMM);
1818 #endif
1819
1820 if(pBufHeader != NULL){
1821 OMX_FREE(pBufferStart);
1822 pBufferStart = NULL;
1823 pBufHeader->pBuffer = NULL;
1824 }
1825
1826 pComponentPrivate->sCompPorts[nPortIndex].nBufferCount --;
1827 pComponentPrivate->sCompPorts[nPortIndex].pPortDef.bPopulated = OMX_FALSE;
1828 eError = OMX_FreeBuffer(pComponentPrivate->sCompPorts[nPortIndex].hTunnelComponent,
1829 pComponentPrivate->sCompPorts[nPortIndex].nTunnelPort,
1830 pComponentPrivate->sCompPorts[nPortIndex].pVPPBufHeader[nBuf].pBufHeader
1831 );
1832 if (eError != OMX_ErrorNone) {
1833 VPP_DPRINT ("OMX_FreeBuffer Failed !! .....\n");
1834 goto EXIT;
1835 }
1836 }
1837
1838 }/*End of Tunneling component*/
1839
1840 pComponentPrivate->nInputFrame = 0;
1841 pComponentPrivate->nOverlayFrame = 0;
1842 pComponentPrivate->nInYUVBufferCount = 0;
1843 pComponentPrivate->nInRGBBufferCount = 0;
1844 pComponentPrivate->nOutYUVBufferCount = 0;
1845 pComponentPrivate->nOutRGBBufferCount = 0;
1846
1847 pPortDef = &(pComponentPrivate->sCompPorts[nPortIndex].pPortDef);
1848 VPP_DPRINT("%d pPortDef.bEnabled %d\n", nPortIndex, pComponentPrivate->sCompPorts[nPortIndex].pPortDef.bEnabled);
1849 if (pComponentPrivate->sCompPorts[nPortIndex].pPortDef.bEnabled == OMX_TRUE) {
1850 nTimeout = 0;
1851 while(1)
1852 {
1853 if (!pComponentPrivate->sCompPorts[nPortIndex].pPortDef.bPopulated) {
1854 break;
1855 }
1856 else if (nTimeout++ > 0xEFFFFFFE) {
1857 pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle,
1858 pComponentPrivate->pHandle->pApplicationPrivate,
1859 OMX_EventError,
1860 OMX_ErrorPortUnresponsiveDuringDeallocation,
1861 OMX_TI_ErrorSevere,
1862 "Port Unresponsive - Idle");
1863 break;
1864 }
1865 sched_yield();
1866 }
1867 }
1868 }
1869 }
1870
1871
1872 #if 0
1873 #ifdef __PERF_INSTRUMENTATION__
1874 PERF_Boundary(pComponentPrivate->pPERFcomp,
1875 PERF_BoundaryComplete | PERF_BoundaryCleanup);
1876 #endif
1877 #endif
1878
1879
1880
1881 if ((pComponentPrivate->curState == OMX_StateIdle) &&
1882 (pComponentPrivate->bPreempted == 1 )){
1883
1884 pComponentPrivate->curState = OMX_StateLoaded;
1885 pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle,
1886 pComponentPrivate->pHandle->pApplicationPrivate,
1887 OMX_EventError,
1888 OMX_ErrorResourcesLost,
1889 OMX_TI_ErrorSevere,
1890 NULL);
1891 pComponentPrivate->bPreempted = 0;
1892 }
1893 else {
1894 pComponentPrivate->curState = OMX_StateLoaded;
1895 pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle,
1896 pComponentPrivate->pHandle->pApplicationPrivate,
1897 OMX_EventCmdComplete,
1898 OMX_CommandStateSet,
1899 OMX_StateLoaded,
1900 NULL);
1901 }
1902
1903 EXIT:
1904 return eError;
1905 }
1906
1907
1908
1909 /* ========================================================================== */
1910 /**
1911 * @HandleCommand() This function is called by the component when ever it
1912 * receives the command from the application
1913 *
1914 * @param pComponentPrivate Component private data
1915 *
1916 * @pre
1917 *
1918 * @post
1919 *
1920 * @return none
1921 */
1922 /* ========================================================================== */
VPP_HandleCommand(VPP_COMPONENT_PRIVATE * pComponentPrivate,OMX_U32 nParam1)1923 OMX_ERRORTYPE VPP_HandleCommand (VPP_COMPONENT_PRIVATE *pComponentPrivate, OMX_U32 nParam1)
1924 {
1925 OMX_ERRORTYPE eError = OMX_ErrorNone;
1926 char *pArgs = "damedesuStr";
1927 /*OMX_COMPONENTTYPE *pHandle = (OMX_COMPONENTTYPE *) pComponentPrivate->pHandle;*/
1928 OMX_HANDLETYPE pLcmlHandle = pComponentPrivate->pLcmlHandle;
1929
1930 VPP_DPRINT ("VPP::%d :: >>> Entering HandleCommand Function\n",__LINE__);
1931
1932 if (pComponentPrivate->curState == nParam1) {
1933 VPP_DPRINT("VPP: send OMX_ErrorSameState from OMX_StateInvalid\n");
1934 pComponentPrivate->cbInfo.EventHandler(
1935 pComponentPrivate->pHandle,
1936 pComponentPrivate->pHandle->pApplicationPrivate,
1937 OMX_EventError,
1938 OMX_ErrorSameState,
1939 OMX_TI_ErrorMinor,
1940 NULL);
1941 if (eError != OMX_ErrorNone) {
1942 VPP_DPRINT("VPP::%d : Error 0x%X: in Destroying the codec\n",__LINE__,eError);
1943 }
1944 goto EXIT;
1945 }
1946
1947 switch(nParam1)
1948 {
1949 case OMX_StateInvalid:
1950 if (pComponentPrivate->curState == OMX_StateIdle ||
1951 pComponentPrivate->curState == OMX_StateExecuting ||
1952 pComponentPrivate->curState == OMX_StatePause ) {
1953 eError = LCML_ControlCodec(
1954 ((LCML_DSP_INTERFACE*)pLcmlHandle)->pCodecinterfacehandle,
1955 EMMCodecControlDestroy,
1956 NULL);
1957 #ifdef UNDER_CE
1958 FreeLibrary(g_hLcmlDllHandle);
1959 g_hLcmlDllHandle = NULL;
1960 #else
1961 if(pComponentPrivate->pLcmlHandle){
1962 dlclose(pComponentPrivate->pDllHandle);
1963 pComponentPrivate->pLcmlHandle = NULL;
1964 pComponentPrivate->pLCML = NULL;
1965 }
1966 #endif
1967 }
1968 pComponentPrivate->curState = OMX_StateInvalid;
1969 pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle,
1970 pComponentPrivate->pHandle->pApplicationPrivate,
1971 OMX_EventError,
1972 OMX_ErrorInvalidState,
1973 OMX_TI_ErrorCritical,
1974 NULL);
1975 pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle,
1976 pComponentPrivate->pHandle->pApplicationPrivate,
1977 OMX_EventCmdComplete,
1978 OMX_CommandStateSet,
1979 pComponentPrivate->curState,
1980 NULL);
1981 break;
1982 case OMX_StateIdle:
1983 eError = VPP_StateToIdle(pComponentPrivate);
1984 break;
1985 case OMX_StateExecuting:
1986 eError = VPP_StateToExecuting(pComponentPrivate);
1987 break;
1988 case OMX_StateLoaded:
1989 eError = VPP_StateToLoaded(pComponentPrivate);
1990 break;
1991 case OMX_StatePause:
1992 VPP_DPRINT("%d: HandleCommand: Cmd Pause: Cur State = %d\n",__LINE__, pComponentPrivate->curState);
1993 if ( pComponentPrivate->curState == OMX_StateExecuting ||
1994 pComponentPrivate->curState == OMX_StateIdle ) {
1995
1996 #ifdef __PERF_INSTRUMENTATION__
1997 PERF_Boundary(pComponentPrivate->pPERFcomp,
1998 PERF_BoundaryComplete | PERF_BoundarySteadyState);
1999 #endif
2000
2001 pComponentPrivate->toState = OMX_StatePause;
2002 pComponentPrivate->ExeToIdleFlag = VPP_ZERO;
2003 eError = LCML_ControlCodec(
2004 ((LCML_DSP_INTERFACE*)pLcmlHandle)->pCodecinterfacehandle,
2005 EMMCodecControlPause,
2006 (void *)pArgs);
2007
2008 if (eError != OMX_ErrorNone) {
2009 VPP_DPRINT("VPP::%d : Error0x%X: in Pausing the codec\n",__LINE__,eError);
2010 goto EXIT;
2011 }
2012
2013 /*Sending to Idle until receiving EMMCodecProcessingPaused call back*/
2014
2015 }
2016 else {
2017 pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle,
2018 pComponentPrivate->pHandle->pApplicationPrivate,
2019 OMX_EventError,
2020 OMX_ErrorIncorrectStateTransition,
2021 OMX_TI_ErrorMinor,
2022 NULL);
2023 VPP_DPRINT ("VPP::%d :: Error: Invalid State Given by Application\n",__LINE__);
2024 }
2025 break;
2026 case OMX_StateWaitForResources:
2027 VPP_DPRINT("VPP: SetState to WaitForResources, curState is %d\n", pComponentPrivate->curState);
2028 if (pComponentPrivate->curState == OMX_StateLoaded) {
2029
2030 #ifdef RESOURCE_MANAGER_ENABLED
2031 eError= RMProxy_NewSendCommand(pComponentPrivate->pHandle, RMProxy_StateSet, OMX_VPP_COMPONENT, OMX_StateWaitForResources, 3456, NULL);
2032 if (eError != OMX_ErrorNone) {
2033 VPP_DPRINT("RMProxy_NewSendCommand(OMX_StateWaitForResources) failed\n");
2034 pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle,
2035 pComponentPrivate->pHandle->pApplicationPrivate,
2036 OMX_EventError,
2037 OMX_ErrorUndefined,
2038 OMX_TI_ErrorSevere,
2039 NULL);
2040 break;
2041 }
2042 #endif
2043
2044 pComponentPrivate->curState = OMX_StateWaitForResources;
2045 VPP_DPRINT("VPP: my state is %d, from OMX_StateLoaded, before call EventHandler\n", pComponentPrivate->curState);
2046 pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle,
2047 pComponentPrivate->pHandle->pApplicationPrivate,
2048 OMX_EventCmdComplete,
2049 OMX_CommandStateSet,
2050 pComponentPrivate->curState,
2051 NULL);
2052 VPP_DPRINT("VPP: after call EventHandler\n");
2053 }
2054 else {
2055 pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle,
2056 pComponentPrivate->pHandle->pApplicationPrivate,
2057 OMX_EventError,
2058 OMX_ErrorIncorrectStateTransition,
2059 OMX_TI_ErrorMinor,
2060 NULL);
2061 }
2062 break;
2063 case OMX_StateMax:
2064 VPP_DPRINT("VPP::%d: HandleCommand: Cmd OMX_StateMax::\n",__LINE__);
2065 break;
2066 default:
2067 break;
2068 }
2069 EXIT:
2070 VPP_DPRINT ("VPP::%d :: Exiting HandleCommand Function, eError=0x%X,\n",__LINE__,eError);
2071 return eError;
2072 }
2073
2074
2075
2076 /**
2077 * @VPP_ProcessFilledInBuf() This function is called by the component Thread whenever it
2078 * receives the an input buffer from the application
2079 *
2080 * @param pComponentPrivate Component private data
2081 * @param pBufHeader Buffer from the application
2082 *
2083 * @pre
2084 *
2085 * @post
2086 *
2087 * @return none
2088 */
VPP_Process_FilledInBuf(VPP_COMPONENT_PRIVATE * pComponentPrivate)2089 OMX_ERRORTYPE VPP_Process_FilledInBuf(VPP_COMPONENT_PRIVATE* pComponentPrivate)
2090 {
2091 OMX_ERRORTYPE eError = OMX_ErrorNone;
2092 OMX_DIRTYPE eDir = OMX_DirMax;
2093 OMX_PARAM_PORTDEFINITIONTYPE *portDef = NULL;
2094 OMX_U32 nIndex;
2095 OMX_VPP_COMPONENT_BUFFER *pComponentBuf = NULL;
2096 LCML_DSP_INTERFACE *pLcmlHandle = NULL;
2097 OMX_BUFFERHEADERTYPE* pBufHeader = NULL;
2098 OMX_COMPONENTTYPE *pHandle = NULL;
2099 OMX_U8 *pTemp = NULL;
2100 int nRet=0;
2101
2102 pHandle = pComponentPrivate->pHandle;
2103
2104 VPP_DPRINT("In VPP_Process_FilledInBuf\n");
2105
2106 nRet = read(pComponentPrivate->nFilled_iPipe[0], &(pBufHeader),sizeof(pBufHeader));
2107 if (-1 == nRet) {
2108 VPP_DPRINT ("%d :: Error while reading from the pipe\n",__LINE__);
2109 }
2110 VPP_DPRINT("%d :: Entering VPP_Process_FilledInBuf with pBufHeader=%p\n",__LINE__, pBufHeader);
2111
2112 if (pBufHeader->nFlags & OMX_BUFFERFLAG_EOS) {
2113 VPP_DPRINT("EOS flag is in input buffer (len %d)\n", pBufHeader->nFilledLen);
2114 }
2115
2116 eError = VPP_GetPortDefFromBufHeader(pBufHeader, &portDef);
2117
2118 if (eError != OMX_ErrorNone) {
2119 VPP_DPRINT("VPP:: Got error in _GetPortDefFromBufHeader. Code %x\n", eError);
2120 goto EXIT;
2121 }
2122 VPP_DPRINT("THE PORT INDEX BEFORE VPP_ISVALIDBUFFER IS %d\n", portDef->nPortIndex);
2123
2124 eError = VPP_IsValidBuffer(pBufHeader, pComponentPrivate, portDef->nPortIndex, &nIndex);
2125 if (eError != OMX_ErrorNone) {
2126 OMX_SET_ERROR_BAIL(eError, OMX_ErrorBadParameter);
2127 }
2128 pComponentPrivate->sCompPorts[portDef->nPortIndex].pVPPBufHeader[nIndex].bHolding = OMX_TRUE;
2129
2130 if (!pComponentPrivate->sCompPorts[portDef->nPortIndex].pPortDef.bEnabled) {
2131 VPP_DPRINT("cur port %p is disabled\n", portDef);
2132 pComponentPrivate->sCompPorts[portDef->nPortIndex].pVPPBufHeader[nIndex].eBufferOwner = VPP_BUFFER_CLIENT;
2133 pComponentPrivate->cbInfo.EmptyBufferDone (
2134 pHandle,
2135 pHandle->pApplicationPrivate,
2136 pBufHeader
2137 );
2138 goto EXIT;
2139 }
2140
2141 if (pComponentPrivate->bIsStopping == OMX_TRUE) {
2142 VPP_DPRINT("VPP: stop! return buffer to %p\n", pComponentPrivate->sCompPorts[portDef->nPortIndex].hTunnelComponent);
2143 if (pComponentPrivate->sCompPorts[portDef->nPortIndex].hTunnelComponent == NULL) {
2144 pComponentPrivate->sCompPorts[portDef->nPortIndex].pVPPBufHeader[nIndex].eBufferOwner = VPP_BUFFER_CLIENT;
2145 pComponentPrivate->cbInfo.EmptyBufferDone (pHandle,
2146 pHandle->pApplicationPrivate,
2147 pBufHeader
2148 );
2149 } else {
2150 if(pComponentPrivate->sCompPorts[portDef->nPortIndex].eSupplierSetting == OMX_BufferSupplyOutput){
2151 pComponentPrivate->sCompPorts[portDef->nPortIndex].pVPPBufHeader[nIndex].eBufferOwner = VPP_BUFFER_TUNNEL_COMPONENT;
2152 VPP_DPRINT("VPP_UTILS: call to OMX_FillThisBuffer():: %d\n", __LINE__);
2153 eError = OMX_FillThisBuffer(
2154 pComponentPrivate->sCompPorts[portDef->nPortIndex].hTunnelComponent,
2155 pComponentPrivate->sCompPorts[portDef->nPortIndex].pVPPBufHeader[nIndex].pBufHeader);
2156 }
2157 else{
2158 pComponentPrivate->sCompPorts[portDef->nPortIndex].pVPPBufHeader[nIndex].eBufferOwner = VPP_BUFFER_COMPONENT_IN;
2159 }
2160 }
2161 goto EXIT;
2162 }
2163 if (portDef->nPortIndex == OMX_VPP_INPUT_PORT || portDef->nPortIndex == OMX_VPP_INPUT_OVERLAY_PORT) {
2164 VPP_DPRINT("VPP:: INPUT Buffer Came %ld ...\n",portDef->nPortIndex);
2165 eDir = OMX_DirInput;
2166 }
2167 else {
2168 VPP_DPRINT ("VPP::%d :: The PBufHeader is not found in the list\n", __LINE__);
2169 goto EXIT;
2170 }
2171
2172 if (pBufHeader->nFilledLen >= 0) {
2173 pLcmlHandle = (LCML_DSP_INTERFACE *) pComponentPrivate->pLcmlHandle;
2174 eError = VPP_GetCorresponding_LCMLHeader(pComponentPrivate, pBufHeader->pBuffer, OMX_DirInput, &pComponentBuf, portDef->nPortIndex );
2175 if (eError != OMX_ErrorNone) {
2176 VPP_DPRINT("%d :: Error: Invalid Buffer Came ...\n",__LINE__);
2177 goto EXIT;
2178 }
2179
2180 if (pComponentPrivate->bIsStopping == 1) {
2181 pComponentBuf->eBufferOwner = VPP_BUFFER_CLIENT;
2182 pComponentPrivate->cbInfo.EmptyBufferDone (pHandle,
2183 pHandle->pApplicationPrivate,
2184 pComponentBuf->pBufHeader
2185 );
2186 goto EXIT;
2187 }
2188
2189 /*check for overlay data if yes then go for no parameter BUFER */
2190 if (portDef->nPortIndex == OMX_VPP_INPUT_PORT) {
2191
2192 #ifdef __PERF_INSTRUMENTATION__
2193 PERF_SendingFrame(pComponentPrivate->pPERFcomp,
2194 pBufHeader->pBuffer,
2195 pBufHeader->nFilledLen,
2196 PERF_ModuleCommonLayer);
2197 #endif
2198
2199 pComponentPrivate->sCompPorts[portDef->nPortIndex].pVPPBufHeader[nIndex].eBufferOwner = VPP_BUFFER_DSP;
2200
2201 VPP_DPRINT("VPP: queue input buffer nFilledLen = (%d), BufHdr = %p\n", pBufHeader->nFilledLen, pBufHeader);
2202 VPP_DPRINT("Queued Input Buffer: Input Width= %lu, Input Height=%lu, Inp. Offset: %lu \
2203 RGBRotation = %lu, ulYUVRotation = %lu, ulMirror = %lu\n",
2204 pComponentPrivate->pIpFrameStatus->ulInWidth,
2205 pComponentPrivate->pIpFrameStatus->ulInHeight,
2206 pComponentPrivate->pIpFrameStatus->ulCInOffset,
2207 pComponentPrivate->pIpFrameStatus->ulRGBRotation,
2208 pComponentPrivate->pIpFrameStatus->ulYUVRotation,
2209 pComponentPrivate->pIpFrameStatus->ulMirror);
2210
2211 eError = LCML_QueueBuffer(pLcmlHandle->pCodecinterfacehandle,
2212 EMMCodecInputBuffer,
2213 pBufHeader->pBuffer,
2214 pBufHeader->nAllocLen,
2215 pBufHeader->nFilledLen,
2216 (OMX_U8 *) pComponentPrivate->pIpFrameStatus,
2217 sizeof(GPPToVPPInputFrameStatus),
2218 (void *) pBufHeader);
2219
2220
2221
2222 }
2223 else if (portDef->nPortIndex == OMX_VPP_INPUT_OVERLAY_PORT) {
2224 pTemp = memcpy(pComponentPrivate->RGBbuffer,pBufHeader->pBuffer,pBufHeader->nFilledLen);
2225 if(pTemp == NULL){
2226 eError = OMX_ErrorUndefined;
2227 goto EXIT;
2228 }
2229 VPP_DPRINT("VPP::%d: before calling ComputeTiOverlayImgFormat \n",__LINE__);
2230 eError = ComputeTiOverlayImgFormat(pComponentPrivate,
2231 pComponentPrivate->RGBbuffer,
2232 pBufHeader->pBuffer,
2233 pComponentPrivate->colorKey);
2234 if (eError != OMX_ErrorNone) {
2235 VPP_DPRINT ("VPP::%d ::ComputeTiOverlayImgFormat, Error Occurred: %x\n",__LINE__, eError);
2236 goto EXIT;
2237 }
2238 VPP_DPRINT("VPP::%d: after calling ComputeTiOverlayImgFormat \n",__LINE__);
2239 pBufHeader->nFilledLen= (pBufHeader->nFilledLen*2)/3;
2240 #if 0
2241
2242 FILE *fp;
2243
2244 fp = fopen("mytestcvnew.raw", "w");
2245 fwrite(pBufHeader->pBuffer, 1, pBufHeader->nFilledLen, fp);
2246 fclose(fp);
2247 VPP_DPRINT("write %d bytes to mytestcvnew.raw\n", pBufHeader->nFilledLen);
2248 exit(0);
2249 #endif
2250
2251 #ifdef __PERF_INSTRUMENTATION__
2252 PERF_SendingFrame(pComponentPrivate->pPERFcomp,
2253 pBufHeader->pBuffer,
2254 pBufHeader->nFilledLen,
2255 PERF_ModuleCommonLayer);
2256 #endif
2257 pComponentPrivate->sCompPorts[portDef->nPortIndex].pVPPBufHeader[nIndex].eBufferOwner = VPP_BUFFER_DSP;
2258 eError = LCML_QueueBuffer(
2259 pLcmlHandle->pCodecinterfacehandle,
2260 EMMCodecStream1,
2261 pBufHeader->pBuffer,
2262 pBufHeader->nAllocLen,
2263 pBufHeader->nFilledLen,
2264 NULL,
2265 0,
2266 (void *) pBufHeader);
2267
2268 VPP_DPRINT("LCML_QueueBuffer from OMX_VPP_INPUT_OVERLAY_PORT, pBufHeader %p, ->pBuffer %p\n",
2269 pBufHeader, pBufHeader->pBuffer);
2270 }
2271 if (eError != OMX_ErrorNone) {
2272 VPP_DPRINT ("VPP::%d ::Comp: SetBuff: IP: Error Occurred\n",__LINE__);
2273 eError = OMX_ErrorHardware;
2274 goto EXIT;
2275 }
2276 }
2277 VPP_DPRINT ("VPP::Sending Input buffer to Codec\n");
2278 EXIT:
2279 return eError;
2280 }
2281
2282
2283
2284 /**
2285 * VPP_Process_FreeOutBuf()
2286 *
2287 * Called by component thread, handles free output buffers from app.
2288 *
2289 * @param pComponentPrivate private component structure for this instance of the component
2290 *
2291 * @param phandle LCML_DSP_INTERFACE handle for this instance of the component
2292 *
2293 * @retval OMX_ErrorNone success, ready to roll
2294 * OMX_ErrorInsufficientResources if the malloc fails
2295 **/
VPP_Process_FreeOutBuf(VPP_COMPONENT_PRIVATE * pComponentPrivate)2296 OMX_ERRORTYPE VPP_Process_FreeOutBuf(VPP_COMPONENT_PRIVATE* pComponentPrivate)
2297 {
2298 OMX_ERRORTYPE eError = OMX_ErrorNone;
2299 OMX_PARAM_PORTDEFINITIONTYPE *portDef = NULL;
2300 OMX_U32 nIndex;
2301 OMX_VPP_COMPONENT_BUFFER *pComponentBuf = NULL;
2302 LCML_DSP_INTERFACE *pLcmlHandle = NULL;
2303 OMX_BUFFERHEADERTYPE* pBufHeader = NULL;
2304 OMX_COMPONENTTYPE *pHandle = NULL;
2305 int nRet = 0;
2306
2307 VPP_DPRINT("In VPP_Process_FreeOutBuf\n");
2308
2309 pHandle = pComponentPrivate->pHandle;
2310
2311 nRet = read(pComponentPrivate->nFree_oPipe[0], &pBufHeader,sizeof(pBufHeader));
2312 if (-1 == nRet) {
2313 VPP_DPRINT ("%d :: Error while reading from the pipe\n",__LINE__);
2314 }
2315 VPP_DPRINT("In VPP_Process_FreeOutBuf\n");
2316
2317
2318
2319 pLcmlHandle = (LCML_DSP_INTERFACE *) pComponentPrivate->pLcmlHandle;
2320 eError = VPP_GetPortDefFromBufHeader(pBufHeader, &portDef);
2321 if (eError != OMX_ErrorNone) {
2322 VPP_DPRINT("VPP: Error in _GetPortDefFromBufHeader. Code %d\n", eError);
2323 goto EXIT;
2324 }
2325
2326
2327
2328 eError = VPP_IsValidBuffer(pBufHeader, pComponentPrivate, portDef->nPortIndex, &nIndex);
2329
2330 if ( eError != OMX_ErrorNone) {
2331 goto EXIT;
2332 }
2333
2334 if ((pComponentPrivate->bIsStopping != OMX_FALSE ) || (pComponentPrivate->curState == OMX_StateIdle)) {
2335 VPP_DPRINT("VPP is not in executing state (in FreeOutBuf %d %d %p)\n", portDef->nPortIndex, nIndex, pBufHeader);
2336 VPP_DPRINT("cur state %d to state %d\n", pComponentPrivate->curState, pComponentPrivate->toState);
2337 pthread_mutex_lock(&pComponentPrivate->buf_mutex);
2338 VPP_DPRINT("VPP: return buffer to (%d) %p\n", portDef->nPortIndex, pComponentPrivate->sCompPorts[portDef->nPortIndex].hTunnelComponent);
2339 if (pComponentPrivate->sCompPorts[portDef->nPortIndex].hTunnelComponent == NULL) {
2340 pComponentPrivate->sCompPorts[portDef->nPortIndex].pVPPBufHeader[nIndex].eBufferOwner = VPP_BUFFER_CLIENT;
2341 pComponentPrivate->cbInfo.FillBufferDone (
2342 pHandle,
2343 pHandle->pApplicationPrivate,
2344 pBufHeader
2345 );
2346 } else {
2347 if(pComponentPrivate->sCompPorts[portDef->nPortIndex].eSupplierSetting == OMX_BufferSupplyInput){
2348 pComponentPrivate->sCompPorts[portDef->nPortIndex].pVPPBufHeader[nIndex].eBufferOwner = VPP_BUFFER_TUNNEL_COMPONENT;
2349 eError = OMX_EmptyThisBuffer(
2350 pComponentPrivate->sCompPorts[portDef->nPortIndex].hTunnelComponent,
2351 pComponentPrivate->sCompPorts[portDef->nPortIndex].pVPPBufHeader[nIndex].pBufHeader);
2352 }
2353 else{
2354 pComponentPrivate->sCompPorts[portDef->nPortIndex].pVPPBufHeader[nIndex].eBufferOwner = VPP_BUFFER_COMPONENT_IN;
2355 }
2356 }
2357 pthread_mutex_unlock(&pComponentPrivate->buf_mutex);
2358
2359 goto EXIT;
2360 }
2361
2362 if (!pComponentPrivate->sCompPorts[portDef->nPortIndex].pPortDef.bEnabled) {
2363 VPP_DPRINT("In VPP_Process_FreeOutBuf port %p is disabled %p\n", portDef, pBufHeader);
2364 pComponentPrivate->sCompPorts[portDef->nPortIndex].pVPPBufHeader[nIndex].eBufferOwner = VPP_BUFFER_CLIENT;
2365 pComponentPrivate->cbInfo.FillBufferDone (
2366 pHandle,
2367 pHandle->pApplicationPrivate,
2368 pBufHeader
2369 );
2370 goto EXIT;
2371 }
2372
2373 pComponentPrivate->sCompPorts[portDef->nPortIndex].pVPPBufHeader[nIndex].bHolding = OMX_TRUE;
2374 eError = VPP_GetCorresponding_LCMLHeader(pComponentPrivate, pBufHeader->pBuffer, OMX_DirOutput, &pComponentBuf, portDef->nPortIndex);
2375 if (eError != OMX_ErrorNone) {
2376 VPP_DPRINT("VPP::%d :: Error: Invalid Buffer Came ...\n",__LINE__);
2377 goto EXIT;
2378 }
2379
2380
2381
2382 if (pComponentPrivate->bIsStopping == OMX_FALSE) {
2383 #ifdef __PERF_INSTRUMENTATION__
2384 PERF_SendingFrame(pComponentPrivate->pPERFcomp,
2385 pBufHeader->pBuffer,
2386 0,
2387 PERF_ModuleCommonLayer);
2388 #endif
2389
2390 pComponentPrivate->sCompPorts[portDef->nPortIndex].pVPPBufHeader[nIndex].eBufferOwner = VPP_BUFFER_DSP;
2391 if (portDef->nPortIndex == OMX_VPP_RGB_OUTPUT_PORT) {
2392 eError = LCML_QueueBuffer(
2393 pLcmlHandle->pCodecinterfacehandle,
2394 EMMCodecStream2,
2395 pBufHeader->pBuffer,
2396 pBufHeader->nAllocLen,0,
2397 (OMX_U8 *) pComponentPrivate->pOpRGBFrameStatus,
2398 sizeof(GPPToVPPOutputFrameStatus),
2399 (void *) pBufHeader);
2400 VPP_DPRINT("VPP queue OMX_VPP_RGB_OUTPUT_PORT %p\n", pBufHeader);
2401 } else { /* portDef->nPortIndex == OMX_VPP_YUV_OUTPUT_PORT) */
2402 eError = LCML_QueueBuffer(
2403 pLcmlHandle->pCodecinterfacehandle,
2404 EMMCodecStream3,
2405 pBufHeader->pBuffer,
2406 pBufHeader->nAllocLen,0,
2407 (OMX_U8 *) pComponentPrivate->pOpYUVFrameStatus,
2408 sizeof(GPPToVPPOutputFrameStatus),
2409 (void *) pBufHeader);
2410 VPP_DPRINT("VPP queue OMX_VPP_YUV_OUTPUT_PORT %p\n", pBufHeader);
2411 }
2412
2413 VPP_DPRINT("Queued Output Buffer: Out Width= %lu, Out Height=%lu, Out. Offset: %lu, befferlen: %lu\n",
2414 pComponentPrivate->pOpYUVFrameStatus->ulOutWidth,
2415 pComponentPrivate->pOpYUVFrameStatus->ulOutHeight,
2416 pComponentPrivate->pOpYUVFrameStatus->ulCOutOffset,
2417 pBufHeader->nAllocLen);
2418
2419 if (eError != OMX_ErrorNone ) {
2420 VPP_DPRINT ("VPP::%d :: Comp:: SetBuff OP: Error Occurred\n", __LINE__);
2421 VPP_DPRINT("%s::%d::Error 0x%X from LCML_QueueBuffer\n",__FILE__,__LINE__,eError);
2422 eError = OMX_ErrorHardware;
2423 goto EXIT;
2424 }
2425 }
2426 EXIT:
2427 return eError;
2428 }
2429
2430
2431
2432 /**
2433 * @VPP_Process_FreeInBuf() This function is called by the component Thread whenever it
2434 * receives the a Freed Input buffer from the DSP
2435 *
2436 * @param pComponentPrivate Component private data
2437
2438 * @pre
2439 *
2440 * @post
2441 *
2442 * @return none
2443 */
VPP_Process_FreeInBuf(VPP_COMPONENT_PRIVATE * pComponentPrivate,OMX_VPP_COMPONENT_BUFFER * pComponentBuf)2444 OMX_ERRORTYPE VPP_Process_FreeInBuf(VPP_COMPONENT_PRIVATE* pComponentPrivate,
2445 OMX_VPP_COMPONENT_BUFFER *pComponentBuf)
2446 {
2447 OMX_ERRORTYPE eError = OMX_ErrorNone;
2448 OMX_COMPONENTTYPE* pHandle = (OMX_COMPONENTTYPE*)pComponentPrivate->pHandle;
2449 OMX_U32 nIndex;
2450 OMX_PARAM_PORTDEFINITIONTYPE *portDef = NULL;
2451
2452
2453 if (pComponentPrivate->toState == OMX_StateIdle) {
2454 VPP_DPRINT ("%d :: Entering HandleDataBuf_FromLCML Function\n",__LINE__);
2455 }
2456
2457 VPP_DPRINT("VPP::%d: Component Sending Empty Input buffer%p to App\n",__LINE__,pComponentBuf->pBufHeader->pBuffer);
2458 portDef = pComponentBuf->pBufHeader->pInputPortPrivate;
2459
2460 eError = VPP_IsValidBuffer(pComponentBuf->pBufHeader, pComponentPrivate, portDef->nPortIndex, &nIndex);
2461 if (pComponentPrivate->toState == OMX_StateIdle) {
2462 VPP_DPRINT("VPP_Process_FreeInBuf: VPP_IsValidBuffer %d\n", eError);
2463 }
2464 if ( eError !=OMX_ErrorNone) {
2465 OMX_SET_ERROR_BAIL(eError, OMX_ErrorBadParameter);
2466 }
2467 /*If Tunneling*/
2468 if (pComponentPrivate->toState == OMX_StateIdle) {
2469 VPP_DPRINT("tunneling %p\n", pComponentPrivate->sCompPorts[pComponentBuf->pBufHeader->nInputPortIndex].hTunnelComponent);
2470 }
2471 if (pComponentPrivate->sCompPorts[pComponentBuf->pBufHeader->nInputPortIndex].hTunnelComponent != NULL) {
2472 if (OMX_StateExecuting == pComponentPrivate->curState) {
2473 if ((!pComponentPrivate->bIsStopping) ||
2474 (OMX_TRUE != pComponentPrivate->sCompPorts[portDef->nPortIndex].pVPPBufHeader[nIndex].bSelfAllocated)) {
2475 pComponentPrivate->sCompPorts[portDef->nPortIndex].pVPPBufHeader[nIndex].bHolding = OMX_FALSE;
2476 VPP_DPRINT ("VPP::Sending INput buffer to TUNNEL component (%d)\n", pComponentPrivate->bIsStopping);
2477
2478 #ifdef __PERF_INSTRUMENTATION__
2479 PERF_SendingFrame(pComponentPrivate->pPERFcomp,
2480 pComponentBuf->pBufHeader->pBuffer,
2481 0,
2482 PERF_ModuleLLMM);
2483 #endif
2484 if(pComponentBuf->eBufferOwner != VPP_BUFFER_CLIENT ){
2485 pComponentBuf->eBufferOwner = VPP_BUFFER_CLIENT;
2486 VPP_DPRINT("$$$VPP_UTILS: call to OMX_FillThisBuffer():: %d\n", __LINE__);
2487 eError = OMX_FillThisBuffer(pComponentPrivate->sCompPorts[pComponentBuf->pBufHeader->nInputPortIndex].hTunnelComponent, pComponentBuf->pBufHeader);
2488 VPP_DPRINT ("VPP:: buffer is sent to tunnel component\n");
2489 }
2490 else{
2491 VPP_DPRINT("VPP:: buffer is already in tunnel component\n");
2492 }
2493 }
2494 }
2495 }
2496 else {
2497 VPP_DPRINT("pComponentPrivate->bIsEOFSent %d\n", pComponentPrivate->bIsEOFSent);
2498 if (1) { /* if (pComponentPrivate->bIsEOFSent != 1) { */
2499 pComponentPrivate->sCompPorts[portDef->nPortIndex].pVPPBufHeader[nIndex].bHolding = OMX_FALSE;
2500
2501 #ifdef __PERF_INSTRUMENTATION__
2502 PERF_SendingFrame(pComponentPrivate->pPERFcomp,
2503 PREF(pComponentBuf->pBufHeader,pBuffer),
2504 0,
2505 PERF_ModuleHLMM);
2506 #endif
2507
2508 if (pComponentPrivate->toState == OMX_StateIdle) {
2509 VPP_DPRINT("pComponentBuf->eBufferOwner %d (%p)\n", pComponentBuf->eBufferOwner, pComponentBuf->pBufHeader);
2510 }
2511 if(pComponentBuf->eBufferOwner != VPP_BUFFER_CLIENT){
2512 pComponentBuf->eBufferOwner = VPP_BUFFER_CLIENT;
2513 if (pComponentBuf->pBufHeader->pMarkData) {
2514 VPP_DPRINT("return marked buffer %x %d\n", pComponentBuf->pBufHeader->pMarkData, pComponentBuf->pBufHeader->nInputPortIndex);
2515 }
2516 VPP_DPRINT("VPP:: Sent buffer to the client\n");
2517 pComponentPrivate->cbInfo.EmptyBufferDone (pHandle,
2518 pHandle->pApplicationPrivate,
2519 pComponentBuf->pBufHeader
2520 );
2521 if (pComponentPrivate->toState == OMX_StateIdle) {
2522 VPP_DPRINT("VPP:: Sent buffer to the client\n");
2523 }
2524 }
2525 else{
2526 VPP_DPRINT("VPP:: Buffer already with the client\n");
2527 }
2528 }
2529 else {
2530 VPP_DPRINT(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
2531 VPP_DPRINT("%d :: Comp: Last IP Buffer: So will not be sent to app\n", __LINE__);
2532 VPP_DPRINT(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
2533 }
2534 }
2535 EXIT:
2536 return eError;
2537 }
2538
2539
2540
2541 /**
2542 * @VPP_ProcessFilledOutBuf() This function is called by the component Thread whenever it
2543 * receives the an Filled output buffer from the DSP
2544 *
2545 * @param pComponentPrivate Component private data
2546
2547 * @pre
2548 *
2549 * @post
2550 *
2551 * @return none
2552 */
VPP_Process_FilledOutBuf(VPP_COMPONENT_PRIVATE * pComponentPrivate,OMX_VPP_COMPONENT_BUFFER * pComponentBuf)2553 OMX_ERRORTYPE VPP_Process_FilledOutBuf(VPP_COMPONENT_PRIVATE* pComponentPrivate,
2554 OMX_VPP_COMPONENT_BUFFER *pComponentBuf)
2555 {
2556 OMX_ERRORTYPE eError = OMX_ErrorNone;
2557 OMX_COMPONENTTYPE* pHandle = (OMX_COMPONENTTYPE*)pComponentPrivate->pHandle;
2558 OMX_U32 nIndex;
2559 OMX_PARAM_PORTDEFINITIONTYPE *portDef = NULL;
2560
2561 VPP_DPRINT ("VPP %d :: Entering HandleDataBuf_FromLCML Function\n",__LINE__);
2562
2563 portDef = pComponentBuf->pBufHeader->pOutputPortPrivate;
2564 VPP_DPRINT("VPP::%d: Component Sending Filled Output buffer of index %lu to App\n",__LINE__,portDef->nPortIndex);
2565 eError = VPP_IsValidBuffer(pComponentBuf->pBufHeader, pComponentPrivate, portDef->nPortIndex, &nIndex);
2566 if ( eError !=OMX_ErrorNone){
2567 OMX_SET_ERROR_BAIL(eError, OMX_ErrorBadParameter);
2568 }
2569
2570 if (pComponentBuf->pBufHeader->pMarkData && pComponentBuf->pBufHeader->hMarkTargetComponent == pComponentPrivate->pHandle) {
2571 VPP_DPRINT("Send OMX_MarkEvent\n");
2572 if (pComponentBuf->pBufHeader->nOutputPortIndex == OMX_VPP_YUV_OUTPUT_PORT) {
2573 pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle,
2574 pComponentPrivate->pHandle->pApplicationPrivate,
2575 OMX_EventMark,
2576 OMX_VPP_YUV_OUTPUT_PORT,
2577 0,
2578 pComponentBuf->pBufHeader->pMarkData);
2579 }
2580 else { /*OMX_VPP_RGB_OUTPUT_PORT*/
2581 pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle,
2582 pComponentPrivate->pHandle->pApplicationPrivate,
2583 OMX_EventMark,
2584 OMX_VPP_RGB_OUTPUT_PORT,
2585 0,
2586 pComponentBuf->pBufHeader->pMarkData);
2587 }
2588 }
2589
2590 if(pComponentBuf->pBufHeader->nFlags & OMX_BUFFERFLAG_EOS){
2591 VPP_DPRINT("set EOS flag at YUV output buffer\n");
2592 pComponentPrivate->cbInfo.EventHandler (pComponentPrivate->pHandle,
2593 pComponentPrivate->pHandle->pApplicationPrivate,
2594 OMX_EventBufferFlag,
2595 pComponentBuf->pBufHeader->nOutputPortIndex,
2596 OMX_BUFFERFLAG_EOS,
2597 NULL);
2598 }
2599
2600 VPP_DPRINT("VPP: VPP_Process_FilledOutBuf: nPortIndex=%d, nIndex= %d, bHolding= %d\n", portDef->nPortIndex, nIndex, pComponentPrivate->sCompPorts[portDef->nPortIndex].pVPPBufHeader[nIndex].bHolding);
2601
2602 /*TUNNEL HERE*/
2603 if (pComponentPrivate->sCompPorts[portDef->nPortIndex].hTunnelComponent != NULL) {
2604 pComponentPrivate->sCompPorts[portDef->nPortIndex].pVPPBufHeader[nIndex].bHolding = OMX_FALSE;
2605
2606
2607 #ifdef __PERF_INSTRUMENTATION__
2608 PERF_SendingFrame(pComponentPrivate->pPERFcomp,
2609 pComponentBuf->pBufHeader->pBuffer,
2610 pComponentBuf->pBufHeader->nFilledLen,
2611 PERF_ModuleLLMM);
2612 #endif
2613
2614 if((pComponentBuf->eBufferOwner != VPP_BUFFER_CLIENT) && (pComponentPrivate->toState != OMX_StateIdle)){
2615 VPP_DPRINT("VPP::Sending Output buffer to TUNNEL component\n");
2616 pComponentBuf->eBufferOwner = VPP_BUFFER_CLIENT;
2617 eError = OMX_EmptyThisBuffer(pComponentPrivate->sCompPorts[pComponentBuf->pBufHeader->nOutputPortIndex].hTunnelComponent, pComponentBuf->pBufHeader);
2618 }
2619 else{
2620 VPP_DPRINT("VPP:: Output buffer already with the TUNNEL component\n");
2621 }
2622 #if 0
2623 FILE *fp;
2624
2625 fp = fopen("mytestcv.yuv", "w");
2626 fwrite(pComponentBuf->pBufHeader->pBuffer, 1, pComponentBuf->pBufHeader->nFilledLen, fp);
2627 fclose(fp);
2628 #endif
2629 }
2630 else {
2631
2632 pComponentPrivate->sCompPorts[portDef->nPortIndex].pVPPBufHeader[nIndex].bHolding = OMX_FALSE;
2633
2634 #ifdef __PERF_INSTRUMENTATION__
2635 PERF_SendingFrame(pComponentPrivate->pPERFcomp,
2636 PREF(pComponentBuf->pBufHeader,pBuffer),
2637 PREF(pComponentBuf->pBufHeader,nFilledLen),
2638 PERF_ModuleHLMM);
2639 #endif
2640
2641 if(pComponentBuf->eBufferOwner != VPP_BUFFER_CLIENT){
2642 VPP_DPRINT("VPP::Sending Output buffer to Applcation %p (%p %p)\n", pComponentBuf->pBufHeader, pComponentBuf->pBufHeader->hMarkTargetComponent, pComponentBuf->pBufHeader->pMarkData);
2643 pComponentBuf->eBufferOwner = VPP_BUFFER_CLIENT;
2644 pComponentPrivate->cbInfo.FillBufferDone (
2645 pHandle,
2646 pHandle->pApplicationPrivate,
2647 pComponentBuf->pBufHeader
2648 );
2649 }
2650 else{
2651 VPP_DPRINT("VPP:: Buffer already with the client\n");
2652 }
2653
2654 }
2655
2656 EXIT:
2657 VPP_DPRINT ("VPP::%d :: VPP_Process_FilledOutBuf Function with eError %d\n",__LINE__, eError);
2658 return eError;
2659 }
2660
2661
2662
2663 /* -------------------------------------------------------------------*/
2664 /**
2665 * Callback() function will be called LCML component to write the msg
2666 *
2667 * @param msgBuffer This buffer will be returned by the LCML
2668 *
2669 * @retval OMX_NoError Success, ready to roll
2670 * OMX_Error_BadParameter The input parameter pointer is null
2671 **/
2672 /*-------------------------------------------------------------------*/
VPP_LCML_Callback(TUsnCodecEvent event,void * args[10])2673 OMX_ERRORTYPE VPP_LCML_Callback (TUsnCodecEvent event,void * args [10])
2674 {
2675 OMX_ERRORTYPE eError = OMX_ErrorNone;
2676 OMX_U8 *pBuffer = args[1];
2677 OMX_VPP_COMPONENT_BUFFER *pComponentBuf = NULL;
2678
2679 VPP_COMPONENT_PRIVATE* pComponentPrivate = NULL;
2680 OMX_COMPONENTTYPE* pHandle = NULL;
2681 LCML_DSP_INTERFACE* pLcmlDspInterface = NULL;
2682 VPP_BUFFERDATA_PROPAGATION *pDataProp = NULL;
2683 OMX_U8 i = 0;
2684
2685 if (args[6]) {
2686 pLcmlDspInterface = (LCML_DSP_INTERFACE*)args[6];
2687
2688 pComponentPrivate = (VPP_COMPONENT_PRIVATE*)pLcmlDspInterface->pComponentPrivate;
2689
2690 pHandle = (OMX_COMPONENTTYPE *)pComponentPrivate->pHandle;
2691
2692 }
2693 else {
2694 VPP_DPRINT("wrong in LCML callback, exit\n");
2695 goto EXIT;
2696 }
2697
2698 VPP_DPRINT ("VPP::%d :: Entering the LCML_Callback Function, event = %d\n",__LINE__, event);
2699
2700 switch (event)
2701 {
2702 case EMMCodecBufferProcessed:
2703 switch ((int)args[0])
2704 {
2705 case EMMCodecInputBuffer:
2706 VPP_DPRINT ("VPP :: Inside the LCML_Callback EMMCodecInputBuffer\n");
2707 VPP_DPRINT("VPP::%d :: Input: pBufferr = %p\n",__LINE__, pBuffer);
2708 eError = VPP_GetCorresponding_LCMLHeader(pComponentPrivate, pBuffer, OMX_DirInput, &pComponentBuf, 0);
2709 if (eError != OMX_ErrorNone) {
2710 VPP_DPRINT("VPP::%d :: Error: Invalid Buffer Came ...\n",__LINE__);
2711 goto EXIT;
2712 }
2713 VPP_DPRINT("VPP::%d :: Input: pLcmlHeader = %p.\n",__LINE__, pComponentBuf->pBufHeader);
2714
2715 if (pComponentPrivate->bFlushComplete == OMX_FALSE && pComponentPrivate->nFlushPort == 0) {
2716 pComponentBuf->eBufferOwner = VPP_BUFFER_CLIENT;
2717 pComponentPrivate->cbInfo.EmptyBufferDone (pComponentPrivate->pHandle,
2718 pComponentPrivate->pHandle->pApplicationPrivate,
2719 pComponentBuf->pBufHeader
2720 );
2721 break;
2722 }
2723 #ifdef __PERF_INSTRUMENTATION__
2724 PERF_ReceivedFrame(pComponentPrivate->pPERFcomp,
2725 PREF(pComponentBuf->pBufHeader,pBuffer),
2726 0,
2727 PERF_ModuleCommonLayer);
2728 #endif
2729
2730 pComponentBuf->eBufferOwner = VPP_BUFFER_COMPONENT_OUT;
2731
2732 /*Freed Input buffers from DSP to component*/
2733 eError = VPP_Process_FreeInBuf(pComponentPrivate, pComponentBuf);
2734 if (eError != OMX_ErrorNone) {
2735 pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle,
2736 pComponentPrivate->pHandle->pApplicationPrivate,
2737 OMX_EventError,
2738 OMX_ErrorUndefined,
2739 OMX_TI_ErrorSevere,
2740 NULL);
2741 goto EXIT;
2742 }
2743 break;
2744 case EMMCodecStream1:
2745 VPP_DPRINT ("VPP:: Inside the LCML_Callback EMMCodecInputBuffer Overlay\n");
2746 VPP_DPRINT("VPP::%d :: Overlay: pBuffer = %p\n",__LINE__, pBuffer);
2747 eError = VPP_GetCorresponding_LCMLHeader(pComponentPrivate, pBuffer, OMX_DirInput, &pComponentBuf,1);
2748 if (eError != OMX_ErrorNone) {
2749 VPP_DPRINT("VPP::%d :: Error: Invalid Buffer Came ...\n",__LINE__);
2750 goto EXIT;
2751 }
2752 VPP_DPRINT("VPP::%d :: Input: pLcmlHeader = %p\n",__LINE__, pComponentBuf);
2753 VPP_DPRINT("VPP::%d :: Overlay: pLcmlHeader = %p.\n",__LINE__, pComponentBuf->pBufHeader);
2754
2755 if (pComponentPrivate->bFlushComplete == OMX_FALSE && pComponentPrivate->nFlushPort == 1) {
2756 pComponentBuf->eBufferOwner = VPP_BUFFER_CLIENT;
2757 pComponentPrivate->cbInfo.EmptyBufferDone (pComponentPrivate->pHandle,
2758 pComponentPrivate->pHandle->pApplicationPrivate,
2759 pComponentBuf->pBufHeader
2760 );
2761 break;
2762 }
2763 #ifdef __PERF_INSTRUMENTATION__
2764 PERF_ReceivedFrame(pComponentPrivate->pPERFcomp,
2765 PREF(pComponentBuf->pBufHeader,pBuffer),
2766 0,
2767 PERF_ModuleCommonLayer);
2768 #endif
2769 pComponentBuf->eBufferOwner = VPP_BUFFER_COMPONENT_OUT;
2770
2771 /*Freed Input buffers from DSP to component*/
2772 eError = VPP_Process_FreeInBuf(pComponentPrivate, pComponentBuf);
2773 if (eError != OMX_ErrorNone) {
2774 pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle,
2775 pComponentPrivate->pHandle->pApplicationPrivate,
2776 OMX_EventError,
2777 OMX_ErrorUndefined,
2778 OMX_TI_ErrorSevere,
2779 NULL);
2780 goto EXIT;
2781 }
2782 break;
2783 case EMMCodecStream2:
2784 VPP_DPRINT("VPP :: Inside the LCML_Callback EMMCodecOuputBuffer stream2 \n");
2785 VPP_DPRINT("VPP::%d :: Output: pBufferr = %p\n",__LINE__, pBuffer);
2786 eError = VPP_GetCorresponding_LCMLHeader(pComponentPrivate, pBuffer, OMX_DirOutput, &pComponentBuf, 2);
2787 if (eError != OMX_ErrorNone) {
2788 VPP_DPRINT("VPP::%d :: Error: Invalid Buffer Came ...\n",__LINE__);
2789 goto EXIT;
2790 }
2791 pComponentBuf->pBufHeader->nFilledLen = (int)args[8];
2792 VPP_DPRINT("VPP::%d :: Output(2): pLcmlHeader = %p\n",__LINE__, pComponentBuf);
2793 VPP_DPRINT("VPP::%d :: Output: Filled Len = %ld\n",__LINE__, pComponentBuf->pBufHeader->nFilledLen);
2794
2795 if(pComponentBuf->eBufferOwner == VPP_BUFFER_DSP){
2796 pComponentPrivate->nOutRGBBufferCount ++;
2797 }
2798 VPP_DPRINT("RGB Filled Data from DSP \n");
2799 VPP_DPRINT("buffer summary (LCML for output buffer %p) %d %d %d %d\n", pComponentBuf->pBufHeader,
2800 pComponentPrivate->nInYUVBufferCount,
2801 pComponentPrivate->nInRGBBufferCount,
2802 pComponentPrivate->nOutYUVBufferCount,
2803 pComponentPrivate->nOutRGBBufferCount);
2804
2805
2806 for (i = 0; i < pComponentPrivate->sCompPorts[OMX_VPP_INPUT_PORT].pPortDef.nBufferCountActual; i ++) {
2807 pDataProp = &(pComponentPrivate->sCompPorts[OMX_VPP_INPUT_PORT].sBufferDataProp[i]);
2808 if (pDataProp->buffer_idRGB == pComponentPrivate->nOutRGBBufferCount) {
2809 VPP_DPRINT("Output RGB buffer %d has data from Input port. \nFlag=%x, nTickCount=%ld, nTimeStamp=%Ld\n",
2810 pDataProp->buffer_idRGB,
2811 pDataProp->flag,
2812 pDataProp->nTickCount,
2813 pDataProp->nTimeStamp);
2814 pComponentBuf->pBufHeader->nFlags = pDataProp->flag;
2815 pComponentBuf->pBufHeader->pMarkData = pDataProp->pMarkData;
2816 pComponentBuf->pBufHeader->hMarkTargetComponent = pDataProp->hMarkTargetComponent;
2817 pComponentBuf->pBufHeader->nTickCount = pDataProp->nTickCount;
2818 pComponentBuf->pBufHeader->nTimeStamp = pDataProp->nTimeStamp;
2819 pDataProp->buffer_idRGB = 0xFFFFFFFF;
2820 break;
2821 }
2822 }
2823
2824 for (i = 0; i < pComponentPrivate->sCompPorts[OMX_VPP_INPUT_OVERLAY_PORT].pPortDef.nBufferCountActual; i ++) {
2825 pDataProp = &(pComponentPrivate->sCompPorts[OMX_VPP_INPUT_OVERLAY_PORT].sBufferDataProp[i]);
2826 if (pDataProp->buffer_idRGB == pComponentPrivate->nOutRGBBufferCount) {
2827 VPP_DPRINT("Output RGB buffer %d has data from Overlay port. \nFlag=%x, nTickCount=%ld, nTimeStamp=%Ld\n",
2828 pDataProp->buffer_idRGB,
2829 pDataProp->flag,
2830 pDataProp->nTickCount,
2831 pDataProp->nTimeStamp);
2832 pComponentBuf->pBufHeader->nFlags |= pDataProp->flag;
2833 /*if both input ports are been mark RGB output port propagate Input overlay mark*/
2834 pComponentBuf->pBufHeader->pMarkData = pDataProp->pMarkData;
2835 pComponentBuf->pBufHeader->hMarkTargetComponent = pDataProp->hMarkTargetComponent;
2836 #if 0
2837 if(pComponentBuf->pBufHeader->hMarkTargetComponent == NULL){ /*OMX_VPP_INPUT_PORT has preference while marking data*/
2838 pComponentBuf->pBufHeader->pMarkData = pDataProp->pMarkData;
2839 pComponentBuf->pBufHeader->hMarkTargetComponent = pDataProp->hMarkTargetComponent;
2840 }
2841 #endif
2842 pComponentBuf->pBufHeader->nTickCount = pDataProp->nTickCount;
2843 pComponentBuf->pBufHeader->nTimeStamp = pDataProp->nTimeStamp;
2844 pDataProp->buffer_idRGB = 0xFFFFFFFF;
2845 break;
2846 }
2847 }
2848
2849 if (pComponentPrivate->bFlushComplete == OMX_FALSE && pComponentPrivate->nFlushPort == 2) {
2850 pComponentBuf->eBufferOwner = VPP_BUFFER_CLIENT;
2851 pComponentPrivate->cbInfo.FillBufferDone (pComponentPrivate->pHandle,
2852 pComponentPrivate->pHandle->pApplicationPrivate,
2853 pComponentBuf->pBufHeader
2854 );
2855 break;
2856 }
2857
2858 #ifdef __PERF_INSTRUMENTATION__
2859 PERF_ReceivedFrame(pComponentPrivate->pPERFcomp,
2860 pComponentBuf->pBufHeader->pBuffer,
2861 pComponentBuf->pBufHeader->nFilledLen,
2862 PERF_ModuleCommonLayer);
2863 pComponentPrivate->lcml_nCntOpReceived++; /*CRITICAL: increment Op counter!!! */
2864 if ((pComponentPrivate->lcml_nCntIp >= 1) &&
2865 (pComponentPrivate->lcml_nCntOpReceived == 1)) {
2866 PERF_Boundary(pComponentPrivate->pPERFcomp,
2867 PERF_BoundaryStart | PERF_BoundarySteadyState);
2868 }
2869 #endif
2870
2871 pComponentBuf->eBufferOwner = VPP_BUFFER_COMPONENT_OUT;
2872
2873 /* Filled Output buffer from DSP to Component */
2874 eError = VPP_Process_FilledOutBuf(pComponentPrivate, pComponentBuf);
2875 if (eError != OMX_ErrorNone) {
2876 pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle,
2877 pComponentPrivate->pHandle->pApplicationPrivate,
2878 OMX_EventError,
2879 OMX_ErrorUndefined,
2880 OMX_TI_ErrorSevere,
2881 NULL);
2882 goto EXIT;
2883 }
2884 break;
2885 case EMMCodecStream3:
2886 VPP_DPRINT ("VPP::Inside the LCML_Callback EMMCodecOuputBuffer stream3\n");
2887 VPP_DPRINT("VPP::%d :: Output: pBufferr = %p\n",__LINE__, pBuffer);
2888 eError = VPP_GetCorresponding_LCMLHeader(pComponentPrivate, pBuffer, OMX_DirOutput, &pComponentBuf,3);
2889 if (eError != OMX_ErrorNone) {
2890 VPP_DPRINT("VPP::%d :: Error: Invalid Buffer Came ...\n",__LINE__);
2891 goto EXIT;
2892 }
2893 pComponentBuf->pBufHeader->nFilledLen = (int)args[8];
2894 VPP_DPRINT("VPP::%d :: Output(3): pLcmlHeader = %p\n",__LINE__, pComponentBuf);
2895 VPP_DPRINT("VPP::%d :: Output: Filled Len = %ld\n",__LINE__, pComponentBuf->pBufHeader->nFilledLen);
2896
2897 if(pComponentBuf->eBufferOwner == VPP_BUFFER_DSP){
2898 pComponentPrivate->nOutYUVBufferCount ++;
2899 }
2900 VPP_DPRINT("YUV Filled Data from DSP \n");
2901 VPP_DPRINT("buffer summary (LCML for output buffer %p) %d %d %d %d\n", pComponentBuf->pBufHeader,
2902 pComponentPrivate->nInYUVBufferCount,
2903 pComponentPrivate->nInRGBBufferCount,
2904 pComponentPrivate->nOutYUVBufferCount,
2905 pComponentPrivate->nOutRGBBufferCount);
2906
2907 for (i = 0; i < pComponentPrivate->sCompPorts[OMX_VPP_INPUT_PORT].pPortDef.nBufferCountActual; i ++) {
2908 pDataProp = &(pComponentPrivate->sCompPorts[OMX_VPP_INPUT_PORT].sBufferDataProp[i]);
2909 if (pDataProp->buffer_idYUV == pComponentPrivate->nOutYUVBufferCount) {
2910 VPP_DPRINT("Output YUV buffer %d has data from Input port. \nFlag=%x, nTickCount=%ld, nTimeStamp=%Ld\n\n",
2911 pDataProp->buffer_idYUV,
2912 pDataProp->flag,
2913 pDataProp->nTickCount,
2914 pDataProp->nTimeStamp);
2915
2916 pComponentBuf->pBufHeader->nFlags = pDataProp->flag;
2917 pComponentBuf->pBufHeader->pMarkData = pDataProp->pMarkData;
2918 pComponentBuf->pBufHeader->hMarkTargetComponent = pDataProp->hMarkTargetComponent;
2919 pComponentBuf->pBufHeader->nTickCount = pDataProp->nTickCount;
2920 pComponentBuf->pBufHeader->nTimeStamp = pDataProp->nTimeStamp;
2921 pDataProp->buffer_idYUV = 0xFFFFFFFF;
2922 break;
2923 }
2924 }
2925
2926 for (i = 0; i < pComponentPrivate->sCompPorts[OMX_VPP_INPUT_OVERLAY_PORT].pPortDef.nBufferCountActual; i ++) {
2927 pDataProp = &(pComponentPrivate->sCompPorts[OMX_VPP_INPUT_OVERLAY_PORT].sBufferDataProp[i]);
2928 if (pDataProp->buffer_idYUV == pComponentPrivate->nOutYUVBufferCount) {
2929 VPP_DPRINT("Output YUV buffer %d has data from Overlay port. \nFlag=%x, nTickCount=%ld, nTimeStamp=%Ld\n\n",
2930 pDataProp->buffer_idYUV,
2931 pDataProp->flag,
2932 pDataProp->nTickCount,
2933 pDataProp->nTimeStamp);
2934 pComponentBuf->pBufHeader->nFlags |= pDataProp->flag;
2935 if(pComponentBuf->pBufHeader->hMarkTargetComponent == NULL){ /*OMX_VPP_INPUT_PORT has preference while marking data*/
2936 pComponentBuf->pBufHeader->pMarkData = pDataProp->pMarkData;
2937 pComponentBuf->pBufHeader->hMarkTargetComponent = pDataProp->hMarkTargetComponent;
2938 }
2939 pComponentBuf->pBufHeader->nTickCount = pDataProp->nTickCount;
2940 pComponentBuf->pBufHeader->nTimeStamp = pDataProp->nTimeStamp;
2941 pDataProp->buffer_idYUV = 0xFFFFFFFF;
2942 break;
2943 }
2944 }
2945
2946
2947 if (pComponentPrivate->bFlushComplete == OMX_FALSE && pComponentPrivate->nFlushPort == 3) {
2948 pComponentBuf->eBufferOwner = VPP_BUFFER_CLIENT;
2949 pComponentPrivate->cbInfo.FillBufferDone (pComponentPrivate->pHandle,
2950 pComponentPrivate->pHandle->pApplicationPrivate,
2951 pComponentBuf->pBufHeader
2952 );
2953 break;
2954 }
2955
2956 #ifdef __PERF_INSTRUMENTATION__
2957 PERF_ReceivedFrame(pComponentPrivate->pPERFcomp,
2958 pComponentBuf->pBufHeader->pBuffer,
2959 pComponentBuf->pBufHeader->nFilledLen,
2960 PERF_ModuleCommonLayer);
2961 pComponentPrivate->lcml_nCntOpReceived++; /*CRITICAL: increment Op counter!!! */
2962 if ((pComponentPrivate->lcml_nCntIp >= 1) &&
2963 (pComponentPrivate->lcml_nCntOpReceived == 1)) {
2964 PERF_Boundary(pComponentPrivate->pPERFcomp,
2965 PERF_BoundaryStart | PERF_BoundarySteadyState);
2966 }
2967 #endif
2968
2969 pComponentBuf->eBufferOwner = VPP_BUFFER_COMPONENT_OUT;
2970
2971 /* Filled Output buffer from DSP to Component */
2972 eError = VPP_Process_FilledOutBuf(pComponentPrivate, pComponentBuf);
2973 if (eError != OMX_ErrorNone) {
2974 pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle,
2975 pComponentPrivate->pHandle->pApplicationPrivate,
2976 OMX_EventError,
2977 OMX_ErrorUndefined,
2978 OMX_TI_ErrorSevere,
2979 NULL);
2980 goto EXIT;
2981 }
2982 break;
2983 }
2984 break;
2985 case EMMCodecProcessingStoped:
2986 VPP_DPRINT("VPP::%d :: Comp: Inside the LCML_Callback: EMMCodecProcessingStopped\n",__LINE__);
2987 VPP_DPRINT("VPP::%d :: VPP: State has been Set to Idle\n",__LINE__);
2988 if (pComponentPrivate->toState == OMX_StateIdle) {
2989 pComponentPrivate->ExeToIdleFlag |= VPP_DSPSTOP;
2990 VPP_DPRINT("LCML_Callback: pComponentPrivate->ExeToIdleFlag = %x\n", pComponentPrivate->ExeToIdleFlag);
2991
2992 pthread_mutex_lock(&pComponentPrivate->vpp_mutex);
2993 pthread_cond_signal(&pComponentPrivate->stop_cond);
2994 pthread_mutex_unlock(&pComponentPrivate->vpp_mutex);
2995
2996 } else {
2997 pComponentPrivate->bDisable = OMX_TRUE;
2998 }
2999 break;
3000 case EMMCodecDspError:
3001 VPP_DPRINT("VPP::LCML_Callback. Received EMMCodecDSPError\n");
3002 VPP_DPRINT("EMMCodec Args -> %x, %x, %x\n", (int)args[0], (int)args[4], (int)args[5]);
3003 if ((int)args[4] != 0x1 || (int)args[5] != 0x500) {
3004 pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle,
3005 pComponentPrivate->pHandle->pApplicationPrivate,
3006 OMX_EventError,
3007 OMX_ErrorHardware,
3008 OMX_TI_ErrorCritical,
3009 NULL);
3010
3011 pComponentPrivate->curState = OMX_StateInvalid;
3012 pComponentPrivate->cbInfo.EventHandler(pHandle,
3013 pHandle->pApplicationPrivate,
3014 OMX_EventError,
3015 OMX_ErrorInvalidState,
3016 OMX_TI_ErrorCritical,
3017 "DSP Hardware Error");
3018 goto EXIT;
3019 }
3020 #ifdef DSP_MMU_FAULT_HANDLING
3021 /* Cheking for MMU_fault */
3022 if((args[4] == (void *)NULL) && (args[5] == (void*)NULL)) {
3023 VPP_DPRINT("DSP MMU_Fault");
3024 pComponentPrivate->curState = OMX_StateInvalid;
3025 pComponentPrivate->cbInfo.EventHandler(pHandle,
3026 pHandle->pApplicationPrivate,
3027 OMX_EventError,
3028 OMX_ErrorInvalidState,
3029 OMX_TI_ErrorCritical,
3030 "DSP MMU FAULT");
3031 }
3032 #endif
3033 break;
3034 case EMMCodecInternalError:
3035 VPP_DPRINT("VPP::LCML_Callback. EMMCodecInternalError\n");
3036 eError = OMX_ErrorHardware;
3037 pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle,
3038 pComponentPrivate->pHandle->pApplicationPrivate,
3039 OMX_EventError,
3040 OMX_ErrorHardware,
3041 OMX_TI_ErrorCritical,
3042 NULL);
3043 goto EXIT;
3044 break;
3045 case EMMCodecInitError:
3046 VPP_DPRINT("VPP::LCML_Callback. EMMCodecInitError\n");
3047 eError = OMX_ErrorHardware;
3048 pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle,
3049 pComponentPrivate->pHandle->pApplicationPrivate,
3050 OMX_EventError,
3051 OMX_ErrorHardware,
3052 OMX_TI_ErrorCritical,
3053 NULL);
3054 goto EXIT;
3055 break;
3056 case EMMCodecDspMessageRecieved:
3057 VPP_DPRINT("VPP::LCML_Callback. EMMCodecDspMessageReceived\n");
3058 break;
3059 case EMMCodecProcessingStarted:
3060 VPP_DPRINT("VPP::LCML_Callback. EMMCodecProcessingStarted\n");
3061 break;
3062 case EMMCodecProcessingPaused:
3063 VPP_DPRINT("VPP::LCML_Callback. EMMCodecProcessingPaused\n");
3064 if (pComponentPrivate->toState == OMX_StatePause) {
3065 pComponentPrivate->curState = OMX_StatePause;
3066 VPP_DPRINT ("%d :: The component %p is paused after get stop from DSP\n",__LINE__, pHandle);
3067 VPP_DPRINT("LCML_Callback: pComponentPrivate->ExeToIdleFlag = %x\n", pComponentPrivate->ExeToIdleFlag);
3068
3069 pComponentPrivate->cbInfo.EventHandler (
3070 pHandle,
3071 pHandle->pApplicationPrivate,
3072 OMX_EventCmdComplete,
3073 OMX_ErrorNone,
3074 pComponentPrivate->curState,
3075 "NULL");
3076 }
3077 break;
3078 case EMMCodecProcessingEof:
3079 VPP_DPRINT("VPP::LCML_Callback. EMMCodecProcessingEof\n");
3080 break;
3081 case EMMCodecBufferNotProcessed:
3082 VPP_DPRINT("VPP::LCML_Callback. EMMCodecBufferNotProcessed\n");
3083 break;
3084 case EMMCodecAlgCtrlAck:
3085 VPP_DPRINT("VPP::LCML_Callback. EMMCodecAlgCtrlAck\n");
3086 pComponentPrivate->CodecAlgCtrlAck = 1;
3087 break;
3088 case EMMCodecStrmCtrlAck:
3089 VPP_DPRINT("VPP::LCML_Callback. EMMCodecStrmCtrlAck\n");
3090 #if 1
3091 if (1) { /* ((int)args[0] == USN_ERR_NONE) { */
3092 VPP_DPRINT("Callback: EMMCodecStrmCtrlAck\n");
3093 pComponentPrivate->bFlushComplete = OMX_TRUE;
3094 } else {
3095 VPP_DPRINT("callback error %x\n", args[0]);
3096 }
3097 #endif
3098 break;
3099 default:
3100 VPP_DPRINT ("VPP::Comp: Inside the LCML_Callback: EVENT UNKNOWN %d\n", event);
3101 break;
3102 }
3103
3104 EXIT:
3105 VPP_DPRINT ("VPP::%d :: Exiting the LCML_Callback Function\n",__LINE__);
3106 return eError;
3107 }
3108
3109
3110
3111 /* -------------------------------------------------------------------*/
3112 /**
3113 * VPP_GetCorresponding_LCMLHeader() function retrun correponding Parameter buffer stored
3114 *
3115 * @param pBuffer This buffer will be returned by the LCML
3116 eDir
3117 ppLcmlHdr pointer where LCML header is returned
3118 *
3119 * @retval OMX_NoError Success, ready to roll
3120 * OMX_Error_BadParameter The input parameter pointer is null
3121 **/
3122 /*-------------------------------------------------------------------*/
VPP_GetCorresponding_LCMLHeader(VPP_COMPONENT_PRIVATE * pComponentPrivate,OMX_U8 * pBuffer,OMX_DIRTYPE eDir,OMX_VPP_COMPONENT_BUFFER ** ppCmpBuf,OMX_U32 Index)3123 OMX_ERRORTYPE VPP_GetCorresponding_LCMLHeader(VPP_COMPONENT_PRIVATE* pComponentPrivate,
3124 OMX_U8 *pBuffer,
3125 OMX_DIRTYPE eDir,
3126 OMX_VPP_COMPONENT_BUFFER** ppCmpBuf,
3127 OMX_U32 Index)
3128 {
3129 OMX_ERRORTYPE eError = OMX_ErrorNone;
3130 OMX_VPP_COMPONENT_BUFFER* pComponentBuffer = NULL;
3131 int i = 0 ;
3132 int nBuf = pComponentPrivate->sCompPorts[Index].nBufferCount;
3133
3134 VPP_DPRINT("VPP:: Buffer Count :: %ld\n",nBuf);
3135
3136 VPP_DPRINT("VPP:: Index of Buffer Type :: %ld\n",Index);
3137
3138 for (i=0; i<nBuf; i++) {
3139 pComponentBuffer = &pComponentPrivate->sCompPorts[Index].pVPPBufHeader[i];
3140 if (pBuffer == pComponentBuffer->pBufHeader->pBuffer) {
3141 *ppCmpBuf = pComponentBuffer;
3142 VPP_DPRINT("VPP::%d::Corresponding LCML Header Found\n",__LINE__);
3143 goto EXIT;
3144 }
3145 }
3146
3147 VPP_DPRINT("VPP: %d, Haven't found the header...\n", __LINE__);
3148 eError = OMX_ErrorMax;
3149 EXIT:
3150 return eError;
3151 }
3152
3153
3154
3155 /* -------------------------------------------------------------------*/
3156 /**
3157 * GetLCMLHandle() function will be called to load LCML component
3158 *
3159 *
3160 *
3161 * @retval OMX_NoError Success, ready to roll
3162 * OMX_ErrorUndefined The input parameter pointer is null
3163 **/
3164 /*-------------------------------------------------------------------*/
VPP_GetLCMLHandle(VPP_COMPONENT_PRIVATE * pComponentPrivate)3165 OMX_HANDLETYPE VPP_GetLCMLHandle(VPP_COMPONENT_PRIVATE* pComponentPrivate)
3166 {
3167 #ifndef UNDER_CE
3168 void *handle;
3169 OMX_ERRORTYPE (*fpGetHandle)(OMX_HANDLETYPE);
3170 OMX_HANDLETYPE pHandle = NULL;
3171 char *error = NULL;
3172 OMX_ERRORTYPE eError;
3173
3174 handle = dlopen("libLCML.so", RTLD_LAZY);
3175 if (!handle) {
3176 fputs(dlerror(), stderr);
3177 goto EXIT;
3178 }
3179 fpGetHandle = dlsym (handle, "GetHandle");
3180 if ((error = dlerror()) != NULL) {
3181 if(fpGetHandle){
3182 dlclose(handle);
3183 handle = NULL;
3184 }
3185 fputs(error, stderr);
3186 goto EXIT;
3187 }
3188 eError = (*fpGetHandle)(&pHandle);
3189 if(eError != OMX_ErrorNone) {
3190 eError = OMX_ErrorUndefined;
3191 VPP_DPRINT("eError != OMX_ErrorNone...\n");
3192 pHandle = NULL;
3193 goto EXIT;
3194 }
3195 pComponentPrivate->pDllHandle = handle;
3196 pComponentPrivate->pLCML = (void*)pHandle;
3197 pComponentPrivate->pLCML->pComponentPrivate = (VPP_COMPONENT_PRIVATE *)pComponentPrivate;
3198
3199 EXIT:
3200 return pHandle;
3201 #else
3202
3203 typedef OMX_ERRORTYPE (*LPFNDLLFUNC1)(OMX_HANDLETYPE);
3204 OMX_HANDLETYPE pHandle = NULL;
3205 OMX_ERRORTYPE eError;
3206 LPFNDLLFUNC1 fpGetHandle1;
3207
3208 g_hLcmlDllHandle = LoadLibraryEx(TEXT("OAF_BML.dll"), NULL, 0);
3209 if (g_hLcmlDllHandle == NULL) {
3210 VPP_DPRINT("BML Load Failed!!!\n");
3211 return pHandle;
3212 }
3213
3214 fpGetHandle1 = (LPFNDLLFUNC1)GetProcAddress(g_hLcmlDllHandle,TEXT("GetHandle"));
3215 if (!fpGetHandle1) {
3216 FreeLibrary(g_hLcmlDllHandle);
3217 g_hLcmlDllHandle = NULL;
3218 return pHandle;
3219 }
3220
3221 eError = fpGetHandle1(&pHandle);
3222 if(eError != OMX_ErrorNone) {
3223 FreeLibrary(g_hLcmlDllHandle);
3224 g_hLcmlDllHandle = NULL;
3225 eError = OMX_ErrorUndefined;
3226 VPP_DPRINT("eError != OMX_ErrorNone...\n");
3227 pHandle = NULL;
3228 goto EXIT;
3229 }
3230
3231 (LCML_DSP_INTERFACE*)pComponentPrivate->pLCML = (LCML_DSP_INTERFACE*)pHandle;
3232 pComponentPrivate->pLCML->pComponentPrivate = (VPP_COMPONENT_PRIVATE *)pComponentPrivate;
3233 EXIT:
3234 return pHandle;
3235 #endif
3236 }
3237
3238
3239
VPP_Initialize_PrivateStruct(VPP_COMPONENT_PRIVATE * pComponentPrivate)3240 OMX_ERRORTYPE VPP_Initialize_PrivateStruct(VPP_COMPONENT_PRIVATE *pComponentPrivate)
3241 {
3242 int port;
3243 int buffers;
3244
3245 OMX_ERRORTYPE eError=OMX_ErrorNone;
3246
3247 OMX_INIT_STRUCT(pComponentPrivate->pPortParamTypeVideo, OMX_PORT_PARAM_TYPE);
3248 pComponentPrivate->pPortParamTypeVideo->nPorts = NUM_OF_VPP_PORTS;
3249 pComponentPrivate->pPortParamTypeVideo->nStartPortNumber = 0;
3250
3251 OMX_INIT_STRUCT(pComponentPrivate->pPortParamTypeImage, OMX_PORT_PARAM_TYPE);
3252 pComponentPrivate->pPortParamTypeImage->nPorts = 0;
3253 pComponentPrivate->pPortParamTypeImage->nStartPortNumber = -1;
3254
3255 OMX_INIT_STRUCT(pComponentPrivate->pPortParamTypeAudio, OMX_PORT_PARAM_TYPE);
3256 pComponentPrivate->pPortParamTypeAudio->nPorts = 0;
3257 pComponentPrivate->pPortParamTypeAudio->nStartPortNumber = -1;
3258
3259 OMX_INIT_STRUCT(pComponentPrivate->pPortParamTypeOthers, OMX_PORT_PARAM_TYPE);
3260 pComponentPrivate->pPortParamTypeOthers->nPorts = 0;
3261 pComponentPrivate->pPortParamTypeOthers->nStartPortNumber = -1;
3262 OMX_INIT_STRUCT(pComponentPrivate->pCrop, OMX_CONFIG_RECTTYPE);
3263 pComponentPrivate->pCrop->nWidth = DEFAULT_WIDTH;
3264 pComponentPrivate->pCrop->nHeight = 220;
3265
3266 /* Set component version */
3267 pComponentPrivate->ComponentVersion.s.nVersionMajor = VPP_MAJOR_VER;
3268 pComponentPrivate->ComponentVersion.s.nVersionMinor = VPP_MINOR_VER;
3269 pComponentPrivate->ComponentVersion.s.nRevision = VPP_REVISION;
3270 pComponentPrivate->ComponentVersion.s.nStep = VPP_STEP;
3271
3272
3273 /* Set Default values for each port supports qcif size and two streams */
3274 pComponentPrivate->sCompPorts[OMX_VPP_INPUT_PORT].pPortDef.nPortIndex = OMX_VPP_INPUT_PORT;
3275 pComponentPrivate->sCompPorts[OMX_VPP_INPUT_PORT].pPortDef.eDir = OMX_DirInput;
3276 pComponentPrivate->sCompPorts[OMX_VPP_INPUT_PORT].pPortDef.eDomain = OMX_PortDomainVideo;
3277 pComponentPrivate->sCompPorts[OMX_VPP_INPUT_PORT].pPortDef.nBufferCountActual = MIN_NUM_OF_VPP_BUFFERS;
3278 pComponentPrivate->sCompPorts[OMX_VPP_INPUT_PORT].pPortDef.nBufferCountMin = MIN_NUM_OF_VPP_BUFFERS;
3279 pComponentPrivate->sCompPorts[OMX_VPP_INPUT_PORT].pPortDef.nBufferSize = DEFAULT_WIDTH * 220*1.5;
3280 pComponentPrivate->sCompPorts[OMX_VPP_INPUT_PORT].pPortDef.bEnabled = OMX_TRUE;
3281 pComponentPrivate->sCompPorts[OMX_VPP_INPUT_PORT].pPortDef.bPopulated = OMX_FALSE;
3282 pComponentPrivate->sCompPorts[OMX_VPP_INPUT_PORT].pPortDef.format.video.nFrameWidth = DEFAULT_WIDTH;
3283 pComponentPrivate->sCompPorts[OMX_VPP_INPUT_PORT].pPortDef.format.video.nFrameHeight = 220;
3284 pComponentPrivate->sCompPorts[OMX_VPP_INPUT_PORT].pPortDef.format.video.nStride = 176;
3285 pComponentPrivate->sCompPorts[OMX_VPP_INPUT_PORT].pPortDef.format.video.nSliceHeight = 16;
3286 pComponentPrivate->sCompPorts[OMX_VPP_INPUT_PORT].pPortDef.format.video.eColorFormat = OMX_COLOR_FormatYUV420PackedPlanar;/*OMX_COLOR_FormatCbYCrY;*/
3287 pComponentPrivate->sCompPorts[OMX_VPP_INPUT_PORT].pPortDef.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
3288 pComponentPrivate->sCompPorts[OMX_VPP_INPUT_PORT].eSupplierSetting = OMX_BufferSupplyInput;
3289 pComponentPrivate->sCompPorts[OMX_VPP_INPUT_PORT].hTunnelComponent = NULL;
3290 pComponentPrivate->sCompPorts[OMX_VPP_INPUT_PORT].nReturnedBufferCount = 0;
3291 pComponentPrivate->sCompPorts[OMX_VPP_INPUT_PORT].eMirror = OMX_MirrorNone;
3292
3293 pComponentPrivate->sCompPorts[OMX_VPP_INPUT_OVERLAY_PORT].pPortDef.nPortIndex = OMX_VPP_INPUT_OVERLAY_PORT;
3294 pComponentPrivate->sCompPorts[OMX_VPP_INPUT_OVERLAY_PORT].pPortDef.eDir = OMX_DirInput;
3295 pComponentPrivate->sCompPorts[OMX_VPP_INPUT_OVERLAY_PORT].pPortDef.eDomain = OMX_PortDomainVideo;
3296 pComponentPrivate->sCompPorts[OMX_VPP_INPUT_OVERLAY_PORT].pPortDef.nBufferCountActual = MIN_NUM_OF_VPP_BUFFERS;
3297 pComponentPrivate->sCompPorts[OMX_VPP_INPUT_OVERLAY_PORT].pPortDef.nBufferCountMin = MIN_NUM_OF_VPP_BUFFERS;
3298 pComponentPrivate->sCompPorts[OMX_VPP_INPUT_OVERLAY_PORT].pPortDef.nBufferSize = DEFAULT_HEIGHT *DEFAULT_WIDTH * 3;
3299 pComponentPrivate->sCompPorts[OMX_VPP_INPUT_OVERLAY_PORT].pPortDef.bEnabled = OMX_TRUE;
3300 pComponentPrivate->sCompPorts[OMX_VPP_INPUT_OVERLAY_PORT].pPortDef.bPopulated = OMX_FALSE;
3301 pComponentPrivate->sCompPorts[OMX_VPP_INPUT_OVERLAY_PORT].pPortDef.format.video.nFrameWidth = DEFAULT_WIDTH;
3302 pComponentPrivate->sCompPorts[OMX_VPP_INPUT_OVERLAY_PORT].pPortDef.format.video.nFrameHeight = DEFAULT_HEIGHT;
3303 pComponentPrivate->sCompPorts[OMX_VPP_INPUT_OVERLAY_PORT].pPortDef.format.video.eColorFormat = OMX_COLOR_Format24bitRGB888;
3304 pComponentPrivate->sCompPorts[OMX_VPP_INPUT_OVERLAY_PORT].pPortDef.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
3305 pComponentPrivate->sCompPorts[OMX_VPP_INPUT_OVERLAY_PORT].eSupplierSetting = OMX_BufferSupplyInput;
3306 pComponentPrivate->sCompPorts[OMX_VPP_INPUT_OVERLAY_PORT].hTunnelComponent = NULL;
3307
3308 pComponentPrivate->sCompPorts[OMX_VPP_INPUT_OVERLAY_PORT].nReturnedBufferCount = 0;
3309 pComponentPrivate->sCompPorts[OMX_VPP_INPUT_OVERLAY_PORT].eMirror = OMX_MirrorNone;
3310
3311 pComponentPrivate->sCompPorts[OMX_VPP_RGB_OUTPUT_PORT].pPortDef.nPortIndex = OMX_VPP_RGB_OUTPUT_PORT;
3312 pComponentPrivate->sCompPorts[OMX_VPP_RGB_OUTPUT_PORT].pPortDef.eDir = OMX_DirOutput;
3313 pComponentPrivate->sCompPorts[OMX_VPP_RGB_OUTPUT_PORT].pPortDef.eDomain = OMX_PortDomainVideo;
3314 pComponentPrivate->sCompPorts[OMX_VPP_RGB_OUTPUT_PORT].pPortDef.nBufferCountActual =MIN_NUM_OF_VPP_BUFFERS;
3315 pComponentPrivate->sCompPorts[OMX_VPP_RGB_OUTPUT_PORT].pPortDef.nBufferCountMin = MIN_NUM_OF_VPP_BUFFERS;
3316 pComponentPrivate->sCompPorts[OMX_VPP_RGB_OUTPUT_PORT].pPortDef.nBufferSize = DEFAULT_HEIGHT *DEFAULT_WIDTH *2;
3317 pComponentPrivate->sCompPorts[OMX_VPP_RGB_OUTPUT_PORT].pPortDef.bEnabled = OMX_TRUE;
3318 pComponentPrivate->sCompPorts[OMX_VPP_RGB_OUTPUT_PORT].pPortDef.bPopulated = OMX_FALSE;
3319 pComponentPrivate->sCompPorts[OMX_VPP_RGB_OUTPUT_PORT].pPortDef.format.video.nFrameWidth = DEFAULT_WIDTH;
3320 pComponentPrivate->sCompPorts[OMX_VPP_RGB_OUTPUT_PORT].pPortDef.format.video.nFrameHeight = DEFAULT_HEIGHT;
3321 pComponentPrivate->sCompPorts[OMX_VPP_RGB_OUTPUT_PORT].pPortDef.format.video.eColorFormat = OMX_COLOR_Format16bitRGB565;
3322 pComponentPrivate->sCompPorts[OMX_VPP_RGB_OUTPUT_PORT].pPortDef.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
3323 pComponentPrivate->sCompPorts[OMX_VPP_RGB_OUTPUT_PORT].eSupplierSetting = OMX_BufferSupplyInput;
3324 pComponentPrivate->sCompPorts[OMX_VPP_RGB_OUTPUT_PORT].hTunnelComponent = NULL;
3325 pComponentPrivate->sCompPorts[OMX_VPP_RGB_OUTPUT_PORT].nReturnedBufferCount = 0;
3326 pComponentPrivate->sCompPorts[OMX_VPP_RGB_OUTPUT_PORT].eMirror = OMX_MirrorNone;
3327
3328 pComponentPrivate->sCompPorts[OMX_VPP_YUV_OUTPUT_PORT].pPortDef.nPortIndex = OMX_VPP_YUV_OUTPUT_PORT;
3329 pComponentPrivate->sCompPorts[OMX_VPP_YUV_OUTPUT_PORT].pPortDef.eDir = OMX_DirOutput;
3330 pComponentPrivate->sCompPorts[OMX_VPP_YUV_OUTPUT_PORT].pPortDef.eDomain = OMX_PortDomainVideo;
3331 pComponentPrivate->sCompPorts[OMX_VPP_YUV_OUTPUT_PORT].pPortDef.nBufferCountActual = 1;
3332 pComponentPrivate->sCompPorts[OMX_VPP_YUV_OUTPUT_PORT].pPortDef.nBufferCountMin = 1;
3333 pComponentPrivate->sCompPorts[OMX_VPP_YUV_OUTPUT_PORT].pPortDef.nBufferSize = (DEFAULT_HEIGHT *DEFAULT_WIDTH *2);
3334 pComponentPrivate->sCompPorts[OMX_VPP_YUV_OUTPUT_PORT].pPortDef.bEnabled = OMX_TRUE;
3335 pComponentPrivate->sCompPorts[OMX_VPP_YUV_OUTPUT_PORT].pPortDef.bPopulated = OMX_FALSE;
3336 pComponentPrivate->sCompPorts[OMX_VPP_YUV_OUTPUT_PORT].pPortDef.format.video.nFrameWidth = DEFAULT_WIDTH;
3337 pComponentPrivate->sCompPorts[OMX_VPP_YUV_OUTPUT_PORT].pPortDef.format.video.nFrameHeight = DEFAULT_HEIGHT;
3338 pComponentPrivate->sCompPorts[OMX_VPP_YUV_OUTPUT_PORT].pPortDef.format.video.eColorFormat = OMX_COLOR_FormatCbYCrY;
3339 pComponentPrivate->sCompPorts[OMX_VPP_YUV_OUTPUT_PORT].pPortDef.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
3340 pComponentPrivate->sCompPorts[OMX_VPP_YUV_OUTPUT_PORT].eSupplierSetting = OMX_BufferSupplyInput;
3341 pComponentPrivate->sCompPorts[OMX_VPP_YUV_OUTPUT_PORT].hTunnelComponent = NULL;
3342 pComponentPrivate->sCompPorts[OMX_VPP_YUV_OUTPUT_PORT].nReturnedBufferCount = 0;
3343 pComponentPrivate->sCompPorts[OMX_VPP_YUV_OUTPUT_PORT].eMirror = OMX_MirrorNone;
3344
3345
3346 /* Set pInPortFormat defaults */
3347 OMX_INIT_STRUCT(pComponentPrivate->pInPortFormat, OMX_VIDEO_PARAM_PORTFORMATTYPE);
3348 pComponentPrivate->pInPortFormat->nPortIndex = OMX_VPP_INPUT_PORT;
3349 pComponentPrivate->pInPortFormat->nIndex = 9;
3350 pComponentPrivate->pInPortFormat->eColorFormat = OMX_COLOR_FormatYUV420PackedPlanar;/*OMX_COLOR_FormatCbYCrY; */
3351 pComponentPrivate->pInPortFormat->eCompressionFormat = OMX_VIDEO_CodingUnused;
3352
3353
3354 OMX_INIT_STRUCT(pComponentPrivate->pInPortOverlayFormat, OMX_VIDEO_PARAM_PORTFORMATTYPE);
3355 pComponentPrivate->pInPortOverlayFormat->nPortIndex = OMX_VPP_INPUT_OVERLAY_PORT;
3356 pComponentPrivate->pInPortOverlayFormat->nIndex = 1;
3357 pComponentPrivate->pInPortOverlayFormat->eColorFormat = OMX_COLOR_Format24bitRGB888;
3358 pComponentPrivate->pInPortOverlayFormat->eCompressionFormat = OMX_VIDEO_CodingUnused;
3359
3360 /* Set pOutPortFormat defaults */
3361 OMX_INIT_STRUCT(pComponentPrivate->pOutPortRGBFormat, OMX_VIDEO_PARAM_PORTFORMATTYPE);
3362 pComponentPrivate->pOutPortRGBFormat->nPortIndex = OMX_VPP_RGB_OUTPUT_PORT;
3363 pComponentPrivate->pOutPortRGBFormat->nIndex = 8;
3364 pComponentPrivate->pOutPortRGBFormat->eColorFormat = OMX_COLOR_Format16bitRGB565;
3365 pComponentPrivate->pOutPortRGBFormat->eCompressionFormat = OMX_VIDEO_CodingUnused;
3366
3367 /* Set pOutPortFormat defaults */
3368 OMX_INIT_STRUCT(pComponentPrivate->pOutPortYUVFormat, OMX_VIDEO_PARAM_PORTFORMATTYPE);
3369 pComponentPrivate->pOutPortYUVFormat->nPortIndex = OMX_VPP_YUV_OUTPUT_PORT;
3370 pComponentPrivate->pOutPortYUVFormat->nIndex = 2;
3371 pComponentPrivate->pOutPortYUVFormat->eColorFormat = OMX_COLOR_FormatCbYCrY;
3372 pComponentPrivate->pOutPortYUVFormat->eCompressionFormat = OMX_VIDEO_CodingUnused;
3373
3374 /*Set sScale defaults*/
3375 pComponentPrivate->sScale.nSize = sizeof(OMX_CONFIG_SCALEFACTORTYPE);
3376 pComponentPrivate->sScale.nVersion.s.nVersionMajor = VPP_MAJOR_VER;
3377 pComponentPrivate->sScale.nVersion.s.nVersionMinor = VPP_MINOR_VER;
3378 pComponentPrivate->sScale.nVersion.s.nRevision = VPP_REVISION;
3379 pComponentPrivate->sScale.nVersion.s.nStep = VPP_STEP;
3380 pComponentPrivate->sScale.xHeight = 0;
3381 pComponentPrivate->sScale.xWidth = 0;
3382
3383 /* Set pPriorityMgmt defaults */
3384 OMX_INIT_STRUCT(pComponentPrivate->pPriorityMgmt, OMX_PRIORITYMGMTTYPE);
3385 pComponentPrivate->pPriorityMgmt->nGroupPriority = 0;
3386 pComponentPrivate->pPriorityMgmt->nGroupID = 0;
3387
3388 pComponentPrivate->pMarkData = NULL;
3389 pComponentPrivate->hMarkTargetComponent = NULL;
3390 pComponentPrivate->bIsStopping = 0;
3391
3392 pComponentPrivate->nInputFrame = 0;
3393 pComponentPrivate->nOverlayFrame = 0;
3394 pComponentPrivate->nInYUVBufferCount = 0;
3395 pComponentPrivate->nInRGBBufferCount = 0;
3396 pComponentPrivate->nOutYUVBufferCount = 0;
3397 pComponentPrivate->nOutRGBBufferCount = 0;
3398
3399 pComponentPrivate->nFlushPort = OMX_NOPORT;
3400
3401 pthread_mutex_init(&pComponentPrivate->vpp_mutex, NULL);
3402 pthread_cond_init(&pComponentPrivate->stop_cond, NULL);
3403 pthread_mutex_init(&pComponentPrivate->buf_mutex, NULL);
3404
3405 /* Set pInBufSupplier defaults */
3406 for(port=0; port<NUM_OF_VPP_PORTS; port++) {
3407 for (buffers = 0; buffers < NUM_OF_VPP_BUFFERS; buffers++) {
3408 pComponentPrivate->sCompPorts[port].pVPPBufHeader[buffers].pBufHeader = NULL;
3409 pComponentPrivate->sCompPorts[port].pVPPBufHeader[buffers].pBufferStart = NULL;
3410 pComponentPrivate->sCompPorts[port].nBufferCount = 0;
3411 pComponentPrivate->sCompPorts[port].nBufSupplier = OMX_FALSE;
3412 }
3413 }
3414 pComponentPrivate->RGBbuffer = NULL;
3415 pComponentPrivate->pLcmlHandle = NULL;
3416 pComponentPrivate->bPreempted = OMX_FALSE;
3417
3418 return eError;
3419 }
3420
3421
3422
3423 /*-------------------------------------------------------------------*/
3424 /**
3425 * IsTIOMXComponent()
3426 *
3427 * Check if the component is TI component.
3428 *
3429 * @param hTunneledComp Component Tunnel Pipe
3430 *
3431 * @retval OMX_TRUE Input is a TI component.
3432 * OMX_FALSE Input is a not a TI component.
3433 *
3434 **/
3435 /*-------------------------------------------------------------------*/
3436
IsTIOMXComponent(OMX_HANDLETYPE hComp)3437 OMX_BOOL IsTIOMXComponent(OMX_HANDLETYPE hComp)
3438 {
3439
3440 OMX_ERRORTYPE eError = OMX_ErrorNone;
3441 OMX_STRING pTunnelcComponentName = NULL;
3442 OMX_VERSIONTYPE* pTunnelComponentVersion = NULL;
3443 OMX_VERSIONTYPE* pSpecVersion = NULL;
3444 OMX_UUIDTYPE* pComponentUUID = NULL;
3445 char *pSubstring = NULL;
3446 OMX_BOOL bResult = OMX_TRUE;
3447
3448 OMX_MALLOC(pTunnelcComponentName, 128);
3449 OMX_MALLOC(pTunnelComponentVersion, sizeof(OMX_VERSIONTYPE));
3450 OMX_MALLOC(pSpecVersion, sizeof(OMX_VERSIONTYPE));
3451 OMX_MALLOC(pComponentUUID, sizeof(OMX_UUIDTYPE));
3452
3453 eError = OMX_GetComponentVersion (hComp, pTunnelcComponentName, pTunnelComponentVersion, pSpecVersion, pComponentUUID);
3454
3455 /* Check if tunneled component is a TI component */
3456 pSubstring = strstr(pTunnelcComponentName, "OMX.TI.");
3457
3458 if(pSubstring == NULL) {
3459 bResult = OMX_FALSE;
3460 }
3461
3462 EXIT:
3463 OMX_FREE(pTunnelcComponentName);
3464 OMX_FREE(pTunnelComponentVersion);
3465 OMX_FREE(pSpecVersion);
3466 OMX_FREE(pComponentUUID);
3467
3468 return bResult;
3469 } /* End of IsTIOMXComponent */
3470
3471
3472
3473 /*-------------------------------------------------------------------*/
3474 /**
3475 * VPP_InitBufferDataPropagation()
3476 *
3477 *
3478 *
3479 *
3480 * @param
3481 * @param
3482 * @param
3483 *
3484 * @retval OMX_NoError Success, ready to roll
3485 *
3486 **/
3487 /*-------------------------------------------------------------------*/
VPP_InitBufferDataPropagation(VPP_COMPONENT_PRIVATE * pComponentPrivate,OMX_U32 nPortIndex)3488 void VPP_InitBufferDataPropagation(
3489 VPP_COMPONENT_PRIVATE *pComponentPrivate,
3490 OMX_U32 nPortIndex)
3491 {
3492 VPP_PORT_TYPE *pPortType = NULL;
3493 int i;
3494
3495 pPortType = &(pComponentPrivate->sCompPorts[nPortIndex]);
3496
3497 /* assume pPortType->pPortDef->nBufferCountActual <= NUM_OF_BUFFERSJPEG */
3498 for (i = 0; i < pPortType->pPortDef.nBufferCountActual; i ++) {
3499 pPortType->sBufferDataProp[i].flag = 0;
3500 pPortType->sBufferDataProp[i].buffer_idYUV = 0xFFFFFFFF;
3501 pPortType->sBufferDataProp[i].buffer_idRGB = 0xFFFFFFFF;
3502 pPortType->sBufferDataProp[i].pMarkData = NULL;
3503 pPortType->sBufferDataProp[i].hMarkTargetComponent = NULL;
3504 pPortType->sBufferDataProp[i].nTickCount = 0;
3505 pPortType->sBufferDataProp[i].nTimeStamp = 0;
3506 }
3507 }
3508
3509
3510 #ifdef RESOURCE_MANAGER_ENABLED
3511 /* ========================================================================== */
3512 /**
3513 * ResourceManagerCallback() - handle callbacks from Resource Manager
3514 * @param cbData Resource Manager Command Data Structure
3515 * @return: void
3516 **/
3517 /* ========================================================================== */
3518
ResourceManagerCallback(RMPROXY_COMMANDDATATYPE cbData)3519 void ResourceManagerCallback(RMPROXY_COMMANDDATATYPE cbData)
3520 {
3521 OMX_COMMANDTYPE Cmd = OMX_CommandStateSet;
3522 OMX_COMPONENTTYPE *pHandle = (OMX_COMPONENTTYPE *)cbData.hComponent;
3523 VPP_COMPONENT_PRIVATE *pComponentPrivate = NULL;
3524 OMX_ERRORTYPE RM_Error = *(cbData.RM_Error);
3525
3526 VPP_DPRINT("%s: %d: RM_Error = %x\n", __FUNCTION__, __LINE__, RM_Error);
3527
3528 pComponentPrivate = (VPP_COMPONENT_PRIVATE *)pHandle->pComponentPrivate;
3529
3530 if (RM_Error == OMX_RmProxyCallback_ResourcesPreempted) {
3531
3532 pComponentPrivate->bPreempted = 1;
3533
3534 if (pComponentPrivate->curState == OMX_StateExecuting ||
3535 pComponentPrivate->curState == OMX_StatePause) {
3536
3537 pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle,
3538 pComponentPrivate->pHandle->pApplicationPrivate,
3539 OMX_EventError,
3540 OMX_ErrorResourcesPreempted,
3541 OMX_TI_ErrorMajor,
3542 NULL);
3543
3544 pComponentPrivate->toState = OMX_StateIdle;
3545 pComponentPrivate->bIsStopping = OMX_TRUE;
3546 VPP_DPRINT("Component Preempted. Going to IDLE State.\n");
3547 }
3548 else if (pComponentPrivate->curState == OMX_StateIdle){
3549 pComponentPrivate->toState = OMX_StateLoaded;
3550 VPP_DPRINT("Component Preempted. Going to LOADED State.\n");
3551 }
3552
3553 #ifdef __PERF_INSTRUMENTATION__
3554 PERF_SendingCommand(pComponentPrivate->pPERF, Cmd, pComponentPrivate->toState, PERF_ModuleComponent);
3555 #endif
3556
3557 write (pComponentPrivate->cmdPipe[1], &Cmd, sizeof(Cmd));
3558 write (pComponentPrivate->nCmdDataPipe[1], &(pComponentPrivate->toState) ,sizeof(OMX_U32));
3559
3560 }
3561 else if (RM_Error == OMX_RmProxyCallback_ResourcesAcquired ){
3562
3563 if (pComponentPrivate->curState == OMX_StateWaitForResources) /* Wait for Resource Response */
3564 {
3565 pComponentPrivate->cbInfo.EventHandler (
3566 pHandle, pHandle->pApplicationPrivate,
3567 OMX_EventResourcesAcquired, 0,0,
3568 NULL);
3569
3570 pComponentPrivate->toState = OMX_StateIdle;
3571 pComponentPrivate->bIsStopping = OMX_TRUE;
3572
3573 #ifdef __PERF_INSTRUMENTATION__
3574 PERF_SendingCommand(pComponentPrivate->pPERF, Cmd, pComponentPrivate->toState, PERF_ModuleComponent);
3575 #endif
3576
3577 write (pComponentPrivate->cmdPipe[1], &Cmd, sizeof(Cmd));
3578 write (pComponentPrivate->nCmdDataPipe[1], &(pComponentPrivate->toState) ,sizeof(OMX_U32));
3579 VPP_DPRINT("OMX_RmProxyCallback_ResourcesAcquired.\n");
3580 }
3581
3582 }
3583
3584 }
3585 #endif
3586
LinkedList_Create(LinkedList * LinkedList)3587 void LinkedList_Create(LinkedList *LinkedList) {
3588 LinkedList->pRoot = NULL;
3589 }
3590
LinkedList_AddElement(LinkedList * LinkedList,void * pValue)3591 void LinkedList_AddElement(LinkedList *LinkedList, void *pValue) {
3592 /* create new node and fill the value */
3593 Node *pNewNode = (Node *)malloc(sizeof(Node));
3594 if (pNewNode != NULL) {
3595 pNewNode->pValue = (void *)pValue;
3596 /*printf("LinkedList:::: Pointer=%p has been added.\n", pNewNode->pValue); */
3597 /* add new node on the root to implement quick FIFO */
3598 /* modify new node pointers */
3599 if (LinkedList->pRoot == NULL) {
3600 pNewNode->pNextNode = NULL;
3601 }
3602 else {
3603 pNewNode->pNextNode = LinkedList->pRoot;
3604 }
3605 /*modify root */
3606 LinkedList->pRoot = pNewNode;
3607 }
3608 }
3609
LinkedList_FreeElement(LinkedList * LinkedList,void * pValue)3610 void LinkedList_FreeElement(LinkedList *LinkedList, void *pValue) {
3611 Node *pNode = LinkedList->pRoot;
3612 Node *pPastNode = NULL;
3613 while (pNode != NULL) {
3614 if (pNode->pValue == pValue) {
3615 Node *pTempNode = pNode->pNextNode;
3616 if(pPastNode == NULL) {
3617 LinkedList->pRoot = pTempNode;
3618 }
3619 else {
3620 pPastNode->pNextNode = pTempNode;
3621 }
3622 /*printf("LinkedList:::: Pointer=%p has been freed\n", pNode->pValue); */
3623 free(pNode->pValue);
3624 free(pNode);
3625 break;
3626 }
3627 pPastNode = pNode;
3628 pNode = pNode->pNextNode;
3629 }
3630 }
3631
LinkedList_FreeAll(LinkedList * LinkedList)3632 void LinkedList_FreeAll(LinkedList *LinkedList) {
3633 Node *pTempNode;
3634 int nodes = 0;
3635 while (LinkedList->pRoot != NULL) {
3636 pTempNode = LinkedList->pRoot->pNextNode;
3637 /*printf("LinkedList:::: Pointer=%p has been freed\n", LinkedList->pRoot->pValue); */
3638 free(LinkedList->pRoot->pValue);
3639 free(LinkedList->pRoot);
3640 LinkedList->pRoot = pTempNode;
3641 nodes++;
3642 }
3643 /* printf("==================No. of deleted nodes: %d=======================================\n\n", nodes); */
3644 }
3645
LinkedList_DisplayAll(LinkedList * LinkedList)3646 void LinkedList_DisplayAll(LinkedList *LinkedList) {
3647 Node *pNode = LinkedList->pRoot;
3648 int nodes = 0;
3649 printf("\n================== Displaying contents of linked list=%p=====================\n", LinkedList);
3650 printf("root->\n");
3651 while (pNode != NULL) {
3652 printf("[Value=%p, NextNode=%p]->\n", pNode->pValue, pNode->pNextNode);
3653 pNode = pNode->pNextNode;
3654 nodes++;
3655 }
3656 printf("==================No. of existing nodes: %d=======================================\n\n", nodes);
3657 }
3658
LinkedList_Destroy(LinkedList * LinkedList)3659 void LinkedList_Destroy(LinkedList *LinkedList) {
3660 /* do nothing */
3661 }
3662
3663