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