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 /*============================================================================ 30 O p e n M A X w r a p p e r s 31 O p e n M A X C o r e 32 33 *//** @file omx_vdec.cpp 34 This module contains the implementation of the OpenMAX core & component. 35 36 *//*========================================================================*/ 37 38 ////////////////////////////////////////////////////////////////////////////// 39 // Include Files 40 ////////////////////////////////////////////////////////////////////////////// 41 42 #include <string.h> 43 #include <pthread.h> 44 #include <sys/prctl.h> 45 #include <stdlib.h> 46 #include <unistd.h> 47 #include <errno.h> 48 #include "omx_vdec.h" 49 #include <fcntl.h> 50 #include <limits.h> 51 #include <qdMetaData.h> 52 53 #ifndef _ANDROID_ 54 #include <sys/ioctl.h> 55 #include <sys/mman.h> 56 #endif //_ANDROID_ 57 58 #ifdef _ANDROID_ 59 #include <cutils/properties.h> 60 #undef USE_EGL_IMAGE_GPU 61 #endif 62 63 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) 64 #include <gralloc_priv.h> 65 #endif 66 67 #ifdef _ANDROID_ 68 #include "DivXDrmDecrypt.h" 69 #endif //_ANDROID_ 70 71 #ifdef USE_EGL_IMAGE_GPU 72 #include <EGL/egl.h> 73 #include <EGL/eglQCOM.h> 74 #define EGL_BUFFER_HANDLE_QCOM 0x4F00 75 #define EGL_BUFFER_OFFSET_QCOM 0x4F01 76 #endif 77 78 #ifdef INPUT_BUFFER_LOG 79 #define INPUT_BUFFER_FILE_NAME "/data/input-bitstream.\0\0\0\0" 80 #define INPUT_BUFFER_FILE_NAME_LEN 30 81 FILE *inputBufferFile1; 82 char inputfilename [INPUT_BUFFER_FILE_NAME_LEN] = "\0"; 83 #endif 84 #ifdef OUTPUT_BUFFER_LOG 85 FILE *outputBufferFile1; 86 char outputfilename [] = "/data/output.yuv"; 87 #endif 88 #ifdef OUTPUT_EXTRADATA_LOG 89 FILE *outputExtradataFile; 90 char ouputextradatafilename [] = "/data/extradata"; 91 #endif 92 93 #define DEFAULT_FPS 30 94 #define MAX_NUM_SPS 32 95 #define MAX_NUM_PPS 256 96 #define MAX_INPUT_ERROR (MAX_NUM_SPS + MAX_NUM_PPS) 97 #define MAX_SUPPORTED_FPS 120 98 99 #define VC1_SP_MP_START_CODE 0xC5000000 100 #define VC1_SP_MP_START_CODE_MASK 0xFF000000 101 #define VC1_AP_SEQ_START_CODE 0x0F010000 102 #define VC1_STRUCT_C_PROFILE_MASK 0xF0 103 #define VC1_STRUCT_B_LEVEL_MASK 0xE0000000 104 #define VC1_SIMPLE_PROFILE 0 105 #define VC1_MAIN_PROFILE 1 106 #define VC1_ADVANCE_PROFILE 3 107 #define VC1_SIMPLE_PROFILE_LOW_LEVEL 0 108 #define VC1_SIMPLE_PROFILE_MED_LEVEL 2 109 #define VC1_STRUCT_C_LEN 4 110 #define VC1_STRUCT_C_POS 8 111 #define VC1_STRUCT_A_POS 12 112 #define VC1_STRUCT_B_POS 24 113 #define VC1_SEQ_LAYER_SIZE 36 114 115 #ifdef USE_ION 116 #define MEM_DEVICE "/dev/ion" 117 #define MEM_HEAP_ID ION_CP_MM_HEAP_ID 118 #elif MAX_RES_720P 119 #define MEM_DEVICE "/dev/pmem_adsp" 120 #elif MAX_RES_1080P_EBI 121 #define MEM_DEVICE "/dev/pmem_adsp" 122 #elif MAX_RES_1080P 123 #define MEM_DEVICE "/dev/pmem_smipool" 124 #endif 125 126 /* 127 #ifdef _ANDROID_ 128 extern "C"{ 129 #include<utils/Log.h> 130 } 131 #endif//_ANDROID_ 132 */ 133 134 #undef DEBUG_PRINT_LOW 135 #undef DEBUG_PRINT_HIGH 136 #undef DEBUG_PRINT_ERROR 137 138 #define DEBUG_PRINT_LOW ALOGV 139 #define DEBUG_PRINT_HIGH ALOGV 140 #define DEBUG_PRINT_ERROR ALOGE 141 142 #ifndef _ANDROID_ 143 #include <glib.h> 144 #define strlcpy g_strlcpy 145 #endif 146 147 #define Log2(number, power) { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) && power < 16) { temp >>=0x1; power++; } } 148 #define Q16ToFraction(q,num,den) { OMX_U32 power; Log2(q,power); num = q >> power; den = 0x1 << (16 - power); } 149 150 bool omx_vdec::m_secure_display = false; 151 152 void* async_message_thread (void *input) 153 { 154 struct vdec_ioctl_msg ioctl_msg; 155 struct vdec_msginfo vdec_msg; 156 omx_vdec *omx = reinterpret_cast<omx_vdec*>(input); 157 int error_code = 0; 158 DEBUG_PRINT_HIGH("omx_vdec: Async thread start\n"); 159 prctl(PR_SET_NAME, (unsigned long)"VideoDecCallBackThread", 0, 0, 0); 160 while (1) 161 { 162 ioctl_msg.in = NULL; 163 ioctl_msg.out = (void*)&vdec_msg; 164 /*Wait for a message from the video decoder driver*/ 165 error_code = ioctl ( omx->drv_ctx.video_driver_fd,VDEC_IOCTL_GET_NEXT_MSG, 166 (void*)&ioctl_msg); 167 if (error_code == -512) // ERESTARTSYS 168 { 169 DEBUG_PRINT_ERROR("\n ERESTARTSYS received in ioctl read next msg!"); 170 } 171 else if (error_code < 0) 172 { 173 DEBUG_PRINT_ERROR("\n Error in ioctl read next msg"); 174 break; 175 } /*Call Instance specific process function*/ 176 else if (omx->async_message_process(input,&vdec_msg) < 0) 177 { 178 DEBUG_PRINT_ERROR("\nERROR:Wrong ioctl message"); 179 } 180 } 181 DEBUG_PRINT_HIGH("omx_vdec: Async thread stop\n"); 182 return NULL; 183 } 184 185 void* message_thread(void *input) 186 { 187 omx_vdec* omx = reinterpret_cast<omx_vdec*>(input); 188 unsigned char id; 189 int n; 190 191 DEBUG_PRINT_HIGH("omx_vdec: message thread start\n"); 192 prctl(PR_SET_NAME, (unsigned long)"VideoDecMsgThread", 0, 0, 0); 193 while (1) 194 { 195 196 n = read(omx->m_pipe_in, &id, 1); 197 198 if(0 == n) 199 { 200 break; 201 } 202 203 if (1 == n) 204 { 205 omx->process_event_cb(omx, id); 206 } 207 if ((n < 0) && (errno != EINTR)) 208 { 209 DEBUG_PRINT_ERROR("\nERROR: read from pipe failed, ret %d errno %d", n, errno); 210 break; 211 } 212 } 213 DEBUG_PRINT_HIGH("omx_vdec: message thread stop\n"); 214 return 0; 215 } 216 217 void post_message(omx_vdec *omx, unsigned char id) 218 { 219 int ret_value; 220 DEBUG_PRINT_LOW("omx_vdec: post_message %d pipe out%d\n", id,omx->m_pipe_out); 221 ret_value = write(omx->m_pipe_out, &id, 1); 222 DEBUG_PRINT_LOW("post_message to pipe done %d\n",ret_value); 223 } 224 225 // omx_cmd_queue destructor 226 omx_vdec::omx_cmd_queue::~omx_cmd_queue() 227 { 228 // Nothing to do 229 } 230 231 // omx cmd queue constructor 232 omx_vdec::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0) 233 { 234 memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE); 235 } 236 237 // omx cmd queue insert 238 bool omx_vdec::omx_cmd_queue::insert_entry(unsigned p1, unsigned p2, unsigned id) 239 { 240 bool ret = true; 241 if(m_size < OMX_CORE_CONTROL_CMDQ_SIZE) 242 { 243 m_q[m_write].id = id; 244 m_q[m_write].param1 = p1; 245 m_q[m_write].param2 = p2; 246 m_write++; 247 m_size ++; 248 if(m_write >= OMX_CORE_CONTROL_CMDQ_SIZE) 249 { 250 m_write = 0; 251 } 252 } 253 else 254 { 255 ret = false; 256 DEBUG_PRINT_ERROR("ERROR: %s()::Command Queue Full\n", __func__); 257 } 258 return ret; 259 } 260 261 // omx cmd queue pop 262 bool omx_vdec::omx_cmd_queue::pop_entry(unsigned *p1, unsigned *p2, unsigned *id) 263 { 264 bool ret = true; 265 if (m_size > 0) 266 { 267 *id = m_q[m_read].id; 268 *p1 = m_q[m_read].param1; 269 *p2 = m_q[m_read].param2; 270 // Move the read pointer ahead 271 ++m_read; 272 --m_size; 273 if(m_read >= OMX_CORE_CONTROL_CMDQ_SIZE) 274 { 275 m_read = 0; 276 } 277 } 278 else 279 { 280 ret = false; 281 } 282 return ret; 283 } 284 285 // Retrieve the first mesg type in the queue 286 unsigned omx_vdec::omx_cmd_queue::get_q_msg_type() 287 { 288 return m_q[m_read].id; 289 } 290 291 #ifdef _ANDROID_ 292 omx_vdec::ts_arr_list::ts_arr_list() 293 { 294 //initialize timestamps array 295 memset(m_ts_arr_list, 0, ( sizeof(ts_entry) * MAX_NUM_INPUT_OUTPUT_BUFFERS) ); 296 } 297 omx_vdec::ts_arr_list::~ts_arr_list() 298 { 299 //free m_ts_arr_list? 300 } 301 302 bool omx_vdec::ts_arr_list::insert_ts(OMX_TICKS ts) 303 { 304 bool ret = true; 305 bool duplicate_ts = false; 306 int idx = 0; 307 308 //insert at the first available empty location 309 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) 310 { 311 if (!m_ts_arr_list[idx].valid) 312 { 313 //found invalid or empty entry, save timestamp 314 m_ts_arr_list[idx].valid = true; 315 m_ts_arr_list[idx].timestamp = ts; 316 DEBUG_PRINT_LOW("Insert_ts(): Inserting TIMESTAMP (%lld) at idx (%d)", 317 ts, idx); 318 break; 319 } 320 } 321 322 if (idx == MAX_NUM_INPUT_OUTPUT_BUFFERS) 323 { 324 DEBUG_PRINT_LOW("Timestamp array list is FULL. Unsuccessful insert"); 325 ret = false; 326 } 327 return ret; 328 } 329 330 bool omx_vdec::ts_arr_list::pop_min_ts(OMX_TICKS &ts) 331 { 332 bool ret = true; 333 int min_idx = -1; 334 OMX_TICKS min_ts = 0; 335 int idx = 0; 336 337 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) 338 { 339 340 if (m_ts_arr_list[idx].valid) 341 { 342 //found valid entry, save index 343 if (min_idx < 0) 344 { 345 //first valid entry 346 min_ts = m_ts_arr_list[idx].timestamp; 347 min_idx = idx; 348 } 349 else if (m_ts_arr_list[idx].timestamp < min_ts) 350 { 351 min_ts = m_ts_arr_list[idx].timestamp; 352 min_idx = idx; 353 } 354 } 355 356 } 357 358 if (min_idx < 0) 359 { 360 //no valid entries found 361 DEBUG_PRINT_LOW("Timestamp array list is empty. Unsuccessful pop"); 362 ts = 0; 363 ret = false; 364 } 365 else 366 { 367 ts = m_ts_arr_list[min_idx].timestamp; 368 m_ts_arr_list[min_idx].valid = false; 369 DEBUG_PRINT_LOW("Pop_min_ts:Timestamp (%lld), index(%d)", 370 ts, min_idx); 371 } 372 373 return ret; 374 375 } 376 377 378 bool omx_vdec::ts_arr_list::reset_ts_list() 379 { 380 bool ret = true; 381 int idx = 0; 382 383 DEBUG_PRINT_LOW("reset_ts_list(): Resetting timestamp array list"); 384 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) 385 { 386 m_ts_arr_list[idx].valid = false; 387 } 388 return ret; 389 } 390 #endif 391 392 // factory function executed by the core to create instances 393 void *get_omx_component_factory_fn(void) 394 { 395 return (new omx_vdec); 396 } 397 398 #ifdef _ANDROID_ 399 #ifdef USE_ION 400 VideoHeap::VideoHeap(int devicefd, size_t size, void* base, 401 struct ion_handle *handle, int ionMapfd) 402 { 403 m_ion_device_fd = devicefd; 404 m_ion_handle = handle; 405 MemoryHeapBase::init(ionMapfd, base, size, 0, MEM_DEVICE); 406 //ionInit(devicefd, base, size, 0 , MEM_DEVICE,handle,ionMapfd); 407 } 408 #else 409 VideoHeap::VideoHeap(int fd, size_t size, void* base) 410 { 411 // dup file descriptor, map once, use pmem 412 init(dup(fd), base, size, 0 , MEM_DEVICE); 413 } 414 #endif 415 #endif // _ANDROID_ 416 /* ====================================================================== 417 FUNCTION 418 omx_vdec::omx_vdec 419 420 DESCRIPTION 421 Constructor 422 423 PARAMETERS 424 None 425 426 RETURN VALUE 427 None. 428 ========================================================================== */ 429 omx_vdec::omx_vdec(): m_state(OMX_StateInvalid), 430 m_app_data(NULL), 431 m_inp_mem_ptr(NULL), 432 m_out_mem_ptr(NULL), 433 m_phdr_pmem_ptr(NULL), 434 pending_input_buffers(0), 435 pending_output_buffers(0), 436 m_out_bm_count(0), 437 m_inp_bm_count(0), 438 m_inp_bPopulated(OMX_FALSE), 439 m_out_bPopulated(OMX_FALSE), 440 m_flags(0), 441 m_inp_bEnabled(OMX_TRUE), 442 m_out_bEnabled(OMX_TRUE), 443 m_platform_list(NULL), 444 m_platform_entry(NULL), 445 m_pmem_info(NULL), 446 output_flush_progress (false), 447 input_flush_progress (false), 448 input_use_buffer (false), 449 output_use_buffer (false), 450 arbitrary_bytes (true), 451 psource_frame (NULL), 452 pdest_frame (NULL), 453 m_inp_heap_ptr (NULL), 454 m_heap_inp_bm_count (0), 455 codec_type_parse ((codec_type)0), 456 first_frame_meta (true), 457 frame_count (0), 458 nal_length(0), 459 nal_count (0), 460 look_ahead_nal (false), 461 first_frame(0), 462 first_buffer(NULL), 463 first_frame_size (0), 464 m_error_propogated(false), 465 m_device_file_ptr(NULL), 466 m_vc1_profile((vc1_profile_type)0), 467 prev_ts(LLONG_MAX), 468 rst_prev_ts(true), 469 frm_int(0), 470 m_in_alloc_cnt(0), 471 m_display_id(NULL), 472 ouput_egl_buffers(false), 473 h264_parser(NULL), 474 client_extradata(0), 475 h264_last_au_ts(LLONG_MAX), 476 h264_last_au_flags(0), 477 m_inp_err_count(0), 478 #ifdef _ANDROID_ 479 m_heap_ptr(NULL), 480 m_heap_count(0), 481 m_enable_android_native_buffers(OMX_FALSE), 482 m_use_android_native_buffers(OMX_FALSE), 483 #endif 484 in_reconfig(false), 485 m_use_output_pmem(OMX_FALSE), 486 m_out_mem_region_smi(OMX_FALSE), 487 m_out_pvt_entry_pmem(OMX_FALSE), 488 secure_mode(false) 489 #ifdef _ANDROID_ 490 ,iDivXDrmDecrypt(NULL) 491 #endif 492 ,m_desc_buffer_ptr(NULL) 493 ,m_extradata(NULL) 494 ,m_use_smoothstreaming(false) 495 { 496 /* Assumption is that , to begin with , we have all the frames with decoder */ 497 DEBUG_PRINT_HIGH("In OMX vdec Constructor"); 498 #ifdef _ANDROID_ 499 char property_value[PROPERTY_VALUE_MAX] = {0}; 500 property_get("vidc.dec.debug.perf", property_value, "0"); 501 perf_flag = atoi(property_value); 502 if (perf_flag) 503 { 504 DEBUG_PRINT_HIGH("vidc.dec.debug.perf is %d", perf_flag); 505 dec_time.start(); 506 proc_frms = latency = 0; 507 } 508 property_value[0] = NULL; 509 property_get("vidc.dec.debug.ts", property_value, "0"); 510 m_debug_timestamp = atoi(property_value); 511 DEBUG_PRINT_HIGH("vidc.dec.debug.ts value is %d",m_debug_timestamp); 512 if (m_debug_timestamp) 513 { 514 time_stamp_dts.set_timestamp_reorder_mode(true); 515 time_stamp_dts.enable_debug_print(true); 516 } 517 518 property_value[0] = NULL; 519 property_get("vidc.dec.debug.concealedmb", property_value, "0"); 520 m_debug_concealedmb = atoi(property_value); 521 DEBUG_PRINT_HIGH("vidc.dec.debug.concealedmb value is %d",m_debug_concealedmb); 522 523 #endif 524 memset(&m_cmp,0,sizeof(m_cmp)); 525 memset(&m_cb,0,sizeof(m_cb)); 526 memset (&drv_ctx,0,sizeof(drv_ctx)); 527 memset (&h264_scratch,0,sizeof (OMX_BUFFERHEADERTYPE)); 528 memset (m_hwdevice_name,0,sizeof(m_hwdevice_name)); 529 memset(&op_buf_rcnfg, 0 ,sizeof(vdec_allocatorproperty)); 530 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) ); 531 m_demux_entries = 0; 532 drv_ctx.timestamp_adjust = false; 533 drv_ctx.video_driver_fd = -1; 534 m_vendor_config.pData = NULL; 535 pthread_mutex_init(&m_lock, NULL); 536 sem_init(&m_cmd_lock,0,0); 537 #ifdef _ANDROID_ 538 char extradata_value[PROPERTY_VALUE_MAX] = {0}; 539 property_get("vidc.dec.debug.extradata", extradata_value, "0"); 540 m_debug_extradata = atoi(extradata_value); 541 DEBUG_PRINT_HIGH("vidc.dec.debug.extradata value is %d",m_debug_extradata); 542 #endif 543 m_fill_output_msg = OMX_COMPONENT_GENERATE_FTB; 544 client_buffers.set_vdec_client(this); 545 memset(native_buffer, 0, sizeof(native_buffer)); 546 } 547 548 549 /* ====================================================================== 550 FUNCTION 551 omx_vdec::~omx_vdec 552 553 DESCRIPTION 554 Destructor 555 556 PARAMETERS 557 None 558 559 RETURN VALUE 560 None. 561 ========================================================================== */ 562 omx_vdec::~omx_vdec() 563 { 564 m_pmem_info = NULL; 565 DEBUG_PRINT_HIGH("In OMX vdec Destructor"); 566 if(m_pipe_in) close(m_pipe_in); 567 if(m_pipe_out) close(m_pipe_out); 568 m_pipe_in = -1; 569 m_pipe_out = -1; 570 DEBUG_PRINT_HIGH("Waiting on OMX Msg Thread exit"); 571 pthread_join(msg_thread_id,NULL); 572 DEBUG_PRINT_HIGH("Waiting on OMX Async Thread exit"); 573 pthread_join(async_thread_id,NULL); 574 pthread_mutex_destroy(&m_lock); 575 sem_destroy(&m_cmd_lock); 576 #ifdef _ANDROID_ 577 if (perf_flag) 578 { 579 DEBUG_PRINT_HIGH("--> TOTAL PROCESSING TIME"); 580 dec_time.end(); 581 } 582 #endif /* _ANDROID_ */ 583 DEBUG_PRINT_HIGH("Exit OMX vdec Destructor"); 584 } 585 586 /* ====================================================================== 587 FUNCTION 588 omx_vdec::OMXCntrlProcessMsgCb 589 590 DESCRIPTION 591 IL Client callbacks are generated through this routine. The decoder 592 provides the thread context for this routine. 593 594 PARAMETERS 595 ctxt -- Context information related to the self. 596 id -- Event identifier. This could be any of the following: 597 1. Command completion event 598 2. Buffer done callback event 599 3. Frame done callback event 600 601 RETURN VALUE 602 None. 603 604 ========================================================================== */ 605 void omx_vdec::process_event_cb(void *ctxt, unsigned char id) 606 { 607 unsigned p1; // Parameter - 1 608 unsigned p2; // Parameter - 2 609 unsigned ident; 610 unsigned qsize=0; // qsize 611 omx_vdec *pThis = (omx_vdec *) ctxt; 612 613 if(!pThis) 614 { 615 DEBUG_PRINT_ERROR("ERROR: %s()::Context is incorrect, bailing out\n", 616 __func__); 617 return; 618 } 619 620 // Protect the shared queue data structure 621 do 622 { 623 /*Read the message id's from the queue*/ 624 pthread_mutex_lock(&pThis->m_lock); 625 qsize = pThis->m_cmd_q.m_size; 626 if(qsize) 627 { 628 pThis->m_cmd_q.pop_entry(&p1,&p2,&ident); 629 } 630 631 if (qsize == 0 && pThis->m_state != OMX_StatePause) 632 { 633 qsize = pThis->m_ftb_q.m_size; 634 if (qsize) 635 { 636 pThis->m_ftb_q.pop_entry(&p1,&p2,&ident); 637 } 638 } 639 640 if (qsize == 0 && pThis->m_state != OMX_StatePause) 641 { 642 qsize = pThis->m_etb_q.m_size; 643 if (qsize) 644 { 645 pThis->m_etb_q.pop_entry(&p1,&p2,&ident); 646 } 647 } 648 pthread_mutex_unlock(&pThis->m_lock); 649 650 /*process message if we have one*/ 651 if(qsize > 0) 652 { 653 id = ident; 654 switch (id) 655 { 656 case OMX_COMPONENT_GENERATE_EVENT: 657 if (pThis->m_cb.EventHandler) 658 { 659 switch (p1) 660 { 661 case OMX_CommandStateSet: 662 pThis->m_state = (OMX_STATETYPE) p2; 663 DEBUG_PRINT_HIGH("\n OMX_CommandStateSet complete, m_state = %d", 664 pThis->m_state); 665 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 666 OMX_EventCmdComplete, p1, p2, NULL); 667 break; 668 669 case OMX_EventError: 670 if(p2 == OMX_StateInvalid) 671 { 672 DEBUG_PRINT_ERROR("\n OMX_EventError: p2 is OMX_StateInvalid"); 673 pThis->m_state = (OMX_STATETYPE) p2; 674 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 675 OMX_EventError, OMX_ErrorInvalidState, p2, NULL); 676 } 677 else if (p2 == OMX_ErrorHardware) 678 { 679 pThis->omx_report_error(); 680 } 681 else 682 { 683 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 684 OMX_EventError, p2, NULL, NULL ); 685 } 686 break; 687 688 case OMX_CommandPortDisable: 689 DEBUG_PRINT_HIGH("\n OMX_CommandPortDisable complete for port [%d]", p2); 690 if (BITMASK_PRESENT(&pThis->m_flags, 691 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) 692 { 693 BITMASK_SET(&pThis->m_flags, OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED); 694 break; 695 } 696 if (p2 == OMX_CORE_OUTPUT_PORT_INDEX && pThis->in_reconfig) 697 { 698 pThis->in_reconfig = false; 699 pThis->drv_ctx.op_buf = pThis->op_buf_rcnfg; 700 OMX_ERRORTYPE eRet = pThis->set_buffer_req(&pThis->drv_ctx.op_buf); 701 if(eRet != OMX_ErrorNone) 702 { 703 DEBUG_PRINT_ERROR("set_buffer_req failed eRet = %d",eRet); 704 pThis->omx_report_error(); 705 break; 706 } 707 } 708 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 709 OMX_EventCmdComplete, p1, p2, NULL ); 710 break; 711 case OMX_CommandPortEnable: 712 DEBUG_PRINT_HIGH("\n OMX_CommandPortEnable complete for port [%d]", p2); 713 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,\ 714 OMX_EventCmdComplete, p1, p2, NULL ); 715 break; 716 717 default: 718 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 719 OMX_EventCmdComplete, p1, p2, NULL ); 720 break; 721 722 } 723 } 724 else 725 { 726 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL\n", __func__); 727 } 728 break; 729 case OMX_COMPONENT_GENERATE_ETB_ARBITRARY: 730 if (pThis->empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\ 731 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) 732 { 733 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure"); 734 pThis->omx_report_error (); 735 } 736 break; 737 case OMX_COMPONENT_GENERATE_ETB: 738 if (pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\ 739 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) 740 { 741 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure"); 742 pThis->omx_report_error (); 743 } 744 break; 745 746 case OMX_COMPONENT_GENERATE_FTB: 747 if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\ 748 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) 749 { 750 DEBUG_PRINT_ERROR("\n fill_this_buffer_proxy failure"); 751 pThis->omx_report_error (); 752 } 753 break; 754 755 case OMX_COMPONENT_GENERATE_COMMAND: 756 pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\ 757 (OMX_U32)p2,(OMX_PTR)NULL); 758 break; 759 760 case OMX_COMPONENT_GENERATE_EBD: 761 762 if (p2 != VDEC_S_SUCCESS && p2 != VDEC_S_INPUT_BITSTREAM_ERR) 763 { 764 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EBD failure"); 765 pThis->omx_report_error (); 766 } 767 else 768 { 769 if (p2 == VDEC_S_INPUT_BITSTREAM_ERR && p1) 770 { 771 pThis->m_inp_err_count++; 772 pThis->time_stamp_dts.remove_time_stamp( 773 ((OMX_BUFFERHEADERTYPE *)p1)->nTimeStamp, 774 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive) 775 ?true:false); 776 } 777 else 778 { 779 pThis->m_inp_err_count = 0; 780 } 781 if ( pThis->empty_buffer_done(&pThis->m_cmp, 782 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) 783 { 784 DEBUG_PRINT_ERROR("\n empty_buffer_done failure"); 785 pThis->omx_report_error (); 786 } 787 if(!pThis->arbitrary_bytes && pThis->m_inp_err_count > MAX_INPUT_ERROR) 788 { 789 DEBUG_PRINT_ERROR("\n Input bitstream error for consecutive %d frames.", MAX_INPUT_ERROR); 790 pThis->omx_report_error (); 791 } 792 } 793 break; 794 case OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED: 795 { 796 int64_t *timestamp = (int64_t *)p1; 797 if (p1) 798 { 799 pThis->time_stamp_dts.remove_time_stamp(*timestamp, 800 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive) 801 ?true:false); 802 free(timestamp); 803 } 804 } 805 break; 806 case OMX_COMPONENT_GENERATE_FBD: 807 if (p2 != VDEC_S_SUCCESS) 808 { 809 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_FBD failure"); 810 pThis->omx_report_error (); 811 } 812 else if ( pThis->fill_buffer_done(&pThis->m_cmp, 813 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) 814 { 815 DEBUG_PRINT_ERROR("\n fill_buffer_done failure"); 816 pThis->omx_report_error (); 817 } 818 break; 819 820 case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH: 821 DEBUG_PRINT_HIGH("\n Driver flush i/p Port complete"); 822 if (!pThis->input_flush_progress) 823 { 824 DEBUG_PRINT_ERROR("\n WARNING: Unexpected flush from driver"); 825 } 826 else 827 { 828 pThis->execute_input_flush(); 829 if (pThis->m_cb.EventHandler) 830 { 831 if (p2 != VDEC_S_SUCCESS) 832 { 833 DEBUG_PRINT_ERROR("\nOMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH failure"); 834 pThis->omx_report_error (); 835 } 836 else 837 { 838 /*Check if we need generate event for Flush done*/ 839 if(BITMASK_PRESENT(&pThis->m_flags, 840 OMX_COMPONENT_INPUT_FLUSH_PENDING)) 841 { 842 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING); 843 DEBUG_PRINT_LOW("\n Input Flush completed - Notify Client"); 844 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 845 OMX_EventCmdComplete,OMX_CommandFlush, 846 OMX_CORE_INPUT_PORT_INDEX,NULL ); 847 } 848 if (BITMASK_PRESENT(&pThis->m_flags, 849 OMX_COMPONENT_IDLE_PENDING)) 850 { 851 if (!pThis->output_flush_progress) 852 { 853 DEBUG_PRINT_LOW("\n Output flush done hence issue stop"); 854 if (ioctl (pThis->drv_ctx.video_driver_fd, 855 VDEC_IOCTL_CMD_STOP,NULL ) < 0) 856 { 857 DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_STOP failed"); 858 pThis->omx_report_error (); 859 } 860 } 861 } 862 } 863 } 864 else 865 { 866 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); 867 } 868 } 869 break; 870 871 case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH: 872 DEBUG_PRINT_HIGH("\n Driver flush o/p Port complete"); 873 if (!pThis->output_flush_progress) 874 { 875 DEBUG_PRINT_ERROR("\n WARNING: Unexpected flush from driver"); 876 } 877 else 878 { 879 pThis->execute_output_flush(); 880 if (pThis->m_cb.EventHandler) 881 { 882 if (p2 != VDEC_S_SUCCESS) 883 { 884 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH failed"); 885 pThis->omx_report_error (); 886 } 887 else 888 { 889 /*Check if we need generate event for Flush done*/ 890 if(BITMASK_PRESENT(&pThis->m_flags, 891 OMX_COMPONENT_OUTPUT_FLUSH_PENDING)) 892 { 893 DEBUG_PRINT_LOW("\n Notify Output Flush done"); 894 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING); 895 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 896 OMX_EventCmdComplete,OMX_CommandFlush, 897 OMX_CORE_OUTPUT_PORT_INDEX,NULL ); 898 } 899 if(BITMASK_PRESENT(&pThis->m_flags, 900 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) 901 { 902 DEBUG_PRINT_LOW("\n Internal flush complete"); 903 BITMASK_CLEAR (&pThis->m_flags, 904 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING); 905 if (BITMASK_PRESENT(&pThis->m_flags, 906 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED)) 907 { 908 pThis->post_event(OMX_CommandPortDisable, 909 OMX_CORE_OUTPUT_PORT_INDEX, 910 OMX_COMPONENT_GENERATE_EVENT); 911 BITMASK_CLEAR (&pThis->m_flags, 912 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED); 913 914 } 915 } 916 917 if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING)) 918 { 919 if (!pThis->input_flush_progress) 920 { 921 DEBUG_PRINT_LOW("\n Input flush done hence issue stop"); 922 if (ioctl (pThis->drv_ctx.video_driver_fd, 923 VDEC_IOCTL_CMD_STOP,NULL ) < 0) 924 { 925 DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_STOP failed"); 926 pThis->omx_report_error (); 927 } 928 } 929 } 930 } 931 } 932 else 933 { 934 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); 935 } 936 } 937 break; 938 939 case OMX_COMPONENT_GENERATE_START_DONE: 940 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_START_DONE"); 941 942 if (pThis->m_cb.EventHandler) 943 { 944 if (p2 != VDEC_S_SUCCESS) 945 { 946 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_START_DONE Failure"); 947 pThis->omx_report_error (); 948 } 949 else 950 { 951 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE Success"); 952 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) 953 { 954 DEBUG_PRINT_LOW("\n Move to executing"); 955 // Send the callback now 956 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING); 957 pThis->m_state = OMX_StateExecuting; 958 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 959 OMX_EventCmdComplete,OMX_CommandStateSet, 960 OMX_StateExecuting, NULL); 961 } 962 else if (BITMASK_PRESENT(&pThis->m_flags, 963 OMX_COMPONENT_PAUSE_PENDING)) 964 { 965 if (ioctl (pThis->drv_ctx.video_driver_fd, 966 VDEC_IOCTL_CMD_PAUSE,NULL ) < 0) 967 { 968 DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_PAUSE failed"); 969 pThis->omx_report_error (); 970 } 971 } 972 } 973 } 974 else 975 { 976 DEBUG_PRINT_LOW("\n Event Handler callback is NULL"); 977 } 978 break; 979 980 case OMX_COMPONENT_GENERATE_PAUSE_DONE: 981 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_PAUSE_DONE"); 982 if (pThis->m_cb.EventHandler) 983 { 984 if (p2 != VDEC_S_SUCCESS) 985 { 986 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_PAUSE_DONE ret failed"); 987 pThis->omx_report_error (); 988 } 989 else 990 { 991 pThis->complete_pending_buffer_done_cbs(); 992 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING)) 993 { 994 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_PAUSE_DONE nofity"); 995 //Send the callback now 996 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING); 997 pThis->m_state = OMX_StatePause; 998 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 999 OMX_EventCmdComplete,OMX_CommandStateSet, 1000 OMX_StatePause, NULL); 1001 } 1002 } 1003 } 1004 else 1005 { 1006 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); 1007 } 1008 1009 break; 1010 1011 case OMX_COMPONENT_GENERATE_RESUME_DONE: 1012 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_RESUME_DONE"); 1013 if (pThis->m_cb.EventHandler) 1014 { 1015 if (p2 != VDEC_S_SUCCESS) 1016 { 1017 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_RESUME_DONE failed"); 1018 pThis->omx_report_error (); 1019 } 1020 else 1021 { 1022 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) 1023 { 1024 DEBUG_PRINT_LOW("\n Moving the decoder to execute state"); 1025 // Send the callback now 1026 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING); 1027 pThis->m_state = OMX_StateExecuting; 1028 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 1029 OMX_EventCmdComplete,OMX_CommandStateSet, 1030 OMX_StateExecuting,NULL); 1031 } 1032 } 1033 } 1034 else 1035 { 1036 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); 1037 } 1038 1039 break; 1040 1041 case OMX_COMPONENT_GENERATE_STOP_DONE: 1042 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_STOP_DONE"); 1043 if (pThis->m_cb.EventHandler) 1044 { 1045 if (p2 != VDEC_S_SUCCESS) 1046 { 1047 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_STOP_DONE ret failed"); 1048 pThis->omx_report_error (); 1049 } 1050 else 1051 { 1052 pThis->complete_pending_buffer_done_cbs(); 1053 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING)) 1054 { 1055 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_STOP_DONE Success"); 1056 // Send the callback now 1057 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING); 1058 pThis->m_state = OMX_StateIdle; 1059 DEBUG_PRINT_LOW("\n Move to Idle State"); 1060 pThis->m_cb.EventHandler(&pThis->m_cmp,pThis->m_app_data, 1061 OMX_EventCmdComplete,OMX_CommandStateSet, 1062 OMX_StateIdle,NULL); 1063 } 1064 } 1065 } 1066 else 1067 { 1068 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); 1069 } 1070 1071 break; 1072 1073 case OMX_COMPONENT_GENERATE_PORT_RECONFIG: 1074 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_PORT_RECONFIG"); 1075 if (p2 == OMX_IndexParamPortDefinition && (pThis->start_port_reconfig() != OMX_ErrorNone)) 1076 pThis->omx_report_error(); 1077 else 1078 { 1079 if (pThis->m_cb.EventHandler) { 1080 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 1081 OMX_EventPortSettingsChanged, p1, p2, NULL ); 1082 } else { 1083 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); 1084 } 1085 if (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive) 1086 { 1087 OMX_INTERLACETYPE format = (OMX_INTERLACETYPE)-1; 1088 OMX_EVENTTYPE event = (OMX_EVENTTYPE)OMX_EventIndexsettingChanged; 1089 if (pThis->drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst) 1090 format = OMX_InterlaceInterleaveFrameTopFieldFirst; 1091 else if (pThis->drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst) 1092 format = OMX_InterlaceInterleaveFrameBottomFieldFirst; 1093 else //unsupported interlace format; raise a error 1094 event = OMX_EventError; 1095 if (pThis->m_cb.EventHandler) { 1096 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 1097 event, format, 0, NULL ); 1098 } else { 1099 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); 1100 } 1101 } 1102 } 1103 break; 1104 1105 case OMX_COMPONENT_GENERATE_EOS_DONE: 1106 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_EOS_DONE"); 1107 if (pThis->m_cb.EventHandler) { 1108 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, OMX_EventBufferFlag, 1109 OMX_CORE_OUTPUT_PORT_INDEX, OMX_BUFFERFLAG_EOS, NULL ); 1110 } else { 1111 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); 1112 } 1113 pThis->prev_ts = LLONG_MAX; 1114 pThis->rst_prev_ts = true; 1115 break; 1116 1117 case OMX_COMPONENT_GENERATE_HARDWARE_ERROR: 1118 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_HARDWARE_ERROR"); 1119 pThis->omx_report_error (); 1120 break; 1121 1122 default: 1123 break; 1124 } 1125 } 1126 pthread_mutex_lock(&pThis->m_lock); 1127 qsize = pThis->m_cmd_q.m_size; 1128 if (pThis->m_state != OMX_StatePause) 1129 qsize += (pThis->m_ftb_q.m_size + pThis->m_etb_q.m_size); 1130 pthread_mutex_unlock(&pThis->m_lock); 1131 } 1132 while(qsize>0); 1133 1134 } 1135 1136 void omx_vdec::update_resolution(int width, int height) 1137 { 1138 drv_ctx.video_resolution.frame_height = height; 1139 drv_ctx.video_resolution.frame_width = width; 1140 drv_ctx.video_resolution.scan_lines = height; 1141 drv_ctx.video_resolution.stride = width; 1142 rectangle.nLeft = 0; 1143 rectangle.nTop = 0; 1144 rectangle.nWidth = drv_ctx.video_resolution.frame_width; 1145 rectangle.nHeight = drv_ctx.video_resolution.frame_height; 1146 } 1147 1148 /* ====================================================================== 1149 FUNCTION 1150 omx_vdec::ComponentInit 1151 1152 DESCRIPTION 1153 Initialize the component. 1154 1155 PARAMETERS 1156 ctxt -- Context information related to the self. 1157 id -- Event identifier. This could be any of the following: 1158 1. Command completion event 1159 2. Buffer done callback event 1160 3. Frame done callback event 1161 1162 RETURN VALUE 1163 None. 1164 1165 ========================================================================== */ 1166 OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role) 1167 { 1168 1169 OMX_ERRORTYPE eRet = OMX_ErrorNone; 1170 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; 1171 unsigned int alignment = 0,buffer_size = 0; 1172 int fds[2]; 1173 int r; 1174 OMX_STRING device_name = "/dev/msm_vidc_dec"; 1175 1176 if(!strncmp(role, "OMX.qcom.video.decoder.avc.smoothstreaming",OMX_MAX_STRINGNAME_SIZE)){ 1177 ALOGI("smooth streaming role"); 1178 m_use_smoothstreaming = true; 1179 role = "OMX.qcom.video.decoder.avc"; 1180 } 1181 if(!strncmp(role, "OMX.qcom.video.decoder.avc.smoothstreaming.secure",OMX_MAX_STRINGNAME_SIZE)){ 1182 ALOGI("secure smooth streaming role"); 1183 m_use_smoothstreaming = true; 1184 role = "OMX.qcom.video.decoder.avc.secure"; 1185 } 1186 1187 if(!strncmp(role, "OMX.qcom.video.decoder.avc.secure",OMX_MAX_STRINGNAME_SIZE)){ 1188 secure_mode = true; 1189 arbitrary_bytes = false; 1190 role = "OMX.qcom.video.decoder.avc"; 1191 device_name = "/dev/msm_vidc_dec_sec"; 1192 } 1193 1194 if (secure_mode) { 1195 if (secureDisplay(qService::IQService::START) < 0) { 1196 DEBUG_PRINT_HIGH("Sending message to start securing display failed"); 1197 } 1198 } 1199 1200 DEBUG_PRINT_HIGH("\n omx_vdec::component_init(): Start of New Playback : role = %s : DEVICE = %s", 1201 role, device_name); 1202 1203 drv_ctx.video_driver_fd = open(device_name, O_RDWR | O_NONBLOCK); 1204 1205 DEBUG_PRINT_HIGH("\n omx_vdec::component_init(): Open returned fd %d, errno %d", 1206 drv_ctx.video_driver_fd, errno); 1207 1208 if(drv_ctx.video_driver_fd == 0){ 1209 drv_ctx.video_driver_fd = open(device_name, O_RDWR | O_NONBLOCK); 1210 } 1211 1212 if(drv_ctx.video_driver_fd < 0) 1213 { 1214 DEBUG_PRINT_ERROR("Omx_vdec::Comp Init Returning failure, errno %d\n", errno); 1215 eRet = OMX_ErrorInsufficientResources; 1216 goto cleanup; 1217 } 1218 drv_ctx.frame_rate.fps_numerator = DEFAULT_FPS; 1219 drv_ctx.frame_rate.fps_denominator = 1; 1220 1221 1222 #ifdef INPUT_BUFFER_LOG 1223 strcpy(inputfilename, INPUT_BUFFER_FILE_NAME); 1224 #endif 1225 #ifdef OUTPUT_BUFFER_LOG 1226 outputBufferFile1 = fopen (outputfilename, "ab"); 1227 #endif 1228 #ifdef OUTPUT_EXTRADATA_LOG 1229 outputExtradataFile = fopen (ouputextradatafilename, "ab"); 1230 #endif 1231 1232 // Copy the role information which provides the decoder kind 1233 strlcpy(drv_ctx.kind,role,128); 1234 if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4",\ 1235 OMX_MAX_STRINGNAME_SIZE)) 1236 { 1237 strlcpy((char *)m_cRole, "video_decoder.mpeg4",\ 1238 OMX_MAX_STRINGNAME_SIZE); 1239 drv_ctx.timestamp_adjust = true; 1240 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG4; 1241 eCompressionFormat = OMX_VIDEO_CodingMPEG4; 1242 /*Initialize Start Code for MPEG4*/ 1243 codec_type_parse = CODEC_TYPE_MPEG4; 1244 m_frame_parser.init_start_codes (codec_type_parse); 1245 #ifdef INPUT_BUFFER_LOG 1246 strcat(inputfilename, "m4v"); 1247 #endif 1248 } 1249 else if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2",\ 1250 OMX_MAX_STRINGNAME_SIZE)) 1251 { 1252 strlcpy((char *)m_cRole, "video_decoder.mpeg2",\ 1253 OMX_MAX_STRINGNAME_SIZE); 1254 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG2; 1255 eCompressionFormat = OMX_VIDEO_CodingMPEG2; 1256 /*Initialize Start Code for MPEG2*/ 1257 codec_type_parse = CODEC_TYPE_MPEG2; 1258 m_frame_parser.init_start_codes (codec_type_parse); 1259 #ifdef INPUT_BUFFER_LOG 1260 strcat(inputfilename, "mpg"); 1261 #endif 1262 } 1263 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",\ 1264 OMX_MAX_STRINGNAME_SIZE)) 1265 { 1266 strlcpy((char *)m_cRole, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE); 1267 DEBUG_PRINT_LOW("\n H263 Decoder selected"); 1268 drv_ctx.decoder_format = VDEC_CODECTYPE_H263; 1269 eCompressionFormat = OMX_VIDEO_CodingH263; 1270 codec_type_parse = CODEC_TYPE_H263; 1271 m_frame_parser.init_start_codes (codec_type_parse); 1272 #ifdef INPUT_BUFFER_LOG 1273 strcat(inputfilename, "263"); 1274 #endif 1275 } 1276 #ifdef MAX_RES_1080P 1277 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",\ 1278 OMX_MAX_STRINGNAME_SIZE)) 1279 { 1280 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); 1281 DEBUG_PRINT_LOW ("\n DIVX 311 Decoder selected"); 1282 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_3; 1283 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx; 1284 codec_type_parse = CODEC_TYPE_DIVX; 1285 m_frame_parser.init_start_codes (codec_type_parse); 1286 #ifdef _ANDROID_ 1287 OMX_ERRORTYPE err = createDivxDrmContext(); 1288 if( err != OMX_ErrorNone ) { 1289 DEBUG_PRINT_ERROR("createDivxDrmContext Failed"); 1290 eRet = err; 1291 goto cleanup; 1292 } 1293 #endif //_ANDROID_ 1294 } 1295 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4",\ 1296 OMX_MAX_STRINGNAME_SIZE)) 1297 { 1298 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); 1299 DEBUG_PRINT_ERROR ("\n DIVX 4 Decoder selected"); 1300 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_4; 1301 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx; 1302 codec_type_parse = CODEC_TYPE_DIVX; 1303 m_frame_parser.init_start_codes (codec_type_parse); 1304 #ifdef _ANDROID_ 1305 OMX_ERRORTYPE err = createDivxDrmContext(); 1306 if( err != OMX_ErrorNone ) { 1307 DEBUG_PRINT_ERROR("createDivxDrmContext Failed"); 1308 eRet = err; 1309 goto cleanup; 1310 } 1311 #endif //_ANDROID_ 1312 } 1313 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",\ 1314 OMX_MAX_STRINGNAME_SIZE)) 1315 { 1316 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); 1317 DEBUG_PRINT_ERROR ("\n DIVX 5/6 Decoder selected"); 1318 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_6; 1319 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx; 1320 codec_type_parse = CODEC_TYPE_DIVX; 1321 m_frame_parser.init_start_codes (codec_type_parse); 1322 #ifdef _ANDROID_ 1323 OMX_ERRORTYPE err = createDivxDrmContext(); 1324 if( err != OMX_ErrorNone ) { 1325 DEBUG_PRINT_ERROR("createDivxDrmContext Failed"); 1326 eRet = err; 1327 goto cleanup; 1328 } 1329 #endif //_ANDROID_ 1330 } 1331 #else 1332 else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4",\ 1333 OMX_MAX_STRINGNAME_SIZE)) || (!strncmp(drv_ctx.kind, \ 1334 "OMX.qcom.video.decoder.divx", OMX_MAX_STRINGNAME_SIZE))) 1335 { 1336 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); 1337 DEBUG_PRINT_ERROR ("\n DIVX Decoder selected"); 1338 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_5; 1339 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx; 1340 codec_type_parse = CODEC_TYPE_DIVX; 1341 m_frame_parser.init_start_codes (codec_type_parse); 1342 1343 #ifdef _ANDROID_ 1344 OMX_ERRORTYPE err = createDivxDrmContext(); 1345 if( err != OMX_ErrorNone ) { 1346 DEBUG_PRINT_ERROR("createDivxDrmContext Failed"); 1347 eRet = err; 1348 goto cleanup; 1349 } 1350 #endif //_ANDROID_ 1351 } 1352 #endif 1353 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",\ 1354 OMX_MAX_STRINGNAME_SIZE)) 1355 { 1356 strlcpy((char *)m_cRole, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE); 1357 drv_ctx.decoder_format = VDEC_CODECTYPE_H264; 1358 eCompressionFormat = OMX_VIDEO_CodingAVC; 1359 codec_type_parse = CODEC_TYPE_H264; 1360 m_frame_parser.init_start_codes (codec_type_parse); 1361 m_frame_parser.init_nal_length(nal_length); 1362 #ifdef INPUT_BUFFER_LOG 1363 strcat(inputfilename, "264"); 1364 #endif 1365 } 1366 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",\ 1367 OMX_MAX_STRINGNAME_SIZE)) 1368 { 1369 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE); 1370 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1; 1371 eCompressionFormat = OMX_VIDEO_CodingWMV; 1372 codec_type_parse = CODEC_TYPE_VC1; 1373 m_frame_parser.init_start_codes (codec_type_parse); 1374 #ifdef INPUT_BUFFER_LOG 1375 strcat(inputfilename, "vc1"); 1376 #endif 1377 } 1378 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",\ 1379 OMX_MAX_STRINGNAME_SIZE)) 1380 { 1381 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE); 1382 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1_RCV; 1383 eCompressionFormat = OMX_VIDEO_CodingWMV; 1384 codec_type_parse = CODEC_TYPE_VC1; 1385 m_frame_parser.init_start_codes (codec_type_parse); 1386 #ifdef INPUT_BUFFER_LOG 1387 strcat(inputfilename, "vc1"); 1388 #endif 1389 } 1390 else 1391 { 1392 DEBUG_PRINT_ERROR("\nERROR:Unknown Component\n"); 1393 eRet = OMX_ErrorInvalidComponentName; 1394 } 1395 #ifdef INPUT_BUFFER_LOG 1396 inputBufferFile1 = fopen (inputfilename, "ab"); 1397 #endif 1398 if (eRet == OMX_ErrorNone) 1399 { 1400 #ifdef MAX_RES_720P 1401 drv_ctx.output_format = VDEC_YUV_FORMAT_NV12; 1402 1403 #endif 1404 #ifdef MAX_RES_1080P 1405 drv_ctx.output_format = VDEC_YUV_FORMAT_TILE_4x2; 1406 OMX_COLOR_FORMATTYPE dest_color_format = (OMX_COLOR_FORMATTYPE) 1407 QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka; 1408 if (!client_buffers.set_color_format(dest_color_format)) { 1409 DEBUG_PRINT_ERROR("\n Setting color format failed"); 1410 eRet = OMX_ErrorInsufficientResources; 1411 } 1412 #endif 1413 /*Initialize Decoder with codec type and resolution*/ 1414 ioctl_msg.in = &drv_ctx.decoder_format; 1415 ioctl_msg.out = NULL; 1416 1417 if ( (eRet == OMX_ErrorNone) && 1418 ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_SET_CODEC, 1419 (void*)&ioctl_msg) < 0) 1420 1421 { 1422 DEBUG_PRINT_ERROR("\n Set codec type failed"); 1423 eRet = OMX_ErrorInsufficientResources; 1424 } 1425 1426 /*Set the output format*/ 1427 ioctl_msg.in = &drv_ctx.output_format; 1428 ioctl_msg.out = NULL; 1429 1430 if ( (eRet == OMX_ErrorNone) && 1431 ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_SET_OUTPUT_FORMAT, 1432 (void*)&ioctl_msg) < 0) 1433 { 1434 DEBUG_PRINT_ERROR("\n Set output format failed"); 1435 eRet = OMX_ErrorInsufficientResources; 1436 } 1437 1438 if (m_use_smoothstreaming) { 1439 int rc = ioctl(drv_ctx.video_driver_fd, 1440 VDEC_IOCTL_SET_CONT_ON_RECONFIG); 1441 if(rc < 0) { 1442 DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver."); 1443 } 1444 } 1445 1446 #ifdef MAX_RES_720P 1447 update_resolution(1280, 720); 1448 #endif 1449 #ifdef MAX_RES_1080P 1450 update_resolution(1920, 1088); 1451 #endif 1452 1453 ioctl_msg.in = &drv_ctx.video_resolution; 1454 ioctl_msg.out = NULL; 1455 1456 if ( (eRet == OMX_ErrorNone) && 1457 ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_SET_PICRES, 1458 (void*)&ioctl_msg) < 0) 1459 { 1460 DEBUG_PRINT_ERROR("\n Set Resolution failed"); 1461 eRet = OMX_ErrorInsufficientResources; 1462 } 1463 1464 /*Get the Buffer requirements for input and output ports*/ 1465 drv_ctx.ip_buf.buffer_type = VDEC_BUFFER_TYPE_INPUT; 1466 drv_ctx.op_buf.buffer_type = VDEC_BUFFER_TYPE_OUTPUT; 1467 drv_ctx.interlace = VDEC_InterlaceFrameProgressive; 1468 drv_ctx.extradata = 0; 1469 drv_ctx.picture_order = VDEC_ORDER_DISPLAY; 1470 drv_ctx.idr_only_decoding = 0; 1471 1472 if (eRet == OMX_ErrorNone) 1473 eRet = get_buffer_req(&drv_ctx.ip_buf); 1474 if (eRet == OMX_ErrorNone) 1475 eRet = get_buffer_req(&drv_ctx.op_buf); 1476 m_state = OMX_StateLoaded; 1477 #ifdef DEFAULT_EXTRADATA 1478 if (eRet == OMX_ErrorNone && !secure_mode) 1479 eRet = enable_extradata(DEFAULT_EXTRADATA); 1480 #endif 1481 if ( (codec_type_parse == CODEC_TYPE_VC1) || 1482 (codec_type_parse == CODEC_TYPE_H264)) //add CP check here 1483 { 1484 //Check if dmx can be disabled 1485 struct vdec_ioctl_msg ioctl_msg = {NULL, NULL}; 1486 OMX_ERRORTYPE eRet = OMX_ErrorNone; 1487 ioctl_msg.out = &drv_ctx.disable_dmx; 1488 if (ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_GET_DISABLE_DMX_SUPPORT, &ioctl_msg)) 1489 { 1490 DEBUG_PRINT_ERROR("Error VDEC_IOCTL_GET_DISABLE_DMX_SUPPORT"); 1491 eRet = OMX_ErrorHardware; 1492 } 1493 else 1494 { 1495 if (drv_ctx.disable_dmx && !secure_mode) 1496 { 1497 DEBUG_PRINT_HIGH("DMX disable is supported"); 1498 1499 int rc = ioctl(drv_ctx.video_driver_fd, 1500 VDEC_IOCTL_SET_DISABLE_DMX); 1501 if(rc < 0) { 1502 DEBUG_PRINT_ERROR("Failed to disable dmx on driver."); 1503 drv_ctx.disable_dmx = false; 1504 eRet = OMX_ErrorHardware; 1505 } 1506 } 1507 else { 1508 drv_ctx.disable_dmx = false; 1509 } 1510 } 1511 } 1512 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) 1513 { 1514 if (m_frame_parser.mutils == NULL) 1515 { 1516 m_frame_parser.mutils = new H264_Utils(); 1517 1518 if (m_frame_parser.mutils == NULL) 1519 { 1520 DEBUG_PRINT_ERROR("\n parser utils Allocation failed "); 1521 eRet = OMX_ErrorInsufficientResources; 1522 } 1523 else 1524 { 1525 h264_scratch.nAllocLen = drv_ctx.ip_buf.buffer_size; 1526 h264_scratch.pBuffer = (OMX_U8 *)malloc (drv_ctx.ip_buf.buffer_size); 1527 h264_scratch.nFilledLen = 0; 1528 h264_scratch.nOffset = 0; 1529 1530 if (h264_scratch.pBuffer == NULL) 1531 { 1532 DEBUG_PRINT_ERROR("\n h264_scratch.pBuffer Allocation failed "); 1533 return OMX_ErrorInsufficientResources; 1534 } 1535 m_frame_parser.mutils->initialize_frame_checking_environment(); 1536 m_frame_parser.mutils->allocate_rbsp_buffer (drv_ctx.ip_buf.buffer_size); 1537 } 1538 } 1539 1540 h264_parser = new h264_stream_parser(); 1541 if (!h264_parser) 1542 { 1543 DEBUG_PRINT_ERROR("ERROR: H264 parser allocation failed!"); 1544 eRet = OMX_ErrorInsufficientResources; 1545 } 1546 } 1547 1548 if(pipe(fds)) 1549 { 1550 DEBUG_PRINT_ERROR("pipe creation failed\n"); 1551 eRet = OMX_ErrorInsufficientResources; 1552 } 1553 else 1554 { 1555 int temp1[2]; 1556 if(fds[0] == 0 || fds[1] == 0) 1557 { 1558 if (pipe (temp1)) 1559 { 1560 DEBUG_PRINT_ERROR("pipe creation failed\n"); 1561 return OMX_ErrorInsufficientResources; 1562 } 1563 //close (fds[0]); 1564 //close (fds[1]); 1565 fds[0] = temp1 [0]; 1566 fds[1] = temp1 [1]; 1567 } 1568 m_pipe_in = fds[0]; 1569 m_pipe_out = fds[1]; 1570 r = pthread_create(&msg_thread_id,0,message_thread,this); 1571 1572 if(r < 0) 1573 { 1574 DEBUG_PRINT_ERROR("\n component_init(): message_thread creation failed"); 1575 eRet = OMX_ErrorInsufficientResources; 1576 } 1577 else 1578 { 1579 r = pthread_create(&async_thread_id,0,async_message_thread,this); 1580 if(r < 0) 1581 { 1582 DEBUG_PRINT_ERROR("\n component_init(): async_message_thread creation failed"); 1583 eRet = OMX_ErrorInsufficientResources; 1584 } 1585 } 1586 } 1587 } 1588 1589 if (eRet != OMX_ErrorNone) 1590 { 1591 DEBUG_PRINT_ERROR("\n Component Init Failed"); 1592 DEBUG_PRINT_HIGH("\n Calling VDEC_IOCTL_STOP_NEXT_MSG"); 1593 (void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG, 1594 NULL); 1595 DEBUG_PRINT_HIGH("\n Calling close() on Video Driver"); 1596 close (drv_ctx.video_driver_fd); 1597 drv_ctx.video_driver_fd = -1; 1598 } 1599 else 1600 { 1601 DEBUG_PRINT_HIGH("\n omx_vdec::component_init() success"); 1602 } 1603 1604 memset(&h264_mv_buff,0,sizeof(struct h264_mv_buffer)); 1605 1606 cleanup: 1607 1608 if (secure_mode && (eRet == OMX_ErrorNone)) { 1609 if (secureDisplay(qService::IQService::END) < 0) { 1610 DEBUG_PRINT_HIGH("sending message to stop securing display failed"); 1611 } 1612 } 1613 1614 return eRet; 1615 } 1616 1617 /* ====================================================================== 1618 FUNCTION 1619 omx_vdec::GetComponentVersion 1620 1621 DESCRIPTION 1622 Returns the component version. 1623 1624 PARAMETERS 1625 TBD. 1626 1627 RETURN VALUE 1628 OMX_ErrorNone. 1629 1630 ========================================================================== */ 1631 OMX_ERRORTYPE omx_vdec::get_component_version 1632 ( 1633 OMX_IN OMX_HANDLETYPE hComp, 1634 OMX_OUT OMX_STRING componentName, 1635 OMX_OUT OMX_VERSIONTYPE* componentVersion, 1636 OMX_OUT OMX_VERSIONTYPE* specVersion, 1637 OMX_OUT OMX_UUIDTYPE* componentUUID 1638 ) 1639 { 1640 if(m_state == OMX_StateInvalid) 1641 { 1642 DEBUG_PRINT_ERROR("Get Comp Version in Invalid State\n"); 1643 return OMX_ErrorInvalidState; 1644 } 1645 /* TBD -- Return the proper version */ 1646 if (specVersion) 1647 { 1648 specVersion->nVersion = OMX_SPEC_VERSION; 1649 } 1650 return OMX_ErrorNone; 1651 } 1652 /* ====================================================================== 1653 FUNCTION 1654 omx_vdec::SendCommand 1655 1656 DESCRIPTION 1657 Returns zero if all the buffers released.. 1658 1659 PARAMETERS 1660 None. 1661 1662 RETURN VALUE 1663 true/false 1664 1665 ========================================================================== */ 1666 OMX_ERRORTYPE omx_vdec::send_command(OMX_IN OMX_HANDLETYPE hComp, 1667 OMX_IN OMX_COMMANDTYPE cmd, 1668 OMX_IN OMX_U32 param1, 1669 OMX_IN OMX_PTR cmdData 1670 ) 1671 { 1672 DEBUG_PRINT_LOW("\n send_command: Recieved a Command from Client"); 1673 if(m_state == OMX_StateInvalid) 1674 { 1675 DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State\n"); 1676 return OMX_ErrorInvalidState; 1677 } 1678 if (cmd == OMX_CommandFlush && param1 != OMX_CORE_INPUT_PORT_INDEX 1679 && param1 != OMX_CORE_OUTPUT_PORT_INDEX && param1 != OMX_ALL) 1680 { 1681 DEBUG_PRINT_ERROR("\n send_command(): ERROR OMX_CommandFlush " 1682 "to invalid port: %d", param1); 1683 return OMX_ErrorBadPortIndex; 1684 } 1685 post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND); 1686 sem_wait(&m_cmd_lock); 1687 DEBUG_PRINT_LOW("\n send_command: Command Processed\n"); 1688 return OMX_ErrorNone; 1689 } 1690 1691 /* ====================================================================== 1692 FUNCTION 1693 omx_vdec::SendCommand 1694 1695 DESCRIPTION 1696 Returns zero if all the buffers released.. 1697 1698 PARAMETERS 1699 None. 1700 1701 RETURN VALUE 1702 true/false 1703 1704 ========================================================================== */ 1705 OMX_ERRORTYPE omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp, 1706 OMX_IN OMX_COMMANDTYPE cmd, 1707 OMX_IN OMX_U32 param1, 1708 OMX_IN OMX_PTR cmdData 1709 ) 1710 { 1711 OMX_ERRORTYPE eRet = OMX_ErrorNone; 1712 OMX_STATETYPE eState = (OMX_STATETYPE) param1; 1713 int bFlag = 1,sem_posted = 0; 1714 1715 DEBUG_PRINT_LOW("\n send_command_proxy(): cmd = %d", cmd); 1716 DEBUG_PRINT_HIGH("\n send_command_proxy(): Current State %d, Expected State %d", 1717 m_state, eState); 1718 1719 if(cmd == OMX_CommandStateSet) 1720 { 1721 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandStateSet issued"); 1722 DEBUG_PRINT_HIGH("\n Current State %d, Expected State %d", m_state, eState); 1723 /***************************/ 1724 /* Current State is Loaded */ 1725 /***************************/ 1726 if(m_state == OMX_StateLoaded) 1727 { 1728 if(eState == OMX_StateIdle) 1729 { 1730 //if all buffers are allocated or all ports disabled 1731 if(allocate_done() || 1732 (m_inp_bEnabled == OMX_FALSE && m_out_bEnabled == OMX_FALSE)) 1733 { 1734 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle\n"); 1735 } 1736 else 1737 { 1738 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle-Pending\n"); 1739 BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING); 1740 // Skip the event notification 1741 bFlag = 0; 1742 } 1743 } 1744 /* Requesting transition from Loaded to Loaded */ 1745 else if(eState == OMX_StateLoaded) 1746 { 1747 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Loaded\n"); 1748 post_event(OMX_EventError,OMX_ErrorSameState,\ 1749 OMX_COMPONENT_GENERATE_EVENT); 1750 eRet = OMX_ErrorSameState; 1751 } 1752 /* Requesting transition from Loaded to WaitForResources */ 1753 else if(eState == OMX_StateWaitForResources) 1754 { 1755 /* Since error is None , we will post an event 1756 at the end of this function definition */ 1757 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->WaitForResources\n"); 1758 } 1759 /* Requesting transition from Loaded to Executing */ 1760 else if(eState == OMX_StateExecuting) 1761 { 1762 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Executing\n"); 1763 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 1764 OMX_COMPONENT_GENERATE_EVENT); 1765 eRet = OMX_ErrorIncorrectStateTransition; 1766 } 1767 /* Requesting transition from Loaded to Pause */ 1768 else if(eState == OMX_StatePause) 1769 { 1770 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Pause\n"); 1771 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 1772 OMX_COMPONENT_GENERATE_EVENT); 1773 eRet = OMX_ErrorIncorrectStateTransition; 1774 } 1775 /* Requesting transition from Loaded to Invalid */ 1776 else if(eState == OMX_StateInvalid) 1777 { 1778 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid\n"); 1779 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); 1780 eRet = OMX_ErrorInvalidState; 1781 } 1782 else 1783 { 1784 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)\n",\ 1785 eState); 1786 eRet = OMX_ErrorBadParameter; 1787 } 1788 } 1789 1790 /***************************/ 1791 /* Current State is IDLE */ 1792 /***************************/ 1793 else if(m_state == OMX_StateIdle) 1794 { 1795 if(eState == OMX_StateLoaded) 1796 { 1797 if(release_done()) 1798 { 1799 /* 1800 Since error is None , we will post an event at the end 1801 of this function definition 1802 */ 1803 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded\n"); 1804 } 1805 else 1806 { 1807 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded-Pending\n"); 1808 BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING); 1809 // Skip the event notification 1810 bFlag = 0; 1811 } 1812 } 1813 /* Requesting transition from Idle to Executing */ 1814 else if(eState == OMX_StateExecuting) 1815 { 1816 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n"); 1817 BITMASK_SET(&m_flags, OMX_COMPONENT_EXECUTE_PENDING); 1818 bFlag = 0; 1819 if (ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_START, 1820 NULL) < 0) 1821 { 1822 DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_START FAILED"); 1823 omx_report_error (); 1824 eRet = OMX_ErrorHardware; 1825 } 1826 } 1827 /* Requesting transition from Idle to Idle */ 1828 else if(eState == OMX_StateIdle) 1829 { 1830 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle\n"); 1831 post_event(OMX_EventError,OMX_ErrorSameState,\ 1832 OMX_COMPONENT_GENERATE_EVENT); 1833 eRet = OMX_ErrorSameState; 1834 } 1835 /* Requesting transition from Idle to WaitForResources */ 1836 else if(eState == OMX_StateWaitForResources) 1837 { 1838 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->WaitForResources\n"); 1839 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 1840 OMX_COMPONENT_GENERATE_EVENT); 1841 eRet = OMX_ErrorIncorrectStateTransition; 1842 } 1843 /* Requesting transition from Idle to Pause */ 1844 else if(eState == OMX_StatePause) 1845 { 1846 /*To pause the Video core we need to start the driver*/ 1847 if (ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_START, 1848 NULL) < 0) 1849 { 1850 DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_START FAILED"); 1851 omx_report_error (); 1852 eRet = OMX_ErrorHardware; 1853 } 1854 else 1855 { 1856 BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING); 1857 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Pause\n"); 1858 bFlag = 0; 1859 } 1860 } 1861 /* Requesting transition from Idle to Invalid */ 1862 else if(eState == OMX_StateInvalid) 1863 { 1864 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid\n"); 1865 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); 1866 eRet = OMX_ErrorInvalidState; 1867 } 1868 else 1869 { 1870 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled\n",eState); 1871 eRet = OMX_ErrorBadParameter; 1872 } 1873 } 1874 1875 /******************************/ 1876 /* Current State is Executing */ 1877 /******************************/ 1878 else if(m_state == OMX_StateExecuting) 1879 { 1880 DEBUG_PRINT_LOW("\n Command Recieved in OMX_StateExecuting"); 1881 /* Requesting transition from Executing to Idle */ 1882 if(eState == OMX_StateIdle) 1883 { 1884 /* Since error is None , we will post an event 1885 at the end of this function definition 1886 */ 1887 DEBUG_PRINT_LOW("\n send_command_proxy(): Executing --> Idle \n"); 1888 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING); 1889 if(!sem_posted) 1890 { 1891 sem_posted = 1; 1892 sem_post (&m_cmd_lock); 1893 execute_omx_flush(OMX_ALL); 1894 } 1895 bFlag = 0; 1896 } 1897 /* Requesting transition from Executing to Paused */ 1898 else if(eState == OMX_StatePause) 1899 { 1900 DEBUG_PRINT_LOW("\n PAUSE Command Issued"); 1901 if (ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_PAUSE, 1902 NULL) < 0) 1903 { 1904 DEBUG_PRINT_ERROR("\n Error In Pause State"); 1905 post_event(OMX_EventError,OMX_ErrorHardware,\ 1906 OMX_COMPONENT_GENERATE_EVENT); 1907 eRet = OMX_ErrorHardware; 1908 } 1909 else 1910 { 1911 BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING); 1912 DEBUG_PRINT_LOW("send_command_proxy(): Executing-->Pause\n"); 1913 bFlag = 0; 1914 } 1915 } 1916 /* Requesting transition from Executing to Loaded */ 1917 else if(eState == OMX_StateLoaded) 1918 { 1919 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Loaded \n"); 1920 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 1921 OMX_COMPONENT_GENERATE_EVENT); 1922 eRet = OMX_ErrorIncorrectStateTransition; 1923 } 1924 /* Requesting transition from Executing to WaitForResources */ 1925 else if(eState == OMX_StateWaitForResources) 1926 { 1927 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> WaitForResources \n"); 1928 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 1929 OMX_COMPONENT_GENERATE_EVENT); 1930 eRet = OMX_ErrorIncorrectStateTransition; 1931 } 1932 /* Requesting transition from Executing to Executing */ 1933 else if(eState == OMX_StateExecuting) 1934 { 1935 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Executing \n"); 1936 post_event(OMX_EventError,OMX_ErrorSameState,\ 1937 OMX_COMPONENT_GENERATE_EVENT); 1938 eRet = OMX_ErrorSameState; 1939 } 1940 /* Requesting transition from Executing to Invalid */ 1941 else if(eState == OMX_StateInvalid) 1942 { 1943 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Invalid \n"); 1944 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); 1945 eRet = OMX_ErrorInvalidState; 1946 } 1947 else 1948 { 1949 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled\n",eState); 1950 eRet = OMX_ErrorBadParameter; 1951 } 1952 } 1953 /***************************/ 1954 /* Current State is Pause */ 1955 /***************************/ 1956 else if(m_state == OMX_StatePause) 1957 { 1958 /* Requesting transition from Pause to Executing */ 1959 if(eState == OMX_StateExecuting) 1960 { 1961 DEBUG_PRINT_LOW("\n Pause --> Executing \n"); 1962 if (ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_RESUME, 1963 NULL) < 0) 1964 { 1965 DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_RESUME failed"); 1966 post_event(OMX_EventError,OMX_ErrorHardware,\ 1967 OMX_COMPONENT_GENERATE_EVENT); 1968 eRet = OMX_ErrorHardware; 1969 } 1970 else 1971 { 1972 BITMASK_SET(&m_flags,OMX_COMPONENT_EXECUTE_PENDING); 1973 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n"); 1974 post_event (NULL,VDEC_S_SUCCESS,\ 1975 OMX_COMPONENT_GENERATE_RESUME_DONE); 1976 bFlag = 0; 1977 } 1978 } 1979 /* Requesting transition from Pause to Idle */ 1980 else if(eState == OMX_StateIdle) 1981 { 1982 /* Since error is None , we will post an event 1983 at the end of this function definition */ 1984 DEBUG_PRINT_LOW("\n Pause --> Idle \n"); 1985 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING); 1986 if(!sem_posted) 1987 { 1988 sem_posted = 1; 1989 sem_post (&m_cmd_lock); 1990 execute_omx_flush(OMX_ALL); 1991 } 1992 bFlag = 0; 1993 } 1994 /* Requesting transition from Pause to loaded */ 1995 else if(eState == OMX_StateLoaded) 1996 { 1997 DEBUG_PRINT_ERROR("\n Pause --> loaded \n"); 1998 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 1999 OMX_COMPONENT_GENERATE_EVENT); 2000 eRet = OMX_ErrorIncorrectStateTransition; 2001 } 2002 /* Requesting transition from Pause to WaitForResources */ 2003 else if(eState == OMX_StateWaitForResources) 2004 { 2005 DEBUG_PRINT_ERROR("\n Pause --> WaitForResources \n"); 2006 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 2007 OMX_COMPONENT_GENERATE_EVENT); 2008 eRet = OMX_ErrorIncorrectStateTransition; 2009 } 2010 /* Requesting transition from Pause to Pause */ 2011 else if(eState == OMX_StatePause) 2012 { 2013 DEBUG_PRINT_ERROR("\n Pause --> Pause \n"); 2014 post_event(OMX_EventError,OMX_ErrorSameState,\ 2015 OMX_COMPONENT_GENERATE_EVENT); 2016 eRet = OMX_ErrorSameState; 2017 } 2018 /* Requesting transition from Pause to Invalid */ 2019 else if(eState == OMX_StateInvalid) 2020 { 2021 DEBUG_PRINT_ERROR("\n Pause --> Invalid \n"); 2022 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); 2023 eRet = OMX_ErrorInvalidState; 2024 } 2025 else 2026 { 2027 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled\n",eState); 2028 eRet = OMX_ErrorBadParameter; 2029 } 2030 } 2031 /***************************/ 2032 /* Current State is WaitForResources */ 2033 /***************************/ 2034 else if(m_state == OMX_StateWaitForResources) 2035 { 2036 /* Requesting transition from WaitForResources to Loaded */ 2037 if(eState == OMX_StateLoaded) 2038 { 2039 /* Since error is None , we will post an event 2040 at the end of this function definition */ 2041 DEBUG_PRINT_LOW("send_command_proxy(): WaitForResources-->Loaded\n"); 2042 } 2043 /* Requesting transition from WaitForResources to WaitForResources */ 2044 else if (eState == OMX_StateWaitForResources) 2045 { 2046 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources\n"); 2047 post_event(OMX_EventError,OMX_ErrorSameState, 2048 OMX_COMPONENT_GENERATE_EVENT); 2049 eRet = OMX_ErrorSameState; 2050 } 2051 /* Requesting transition from WaitForResources to Executing */ 2052 else if(eState == OMX_StateExecuting) 2053 { 2054 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Executing\n"); 2055 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 2056 OMX_COMPONENT_GENERATE_EVENT); 2057 eRet = OMX_ErrorIncorrectStateTransition; 2058 } 2059 /* Requesting transition from WaitForResources to Pause */ 2060 else if(eState == OMX_StatePause) 2061 { 2062 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Pause\n"); 2063 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 2064 OMX_COMPONENT_GENERATE_EVENT); 2065 eRet = OMX_ErrorIncorrectStateTransition; 2066 } 2067 /* Requesting transition from WaitForResources to Invalid */ 2068 else if(eState == OMX_StateInvalid) 2069 { 2070 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Invalid\n"); 2071 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); 2072 eRet = OMX_ErrorInvalidState; 2073 } 2074 /* Requesting transition from WaitForResources to Loaded - 2075 is NOT tested by Khronos TS */ 2076 2077 } 2078 else 2079 { 2080 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)\n",m_state,eState); 2081 eRet = OMX_ErrorBadParameter; 2082 } 2083 } 2084 /********************************/ 2085 /* Current State is Invalid */ 2086 /*******************************/ 2087 else if(m_state == OMX_StateInvalid) 2088 { 2089 /* State Transition from Inavlid to any state */ 2090 if(eState == (OMX_StateLoaded || OMX_StateWaitForResources 2091 || OMX_StateIdle || OMX_StateExecuting 2092 || OMX_StatePause || OMX_StateInvalid)) 2093 { 2094 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Invalid -->Loaded\n"); 2095 post_event(OMX_EventError,OMX_ErrorInvalidState,\ 2096 OMX_COMPONENT_GENERATE_EVENT); 2097 eRet = OMX_ErrorInvalidState; 2098 } 2099 } 2100 else if (cmd == OMX_CommandFlush) 2101 { 2102 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandFlush issued" 2103 "with param1: %d", param1); 2104 if(OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1) 2105 { 2106 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING); 2107 } 2108 if(OMX_CORE_OUTPUT_PORT_INDEX == param1 || OMX_ALL == param1) 2109 { 2110 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING); 2111 } 2112 if (!sem_posted){ 2113 sem_posted = 1; 2114 DEBUG_PRINT_LOW("\n Set the Semaphore"); 2115 sem_post (&m_cmd_lock); 2116 execute_omx_flush(param1); 2117 } 2118 bFlag = 0; 2119 } 2120 else if ( cmd == OMX_CommandPortEnable) 2121 { 2122 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandPortEnable issued" 2123 "with param1: %d", param1); 2124 if(param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) 2125 { 2126 m_inp_bEnabled = OMX_TRUE; 2127 2128 if( (m_state == OMX_StateLoaded && 2129 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) 2130 || allocate_input_done()) 2131 { 2132 post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX, 2133 OMX_COMPONENT_GENERATE_EVENT); 2134 } 2135 else 2136 { 2137 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending\n"); 2138 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING); 2139 // Skip the event notification 2140 bFlag = 0; 2141 } 2142 } 2143 if(param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) 2144 { 2145 DEBUG_PRINT_LOW("\n Enable output Port command recieved"); 2146 m_out_bEnabled = OMX_TRUE; 2147 2148 if( (m_state == OMX_StateLoaded && 2149 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) 2150 || (allocate_output_done())) 2151 { 2152 post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX, 2153 OMX_COMPONENT_GENERATE_EVENT); 2154 2155 } 2156 else 2157 { 2158 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending\n"); 2159 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING); 2160 // Skip the event notification 2161 bFlag = 0; 2162 } 2163 } 2164 } 2165 else if (cmd == OMX_CommandPortDisable) 2166 { 2167 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandPortDisable issued" 2168 "with param1: %d", param1); 2169 if(param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) 2170 { 2171 m_inp_bEnabled = OMX_FALSE; 2172 if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle) 2173 && release_input_done()) 2174 { 2175 post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX, 2176 OMX_COMPONENT_GENERATE_EVENT); 2177 } 2178 else 2179 { 2180 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING); 2181 if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting) 2182 { 2183 if(!sem_posted) 2184 { 2185 sem_posted = 1; 2186 sem_post (&m_cmd_lock); 2187 } 2188 execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX); 2189 } 2190 2191 // Skip the event notification 2192 bFlag = 0; 2193 } 2194 } 2195 if(param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) 2196 { 2197 m_out_bEnabled = OMX_FALSE; 2198 DEBUG_PRINT_LOW("\n Disable output Port command recieved"); 2199 if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle) 2200 && release_output_done()) 2201 { 2202 post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\ 2203 OMX_COMPONENT_GENERATE_EVENT); 2204 } 2205 else 2206 { 2207 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING); 2208 if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting) 2209 { 2210 if (!sem_posted) 2211 { 2212 sem_posted = 1; 2213 sem_post (&m_cmd_lock); 2214 } 2215 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING); 2216 execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX); 2217 } 2218 // Skip the event notification 2219 bFlag = 0; 2220 2221 } 2222 } 2223 } 2224 else 2225 { 2226 DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)\n",cmd); 2227 eRet = OMX_ErrorNotImplemented; 2228 } 2229 if(eRet == OMX_ErrorNone && bFlag) 2230 { 2231 post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT); 2232 } 2233 if(!sem_posted) 2234 { 2235 sem_post(&m_cmd_lock); 2236 } 2237 2238 return eRet; 2239 } 2240 2241 /* ====================================================================== 2242 FUNCTION 2243 omx_vdec::ExecuteOmxFlush 2244 2245 DESCRIPTION 2246 Executes the OMX flush. 2247 2248 PARAMETERS 2249 flushtype - input flush(1)/output flush(0)/ both. 2250 2251 RETURN VALUE 2252 true/false 2253 2254 ========================================================================== */ 2255 bool omx_vdec::execute_omx_flush(OMX_U32 flushType) 2256 { 2257 struct vdec_ioctl_msg ioctl_msg = {NULL, NULL}; 2258 enum vdec_bufferflush flush_dir; 2259 bool bRet = false; 2260 switch (flushType) 2261 { 2262 case OMX_CORE_INPUT_PORT_INDEX: 2263 input_flush_progress = true; 2264 flush_dir = VDEC_FLUSH_TYPE_INPUT; 2265 break; 2266 case OMX_CORE_OUTPUT_PORT_INDEX: 2267 output_flush_progress = true; 2268 flush_dir = VDEC_FLUSH_TYPE_OUTPUT; 2269 break; 2270 default: 2271 input_flush_progress = true; 2272 output_flush_progress = true; 2273 flush_dir = VDEC_FLUSH_TYPE_ALL; 2274 } 2275 ioctl_msg.in = &flush_dir; 2276 ioctl_msg.out = NULL; 2277 if (ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_CMD_FLUSH, &ioctl_msg) < 0) 2278 { 2279 DEBUG_PRINT_ERROR("\n Flush Port (%d) Failed ", (int)flush_dir); 2280 bRet = false; 2281 } 2282 return bRet; 2283 } 2284 /*========================================================================= 2285 FUNCTION : execute_output_flush 2286 2287 DESCRIPTION 2288 Executes the OMX flush at OUTPUT PORT. 2289 2290 PARAMETERS 2291 None. 2292 2293 RETURN VALUE 2294 true/false 2295 ==========================================================================*/ 2296 bool omx_vdec::execute_output_flush() 2297 { 2298 unsigned p1 = 0; // Parameter - 1 2299 unsigned p2 = 0; // Parameter - 2 2300 unsigned ident = 0; 2301 bool bRet = true; 2302 2303 /*Generate FBD for all Buffers in the FTBq*/ 2304 pthread_mutex_lock(&m_lock); 2305 DEBUG_PRINT_LOW("\n Initiate Output Flush"); 2306 while (m_ftb_q.m_size) 2307 { 2308 DEBUG_PRINT_LOW("\n Buffer queue size %d pending buf cnt %d", 2309 m_ftb_q.m_size,pending_output_buffers); 2310 m_ftb_q.pop_entry(&p1,&p2,&ident); 2311 DEBUG_PRINT_LOW("\n ID(%x) P1(%x) P2(%x)", ident, p1, p2); 2312 if(ident == m_fill_output_msg) 2313 { 2314 pending_output_buffers++; 2315 m_cb.FillBufferDone(&m_cmp, m_app_data, (OMX_BUFFERHEADERTYPE *)p2); 2316 } 2317 else if (ident == OMX_COMPONENT_GENERATE_FBD) 2318 { 2319 fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1); 2320 } 2321 } 2322 pthread_mutex_unlock(&m_lock); 2323 output_flush_progress = false; 2324 2325 if (arbitrary_bytes) 2326 { 2327 prev_ts = LLONG_MAX; 2328 rst_prev_ts = true; 2329 } 2330 DEBUG_PRINT_HIGH("\n OMX flush o/p Port complete PenBuf(%d)", pending_output_buffers); 2331 return bRet; 2332 } 2333 /*========================================================================= 2334 FUNCTION : execute_input_flush 2335 2336 DESCRIPTION 2337 Executes the OMX flush at INPUT PORT. 2338 2339 PARAMETERS 2340 None. 2341 2342 RETURN VALUE 2343 true/false 2344 ==========================================================================*/ 2345 bool omx_vdec::execute_input_flush() 2346 { 2347 unsigned i =0; 2348 unsigned p1 = 0; // Parameter - 1 2349 unsigned p2 = 0; // Parameter - 2 2350 unsigned ident = 0; 2351 bool bRet = true; 2352 2353 /*Generate EBD for all Buffers in the ETBq*/ 2354 DEBUG_PRINT_LOW("\n Initiate Input Flush \n"); 2355 2356 pthread_mutex_lock(&m_lock); 2357 DEBUG_PRINT_LOW("\n Check if the Queue is empty \n"); 2358 while (m_etb_q.m_size) 2359 { 2360 m_etb_q.pop_entry(&p1,&p2,&ident); 2361 2362 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) 2363 { 2364 DEBUG_PRINT_LOW("\n Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2); 2365 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2); 2366 } 2367 else if(ident == OMX_COMPONENT_GENERATE_ETB) 2368 { 2369 pending_input_buffers++; 2370 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d", 2371 (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers); 2372 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2); 2373 } 2374 else if (ident == OMX_COMPONENT_GENERATE_EBD) 2375 { 2376 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_EBD %p", 2377 (OMX_BUFFERHEADERTYPE *)p1); 2378 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1); 2379 } 2380 } 2381 time_stamp_dts.flush_timestamp(); 2382 /*Check if Heap Buffers are to be flushed*/ 2383 if (arbitrary_bytes && !(codec_config_flag)) 2384 { 2385 DEBUG_PRINT_LOW("\n Reset all the variables before flusing"); 2386 h264_scratch.nFilledLen = 0; 2387 nal_count = 0; 2388 look_ahead_nal = false; 2389 frame_count = 0; 2390 h264_last_au_ts = LLONG_MAX; 2391 h264_last_au_flags = 0; 2392 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) ); 2393 m_demux_entries = 0; 2394 DEBUG_PRINT_LOW("\n Initialize parser"); 2395 if (m_frame_parser.mutils) 2396 { 2397 m_frame_parser.mutils->initialize_frame_checking_environment(); 2398 } 2399 2400 while (m_input_pending_q.m_size) 2401 { 2402 m_input_pending_q.pop_entry(&p1,&p2,&ident); 2403 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1); 2404 } 2405 2406 if (psource_frame) 2407 { 2408 m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame); 2409 psource_frame = NULL; 2410 } 2411 2412 if (pdest_frame) 2413 { 2414 pdest_frame->nFilledLen = 0; 2415 m_input_free_q.insert_entry((unsigned) pdest_frame,NULL,NULL); 2416 pdest_frame = NULL; 2417 } 2418 m_frame_parser.flush(); 2419 } 2420 else if (codec_config_flag) 2421 { 2422 DEBUG_PRINT_HIGH("frame_parser flushing skipped due to codec config buffer " 2423 "is not sent to the driver yet"); 2424 } 2425 pthread_mutex_unlock(&m_lock); 2426 input_flush_progress = false; 2427 if (!arbitrary_bytes) 2428 { 2429 prev_ts = LLONG_MAX; 2430 rst_prev_ts = true; 2431 } 2432 #ifdef _ANDROID_ 2433 if (m_debug_timestamp) 2434 { 2435 m_timestamp_list.reset_ts_list(); 2436 } 2437 #endif 2438 DEBUG_PRINT_HIGH("\n OMX flush i/p Port complete PenBuf(%d)", pending_input_buffers); 2439 return bRet; 2440 } 2441 2442 2443 /* ====================================================================== 2444 FUNCTION 2445 omx_vdec::SendCommandEvent 2446 2447 DESCRIPTION 2448 Send the event to decoder pipe. This is needed to generate the callbacks 2449 in decoder thread context. 2450 2451 PARAMETERS 2452 None. 2453 2454 RETURN VALUE 2455 true/false 2456 2457 ========================================================================== */ 2458 bool omx_vdec::post_event(unsigned int p1, 2459 unsigned int p2, 2460 unsigned int id) 2461 { 2462 bool bRet = false; 2463 2464 2465 pthread_mutex_lock(&m_lock); 2466 2467 if (id == m_fill_output_msg || 2468 id == OMX_COMPONENT_GENERATE_FBD) 2469 { 2470 m_ftb_q.insert_entry(p1,p2,id); 2471 } 2472 else if (id == OMX_COMPONENT_GENERATE_ETB || 2473 id == OMX_COMPONENT_GENERATE_EBD || 2474 id == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) 2475 { 2476 m_etb_q.insert_entry(p1,p2,id); 2477 } 2478 else 2479 { 2480 m_cmd_q.insert_entry(p1,p2,id); 2481 } 2482 2483 bRet = true; 2484 DEBUG_PRINT_LOW("\n Value of this pointer in post_event 0x%x", p2); 2485 post_message(this, id); 2486 2487 pthread_mutex_unlock(&m_lock); 2488 2489 return bRet; 2490 } 2491 #ifdef MAX_RES_720P 2492 OMX_ERRORTYPE omx_vdec::get_supported_profile_level_for_720p(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType) 2493 { 2494 OMX_ERRORTYPE eRet = OMX_ErrorNone; 2495 if(!profileLevelType) 2496 return OMX_ErrorBadParameter; 2497 2498 if(profileLevelType->nPortIndex == 0) { 2499 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) 2500 { 2501 if (profileLevelType->nProfileIndex == 0) 2502 { 2503 profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline; 2504 profileLevelType->eLevel = OMX_VIDEO_AVCLevel31; 2505 2506 } 2507 else if (profileLevelType->nProfileIndex == 1) 2508 { 2509 profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain; 2510 profileLevelType->eLevel = OMX_VIDEO_AVCLevel31; 2511 } 2512 else if(profileLevelType->nProfileIndex == 2) 2513 { 2514 profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh; 2515 profileLevelType->eLevel = OMX_VIDEO_AVCLevel31; 2516 } 2517 else 2518 { 2519 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", 2520 profileLevelType->nProfileIndex); 2521 eRet = OMX_ErrorNoMore; 2522 } 2523 } else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))) 2524 { 2525 if (profileLevelType->nProfileIndex == 0) 2526 { 2527 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline; 2528 profileLevelType->eLevel = OMX_VIDEO_H263Level70; 2529 } 2530 else 2531 { 2532 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex); 2533 eRet = OMX_ErrorNoMore; 2534 } 2535 } 2536 else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) 2537 { 2538 if (profileLevelType->nProfileIndex == 0) 2539 { 2540 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple; 2541 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5; 2542 } 2543 else if(profileLevelType->nProfileIndex == 1) 2544 { 2545 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple; 2546 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5; 2547 } 2548 else 2549 { 2550 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex); 2551 eRet = OMX_ErrorNoMore; 2552 } 2553 } 2554 } 2555 else 2556 { 2557 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %d\n", profileLevelType->nPortIndex); 2558 eRet = OMX_ErrorBadPortIndex; 2559 } 2560 return eRet; 2561 } 2562 #endif 2563 #ifdef MAX_RES_1080P 2564 OMX_ERRORTYPE omx_vdec::get_supported_profile_level_for_1080p(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType) 2565 { 2566 OMX_ERRORTYPE eRet = OMX_ErrorNone; 2567 if(!profileLevelType) 2568 return OMX_ErrorBadParameter; 2569 2570 if(profileLevelType->nPortIndex == 0) { 2571 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) 2572 { 2573 if (profileLevelType->nProfileIndex == 0) 2574 { 2575 profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline; 2576 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4; 2577 2578 } 2579 else if (profileLevelType->nProfileIndex == 1) 2580 { 2581 profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain; 2582 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4; 2583 } 2584 else if(profileLevelType->nProfileIndex == 2) 2585 { 2586 profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh; 2587 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4; 2588 } 2589 else 2590 { 2591 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", 2592 profileLevelType->nProfileIndex); 2593 eRet = OMX_ErrorNoMore; 2594 } 2595 } 2596 else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))) 2597 { 2598 if (profileLevelType->nProfileIndex == 0) 2599 { 2600 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline; 2601 profileLevelType->eLevel = OMX_VIDEO_H263Level70; 2602 } 2603 else 2604 { 2605 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex); 2606 eRet = OMX_ErrorNoMore; 2607 } 2608 } 2609 else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) 2610 { 2611 if (profileLevelType->nProfileIndex == 0) 2612 { 2613 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple; 2614 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5; 2615 } 2616 else if(profileLevelType->nProfileIndex == 1) 2617 { 2618 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple; 2619 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5; 2620 } 2621 else 2622 { 2623 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex); 2624 eRet = OMX_ErrorNoMore; 2625 } 2626 } 2627 else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) 2628 { 2629 if (profileLevelType->nProfileIndex == 0) 2630 { 2631 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileSimple; 2632 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL; 2633 } 2634 else if(profileLevelType->nProfileIndex == 1) 2635 { 2636 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileMain; 2637 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL; 2638 } 2639 else 2640 { 2641 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex); 2642 eRet = OMX_ErrorNoMore; 2643 } 2644 } 2645 } 2646 else 2647 { 2648 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %d\n", profileLevelType->nPortIndex); 2649 eRet = OMX_ErrorBadPortIndex; 2650 } 2651 return eRet; 2652 } 2653 #endif 2654 2655 /* ====================================================================== 2656 FUNCTION 2657 omx_vdec::GetParameter 2658 2659 DESCRIPTION 2660 OMX Get Parameter method implementation 2661 2662 PARAMETERS 2663 <TBD>. 2664 2665 RETURN VALUE 2666 Error None if successful. 2667 2668 ========================================================================== */ 2669 OMX_ERRORTYPE omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE hComp, 2670 OMX_IN OMX_INDEXTYPE paramIndex, 2671 OMX_INOUT OMX_PTR paramData) 2672 { 2673 OMX_ERRORTYPE eRet = OMX_ErrorNone; 2674 2675 DEBUG_PRINT_LOW("get_parameter: \n"); 2676 if(m_state == OMX_StateInvalid) 2677 { 2678 DEBUG_PRINT_ERROR("Get Param in Invalid State\n"); 2679 return OMX_ErrorInvalidState; 2680 } 2681 if(paramData == NULL) 2682 { 2683 DEBUG_PRINT_LOW("Get Param in Invalid paramData \n"); 2684 return OMX_ErrorBadParameter; 2685 } 2686 switch(paramIndex) 2687 { 2688 case OMX_IndexParamPortDefinition: 2689 { 2690 OMX_PARAM_PORTDEFINITIONTYPE *portDefn = 2691 (OMX_PARAM_PORTDEFINITIONTYPE *) paramData; 2692 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition\n"); 2693 eRet = update_portdef(portDefn); 2694 if (eRet == OMX_ErrorNone) 2695 m_port_def = *portDefn; 2696 break; 2697 } 2698 case OMX_IndexParamVideoInit: 2699 { 2700 OMX_PORT_PARAM_TYPE *portParamType = 2701 (OMX_PORT_PARAM_TYPE *) paramData; 2702 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit\n"); 2703 2704 portParamType->nVersion.nVersion = OMX_SPEC_VERSION; 2705 portParamType->nSize = sizeof(portParamType); 2706 portParamType->nPorts = 2; 2707 portParamType->nStartPortNumber = 0; 2708 break; 2709 } 2710 case OMX_IndexParamVideoPortFormat: 2711 { 2712 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt = 2713 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData; 2714 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat\n"); 2715 2716 portFmt->nVersion.nVersion = OMX_SPEC_VERSION; 2717 portFmt->nSize = sizeof(portFmt); 2718 2719 if (0 == portFmt->nPortIndex) 2720 { 2721 if (0 == portFmt->nIndex) 2722 { 2723 portFmt->eColorFormat = OMX_COLOR_FormatUnused; 2724 portFmt->eCompressionFormat = eCompressionFormat; 2725 } 2726 else 2727 { 2728 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\ 2729 " NoMore compression formats\n"); 2730 eRet = OMX_ErrorNoMore; 2731 } 2732 } 2733 else if (1 == portFmt->nPortIndex) 2734 { 2735 portFmt->eCompressionFormat = OMX_VIDEO_CodingUnused; 2736 #ifdef MAX_RES_720P 2737 if (0 == portFmt->nIndex) 2738 portFmt->eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; 2739 else if(1 == portFmt->nIndex) 2740 portFmt->eColorFormat = (OMX_COLOR_FORMATTYPE) 2741 QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka; 2742 #endif 2743 #ifdef MAX_RES_1080P 2744 if(0 == portFmt->nIndex) 2745 portFmt->eColorFormat = (OMX_COLOR_FORMATTYPE) 2746 QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka; 2747 #endif 2748 else if (1 == portFmt->nIndex) { 2749 portFmt->eColorFormat = OMX_COLOR_FormatYUV420Planar; 2750 } 2751 else 2752 { 2753 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\ 2754 " NoMore Color formats\n"); 2755 eRet = OMX_ErrorNoMore; 2756 } 2757 } 2758 else 2759 { 2760 DEBUG_PRINT_ERROR("get_parameter: Bad port index %d\n", 2761 (int)portFmt->nPortIndex); 2762 eRet = OMX_ErrorBadPortIndex; 2763 } 2764 break; 2765 } 2766 /*Component should support this port definition*/ 2767 case OMX_IndexParamAudioInit: 2768 { 2769 OMX_PORT_PARAM_TYPE *audioPortParamType = 2770 (OMX_PORT_PARAM_TYPE *) paramData; 2771 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit\n"); 2772 audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION; 2773 audioPortParamType->nSize = sizeof(audioPortParamType); 2774 audioPortParamType->nPorts = 0; 2775 audioPortParamType->nStartPortNumber = 0; 2776 break; 2777 } 2778 /*Component should support this port definition*/ 2779 case OMX_IndexParamImageInit: 2780 { 2781 OMX_PORT_PARAM_TYPE *imagePortParamType = 2782 (OMX_PORT_PARAM_TYPE *) paramData; 2783 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit\n"); 2784 imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION; 2785 imagePortParamType->nSize = sizeof(imagePortParamType); 2786 imagePortParamType->nPorts = 0; 2787 imagePortParamType->nStartPortNumber = 0; 2788 break; 2789 2790 } 2791 /*Component should support this port definition*/ 2792 case OMX_IndexParamOtherInit: 2793 { 2794 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x\n", 2795 paramIndex); 2796 eRet =OMX_ErrorUnsupportedIndex; 2797 break; 2798 } 2799 case OMX_IndexParamStandardComponentRole: 2800 { 2801 OMX_PARAM_COMPONENTROLETYPE *comp_role; 2802 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData; 2803 comp_role->nVersion.nVersion = OMX_SPEC_VERSION; 2804 comp_role->nSize = sizeof(*comp_role); 2805 2806 DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d\n", 2807 paramIndex); 2808 strlcpy((char*)comp_role->cRole,(const char*)m_cRole, 2809 OMX_MAX_STRINGNAME_SIZE); 2810 break; 2811 } 2812 /* Added for parameter test */ 2813 case OMX_IndexParamPriorityMgmt: 2814 { 2815 2816 OMX_PRIORITYMGMTTYPE *priorityMgmType = 2817 (OMX_PRIORITYMGMTTYPE *) paramData; 2818 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt\n"); 2819 priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION; 2820 priorityMgmType->nSize = sizeof(priorityMgmType); 2821 2822 break; 2823 } 2824 /* Added for parameter test */ 2825 case OMX_IndexParamCompBufferSupplier: 2826 { 2827 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = 2828 (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData; 2829 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier\n"); 2830 2831 bufferSupplierType->nSize = sizeof(bufferSupplierType); 2832 bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION; 2833 if(0 == bufferSupplierType->nPortIndex) 2834 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified; 2835 else if (1 == bufferSupplierType->nPortIndex) 2836 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified; 2837 else 2838 eRet = OMX_ErrorBadPortIndex; 2839 2840 2841 break; 2842 } 2843 case OMX_IndexParamVideoAvc: 2844 { 2845 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x\n", 2846 paramIndex); 2847 break; 2848 } 2849 case OMX_IndexParamVideoH263: 2850 { 2851 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x\n", 2852 paramIndex); 2853 break; 2854 } 2855 case OMX_IndexParamVideoMpeg4: 2856 { 2857 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x\n", 2858 paramIndex); 2859 break; 2860 } 2861 case OMX_IndexParamVideoMpeg2: 2862 { 2863 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x\n", 2864 paramIndex); 2865 break; 2866 } 2867 case OMX_IndexParamVideoProfileLevelQuerySupported: 2868 { 2869 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x\n", paramIndex); 2870 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType = 2871 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData; 2872 #ifdef MAX_RES_720P 2873 eRet = get_supported_profile_level_for_720p(profileLevelType); 2874 #endif 2875 #ifdef MAX_RES_1080P 2876 eRet = get_supported_profile_level_for_1080p(profileLevelType); 2877 #endif 2878 break; 2879 } 2880 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) 2881 case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage: 2882 { 2883 DEBUG_PRINT_LOW("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage\n"); 2884 GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData; 2885 if(nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) { 2886 #ifdef USE_ION 2887 if(secure_mode) { 2888 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PROTECTED | 2889 GRALLOC_USAGE_PRIVATE_CP_BUFFER | GRALLOC_USAGE_PRIVATE_UNCACHED); 2890 } else { 2891 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_IOMMU_HEAP); 2892 } 2893 #else 2894 #if defined (MAX_RES_720P) || defined (MAX_RES_1080P_EBI) 2895 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_ADSP_HEAP | GRALLOC_USAGE_PRIVATE_UNCACHED); 2896 #elif MAX_RES_1080P 2897 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_SMI_HEAP | GRALLOC_USAGE_PRIVATE_UNCACHED); 2898 #endif 2899 #endif 2900 } else { 2901 DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!\n"); 2902 eRet = OMX_ErrorBadParameter; 2903 } 2904 } 2905 break; 2906 #endif 2907 2908 default: 2909 { 2910 DEBUG_PRINT_ERROR("get_parameter: unknown param %08x\n", paramIndex); 2911 eRet =OMX_ErrorUnsupportedIndex; 2912 } 2913 2914 } 2915 2916 DEBUG_PRINT_LOW("\n get_parameter returning WxH(%d x %d) SxSH(%d x %d)\n", 2917 drv_ctx.video_resolution.frame_width, 2918 drv_ctx.video_resolution.frame_height, 2919 drv_ctx.video_resolution.stride, 2920 drv_ctx.video_resolution.scan_lines); 2921 2922 return eRet; 2923 } 2924 2925 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) 2926 OMX_ERRORTYPE omx_vdec::use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data) 2927 { 2928 DEBUG_PRINT_LOW("Inside use_android_native_buffer"); 2929 OMX_ERRORTYPE eRet = OMX_ErrorNone; 2930 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)data; 2931 2932 if((params == NULL) || 2933 (params->nativeBuffer == NULL) || 2934 (params->nativeBuffer->handle == NULL) || 2935 !m_enable_android_native_buffers) 2936 return OMX_ErrorBadParameter; 2937 m_use_android_native_buffers = OMX_TRUE; 2938 sp<android_native_buffer_t> nBuf = params->nativeBuffer; 2939 private_handle_t *handle = (private_handle_t *)nBuf->handle; 2940 2941 if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) { 2942 DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback," 2943 " expected %u, got %lu", 2944 drv_ctx.op_buf.buffer_size, (OMX_U32)handle->size); 2945 return OMX_ErrorBadParameter; 2946 } 2947 2948 if(OMX_CORE_OUTPUT_PORT_INDEX == params->nPortIndex) { //android native buffers can be used only on Output port 2949 OMX_U8 *buffer = NULL; 2950 if(!secure_mode) { 2951 buffer = (OMX_U8*)mmap(0, handle->size, 2952 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0); 2953 if(buffer == MAP_FAILED) { 2954 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size); 2955 return OMX_ErrorInsufficientResources; 2956 } 2957 } 2958 eRet = use_buffer(hComp,params->bufferHeader,params->nPortIndex,data,handle->size,buffer); 2959 } else { 2960 eRet = OMX_ErrorBadParameter; 2961 } 2962 return eRet; 2963 } 2964 #endif 2965 /* ====================================================================== 2966 FUNCTION 2967 omx_vdec::Setparameter 2968 2969 DESCRIPTION 2970 OMX Set Parameter method implementation. 2971 2972 PARAMETERS 2973 <TBD>. 2974 2975 RETURN VALUE 2976 OMX Error None if successful. 2977 2978 ========================================================================== */ 2979 OMX_ERRORTYPE omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE hComp, 2980 OMX_IN OMX_INDEXTYPE paramIndex, 2981 OMX_IN OMX_PTR paramData) 2982 { 2983 OMX_ERRORTYPE eRet = OMX_ErrorNone; 2984 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; 2985 2986 if(m_state == OMX_StateInvalid) 2987 { 2988 DEBUG_PRINT_ERROR("Set Param in Invalid State\n"); 2989 return OMX_ErrorInvalidState; 2990 } 2991 if(paramData == NULL) 2992 { 2993 DEBUG_PRINT_ERROR("Get Param in Invalid paramData \n"); 2994 return OMX_ErrorBadParameter; 2995 } 2996 if((m_state != OMX_StateLoaded) && 2997 BITMASK_ABSENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING) && 2998 (m_out_bEnabled == OMX_TRUE) && 2999 BITMASK_ABSENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING) && 3000 (m_inp_bEnabled == OMX_TRUE)) { 3001 DEBUG_PRINT_ERROR("Set Param in Invalid State \n"); 3002 return OMX_ErrorIncorrectStateOperation; 3003 } 3004 3005 switch(paramIndex) 3006 { 3007 case OMX_IndexParamPortDefinition: 3008 { 3009 OMX_PARAM_PORTDEFINITIONTYPE *portDefn; 3010 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData; 3011 //TODO: Check if any allocate buffer/use buffer/useNativeBuffer has 3012 //been called. 3013 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d\n", 3014 (int)portDefn->format.video.nFrameHeight, 3015 (int)portDefn->format.video.nFrameWidth); 3016 if(OMX_DirOutput == portDefn->eDir) 3017 { 3018 eRet = update_color_format(portDefn->format.video.eColorFormat); 3019 if (eRet != OMX_ErrorNone) { 3020 DEBUG_PRINT_ERROR("\n Setparam: color format failed for %u", 3021 portDefn->format.video.eColorFormat); 3022 break; 3023 } 3024 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port"); 3025 m_display_id = portDefn->format.video.pNativeWindow; 3026 unsigned int buffer_size; 3027 if (!client_buffers.get_buffer_req(buffer_size)) { 3028 DEBUG_PRINT_ERROR("\n Error in getting buffer requirements"); 3029 eRet = OMX_ErrorBadParameter; 3030 } else { 3031 if ( portDefn->nBufferCountActual >= drv_ctx.op_buf.mincount && 3032 portDefn->nBufferSize >= buffer_size) 3033 { 3034 drv_ctx.op_buf.actualcount = portDefn->nBufferCountActual; 3035 drv_ctx.op_buf.buffer_size = portDefn->nBufferSize; 3036 eRet = set_buffer_req(&drv_ctx.op_buf); 3037 if (eRet == OMX_ErrorNone) 3038 m_port_def = *portDefn; 3039 } 3040 else 3041 { 3042 DEBUG_PRINT_HIGH("ERROR: OP Requirements(#%d: %u) Requested(#%d: %u)\n", 3043 drv_ctx.op_buf.mincount, drv_ctx.op_buf.buffer_size, 3044 portDefn->nBufferCountActual, portDefn->nBufferSize); 3045 eRet = OMX_ErrorBadParameter; 3046 } 3047 } 3048 } 3049 else if(OMX_DirInput == portDefn->eDir) 3050 { 3051 if((portDefn->format.video.xFramerate >> 16) > 0 && 3052 (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS) 3053 { 3054 // Frame rate only should be set if this is a "known value" or to 3055 // activate ts prediction logic (arbitrary mode only) sending input 3056 // timestamps with max value (LLONG_MAX). 3057 DEBUG_PRINT_HIGH("set_parameter: frame rate set by omx client : %d", 3058 portDefn->format.video.xFramerate >> 16); 3059 Q16ToFraction(portDefn->format.video.xFramerate, drv_ctx.frame_rate.fps_numerator, 3060 drv_ctx.frame_rate.fps_denominator); 3061 if(!drv_ctx.frame_rate.fps_numerator) 3062 { 3063 DEBUG_PRINT_ERROR("Numerator is zero setting to 30"); 3064 drv_ctx.frame_rate.fps_numerator = 30; 3065 } 3066 if(drv_ctx.frame_rate.fps_denominator) 3067 drv_ctx.frame_rate.fps_numerator = (int) 3068 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator; 3069 drv_ctx.frame_rate.fps_denominator = 1; 3070 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 / 3071 drv_ctx.frame_rate.fps_numerator; 3072 ioctl_msg.in = &drv_ctx.frame_rate; 3073 if (ioctl (drv_ctx.video_driver_fd, VDEC_IOCTL_SET_FRAME_RATE, 3074 (void*)&ioctl_msg) < 0) 3075 { 3076 DEBUG_PRINT_ERROR("Setting frame rate to driver failed"); 3077 } 3078 DEBUG_PRINT_LOW("set_parameter: frm_int(%u) fps(%.2f)", 3079 frm_int, drv_ctx.frame_rate.fps_numerator / 3080 (float)drv_ctx.frame_rate.fps_denominator); 3081 } 3082 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port\n"); 3083 if(drv_ctx.video_resolution.frame_height != 3084 portDefn->format.video.nFrameHeight || 3085 drv_ctx.video_resolution.frame_width != 3086 portDefn->format.video.nFrameWidth) 3087 { 3088 DEBUG_PRINT_LOW("\n SetParam IP: WxH(%d x %d)\n", 3089 portDefn->format.video.nFrameWidth, 3090 portDefn->format.video.nFrameHeight); 3091 if (portDefn->format.video.nFrameHeight != 0x0 && 3092 portDefn->format.video.nFrameWidth != 0x0) 3093 { 3094 update_resolution(portDefn->format.video.nFrameWidth, 3095 portDefn->format.video.nFrameHeight); 3096 ioctl_msg.in = &drv_ctx.video_resolution; 3097 ioctl_msg.out = NULL; 3098 if (ioctl (drv_ctx.video_driver_fd, VDEC_IOCTL_SET_PICRES, 3099 (void*)&ioctl_msg) < 0) 3100 { 3101 DEBUG_PRINT_ERROR("\n Set Resolution failed"); 3102 eRet = OMX_ErrorUnsupportedSetting; 3103 } 3104 else 3105 eRet = get_buffer_req(&drv_ctx.op_buf); 3106 } 3107 } 3108 else if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount 3109 && portDefn->nBufferSize == drv_ctx.ip_buf.buffer_size) 3110 { 3111 drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual; 3112 drv_ctx.ip_buf.buffer_size = portDefn->nBufferSize; 3113 eRet = set_buffer_req(&drv_ctx.ip_buf); 3114 } 3115 else 3116 { 3117 DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%d: %u)\n", 3118 drv_ctx.ip_buf.mincount, drv_ctx.ip_buf.buffer_size, 3119 portDefn->nBufferCountActual, portDefn->nBufferSize); 3120 eRet = OMX_ErrorBadParameter; 3121 } 3122 } 3123 else if (portDefn->eDir == OMX_DirMax) 3124 { 3125 DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d", 3126 (int)portDefn->nPortIndex); 3127 eRet = OMX_ErrorBadPortIndex; 3128 } 3129 } 3130 break; 3131 case OMX_IndexParamVideoPortFormat: 3132 { 3133 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt = 3134 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData; 3135 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d\n", 3136 portFmt->eColorFormat); 3137 3138 if(1 == portFmt->nPortIndex) 3139 eRet = update_color_format(portFmt->eColorFormat); 3140 3141 DEBUG_PRINT_HIGH("Set_parameter: OMX_IndexParamVideoPortFormat: " 3142 "nPortIndex (%d), nIndex (%d), eCompressionFormat (0x%x), " 3143 "eColorFormat (0x%x), xFramerate (0x%x)", (int)portFmt->nPortIndex, 3144 (int)portFmt->nIndex, (int)portFmt->eCompressionFormat, 3145 (int)portFmt->eColorFormat, (int)portFmt->xFramerate); 3146 } 3147 break; 3148 3149 case OMX_QcomIndexPortDefn: 3150 { 3151 OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt = 3152 (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData; 3153 DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %d\n", 3154 portFmt->nFramePackingFormat); 3155 3156 /* Input port */ 3157 if (portFmt->nPortIndex == 0) 3158 { 3159 if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary) 3160 { 3161 if(secure_mode) { 3162 arbitrary_bytes = false; 3163 DEBUG_PRINT_ERROR("setparameter: cannot set to arbitary bytes mode in secure session"); 3164 eRet = OMX_ErrorUnsupportedSetting; 3165 } else { 3166 arbitrary_bytes = true; 3167 DEBUG_PRINT_HIGH("setparameter: arbitrary_bytes enabled"); 3168 } 3169 } 3170 else if (portFmt->nFramePackingFormat == 3171 OMX_QCOM_FramePacking_OnlyOneCompleteFrame) 3172 { 3173 arbitrary_bytes = false; 3174 DEBUG_PRINT_HIGH("setparameter: arbitrary_bytes disabled"); 3175 } 3176 else 3177 { 3178 DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %d\n", 3179 portFmt->nFramePackingFormat); 3180 eRet = OMX_ErrorUnsupportedSetting; 3181 } 3182 } 3183 else if (portFmt->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) 3184 { 3185 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port\n"); 3186 if( (portFmt->nMemRegion > OMX_QCOM_MemRegionInvalid && 3187 portFmt->nMemRegion < OMX_QCOM_MemRegionMax) && 3188 portFmt->nCacheAttr == OMX_QCOM_CacheAttrNone) 3189 { 3190 m_out_mem_region_smi = OMX_TRUE; 3191 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) 3192 { 3193 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port: out pmem set\n"); 3194 m_use_output_pmem = OMX_TRUE; 3195 } 3196 } 3197 } 3198 } 3199 break; 3200 3201 case OMX_IndexParamStandardComponentRole: 3202 { 3203 OMX_PARAM_COMPONENTROLETYPE *comp_role; 3204 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData; 3205 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s\n", 3206 comp_role->cRole); 3207 3208 if((m_state == OMX_StateLoaded)&& 3209 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) 3210 { 3211 DEBUG_PRINT_LOW("Set Parameter called in valid state"); 3212 } 3213 else 3214 { 3215 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n"); 3216 return OMX_ErrorIncorrectStateOperation; 3217 } 3218 3219 if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) 3220 { 3221 if(!strncmp((char*)comp_role->cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE)) 3222 { 3223 strlcpy((char*)m_cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE); 3224 } 3225 else 3226 { 3227 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole); 3228 eRet =OMX_ErrorUnsupportedSetting; 3229 } 3230 } 3231 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) 3232 { 3233 if(!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) 3234 { 3235 strlcpy((char*)m_cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE); 3236 } 3237 else 3238 { 3239 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole); 3240 eRet = OMX_ErrorUnsupportedSetting; 3241 } 3242 } 3243 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) 3244 { 3245 if(!strncmp((const char*)comp_role->cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE)) 3246 { 3247 strlcpy((char*)m_cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE); 3248 } 3249 else 3250 { 3251 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole); 3252 eRet =OMX_ErrorUnsupportedSetting; 3253 } 3254 } 3255 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) 3256 { 3257 if(!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) 3258 { 3259 strlcpy((char*)m_cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE); 3260 } 3261 else 3262 { 3263 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole); 3264 eRet = OMX_ErrorUnsupportedSetting; 3265 } 3266 } 3267 #ifdef MAX_RES_1080P 3268 else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) || 3269 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE)) 3270 ) 3271 #else 3272 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) 3273 #endif 3274 { 3275 if(!strncmp((const char*)comp_role->cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE)) 3276 { 3277 strlcpy((char*)m_cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); 3278 } 3279 else 3280 { 3281 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole); 3282 eRet =OMX_ErrorUnsupportedSetting; 3283 } 3284 } 3285 else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) || 3286 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE)) 3287 ) 3288 { 3289 if(!strncmp((const char*)comp_role->cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) 3290 { 3291 strlcpy((char*)m_cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE); 3292 } 3293 else 3294 { 3295 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole); 3296 eRet =OMX_ErrorUnsupportedSetting; 3297 } 3298 } 3299 else 3300 { 3301 DEBUG_PRINT_ERROR("Setparameter: unknown param %s\n", drv_ctx.kind); 3302 eRet = OMX_ErrorInvalidComponentName; 3303 } 3304 break; 3305 } 3306 3307 case OMX_IndexParamPriorityMgmt: 3308 { 3309 if(m_state != OMX_StateLoaded) 3310 { 3311 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n"); 3312 return OMX_ErrorIncorrectStateOperation; 3313 } 3314 OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData; 3315 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %d\n", 3316 priorityMgmtype->nGroupID); 3317 3318 DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %d\n", 3319 priorityMgmtype->nGroupPriority); 3320 3321 m_priority_mgm.nGroupID = priorityMgmtype->nGroupID; 3322 m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority; 3323 3324 break; 3325 } 3326 3327 case OMX_IndexParamCompBufferSupplier: 3328 { 3329 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData; 3330 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d\n", 3331 bufferSupplierType->eBufferSupplier); 3332 if(bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1) 3333 m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier; 3334 3335 else 3336 3337 eRet = OMX_ErrorBadPortIndex; 3338 3339 break; 3340 3341 } 3342 case OMX_IndexParamVideoAvc: 3343 { 3344 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d\n", 3345 paramIndex); 3346 break; 3347 } 3348 case OMX_IndexParamVideoH263: 3349 { 3350 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d\n", 3351 paramIndex); 3352 break; 3353 } 3354 case OMX_IndexParamVideoMpeg4: 3355 { 3356 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d\n", 3357 paramIndex); 3358 break; 3359 } 3360 case OMX_IndexParamVideoMpeg2: 3361 { 3362 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d\n", 3363 paramIndex); 3364 break; 3365 } 3366 case OMX_QcomIndexParamVideoDecoderPictureOrder: 3367 { 3368 QOMX_VIDEO_DECODER_PICTURE_ORDER *pictureOrder = 3369 (QOMX_VIDEO_DECODER_PICTURE_ORDER *)paramData; 3370 enum vdec_output_order pic_order = VDEC_ORDER_DISPLAY; 3371 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoDecoderPictureOrder %d\n", 3372 pictureOrder->eOutputPictureOrder); 3373 if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DISPLAY_ORDER) 3374 pic_order = VDEC_ORDER_DISPLAY; 3375 else if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER){ 3376 pic_order = VDEC_ORDER_DECODE; 3377 time_stamp_dts.set_timestamp_reorder_mode(false); 3378 } 3379 else 3380 eRet = OMX_ErrorBadParameter; 3381 #ifdef MAX_RES_720P 3382 if (drv_ctx.idr_only_decoding) 3383 { 3384 if (pictureOrder->eOutputPictureOrder != QOMX_VIDEO_DECODE_ORDER) 3385 { 3386 DEBUG_PRINT_HIGH("only decode order is supported for thumbnail mode"); 3387 eRet = OMX_ErrorBadParameter; 3388 } 3389 } 3390 #endif 3391 if (eRet == OMX_ErrorNone && pic_order != drv_ctx.picture_order) 3392 { 3393 drv_ctx.picture_order = pic_order; 3394 ioctl_msg.in = &drv_ctx.picture_order; 3395 ioctl_msg.out = NULL; 3396 if (ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_SET_PICTURE_ORDER, 3397 (void*)&ioctl_msg) < 0) 3398 { 3399 DEBUG_PRINT_ERROR("\n Set picture order failed"); 3400 eRet = OMX_ErrorUnsupportedSetting; 3401 } 3402 } 3403 break; 3404 } 3405 case OMX_QcomIndexParamConcealMBMapExtraData: 3406 if(!secure_mode) 3407 eRet = enable_extradata(VDEC_EXTRADATA_MB_ERROR_MAP, 3408 ((QOMX_ENABLETYPE *)paramData)->bEnable); 3409 else { 3410 DEBUG_PRINT_ERROR("\n secure mode setting not supported"); 3411 eRet = OMX_ErrorUnsupportedSetting; 3412 } 3413 break; 3414 case OMX_QcomIndexParamFrameInfoExtraData: 3415 { 3416 if(!secure_mode) 3417 eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, 3418 ((QOMX_ENABLETYPE *)paramData)->bEnable); 3419 else { 3420 DEBUG_PRINT_ERROR("\n secure mode setting not supported"); 3421 eRet = OMX_ErrorUnsupportedSetting; 3422 } 3423 break; 3424 } 3425 case OMX_QcomIndexParamInterlaceExtraData: 3426 if(!secure_mode) 3427 eRet = enable_extradata(OMX_INTERLACE_EXTRADATA, 3428 ((QOMX_ENABLETYPE *)paramData)->bEnable); 3429 else { 3430 DEBUG_PRINT_ERROR("\n secure mode setting not supported"); 3431 eRet = OMX_ErrorUnsupportedSetting; 3432 } 3433 break; 3434 case OMX_QcomIndexParamH264TimeInfo: 3435 if(!secure_mode) 3436 eRet = enable_extradata(OMX_TIMEINFO_EXTRADATA, 3437 ((QOMX_ENABLETYPE *)paramData)->bEnable); 3438 else { 3439 DEBUG_PRINT_ERROR("\n secure mode setting not supported"); 3440 eRet = OMX_ErrorUnsupportedSetting; 3441 } 3442 break; 3443 case OMX_QcomIndexParamVideoDivx: 3444 { 3445 #ifdef MAX_RES_720P 3446 QOMX_VIDEO_PARAM_DIVXTYPE* divXType = (QOMX_VIDEO_PARAM_DIVXTYPE *) paramData; 3447 if((divXType) && (divXType->eFormat == QOMX_VIDEO_DIVXFormat311)) { 3448 DEBUG_PRINT_HIGH("set_parameter: DivX 3.11 not supported in 7x30 core."); 3449 eRet = OMX_ErrorUnsupportedSetting; 3450 } 3451 #endif 3452 } 3453 break; 3454 case OMX_QcomIndexPlatformPvt: 3455 { 3456 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port\n"); 3457 OMX_QCOM_PLATFORMPRIVATE_EXTN* entryType = (OMX_QCOM_PLATFORMPRIVATE_EXTN *) paramData; 3458 if (entryType->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) 3459 { 3460 DEBUG_PRINT_HIGH("set_parameter: Platform Private entry type (%d) not supported.", entryType->type); 3461 eRet = OMX_ErrorUnsupportedSetting; 3462 } 3463 else 3464 { 3465 m_out_pvt_entry_pmem = OMX_TRUE; 3466 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) 3467 { 3468 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port: out pmem set\n"); 3469 m_use_output_pmem = OMX_TRUE; 3470 } 3471 } 3472 3473 } 3474 break; 3475 case OMX_QcomIndexParamVideoSyncFrameDecodingMode: 3476 { 3477 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoSyncFrameDecodingMode"); 3478 DEBUG_PRINT_HIGH("set idr only decoding for thumbnail mode"); 3479 drv_ctx.idr_only_decoding = 1; 3480 int rc = ioctl(drv_ctx.video_driver_fd, 3481 VDEC_IOCTL_SET_IDR_ONLY_DECODING); 3482 if(rc < 0) { 3483 DEBUG_PRINT_ERROR("Failed to set IDR only decoding on driver."); 3484 eRet = OMX_ErrorHardware; 3485 } 3486 #ifdef MAX_RES_720P 3487 if (eRet == OMX_ErrorNone) 3488 { 3489 DEBUG_PRINT_HIGH("set decode order for thumbnail mode"); 3490 drv_ctx.picture_order = VDEC_ORDER_DECODE; 3491 ioctl_msg.in = &drv_ctx.picture_order; 3492 ioctl_msg.out = NULL; 3493 if (ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_SET_PICTURE_ORDER, 3494 (void*)&ioctl_msg) < 0) 3495 { 3496 DEBUG_PRINT_ERROR("\n Set picture order failed"); 3497 eRet = OMX_ErrorUnsupportedSetting; 3498 } 3499 } 3500 #endif 3501 } 3502 break; 3503 #ifdef MAX_RES_1080P 3504 case OMX_QcomIndexParamIndexExtraDataType: 3505 { 3506 if(!secure_mode) { 3507 QOMX_INDEXEXTRADATATYPE *extradataIndexType = (QOMX_INDEXEXTRADATATYPE *) paramData; 3508 if ((extradataIndexType->nIndex == OMX_IndexParamPortDefinition) && 3509 (extradataIndexType->bEnabled == OMX_TRUE) && 3510 (extradataIndexType->nPortIndex == 1)) 3511 { 3512 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamIndexExtraDataType SmoothStreaming\n"); 3513 eRet = enable_extradata(OMX_PORTDEF_EXTRADATA, extradataIndexType->bEnabled); 3514 // Set smooth streaming parameter 3515 int rc = ioctl(drv_ctx.video_driver_fd, 3516 VDEC_IOCTL_SET_CONT_ON_RECONFIG); 3517 if(rc < 0) { 3518 DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver."); 3519 eRet = OMX_ErrorHardware; 3520 } 3521 } 3522 } 3523 } 3524 break; 3525 #endif 3526 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) 3527 /* Need to allow following two set_parameters even in Idle 3528 * state. This is ANDROID architecture which is not in sync 3529 * with openmax standard. */ 3530 case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers: 3531 { 3532 EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData; 3533 if(enableNativeBuffers) { 3534 m_enable_android_native_buffers = enableNativeBuffers->enable; 3535 } 3536 } 3537 break; 3538 case OMX_GoogleAndroidIndexUseAndroidNativeBuffer: 3539 { 3540 eRet = use_android_native_buffer(hComp, paramData); 3541 } 3542 break; 3543 #endif 3544 case OMX_QcomIndexParamEnableTimeStampReorder: 3545 { 3546 QOMX_INDEXTIMESTAMPREORDER *reorder = (QOMX_INDEXTIMESTAMPREORDER *)paramData; 3547 if (drv_ctx.picture_order == QOMX_VIDEO_DISPLAY_ORDER) { 3548 if (reorder->bEnable == OMX_TRUE) { 3549 frm_int =0; 3550 time_stamp_dts.set_timestamp_reorder_mode(true); 3551 } 3552 else 3553 time_stamp_dts.set_timestamp_reorder_mode(false); 3554 } else { 3555 time_stamp_dts.set_timestamp_reorder_mode(false); 3556 if (reorder->bEnable == OMX_TRUE) 3557 { 3558 eRet = OMX_ErrorUnsupportedSetting; 3559 } 3560 } 3561 } 3562 break; 3563 default: 3564 { 3565 DEBUG_PRINT_ERROR("Setparameter: unknown param %d\n", paramIndex); 3566 eRet = OMX_ErrorUnsupportedIndex; 3567 } 3568 } 3569 return eRet; 3570 } 3571 3572 /* ====================================================================== 3573 FUNCTION 3574 omx_vdec::GetConfig 3575 3576 DESCRIPTION 3577 OMX Get Config Method implementation. 3578 3579 PARAMETERS 3580 <TBD>. 3581 3582 RETURN VALUE 3583 OMX Error None if successful. 3584 3585 ========================================================================== */ 3586 OMX_ERRORTYPE omx_vdec::get_config(OMX_IN OMX_HANDLETYPE hComp, 3587 OMX_IN OMX_INDEXTYPE configIndex, 3588 OMX_INOUT OMX_PTR configData) 3589 { 3590 OMX_ERRORTYPE eRet = OMX_ErrorNone; 3591 3592 if (m_state == OMX_StateInvalid) 3593 { 3594 DEBUG_PRINT_ERROR("Get Config in Invalid State\n"); 3595 return OMX_ErrorInvalidState; 3596 } 3597 3598 switch (configIndex) 3599 { 3600 case OMX_QcomIndexConfigInterlaced: 3601 { 3602 OMX_QCOM_CONFIG_INTERLACETYPE *configFmt = 3603 (OMX_QCOM_CONFIG_INTERLACETYPE *) configData; 3604 if (configFmt->nPortIndex == 1) 3605 { 3606 if (configFmt->nIndex == 0) 3607 { 3608 configFmt->eInterlaceType = OMX_QCOM_InterlaceFrameProgressive; 3609 } 3610 else if (configFmt->nIndex == 1) 3611 { 3612 configFmt->eInterlaceType = 3613 OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst; 3614 } 3615 else if (configFmt->nIndex == 2) 3616 { 3617 configFmt->eInterlaceType = 3618 OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst; 3619 } 3620 else 3621 { 3622 DEBUG_PRINT_ERROR("get_config: OMX_QcomIndexConfigInterlaced:" 3623 " NoMore Interlaced formats\n"); 3624 eRet = OMX_ErrorNoMore; 3625 } 3626 3627 } 3628 else 3629 { 3630 DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port\n", 3631 (int)configFmt->nPortIndex); 3632 eRet = OMX_ErrorBadPortIndex; 3633 } 3634 break; 3635 } 3636 case OMX_QcomIndexQueryNumberOfVideoDecInstance: 3637 { 3638 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; 3639 QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances = 3640 (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData; 3641 ioctl_msg.out = (void*)&decoderinstances->nNumOfInstances; 3642 (void)(ioctl(drv_ctx.video_driver_fd, 3643 VDEC_IOCTL_GET_NUMBER_INSTANCES,&ioctl_msg)); 3644 break; 3645 } 3646 case OMX_QcomIndexConfigVideoFramePackingArrangement: 3647 { 3648 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) 3649 { 3650 OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt = 3651 (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData; 3652 h264_parser->get_frame_pack_data(configFmt); 3653 } 3654 else 3655 { 3656 DEBUG_PRINT_ERROR("get_config: Framepack data not supported for non H264 codecs"); 3657 } 3658 break; 3659 } 3660 case OMX_QcomIndexParamFrameInfoExtraData: 3661 { 3662 OMX_QCOM_EXTRADATA_FRAMEINFO *extradata = 3663 (OMX_QCOM_EXTRADATA_FRAMEINFO *) configData; 3664 3665 if(m_extradata == NULL){ 3666 DEBUG_PRINT_ERROR("get_config: m_extradata not set. " 3667 "Aspect Ratio information missing!!"); 3668 } 3669 else { 3670 extradata->aspectRatio.aspectRatioX = 3671 m_extradata->aspectRatio.aspectRatioX; 3672 extradata->aspectRatio.aspectRatioY = 3673 m_extradata->aspectRatio.aspectRatioY; 3674 } 3675 break; 3676 } 3677 case OMX_IndexConfigCommonOutputCrop: 3678 { 3679 OMX_CONFIG_RECTTYPE *rect = (OMX_CONFIG_RECTTYPE *) configData; 3680 memcpy(rect, &rectangle, sizeof(OMX_CONFIG_RECTTYPE)); 3681 break; 3682 } 3683 3684 default: 3685 { 3686 DEBUG_PRINT_ERROR("get_config: unknown param %d\n",configIndex); 3687 eRet = OMX_ErrorBadParameter; 3688 } 3689 3690 } 3691 3692 return eRet; 3693 } 3694 3695 /* ====================================================================== 3696 FUNCTION 3697 omx_vdec::SetConfig 3698 3699 DESCRIPTION 3700 OMX Set Config method implementation 3701 3702 PARAMETERS 3703 <TBD>. 3704 3705 RETURN VALUE 3706 OMX Error None if successful. 3707 ========================================================================== */ 3708 OMX_ERRORTYPE omx_vdec::set_config(OMX_IN OMX_HANDLETYPE hComp, 3709 OMX_IN OMX_INDEXTYPE configIndex, 3710 OMX_IN OMX_PTR configData) 3711 { 3712 if(m_state == OMX_StateInvalid) 3713 { 3714 DEBUG_PRINT_ERROR("Get Config in Invalid State\n"); 3715 return OMX_ErrorInvalidState; 3716 } 3717 3718 OMX_ERRORTYPE ret = OMX_ErrorNone; 3719 OMX_VIDEO_CONFIG_NALSIZE *pNal; 3720 3721 DEBUG_PRINT_LOW("\n Set Config Called"); 3722 3723 if (m_state == OMX_StateExecuting) 3724 { 3725 DEBUG_PRINT_ERROR("set_config:Ignore in Exe state\n"); 3726 return ret; 3727 } 3728 3729 if (configIndex == OMX_IndexVendorVideoExtraData) 3730 { 3731 OMX_VENDOR_EXTRADATATYPE *config = (OMX_VENDOR_EXTRADATATYPE *) configData; 3732 DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData called"); 3733 if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc")) 3734 { 3735 DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData AVC"); 3736 OMX_U32 extra_size; 3737 // Parsing done here for the AVC atom is definitely not generic 3738 // Currently this piece of code is working, but certainly 3739 // not tested with all .mp4 files. 3740 // Incase of failure, we might need to revisit this 3741 // for a generic piece of code. 3742 3743 // Retrieve size of NAL length field 3744 // byte #4 contains the size of NAL lenght field 3745 nal_length = (config->pData[4] & 0x03) + 1; 3746 3747 extra_size = 0; 3748 if (nal_length > 2) 3749 { 3750 /* Presently we assume that only one SPS and one PPS in AvC1 Atom */ 3751 extra_size = (nal_length - 2) * 2; 3752 } 3753 3754 // SPS starts from byte #6 3755 OMX_U8 *pSrcBuf = (OMX_U8 *) (&config->pData[6]); 3756 OMX_U8 *pDestBuf; 3757 m_vendor_config.nPortIndex = config->nPortIndex; 3758 3759 // minus 6 --> SPS starts from byte #6 3760 // minus 1 --> picture param set byte to be ignored from avcatom 3761 m_vendor_config.nDataSize = config->nDataSize - 6 - 1 + extra_size; 3762 m_vendor_config.pData = (OMX_U8 *) malloc(m_vendor_config.nDataSize); 3763 OMX_U32 len; 3764 OMX_U8 index = 0; 3765 // case where SPS+PPS is sent as part of set_config 3766 pDestBuf = m_vendor_config.pData; 3767 3768 DEBUG_PRINT_LOW("Rxd SPS+PPS nPortIndex[%d] len[%d] data[0x%x]\n", 3769 m_vendor_config.nPortIndex, 3770 m_vendor_config.nDataSize, 3771 m_vendor_config.pData); 3772 while (index < 2) 3773 { 3774 uint8 *psize; 3775 len = *pSrcBuf; 3776 len = len << 8; 3777 len |= *(pSrcBuf + 1); 3778 psize = (uint8 *) & len; 3779 memcpy(pDestBuf + nal_length, pSrcBuf + 2,len); 3780 for (int i = 0; i < nal_length; i++) 3781 { 3782 pDestBuf[i] = psize[nal_length - 1 - i]; 3783 } 3784 //memcpy(pDestBuf,pSrcBuf,(len+2)); 3785 pDestBuf += len + nal_length; 3786 pSrcBuf += len + 2; 3787 index++; 3788 pSrcBuf++; // skip picture param set 3789 len = 0; 3790 } 3791 } 3792 else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4") || 3793 !strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2")) 3794 { 3795 m_vendor_config.nPortIndex = config->nPortIndex; 3796 m_vendor_config.nDataSize = config->nDataSize; 3797 m_vendor_config.pData = (OMX_U8 *) malloc((config->nDataSize)); 3798 memcpy(m_vendor_config.pData, config->pData,config->nDataSize); 3799 } 3800 else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1")) 3801 { 3802 if(m_vendor_config.pData) 3803 { 3804 free(m_vendor_config.pData); 3805 m_vendor_config.pData = NULL; 3806 m_vendor_config.nDataSize = 0; 3807 } 3808 3809 if (((*((OMX_U32 *) config->pData)) & 3810 VC1_SP_MP_START_CODE_MASK) == 3811 VC1_SP_MP_START_CODE) 3812 { 3813 DEBUG_PRINT_LOW("set_config - VC1 simple/main profile\n"); 3814 m_vendor_config.nPortIndex = config->nPortIndex; 3815 m_vendor_config.nDataSize = config->nDataSize; 3816 m_vendor_config.pData = 3817 (OMX_U8 *) malloc(config->nDataSize); 3818 memcpy(m_vendor_config.pData, config->pData, 3819 config->nDataSize); 3820 m_vc1_profile = VC1_SP_MP_RCV; 3821 } 3822 else if (*((OMX_U32 *) config->pData) == VC1_AP_SEQ_START_CODE) 3823 { 3824 DEBUG_PRINT_LOW("set_config - VC1 Advance profile\n"); 3825 m_vendor_config.nPortIndex = config->nPortIndex; 3826 m_vendor_config.nDataSize = config->nDataSize; 3827 m_vendor_config.pData = 3828 (OMX_U8 *) malloc((config->nDataSize)); 3829 memcpy(m_vendor_config.pData, config->pData, 3830 config->nDataSize); 3831 m_vc1_profile = VC1_AP; 3832 } 3833 else if ((config->nDataSize == VC1_STRUCT_C_LEN)) 3834 { 3835 DEBUG_PRINT_LOW("set_config - VC1 Simple/Main profile struct C only\n"); 3836 m_vendor_config.nPortIndex = config->nPortIndex; 3837 m_vendor_config.nDataSize = config->nDataSize; 3838 m_vendor_config.pData = (OMX_U8*)malloc(config->nDataSize); 3839 memcpy(m_vendor_config.pData,config->pData,config->nDataSize); 3840 m_vc1_profile = VC1_SP_MP_RCV; 3841 } 3842 else 3843 { 3844 DEBUG_PRINT_LOW("set_config - Error: Unknown VC1 profile\n"); 3845 } 3846 } 3847 return ret; 3848 } 3849 else if (configIndex == OMX_IndexConfigVideoNalSize) 3850 { 3851 3852 pNal = reinterpret_cast < OMX_VIDEO_CONFIG_NALSIZE * >(configData); 3853 nal_length = pNal->nNaluBytes; 3854 m_frame_parser.init_nal_length(nal_length); 3855 DEBUG_PRINT_LOW("\n OMX_IndexConfigVideoNalSize called with Size %d",nal_length); 3856 return ret; 3857 } 3858 3859 return OMX_ErrorNotImplemented; 3860 } 3861 3862 /* ====================================================================== 3863 FUNCTION 3864 omx_vdec::GetExtensionIndex 3865 3866 DESCRIPTION 3867 OMX GetExtensionIndex method implementaion. <TBD> 3868 3869 PARAMETERS 3870 <TBD>. 3871 3872 RETURN VALUE 3873 OMX Error None if everything successful. 3874 3875 ========================================================================== */ 3876 OMX_ERRORTYPE omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE hComp, 3877 OMX_IN OMX_STRING paramName, 3878 OMX_OUT OMX_INDEXTYPE* indexType) 3879 { 3880 if(m_state == OMX_StateInvalid) 3881 { 3882 DEBUG_PRINT_ERROR("Get Extension Index in Invalid State\n"); 3883 return OMX_ErrorInvalidState; 3884 } 3885 else if (!strncmp(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode",sizeof("OMX.QCOM.index.param.video.SyncFrameDecodingMode") - 1)) { 3886 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode; 3887 } 3888 #ifdef MAX_RES_1080P 3889 else if (!strncmp(paramName, "OMX.QCOM.index.param.IndexExtraData",sizeof("OMX.QCOM.index.param.IndexExtraData") - 1)) 3890 { 3891 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType; 3892 } 3893 #endif 3894 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) 3895 else if(!strncmp(paramName,"OMX.google.android.index.enableAndroidNativeBuffers", sizeof("OMX.google.android.index.enableAndroidNativeBuffers") - 1)) { 3896 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers; 3897 } 3898 else if(!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer2", sizeof("OMX.google.android.index.enableAndroidNativeBuffer2") - 1)) { 3899 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2; 3900 } 3901 else if(!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer", sizeof("OMX.google.android.index.enableAndroidNativeBuffer") - 1)) { 3902 DEBUG_PRINT_ERROR("Extension: %s is supported\n", paramName); 3903 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer; 3904 } 3905 else if(!strncmp(paramName,"OMX.google.android.index.getAndroidNativeBufferUsage", sizeof("OMX.google.android.index.getAndroidNativeBufferUsage") - 1)) { 3906 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage; 3907 } 3908 #endif 3909 else { 3910 DEBUG_PRINT_ERROR("Extension: %s not implemented\n", paramName); 3911 return OMX_ErrorNotImplemented; 3912 } 3913 return OMX_ErrorNone; 3914 } 3915 3916 /* ====================================================================== 3917 FUNCTION 3918 omx_vdec::GetState 3919 3920 DESCRIPTION 3921 Returns the state information back to the caller.<TBD> 3922 3923 PARAMETERS 3924 <TBD>. 3925 3926 RETURN VALUE 3927 Error None if everything is successful. 3928 ========================================================================== */ 3929 OMX_ERRORTYPE omx_vdec::get_state(OMX_IN OMX_HANDLETYPE hComp, 3930 OMX_OUT OMX_STATETYPE* state) 3931 { 3932 *state = m_state; 3933 DEBUG_PRINT_LOW("get_state: Returning the state %d\n",*state); 3934 return OMX_ErrorNone; 3935 } 3936 3937 /* ====================================================================== 3938 FUNCTION 3939 omx_vdec::ComponentTunnelRequest 3940 3941 DESCRIPTION 3942 OMX Component Tunnel Request method implementation. <TBD> 3943 3944 PARAMETERS 3945 None. 3946 3947 RETURN VALUE 3948 OMX Error None if everything successful. 3949 3950 ========================================================================== */ 3951 OMX_ERRORTYPE omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp, 3952 OMX_IN OMX_U32 port, 3953 OMX_IN OMX_HANDLETYPE peerComponent, 3954 OMX_IN OMX_U32 peerPort, 3955 OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup) 3956 { 3957 DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented\n"); 3958 return OMX_ErrorNotImplemented; 3959 } 3960 3961 /* ====================================================================== 3962 FUNCTION 3963 omx_vdec::UseOutputBuffer 3964 3965 DESCRIPTION 3966 Helper function for Use buffer in the input pin 3967 3968 PARAMETERS 3969 None. 3970 3971 RETURN VALUE 3972 true/false 3973 3974 ========================================================================== */ 3975 OMX_ERRORTYPE omx_vdec::use_output_buffer( 3976 OMX_IN OMX_HANDLETYPE hComp, 3977 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 3978 OMX_IN OMX_U32 port, 3979 OMX_IN OMX_PTR appData, 3980 OMX_IN OMX_U32 bytes, 3981 OMX_IN OMX_U8* buffer) 3982 { 3983 OMX_ERRORTYPE eRet = OMX_ErrorNone; 3984 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header 3985 unsigned i= 0; // Temporary counter 3986 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; 3987 struct vdec_setbuffer_cmd setbuffers; 3988 OMX_PTR privateAppData = NULL; 3989 #if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_) 3990 private_handle_t *handle = NULL; 3991 #endif 3992 OMX_U8 *buff = buffer; 3993 3994 if (!m_out_mem_ptr) { 3995 DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers"); 3996 eRet = allocate_output_headers(); 3997 #ifdef MAX_RES_1080P 3998 if(drv_ctx.decoder_format == VDEC_CODECTYPE_H264) 3999 { 4000 //allocate H264_mv_buffer 4001 eRet = vdec_alloc_h264_mv(); 4002 if (eRet) { 4003 DEBUG_PRINT_ERROR("ERROR in allocating MV buffers\n"); 4004 return OMX_ErrorInsufficientResources; 4005 } 4006 } 4007 #endif 4008 4009 } 4010 4011 if (eRet == OMX_ErrorNone) { 4012 for(i=0; i< drv_ctx.op_buf.actualcount; i++) { 4013 if(BITMASK_ABSENT(&m_out_bm_count,i)) 4014 { 4015 break; 4016 } 4017 } 4018 } 4019 4020 if(i >= drv_ctx.op_buf.actualcount) { 4021 eRet = OMX_ErrorInsufficientResources; 4022 } 4023 4024 if (eRet == OMX_ErrorNone) { 4025 #if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_) 4026 if(m_enable_android_native_buffers) { 4027 if (m_use_android_native_buffers) { 4028 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData; 4029 sp<android_native_buffer_t> nBuf = params->nativeBuffer; 4030 handle = (private_handle_t *)nBuf->handle; 4031 privateAppData = params->pAppPrivate; 4032 } else { 4033 handle = (private_handle_t *)buff; 4034 privateAppData = appData; 4035 } 4036 4037 if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) { 4038 DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback," 4039 " expected %u, got %lu", 4040 drv_ctx.op_buf.buffer_size, (OMX_U32)handle->size); 4041 return OMX_ErrorBadParameter; 4042 } 4043 4044 if (!m_use_android_native_buffers) { 4045 if (!secure_mode) { 4046 buff = (OMX_U8*)mmap(0, handle->size, 4047 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0); 4048 if (buff == MAP_FAILED) { 4049 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size); 4050 return OMX_ErrorInsufficientResources; 4051 } 4052 } 4053 } 4054 4055 if(!handle) { 4056 DEBUG_PRINT_ERROR("Native Buffer handle is NULL"); 4057 return OMX_ErrorBadParameter; 4058 } 4059 drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd; 4060 drv_ctx.ptr_outputbuffer[i].offset = 0; 4061 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff; 4062 drv_ctx.ptr_outputbuffer[i].mmaped_size = 4063 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size; 4064 native_buffer[i] = handle; 4065 } else 4066 #endif 4067 4068 if (!ouput_egl_buffers && !m_use_output_pmem) { 4069 #ifdef USE_ION 4070 drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory( 4071 drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment, 4072 &drv_ctx.op_buf_ion_info[i].ion_alloc_data, 4073 &drv_ctx.op_buf_ion_info[i].fd_ion_data,ION_FLAG_CACHED); 4074 if(drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) { 4075 return OMX_ErrorInsufficientResources; 4076 } 4077 drv_ctx.ptr_outputbuffer[i].pmem_fd = \ 4078 drv_ctx.op_buf_ion_info[i].fd_ion_data.fd; 4079 #else 4080 drv_ctx.ptr_outputbuffer[i].pmem_fd = \ 4081 open (MEM_DEVICE,O_RDWR); 4082 4083 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) { 4084 return OMX_ErrorInsufficientResources; 4085 } 4086 4087 if(drv_ctx.ptr_outputbuffer[i].pmem_fd == 0) 4088 { 4089 drv_ctx.ptr_outputbuffer[i].pmem_fd = \ 4090 open (MEM_DEVICE,O_RDWR); 4091 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) { 4092 return OMX_ErrorInsufficientResources; 4093 } 4094 } 4095 4096 if(!align_pmem_buffers(drv_ctx.ptr_outputbuffer[i].pmem_fd, 4097 drv_ctx.op_buf.buffer_size, 4098 drv_ctx.op_buf.alignment)) 4099 { 4100 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed"); 4101 close(drv_ctx.ptr_outputbuffer[i].pmem_fd); 4102 return OMX_ErrorInsufficientResources; 4103 } 4104 #endif 4105 if(!secure_mode) { 4106 drv_ctx.ptr_outputbuffer[i].bufferaddr = 4107 (unsigned char *)mmap(NULL, drv_ctx.op_buf.buffer_size, 4108 PROT_READ|PROT_WRITE, MAP_SHARED, 4109 drv_ctx.ptr_outputbuffer[i].pmem_fd,0); 4110 if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) { 4111 close(drv_ctx.ptr_outputbuffer[i].pmem_fd); 4112 #ifdef USE_ION 4113 free_ion_memory(&drv_ctx.op_buf_ion_info[i]); 4114 #endif 4115 return OMX_ErrorInsufficientResources; 4116 } 4117 } 4118 drv_ctx.ptr_outputbuffer[i].offset = 0; 4119 privateAppData = appData; 4120 } 4121 else { 4122 4123 DEBUG_PRINT_LOW("Use_op_buf: out_pmem=%d",m_use_output_pmem); 4124 4125 if (!appData || !bytes ) 4126 { 4127 DEBUG_PRINT_ERROR("\n Invalid appData or bytes"); 4128 return OMX_ErrorBadParameter; 4129 } 4130 4131 if(!secure_mode && !buffer) 4132 { 4133 DEBUG_PRINT_ERROR("\n Bad parameters for use buffer in EGL image case"); 4134 return OMX_ErrorBadParameter; 4135 } 4136 4137 4138 OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list; 4139 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info; 4140 pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData; 4141 if (!pmem_list->entryList || !pmem_list->entryList->entry || 4142 !pmem_list->nEntries || 4143 pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) { 4144 DEBUG_PRINT_ERROR("\n Pmem info not valid in use buffer"); 4145 return OMX_ErrorBadParameter; 4146 } 4147 pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) 4148 pmem_list->entryList->entry; 4149 DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%x", 4150 pmem_info->pmem_fd); 4151 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd; 4152 drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset; 4153 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff; 4154 drv_ctx.ptr_outputbuffer[i].mmaped_size = 4155 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size; 4156 privateAppData = appData; 4157 } 4158 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset; 4159 m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd; 4160 4161 *bufferHdr = (m_out_mem_ptr + i ); 4162 if(secure_mode) 4163 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr; 4164 setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT; 4165 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[i], 4166 sizeof (vdec_bufferpayload)); 4167 4168 ioctl_msg.in = &setbuffers; 4169 ioctl_msg.out = NULL; 4170 4171 DEBUG_PRINT_HIGH("\n Set the Output Buffer Idx: %d Addr: %x, pmem_fd=%0x%x", i, 4172 drv_ctx.ptr_outputbuffer[i],drv_ctx.ptr_outputbuffer[i].pmem_fd ); 4173 if (ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_SET_BUFFER, 4174 &ioctl_msg) < 0) 4175 { 4176 DEBUG_PRINT_ERROR("\n Set output buffer failed"); 4177 return OMX_ErrorInsufficientResources; 4178 } 4179 // found an empty buffer at i 4180 (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size; 4181 if (m_enable_android_native_buffers) { 4182 DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle); 4183 (*bufferHdr)->pBuffer = (OMX_U8 *)handle; 4184 } else { 4185 (*bufferHdr)->pBuffer = buff; 4186 } 4187 (*bufferHdr)->pAppPrivate = privateAppData; 4188 BITMASK_SET(&m_out_bm_count,i); 4189 } 4190 return eRet; 4191 } 4192 4193 /* ====================================================================== 4194 FUNCTION 4195 omx_vdec::use_input_heap_buffers 4196 4197 DESCRIPTION 4198 OMX Use Buffer Heap allocation method implementation. 4199 4200 PARAMETERS 4201 <TBD>. 4202 4203 RETURN VALUE 4204 OMX Error None , if everything successful. 4205 4206 ========================================================================== */ 4207 OMX_ERRORTYPE omx_vdec::use_input_heap_buffers( 4208 OMX_IN OMX_HANDLETYPE hComp, 4209 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 4210 OMX_IN OMX_U32 port, 4211 OMX_IN OMX_PTR appData, 4212 OMX_IN OMX_U32 bytes, 4213 OMX_IN OMX_U8* buffer) 4214 { 4215 DEBUG_PRINT_LOW("Inside %s, %p\n", __FUNCTION__, buffer); 4216 OMX_ERRORTYPE eRet = OMX_ErrorNone; 4217 if(!m_inp_heap_ptr) 4218 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) 4219 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), 4220 drv_ctx.ip_buf.actualcount); 4221 if(!m_phdr_pmem_ptr) 4222 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) 4223 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)), 4224 drv_ctx.ip_buf.actualcount); 4225 if(!m_inp_heap_ptr || !m_phdr_pmem_ptr) 4226 { 4227 DEBUG_PRINT_ERROR("Insufficent memory"); 4228 eRet = OMX_ErrorInsufficientResources; 4229 } 4230 else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount) 4231 { 4232 input_use_buffer = true; 4233 memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE)); 4234 m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer; 4235 m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes; 4236 m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData; 4237 m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput; 4238 m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax; 4239 *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt]; 4240 eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes); 4241 DEBUG_PRINT_HIGH("\n Heap buffer(%p) Pmem buffer(%p)", *bufferHdr, m_phdr_pmem_ptr[m_in_alloc_cnt]); 4242 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[m_in_alloc_cnt], NULL, NULL)) 4243 { 4244 DEBUG_PRINT_ERROR("\nERROR:Free_q is full"); 4245 return OMX_ErrorInsufficientResources; 4246 } 4247 m_in_alloc_cnt++; 4248 } 4249 else 4250 { 4251 DEBUG_PRINT_ERROR("All i/p buffers have been set!"); 4252 eRet = OMX_ErrorInsufficientResources; 4253 } 4254 return eRet; 4255 } 4256 4257 /* ====================================================================== 4258 FUNCTION 4259 omx_vdec::UseBuffer 4260 4261 DESCRIPTION 4262 OMX Use Buffer method implementation. 4263 4264 PARAMETERS 4265 <TBD>. 4266 4267 RETURN VALUE 4268 OMX Error None , if everything successful. 4269 4270 ========================================================================== */ 4271 OMX_ERRORTYPE omx_vdec::use_buffer( 4272 OMX_IN OMX_HANDLETYPE hComp, 4273 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 4274 OMX_IN OMX_U32 port, 4275 OMX_IN OMX_PTR appData, 4276 OMX_IN OMX_U32 bytes, 4277 OMX_IN OMX_U8* buffer) 4278 { 4279 OMX_ERRORTYPE error = OMX_ErrorNone; 4280 struct vdec_setbuffer_cmd setbuffers; 4281 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; 4282 4283 if (bufferHdr == NULL || bytes == 0) 4284 { 4285 DEBUG_PRINT_ERROR("bad param 0x%p %ld",bufferHdr, bytes); 4286 return OMX_ErrorBadParameter; 4287 } 4288 4289 if(!secure_mode && buffer == NULL) { 4290 DEBUG_PRINT_ERROR("bad param 0x%p",buffer); 4291 return OMX_ErrorBadParameter; 4292 } 4293 4294 if(m_state == OMX_StateInvalid) 4295 { 4296 DEBUG_PRINT_ERROR("Use Buffer in Invalid State\n"); 4297 return OMX_ErrorInvalidState; 4298 } 4299 if(port == OMX_CORE_INPUT_PORT_INDEX) 4300 error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer); 4301 else if(port == OMX_CORE_OUTPUT_PORT_INDEX) 4302 error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested 4303 else 4304 { 4305 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port); 4306 error = OMX_ErrorBadPortIndex; 4307 } 4308 DEBUG_PRINT_LOW("Use Buffer: port %u, buffer %p, eRet %d", port, *bufferHdr, error); 4309 if(error == OMX_ErrorNone) 4310 { 4311 if(allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) 4312 { 4313 // Send the callback now 4314 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING); 4315 post_event(OMX_CommandStateSet,OMX_StateIdle, 4316 OMX_COMPONENT_GENERATE_EVENT); 4317 } 4318 if(port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated && 4319 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) 4320 { 4321 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING); 4322 post_event(OMX_CommandPortEnable, 4323 OMX_CORE_INPUT_PORT_INDEX, 4324 OMX_COMPONENT_GENERATE_EVENT); 4325 } 4326 else if(port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated && 4327 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) 4328 { 4329 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING); 4330 post_event(OMX_CommandPortEnable, 4331 OMX_CORE_OUTPUT_PORT_INDEX, 4332 OMX_COMPONENT_GENERATE_EVENT); 4333 } 4334 } 4335 return error; 4336 } 4337 4338 OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex, 4339 OMX_BUFFERHEADERTYPE *pmem_bufferHdr) 4340 { 4341 if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes) 4342 { 4343 if(m_inp_heap_ptr[bufferindex].pBuffer) 4344 free(m_inp_heap_ptr[bufferindex].pBuffer); 4345 m_inp_heap_ptr[bufferindex].pBuffer = NULL; 4346 } 4347 if (pmem_bufferHdr) 4348 free_input_buffer(pmem_bufferHdr); 4349 return OMX_ErrorNone; 4350 } 4351 4352 OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr) 4353 { 4354 unsigned int index = 0; 4355 if (bufferHdr == NULL || m_inp_mem_ptr == NULL) 4356 { 4357 return OMX_ErrorBadParameter; 4358 } 4359 4360 index = bufferHdr - m_inp_mem_ptr; 4361 DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index); 4362 4363 if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer) 4364 { 4365 DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index); 4366 if (drv_ctx.ptr_inputbuffer[index].pmem_fd > 0) 4367 { 4368 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; 4369 struct vdec_setbuffer_cmd setbuffers; 4370 setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT; 4371 memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index], 4372 sizeof (vdec_bufferpayload)); 4373 ioctl_msg.in = &setbuffers; 4374 ioctl_msg.out = NULL; 4375 int ioctl_r = ioctl (drv_ctx.video_driver_fd, 4376 VDEC_IOCTL_FREE_BUFFER, &ioctl_msg); 4377 if (ioctl_r < 0) 4378 { 4379 DEBUG_PRINT_ERROR("\nVDEC_IOCTL_FREE_BUFFER returned error %d", ioctl_r); 4380 } 4381 if (!secure_mode) { 4382 DEBUG_PRINT_LOW("\n unmap the input buffer fd=%d", 4383 drv_ctx.ptr_inputbuffer[index].pmem_fd); 4384 DEBUG_PRINT_LOW("\n unmap the input buffer size=%d address = %d", 4385 drv_ctx.ptr_inputbuffer[index].mmaped_size, 4386 drv_ctx.ptr_inputbuffer[index].bufferaddr); 4387 munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr, 4388 drv_ctx.ptr_inputbuffer[index].mmaped_size); 4389 } 4390 close (drv_ctx.ptr_inputbuffer[index].pmem_fd); 4391 drv_ctx.ptr_inputbuffer[index].pmem_fd = -1; 4392 if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr) 4393 { 4394 free(m_desc_buffer_ptr[index].buf_addr); 4395 m_desc_buffer_ptr[index].buf_addr = NULL; 4396 m_desc_buffer_ptr[index].desc_data_size = 0; 4397 } 4398 #ifdef USE_ION 4399 free_ion_memory(&drv_ctx.ip_buf_ion_info[index]); 4400 #endif 4401 } 4402 } 4403 4404 return OMX_ErrorNone; 4405 } 4406 4407 OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr) 4408 { 4409 unsigned int index = 0; 4410 4411 if (bufferHdr == NULL || m_out_mem_ptr == NULL) 4412 { 4413 DEBUG_PRINT_ERROR("\nfree_output_buffer ERROR"); 4414 return OMX_ErrorBadParameter; 4415 } 4416 4417 index = bufferHdr - m_out_mem_ptr; 4418 DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d",index); 4419 4420 if (index < drv_ctx.op_buf.actualcount 4421 && drv_ctx.ptr_outputbuffer) 4422 { 4423 DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d addr = %x", index, 4424 drv_ctx.ptr_outputbuffer[index].bufferaddr); 4425 4426 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; 4427 struct vdec_setbuffer_cmd setbuffers; 4428 setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT; 4429 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index], 4430 sizeof (vdec_bufferpayload)); 4431 ioctl_msg.in = &setbuffers; 4432 ioctl_msg.out = NULL; 4433 DEBUG_PRINT_LOW("\nRelease the Output Buffer"); 4434 if (ioctl (drv_ctx.video_driver_fd, VDEC_IOCTL_FREE_BUFFER, 4435 &ioctl_msg) < 0) 4436 DEBUG_PRINT_ERROR("\nRelease output buffer failed in VCD"); 4437 4438 #ifdef _ANDROID_ 4439 if(m_enable_android_native_buffers) { 4440 if(drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) { 4441 if(!secure_mode) { 4442 munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr, 4443 drv_ctx.ptr_outputbuffer[index].mmaped_size); 4444 } 4445 } 4446 drv_ctx.ptr_outputbuffer[index].pmem_fd = -1; 4447 } else { 4448 #endif 4449 if (drv_ctx.ptr_outputbuffer[index].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem) 4450 { 4451 if(!secure_mode) { 4452 DEBUG_PRINT_LOW("\n unmap the output buffer fd = %d", 4453 drv_ctx.ptr_outputbuffer[index].pmem_fd); 4454 DEBUG_PRINT_LOW("\n unmap the ouput buffer size=%d address = %d", 4455 drv_ctx.ptr_outputbuffer[index].mmaped_size, 4456 drv_ctx.ptr_outputbuffer[index].bufferaddr); 4457 munmap (drv_ctx.ptr_outputbuffer[index].bufferaddr, 4458 drv_ctx.ptr_outputbuffer[index].mmaped_size); 4459 } 4460 #ifdef USE_ION 4461 free_ion_memory(&drv_ctx.op_buf_ion_info[index]); 4462 #endif 4463 close (drv_ctx.ptr_outputbuffer[index].pmem_fd); 4464 drv_ctx.ptr_outputbuffer[index].pmem_fd = -1; 4465 #ifdef _ANDROID_ 4466 m_heap_ptr[index].video_heap_ptr = NULL; 4467 m_heap_count = m_heap_count - 1; 4468 if (m_heap_count == 0) 4469 { 4470 free(m_heap_ptr); 4471 m_heap_ptr = NULL; 4472 } 4473 #endif // _ANDROID_ 4474 } 4475 #ifdef _ANDROID_ 4476 } 4477 #endif 4478 } 4479 #ifdef MAX_RES_1080P 4480 if(drv_ctx.decoder_format == VDEC_CODECTYPE_H264) 4481 { 4482 vdec_dealloc_h264_mv(); 4483 } 4484 #endif 4485 4486 return OMX_ErrorNone; 4487 4488 } 4489 4490 OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE hComp, 4491 OMX_BUFFERHEADERTYPE **bufferHdr, 4492 OMX_U32 port, 4493 OMX_PTR appData, 4494 OMX_U32 bytes) 4495 { 4496 OMX_BUFFERHEADERTYPE *input = NULL; 4497 unsigned char *buf_addr = NULL; 4498 OMX_ERRORTYPE eRet = OMX_ErrorNone; 4499 unsigned i = 0; 4500 4501 /* Sanity Check*/ 4502 if (bufferHdr == NULL) 4503 { 4504 return OMX_ErrorBadParameter; 4505 } 4506 4507 if (m_inp_heap_ptr == NULL) 4508 { 4509 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \ 4510 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), 4511 drv_ctx.ip_buf.actualcount); 4512 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \ 4513 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)), 4514 drv_ctx.ip_buf.actualcount); 4515 4516 if (m_inp_heap_ptr == NULL) 4517 { 4518 DEBUG_PRINT_ERROR("\n m_inp_heap_ptr Allocation failed "); 4519 return OMX_ErrorInsufficientResources; 4520 } 4521 } 4522 4523 /*Find a Free index*/ 4524 for(i=0; i< drv_ctx.ip_buf.actualcount; i++) 4525 { 4526 if(BITMASK_ABSENT(&m_heap_inp_bm_count,i)) 4527 { 4528 DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i); 4529 break; 4530 } 4531 } 4532 4533 if (i < drv_ctx.ip_buf.actualcount) 4534 { 4535 buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size); 4536 4537 if (buf_addr == NULL) 4538 { 4539 return OMX_ErrorInsufficientResources; 4540 } 4541 4542 *bufferHdr = (m_inp_heap_ptr + i); 4543 input = *bufferHdr; 4544 BITMASK_SET(&m_heap_inp_bm_count,i); 4545 4546 input->pBuffer = (OMX_U8 *)buf_addr; 4547 input->nSize = sizeof(OMX_BUFFERHEADERTYPE); 4548 input->nVersion.nVersion = OMX_SPEC_VERSION; 4549 input->nAllocLen = drv_ctx.ip_buf.buffer_size; 4550 input->pAppPrivate = appData; 4551 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX; 4552 DEBUG_PRINT_LOW("\n Address of Heap Buffer %p",*bufferHdr ); 4553 eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes); 4554 DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",m_phdr_pmem_ptr [i] ); 4555 /*Add the Buffers to freeq*/ 4556 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr [i],NULL,NULL)) 4557 { 4558 DEBUG_PRINT_ERROR("\nERROR:Free_q is full"); 4559 return OMX_ErrorInsufficientResources; 4560 } 4561 } 4562 else 4563 { 4564 return OMX_ErrorBadParameter; 4565 } 4566 4567 return eRet; 4568 4569 } 4570 4571 4572 /* ====================================================================== 4573 FUNCTION 4574 omx_vdec::AllocateInputBuffer 4575 4576 DESCRIPTION 4577 Helper function for allocate buffer in the input pin 4578 4579 PARAMETERS 4580 None. 4581 4582 RETURN VALUE 4583 true/false 4584 4585 ========================================================================== */ 4586 OMX_ERRORTYPE omx_vdec::allocate_input_buffer( 4587 OMX_IN OMX_HANDLETYPE hComp, 4588 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 4589 OMX_IN OMX_U32 port, 4590 OMX_IN OMX_PTR appData, 4591 OMX_IN OMX_U32 bytes) 4592 { 4593 4594 OMX_ERRORTYPE eRet = OMX_ErrorNone; 4595 struct vdec_setbuffer_cmd setbuffers; 4596 OMX_BUFFERHEADERTYPE *input = NULL; 4597 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; 4598 unsigned i = 0; 4599 unsigned char *buf_addr = NULL; 4600 int pmem_fd = -1; 4601 4602 if(bytes != drv_ctx.ip_buf.buffer_size) 4603 { 4604 DEBUG_PRINT_LOW("\n Requested Size is wrong %d epected is %d", 4605 bytes, drv_ctx.ip_buf.buffer_size); 4606 //return OMX_ErrorBadParameter; 4607 } 4608 4609 if(!m_inp_mem_ptr) 4610 { 4611 DEBUG_PRINT_HIGH("\n Allocate i/p buffer Header: Cnt(%d) Sz(%d)", 4612 drv_ctx.ip_buf.actualcount, 4613 drv_ctx.ip_buf.buffer_size); 4614 4615 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \ 4616 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount); 4617 4618 if (m_inp_mem_ptr == NULL) 4619 { 4620 return OMX_ErrorInsufficientResources; 4621 } 4622 4623 drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \ 4624 calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount); 4625 4626 if (drv_ctx.ptr_inputbuffer == NULL) 4627 { 4628 return OMX_ErrorInsufficientResources; 4629 } 4630 #ifdef USE_ION 4631 drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \ 4632 calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount); 4633 4634 if (drv_ctx.ip_buf_ion_info == NULL) 4635 { 4636 return OMX_ErrorInsufficientResources; 4637 } 4638 #endif 4639 4640 for (i=0; i < drv_ctx.ip_buf.actualcount; i++) 4641 { 4642 drv_ctx.ptr_inputbuffer [i].pmem_fd = -1; 4643 #ifdef USE_ION 4644 drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1; 4645 #endif 4646 } 4647 } 4648 4649 for(i=0; i< drv_ctx.ip_buf.actualcount; i++) 4650 { 4651 if(BITMASK_ABSENT(&m_inp_bm_count,i)) 4652 { 4653 DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i); 4654 break; 4655 } 4656 } 4657 4658 if(i < drv_ctx.ip_buf.actualcount) 4659 { 4660 DEBUG_PRINT_LOW("\n Allocate input Buffer"); 4661 4662 #ifdef USE_ION 4663 drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory( 4664 drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment, 4665 &drv_ctx.ip_buf_ion_info[i].ion_alloc_data, 4666 &drv_ctx.ip_buf_ion_info[i].fd_ion_data,ION_FLAG_CACHED); 4667 if(drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) { 4668 return OMX_ErrorInsufficientResources; 4669 } 4670 pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd; 4671 #else 4672 pmem_fd = open (MEM_DEVICE,O_RDWR); 4673 4674 if (pmem_fd < 0) 4675 { 4676 DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer"); 4677 return OMX_ErrorInsufficientResources; 4678 } 4679 4680 if (pmem_fd == 0) 4681 { 4682 pmem_fd = open (MEM_DEVICE,O_RDWR); 4683 4684 if (pmem_fd < 0) 4685 { 4686 DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer"); 4687 return OMX_ErrorInsufficientResources; 4688 } 4689 } 4690 4691 if(!align_pmem_buffers(pmem_fd, drv_ctx.ip_buf.buffer_size, 4692 drv_ctx.ip_buf.alignment)) 4693 { 4694 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed"); 4695 close(pmem_fd); 4696 return OMX_ErrorInsufficientResources; 4697 } 4698 #endif 4699 if (!secure_mode) { 4700 buf_addr = (unsigned char *)mmap(NULL, 4701 drv_ctx.ip_buf.buffer_size, 4702 PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0); 4703 4704 if (buf_addr == MAP_FAILED) 4705 { 4706 close(pmem_fd); 4707 #ifdef USE_ION 4708 free_ion_memory(&drv_ctx.ip_buf_ion_info[i]); 4709 #endif 4710 DEBUG_PRINT_ERROR("\n Map Failed to allocate input buffer"); 4711 return OMX_ErrorInsufficientResources; 4712 } 4713 } 4714 *bufferHdr = (m_inp_mem_ptr + i); 4715 if (secure_mode) 4716 drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr; 4717 else 4718 drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr; 4719 drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd; 4720 drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size; 4721 drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size; 4722 drv_ctx.ptr_inputbuffer [i].offset = 0; 4723 4724 setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT; 4725 memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer [i], 4726 sizeof (vdec_bufferpayload)); 4727 ioctl_msg.in = &setbuffers; 4728 ioctl_msg.out = NULL; 4729 4730 if (ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_SET_BUFFER, 4731 &ioctl_msg) < 0) 4732 { 4733 DEBUG_PRINT_ERROR("\n Set Buffers Failed"); 4734 return OMX_ErrorInsufficientResources; 4735 } 4736 4737 input = *bufferHdr; 4738 BITMASK_SET(&m_inp_bm_count,i); 4739 DEBUG_PRINT_LOW("\n Buffer address %p of pmem",*bufferHdr); 4740 if (secure_mode) 4741 input->pBuffer = (OMX_U8 *)drv_ctx.ptr_inputbuffer [i].pmem_fd; 4742 else 4743 input->pBuffer = (OMX_U8 *)buf_addr; 4744 input->nSize = sizeof(OMX_BUFFERHEADERTYPE); 4745 input->nVersion.nVersion = OMX_SPEC_VERSION; 4746 input->nAllocLen = drv_ctx.ip_buf.buffer_size; 4747 input->pAppPrivate = appData; 4748 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX; 4749 input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i]; 4750 4751 if (drv_ctx.disable_dmx) 4752 { 4753 eRet = allocate_desc_buffer(i); 4754 } 4755 } 4756 else 4757 { 4758 DEBUG_PRINT_ERROR("\nERROR:Input Buffer Index not found"); 4759 eRet = OMX_ErrorInsufficientResources; 4760 } 4761 return eRet; 4762 } 4763 4764 4765 /* ====================================================================== 4766 FUNCTION 4767 omx_vdec::AllocateOutputBuffer 4768 4769 DESCRIPTION 4770 Helper fn for AllocateBuffer in the output pin 4771 4772 PARAMETERS 4773 <TBD>. 4774 4775 RETURN VALUE 4776 OMX Error None if everything went well. 4777 4778 ========================================================================== */ 4779 OMX_ERRORTYPE omx_vdec::allocate_output_buffer( 4780 OMX_IN OMX_HANDLETYPE hComp, 4781 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 4782 OMX_IN OMX_U32 port, 4783 OMX_IN OMX_PTR appData, 4784 OMX_IN OMX_U32 bytes) 4785 { 4786 OMX_ERRORTYPE eRet = OMX_ErrorNone; 4787 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header 4788 unsigned i= 0; // Temporary counter 4789 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; 4790 struct vdec_setbuffer_cmd setbuffers; 4791 #ifdef USE_ION 4792 int ion_device_fd =-1; 4793 struct ion_allocation_data ion_alloc_data; 4794 struct ion_fd_data fd_ion_data; 4795 #endif 4796 4797 int nBufHdrSize = 0; 4798 int nPlatformEntrySize = 0; 4799 int nPlatformListSize = 0; 4800 int nPMEMInfoSize = 0; 4801 int pmem_fd = -1; 4802 unsigned char *pmem_baseaddress = NULL; 4803 4804 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList; 4805 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry; 4806 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo; 4807 4808 if (!m_out_mem_ptr) 4809 { 4810 DEBUG_PRINT_HIGH("\n Allocate o/p buffer Header: Cnt(%d) Sz(%d)", 4811 drv_ctx.op_buf.actualcount, 4812 drv_ctx.op_buf.buffer_size); 4813 4814 DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)\n", 4815 drv_ctx.op_buf.actualcount); 4816 4817 nBufHdrSize = drv_ctx.op_buf.actualcount * 4818 sizeof(OMX_BUFFERHEADERTYPE); 4819 4820 nPMEMInfoSize = drv_ctx.op_buf.actualcount * 4821 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO); 4822 nPlatformListSize = drv_ctx.op_buf.actualcount * 4823 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST); 4824 nPlatformEntrySize = drv_ctx.op_buf.actualcount * 4825 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY); 4826 4827 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize, 4828 sizeof(OMX_BUFFERHEADERTYPE), 4829 nPMEMInfoSize, 4830 nPlatformListSize); 4831 DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d \n",nPlatformEntrySize, 4832 drv_ctx.op_buf.actualcount); 4833 4834 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1); 4835 // Alloc mem for platform specific info 4836 char *pPtr=NULL; 4837 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize + 4838 nPMEMInfoSize,1); 4839 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *)\ 4840 calloc (sizeof(struct vdec_bufferpayload), 4841 drv_ctx.op_buf.actualcount); 4842 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\ 4843 calloc (sizeof (struct vdec_output_frameinfo), 4844 drv_ctx.op_buf.actualcount); 4845 #ifdef USE_ION 4846 drv_ctx.op_buf_ion_info = (struct vdec_ion *)\ 4847 calloc (sizeof(struct vdec_ion), 4848 drv_ctx.op_buf.actualcount); 4849 #endif 4850 #ifdef _ANDROID_ 4851 m_heap_ptr = (struct vidc_heap *)\ 4852 calloc (sizeof(struct vidc_heap), 4853 drv_ctx.op_buf.actualcount); 4854 #endif 4855 4856 if(m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer 4857 && drv_ctx.ptr_respbuffer 4858 #ifdef _ANDROID_ 4859 && m_heap_ptr 4860 #endif 4861 ) 4862 { 4863 drv_ctx.ptr_outputbuffer[0].mmaped_size = 4864 (drv_ctx.op_buf.buffer_size * 4865 drv_ctx.op_buf.actualcount); 4866 bufHdr = m_out_mem_ptr; 4867 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr); 4868 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *) 4869 (((char *) m_platform_list) + nPlatformListSize); 4870 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) 4871 (((char *) m_platform_entry) + nPlatformEntrySize); 4872 pPlatformList = m_platform_list; 4873 pPlatformEntry = m_platform_entry; 4874 pPMEMInfo = m_pmem_info; 4875 4876 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr); 4877 4878 // Settting the entire storage nicely 4879 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr, m_out_mem_ptr,pPlatformEntry); 4880 DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo); 4881 for(i=0; i < drv_ctx.op_buf.actualcount ; i++) 4882 { 4883 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE); 4884 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION; 4885 // Set the values when we determine the right HxW param 4886 bufHdr->nAllocLen = 0; 4887 bufHdr->nFilledLen = 0; 4888 bufHdr->pAppPrivate = NULL; 4889 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 4890 // Platform specific PMEM Information 4891 // Initialize the Platform Entry 4892 //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d\n",i); 4893 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM; 4894 pPlatformEntry->entry = pPMEMInfo; 4895 // Initialize the Platform List 4896 pPlatformList->nEntries = 1; 4897 pPlatformList->entryList = pPlatformEntry; 4898 // Keep pBuffer NULL till vdec is opened 4899 bufHdr->pBuffer = NULL; 4900 4901 pPMEMInfo->offset = 0; 4902 pPMEMInfo->pmem_fd = 0; 4903 bufHdr->pPlatformPrivate = pPlatformList; 4904 drv_ctx.ptr_outputbuffer[i].pmem_fd = -1; 4905 #ifdef USE_ION 4906 drv_ctx.op_buf_ion_info[i].ion_device_fd =-1; 4907 #endif 4908 /*Create a mapping between buffers*/ 4909 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i]; 4910 drv_ctx.ptr_respbuffer[i].client_data = (void *)\ 4911 &drv_ctx.ptr_outputbuffer[i]; 4912 #ifdef _ANDROID_ 4913 m_heap_ptr[i].video_heap_ptr = NULL; 4914 #endif 4915 // Move the buffer and buffer header pointers 4916 bufHdr++; 4917 pPMEMInfo++; 4918 pPlatformEntry++; 4919 pPlatformList++; 4920 } 4921 #ifdef MAX_RES_1080P 4922 if(eRet == OMX_ErrorNone && drv_ctx.decoder_format == VDEC_CODECTYPE_H264) 4923 { 4924 //Allocate the h264_mv_buffer 4925 eRet = vdec_alloc_h264_mv(); 4926 if(eRet) { 4927 DEBUG_PRINT_ERROR("ERROR in allocating MV buffers\n"); 4928 return OMX_ErrorInsufficientResources; 4929 } 4930 } 4931 #endif 4932 } 4933 else 4934 { 4935 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%x][0x%x]\n",\ 4936 m_out_mem_ptr, pPtr); 4937 if(m_out_mem_ptr) 4938 { 4939 free(m_out_mem_ptr); 4940 m_out_mem_ptr = NULL; 4941 } 4942 if(pPtr) 4943 { 4944 free(pPtr); 4945 pPtr = NULL; 4946 } 4947 if(drv_ctx.ptr_outputbuffer) 4948 { 4949 free(drv_ctx.ptr_outputbuffer); 4950 drv_ctx.ptr_outputbuffer = NULL; 4951 } 4952 if(drv_ctx.ptr_respbuffer) 4953 { 4954 free(drv_ctx.ptr_respbuffer); 4955 drv_ctx.ptr_respbuffer = NULL; 4956 } 4957 #ifdef USE_ION 4958 if (drv_ctx.op_buf_ion_info) { 4959 DEBUG_PRINT_LOW("\n Free o/p ion context"); 4960 free(drv_ctx.op_buf_ion_info); 4961 drv_ctx.op_buf_ion_info = NULL; 4962 } 4963 #endif 4964 eRet = OMX_ErrorInsufficientResources; 4965 } 4966 } 4967 4968 for (i=0; i< drv_ctx.op_buf.actualcount; i++) 4969 { 4970 if(BITMASK_ABSENT(&m_out_bm_count,i)) 4971 { 4972 DEBUG_PRINT_LOW("\n Found a Free Output Buffer Index %d",i); 4973 break; 4974 } 4975 } 4976 4977 if (i < drv_ctx.op_buf.actualcount) 4978 { 4979 DEBUG_PRINT_LOW("\n Allocate Output Buffer"); 4980 4981 #ifdef USE_ION 4982 drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory( 4983 drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment, 4984 &drv_ctx.op_buf_ion_info[i].ion_alloc_data, 4985 &drv_ctx.op_buf_ion_info[i].fd_ion_data, ION_FLAG_CACHED); 4986 if (drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) { 4987 return OMX_ErrorInsufficientResources; 4988 } 4989 pmem_fd = drv_ctx.op_buf_ion_info[i].fd_ion_data.fd; 4990 #else 4991 pmem_fd = open (MEM_DEVICE,O_RDWR); 4992 4993 if (pmem_fd < 0) 4994 { 4995 DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d", 4996 drv_ctx.op_buf.buffer_size); 4997 return OMX_ErrorInsufficientResources; 4998 } 4999 5000 if (pmem_fd == 0) 5001 { 5002 pmem_fd = open (MEM_DEVICE,O_RDWR); 5003 5004 if (pmem_fd < 0) 5005 { 5006 DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d", 5007 drv_ctx.op_buf.buffer_size); 5008 return OMX_ErrorInsufficientResources; 5009 } 5010 } 5011 5012 if (!align_pmem_buffers(pmem_fd, drv_ctx.op_buf.buffer_size, 5013 drv_ctx.op_buf.alignment)) 5014 { 5015 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed"); 5016 close(pmem_fd); 5017 return OMX_ErrorInsufficientResources; 5018 } 5019 #endif 5020 if (!secure_mode) { 5021 pmem_baseaddress = (unsigned char *)mmap(NULL, 5022 drv_ctx.op_buf.buffer_size, 5023 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0); 5024 5025 if (pmem_baseaddress == MAP_FAILED) 5026 { 5027 DEBUG_PRINT_ERROR("\n MMAP failed for Size %d", 5028 drv_ctx.op_buf.buffer_size); 5029 close(pmem_fd); 5030 #ifdef USE_ION 5031 free_ion_memory(&drv_ctx.op_buf_ion_info[i]); 5032 #endif 5033 return OMX_ErrorInsufficientResources; 5034 } 5035 } 5036 5037 *bufferHdr = (m_out_mem_ptr + i); 5038 if (secure_mode) 5039 drv_ctx.ptr_outputbuffer [i].bufferaddr = *bufferHdr; 5040 else 5041 drv_ctx.ptr_outputbuffer [i].bufferaddr = pmem_baseaddress; 5042 5043 drv_ctx.ptr_outputbuffer [i].pmem_fd = pmem_fd; 5044 drv_ctx.ptr_outputbuffer [i].buffer_len = drv_ctx.op_buf.buffer_size; 5045 drv_ctx.ptr_outputbuffer [i].mmaped_size = drv_ctx.op_buf.buffer_size; 5046 drv_ctx.ptr_outputbuffer [i].offset = 0; 5047 5048 #ifdef _ANDROID_ 5049 #ifdef USE_ION 5050 m_heap_ptr[i].video_heap_ptr = new VideoHeap (drv_ctx.op_buf_ion_info[i].ion_device_fd, 5051 drv_ctx.op_buf.buffer_size, 5052 pmem_baseaddress, 5053 ion_alloc_data.handle, 5054 pmem_fd); 5055 m_heap_count = m_heap_count + 1; 5056 #else 5057 m_heap_ptr[i].video_heap_ptr = new VideoHeap (pmem_fd, 5058 drv_ctx.op_buf.buffer_size, 5059 pmem_baseaddress); 5060 #endif 5061 #endif 5062 5063 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset; 5064 #ifdef _ANDROID_ 5065 m_pmem_info[i].pmem_fd = (OMX_U32) m_heap_ptr[i].video_heap_ptr.get (); 5066 #else 5067 m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd ; 5068 #endif 5069 setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT; 5070 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer [i], 5071 sizeof (vdec_bufferpayload)); 5072 ioctl_msg.in = &setbuffers; 5073 ioctl_msg.out = NULL; 5074 5075 DEBUG_PRINT_LOW("\n Set the Output Buffer Idx: %d Addr: %x", i, drv_ctx.ptr_outputbuffer[i]); 5076 if (ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_SET_BUFFER, 5077 &ioctl_msg) < 0) 5078 { 5079 DEBUG_PRINT_ERROR("\n Set output buffer failed"); 5080 return OMX_ErrorInsufficientResources; 5081 } 5082 5083 // found an empty buffer at i 5084 (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size; 5085 (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr; 5086 (*bufferHdr)->pAppPrivate = appData; 5087 BITMASK_SET(&m_out_bm_count,i); 5088 5089 } 5090 else 5091 { 5092 DEBUG_PRINT_ERROR("\nERROR:Output Buffer Index not found"); 5093 eRet = OMX_ErrorInsufficientResources; 5094 } 5095 return eRet; 5096 } 5097 5098 5099 // AllocateBuffer -- API Call 5100 /* ====================================================================== 5101 FUNCTION 5102 omx_vdec::AllocateBuffer 5103 5104 DESCRIPTION 5105 Returns zero if all the buffers released.. 5106 5107 PARAMETERS 5108 None. 5109 5110 RETURN VALUE 5111 true/false 5112 5113 ========================================================================== */ 5114 OMX_ERRORTYPE omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp, 5115 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 5116 OMX_IN OMX_U32 port, 5117 OMX_IN OMX_PTR appData, 5118 OMX_IN OMX_U32 bytes) 5119 { 5120 unsigned i = 0; 5121 OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type 5122 5123 DEBUG_PRINT_LOW("\n Allocate buffer on port %d \n", (int)port); 5124 if(m_state == OMX_StateInvalid) 5125 { 5126 DEBUG_PRINT_ERROR("Allocate Buf in Invalid State\n"); 5127 return OMX_ErrorInvalidState; 5128 } 5129 5130 if(port == OMX_CORE_INPUT_PORT_INDEX) 5131 { 5132 if (arbitrary_bytes) 5133 { 5134 eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes); 5135 } 5136 else 5137 { 5138 eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes); 5139 } 5140 } 5141 else if(port == OMX_CORE_OUTPUT_PORT_INDEX) 5142 { 5143 eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port, 5144 appData,bytes); 5145 } 5146 else 5147 { 5148 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port); 5149 eRet = OMX_ErrorBadPortIndex; 5150 } 5151 DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done"); 5152 if(eRet == OMX_ErrorNone) 5153 { 5154 if(allocate_done()){ 5155 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) 5156 { 5157 // Send the callback now 5158 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING); 5159 post_event(OMX_CommandStateSet,OMX_StateIdle, 5160 OMX_COMPONENT_GENERATE_EVENT); 5161 } 5162 } 5163 if(port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated) 5164 { 5165 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) 5166 { 5167 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING); 5168 post_event(OMX_CommandPortEnable, 5169 OMX_CORE_INPUT_PORT_INDEX, 5170 OMX_COMPONENT_GENERATE_EVENT); 5171 } 5172 } 5173 if(port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated) 5174 { 5175 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) 5176 { 5177 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING); 5178 post_event(OMX_CommandPortEnable, 5179 OMX_CORE_OUTPUT_PORT_INDEX, 5180 OMX_COMPONENT_GENERATE_EVENT); 5181 } 5182 } 5183 } 5184 DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d\n",eRet); 5185 return eRet; 5186 } 5187 5188 // Free Buffer - API call 5189 /* ====================================================================== 5190 FUNCTION 5191 omx_vdec::FreeBuffer 5192 5193 DESCRIPTION 5194 5195 PARAMETERS 5196 None. 5197 5198 RETURN VALUE 5199 true/false 5200 5201 ========================================================================== */ 5202 OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp, 5203 OMX_IN OMX_U32 port, 5204 OMX_IN OMX_BUFFERHEADERTYPE* buffer) 5205 { 5206 OMX_ERRORTYPE eRet = OMX_ErrorNone; 5207 unsigned int nPortIndex; 5208 5209 DEBUG_PRINT_LOW("In for decoder free_buffer \n"); 5210 5211 if(m_state == OMX_StateIdle && 5212 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) 5213 { 5214 DEBUG_PRINT_LOW(" free buffer while Component in Loading pending\n"); 5215 } 5216 else if((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)|| 5217 (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX)) 5218 { 5219 DEBUG_PRINT_LOW("Free Buffer while port %d disabled\n", port); 5220 } 5221 else if(m_state == OMX_StateExecuting || m_state == OMX_StatePause) 5222 { 5223 DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled\n"); 5224 post_event(OMX_EventError, 5225 OMX_ErrorPortUnpopulated, 5226 OMX_COMPONENT_GENERATE_EVENT); 5227 5228 return OMX_ErrorIncorrectStateOperation; 5229 } 5230 else if (m_state != OMX_StateInvalid) 5231 { 5232 DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers\n"); 5233 post_event(OMX_EventError, 5234 OMX_ErrorPortUnpopulated, 5235 OMX_COMPONENT_GENERATE_EVENT); 5236 } 5237 5238 if(port == OMX_CORE_INPUT_PORT_INDEX) 5239 { 5240 /*Check if arbitrary bytes*/ 5241 if(!arbitrary_bytes && !input_use_buffer) 5242 nPortIndex = buffer - m_inp_mem_ptr; 5243 else 5244 nPortIndex = buffer - m_inp_heap_ptr; 5245 5246 DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d \n", nPortIndex); 5247 if(nPortIndex < drv_ctx.ip_buf.actualcount) 5248 { 5249 // Clear the bit associated with it. 5250 BITMASK_CLEAR(&m_inp_bm_count,nPortIndex); 5251 BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex); 5252 if (input_use_buffer == true) 5253 { 5254 5255 DEBUG_PRINT_LOW("\n Free pmem Buffer index %d",nPortIndex); 5256 if(m_phdr_pmem_ptr) 5257 free_input_buffer(m_phdr_pmem_ptr[nPortIndex]); 5258 } 5259 else 5260 { 5261 if (arbitrary_bytes) 5262 { 5263 if(m_phdr_pmem_ptr) 5264 free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]); 5265 else 5266 free_input_buffer(nPortIndex,NULL); 5267 } 5268 else 5269 free_input_buffer(buffer); 5270 } 5271 m_inp_bPopulated = OMX_FALSE; 5272 /*Free the Buffer Header*/ 5273 if (release_input_done()) 5274 { 5275 DEBUG_PRINT_HIGH("\n ALL input buffers are freed/released"); 5276 free_input_buffer_header(); 5277 } 5278 } 5279 else 5280 { 5281 DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid\n"); 5282 eRet = OMX_ErrorBadPortIndex; 5283 } 5284 5285 if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING) 5286 && release_input_done()) 5287 { 5288 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n"); 5289 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING); 5290 post_event(OMX_CommandPortDisable, 5291 OMX_CORE_INPUT_PORT_INDEX, 5292 OMX_COMPONENT_GENERATE_EVENT); 5293 } 5294 } 5295 else if(port == OMX_CORE_OUTPUT_PORT_INDEX) 5296 { 5297 // check if the buffer is valid 5298 nPortIndex = buffer - client_buffers.get_il_buf_hdr(); 5299 if(nPortIndex < drv_ctx.op_buf.actualcount) 5300 { 5301 DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d \n", nPortIndex); 5302 // Clear the bit associated with it. 5303 BITMASK_CLEAR(&m_out_bm_count,nPortIndex); 5304 m_out_bPopulated = OMX_FALSE; 5305 client_buffers.free_output_buffer (buffer); 5306 5307 if (release_output_done()) 5308 { 5309 free_output_buffer_header(); 5310 } 5311 } 5312 else 5313 { 5314 DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid\n"); 5315 eRet = OMX_ErrorBadPortIndex; 5316 } 5317 if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING) 5318 && release_output_done()) 5319 { 5320 DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it\n"); 5321 5322 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n"); 5323 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING); 5324 5325 post_event(OMX_CommandPortDisable, 5326 OMX_CORE_OUTPUT_PORT_INDEX, 5327 OMX_COMPONENT_GENERATE_EVENT); 5328 } 5329 } 5330 else 5331 { 5332 eRet = OMX_ErrorBadPortIndex; 5333 } 5334 if((eRet == OMX_ErrorNone) && 5335 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) 5336 { 5337 if(release_done()) 5338 { 5339 // Send the callback now 5340 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING); 5341 post_event(OMX_CommandStateSet, OMX_StateLoaded, 5342 OMX_COMPONENT_GENERATE_EVENT); 5343 } 5344 } 5345 return eRet; 5346 } 5347 5348 5349 /* ====================================================================== 5350 FUNCTION 5351 omx_vdec::EmptyThisBuffer 5352 5353 DESCRIPTION 5354 This routine is used to push the encoded video frames to 5355 the video decoder. 5356 5357 PARAMETERS 5358 None. 5359 5360 RETURN VALUE 5361 OMX Error None if everything went successful. 5362 5363 ========================================================================== */ 5364 OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp, 5365 OMX_IN OMX_BUFFERHEADERTYPE* buffer) 5366 { 5367 OMX_ERRORTYPE ret1 = OMX_ErrorNone; 5368 unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount; 5369 5370 if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) 5371 { 5372 codec_config_flag = true; 5373 DEBUG_PRINT_LOW("%s: codec_config buffer", __FUNCTION__); 5374 } 5375 else 5376 { 5377 codec_config_flag = false; 5378 } 5379 5380 if(m_state == OMX_StateInvalid) 5381 { 5382 DEBUG_PRINT_ERROR("Empty this buffer in Invalid State\n"); 5383 return OMX_ErrorInvalidState; 5384 } 5385 5386 if (buffer == NULL) 5387 { 5388 DEBUG_PRINT_ERROR("\nERROR:ETB Buffer is NULL"); 5389 return OMX_ErrorBadParameter; 5390 } 5391 5392 if (!m_inp_bEnabled) 5393 { 5394 DEBUG_PRINT_ERROR("\nERROR:ETB incorrect state operation, input port is disabled."); 5395 return OMX_ErrorIncorrectStateOperation; 5396 } 5397 5398 if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX) 5399 { 5400 DEBUG_PRINT_ERROR("\nERROR:ETB invalid port in header %d", buffer->nInputPortIndex); 5401 return OMX_ErrorBadPortIndex; 5402 } 5403 5404 #ifdef _ANDROID_ 5405 if(iDivXDrmDecrypt) 5406 { 5407 OMX_ERRORTYPE drmErr = iDivXDrmDecrypt->Decrypt(buffer); 5408 if(drmErr != OMX_ErrorNone) { 5409 // this error can be ignored 5410 DEBUG_PRINT_LOW("\nERROR:iDivXDrmDecrypt->Decrypt %d", drmErr); 5411 } 5412 } 5413 if (perf_flag) 5414 { 5415 if (!latency) 5416 { 5417 dec_time.stop(); 5418 latency = dec_time.processing_time_us(); 5419 dec_time.start(); 5420 } 5421 } 5422 #endif //_ANDROID_ 5423 5424 if (arbitrary_bytes) 5425 { 5426 nBufferIndex = buffer - m_inp_heap_ptr; 5427 } 5428 else 5429 { 5430 if (input_use_buffer == true) 5431 { 5432 nBufferIndex = buffer - m_inp_heap_ptr; 5433 m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen; 5434 m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp; 5435 m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags; 5436 buffer = &m_inp_mem_ptr[nBufferIndex]; 5437 DEBUG_PRINT_LOW("Non-Arbitrary mode - buffer address is: malloc %p, pmem%p in Index %d, buffer %p of size %d", 5438 &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, buffer->nFilledLen); 5439 } 5440 else{ 5441 nBufferIndex = buffer - m_inp_mem_ptr; 5442 } 5443 } 5444 5445 if (nBufferIndex > drv_ctx.ip_buf.actualcount ) 5446 { 5447 DEBUG_PRINT_ERROR("\nERROR:ETB nBufferIndex is invalid"); 5448 return OMX_ErrorBadParameter; 5449 } 5450 5451 DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%lu)", 5452 buffer, buffer->pBuffer, buffer->nTimeStamp, buffer->nFilledLen); 5453 if (arbitrary_bytes) 5454 { 5455 post_event ((unsigned)hComp,(unsigned)buffer, 5456 OMX_COMPONENT_GENERATE_ETB_ARBITRARY); 5457 } 5458 else 5459 { 5460 if (!(client_extradata & OMX_TIMEINFO_EXTRADATA)) 5461 set_frame_rate(buffer->nTimeStamp); 5462 post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB); 5463 } 5464 return OMX_ErrorNone; 5465 } 5466 5467 /* ====================================================================== 5468 FUNCTION 5469 omx_vdec::empty_this_buffer_proxy 5470 5471 DESCRIPTION 5472 This routine is used to push the encoded video frames to 5473 the video decoder. 5474 5475 PARAMETERS 5476 None. 5477 5478 RETURN VALUE 5479 OMX Error None if everything went successful. 5480 5481 ========================================================================== */ 5482 OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp, 5483 OMX_IN OMX_BUFFERHEADERTYPE* buffer) 5484 { 5485 int push_cnt = 0,i=0; 5486 unsigned nPortIndex = 0; 5487 OMX_ERRORTYPE ret = OMX_ErrorNone; 5488 struct vdec_input_frameinfo frameinfo; 5489 struct vdec_bufferpayload *temp_buffer; 5490 struct vdec_ioctl_msg ioctl_msg; 5491 struct vdec_seqheader seq_header; 5492 bool port_setting_changed = true; 5493 #ifdef MAX_RES_1080P 5494 bool not_coded_vop = false; 5495 #endif 5496 5497 /*Should we generate a Aync error event*/ 5498 if (buffer == NULL || buffer->pInputPortPrivate == NULL) 5499 { 5500 DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy is invalid"); 5501 return OMX_ErrorBadParameter; 5502 } 5503 5504 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr); 5505 5506 if (nPortIndex > drv_ctx.ip_buf.actualcount) 5507 { 5508 DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy invalid nPortIndex[%u]", 5509 nPortIndex); 5510 return OMX_ErrorBadParameter; 5511 } 5512 5513 pending_input_buffers++; 5514 5515 /* return zero length and not an EOS buffer */ 5516 if (!arbitrary_bytes && (buffer->nFilledLen == 0) && 5517 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)) 5518 { 5519 DEBUG_PRINT_HIGH("\n return zero legth buffer"); 5520 post_event ((unsigned int)buffer,VDEC_S_SUCCESS, 5521 OMX_COMPONENT_GENERATE_EBD); 5522 return OMX_ErrorNone; 5523 } 5524 5525 #ifdef MAX_RES_1080P 5526 if(codec_type_parse == CODEC_TYPE_MPEG4 || codec_type_parse == CODEC_TYPE_DIVX){ 5527 mp4StreamType psBits; 5528 psBits.data = (unsigned char *)(buffer->pBuffer + buffer->nOffset); 5529 psBits.numBytes = buffer->nFilledLen; 5530 mp4_headerparser.parseHeader(&psBits); 5531 not_coded_vop = mp4_headerparser.is_notcodec_vop( 5532 (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen); 5533 if(not_coded_vop) { 5534 DEBUG_PRINT_HIGH("\n Found Not coded vop len %d frame number %d", 5535 buffer->nFilledLen,frame_count); 5536 if(buffer->nFlags & OMX_BUFFERFLAG_EOS){ 5537 DEBUG_PRINT_HIGH("\n Eos and Not coded Vop set len to zero"); 5538 not_coded_vop = false; 5539 buffer->nFilledLen = 0; 5540 } 5541 } 5542 } 5543 #endif 5544 if(input_flush_progress == true 5545 #ifdef MAX_RES_1080P 5546 || not_coded_vop 5547 #endif 5548 ) 5549 { 5550 DEBUG_PRINT_LOW("\n Flush in progress return buffer "); 5551 post_event ((unsigned int)buffer,VDEC_S_SUCCESS, 5552 OMX_COMPONENT_GENERATE_EBD); 5553 return OMX_ErrorNone; 5554 } 5555 5556 temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate; 5557 5558 if ((temp_buffer - drv_ctx.ptr_inputbuffer) > drv_ctx.ip_buf.actualcount) 5559 { 5560 return OMX_ErrorBadParameter; 5561 } 5562 5563 DEBUG_PRINT_LOW("\n ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer); 5564 /*for use buffer we need to memcpy the data*/ 5565 temp_buffer->buffer_len = buffer->nFilledLen; 5566 5567 if (input_use_buffer) 5568 { 5569 if (buffer->nFilledLen <= temp_buffer->buffer_len) 5570 { 5571 if(arbitrary_bytes) 5572 { 5573 memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen); 5574 } 5575 else 5576 { 5577 memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset), 5578 buffer->nFilledLen); 5579 } 5580 } 5581 else 5582 { 5583 return OMX_ErrorBadParameter; 5584 } 5585 5586 } 5587 5588 frameinfo.bufferaddr = temp_buffer->bufferaddr; 5589 frameinfo.client_data = (void *) buffer; 5590 frameinfo.datalen = temp_buffer->buffer_len; 5591 frameinfo.flags = 0; 5592 frameinfo.offset = buffer->nOffset; 5593 frameinfo.pmem_fd = temp_buffer->pmem_fd; 5594 frameinfo.pmem_offset = temp_buffer->offset; 5595 frameinfo.timestamp = buffer->nTimeStamp; 5596 if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr) 5597 { 5598 DEBUG_PRINT_LOW("ETB: dmx enabled"); 5599 if (m_demux_entries == 0) 5600 { 5601 extract_demux_addr_offsets(buffer); 5602 } 5603 5604 DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%d",m_demux_entries); 5605 handle_demux_data(buffer); 5606 frameinfo.desc_addr = (OMX_U8 *)m_desc_buffer_ptr[nPortIndex].buf_addr; 5607 frameinfo.desc_size = m_desc_buffer_ptr[nPortIndex].desc_data_size; 5608 } 5609 else 5610 { 5611 frameinfo.desc_addr = NULL; 5612 frameinfo.desc_size = 0; 5613 } 5614 if(!arbitrary_bytes) 5615 { 5616 frameinfo.flags |= buffer->nFlags; 5617 } 5618 5619 5620 #ifdef _ANDROID_ 5621 if (m_debug_timestamp) 5622 { 5623 if(arbitrary_bytes) 5624 { 5625 DEBUG_PRINT_LOW("\n Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp); 5626 m_timestamp_list.insert_ts(buffer->nTimeStamp); 5627 } 5628 else if(!arbitrary_bytes && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) 5629 { 5630 DEBUG_PRINT_LOW("\n Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp); 5631 m_timestamp_list.insert_ts(buffer->nTimeStamp); 5632 } 5633 } 5634 #endif 5635 5636 #ifdef INPUT_BUFFER_LOG 5637 if (inputBufferFile1) 5638 { 5639 fwrite((const char *)temp_buffer->bufferaddr, 5640 temp_buffer->buffer_len,1,inputBufferFile1); 5641 } 5642 #endif 5643 5644 if(buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) 5645 { 5646 frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ; 5647 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ; 5648 } 5649 5650 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) 5651 { 5652 DEBUG_PRINT_HIGH("\n Rxd i/p EOS, Notify Driver that EOS has been reached"); 5653 frameinfo.flags |= VDEC_BUFFERFLAG_EOS; 5654 h264_scratch.nFilledLen = 0; 5655 nal_count = 0; 5656 look_ahead_nal = false; 5657 frame_count = 0; 5658 if (m_frame_parser.mutils) 5659 m_frame_parser.mutils->initialize_frame_checking_environment(); 5660 m_frame_parser.flush(); 5661 h264_last_au_ts = LLONG_MAX; 5662 h264_last_au_flags = 0; 5663 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) ); 5664 m_demux_entries = 0; 5665 } 5666 DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%d)", 5667 frameinfo.bufferaddr, frameinfo.timestamp, frameinfo.datalen); 5668 ioctl_msg.in = &frameinfo; 5669 ioctl_msg.out = NULL; 5670 if (ioctl(drv_ctx.video_driver_fd,VDEC_IOCTL_DECODE_FRAME, 5671 &ioctl_msg) < 0) 5672 { 5673 /*Generate an async error and move to invalid state*/ 5674 DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy VDEC_IOCTL_DECODE_FRAME failed"); 5675 if (!arbitrary_bytes) 5676 { 5677 DEBUG_PRINT_LOW("\n Return failed buffer"); 5678 post_event ((unsigned int)buffer,VDEC_S_SUCCESS, 5679 OMX_COMPONENT_GENERATE_EBD); 5680 } 5681 return OMX_ErrorBadParameter; 5682 } else 5683 time_stamp_dts.insert_timestamp(buffer); 5684 5685 return ret; 5686 } 5687 5688 /* ====================================================================== 5689 FUNCTION 5690 omx_vdec::FillThisBuffer 5691 5692 DESCRIPTION 5693 IL client uses this method to release the frame buffer 5694 after displaying them. 5695 5696 PARAMETERS 5697 None. 5698 5699 RETURN VALUE 5700 true/false 5701 5702 ========================================================================== */ 5703 OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp, 5704 OMX_IN OMX_BUFFERHEADERTYPE* buffer) 5705 { 5706 5707 if(m_state == OMX_StateInvalid) 5708 { 5709 DEBUG_PRINT_ERROR("FTB in Invalid State\n"); 5710 return OMX_ErrorInvalidState; 5711 } 5712 5713 if (!m_out_bEnabled) 5714 { 5715 DEBUG_PRINT_ERROR("\nERROR:FTB incorrect state operation, output port is disabled."); 5716 return OMX_ErrorIncorrectStateOperation; 5717 } 5718 5719 if (buffer == NULL || 5720 ((buffer - client_buffers.get_il_buf_hdr()) >= drv_ctx.op_buf.actualcount)) 5721 { 5722 return OMX_ErrorBadParameter; 5723 } 5724 5725 if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) 5726 { 5727 DEBUG_PRINT_ERROR("\nERROR:FTB invalid port in header %d", buffer->nOutputPortIndex); 5728 return OMX_ErrorBadPortIndex; 5729 } 5730 5731 DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer); 5732 post_event((unsigned) hComp, (unsigned)buffer,m_fill_output_msg); 5733 return OMX_ErrorNone; 5734 } 5735 /* ====================================================================== 5736 FUNCTION 5737 omx_vdec::fill_this_buffer_proxy 5738 5739 DESCRIPTION 5740 IL client uses this method to release the frame buffer 5741 after displaying them. 5742 5743 PARAMETERS 5744 None. 5745 5746 RETURN VALUE 5747 true/false 5748 5749 ========================================================================== */ 5750 OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy( 5751 OMX_IN OMX_HANDLETYPE hComp, 5752 OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd) 5753 { 5754 OMX_ERRORTYPE nRet = OMX_ErrorNone; 5755 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; 5756 OMX_BUFFERHEADERTYPE *buffer = bufferAdd; 5757 struct vdec_fillbuffer_cmd fillbuffer; 5758 struct vdec_bufferpayload *ptr_outputbuffer = NULL; 5759 struct vdec_output_frameinfo *ptr_respbuffer = NULL; 5760 5761 5762 if (bufferAdd == NULL || ((buffer - client_buffers.get_il_buf_hdr()) > 5763 drv_ctx.op_buf.actualcount) ) 5764 return OMX_ErrorBadParameter; 5765 5766 DEBUG_PRINT_LOW("\n FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p", 5767 bufferAdd, bufferAdd->pBuffer); 5768 /*Return back the output buffer to client*/ 5769 if(m_out_bEnabled != OMX_TRUE || output_flush_progress == true) 5770 { 5771 DEBUG_PRINT_LOW("\n Output Buffers return flush/disable condition"); 5772 buffer->nFilledLen = 0; 5773 m_cb.FillBufferDone (hComp,m_app_data,buffer); 5774 return OMX_ErrorNone; 5775 } 5776 pending_output_buffers++; 5777 buffer = client_buffers.get_dr_buf_hdr(bufferAdd); 5778 ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate; 5779 if (ptr_respbuffer) 5780 { 5781 ptr_outputbuffer = (struct vdec_bufferpayload*)ptr_respbuffer->client_data; 5782 } 5783 5784 if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL) 5785 { 5786 DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL"); 5787 buffer->nFilledLen = 0; 5788 m_cb.FillBufferDone (hComp,m_app_data,buffer); 5789 pending_output_buffers--; 5790 return OMX_ErrorBadParameter; 5791 } 5792 5793 memcpy (&fillbuffer.buffer,ptr_outputbuffer,\ 5794 sizeof(struct vdec_bufferpayload)); 5795 fillbuffer.client_data = buffer; 5796 5797 ioctl_msg.in = &fillbuffer; 5798 ioctl_msg.out = NULL; 5799 if (ioctl (drv_ctx.video_driver_fd, 5800 VDEC_IOCTL_FILL_OUTPUT_BUFFER,&ioctl_msg) < 0) 5801 { 5802 DEBUG_PRINT_ERROR("\n Decoder frame failed"); 5803 m_cb.FillBufferDone (hComp,m_app_data,buffer); 5804 pending_output_buffers--; 5805 return OMX_ErrorBadParameter; 5806 } 5807 5808 return OMX_ErrorNone; 5809 } 5810 5811 /* ====================================================================== 5812 FUNCTION 5813 omx_vdec::SetCallbacks 5814 5815 DESCRIPTION 5816 Set the callbacks. 5817 5818 PARAMETERS 5819 None. 5820 5821 RETURN VALUE 5822 OMX Error None if everything successful. 5823 5824 ========================================================================== */ 5825 OMX_ERRORTYPE omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE hComp, 5826 OMX_IN OMX_CALLBACKTYPE* callbacks, 5827 OMX_IN OMX_PTR appData) 5828 { 5829 5830 m_cb = *callbacks; 5831 DEBUG_PRINT_LOW("\n Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\ 5832 m_cb.EventHandler,m_cb.FillBufferDone); 5833 m_app_data = appData; 5834 return OMX_ErrorNotImplemented; 5835 } 5836 5837 /* ====================================================================== 5838 FUNCTION 5839 omx_vdec::ComponentDeInit 5840 5841 DESCRIPTION 5842 Destroys the component and release memory allocated to the heap. 5843 5844 PARAMETERS 5845 <TBD>. 5846 5847 RETURN VALUE 5848 OMX Error None if everything successful. 5849 5850 ========================================================================== */ 5851 OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp) 5852 { 5853 #ifdef _ANDROID_ 5854 if(iDivXDrmDecrypt) 5855 { 5856 delete iDivXDrmDecrypt; 5857 iDivXDrmDecrypt=NULL; 5858 } 5859 #endif //_ANDROID_ 5860 int i = 0; 5861 if (OMX_StateLoaded != m_state) 5862 { 5863 DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d\n",\ 5864 m_state); 5865 DEBUG_PRINT_ERROR("\nPlayback Ended - FAILED"); 5866 } 5867 else 5868 { 5869 DEBUG_PRINT_HIGH("\n Playback Ended - PASSED"); 5870 } 5871 5872 if (secure_mode) { 5873 if (unsecureDisplay(qService::IQService::START) < 0) { 5874 DEBUG_PRINT_HIGH("Failed to send message to unsecure display START"); 5875 } 5876 } 5877 5878 /*Check if the output buffers have to be cleaned up*/ 5879 if(m_out_mem_ptr) 5880 { 5881 DEBUG_PRINT_LOW("Freeing the Output Memory\n"); 5882 for (i=0; i < drv_ctx.op_buf.actualcount; i++ ) 5883 { 5884 free_output_buffer (&m_out_mem_ptr[i]); 5885 } 5886 } 5887 5888 /*Check if the input buffers have to be cleaned up*/ 5889 if(m_inp_mem_ptr || m_inp_heap_ptr) 5890 { 5891 DEBUG_PRINT_LOW("Freeing the Input Memory\n"); 5892 for (i=0; i<drv_ctx.ip_buf.actualcount; i++ ) 5893 { 5894 if (m_inp_mem_ptr) 5895 free_input_buffer (i,&m_inp_mem_ptr[i]); 5896 else 5897 free_input_buffer (i,NULL); 5898 } 5899 } 5900 free_input_buffer_header(); 5901 free_output_buffer_header(); 5902 if(h264_scratch.pBuffer) 5903 { 5904 free(h264_scratch.pBuffer); 5905 h264_scratch.pBuffer = NULL; 5906 } 5907 5908 if (h264_parser) 5909 { 5910 delete h264_parser; 5911 h264_parser = NULL; 5912 } 5913 5914 if (m_frame_parser.mutils) 5915 { 5916 DEBUG_PRINT_LOW("\n Free utils parser"); 5917 delete (m_frame_parser.mutils); 5918 m_frame_parser.mutils = NULL; 5919 } 5920 5921 if(m_platform_list) 5922 { 5923 free(m_platform_list); 5924 m_platform_list = NULL; 5925 } 5926 if(m_vendor_config.pData) 5927 { 5928 free(m_vendor_config.pData); 5929 m_vendor_config.pData = NULL; 5930 } 5931 5932 // Reset counters in mesg queues 5933 m_ftb_q.m_size=0; 5934 m_cmd_q.m_size=0; 5935 m_etb_q.m_size=0; 5936 m_ftb_q.m_read = m_ftb_q.m_write =0; 5937 m_cmd_q.m_read = m_cmd_q.m_write =0; 5938 m_etb_q.m_read = m_etb_q.m_write =0; 5939 #ifdef _ANDROID_ 5940 if (m_debug_timestamp) 5941 { 5942 m_timestamp_list.reset_ts_list(); 5943 } 5944 #endif 5945 5946 DEBUG_PRINT_LOW("\n Calling VDEC_IOCTL_STOP_NEXT_MSG"); 5947 (void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG, 5948 NULL); 5949 DEBUG_PRINT_HIGH("\n Close the driver instance"); 5950 #ifdef _ANDROID_ 5951 /* get strong count gets the refernce count of the pmem, the count will 5952 * be incremented by our kernal driver and surface flinger, by the time 5953 * we close the pmem, this cound needs to be zero, but there is no way 5954 * for us to know when surface flinger reduces its cound, so we wait 5955 * here in a infinite loop till the count is zero 5956 */ 5957 if (m_heap_ptr) 5958 { 5959 for (int indx = 0; indx < drv_ctx.op_buf.actualcount; indx++) 5960 m_heap_ptr[indx].video_heap_ptr = NULL; 5961 free(m_heap_ptr); 5962 m_heap_ptr = NULL; 5963 m_heap_count = 0; 5964 } 5965 #endif // _ANDROID_ 5966 close(drv_ctx.video_driver_fd); 5967 #ifdef INPUT_BUFFER_LOG 5968 fclose (inputBufferFile1); 5969 #endif 5970 #ifdef OUTPUT_BUFFER_LOG 5971 fclose (outputBufferFile1); 5972 #endif 5973 #ifdef OUTPUT_EXTRADATA_LOG 5974 fclose (outputExtradataFile); 5975 #endif 5976 5977 if (secure_mode) { 5978 if (unsecureDisplay(qService::IQService::END) < 0) { 5979 DEBUG_PRINT_HIGH("Failed to send message to unsecure display STOP"); 5980 } 5981 } 5982 5983 DEBUG_PRINT_HIGH("\n omx_vdec::component_deinit() complete"); 5984 return OMX_ErrorNone; 5985 } 5986 5987 /* ====================================================================== 5988 FUNCTION 5989 omx_vdec::UseEGLImage 5990 5991 DESCRIPTION 5992 OMX Use EGL Image method implementation <TBD>. 5993 5994 PARAMETERS 5995 <TBD>. 5996 5997 RETURN VALUE 5998 Not Implemented error. 5999 6000 ========================================================================== */ 6001 OMX_ERRORTYPE omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp, 6002 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 6003 OMX_IN OMX_U32 port, 6004 OMX_IN OMX_PTR appData, 6005 OMX_IN void* eglImage) 6006 { 6007 OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list; 6008 OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry; 6009 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info; 6010 6011 #ifdef USE_EGL_IMAGE_GPU 6012 PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc; 6013 EGLint fd = -1, offset = 0,pmemPtr = 0; 6014 #else 6015 int fd = -1, offset = 0; 6016 #endif 6017 DEBUG_PRINT_HIGH("\nuse EGL image support for decoder"); 6018 if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) { 6019 DEBUG_PRINT_ERROR("\n "); 6020 } 6021 #ifdef USE_EGL_IMAGE_GPU 6022 if(m_display_id == NULL) { 6023 DEBUG_PRINT_ERROR("Display ID is not set by IL client \n"); 6024 return OMX_ErrorInsufficientResources; 6025 } 6026 egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC) 6027 eglGetProcAddress("eglQueryImageKHR"); 6028 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE_QCOM,&fd); 6029 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET_QCOM,&offset); 6030 egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR,&pmemPtr); 6031 #else //with OMX test app 6032 struct temp_egl { 6033 int pmem_fd; 6034 int offset; 6035 }; 6036 struct temp_egl *temp_egl_id = NULL; 6037 void * pmemPtr = (void *) eglImage; 6038 temp_egl_id = (struct temp_egl *)eglImage; 6039 if (temp_egl_id != NULL) 6040 { 6041 fd = temp_egl_id->pmem_fd; 6042 offset = temp_egl_id->offset; 6043 } 6044 #endif 6045 if (fd < 0) { 6046 DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d \n",fd); 6047 return OMX_ErrorInsufficientResources; 6048 } 6049 pmem_info.pmem_fd = (OMX_U32) fd; 6050 pmem_info.offset = (OMX_U32) offset; 6051 pmem_entry.entry = (void *) &pmem_info; 6052 pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM; 6053 pmem_list.entryList = &pmem_entry; 6054 pmem_list.nEntries = 1; 6055 ouput_egl_buffers = true; 6056 if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port, 6057 (void *)&pmem_list, drv_ctx.op_buf.buffer_size, 6058 (OMX_U8 *)pmemPtr)) { 6059 DEBUG_PRINT_ERROR("use buffer call failed for egl image\n"); 6060 return OMX_ErrorInsufficientResources; 6061 } 6062 return OMX_ErrorNone; 6063 } 6064 6065 /* ====================================================================== 6066 FUNCTION 6067 omx_vdec::ComponentRoleEnum 6068 6069 DESCRIPTION 6070 OMX Component Role Enum method implementation. 6071 6072 PARAMETERS 6073 <TBD>. 6074 6075 RETURN VALUE 6076 OMX Error None if everything is successful. 6077 ========================================================================== */ 6078 OMX_ERRORTYPE omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp, 6079 OMX_OUT OMX_U8* role, 6080 OMX_IN OMX_U32 index) 6081 { 6082 OMX_ERRORTYPE eRet = OMX_ErrorNone; 6083 6084 if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) 6085 { 6086 if((0 == index) && role) 6087 { 6088 strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE); 6089 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); 6090 } 6091 else 6092 { 6093 eRet = OMX_ErrorNoMore; 6094 } 6095 } 6096 if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) 6097 { 6098 if((0 == index) && role) 6099 { 6100 strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE); 6101 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); 6102 } 6103 else 6104 { 6105 eRet = OMX_ErrorNoMore; 6106 } 6107 } 6108 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) 6109 { 6110 if((0 == index) && role) 6111 { 6112 strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE); 6113 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); 6114 } 6115 else 6116 { 6117 DEBUG_PRINT_LOW("\n No more roles \n"); 6118 eRet = OMX_ErrorNoMore; 6119 } 6120 } 6121 #ifdef MAX_RES_1080P 6122 else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) || 6123 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE)) 6124 ) 6125 #else 6126 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) 6127 #endif 6128 { 6129 if((0 == index) && role) 6130 { 6131 strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); 6132 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); 6133 } 6134 else 6135 { 6136 DEBUG_PRINT_LOW("\n No more roles \n"); 6137 eRet = OMX_ErrorNoMore; 6138 } 6139 } 6140 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) 6141 { 6142 if((0 == index) && role) 6143 { 6144 strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE); 6145 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); 6146 } 6147 else 6148 { 6149 DEBUG_PRINT_LOW("\n No more roles \n"); 6150 eRet = OMX_ErrorNoMore; 6151 } 6152 } 6153 else if( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) || 6154 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE)) 6155 ) 6156 { 6157 if((0 == index) && role) 6158 { 6159 strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE); 6160 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); 6161 } 6162 else 6163 { 6164 DEBUG_PRINT_LOW("\n No more roles \n"); 6165 eRet = OMX_ErrorNoMore; 6166 } 6167 } 6168 else 6169 { 6170 DEBUG_PRINT_ERROR("\nERROR:Querying Role on Unknown Component\n"); 6171 eRet = OMX_ErrorInvalidComponentName; 6172 } 6173 return eRet; 6174 } 6175 6176 6177 6178 6179 /* ====================================================================== 6180 FUNCTION 6181 omx_vdec::AllocateDone 6182 6183 DESCRIPTION 6184 Checks if entire buffer pool is allocated by IL Client or not. 6185 Need this to move to IDLE state. 6186 6187 PARAMETERS 6188 None. 6189 6190 RETURN VALUE 6191 true/false. 6192 6193 ========================================================================== */ 6194 bool omx_vdec::allocate_done(void) 6195 { 6196 bool bRet = false; 6197 bool bRet_In = false; 6198 bool bRet_Out = false; 6199 6200 bRet_In = allocate_input_done(); 6201 bRet_Out = allocate_output_done(); 6202 6203 if(bRet_In && bRet_Out) 6204 { 6205 bRet = true; 6206 } 6207 6208 return bRet; 6209 } 6210 /* ====================================================================== 6211 FUNCTION 6212 omx_vdec::AllocateInputDone 6213 6214 DESCRIPTION 6215 Checks if I/P buffer pool is allocated by IL Client or not. 6216 6217 PARAMETERS 6218 None. 6219 6220 RETURN VALUE 6221 true/false. 6222 6223 ========================================================================== */ 6224 bool omx_vdec::allocate_input_done(void) 6225 { 6226 bool bRet = false; 6227 unsigned i=0; 6228 6229 if (m_inp_mem_ptr == NULL) 6230 { 6231 return bRet; 6232 } 6233 if(m_inp_mem_ptr ) 6234 { 6235 for(;i<drv_ctx.ip_buf.actualcount;i++) 6236 { 6237 if(BITMASK_ABSENT(&m_inp_bm_count,i)) 6238 { 6239 break; 6240 } 6241 } 6242 } 6243 if(i == drv_ctx.ip_buf.actualcount) 6244 { 6245 bRet = true; 6246 DEBUG_PRINT_HIGH("Allocate done for all i/p buffers"); 6247 } 6248 if(i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled) 6249 { 6250 m_inp_bPopulated = OMX_TRUE; 6251 } 6252 return bRet; 6253 } 6254 /* ====================================================================== 6255 FUNCTION 6256 omx_vdec::AllocateOutputDone 6257 6258 DESCRIPTION 6259 Checks if entire O/P buffer pool is allocated by IL Client or not. 6260 6261 PARAMETERS 6262 None. 6263 6264 RETURN VALUE 6265 true/false. 6266 6267 ========================================================================== */ 6268 bool omx_vdec::allocate_output_done(void) 6269 { 6270 bool bRet = false; 6271 unsigned j=0; 6272 6273 if (m_out_mem_ptr == NULL) 6274 { 6275 return bRet; 6276 } 6277 6278 if (m_out_mem_ptr) 6279 { 6280 for(;j < drv_ctx.op_buf.actualcount;j++) 6281 { 6282 if(BITMASK_ABSENT(&m_out_bm_count,j)) 6283 { 6284 break; 6285 } 6286 } 6287 } 6288 6289 if(j == drv_ctx.op_buf.actualcount) 6290 { 6291 bRet = true; 6292 DEBUG_PRINT_HIGH("Allocate done for all o/p buffers"); 6293 if(m_out_bEnabled) 6294 m_out_bPopulated = OMX_TRUE; 6295 } 6296 6297 return bRet; 6298 } 6299 6300 /* ====================================================================== 6301 FUNCTION 6302 omx_vdec::ReleaseDone 6303 6304 DESCRIPTION 6305 Checks if IL client has released all the buffers. 6306 6307 PARAMETERS 6308 None. 6309 6310 RETURN VALUE 6311 true/false 6312 6313 ========================================================================== */ 6314 bool omx_vdec::release_done(void) 6315 { 6316 bool bRet = false; 6317 6318 if(release_input_done()) 6319 { 6320 if(release_output_done()) 6321 { 6322 bRet = true; 6323 } 6324 } 6325 return bRet; 6326 } 6327 6328 6329 /* ====================================================================== 6330 FUNCTION 6331 omx_vdec::ReleaseOutputDone 6332 6333 DESCRIPTION 6334 Checks if IL client has released all the buffers. 6335 6336 PARAMETERS 6337 None. 6338 6339 RETURN VALUE 6340 true/false 6341 6342 ========================================================================== */ 6343 bool omx_vdec::release_output_done(void) 6344 { 6345 bool bRet = false; 6346 unsigned i=0,j=0; 6347 6348 DEBUG_PRINT_LOW("\n Value of m_out_mem_ptr %p",m_inp_mem_ptr); 6349 if(m_out_mem_ptr) 6350 { 6351 for(;j < drv_ctx.op_buf.actualcount ; j++) 6352 { 6353 if(BITMASK_PRESENT(&m_out_bm_count,j)) 6354 { 6355 break; 6356 } 6357 } 6358 if(j == drv_ctx.op_buf.actualcount) 6359 { 6360 m_out_bm_count = 0; 6361 bRet = true; 6362 } 6363 } 6364 else 6365 { 6366 m_out_bm_count = 0; 6367 bRet = true; 6368 } 6369 return bRet; 6370 } 6371 /* ====================================================================== 6372 FUNCTION 6373 omx_vdec::ReleaseInputDone 6374 6375 DESCRIPTION 6376 Checks if IL client has released all the buffers. 6377 6378 PARAMETERS 6379 None. 6380 6381 RETURN VALUE 6382 true/false 6383 6384 ========================================================================== */ 6385 bool omx_vdec::release_input_done(void) 6386 { 6387 bool bRet = false; 6388 unsigned i=0,j=0; 6389 6390 DEBUG_PRINT_LOW("\n Value of m_inp_mem_ptr %p",m_inp_mem_ptr); 6391 if(m_inp_mem_ptr) 6392 { 6393 for(;j<drv_ctx.ip_buf.actualcount;j++) 6394 { 6395 if( BITMASK_PRESENT(&m_inp_bm_count,j)) 6396 { 6397 break; 6398 } 6399 } 6400 if(j==drv_ctx.ip_buf.actualcount) 6401 { 6402 bRet = true; 6403 } 6404 } 6405 else 6406 { 6407 bRet = true; 6408 } 6409 return bRet; 6410 } 6411 6412 OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp, 6413 OMX_BUFFERHEADERTYPE * buffer) 6414 { 6415 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL; 6416 if (!buffer || (buffer - m_out_mem_ptr) >= drv_ctx.op_buf.actualcount) 6417 { 6418 DEBUG_PRINT_ERROR("\n [FBD] ERROR in ptr(%p)", buffer); 6419 return OMX_ErrorBadParameter; 6420 } 6421 else if (output_flush_progress) 6422 { 6423 DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer); 6424 buffer->nFilledLen = 0; 6425 buffer->nTimeStamp = 0; 6426 buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA; 6427 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ; 6428 buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT; 6429 } 6430 6431 #ifdef _ANDROID_ 6432 char value[PROPERTY_VALUE_MAX]; 6433 property_get("vidc.dec.debug.panframedata", value, NULL); 6434 6435 if (atoi(value)) 6436 { 6437 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) 6438 { 6439 DEBUG_PRINT_HIGH("\n"); 6440 DEBUG_PRINT_HIGH("***************************************************\n"); 6441 DEBUG_PRINT_HIGH("FillBufferDone: End Of Sequence Received\n"); 6442 DEBUG_PRINT_HIGH("***************************************************\n"); 6443 } 6444 6445 if (buffer->nFlags & OMX_BUFFERFLAG_DATACORRUPT) 6446 { 6447 DEBUG_PRINT_HIGH("\n"); 6448 DEBUG_PRINT_HIGH("***************************************************\n"); 6449 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received\n"); 6450 DEBUG_PRINT_HIGH("***************************************************\n"); 6451 } 6452 } 6453 #endif 6454 6455 DEBUG_PRINT_LOW("\n fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p", 6456 buffer, buffer->pBuffer); 6457 pending_output_buffers --; 6458 6459 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) 6460 { 6461 DEBUG_PRINT_HIGH("\n Output EOS has been reached"); 6462 if (!output_flush_progress) 6463 post_event(NULL,NULL,OMX_COMPONENT_GENERATE_EOS_DONE); 6464 6465 if (psource_frame) 6466 { 6467 m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame); 6468 psource_frame = NULL; 6469 } 6470 if (pdest_frame) 6471 { 6472 pdest_frame->nFilledLen = 0; 6473 m_input_free_q.insert_entry((unsigned) pdest_frame,NULL,NULL); 6474 pdest_frame = NULL; 6475 } 6476 } 6477 6478 DEBUG_PRINT_LOW("\n In fill Buffer done call address %p ",buffer); 6479 #ifdef OUTPUT_BUFFER_LOG 6480 if (outputBufferFile1) 6481 { 6482 OMX_U32 index = buffer - m_out_mem_ptr; 6483 OMX_U8* pBuffer = (OMX_U8 *)drv_ctx.ptr_outputbuffer[index].bufferaddr; 6484 6485 fwrite (pBuffer,1,buffer->nFilledLen, 6486 outputBufferFile1); 6487 } 6488 #endif 6489 6490 /* For use buffer we need to copy the data */ 6491 if (!output_flush_progress) 6492 { 6493 time_stamp_dts.get_next_timestamp(buffer, 6494 (drv_ctx.interlace != VDEC_InterlaceFrameProgressive) 6495 ?true:false); 6496 } 6497 if (m_cb.FillBufferDone) 6498 { 6499 if (buffer->nFilledLen > 0) 6500 { 6501 if (client_extradata) 6502 handle_extradata(buffer); 6503 if (client_extradata & OMX_TIMEINFO_EXTRADATA) 6504 // Keep min timestamp interval to handle corrupted bit stream scenario 6505 set_frame_rate(buffer->nTimeStamp); 6506 else if (arbitrary_bytes) 6507 adjust_timestamp(buffer->nTimeStamp); 6508 #ifdef _ANDROID_ 6509 if (perf_flag) 6510 { 6511 if (!proc_frms) 6512 { 6513 dec_time.stop(); 6514 latency = dec_time.processing_time_us() - latency; 6515 DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3); 6516 dec_time.start(); 6517 fps_metrics.start(); 6518 } 6519 proc_frms++; 6520 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) 6521 { 6522 OMX_U64 proc_time = 0; 6523 fps_metrics.stop(); 6524 proc_time = fps_metrics.processing_time_us(); 6525 DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%lu) proc_time(%.2f)S fps(%.2f)", 6526 proc_frms, (float)proc_time / 1e6, 6527 (float)(1e6 * proc_frms) / proc_time); 6528 proc_frms = 0; 6529 } 6530 } 6531 #endif //_ANDROID_ 6532 6533 #ifdef OUTPUT_EXTRADATA_LOG 6534 if (outputExtradataFile) 6535 { 6536 6537 OMX_U32 index = buffer - m_out_mem_ptr; 6538 OMX_U8* pBuffer = (OMX_U8 *)drv_ctx.ptr_outputbuffer[index].bufferaddr; 6539 6540 OMX_OTHER_EXTRADATATYPE *p_extra = NULL; 6541 p_extra = (OMX_OTHER_EXTRADATATYPE *) 6542 ((unsigned)(pBuffer + buffer->nOffset + 6543 buffer->nFilledLen + 3)&(~3)); 6544 while(p_extra && 6545 (OMX_U8*)p_extra < (pBuffer + buffer->nAllocLen) ) 6546 { 6547 DEBUG_PRINT_LOW("\nWRITING extradata, size=%d,type=%d",p_extra->nSize, p_extra->eType); 6548 fwrite (p_extra,1,p_extra->nSize,outputExtradataFile); 6549 if (p_extra->eType == OMX_ExtraDataNone) 6550 { 6551 break; 6552 } 6553 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); 6554 } 6555 } 6556 #endif 6557 } 6558 if (buffer->nFlags & OMX_BUFFERFLAG_EOS){ 6559 prev_ts = LLONG_MAX; 6560 rst_prev_ts = true; 6561 } 6562 6563 pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) 6564 ((OMX_QCOM_PLATFORM_PRIVATE_LIST *) 6565 buffer->pPlatformPrivate)->entryList->entry; 6566 DEBUG_PRINT_LOW("\n Before FBD callback Accessed Pmeminfo %d",pPMEMInfo->pmem_fd); 6567 OMX_BUFFERHEADERTYPE *il_buffer; 6568 il_buffer = client_buffers.get_il_buf_hdr(buffer); 6569 if (il_buffer) 6570 m_cb.FillBufferDone (hComp,m_app_data,il_buffer); 6571 else { 6572 DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr"); 6573 return OMX_ErrorBadParameter; 6574 } 6575 6576 DEBUG_PRINT_LOW("\n After Fill Buffer Done callback %d",pPMEMInfo->pmem_fd); 6577 } 6578 else 6579 { 6580 return OMX_ErrorBadParameter; 6581 } 6582 6583 // ss change 6584 if (m_use_smoothstreaming) { 6585 OMX_U32 buf_index = buffer - m_out_mem_ptr; 6586 private_handle_t * handle = NULL; 6587 BufferDim_t dim; 6588 dim.sliceWidth = m_port_def.format.video.nStride; 6589 dim.sliceHeight = m_port_def.format.video.nSliceHeight; 6590 handle = (private_handle_t *)native_buffer[buf_index]; 6591 DEBUG_PRINT_LOW("set metadata: update buffer geo with stride %d slice %d", dim.sliceWidth, dim.sliceHeight); 6592 setMetaData(handle, UPDATE_BUFFER_GEOMETRY, (void*)&dim); 6593 } 6594 6595 return OMX_ErrorNone; 6596 } 6597 6598 OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE hComp, 6599 OMX_BUFFERHEADERTYPE* buffer) 6600 { 6601 6602 if (buffer == NULL || ((buffer - m_inp_mem_ptr) > drv_ctx.ip_buf.actualcount)) 6603 { 6604 DEBUG_PRINT_ERROR("\n empty_buffer_done: ERROR bufhdr = %p", buffer); 6605 return OMX_ErrorBadParameter; 6606 } 6607 6608 DEBUG_PRINT_LOW("\n empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p", 6609 buffer, buffer->pBuffer); 6610 pending_input_buffers--; 6611 6612 if (arbitrary_bytes) 6613 { 6614 if (pdest_frame == NULL && input_flush_progress == false) 6615 { 6616 DEBUG_PRINT_LOW("\n Push input from buffer done address of Buffer %p",buffer); 6617 pdest_frame = buffer; 6618 buffer->nFilledLen = 0; 6619 buffer->nTimeStamp = LLONG_MAX; 6620 push_input_buffer (hComp); 6621 } 6622 else 6623 { 6624 DEBUG_PRINT_LOW("\n Push buffer into freeq address of Buffer %p",buffer); 6625 buffer->nFilledLen = 0; 6626 if (!m_input_free_q.insert_entry((unsigned)buffer,NULL,NULL)) 6627 { 6628 DEBUG_PRINT_ERROR("\nERROR:i/p free Queue is FULL Error"); 6629 } 6630 } 6631 } 6632 else if(m_cb.EmptyBufferDone) 6633 { 6634 buffer->nFilledLen = 0; 6635 if (input_use_buffer == true){ 6636 buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr]; 6637 } 6638 m_cb.EmptyBufferDone(hComp ,m_app_data, buffer); 6639 } 6640 return OMX_ErrorNone; 6641 } 6642 6643 6644 int omx_vdec::async_message_process (void *context, void* message) 6645 { 6646 omx_vdec* omx = NULL; 6647 struct vdec_msginfo *vdec_msg = NULL; 6648 OMX_BUFFERHEADERTYPE* omxhdr = NULL; 6649 struct vdec_output_frameinfo *output_respbuf = NULL; 6650 6651 if (context == NULL || message == NULL) 6652 { 6653 DEBUG_PRINT_ERROR("\n FATAL ERROR in omx_vdec::async_message_process NULL Check"); 6654 return -1; 6655 } 6656 vdec_msg = (struct vdec_msginfo *)message; 6657 6658 omx = reinterpret_cast<omx_vdec*>(context); 6659 6660 #ifdef _ANDROID_ 6661 if (omx->m_debug_timestamp) 6662 { 6663 if ( (vdec_msg->msgcode == VDEC_MSG_RESP_OUTPUT_BUFFER_DONE) && 6664 !(omx->output_flush_progress) ) 6665 { 6666 OMX_TICKS expected_ts = 0; 6667 omx->m_timestamp_list.pop_min_ts(expected_ts); 6668 DEBUG_PRINT_LOW("\n Current timestamp (%lld),Popped TIMESTAMP (%lld) from list", 6669 vdec_msg->msgdata.output_frame.time_stamp, expected_ts); 6670 6671 if (vdec_msg->msgdata.output_frame.time_stamp != expected_ts) 6672 { 6673 DEBUG_PRINT_ERROR("\n ERROR in omx_vdec::async_message_process timestamp Check"); 6674 } 6675 } 6676 } 6677 #endif 6678 6679 switch (vdec_msg->msgcode) 6680 { 6681 6682 case VDEC_MSG_EVT_HW_ERROR: 6683 omx->post_event (NULL,vdec_msg->status_code,\ 6684 OMX_COMPONENT_GENERATE_HARDWARE_ERROR); 6685 break; 6686 6687 case VDEC_MSG_RESP_START_DONE: 6688 omx->post_event (NULL,vdec_msg->status_code,\ 6689 OMX_COMPONENT_GENERATE_START_DONE); 6690 break; 6691 6692 case VDEC_MSG_RESP_STOP_DONE: 6693 omx->post_event (NULL,vdec_msg->status_code,\ 6694 OMX_COMPONENT_GENERATE_STOP_DONE); 6695 break; 6696 6697 case VDEC_MSG_RESP_RESUME_DONE: 6698 omx->post_event (NULL,vdec_msg->status_code,\ 6699 OMX_COMPONENT_GENERATE_RESUME_DONE); 6700 break; 6701 6702 case VDEC_MSG_RESP_PAUSE_DONE: 6703 omx->post_event (NULL,vdec_msg->status_code,\ 6704 OMX_COMPONENT_GENERATE_PAUSE_DONE); 6705 break; 6706 6707 case VDEC_MSG_RESP_FLUSH_INPUT_DONE: 6708 omx->post_event (NULL,vdec_msg->status_code,\ 6709 OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH); 6710 break; 6711 case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE: 6712 omx->post_event (NULL,vdec_msg->status_code,\ 6713 OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH); 6714 break; 6715 case VDEC_MSG_RESP_INPUT_FLUSHED: 6716 case VDEC_MSG_RESP_INPUT_BUFFER_DONE: 6717 6718 omxhdr = (OMX_BUFFERHEADERTYPE* )\ 6719 vdec_msg->msgdata.input_frame_clientdata; 6720 6721 6722 if (omxhdr == NULL || 6723 ((omxhdr - omx->m_inp_mem_ptr) > omx->drv_ctx.ip_buf.actualcount) ) 6724 { 6725 omxhdr = NULL; 6726 vdec_msg->status_code = VDEC_S_EFATAL; 6727 } 6728 6729 omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code, 6730 OMX_COMPONENT_GENERATE_EBD); 6731 break; 6732 case VDEC_MSG_EVT_INFO_FIELD_DROPPED: 6733 int64_t *timestamp; 6734 timestamp = (int64_t *) malloc(sizeof(int64_t)); 6735 if (timestamp) { 6736 *timestamp = vdec_msg->msgdata.output_frame.time_stamp; 6737 omx->post_event ((unsigned int)timestamp, vdec_msg->status_code, 6738 OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED); 6739 DEBUG_PRINT_HIGH("\nField dropped time stamp is %lld", 6740 vdec_msg->msgdata.output_frame.time_stamp); 6741 } 6742 break; 6743 case VDEC_MSG_RESP_OUTPUT_FLUSHED: 6744 case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE: 6745 omxhdr = (OMX_BUFFERHEADERTYPE*)vdec_msg->msgdata.output_frame.client_data; 6746 DEBUG_PRINT_LOW("[RespBufDone] Buf(%p) Ts(%lld) Pic_type(%u)", 6747 omxhdr, vdec_msg->msgdata.output_frame.time_stamp, 6748 vdec_msg->msgdata.output_frame.pic_type); 6749 6750 /* update SYNCFRAME flag */ 6751 if (omx->eCompressionFormat == OMX_VIDEO_CodingAVC) 6752 { 6753 /* set SYNCFRAME flag if picture type is IDR for h264 */ 6754 if (vdec_msg->msgdata.output_frame.pic_type == PICTURE_TYPE_IDR) 6755 vdec_msg->msgdata.output_frame.flags |= OMX_BUFFERFLAG_SYNCFRAME; 6756 else 6757 vdec_msg->msgdata.output_frame.flags &= ~OMX_BUFFERFLAG_SYNCFRAME; 6758 } 6759 else 6760 { 6761 /* set SYNCFRAME flag if picture type is I_TYPE */ 6762 if (vdec_msg->msgdata.output_frame.pic_type == PICTURE_TYPE_I) 6763 vdec_msg->msgdata.output_frame.flags |= OMX_BUFFERFLAG_SYNCFRAME; 6764 else 6765 vdec_msg->msgdata.output_frame.flags &= ~OMX_BUFFERFLAG_SYNCFRAME; 6766 } 6767 6768 if (omxhdr && omxhdr->pOutputPortPrivate && 6769 ((omxhdr - omx->m_out_mem_ptr) < omx->drv_ctx.op_buf.actualcount) && 6770 (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate 6771 - omx->drv_ctx.ptr_respbuffer) < omx->drv_ctx.op_buf.actualcount)) 6772 { 6773 if (vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen) 6774 { 6775 omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len; 6776 omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset; 6777 omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp; 6778 omxhdr->nFlags = (vdec_msg->msgdata.output_frame.flags); 6779 6780 output_respbuf = (struct vdec_output_frameinfo *)\ 6781 omxhdr->pOutputPortPrivate; 6782 if (omxhdr->nFilledLen && ((omx->rectangle.nLeft != vdec_msg->msgdata.output_frame.framesize.left) 6783 || (omx->rectangle.nTop != vdec_msg->msgdata.output_frame.framesize.top) 6784 || (omx->rectangle.nWidth != vdec_msg->msgdata.output_frame.framesize.right) 6785 || (omx->rectangle.nHeight != vdec_msg->msgdata.output_frame.framesize.bottom))) 6786 { 6787 DEBUG_PRINT_LOW("Old crop info: left = %u top = %u width = %u height = %u\n", 6788 omx->rectangle.nLeft, omx->rectangle.nTop, 6789 omx->rectangle.nWidth, omx->rectangle.nHeight); 6790 omx->rectangle.nLeft = vdec_msg->msgdata.output_frame.framesize.left; 6791 omx->rectangle.nTop = vdec_msg->msgdata.output_frame.framesize.top; 6792 omx->rectangle.nWidth = vdec_msg->msgdata.output_frame.framesize.right; 6793 omx->rectangle.nHeight = vdec_msg->msgdata.output_frame.framesize.bottom; 6794 DEBUG_PRINT_HIGH(" Crop information has changed"); 6795 DEBUG_PRINT_LOW("New crop info: left = %u top = %u width = %u height = %u\n", 6796 omx->rectangle.nLeft, omx->rectangle.nTop, 6797 omx->rectangle.nWidth, omx->rectangle.nHeight); 6798 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexConfigCommonOutputCrop, 6799 OMX_COMPONENT_GENERATE_PORT_RECONFIG); 6800 } 6801 6802 output_respbuf->framesize.bottom = 6803 vdec_msg->msgdata.output_frame.framesize.bottom; 6804 output_respbuf->framesize.left = 6805 vdec_msg->msgdata.output_frame.framesize.left; 6806 output_respbuf->framesize.right = 6807 vdec_msg->msgdata.output_frame.framesize.right; 6808 output_respbuf->framesize.top = 6809 vdec_msg->msgdata.output_frame.framesize.top; 6810 output_respbuf->len = vdec_msg->msgdata.output_frame.len; 6811 output_respbuf->offset = vdec_msg->msgdata.output_frame.offset; 6812 output_respbuf->time_stamp = vdec_msg->msgdata.output_frame.time_stamp; 6813 output_respbuf->flags = vdec_msg->msgdata.output_frame.flags; 6814 output_respbuf->pic_type = vdec_msg->msgdata.output_frame.pic_type; 6815 output_respbuf->interlaced_format = vdec_msg->msgdata.output_frame.interlaced_format; 6816 output_respbuf->aspect_ratio_info = 6817 vdec_msg->msgdata.output_frame.aspect_ratio_info; 6818 6819 6820 if (omx->output_use_buffer) 6821 memcpy ( omxhdr->pBuffer, 6822 (vdec_msg->msgdata.output_frame.bufferaddr + 6823 vdec_msg->msgdata.output_frame.offset), 6824 vdec_msg->msgdata.output_frame.len ); 6825 } 6826 else 6827 omxhdr->nFilledLen = 0; 6828 omx->post_event ((unsigned int)omxhdr, vdec_msg->status_code, 6829 OMX_COMPONENT_GENERATE_FBD); 6830 } 6831 else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS) 6832 omx->post_event (NULL, vdec_msg->status_code, 6833 OMX_COMPONENT_GENERATE_EOS_DONE); 6834 else 6835 omx->post_event (NULL, vdec_msg->status_code, 6836 OMX_COMPONENT_GENERATE_HARDWARE_ERROR); 6837 break; 6838 case VDEC_MSG_EVT_CONFIG_CHANGED: 6839 DEBUG_PRINT_HIGH("\n Port settings changed"); 6840 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition, 6841 OMX_COMPONENT_GENERATE_PORT_RECONFIG); 6842 break; 6843 case VDEC_MSG_EVT_INFO_CONFIG_CHANGED: 6844 { 6845 DEBUG_PRINT_HIGH("\n Port settings changed info"); 6846 // get_buffer_req and populate port defn structure 6847 OMX_ERRORTYPE eRet = OMX_ErrorNone; 6848 omx->m_port_def.nPortIndex = 1; 6849 eRet = omx->update_portdef(&(omx->m_port_def)); 6850 break; 6851 } 6852 default: 6853 break; 6854 } 6855 return 1; 6856 } 6857 6858 OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary ( 6859 OMX_HANDLETYPE hComp, 6860 OMX_BUFFERHEADERTYPE *buffer 6861 ) 6862 { 6863 unsigned address,p2,id; 6864 DEBUG_PRINT_LOW("\n Empty this arbitrary"); 6865 6866 if (buffer == NULL) 6867 { 6868 return OMX_ErrorBadParameter; 6869 } 6870 DEBUG_PRINT_LOW("\n ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer); 6871 DEBUG_PRINT_LOW("\n ETBProxyArb: nFilledLen %u, flags %d, timestamp %u", 6872 buffer->nFilledLen, buffer->nFlags, (unsigned)buffer->nTimeStamp); 6873 6874 /* return zero length and not an EOS buffer */ 6875 /* return buffer if input flush in progress */ 6876 if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) && 6877 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))) 6878 { 6879 DEBUG_PRINT_HIGH("\n return zero legth buffer or flush in progress"); 6880 m_cb.EmptyBufferDone (hComp,m_app_data,buffer); 6881 return OMX_ErrorNone; 6882 } 6883 6884 if (psource_frame == NULL) 6885 { 6886 DEBUG_PRINT_LOW("\n Set Buffer as source Buffer %p time stamp %d",buffer,buffer->nTimeStamp); 6887 psource_frame = buffer; 6888 DEBUG_PRINT_LOW("\n Try to Push One Input Buffer "); 6889 push_input_buffer (hComp); 6890 } 6891 else 6892 { 6893 DEBUG_PRINT_LOW("\n Push the source buffer into pendingq %p",buffer); 6894 if (!m_input_pending_q.insert_entry((unsigned)buffer,NULL,NULL)) 6895 { 6896 return OMX_ErrorBadParameter; 6897 } 6898 } 6899 6900 6901 return OMX_ErrorNone; 6902 } 6903 6904 OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp) 6905 { 6906 unsigned address,p2,id; 6907 OMX_ERRORTYPE ret = OMX_ErrorNone; 6908 6909 if (pdest_frame == NULL || psource_frame == NULL) 6910 { 6911 /*Check if we have a destination buffer*/ 6912 if (pdest_frame == NULL) 6913 { 6914 DEBUG_PRINT_LOW("\n Get a Destination buffer from the queue"); 6915 if (m_input_free_q.m_size) 6916 { 6917 m_input_free_q.pop_entry(&address,&p2,&id); 6918 pdest_frame = (OMX_BUFFERHEADERTYPE *)address; 6919 pdest_frame->nFilledLen = 0; 6920 pdest_frame->nTimeStamp = LLONG_MAX; 6921 DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",pdest_frame); 6922 } 6923 } 6924 6925 /*Check if we have a destination buffer*/ 6926 if (psource_frame == NULL) 6927 { 6928 DEBUG_PRINT_LOW("\n Get a source buffer from the queue"); 6929 if (m_input_pending_q.m_size) 6930 { 6931 m_input_pending_q.pop_entry(&address,&p2,&id); 6932 psource_frame = (OMX_BUFFERHEADERTYPE *)address; 6933 DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %d",psource_frame, 6934 psource_frame->nTimeStamp); 6935 DEBUG_PRINT_LOW("\n Next source Buffer flag %d length %d", 6936 psource_frame->nFlags,psource_frame->nFilledLen); 6937 6938 } 6939 } 6940 6941 } 6942 6943 while ((pdest_frame != NULL) && (psource_frame != NULL)) 6944 { 6945 switch (codec_type_parse) 6946 { 6947 case CODEC_TYPE_MPEG4: 6948 case CODEC_TYPE_H263: 6949 case CODEC_TYPE_MPEG2: 6950 ret = push_input_sc_codec(hComp); 6951 break; 6952 case CODEC_TYPE_H264: 6953 ret = push_input_h264(hComp); 6954 break; 6955 case CODEC_TYPE_VC1: 6956 ret = push_input_vc1(hComp); 6957 break; 6958 } 6959 if (ret != OMX_ErrorNone) 6960 { 6961 DEBUG_PRINT_ERROR("\n Pushing input Buffer Failed"); 6962 omx_report_error (); 6963 break; 6964 } 6965 } 6966 6967 return ret; 6968 } 6969 6970 OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp) 6971 { 6972 OMX_U32 partial_frame = 1; 6973 OMX_BOOL generate_ebd = OMX_TRUE; 6974 unsigned address,p2,id; 6975 6976 DEBUG_PRINT_LOW("\n Start Parsing the bit stream address %p TimeStamp %d", 6977 psource_frame,psource_frame->nTimeStamp); 6978 if (m_frame_parser.parse_sc_frame(psource_frame, 6979 pdest_frame,&partial_frame) == -1) 6980 { 6981 DEBUG_PRINT_ERROR("\n Error In Parsing Return Error"); 6982 return OMX_ErrorBadParameter; 6983 } 6984 6985 if (partial_frame == 0) 6986 { 6987 DEBUG_PRINT_LOW("\n Frame size %d source %p frame count %d", 6988 pdest_frame->nFilledLen,psource_frame,frame_count); 6989 6990 6991 DEBUG_PRINT_LOW("\n TimeStamp updated %d",pdest_frame->nTimeStamp); 6992 /*First Parsed buffer will have only header Hence skip*/ 6993 if (frame_count == 0) 6994 { 6995 DEBUG_PRINT_LOW("\n H263/MPEG4 Codec First Frame "); 6996 #ifdef MAX_RES_1080P 6997 if(codec_type_parse == CODEC_TYPE_MPEG4 || 6998 codec_type_parse == CODEC_TYPE_DIVX) { 6999 mp4StreamType psBits; 7000 psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset; 7001 psBits.numBytes = pdest_frame->nFilledLen; 7002 mp4_headerparser.parseHeader(&psBits); 7003 } 7004 #endif 7005 frame_count++; 7006 } 7007 else 7008 { 7009 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS; 7010 if(pdest_frame->nFilledLen) 7011 { 7012 /*Push the frame to the Decoder*/ 7013 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) 7014 { 7015 return OMX_ErrorBadParameter; 7016 } 7017 frame_count++; 7018 pdest_frame = NULL; 7019 7020 if (m_input_free_q.m_size) 7021 { 7022 m_input_free_q.pop_entry(&address,&p2,&id); 7023 pdest_frame = (OMX_BUFFERHEADERTYPE *) address; 7024 pdest_frame->nFilledLen = 0; 7025 } 7026 } 7027 else if(!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS)) 7028 { 7029 DEBUG_PRINT_ERROR("\nZero len buffer return back to POOL"); 7030 m_input_free_q.insert_entry((unsigned) pdest_frame,NULL,NULL); 7031 pdest_frame = NULL; 7032 } 7033 } 7034 } 7035 else 7036 { 7037 DEBUG_PRINT_LOW("\n Not a Complete Frame %d",pdest_frame->nFilledLen); 7038 /*Check if Destination Buffer is full*/ 7039 if (pdest_frame->nAllocLen == 7040 pdest_frame->nFilledLen + pdest_frame->nOffset) 7041 { 7042 DEBUG_PRINT_ERROR("\nERROR:Frame Not found though Destination Filled"); 7043 return OMX_ErrorStreamCorrupt; 7044 } 7045 } 7046 7047 if (psource_frame->nFilledLen == 0) 7048 { 7049 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) 7050 { 7051 if (pdest_frame) 7052 { 7053 pdest_frame->nFlags |= psource_frame->nFlags; 7054 DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%d TimeStamp = %x", 7055 pdest_frame->nFilledLen,pdest_frame->nTimeStamp); 7056 DEBUG_PRINT_LOW("\n Found a frame size = %d number = %d", 7057 pdest_frame->nFilledLen,frame_count++); 7058 /*Push the frame to the Decoder*/ 7059 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) 7060 { 7061 return OMX_ErrorBadParameter; 7062 } 7063 frame_count++; 7064 pdest_frame = NULL; 7065 } 7066 else 7067 { 7068 DEBUG_PRINT_LOW("\n Last frame in else dest addr") ; 7069 generate_ebd = OMX_FALSE; 7070 } 7071 } 7072 if(generate_ebd) 7073 { 7074 DEBUG_PRINT_LOW("\n Buffer Consumed return back to client %p",psource_frame); 7075 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame); 7076 psource_frame = NULL; 7077 7078 if (m_input_pending_q.m_size) 7079 { 7080 DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame); 7081 m_input_pending_q.pop_entry(&address,&p2,&id); 7082 psource_frame = (OMX_BUFFERHEADERTYPE *) address; 7083 DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %d",psource_frame, 7084 psource_frame->nTimeStamp); 7085 DEBUG_PRINT_LOW("\n Next source Buffer flag %d length %d", 7086 psource_frame->nFlags,psource_frame->nFilledLen); 7087 } 7088 } 7089 } 7090 return OMX_ErrorNone; 7091 } 7092 7093 OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp) 7094 { 7095 OMX_U32 partial_frame = 1; 7096 unsigned address,p2,id; 7097 OMX_BOOL isNewFrame = OMX_FALSE; 7098 OMX_BOOL generate_ebd = OMX_TRUE; 7099 7100 if (h264_scratch.pBuffer == NULL) 7101 { 7102 DEBUG_PRINT_ERROR("\nERROR:H.264 Scratch Buffer not allocated"); 7103 return OMX_ErrorBadParameter; 7104 } 7105 DEBUG_PRINT_LOW("\n Pending h264_scratch.nFilledLen %d " 7106 "look_ahead_nal %d", h264_scratch.nFilledLen, look_ahead_nal); 7107 DEBUG_PRINT_LOW("\n Pending pdest_frame->nFilledLen %d",pdest_frame->nFilledLen); 7108 if (h264_scratch.nFilledLen && look_ahead_nal) 7109 { 7110 look_ahead_nal = false; 7111 if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >= 7112 h264_scratch.nFilledLen) 7113 { 7114 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen), 7115 h264_scratch.pBuffer,h264_scratch.nFilledLen); 7116 pdest_frame->nFilledLen += h264_scratch.nFilledLen; 7117 DEBUG_PRINT_LOW("\n Copy the previous NAL (h264 scratch) into Dest frame"); 7118 h264_scratch.nFilledLen = 0; 7119 } 7120 else 7121 { 7122 DEBUG_PRINT_ERROR("\n Error:1: Destination buffer overflow for H264"); 7123 return OMX_ErrorBadParameter; 7124 } 7125 } 7126 if (nal_length == 0) 7127 { 7128 DEBUG_PRINT_LOW("\n Zero NAL, hence parse using start code"); 7129 if (m_frame_parser.parse_sc_frame(psource_frame, 7130 &h264_scratch,&partial_frame) == -1) 7131 { 7132 DEBUG_PRINT_ERROR("\n Error In Parsing Return Error"); 7133 return OMX_ErrorBadParameter; 7134 } 7135 } 7136 else 7137 { 7138 DEBUG_PRINT_LOW("\n Non-zero NAL length clip, hence parse with NAL size %d ",nal_length); 7139 if (m_frame_parser.parse_h264_nallength(psource_frame, 7140 &h264_scratch,&partial_frame) == -1) 7141 { 7142 DEBUG_PRINT_ERROR("\n Error In Parsing NAL size, Return Error"); 7143 return OMX_ErrorBadParameter; 7144 } 7145 } 7146 7147 if (partial_frame == 0) 7148 { 7149 if (nal_count == 0 && h264_scratch.nFilledLen == 0) 7150 { 7151 DEBUG_PRINT_LOW("\n First NAL with Zero Length, hence Skip"); 7152 nal_count++; 7153 h264_scratch.nTimeStamp = psource_frame->nTimeStamp; 7154 h264_scratch.nFlags = psource_frame->nFlags; 7155 } 7156 else 7157 { 7158 DEBUG_PRINT_LOW("\n Parsed New NAL Length = %d",h264_scratch.nFilledLen); 7159 if(h264_scratch.nFilledLen) 7160 { 7161 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen, 7162 NALU_TYPE_SPS); 7163 #ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT 7164 if (client_extradata & OMX_TIMEINFO_EXTRADATA) 7165 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, 7166 h264_scratch.nFilledLen, NALU_TYPE_SEI); 7167 else if (client_extradata & OMX_FRAMEINFO_EXTRADATA) 7168 // If timeinfo is present frame info from SEI is already processed 7169 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, 7170 h264_scratch.nFilledLen, NALU_TYPE_SEI); 7171 #endif 7172 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame); 7173 nal_count++; 7174 if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) { 7175 pdest_frame->nTimeStamp = h264_last_au_ts; 7176 pdest_frame->nFlags = h264_last_au_flags; 7177 #ifdef PANSCAN_HDLR 7178 if (client_extradata & OMX_FRAMEINFO_EXTRADATA) 7179 h264_parser->update_panscan_data(h264_last_au_ts); 7180 #endif 7181 } 7182 if(m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR || 7183 m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) { 7184 h264_last_au_ts = h264_scratch.nTimeStamp; 7185 h264_last_au_flags = h264_scratch.nFlags; 7186 #ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT 7187 if (client_extradata & OMX_TIMEINFO_EXTRADATA) 7188 { 7189 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts); 7190 if (!VALID_TS(h264_last_au_ts)) 7191 h264_last_au_ts = ts_in_sei; 7192 } 7193 #endif 7194 } else 7195 h264_last_au_ts = LLONG_MAX; 7196 } 7197 7198 if (!isNewFrame) 7199 { 7200 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >= 7201 h264_scratch.nFilledLen) 7202 { 7203 DEBUG_PRINT_LOW("\n Not a NewFrame Copy into Dest len %d", 7204 h264_scratch.nFilledLen); 7205 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen), 7206 h264_scratch.pBuffer,h264_scratch.nFilledLen); 7207 pdest_frame->nFilledLen += h264_scratch.nFilledLen; 7208 if(m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ) 7209 pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ; 7210 h264_scratch.nFilledLen = 0; 7211 } 7212 else 7213 { 7214 DEBUG_PRINT_LOW("\n Error:2: Destination buffer overflow for H264"); 7215 return OMX_ErrorBadParameter; 7216 } 7217 } 7218 else if(h264_scratch.nFilledLen) 7219 { 7220 look_ahead_nal = true; 7221 DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%d TimeStamp = %x", 7222 pdest_frame->nFilledLen,pdest_frame->nTimeStamp); 7223 DEBUG_PRINT_LOW("\n Found a frame size = %d number = %d", 7224 pdest_frame->nFilledLen,frame_count++); 7225 7226 if (pdest_frame->nFilledLen == 0) 7227 { 7228 DEBUG_PRINT_LOW("\n Copy the Current Frame since and push it"); 7229 look_ahead_nal = false; 7230 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >= 7231 h264_scratch.nFilledLen) 7232 { 7233 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen), 7234 h264_scratch.pBuffer,h264_scratch.nFilledLen); 7235 pdest_frame->nFilledLen += h264_scratch.nFilledLen; 7236 h264_scratch.nFilledLen = 0; 7237 } 7238 else 7239 { 7240 DEBUG_PRINT_ERROR("\n Error:3: Destination buffer overflow for H264"); 7241 return OMX_ErrorBadParameter; 7242 } 7243 } 7244 else 7245 { 7246 if(psource_frame->nFilledLen || h264_scratch.nFilledLen) 7247 { 7248 DEBUG_PRINT_LOW("\n Reset the EOS Flag"); 7249 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS; 7250 } 7251 /*Push the frame to the Decoder*/ 7252 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) 7253 { 7254 return OMX_ErrorBadParameter; 7255 } 7256 //frame_count++; 7257 pdest_frame = NULL; 7258 if (m_input_free_q.m_size) 7259 { 7260 m_input_free_q.pop_entry(&address,&p2,&id); 7261 pdest_frame = (OMX_BUFFERHEADERTYPE *) address; 7262 DEBUG_PRINT_LOW("\n Pop the next pdest_buffer %p",pdest_frame); 7263 pdest_frame->nFilledLen = 0; 7264 pdest_frame->nFlags = 0; 7265 pdest_frame->nTimeStamp = LLONG_MAX; 7266 } 7267 } 7268 } 7269 } 7270 } 7271 else 7272 { 7273 DEBUG_PRINT_LOW("\n Not a Complete Frame, pdest_frame->nFilledLen %d",pdest_frame->nFilledLen); 7274 /*Check if Destination Buffer is full*/ 7275 if (h264_scratch.nAllocLen == 7276 h264_scratch.nFilledLen + h264_scratch.nOffset) 7277 { 7278 DEBUG_PRINT_ERROR("\nERROR: Frame Not found though Destination Filled"); 7279 return OMX_ErrorStreamCorrupt; 7280 } 7281 } 7282 7283 if (!psource_frame->nFilledLen) 7284 { 7285 DEBUG_PRINT_LOW("\n Buffer Consumed return source %p back to client",psource_frame); 7286 7287 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) 7288 { 7289 if (pdest_frame) 7290 { 7291 DEBUG_PRINT_LOW("\n EOS Reached Pass Last Buffer"); 7292 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >= 7293 h264_scratch.nFilledLen) 7294 { 7295 if (pdest_frame->nFilledLen == 0) 7296 { 7297 /* No residual frame from before, send whatever 7298 * we have left */ 7299 memcpy((pdest_frame->pBuffer + pdest_frame->nFilledLen), 7300 h264_scratch.pBuffer, h264_scratch.nFilledLen); 7301 pdest_frame->nFilledLen += h264_scratch.nFilledLen; 7302 h264_scratch.nFilledLen = 0; 7303 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp; 7304 } 7305 else 7306 { 7307 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame); 7308 if (!isNewFrame) 7309 { 7310 /* Have a residual frame, but we know that the 7311 * AU in this frame is belonging to whatever 7312 * frame we had left over. So append it */ 7313 memcpy((pdest_frame->pBuffer + pdest_frame->nFilledLen), 7314 h264_scratch.pBuffer, h264_scratch.nFilledLen); 7315 pdest_frame->nFilledLen += h264_scratch.nFilledLen; 7316 h264_scratch.nFilledLen = 0; 7317 pdest_frame->nTimeStamp = h264_last_au_ts; 7318 } 7319 else 7320 { 7321 /* Completely new frame, let's just push what 7322 * we have now. The resulting EBD would trigger 7323 * another push */ 7324 generate_ebd = OMX_FALSE; 7325 pdest_frame->nTimeStamp = h264_last_au_ts; 7326 h264_last_au_ts = h264_scratch.nTimeStamp; 7327 } 7328 } 7329 } 7330 else 7331 { 7332 DEBUG_PRINT_ERROR("\nERROR:4: Destination buffer overflow for H264"); 7333 return OMX_ErrorBadParameter; 7334 } 7335 7336 /* Iff we coalesced two buffers, inherit the flags of both bufs */ 7337 if (generate_ebd == OMX_TRUE) 7338 { 7339 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags; 7340 } 7341 #ifdef MAX_RES_720P 7342 if (frame_count == 0) 7343 { 7344 DEBUG_PRINT_HIGH("No frames sent to driver yet, " 7345 "So send zero length EOS buffer"); 7346 pdest_frame->nFilledLen = 0; 7347 } 7348 #endif 7349 DEBUG_PRINT_LOW("pdest_frame->nFilledLen = %d, nFlags = 0x%x, TimeStamp = %x", 7350 pdest_frame->nFilledLen, pdest_frame->nFlags, pdest_frame->nTimeStamp); 7351 DEBUG_PRINT_LOW("\n Push AU frame number %d to driver", frame_count++); 7352 #ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT 7353 if (client_extradata & OMX_TIMEINFO_EXTRADATA) 7354 { 7355 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp); 7356 if (!VALID_TS(pdest_frame->nTimeStamp)) 7357 pdest_frame->nTimeStamp = ts_in_sei; 7358 } 7359 #endif 7360 /*Push the frame to the Decoder*/ 7361 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) 7362 { 7363 return OMX_ErrorBadParameter; 7364 } 7365 frame_count++; 7366 pdest_frame = NULL; 7367 } 7368 else 7369 { 7370 DEBUG_PRINT_LOW("\n Last frame in else dest addr %p size %d", 7371 pdest_frame,h264_scratch.nFilledLen); 7372 generate_ebd = OMX_FALSE; 7373 } 7374 } 7375 } 7376 if(generate_ebd && !psource_frame->nFilledLen) 7377 { 7378 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame); 7379 psource_frame = NULL; 7380 if (m_input_pending_q.m_size) 7381 { 7382 DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame); 7383 m_input_pending_q.pop_entry(&address,&p2,&id); 7384 psource_frame = (OMX_BUFFERHEADERTYPE *) address; 7385 DEBUG_PRINT_LOW("\nNext source Buffer flag %d src length %d", 7386 psource_frame->nFlags,psource_frame->nFilledLen); 7387 } 7388 } 7389 return OMX_ErrorNone; 7390 } 7391 7392 OMX_ERRORTYPE omx_vdec::push_input_vc1 (OMX_HANDLETYPE hComp) 7393 { 7394 OMX_U8 *buf, *pdest; 7395 OMX_U32 partial_frame = 1; 7396 OMX_U32 buf_len, dest_len; 7397 7398 if(first_frame == 0) 7399 { 7400 first_frame = 1; 7401 DEBUG_PRINT_LOW("\nFirst i/p buffer for VC1 arbitrary bytes\n"); 7402 if(!m_vendor_config.pData) 7403 { 7404 DEBUG_PRINT_LOW("\nCheck profile type in 1st source buffer\n"); 7405 buf = psource_frame->pBuffer; 7406 buf_len = psource_frame->nFilledLen; 7407 7408 if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) == 7409 VC1_SP_MP_START_CODE) 7410 { 7411 m_vc1_profile = VC1_SP_MP_RCV; 7412 } 7413 else if(*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE) 7414 { 7415 m_vc1_profile = VC1_AP; 7416 } 7417 else 7418 { 7419 DEBUG_PRINT_ERROR("\nInvalid sequence layer in first buffer\n"); 7420 return OMX_ErrorStreamCorrupt; 7421 } 7422 } 7423 else 7424 { 7425 pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen + 7426 pdest_frame->nOffset; 7427 dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen + 7428 pdest_frame->nOffset); 7429 7430 if(dest_len < m_vendor_config.nDataSize) 7431 { 7432 DEBUG_PRINT_ERROR("\nDestination buffer full\n"); 7433 return OMX_ErrorBadParameter; 7434 } 7435 else 7436 { 7437 memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize); 7438 pdest_frame->nFilledLen += m_vendor_config.nDataSize; 7439 } 7440 } 7441 } 7442 7443 switch(m_vc1_profile) 7444 { 7445 case VC1_AP: 7446 DEBUG_PRINT_LOW("\n VC1 AP, hence parse using frame start code"); 7447 if (push_input_sc_codec(hComp) != OMX_ErrorNone) 7448 { 7449 DEBUG_PRINT_ERROR("\n Error In Parsing VC1 AP start code"); 7450 return OMX_ErrorBadParameter; 7451 } 7452 break; 7453 7454 case VC1_SP_MP_RCV: 7455 default: 7456 DEBUG_PRINT_ERROR("\n Unsupported VC1 profile in ArbitraryBytes Mode\n"); 7457 return OMX_ErrorBadParameter; 7458 } 7459 return OMX_ErrorNone; 7460 } 7461 7462 #ifndef USE_ION 7463 bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size, 7464 OMX_U32 alignment) 7465 { 7466 struct pmem_allocation allocation; 7467 allocation.size = buffer_size; 7468 allocation.align = clip2(alignment); 7469 if (allocation.align < 4096) 7470 { 7471 allocation.align = 4096; 7472 } 7473 if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) 7474 { 7475 DEBUG_PRINT_ERROR("\n Aligment(%u) failed with pmem driver Sz(%lu)", 7476 allocation.align, allocation.size); 7477 return false; 7478 } 7479 return true; 7480 } 7481 #endif 7482 7483 #ifdef USE_ION 7484 int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size, 7485 OMX_U32 alignment, struct ion_allocation_data *alloc_data, 7486 struct ion_fd_data *fd_data,int flag) 7487 { 7488 int fd = -EINVAL; 7489 int rc = -EINVAL; 7490 int ion_dev_flag; 7491 struct vdec_ion ion_buf_info; 7492 if (!alloc_data || buffer_size <= 0 || !fd_data) { 7493 DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory\n"); 7494 return -EINVAL; 7495 } 7496 ion_dev_flag = O_RDONLY; 7497 fd = open (MEM_DEVICE, ion_dev_flag); 7498 if (fd < 0) { 7499 DEBUG_PRINT_ERROR("opening ion device failed with fd = %d\n", fd); 7500 return fd; 7501 } 7502 alloc_data->flags = 0; 7503 if (!secure_mode && (flag & ION_FLAG_CACHED)) 7504 { 7505 alloc_data->flags |= ION_FLAG_CACHED; 7506 } 7507 alloc_data->len = buffer_size; 7508 alloc_data->align = clip2(alignment); 7509 if (alloc_data->align < 4096) 7510 { 7511 alloc_data->align = 4096; 7512 } 7513 7514 if(secure_mode) { 7515 alloc_data->heap_mask = ION_HEAP(MEM_HEAP_ID); 7516 alloc_data->flags |= ION_SECURE; 7517 } else { 7518 alloc_data->heap_mask = (ION_HEAP(ION_IOMMU_HEAP_ID)); 7519 } 7520 rc = ioctl(fd,ION_IOC_ALLOC,alloc_data); 7521 if (rc || !alloc_data->handle) { 7522 DEBUG_PRINT_ERROR("\n ION ALLOC memory failed "); 7523 alloc_data->handle = NULL; 7524 close(fd); 7525 fd = -ENOMEM; 7526 return fd; 7527 } 7528 fd_data->handle = alloc_data->handle; 7529 rc = ioctl(fd,ION_IOC_MAP,fd_data); 7530 if (rc) { 7531 DEBUG_PRINT_ERROR("\n ION MAP failed "); 7532 ion_buf_info.ion_alloc_data = *alloc_data; 7533 ion_buf_info.ion_device_fd = fd; 7534 ion_buf_info.fd_ion_data = *fd_data; 7535 free_ion_memory(&ion_buf_info); 7536 fd_data->fd =-1; 7537 close(fd); 7538 fd = -ENOMEM; 7539 } 7540 7541 return fd; 7542 } 7543 7544 void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info) { 7545 7546 if(!buf_ion_info) { 7547 DEBUG_PRINT_ERROR("\n ION: free called with invalid fd/allocdata"); 7548 return; 7549 } 7550 if(ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE, 7551 &buf_ion_info->ion_alloc_data.handle)) { 7552 DEBUG_PRINT_ERROR("\n ION: free failed" ); 7553 } 7554 close(buf_ion_info->ion_device_fd); 7555 buf_ion_info->ion_device_fd = -1; 7556 buf_ion_info->ion_alloc_data.handle = NULL; 7557 buf_ion_info->fd_ion_data.fd = -1; 7558 } 7559 #endif 7560 void omx_vdec::free_output_buffer_header() 7561 { 7562 DEBUG_PRINT_HIGH("\n ALL output buffers are freed/released"); 7563 output_use_buffer = false; 7564 ouput_egl_buffers = false; 7565 7566 if (m_out_mem_ptr) 7567 { 7568 free (m_out_mem_ptr); 7569 m_out_mem_ptr = NULL; 7570 } 7571 7572 if(m_platform_list) 7573 { 7574 free(m_platform_list); 7575 m_platform_list = NULL; 7576 } 7577 7578 if (drv_ctx.ptr_respbuffer) 7579 { 7580 free (drv_ctx.ptr_respbuffer); 7581 drv_ctx.ptr_respbuffer = NULL; 7582 } 7583 if (drv_ctx.ptr_outputbuffer) 7584 { 7585 free (drv_ctx.ptr_outputbuffer); 7586 drv_ctx.ptr_outputbuffer = NULL; 7587 } 7588 #ifdef USE_ION 7589 if (drv_ctx.op_buf_ion_info) { 7590 DEBUG_PRINT_LOW("\n Free o/p ion context"); 7591 free(drv_ctx.op_buf_ion_info); 7592 drv_ctx.op_buf_ion_info = NULL; 7593 } 7594 #endif 7595 } 7596 7597 void omx_vdec::free_input_buffer_header() 7598 { 7599 input_use_buffer = false; 7600 if (arbitrary_bytes) 7601 { 7602 if (m_inp_heap_ptr) 7603 { 7604 DEBUG_PRINT_LOW("\n Free input Heap Pointer"); 7605 free (m_inp_heap_ptr); 7606 m_inp_heap_ptr = NULL; 7607 } 7608 7609 if (m_phdr_pmem_ptr) 7610 { 7611 DEBUG_PRINT_LOW("\n Free input pmem header Pointer"); 7612 free (m_phdr_pmem_ptr); 7613 m_phdr_pmem_ptr = NULL; 7614 } 7615 } 7616 if (m_inp_mem_ptr) 7617 { 7618 DEBUG_PRINT_LOW("\n Free input pmem Pointer area"); 7619 free (m_inp_mem_ptr); 7620 m_inp_mem_ptr = NULL; 7621 } 7622 7623 /* We just freed all the buffer headers, every thing in m_input_free_q 7624 * is now invalid */ 7625 while (m_input_free_q.m_size) 7626 { 7627 unsigned address,p2,id; 7628 m_input_free_q.pop_entry(&address,&p2,&id); 7629 } 7630 7631 if (drv_ctx.ptr_inputbuffer) 7632 { 7633 DEBUG_PRINT_LOW("\n Free Driver Context pointer"); 7634 free (drv_ctx.ptr_inputbuffer); 7635 drv_ctx.ptr_inputbuffer = NULL; 7636 } 7637 #ifdef USE_ION 7638 if (drv_ctx.ip_buf_ion_info) { 7639 DEBUG_PRINT_LOW("\n Free ion context"); 7640 free(drv_ctx.ip_buf_ion_info); 7641 drv_ctx.ip_buf_ion_info = NULL; 7642 } 7643 #endif 7644 } 7645 7646 OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop) 7647 { 7648 struct vdec_ioctl_msg ioctl_msg = {NULL, NULL}; 7649 OMX_ERRORTYPE eRet = OMX_ErrorNone; 7650 unsigned int buf_size = 0, extra_data_size = 0; 7651 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)", 7652 buffer_prop->actualcount, buffer_prop->buffer_size); 7653 ioctl_msg.in = NULL; 7654 ioctl_msg.out = buffer_prop; 7655 if (ioctl (drv_ctx.video_driver_fd, VDEC_IOCTL_GET_BUFFER_REQ, 7656 (void*)&ioctl_msg) < 0) 7657 { 7658 DEBUG_PRINT_ERROR("Requesting buffer requirements failed"); 7659 eRet = OMX_ErrorInsufficientResources; 7660 } 7661 else 7662 { 7663 buf_size = buffer_prop->buffer_size; 7664 7665 ioctl_msg.in = NULL; 7666 ioctl_msg.out = &drv_ctx.video_resolution; 7667 if (ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_GET_PICRES, &ioctl_msg)) 7668 { 7669 DEBUG_PRINT_ERROR("Error VDEC_IOCTL_GET_PICRES"); 7670 eRet = OMX_ErrorHardware; 7671 return eRet; 7672 } 7673 else 7674 { 7675 update_resolution(drv_ctx.video_resolution.frame_width, 7676 drv_ctx.video_resolution.frame_height); 7677 } 7678 7679 if (client_extradata & OMX_FRAMEINFO_EXTRADATA) 7680 { 7681 DEBUG_PRINT_HIGH("Frame info extra data enabled!"); 7682 extra_data_size += OMX_FRAMEINFO_EXTRADATA_SIZE; 7683 } 7684 if (client_extradata & OMX_INTERLACE_EXTRADATA) 7685 { 7686 DEBUG_PRINT_HIGH("Interlace extra data enabled!"); 7687 extra_data_size += OMX_INTERLACE_EXTRADATA_SIZE; 7688 } 7689 if (client_extradata & OMX_PORTDEF_EXTRADATA) 7690 { 7691 extra_data_size += OMX_PORTDEF_EXTRADATA_SIZE; 7692 DEBUG_PRINT_HIGH("Smooth streaming enabled extra_data_size=%d\n", 7693 extra_data_size); 7694 } 7695 if (extra_data_size) 7696 { 7697 extra_data_size += sizeof(OMX_OTHER_EXTRADATATYPE); //Space for terminator 7698 buf_size = ((buf_size + 3)&(~3)); //Align extradata start address to 64Bit 7699 } 7700 buf_size += extra_data_size; 7701 buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1)); 7702 DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%d) BufSize(%d)", 7703 buffer_prop->actualcount, buffer_prop->buffer_size, buf_size); 7704 if (in_reconfig) // BufReq will be set to driver when port is disabled 7705 buffer_prop->buffer_size = buf_size; 7706 else if (buf_size != buffer_prop->buffer_size) 7707 { 7708 buffer_prop->buffer_size = buf_size; 7709 eRet = set_buffer_req(buffer_prop); 7710 } 7711 } 7712 DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%d)", 7713 buffer_prop->actualcount, buffer_prop->buffer_size); 7714 return eRet; 7715 } 7716 7717 OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop) 7718 { 7719 struct vdec_ioctl_msg ioctl_msg = {NULL, NULL}; 7720 OMX_ERRORTYPE eRet = OMX_ErrorNone; 7721 unsigned buf_size = 0; 7722 DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%d)", 7723 buffer_prop->actualcount, buffer_prop->buffer_size); 7724 buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1)); 7725 if (buf_size != buffer_prop->buffer_size) 7726 { 7727 DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%d) Required(%d)", 7728 buffer_prop->buffer_size, buf_size); 7729 eRet = OMX_ErrorBadParameter; 7730 } 7731 else 7732 { 7733 ioctl_msg.in = buffer_prop; 7734 ioctl_msg.out = NULL; 7735 if (ioctl (drv_ctx.video_driver_fd, VDEC_IOCTL_SET_BUFFER_REQ, 7736 (void*)&ioctl_msg) < 0) 7737 { 7738 DEBUG_PRINT_ERROR("Setting buffer requirements failed"); 7739 eRet = OMX_ErrorInsufficientResources; 7740 } else { 7741 if (!client_buffers.update_buffer_req()) { 7742 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed"); 7743 eRet = OMX_ErrorInsufficientResources; 7744 } 7745 } 7746 } 7747 return eRet; 7748 } 7749 7750 OMX_ERRORTYPE omx_vdec::start_port_reconfig() 7751 { 7752 struct vdec_ioctl_msg ioctl_msg = {NULL, NULL}; 7753 OMX_ERRORTYPE eRet = OMX_ErrorNone; 7754 eRet = update_picture_resolution(); 7755 if (eRet == OMX_ErrorNone) 7756 { 7757 ioctl_msg.out = &drv_ctx.interlace; 7758 if (ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_GET_INTERLACE_FORMAT, &ioctl_msg)) 7759 { 7760 DEBUG_PRINT_ERROR("Error VDEC_IOCTL_GET_INTERLACE_FORMAT"); 7761 eRet = OMX_ErrorHardware; 7762 } 7763 else 7764 { 7765 if (drv_ctx.interlace != VDEC_InterlaceFrameProgressive) 7766 { 7767 DEBUG_PRINT_HIGH("Interlace format detected (%x)!", drv_ctx.interlace); 7768 if(!secure_mode) 7769 client_extradata |= OMX_INTERLACE_EXTRADATA; 7770 else { 7771 DEBUG_PRINT_ERROR("secure mode interlaced format not supported"); 7772 eRet = OMX_ErrorUnsupportedSetting; 7773 } 7774 } 7775 in_reconfig = true; 7776 op_buf_rcnfg.buffer_type = VDEC_BUFFER_TYPE_OUTPUT; 7777 eRet = get_buffer_req(&op_buf_rcnfg); 7778 } 7779 } 7780 return eRet; 7781 } 7782 7783 OMX_ERRORTYPE omx_vdec::update_picture_resolution() 7784 { 7785 struct vdec_ioctl_msg ioctl_msg = {NULL, NULL}; 7786 OMX_ERRORTYPE eRet = OMX_ErrorNone; 7787 ioctl_msg.in = NULL; 7788 ioctl_msg.out = &drv_ctx.video_resolution; 7789 if (ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_GET_PICRES, &ioctl_msg)) 7790 { 7791 DEBUG_PRINT_ERROR("Error VDEC_IOCTL_GET_PICRES"); 7792 eRet = OMX_ErrorHardware; 7793 } 7794 return eRet; 7795 } 7796 7797 OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn) 7798 { 7799 OMX_ERRORTYPE eRet = OMX_ErrorNone; 7800 if (!portDefn) 7801 { 7802 return OMX_ErrorBadParameter; 7803 } 7804 DEBUG_PRINT_LOW("omx_vdec::update_portdef\n"); 7805 portDefn->nVersion.nVersion = OMX_SPEC_VERSION; 7806 portDefn->nSize = sizeof(portDefn); 7807 portDefn->eDomain = OMX_PortDomainVideo; 7808 if (drv_ctx.frame_rate.fps_denominator > 0) 7809 portDefn->format.video.xFramerate = drv_ctx.frame_rate.fps_numerator / 7810 drv_ctx.frame_rate.fps_denominator; 7811 else { 7812 DEBUG_PRINT_ERROR("Error: Divide by zero \n"); 7813 return OMX_ErrorBadParameter; 7814 } 7815 if (0 == portDefn->nPortIndex) 7816 { 7817 portDefn->eDir = OMX_DirInput; 7818 portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount; 7819 portDefn->nBufferCountMin = drv_ctx.ip_buf.mincount; 7820 portDefn->nBufferSize = drv_ctx.ip_buf.buffer_size; 7821 portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused; 7822 portDefn->format.video.eCompressionFormat = eCompressionFormat; 7823 portDefn->bEnabled = m_inp_bEnabled; 7824 portDefn->bPopulated = m_inp_bPopulated; 7825 } 7826 else if (1 == portDefn->nPortIndex) 7827 { 7828 portDefn->eDir = OMX_DirOutput; 7829 if (update_picture_resolution() != OMX_ErrorNone) 7830 { 7831 ALOGE(" update_picture_resolution failed \n"); 7832 return OMX_ErrorHardware; 7833 } 7834 if (!client_buffers.update_buffer_req()) { 7835 DEBUG_PRINT_ERROR("\n client_buffers.update_buffer_req Failed"); 7836 return OMX_ErrorHardware; 7837 } 7838 if (in_reconfig) 7839 { 7840 portDefn->nBufferCountActual = op_buf_rcnfg.actualcount; 7841 portDefn->nBufferCountMin = op_buf_rcnfg.mincount; 7842 portDefn->nBufferSize = op_buf_rcnfg.buffer_size; 7843 } 7844 else 7845 { 7846 portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount; 7847 portDefn->nBufferCountMin = drv_ctx.op_buf.mincount; 7848 portDefn->nBufferSize = drv_ctx.op_buf.buffer_size; 7849 } 7850 unsigned int buf_size = 0; 7851 if (!client_buffers.get_buffer_req(buf_size)) { 7852 DEBUG_PRINT_ERROR("\n update buffer requirements"); 7853 return OMX_ErrorHardware; 7854 } 7855 portDefn->nBufferSize = buf_size; 7856 portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; 7857 portDefn->bEnabled = m_out_bEnabled; 7858 portDefn->bPopulated = m_out_bPopulated; 7859 if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) { 7860 DEBUG_PRINT_ERROR("\n Error in getting color format"); 7861 return OMX_ErrorHardware; 7862 } 7863 } 7864 else 7865 { 7866 portDefn->eDir = OMX_DirMax; 7867 DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d", 7868 (int)portDefn->nPortIndex); 7869 eRet = OMX_ErrorBadPortIndex; 7870 } 7871 portDefn->format.video.nFrameHeight = drv_ctx.video_resolution.frame_height; 7872 portDefn->format.video.nFrameWidth = drv_ctx.video_resolution.frame_width; 7873 portDefn->format.video.nStride = drv_ctx.video_resolution.stride; 7874 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines; 7875 DEBUG_PRINT_LOW("update_portdef Width = %d Height = %d Stride = %u" 7876 "SliceHeight = %u \n", portDefn->format.video.nFrameHeight, 7877 portDefn->format.video.nFrameWidth, 7878 portDefn->format.video.nStride, 7879 portDefn->format.video.nSliceHeight); 7880 return eRet; 7881 7882 } 7883 7884 OMX_ERRORTYPE omx_vdec::allocate_output_headers() 7885 { 7886 OMX_ERRORTYPE eRet = OMX_ErrorNone; 7887 OMX_BUFFERHEADERTYPE *bufHdr = NULL; 7888 unsigned i= 0; 7889 7890 if(!m_out_mem_ptr) { 7891 DEBUG_PRINT_HIGH("\n Use o/p buffer case - Header List allocation"); 7892 int nBufHdrSize = 0; 7893 int nPlatformEntrySize = 0; 7894 int nPlatformListSize = 0; 7895 int nPMEMInfoSize = 0; 7896 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList; 7897 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry; 7898 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo; 7899 7900 DEBUG_PRINT_LOW("Setting First Output Buffer(%d)\n", 7901 drv_ctx.op_buf.actualcount); 7902 nBufHdrSize = drv_ctx.op_buf.actualcount * 7903 sizeof(OMX_BUFFERHEADERTYPE); 7904 7905 nPMEMInfoSize = drv_ctx.op_buf.actualcount * 7906 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO); 7907 nPlatformListSize = drv_ctx.op_buf.actualcount * 7908 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST); 7909 nPlatformEntrySize = drv_ctx.op_buf.actualcount * 7910 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY); 7911 7912 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize, 7913 sizeof(OMX_BUFFERHEADERTYPE), 7914 nPMEMInfoSize, 7915 nPlatformListSize); 7916 DEBUG_PRINT_LOW("PE %d bmSize %d \n",nPlatformEntrySize, 7917 m_out_bm_count); 7918 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1); 7919 // Alloc mem for platform specific info 7920 char *pPtr=NULL; 7921 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize + 7922 nPMEMInfoSize,1); 7923 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \ 7924 calloc (sizeof(struct vdec_bufferpayload), 7925 drv_ctx.op_buf.actualcount); 7926 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\ 7927 calloc (sizeof (struct vdec_output_frameinfo), 7928 drv_ctx.op_buf.actualcount); 7929 #ifdef USE_ION 7930 drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \ 7931 calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount); 7932 #endif 7933 7934 if(m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer 7935 && drv_ctx.ptr_respbuffer) 7936 { 7937 bufHdr = m_out_mem_ptr; 7938 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr); 7939 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *) 7940 (((char *) m_platform_list) + nPlatformListSize); 7941 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) 7942 (((char *) m_platform_entry) + nPlatformEntrySize); 7943 pPlatformList = m_platform_list; 7944 pPlatformEntry = m_platform_entry; 7945 pPMEMInfo = m_pmem_info; 7946 7947 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr); 7948 7949 // Settting the entire storage nicely 7950 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr, 7951 m_out_mem_ptr,pPlatformEntry); 7952 DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo); 7953 for(i=0; i < drv_ctx.op_buf.actualcount ; i++) 7954 { 7955 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE); 7956 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION; 7957 // Set the values when we determine the right HxW param 7958 bufHdr->nAllocLen = 0; 7959 bufHdr->nFilledLen = 0; 7960 bufHdr->pAppPrivate = NULL; 7961 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 7962 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM; 7963 pPlatformEntry->entry = pPMEMInfo; 7964 // Initialize the Platform List 7965 pPlatformList->nEntries = 1; 7966 pPlatformList->entryList = pPlatformEntry; 7967 // Keep pBuffer NULL till vdec is opened 7968 bufHdr->pBuffer = NULL; 7969 pPMEMInfo->offset = 0; 7970 pPMEMInfo->pmem_fd = 0; 7971 bufHdr->pPlatformPrivate = pPlatformList; 7972 drv_ctx.ptr_outputbuffer[i].pmem_fd = -1; 7973 #ifdef USE_ION 7974 drv_ctx.op_buf_ion_info[i].ion_device_fd =-1; 7975 #endif 7976 /*Create a mapping between buffers*/ 7977 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i]; 7978 drv_ctx.ptr_respbuffer[i].client_data = (void *) \ 7979 &drv_ctx.ptr_outputbuffer[i]; 7980 // Move the buffer and buffer header pointers 7981 bufHdr++; 7982 pPMEMInfo++; 7983 pPlatformEntry++; 7984 pPlatformList++; 7985 } 7986 } 7987 else 7988 { 7989 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%x][0x%x]\n",\ 7990 m_out_mem_ptr, pPtr); 7991 if(m_out_mem_ptr) 7992 { 7993 free(m_out_mem_ptr); 7994 m_out_mem_ptr = NULL; 7995 } 7996 if(pPtr) 7997 { 7998 free(pPtr); 7999 pPtr = NULL; 8000 } 8001 if(drv_ctx.ptr_outputbuffer) 8002 { 8003 free(drv_ctx.ptr_outputbuffer); 8004 drv_ctx.ptr_outputbuffer = NULL; 8005 } 8006 if(drv_ctx.ptr_respbuffer) 8007 { 8008 free(drv_ctx.ptr_respbuffer); 8009 drv_ctx.ptr_respbuffer = NULL; 8010 } 8011 #ifdef USE_ION 8012 if (drv_ctx.op_buf_ion_info) { 8013 DEBUG_PRINT_LOW("\n Free o/p ion context"); 8014 free(drv_ctx.op_buf_ion_info); 8015 drv_ctx.op_buf_ion_info = NULL; 8016 } 8017 #endif 8018 eRet = OMX_ErrorInsufficientResources; 8019 } 8020 } else { 8021 eRet = OMX_ErrorInsufficientResources; 8022 } 8023 return eRet; 8024 } 8025 8026 void omx_vdec::complete_pending_buffer_done_cbs() 8027 { 8028 unsigned p1; 8029 unsigned p2; 8030 unsigned ident; 8031 omx_cmd_queue tmp_q, pending_bd_q; 8032 pthread_mutex_lock(&m_lock); 8033 // pop all pending GENERATE FDB from ftb queue 8034 while (m_ftb_q.m_size) 8035 { 8036 m_ftb_q.pop_entry(&p1,&p2,&ident); 8037 if(ident == OMX_COMPONENT_GENERATE_FBD) 8038 { 8039 pending_bd_q.insert_entry(p1,p2,ident); 8040 } 8041 else 8042 { 8043 tmp_q.insert_entry(p1,p2,ident); 8044 } 8045 } 8046 //return all non GENERATE FDB to ftb queue 8047 while(tmp_q.m_size) 8048 { 8049 tmp_q.pop_entry(&p1,&p2,&ident); 8050 m_ftb_q.insert_entry(p1,p2,ident); 8051 } 8052 // pop all pending GENERATE EDB from etb queue 8053 while (m_etb_q.m_size) 8054 { 8055 m_etb_q.pop_entry(&p1,&p2,&ident); 8056 if(ident == OMX_COMPONENT_GENERATE_EBD) 8057 { 8058 pending_bd_q.insert_entry(p1,p2,ident); 8059 } 8060 else 8061 { 8062 tmp_q.insert_entry(p1,p2,ident); 8063 } 8064 } 8065 //return all non GENERATE FDB to etb queue 8066 while(tmp_q.m_size) 8067 { 8068 tmp_q.pop_entry(&p1,&p2,&ident); 8069 m_etb_q.insert_entry(p1,p2,ident); 8070 } 8071 pthread_mutex_unlock(&m_lock); 8072 // process all pending buffer dones 8073 while(pending_bd_q.m_size) 8074 { 8075 pending_bd_q.pop_entry(&p1,&p2,&ident); 8076 switch(ident) 8077 { 8078 case OMX_COMPONENT_GENERATE_EBD: 8079 if(empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) 8080 { 8081 DEBUG_PRINT_ERROR("\nERROR: empty_buffer_done() failed!\n"); 8082 omx_report_error (); 8083 } 8084 break; 8085 8086 case OMX_COMPONENT_GENERATE_FBD: 8087 if(fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) 8088 { 8089 DEBUG_PRINT_ERROR("\nERROR: fill_buffer_done() failed!\n"); 8090 omx_report_error (); 8091 } 8092 break; 8093 } 8094 } 8095 } 8096 8097 void omx_vdec::set_frame_rate(OMX_S64 act_timestamp) 8098 { 8099 OMX_U32 new_frame_interval = 0; 8100 struct vdec_ioctl_msg ioctl_msg = {NULL, NULL}; 8101 if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts 8102 && (((act_timestamp > prev_ts )? act_timestamp - prev_ts: prev_ts-act_timestamp)>2000)) 8103 { 8104 new_frame_interval = (act_timestamp > prev_ts)? 8105 act_timestamp - prev_ts : 8106 prev_ts - act_timestamp; 8107 if (new_frame_interval < frm_int || frm_int == 0) 8108 { 8109 frm_int = new_frame_interval; 8110 if(frm_int) 8111 { 8112 drv_ctx.frame_rate.fps_numerator = 1e6; 8113 drv_ctx.frame_rate.fps_denominator = frm_int; 8114 DEBUG_PRINT_LOW("set_frame_rate: frm_int(%u) fps(%f)", 8115 frm_int, drv_ctx.frame_rate.fps_numerator / 8116 (float)drv_ctx.frame_rate.fps_denominator); 8117 ioctl_msg.in = &drv_ctx.frame_rate; 8118 if (ioctl (drv_ctx.video_driver_fd, VDEC_IOCTL_SET_FRAME_RATE, 8119 (void*)&ioctl_msg) < 0) 8120 { 8121 DEBUG_PRINT_ERROR("Setting frame rate failed"); 8122 } 8123 } 8124 } 8125 } 8126 prev_ts = act_timestamp; 8127 } 8128 8129 void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp) 8130 { 8131 if (rst_prev_ts && VALID_TS(act_timestamp)) 8132 { 8133 prev_ts = act_timestamp; 8134 rst_prev_ts = false; 8135 } 8136 else if (VALID_TS(prev_ts)) 8137 { 8138 bool codec_cond = (drv_ctx.timestamp_adjust)? 8139 (!VALID_TS(act_timestamp) || (((act_timestamp > prev_ts)? 8140 (act_timestamp - prev_ts):(prev_ts - act_timestamp)) <= 2000)): 8141 (!VALID_TS(act_timestamp) || act_timestamp == prev_ts); 8142 if(frm_int > 0 && codec_cond) 8143 { 8144 DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp); 8145 act_timestamp = prev_ts + frm_int; 8146 DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp); 8147 prev_ts = act_timestamp; 8148 } 8149 else 8150 set_frame_rate(act_timestamp); 8151 } 8152 else if (frm_int > 0) // In this case the frame rate was set along 8153 { // with the port definition, start ts with 0 8154 act_timestamp = prev_ts = 0; // and correct if a valid ts is received. 8155 rst_prev_ts = true; 8156 } 8157 } 8158 8159 void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr) 8160 { 8161 OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL; 8162 OMX_U32 num_conceal_MB = 0; 8163 OMX_S64 ts_in_sei = 0; 8164 OMX_U32 frame_rate = 0; 8165 8166 OMX_U32 index = p_buf_hdr - m_out_mem_ptr; 8167 OMX_U8* pBuffer = (OMX_U8 *)drv_ctx.ptr_outputbuffer[index].bufferaddr; 8168 8169 p_extra = (OMX_OTHER_EXTRADATATYPE *) 8170 ((unsigned)(pBuffer + p_buf_hdr->nOffset + 8171 p_buf_hdr->nFilledLen + 3)&(~3)); 8172 if ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen)) 8173 p_extra = NULL; 8174 if (drv_ctx.extradata && (p_buf_hdr->nFlags & OMX_BUFFERFLAG_EXTRADATA)) 8175 { 8176 // Process driver extradata 8177 while(p_extra && p_extra->eType != VDEC_EXTRADATA_NONE) 8178 { 8179 DEBUG_PRINT_LOW("handle_extradata : pBuf(%p) BufTS(%lld) Type(%x) DataSz(%u)", 8180 p_buf_hdr, p_buf_hdr->nTimeStamp, p_extra->eType, p_extra->nDataSize); 8181 if (p_extra->nSize < p_extra->nDataSize) 8182 { 8183 DEBUG_PRINT_ERROR(" \n Corrupt metadata Buffer size %d payload size %d", 8184 p_extra->nSize, p_extra->nDataSize); 8185 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); 8186 if ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen) || 8187 p_extra->nDataSize == 0 || p_extra->nSize == 0) 8188 p_extra = NULL; 8189 continue; 8190 } 8191 if (p_extra->eType == VDEC_EXTRADATA_MB_ERROR_MAP) 8192 { 8193 if (client_extradata & OMX_FRAMEINFO_EXTRADATA) 8194 num_conceal_MB = count_MB_in_extradata(p_extra); 8195 if (client_extradata & VDEC_EXTRADATA_MB_ERROR_MAP) 8196 // Map driver extradata to corresponding OMX type 8197 p_extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataConcealMB; 8198 else 8199 p_extra->eType = OMX_ExtraDataMax; // Invalid type to avoid expose this extradata to OMX client 8200 #ifdef _ANDROID_ 8201 if (m_debug_concealedmb) { 8202 DEBUG_PRINT_HIGH("Concealed MB percentage is %u", num_conceal_MB); 8203 } 8204 #endif /* _ANDROID_ */ 8205 } 8206 else if (p_extra->eType == VDEC_EXTRADATA_SEI) 8207 { 8208 p_sei = p_extra; 8209 #ifdef MAX_RES_1080P 8210 h264_parser->parse_nal((OMX_U8*)p_sei->data, p_sei->nDataSize, NALU_TYPE_SEI); 8211 #endif 8212 p_extra->eType = OMX_ExtraDataMax; // Invalid type to avoid expose this extradata to OMX client 8213 } 8214 else if (p_extra->eType == VDEC_EXTRADATA_VUI) 8215 { 8216 p_vui = p_extra; 8217 #ifdef MAX_RES_1080P 8218 h264_parser->parse_nal((OMX_U8*)p_vui->data, p_vui->nDataSize, NALU_TYPE_VUI, false); 8219 #endif 8220 p_extra->eType = OMX_ExtraDataMax; // Invalid type to avoid expose this extradata to OMX client 8221 } 8222 print_debug_extradata(p_extra); 8223 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); 8224 if ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen) || 8225 p_extra->nDataSize == 0 || p_extra->nSize == 0) 8226 p_extra = NULL; 8227 } 8228 if (!(client_extradata & VDEC_EXTRADATA_MB_ERROR_MAP)) 8229 { 8230 // Driver extradata is only exposed if MB map is requested by client, 8231 // otherwise can be overwritten by omx extradata. 8232 p_extra = (OMX_OTHER_EXTRADATATYPE *) 8233 ((unsigned)(pBuffer + p_buf_hdr->nOffset + 8234 p_buf_hdr->nFilledLen + 3)&(~3)); 8235 p_buf_hdr->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA; 8236 } 8237 } 8238 8239 #ifdef PROCESS_EXTRADATA_IN_OUTPUT_PORT 8240 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) 8241 { 8242 if (client_extradata & OMX_TIMEINFO_EXTRADATA) 8243 { 8244 if (p_vui) 8245 h264_parser->parse_nal((OMX_U8*)p_vui->data, p_vui->nDataSize, NALU_TYPE_VUI, false); 8246 if (p_sei) 8247 h264_parser->parse_nal((OMX_U8*)p_sei->data, p_sei->nDataSize, NALU_TYPE_SEI); 8248 ts_in_sei = h264_parser->process_ts_with_sei_vui(p_buf_hdr->nTimeStamp); 8249 if (!VALID_TS(p_buf_hdr->nTimeStamp)) 8250 p_buf_hdr->nTimeStamp = ts_in_sei; 8251 } 8252 else if ((client_extradata & OMX_FRAMEINFO_EXTRADATA) && p_sei) 8253 // If timeinfo is present frame info from SEI is already processed 8254 h264_parser->parse_nal((OMX_U8*)p_sei->data, p_sei->nDataSize, NALU_TYPE_SEI); 8255 } 8256 #endif 8257 if ((client_extradata & OMX_INTERLACE_EXTRADATA) && p_extra && 8258 ((OMX_U8*)p_extra + OMX_INTERLACE_EXTRADATA_SIZE) < 8259 (pBuffer + p_buf_hdr->nAllocLen)) 8260 { 8261 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA; 8262 append_interlace_extradata(p_extra, 8263 ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->interlaced_format); 8264 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); 8265 } 8266 if (client_extradata & OMX_FRAMEINFO_EXTRADATA && p_extra && 8267 ((OMX_U8*)p_extra + OMX_FRAMEINFO_EXTRADATA_SIZE) < 8268 (pBuffer + p_buf_hdr->nAllocLen)) 8269 { 8270 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA; 8271 /* vui extra data (frame_rate) information */ 8272 if (h264_parser) 8273 h264_parser->get_frame_rate(&frame_rate); 8274 append_frame_info_extradata(p_extra, num_conceal_MB, 8275 ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, 8276 p_buf_hdr->nTimeStamp, frame_rate, 8277 &((struct vdec_output_frameinfo *) 8278 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info); 8279 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); 8280 } 8281 if ((client_extradata & OMX_PORTDEF_EXTRADATA) && 8282 p_extra != NULL && 8283 ((OMX_U8*)p_extra + OMX_PORTDEF_EXTRADATA_SIZE) < 8284 (pBuffer + p_buf_hdr->nAllocLen)) 8285 { 8286 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA; 8287 append_portdef_extradata(p_extra); 8288 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); 8289 } 8290 if (p_buf_hdr->nFlags & OMX_BUFFERFLAG_EXTRADATA) 8291 if (p_extra && 8292 ((OMX_U8*)p_extra + OMX_FRAMEINFO_EXTRADATA_SIZE) < 8293 (pBuffer + p_buf_hdr->nAllocLen)) 8294 append_terminator_extradata(p_extra); 8295 else 8296 { 8297 DEBUG_PRINT_ERROR("ERROR: Terminator extradata cannot be added"); 8298 p_buf_hdr->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA; 8299 } 8300 } 8301 8302 OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U32 requested_extradata, bool enable) 8303 { 8304 OMX_ERRORTYPE ret = OMX_ErrorNone; 8305 OMX_U32 driver_extradata = 0, extradata_size = 0; 8306 struct vdec_ioctl_msg ioctl_msg = {NULL, NULL}; 8307 if(m_state != OMX_StateLoaded) 8308 { 8309 DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only"); 8310 return OMX_ErrorIncorrectStateOperation; 8311 } 8312 if (requested_extradata & OMX_FRAMEINFO_EXTRADATA) 8313 extradata_size += OMX_FRAMEINFO_EXTRADATA_SIZE; 8314 if (requested_extradata & OMX_INTERLACE_EXTRADATA) 8315 extradata_size += OMX_INTERLACE_EXTRADATA_SIZE; 8316 if (requested_extradata & OMX_PORTDEF_EXTRADATA) 8317 { 8318 extradata_size += OMX_PORTDEF_EXTRADATA_SIZE; 8319 } 8320 DEBUG_PRINT_ERROR("enable_extradata: actual[%x] requested[%x] enable[%d]", 8321 client_extradata, requested_extradata, enable); 8322 8323 if (enable) 8324 requested_extradata |= client_extradata; 8325 else 8326 { 8327 requested_extradata = client_extradata & ~requested_extradata; 8328 extradata_size *= -1; 8329 } 8330 8331 driver_extradata = requested_extradata & DRIVER_EXTRADATA_MASK; 8332 if (requested_extradata & OMX_FRAMEINFO_EXTRADATA) 8333 driver_extradata |= VDEC_EXTRADATA_MB_ERROR_MAP; // Required for conceal MB frame info 8334 #ifdef PROCESS_EXTRADATA_IN_OUTPUT_PORT 8335 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) 8336 { 8337 driver_extradata |= ((requested_extradata & OMX_FRAMEINFO_EXTRADATA)? 8338 VDEC_EXTRADATA_SEI : 0); // Required for pan scan frame info 8339 driver_extradata |= ((requested_extradata & OMX_TIMEINFO_EXTRADATA)? 8340 VDEC_EXTRADATA_VUI | VDEC_EXTRADATA_SEI : 0); //Required for time info 8341 } 8342 8343 #endif 8344 if (driver_extradata != drv_ctx.extradata) 8345 { 8346 client_extradata = requested_extradata; 8347 drv_ctx.extradata = driver_extradata; 8348 ioctl_msg.in = &drv_ctx.extradata; 8349 ioctl_msg.out = NULL; 8350 if (ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_SET_EXTRADATA, 8351 (void*)&ioctl_msg) < 0) 8352 { 8353 DEBUG_PRINT_ERROR("\nSet extradata failed"); 8354 ret = OMX_ErrorUnsupportedSetting; 8355 } 8356 else 8357 ret = get_buffer_req(&drv_ctx.op_buf); 8358 } 8359 else if ((client_extradata & ~DRIVER_EXTRADATA_MASK) != (requested_extradata & ~DRIVER_EXTRADATA_MASK)) 8360 { 8361 client_extradata = requested_extradata; 8362 drv_ctx.op_buf.buffer_size += extradata_size; 8363 // align the buffer size 8364 drv_ctx.op_buf.buffer_size = (drv_ctx.op_buf.buffer_size + drv_ctx.op_buf.alignment - 1)&(~(drv_ctx.op_buf.alignment - 1)); 8365 DEBUG_PRINT_LOW("Aligned buffer size with exreadata = %d\n", drv_ctx.op_buf.buffer_size); 8366 if (!(client_extradata & ~DRIVER_EXTRADATA_MASK)) // If no omx extradata is required remove space for terminator 8367 drv_ctx.op_buf.buffer_size -= sizeof(OMX_OTHER_EXTRADATATYPE); 8368 ret = set_buffer_req(&drv_ctx.op_buf); 8369 } 8370 return ret; 8371 } 8372 8373 OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra) 8374 { 8375 OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0; 8376 OMX_U8 *data_ptr = extra->data, data = 0; 8377 while (byte_count < extra->nDataSize) 8378 { 8379 data = *data_ptr; 8380 while (data) 8381 { 8382 num_MB += (data&0x01); 8383 data >>= 1; 8384 } 8385 data_ptr++; 8386 byte_count++; 8387 } 8388 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) * 8389 (drv_ctx.video_resolution.frame_height + 15)) >> 8; 8390 return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0); 8391 } 8392 8393 void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra) 8394 { 8395 #ifdef _ANDROID_ 8396 if (!m_debug_extradata) 8397 return; 8398 8399 DEBUG_PRINT_HIGH( 8400 "============== Extra Data ==============\n" 8401 " Size: %u \n" 8402 " Version: %u \n" 8403 " PortIndex: %u \n" 8404 " Type: %x \n" 8405 " DataSize: %u \n", 8406 extra->nSize, extra->nVersion.nVersion, 8407 extra->nPortIndex, extra->eType, extra->nDataSize); 8408 8409 if (extra->eType == OMX_ExtraDataInterlaceFormat) 8410 { 8411 OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)extra->data; 8412 DEBUG_PRINT_HIGH( 8413 "------ Interlace Format ------\n" 8414 " Size: %u \n" 8415 " Version: %u \n" 8416 " PortIndex: %u \n" 8417 " Is Interlace Format: %u \n" 8418 " Interlace Formats: %u \n" 8419 "=========== End of Interlace ===========\n", 8420 intfmt->nSize, intfmt->nVersion.nVersion, intfmt->nPortIndex, 8421 intfmt->bInterlaceFormat, intfmt->nInterlaceFormats); 8422 } 8423 else if (extra->eType == OMX_ExtraDataFrameInfo) 8424 { 8425 OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data; 8426 8427 DEBUG_PRINT_HIGH( 8428 "-------- Frame Format --------\n" 8429 " Picture Type: %u \n" 8430 " Interlace Type: %u \n" 8431 " Pan Scan Total Frame Num: %u \n" 8432 " Concealed Macro Blocks: %u \n" 8433 " frame rate: %u \n" 8434 " Aspect Ratio X: %u \n" 8435 " Aspect Ratio Y: %u \n", 8436 fminfo->ePicType, 8437 fminfo->interlaceType, 8438 fminfo->panScan.numWindows, 8439 fminfo->nConcealedMacroblocks, 8440 fminfo->nFrameRate, 8441 fminfo->aspectRatio.aspectRatioX, 8442 fminfo->aspectRatio.aspectRatioY); 8443 8444 for (int i = 0; i < fminfo->panScan.numWindows; i++) 8445 { 8446 DEBUG_PRINT_HIGH( 8447 "------------------------------\n" 8448 " Pan Scan Frame Num: %d \n" 8449 " Rectangle x: %d \n" 8450 " Rectangle y: %d \n" 8451 " Rectangle dx: %d \n" 8452 " Rectangle dy: %d \n", 8453 i, fminfo->panScan.window[i].x, fminfo->panScan.window[i].y, 8454 fminfo->panScan.window[i].dx, fminfo->panScan.window[i].dy); 8455 } 8456 8457 DEBUG_PRINT_HIGH("========= End of Frame Format =========="); 8458 } 8459 else if (extra->eType == OMX_ExtraDataNone) 8460 { 8461 DEBUG_PRINT_HIGH("========== End of Terminator ==========="); 8462 } 8463 else 8464 { 8465 DEBUG_PRINT_HIGH("======= End of Driver Extradata ========"); 8466 } 8467 #endif /* _ANDROID_ */ 8468 } 8469 8470 void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra, 8471 OMX_U32 interlaced_format_type) 8472 { 8473 OMX_STREAMINTERLACEFORMAT *interlace_format; 8474 OMX_U32 mbaff = 0; 8475 extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE; 8476 extra->nVersion.nVersion = OMX_SPEC_VERSION; 8477 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 8478 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat; 8479 extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT); 8480 interlace_format = (OMX_STREAMINTERLACEFORMAT *)extra->data; 8481 interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT); 8482 interlace_format->nVersion.nVersion = OMX_SPEC_VERSION; 8483 interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 8484 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false; 8485 if ((interlaced_format_type == VDEC_InterlaceFrameProgressive) && !mbaff) 8486 { 8487 interlace_format->bInterlaceFormat = OMX_FALSE; 8488 interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive; 8489 drv_ctx.interlace = VDEC_InterlaceFrameProgressive; 8490 } 8491 else 8492 { 8493 interlace_format->bInterlaceFormat = OMX_TRUE; 8494 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst; 8495 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst; 8496 } 8497 print_debug_extradata(extra); 8498 } 8499 8500 void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra, 8501 OMX_U32 num_conceal_mb, OMX_U32 picture_type, OMX_S64 timestamp, 8502 OMX_U32 frame_rate, struct vdec_aspectratioinfo *aspect_ratio_info) 8503 { 8504 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL; 8505 extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE; 8506 extra->nVersion.nVersion = OMX_SPEC_VERSION; 8507 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 8508 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo; 8509 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO); 8510 frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data; 8511 8512 switch (picture_type) 8513 { 8514 case PICTURE_TYPE_I: 8515 frame_info->ePicType = OMX_VIDEO_PictureTypeI; 8516 break; 8517 case PICTURE_TYPE_P: 8518 frame_info->ePicType = OMX_VIDEO_PictureTypeP; 8519 break; 8520 case PICTURE_TYPE_B: 8521 frame_info->ePicType = OMX_VIDEO_PictureTypeB; 8522 break; 8523 default: 8524 frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0; 8525 } 8526 if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst) 8527 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst; 8528 else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst) 8529 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst; 8530 else 8531 frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive; 8532 memset(&frame_info->panScan,0,sizeof(frame_info->panScan)); 8533 memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio)); 8534 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) 8535 { 8536 h264_parser->fill_pan_scan_data(&frame_info->panScan, timestamp); 8537 } 8538 8539 fill_aspect_ratio_info(aspect_ratio_info, frame_info); 8540 frame_info->nConcealedMacroblocks = num_conceal_mb; 8541 frame_info->nFrameRate = frame_rate; 8542 print_debug_extradata(extra); 8543 } 8544 8545 void omx_vdec::fill_aspect_ratio_info( 8546 struct vdec_aspectratioinfo *aspect_ratio_info, 8547 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info) 8548 { 8549 m_extradata = frame_info; 8550 8551 m_extradata->aspectRatio.aspectRatioX = 0; 8552 m_extradata->aspectRatio.aspectRatioY = 0; 8553 8554 if(drv_ctx.decoder_format == VDEC_CODECTYPE_H264) 8555 { 8556 h264_parser->fill_aspect_ratio_info(&m_extradata->aspectRatio); 8557 } 8558 #ifdef MAX_RES_1080P 8559 else if(drv_ctx.decoder_format == VDEC_CODECTYPE_MPEG4 || 8560 drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_3 || 8561 drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_4 || 8562 drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_5 || 8563 drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_6) 8564 { 8565 mp4_fill_aspect_ratio_info(aspect_ratio_info,m_extradata); 8566 } 8567 #endif 8568 if(m_extradata->aspectRatio.aspectRatioX == 0 || 8569 m_extradata->aspectRatio.aspectRatioY == 0) { 8570 m_extradata->aspectRatio.aspectRatioX = 1; 8571 m_extradata->aspectRatio.aspectRatioY = 1; 8572 } 8573 } 8574 8575 void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra) 8576 { 8577 OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL; 8578 extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE; 8579 extra->nVersion.nVersion = OMX_SPEC_VERSION; 8580 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 8581 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef; 8582 extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); 8583 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)extra->data; 8584 *portDefn = m_port_def; 8585 DEBUG_PRINT_LOW("append_portdef_extradata height = %u width = %u stride = %u" 8586 "sliceheight = %u \n",portDefn->format.video.nFrameHeight, 8587 portDefn->format.video.nFrameWidth, 8588 portDefn->format.video.nStride, 8589 portDefn->format.video.nSliceHeight); 8590 } 8591 8592 void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra) 8593 { 8594 extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE); 8595 extra->nVersion.nVersion = OMX_SPEC_VERSION; 8596 extra->eType = OMX_ExtraDataNone; 8597 extra->nDataSize = 0; 8598 extra->data[0] = 0; 8599 8600 print_debug_extradata(extra); 8601 } 8602 8603 OMX_ERRORTYPE omx_vdec::allocate_desc_buffer(OMX_U32 index) 8604 { 8605 OMX_ERRORTYPE eRet = OMX_ErrorNone; 8606 if (index >= drv_ctx.ip_buf.actualcount) 8607 { 8608 DEBUG_PRINT_ERROR("\nERROR:Desc Buffer Index not found"); 8609 return OMX_ErrorInsufficientResources; 8610 } 8611 if (m_desc_buffer_ptr == NULL) 8612 { 8613 m_desc_buffer_ptr = (desc_buffer_hdr*) \ 8614 calloc( (sizeof(desc_buffer_hdr)), 8615 drv_ctx.ip_buf.actualcount); 8616 if (m_desc_buffer_ptr == NULL) 8617 { 8618 DEBUG_PRINT_ERROR("\n m_desc_buffer_ptr Allocation failed "); 8619 return OMX_ErrorInsufficientResources; 8620 } 8621 } 8622 8623 m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8)); 8624 if (m_desc_buffer_ptr[index].buf_addr == NULL) 8625 { 8626 DEBUG_PRINT_ERROR("\ndesc buffer Allocation failed "); 8627 return OMX_ErrorInsufficientResources; 8628 } 8629 8630 return eRet; 8631 } 8632 8633 void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset) 8634 { 8635 DEBUG_PRINT_LOW("Inserting address offset (%d) at idx (%d)", address_offset,m_demux_entries); 8636 if (m_demux_entries < 8192) 8637 { 8638 m_demux_offsets[m_demux_entries++] = address_offset; 8639 } 8640 return; 8641 } 8642 8643 void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr) 8644 { 8645 OMX_U32 bytes_to_parse = buf_hdr->nFilledLen; 8646 OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset; 8647 OMX_U32 index = 0; 8648 8649 m_demux_entries = 0; 8650 8651 while (index < bytes_to_parse) 8652 { 8653 if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) && 8654 (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) || 8655 ((buf[index] == 0x00) && (buf[index+1] == 0x00) && 8656 (buf[index+2] == 0x01)) ) 8657 { 8658 //Found start code, insert address offset 8659 insert_demux_addr_offset(index); 8660 if (buf[index+2] == 0x01) // 3 byte start code 8661 index += 3; 8662 else //4 byte start code 8663 index += 4; 8664 } 8665 else 8666 index++; 8667 } 8668 DEBUG_PRINT_LOW("Extracted (%d) demux entry offsets",m_demux_entries); 8669 return; 8670 } 8671 8672 OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr) 8673 { 8674 //fix this, handle 3 byte start code, vc1 terminator entry 8675 OMX_U8 *p_demux_data = NULL; 8676 OMX_U32 desc_data = 0; 8677 OMX_U32 start_addr = 0; 8678 OMX_U32 nal_size = 0; 8679 OMX_U32 suffix_byte = 0; 8680 OMX_U32 demux_index = 0; 8681 OMX_U32 buffer_index = 0; 8682 8683 if (m_desc_buffer_ptr == NULL) 8684 { 8685 DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries."); 8686 return OMX_ErrorBadParameter; 8687 } 8688 8689 buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr); 8690 if (buffer_index > drv_ctx.ip_buf.actualcount) 8691 { 8692 DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%d)", buffer_index); 8693 return OMX_ErrorBadParameter; 8694 } 8695 8696 p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr; 8697 8698 if ( ((OMX_U8*)p_demux_data == NULL) || 8699 ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE) 8700 { 8701 DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries."); 8702 return OMX_ErrorBadParameter; 8703 } 8704 else 8705 { 8706 for (; demux_index < m_demux_entries; demux_index++) 8707 { 8708 desc_data = 0; 8709 start_addr = m_demux_offsets[demux_index]; 8710 if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01) 8711 { 8712 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3]; 8713 } 8714 else 8715 { 8716 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4]; 8717 } 8718 if (demux_index < (m_demux_entries - 1)) 8719 { 8720 nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2; 8721 } 8722 else 8723 { 8724 nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2; 8725 } 8726 DEBUG_PRINT_LOW("Start_addr(%p), suffix_byte(0x%x),nal_size(%d),demux_index(%d)", 8727 start_addr, 8728 suffix_byte, 8729 nal_size, 8730 demux_index); 8731 desc_data = (start_addr >> 3) << 1; 8732 desc_data |= (start_addr & 7) << 21; 8733 desc_data |= suffix_byte << 24; 8734 8735 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32)); 8736 memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32)); 8737 memset(p_demux_data + 8, 0, sizeof(OMX_U32)); 8738 memset(p_demux_data + 12, 0, sizeof(OMX_U32)); 8739 8740 p_demux_data += 16; 8741 } 8742 if (codec_type_parse == CODEC_TYPE_VC1) 8743 { 8744 DEBUG_PRINT_LOW("VC1 terminator entry"); 8745 desc_data = 0; 8746 desc_data = 0x82 << 24; 8747 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32)); 8748 memset(p_demux_data + 4, 0, sizeof(OMX_U32)); 8749 memset(p_demux_data + 8, 0, sizeof(OMX_U32)); 8750 memset(p_demux_data + 12, 0, sizeof(OMX_U32)); 8751 p_demux_data += 16; 8752 m_demux_entries++; 8753 } 8754 //Add zero word to indicate end of descriptors 8755 memset(p_demux_data, 0, sizeof(OMX_U32)); 8756 8757 m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32); 8758 DEBUG_PRINT_LOW("desc table data size=%d", m_desc_buffer_ptr[buffer_index].desc_data_size); 8759 } 8760 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) ); 8761 m_demux_entries = 0; 8762 DEBUG_PRINT_LOW("Demux table complete!"); 8763 return OMX_ErrorNone; 8764 } 8765 8766 #ifdef MAX_RES_1080P 8767 OMX_ERRORTYPE omx_vdec::vdec_alloc_h264_mv() 8768 { 8769 OMX_U32 pmem_fd = -1; 8770 OMX_U32 width, height, size, alignment; 8771 void *buf_addr = NULL; 8772 struct vdec_ioctl_msg ioctl_msg; 8773 #ifndef USE_ION 8774 struct pmem_allocation allocation; 8775 #endif 8776 struct vdec_h264_mv h264_mv; 8777 struct vdec_mv_buff_size mv_buff_size; 8778 8779 mv_buff_size.width = drv_ctx.video_resolution.stride; 8780 mv_buff_size.height = drv_ctx.video_resolution.scan_lines>>2; 8781 8782 ioctl_msg.in = NULL; 8783 ioctl_msg.out = (void*)&mv_buff_size; 8784 8785 if (ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_GET_MV_BUFFER_SIZE, (void*)&ioctl_msg) < 0) 8786 { 8787 DEBUG_PRINT_ERROR("\n GET_MV_BUFFER_SIZE Failed for width: %d, Height %d" , 8788 mv_buff_size.width, mv_buff_size.height); 8789 return OMX_ErrorInsufficientResources; 8790 } 8791 8792 DEBUG_PRINT_ERROR("GET_MV_BUFFER_SIZE returned: Size: %d and alignment: %d", 8793 mv_buff_size.size, mv_buff_size.alignment); 8794 8795 size = mv_buff_size.size * drv_ctx.op_buf.actualcount; 8796 alignment = mv_buff_size.alignment; 8797 8798 DEBUG_PRINT_LOW("Entered vdec_alloc_h264_mv act_width: %d, act_height: %d, size: %d, alignment %d\n", 8799 drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height,size,alignment); 8800 8801 8802 #ifdef USE_ION 8803 drv_ctx.h264_mv.ion_device_fd = alloc_map_ion_memory( 8804 size, 8192, 8805 &drv_ctx.h264_mv.ion_alloc_data, 8806 &drv_ctx.h264_mv.fd_ion_data,ION_FLAG_CACHED); 8807 if (drv_ctx.h264_mv.ion_device_fd < 0) { 8808 return OMX_ErrorInsufficientResources; 8809 } 8810 pmem_fd = drv_ctx.h264_mv.fd_ion_data.fd; 8811 #else 8812 allocation.size = size; 8813 allocation.align = clip2(alignment); 8814 if (allocation.align != 8192) 8815 allocation.align = 8192; 8816 8817 pmem_fd = open(MEM_DEVICE, O_RDWR); 8818 8819 if ((int)(pmem_fd) < 0) 8820 return OMX_ErrorInsufficientResources; 8821 8822 if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) 8823 { 8824 DEBUG_PRINT_ERROR("\n Aligment(%u) failed with pmem driver Sz(%lu)", 8825 allocation.align, allocation.size); 8826 return OMX_ErrorInsufficientResources; 8827 } 8828 #endif 8829 if(!secure_mode) { 8830 buf_addr = mmap(NULL, size, 8831 PROT_READ | PROT_WRITE, 8832 MAP_SHARED, pmem_fd, 0); 8833 8834 if (buf_addr == (void*) MAP_FAILED) 8835 { 8836 close(pmem_fd); 8837 #ifdef USE_ION 8838 free_ion_memory(&drv_ctx.h264_mv); 8839 #endif 8840 pmem_fd = -1; 8841 DEBUG_PRINT_ERROR("Error returned in allocating recon buffers buf_addr: %p\n",buf_addr); 8842 return OMX_ErrorInsufficientResources; 8843 } 8844 } else 8845 buf_addr =(unsigned char *) (pmem_fd + 1234); 8846 DEBUG_PRINT_LOW("\n Allocated virt:%p, FD: %d of size %d count: %d \n", buf_addr, 8847 pmem_fd, size, drv_ctx.op_buf.actualcount); 8848 8849 h264_mv.size = size; 8850 h264_mv.count = drv_ctx.op_buf.actualcount; 8851 h264_mv.pmem_fd = pmem_fd; 8852 h264_mv.offset = 0; 8853 8854 ioctl_msg.in = (void*)&h264_mv; 8855 ioctl_msg.out = NULL; 8856 8857 if (ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_SET_H264_MV_BUFFER, (void*)&ioctl_msg) < 0) 8858 { 8859 DEBUG_PRINT_ERROR("Failed to set the H264_mv_buffers\n"); 8860 return OMX_ErrorInsufficientResources; 8861 } 8862 8863 h264_mv_buff.buffer = (unsigned char *) buf_addr; 8864 h264_mv_buff.size = size; 8865 h264_mv_buff.count = drv_ctx.op_buf.actualcount; 8866 h264_mv_buff.offset = 0; 8867 h264_mv_buff.pmem_fd = pmem_fd; 8868 DEBUG_PRINT_LOW("\n Saving virt:%p, FD: %d of size %d count: %d \n", h264_mv_buff.buffer, 8869 h264_mv_buff.pmem_fd, h264_mv_buff.size, drv_ctx.op_buf.actualcount); 8870 return OMX_ErrorNone; 8871 } 8872 8873 void omx_vdec::vdec_dealloc_h264_mv() 8874 { 8875 if(h264_mv_buff.pmem_fd > 0) 8876 { 8877 if(ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_FREE_H264_MV_BUFFER,NULL) < 0) 8878 DEBUG_PRINT_ERROR("VDEC_IOCTL_FREE_H264_MV_BUFFER failed"); 8879 if(!secure_mode) 8880 munmap(h264_mv_buff.buffer, h264_mv_buff.size); 8881 close(h264_mv_buff.pmem_fd); 8882 #ifdef USE_ION 8883 free_ion_memory(&drv_ctx.h264_mv); 8884 #endif 8885 DEBUG_PRINT_LOW("\n Cleaning H264_MV buffer of size %d \n",h264_mv_buff.size); 8886 h264_mv_buff.pmem_fd = -1; 8887 h264_mv_buff.offset = 0; 8888 h264_mv_buff.size = 0; 8889 h264_mv_buff.count = 0; 8890 h264_mv_buff.buffer = NULL; 8891 } 8892 } 8893 8894 #endif 8895 8896 #ifdef _ANDROID_ 8897 OMX_ERRORTYPE omx_vdec::createDivxDrmContext() 8898 { 8899 OMX_ERRORTYPE err = OMX_ErrorNone; 8900 iDivXDrmDecrypt = DivXDrmDecrypt::Create(); 8901 if (iDivXDrmDecrypt) { 8902 OMX_ERRORTYPE err = iDivXDrmDecrypt->Init(); 8903 if(err!=OMX_ErrorNone) { 8904 DEBUG_PRINT_ERROR("\nERROR :iDivXDrmDecrypt->Init %d", err); 8905 delete iDivXDrmDecrypt; 8906 iDivXDrmDecrypt = NULL; 8907 } 8908 } 8909 else { 8910 DEBUG_PRINT_ERROR("\nUnable to Create DIVX DRM"); 8911 err = OMX_ErrorUndefined; 8912 } 8913 return err; 8914 } 8915 #endif //_ANDROID_ 8916 8917 omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf() 8918 { 8919 enabled = false; 8920 omx = NULL; 8921 init_members(); 8922 ColorFormat = OMX_COLOR_FormatMax; 8923 } 8924 8925 void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client) 8926 { 8927 omx = reinterpret_cast<omx_vdec*>(client); 8928 } 8929 8930 void omx_vdec::allocate_color_convert_buf::init_members() { 8931 allocated_count = 0; 8932 buffer_size_req = 0; 8933 buffer_alignment_req = 0; 8934 memset(m_platform_list_client,0,sizeof(m_platform_list_client)); 8935 memset(m_platform_entry_client,0,sizeof(m_platform_entry_client)); 8936 memset(m_pmem_info_client,0,sizeof(m_pmem_info_client)); 8937 memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client)); 8938 memset(op_buf_ion_info,0,sizeof(m_platform_entry_client)); 8939 for (int i = 0; i < MAX_COUNT;i++) 8940 pmem_fd[i] = -1; 8941 } 8942 8943 omx_vdec::allocate_color_convert_buf::~allocate_color_convert_buf() { 8944 c2d.destroy(); 8945 } 8946 8947 bool omx_vdec::allocate_color_convert_buf::update_buffer_req() 8948 { 8949 bool status = true; 8950 unsigned int src_size = 0, destination_size = 0; 8951 OMX_COLOR_FORMATTYPE drv_color_format; 8952 if (!omx){ 8953 DEBUG_PRINT_ERROR("\n Invalid client in color convert"); 8954 return false; 8955 } 8956 if (!enabled){ 8957 DEBUG_PRINT_ERROR("\n No color conversion required"); 8958 return status; 8959 } 8960 if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_TILE_4x2 && 8961 ColorFormat != OMX_COLOR_FormatYUV420Planar) { 8962 DEBUG_PRINT_ERROR("\nupdate_buffer_req: Unsupported color conversion"); 8963 return false; 8964 } 8965 c2d.close(); 8966 status = c2d.open(omx->drv_ctx.video_resolution.frame_height, 8967 omx->drv_ctx.video_resolution.frame_width, 8968 YCbCr420Tile,YCbCr420P); 8969 if (status) { 8970 status = c2d.get_buffer_size(C2D_INPUT,src_size); 8971 if (status) 8972 status = c2d.get_buffer_size(C2D_OUTPUT,destination_size); 8973 } 8974 if (status) { 8975 if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size || 8976 !destination_size) { 8977 DEBUG_PRINT_ERROR("\nERROR: Size mismatch in C2D src_size %d" 8978 "driver size %d destination size %d", 8979 src_size,omx->drv_ctx.op_buf.buffer_size,destination_size); 8980 status = false; 8981 c2d.close(); 8982 buffer_size_req = 0; 8983 } else { 8984 buffer_size_req = destination_size; 8985 if (buffer_size_req < omx->drv_ctx.op_buf.buffer_size) 8986 buffer_size_req = omx->drv_ctx.op_buf.buffer_size; 8987 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment) 8988 buffer_alignment_req = omx->drv_ctx.op_buf.alignment; 8989 } 8990 } 8991 return status; 8992 } 8993 8994 bool omx_vdec::allocate_color_convert_buf::set_color_format( 8995 OMX_COLOR_FORMATTYPE dest_color_format) 8996 { 8997 bool status = true; 8998 OMX_COLOR_FORMATTYPE drv_color_format; 8999 if (!omx){ 9000 DEBUG_PRINT_ERROR("\n Invalid client in color convert"); 9001 return false; 9002 } 9003 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_TILE_4x2) 9004 drv_color_format = (OMX_COLOR_FORMATTYPE) 9005 QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka; 9006 else { 9007 DEBUG_PRINT_ERROR("\n Incorrect color format"); 9008 status = false; 9009 } 9010 if (status && (drv_color_format != dest_color_format)) { 9011 if (dest_color_format != OMX_COLOR_FormatYUV420Planar) { 9012 DEBUG_PRINT_ERROR("\n Unsupported color format for c2d"); 9013 status = false; 9014 } else { 9015 DEBUG_PRINT_HIGH("\n Planar color format set"); 9016 ColorFormat = OMX_COLOR_FormatYUV420Planar; 9017 if (enabled) 9018 c2d.destroy(); 9019 enabled = false; 9020 if (!c2d.init()) { 9021 DEBUG_PRINT_ERROR("\n open failed for c2d"); 9022 status = false; 9023 } else 9024 enabled = true; 9025 } 9026 } else { 9027 if (enabled) 9028 c2d.destroy(); 9029 enabled = false; 9030 } 9031 return status; 9032 } 9033 9034 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr() 9035 { 9036 if (!omx){ 9037 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr"); 9038 return NULL; 9039 } 9040 if (!enabled) 9041 return omx->m_out_mem_ptr; 9042 return m_out_mem_ptr_client; 9043 } 9044 9045 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr 9046 (OMX_BUFFERHEADERTYPE *bufadd) 9047 { 9048 if (!omx){ 9049 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr"); 9050 return NULL; 9051 } 9052 if (!enabled) 9053 return bufadd; 9054 unsigned index = 0; 9055 index = bufadd - omx->m_out_mem_ptr; 9056 if (index < omx->drv_ctx.op_buf.actualcount) { 9057 m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS); 9058 m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp; 9059 bool status; 9060 if (!omx->in_reconfig && !omx->output_flush_progress) { 9061 status = c2d.convert(omx->drv_ctx.ptr_outputbuffer[index].pmem_fd, 9062 bufadd->pBuffer,pmem_fd[index],pmem_baseaddress[index]); 9063 m_out_mem_ptr_client[index].nFilledLen = buffer_size_req; 9064 if (!status){ 9065 DEBUG_PRINT_ERROR("\n Failed color conversion %d", status); 9066 return NULL; 9067 } 9068 } else 9069 m_out_mem_ptr_client[index].nFilledLen = 0; 9070 return &m_out_mem_ptr_client[index]; 9071 } 9072 DEBUG_PRINT_ERROR("\n Index messed up in the get_il_buf_hdr"); 9073 return NULL; 9074 } 9075 9076 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_dr_buf_hdr 9077 (OMX_BUFFERHEADERTYPE *bufadd) 9078 { 9079 if (!omx){ 9080 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr"); 9081 return NULL; 9082 } 9083 if (!enabled) 9084 return bufadd; 9085 unsigned index = 0; 9086 index = bufadd - m_out_mem_ptr_client; 9087 if (index < omx->drv_ctx.op_buf.actualcount) { 9088 return &omx->m_out_mem_ptr[index]; 9089 } 9090 DEBUG_PRINT_ERROR("\n Index messed up in the get_dr_buf_hdr"); 9091 return NULL; 9092 } 9093 bool omx_vdec::allocate_color_convert_buf::get_buffer_req 9094 (unsigned int &buffer_size) 9095 { 9096 if (!enabled) 9097 buffer_size = omx->drv_ctx.op_buf.buffer_size; 9098 else 9099 if (!c2d.get_buffer_size(C2D_OUTPUT,buffer_size)) { 9100 DEBUG_PRINT_ERROR("\n Get buffer size failed"); 9101 return false; 9102 } 9103 if (buffer_size < omx->drv_ctx.op_buf.buffer_size) 9104 buffer_size = omx->drv_ctx.op_buf.buffer_size; 9105 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment) 9106 buffer_alignment_req = omx->drv_ctx.op_buf.alignment; 9107 return true; 9108 } 9109 OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer( 9110 OMX_BUFFERHEADERTYPE *bufhdr) { 9111 unsigned int index = 0; 9112 9113 if (!enabled) 9114 return omx->free_output_buffer(bufhdr); 9115 if (enabled && omx->is_component_secure()) 9116 return OMX_ErrorNone; 9117 if (!allocated_count || !bufhdr) { 9118 DEBUG_PRINT_ERROR("\n Color convert no buffer to be freed %p",bufhdr); 9119 return OMX_ErrorBadParameter; 9120 } 9121 index = bufhdr - m_out_mem_ptr_client; 9122 if (index >= omx->drv_ctx.op_buf.actualcount){ 9123 DEBUG_PRINT_ERROR("\n Incorrect index color convert free_output_buffer"); 9124 return OMX_ErrorBadParameter; 9125 } 9126 if (pmem_fd[index] > 0) { 9127 munmap(pmem_baseaddress[index], buffer_size_req); 9128 close(pmem_fd[index]); 9129 } 9130 pmem_fd[index] = -1; 9131 omx->free_ion_memory(&op_buf_ion_info[index]); 9132 m_heap_ptr[index].video_heap_ptr = NULL; 9133 if (allocated_count > 0) 9134 allocated_count--; 9135 else 9136 allocated_count = 0; 9137 if (!allocated_count) { 9138 c2d.close(); 9139 init_members(); 9140 } 9141 return omx->free_output_buffer(&omx->m_out_mem_ptr[index]); 9142 } 9143 9144 OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::allocate_buffers_color_convert(OMX_HANDLETYPE hComp, 9145 OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes) 9146 { 9147 OMX_ERRORTYPE eRet = OMX_ErrorNone; 9148 if (!enabled){ 9149 eRet = omx->allocate_output_buffer(hComp,bufferHdr,port,appData,bytes); 9150 return eRet; 9151 } 9152 if (enabled && omx->is_component_secure()) { 9153 DEBUG_PRINT_ERROR("\nNotin color convert mode secure_mode %d", 9154 omx->is_component_secure()); 9155 return OMX_ErrorUnsupportedSetting; 9156 } 9157 if (!bufferHdr || bytes > buffer_size_req) { 9158 DEBUG_PRINT_ERROR("\n Invalid params allocate_buffers_color_convert %p", bufferHdr); 9159 DEBUG_PRINT_ERROR("\n color_convert buffer_size_req %d bytes %d", 9160 buffer_size_req,bytes); 9161 return OMX_ErrorBadParameter; 9162 } 9163 if (allocated_count >= omx->drv_ctx.op_buf.actualcount) { 9164 DEBUG_PRINT_ERROR("\n Actual count err in allocate_buffers_color_convert"); 9165 return OMX_ErrorInsufficientResources; 9166 } 9167 OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL; 9168 eRet = omx->allocate_output_buffer(hComp,&temp_bufferHdr, 9169 port,appData,omx->drv_ctx.op_buf.buffer_size); 9170 if (eRet != OMX_ErrorNone || !temp_bufferHdr){ 9171 DEBUG_PRINT_ERROR("\n Buffer allocation failed color_convert"); 9172 return eRet; 9173 } 9174 if ((temp_bufferHdr - omx->m_out_mem_ptr) >= 9175 omx->drv_ctx.op_buf.actualcount) { 9176 DEBUG_PRINT_ERROR("\n Invalid header index %d", 9177 (temp_bufferHdr - omx->m_out_mem_ptr)); 9178 return OMX_ErrorUndefined; 9179 } 9180 unsigned int i = allocated_count; 9181 op_buf_ion_info[i].ion_device_fd = omx->alloc_map_ion_memory( 9182 buffer_size_req,buffer_alignment_req, 9183 &op_buf_ion_info[i].ion_alloc_data,&op_buf_ion_info[i].fd_ion_data, 9184 ION_FLAG_CACHED); 9185 9186 pmem_fd[i] = op_buf_ion_info[i].fd_ion_data.fd; 9187 if (op_buf_ion_info[i].ion_device_fd < 0) { 9188 DEBUG_PRINT_ERROR("\n alloc_map_ion failed in color_convert"); 9189 return OMX_ErrorInsufficientResources; 9190 } 9191 pmem_baseaddress[i] = (unsigned char *)mmap(NULL,buffer_size_req, 9192 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd[i],0); 9193 9194 if (pmem_baseaddress[i] == MAP_FAILED) { 9195 DEBUG_PRINT_ERROR("\n MMAP failed for Size %d",buffer_size_req); 9196 close(pmem_fd[i]); 9197 omx->free_ion_memory(&op_buf_ion_info[i]); 9198 return OMX_ErrorInsufficientResources; 9199 } 9200 m_heap_ptr[i].video_heap_ptr = new VideoHeap ( 9201 op_buf_ion_info[i].ion_device_fd,buffer_size_req, 9202 pmem_baseaddress[i],op_buf_ion_info[i].ion_alloc_data.handle,pmem_fd[i]); 9203 m_pmem_info_client[i].pmem_fd = (OMX_U32)m_heap_ptr[i].video_heap_ptr.get(); 9204 m_pmem_info_client[i].offset = 0; 9205 m_platform_entry_client[i].entry = (void *)&m_pmem_info_client[i]; 9206 m_platform_entry_client[i].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM; 9207 m_platform_list_client[i].nEntries = 1; 9208 m_platform_list_client[i].entryList = &m_platform_entry_client[i]; 9209 m_out_mem_ptr_client[i].pOutputPortPrivate = NULL; 9210 m_out_mem_ptr_client[i].nAllocLen = buffer_size_req; 9211 m_out_mem_ptr_client[i].nFilledLen = 0; 9212 m_out_mem_ptr_client[i].nFlags = 0; 9213 m_out_mem_ptr_client[i].nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 9214 m_out_mem_ptr_client[i].nSize = sizeof(OMX_BUFFERHEADERTYPE); 9215 m_out_mem_ptr_client[i].nVersion.nVersion = OMX_SPEC_VERSION; 9216 m_out_mem_ptr_client[i].pPlatformPrivate = &m_platform_list_client[i]; 9217 m_out_mem_ptr_client[i].pBuffer = pmem_baseaddress[i]; 9218 m_out_mem_ptr_client[i].pAppPrivate = appData; 9219 *bufferHdr = &m_out_mem_ptr_client[i]; 9220 DEBUG_PRINT_ERROR("\n IL client buffer header %p", *bufferHdr); 9221 allocated_count++; 9222 return eRet; 9223 } 9224 9225 bool omx_vdec::is_component_secure() 9226 { 9227 return secure_mode; 9228 } 9229 9230 bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format) 9231 { 9232 bool status = true; 9233 if (!enabled) { 9234 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_TILE_4x2) 9235 dest_color_format = (OMX_COLOR_FORMATTYPE) 9236 QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka; 9237 else if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) 9238 dest_color_format = OMX_COLOR_FormatYUV420SemiPlanar; 9239 else 9240 status = false; 9241 } else { 9242 if (ColorFormat != OMX_COLOR_FormatYUV420Planar) { 9243 status = false; 9244 } else 9245 dest_color_format = OMX_COLOR_FormatYUV420Planar; 9246 } 9247 return status; 9248 } 9249 9250 int omx_vdec::secureDisplay(int mode) { 9251 if (m_secure_display == true) { 9252 return 0; 9253 } 9254 9255 sp<IServiceManager> sm = defaultServiceManager(); 9256 sp<qService::IQService> displayBinder = 9257 interface_cast<qService::IQService>(sm->getService(String16("display.qservice"))); 9258 9259 if (displayBinder != NULL) { 9260 displayBinder->securing(mode); 9261 if (mode == qService::IQService::END) { 9262 m_secure_display = true; 9263 } 9264 } 9265 else { 9266 DEBUG_PRINT_ERROR("secureDisplay(%d) display.qservice unavailable", mode); 9267 } 9268 return 0; 9269 } 9270 9271 int omx_vdec::unsecureDisplay(int mode) { 9272 if (m_secure_display == false) { 9273 return 0; 9274 } 9275 9276 if (mode == qService::IQService::END) { 9277 m_secure_display = false; 9278 } 9279 9280 sp<IServiceManager> sm = defaultServiceManager(); 9281 sp<qService::IQService> displayBinder = 9282 interface_cast<qService::IQService>(sm->getService(String16("display.qservice"))); 9283 9284 if (displayBinder != NULL) 9285 displayBinder->unsecuring(mode); 9286 else 9287 DEBUG_PRINT_ERROR("unsecureDisplay(%d) display.qservice unavailable", mode); 9288 return 0; 9289 } 9290 9291 OMX_ERRORTYPE omx_vdec::update_color_format(OMX_COLOR_FORMATTYPE eColorFormat) 9292 { 9293 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; 9294 OMX_ERRORTYPE eRet = OMX_ErrorNone; 9295 enum vdec_output_fromat op_format; 9296 if(eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) 9297 op_format = VDEC_YUV_FORMAT_NV12; 9298 else if(eColorFormat == 9299 QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka || 9300 eColorFormat == OMX_COLOR_FormatYUV420Planar) 9301 op_format = VDEC_YUV_FORMAT_TILE_4x2; 9302 else 9303 eRet = OMX_ErrorBadParameter; 9304 9305 if(eRet == OMX_ErrorNone && drv_ctx.output_format != op_format) { 9306 /*Set the output format*/ 9307 drv_ctx.output_format = op_format; 9308 ioctl_msg.in = &drv_ctx.output_format; 9309 ioctl_msg.out = NULL; 9310 if (ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_SET_OUTPUT_FORMAT, 9311 (void*)&ioctl_msg) < 0) { 9312 DEBUG_PRINT_ERROR("\n Set output format failed for %u with err %s", 9313 eColorFormat, strerror(errno)); 9314 eRet = OMX_ErrorUnsupportedSetting; 9315 } 9316 else 9317 eRet = get_buffer_req(&drv_ctx.op_buf); 9318 } 9319 if (eRet == OMX_ErrorNone){ 9320 if (!client_buffers.set_color_format(eColorFormat)) { 9321 DEBUG_PRINT_ERROR("\n Set color format failed for %u", eColorFormat); 9322 eRet = OMX_ErrorBadParameter; 9323 } 9324 } 9325 if (!client_buffers.update_buffer_req()) { 9326 DEBUG_PRINT_ERROR("\n Update bufreq in color format failed for %u", eColorFormat); 9327 eRet = OMX_ErrorBadParameter; 9328 } 9329 return eRet; 9330 } 9331