Home | History | Annotate | Download | only in test
      1 /*--------------------------------------------------------------------------
      2 Copyright (c) 2010, Code Aurora Forum. All rights reserved.
      3 
      4 Redistribution and use in source and binary forms, with or without
      5 modification, are permitted provided that the following conditions are met:
      6     * Redistributions of source code must retain the above copyright
      7       notice, this list of conditions and the following disclaimer.
      8     * Redistributions in binary form must reproduce the above copyright
      9       notice, this list of conditions and the following disclaimer in the
     10       documentation and/or other materials provided with the distribution.
     11     * Neither the name of Code Aurora nor
     12       the names of its contributors may be used to endorse or promote
     13       products derived from this software without specific prior written
     14       permission.
     15 
     16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     18 IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     19 NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     20 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     21 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     22 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     23 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     24 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     25 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
     26 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 --------------------------------------------------------------------------*/
     28 /*============================================================================
     29                     V E N C _ T E S T. C P P
     30 
     31 DESCRIPTION
     32 
     33  This is the OMX test app .
     34 
     35 REFERENCES
     36 
     37 ============================================================================*/
     38 
     39 //usage
     40 // FILE QVGA MP4 24 384000 100 enc_qvga.yuv QVGA_24.m4v
     41 // FILE QCIF MP4 15 96000 0 foreman.qcif.yuv output_qcif.m4v
     42 // FILE VGA MP4 24 1200000 218 enc_vga.yuv vga_output.m4v
     43 #include <sys/types.h>
     44 #include <sys/stat.h>
     45 #include <string.h>
     46 #include <unistd.h>
     47 #include <stdlib.h>
     48 #include <stdio.h>
     49 #include <pthread.h>
     50 #include <fcntl.h>
     51 #include <sys/mman.h>
     52 //#include <sys/time.h>
     53 #include <time.h>
     54 #include <sys/ioctl.h>
     55 #include <string.h>
     56 //#include <sys/stat.h>
     57 #include "OMX_QCOMExtns.h"
     58 #include "OMX_Core.h"
     59 
     60 
     61 #define QCOM_EXT 1
     62 
     63 #include "OMX_Core.h"
     64 #include "OMX_Video.h"
     65 #include "OMX_Component.h"
     66 #include "camera_test.h"
     67 #include "fb_test.h"
     68 #include "venc_util.h"
     69 
     70 //////////////////////////
     71 // MACROS
     72 //////////////////////////
     73 
     74 #define CHK(result) if (result != OMX_ErrorNone) { E("*************** error *************"); exit(0); }
     75 #define TEST_LOG
     76 #ifdef VENC_SYSLOG
     77 #include "cutils/log.h"
     78 /// Debug message macro
     79 #define D(fmt, ...) ALOGE("venc_test Debug %s::%d "fmt"\n",              \
     80                          __FUNCTION__, __LINE__,                        \
     81                          ## __VA_ARGS__)
     82 
     83 /// Error message macro
     84 #define E(fmt, ...) ALOGE("venc_test Error %s::%d "fmt"\n",            \
     85                          __FUNCTION__, __LINE__,                      \
     86                          ## __VA_ARGS__)
     87 
     88 #else
     89      #ifdef TEST_LOG
     90        #define D(fmt, ...) fprintf(stderr, "venc_test Debug %s::%d "fmt"\n",   \
     91                             __FUNCTION__, __LINE__,                     \
     92                             ## __VA_ARGS__)
     93 
     94      /// Error message macro
     95       #define E(fmt, ...) fprintf(stderr, "venc_test Error %s::%d "fmt"\n", \
     96                             __FUNCTION__, __LINE__,                   \
     97                             ## __VA_ARGS__)
     98      #else
     99       #define D(fmt, ...)
    100       #define E(fmt, ...)
    101          #endif
    102 
    103 #endif
    104 
    105 //////////////////////////
    106 // CONSTANTS
    107 //////////////////////////
    108 static const int MAX_MSG = 100;
    109 //#warning do not hardcode these use port definition
    110 static const int PORT_INDEX_IN = 0;
    111 static const int PORT_INDEX_OUT = 1;
    112 
    113 static const int NUM_IN_BUFFERS = 10;
    114 static const int NUM_OUT_BUFFERS = 10;
    115 
    116 unsigned int num_in_buffers = 0;
    117 unsigned int num_out_buffers = 0;
    118 
    119 //////////////////////////
    120 /* MPEG4 profile and level table*/
    121 static const unsigned int mpeg4_profile_level_table[][5]=
    122 {
    123     /*max mb per frame, max mb per sec, max bitrate, level, profile*/
    124     {99,1485,64000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileSimple},
    125     {99,1485,128000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileSimple},
    126     {396,5940,128000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileSimple},
    127     {396,11880,384000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileSimple},
    128     {1200,36000,4000000,OMX_VIDEO_MPEG4Level4a,OMX_VIDEO_MPEG4ProfileSimple},
    129     {1620,40500,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple},
    130     {3600,108000,14000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple},
    131 
    132     {99,2970,128000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
    133     {99,2970,128000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
    134     {396,5940,384000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
    135     {396,11880,768000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
    136     {792,23760,3000000,OMX_VIDEO_MPEG4Level4,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
    137     {1620,48600,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
    138     {3600,108000,14000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
    139     {0     ,0       ,0                 ,0     ,0                  }
    140 };
    141 
    142 /* H264 profile and level table*/
    143 static const unsigned int h264_profile_level_table[][5]=
    144 {
    145      /*max mb per frame, max mb per sec, max bitrate, level, profile*/
    146     {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileBaseline},
    147     {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileBaseline},
    148     {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileBaseline},
    149     {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileBaseline},
    150     {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileBaseline},
    151     {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileBaseline},
    152     {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileBaseline},
    153     {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileBaseline},
    154     {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileBaseline},
    155     {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileBaseline},
    156 
    157     {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileHigh},
    158     {99,1485,160000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileHigh},
    159     {396,3000,240000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileHigh},
    160     {396,6000,480000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileHigh},
    161     {396,11880,960000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileHigh},
    162     {396,11880,2500000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileHigh},
    163     {792,19800,5000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileHigh},
    164     {1620,20250,5000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileHigh},
    165     {1620,40500,12500000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileHigh},
    166     {3600,108000,17500000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileHigh},
    167     {0     ,0       ,0                 ,0                    }
    168 };
    169 
    170 /* H263 profile and level table*/
    171 static const unsigned int h263_profile_level_table[][5]=
    172 {
    173     /*max mb per frame, max mb per sec, max bitrate, level, profile*/
    174     {99,1485,64000,OMX_VIDEO_H263Level10,OMX_VIDEO_H263ProfileBaseline},
    175     {396,5940,128000,OMX_VIDEO_H263Level20,OMX_VIDEO_H263ProfileBaseline},
    176     {396,11880,384000,OMX_VIDEO_H263Level30,OMX_VIDEO_H263ProfileBaseline},
    177     {396,11880,2048000,OMX_VIDEO_H263Level40,OMX_VIDEO_H263ProfileBaseline},
    178     {99,1485,128000,OMX_VIDEO_H263Level45,OMX_VIDEO_H263ProfileBaseline},
    179     {396,19800,4096000,OMX_VIDEO_H263Level50,OMX_VIDEO_H263ProfileBaseline},
    180     {810,40500,8192000,OMX_VIDEO_H263Level60,OMX_VIDEO_H263ProfileBaseline},
    181     {1620,81000,16384000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline},
    182     {0    , 0      , 0               , 0                       }
    183 };
    184 
    185 //////////////////////////
    186 // TYPES
    187 //////////////////////////
    188 struct ProfileType
    189 {
    190    OMX_VIDEO_CODINGTYPE eCodec;
    191    OMX_VIDEO_MPEG4LEVELTYPE eLevel;
    192    OMX_VIDEO_CONTROLRATETYPE eControlRate;
    193    OMX_VIDEO_AVCSLICEMODETYPE eSliceMode;
    194    OMX_U32 nFrameWidth;
    195    OMX_U32 nFrameHeight;
    196    OMX_U32 nFrameBytes;
    197    OMX_U32 nBitrate;
    198    OMX_U32 nFramerate;
    199    char* cInFileName;
    200    char* cOutFileName;
    201 };
    202 
    203 enum MsgId
    204 {
    205    MSG_ID_OUTPUT_FRAME_DONE,
    206    MSG_ID_INPUT_FRAME_DONE,
    207    MSG_ID_MAX
    208 };
    209 union MsgData
    210 {
    211    struct
    212    {
    213       OMX_BUFFERHEADERTYPE* pBuffer;
    214    } sBitstreamData;
    215 };
    216 struct Msg
    217 {
    218    MsgId id;
    219    MsgData data;
    220 };
    221 struct MsgQ
    222 {
    223    Msg q[MAX_MSG];
    224    int head;
    225    int size;
    226 };
    227 
    228 enum Mode
    229 {
    230    MODE_PREVIEW,
    231    MODE_DISPLAY,
    232    MODE_PROFILE,
    233    MODE_FILE_ENCODE,
    234    MODE_LIVE_ENCODE
    235 };
    236 
    237 //////////////////////////
    238 // MODULE VARS
    239 //////////////////////////
    240 static pthread_mutex_t m_mutex;
    241 static pthread_cond_t m_signal;
    242 static MsgQ m_sMsgQ;
    243 
    244 //#warning determine how many buffers we really have
    245 OMX_STATETYPE m_eState = OMX_StateInvalid;
    246 OMX_COMPONENTTYPE m_sComponent;
    247 OMX_HANDLETYPE m_hHandle = NULL;
    248 OMX_BUFFERHEADERTYPE* m_pOutBuffers[NUM_OUT_BUFFERS] = {NULL};
    249 OMX_BUFFERHEADERTYPE* m_pInBuffers[NUM_IN_BUFFERS] = {NULL};
    250 OMX_BOOL m_bInFrameFree[NUM_IN_BUFFERS];
    251 
    252 ProfileType m_sProfile;
    253 
    254 static int m_nFramePlay = 0;
    255 static int m_eMode = MODE_PREVIEW;
    256 static int m_nInFd = -1;
    257 static int m_nOutFd = -1;
    258 static int m_nTimeStamp = 0;
    259 static int m_nFrameIn = 0; // frames pushed to encoder
    260 static int m_nFrameOut = 0; // frames returned by encoder
    261 static int m_nAVCSliceMode = 0;
    262 
    263 static bool m_bWatchDogKicked = false;
    264 
    265 /* Statistics Logging */
    266 static long long tot_bufsize = 0;
    267 int ebd_cnt=0, fbd_cnt=0;
    268 
    269 //////////////////////////
    270 // MODULE FUNCTIONS
    271 //////////////////////////
    272 
    273 void* PmemMalloc(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO* pMem, int nSize)
    274 {
    275    void *pvirt = NULL;
    276 
    277    if (!pMem)
    278       return NULL;
    279 
    280    pMem->pmem_fd = open("/dev/pmem_adsp", O_RDWR | O_SYNC);
    281    if ((int)(pMem->pmem_fd) < 0)
    282       return NULL;
    283    nSize = (nSize + 4095) & (~4095);
    284    pMem->offset = 0;
    285    pvirt = mmap(NULL, nSize,
    286                 PROT_READ | PROT_WRITE,
    287                 MAP_SHARED, pMem->pmem_fd, pMem->offset);
    288    if (pvirt == (void*) MAP_FAILED)
    289    {
    290       close(pMem->pmem_fd);
    291 	  pMem->pmem_fd = -1;
    292 	  return NULL;
    293    }
    294    D("allocated pMem->fd = %d pvirt=0x%x, pMem->phys=0x%x, size = %d", pMem->pmem_fd,
    295        pvirt, pMem->offset, nSize);
    296    return pvirt;
    297 }
    298 
    299 int PmemFree(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO* pMem, void* pvirt, int nSize)
    300 {
    301    if (!pMem || !pvirt)
    302       return -1;
    303 
    304    nSize = (nSize + 4095) & (~4095);
    305    munmap(pvirt, nSize);
    306    close(pMem->pmem_fd);
    307    pMem->pmem_fd = -1;
    308    return 0;
    309 }
    310 
    311 void SetState(OMX_STATETYPE eState)
    312 {
    313 #define GOTO_STATE(eState)                      \
    314    case eState:                                 \
    315       {                                         \
    316          D("Going to state " # eState"...");            \
    317          OMX_SendCommand(m_hHandle,                     \
    318                          OMX_CommandStateSet,           \
    319                          (OMX_U32) eState,              \
    320                          NULL);                         \
    321          while (m_eState != eState)                     \
    322          {                                              \
    323             sleep(1);                               \
    324          }                                              \
    325          D("Now in state " # eState);                   \
    326          break;                                         \
    327       }
    328 
    329    switch (eState)
    330    {
    331       GOTO_STATE(OMX_StateLoaded);
    332       GOTO_STATE(OMX_StateIdle);
    333       GOTO_STATE(OMX_StateExecuting);
    334       GOTO_STATE(OMX_StateInvalid);
    335       GOTO_STATE(OMX_StateWaitForResources);
    336       GOTO_STATE(OMX_StatePause);
    337    }
    338 }
    339 ////////////////////////////////////////////////////////////////////////////////
    340 OMX_ERRORTYPE ConfigureEncoder()
    341 {
    342    OMX_ERRORTYPE result = OMX_ErrorNone;
    343    unsigned const int *profile_tbl = NULL;
    344    OMX_U32 mb_per_sec, mb_per_frame;
    345    bool profile_level_found = false;
    346    OMX_U32 eProfile,eLevel;
    347 
    348    OMX_PARAM_PORTDEFINITIONTYPE portdef; // OMX_IndexParamPortDefinition
    349 #ifdef QCOM_EXT
    350       OMX_QCOM_PARAM_PORTDEFINITIONTYPE qPortDefnType;
    351 #endif
    352 
    353    portdef.nPortIndex = (OMX_U32) 0; // input
    354    result = OMX_GetParameter(m_hHandle,
    355                              OMX_IndexParamPortDefinition,
    356                              &portdef);
    357    E("\n OMX_IndexParamPortDefinition Get Paramter on input port");
    358    CHK(result);
    359    portdef.format.video.nFrameWidth = m_sProfile.nFrameWidth;
    360    portdef.format.video.nFrameHeight = m_sProfile.nFrameHeight;
    361 
    362    E ("\n Height %d width %d bit rate %d",portdef.format.video.nFrameHeight
    363       ,portdef.format.video.nFrameWidth,portdef.format.video.nBitrate);
    364    result = OMX_SetParameter(m_hHandle,
    365                              OMX_IndexParamPortDefinition,
    366                              &portdef);
    367    E("\n OMX_IndexParamPortDefinition Set Paramter on input port");
    368    CHK(result);
    369    portdef.nPortIndex = (OMX_U32) 1; // output
    370    result = OMX_GetParameter(m_hHandle,
    371                              OMX_IndexParamPortDefinition,
    372                              &portdef);
    373    E("\n OMX_IndexParamPortDefinition Get Paramter on output port");
    374    CHK(result);
    375    portdef.format.video.nFrameWidth = m_sProfile.nFrameWidth;
    376    portdef.format.video.nFrameHeight = m_sProfile.nFrameHeight;
    377    portdef.format.video.nBitrate = m_sProfile.nBitrate;
    378    portdef.format.video.xFramerate = m_sProfile.nFramerate << 16;
    379    result = OMX_SetParameter(m_hHandle,
    380                              OMX_IndexParamPortDefinition,
    381                              &portdef);
    382    E("\n OMX_IndexParamPortDefinition Set Paramter on output port");
    383    CHK(result);
    384 
    385 #ifdef QCOM_EXT
    386 
    387 qPortDefnType.nPortIndex = PORT_INDEX_IN;
    388 qPortDefnType.nMemRegion = OMX_QCOM_MemRegionEBI1;
    389 qPortDefnType.nSize = sizeof(OMX_QCOM_PARAM_PORTDEFINITIONTYPE);
    390 
    391 result = OMX_SetParameter(m_hHandle,
    392                              (OMX_INDEXTYPE)OMX_QcomIndexPortDefn,
    393                              &qPortDefnType);
    394 
    395 #endif
    396    //validate the ht,width,fps,bitrate and set the appropriate profile and level
    397    if(m_sProfile.eCodec == OMX_VIDEO_CodingMPEG4)
    398    {
    399      profile_tbl = (unsigned int const *)mpeg4_profile_level_table;
    400    }
    401    else if(m_sProfile.eCodec == OMX_VIDEO_CodingAVC)
    402    {
    403      profile_tbl = (unsigned int const *)h264_profile_level_table;
    404    }
    405    else if(m_sProfile.eCodec == OMX_VIDEO_CodingH263)
    406    {
    407      profile_tbl = (unsigned int const *)h263_profile_level_table;
    408    }
    409 
    410    mb_per_frame = ((m_sProfile.nFrameHeight+15)>>4)*
    411                 ((m_sProfile.nFrameWidth+15)>>4);
    412 
    413    mb_per_sec = mb_per_frame*(m_sProfile.nFramerate);
    414 
    415    do{
    416       if(mb_per_frame <= (int)profile_tbl[0])
    417       {
    418           if(mb_per_sec <= (int)profile_tbl[1])
    419           {
    420             if(m_sProfile.nBitrate <= (int)profile_tbl[2])
    421             {
    422               eLevel = (int)profile_tbl[3];
    423               eProfile = (int)profile_tbl[4];
    424               E("\n profile and level found \n");
    425               profile_level_found = true;
    426               break;
    427             }
    428           }
    429       }
    430       profile_tbl = profile_tbl + 5;
    431    }while(profile_tbl[0] != 0);
    432 
    433    if ( profile_level_found != true )
    434    {
    435      E("\n Error: Unsupported profile/level\n");
    436      return OMX_ErrorNone;
    437    }
    438 
    439    if (m_sProfile.eCodec == OMX_VIDEO_CodingH263)
    440    {
    441       D("Configuring H263...");
    442 
    443       OMX_VIDEO_PARAM_H263TYPE h263;
    444       result = OMX_GetParameter(m_hHandle,
    445                                 OMX_IndexParamVideoH263,
    446                                 &h263);
    447       CHK(result);
    448       h263.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
    449       h263.nPFrames = m_sProfile.nFramerate * 2 - 1; // intra period
    450       h263.nBFrames = 0;
    451       h263.eProfile = (OMX_VIDEO_H263PROFILETYPE)eProfile;
    452       h263.eLevel = (OMX_VIDEO_H263LEVELTYPE)eLevel;
    453       h263.bPLUSPTYPEAllowed = OMX_FALSE;
    454       h263.nAllowedPictureTypes = 2;
    455       h263.bForceRoundingTypeToZero = OMX_TRUE; ///@todo determine what this should be
    456       h263.nPictureHeaderRepetition = 0; ///@todo determine what this should be
    457       h263.nGOBHeaderInterval = 0; ///@todo determine what this should be
    458       result = OMX_SetParameter(m_hHandle,
    459                                 OMX_IndexParamVideoH263,
    460                                 &h263);
    461    }
    462    else
    463    {
    464       D("Configuring MP4/H264...");
    465 
    466       OMX_VIDEO_PARAM_PROFILELEVELTYPE profileLevel; // OMX_IndexParamVideoProfileLevelCurrent
    467       profileLevel.eProfile = eProfile;
    468       profileLevel.eLevel =  eLevel;
    469       result = OMX_SetParameter(m_hHandle,
    470                                 OMX_IndexParamVideoProfileLevelCurrent,
    471                                 &profileLevel);
    472       E("\n OMX_IndexParamVideoProfileLevelCurrent Set Paramter port");
    473       CHK(result);
    474       //profileLevel.eLevel = (OMX_U32) m_sProfile.eLevel;
    475       result = OMX_GetParameter(m_hHandle,
    476                                 OMX_IndexParamVideoProfileLevelCurrent,
    477                                 &profileLevel);
    478       E("\n OMX_IndexParamVideoProfileLevelCurrent Get Paramter port");
    479       D ("\n Profile = %d level = %d",profileLevel.eProfile,profileLevel.eLevel);
    480       CHK(result);
    481 
    482      /*OMX_VIDEO_PARAM_MPEG4TYPE mp4;
    483 
    484       result = OMX_GetParameter(m_hHandle,
    485                                 OMX_IndexParamVideoMpeg4,
    486                                 &mp4);
    487       E("\n OMX_IndexParamVideoMpeg4 Set Paramter port");
    488       CHK(result);
    489 
    490       mp4.nTimeIncRes = m_sProfile.nFramerate * 2;
    491       mp4.nPFrames = mp4.nTimeIncRes - 1; // intra period
    492 
    493       result = OMX_SetParameter(m_hHandle,
    494                                 OMX_IndexParamVideoMpeg4,
    495                                 &mp4);
    496       CHK(result);*/
    497 
    498 //       OMX_VIDEO_PARAM_MPEG4TYPE mp4; // OMX_IndexParamVideoMpeg4
    499 //       result = OMX_GetParameter(m_hHandle,
    500 //                                 OMX_IndexParamVideoMpeg4,
    501 //                                 &mp4);
    502 //       CHK(result);
    503 //       mp4.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
    504 //       mp4.eProfile = OMX_VIDEO_MPEG4ProfileSimple;
    505 //       mp4.eLevel = m_sProfile.eLevel;
    506 //       mp4.nSliceHeaderSpacing = 0;
    507 //       mp4.bSVH = OMX_FALSE;
    508 //       mp4.bGov = OMX_FALSE;
    509 //       mp4.nPFrames = m_sProfile.nFramerate * 2 - 1; // intra period
    510 //       mp4.bACPred = OMX_TRUE;
    511 //       mp4.nTimeIncRes = m_sProfile.nFramerate * 2; // delta = 2 @ 15 fps
    512 //       mp4.nAllowedPictureTypes = 2; // pframe and iframe
    513 //       result = OMX_SetParameter(m_hHandle,
    514 //                                 OMX_IndexParamVideoMpeg4,
    515 //                                 &mp4);
    516 //       CHK(result);
    517    }
    518 
    519    if (m_sProfile.eCodec == OMX_VIDEO_CodingAVC)
    520    {
    521       OMX_VIDEO_PARAM_AVCSLICEFMO avcslicefmo;
    522       avcslicefmo.nPortIndex = (OMX_U32)PORT_INDEX_OUT;
    523       result = OMX_GetParameter(m_hHandle,
    524                              OMX_IndexParamVideoSliceFMO,
    525                              &avcslicefmo);
    526       E("\n OMX_IndexParamVideoSliceFMO Get Paramter port");
    527       CHK(result);
    528 
    529       avcslicefmo.eSliceMode = m_sProfile.eSliceMode;
    530       result = OMX_SetParameter(m_hHandle,
    531                                 OMX_IndexParamVideoSliceFMO,
    532                                 &avcslicefmo);
    533       E("\n OMX_IndexParamVideoSliceFMO Set Paramter port");
    534       CHK(result);
    535    }
    536 
    537    OMX_VIDEO_PARAM_BITRATETYPE bitrate; // OMX_IndexParamVideoBitrate
    538    bitrate.nPortIndex = (OMX_U32)PORT_INDEX_OUT;
    539    result = OMX_GetParameter(m_hHandle,
    540                              OMX_IndexParamVideoBitrate,
    541                              &bitrate);
    542    E("\n OMX_IndexParamVideoBitrate Get Paramter port");
    543    CHK(result);
    544    bitrate.eControlRate = m_sProfile.eControlRate;
    545    bitrate.nTargetBitrate = m_sProfile.nBitrate;
    546    result = OMX_SetParameter(m_hHandle,
    547                              OMX_IndexParamVideoBitrate,
    548                              &bitrate);
    549    E("\n OMX_IndexParamVideoBitrate Set Paramter port");
    550    CHK(result);
    551 
    552    OMX_VIDEO_PARAM_PORTFORMATTYPE framerate; // OMX_IndexParamVidePortFormat
    553    framerate.nPortIndex = 0;
    554    result = OMX_GetParameter(m_hHandle,
    555                              OMX_IndexParamVideoPortFormat,
    556                              &framerate);
    557    E("\n OMX_IndexParamVideoPortFormat Get Paramter port");
    558    CHK(result);
    559    framerate.xFramerate = m_sProfile.nFramerate << 16;
    560    result = OMX_SetParameter(m_hHandle,
    561                              OMX_IndexParamVideoPortFormat,
    562                              &framerate);
    563    E("\n OMX_IndexParamVideoPortFormat Set Paramter port");
    564    CHK(result);
    565 
    566 #if 1
    567    OMX_CONFIG_FRAMERATETYPE enc_framerate; // OMX_IndexConfigVideoFramerate
    568    enc_framerate.nPortIndex = (OMX_U32)PORT_INDEX_OUT;
    569    result = OMX_GetConfig(m_hHandle,
    570                           OMX_IndexConfigVideoFramerate,
    571                           &enc_framerate);
    572    E("\n OMX_IndexConfigVideoFramerate Get config port");
    573    CHK(result);
    574    enc_framerate.xEncodeFramerate = m_sProfile.nFramerate << 16;
    575    result = OMX_SetConfig(m_hHandle,
    576                           OMX_IndexConfigVideoFramerate,
    577                           &enc_framerate);
    578    E("\n OMX_IndexConfigVideoFramerate Set config port");
    579    CHK(result);
    580 #endif
    581    return OMX_ErrorNone;
    582 }
    583 ////////////////////////////////////////////////////////////////////////////////
    584 void SendMessage(MsgId id, MsgData* data)
    585 {
    586    pthread_mutex_lock(&m_mutex);
    587    if (m_sMsgQ.size >= MAX_MSG)
    588    {
    589       E("main msg m_sMsgQ is full");
    590       return;
    591    }
    592    m_sMsgQ.q[(m_sMsgQ.head + m_sMsgQ.size) % MAX_MSG].id = id;
    593    if (data)
    594       m_sMsgQ.q[(m_sMsgQ.head + m_sMsgQ.size) % MAX_MSG].data = *data;
    595    ++m_sMsgQ.size;
    596    pthread_cond_signal(&m_signal);
    597    pthread_mutex_unlock(&m_mutex);
    598 }
    599 ////////////////////////////////////////////////////////////////////////////////
    600 void PopMessage(Msg* msg)
    601 {
    602    pthread_mutex_lock(&m_mutex);
    603    while (m_sMsgQ.size == 0)
    604    {
    605       pthread_cond_wait(&m_signal, &m_mutex);
    606    }
    607    *msg = m_sMsgQ.q[m_sMsgQ.head];
    608    --m_sMsgQ.size;
    609    m_sMsgQ.head = (m_sMsgQ.head + 1) % MAX_MSG;
    610    pthread_mutex_unlock(&m_mutex);
    611 }
    612 ////////////////////////////////////////////////////////////////////////////////
    613 OMX_ERRORTYPE EVT_CB(OMX_IN OMX_HANDLETYPE hComponent,
    614                      OMX_IN OMX_PTR pAppData,
    615                      OMX_IN OMX_EVENTTYPE eEvent,
    616                      OMX_IN OMX_U32 nData1,
    617                      OMX_IN OMX_U32 nData2,
    618                      OMX_IN OMX_PTR pEventData)
    619 {
    620 #define SET_STATE(eState)                                   \
    621    case eState:                                             \
    622       {                                                     \
    623          D("" # eState " complete");                        \
    624          m_eState = eState;                                 \
    625          break;                                             \
    626       }
    627 
    628    if (eEvent == OMX_EventCmdComplete)
    629    {
    630       if ((OMX_COMMANDTYPE) nData1 == OMX_CommandStateSet)
    631       {
    632          switch ((OMX_STATETYPE) nData2)
    633          {
    634             SET_STATE(OMX_StateLoaded);
    635             SET_STATE(OMX_StateIdle);
    636             SET_STATE(OMX_StateExecuting);
    637             SET_STATE(OMX_StateInvalid);
    638             SET_STATE(OMX_StateWaitForResources);
    639             SET_STATE(OMX_StatePause);
    640          default:
    641             E("invalid state %d", (int) nData2);
    642           }
    643       }
    644    }
    645 
    646    else if (eEvent == OMX_EventError)
    647    {
    648       E("OMX_EventError");
    649    }
    650 
    651    else
    652    {
    653       E("unexpected event %d", (int) eEvent);
    654    }
    655    return OMX_ErrorNone;
    656 }
    657 ////////////////////////////////////////////////////////////////////////////////
    658 OMX_ERRORTYPE EBD_CB(OMX_IN OMX_HANDLETYPE hComponent,
    659                      OMX_IN OMX_PTR pAppData,
    660                      OMX_IN OMX_BUFFERHEADERTYPE* pBuffer)
    661 {
    662    D("Got EBD callback ts=%lld", pBuffer->nTimeStamp);
    663 
    664    for (int i = 0; i < num_in_buffers; i++)
    665    {
    666       // mark this buffer ready for use again
    667       if (m_pInBuffers[i] == pBuffer)
    668       {
    669 
    670          D("Marked input buffer idx %d as free, buf %p", i, pBuffer->pBuffer);
    671          m_bInFrameFree[i] = OMX_TRUE;
    672          break;
    673       }
    674    }
    675 
    676    if (m_eMode == MODE_LIVE_ENCODE)
    677    {
    678       CameraTest_ReleaseFrame(pBuffer->pBuffer,
    679                               ((OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO*)pBuffer->pAppPrivate));
    680    }
    681    else
    682    {
    683       // wake up main thread and tell it to send next frame
    684       MsgData data;
    685       data.sBitstreamData.pBuffer = pBuffer;
    686       SendMessage(MSG_ID_INPUT_FRAME_DONE,
    687                   &data);
    688 
    689    }
    690    return OMX_ErrorNone;
    691 }
    692 ////////////////////////////////////////////////////////////////////////////////
    693 OMX_ERRORTYPE FBD_CB(OMX_OUT OMX_HANDLETYPE hComponent,
    694                      OMX_OUT OMX_PTR pAppData,
    695                      OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer)
    696 {
    697    D("Got FBD callback ts=%lld", pBuffer->nTimeStamp);
    698 
    699    static long long prevTime = 0;
    700    long long currTime = GetTimeStamp();
    701 
    702    m_bWatchDogKicked = true;
    703 
    704    /* Empty Buffers should not be counted */
    705    if(pBuffer->nFilledLen !=0)
    706    {
    707       /* Counting Buffers supplied from OpneMax Encoder */
    708       fbd_cnt++;
    709       tot_bufsize += pBuffer->nFilledLen;
    710    }
    711    if (prevTime != 0)
    712    {
    713       long long currTime = GetTimeStamp();
    714       D("FBD_DELTA = %lld\n", currTime - prevTime);
    715    }
    716    prevTime = currTime;
    717 
    718    if (m_eMode == MODE_PROFILE)
    719    {
    720       // if we are profiling we are not doing file I/O
    721       // so just give back to encoder
    722       if (OMX_FillThisBuffer(m_hHandle, pBuffer) != OMX_ErrorNone)
    723       {
    724          E("empty buffer failed for profiling");
    725       }
    726    }
    727    else
    728    {
    729       // wake up main thread and tell it to write to file
    730       MsgData data;
    731       data.sBitstreamData.pBuffer = pBuffer;
    732       SendMessage(MSG_ID_OUTPUT_FRAME_DONE,
    733                   &data);
    734    }
    735    return OMX_ErrorNone;
    736 }
    737 ////////////////////////////////////////////////////////////////////////////////
    738 OMX_ERRORTYPE VencTest_Initialize()
    739 {
    740    OMX_ERRORTYPE result = OMX_ErrorNone;
    741    static OMX_CALLBACKTYPE sCallbacks = {EVT_CB, EBD_CB, FBD_CB};
    742    int i;
    743 
    744    for (i = 0; i < num_in_buffers; i++)
    745    {
    746       m_pInBuffers[i] = NULL;
    747    }
    748 
    749    result = OMX_Init();
    750    CHK(result);
    751 
    752    if (m_sProfile.eCodec == OMX_VIDEO_CodingMPEG4)
    753    {
    754         result = OMX_GetHandle(&m_hHandle,
    755                              "OMX.qcom.video.encoder.mpeg4",
    756                              NULL,
    757                              &sCallbacks);
    758      // CHK(result);
    759    }
    760    else if (m_sProfile.eCodec == OMX_VIDEO_CodingH263)
    761    {
    762       result = OMX_GetHandle(&m_hHandle,
    763                              "OMX.qcom.video.encoder.h263",
    764                              NULL,
    765                              &sCallbacks);
    766       CHK(result);
    767    }
    768    else
    769    {
    770       result = OMX_GetHandle(&m_hHandle,
    771                              "OMX.qcom.video.encoder.avc",
    772                              NULL,
    773                              &sCallbacks);
    774       CHK(result);
    775    }
    776 
    777 
    778    result = ConfigureEncoder();
    779    CHK(result);
    780 
    781    return result;
    782 }
    783 
    784 ////////////////////////////////////////////////////////////////////////////////
    785 OMX_ERRORTYPE VencTest_RegisterYUVBuffer(OMX_BUFFERHEADERTYPE** ppBufferHeader,
    786                                          OMX_U8 *pBuffer,
    787                                          OMX_PTR pAppPrivate)
    788 {
    789    OMX_ERRORTYPE result = OMX_ErrorNone;
    790 #if 0
    791    D("register buffer");
    792    if ((result = OMX_AllocateBuffer(m_hHandle,
    793                                ppBufferHeader,
    794                                (OMX_U32) PORT_INDEX_IN,
    795                                pAppPrivate,
    796                                m_sProfile.nFrameBytes
    797                                )) != OMX_ErrorNone)
    798    {
    799       E("use buffer failed");
    800    }
    801    else
    802    {
    803      E("Allocate Buffer Success %x", (*ppBufferHeader)->pBuffer);
    804    }
    805   #endif
    806    D("register buffer");
    807    D("Calling UseBuffer for Input port");
    808    if ((result = OMX_UseBuffer(m_hHandle,
    809                                ppBufferHeader,
    810                                (OMX_U32) PORT_INDEX_IN,
    811                                pAppPrivate,
    812                                m_sProfile.nFrameBytes,
    813                                pBuffer)) != OMX_ErrorNone)
    814    {
    815       E("use buffer failed");
    816    }
    817 
    818    return result;
    819 }
    820 ////////////////////////////////////////////////////////////////////////////////
    821 OMX_ERRORTYPE VencTest_EncodeFrame(void* pYUVBuff,
    822                                    long long nTimeStamp)
    823 {
    824    OMX_ERRORTYPE result = OMX_ErrorUndefined;
    825    D("calling OMX empty this buffer");
    826    for (int i = 0; i < num_in_buffers; i++)
    827    {
    828       if (pYUVBuff == m_pInBuffers[i]->pBuffer)
    829       {
    830          m_pInBuffers[i]->nTimeStamp = nTimeStamp;
    831     D("Sending Buffer - %x", m_pInBuffers[i]->pBuffer);
    832          result = OMX_EmptyThisBuffer(m_hHandle,
    833                                       m_pInBuffers[i]);
    834          /* Counting Buffers supplied to OpenMax Encoder */
    835          if(OMX_ErrorNone == result)
    836             ebd_cnt++;
    837          CHK(result);
    838          break;
    839       }
    840    }
    841    return result;
    842 }
    843 ////////////////////////////////////////////////////////////////////////////////
    844 OMX_ERRORTYPE VencTest_Exit(void)
    845 {
    846    int i;
    847    OMX_ERRORTYPE result = OMX_ErrorNone;
    848    D("trying to exit venc");
    849 
    850    D("going to idle state");
    851    SetState(OMX_StateIdle);
    852 
    853 
    854    D("going to loaded state");
    855    //SetState(OMX_StateLoaded);
    856       OMX_SendCommand(m_hHandle,
    857                       OMX_CommandStateSet,
    858                       (OMX_U32) OMX_StateLoaded,
    859                        NULL);
    860 
    861       for (i = 0; i < num_in_buffers; i++)
    862    {
    863       D("free buffer");
    864       if (m_pInBuffers[i]->pBuffer)
    865       {
    866         // free(m_pInBuffers[i]->pBuffer);
    867          result = OMX_FreeBuffer(m_hHandle,
    868                                  PORT_INDEX_IN,
    869                                  m_pInBuffers[i]);
    870          CHK(result);
    871       }
    872       else
    873       {
    874          E("buffer %d is null", i);
    875          result = OMX_ErrorUndefined;
    876          CHK(result);
    877       }
    878    }
    879    for (i = 0; i < num_out_buffers; i++)
    880    {
    881       D("free buffer");
    882       if (m_pOutBuffers[i]->pBuffer)
    883       {
    884          free(m_pOutBuffers[i]->pBuffer);
    885          result = OMX_FreeBuffer(m_hHandle,
    886                                  PORT_INDEX_OUT,
    887                                  m_pOutBuffers[i]);
    888          CHK(result);
    889 
    890       }
    891       else
    892       {
    893          E("buffer %d is null", i);
    894          result = OMX_ErrorUndefined;
    895          CHK(result);
    896       }
    897    }
    898 
    899      while (m_eState != OMX_StateLoaded)
    900      {
    901         sleep(1);
    902      }
    903    D("component_deinit...");
    904    result = OMX_Deinit();
    905    CHK(result);
    906 
    907    D("venc is exiting...");
    908    return result;
    909 }
    910 ////////////////////////////////////////////////////////////////////////////////
    911 OMX_ERRORTYPE VencTest_ReadAndEmpty(OMX_BUFFERHEADERTYPE* pYUVBuffer)
    912 {
    913    OMX_ERRORTYPE result = OMX_ErrorNone;
    914 #ifdef T_ARM
    915    if (read(m_nInFd,
    916             pYUVBuffer->pBuffer,
    917             m_sProfile.nFrameBytes) != m_sProfile.nFrameBytes)
    918    {
    919       return OMX_ErrorUndefined;
    920    }
    921 #else
    922    {
    923 	  char * pInputbuf = (char *)(pYUVBuffer->pBuffer) ;
    924 	      read(m_nInFd,pInputbuf,m_sProfile.nFrameBytes) ;
    925 
    926    }
    927 #endif
    928    D("about to call VencTest_EncodeFrame...");
    929    pthread_mutex_lock(&m_mutex);
    930    ++m_nFrameIn;
    931    pYUVBuffer->nFilledLen = m_sProfile.nFrameBytes;
    932    D("Called Buffer with Data filled length %d",pYUVBuffer->nFilledLen);
    933 
    934       result = VencTest_EncodeFrame(pYUVBuffer->pBuffer,
    935                                  m_nTimeStamp);
    936 
    937    m_nTimeStamp += (1000000) / m_sProfile.nFramerate;
    938    CHK(result);
    939    pthread_mutex_unlock(&m_mutex);
    940    return result;
    941 }
    942 ////////////////////////////////////////////////////////////////////////////////
    943 void PreviewCallback(int nFD,
    944                      int nOffset,
    945                      void* pPhys,
    946                      void* pVirt,
    947                      long long nTimeStamp)
    948 {
    949 
    950    D("================= preview frame %d, phys=0x%x, nTimeStamp(millis)=%lld",
    951      m_nFrameIn+1, pPhys, (nTimeStamp / 1000));
    952 
    953    if (m_nFrameIn == m_nFramePlay &&
    954        m_nFramePlay != 0)
    955    {
    956       // we will stop camera after last frame is encoded.
    957       // for now just ignore input frames
    958 
    959       CameraTest_ReleaseFrame(pPhys, pVirt);
    960       return;
    961    }
    962 
    963    // see if we should stop
    964    pthread_mutex_lock(&m_mutex);
    965    ++m_nFrameIn;
    966    pthread_mutex_unlock(&m_mutex);
    967 
    968 
    969    if (m_eMode == MODE_LIVE_ENCODE)
    970    {
    971 
    972       OMX_ERRORTYPE result;
    973 
    974       // register new camera buffers with encoder
    975       int i;
    976       for (i = 0; i < num_in_buffers; i++)
    977       {
    978          if (m_pInBuffers[i] != NULL &&
    979              m_pInBuffers[i]->pBuffer == pPhys)
    980          {
    981             break;
    982          }
    983          else if (m_pInBuffers[i] == NULL)
    984          {
    985             D("registering buffer...");
    986             result = VencTest_RegisterYUVBuffer(&m_pInBuffers[i],
    987                                                 (OMX_U8*) pPhys,
    988                                                 (OMX_PTR) pVirt); // store virt in app private field
    989             D("register done");
    990             CHK(result);
    991             break;
    992          }
    993       }
    994 
    995       if (i == num_in_buffers)
    996       {
    997          E("There are more camera buffers than we thought");
    998          CHK(1);
    999       }
   1000 
   1001       // encode the yuv frame
   1002 
   1003       D("StartEncodeTime=%lld", GetTimeStamp());
   1004       result = VencTest_EncodeFrame(pPhys,
   1005                                     nTimeStamp);
   1006       CHK(result);
   1007      // FBTest_DisplayImage(nFD, nOffset);
   1008    }
   1009    else
   1010    {
   1011      // FBTest_DisplayImage(nFD, nOffset);
   1012       CameraTest_ReleaseFrame(pPhys, pVirt);
   1013    }
   1014 }
   1015 ////////////////////////////////////////////////////////////////////////////////
   1016 void usage(char* filename)
   1017 {
   1018    char* fname = strrchr(filename, (int) '/');
   1019    fname = (fname == NULL) ? filename : fname;
   1020 
   1021    fprintf(stderr, "usage: %s LIVE <QCIF|QVGA> <MP4|H263> <FPS> <BITRATE> <NFRAMES> <OUTFILE>\n", fname);
   1022    fprintf(stderr, "usage: %s FILE <QCIF|QVGA> <MP4|H263 <FPS> <BITRATE> <NFRAMES> <INFILE> <OUTFILE> ", fname);
   1023    fprintf(stderr, "<Rate Control - optional> <AVC Slice Mode - optional\n", fname);
   1024    fprintf(stderr, "usage: %s PROFILE <QCIF|QVGA> <MP4|H263 <FPS> <BITRATE> <NFRAMES> <INFILE>\n", fname);
   1025    fprintf(stderr, "usage: %s PREVIEW <QCIF|QVGA> <FPS> <NFRAMES>\n", fname);
   1026    fprintf(stderr, "usage: %s DISPLAY <QCIF|QVGA> <FPS> <NFRAMES> <INFILE>\n", fname);
   1027    fprintf(stderr, "\n       BITRATE - bitrate in kbps\n");
   1028    fprintf(stderr, "       FPS - frames per second\n");
   1029    fprintf(stderr, "       NFRAMES - number of frames to play, 0 for infinite\n");
   1030    fprintf(stderr, "       RateControl (Values 0 - 4 for RC_OFF, RC_CBR_CFR, RC_CBR_VFR, RC_VBR_CFR, RC_VBR_VFR\n");
   1031    exit(1);
   1032 }
   1033 ////////////////////////////////////////////////////////////////////////////////
   1034 void parseArgs(int argc, char** argv)
   1035 {
   1036 
   1037    if (argc == 1)
   1038    {
   1039       usage(argv[0]);
   1040    }
   1041    else if (strcmp("PREVIEW", argv[1]) == 0 ||
   1042             strcmp("preview", argv[1]) == 0)
   1043    {
   1044       m_eMode = MODE_PREVIEW;
   1045       if (argc != 5)
   1046       {
   1047          usage(argv[0]);
   1048       }
   1049    }
   1050    else if (strcmp("DISPLAY", argv[1]) == 0 ||
   1051             strcmp("display", argv[1]) == 0)
   1052    {
   1053       m_eMode = MODE_DISPLAY;
   1054       if (argc != 6)
   1055       {
   1056          usage(argv[0]);
   1057       }
   1058       m_sProfile.cInFileName = argv[5];
   1059       m_sProfile.cOutFileName = NULL;
   1060    }
   1061    else if (strcmp("LIVE", argv[1]) == 0 ||
   1062             strcmp("live", argv[1]) == 0)
   1063    {//263
   1064       m_eMode = MODE_LIVE_ENCODE;
   1065       if (argc != 8)
   1066       {
   1067          usage(argv[0]);
   1068       }
   1069       m_sProfile.cInFileName = NULL;
   1070       m_sProfile.cOutFileName = argv[7];
   1071    }
   1072    else if (strcmp("FILE", argv[1]) == 0 ||
   1073             strcmp("file", argv[1]) == 0)
   1074    {//263
   1075       m_eMode = MODE_FILE_ENCODE;
   1076 
   1077       if(argc < 9 || argc > 11)
   1078       {
   1079           usage(argv[0]);
   1080       }
   1081       else
   1082       {
   1083          if ((argc == 10))
   1084          {
   1085            m_sProfile.eControlRate = OMX_Video_ControlRateVariable;
   1086             int RC = atoi(argv[9]);
   1087 
   1088             switch (RC)
   1089             {
   1090             case 0:
   1091                m_sProfile.eControlRate  = OMX_Video_ControlRateDisable ;//VENC_RC_NONE
   1092                break;
   1093             case 1:
   1094                m_sProfile.eControlRate  = OMX_Video_ControlRateConstant;//VENC_RC_CBR_CFR
   1095                break;
   1096 
   1097             case 2:
   1098                m_sProfile.eControlRate  = OMX_Video_ControlRateConstantSkipFrames;//VENC_RC_CBR_VFR
   1099                break;
   1100 
   1101             case 3:
   1102                m_sProfile.eControlRate  =OMX_Video_ControlRateVariable ;//VENC_RC_VBR_CFR
   1103                break;
   1104 
   1105             case 4:
   1106                m_sProfile.eControlRate  = OMX_Video_ControlRateVariableSkipFrames;//VENC_RC_VBR_VFR
   1107                break;
   1108 
   1109            default:
   1110                E("invalid rate control selection");
   1111                m_sProfile.eControlRate = OMX_Video_ControlRateVariable; //VENC_RC_VBR_CFR
   1112                break;
   1113             }
   1114          }
   1115 
   1116          if (argc == 11)
   1117          {
   1118             if(!strcmp(argv[3], "H264") || !strcmp(argv[3], "h264"))
   1119             {
   1120                E("\nSetting AVCSliceMode ... ");
   1121                int AVCSliceMode = atoi(argv[10]);
   1122                switch(AVCSliceMode)
   1123                {
   1124                case 0:
   1125                   m_sProfile.eSliceMode = OMX_VIDEO_SLICEMODE_AVCDefault;
   1126                   break;
   1127 
   1128                case 1:
   1129                   m_sProfile.eSliceMode = OMX_VIDEO_SLICEMODE_AVCMBSlice;
   1130                   break;
   1131 
   1132                case 2:
   1133                   m_sProfile.eSliceMode = OMX_VIDEO_SLICEMODE_AVCByteSlice;
   1134                   break;
   1135 
   1136                default:
   1137                   E("invalid Slice Mode");
   1138                   m_sProfile.eSliceMode = OMX_VIDEO_SLICEMODE_AVCDefault;
   1139                   break;
   1140               }
   1141             }
   1142             else
   1143             {
   1144                E("SliceMode support only for H.264 codec");
   1145                usage(argv[0]);
   1146             }
   1147          }
   1148       }
   1149       m_sProfile.cInFileName = argv[7];
   1150       m_sProfile.cOutFileName = argv[8];
   1151    }
   1152    else if (strcmp("PROFILE", argv[1]) == 0 ||
   1153             strcmp("profile", argv[1]) == 0)
   1154    {//263
   1155       m_eMode = MODE_PROFILE;
   1156       if (argc != 8)
   1157       {
   1158          usage(argv[0]);
   1159       }
   1160       m_sProfile.cInFileName = argv[7];
   1161       m_sProfile.cOutFileName = NULL;
   1162    }
   1163    else
   1164    {
   1165       usage(argv[0]);
   1166    }
   1167 
   1168 
   1169    if (strcmp("QCIF", argv[2]) == 0 ||
   1170        strcmp("qcif", argv[2]) == 0)
   1171    {
   1172       m_sProfile.nFrameWidth = 176;
   1173       m_sProfile.nFrameHeight = 144;
   1174       m_sProfile.nFrameBytes = 176*144*3/2;
   1175       m_sProfile.eLevel = OMX_VIDEO_MPEG4Level0;
   1176    }
   1177    else if (strcmp("QVGA", argv[2]) == 0 ||
   1178             strcmp("qvga", argv[2]) == 0)
   1179    {
   1180       m_sProfile.nFrameWidth = 320;
   1181       m_sProfile.nFrameHeight = 240;
   1182       m_sProfile.nFrameBytes = 320*240*3/2;
   1183       m_sProfile.eLevel = OMX_VIDEO_MPEG4Level1;
   1184    }
   1185 
   1186 
   1187     else if (strcmp("VGA", argv[2]) == 0 ||
   1188             strcmp("vga", argv[2]) == 0)
   1189    {
   1190       m_sProfile.nFrameWidth = 640;
   1191       m_sProfile.nFrameHeight = 480;
   1192       m_sProfile.nFrameBytes = 640*480*3/2;
   1193       m_sProfile.eLevel = OMX_VIDEO_MPEG4Level1;
   1194    }
   1195 
   1196     else if (strcmp("WVGA", argv[2]) == 0 ||
   1197             strcmp("wvga", argv[2]) == 0)
   1198    {
   1199       m_sProfile.nFrameWidth = 800;
   1200       m_sProfile.nFrameHeight = 480;
   1201       m_sProfile.nFrameBytes = 800*480*3/2;
   1202       m_sProfile.eLevel = OMX_VIDEO_MPEG4Level1;
   1203    }
   1204   else if (strcmp("CIF", argv[2]) == 0 ||
   1205             strcmp("CIF", argv[2]) == 0)
   1206    {
   1207       m_sProfile.nFrameWidth = 352;
   1208       m_sProfile.nFrameHeight = 288;
   1209       m_sProfile.nFrameBytes = 352*288*3/2;
   1210       m_sProfile.eLevel = OMX_VIDEO_MPEG4Level1;
   1211    }
   1212    else if (strcmp("720", argv[2]) == 0 ||
   1213             strcmp("720", argv[2]) == 0)
   1214    {
   1215       m_sProfile.nFrameWidth = 1280;
   1216       m_sProfile.nFrameHeight = 720;
   1217       m_sProfile.nFrameBytes = 720*1280*3/2;
   1218       m_sProfile.eLevel = OMX_VIDEO_MPEG4Level1;
   1219    }
   1220    else
   1221    {
   1222       usage(argv[0]);
   1223    }
   1224 
   1225    if (m_eMode == MODE_DISPLAY ||
   1226        m_eMode == MODE_PREVIEW)
   1227    {
   1228       m_sProfile.nFramerate = atoi(argv[3]);
   1229       m_nFramePlay = atoi(argv[4]);
   1230 
   1231    }
   1232    else if (m_eMode == MODE_LIVE_ENCODE ||
   1233             m_eMode == MODE_FILE_ENCODE ||
   1234             m_eMode == MODE_PROFILE)
   1235    {//263
   1236       if ((!strcmp(argv[3], "MP4")) || (!strcmp(argv[3], "mp4")))
   1237       {
   1238          m_sProfile.eCodec = OMX_VIDEO_CodingMPEG4;
   1239       }
   1240       else if ((!strcmp(argv[3], "H263")) || (!strcmp(argv[3], "h263")))
   1241       {
   1242          m_sProfile.eCodec = OMX_VIDEO_CodingH263;
   1243       }
   1244       else if ((!strcmp(argv[3], "H264")) || (!strcmp(argv[3], "h264")))
   1245       {
   1246          m_sProfile.eCodec = OMX_VIDEO_CodingAVC;
   1247       }
   1248       else
   1249       {
   1250          usage(argv[0]);
   1251       }
   1252 
   1253       m_sProfile.nFramerate = atoi(argv[4]);
   1254       m_sProfile.nBitrate = atoi(argv[5]);
   1255 //      m_sProfile.eControlRate = OMX_Video_ControlRateVariable;
   1256       m_nFramePlay = atoi(argv[6]);
   1257    }
   1258 }
   1259 
   1260 
   1261 void* Watchdog(void* data)
   1262 {
   1263    while (1)
   1264    {
   1265       sleep(1000);
   1266       if (m_bWatchDogKicked == true)
   1267          m_bWatchDogKicked = false;
   1268       else
   1269          E("watchdog has not been kicked. we may have a deadlock");
   1270    }
   1271    return NULL;
   1272 }
   1273 
   1274 int main(int argc, char** argv)
   1275 {
   1276    OMX_U8* pvirt = NULL;
   1277    int result;
   1278    float enc_time_sec=0.0,enc_time_usec=0.0;
   1279 
   1280    m_nInFd = -1;
   1281    m_nOutFd = -1;
   1282    m_nTimeStamp = 0;
   1283    m_nFrameIn = 0;
   1284    m_nFrameOut = 0;
   1285 
   1286    memset(&m_sMsgQ, 0, sizeof(MsgQ));
   1287    parseArgs(argc, argv);
   1288 
   1289    D("fps=%d, bitrate=%d, width=%d, height=%d",
   1290      m_sProfile.nFramerate,
   1291      m_sProfile.nBitrate,
   1292      m_sProfile.nFrameWidth,
   1293      m_sProfile.nFrameHeight);
   1294 
   1295 
   1296    //if (m_eMode != MODE_PREVIEW && m_eMode != MODE_DISPLAY)
   1297    //{
   1298      // pthread_t wd;
   1299      // pthread_create(&wd, NULL, Watchdog, NULL);
   1300    //}
   1301 
   1302    for (int x = 0; x < num_in_buffers; x++)
   1303    {
   1304       // mark all buffers as ready to use
   1305       m_bInFrameFree[x] = OMX_TRUE;
   1306    }
   1307 
   1308 
   1309     if (m_eMode != MODE_PROFILE)
   1310    {
   1311       #if T_ARM
   1312 	   m_nOutFd = open(m_sProfile.cOutFileName, O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU | S_IRWXG | S_IRWXO);
   1313       #else
   1314 	  m_nOutFd = open(m_sProfile.cOutFileName,0);
   1315       #endif
   1316       if (m_nOutFd < 0)
   1317       {
   1318          E("could not open output file %s", m_sProfile.cOutFileName);
   1319          CHK(1);
   1320       }
   1321    }
   1322 
   1323    pthread_mutex_init(&m_mutex, NULL);
   1324    pthread_cond_init(&m_signal, NULL);
   1325 
   1326    if (m_eMode != MODE_PREVIEW)
   1327    {
   1328       VencTest_Initialize();
   1329    }
   1330 
   1331    ////////////////////////////////////////
   1332    // Camera + Encode
   1333    ////////////////////////////////////////
   1334    if (m_eMode == MODE_LIVE_ENCODE)
   1335    {
   1336      CameraTest_Initialize(m_sProfile.nFramerate,
   1337                             m_sProfile.nFrameWidth,
   1338                             m_sProfile.nFrameHeight,
   1339                             PreviewCallback);
   1340       CameraTest_Run();
   1341    }
   1342 
   1343    if (m_eMode == MODE_FILE_ENCODE ||
   1344        m_eMode == MODE_PROFILE)
   1345    {
   1346       int i;
   1347       #if T_ARM
   1348       m_nInFd = open(m_sProfile.cInFileName, O_RDONLY);
   1349       #else
   1350       m_nInFd = open(m_sProfile.cInFileName,1);
   1351       #endif
   1352 	  if (m_nInFd < 0)
   1353       {
   1354          E("could not open input file");
   1355          CHK(1);
   1356       }
   1357       D("going to idle state");
   1358       //SetState(OMX_StateIdle);
   1359       OMX_SendCommand(m_hHandle,
   1360                       OMX_CommandStateSet,
   1361                       (OMX_U32) OMX_StateIdle,
   1362                        NULL);
   1363 
   1364       OMX_PARAM_PORTDEFINITIONTYPE portDef;
   1365 
   1366       portDef.nPortIndex = 0;
   1367       result = OMX_GetParameter(m_hHandle, OMX_IndexParamPortDefinition, &portDef);
   1368       CHK(result);
   1369 
   1370       D("allocating output buffers");
   1371 
   1372       D("allocating Input buffers");
   1373       num_in_buffers = portDef.nBufferCountActual;
   1374       for (i = 0; i < portDef.nBufferCountActual; i++)
   1375       {
   1376          OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO* pMem = new OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO;
   1377          pvirt = (OMX_U8*)PmemMalloc(pMem, m_sProfile.nFrameBytes);
   1378 
   1379          if(pvirt == NULL)
   1380          {
   1381             CHK(1);
   1382          }
   1383          result = VencTest_RegisterYUVBuffer(&m_pInBuffers[i],
   1384                                              (OMX_U8*) pvirt,
   1385                                              (OMX_PTR) pMem);
   1386          CHK(result);
   1387       }
   1388    }
   1389    else if (m_eMode == MODE_LIVE_ENCODE)
   1390    {
   1391        D("going to idle state");
   1392        //SetState(OMX_StateIdle);
   1393        OMX_SendCommand(m_hHandle,
   1394                        OMX_CommandStateSet,
   1395                        (OMX_U32) OMX_StateIdle,
   1396                         NULL);
   1397    }
   1398 
   1399    int i;
   1400    OMX_PARAM_PORTDEFINITIONTYPE portDef;
   1401 
   1402    portDef.nPortIndex = 1;
   1403    result = OMX_GetParameter(m_hHandle, OMX_IndexParamPortDefinition, &portDef);
   1404    CHK(result);
   1405 
   1406    D("allocating output buffers");
   1407    D("Calling UseBuffer for Output port");
   1408    num_out_buffers = portDef.nBufferCountActual;
   1409    for (i = 0; i < portDef.nBufferCountActual; i++)
   1410    {
   1411       void* pBuff;
   1412 
   1413       pBuff = malloc(portDef.nBufferSize);
   1414      D("portDef.nBufferSize = %d ",portDef.nBufferSize);
   1415       result = OMX_UseBuffer(m_hHandle,
   1416                              &m_pOutBuffers[i],
   1417                              (OMX_U32) PORT_INDEX_OUT,
   1418                              NULL,
   1419                              portDef.nBufferSize,
   1420                              (OMX_U8*) pBuff);
   1421       CHK(result);
   1422    }
   1423    D("allocate done");
   1424 
   1425         // D("Going to state " # eState"...");
   1426 
   1427          while (m_eState != OMX_StateIdle)
   1428          {
   1429             sleep(1);
   1430          }
   1431          //D("Now in state " # eState);
   1432 
   1433 
   1434    D("going to executing state");
   1435    SetState(OMX_StateExecuting);
   1436 
   1437    for (i = 0; i < num_out_buffers; i++)
   1438    {
   1439       D("filling buffer %d", i);
   1440       result = OMX_FillThisBuffer(m_hHandle, m_pOutBuffers[i]);
   1441       //sleep(1000);
   1442       CHK(result);
   1443    }
   1444 
   1445    if (m_eMode == MODE_FILE_ENCODE)
   1446    {
   1447       // encode the first frame to kick off the whole process
   1448       VencTest_ReadAndEmpty(m_pInBuffers[0]);
   1449     //  FBTest_DisplayImage(((PmemBuffer*) m_pInBuffers[0]->pAppPrivate)->fd,0);
   1450    }
   1451 
   1452    if (m_eMode == MODE_PROFILE)
   1453    {
   1454       int i;
   1455 
   1456       // read several frames into memory
   1457       D("reading frames into memory");
   1458       for (i = 0; i < num_in_buffers; i++)
   1459       {
   1460         D("[%d] address 0x%x",i, m_pInBuffers[i]->pBuffer);
   1461          read(m_nInFd,
   1462               m_pInBuffers[i]->pBuffer,
   1463               m_sProfile.nFrameBytes);
   1464 
   1465       }
   1466 
   1467      // FBTest_Initialize(m_sProfile.nFrameWidth, m_sProfile.nFrameHeight);
   1468 
   1469       // loop over the mem-resident frames and encode them
   1470       D("beging playing mem-resident frames...");
   1471       for (i = 0; m_nFramePlay == 0 || i < m_nFramePlay; i++)
   1472       {
   1473          int idx = i % num_in_buffers;
   1474          if (m_bInFrameFree[idx] == OMX_FALSE)
   1475          {
   1476             int j;
   1477             E("the expected buffer is not free, but lets find another");
   1478 
   1479             idx = -1;
   1480 
   1481             // lets see if we can find another free buffer
   1482             for (j = 0; j < num_in_buffers; j++)
   1483             {
   1484                if(m_bInFrameFree[j])
   1485                {
   1486                   idx = j;
   1487                   break;
   1488                }
   1489             }
   1490          }
   1491 
   1492          // if we have a free buffer let's encode it
   1493          if (idx >= 0)
   1494          {
   1495             D("encode frame %d...m_pInBuffers[idx]->pBuffer=0x%x", i,m_pInBuffers[idx]->pBuffer);
   1496             m_bInFrameFree[idx] = OMX_FALSE;
   1497             VencTest_EncodeFrame(m_pInBuffers[idx]->pBuffer,
   1498                                  m_nTimeStamp);
   1499             D("display frame %d...", i);
   1500         //    FBTest_DisplayImage(((PmemBuffer*) m_pInBuffers[idx]->pAppPrivate)->fd,0);
   1501             m_nTimeStamp += 1000000 / m_sProfile.nFramerate;
   1502          }
   1503          else
   1504          {
   1505             E("wow, no buffers are free, performance "
   1506               "is not so good. lets just sleep some more");
   1507 
   1508          }
   1509          D("sleep for %d microsec", 1000000/m_sProfile.nFramerate);
   1510          sleep (1000000 / m_sProfile.nFramerate);
   1511       }
   1512      // FBTest_Exit();
   1513    }
   1514 
   1515    Msg msg;
   1516    bool bQuit = false;
   1517    while ((m_eMode == MODE_FILE_ENCODE || m_eMode == MODE_LIVE_ENCODE) &&
   1518           !bQuit)
   1519    {
   1520       PopMessage(&msg);
   1521       switch (msg.id)
   1522       {
   1523       //////////////////////////////////
   1524       // FRAME IS ENCODED
   1525       //////////////////////////////////
   1526       case MSG_ID_INPUT_FRAME_DONE:
   1527          /*pthread_mutex_lock(&m_mutex);
   1528          ++m_nFrameOut;
   1529          if (m_nFrameOut == m_nFramePlay && m_nFramePlay != 0)
   1530          {
   1531             bQuit = true;
   1532          }
   1533          pthread_mutex_unlock(&m_mutex);*/
   1534 
   1535          if (!bQuit && m_eMode == MODE_FILE_ENCODE)
   1536          {
   1537             D("pushing another frame down to encoder");
   1538             if (VencTest_ReadAndEmpty(msg.data.sBitstreamData.pBuffer))
   1539             {
   1540                // we have read the last frame
   1541                D("main is exiting...");
   1542                bQuit = true;
   1543             }
   1544          }
   1545        break;
   1546       case MSG_ID_OUTPUT_FRAME_DONE:
   1547          D("================ writing frame %d = %d bytes to output file",
   1548            m_nFrameOut+1,
   1549            msg.data.sBitstreamData.pBuffer->nFilledLen);
   1550          D("StopEncodeTime=%lld", GetTimeStamp());
   1551 
   1552 
   1553 		 write(m_nOutFd,
   1554                msg.data.sBitstreamData.pBuffer->pBuffer,
   1555                msg.data.sBitstreamData.pBuffer->nFilledLen);
   1556 
   1557 
   1558          result = OMX_FillThisBuffer(m_hHandle,
   1559                                      msg.data.sBitstreamData.pBuffer);
   1560 
   1561          if (result != OMX_ErrorNone)
   1562          {
   1563             CHK(result);
   1564          }
   1565 
   1566          pthread_mutex_lock(&m_mutex);
   1567          ++m_nFrameOut;
   1568          if (m_nFrameOut == m_nFramePlay && m_nFramePlay != 0)
   1569          {
   1570             bQuit = true;
   1571          }
   1572          pthread_mutex_unlock(&m_mutex);
   1573          break;
   1574 
   1575       default:
   1576          E("invalid msg id %d", (int) msg.id);
   1577       } // end switch (msg.id)
   1578    } // end while (!bQuit)
   1579 
   1580 
   1581    if (m_eMode == MODE_LIVE_ENCODE)
   1582    {
   1583       CameraTest_Exit();
   1584       close(m_nOutFd);
   1585    }
   1586    else if (m_eMode == MODE_FILE_ENCODE ||
   1587             m_eMode == MODE_PROFILE)
   1588    {
   1589       // deallocate pmem buffers
   1590       for (int i = 0; i < num_in_buffers; i++)
   1591       {
   1592          PmemFree((OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO*)m_pInBuffers[i]->pAppPrivate,
   1593                   m_pInBuffers[i]->pBuffer,
   1594                   m_sProfile.nFrameBytes);
   1595          delete (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO*) m_pInBuffers[i]->pAppPrivate;
   1596       }
   1597       close(m_nInFd);
   1598 
   1599       if (m_eMode == MODE_FILE_ENCODE)
   1600       {
   1601          close(m_nOutFd);
   1602       }
   1603    }
   1604 
   1605    if (m_eMode != MODE_PREVIEW)
   1606    {
   1607       D("exit encoder test");
   1608       VencTest_Exit();
   1609    }
   1610 
   1611    pthread_mutex_destroy(&m_mutex);
   1612    pthread_cond_destroy(&m_signal);
   1613 
   1614    /* Time Statistics Logging */
   1615    if(0 != m_sProfile.nFramerate)
   1616    {
   1617       enc_time_usec = m_nTimeStamp - (1000000 / m_sProfile.nFramerate);
   1618       enc_time_sec =enc_time_usec/1000000;
   1619       if(0 != enc_time_sec)
   1620       {
   1621          printf("Total Frame Rate: %f",ebd_cnt/enc_time_sec);
   1622          printf("\nEncoder Bitrate :%lf Kbps",(tot_bufsize*8)/(enc_time_sec*1000));
   1623       }
   1624    }
   1625    else
   1626    {
   1627       printf("\n\n Encode Time is zero");
   1628    }
   1629    printf("\nTotal Number of Frames :%d",ebd_cnt);
   1630    printf("\nNumber of dropped frames during encoding:%d\n",ebd_cnt-fbd_cnt);
   1631    /* End of Time Statistics Logging */
   1632 
   1633    D("main has exited");
   1634    return 0;
   1635 }
   1636