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