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