1/*--------------------------------------------------------------------------
2Copyright (c) 2010 - 2014, The Linux Foundation. All rights reserved.
3
4Redistribution and use in source and binary forms, with or without
5modification, are permitted provided that the following conditions are met:
6    * Redistributions of source code must retain the above copyright
7      notice, this list of conditions and the following disclaimer.
8    * Redistributions in binary form must reproduce the above copyright
9      notice, this list of conditions and the following disclaimer in the
10      documentation and/or other materials provided with the distribution.
11    * Neither the name of 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
16THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27--------------------------------------------------------------------------*/
28/*
29    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
55extern "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"
80extern "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
107static int previous_vc1_au = 0;
108#define CONFIG_VERSION_SIZE(param) \
109    param.nVersion.nVersion = CURRENT_OMX_SPEC_VERSION;\
110param.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_
135using namespace android;
136#endif
137
138#ifdef _MSM8974_
139typedef unsigned short int uint16;
140const uint16 CRC_INIT = 0xFFFF ;
141
142const 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
179static 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 */
187size_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
208uint16 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
240typedef 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
256typedef 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
289typedef enum {
290    GOOD_STATE = 0,
291    PORT_SETTING_CHANGE_STATE,
292    ERROR_STATE
293} test_status;
294
295typedef 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
302struct temp_egl {
303    int pmem_fd;
304    int offset;
305};
306
307static int (*Read_Buffer)(OMX_BUFFERHEADERTYPE  *pBufHdr );
308
309int inputBufferFileFd;
310
311FILE * outputBufferFile;
312#ifdef _MSM8974_
313FILE * crcFile;
314#endif
315FILE * seqFile;
316int takeYuvLog = 0;
317int displayYuv = 0;
318int displayWindow = 0;
319int realtime_display = 0;
320int num_frames_to_decode = 0;
321int thumbnailMode = 0;
322
323Queue *etb_queue = NULL;
324Queue *fbd_queue = NULL;
325
326pthread_t ebd_thread_id;
327pthread_t fbd_thread_id;
328void* ebd_thread(void*);
329void* fbd_thread(void*);
330
331pthread_mutex_t etb_lock;
332pthread_mutex_t fbd_lock;
333pthread_mutex_t lock;
334pthread_cond_t cond;
335pthread_mutex_t eos_lock;
336pthread_cond_t eos_cond;
337pthread_mutex_t enable_lock;
338
339sem_t etb_sem;
340sem_t fbd_sem;
341sem_t seq_sem;
342sem_t in_flush_sem, out_flush_sem;
343
344OMX_PARAM_PORTDEFINITIONTYPE portFmt;
345OMX_PORT_PARAM_TYPE portParam;
346OMX_ERRORTYPE error;
347OMX_COLOR_FORMATTYPE color_fmt;
348static bool input_use_buffer = false,output_use_buffer = false;
349QOMX_VIDEO_DECODER_PICTURE_ORDER picture_order;
350
351#ifdef MAX_RES_1080P
352unsigned int color_fmt_type = 1;
353#else
354unsigned 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
361static int fb_fd = -1;
362static struct fb_var_screeninfo vinfo;
363static struct fb_fix_screeninfo finfo;
364static struct mdp_overlay overlay, *overlayp;
365static struct msmfb_overlay_data ov_front;
366static int vid_buf_front_id;
367static char tempbuf[16];
368int overlay_fb(struct OMX_BUFFERHEADERTYPE *pBufHdr);
369void overlay_set();
370void overlay_unset();
371void render_fb(struct OMX_BUFFERHEADERTYPE *pBufHdr);
372int disable_output_port();
373int enable_output_port();
374int output_port_reconfig();
375void free_output_buffers();
376int open_display();
377void close_display();
378/************************************************************************/
379/*              GLOBAL INIT                 */
380/************************************************************************/
381int input_buf_cnt = 0;
382int height =0, width =0;
383int sliceheight = 0, stride = 0;
384int used_ip_buf_cnt = 0;
385unsigned free_op_buf_cnt = 0;
386volatile int event_is_done = 0;
387int ebd_cnt= 0, fbd_cnt = 0;
388int bInputEosReached = 0;
389int bOutputEosReached = 0;
390char in_filename[512];
391#ifdef _MSM8974_
392char crclogname[512];
393#endif
394char seq_file_name[512];
395unsigned char seq_enabled = 0;
396bool anti_flickering = true;
397unsigned char flush_input_progress = 0, flush_output_progress = 0;
398unsigned cmd_data = ~(unsigned)0, etb_count = 0;
399
400char curr_seq_command[100];
401OMX_S64 timeStampLfile = 0;
402int fps = 30;
403unsigned int timestampInterval = 33333;
404codec_format  codec_format_option;
405file_type     file_type_option;
406freeHandle_test freeHandle_option;
407int nalSize = 0;
408int sent_disabled = 0;
409int waitForPortSettingsChanged = 1;
410test_status currentStatus = GOOD_STATE;
411struct timeval t_start = {0, 0}, t_end = {0, 0};
412
413//* OMX Spec Version supported by the wrappers. Version = 1.1 */
414const OMX_U32 CURRENT_OMX_SPEC_VERSION = 0x00000101;
415OMX_COMPONENTTYPE* dec_handle = 0;
416
417OMX_BUFFERHEADERTYPE  **pInputBufHdrs = NULL;
418OMX_BUFFERHEADERTYPE  **pOutYUVBufHdrs= NULL;
419
420static OMX_BOOL use_external_pmem_buf = OMX_FALSE;
421
422int rcv_v1=0;
423static struct temp_egl **p_eglHeaders = NULL;
424static unsigned use_buf_virt_addr[32];
425
426OMX_QCOM_PLATFORM_PRIVATE_LIST      *pPlatformList = NULL;
427OMX_QCOM_PLATFORM_PRIVATE_ENTRY     *pPlatformEntry = NULL;
428OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
429OMX_CONFIG_RECTTYPE crop_rect = {0, {{0, 0, 0, 0}}, 0, 0, 0, 0, 0};
430
431static 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/************************************************************************/
440int Init_Decoder();
441int Play_Decoder();
442int run_tests();
443
444/**************************************************************************/
445/*              STATIC DECLARATIONS                       */
446/**************************************************************************/
447static int video_playback_count = 1;
448static int open_video_file ();
449static int Read_Buffer_From_DAT_File(OMX_BUFFERHEADERTYPE  *pBufHdr );
450static int Read_Buffer_From_H264_Start_Code_File(OMX_BUFFERHEADERTYPE  *pBufHdr);
451static int Read_Buffer_ArbitraryBytes(OMX_BUFFERHEADERTYPE  *pBufHdr);
452static int Read_Buffer_From_Vop_Start_Code_File(OMX_BUFFERHEADERTYPE  *pBufHdr);
453static int Read_Buffer_From_Mpeg2_Start_Code(OMX_BUFFERHEADERTYPE  *pBufHdr);
454static int Read_Buffer_From_Size_Nal(OMX_BUFFERHEADERTYPE  *pBufHdr);
455static int Read_Buffer_From_RCV_File_Seq_Layer(OMX_BUFFERHEADERTYPE  *pBufHdr);
456static int Read_Buffer_From_RCV_File(OMX_BUFFERHEADERTYPE  *pBufHdr);
457#ifdef _MSM8974_
458static int Read_Buffer_From_VP8_File(OMX_BUFFERHEADERTYPE  *pBufHdr);
459static int Read_Buffer_From_MVC_File(OMX_BUFFERHEADERTYPE  *pBufHdr);
460#endif
461static int Read_Buffer_From_VC1_File(OMX_BUFFERHEADERTYPE  *pBufHdr);
462static int Read_Buffer_From_DivX_4_5_6_File(OMX_BUFFERHEADERTYPE  *pBufHdr);
463static int Read_Buffer_From_DivX_311_File(OMX_BUFFERHEADERTYPE  *pBufHdr);
464
465static OMX_ERRORTYPE Allocate_Buffer ( OMX_COMPONENTTYPE *dec_handle,
466        OMX_BUFFERHEADERTYPE  ***pBufHdrs,
467        OMX_U32 nPortIndex,
468        long bufCntMin, long bufSize);
469
470static 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
476static 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
482static 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
488static 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);
493static OMX_ERRORTYPE EmptyBufferDone(OMX_IN OMX_HANDLETYPE hComponent,
494        OMX_IN OMX_PTR pAppData,
495        OMX_IN OMX_BUFFERHEADERTYPE* pBuffer);
496static OMX_ERRORTYPE FillBufferDone(OMX_OUT OMX_HANDLETYPE hComponent,
497        OMX_OUT OMX_PTR pAppData,
498        OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer);
499
500static void do_freeHandle_and_clean_up(bool isDueToError);
501
502#ifndef USE_ION
503static bool align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
504        OMX_U32 alignment);
505#endif
506void getFreePmem();
507static int overlay_vsync_ctrl(int enable);
508
509static  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}
519void 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
531void 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}
540int 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
553int 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
642void 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}
687void* 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
734void* 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
1108OMX_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
1236OMX_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
1264OMX_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
1294int 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
1688int 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
1808int 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
1974int 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
2504static 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
2529static 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
2561static 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
2622static 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}
2699static 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
2826static 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
2873static 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
2947static 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
2970static 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}
3016static 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
3099static 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
3137static 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
3201static 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
3270static 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
3364static 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
3501static 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_
3549static 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
3592static 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
3659static 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
3695void 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
3706int 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
3743static 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
3756void 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
3864int 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
3916void 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
3923void 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
4079int 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
4116int 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
4209int 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
4250void 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
4292static 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
4310int 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
4339void close_display()
4340{
4341    overlay_unset();
4342    overlay_vsync_ctrl(OMX_FALSE);
4343    close(fb_fd);
4344    fb_fd = -1;
4345}
4346
4347void 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);
4365freespace_query_failed:
4366    close(pmem_fd);
4367#endif
4368}
4369