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 /*-------------------------------------------------------------------*/ 97 void* 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 280 EXIT: 281 282 #ifdef __PERF_INSTRUMENTATION__ 283 PERF_Done(pComponentPrivate->pPERFcomp); 284 #endif 285 286 return (void*)OMX_ErrorNone; 287 } 288