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