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