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