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_AmrDec_ComponentThread.c
30*
31* This file implements OMX Component for PCM decoder that
32* is fully compliant with the OMX Audio specification .
33*
34* @path  $(CSLPATH)\
35*
36* @rev  0.1
37*/
38/* ----------------------------------------------------------------------------*/
39
40/* ------compilation control switches -------------------------*/
41/****************************************************************
42*  INCLUDE FILES
43****************************************************************/
44/* ----- system and platform files ----------------------------*/
45#ifdef UNDER_CE
46#include <windows.h>
47#else
48#include <wchar.h>
49#include <unistd.h>
50#include <dbapi.h>
51#include <string.h>
52#include <fcntl.h>
53#include <stdlib.h>
54#include <stdio.h>
55#include <errno.h>
56#include <sys/time.h>
57#include <signal.h>
58#include <sys/select.h>
59
60#endif
61#include "OMX_AmrDec_Utils.h"
62#include "OMX_AmrDecoder.h"
63#include "OMX_AmrDec_ComponentThread.h"
64
65void* NBAMRDEC_ComponentThread (void* pThreadData)
66{
67    OMX_S16 status;
68    struct timespec tv;
69    OMX_S16 fdmax;
70    fd_set rfds;
71    OMX_U32 nRet;
72    OMX_ERRORTYPE eError = OMX_ErrorNone;
73    AMRDEC_COMPONENT_PRIVATE* pComponentPrivate = (AMRDEC_COMPONENT_PRIVATE*)pThreadData;
74    OMX_COMPONENTTYPE *pHandle = pComponentPrivate->pHandle;
75    OMX_BUFFERHEADERTYPE *pBufHeader = NULL;
76	ssize_t ret;
77
78	OMX_PRINT1(pComponentPrivate->dbg, "%d :: OMX_AmrDec_ComponentThread.c :: \n",__LINE__);
79
80#ifdef __PERF_INSTRUMENTATION__
81    pComponentPrivate->pPERFcomp = PERF_Create(PERF_FOURCC('N', 'B', '_', 'D'),
82                                               PERF_ModuleComponent |
83                                               PERF_ModuleAudioDecode);
84#endif
85
86    fdmax = pComponentPrivate->cmdPipe[0];
87
88    if (pComponentPrivate->dataPipe[0] > fdmax) {
89        fdmax = pComponentPrivate->dataPipe[0];
90    }
91
92    while (1) {
93        FD_ZERO (&rfds);
94        FD_SET (pComponentPrivate->cmdPipe[0], &rfds);
95        FD_SET (pComponentPrivate->dataPipe[0], &rfds);
96
97        tv.tv_sec = 1;
98        tv.tv_nsec = 0;
99
100#ifndef UNDER_CE
101		sigset_t set;
102		sigemptyset (&set);
103		sigaddset (&set, SIGALRM);
104		status = pselect (fdmax+1, &rfds, NULL, NULL, &tv, &set);
105#else
106        status = select (fdmax+1, &rfds, NULL, NULL, &tv);
107#endif
108
109        if (pComponentPrivate->bIsStopping == 1) {
110            OMX_ERROR4(pComponentPrivate->dbg, ":: Comp Thrd Exiting here...\n");
111            goto EXIT;
112        }
113
114        if (0 == status) {
115
116            OMX_PRBUFFER2(pComponentPrivate->dbg, "%d :: OMX_AmrDec_ComponentThread.c :: bIsStopping = %ld\n",__LINE__,
117                                  pComponentPrivate->bIsStopping);
118
119            OMX_PRBUFFER2(pComponentPrivate->dbg, "%d :: OMX_AmrDec_ComponentThread.c :: lcml_nOpBuf = %ld\n",__LINE__,
120                                  pComponentPrivate->lcml_nOpBuf);
121
122            OMX_PRBUFFER2(pComponentPrivate->dbg, "%d :: OMX_AmrDec_ComponentThread.c :: lcml_nIpBuf = %ld\n",__LINE__,
123                                  pComponentPrivate->lcml_nIpBuf);
124            OMX_PRBUFFER2(pComponentPrivate->dbg, "%d :: OMX_AmrDec_ComponentThread.c :: app_nBuf = %ld\n",__LINE__,
125                                  pComponentPrivate->app_nBuf);
126
127            if (pComponentPrivate->bIsStopping == 1)  {
128               OMX_PRINT2(pComponentPrivate->dbg, "%d :: OMX_AmrDec_ComponentThread.c :: AmrComponentThread \n",__LINE__);
129
130                   OMX_PRINT2(pComponentPrivate->dbg, "%d :: OMX_AmrDec_ComponentThread.c :: AmrComponentThread \n",__LINE__);
131                if(eError != OMX_ErrorNone) {
132                   OMX_ERROR4(pComponentPrivate->dbg, "%d :: OMX_AmrDec_ComponentThread.c :: Error Occurred in Codec Stop..\n",__LINE__);
133                    break;
134                }
135                pComponentPrivate->bIsStopping = 0;
136                pComponentPrivate->lcml_nOpBuf = 0;
137                pComponentPrivate->lcml_nIpBuf = 0;
138                pComponentPrivate->app_nBuf = 0;
139                pComponentPrivate->num_Reclaimed_Op_Buff = 0;
140
141                   OMX_PRINT2(pComponentPrivate->dbg, "%d :: OMX_AmrDec_ComponentThread.c :: AmrComponentThread \n",__LINE__);
142                if (pComponentPrivate->curState != OMX_StateIdle) {
143                   OMX_ERROR4(pComponentPrivate->dbg, "%d :: OMX_AmrDec_ComponentThread.c :: AmrComponentThread \n",__LINE__);
144                    goto EXIT;
145                }
146            }
147             OMX_PRDSP1(pComponentPrivate->dbg, "%d :: OMX_AmrDec_ComponentThread.c :: Component Time Out !!!!!!!!!!!! \n",__LINE__);
148        } else if (-1 == status) {
149            OMX_ERROR4(pComponentPrivate->dbg, "%d :: OMX_AmrDec_ComponentThread.c :: Error in Select\n", __LINE__);
150            pComponentPrivate->cbInfo.EventHandler (pHandle,
151                                                    pHandle->pApplicationPrivate,
152                                                    OMX_EventError,
153                                                    OMX_ErrorInsufficientResources,
154                                                    OMX_TI_ErrorSevere,
155                                                    "Error from Component Thread in select");
156            eError = OMX_ErrorInsufficientResources;
157        }
158        else if (FD_ISSET (pComponentPrivate->dataPipe[0], &rfds)) {
159            OMX_PRCOMM2(pComponentPrivate->dbg, "%d :: OMX_AmrDec_ComponentThread.c :: DATA pipe is set in Component Thread\n",__LINE__);
160            ret = read(pComponentPrivate->dataPipe[0], &pBufHeader, sizeof(pBufHeader));
161            if (ret == -1) {
162                OMX_ERROR4(pComponentPrivate->dbg, "%d :: OMX_AmrDec_ComponentThread.c :: Error while reading from the pipe\n",__LINE__);
163            }
164            eError = NBAMRDECHandleDataBuf_FromApp (pBufHeader,pComponentPrivate);
165            if (eError != OMX_ErrorNone) {
166                OMX_ERROR4(pComponentPrivate->dbg, "%d :: OMX_AmrDec_ComponentThread.c :: Error From NBAMRDECHandleDataBuf_FromApp\n",__LINE__);
167                break;
168            }
169
170        }
171        else if (FD_ISSET (pComponentPrivate->cmdPipe[0], &rfds)) {
172            /* Do not accept any command when the component is stopping */
173            OMX_PRCOMM2(pComponentPrivate->dbg, "%d :: OMX_AmrDec_ComponentThread.c :: CMD pipe is set in Component Thread\n",__LINE__);
174            nRet = NBAMRDECHandleCommand (pComponentPrivate);
175            if (nRet == EXIT_COMPONENT_THRD) {
176                OMX_PRDSP2(pComponentPrivate->dbg, "%d :: OMX_AmrDec_ComponentThread.c :: Exiting from Component thread\n",__LINE__);
177
178                if(eError != OMX_ErrorNone) {
179                    OMX_ERROR4(pComponentPrivate->dbg, "%d :: OMX_AmrDec_ComponentThread.c :: Function Mp3Dec_FreeCompResources returned\
180                                                                error\n",__LINE__);
181                    goto EXIT;
182                }
183                OMX_PRINT2(pComponentPrivate->dbg, "%d :: OMX_AmrDec_ComponentThread.c :: ARM Side Resources Have Been Freed\n",__LINE__);
184
185                pComponentPrivate->curState = OMX_StateLoaded;
186#ifdef __PERF_INSTRUMENTATION__
187				PERF_Boundary(pComponentPrivate->pPERFcomp,PERF_BoundaryComplete | PERF_BoundaryCleanup);
188#endif
189			if (pComponentPrivate->bPreempted == 0) {
190                pComponentPrivate->cbInfo.EventHandler(
191                     pHandle, pHandle->pApplicationPrivate,
192                     OMX_EventCmdComplete,
193                     OMX_ErrorNone,pComponentPrivate->curState, NULL);
194            }
195            else {
196                pComponentPrivate->cbInfo.EventHandler(pHandle,
197                                                    pHandle->pApplicationPrivate,
198                                                    OMX_EventError,
199                                                    OMX_ErrorResourcesLost,
200													OMX_TI_ErrorMajor,
201													NULL);
202                pComponentPrivate->bPreempted = 0;
203                 }
204            }
205        }
206    }
207EXIT:
208
209#ifdef __PERF_INSTRUMENTATION__
210    PERF_Done(pComponentPrivate->pPERFcomp);
211#endif
212
213    OMX_PRINT1(pComponentPrivate->dbg, "%d :: OMX_AmrDec_ComponentThread.c :: Exiting ComponentThread\n",__LINE__);
214    return (void*)eError;
215}
216