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