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