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_VideoEnc_Thread.c
30 *
31 * This file implements OMX Component for MPEG-4 encoder that
32 * is fully compliant with the OMX specification 1.5.
33 *
34 * @path $(CSLPATH)\src
35 *
36 * @rev 0.1
37 */
38 /* -------------------------------------------------------------------------- */
39 /* =============================================================================
40 *!
41 *! Revision History
42 *! ================================================================
43 *!
44 *! 02-Feb-2006 mf: Revisions appear in reverse chronological order;
45 *! that is, newest first. The date format is dd-Mon-yyyy.
46 * =========================================================================== */
47
48
49 /* ------compilation control switches ----------------------------------------*/
50 /******************************************************************************
51 * INCLUDE FILES
52 *******************************************************************************/
53 /* ----- system and platform files -------------------------------------------*/
54 #ifdef UNDER_CE
55 #include <windows.h>
56 #include <oaf_osal.h>
57 #include <omx_core.h>
58 #else
59 #define _XOPEN_SOURCE 600
60 #include <wchar.h>
61 #include <unistd.h>
62 #include <sys/select.h>
63 #include <errno.h>
64 #include <fcntl.h>
65 #endif
66
67 #include <dbapi.h>
68 #include <string.h>
69 #include <stdlib.h>
70 #include <stdio.h>
71 #include <signal.h>
72
73 /*------- Program Header Files -----------------------------------------------*/
74 #include "OMX_VideoEnc_Utils.h"
75
76 /******************************************************************************
77 * EXTERNAL REFERENCES NOTE : only use if not found in header file
78 *******************************************************************************/
79 /*--------data declarations --------------------------------------------------*/
80
81 /*--------function prototypes ------------------------------------------------*/
82
83 /******************************************************************************
84 * PUBLIC DECLARATIONS Defined here, used elsewhere
85 *******************************************************************************/
86 /*--------data declarations --------------------------------------------------*/
87
88 /*--------function prototypes ------------------------------------------------*/
89
90 /******************************************************************************
91 * PRIVATE DECLARATIONS Defined here, used only here
92 *******************************************************************************/
93 /*--------data declarations --------------------------------------------------*/
94
95 /*--------macro definitions --------------------------------------------------*/
96
97 /*--------function prototypes ------------------------------------------------*/
98
99 /*----------------------------------------------------------------------------*/
100 /**
101 * OMX_VideoEnc_Thread()
102 *
103 * Called by VIDENC_Start_ComponentThread function.
104 *
105 * @param pThreadData
106 *
107 * @retval OMX_ErrorNone success, ready to roll
108 * OMX_ErrorInsufficientResources if the malloc fails
109 **/
110 /*----------------------------------------------------------------------------*/
OMX_VIDENC_Thread(void * pThreadData)111 void* OMX_VIDENC_Thread (void* pThreadData)
112 {
113 int status = -1;
114 int fdmax = -1;
115 fd_set rfds;
116 OMX_ERRORTYPE eError = OMX_ErrorNone;
117 OMX_COMMANDTYPE eCmd = -1;
118 OMX_U32 nParam1;
119 int nRet = -1;
120 OMX_PTR pCmdData = NULL;
121 VIDENC_COMPONENT_PRIVATE* pComponentPrivate = NULL;
122 LCML_DSP_INTERFACE* pLcmlHandle = NULL;
123 sigset_t set;
124
125 if (!pThreadData)
126 {
127 eError = OMX_ErrorBadParameter;
128 goto OMX_CONF_CMD_BAIL;
129 }
130
131 pComponentPrivate = (VIDENC_COMPONENT_PRIVATE*)pThreadData;
132 pLcmlHandle = (LCML_DSP_INTERFACE*)pComponentPrivate->pLCML;
133
134 #ifdef __PERF_INSTRUMENTATION__
135 pComponentPrivate->pPERFcomp = PERF_Create(PERF_FOURCC('V', 'E', ' ', 'T'),
136 PERF_ModuleComponent |
137 PERF_ModuleVideoEncode);
138 #endif
139
140 /** Looking for highest number of file descriptor
141 for pipes inorder to put in select loop */
142
143 fdmax = pComponentPrivate->nCmdPipe[0];
144
145 if (pComponentPrivate->nFree_oPipe[0] > fdmax)
146 {
147 fdmax = pComponentPrivate->nFree_oPipe[0];
148 }
149
150 if (pComponentPrivate->nFilled_iPipe[0] > fdmax)
151 {
152 fdmax = pComponentPrivate->nFilled_iPipe[0];
153 }
154
155 while (1)
156 {
157 FD_ZERO (&rfds);
158 FD_SET (pComponentPrivate->nCmdPipe[0], &rfds);
159 FD_SET (pComponentPrivate->nFree_oPipe[0], &rfds);
160 FD_SET (pComponentPrivate->nFilled_iPipe[0], &rfds);
161
162 sigemptyset(&set);
163 sigaddset(&set,SIGALRM);
164 status = pselect(fdmax+1, &rfds, NULL, NULL, NULL,&set);
165
166 if (0 == status)
167 {
168 OMX_TRACE2(pComponentPrivate->dbg, "pselect() = 0\n");
169 #ifndef UNDER_CE
170 sched_yield();
171 #else
172 sched_yield();
173 #endif
174 }
175 else if (-1 == status)
176 {
177 if (pComponentPrivate->eState != OMX_StateLoaded)
178 {
179 OMX_TRACE3(pComponentPrivate->dbg, "select() error.\n");
180 OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, OMX_EventError, OMX_ErrorHardware, 0, NULL);
181 }
182 /*OMX_VIDENC_SET_ERROR_BAIL(eError, OMX_ErrorHardware, pComponentPrivate);*/
183 eError = OMX_ErrorHardware;
184 OMX_ERROR5(pComponentPrivate->dbg, "*Fatal Error : %x\n", eError);
185 OMX_VIDENC_HandleError(pComponentPrivate, eError);
186 }
187 else
188 {
189 if (FD_ISSET(pComponentPrivate->nCmdPipe[0], &rfds))
190 {
191 nRet = read(pComponentPrivate->nCmdPipe[0],
192 &eCmd,
193 sizeof(eCmd));
194 if (nRet == -1)
195 {
196 OMX_PRCOMM4(pComponentPrivate->dbg, "Error while reading from cmdPipe\n");
197 OMX_VIDENC_SET_ERROR_BAIL(eError,
198 OMX_ErrorHardware,
199 pComponentPrivate);
200 }
201
202 #ifdef __PERF_INSTRUMENTATION__
203 PERF_ReceivedCommand(pComponentPrivate->pPERFcomp,
204 eCmd, 0, PERF_ModuleLLMM);
205 #endif
206 if (eCmd == (OMX_COMMANDTYPE)-1)
207 {
208 OMX_PRCOMM2(pComponentPrivate->dbg, "Received thread close command.\n");
209 OMX_CONF_SET_ERROR_BAIL(eError, OMX_ErrorNone);
210 }
211
212 if (eCmd == OMX_CommandMarkBuffer)
213 {
214 nRet = read(pComponentPrivate->nCmdDataPipe[0],
215 &pCmdData,
216 sizeof(pCmdData));
217 if (nRet == -1)
218 {
219 OMX_PRCOMM4(pComponentPrivate->dbg, "Error while reading from cmdDataPipe\n");
220 OMX_VIDENC_SET_ERROR_BAIL(eError,
221 OMX_ErrorHardware,
222 pComponentPrivate);
223 }
224 }
225 else
226 {
227 nRet = read(pComponentPrivate->nCmdDataPipe[0],
228 &nParam1,
229 sizeof(nParam1));
230 if (nRet == -1)
231 {
232 OMX_PRCOMM4(pComponentPrivate->dbg, "Error while reading from cmdDataPipe\n");
233 OMX_VIDENC_SET_ERROR_BAIL(eError,
234 OMX_ErrorHardware,
235 pComponentPrivate);
236 }
237 }
238
239 #ifdef __PERF_INSTRUMENTATION__
240 PERF_ReceivedCommand(pComponentPrivate->pPERFcomp,
241 eCmd,
242 (eCmd == OMX_CommandMarkBuffer) ? ((OMX_U32) pCmdData) : nParam1,
243 PERF_ModuleLLMM);
244 #endif
245
246 switch (eCmd)
247 {
248 case OMX_CommandStateSet :
249 OMX_PRSTATE2(pComponentPrivate->dbg, "Enters OMX_VIDENC_HandleCommandStateSet\n");
250 eError = OMX_VIDENC_HandleCommandStateSet(pComponentPrivate,
251 nParam1);
252 OMX_VIDENC_BAIL_IF_ERROR(eError, pComponentPrivate);
253 OMX_PRSTATE2(pComponentPrivate->dbg, "Exits OMX_VIDENC_HandleCommandStateSet\n");
254 break;
255 case OMX_CommandFlush :
256 OMX_PRSTATE2(pComponentPrivate->dbg, "Enters OMX_VIDENC_HandleCommandFlush\n");
257 eError = OMX_VIDENC_HandleCommandFlush(pComponentPrivate,
258 nParam1,
259 OMX_FALSE);
260 OMX_VIDENC_BAIL_IF_ERROR(eError, pComponentPrivate);
261 OMX_PRSTATE2(pComponentPrivate->dbg, "Exits OMX_VIDENC_HandleCommandFlush\n");
262 break;
263 case OMX_CommandPortDisable :
264 OMX_PRSTATE2(pComponentPrivate->dbg, "Enters OMX_VIDENC_HandleCommandDisablePort\n");
265 eError = OMX_VIDENC_HandleCommandDisablePort(pComponentPrivate,
266 nParam1);
267 OMX_VIDENC_BAIL_IF_ERROR(eError, pComponentPrivate);
268 OMX_PRSTATE2(pComponentPrivate->dbg, "Exits OMX_VIDENC_HandleCommandDisablePort\n");
269 break;
270 case OMX_CommandPortEnable :
271 OMX_PRSTATE2(pComponentPrivate->dbg, "Enters OMX_VIDENC_HandleCommandDisablePort\n");
272 eError = OMX_VIDENC_HandleCommandEnablePort(pComponentPrivate,
273 nParam1);
274 OMX_VIDENC_BAIL_IF_ERROR(eError, pComponentPrivate);
275 OMX_PRSTATE2(pComponentPrivate->dbg, "Exits OMX_VIDENC_HandleCommandDisablePort\n");
276 break;
277 case OMX_CommandMarkBuffer :
278 if (!pComponentPrivate->pMarkBuf)
279 {
280 pComponentPrivate->pMarkBuf = (OMX_MARKTYPE*)(pCmdData);
281 }
282 break;
283 default:
284 OMX_VIDENC_EVENT_HANDLER(pComponentPrivate,
285 OMX_EventError,
286 OMX_ErrorUndefined,
287 0,
288 NULL);
289 }
290 }
291
292 if ((FD_ISSET(pComponentPrivate->nFilled_iPipe[0], &rfds)) &&
293 (pComponentPrivate->eState != OMX_StatePause &&
294 pComponentPrivate->eState != OMX_StateIdle &&
295 pComponentPrivate->eState != OMX_StateLoaded))
296 {
297 OMX_PRBUFFER1(pComponentPrivate->dbg, "Enters OMX_VIDENC_Process_FilledInBuf\n");
298 eError = OMX_VIDENC_Process_FilledInBuf(pComponentPrivate);
299 if (eError != OMX_ErrorNone)
300 {
301 OMX_VIDENC_EVENT_HANDLER(pComponentPrivate,
302 OMX_EventError,
303 OMX_ErrorUndefined,
304 0,
305 NULL);
306 OMX_VIDENC_BAIL_IF_ERROR(eError, pComponentPrivate);
307 }
308 OMX_PRBUFFER1(pComponentPrivate->dbg, "Exits OMX_VIDENC_Process_FilledInBuf\n");
309 }
310
311 if (FD_ISSET(pComponentPrivate->nFree_oPipe[0], &rfds) &&
312 (pComponentPrivate->eState!= OMX_StatePause &&
313 pComponentPrivate->eState != OMX_StateIdle &&
314 pComponentPrivate->eState != OMX_StateLoaded))
315 {
316 OMX_PRBUFFER1(pComponentPrivate->dbg, "Enters OMX_VIDENC_Process_FreeOutBuf\n");
317 eError = OMX_VIDENC_Process_FreeOutBuf(pComponentPrivate);
318 if (eError != OMX_ErrorNone)
319 {
320 OMX_VIDENC_EVENT_HANDLER(pComponentPrivate,
321 OMX_EventError,
322 OMX_ErrorUndefined,
323 0,
324 NULL);
325 OMX_VIDENC_BAIL_IF_ERROR(eError, pComponentPrivate);
326 }
327 OMX_PRBUFFER1(pComponentPrivate->dbg, "Exits OMX_VIDENC_Process_FreeOutBuf\n");
328 }
329 }
330 }
331
332 OMX_CONF_CMD_BAIL:
333
334 #ifdef __PERF_INSTRUMENTATION__
335 if (pComponentPrivate)
336 PERF_Done(pComponentPrivate->pPERFcomp);
337 #endif
338 if (pComponentPrivate)
339 OMX_PRINT2(pComponentPrivate->dbg, "Component Thread Exits\n");
340 return (void*)eError;
341 }
342