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_ComponentThread.c
30 *
31 * This file implements OMX Component for video post processing that
32 * is fully compliant with the OMX Audio specification 1.0.
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 
47 
48 /* ------compilation control switches -------------------------*/
49 /****************************************************************
50 *  INCLUDE FILES
51 ****************************************************************/
52 /* ----- system and platform files ----------------------------*/
53 
54 #ifdef UNDER_CE
55 #include <windows.h>
56 #include <oaf_osal.h>
57 #include <omx_core.h>
58 #include <stdlib.h>
59 #else
60 
61 #define _XOPEN_SOURCE 600
62 
63 #include <unistd.h>
64 #include <sys/time.h>
65 #include <sys/types.h>
66 #include <sys/ioctl.h>
67 #include <sys/select.h>
68 
69 #include <fcntl.h>
70 #include <errno.h>
71 #endif
72 #include <dbapi.h>
73 #include <string.h>
74 
75 #include <stdio.h>
76 
77 #include "OMX_VPP.h"
78 #include "OMX_VPP_Utils.h"
79 #include "OMX_VPP_CompThread.h"
80 #include <OMX_Component.h>
81 #include <signal.h>
82 
83 /** Default timeout used to come out of blocking calls*/
84 #define VPP_THREAD_TIMEOUT (100)
85 
86 
87 /* -------------------------------------------------------------------*/
88 /**
89   *  ComponentThread() thread polling for messages and data in pipe
90   *
91   * @param pThreadData
92   *
93   * @retval OMX_NoError              Success, ready to roll
94   *         OMX_Error_BadParameter   The input parameter pointer is null
95   **/
96 /*-------------------------------------------------------------------*/
VPP_ComponentThreadFunc(void * pThreadData)97 void* VPP_ComponentThreadFunc (void* pThreadData)
98 {
99     int status;
100     struct timeval tv;
101     int fdmax;
102     fd_set rfds;
103     OMX_ERRORTYPE eError = OMX_ErrorNone;
104     OMX_COMMANDTYPE eCmd = -1;
105     OMX_U32 nParam1;
106     int nRet = -1;
107     OMX_PTR pCmdData = NULL;
108     sigset_t set;
109 
110 
111 
112     VPP_COMPONENT_PRIVATE* pComponentPrivate = (VPP_COMPONENT_PRIVATE*)pThreadData;
113     OMX_COMPONENTTYPE *pHandle = pComponentPrivate->pHandle;
114 
115 #ifdef __PERF_INSTRUMENTATION__
116     pComponentPrivate->pPERFcomp = PERF_Create(PERF_FOURCC('V','P','P','T'),
117                                             PERF_ModuleComponent |
118                                             PERF_ModuleVideoEncode | PERF_ModuleImageEncode |
119                                             PERF_ModuleVideoDecode | PERF_ModuleImageDecode);
120 #endif
121 
122     fdmax = pComponentPrivate->cmdPipe[0];
123 
124     /** Looking for highest number of file descriptor
125         for pipes inorder to put in select loop */
126     if (pComponentPrivate->nFree_oPipe[0] > fdmax) {
127         fdmax = pComponentPrivate->nFree_oPipe[0];
128     }
129 
130     if (pComponentPrivate->nFilled_iPipe[0] > fdmax) {
131         fdmax = pComponentPrivate->nFilled_iPipe[0];
132     }
133 
134     while (1) {
135         FD_ZERO (&rfds);
136         FD_SET (pComponentPrivate->cmdPipe[0], &rfds);
137 
138         if (pComponentPrivate->curState != OMX_StatePause) {
139         FD_SET (pComponentPrivate->nFree_oPipe[0], &rfds);
140         FD_SET (pComponentPrivate->nFilled_iPipe[0], &rfds);
141         }
142 
143         tv.tv_sec  = 0;
144         tv.tv_usec = VPP_THREAD_TIMEOUT * 1000;
145 
146 	sigemptyset(&set);
147 	sigaddset(&set,SIGALRM);
148 
149         status = pselect (fdmax+1, &rfds, NULL, NULL, NULL, &set);
150 
151         if (0 == status) {
152             /*VPP_DPRINT("\n\n\n%d ::!!!!!  Component Time Out !!!!!!!!!!!! \n",__LINE__);*/
153             if (pComponentPrivate->bIsStopping == 1) {
154                 pComponentPrivate->bIsStopping = 0;
155                 pComponentPrivate->bIsEOFSent  = 0;
156             }
157             continue;
158         }
159 
160         if (-1 == status) {
161             VPP_DPRINT ("%d :: Error in Select\n", __LINE__);
162             pComponentPrivate->cbInfo.EventHandler (
163                                     pHandle,pHandle->pApplicationPrivate,
164                                     OMX_EventError,OMX_ErrorInsufficientResources,OMX_TI_ErrorSevere,
165                                     "Error from Component Thread in select");
166             goto EXIT;
167         }
168 
169         if (FD_ISSET (pComponentPrivate->cmdPipe[0], &rfds)) {
170             nRet = read(pComponentPrivate->cmdPipe[0], &eCmd, sizeof(eCmd));
171             if (nRet == -1) {
172                 VPP_DPRINT ("Error while writing to the free_oPipe\n");
173                 eError = OMX_ErrorInsufficientResources;
174                 goto EXIT;
175             }
176 
177             if (eCmd == EXIT_COMPONENT_THRD)
178             {
179 
180 #ifdef __PERF_INSTRUMENTATION__
181                 PERF_ReceivedCommand(pComponentPrivate->pPERFcomp,
182                                     eCmd, 0, PERF_ModuleLLMM);
183 #endif
184 
185                 VPP_DPRINT ("VPP::%d: Exiting thread Cmd : \n",__LINE__);
186                 break;
187             }
188 
189 
190             if (eCmd == OMX_CommandMarkBuffer) {
191                 nRet = read(pComponentPrivate->nCmdDataPipe[0], &pCmdData, sizeof(pCmdData));
192                 if (nRet == -1) {
193                     VPP_DPRINT ("Error while writing to the free_oPipe\n");
194                     eError = OMX_ErrorInsufficientResources;
195                     goto EXIT;
196                 }
197             }
198             else {
199                 nRet = read(pComponentPrivate->nCmdDataPipe[0], &nParam1, sizeof(nParam1));
200                 if (nRet == -1) {
201                     VPP_DPRINT ("Error while writing to the free_oPipe\n");
202                     eError = OMX_ErrorInsufficientResources;
203                     goto EXIT;
204                 }
205             }
206 
207 #ifdef __PERF_INSTRUMENTATION__
208             PERF_ReceivedCommand(pComponentPrivate->pPERFcomp,
209                                 eCmd,
210                                 (eCmd == OMX_CommandMarkBuffer) ? ((OMX_U32) pCmdData) : nParam1,
211                                 PERF_ModuleLLMM);
212 #endif
213 
214             switch (eCmd)
215             {
216             case OMX_CommandPortDisable:
217                     VPP_DisablePort(pComponentPrivate, nParam1);
218                     break;
219 
220             case OMX_CommandStateSet:
221                 eError = VPP_HandleCommand(pComponentPrivate, nParam1);
222                 if(eError != OMX_ErrorNone) {
223 #ifdef RESOURCE_MANAGER_ENABLED
224                     pComponentPrivate->curState = OMX_StateInvalid;
225 #endif
226                     pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle,
227                                         pComponentPrivate->pHandle->pApplicationPrivate,
228                                         OMX_EventError,
229                                         OMX_ErrorInsufficientResources,
230                                         OMX_TI_ErrorMajor,
231                                         "Error from Component Thread while processing Command Pipe.\n");
232                     goto EXIT;
233                 }
234                 VPP_DPRINT("return from StateSet %d\n", nParam1);
235                 break;
236 
237             case OMX_CommandPortEnable:
238                 VPP_EnablePort(pComponentPrivate, nParam1);
239                 break;
240 
241             case OMX_CommandMarkBuffer:
242                 /* OMX_CommandMarkBuffer is handled directly on VPP_SendCommand() function*/
243                 break;
244 
245             case OMX_CommandFlush:
246                 VPP_HandleCommandFlush(pComponentPrivate, nParam1, OMX_TRUE);
247                 break;
248             case OMX_CommandMax:
249                 break;
250             }
251             continue;
252         }
253 
254         /*Filled Input Buffer from Application to component*/
255         if ((FD_ISSET(pComponentPrivate->nFilled_iPipe[0], &rfds))) {
256             eError = VPP_Process_FilledInBuf(pComponentPrivate);
257             if (eError != OMX_ErrorNone) {
258                 pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle,
259                                     pComponentPrivate->pHandle->pApplicationPrivate,
260                                     OMX_EventError,
261                                     OMX_ErrorUndefined,
262                                     OMX_TI_ErrorSevere,
263                                     NULL);
264             }
265         }
266         /*Free output buffers from Application to component*/
267         if (FD_ISSET(pComponentPrivate->nFree_oPipe[0], &rfds)) {
268             eError = VPP_Process_FreeOutBuf(pComponentPrivate);
269             if (eError != OMX_ErrorNone) {
270                 pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle,
271                                     pComponentPrivate->pHandle->pApplicationPrivate,
272                                     OMX_EventError,
273                                     OMX_ErrorUndefined,
274                                     OMX_TI_ErrorSevere,
275                                     NULL);
276             }
277         }
278     }
279 
280 EXIT:
281 
282 #ifdef __PERF_INSTRUMENTATION__
283     PERF_Done(pComponentPrivate->pPERFcomp);
284 #endif
285 
286     return (void*)OMX_ErrorNone;
287 }
288