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_VideoEnc_Thread.c 30 * 31 * This file implements OMX Component for MPEG-4 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 *! 02-Feb-2006 mf: Revisions appear in reverse chronological order; 45 *! that is, newest first. The date format is dd-Mon-yyyy. 46 * =========================================================================== */ 47 48 49 /* ------compilation control switches ----------------------------------------*/ 50 /****************************************************************************** 51 * INCLUDE FILES 52 *******************************************************************************/ 53 /* ----- system and platform files -------------------------------------------*/ 54 #ifdef UNDER_CE 55 #include <windows.h> 56 #include <oaf_osal.h> 57 #include <omx_core.h> 58 #else 59 #define _XOPEN_SOURCE 600 60 #include <wchar.h> 61 #include <unistd.h> 62 #include <sys/select.h> 63 #include <errno.h> 64 #include <fcntl.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 #include "OMX_VideoEnc_Utils.h" 75 76 /****************************************************************************** 77 * EXTERNAL REFERENCES NOTE : only use if not found in header file 78 *******************************************************************************/ 79 /*--------data declarations --------------------------------------------------*/ 80 81 /*--------function prototypes ------------------------------------------------*/ 82 83 /****************************************************************************** 84 * PUBLIC DECLARATIONS Defined here, used elsewhere 85 *******************************************************************************/ 86 /*--------data declarations --------------------------------------------------*/ 87 88 /*--------function prototypes ------------------------------------------------*/ 89 90 /****************************************************************************** 91 * PRIVATE DECLARATIONS Defined here, used only here 92 *******************************************************************************/ 93 /*--------data declarations --------------------------------------------------*/ 94 95 /*--------macro definitions --------------------------------------------------*/ 96 97 /*--------function prototypes ------------------------------------------------*/ 98 99 /*----------------------------------------------------------------------------*/ 100 /** 101 * OMX_VideoEnc_Thread() 102 * 103 * Called by VIDENC_Start_ComponentThread function. 104 * 105 * @param pThreadData 106 * 107 * @retval OMX_ErrorNone success, ready to roll 108 * OMX_ErrorInsufficientResources if the malloc fails 109 **/ 110 /*----------------------------------------------------------------------------*/ 111 void* OMX_VIDENC_Thread (void* pThreadData) 112 { 113 int status = -1; 114 int fdmax = -1; 115 fd_set rfds; 116 OMX_ERRORTYPE eError = OMX_ErrorNone; 117 OMX_COMMANDTYPE eCmd = -1; 118 OMX_U32 nParam1; 119 int nRet = -1; 120 OMX_PTR pCmdData = NULL; 121 VIDENC_COMPONENT_PRIVATE* pComponentPrivate = NULL; 122 LCML_DSP_INTERFACE* pLcmlHandle = NULL; 123 sigset_t set; 124 125 if (!pThreadData) 126 { 127 eError = OMX_ErrorBadParameter; 128 goto OMX_CONF_CMD_BAIL; 129 } 130 131 pComponentPrivate = (VIDENC_COMPONENT_PRIVATE*)pThreadData; 132 pLcmlHandle = (LCML_DSP_INTERFACE*)pComponentPrivate->pLCML; 133 134 #ifdef __PERF_INSTRUMENTATION__ 135 pComponentPrivate->pPERFcomp = PERF_Create(PERF_FOURCC('V', 'E', ' ', 'T'), 136 PERF_ModuleComponent | 137 PERF_ModuleVideoEncode); 138 #endif 139 140 /** Looking for highest number of file descriptor 141 for pipes inorder to put in select loop */ 142 143 fdmax = pComponentPrivate->nCmdPipe[0]; 144 145 if (pComponentPrivate->nFree_oPipe[0] > fdmax) 146 { 147 fdmax = pComponentPrivate->nFree_oPipe[0]; 148 } 149 150 if (pComponentPrivate->nFilled_iPipe[0] > fdmax) 151 { 152 fdmax = pComponentPrivate->nFilled_iPipe[0]; 153 } 154 155 while (1) 156 { 157 FD_ZERO (&rfds); 158 FD_SET (pComponentPrivate->nCmdPipe[0], &rfds); 159 FD_SET (pComponentPrivate->nFree_oPipe[0], &rfds); 160 FD_SET (pComponentPrivate->nFilled_iPipe[0], &rfds); 161 162 sigemptyset(&set); 163 sigaddset(&set,SIGALRM); 164 status = pselect(fdmax+1, &rfds, NULL, NULL, NULL,&set); 165 166 if (0 == status) 167 { 168 OMX_TRACE2(pComponentPrivate->dbg, "pselect() = 0\n"); 169 #ifndef UNDER_CE 170 sched_yield(); 171 #else 172 sched_yield(); 173 #endif 174 } 175 else if (-1 == status) 176 { 177 if (pComponentPrivate->eState != OMX_StateLoaded) 178 { 179 OMX_TRACE3(pComponentPrivate->dbg, "select() error.\n"); 180 OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, OMX_EventError, OMX_ErrorHardware, 0, NULL); 181 } 182 /*OMX_VIDENC_SET_ERROR_BAIL(eError, OMX_ErrorHardware, pComponentPrivate);*/ 183 eError = OMX_ErrorHardware; 184 OMX_ERROR5(pComponentPrivate->dbg, "*Fatal Error : %x\n", eError); 185 OMX_VIDENC_HandleError(pComponentPrivate, eError); 186 } 187 else 188 { 189 if (FD_ISSET(pComponentPrivate->nCmdPipe[0], &rfds)) 190 { 191 nRet = read(pComponentPrivate->nCmdPipe[0], 192 &eCmd, 193 sizeof(eCmd)); 194 if (nRet == -1) 195 { 196 OMX_PRCOMM4(pComponentPrivate->dbg, "Error while reading from cmdPipe\n"); 197 OMX_VIDENC_SET_ERROR_BAIL(eError, 198 OMX_ErrorHardware, 199 pComponentPrivate); 200 } 201 202 #ifdef __PERF_INSTRUMENTATION__ 203 PERF_ReceivedCommand(pComponentPrivate->pPERFcomp, 204 eCmd, 0, PERF_ModuleLLMM); 205 #endif 206 if (eCmd == (OMX_COMMANDTYPE)-1) 207 { 208 OMX_PRCOMM2(pComponentPrivate->dbg, "Received thread close command.\n"); 209 OMX_CONF_SET_ERROR_BAIL(eError, OMX_ErrorNone); 210 } 211 212 if (eCmd == OMX_CommandMarkBuffer) 213 { 214 nRet = read(pComponentPrivate->nCmdDataPipe[0], 215 &pCmdData, 216 sizeof(pCmdData)); 217 if (nRet == -1) 218 { 219 OMX_PRCOMM4(pComponentPrivate->dbg, "Error while reading from cmdDataPipe\n"); 220 OMX_VIDENC_SET_ERROR_BAIL(eError, 221 OMX_ErrorHardware, 222 pComponentPrivate); 223 } 224 } 225 else 226 { 227 nRet = read(pComponentPrivate->nCmdDataPipe[0], 228 &nParam1, 229 sizeof(nParam1)); 230 if (nRet == -1) 231 { 232 OMX_PRCOMM4(pComponentPrivate->dbg, "Error while reading from cmdDataPipe\n"); 233 OMX_VIDENC_SET_ERROR_BAIL(eError, 234 OMX_ErrorHardware, 235 pComponentPrivate); 236 } 237 } 238 239 #ifdef __PERF_INSTRUMENTATION__ 240 PERF_ReceivedCommand(pComponentPrivate->pPERFcomp, 241 eCmd, 242 (eCmd == OMX_CommandMarkBuffer) ? ((OMX_U32) pCmdData) : nParam1, 243 PERF_ModuleLLMM); 244 #endif 245 246 switch (eCmd) 247 { 248 case OMX_CommandStateSet : 249 OMX_PRSTATE2(pComponentPrivate->dbg, "Enters OMX_VIDENC_HandleCommandStateSet\n"); 250 eError = OMX_VIDENC_HandleCommandStateSet(pComponentPrivate, 251 nParam1); 252 OMX_VIDENC_BAIL_IF_ERROR(eError, pComponentPrivate); 253 OMX_PRSTATE2(pComponentPrivate->dbg, "Exits OMX_VIDENC_HandleCommandStateSet\n"); 254 break; 255 case OMX_CommandFlush : 256 OMX_PRSTATE2(pComponentPrivate->dbg, "Enters OMX_VIDENC_HandleCommandFlush\n"); 257 eError = OMX_VIDENC_HandleCommandFlush(pComponentPrivate, 258 nParam1, 259 OMX_FALSE); 260 OMX_VIDENC_BAIL_IF_ERROR(eError, pComponentPrivate); 261 OMX_PRSTATE2(pComponentPrivate->dbg, "Exits OMX_VIDENC_HandleCommandFlush\n"); 262 break; 263 case OMX_CommandPortDisable : 264 OMX_PRSTATE2(pComponentPrivate->dbg, "Enters OMX_VIDENC_HandleCommandDisablePort\n"); 265 eError = OMX_VIDENC_HandleCommandDisablePort(pComponentPrivate, 266 nParam1); 267 OMX_VIDENC_BAIL_IF_ERROR(eError, pComponentPrivate); 268 OMX_PRSTATE2(pComponentPrivate->dbg, "Exits OMX_VIDENC_HandleCommandDisablePort\n"); 269 break; 270 case OMX_CommandPortEnable : 271 OMX_PRSTATE2(pComponentPrivate->dbg, "Enters OMX_VIDENC_HandleCommandDisablePort\n"); 272 eError = OMX_VIDENC_HandleCommandEnablePort(pComponentPrivate, 273 nParam1); 274 OMX_VIDENC_BAIL_IF_ERROR(eError, pComponentPrivate); 275 OMX_PRSTATE2(pComponentPrivate->dbg, "Exits OMX_VIDENC_HandleCommandDisablePort\n"); 276 break; 277 case OMX_CommandMarkBuffer : 278 if (!pComponentPrivate->pMarkBuf) 279 { 280 pComponentPrivate->pMarkBuf = (OMX_MARKTYPE*)(pCmdData); 281 } 282 break; 283 default: 284 OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, 285 OMX_EventError, 286 OMX_ErrorUndefined, 287 0, 288 NULL); 289 } 290 } 291 292 if ((FD_ISSET(pComponentPrivate->nFilled_iPipe[0], &rfds)) && 293 (pComponentPrivate->eState != OMX_StatePause && 294 pComponentPrivate->eState != OMX_StateIdle && 295 pComponentPrivate->eState != OMX_StateLoaded)) 296 { 297 OMX_PRBUFFER1(pComponentPrivate->dbg, "Enters OMX_VIDENC_Process_FilledInBuf\n"); 298 eError = OMX_VIDENC_Process_FilledInBuf(pComponentPrivate); 299 if (eError != OMX_ErrorNone) 300 { 301 OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, 302 OMX_EventError, 303 OMX_ErrorUndefined, 304 0, 305 NULL); 306 OMX_VIDENC_BAIL_IF_ERROR(eError, pComponentPrivate); 307 } 308 OMX_PRBUFFER1(pComponentPrivate->dbg, "Exits OMX_VIDENC_Process_FilledInBuf\n"); 309 } 310 311 if (FD_ISSET(pComponentPrivate->nFree_oPipe[0], &rfds) && 312 (pComponentPrivate->eState!= OMX_StatePause && 313 pComponentPrivate->eState != OMX_StateIdle && 314 pComponentPrivate->eState != OMX_StateLoaded)) 315 { 316 OMX_PRBUFFER1(pComponentPrivate->dbg, "Enters OMX_VIDENC_Process_FreeOutBuf\n"); 317 eError = OMX_VIDENC_Process_FreeOutBuf(pComponentPrivate); 318 if (eError != OMX_ErrorNone) 319 { 320 OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, 321 OMX_EventError, 322 OMX_ErrorUndefined, 323 0, 324 NULL); 325 OMX_VIDENC_BAIL_IF_ERROR(eError, pComponentPrivate); 326 } 327 OMX_PRBUFFER1(pComponentPrivate->dbg, "Exits OMX_VIDENC_Process_FreeOutBuf\n"); 328 } 329 } 330 } 331 332 OMX_CONF_CMD_BAIL: 333 334 #ifdef __PERF_INSTRUMENTATION__ 335 if (pComponentPrivate) 336 PERF_Done(pComponentPrivate->pPERFcomp); 337 #endif 338 if (pComponentPrivate) 339 OMX_PRINT2(pComponentPrivate->dbg, "Component Thread Exits\n"); 340 return (void*)eError; 341 } 342