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