Home | History | Annotate | Download | only in src
      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