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