Home | History | Annotate | Download | only in test
      1 /*--------------------------------------------------------------------------
      2 Copyright (c) 2010-2011, 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 <limits.h>
     56 #include <string.h>
     57 //#include <sys/stat.h>
     58 #include "OMX_QCOMExtns.h"
     59 #include "OMX_Core.h"
     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 #include "extra_data_handler.h"
     70 #ifdef USE_ION
     71 #include <linux/msm_ion.h>
     72 #endif
     73 
     74 //////////////////////////
     75 // MACROS
     76 //////////////////////////
     77 
     78 #define CHK(result) if (result != OMX_ErrorNone) { E("*************** error *************"); exit(0); }
     79 #define TEST_LOG
     80 #ifdef VENC_SYSLOG
     81 #include "cutils/log.h"
     82 /// Debug message macro
     83 #define D(fmt, ...) LOGE("venc_test Debug %s::%d "fmt"\n",              \
     84                          __FUNCTION__, __LINE__,                        \
     85                          ## __VA_ARGS__)
     86 
     87 /// Error message macro
     88 #define E(fmt, ...) LOGE("venc_test Error %s::%d "fmt"\n",            \
     89                          __FUNCTION__, __LINE__,                      \
     90                          ## __VA_ARGS__)
     91 
     92 #else
     93      #ifdef TEST_LOG
     94        #define D(fmt, ...) fprintf(stderr, "venc_test Debug %s::%d "fmt"\n",   \
     95                             __FUNCTION__, __LINE__,                     \
     96                             ## __VA_ARGS__)
     97 
     98      /// Error message macro
     99       #define E(fmt, ...) fprintf(stderr, "venc_test Error %s::%d "fmt"\n", \
    100                             __FUNCTION__, __LINE__,                   \
    101                             ## __VA_ARGS__)
    102      #else
    103       #define D(fmt, ...)
    104       #define E(fmt, ...)
    105          #endif
    106 
    107 #endif
    108 
    109 //////////////////////////
    110 // CONSTANTS
    111 //////////////////////////
    112 static const int MAX_MSG = 100;
    113 //#warning do not hardcode these use port definition
    114 static const int PORT_INDEX_IN = 0;
    115 static const int PORT_INDEX_OUT = 1;
    116 
    117 static const int NUM_IN_BUFFERS = 10;
    118 static const int NUM_OUT_BUFFERS = 10;
    119 
    120 unsigned int num_in_buffers = 0;
    121 unsigned int num_out_buffers = 0;
    122 
    123 //////////////////////////
    124 /* MPEG4 profile and level table*/
    125 static const unsigned int mpeg4_profile_level_table[][5]=
    126 {
    127     /*max mb per frame, max mb per sec, max bitrate, level, profile*/
    128     {99,1485,64000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileSimple},
    129     {99,1485,64000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileSimple},
    130     {396,5940,128000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileSimple},
    131     {396,11880,384000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileSimple},
    132     {1200,36000,4000000,OMX_VIDEO_MPEG4Level4a,OMX_VIDEO_MPEG4ProfileSimple},
    133     {1620,40500,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple},
    134     {3600,108000,12000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple},
    135     {0,0,0,0,0},
    136 
    137     {99,1485,128000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
    138     {99,1485,128000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
    139     {396,5940,384000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
    140     {396,11880,768000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
    141     {792,23760,3000000,OMX_VIDEO_MPEG4Level4,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
    142     {1620,48600,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
    143     {0,0,0,0,0},
    144 };
    145 
    146 /* H264 profile and level table*/
    147 static const unsigned int h264_profile_level_table[][5]=
    148 {
    149      /*max mb per frame, max mb per sec, max bitrate, level, profile*/
    150     {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileBaseline},
    151     {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileBaseline},
    152     {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileBaseline},
    153     {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileBaseline},
    154     {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileBaseline},
    155     {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileBaseline},
    156     {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileBaseline},
    157     {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileBaseline},
    158     {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileBaseline},
    159     {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileBaseline},
    160     {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileBaseline},
    161     {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileBaseline},
    162     {0,0,0,0,0},
    163 
    164     {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileHigh},
    165     {99,1485,160000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileHigh},
    166     {396,3000,240000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileHigh},
    167     {396,6000,480000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileHigh},
    168     {396,11880,960000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileHigh},
    169     {396,11880,2500000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileHigh},
    170     {792,19800,5000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileHigh},
    171     {1620,20250,5000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileHigh},
    172     {1620,40500,12500000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileHigh},
    173     {3600,108000,17500000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileHigh},
    174     {5120,216000,25000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileHigh},
    175     {8192,245760,25000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileHigh},
    176     {0,0,0,0,0},
    177 
    178     {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileMain},
    179     {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileMain},
    180     {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileMain},
    181     {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileMain},
    182     {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileMain},
    183     {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileMain},
    184     {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileMain},
    185     {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileMain},
    186     {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileMain},
    187     {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileMain},
    188     {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileMain},
    189     {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileMain},
    190     {0,0,0,0,0}
    191 
    192 };
    193 
    194 /* H263 profile and level table*/
    195 static const unsigned int h263_profile_level_table[][5]=
    196 {
    197     /*max mb per frame, max mb per sec, max bitrate, level, profile*/
    198     {99,1485,64000,OMX_VIDEO_H263Level10,OMX_VIDEO_H263ProfileBaseline},
    199     {396,5940,128000,OMX_VIDEO_H263Level20,OMX_VIDEO_H263ProfileBaseline},
    200     {396,11880,384000,OMX_VIDEO_H263Level30,OMX_VIDEO_H263ProfileBaseline},
    201     {396,11880,2048000,OMX_VIDEO_H263Level40,OMX_VIDEO_H263ProfileBaseline},
    202     {99,1485,128000,OMX_VIDEO_H263Level45,OMX_VIDEO_H263ProfileBaseline},
    203     {396,19800,4096000,OMX_VIDEO_H263Level50,OMX_VIDEO_H263ProfileBaseline},
    204     {810,40500,8192000,OMX_VIDEO_H263Level60,OMX_VIDEO_H263ProfileBaseline},
    205     {1620,81000,16384000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline},
    206     {0,0,0,0,0}
    207 };
    208 
    209 #define Log2(number, power)  { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) &&  power < 16) { temp >>=0x1; power++; } }
    210 #define FractionToQ16(q,num,den) { OMX_U32 power; Log2(den,power); q = num << (16 - power); }
    211 
    212 //////////////////////////
    213 // TYPES
    214 //////////////////////////
    215 struct ProfileType
    216 {
    217    OMX_VIDEO_CODINGTYPE eCodec;
    218    OMX_VIDEO_MPEG4LEVELTYPE eLevel;
    219    OMX_VIDEO_CONTROLRATETYPE eControlRate;
    220    OMX_VIDEO_AVCSLICEMODETYPE eSliceMode;
    221    OMX_U32 nFrameWidth;
    222    OMX_U32 nFrameHeight;
    223    OMX_U32 nFrameBytes;
    224 #ifdef BADGER
    225    OMX_U32 nFramestride;
    226    OMX_U32 nFrameScanlines;
    227    OMX_U32 nFrameRead;
    228 #endif
    229    OMX_U32 nBitrate;
    230    float nFramerate;
    231    char* cInFileName;
    232    char* cOutFileName;
    233    OMX_U32 nUserProfile;
    234 };
    235 
    236 enum MsgId
    237 {
    238    MSG_ID_OUTPUT_FRAME_DONE,
    239    MSG_ID_INPUT_FRAME_DONE,
    240    MSG_ID_MAX
    241 };
    242 union MsgData
    243 {
    244    struct
    245    {
    246       OMX_BUFFERHEADERTYPE* pBuffer;
    247    } sBitstreamData;
    248 };
    249 struct Msg
    250 {
    251    MsgId id;
    252    MsgData data;
    253 };
    254 struct MsgQ
    255 {
    256    Msg q[MAX_MSG];
    257    int head;
    258    int size;
    259 };
    260 
    261 enum Mode
    262 {
    263    MODE_PREVIEW,
    264    MODE_DISPLAY,
    265    MODE_PROFILE,
    266    MODE_FILE_ENCODE,
    267    MODE_LIVE_ENCODE
    268 };
    269 
    270 enum ResyncMarkerType
    271 {
    272    RESYNC_MARKER_NONE,     ///< No resync marker
    273    RESYNC_MARKER_BYTE,     ///< BYTE Resync marker for MPEG4, H.264
    274    RESYNC_MARKER_MB,       ///< MB resync marker for MPEG4, H.264
    275    RESYNC_MARKER_GOB       ///< GOB resync marker for H.263
    276 };
    277 
    278 union DynamicConfigData
    279 {
    280    OMX_VIDEO_CONFIG_BITRATETYPE bitrate;
    281    OMX_CONFIG_FRAMERATETYPE framerate;
    282    QOMX_VIDEO_INTRAPERIODTYPE intraperiod;
    283    OMX_CONFIG_INTRAREFRESHVOPTYPE intravoprefresh;
    284    OMX_CONFIG_ROTATIONTYPE rotation;
    285    float f_framerate;
    286 };
    287 
    288 struct DynamicConfig
    289 {
    290    bool pending;
    291    unsigned frame_num;
    292    OMX_INDEXTYPE config_param;
    293    union DynamicConfigData config_data;
    294 };
    295 
    296 #ifdef USE_ION
    297 struct enc_ion
    298 {
    299    int ion_device_fd;
    300    struct ion_allocation_data alloc_data;
    301    struct ion_fd_data ion_alloc_fd;
    302 };
    303 #endif
    304 
    305 //////////////////////////
    306 // MODULE VARS
    307 //////////////////////////
    308 static pthread_mutex_t m_mutex;
    309 static pthread_cond_t m_signal;
    310 static MsgQ m_sMsgQ;
    311 
    312 //#warning determine how many buffers we really have
    313 OMX_STATETYPE m_eState = OMX_StateInvalid;
    314 OMX_COMPONENTTYPE m_sComponent;
    315 OMX_HANDLETYPE m_hHandle = NULL;
    316 OMX_BUFFERHEADERTYPE* m_pOutBuffers[NUM_OUT_BUFFERS] = {NULL};
    317 OMX_BUFFERHEADERTYPE* m_pInBuffers[NUM_IN_BUFFERS] = {NULL};
    318 OMX_BOOL m_bInFrameFree[NUM_IN_BUFFERS];
    319 
    320 ProfileType m_sProfile;
    321 
    322 static int m_nFramePlay = 0;
    323 static int m_eMode = MODE_PREVIEW;
    324 static int m_nInFd = -1;
    325 static int m_nOutFd = -1;
    326 static int m_nTimeStamp = 0;
    327 static int m_nFrameIn = 0; // frames pushed to encoder
    328 static int m_nFrameOut = 0; // frames returned by encoder
    329 static int m_nAVCSliceMode = 0;
    330 static bool m_bWatchDogKicked = false;
    331 FILE  *m_pDynConfFile = NULL;
    332 static struct DynamicConfig dynamic_config;
    333 
    334 /* Statistics Logging */
    335 static long long tot_bufsize = 0;
    336 int ebd_cnt=0, fbd_cnt=0;
    337 
    338 #ifdef USE_ION
    339 static const char* PMEM_DEVICE = "/dev/ion";
    340 #elif MAX_RES_720P
    341 static const char* PMEM_DEVICE = "/dev/pmem_adsp";
    342 #elif MAX_RES_1080P_EBI
    343 static const char* PMEM_DEVICE  = "/dev/pmem_adsp";
    344 #elif MAX_RES_1080P
    345 static const char* PMEM_DEVICE = "/dev/pmem_smipool";
    346 #else
    347 #error PMEM_DEVICE cannot be determined.
    348 #endif
    349 
    350 #ifdef USE_ION
    351 struct enc_ion ion_data;
    352 #endif
    353 //////////////////////////
    354 // MODULE FUNCTIONS
    355 //////////////////////////
    356 
    357 void* PmemMalloc(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO* pMem, int nSize)
    358 {
    359    void *pvirt = NULL;
    360    int rc = 0;
    361 
    362    if (!pMem)
    363       return NULL;
    364 
    365 #ifdef USE_ION
    366   ion_data.ion_device_fd = open (PMEM_DEVICE,O_RDONLY);
    367   if(ion_data.ion_device_fd < 0)
    368   {
    369       E("\nERROR: ION Device open() Failed");
    370       return NULL;
    371   }
    372   nSize = (nSize + 4095) & (~4095);
    373   ion_data.alloc_data.len = nSize;
    374   ion_data.alloc_data.heap_id_mask = 0x1 << ION_CP_MM_HEAP_ID;
    375   ion_data.alloc_data.align = 4096;
    376   ion_data.alloc_data.flags = 0;
    377 
    378   rc = ioctl(ion_data.ion_device_fd,ION_IOC_ALLOC,&ion_data.alloc_data);
    379   if(rc || !ion_data.alloc_data.handle) {
    380          E("\n ION ALLOC memory failed ");
    381          ion_data.alloc_data.handle=NULL;
    382          return NULL;
    383   }
    384 
    385   ion_data.ion_alloc_fd.handle = ion_data.alloc_data.handle;
    386   rc = ioctl(ion_data.ion_device_fd,ION_IOC_MAP,&ion_data.ion_alloc_fd);
    387   if(rc) {
    388         E("\n ION MAP failed ");
    389         ion_data.ion_alloc_fd.fd =-1;
    390         ion_data.ion_alloc_fd.fd =-1;
    391         return NULL;
    392   }
    393   pMem->pmem_fd = ion_data.ion_alloc_fd.fd;
    394 #else
    395    pMem->pmem_fd = open(PMEM_DEVICE, O_RDWR);
    396    if ((int)(pMem->pmem_fd) < 0)
    397       return NULL;
    398    nSize = (nSize + 4095) & (~4095);
    399 #endif
    400    pMem->offset = 0;
    401    pvirt = mmap(NULL, nSize,
    402                 PROT_READ | PROT_WRITE,
    403                 MAP_SHARED, pMem->pmem_fd, pMem->offset);
    404    if (pvirt == (void*) MAP_FAILED)
    405    {
    406       close(pMem->pmem_fd);
    407       pMem->pmem_fd = -1;
    408 #ifdef USE_ION
    409     if(ioctl(ion_data.ion_device_fd,ION_IOC_FREE,
    410        &ion_data.alloc_data.handle)) {
    411       E("ion recon buffer free failed");
    412     }
    413     ion_data.alloc_data.handle = NULL;
    414     ion_data.ion_alloc_fd.fd =-1;
    415     close(ion_data.ion_device_fd);
    416     ion_data.ion_device_fd =-1;
    417 #endif
    418       return NULL;
    419    }
    420    D("allocated pMem->fd = %d pvirt=0x%x, pMem->phys=0x%x, size = %d", pMem->pmem_fd,
    421        pvirt, pMem->offset, nSize);
    422    return pvirt;
    423 }
    424 
    425 int PmemFree(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO* pMem, void* pvirt, int nSize)
    426 {
    427    if (!pMem || !pvirt)
    428       return -1;
    429 
    430    nSize = (nSize + 4095) & (~4095);
    431    munmap(pvirt, nSize);
    432    close(pMem->pmem_fd);
    433    pMem->pmem_fd = -1;
    434 #ifdef USE_ION
    435    if(ioctl(ion_data.ion_device_fd,ION_IOC_FREE,
    436          &ion_data.alloc_data.handle)) {
    437         E("ion recon buffer free failed");
    438    }
    439    ion_data.alloc_data.handle = NULL;
    440    ion_data.ion_alloc_fd.fd =-1;
    441    close(ion_data.ion_device_fd);
    442    ion_data.ion_device_fd =-1;
    443 #endif
    444    return 0;
    445 }
    446 void PrintFramePackArrangement(OMX_QCOM_FRAME_PACK_ARRANGEMENT framePackingArrangement)
    447 {
    448     printf("id (%d)\n",
    449            framePackingArrangement.id);
    450     printf("cancel_flag (%d)\n",
    451            framePackingArrangement.cancel_flag);
    452     printf("type (%d)\n",
    453            framePackingArrangement.type);
    454     printf("quincunx_sampling_flag (%d)\n",
    455            framePackingArrangement.quincunx_sampling_flag);
    456    printf("content_interpretation_type (%d)\n",
    457           framePackingArrangement.content_interpretation_type);
    458    printf("spatial_flipping_flag (%d)\n",
    459           framePackingArrangement.spatial_flipping_flag);
    460    printf("frame0_flipped_flag (%d)\n",
    461           framePackingArrangement.frame0_flipped_flag);
    462    printf("field_views_flag (%d)\n",
    463           framePackingArrangement.field_views_flag);
    464    printf("current_frame_is_frame0_flag (%d)\n",
    465           framePackingArrangement.current_frame_is_frame0_flag);
    466    printf("frame0_self_contained_flag (%d)\n",
    467           framePackingArrangement.frame0_self_contained_flag);
    468    printf("frame1_self_contained_flag (%d)\n",
    469           framePackingArrangement.frame1_self_contained_flag);
    470    printf("frame0_grid_position_x (%d)\n",
    471           framePackingArrangement.frame0_grid_position_x);
    472    printf("frame0_grid_position_y (%d)\n",
    473           framePackingArrangement.frame0_grid_position_y);
    474    printf("frame1_grid_position_x (%d)\n",
    475           framePackingArrangement.frame1_grid_position_x);
    476    printf("frame1_grid_position_y (%d)\n",
    477           framePackingArrangement.frame1_grid_position_y);
    478    printf("reserved_byte (%d)\n",
    479           framePackingArrangement.reserved_byte);
    480    printf("repetition_period (%d)\n",
    481           framePackingArrangement.repetition_period);
    482    printf("extension_flag (%d)\n",
    483           framePackingArrangement.extension_flag);
    484 }
    485 void SetState(OMX_STATETYPE eState)
    486 {
    487 #define GOTO_STATE(eState)                      \
    488    case eState:                                 \
    489       {                                         \
    490          D("Going to state " # eState"...");            \
    491          OMX_SendCommand(m_hHandle,                     \
    492                          OMX_CommandStateSet,           \
    493                          (OMX_U32) eState,              \
    494                          NULL);                         \
    495          while (m_eState != eState)                     \
    496          {                                              \
    497             sleep(1);                               \
    498          }                                              \
    499          D("Now in state " # eState);                   \
    500          break;                                         \
    501       }
    502 
    503    switch (eState)
    504    {
    505       GOTO_STATE(OMX_StateLoaded);
    506       GOTO_STATE(OMX_StateIdle);
    507       GOTO_STATE(OMX_StateExecuting);
    508       GOTO_STATE(OMX_StateInvalid);
    509       GOTO_STATE(OMX_StateWaitForResources);
    510       GOTO_STATE(OMX_StatePause);
    511    }
    512 }
    513 ////////////////////////////////////////////////////////////////////////////////
    514 OMX_ERRORTYPE ConfigureEncoder()
    515 {
    516    OMX_ERRORTYPE result = OMX_ErrorNone;
    517    unsigned const int *profile_tbl = (unsigned int const *)mpeg4_profile_level_table;
    518    OMX_U32 mb_per_sec, mb_per_frame;
    519    bool profile_level_found = false;
    520    OMX_U32 eProfile,eLevel;
    521 
    522    OMX_PARAM_PORTDEFINITIONTYPE portdef; // OMX_IndexParamPortDefinition
    523 #ifdef QCOM_EXT
    524       OMX_QCOM_PARAM_PORTDEFINITIONTYPE qPortDefnType;
    525 #endif
    526    portdef.nPortIndex = (OMX_U32) 0; // input
    527    result = OMX_GetParameter(m_hHandle,
    528                              OMX_IndexParamPortDefinition,
    529                              &portdef);
    530    E("\n OMX_IndexParamPortDefinition Get Paramter on input port");
    531    CHK(result);
    532    portdef.format.video.nFrameWidth = m_sProfile.nFrameWidth;
    533    portdef.format.video.nFrameHeight = m_sProfile.nFrameHeight;
    534 
    535    E ("\n Height %d width %d bit rate %d",portdef.format.video.nFrameHeight
    536       ,portdef.format.video.nFrameWidth,portdef.format.video.nBitrate);
    537    result = OMX_SetParameter(m_hHandle,
    538                              OMX_IndexParamPortDefinition,
    539                              &portdef);
    540    E("\n OMX_IndexParamPortDefinition Set Paramter on input port");
    541    CHK(result);
    542    // once more to get proper buffer size
    543    result = OMX_GetParameter(m_hHandle,
    544                              OMX_IndexParamPortDefinition,
    545                              &portdef);
    546    E("\n OMX_IndexParamPortDefinition Get Paramter on input port, 2nd pass");
    547    CHK(result);
    548    // update size accordingly
    549    m_sProfile.nFrameBytes = portdef.nBufferSize;
    550    portdef.nPortIndex = (OMX_U32) 1; // output
    551    result = OMX_GetParameter(m_hHandle,
    552                              OMX_IndexParamPortDefinition,
    553                              &portdef);
    554    E("\n OMX_IndexParamPortDefinition Get Paramter on output port");
    555    CHK(result);
    556    portdef.format.video.nFrameWidth = m_sProfile.nFrameWidth;
    557    portdef.format.video.nFrameHeight = m_sProfile.nFrameHeight;
    558    portdef.format.video.nBitrate = m_sProfile.nBitrate;
    559    FractionToQ16(portdef.format.video.xFramerate,(int) (m_sProfile.nFramerate * 2),2);
    560    result = OMX_SetParameter(m_hHandle,
    561                              OMX_IndexParamPortDefinition,
    562                              &portdef);
    563    E("\n OMX_IndexParamPortDefinition Set Paramter on output port");
    564    CHK(result);
    565 
    566 #ifdef QCOM_EXT
    567 
    568 qPortDefnType.nPortIndex = PORT_INDEX_IN;
    569 qPortDefnType.nMemRegion = OMX_QCOM_MemRegionEBI1;
    570 qPortDefnType.nSize = sizeof(OMX_QCOM_PARAM_PORTDEFINITIONTYPE);
    571 
    572 result = OMX_SetParameter(m_hHandle,
    573                              (OMX_INDEXTYPE)OMX_QcomIndexPortDefn,
    574                              &qPortDefnType);
    575 
    576 #endif
    577    if (!m_sProfile.nUserProfile) // profile not set by user, go ahead with table calculation
    578    {
    579    //validate the ht,width,fps,bitrate and set the appropriate profile and level
    580    if(m_sProfile.eCodec == OMX_VIDEO_CodingMPEG4)
    581    {
    582      profile_tbl = (unsigned int const *)mpeg4_profile_level_table;
    583    }
    584    else if(m_sProfile.eCodec == OMX_VIDEO_CodingAVC)
    585    {
    586      profile_tbl = (unsigned int const *)h264_profile_level_table;
    587    }
    588    else if(m_sProfile.eCodec == OMX_VIDEO_CodingH263)
    589    {
    590      profile_tbl = (unsigned int const *)h263_profile_level_table;
    591    }
    592 
    593    mb_per_frame = ((m_sProfile.nFrameHeight+15)>>4)*
    594                 ((m_sProfile.nFrameWidth+15)>>4);
    595 
    596    mb_per_sec = mb_per_frame*(m_sProfile.nFramerate);
    597 
    598    do{
    599       if(mb_per_frame <= (int)profile_tbl[0])
    600       {
    601           if(mb_per_sec <= (int)profile_tbl[1])
    602           {
    603             if(m_sProfile.nBitrate <= (int)profile_tbl[2])
    604             {
    605               eLevel = (int)profile_tbl[3];
    606               eProfile = (int)profile_tbl[4];
    607               E("\n profile/level found: %d/%d\n",eProfile/eLevel);
    608               profile_level_found = true;
    609               break;
    610             }
    611           }
    612       }
    613       profile_tbl = profile_tbl + 5;
    614    }while(profile_tbl[0] != 0);
    615 
    616    if ( profile_level_found != true )
    617    {
    618      E("\n Error: Unsupported profile/level\n");
    619      return OMX_ErrorNone;
    620    }
    621    }
    622    else // Profile set by user!
    623    {
    624       eProfile = m_sProfile.nUserProfile;
    625       eLevel = 0;
    626    }
    627    if (m_sProfile.eCodec == OMX_VIDEO_CodingH263)
    628    {
    629       D("Configuring H263...");
    630 
    631       OMX_VIDEO_PARAM_H263TYPE h263;
    632       result = OMX_GetParameter(m_hHandle,
    633                                 OMX_IndexParamVideoH263,
    634                                 &h263);
    635       CHK(result);
    636       h263.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
    637       h263.nPFrames = m_sProfile.nFramerate * 2 - 1; // intra period
    638       h263.nBFrames = 0;
    639       h263.eProfile = (OMX_VIDEO_H263PROFILETYPE)eProfile;
    640       h263.eLevel = (OMX_VIDEO_H263LEVELTYPE)eLevel;
    641       h263.bPLUSPTYPEAllowed = OMX_FALSE;
    642       h263.nAllowedPictureTypes = 2;
    643       h263.bForceRoundingTypeToZero = OMX_TRUE;
    644       h263.nPictureHeaderRepetition = 0;
    645       h263.nGOBHeaderInterval = 1;
    646       result = OMX_SetParameter(m_hHandle,
    647                                 OMX_IndexParamVideoH263,
    648                                 &h263);
    649    }
    650    else
    651    {
    652       D("Configuring MP4/H264...");
    653 
    654       OMX_VIDEO_PARAM_PROFILELEVELTYPE profileLevel; // OMX_IndexParamVideoProfileLevelCurrent
    655       profileLevel.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
    656       profileLevel.eProfile = eProfile;
    657       profileLevel.eLevel =  eLevel;
    658       result = OMX_SetParameter(m_hHandle,
    659                                 OMX_IndexParamVideoProfileLevelCurrent,
    660                                 &profileLevel);
    661       E("\n OMX_IndexParamVideoProfileLevelCurrent Set Paramter port");
    662       CHK(result);
    663       //profileLevel.eLevel = (OMX_U32) m_sProfile.eLevel;
    664       result = OMX_GetParameter(m_hHandle,
    665                                 OMX_IndexParamVideoProfileLevelCurrent,
    666                                 &profileLevel);
    667       E("\n OMX_IndexParamVideoProfileLevelCurrent Get Paramter port");
    668       D ("\n Profile = %d level = %d",profileLevel.eProfile,profileLevel.eLevel);
    669       CHK(result);
    670 
    671         if (m_sProfile.eCodec == OMX_VIDEO_CodingMPEG4)
    672         {
    673         OMX_VIDEO_PARAM_MPEG4TYPE mp4; // OMX_IndexParamVideoMpeg4
    674        result = OMX_GetParameter(m_hHandle,
    675                                  OMX_IndexParamVideoMpeg4,
    676                                  &mp4);
    677        CHK(result);
    678        mp4.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
    679        mp4.nTimeIncRes = 1000;
    680        result = OMX_SetParameter(m_hHandle,
    681                                  OMX_IndexParamVideoMpeg4,
    682                                  &mp4);
    683        CHK(result);
    684          }
    685    }
    686    if (m_sProfile.eCodec == OMX_VIDEO_CodingAVC)
    687    {
    688 #if 1
    689 /////////////C A B A C ///A N D/////D E B L O C K I N G /////////////////
    690 
    691       OMX_VIDEO_PARAM_AVCTYPE avcdata;
    692       avcdata.nPortIndex = (OMX_U32)PORT_INDEX_OUT;
    693       result = OMX_GetParameter(m_hHandle,
    694                                 OMX_IndexParamVideoAvc,
    695                                 &avcdata);
    696       CHK(result);
    697 // TEST VALUES (CHANGE FOR DIFF CONFIG's)
    698     avcdata.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
    699 //      avcdata.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterDisable;
    700 //    avcdata.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterDisableSliceBoundary;
    701    avcdata.bEntropyCodingCABAC = OMX_FALSE;
    702 //   avcdata.bEntropyCodingCABAC = OMX_TRUE;
    703    avcdata.nCabacInitIdc = 1;
    704 ///////////////////////////////////////////////
    705 
    706       result = OMX_SetParameter(m_hHandle,
    707                                 OMX_IndexParamVideoAvc,
    708                                 &avcdata);
    709       CHK(result);
    710 
    711 /////////////C A B A C ///A N D/////D E B L O C K I N G /////////////////
    712 #endif
    713    }
    714 
    715    OMX_VIDEO_PARAM_BITRATETYPE bitrate; // OMX_IndexParamVideoBitrate
    716    bitrate.nPortIndex = (OMX_U32)PORT_INDEX_OUT;
    717    result = OMX_GetParameter(m_hHandle,
    718                              OMX_IndexParamVideoBitrate,
    719                              &bitrate);
    720    E("\n OMX_IndexParamVideoBitrate Get Paramter port");
    721    CHK(result);
    722    bitrate.eControlRate = m_sProfile.eControlRate;
    723    bitrate.nTargetBitrate = m_sProfile.nBitrate;
    724    result = OMX_SetParameter(m_hHandle,
    725                              OMX_IndexParamVideoBitrate,
    726                              &bitrate);
    727    E("\n OMX_IndexParamVideoBitrate Set Paramter port");
    728    CHK(result);
    729 
    730    OMX_VIDEO_PARAM_PORTFORMATTYPE framerate; // OMX_IndexParamVidePortFormat
    731    framerate.nPortIndex = 0;
    732    result = OMX_GetParameter(m_hHandle,
    733                              OMX_IndexParamVideoPortFormat,
    734                              &framerate);
    735    E("\n OMX_IndexParamVideoPortFormat Get Paramter port");
    736    CHK(result);
    737    FractionToQ16(framerate.xFramerate,(int) (m_sProfile.nFramerate * 2),2);
    738    result = OMX_SetParameter(m_hHandle,
    739                              OMX_IndexParamVideoPortFormat,
    740                              &framerate);
    741    E("\n OMX_IndexParamVideoPortFormat Set Paramter port");
    742    CHK(result);
    743 
    744 #if 1
    745 ///////////////////I N T R A P E R I O D ///////////////////
    746 
    747       QOMX_VIDEO_INTRAPERIODTYPE intra;
    748 
    749       intra.nPortIndex = (OMX_U32) PORT_INDEX_OUT; // output
    750       result = OMX_GetConfig(m_hHandle,
    751                              (OMX_INDEXTYPE) QOMX_IndexConfigVideoIntraperiod,
    752                              (OMX_PTR) &intra);
    753 
    754       if (result == OMX_ErrorNone)
    755       {
    756          intra.nPFrames = (OMX_U32) (2 * m_sProfile.nFramerate - 1); //setting I
    757                                                                      //frame interval to
    758                                                                      //2 x framerate
    759          intra.nIDRPeriod = 1; //every I frame is an IDR
    760          intra.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
    761          result = OMX_SetConfig(m_hHandle,
    762                                 (OMX_INDEXTYPE) QOMX_IndexConfigVideoIntraperiod,
    763                                 (OMX_PTR) &intra);
    764       }
    765       else
    766       {
    767          E("failed to get state", 0, 0, 0);
    768       }
    769 
    770 
    771 ///////////////////I N T R A P E R I O D ///////////////////
    772 #endif
    773 
    774 #if 1
    775 ///////////////////E R R O R C O R R E C T I O N ///////////////////
    776 
    777       ResyncMarkerType eResyncMarkerType = RESYNC_MARKER_NONE;
    778       unsigned long int nResyncMarkerSpacing = 0;
    779       OMX_BOOL enableHEC = OMX_FALSE;
    780 
    781 //For Testing ONLY
    782    if (m_sProfile.eCodec == OMX_VIDEO_CodingMPEG4)
    783    {
    784 // MPEG4
    785 //      eResyncMarkerType = RESYNC_MARKER_BYTE;
    786 //      nResyncMarkerSpacing = 1920;
    787       eResyncMarkerType = RESYNC_MARKER_MB;
    788       nResyncMarkerSpacing = 50;
    789       enableHEC = OMX_TRUE;
    790    }
    791    else if (m_sProfile.eCodec == OMX_VIDEO_CodingH263)
    792    {
    793 //H263
    794       eResyncMarkerType = RESYNC_MARKER_GOB;
    795       nResyncMarkerSpacing = 0;
    796    }
    797    else if (m_sProfile.eCodec == OMX_VIDEO_CodingAVC)
    798    {
    799 //H264
    800 //      eResyncMarkerType = RESYNC_MARKER_BYTE;
    801 //      nResyncMarkerSpacing = 1920;
    802 
    803       //nResyncMarkerSpacing sets the slice size in venc_set_multislice_cfg
    804       //
    805       //As of 9/24/10, it is known that the firmware has a bitstream
    806       //corruption issue when RateControl and multislice are enabled for 720P
    807       //So, disabling multislice for 720P when ratecontrol is enabled until
    808       //the firmware issue is resolved.
    809 
    810       if ( ( (m_sProfile.nFrameWidth == 1280) && (m_sProfile.nFrameHeight = 720) ) &&
    811            (m_sProfile.eControlRate  != OMX_Video_ControlRateDisable) )
    812       {
    813          eResyncMarkerType = RESYNC_MARKER_NONE;
    814          nResyncMarkerSpacing = 0;
    815       }
    816       else
    817       {
    818          eResyncMarkerType = RESYNC_MARKER_MB;
    819           nResyncMarkerSpacing = 50;
    820       }
    821    }
    822 
    823    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrection; //OMX_IndexParamVideoErrorCorrection
    824    errorCorrection.nPortIndex = (OMX_U32) PORT_INDEX_OUT; // output
    825    result = OMX_GetParameter(m_hHandle,
    826                              (OMX_INDEXTYPE) OMX_IndexParamVideoErrorCorrection,
    827                              (OMX_PTR) &errorCorrection);
    828 
    829    errorCorrection.bEnableRVLC = OMX_FALSE;
    830    errorCorrection.bEnableDataPartitioning = OMX_FALSE;
    831 
    832       if ((eResyncMarkerType == RESYNC_MARKER_BYTE) &&
    833          (m_sProfile.eCodec == OMX_VIDEO_CodingMPEG4)){
    834             errorCorrection.bEnableResync = OMX_TRUE;
    835             errorCorrection.nResynchMarkerSpacing = nResyncMarkerSpacing;
    836             errorCorrection.bEnableHEC = enableHEC;
    837             }
    838       else if ((eResyncMarkerType == RESYNC_MARKER_BYTE) &&
    839                (m_sProfile.eCodec == OMX_VIDEO_CodingAVC)){
    840          errorCorrection.bEnableResync = OMX_TRUE;
    841          errorCorrection.nResynchMarkerSpacing = nResyncMarkerSpacing;
    842          }
    843       else if ((eResyncMarkerType == RESYNC_MARKER_GOB) &&
    844                (m_sProfile.eCodec == OMX_VIDEO_CodingH263)){
    845          errorCorrection.bEnableResync = OMX_FALSE;
    846          errorCorrection.nResynchMarkerSpacing = nResyncMarkerSpacing;
    847          errorCorrection.bEnableDataPartitioning = OMX_TRUE;
    848          }
    849 
    850       result = OMX_SetParameter(m_hHandle,
    851                             (OMX_INDEXTYPE) OMX_IndexParamVideoErrorCorrection,
    852                             (OMX_PTR) &errorCorrection);
    853    CHK(result);
    854 
    855       if (eResyncMarkerType == RESYNC_MARKER_MB){
    856          if (m_sProfile.eCodec == OMX_VIDEO_CodingAVC){
    857             OMX_VIDEO_PARAM_AVCTYPE avcdata;
    858             avcdata.nPortIndex = (OMX_U32) PORT_INDEX_OUT; // output
    859             result = OMX_GetParameter(m_hHandle,
    860                                       OMX_IndexParamVideoAvc,
    861                                       (OMX_PTR) &avcdata);
    862             CHK(result);
    863             if (result == OMX_ErrorNone)
    864             {
    865                avcdata.nSliceHeaderSpacing = nResyncMarkerSpacing;
    866                result = OMX_SetParameter(m_hHandle,
    867                                          OMX_IndexParamVideoAvc,
    868                                          (OMX_PTR) &avcdata);
    869                CHK(result);
    870 
    871             }
    872          }
    873          else if(m_sProfile.eCodec == OMX_VIDEO_CodingMPEG4){
    874             OMX_VIDEO_PARAM_MPEG4TYPE mp4;
    875             mp4.nPortIndex = (OMX_U32) PORT_INDEX_OUT; // output
    876             result = OMX_GetParameter(m_hHandle,
    877                                       OMX_IndexParamVideoMpeg4,
    878                                       (OMX_PTR) &mp4);
    879             CHK(result);
    880 
    881             if (result == OMX_ErrorNone)
    882             {
    883                mp4.nSliceHeaderSpacing = nResyncMarkerSpacing;
    884                result = OMX_SetParameter(m_hHandle,
    885                                          OMX_IndexParamVideoMpeg4,
    886                                          (OMX_PTR) &mp4);
    887                CHK(result);
    888             }
    889          }
    890          }
    891 
    892 ///////////////////E R R O R C O R R E C T I O N ///////////////////
    893 #endif
    894 
    895 #if 1
    896 ///////////////////I N T R A R E F R E S H///////////////////
    897       bool bEnableIntraRefresh = OMX_TRUE;
    898 
    899       if (result == OMX_ErrorNone)
    900       {
    901          OMX_VIDEO_PARAM_INTRAREFRESHTYPE ir; // OMX_IndexParamVideoIntraRefresh
    902          ir.nPortIndex = (OMX_U32) PORT_INDEX_OUT; // output
    903          result = OMX_GetParameter(m_hHandle,
    904                                    OMX_IndexParamVideoIntraRefresh,
    905                                    (OMX_PTR) &ir);
    906          if (result == OMX_ErrorNone)
    907          {
    908             if (bEnableIntraRefresh)
    909             {
    910                ir.eRefreshMode = OMX_VIDEO_IntraRefreshCyclic;
    911                ir.nCirMBs = 5;
    912                result = OMX_SetParameter(m_hHandle,
    913                                          OMX_IndexParamVideoIntraRefresh,
    914                                          (OMX_PTR) &ir);
    915                CHK(result);
    916             }
    917          }
    918       }
    919 #endif
    920 #if 1
    921 ///////////////////FRAMEPACKING DATA///////////////////
    922       OMX_QCOM_FRAME_PACK_ARRANGEMENT framePackingArrangement;
    923       FILE *m_pConfigFile;
    924       char m_configFilename [128] = "/data/configFile.cfg";
    925       memset(&framePackingArrangement, 0, sizeof(framePackingArrangement));
    926       m_pConfigFile = fopen(m_configFilename, "r");
    927       if (m_pConfigFile != NULL)
    928       {
    929          //read all frame packing data
    930          framePackingArrangement.nPortIndex = (OMX_U32)PORT_INDEX_OUT;
    931          int totalSizeToRead = FRAME_PACK_SIZE * sizeof(OMX_U32);
    932          char *pFramePack = (char *) &(framePackingArrangement.id);
    933          while ( ( (fscanf(m_pConfigFile, "%d", pFramePack)) != EOF ) &&
    934                  (totalSizeToRead != 0) )
    935          {
    936             //printf("Addr = %p, Value read = %d, sizeToRead remaining=%d\n",
    937             //       pFramePack, *pFramePack, totalSizeToRead);
    938             pFramePack += sizeof(OMX_U32);
    939             totalSizeToRead -= sizeof(OMX_U32);
    940          }
    941          //close the file.
    942          fclose(m_pConfigFile);
    943 
    944          printf("Frame Packing data from config file:\n");
    945          PrintFramePackArrangement(framePackingArrangement);
    946       }
    947       else
    948       {
    949          D("\n Config file does not exist or could not be opened.");
    950          //set the default values
    951          framePackingArrangement.nPortIndex = (OMX_U32)PORT_INDEX_OUT;
    952          framePackingArrangement.id = 123;
    953          framePackingArrangement.cancel_flag = false;
    954          framePackingArrangement.type = 3;
    955          framePackingArrangement.quincunx_sampling_flag = false;
    956          framePackingArrangement.content_interpretation_type = 0;
    957          framePackingArrangement.spatial_flipping_flag = true;
    958          framePackingArrangement.frame0_flipped_flag = false;
    959          framePackingArrangement.field_views_flag = false;
    960          framePackingArrangement.current_frame_is_frame0_flag = false;
    961          framePackingArrangement.frame0_self_contained_flag = true;
    962          framePackingArrangement.frame1_self_contained_flag = false;
    963          framePackingArrangement.frame0_grid_position_x = 3;
    964          framePackingArrangement.frame0_grid_position_y = 15;
    965          framePackingArrangement.frame1_grid_position_x = 11;
    966          framePackingArrangement.frame1_grid_position_y = 7;
    967          framePackingArrangement.reserved_byte = 0;
    968          framePackingArrangement.repetition_period = 16381;
    969          framePackingArrangement.extension_flag = false;
    970 
    971          printf("Frame Packing Defaults :\n");
    972          PrintFramePackArrangement(framePackingArrangement);
    973       }
    974       result = OMX_SetConfig(m_hHandle,
    975                 (OMX_INDEXTYPE)OMX_QcomIndexConfigVideoFramePackingArrangement,
    976                 (OMX_PTR) &framePackingArrangement);
    977       CHK(result);
    978 
    979 //////////////////////OMX_VIDEO_PARAM_INTRAREFRESHTYPE///////////////////
    980 #endif
    981 
    982    OMX_CONFIG_FRAMERATETYPE enc_framerate; // OMX_IndexConfigVideoFramerate
    983    enc_framerate.nPortIndex = (OMX_U32)PORT_INDEX_OUT;
    984    result = OMX_GetConfig(m_hHandle,
    985                           OMX_IndexConfigVideoFramerate,
    986                           &enc_framerate);
    987    CHK(result);
    988    FractionToQ16(enc_framerate.xEncodeFramerate,(int) (m_sProfile.nFramerate * 2),2);
    989    result = OMX_SetConfig(m_hHandle,
    990                           OMX_IndexConfigVideoFramerate,
    991                           &enc_framerate);
    992    CHK(result);
    993    return OMX_ErrorNone;
    994 }
    995 ////////////////////////////////////////////////////////////////////////////////
    996 void SendMessage(MsgId id, MsgData* data)
    997 {
    998    pthread_mutex_lock(&m_mutex);
    999    if (m_sMsgQ.size >= MAX_MSG)
   1000    {
   1001       E("main msg m_sMsgQ is full");
   1002       return;
   1003    }
   1004    m_sMsgQ.q[(m_sMsgQ.head + m_sMsgQ.size) % MAX_MSG].id = id;
   1005    if (data)
   1006       m_sMsgQ.q[(m_sMsgQ.head + m_sMsgQ.size) % MAX_MSG].data = *data;
   1007    ++m_sMsgQ.size;
   1008    pthread_cond_signal(&m_signal);
   1009    pthread_mutex_unlock(&m_mutex);
   1010 }
   1011 ////////////////////////////////////////////////////////////////////////////////
   1012 void PopMessage(Msg* msg)
   1013 {
   1014    pthread_mutex_lock(&m_mutex);
   1015    while (m_sMsgQ.size == 0)
   1016    {
   1017       pthread_cond_wait(&m_signal, &m_mutex);
   1018    }
   1019    *msg = m_sMsgQ.q[m_sMsgQ.head];
   1020    --m_sMsgQ.size;
   1021    m_sMsgQ.head = (m_sMsgQ.head + 1) % MAX_MSG;
   1022    pthread_mutex_unlock(&m_mutex);
   1023 }
   1024 ////////////////////////////////////////////////////////////////////////////////
   1025 OMX_ERRORTYPE EVT_CB(OMX_IN OMX_HANDLETYPE hComponent,
   1026                      OMX_IN OMX_PTR pAppData,
   1027                      OMX_IN OMX_EVENTTYPE eEvent,
   1028                      OMX_IN OMX_U32 nData1,
   1029                      OMX_IN OMX_U32 nData2,
   1030                      OMX_IN OMX_PTR pEventData)
   1031 {
   1032 #define SET_STATE(eState)                                   \
   1033    case eState:                                             \
   1034       {                                                     \
   1035          D("" # eState " complete");                        \
   1036          m_eState = eState;                                 \
   1037          break;                                             \
   1038       }
   1039 
   1040    if (eEvent == OMX_EventCmdComplete)
   1041    {
   1042       if ((OMX_COMMANDTYPE) nData1 == OMX_CommandStateSet)
   1043       {
   1044          switch ((OMX_STATETYPE) nData2)
   1045          {
   1046             SET_STATE(OMX_StateLoaded);
   1047             SET_STATE(OMX_StateIdle);
   1048             SET_STATE(OMX_StateExecuting);
   1049             SET_STATE(OMX_StateInvalid);
   1050             SET_STATE(OMX_StateWaitForResources);
   1051             SET_STATE(OMX_StatePause);
   1052          default:
   1053             E("invalid state %d", (int) nData2);
   1054           }
   1055       }
   1056    }
   1057 
   1058    else if (eEvent == OMX_EventError)
   1059    {
   1060       E("OMX_EventError");
   1061    }
   1062 
   1063    else
   1064    {
   1065       E("unexpected event %d", (int) eEvent);
   1066    }
   1067    return OMX_ErrorNone;
   1068 }
   1069 ////////////////////////////////////////////////////////////////////////////////
   1070 OMX_ERRORTYPE EBD_CB(OMX_IN OMX_HANDLETYPE hComponent,
   1071                      OMX_IN OMX_PTR pAppData,
   1072                      OMX_IN OMX_BUFFERHEADERTYPE* pBuffer)
   1073 {
   1074    D("Got EBD callback ts=%lld", pBuffer->nTimeStamp);
   1075 
   1076    for (int i = 0; i < num_in_buffers; i++)
   1077    {
   1078       // mark this buffer ready for use again
   1079       if (m_pInBuffers[i] == pBuffer)
   1080       {
   1081 
   1082          D("Marked input buffer idx %d as free, buf %p", i, pBuffer->pBuffer);
   1083          m_bInFrameFree[i] = OMX_TRUE;
   1084          break;
   1085       }
   1086    }
   1087 
   1088    if (m_eMode == MODE_LIVE_ENCODE)
   1089    {
   1090       CameraTest_ReleaseFrame(pBuffer->pBuffer,
   1091                               ((OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO*)pBuffer->pAppPrivate));
   1092    }
   1093    else
   1094    {
   1095       // wake up main thread and tell it to send next frame
   1096       MsgData data;
   1097       data.sBitstreamData.pBuffer = pBuffer;
   1098       SendMessage(MSG_ID_INPUT_FRAME_DONE,
   1099                   &data);
   1100 
   1101    }
   1102    return OMX_ErrorNone;
   1103 }
   1104 ////////////////////////////////////////////////////////////////////////////////
   1105 OMX_ERRORTYPE FBD_CB(OMX_OUT OMX_HANDLETYPE hComponent,
   1106                      OMX_OUT OMX_PTR pAppData,
   1107                      OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer)
   1108 {
   1109    D("Got FBD callback ts=%lld", pBuffer->nTimeStamp);
   1110 
   1111    static long long prevTime = 0;
   1112    long long currTime = GetTimeStamp();
   1113 
   1114    m_bWatchDogKicked = true;
   1115 
   1116    /* Empty Buffers should not be counted */
   1117    if(pBuffer->nFilledLen !=0)
   1118    {
   1119       /* Counting Buffers supplied from OpneMax Encoder */
   1120       fbd_cnt++;
   1121       tot_bufsize += pBuffer->nFilledLen;
   1122    }
   1123    if (prevTime != 0)
   1124    {
   1125       long long currTime = GetTimeStamp();
   1126       D("FBD_DELTA = %lld\n", currTime - prevTime);
   1127    }
   1128    prevTime = currTime;
   1129 
   1130    if (m_eMode == MODE_PROFILE)
   1131    {
   1132       // if we are profiling we are not doing file I/O
   1133       // so just give back to encoder
   1134       if (OMX_FillThisBuffer(m_hHandle, pBuffer) != OMX_ErrorNone)
   1135       {
   1136          E("empty buffer failed for profiling");
   1137       }
   1138    }
   1139    else
   1140    {
   1141       // wake up main thread and tell it to write to file
   1142       MsgData data;
   1143       data.sBitstreamData.pBuffer = pBuffer;
   1144       SendMessage(MSG_ID_OUTPUT_FRAME_DONE,
   1145                   &data);
   1146    }
   1147    return OMX_ErrorNone;
   1148 }
   1149 ////////////////////////////////////////////////////////////////////////////////
   1150 OMX_ERRORTYPE VencTest_Initialize()
   1151 {
   1152    OMX_ERRORTYPE result = OMX_ErrorNone;
   1153    static OMX_CALLBACKTYPE sCallbacks = {EVT_CB, EBD_CB, FBD_CB};
   1154    int i;
   1155 
   1156    for (i = 0; i < num_in_buffers; i++)
   1157    {
   1158       m_pInBuffers[i] = NULL;
   1159    }
   1160 
   1161    result = OMX_Init();
   1162    CHK(result);
   1163 
   1164    if (m_sProfile.eCodec == OMX_VIDEO_CodingMPEG4)
   1165    {
   1166         result = OMX_GetHandle(&m_hHandle,
   1167                              "OMX.qcom.video.encoder.mpeg4",
   1168                              NULL,
   1169                              &sCallbacks);
   1170      // CHK(result);
   1171    }
   1172    else if (m_sProfile.eCodec == OMX_VIDEO_CodingH263)
   1173    {
   1174       result = OMX_GetHandle(&m_hHandle,
   1175                              "OMX.qcom.video.encoder.h263",
   1176                              NULL,
   1177                              &sCallbacks);
   1178       CHK(result);
   1179    }
   1180    else
   1181    {
   1182       result = OMX_GetHandle(&m_hHandle,
   1183                              "OMX.qcom.video.encoder.avc",
   1184                              NULL,
   1185                              &sCallbacks);
   1186       CHK(result);
   1187    }
   1188 
   1189 
   1190    result = ConfigureEncoder();
   1191    CHK(result);
   1192 
   1193    return result;
   1194 }
   1195 
   1196 ////////////////////////////////////////////////////////////////////////////////
   1197 OMX_ERRORTYPE VencTest_RegisterYUVBuffer(OMX_BUFFERHEADERTYPE** ppBufferHeader,
   1198                                          OMX_U8 *pBuffer,
   1199                                          OMX_PTR pAppPrivate)
   1200 {
   1201    OMX_ERRORTYPE result = OMX_ErrorNone;
   1202 #if 0
   1203    D("register buffer");
   1204    if ((result = OMX_AllocateBuffer(m_hHandle,
   1205                                ppBufferHeader,
   1206                                (OMX_U32) PORT_INDEX_IN,
   1207                                pAppPrivate,
   1208                                m_sProfile.nFrameBytes
   1209                                )) != OMX_ErrorNone)
   1210    {
   1211       E("use buffer failed");
   1212    }
   1213    else
   1214    {
   1215      E("Allocate Buffer Success %x", (*ppBufferHeader)->pBuffer);
   1216    }
   1217   #endif
   1218    D("register buffer");
   1219    D("Calling UseBuffer for Input port");
   1220    if ((result = OMX_UseBuffer(m_hHandle,
   1221                                ppBufferHeader,
   1222                                (OMX_U32) PORT_INDEX_IN,
   1223                                pAppPrivate,
   1224                                m_sProfile.nFrameBytes,
   1225                                pBuffer)) != OMX_ErrorNone)
   1226    {
   1227       E("use buffer failed");
   1228    }
   1229 
   1230    return result;
   1231 }
   1232 ////////////////////////////////////////////////////////////////////////////////
   1233 OMX_ERRORTYPE VencTest_EncodeFrame(void* pYUVBuff,
   1234                                    long long nTimeStamp)
   1235 {
   1236    OMX_ERRORTYPE result = OMX_ErrorUndefined;
   1237    D("calling OMX empty this buffer");
   1238    for (int i = 0; i < num_in_buffers; i++)
   1239    {
   1240       if (pYUVBuff == m_pInBuffers[i]->pBuffer)
   1241       {
   1242          m_pInBuffers[i]->nTimeStamp = nTimeStamp;
   1243     D("Sending Buffer - %x", m_pInBuffers[i]->pBuffer);
   1244          result = OMX_EmptyThisBuffer(m_hHandle,
   1245                                       m_pInBuffers[i]);
   1246          /* Counting Buffers supplied to OpenMax Encoder */
   1247          if(OMX_ErrorNone == result)
   1248             ebd_cnt++;
   1249          CHK(result);
   1250          break;
   1251       }
   1252    }
   1253    return result;
   1254 }
   1255 ////////////////////////////////////////////////////////////////////////////////
   1256 OMX_ERRORTYPE VencTest_Exit(void)
   1257 {
   1258    int i;
   1259    OMX_ERRORTYPE result = OMX_ErrorNone;
   1260    D("trying to exit venc");
   1261 
   1262    D("going to idle state");
   1263    SetState(OMX_StateIdle);
   1264 
   1265 
   1266    D("going to loaded state");
   1267    //SetState(OMX_StateLoaded);
   1268       OMX_SendCommand(m_hHandle,
   1269                       OMX_CommandStateSet,
   1270                       (OMX_U32) OMX_StateLoaded,
   1271                        NULL);
   1272 
   1273       for (i = 0; i < num_in_buffers; i++)
   1274    {
   1275       D("free buffer");
   1276       if (m_pInBuffers[i]->pBuffer)
   1277       {
   1278         // free(m_pInBuffers[i]->pBuffer);
   1279          result = OMX_FreeBuffer(m_hHandle,
   1280                                  PORT_INDEX_IN,
   1281                                  m_pInBuffers[i]);
   1282          CHK(result);
   1283       }
   1284       else
   1285       {
   1286          E("buffer %d is null", i);
   1287          result = OMX_ErrorUndefined;
   1288          CHK(result);
   1289       }
   1290    }
   1291    for (i = 0; i < num_out_buffers; i++)
   1292    {
   1293       D("free buffer");
   1294       if (m_pOutBuffers[i]->pBuffer)
   1295       {
   1296          free(m_pOutBuffers[i]->pBuffer);
   1297          result = OMX_FreeBuffer(m_hHandle,
   1298                                  PORT_INDEX_OUT,
   1299                                  m_pOutBuffers[i]);
   1300          CHK(result);
   1301 
   1302       }
   1303       else
   1304       {
   1305          E("buffer %d is null", i);
   1306          result = OMX_ErrorUndefined;
   1307          CHK(result);
   1308       }
   1309    }
   1310 
   1311      while (m_eState != OMX_StateLoaded)
   1312      {
   1313         sleep(1);
   1314      }
   1315    D("component_deinit...");
   1316    result = OMX_Deinit();
   1317    CHK(result);
   1318 
   1319    D("venc is exiting...");
   1320    return result;
   1321 }
   1322 ////////////////////////////////////////////////////////////////////////////////
   1323 
   1324 void VencTest_ReadDynamicConfigMsg()
   1325 {
   1326   char frame_n[8], config[16], param[8];
   1327   char *dest = frame_n;
   1328   bool end = false;
   1329   int cntr, nparam = 0;
   1330   memset(&dynamic_config, 0, sizeof(struct DynamicConfig));
   1331   do
   1332   {
   1333     cntr = -1;
   1334     do
   1335     {
   1336       dest[++cntr] = fgetc(m_pDynConfFile);
   1337     } while(dest[cntr] != ' ' && dest[cntr] != '\t' && dest[cntr] != '\n' && dest[cntr] != '\r' && !feof(m_pDynConfFile));
   1338     if (dest[cntr] == '\n' || dest[cntr] == '\r')
   1339       end = true;
   1340     dest[cntr] = NULL;
   1341     if (dest == frame_n)
   1342       dest = config;
   1343     else if (dest == config)
   1344       dest = param;
   1345     else
   1346       end = true;
   1347     nparam++;
   1348   } while (!end && !feof(m_pDynConfFile));
   1349 
   1350   if (nparam > 1)
   1351   {
   1352     dynamic_config.pending = true;
   1353     dynamic_config.frame_num = atoi(frame_n);
   1354     if (!strcmp(config, "bitrate"))
   1355     {
   1356       dynamic_config.config_param = OMX_IndexConfigVideoBitrate;
   1357       dynamic_config.config_data.bitrate.nPortIndex = PORT_INDEX_OUT;
   1358       dynamic_config.config_data.bitrate.nEncodeBitrate = strtoul(param, NULL, 10);
   1359     }
   1360     else if (!strcmp(config, "framerate"))
   1361     {
   1362       dynamic_config.config_param = OMX_IndexConfigVideoFramerate;
   1363       dynamic_config.config_data.framerate.nPortIndex = PORT_INDEX_OUT;
   1364       dynamic_config.config_data.f_framerate = atof(param);
   1365     }
   1366     else if (!strcmp(config, "iperiod"))
   1367     {
   1368       dynamic_config.config_param = (OMX_INDEXTYPE)QOMX_IndexConfigVideoIntraperiod;
   1369       dynamic_config.config_data.intraperiod.nPortIndex = PORT_INDEX_OUT;
   1370       dynamic_config.config_data.intraperiod.nPFrames = strtoul(param, NULL, 10) - 1;
   1371       dynamic_config.config_data.intraperiod.nIDRPeriod = 1; // This value is ignored in OMX component
   1372     }
   1373     else if (!strcmp(config, "ivoprefresh"))
   1374     {
   1375       dynamic_config.config_param = OMX_IndexConfigVideoIntraVOPRefresh;
   1376       dynamic_config.config_data.intravoprefresh.nPortIndex = PORT_INDEX_OUT;
   1377       dynamic_config.config_data.intravoprefresh.IntraRefreshVOP = OMX_TRUE;
   1378     }
   1379     else if (!strcmp(config, "rotation"))
   1380     {
   1381       dynamic_config.config_param = OMX_IndexConfigCommonRotate;
   1382       dynamic_config.config_data.rotation.nPortIndex = PORT_INDEX_OUT;
   1383       dynamic_config.config_data.rotation.nRotation = strtoul(param, NULL, 10);
   1384     }
   1385     else
   1386     {
   1387       E("UNKNOWN CONFIG PARAMETER: %s!", config);
   1388       dynamic_config.pending = false;
   1389     }
   1390   }
   1391   else if (feof(m_pDynConfFile))
   1392   {
   1393     fclose(m_pDynConfFile);
   1394     m_pDynConfFile = NULL;
   1395   }
   1396 }
   1397 
   1398 void VencTest_ProcessDynamicConfigurationFile()
   1399 {
   1400   do
   1401   {
   1402     if (dynamic_config.pending)
   1403     {
   1404       if(m_nFrameIn == dynamic_config.frame_num)
   1405       {
   1406         if (dynamic_config.config_param == OMX_IndexConfigVideoFramerate)
   1407         {
   1408           m_sProfile.nFramerate = dynamic_config.config_data.f_framerate;
   1409           FractionToQ16(dynamic_config.config_data.framerate.xEncodeFramerate,
   1410                         (int)(m_sProfile.nFramerate * 2), 2);
   1411         }
   1412         if (OMX_SetConfig(m_hHandle, dynamic_config.config_param,
   1413             &dynamic_config.config_data) != OMX_ErrorNone)
   1414           E("ERROR: Setting dynamic config to OMX param[0x%x]", dynamic_config.config_param);
   1415         dynamic_config.pending = false;
   1416       }
   1417       else if (m_nFrameIn > dynamic_config.frame_num)
   1418       {
   1419         E("WARNING: Config change requested in passed frame(%d)", dynamic_config.frame_num);
   1420         dynamic_config.pending = false;
   1421       }
   1422     }
   1423     if (!dynamic_config.pending)
   1424       VencTest_ReadDynamicConfigMsg();
   1425   } while (!dynamic_config.pending && m_pDynConfFile);
   1426 }
   1427 
   1428 ////////////////////////////////////////////////////////////////////////////////
   1429 OMX_ERRORTYPE VencTest_ReadAndEmpty(OMX_BUFFERHEADERTYPE* pYUVBuffer)
   1430 {
   1431    OMX_ERRORTYPE result = OMX_ErrorNone;
   1432 #ifdef T_ARM
   1433 #ifdef MAX_RES_720P
   1434    if (read(m_nInFd,
   1435             pYUVBuffer->pBuffer,
   1436             m_sProfile.nFrameBytes) != m_sProfile.nFrameBytes)
   1437    {
   1438       return OMX_ErrorUndefined;
   1439    }
   1440 #elif BADGER
   1441    int bytes;
   1442    E("will read YUV now: %d bytes to buffer %p\n", m_sProfile.nFrameRead, pYUVBuffer->pBuffer);
   1443    E("W: %d H: %d Str: %d scal: %d \n", m_sProfile.nFrameWidth, m_sProfile.nFrameHeight,
   1444 		m_sProfile.nFramestride, m_sProfile.nFrameScanlines);
   1445    bytes = read(m_nInFd, pYUVBuffer->pBuffer, m_sProfile.nFrameRead);
   1446    if (bytes != m_sProfile.nFrameRead) {
   1447 		E("read failed: %d != %d\n", read, m_sProfile.nFrameRead);
   1448 		return OMX_ErrorUndefined;
   1449    }
   1450    E("\n\nRead %d bytes\n\n\n", m_sProfile.nFrameRead);
   1451 #else
   1452          OMX_U32 bytestoread = m_sProfile.nFrameWidth*m_sProfile.nFrameHeight;
   1453          // read Y first
   1454          if (read(m_nInFd,
   1455               pYUVBuffer->pBuffer,
   1456               bytestoread) != bytestoread)
   1457             return OMX_ErrorUndefined;
   1458 
   1459          // check alignment for offset to C
   1460          OMX_U32 offset_to_c = m_sProfile.nFrameWidth * m_sProfile.nFrameHeight;
   1461 
   1462          const OMX_U32 C_2K = (1024*2),
   1463             MASK_2K = C_2K-1,
   1464             IMASK_2K = ~MASK_2K;
   1465 
   1466          if (offset_to_c & MASK_2K)
   1467          {
   1468             // offset to C is not 2k aligned, adjustment is required
   1469             offset_to_c = (offset_to_c & IMASK_2K) + C_2K;
   1470          }
   1471 
   1472          bytestoread = m_sProfile.nFrameWidth*m_sProfile.nFrameHeight/2;
   1473          // read C
   1474          if (read(m_nInFd,
   1475               pYUVBuffer->pBuffer + offset_to_c,
   1476               bytestoread)!= bytestoread)
   1477             return OMX_ErrorUndefined;
   1478 #endif
   1479 #else
   1480    {
   1481 	  char * pInputbuf = (char *)(pYUVBuffer->pBuffer) ;
   1482 	      read(m_nInFd,pInputbuf,m_sProfile.nFrameBytes) ;
   1483 
   1484    }
   1485 #endif
   1486    if (m_pDynConfFile)
   1487      VencTest_ProcessDynamicConfigurationFile();
   1488    D("about to call VencTest_EncodeFrame...");
   1489    pthread_mutex_lock(&m_mutex);
   1490    ++m_nFrameIn;
   1491 #ifdef BADGER
   1492    pYUVBuffer->nFilledLen = m_sProfile.nFrameRead;
   1493 #else
   1494    pYUVBuffer->nFilledLen = m_sProfile.nFrameBytes;
   1495 #endif
   1496    D("Called Buffer with Data filled length %d",pYUVBuffer->nFilledLen);
   1497 
   1498       result = VencTest_EncodeFrame(pYUVBuffer->pBuffer,
   1499                                  m_nTimeStamp);
   1500 
   1501    m_nTimeStamp += (1000000) / m_sProfile.nFramerate;
   1502    CHK(result);
   1503    pthread_mutex_unlock(&m_mutex);
   1504    return result;
   1505 }
   1506 ////////////////////////////////////////////////////////////////////////////////
   1507 void PreviewCallback(int nFD,
   1508                      int nOffset,
   1509                      void* pPhys,
   1510                      void* pVirt,
   1511                      long long nTimeStamp)
   1512 {
   1513 
   1514    D("================= preview frame %d, phys=0x%x, nTimeStamp(millis)=%lld",
   1515      m_nFrameIn+1, pPhys, (nTimeStamp / 1000));
   1516 
   1517    if (m_nFrameIn == m_nFramePlay &&
   1518        m_nFramePlay != 0)
   1519    {
   1520       // we will stop camera after last frame is encoded.
   1521       // for now just ignore input frames
   1522 
   1523       CameraTest_ReleaseFrame(pPhys, pVirt);
   1524       return;
   1525    }
   1526 
   1527    // see if we should stop
   1528    pthread_mutex_lock(&m_mutex);
   1529    ++m_nFrameIn;
   1530    pthread_mutex_unlock(&m_mutex);
   1531 
   1532 
   1533    if (m_eMode == MODE_LIVE_ENCODE)
   1534    {
   1535 
   1536       OMX_ERRORTYPE result;
   1537 
   1538       // register new camera buffers with encoder
   1539       int i;
   1540       for (i = 0; i < num_in_buffers; i++)
   1541       {
   1542          if (m_pInBuffers[i] != NULL &&
   1543              m_pInBuffers[i]->pBuffer == pPhys)
   1544          {
   1545             break;
   1546          }
   1547          else if (m_pInBuffers[i] == NULL)
   1548          {
   1549             D("registering buffer...");
   1550             result = VencTest_RegisterYUVBuffer(&m_pInBuffers[i],
   1551                                                 (OMX_U8*) pPhys,
   1552                                                 (OMX_PTR) pVirt); // store virt in app private field
   1553             D("register done");
   1554             CHK(result);
   1555             break;
   1556          }
   1557       }
   1558 
   1559       if (i == num_in_buffers)
   1560       {
   1561          E("There are more camera buffers than we thought");
   1562          CHK(1);
   1563       }
   1564 
   1565       // encode the yuv frame
   1566 
   1567       D("StartEncodeTime=%lld", GetTimeStamp());
   1568       result = VencTest_EncodeFrame(pPhys,
   1569                                     nTimeStamp);
   1570       CHK(result);
   1571      // FBTest_DisplayImage(nFD, nOffset);
   1572    }
   1573    else
   1574    {
   1575      // FBTest_DisplayImage(nFD, nOffset);
   1576       CameraTest_ReleaseFrame(pPhys, pVirt);
   1577    }
   1578 }
   1579 ////////////////////////////////////////////////////////////////////////////////
   1580 void usage(char* filename)
   1581 {
   1582    char* fname = strrchr(filename, (int) '/');
   1583    fname = (fname == NULL) ? filename : fname;
   1584 
   1585    fprintf(stderr, "usage: %s LIVE <QCIF|QVGA> <MP4|H263> <FPS> <BITRATE> <NFRAMES> <OUTFILE>\n", fname);
   1586    fprintf(stderr, "usage: %s FILE <QCIF|QVGA> <MP4|H263 <FPS> <BITRATE> <NFRAMES> <INFILE> <OUTFILE> ", fname);
   1587    fprintf(stderr, "<Dynamic config file - opt> <Rate Control - opt> <AVC Slice Mode - opt>\n", fname);
   1588    fprintf(stderr, "usage: %s PROFILE <QCIF|QVGA> <MP4|H263 <FPS> <BITRATE> <NFRAMES> <INFILE>\n", fname);
   1589    fprintf(stderr, "usage: %s PREVIEW <QCIF|QVGA> <FPS> <NFRAMES>\n", fname);
   1590    fprintf(stderr, "usage: %s DISPLAY <QCIF|QVGA> <FPS> <NFRAMES> <INFILE>\n", fname);
   1591    fprintf(stderr, "\n       BITRATE - bitrate in kbps\n");
   1592    fprintf(stderr, "       FPS - frames per second\n");
   1593    fprintf(stderr, "       NFRAMES - number of frames to play, 0 for infinite\n");
   1594    fprintf(stderr, "       RateControl (Values 0 - 4 for RC_OFF, RC_CBR_CFR, RC_CBR_VFR, RC_VBR_CFR, RC_VBR_VFR\n");
   1595    exit(1);
   1596 }
   1597 
   1598 bool parseWxH(char *str, OMX_U32 *width, OMX_U32 *height)
   1599 {
   1600    bool parseOK = false;
   1601    const char delimiters[] = " x*,";
   1602    char *token, *dupstr, *temp;
   1603    OMX_U32 w, h;
   1604 
   1605    dupstr = strdup(str);
   1606    token = strtok_r(dupstr, delimiters, &temp);
   1607    if (token)
   1608    {
   1609        w = strtoul(token, NULL, 10);
   1610        token = strtok_r(NULL, delimiters, &temp);
   1611        if (token)
   1612        {
   1613            h = strtoul(token, NULL, 10);
   1614            if (w != ULONG_MAX && h != ULONG_MAX)
   1615            {
   1616 #ifdef MAX_RES_720P
   1617               if ((w * h >> 8) <= 3600)
   1618               {
   1619                  parseOK = true;
   1620                  *width = w;
   1621                  *height = h;
   1622                  }
   1623 #else
   1624               if ((w * h >> 8) <= 8160)
   1625               {
   1626                  parseOK = true;
   1627                  *width = w;
   1628                  *height = h;
   1629                  }
   1630 #endif
   1631               else
   1632                  E("\nInvalid dimensions %dx%d",w,h);
   1633               }
   1634            }
   1635        }
   1636    free(dupstr);
   1637    return parseOK;
   1638 }
   1639 
   1640 ////////////////////////////////////////////////////////////////////////////////
   1641 void parseArgs(int argc, char** argv)
   1642 {
   1643    int dyn_file_arg = argc;
   1644    if (argc == 1)
   1645    {
   1646       usage(argv[0]);
   1647    }
   1648    else if (strcmp("PREVIEW", argv[1]) == 0 ||
   1649             strcmp("preview", argv[1]) == 0)
   1650    {
   1651       m_eMode = MODE_PREVIEW;
   1652       if (argc != 5)
   1653       {
   1654          usage(argv[0]);
   1655       }
   1656    }
   1657    else if (strcmp("DISPLAY", argv[1]) == 0 ||
   1658             strcmp("display", argv[1]) == 0)
   1659    {
   1660       m_eMode = MODE_DISPLAY;
   1661       if (argc != 6)
   1662       {
   1663          usage(argv[0]);
   1664       }
   1665       m_sProfile.cInFileName = argv[5];
   1666       m_sProfile.cOutFileName = NULL;
   1667    }
   1668    else if (strcmp("LIVE", argv[1]) == 0 ||
   1669             strcmp("live", argv[1]) == 0)
   1670    {//263
   1671       m_eMode = MODE_LIVE_ENCODE;
   1672       if (argc != 8)
   1673       {
   1674          usage(argv[0]);
   1675       }
   1676       m_sProfile.cInFileName = NULL;
   1677       m_sProfile.cOutFileName = argv[7];
   1678    }
   1679    else if (strcmp("FILE", argv[1]) == 0 ||
   1680             strcmp("file", argv[1]) == 0)
   1681    {//263
   1682       m_eMode = MODE_FILE_ENCODE;
   1683 
   1684       if(argc < 9 || argc > 13)
   1685       {
   1686           usage(argv[0]);
   1687       }
   1688       else
   1689       {
   1690          if (argc > 9)
   1691             dyn_file_arg = 9;
   1692 
   1693          if (argc > 10)
   1694          {
   1695            m_sProfile.eControlRate = OMX_Video_ControlRateVariable;
   1696             int RC = atoi(argv[10]);
   1697 
   1698             switch (RC)
   1699             {
   1700             case 0:
   1701                m_sProfile.eControlRate  = OMX_Video_ControlRateDisable ;//VENC_RC_NONE
   1702                break;
   1703             case 1:
   1704                m_sProfile.eControlRate  = OMX_Video_ControlRateConstant;//VENC_RC_CBR_CFR
   1705                break;
   1706 
   1707             case 2:
   1708                m_sProfile.eControlRate  = OMX_Video_ControlRateConstantSkipFrames;//VENC_RC_CBR_VFR
   1709                break;
   1710 
   1711             case 3:
   1712                m_sProfile.eControlRate  =OMX_Video_ControlRateVariable ;//VENC_RC_VBR_CFR
   1713                break;
   1714 
   1715             case 4:
   1716                m_sProfile.eControlRate  = OMX_Video_ControlRateVariableSkipFrames;//VENC_RC_VBR_VFR
   1717                break;
   1718 
   1719            default:
   1720                E("invalid rate control selection");
   1721                m_sProfile.eControlRate = OMX_Video_ControlRateVariable; //VENC_RC_VBR_CFR
   1722                break;
   1723             }
   1724          }
   1725 
   1726          if (argc > 11)
   1727          {
   1728             int profile_argi = 11;
   1729             if(!strcmp(argv[3], "H264") || !strcmp(argv[3], "h264"))
   1730             {
   1731                profile_argi = 12;
   1732                D("\nSetting AVCSliceMode ... ");
   1733                int AVCSliceMode = atoi(argv[11]);
   1734                switch(AVCSliceMode)
   1735                {
   1736                case 0:
   1737                   m_sProfile.eSliceMode = OMX_VIDEO_SLICEMODE_AVCDefault;
   1738                   break;
   1739 
   1740                case 1:
   1741                   m_sProfile.eSliceMode = OMX_VIDEO_SLICEMODE_AVCMBSlice;
   1742                   break;
   1743 
   1744                case 2:
   1745                   m_sProfile.eSliceMode = OMX_VIDEO_SLICEMODE_AVCByteSlice;
   1746                   break;
   1747 
   1748                default:
   1749                   E("invalid Slice Mode");
   1750                   m_sProfile.eSliceMode = OMX_VIDEO_SLICEMODE_AVCDefault;
   1751                   break;
   1752               }
   1753             }
   1754             if (profile_argi < argc)
   1755             {
   1756                if (!strncmp(argv[profile_argi], "0x", 2) || !strncmp(argv[profile_argi], "0x", 2))
   1757                {
   1758                   m_sProfile.nUserProfile = strtoul(argv[profile_argi], NULL, 16);
   1759                }
   1760                else
   1761                {
   1762                   m_sProfile.nUserProfile = strtoul(argv[profile_argi], NULL, 10);
   1763                }
   1764                if (!m_sProfile.nUserProfile || m_sProfile.nUserProfile == ULONG_MAX)
   1765                {
   1766                   E("invalid specified Profile %s, using default", argv[profile_argi]);
   1767                   m_sProfile.nUserProfile = 0;
   1768                }
   1769             }
   1770          }
   1771       }
   1772       m_sProfile.cInFileName = argv[7];
   1773       m_sProfile.cOutFileName = argv[8];
   1774    }
   1775    else if (strcmp("PROFILE", argv[1]) == 0 ||
   1776             strcmp("profile", argv[1]) == 0)
   1777    {//263
   1778       m_eMode = MODE_PROFILE;
   1779       if (argc != 8)
   1780       {
   1781          usage(argv[0]);
   1782       }
   1783       m_sProfile.cInFileName = argv[7];
   1784       m_sProfile.cOutFileName = NULL;
   1785    }
   1786    else
   1787    {
   1788       usage(argv[0]);
   1789    }
   1790 
   1791 
   1792    if (strcmp("QCIF", argv[2]) == 0 ||
   1793        strcmp("qcif", argv[2]) == 0)
   1794    {
   1795       m_sProfile.nFrameWidth = 176;
   1796       m_sProfile.nFrameHeight = 144;
   1797       m_sProfile.nFrameBytes = 176*144*3/2;
   1798       m_sProfile.eLevel = OMX_VIDEO_MPEG4Level0;
   1799    }
   1800    else if (strcmp("QVGA", argv[2]) == 0 ||
   1801             strcmp("qvga", argv[2]) == 0)
   1802    {
   1803       m_sProfile.nFrameWidth = 320;
   1804       m_sProfile.nFrameHeight = 240;
   1805       m_sProfile.nFrameBytes = 320*240*3/2;
   1806       m_sProfile.eLevel = OMX_VIDEO_MPEG4Level1;
   1807    }
   1808 
   1809 
   1810     else if (strcmp("VGA", argv[2]) == 0 ||
   1811             strcmp("vga", argv[2]) == 0)
   1812    {
   1813       m_sProfile.nFrameWidth = 640;
   1814       m_sProfile.nFrameHeight = 480;
   1815       m_sProfile.nFrameBytes = 640*480*3/2;
   1816       m_sProfile.eLevel = OMX_VIDEO_MPEG4Level1;
   1817    }
   1818 
   1819     else if (strcmp("WVGA", argv[2]) == 0 ||
   1820             strcmp("wvga", argv[2]) == 0)
   1821    {
   1822       m_sProfile.nFrameWidth = 800;
   1823       m_sProfile.nFrameHeight = 480;
   1824       m_sProfile.nFrameBytes = 800*480*3/2;
   1825       m_sProfile.eLevel = OMX_VIDEO_MPEG4Level1;
   1826    }
   1827   else if (strcmp("CIF", argv[2]) == 0 ||
   1828             strcmp("cif", argv[2]) == 0)
   1829    {
   1830       m_sProfile.nFrameWidth = 352;
   1831       m_sProfile.nFrameHeight = 288;
   1832       m_sProfile.nFrameBytes = 352*288*3/2;
   1833       m_sProfile.eLevel = OMX_VIDEO_MPEG4Level1;
   1834    }
   1835    else if (strcmp("720", argv[2]) == 0)
   1836    {
   1837       m_sProfile.nFrameWidth = 1280;
   1838       m_sProfile.nFrameHeight = 720;
   1839       m_sProfile.nFrameBytes = 720*1280*3/2;
   1840       m_sProfile.eLevel = OMX_VIDEO_MPEG4Level1;
   1841    }
   1842    else if (strcmp("1080", argv[2]) == 0)
   1843    {
   1844       m_sProfile.nFrameWidth = 1920;
   1845       m_sProfile.nFrameHeight = 1080;
   1846       m_sProfile.nFrameBytes = 1920*1080*3/2;
   1847       m_sProfile.eLevel = OMX_VIDEO_MPEG4Level1;
   1848    }
   1849    else if (parseWxH(argv[2], &m_sProfile.nFrameWidth, &m_sProfile.nFrameHeight))
   1850    {
   1851       m_sProfile.nFrameBytes = m_sProfile.nFrameWidth*m_sProfile.nFrameHeight*3/2;
   1852       m_sProfile.eLevel = OMX_VIDEO_MPEG4Level1;
   1853    }
   1854    else
   1855    {
   1856       usage(argv[0]);
   1857    }
   1858 
   1859 #ifdef BADGER
   1860    m_sProfile.nFramestride =  (m_sProfile.nFrameWidth + 31) & (~31);
   1861    m_sProfile.nFrameScanlines = (m_sProfile.nFrameHeight + 31) & (~31);
   1862    m_sProfile.nFrameBytes = ((m_sProfile.nFramestride * m_sProfile.nFrameScanlines * 3/2) + 4095) & (~4095);
   1863    E("stride: %d, Scanlines: %d, Size: %d",
   1864      m_sProfile.nFramestride, m_sProfile.nFrameScanlines, m_sProfile.nFrameBytes);
   1865    m_sProfile.nFrameRead = m_sProfile.nFramestride * m_sProfile.nFrameScanlines * 3/2;
   1866 #endif
   1867    if (m_eMode == MODE_DISPLAY ||
   1868        m_eMode == MODE_PREVIEW)
   1869    {
   1870       m_sProfile.nFramerate = atof(argv[3]);
   1871       m_nFramePlay = atoi(argv[4]);
   1872 
   1873    }
   1874    else if (m_eMode == MODE_LIVE_ENCODE ||
   1875             m_eMode == MODE_FILE_ENCODE ||
   1876             m_eMode == MODE_PROFILE)
   1877    {
   1878       if ((!strcmp(argv[3], "MP4")) || (!strcmp(argv[3], "mp4")))
   1879       {
   1880          m_sProfile.eCodec = OMX_VIDEO_CodingMPEG4;
   1881       }
   1882       else if ((!strcmp(argv[3], "H263")) || (!strcmp(argv[3], "h263")))
   1883       {
   1884          m_sProfile.eCodec = OMX_VIDEO_CodingH263;
   1885       }
   1886       else if ((!strcmp(argv[3], "H264")) || (!strcmp(argv[3], "h264")))
   1887       {
   1888          m_sProfile.eCodec = OMX_VIDEO_CodingAVC;
   1889       }
   1890       else
   1891       {
   1892          usage(argv[0]);
   1893       }
   1894 
   1895       m_sProfile.nFramerate = atof(argv[4]);
   1896       m_sProfile.nBitrate = atoi(argv[5]);
   1897 //      m_sProfile.eControlRate = OMX_Video_ControlRateVariable;
   1898       m_nFramePlay = atoi(argv[6]);
   1899       if (dyn_file_arg < argc)
   1900       {
   1901         m_pDynConfFile = fopen(argv[dyn_file_arg], "r");
   1902         if (!m_pDynConfFile)
   1903           E("ERROR: Cannot open dynamic config file: %s", argv[dyn_file_arg]);
   1904         else
   1905         {
   1906           memset(&dynamic_config, 0, sizeof(struct DynamicConfig));
   1907         }
   1908       }
   1909    }
   1910 }
   1911 
   1912 void* Watchdog(void* data)
   1913 {
   1914    while (1)
   1915    {
   1916       sleep(1000);
   1917       if (m_bWatchDogKicked == true)
   1918          m_bWatchDogKicked = false;
   1919       else
   1920          E("watchdog has not been kicked. we may have a deadlock");
   1921    }
   1922    return NULL;
   1923 }
   1924 
   1925 int main(int argc, char** argv)
   1926 {
   1927    OMX_U8* pvirt = NULL;
   1928    int result;
   1929    float enc_time_sec=0.0,enc_time_usec=0.0;
   1930 
   1931    m_nInFd = -1;
   1932    m_nOutFd = -1;
   1933    m_nTimeStamp = 0;
   1934    m_nFrameIn = 0;
   1935    m_nFrameOut = 0;
   1936 
   1937    memset(&m_sMsgQ, 0, sizeof(MsgQ));
   1938    parseArgs(argc, argv);
   1939 
   1940    D("fps=%d, bitrate=%d, width=%d, height=%d",
   1941      m_sProfile.nFramerate,
   1942      m_sProfile.nBitrate,
   1943      m_sProfile.nFrameWidth,
   1944      m_sProfile.nFrameHeight);
   1945 
   1946 
   1947    //if (m_eMode != MODE_PREVIEW && m_eMode != MODE_DISPLAY)
   1948    //{
   1949      // pthread_t wd;
   1950      // pthread_create(&wd, NULL, Watchdog, NULL);
   1951    //}
   1952 
   1953    for (int x = 0; x < num_in_buffers; x++)
   1954    {
   1955       // mark all buffers as ready to use
   1956       m_bInFrameFree[x] = OMX_TRUE;
   1957    }
   1958 
   1959 
   1960     if (m_eMode != MODE_PROFILE)
   1961    {
   1962       #if T_ARM
   1963 	   m_nOutFd = open(m_sProfile.cOutFileName, O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU | S_IRWXG | S_IRWXO);
   1964       #else
   1965 	  m_nOutFd = open(m_sProfile.cOutFileName,0);
   1966       #endif
   1967       if (m_nOutFd < 0)
   1968       {
   1969          E("could not open output file %s", m_sProfile.cOutFileName);
   1970          CHK(1);
   1971       }
   1972    }
   1973 
   1974    pthread_mutex_init(&m_mutex, NULL);
   1975    pthread_cond_init(&m_signal, NULL);
   1976 
   1977    if (m_eMode != MODE_PREVIEW)
   1978    {
   1979       VencTest_Initialize();
   1980    }
   1981 
   1982    ////////////////////////////////////////
   1983    // Camera + Encode
   1984    ////////////////////////////////////////
   1985    if (m_eMode == MODE_LIVE_ENCODE)
   1986    {
   1987      CameraTest_Initialize(m_sProfile.nFramerate,
   1988                             m_sProfile.nFrameWidth,
   1989                             m_sProfile.nFrameHeight,
   1990                             PreviewCallback);
   1991       CameraTest_Run();
   1992    }
   1993 
   1994    if (m_eMode == MODE_FILE_ENCODE ||
   1995        m_eMode == MODE_PROFILE)
   1996    {
   1997       int i;
   1998       #if T_ARM
   1999       m_nInFd = open(m_sProfile.cInFileName, O_RDONLY);
   2000       #else
   2001       m_nInFd = open(m_sProfile.cInFileName,1);
   2002       #endif
   2003 	  if (m_nInFd < 0)
   2004       {
   2005          E("could not open input file");
   2006          CHK(1);
   2007 
   2008       }
   2009       D("going to idle state");
   2010       //SetState(OMX_StateIdle);
   2011       OMX_SendCommand(m_hHandle,
   2012                       OMX_CommandStateSet,
   2013                       (OMX_U32) OMX_StateIdle,
   2014                        NULL);
   2015 
   2016       OMX_PARAM_PORTDEFINITIONTYPE portDef;
   2017 
   2018       portDef.nPortIndex = 0;
   2019       result = OMX_GetParameter(m_hHandle, OMX_IndexParamPortDefinition, &portDef);
   2020       CHK(result);
   2021 
   2022       D("allocating Input buffers");
   2023       num_in_buffers = portDef.nBufferCountActual;
   2024       for (i = 0; i < portDef.nBufferCountActual; i++)
   2025       {
   2026          OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO* pMem = new OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO;
   2027          pvirt = (OMX_U8*)PmemMalloc(pMem, m_sProfile.nFrameBytes);
   2028 
   2029          if(pvirt == NULL)
   2030          {
   2031             CHK(1);
   2032          }
   2033          result = VencTest_RegisterYUVBuffer(&m_pInBuffers[i],
   2034                                              (OMX_U8*) pvirt,
   2035                                              (OMX_PTR) pMem);
   2036          CHK(result);
   2037       }
   2038    }
   2039    else if (m_eMode == MODE_LIVE_ENCODE)
   2040    {
   2041        D("going to idle state");
   2042        //SetState(OMX_StateIdle);
   2043        OMX_SendCommand(m_hHandle,
   2044                        OMX_CommandStateSet,
   2045                        (OMX_U32) OMX_StateIdle,
   2046                         NULL);
   2047    }
   2048 
   2049    int i;
   2050    OMX_PARAM_PORTDEFINITIONTYPE portDef;
   2051 
   2052    portDef.nPortIndex = 1;
   2053    result = OMX_GetParameter(m_hHandle, OMX_IndexParamPortDefinition, &portDef);
   2054    CHK(result);
   2055 
   2056    D("allocating output buffers");
   2057    D("Calling UseBuffer for Output port");
   2058    num_out_buffers = portDef.nBufferCountActual;
   2059    for (i = 0; i < portDef.nBufferCountActual; i++)
   2060    {
   2061       void* pBuff;
   2062 
   2063       pBuff = malloc(portDef.nBufferSize);
   2064      D("portDef.nBufferSize = %d ",portDef.nBufferSize);
   2065       result = OMX_UseBuffer(m_hHandle,
   2066                              &m_pOutBuffers[i],
   2067                              (OMX_U32) PORT_INDEX_OUT,
   2068                              NULL,
   2069                              portDef.nBufferSize,
   2070                              (OMX_U8*) pBuff);
   2071       CHK(result);
   2072    }
   2073    D("allocate done");
   2074 
   2075         // D("Going to state " # eState"...");
   2076 
   2077          while (m_eState != OMX_StateIdle)
   2078          {
   2079             sleep(1);
   2080          }
   2081          //D("Now in state " # eState);
   2082 
   2083 
   2084    D("going to executing state");
   2085    SetState(OMX_StateExecuting);
   2086    for (i = 0; i < num_out_buffers; i++)
   2087    {
   2088       D("filling buffer %d", i);
   2089       result = OMX_FillThisBuffer(m_hHandle, m_pOutBuffers[i]);
   2090       //sleep(1000);
   2091       CHK(result);
   2092    }
   2093 
   2094    if (m_eMode == MODE_FILE_ENCODE)
   2095    {
   2096       // encode the first frame to kick off the whole process
   2097       VencTest_ReadAndEmpty(m_pInBuffers[0]);
   2098     //  FBTest_DisplayImage(((PmemBuffer*) m_pInBuffers[0]->pAppPrivate)->fd,0);
   2099    }
   2100 
   2101    if (m_eMode == MODE_PROFILE)
   2102    {
   2103       int i;
   2104 
   2105       // read several frames into memory
   2106       D("reading frames into memory");
   2107       for (i = 0; i < num_in_buffers; i++)
   2108       {
   2109         D("[%d] address 0x%x",i, m_pInBuffers[i]->pBuffer);
   2110 #ifdef MAX_RES_720P
   2111          read(m_nInFd,
   2112               m_pInBuffers[i]->pBuffer,
   2113               m_sProfile.nFrameBytes);
   2114 #else
   2115          // read Y first
   2116          read(m_nInFd,
   2117               m_pInBuffers[i]->pBuffer,
   2118               m_sProfile.nFrameWidth*m_sProfile.nFrameHeight);
   2119 
   2120          // check alignment for offset to C
   2121          OMX_U32 offset_to_c = m_sProfile.nFrameWidth * m_sProfile.nFrameHeight;
   2122 
   2123          const OMX_U32 C_2K = (1024*2),
   2124             MASK_2K = C_2K-1,
   2125             IMASK_2K = ~MASK_2K;
   2126 
   2127          if (offset_to_c & MASK_2K)
   2128          {
   2129             // offset to C is not 2k aligned, adjustment is required
   2130             offset_to_c = (offset_to_c & IMASK_2K) + C_2K;
   2131          }
   2132 
   2133          // read C
   2134          read(m_nInFd,
   2135               m_pInBuffers[i]->pBuffer + offset_to_c,
   2136               m_sProfile.nFrameWidth*m_sProfile.nFrameHeight/2);
   2137 #endif
   2138 
   2139       }
   2140 
   2141      // FBTest_Initialize(m_sProfile.nFrameWidth, m_sProfile.nFrameHeight);
   2142 
   2143       // loop over the mem-resident frames and encode them
   2144       D("beging playing mem-resident frames...");
   2145       for (i = 0; m_nFramePlay == 0 || i < m_nFramePlay; i++)
   2146       {
   2147          int idx = i % num_in_buffers;
   2148          if (m_bInFrameFree[idx] == OMX_FALSE)
   2149          {
   2150             int j;
   2151             E("the expected buffer is not free, but lets find another");
   2152 
   2153             idx = -1;
   2154 
   2155             // lets see if we can find another free buffer
   2156             for (j = 0; j < num_in_buffers; j++)
   2157             {
   2158                if(m_bInFrameFree[j])
   2159                {
   2160                   idx = j;
   2161                   break;
   2162                }
   2163             }
   2164          }
   2165 
   2166          // if we have a free buffer let's encode it
   2167          if (idx >= 0)
   2168          {
   2169             D("encode frame %d...m_pInBuffers[idx]->pBuffer=0x%x", i,m_pInBuffers[idx]->pBuffer);
   2170             m_bInFrameFree[idx] = OMX_FALSE;
   2171             VencTest_EncodeFrame(m_pInBuffers[idx]->pBuffer,
   2172                                  m_nTimeStamp);
   2173             D("display frame %d...", i);
   2174         //    FBTest_DisplayImage(((PmemBuffer*) m_pInBuffers[idx]->pAppPrivate)->fd,0);
   2175             m_nTimeStamp += 1000000 / m_sProfile.nFramerate;
   2176          }
   2177          else
   2178          {
   2179             E("wow, no buffers are free, performance "
   2180               "is not so good. lets just sleep some more");
   2181 
   2182          }
   2183          D("sleep for %d microsec", 1000000/m_sProfile.nFramerate);
   2184          sleep (1000000 / m_sProfile.nFramerate);
   2185       }
   2186      // FBTest_Exit();
   2187    }
   2188 
   2189    Msg msg;
   2190    bool bQuit = false;
   2191    while ((m_eMode == MODE_FILE_ENCODE || m_eMode == MODE_LIVE_ENCODE) &&
   2192           !bQuit)
   2193    {
   2194       PopMessage(&msg);
   2195       switch (msg.id)
   2196       {
   2197       //////////////////////////////////
   2198       // FRAME IS ENCODED
   2199       //////////////////////////////////
   2200       case MSG_ID_INPUT_FRAME_DONE:
   2201          /*pthread_mutex_lock(&m_mutex);
   2202          ++m_nFrameOut;
   2203          if (m_nFrameOut == m_nFramePlay && m_nFramePlay != 0)
   2204          {
   2205             bQuit = true;
   2206          }
   2207          pthread_mutex_unlock(&m_mutex);*/
   2208 
   2209          if (!bQuit && m_eMode == MODE_FILE_ENCODE)
   2210          {
   2211             D("pushing another frame down to encoder");
   2212             if (VencTest_ReadAndEmpty(msg.data.sBitstreamData.pBuffer))
   2213             {
   2214                // we have read the last frame
   2215                D("main is exiting...");
   2216                bQuit = true;
   2217             }
   2218          }
   2219        break;
   2220       case MSG_ID_OUTPUT_FRAME_DONE:
   2221          D("================ writing frame %d = %d bytes to output file",
   2222            m_nFrameOut+1,
   2223            msg.data.sBitstreamData.pBuffer->nFilledLen);
   2224          D("StopEncodeTime=%lld", GetTimeStamp());
   2225 
   2226 
   2227 		 write(m_nOutFd,
   2228                msg.data.sBitstreamData.pBuffer->pBuffer,
   2229                msg.data.sBitstreamData.pBuffer->nFilledLen);
   2230 
   2231 
   2232          result = OMX_FillThisBuffer(m_hHandle,
   2233                                      msg.data.sBitstreamData.pBuffer);
   2234 
   2235          if (result != OMX_ErrorNone)
   2236          {
   2237             CHK(result);
   2238          }
   2239 
   2240          pthread_mutex_lock(&m_mutex);
   2241          ++m_nFrameOut;
   2242          if (m_nFrameOut == m_nFramePlay && m_nFramePlay != 0)
   2243          {
   2244             bQuit = true;
   2245          }
   2246          pthread_mutex_unlock(&m_mutex);
   2247          break;
   2248 
   2249       default:
   2250          E("invalid msg id %d", (int) msg.id);
   2251       } // end switch (msg.id)
   2252 
   2253 /*  // TO UNCOMMENT FOR PAUSE TESTINGS
   2254       if(m_nFrameOut == 10)
   2255       {
   2256          E("\nGoing to Pause state\n");
   2257          SetState(OMX_StatePause);
   2258          sleep(3);
   2259 //REQUEST AN I FRAME AFTER PAUSE
   2260          OMX_CONFIG_INTRAREFRESHVOPTYPE voprefresh;
   2261          voprefresh.nPortIndex = (OMX_U32)PORT_INDEX_OUT;
   2262          voprefresh.IntraRefreshVOP = OMX_TRUE;
   2263          result = OMX_SetConfig(m_hHandle,
   2264                                    OMX_IndexConfigVideoIntraVOPRefresh,
   2265                                    &voprefresh);
   2266          E("\n OMX_IndexConfigVideoIntraVOPRefresh Set Paramter port");
   2267          CHK(result);
   2268          E("\nGoing to executing state\n");
   2269          SetState(OMX_StateExecuting);
   2270       }
   2271 */
   2272    } // end while (!bQuit)
   2273 
   2274 
   2275    if (m_eMode == MODE_LIVE_ENCODE)
   2276    {
   2277       CameraTest_Exit();
   2278       close(m_nOutFd);
   2279    }
   2280    else if (m_eMode == MODE_FILE_ENCODE ||
   2281             m_eMode == MODE_PROFILE)
   2282    {
   2283       // deallocate pmem buffers
   2284       for (int i = 0; i < num_in_buffers; i++)
   2285       {
   2286          PmemFree((OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO*)m_pInBuffers[i]->pAppPrivate,
   2287                   m_pInBuffers[i]->pBuffer,
   2288                   m_sProfile.nFrameBytes);
   2289          delete (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO*) m_pInBuffers[i]->pAppPrivate;
   2290       }
   2291       close(m_nInFd);
   2292 
   2293       if (m_eMode == MODE_FILE_ENCODE)
   2294       {
   2295          close(m_nOutFd);
   2296       }
   2297       if (m_pDynConfFile)
   2298       {
   2299         fclose(m_pDynConfFile);
   2300         m_pDynConfFile = NULL;
   2301       }
   2302    }
   2303 
   2304    if (m_eMode != MODE_PREVIEW)
   2305    {
   2306       D("exit encoder test");
   2307       VencTest_Exit();
   2308    }
   2309 
   2310    pthread_mutex_destroy(&m_mutex);
   2311    pthread_cond_destroy(&m_signal);
   2312 
   2313    /* Time Statistics Logging */
   2314    if(0 != m_sProfile.nFramerate)
   2315    {
   2316       enc_time_usec = m_nTimeStamp - (1000000 / m_sProfile.nFramerate);
   2317       enc_time_sec =enc_time_usec/1000000;
   2318       if(0 != enc_time_sec)
   2319       {
   2320          printf("Total Frame Rate: %f",ebd_cnt/enc_time_sec);
   2321          printf("\nEncoder Bitrate :%lf Kbps",(tot_bufsize*8)/(enc_time_sec*1000));
   2322       }
   2323    }
   2324    else
   2325    {
   2326       printf("\n\n Encode Time is zero");
   2327    }
   2328    printf("\nTotal Number of Frames :%d",ebd_cnt);
   2329    printf("\nNumber of dropped frames during encoding:%d\n",ebd_cnt-fbd_cnt);
   2330    /* End of Time Statistics Logging */
   2331 
   2332    D("main has exited");
   2333    return 0;
   2334 }
   2335