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