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 
PmemMalloc(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO * pMem,int nSize)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 
PmemFree(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO * pMem,void * pvirt,int nSize)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 }
PrintFramePackArrangement(OMX_QCOM_FRAME_PACK_ARRANGEMENT framePackingArrangement)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 }
SetState(OMX_STATETYPE eState)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 ////////////////////////////////////////////////////////////////////////////////
ConfigureEncoder()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 ////////////////////////////////////////////////////////////////////////////////
SendMessage(MsgId id,MsgData * data)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 ////////////////////////////////////////////////////////////////////////////////
PopMessage(Msg * msg)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 ////////////////////////////////////////////////////////////////////////////////
EVT_CB(OMX_IN OMX_HANDLETYPE hComponent,OMX_IN OMX_PTR pAppData,OMX_IN OMX_EVENTTYPE eEvent,OMX_IN OMX_U32 nData1,OMX_IN OMX_U32 nData2,OMX_IN OMX_PTR pEventData)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 ////////////////////////////////////////////////////////////////////////////////
EBD_CB(OMX_IN OMX_HANDLETYPE hComponent,OMX_IN OMX_PTR pAppData,OMX_IN OMX_BUFFERHEADERTYPE * pBuffer)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 ////////////////////////////////////////////////////////////////////////////////
FBD_CB(OMX_OUT OMX_HANDLETYPE hComponent,OMX_OUT OMX_PTR pAppData,OMX_OUT OMX_BUFFERHEADERTYPE * pBuffer)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 ////////////////////////////////////////////////////////////////////////////////
VencTest_Initialize()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 ////////////////////////////////////////////////////////////////////////////////
VencTest_RegisterYUVBuffer(OMX_BUFFERHEADERTYPE ** ppBufferHeader,OMX_U8 * pBuffer,OMX_PTR pAppPrivate)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 ////////////////////////////////////////////////////////////////////////////////
VencTest_EncodeFrame(void * pYUVBuff,long long nTimeStamp)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 ////////////////////////////////////////////////////////////////////////////////
VencTest_Exit(void)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 
VencTest_ReadDynamicConfigMsg()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 
VencTest_ProcessDynamicConfigurationFile()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 ////////////////////////////////////////////////////////////////////////////////
VencTest_ReadAndEmpty(OMX_BUFFERHEADERTYPE * pYUVBuffer)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 ////////////////////////////////////////////////////////////////////////////////
PreviewCallback(int nFD,int nOffset,void * pPhys,void * pVirt,long long nTimeStamp)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 ////////////////////////////////////////////////////////////////////////////////
usage(char * filename)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 
parseWxH(char * str,OMX_U32 * width,OMX_U32 * height)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 ////////////////////////////////////////////////////////////////////////////////
parseArgs(int argc,char ** argv)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 
Watchdog(void * data)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 
main(int argc,char ** argv)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