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_G729Enc_ComponentThread.c
30 *
31 * This file implements G729 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\g729_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 *! 21-Jun-2006 bk: Khronos OpenMAX (TM) 1.0 migration done
46 *! 22-May-2006 bk: DASF recording quality improved
47 *! 19-Apr-2006 bk: DASF recording speed issue resloved
48 *! 23-Feb-2006 bk: DASF functionality added
49 *! 18-Jan-2006 bk: Repated recording issue fixed and LCML changes taken care
50 *! 14-Dec-2005 bk: Initial Version
51 *! 16-Nov-2005 bk: Initial Version
52 *! 23-Sept-2005 bk: Initial Version
53 *! 10-Sept-2005 bk: Initial Version
54 *! 10-Sept-2005 bk:
55 *! This is newest file
56 * =========================================================================== */
57
58/* ------compilation control switches -------------------------*/
59/****************************************************************
60 *  INCLUDE FILES
61 ****************************************************************/
62/* ----- system and platform files ----------------------------*/
63
64#ifdef UNDER_CE
65#include <windows.h>
66#include <oaf_osal.h>
67#include <omx_core.h>
68#else
69#include <dbapi.h>
70#include <unistd.h>
71#include <sys/time.h>
72#include <sys/types.h>
73#include <sys/ioctl.h>
74#include <sys/select.h>
75#include <string.h>
76#include <fcntl.h>
77#include <errno.h>
78#include <stdlib.h>
79#include <stdio.h>
80#include <pthread.h>
81#include <signal.h>
82#include <sys/select.h>
83#endif
84#ifdef RESOURCE_MANAGER_ENABLED
85#include <ResourceManagerProxyAPI.h>
86#endif
87#ifdef __PERF_INSTRUMENTATION__
88#include "perf.h"
89#endif
90
91/*-------program files ----------------------------------------*/
92#include "OMX_G729Enc_Utils.h"
93#include "OMX_G729Enc_ComponentThread.h"
94
95/* ================================================================================= */
96/**
97 * @fn G729ENC_CompThread() Component thread
98 *
99 *  @see         OMX_G729Enc_ComponentThread.h
100 */
101/* ================================================================================ */
102
103void* G729ENC_CompThread(void* pThreadData)
104{
105    OMX_ERRORTYPE eError = OMX_ErrorNone;
106    int status = 0;
107    struct timespec tv;
108    int fdmax = 0;
109    int ret = 0;
110    fd_set rfds;
111    OMX_U32 nRet = 0;
112    OMX_BUFFERHEADERTYPE *pBufHeader = NULL;
113    G729ENC_COMPONENT_PRIVATE* pComponentPrivate = (G729ENC_COMPONENT_PRIVATE*)pThreadData;
114    OMX_COMPONENTTYPE *pHandle = pComponentPrivate->pHandle;
115
116    G729ENC_DPRINT("Entering\n");
117#ifdef __PERF_INSTRUMENTATION__
118    pComponentPrivate->pPERFcomp = PERF_Create(PERF_FOURCC('7', '2', '9', 'E'),
119                                               PERF_ModuleComponent |
120                                               PERF_ModuleAudioDecode);
121#endif
122    fdmax = pComponentPrivate->cmdPipe[0];
123
124    if (pComponentPrivate->dataPipe[0] > fdmax)
125    {
126        fdmax = pComponentPrivate->dataPipe[0];
127    }
128
129    while (1)
130    {
131        FD_ZERO (&rfds);
132        FD_SET (pComponentPrivate->cmdPipe[0], &rfds);
133        FD_SET (pComponentPrivate->dataPipe[0], &rfds);
134        tv.tv_sec = 1;
135        tv.tv_nsec = 0;
136
137#ifndef UNDER_CE
138        sigset_t set;
139        sigemptyset (&set);
140        sigaddset (&set, SIGALRM);
141        status = pselect (fdmax+1, &rfds, NULL, NULL, &tv, &set);
142#else
143        status = select (fdmax+1, &rfds, NULL, NULL, &tv);
144#endif
145        if (0 == status)
146        {
147            G729ENC_DPRINT("bIsThreadstop=%ld\n", pComponentPrivate->bIsThreadstop);
148            G729ENC_DPRINT("lcml_nOpBuf=%ld\n", pComponentPrivate->lcml_nOpBuf);
149            G729ENC_DPRINT("lcml_nIpBuf=%ld\n", pComponentPrivate->lcml_nIpBuf);
150            G729ENC_DPRINT("app_nBuf=%ld\n", pComponentPrivate->app_nBuf);
151            if (pComponentPrivate->bIsThreadstop == 1)
152            {
153                pComponentPrivate->bIsStopping = 0;
154                pComponentPrivate->bIsThreadstop = 0;
155                pComponentPrivate->lcml_nOpBuf = 0;
156                pComponentPrivate->lcml_nIpBuf = 0;
157                pComponentPrivate->app_nBuf = 0;
158                pComponentPrivate->num_Op_Issued = 0;
159                pComponentPrivate->num_Sent_Ip_Buff = 0;
160                pComponentPrivate->num_Reclaimed_Op_Buff = 0;
161                pComponentPrivate->bIsEOFSent = 0;
162                if (pComponentPrivate->curState != OMX_StateIdle)
163                {
164                    G729ENC_DPRINT("pComponentPrivate->curState not OMX_StateIdle\n");
165                    goto EXIT;
166                }
167            }
168            G729ENC_DPRINT("Component Time Out !!!!! \n");
169        }
170        else if(-1 == status)
171        {
172            OMX_EPRINT("from CompThread in select\n");
173            pComponentPrivate->cbInfo.EventHandler(pHandle,
174                                                   pHandle->pApplicationPrivate,
175                                                   OMX_EventError,
176                                                   OMX_ErrorInsufficientResources,
177                                                   0,
178                                                   "");
179            eError = OMX_ErrorInsufficientResources;
180        }
181        else if ((FD_ISSET (pComponentPrivate->dataPipe[0], &rfds)))
182        {
183            G729ENC_DPRINT("DATA pipe is set in Component Thread\n");
184            ret = read(pComponentPrivate->dataPipe[0], &pBufHeader,
185                       sizeof(pBufHeader));
186            if (ret == -1)
187            {
188                OMX_EPRINT("while reading from the pipe\n");
189                goto EXIT;
190            }
191            eError = G729ENC_HandleDataBufFromApp(pBufHeader,pComponentPrivate);
192            if (eError != OMX_ErrorNone)
193            {
194                OMX_EPRINT("from G729ENC_HandleDataBufFromApp\n");
195                break;
196            }
197        }
198
199        else if(FD_ISSET (pComponentPrivate->cmdPipe[0], &rfds))
200        {
201            /* Do not accept any command when the component is stopping */
202            G729ENC_DPRINT("CMD pipe is set in Component Thread\n");
203            nRet = G729ENC_HandleCommand(pComponentPrivate);
204            if (nRet == G729ENC_EXIT_COMPONENT_THRD)
205            {
206                if(eError != OMX_ErrorNone)
207                {
208                    OMX_EPRINT("from G729ENC_CleanupInitParams\n");
209                    goto EXIT;
210                }
211                pComponentPrivate->curState = OMX_StateLoaded;
212#ifdef __PERF_INSTRUMENTATION__
213                PERF_Boundary(pComponentPrivate->pPERFcomp,
214                              PERF_BoundaryComplete | PERF_BoundaryCleanup);
215#endif
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 EXIT:
234#ifdef __PERF_INSTRUMENTATION__
235    PERF_Done(pComponentPrivate->pPERFcomp);
236#endif
237    G729ENC_DPRINT("Exiting. Returning = 0x%x\n", eError);
238    return (void*)eError;
239}
240