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/**
30* @file OMX_JpegDec_Thread.c
31*
32* This file implements OMX Component for JPEG decoder.This contains
33* functionality for the  pipe - Buffer manager thread.
34*
35* @patth $(CSLPATH)\jpeg_dec\src\OMX_JpegDec_Thread.c
36*
37* @rev 0.2
38*/
39
40#ifdef UNDER_CE
41    #include <windows.h>
42    #include <oaf_osal.h>
43#else
44    #include <wchar.h>
45    #include <unistd.h>
46    #include <sys/time.h>
47    #include <sys/types.h>
48    #include <sys/ioctl.h>
49    #include <sys/select.h>
50    #include <errno.h>
51    #include <fcntl.h>
52    #include <signal.h>
53#endif
54
55#include <dbapi.h>
56#include <string.h>
57#include <stdlib.h>
58#include <stdio.h>
59
60#include "OMX_JpegDec_Utils.h"
61
62/*------------------------- Function Implementation ------------------*/
63
64
65/* ========================================================================== */
66/**
67 * @fn OMX_JpegDec_Thread - Implements the JPEG decoder OMX component thread
68 * @param pThreadData - components private structure
69 * @return: void*
70 *          OMX_ErrorNone on all count
71 */
72/* ========================================================================== */
73void* OMX_JpegDec_Thread (void* pThreadData)
74{
75    struct timespec tv;
76    OMX_ERRORTYPE eError = OMX_ErrorNone;
77    OMX_COMMANDTYPE eCmd;
78    OMX_U32 nParam1;
79    OMX_COMPONENTTYPE *pHandle = (OMX_COMPONENTTYPE *)pThreadData;
80    int nStatus;
81    int nFdmax;
82    fd_set rfds;
83    JPEGDEC_COMPONENT_PRIVATE *pComponentPrivate = (JPEGDEC_COMPONENT_PRIVATE *)pHandle->pComponentPrivate;
84    OMX_U32 error = 0;
85    sigset_t set;
86
87#ifdef __PERF_INSTRUMENTATION__
88    pComponentPrivate->pPERFcomp = PERF_Create(PERF_FOURS("JPDT"),
89					    PERF_ModuleComponent | PERF_ModuleImageDecode);
90#endif
91
92    /**Looking for highest number of file descriptor for pipes
93       inorder to put in select loop */
94
95    nFdmax = pComponentPrivate->nCmdPipe[0];
96
97    if (pComponentPrivate->nFree_outBuf_Q[0] > nFdmax) {
98        nFdmax = pComponentPrivate->nFree_outBuf_Q[0];
99    }
100
101    if (pComponentPrivate->nFilled_inpBuf_Q[0] > nFdmax) {
102        nFdmax = pComponentPrivate->nFilled_inpBuf_Q[0];
103    }
104
105    OMX_PRINT1(pComponentPrivate->dbg, "fd max is %d\n", nFdmax);
106
107    while (1)
108    {
109        FD_ZERO (&rfds);
110        FD_SET (pComponentPrivate->nCmdPipe[0], &rfds);
111        if (pComponentPrivate->nCurState != OMX_StatePause) {
112          FD_SET (pComponentPrivate->nFree_outBuf_Q[0], &rfds);
113          FD_SET (pComponentPrivate->nFilled_inpBuf_Q[0], &rfds);
114        }
115
116        tv.tv_sec = 1;
117
118        tv.tv_nsec = 0;
119
120        sigemptyset(&set);
121        sigaddset(&set, SIGALRM);
122        nStatus = pselect (nFdmax+1, &rfds, NULL, NULL, NULL,&set);
123
124        if (-1 == nStatus) {
125	    OMX_TRACE5(pComponentPrivate->dbg, "Error in Select\n");
126            pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle,
127                                                   pComponentPrivate->pHandle->pApplicationPrivate,
128                                                   OMX_EventError,
129                                                   OMX_ErrorInsufficientResources,
130                                                   OMX_TI_ErrorSevere,
131                                                   "Error from COmponent Thread in select");
132	     eError = OMX_ErrorInsufficientResources;
133        }
134        else {
135            if ((FD_ISSET(pComponentPrivate->nCmdPipe[0], &rfds)) ||
136                (FD_ISSET(pComponentPrivate->nCmdDataPipe[0], &rfds))) {
137                /* Do not accept any command when the component is stopping */
138		OMX_PRCOMM2(pComponentPrivate->dbg, "CMD pipe is set in Component Thread\n");
139
140                read (pComponentPrivate->nCmdPipe[0], &eCmd, sizeof (eCmd));   /*Manage error from any read and write*/
141                OMX_PRCOMM1(pComponentPrivate->dbg, "read ecmd %d\n", eCmd);
142                read (pComponentPrivate->nCmdDataPipe[0], &nParam1, sizeof (nParam1));
143                OMX_PRCOMM1(pComponentPrivate->dbg, "read nParam1 %lu\n", nParam1);
144
145#ifdef __PERF_INSTRUMENTATION__
146                PERF_ReceivedCommand(pComponentPrivate->pPERFcomp,
147                                     eCmd, nParam1, PERF_ModuleLLMM);
148
149#endif
150
151                if (eCmd == OMX_CommandStateSet) {
152		    if ((int)nParam1 != -1) {
153			    OMX_PRINT2(pComponentPrivate->dbg, "calling handlecommand  from JPEGDEC (%lu)\n", nParam1);
154                        if(nParam1 == OMX_StateInvalid){
155                            pComponentPrivate->nToState = OMX_StateInvalid;
156                        }
157                        error =  HandleCommandJpegDec (pComponentPrivate, nParam1);
158                        OMX_PRINT2(pComponentPrivate->dbg, "after called handlecommand  from JPEGDEC (%lu)\n", error);
159                        if (error != OMX_ErrorNone) {
160                            pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle,
161                                                                   pComponentPrivate->pHandle->pApplicationPrivate,
162                                                                   OMX_EventError,
163                                                                   error,
164                                                                   OMX_TI_ErrorSevere,
165                                                                   NULL);
166                        }
167                    }
168                    else
169                        break;
170                }
171                else if (eCmd == OMX_CommandPortDisable) {
172		    OMX_PRINT2(pComponentPrivate->dbg, "PORT DISABLE\n");
173                    error = DisablePortJpegDec(pComponentPrivate, nParam1);
174                    if(error != OMX_ErrorNone){
175                        pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle,
176                                       pComponentPrivate->pHandle->pApplicationPrivate,
177                                       OMX_EventError,
178                                       error,
179                                       OMX_TI_ErrorSevere,
180                                       NULL);
181                    }
182                }
183                else if (eCmd == OMX_CommandPortEnable) {
184		    OMX_PRINT2(pComponentPrivate->dbg, "PORT Enable\n");
185                    error = EnablePortJpegDec(pComponentPrivate, nParam1);
186                    if(error != OMX_ErrorNone){
187                        pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle,
188                                       pComponentPrivate->pHandle->pApplicationPrivate,
189                                       OMX_EventError,
190                                       error,
191                                       OMX_TI_ErrorSevere,
192                                       NULL);
193                    }
194                }
195                else if (eCmd == OMX_CustomCommandStopThread) {
196		    OMX_PRINT2(pComponentPrivate->dbg, "cmd nStop\n");
197                    goto EXIT;
198                }
199                else if (eCmd == OMX_CommandMarkBuffer) {
200		    OMX_PRBUFFER2(pComponentPrivate->dbg, "Command OMX_CommandMarkBuffer received \n");
201                    if (!pComponentPrivate->pMarkBuf) {
202			OMX_PRBUFFER2(pComponentPrivate->dbg, "Command OMX_CommandMarkBuffer received \n");
203                        /* TODO Need to handle multiple marks */
204                        pComponentPrivate->pMarkBuf = (OMX_MARKTYPE *)(nParam1);
205                    }
206                }
207                else if (eCmd == OMX_CommandFlush) {
208		    OMX_PRBUFFER2(pComponentPrivate->dbg, "eCmd =  OMX_CommandFlush\n");
209                    error = HandleCommandFlush (pComponentPrivate, nParam1);
210                    if(error != OMX_ErrorNone){
211                        pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle,
212                                       pComponentPrivate->pHandle->pApplicationPrivate,
213                                       OMX_EventError,
214                                       error,
215                                       OMX_TI_ErrorSevere,
216                                       NULL);
217                    }
218                }
219                continue;
220            }
221
222            if ((FD_ISSET(pComponentPrivate->nFilled_inpBuf_Q[0], &rfds)) &&
223                (pComponentPrivate->nCurState != OMX_StatePause)) {
224
225                eError = HandleDataBuf_FromAppJpegDec (pComponentPrivate);
226                if (eError != OMX_ErrorNone) {
227		    OMX_PRBUFFER4(pComponentPrivate->dbg, "Error while processing free Q Buffers\n");
228                    pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle,
229                                                           pComponentPrivate->pHandle->pApplicationPrivate,
230                                                           OMX_EventError,
231                                                           eError,
232                                                           OMX_TI_ErrorSevere,
233                                                           "Error from COmponent Thread while processing filled inp Q");
234                }
235            }
236
237            if (FD_ISSET (pComponentPrivate->nFree_outBuf_Q[0], &rfds)) {
238
239	        OMX_PRBUFFER2(pComponentPrivate->dbg, "nFree_outBuf_Q has some buffers in Component Thread\n");
240                eError = HandleFreeOutputBufferFromAppJpegDec(pComponentPrivate);
241                if (eError != OMX_ErrorNone) {
242		    OMX_PRBUFFER4(pComponentPrivate->dbg, "Error while processing free Q Buffers\n");
243                    pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle,
244                                                           pComponentPrivate->pHandle->pApplicationPrivate,
245                                                           OMX_EventError,
246                                                           eError,
247                                                           OMX_TI_ErrorSevere,
248                                                           "Error from COmponent Thread while processing free out Q");
249                }
250            }
251        }
252    }
253EXIT:
254#ifdef __PERF_INSTRUMENTATION__
255    PERF_Done(pComponentPrivate->pPERFcomp);
256#endif
257    return (void *)eError;
258
259}
260
261
262