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