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_JpegEnc_Thread.c
30 *
31 * This file implements OMX Component for JPEG encoder that
32 * is fully compliant with the OMX specification 1.5.
33 *
34 * @path  $(CSLPATH)\src
35 *
36 * @rev  0.1
37 */
38 /* -------------------------------------------------------------------------------- */
39 /* ================================================================================
40 *!
41 *! Revision History
42 *! ===================================
43 *!
44 *! 22-May-2006 mf: Revisions appear in reverse chronological order;
45 *! that is, newest first.  The date format is dd-Mon-yyyy.
46 * ================================================================================= */
47 
48 /****************************************************************
49 *  INCLUDE FILES
50 ****************************************************************/
51 
52 /* ----- System and Platform Files ----------------------------*/
53 #ifdef UNDER_CE
54 #include <windows.h>
55 #include <oaf_osal.h>
56 #include <omx_core.h>
57 #else
58 #include <unistd.h>
59 #include <sys/time.h>
60 #include <sys/types.h>
61 #include <sys/ioctl.h>
62 #include <sys/select.h>
63 #include <fcntl.h>
64 #include <errno.h>
65 #endif
66 
67 #include <dbapi.h>
68 #include <string.h>
69 #include <stdlib.h>
70 #include <stdio.h>
71 #include <signal.h>
72 
73 /*------- Program Header Files ----------------------------------------*/
74 
75 #include "OMX_JpegEnc_Utils.h"
76 
77 
78 #define OMX_MAX_TIMEOUTS 200
79 
80 /*-------- Function Implementations ---------------------------------*/
81 /*-------------------------------------------------------------------*/
82 /**
83   * OMX_JpegEnc_Thread()
84   *
85   * Called by Start_ComponentThread function.
86   *
87   * @param pThreadData
88   *
89   * @retval OMX_ErrorNone                  success, ready to roll
90   *         OMX_ErrorInsufficientResources if the malloc fails
91   **/
92 /*-------------------------------------------------------------------*/
OMX_JpegEnc_Thread(void * pThreadData)93 void* OMX_JpegEnc_Thread (void* pThreadData)
94 {
95     int status;
96     struct timeval tv;
97     int fdmax;
98     fd_set rfds;
99     OMX_ERRORTYPE eError = OMX_ErrorNone;
100     OMX_COMMANDTYPE eCmd;
101     OMX_U32 nParam1;
102     sigset_t set;
103 
104 
105     OMX_COMPONENTTYPE *pHandle = (OMX_COMPONENTTYPE *)pThreadData;
106     JPEGENC_COMPONENT_PRIVATE *pComponentPrivate = (JPEGENC_COMPONENT_PRIVATE *)pHandle->pComponentPrivate;
107 
108 #ifdef __PERF_INSTRUMENTATION__
109     pComponentPrivate->pPERFcomp = PERF_Create(PERF_FOURS("JPET"),
110                                                PERF_ModuleComponent |PERF_ModuleImageEncode);
111 #endif
112 
113     /**Looking for highest number of file descriptor for pipes
114        inorder to put in select loop */
115     fdmax = pComponentPrivate->nCmdPipe[0];
116 
117     if ( pComponentPrivate->free_outBuf_Q[0] > fdmax ) {
118         fdmax = pComponentPrivate->free_outBuf_Q[0];
119     }
120 
121 
122     if ( pComponentPrivate->filled_inpBuf_Q[0] > fdmax ) {
123         fdmax = pComponentPrivate->filled_inpBuf_Q[0];
124     }
125 
126     OMX_TRACE2(pComponentPrivate->dbg, "fd max is %d\n",fdmax);
127 
128     while ( 1 ) {
129         FD_ZERO (&rfds);
130         FD_SET (pComponentPrivate->nCmdPipe[0], &rfds);
131         if (pComponentPrivate->nCurState != OMX_StatePause) {
132             FD_SET (pComponentPrivate->free_outBuf_Q[0], &rfds);
133             FD_SET (pComponentPrivate->filled_inpBuf_Q[0], &rfds);
134         }
135 
136 
137         tv.tv_sec = 1;
138         tv.tv_usec = 0;
139 
140 	 sigemptyset(&set)	;
141 	 sigaddset(&set,SIGALRM);
142         status = pselect (fdmax+1, &rfds, NULL, NULL, NULL,&set);
143 
144         if ( 0 == status ) {
145             OMX_TRACE2(pComponentPrivate->dbg, "Component Thread Time Out!!!\n");
146         } else if ( -1 == status ) {
147             OMX_TRACE4(pComponentPrivate->dbg, "Error in Select\n");
148 
149             pComponentPrivate->cbInfo.EventHandler (pComponentPrivate->pHandle, pComponentPrivate->pHandle->pApplicationPrivate,
150                                                     OMX_EventError, OMX_ErrorInsufficientResources, OMX_TI_ErrorSevere,
151                                                     "Error from COmponent Thread in select");
152 	     eError = OMX_ErrorInsufficientResources;
153             break;
154         } else {
155             if ( (FD_ISSET (pComponentPrivate->filled_inpBuf_Q[0], &rfds))
156                  && (pComponentPrivate->nCurState != OMX_StatePause) ) {
157                 OMX_PRBUFFER2(pComponentPrivate->dbg, "filled_inpBuf_Q pipe is set\n");
158 
159                 eError = HandleJpegEncDataBuf_FromApp (pComponentPrivate);
160 
161                 if ( eError != OMX_ErrorNone ) {
162                     OMX_PRBUFFER4(pComponentPrivate->dbg, "Error while processing free queue buffers\n");
163                     pComponentPrivate->cbInfo.EventHandler (pComponentPrivate->pHandle, pComponentPrivate->pHandle->pApplicationPrivate,
164                                                             OMX_EventError, OMX_ErrorUndefined, OMX_TI_ErrorSevere,
165                                                             "1-Error from Component Thread while processing free Q\n");
166                 }
167             }
168 
169             if ( FD_ISSET (pComponentPrivate->free_outBuf_Q[0], &rfds) ) {
170                 OMX_PRBUFFER2(pComponentPrivate->dbg, "free_outBuf_Q has some buffers in Component Thread\n");
171                 eError = HandleJpegEncFreeOutputBufferFromApp(pComponentPrivate);
172                 if ( eError != OMX_ErrorNone ) {
173                     OMX_PRBUFFER4(pComponentPrivate->dbg, "Error while processing free Q Buffers\n");
174                     pComponentPrivate->cbInfo.EventHandler (pComponentPrivate->pHandle, pComponentPrivate->pHandle->pApplicationPrivate,
175                                                             OMX_EventError, OMX_ErrorUndefined, OMX_TI_ErrorSevere,
176                                                             "3-Error from Component Thread while processing free Q\n");
177                 }
178             }
179             if ( FD_ISSET (pComponentPrivate->nCmdPipe[0], &rfds) ) {
180                 /* Do not accept any command when the component is stopping */
181 		OMX_PRCOMM2(pComponentPrivate->dbg, "CMD pipe is set in Component Thread\n");
182 
183                 read (pComponentPrivate->nCmdPipe[0], &eCmd, sizeof (eCmd));
184                 read (pComponentPrivate->nCmdDataPipe[0], &nParam1, sizeof (nParam1));
185 
186 #ifdef __PERF_INSTRUMENTATION__
187                                 PERF_ReceivedCommand(pComponentPrivate->pPERFcomp,
188                                                      eCmd, nParam1,
189                                                      PERF_ModuleLLMM);
190 #endif
191 
192                 OMX_PRINT2(pComponentPrivate->dbg, "eCmd %d, nParam1 %d\n", (int)eCmd, (int)nParam1);
193                 if ( eCmd == OMX_CommandStateSet ) {
194                     OMX_PRINT2(pComponentPrivate->dbg, "processing OMX_CommandStateSet\n");
195                     if ( (int)nParam1 != -1 ){
196                         if(nParam1 == OMX_StateInvalid){
197                             pComponentPrivate->nToState = OMX_StateInvalid;
198                         }
199                         eError = HandleJpegEncCommand (pComponentPrivate, nParam1);
200                         if ( eError != OMX_ErrorNone ) {
201                             OMX_PRINT4(pComponentPrivate->dbg, "Error returned by HandleJpegEncCommand\n");
202                             pComponentPrivate->cbInfo.EventHandler (pComponentPrivate->pHandle, pComponentPrivate->pHandle->pApplicationPrivate,
203                                                                     OMX_EventError, OMX_ErrorHardware, OMX_TI_ErrorSevere,
204                                                                     "Error returned by HandleJpegEncCommand\n");
205                         }
206 
207                     }
208                     else{
209                         break;
210                     }
211                 }
212                 else if ( eCmd == OMX_CommandPortDisable ) {
213                     OMX_PRBUFFER2(pComponentPrivate->dbg, "Before Disable Port function Port %d\n",(int)nParam1);
214                     eError = JpegEncDisablePort(pComponentPrivate, nParam1);
215                     OMX_PRBUFFER2(pComponentPrivate->dbg, "After JPEG Encoder Sisable Port error = %d\n", eError);
216                     if (eError != OMX_ErrorNone ) {
217                         break;
218                         }
219                     }
220                 else if ( eCmd == OMX_CommandPortEnable ) {   /*TODO: Check errors*/
221                     eError = JpegEncEnablePort(pComponentPrivate, nParam1);
222                     if (eError != OMX_ErrorNone ) {
223                         break;
224                         }
225                     }
226 
227                 else if ( eCmd == OMX_CustomCommandStopThread ) {
228                     /*eError = 10;*/
229                     goto EXIT;
230                     }
231                 else if ( eCmd == OMX_CommandFlush ) {
232                       OMX_PRBUFFER2(pComponentPrivate->dbg, "eCmd =  OMX_CommandFlush\n");
233                       eError = HandleJpegEncCommandFlush (pComponentPrivate, nParam1);
234                       if (eError != OMX_ErrorNone) {
235                           break;
236                           }
237                     }
238                     if (pComponentPrivate->nCurState == OMX_StatePause)
239                         continue;
240             }
241 
242 
243         }
244     }
245     OMX_PRINT1(pComponentPrivate->dbg, "Component Thread Exit while loop\n");
246 
247 EXIT:
248 
249 #ifdef __PERF_INSTRUMENTATION__
250     PERF_Done(pComponentPrivate->pPERFcomp);
251 #endif
252 
253     OMX_PRINT1(pComponentPrivate->dbg, "Component Thread Exit while loop from EXIT label\n");
254     return(void*)eError; /*OMX_ErrorNone;*/
255 
256 }
257