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/*-------------------------------------------------------------------*/
93void* 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
247EXIT:
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