OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / hardware / qcom / media / mm-video / vidc / vdec / test / omx_vdec_test.cpp
1 /*--------------------------------------------------------------------------
2 Copyright (c) 2010, Code Aurora Forum. All rights reserved.
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are met:
6     * Redistributions of source code must retain the above copyright
7       notice, this list of conditions and the following disclaimer.
8     * Redistributions in binary form must reproduce the above copyright
9       notice, this list of conditions and the following disclaimer in the
10       documentation and/or other materials provided with the distribution.
11     * Neither the name of 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
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 --------------------------------------------------------------------------*/
28 /*
29     An Open max test application ....
30 */
31
32 #define LOG_TAG "OMX-VDEC-TEST"
33
34 #include <stdio.h>
35 #include <string.h>
36 #include <stdlib.h>
37 #include <unistd.h>
38 #include <fcntl.h>
39 #include <sys/types.h>
40 #include <sys/mman.h>
41 #include <time.h>
42 #include <sys/ioctl.h>
43 #include <errno.h>
44 #include <pthread.h>
45 #include <semaphore.h>
46 #include "OMX_QCOMExtns.h"
47
48 #ifdef _ANDROID_
49 #include <binder/MemoryHeapBase.h>
50
51 extern "C"{
52 #include<utils/Log.h>
53 }
54 #define DEBUG_PRINT
55 #define DEBUG_PRINT_ERROR
56
57 #else
58 #define DEBUG_PRINT printf
59 #define DEBUG_PRINT_ERROR printf
60 #endif /* _ANDROID_ */
61
62 #include "OMX_Core.h"
63 #include "OMX_Component.h"
64 #include "OMX_QCOMExtns.h"
65 extern "C" {
66 #include "queue.h"
67 }
68
69 #include <linux/msm_mdp.h>
70 #include <linux/fb.h>
71 //#include "qutility.h"
72
73 #define DEBUG_PRINT(...) printf(__VA_ARGS__)
74 #define DEBUG_PRINT_ERROR(...) printf(__VA_ARGS__)
75 #define DEBUG_PRINT_LOW(...) printf(__VA_ARGS__)
76
77 /************************************************************************/
78 /*              #DEFINES                            */
79 /************************************************************************/
80 #define DELAY 66
81 #define false 0
82 #define true 1
83 #define VOP_START_CODE 0x000001B6
84 #define SHORT_HEADER_START_CODE 0x00008000
85 #define VC1_START_CODE  0x00000100
86 #define VC1_FRAME_START_CODE  0x0000010D
87 #define NUMBER_OF_ARBITRARYBYTES_READ  (4 * 1024)
88 #define VC1_SEQ_LAYER_SIZE_WITHOUT_STRUCTC 32
89 #define VC1_SEQ_LAYER_SIZE_V1_WITHOUT_STRUCTC 16
90
91 #define CONFIG_VERSION_SIZE(param) \
92     param.nVersion.nVersion = CURRENT_OMX_SPEC_VERSION;\
93     param.nSize = sizeof(param);
94
95 #define FAILED(result) (result != OMX_ErrorNone)
96
97 #define SUCCEEDED(result) (result == OMX_ErrorNone)
98 #define SWAPBYTES(ptrA, ptrB) { char t = *ptrA; *ptrA = *ptrB; *ptrB = t;}
99 #define SIZE_NAL_FIELD_MAX  4
100 #define MDP_DEINTERLACE 0x80000000
101
102 /************************************************************************/
103 /*              GLOBAL DECLARATIONS                     */
104 /************************************************************************/
105 #ifdef _ANDROID_
106 using namespace android;
107 #endif
108
109 typedef enum {
110   CODEC_FORMAT_H264 = 1,
111   CODEC_FORMAT_MP4,
112   CODEC_FORMAT_H263,
113   CODEC_FORMAT_VC1,
114   CODEC_FORMAT_MAX = CODEC_FORMAT_VC1
115 } codec_format;
116
117 typedef enum {
118   FILE_TYPE_DAT_PER_AU = 1,
119   FILE_TYPE_ARBITRARY_BYTES,
120   FILE_TYPE_COMMON_CODEC_MAX,
121
122   FILE_TYPE_START_OF_H264_SPECIFIC = 10,
123   FILE_TYPE_264_NAL_SIZE_LENGTH = FILE_TYPE_START_OF_H264_SPECIFIC,
124
125   FILE_TYPE_START_OF_MP4_SPECIFIC = 20,
126   FILE_TYPE_PICTURE_START_CODE = FILE_TYPE_START_OF_MP4_SPECIFIC,
127
128   FILE_TYPE_START_OF_VC1_SPECIFIC = 30,
129   FILE_TYPE_RCV = FILE_TYPE_START_OF_VC1_SPECIFIC,
130   FILE_TYPE_VC1
131 } file_type;
132
133 typedef enum {
134   GOOD_STATE = 0,
135   PORT_SETTING_CHANGE_STATE,
136   ERROR_STATE,
137   INVALID_STATE
138 } test_status;
139
140 typedef enum {
141   FREE_HANDLE_AT_LOADED = 1,
142   FREE_HANDLE_AT_IDLE,
143   FREE_HANDLE_AT_EXECUTING,
144   FREE_HANDLE_AT_PAUSE
145 } freeHandle_test;
146
147 static int (*Read_Buffer)(OMX_BUFFERHEADERTYPE  *pBufHdr );
148
149 FILE * inputBufferFile;
150 FILE * outputBufferFile;
151 FILE * seqFile;
152 int takeYuvLog = 0;
153 int displayWindow = 0;
154 int realtime_display = 0;
155 struct timeval t_avsync={0,0};
156
157 Queue *etb_queue = NULL;
158 Queue *fbd_queue = NULL;
159
160 pthread_t ebd_thread_id;
161 pthread_t fbd_thread_id;
162 void* ebd_thread(void*);
163 void* fbd_thread(void*);
164
165 pthread_mutex_t etb_lock;
166 pthread_mutex_t fbd_lock;
167 pthread_mutex_t lock;
168 pthread_cond_t cond;
169 pthread_mutex_t elock;
170 pthread_cond_t econd;
171 pthread_cond_t fcond;
172 pthread_mutex_t eos_lock;
173 pthread_cond_t eos_cond;
174
175 sem_t etb_sem;
176 sem_t fbd_sem;
177 sem_t seq_sem;
178 sem_t in_flush_sem, out_flush_sem;
179
180 OMX_PARAM_PORTDEFINITIONTYPE portFmt;
181 OMX_PORT_PARAM_TYPE portParam;
182 OMX_ERRORTYPE error;
183
184 #define CLR_KEY  0xe8fd
185 #define COLOR_BLACK_RGBA_8888 0x00000000
186 #define FRAMEBUFFER_32
187
188 static int fb_fd = -1;
189 static struct fb_var_screeninfo vinfo;
190 static struct fb_fix_screeninfo finfo;
191 static int vid_buf_front_id;
192 int overlay_fb(struct OMX_BUFFERHEADERTYPE *pBufHdr);
193 void overlay_set();
194 void overlay_unset();
195 void render_fb(struct OMX_BUFFERHEADERTYPE *pBufHdr);
196
197 /************************************************************************/
198 /*              GLOBAL INIT                 */
199 /************************************************************************/
200 unsigned int input_buf_cnt = 0;
201 int height =0, width =0;
202 int sliceheight = 0, stride = 0;
203 int used_ip_buf_cnt = 0;
204 volatile int event_is_done = 0;
205 int ebd_cnt, fbd_cnt;
206 int bInputEosReached = 0;
207 int bOutputEosReached = 0;
208 char in_filename[512];
209 char seq_file_name[512];
210 unsigned char seq_enabled = 0, flush_in_progress = 0;
211 unsigned int cmd_data = 0, etb_count = 0;;
212
213 char curr_seq_command[100];
214 int timeStampLfile = 0;
215 int timestampInterval = 33333;
216 codec_format  codec_format_option;
217 file_type     file_type_option;
218 freeHandle_test freeHandle_option;
219 int nalSize;
220 int sent_disabled = 0;
221 int waitForPortSettingsChanged = 1;
222 test_status currentStatus = GOOD_STATE;
223
224 //* OMX Spec Version supported by the wrappers. Version = 1.1 */
225 const OMX_U32 CURRENT_OMX_SPEC_VERSION = 0x00000101;
226 OMX_COMPONENTTYPE* dec_handle = 0;
227
228 OMX_BUFFERHEADERTYPE  **pInputBufHdrs = NULL;
229 OMX_BUFFERHEADERTYPE  **pOutYUVBufHdrs= NULL;
230
231 int rcv_v1=0;
232
233 /* Performance related variable*/
234 //QPERF_INIT(render_fb);
235 //QPERF_INIT(client_decode);
236
237 /************************************************************************/
238 /*              GLOBAL FUNC DECL                        */
239 /************************************************************************/
240 int Init_Decoder();
241 int Play_Decoder();
242 int run_tests();
243
244 /**************************************************************************/
245 /*              STATIC DECLARATIONS                       */
246 /**************************************************************************/
247 static int video_playback_count = 1;
248 static int open_video_file ();
249 static int Read_Buffer_From_DAT_File(OMX_BUFFERHEADERTYPE  *pBufHdr );
250 static int Read_Buffer_ArbitraryBytes(OMX_BUFFERHEADERTYPE  *pBufHdr);
251 static int Read_Buffer_From_Vop_Start_Code_File(OMX_BUFFERHEADERTYPE  *pBufHdr);
252 static int Read_Buffer_From_Size_Nal(OMX_BUFFERHEADERTYPE  *pBufHdr);
253 static int Read_Buffer_From_RCV_File_Seq_Layer(OMX_BUFFERHEADERTYPE  *pBufHdr);
254 static int Read_Buffer_From_RCV_File(OMX_BUFFERHEADERTYPE  *pBufHdr);
255 static int Read_Buffer_From_VC1_File(OMX_BUFFERHEADERTYPE  *pBufHdr);
256
257 static OMX_ERRORTYPE Allocate_Buffer ( OMX_COMPONENTTYPE *dec_handle,
258                                        OMX_BUFFERHEADERTYPE  ***pBufHdrs,
259                                        OMX_U32 nPortIndex,
260                                        long bufCntMin, long bufSize);
261
262
263 static OMX_ERRORTYPE EventHandler(OMX_IN OMX_HANDLETYPE hComponent,
264                                   OMX_IN OMX_PTR pAppData,
265                                   OMX_IN OMX_EVENTTYPE eEvent,
266                                   OMX_IN OMX_U32 nData1, OMX_IN OMX_U32 nData2,
267                                   OMX_IN OMX_PTR pEventData);
268 static OMX_ERRORTYPE EmptyBufferDone(OMX_IN OMX_HANDLETYPE hComponent,
269                                      OMX_IN OMX_PTR pAppData,
270                                      OMX_IN OMX_BUFFERHEADERTYPE* pBuffer);
271 static OMX_ERRORTYPE FillBufferDone(OMX_OUT OMX_HANDLETYPE hComponent,
272                                     OMX_OUT OMX_PTR pAppData,
273                                     OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer);
274
275 static void do_freeHandle_and_clean_up(bool isDueToError);
276
277 /*static usecs_t get_time(void)
278 {
279     struct timeval tv;
280     gettimeofday(&tv, 0);
281     return ((usecs_t)tv.tv_usec) +
282         (((usecs_t)tv.tv_sec) * ((usecs_t)1000000));
283 }*/
284
285
286 void wait_for_event(void)
287 {
288     DEBUG_PRINT("Waiting for event\n");
289     pthread_mutex_lock(&lock);
290     while (event_is_done == 0) {
291         pthread_cond_wait(&cond, &lock);
292     }
293     event_is_done = 0;
294     pthread_mutex_unlock(&lock);
295     DEBUG_PRINT("Running .... get the event\n");
296 }
297
298 void event_complete(void )
299 {
300     pthread_mutex_lock(&lock);
301     if (event_is_done == 0) {
302         event_is_done = 1;
303         pthread_cond_broadcast(&cond);
304     }
305     pthread_mutex_unlock(&lock);
306 }
307 int get_next_command(FILE *seq_file)
308 {
309     int i = -1;
310     do{
311         i++;
312         if(fread(&curr_seq_command[i], 1, 1, seq_file) != 1)
313             return -1;
314     }while(curr_seq_command[i] != '\n');
315     curr_seq_command[i] = 0;
316     printf("\n cmd_str = %s", curr_seq_command);
317     return 0;
318 }
319
320 void process_current_command(const char *seq_command)
321 {
322     char *data_str = NULL;
323     unsigned int data = 0, bufCnt = 0, i = 0;
324     int frameSize;
325     OMX_ERRORTYPE ret;
326
327     if(strstr(seq_command, "pause") == seq_command)
328     {
329         printf("\n\n $$$$$   PAUSE    $$$$$");
330         data_str = (char*)seq_command + strlen("pause") + 1;
331         data = atoi(data_str);
332         printf("\n After frame number %u", data);
333         cmd_data = data;
334         sem_wait(&seq_sem);
335         printf("\n Sending PAUSE cmd to OMX compt");
336         OMX_SendCommand(dec_handle, OMX_CommandStateSet, OMX_StatePause,0);
337         wait_for_event();
338         printf("\n EventHandler for PAUSE DONE");
339     }
340     else if(strstr(seq_command, "sleep") == seq_command)
341     {
342         printf("\n\n $$$$$   SLEEP    $$$$$");
343         data_str = (char*)seq_command + strlen("sleep") + 1;
344         data = atoi(data_str);
345         printf("\n Sleep Time = %u ms", data);
346         usleep(data*1000);
347     }
348     else if(strstr(seq_command, "resume") == seq_command)
349     {
350         printf("\n\n $$$$$   RESUME    $$$$$");
351         printf("\n Immediate effect");
352         printf("\n Sending PAUSE cmd to OMX compt");
353         OMX_SendCommand(dec_handle, OMX_CommandStateSet, OMX_StateExecuting,0);
354         wait_for_event();
355         printf("\n EventHandler for RESUME DONE");
356     }
357     else if(strstr(seq_command, "flush") == seq_command)
358     {
359         printf("\n\n $$$$$   FLUSH    $$$$$");
360         data_str = (char*)seq_command + strlen("flush") + 1;
361         data = atoi(data_str);
362         printf("\n After frame number %u", data);
363         cmd_data = data;
364         sem_wait(&seq_sem);
365         printf("\n Sending FLUSH cmd to OMX compt");
366         flush_in_progress = 1;
367         OMX_SendCommand(dec_handle, OMX_CommandFlush, OMX_ALL, 0);
368         wait_for_event();
369         flush_in_progress = 0;
370         printf("\n EventHandler for FLUSH DONE");
371         printf("\n Post EBD_thread flush sem");
372         sem_post(&in_flush_sem);
373         printf("\n Post FBD_thread flush sem");
374         sem_post(&out_flush_sem);
375     }
376     else
377     {
378         printf("\n\n $$$$$   INVALID CMD    $$$$$");
379         printf("\n seq_command[%s] is invalid", seq_command);
380         seq_enabled = 0;
381     }
382 }
383
384 void* ebd_thread(void* pArg)
385 {
386   while(currentStatus != INVALID_STATE)
387   {
388     int readBytes =0;
389     OMX_BUFFERHEADERTYPE* pBuffer = NULL;
390
391     if(flush_in_progress)
392     {
393         printf("\n EBD_thread flush wait start");
394         sem_wait(&in_flush_sem);
395         printf("\n EBD_thread flush wait complete");
396     }
397
398     sem_wait(&etb_sem);
399     pthread_mutex_lock(&etb_lock);
400     pBuffer = (OMX_BUFFERHEADERTYPE *) pop(etb_queue);
401     pthread_mutex_unlock(&etb_lock);
402     if(pBuffer == NULL)
403     {
404       DEBUG_PRINT_ERROR("Error - No etb pBuffer to dequeue\n");
405       continue;
406     }
407
408     pBuffer->nOffset = 0;
409     if((readBytes = Read_Buffer(pBuffer)) > 0) {
410         pBuffer->nFilledLen = readBytes;
411         OMX_EmptyThisBuffer(dec_handle,pBuffer);
412         etb_count++;
413         if(cmd_data == etb_count)
414         {
415             sem_post(&seq_sem);
416             printf("\n Posted seq_sem");
417         }
418     }
419     else
420     {
421         pBuffer->nFlags |= OMX_BUFFERFLAG_EOS;
422         bInputEosReached = true;
423         pBuffer->nFilledLen = readBytes;
424         OMX_EmptyThisBuffer(dec_handle,pBuffer);
425         DEBUG_PRINT("EBD::Either EOS or Some Error while reading file\n");
426         etb_count++;
427         if(cmd_data == etb_count)
428         {
429             sem_post(&seq_sem);
430             printf("\n Posted seq_sem");
431         }
432         break;
433     }
434   }
435   return NULL;
436 }
437
438 void* fbd_thread(void* pArg)
439 {
440   while(currentStatus != INVALID_STATE)
441   {
442     long current_avsync_time = 0, delta_time = 0;
443     int canDisplay = 1;
444     static int contigous_drop_frame = 0;
445     static long base_avsync_time = 0;
446     static long base_timestamp = 0;
447     long lipsync_time = 250000;
448     int bytes_written = 0;
449     OMX_BUFFERHEADERTYPE *pBuffer;
450
451     if(flush_in_progress)
452     {
453         printf("\n FBD_thread flush wait start");
454         sem_wait(&out_flush_sem);
455         printf("\n FBD_thread flush wait complete");
456     }
457
458     sem_wait(&fbd_sem);
459     DEBUG_PRINT("Inside %s fbd_cnt[%d] \n", __FUNCTION__, fbd_cnt);
460
461     fbd_cnt++;
462     pthread_mutex_lock(&fbd_lock);
463     pBuffer = (OMX_BUFFERHEADERTYPE *) pop(fbd_queue);
464     pthread_mutex_unlock(&fbd_lock);
465     if (pBuffer == NULL)
466     {
467       DEBUG_PRINT("Error - No pBuffer to dequeue\n");
468       continue;
469     }
470
471     /*********************************************
472     Write the output of the decoder to the file.
473     *********************************************/
474
475     if (sent_disabled)
476     {
477        DEBUG_PRINT("Ignoring FillBufferDone\n");
478        continue;
479     }
480
481     if (realtime_display)
482     {
483       if(!gettimeofday(&t_avsync,NULL))
484       {
485          current_avsync_time =(t_avsync.tv_sec*1000000)+t_avsync.tv_usec;
486       }
487
488       if (base_avsync_time != 0)
489       {
490         pthread_mutex_lock(&fbd_lock);
491         delta_time = (current_avsync_time - base_avsync_time) - ((long)pBuffer->nTimeStamp - base_timestamp);
492         if (delta_time < 0 )
493         {
494           DEBUG_PRINT_ERROR("Sleep %d us. AV Sync time is left behind\n",
495                  -delta_time);
496           usleep(-delta_time);
497           canDisplay = 1;
498         }
499         else if ((delta_time>lipsync_time) && (contigous_drop_frame < 6))
500         {
501           DEBUG_PRINT_ERROR("Error - Drop the frame at the renderer. Video frame with ts %lu usec behind by %ld usec"
502                          ", pBuffer->nFilledLen %u\n",
503                         (unsigned long)pBuffer->nTimeStamp, delta_time, pBuffer->nFilledLen);
504           canDisplay = 0;
505           contigous_drop_frame++;
506         }
507         else
508     {
509           canDisplay = 1;
510         }
511         pthread_mutex_unlock(&fbd_lock);
512       }
513       else
514       {
515         base_avsync_time = current_avsync_time;
516         base_timestamp = (long)pBuffer->nTimeStamp;
517       }
518     }
519
520     if (!flush_in_progress && takeYuvLog) {
521         pthread_mutex_lock(&fbd_lock);
522         bytes_written = fwrite((const char *)pBuffer->pBuffer,
523                                 pBuffer->nFilledLen,1,outputBufferFile);
524         pthread_mutex_unlock(&fbd_lock);
525         if (bytes_written < 0) {
526             DEBUG_PRINT("\nFillBufferDone: Failed to write to the file\n");
527         }
528         else {
529             DEBUG_PRINT("\nFillBufferDone: Wrote %d YUV bytes to the file\n",
530                           bytes_written);
531         }
532     }
533
534     /********************************************************************/
535     /* De-Initializing the open max and relasing the buffers and */
536     /* closing the files.*/
537     /********************************************************************/
538     if (pBuffer->nFlags & OMX_BUFFERFLAG_EOS ) {
539       DEBUG_PRINT("***************************************************\n");
540       DEBUG_PRINT("FillBufferDone: End Of Stream Reached\n");
541       DEBUG_PRINT("***************************************************\n");
542       pthread_mutex_lock(&eos_lock);
543       bOutputEosReached = true;
544       pthread_cond_broadcast(&eos_cond);
545       pthread_mutex_unlock(&eos_lock);
546       //QPERF_END(client_decode);
547       //QPERF_SET_ITERATION(client_decode, fbd_cnt);
548       DEBUG_PRINT("***************************************************\n");
549       DEBUG_PRINT("FBD_THREAD bOutputEosReached %d\n",bOutputEosReached);
550       break;
551     }
552     OMX_FillThisBuffer(dec_handle, pBuffer);
553   }
554   return NULL;
555 }
556
557 OMX_ERRORTYPE EventHandler(OMX_IN OMX_HANDLETYPE hComponent,
558                            OMX_IN OMX_PTR pAppData,
559                            OMX_IN OMX_EVENTTYPE eEvent,
560                            OMX_IN OMX_U32 nData1, OMX_IN OMX_U32 nData2,
561                            OMX_IN OMX_PTR pEventData)
562 {
563     DEBUG_PRINT("Function %s \n", __FUNCTION__);
564
565     switch(eEvent) {
566         case OMX_EventCmdComplete:
567             DEBUG_PRINT("\n OMX_EventCmdComplete \n");
568             // check nData1 for DISABLE event
569             if(OMX_CommandPortDisable == (OMX_COMMANDTYPE)nData1)
570             {
571                 DEBUG_PRINT("*********************************************\n");
572                 DEBUG_PRINT("Recieved DISABLE Event Command Complete[%d]\n",nData2);
573                 DEBUG_PRINT("*********************************************\n");
574                 sent_disabled = 0;
575             }
576             else if(OMX_CommandPortEnable == (OMX_COMMANDTYPE)nData1)
577             {
578                 DEBUG_PRINT("*********************************************\n");
579                 DEBUG_PRINT("Recieved ENABLE Event Command Complete[%d]\n",nData2);
580                 DEBUG_PRINT("*********************************************\n");
581             }
582             currentStatus = GOOD_STATE;
583             event_complete();
584             break;
585
586         case OMX_EventError:
587             DEBUG_PRINT("OMX_EventError \n");
588             currentStatus = ERROR_STATE;
589             if (OMX_ErrorInvalidState == (OMX_ERRORTYPE)nData1 ||
590                 OMX_ErrorHardware == (OMX_ERRORTYPE)nData1)
591             {
592               DEBUG_PRINT("Invalid State or hardware error \n");
593               currentStatus = INVALID_STATE;
594               if(event_is_done == 0)
595               {
596                 DEBUG_PRINT("Event error in the middle of Decode \n");
597                 pthread_mutex_lock(&eos_lock);
598                 bOutputEosReached = true;
599                 pthread_cond_broadcast(&eos_cond);
600                 pthread_mutex_unlock(&eos_lock);
601
602               }
603             }
604
605             event_complete();
606             break;
607         case OMX_EventPortSettingsChanged:
608             DEBUG_PRINT("OMX_EventPortSettingsChanged port[%d]\n",nData1);
609             waitForPortSettingsChanged = 0;
610             currentStatus = PORT_SETTING_CHANGE_STATE;
611             // reset the event
612             event_complete();
613             break;
614
615         default:
616             DEBUG_PRINT_ERROR("ERROR - Unknown Event \n");
617             break;
618     }
619     return OMX_ErrorNone;
620 }
621
622 OMX_ERRORTYPE EmptyBufferDone(OMX_IN OMX_HANDLETYPE hComponent,
623                               OMX_IN OMX_PTR pAppData,
624                               OMX_IN OMX_BUFFERHEADERTYPE* pBuffer)
625 {
626     int readBytes =0; int bufCnt=0;
627     OMX_ERRORTYPE result;
628
629     DEBUG_PRINT("Function %s cnt[%d]\n", __FUNCTION__, ebd_cnt);
630     ebd_cnt++;
631
632
633     if(bInputEosReached) {
634         DEBUG_PRINT("*****EBD:Input EoS Reached************\n");
635         return OMX_ErrorNone;
636     }
637
638     pthread_mutex_lock(&etb_lock);
639     if(push(etb_queue, (void *) pBuffer) < 0)
640     {
641        DEBUG_PRINT_ERROR("Error in enqueue  ebd data\n");
642        return OMX_ErrorUndefined;
643     }
644     pthread_mutex_unlock(&etb_lock);
645     sem_post(&etb_sem);
646
647     return OMX_ErrorNone;
648 }
649
650 OMX_ERRORTYPE FillBufferDone(OMX_OUT OMX_HANDLETYPE hComponent,
651                              OMX_OUT OMX_PTR pAppData,
652                              OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer)
653 {
654     DEBUG_PRINT("Inside %s callback_count[%d] \n", __FUNCTION__, fbd_cnt);
655
656     /* Test app will assume there is a dynamic port setting
657      * In case that there is no dynamic port setting, OMX will not call event cb,
658      * instead OMX will send empty this buffer directly and we need to clear an event here
659      */
660     if(waitForPortSettingsChanged)
661     {
662       currentStatus = GOOD_STATE;
663       waitForPortSettingsChanged = 0;
664
665       event_complete();
666     }
667
668     if(!sent_disabled)
669     {
670       pthread_mutex_lock(&fbd_lock);
671       if(push(fbd_queue, (void *)pBuffer) < 0)
672       {
673          DEBUG_PRINT_ERROR("Error in enqueueing fbd_data\n");
674          return OMX_ErrorUndefined;
675       }
676       pthread_mutex_unlock(&fbd_lock);
677       sem_post(&fbd_sem);
678     }
679     return OMX_ErrorNone;
680 }
681
682 int main(int argc, char **argv)
683 {
684     int i=0;
685     int bufCnt=0;
686     int num=0;
687     int outputOption = 0;
688     int test_option = 0;
689     OMX_ERRORTYPE result;
690
691     if (argc < 2)
692     {
693       printf("To use it: ./mm-vdec-omx-test <clip location> \n");
694       printf("Command line argument is also available\n");
695       return -1;
696     }
697
698     strncpy(in_filename, argv[1], strlen(argv[1])+1);
699
700     if(argc > 5)
701     {
702       codec_format_option = (codec_format)atoi(argv[2]);
703       file_type_option = (file_type)atoi(argv[3]);
704     }
705     else
706     {
707       printf("Command line argument is available\n");
708       printf("To use it: ./mm-vdec-omx-test <clip location> <codec_type> \n");
709       printf("           <input_type: 1. per AU(.dat), 2. arbitrary, 3.per NAL/frame>\n");
710       printf("           <output_type> <test_case> <size_nal if H264>\n\n\n");
711
712       printf(" *********************************************\n");
713       printf(" ENTER THE TEST CASE YOU WOULD LIKE TO EXECUTE\n");
714       printf(" *********************************************\n");
715       printf(" 1--> H264\n");
716       printf(" 2--> MP4\n");
717       printf(" 3--> H263\n");
718       printf(" 4--> VC1\n");
719       fflush(stdin);
720       scanf("%d", (int *)&codec_format_option);
721       fflush(stdin);
722
723       if (codec_format_option > CODEC_FORMAT_MAX)
724       {
725           printf(" Wrong test case...[%d] \n", codec_format_option);
726           return -1;
727       }
728
729       printf(" *********************************************\n");
730       printf(" ENTER THE TEST CASE YOU WOULD LIKE TO EXECUTE\n");
731       printf(" *********************************************\n");
732       printf(" 1--> PER ACCESS UNIT CLIP (.dat). Clip only available for H264 and Mpeg4\n");
733       printf(" 2--> ARBITRARY BYTES (need .264/.264c/.mv4/.263/.rcv/.vc1)\n");
734       if (codec_format_option == CODEC_FORMAT_H264)
735       {
736         printf(" 3--> NAL LENGTH SIZE CLIP (.264c)\n");
737       }
738       else if ( (codec_format_option == CODEC_FORMAT_MP4) || (codec_format_option == CODEC_FORMAT_H263) )
739       {
740         printf(" 3--> MP4 VOP or H263 P0 SHORT HEADER START CODE CLIP (.m4v or .263)\n");
741       }
742       else if (codec_format_option == CODEC_FORMAT_VC1)
743       {
744         printf(" 3--> VC1 clip Simple/Main Profile (.rcv)\n");
745         printf(" 4--> VC1 clip Advance Profile (.vc1)\n");
746       }
747       fflush(stdin);
748       scanf("%d", (int *)&file_type_option);
749       fflush(stdin);
750     }
751
752     if (file_type_option >= FILE_TYPE_COMMON_CODEC_MAX)
753     {
754       switch (codec_format_option)
755       {
756         case CODEC_FORMAT_H264:
757           file_type_option = (file_type)(FILE_TYPE_START_OF_H264_SPECIFIC + file_type_option - FILE_TYPE_COMMON_CODEC_MAX);
758           break;
759         case CODEC_FORMAT_MP4:
760         case CODEC_FORMAT_H263:
761           file_type_option = (file_type)(FILE_TYPE_START_OF_MP4_SPECIFIC + file_type_option - FILE_TYPE_COMMON_CODEC_MAX);
762           break;
763         case CODEC_FORMAT_VC1:
764           file_type_option = (file_type)(FILE_TYPE_START_OF_VC1_SPECIFIC + file_type_option - FILE_TYPE_COMMON_CODEC_MAX);
765           break;
766         default:
767           printf("Error: Unknown code %d\n", codec_format_option);
768       }
769     }
770
771     if(argc > 5)
772     {
773       outputOption = atoi(argv[4]);
774       test_option = atoi(argv[5]);
775       if (argc > 6)
776       {
777         nalSize = atoi(argv[6]);
778       }
779       else
780       {
781         nalSize = 0;
782       }
783
784       if(argc > 7)
785       {
786         displayWindow = atoi(argv[7]);
787         if(displayWindow > 0)
788         {
789             printf(" Curently display window 0 only supported; ignoring other values\n");
790             displayWindow = 0;
791         }
792       }
793       else
794       {
795         displayWindow = 0;
796       }
797
798       if(file_type_option == FILE_TYPE_PICTURE_START_CODE ||
799          file_type_option == FILE_TYPE_RCV ||
800          (file_type_option == FILE_TYPE_VC1 && argc > 8))
801       {
802           realtime_display = atoi(argv[8]);
803       }
804
805       if(realtime_display)
806       {
807           takeYuvLog = 0;
808           if(argc > 9)
809           {
810               int fps = atoi(argv[9]);
811               timestampInterval = 1000000/fps;
812           }
813           else if(argc > 10)
814           {
815               strncpy(seq_file_name, argv[10], strlen(argv[10])+1);
816           }
817       }
818       else
819       {
820           if(argc > 9)
821           {
822               strncpy(seq_file_name, argv[9], strlen(argv[9])+1);
823           }
824       }
825       height=144;width=176; // Assume Default as QCIF
826       sliceheight = 144;
827       stride = 176;
828       printf("Executing DynPortReconfig QCIF 144 x 176 \n");
829     }
830     else
831     {
832       int fps = 30;
833       switch(file_type_option)
834       {
835           case FILE_TYPE_DAT_PER_AU:
836           case FILE_TYPE_ARBITRARY_BYTES:
837           case FILE_TYPE_264_NAL_SIZE_LENGTH:
838           case FILE_TYPE_PICTURE_START_CODE:
839           case FILE_TYPE_RCV:
840           case FILE_TYPE_VC1:
841           {
842               nalSize = 0;
843               if ((file_type_option == FILE_TYPE_264_NAL_SIZE_LENGTH) ||
844                   ((codec_format_option == CODEC_FORMAT_H264) && (file_type_option == FILE_TYPE_ARBITRARY_BYTES)))
845               {
846                 printf(" Enter Nal length size [2 or 4] \n");
847                 if (file_type_option == FILE_TYPE_ARBITRARY_BYTES)
848                 {
849                   printf(" Enter 0 if it is a start code based clip\n");
850                 }
851                 scanf("%d", &nalSize);
852                 if ((file_type_option == FILE_TYPE_264_NAL_SIZE_LENGTH) &&
853                     (nalSize == 0))
854                 {
855                   printf("Error - Can't pass NAL length size = 0\n");
856                   return -1;
857                 }
858               }
859
860               height=144;width=176; // Assume Default as QCIF
861               printf("Executing DynPortReconfig QCIF 144 x 176 \n");
862               break;
863           }
864
865           default:
866           {
867               printf(" Wrong test case...[%d] \n",file_type_option);
868               return -1;
869           }
870       }
871
872       printf(" *********************************************\n");
873       printf(" Output buffer option:\n");
874       printf(" *********************************************\n");
875       printf(" 0 --> No display and no YUV log\n");
876       printf(" 1 --> Diplay YUV\n");
877       printf(" 2 --> Take YUV log\n");
878       printf(" 3 --> Display YUV and take YUV log\n");
879       fflush(stdin);
880       scanf("%d", &outputOption);
881       fflush(stdin);
882
883       printf(" *********************************************\n");
884       printf(" ENTER THE TEST CASE YOU WOULD LIKE TO EXECUTE\n");
885       printf(" *********************************************\n");
886       printf(" 1 --> Play the clip till the end\n");
887       printf(" 2 --> Run compliance test. Do NOT expect any display for most option. \n");
888       printf("       Please only see \"TEST SUCCESSFULL\" to indidcate test pass\n");
889       fflush(stdin);
890       scanf("%d", &test_option);
891       fflush(stdin);
892
893       printf(" *********************************************\n");
894       printf(" ENTER THE PORTION OF DISPLAY TO USE\n");
895       printf(" *********************************************\n");
896       printf(" 0 --> Entire Screen\n");
897       printf(" 1 --> 1/4 th of the screen starting from top left corner to middle \n");
898       printf(" 2 --> 1/4 th of the screen starting from middle to top right corner \n");
899       printf(" 3 --> 1/4 th of the screen starting from middle to bottom left \n");
900       printf(" 4 --> 1/4 th of the screen starting from middle to bottom right \n");
901       printf("       Please only see \"TEST SUCCESSFULL\" to indidcate test pass\n");
902       fflush(stdin);
903       scanf("%d", &displayWindow);
904       fflush(stdin);
905
906       if(displayWindow > 0)
907       {
908           printf(" Curently display window 0 only supported; ignoring other values\n");
909           displayWindow = 0;
910       }
911
912       if((file_type_option == FILE_TYPE_PICTURE_START_CODE) ||
913          (file_type_option == FILE_TYPE_RCV) ||
914          (file_type_option == FILE_TYPE_VC1))
915       {
916           printf(" *********************************************\n");
917           printf(" DO YOU WANT TEST APP TO RENDER in Real time \n");
918           printf(" 0 --> NO\n 1 --> YES\n");
919           printf(" Warning: For H264, it require one NAL per frame clip.\n");
920           printf("          For Arbitrary bytes option, Real time display is not recommended\n");
921           printf(" *********************************************\n");
922           fflush(stdin);
923           scanf("%d", &realtime_display);
924           fflush(stdin);
925       }
926
927
928       if (realtime_display)
929       {
930           printf(" *********************************************\n");
931           printf(" ENTER THE CLIP FPS\n");
932           printf(" Exception: Timestamp extracted from clips will be used.\n");
933           printf(" *********************************************\n");
934           fflush(stdin);
935           scanf("%d", &fps);
936           fflush(stdin);
937           timestampInterval = 1000000/fps;
938       }
939       printf(" *********************************************\n");
940       printf(" ENTER THE SEQ FILE NAME\n");
941       printf(" *********************************************\n");
942       fflush(stdin);
943       scanf("%[^\n]", (char *)&seq_file_name);
944       fflush(stdin);
945     }
946
947     if (outputOption == 0)
948     {
949       takeYuvLog = 0;
950       realtime_display = 0;
951     }
952     else if (outputOption == 1)
953     {
954       printf("Sorry, cannot display to screen\n");
955       return -1;
956     }
957     else if (outputOption == 2)
958     {
959       takeYuvLog = 1;
960       realtime_display = 0;
961     }
962     else if (outputOption == 3)
963     {
964       printf("Sorry, cannot display to screen\n");
965       return -1;
966     }
967     else
968     {
969       printf("Wrong option. Assume you want to take YUV log\n");
970       takeYuvLog = 1;
971       realtime_display = 0;
972     }
973
974     if (test_option == 2)
975     {
976       printf(" *********************************************\n");
977       printf(" ENTER THE COMPLIANCE TEST YOU WOULD LIKE TO EXECUTE\n");
978       printf(" *********************************************\n");
979       printf(" 1 --> Call Free Handle at the OMX_StateLoaded\n");
980       printf(" 2 --> Call Free Handle at the OMX_StateIdle\n");
981       printf(" 3 --> Call Free Handle at the OMX_StateExecuting\n");
982       printf(" 4 --> Call Free Handle at the OMX_StatePause\n");
983       fflush(stdin);
984       scanf("%d", (int *)&freeHandle_option);
985       fflush(stdin);
986     }
987     else
988     {
989       freeHandle_option = (freeHandle_test)0;
990     }
991
992     printf("Input values: inputfilename[%s]\n", in_filename);
993     printf("*******************************************************\n");
994     pthread_cond_init(&cond, 0);
995     pthread_cond_init(&eos_cond, 0);
996     pthread_mutex_init(&eos_lock, 0);
997     pthread_mutex_init(&lock, 0);
998     pthread_mutex_init(&etb_lock, 0);
999     pthread_mutex_init(&fbd_lock, 0);
1000     if (-1 == sem_init(&etb_sem, 0, 0))
1001     {
1002       printf("Error - sem_init failed %d\n", errno);
1003     }
1004     if (-1 == sem_init(&fbd_sem, 0, 0))
1005     {
1006       printf("Error - sem_init failed %d\n", errno);
1007     }
1008     if (-1 == sem_init(&seq_sem, 0, 0))
1009     {
1010       printf("Error - sem_init failed %d\n", errno);
1011     }
1012     if (-1 == sem_init(&in_flush_sem, 0, 0))
1013     {
1014       printf("Error - sem_init failed %d\n", errno);
1015     }
1016     if (-1 == sem_init(&out_flush_sem, 0, 0))
1017     {
1018       printf("Error - sem_init failed %d\n", errno);
1019     }
1020     etb_queue = alloc_queue();
1021     if (etb_queue == NULL)
1022     {
1023       printf("\n Error in Creating etb_queue\n");
1024       return -1;
1025     }
1026
1027     fbd_queue = alloc_queue();
1028     if (fbd_queue == NULL)
1029     {
1030       printf("\n Error in Creating fbd_queue\n");
1031       free_queue(etb_queue);
1032       return -1;
1033     }
1034
1035     if(0 != pthread_create(&fbd_thread_id, NULL, fbd_thread, NULL))
1036     {
1037       printf("\n Error in Creating fbd_thread \n");
1038       free_queue(etb_queue);
1039       free_queue(fbd_queue);
1040       return -1;
1041     }
1042
1043     run_tests();
1044     pthread_cond_destroy(&cond);
1045     pthread_mutex_destroy(&lock);
1046     pthread_mutex_destroy(&etb_lock);
1047     pthread_mutex_destroy(&fbd_lock);
1048     pthread_cond_destroy(&eos_cond);
1049     pthread_mutex_destroy(&eos_lock);
1050     if (-1 == sem_destroy(&etb_sem))
1051     {
1052       DEBUG_PRINT_ERROR("Error - sem_destroy failed %d\n", errno);
1053     }
1054     if (-1 == sem_destroy(&fbd_sem))
1055     {
1056       DEBUG_PRINT_ERROR("Error - sem_destroy failed %d\n", errno);
1057     }
1058     if (-1 == sem_destroy(&seq_sem))
1059     {
1060       DEBUG_PRINT_ERROR("Error - sem_destroy failed %d\n", errno);
1061     }
1062     if (-1 == sem_destroy(&in_flush_sem))
1063     {
1064       DEBUG_PRINT_ERROR("Error - sem_destroy failed %d\n", errno);
1065     }
1066     if (-1 == sem_destroy(&out_flush_sem))
1067     {
1068       DEBUG_PRINT_ERROR("Error - sem_destroy failed %d\n", errno);
1069     }
1070     //QPERF_TERMINATE(client_decode);
1071     return 0;
1072 }
1073
1074 int run_tests()
1075 {
1076   DEBUG_PRINT("Inside %s\n", __FUNCTION__);
1077   waitForPortSettingsChanged = 1;
1078   currentStatus = GOOD_STATE;
1079
1080   if(file_type_option == FILE_TYPE_DAT_PER_AU) {
1081     Read_Buffer = Read_Buffer_From_DAT_File;
1082   }
1083   else if(file_type_option == FILE_TYPE_ARBITRARY_BYTES) {
1084     Read_Buffer = Read_Buffer_ArbitraryBytes;
1085   }
1086   else if(codec_format_option == CODEC_FORMAT_H264) {
1087     Read_Buffer = Read_Buffer_From_Size_Nal;
1088   }
1089   else if((codec_format_option == CODEC_FORMAT_H263) ||
1090           (codec_format_option == CODEC_FORMAT_MP4)) {
1091     Read_Buffer = Read_Buffer_From_Vop_Start_Code_File;
1092   }
1093   else if(file_type_option == FILE_TYPE_RCV) {
1094     Read_Buffer = Read_Buffer_From_RCV_File;
1095   }
1096   else if(file_type_option == FILE_TYPE_VC1) {
1097     Read_Buffer = Read_Buffer_From_VC1_File;
1098   }
1099
1100   DEBUG_PRINT("file_type_option %d!\n", file_type_option);
1101
1102   switch(file_type_option)
1103   {
1104     case FILE_TYPE_DAT_PER_AU:
1105     case FILE_TYPE_ARBITRARY_BYTES:
1106     case FILE_TYPE_264_NAL_SIZE_LENGTH:
1107     case FILE_TYPE_PICTURE_START_CODE:
1108     case FILE_TYPE_RCV:
1109     case FILE_TYPE_VC1:
1110       if(Init_Decoder()!= 0x00)
1111       {
1112         DEBUG_PRINT_ERROR("Error - Decoder Init failed\n");
1113         return -1;
1114       }
1115       if(Play_Decoder() != 0x00)
1116       {
1117         return -1;
1118       }
1119       break;
1120     default:
1121       DEBUG_PRINT_ERROR("Error - Invalid Entry...%d\n",file_type_option);
1122       break;
1123   }
1124
1125   if(strlen(seq_file_name))
1126   {
1127         seqFile = fopen (seq_file_name, "rb");
1128         if (seqFile == NULL)
1129         {
1130             DEBUG_PRINT_ERROR("Error - Seq file %s could NOT be opened\n",
1131                               seq_file_name);
1132         }
1133         else
1134         {
1135             DEBUG_PRINT("Seq file %s is opened \n", seq_file_name);
1136             seq_enabled = 1;
1137         }
1138   }
1139
1140   pthread_mutex_lock(&eos_lock);
1141   while (bOutputEosReached == false)
1142   {
1143     if(seq_enabled)
1144     {
1145         if(!get_next_command(seqFile))
1146         {
1147             process_current_command(curr_seq_command);
1148         }
1149         else
1150         {
1151             printf("\n Error in get_next_cmd or EOF");
1152             seq_enabled = 0;
1153         }
1154     }
1155     else
1156     {
1157         pthread_cond_wait(&eos_cond, &eos_lock);
1158     }
1159   }
1160   pthread_mutex_unlock(&eos_lock);
1161
1162   // Wait till EOS is reached...
1163     if(bOutputEosReached)
1164     {
1165       unsigned int bufCnt = 0;
1166
1167       DEBUG_PRINT("Moving the decoder to idle state \n");
1168       OMX_SendCommand(dec_handle, OMX_CommandStateSet, OMX_StateIdle,0);
1169       wait_for_event();
1170       if (currentStatus == INVALID_STATE)
1171       {
1172         do_freeHandle_and_clean_up(true);
1173         return 0;
1174       }
1175
1176       DEBUG_PRINT("Moving the decoder to loaded state \n");
1177       OMX_SendCommand(dec_handle, OMX_CommandStateSet, OMX_StateLoaded,0);
1178
1179       DEBUG_PRINT("[OMX Vdec Test] - Deallocating i/p and o/p buffers \n");
1180       for(bufCnt=0; bufCnt < input_buf_cnt; ++bufCnt)
1181       {
1182         OMX_FreeBuffer(dec_handle, 0, pInputBufHdrs[bufCnt]);
1183       }
1184
1185       for(bufCnt=0; bufCnt < portFmt.nBufferCountActual; ++bufCnt)
1186       {
1187         OMX_FreeBuffer(dec_handle, 1, pOutYUVBufHdrs[bufCnt]);
1188       }
1189
1190       fbd_cnt = 0; ebd_cnt=0;
1191       bInputEosReached = false;
1192       bOutputEosReached = false;
1193
1194       wait_for_event();
1195
1196       DEBUG_PRINT("[OMX Vdec Test] - Free handle decoder\n");
1197       OMX_ERRORTYPE result = OMX_FreeHandle(dec_handle);
1198       if (result != OMX_ErrorNone)
1199       {
1200         DEBUG_PRINT_ERROR("[OMX Vdec Test] - Terminate: OMX_FreeHandle error. Error code: %d\n", result);
1201       }
1202       dec_handle = NULL;
1203
1204       /* Deinit OpenMAX */
1205       DEBUG_PRINT("[OMX Vdec Test] - Terminate: De-initializing OMX \n");
1206       OMX_Deinit();
1207
1208       DEBUG_PRINT("[OMX Vdec Test] - Terminate: closing all files\n");
1209       if(inputBufferFile)
1210       {
1211       fclose(inputBufferFile);
1212           inputBufferFile = NULL;
1213       }
1214
1215
1216       if (takeYuvLog && outputBufferFile) {
1217         fclose(outputBufferFile);
1218         outputBufferFile = NULL;
1219       }
1220
1221       if(etb_queue)
1222       {
1223         free_queue(etb_queue);
1224         etb_queue = NULL;
1225       }
1226       if(fbd_queue)
1227       {
1228         free_queue(fbd_queue);
1229         fbd_queue = NULL;
1230       }
1231
1232       printf("*****************************************\n");
1233       printf("******...TEST SUCCESSFULL...*******\n");
1234       printf("*****************************************\n");
1235
1236   }
1237
1238   return 0;
1239 }
1240
1241 int Init_Decoder()
1242 {
1243     DEBUG_PRINT("Inside %s \n", __FUNCTION__);
1244     OMX_ERRORTYPE omxresult;
1245     OMX_U32 total = 0;
1246     char vdecCompNames[50];
1247     typedef OMX_U8* OMX_U8_PTR;
1248     char role[] ="video_decoder";
1249
1250     static OMX_CALLBACKTYPE call_back = {&EventHandler, &EmptyBufferDone, &FillBufferDone};
1251
1252     unsigned int i = 0;
1253     long bufCnt = 0;
1254
1255     /* Init. the OpenMAX Core */
1256     DEBUG_PRINT("\nInitializing OpenMAX Core....\n");
1257     omxresult = OMX_Init();
1258
1259     if(OMX_ErrorNone != omxresult) {
1260         DEBUG_PRINT_ERROR("\n Failed to Init OpenMAX core");
1261         return -1;
1262     }
1263     else {
1264         DEBUG_PRINT_ERROR("\nOpenMAX Core Init Done\n");
1265     }
1266
1267     /* Query for video decoders*/
1268     OMX_GetComponentsOfRole(role, &total, 0);
1269     DEBUG_PRINT("\nTotal components of role=%s :%d", role, total);
1270
1271     if(total)
1272     {
1273         /* Allocate memory for pointers to component name */
1274         OMX_U8** vidCompNames = (OMX_U8**)malloc((sizeof(OMX_U8*))*total);
1275
1276         for (i = 0; i < total; ++i) {
1277             vidCompNames[i] = (OMX_U8*)malloc(sizeof(OMX_U8)*OMX_MAX_STRINGNAME_SIZE);
1278         }
1279         OMX_GetComponentsOfRole(role, &total, vidCompNames);
1280         DEBUG_PRINT("\nComponents of Role:%s\n", role);
1281         for (i = 0; i < total; ++i) {
1282             DEBUG_PRINT("\nComponent Name [%s]\n",vidCompNames[i]);
1283             free(vidCompNames[i]);
1284         }
1285         free(vidCompNames);
1286     }
1287     else {
1288         DEBUG_PRINT_ERROR("No components found with Role:%s", role);
1289     }
1290
1291     if (codec_format_option == CODEC_FORMAT_H264)
1292     {
1293       strncpy(vdecCompNames, "OMX.qcom.video.decoder.avc", 27);
1294     }
1295     else if (codec_format_option == CODEC_FORMAT_MP4)
1296     {
1297       strncpy(vdecCompNames, "OMX.qcom.video.decoder.mpeg4", 29);
1298     }
1299     else if (codec_format_option == CODEC_FORMAT_H263)
1300     {
1301       strncpy(vdecCompNames, "OMX.qcom.video.decoder.h263", 28);
1302     }
1303     else if (codec_format_option == CODEC_FORMAT_VC1)
1304     {
1305       strncpy(vdecCompNames, "OMX.qcom.video.decoder.vc1", 27);
1306     }
1307     else
1308     {
1309       DEBUG_PRINT_ERROR("Error: Unsupported codec %d\n", codec_format_option);
1310       return -1;
1311     }
1312
1313     omxresult = OMX_GetHandle((OMX_HANDLETYPE*)(&dec_handle),
1314                               (OMX_STRING)vdecCompNames, NULL, &call_back);
1315     if (FAILED(omxresult)) {
1316         DEBUG_PRINT_ERROR("\nFailed to Load the component:%s\n", vdecCompNames);
1317         return -1;
1318     }
1319     else
1320     {
1321         DEBUG_PRINT("\nComponent %s is in LOADED state\n", vdecCompNames);
1322     }
1323
1324     QOMX_VIDEO_QUERY_DECODER_INSTANCES decoder_instances;
1325     omxresult = OMX_GetConfig(dec_handle,
1326                  (OMX_INDEXTYPE)OMX_QcomIndexQueryNumberOfVideoDecInstance,
1327                               &decoder_instances);
1328     DEBUG_PRINT("\n Number of decoder instances %d",
1329                       decoder_instances.nNumOfInstances);
1330
1331     /* Get the port information */
1332     CONFIG_VERSION_SIZE(portParam);
1333     omxresult = OMX_GetParameter(dec_handle, OMX_IndexParamVideoInit,
1334                                 (OMX_PTR)&portParam);
1335
1336     if(FAILED(omxresult)) {
1337         DEBUG_PRINT_ERROR("ERROR - Failed to get Port Param\n");
1338         return -1;
1339     }
1340     else
1341     {
1342         DEBUG_PRINT("portParam.nPorts:%d\n", portParam.nPorts);
1343         DEBUG_PRINT("portParam.nStartPortNumber:%d\n", portParam.nStartPortNumber);
1344     }
1345
1346     DEBUG_PRINT("Set parameter immediately followed by getparameter");
1347     omxresult = OMX_SetParameter(dec_handle,
1348                                OMX_IndexParamPortDefinition,
1349                                &portFmt);
1350
1351     if(OMX_ErrorNone != omxresult)
1352     {
1353         DEBUG_PRINT_ERROR("ERROR - Set parameter failed");
1354     }
1355
1356     /* Set the compression format on i/p port */
1357     if (codec_format_option == CODEC_FORMAT_H264)
1358     {
1359       portFmt.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC;
1360     }
1361     else if (codec_format_option == CODEC_FORMAT_MP4)
1362     {
1363       portFmt.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4;
1364     }
1365     else if (codec_format_option == CODEC_FORMAT_H263)
1366     {
1367       portFmt.format.video.eCompressionFormat = OMX_VIDEO_CodingH263;
1368     }
1369     else if (codec_format_option == CODEC_FORMAT_VC1)
1370     {
1371       portFmt.format.video.eCompressionFormat = OMX_VIDEO_CodingWMV;
1372     }
1373     else
1374     {
1375       DEBUG_PRINT_ERROR("Error: Unsupported codec %d\n", codec_format_option);
1376     }
1377
1378
1379     return 0;
1380 }
1381
1382 int Play_Decoder()
1383 {
1384     int i;
1385     unsigned int bufCnt;
1386     int frameSize=0;
1387     DEBUG_PRINT("Inside %s \n", __FUNCTION__);
1388     OMX_ERRORTYPE ret;
1389
1390     DEBUG_PRINT("sizeof[%d]\n", sizeof(OMX_BUFFERHEADERTYPE));
1391
1392     /* open the i/p and o/p files based on the video file format passed */
1393     if(open_video_file()) {
1394         DEBUG_PRINT_ERROR("Error in opening video file\n");
1395         return -1;
1396     }
1397
1398     OMX_QCOM_PARAM_PORTDEFINITIONTYPE inputPortFmt;
1399     memset(&inputPortFmt, 0, sizeof(OMX_QCOM_PARAM_PORTDEFINITIONTYPE));
1400     CONFIG_VERSION_SIZE(inputPortFmt);
1401     inputPortFmt.nPortIndex = 0;  // input port
1402     switch (file_type_option)
1403     {
1404       case FILE_TYPE_DAT_PER_AU:
1405       case FILE_TYPE_PICTURE_START_CODE:
1406       case FILE_TYPE_RCV:
1407       case FILE_TYPE_VC1:
1408       {
1409         inputPortFmt.nFramePackingFormat = OMX_QCOM_FramePacking_OnlyOneCompleteFrame;
1410         break;
1411       }
1412
1413       case FILE_TYPE_ARBITRARY_BYTES:
1414       case FILE_TYPE_264_NAL_SIZE_LENGTH:
1415       {
1416         inputPortFmt.nFramePackingFormat = OMX_QCOM_FramePacking_Arbitrary;
1417         break;
1418       }
1419
1420       default:
1421         inputPortFmt.nFramePackingFormat = OMX_QCOM_FramePacking_Unspecified;
1422     }
1423     OMX_SetParameter(dec_handle,(OMX_INDEXTYPE)OMX_QcomIndexPortDefn,
1424                      (OMX_PTR)&inputPortFmt);
1425
1426     /* Query the decoder outport's min buf requirements */
1427     CONFIG_VERSION_SIZE(portFmt);
1428
1429     /* Port for which the Client needs to obtain info */
1430     portFmt.nPortIndex = portParam.nStartPortNumber;
1431
1432     OMX_GetParameter(dec_handle,OMX_IndexParamPortDefinition,&portFmt);
1433     DEBUG_PRINT("\nDec: Min Buffer Count %d\n", portFmt.nBufferCountMin);
1434     DEBUG_PRINT("\nDec: Buffer Size %d\n", portFmt.nBufferSize);
1435
1436     if(OMX_DirInput != portFmt.eDir) {
1437         printf ("\nDec: Expect Input Port\n");
1438         return -1;
1439     }
1440
1441     bufCnt = 0;
1442     portFmt.format.video.nFrameHeight = height;
1443     portFmt.format.video.nFrameWidth  = width;
1444     OMX_SetParameter(dec_handle,OMX_IndexParamPortDefinition,
1445                                                        (OMX_PTR)&portFmt);
1446     OMX_GetParameter(dec_handle,OMX_IndexParamPortDefinition,
1447                                                                &portFmt);
1448     DEBUG_PRINT("\nDec: New Min Buffer Count %d", portFmt.nBufferCountMin);
1449
1450
1451     DEBUG_PRINT("\nVideo format, height = %d", portFmt.format.video.nFrameHeight);
1452     DEBUG_PRINT("\nVideo format, height = %d\n", portFmt.format.video.nFrameWidth);
1453     if(codec_format_option == CODEC_FORMAT_H264)
1454     {
1455         OMX_VIDEO_CONFIG_NALSIZE naluSize;
1456         naluSize.nNaluBytes = nalSize;
1457         DEBUG_PRINT("\n Nal length is %d index %d",nalSize,OMX_IndexConfigVideoNalSize);
1458         OMX_SetConfig(dec_handle,OMX_IndexConfigVideoNalSize,(OMX_PTR)&naluSize);
1459         DEBUG_PRINT("SETTING THE NAL SIZE to %d\n",naluSize.nNaluBytes);
1460     }
1461     DEBUG_PRINT("\nOMX_SendCommand Decoder -> IDLE\n");
1462     OMX_SendCommand(dec_handle, OMX_CommandStateSet, OMX_StateIdle,0);
1463
1464     input_buf_cnt = portFmt.nBufferCountActual;
1465     DEBUG_PRINT("Transition to Idle State succesful...\n");
1466     /* Allocate buffer on decoder's i/p port */
1467     error = Allocate_Buffer(dec_handle, &pInputBufHdrs, portFmt.nPortIndex,
1468                             portFmt.nBufferCountActual, portFmt.nBufferSize);
1469     if (error != OMX_ErrorNone) {
1470         DEBUG_PRINT_ERROR("Error - OMX_AllocateBuffer Input buffer error\n");
1471         return -1;
1472     }
1473     else {
1474         DEBUG_PRINT("\nOMX_AllocateBuffer Input buffer success\n");
1475     }
1476
1477     portFmt.nPortIndex = portParam.nStartPortNumber+1;
1478     /* Port for which the Client needs to obtain info */
1479
1480     OMX_GetParameter(dec_handle,OMX_IndexParamPortDefinition,&portFmt);
1481     DEBUG_PRINT("nMin Buffer Count=%d", portFmt.nBufferCountMin);
1482     DEBUG_PRINT("nBuffer Size=%d", portFmt.nBufferSize);
1483     if(OMX_DirOutput != portFmt.eDir) {
1484         DEBUG_PRINT_ERROR("Error - Expect Output Port\n");
1485         return -1;
1486     }
1487
1488     /* Allocate buffer on decoder's o/p port */
1489     error = Allocate_Buffer(dec_handle, &pOutYUVBufHdrs, portFmt.nPortIndex,
1490                             portFmt.nBufferCountActual, portFmt.nBufferSize);
1491     if (error != OMX_ErrorNone) {
1492         DEBUG_PRINT_ERROR("Error - OMX_AllocateBuffer Output buffer error\n");
1493         return -1;
1494     }
1495     else
1496     {
1497         DEBUG_PRINT("OMX_AllocateBuffer Output buffer success\n");
1498     }
1499
1500     wait_for_event();
1501     if (currentStatus == INVALID_STATE)
1502     {
1503       do_freeHandle_and_clean_up(true);
1504       return -1;
1505     }
1506
1507     if (freeHandle_option == FREE_HANDLE_AT_IDLE)
1508     {
1509       OMX_STATETYPE state = OMX_StateInvalid;
1510       OMX_GetState(dec_handle, &state);
1511       if (state == OMX_StateIdle)
1512       {
1513         DEBUG_PRINT("Decoder is in OMX_StateIdle and trying to call OMX_FreeHandle \n");
1514         do_freeHandle_and_clean_up(false);
1515       }
1516       else
1517       {
1518         DEBUG_PRINT_ERROR("Error - Decoder is in state %d and trying to call OMX_FreeHandle \n", state);
1519         do_freeHandle_and_clean_up(true);
1520       }
1521       return -1;
1522     }
1523
1524
1525     DEBUG_PRINT("OMX_SendCommand Decoder -> Executing\n");
1526     OMX_SendCommand(dec_handle, OMX_CommandStateSet, OMX_StateExecuting,0);
1527     wait_for_event();
1528     if (currentStatus == INVALID_STATE)
1529     {
1530       do_freeHandle_and_clean_up(true);
1531       return -1;
1532     }
1533
1534     for(bufCnt=0; bufCnt < portFmt.nBufferCountActual; ++bufCnt) {
1535         DEBUG_PRINT("OMX_FillThisBuffer on output buf no.%d\n",bufCnt);
1536         pOutYUVBufHdrs[bufCnt]->nOutputPortIndex = 1;
1537         pOutYUVBufHdrs[bufCnt]->nFlags &= ~OMX_BUFFERFLAG_EOS;
1538         ret = OMX_FillThisBuffer(dec_handle, pOutYUVBufHdrs[bufCnt]);
1539         if (OMX_ErrorNone != ret) {
1540             DEBUG_PRINT_ERROR("Error - OMX_FillThisBuffer failed with result %d\n", ret);
1541         }
1542         else {
1543             DEBUG_PRINT("OMX_FillThisBuffer success!\n");
1544         }
1545     }
1546
1547     used_ip_buf_cnt = input_buf_cnt;
1548
1549     rcv_v1 = 0;
1550
1551     //QPERF_START(client_decode);
1552     if (codec_format_option == CODEC_FORMAT_VC1)
1553     {
1554       pInputBufHdrs[0]->nOffset = 0;
1555       if(file_type_option == FILE_TYPE_RCV)
1556       {
1557       frameSize = Read_Buffer_From_RCV_File_Seq_Layer(pInputBufHdrs[0]);
1558       pInputBufHdrs[0]->nFilledLen = frameSize;
1559           DEBUG_PRINT("After Read_Buffer_From_RCV_File_Seq_Layer, "
1560               "frameSize %d\n", frameSize);
1561       }
1562       else if(file_type_option == FILE_TYPE_VC1)
1563       {
1564           pInputBufHdrs[0]->nFilledLen = Read_Buffer(pInputBufHdrs[0]);
1565           DEBUG_PRINT_ERROR("After 1st Read_Buffer for VC1, "
1566               "pInputBufHdrs[0]->nFilledLen %d\n", pInputBufHdrs[0]->nFilledLen);
1567       }
1568       else
1569       {
1570           pInputBufHdrs[0]->nFilledLen = Read_Buffer(pInputBufHdrs[0]);
1571           DEBUG_PRINT("After Read_Buffer pInputBufHdrs[0]->nFilledLen %d\n",
1572               pInputBufHdrs[0]->nFilledLen);
1573       }
1574
1575       pInputBufHdrs[0]->nInputPortIndex = 0;
1576       pInputBufHdrs[0]->nOffset = 0;
1577       pInputBufHdrs[0]->nFlags = 0;
1578
1579       ret = OMX_EmptyThisBuffer(dec_handle, pInputBufHdrs[0]);
1580       if (ret != OMX_ErrorNone)
1581       {
1582           DEBUG_PRINT_ERROR("ERROR - OMX_EmptyThisBuffer failed with result %d\n", ret);
1583           do_freeHandle_and_clean_up(true);
1584           return -1;
1585       }
1586       else
1587       {
1588           etb_count++;
1589           DEBUG_PRINT("OMX_EmptyThisBuffer success!\n");
1590           if(cmd_data == etb_count)
1591           {
1592             sem_post(&seq_sem);
1593             printf("\n Posted seq_sem");
1594           }
1595       }
1596       i = 1;
1597     }
1598     else
1599     {
1600       i = 0;
1601     }
1602
1603     for (i; i < used_ip_buf_cnt;i++) {
1604       pInputBufHdrs[i]->nInputPortIndex = 0;
1605       pInputBufHdrs[i]->nOffset = 0;
1606       if((frameSize = Read_Buffer(pInputBufHdrs[i])) <= 0 ){
1607         DEBUG_PRINT("NO FRAME READ\n");
1608         pInputBufHdrs[i]->nFilledLen = frameSize;
1609         pInputBufHdrs[i]->nInputPortIndex = 0;
1610         pInputBufHdrs[i]->nFlags |= OMX_BUFFERFLAG_EOS;;
1611         bInputEosReached = true;
1612
1613         OMX_EmptyThisBuffer(dec_handle, pInputBufHdrs[i]);
1614         etb_count++;
1615         if(cmd_data == etb_count)
1616         {
1617             sem_post(&seq_sem);
1618             printf("\n Posted seq_sem");
1619         }
1620         DEBUG_PRINT("File is small::Either EOS or Some Error while reading file\n");
1621         break;
1622       }
1623       pInputBufHdrs[i]->nFilledLen = frameSize;
1624       pInputBufHdrs[i]->nInputPortIndex = 0;
1625       pInputBufHdrs[i]->nFlags = 0;
1626 //pBufHdr[bufCnt]->pAppPrivate = this;
1627       ret = OMX_EmptyThisBuffer(dec_handle, pInputBufHdrs[i]);
1628       if (OMX_ErrorNone != ret) {
1629           DEBUG_PRINT_ERROR("ERROR - OMX_EmptyThisBuffer failed with result %d\n", ret);
1630           do_freeHandle_and_clean_up(true);
1631           return -1;
1632       }
1633       else {
1634           DEBUG_PRINT("OMX_EmptyThisBuffer success!\n");
1635           etb_count++;
1636           if(cmd_data == etb_count)
1637           {
1638             sem_post(&seq_sem);
1639             printf("\n Posted seq_sem");
1640           }
1641       }
1642     }
1643
1644     if(0 != pthread_create(&ebd_thread_id, NULL, ebd_thread, NULL))
1645     {
1646       printf("\n Error in Creating fbd_thread \n");
1647       free_queue(etb_queue);
1648       free_queue(fbd_queue);
1649       return -1;
1650     }
1651
1652     // wait for event port settings changed event
1653     wait_for_event();
1654     DEBUG_PRINT("RECIEVED EVENT PORT TO DETERMINE IF DYN PORT RECONFIGURATION NEEDED, currentStatus %d\n",
1655                   currentStatus);
1656     if (currentStatus == INVALID_STATE)
1657     {
1658       DEBUG_PRINT_ERROR("Error - INVALID_STATE\n");
1659       do_freeHandle_and_clean_up(true);
1660       return -1;
1661     }
1662     else if (currentStatus == PORT_SETTING_CHANGE_STATE)
1663     {
1664         DEBUG_PRINT("PORT_SETTING_CHANGE_STATE\n");
1665         // Send DISABLE command
1666         sent_disabled = 1;
1667         OMX_SendCommand(dec_handle, OMX_CommandPortDisable, 1, 0);
1668
1669         DEBUG_PRINT("FREEING BUFFERS\n");
1670         // Free output Buffer
1671         for(bufCnt=0; bufCnt < portFmt.nBufferCountActual; ++bufCnt) {
1672             OMX_FreeBuffer(dec_handle, 1, pOutYUVBufHdrs[bufCnt]);
1673         }
1674
1675         // wait for Disable event to come back
1676         wait_for_event();
1677         if (currentStatus == INVALID_STATE)
1678         {
1679           do_freeHandle_and_clean_up(true);
1680           return -1;
1681         }
1682         DEBUG_PRINT("DISABLE EVENT RECD\n");
1683         // GetParam and SetParam
1684
1685         // Send Enable command
1686         OMX_SendCommand(dec_handle, OMX_CommandPortEnable, 1, 0);
1687         // AllocateBuffers
1688         /* Allocate buffer on decoder's o/p port */
1689
1690         portFmt.nPortIndex = 1;
1691         /* Port for which the Client needs to obtain info */
1692
1693         OMX_GetParameter(dec_handle,OMX_IndexParamPortDefinition,&portFmt);
1694         DEBUG_PRINT("Min Buffer Count=%d", portFmt.nBufferCountMin);
1695         DEBUG_PRINT("Buffer Size=%d", portFmt.nBufferSize);
1696         if(OMX_DirOutput != portFmt.eDir) {
1697             DEBUG_PRINT_ERROR("Error - Expect Output Port\n");
1698             return -1;
1699         }
1700         height = portFmt.format.video.nFrameHeight;
1701         width = portFmt.format.video.nFrameWidth;
1702         stride = portFmt.format.video.nStride;
1703         sliceheight = portFmt.format.video.nSliceHeight;
1704
1705         error = Allocate_Buffer(dec_handle, &pOutYUVBufHdrs, portFmt.nPortIndex,
1706                                 portFmt.nBufferCountActual, portFmt.nBufferSize);
1707         if (error != OMX_ErrorNone) {
1708             DEBUG_PRINT_ERROR("Error - OMX_AllocateBuffer Output buffer error\n");
1709             return -1;
1710         }
1711         else
1712         {
1713             DEBUG_PRINT("OMX_AllocateBuffer Output buffer success\n");
1714         }
1715
1716         // wait for enable event to come back
1717         wait_for_event();
1718         if (currentStatus == INVALID_STATE)
1719         {
1720           do_freeHandle_and_clean_up(true);
1721           return -1;
1722         }
1723         DEBUG_PRINT("ENABLE EVENT HANDLER RECD\n");
1724
1725         for(bufCnt=0; bufCnt < portFmt.nBufferCountActual; ++bufCnt) {
1726             DEBUG_PRINT("OMX_FillThisBuffer on output buf no.%d\n",bufCnt);
1727             pOutYUVBufHdrs[bufCnt]->nOutputPortIndex = 1;
1728             pOutYUVBufHdrs[bufCnt]->nFlags &= ~OMX_BUFFERFLAG_EOS;
1729             ret = OMX_FillThisBuffer(dec_handle, pOutYUVBufHdrs[bufCnt]);
1730             if (OMX_ErrorNone != ret) {
1731                 DEBUG_PRINT_ERROR("ERROR - OMX_FillThisBuffer failed with result %d\n", ret);
1732             }
1733             else {
1734                 DEBUG_PRINT("OMX_FillThisBuffer success!\n");
1735             }
1736         }
1737     }
1738
1739     if (freeHandle_option == FREE_HANDLE_AT_EXECUTING)
1740     {
1741       OMX_STATETYPE state = OMX_StateInvalid;
1742       OMX_GetState(dec_handle, &state);
1743       if (state == OMX_StateExecuting)
1744       {
1745         DEBUG_PRINT("Decoder is in OMX_StateExecuting and trying to call OMX_FreeHandle \n");
1746         do_freeHandle_and_clean_up(false);
1747       }
1748       else
1749       {
1750         DEBUG_PRINT_ERROR("Error - Decoder is in state %d and trying to call OMX_FreeHandle \n", state);
1751         do_freeHandle_and_clean_up(true);
1752       }
1753       return -1;
1754     }
1755     else if (freeHandle_option == FREE_HANDLE_AT_PAUSE)
1756     {
1757       OMX_SendCommand(dec_handle, OMX_CommandStateSet, OMX_StatePause,0);
1758       wait_for_event();
1759
1760       OMX_STATETYPE state = OMX_StateInvalid;
1761       OMX_GetState(dec_handle, &state);
1762       if (state == OMX_StatePause)
1763       {
1764         DEBUG_PRINT("Decoder is in OMX_StatePause and trying to call OMX_FreeHandle \n");
1765         do_freeHandle_and_clean_up(false);
1766       }
1767       else
1768       {
1769         DEBUG_PRINT_ERROR("Error - Decoder is in state %d and trying to call OMX_FreeHandle \n", state);
1770         do_freeHandle_and_clean_up(true);
1771       }
1772       return -1;
1773     }
1774
1775     return 0;
1776 }
1777
1778 static OMX_ERRORTYPE Allocate_Buffer ( OMX_COMPONENTTYPE *dec_handle,
1779                                        OMX_BUFFERHEADERTYPE  ***pBufHdrs,
1780                                        OMX_U32 nPortIndex,
1781                                        long bufCntMin, long bufSize)
1782 {
1783     DEBUG_PRINT("Inside %s \n", __FUNCTION__);
1784     OMX_ERRORTYPE error=OMX_ErrorNone;
1785     long bufCnt=0;
1786
1787     DEBUG_PRINT("pBufHdrs = %x,bufCntMin = %d\n", pBufHdrs, bufCntMin);
1788     *pBufHdrs= (OMX_BUFFERHEADERTYPE **)
1789                    malloc(sizeof(OMX_BUFFERHEADERTYPE)*bufCntMin);
1790
1791     for(bufCnt=0; bufCnt < bufCntMin; ++bufCnt) {
1792         DEBUG_PRINT("OMX_AllocateBuffer No %d \n", bufCnt);
1793         error = OMX_AllocateBuffer(dec_handle, &((*pBufHdrs)[bufCnt]),
1794                                    nPortIndex, NULL, bufSize);
1795     }
1796
1797     return error;
1798 }
1799
1800 static void do_freeHandle_and_clean_up(bool isDueToError)
1801 {
1802     unsigned int bufCnt = 0;
1803
1804     for(bufCnt=0; bufCnt < input_buf_cnt; ++bufCnt)
1805     {
1806         OMX_FreeBuffer(dec_handle, 0, pInputBufHdrs[bufCnt]);
1807     }
1808
1809     for(bufCnt=0; bufCnt < portFmt.nBufferCountActual; ++bufCnt)
1810     {
1811         OMX_FreeBuffer(dec_handle, 1, pOutYUVBufHdrs[bufCnt]);
1812     }
1813
1814     DEBUG_PRINT("[OMX Vdec Test] - Free handle decoder\n");
1815     OMX_ERRORTYPE result = OMX_FreeHandle(dec_handle);
1816     if (result != OMX_ErrorNone)
1817     {
1818        DEBUG_PRINT_ERROR("[OMX Vdec Test] - OMX_FreeHandle error. Error code: %d\n", result);
1819     }
1820     dec_handle = NULL;
1821
1822     /* Deinit OpenMAX */
1823     DEBUG_PRINT("[OMX Vdec Test] - De-initializing OMX \n");
1824     OMX_Deinit();
1825
1826     DEBUG_PRINT("[OMX Vdec Test] - closing all files\n");
1827     if(inputBufferFile)
1828     {
1829     fclose(inputBufferFile);
1830        inputBufferFile = NULL;
1831     }
1832
1833     DEBUG_PRINT("[OMX Vdec Test] - after free inputfile\n");
1834
1835     if (takeYuvLog && outputBufferFile) {
1836         fclose(outputBufferFile);
1837         outputBufferFile = NULL;
1838     }
1839     DEBUG_PRINT("[OMX Vdec Test] - after free outputfile\n");
1840
1841     if(etb_queue)
1842     {
1843       free_queue(etb_queue);
1844       etb_queue = NULL;
1845     }
1846     DEBUG_PRINT("[OMX Vdec Test] - after free etb_queue \n");
1847     if(fbd_queue)
1848     {
1849       free_queue(fbd_queue);
1850       fbd_queue = NULL;
1851     }
1852     DEBUG_PRINT("[OMX Vdec Test] - after free iftb_queue\n");
1853
1854
1855     printf("*****************************************\n");
1856     if (isDueToError)
1857     {
1858       printf("************...TEST FAILED...************\n");
1859     }
1860     else
1861     {
1862       printf("**********...TEST SUCCESSFULL...*********\n");
1863     }
1864     printf("*****************************************\n");
1865 }
1866
1867 static int Read_Buffer_From_DAT_File(OMX_BUFFERHEADERTYPE  *pBufHdr)
1868 {
1869     long frameSize=0;
1870     char temp_buffer[10];
1871     char temp_byte;
1872     int bytes_read=0;
1873     int i=0;
1874     unsigned char *read_buffer=NULL;
1875     char c = '1'; //initialize to anything except '\0'(0)
1876     char inputFrameSize[10];
1877     int count =0;
1878     int cnt = 0;
1879     memset(temp_buffer, 0, sizeof(temp_buffer));
1880
1881     DEBUG_PRINT("Inside %s \n", __FUNCTION__);
1882
1883     while (cnt < 10)
1884     /* Check the input file format, may result in infinite loop */
1885     {
1886         DEBUG_PRINT("loop[%d] count[%d]\n",cnt,count);
1887         count  = fread(&inputFrameSize[cnt], 1, 1, inputBufferFile);
1888         if(inputFrameSize[cnt] == '\0' )
1889           break;
1890         cnt++;
1891     }
1892     inputFrameSize[cnt]='\0';
1893     frameSize = atoi(inputFrameSize);
1894     pBufHdr->nFilledLen = 0;
1895
1896     /* get the frame length */
1897     fseek(inputBufferFile, -1, SEEK_CUR);
1898     bytes_read = fread(pBufHdr->pBuffer, 1, frameSize,  inputBufferFile);
1899
1900     DEBUG_PRINT("Actual frame Size [%d] bytes_read using fread[%d]\n",
1901                   frameSize, bytes_read);
1902
1903     if(bytes_read == 0 || bytes_read < frameSize ) {
1904         DEBUG_PRINT("Bytes read Zero After Read frame Size \n");
1905         DEBUG_PRINT("Checking VideoPlayback Count:video_playback_count is:%d\n",
1906                        video_playback_count);
1907         return 0;
1908     }
1909     pBufHdr->nTimeStamp = timeStampLfile;
1910     timeStampLfile += timestampInterval;
1911     return bytes_read;
1912 }
1913
1914 static int Read_Buffer_ArbitraryBytes(OMX_BUFFERHEADERTYPE  *pBufHdr)
1915 {
1916     char temp_buffer[10];
1917     char temp_byte;
1918     int bytes_read=0;
1919     int i=0;
1920     unsigned char *read_buffer=NULL;
1921     char c = '1'; //initialize to anything except '\0'(0)
1922     char inputFrameSize[10];
1923     int count =0; char cnt =0;
1924     memset(temp_buffer, 0, sizeof(temp_buffer));
1925
1926     DEBUG_PRINT("Inside %s \n", __FUNCTION__);
1927
1928     bytes_read = fread(pBufHdr->pBuffer, 1, NUMBER_OF_ARBITRARYBYTES_READ,  inputBufferFile);
1929
1930     if(bytes_read == 0) {
1931         DEBUG_PRINT("Bytes read Zero After Read frame Size \n");
1932         DEBUG_PRINT("Checking VideoPlayback Count:video_playback_count is:%d\n",
1933                       video_playback_count);
1934         return 0;
1935     }
1936     pBufHdr->nTimeStamp = timeStampLfile;
1937     timeStampLfile += timestampInterval;
1938     return bytes_read;
1939 }
1940
1941 static int Read_Buffer_From_Vop_Start_Code_File(OMX_BUFFERHEADERTYPE  *pBufHdr)
1942 {
1943     unsigned int readOffset = 0;
1944     int bytes_read = 0;
1945     unsigned int code = 0;
1946     pBufHdr->nFilledLen = 0;
1947     static unsigned int header_code = 0;
1948
1949     DEBUG_PRINT("Inside %s \n", __FUNCTION__);
1950
1951     do
1952     {
1953       //Start codes are always byte aligned.
1954       bytes_read = fread(&pBufHdr->pBuffer[readOffset],1, 1,inputBufferFile);
1955       if(!bytes_read)
1956       {
1957           DEBUG_PRINT("Bytes read Zero \n");
1958           break;
1959       }
1960       code <<= 8;
1961       code |= (0x000000FF & pBufHdr->pBuffer[readOffset]);
1962       //VOP start code comparision
1963       if (readOffset>3)
1964       {
1965         if(!header_code ){
1966           if( VOP_START_CODE == code)
1967           {
1968             header_code = VOP_START_CODE;
1969           }
1970           else if ( (0xFFFFFC00 & code) == SHORT_HEADER_START_CODE )
1971           {
1972             header_code = SHORT_HEADER_START_CODE;
1973           }
1974         }
1975         if ((header_code == VOP_START_CODE) && (code == VOP_START_CODE))
1976         {
1977           //Seek backwards by 4
1978           fseek(inputBufferFile, -4, SEEK_CUR);
1979           readOffset-=3;
1980           break;
1981
1982         }
1983         else if (( header_code == SHORT_HEADER_START_CODE ) && ( SHORT_HEADER_START_CODE == (code & 0xFFFFFC00)))
1984         {
1985           //Seek backwards by 4
1986           fseek(inputBufferFile, -4, SEEK_CUR);
1987           readOffset-=3;
1988           break;
1989         }
1990       }
1991       readOffset++;
1992     }while (1);
1993     pBufHdr->nTimeStamp = timeStampLfile;
1994     timeStampLfile += timestampInterval;
1995     return readOffset;
1996 }
1997
1998 static int Read_Buffer_From_Size_Nal(OMX_BUFFERHEADERTYPE  *pBufHdr)
1999 {
2000     // NAL unit stream processing
2001     char temp_size[SIZE_NAL_FIELD_MAX];
2002     int i = 0;
2003     int j = 0;
2004     unsigned int size = 0;   // Need to make sure that uint32 has SIZE_NAL_FIELD_MAX (4) bytes
2005     unsigned int bytes_read = 0;
2006
2007     // read the "size_nal_field"-byte size field
2008     bytes_read = fread(pBufHdr->pBuffer + pBufHdr->nOffset, 1, nalSize, inputBufferFile);
2009     if (bytes_read == 0)
2010     {
2011       DEBUG_PRINT("Failed to read frame or it might be EOF\n");
2012       return 0;
2013     }
2014
2015     for (i=0; i<SIZE_NAL_FIELD_MAX-nalSize; i++)
2016     {
2017       temp_size[SIZE_NAL_FIELD_MAX - 1 - i] = 0;
2018     }
2019
2020     /* Due to little endiannes, Reorder the size based on size_nal_field */
2021     for (j=0; i<SIZE_NAL_FIELD_MAX; i++, j++)
2022     {
2023       temp_size[SIZE_NAL_FIELD_MAX - 1 - i] = pBufHdr->pBuffer[pBufHdr->nOffset + j];
2024     }
2025     size = (unsigned int)(*((unsigned int *)(temp_size)));
2026
2027     // now read the data
2028     bytes_read = fread(pBufHdr->pBuffer + pBufHdr->nOffset + nalSize, 1, size, inputBufferFile);
2029     if (bytes_read != size)
2030     {
2031       DEBUG_PRINT_ERROR("Failed to read frame\n");
2032     }
2033
2034     return bytes_read + nalSize;
2035 }
2036
2037 static int Read_Buffer_From_RCV_File_Seq_Layer(OMX_BUFFERHEADERTYPE  *pBufHdr)
2038 {
2039     unsigned int readOffset = 0, size_struct_C = 0;
2040     unsigned int startcode = 0;
2041     pBufHdr->nFilledLen = 0;
2042     pBufHdr->nFlags = 0;
2043
2044     DEBUG_PRINT("Inside %s \n", __FUNCTION__);
2045
2046     fread(&startcode, 4, 1, inputBufferFile);
2047
2048     /* read size of struct C as it need not be 4 always*/
2049     fread(&size_struct_C, 1, 4, inputBufferFile);
2050
2051     /* reseek to beginning of sequence header */
2052     fseek(inputBufferFile, -8, SEEK_CUR);
2053
2054     if ((startcode & 0xFF000000) == 0xC5000000)
2055     {
2056
2057       DEBUG_PRINT("Read_Buffer_From_RCV_File_Seq_Layer size_struct_C: %d\n", size_struct_C);
2058
2059       readOffset = fread(pBufHdr->pBuffer, 1, VC1_SEQ_LAYER_SIZE_WITHOUT_STRUCTC + size_struct_C, inputBufferFile);
2060     }
2061     else if((startcode & 0xFF000000) == 0x85000000)
2062     {
2063       // .RCV V1 file
2064
2065       rcv_v1 = 1;
2066
2067       DEBUG_PRINT("Read_Buffer_From_RCV_File_Seq_Layer size_struct_C: %d\n", size_struct_C);
2068
2069       readOffset = fread(pBufHdr->pBuffer, 1, VC1_SEQ_LAYER_SIZE_V1_WITHOUT_STRUCTC + size_struct_C, inputBufferFile);
2070     }
2071     else
2072     {
2073       DEBUG_PRINT_ERROR("Error: Unknown VC1 clip format %x\n", startcode);
2074     }
2075
2076 #if 0
2077     {
2078       int i=0;
2079       printf("Read_Buffer_From_RCV_File, length %d readOffset %d\n", readOffset, readOffset);
2080       for (i=0; i<36; i++)
2081       {
2082         printf("0x%.2x ", pBufHdr->pBuffer[i]);
2083         if (i%16 == 15) {
2084           printf("\n");
2085         }
2086       }
2087       printf("\n");
2088     }
2089 #endif
2090     return readOffset;
2091 }
2092
2093 static int Read_Buffer_From_RCV_File(OMX_BUFFERHEADERTYPE  *pBufHdr)
2094 {
2095     unsigned int readOffset = 0;
2096     unsigned int len = 0;
2097     unsigned int key = 0;
2098     DEBUG_PRINT("Inside %s \n", __FUNCTION__);
2099
2100     DEBUG_PRINT("Read_Buffer_From_RCV_File - nOffset %d\n", pBufHdr->nOffset);
2101     if(rcv_v1)
2102     {
2103       /* for the case of RCV V1 format, the frame header is only of 4 bytes and has
2104          only the frame size information */
2105       readOffset = fread(&len, 1, 4, inputBufferFile);
2106       DEBUG_PRINT("Read_Buffer_From_RCV_File - framesize %d %x\n", len, len);
2107
2108     }
2109     else
2110     {
2111       /* for a regular RCV file, 3 bytes comprise the frame size and 1 byte for key*/
2112       readOffset = fread(&len, 1, 3, inputBufferFile);
2113       DEBUG_PRINT("Read_Buffer_From_RCV_File - framesize %d %x\n", len, len);
2114
2115       readOffset = fread(&key, 1, 1, inputBufferFile);
2116       if ( (key & 0x80) == false)
2117       {
2118         DEBUG_PRINT("Read_Buffer_From_RCV_File - Non IDR frame key %x\n", key);
2119        }
2120
2121     }
2122
2123     if(!rcv_v1)
2124     {
2125       /* There is timestamp field only for regular RCV format and not for RCV V1 format*/
2126       readOffset = fread(&pBufHdr->nTimeStamp, 1, 4, inputBufferFile);
2127       DEBUG_PRINT("Read_Buffer_From_RCV_File - timeStamp %d\n", pBufHdr->nTimeStamp);
2128       pBufHdr->nTimeStamp *= 1000;
2129     }
2130     else
2131     {
2132         pBufHdr->nTimeStamp = timeStampLfile;
2133         timeStampLfile += timestampInterval;
2134     }
2135
2136     if(len > pBufHdr->nAllocLen)
2137     {
2138        DEBUG_PRINT_ERROR("Error in sufficient buffer framesize %d, allocalen %d noffset %d\n",len,pBufHdr->nAllocLen, pBufHdr->nOffset);
2139        readOffset = fread(pBufHdr->pBuffer+pBufHdr->nOffset, 1, pBufHdr->nAllocLen - pBufHdr->nOffset , inputBufferFile);
2140        fseek(inputBufferFile, len - readOffset,SEEK_CUR);
2141        return readOffset;
2142     }
2143     else
2144     readOffset = fread(pBufHdr->pBuffer+pBufHdr->nOffset, 1, len, inputBufferFile);
2145     if (readOffset != len)
2146     {
2147       DEBUG_PRINT("EOS reach or Reading error %d, %s \n", readOffset, strerror( errno ));
2148       return 0;
2149     }
2150
2151 #if 0
2152     {
2153       int i=0;
2154       printf("Read_Buffer_From_RCV_File, length %d readOffset %d\n", len, readOffset);
2155       for (i=0; i<64; i++)
2156       {
2157         printf("0x%.2x ", pBufHdr->pBuffer[i]);
2158         if (i%16 == 15) {
2159           printf("\n");
2160         }
2161       }
2162       printf("\n");
2163     }
2164 #endif
2165
2166     return readOffset;
2167 }
2168
2169 static int Read_Buffer_From_VC1_File(OMX_BUFFERHEADERTYPE  *pBufHdr)
2170 {
2171     static int timeStampLfile = 0;
2172     OMX_U8 *pBuffer = pBufHdr->pBuffer + pBufHdr->nOffset;
2173     DEBUG_PRINT("Inside %s \n", __FUNCTION__);
2174
2175     unsigned int readOffset = 0;
2176     int bytes_read = 0;
2177     unsigned int code = 0;
2178
2179     do
2180     {
2181       //Start codes are always byte aligned.
2182       bytes_read = fread(&pBuffer[readOffset],1, 1,inputBufferFile);
2183       if(!bytes_read)
2184       {
2185           DEBUG_PRINT("\n Bytes read Zero \n");
2186           break;
2187       }
2188       code <<= 8;
2189       code |= (0x000000FF & pBufHdr->pBuffer[readOffset]);
2190       //VOP start code comparision
2191       if (readOffset>3)
2192       {
2193         if (VC1_FRAME_START_CODE == (code & 0xFFFFFFFF))
2194         {
2195           //Seek backwards by 4
2196           fseek(inputBufferFile, -4, SEEK_CUR);
2197           readOffset-=3;
2198
2199           while(pBufHdr->pBuffer[readOffset-1] == 0)
2200             readOffset--;
2201
2202           break;
2203         }
2204       }
2205       readOffset++;
2206     }while (1);
2207
2208     pBufHdr->nTimeStamp = timeStampLfile;
2209     timeStampLfile += timestampInterval;
2210
2211 #if 0
2212     {
2213       int i=0;
2214       printf("Read_Buffer_From_VC1_File, readOffset %d\n", readOffset);
2215       for (i=0; i<64; i++)
2216       {
2217         printf("0x%.2x ", pBufHdr->pBuffer[i]);
2218         if (i%16 == 15) {
2219           printf("\n");
2220         }
2221       }
2222       printf("\n");
2223     }
2224 #endif
2225
2226     return readOffset;
2227 }
2228
2229 static int open_video_file ()
2230 {
2231     int error_code = 0;
2232     char outputfilename[512];
2233     DEBUG_PRINT("Inside %s filename=%s\n", __FUNCTION__, in_filename);
2234
2235     inputBufferFile = fopen (in_filename, "rb");
2236     if (inputBufferFile == NULL) {
2237         DEBUG_PRINT_ERROR("Error - i/p file %s could NOT be opened\n",
2238                           in_filename);
2239         error_code = -1;
2240     }
2241     else {
2242         DEBUG_PRINT("I/p file %s is opened \n", in_filename);
2243     }
2244
2245     if (takeYuvLog) {
2246         strcpy(outputfilename, "/data/misc/yuv");
2247         outputBufferFile = fopen (outputfilename, "ab");
2248         if (outputBufferFile == NULL)
2249         {
2250           DEBUG_PRINT_ERROR("ERROR - o/p file %s could NOT be opened\n", outputfilename);
2251           error_code = -1;
2252         }
2253         else
2254         {
2255           DEBUG_PRINT("O/p file %s is opened \n", outputfilename);
2256         }
2257     }
2258     return error_code;
2259 }
2260
2261 void swap_byte(char *pByte, int nbyte)
2262 {
2263   int i=0;
2264
2265   for (i=0; i<nbyte/2; i++)
2266   {
2267     pByte[i] ^= pByte[nbyte-i-1];
2268     pByte[nbyte-i-1] ^= pByte[i];
2269     pByte[i] ^= pByte[nbyte-i-1];
2270   }
2271 }
2272
2273 int drawBG(void)
2274 {
2275     int result;
2276     unsigned int i;
2277 #ifdef FRAMEBUFFER_32
2278     long * p;
2279 #else
2280     short * p;
2281 #endif
2282     void *fb_buf = mmap (NULL, finfo.smem_len,PROT_READ|PROT_WRITE, MAP_SHARED, fb_fd, 0);
2283
2284     if (fb_buf == MAP_FAILED)
2285     {
2286         printf("ERROR: Framebuffer MMAP failed!\n");
2287         close(fb_fd);
2288         return -1;
2289     }
2290
2291     vinfo.yoffset = 0;
2292     p = (long *)fb_buf;
2293
2294     for (i=0; i < vinfo.xres * vinfo.yres; i++)
2295     {
2296     #ifdef FRAMEBUFFER_32
2297         *p++ = COLOR_BLACK_RGBA_8888;
2298     #else
2299         *p++ = CLR_KEY;
2300     #endif
2301     }
2302
2303     if (ioctl(fb_fd, FBIOPAN_DISPLAY, &vinfo) < 0)
2304     {
2305         printf("ERROR: FBIOPAN_DISPLAY failed! line=%d\n", __LINE__);
2306         return -1;
2307     }
2308
2309     DEBUG_PRINT("drawBG success!\n");
2310     return 0;
2311 }
2312
2313 void render_fb(struct OMX_BUFFERHEADERTYPE *pBufHdr)
2314 {
2315     unsigned int addr = 0;
2316     OMX_OTHER_EXTRADATATYPE *pExtraData = 0;
2317     OMX_QCOM_EXTRADATA_FRAMEINFO *pExtraFrameInfo = 0;
2318     OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
2319     unsigned int destx, desty,destW, destH;
2320 #ifdef _ANDROID_
2321     MemoryHeapBase *vheap = NULL;
2322 #endif
2323
2324     unsigned int end = (unsigned int)(pBufHdr->pBuffer + pBufHdr->nAllocLen);
2325
2326     struct mdp_blit_req *e;
2327     union {
2328         char dummy[sizeof(struct mdp_blit_req_list) +
2329                sizeof(struct mdp_blit_req) * 1];
2330         struct mdp_blit_req_list list;
2331     } img;
2332
2333     if (fb_fd < 0)
2334     {
2335         DEBUG_PRINT_ERROR("Warning: /dev/fb0 is not opened!\n");
2336         return;
2337     }
2338
2339     img.list.count = 1;
2340     e = &img.list.req[0];
2341
2342     addr = (unsigned int)(pBufHdr->pBuffer + pBufHdr->nFilledLen);
2343     // align to a 4 byte boundary
2344     addr = (addr + 3) & (~3);
2345
2346     // read to the end of existing extra data sections
2347     pExtraData = (OMX_OTHER_EXTRADATATYPE*)addr;
2348
2349     while (addr < end && pExtraData->eType != (enum OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo)
2350     {
2351             addr += pExtraData->nSize;
2352             pExtraData = (OMX_OTHER_EXTRADATATYPE*)addr;
2353     }
2354
2355     if (pExtraData->eType != (enum OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo)
2356     {
2357        DEBUG_PRINT_ERROR("pExtraData->eType %d pExtraData->nSize %d\n",pExtraData->eType,pExtraData->nSize);
2358     }
2359     pExtraFrameInfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)pExtraData->data;
2360
2361    pPMEMInfo  = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
2362                 ((OMX_QCOM_PLATFORM_PRIVATE_LIST *)
2363                     pBufHdr->pPlatformPrivate)->entryList->entry;
2364 #ifdef _ANDROID_
2365     vheap = (MemoryHeapBase *)pPMEMInfo->pmem_fd;
2366 #endif
2367
2368
2369     DEBUG_PRINT_ERROR("DecWidth %d DecHeight %d\n",portFmt.format.video.nStride,portFmt.format.video.nSliceHeight);
2370     DEBUG_PRINT_ERROR("DispWidth %d DispHeight %d\n",portFmt.format.video.nFrameWidth,portFmt.format.video.nFrameHeight);
2371
2372
2373
2374     e->src.width = portFmt.format.video.nStride;
2375     e->src.height = portFmt.format.video.nSliceHeight;
2376     e->src.format = MDP_Y_CBCR_H2V2;
2377         e->src.offset = pPMEMInfo->offset;
2378 #ifdef _ANDROID_
2379     e->src.memory_id = vheap->getHeapID();
2380 #else
2381     e->src.memory_id = pPMEMInfo->pmem_fd;
2382 #endif
2383
2384     DEBUG_PRINT_ERROR("pmemOffset %d pmemID %d\n",e->src.offset,e->src.memory_id);
2385
2386     e->dst.width = vinfo.xres;
2387     e->dst.height = vinfo.yres;
2388     e->dst.format = MDP_RGB_565;
2389     e->dst.offset = 0;
2390     e->dst.memory_id = fb_fd;
2391
2392     e->transp_mask = 0xffffffff;
2393     DEBUG_PRINT("Frame interlace type %d!\n", pExtraFrameInfo->interlaceType);
2394     if(pExtraFrameInfo->interlaceType != OMX_QCOM_InterlaceFrameProgressive)
2395     {
2396        DEBUG_PRINT("Interlaced Frame!\n");
2397        e->flags = MDP_DEINTERLACE;
2398     }
2399     else
2400         e->flags = 0;
2401     e->alpha = 0xff;
2402
2403     switch(displayWindow)
2404     {
2405     case 1: destx = 0;
2406             desty = 0;
2407             destW = vinfo.xres/2;
2408             destH = vinfo.yres/2;
2409             break;
2410     case 2: destx = vinfo.xres/2;
2411             desty = 0;
2412             destW = vinfo.xres/2;
2413             destH = vinfo.yres/2;
2414             break;
2415
2416     case 3: destx = 0;
2417             desty = vinfo.yres/2;
2418             destW = vinfo.xres/2;
2419             destH = vinfo.yres/2;
2420             break;
2421      case 4: destx = vinfo.xres/2;
2422             desty = vinfo.yres/2;
2423             destW = vinfo.xres/2;
2424             destH = vinfo.yres/2;
2425             break;
2426      case 0:
2427      default:
2428             destx = 0;
2429             desty = 0;
2430             destW = vinfo.xres;
2431             destH = vinfo.yres;
2432     }
2433
2434
2435         if(portFmt.format.video.nFrameWidth < destW)
2436           destW = portFmt.format.video.nFrameWidth ;
2437
2438
2439         if(portFmt.format.video.nFrameHeight < destH)
2440            destH = portFmt.format.video.nFrameHeight;
2441
2442     e->dst_rect.x = destx;
2443     e->dst_rect.y = desty;
2444     e->dst_rect.w = destW;
2445     e->dst_rect.h = destH;
2446
2447     //e->dst_rect.w = 800;
2448     //e->dst_rect.h = 480;
2449
2450     e->src_rect.x = 0;
2451     e->src_rect.y = 0;
2452     e->src_rect.w = portFmt.format.video.nFrameWidth;
2453     e->src_rect.h = portFmt.format.video.nFrameHeight;
2454
2455     //e->src_rect.w = portFmt.format.video.nStride;
2456     //e->src_rect.h = portFmt.format.video.nSliceHeight;
2457
2458     if (ioctl(fb_fd, MSMFB_BLIT, &img)) {
2459         DEBUG_PRINT_ERROR("MSMFB_BLIT ioctl failed!\n");
2460         return;
2461     }
2462
2463     if (ioctl(fb_fd, FBIOPAN_DISPLAY, &vinfo) < 0) {
2464         DEBUG_PRINT_ERROR("FBIOPAN_DISPLAY failed! line=%d\n", __LINE__);
2465         return;
2466     }
2467
2468     DEBUG_PRINT("render_fb complete!\n");
2469 }
2470