OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / hardware / ti / omap3 / omx / video / src / openmax_il / video_encode / src / OMX_VideoEnc_Thread.c
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 /*----------------------------------------------------------------------------*/
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 }