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 <sys/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 /* ================================================================================ * */
AACDEC_ComponentThread(void * pThreadData)102 void* 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