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