1 /*--------------------------------------------------------------------------
2 Copyright (c) 2010, Code Aurora Forum. All rights reserved.
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
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 --------------------------------------------------------------------------*/
29 /*============================================================================
30 O p e n M A X w r a p p e r s
33 *//** @file omx_vdec.cpp
34 This module contains the implementation of the OpenMAX core & component.
36 *//*========================================================================*/
38 //////////////////////////////////////////////////////////////////////////////
40 //////////////////////////////////////////////////////////////////////////////
50 #define BITSTREAM_LOG 0
53 FILE *outputBufferFile1;
54 char filename [] = "/data/input-bitstream.m4v";
57 #define H264_SUPPORTED_WIDTH (480)
58 #define H264_SUPPORTED_HEIGHT (368)
60 #define MPEG4_SUPPORTED_WIDTH (480)
61 #define MPEG4_SUPPORTED_HEIGHT (368)
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
85 #define DEBUG_PRINT(...) printf(__VA_ARGS__)
86 #define DEBUG_PRINT_ERROR(...) printf(__VA_ARGS__)
87 #define DEBUG_PRINT_LOW(...) printf(__VA_ARGS__)
90 void* async_message_thread (void *input)
92 struct vdec_ioctl_msg ioctl_msg;
93 struct vdec_msginfo vdec_msg;
94 omx_vdec *omx = reinterpret_cast<omx_vdec*>(input);
96 DEBUG_PRINT_HIGH("omx_vdec: Async thread start\n");
99 ioctl_msg.inputparam = NULL;
100 ioctl_msg.outputparam = (void*)&vdec_msg;
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)
106 DEBUG_PRINT_ERROR("\n Error in ioctl read next msg");
111 /*Call Instance specific process function*/
112 if (omx->async_message_process(input,&vdec_msg) < 0)
114 DEBUG_PRINT_ERROR("\nERROR:Wrong ioctl message");
118 DEBUG_PRINT_HIGH("omx_vdec: Async thread stop\n");
122 void* message_thread(void *input)
124 omx_vdec* omx = reinterpret_cast<omx_vdec*>(input);
128 DEBUG_PRINT_HIGH("omx_vdec: message thread start\n");
132 n = read(omx->m_pipe_in, &id, 1);
141 omx->process_event_cb(omx, id);
143 if ((n < 0) && (errno != EINTR))
145 DEBUG_PRINT_ERROR("\nERROR: read from pipe failed, ret %d errno %d", n, errno);
149 DEBUG_PRINT_HIGH("omx_vdec: message thread stop\n");
153 void post_message(omx_vdec *omx, unsigned char id)
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);
161 // omx_cmd_queue destructor
162 omx_vdec::omx_cmd_queue::~omx_cmd_queue()
167 // omx cmd queue constructor
168 omx_vdec::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0)
170 memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE);
173 // omx cmd queue insert
174 bool omx_vdec::omx_cmd_queue::insert_entry(unsigned p1, unsigned p2, unsigned id)
177 if(m_size < OMX_CORE_CONTROL_CMDQ_SIZE)
179 m_q[m_write].id = id;
180 m_q[m_write].param1 = p1;
181 m_q[m_write].param2 = p2;
184 if(m_write >= OMX_CORE_CONTROL_CMDQ_SIZE)
192 DEBUG_PRINT_ERROR("ERROR: %s()::Command Queue Full\n", __func__);
198 bool omx_vdec::omx_cmd_queue::pop_entry(unsigned *p1, unsigned *p2, unsigned *id)
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
209 if(m_read >= OMX_CORE_CONTROL_CMDQ_SIZE)
221 // Retrieve the first mesg type in the queue
222 unsigned omx_vdec::omx_cmd_queue::get_q_msg_type()
224 return m_q[m_read].id;
227 // factory function executed by the core to create instances
228 void *get_omx_component_factory_fn(void)
230 return (new omx_vdec);
234 VideoHeap::VideoHeap(int fd, size_t size, void* base)
236 // dup file descriptor, map once, use pmem
237 init(dup(fd), base, size, 0 , "/dev/pmem_adsp");
241 /* ======================================================================
253 ========================================================================== */
254 omx_vdec::omx_vdec(): m_state(OMX_StateInvalid),
256 m_color_format(OMX_COLOR_FormatYUV420Planar),
259 pending_input_buffers(0),
260 pending_output_buffers(0),
263 m_inp_buf_count(OMX_VIDEO_DEC_NUM_INPUT_BUFFERS),
264 m_inp_buf_size(OMX_VIDEO_DEC_INPUT_BUFFER_SIZE),
266 m_inp_bPopulated(OMX_FALSE),
267 m_out_bPopulated(OMX_FALSE),
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),
285 input_use_buffer (false),
286 output_use_buffer (false),
288 m_outeos_pending (0),
289 m_outeos_reached (0),
290 arbitrary_bytes (true),
291 psource_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),
300 look_ahead_nal (false),
303 first_frame_size (0),
304 set_seq_header_done(false),
305 gate_output_buffers(true),
306 gate_input_buffers(false),
308 sent_first_frame(false),
309 m_error_propogated(false),
311 m_device_file_ptr(NULL),
312 m_vc1_profile((vc1_profile_type)0)
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);
328 /* ======================================================================
340 ========================================================================== */
341 omx_vdec::~omx_vdec()
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);
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");
359 /* ======================================================================
361 omx_vdec::OMXCntrlProcessMsgCb
364 IL Client callbacks are generated through this routine. The decoder
365 provides the thread context for this routine.
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
377 ========================================================================== */
378 void omx_vdec::process_event_cb(void *ctxt, unsigned char id)
380 unsigned p1; // Parameter - 1
381 unsigned p2; // Parameter - 2
383 unsigned qsize=0; // qsize
384 omx_vdec *pThis = (omx_vdec *) ctxt;
388 DEBUG_PRINT_ERROR("ERROR: %s()::Context is incorrect, bailing out\n",
393 // Protect the shared queue data structure
396 /*Read the message id's from the queue*/
397 pthread_mutex_lock(&pThis->m_lock);
398 qsize = pThis->m_cmd_q.m_size;
401 pThis->m_cmd_q.pop_entry(&p1,&p2,&ident);
404 if (qsize == 0 && !pThis->gate_output_buffers)
406 qsize = pThis->m_ftb_q.m_size;
409 pThis->m_ftb_q.pop_entry(&p1,&p2,&ident);
415 qsize = pThis->m_etb_q.m_size;
418 pThis->m_etb_q.pop_entry(&p1,&p2,&ident);
421 pthread_mutex_unlock(&pThis->m_lock);
423 /*process message if we have one*/
429 case OMX_COMPONENT_GENERATE_EVENT:
430 if (pThis->m_cb.EventHandler)
434 case OMX_CommandStateSet:
435 pThis->m_state = (OMX_STATETYPE) p2;
436 DEBUG_PRINT_HIGH("\n OMX_CommandStateSet complete, m_state = %d",
438 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
439 OMX_EventCmdComplete, p1, p2, NULL);
443 if(p2 == OMX_StateInvalid)
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);
450 else if (p2 == (unsigned)OMX_ErrorHardware)
452 pThis->omx_report_error();
456 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
457 OMX_EventError, p2, NULL, NULL );
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;
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 );
475 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
476 OMX_EventCmdComplete, p1, p2, NULL );
483 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL\n", __func__);
486 case OMX_COMPONENT_GENERATE_ETB_ARBITRARY:
487 if (pThis->empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
488 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
490 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure");
491 pThis->omx_report_error ();
494 case OMX_COMPONENT_GENERATE_ETB:
495 if (pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
496 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
498 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure");
499 pThis->omx_report_error ();
503 case OMX_COMPONENT_GENERATE_FTB:
504 if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\
505 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
507 DEBUG_PRINT_ERROR("\n fill_this_buffer_proxy failure");
508 pThis->omx_report_error ();
512 case OMX_COMPONENT_GENERATE_COMMAND:
513 pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\
514 (OMX_U32)p2,(OMX_PTR)NULL);
517 case OMX_COMPONENT_GENERATE_EBD:
519 if (p2 != VDEC_S_SUCCESS)
521 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EBD failure");
522 pThis->omx_report_error ();
526 if ( pThis->empty_buffer_done(&pThis->m_cmp,
527 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone)
529 DEBUG_PRINT_ERROR("\n empty_buffer_done failure");
530 pThis->omx_report_error ();
535 case OMX_COMPONENT_GENERATE_FBD:
536 if (p2 != VDEC_S_SUCCESS)
538 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_FBD failure");
539 pThis->omx_report_error ();
543 if ( pThis->fill_buffer_done(&pThis->m_cmp,
544 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone )
546 DEBUG_PRINT_ERROR("\n fill_buffer_done failure");
547 pThis->omx_report_error ();
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);
558 if (pThis->m_cb.EventHandler)
560 if (p2 != VDEC_S_SUCCESS)
562 DEBUG_PRINT_ERROR("\nOMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH failure");
563 pThis->omx_report_error ();
567 /*Check if we need generate event for Flush done*/
568 if(BITMASK_PRESENT(&pThis->m_flags,
569 OMX_COMPONENT_INPUT_FLUSH_PENDING))
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 );
577 if (BITMASK_PRESENT(&pThis->m_flags,
578 OMX_COMPONENT_IDLE_PENDING))
580 if (!pThis->output_flush_progress)
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)
586 DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_STOP failed");
587 pThis->omx_report_error ();
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);
601 if (pThis->m_cb.EventHandler)
603 if (p2 != VDEC_S_SUCCESS)
605 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH failed");
606 pThis->omx_report_error ();
610 /*Check if we need generate event for Flush done*/
611 if(BITMASK_PRESENT(&pThis->m_flags,
612 OMX_COMPONENT_OUTPUT_FLUSH_PENDING))
614 DEBUG_PRINT_LOW("\n Notify Output Flush done");
615 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
617 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
618 OMX_EventCmdComplete,OMX_CommandFlush,
619 OMX_CORE_OUTPUT_PORT_INDEX,NULL );
621 if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING))
623 if (!pThis->input_flush_progress)
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)
629 DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_STOP failed");
630 pThis->omx_report_error ();
638 case OMX_COMPONENT_GENERATE_START_DONE:
639 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_START_DONE");
641 if (pThis->m_cb.EventHandler)
643 if (p2 != VDEC_S_SUCCESS)
645 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_START_DONE Failure");
646 pThis->omx_report_error ();
650 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE Success");
651 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING))
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);
661 else if (BITMASK_PRESENT(&pThis->m_flags,
662 OMX_COMPONENT_PAUSE_PENDING))
664 if (ioctl (pThis->driver_context.video_driver_fd,
665 VDEC_IOCTL_CMD_PAUSE,NULL ) < 0)
667 DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_PAUSE failed");
668 pThis->omx_report_error ();
675 DEBUG_PRINT_LOW("\n Event Handler callback is NULL");
679 case OMX_COMPONENT_GENERATE_PAUSE_DONE:
680 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_PAUSE_DONE");
681 if (pThis->m_cb.EventHandler)
683 if (p2 != VDEC_S_SUCCESS)
685 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_PAUSE_DONE ret failed");
686 pThis->omx_report_error ();
690 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING))
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);
705 case OMX_COMPONENT_GENERATE_RESUME_DONE:
706 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_RESUME_DONE");
707 if (pThis->m_cb.EventHandler)
709 if (p2 != VDEC_S_SUCCESS)
711 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_RESUME_DONE failed");
712 pThis->omx_report_error ();
716 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING))
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);
731 case OMX_COMPONENT_GENERATE_STOP_DONE:
732 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_STOP_DONE");
733 if (pThis->m_cb.EventHandler)
735 if (p2 != VDEC_S_SUCCESS)
737 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_STOP_DONE ret failed");
738 pThis->omx_report_error ();
742 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING))
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,
758 case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
759 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_HARDWARE_ERROR");
760 pThis->omx_report_error ();
767 pthread_mutex_lock(&pThis->m_lock);
768 if(!pThis->gate_output_buffers)
770 qsize = pThis->m_cmd_q.m_size + pThis->m_ftb_q.m_size +\
771 pThis->m_etb_q.m_size;
775 qsize = pThis->m_cmd_q.m_size + pThis->m_etb_q.m_size;
777 pthread_mutex_unlock(&pThis->m_lock);
785 /* ======================================================================
787 omx_vdec::ComponentInit
790 Initialize the component.
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
802 ========================================================================== */
803 OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role)
806 OMX_ERRORTYPE eRet = OMX_ErrorNone;
807 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
808 unsigned int alignment = 0,buffer_size = 0;
811 bool is_fluid = false;
813 if (!m_device_file_ptr) {
814 int bytes_read = 0,count = 0;
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"));
824 if (!strncmp("Fluid",(const char *)m_hwdevice_name,min_size)) {
827 fclose (m_device_file_ptr);
829 DEBUG_PRINT_HIGH("\n Could not open hw_platform file");
833 DEBUG_PRINT_HIGH("\n omx_vdec::component_init(): Start of New Playback");
834 driver_context.video_driver_fd = open ("/dev/msm_vidc_dec",\
837 DEBUG_PRINT_HIGH("\n omx_vdec::component_init(): Open returned fd %d",
838 driver_context.video_driver_fd);
840 if(driver_context.video_driver_fd == 0){
841 driver_context.video_driver_fd = open ("/dev/msm_vidc_dec",\
845 if(driver_context.video_driver_fd < 0)
847 DEBUG_PRINT_ERROR("Omx_vdec::Comp Init Returning failure\n");
848 return OMX_ErrorInsufficientResources;
851 #ifndef MULTI_DEC_INST
852 unsigned int instance_count = 0;
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;
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;
870 outputBufferFile1 = fopen (filename, "ab");
873 // Copy the role information which provides the decoder kind
874 strncpy(driver_context.kind,role,128);
876 if(!strncmp(driver_context.kind,"OMX.qcom.video.decoder.mpeg4",\
877 OMX_MAX_STRINGNAME_SIZE))
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);
887 else if(!strncmp(driver_context.kind, "OMX.qcom.video.decoder.h263",\
888 OMX_MAX_STRINGNAME_SIZE))
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);
897 else if(!strncmp(driver_context.kind, "OMX.qcom.video.decoder.avc",\
898 OMX_MAX_STRINGNAME_SIZE))
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);
907 else if(!strncmp(driver_context.kind, "OMX.qcom.video.decoder.vc1",\
908 OMX_MAX_STRINGNAME_SIZE))
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);
918 DEBUG_PRINT_ERROR("\nERROR:Unknown Component\n");
919 eRet = OMX_ErrorInvalidComponentName;
922 if (eRet == OMX_ErrorNone)
924 driver_context.output_format = VDEC_YUV_FORMAT_NV12;
929 char disable_overlay = '0';
931 ("/data/data/com.arcsoft.videowall/files/disableoverlay.txt", "rb" );
933 DEBUG_PRINT_HIGH(" fopen FAiLED for disableoverlay.txt\n");
935 int count = fread(&disable_overlay, 1, 1, pFile);
939 if(disable_overlay == '1') {
940 DEBUG_PRINT_HIGH(" vdec : TILE format \n");
941 driver_context.output_format = VDEC_YUV_FORMAT_TILE_4x2;
943 DEBUG_PRINT_HIGH(" vdec : NV 12 format \n");
944 driver_context.output_format = VDEC_YUV_FORMAT_NV12;
948 /*Initialize Decoder with codec type and resolution*/
949 ioctl_msg.inputparam = &driver_context.decoder_format;
950 ioctl_msg.outputparam = NULL;
952 if ( (eRet == OMX_ErrorNone) &&
953 ioctl (driver_context.video_driver_fd,VDEC_IOCTL_SET_CODEC,
954 (void*)&ioctl_msg) < 0)
957 DEBUG_PRINT_ERROR("\n Set codec type failed");
958 eRet = OMX_ErrorInsufficientResources;
961 /*Set the output format*/
962 ioctl_msg.inputparam = &driver_context.output_format;
963 ioctl_msg.outputparam = NULL;
965 if ( (eRet == OMX_ErrorNone) &&
966 ioctl (driver_context.video_driver_fd,VDEC_IOCTL_SET_OUTPUT_FORMAT,
967 (void*)&ioctl_msg) < 0)
969 DEBUG_PRINT_ERROR("\n Set output format failed");
970 eRet = OMX_ErrorInsufficientResources;
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;
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;
986 ioctl_msg.inputparam = &driver_context.video_resoultion;
987 ioctl_msg.outputparam = NULL;
989 if ( (eRet == OMX_ErrorNone) &&
990 ioctl (driver_context.video_driver_fd,VDEC_IOCTL_SET_PICRES,
991 (void*)&ioctl_msg) < 0)
993 DEBUG_PRINT_ERROR("\n Set Resolution failed");
994 eRet = OMX_ErrorInsufficientResources;
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;
1002 if ( (eRet == OMX_ErrorNone) &&
1003 ioctl (driver_context.video_driver_fd,VDEC_IOCTL_GET_BUFFER_REQ,
1004 (void*)&ioctl_msg) < 0)
1006 DEBUG_PRINT_ERROR("\n Requesting for input buffer requirements failed");
1007 eRet = OMX_ErrorInsufficientResources;
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;
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;
1021 m_inp_buf_count_min = m_inp_buf_count = driver_context.input_buffer.actualcount =
1022 driver_context.input_buffer.mincount + 3;
1024 if ( (eRet == OMX_ErrorNone) &&
1025 ioctl (driver_context.video_driver_fd,VDEC_IOCTL_SET_BUFFER_REQ,
1026 (void*)&ioctl_msg) < 0)
1028 DEBUG_PRINT_ERROR("\n Set input buffer requirements failed");
1029 eRet = OMX_ErrorInsufficientResources;
1033 driver_context.output_buffer.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
1034 ioctl_msg.inputparam = NULL;
1035 ioctl_msg.outputparam = &driver_context.output_buffer;
1037 if ((eRet == OMX_ErrorNone) &&
1038 ioctl (driver_context.video_driver_fd,VDEC_IOCTL_GET_BUFFER_REQ,
1039 (void*)&ioctl_msg) < 0)
1041 DEBUG_PRINT_ERROR("\n Requesting for output buffer requirements failed");
1042 eRet = OMX_ErrorInsufficientResources;
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;
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)));
1053 scan_lines = m_crop_dy = m_height = 720;
1054 stride = m_crop_dx = m_width = 1280;
1056 #ifdef MAX_RES_1080P
1057 scan_lines = m_crop_dy = m_height = 1088;
1058 stride = m_crop_dx = m_width = 1920;
1060 m_port_height = m_height;
1061 m_port_width = m_width;
1062 m_state = OMX_StateLoaded;
1066 DEBUG_PRINT_ERROR("pipe creation failed\n");
1067 eRet = OMX_ErrorInsufficientResources;
1072 if(fds[0] == 0 || fds[1] == 0)
1076 DEBUG_PRINT_ERROR("pipe creation failed\n");
1077 return OMX_ErrorInsufficientResources;
1085 m_pipe_out = fds[1];
1086 r = pthread_create(&msg_thread_id,0,message_thread,this);
1090 DEBUG_PRINT_ERROR("\n component_init(): message_thread creation failed");
1091 eRet = OMX_ErrorInsufficientResources;
1095 r = pthread_create(&async_thread_id,0,async_message_thread,this);
1098 DEBUG_PRINT_ERROR("\n component_init(): async_message_thread creation failed");
1099 eRet = OMX_ErrorInsufficientResources;
1105 if (eRet != OMX_ErrorNone)
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,
1111 DEBUG_PRINT_HIGH("\n Calling close() on Video Driver");
1112 close (driver_context.video_driver_fd);
1113 driver_context.video_driver_fd = -1;
1117 DEBUG_PRINT_HIGH("\n omx_vdec::component_init() success");
1123 /* ======================================================================
1125 omx_vdec::GetComponentVersion
1128 Returns the component version.
1136 ========================================================================== */
1137 OMX_ERRORTYPE omx_vdec::get_component_version
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
1146 if(m_state == OMX_StateInvalid)
1148 DEBUG_PRINT_ERROR("Get Comp Version in Invalid State\n");
1149 return OMX_ErrorInvalidState;
1151 /* TBD -- Return the proper version */
1152 return OMX_ErrorNone;
1154 /* ======================================================================
1156 omx_vdec::SendCommand
1159 Returns zero if all the buffers released..
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
1174 DEBUG_PRINT_LOW("\n send_command: Recieved a Command from Client");
1175 if(m_state == OMX_StateInvalid)
1177 DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State\n");
1178 return OMX_ErrorInvalidState;
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;
1186 /* ======================================================================
1188 omx_vdec::SendCommand
1191 Returns zero if all the buffers released..
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
1206 OMX_ERRORTYPE eRet = OMX_ErrorNone;
1207 OMX_STATETYPE eState = (OMX_STATETYPE) param1;
1208 int bFlag = 1,sem_posted = 0;;
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",
1214 if(cmd == OMX_CommandStateSet)
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)
1223 if(eState == OMX_StateIdle)
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))
1229 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle\n");
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
1239 /* Requesting transition from Loaded to Loaded */
1240 else if(eState == OMX_StateLoaded)
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;
1247 /* Requesting transition from Loaded to WaitForResources */
1248 else if(eState == OMX_StateWaitForResources)
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");
1254 /* Requesting transition from Loaded to Executing */
1255 else if(eState == OMX_StateExecuting)
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;
1262 /* Requesting transition from Loaded to Pause */
1263 else if(eState == OMX_StatePause)
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;
1270 /* Requesting transition from Loaded to Invalid */
1271 else if(eState == OMX_StateInvalid)
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;
1279 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)\n",\
1281 eRet = OMX_ErrorBadParameter;
1285 /***************************/
1286 /* Current State is IDLE */
1287 /***************************/
1288 else if(m_state == OMX_StateIdle)
1290 if(eState == OMX_StateLoaded)
1295 Since error is None , we will post an event at the end
1296 of this function definition
1298 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded\n");
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
1308 /* Requesting transition from Idle to Executing */
1309 else if(eState == OMX_StateExecuting)
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);
1316 /* Requesting transition from Idle to Idle */
1317 else if(eState == OMX_StateIdle)
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;
1324 /* Requesting transition from Idle to WaitForResources */
1325 else if(eState == OMX_StateWaitForResources)
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;
1332 /* Requesting transition from Idle to Pause */
1333 else if(eState == OMX_StatePause)
1335 /*To pause the Video core we need to start the driver*/
1336 if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_CMD_START,
1339 DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_START FAILED");
1340 omx_report_error ();
1341 eRet = OMX_ErrorHardware;
1345 BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
1346 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Pause\n");
1350 /* Requesting transition from Idle to Invalid */
1351 else if(eState == OMX_StateInvalid)
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;
1359 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled\n",eState);
1360 eRet = OMX_ErrorBadParameter;
1364 /******************************/
1365 /* Current State is Executing */
1366 /******************************/
1367 else if(m_state == OMX_StateExecuting)
1369 DEBUG_PRINT_LOW("\n Command Recieved in OMX_StateExecuting");
1370 /* Requesting transition from Executing to Idle */
1371 if(eState == OMX_StateIdle)
1373 /* Since error is None , we will post an event
1374 at the end of this function definition
1376 DEBUG_PRINT_LOW("\n send_command_proxy(): Executing --> Idle \n");
1377 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
1381 sem_post (&m_cmd_lock);
1382 execute_omx_flush(OMX_ALL);
1386 /* Requesting transition from Executing to Paused */
1387 else if(eState == OMX_StatePause)
1389 DEBUG_PRINT_LOW("\n PAUSE Command Issued");
1390 if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_CMD_PAUSE,
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;
1400 BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
1401 DEBUG_PRINT_LOW("send_command_proxy(): Pause-->Executing\n");
1405 /* Requesting transition from Executing to Loaded */
1406 else if(eState == OMX_StateLoaded)
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;
1413 /* Requesting transition from Executing to WaitForResources */
1414 else if(eState == OMX_StateWaitForResources)
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;
1421 /* Requesting transition from Executing to Executing */
1422 else if(eState == OMX_StateExecuting)
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;
1429 /* Requesting transition from Executing to Invalid */
1430 else if(eState == OMX_StateInvalid)
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;
1438 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled\n",eState);
1439 eRet = OMX_ErrorBadParameter;
1442 /***************************/
1443 /* Current State is Pause */
1444 /***************************/
1445 else if(m_state == OMX_StatePause)
1447 /* Requesting transition from Pause to Executing */
1448 if(eState == OMX_StateExecuting)
1450 DEBUG_PRINT_LOW("\n Pause --> Executing \n");
1451 if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_CMD_RESUME,
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;
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);
1468 /* Requesting transition from Pause to Idle */
1469 else if(eState == OMX_StateIdle)
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);
1478 sem_post (&m_cmd_lock);
1479 execute_omx_flush(OMX_ALL);
1483 /* Requesting transition from Pause to loaded */
1484 else if(eState == OMX_StateLoaded)
1486 DEBUG_PRINT_ERROR("\n Pause --> loaded \n");
1487 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1488 OMX_COMPONENT_GENERATE_EVENT);
1489 eRet = OMX_ErrorIncorrectStateTransition;
1491 /* Requesting transition from Pause to WaitForResources */
1492 else if(eState == OMX_StateWaitForResources)
1494 DEBUG_PRINT_ERROR("\n Pause --> WaitForResources \n");
1495 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1496 OMX_COMPONENT_GENERATE_EVENT);
1497 eRet = OMX_ErrorIncorrectStateTransition;
1499 /* Requesting transition from Pause to Pause */
1500 else if(eState == OMX_StatePause)
1502 DEBUG_PRINT_ERROR("\n Pause --> Pause \n");
1503 post_event(OMX_EventError,OMX_ErrorSameState,\
1504 OMX_COMPONENT_GENERATE_EVENT);
1505 eRet = OMX_ErrorSameState;
1507 /* Requesting transition from Pause to Invalid */
1508 else if(eState == OMX_StateInvalid)
1510 DEBUG_PRINT_ERROR("\n Pause --> Invalid \n");
1511 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
1512 eRet = OMX_ErrorInvalidState;
1516 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled\n",eState);
1517 eRet = OMX_ErrorBadParameter;
1520 /***************************/
1521 /* Current State is WaitForResources */
1522 /***************************/
1523 else if(m_state == OMX_StateWaitForResources)
1525 /* Requesting transition from WaitForResources to Loaded */
1526 if(eState == OMX_StateLoaded)
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");
1532 /* Requesting transition from WaitForResources to WaitForResources */
1533 else if (eState == OMX_StateWaitForResources)
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;
1540 /* Requesting transition from WaitForResources to Executing */
1541 else if(eState == OMX_StateExecuting)
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;
1548 /* Requesting transition from WaitForResources to Pause */
1549 else if(eState == OMX_StatePause)
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;
1556 /* Requesting transition from WaitForResources to Invalid */
1557 else if(eState == OMX_StateInvalid)
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;
1563 /* Requesting transition from WaitForResources to Loaded -
1564 is NOT tested by Khronos TS */
1569 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)\n",m_state,eState);
1570 eRet = OMX_ErrorBadParameter;
1573 /********************************/
1574 /* Current State is Invalid */
1575 /*******************************/
1576 else if(m_state == OMX_StateInvalid)
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))
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;
1589 else if (cmd == OMX_CommandFlush)
1591 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandFlush issued"
1592 "with param1: %d", param1);
1593 if(0 == param1 || OMX_ALL == param1)
1595 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
1597 if(1 == param1 || OMX_ALL == param1)
1599 //generate output flush event only.
1600 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
1604 DEBUG_PRINT_LOW("\n Set the Semaphore");
1605 sem_post (&m_cmd_lock);
1606 execute_omx_flush(param1);
1610 else if ( cmd == OMX_CommandPortEnable)
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)
1616 m_inp_bEnabled = OMX_TRUE;
1618 if( (m_state == OMX_StateLoaded &&
1619 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
1620 || allocate_input_done())
1622 post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX,
1623 OMX_COMPONENT_GENERATE_EVENT);
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
1633 if(param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL)
1635 DEBUG_PRINT_LOW("\n Enable output Port command recieved");
1636 m_out_bEnabled = OMX_TRUE;
1638 if( (m_state == OMX_StateLoaded &&
1639 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
1640 || (allocate_output_done()))
1642 post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX,
1643 OMX_COMPONENT_GENERATE_EVENT);
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
1655 else if (cmd == OMX_CommandPortDisable)
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)
1661 m_inp_bEnabled = OMX_FALSE;
1662 if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
1663 && release_input_done())
1665 post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX,
1666 OMX_COMPONENT_GENERATE_EVENT);
1670 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
1671 if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting)
1676 sem_post (&m_cmd_lock);
1677 execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX);
1681 // Skip the event notification
1685 if(param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL)
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())
1692 post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\
1693 OMX_COMPONENT_GENERATE_EVENT);
1697 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
1698 if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting)
1703 sem_post (&m_cmd_lock);
1704 execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX);
1707 // Skip the event notification
1715 DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)\n",cmd);
1716 eRet = OMX_ErrorNotImplemented;
1718 if(eRet == OMX_ErrorNone && bFlag)
1720 post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
1724 sem_post(&m_cmd_lock);
1730 /* ======================================================================
1732 omx_vdec::ExecuteOmxFlush
1735 Executes the OMX flush.
1738 flushtype - input flush(1)/output flush(0)/ both.
1743 ========================================================================== */
1744 bool omx_vdec::execute_omx_flush(OMX_U32 flushType)
1746 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
1747 enum vdec_bufferflush flush_dir = VDEC_FLUSH_TYPE_ALL;
1750 if(flushType == 0 || flushType == OMX_ALL)
1752 input_flush_progress = true;
1754 bRet = execute_input_flush(flushType);
1756 if(flushType == 1 || flushType == OMX_ALL)
1759 output_flush_progress = true;
1760 bRet = execute_output_flush(flushType);
1763 if(flushType == OMX_ALL)
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;
1770 if (ioctl(driver_context.video_driver_fd,VDEC_IOCTL_CMD_FLUSH,&ioctl_msg) < 0)
1772 DEBUG_PRINT_ERROR("\n Flush ALL Failed ");
1779 /*=========================================================================
1780 FUNCTION : execute_output_flush
1783 Executes the OMX flush at OUTPUT PORT.
1790 ==========================================================================*/
1791 bool omx_vdec::execute_output_flush(OMX_U32 flushType)
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
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)
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);
1809 if(ident == OMX_COMPONENT_GENERATE_FTB )
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);
1815 else if (ident == OMX_COMPONENT_GENERATE_FBD)
1817 fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
1820 pthread_mutex_unlock(&m_lock);
1822 if(gate_output_buffers)
1824 DEBUG_PRINT_LOW("\n Output Buffers gated Check flush response");
1825 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING))
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 );
1832 output_flush_progress = false;
1836 DEBUG_PRINT_LOW("\n output buffers count = %d",pending_output_buffers);
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;
1845 if (ioctl(driver_context.video_driver_fd,VDEC_IOCTL_CMD_FLUSH,&ioctl_msg) < 0)
1847 DEBUG_PRINT_ERROR("\n output flush failed");
1854 /*=========================================================================
1855 FUNCTION : execute_input_flush
1858 Executes the OMX flush at INPUT PORT.
1865 ==========================================================================*/
1866 bool omx_vdec::execute_input_flush(OMX_U32 flushType)
1868 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
1869 enum vdec_bufferflush flush_dir = VDEC_FLUSH_TYPE_INPUT;
1871 unsigned p1 = 0; // Parameter - 1
1872 unsigned p2 = 0; // Parameter - 2
1876 /*Generate EBD for all Buffers in the ETBq*/
1877 DEBUG_PRINT_LOW("\n Initiate Input Flush \n");
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)
1883 m_etb_q.pop_entry(&p1,&p2,&ident);
1885 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY)
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);
1890 else if(ident == OMX_COMPONENT_GENERATE_ETB)
1892 pending_input_buffers++;
1893 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
1895 else if (ident == OMX_COMPONENT_GENERATE_EBD)
1897 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
1901 /*Check if Heap Buffers are to be flushed*/
1902 if (arbitrary_bytes)
1904 DEBUG_PRINT_LOW("\n Reset all the variables before flusing");
1905 h264_scratch.nFilledLen = 0;
1907 look_ahead_nal = false;
1909 DEBUG_PRINT_LOW("\n Initialize parser");
1910 if (m_frame_parser.mutils)
1912 m_frame_parser.mutils->initialize_frame_checking_environment();
1915 while (m_input_pending_q.m_size)
1917 m_input_pending_q.pop_entry(&p1,&p2,&ident);
1918 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1);
1923 m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame);
1924 psource_frame = NULL;
1929 pdest_frame->nFilledLen = 0;
1930 m_input_free_q.insert_entry((unsigned) pdest_frame,NULL,NULL);
1933 m_frame_parser.flush();
1936 pthread_mutex_unlock(&m_lock);
1937 DEBUG_PRINT_LOW("\n Value of pending input buffers %d \n",pending_input_buffers);
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;
1946 if (ioctl(driver_context.video_driver_fd,VDEC_IOCTL_CMD_FLUSH,&ioctl_msg) < 0)
1948 DEBUG_PRINT_ERROR("\n Input Flush Failed ");
1957 /* ======================================================================
1959 omx_vdec::SendCommandEvent
1962 Send the event to decoder pipe. This is needed to generate the callbacks
1963 in decoder thread context.
1971 ========================================================================== */
1972 bool omx_vdec::post_event(unsigned int p1,
1979 pthread_mutex_lock(&m_lock);
1981 if( id == OMX_COMPONENT_GENERATE_FTB || \
1982 (id == OMX_COMPONENT_GENERATE_FBD)||
1983 (id == OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH))
1985 m_ftb_q.insert_entry(p1,p2,id);
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))
1992 m_etb_q.insert_entry(p1,p2,id);
1996 m_cmd_q.insert_entry(p1,p2,id);
2000 DEBUG_PRINT_LOW("\n Value of this pointer in post_event %p",this);
2001 post_message(this, id);
2003 pthread_mutex_unlock(&m_lock);
2008 /* ======================================================================
2010 omx_vdec::GetParameter
2013 OMX Get Parameter method implementation
2019 Error None if successful.
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)
2026 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2027 unsigned int height=0,width = 0;
2029 DEBUG_PRINT_LOW("get_parameter: \n");
2030 if(m_state == OMX_StateInvalid)
2032 DEBUG_PRINT_ERROR("Get Param in Invalid State\n");
2033 return OMX_ErrorInvalidState;
2035 if(paramData == NULL)
2037 DEBUG_PRINT_LOW("Get Param in Invalid paramData \n");
2038 return OMX_ErrorBadParameter;
2042 case OMX_IndexParamPortDefinition:
2044 OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
2045 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
2047 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition\n");
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;
2058 if (0 == portDefn->nPortIndex)
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;
2071 else if (1 == portDefn->nPortIndex)
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;
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",
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);
2099 portDefn->eDir = OMX_DirMax;
2100 DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
2101 (int)portDefn->nPortIndex);
2102 eRet = OMX_ErrorBadPortIndex;
2107 case OMX_IndexParamVideoInit:
2109 OMX_PORT_PARAM_TYPE *portParamType =
2110 (OMX_PORT_PARAM_TYPE *) paramData;
2111 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit\n");
2113 portParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2114 portParamType->nSize = sizeof(portParamType);
2115 portParamType->nPorts = 2;
2116 portParamType->nStartPortNumber = 0;
2119 case OMX_IndexParamVideoPortFormat:
2121 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
2122 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
2123 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat\n");
2125 portFmt->nVersion.nVersion = OMX_SPEC_VERSION;
2126 portFmt->nSize = sizeof(portFmt);
2128 if (0 == portFmt->nPortIndex)
2130 if (0 == portFmt->nIndex)
2132 portFmt->eColorFormat = OMX_COLOR_FormatUnused;
2133 portFmt->eCompressionFormat = eCompressionFormat;
2137 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\
2138 " NoMore compression formats\n");
2139 eRet = OMX_ErrorNoMore;
2142 else if (1 == portFmt->nPortIndex)
2144 if (0 == portFmt->nIndex)
2146 if (driver_context.output_format == VDEC_YUV_FORMAT_NV12)
2147 portFmt->eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
2149 portFmt->eColorFormat = (OMX_COLOR_FORMATTYPE)0x7F000000;
2151 portFmt->eCompressionFormat = OMX_VIDEO_CodingUnused;
2155 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\
2156 " NoMore Color formats\n");
2157 eRet = OMX_ErrorNoMore;
2162 DEBUG_PRINT_ERROR("get_parameter: Bad port index %d\n",
2163 (int)portFmt->nPortIndex);
2164 eRet = OMX_ErrorBadPortIndex;
2168 /*Component should support this port definition*/
2169 case OMX_IndexParamAudioInit:
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;
2180 /*Component should support this port definition*/
2181 case OMX_IndexParamImageInit:
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;
2193 /*Component should support this port definition*/
2194 case OMX_IndexParamOtherInit:
2196 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x\n",
2198 eRet =OMX_ErrorUnsupportedIndex;
2201 case OMX_IndexParamStandardComponentRole:
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);
2208 DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d\n",
2210 strncpy((char*)comp_role->cRole,(const char*)m_cRole,
2211 OMX_MAX_STRINGNAME_SIZE);
2214 /* Added for parameter test */
2215 case OMX_IndexParamPriorityMgmt:
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);
2226 /* Added for parameter test */
2227 case OMX_IndexParamCompBufferSupplier:
2229 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType =
2230 (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
2231 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier\n");
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;
2240 eRet = OMX_ErrorBadPortIndex;
2245 case OMX_IndexParamVideoAvc:
2247 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x\n",
2251 case OMX_IndexParamVideoH263:
2253 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x\n",
2257 case OMX_IndexParamVideoMpeg4:
2259 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x\n",
2265 DEBUG_PRINT_ERROR("get_parameter: unknown param %08x\n", paramIndex);
2266 eRet =OMX_ErrorUnsupportedIndex;
2271 DEBUG_PRINT_LOW("\n get_parameter returning Height %d , Width %d \n",
2277 /* ======================================================================
2279 omx_vdec::Setparameter
2282 OMX Set Parameter method implementation.
2288 OMX Error None if successful.
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)
2295 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2296 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
2297 unsigned int alignment = 0,buffer_size = 0;
2300 if(m_state == OMX_StateInvalid)
2302 DEBUG_PRINT_ERROR("Set Param in Invalid State\n");
2303 return OMX_ErrorInvalidState;
2305 if(paramData == NULL)
2307 DEBUG_PRINT_ERROR("Get Param in Invalid paramData \n");
2308 return OMX_ErrorBadParameter;
2312 case OMX_IndexParamPortDefinition:
2314 OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
2315 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
2317 /*set_parameter can be called in loaded state
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)))
2327 DEBUG_PRINT_LOW("Set Parameter called in valid state");
2331 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n");
2332 return OMX_ErrorIncorrectStateOperation;
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);
2338 eRet = omx_vdec_validate_port_param(portDefn->format.video.nFrameHeight,
2339 portDefn->format.video.nFrameWidth);
2340 if(eRet != OMX_ErrorNone)
2342 return OMX_ErrorUnsupportedSetting;
2344 if(OMX_DirOutput == portDefn->eDir)
2346 if ( portDefn->nBufferCountActual < m_out_buf_count_min ||
2347 portDefn->nBufferSize != m_out_buf_size
2350 return OMX_ErrorBadParameter;
2352 driver_context.output_buffer.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
2353 ioctl_msg.inputparam = NULL;
2354 ioctl_msg.outputparam = &driver_context.output_buffer;
2356 if (ioctl (driver_context.video_driver_fd,
2357 VDEC_IOCTL_GET_BUFFER_REQ,(void*)&ioctl_msg) < 0)
2359 DEBUG_PRINT_ERROR("\n Request output buffer requirements failed");
2360 return OMX_ErrorUnsupportedSetting;
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;
2368 if (ioctl (driver_context.video_driver_fd,
2369 VDEC_IOCTL_SET_BUFFER_REQ,(void*)&ioctl_msg) < 0)
2371 DEBUG_PRINT_ERROR("\n Request output buffer requirements failed");
2372 return OMX_ErrorUnsupportedSetting;
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");
2378 else if(OMX_DirInput == portDefn->eDir)
2380 if(m_height != portDefn->format.video.nFrameHeight ||
2381 m_width != portDefn->format.video.nFrameWidth)
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))
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;
2405 if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_SET_PICRES,
2406 (void*)&ioctl_msg) < 0)
2408 DEBUG_PRINT_ERROR("\n Set Resolution failed");
2409 return OMX_ErrorUnsupportedSetting;
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;
2416 if (ioctl (driver_context.video_driver_fd,
2417 VDEC_IOCTL_GET_BUFFER_REQ,(void*)&ioctl_msg) < 0)
2419 DEBUG_PRINT_ERROR("\n Request output buffer requirements failed");
2420 return OMX_ErrorUnsupportedSetting;
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;
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)));
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
2440 if ( portDefn->nBufferCountActual < m_inp_buf_count_min ||
2441 portDefn->nBufferSize != m_inp_buf_size
2444 return OMX_ErrorBadParameter;
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;
2451 if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_GET_BUFFER_REQ,
2452 (void*)&ioctl_msg) < 0)
2454 DEBUG_PRINT_ERROR("\n Request input buffer requirements failed");
2455 return OMX_ErrorUnsupportedSetting;
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;
2464 if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_SET_BUFFER_REQ,
2465 (void*)&ioctl_msg) < 0)
2467 DEBUG_PRINT_ERROR("\n Request input buffer requirements failed");
2468 return OMX_ErrorUnsupportedSetting;
2471 m_inp_buf_count = portDefn->nBufferCountActual;
2472 DEBUG_PRINT_LOW("\n set_parameter: Image Dimensions same \n");
2476 else if (portDefn->eDir == OMX_DirMax)
2478 DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d",
2479 (int)portDefn->nPortIndex);
2480 eRet = OMX_ErrorBadPortIndex;
2486 case OMX_IndexParamVideoPortFormat:
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);
2493 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d\n",
2494 portFmt->eColorFormat);
2495 if(1 == portFmt->nPortIndex)
2498 m_color_format = portFmt->eColorFormat;
2503 case OMX_QcomIndexPortDefn:
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);
2511 if (portFmt->nPortIndex == 0)
2513 if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary)
2515 arbitrary_bytes = true;
2517 else if (portFmt->nFramePackingFormat ==
2518 OMX_QCOM_FramePacking_OnlyOneCompleteFrame)
2520 arbitrary_bytes = false;
2524 DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %d\n",
2525 portFmt->nFramePackingFormat);
2526 eRet = OMX_ErrorUnsupportedSetting;
2532 case OMX_IndexParamStandardComponentRole:
2534 OMX_PARAM_COMPONENTROLETYPE *comp_role;
2535 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
2536 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s\n",
2539 if((m_state == OMX_StateLoaded)&&
2540 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2542 DEBUG_PRINT_LOW("Set Parameter called in valid state");
2546 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n");
2547 return OMX_ErrorIncorrectStateOperation;
2550 if(!strncmp(driver_context.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE))
2552 if(!strncmp((char*)comp_role->cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE))
2554 strncpy((char*)m_cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
2558 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
2559 eRet =OMX_ErrorUnsupportedSetting;
2562 else if(!strncmp(driver_context.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
2564 if(!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
2566 strncpy((char*)m_cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
2570 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
2571 eRet = OMX_ErrorUnsupportedSetting;
2574 else if(!strncmp(driver_context.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))
2576 if(!strncmp((const char*)comp_role->cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE))
2578 strncpy((char*)m_cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
2582 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
2583 eRet =OMX_ErrorUnsupportedSetting;
2586 else if(!strncmp(driver_context.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE))
2588 if(!strncmp((const char*)comp_role->cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE))
2590 strncpy((char*)m_cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
2594 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
2595 eRet =OMX_ErrorUnsupportedSetting;
2600 DEBUG_PRINT_ERROR("Setparameter: unknown param %s\n", driver_context.kind);
2601 eRet = OMX_ErrorInvalidComponentName;
2606 case OMX_IndexParamPriorityMgmt:
2608 if(m_state != OMX_StateLoaded)
2610 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n");
2611 return OMX_ErrorIncorrectStateOperation;
2613 OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
2614 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %d\n",
2615 priorityMgmtype->nGroupID);
2617 DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %d\n",
2618 priorityMgmtype->nGroupPriority);
2620 m_priority_mgm.nGroupID = priorityMgmtype->nGroupID;
2621 m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority;
2626 case OMX_IndexParamCompBufferSupplier:
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;
2636 eRet = OMX_ErrorBadPortIndex;
2641 case OMX_IndexParamVideoAvc:
2643 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d\n",
2647 case OMX_IndexParamVideoH263:
2649 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d\n",
2653 case OMX_IndexParamVideoMpeg4:
2655 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d\n",
2662 DEBUG_PRINT_ERROR("Setparameter: unknown param %d\n", paramIndex);
2663 eRet = OMX_ErrorUnsupportedIndex;
2670 /* ======================================================================
2675 OMX Get Config Method implementation.
2681 OMX Error None if successful.
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)
2688 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2690 if (m_state == OMX_StateInvalid)
2692 DEBUG_PRINT_ERROR("Get Config in Invalid State\n");
2693 return OMX_ErrorInvalidState;
2696 switch (configIndex)
2698 case OMX_QcomIndexConfigInterlaced:
2700 OMX_QCOM_CONFIG_INTERLACETYPE *configFmt =
2701 (OMX_QCOM_CONFIG_INTERLACETYPE *) configData;
2702 if (configFmt->nPortIndex == 1)
2704 if (configFmt->nIndex == 0)
2706 configFmt->eInterlaceType = OMX_QCOM_InterlaceFrameProgressive;
2708 else if (configFmt->nIndex == 1)
2710 configFmt->eInterlaceType =
2711 OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
2713 else if (configFmt->nIndex == 2)
2715 configFmt->eInterlaceType =
2716 OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
2720 DEBUG_PRINT_ERROR("get_config: OMX_QcomIndexConfigInterlaced:"
2721 " NoMore Interlaced formats\n");
2722 eRet = OMX_ErrorNoMore;
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;
2734 case OMX_QcomIndexQueryNumberOfVideoDecInstance:
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));
2746 DEBUG_PRINT_ERROR("get_config: unknown param %d\n",configIndex);
2747 eRet = OMX_ErrorBadParameter;
2755 /* ======================================================================
2760 OMX Set Config method implementation
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)
2772 if(m_state == OMX_StateInvalid)
2774 DEBUG_PRINT_ERROR("Get Config in Invalid State\n");
2775 return OMX_ErrorInvalidState;
2778 OMX_ERRORTYPE ret = OMX_ErrorNone;
2779 OMX_VIDEO_CONFIG_NALSIZE *pNal;
2781 DEBUG_PRINT_LOW("\n Set Config Called");
2783 if (m_state == OMX_StateExecuting)
2785 DEBUG_PRINT_ERROR("set_config:Ignore in Exe state\n");
2789 if (configIndex == OMX_IndexVendorVideoExtraData)
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"))
2795 DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData AVC");
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.
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;
2810 /* Presently we assume that only one SPS and one PPS in AvC1 Atom */
2811 extra_size = (nal_length - 2) * 2;
2814 // SPS starts from byte #6
2815 OMX_U8 *pSrcBuf = (OMX_U8 *) (&config->pData[6]);
2817 m_vendor_config.nPortIndex = config->nPortIndex;
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);
2825 // case where SPS+PPS is sent as part of set_config
2826 pDestBuf = m_vendor_config.pData;
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);
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++)
2842 pDestBuf[i] = psize[nal_length - 1 - i];
2844 //memcpy(pDestBuf,pSrcBuf,(len+2));
2845 pDestBuf += len + nal_length;
2848 pSrcBuf++; // skip picture param set
2852 else if (!strcmp(driver_context.kind, "OMX.qcom.video.decoder.mpeg4"))
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);
2859 else if (!strcmp(driver_context.kind, "OMX.qcom.video.decoder.vc1"))
2861 if(m_vendor_config.pData)
2863 free(m_vendor_config.pData);
2864 m_vendor_config.pData = NULL;
2865 m_vendor_config.nDataSize = 0;
2868 if (((*((OMX_U32 *) config->pData)) &
2869 VC1_SP_MP_START_CODE_MASK) ==
2870 VC1_SP_MP_START_CODE)
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,
2879 m_vc1_profile = VC1_SP_MP_RCV;
2881 else if (*((OMX_U32 *) config->pData) == VC1_AP_SEQ_START_CODE)
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,
2890 m_vc1_profile = VC1_AP;
2892 else if ((config->nDataSize == VC1_STRUCT_C_LEN))
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;
2903 DEBUG_PRINT_LOW("set_config - Error: Unknown VC1 profile\n");
2908 else if (configIndex == OMX_IndexConfigVideoNalSize)
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);
2918 return OMX_ErrorNotImplemented;
2921 /* ======================================================================
2923 omx_vdec::GetExtensionIndex
2926 OMX GetExtensionIndex method implementaion. <TBD>
2932 OMX Error None if everything successful.
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)
2939 DEBUG_PRINT_ERROR("get_extension_index: Error, Not implemented\n");
2940 if(m_state == OMX_StateInvalid)
2942 DEBUG_PRINT_ERROR("Get Extension Index in Invalid State\n");
2943 return OMX_ErrorInvalidState;
2945 return OMX_ErrorNotImplemented;
2948 /* ======================================================================
2953 Returns the state information back to the caller.<TBD>
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)
2965 DEBUG_PRINT_LOW("get_state: Returning the state %d\n",*state);
2966 return OMX_ErrorNone;
2969 /* ======================================================================
2971 omx_vdec::ComponentTunnelRequest
2974 OMX Component Tunnel Request method implementation. <TBD>
2980 OMX Error None if everything successful.
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)
2989 DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented\n");
2990 return OMX_ErrorNotImplemented;
2993 /* ======================================================================
2995 omx_vdec::UseInputBuffer
2998 Helper function for Use buffer in the input pin
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)
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};
3020 unsigned char *buf_addr = NULL;
3023 if(bytes != m_inp_buf_size)
3025 return OMX_ErrorBadParameter;
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);
3035 if (m_inp_mem_ptr == NULL)
3037 return OMX_ErrorInsufficientResources;
3040 driver_context.ptr_inputbuffer = (struct vdec_bufferpayload *) \
3041 calloc ((sizeof (struct vdec_bufferpayload)),m_inp_buf_count);
3043 if (driver_context.ptr_inputbuffer == NULL)
3045 return OMX_ErrorInsufficientResources;
3048 for (i=0; i < m_inp_buf_count; i++)
3050 driver_context.ptr_inputbuffer [i].pmem_fd = -1;
3054 for(i=0; i< m_inp_buf_count; i++)
3056 if(BITMASK_ABSENT(&m_inp_bm_count,i))
3062 if(i < m_inp_buf_count)
3064 pmem_fd = open ("/dev/pmem_adsp",O_RDWR | O_SYNC);
3068 return OMX_ErrorInsufficientResources;
3073 pmem_fd = open ("/dev/pmem_adsp",O_RDWR | O_SYNC);
3076 return OMX_ErrorInsufficientResources;
3080 if(!align_pmem_buffers(pmem_fd, m_inp_buf_size,
3081 driver_context.input_buffer.alignment))
3083 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
3085 return OMX_ErrorInsufficientResources;
3088 buf_addr = (unsigned char *)mmap(NULL,m_inp_buf_size,PROT_READ|PROT_WRITE,
3089 MAP_SHARED,pmem_fd,0);
3091 if (buf_addr == MAP_FAILED)
3093 return OMX_ErrorInsufficientResources;
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;
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;
3107 if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_SET_BUFFER,
3110 return OMX_ErrorInsufficientResources;
3113 *bufferHdr = (m_inp_mem_ptr + i);
3115 BITMASK_SET(&m_inp_bm_count,i);
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];
3127 eRet = OMX_ErrorInsufficientResources;
3133 /* ======================================================================
3135 omx_vdec::UseOutputBuffer
3138 Helper function for Use buffer in the input pin
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)
3155 OMX_ERRORTYPE eRet = OMX_ErrorNone;
3156 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
3157 unsigned i= 0; // Temporary counter
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;
3171 DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)\n",m_out_buf_count);
3172 nBufHdrSize = m_out_buf_count * sizeof(OMX_BUFFERHEADERTYPE);
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);
3181 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize,
3182 sizeof(OMX_BUFFERHEADERTYPE),
3185 DEBUG_PRINT_LOW("PE %d bmSize %d \n",nPlatformEntrySize,
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.
3198 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
3199 // Alloc mem for platform specific info
3201 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
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);
3208 if(m_out_mem_ptr && pPtr && driver_context.ptr_outputbuffer
3209 && driver_context.ptr_respbuffer)
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;
3221 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
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++)
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;
3246 pPMEMInfo->offset = 0;
3247 pPMEMInfo->pmem_fd = 0;
3248 bufHdr->pPlatformPrivate = pPlatformList;
3250 driver_context.ptr_outputbuffer[i].pmem_fd = -1;
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
3265 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%x][0x%x]\n",\
3266 m_out_mem_ptr, pPtr);
3269 free(m_out_mem_ptr);
3270 m_out_mem_ptr = NULL;
3277 if(driver_context.ptr_outputbuffer)
3279 free(driver_context.ptr_outputbuffer);
3280 driver_context.ptr_outputbuffer = NULL;
3282 if(driver_context.ptr_respbuffer)
3284 free(driver_context.ptr_respbuffer);
3285 driver_context.ptr_respbuffer = NULL;
3287 eRet = OMX_ErrorInsufficientResources;
3291 for(i=0; i< m_out_buf_count; i++)
3293 if(BITMASK_ABSENT(&m_out_bm_count,i))
3299 if (eRet == OMX_ErrorNone)
3301 if(i < m_out_buf_count)
3303 driver_context.ptr_outputbuffer[i].pmem_fd = \
3304 open ("/dev/pmem_adsp", O_RDWR | O_SYNC);
3306 if (driver_context.ptr_outputbuffer[i].pmem_fd < 0)
3308 return OMX_ErrorInsufficientResources;
3311 if(driver_context.ptr_outputbuffer[i].pmem_fd == 0)
3313 driver_context.ptr_outputbuffer[i].pmem_fd = \
3314 open ("/dev/pmem_adsp", O_RDWR | O_SYNC);
3316 if (driver_context.ptr_outputbuffer[i].pmem_fd < 0)
3318 return OMX_ErrorInsufficientResources;
3322 if(!align_pmem_buffers(driver_context.ptr_outputbuffer[i].pmem_fd,
3323 m_out_buf_size, driver_context.output_buffer.alignment))
3325 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
3326 close(driver_context.ptr_outputbuffer[i].pmem_fd);
3327 return OMX_ErrorInsufficientResources;
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);
3334 if (driver_context.ptr_outputbuffer[i].bufferaddr == MAP_FAILED)
3336 return OMX_ErrorInsufficientResources;
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;
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);
3350 DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient \n");
3351 eRet = OMX_ErrorInsufficientResources;
3358 /* ======================================================================
3363 OMX Use Buffer method implementation.
3369 OMX Error None , if everything successful.
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)
3380 OMX_ERRORTYPE eRet = OMX_ErrorNone;
3381 if(m_state == OMX_StateInvalid)
3383 DEBUG_PRINT_ERROR("Use Buffer in Invalid State\n");
3384 return OMX_ErrorInvalidState;
3386 if(port == OMX_CORE_INPUT_PORT_INDEX)
3388 eRet = use_input_buffer(hComp,bufferHdr,port,appData,bytes,buffer);
3390 else if(port == OMX_CORE_OUTPUT_PORT_INDEX)
3392 eRet = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer);
3396 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
3397 eRet = OMX_ErrorBadPortIndex;
3399 DEBUG_PRINT_LOW("Use Buffer: port %u, buffer %p, eRet %d", port, *bufferHdr, eRet);
3401 if(eRet == OMX_ErrorNone)
3405 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
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);
3413 if(port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated)
3415 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING))
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);
3424 else if(port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated)
3426 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING))
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;
3439 OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
3441 unsigned int index = 0;
3443 if (bufferHdr == NULL || m_inp_mem_ptr == NULL)
3445 return OMX_ErrorBadParameter;
3448 index = bufferHdr - m_inp_mem_ptr;
3449 DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index);
3451 if (index < m_inp_buf_count && driver_context.ptr_inputbuffer)
3453 DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index);
3454 if (driver_context.ptr_inputbuffer[index].pmem_fd > 0)
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);
3467 DEBUG_PRINT_ERROR("\nVDEC_IOCTL_FREE_BUFFER returned error %d", ioctl_r);
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;
3482 return OMX_ErrorNone;
3485 OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
3487 unsigned int index = 0;
3489 if (bufferHdr == NULL || m_out_mem_ptr == NULL)
3491 return OMX_ErrorBadParameter;
3494 index = bufferHdr - m_out_mem_ptr;
3495 DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d",index);
3497 if (index < m_out_buf_count && driver_context.ptr_outputbuffer)
3499 DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d addr = %x", index,
3500 driver_context.ptr_outputbuffer[index].bufferaddr);
3502 if (!gate_output_buffers)
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,
3514 DEBUG_PRINT_ERROR("\nRelease output buffer failed in VCD");
3517 if (driver_context.ptr_outputbuffer[0].pmem_fd > 0)
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;
3531 return OMX_ErrorNone;
3535 OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE hComp,
3536 OMX_BUFFERHEADERTYPE **bufferHdr,
3541 OMX_BUFFERHEADERTYPE *input = NULL;
3542 unsigned char *buf_addr = NULL;
3543 OMX_ERRORTYPE eRet = OMX_ErrorNone;
3547 if (bufferHdr == NULL)
3549 return OMX_ErrorBadParameter;
3552 if (m_inp_heap_ptr == NULL)
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);
3559 if (m_inp_heap_ptr == NULL)
3561 DEBUG_PRINT_ERROR("\n m_inp_heap_ptr Allocation failed ");
3562 return OMX_ErrorInsufficientResources;
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;
3570 if (h264_scratch.pBuffer == NULL)
3572 DEBUG_PRINT_ERROR("\n h264_scratch.pBuffer Allocation failed ");
3573 return OMX_ErrorInsufficientResources;
3576 if (m_frame_parser.mutils == NULL)
3578 m_frame_parser.mutils = new H264_Utils();
3580 if (m_frame_parser.mutils == NULL)
3582 DEBUG_PRINT_ERROR("\n parser utils Allocation failed ");
3583 return OMX_ErrorInsufficientResources;
3586 m_frame_parser.mutils->initialize_frame_checking_environment();
3587 m_frame_parser.mutils->allocate_rbsp_buffer (m_inp_buf_size);
3591 /*Find a Free index*/
3592 for(i=0; i< m_inp_buf_count; i++)
3594 if(BITMASK_ABSENT(&m_heap_inp_bm_count,i))
3596 DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i);
3601 if (i < m_inp_buf_count)
3603 buf_addr = (unsigned char *)malloc (m_inp_buf_size);
3605 if (buf_addr == NULL)
3607 return OMX_ErrorInsufficientResources;
3610 *bufferHdr = (m_inp_heap_ptr + i);
3612 BITMASK_SET(&m_heap_inp_bm_count,i);
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))
3626 DEBUG_PRINT_ERROR("\nERROR:Free_q is full");
3627 return OMX_ErrorInsufficientResources;
3632 return OMX_ErrorBadParameter;
3640 /* ======================================================================
3642 omx_vdec::AllocateInputBuffer
3645 Helper function for allocate buffer in the input pin
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)
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};
3667 unsigned char *buf_addr = NULL;
3670 if(bytes != m_inp_buf_size)
3672 DEBUG_PRINT_LOW("\n Requested Size is wrong %d epected is %d",bytes,m_inp_buf_size);
3673 //return OMX_ErrorBadParameter;
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);
3682 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
3683 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), m_inp_buf_count);
3685 if (m_inp_mem_ptr == NULL)
3687 return OMX_ErrorInsufficientResources;
3690 driver_context.ptr_inputbuffer = (struct vdec_bufferpayload *) \
3691 calloc ((sizeof (struct vdec_bufferpayload)),m_inp_buf_count);
3693 if (driver_context.ptr_inputbuffer == NULL)
3695 return OMX_ErrorInsufficientResources;
3698 for (i=0; i < m_inp_buf_count; i++)
3700 driver_context.ptr_inputbuffer [i].pmem_fd = -1;
3704 for(i=0; i< m_inp_buf_count; i++)
3706 if(BITMASK_ABSENT(&m_inp_bm_count,i))
3708 DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i);
3713 if(i < m_inp_buf_count)
3715 DEBUG_PRINT_LOW("\n Allocate input Buffer");
3716 pmem_fd = open ("/dev/pmem_adsp", O_RDWR, O_SYNC);
3720 DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer");
3721 return OMX_ErrorInsufficientResources;
3726 pmem_fd = open ("/dev/pmem_adsp", O_RDWR | O_SYNC);
3730 DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer");
3731 return OMX_ErrorInsufficientResources;
3735 if(!align_pmem_buffers(pmem_fd, m_inp_buf_size,
3736 driver_context.input_buffer.alignment))
3738 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
3740 return OMX_ErrorInsufficientResources;
3743 buf_addr = (unsigned char *)mmap(NULL,m_inp_buf_size,PROT_READ|PROT_WRITE,
3744 MAP_SHARED,pmem_fd,0);
3746 if (buf_addr == MAP_FAILED)
3748 DEBUG_PRINT_ERROR("\n Map Failed to allocate input buffer");
3749 return OMX_ErrorInsufficientResources;
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;
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;
3764 if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_SET_BUFFER,
3767 DEBUG_PRINT_ERROR("\n Set Buffers Failed");
3768 return OMX_ErrorInsufficientResources;
3771 *bufferHdr = (m_inp_mem_ptr + i);
3773 BITMASK_SET(&m_inp_bm_count,i);
3774 DEBUG_PRINT_LOW("\n Buffer address %p of pmem",*bufferHdr);
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];
3786 DEBUG_PRINT_ERROR("\nERROR:Input Buffer Index not found");
3787 eRet = OMX_ErrorInsufficientResources;
3793 /* ======================================================================
3795 omx_vdec::AllocateOutputBuffer
3798 Helper fn for AllocateBuffer in the output pin
3804 OMX Error None if everything went well.
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)
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;
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;
3828 unsigned char *pmem_baseaddress = NULL;
3830 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
3831 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
3832 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
3834 DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)\n",m_out_buf_count);
3835 nBufHdrSize = m_out_buf_count * sizeof(OMX_BUFFERHEADERTYPE);
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);
3844 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize,
3845 sizeof(OMX_BUFFERHEADERTYPE),
3848 DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d \n",nPlatformEntrySize,
3851 pmem_fd = open ("/dev/pmem_adsp", O_RDWR | O_SYNC);
3855 DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d",m_out_buf_size);
3856 return OMX_ErrorInsufficientResources;
3861 pmem_fd = open ("/dev/pmem_adsp", O_RDWR | O_SYNC);
3865 DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d",m_out_buf_size);
3866 return OMX_ErrorInsufficientResources;
3870 if(!align_pmem_buffers(pmem_fd, m_out_buf_size * m_out_buf_count,
3871 driver_context.output_buffer.alignment))
3873 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
3875 return OMX_ErrorInsufficientResources;
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,
3885 if (pmem_baseaddress == MAP_FAILED)
3887 DEBUG_PRINT_ERROR("\n MMAP failed for Size %d",m_out_buf_size);
3888 return OMX_ErrorInsufficientResources;
3890 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
3891 // Alloc mem for platform specific info
3893 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
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);
3900 if(m_out_mem_ptr && pPtr && driver_context.ptr_outputbuffer
3901 && driver_context.ptr_respbuffer)
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;
3915 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
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++)
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;
3941 pPMEMInfo->offset = m_out_buf_size*i;
3942 pPMEMInfo->pmem_fd = 0;
3943 bufHdr->pPlatformPrivate = pPlatformList;
3945 driver_context.ptr_outputbuffer[i].pmem_fd = pmem_fd;
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);
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
3966 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%x][0x%x]\n",\
3967 m_out_mem_ptr, pPtr);
3970 free(m_out_mem_ptr);
3971 m_out_mem_ptr = NULL;
3978 if(driver_context.ptr_outputbuffer)
3980 free(driver_context.ptr_outputbuffer);
3981 driver_context.ptr_outputbuffer = NULL;
3983 if(driver_context.ptr_respbuffer)
3985 free(driver_context.ptr_respbuffer);
3986 driver_context.ptr_respbuffer = NULL;
3988 eRet = OMX_ErrorInsufficientResources;
3992 for(i=0; i< m_out_buf_count; i++)
3994 if(BITMASK_ABSENT(&m_out_bm_count,i))
3996 DEBUG_PRINT_LOW("\n Found a Free Output Buffer %d",i);
4001 if (eRet == OMX_ErrorNone)
4003 if(i < m_out_buf_count)
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)
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;
4017 DEBUG_PRINT_LOW("\n Set the Output Buffer");
4018 if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_SET_BUFFER,
4021 DEBUG_PRINT_ERROR("\n Set output buffer failed");
4022 return OMX_ErrorInsufficientResources;
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);
4034 DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient \n");
4035 eRet = OMX_ErrorInsufficientResources;
4043 // AllocateBuffer -- API Call
4044 /* ======================================================================
4046 omx_vdec::AllocateBuffer
4049 Returns zero if all the buffers released..
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)
4065 OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
4067 DEBUG_PRINT_LOW("\n Allocate buffer on port %d \n", (int)port);
4068 if(m_state == OMX_StateInvalid)
4070 DEBUG_PRINT_ERROR("Allocate Buf in Invalid State\n");
4071 return OMX_ErrorInvalidState;
4074 if(port == OMX_CORE_INPUT_PORT_INDEX)
4076 if (arbitrary_bytes)
4078 eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes);
4082 eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
4085 else if(port == OMX_CORE_OUTPUT_PORT_INDEX)
4087 eRet = allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
4091 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
4092 eRet = OMX_ErrorBadPortIndex;
4094 DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
4095 if(eRet == OMX_ErrorNone)
4097 if(allocate_done()){
4098 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
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);
4106 if(port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated)
4108 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING))
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);
4116 if(port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated)
4118 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING))
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;
4128 DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d\n",eRet);
4132 // Free Buffer - API call
4133 /* ======================================================================
4135 omx_vdec::FreeBuffer
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)
4150 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4151 unsigned int nPortIndex;
4153 DEBUG_PRINT_LOW("In for decoder free_buffer \n");
4155 if(m_state == OMX_StateIdle &&
4156 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING)))
4158 DEBUG_PRINT_LOW(" free buffer while Component in Loading pending\n");
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))
4163 DEBUG_PRINT_LOW("Free Buffer while port %d disabled\n", port);
4165 else if(m_state == OMX_StateExecuting || m_state == OMX_StatePause)
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);
4174 else if (m_state != OMX_StateInvalid)
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);
4182 if(port == OMX_CORE_INPUT_PORT_INDEX)
4184 /*Check if arbitrary bytes*/
4185 if (!arbitrary_bytes)
4187 // check if the buffer is valid
4188 nPortIndex = buffer - m_inp_mem_ptr;
4192 nPortIndex = buffer - m_inp_heap_ptr;
4195 DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d \n", nPortIndex);
4196 if(nPortIndex < m_inp_buf_count)
4198 // Clear the bit associated with it.
4199 BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
4201 if (arbitrary_bytes)
4203 if (m_inp_heap_ptr[nPortIndex].pBuffer)
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;
4210 if (m_phdr_pmem_ptr[nPortIndex])
4212 DEBUG_PRINT_LOW("\n Free pmem Buffer index %d",nPortIndex);
4213 free_input_buffer(m_phdr_pmem_ptr[nPortIndex]);
4218 free_input_buffer(buffer);
4221 m_inp_bPopulated = OMX_FALSE;
4223 /*Free the Buffer Header*/
4224 if (release_input_done())
4226 DEBUG_PRINT_HIGH("\n ALL input buffers are freed/released");
4227 input_use_buffer = false;
4228 if (arbitrary_bytes)
4230 if (m_frame_parser.mutils)
4232 DEBUG_PRINT_LOW("\n Free utils parser");
4233 delete (m_frame_parser.mutils);
4234 m_frame_parser.mutils = NULL;
4239 DEBUG_PRINT_LOW("\n Free input Heap Pointer");
4240 free (m_inp_heap_ptr);
4241 m_inp_heap_ptr = NULL;
4244 if (m_phdr_pmem_ptr)
4246 DEBUG_PRINT_LOW("\n Free input pmem header Pointer");
4247 free (m_phdr_pmem_ptr);
4248 m_phdr_pmem_ptr = NULL;
4253 DEBUG_PRINT_LOW("\n Free input pmem Pointer area");
4254 free (m_inp_mem_ptr);
4255 m_inp_mem_ptr = NULL;
4258 if (driver_context.ptr_inputbuffer)
4260 DEBUG_PRINT_LOW("\n Free Driver Context pointer");
4261 free (driver_context.ptr_inputbuffer);
4262 driver_context.ptr_inputbuffer = NULL;
4269 DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid\n");
4270 eRet = OMX_ErrorBadPortIndex;
4273 if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
4274 && release_input_done())
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);
4283 else if(port == OMX_CORE_OUTPUT_PORT_INDEX)
4285 // check if the buffer is valid
4286 nPortIndex = buffer - (OMX_BUFFERHEADERTYPE*)m_out_mem_ptr;
4287 if(nPortIndex < m_out_buf_count)
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);
4295 if (release_output_done())
4297 DEBUG_PRINT_HIGH("\n ALL output buffers are freed/released");
4298 output_use_buffer = false;
4301 free (m_out_mem_ptr);
4302 m_out_mem_ptr = NULL;
4304 if (driver_context.ptr_respbuffer)
4306 free (driver_context.ptr_respbuffer);
4307 driver_context.ptr_respbuffer = NULL;
4309 if (driver_context.ptr_outputbuffer)
4311 free (driver_context.ptr_outputbuffer);
4312 driver_context.ptr_outputbuffer = NULL;
4318 DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid\n");
4319 eRet = OMX_ErrorBadPortIndex;
4321 if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
4322 && release_output_done() )
4324 DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it\n");
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);
4335 eRet = OMX_ErrorBadPortIndex;
4337 if((eRet == OMX_ErrorNone) &&
4338 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING)))
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);
4352 /* ======================================================================
4354 omx_vdec::EmptyThisBuffer
4357 This routine is used to push the encoded video frames to
4364 OMX Error None if everything went successful.
4366 ========================================================================== */
4367 OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
4368 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
4370 OMX_ERRORTYPE ret1 = OMX_ErrorNone;
4371 unsigned int nBufferIndex = m_inp_buf_count;
4373 if(m_state == OMX_StateInvalid)
4375 DEBUG_PRINT_ERROR("Empty this buffer in Invalid State\n");
4376 return OMX_ErrorInvalidState;
4381 DEBUG_PRINT_ERROR("\nERROR:ETB Buffer is NULL");
4382 return OMX_ErrorBadParameter;
4385 if (arbitrary_bytes)
4387 nBufferIndex = buffer - m_inp_heap_ptr;
4391 nBufferIndex = buffer - m_inp_mem_ptr;
4394 if (nBufferIndex > m_inp_buf_count )
4396 DEBUG_PRINT_ERROR("\nERROR:ETB nBufferIndex is invalid");
4397 return OMX_ErrorBadParameter;
4400 DEBUG_PRINT_LOW("\n ETB: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
4401 if (arbitrary_bytes)
4403 post_event ((unsigned)hComp,(unsigned)buffer,
4404 OMX_COMPONENT_GENERATE_ETB_ARBITRARY);
4408 post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB);
4410 return OMX_ErrorNone;
4413 /* ======================================================================
4415 omx_vdec::empty_this_buffer_proxy
4418 This routine is used to push the encoded video frames to
4425 OMX Error None if everything went successful.
4427 ========================================================================== */
4428 OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,
4429 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
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;
4440 /*Should we generate a Aync error event*/
4441 if (buffer == NULL || buffer->pInputPortPrivate == NULL)
4443 DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy is invalid");
4444 return OMX_ErrorBadParameter;
4447 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
4449 if (nPortIndex > m_inp_buf_count)
4451 DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy invalid nPortIndex[%u]",
4453 return OMX_ErrorBadParameter;
4456 pending_input_buffers++;
4458 if( input_flush_progress == true || m_ineos_reached == 1)
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;
4466 if(m_event_port_settings_sent && !arbitrary_bytes)
4468 post_event((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB);
4469 return OMX_ErrorNone;
4472 temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate;
4474 if ((temp_buffer - driver_context.ptr_inputbuffer) > m_inp_buf_count)
4476 return OMX_ErrorBadParameter;
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;
4483 if (input_use_buffer)
4485 if (buffer->nFilledLen <= temp_buffer->buffer_len)
4487 memcpy (temp_buffer->bufferaddr,(buffer->pBuffer + buffer->nOffset),
4488 buffer->nFilledLen);
4492 return OMX_ErrorBadParameter;
4497 if (!arbitrary_bytes && first_frame < 2 && codec_type_parse == CODEC_TYPE_MPEG4)
4500 if (first_frame == 0)
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);
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;
4513 else if (first_frame == 1)
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);
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;
4538 bytes_written = fwrite((const char *)temp_buffer->bufferaddr,
4539 temp_buffer->buffer_len,1,outputBufferFile1);
4543 if(!set_seq_header_done)
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,
4556 DEBUG_PRINT_ERROR("\n Set Sequence Header Failed");
4557 /*Generate an async error and move to invalid state*/
4558 return OMX_ErrorBadParameter;
4560 if(omx_vdec_check_port_settings (&port_setting_changed) != OMX_ErrorNone)
4562 DEBUG_PRINT_ERROR("\n Check port setting failed");
4563 return OMX_ErrorBadParameter;
4566 if(port_setting_changed)
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;
4577 if(!register_output_buffers())
4579 DEBUG_PRINT_ERROR("\n register output failed");
4580 return OMX_ErrorBadParameter;
4582 DEBUG_PRINT_HIGH("\n Port settings Not changed");
4586 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & 0x01))
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;
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;
4598 if (ioctl(driver_context.video_driver_fd,VDEC_IOCTL_DECODE_FRAME,
4601 /*Generate an async error and move to invalid state*/
4602 return OMX_ErrorBadParameter;
4608 /* ======================================================================
4610 omx_vdec::FillThisBuffer
4613 IL client uses this method to release the frame buffer
4614 after displaying them.
4622 ========================================================================== */
4623 OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
4624 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
4627 if(m_state == OMX_StateInvalid)
4629 DEBUG_PRINT_ERROR("FTB in Invalid State\n");
4630 return OMX_ErrorInvalidState;
4633 if (buffer == NULL || ((buffer - m_out_mem_ptr) > m_out_buf_size))
4635 return OMX_ErrorBadParameter;
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;
4642 /* ======================================================================
4644 omx_vdec::fill_this_buffer_proxy
4647 IL client uses this method to release the frame buffer
4648 after displaying them.
4656 ========================================================================== */
4657 OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy(
4658 OMX_IN OMX_HANDLETYPE hComp,
4659 OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
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;
4669 if (bufferAdd == NULL || ((buffer - m_out_mem_ptr) > m_out_buf_count) )
4671 return OMX_ErrorBadParameter;
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)
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;
4685 pending_output_buffers++;
4686 ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate;
4689 ptr_outputbuffer = (struct vdec_bufferpayload*)ptr_respbuffer->client_data;
4692 if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL)
4694 return OMX_ErrorBadParameter;
4697 memcpy (&fillbuffer.buffer,ptr_outputbuffer,\
4698 sizeof(struct vdec_bufferpayload));
4699 fillbuffer.client_data = bufferAdd;
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)
4706 DEBUG_PRINT_ERROR("\n Decoder frame failed");
4707 m_cb.FillBufferDone (hComp,m_app_data,buffer);
4708 return OMX_ErrorBadParameter;
4711 if(gate_input_buffers)
4713 gate_input_buffers = false;
4716 /*Push the frame to the Decoder*/
4717 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
4719 return OMX_ErrorBadParameter;
4725 return OMX_ErrorNone;
4728 /* ======================================================================
4730 omx_vdec::SetCallbacks
4739 OMX Error None if everything successful.
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)
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;
4754 /* ======================================================================
4756 omx_vdec::ComponentDeInit
4759 Destroys the component and release memory allocated to the heap.
4765 OMX Error None if everything successful.
4767 ========================================================================== */
4768 OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
4771 if (OMX_StateLoaded != m_state)
4773 DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d\n",\
4775 DEBUG_PRINT_ERROR("\nPlayback Ended - FAILED");
4779 DEBUG_PRINT_HIGH("\n Playback Ended - PASSED");
4782 /*Check if the output buffers have to be cleaned up*/
4785 DEBUG_PRINT_LOW("Freeing the Output Memory\n");
4786 for (i=0; i<m_out_buf_count; i++ )
4788 free_output_buffer (&m_out_mem_ptr[i]);
4790 if (driver_context.ptr_outputbuffer)
4792 free (driver_context.ptr_outputbuffer);
4793 driver_context.ptr_outputbuffer = NULL;
4796 if (driver_context.ptr_respbuffer)
4798 free (driver_context.ptr_respbuffer);
4799 driver_context.ptr_respbuffer = NULL;
4801 free(m_out_mem_ptr);
4802 m_out_mem_ptr = NULL;
4805 /*Check if the input buffers have to be cleaned up*/
4808 DEBUG_PRINT_LOW("Freeing the Input Memory\n");
4809 for (i=0; i<m_inp_buf_count; i++ )
4811 free_input_buffer (&m_inp_mem_ptr[i]);
4814 if (driver_context.ptr_inputbuffer)
4816 free (driver_context.ptr_inputbuffer);
4817 driver_context.ptr_inputbuffer = NULL;
4820 free(m_inp_mem_ptr);
4821 m_inp_mem_ptr = NULL;
4824 if(h264_scratch.pBuffer)
4826 free(h264_scratch.pBuffer);
4827 h264_scratch.pBuffer = NULL;
4832 free(m_platform_list);
4833 m_platform_list = NULL;
4835 if(m_vendor_config.pData)
4837 free(m_vendor_config.pData);
4838 m_vendor_config.pData = NULL;
4841 // Reset counters in mesg queues
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;
4849 DEBUG_PRINT_LOW("\n Calling VDEC_IOCTL_STOP_NEXT_MSG");
4850 (void)ioctl(driver_context.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
4852 DEBUG_PRINT_HIGH("\n Close the driver instance");
4853 close(driver_context.video_driver_fd);
4856 fclose (outputBufferFile1);
4859 //for (i=0; i<m_out_buf_count; i++ )
4861 // Clear the strong reference
4865 DEBUG_PRINT_HIGH("\n omx_vdec::component_deinit() complete");
4866 return OMX_ErrorNone;
4869 /* ======================================================================
4871 omx_vdec::UseEGLImage
4874 OMX Use EGL Image method implementation <TBD>.
4880 Not Implemented error.
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)
4889 DEBUG_PRINT_ERROR("Error : use_EGL_image: Not Implemented \n");
4890 return OMX_ErrorNotImplemented;
4893 /* ======================================================================
4895 omx_vdec::ComponentRoleEnum
4898 OMX Component Role Enum method implementation.
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)
4910 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4912 if(!strncmp(driver_context.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
4914 if((0 == index) && role)
4916 strncpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
4917 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
4921 eRet = OMX_ErrorNoMore;
4924 else if(!strncmp(driver_context.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))
4926 if((0 == index) && role)
4928 strncpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
4929 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
4933 DEBUG_PRINT_LOW("\n No more roles \n");
4934 eRet = OMX_ErrorNoMore;
4937 else if(!strncmp(driver_context.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE))
4939 if((0 == index) && role)
4941 strncpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
4942 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
4946 DEBUG_PRINT_LOW("\n No more roles \n");
4947 eRet = OMX_ErrorNoMore;
4950 else if(!strncmp(driver_context.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE))
4952 if((0 == index) && role)
4954 strncpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
4955 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
4959 DEBUG_PRINT_LOW("\n No more roles \n");
4960 eRet = OMX_ErrorNoMore;
4965 DEBUG_PRINT_ERROR("\nERROR:Querying Role on Unknown Component\n");
4966 eRet = OMX_ErrorInvalidComponentName;
4974 /* ======================================================================
4976 omx_vdec::AllocateDone
4979 Checks if entire buffer pool is allocated by IL Client or not.
4980 Need this to move to IDLE state.
4988 ========================================================================== */
4989 bool omx_vdec::allocate_done(void)
4992 bool bRet_In = false;
4993 bool bRet_Out = false;
4995 bRet_In = allocate_input_done();
4996 bRet_Out = allocate_output_done();
4998 if(bRet_In && bRet_Out)
5005 /* ======================================================================
5007 omx_vdec::AllocateInputDone
5010 Checks if I/P buffer pool is allocated by IL Client or not.
5018 ========================================================================== */
5019 bool omx_vdec::allocate_input_done(void)
5024 if (m_inp_mem_ptr == NULL)
5030 for(;i<m_inp_buf_count;i++)
5032 if(BITMASK_ABSENT(&m_inp_bm_count,i))
5038 if(i==m_inp_buf_count)
5041 DEBUG_PRINT_HIGH("\n Allocate done for all i/p buffers");
5043 if(i==m_inp_buf_count && m_inp_bEnabled)
5045 m_inp_bPopulated = OMX_TRUE;
5049 /* ======================================================================
5051 omx_vdec::AllocateOutputDone
5054 Checks if entire O/P buffer pool is allocated by IL Client or not.
5062 ========================================================================== */
5063 bool omx_vdec::allocate_output_done(void)
5068 if (m_out_mem_ptr == NULL)
5075 for(;j<m_out_buf_count;j++)
5077 if(BITMASK_ABSENT(&m_out_bm_count,j))
5084 if(j==m_out_buf_count)
5087 DEBUG_PRINT_HIGH("\n Allocate done for all o/p buffers");
5090 if(j==m_out_buf_count && m_out_bEnabled)
5092 m_out_bPopulated = OMX_TRUE;
5097 /* ======================================================================
5099 omx_vdec::ReleaseDone
5102 Checks if IL client has released all the buffers.
5110 ========================================================================== */
5111 bool omx_vdec::release_done(void)
5115 if(release_input_done())
5117 if(release_output_done())
5126 /* ======================================================================
5128 omx_vdec::ReleaseOutputDone
5131 Checks if IL client has released all the buffers.
5139 ========================================================================== */
5140 bool omx_vdec::release_output_done(void)
5145 DEBUG_PRINT_LOW("\n Value of m_out_mem_ptr %p",m_inp_mem_ptr);
5148 for(;j<m_out_buf_count;j++)
5150 if(BITMASK_PRESENT(&m_out_bm_count,j))
5155 if(j==m_out_buf_count)
5168 /* ======================================================================
5170 omx_vdec::ReleaseInputDone
5173 Checks if IL client has released all the buffers.
5181 ========================================================================== */
5182 bool omx_vdec::release_input_done(void)
5187 DEBUG_PRINT_LOW("\n Value of m_inp_mem_ptr %p",m_inp_mem_ptr);
5190 for(;j<m_inp_buf_count;j++)
5192 if( BITMASK_PRESENT(&m_inp_bm_count,j))
5197 if(j==m_inp_buf_count)
5209 /* ======================================================================
5211 omx_vdec::omx_vdec_check_port_settings
5214 Parse meta data to check the height and width param
5215 Check the level and profile
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)
5226 struct vdec_ioctl_msg ioctl_msg;
5227 unsigned int alignment = 0,buffer_size = 0;
5228 OMX_ERRORTYPE eRet = OMX_ErrorNone;
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))
5235 DEBUG_PRINT_ERROR("\n Error in VDEC_IOCTL_GET_PICRES in port_setting");
5236 return OMX_ErrorHardware;
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,
5244 DEBUG_PRINT_ERROR("\n Error in VDEC_IOCTL_GET_BUFFER_REQ in port_setting");
5245 return OMX_ErrorHardware;
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,
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);
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,
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)
5268 *port_setting_changed = true;
5269 ioctl_msg.inputparam = &driver_context.output_buffer;
5270 ioctl_msg.outputparam = NULL;
5272 if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_SET_BUFFER_REQ,
5275 DEBUG_PRINT_ERROR("\n Error in VDEC_IOCTL_GET_BUFFER_REQ in port_setting");
5276 return OMX_ErrorHardware;
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;
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;
5298 /* ======================================================================
5300 omx_vdec::omx_vdec_validate_port_param
5303 Get the PMEM area from video decoder
5310 ========================================================================== */
5311 OMX_ERRORTYPE omx_vdec::omx_vdec_validate_port_param(int height, int width)
5313 OMX_ERRORTYPE ret = OMX_ErrorNone;
5314 long hxw = height*width;
5320 static FILE * outputBufferFile = NULL;
5322 OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp,
5323 OMX_BUFFERHEADERTYPE * buffer)
5325 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
5327 if (buffer == NULL || ((buffer - m_out_mem_ptr) > m_out_buf_count))
5329 return OMX_ErrorBadParameter;
5332 DEBUG_PRINT_LOW("\n fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
5333 buffer, buffer->pBuffer);
5334 pending_output_buffers --;
5336 if (buffer->nFlags & 0x01)
5338 DEBUG_PRINT_LOW("\n Output EOS has been reached");
5340 m_outeos_reached = 0;
5341 m_ineos_reached = 0;
5342 h264_scratch.nFilledLen = 0;
5344 look_ahead_nal = false;
5347 if (m_frame_parser.mutils)
5349 m_frame_parser.mutils->initialize_frame_checking_environment();
5353 m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame);
5354 psource_frame = NULL;
5359 pdest_frame->nFilledLen = 0;
5360 m_input_free_q.insert_entry((unsigned) pdest_frame,NULL,NULL);
5363 m_frame_parser.flush();
5366 DEBUG_PRINT_LOW("\n In fill Buffer done call address %p ",buffer);
5368 if (outputBufferFile == NULL)
5370 outputBufferFile = fopen ("/data/output.yuv","wb");
5372 if (outputBufferFile)
5374 /*fwrite (buffer->pBuffer,1,buffer->nFilledLen,
5375 outputBufferFile); */
5377 /* For use buffer we need to copy the data */
5378 if (m_cb.FillBufferDone)
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);
5389 return OMX_ErrorBadParameter;
5392 return OMX_ErrorNone;
5395 OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE hComp,
5396 OMX_BUFFERHEADERTYPE* buffer)
5399 if (buffer == NULL || ((buffer - m_inp_mem_ptr) > m_inp_buf_count))
5401 return OMX_ErrorBadParameter;
5404 DEBUG_PRINT_LOW("\n empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
5405 buffer, buffer->pBuffer);
5406 pending_input_buffers--;
5408 if (arbitrary_bytes)
5410 if (pdest_frame == NULL && input_flush_progress == false)
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);
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))
5423 DEBUG_PRINT_ERROR("\nERROR:i/p free Queue is FULL Error");
5427 else if(m_cb.EmptyBufferDone)
5429 buffer->nFilledLen = 0;
5430 m_cb.EmptyBufferDone(hComp ,m_app_data, buffer);
5432 return OMX_ErrorNone;
5436 int omx_vdec::async_message_process (void *context, void* message)
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;
5443 if (context == NULL || message == NULL)
5445 DEBUG_PRINT_ERROR("\n FATAL ERROR in omx_vdec::async_message_process NULL Check");
5448 vdec_msg = (struct vdec_msginfo *)message;
5450 omx = reinterpret_cast<omx_vdec*>(context);
5451 switch (vdec_msg->msgcode)
5454 case VDEC_MSG_EVT_HW_ERROR:
5455 omx->post_event (NULL,vdec_msg->status_code,\
5456 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
5459 case VDEC_MSG_RESP_START_DONE:
5460 omx->post_event (NULL,vdec_msg->status_code,\
5461 OMX_COMPONENT_GENERATE_START_DONE);
5464 case VDEC_MSG_RESP_STOP_DONE:
5465 omx->post_event (NULL,vdec_msg->status_code,\
5466 OMX_COMPONENT_GENERATE_STOP_DONE);
5469 case VDEC_MSG_RESP_RESUME_DONE:
5470 omx->post_event (NULL,vdec_msg->status_code,\
5471 OMX_COMPONENT_GENERATE_RESUME_DONE);
5474 case VDEC_MSG_RESP_PAUSE_DONE:
5475 omx->post_event (NULL,vdec_msg->status_code,\
5476 OMX_COMPONENT_GENERATE_PAUSE_DONE);
5479 case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
5480 omx->post_event (NULL,vdec_msg->status_code,\
5481 OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
5483 case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
5484 omx->post_event (NULL,vdec_msg->status_code,\
5485 OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
5487 case VDEC_MSG_RESP_INPUT_FLUSHED:
5488 case VDEC_MSG_RESP_INPUT_BUFFER_DONE:
5490 omxhdr = (OMX_BUFFERHEADERTYPE* )\
5491 vdec_msg->msgdata.input_frame_clientdata;
5494 if (omxhdr == NULL ||
5495 ((omxhdr - omx->m_inp_mem_ptr) > omx->m_inp_buf_count) )
5498 vdec_msg->status_code = VDEC_S_EFATAL;
5501 omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code,
5502 OMX_COMPONENT_GENERATE_EBD);
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);
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)
5516 if (vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen)
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);
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;
5539 if (omx->output_use_buffer)
5541 if (vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen)
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 );
5550 omxhdr->nFilledLen = 0;
5556 omxhdr->nFilledLen = 0;
5563 vdec_msg->status_code = VDEC_S_EFATAL;
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);
5577 OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary (
5578 OMX_HANDLETYPE hComp,
5579 OMX_BUFFERHEADERTYPE *buffer
5582 unsigned address,p2,id;
5583 DEBUG_PRINT_LOW("\n Empty this arbitrary");
5587 return OMX_ErrorBadParameter;
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);
5593 if( input_flush_progress == true || m_ineos_reached == 1)
5595 DEBUG_PRINT_LOW("\n Flush in progress return buffer ");
5596 m_cb.EmptyBufferDone (hComp,m_app_data,buffer);
5597 return OMX_ErrorNone;
5600 if (psource_frame == NULL)
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);
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))
5612 return OMX_ErrorBadParameter;
5617 return OMX_ErrorNone;
5620 OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp)
5622 unsigned address,p2,id;
5623 OMX_ERRORTYPE ret = OMX_ErrorNone;
5625 if (pdest_frame == NULL || psource_frame == NULL)
5627 /*Check if we have a destination buffer*/
5628 if (pdest_frame == NULL)
5630 DEBUG_PRINT_LOW("\n Get a Destination buffer from the queue");
5631 if (m_input_free_q.m_size && !gate_input_buffers)
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);
5640 /*Check if we have a destination buffer*/
5641 if (psource_frame == NULL)
5643 DEBUG_PRINT_LOW("\n Get a source buffer from the queue");
5644 if (m_input_pending_q.m_size && !gate_input_buffers)
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);
5658 while ((pdest_frame != NULL) && (psource_frame != NULL)&& !gate_input_buffers)
5660 switch (codec_type_parse)
5662 case CODEC_TYPE_MPEG4:
5663 case CODEC_TYPE_H263:
5664 ret = push_input_sc_codec(hComp);
5666 case CODEC_TYPE_H264:
5667 ret = push_input_h264(hComp);
5669 case CODEC_TYPE_VC1:
5670 ret = push_input_vc1(hComp);
5673 if (ret != OMX_ErrorNone)
5675 DEBUG_PRINT_ERROR("\n Pushing input Buffer Failed");
5676 omx_report_error ();
5684 OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp)
5686 OMX_U32 partial_frame = 1;
5687 OMX_BOOL genarte_edb = OMX_TRUE,generate_eos = OMX_TRUE;
5688 unsigned address,p2,id;
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)
5695 DEBUG_PRINT_ERROR("\n Error In Parsing Return Error");
5696 return OMX_ErrorBadParameter;
5699 if (partial_frame == 0)
5701 DEBUG_PRINT_LOW("\n Frame size %d source %p frame count %d",
5702 pdest_frame->nFilledLen,psource_frame,frame_count);
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)
5709 DEBUG_PRINT_LOW("\n H263/MPEG4 Codec First Frame ");
5710 mp4h263_flags = psource_frame->nFlags;
5711 mp4h263_timestamp = psource_frame->nTimeStamp;
5716 pdest_frame->nTimeStamp = mp4h263_timestamp;
5717 mp4h263_timestamp = psource_frame->nTimeStamp;
5718 pdest_frame->nFlags = mp4h263_flags;
5719 mp4h263_flags = psource_frame->nFlags;
5721 if(psource_frame->nFilledLen == 0)
5723 pdest_frame->nFlags = mp4h263_flags;
5724 generate_eos = OMX_FALSE;
5728 /*Push the frame to the Decoder*/
5729 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
5731 return OMX_ErrorBadParameter;
5733 if(m_event_port_settings_sent)
5735 gate_input_buffers = true;
5736 return OMX_ErrorNone;
5741 if (m_input_free_q.m_size && !gate_input_buffers)
5743 m_input_free_q.pop_entry(&address,&p2,&id);
5744 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
5745 pdest_frame->nFilledLen = 0;
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)
5756 DEBUG_PRINT_ERROR("\nERROR:Frame Not found though Destination Filled");
5757 return OMX_ErrorStreamCorrupt;
5761 if (psource_frame->nFilledLen == 0)
5763 if ((psource_frame->nFlags & 0x01) && generate_eos)
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)
5776 return OMX_ErrorBadParameter;
5783 DEBUG_PRINT_LOW("\n Last frame in else dest addr") ;
5784 genarte_edb = OMX_FALSE;
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;
5793 if (m_input_pending_q.m_size)
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);
5805 return OMX_ErrorNone;
5808 OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp)
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;
5816 if (h264_scratch.pBuffer == NULL)
5818 DEBUG_PRINT_ERROR("\nERROR:H.264 Scratch Buffer not allocated");
5819 return OMX_ErrorBadParameter;
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)
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)
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;
5840 DEBUG_PRINT_ERROR("\nERROR:Destination buffer overflow for H264");
5841 return OMX_ErrorBadParameter;
5845 if(psource_frame->nFlags & 0x01)
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)
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;
5861 DEBUG_PRINT_ERROR("\nERROR:Destination buffer overflow for H264");
5862 return OMX_ErrorBadParameter;
5868 if (nal_length == 0)
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)
5874 DEBUG_PRINT_ERROR("\n Error In Parsing Return Error");
5875 return OMX_ErrorBadParameter;
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)
5884 DEBUG_PRINT_ERROR("\n Error In Parsing NAL Return Error");
5885 return OMX_ErrorBadParameter;
5889 if (partial_frame == 0)
5892 if (nal_count == 0 && h264_scratch.nFilledLen == 0)
5894 DEBUG_PRINT_LOW("\n First NAL with Zero Length Hence Skip");
5896 h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
5897 h264_scratch.nFlags = psource_frame->nFlags;
5901 DEBUG_PRINT_LOW("\n Length of New NAL is %d",h264_scratch.nFilledLen);
5903 m_frame_parser.mutils->isNewFrame(h264_scratch.pBuffer,
5904 h264_scratch.nFilledLen,0,isNewFrame);
5909 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
5910 h264_scratch.nFilledLen)
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;
5921 DEBUG_PRINT_LOW("\n Destination buffer overflow for H264");
5922 return OMX_ErrorBadParameter;
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;
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++);
5938 if (pdest_frame->nFilledLen == 0)
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)
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;
5952 DEBUG_PRINT_ERROR("\nERROR:Destination buffer overflow for H264");
5953 return OMX_ErrorBadParameter;
5958 /*Push the frame to the Decoder*/
5959 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
5961 return OMX_ErrorBadParameter;
5963 if(m_event_port_settings_sent)
5965 gate_input_buffers = true;
5966 return OMX_ErrorNone;
5970 if (m_input_free_q.m_size && !gate_input_buffers)
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;
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)
5988 DEBUG_PRINT_ERROR("\nERROR: Frame Not found though Destination Filled");
5989 return OMX_ErrorStreamCorrupt;
5994 if (psource_frame->nFilledLen == 0)
5996 DEBUG_PRINT_LOW("\n Buffer Consumed return back to client %p",psource_frame);
5998 if (psource_frame->nFlags & 0x01)
6002 DEBUG_PRINT_LOW("\n EOS Reached Pass Last Buffer");
6003 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
6004 h264_scratch.nFilledLen)
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;
6013 DEBUG_PRINT_ERROR("\nERROR:Destination buffer overflow for H264");
6014 return OMX_ErrorBadParameter;
6016 pdest_frame->nTimeStamp = psource_frame->nTimeStamp;
6017 pdest_frame->nFlags = psource_frame->nFlags;
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)
6026 return OMX_ErrorBadParameter;
6028 if(m_event_port_settings_sent)
6030 gate_input_buffers = true;
6031 return OMX_ErrorNone;
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;
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)
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);
6057 return OMX_ErrorNone;
6060 OMX_ERRORTYPE omx_vdec::push_input_vc1 (OMX_HANDLETYPE hComp)
6062 OMX_U8 *buf, *pdest;
6063 OMX_U32 partial_frame = 1;
6064 OMX_U32 buf_len, dest_len;
6066 if(frame_count == 0)
6068 DEBUG_PRINT_LOW("\nFirst i/p buffer for VC1 arbitrary bytes\n");
6069 if(!m_vendor_config.pData)
6071 DEBUG_PRINT_LOW("\nCheck profile type in 1st source buffer\n");
6072 buf = psource_frame->pBuffer;
6073 buf_len = psource_frame->nFilledLen;
6075 if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) ==
6076 VC1_SP_MP_START_CODE)
6078 m_vc1_profile = VC1_SP_MP_RCV;
6080 else if(*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE)
6082 m_vc1_profile = VC1_AP;
6086 DEBUG_PRINT_ERROR("\nInvalid sequence layer in first buffer\n");
6087 return OMX_ErrorStreamCorrupt;
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);
6097 if(dest_len < m_vendor_config.nDataSize)
6099 DEBUG_PRINT_ERROR("\nDestination buffer full\n");
6100 return OMX_ErrorBadParameter;
6104 memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize);
6105 pdest_frame->nFilledLen += m_vendor_config.nDataSize;
6110 switch(m_vc1_profile)
6113 DEBUG_PRINT_LOW("\n VC1 AP, hence parse using frame start code");
6114 if (push_input_sc_codec(hComp) != OMX_ErrorNone)
6116 DEBUG_PRINT_ERROR("\n Error In Parsing VC1 AP start code");
6117 return OMX_ErrorBadParameter;
6123 DEBUG_PRINT_ERROR("\n Unsupported VC1 profile in ArbitraryBytes Mode\n");
6124 return OMX_ErrorBadParameter;
6126 return OMX_ErrorNone;
6129 bool omx_vdec::register_output_buffers()
6131 struct vdec_ioctl_msg ioctl_msg;
6132 struct vdec_setbuffer_cmd setbuffers;
6134 unsigned p1 =0,p2 = 0,ident = 0;
6136 for(i=0;i<m_out_buf_count;i++)
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;
6144 DEBUG_PRINT_LOW("\n Set the Output Buffer");
6145 if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_SET_BUFFER,
6148 DEBUG_PRINT_ERROR("\n Set output buffer failed");
6152 if(gate_output_buffers)
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)
6159 m_ftb_q.pop_entry(&p1,&p2,&ident);
6160 if(ident == OMX_COMPONENT_GENERATE_FTB )
6162 if (fill_this_buffer_proxy ((OMX_HANDLETYPE)p1,
6163 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
6165 DEBUG_PRINT_ERROR("\n fill_this_buffer_proxy failure");
6166 omx_report_error ();
6170 else if (ident == OMX_COMPONENT_GENERATE_FBD)
6172 fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
6175 gate_output_buffers = false;
6176 pthread_mutex_unlock(&m_lock);
6181 bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
6184 //TODO: figure out if this is really necessary (PMEM_ALLOCATE_ALIGNED is a
6185 // QCOM extension to pmem
6188 struct pmem_allocation allocation;
6189 allocation.size = buffer_size;
6190 allocation.align = clip2(alignment);
6191 if (allocation.align < 4096)
6193 allocation.align = 4096;
6195 if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0)
6197 DEBUG_PRINT_ERROR("\n Aligment failed with pmem driver");