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_VPP_ComponentThread.c
30*
31* This file implements OMX Component for video post processing 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#ifdef UNDER_CE
55#include <windows.h>
56#include <oaf_osal.h>
57#include <omx_core.h>
58#include <stdlib.h>
59#else
60
61#define _XOPEN_SOURCE 600
62
63#include <unistd.h>
64#include <sys/time.h>
65#include <sys/types.h>
66#include <sys/ioctl.h>
67#include <sys/select.h>
68
69#include <fcntl.h>
70#include <errno.h>
71#endif
72#include <dbapi.h>
73#include <string.h>
74
75#include <stdio.h>
76
77#include "OMX_VPP.h"
78#include "OMX_VPP_Utils.h"
79#include "OMX_VPP_CompThread.h"
80#include <OMX_Component.h>
81#include <signal.h>
82
83/** Default timeout used to come out of blocking calls*/
84#define VPP_THREAD_TIMEOUT (100)
85
86
87/* -------------------------------------------------------------------*/
88/**
89  *  ComponentThread() thread polling for messages and data in pipe
90  *
91  * @param pThreadData
92  *
93  * @retval OMX_NoError              Success, ready to roll
94  *         OMX_Error_BadParameter   The input parameter pointer is null
95  **/
96/*-------------------------------------------------------------------*/
97void* VPP_ComponentThreadFunc (void* pThreadData)
98{
99    int status;
100    struct timeval tv;
101    int fdmax;
102    fd_set rfds;
103    OMX_ERRORTYPE eError = OMX_ErrorNone;
104    OMX_COMMANDTYPE eCmd = -1;
105    OMX_U32 nParam1;
106    int nRet = -1;
107    OMX_PTR pCmdData = NULL;
108    sigset_t set;
109
110
111
112    VPP_COMPONENT_PRIVATE* pComponentPrivate = (VPP_COMPONENT_PRIVATE*)pThreadData;
113    OMX_COMPONENTTYPE *pHandle = pComponentPrivate->pHandle;
114
115#ifdef __PERF_INSTRUMENTATION__
116    pComponentPrivate->pPERFcomp = PERF_Create(PERF_FOURCC('V','P','P','T'),
117                                            PERF_ModuleComponent |
118                                            PERF_ModuleVideoEncode | PERF_ModuleImageEncode |
119                                            PERF_ModuleVideoDecode | PERF_ModuleImageDecode);
120#endif
121
122    fdmax = pComponentPrivate->cmdPipe[0];
123
124    /** Looking for highest number of file descriptor
125        for pipes inorder to put in select loop */
126    if (pComponentPrivate->nFree_oPipe[0] > fdmax) {
127        fdmax = pComponentPrivate->nFree_oPipe[0];
128    }
129
130    if (pComponentPrivate->nFilled_iPipe[0] > fdmax) {
131        fdmax = pComponentPrivate->nFilled_iPipe[0];
132    }
133
134    while (1) {
135        FD_ZERO (&rfds);
136        FD_SET (pComponentPrivate->cmdPipe[0], &rfds);
137
138        if (pComponentPrivate->curState != OMX_StatePause) {
139        FD_SET (pComponentPrivate->nFree_oPipe[0], &rfds);
140        FD_SET (pComponentPrivate->nFilled_iPipe[0], &rfds);
141        }
142
143        tv.tv_sec  = 0;
144        tv.tv_usec = VPP_THREAD_TIMEOUT * 1000;
145
146	sigemptyset(&set);
147	sigaddset(&set,SIGALRM);
148
149        status = pselect (fdmax+1, &rfds, NULL, NULL, NULL, &set);
150
151        if (0 == status) {
152            /*VPP_DPRINT("\n\n\n%d ::!!!!!  Component Time Out !!!!!!!!!!!! \n",__LINE__);*/
153            if (pComponentPrivate->bIsStopping == 1) {
154                pComponentPrivate->bIsStopping = 0;
155                pComponentPrivate->bIsEOFSent  = 0;
156            }
157            continue;
158        }
159
160        if (-1 == status) {
161            VPP_DPRINT ("%d :: Error in Select\n", __LINE__);
162            pComponentPrivate->cbInfo.EventHandler (
163                                    pHandle,pHandle->pApplicationPrivate,
164                                    OMX_EventError,OMX_ErrorInsufficientResources,OMX_TI_ErrorSevere,
165                                    "Error from Component Thread in select");
166            goto EXIT;
167        }
168
169        if (FD_ISSET (pComponentPrivate->cmdPipe[0], &rfds)) {
170            nRet = read(pComponentPrivate->cmdPipe[0], &eCmd, sizeof(eCmd));
171            if (nRet == -1) {
172                VPP_DPRINT ("Error while writing to the free_oPipe\n");
173                eError = OMX_ErrorInsufficientResources;
174                goto EXIT;
175            }
176
177            if (eCmd == EXIT_COMPONENT_THRD)
178            {
179
180#ifdef __PERF_INSTRUMENTATION__
181                PERF_ReceivedCommand(pComponentPrivate->pPERFcomp,
182                                    eCmd, 0, PERF_ModuleLLMM);
183#endif
184
185                VPP_DPRINT ("VPP::%d: Exiting thread Cmd : \n",__LINE__);
186                break;
187            }
188
189
190            if (eCmd == OMX_CommandMarkBuffer) {
191                nRet = read(pComponentPrivate->nCmdDataPipe[0], &pCmdData, sizeof(pCmdData));
192                if (nRet == -1) {
193                    VPP_DPRINT ("Error while writing to the free_oPipe\n");
194                    eError = OMX_ErrorInsufficientResources;
195                    goto EXIT;
196                }
197            }
198            else {
199                nRet = read(pComponentPrivate->nCmdDataPipe[0], &nParam1, sizeof(nParam1));
200                if (nRet == -1) {
201                    VPP_DPRINT ("Error while writing to the free_oPipe\n");
202                    eError = OMX_ErrorInsufficientResources;
203                    goto EXIT;
204                }
205            }
206
207#ifdef __PERF_INSTRUMENTATION__
208            PERF_ReceivedCommand(pComponentPrivate->pPERFcomp,
209                                eCmd,
210                                (eCmd == OMX_CommandMarkBuffer) ? ((OMX_U32) pCmdData) : nParam1,
211                                PERF_ModuleLLMM);
212#endif
213
214            switch (eCmd)
215            {
216            case OMX_CommandPortDisable:
217                    VPP_DisablePort(pComponentPrivate, nParam1);
218                    break;
219
220            case OMX_CommandStateSet:
221                eError = VPP_HandleCommand(pComponentPrivate, nParam1);
222                if(eError != OMX_ErrorNone) {
223#ifdef RESOURCE_MANAGER_ENABLED
224                    pComponentPrivate->curState = OMX_StateInvalid;
225#endif
226                    pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle,
227                                        pComponentPrivate->pHandle->pApplicationPrivate,
228                                        OMX_EventError,
229                                        OMX_ErrorInsufficientResources,
230                                        OMX_TI_ErrorMajor,
231                                        "Error from Component Thread while processing Command Pipe.\n");
232                    goto EXIT;
233                }
234                VPP_DPRINT("return from StateSet %d\n", nParam1);
235                break;
236
237            case OMX_CommandPortEnable:
238                VPP_EnablePort(pComponentPrivate, nParam1);
239                break;
240
241            case OMX_CommandMarkBuffer:
242                /* OMX_CommandMarkBuffer is handled directly on VPP_SendCommand() function*/
243                break;
244
245            case OMX_CommandFlush:
246                VPP_HandleCommandFlush(pComponentPrivate, nParam1, OMX_TRUE);
247                break;
248            case OMX_CommandMax:
249                break;
250            }
251            continue;
252        }
253
254        /*Filled Input Buffer from Application to component*/
255        if ((FD_ISSET(pComponentPrivate->nFilled_iPipe[0], &rfds))) {
256            eError = VPP_Process_FilledInBuf(pComponentPrivate);
257            if (eError != OMX_ErrorNone) {
258                pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle,
259                                    pComponentPrivate->pHandle->pApplicationPrivate,
260                                    OMX_EventError,
261                                    OMX_ErrorUndefined,
262                                    OMX_TI_ErrorSevere,
263                                    NULL);
264            }
265        }
266        /*Free output buffers from Application to component*/
267        if (FD_ISSET(pComponentPrivate->nFree_oPipe[0], &rfds)) {
268            eError = VPP_Process_FreeOutBuf(pComponentPrivate);
269            if (eError != OMX_ErrorNone) {
270                pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle,
271                                    pComponentPrivate->pHandle->pApplicationPrivate,
272                                    OMX_EventError,
273                                    OMX_ErrorUndefined,
274                                    OMX_TI_ErrorSevere,
275                                    NULL);
276            }
277        }
278    }
279
280EXIT:
281
282#ifdef __PERF_INSTRUMENTATION__
283    PERF_Done(pComponentPrivate->pPERFcomp);
284#endif
285
286    return (void*)OMX_ErrorNone;
287}
288