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_WbAmrEnc_CompThread.c
30*
31* This file implements WBAMR Encoder Component Thread and its functionality
32* that is fully compliant with the Khronos OpenMAX (TM) 1.0 Specification
33*
34* @path  $(CSLPATH)\OMAPSW_MPU\linux\audio\src\openmax_il\wbamr_enc\src
35*
36* @rev  1.0
37*/
38/* ----------------------------------------------------------------------------
39*!
40*! Revision History
41*! ===================================
42*! 21-sept-2006 bk: updated review findings for alpha release
43*! 24-Aug-2006 bk: Khronos OpenMAX (TM) 1.0 Conformance tests some more
44*! 18-July-2006 bk: Khronos OpenMAX (TM) 1.0 Conformance tests validated for few cases
45*! This is newest file
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#else
59#include <wchar.h>
60#include <dbapi.h>
61#include <unistd.h>
62#include <sys/time.h>
63#include <sys/types.h>
64#include <sys/ioctl.h>
65#include <sys/select.h>
66#include <string.h>
67#include <fcntl.h>
68#include <errno.h>
69#include <stdlib.h>
70#include <stdio.h>
71#include <signal.h>
72
73#include <dlfcn.h>
74
75#endif
76/*-------program files ----------------------------------------*/
77#include "OMX_WbAmrEncoder.h"
78#include "OMX_WbAmrEnc_Utils.h"
79#include "OMX_WbAmrEnc_CompThread.h"
80
81/* ================================================================================= */
82/**
83* @fn WBAMRENC_CompThread() Component thread
84*
85*  @see         OMX_WbAmrEnc_CompThread.h
86*/
87/* ================================================================================ */
88
89void* WBAMRENC_CompThread(void* pThreadData) {
90    OMX_ERRORTYPE eError = OMX_ErrorNone;
91    int status;
92    struct timespec tv;
93    int fdmax;
94    int ret = 0;
95    fd_set rfds;
96    OMX_U32 nRet;
97    OMX_BUFFERHEADERTYPE *pBufHeader = NULL;
98    WBAMRENC_COMPONENT_PRIVATE* pComponentPrivate = (WBAMRENC_COMPONENT_PRIVATE*)pThreadData;
99    OMX_COMPONENTTYPE *pHandle = pComponentPrivate->pHandle;
100
101    OMX_U32 commandData;
102    OMX_COMMANDTYPE command;
103
104    OMX_PRINT1(pComponentPrivate->dbg, "Entering\n");
105
106#ifdef __PERF_INSTRUMENTATION__
107    pComponentPrivate->pPERFcomp = PERF_Create(PERF_FOURCC('W', 'B', 'E', '_'),
108                                   PERF_ModuleComponent |
109                                   PERF_ModuleAudioDecode);
110#endif
111
112    fdmax = pComponentPrivate->cmdPipe[0];
113
114    if (pComponentPrivate->dataPipe[0] > fdmax) {
115        fdmax = pComponentPrivate->dataPipe[0];
116    }
117
118    while (1) {
119        FD_ZERO (&rfds);
120        FD_SET (pComponentPrivate->dataPipe[0], &rfds);
121        FD_SET (pComponentPrivate->cmdPipe[0], &rfds);
122
123        tv.tv_sec = 1;
124        tv.tv_nsec = 0;
125
126#ifndef UNDER_CE
127        sigset_t set;
128        sigemptyset (&set);
129        sigaddset (&set, SIGALRM);
130        status = pselect (fdmax + 1, &rfds, NULL, NULL, &tv, &set);
131#else
132        status = select (fdmax + 1, &rfds, NULL, NULL, &tv);
133#endif
134
135        if (pComponentPrivate->bIsThreadstop == 1) {
136            OMX_ERROR4(pComponentPrivate->dbg, "Comp Thrd Exiting!\n");
137            goto EXIT;
138        }
139
140        if (0 == status) {
141            if (pComponentPrivate->bIsThreadstop == 1)  {
142                pComponentPrivate->bIsThreadstop = 0;
143                pComponentPrivate->lcml_nOpBuf = 0;
144                pComponentPrivate->lcml_nIpBuf = 0;
145                pComponentPrivate->app_nBuf = 0;
146
147                if (pComponentPrivate->curState != OMX_StateIdle) {
148                    OMX_ERROR4(pComponentPrivate->dbg, "curState is not OMX_StateIdle\n");
149                    goto EXIT;
150                }
151            }
152
153            OMX_PRINT2(pComponentPrivate->dbg, "Component Time Out !!!!! \n");
154        } else if (-1 == status) {
155            OMX_ERROR4(pComponentPrivate->dbg, "Error in Select\n");
156            pComponentPrivate->cbInfo.EventHandler ( pHandle,
157                    pHandle->pApplicationPrivate,
158                    OMX_EventError,
159                    OMX_ErrorInsufficientResources,
160                    OMX_TI_ErrorSevere,
161                    "Error from Component Thread in select");
162            eError = OMX_ErrorInsufficientResources;
163        } else if ((FD_ISSET (pComponentPrivate->dataPipe[0], &rfds))) {
164            OMX_PRCOMM2(pComponentPrivate->dbg, "DATA pipe is set in Component Thread\n");
165
166            ret = read(pComponentPrivate->dataPipe[0], &pBufHeader, sizeof(pBufHeader));
167
168            if (ret == -1) {
169                OMX_ERROR4(pComponentPrivate->dbg, "Error while reading from the pipe\n");
170                goto EXIT;
171            }
172
173            eError = WBAMRENC_HandleDataBufFromApp(pBufHeader, pComponentPrivate);
174
175            if (eError != OMX_ErrorNone) {
176                OMX_ERROR2(pComponentPrivate->dbg, "WBAMRENC_HandleDataBufFromApp returned error\n");
177                break;
178            }
179        } else if (FD_ISSET (pComponentPrivate->cmdPipe[0], &rfds)) {
180            /* Do not accept any command when the component is stopping */
181            OMX_PRINT1(pComponentPrivate->dbg, "CMD pipe is set in Component Thread\n");
182            ret = read(pComponentPrivate->cmdPipe[0], &command, sizeof (command));
183
184            if (ret == -1) {
185                OMX_ERROR4(pComponentPrivate->dbg, "Error in Reading from the Data pipe\n");
186                eError = OMX_ErrorHardware;
187                goto EXIT;
188            }
189
190            ret = read(pComponentPrivate->cmdDataPipe[0], &commandData, sizeof (commandData));
191
192            if (ret == -1) {
193                OMX_ERROR4(pComponentPrivate->dbg, "Error in Reading from the Data pipe\n");
194                eError = OMX_ErrorHardware;
195                goto EXIT;
196            }
197
198            nRet = WBAMRENC_HandleCommand(pComponentPrivate, command, commandData);
199
200            if (nRet == WBAMRENC_EXIT_COMPONENT_THRD) {
201                pComponentPrivate->curState = OMX_StateLoaded;
202#ifdef __PERF_INSTRUMENTATION__
203                PERF_Boundary(pComponentPrivate->pPERFcomp, PERF_BoundaryComplete | PERF_BoundaryCleanup);
204#endif
205
206                if (pComponentPrivate->bPreempted == 0) {
207                   if(RemoveStateTransition(pComponentPrivate, OMX_TRUE) != OMX_ErrorNone) {
208                       return OMX_ErrorUndefined;
209                   }
210
211                    pComponentPrivate->cbInfo.EventHandler( pHandle,
212                                                            pHandle->pApplicationPrivate,
213                                                            OMX_EventCmdComplete,
214                                                            OMX_CommandStateSet,
215                                                            pComponentPrivate->curState,
216                                                            NULL);
217                } else {
218                    pComponentPrivate->cbInfo.EventHandler( pHandle,
219                                                            pHandle->pApplicationPrivate,
220                                                            OMX_EventError,
221                                                            OMX_ErrorResourcesLost,
222                                                            OMX_TI_ErrorMajor,
223                                                            NULL);
224                    pComponentPrivate->bPreempted = 0;
225                }
226
227            }
228        }
229    }
230
231EXIT:
232#ifdef __PERF_INSTRUMENTATION__
233    PERF_Done(pComponentPrivate->pPERFcomp);
234#endif
235
236    OMX_PRINT1(pComponentPrivate->dbg, "Exiting WBAMRENC_CompThread\n");
237    OMX_PRINT1(pComponentPrivate->dbg, "Returning = 0x%x\n", eError);
238    return (void*)eError;
239}
240
241