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