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/*----------------------------------------------------------------------------*/
111void* 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
332OMX_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