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