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