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