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