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_AacDec_CompThread.c
30*
31* This file implements OMX Component for AAC Decoder that
32* is fully compliant with the OMX Audio specification 1.0.
33*
34* @path  $(CSLPATH)\
35*
36* @rev  1.0
37*/
38/* ----------------------------------------------------------------------------
39*!
40*! Revision History
41*! ===================================
42*! 13-Dec-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
54
55
56#ifdef UNDER_CE
57#include <windows.h>
58#include <oaf_osal.h>
59#include <omx_core.h>
60#include <stdlib.h>
61#else
62#include <wchar.h>
63#include <unistd.h>
64#include <sys/types.h>
65#include <sys/wait.h>
66#include <sys/types.h>
67#include <sys/stat.h>
68#include <dlfcn.h>
69#include <sys/select.h>
70#include <memory.h>
71#include <fcntl.h>
72#include <signal.h>
73#endif
74
75#include <dbapi.h>
76#include <string.h>
77#include <stdio.h>
78
79#ifdef ANDROID
80#include <utils/threads.h>
81#include <linux/prctl.h>
82#endif
83
84#include "OMX_AacDec_Utils.h"
85
86/* ================================================================================= * */
87/**
88* @fn AACDEC_ComponentThread() This is component thread that keeps listening for
89* commands or event/messages/buffers from application or from LCML.
90*
91* @param pThreadData This is thread argument.
92*
93* @pre          None
94*
95* @post         None
96*
97*  @return      OMX_ErrorNone = Always
98*
99*  @see         None
100*/
101/* ================================================================================ * */
102void* AACDEC_ComponentThread (void* pThreadData)
103{
104    int status;
105    struct timespec tv;
106    int fdmax;
107    fd_set rfds;
108    OMX_U32 nRet;
109    OMX_ERRORTYPE eError = OMX_ErrorNone;
110    AACDEC_COMPONENT_PRIVATE* pComponentPrivate = (AACDEC_COMPONENT_PRIVATE*)pThreadData;
111    OMX_COMPONENTTYPE *pHandle = pComponentPrivate->pHandle;
112
113#ifdef ANDROID
114    setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_AUDIO);
115    prctl(PR_SET_NAME, (unsigned long)"AACComponent", 0, 0, 0);
116#endif
117
118    OMX_PRINT1(pComponentPrivate->dbg, "%d :: Entering ComponentThread \n",__LINE__);
119#ifdef __PERF_INSTRUMENTATION__
120    pComponentPrivate->pPERFcomp = PERF_Create(PERF_FOURCC('A', 'C', 'D', '_'),
121                                               PERF_ModuleComponent |
122                                               PERF_ModuleAudioDecode);
123#endif
124    fdmax = pComponentPrivate->cmdPipe[0];
125
126    if (pComponentPrivate->dataPipe[0] > fdmax) {
127        fdmax = pComponentPrivate->dataPipe[0];
128    }
129
130
131    while (1) {
132        FD_ZERO (&rfds);
133        FD_SET (pComponentPrivate->cmdPipe[0], &rfds);
134        FD_SET (pComponentPrivate->dataPipe[0], &rfds);
135
136        tv.tv_sec = 1;
137        tv.tv_nsec = 0;
138
139#ifndef UNDER_CE
140        sigset_t set;
141        sigemptyset (&set);
142        sigaddset (&set, SIGALRM);
143        status = pselect (fdmax+1, &rfds, NULL, NULL, &tv, &set);
144#else
145        status = select (fdmax+1, &rfds, NULL, NULL, &tv);
146#endif
147
148
149        if (pComponentPrivate->bExitCompThrd == 1) {
150            OMX_ERROR4(pComponentPrivate->dbg, "%d :: Comp Thrd Exiting here...\n",__LINE__);
151            goto EXIT;
152        }
153
154
155
156        if (0 == status) {
157            OMX_ERROR2(pComponentPrivate->dbg, "\n\n\n!!!!!  Component Time Out !!!!!!!!!!!! \n");
158        }
159        else if (-1 == status) {
160            OMX_ERROR4(pComponentPrivate->dbg, "%d :: Error in Select\n", __LINE__);
161            pComponentPrivate->cbInfo.EventHandler (pHandle,
162                                                    pHandle->pApplicationPrivate,
163                                                    OMX_EventError,
164                                                    OMX_ErrorInsufficientResources,
165                                                    OMX_TI_ErrorSevere,
166                                                    "Error from COmponent Thread in select");
167            eError = OMX_ErrorInsufficientResources;
168        }
169        else if (FD_ISSET (pComponentPrivate->cmdPipe[0], &rfds)) {
170            OMX_PRCOMM2(pComponentPrivate->dbg, "%d :: CMD pipe is set in Component Thread\n",__LINE__);
171            nRet = AACDEC_HandleCommand (pComponentPrivate);
172            if (nRet == EXIT_COMPONENT_THRD) {
173                OMX_PRINT1(pComponentPrivate->dbg, "Exiting from Component thread\n");
174                AACDEC_CleanupInitParams(pHandle);
175                OMX_PRSTATE2(pComponentPrivate->dbg, "******************* Component State Set to Loaded\n\n");
176
177                pComponentPrivate->curState = OMX_StateLoaded;
178#ifdef __PERF_INSTRUMENTATION__
179                PERF_Boundary(pComponentPrivate->pPERFcomp,PERF_BoundaryComplete | PERF_BoundaryCleanup);
180#endif
181                if(pComponentPrivate->bPreempted==0){
182                    pComponentPrivate->cbInfo.EventHandler(
183                                                           pHandle, pHandle->pApplicationPrivate,
184                                                           OMX_EventCmdComplete,
185                                                           OMX_ErrorNone,pComponentPrivate->curState, NULL);
186                } else {
187                    OMX_ERROR4(pComponentPrivate->dbg, "OMX_EventError:: OMX_ErrorPortUnpopulated at CompThread line %d\n", __LINE__);
188                    pComponentPrivate->cbInfo.EventHandler(pHandle,
189                                                           pHandle->pApplicationPrivate,
190                                                           OMX_EventError,
191                                                           OMX_ErrorResourcesLost,
192                                                           OMX_TI_ErrorMajor,
193                                                           NULL);
194                    pComponentPrivate->bPreempted = 0;
195                }
196            }
197        }
198        else if ((FD_ISSET (pComponentPrivate->dataPipe[0], &rfds))) {
199            int ret;
200            OMX_BUFFERHEADERTYPE *pBufHeader = NULL;
201
202            OMX_PRCOMM2(pComponentPrivate->dbg, "%d :: DATA pipe is set in Component Thread\n",__LINE__);
203            ret = read(pComponentPrivate->dataPipe[0], &pBufHeader, sizeof(pBufHeader));
204            if (ret == -1) {
205                OMX_ERROR2(pComponentPrivate->dbg, "%d :: Error while reading from the pipe\n",__LINE__);
206            }
207
208            eError = AACDEC_HandleDataBuf_FromApp (pBufHeader,pComponentPrivate);
209            if (eError != OMX_ErrorNone) {
210                OMX_ERROR2(pComponentPrivate->dbg, "%d :: Error From HandleDataBuf_FromApp\n",__LINE__);
211                break;
212            }
213        }
214    }
215 EXIT:
216
217    pComponentPrivate->bCompThreadStarted = 0;
218
219#ifdef __PERF_INSTRUMENTATION__
220    PERF_Done(pComponentPrivate->pPERFcomp);
221#endif
222    OMX_PRINT1(pComponentPrivate->dbg, "%d :: Exiting ComponentThread \n",__LINE__);
223    return (void*)eError;
224}
225