1 /*-------------------------------------------------------------------------- 2 Copyright (c) 2010, 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 <stdlib.h> 45 #include <unistd.h> 46 #include <errno.h> 47 #include "omx_vdec.h" 48 #include <fcntl.h> 49 50 #define BITSTREAM_LOG 0 51 52 #if BITSTREAM_LOG 53 FILE *outputBufferFile1; 54 char filename [] = "/data/input-bitstream.m4v"; 55 #endif 56 57 #define H264_SUPPORTED_WIDTH (480) 58 #define H264_SUPPORTED_HEIGHT (368) 59 60 #define MPEG4_SUPPORTED_WIDTH (480) 61 #define MPEG4_SUPPORTED_HEIGHT (368) 62 63 #define VC1_SP_MP_START_CODE 0xC5000000 64 #define VC1_SP_MP_START_CODE_MASK 0xFF000000 65 #define VC1_AP_SEQ_START_CODE 0x0F010000 66 #define VC1_STRUCT_C_PROFILE_MASK 0xF0 67 #define VC1_STRUCT_B_LEVEL_MASK 0xE0000000 68 #define VC1_SIMPLE_PROFILE 0 69 #define VC1_MAIN_PROFILE 1 70 #define VC1_ADVANCE_PROFILE 3 71 #define VC1_SIMPLE_PROFILE_LOW_LEVEL 0 72 #define VC1_SIMPLE_PROFILE_MED_LEVEL 2 73 #define VC1_STRUCT_C_LEN 4 74 #define VC1_STRUCT_C_POS 8 75 #define VC1_STRUCT_A_POS 12 76 #define VC1_STRUCT_B_POS 24 77 #define VC1_SEQ_LAYER_SIZE 36 78 79 #ifdef _ANDROID_ 80 extern "C"{ 81 #include<utils/Log.h> 82 } 83 #endif//_ANDROID_ 84 85 #define DEBUG_PRINT(...) printf(__VA_ARGS__) 86 #define DEBUG_PRINT_ERROR(...) printf(__VA_ARGS__) 87 #define DEBUG_PRINT_LOW(...) printf(__VA_ARGS__) 88 89 90 void* async_message_thread (void *input) 91 { 92 struct vdec_ioctl_msg ioctl_msg; 93 struct vdec_msginfo vdec_msg; 94 omx_vdec *omx = reinterpret_cast<omx_vdec*>(input); 95 96 DEBUG_PRINT_HIGH("omx_vdec: Async thread start\n"); 97 while (1) 98 { 99 ioctl_msg.inputparam = NULL; 100 ioctl_msg.outputparam = (void*)&vdec_msg; 101 102 /*Wait for a message from the video decoder driver*/ 103 if (ioctl ( omx->driver_context.video_driver_fd,VDEC_IOCTL_GET_NEXT_MSG, 104 (void*)&ioctl_msg) < 0) 105 { 106 DEBUG_PRINT_ERROR("\n Error in ioctl read next msg"); 107 break; 108 } 109 else 110 { 111 /*Call Instance specific process function*/ 112 if (omx->async_message_process(input,&vdec_msg) < 0) 113 { 114 DEBUG_PRINT_ERROR("\nERROR:Wrong ioctl message"); 115 } 116 } 117 } 118 DEBUG_PRINT_HIGH("omx_vdec: Async thread stop\n"); 119 return NULL; 120 } 121 122 void* message_thread(void *input) 123 { 124 omx_vdec* omx = reinterpret_cast<omx_vdec*>(input); 125 unsigned char id; 126 int n; 127 128 DEBUG_PRINT_HIGH("omx_vdec: message thread start\n"); 129 while (1) 130 { 131 132 n = read(omx->m_pipe_in, &id, 1); 133 134 if(0 == n) 135 { 136 break; 137 } 138 139 if (1 == n) 140 { 141 omx->process_event_cb(omx, id); 142 } 143 if ((n < 0) && (errno != EINTR)) 144 { 145 DEBUG_PRINT_ERROR("\nERROR: read from pipe failed, ret %d errno %d", n, errno); 146 break; 147 } 148 } 149 DEBUG_PRINT_HIGH("omx_vdec: message thread stop\n"); 150 return 0; 151 } 152 153 void post_message(omx_vdec *omx, unsigned char id) 154 { 155 int ret_value; 156 DEBUG_PRINT_LOW("omx_vdec: post_message %d pipe out%d\n", id,omx->m_pipe_out); 157 ret_value = write(omx->m_pipe_out, &id, 1); 158 DEBUG_PRINT_LOW("post_message to pipe done %d\n",ret_value); 159 } 160 161 // omx_cmd_queue destructor 162 omx_vdec::omx_cmd_queue::~omx_cmd_queue() 163 { 164 // Nothing to do 165 } 166 167 // omx cmd queue constructor 168 omx_vdec::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0) 169 { 170 memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE); 171 } 172 173 // omx cmd queue insert 174 bool omx_vdec::omx_cmd_queue::insert_entry(unsigned p1, unsigned p2, unsigned id) 175 { 176 bool ret = true; 177 if(m_size < OMX_CORE_CONTROL_CMDQ_SIZE) 178 { 179 m_q[m_write].id = id; 180 m_q[m_write].param1 = p1; 181 m_q[m_write].param2 = p2; 182 m_write++; 183 m_size ++; 184 if(m_write >= OMX_CORE_CONTROL_CMDQ_SIZE) 185 { 186 m_write = 0; 187 } 188 } 189 else 190 { 191 ret = false; 192 DEBUG_PRINT_ERROR("ERROR: %s()::Command Queue Full\n", __func__); 193 } 194 return ret; 195 } 196 197 // omx cmd queue pop 198 bool omx_vdec::omx_cmd_queue::pop_entry(unsigned *p1, unsigned *p2, unsigned *id) 199 { 200 bool ret = true; 201 if (m_size > 0) 202 { 203 *id = m_q[m_read].id; 204 *p1 = m_q[m_read].param1; 205 *p2 = m_q[m_read].param2; 206 // Move the read pointer ahead 207 ++m_read; 208 --m_size; 209 if(m_read >= OMX_CORE_CONTROL_CMDQ_SIZE) 210 { 211 m_read = 0; 212 } 213 } 214 else 215 { 216 ret = false; 217 } 218 return ret; 219 } 220 221 // Retrieve the first mesg type in the queue 222 unsigned omx_vdec::omx_cmd_queue::get_q_msg_type() 223 { 224 return m_q[m_read].id; 225 } 226 227 // factory function executed by the core to create instances 228 void *get_omx_component_factory_fn(void) 229 { 230 return (new omx_vdec); 231 } 232 233 #ifdef _ANDROID_ 234 VideoHeap::VideoHeap(int fd, size_t size, void* base) 235 { 236 // dup file descriptor, map once, use pmem 237 init(dup(fd), base, size, 0 , "/dev/pmem_adsp"); 238 } 239 #endif // _ANDROID_ 240 241 /* ====================================================================== 242 FUNCTION 243 omx_vdec::omx_vdec 244 245 DESCRIPTION 246 Constructor 247 248 PARAMETERS 249 None 250 251 RETURN VALUE 252 None. 253 ========================================================================== */ 254 omx_vdec::omx_vdec(): m_state(OMX_StateInvalid), 255 m_app_data(NULL), 256 m_color_format(OMX_COLOR_FormatYUV420Planar), 257 m_inp_mem_ptr(NULL), 258 m_out_mem_ptr(NULL), 259 pending_input_buffers(0), 260 pending_output_buffers(0), 261 m_out_bm_count(0), 262 m_out_buf_count(0), 263 m_inp_buf_count(OMX_VIDEO_DEC_NUM_INPUT_BUFFERS), 264 m_inp_buf_size(OMX_VIDEO_DEC_INPUT_BUFFER_SIZE), 265 m_inp_bm_count(0), 266 m_inp_bPopulated(OMX_FALSE), 267 m_out_bPopulated(OMX_FALSE), 268 m_height(0), 269 m_width(0), 270 m_port_height(0), 271 m_port_width(0), 272 m_crop_x(0), 273 m_crop_y(0), 274 m_crop_dx(0), 275 m_crop_dy(0), 276 m_flags(0), 277 m_inp_bEnabled(OMX_TRUE), 278 m_out_bEnabled(OMX_TRUE), 279 m_event_port_settings_sent(false), 280 input_flush_progress (false), 281 output_flush_progress (false), 282 m_platform_list(NULL), 283 m_platform_entry(NULL), 284 m_pmem_info(NULL), 285 input_use_buffer (false), 286 output_use_buffer (false), 287 m_ineos_reached (0), 288 m_outeos_pending (0), 289 m_outeos_reached (0), 290 arbitrary_bytes (true), 291 psource_frame (NULL), 292 pdest_frame (NULL), 293 m_inp_heap_ptr (NULL), 294 m_heap_inp_bm_count (0), 295 codec_type_parse ((codec_type)0), 296 first_frame_meta (true), 297 frame_count (0), 298 nal_count (0), 299 nal_length(0), 300 look_ahead_nal (false), 301 first_frame(0), 302 first_buffer(NULL), 303 first_frame_size (0), 304 set_seq_header_done(false), 305 gate_output_buffers(true), 306 gate_input_buffers(false), 307 stride(0), 308 sent_first_frame(false), 309 m_error_propogated(false), 310 scan_lines(0), 311 m_device_file_ptr(NULL), 312 m_vc1_profile((vc1_profile_type)0) 313 { 314 /* Assumption is that , to begin with , we have all the frames with decoder */ 315 DEBUG_PRINT_HIGH("\n In OMX vdec Constuctor"); 316 memset(&m_cmp,0,sizeof(m_cmp)); 317 memset(&m_cb,0,sizeof(m_cb)); 318 memset (&driver_context,0,sizeof(driver_context)); 319 memset (&h264_scratch,0,sizeof (OMX_BUFFERHEADERTYPE)); 320 memset (m_hwdevice_name,0,sizeof(m_hwdevice_name)); 321 driver_context.video_driver_fd = -1; 322 m_vendor_config.pData = NULL; 323 pthread_mutex_init(&m_lock, NULL); 324 sem_init(&m_cmd_lock,0,0); 325 } 326 327 328 /* ====================================================================== 329 FUNCTION 330 omx_vdec::~omx_vdec 331 332 DESCRIPTION 333 Destructor 334 335 PARAMETERS 336 None 337 338 RETURN VALUE 339 None. 340 ========================================================================== */ 341 omx_vdec::~omx_vdec() 342 { 343 m_pmem_info = NULL; 344 m_port_width = m_port_height = 0; 345 DEBUG_PRINT_HIGH("\n In OMX vdec Destructor"); 346 if(m_pipe_in) close(m_pipe_in); 347 if(m_pipe_out) close(m_pipe_out); 348 m_pipe_in = -1; 349 m_pipe_out = -1; 350 DEBUG_PRINT_HIGH("\n Waiting on OMX Msg Thread exit"); 351 pthread_join(msg_thread_id,NULL); 352 DEBUG_PRINT_HIGH("\n Waiting on OMX Async Thread exit"); 353 pthread_join(async_thread_id,NULL); 354 pthread_mutex_destroy(&m_lock); 355 sem_destroy(&m_cmd_lock); 356 DEBUG_PRINT_HIGH("\n Exit OMX vdec Destructor"); 357 } 358 359 /* ====================================================================== 360 FUNCTION 361 omx_vdec::OMXCntrlProcessMsgCb 362 363 DESCRIPTION 364 IL Client callbacks are generated through this routine. The decoder 365 provides the thread context for this routine. 366 367 PARAMETERS 368 ctxt -- Context information related to the self. 369 id -- Event identifier. This could be any of the following: 370 1. Command completion event 371 2. Buffer done callback event 372 3. Frame done callback event 373 374 RETURN VALUE 375 None. 376 377 ========================================================================== */ 378 void omx_vdec::process_event_cb(void *ctxt, unsigned char id) 379 { 380 unsigned p1; // Parameter - 1 381 unsigned p2; // Parameter - 2 382 unsigned ident; 383 unsigned qsize=0; // qsize 384 omx_vdec *pThis = (omx_vdec *) ctxt; 385 386 if(!pThis) 387 { 388 DEBUG_PRINT_ERROR("ERROR: %s()::Context is incorrect, bailing out\n", 389 __func__); 390 return; 391 } 392 393 // Protect the shared queue data structure 394 do 395 { 396 /*Read the message id's from the queue*/ 397 pthread_mutex_lock(&pThis->m_lock); 398 qsize = pThis->m_cmd_q.m_size; 399 if(qsize) 400 { 401 pThis->m_cmd_q.pop_entry(&p1,&p2,&ident); 402 } 403 404 if (qsize == 0 && !pThis->gate_output_buffers) 405 { 406 qsize = pThis->m_ftb_q.m_size; 407 if (qsize) 408 { 409 pThis->m_ftb_q.pop_entry(&p1,&p2,&ident); 410 } 411 } 412 413 if (qsize == 0) 414 { 415 qsize = pThis->m_etb_q.m_size; 416 if (qsize) 417 { 418 pThis->m_etb_q.pop_entry(&p1,&p2,&ident); 419 } 420 } 421 pthread_mutex_unlock(&pThis->m_lock); 422 423 /*process message if we have one*/ 424 if(qsize > 0) 425 { 426 id = ident; 427 switch (id) 428 { 429 case OMX_COMPONENT_GENERATE_EVENT: 430 if (pThis->m_cb.EventHandler) 431 { 432 switch (p1) 433 { 434 case OMX_CommandStateSet: 435 pThis->m_state = (OMX_STATETYPE) p2; 436 DEBUG_PRINT_HIGH("\n OMX_CommandStateSet complete, m_state = %d", 437 pThis->m_state); 438 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 439 OMX_EventCmdComplete, p1, p2, NULL); 440 break; 441 442 case OMX_EventError: 443 if(p2 == OMX_StateInvalid) 444 { 445 DEBUG_PRINT_ERROR("\n OMX_EventError: p2 is OMX_StateInvalid"); 446 pThis->m_state = (OMX_STATETYPE) p2; 447 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 448 OMX_EventError, OMX_ErrorInvalidState, p2, NULL); 449 } 450 else if (p2 == (unsigned)OMX_ErrorHardware) 451 { 452 pThis->omx_report_error(); 453 } 454 else 455 { 456 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 457 OMX_EventError, p2, NULL, NULL ); 458 } 459 break; 460 461 case OMX_CommandPortDisable: 462 DEBUG_PRINT_HIGH("\n OMX_CommandPortDisable complete for port [%d]", p2); 463 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 464 OMX_EventCmdComplete, p1, p2, NULL ); 465 //TODO: Check if output port is one that got disabled 466 pThis->gate_output_buffers = false; 467 break; 468 case OMX_CommandPortEnable: 469 DEBUG_PRINT_HIGH("\n OMX_CommandPortEnable complete for port [%d]", p2); 470 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,\ 471 OMX_EventCmdComplete, p1, p2, NULL ); 472 break; 473 474 default: 475 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 476 OMX_EventCmdComplete, p1, p2, NULL ); 477 break; 478 479 } 480 } 481 else 482 { 483 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL\n", __func__); 484 } 485 break; 486 case OMX_COMPONENT_GENERATE_ETB_ARBITRARY: 487 if (pThis->empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\ 488 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) 489 { 490 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure"); 491 pThis->omx_report_error (); 492 } 493 break; 494 case OMX_COMPONENT_GENERATE_ETB: 495 if (pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\ 496 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) 497 { 498 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure"); 499 pThis->omx_report_error (); 500 } 501 break; 502 503 case OMX_COMPONENT_GENERATE_FTB: 504 if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\ 505 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) 506 { 507 DEBUG_PRINT_ERROR("\n fill_this_buffer_proxy failure"); 508 pThis->omx_report_error (); 509 } 510 break; 511 512 case OMX_COMPONENT_GENERATE_COMMAND: 513 pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\ 514 (OMX_U32)p2,(OMX_PTR)NULL); 515 break; 516 517 case OMX_COMPONENT_GENERATE_EBD: 518 519 if (p2 != VDEC_S_SUCCESS) 520 { 521 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EBD failure"); 522 pThis->omx_report_error (); 523 } 524 else 525 { 526 if ( pThis->empty_buffer_done(&pThis->m_cmp, 527 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) 528 { 529 DEBUG_PRINT_ERROR("\n empty_buffer_done failure"); 530 pThis->omx_report_error (); 531 } 532 } 533 break; 534 535 case OMX_COMPONENT_GENERATE_FBD: 536 if (p2 != VDEC_S_SUCCESS) 537 { 538 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_FBD failure"); 539 pThis->omx_report_error (); 540 } 541 else 542 { 543 if ( pThis->fill_buffer_done(&pThis->m_cmp, 544 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) 545 { 546 DEBUG_PRINT_ERROR("\n fill_buffer_done failure"); 547 pThis->omx_report_error (); 548 } 549 } 550 break; 551 552 case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH: 553 DEBUG_PRINT_HIGH("\n Flush i/p Port complete"); 554 pThis->input_flush_progress = false; 555 DEBUG_PRINT_LOW("\n Input flush done pending input %d", 556 pThis->pending_input_buffers); 557 558 if (pThis->m_cb.EventHandler) 559 { 560 if (p2 != VDEC_S_SUCCESS) 561 { 562 DEBUG_PRINT_ERROR("\nOMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH failure"); 563 pThis->omx_report_error (); 564 } 565 else 566 { 567 /*Check if we need generate event for Flush done*/ 568 if(BITMASK_PRESENT(&pThis->m_flags, 569 OMX_COMPONENT_INPUT_FLUSH_PENDING)) 570 { 571 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING); 572 DEBUG_PRINT_LOW("\n Input Flush completed - Notify Client"); 573 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 574 OMX_EventCmdComplete,OMX_CommandFlush, 575 OMX_CORE_INPUT_PORT_INDEX,NULL ); 576 } 577 if (BITMASK_PRESENT(&pThis->m_flags, 578 OMX_COMPONENT_IDLE_PENDING)) 579 { 580 if (!pThis->output_flush_progress) 581 { 582 DEBUG_PRINT_LOW("\n Output flush done hence issue stop"); 583 if (ioctl (pThis->driver_context.video_driver_fd, 584 VDEC_IOCTL_CMD_STOP,NULL ) < 0) 585 { 586 DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_STOP failed"); 587 pThis->omx_report_error (); 588 } 589 } 590 } 591 } 592 } 593 594 break; 595 596 case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH: 597 DEBUG_PRINT_HIGH("\n Flush o/p Port complete"); 598 pThis->output_flush_progress = false; 599 DEBUG_PRINT_LOW("\n Output flush done pending buf %d",pThis->pending_output_buffers); 600 601 if (pThis->m_cb.EventHandler) 602 { 603 if (p2 != VDEC_S_SUCCESS) 604 { 605 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH failed"); 606 pThis->omx_report_error (); 607 } 608 else 609 { 610 /*Check if we need generate event for Flush done*/ 611 if(BITMASK_PRESENT(&pThis->m_flags, 612 OMX_COMPONENT_OUTPUT_FLUSH_PENDING)) 613 { 614 DEBUG_PRINT_LOW("\n Notify Output Flush done"); 615 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING); 616 617 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 618 OMX_EventCmdComplete,OMX_CommandFlush, 619 OMX_CORE_OUTPUT_PORT_INDEX,NULL ); 620 } 621 if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING)) 622 { 623 if (!pThis->input_flush_progress) 624 { 625 DEBUG_PRINT_LOW("\n Input flush done hence issue stop"); 626 if (ioctl (pThis->driver_context.video_driver_fd, 627 VDEC_IOCTL_CMD_STOP,NULL ) < 0) 628 { 629 DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_STOP failed"); 630 pThis->omx_report_error (); 631 } 632 } 633 } 634 } 635 } 636 break; 637 638 case OMX_COMPONENT_GENERATE_START_DONE: 639 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_START_DONE"); 640 641 if (pThis->m_cb.EventHandler) 642 { 643 if (p2 != VDEC_S_SUCCESS) 644 { 645 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_START_DONE Failure"); 646 pThis->omx_report_error (); 647 } 648 else 649 { 650 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE Success"); 651 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) 652 { 653 DEBUG_PRINT_LOW("\n Move to executing"); 654 // Send the callback now 655 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING); 656 pThis->m_state = OMX_StateExecuting; 657 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 658 OMX_EventCmdComplete,OMX_CommandStateSet, 659 OMX_StateExecuting, NULL); 660 } 661 else if (BITMASK_PRESENT(&pThis->m_flags, 662 OMX_COMPONENT_PAUSE_PENDING)) 663 { 664 if (ioctl (pThis->driver_context.video_driver_fd, 665 VDEC_IOCTL_CMD_PAUSE,NULL ) < 0) 666 { 667 DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_PAUSE failed"); 668 pThis->omx_report_error (); 669 } 670 } 671 } 672 } 673 else 674 { 675 DEBUG_PRINT_LOW("\n Event Handler callback is NULL"); 676 } 677 break; 678 679 case OMX_COMPONENT_GENERATE_PAUSE_DONE: 680 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_PAUSE_DONE"); 681 if (pThis->m_cb.EventHandler) 682 { 683 if (p2 != VDEC_S_SUCCESS) 684 { 685 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_PAUSE_DONE ret failed"); 686 pThis->omx_report_error (); 687 } 688 else 689 { 690 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING)) 691 { 692 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_PAUSE_DONE nofity"); 693 //Send the callback now 694 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING); 695 pThis->m_state = OMX_StatePause; 696 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 697 OMX_EventCmdComplete,OMX_CommandStateSet, 698 OMX_StatePause, NULL); 699 } 700 } 701 } 702 703 break; 704 705 case OMX_COMPONENT_GENERATE_RESUME_DONE: 706 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_RESUME_DONE"); 707 if (pThis->m_cb.EventHandler) 708 { 709 if (p2 != VDEC_S_SUCCESS) 710 { 711 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_RESUME_DONE failed"); 712 pThis->omx_report_error (); 713 } 714 else 715 { 716 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) 717 { 718 DEBUG_PRINT_LOW("\n Moving the decoder to execute state"); 719 // Send the callback now 720 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING); 721 pThis->m_state = OMX_StateExecuting; 722 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, 723 OMX_EventCmdComplete,OMX_CommandStateSet, 724 OMX_StateExecuting,NULL); 725 } 726 } 727 } 728 729 break; 730 731 case OMX_COMPONENT_GENERATE_STOP_DONE: 732 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_STOP_DONE"); 733 if (pThis->m_cb.EventHandler) 734 { 735 if (p2 != VDEC_S_SUCCESS) 736 { 737 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_STOP_DONE ret failed"); 738 pThis->omx_report_error (); 739 } 740 else 741 { 742 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING)) 743 { 744 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_STOP_DONE Success"); 745 // Send the callback now 746 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING); 747 pThis->m_state = OMX_StateIdle; 748 DEBUG_PRINT_LOW("\n Move to Idle State"); 749 pThis->m_cb.EventHandler(&pThis->m_cmp,pThis->m_app_data, 750 OMX_EventCmdComplete,OMX_CommandStateSet, 751 OMX_StateIdle,NULL); 752 } 753 } 754 } 755 756 break; 757 758 case OMX_COMPONENT_GENERATE_HARDWARE_ERROR: 759 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_HARDWARE_ERROR"); 760 pThis->omx_report_error (); 761 break; 762 763 default: 764 break; 765 } 766 } 767 pthread_mutex_lock(&pThis->m_lock); 768 if(!pThis->gate_output_buffers) 769 { 770 qsize = pThis->m_cmd_q.m_size + pThis->m_ftb_q.m_size +\ 771 pThis->m_etb_q.m_size; 772 } 773 else 774 { 775 qsize = pThis->m_cmd_q.m_size + pThis->m_etb_q.m_size; 776 } 777 pthread_mutex_unlock(&pThis->m_lock); 778 } 779 while(qsize>0); 780 781 } 782 783 784 785 /* ====================================================================== 786 FUNCTION 787 omx_vdec::ComponentInit 788 789 DESCRIPTION 790 Initialize the component. 791 792 PARAMETERS 793 ctxt -- Context information related to the self. 794 id -- Event identifier. This could be any of the following: 795 1. Command completion event 796 2. Buffer done callback event 797 3. Frame done callback event 798 799 RETURN VALUE 800 None. 801 802 ========================================================================== */ 803 OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role) 804 { 805 806 OMX_ERRORTYPE eRet = OMX_ErrorNone; 807 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; 808 unsigned int alignment = 0,buffer_size = 0; 809 int fds[2]; 810 int r; 811 bool is_fluid = false; 812 813 if (!m_device_file_ptr) { 814 int bytes_read = 0,count = 0; 815 unsigned min_size; 816 m_device_file_ptr = fopen("/sys/devices/system/soc/soc0/hw_platform","rb"); 817 if (m_device_file_ptr) { 818 (void)fgets((char *)m_hwdevice_name,sizeof(m_hwdevice_name),m_device_file_ptr); 819 DEBUG_PRINT_HIGH ("\n Name of the device is %s",m_hwdevice_name); 820 min_size = strnlen((const char *)m_hwdevice_name,sizeof(m_hwdevice_name)); 821 if (strlen("Fluid") < min_size) { 822 min_size = strnlen("Fluid",sizeof("Fluid")); 823 } 824 if (!strncmp("Fluid",(const char *)m_hwdevice_name,min_size)) { 825 is_fluid = true; 826 } 827 fclose (m_device_file_ptr); 828 } else { 829 DEBUG_PRINT_HIGH("\n Could not open hw_platform file"); 830 } 831 } 832 833 DEBUG_PRINT_HIGH("\n omx_vdec::component_init(): Start of New Playback"); 834 driver_context.video_driver_fd = open ("/dev/msm_vidc_dec",\ 835 O_RDWR|O_NONBLOCK); 836 837 DEBUG_PRINT_HIGH("\n omx_vdec::component_init(): Open returned fd %d", 838 driver_context.video_driver_fd); 839 840 if(driver_context.video_driver_fd == 0){ 841 driver_context.video_driver_fd = open ("/dev/msm_vidc_dec",\ 842 O_RDWR|O_NONBLOCK); 843 } 844 845 if(driver_context.video_driver_fd < 0) 846 { 847 DEBUG_PRINT_ERROR("Omx_vdec::Comp Init Returning failure\n"); 848 return OMX_ErrorInsufficientResources; 849 } 850 851 #ifndef MULTI_DEC_INST 852 unsigned int instance_count = 0; 853 if (!is_fluid) { 854 ioctl_msg.outputparam = &instance_count; 855 if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_GET_NUMBER_INSTANCES, 856 (void*)&ioctl_msg) < 0){ 857 DEBUG_PRINT_ERROR("\n Instance Query Failed"); 858 return OMX_ErrorInsufficientResources; 859 } 860 if (instance_count > 1) { 861 close(driver_context.video_driver_fd); 862 DEBUG_PRINT_ERROR("\n Reject Second instance of Decoder"); 863 driver_context.video_driver_fd = -1; 864 return OMX_ErrorInsufficientResources; 865 } 866 } 867 #endif 868 869 #if BITSTREAM_LOG 870 outputBufferFile1 = fopen (filename, "ab"); 871 #endif 872 873 // Copy the role information which provides the decoder kind 874 strncpy(driver_context.kind,role,128); 875 876 if(!strncmp(driver_context.kind,"OMX.qcom.video.decoder.mpeg4",\ 877 OMX_MAX_STRINGNAME_SIZE)) 878 { 879 strncpy((char *)m_cRole, "video_decoder.mpeg4",\ 880 OMX_MAX_STRINGNAME_SIZE); 881 driver_context.decoder_format = VDEC_CODECTYPE_MPEG4; 882 eCompressionFormat = OMX_VIDEO_CodingMPEG4; 883 /*Initialize Start Code for MPEG4*/ 884 codec_type_parse = CODEC_TYPE_MPEG4; 885 m_frame_parser.init_start_codes (codec_type_parse); 886 } 887 else if(!strncmp(driver_context.kind, "OMX.qcom.video.decoder.h263",\ 888 OMX_MAX_STRINGNAME_SIZE)) 889 { 890 strncpy((char *)m_cRole, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE); 891 DEBUG_PRINT_LOW("\n H263 Decoder selected"); 892 driver_context.decoder_format = VDEC_CODECTYPE_H263; 893 eCompressionFormat = OMX_VIDEO_CodingH263; 894 codec_type_parse = CODEC_TYPE_H263; 895 m_frame_parser.init_start_codes (codec_type_parse); 896 } 897 else if(!strncmp(driver_context.kind, "OMX.qcom.video.decoder.avc",\ 898 OMX_MAX_STRINGNAME_SIZE)) 899 { 900 strncpy((char *)m_cRole, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE); 901 driver_context.decoder_format = VDEC_CODECTYPE_H264; 902 eCompressionFormat = OMX_VIDEO_CodingAVC; 903 codec_type_parse = CODEC_TYPE_H264; 904 m_frame_parser.init_start_codes (codec_type_parse); 905 m_frame_parser.init_nal_length(nal_length); 906 } 907 else if(!strncmp(driver_context.kind, "OMX.qcom.video.decoder.vc1",\ 908 OMX_MAX_STRINGNAME_SIZE)) 909 { 910 strncpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE); 911 driver_context.decoder_format = VDEC_CODECTYPE_VC1; 912 eCompressionFormat = OMX_VIDEO_CodingWMV; 913 codec_type_parse = CODEC_TYPE_VC1; 914 m_frame_parser.init_start_codes (codec_type_parse); 915 } 916 else 917 { 918 DEBUG_PRINT_ERROR("\nERROR:Unknown Component\n"); 919 eRet = OMX_ErrorInvalidComponentName; 920 } 921 922 if (eRet == OMX_ErrorNone) 923 { 924 driver_context.output_format = VDEC_YUV_FORMAT_NV12; 925 926 if (is_fluid) { 927 928 FILE * pFile; 929 char disable_overlay = '0'; 930 pFile = fopen 931 ("/data/data/com.arcsoft.videowall/files/disableoverlay.txt", "rb" ); 932 if (pFile == NULL) { 933 DEBUG_PRINT_HIGH(" fopen FAiLED for disableoverlay.txt\n"); 934 } else { 935 int count = fread(&disable_overlay, 1, 1, pFile); 936 fclose(pFile); 937 } 938 939 if(disable_overlay == '1') { 940 DEBUG_PRINT_HIGH(" vdec : TILE format \n"); 941 driver_context.output_format = VDEC_YUV_FORMAT_TILE_4x2; 942 } else { 943 DEBUG_PRINT_HIGH(" vdec : NV 12 format \n"); 944 driver_context.output_format = VDEC_YUV_FORMAT_NV12; 945 } 946 } 947 948 /*Initialize Decoder with codec type and resolution*/ 949 ioctl_msg.inputparam = &driver_context.decoder_format; 950 ioctl_msg.outputparam = NULL; 951 952 if ( (eRet == OMX_ErrorNone) && 953 ioctl (driver_context.video_driver_fd,VDEC_IOCTL_SET_CODEC, 954 (void*)&ioctl_msg) < 0) 955 956 { 957 DEBUG_PRINT_ERROR("\n Set codec type failed"); 958 eRet = OMX_ErrorInsufficientResources; 959 } 960 961 /*Set the output format*/ 962 ioctl_msg.inputparam = &driver_context.output_format; 963 ioctl_msg.outputparam = NULL; 964 965 if ( (eRet == OMX_ErrorNone) && 966 ioctl (driver_context.video_driver_fd,VDEC_IOCTL_SET_OUTPUT_FORMAT, 967 (void*)&ioctl_msg) < 0) 968 { 969 DEBUG_PRINT_ERROR("\n Set output format failed"); 970 eRet = OMX_ErrorInsufficientResources; 971 } 972 973 #ifdef MAX_RES_720P 974 driver_context.video_resoultion.frame_height = 720; 975 driver_context.video_resoultion.frame_width = 1280; 976 driver_context.video_resoultion.stride = 1280; 977 driver_context.video_resoultion.scan_lines = 720; 978 #endif 979 #ifdef MAX_RES_1080P 980 driver_context.video_resoultion.frame_height = 1088; 981 driver_context.video_resoultion.frame_width = 1920; 982 driver_context.video_resoultion.stride = 1920; 983 driver_context.video_resoultion.scan_lines = 1088; 984 #endif 985 986 ioctl_msg.inputparam = &driver_context.video_resoultion; 987 ioctl_msg.outputparam = NULL; 988 989 if ( (eRet == OMX_ErrorNone) && 990 ioctl (driver_context.video_driver_fd,VDEC_IOCTL_SET_PICRES, 991 (void*)&ioctl_msg) < 0) 992 { 993 DEBUG_PRINT_ERROR("\n Set Resolution failed"); 994 eRet = OMX_ErrorInsufficientResources; 995 } 996 997 /*Get the Buffer requirements for input and output ports*/ 998 driver_context.input_buffer.buffer_type = VDEC_BUFFER_TYPE_INPUT; 999 ioctl_msg.inputparam = NULL; 1000 ioctl_msg.outputparam = &driver_context.input_buffer; 1001 1002 if ( (eRet == OMX_ErrorNone) && 1003 ioctl (driver_context.video_driver_fd,VDEC_IOCTL_GET_BUFFER_REQ, 1004 (void*)&ioctl_msg) < 0) 1005 { 1006 DEBUG_PRINT_ERROR("\n Requesting for input buffer requirements failed"); 1007 eRet = OMX_ErrorInsufficientResources; 1008 } 1009 1010 m_inp_buf_count = driver_context.input_buffer.actualcount; 1011 buffer_size = driver_context.input_buffer.buffer_size; 1012 alignment = driver_context.input_buffer.alignment; 1013 m_inp_buf_size = ((buffer_size + alignment -1 ) & (~(alignment -1))); 1014 m_inp_buf_count_min = driver_context.input_buffer.mincount; 1015 1016 /*Get the Buffer requirements for input and output ports*/ 1017 driver_context.input_buffer.buffer_type = VDEC_BUFFER_TYPE_INPUT; 1018 ioctl_msg.inputparam = &driver_context.input_buffer; 1019 ioctl_msg.outputparam = NULL; 1020 1021 m_inp_buf_count_min = m_inp_buf_count = driver_context.input_buffer.actualcount = 1022 driver_context.input_buffer.mincount + 3; 1023 1024 if ( (eRet == OMX_ErrorNone) && 1025 ioctl (driver_context.video_driver_fd,VDEC_IOCTL_SET_BUFFER_REQ, 1026 (void*)&ioctl_msg) < 0) 1027 { 1028 DEBUG_PRINT_ERROR("\n Set input buffer requirements failed"); 1029 eRet = OMX_ErrorInsufficientResources; 1030 } 1031 1032 1033 driver_context.output_buffer.buffer_type = VDEC_BUFFER_TYPE_OUTPUT; 1034 ioctl_msg.inputparam = NULL; 1035 ioctl_msg.outputparam = &driver_context.output_buffer; 1036 1037 if ((eRet == OMX_ErrorNone) && 1038 ioctl (driver_context.video_driver_fd,VDEC_IOCTL_GET_BUFFER_REQ, 1039 (void*)&ioctl_msg) < 0) 1040 { 1041 DEBUG_PRINT_ERROR("\n Requesting for output buffer requirements failed"); 1042 eRet = OMX_ErrorInsufficientResources; 1043 } 1044 1045 m_out_buf_count_recon = m_out_buf_count = driver_context.output_buffer.actualcount; 1046 m_out_buf_count_min_recon = m_out_buf_count_min = driver_context.output_buffer.mincount; 1047 1048 alignment = driver_context.output_buffer.alignment; 1049 buffer_size = driver_context.output_buffer.buffer_size; 1050 m_out_buf_size_recon = m_out_buf_size = 1051 ((buffer_size + alignment - 1) & (~(alignment -1))); 1052 #ifdef MAX_RES_720P 1053 scan_lines = m_crop_dy = m_height = 720; 1054 stride = m_crop_dx = m_width = 1280; 1055 #endif 1056 #ifdef MAX_RES_1080P 1057 scan_lines = m_crop_dy = m_height = 1088; 1058 stride = m_crop_dx = m_width = 1920; 1059 #endif 1060 m_port_height = m_height; 1061 m_port_width = m_width; 1062 m_state = OMX_StateLoaded; 1063 1064 if(pipe(fds)) 1065 { 1066 DEBUG_PRINT_ERROR("pipe creation failed\n"); 1067 eRet = OMX_ErrorInsufficientResources; 1068 } 1069 else 1070 { 1071 int temp1[2]; 1072 if(fds[0] == 0 || fds[1] == 0) 1073 { 1074 if (pipe (temp1)) 1075 { 1076 DEBUG_PRINT_ERROR("pipe creation failed\n"); 1077 return OMX_ErrorInsufficientResources; 1078 } 1079 //close (fds[0]); 1080 //close (fds[1]); 1081 fds[0] = temp1 [0]; 1082 fds[1] = temp1 [1]; 1083 } 1084 m_pipe_in = fds[0]; 1085 m_pipe_out = fds[1]; 1086 r = pthread_create(&msg_thread_id,0,message_thread,this); 1087 1088 if(r < 0) 1089 { 1090 DEBUG_PRINT_ERROR("\n component_init(): message_thread creation failed"); 1091 eRet = OMX_ErrorInsufficientResources; 1092 } 1093 else 1094 { 1095 r = pthread_create(&async_thread_id,0,async_message_thread,this); 1096 if(r < 0) 1097 { 1098 DEBUG_PRINT_ERROR("\n component_init(): async_message_thread creation failed"); 1099 eRet = OMX_ErrorInsufficientResources; 1100 } 1101 } 1102 } 1103 } 1104 1105 if (eRet != OMX_ErrorNone) 1106 { 1107 DEBUG_PRINT_ERROR("\n Component Init Failed"); 1108 DEBUG_PRINT_HIGH("\n Calling VDEC_IOCTL_STOP_NEXT_MSG"); 1109 (void)ioctl(driver_context.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG, 1110 NULL); 1111 DEBUG_PRINT_HIGH("\n Calling close() on Video Driver"); 1112 close (driver_context.video_driver_fd); 1113 driver_context.video_driver_fd = -1; 1114 } 1115 else 1116 { 1117 DEBUG_PRINT_HIGH("\n omx_vdec::component_init() success"); 1118 } 1119 1120 return eRet; 1121 } 1122 1123 /* ====================================================================== 1124 FUNCTION 1125 omx_vdec::GetComponentVersion 1126 1127 DESCRIPTION 1128 Returns the component version. 1129 1130 PARAMETERS 1131 TBD. 1132 1133 RETURN VALUE 1134 OMX_ErrorNone. 1135 1136 ========================================================================== */ 1137 OMX_ERRORTYPE omx_vdec::get_component_version 1138 ( 1139 OMX_IN OMX_HANDLETYPE hComp, 1140 OMX_OUT OMX_STRING componentName, 1141 OMX_OUT OMX_VERSIONTYPE* componentVersion, 1142 OMX_OUT OMX_VERSIONTYPE* specVersion, 1143 OMX_OUT OMX_UUIDTYPE* componentUUID 1144 ) 1145 { 1146 if(m_state == OMX_StateInvalid) 1147 { 1148 DEBUG_PRINT_ERROR("Get Comp Version in Invalid State\n"); 1149 return OMX_ErrorInvalidState; 1150 } 1151 /* TBD -- Return the proper version */ 1152 return OMX_ErrorNone; 1153 } 1154 /* ====================================================================== 1155 FUNCTION 1156 omx_vdec::SendCommand 1157 1158 DESCRIPTION 1159 Returns zero if all the buffers released.. 1160 1161 PARAMETERS 1162 None. 1163 1164 RETURN VALUE 1165 true/false 1166 1167 ========================================================================== */ 1168 OMX_ERRORTYPE omx_vdec::send_command(OMX_IN OMX_HANDLETYPE hComp, 1169 OMX_IN OMX_COMMANDTYPE cmd, 1170 OMX_IN OMX_U32 param1, 1171 OMX_IN OMX_PTR cmdData 1172 ) 1173 { 1174 DEBUG_PRINT_LOW("\n send_command: Recieved a Command from Client"); 1175 if(m_state == OMX_StateInvalid) 1176 { 1177 DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State\n"); 1178 return OMX_ErrorInvalidState; 1179 } 1180 post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND); 1181 sem_wait(&m_cmd_lock); 1182 DEBUG_PRINT_LOW("\n send_command: Command Processed\n"); 1183 return OMX_ErrorNone; 1184 } 1185 1186 /* ====================================================================== 1187 FUNCTION 1188 omx_vdec::SendCommand 1189 1190 DESCRIPTION 1191 Returns zero if all the buffers released.. 1192 1193 PARAMETERS 1194 None. 1195 1196 RETURN VALUE 1197 true/false 1198 1199 ========================================================================== */ 1200 OMX_ERRORTYPE omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp, 1201 OMX_IN OMX_COMMANDTYPE cmd, 1202 OMX_IN OMX_U32 param1, 1203 OMX_IN OMX_PTR cmdData 1204 ) 1205 { 1206 OMX_ERRORTYPE eRet = OMX_ErrorNone; 1207 OMX_STATETYPE eState = (OMX_STATETYPE) param1; 1208 int bFlag = 1,sem_posted = 0;; 1209 1210 DEBUG_PRINT_LOW("\n send_command_proxy(): cmd = %d", cmd); 1211 DEBUG_PRINT_HIGH("\n send_command_proxy(): Current State %d, Expected State %d", 1212 m_state, eState); 1213 1214 if(cmd == OMX_CommandStateSet) 1215 { 1216 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandStateSet issued"); 1217 DEBUG_PRINT_HIGH("\n Current State %d, Expected State %d", m_state, eState); 1218 /***************************/ 1219 /* Current State is Loaded */ 1220 /***************************/ 1221 if(m_state == OMX_StateLoaded) 1222 { 1223 if(eState == OMX_StateIdle) 1224 { 1225 //if all buffers are allocated or all ports disabled 1226 if(allocate_done() || 1227 (m_inp_bEnabled == OMX_FALSE && m_out_bEnabled == OMX_FALSE)) 1228 { 1229 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle\n"); 1230 } 1231 else 1232 { 1233 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle-Pending\n"); 1234 BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING); 1235 // Skip the event notification 1236 bFlag = 0; 1237 } 1238 } 1239 /* Requesting transition from Loaded to Loaded */ 1240 else if(eState == OMX_StateLoaded) 1241 { 1242 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Loaded\n"); 1243 post_event(OMX_EventError,OMX_ErrorSameState,\ 1244 OMX_COMPONENT_GENERATE_EVENT); 1245 eRet = OMX_ErrorSameState; 1246 } 1247 /* Requesting transition from Loaded to WaitForResources */ 1248 else if(eState == OMX_StateWaitForResources) 1249 { 1250 /* Since error is None , we will post an event 1251 at the end of this function definition */ 1252 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->WaitForResources\n"); 1253 } 1254 /* Requesting transition from Loaded to Executing */ 1255 else if(eState == OMX_StateExecuting) 1256 { 1257 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Executing\n"); 1258 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 1259 OMX_COMPONENT_GENERATE_EVENT); 1260 eRet = OMX_ErrorIncorrectStateTransition; 1261 } 1262 /* Requesting transition from Loaded to Pause */ 1263 else if(eState == OMX_StatePause) 1264 { 1265 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Pause\n"); 1266 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 1267 OMX_COMPONENT_GENERATE_EVENT); 1268 eRet = OMX_ErrorIncorrectStateTransition; 1269 } 1270 /* Requesting transition from Loaded to Invalid */ 1271 else if(eState == OMX_StateInvalid) 1272 { 1273 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid\n"); 1274 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); 1275 eRet = OMX_ErrorInvalidState; 1276 } 1277 else 1278 { 1279 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)\n",\ 1280 eState); 1281 eRet = OMX_ErrorBadParameter; 1282 } 1283 } 1284 1285 /***************************/ 1286 /* Current State is IDLE */ 1287 /***************************/ 1288 else if(m_state == OMX_StateIdle) 1289 { 1290 if(eState == OMX_StateLoaded) 1291 { 1292 if(release_done()) 1293 { 1294 /* 1295 Since error is None , we will post an event at the end 1296 of this function definition 1297 */ 1298 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded\n"); 1299 } 1300 else 1301 { 1302 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded-Pending\n"); 1303 BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING); 1304 // Skip the event notification 1305 bFlag = 0; 1306 } 1307 } 1308 /* Requesting transition from Idle to Executing */ 1309 else if(eState == OMX_StateExecuting) 1310 { 1311 BITMASK_SET(&m_flags,OMX_COMPONENT_EXECUTE_PENDING); 1312 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n"); 1313 post_event (NULL,VDEC_S_SUCCESS,OMX_COMPONENT_GENERATE_START_DONE); 1314 bFlag = 0; 1315 } 1316 /* Requesting transition from Idle to Idle */ 1317 else if(eState == OMX_StateIdle) 1318 { 1319 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle\n"); 1320 post_event(OMX_EventError,OMX_ErrorSameState,\ 1321 OMX_COMPONENT_GENERATE_EVENT); 1322 eRet = OMX_ErrorSameState; 1323 } 1324 /* Requesting transition from Idle to WaitForResources */ 1325 else if(eState == OMX_StateWaitForResources) 1326 { 1327 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->WaitForResources\n"); 1328 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 1329 OMX_COMPONENT_GENERATE_EVENT); 1330 eRet = OMX_ErrorIncorrectStateTransition; 1331 } 1332 /* Requesting transition from Idle to Pause */ 1333 else if(eState == OMX_StatePause) 1334 { 1335 /*To pause the Video core we need to start the driver*/ 1336 if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_CMD_START, 1337 NULL) < 0) 1338 { 1339 DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_START FAILED"); 1340 omx_report_error (); 1341 eRet = OMX_ErrorHardware; 1342 } 1343 else 1344 { 1345 BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING); 1346 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Pause\n"); 1347 bFlag = 0; 1348 } 1349 } 1350 /* Requesting transition from Idle to Invalid */ 1351 else if(eState == OMX_StateInvalid) 1352 { 1353 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid\n"); 1354 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); 1355 eRet = OMX_ErrorInvalidState; 1356 } 1357 else 1358 { 1359 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled\n",eState); 1360 eRet = OMX_ErrorBadParameter; 1361 } 1362 } 1363 1364 /******************************/ 1365 /* Current State is Executing */ 1366 /******************************/ 1367 else if(m_state == OMX_StateExecuting) 1368 { 1369 DEBUG_PRINT_LOW("\n Command Recieved in OMX_StateExecuting"); 1370 /* Requesting transition from Executing to Idle */ 1371 if(eState == OMX_StateIdle) 1372 { 1373 /* Since error is None , we will post an event 1374 at the end of this function definition 1375 */ 1376 DEBUG_PRINT_LOW("\n send_command_proxy(): Executing --> Idle \n"); 1377 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING); 1378 if(!sem_posted) 1379 { 1380 sem_posted = 1; 1381 sem_post (&m_cmd_lock); 1382 execute_omx_flush(OMX_ALL); 1383 } 1384 bFlag = 0; 1385 } 1386 /* Requesting transition from Executing to Paused */ 1387 else if(eState == OMX_StatePause) 1388 { 1389 DEBUG_PRINT_LOW("\n PAUSE Command Issued"); 1390 if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_CMD_PAUSE, 1391 NULL) < 0) 1392 { 1393 DEBUG_PRINT_ERROR("\n Error In Pause State"); 1394 post_event(OMX_EventError,OMX_ErrorHardware,\ 1395 OMX_COMPONENT_GENERATE_EVENT); 1396 eRet = OMX_ErrorHardware; 1397 } 1398 else 1399 { 1400 BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING); 1401 DEBUG_PRINT_LOW("send_command_proxy(): Pause-->Executing\n"); 1402 bFlag = 0; 1403 } 1404 } 1405 /* Requesting transition from Executing to Loaded */ 1406 else if(eState == OMX_StateLoaded) 1407 { 1408 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Loaded \n"); 1409 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 1410 OMX_COMPONENT_GENERATE_EVENT); 1411 eRet = OMX_ErrorIncorrectStateTransition; 1412 } 1413 /* Requesting transition from Executing to WaitForResources */ 1414 else if(eState == OMX_StateWaitForResources) 1415 { 1416 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> WaitForResources \n"); 1417 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 1418 OMX_COMPONENT_GENERATE_EVENT); 1419 eRet = OMX_ErrorIncorrectStateTransition; 1420 } 1421 /* Requesting transition from Executing to Executing */ 1422 else if(eState == OMX_StateExecuting) 1423 { 1424 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Executing \n"); 1425 post_event(OMX_EventError,OMX_ErrorSameState,\ 1426 OMX_COMPONENT_GENERATE_EVENT); 1427 eRet = OMX_ErrorSameState; 1428 } 1429 /* Requesting transition from Executing to Invalid */ 1430 else if(eState == OMX_StateInvalid) 1431 { 1432 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Invalid \n"); 1433 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); 1434 eRet = OMX_ErrorInvalidState; 1435 } 1436 else 1437 { 1438 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled\n",eState); 1439 eRet = OMX_ErrorBadParameter; 1440 } 1441 } 1442 /***************************/ 1443 /* Current State is Pause */ 1444 /***************************/ 1445 else if(m_state == OMX_StatePause) 1446 { 1447 /* Requesting transition from Pause to Executing */ 1448 if(eState == OMX_StateExecuting) 1449 { 1450 DEBUG_PRINT_LOW("\n Pause --> Executing \n"); 1451 if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_CMD_RESUME, 1452 NULL) < 0) 1453 { 1454 DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_RESUME failed"); 1455 post_event(OMX_EventError,OMX_ErrorHardware,\ 1456 OMX_COMPONENT_GENERATE_EVENT); 1457 eRet = OMX_ErrorHardware; 1458 } 1459 else 1460 { 1461 BITMASK_SET(&m_flags,OMX_COMPONENT_EXECUTE_PENDING); 1462 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n"); 1463 post_event (NULL,VDEC_S_SUCCESS,\ 1464 OMX_COMPONENT_GENERATE_RESUME_DONE); 1465 bFlag = 0; 1466 } 1467 } 1468 /* Requesting transition from Pause to Idle */ 1469 else if(eState == OMX_StateIdle) 1470 { 1471 /* Since error is None , we will post an event 1472 at the end of this function definition */ 1473 DEBUG_PRINT_LOW("\n Pause --> Idle \n"); 1474 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING); 1475 if(!sem_posted) 1476 { 1477 sem_posted = 1; 1478 sem_post (&m_cmd_lock); 1479 execute_omx_flush(OMX_ALL); 1480 } 1481 bFlag = 0; 1482 } 1483 /* Requesting transition from Pause to loaded */ 1484 else if(eState == OMX_StateLoaded) 1485 { 1486 DEBUG_PRINT_ERROR("\n Pause --> loaded \n"); 1487 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 1488 OMX_COMPONENT_GENERATE_EVENT); 1489 eRet = OMX_ErrorIncorrectStateTransition; 1490 } 1491 /* Requesting transition from Pause to WaitForResources */ 1492 else if(eState == OMX_StateWaitForResources) 1493 { 1494 DEBUG_PRINT_ERROR("\n Pause --> WaitForResources \n"); 1495 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 1496 OMX_COMPONENT_GENERATE_EVENT); 1497 eRet = OMX_ErrorIncorrectStateTransition; 1498 } 1499 /* Requesting transition from Pause to Pause */ 1500 else if(eState == OMX_StatePause) 1501 { 1502 DEBUG_PRINT_ERROR("\n Pause --> Pause \n"); 1503 post_event(OMX_EventError,OMX_ErrorSameState,\ 1504 OMX_COMPONENT_GENERATE_EVENT); 1505 eRet = OMX_ErrorSameState; 1506 } 1507 /* Requesting transition from Pause to Invalid */ 1508 else if(eState == OMX_StateInvalid) 1509 { 1510 DEBUG_PRINT_ERROR("\n Pause --> Invalid \n"); 1511 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); 1512 eRet = OMX_ErrorInvalidState; 1513 } 1514 else 1515 { 1516 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled\n",eState); 1517 eRet = OMX_ErrorBadParameter; 1518 } 1519 } 1520 /***************************/ 1521 /* Current State is WaitForResources */ 1522 /***************************/ 1523 else if(m_state == OMX_StateWaitForResources) 1524 { 1525 /* Requesting transition from WaitForResources to Loaded */ 1526 if(eState == OMX_StateLoaded) 1527 { 1528 /* Since error is None , we will post an event 1529 at the end of this function definition */ 1530 DEBUG_PRINT_LOW("send_command_proxy(): WaitForResources-->Loaded\n"); 1531 } 1532 /* Requesting transition from WaitForResources to WaitForResources */ 1533 else if (eState == OMX_StateWaitForResources) 1534 { 1535 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources\n"); 1536 post_event(OMX_EventError,OMX_ErrorSameState, 1537 OMX_COMPONENT_GENERATE_EVENT); 1538 eRet = OMX_ErrorSameState; 1539 } 1540 /* Requesting transition from WaitForResources to Executing */ 1541 else if(eState == OMX_StateExecuting) 1542 { 1543 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Executing\n"); 1544 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 1545 OMX_COMPONENT_GENERATE_EVENT); 1546 eRet = OMX_ErrorIncorrectStateTransition; 1547 } 1548 /* Requesting transition from WaitForResources to Pause */ 1549 else if(eState == OMX_StatePause) 1550 { 1551 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Pause\n"); 1552 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 1553 OMX_COMPONENT_GENERATE_EVENT); 1554 eRet = OMX_ErrorIncorrectStateTransition; 1555 } 1556 /* Requesting transition from WaitForResources to Invalid */ 1557 else if(eState == OMX_StateInvalid) 1558 { 1559 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Invalid\n"); 1560 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); 1561 eRet = OMX_ErrorInvalidState; 1562 } 1563 /* Requesting transition from WaitForResources to Loaded - 1564 is NOT tested by Khronos TS */ 1565 1566 } 1567 else 1568 { 1569 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)\n",m_state,eState); 1570 eRet = OMX_ErrorBadParameter; 1571 } 1572 } 1573 /********************************/ 1574 /* Current State is Invalid */ 1575 /*******************************/ 1576 else if(m_state == OMX_StateInvalid) 1577 { 1578 /* State Transition from Inavlid to any state */ 1579 if(eState == (OMX_StateLoaded || OMX_StateWaitForResources 1580 || OMX_StateIdle || OMX_StateExecuting 1581 || OMX_StatePause || OMX_StateInvalid)) 1582 { 1583 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Invalid -->Loaded\n"); 1584 post_event(OMX_EventError,OMX_ErrorInvalidState,\ 1585 OMX_COMPONENT_GENERATE_EVENT); 1586 eRet = OMX_ErrorInvalidState; 1587 } 1588 } 1589 else if (cmd == OMX_CommandFlush) 1590 { 1591 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandFlush issued" 1592 "with param1: %d", param1); 1593 if(0 == param1 || OMX_ALL == param1) 1594 { 1595 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING); 1596 } 1597 if(1 == param1 || OMX_ALL == param1) 1598 { 1599 //generate output flush event only. 1600 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING); 1601 } 1602 if (!sem_posted){ 1603 sem_posted = 1; 1604 DEBUG_PRINT_LOW("\n Set the Semaphore"); 1605 sem_post (&m_cmd_lock); 1606 execute_omx_flush(param1); 1607 } 1608 bFlag = 0; 1609 } 1610 else if ( cmd == OMX_CommandPortEnable) 1611 { 1612 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandPortEnable issued" 1613 "with param1: %d", param1); 1614 if(param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) 1615 { 1616 m_inp_bEnabled = OMX_TRUE; 1617 1618 if( (m_state == OMX_StateLoaded && 1619 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) 1620 || allocate_input_done()) 1621 { 1622 post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX, 1623 OMX_COMPONENT_GENERATE_EVENT); 1624 } 1625 else 1626 { 1627 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending\n"); 1628 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING); 1629 // Skip the event notification 1630 bFlag = 0; 1631 } 1632 } 1633 if(param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) 1634 { 1635 DEBUG_PRINT_LOW("\n Enable output Port command recieved"); 1636 m_out_bEnabled = OMX_TRUE; 1637 1638 if( (m_state == OMX_StateLoaded && 1639 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) 1640 || (allocate_output_done())) 1641 { 1642 post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX, 1643 OMX_COMPONENT_GENERATE_EVENT); 1644 1645 } 1646 else 1647 { 1648 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending\n"); 1649 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING); 1650 // Skip the event notification 1651 bFlag = 0; 1652 } 1653 } 1654 } 1655 else if (cmd == OMX_CommandPortDisable) 1656 { 1657 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandPortDisable issued" 1658 "with param1: %d", param1); 1659 if(param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) 1660 { 1661 m_inp_bEnabled = OMX_FALSE; 1662 if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle) 1663 && release_input_done()) 1664 { 1665 post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX, 1666 OMX_COMPONENT_GENERATE_EVENT); 1667 } 1668 else 1669 { 1670 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING); 1671 if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting) 1672 { 1673 if(!sem_posted) 1674 { 1675 sem_posted = 1; 1676 sem_post (&m_cmd_lock); 1677 execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX); 1678 } 1679 } 1680 1681 // Skip the event notification 1682 bFlag = 0; 1683 } 1684 } 1685 if(param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) 1686 { 1687 m_out_bEnabled = OMX_FALSE; 1688 DEBUG_PRINT_LOW("\n Disable output Port command recieved"); 1689 if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle) 1690 && release_output_done()) 1691 { 1692 post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\ 1693 OMX_COMPONENT_GENERATE_EVENT); 1694 } 1695 else 1696 { 1697 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING); 1698 if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting) 1699 { 1700 if(!sem_posted) 1701 { 1702 sem_posted = 1; 1703 sem_post (&m_cmd_lock); 1704 execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX); 1705 } 1706 } 1707 // Skip the event notification 1708 bFlag = 0; 1709 1710 } 1711 } 1712 } 1713 else 1714 { 1715 DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)\n",cmd); 1716 eRet = OMX_ErrorNotImplemented; 1717 } 1718 if(eRet == OMX_ErrorNone && bFlag) 1719 { 1720 post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT); 1721 } 1722 if(!sem_posted) 1723 { 1724 sem_post(&m_cmd_lock); 1725 } 1726 1727 return eRet; 1728 } 1729 1730 /* ====================================================================== 1731 FUNCTION 1732 omx_vdec::ExecuteOmxFlush 1733 1734 DESCRIPTION 1735 Executes the OMX flush. 1736 1737 PARAMETERS 1738 flushtype - input flush(1)/output flush(0)/ both. 1739 1740 RETURN VALUE 1741 true/false 1742 1743 ========================================================================== */ 1744 bool omx_vdec::execute_omx_flush(OMX_U32 flushType) 1745 { 1746 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; 1747 enum vdec_bufferflush flush_dir = VDEC_FLUSH_TYPE_ALL; 1748 bool bRet = false; 1749 1750 if(flushType == 0 || flushType == OMX_ALL) 1751 { 1752 input_flush_progress = true; 1753 //flush input only 1754 bRet = execute_input_flush(flushType); 1755 } 1756 if(flushType == 1 || flushType == OMX_ALL) 1757 { 1758 //flush output only 1759 output_flush_progress = true; 1760 bRet = execute_output_flush(flushType); 1761 } 1762 1763 if(flushType == OMX_ALL) 1764 { 1765 /*Check if there are buffers with the Driver*/ 1766 DEBUG_PRINT_LOW("\n Flush ALL ioctl issued"); 1767 ioctl_msg.inputparam = &flush_dir; 1768 ioctl_msg.outputparam = NULL; 1769 1770 if (ioctl(driver_context.video_driver_fd,VDEC_IOCTL_CMD_FLUSH,&ioctl_msg) < 0) 1771 { 1772 DEBUG_PRINT_ERROR("\n Flush ALL Failed "); 1773 return false; 1774 } 1775 } 1776 1777 return bRet; 1778 } 1779 /*========================================================================= 1780 FUNCTION : execute_output_flush 1781 1782 DESCRIPTION 1783 Executes the OMX flush at OUTPUT PORT. 1784 1785 PARAMETERS 1786 None. 1787 1788 RETURN VALUE 1789 true/false 1790 ==========================================================================*/ 1791 bool omx_vdec::execute_output_flush(OMX_U32 flushType) 1792 { 1793 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; 1794 enum vdec_bufferflush flush_dir = VDEC_FLUSH_TYPE_OUTPUT; 1795 unsigned p1 = 0; // Parameter - 1 1796 unsigned p2 = 0; // Parameter - 2 1797 unsigned ident = 0; 1798 bool bRet = true; 1799 1800 /*Generate FBD for all Buffers in the FTBq*/ 1801 pthread_mutex_lock(&m_lock); 1802 DEBUG_PRINT_LOW("\n Initiate Output Flush"); 1803 while (m_ftb_q.m_size) 1804 { 1805 DEBUG_PRINT_LOW("\n Buffer queue size %d pending buf cnt %d", 1806 m_ftb_q.m_size,pending_output_buffers); 1807 m_ftb_q.pop_entry(&p1,&p2,&ident); 1808 1809 if(ident == OMX_COMPONENT_GENERATE_FTB ) 1810 { 1811 DEBUG_PRINT_LOW("\n Inside Flush Buffer OMX_COMPONENT_GENERATE_FTB"); 1812 pending_output_buffers++; 1813 fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2); 1814 } 1815 else if (ident == OMX_COMPONENT_GENERATE_FBD) 1816 { 1817 fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1); 1818 } 1819 } 1820 pthread_mutex_unlock(&m_lock); 1821 1822 if(gate_output_buffers) 1823 { 1824 DEBUG_PRINT_LOW("\n Output Buffers gated Check flush response"); 1825 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING)) 1826 { 1827 DEBUG_PRINT_LOW("\n Notify Output Flush done"); 1828 BITMASK_CLEAR (&m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING); 1829 m_cb.EventHandler(&m_cmp,m_app_data,OMX_EventCmdComplete,OMX_CommandFlush, 1830 OMX_CORE_OUTPUT_PORT_INDEX,NULL ); 1831 } 1832 output_flush_progress = false; 1833 return bRet; 1834 } 1835 1836 DEBUG_PRINT_LOW("\n output buffers count = %d",pending_output_buffers); 1837 1838 if(flushType == 1) 1839 { 1840 /*Check if there are buffers with the Driver*/ 1841 DEBUG_PRINT_LOW("\n ioctl command flush for output"); 1842 ioctl_msg.inputparam = &flush_dir; 1843 ioctl_msg.outputparam = NULL; 1844 1845 if (ioctl(driver_context.video_driver_fd,VDEC_IOCTL_CMD_FLUSH,&ioctl_msg) < 0) 1846 { 1847 DEBUG_PRINT_ERROR("\n output flush failed"); 1848 return false; 1849 } 1850 } 1851 1852 return bRet; 1853 } 1854 /*========================================================================= 1855 FUNCTION : execute_input_flush 1856 1857 DESCRIPTION 1858 Executes the OMX flush at INPUT PORT. 1859 1860 PARAMETERS 1861 None. 1862 1863 RETURN VALUE 1864 true/false 1865 ==========================================================================*/ 1866 bool omx_vdec::execute_input_flush(OMX_U32 flushType) 1867 { 1868 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; 1869 enum vdec_bufferflush flush_dir = VDEC_FLUSH_TYPE_INPUT; 1870 unsigned i =0; 1871 unsigned p1 = 0; // Parameter - 1 1872 unsigned p2 = 0; // Parameter - 2 1873 unsigned ident = 0; 1874 bool bRet = true; 1875 1876 /*Generate EBD for all Buffers in the ETBq*/ 1877 DEBUG_PRINT_LOW("\n Initiate Input Flush \n"); 1878 1879 pthread_mutex_lock(&m_lock); 1880 DEBUG_PRINT_LOW("\n Check if the Queue is empty \n"); 1881 while (m_etb_q.m_size) 1882 { 1883 m_etb_q.pop_entry(&p1,&p2,&ident); 1884 1885 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) 1886 { 1887 DEBUG_PRINT_LOW("\n Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2); 1888 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2); 1889 } 1890 else if(ident == OMX_COMPONENT_GENERATE_ETB) 1891 { 1892 pending_input_buffers++; 1893 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2); 1894 } 1895 else if (ident == OMX_COMPONENT_GENERATE_EBD) 1896 { 1897 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1); 1898 } 1899 } 1900 1901 /*Check if Heap Buffers are to be flushed*/ 1902 if (arbitrary_bytes) 1903 { 1904 DEBUG_PRINT_LOW("\n Reset all the variables before flusing"); 1905 h264_scratch.nFilledLen = 0; 1906 nal_count = 0; 1907 look_ahead_nal = false; 1908 frame_count = 0; 1909 DEBUG_PRINT_LOW("\n Initialize parser"); 1910 if (m_frame_parser.mutils) 1911 { 1912 m_frame_parser.mutils->initialize_frame_checking_environment(); 1913 } 1914 1915 while (m_input_pending_q.m_size) 1916 { 1917 m_input_pending_q.pop_entry(&p1,&p2,&ident); 1918 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1); 1919 } 1920 1921 if (psource_frame) 1922 { 1923 m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame); 1924 psource_frame = NULL; 1925 } 1926 1927 if (pdest_frame) 1928 { 1929 pdest_frame->nFilledLen = 0; 1930 m_input_free_q.insert_entry((unsigned) pdest_frame,NULL,NULL); 1931 pdest_frame = NULL; 1932 } 1933 m_frame_parser.flush(); 1934 } 1935 1936 pthread_mutex_unlock(&m_lock); 1937 DEBUG_PRINT_LOW("\n Value of pending input buffers %d \n",pending_input_buffers); 1938 1939 if(flushType == 0) 1940 { 1941 /*Check if there are buffers with the Driver*/ 1942 DEBUG_PRINT_LOW("\n Input Flush ioctl issued"); 1943 ioctl_msg.inputparam = &flush_dir; 1944 ioctl_msg.outputparam = NULL; 1945 1946 if (ioctl(driver_context.video_driver_fd,VDEC_IOCTL_CMD_FLUSH,&ioctl_msg) < 0) 1947 { 1948 DEBUG_PRINT_ERROR("\n Input Flush Failed "); 1949 return false; 1950 } 1951 } 1952 1953 return bRet; 1954 } 1955 1956 1957 /* ====================================================================== 1958 FUNCTION 1959 omx_vdec::SendCommandEvent 1960 1961 DESCRIPTION 1962 Send the event to decoder pipe. This is needed to generate the callbacks 1963 in decoder thread context. 1964 1965 PARAMETERS 1966 None. 1967 1968 RETURN VALUE 1969 true/false 1970 1971 ========================================================================== */ 1972 bool omx_vdec::post_event(unsigned int p1, 1973 unsigned int p2, 1974 unsigned int id) 1975 { 1976 bool bRet = false; 1977 1978 1979 pthread_mutex_lock(&m_lock); 1980 1981 if( id == OMX_COMPONENT_GENERATE_FTB || \ 1982 (id == OMX_COMPONENT_GENERATE_FBD)|| 1983 (id == OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH)) 1984 { 1985 m_ftb_q.insert_entry(p1,p2,id); 1986 } 1987 else if((id == OMX_COMPONENT_GENERATE_ETB) \ 1988 || (id == OMX_COMPONENT_GENERATE_EBD)|| 1989 (id == OMX_COMPONENT_GENERATE_ETB_ARBITRARY)|| 1990 (id == OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH)) 1991 { 1992 m_etb_q.insert_entry(p1,p2,id); 1993 } 1994 else 1995 { 1996 m_cmd_q.insert_entry(p1,p2,id); 1997 } 1998 1999 bRet = true; 2000 DEBUG_PRINT_LOW("\n Value of this pointer in post_event %p",this); 2001 post_message(this, id); 2002 2003 pthread_mutex_unlock(&m_lock); 2004 2005 return bRet; 2006 } 2007 2008 /* ====================================================================== 2009 FUNCTION 2010 omx_vdec::GetParameter 2011 2012 DESCRIPTION 2013 OMX Get Parameter method implementation 2014 2015 PARAMETERS 2016 <TBD>. 2017 2018 RETURN VALUE 2019 Error None if successful. 2020 2021 ========================================================================== */ 2022 OMX_ERRORTYPE omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE hComp, 2023 OMX_IN OMX_INDEXTYPE paramIndex, 2024 OMX_INOUT OMX_PTR paramData) 2025 { 2026 OMX_ERRORTYPE eRet = OMX_ErrorNone; 2027 unsigned int height=0,width = 0; 2028 2029 DEBUG_PRINT_LOW("get_parameter: \n"); 2030 if(m_state == OMX_StateInvalid) 2031 { 2032 DEBUG_PRINT_ERROR("Get Param in Invalid State\n"); 2033 return OMX_ErrorInvalidState; 2034 } 2035 if(paramData == NULL) 2036 { 2037 DEBUG_PRINT_LOW("Get Param in Invalid paramData \n"); 2038 return OMX_ErrorBadParameter; 2039 } 2040 switch(paramIndex) 2041 { 2042 case OMX_IndexParamPortDefinition: 2043 { 2044 OMX_PARAM_PORTDEFINITIONTYPE *portDefn; 2045 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData; 2046 2047 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition\n"); 2048 2049 portDefn->nVersion.nVersion = OMX_SPEC_VERSION; 2050 portDefn->nSize = sizeof(portDefn); 2051 portDefn->eDomain = OMX_PortDomainVideo; 2052 portDefn->format.video.nFrameHeight = m_crop_dy; 2053 portDefn->format.video.nFrameWidth = m_crop_dx; 2054 portDefn->format.video.nStride = m_width; 2055 portDefn->format.video.nSliceHeight = m_height; 2056 portDefn->format.video.xFramerate= 25; 2057 2058 if (0 == portDefn->nPortIndex) 2059 { 2060 portDefn->eDir = OMX_DirInput; 2061 /*Actual count is based on input buffer count*/ 2062 portDefn->nBufferCountActual = m_inp_buf_count; 2063 /*Set the Min count*/ 2064 portDefn->nBufferCountMin = m_inp_buf_count_min; 2065 portDefn->nBufferSize = m_inp_buf_size; 2066 portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused; 2067 portDefn->format.video.eCompressionFormat = eCompressionFormat; 2068 portDefn->bEnabled = m_inp_bEnabled; 2069 portDefn->bPopulated = m_inp_bPopulated; 2070 } 2071 else if (1 == portDefn->nPortIndex) 2072 { 2073 m_out_buf_count = m_out_buf_count_recon; 2074 m_out_buf_count_min = m_out_buf_count_min_recon; 2075 m_out_buf_size = m_out_buf_size_recon; 2076 portDefn->eDir = OMX_DirOutput; 2077 portDefn->nBufferCountActual = m_out_buf_count; 2078 portDefn->nBufferCountMin = m_out_buf_count_min; 2079 portDefn->nBufferSize = m_out_buf_size; 2080 portDefn->bEnabled = m_out_bEnabled; 2081 portDefn->bPopulated = m_out_bPopulated; 2082 height = driver_context.video_resoultion.frame_height; 2083 width = driver_context.video_resoultion.frame_width; 2084 2085 portDefn->format.video.nFrameHeight = height; 2086 portDefn->format.video.nFrameWidth = width; 2087 portDefn->format.video.nStride = stride; 2088 portDefn->format.video.nSliceHeight = scan_lines; 2089 DEBUG_PRINT_LOW("\n Get Param Slice Height %d Slice Width %d", 2090 scan_lines,stride); 2091 //TODO: Need to add color format 2092 portDefn->format.video.eColorFormat = m_color_format; 2093 portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; 2094 DEBUG_PRINT_LOW("\n Output Actual %d Output Min %d", 2095 portDefn->nBufferCountActual,portDefn->nBufferCountMin); 2096 } 2097 else 2098 { 2099 portDefn->eDir = OMX_DirMax; 2100 DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d", 2101 (int)portDefn->nPortIndex); 2102 eRet = OMX_ErrorBadPortIndex; 2103 } 2104 2105 break; 2106 } 2107 case OMX_IndexParamVideoInit: 2108 { 2109 OMX_PORT_PARAM_TYPE *portParamType = 2110 (OMX_PORT_PARAM_TYPE *) paramData; 2111 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit\n"); 2112 2113 portParamType->nVersion.nVersion = OMX_SPEC_VERSION; 2114 portParamType->nSize = sizeof(portParamType); 2115 portParamType->nPorts = 2; 2116 portParamType->nStartPortNumber = 0; 2117 break; 2118 } 2119 case OMX_IndexParamVideoPortFormat: 2120 { 2121 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt = 2122 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData; 2123 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat\n"); 2124 2125 portFmt->nVersion.nVersion = OMX_SPEC_VERSION; 2126 portFmt->nSize = sizeof(portFmt); 2127 2128 if (0 == portFmt->nPortIndex) 2129 { 2130 if (0 == portFmt->nIndex) 2131 { 2132 portFmt->eColorFormat = OMX_COLOR_FormatUnused; 2133 portFmt->eCompressionFormat = eCompressionFormat; 2134 } 2135 else 2136 { 2137 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\ 2138 " NoMore compression formats\n"); 2139 eRet = OMX_ErrorNoMore; 2140 } 2141 } 2142 else if (1 == portFmt->nPortIndex) 2143 { 2144 if (0 == portFmt->nIndex) 2145 { 2146 if (driver_context.output_format == VDEC_YUV_FORMAT_NV12) 2147 portFmt->eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; 2148 else 2149 portFmt->eColorFormat = (OMX_COLOR_FORMATTYPE)0x7F000000; 2150 2151 portFmt->eCompressionFormat = OMX_VIDEO_CodingUnused; 2152 } 2153 else 2154 { 2155 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\ 2156 " NoMore Color formats\n"); 2157 eRet = OMX_ErrorNoMore; 2158 } 2159 } 2160 else 2161 { 2162 DEBUG_PRINT_ERROR("get_parameter: Bad port index %d\n", 2163 (int)portFmt->nPortIndex); 2164 eRet = OMX_ErrorBadPortIndex; 2165 } 2166 break; 2167 } 2168 /*Component should support this port definition*/ 2169 case OMX_IndexParamAudioInit: 2170 { 2171 OMX_PORT_PARAM_TYPE *audioPortParamType = 2172 (OMX_PORT_PARAM_TYPE *) paramData; 2173 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit\n"); 2174 audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION; 2175 audioPortParamType->nSize = sizeof(audioPortParamType); 2176 audioPortParamType->nPorts = 0; 2177 audioPortParamType->nStartPortNumber = 0; 2178 break; 2179 } 2180 /*Component should support this port definition*/ 2181 case OMX_IndexParamImageInit: 2182 { 2183 OMX_PORT_PARAM_TYPE *imagePortParamType = 2184 (OMX_PORT_PARAM_TYPE *) paramData; 2185 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit\n"); 2186 imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION; 2187 imagePortParamType->nSize = sizeof(imagePortParamType); 2188 imagePortParamType->nPorts = 0; 2189 imagePortParamType->nStartPortNumber = 0; 2190 break; 2191 2192 } 2193 /*Component should support this port definition*/ 2194 case OMX_IndexParamOtherInit: 2195 { 2196 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x\n", 2197 paramIndex); 2198 eRet =OMX_ErrorUnsupportedIndex; 2199 break; 2200 } 2201 case OMX_IndexParamStandardComponentRole: 2202 { 2203 OMX_PARAM_COMPONENTROLETYPE *comp_role; 2204 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData; 2205 comp_role->nVersion.nVersion = OMX_SPEC_VERSION; 2206 comp_role->nSize = sizeof(*comp_role); 2207 2208 DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d\n", 2209 paramIndex); 2210 strncpy((char*)comp_role->cRole,(const char*)m_cRole, 2211 OMX_MAX_STRINGNAME_SIZE); 2212 break; 2213 } 2214 /* Added for parameter test */ 2215 case OMX_IndexParamPriorityMgmt: 2216 { 2217 2218 OMX_PRIORITYMGMTTYPE *priorityMgmType = 2219 (OMX_PRIORITYMGMTTYPE *) paramData; 2220 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt\n"); 2221 priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION; 2222 priorityMgmType->nSize = sizeof(priorityMgmType); 2223 2224 break; 2225 } 2226 /* Added for parameter test */ 2227 case OMX_IndexParamCompBufferSupplier: 2228 { 2229 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = 2230 (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData; 2231 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier\n"); 2232 2233 bufferSupplierType->nSize = sizeof(bufferSupplierType); 2234 bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION; 2235 if(0 == bufferSupplierType->nPortIndex) 2236 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified; 2237 else if (1 == bufferSupplierType->nPortIndex) 2238 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified; 2239 else 2240 eRet = OMX_ErrorBadPortIndex; 2241 2242 2243 break; 2244 } 2245 case OMX_IndexParamVideoAvc: 2246 { 2247 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x\n", 2248 paramIndex); 2249 break; 2250 } 2251 case OMX_IndexParamVideoH263: 2252 { 2253 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x\n", 2254 paramIndex); 2255 break; 2256 } 2257 case OMX_IndexParamVideoMpeg4: 2258 { 2259 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x\n", 2260 paramIndex); 2261 break; 2262 } 2263 default: 2264 { 2265 DEBUG_PRINT_ERROR("get_parameter: unknown param %08x\n", paramIndex); 2266 eRet =OMX_ErrorUnsupportedIndex; 2267 } 2268 2269 } 2270 2271 DEBUG_PRINT_LOW("\n get_parameter returning Height %d , Width %d \n", 2272 m_height, m_width); 2273 return eRet; 2274 2275 } 2276 2277 /* ====================================================================== 2278 FUNCTION 2279 omx_vdec::Setparameter 2280 2281 DESCRIPTION 2282 OMX Set Parameter method implementation. 2283 2284 PARAMETERS 2285 <TBD>. 2286 2287 RETURN VALUE 2288 OMX Error None if successful. 2289 2290 ========================================================================== */ 2291 OMX_ERRORTYPE omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE hComp, 2292 OMX_IN OMX_INDEXTYPE paramIndex, 2293 OMX_IN OMX_PTR paramData) 2294 { 2295 OMX_ERRORTYPE eRet = OMX_ErrorNone; 2296 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; 2297 unsigned int alignment = 0,buffer_size = 0; 2298 int i; 2299 2300 if(m_state == OMX_StateInvalid) 2301 { 2302 DEBUG_PRINT_ERROR("Set Param in Invalid State\n"); 2303 return OMX_ErrorInvalidState; 2304 } 2305 if(paramData == NULL) 2306 { 2307 DEBUG_PRINT_ERROR("Get Param in Invalid paramData \n"); 2308 return OMX_ErrorBadParameter; 2309 } 2310 switch(paramIndex) 2311 { 2312 case OMX_IndexParamPortDefinition: 2313 { 2314 OMX_PARAM_PORTDEFINITIONTYPE *portDefn; 2315 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData; 2316 2317 /*set_parameter can be called in loaded state 2318 or disabled port */ 2319 2320 /* When the component is in Loaded state and IDLE Pending*/ 2321 if(((m_state == OMX_StateLoaded)&& 2322 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) 2323 /* Or while the I/P or the O/P port or disabled */ 2324 ||((OMX_DirInput == portDefn->eDir && m_inp_bEnabled == OMX_FALSE)|| 2325 (OMX_DirOutput == portDefn->eDir && m_out_bEnabled == OMX_FALSE))) 2326 { 2327 DEBUG_PRINT_LOW("Set Parameter called in valid state"); 2328 } 2329 else 2330 { 2331 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n"); 2332 return OMX_ErrorIncorrectStateOperation; 2333 } 2334 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d\n", 2335 (int)portDefn->format.video.nFrameHeight, 2336 (int)portDefn->format.video.nFrameWidth); 2337 2338 eRet = omx_vdec_validate_port_param(portDefn->format.video.nFrameHeight, 2339 portDefn->format.video.nFrameWidth); 2340 if(eRet != OMX_ErrorNone) 2341 { 2342 return OMX_ErrorUnsupportedSetting; 2343 } 2344 if(OMX_DirOutput == portDefn->eDir) 2345 { 2346 if ( portDefn->nBufferCountActual < m_out_buf_count_min || 2347 portDefn->nBufferSize != m_out_buf_size 2348 ) 2349 { 2350 return OMX_ErrorBadParameter; 2351 } 2352 driver_context.output_buffer.buffer_type = VDEC_BUFFER_TYPE_OUTPUT; 2353 ioctl_msg.inputparam = NULL; 2354 ioctl_msg.outputparam = &driver_context.output_buffer; 2355 2356 if (ioctl (driver_context.video_driver_fd, 2357 VDEC_IOCTL_GET_BUFFER_REQ,(void*)&ioctl_msg) < 0) 2358 { 2359 DEBUG_PRINT_ERROR("\n Request output buffer requirements failed"); 2360 return OMX_ErrorUnsupportedSetting; 2361 } 2362 driver_context.output_buffer.buffer_type = VDEC_BUFFER_TYPE_OUTPUT; 2363 driver_context.output_buffer.actualcount = 2364 portDefn->nBufferCountActual; 2365 ioctl_msg.inputparam = &driver_context.output_buffer; 2366 ioctl_msg.outputparam = NULL; 2367 2368 if (ioctl (driver_context.video_driver_fd, 2369 VDEC_IOCTL_SET_BUFFER_REQ,(void*)&ioctl_msg) < 0) 2370 { 2371 DEBUG_PRINT_ERROR("\n Request output buffer requirements failed"); 2372 return OMX_ErrorUnsupportedSetting; 2373 } 2374 m_out_buf_count = portDefn->nBufferCountActual; 2375 m_out_buf_count_recon = m_out_buf_count; 2376 DEBUG_PRINT_LOW("set_parameter:OMX_IndexParamPortDefinition output port\n"); 2377 } 2378 else if(OMX_DirInput == portDefn->eDir) 2379 { 2380 if(m_height != portDefn->format.video.nFrameHeight || 2381 m_width != portDefn->format.video.nFrameWidth) 2382 { 2383 DEBUG_PRINT_LOW("set_parameter ip port: stride %d\n", 2384 (int)portDefn->format.video.nStride); 2385 // set the HxW only if non-zero 2386 if((portDefn->format.video.nFrameHeight != 0x0) 2387 && (portDefn->format.video.nFrameWidth != 0x0)) 2388 { 2389 m_crop_x = m_crop_y = 0; 2390 m_crop_dy = m_port_height = m_height = 2391 portDefn->format.video.nFrameHeight; 2392 m_crop_dx = m_port_width = m_width = 2393 portDefn->format.video.nFrameWidth; 2394 scan_lines = portDefn->format.video.nSliceHeight; 2395 stride = portDefn->format.video.nStride; 2396 DEBUG_PRINT_LOW("\n SetParam with new H %d and W %d\n", 2397 m_height, m_width ); 2398 driver_context.video_resoultion.frame_height = m_height; 2399 driver_context.video_resoultion.frame_width = m_width; 2400 driver_context.video_resoultion.stride = stride; 2401 driver_context.video_resoultion.scan_lines = scan_lines; 2402 ioctl_msg.inputparam = &driver_context.video_resoultion; 2403 ioctl_msg.outputparam = NULL; 2404 2405 if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_SET_PICRES, 2406 (void*)&ioctl_msg) < 0) 2407 { 2408 DEBUG_PRINT_ERROR("\n Set Resolution failed"); 2409 return OMX_ErrorUnsupportedSetting; 2410 } 2411 driver_context.output_buffer.buffer_type = 2412 VDEC_BUFFER_TYPE_OUTPUT; 2413 ioctl_msg.inputparam = NULL; 2414 ioctl_msg.outputparam = &driver_context.output_buffer; 2415 2416 if (ioctl (driver_context.video_driver_fd, 2417 VDEC_IOCTL_GET_BUFFER_REQ,(void*)&ioctl_msg) < 0) 2418 { 2419 DEBUG_PRINT_ERROR("\n Request output buffer requirements failed"); 2420 return OMX_ErrorUnsupportedSetting; 2421 } 2422 2423 m_out_buf_count_recon = m_out_buf_count = driver_context.output_buffer.actualcount; 2424 m_out_buf_count_min_recon = m_out_buf_count_min = driver_context.output_buffer.mincount; 2425 2426 alignment = driver_context.output_buffer.alignment; 2427 buffer_size = driver_context.output_buffer.buffer_size; 2428 m_out_buf_size_recon = m_out_buf_size = 2429 ((buffer_size + alignment - 1) & (~(alignment - 1))); 2430 } 2431 } 2432 else 2433 { 2434 /* 2435 If actual buffer count is greater than the Min buffer 2436 count,change the actual count. 2437 m_inp_buf_count is initialized to OMX_CORE_NUM_INPUT_BUFFERS 2438 in the constructor 2439 */ 2440 if ( portDefn->nBufferCountActual < m_inp_buf_count_min || 2441 portDefn->nBufferSize != m_inp_buf_size 2442 ) 2443 { 2444 return OMX_ErrorBadParameter; 2445 } 2446 /*Get the Buffer requirements for input and output ports*/ 2447 driver_context.input_buffer.buffer_type = VDEC_BUFFER_TYPE_INPUT; 2448 ioctl_msg.inputparam = NULL; 2449 ioctl_msg.outputparam = &driver_context.input_buffer; 2450 2451 if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_GET_BUFFER_REQ, 2452 (void*)&ioctl_msg) < 0) 2453 { 2454 DEBUG_PRINT_ERROR("\n Request input buffer requirements failed"); 2455 return OMX_ErrorUnsupportedSetting; 2456 } 2457 2458 driver_context.input_buffer.buffer_type = VDEC_BUFFER_TYPE_INPUT; 2459 driver_context.input_buffer.actualcount = 2460 portDefn->nBufferCountActual; 2461 ioctl_msg.inputparam = &driver_context.input_buffer; 2462 ioctl_msg.outputparam = NULL; 2463 2464 if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_SET_BUFFER_REQ, 2465 (void*)&ioctl_msg) < 0) 2466 { 2467 DEBUG_PRINT_ERROR("\n Request input buffer requirements failed"); 2468 return OMX_ErrorUnsupportedSetting; 2469 } 2470 2471 m_inp_buf_count = portDefn->nBufferCountActual; 2472 DEBUG_PRINT_LOW("\n set_parameter: Image Dimensions same \n"); 2473 } 2474 2475 } 2476 else if (portDefn->eDir == OMX_DirMax) 2477 { 2478 DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d", 2479 (int)portDefn->nPortIndex); 2480 eRet = OMX_ErrorBadPortIndex; 2481 } 2482 } 2483 break; 2484 2485 2486 case OMX_IndexParamVideoPortFormat: 2487 { 2488 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt = 2489 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData; 2490 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d\n", 2491 portFmt->eColorFormat); 2492 2493 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d\n", 2494 portFmt->eColorFormat); 2495 if(1 == portFmt->nPortIndex) 2496 { 2497 2498 m_color_format = portFmt->eColorFormat; 2499 } 2500 } 2501 break; 2502 2503 case OMX_QcomIndexPortDefn: 2504 { 2505 OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt = 2506 (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData; 2507 DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %d\n", 2508 portFmt->nFramePackingFormat); 2509 2510 /* Input port */ 2511 if (portFmt->nPortIndex == 0) 2512 { 2513 if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary) 2514 { 2515 arbitrary_bytes = true; 2516 } 2517 else if (portFmt->nFramePackingFormat == 2518 OMX_QCOM_FramePacking_OnlyOneCompleteFrame) 2519 { 2520 arbitrary_bytes = false; 2521 } 2522 else 2523 { 2524 DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %d\n", 2525 portFmt->nFramePackingFormat); 2526 eRet = OMX_ErrorUnsupportedSetting; 2527 } 2528 } 2529 } 2530 break; 2531 2532 case OMX_IndexParamStandardComponentRole: 2533 { 2534 OMX_PARAM_COMPONENTROLETYPE *comp_role; 2535 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData; 2536 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s\n", 2537 comp_role->cRole); 2538 2539 if((m_state == OMX_StateLoaded)&& 2540 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) 2541 { 2542 DEBUG_PRINT_LOW("Set Parameter called in valid state"); 2543 } 2544 else 2545 { 2546 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n"); 2547 return OMX_ErrorIncorrectStateOperation; 2548 } 2549 2550 if(!strncmp(driver_context.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) 2551 { 2552 if(!strncmp((char*)comp_role->cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE)) 2553 { 2554 strncpy((char*)m_cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE); 2555 } 2556 else 2557 { 2558 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole); 2559 eRet =OMX_ErrorUnsupportedSetting; 2560 } 2561 } 2562 else if(!strncmp(driver_context.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) 2563 { 2564 if(!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) 2565 { 2566 strncpy((char*)m_cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE); 2567 } 2568 else 2569 { 2570 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole); 2571 eRet = OMX_ErrorUnsupportedSetting; 2572 } 2573 } 2574 else if(!strncmp(driver_context.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) 2575 { 2576 if(!strncmp((const char*)comp_role->cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE)) 2577 { 2578 strncpy((char*)m_cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE); 2579 } 2580 else 2581 { 2582 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole); 2583 eRet =OMX_ErrorUnsupportedSetting; 2584 } 2585 } 2586 else if(!strncmp(driver_context.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) 2587 { 2588 if(!strncmp((const char*)comp_role->cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) 2589 { 2590 strncpy((char*)m_cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE); 2591 } 2592 else 2593 { 2594 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole); 2595 eRet =OMX_ErrorUnsupportedSetting; 2596 } 2597 } 2598 else 2599 { 2600 DEBUG_PRINT_ERROR("Setparameter: unknown param %s\n", driver_context.kind); 2601 eRet = OMX_ErrorInvalidComponentName; 2602 } 2603 break; 2604 } 2605 2606 case OMX_IndexParamPriorityMgmt: 2607 { 2608 if(m_state != OMX_StateLoaded) 2609 { 2610 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n"); 2611 return OMX_ErrorIncorrectStateOperation; 2612 } 2613 OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData; 2614 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %d\n", 2615 priorityMgmtype->nGroupID); 2616 2617 DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %d\n", 2618 priorityMgmtype->nGroupPriority); 2619 2620 m_priority_mgm.nGroupID = priorityMgmtype->nGroupID; 2621 m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority; 2622 2623 break; 2624 } 2625 2626 case OMX_IndexParamCompBufferSupplier: 2627 { 2628 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData; 2629 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d\n", 2630 bufferSupplierType->eBufferSupplier); 2631 if(bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1) 2632 m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier; 2633 2634 else 2635 2636 eRet = OMX_ErrorBadPortIndex; 2637 2638 break; 2639 2640 } 2641 case OMX_IndexParamVideoAvc: 2642 { 2643 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d\n", 2644 paramIndex); 2645 break; 2646 } 2647 case OMX_IndexParamVideoH263: 2648 { 2649 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d\n", 2650 paramIndex); 2651 break; 2652 } 2653 case OMX_IndexParamVideoMpeg4: 2654 { 2655 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d\n", 2656 paramIndex); 2657 break; 2658 } 2659 2660 default: 2661 { 2662 DEBUG_PRINT_ERROR("Setparameter: unknown param %d\n", paramIndex); 2663 eRet = OMX_ErrorUnsupportedIndex; 2664 } 2665 } 2666 2667 return eRet; 2668 } 2669 2670 /* ====================================================================== 2671 FUNCTION 2672 omx_vdec::GetConfig 2673 2674 DESCRIPTION 2675 OMX Get Config Method implementation. 2676 2677 PARAMETERS 2678 <TBD>. 2679 2680 RETURN VALUE 2681 OMX Error None if successful. 2682 2683 ========================================================================== */ 2684 OMX_ERRORTYPE omx_vdec::get_config(OMX_IN OMX_HANDLETYPE hComp, 2685 OMX_IN OMX_INDEXTYPE configIndex, 2686 OMX_INOUT OMX_PTR configData) 2687 { 2688 OMX_ERRORTYPE eRet = OMX_ErrorNone; 2689 2690 if (m_state == OMX_StateInvalid) 2691 { 2692 DEBUG_PRINT_ERROR("Get Config in Invalid State\n"); 2693 return OMX_ErrorInvalidState; 2694 } 2695 2696 switch (configIndex) 2697 { 2698 case OMX_QcomIndexConfigInterlaced: 2699 { 2700 OMX_QCOM_CONFIG_INTERLACETYPE *configFmt = 2701 (OMX_QCOM_CONFIG_INTERLACETYPE *) configData; 2702 if (configFmt->nPortIndex == 1) 2703 { 2704 if (configFmt->nIndex == 0) 2705 { 2706 configFmt->eInterlaceType = OMX_QCOM_InterlaceFrameProgressive; 2707 } 2708 else if (configFmt->nIndex == 1) 2709 { 2710 configFmt->eInterlaceType = 2711 OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst; 2712 } 2713 else if (configFmt->nIndex == 2) 2714 { 2715 configFmt->eInterlaceType = 2716 OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst; 2717 } 2718 else 2719 { 2720 DEBUG_PRINT_ERROR("get_config: OMX_QcomIndexConfigInterlaced:" 2721 " NoMore Interlaced formats\n"); 2722 eRet = OMX_ErrorNoMore; 2723 } 2724 2725 } 2726 else 2727 { 2728 DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port\n", 2729 (int)configFmt->nPortIndex); 2730 eRet = OMX_ErrorBadPortIndex; 2731 } 2732 break; 2733 } 2734 case OMX_QcomIndexQueryNumberOfVideoDecInstance: 2735 { 2736 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; 2737 QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances = 2738 (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData; 2739 ioctl_msg.outputparam = (void*)&decoderinstances->nNumOfInstances; 2740 (void)(ioctl(driver_context.video_driver_fd, 2741 VDEC_IOCTL_GET_NUMBER_INSTANCES,&ioctl_msg)); 2742 break; 2743 } 2744 default: 2745 { 2746 DEBUG_PRINT_ERROR("get_config: unknown param %d\n",configIndex); 2747 eRet = OMX_ErrorBadParameter; 2748 } 2749 2750 } 2751 2752 return eRet; 2753 } 2754 2755 /* ====================================================================== 2756 FUNCTION 2757 omx_vdec::SetConfig 2758 2759 DESCRIPTION 2760 OMX Set Config method implementation 2761 2762 PARAMETERS 2763 <TBD>. 2764 2765 RETURN VALUE 2766 OMX Error None if successful. 2767 ========================================================================== */ 2768 OMX_ERRORTYPE omx_vdec::set_config(OMX_IN OMX_HANDLETYPE hComp, 2769 OMX_IN OMX_INDEXTYPE configIndex, 2770 OMX_IN OMX_PTR configData) 2771 { 2772 if(m_state == OMX_StateInvalid) 2773 { 2774 DEBUG_PRINT_ERROR("Get Config in Invalid State\n"); 2775 return OMX_ErrorInvalidState; 2776 } 2777 2778 OMX_ERRORTYPE ret = OMX_ErrorNone; 2779 OMX_VIDEO_CONFIG_NALSIZE *pNal; 2780 2781 DEBUG_PRINT_LOW("\n Set Config Called"); 2782 2783 if (m_state == OMX_StateExecuting) 2784 { 2785 DEBUG_PRINT_ERROR("set_config:Ignore in Exe state\n"); 2786 return ret; 2787 } 2788 2789 if (configIndex == OMX_IndexVendorVideoExtraData) 2790 { 2791 OMX_VENDOR_EXTRADATATYPE *config = (OMX_VENDOR_EXTRADATATYPE *) configData; 2792 DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData called"); 2793 if (!strcmp(driver_context.kind, "OMX.qcom.video.decoder.avc")) 2794 { 2795 DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData AVC"); 2796 OMX_U32 extra_size; 2797 // Parsing done here for the AVC atom is definitely not generic 2798 // Currently this piece of code is working, but certainly 2799 // not tested with all .mp4 files. 2800 // Incase of failure, we might need to revisit this 2801 // for a generic piece of code. 2802 2803 // Retrieve size of NAL length field 2804 // byte #4 contains the size of NAL lenght field 2805 nal_length = (config->pData[4] & 0x03) + 1; 2806 2807 extra_size = 0; 2808 if (nal_length > 2) 2809 { 2810 /* Presently we assume that only one SPS and one PPS in AvC1 Atom */ 2811 extra_size = (nal_length - 2) * 2; 2812 } 2813 2814 // SPS starts from byte #6 2815 OMX_U8 *pSrcBuf = (OMX_U8 *) (&config->pData[6]); 2816 OMX_U8 *pDestBuf; 2817 m_vendor_config.nPortIndex = config->nPortIndex; 2818 2819 // minus 6 --> SPS starts from byte #6 2820 // minus 1 --> picture param set byte to be ignored from avcatom 2821 m_vendor_config.nDataSize = config->nDataSize - 6 - 1 + extra_size; 2822 m_vendor_config.pData = (OMX_U8 *) malloc(m_vendor_config.nDataSize); 2823 OMX_U32 len; 2824 OMX_U8 index = 0; 2825 // case where SPS+PPS is sent as part of set_config 2826 pDestBuf = m_vendor_config.pData; 2827 2828 DEBUG_PRINT_LOW("Rxd SPS+PPS nPortIndex[%d] len[%d] data[0x%x]\n", 2829 m_vendor_config.nPortIndex, 2830 m_vendor_config.nDataSize, 2831 m_vendor_config.pData); 2832 while (index < 2) 2833 { 2834 uint8 *psize; 2835 len = *pSrcBuf; 2836 len = len << 8; 2837 len |= *(pSrcBuf + 1); 2838 psize = (uint8 *) & len; 2839 memcpy(pDestBuf + nal_length, pSrcBuf + 2,len); 2840 for (int i = 0; i < nal_length; i++) 2841 { 2842 pDestBuf[i] = psize[nal_length - 1 - i]; 2843 } 2844 //memcpy(pDestBuf,pSrcBuf,(len+2)); 2845 pDestBuf += len + nal_length; 2846 pSrcBuf += len + 2; 2847 index++; 2848 pSrcBuf++; // skip picture param set 2849 len = 0; 2850 } 2851 } 2852 else if (!strcmp(driver_context.kind, "OMX.qcom.video.decoder.mpeg4")) 2853 { 2854 m_vendor_config.nPortIndex = config->nPortIndex; 2855 m_vendor_config.nDataSize = config->nDataSize; 2856 m_vendor_config.pData = (OMX_U8 *) malloc((config->nDataSize)); 2857 memcpy(m_vendor_config.pData, config->pData,config->nDataSize); 2858 } 2859 else if (!strcmp(driver_context.kind, "OMX.qcom.video.decoder.vc1")) 2860 { 2861 if(m_vendor_config.pData) 2862 { 2863 free(m_vendor_config.pData); 2864 m_vendor_config.pData = NULL; 2865 m_vendor_config.nDataSize = 0; 2866 } 2867 2868 if (((*((OMX_U32 *) config->pData)) & 2869 VC1_SP_MP_START_CODE_MASK) == 2870 VC1_SP_MP_START_CODE) 2871 { 2872 DEBUG_PRINT_LOW("set_config - VC1 simple/main profile\n"); 2873 m_vendor_config.nPortIndex = config->nPortIndex; 2874 m_vendor_config.nDataSize = config->nDataSize; 2875 m_vendor_config.pData = 2876 (OMX_U8 *) malloc(config->nDataSize); 2877 memcpy(m_vendor_config.pData, config->pData, 2878 config->nDataSize); 2879 m_vc1_profile = VC1_SP_MP_RCV; 2880 } 2881 else if (*((OMX_U32 *) config->pData) == VC1_AP_SEQ_START_CODE) 2882 { 2883 DEBUG_PRINT_LOW("set_config - VC1 Advance profile\n"); 2884 m_vendor_config.nPortIndex = config->nPortIndex; 2885 m_vendor_config.nDataSize = config->nDataSize; 2886 m_vendor_config.pData = 2887 (OMX_U8 *) malloc((config->nDataSize)); 2888 memcpy(m_vendor_config.pData, config->pData, 2889 config->nDataSize); 2890 m_vc1_profile = VC1_AP; 2891 } 2892 else if ((config->nDataSize == VC1_STRUCT_C_LEN)) 2893 { 2894 DEBUG_PRINT_LOW("set_config - VC1 Simple/Main profile struct C only\n"); 2895 m_vendor_config.nPortIndex = config->nPortIndex; 2896 m_vendor_config.nDataSize = config->nDataSize; 2897 m_vendor_config.pData = (OMX_U8*)malloc(config->nDataSize); 2898 memcpy(m_vendor_config.pData,config->pData,config->nDataSize); 2899 m_vc1_profile = VC1_SP_MP_RCV; 2900 } 2901 else 2902 { 2903 DEBUG_PRINT_LOW("set_config - Error: Unknown VC1 profile\n"); 2904 } 2905 } 2906 return ret; 2907 } 2908 else if (configIndex == OMX_IndexConfigVideoNalSize) 2909 { 2910 2911 pNal = reinterpret_cast < OMX_VIDEO_CONFIG_NALSIZE * >(configData); 2912 nal_length = pNal->nNaluBytes; 2913 m_frame_parser.init_nal_length(nal_length); 2914 DEBUG_PRINT_LOW("\n Nal Length option called with Size %d",nal_length); 2915 return ret; 2916 } 2917 2918 return OMX_ErrorNotImplemented; 2919 } 2920 2921 /* ====================================================================== 2922 FUNCTION 2923 omx_vdec::GetExtensionIndex 2924 2925 DESCRIPTION 2926 OMX GetExtensionIndex method implementaion. <TBD> 2927 2928 PARAMETERS 2929 <TBD>. 2930 2931 RETURN VALUE 2932 OMX Error None if everything successful. 2933 2934 ========================================================================== */ 2935 OMX_ERRORTYPE omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE hComp, 2936 OMX_IN OMX_STRING paramName, 2937 OMX_OUT OMX_INDEXTYPE* indexType) 2938 { 2939 DEBUG_PRINT_ERROR("get_extension_index: Error, Not implemented\n"); 2940 if(m_state == OMX_StateInvalid) 2941 { 2942 DEBUG_PRINT_ERROR("Get Extension Index in Invalid State\n"); 2943 return OMX_ErrorInvalidState; 2944 } 2945 return OMX_ErrorNotImplemented; 2946 } 2947 2948 /* ====================================================================== 2949 FUNCTION 2950 omx_vdec::GetState 2951 2952 DESCRIPTION 2953 Returns the state information back to the caller.<TBD> 2954 2955 PARAMETERS 2956 <TBD>. 2957 2958 RETURN VALUE 2959 Error None if everything is successful. 2960 ========================================================================== */ 2961 OMX_ERRORTYPE omx_vdec::get_state(OMX_IN OMX_HANDLETYPE hComp, 2962 OMX_OUT OMX_STATETYPE* state) 2963 { 2964 *state = m_state; 2965 DEBUG_PRINT_LOW("get_state: Returning the state %d\n",*state); 2966 return OMX_ErrorNone; 2967 } 2968 2969 /* ====================================================================== 2970 FUNCTION 2971 omx_vdec::ComponentTunnelRequest 2972 2973 DESCRIPTION 2974 OMX Component Tunnel Request method implementation. <TBD> 2975 2976 PARAMETERS 2977 None. 2978 2979 RETURN VALUE 2980 OMX Error None if everything successful. 2981 2982 ========================================================================== */ 2983 OMX_ERRORTYPE omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp, 2984 OMX_IN OMX_U32 port, 2985 OMX_IN OMX_HANDLETYPE peerComponent, 2986 OMX_IN OMX_U32 peerPort, 2987 OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup) 2988 { 2989 DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented\n"); 2990 return OMX_ErrorNotImplemented; 2991 } 2992 2993 /* ====================================================================== 2994 FUNCTION 2995 omx_vdec::UseInputBuffer 2996 2997 DESCRIPTION 2998 Helper function for Use buffer in the input pin 2999 3000 PARAMETERS 3001 None. 3002 3003 RETURN VALUE 3004 true/false 3005 3006 ========================================================================== */ 3007 OMX_ERRORTYPE omx_vdec::use_input_buffer( 3008 OMX_IN OMX_HANDLETYPE hComp, 3009 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 3010 OMX_IN OMX_U32 port, 3011 OMX_IN OMX_PTR appData, 3012 OMX_IN OMX_U32 bytes, 3013 OMX_IN OMX_U8* buffer) 3014 { 3015 OMX_ERRORTYPE eRet = OMX_ErrorNone; 3016 struct vdec_setbuffer_cmd setbuffers; 3017 OMX_BUFFERHEADERTYPE *input = NULL; 3018 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; 3019 unsigned i = 0; 3020 unsigned char *buf_addr = NULL; 3021 int pmem_fd = -1; 3022 3023 if(bytes != m_inp_buf_size) 3024 { 3025 return OMX_ErrorBadParameter; 3026 } 3027 3028 if(!m_inp_mem_ptr) 3029 { 3030 DEBUG_PRINT_HIGH("\n Use i/p buffer case - Header List allocation"); 3031 input_use_buffer = true; 3032 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \ 3033 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), m_inp_buf_count); 3034 3035 if (m_inp_mem_ptr == NULL) 3036 { 3037 return OMX_ErrorInsufficientResources; 3038 } 3039 3040 driver_context.ptr_inputbuffer = (struct vdec_bufferpayload *) \ 3041 calloc ((sizeof (struct vdec_bufferpayload)),m_inp_buf_count); 3042 3043 if (driver_context.ptr_inputbuffer == NULL) 3044 { 3045 return OMX_ErrorInsufficientResources; 3046 } 3047 3048 for (i=0; i < m_inp_buf_count; i++) 3049 { 3050 driver_context.ptr_inputbuffer [i].pmem_fd = -1; 3051 } 3052 } 3053 3054 for(i=0; i< m_inp_buf_count; i++) 3055 { 3056 if(BITMASK_ABSENT(&m_inp_bm_count,i)) 3057 { 3058 break; 3059 } 3060 } 3061 3062 if(i < m_inp_buf_count) 3063 { 3064 pmem_fd = open ("/dev/pmem_adsp",O_RDWR | O_SYNC); 3065 3066 if (pmem_fd < 0) 3067 { 3068 return OMX_ErrorInsufficientResources; 3069 } 3070 3071 if(pmem_fd == 0) 3072 { 3073 pmem_fd = open ("/dev/pmem_adsp",O_RDWR | O_SYNC); 3074 if (pmem_fd < 0) 3075 { 3076 return OMX_ErrorInsufficientResources; 3077 } 3078 } 3079 3080 if(!align_pmem_buffers(pmem_fd, m_inp_buf_size, 3081 driver_context.input_buffer.alignment)) 3082 { 3083 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed"); 3084 close(pmem_fd); 3085 return OMX_ErrorInsufficientResources; 3086 } 3087 3088 buf_addr = (unsigned char *)mmap(NULL,m_inp_buf_size,PROT_READ|PROT_WRITE, 3089 MAP_SHARED,pmem_fd,0); 3090 3091 if (buf_addr == MAP_FAILED) 3092 { 3093 return OMX_ErrorInsufficientResources; 3094 } 3095 3096 driver_context.ptr_inputbuffer [i].bufferaddr = buf_addr; 3097 driver_context.ptr_inputbuffer [i].pmem_fd = pmem_fd; 3098 driver_context.ptr_inputbuffer [i].mmaped_size = m_inp_buf_size; 3099 driver_context.ptr_inputbuffer [i].offset = 0; 3100 3101 setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT; 3102 memcpy (&setbuffers.buffer,&driver_context.ptr_inputbuffer [i], 3103 sizeof (vdec_bufferpayload)); 3104 ioctl_msg.inputparam = &setbuffers; 3105 ioctl_msg.outputparam = NULL; 3106 3107 if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_SET_BUFFER, 3108 &ioctl_msg) < 0) 3109 { 3110 return OMX_ErrorInsufficientResources; 3111 } 3112 3113 *bufferHdr = (m_inp_mem_ptr + i); 3114 input = *bufferHdr; 3115 BITMASK_SET(&m_inp_bm_count,i); 3116 3117 input->pBuffer = (OMX_U8 *)buffer; 3118 input->nSize = sizeof(OMX_BUFFERHEADERTYPE); 3119 input->nVersion.nVersion = OMX_SPEC_VERSION; 3120 input->nAllocLen = m_inp_buf_size; 3121 input->pAppPrivate = appData; 3122 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX; 3123 input->pInputPortPrivate = (void *)&driver_context.ptr_inputbuffer [i]; 3124 } 3125 else 3126 { 3127 eRet = OMX_ErrorInsufficientResources; 3128 } 3129 return eRet; 3130 } 3131 3132 3133 /* ====================================================================== 3134 FUNCTION 3135 omx_vdec::UseOutputBuffer 3136 3137 DESCRIPTION 3138 Helper function for Use buffer in the input pin 3139 3140 PARAMETERS 3141 None. 3142 3143 RETURN VALUE 3144 true/false 3145 3146 ========================================================================== */ 3147 OMX_ERRORTYPE omx_vdec::use_output_buffer( 3148 OMX_IN OMX_HANDLETYPE hComp, 3149 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 3150 OMX_IN OMX_U32 port, 3151 OMX_IN OMX_PTR appData, 3152 OMX_IN OMX_U32 bytes, 3153 OMX_IN OMX_U8* buffer) 3154 { 3155 OMX_ERRORTYPE eRet = OMX_ErrorNone; 3156 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header 3157 unsigned i= 0; // Temporary counter 3158 3159 if(!m_out_mem_ptr) 3160 { 3161 DEBUG_PRINT_HIGH("\n Use o/p buffer case - Header List allocation"); 3162 output_use_buffer = true; 3163 int nBufHdrSize = 0; 3164 int nPlatformEntrySize = 0; 3165 int nPlatformListSize = 0; 3166 int nPMEMInfoSize = 0; 3167 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList; 3168 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry; 3169 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo; 3170 3171 DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)\n",m_out_buf_count); 3172 nBufHdrSize = m_out_buf_count * sizeof(OMX_BUFFERHEADERTYPE); 3173 3174 nPMEMInfoSize = m_out_buf_count * 3175 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO); 3176 nPlatformListSize = m_out_buf_count * 3177 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST); 3178 nPlatformEntrySize = m_out_buf_count * 3179 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY); 3180 3181 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize, 3182 sizeof(OMX_BUFFERHEADERTYPE), 3183 nPMEMInfoSize, 3184 nPlatformListSize); 3185 DEBUG_PRINT_LOW("PE %d bmSize %d \n",nPlatformEntrySize, 3186 m_out_bm_count); 3187 3188 /* 3189 * Memory for output side involves the following: 3190 * 1. Array of Buffer Headers 3191 * 2. Platform specific information List 3192 * 3. Platform specific Entry List 3193 * 4. PMem Information entries 3194 * 5. Bitmask array to hold the buffer allocation details 3195 * In order to minimize the memory management entire allocation 3196 * is done in one step. 3197 */ 3198 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1); 3199 // Alloc mem for platform specific info 3200 char *pPtr=NULL; 3201 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize + 3202 nPMEMInfoSize,1); 3203 driver_context.ptr_outputbuffer = (struct vdec_bufferpayload *) \ 3204 calloc (sizeof(struct vdec_bufferpayload),m_out_buf_count); 3205 driver_context.ptr_respbuffer = (struct vdec_output_frameinfo *)\ 3206 calloc (sizeof (struct vdec_output_frameinfo),m_out_buf_count); 3207 3208 if(m_out_mem_ptr && pPtr && driver_context.ptr_outputbuffer 3209 && driver_context.ptr_respbuffer) 3210 { 3211 bufHdr = m_out_mem_ptr; 3212 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr); 3213 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *) 3214 (((char *) m_platform_list) + nPlatformListSize); 3215 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) 3216 (((char *) m_platform_entry) + nPlatformEntrySize); 3217 pPlatformList = m_platform_list; 3218 pPlatformEntry = m_platform_entry; 3219 pPMEMInfo = m_pmem_info; 3220 3221 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr); 3222 3223 // Settting the entire storage nicely 3224 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr, m_out_mem_ptr,pPlatformEntry); 3225 DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo); 3226 for(i=0; i < m_out_buf_count ; i++) 3227 { 3228 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE); 3229 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION; 3230 // Set the values when we determine the right HxW param 3231 bufHdr->nAllocLen = bytes; 3232 bufHdr->nFilledLen = 0; 3233 bufHdr->pAppPrivate = appData; 3234 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 3235 // Platform specific PMEM Information 3236 // Initialize the Platform Entry 3237 //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d\n",i); 3238 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM; 3239 pPlatformEntry->entry = pPMEMInfo; 3240 // Initialize the Platform List 3241 pPlatformList->nEntries = 1; 3242 pPlatformList->entryList = pPlatformEntry; 3243 // Keep pBuffer NULL till vdec is opened 3244 bufHdr->pBuffer = NULL; 3245 3246 pPMEMInfo->offset = 0; 3247 pPMEMInfo->pmem_fd = 0; 3248 bufHdr->pPlatformPrivate = pPlatformList; 3249 3250 driver_context.ptr_outputbuffer[i].pmem_fd = -1; 3251 3252 /*Create a mapping between buffers*/ 3253 bufHdr->pOutputPortPrivate = &driver_context.ptr_respbuffer[i]; 3254 driver_context.ptr_respbuffer[i].client_data = (void *) \ 3255 &driver_context.ptr_outputbuffer[i]; 3256 // Move the buffer and buffer header pointers 3257 bufHdr++; 3258 pPMEMInfo++; 3259 pPlatformEntry++; 3260 pPlatformList++; 3261 } 3262 } 3263 else 3264 { 3265 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%x][0x%x]\n",\ 3266 m_out_mem_ptr, pPtr); 3267 if(m_out_mem_ptr) 3268 { 3269 free(m_out_mem_ptr); 3270 m_out_mem_ptr = NULL; 3271 } 3272 if(pPtr) 3273 { 3274 free(pPtr); 3275 pPtr = NULL; 3276 } 3277 if(driver_context.ptr_outputbuffer) 3278 { 3279 free(driver_context.ptr_outputbuffer); 3280 driver_context.ptr_outputbuffer = NULL; 3281 } 3282 if(driver_context.ptr_respbuffer) 3283 { 3284 free(driver_context.ptr_respbuffer); 3285 driver_context.ptr_respbuffer = NULL; 3286 } 3287 eRet = OMX_ErrorInsufficientResources; 3288 } 3289 } 3290 3291 for(i=0; i< m_out_buf_count; i++) 3292 { 3293 if(BITMASK_ABSENT(&m_out_bm_count,i)) 3294 { 3295 break; 3296 } 3297 } 3298 3299 if (eRet == OMX_ErrorNone) 3300 { 3301 if(i < m_out_buf_count) 3302 { 3303 driver_context.ptr_outputbuffer[i].pmem_fd = \ 3304 open ("/dev/pmem_adsp", O_RDWR | O_SYNC); 3305 3306 if (driver_context.ptr_outputbuffer[i].pmem_fd < 0) 3307 { 3308 return OMX_ErrorInsufficientResources; 3309 } 3310 3311 if(driver_context.ptr_outputbuffer[i].pmem_fd == 0) 3312 { 3313 driver_context.ptr_outputbuffer[i].pmem_fd = \ 3314 open ("/dev/pmem_adsp", O_RDWR | O_SYNC); 3315 3316 if (driver_context.ptr_outputbuffer[i].pmem_fd < 0) 3317 { 3318 return OMX_ErrorInsufficientResources; 3319 } 3320 } 3321 3322 if(!align_pmem_buffers(driver_context.ptr_outputbuffer[i].pmem_fd, 3323 m_out_buf_size, driver_context.output_buffer.alignment)) 3324 { 3325 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed"); 3326 close(driver_context.ptr_outputbuffer[i].pmem_fd); 3327 return OMX_ErrorInsufficientResources; 3328 } 3329 3330 driver_context.ptr_outputbuffer[i].bufferaddr = 3331 (unsigned char *)mmap(NULL,m_out_buf_size,PROT_READ|PROT_WRITE, 3332 MAP_SHARED,driver_context.ptr_outputbuffer[i].pmem_fd,0); 3333 3334 if (driver_context.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) 3335 { 3336 return OMX_ErrorInsufficientResources; 3337 } 3338 driver_context.ptr_outputbuffer[i].offset = 0; 3339 m_pmem_info[i].offset = driver_context.ptr_outputbuffer[i].offset; 3340 m_pmem_info[i].pmem_fd = driver_context.ptr_outputbuffer[i].pmem_fd; 3341 3342 // found an empty buffer at i 3343 *bufferHdr = (m_out_mem_ptr + i ); 3344 (*bufferHdr)->pBuffer = buffer; 3345 (*bufferHdr)->pAppPrivate = appData; 3346 BITMASK_SET(&m_out_bm_count,i); 3347 } 3348 else 3349 { 3350 DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient \n"); 3351 eRet = OMX_ErrorInsufficientResources; 3352 } 3353 } 3354 3355 return eRet; 3356 } 3357 3358 /* ====================================================================== 3359 FUNCTION 3360 omx_vdec::UseBuffer 3361 3362 DESCRIPTION 3363 OMX Use Buffer method implementation. 3364 3365 PARAMETERS 3366 <TBD>. 3367 3368 RETURN VALUE 3369 OMX Error None , if everything successful. 3370 3371 ========================================================================== */ 3372 OMX_ERRORTYPE omx_vdec::use_buffer( 3373 OMX_IN OMX_HANDLETYPE hComp, 3374 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 3375 OMX_IN OMX_U32 port, 3376 OMX_IN OMX_PTR appData, 3377 OMX_IN OMX_U32 bytes, 3378 OMX_IN OMX_U8* buffer) 3379 { 3380 OMX_ERRORTYPE eRet = OMX_ErrorNone; 3381 if(m_state == OMX_StateInvalid) 3382 { 3383 DEBUG_PRINT_ERROR("Use Buffer in Invalid State\n"); 3384 return OMX_ErrorInvalidState; 3385 } 3386 if(port == OMX_CORE_INPUT_PORT_INDEX) 3387 { 3388 eRet = use_input_buffer(hComp,bufferHdr,port,appData,bytes,buffer); 3389 } 3390 else if(port == OMX_CORE_OUTPUT_PORT_INDEX) 3391 { 3392 eRet = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); 3393 } 3394 else 3395 { 3396 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port); 3397 eRet = OMX_ErrorBadPortIndex; 3398 } 3399 DEBUG_PRINT_LOW("Use Buffer: port %u, buffer %p, eRet %d", port, *bufferHdr, eRet); 3400 3401 if(eRet == OMX_ErrorNone) 3402 { 3403 if(allocate_done()) 3404 { 3405 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) 3406 { 3407 // Send the callback now 3408 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING); 3409 post_event(OMX_CommandStateSet,OMX_StateIdle, 3410 OMX_COMPONENT_GENERATE_EVENT); 3411 } 3412 } 3413 if(port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated) 3414 { 3415 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) 3416 { 3417 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING); 3418 post_event(OMX_CommandPortEnable, 3419 OMX_CORE_INPUT_PORT_INDEX, 3420 OMX_COMPONENT_GENERATE_EVENT); 3421 } 3422 3423 } 3424 else if(port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated) 3425 { 3426 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) 3427 { 3428 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING); 3429 post_event(OMX_CommandPortEnable, 3430 OMX_CORE_OUTPUT_PORT_INDEX, 3431 OMX_COMPONENT_GENERATE_EVENT); 3432 m_event_port_settings_sent = false; 3433 } 3434 } 3435 } 3436 return eRet; 3437 } 3438 3439 OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr) 3440 { 3441 unsigned int index = 0; 3442 3443 if (bufferHdr == NULL || m_inp_mem_ptr == NULL) 3444 { 3445 return OMX_ErrorBadParameter; 3446 } 3447 3448 index = bufferHdr - m_inp_mem_ptr; 3449 DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index); 3450 3451 if (index < m_inp_buf_count && driver_context.ptr_inputbuffer) 3452 { 3453 DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index); 3454 if (driver_context.ptr_inputbuffer[index].pmem_fd > 0) 3455 { 3456 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; 3457 struct vdec_setbuffer_cmd setbuffers; 3458 setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT; 3459 memcpy (&setbuffers.buffer,&driver_context.ptr_inputbuffer[index], 3460 sizeof (vdec_bufferpayload)); 3461 ioctl_msg.inputparam = &setbuffers; 3462 ioctl_msg.outputparam = NULL; 3463 int ioctl_r = ioctl (driver_context.video_driver_fd, 3464 VDEC_IOCTL_FREE_BUFFER, &ioctl_msg); 3465 if (ioctl_r < 0) 3466 { 3467 DEBUG_PRINT_ERROR("\nVDEC_IOCTL_FREE_BUFFER returned error %d", ioctl_r); 3468 } 3469 3470 DEBUG_PRINT_LOW("\n unmap the input buffer fd=%d", 3471 driver_context.ptr_inputbuffer[index].pmem_fd); 3472 DEBUG_PRINT_LOW("\n unmap the input buffer size=%d address = %d", 3473 driver_context.ptr_inputbuffer[index].mmaped_size, 3474 driver_context.ptr_inputbuffer[index].bufferaddr); 3475 munmap (driver_context.ptr_inputbuffer[index].bufferaddr, 3476 driver_context.ptr_inputbuffer[index].mmaped_size); 3477 close (driver_context.ptr_inputbuffer[index].pmem_fd); 3478 driver_context.ptr_inputbuffer[index].pmem_fd = -1; 3479 } 3480 } 3481 3482 return OMX_ErrorNone; 3483 } 3484 3485 OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr) 3486 { 3487 unsigned int index = 0; 3488 3489 if (bufferHdr == NULL || m_out_mem_ptr == NULL) 3490 { 3491 return OMX_ErrorBadParameter; 3492 } 3493 3494 index = bufferHdr - m_out_mem_ptr; 3495 DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d",index); 3496 3497 if (index < m_out_buf_count && driver_context.ptr_outputbuffer) 3498 { 3499 DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d addr = %x", index, 3500 driver_context.ptr_outputbuffer[index].bufferaddr); 3501 3502 if (!gate_output_buffers) 3503 { 3504 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; 3505 struct vdec_setbuffer_cmd setbuffers; 3506 setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT; 3507 memcpy (&setbuffers.buffer,&driver_context.ptr_outputbuffer[index], 3508 sizeof (vdec_bufferpayload)); 3509 ioctl_msg.inputparam = &setbuffers; 3510 ioctl_msg.outputparam = NULL; 3511 DEBUG_PRINT_LOW("\nRelease the Output Buffer"); 3512 if (ioctl (driver_context.video_driver_fd, VDEC_IOCTL_FREE_BUFFER, 3513 &ioctl_msg) < 0) 3514 DEBUG_PRINT_ERROR("\nRelease output buffer failed in VCD"); 3515 } 3516 3517 if (driver_context.ptr_outputbuffer[0].pmem_fd > 0) 3518 { 3519 DEBUG_PRINT_LOW("\n unmap the output buffer fd = %d", 3520 driver_context.ptr_outputbuffer[0].pmem_fd); 3521 DEBUG_PRINT_LOW("\n unmap the ouput buffer size=%d address = %d", 3522 driver_context.ptr_outputbuffer[0].mmaped_size, 3523 driver_context.ptr_outputbuffer[0].bufferaddr); 3524 munmap (driver_context.ptr_outputbuffer[0].bufferaddr, 3525 driver_context.ptr_outputbuffer[0].mmaped_size); 3526 close (driver_context.ptr_outputbuffer[0].pmem_fd); 3527 driver_context.ptr_outputbuffer[0].pmem_fd = -1; 3528 } 3529 } 3530 3531 return OMX_ErrorNone; 3532 3533 } 3534 3535 OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE hComp, 3536 OMX_BUFFERHEADERTYPE **bufferHdr, 3537 OMX_U32 port, 3538 OMX_PTR appData, 3539 OMX_U32 bytes) 3540 { 3541 OMX_BUFFERHEADERTYPE *input = NULL; 3542 unsigned char *buf_addr = NULL; 3543 OMX_ERRORTYPE eRet = OMX_ErrorNone; 3544 unsigned i = 0; 3545 3546 /* Sanity Check*/ 3547 if (bufferHdr == NULL) 3548 { 3549 return OMX_ErrorBadParameter; 3550 } 3551 3552 if (m_inp_heap_ptr == NULL) 3553 { 3554 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \ 3555 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), m_inp_buf_count); 3556 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \ 3557 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)), m_inp_buf_count); 3558 3559 if (m_inp_heap_ptr == NULL) 3560 { 3561 DEBUG_PRINT_ERROR("\n m_inp_heap_ptr Allocation failed "); 3562 return OMX_ErrorInsufficientResources; 3563 } 3564 3565 h264_scratch.nAllocLen = m_inp_buf_size; 3566 h264_scratch.pBuffer = (OMX_U8 *)malloc (m_inp_buf_size); 3567 h264_scratch.nFilledLen = 0; 3568 h264_scratch.nOffset = 0; 3569 3570 if (h264_scratch.pBuffer == NULL) 3571 { 3572 DEBUG_PRINT_ERROR("\n h264_scratch.pBuffer Allocation failed "); 3573 return OMX_ErrorInsufficientResources; 3574 } 3575 3576 if (m_frame_parser.mutils == NULL) 3577 { 3578 m_frame_parser.mutils = new H264_Utils(); 3579 3580 if (m_frame_parser.mutils == NULL) 3581 { 3582 DEBUG_PRINT_ERROR("\n parser utils Allocation failed "); 3583 return OMX_ErrorInsufficientResources; 3584 } 3585 3586 m_frame_parser.mutils->initialize_frame_checking_environment(); 3587 m_frame_parser.mutils->allocate_rbsp_buffer (m_inp_buf_size); 3588 } 3589 } 3590 3591 /*Find a Free index*/ 3592 for(i=0; i< m_inp_buf_count; i++) 3593 { 3594 if(BITMASK_ABSENT(&m_heap_inp_bm_count,i)) 3595 { 3596 DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i); 3597 break; 3598 } 3599 } 3600 3601 if (i < m_inp_buf_count) 3602 { 3603 buf_addr = (unsigned char *)malloc (m_inp_buf_size); 3604 3605 if (buf_addr == NULL) 3606 { 3607 return OMX_ErrorInsufficientResources; 3608 } 3609 3610 *bufferHdr = (m_inp_heap_ptr + i); 3611 input = *bufferHdr; 3612 BITMASK_SET(&m_heap_inp_bm_count,i); 3613 3614 input->pBuffer = (OMX_U8 *)buf_addr; 3615 input->nSize = sizeof(OMX_BUFFERHEADERTYPE); 3616 input->nVersion.nVersion = OMX_SPEC_VERSION; 3617 input->nAllocLen = m_inp_buf_size; 3618 input->pAppPrivate = appData; 3619 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX; 3620 DEBUG_PRINT_LOW("\n Address of Heap Buffer %p",*bufferHdr ); 3621 eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes); 3622 DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",m_phdr_pmem_ptr [i] ); 3623 /*Add the Buffers to freeq*/ 3624 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr [i],NULL,NULL)) 3625 { 3626 DEBUG_PRINT_ERROR("\nERROR:Free_q is full"); 3627 return OMX_ErrorInsufficientResources; 3628 } 3629 } 3630 else 3631 { 3632 return OMX_ErrorBadParameter; 3633 } 3634 3635 return eRet; 3636 3637 } 3638 3639 3640 /* ====================================================================== 3641 FUNCTION 3642 omx_vdec::AllocateInputBuffer 3643 3644 DESCRIPTION 3645 Helper function for allocate buffer in the input pin 3646 3647 PARAMETERS 3648 None. 3649 3650 RETURN VALUE 3651 true/false 3652 3653 ========================================================================== */ 3654 OMX_ERRORTYPE omx_vdec::allocate_input_buffer( 3655 OMX_IN OMX_HANDLETYPE hComp, 3656 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 3657 OMX_IN OMX_U32 port, 3658 OMX_IN OMX_PTR appData, 3659 OMX_IN OMX_U32 bytes) 3660 { 3661 3662 OMX_ERRORTYPE eRet = OMX_ErrorNone; 3663 struct vdec_setbuffer_cmd setbuffers; 3664 OMX_BUFFERHEADERTYPE *input = NULL; 3665 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; 3666 unsigned i = 0; 3667 unsigned char *buf_addr = NULL; 3668 int pmem_fd = -1; 3669 3670 if(bytes != m_inp_buf_size) 3671 { 3672 DEBUG_PRINT_LOW("\n Requested Size is wrong %d epected is %d",bytes,m_inp_buf_size); 3673 //return OMX_ErrorBadParameter; 3674 } 3675 3676 if(!m_inp_mem_ptr) 3677 { 3678 DEBUG_PRINT_HIGH("\n Allocate i/p buffer case - Header List allocation"); 3679 DEBUG_PRINT_LOW("\n Allocating input buffer count %d ",m_inp_buf_count); 3680 DEBUG_PRINT_LOW("\n Size of input buffer is %d",m_inp_buf_size); 3681 3682 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \ 3683 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), m_inp_buf_count); 3684 3685 if (m_inp_mem_ptr == NULL) 3686 { 3687 return OMX_ErrorInsufficientResources; 3688 } 3689 3690 driver_context.ptr_inputbuffer = (struct vdec_bufferpayload *) \ 3691 calloc ((sizeof (struct vdec_bufferpayload)),m_inp_buf_count); 3692 3693 if (driver_context.ptr_inputbuffer == NULL) 3694 { 3695 return OMX_ErrorInsufficientResources; 3696 } 3697 3698 for (i=0; i < m_inp_buf_count; i++) 3699 { 3700 driver_context.ptr_inputbuffer [i].pmem_fd = -1; 3701 } 3702 } 3703 3704 for(i=0; i< m_inp_buf_count; i++) 3705 { 3706 if(BITMASK_ABSENT(&m_inp_bm_count,i)) 3707 { 3708 DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i); 3709 break; 3710 } 3711 } 3712 3713 if(i < m_inp_buf_count) 3714 { 3715 DEBUG_PRINT_LOW("\n Allocate input Buffer"); 3716 pmem_fd = open ("/dev/pmem_adsp", O_RDWR, O_SYNC); 3717 3718 if (pmem_fd < 0) 3719 { 3720 DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer"); 3721 return OMX_ErrorInsufficientResources; 3722 } 3723 3724 if (pmem_fd == 0) 3725 { 3726 pmem_fd = open ("/dev/pmem_adsp", O_RDWR | O_SYNC); 3727 3728 if (pmem_fd < 0) 3729 { 3730 DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer"); 3731 return OMX_ErrorInsufficientResources; 3732 } 3733 } 3734 3735 if(!align_pmem_buffers(pmem_fd, m_inp_buf_size, 3736 driver_context.input_buffer.alignment)) 3737 { 3738 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed"); 3739 close(pmem_fd); 3740 return OMX_ErrorInsufficientResources; 3741 } 3742 3743 buf_addr = (unsigned char *)mmap(NULL,m_inp_buf_size,PROT_READ|PROT_WRITE, 3744 MAP_SHARED,pmem_fd,0); 3745 3746 if (buf_addr == MAP_FAILED) 3747 { 3748 DEBUG_PRINT_ERROR("\n Map Failed to allocate input buffer"); 3749 return OMX_ErrorInsufficientResources; 3750 } 3751 3752 driver_context.ptr_inputbuffer [i].bufferaddr = buf_addr; 3753 driver_context.ptr_inputbuffer [i].pmem_fd = pmem_fd; 3754 driver_context.ptr_inputbuffer [i].buffer_len = m_inp_buf_size; 3755 driver_context.ptr_inputbuffer [i].mmaped_size = m_inp_buf_size; 3756 driver_context.ptr_inputbuffer [i].offset = 0; 3757 3758 setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT; 3759 memcpy (&setbuffers.buffer,&driver_context.ptr_inputbuffer [i], 3760 sizeof (vdec_bufferpayload)); 3761 ioctl_msg.inputparam = &setbuffers; 3762 ioctl_msg.outputparam = NULL; 3763 3764 if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_SET_BUFFER, 3765 &ioctl_msg) < 0) 3766 { 3767 DEBUG_PRINT_ERROR("\n Set Buffers Failed"); 3768 return OMX_ErrorInsufficientResources; 3769 } 3770 3771 *bufferHdr = (m_inp_mem_ptr + i); 3772 input = *bufferHdr; 3773 BITMASK_SET(&m_inp_bm_count,i); 3774 DEBUG_PRINT_LOW("\n Buffer address %p of pmem",*bufferHdr); 3775 3776 input->pBuffer = (OMX_U8 *)buf_addr; 3777 input->nSize = sizeof(OMX_BUFFERHEADERTYPE); 3778 input->nVersion.nVersion = OMX_SPEC_VERSION; 3779 input->nAllocLen = m_inp_buf_size; 3780 input->pAppPrivate = appData; 3781 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX; 3782 input->pInputPortPrivate = (void *)&driver_context.ptr_inputbuffer [i]; 3783 } 3784 else 3785 { 3786 DEBUG_PRINT_ERROR("\nERROR:Input Buffer Index not found"); 3787 eRet = OMX_ErrorInsufficientResources; 3788 } 3789 return eRet; 3790 } 3791 3792 3793 /* ====================================================================== 3794 FUNCTION 3795 omx_vdec::AllocateOutputBuffer 3796 3797 DESCRIPTION 3798 Helper fn for AllocateBuffer in the output pin 3799 3800 PARAMETERS 3801 <TBD>. 3802 3803 RETURN VALUE 3804 OMX Error None if everything went well. 3805 3806 ========================================================================== */ 3807 OMX_ERRORTYPE omx_vdec::allocate_output_buffer( 3808 OMX_IN OMX_HANDLETYPE hComp, 3809 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 3810 OMX_IN OMX_U32 port, 3811 OMX_IN OMX_PTR appData, 3812 OMX_IN OMX_U32 bytes) 3813 { 3814 OMX_ERRORTYPE eRet = OMX_ErrorNone; 3815 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header 3816 unsigned i= 0; // Temporary counter 3817 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; 3818 struct vdec_setbuffer_cmd setbuffers; 3819 3820 if(!m_out_mem_ptr) 3821 { 3822 DEBUG_PRINT_HIGH("\n Allocate o/p buffer case - Header List allocation"); 3823 int nBufHdrSize = 0; 3824 int nPlatformEntrySize = 0; 3825 int nPlatformListSize = 0; 3826 int nPMEMInfoSize = 0; 3827 int pmem_fd = -1; 3828 unsigned char *pmem_baseaddress = NULL; 3829 3830 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList; 3831 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry; 3832 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo; 3833 3834 DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)\n",m_out_buf_count); 3835 nBufHdrSize = m_out_buf_count * sizeof(OMX_BUFFERHEADERTYPE); 3836 3837 nPMEMInfoSize = m_out_buf_count * 3838 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO); 3839 nPlatformListSize = m_out_buf_count * 3840 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST); 3841 nPlatformEntrySize = m_out_buf_count * 3842 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY); 3843 3844 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize, 3845 sizeof(OMX_BUFFERHEADERTYPE), 3846 nPMEMInfoSize, 3847 nPlatformListSize); 3848 DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d \n",nPlatformEntrySize, 3849 m_out_buf_count); 3850 3851 pmem_fd = open ("/dev/pmem_adsp", O_RDWR | O_SYNC); 3852 3853 if (pmem_fd < 0) 3854 { 3855 DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d",m_out_buf_size); 3856 return OMX_ErrorInsufficientResources; 3857 } 3858 3859 if(pmem_fd == 0) 3860 { 3861 pmem_fd = open ("/dev/pmem_adsp", O_RDWR | O_SYNC); 3862 3863 if (pmem_fd < 0) 3864 { 3865 DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d",m_out_buf_size); 3866 return OMX_ErrorInsufficientResources; 3867 } 3868 } 3869 3870 if(!align_pmem_buffers(pmem_fd, m_out_buf_size * m_out_buf_count, 3871 driver_context.output_buffer.alignment)) 3872 { 3873 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed"); 3874 close(pmem_fd); 3875 return OMX_ErrorInsufficientResources; 3876 } 3877 3878 pmem_baseaddress = (unsigned char *)mmap(NULL,(m_out_buf_size * m_out_buf_count), 3879 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0); 3880 m_heap_ptr = new VideoHeap (pmem_fd, 3881 m_out_buf_size*m_out_buf_count, 3882 pmem_baseaddress); 3883 3884 3885 if (pmem_baseaddress == MAP_FAILED) 3886 { 3887 DEBUG_PRINT_ERROR("\n MMAP failed for Size %d",m_out_buf_size); 3888 return OMX_ErrorInsufficientResources; 3889 } 3890 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1); 3891 // Alloc mem for platform specific info 3892 char *pPtr=NULL; 3893 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize + 3894 nPMEMInfoSize,1); 3895 driver_context.ptr_outputbuffer = (struct vdec_bufferpayload *) \ 3896 calloc (sizeof(struct vdec_bufferpayload),m_out_buf_count); 3897 driver_context.ptr_respbuffer = (struct vdec_output_frameinfo *)\ 3898 calloc (sizeof (struct vdec_output_frameinfo),m_out_buf_count); 3899 3900 if(m_out_mem_ptr && pPtr && driver_context.ptr_outputbuffer 3901 && driver_context.ptr_respbuffer) 3902 { 3903 driver_context.ptr_outputbuffer[0].mmaped_size = 3904 (m_out_buf_size * m_out_buf_count); 3905 bufHdr = m_out_mem_ptr; 3906 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr); 3907 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *) 3908 (((char *) m_platform_list) + nPlatformListSize); 3909 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) 3910 (((char *) m_platform_entry) + nPlatformEntrySize); 3911 pPlatformList = m_platform_list; 3912 pPlatformEntry = m_platform_entry; 3913 pPMEMInfo = m_pmem_info; 3914 3915 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr); 3916 3917 // Settting the entire storage nicely 3918 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr, m_out_mem_ptr,pPlatformEntry); 3919 DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo); 3920 for(i=0; i < m_out_buf_count ; i++) 3921 { 3922 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE); 3923 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION; 3924 // Set the values when we determine the right HxW param 3925 bufHdr->nAllocLen = bytes; 3926 bufHdr->nFilledLen = 0; 3927 bufHdr->pAppPrivate = appData; 3928 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; 3929 // Platform specific PMEM Information 3930 // Initialize the Platform Entry 3931 //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d\n",i); 3932 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM; 3933 pPlatformEntry->entry = pPMEMInfo; 3934 // Initialize the Platform List 3935 pPlatformList->nEntries = 1; 3936 pPlatformList->entryList = pPlatformEntry; 3937 // Keep pBuffer NULL till vdec is opened 3938 bufHdr->pBuffer = NULL; 3939 bufHdr->nOffset = 0; 3940 3941 pPMEMInfo->offset = m_out_buf_size*i; 3942 pPMEMInfo->pmem_fd = 0; 3943 bufHdr->pPlatformPrivate = pPlatformList; 3944 3945 driver_context.ptr_outputbuffer[i].pmem_fd = pmem_fd; 3946 3947 /*Create a mapping between buffers*/ 3948 bufHdr->pOutputPortPrivate = &driver_context.ptr_respbuffer[i]; 3949 driver_context.ptr_respbuffer[i].client_data = (void *) \ 3950 &driver_context.ptr_outputbuffer[i]; 3951 driver_context.ptr_outputbuffer[i].offset = m_out_buf_size*i; 3952 driver_context.ptr_outputbuffer[i].bufferaddr = \ 3953 pmem_baseaddress + (m_out_buf_size*i); 3954 3955 DEBUG_PRINT_LOW("\n pmem_fd = %d offset = %d address = %p",\ 3956 pmem_fd,driver_context.ptr_outputbuffer[i].offset,driver_context.ptr_outputbuffer[i].bufferaddr); 3957 // Move the buffer and buffer header pointers 3958 bufHdr++; 3959 pPMEMInfo++; 3960 pPlatformEntry++; 3961 pPlatformList++; 3962 } 3963 } 3964 else 3965 { 3966 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%x][0x%x]\n",\ 3967 m_out_mem_ptr, pPtr); 3968 if(m_out_mem_ptr) 3969 { 3970 free(m_out_mem_ptr); 3971 m_out_mem_ptr = NULL; 3972 } 3973 if(pPtr) 3974 { 3975 free(pPtr); 3976 pPtr = NULL; 3977 } 3978 if(driver_context.ptr_outputbuffer) 3979 { 3980 free(driver_context.ptr_outputbuffer); 3981 driver_context.ptr_outputbuffer = NULL; 3982 } 3983 if(driver_context.ptr_respbuffer) 3984 { 3985 free(driver_context.ptr_respbuffer); 3986 driver_context.ptr_respbuffer = NULL; 3987 } 3988 eRet = OMX_ErrorInsufficientResources; 3989 } 3990 } 3991 3992 for(i=0; i< m_out_buf_count; i++) 3993 { 3994 if(BITMASK_ABSENT(&m_out_bm_count,i)) 3995 { 3996 DEBUG_PRINT_LOW("\n Found a Free Output Buffer %d",i); 3997 break; 3998 } 3999 } 4000 4001 if (eRet == OMX_ErrorNone) 4002 { 4003 if(i < m_out_buf_count) 4004 { 4005 m_pmem_info[i].offset = driver_context.ptr_outputbuffer[i].offset; 4006 m_pmem_info[i].pmem_fd = (OMX_U32) m_heap_ptr.get (); 4007 driver_context.ptr_outputbuffer[i].buffer_len = m_out_buf_size; 4008 //driver_context.ptr_outputbuffer[i].mmaped_size = m_out_buf_size; 4009 if(!gate_output_buffers) 4010 { 4011 setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT; 4012 memcpy (&setbuffers.buffer,&driver_context.ptr_outputbuffer [i], 4013 sizeof (vdec_bufferpayload)); 4014 ioctl_msg.inputparam = &setbuffers; 4015 ioctl_msg.outputparam = NULL; 4016 4017 DEBUG_PRINT_LOW("\n Set the Output Buffer"); 4018 if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_SET_BUFFER, 4019 &ioctl_msg) < 0) 4020 { 4021 DEBUG_PRINT_ERROR("\n Set output buffer failed"); 4022 return OMX_ErrorInsufficientResources; 4023 } 4024 } 4025 4026 // found an empty buffer at i 4027 *bufferHdr = (m_out_mem_ptr + i ); 4028 (*bufferHdr)->pBuffer = driver_context.ptr_outputbuffer[i].bufferaddr; 4029 (*bufferHdr)->pAppPrivate = appData; 4030 BITMASK_SET(&m_out_bm_count,i); 4031 } 4032 else 4033 { 4034 DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient \n"); 4035 eRet = OMX_ErrorInsufficientResources; 4036 } 4037 } 4038 4039 return eRet; 4040 } 4041 4042 4043 // AllocateBuffer -- API Call 4044 /* ====================================================================== 4045 FUNCTION 4046 omx_vdec::AllocateBuffer 4047 4048 DESCRIPTION 4049 Returns zero if all the buffers released.. 4050 4051 PARAMETERS 4052 None. 4053 4054 RETURN VALUE 4055 true/false 4056 4057 ========================================================================== */ 4058 OMX_ERRORTYPE omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp, 4059 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 4060 OMX_IN OMX_U32 port, 4061 OMX_IN OMX_PTR appData, 4062 OMX_IN OMX_U32 bytes) 4063 { 4064 unsigned i = 0; 4065 OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type 4066 4067 DEBUG_PRINT_LOW("\n Allocate buffer on port %d \n", (int)port); 4068 if(m_state == OMX_StateInvalid) 4069 { 4070 DEBUG_PRINT_ERROR("Allocate Buf in Invalid State\n"); 4071 return OMX_ErrorInvalidState; 4072 } 4073 4074 if(port == OMX_CORE_INPUT_PORT_INDEX) 4075 { 4076 if (arbitrary_bytes) 4077 { 4078 eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes); 4079 } 4080 else 4081 { 4082 eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes); 4083 } 4084 } 4085 else if(port == OMX_CORE_OUTPUT_PORT_INDEX) 4086 { 4087 eRet = allocate_output_buffer(hComp,bufferHdr,port,appData,bytes); 4088 } 4089 else 4090 { 4091 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port); 4092 eRet = OMX_ErrorBadPortIndex; 4093 } 4094 DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done"); 4095 if(eRet == OMX_ErrorNone) 4096 { 4097 if(allocate_done()){ 4098 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) 4099 { 4100 // Send the callback now 4101 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING); 4102 post_event(OMX_CommandStateSet,OMX_StateIdle, 4103 OMX_COMPONENT_GENERATE_EVENT); 4104 } 4105 } 4106 if(port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated) 4107 { 4108 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) 4109 { 4110 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING); 4111 post_event(OMX_CommandPortEnable, 4112 OMX_CORE_INPUT_PORT_INDEX, 4113 OMX_COMPONENT_GENERATE_EVENT); 4114 } 4115 } 4116 if(port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated) 4117 { 4118 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) 4119 { 4120 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING); 4121 post_event(OMX_CommandPortEnable, 4122 OMX_CORE_OUTPUT_PORT_INDEX, 4123 OMX_COMPONENT_GENERATE_EVENT); 4124 m_event_port_settings_sent = false; 4125 } 4126 } 4127 } 4128 DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d\n",eRet); 4129 return eRet; 4130 } 4131 4132 // Free Buffer - API call 4133 /* ====================================================================== 4134 FUNCTION 4135 omx_vdec::FreeBuffer 4136 4137 DESCRIPTION 4138 4139 PARAMETERS 4140 None. 4141 4142 RETURN VALUE 4143 true/false 4144 4145 ========================================================================== */ 4146 OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp, 4147 OMX_IN OMX_U32 port, 4148 OMX_IN OMX_BUFFERHEADERTYPE* buffer) 4149 { 4150 OMX_ERRORTYPE eRet = OMX_ErrorNone; 4151 unsigned int nPortIndex; 4152 4153 DEBUG_PRINT_LOW("In for decoder free_buffer \n"); 4154 4155 if(m_state == OMX_StateIdle && 4156 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) 4157 { 4158 DEBUG_PRINT_LOW(" free buffer while Component in Loading pending\n"); 4159 } 4160 else if((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)|| 4161 (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX)) 4162 { 4163 DEBUG_PRINT_LOW("Free Buffer while port %d disabled\n", port); 4164 } 4165 else if(m_state == OMX_StateExecuting || m_state == OMX_StatePause) 4166 { 4167 DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled\n"); 4168 post_event(OMX_EventError, 4169 OMX_ErrorPortUnpopulated, 4170 OMX_COMPONENT_GENERATE_EVENT); 4171 4172 return eRet; 4173 } 4174 else if (m_state != OMX_StateInvalid) 4175 { 4176 DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers\n"); 4177 post_event(OMX_EventError, 4178 OMX_ErrorPortUnpopulated, 4179 OMX_COMPONENT_GENERATE_EVENT); 4180 } 4181 4182 if(port == OMX_CORE_INPUT_PORT_INDEX) 4183 { 4184 /*Check if arbitrary bytes*/ 4185 if (!arbitrary_bytes) 4186 { 4187 // check if the buffer is valid 4188 nPortIndex = buffer - m_inp_mem_ptr; 4189 } 4190 else 4191 { 4192 nPortIndex = buffer - m_inp_heap_ptr; 4193 } 4194 4195 DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d \n", nPortIndex); 4196 if(nPortIndex < m_inp_buf_count) 4197 { 4198 // Clear the bit associated with it. 4199 BITMASK_CLEAR(&m_inp_bm_count,nPortIndex); 4200 4201 if (arbitrary_bytes) 4202 { 4203 if (m_inp_heap_ptr[nPortIndex].pBuffer) 4204 { 4205 BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex); 4206 DEBUG_PRINT_LOW("\n Free Heap Buffer index %d",nPortIndex); 4207 free (m_inp_heap_ptr[nPortIndex].pBuffer); 4208 m_inp_heap_ptr[nPortIndex].pBuffer = NULL; 4209 } 4210 if (m_phdr_pmem_ptr[nPortIndex]) 4211 { 4212 DEBUG_PRINT_LOW("\n Free pmem Buffer index %d",nPortIndex); 4213 free_input_buffer(m_phdr_pmem_ptr[nPortIndex]); 4214 } 4215 } 4216 else 4217 { 4218 free_input_buffer(buffer); 4219 } 4220 4221 m_inp_bPopulated = OMX_FALSE; 4222 4223 /*Free the Buffer Header*/ 4224 if (release_input_done()) 4225 { 4226 DEBUG_PRINT_HIGH("\n ALL input buffers are freed/released"); 4227 input_use_buffer = false; 4228 if (arbitrary_bytes) 4229 { 4230 if (m_frame_parser.mutils) 4231 { 4232 DEBUG_PRINT_LOW("\n Free utils parser"); 4233 delete (m_frame_parser.mutils); 4234 m_frame_parser.mutils = NULL; 4235 } 4236 4237 if (m_inp_heap_ptr) 4238 { 4239 DEBUG_PRINT_LOW("\n Free input Heap Pointer"); 4240 free (m_inp_heap_ptr); 4241 m_inp_heap_ptr = NULL; 4242 } 4243 4244 if (m_phdr_pmem_ptr) 4245 { 4246 DEBUG_PRINT_LOW("\n Free input pmem header Pointer"); 4247 free (m_phdr_pmem_ptr); 4248 m_phdr_pmem_ptr = NULL; 4249 } 4250 } 4251 if (m_inp_mem_ptr) 4252 { 4253 DEBUG_PRINT_LOW("\n Free input pmem Pointer area"); 4254 free (m_inp_mem_ptr); 4255 m_inp_mem_ptr = NULL; 4256 } 4257 4258 if (driver_context.ptr_inputbuffer) 4259 { 4260 DEBUG_PRINT_LOW("\n Free Driver Context pointer"); 4261 free (driver_context.ptr_inputbuffer); 4262 driver_context.ptr_inputbuffer = NULL; 4263 } 4264 } 4265 4266 } 4267 else 4268 { 4269 DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid\n"); 4270 eRet = OMX_ErrorBadPortIndex; 4271 } 4272 4273 if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING) 4274 && release_input_done()) 4275 { 4276 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n"); 4277 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING); 4278 post_event(OMX_CommandPortDisable, 4279 OMX_CORE_INPUT_PORT_INDEX, 4280 OMX_COMPONENT_GENERATE_EVENT); 4281 } 4282 } 4283 else if(port == OMX_CORE_OUTPUT_PORT_INDEX) 4284 { 4285 // check if the buffer is valid 4286 nPortIndex = buffer - (OMX_BUFFERHEADERTYPE*)m_out_mem_ptr; 4287 if(nPortIndex < m_out_buf_count) 4288 { 4289 DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d \n", nPortIndex); 4290 // Clear the bit associated with it. 4291 BITMASK_CLEAR(&m_out_bm_count,nPortIndex); 4292 m_out_bPopulated = OMX_FALSE; 4293 free_output_buffer (buffer); 4294 4295 if (release_output_done()) 4296 { 4297 DEBUG_PRINT_HIGH("\n ALL output buffers are freed/released"); 4298 output_use_buffer = false; 4299 if (m_out_mem_ptr) 4300 { 4301 free (m_out_mem_ptr); 4302 m_out_mem_ptr = NULL; 4303 } 4304 if (driver_context.ptr_respbuffer) 4305 { 4306 free (driver_context.ptr_respbuffer); 4307 driver_context.ptr_respbuffer = NULL; 4308 } 4309 if (driver_context.ptr_outputbuffer) 4310 { 4311 free (driver_context.ptr_outputbuffer); 4312 driver_context.ptr_outputbuffer = NULL; 4313 } 4314 } 4315 } 4316 else 4317 { 4318 DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid\n"); 4319 eRet = OMX_ErrorBadPortIndex; 4320 } 4321 if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING) 4322 && release_output_done() ) 4323 { 4324 DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it\n"); 4325 4326 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n"); 4327 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING); 4328 post_event(OMX_CommandPortDisable, 4329 OMX_CORE_OUTPUT_PORT_INDEX, 4330 OMX_COMPONENT_GENERATE_EVENT); 4331 } 4332 } 4333 else 4334 { 4335 eRet = OMX_ErrorBadPortIndex; 4336 } 4337 if((eRet == OMX_ErrorNone) && 4338 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) 4339 { 4340 if(release_done()) 4341 { 4342 // Send the callback now 4343 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING); 4344 post_event(OMX_CommandStateSet, OMX_StateLoaded, 4345 OMX_COMPONENT_GENERATE_EVENT); 4346 } 4347 } 4348 return eRet; 4349 } 4350 4351 4352 /* ====================================================================== 4353 FUNCTION 4354 omx_vdec::EmptyThisBuffer 4355 4356 DESCRIPTION 4357 This routine is used to push the encoded video frames to 4358 the video decoder. 4359 4360 PARAMETERS 4361 None. 4362 4363 RETURN VALUE 4364 OMX Error None if everything went successful. 4365 4366 ========================================================================== */ 4367 OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp, 4368 OMX_IN OMX_BUFFERHEADERTYPE* buffer) 4369 { 4370 OMX_ERRORTYPE ret1 = OMX_ErrorNone; 4371 unsigned int nBufferIndex = m_inp_buf_count; 4372 4373 if(m_state == OMX_StateInvalid) 4374 { 4375 DEBUG_PRINT_ERROR("Empty this buffer in Invalid State\n"); 4376 return OMX_ErrorInvalidState; 4377 } 4378 4379 if (buffer == NULL) 4380 { 4381 DEBUG_PRINT_ERROR("\nERROR:ETB Buffer is NULL"); 4382 return OMX_ErrorBadParameter; 4383 } 4384 4385 if (arbitrary_bytes) 4386 { 4387 nBufferIndex = buffer - m_inp_heap_ptr; 4388 } 4389 else 4390 { 4391 nBufferIndex = buffer - m_inp_mem_ptr; 4392 } 4393 4394 if (nBufferIndex > m_inp_buf_count ) 4395 { 4396 DEBUG_PRINT_ERROR("\nERROR:ETB nBufferIndex is invalid"); 4397 return OMX_ErrorBadParameter; 4398 } 4399 4400 DEBUG_PRINT_LOW("\n ETB: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer); 4401 if (arbitrary_bytes) 4402 { 4403 post_event ((unsigned)hComp,(unsigned)buffer, 4404 OMX_COMPONENT_GENERATE_ETB_ARBITRARY); 4405 } 4406 else 4407 { 4408 post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB); 4409 } 4410 return OMX_ErrorNone; 4411 } 4412 4413 /* ====================================================================== 4414 FUNCTION 4415 omx_vdec::empty_this_buffer_proxy 4416 4417 DESCRIPTION 4418 This routine is used to push the encoded video frames to 4419 the video decoder. 4420 4421 PARAMETERS 4422 None. 4423 4424 RETURN VALUE 4425 OMX Error None if everything went successful. 4426 4427 ========================================================================== */ 4428 OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp, 4429 OMX_IN OMX_BUFFERHEADERTYPE* buffer) 4430 { 4431 int push_cnt = 0,i=0; 4432 unsigned nPortIndex = 0; 4433 OMX_ERRORTYPE ret = OMX_ErrorNone; 4434 struct vdec_input_frameinfo frameinfo; 4435 struct vdec_bufferpayload *temp_buffer; 4436 struct vdec_ioctl_msg ioctl_msg; 4437 struct vdec_seqheader seq_header; 4438 bool port_setting_changed = true; 4439 4440 /*Should we generate a Aync error event*/ 4441 if (buffer == NULL || buffer->pInputPortPrivate == NULL) 4442 { 4443 DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy is invalid"); 4444 return OMX_ErrorBadParameter; 4445 } 4446 4447 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr); 4448 4449 if (nPortIndex > m_inp_buf_count) 4450 { 4451 DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy invalid nPortIndex[%u]", 4452 nPortIndex); 4453 return OMX_ErrorBadParameter; 4454 } 4455 4456 pending_input_buffers++; 4457 4458 if( input_flush_progress == true || m_ineos_reached == 1) 4459 { 4460 DEBUG_PRINT_LOW("\n Flush in progress return buffer "); 4461 post_event ((unsigned int)buffer,VDEC_S_SUCCESS, 4462 OMX_COMPONENT_GENERATE_EBD); 4463 return OMX_ErrorNone; 4464 } 4465 4466 if(m_event_port_settings_sent && !arbitrary_bytes) 4467 { 4468 post_event((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB); 4469 return OMX_ErrorNone; 4470 } 4471 4472 temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate; 4473 4474 if ((temp_buffer - driver_context.ptr_inputbuffer) > m_inp_buf_count) 4475 { 4476 return OMX_ErrorBadParameter; 4477 } 4478 4479 DEBUG_PRINT_LOW("\n ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer); 4480 /*for use buffer we need to memcpy the data*/ 4481 temp_buffer->buffer_len = buffer->nFilledLen; 4482 4483 if (input_use_buffer) 4484 { 4485 if (buffer->nFilledLen <= temp_buffer->buffer_len) 4486 { 4487 memcpy (temp_buffer->bufferaddr,(buffer->pBuffer + buffer->nOffset), 4488 buffer->nFilledLen); 4489 } 4490 else 4491 { 4492 return OMX_ErrorBadParameter; 4493 } 4494 4495 } 4496 4497 if (!arbitrary_bytes && first_frame < 2 && codec_type_parse == CODEC_TYPE_MPEG4) 4498 { 4499 4500 if (first_frame == 0) 4501 { 4502 first_buffer = (unsigned char *)malloc (m_inp_buf_size); 4503 DEBUG_PRINT_LOW("\n Copied the first buffer data size %d ", 4504 temp_buffer->buffer_len); 4505 first_frame = 1; 4506 memcpy (first_buffer,temp_buffer->bufferaddr,temp_buffer->buffer_len); 4507 first_frame_size = buffer->nFilledLen; 4508 buffer->nFilledLen = 0; 4509 post_event ((unsigned int)buffer,VDEC_S_SUCCESS, 4510 OMX_COMPONENT_GENERATE_EBD); 4511 return OMX_ErrorNone; 4512 } 4513 else if (first_frame == 1) 4514 { 4515 first_frame = 2; 4516 DEBUG_PRINT_LOW("\n Second buffer copy the header size %d frame size %d", 4517 first_frame_size,temp_buffer->buffer_len); 4518 memcpy (&first_buffer [first_frame_size],temp_buffer->bufferaddr, 4519 temp_buffer->buffer_len); 4520 first_frame_size += temp_buffer->buffer_len; 4521 memcpy (temp_buffer->bufferaddr,first_buffer,first_frame_size); 4522 temp_buffer->buffer_len = first_frame_size; 4523 free (first_buffer); 4524 } 4525 } 4526 4527 frameinfo.bufferaddr = temp_buffer->bufferaddr; 4528 frameinfo.client_data = (void *) buffer; 4529 frameinfo.datalen = temp_buffer->buffer_len; 4530 frameinfo.flags = 0; 4531 frameinfo.offset = buffer->nOffset; 4532 frameinfo.pmem_fd = temp_buffer->pmem_fd; 4533 frameinfo.pmem_offset = temp_buffer->offset; 4534 frameinfo.timestamp = buffer->nTimeStamp; 4535 4536 #if BITSTREAM_LOG 4537 int bytes_written; 4538 bytes_written = fwrite((const char *)temp_buffer->bufferaddr, 4539 temp_buffer->buffer_len,1,outputBufferFile1); 4540 4541 #endif 4542 4543 if(!set_seq_header_done) 4544 { 4545 set_seq_header_done = true; 4546 DEBUG_PRINT_HIGH("\n Set Sequence Header"); 4547 seq_header.ptr_seqheader = frameinfo.bufferaddr; 4548 seq_header.seq_header_len = frameinfo.datalen; 4549 seq_header.pmem_fd = frameinfo.pmem_fd; 4550 seq_header.pmem_offset = frameinfo.pmem_offset; 4551 ioctl_msg.inputparam = &seq_header; 4552 ioctl_msg.outputparam = NULL; 4553 if (ioctl(driver_context.video_driver_fd,VDEC_IOCTL_SET_SEQUENCE_HEADER, 4554 &ioctl_msg) < 0) 4555 { 4556 DEBUG_PRINT_ERROR("\n Set Sequence Header Failed"); 4557 /*Generate an async error and move to invalid state*/ 4558 return OMX_ErrorBadParameter; 4559 } 4560 if(omx_vdec_check_port_settings (&port_setting_changed) != OMX_ErrorNone) 4561 { 4562 DEBUG_PRINT_ERROR("\n Check port setting failed"); 4563 return OMX_ErrorBadParameter; 4564 } 4565 4566 if(port_setting_changed) 4567 { 4568 DEBUG_PRINT_HIGH("\n Port settings changed"); 4569 m_event_port_settings_sent = true; 4570 m_cb.EventHandler(&m_cmp, m_app_data,OMX_EventPortSettingsChanged, 4571 OMX_CORE_OUTPUT_PORT_INDEX, 0, NULL ); 4572 DEBUG_PRINT_HIGH("\n EventHandler for Port Setting changed done"); 4573 return OMX_ErrorNone; 4574 } 4575 else 4576 { 4577 if(!register_output_buffers()) 4578 { 4579 DEBUG_PRINT_ERROR("\n register output failed"); 4580 return OMX_ErrorBadParameter; 4581 } 4582 DEBUG_PRINT_HIGH("\n Port settings Not changed"); 4583 } 4584 } 4585 4586 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & 0x01)) 4587 { 4588 DEBUG_PRINT_HIGH("\n Rxd i/p EOS, Notify Driver that EOS has been reached"); 4589 frameinfo.flags |= VDEC_BUFFERFLAG_EOS; 4590 m_ineos_reached = 1; 4591 } 4592 4593 sent_first_frame = true; 4594 DEBUG_PRINT_LOW("\n Decode Input Frame Size %d",frameinfo.datalen); 4595 ioctl_msg.inputparam = &frameinfo; 4596 ioctl_msg.outputparam = NULL; 4597 4598 if (ioctl(driver_context.video_driver_fd,VDEC_IOCTL_DECODE_FRAME, 4599 &ioctl_msg) < 0) 4600 { 4601 /*Generate an async error and move to invalid state*/ 4602 return OMX_ErrorBadParameter; 4603 } 4604 4605 return ret; 4606 } 4607 4608 /* ====================================================================== 4609 FUNCTION 4610 omx_vdec::FillThisBuffer 4611 4612 DESCRIPTION 4613 IL client uses this method to release the frame buffer 4614 after displaying them. 4615 4616 PARAMETERS 4617 None. 4618 4619 RETURN VALUE 4620 true/false 4621 4622 ========================================================================== */ 4623 OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp, 4624 OMX_IN OMX_BUFFERHEADERTYPE* buffer) 4625 { 4626 4627 if(m_state == OMX_StateInvalid) 4628 { 4629 DEBUG_PRINT_ERROR("FTB in Invalid State\n"); 4630 return OMX_ErrorInvalidState; 4631 } 4632 4633 if (buffer == NULL || ((buffer - m_out_mem_ptr) > m_out_buf_size)) 4634 { 4635 return OMX_ErrorBadParameter; 4636 } 4637 4638 DEBUG_PRINT_LOW("\n FTB: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer); 4639 post_event((unsigned) hComp, (unsigned)buffer,OMX_COMPONENT_GENERATE_FTB); 4640 return OMX_ErrorNone; 4641 } 4642 /* ====================================================================== 4643 FUNCTION 4644 omx_vdec::fill_this_buffer_proxy 4645 4646 DESCRIPTION 4647 IL client uses this method to release the frame buffer 4648 after displaying them. 4649 4650 PARAMETERS 4651 None. 4652 4653 RETURN VALUE 4654 true/false 4655 4656 ========================================================================== */ 4657 OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy( 4658 OMX_IN OMX_HANDLETYPE hComp, 4659 OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd) 4660 { 4661 OMX_ERRORTYPE nRet = OMX_ErrorNone; 4662 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; 4663 OMX_BUFFERHEADERTYPE *buffer = bufferAdd; 4664 struct vdec_fillbuffer_cmd fillbuffer; 4665 struct vdec_bufferpayload *ptr_outputbuffer = NULL; 4666 struct vdec_output_frameinfo *ptr_respbuffer = NULL; 4667 4668 4669 if (bufferAdd == NULL || ((buffer - m_out_mem_ptr) > m_out_buf_count) ) 4670 { 4671 return OMX_ErrorBadParameter; 4672 } 4673 4674 DEBUG_PRINT_LOW("\n FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p", 4675 bufferAdd, bufferAdd->pBuffer); 4676 /*Return back the output buffer to client*/ 4677 if( (m_event_port_settings_sent == true) || (m_out_bEnabled != OMX_TRUE) 4678 || output_flush_progress == true || m_outeos_reached == 1) 4679 { 4680 DEBUG_PRINT_LOW("\n Output Buffers return in EOS condition"); 4681 buffer->nFlags |= m_outeos_reached; 4682 m_cb.FillBufferDone (hComp,m_app_data,buffer); 4683 return OMX_ErrorNone; 4684 } 4685 pending_output_buffers++; 4686 ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate; 4687 if (ptr_respbuffer) 4688 { 4689 ptr_outputbuffer = (struct vdec_bufferpayload*)ptr_respbuffer->client_data; 4690 } 4691 4692 if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL) 4693 { 4694 return OMX_ErrorBadParameter; 4695 } 4696 4697 memcpy (&fillbuffer.buffer,ptr_outputbuffer,\ 4698 sizeof(struct vdec_bufferpayload)); 4699 fillbuffer.client_data = bufferAdd; 4700 4701 ioctl_msg.inputparam = &fillbuffer; 4702 ioctl_msg.outputparam = NULL; 4703 if (ioctl (driver_context.video_driver_fd, 4704 VDEC_IOCTL_FILL_OUTPUT_BUFFER,&ioctl_msg) < 0) 4705 { 4706 DEBUG_PRINT_ERROR("\n Decoder frame failed"); 4707 m_cb.FillBufferDone (hComp,m_app_data,buffer); 4708 return OMX_ErrorBadParameter; 4709 } 4710 4711 if(gate_input_buffers) 4712 { 4713 gate_input_buffers = false; 4714 if(pdest_frame) 4715 { 4716 /*Push the frame to the Decoder*/ 4717 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) 4718 { 4719 return OMX_ErrorBadParameter; 4720 } 4721 frame_count++; 4722 pdest_frame = NULL; 4723 } 4724 } 4725 return OMX_ErrorNone; 4726 } 4727 4728 /* ====================================================================== 4729 FUNCTION 4730 omx_vdec::SetCallbacks 4731 4732 DESCRIPTION 4733 Set the callbacks. 4734 4735 PARAMETERS 4736 None. 4737 4738 RETURN VALUE 4739 OMX Error None if everything successful. 4740 4741 ========================================================================== */ 4742 OMX_ERRORTYPE omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE hComp, 4743 OMX_IN OMX_CALLBACKTYPE* callbacks, 4744 OMX_IN OMX_PTR appData) 4745 { 4746 4747 m_cb = *callbacks; 4748 DEBUG_PRINT_LOW("\n Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\ 4749 m_cb.EventHandler,m_cb.FillBufferDone); 4750 m_app_data = appData; 4751 return OMX_ErrorNotImplemented; 4752 } 4753 4754 /* ====================================================================== 4755 FUNCTION 4756 omx_vdec::ComponentDeInit 4757 4758 DESCRIPTION 4759 Destroys the component and release memory allocated to the heap. 4760 4761 PARAMETERS 4762 <TBD>. 4763 4764 RETURN VALUE 4765 OMX Error None if everything successful. 4766 4767 ========================================================================== */ 4768 OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp) 4769 { 4770 int i = 0; 4771 if (OMX_StateLoaded != m_state) 4772 { 4773 DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d\n",\ 4774 m_state); 4775 DEBUG_PRINT_ERROR("\nPlayback Ended - FAILED"); 4776 } 4777 else 4778 { 4779 DEBUG_PRINT_HIGH("\n Playback Ended - PASSED"); 4780 } 4781 4782 /*Check if the output buffers have to be cleaned up*/ 4783 if(m_out_mem_ptr) 4784 { 4785 DEBUG_PRINT_LOW("Freeing the Output Memory\n"); 4786 for (i=0; i<m_out_buf_count; i++ ) 4787 { 4788 free_output_buffer (&m_out_mem_ptr[i]); 4789 } 4790 if (driver_context.ptr_outputbuffer) 4791 { 4792 free (driver_context.ptr_outputbuffer); 4793 driver_context.ptr_outputbuffer = NULL; 4794 } 4795 4796 if (driver_context.ptr_respbuffer) 4797 { 4798 free (driver_context.ptr_respbuffer); 4799 driver_context.ptr_respbuffer = NULL; 4800 } 4801 free(m_out_mem_ptr); 4802 m_out_mem_ptr = NULL; 4803 } 4804 4805 /*Check if the input buffers have to be cleaned up*/ 4806 if(m_inp_mem_ptr) 4807 { 4808 DEBUG_PRINT_LOW("Freeing the Input Memory\n"); 4809 for (i=0; i<m_inp_buf_count; i++ ) 4810 { 4811 free_input_buffer (&m_inp_mem_ptr[i]); 4812 } 4813 4814 if (driver_context.ptr_inputbuffer) 4815 { 4816 free (driver_context.ptr_inputbuffer); 4817 driver_context.ptr_inputbuffer = NULL; 4818 } 4819 4820 free(m_inp_mem_ptr); 4821 m_inp_mem_ptr = NULL; 4822 } 4823 4824 if(h264_scratch.pBuffer) 4825 { 4826 free(h264_scratch.pBuffer); 4827 h264_scratch.pBuffer = NULL; 4828 } 4829 4830 if(m_platform_list) 4831 { 4832 free(m_platform_list); 4833 m_platform_list = NULL; 4834 } 4835 if(m_vendor_config.pData) 4836 { 4837 free(m_vendor_config.pData); 4838 m_vendor_config.pData = NULL; 4839 } 4840 4841 // Reset counters in mesg queues 4842 m_ftb_q.m_size=0; 4843 m_cmd_q.m_size=0; 4844 m_etb_q.m_size=0; 4845 m_ftb_q.m_read = m_ftb_q.m_write =0; 4846 m_cmd_q.m_read = m_cmd_q.m_write =0; 4847 m_etb_q.m_read = m_etb_q.m_write =0; 4848 4849 DEBUG_PRINT_LOW("\n Calling VDEC_IOCTL_STOP_NEXT_MSG"); 4850 (void)ioctl(driver_context.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG, 4851 NULL); 4852 DEBUG_PRINT_HIGH("\n Close the driver instance"); 4853 close(driver_context.video_driver_fd); 4854 4855 #if BITSTREAM_LOG 4856 fclose (outputBufferFile1); 4857 #endif 4858 #ifdef _ANDROID_ 4859 //for (i=0; i<m_out_buf_count; i++ ) 4860 { 4861 // Clear the strong reference 4862 m_heap_ptr.clear(); 4863 } 4864 #endif // _ANDROID_ 4865 DEBUG_PRINT_HIGH("\n omx_vdec::component_deinit() complete"); 4866 return OMX_ErrorNone; 4867 } 4868 4869 /* ====================================================================== 4870 FUNCTION 4871 omx_vdec::UseEGLImage 4872 4873 DESCRIPTION 4874 OMX Use EGL Image method implementation <TBD>. 4875 4876 PARAMETERS 4877 <TBD>. 4878 4879 RETURN VALUE 4880 Not Implemented error. 4881 4882 ========================================================================== */ 4883 OMX_ERRORTYPE omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp, 4884 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 4885 OMX_IN OMX_U32 port, 4886 OMX_IN OMX_PTR appData, 4887 OMX_IN void* eglImage) 4888 { 4889 DEBUG_PRINT_ERROR("Error : use_EGL_image: Not Implemented \n"); 4890 return OMX_ErrorNotImplemented; 4891 } 4892 4893 /* ====================================================================== 4894 FUNCTION 4895 omx_vdec::ComponentRoleEnum 4896 4897 DESCRIPTION 4898 OMX Component Role Enum method implementation. 4899 4900 PARAMETERS 4901 <TBD>. 4902 4903 RETURN VALUE 4904 OMX Error None if everything is successful. 4905 ========================================================================== */ 4906 OMX_ERRORTYPE omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp, 4907 OMX_OUT OMX_U8* role, 4908 OMX_IN OMX_U32 index) 4909 { 4910 OMX_ERRORTYPE eRet = OMX_ErrorNone; 4911 4912 if(!strncmp(driver_context.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) 4913 { 4914 if((0 == index) && role) 4915 { 4916 strncpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE); 4917 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); 4918 } 4919 else 4920 { 4921 eRet = OMX_ErrorNoMore; 4922 } 4923 } 4924 else if(!strncmp(driver_context.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) 4925 { 4926 if((0 == index) && role) 4927 { 4928 strncpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE); 4929 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); 4930 } 4931 else 4932 { 4933 DEBUG_PRINT_LOW("\n No more roles \n"); 4934 eRet = OMX_ErrorNoMore; 4935 } 4936 } 4937 else if(!strncmp(driver_context.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) 4938 { 4939 if((0 == index) && role) 4940 { 4941 strncpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE); 4942 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); 4943 } 4944 else 4945 { 4946 DEBUG_PRINT_LOW("\n No more roles \n"); 4947 eRet = OMX_ErrorNoMore; 4948 } 4949 } 4950 else if(!strncmp(driver_context.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) 4951 { 4952 if((0 == index) && role) 4953 { 4954 strncpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE); 4955 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); 4956 } 4957 else 4958 { 4959 DEBUG_PRINT_LOW("\n No more roles \n"); 4960 eRet = OMX_ErrorNoMore; 4961 } 4962 } 4963 else 4964 { 4965 DEBUG_PRINT_ERROR("\nERROR:Querying Role on Unknown Component\n"); 4966 eRet = OMX_ErrorInvalidComponentName; 4967 } 4968 return eRet; 4969 } 4970 4971 4972 4973 4974 /* ====================================================================== 4975 FUNCTION 4976 omx_vdec::AllocateDone 4977 4978 DESCRIPTION 4979 Checks if entire buffer pool is allocated by IL Client or not. 4980 Need this to move to IDLE state. 4981 4982 PARAMETERS 4983 None. 4984 4985 RETURN VALUE 4986 true/false. 4987 4988 ========================================================================== */ 4989 bool omx_vdec::allocate_done(void) 4990 { 4991 bool bRet = false; 4992 bool bRet_In = false; 4993 bool bRet_Out = false; 4994 4995 bRet_In = allocate_input_done(); 4996 bRet_Out = allocate_output_done(); 4997 4998 if(bRet_In && bRet_Out) 4999 { 5000 bRet = true; 5001 } 5002 5003 return bRet; 5004 } 5005 /* ====================================================================== 5006 FUNCTION 5007 omx_vdec::AllocateInputDone 5008 5009 DESCRIPTION 5010 Checks if I/P buffer pool is allocated by IL Client or not. 5011 5012 PARAMETERS 5013 None. 5014 5015 RETURN VALUE 5016 true/false. 5017 5018 ========================================================================== */ 5019 bool omx_vdec::allocate_input_done(void) 5020 { 5021 bool bRet = false; 5022 unsigned i=0; 5023 5024 if (m_inp_mem_ptr == NULL) 5025 { 5026 return bRet; 5027 } 5028 if(m_inp_mem_ptr ) 5029 { 5030 for(;i<m_inp_buf_count;i++) 5031 { 5032 if(BITMASK_ABSENT(&m_inp_bm_count,i)) 5033 { 5034 break; 5035 } 5036 } 5037 } 5038 if(i==m_inp_buf_count) 5039 { 5040 bRet = true; 5041 DEBUG_PRINT_HIGH("\n Allocate done for all i/p buffers"); 5042 } 5043 if(i==m_inp_buf_count && m_inp_bEnabled) 5044 { 5045 m_inp_bPopulated = OMX_TRUE; 5046 } 5047 return bRet; 5048 } 5049 /* ====================================================================== 5050 FUNCTION 5051 omx_vdec::AllocateOutputDone 5052 5053 DESCRIPTION 5054 Checks if entire O/P buffer pool is allocated by IL Client or not. 5055 5056 PARAMETERS 5057 None. 5058 5059 RETURN VALUE 5060 true/false. 5061 5062 ========================================================================== */ 5063 bool omx_vdec::allocate_output_done(void) 5064 { 5065 bool bRet = false; 5066 unsigned j=0; 5067 5068 if (m_out_mem_ptr == NULL) 5069 { 5070 return bRet; 5071 } 5072 5073 if(m_out_mem_ptr ) 5074 { 5075 for(;j<m_out_buf_count;j++) 5076 { 5077 if(BITMASK_ABSENT(&m_out_bm_count,j)) 5078 { 5079 break; 5080 } 5081 } 5082 } 5083 5084 if(j==m_out_buf_count) 5085 { 5086 bRet = true; 5087 DEBUG_PRINT_HIGH("\n Allocate done for all o/p buffers"); 5088 } 5089 5090 if(j==m_out_buf_count && m_out_bEnabled) 5091 { 5092 m_out_bPopulated = OMX_TRUE; 5093 } 5094 return bRet; 5095 } 5096 5097 /* ====================================================================== 5098 FUNCTION 5099 omx_vdec::ReleaseDone 5100 5101 DESCRIPTION 5102 Checks if IL client has released all the buffers. 5103 5104 PARAMETERS 5105 None. 5106 5107 RETURN VALUE 5108 true/false 5109 5110 ========================================================================== */ 5111 bool omx_vdec::release_done(void) 5112 { 5113 bool bRet = false; 5114 5115 if(release_input_done()) 5116 { 5117 if(release_output_done()) 5118 { 5119 bRet = true; 5120 } 5121 } 5122 return bRet; 5123 } 5124 5125 5126 /* ====================================================================== 5127 FUNCTION 5128 omx_vdec::ReleaseOutputDone 5129 5130 DESCRIPTION 5131 Checks if IL client has released all the buffers. 5132 5133 PARAMETERS 5134 None. 5135 5136 RETURN VALUE 5137 true/false 5138 5139 ========================================================================== */ 5140 bool omx_vdec::release_output_done(void) 5141 { 5142 bool bRet = false; 5143 unsigned i=0,j=0; 5144 5145 DEBUG_PRINT_LOW("\n Value of m_out_mem_ptr %p",m_inp_mem_ptr); 5146 if(m_out_mem_ptr) 5147 { 5148 for(;j<m_out_buf_count;j++) 5149 { 5150 if(BITMASK_PRESENT(&m_out_bm_count,j)) 5151 { 5152 break; 5153 } 5154 } 5155 if(j==m_out_buf_count) 5156 { 5157 m_out_bm_count = 0; 5158 bRet = true; 5159 } 5160 } 5161 else 5162 { 5163 m_out_bm_count = 0; 5164 bRet = true; 5165 } 5166 return bRet; 5167 } 5168 /* ====================================================================== 5169 FUNCTION 5170 omx_vdec::ReleaseInputDone 5171 5172 DESCRIPTION 5173 Checks if IL client has released all the buffers. 5174 5175 PARAMETERS 5176 None. 5177 5178 RETURN VALUE 5179 true/false 5180 5181 ========================================================================== */ 5182 bool omx_vdec::release_input_done(void) 5183 { 5184 bool bRet = false; 5185 unsigned i=0,j=0; 5186 5187 DEBUG_PRINT_LOW("\n Value of m_inp_mem_ptr %p",m_inp_mem_ptr); 5188 if(m_inp_mem_ptr) 5189 { 5190 for(;j<m_inp_buf_count;j++) 5191 { 5192 if( BITMASK_PRESENT(&m_inp_bm_count,j)) 5193 { 5194 break; 5195 } 5196 } 5197 if(j==m_inp_buf_count) 5198 { 5199 bRet = true; 5200 } 5201 } 5202 else 5203 { 5204 bRet = true; 5205 } 5206 return bRet; 5207 } 5208 5209 /* ====================================================================== 5210 FUNCTION 5211 omx_vdec::omx_vdec_check_port_settings 5212 5213 DESCRIPTION 5214 Parse meta data to check the height and width param 5215 Check the level and profile 5216 5217 PARAMETERS 5218 None. 5219 5220 RETURN VALUE 5221 OMX_ErrorNone, if profile and level are supported 5222 OMX_ErrorUnsupportedSetting, if profile and level are not supported 5223 ========================================================================== */ 5224 OMX_ERRORTYPE omx_vdec::omx_vdec_check_port_settings(bool *port_setting_changed) 5225 { 5226 struct vdec_ioctl_msg ioctl_msg; 5227 unsigned int alignment = 0,buffer_size = 0; 5228 OMX_ERRORTYPE eRet = OMX_ErrorNone; 5229 5230 *port_setting_changed = false; 5231 ioctl_msg.inputparam = NULL; 5232 ioctl_msg.outputparam = &driver_context.video_resoultion; 5233 if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_GET_PICRES,&ioctl_msg)) 5234 { 5235 DEBUG_PRINT_ERROR("\n Error in VDEC_IOCTL_GET_PICRES in port_setting"); 5236 return OMX_ErrorHardware; 5237 } 5238 5239 ioctl_msg.inputparam = NULL; 5240 ioctl_msg.outputparam = &driver_context.output_buffer; 5241 if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_GET_BUFFER_REQ, 5242 &ioctl_msg)) 5243 { 5244 DEBUG_PRINT_ERROR("\n Error in VDEC_IOCTL_GET_BUFFER_REQ in port_setting"); 5245 return OMX_ErrorHardware; 5246 } 5247 DEBUG_PRINT_HIGH("\n Queried Dimensions H=%d W=%d Act H=%d W=%d", 5248 driver_context.video_resoultion.frame_height, 5249 driver_context.video_resoultion.frame_width, 5250 m_height,m_width); 5251 DEBUG_PRINT_HIGH("\n Queried Buffer ACnt=%d BSiz=%d Act Acnt=%d Bsiz=%d", 5252 driver_context.output_buffer.actualcount, 5253 driver_context.output_buffer.buffer_size, 5254 m_out_buf_count,m_out_buf_size); 5255 5256 DEBUG_PRINT_HIGH("\n Queried stride cuur Str=%d cur scan=%d Act str=%d act scan =%d", 5257 driver_context.video_resoultion.stride,driver_context.video_resoultion.scan_lines, 5258 stride,scan_lines); 5259 5260 5261 if(driver_context.video_resoultion.frame_height != m_height || 5262 driver_context.video_resoultion.frame_width != m_width || 5263 driver_context.video_resoultion.scan_lines != scan_lines || 5264 driver_context.video_resoultion.stride != stride || 5265 driver_context.output_buffer.actualcount != m_out_buf_count || 5266 driver_context.output_buffer.buffer_size > m_out_buf_size) 5267 { 5268 *port_setting_changed = true; 5269 ioctl_msg.inputparam = &driver_context.output_buffer; 5270 ioctl_msg.outputparam = NULL; 5271 5272 if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_SET_BUFFER_REQ, 5273 &ioctl_msg)) 5274 { 5275 DEBUG_PRINT_ERROR("\n Error in VDEC_IOCTL_GET_BUFFER_REQ in port_setting"); 5276 return OMX_ErrorHardware; 5277 } 5278 m_out_buf_size_recon = driver_context.output_buffer.buffer_size; 5279 m_out_buf_count_recon = driver_context.output_buffer.actualcount; 5280 m_out_buf_count_min_recon = driver_context.output_buffer.mincount; 5281 5282 alignment = driver_context.output_buffer.alignment; 5283 buffer_size = driver_context.output_buffer.buffer_size; 5284 m_out_buf_size_recon = 5285 ((buffer_size + alignment - 1) & (~(alignment - 1))); 5286 m_crop_dy = m_height = driver_context.video_resoultion.frame_height; 5287 m_crop_dx = m_width = driver_context.video_resoultion.frame_width; 5288 scan_lines = driver_context.video_resoultion.scan_lines; 5289 stride = driver_context.video_resoultion.stride; 5290 m_port_height = m_height; 5291 m_port_width = m_width; 5292 } 5293 5294 return eRet; 5295 } 5296 5297 5298 /* ====================================================================== 5299 FUNCTION 5300 omx_vdec::omx_vdec_validate_port_param 5301 5302 DESCRIPTION 5303 Get the PMEM area from video decoder 5304 5305 PARAMETERS 5306 None. 5307 5308 RETURN VALUE 5309 None 5310 ========================================================================== */ 5311 OMX_ERRORTYPE omx_vdec::omx_vdec_validate_port_param(int height, int width) 5312 { 5313 OMX_ERRORTYPE ret = OMX_ErrorNone; 5314 long hxw = height*width; 5315 long lmt_hxw = 0; 5316 5317 return ret; 5318 } 5319 5320 static FILE * outputBufferFile = NULL; 5321 5322 OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp, 5323 OMX_BUFFERHEADERTYPE * buffer) 5324 { 5325 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL; 5326 5327 if (buffer == NULL || ((buffer - m_out_mem_ptr) > m_out_buf_count)) 5328 { 5329 return OMX_ErrorBadParameter; 5330 } 5331 5332 DEBUG_PRINT_LOW("\n fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p", 5333 buffer, buffer->pBuffer); 5334 pending_output_buffers --; 5335 5336 if (buffer->nFlags & 0x01) 5337 { 5338 DEBUG_PRINT_LOW("\n Output EOS has been reached"); 5339 5340 m_outeos_reached = 0; 5341 m_ineos_reached = 0; 5342 h264_scratch.nFilledLen = 0; 5343 nal_count = 0; 5344 look_ahead_nal = false; 5345 frame_count = 0; 5346 5347 if (m_frame_parser.mutils) 5348 { 5349 m_frame_parser.mutils->initialize_frame_checking_environment(); 5350 } 5351 if (psource_frame) 5352 { 5353 m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame); 5354 psource_frame = NULL; 5355 } 5356 5357 if (pdest_frame) 5358 { 5359 pdest_frame->nFilledLen = 0; 5360 m_input_free_q.insert_entry((unsigned) pdest_frame,NULL,NULL); 5361 pdest_frame = NULL; 5362 } 5363 m_frame_parser.flush(); 5364 } 5365 5366 DEBUG_PRINT_LOW("\n In fill Buffer done call address %p ",buffer); 5367 5368 if (outputBufferFile == NULL) 5369 { 5370 outputBufferFile = fopen ("/data/output.yuv","wb"); 5371 } 5372 if (outputBufferFile) 5373 { 5374 /*fwrite (buffer->pBuffer,1,buffer->nFilledLen, 5375 outputBufferFile); */ 5376 } 5377 /* For use buffer we need to copy the data */ 5378 if (m_cb.FillBufferDone) 5379 { 5380 pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) 5381 ((OMX_QCOM_PLATFORM_PRIVATE_LIST *) 5382 buffer->pPlatformPrivate)->entryList->entry; 5383 DEBUG_PRINT_LOW("\n Before FBD callback Accessed Pmeminfo %d",pPMEMInfo->pmem_fd); 5384 m_cb.FillBufferDone (hComp,m_app_data,buffer); 5385 DEBUG_PRINT_LOW("\n After Fill Buffer Done callback %d",pPMEMInfo->pmem_fd); 5386 } 5387 else 5388 { 5389 return OMX_ErrorBadParameter; 5390 } 5391 5392 return OMX_ErrorNone; 5393 } 5394 5395 OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE hComp, 5396 OMX_BUFFERHEADERTYPE* buffer) 5397 { 5398 5399 if (buffer == NULL || ((buffer - m_inp_mem_ptr) > m_inp_buf_count)) 5400 { 5401 return OMX_ErrorBadParameter; 5402 } 5403 5404 DEBUG_PRINT_LOW("\n empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p", 5405 buffer, buffer->pBuffer); 5406 pending_input_buffers--; 5407 5408 if (arbitrary_bytes) 5409 { 5410 if (pdest_frame == NULL && input_flush_progress == false) 5411 { 5412 DEBUG_PRINT_LOW("\n Push input from buffer done address of Buffer %p",buffer); 5413 pdest_frame = buffer; 5414 buffer->nFilledLen = 0; 5415 push_input_buffer (hComp); 5416 } 5417 else 5418 { 5419 DEBUG_PRINT_LOW("\n Push buffer into freeq address of Buffer %p",buffer); 5420 buffer->nFilledLen = 0; 5421 if (!m_input_free_q.insert_entry((unsigned)buffer,NULL,NULL)) 5422 { 5423 DEBUG_PRINT_ERROR("\nERROR:i/p free Queue is FULL Error"); 5424 } 5425 } 5426 } 5427 else if(m_cb.EmptyBufferDone) 5428 { 5429 buffer->nFilledLen = 0; 5430 m_cb.EmptyBufferDone(hComp ,m_app_data, buffer); 5431 } 5432 return OMX_ErrorNone; 5433 } 5434 5435 5436 int omx_vdec::async_message_process (void *context, void* message) 5437 { 5438 omx_vdec* omx = NULL; 5439 struct vdec_msginfo *vdec_msg = NULL; 5440 OMX_BUFFERHEADERTYPE* omxhdr = NULL; 5441 struct vdec_output_frameinfo *output_respbuf = NULL; 5442 5443 if (context == NULL || message == NULL) 5444 { 5445 DEBUG_PRINT_ERROR("\n FATAL ERROR in omx_vdec::async_message_process NULL Check"); 5446 return -1; 5447 } 5448 vdec_msg = (struct vdec_msginfo *)message; 5449 5450 omx = reinterpret_cast<omx_vdec*>(context); 5451 switch (vdec_msg->msgcode) 5452 { 5453 5454 case VDEC_MSG_EVT_HW_ERROR: 5455 omx->post_event (NULL,vdec_msg->status_code,\ 5456 OMX_COMPONENT_GENERATE_HARDWARE_ERROR); 5457 break; 5458 5459 case VDEC_MSG_RESP_START_DONE: 5460 omx->post_event (NULL,vdec_msg->status_code,\ 5461 OMX_COMPONENT_GENERATE_START_DONE); 5462 break; 5463 5464 case VDEC_MSG_RESP_STOP_DONE: 5465 omx->post_event (NULL,vdec_msg->status_code,\ 5466 OMX_COMPONENT_GENERATE_STOP_DONE); 5467 break; 5468 5469 case VDEC_MSG_RESP_RESUME_DONE: 5470 omx->post_event (NULL,vdec_msg->status_code,\ 5471 OMX_COMPONENT_GENERATE_RESUME_DONE); 5472 break; 5473 5474 case VDEC_MSG_RESP_PAUSE_DONE: 5475 omx->post_event (NULL,vdec_msg->status_code,\ 5476 OMX_COMPONENT_GENERATE_PAUSE_DONE); 5477 break; 5478 5479 case VDEC_MSG_RESP_FLUSH_INPUT_DONE: 5480 omx->post_event (NULL,vdec_msg->status_code,\ 5481 OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH); 5482 break; 5483 case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE: 5484 omx->post_event (NULL,vdec_msg->status_code,\ 5485 OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH); 5486 break; 5487 case VDEC_MSG_RESP_INPUT_FLUSHED: 5488 case VDEC_MSG_RESP_INPUT_BUFFER_DONE: 5489 5490 omxhdr = (OMX_BUFFERHEADERTYPE* )\ 5491 vdec_msg->msgdata.input_frame_clientdata; 5492 5493 5494 if (omxhdr == NULL || 5495 ((omxhdr - omx->m_inp_mem_ptr) > omx->m_inp_buf_count) ) 5496 { 5497 omxhdr = NULL; 5498 vdec_msg->status_code = VDEC_S_EFATAL; 5499 } 5500 5501 omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code, 5502 OMX_COMPONENT_GENERATE_EBD); 5503 break; 5504 case VDEC_MSG_RESP_OUTPUT_FLUSHED: 5505 case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE: 5506 omxhdr = (OMX_BUFFERHEADERTYPE*)vdec_msg->msgdata.output_frame.client_data; 5507 DEBUG_PRINT_LOW("\n Got Buffer back from Driver %p omxhdr time stamp = %d " ,omxhdr,vdec_msg->msgdata.output_frame.time_stamp); 5508 5509 if ( (omxhdr != NULL) && 5510 ((omxhdr - omx->m_out_mem_ptr) < omx->m_out_buf_count) && 5511 (omxhdr->pOutputPortPrivate != NULL) && 5512 ( ((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate 5513 - omx->driver_context.ptr_respbuffer) < omx->m_out_buf_count) 5514 ) 5515 { 5516 if (vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen) 5517 { 5518 omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len; 5519 omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset; 5520 omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp; 5521 omxhdr->nFlags = (vdec_msg->msgdata.output_frame.flags & 0x01); 5522 5523 output_respbuf = (struct vdec_output_frameinfo *)\ 5524 omxhdr->pOutputPortPrivate; 5525 output_respbuf->framesize.bottom = \ 5526 vdec_msg->msgdata.output_frame.framesize.bottom; 5527 output_respbuf->framesize.left = \ 5528 vdec_msg->msgdata.output_frame.framesize.left; 5529 output_respbuf->framesize.right = \ 5530 vdec_msg->msgdata.output_frame.framesize.right; 5531 output_respbuf->framesize.top = \ 5532 vdec_msg->msgdata.output_frame.framesize.top; 5533 output_respbuf->len = vdec_msg->msgdata.output_frame.len; 5534 output_respbuf->offset = vdec_msg->msgdata.output_frame.offset; 5535 output_respbuf->time_stamp = vdec_msg->msgdata.output_frame.time_stamp; 5536 output_respbuf->flags = vdec_msg->msgdata.output_frame.flags; 5537 5538 /*Use buffer case*/ 5539 if (omx->output_use_buffer) 5540 { 5541 if (vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen) 5542 { 5543 memcpy ( omxhdr->pBuffer, 5544 (vdec_msg->msgdata.output_frame.bufferaddr + 5545 vdec_msg->msgdata.output_frame.offset), 5546 vdec_msg->msgdata.output_frame.len ); 5547 } 5548 else 5549 { 5550 omxhdr->nFilledLen = 0; 5551 } 5552 } 5553 } 5554 else 5555 { 5556 omxhdr->nFilledLen = 0; 5557 } 5558 5559 } 5560 else 5561 { 5562 omxhdr = NULL; 5563 vdec_msg->status_code = VDEC_S_EFATAL; 5564 } 5565 5566 DEBUG_PRINT_LOW("\n Driver returned a output Buffer status %d", 5567 vdec_msg->status_code); 5568 omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code, 5569 OMX_COMPONENT_GENERATE_FBD); 5570 break; 5571 default: 5572 break; 5573 } 5574 return 1; 5575 } 5576 5577 OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary ( 5578 OMX_HANDLETYPE hComp, 5579 OMX_BUFFERHEADERTYPE *buffer 5580 ) 5581 { 5582 unsigned address,p2,id; 5583 DEBUG_PRINT_LOW("\n Empty this arbitrary"); 5584 5585 if (buffer == NULL) 5586 { 5587 return OMX_ErrorBadParameter; 5588 } 5589 DEBUG_PRINT_LOW("\n ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer); 5590 DEBUG_PRINT_LOW("\n ETBProxyArb: nFilledLen %u, flags %d, timestamp %u", 5591 buffer->nFilledLen, buffer->nFlags, (unsigned)buffer->nTimeStamp); 5592 5593 if( input_flush_progress == true || m_ineos_reached == 1) 5594 { 5595 DEBUG_PRINT_LOW("\n Flush in progress return buffer "); 5596 m_cb.EmptyBufferDone (hComp,m_app_data,buffer); 5597 return OMX_ErrorNone; 5598 } 5599 5600 if (psource_frame == NULL) 5601 { 5602 DEBUG_PRINT_LOW("\n Set Buffer as source Buffer %p time stamp %d",buffer,buffer->nTimeStamp); 5603 psource_frame = buffer; 5604 DEBUG_PRINT_LOW("\n Try to Push One Input Buffer "); 5605 push_input_buffer (hComp); 5606 } 5607 else 5608 { 5609 DEBUG_PRINT_LOW("\n Push the source buffer into pendingq %p",buffer); 5610 if (!m_input_pending_q.insert_entry((unsigned)buffer,NULL,NULL)) 5611 { 5612 return OMX_ErrorBadParameter; 5613 } 5614 } 5615 5616 5617 return OMX_ErrorNone; 5618 } 5619 5620 OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp) 5621 { 5622 unsigned address,p2,id; 5623 OMX_ERRORTYPE ret = OMX_ErrorNone; 5624 5625 if (pdest_frame == NULL || psource_frame == NULL) 5626 { 5627 /*Check if we have a destination buffer*/ 5628 if (pdest_frame == NULL) 5629 { 5630 DEBUG_PRINT_LOW("\n Get a Destination buffer from the queue"); 5631 if (m_input_free_q.m_size && !gate_input_buffers) 5632 { 5633 m_input_free_q.pop_entry(&address,&p2,&id); 5634 pdest_frame = (OMX_BUFFERHEADERTYPE *)address; 5635 pdest_frame->nFilledLen = 0; 5636 DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",pdest_frame); 5637 } 5638 } 5639 5640 /*Check if we have a destination buffer*/ 5641 if (psource_frame == NULL) 5642 { 5643 DEBUG_PRINT_LOW("\n Get a source buffer from the queue"); 5644 if (m_input_pending_q.m_size && !gate_input_buffers) 5645 { 5646 m_input_pending_q.pop_entry(&address,&p2,&id); 5647 psource_frame = (OMX_BUFFERHEADERTYPE *)address; 5648 DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %d",psource_frame, 5649 psource_frame->nTimeStamp); 5650 DEBUG_PRINT_LOW("\n Next source Buffer flag %d length %d", 5651 psource_frame->nFlags,psource_frame->nFilledLen); 5652 5653 } 5654 } 5655 5656 } 5657 5658 while ((pdest_frame != NULL) && (psource_frame != NULL)&& !gate_input_buffers) 5659 { 5660 switch (codec_type_parse) 5661 { 5662 case CODEC_TYPE_MPEG4: 5663 case CODEC_TYPE_H263: 5664 ret = push_input_sc_codec(hComp); 5665 break; 5666 case CODEC_TYPE_H264: 5667 ret = push_input_h264(hComp); 5668 break; 5669 case CODEC_TYPE_VC1: 5670 ret = push_input_vc1(hComp); 5671 break; 5672 } 5673 if (ret != OMX_ErrorNone) 5674 { 5675 DEBUG_PRINT_ERROR("\n Pushing input Buffer Failed"); 5676 omx_report_error (); 5677 break; 5678 } 5679 } 5680 5681 return ret; 5682 } 5683 5684 OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp) 5685 { 5686 OMX_U32 partial_frame = 1; 5687 OMX_BOOL genarte_edb = OMX_TRUE,generate_eos = OMX_TRUE; 5688 unsigned address,p2,id; 5689 5690 DEBUG_PRINT_LOW("\n Start Parsing the bit stream address %p TimeStamp %d", 5691 psource_frame,psource_frame->nTimeStamp); 5692 if (m_frame_parser.parse_mpeg4_frame(psource_frame, 5693 pdest_frame,&partial_frame) == -1) 5694 { 5695 DEBUG_PRINT_ERROR("\n Error In Parsing Return Error"); 5696 return OMX_ErrorBadParameter; 5697 } 5698 5699 if (partial_frame == 0) 5700 { 5701 DEBUG_PRINT_LOW("\n Frame size %d source %p frame count %d", 5702 pdest_frame->nFilledLen,psource_frame,frame_count); 5703 5704 5705 DEBUG_PRINT_LOW("\n TimeStamp updated %d",pdest_frame->nTimeStamp); 5706 /*First Parsed buffer will have only header Hence skip*/ 5707 if (frame_count == 0) 5708 { 5709 DEBUG_PRINT_LOW("\n H263/MPEG4 Codec First Frame "); 5710 mp4h263_flags = psource_frame->nFlags; 5711 mp4h263_timestamp = psource_frame->nTimeStamp; 5712 frame_count++; 5713 } 5714 else 5715 { 5716 pdest_frame->nTimeStamp = mp4h263_timestamp; 5717 mp4h263_timestamp = psource_frame->nTimeStamp; 5718 pdest_frame->nFlags = mp4h263_flags; 5719 mp4h263_flags = psource_frame->nFlags; 5720 5721 if(psource_frame->nFilledLen == 0) 5722 { 5723 pdest_frame->nFlags = mp4h263_flags; 5724 generate_eos = OMX_FALSE; 5725 } 5726 5727 5728 /*Push the frame to the Decoder*/ 5729 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) 5730 { 5731 return OMX_ErrorBadParameter; 5732 } 5733 if(m_event_port_settings_sent) 5734 { 5735 gate_input_buffers = true; 5736 return OMX_ErrorNone; 5737 } 5738 frame_count++; 5739 pdest_frame = NULL; 5740 5741 if (m_input_free_q.m_size && !gate_input_buffers) 5742 { 5743 m_input_free_q.pop_entry(&address,&p2,&id); 5744 pdest_frame = (OMX_BUFFERHEADERTYPE *) address; 5745 pdest_frame->nFilledLen = 0; 5746 } 5747 } 5748 } 5749 else 5750 { 5751 DEBUG_PRINT_LOW("\n Not a Complete Frame %d",pdest_frame->nFilledLen); 5752 /*Check if Destination Buffer is full*/ 5753 if (pdest_frame->nAllocLen == 5754 pdest_frame->nFilledLen + pdest_frame->nOffset) 5755 { 5756 DEBUG_PRINT_ERROR("\nERROR:Frame Not found though Destination Filled"); 5757 return OMX_ErrorStreamCorrupt; 5758 } 5759 } 5760 5761 if (psource_frame->nFilledLen == 0) 5762 { 5763 if ((psource_frame->nFlags & 0x01) && generate_eos) 5764 { 5765 if (pdest_frame) 5766 { 5767 pdest_frame->nTimeStamp = psource_frame->nTimeStamp; 5768 pdest_frame->nFlags = psource_frame->nFlags; 5769 DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%d TimeStamp = %x", 5770 pdest_frame->nFilledLen,pdest_frame->nTimeStamp); 5771 DEBUG_PRINT_LOW("\n Found a frame size = %d number = %d", 5772 pdest_frame->nFilledLen,frame_count++); 5773 /*Push the frame to the Decoder*/ 5774 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) 5775 { 5776 return OMX_ErrorBadParameter; 5777 } 5778 frame_count++; 5779 pdest_frame = NULL; 5780 } 5781 else 5782 { 5783 DEBUG_PRINT_LOW("\n Last frame in else dest addr") ; 5784 genarte_edb = OMX_FALSE; 5785 } 5786 } 5787 if(genarte_edb) 5788 { 5789 DEBUG_PRINT_LOW("\n Buffer Consumed return back to client %p",psource_frame); 5790 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame); 5791 psource_frame = NULL; 5792 5793 if (m_input_pending_q.m_size) 5794 { 5795 DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame); 5796 m_input_pending_q.pop_entry(&address,&p2,&id); 5797 psource_frame = (OMX_BUFFERHEADERTYPE *) address; 5798 DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %d",psource_frame, 5799 psource_frame->nTimeStamp); 5800 DEBUG_PRINT_LOW("\n Next source Buffer flag %d length %d", 5801 psource_frame->nFlags,psource_frame->nFilledLen); 5802 } 5803 } 5804 } 5805 return OMX_ErrorNone; 5806 } 5807 5808 OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp) 5809 { 5810 OMX_U32 partial_frame = 1; 5811 unsigned address,p2,id; 5812 OMX_BOOL isNewFrame = OMX_FALSE; 5813 OMX_BOOL genarte_edb = OMX_TRUE; 5814 OMX_BOOL skip_parsing = OMX_FALSE; 5815 5816 if (h264_scratch.pBuffer == NULL) 5817 { 5818 DEBUG_PRINT_ERROR("\nERROR:H.264 Scratch Buffer not allocated"); 5819 return OMX_ErrorBadParameter; 5820 } 5821 DEBUG_PRINT_LOW("\n Values of h264_scratch.nFilledLen %d look_ahead_nal %d", 5822 h264_scratch.nFilledLen,look_ahead_nal); 5823 DEBUG_PRINT_LOW("\n pdest_frame->nFilledLen %d",pdest_frame->nFilledLen); 5824 if (h264_scratch.nFilledLen && look_ahead_nal) 5825 { 5826 look_ahead_nal = false; 5827 DEBUG_PRINT_LOW("\n Copy the previous NAL into Buffer %d ", 5828 h264_scratch.nFilledLen); 5829 if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >= 5830 h264_scratch.nFilledLen) 5831 { 5832 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen), 5833 h264_scratch.pBuffer,h264_scratch.nFilledLen); 5834 pdest_frame->nFilledLen += h264_scratch.nFilledLen; 5835 DEBUG_PRINT_LOW("\n Total filled length %d",pdest_frame->nFilledLen); 5836 h264_scratch.nFilledLen = 0; 5837 } 5838 else 5839 { 5840 DEBUG_PRINT_ERROR("\nERROR:Destination buffer overflow for H264"); 5841 return OMX_ErrorBadParameter; 5842 } 5843 } 5844 5845 if(psource_frame->nFlags & 0x01) 5846 { 5847 DEBUG_PRINT_LOW("\n EOS has been reached no parsing required"); 5848 skip_parsing = OMX_TRUE; 5849 if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >= 5850 psource_frame->nFilledLen) 5851 { 5852 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen), 5853 (psource_frame->pBuffer+psource_frame->nOffset), 5854 psource_frame->nFilledLen); 5855 pdest_frame->nFilledLen += psource_frame->nFilledLen; 5856 DEBUG_PRINT_LOW("\n Total filled length %d",pdest_frame->nFilledLen); 5857 psource_frame->nFilledLen = 0; 5858 } 5859 else 5860 { 5861 DEBUG_PRINT_ERROR("\nERROR:Destination buffer overflow for H264"); 5862 return OMX_ErrorBadParameter; 5863 } 5864 } 5865 5866 if(!skip_parsing) 5867 { 5868 if (nal_length == 0) 5869 { 5870 DEBUG_PRINT_LOW("\n NAL length Zero hence parse using start code"); 5871 if (m_frame_parser.parse_mpeg4_frame(psource_frame, 5872 &h264_scratch,&partial_frame) == -1) 5873 { 5874 DEBUG_PRINT_ERROR("\n Error In Parsing Return Error"); 5875 return OMX_ErrorBadParameter; 5876 } 5877 } 5878 else 5879 { 5880 DEBUG_PRINT_LOW("\n NAL length %d hence parse with NAL length %d",nal_length); 5881 if (m_frame_parser.parse_h264_nallength(psource_frame, 5882 &h264_scratch,&partial_frame) == -1) 5883 { 5884 DEBUG_PRINT_ERROR("\n Error In Parsing NAL Return Error"); 5885 return OMX_ErrorBadParameter; 5886 } 5887 } 5888 5889 if (partial_frame == 0) 5890 { 5891 5892 if (nal_count == 0 && h264_scratch.nFilledLen == 0) 5893 { 5894 DEBUG_PRINT_LOW("\n First NAL with Zero Length Hence Skip"); 5895 nal_count++; 5896 h264_scratch.nTimeStamp = psource_frame->nTimeStamp; 5897 h264_scratch.nFlags = psource_frame->nFlags; 5898 } 5899 else 5900 { 5901 DEBUG_PRINT_LOW("\n Length of New NAL is %d",h264_scratch.nFilledLen); 5902 5903 m_frame_parser.mutils->isNewFrame(h264_scratch.pBuffer, 5904 h264_scratch.nFilledLen,0,isNewFrame); 5905 nal_count++; 5906 5907 if (!isNewFrame) 5908 { 5909 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >= 5910 h264_scratch.nFilledLen) 5911 { 5912 DEBUG_PRINT_LOW("\n Not a NewFrame Copy into Dest len %d", 5913 h264_scratch.nFilledLen); 5914 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen), 5915 h264_scratch.pBuffer,h264_scratch.nFilledLen); 5916 pdest_frame->nFilledLen += h264_scratch.nFilledLen; 5917 h264_scratch.nFilledLen = 0; 5918 } 5919 else 5920 { 5921 DEBUG_PRINT_LOW("\n Destination buffer overflow for H264"); 5922 return OMX_ErrorBadParameter; 5923 } 5924 } 5925 else 5926 { 5927 look_ahead_nal = true; 5928 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp; 5929 pdest_frame->nFlags = h264_scratch.nFlags; 5930 h264_scratch.nTimeStamp = psource_frame->nTimeStamp; 5931 h264_scratch.nFlags = psource_frame->nFlags; 5932 5933 DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%d TimeStamp = %x", 5934 pdest_frame->nFilledLen,pdest_frame->nTimeStamp); 5935 DEBUG_PRINT_LOW("\n Found a frame size = %d number = %d", 5936 pdest_frame->nFilledLen,frame_count++); 5937 5938 if (pdest_frame->nFilledLen == 0) 5939 { 5940 DEBUG_PRINT_LOW("\n Copy the Current Frame since and push it"); 5941 look_ahead_nal = false; 5942 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >= 5943 h264_scratch.nFilledLen) 5944 { 5945 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen), 5946 h264_scratch.pBuffer,h264_scratch.nFilledLen); 5947 pdest_frame->nFilledLen += h264_scratch.nFilledLen; 5948 h264_scratch.nFilledLen = 0; 5949 } 5950 else 5951 { 5952 DEBUG_PRINT_ERROR("\nERROR:Destination buffer overflow for H264"); 5953 return OMX_ErrorBadParameter; 5954 } 5955 } 5956 else 5957 { 5958 /*Push the frame to the Decoder*/ 5959 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) 5960 { 5961 return OMX_ErrorBadParameter; 5962 } 5963 if(m_event_port_settings_sent) 5964 { 5965 gate_input_buffers = true; 5966 return OMX_ErrorNone; 5967 } 5968 //frame_count++; 5969 pdest_frame = NULL; 5970 if (m_input_free_q.m_size && !gate_input_buffers) 5971 { 5972 m_input_free_q.pop_entry(&address,&p2,&id); 5973 pdest_frame = (OMX_BUFFERHEADERTYPE *) address; 5974 DEBUG_PRINT_LOW("\n Pop the next pdest_buffer %p",pdest_frame); 5975 pdest_frame->nFilledLen = 0; 5976 } 5977 } 5978 } 5979 } 5980 } 5981 else 5982 { 5983 DEBUG_PRINT_LOW("\n Not a Complete Frame %d",pdest_frame->nFilledLen); 5984 /*Check if Destination Buffer is full*/ 5985 if (h264_scratch.nAllocLen == 5986 h264_scratch.nFilledLen + h264_scratch.nOffset) 5987 { 5988 DEBUG_PRINT_ERROR("\nERROR: Frame Not found though Destination Filled"); 5989 return OMX_ErrorStreamCorrupt; 5990 } 5991 } 5992 } 5993 5994 if (psource_frame->nFilledLen == 0) 5995 { 5996 DEBUG_PRINT_LOW("\n Buffer Consumed return back to client %p",psource_frame); 5997 5998 if (psource_frame->nFlags & 0x01) 5999 { 6000 if (pdest_frame) 6001 { 6002 DEBUG_PRINT_LOW("\n EOS Reached Pass Last Buffer"); 6003 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >= 6004 h264_scratch.nFilledLen) 6005 { 6006 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen), 6007 h264_scratch.pBuffer,h264_scratch.nFilledLen); 6008 pdest_frame->nFilledLen += h264_scratch.nFilledLen; 6009 h264_scratch.nFilledLen = 0; 6010 } 6011 else 6012 { 6013 DEBUG_PRINT_ERROR("\nERROR:Destination buffer overflow for H264"); 6014 return OMX_ErrorBadParameter; 6015 } 6016 pdest_frame->nTimeStamp = psource_frame->nTimeStamp; 6017 pdest_frame->nFlags = psource_frame->nFlags; 6018 6019 DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%d TimeStamp = %x", 6020 pdest_frame->nFilledLen,pdest_frame->nTimeStamp); 6021 DEBUG_PRINT_LOW("\n Found a frame size = %d number = %d", 6022 pdest_frame->nFilledLen,frame_count++); 6023 /*Push the frame to the Decoder*/ 6024 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) 6025 { 6026 return OMX_ErrorBadParameter; 6027 } 6028 if(m_event_port_settings_sent) 6029 { 6030 gate_input_buffers = true; 6031 return OMX_ErrorNone; 6032 } 6033 frame_count++; 6034 pdest_frame = NULL; 6035 } 6036 else 6037 { 6038 DEBUG_PRINT_LOW("\n Last frame in else dest addr %p size %d", 6039 pdest_frame,h264_scratch.nFilledLen); 6040 genarte_edb = OMX_FALSE; 6041 } 6042 } 6043 if(genarte_edb) 6044 { 6045 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame); 6046 psource_frame = NULL; 6047 if (m_input_pending_q.m_size && !gate_input_buffers) 6048 { 6049 DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame); 6050 m_input_pending_q.pop_entry(&address,&p2,&id); 6051 psource_frame = (OMX_BUFFERHEADERTYPE *) address; 6052 DEBUG_PRINT_LOW("\nNext source Buffer flag %d length %d", 6053 psource_frame->nFlags,psource_frame->nFilledLen); 6054 } 6055 } 6056 } 6057 return OMX_ErrorNone; 6058 } 6059 6060 OMX_ERRORTYPE omx_vdec::push_input_vc1 (OMX_HANDLETYPE hComp) 6061 { 6062 OMX_U8 *buf, *pdest; 6063 OMX_U32 partial_frame = 1; 6064 OMX_U32 buf_len, dest_len; 6065 6066 if(frame_count == 0) 6067 { 6068 DEBUG_PRINT_LOW("\nFirst i/p buffer for VC1 arbitrary bytes\n"); 6069 if(!m_vendor_config.pData) 6070 { 6071 DEBUG_PRINT_LOW("\nCheck profile type in 1st source buffer\n"); 6072 buf = psource_frame->pBuffer; 6073 buf_len = psource_frame->nFilledLen; 6074 6075 if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) == 6076 VC1_SP_MP_START_CODE) 6077 { 6078 m_vc1_profile = VC1_SP_MP_RCV; 6079 } 6080 else if(*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE) 6081 { 6082 m_vc1_profile = VC1_AP; 6083 } 6084 else 6085 { 6086 DEBUG_PRINT_ERROR("\nInvalid sequence layer in first buffer\n"); 6087 return OMX_ErrorStreamCorrupt; 6088 } 6089 } 6090 else 6091 { 6092 pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen + 6093 pdest_frame->nOffset; 6094 dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen + 6095 pdest_frame->nOffset); 6096 6097 if(dest_len < m_vendor_config.nDataSize) 6098 { 6099 DEBUG_PRINT_ERROR("\nDestination buffer full\n"); 6100 return OMX_ErrorBadParameter; 6101 } 6102 else 6103 { 6104 memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize); 6105 pdest_frame->nFilledLen += m_vendor_config.nDataSize; 6106 } 6107 } 6108 } 6109 6110 switch(m_vc1_profile) 6111 { 6112 case VC1_AP: 6113 DEBUG_PRINT_LOW("\n VC1 AP, hence parse using frame start code"); 6114 if (push_input_sc_codec(hComp) != OMX_ErrorNone) 6115 { 6116 DEBUG_PRINT_ERROR("\n Error In Parsing VC1 AP start code"); 6117 return OMX_ErrorBadParameter; 6118 } 6119 break; 6120 6121 case VC1_SP_MP_RCV: 6122 default: 6123 DEBUG_PRINT_ERROR("\n Unsupported VC1 profile in ArbitraryBytes Mode\n"); 6124 return OMX_ErrorBadParameter; 6125 } 6126 return OMX_ErrorNone; 6127 } 6128 6129 bool omx_vdec::register_output_buffers() 6130 { 6131 struct vdec_ioctl_msg ioctl_msg; 6132 struct vdec_setbuffer_cmd setbuffers; 6133 int i = 0; 6134 unsigned p1 =0,p2 = 0,ident = 0; 6135 6136 for(i=0;i<m_out_buf_count;i++) 6137 { 6138 setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT; 6139 memcpy (&setbuffers.buffer,&driver_context.ptr_outputbuffer [i], 6140 sizeof (vdec_bufferpayload)); 6141 ioctl_msg.inputparam = &setbuffers; 6142 ioctl_msg.outputparam = NULL; 6143 6144 DEBUG_PRINT_LOW("\n Set the Output Buffer"); 6145 if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_SET_BUFFER, 6146 &ioctl_msg) < 0) 6147 { 6148 DEBUG_PRINT_ERROR("\n Set output buffer failed"); 6149 return false; 6150 } 6151 } 6152 if(gate_output_buffers) 6153 { 6154 /*Generate FBD for all Buffers in the FTBq*/ 6155 pthread_mutex_lock(&m_lock); 6156 DEBUG_PRINT_LOW("\n Initiate Pushing Output Buffers"); 6157 while (m_ftb_q.m_size) 6158 { 6159 m_ftb_q.pop_entry(&p1,&p2,&ident); 6160 if(ident == OMX_COMPONENT_GENERATE_FTB ) 6161 { 6162 if (fill_this_buffer_proxy ((OMX_HANDLETYPE)p1, 6163 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) 6164 { 6165 DEBUG_PRINT_ERROR("\n fill_this_buffer_proxy failure"); 6166 omx_report_error (); 6167 return false; 6168 } 6169 } 6170 else if (ident == OMX_COMPONENT_GENERATE_FBD) 6171 { 6172 fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1); 6173 } 6174 } 6175 gate_output_buffers = false; 6176 pthread_mutex_unlock(&m_lock); 6177 } 6178 return true; 6179 } 6180 6181 bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size, 6182 OMX_U32 alignment) 6183 { 6184 //TODO: figure out if this is really necessary (PMEM_ALLOCATE_ALIGNED is a 6185 // QCOM extension to pmem 6186 return true; 6187 #if 0 6188 struct pmem_allocation allocation; 6189 allocation.size = buffer_size; 6190 allocation.align = clip2(alignment); 6191 if (allocation.align < 4096) 6192 { 6193 allocation.align = 4096; 6194 } 6195 if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) 6196 { 6197 DEBUG_PRINT_ERROR("\n Aligment failed with pmem driver"); 6198 return false; 6199 } 6200 return true; 6201 #endif 6202 } 6203 6204