1 /*--------------------------------------------------------------------------
2 Copyright (c) 2010 - 2014, 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 An Open max test application ....
30 */
31
32 #define LOG_TAG "OMX-VDEC-TEST"
33
34 #include <stdio.h>
35 #include <string.h>
36 #include <stdlib.h>
37 #include <unistd.h>
38 #include <math.h>
39 #include <media/msm_media_info.h>
40 #include <fcntl.h>
41 #include <sys/types.h>
42 #include <sys/mman.h>
43 #include <time.h>
44 #include <sys/ioctl.h>
45 #include <errno.h>
46 #include <pthread.h>
47 #include <semaphore.h>
48 #include "OMX_QCOMExtns.h"
49 #include <sys/time.h>
50 #include <cutils/properties.h>
51
52 #ifdef _ANDROID_
53 #include <binder/MemoryHeapBase.h>
54
55 extern "C" {
56 #include<utils/Log.h>
57 }
58 #define DEBUG_PRINT
59 #define DEBUG_PRINT_ERROR ALOGE
60
61 //#define __DEBUG_DIVX__ // Define this macro to print (through logcat)
62 // the kind of frames packed per buffer and
63 // timestamps adjustments for divx.
64
65 //#define TEST_TS_FROM_SEI // Define this macro to calculate the timestamps
66 // from the SEI and VUI data for H264
67
68 #else
69 #include <glib.h>
70 #define strlcpy g_strlcpy
71
72 #define ALOGE(fmt, args...) fprintf(stderr, fmt, ##args)
73 #define DEBUG_PRINT printf
74 #define DEBUG_PRINT_ERROR printf
75 #endif /* _ANDROID_ */
76
77 #include "OMX_Core.h"
78 #include "OMX_Component.h"
79 #include "OMX_QCOMExtns.h"
80 extern "C" {
81 #include "queue.h"
82 }
83
84 #include <inttypes.h>
85 #include <linux/msm_mdp.h>
86 #include <linux/fb.h>
87
88 /************************************************************************/
89 /* #DEFINES */
90 /************************************************************************/
91 #define DELAY 66
92 #define false 0
93 #define true 1
94 #define H264_START_CODE 0x00000001
95 #define VOP_START_CODE 0x000001B6
96 #define SHORT_HEADER_START_CODE 0x00008000
97 #define MPEG2_FRAME_START_CODE 0x00000100
98 #define MPEG2_SEQ_START_CODE 0x000001B3
99 #define VC1_START_CODE 0x00000100
100 #define VC1_FRAME_START_CODE 0x0000010D
101 #define VC1_FRAME_FIELD_CODE 0x0000010C
102 #define VC1_SEQUENCE_START_CODE 0x0000010F
103 #define VC1_ENTRY_POINT_START_CODE 0x0000010E
104 #define NUMBER_OF_ARBITRARYBYTES_READ (4 * 1024)
105 #define VC1_SEQ_LAYER_SIZE_WITHOUT_STRUCTC 32
106 #define VC1_SEQ_LAYER_SIZE_V1_WITHOUT_STRUCTC 16
107 static int previous_vc1_au = 0;
108 #define CONFIG_VERSION_SIZE(param) \
109 param.nVersion.nVersion = CURRENT_OMX_SPEC_VERSION;\
110 param.nSize = sizeof(param);
111
112 #define FAILED(result) (result != OMX_ErrorNone)
113
114 #define SUCCEEDED(result) (result == OMX_ErrorNone)
115 #define SWAPBYTES(ptrA, ptrB) { char t = *ptrA; *ptrA = *ptrB; *ptrB = t;}
116 #define SIZE_NAL_FIELD_MAX 4
117 #define MDP_DEINTERLACE 0x80000000
118
119 #define ALLOCATE_BUFFER 0
120
121 #ifdef MAX_RES_720P
122 #define PMEM_DEVICE "/dev/pmem_adsp"
123 #elif MAX_RES_1080P_EBI
124 #define PMEM_DEVICE "/dev/pmem_adsp"
125 #elif MAX_RES_1080P
126 #define PMEM_DEVICE "/dev/pmem_smipool"
127 #endif
128
129 //#define USE_EXTERN_PMEM_BUF
130
131 /************************************************************************/
132 /* GLOBAL DECLARATIONS */
133 /************************************************************************/
134 #ifdef _ANDROID_
135 using namespace android;
136 #endif
137
138 #ifdef _MSM8974_
139 typedef unsigned short int uint16;
140 const uint16 CRC_INIT = 0xFFFF ;
141
142 const uint16 crc_16_l_table[ 256 ] = {
143 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
144 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
145 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
146 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
147 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
148 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
149 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
150 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
151 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
152 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
153 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
154 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
155 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
156 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
157 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
158 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
159 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
160 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
161 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
162 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
163 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
164 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
165 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
166 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
167 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
168 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
169 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
170 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
171 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
172 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
173 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
174 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
175 };
176
177 #ifdef ANDROID_JELLYBEAN_MR1
178 //Since this is unavailable on Android 4.2.2, defining it in terms of base 10
log2f(const float & x)179 static inline float log2f(const float& x)
180 {
181 return log(x) / log(2);
182 }
183 #endif
184
185 /* fwrite doesn't necessarily write the entire buffer in one shot hence a helper
186 * function to make sure the entire buffer is written */
fwrite_helper(const void * ptr,size_t size,size_t nmemb,FILE * stream)187 size_t fwrite_helper(const void *ptr, size_t size, size_t nmemb, FILE *stream)
188 {
189 size_t written = 0, to_write = size * nmemb;
190 const char *ptr2 = (char *)ptr;
191
192 while (written < to_write) {
193 /* XXX: Ideally we'd like to do fwrite(..., size, 1, ...) as it makes
194 * more sense, but fwrite(..., 1, size, ...) seems to give better perf.
195 * for some reason. Seems contrary to what one would expect */
196 size_t temp = fwrite(ptr2 + written, 1, to_write - written, stream);
197
198 if (!temp && ferror(stream)) {
199 printf("Error while writing\n");
200 return temp;
201 }
202 written += temp;
203 }
204
205 return written;
206 }
207
crc_16_l_step_nv12(uint16 seed,const void * buf_ptr,unsigned int byte_len,unsigned int height,unsigned int width)208 uint16 crc_16_l_step_nv12 (uint16 seed, const void *buf_ptr,
209 unsigned int byte_len, unsigned int height, unsigned int width)
210 {
211 uint16 crc_16 = ~seed;
212 char *buf = (char *)buf_ptr;
213 char *byte_ptr = buf;
214 unsigned int i, j;
215 const unsigned int width_align = 32;
216 const unsigned int height_align = 32;
217 unsigned int stride = (width + width_align -1) & (~(width_align-1));
218 unsigned int scan_lines = (height + height_align -1) & (~(height_align-1));
219 for (i = 0; i < height; i++) {
220 for (j = 0; j < stride; j++) {
221 if (j < width) {
222 crc_16 = crc_16_l_table[ (crc_16 ^ *byte_ptr) & 0x00ff ] ^ (crc_16 >> 8);
223 }
224 byte_ptr++;
225 }
226 }
227 byte_ptr = buf + (scan_lines * stride);
228 for (i = scan_lines; i < scan_lines + height/2; i++) {
229 for (j = 0; j < stride; j++) {
230 if (j < width) {
231 crc_16 = crc_16_l_table[ (crc_16 ^ *byte_ptr) & 0x00ff ] ^ (crc_16 >> 8);
232 }
233 byte_ptr++;
234 }
235 }
236 return( ~crc_16 );
237 }
238 #endif
239
240 typedef enum {
241 CODEC_FORMAT_H264 = 1,
242 CODEC_FORMAT_MP4,
243 CODEC_FORMAT_H263,
244 CODEC_FORMAT_VC1,
245 CODEC_FORMAT_DIVX,
246 CODEC_FORMAT_MPEG2,
247 #ifdef _MSM8974_
248 CODEC_FORMAT_VP8,
249 CODEC_FORMAT_HEVC,
250 CODEC_FORMAT_HEVC_HYBRID,
251 CODEC_FORMAT_MVC,
252 #endif
253 CODEC_FORMAT_MAX
254 } codec_format;
255
256 typedef enum {
257 FILE_TYPE_DAT_PER_AU = 1,
258 FILE_TYPE_ARBITRARY_BYTES,
259 FILE_TYPE_COMMON_CODEC_MAX,
260
261 FILE_TYPE_START_OF_H264_SPECIFIC = 10,
262 FILE_TYPE_264_NAL_SIZE_LENGTH = FILE_TYPE_START_OF_H264_SPECIFIC,
263 FILE_TYPE_264_START_CODE_BASED,
264
265 FILE_TYPE_START_OF_MP4_SPECIFIC = 20,
266 FILE_TYPE_PICTURE_START_CODE = FILE_TYPE_START_OF_MP4_SPECIFIC,
267
268 FILE_TYPE_START_OF_VC1_SPECIFIC = 30,
269 FILE_TYPE_RCV = FILE_TYPE_START_OF_VC1_SPECIFIC,
270 FILE_TYPE_VC1,
271
272 FILE_TYPE_START_OF_DIVX_SPECIFIC = 40,
273 FILE_TYPE_DIVX_4_5_6 = FILE_TYPE_START_OF_DIVX_SPECIFIC,
274 FILE_TYPE_DIVX_311,
275
276 FILE_TYPE_START_OF_MPEG2_SPECIFIC = 50,
277 FILE_TYPE_MPEG2_START_CODE = FILE_TYPE_START_OF_MPEG2_SPECIFIC,
278
279 #ifdef _MSM8974_
280 FILE_TYPE_START_OF_VP8_SPECIFIC = 60,
281 FILE_TYPE_VP8_START_CODE = FILE_TYPE_START_OF_VP8_SPECIFIC,
282 FILE_TYPE_VP8,
283
284 FILE_TYPE_MVC = 5,
285 #endif
286
287 } file_type;
288
289 typedef enum {
290 GOOD_STATE = 0,
291 PORT_SETTING_CHANGE_STATE,
292 ERROR_STATE
293 } test_status;
294
295 typedef enum {
296 FREE_HANDLE_AT_LOADED = 1,
297 FREE_HANDLE_AT_IDLE,
298 FREE_HANDLE_AT_EXECUTING,
299 FREE_HANDLE_AT_PAUSE
300 } freeHandle_test;
301
302 struct temp_egl {
303 int pmem_fd;
304 int offset;
305 };
306
307 static int (*Read_Buffer)(OMX_BUFFERHEADERTYPE *pBufHdr );
308
309 int inputBufferFileFd;
310
311 FILE * outputBufferFile;
312 #ifdef _MSM8974_
313 FILE * crcFile;
314 #endif
315 FILE * seqFile;
316 int takeYuvLog = 0;
317 int displayYuv = 0;
318 int displayWindow = 0;
319 int realtime_display = 0;
320 int num_frames_to_decode = 0;
321 int thumbnailMode = 0;
322
323 Queue *etb_queue = NULL;
324 Queue *fbd_queue = NULL;
325
326 pthread_t ebd_thread_id;
327 pthread_t fbd_thread_id;
328 void* ebd_thread(void*);
329 void* fbd_thread(void*);
330
331 pthread_mutex_t etb_lock;
332 pthread_mutex_t fbd_lock;
333 pthread_mutex_t lock;
334 pthread_cond_t cond;
335 pthread_mutex_t eos_lock;
336 pthread_cond_t eos_cond;
337 pthread_mutex_t enable_lock;
338
339 sem_t etb_sem;
340 sem_t fbd_sem;
341 sem_t seq_sem;
342 sem_t in_flush_sem, out_flush_sem;
343
344 OMX_PARAM_PORTDEFINITIONTYPE portFmt;
345 OMX_PORT_PARAM_TYPE portParam;
346 OMX_ERRORTYPE error;
347 OMX_COLOR_FORMATTYPE color_fmt;
348 static bool input_use_buffer = false,output_use_buffer = false;
349 QOMX_VIDEO_DECODER_PICTURE_ORDER picture_order;
350
351 #ifdef MAX_RES_1080P
352 unsigned int color_fmt_type = 1;
353 #else
354 unsigned int color_fmt_type = 0;
355 #endif
356
357 #define CLR_KEY 0xe8fd
358 #define COLOR_BLACK_RGBA_8888 0x00000000
359 #define FRAMEBUFFER_32
360
361 static int fb_fd = -1;
362 static struct fb_var_screeninfo vinfo;
363 static struct fb_fix_screeninfo finfo;
364 static struct mdp_overlay overlay, *overlayp;
365 static struct msmfb_overlay_data ov_front;
366 static int vid_buf_front_id;
367 static char tempbuf[16];
368 int overlay_fb(struct OMX_BUFFERHEADERTYPE *pBufHdr);
369 void overlay_set();
370 void overlay_unset();
371 void render_fb(struct OMX_BUFFERHEADERTYPE *pBufHdr);
372 int disable_output_port();
373 int enable_output_port();
374 int output_port_reconfig();
375 void free_output_buffers();
376 int open_display();
377 void close_display();
378 /************************************************************************/
379 /* GLOBAL INIT */
380 /************************************************************************/
381 int input_buf_cnt = 0;
382 int height =0, width =0;
383 int sliceheight = 0, stride = 0;
384 int used_ip_buf_cnt = 0;
385 unsigned free_op_buf_cnt = 0;
386 volatile int event_is_done = 0;
387 int ebd_cnt= 0, fbd_cnt = 0;
388 int bInputEosReached = 0;
389 int bOutputEosReached = 0;
390 char in_filename[512];
391 #ifdef _MSM8974_
392 char crclogname[512];
393 #endif
394 char seq_file_name[512];
395 unsigned char seq_enabled = 0;
396 bool anti_flickering = true;
397 unsigned char flush_input_progress = 0, flush_output_progress = 0;
398 unsigned cmd_data = ~(unsigned)0, etb_count = 0;
399
400 char curr_seq_command[100];
401 OMX_S64 timeStampLfile = 0;
402 int fps = 30;
403 unsigned int timestampInterval = 33333;
404 codec_format codec_format_option;
405 file_type file_type_option;
406 freeHandle_test freeHandle_option;
407 int nalSize = 0;
408 int sent_disabled = 0;
409 int waitForPortSettingsChanged = 1;
410 test_status currentStatus = GOOD_STATE;
411 struct timeval t_start = {0, 0}, t_end = {0, 0};
412
413 //* OMX Spec Version supported by the wrappers. Version = 1.1 */
414 const OMX_U32 CURRENT_OMX_SPEC_VERSION = 0x00000101;
415 OMX_COMPONENTTYPE* dec_handle = 0;
416
417 OMX_BUFFERHEADERTYPE **pInputBufHdrs = NULL;
418 OMX_BUFFERHEADERTYPE **pOutYUVBufHdrs= NULL;
419
420 static OMX_BOOL use_external_pmem_buf = OMX_FALSE;
421
422 int rcv_v1=0;
423 static struct temp_egl **p_eglHeaders = NULL;
424 static unsigned use_buf_virt_addr[32];
425
426 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList = NULL;
427 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry = NULL;
428 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
429 OMX_CONFIG_RECTTYPE crop_rect = {0, {{0, 0, 0, 0}}, 0, 0, 0, 0, 0};
430
431 static int bHdrflag = 0;
432
433 /* Performance related variable*/
434 //QPERF_INIT(render_fb);
435 //QPERF_INIT(client_decode);
436
437 /************************************************************************/
438 /* GLOBAL FUNC DECL */
439 /************************************************************************/
440 int Init_Decoder();
441 int Play_Decoder();
442 int run_tests();
443
444 /**************************************************************************/
445 /* STATIC DECLARATIONS */
446 /**************************************************************************/
447 static int video_playback_count = 1;
448 static int open_video_file ();
449 static int Read_Buffer_From_DAT_File(OMX_BUFFERHEADERTYPE *pBufHdr );
450 static int Read_Buffer_From_H264_Start_Code_File(OMX_BUFFERHEADERTYPE *pBufHdr);
451 static int Read_Buffer_ArbitraryBytes(OMX_BUFFERHEADERTYPE *pBufHdr);
452 static int Read_Buffer_From_Vop_Start_Code_File(OMX_BUFFERHEADERTYPE *pBufHdr);
453 static int Read_Buffer_From_Mpeg2_Start_Code(OMX_BUFFERHEADERTYPE *pBufHdr);
454 static int Read_Buffer_From_Size_Nal(OMX_BUFFERHEADERTYPE *pBufHdr);
455 static int Read_Buffer_From_RCV_File_Seq_Layer(OMX_BUFFERHEADERTYPE *pBufHdr);
456 static int Read_Buffer_From_RCV_File(OMX_BUFFERHEADERTYPE *pBufHdr);
457 #ifdef _MSM8974_
458 static int Read_Buffer_From_VP8_File(OMX_BUFFERHEADERTYPE *pBufHdr);
459 static int Read_Buffer_From_MVC_File(OMX_BUFFERHEADERTYPE *pBufHdr);
460 #endif
461 static int Read_Buffer_From_VC1_File(OMX_BUFFERHEADERTYPE *pBufHdr);
462 static int Read_Buffer_From_DivX_4_5_6_File(OMX_BUFFERHEADERTYPE *pBufHdr);
463 static int Read_Buffer_From_DivX_311_File(OMX_BUFFERHEADERTYPE *pBufHdr);
464
465 static OMX_ERRORTYPE Allocate_Buffer ( OMX_COMPONENTTYPE *dec_handle,
466 OMX_BUFFERHEADERTYPE ***pBufHdrs,
467 OMX_U32 nPortIndex,
468 long bufCntMin, long bufSize);
469
470 static OMX_ERRORTYPE use_input_buffer(OMX_COMPONENTTYPE *dec_handle,
471 OMX_BUFFERHEADERTYPE ***bufferHdr,
472 OMX_U32 nPortIndex,
473 OMX_U32 bufSize,
474 long bufcnt);
475
476 static OMX_ERRORTYPE use_output_buffer(OMX_COMPONENTTYPE *dec_handle,
477 OMX_BUFFERHEADERTYPE ***bufferHdr,
478 OMX_U32 nPortIndex,
479 OMX_U32 bufSize,
480 long bufcnt);
481
482 static OMX_ERRORTYPE use_output_buffer_multiple_fd(OMX_COMPONENTTYPE *dec_handle,
483 OMX_BUFFERHEADERTYPE ***bufferHdr,
484 OMX_U32 nPortIndex,
485 OMX_U32 bufSize,
486 long bufcnt);
487
488 static OMX_ERRORTYPE EventHandler(OMX_IN OMX_HANDLETYPE hComponent,
489 OMX_IN OMX_PTR pAppData,
490 OMX_IN OMX_EVENTTYPE eEvent,
491 OMX_IN OMX_U32 nData1, OMX_IN OMX_U32 nData2,
492 OMX_IN OMX_PTR pEventData);
493 static OMX_ERRORTYPE EmptyBufferDone(OMX_IN OMX_HANDLETYPE hComponent,
494 OMX_IN OMX_PTR pAppData,
495 OMX_IN OMX_BUFFERHEADERTYPE* pBuffer);
496 static OMX_ERRORTYPE FillBufferDone(OMX_OUT OMX_HANDLETYPE hComponent,
497 OMX_OUT OMX_PTR pAppData,
498 OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer);
499
500 static void do_freeHandle_and_clean_up(bool isDueToError);
501
502 #ifndef USE_ION
503 static bool align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
504 OMX_U32 alignment);
505 #endif
506 void getFreePmem();
507 static int overlay_vsync_ctrl(int enable);
508
clip2(int x)509 static int clip2(int x)
510 {
511 x = x -1;
512 x = x | x >> 1;
513 x = x | x >> 2;
514 x = x | x >> 4;
515 x = x | x >> 16;
516 x = x + 1;
517 return x;
518 }
wait_for_event(void)519 void wait_for_event(void)
520 {
521 DEBUG_PRINT("Waiting for event\n");
522 pthread_mutex_lock(&lock);
523 while (event_is_done == 0) {
524 pthread_cond_wait(&cond, &lock);
525 }
526 event_is_done = 0;
527 pthread_mutex_unlock(&lock);
528 DEBUG_PRINT("Running .... get the event\n");
529 }
530
event_complete(void)531 void event_complete(void )
532 {
533 pthread_mutex_lock(&lock);
534 if (event_is_done == 0) {
535 event_is_done = 1;
536 pthread_cond_broadcast(&cond);
537 }
538 pthread_mutex_unlock(&lock);
539 }
get_next_command(FILE * seq_file)540 int get_next_command(FILE *seq_file)
541 {
542 int i = -1;
543 do {
544 i++;
545 if (fread(&curr_seq_command[i], 1, 1, seq_file) != 1)
546 return -1;
547 } while (curr_seq_command[i] != '\n');
548 curr_seq_command[i] = 0;
549 printf("\n cmd_str = %s", curr_seq_command);
550 return 0;
551 }
552
process_current_command(const char * seq_command)553 int process_current_command(const char *seq_command)
554 {
555 char *data_str = NULL;
556 unsigned int data = 0, bufCnt = 0, i = 0;
557 int frameSize;
558
559 if (strstr(seq_command, "pause") == seq_command) {
560 printf("\n\n $$$$$ PAUSE $$$$$");
561 data_str = (char*)seq_command + strlen("pause") + 1;
562 data = atoi(data_str);
563 printf("\n After frame number %u", data);
564 cmd_data = data;
565 sem_wait(&seq_sem);
566 if (!bOutputEosReached && !bInputEosReached) {
567 printf("\n Sending PAUSE cmd to OMX compt");
568 OMX_SendCommand(dec_handle, OMX_CommandStateSet, OMX_StatePause,0);
569 wait_for_event();
570 printf("\n EventHandler for PAUSE DONE");
571 } else
572 seq_enabled = 0;
573 } else if (strstr(seq_command, "sleep") == seq_command) {
574 printf("\n\n $$$$$ SLEEP $$$$$");
575 data_str = (char*)seq_command + strlen("sleep") + 1;
576 data = atoi(data_str);
577 printf("\n Sleep Time = %u ms", data);
578 usleep(data*1000);
579 } else if (strstr(seq_command, "resume") == seq_command) {
580 printf("\n\n $$$$$ RESUME $$$$$");
581 printf("\n Immediate effect");
582 printf("\n Sending RESUME cmd to OMX compt");
583 OMX_SendCommand(dec_handle, OMX_CommandStateSet, OMX_StateExecuting,0);
584 wait_for_event();
585 printf("\n EventHandler for RESUME DONE");
586 } else if (strstr(seq_command, "flush") == seq_command) {
587 printf("\n\n $$$$$ FLUSH $$$$$");
588 data_str = (char*)seq_command + strlen("flush") + 1;
589 data = atoi(data_str);
590 printf("\n After frame number %u", data);
591 if (previous_vc1_au) {
592 printf("\n Flush not allowed on Field boundary");
593 return 0;
594 }
595 cmd_data = data;
596 sem_wait(&seq_sem);
597 if (!bOutputEosReached && !bInputEosReached) {
598 printf("\n Sending FLUSH cmd to OMX compt");
599 flush_input_progress = 1;
600 flush_output_progress = 1;
601 OMX_SendCommand(dec_handle, OMX_CommandFlush, OMX_ALL, 0);
602 wait_for_event();
603 printf("\n EventHandler for FLUSH DONE");
604 printf("\n Post EBD_thread flush sem");
605 sem_post(&in_flush_sem);
606 printf("\n Post FBD_thread flush sem");
607 sem_post(&out_flush_sem);
608 } else
609 seq_enabled = 0;
610 } else if (strstr(seq_command, "disable_op") == seq_command) {
611 printf("\n\n $$$$$ DISABLE OP PORT $$$$$");
612 data_str = (char*)seq_command + strlen("disable_op") + 1;
613 data = atoi(data_str);
614 printf("\n After frame number %u", data);
615 cmd_data = data;
616 sem_wait(&seq_sem);
617 printf("\n Sending DISABLE OP cmd to OMX compt");
618 if (disable_output_port() != 0) {
619 printf("\n ERROR: While DISABLE OP...");
620 do_freeHandle_and_clean_up(true);
621 return -1;
622 } else
623 printf("\n EventHandler for DISABLE OP");
624 } else if (strstr(seq_command, "enable_op") == seq_command) {
625 printf("\n\n $$$$$ ENABLE OP PORT $$$$$");
626 data_str = (char*)seq_command + strlen("enable_op") + 1;
627 printf("\n Sending ENABLE OP cmd to OMX compt");
628 if (enable_output_port() != 0) {
629 printf("\n ERROR: While ENABLE OP...");
630 do_freeHandle_and_clean_up(true);
631 return -1;
632 } else
633 printf("\n EventHandler for ENABLE OP");
634 } else {
635 printf("\n\n $$$$$ INVALID CMD $$$$$");
636 printf("\n seq_command[%s] is invalid", seq_command);
637 seq_enabled = 0;
638 }
639 return 0;
640 }
641
PrintFramePackArrangement(OMX_QCOM_FRAME_PACK_ARRANGEMENT framePackingArrangement)642 void PrintFramePackArrangement(OMX_QCOM_FRAME_PACK_ARRANGEMENT framePackingArrangement)
643 {
644 if (framePackingArrangement.cancel_flag == 1) {
645 /* Not worth printing out because the struct doesn't contain
646 * valid or useful data */
647 return;
648 }
649
650 printf("id (%u)\n",
651 (unsigned int)framePackingArrangement.id);
652 printf("cancel_flag (%u)\n",
653 (unsigned int)framePackingArrangement.cancel_flag);
654 printf("type (%u)\n",
655 (unsigned int)framePackingArrangement.type);
656 printf("quincunx_sampling_flag (%u)\n",
657 (unsigned int)framePackingArrangement.quincunx_sampling_flag);
658 printf("content_interpretation_type (%u)\n",
659 (unsigned int)framePackingArrangement.content_interpretation_type);
660 printf("spatial_flipping_flag (%u)\n",
661 (unsigned int)framePackingArrangement.spatial_flipping_flag);
662 printf("frame0_flipped_flag (%u)\n",
663 (unsigned int)framePackingArrangement.frame0_flipped_flag);
664 printf("field_views_flag (%u)\n",
665 (unsigned int)framePackingArrangement.field_views_flag);
666 printf("current_frame_is_frame0_flag (%u)\n",
667 (unsigned int)framePackingArrangement.current_frame_is_frame0_flag);
668 printf("frame0_self_contained_flag (%u)\n",
669 (unsigned int)framePackingArrangement.frame0_self_contained_flag);
670 printf("frame1_self_contained_flag (%u)\n",
671 (unsigned int)framePackingArrangement.frame1_self_contained_flag);
672 printf("frame0_grid_position_x (%u)\n",
673 (unsigned int)framePackingArrangement.frame0_grid_position_x);
674 printf("frame0_grid_position_y (%u)\n",
675 (unsigned int)framePackingArrangement.frame0_grid_position_y);
676 printf("frame1_grid_position_x (%u)\n",
677 (unsigned int)framePackingArrangement.frame1_grid_position_x);
678 printf("frame1_grid_position_y (%u)\n",
679 (unsigned int)framePackingArrangement.frame1_grid_position_y);
680 printf("reserved_byte (%u)\n",
681 (unsigned int)framePackingArrangement.reserved_byte);
682 printf("repetition_period (%u)\n",
683 (unsigned int)framePackingArrangement.repetition_period);
684 printf("extension_flag (%u)\n",
685 (unsigned int)framePackingArrangement.extension_flag);
686 }
ebd_thread(void * pArg)687 void* ebd_thread(void* pArg)
688 {
689 int signal_eos = 0;
690 while (currentStatus != ERROR_STATE) {
691 int readBytes =0;
692 OMX_BUFFERHEADERTYPE* pBuffer = NULL;
693
694 if (flush_input_progress) {
695 DEBUG_PRINT("\n EBD_thread flush wait start");
696 sem_wait(&in_flush_sem);
697 DEBUG_PRINT("\n EBD_thread flush wait complete");
698 }
699
700 sem_wait(&etb_sem);
701 pthread_mutex_lock(&etb_lock);
702 pBuffer = (OMX_BUFFERHEADERTYPE *) pop(etb_queue);
703 pthread_mutex_unlock(&etb_lock);
704 if (pBuffer == NULL) {
705 DEBUG_PRINT_ERROR("Error - No etb pBuffer to dequeue\n");
706 continue;
707 }
708
709 if (num_frames_to_decode && (etb_count >= (unsigned int)num_frames_to_decode)) {
710 printf("\n Signal EOS %d frames decoded \n", num_frames_to_decode);
711 signal_eos = 1;
712 }
713
714 pBuffer->nOffset = 0;
715 if (((readBytes = Read_Buffer(pBuffer)) > 0) && !signal_eos) {
716 pBuffer->nFilledLen = readBytes;
717 DEBUG_PRINT("%s: Timestamp sent(%lld)", __FUNCTION__, pBuffer->nTimeStamp);
718 OMX_EmptyThisBuffer(dec_handle,pBuffer);
719 etb_count++;
720 } else {
721 pBuffer->nFlags |= OMX_BUFFERFLAG_EOS;
722 bInputEosReached = true;
723 pBuffer->nFilledLen = readBytes;
724 DEBUG_PRINT("%s: Timestamp sent(%lld)", __FUNCTION__, pBuffer->nTimeStamp);
725 OMX_EmptyThisBuffer(dec_handle,pBuffer);
726 DEBUG_PRINT("EBD::Either EOS or Some Error while reading file\n");
727 etb_count++;
728 break;
729 }
730 }
731 return NULL;
732 }
733
fbd_thread(void * pArg)734 void* fbd_thread(void* pArg)
735 {
736 long unsigned act_time = 0, display_time = 0, render_time = 5e3, lipsync = 15e3;
737 struct timeval t_avsync = {0, 0}, base_avsync = {0, 0};
738 float total_time = 0;
739 int canDisplay = 1, contigous_drop_frame = 0, bytes_written = 0, ret = 0;
740 OMX_S64 base_timestamp = 0, lastTimestamp = 0;
741 OMX_BUFFERHEADERTYPE *pBuffer = NULL, *pPrevBuff = NULL;
742 char value[PROPERTY_VALUE_MAX] = {0};
743 OMX_U32 aspectratio_prop = 0;
744 pthread_mutex_lock(&eos_lock);
745 #ifdef _MSM8974_
746 int stride,scanlines,stride_c,i;
747 #endif
748 DEBUG_PRINT("First Inside %s\n", __FUNCTION__);
749 property_get("vidc.vdec.debug.aspectratio", value, "0");
750 aspectratio_prop = atoi(value);
751 while (currentStatus != ERROR_STATE && !bOutputEosReached) {
752 pthread_mutex_unlock(&eos_lock);
753 DEBUG_PRINT("Inside %s\n", __FUNCTION__);
754 if (flush_output_progress) {
755 DEBUG_PRINT("\n FBD_thread flush wait start");
756 sem_wait(&out_flush_sem);
757 DEBUG_PRINT("\n FBD_thread flush wait complete");
758 }
759 sem_wait(&fbd_sem);
760 pthread_mutex_lock(&enable_lock);
761 if (sent_disabled) {
762 pthread_mutex_unlock(&enable_lock);
763 pthread_mutex_lock(&fbd_lock);
764 if (pPrevBuff != NULL ) {
765 if (push(fbd_queue, (void *)pBuffer))
766 DEBUG_PRINT_ERROR("Error in enqueueing fbd_data\n");
767 else
768 sem_post(&fbd_sem);
769 }
770 pPrevBuff = NULL;
771 pBuffer = NULL;
772 if (free_op_buf_cnt == portFmt.nBufferCountActual)
773 free_output_buffers();
774 pthread_mutex_unlock(&fbd_lock);
775 pthread_mutex_lock(&eos_lock);
776 continue;
777 }
778 pthread_mutex_unlock(&enable_lock);
779 if (anti_flickering)
780 pPrevBuff = pBuffer;
781 pthread_mutex_lock(&fbd_lock);
782 pBuffer = (OMX_BUFFERHEADERTYPE *)pop(fbd_queue);
783 pthread_mutex_unlock(&fbd_lock);
784 if (pBuffer == NULL) {
785 if (anti_flickering)
786 pBuffer = pPrevBuff;
787 DEBUG_PRINT("Error - No pBuffer to dequeue\n");
788 pthread_mutex_lock(&eos_lock);
789 continue;
790 } else if (pBuffer->nFilledLen > 0) {
791 if (!fbd_cnt) {
792 gettimeofday(&t_start, NULL);
793 }
794 fbd_cnt++;
795 DEBUG_PRINT("%s: fbd_cnt(%d) Buf(%p) Timestamp(%lld)",
796 __FUNCTION__, fbd_cnt, pBuffer, pBuffer->nTimeStamp);
797 canDisplay = 1;
798 if (realtime_display) {
799 if (pBuffer->nTimeStamp != (lastTimestamp + timestampInterval)) {
800 DEBUG_PRINT("Unexpected timestamp[%lld]! Expected[%lld]\n",
801 pBuffer->nTimeStamp, lastTimestamp + timestampInterval);
802 }
803 lastTimestamp = pBuffer->nTimeStamp;
804 gettimeofday(&t_avsync, NULL);
805 if (!base_avsync.tv_sec && !base_avsync.tv_usec) {
806 display_time = 0;
807 base_avsync = t_avsync;
808 base_timestamp = pBuffer->nTimeStamp;
809 DEBUG_PRINT("base_avsync Sec(%lu) uSec(%lu) base_timestamp(%lld)",
810 base_avsync.tv_sec, base_avsync.tv_usec, base_timestamp);
811 } else {
812 act_time = (t_avsync.tv_sec - base_avsync.tv_sec) * 1e6
813 + t_avsync.tv_usec - base_avsync.tv_usec;
814 display_time = pBuffer->nTimeStamp - base_timestamp;
815 DEBUG_PRINT("%s: act_time(%lu) display_time(%lu)",
816 __FUNCTION__, act_time, display_time);
817 //Frame rcvd on time
818 if (((act_time + render_time) >= (display_time - lipsync) &&
819 (act_time + render_time) <= (display_time + lipsync)) ||
820 //Display late frame
821 (contigous_drop_frame > 5))
822 display_time = 0;
823 else if ((act_time + render_time) < (display_time - lipsync))
824 //Delaying early frame
825 display_time -= (lipsync + act_time + render_time);
826 else {
827 //Dropping late frame
828 canDisplay = 0;
829 contigous_drop_frame++;
830 }
831 }
832 }
833 if (displayYuv && canDisplay) {
834 if (display_time)
835 usleep(display_time);
836 ret = overlay_fb(pBuffer);
837 if (ret != 0) {
838 printf("\nERROR in overlay_fb, disabling display!");
839 close_display();
840 displayYuv = 0;
841 }
842 usleep(render_time);
843 contigous_drop_frame = 0;
844 }
845
846 if (takeYuvLog) {
847 bytes_written = 0;
848 if (color_fmt == (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m ||
849 color_fmt == (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView) {
850 unsigned int i = 0;
851 unsigned int nViewsDone = 0;
852 unsigned int stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, portFmt.format.video.nFrameWidth);
853 unsigned int scanlines = VENUS_Y_SCANLINES(COLOR_FMT_NV12, portFmt.format.video.nFrameHeight);
854 char *frame_pos = (char *) pBuffer->pBuffer;
855 char *view2 = color_fmt == (OMX_COLOR_FORMATTYPE)
856 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView?
857 (char *) pBuffer->pBuffer +
858 VENUS_VIEW2_OFFSET(COLOR_FMT_NV12_MVTB,
859 portFmt.format.video.nFrameWidth,
860 portFmt.format.video.nFrameHeight):
861 NULL;
862 do {
863 frame_pos += (stride * (int)crop_rect.nTop) + (int)crop_rect.nLeft;
864 for (i = 0; i < crop_rect.nHeight; i++) {
865 bytes_written += fwrite_helper(frame_pos, crop_rect.nWidth, 1, outputBufferFile);
866 frame_pos += stride;
867 }
868
869 frame_pos = (nViewsDone == 0 ?
870 (char *) pBuffer->pBuffer:
871 view2) + stride * scanlines;
872 frame_pos += (stride * (int)crop_rect.nTop) + (int)crop_rect.nLeft;
873 for (i = 0; i < crop_rect.nHeight/2; i++) {
874 bytes_written += fwrite_helper(frame_pos, crop_rect.nWidth, 1, outputBufferFile);
875 frame_pos += stride;
876 }
877 nViewsDone++;
878 if (view2 != NULL) {
879 frame_pos = view2;
880 }
881 } while (view2 != NULL && nViewsDone < 2);
882 } else {
883 bytes_written = fwrite_helper((const char *)pBuffer->pBuffer,
884 pBuffer->nFilledLen,1,outputBufferFile);
885 }
886 if (bytes_written < 0) {
887 DEBUG_PRINT("\nFillBufferDone: Failed to write to the file\n");
888 } else {
889 DEBUG_PRINT("\nFillBufferDone: Wrote %d YUV bytes to the file\n",
890 bytes_written);
891 }
892 }
893 #ifdef _MSM8974_
894 if (crcFile) {
895 uint16 crc_val;
896 crc_val = crc_16_l_step_nv12(CRC_INIT, pBuffer->pBuffer,
897 pBuffer->nFilledLen, height, width);
898 unsigned int num_bytes = fwrite_helper(&crc_val, 1, sizeof(crc_val), crcFile);
899 if (num_bytes < sizeof(crc_val)) {
900 printf("Failed to write CRC value into file\n");
901 }
902 }
903 #endif
904 if (pBuffer->nFlags & OMX_BUFFERFLAG_EXTRADATA) {
905 OMX_OTHER_EXTRADATATYPE *pExtra;
906 DEBUG_PRINT_ERROR(">> BUFFER WITH EXTRA DATA RCVD <<<");
907 pExtra = (OMX_OTHER_EXTRADATATYPE *)
908 ((unsigned)(pBuffer->pBuffer + pBuffer->nOffset +
909 pBuffer->nFilledLen + 3)&(~3));
910 while (pExtra &&
911 (OMX_U8*)pExtra < (pBuffer->pBuffer + pBuffer->nAllocLen) &&
912 pExtra->eType != OMX_ExtraDataNone ) {
913 DEBUG_PRINT("ExtraData : pBuf(%p) BufTS(%lld) Type(%x) DataSz(%u)",
914 pBuffer, pBuffer->nTimeStamp, pExtra->eType, pExtra->nDataSize);
915 switch ((int)pExtra->eType) {
916 case OMX_ExtraDataInterlaceFormat:
917 {
918 OMX_STREAMINTERLACEFORMAT *pInterlaceFormat = (OMX_STREAMINTERLACEFORMAT *)pExtra->data;
919 DEBUG_PRINT("OMX_ExtraDataInterlaceFormat: Buf(%p) TSmp(%lld) IntPtr(%p) Fmt(%x)",
920 pBuffer->pBuffer, pBuffer->nTimeStamp,
921 pInterlaceFormat, pInterlaceFormat->nInterlaceFormats);
922 break;
923 }
924 case OMX_ExtraDataFrameInfo:
925 {
926 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)pExtra->data;
927 DEBUG_PRINT_ERROR("OMX_ExtraDataFrameInfo: Buf(%p) TSmp(%lld) PicType(%u) IntT(%d) ConMB(%u)",
928 pBuffer->pBuffer, pBuffer->nTimeStamp, frame_info->ePicType,
929 frame_info->interlaceType, (unsigned int)frame_info->nConcealedMacroblocks);
930 if (aspectratio_prop)
931 DEBUG_PRINT_ERROR(" FrmRate(%u), AspRatioX(%u), AspRatioY(%u) DispWidth(%u) DispHeight(%u)",
932 (unsigned int)frame_info->nFrameRate, (unsigned int)frame_info->aspectRatio.aspectRatioX,
933 (unsigned int)frame_info->aspectRatio.aspectRatioY, (unsigned int)frame_info->displayAspectRatio.displayHorizontalSize,
934 (unsigned int)frame_info->displayAspectRatio.displayVerticalSize);
935 else
936 DEBUG_PRINT_ERROR(" FrmRate(%u), AspRatioX(%u), AspRatioY(%u) DispWidth(%u) DispHeight(%u)",
937 (unsigned int)frame_info->nFrameRate, (unsigned int)frame_info->aspectRatio.aspectRatioX,
938 (unsigned int)frame_info->aspectRatio.aspectRatioY, (unsigned int)frame_info->displayAspectRatio.displayHorizontalSize,
939 (unsigned int)frame_info->displayAspectRatio.displayVerticalSize);
940 DEBUG_PRINT_ERROR("PANSCAN numWindows(%u)", (unsigned int)frame_info->panScan.numWindows);
941 for (unsigned int i = 0; i < frame_info->panScan.numWindows; i++) {
942 DEBUG_PRINT_ERROR("WINDOW Lft(%d) Tp(%d) Rgt(%d) Bttm(%d)",
943 (int)frame_info->panScan.window[i].x,
944 (int)frame_info->panScan.window[i].y,
945 (int)frame_info->panScan.window[i].dx,
946 (int)frame_info->panScan.window[i].dy);
947 }
948 break;
949 }
950 break;
951 case OMX_ExtraDataConcealMB:
952 {
953 OMX_U8 data = 0, *data_ptr = (OMX_U8 *)pExtra->data;
954 OMX_U32 concealMBnum = 0, bytes_cnt = 0;
955 while (bytes_cnt < pExtra->nDataSize) {
956 data = *data_ptr;
957 while (data) {
958 concealMBnum += (data&0x01);
959 data >>= 1;
960 }
961 data_ptr++;
962 bytes_cnt++;
963 }
964 DEBUG_PRINT_ERROR("OMX_ExtraDataConcealMB: Buf(%p) TSmp(%lld) ConcealMB(%u)",
965 pBuffer->pBuffer, pBuffer->nTimeStamp, (unsigned int)concealMBnum);
966 }
967 break;
968 case OMX_ExtraDataMP2ExtnData:
969 {
970 DEBUG_PRINT_ERROR("\nOMX_ExtraDataMP2ExtnData");
971 OMX_U8 data = 0, *data_ptr = (OMX_U8 *)pExtra->data;
972 OMX_U32 bytes_cnt = 0;
973 while (bytes_cnt < pExtra->nDataSize) {
974 DEBUG_PRINT_ERROR("\n MPEG-2 Extension Data Values[%u] = 0x%x", (unsigned int)bytes_cnt, *data_ptr);
975 data_ptr++;
976 bytes_cnt++;
977 }
978 }
979 break;
980 case OMX_ExtraDataMP2UserData:
981 {
982 DEBUG_PRINT_ERROR("\nOMX_ExtraDataMP2UserData");
983 OMX_U8 data = 0, *data_ptr = (OMX_U8 *)pExtra->data;
984 OMX_U32 bytes_cnt = 0;
985 while (bytes_cnt < pExtra->nDataSize) {
986 DEBUG_PRINT_ERROR("\n MPEG-2 User Data Values[%u] = 0x%x", (unsigned int)bytes_cnt, *data_ptr);
987 data_ptr++;
988 bytes_cnt++;
989 }
990 }
991 break;
992 case OMX_ExtraDataQP:
993 {
994 DEBUG_PRINT("\nOMX_ExtraDataQP\n");
995 OMX_QCOM_EXTRADATA_QP *qp_info = (OMX_QCOM_EXTRADATA_QP *)pExtra->data;
996 DEBUG_PRINT("Input frame QP = %lu\n", qp_info->nQP);
997 }
998 break;
999 case OMX_ExtraDataInputBitsInfo:
1000 {
1001 DEBUG_PRINT("\nOMX_ExtraDataInputBitsInfo\n");
1002 OMX_QCOM_EXTRADATA_BITS_INFO *bits_info = (OMX_QCOM_EXTRADATA_BITS_INFO *)pExtra->data;
1003 DEBUG_PRINT("Input header bits size = %lu\n", bits_info->header_bits);
1004 DEBUG_PRINT("Input frame bits size = %lu\n", bits_info->frame_bits);
1005 }
1006 break;
1007 default:
1008 DEBUG_PRINT_ERROR("Unknown Extrata!");
1009 }
1010 if (pExtra->nSize < (pBuffer->nAllocLen - (OMX_U32)pExtra))
1011 pExtra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) pExtra) + pExtra->nSize);
1012 else {
1013 DEBUG_PRINT_ERROR("ERROR: Extradata pointer overflow buffer(%p) extra(%p)",
1014 pBuffer, pExtra);
1015 pExtra = NULL;
1016 }
1017 }
1018 }
1019 }
1020 if (pBuffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
1021 DEBUG_PRINT("\n");
1022 DEBUG_PRINT("***************************************************\n");
1023 DEBUG_PRINT("FillBufferDone: End Of Sequence Received\n");
1024 DEBUG_PRINT("***************************************************\n");
1025 }
1026 if (pBuffer->nFlags & OMX_BUFFERFLAG_DATACORRUPT) {
1027 DEBUG_PRINT("\n");
1028 DEBUG_PRINT("***************************************************\n");
1029 DEBUG_PRINT("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received\n");
1030 DEBUG_PRINT("***************************************************\n");
1031 }
1032 /********************************************************************/
1033 /* De-Initializing the open max and relasing the buffers and */
1034 /* closing the files.*/
1035 /********************************************************************/
1036 if (pBuffer->nFlags & OMX_BUFFERFLAG_EOS ) {
1037 OMX_QCOM_FRAME_PACK_ARRANGEMENT framePackingArrangement;
1038 OMX_GetConfig(dec_handle,
1039 (OMX_INDEXTYPE)OMX_QcomIndexConfigVideoFramePackingArrangement,
1040 &framePackingArrangement);
1041 PrintFramePackArrangement(framePackingArrangement);
1042
1043 gettimeofday(&t_end, NULL);
1044 total_time = ((float) ((t_end.tv_sec - t_start.tv_sec) * 1e6
1045 + t_end.tv_usec - t_start.tv_usec))/ 1e6;
1046 //total frames is fbd_cnt - 1 since the start time is
1047 //recorded after the first frame is decoded.
1048 printf("\nAvg decoding frame rate=%f\n", (fbd_cnt - 1)/total_time);
1049
1050 DEBUG_PRINT("***************************************************\n");
1051 DEBUG_PRINT("FillBufferDone: End Of Stream Reached\n");
1052 DEBUG_PRINT("***************************************************\n");
1053 pthread_mutex_lock(&eos_lock);
1054 bOutputEosReached = true;
1055 break;
1056 }
1057
1058 pthread_mutex_lock(&enable_lock);
1059 if (flush_output_progress || sent_disabled) {
1060 pBuffer->nFilledLen = 0;
1061 pBuffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
1062 pthread_mutex_lock(&fbd_lock);
1063 if ( pPrevBuff != NULL ) {
1064 if (push(fbd_queue, (void *)pPrevBuff))
1065 DEBUG_PRINT_ERROR("Error in enqueueing fbd_data\n");
1066 else
1067 sem_post(&fbd_sem);
1068 pPrevBuff = NULL;
1069 }
1070 if (push(fbd_queue, (void *)pBuffer) < 0) {
1071 DEBUG_PRINT_ERROR("Error in enqueueing fbd_data\n");
1072 } else
1073 sem_post(&fbd_sem);
1074 pthread_mutex_unlock(&fbd_lock);
1075 } else {
1076 if (!anti_flickering)
1077 pPrevBuff = pBuffer;
1078 if (pPrevBuff) {
1079 pthread_mutex_lock(&fbd_lock);
1080 pthread_mutex_lock(&eos_lock);
1081 if (!bOutputEosReached) {
1082 if ( OMX_FillThisBuffer(dec_handle, pPrevBuff) == OMX_ErrorNone ) {
1083 free_op_buf_cnt--;
1084 }
1085 }
1086 pthread_mutex_unlock(&eos_lock);
1087 pthread_mutex_unlock(&fbd_lock);
1088 }
1089 }
1090 pthread_mutex_unlock(&enable_lock);
1091 if (cmd_data <= (unsigned)fbd_cnt) {
1092 sem_post(&seq_sem);
1093 printf("\n Posted seq_sem Frm(%d) Req(%d)", fbd_cnt, cmd_data);
1094 cmd_data = ~(unsigned)0;
1095 }
1096 pthread_mutex_lock(&eos_lock);
1097 }
1098 if (seq_enabled) {
1099 seq_enabled = 0;
1100 sem_post(&seq_sem);
1101 printf("\n Posted seq_sem in EOS \n");
1102 }
1103 pthread_cond_broadcast(&eos_cond);
1104 pthread_mutex_unlock(&eos_lock);
1105 return NULL;
1106 }
1107
EventHandler(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)1108 OMX_ERRORTYPE EventHandler(OMX_IN OMX_HANDLETYPE hComponent,
1109 OMX_IN OMX_PTR pAppData,
1110 OMX_IN OMX_EVENTTYPE eEvent,
1111 OMX_IN OMX_U32 nData1, OMX_IN OMX_U32 nData2,
1112 OMX_IN OMX_PTR pEventData)
1113 {
1114 DEBUG_PRINT("Function %s \n", __FUNCTION__);
1115
1116 switch (eEvent) {
1117 case OMX_EventCmdComplete:
1118 DEBUG_PRINT("\n OMX_EventCmdComplete \n");
1119 if (OMX_CommandPortDisable == (OMX_COMMANDTYPE)nData1) {
1120 DEBUG_PRINT("*********************************************\n");
1121 DEBUG_PRINT("Recieved DISABLE Event Command Complete[%d]\n",nData2);
1122 DEBUG_PRINT("*********************************************\n");
1123 } else if (OMX_CommandPortEnable == (OMX_COMMANDTYPE)nData1) {
1124 DEBUG_PRINT("*********************************************\n");
1125 DEBUG_PRINT("Recieved ENABLE Event Command Complete[%d]\n",nData2);
1126 DEBUG_PRINT("*********************************************\n");
1127 if (currentStatus == PORT_SETTING_CHANGE_STATE)
1128 currentStatus = GOOD_STATE;
1129 pthread_mutex_lock(&enable_lock);
1130 sent_disabled = 0;
1131 pthread_mutex_unlock(&enable_lock);
1132 } else if (OMX_CommandFlush == (OMX_COMMANDTYPE)nData1) {
1133 DEBUG_PRINT("*********************************************\n");
1134 DEBUG_PRINT("Received FLUSH Event Command Complete[%d]\n",nData2);
1135 DEBUG_PRINT("*********************************************\n");
1136 if (nData2 == 0)
1137 flush_input_progress = 0;
1138 else if (nData2 == 1)
1139 flush_output_progress = 0;
1140 }
1141 if (!flush_input_progress && !flush_output_progress)
1142 event_complete();
1143 break;
1144
1145 case OMX_EventError:
1146 printf("*********************************************\n");
1147 printf("Received OMX_EventError Event Command !\n");
1148 printf("*********************************************\n");
1149 currentStatus = ERROR_STATE;
1150 if (OMX_ErrorInvalidState == (OMX_ERRORTYPE)nData1 ||
1151 OMX_ErrorHardware == (OMX_ERRORTYPE)nData1) {
1152 printf("Invalid State or hardware error \n");
1153 if (event_is_done == 0) {
1154 DEBUG_PRINT("Event error in the middle of Decode \n");
1155 pthread_mutex_lock(&eos_lock);
1156 bOutputEosReached = true;
1157 pthread_mutex_unlock(&eos_lock);
1158 if (seq_enabled) {
1159 seq_enabled = 0;
1160 sem_post(&seq_sem);
1161 printf("\n Posted seq_sem in ERROR");
1162 }
1163 event_complete();
1164 }
1165 }
1166 if (waitForPortSettingsChanged) {
1167 waitForPortSettingsChanged = 0;
1168 event_complete();
1169 }
1170 sem_post(&etb_sem);
1171 sem_post(&fbd_sem);
1172 break;
1173 case OMX_EventPortSettingsChanged:
1174 DEBUG_PRINT("OMX_EventPortSettingsChanged port[%d]\n", nData1);
1175 if (nData2 == OMX_IndexConfigCommonOutputCrop) {
1176 OMX_U32 outPortIndex = 1;
1177 if (nData1 == outPortIndex) {
1178 crop_rect.nPortIndex = outPortIndex;
1179 OMX_ERRORTYPE ret = OMX_GetConfig(dec_handle,
1180 OMX_IndexConfigCommonOutputCrop, &crop_rect);
1181 if (FAILED(ret)) {
1182 DEBUG_PRINT_ERROR("Failed to get crop rectangle\n");
1183 break;
1184 } else
1185 DEBUG_PRINT("Got Crop Rect: (%d, %d) (%d x %d)\n",
1186 crop_rect.nLeft, crop_rect.nTop, crop_rect.nWidth, crop_rect.nHeight);
1187 }
1188 currentStatus = GOOD_STATE;
1189 break;
1190 }
1191
1192 #ifdef _MSM8974_
1193 if (nData2 != OMX_IndexParamPortDefinition)
1194 break;
1195 #endif
1196 currentStatus = PORT_SETTING_CHANGE_STATE;
1197 if (waitForPortSettingsChanged) {
1198 waitForPortSettingsChanged = 0;
1199 event_complete();
1200 } else {
1201 pthread_mutex_lock(&eos_lock);
1202 pthread_cond_broadcast(&eos_cond);
1203 pthread_mutex_unlock(&eos_lock);
1204 }
1205 break;
1206
1207 case OMX_EventBufferFlag:
1208 DEBUG_PRINT("OMX_EventBufferFlag port[%d] flags[%x]\n", nData1, nData2);
1209 #if 0
1210 // we should not set the bOutputEosReached here. in stead we wait until fbd_thread to
1211 // check the flag so that all frames can be dumped for bit exactness check.
1212 if (nData1 == 1 && (nData2 & OMX_BUFFERFLAG_EOS)) {
1213 pthread_mutex_lock(&eos_lock);
1214 bOutputEosReached = true;
1215 pthread_mutex_unlock(&eos_lock);
1216 if (seq_enabled) {
1217 seq_enabled = 0;
1218 sem_post(&seq_sem);
1219 printf("\n Posted seq_sem in OMX_EventBufferFlag");
1220 }
1221 } else {
1222 DEBUG_PRINT_ERROR("OMX_EventBufferFlag Event not handled\n");
1223 }
1224 #endif
1225 break;
1226 case OMX_EventIndexsettingChanged:
1227 DEBUG_PRINT("OMX_EventIndexSettingChanged Interlace mode[%x]\n", nData1);
1228 break;
1229 default:
1230 DEBUG_PRINT_ERROR("ERROR - Unknown Event \n");
1231 break;
1232 }
1233 return OMX_ErrorNone;
1234 }
1235
EmptyBufferDone(OMX_IN OMX_HANDLETYPE hComponent,OMX_IN OMX_PTR pAppData,OMX_IN OMX_BUFFERHEADERTYPE * pBuffer)1236 OMX_ERRORTYPE EmptyBufferDone(OMX_IN OMX_HANDLETYPE hComponent,
1237 OMX_IN OMX_PTR pAppData,
1238 OMX_IN OMX_BUFFERHEADERTYPE* pBuffer)
1239 {
1240 int readBytes =0;
1241 int bufCnt=0;
1242 OMX_ERRORTYPE result;
1243
1244 DEBUG_PRINT("Function %s cnt[%d]\n", __FUNCTION__, ebd_cnt);
1245 ebd_cnt++;
1246
1247
1248 if (bInputEosReached) {
1249 DEBUG_PRINT("*****EBD:Input EoS Reached************\n");
1250 return OMX_ErrorNone;
1251 }
1252
1253 pthread_mutex_lock(&etb_lock);
1254 if (push(etb_queue, (void *) pBuffer) < 0) {
1255 DEBUG_PRINT_ERROR("Error in enqueue ebd data\n");
1256 return OMX_ErrorUndefined;
1257 }
1258 pthread_mutex_unlock(&etb_lock);
1259 sem_post(&etb_sem);
1260
1261 return OMX_ErrorNone;
1262 }
1263
FillBufferDone(OMX_OUT OMX_HANDLETYPE hComponent,OMX_OUT OMX_PTR pAppData,OMX_OUT OMX_BUFFERHEADERTYPE * pBuffer)1264 OMX_ERRORTYPE FillBufferDone(OMX_OUT OMX_HANDLETYPE hComponent,
1265 OMX_OUT OMX_PTR pAppData,
1266 OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer)
1267 {
1268 DEBUG_PRINT("Inside %s callback_count[%d] \n", __FUNCTION__, fbd_cnt);
1269
1270 /* Test app will assume there is a dynamic port setting
1271 * In case that there is no dynamic port setting, OMX will not call event cb,
1272 * instead OMX will send empty this buffer directly and we need to clear an event here
1273 */
1274 if (waitForPortSettingsChanged) {
1275 waitForPortSettingsChanged = 0;
1276 if (displayYuv)
1277 overlay_set();
1278 event_complete();
1279 }
1280
1281 pthread_mutex_lock(&fbd_lock);
1282 free_op_buf_cnt++;
1283 if (push(fbd_queue, (void *)pBuffer) < 0) {
1284 pthread_mutex_unlock(&fbd_lock);
1285 DEBUG_PRINT_ERROR("Error in enqueueing fbd_data\n");
1286 return OMX_ErrorUndefined;
1287 }
1288 pthread_mutex_unlock(&fbd_lock);
1289 sem_post(&fbd_sem);
1290
1291 return OMX_ErrorNone;
1292 }
1293
main(int argc,char ** argv)1294 int main(int argc, char **argv)
1295 {
1296 int i=0;
1297 int bufCnt=0;
1298 int num=0;
1299 int outputOption = 0;
1300 int test_option = 0;
1301 int pic_order = 0;
1302 OMX_ERRORTYPE result;
1303 sliceheight = height = 144;
1304 stride = width = 176;
1305
1306 crop_rect.nLeft = 0;
1307 crop_rect.nTop = 0;
1308 crop_rect.nWidth = width;
1309 crop_rect.nHeight = height;
1310
1311
1312 if (argc < 2) {
1313 printf("To use it: ./mm-vdec-omx-test <clip location> \n");
1314 printf("Command line argument is also available\n");
1315 return -1;
1316 }
1317
1318 strlcpy(in_filename, argv[1], strlen(argv[1])+1);
1319 #ifdef _MSM8974_
1320 strlcpy(crclogname, argv[1], strlen(argv[1])+1);
1321 strcat(crclogname, ".crc");
1322 #endif
1323 if (argc > 2) {
1324 codec_format_option = (codec_format)atoi(argv[2]);
1325 // file_type, out_op, tst_op, nal_sz, disp_win, rt_dis, (fps), color, pic_order, num_frames_to_decode
1326 int param[10] = {2, 1, 1, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF};
1327 int next_arg = 3, idx = 0;
1328 while (argc > next_arg && idx < 10) {
1329 if (strlen(argv[next_arg]) > 2) {
1330 strlcpy(seq_file_name, argv[next_arg],strlen(argv[next_arg]) + 1);
1331 next_arg = argc;
1332 } else
1333 param[idx++] = atoi(argv[next_arg++]);
1334 }
1335 idx = 0;
1336 file_type_option = (file_type)param[idx++];
1337 if (codec_format_option == CODEC_FORMAT_H264 && file_type_option == 3) {
1338 nalSize = param[idx++];
1339 if (nalSize != 2 && nalSize != 4) {
1340 printf("Error - Can't pass NAL length size = %d\n", nalSize);
1341 return -1;
1342 }
1343 }
1344 outputOption = param[idx++];
1345 test_option = param[idx++];
1346 if ((outputOption == 1 || outputOption ==3) && test_option != 3) {
1347 displayWindow = param[idx++];
1348 if (displayWindow > 0)
1349 printf("Only entire display window supported! Ignoring value\n");
1350 realtime_display = param[idx++];
1351 }
1352 if (realtime_display) {
1353 takeYuvLog = 0;
1354 if (param[idx] != 0xFF) {
1355 fps = param[idx++];
1356 timestampInterval = 1e6 / fps;
1357 }
1358 }
1359 color_fmt_type = (param[idx] != 0xFF)? param[idx++] : color_fmt_type;
1360 if (test_option != 3) {
1361 pic_order = (param[idx] != 0xFF)? param[idx++] : 0;
1362 num_frames_to_decode = param[idx++];
1363 }
1364 printf("Executing DynPortReconfig QCIF 144 x 176 \n");
1365 } else {
1366 printf("Command line argument is available\n");
1367 printf("To use it: ./mm-vdec-omx-test <clip location> <codec_type> \n");
1368 printf(" <input_type: 1. per AU(.dat), 2. arbitrary, 3.per NAL/frame>\n");
1369 printf(" <output_type> <test_case> <size_nal if H264>\n\n\n");
1370 printf(" *********************************************\n");
1371 printf(" ENTER THE TEST CASE YOU WOULD LIKE TO EXECUTE\n");
1372 printf(" *********************************************\n");
1373 printf(" 1--> H264\n");
1374 printf(" 2--> MP4\n");
1375 printf(" 3--> H263\n");
1376 printf(" 4--> VC1\n");
1377 printf(" 5--> DivX\n");
1378 printf(" 6--> MPEG2\n");
1379 #ifdef _MSM8974_
1380 printf(" 7--> VP8\n");
1381 printf(" 8--> HEVC\n");
1382 printf(" 9--> HYBRID\n");
1383 printf(" 10-> MVC\n");
1384 #endif
1385 fflush(stdin);
1386 fgets(tempbuf,sizeof(tempbuf),stdin);
1387 sscanf(tempbuf,"%d",(int *)&codec_format_option);
1388 fflush(stdin);
1389 if (codec_format_option > CODEC_FORMAT_MAX) {
1390 printf(" Wrong test case...[%d] \n", codec_format_option);
1391 return -1;
1392 }
1393 printf(" *********************************************\n");
1394 printf(" ENTER THE TEST CASE YOU WOULD LIKE TO EXECUTE\n");
1395 printf(" *********************************************\n");
1396 printf(" 1--> PER ACCESS UNIT CLIP (.dat). Clip only available for H264 and Mpeg4\n");
1397 printf(" 2--> ARBITRARY BYTES (need .264/.264c/.m4v/.263/.rcv/.vc1/.m2v)\n");
1398 if (codec_format_option == CODEC_FORMAT_H264) {
1399 printf(" 3--> NAL LENGTH SIZE CLIP (.264c)\n");
1400 printf(" 4--> START CODE BASED CLIP (.264/.h264)\n");
1401 } else if ( (codec_format_option == CODEC_FORMAT_MP4) || (codec_format_option == CODEC_FORMAT_H263) ) {
1402 printf(" 3--> MP4 VOP or H263 P0 SHORT HEADER START CODE CLIP (.m4v or .263)\n");
1403 } else if (codec_format_option == CODEC_FORMAT_VC1) {
1404 printf(" 3--> VC1 clip Simple/Main Profile (.rcv)\n");
1405 printf(" 4--> VC1 clip Advance Profile (.vc1)\n");
1406 } else if (codec_format_option == CODEC_FORMAT_DIVX) {
1407 printf(" 3--> DivX 4, 5, 6 clip (.cmp)\n");
1408 #ifdef MAX_RES_1080P
1409 printf(" 4--> DivX 3.11 clip \n");
1410 #endif
1411 } else if (codec_format_option == CODEC_FORMAT_MPEG2) {
1412 printf(" 3--> MPEG2 START CODE CLIP (.m2v)\n");
1413 }
1414 #ifdef _MSM8974_
1415 else if (codec_format_option == CODEC_FORMAT_MVC) {
1416 printf(" 5--> MVC clip (.264)\n");
1417 } else if (codec_format_option == CODEC_FORMAT_VP8) {
1418 printf(" 61--> VP8 START CODE CLIP (.ivf)\n");
1419 }
1420 #endif
1421 fflush(stdin);
1422 fgets(tempbuf,sizeof(tempbuf),stdin);
1423 sscanf(tempbuf,"%d",(int *)&file_type_option);
1424 #ifdef _MSM8974_
1425 if (codec_format_option == CODEC_FORMAT_VP8) {
1426 file_type_option = FILE_TYPE_VP8;
1427 } else if (codec_format_option == CODEC_FORMAT_MVC) {
1428 file_type_option = FILE_TYPE_MVC;
1429 }
1430 #endif
1431 fflush(stdin);
1432 if (codec_format_option == CODEC_FORMAT_H264 && file_type_option == 3) {
1433 printf(" Enter Nal length size [2 or 4] \n");
1434 fgets(tempbuf,sizeof(tempbuf),stdin);
1435 sscanf(tempbuf,"%d",&nalSize);
1436 if (nalSize != 2 && nalSize != 4) {
1437 printf("Error - Can't pass NAL length size = %d\n", nalSize);
1438 return -1;
1439 }
1440 }
1441
1442 printf(" *********************************************\n");
1443 printf(" Output buffer option:\n");
1444 printf(" *********************************************\n");
1445 printf(" 0 --> No display and no YUV log\n");
1446 printf(" 1 --> Diplay YUV\n");
1447 printf(" 2 --> Take YUV log\n");
1448 printf(" 3 --> Display YUV and take YUV log\n");
1449 fflush(stdin);
1450 fgets(tempbuf,sizeof(tempbuf),stdin);
1451 sscanf(tempbuf,"%d",(int *)&outputOption);
1452 fflush(stdin);
1453
1454 printf(" *********************************************\n");
1455 printf(" ENTER THE TEST CASE YOU WOULD LIKE TO EXECUTE\n");
1456 printf(" *********************************************\n");
1457 printf(" 1 --> Play the clip till the end\n");
1458 printf(" 2 --> Run compliance test. Do NOT expect any display for most option. \n");
1459 printf(" Please only see \"TEST SUCCESSFULL\" to indicate test pass\n");
1460 printf(" 3 --> Thumbnail decode mode\n");
1461 fflush(stdin);
1462 fgets(tempbuf,sizeof(tempbuf),stdin);
1463 sscanf(tempbuf,"%d",&test_option);
1464 fflush(stdin);
1465 if (test_option == 3)
1466 thumbnailMode = 1;
1467
1468 if ((outputOption == 1 || outputOption == 3) && thumbnailMode == 0) {
1469 printf(" *********************************************\n");
1470 printf(" ENTER THE PORTION OF DISPLAY TO USE\n");
1471 printf(" *********************************************\n");
1472 printf(" 0 --> Entire Screen\n");
1473 printf(" 1 --> 1/4 th of the screen starting from top left corner to middle \n");
1474 printf(" 2 --> 1/4 th of the screen starting from middle to top right corner \n");
1475 printf(" 3 --> 1/4 th of the screen starting from middle to bottom left \n");
1476 printf(" 4 --> 1/4 th of the screen starting from middle to bottom right \n");
1477 printf(" Please only see \"TEST SUCCESSFULL\" to indidcate test pass\n");
1478 fflush(stdin);
1479 fgets(tempbuf,sizeof(tempbuf),stdin);
1480 sscanf(tempbuf,"%d",&displayWindow);
1481 fflush(stdin);
1482 if (displayWindow > 0) {
1483 printf(" Curently display window 0 only supported; ignoring other values\n");
1484 displayWindow = 0;
1485 }
1486 }
1487
1488 if ((outputOption == 1 || outputOption == 3) && thumbnailMode == 0) {
1489 printf(" *********************************************\n");
1490 printf(" DO YOU WANT TEST APP TO RENDER in Real time \n");
1491 printf(" 0 --> NO\n 1 --> YES\n");
1492 printf(" Warning: For H264, it require one NAL per frame clip.\n");
1493 printf(" For Arbitrary bytes option, Real time display is not recommended\n");
1494 printf(" *********************************************\n");
1495 fflush(stdin);
1496 fgets(tempbuf,sizeof(tempbuf),stdin);
1497 sscanf(tempbuf,"%d",&realtime_display);
1498 fflush(stdin);
1499 }
1500
1501
1502 if (realtime_display) {
1503 printf(" *********************************************\n");
1504 printf(" ENTER THE CLIP FPS\n");
1505 printf(" Exception: Timestamp extracted from clips will be used.\n");
1506 printf(" *********************************************\n");
1507 fflush(stdin);
1508 fgets(tempbuf,sizeof(tempbuf),stdin);
1509 sscanf(tempbuf,"%d",&fps);
1510 fflush(stdin);
1511 timestampInterval = 1000000/fps;
1512 }
1513
1514 printf(" *********************************************\n");
1515 printf(" ENTER THE COLOR FORMAT \n");
1516 printf(" 0 --> Semiplanar \n 1 --> Tile Mode\n");
1517 printf(" *********************************************\n");
1518 fflush(stdin);
1519 fgets(tempbuf,sizeof(tempbuf),stdin);
1520 sscanf(tempbuf,"%d",&color_fmt_type);
1521 fflush(stdin);
1522
1523 if (thumbnailMode != 1) {
1524 printf(" *********************************************\n");
1525 printf(" Output picture order option: \n");
1526 printf(" *********************************************\n");
1527 printf(" 0 --> Display order\n 1 --> Decode order\n");
1528 fflush(stdin);
1529 fgets(tempbuf,sizeof(tempbuf),stdin);
1530 sscanf(tempbuf,"%d",&pic_order);
1531 fflush(stdin);
1532
1533 printf(" *********************************************\n");
1534 printf(" Number of frames to decode: \n");
1535 printf(" 0 ---> decode all frames: \n");
1536 printf(" *********************************************\n");
1537 fflush(stdin);
1538 fgets(tempbuf,sizeof(tempbuf),stdin);
1539 sscanf(tempbuf,"%d",&num_frames_to_decode);
1540 fflush(stdin);
1541 }
1542 }
1543 if (file_type_option >= FILE_TYPE_COMMON_CODEC_MAX) {
1544 switch (codec_format_option) {
1545 case CODEC_FORMAT_H264:
1546 file_type_option = (file_type)(FILE_TYPE_START_OF_H264_SPECIFIC + file_type_option - FILE_TYPE_COMMON_CODEC_MAX);
1547 break;
1548 case CODEC_FORMAT_DIVX:
1549 file_type_option = (file_type)(FILE_TYPE_START_OF_DIVX_SPECIFIC + file_type_option - FILE_TYPE_COMMON_CODEC_MAX);
1550 break;
1551 case CODEC_FORMAT_MP4:
1552 case CODEC_FORMAT_H263:
1553 file_type_option = (file_type)(FILE_TYPE_START_OF_MP4_SPECIFIC + file_type_option - FILE_TYPE_COMMON_CODEC_MAX);
1554 break;
1555 case CODEC_FORMAT_VC1:
1556 file_type_option = (file_type)(FILE_TYPE_START_OF_VC1_SPECIFIC + file_type_option - FILE_TYPE_COMMON_CODEC_MAX);
1557 break;
1558 case CODEC_FORMAT_MPEG2:
1559 file_type_option = (file_type)(FILE_TYPE_START_OF_MPEG2_SPECIFIC + file_type_option - FILE_TYPE_COMMON_CODEC_MAX);
1560 break;
1561 #ifdef _MSM8974_
1562 case CODEC_FORMAT_VP8:
1563 case CODEC_FORMAT_MVC:
1564 break;
1565 #endif
1566 default:
1567 printf("Error: Unknown code %d\n", codec_format_option);
1568 }
1569 }
1570
1571 CONFIG_VERSION_SIZE(picture_order);
1572 picture_order.eOutputPictureOrder = QOMX_VIDEO_DISPLAY_ORDER;
1573 if (pic_order == 1)
1574 picture_order.eOutputPictureOrder = QOMX_VIDEO_DECODE_ORDER;
1575
1576 if (outputOption == 0) {
1577 displayYuv = 0;
1578 takeYuvLog = 0;
1579 realtime_display = 0;
1580 } else if (outputOption == 1) {
1581 displayYuv = 1;
1582 } else if (outputOption == 2) {
1583 takeYuvLog = 1;
1584 realtime_display = 0;
1585 } else if (outputOption == 3) {
1586 displayYuv = 1;
1587 takeYuvLog = !realtime_display;
1588 } else {
1589 printf("Wrong option. Assume you want to see the YUV display\n");
1590 displayYuv = 1;
1591 }
1592
1593 if (test_option == 2) {
1594 printf(" *********************************************\n");
1595 printf(" ENTER THE COMPLIANCE TEST YOU WOULD LIKE TO EXECUTE\n");
1596 printf(" *********************************************\n");
1597 printf(" 1 --> Call Free Handle at the OMX_StateLoaded\n");
1598 printf(" 2 --> Call Free Handle at the OMX_StateIdle\n");
1599 printf(" 3 --> Call Free Handle at the OMX_StateExecuting\n");
1600 printf(" 4 --> Call Free Handle at the OMX_StatePause\n");
1601 fflush(stdin);
1602 fgets(tempbuf,sizeof(tempbuf),stdin);
1603 sscanf(tempbuf,"%d",(int *)&freeHandle_option);
1604 fflush(stdin);
1605 } else {
1606 freeHandle_option = (freeHandle_test)0;
1607 }
1608
1609 printf("Input values: inputfilename[%s]\n", in_filename);
1610 printf("*******************************************************\n");
1611 pthread_cond_init(&cond, 0);
1612 pthread_cond_init(&eos_cond, 0);
1613 pthread_mutex_init(&eos_lock, 0);
1614 pthread_mutex_init(&lock, 0);
1615 pthread_mutex_init(&etb_lock, 0);
1616 pthread_mutex_init(&fbd_lock, 0);
1617 pthread_mutex_init(&enable_lock, 0);
1618 if (-1 == sem_init(&etb_sem, 0, 0)) {
1619 printf("Error - sem_init failed %d\n", errno);
1620 }
1621 if (-1 == sem_init(&fbd_sem, 0, 0)) {
1622 printf("Error - sem_init failed %d\n", errno);
1623 }
1624 if (-1 == sem_init(&seq_sem, 0, 0)) {
1625 printf("Error - sem_init failed %d\n", errno);
1626 }
1627 if (-1 == sem_init(&in_flush_sem, 0, 0)) {
1628 printf("Error - sem_init failed %d\n", errno);
1629 }
1630 if (-1 == sem_init(&out_flush_sem, 0, 0)) {
1631 printf("Error - sem_init failed %d\n", errno);
1632 }
1633 etb_queue = alloc_queue();
1634 if (etb_queue == NULL) {
1635 printf("\n Error in Creating etb_queue\n");
1636 return -1;
1637 }
1638
1639 fbd_queue = alloc_queue();
1640 if (fbd_queue == NULL) {
1641 printf("\n Error in Creating fbd_queue\n");
1642 free_queue(etb_queue);
1643 return -1;
1644 }
1645
1646 if (0 != pthread_create(&fbd_thread_id, NULL, fbd_thread, NULL)) {
1647 printf("\n Error in Creating fbd_thread \n");
1648 free_queue(etb_queue);
1649 free_queue(fbd_queue);
1650 return -1;
1651 }
1652
1653 if (displayYuv) {
1654 if (open_display() != 0) {
1655 printf("\n Error opening display! Video won't be displayed...");
1656 displayYuv = 0;
1657 }
1658 }
1659
1660 run_tests();
1661 pthread_cond_destroy(&cond);
1662 pthread_mutex_destroy(&lock);
1663 pthread_mutex_destroy(&etb_lock);
1664 pthread_mutex_destroy(&fbd_lock);
1665 pthread_mutex_destroy(&enable_lock);
1666 pthread_cond_destroy(&eos_cond);
1667 pthread_mutex_destroy(&eos_lock);
1668 if (-1 == sem_destroy(&etb_sem)) {
1669 DEBUG_PRINT_ERROR("Error - sem_destroy failed %d\n", errno);
1670 }
1671 if (-1 == sem_destroy(&fbd_sem)) {
1672 DEBUG_PRINT_ERROR("Error - sem_destroy failed %d\n", errno);
1673 }
1674 if (-1 == sem_destroy(&seq_sem)) {
1675 DEBUG_PRINT_ERROR("Error - sem_destroy failed %d\n", errno);
1676 }
1677 if (-1 == sem_destroy(&in_flush_sem)) {
1678 DEBUG_PRINT_ERROR("Error - sem_destroy failed %d\n", errno);
1679 }
1680 if (-1 == sem_destroy(&out_flush_sem)) {
1681 DEBUG_PRINT_ERROR("Error - sem_destroy failed %d\n", errno);
1682 }
1683 if (displayYuv)
1684 close_display();
1685 return 0;
1686 }
1687
run_tests()1688 int run_tests()
1689 {
1690 int cmd_error = 0;
1691 DEBUG_PRINT("Inside %s\n", __FUNCTION__);
1692 waitForPortSettingsChanged = 1;
1693
1694 if (file_type_option == FILE_TYPE_DAT_PER_AU) {
1695 Read_Buffer = Read_Buffer_From_DAT_File;
1696 } else if (file_type_option == FILE_TYPE_ARBITRARY_BYTES) {
1697 Read_Buffer = Read_Buffer_ArbitraryBytes;
1698 } else if (codec_format_option == CODEC_FORMAT_H264) {
1699 if (file_type_option == FILE_TYPE_264_NAL_SIZE_LENGTH) {
1700 Read_Buffer = Read_Buffer_From_Size_Nal;
1701 } else if (file_type_option == FILE_TYPE_264_START_CODE_BASED) {
1702 Read_Buffer = Read_Buffer_From_H264_Start_Code_File;
1703 } else {
1704 DEBUG_PRINT_ERROR("Invalid file_type_option(%d) for H264", file_type_option);
1705 return -1;
1706 }
1707 } else if ((codec_format_option == CODEC_FORMAT_H263) ||
1708 (codec_format_option == CODEC_FORMAT_MP4)) {
1709 Read_Buffer = Read_Buffer_From_Vop_Start_Code_File;
1710 } else if (codec_format_option == CODEC_FORMAT_MPEG2) {
1711 Read_Buffer = Read_Buffer_From_Mpeg2_Start_Code;
1712 } else if (file_type_option == FILE_TYPE_DIVX_4_5_6) {
1713 Read_Buffer = Read_Buffer_From_DivX_4_5_6_File;
1714 }
1715 #ifdef MAX_RES_1080P
1716 else if (file_type_option == FILE_TYPE_DIVX_311) {
1717 Read_Buffer = Read_Buffer_From_DivX_311_File;
1718 }
1719 #endif
1720 else if (file_type_option == FILE_TYPE_RCV) {
1721 Read_Buffer = Read_Buffer_From_RCV_File;
1722 }
1723 #ifdef _MSM8974_
1724 else if (file_type_option == FILE_TYPE_VP8) {
1725 Read_Buffer = Read_Buffer_From_VP8_File;
1726 } else if (codec_format_option == CODEC_FORMAT_MVC) {
1727 Read_Buffer = Read_Buffer_From_MVC_File;
1728 }
1729 #endif
1730 else if (file_type_option == FILE_TYPE_VC1) {
1731 Read_Buffer = Read_Buffer_From_VC1_File;
1732 }
1733
1734 DEBUG_PRINT("file_type_option %d!\n", file_type_option);
1735
1736 switch (file_type_option) {
1737 case FILE_TYPE_DAT_PER_AU:
1738 case FILE_TYPE_ARBITRARY_BYTES:
1739 case FILE_TYPE_264_START_CODE_BASED:
1740 case FILE_TYPE_264_NAL_SIZE_LENGTH:
1741 case FILE_TYPE_PICTURE_START_CODE:
1742 case FILE_TYPE_MPEG2_START_CODE:
1743 case FILE_TYPE_RCV:
1744 case FILE_TYPE_VC1:
1745 #ifdef _MSM8974_
1746 case FILE_TYPE_VP8:
1747 case FILE_TYPE_MVC:
1748 #endif
1749 case FILE_TYPE_DIVX_4_5_6:
1750 #ifdef MAX_RES_1080P
1751 case FILE_TYPE_DIVX_311:
1752 #endif
1753 if (Init_Decoder()!= 0x00) {
1754 DEBUG_PRINT_ERROR("Error - Decoder Init failed\n");
1755 return -1;
1756 }
1757 if (Play_Decoder() != 0x00) {
1758 return -1;
1759 }
1760 break;
1761 default:
1762 DEBUG_PRINT_ERROR("Error - Invalid Entry...%d\n",file_type_option);
1763 break;
1764 }
1765
1766 anti_flickering = true;
1767 if (strlen(seq_file_name)) {
1768 seqFile = fopen (seq_file_name, "rb");
1769 if (seqFile == NULL) {
1770 DEBUG_PRINT_ERROR("Error - Seq file %s could NOT be opened\n",
1771 seq_file_name);
1772 return -1;
1773 } else {
1774 DEBUG_PRINT("Seq file %s is opened \n", seq_file_name);
1775 seq_enabled = 1;
1776 anti_flickering = false;
1777 }
1778 }
1779
1780 pthread_mutex_lock(&eos_lock);
1781 while (bOutputEosReached == false && cmd_error == 0) {
1782 if (seq_enabled) {
1783 pthread_mutex_unlock(&eos_lock);
1784 if (!get_next_command(seqFile))
1785 cmd_error = process_current_command(curr_seq_command);
1786 else {
1787 printf("\n Error in get_next_cmd or EOF");
1788 seq_enabled = 0;
1789 }
1790 pthread_mutex_lock(&eos_lock);
1791 } else
1792 pthread_cond_wait(&eos_cond, &eos_lock);
1793
1794 if (currentStatus == PORT_SETTING_CHANGE_STATE) {
1795 pthread_mutex_unlock(&eos_lock);
1796 cmd_error = output_port_reconfig();
1797 pthread_mutex_lock(&eos_lock);
1798 }
1799 }
1800 pthread_mutex_unlock(&eos_lock);
1801
1802 // Wait till EOS is reached...
1803 if (bOutputEosReached)
1804 do_freeHandle_and_clean_up(currentStatus == ERROR_STATE);
1805 return 0;
1806 }
1807
Init_Decoder()1808 int Init_Decoder()
1809 {
1810 DEBUG_PRINT("Inside %s \n", __FUNCTION__);
1811 OMX_ERRORTYPE omxresult;
1812 OMX_U32 total = 0;
1813 char vdecCompNames[50];
1814 typedef OMX_U8* OMX_U8_PTR;
1815 char role[strlen("video_decoder") + 1];
1816 strcpy(role, "video_decoder");
1817
1818 static OMX_CALLBACKTYPE call_back = {&EventHandler, &EmptyBufferDone, &FillBufferDone};
1819
1820 unsigned int i = 0;
1821 long bufCnt = 0;
1822
1823 /* Init. the OpenMAX Core */
1824 DEBUG_PRINT("\nInitializing OpenMAX Core....\n");
1825 omxresult = OMX_Init();
1826
1827 if (OMX_ErrorNone != omxresult) {
1828 DEBUG_PRINT_ERROR("\n Failed to Init OpenMAX core");
1829 return -1;
1830 } else {
1831 DEBUG_PRINT_ERROR("\nOpenMAX Core Init Done\n");
1832 }
1833
1834 /* Query for video decoders*/
1835 OMX_GetComponentsOfRole(role, &total, 0);
1836 DEBUG_PRINT("\nTotal components of role=%s :%d", role, total);
1837
1838 if (total) {
1839 /* Allocate memory for pointers to component name */
1840 OMX_U8** vidCompNames = (OMX_U8**)malloc((sizeof(OMX_U8*))*total);
1841 if (vidCompNames == NULL) {
1842 DEBUG_PRINT_ERROR("\nFailed to allocate vidCompNames\n");
1843 return -1;
1844 }
1845
1846 for (i = 0; i < total; ++i) {
1847 vidCompNames[i] = (OMX_U8*)malloc(sizeof(OMX_U8)*OMX_MAX_STRINGNAME_SIZE);
1848 if (vidCompNames[i] == NULL) {
1849 DEBUG_PRINT_ERROR("\nFailed to allocate vidCompNames[%d]\n", i);
1850 return -1;
1851 }
1852 }
1853 OMX_GetComponentsOfRole(role, &total, vidCompNames);
1854 DEBUG_PRINT("\nComponents of Role:%s\n", role);
1855 for (i = 0; i < total; ++i) {
1856 DEBUG_PRINT("\nComponent Name [%s]\n",vidCompNames[i]);
1857 free(vidCompNames[i]);
1858 }
1859 free(vidCompNames);
1860 } else {
1861 DEBUG_PRINT_ERROR("No components found with Role:%s", role);
1862 }
1863
1864 if (codec_format_option == CODEC_FORMAT_H264) {
1865 strlcpy(vdecCompNames, "OMX.qcom.video.decoder.avc", 27);
1866 //strlcpy(vdecCompNames, "OMX.SEC.qcom.video.decoder.avc", 31);
1867 } else if (codec_format_option == CODEC_FORMAT_MP4) {
1868 strlcpy(vdecCompNames, "OMX.qcom.video.decoder.mpeg4", 29);
1869 } else if (codec_format_option == CODEC_FORMAT_H263) {
1870 strlcpy(vdecCompNames, "OMX.qcom.video.decoder.h263", 28);
1871 } else if (codec_format_option == CODEC_FORMAT_VC1) {
1872 strlcpy(vdecCompNames, "OMX.qcom.video.decoder.vc1", 27);
1873 } else if (codec_format_option == CODEC_FORMAT_MPEG2) {
1874 strlcpy(vdecCompNames, "OMX.qcom.video.decoder.mpeg2", 29);
1875 } else if (file_type_option == FILE_TYPE_RCV) {
1876 strlcpy(vdecCompNames, "OMX.qcom.video.decoder.wmv", 27);
1877 } else if (file_type_option == FILE_TYPE_DIVX_4_5_6) {
1878 strlcpy(vdecCompNames, "OMX.qcom.video.decoder.divx", 28);
1879 }
1880 #ifdef _MSM8974_
1881 else if (codec_format_option == CODEC_FORMAT_VP8) {
1882 strlcpy(vdecCompNames, "OMX.qcom.video.decoder.vp8", 27);
1883 }
1884 else if (codec_format_option == CODEC_FORMAT_MVC) {
1885 strlcpy(vdecCompNames, "OMX.qcom.video.decoder.mvc", 27);
1886 }
1887 #endif
1888 else if (codec_format_option == CODEC_FORMAT_HEVC) {
1889 strlcpy(vdecCompNames, "OMX.qcom.video.decoder.hevc", 28);
1890 DEBUG_PRINT_ERROR("vdecCompNames: %s\n", vdecCompNames);
1891 }
1892 else if (codec_format_option == CODEC_FORMAT_HEVC_HYBRID) {
1893 strlcpy(vdecCompNames, "OMX.qcom.video.decoder.hevchybrid", 34);
1894 DEBUG_PRINT_ERROR("vdecCompNames: %s\n", vdecCompNames);
1895 }
1896 #ifdef MAX_RES_1080P
1897 else if (file_type_option == FILE_TYPE_DIVX_311) {
1898 strlcpy(vdecCompNames, "OMX.qcom.video.decoder.divx311", 31);
1899 }
1900 #endif
1901 else {
1902 DEBUG_PRINT_ERROR("Error: Unsupported codec %d\n", codec_format_option);
1903 return -1;
1904 }
1905
1906 omxresult = OMX_GetHandle((OMX_HANDLETYPE*)(&dec_handle),
1907 (OMX_STRING)vdecCompNames, NULL, &call_back);
1908 if (FAILED(omxresult)) {
1909 DEBUG_PRINT_ERROR("\nFailed to Load the component:%s\n", vdecCompNames);
1910 if (!strncmp(vdecCompNames, "OMX.qcom.video.decoder.mvc", 27)) {
1911 char platform_name[PROPERTY_VALUE_MAX] = {0};
1912 property_get("ro.product.name", platform_name, "Name not available");
1913 printf("Error: MVC not listed as supported codec in this platform: %s\n", platform_name);
1914 }
1915 return -1;
1916 } else {
1917 DEBUG_PRINT("\nComponent %s is in LOADED state\n", vdecCompNames);
1918 }
1919
1920 QOMX_VIDEO_QUERY_DECODER_INSTANCES decoder_instances;
1921 omxresult = OMX_GetConfig(dec_handle,
1922 (OMX_INDEXTYPE)OMX_QcomIndexQueryNumberOfVideoDecInstance,
1923 &decoder_instances);
1924 DEBUG_PRINT("\n Number of decoder instances %d",
1925 decoder_instances.nNumOfInstances);
1926
1927 /* Get the port information */
1928 CONFIG_VERSION_SIZE(portParam);
1929 omxresult = OMX_GetParameter(dec_handle, OMX_IndexParamVideoInit,
1930 (OMX_PTR)&portParam);
1931
1932 if (FAILED(omxresult)) {
1933 DEBUG_PRINT_ERROR("ERROR - Failed to get Port Param\n");
1934 return -1;
1935 } else {
1936 DEBUG_PRINT("portParam.nPorts:%d\n", portParam.nPorts);
1937 DEBUG_PRINT("portParam.nStartPortNumber:%d\n", portParam.nStartPortNumber);
1938 }
1939
1940 /* Set the compression format on i/p port */
1941 if (codec_format_option == CODEC_FORMAT_H264) {
1942 portFmt.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC;
1943 } else if (codec_format_option == CODEC_FORMAT_MVC) {
1944 portFmt.format.video.eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingMVC;
1945 } else if (codec_format_option == CODEC_FORMAT_MP4) {
1946 portFmt.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4;
1947 } else if (codec_format_option == CODEC_FORMAT_H263) {
1948 portFmt.format.video.eCompressionFormat = OMX_VIDEO_CodingH263;
1949 } else if (codec_format_option == CODEC_FORMAT_VC1) {
1950 portFmt.format.video.eCompressionFormat = OMX_VIDEO_CodingWMV;
1951 } else if (codec_format_option == CODEC_FORMAT_DIVX) {
1952 portFmt.format.video.eCompressionFormat =
1953 (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1954 } else if (codec_format_option == CODEC_FORMAT_MPEG2) {
1955 portFmt.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG2;
1956 } else if (codec_format_option == CODEC_FORMAT_HEVC ||
1957 codec_format_option == CODEC_FORMAT_HEVC_HYBRID) {
1958 portFmt.format.video.eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingHevc;
1959 } else {
1960 DEBUG_PRINT_ERROR("Error: Unsupported codec %d\n", codec_format_option);
1961 }
1962
1963 if (thumbnailMode == 1) {
1964 QOMX_ENABLETYPE thumbNailMode;
1965 thumbNailMode.bEnable = OMX_TRUE;
1966 OMX_SetParameter(dec_handle,(OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode,
1967 (OMX_PTR)&thumbNailMode);
1968 DEBUG_PRINT("Enabled Thumbnail mode\n");
1969 }
1970
1971 return 0;
1972 }
1973
Play_Decoder()1974 int Play_Decoder()
1975 {
1976 OMX_VIDEO_PARAM_PORTFORMATTYPE videoportFmt;
1977 memset(&videoportFmt, 0, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
1978 int i, bufCnt, index = 0;
1979 int frameSize=0;
1980 OMX_ERRORTYPE ret = OMX_ErrorNone;
1981 OMX_BUFFERHEADERTYPE* pBuffer = NULL;
1982 DEBUG_PRINT("Inside %s \n", __FUNCTION__);
1983
1984 /* open the i/p and o/p files based on the video file format passed */
1985 if (open_video_file()) {
1986 DEBUG_PRINT_ERROR("Error in opening video file\n");
1987 return -1;
1988 }
1989
1990 OMX_QCOM_PARAM_PORTDEFINITIONTYPE inputPortFmt;
1991 memset(&inputPortFmt, 0, sizeof(OMX_QCOM_PARAM_PORTDEFINITIONTYPE));
1992 CONFIG_VERSION_SIZE(inputPortFmt);
1993 inputPortFmt.nPortIndex = 0; // input port
1994 switch (file_type_option) {
1995 case FILE_TYPE_DAT_PER_AU:
1996 case FILE_TYPE_PICTURE_START_CODE:
1997 case FILE_TYPE_MPEG2_START_CODE:
1998 case FILE_TYPE_264_START_CODE_BASED:
1999 case FILE_TYPE_RCV:
2000 case FILE_TYPE_VC1:
2001 #ifdef MAX_RES_1080P
2002 case FILE_TYPE_DIVX_311:
2003 #endif
2004 {
2005 inputPortFmt.nFramePackingFormat = OMX_QCOM_FramePacking_OnlyOneCompleteFrame;
2006 break;
2007 }
2008
2009 case FILE_TYPE_ARBITRARY_BYTES:
2010 case FILE_TYPE_264_NAL_SIZE_LENGTH:
2011 case FILE_TYPE_DIVX_4_5_6:
2012 {
2013 inputPortFmt.nFramePackingFormat = OMX_QCOM_FramePacking_Arbitrary;
2014 break;
2015 }
2016 #ifdef _MSM8974_
2017 case FILE_TYPE_VP8:
2018 {
2019 inputPortFmt.nFramePackingFormat = OMX_QCOM_FramePacking_OnlyOneCompleteFrame;
2020 break;
2021 }
2022 #endif
2023 default:
2024 inputPortFmt.nFramePackingFormat = OMX_QCOM_FramePacking_Unspecified;
2025 }
2026 OMX_SetParameter(dec_handle,(OMX_INDEXTYPE)OMX_QcomIndexPortDefn,
2027 (OMX_PTR)&inputPortFmt);
2028 #ifdef USE_EXTERN_PMEM_BUF
2029 OMX_QCOM_PARAM_PORTDEFINITIONTYPE outPortFmt;
2030 memset(&outPortFmt, 0, sizeof(OMX_QCOM_PARAM_PORTDEFINITIONTYPE));
2031 CONFIG_VERSION_SIZE(outPortFmt);
2032 outPortFmt.nPortIndex = 1; // output port
2033 outPortFmt.nCacheAttr = OMX_QCOM_CacheAttrNone;
2034 outPortFmt.nMemRegion = OMX_QCOM_MemRegionSMI;
2035 OMX_SetParameter(dec_handle,(OMX_INDEXTYPE)OMX_QcomIndexPortDefn,
2036 (OMX_PTR)&outPortFmt);
2037
2038 OMX_QCOM_PLATFORMPRIVATE_EXTN outPltPvtExtn;
2039 memset(&outPltPvtExtn, 0, sizeof(OMX_QCOM_PLATFORMPRIVATE_EXTN));
2040 CONFIG_VERSION_SIZE(outPltPvtExtn);
2041 outPltPvtExtn.nPortIndex = 1; // output port
2042 outPltPvtExtn.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
2043 OMX_SetParameter(dec_handle,(OMX_INDEXTYPE)OMX_QcomIndexPlatformPvt,
2044 (OMX_PTR)&outPltPvtExtn);
2045 use_external_pmem_buf = OMX_TRUE;
2046 #endif
2047 QOMX_ENABLETYPE extra_data;
2048 extra_data.bEnable = OMX_TRUE;
2049
2050 char frameinfo_value[PROPERTY_VALUE_MAX] = {0};
2051 char interlace_value[PROPERTY_VALUE_MAX] = {0};
2052 char h264info_value[PROPERTY_VALUE_MAX] = {0};
2053 char video_qp_value[PROPERTY_VALUE_MAX] = {0};
2054 char videoinput_bitsinfo_value[PROPERTY_VALUE_MAX] = {0};
2055
2056 OMX_U32 frameinfo = 0,interlace = 0,h264info =0, video_qp =0, videoinput_bitsinfo =0;
2057 property_get("vidc.vdec.debug.frameinfo", frameinfo_value, "0");
2058 frameinfo = atoi(frameinfo_value);
2059 if (frameinfo) {
2060 OMX_SetParameter(dec_handle,(OMX_INDEXTYPE)OMX_QcomIndexParamFrameInfoExtraData,
2061 (OMX_PTR)&extra_data);
2062 }
2063 property_get("vidc.vdec.debug.interlace", interlace_value, "0");
2064 interlace = atoi(interlace_value);
2065 if (interlace) {
2066 OMX_SetParameter(dec_handle,(OMX_INDEXTYPE)OMX_QcomIndexParamInterlaceExtraData,
2067 (OMX_PTR)&extra_data);
2068 }
2069 property_get("vidc.vdec.debug.h264info", h264info_value, "0");
2070 h264info = atoi(h264info_value);
2071 if (h264info) {
2072 OMX_SetParameter(dec_handle,(OMX_INDEXTYPE)OMX_QcomIndexParamH264TimeInfo,
2073 (OMX_PTR)&extra_data);
2074 }
2075 property_get("vidc.vdec.debug.video_qp_value", video_qp_value, "0");
2076 video_qp = atoi(video_qp_value);
2077 if (video_qp) {
2078 OMX_SetParameter(dec_handle,(OMX_INDEXTYPE)OMX_QcomIndexParamVideoQPExtraData,
2079 (OMX_PTR)&extra_data);
2080 }
2081 property_get("vidc.vdec.debug.input_bitsinfo", videoinput_bitsinfo_value, "0");
2082 videoinput_bitsinfo = atoi(videoinput_bitsinfo_value);
2083 if (videoinput_bitsinfo) {
2084 OMX_SetParameter(dec_handle,(OMX_INDEXTYPE)OMX_QcomIndexParamVideoInputBitsInfoExtraData,
2085 (OMX_PTR)&extra_data);
2086 }
2087
2088 /* Query the decoder outport's min buf requirements */
2089 CONFIG_VERSION_SIZE(portFmt);
2090
2091 /* Port for which the Client needs to obtain info */
2092 portFmt.nPortIndex = portParam.nStartPortNumber;
2093
2094 OMX_GetParameter(dec_handle,OMX_IndexParamPortDefinition,&portFmt);
2095 DEBUG_PRINT("\nDec: Min Buffer Count %d\n", portFmt.nBufferCountMin);
2096 DEBUG_PRINT("\nDec: Buffer Size %d\n", portFmt.nBufferSize);
2097
2098 if (OMX_DirInput != portFmt.eDir) {
2099 printf ("\nDec: Expect Input Port\n");
2100 return -1;
2101 }
2102 #ifdef MAX_RES_1080P
2103 if ( (codec_format_option == CODEC_FORMAT_DIVX) &&
2104 (file_type_option == FILE_TYPE_DIVX_311) ) {
2105
2106 int off;
2107
2108 if ( read(inputBufferFileFd, &width, 4 ) == -1 ) {
2109 DEBUG_PRINT_ERROR("\nFailed to read width for divx\n");
2110 return -1;
2111 }
2112
2113 DEBUG_PRINT("\nWidth for DIVX = %d\n", width);
2114
2115 if ( read(inputBufferFileFd, &height, 4 ) == -1 ) {
2116 DEBUG_PRINT_ERROR("\nFailed to read height for divx\n");
2117 return -1;
2118 }
2119
2120 DEBUG_PRINT("\nHeight for DIVX = %u\n", height);
2121 sliceheight = height;
2122 stride = width;
2123 }
2124 #endif
2125 #ifdef _MSM8974_
2126 if ( (codec_format_option == CODEC_FORMAT_VC1) &&
2127 (file_type_option == FILE_TYPE_RCV) ) {
2128 //parse struct_A data to get height and width information
2129 unsigned int temp;
2130 lseek64(inputBufferFileFd, 0, SEEK_SET);
2131 if (read(inputBufferFileFd, &temp, 4) < 0) {
2132 DEBUG_PRINT_ERROR("\nFailed to read vc1 data\n");
2133 return -1;
2134 }
2135 //Refer to Annex L of SMPTE 421M-2006 VC1 decoding standard
2136 //We need to skip 12 bytes after 0xC5 in sequence layer data
2137 //structure to read struct_A, which includes height and
2138 //width information.
2139 if ((temp & 0xFF000000) == 0xC5000000) {
2140 lseek64(inputBufferFileFd, 12, SEEK_SET);
2141
2142 if ( read(inputBufferFileFd, &height, 4 ) < -1 ) {
2143 DEBUG_PRINT_ERROR("\nFailed to read height for vc-1\n");
2144 return -1;
2145 }
2146 if ( read(inputBufferFileFd, &width, 4 ) == -1 ) {
2147 DEBUG_PRINT_ERROR("\nFailed to read width for vc-1\n");
2148 return -1;
2149 }
2150 lseek64(inputBufferFileFd, 0, SEEK_SET);
2151 }
2152 if ((temp & 0xFF000000) == 0x85000000) {
2153 lseek64(inputBufferFileFd, 0, SEEK_SET);
2154 }
2155 DEBUG_PRINT("\n RCV clip width = %u height = %u \n",width, height);
2156 }
2157 #endif
2158 crop_rect.nWidth = width;
2159 crop_rect.nHeight = height;
2160
2161 bufCnt = 0;
2162 portFmt.format.video.nFrameHeight = height;
2163 portFmt.format.video.nFrameWidth = width;
2164 portFmt.format.video.xFramerate = fps;
2165 OMX_SetParameter(dec_handle,OMX_IndexParamPortDefinition, (OMX_PTR)&portFmt);
2166 OMX_GetParameter(dec_handle,OMX_IndexParamPortDefinition, &portFmt);
2167 DEBUG_PRINT("\nDec: New Min Buffer Count %d", portFmt.nBufferCountMin);
2168 CONFIG_VERSION_SIZE(videoportFmt);
2169 #ifdef MAX_RES_720P
2170 if (color_fmt_type == 0) {
2171 color_fmt = OMX_COLOR_FormatYUV420SemiPlanar;
2172 } else {
2173 color_fmt = (OMX_COLOR_FORMATTYPE)
2174 QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka;
2175 }
2176 #elif _MSM8974_
2177 if (codec_format_option == CODEC_FORMAT_MVC)
2178 color_fmt = (OMX_COLOR_FORMATTYPE)
2179 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView;
2180 else
2181 color_fmt = (OMX_COLOR_FORMATTYPE)
2182 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
2183 #else
2184 color_fmt = (OMX_COLOR_FORMATTYPE)
2185 QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka;
2186 #endif
2187
2188 while (ret == OMX_ErrorNone) {
2189 videoportFmt.nPortIndex = 1;
2190 videoportFmt.nIndex = index;
2191 ret = OMX_GetParameter(dec_handle, OMX_IndexParamVideoPortFormat,
2192 (OMX_PTR)&videoportFmt);
2193
2194 if ((ret == OMX_ErrorNone) && (videoportFmt.eColorFormat ==
2195 color_fmt)) {
2196 DEBUG_PRINT("\n Format[%u] supported by OMX Decoder", color_fmt);
2197 break;
2198 }
2199 index++;
2200 }
2201
2202 if (ret == OMX_ErrorNone) {
2203 if (OMX_SetParameter(dec_handle, OMX_IndexParamVideoPortFormat,
2204 (OMX_PTR)&videoportFmt) != OMX_ErrorNone) {
2205 DEBUG_PRINT_ERROR("\n Setting Tile format failed");
2206 return -1;
2207 }
2208 } else {
2209 DEBUG_PRINT_ERROR("\n Error in retrieving supported color formats");
2210 return -1;
2211 }
2212 picture_order.nPortIndex = 1;
2213 DEBUG_PRINT("\nSet picture order\n");
2214 if (OMX_SetParameter(dec_handle,
2215 (OMX_INDEXTYPE)OMX_QcomIndexParamVideoDecoderPictureOrder,
2216 (OMX_PTR)&picture_order) != OMX_ErrorNone) {
2217 printf("\n ERROR: Setting picture order!");
2218 return -1;
2219 }
2220 DEBUG_PRINT("\nVideo format: W x H (%d x %d)",
2221 portFmt.format.video.nFrameWidth,
2222 portFmt.format.video.nFrameHeight);
2223 if (codec_format_option == CODEC_FORMAT_H264 ||
2224 codec_format_option == CODEC_FORMAT_HEVC ||
2225 codec_format_option == CODEC_FORMAT_HEVC_HYBRID)
2226 {
2227 OMX_VIDEO_CONFIG_NALSIZE naluSize;
2228 naluSize.nNaluBytes = nalSize;
2229 DEBUG_PRINT("\n Nal length is %d index %d",nalSize,OMX_IndexConfigVideoNalSize);
2230 OMX_SetConfig(dec_handle,OMX_IndexConfigVideoNalSize,(OMX_PTR)&naluSize);
2231 DEBUG_PRINT("SETTING THE NAL SIZE to %d\n",naluSize.nNaluBytes);
2232 }
2233 DEBUG_PRINT("\nOMX_SendCommand Decoder -> IDLE\n");
2234 OMX_SendCommand(dec_handle, OMX_CommandStateSet, OMX_StateIdle,0);
2235
2236 input_buf_cnt = portFmt.nBufferCountActual;
2237 DEBUG_PRINT("Transition to Idle State succesful...\n");
2238
2239 #if ALLOCATE_BUFFER
2240 // Allocate buffer on decoder's i/p port
2241 error = Allocate_Buffer(dec_handle, &pInputBufHdrs, portFmt.nPortIndex,
2242 portFmt.nBufferCountActual, portFmt.nBufferSize);
2243 if (error != OMX_ErrorNone) {
2244 DEBUG_PRINT_ERROR("Error - OMX_AllocateBuffer Input buffer error\n");
2245 return -1;
2246 } else {
2247 DEBUG_PRINT("\nOMX_AllocateBuffer Input buffer success\n");
2248 }
2249 #else
2250 // Use buffer on decoder's i/p port
2251 input_use_buffer = true;
2252 DEBUG_PRINT_ERROR("\n before OMX_UseBuffer %p", &pInputBufHdrs);
2253 error = use_input_buffer(dec_handle,
2254 &pInputBufHdrs,
2255 portFmt.nPortIndex,
2256 portFmt.nBufferSize,
2257 portFmt.nBufferCountActual);
2258 if (error != OMX_ErrorNone) {
2259 DEBUG_PRINT_ERROR("ERROR - OMX_UseBuffer Input buffer failed");
2260 return -1;
2261 } else {
2262 DEBUG_PRINT("OMX_UseBuffer Input buffer success\n");
2263 }
2264 #endif
2265 portFmt.nPortIndex = portParam.nStartPortNumber+1;
2266 // Port for which the Client needs to obtain info
2267
2268 OMX_GetParameter(dec_handle,OMX_IndexParamPortDefinition,&portFmt);
2269 DEBUG_PRINT("nMin Buffer Count=%d", portFmt.nBufferCountMin);
2270 DEBUG_PRINT("nBuffer Size=%d", portFmt.nBufferSize);
2271 if (OMX_DirOutput != portFmt.eDir) {
2272 DEBUG_PRINT_ERROR("Error - Expect Output Port\n");
2273 return -1;
2274 }
2275
2276 if (anti_flickering) {
2277 ret = OMX_GetParameter(dec_handle,OMX_IndexParamPortDefinition,&portFmt);
2278 if (ret != OMX_ErrorNone) {
2279 DEBUG_PRINT_ERROR("%s: OMX_GetParameter failed: %d",__FUNCTION__, ret);
2280 return -1;
2281 }
2282 portFmt.nBufferCountActual += 1;
2283 ret = OMX_SetParameter(dec_handle,OMX_IndexParamPortDefinition,&portFmt);
2284 if (ret != OMX_ErrorNone) {
2285 DEBUG_PRINT_ERROR("%s: OMX_SetParameter failed: %d",__FUNCTION__, ret);
2286 return -1;
2287 }
2288 }
2289
2290 #ifndef USE_EGL_IMAGE_TEST_APP
2291 if (use_external_pmem_buf) {
2292 DEBUG_PRINT_ERROR("\n Use External pmem buf: OMX_UseBuffer %p", &pInputBufHdrs);
2293 error = use_output_buffer_multiple_fd(dec_handle,
2294 &pOutYUVBufHdrs,
2295 portFmt.nPortIndex,
2296 portFmt.nBufferSize,
2297 portFmt.nBufferCountActual);
2298 } else {
2299 /* Allocate buffer on decoder's o/p port */
2300 error = Allocate_Buffer(dec_handle, &pOutYUVBufHdrs, portFmt.nPortIndex,
2301 portFmt.nBufferCountActual, portFmt.nBufferSize);
2302 }
2303 free_op_buf_cnt = portFmt.nBufferCountActual;
2304 if (error != OMX_ErrorNone) {
2305 DEBUG_PRINT_ERROR("Error - OMX_AllocateBuffer Output buffer error\n");
2306 return -1;
2307 } else {
2308 DEBUG_PRINT("OMX_AllocateBuffer Output buffer success\n");
2309 }
2310 #else
2311 DEBUG_PRINT_ERROR("\n before OMX_UseBuffer %p", &pInputBufHdrs);
2312 error = use_output_buffer(dec_handle,
2313 &pOutYUVBufHdrs,
2314 portFmt.nPortIndex,
2315 portFmt.nBufferSize,
2316 portFmt.nBufferCountActual);
2317 free_op_buf_cnt = portFmt.nBufferCountActual;
2318 if (error != OMX_ErrorNone) {
2319 DEBUG_PRINT_ERROR("ERROR - OMX_UseBuffer Input buffer failed");
2320 return -1;
2321 } else {
2322 DEBUG_PRINT("OMX_UseBuffer Input buffer success\n");
2323 }
2324 #endif
2325 wait_for_event();
2326 if (currentStatus == ERROR_STATE) {
2327 do_freeHandle_and_clean_up(true);
2328 return -1;
2329 }
2330
2331 if (freeHandle_option == FREE_HANDLE_AT_IDLE) {
2332 OMX_STATETYPE state = OMX_StateInvalid;
2333 OMX_GetState(dec_handle, &state);
2334 if (state == OMX_StateIdle) {
2335 DEBUG_PRINT("Decoder is in OMX_StateIdle and trying to call OMX_FreeHandle \n");
2336 do_freeHandle_and_clean_up(false);
2337 } else {
2338 DEBUG_PRINT_ERROR("Error - Decoder is in state %d and trying to call OMX_FreeHandle \n", state);
2339 do_freeHandle_and_clean_up(true);
2340 }
2341 return -1;
2342 }
2343
2344
2345 DEBUG_PRINT("OMX_SendCommand Decoder -> Executing\n");
2346 OMX_SendCommand(dec_handle, OMX_CommandStateSet, OMX_StateExecuting,0);
2347 wait_for_event();
2348 if (currentStatus == ERROR_STATE) {
2349 do_freeHandle_and_clean_up(true);
2350 return -1;
2351 }
2352 if (pOutYUVBufHdrs == NULL) {
2353 DEBUG_PRINT_ERROR("Error - pOutYUVBufHdrs is NULL\n");
2354 return -1;
2355 }
2356 for (bufCnt=0; bufCnt < (int)portFmt.nBufferCountActual; ++bufCnt) {
2357 DEBUG_PRINT("OMX_FillThisBuffer on output buf no.%d\n",bufCnt);
2358 if (pOutYUVBufHdrs[bufCnt] == NULL) {
2359 DEBUG_PRINT_ERROR("Error - pOutYUVBufHdrs[%d] is NULL\n", bufCnt);
2360 return -1;
2361 }
2362 pOutYUVBufHdrs[bufCnt]->nOutputPortIndex = 1;
2363 pOutYUVBufHdrs[bufCnt]->nFlags &= ~OMX_BUFFERFLAG_EOS;
2364 ret = OMX_FillThisBuffer(dec_handle, pOutYUVBufHdrs[bufCnt]);
2365 if (OMX_ErrorNone != ret)
2366 DEBUG_PRINT_ERROR("Error - OMX_FillThisBuffer failed with result %d\n", ret);
2367 else {
2368 DEBUG_PRINT("OMX_FillThisBuffer success!\n");
2369 free_op_buf_cnt--;
2370 }
2371 }
2372
2373 used_ip_buf_cnt = input_buf_cnt;
2374
2375 rcv_v1 = 0;
2376
2377 //QPERF_START(client_decode);
2378 if (codec_format_option == CODEC_FORMAT_VC1) {
2379 pInputBufHdrs[0]->nOffset = 0;
2380 if (file_type_option == FILE_TYPE_RCV) {
2381 frameSize = Read_Buffer_From_RCV_File_Seq_Layer(pInputBufHdrs[0]);
2382 pInputBufHdrs[0]->nFilledLen = frameSize;
2383 DEBUG_PRINT("After Read_Buffer_From_RCV_File_Seq_Layer, "
2384 "frameSize %d\n", frameSize);
2385 } else if (file_type_option == FILE_TYPE_VC1) {
2386 bHdrflag = 1;
2387 pInputBufHdrs[0]->nFilledLen = Read_Buffer(pInputBufHdrs[0]);
2388 bHdrflag = 0;
2389 DEBUG_PRINT_ERROR("After 1st Read_Buffer for VC1, "
2390 "pInputBufHdrs[0]->nFilledLen %u\n", (unsigned int)pInputBufHdrs[0]->nFilledLen);
2391 } else {
2392 pInputBufHdrs[0]->nFilledLen = Read_Buffer(pInputBufHdrs[0]);
2393 DEBUG_PRINT("After Read_Buffer pInputBufHdrs[0]->nFilledLen %d\n",
2394 pInputBufHdrs[0]->nFilledLen);
2395 }
2396
2397 pInputBufHdrs[0]->nInputPortIndex = 0;
2398 pInputBufHdrs[0]->nOffset = 0;
2399 #ifndef _MSM8974_
2400 pInputBufHdrs[0]->nFlags = 0;
2401 #endif
2402 ret = OMX_EmptyThisBuffer(dec_handle, pInputBufHdrs[0]);
2403 if (ret != OMX_ErrorNone) {
2404 DEBUG_PRINT_ERROR("ERROR - OMX_EmptyThisBuffer failed with result %d\n", ret);
2405 do_freeHandle_and_clean_up(true);
2406 return -1;
2407 } else {
2408 etb_count++;
2409 DEBUG_PRINT("OMX_EmptyThisBuffer success!\n");
2410 }
2411 i = 1;
2412 #ifdef _MSM8974_
2413 pInputBufHdrs[0]->nFlags = 0;
2414 #endif
2415 } else {
2416 i = 0;
2417 }
2418
2419 for (i; i < used_ip_buf_cnt; i++) {
2420 pInputBufHdrs[i]->nInputPortIndex = 0;
2421 pInputBufHdrs[i]->nOffset = 0;
2422 if ((frameSize = Read_Buffer(pInputBufHdrs[i])) <= 0 ) {
2423 DEBUG_PRINT("NO FRAME READ\n");
2424 pInputBufHdrs[i]->nFilledLen = frameSize;
2425 pInputBufHdrs[i]->nInputPortIndex = 0;
2426 pInputBufHdrs[i]->nFlags |= OMX_BUFFERFLAG_EOS;;
2427 bInputEosReached = true;
2428
2429 OMX_EmptyThisBuffer(dec_handle, pInputBufHdrs[i]);
2430 etb_count++;
2431 DEBUG_PRINT("File is small::Either EOS or Some Error while reading file\n");
2432 break;
2433 }
2434 pInputBufHdrs[i]->nFilledLen = frameSize;
2435 pInputBufHdrs[i]->nInputPortIndex = 0;
2436 pInputBufHdrs[i]->nFlags = 0;
2437 //pBufHdr[bufCnt]->pAppPrivate = this;
2438 DEBUG_PRINT("%s: Timestamp sent(%lld)", __FUNCTION__, pInputBufHdrs[i]->nTimeStamp);
2439 ret = OMX_EmptyThisBuffer(dec_handle, pInputBufHdrs[i]);
2440 if (OMX_ErrorNone != ret) {
2441 DEBUG_PRINT_ERROR("ERROR - OMX_EmptyThisBuffer failed with result %d\n", ret);
2442 do_freeHandle_and_clean_up(true);
2443 return -1;
2444 } else {
2445 DEBUG_PRINT("OMX_EmptyThisBuffer success!\n");
2446 etb_count++;
2447 }
2448 }
2449
2450 if (0 != pthread_create(&ebd_thread_id, NULL, ebd_thread, NULL)) {
2451 printf("\n Error in Creating fbd_thread \n");
2452 free_queue(etb_queue);
2453 free_queue(fbd_queue);
2454 return -1;
2455 }
2456
2457 // wait for event port settings changed event
2458 DEBUG_PRINT("wait_for_event: dyn reconfig");
2459 wait_for_event();
2460 DEBUG_PRINT("wait_for_event: dyn reconfig rcvd, currentStatus %d\n",
2461 currentStatus);
2462 if (currentStatus == ERROR_STATE) {
2463 printf("Error - ERROR_STATE\n");
2464 do_freeHandle_and_clean_up(true);
2465 return -1;
2466 } else if (currentStatus == PORT_SETTING_CHANGE_STATE) {
2467 if (output_port_reconfig() != 0) {
2468 DEBUG_PRINT("output_port_reconfig - ERROR_STATE\n");
2469 do_freeHandle_and_clean_up(true);
2470 return -1;
2471 }
2472 }
2473
2474 if (freeHandle_option == FREE_HANDLE_AT_EXECUTING) {
2475 OMX_STATETYPE state = OMX_StateInvalid;
2476 OMX_GetState(dec_handle, &state);
2477 if (state == OMX_StateExecuting) {
2478 DEBUG_PRINT("Decoder is in OMX_StateExecuting and trying to call OMX_FreeHandle \n");
2479 do_freeHandle_and_clean_up(false);
2480 } else {
2481 DEBUG_PRINT_ERROR("Error - Decoder is in state %d and trying to call OMX_FreeHandle \n", state);
2482 do_freeHandle_and_clean_up(true);
2483 }
2484 return -1;
2485 } else if (freeHandle_option == FREE_HANDLE_AT_PAUSE) {
2486 OMX_SendCommand(dec_handle, OMX_CommandStateSet, OMX_StatePause,0);
2487 wait_for_event();
2488
2489 OMX_STATETYPE state = OMX_StateInvalid;
2490 OMX_GetState(dec_handle, &state);
2491 if (state == OMX_StatePause) {
2492 DEBUG_PRINT("Decoder is in OMX_StatePause and trying to call OMX_FreeHandle \n");
2493 do_freeHandle_and_clean_up(false);
2494 } else {
2495 DEBUG_PRINT_ERROR("Error - Decoder is in state %d and trying to call OMX_FreeHandle \n", state);
2496 do_freeHandle_and_clean_up(true);
2497 }
2498 return -1;
2499 }
2500
2501 return 0;
2502 }
2503
Allocate_Buffer(OMX_COMPONENTTYPE * dec_handle,OMX_BUFFERHEADERTYPE *** pBufHdrs,OMX_U32 nPortIndex,long bufCntMin,long bufSize)2504 static OMX_ERRORTYPE Allocate_Buffer ( OMX_COMPONENTTYPE *dec_handle,
2505 OMX_BUFFERHEADERTYPE ***pBufHdrs,
2506 OMX_U32 nPortIndex,
2507 long bufCntMin, long bufSize)
2508 {
2509 DEBUG_PRINT("Inside %s \n", __FUNCTION__);
2510 OMX_ERRORTYPE error=OMX_ErrorNone;
2511 long bufCnt=0;
2512
2513 if (currentStatus == ERROR_STATE) {
2514 return OMX_ErrorInvalidState;
2515 }
2516 DEBUG_PRINT("pBufHdrs = %x,bufCntMin = %d\n", pBufHdrs, bufCntMin);
2517 *pBufHdrs= (OMX_BUFFERHEADERTYPE **)
2518 malloc(sizeof(OMX_BUFFERHEADERTYPE)*bufCntMin);
2519
2520 for (bufCnt=0; bufCnt < bufCntMin; ++bufCnt) {
2521 DEBUG_PRINT("OMX_AllocateBuffer No %d \n", bufCnt);
2522 error = OMX_AllocateBuffer(dec_handle, &((*pBufHdrs)[bufCnt]),
2523 nPortIndex, NULL, bufSize);
2524 }
2525
2526 return error;
2527 }
2528
use_input_buffer(OMX_COMPONENTTYPE * dec_handle,OMX_BUFFERHEADERTYPE *** pBufHdrs,OMX_U32 nPortIndex,OMX_U32 bufSize,long bufCntMin)2529 static OMX_ERRORTYPE use_input_buffer ( OMX_COMPONENTTYPE *dec_handle,
2530 OMX_BUFFERHEADERTYPE ***pBufHdrs,
2531 OMX_U32 nPortIndex,
2532 OMX_U32 bufSize,
2533 long bufCntMin)
2534 {
2535 DEBUG_PRINT("Inside %s \n", __FUNCTION__);
2536 OMX_ERRORTYPE error=OMX_ErrorNone;
2537 long bufCnt=0;
2538 OMX_U8* pvirt = NULL;
2539
2540 *pBufHdrs= (OMX_BUFFERHEADERTYPE **)
2541 malloc(sizeof(OMX_BUFFERHEADERTYPE)* bufCntMin);
2542 if (*pBufHdrs == NULL) {
2543 DEBUG_PRINT_ERROR("\n m_inp_heap_ptr Allocation failed ");
2544 return OMX_ErrorInsufficientResources;
2545 }
2546
2547 for (bufCnt=0; bufCnt < bufCntMin; ++bufCnt) {
2548 // allocate input buffers
2549 DEBUG_PRINT("OMX_UseBuffer No %d %d \n", bufCnt, bufSize);
2550 pvirt = (OMX_U8*) malloc (bufSize);
2551 if (pvirt == NULL) {
2552 DEBUG_PRINT_ERROR("\n pvirt Allocation failed ");
2553 return OMX_ErrorInsufficientResources;
2554 }
2555 error = OMX_UseBuffer(dec_handle, &((*pBufHdrs)[bufCnt]),
2556 nPortIndex, NULL, bufSize, pvirt);
2557 }
2558 return error;
2559 }
2560
use_output_buffer(OMX_COMPONENTTYPE * dec_handle,OMX_BUFFERHEADERTYPE *** pBufHdrs,OMX_U32 nPortIndex,OMX_U32 bufSize,long bufCntMin)2561 static OMX_ERRORTYPE use_output_buffer ( OMX_COMPONENTTYPE *dec_handle,
2562 OMX_BUFFERHEADERTYPE ***pBufHdrs,
2563 OMX_U32 nPortIndex,
2564 OMX_U32 bufSize,
2565 long bufCntMin)
2566 {
2567 DEBUG_PRINT("Inside %s \n", __FUNCTION__);
2568 OMX_ERRORTYPE error=OMX_ErrorNone;
2569 long bufCnt=0;
2570 OMX_U8* pvirt = NULL;
2571
2572 *pBufHdrs= (OMX_BUFFERHEADERTYPE **)
2573 malloc(sizeof(OMX_BUFFERHEADERTYPE)* bufCntMin);
2574 if (*pBufHdrs == NULL) {
2575 DEBUG_PRINT_ERROR("\n m_inp_heap_ptr Allocation failed ");
2576 return OMX_ErrorInsufficientResources;
2577 }
2578 output_use_buffer = true;
2579 p_eglHeaders = (struct temp_egl **)
2580 malloc(sizeof(struct temp_egl *)* bufCntMin);
2581 if (!p_eglHeaders) {
2582 DEBUG_PRINT_ERROR("\n EGL allocation failed");
2583 return OMX_ErrorInsufficientResources;
2584 }
2585
2586 for (bufCnt=0; bufCnt < bufCntMin; ++bufCnt) {
2587 // allocate input buffers
2588 DEBUG_PRINT("OMX_UseBuffer No %d %d \n", bufCnt, bufSize);
2589 p_eglHeaders[bufCnt] = (struct temp_egl*)
2590 malloc(sizeof(struct temp_egl));
2591 if (!p_eglHeaders[bufCnt]) {
2592 DEBUG_PRINT_ERROR("\n EGL allocation failed");
2593 return OMX_ErrorInsufficientResources;
2594 }
2595 p_eglHeaders[bufCnt]->pmem_fd = open(PMEM_DEVICE,O_RDWR);
2596 p_eglHeaders[bufCnt]->offset = 0;
2597 if (p_eglHeaders[bufCnt]->pmem_fd < 0) {
2598 DEBUG_PRINT_ERROR("\n open failed %s",PMEM_DEVICE);
2599 return OMX_ErrorInsufficientResources;
2600 }
2601
2602 #ifndef USE_ION
2603 /* TBD - this commenting is dangerous */
2604 align_pmem_buffers(p_eglHeaders[bufCnt]->pmem_fd, bufSize,
2605 8192);
2606 #endif
2607 DEBUG_PRINT_ERROR("\n allocation size %u pmem fd %d",(unsigned int)bufSize,p_eglHeaders[bufCnt]->pmem_fd);
2608 pvirt = (unsigned char *)mmap(NULL,bufSize,PROT_READ|PROT_WRITE,
2609 MAP_SHARED,p_eglHeaders[bufCnt]->pmem_fd,0);
2610 DEBUG_PRINT_ERROR("\n Virtaul Address %p Size %u",pvirt,(unsigned int)bufSize);
2611 if (pvirt == MAP_FAILED) {
2612 DEBUG_PRINT_ERROR("\n mmap failed for buffers");
2613 return OMX_ErrorInsufficientResources;
2614 }
2615 use_buf_virt_addr[bufCnt] = (unsigned)pvirt;
2616 error = OMX_UseEGLImage(dec_handle, &((*pBufHdrs)[bufCnt]),
2617 nPortIndex, pvirt,(void *)p_eglHeaders[bufCnt]);
2618 }
2619 return error;
2620 }
2621
use_output_buffer_multiple_fd(OMX_COMPONENTTYPE * dec_handle,OMX_BUFFERHEADERTYPE *** pBufHdrs,OMX_U32 nPortIndex,OMX_U32 bufSize,long bufCntMin)2622 static OMX_ERRORTYPE use_output_buffer_multiple_fd ( OMX_COMPONENTTYPE *dec_handle,
2623 OMX_BUFFERHEADERTYPE ***pBufHdrs,
2624 OMX_U32 nPortIndex,
2625 OMX_U32 bufSize,
2626 long bufCntMin)
2627 {
2628 DEBUG_PRINT("Inside %s \n", __FUNCTION__);
2629 OMX_ERRORTYPE error=OMX_ErrorNone;
2630 long bufCnt=0;
2631 OMX_U8* pvirt = NULL;
2632
2633 *pBufHdrs= (OMX_BUFFERHEADERTYPE **)
2634 malloc(sizeof(OMX_BUFFERHEADERTYPE)* bufCntMin);
2635 if (*pBufHdrs == NULL) {
2636 DEBUG_PRINT_ERROR("\n m_inp_heap_ptr Allocation failed ");
2637 return OMX_ErrorInsufficientResources;
2638 }
2639 pPlatformList = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)
2640 malloc(sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST)* bufCntMin);
2641
2642 if (pPlatformList == NULL) {
2643 DEBUG_PRINT_ERROR("\n pPlatformList Allocation failed ");
2644 return OMX_ErrorInsufficientResources;
2645 }
2646
2647 pPlatformEntry = (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
2648 malloc(sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY)* bufCntMin);
2649
2650 if (pPlatformEntry == NULL) {
2651 DEBUG_PRINT_ERROR("\n pPlatformEntry Allocation failed ");
2652 return OMX_ErrorInsufficientResources;
2653 }
2654
2655 pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
2656 malloc(sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO)* bufCntMin);
2657
2658 if (pPMEMInfo == NULL) {
2659 DEBUG_PRINT_ERROR("\n pPMEMInfo Allocation failed ");
2660 return OMX_ErrorInsufficientResources;
2661 }
2662
2663 //output_use_buffer = true;
2664 for (bufCnt=0; bufCnt < bufCntMin; ++bufCnt) {
2665 // allocate input buffers
2666 DEBUG_PRINT("OMX_UseBuffer_multiple_fd No %d %d \n", bufCnt, bufSize);
2667
2668 pPlatformEntry[bufCnt].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
2669 pPlatformEntry[bufCnt].entry = &pPMEMInfo[bufCnt];
2670 // Initialize the Platform List
2671 pPlatformList[bufCnt].nEntries = 1;
2672 pPlatformList[bufCnt].entryList = &pPlatformEntry[bufCnt];
2673 pPMEMInfo[bufCnt].offset = 0;
2674 pPMEMInfo[bufCnt].pmem_fd = open(PMEM_DEVICE,O_RDWR);;
2675 if ((int)pPMEMInfo[bufCnt].pmem_fd < 0) {
2676 DEBUG_PRINT_ERROR("\n open failed %s",PMEM_DEVICE);
2677 return OMX_ErrorInsufficientResources;
2678 }
2679 #ifndef USE_ION
2680 /* TBD - this commenting is dangerous */
2681 align_pmem_buffers(pPMEMInfo[bufCnt].pmem_fd, bufSize,
2682 8192);
2683 #endif
2684 DEBUG_PRINT("\n allocation size %d pmem fd 0x%x",bufSize,pPMEMInfo[bufCnt].pmem_fd);
2685 pvirt = (unsigned char *)mmap(NULL,bufSize,PROT_READ|PROT_WRITE,
2686 MAP_SHARED,pPMEMInfo[bufCnt].pmem_fd,0);
2687 getFreePmem();
2688 DEBUG_PRINT("\n Virtaul Address %p Size %d pmem_fd=0x%x",pvirt,bufSize,pPMEMInfo[bufCnt].pmem_fd);
2689 if (pvirt == MAP_FAILED) {
2690 DEBUG_PRINT_ERROR("\n mmap failed for buffers");
2691 return OMX_ErrorInsufficientResources;
2692 }
2693 use_buf_virt_addr[bufCnt] = (unsigned)pvirt;
2694 error = OMX_UseBuffer(dec_handle, &((*pBufHdrs)[bufCnt]),
2695 nPortIndex, &pPlatformList[bufCnt], bufSize, pvirt);
2696 }
2697 return error;
2698 }
do_freeHandle_and_clean_up(bool isDueToError)2699 static void do_freeHandle_and_clean_up(bool isDueToError)
2700 {
2701 int bufCnt = 0;
2702 OMX_STATETYPE state = OMX_StateInvalid;
2703 OMX_GetState(dec_handle, &state);
2704 if (state == OMX_StateExecuting || state == OMX_StatePause) {
2705 DEBUG_PRINT("Requesting transition to Idle");
2706 OMX_SendCommand(dec_handle, OMX_CommandStateSet, OMX_StateIdle, 0);
2707 do {
2708 wait_for_event();
2709 OMX_GetState(dec_handle, &state);
2710 DEBUG_PRINT("returned state %d", state);
2711 } while ((state != OMX_StateIdle) && (state != OMX_StateInvalid));
2712 }
2713 OMX_GetState(dec_handle, &state);
2714 if (state == OMX_StateIdle) {
2715 DEBUG_PRINT("Requesting transition to Loaded");
2716 OMX_SendCommand(dec_handle, OMX_CommandStateSet, OMX_StateLoaded, 0);
2717 for (bufCnt=0; bufCnt < input_buf_cnt; ++bufCnt) {
2718 if (pInputBufHdrs[bufCnt]->pBuffer && input_use_buffer) {
2719 free(pInputBufHdrs[bufCnt]->pBuffer);
2720 pInputBufHdrs[bufCnt]->pBuffer = NULL;
2721 DEBUG_PRINT_ERROR("\nFree(pInputBufHdrs[%d]->pBuffer)",bufCnt);
2722 }
2723 OMX_FreeBuffer(dec_handle, 0, pInputBufHdrs[bufCnt]);
2724 }
2725 if (pInputBufHdrs) {
2726 free(pInputBufHdrs);
2727 pInputBufHdrs = NULL;
2728 }
2729 for (bufCnt = 0; bufCnt < (int)portFmt.nBufferCountActual; ++bufCnt) {
2730 if (output_use_buffer && p_eglHeaders) {
2731 if (p_eglHeaders[bufCnt]) {
2732 munmap (pOutYUVBufHdrs[bufCnt]->pBuffer,
2733 pOutYUVBufHdrs[bufCnt]->nAllocLen);
2734 close(p_eglHeaders[bufCnt]->pmem_fd);
2735 p_eglHeaders[bufCnt]->pmem_fd = -1;
2736 free(p_eglHeaders[bufCnt]);
2737 p_eglHeaders[bufCnt] = NULL;
2738 }
2739 }
2740 if (use_external_pmem_buf) {
2741 DEBUG_PRINT("Freeing in external pmem case: buffer=0x%x, pmem_fd=0x%d",
2742 pOutYUVBufHdrs[bufCnt]->pBuffer,
2743 pPMEMInfo[bufCnt].pmem_fd);
2744 if (pOutYUVBufHdrs[bufCnt]->pBuffer) {
2745 munmap (pOutYUVBufHdrs[bufCnt]->pBuffer,
2746 pOutYUVBufHdrs[bufCnt]->nAllocLen);
2747 }
2748 if (&pPMEMInfo[bufCnt]) {
2749 close(pPMEMInfo[bufCnt].pmem_fd);
2750 pPMEMInfo[bufCnt].pmem_fd = -1;
2751 }
2752 }
2753 OMX_FreeBuffer(dec_handle, 1, pOutYUVBufHdrs[bufCnt]);
2754 }
2755 if (p_eglHeaders) {
2756 free(p_eglHeaders);
2757 p_eglHeaders = NULL;
2758 }
2759 if (pPMEMInfo) {
2760 DEBUG_PRINT("Freeing in external pmem case:PMEM");
2761 free(pPMEMInfo);
2762 pPMEMInfo = NULL;
2763 }
2764 if (pPlatformEntry) {
2765 DEBUG_PRINT("Freeing in external pmem case:ENTRY");
2766 free(pPlatformEntry);
2767 pPlatformEntry = NULL;
2768 }
2769 if (pPlatformList) {
2770 DEBUG_PRINT("Freeing in external pmem case:LIST");
2771 free(pPlatformList);
2772 pPlatformList = NULL;
2773 }
2774 wait_for_event();
2775 }
2776
2777 DEBUG_PRINT("[OMX Vdec Test] - Free handle decoder\n");
2778 OMX_ERRORTYPE result = OMX_FreeHandle(dec_handle);
2779 if (result != OMX_ErrorNone) {
2780 DEBUG_PRINT_ERROR("[OMX Vdec Test] - OMX_FreeHandle error. Error code: %d\n", result);
2781 }
2782 dec_handle = NULL;
2783
2784 /* Deinit OpenMAX */
2785 DEBUG_PRINT("[OMX Vdec Test] - De-initializing OMX \n");
2786 OMX_Deinit();
2787
2788 DEBUG_PRINT("[OMX Vdec Test] - closing all files\n");
2789 if (inputBufferFileFd != -1) {
2790 close(inputBufferFileFd);
2791 inputBufferFileFd = -1;
2792 }
2793
2794 DEBUG_PRINT("[OMX Vdec Test] - after free inputfile\n");
2795
2796 if (takeYuvLog && outputBufferFile) {
2797 fclose(outputBufferFile);
2798 outputBufferFile = NULL;
2799 }
2800 #ifdef _MSM8974_
2801 if (crcFile) {
2802 fclose(crcFile);
2803 crcFile = NULL;
2804 }
2805 #endif
2806 DEBUG_PRINT("[OMX Vdec Test] - after free outputfile\n");
2807
2808 if (etb_queue) {
2809 free_queue(etb_queue);
2810 etb_queue = NULL;
2811 }
2812 DEBUG_PRINT("[OMX Vdec Test] - after free etb_queue \n");
2813 if (fbd_queue) {
2814 free_queue(fbd_queue);
2815 fbd_queue = NULL;
2816 }
2817 DEBUG_PRINT("[OMX Vdec Test] - after free iftb_queue\n");
2818 printf("*****************************************\n");
2819 if (isDueToError)
2820 printf("************...TEST FAILED...************\n");
2821 else
2822 printf("**********...TEST SUCCESSFULL...*********\n");
2823 printf("*****************************************\n");
2824 }
2825
Read_Buffer_From_DAT_File(OMX_BUFFERHEADERTYPE * pBufHdr)2826 static int Read_Buffer_From_DAT_File(OMX_BUFFERHEADERTYPE *pBufHdr)
2827 {
2828 long frameSize=0;
2829 char temp_buffer[10];
2830 char temp_byte;
2831 int bytes_read=0;
2832 int i=0;
2833 unsigned char *read_buffer=NULL;
2834 char c = '1'; //initialize to anything except '\0'(0)
2835 char inputFrameSize[12];
2836 int count =0;
2837 int cnt = 0;
2838 memset(temp_buffer, 0, sizeof(temp_buffer));
2839
2840 DEBUG_PRINT("Inside %s \n", __FUNCTION__);
2841
2842 while (cnt < 10)
2843 /* Check the input file format, may result in infinite loop */
2844 {
2845 DEBUG_PRINT("loop[%d] count[%d]\n",cnt,count);
2846 count = read( inputBufferFileFd, &inputFrameSize[cnt], 1);
2847 if (inputFrameSize[cnt] == '\0' )
2848 break;
2849 cnt++;
2850 }
2851 inputFrameSize[cnt]='\0';
2852 frameSize = atoi(inputFrameSize);
2853 pBufHdr->nFilledLen = 0;
2854
2855 /* get the frame length */
2856 lseek64(inputBufferFileFd, -1, SEEK_CUR);
2857 bytes_read = read(inputBufferFileFd, pBufHdr->pBuffer, frameSize);
2858
2859 DEBUG_PRINT("Actual frame Size [%d] bytes_read using fread[%d]\n",
2860 frameSize, bytes_read);
2861
2862 if (bytes_read == 0 || bytes_read < frameSize ) {
2863 DEBUG_PRINT("Bytes read Zero After Read frame Size \n");
2864 DEBUG_PRINT("Checking VideoPlayback Count:video_playback_count is:%d\n",
2865 video_playback_count);
2866 return 0;
2867 }
2868 pBufHdr->nTimeStamp = timeStampLfile;
2869 timeStampLfile += timestampInterval;
2870 return bytes_read;
2871 }
2872
Read_Buffer_From_H264_Start_Code_File(OMX_BUFFERHEADERTYPE * pBufHdr)2873 static int Read_Buffer_From_H264_Start_Code_File(OMX_BUFFERHEADERTYPE *pBufHdr)
2874 {
2875 int bytes_read = 0;
2876 int cnt = 0;
2877 unsigned int code = 0;
2878 int naluType = 0;
2879 int newFrame = 0;
2880 char *dataptr = (char *)pBufHdr->pBuffer;
2881 DEBUG_PRINT("Inside %s", __FUNCTION__);
2882 do {
2883 newFrame = 0;
2884 bytes_read = read(inputBufferFileFd, &dataptr[cnt], 1);
2885 if (!bytes_read) {
2886 DEBUG_PRINT("\n%s: Bytes read Zero", __FUNCTION__);
2887 break;
2888 }
2889 code <<= 8;
2890 code |= (0x000000FF & dataptr[cnt]);
2891 cnt++;
2892 if ((cnt == 4) && (code != H264_START_CODE)) {
2893 DEBUG_PRINT_ERROR("\n%s: ERROR: Invalid start code found 0x%x", __FUNCTION__, code);
2894 cnt = 0;
2895 break;
2896 }
2897 if ((cnt > 4) && (code == H264_START_CODE)) {
2898 DEBUG_PRINT("%s: Found H264_START_CODE", __FUNCTION__);
2899 bytes_read = read(inputBufferFileFd, &dataptr[cnt], 1);
2900 if (!bytes_read) {
2901 DEBUG_PRINT("\n%s: Bytes read Zero", __FUNCTION__);
2902 break;
2903 }
2904 DEBUG_PRINT("%s: READ Byte[%d] = 0x%x", __FUNCTION__, cnt, dataptr[cnt]);
2905 naluType = dataptr[cnt] & 0x1F;
2906 cnt++;
2907 if ((naluType == 1) || (naluType == 5)) {
2908 DEBUG_PRINT("%s: Found AU", __FUNCTION__);
2909 bytes_read = read(inputBufferFileFd, &dataptr[cnt], 1);
2910 if (!bytes_read) {
2911 DEBUG_PRINT("\n%s: Bytes read Zero", __FUNCTION__);
2912 break;
2913 }
2914 DEBUG_PRINT("%s: READ Byte[%d] = 0x%x", __FUNCTION__, cnt, dataptr[cnt]);
2915 newFrame = (dataptr[cnt] & 0x80);
2916 cnt++;
2917 if (newFrame) {
2918 lseek64(inputBufferFileFd, -6, SEEK_CUR);
2919 cnt -= 6;
2920 DEBUG_PRINT("%s: Found a NAL unit (type 0x%x) of size = %d", __FUNCTION__, (dataptr[4] & 0x1F), cnt);
2921 break;
2922 } else {
2923 DEBUG_PRINT("%s: Not a New Frame", __FUNCTION__);
2924 }
2925 } else {
2926 lseek64(inputBufferFileFd, -5, SEEK_CUR);
2927 cnt -= 5;
2928 DEBUG_PRINT("%s: Found NAL unit (type 0x%x) of size = %d", __FUNCTION__, (dataptr[4] & 0x1F), cnt);
2929 break;
2930 }
2931 }
2932 } while (1);
2933
2934 #ifdef TEST_TS_FROM_SEI
2935 if (timeStampLfile == 0)
2936 pBufHdr->nTimeStamp = 0;
2937 else
2938 pBufHdr->nTimeStamp = LLONG_MAX;
2939 #else
2940 pBufHdr->nTimeStamp = timeStampLfile;
2941 #endif
2942 timeStampLfile += timestampInterval;
2943
2944 return cnt;
2945 }
2946
Read_Buffer_ArbitraryBytes(OMX_BUFFERHEADERTYPE * pBufHdr)2947 static int Read_Buffer_ArbitraryBytes(OMX_BUFFERHEADERTYPE *pBufHdr)
2948 {
2949 int bytes_read=0;
2950 DEBUG_PRINT("Inside %s \n", __FUNCTION__);
2951 bytes_read = read(inputBufferFileFd, pBufHdr->pBuffer, NUMBER_OF_ARBITRARYBYTES_READ);
2952 if (bytes_read == 0) {
2953 DEBUG_PRINT("Bytes read Zero After Read frame Size \n");
2954 DEBUG_PRINT("Checking VideoPlayback Count:video_playback_count is:%d\n",
2955 video_playback_count);
2956 return 0;
2957 }
2958 #ifdef TEST_TS_FROM_SEI
2959 if (timeStampLfile == 0)
2960 pBufHdr->nTimeStamp = 0;
2961 else
2962 pBufHdr->nTimeStamp = LLONG_MAX;
2963 #else
2964 pBufHdr->nTimeStamp = timeStampLfile;
2965 #endif
2966 timeStampLfile += timestampInterval;
2967 return bytes_read;
2968 }
2969
Read_Buffer_From_Vop_Start_Code_File(OMX_BUFFERHEADERTYPE * pBufHdr)2970 static int Read_Buffer_From_Vop_Start_Code_File(OMX_BUFFERHEADERTYPE *pBufHdr)
2971 {
2972 unsigned int readOffset = 0;
2973 int bytes_read = 0;
2974 unsigned int code = 0;
2975 pBufHdr->nFilledLen = 0;
2976 static unsigned int header_code = 0;
2977
2978 DEBUG_PRINT("Inside %s", __FUNCTION__);
2979
2980 do {
2981 //Start codes are always byte aligned.
2982 bytes_read = read(inputBufferFileFd, &pBufHdr->pBuffer[readOffset], 1);
2983 if (bytes_read == 0 || bytes_read == -1) {
2984 DEBUG_PRINT("Bytes read Zero \n");
2985 break;
2986 }
2987 code <<= 8;
2988 code |= (0x000000FF & pBufHdr->pBuffer[readOffset]);
2989 //VOP start code comparision
2990 if (readOffset>3) {
2991 if (!header_code ) {
2992 if ( VOP_START_CODE == code) {
2993 header_code = VOP_START_CODE;
2994 } else if ( (0xFFFFFC00 & code) == SHORT_HEADER_START_CODE ) {
2995 header_code = SHORT_HEADER_START_CODE;
2996 }
2997 }
2998 if ((header_code == VOP_START_CODE) && (code == VOP_START_CODE)) {
2999 //Seek backwards by 4
3000 lseek64(inputBufferFileFd, -4, SEEK_CUR);
3001 readOffset-=3;
3002 break;
3003 } else if (( header_code == SHORT_HEADER_START_CODE ) && ( SHORT_HEADER_START_CODE == (code & 0xFFFFFC00))) {
3004 //Seek backwards by 4
3005 lseek64(inputBufferFileFd, -4, SEEK_CUR);
3006 readOffset-=3;
3007 break;
3008 }
3009 }
3010 readOffset++;
3011 } while (1);
3012 pBufHdr->nTimeStamp = timeStampLfile;
3013 timeStampLfile += timestampInterval;
3014 return readOffset;
3015 }
Read_Buffer_From_Mpeg2_Start_Code(OMX_BUFFERHEADERTYPE * pBufHdr)3016 static int Read_Buffer_From_Mpeg2_Start_Code(OMX_BUFFERHEADERTYPE *pBufHdr)
3017 {
3018 unsigned int readOffset = 0;
3019 int bytesRead = 0;
3020 unsigned int code = 0;
3021 pBufHdr->nFilledLen = 0;
3022 static unsigned int firstParse = true;
3023 unsigned int seenFrame = false;
3024
3025 DEBUG_PRINT("Inside %s", __FUNCTION__);
3026
3027 /* Read one byte at a time. Construct the code every byte in order to
3028 * compare to the start codes. Keep looping until we've read in a complete
3029 * frame, which can be either just a picture start code + picture, or can
3030 * include the sequence header as well
3031 */
3032 while (1) {
3033 bytesRead = read(inputBufferFileFd, &pBufHdr->pBuffer[readOffset], 1);
3034
3035 /* Exit the loop if we can't read any more bytes */
3036 if (bytesRead == 0 || bytesRead == -1) {
3037 break;
3038 }
3039
3040 /* Construct the code one byte at a time */
3041 code <<= 8;
3042 code |= (0x000000FF & pBufHdr->pBuffer[readOffset]);
3043
3044 /* Can't compare the code to MPEG2 start codes until we've read the
3045 * first four bytes
3046 */
3047 if (readOffset >= 3) {
3048
3049 /* If this is the first time we're reading from the file, then we
3050 * need to throw away the system start code information at the
3051 * beginning. We can just look for the first sequence header.
3052 */
3053 if (firstParse) {
3054 if (code == MPEG2_SEQ_START_CODE) {
3055 /* Seek back by 4 bytes and reset code so that we can skip
3056 * down to the common case below.
3057 */
3058 lseek(inputBufferFileFd, -4, SEEK_CUR);
3059 code = 0;
3060 readOffset -= 3;
3061 firstParse = false;
3062 continue;
3063 }
3064 }
3065
3066 /* If we have already parsed a frame and we see a sequence header, then
3067 * the sequence header is part of the next frame so we seek back and
3068 * break.
3069 */
3070 if (code == MPEG2_SEQ_START_CODE) {
3071 if (seenFrame) {
3072 lseek(inputBufferFileFd, -4, SEEK_CUR);
3073 readOffset -= 3;
3074 break;
3075 }
3076 /* If we haven't seen a frame yet, then read in all the data until we
3077 * either see another frame start code or sequence header start code.
3078 */
3079 } else if (code == MPEG2_FRAME_START_CODE) {
3080 if (!seenFrame) {
3081 seenFrame = true;
3082 } else {
3083 lseek(inputBufferFileFd, -4, SEEK_CUR);
3084 readOffset -= 3;
3085 break;
3086 }
3087 }
3088 }
3089
3090 readOffset++;
3091 }
3092
3093 pBufHdr->nTimeStamp = timeStampLfile;
3094 timeStampLfile += timestampInterval;
3095 return readOffset;
3096 }
3097
3098
Read_Buffer_From_Size_Nal(OMX_BUFFERHEADERTYPE * pBufHdr)3099 static int Read_Buffer_From_Size_Nal(OMX_BUFFERHEADERTYPE *pBufHdr)
3100 {
3101 // NAL unit stream processing
3102 char temp_size[SIZE_NAL_FIELD_MAX];
3103 int i = 0;
3104 int j = 0;
3105 unsigned int size = 0; // Need to make sure that uint32 has SIZE_NAL_FIELD_MAX (4) bytes
3106 int bytes_read = 0;
3107
3108 // read the "size_nal_field"-byte size field
3109 bytes_read = read(inputBufferFileFd, pBufHdr->pBuffer + pBufHdr->nOffset, nalSize);
3110 if (bytes_read == 0 || bytes_read == -1) {
3111 DEBUG_PRINT("Failed to read frame or it might be EOF\n");
3112 return 0;
3113 }
3114
3115 for (i=0; i<SIZE_NAL_FIELD_MAX-nalSize; i++) {
3116 temp_size[SIZE_NAL_FIELD_MAX - 1 - i] = 0;
3117 }
3118
3119 /* Due to little endiannes, Reorder the size based on size_nal_field */
3120 for (j=0; i<SIZE_NAL_FIELD_MAX; i++, j++) {
3121 temp_size[SIZE_NAL_FIELD_MAX - 1 - i] = pBufHdr->pBuffer[pBufHdr->nOffset + j];
3122 }
3123 size = (unsigned int)(*((unsigned int *)(temp_size)));
3124
3125 // now read the data
3126 bytes_read = read(inputBufferFileFd, pBufHdr->pBuffer + pBufHdr->nOffset + nalSize, size);
3127 if (bytes_read != (int)size) {
3128 DEBUG_PRINT_ERROR("Failed to read frame\n");
3129 }
3130
3131 pBufHdr->nTimeStamp = timeStampLfile;
3132 timeStampLfile += timestampInterval;
3133
3134 return bytes_read + nalSize;
3135 }
3136
Read_Buffer_From_RCV_File_Seq_Layer(OMX_BUFFERHEADERTYPE * pBufHdr)3137 static int Read_Buffer_From_RCV_File_Seq_Layer(OMX_BUFFERHEADERTYPE *pBufHdr)
3138 {
3139 unsigned int readOffset = 0, size_struct_C = 0;
3140 unsigned int startcode = 0;
3141 pBufHdr->nFilledLen = 0;
3142 #ifdef _MSM8974_
3143 pBufHdr->nFlags |= OMX_BUFFERFLAG_CODECCONFIG;
3144 #else
3145 pBufHdr->nFlags = 0;
3146 #endif
3147
3148 DEBUG_PRINT("Inside %s \n", __FUNCTION__);
3149
3150 read(inputBufferFileFd, &startcode, 4);
3151
3152 /* read size of struct C as it need not be 4 always*/
3153 read(inputBufferFileFd, &size_struct_C, 4);
3154
3155 #ifndef _MSM8974_
3156 /* reseek to beginning of sequence header */
3157 lseek64(inputBufferFileFd, -8, SEEK_CUR);
3158 #endif
3159 if ((startcode & 0xFF000000) == 0xC5000000) {
3160
3161 DEBUG_PRINT("Read_Buffer_From_RCV_File_Seq_Layer size_struct_C: %d\n", size_struct_C);
3162 #ifdef _MSM8974_
3163 readOffset = read(inputBufferFileFd, pBufHdr->pBuffer, size_struct_C);
3164 lseek64(inputBufferFileFd, 24, SEEK_CUR);
3165 #else
3166 readOffset = read(inputBufferFileFd, pBufHdr->pBuffer, VC1_SEQ_LAYER_SIZE_WITHOUT_STRUCTC + size_struct_C);
3167 #endif
3168 } else if ((startcode & 0xFF000000) == 0x85000000) {
3169 // .RCV V1 file
3170
3171 rcv_v1 = 1;
3172
3173 DEBUG_PRINT("Read_Buffer_From_RCV_File_Seq_Layer size_struct_C: %d\n", size_struct_C);
3174 #ifdef _MSM8974_
3175 readOffset = read(inputBufferFileFd, pBufHdr->pBuffer, size_struct_C);
3176 lseek64(inputBufferFileFd, 8, SEEK_CUR);
3177 #else
3178 readOffset = read(inputBufferFileFd, pBufHdr->pBuffer, VC1_SEQ_LAYER_SIZE_V1_WITHOUT_STRUCTC + size_struct_C);
3179 #endif
3180
3181 } else {
3182 DEBUG_PRINT_ERROR("Error: Unknown VC1 clip format %x\n", startcode);
3183 }
3184
3185 #if 0
3186 {
3187 int i=0;
3188 printf("Read_Buffer_From_RCV_File, length %d readOffset %d\n", readOffset, readOffset);
3189 for (i=0; i<36; i++) {
3190 printf("0x%.2x ", pBufHdr->pBuffer[i]);
3191 if (i%16 == 15) {
3192 printf("\n");
3193 }
3194 }
3195 printf("\n");
3196 }
3197 #endif
3198 return readOffset;
3199 }
3200
Read_Buffer_From_RCV_File(OMX_BUFFERHEADERTYPE * pBufHdr)3201 static int Read_Buffer_From_RCV_File(OMX_BUFFERHEADERTYPE *pBufHdr)
3202 {
3203 unsigned int readOffset = 0;
3204 unsigned int len = 0;
3205 unsigned int key = 0;
3206 DEBUG_PRINT("Inside %s \n", __FUNCTION__);
3207
3208 DEBUG_PRINT("Read_Buffer_From_RCV_File - nOffset %d\n", pBufHdr->nOffset);
3209 if (rcv_v1) {
3210 /* for the case of RCV V1 format, the frame header is only of 4 bytes and has
3211 only the frame size information */
3212 readOffset = read(inputBufferFileFd, &len, 4);
3213 DEBUG_PRINT("Read_Buffer_From_RCV_File - framesize %d %x\n", len, len);
3214
3215 } else {
3216 /* for a regular RCV file, 3 bytes comprise the frame size and 1 byte for key*/
3217 readOffset = read(inputBufferFileFd, &len, 3);
3218 DEBUG_PRINT("Read_Buffer_From_RCV_File - framesize %d %x\n", len, len);
3219
3220 readOffset = read(inputBufferFileFd, &key, 1);
3221 if ( (key & 0x80) == false) {
3222 DEBUG_PRINT("Read_Buffer_From_RCV_File - Non IDR frame key %x\n", key);
3223 }
3224
3225 }
3226
3227 if (!rcv_v1) {
3228 /* There is timestamp field only for regular RCV format and not for RCV V1 format*/
3229 readOffset = read(inputBufferFileFd, &pBufHdr->nTimeStamp, 4);
3230 DEBUG_PRINT("Read_Buffer_From_RCV_File - timeStamp %d\n", pBufHdr->nTimeStamp);
3231 pBufHdr->nTimeStamp *= 1000;
3232 } else {
3233 pBufHdr->nTimeStamp = timeStampLfile;
3234 timeStampLfile += timestampInterval;
3235 }
3236
3237 if (len > pBufHdr->nAllocLen) {
3238 DEBUG_PRINT_ERROR("Error in sufficient buffer framesize %u, allocalen %u noffset %u\n",len,(unsigned int)pBufHdr->nAllocLen, (unsigned int)pBufHdr->nOffset);
3239 readOffset = read(inputBufferFileFd, pBufHdr->pBuffer+pBufHdr->nOffset,
3240 pBufHdr->nAllocLen - pBufHdr->nOffset);
3241
3242 loff_t off = (len - readOffset)*1LL;
3243 lseek64(inputBufferFileFd, off ,SEEK_CUR);
3244 return readOffset;
3245 } else {
3246 readOffset = read(inputBufferFileFd, pBufHdr->pBuffer+pBufHdr->nOffset, len);
3247 }
3248 if (readOffset != len) {
3249 DEBUG_PRINT("EOS reach or Reading error %d, %s \n", readOffset, strerror( errno ));
3250 return 0;
3251 }
3252
3253 #if 0
3254 {
3255 int i=0;
3256 printf("Read_Buffer_From_RCV_File, length %d readOffset %d\n", len, readOffset);
3257 for (i=0; i<64; i++) {
3258 printf("0x%.2x ", pBufHdr->pBuffer[i]);
3259 if (i%16 == 15) {
3260 printf("\n");
3261 }
3262 }
3263 printf("\n");
3264 }
3265 #endif
3266
3267 return readOffset;
3268 }
3269
Read_Buffer_From_VC1_File(OMX_BUFFERHEADERTYPE * pBufHdr)3270 static int Read_Buffer_From_VC1_File(OMX_BUFFERHEADERTYPE *pBufHdr)
3271 {
3272 static int timeStampLfile = 0;
3273 OMX_U8 *pBuffer = pBufHdr->pBuffer + pBufHdr->nOffset;
3274 DEBUG_PRINT("Inside %s \n", __FUNCTION__);
3275 unsigned int readOffset = 0;
3276 int bytes_read = 0;
3277 unsigned int code = 0, total_bytes = 0;
3278 int startCode_cnt = 0;
3279 int bSEQflag = 0;
3280 int bEntryflag = 0;
3281 unsigned int SEQbytes = 0;
3282 int numStartcodes = 0;
3283
3284 numStartcodes = bHdrflag?1:2;
3285
3286 do {
3287 if (total_bytes == pBufHdr->nAllocLen) {
3288 DEBUG_PRINT_ERROR("Buffer overflow!");
3289 break;
3290 }
3291 //Start codes are always byte aligned.
3292 bytes_read = read(inputBufferFileFd, &pBuffer[readOffset],1 );
3293
3294 if (!bytes_read) {
3295 DEBUG_PRINT("\n Bytes read Zero \n");
3296 break;
3297 }
3298 total_bytes++;
3299 code <<= 8;
3300 code |= (0x000000FF & pBufHdr->pBuffer[readOffset]);
3301
3302 if (!bSEQflag && (code == VC1_SEQUENCE_START_CODE)) {
3303 if (startCode_cnt) bSEQflag = 1;
3304 }
3305
3306 if (!bEntryflag && ( code == VC1_ENTRY_POINT_START_CODE)) {
3307 if (startCode_cnt) bEntryflag = 1;
3308 }
3309
3310 if (code == VC1_FRAME_START_CODE || code == VC1_FRAME_FIELD_CODE) {
3311 startCode_cnt++ ;
3312 }
3313
3314 //VOP start code comparision
3315 if (startCode_cnt == numStartcodes) {
3316 if (VC1_FRAME_START_CODE == (code & 0xFFFFFFFF) ||
3317 VC1_FRAME_FIELD_CODE == (code & 0xFFFFFFFF)) {
3318 previous_vc1_au = 0;
3319 if (VC1_FRAME_FIELD_CODE == (code & 0xFFFFFFFF)) {
3320 previous_vc1_au = 1;
3321 }
3322
3323 if (!bHdrflag && (bSEQflag || bEntryflag)) {
3324 lseek(inputBufferFileFd,-(SEQbytes+4),SEEK_CUR);
3325 readOffset -= (SEQbytes+3);
3326 } else {
3327 //Seek backwards by 4
3328 lseek64(inputBufferFileFd, -4, SEEK_CUR);
3329 readOffset-=3;
3330 }
3331
3332 while (pBufHdr->pBuffer[readOffset-1] == 0)
3333 readOffset--;
3334
3335 break;
3336 }
3337 }
3338 readOffset++;
3339 if (bSEQflag || bEntryflag) {
3340 SEQbytes++;
3341 }
3342 } while (1);
3343
3344 pBufHdr->nTimeStamp = timeStampLfile;
3345 timeStampLfile += timestampInterval;
3346
3347 #if 0
3348 {
3349 int i=0;
3350 printf("Read_Buffer_From_VC1_File, readOffset %d\n", readOffset);
3351 for (i=0; i<64; i++) {
3352 printf("0x%.2x ", pBufHdr->pBuffer[i]);
3353 if (i%16 == 15) {
3354 printf("\n");
3355 }
3356 }
3357 printf("\n");
3358 }
3359 #endif
3360
3361 return readOffset;
3362 }
3363
Read_Buffer_From_DivX_4_5_6_File(OMX_BUFFERHEADERTYPE * pBufHdr)3364 static int Read_Buffer_From_DivX_4_5_6_File(OMX_BUFFERHEADERTYPE *pBufHdr)
3365 {
3366 #define MAX_NO_B_FRMS 3 // Number of non-b-frames packed in each buffer
3367 #define N_PREV_FRMS_B 1 // Number of previous non-b-frames packed
3368 // with a set of consecutive b-frames
3369 #define FRM_ARRAY_SIZE (MAX_NO_B_FRMS + N_PREV_FRMS_B)
3370 char *p_buffer = NULL;
3371 unsigned int offset_array[FRM_ARRAY_SIZE];
3372 int byte_cntr, pckt_end_idx = 0;
3373 unsigned int read_code = 0, bytes_read, byte_pos = 0, frame_type;
3374 unsigned int i, b_frm_idx, b_frames_found = 0, vop_set_cntr = 0;
3375 bool pckt_ready = false;
3376 #ifdef __DEBUG_DIVX__
3377 char pckt_type[20];
3378 int pckd_frms = 0;
3379 static unsigned long long int total_bytes = 0;
3380 static unsigned long long int total_frames = 0;
3381 #endif //__DEBUG_DIVX__
3382
3383 DEBUG_PRINT("Inside %s \n", __FUNCTION__);
3384
3385 do {
3386 p_buffer = (char *)pBufHdr->pBuffer + byte_pos;
3387
3388 bytes_read = read(inputBufferFileFd, p_buffer, NUMBER_OF_ARBITRARYBYTES_READ);
3389 byte_pos += bytes_read;
3390 for (byte_cntr = 0; byte_cntr < (int)bytes_read && !pckt_ready; byte_cntr++) {
3391 read_code <<= 8;
3392 ((char*)&read_code)[0] = p_buffer[byte_cntr];
3393 if (read_code == VOP_START_CODE) {
3394 if (++byte_cntr < (int)bytes_read) {
3395 frame_type = p_buffer[byte_cntr];
3396 frame_type &= 0x000000C0;
3397 #ifdef __DEBUG_DIVX__
3398 switch (frame_type) {
3399 case 0x00:
3400 pckt_type[pckd_frms] = 'I';
3401 break;
3402 case 0x40:
3403 pckt_type[pckd_frms] = 'P';
3404 break;
3405 case 0x80:
3406 pckt_type[pckd_frms] = 'B';
3407 break;
3408 default:
3409 pckt_type[pckd_frms] = 'X';
3410 }
3411 pckd_frms++;
3412 #endif // __DEBUG_DIVX__
3413 offset_array[vop_set_cntr] = byte_pos - bytes_read + byte_cntr - 4;
3414 if (frame_type == 0x80) { // B Frame found!
3415 if (!b_frames_found) {
3416 // Try to packet N_PREV_FRMS_B previous frames
3417 // with the next consecutive B frames
3418 i = N_PREV_FRMS_B;
3419 while (((int)vop_set_cntr - (int)i) < 0 && i > 0) i--;
3420 b_frm_idx = vop_set_cntr - i;
3421 if (b_frm_idx > 0) {
3422 pckt_end_idx = b_frm_idx;
3423 pckt_ready = true;
3424 #ifdef __DEBUG_DIVX__
3425 pckt_type[b_frm_idx] = '\0';
3426 total_frames += b_frm_idx;
3427 #endif //__DEBUG_DIVX__
3428 }
3429 }
3430 b_frames_found++;
3431 } else if (b_frames_found) {
3432 pckt_end_idx = vop_set_cntr;
3433 pckt_ready = true;
3434 #ifdef __DEBUG_DIVX__
3435 pckt_type[pckd_frms - 1] = '\0';
3436 total_frames += pckd_frms - 1;
3437 #endif //__DEBUG_DIVX__
3438 } else if (vop_set_cntr == (FRM_ARRAY_SIZE -1)) {
3439 pckt_end_idx = MAX_NO_B_FRMS;
3440 pckt_ready = true;
3441 #ifdef __DEBUG_DIVX__
3442 pckt_type[pckt_end_idx] = '\0';
3443 total_frames += pckt_end_idx;
3444 #endif //__DEBUG_DIVX__
3445 } else
3446 vop_set_cntr++;
3447 } else {
3448 // The vop start code was found in the last 4 bytes,
3449 // seek backwards by 4 to include this start code
3450 // with the next buffer.
3451 lseek64(inputBufferFileFd, -4, SEEK_CUR);
3452 byte_pos -= 4;
3453 #ifdef __DEBUG_DIVX__
3454 pckd_frms--;
3455 #endif //__DEBUG_DIVX__
3456 }
3457 }
3458 }
3459 if (pckt_ready) {
3460 loff_t off = (byte_pos - offset_array[pckt_end_idx]);
3461 if ( lseek64(inputBufferFileFd, -1LL*off , SEEK_CUR) == -1 ) {
3462 DEBUG_PRINT_ERROR("lseek64 with offset = %lld failed with errno %d"
3463 ", current position =0x%llx", -1LL*off,
3464 errno, lseek64(inputBufferFileFd, 0, SEEK_CUR));
3465 }
3466 } else {
3467 char eofByte;
3468 int ret = read(inputBufferFileFd, &eofByte, 1 );
3469 if ( ret == 0 ) {
3470 offset_array[vop_set_cntr] = byte_pos;
3471 pckt_end_idx = vop_set_cntr;
3472 pckt_ready = true;
3473 #ifdef __DEBUG_DIVX__
3474 pckt_type[pckd_frms] = '\0';
3475 total_frames += pckd_frms;
3476 #endif //__DEBUG_DIVX__
3477 } else if (ret == 1) {
3478 if ( lseek64(inputBufferFileFd, -1, SEEK_CUR ) == -1 ) {
3479 DEBUG_PRINT_ERROR("lseek64 failed with errno = %d, "
3480 "current fileposition = %llx",
3481 errno,
3482 lseek64(inputBufferFileFd, 0, SEEK_CUR));
3483 }
3484 } else {
3485 DEBUG_PRINT_ERROR("Error when checking for EOF");
3486 }
3487 }
3488 } while (!pckt_ready);
3489 pBufHdr->nFilledLen = offset_array[pckt_end_idx];
3490 pBufHdr->nTimeStamp = timeStampLfile;
3491 timeStampLfile += timestampInterval;
3492 #ifdef __DEBUG_DIVX__
3493 total_bytes += pBufHdr->nFilledLen;
3494 ALOGE("[DivX] Packet: Type[%s] Size[%u] TS[%lld] TB[%llx] NFrms[%lld]\n",
3495 pckt_type, pBufHdr->nFilledLen, pBufHdr->nTimeStamp,
3496 total_bytes, total_frames);
3497 #endif //__DEBUG_DIVX__
3498 return pBufHdr->nFilledLen;
3499 }
3500
Read_Buffer_From_DivX_311_File(OMX_BUFFERHEADERTYPE * pBufHdr)3501 static int Read_Buffer_From_DivX_311_File(OMX_BUFFERHEADERTYPE *pBufHdr)
3502 {
3503 static OMX_S64 timeStampLfile = 0;
3504 char *p_buffer = NULL;
3505 bool pkt_ready = false;
3506 unsigned int frame_type = 0;
3507 unsigned int bytes_read = 0;
3508 unsigned int frame_size = 0;
3509 unsigned int num_bytes_size = 4;
3510 unsigned int num_bytes_frame_type = 1;
3511 unsigned int n_offset = pBufHdr->nOffset;
3512
3513 DEBUG_PRINT("Inside %s \n", __FUNCTION__);
3514
3515 pBufHdr->nTimeStamp = timeStampLfile;
3516
3517 if (pBufHdr != NULL) {
3518 p_buffer = (char *)pBufHdr->pBuffer + pBufHdr->nOffset;
3519 } else {
3520 DEBUG_PRINT("\n ERROR:Read_Buffer_From_DivX_311_File: pBufHdr is NULL\n");
3521 return 0;
3522 }
3523
3524 if (p_buffer == NULL) {
3525 DEBUG_PRINT("\n ERROR:Read_Buffer_From_DivX_311_File: p_bufhdr is NULL\n");
3526 return 0;
3527 }
3528
3529 //Read first frame based on size
3530 //DivX 311 frame - 4 byte header with size followed by the frame
3531
3532 bytes_read = read(inputBufferFileFd, &frame_size, num_bytes_size);
3533
3534 DEBUG_PRINT("Read_Buffer_From_DivX_311_File: Frame size = %d\n", frame_size);
3535 n_offset += read(inputBufferFileFd, p_buffer, frame_size);
3536
3537 pBufHdr->nTimeStamp = timeStampLfile;
3538
3539 timeStampLfile += timestampInterval;
3540
3541 //the packet is ready to be sent
3542 DEBUG_PRINT("\nReturning Read Buffer from Divx 311: TS=[%ld], Offset=[%d]\n",
3543 (long int)pBufHdr->nTimeStamp,
3544 n_offset );
3545
3546 return n_offset;
3547 }
3548 #ifdef _MSM8974_
Read_Buffer_From_VP8_File(OMX_BUFFERHEADERTYPE * pBufHdr)3549 static int Read_Buffer_From_VP8_File(OMX_BUFFERHEADERTYPE *pBufHdr)
3550 {
3551 static OMX_S64 timeStampLfile = 0;
3552 char *p_buffer = NULL;
3553 bool pkt_ready = false;
3554 unsigned int frame_type = 0;
3555 unsigned int bytes_read = 0;
3556 unsigned int frame_size = 0;
3557 unsigned int num_bytes_size = 4;
3558 unsigned int num_bytes_frame_type = 1;
3559 unsigned long long time_stamp;
3560 unsigned int n_offset = pBufHdr->nOffset;
3561 static int ivf_header_read;
3562
3563 if (pBufHdr != NULL) {
3564 p_buffer = (char *)pBufHdr->pBuffer + pBufHdr->nOffset;
3565 } else {
3566 DEBUG_PRINT("\n ERROR:Read_Buffer_From_DivX_311_File: pBufHdr is NULL\n");
3567 return 0;
3568 }
3569
3570 if (p_buffer == NULL) {
3571 DEBUG_PRINT("\n ERROR:Read_Buffer_From_DivX_311_File: p_bufhdr is NULL\n");
3572 return 0;
3573 }
3574
3575 if (ivf_header_read == 0) {
3576 bytes_read = read(inputBufferFileFd, p_buffer, 32);
3577 ivf_header_read = 1;
3578 if (p_buffer[0] == 'D' && p_buffer[1] == 'K' && p_buffer[2] == 'I' && p_buffer[3] == 'F') {
3579 printf(" \n IVF header found \n ");
3580 } else {
3581 printf(" \n No IVF header found \n ");
3582 lseek(inputBufferFileFd, -32, SEEK_CUR);
3583 }
3584 }
3585 bytes_read = read(inputBufferFileFd, &frame_size, 4);
3586 bytes_read = read(inputBufferFileFd, &time_stamp, 8);
3587 n_offset += read(inputBufferFileFd, p_buffer, frame_size);
3588 pBufHdr->nTimeStamp = time_stamp;
3589 return n_offset;
3590 }
3591
Read_Buffer_From_MVC_File(OMX_BUFFERHEADERTYPE * pBufHdr)3592 static int Read_Buffer_From_MVC_File(OMX_BUFFERHEADERTYPE *pBufHdr)
3593 {
3594 int newFrame = 0;
3595 int bytes_read = 0;
3596 int cnt = 0;
3597 int naluType = 0;
3598 unsigned int code = 0;
3599 char *pBuffer = NULL;
3600
3601 if (pBufHdr == NULL || pBufHdr->pBuffer == NULL) {
3602 DEBUG_PRINT("\n ERROR: %s: input is NULL\n", __FUNCTION__);
3603 return 0;
3604 }
3605 pBuffer = (char *)pBufHdr->pBuffer;
3606 pBufHdr->nFilledLen = 0;
3607
3608 do {
3609 naluType = 0;
3610 cnt = 0;
3611 code = 0;
3612 newFrame = 0;
3613 do {
3614 bytes_read = read(inputBufferFileFd, &pBuffer[cnt], 1);
3615 if (!bytes_read) {
3616 DEBUG_PRINT("\n%s: Bytes read Zero\n", __FUNCTION__);
3617 break;
3618 } else if (cnt == 4) {
3619 naluType = pBuffer[cnt] & 0x1F;
3620 DEBUG_PRINT("%s: Found NALU type = %d\n", __FUNCTION__, naluType);
3621 }
3622 code <<= 8;
3623 code |= (0x000000FF & pBuffer[cnt]);
3624 cnt++;
3625 if ((cnt == 4) && (code != H264_START_CODE)) {
3626 DEBUG_PRINT_ERROR("\n%s: ERROR: Invalid start code found 0x%x\n", __FUNCTION__, code);
3627 lseek64(inputBufferFileFd, -4, SEEK_CUR);
3628 cnt = 0;
3629 bytes_read = 0;
3630 break;
3631 } else if ((cnt > 4) && (code == H264_START_CODE)) {
3632 DEBUG_PRINT("%s: Found next H264_START_CODE\n", __FUNCTION__);
3633 lseek64(inputBufferFileFd, -4, SEEK_CUR);
3634 cnt -= 4;
3635 break;
3636 }
3637 if (pBufHdr->nAllocLen <= pBufHdr->nFilledLen + cnt) {
3638 DEBUG_PRINT_ERROR("\n%s: ERROR: Invalid input file for MVC codec", __FUNCTION__);
3639 cnt = 0;
3640 bytes_read = 0;
3641 break;
3642 }
3643 } while (1);
3644 pBufHdr->nFilledLen += cnt;
3645 pBuffer += cnt;
3646 }while (naluType != 20 && bytes_read != 0);
3647
3648 pBufHdr->nTimeStamp = 0;
3649 pBufHdr->nOffset = 0;
3650
3651 DEBUG_PRINT("%s: Return: pBuffer = %p, FilledLen= %ld, TS=[%Lu]\n",
3652 __FUNCTION__,
3653 pBufHdr->pBuffer,
3654 pBufHdr->nFilledLen,
3655 pBufHdr->nTimeStamp);
3656 return pBufHdr->nFilledLen;
3657 }
3658 #endif
open_video_file()3659 static int open_video_file ()
3660 {
3661 int error_code = 0;
3662 char outputfilename[512];
3663 DEBUG_PRINT("Inside %s filename=%s\n", __FUNCTION__, in_filename);
3664
3665 if ( (inputBufferFileFd = open( in_filename, O_RDONLY | O_LARGEFILE) ) == -1 ) {
3666 DEBUG_PRINT_ERROR("Error - i/p file %s could NOT be opened errno = %d\n",
3667 in_filename, errno);
3668 error_code = -1;
3669 } else {
3670 DEBUG_PRINT_ERROR("i/p file %s is opened \n", in_filename);
3671 }
3672
3673 if (takeYuvLog) {
3674 strlcpy(outputfilename, "yuvframes.yuv", 14);
3675 outputBufferFile = fopen (outputfilename, "ab");
3676 if (outputBufferFile == NULL) {
3677 DEBUG_PRINT_ERROR("ERROR - o/p file %s could NOT be opened\n", outputfilename);
3678 error_code = -1;
3679 } else {
3680 DEBUG_PRINT("O/p file %s is opened \n", outputfilename);
3681 }
3682 }
3683 #ifdef _MSM8974_
3684 /*if (!crcFile) {
3685 crcFile = fopen(crclogname, "ab");
3686 if (!crcFile) {
3687 printf("Failed to open CRC file\n");
3688 error_code = -1;
3689 }
3690 }*/
3691 #endif
3692 return error_code;
3693 }
3694
swap_byte(char * pByte,int nbyte)3695 void swap_byte(char *pByte, int nbyte)
3696 {
3697 int i=0;
3698
3699 for (i=0; i<nbyte/2; i++) {
3700 pByte[i] ^= pByte[nbyte-i-1];
3701 pByte[nbyte-i-1] ^= pByte[i];
3702 pByte[i] ^= pByte[nbyte-i-1];
3703 }
3704 }
3705
drawBG(void)3706 int drawBG(void)
3707 {
3708 int result;
3709 unsigned int i;
3710 #ifdef FRAMEBUFFER_32
3711 long * p;
3712 #else
3713 short * p;
3714 #endif
3715 void *fb_buf = mmap (NULL, finfo.smem_len,PROT_READ|PROT_WRITE, MAP_SHARED, fb_fd, 0);
3716
3717 if (fb_buf == MAP_FAILED) {
3718 printf("ERROR: Framebuffer MMAP failed!\n");
3719 close(fb_fd);
3720 return -1;
3721 }
3722
3723 vinfo.yoffset = 0;
3724 p = (long *)fb_buf;
3725
3726 for (i=0; i < vinfo.xres * vinfo.yres; i++) {
3727 #ifdef FRAMEBUFFER_32
3728 *p++ = COLOR_BLACK_RGBA_8888;
3729 #else
3730 *p++ = CLR_KEY;
3731 #endif
3732 }
3733
3734 if (ioctl(fb_fd, FBIOPAN_DISPLAY, &vinfo) < 0) {
3735 printf("ERROR: FBIOPAN_DISPLAY failed! line=%d\n", __LINE__);
3736 return -1;
3737 }
3738
3739 DEBUG_PRINT("drawBG success!\n");
3740 return 0;
3741 }
3742
overlay_vsync_ctrl(int enable)3743 static int overlay_vsync_ctrl(int enable)
3744 {
3745 int ret;
3746 int vsync_en = enable;
3747 ret = ioctl(fb_fd, MSMFB_OVERLAY_VSYNC_CTRL, &vsync_en);
3748 if (ret)
3749 printf("\n MSMFB_OVERLAY_VSYNC_CTRL failed! (Line %d)\n",
3750 __LINE__);
3751 return ret;
3752 }
3753
3754
3755
overlay_set()3756 void overlay_set()
3757 {
3758 overlayp = &overlay;
3759 overlayp->src.width = stride;
3760 overlayp->src.height = sliceheight;
3761 #ifdef MAX_RES_720P
3762 overlayp->src.format = MDP_Y_CRCB_H2V2;
3763 if (color_fmt == (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka) {
3764 overlayp->src.format = MDP_Y_CRCB_H2V2_TILE;
3765 }
3766 #endif
3767 #ifdef MAX_RES_1080P
3768 overlayp->src.format = MDP_Y_CBCR_H2V2_TILE;
3769 #endif
3770 #ifdef _MSM8974_
3771 overlayp->src.format = MDP_Y_CBCR_H2V2_VENUS;
3772 #endif
3773 overlayp->src_rect.x = 0;
3774 overlayp->src_rect.y = 0;
3775 overlayp->src_rect.w = width;
3776 overlayp->src_rect.h = height;
3777
3778 if (width >= (int)vinfo.xres) {
3779 overlayp->dst_rect.x = 0;
3780 overlayp->dst_rect.w = vinfo.xres;
3781 } else {
3782 overlayp->dst_rect.x = (vinfo.xres - width)/2;
3783 overlayp->dst_rect.w = width;
3784 }
3785
3786 if (height >= (int)vinfo.yres) {
3787 overlayp->dst_rect.h = (overlayp->dst_rect.w * height)/width;
3788 overlayp->dst_rect.y = 0;
3789 if (overlayp->dst_rect.h < vinfo.yres)
3790 overlayp->dst_rect.y = (vinfo.yres - overlayp->dst_rect.h)/2;
3791 else
3792 overlayp->dst_rect.h = vinfo.yres;
3793 } else {
3794 overlayp->dst_rect.y = (vinfo.yres - height)/2;
3795 overlayp->dst_rect.h = height;
3796 }
3797
3798 //Decimation + MDP Downscale
3799 overlayp->horz_deci = 0;
3800 overlayp->vert_deci = 0;
3801 int minHorDeci = 0;
3802 if (overlayp->src_rect.w > 2048) {
3803 //If the client sends us something > what a layer mixer supports
3804 //then it means it doesn't want to use split-pipe but wants us to
3805 //decimate. A minimum decimation of 2 will ensure that the width is
3806 //always within layer mixer limits.
3807 minHorDeci = 2;
3808 }
3809
3810 float horDscale = ceilf((float)overlayp->src_rect.w /
3811 (float)overlayp->dst_rect.w);
3812 float verDscale = ceilf((float)overlayp->src_rect.h /
3813 (float)overlayp->dst_rect.h);
3814
3815 //Next power of 2, if not already
3816 horDscale = powf(2.0f, ceilf(log2f(horDscale)));
3817 verDscale = powf(2.0f, ceilf(log2f(verDscale)));
3818
3819 //Since MDP can do 1/4 dscale and has better quality, split the task
3820 //between decimator and MDP downscale
3821 horDscale /= 4.0f;
3822 verDscale /= 4.0f;
3823
3824 if (horDscale < minHorDeci)
3825 horDscale = minHorDeci;
3826 if ((int)horDscale)
3827 overlayp->horz_deci = (int)log2f(horDscale);
3828
3829 if ((int)verDscale)
3830 overlayp->vert_deci = (int)log2f(verDscale);
3831
3832 printf("overlayp->src.width = %u \n", overlayp->src.width);
3833 printf("overlayp->src.height = %u \n", overlayp->src.height);
3834 printf("overlayp->src_rect.x = %u \n", overlayp->src_rect.x);
3835 printf("overlayp->src_rect.y = %u \n", overlayp->src_rect.y);
3836 printf("overlayp->src_rect.w = %u \n", overlayp->src_rect.w);
3837 printf("overlayp->src_rect.h = %u \n", overlayp->src_rect.h);
3838 printf("overlayp->dst_rect.x = %u \n", overlayp->dst_rect.x);
3839 printf("overlayp->dst_rect.y = %u \n", overlayp->dst_rect.y);
3840 printf("overlayp->dst_rect.w = %u \n", overlayp->dst_rect.w);
3841 printf("overlayp->dst_rect.h = %u \n", overlayp->dst_rect.h);
3842 printf("overlayp->vert_deci = %u \n", overlayp->vert_deci);
3843 printf("overlayp->horz_deci = %u \n", overlayp->horz_deci);
3844
3845 overlayp->z_order = 0;
3846 overlayp->alpha = 0xff;
3847 overlayp->transp_mask = 0xFFFFFFFF;
3848 overlayp->flags = 0;
3849 overlayp->is_fg = 0;
3850
3851 overlayp->id = MSMFB_NEW_REQUEST;
3852
3853 overlay_vsync_ctrl(OMX_TRUE);
3854 drawBG();
3855 vid_buf_front_id = ioctl(fb_fd, MSMFB_OVERLAY_SET, overlayp);
3856 if (vid_buf_front_id < 0) {
3857 printf("ERROR: MSMFB_OVERLAY_SET failed! line=%d\n", __LINE__);
3858 }
3859 vid_buf_front_id = overlayp->id;
3860 DEBUG_PRINT("\n vid_buf_front_id = %u", vid_buf_front_id);
3861 displayYuv = 2;
3862 }
3863
overlay_fb(struct OMX_BUFFERHEADERTYPE * pBufHdr)3864 int overlay_fb(struct OMX_BUFFERHEADERTYPE *pBufHdr)
3865 {
3866 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
3867 struct msmfb_overlay_data ov_front;
3868 memset(&ov_front, 0, sizeof(struct msmfb_overlay_data));
3869 #if defined(_ANDROID_) && !defined(USE_EGL_IMAGE_TEST_APP) && !defined(USE_EXTERN_PMEM_BUF)
3870 MemoryHeapBase *vheap = NULL;
3871 #endif
3872
3873 DEBUG_PRINT("overlay_fb:");
3874 ov_front.id = overlayp->id;
3875 if (pBufHdr->pPlatformPrivate == NULL) {
3876 ALOGE("overlay_fb: pPlatformPrivate is null");
3877 return -1;
3878 }
3879 pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
3880 ((OMX_QCOM_PLATFORM_PRIVATE_LIST *)
3881 pBufHdr->pPlatformPrivate)->entryList->entry;
3882 if (pPMEMInfo == NULL) {
3883
3884 ALOGE("overlay_fb: pmem_info is null");
3885 return -1;
3886 }
3887 #if defined(_ANDROID_) && !defined(USE_EGL_IMAGE_TEST_APP) && !defined(USE_EXTERN_PMEM_BUF)
3888 vheap = (MemoryHeapBase*)pPMEMInfo->pmem_fd;
3889 #endif
3890
3891
3892 #if defined(_ANDROID_) && !defined(USE_EGL_IMAGE_TEST_APP) && !defined(USE_EXTERN_PMEM_BUF) && !defined(_MSM8974_)
3893 ov_front.data.memory_id = vheap->getHeapID();
3894 #else
3895 ov_front.data.memory_id = pPMEMInfo->pmem_fd;
3896 #endif
3897
3898 ov_front.data.offset = pPMEMInfo->offset;
3899
3900 DEBUG_PRINT("\n ov_front.data.memory_id = %d", ov_front.data.memory_id);
3901 DEBUG_PRINT("\n ov_front.data.offset = %u", ov_front.data.offset);
3902 if (ioctl(fb_fd, MSMFB_OVERLAY_PLAY, (void*)&ov_front)) {
3903 printf("\nERROR! MSMFB_OVERLAY_PLAY failed at frame (Line %d)\n",
3904 __LINE__);
3905 return -1;
3906 }
3907 if (ioctl(fb_fd, FBIOPAN_DISPLAY, &vinfo) < 0) {
3908 printf("ERROR: FBIOPAN_DISPLAY failed! line=%d\n", __LINE__);
3909 return -1;
3910 }
3911
3912 DEBUG_PRINT("\nMSMFB_OVERLAY_PLAY successfull");
3913 return 0;
3914 }
3915
overlay_unset()3916 void overlay_unset()
3917 {
3918 if (ioctl(fb_fd, MSMFB_OVERLAY_UNSET, &vid_buf_front_id)) {
3919 printf("\nERROR! MSMFB_OVERLAY_UNSET failed! (Line %d)\n", __LINE__);
3920 }
3921 }
3922
render_fb(struct OMX_BUFFERHEADERTYPE * pBufHdr)3923 void render_fb(struct OMX_BUFFERHEADERTYPE *pBufHdr)
3924 {
3925 unsigned int addr = 0;
3926 OMX_OTHER_EXTRADATATYPE *pExtraData = 0;
3927 OMX_QCOM_EXTRADATA_FRAMEINFO *pExtraFrameInfo = 0;
3928 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
3929 unsigned int destx, desty,destW, destH;
3930 #if defined(_ANDROID_) && !defined(USE_EGL_IMAGE_TEST_APP) && !defined(USE_EXTERN_PMEM_BUF)
3931 MemoryHeapBase *vheap = NULL;
3932 #endif
3933
3934 unsigned int end = (unsigned int)(pBufHdr->pBuffer + pBufHdr->nAllocLen);
3935
3936 struct mdp_blit_req *e;
3937 union {
3938 char dummy[sizeof(struct mdp_blit_req_list) +
3939 sizeof(struct mdp_blit_req) * 1];
3940 struct mdp_blit_req_list list;
3941 } img;
3942
3943 if (fb_fd < 0) {
3944 DEBUG_PRINT_ERROR("Warning: /dev/fb0 is not opened!\n");
3945 return;
3946 }
3947
3948 img.list.count = 1;
3949 e = &img.list.req[0];
3950
3951 addr = (unsigned int)(pBufHdr->pBuffer + pBufHdr->nFilledLen);
3952 // align to a 4 byte boundary
3953 addr = (addr + 3) & (~3);
3954
3955 // read to the end of existing extra data sections
3956 pExtraData = (OMX_OTHER_EXTRADATATYPE*)addr;
3957
3958 while (addr < end && (int)pExtraData->eType != (int)OMX_ExtraDataFrameInfo) {
3959 addr += pExtraData->nSize;
3960 pExtraData = (OMX_OTHER_EXTRADATATYPE*)addr;
3961 }
3962
3963 if ((int)pExtraData->eType != (int)OMX_ExtraDataFrameInfo) {
3964 DEBUG_PRINT_ERROR("pExtraData->eType %d pExtraData->nSize %u\n",pExtraData->eType, (unsigned int)pExtraData->nSize);
3965 }
3966 pExtraFrameInfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)pExtraData->data;
3967
3968 pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
3969 ((OMX_QCOM_PLATFORM_PRIVATE_LIST *)
3970 pBufHdr->pPlatformPrivate)->entryList->entry;
3971 #if defined(_ANDROID_) && !defined(USE_EGL_IMAGE_TEST_APP) && !defined(USE_EXTERN_PMEM_BUF)
3972 vheap = (MemoryHeapBase *)pPMEMInfo->pmem_fd;
3973 #endif
3974
3975
3976 DEBUG_PRINT_ERROR("DecWidth %u DecHeight %u\n",(unsigned int)portFmt.format.video.nStride,(unsigned int)portFmt.format.video.nSliceHeight);
3977 DEBUG_PRINT_ERROR("DispWidth %u DispHeight %u\n",(unsigned int)portFmt.format.video.nFrameWidth,(unsigned int)portFmt.format.video.nFrameHeight);
3978
3979
3980
3981 e->src.width = portFmt.format.video.nStride;
3982 e->src.height = portFmt.format.video.nSliceHeight;
3983 e->src.format = MDP_Y_CBCR_H2V2;
3984 e->src.offset = pPMEMInfo->offset;
3985 #if defined(_ANDROID_) && !defined(USE_EGL_IMAGE_TEST_APP) && !defined(USE_EXTERN_PMEM_BUF)
3986 e->src.memory_id = vheap->getHeapID();
3987 #else
3988 e->src.memory_id = pPMEMInfo->pmem_fd;
3989 #endif
3990
3991 DEBUG_PRINT_ERROR("pmemOffset %d pmemID %d\n",e->src.offset,e->src.memory_id);
3992
3993 e->dst.width = vinfo.xres;
3994 e->dst.height = vinfo.yres;
3995 e->dst.format = MDP_RGB_565;
3996 e->dst.offset = 0;
3997 e->dst.memory_id = fb_fd;
3998
3999 e->transp_mask = 0xffffffff;
4000 DEBUG_PRINT("Frame interlace type %d!\n", pExtraFrameInfo->interlaceType);
4001 if (pExtraFrameInfo->interlaceType != OMX_QCOM_InterlaceFrameProgressive) {
4002 DEBUG_PRINT("Interlaced Frame!\n");
4003 e->flags = MDP_DEINTERLACE;
4004 } else
4005 e->flags = 0;
4006 e->alpha = 0xff;
4007
4008 switch (displayWindow) {
4009 case 1:
4010 destx = 0;
4011 desty = 0;
4012 destW = vinfo.xres/2;
4013 destH = vinfo.yres/2;
4014 break;
4015 case 2:
4016 destx = vinfo.xres/2;
4017 desty = 0;
4018 destW = vinfo.xres/2;
4019 destH = vinfo.yres/2;
4020 break;
4021
4022 case 3:
4023 destx = 0;
4024 desty = vinfo.yres/2;
4025 destW = vinfo.xres/2;
4026 destH = vinfo.yres/2;
4027 break;
4028 case 4:
4029 destx = vinfo.xres/2;
4030 desty = vinfo.yres/2;
4031 destW = vinfo.xres/2;
4032 destH = vinfo.yres/2;
4033 break;
4034 case 0:
4035 default:
4036 destx = 0;
4037 desty = 0;
4038 destW = vinfo.xres;
4039 destH = vinfo.yres;
4040 }
4041
4042
4043 if (portFmt.format.video.nFrameWidth < destW)
4044 destW = portFmt.format.video.nFrameWidth ;
4045
4046
4047 if (portFmt.format.video.nFrameHeight < destH)
4048 destH = portFmt.format.video.nFrameHeight;
4049
4050 e->dst_rect.x = destx;
4051 e->dst_rect.y = desty;
4052 e->dst_rect.w = destW;
4053 e->dst_rect.h = destH;
4054
4055 //e->dst_rect.w = 800;
4056 //e->dst_rect.h = 480;
4057
4058 e->src_rect.x = 0;
4059 e->src_rect.y = 0;
4060 e->src_rect.w = portFmt.format.video.nFrameWidth;
4061 e->src_rect.h = portFmt.format.video.nFrameHeight;
4062
4063 //e->src_rect.w = portFmt.format.video.nStride;
4064 //e->src_rect.h = portFmt.format.video.nSliceHeight;
4065
4066 if (ioctl(fb_fd, MSMFB_BLIT, &img)) {
4067 DEBUG_PRINT_ERROR("MSMFB_BLIT ioctl failed!\n");
4068 return;
4069 }
4070
4071 if (ioctl(fb_fd, FBIOPAN_DISPLAY, &vinfo) < 0) {
4072 DEBUG_PRINT_ERROR("FBIOPAN_DISPLAY failed! line=%d\n", __LINE__);
4073 return;
4074 }
4075
4076 DEBUG_PRINT("render_fb complete!\n");
4077 }
4078
disable_output_port()4079 int disable_output_port()
4080 {
4081 DEBUG_PRINT("DISABLING OP PORT\n");
4082 pthread_mutex_lock(&enable_lock);
4083 sent_disabled = 1;
4084 // Send DISABLE command
4085 OMX_SendCommand(dec_handle, OMX_CommandPortDisable, 1, 0);
4086 pthread_mutex_unlock(&enable_lock);
4087 // wait for Disable event to come back
4088 wait_for_event();
4089 if (p_eglHeaders) {
4090 free(p_eglHeaders);
4091 p_eglHeaders = NULL;
4092 }
4093 if (pPMEMInfo) {
4094 DEBUG_PRINT("Freeing in external pmem case:PMEM");
4095 free(pPMEMInfo);
4096 pPMEMInfo = NULL;
4097 }
4098 if (pPlatformEntry) {
4099 DEBUG_PRINT("Freeing in external pmem case:ENTRY");
4100 free(pPlatformEntry);
4101 pPlatformEntry = NULL;
4102 }
4103 if (pPlatformList) {
4104 DEBUG_PRINT("Freeing in external pmem case:LIST");
4105 free(pPlatformList);
4106 pPlatformList = NULL;
4107 }
4108 if (currentStatus == ERROR_STATE) {
4109 do_freeHandle_and_clean_up(true);
4110 return -1;
4111 }
4112 DEBUG_PRINT("OP PORT DISABLED!\n");
4113 return 0;
4114 }
4115
enable_output_port()4116 int enable_output_port()
4117 {
4118 unsigned int bufCnt = 0;
4119 OMX_ERRORTYPE ret = OMX_ErrorNone;
4120 DEBUG_PRINT("ENABLING OP PORT\n");
4121
4122 if (currentStatus == ERROR_STATE) {
4123 DEBUG_PRINT("ENABLING OP PORT in ERROR_STATE not allowed\n");
4124 return -1;
4125 }
4126 // Send Enable command
4127 OMX_SendCommand(dec_handle, OMX_CommandPortEnable, 1, 0);
4128 #ifndef USE_EGL_IMAGE_TEST_APP
4129 /* Allocate buffer on decoder's o/p port */
4130 portFmt.nPortIndex = 1;
4131
4132 if (anti_flickering) {
4133 ret = OMX_GetParameter(dec_handle,OMX_IndexParamPortDefinition,&portFmt);
4134 if (ret != OMX_ErrorNone) {
4135 DEBUG_PRINT_ERROR("%s: OMX_GetParameter failed: %d",__FUNCTION__, ret);
4136 return -1;
4137 }
4138 portFmt.nBufferCountActual += 1;
4139 ret = OMX_SetParameter(dec_handle,OMX_IndexParamPortDefinition,&portFmt);
4140 if (ret != OMX_ErrorNone) {
4141 DEBUG_PRINT_ERROR("%s: OMX_SetParameter failed: %d",__FUNCTION__, ret);
4142 return -1;
4143 }
4144 }
4145
4146 if (use_external_pmem_buf) {
4147 DEBUG_PRINT("Enable op port: calling use_buffer_mult_fd\n");
4148 error = use_output_buffer_multiple_fd(dec_handle,
4149 &pOutYUVBufHdrs,
4150 portFmt.nPortIndex,
4151 portFmt.nBufferSize,
4152 portFmt.nBufferCountActual);
4153 } else {
4154 error = Allocate_Buffer(dec_handle, &pOutYUVBufHdrs, portFmt.nPortIndex,
4155 portFmt.nBufferCountActual, portFmt.nBufferSize);
4156 }
4157 if (error != OMX_ErrorNone) {
4158 DEBUG_PRINT_ERROR("Error - OMX_AllocateBuffer Output buffer error\n");
4159 return -1;
4160 } else {
4161 DEBUG_PRINT("OMX_AllocateBuffer Output buffer success\n");
4162 free_op_buf_cnt = portFmt.nBufferCountActual;
4163 }
4164 #else
4165 error = use_output_buffer(dec_handle,
4166 &pOutYUVBufHdrs,
4167 portFmt.nPortIndex,
4168 portFmt.nBufferSize,
4169 portFmt.nBufferCountActual);
4170 free_op_buf_cnt = portFmt.nBufferCountActual;
4171 if (error != OMX_ErrorNone) {
4172 DEBUG_PRINT_ERROR("ERROR - OMX_UseBuffer Input buffer failed");
4173 return -1;
4174 } else {
4175 DEBUG_PRINT("OMX_UseBuffer Input buffer success\n");
4176 }
4177
4178 #endif
4179 // wait for enable event to come back
4180 wait_for_event();
4181 if (currentStatus == ERROR_STATE) {
4182 do_freeHandle_and_clean_up(true);
4183 return -1;
4184 }
4185 if (pOutYUVBufHdrs == NULL) {
4186 DEBUG_PRINT_ERROR("Error - pOutYUVBufHdrs is NULL\n");
4187 return -1;
4188 }
4189 for (bufCnt=0; bufCnt < portFmt.nBufferCountActual; ++bufCnt) {
4190 DEBUG_PRINT("OMX_FillThisBuffer on output buf no.%d\n",bufCnt);
4191 if (pOutYUVBufHdrs[bufCnt] == NULL) {
4192 DEBUG_PRINT_ERROR("Error - pOutYUVBufHdrs[%d] is NULL\n", bufCnt);
4193 return -1;
4194 }
4195 pOutYUVBufHdrs[bufCnt]->nOutputPortIndex = 1;
4196 pOutYUVBufHdrs[bufCnt]->nFlags &= ~OMX_BUFFERFLAG_EOS;
4197 ret = OMX_FillThisBuffer(dec_handle, pOutYUVBufHdrs[bufCnt]);
4198 if (OMX_ErrorNone != ret) {
4199 DEBUG_PRINT_ERROR("ERROR - OMX_FillThisBuffer failed with result %d\n", ret);
4200 } else {
4201 DEBUG_PRINT("OMX_FillThisBuffer success!\n");
4202 free_op_buf_cnt--;
4203 }
4204 }
4205 DEBUG_PRINT("OP PORT ENABLED!\n");
4206 return 0;
4207 }
4208
output_port_reconfig()4209 int output_port_reconfig()
4210 {
4211 DEBUG_PRINT("PORT_SETTING_CHANGE_STATE\n");
4212 if (disable_output_port() != 0)
4213 return -1;
4214
4215 /* Port for which the Client needs to obtain info */
4216 portFmt.nPortIndex = 1;
4217 OMX_GetParameter(dec_handle,OMX_IndexParamPortDefinition,&portFmt);
4218 DEBUG_PRINT("Min Buffer Count=%d", portFmt.nBufferCountMin);
4219 DEBUG_PRINT("Buffer Size=%d", portFmt.nBufferSize);
4220 if (OMX_DirOutput != portFmt.eDir) {
4221 DEBUG_PRINT_ERROR("Error - Expect Output Port\n");
4222 return -1;
4223 }
4224 height = portFmt.format.video.nFrameHeight;
4225 width = portFmt.format.video.nFrameWidth;
4226 stride = portFmt.format.video.nStride;
4227 sliceheight = portFmt.format.video.nSliceHeight;
4228
4229 crop_rect.nWidth = width;
4230 crop_rect.nHeight = height;
4231
4232 if (displayYuv == 2) {
4233 DEBUG_PRINT("Reconfiguration at middle of playback...");
4234 close_display();
4235 if (open_display() != 0) {
4236 printf("\n Error opening display! Video won't be displayed...");
4237 displayYuv = 0;
4238 }
4239 }
4240
4241 if (displayYuv)
4242 overlay_set();
4243
4244 if (enable_output_port() != 0)
4245 return -1;
4246 DEBUG_PRINT("PORT_SETTING_CHANGE DONE!\n");
4247 return 0;
4248 }
4249
free_output_buffers()4250 void free_output_buffers()
4251 {
4252 int index = 0;
4253 OMX_BUFFERHEADERTYPE *pBuffer = (OMX_BUFFERHEADERTYPE *)pop(fbd_queue);
4254 while (pBuffer) {
4255 DEBUG_PRINT("\n pOutYUVBufHdrs %p p_eglHeaders %p output_use_buffer %d",
4256 pOutYUVBufHdrs,p_eglHeaders,output_use_buffer);
4257 if (pOutYUVBufHdrs && p_eglHeaders && output_use_buffer) {
4258 index = pBuffer - pOutYUVBufHdrs[0];
4259 DEBUG_PRINT("\n Index of free buffer %d",index);
4260 DEBUG_PRINT("\n Address freed %p size freed %d",pBuffer->pBuffer,
4261 pBuffer->nAllocLen);
4262 munmap((void *)use_buf_virt_addr[index],pBuffer->nAllocLen);
4263 if (p_eglHeaders[index]) {
4264 close(p_eglHeaders[index]->pmem_fd);
4265 free(p_eglHeaders[index]);
4266 p_eglHeaders[index] = NULL;
4267 }
4268 }
4269
4270 if (pOutYUVBufHdrs && use_external_pmem_buf) {
4271 index = pBuffer - pOutYUVBufHdrs[0];
4272 DEBUG_PRINT("\n Address freed %p size freed %d,virt=0x%x,pmem_fd=0x%x",
4273 pBuffer->pBuffer,
4274 pBuffer->nAllocLen,
4275 use_buf_virt_addr[index],
4276 pPMEMInfo[index].pmem_fd);
4277 munmap((void *)use_buf_virt_addr[index],pBuffer->nAllocLen);
4278 getFreePmem();
4279 use_buf_virt_addr[index] = -1;
4280 if (&pPMEMInfo[index]) {
4281 close(pPMEMInfo[index].pmem_fd);
4282 pPMEMInfo[index].pmem_fd = -1;
4283 }
4284 }
4285 DEBUG_PRINT("\n Free output buffer");
4286 OMX_FreeBuffer(dec_handle, 1, pBuffer);
4287 pBuffer = (OMX_BUFFERHEADERTYPE *)pop(fbd_queue);
4288 }
4289 }
4290
4291 #ifndef USE_ION
align_pmem_buffers(int pmem_fd,OMX_U32 buffer_size,OMX_U32 alignment)4292 static bool align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
4293 OMX_U32 alignment)
4294 {
4295 struct pmem_allocation allocation;
4296 allocation.size = buffer_size;
4297 allocation.align = clip2(alignment);
4298
4299 if (allocation.align < 4096) {
4300 allocation.align = 4096;
4301 }
4302 if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) {
4303 DEBUG_PRINT_ERROR("\n Aligment failed with pmem driver");
4304 return false;
4305 }
4306 return true;
4307 }
4308 #endif
4309
open_display()4310 int open_display()
4311 {
4312 #ifdef _ANDROID_
4313 DEBUG_PRINT("\n Opening /dev/graphics/fb0");
4314 fb_fd = open("/dev/graphics/fb0", O_RDWR);
4315 #else
4316 DEBUG_PRINT("\n Opening /dev/fb0");
4317 fb_fd = open("/dev/fb0", O_RDWR);
4318 #endif
4319 if (fb_fd < 0) {
4320 printf("[omx_vdec_test] - ERROR - can't open framebuffer!\n");
4321 return -1;
4322 }
4323
4324 DEBUG_PRINT("\n fb_fd = %d", fb_fd);
4325 if (ioctl(fb_fd, FBIOGET_FSCREENINFO, &finfo) < 0) {
4326 printf("[omx_vdec_test] - ERROR - can't retrieve fscreenInfo!\n");
4327 close(fb_fd);
4328 return -1;
4329 }
4330 if (ioctl(fb_fd, FBIOGET_VSCREENINFO, &vinfo) < 0) {
4331 printf("[omx_vdec_test] - ERROR - can't retrieve vscreenInfo!\n");
4332 close(fb_fd);
4333 return -1;
4334 }
4335 printf("Display xres = %d, yres = %d \n", vinfo.xres, vinfo.yres);
4336 return 0;
4337 }
4338
close_display()4339 void close_display()
4340 {
4341 overlay_unset();
4342 overlay_vsync_ctrl(OMX_FALSE);
4343 close(fb_fd);
4344 fb_fd = -1;
4345 }
4346
getFreePmem()4347 void getFreePmem()
4348 {
4349 #ifndef USE_ION
4350 int ret = -1;
4351 /*Open pmem device and query free pmem*/
4352 int pmem_fd = open (PMEM_DEVICE,O_RDWR);
4353
4354 if (pmem_fd < 0) {
4355 ALOGE("Unable to open pmem device");
4356 return;
4357 }
4358 struct pmem_freespace fs;
4359 ret = ioctl(pmem_fd, PMEM_GET_FREE_SPACE, &fs);
4360 if (ret) {
4361 ALOGE("IOCTL to query pmem free space failed");
4362 goto freespace_query_failed;
4363 }
4364 ALOGE("Available free space %lx largest chunk %lx\n", fs.total, fs.largest);
4365 freespace_query_failed:
4366 close(pmem_fd);
4367 #endif
4368 }
4369