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