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_G729Dec_ComponentThread.c
30 *
31 * This file implements OMX Component for G729 decoder that
32 * is fully compliant with the OMX Audio specification .
33 *
34 * @path  $(OMAPSW_MPU)\linux\audio\src\openmax_il\g729_dec\src
35 *
36 * @rev  0.1
37 */
38/* -----------------------------------------------------------------------------
39 *!
40 *! Revision History
41 *! ===================================
42 *! Date         Author(s)            Version  Description
43 *! ---------    -------------------  -------  ---------------------------------
44 *! 03-Jan-2007  A.Donjon             0.1      Code update for G729 DECODER
45 *!
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#else
57#include <unistd.h>
58#include <dbapi.h>
59#include <string.h>
60#include <fcntl.h>
61#include <stdlib.h>
62#include <stdio.h>
63#include <errno.h>
64#include <sys/select.h>
65#include <sys/time.h>
66#include <signal.h>
67#endif
68
69/*-------program files ----------------------------------------*/
70#include "OMX_G729Dec_Utils.h"
71#include "OMX_G729Decoder.h"
72#include "OMX_G729Dec_ComponentThread.h"
73
74#ifdef RESOURCE_MANAGER_ENABLED
75#include <ResourceManagerProxyAPI.h>
76#endif
77#ifdef __PERF_INSTRUMENTATION__
78#include "perf.h"
79#endif
80
81/****************************************************************
82 * EXTERNAL REFERENCES NOTE : only use if not found in header file
83 ****************************************************************/
84/*--------data declarations -----------------------------------*/
85/*--------function prototypes ---------------------------------*/
86
87/****************************************************************
88 * PUBLIC DECLARATIONS Defined here, used elsewhere
89 ****************************************************************/
90/*--------data declarations -----------------------------------*/
91
92/*--------function prototypes ---------------------------------*/
93
94/****************************************************************
95 * PRIVATE DECLARATIONS Defined here, used only here
96 ****************************************************************/
97/*--------data declarations -----------------------------------*/
98/*--------function prototypes ---------------------------------*/
99/*--------macros ----------------------------------------------*/
100
101
102void* G729DEC_ComponentThread (void* pThreadData)
103{
104    OMX_S16 status = 0;
105    struct timespec tv;
106    OMX_S16 fdmax = 0;
107    fd_set rfds;
108    OMX_U32 nRet = 0;
109    OMX_ERRORTYPE eError = OMX_ErrorNone;
110    G729DEC_COMPONENT_PRIVATE* pComponentPrivate = (G729DEC_COMPONENT_PRIVATE*)pThreadData;
111    OMX_COMPONENTTYPE *pHandle = pComponentPrivate->pHandle;
112    OMX_BUFFERHEADERTYPE *pBufHeader = NULL;
113    ssize_t ret = 0;
114
115    G729DEC_DPRINT("OMX_G729Dec_ComponentThread:%d\n",__LINE__);
116#ifdef __PERF_INSTRUMENTATION__
117    pComponentPrivate->pPERFcomp = PERF_Create(PERF_FOURCC('7', '2', '9', 'E'),
118                                               PERF_ModuleComponent |
119                                               PERF_ModuleAudioDecode);
120#endif
121    fdmax = pComponentPrivate->cmdPipe[0];
122
123    if (pComponentPrivate->dataPipe[0] > fdmax) {
124        fdmax = pComponentPrivate->dataPipe[0];
125    }
126
127    while (1) {
128        FD_ZERO (&rfds);
129        FD_SET (pComponentPrivate->cmdPipe[0], &rfds);
130        FD_SET (pComponentPrivate->dataPipe[0], &rfds);
131
132        tv.tv_sec = 1;
133        tv.tv_nsec = 0;
134
135        sigset_t set;
136        sigemptyset (&set);
137        sigaddset (&set, SIGALRM);
138        status = pselect (fdmax+1, &rfds, NULL, NULL, &tv, &set);
139
140        if (0 == status) {
141
142            G729DEC_DPRINT("%d : bIsStopping = %d\n",__LINE__,
143                           (int)pComponentPrivate->bIsStopping);
144
145            G729DEC_DPRINT("%d : lcml_nOpBuf = %d\n",__LINE__,
146                           (int)pComponentPrivate->lcml_nOpBuf);
147
148            G729DEC_DPRINT("%d : lcml_nIpBuf = %d\n",__LINE__,
149                           (int)pComponentPrivate->lcml_nIpBuf);
150            G729DEC_DPRINT("%d : app_nBuf = %d\n",__LINE__,
151                           (int)pComponentPrivate->app_nBuf);
152
153            if (pComponentPrivate->bIsStopping == 1)  {
154                G729DEC_DPRINT("%d:G729ComponentThread \n",__LINE__);
155
156                G729DEC_DPRINT("%d:G729ComponentThread \n",__LINE__);
157                if(eError != OMX_ErrorNone) {
158                    G729DEC_DPRINT("%d: Error Occurred in Codec Stop..\n",__LINE__);
159                    break;
160                }
161                pComponentPrivate->bIsStopping = 0;
162                pComponentPrivate->lcml_nOpBuf = 0;
163                pComponentPrivate->lcml_nIpBuf = 0;
164                pComponentPrivate->app_nBuf = 0;
165                pComponentPrivate->num_Op_Issued = 0;
166                pComponentPrivate->num_Sent_Ip_Buff = 0;
167                pComponentPrivate->num_Reclaimed_Op_Buff = 0;
168                pComponentPrivate->bIsEOFSent = 0;
169
170                G729DEC_DPRINT("%d:G729ComponentThread \n",__LINE__);
171                if (pComponentPrivate->curState != OMX_StateIdle) {
172                    G729DEC_DPRINT("%d:G729AComponentThread \n",__LINE__);
173                    goto EXIT;
174                }
175            }
176            G729DEC_DPRINT ("%d :: Component Time Out !!!!!!!!!!!! \n",__LINE__);
177
178        } else if (-1 == status) {
179
180            G729DEC_EPRINT ("%d :: Error in Select\n", __LINE__);
181            pComponentPrivate->cbInfo.EventHandler (
182                                                    pHandle,
183                                                    pHandle->pApplicationPrivate,
184                                                    OMX_EventError,OMX_ErrorInsufficientResources,0,
185                                                    "Error from COmponent Thread in select");
186            eError = OMX_ErrorInsufficientResources;
187
188        }
189        else if ((FD_ISSET (pComponentPrivate->dataPipe[0], &rfds))){
190            G729DEC_DPRINT ("%d :: DATA pipe is set in Component Thread\n",__LINE__);
191            ret = read(pComponentPrivate->dataPipe[0], &pBufHeader, sizeof(pBufHeader));
192            if (ret == -1) {
193                G729DEC_DPRINT ("%d :: Error while reading from the pipe\n",__LINE__);
194            }
195            eError = G729DECHandleDataBuf_FromApp (pBufHeader,pComponentPrivate);
196            if (eError != OMX_ErrorNone) {
197                G729DEC_DPRINT ("%d :: Error From G729DECHandleDataBuf_FromApp\n", __LINE__);
198                break;
199            }
200
201        }
202        else if (FD_ISSET (pComponentPrivate->cmdPipe[0], &rfds)) {
203            /* Do not accept any command when the component is stopping */
204            G729DEC_DPRINT ("%d :: CMD pipe is set in Component Thread\n",__LINE__);
205            nRet = G729DECHandleCommand (pComponentPrivate);
206            if (nRet == EXIT_COMPONENT_THRD) {
207                G729DEC_DPRINT ("Exiting from Component thread\n");
208                G729DEC_CleanupInitParams(pHandle);
209                if(eError != OMX_ErrorNone) {
210                    G729DEC_DPRINT("%d :: Function G729Dec_FreeCompResources returned\
211                                                                error\n",__LINE__);
212                    goto EXIT;
213                }
214                G729DEC_DPRINT("%d :: ARM Side Resources Have Been Freed\n",__LINE__);
215                pComponentPrivate->curState = OMX_StateLoaded;
216                if (pComponentPrivate->bPreempted == 0) {
217                    pComponentPrivate->cbInfo.EventHandler(
218                                                           pHandle, pHandle->pApplicationPrivate,
219                                                           OMX_EventCmdComplete,
220                                                           OMX_ErrorNone,pComponentPrivate->curState, NULL);
221                }
222                else {
223                    pComponentPrivate->cbInfo.EventHandler(
224                                                           pHandle, pHandle->pApplicationPrivate,
225                                                           OMX_EventError,
226                                                           OMX_ErrorResourcesLost,pComponentPrivate->curState, NULL);
227                    pComponentPrivate->bPreempted = 0;
228                }
229
230            }
231        }
232
233    }
234 EXIT:
235    G729DEC_DPRINT("%d::Exiting ComponentThread\n",__LINE__);
236    return (void*)eError;
237}
238