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/* ================================================================================ */
77void* 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__
95OMX_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    }
221EXIT:
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