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