| /*-------------------------------------------------------------------------- |
| Copyright (c) 2010-2016, Linux Foundation. All rights reserved. |
| |
| Redistribution and use in source and binary forms, with or without |
| modification, are permitted provided that the following conditions are met: |
| * Redistributions of source code must retain the above copyright |
| notice, this list of conditions and the following disclaimer. |
| * Redistributions in binary form must reproduce the above copyright |
| notice, this list of conditions and the following disclaimer in the |
| documentation and/or other materials provided with the distribution. |
| * Neither the name of The Linux Foundation nor |
| the names of its contributors may be used to endorse or promote |
| products derived from this software without specific prior written |
| permission. |
| |
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
| NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
| CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
| EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; |
| OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
| WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR |
| OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
| ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| --------------------------------------------------------------------------*/ |
| /*============================================================================ |
| O p e n M A X w r a p p e r s |
| O p e n M A X C o r e |
| |
| *//** @file omx_video_base.cpp |
| This module contains the implementation of the OpenMAX core & component. |
| |
| *//*========================================================================*/ |
| |
| ////////////////////////////////////////////////////////////////////////////// |
| // Include Files |
| ////////////////////////////////////////////////////////////////////////////// |
| |
| #define __STDC_FORMAT_MACROS //enables the format specifiers in inttypes.h |
| #include <inttypes.h> |
| #include <string.h> |
| #include "omx_video_base.h" |
| #include <stdlib.h> |
| #include <errno.h> |
| #include <fcntl.h> |
| #include <unistd.h> |
| #include <sys/prctl.h> |
| #ifdef _ANDROID_ICS_ |
| #include <media/hardware/HardwareAPI.h> |
| #include <gralloc_priv.h> |
| #endif |
| #ifndef _ANDROID_ |
| #include <glib.h> |
| #define strlcpy g_strlcpy |
| #endif |
| #define H264_SUPPORTED_WIDTH (480) |
| #define H264_SUPPORTED_HEIGHT (368) |
| |
| #define MPEG4_SUPPORTED_WIDTH (480) |
| #define MPEG4_SUPPORTED_HEIGHT (368) |
| |
| #define VC1_SP_MP_START_CODE 0xC5000000 |
| #define VC1_SP_MP_START_CODE_MASK 0xFF000000 |
| #define VC1_AP_START_CODE 0x00000100 |
| #define VC1_AP_START_CODE_MASK 0xFFFFFF00 |
| #define VC1_STRUCT_C_PROFILE_MASK 0xF0 |
| #define VC1_STRUCT_B_LEVEL_MASK 0xE0000000 |
| #define VC1_SIMPLE_PROFILE 0 |
| #define VC1_MAIN_PROFILE 1 |
| #define VC1_ADVANCE_PROFILE 3 |
| #define VC1_SIMPLE_PROFILE_LOW_LEVEL 0 |
| #define VC1_SIMPLE_PROFILE_MED_LEVEL 2 |
| #define VC1_STRUCT_C_LEN 4 |
| #define VC1_STRUCT_C_POS 8 |
| #define VC1_STRUCT_A_POS 12 |
| #define VC1_STRUCT_B_POS 24 |
| #define VC1_SEQ_LAYER_SIZE 36 |
| |
| #define SZ_4K 0x1000 |
| #define SZ_1M 0x100000 |
| #define SECURE_BUFPTR 0xDEADBEEF |
| |
| typedef struct OMXComponentCapabilityFlagsType { |
| ////////////////// OMX COMPONENT CAPABILITY RELATED MEMBERS |
| OMX_U32 nSize; |
| OMX_VERSIONTYPE nVersion; |
| OMX_BOOL iIsOMXComponentMultiThreaded; |
| OMX_BOOL iOMXComponentSupportsExternalOutputBufferAlloc; |
| OMX_BOOL iOMXComponentSupportsExternalInputBufferAlloc; |
| OMX_BOOL iOMXComponentSupportsMovableInputBuffers; |
| OMX_BOOL iOMXComponentSupportsPartialFrames; |
| OMX_BOOL iOMXComponentUsesNALStartCodes; |
| OMX_BOOL iOMXComponentCanHandleIncompleteFrames; |
| OMX_BOOL iOMXComponentUsesFullAVCFrames; |
| |
| } OMXComponentCapabilityFlagsType; |
| #define OMX_COMPONENT_CAPABILITY_TYPE_INDEX 0xFF7A347 |
| |
| void* message_thread(void *input) |
| { |
| omx_video* omx = reinterpret_cast<omx_video*>(input); |
| unsigned char id; |
| int n; |
| |
| DEBUG_PRINT_LOW("omx_venc: message thread start"); |
| prctl(PR_SET_NAME, (unsigned long)"VideoEncMsgThread", 0, 0, 0); |
| while (1) { |
| n = read(omx->m_pipe_in, &id, 1); |
| if (0 == n) { |
| break; |
| } |
| |
| if (1 == n) { |
| omx->process_event_cb(omx, id); |
| } |
| #ifdef QLE_BUILD |
| if (n < 0) break; |
| #else |
| if ((n < 0) && (errno != EINTR)) break; |
| #endif |
| } |
| DEBUG_PRINT_LOW("omx_venc: message thread stop"); |
| return 0; |
| } |
| |
| void post_message(omx_video *omx, unsigned char id) |
| { |
| DEBUG_PRINT_LOW("omx_venc: post_message %d", id); |
| write(omx->m_pipe_out, &id, 1); |
| } |
| |
| // omx_cmd_queue destructor |
| omx_video::omx_cmd_queue::~omx_cmd_queue() |
| { |
| // Nothing to do |
| } |
| |
| // omx cmd queue constructor |
| omx_video::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0) |
| { |
| memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE); |
| } |
| |
| // omx cmd queue insert |
| bool omx_video::omx_cmd_queue::insert_entry(unsigned long p1, unsigned long p2, unsigned long id) |
| { |
| bool ret = true; |
| if (m_size < OMX_CORE_CONTROL_CMDQ_SIZE) { |
| m_q[m_write].id = id; |
| m_q[m_write].param1 = p1; |
| m_q[m_write].param2 = p2; |
| m_write++; |
| m_size ++; |
| if (m_write >= OMX_CORE_CONTROL_CMDQ_SIZE) { |
| m_write = 0; |
| } |
| } else { |
| ret = false; |
| DEBUG_PRINT_ERROR("ERROR!!! Command Queue Full"); |
| } |
| return ret; |
| } |
| |
| // omx cmd queue pop |
| bool omx_video::omx_cmd_queue::pop_entry(unsigned long *p1, unsigned long *p2, unsigned long *id) |
| { |
| bool ret = true; |
| if (m_size > 0) { |
| *id = m_q[m_read].id; |
| *p1 = m_q[m_read].param1; |
| *p2 = m_q[m_read].param2; |
| // Move the read pointer ahead |
| ++m_read; |
| --m_size; |
| if (m_read >= OMX_CORE_CONTROL_CMDQ_SIZE) { |
| m_read = 0; |
| } |
| } else { |
| ret = false; |
| } |
| return ret; |
| } |
| |
| // Retrieve the first mesg type in the queue |
| unsigned omx_video::omx_cmd_queue::get_q_msg_type() |
| { |
| return m_q[m_read].id; |
| } |
| |
| |
| |
| #ifdef _ANDROID_ |
| VideoHeap::VideoHeap(int fd, size_t size, void* base) |
| { |
| // dup file descriptor, map once, use pmem |
| init(dup(fd), base, size, 0 , MEM_DEVICE); |
| } |
| #endif // _ANDROID_ |
| |
| /* ====================================================================== |
| FUNCTION |
| omx_venc::omx_venc |
| |
| DESCRIPTION |
| Constructor |
| |
| PARAMETERS |
| None |
| |
| RETURN VALUE |
| None. |
| ========================================================================== */ |
| omx_video::omx_video(): |
| c2d_opened(false), |
| psource_frame(NULL), |
| pdest_frame(NULL), |
| secure_session(false), |
| mEmptyEosBuffer(NULL), |
| m_pipe_in(-1), |
| m_pipe_out(-1), |
| m_pInput_pmem(NULL), |
| m_pOutput_pmem(NULL), |
| #ifdef USE_ION |
| m_pInput_ion(NULL), |
| m_pOutput_ion(NULL), |
| #endif |
| m_error_propogated(false), |
| m_state(OMX_StateInvalid), |
| m_app_data(NULL), |
| m_use_input_pmem(OMX_FALSE), |
| m_use_output_pmem(OMX_FALSE), |
| m_input_msg_id(OMX_COMPONENT_GENERATE_ETB), |
| m_inp_mem_ptr(NULL), |
| m_out_mem_ptr(NULL), |
| input_flush_progress (false), |
| output_flush_progress (false), |
| input_use_buffer (false), |
| output_use_buffer (false), |
| pending_input_buffers(0), |
| pending_output_buffers(0), |
| m_out_bm_count(0), |
| m_inp_bm_count(0), |
| m_flags(0), |
| m_etb_count(0), |
| m_fbd_count(0), |
| m_event_port_settings_sent(false), |
| hw_overload(false) |
| { |
| DEBUG_PRINT_HIGH("omx_video(): Inside Constructor()"); |
| memset(&m_cmp,0,sizeof(m_cmp)); |
| memset(&m_pCallbacks,0,sizeof(m_pCallbacks)); |
| async_thread_created = false; |
| msg_thread_created = false; |
| |
| mUsesColorConversion = false; |
| pthread_mutex_init(&m_lock, NULL); |
| sem_init(&m_cmd_lock,0,0); |
| DEBUG_PRINT_LOW("meta_buffer_hdr = %p", meta_buffer_hdr); |
| } |
| |
| |
| /* ====================================================================== |
| FUNCTION |
| omx_venc::~omx_venc |
| |
| DESCRIPTION |
| Destructor |
| |
| PARAMETERS |
| None |
| |
| RETURN VALUE |
| None. |
| ========================================================================== */ |
| omx_video::~omx_video() |
| { |
| DEBUG_PRINT_HIGH("~omx_video(): Inside Destructor()"); |
| if (m_pipe_in >= 0) close(m_pipe_in); |
| if (m_pipe_out >= 0) close(m_pipe_out); |
| DEBUG_PRINT_HIGH("omx_video: Waiting on Msg Thread exit"); |
| if (msg_thread_created) |
| pthread_join(msg_thread_id,NULL); |
| DEBUG_PRINT_HIGH("omx_video: Waiting on Async Thread exit"); |
| /*For V4L2 based drivers, pthread_join is done in device_close |
| * so no need to do it here*/ |
| #ifndef _MSM8974_ |
| if (async_thread_created) |
| pthread_join(async_thread_id,NULL); |
| #endif |
| pthread_mutex_destroy(&m_lock); |
| sem_destroy(&m_cmd_lock); |
| DEBUG_PRINT_HIGH("m_etb_count = %" PRIu64 ", m_fbd_count = %" PRIu64, m_etb_count, |
| m_fbd_count); |
| DEBUG_PRINT_HIGH("omx_video: Destructor exit"); |
| DEBUG_PRINT_HIGH("Exiting OMX Video Encoder ..."); |
| } |
| |
| /* ====================================================================== |
| FUNCTION |
| omx_venc::OMXCntrlProcessMsgCb |
| |
| DESCRIPTION |
| IL Client callbacks are generated through this routine. The decoder |
| provides the thread context for this routine. |
| |
| PARAMETERS |
| ctxt -- Context information related to the self. |
| id -- Event identifier. This could be any of the following: |
| 1. Command completion event |
| 2. Buffer done callback event |
| 3. Frame done callback event |
| |
| RETURN VALUE |
| None. |
| |
| ========================================================================== */ |
| void omx_video::process_event_cb(void *ctxt, unsigned char id) |
| { |
| unsigned long p1; // Parameter - 1 |
| unsigned long p2; // Parameter - 2 |
| unsigned long ident; |
| unsigned qsize=0; // qsize |
| omx_video *pThis = (omx_video *) ctxt; |
| |
| if (!pThis) { |
| DEBUG_PRINT_ERROR("ERROR:ProcessMsgCb:Context is incorrect; bailing out"); |
| return; |
| } |
| |
| // Protect the shared queue data structure |
| do { |
| /*Read the message id's from the queue*/ |
| |
| pthread_mutex_lock(&pThis->m_lock); |
| qsize = pThis->m_cmd_q.m_size; |
| if (qsize) { |
| pThis->m_cmd_q.pop_entry(&p1,&p2,&ident); |
| } |
| |
| if (qsize == 0) { |
| qsize = pThis->m_ftb_q.m_size; |
| if (qsize) { |
| pThis->m_ftb_q.pop_entry(&p1,&p2,&ident); |
| } |
| } |
| |
| if (qsize == 0) { |
| qsize = pThis->m_etb_q.m_size; |
| if (qsize) { |
| pThis->m_etb_q.pop_entry(&p1,&p2,&ident); |
| } |
| } |
| |
| pthread_mutex_unlock(&pThis->m_lock); |
| |
| /*process message if we have one*/ |
| if (qsize > 0) { |
| id = ident; |
| switch (id) { |
| case OMX_COMPONENT_GENERATE_EVENT: |
| if (pThis->m_pCallbacks.EventHandler) { |
| switch (p1) { |
| case OMX_CommandStateSet: |
| pThis->m_state = (OMX_STATETYPE) p2; |
| DEBUG_PRINT_LOW("Process -> state set to %d", pThis->m_state); |
| pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, |
| OMX_EventCmdComplete, p1, p2, NULL); |
| break; |
| |
| case OMX_EventError: |
| DEBUG_PRINT_ERROR("ERROR: OMX_EventError: p2 = %lu", p2); |
| if (p2 == (unsigned)OMX_ErrorHardware) { |
| pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, |
| OMX_EventError,OMX_ErrorHardware,0,NULL); |
| } else { |
| pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, |
| OMX_EventError, p2, 0, 0); |
| |
| } |
| break; |
| |
| case OMX_CommandPortDisable: |
| DEBUG_PRINT_LOW("Process -> Port %lu set to PORT_STATE_DISABLED" \ |
| "state", p2); |
| pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, |
| OMX_EventCmdComplete, p1, p2, NULL ); |
| break; |
| case OMX_CommandPortEnable: |
| DEBUG_PRINT_LOW("Process ->Port %lu set PORT_STATE_ENABLED state" \ |
| , p2); |
| pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,\ |
| OMX_EventCmdComplete, p1, p2, NULL ); |
| break; |
| |
| default: |
| DEBUG_PRINT_LOW("process_event_cb forwarding EventCmdComplete %lu", p1); |
| pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, |
| OMX_EventCmdComplete, p1, p2, NULL ); |
| break; |
| |
| } |
| } else { |
| DEBUG_PRINT_ERROR("ERROR: ProcessMsgCb NULL callbacks"); |
| } |
| break; |
| case OMX_COMPONENT_GENERATE_ETB_OPQ: |
| DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_ETB_OPQ"); |
| if (pThis->empty_this_buffer_opaque((OMX_HANDLETYPE)p1,\ |
| (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) { |
| DEBUG_PRINT_ERROR("ERROR: ETBProxy() failed!"); |
| pThis->omx_report_error (); |
| } |
| break; |
| case OMX_COMPONENT_GENERATE_ETB: { |
| OMX_ERRORTYPE iret; |
| DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_ETB"); |
| iret = pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1, (OMX_BUFFERHEADERTYPE *)p2); |
| if (iret == OMX_ErrorInsufficientResources) { |
| DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure due to HW overload"); |
| pThis->omx_report_hw_overload (); |
| } else if (iret != OMX_ErrorNone) { |
| DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure"); |
| pThis->omx_report_error (); |
| } |
| } |
| break; |
| |
| case OMX_COMPONENT_GENERATE_FTB: |
| if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\ |
| (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) { |
| DEBUG_PRINT_ERROR("ERROR: FTBProxy() failed!"); |
| pThis->omx_report_error (); |
| } |
| break; |
| |
| case OMX_COMPONENT_GENERATE_COMMAND: |
| pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\ |
| (OMX_U32)p2,(OMX_PTR)NULL); |
| break; |
| |
| case OMX_COMPONENT_GENERATE_EBD: |
| if ( pThis->empty_buffer_done(&pThis->m_cmp, |
| (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) { |
| DEBUG_PRINT_ERROR("ERROR: empty_buffer_done() failed!"); |
| pThis->omx_report_error (); |
| } |
| break; |
| |
| case OMX_COMPONENT_GENERATE_FBD: |
| if ( pThis->fill_buffer_done(&pThis->m_cmp, |
| (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) { |
| DEBUG_PRINT_ERROR("ERROR: fill_buffer_done() failed!"); |
| pThis->omx_report_error (); |
| } |
| break; |
| |
| case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH: |
| |
| pThis->input_flush_progress = false; |
| DEBUG_PRINT_HIGH("m_etb_count at i/p flush = %" PRIu64, m_etb_count); |
| m_etb_count = 0; |
| if (pThis->m_pCallbacks.EventHandler) { |
| /*Check if we need generate event for Flush done*/ |
| if (BITMASK_PRESENT(&pThis->m_flags, |
| OMX_COMPONENT_INPUT_FLUSH_PENDING)) { |
| BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING); |
| pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, |
| OMX_EventCmdComplete,OMX_CommandFlush, |
| PORT_INDEX_IN,NULL ); |
| } else if (BITMASK_PRESENT(&pThis->m_flags, |
| OMX_COMPONENT_IDLE_PENDING)) { |
| if (!pThis->output_flush_progress) { |
| DEBUG_PRINT_LOW("dev_stop called after input flush complete"); |
| if (dev_stop() != 0) { |
| DEBUG_PRINT_ERROR("ERROR: dev_stop() failed in i/p flush!"); |
| pThis->omx_report_error (); |
| } |
| } |
| } |
| } |
| |
| break; |
| |
| case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH: |
| |
| pThis->output_flush_progress = false; |
| DEBUG_PRINT_HIGH("m_fbd_count at o/p flush = %" PRIu64, m_fbd_count); |
| m_fbd_count = 0; |
| if (pThis->m_pCallbacks.EventHandler) { |
| /*Check if we need generate event for Flush done*/ |
| if (BITMASK_PRESENT(&pThis->m_flags, |
| OMX_COMPONENT_OUTPUT_FLUSH_PENDING)) { |
| BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING); |
| |
| pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, |
| OMX_EventCmdComplete,OMX_CommandFlush, |
| PORT_INDEX_OUT,NULL ); |
| } else if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING)) { |
| DEBUG_PRINT_LOW("dev_stop called after Output flush complete"); |
| if (!pThis->input_flush_progress) { |
| if (dev_stop() != 0) { |
| DEBUG_PRINT_ERROR("ERROR: dev_stop() failed in o/p flush!"); |
| pThis->omx_report_error (); |
| } |
| } |
| } |
| } |
| break; |
| |
| case OMX_COMPONENT_GENERATE_START_DONE: |
| DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_START_DONE msg"); |
| |
| if (pThis->m_pCallbacks.EventHandler) { |
| DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_START_DONE Success"); |
| if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) { |
| DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_START_DONE Move to \ |
| executing"); |
| // Send the callback now |
| BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING); |
| pThis->m_state = OMX_StateExecuting; |
| pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, |
| OMX_EventCmdComplete,OMX_CommandStateSet, |
| OMX_StateExecuting, NULL); |
| } else if (BITMASK_PRESENT(&pThis->m_flags, |
| OMX_COMPONENT_PAUSE_PENDING)) { |
| if (dev_pause()) { |
| DEBUG_PRINT_ERROR("ERROR: dev_pause() failed in Start Done!"); |
| pThis->omx_report_error (); |
| } |
| } else if (BITMASK_PRESENT(&pThis->m_flags, |
| OMX_COMPONENT_LOADED_START_PENDING)) { |
| if (dev_loaded_start_done()) { |
| DEBUG_PRINT_LOW("successful loaded Start Done!"); |
| } else { |
| DEBUG_PRINT_ERROR("ERROR: failed in loaded Start Done!"); |
| pThis->omx_report_error (); |
| } |
| BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_LOADED_START_PENDING); |
| } else { |
| DEBUG_PRINT_LOW("ERROR: unknown flags=%" PRIx64, pThis->m_flags); |
| } |
| } else { |
| DEBUG_PRINT_LOW("Event Handler callback is NULL"); |
| } |
| break; |
| |
| case OMX_COMPONENT_GENERATE_PAUSE_DONE: |
| DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_PAUSE_DONE msg"); |
| if (pThis->m_pCallbacks.EventHandler) { |
| if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING)) { |
| //Send the callback now |
| pThis->complete_pending_buffer_done_cbs(); |
| DEBUG_PRINT_LOW("omx_video::process_event_cb() Sending PAUSE complete after all pending EBD/FBD"); |
| BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING); |
| pThis->m_state = OMX_StatePause; |
| pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, |
| OMX_EventCmdComplete,OMX_CommandStateSet, |
| OMX_StatePause, NULL); |
| } |
| } |
| |
| break; |
| |
| case OMX_COMPONENT_GENERATE_RESUME_DONE: |
| DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_RESUME_DONE msg"); |
| if (pThis->m_pCallbacks.EventHandler) { |
| if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) { |
| // Send the callback now |
| BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING); |
| pThis->m_state = OMX_StateExecuting; |
| pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, |
| OMX_EventCmdComplete,OMX_CommandStateSet, |
| OMX_StateExecuting,NULL); |
| } |
| } |
| |
| break; |
| |
| case OMX_COMPONENT_GENERATE_STOP_DONE: |
| DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_STOP_DONE msg"); |
| if (pThis->m_pCallbacks.EventHandler) { |
| pThis->complete_pending_buffer_done_cbs(); |
| if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING)) { |
| // Send the callback now |
| BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING); |
| pThis->m_state = OMX_StateIdle; |
| pThis->m_pCallbacks.EventHandler(&pThis->m_cmp,pThis->m_app_data, |
| OMX_EventCmdComplete,OMX_CommandStateSet, |
| OMX_StateIdle,NULL); |
| } else if (BITMASK_PRESENT(&pThis->m_flags, |
| OMX_COMPONENT_LOADED_STOP_PENDING)) { |
| if (dev_loaded_stop_done()) { |
| DEBUG_PRINT_LOW("successful loaded Stop Done!"); |
| } else { |
| DEBUG_PRINT_ERROR("ERROR: failed in loaded Stop Done!"); |
| pThis->omx_report_error (); |
| } |
| BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_LOADED_STOP_PENDING); |
| } else { |
| DEBUG_PRINT_LOW("ERROR: unknown flags=%" PRIx64, pThis->m_flags); |
| } |
| } |
| |
| break; |
| |
| case OMX_COMPONENT_GENERATE_HARDWARE_ERROR: |
| DEBUG_PRINT_ERROR("ERROR: OMX_COMPONENT_GENERATE_HARDWARE_ERROR!"); |
| pThis->omx_report_error (); |
| break; |
| #ifndef _MSM8974_ |
| case OMX_COMPONENT_GENERATE_LTRUSE_FAILED: |
| DEBUG_PRINT_ERROR("ERROR: OMX_COMPONENT_GENERATE_LTRUSE_FAILED!"); |
| if (pThis->m_pCallbacks.EventHandler) { |
| DEBUG_PRINT_ERROR("Sending QOMX_ErrorLTRUseFailed, p2 = 0x%x", p2); |
| pThis->m_pCallbacks.EventHandler( |
| &pThis->m_cmp, pThis->m_app_data, |
| OMX_EventError, QOMX_ErrorLTRUseFailed, NULL, NULL); |
| } |
| break; |
| #endif |
| default: |
| DEBUG_PRINT_LOW("process_event_cb unknown msg id 0x%02x", id); |
| break; |
| } |
| } |
| |
| pthread_mutex_lock(&pThis->m_lock); |
| qsize = pThis->m_cmd_q.m_size + pThis->m_ftb_q.m_size +\ |
| pThis->m_etb_q.m_size; |
| |
| pthread_mutex_unlock(&pThis->m_lock); |
| |
| } while (qsize>0); |
| DEBUG_PRINT_LOW("exited the while loop"); |
| |
| } |
| |
| |
| |
| |
| /* ====================================================================== |
| FUNCTION |
| omx_venc::GetComponentVersion |
| |
| DESCRIPTION |
| Returns the component version. |
| |
| PARAMETERS |
| TBD. |
| |
| RETURN VALUE |
| OMX_ErrorNone. |
| |
| ========================================================================== */ |
| OMX_ERRORTYPE omx_video::get_component_version |
| ( |
| OMX_IN OMX_HANDLETYPE hComp, |
| OMX_OUT OMX_STRING componentName, |
| OMX_OUT OMX_VERSIONTYPE* componentVersion, |
| OMX_OUT OMX_VERSIONTYPE* specVersion, |
| OMX_OUT OMX_UUIDTYPE* componentUUID |
| ) |
| { |
| (void)hComp; |
| (void)componentName; |
| (void)componentVersion; |
| (void)componentUUID; |
| if (m_state == OMX_StateInvalid) { |
| DEBUG_PRINT_ERROR("ERROR: Get Comp Version in Invalid State"); |
| return OMX_ErrorInvalidState; |
| } |
| /* TBD -- Return the proper version */ |
| if (specVersion) { |
| specVersion->nVersion = OMX_SPEC_VERSION; |
| } |
| return OMX_ErrorNone; |
| } |
| /* ====================================================================== |
| FUNCTION |
| omx_venc::SendCommand |
| |
| DESCRIPTION |
| Returns zero if all the buffers released.. |
| |
| PARAMETERS |
| None. |
| |
| RETURN VALUE |
| true/false |
| |
| ========================================================================== */ |
| OMX_ERRORTYPE omx_video::send_command(OMX_IN OMX_HANDLETYPE hComp, |
| OMX_IN OMX_COMMANDTYPE cmd, |
| OMX_IN OMX_U32 param1, |
| OMX_IN OMX_PTR cmdData |
| ) |
| { |
| (void)hComp; |
| if (m_state == OMX_StateInvalid) { |
| DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State"); |
| return OMX_ErrorInvalidState; |
| } |
| |
| if (cmd == OMX_CommandFlush || cmd == OMX_CommandPortDisable || cmd == OMX_CommandPortEnable) { |
| if ((param1 != (OMX_U32)PORT_INDEX_IN) && (param1 != (OMX_U32)PORT_INDEX_OUT) && (param1 != (OMX_U32)PORT_INDEX_BOTH)) { |
| DEBUG_PRINT_ERROR("ERROR: omx_video::send_command-->bad port index"); |
| return OMX_ErrorBadPortIndex; |
| } |
| } |
| if (cmd == OMX_CommandMarkBuffer) { |
| if (param1 != PORT_INDEX_IN) { |
| DEBUG_PRINT_ERROR("ERROR: omx_video::send_command-->bad port index"); |
| return OMX_ErrorBadPortIndex; |
| } |
| if (!cmdData) { |
| DEBUG_PRINT_ERROR("ERROR: omx_video::send_command-->param is null"); |
| return OMX_ErrorBadParameter; |
| } |
| } |
| |
| post_event((unsigned long)cmd,(unsigned long)param1,OMX_COMPONENT_GENERATE_COMMAND); |
| sem_wait(&m_cmd_lock); |
| return OMX_ErrorNone; |
| } |
| |
| /* ====================================================================== |
| FUNCTION |
| omx_venc::SendCommand |
| |
| DESCRIPTION |
| Returns zero if all the buffers released.. |
| |
| PARAMETERS |
| None. |
| |
| RETURN VALUE |
| true/false |
| |
| ========================================================================== */ |
| OMX_ERRORTYPE omx_video::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp, |
| OMX_IN OMX_COMMANDTYPE cmd, |
| OMX_IN OMX_U32 param1, |
| OMX_IN OMX_PTR cmdData |
| ) |
| { |
| (void)hComp; |
| (void)cmdData; |
| |
| OMX_ERRORTYPE eRet = OMX_ErrorNone; |
| OMX_STATETYPE eState = (OMX_STATETYPE) param1; |
| int bFlag = 1; |
| |
| if (cmd == OMX_CommandStateSet) { |
| /***************************/ |
| /* Current State is Loaded */ |
| /***************************/ |
| if (m_state == OMX_StateLoaded) { |
| if (eState == OMX_StateIdle) { |
| //if all buffers are allocated or all ports disabled |
| if (allocate_done() || |
| ( m_sInPortDef.bEnabled == OMX_FALSE && m_sOutPortDef.bEnabled == OMX_FALSE)) { |
| DEBUG_PRINT_LOW("OMXCORE-SM: Loaded-->Idle"); |
| } else { |
| DEBUG_PRINT_LOW("OMXCORE-SM: Loaded-->Idle-Pending"); |
| BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING); |
| // Skip the event notification |
| bFlag = 0; |
| } |
| } |
| /* Requesting transition from Loaded to Loaded */ |
| else if (eState == OMX_StateLoaded) { |
| DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Loaded"); |
| post_event(OMX_EventError,OMX_ErrorSameState,\ |
| OMX_COMPONENT_GENERATE_EVENT); |
| eRet = OMX_ErrorSameState; |
| } |
| /* Requesting transition from Loaded to WaitForResources */ |
| else if (eState == OMX_StateWaitForResources) { |
| /* Since error is None , we will post an event |
| at the end of this function definition */ |
| DEBUG_PRINT_LOW("OMXCORE-SM: Loaded-->WaitForResources"); |
| } |
| /* Requesting transition from Loaded to Executing */ |
| else if (eState == OMX_StateExecuting) { |
| DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Executing"); |
| post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ |
| OMX_COMPONENT_GENERATE_EVENT); |
| eRet = OMX_ErrorIncorrectStateTransition; |
| } |
| /* Requesting transition from Loaded to Pause */ |
| else if (eState == OMX_StatePause) { |
| DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Pause"); |
| post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ |
| OMX_COMPONENT_GENERATE_EVENT); |
| eRet = OMX_ErrorIncorrectStateTransition; |
| } |
| /* Requesting transition from Loaded to Invalid */ |
| else if (eState == OMX_StateInvalid) { |
| DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Invalid"); |
| post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); |
| eRet = OMX_ErrorInvalidState; |
| } else { |
| DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->%d Not Handled",\ |
| eState); |
| eRet = OMX_ErrorBadParameter; |
| } |
| } |
| |
| /***************************/ |
| /* Current State is IDLE */ |
| /***************************/ |
| else if (m_state == OMX_StateIdle) { |
| if (eState == OMX_StateLoaded) { |
| if (release_done()) { |
| /* |
| Since error is None , we will post an event at the end |
| of this function definition |
| */ |
| DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Loaded"); |
| if (dev_stop() != 0) { |
| DEBUG_PRINT_ERROR("ERROR: dev_stop() failed at Idle --> Loaded"); |
| eRet = OMX_ErrorHardware; |
| } |
| } else { |
| DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Loaded-Pending"); |
| BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING); |
| // Skip the event notification |
| bFlag = 0; |
| } |
| } |
| /* Requesting transition from Idle to Executing */ |
| else if (eState == OMX_StateExecuting) { |
| if ( dev_start() ) { |
| DEBUG_PRINT_ERROR("ERROR: dev_start() failed in SCP on Idle --> Exe"); |
| omx_report_error (); |
| eRet = OMX_ErrorHardware; |
| } else { |
| BITMASK_SET(&m_flags,OMX_COMPONENT_EXECUTE_PENDING); |
| DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Executing"); |
| bFlag = 0; |
| } |
| |
| dev_start_done(); |
| } |
| /* Requesting transition from Idle to Idle */ |
| else if (eState == OMX_StateIdle) { |
| DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle-->Idle"); |
| post_event(OMX_EventError,OMX_ErrorSameState,\ |
| OMX_COMPONENT_GENERATE_EVENT); |
| eRet = OMX_ErrorSameState; |
| } |
| /* Requesting transition from Idle to WaitForResources */ |
| else if (eState == OMX_StateWaitForResources) { |
| DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle-->WaitForResources"); |
| post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ |
| OMX_COMPONENT_GENERATE_EVENT); |
| eRet = OMX_ErrorIncorrectStateTransition; |
| } |
| /* Requesting transition from Idle to Pause */ |
| else if (eState == OMX_StatePause) { |
| /*To pause the Video core we need to start the driver*/ |
| if ( dev_start() ) { |
| DEBUG_PRINT_ERROR("ERROR: dev_start() failed in SCP on Idle --> Pause"); |
| omx_report_error (); |
| eRet = OMX_ErrorHardware; |
| } else { |
| BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING); |
| DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Pause"); |
| bFlag = 0; |
| } |
| } |
| /* Requesting transition from Idle to Invalid */ |
| else if (eState == OMX_StateInvalid) { |
| DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle-->Invalid"); |
| post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); |
| eRet = OMX_ErrorInvalidState; |
| } else { |
| DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle --> %d Not Handled",eState); |
| eRet = OMX_ErrorBadParameter; |
| } |
| } |
| |
| /******************************/ |
| /* Current State is Executing */ |
| /******************************/ |
| else if (m_state == OMX_StateExecuting) { |
| /* Requesting transition from Executing to Idle */ |
| if (eState == OMX_StateIdle) { |
| /* Since error is None , we will post an event |
| at the end of this function definition |
| */ |
| DEBUG_PRINT_LOW("OMXCORE-SM: Executing --> Idle"); |
| //here this should be Pause-Idle pending and should be cleared when flush is complete and change the state to Idle |
| BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING); |
| execute_omx_flush(OMX_ALL); |
| bFlag = 0; |
| } |
| /* Requesting transition from Executing to Paused */ |
| else if (eState == OMX_StatePause) { |
| |
| if (dev_pause()) { |
| DEBUG_PRINT_ERROR("ERROR: dev_pause() failed in SCP on Exe --> Pause"); |
| post_event(OMX_EventError,OMX_ErrorHardware,\ |
| OMX_COMPONENT_GENERATE_EVENT); |
| eRet = OMX_ErrorHardware; |
| } else { |
| BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING); |
| DEBUG_PRINT_LOW("OMXCORE-SM: Executing-->Pause"); |
| bFlag = 0; |
| } |
| } |
| /* Requesting transition from Executing to Loaded */ |
| else if (eState == OMX_StateLoaded) { |
| DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Executing --> Loaded"); |
| post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ |
| OMX_COMPONENT_GENERATE_EVENT); |
| eRet = OMX_ErrorIncorrectStateTransition; |
| } |
| /* Requesting transition from Executing to WaitForResources */ |
| else if (eState == OMX_StateWaitForResources) { |
| DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Executing --> WaitForResources"); |
| post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ |
| OMX_COMPONENT_GENERATE_EVENT); |
| eRet = OMX_ErrorIncorrectStateTransition; |
| } |
| /* Requesting transition from Executing to Executing */ |
| else if (eState == OMX_StateExecuting) { |
| DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Executing --> Executing"); |
| post_event(OMX_EventError,OMX_ErrorSameState,\ |
| OMX_COMPONENT_GENERATE_EVENT); |
| eRet = OMX_ErrorSameState; |
| } |
| /* Requesting transition from Executing to Invalid */ |
| else if (eState == OMX_StateInvalid) { |
| DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Executing --> Invalid"); |
| post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); |
| eRet = OMX_ErrorInvalidState; |
| } else { |
| DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Executing --> %d Not Handled",eState); |
| eRet = OMX_ErrorBadParameter; |
| } |
| } |
| /***************************/ |
| /* Current State is Pause */ |
| /***************************/ |
| else if (m_state == OMX_StatePause) { |
| /* Requesting transition from Pause to Executing */ |
| if (eState == OMX_StateExecuting) { |
| DEBUG_PRINT_LOW("Pause --> Executing"); |
| if ( dev_resume() ) { |
| post_event(OMX_EventError,OMX_ErrorHardware,\ |
| OMX_COMPONENT_GENERATE_EVENT); |
| eRet = OMX_ErrorHardware; |
| } else { |
| BITMASK_SET(&m_flags,OMX_COMPONENT_EXECUTE_PENDING); |
| DEBUG_PRINT_LOW("OMXCORE-SM: Pause-->Executing"); |
| post_event (0, 0, OMX_COMPONENT_GENERATE_RESUME_DONE); |
| bFlag = 0; |
| } |
| } |
| /* Requesting transition from Pause to Idle */ |
| else if (eState == OMX_StateIdle) { |
| /* Since error is None , we will post an event |
| at the end of this function definition */ |
| DEBUG_PRINT_LOW("Pause --> Idle"); |
| BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING); |
| execute_omx_flush(OMX_ALL); |
| bFlag = 0; |
| } |
| /* Requesting transition from Pause to loaded */ |
| else if (eState == OMX_StateLoaded) { |
| DEBUG_PRINT_ERROR("ERROR: Pause --> loaded"); |
| post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ |
| OMX_COMPONENT_GENERATE_EVENT); |
| eRet = OMX_ErrorIncorrectStateTransition; |
| } |
| /* Requesting transition from Pause to WaitForResources */ |
| else if (eState == OMX_StateWaitForResources) { |
| DEBUG_PRINT_ERROR("ERROR: Pause --> WaitForResources"); |
| post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ |
| OMX_COMPONENT_GENERATE_EVENT); |
| eRet = OMX_ErrorIncorrectStateTransition; |
| } |
| /* Requesting transition from Pause to Pause */ |
| else if (eState == OMX_StatePause) { |
| DEBUG_PRINT_ERROR("ERROR: Pause --> Pause"); |
| post_event(OMX_EventError,OMX_ErrorSameState,\ |
| OMX_COMPONENT_GENERATE_EVENT); |
| eRet = OMX_ErrorSameState; |
| } |
| /* Requesting transition from Pause to Invalid */ |
| else if (eState == OMX_StateInvalid) { |
| DEBUG_PRINT_ERROR("ERROR: Pause --> Invalid"); |
| post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); |
| eRet = OMX_ErrorInvalidState; |
| } else { |
| DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Paused --> %d Not Handled",eState); |
| eRet = OMX_ErrorBadParameter; |
| } |
| } |
| /***************************/ |
| /* Current State is WaitForResources */ |
| /***************************/ |
| else if (m_state == OMX_StateWaitForResources) { |
| /* Requesting transition from WaitForResources to Loaded */ |
| if (eState == OMX_StateLoaded) { |
| /* Since error is None , we will post an event |
| at the end of this function definition */ |
| DEBUG_PRINT_LOW("OMXCORE-SM: WaitForResources-->Loaded"); |
| } |
| /* Requesting transition from WaitForResources to WaitForResources */ |
| else if (eState == OMX_StateWaitForResources) { |
| DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->WaitForResources"); |
| post_event(OMX_EventError,OMX_ErrorSameState, |
| OMX_COMPONENT_GENERATE_EVENT); |
| eRet = OMX_ErrorSameState; |
| } |
| /* Requesting transition from WaitForResources to Executing */ |
| else if (eState == OMX_StateExecuting) { |
| DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->Executing"); |
| post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ |
| OMX_COMPONENT_GENERATE_EVENT); |
| eRet = OMX_ErrorIncorrectStateTransition; |
| } |
| /* Requesting transition from WaitForResources to Pause */ |
| else if (eState == OMX_StatePause) { |
| DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->Pause"); |
| post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ |
| OMX_COMPONENT_GENERATE_EVENT); |
| eRet = OMX_ErrorIncorrectStateTransition; |
| } |
| /* Requesting transition from WaitForResources to Invalid */ |
| else if (eState == OMX_StateInvalid) { |
| DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->Invalid"); |
| post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); |
| eRet = OMX_ErrorInvalidState; |
| } |
| /* Requesting transition from WaitForResources to Loaded - |
| is NOT tested by Khronos TS */ |
| |
| } else { |
| DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: %d --> %d(Not Handled)",m_state,eState); |
| eRet = OMX_ErrorBadParameter; |
| } |
| } |
| /********************************/ |
| /* Current State is Invalid */ |
| /*******************************/ |
| else if (m_state == OMX_StateInvalid) { |
| /* State Transition from Inavlid to any state */ |
| if (eState == (OMX_StateLoaded || OMX_StateWaitForResources |
| || OMX_StateIdle || OMX_StateExecuting |
| || OMX_StatePause || OMX_StateInvalid)) { |
| DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Invalid -->Loaded"); |
| post_event(OMX_EventError,OMX_ErrorInvalidState,\ |
| OMX_COMPONENT_GENERATE_EVENT); |
| eRet = OMX_ErrorInvalidState; |
| } |
| } else if (cmd == OMX_CommandFlush) { |
| if (0 == param1 || OMX_ALL == param1) { |
| BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING); |
| } |
| if (1 == param1 || OMX_ALL == param1) { |
| //generate output flush event only. |
| BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING); |
| } |
| |
| execute_omx_flush(param1); |
| bFlag = 0; |
| } else if ( cmd == OMX_CommandPortEnable) { |
| if (param1 == PORT_INDEX_IN || param1 == OMX_ALL) { |
| m_sInPortDef.bEnabled = OMX_TRUE; |
| |
| if ( (m_state == OMX_StateLoaded && |
| !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) |
| || allocate_input_done()) { |
| post_event(OMX_CommandPortEnable,PORT_INDEX_IN, |
| OMX_COMPONENT_GENERATE_EVENT); |
| } else { |
| DEBUG_PRINT_LOW("OMXCORE-SM: Disabled-->Enabled Pending"); |
| BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING); |
| // Skip the event notification |
| bFlag = 0; |
| } |
| } |
| if (param1 == PORT_INDEX_OUT || param1 == OMX_ALL) { |
| m_sOutPortDef.bEnabled = OMX_TRUE; |
| |
| if ( (m_state == OMX_StateLoaded && |
| !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) |
| || (allocate_output_done())) { |
| post_event(OMX_CommandPortEnable,PORT_INDEX_OUT, |
| OMX_COMPONENT_GENERATE_EVENT); |
| |
| } else { |
| DEBUG_PRINT_LOW("OMXCORE-SM: Disabled-->Enabled Pending"); |
| BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING); |
| // Skip the event notification |
| bFlag = 0; |
| } |
| } |
| } else if (cmd == OMX_CommandPortDisable) { |
| if (param1 == PORT_INDEX_IN || param1 == OMX_ALL) { |
| m_sInPortDef.bEnabled = OMX_FALSE; |
| if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle) |
| && release_input_done()) { |
| post_event(OMX_CommandPortDisable,PORT_INDEX_IN, |
| OMX_COMPONENT_GENERATE_EVENT); |
| } else { |
| BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING); |
| if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) { |
| execute_omx_flush(PORT_INDEX_IN); |
| } |
| |
| // Skip the event notification |
| bFlag = 0; |
| } |
| } |
| if (param1 == PORT_INDEX_OUT || param1 == OMX_ALL) { |
| m_sOutPortDef.bEnabled = OMX_FALSE; |
| |
| if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle) |
| && release_output_done()) { |
| post_event(OMX_CommandPortDisable,PORT_INDEX_OUT,\ |
| OMX_COMPONENT_GENERATE_EVENT); |
| } else { |
| BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING); |
| if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) { |
| execute_omx_flush(PORT_INDEX_OUT); |
| } |
| // Skip the event notification |
| bFlag = 0; |
| |
| } |
| } |
| } else { |
| DEBUG_PRINT_ERROR("ERROR: Invalid Command received other than StateSet (%d)",cmd); |
| eRet = OMX_ErrorNotImplemented; |
| } |
| if (eRet == OMX_ErrorNone && bFlag) { |
| post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT); |
| } |
| sem_post(&m_cmd_lock); |
| return eRet; |
| } |
| |
| /* ====================================================================== |
| FUNCTION |
| omx_venc::ExecuteOmxFlush |
| |
| DESCRIPTION |
| Executes the OMX flush. |
| |
| PARAMETERS |
| flushtype - input flush(1)/output flush(0)/ both. |
| |
| RETURN VALUE |
| true/false |
| |
| ========================================================================== */ |
| bool omx_video::execute_omx_flush(OMX_U32 flushType) |
| { |
| bool bRet = false; |
| DEBUG_PRINT_LOW("execute_omx_flush - %u", (unsigned int)flushType); |
| #ifdef _MSM8974_ |
| /* XXX: The driver/hardware does not support flushing of individual ports |
| * in all states. So we pretty much need to flush both ports internally, |
| * but client should only get the FLUSH_(INPUT|OUTPUT)_DONE for the one it |
| * requested. Since OMX_COMPONENT_(OUTPUT|INPUT)_FLUSH_PENDING isn't set, |
| * we automatically omit sending the FLUSH done for the "opposite" port. */ |
| |
| input_flush_progress = true; |
| output_flush_progress = true; |
| bRet = execute_flush_all(); |
| #else |
| if (flushType == 0 || flushType == OMX_ALL) { |
| input_flush_progress = true; |
| //flush input only |
| bRet = execute_input_flush(); |
| } |
| if (flushType == 1 || flushType == OMX_ALL) { |
| //flush output only |
| output_flush_progress = true; |
| bRet = execute_output_flush(); |
| } |
| #endif |
| return bRet; |
| } |
| /*========================================================================= |
| FUNCTION : execute_output_flush |
| |
| DESCRIPTION |
| Executes the OMX flush at OUTPUT PORT. |
| |
| PARAMETERS |
| None. |
| |
| RETURN VALUE |
| true/false |
| ==========================================================================*/ |
| bool omx_video::execute_output_flush(void) |
| { |
| unsigned long p1 = 0; // Parameter - 1 |
| unsigned long p2 = 0; // Parameter - 2 |
| unsigned long ident = 0; |
| bool bRet = true; |
| |
| /*Generate FBD for all Buffers in the FTBq*/ |
| DEBUG_PRINT_LOW("execute_output_flush"); |
| pthread_mutex_lock(&m_lock); |
| while (m_ftb_q.m_size) { |
| m_ftb_q.pop_entry(&p1,&p2,&ident); |
| |
| if (ident == OMX_COMPONENT_GENERATE_FTB ) { |
| pending_output_buffers++; |
| fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2); |
| } else if (ident == OMX_COMPONENT_GENERATE_FBD) { |
| fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1); |
| } |
| } |
| |
| pthread_mutex_unlock(&m_lock); |
| /*Check if there are buffers with the Driver*/ |
| if (dev_flush(PORT_INDEX_OUT)) { |
| DEBUG_PRINT_ERROR("ERROR: o/p dev_flush() Failed"); |
| return false; |
| } |
| |
| return bRet; |
| } |
| /*========================================================================= |
| FUNCTION : execute_input_flush |
| |
| DESCRIPTION |
| Executes the OMX flush at INPUT PORT. |
| |
| PARAMETERS |
| None. |
| |
| RETURN VALUE |
| true/false |
| ==========================================================================*/ |
| bool omx_video::execute_input_flush(void) |
| { |
| unsigned long p1 = 0; // Parameter - 1 |
| unsigned long p2 = 0; // Parameter - 2 |
| unsigned long ident = 0; |
| bool bRet = true; |
| |
| /*Generate EBD for all Buffers in the ETBq*/ |
| DEBUG_PRINT_LOW("execute_input_flush"); |
| |
| pthread_mutex_lock(&m_lock); |
| while (m_etb_q.m_size) { |
| m_etb_q.pop_entry(&p1,&p2,&ident); |
| if (ident == OMX_COMPONENT_GENERATE_ETB) { |
| pending_input_buffers++; |
| empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2); |
| } else if (ident == OMX_COMPONENT_GENERATE_EBD) { |
| empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1); |
| } else if (ident == OMX_COMPONENT_GENERATE_ETB_OPQ) { |
| m_pCallbacks.EmptyBufferDone(&m_cmp,m_app_data,(OMX_BUFFERHEADERTYPE *)p2); |
| } |
| } |
| if (mUseProxyColorFormat) { |
| if (psource_frame) { |
| m_pCallbacks.EmptyBufferDone(&m_cmp,m_app_data,psource_frame); |
| psource_frame = NULL; |
| } |
| while (m_opq_meta_q.m_size) { |
| unsigned long p1,p2,id; |
| m_opq_meta_q.pop_entry(&p1,&p2,&id); |
| m_pCallbacks.EmptyBufferDone(&m_cmp,m_app_data, |
| (OMX_BUFFERHEADERTYPE *)p1); |
| } |
| if (pdest_frame) { |
| m_opq_pmem_q.insert_entry((unsigned long)pdest_frame,0,0); |
| pdest_frame = NULL; |
| } |
| } |
| pthread_mutex_unlock(&m_lock); |
| /*Check if there are buffers with the Driver*/ |
| if (dev_flush(PORT_INDEX_IN)) { |
| DEBUG_PRINT_ERROR("ERROR: i/p dev_flush() Failed"); |
| return false; |
| } |
| |
| return bRet; |
| } |
| |
| |
| /*========================================================================= |
| FUNCTION : execute_flush |
| |
| DESCRIPTION |
| Executes the OMX flush at INPUT & OUTPUT PORT. |
| |
| PARAMETERS |
| None. |
| |
| RETURN VALUE |
| true/false |
| ==========================================================================*/ |
| #ifdef _MSM8974_ |
| bool omx_video::execute_flush_all(void) |
| { |
| unsigned long p1 = 0; // Parameter - 1 |
| unsigned long p2 = 0; // Parameter - 2 |
| unsigned long ident = 0; |
| bool bRet = true; |
| |
| DEBUG_PRINT_LOW("execute_flush_all"); |
| |
| /*Generate EBD for all Buffers in the ETBq*/ |
| pthread_mutex_lock(&m_lock); |
| while (m_etb_q.m_size) { |
| m_etb_q.pop_entry(&p1,&p2,&ident); |
| if (ident == OMX_COMPONENT_GENERATE_ETB) { |
| pending_input_buffers++; |
| empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2); |
| } else if (ident == OMX_COMPONENT_GENERATE_EBD) { |
| empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1); |
| } else if(ident == OMX_COMPONENT_GENERATE_ETB_OPQ) { |
| m_pCallbacks.EmptyBufferDone(&m_cmp,m_app_data,(OMX_BUFFERHEADERTYPE *)p2); |
| } |
| } |
| if(mUseProxyColorFormat) { |
| if(psource_frame) { |
| m_pCallbacks.EmptyBufferDone(&m_cmp,m_app_data,psource_frame); |
| psource_frame = NULL; |
| } |
| while(m_opq_meta_q.m_size) { |
| unsigned long p1,p2,id; |
| m_opq_meta_q.pop_entry(&p1,&p2,&id); |
| m_pCallbacks.EmptyBufferDone(&m_cmp,m_app_data, |
| (OMX_BUFFERHEADERTYPE *)p1); |
| } |
| if(pdest_frame){ |
| m_opq_pmem_q.insert_entry((unsigned long)pdest_frame,0,0); |
| pdest_frame = NULL; |
| } |
| } |
| |
| /*Generate FBD for all Buffers in the FTBq*/ |
| DEBUG_PRINT_LOW("execute_output_flush"); |
| while (m_ftb_q.m_size) { |
| m_ftb_q.pop_entry(&p1,&p2,&ident); |
| |
| if (ident == OMX_COMPONENT_GENERATE_FTB ) { |
| pending_output_buffers++; |
| fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2); |
| } else if (ident == OMX_COMPONENT_GENERATE_FBD) { |
| fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1); |
| } |
| } |
| |
| pthread_mutex_unlock(&m_lock); |
| |
| /*Check if there are buffers with the Driver*/ |
| if (dev_flush(PORT_INDEX_BOTH)) { |
| DEBUG_PRINT_ERROR("ERROR: dev_flush() Failed"); |
| return false; |
| } |
| return bRet; |
| } |
| |
| #endif |
| |
| /* ====================================================================== |
| FUNCTION |
| omx_venc::SendCommandEvent |
| |
| DESCRIPTION |
| Send the event to decoder pipe. This is needed to generate the callbacks |
| in decoder thread context. |
| |
| PARAMETERS |
| None. |
| |
| RETURN VALUE |
| true/false |
| |
| ========================================================================== */ |
| bool omx_video::post_event(unsigned long p1, |
| unsigned long p2, |
| unsigned long id) |
| { |
| bool bRet = false; |
| |
| pthread_mutex_lock(&m_lock); |
| |
| if ((id == OMX_COMPONENT_GENERATE_FTB) || |
| (id == OMX_COMPONENT_GENERATE_FBD) || |
| (id == OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH)) { |
| m_ftb_q.insert_entry(p1,p2,id); |
| } else if ((id == OMX_COMPONENT_GENERATE_ETB) || |
| (id == OMX_COMPONENT_GENERATE_EBD) || |
| (id == OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH)) { |
| m_etb_q.insert_entry(p1,p2,id); |
| } else { |
| m_cmd_q.insert_entry(p1,p2,id); |
| } |
| |
| bRet = true; |
| DEBUG_PRINT_LOW("Value of this pointer in post_event %p",this); |
| post_message(this, id); |
| pthread_mutex_unlock(&m_lock); |
| |
| return bRet; |
| } |
| |
| /* ====================================================================== |
| FUNCTION |
| omx_venc::GetParameter |
| |
| DESCRIPTION |
| OMX Get Parameter method implementation |
| |
| PARAMETERS |
| <TBD>. |
| |
| RETURN VALUE |
| Error None if successful. |
| |
| ========================================================================== */ |
| OMX_ERRORTYPE omx_video::get_parameter(OMX_IN OMX_HANDLETYPE hComp, |
| OMX_IN OMX_INDEXTYPE paramIndex, |
| OMX_INOUT OMX_PTR paramData) |
| { |
| (void)hComp; |
| OMX_ERRORTYPE eRet = OMX_ErrorNone; |
| unsigned int height=0,width = 0; |
| |
| DEBUG_PRINT_LOW("get_parameter:"); |
| if (m_state == OMX_StateInvalid) { |
| DEBUG_PRINT_ERROR("ERROR: Get Param in Invalid State"); |
| return OMX_ErrorInvalidState; |
| } |
| if (paramData == NULL) { |
| DEBUG_PRINT_ERROR("ERROR: Get Param in Invalid paramData"); |
| return OMX_ErrorBadParameter; |
| } |
| switch ((int)paramIndex) { |
| case OMX_IndexParamPortDefinition: |
| { |
| VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_PORTDEFINITIONTYPE); |
| OMX_PARAM_PORTDEFINITIONTYPE *portDefn; |
| portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData; |
| |
| DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition"); |
| if (portDefn->nPortIndex == (OMX_U32) PORT_INDEX_IN) { |
| dev_get_buf_req (&m_sInPortDef.nBufferCountMin, |
| &m_sInPortDef.nBufferCountActual, |
| &m_sInPortDef.nBufferSize, |
| m_sInPortDef.nPortIndex); |
| DEBUG_PRINT_LOW("m_sInPortDef: size = %u, min cnt = %u, actual cnt = %u", |
| (unsigned int)m_sInPortDef.nBufferSize, (unsigned int)m_sInPortDef.nBufferCountMin, |
| (unsigned int)m_sInPortDef.nBufferCountActual); |
| memcpy(portDefn, &m_sInPortDef, sizeof(m_sInPortDef)); |
| #ifdef _ANDROID_ICS_ |
| if (meta_mode_enable) { |
| portDefn->nBufferSize = sizeof(encoder_media_buffer_type); |
| } |
| if (mUseProxyColorFormat) { |
| portDefn->format.video.eColorFormat = |
| (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FormatAndroidOpaque; |
| } |
| #endif |
| } else if (portDefn->nPortIndex == (OMX_U32) PORT_INDEX_OUT) { |
| if (m_state != OMX_StateExecuting) { |
| dev_get_buf_req (&m_sOutPortDef.nBufferCountMin, |
| &m_sOutPortDef.nBufferCountActual, |
| &m_sOutPortDef.nBufferSize, |
| m_sOutPortDef.nPortIndex); |
| } |
| DEBUG_PRINT_LOW("m_sOutPortDef: size = %u, min cnt = %u, actual cnt = %u", |
| (unsigned int)m_sOutPortDef.nBufferSize, (unsigned int)m_sOutPortDef.nBufferCountMin, |
| (unsigned int)m_sOutPortDef.nBufferCountActual); |
| memcpy(portDefn, &m_sOutPortDef, sizeof(m_sOutPortDef)); |
| } else { |
| DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index"); |
| eRet = OMX_ErrorBadPortIndex; |
| } |
| break; |
| } |
| case OMX_IndexParamVideoInit: |
| { |
| VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE); |
| OMX_PORT_PARAM_TYPE *portParamType = |
| (OMX_PORT_PARAM_TYPE *) paramData; |
| DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit"); |
| |
| memcpy(portParamType, &m_sPortParam, sizeof(m_sPortParam)); |
| break; |
| } |
| case OMX_IndexParamVideoPortFormat: |
| { |
| VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PORTFORMATTYPE); |
| OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt = |
| (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData; |
| DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat"); |
| |
| if (portFmt->nPortIndex == (OMX_U32) PORT_INDEX_IN) { |
| unsigned index = portFmt->nIndex; |
| //we support two formats |
| //index 0 - Venus flavour of YUV420SP |
| //index 1 - opaque which internally maps to YUV420SP. |
| //index 2 - vannilla YUV420SP |
| //this can be extended in the future |
| int supportedFormats[] = { |
| [0] = QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m, |
| [1] = QOMX_COLOR_FormatAndroidOpaque, |
| [2] = OMX_COLOR_FormatYUV420SemiPlanar, |
| }; |
| |
| if (index > (sizeof(supportedFormats)/sizeof(*supportedFormats) - 1)) |
| eRet = OMX_ErrorNoMore; |
| else { |
| memcpy(portFmt, &m_sInPortFormat, sizeof(m_sInPortFormat)); |
| portFmt->nIndex = index; //restore index set from client |
| portFmt->eColorFormat = (OMX_COLOR_FORMATTYPE)supportedFormats[index]; |
| } |
| } else if (portFmt->nPortIndex == (OMX_U32) PORT_INDEX_OUT) { |
| memcpy(portFmt, &m_sOutPortFormat, sizeof(m_sOutPortFormat)); |
| } else { |
| DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index"); |
| eRet = OMX_ErrorBadPortIndex; |
| } |
| break; |
| } |
| case OMX_IndexParamVideoBitrate: |
| { |
| VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_BITRATETYPE); |
| OMX_VIDEO_PARAM_BITRATETYPE* pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData; |
| DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoBitrate"); |
| |
| if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) { |
| memcpy(pParam, &m_sParamBitrate, sizeof(m_sParamBitrate)); |
| } else { |
| DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index"); |
| eRet = OMX_ErrorBadPortIndex; |
| } |
| |
| break; |
| } |
| case OMX_IndexParamVideoMpeg4: |
| { |
| VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_MPEG4TYPE); |
| OMX_VIDEO_PARAM_MPEG4TYPE* pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData; |
| DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4"); |
| memcpy(pParam, &m_sParamMPEG4, sizeof(m_sParamMPEG4)); |
| break; |
| } |
| case OMX_IndexParamVideoH263: |
| { |
| VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_H263TYPE); |
| OMX_VIDEO_PARAM_H263TYPE* pParam = (OMX_VIDEO_PARAM_H263TYPE*)paramData; |
| DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263"); |
| memcpy(pParam, &m_sParamH263, sizeof(m_sParamH263)); |
| break; |
| } |
| case OMX_IndexParamVideoAvc: |
| { |
| VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_AVCTYPE); |
| OMX_VIDEO_PARAM_AVCTYPE* pParam = (OMX_VIDEO_PARAM_AVCTYPE*)paramData; |
| DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc"); |
| memcpy(pParam, &m_sParamAVC, sizeof(m_sParamAVC)); |
| break; |
| } |
| case (OMX_INDEXTYPE)OMX_IndexParamVideoVp8: |
| { |
| VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_VP8TYPE); |
| OMX_VIDEO_PARAM_VP8TYPE* pParam = (OMX_VIDEO_PARAM_VP8TYPE*)paramData; |
| DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoVp8"); |
| memcpy(pParam, &m_sParamVP8, sizeof(m_sParamVP8)); |
| break; |
| } |
| case (OMX_INDEXTYPE)OMX_IndexParamVideoHevc: |
| { |
| VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_HEVCTYPE); |
| OMX_VIDEO_PARAM_HEVCTYPE* pParam = (OMX_VIDEO_PARAM_HEVCTYPE*)paramData; |
| DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoHevc"); |
| memcpy(pParam, &m_sParamHEVC, sizeof(m_sParamHEVC)); |
| break; |
| } |
| case OMX_IndexParamVideoProfileLevelQuerySupported: |
| { |
| VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE); |
| OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData; |
| DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported"); |
| eRet = get_supported_profile_level(pParam); |
| if (eRet && eRet != OMX_ErrorNoMore) |
| DEBUG_PRINT_ERROR("Invalid entry returned from get_supported_profile_level %u, %u", |
| (unsigned int)pParam->eProfile, (unsigned int)pParam->eLevel); |
| break; |
| } |
| case OMX_IndexParamVideoProfileLevelCurrent: |
| { |
| VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE); |
| OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData; |
| DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelCurrent"); |
| memcpy(pParam, &m_sParamProfileLevel, sizeof(m_sParamProfileLevel)); |
| break; |
| } |
| /*Component should support this port definition*/ |
| case OMX_IndexParamAudioInit: |
| { |
| VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE); |
| OMX_PORT_PARAM_TYPE *audioPortParamType = (OMX_PORT_PARAM_TYPE *) paramData; |
| DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit"); |
| memcpy(audioPortParamType, &m_sPortParam_audio, sizeof(m_sPortParam_audio)); |
| break; |
| } |
| /*Component should support this port definition*/ |
| case OMX_IndexParamImageInit: |
| { |
| VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE); |
| OMX_PORT_PARAM_TYPE *imagePortParamType = (OMX_PORT_PARAM_TYPE *) paramData; |
| DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit"); |
| memcpy(imagePortParamType, &m_sPortParam_img, sizeof(m_sPortParam_img)); |
| break; |
| |
| } |
| /*Component should support this port definition*/ |
| case OMX_IndexParamOtherInit: |
| { |
| DEBUG_PRINT_ERROR("ERROR: get_parameter: OMX_IndexParamOtherInit %08x", paramIndex); |
| eRet =OMX_ErrorUnsupportedIndex; |
| break; |
| } |
| case OMX_IndexParamStandardComponentRole: |
| { |
| VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_COMPONENTROLETYPE); |
| OMX_PARAM_COMPONENTROLETYPE *comp_role; |
| comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData; |
| comp_role->nVersion.nVersion = OMX_SPEC_VERSION; |
| comp_role->nSize = sizeof(*comp_role); |
| |
| DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d",paramIndex); |
| strlcpy((char*)comp_role->cRole,(const char*)m_cRole,OMX_MAX_STRINGNAME_SIZE); |
| break; |
| } |
| /* Added for parameter test */ |
| case OMX_IndexParamPriorityMgmt: |
| { |
| VALIDATE_OMX_PARAM_DATA(paramData, OMX_PRIORITYMGMTTYPE); |
| OMX_PRIORITYMGMTTYPE *priorityMgmType = (OMX_PRIORITYMGMTTYPE *) paramData; |
| DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt"); |
| memcpy(priorityMgmType, &m_sPriorityMgmt, sizeof(m_sPriorityMgmt)); |
| break; |
| } |
| /* Added for parameter test */ |
| case OMX_IndexParamCompBufferSupplier: |
| { |
| VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_BUFFERSUPPLIERTYPE); |
| OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData; |
| DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier"); |
| if (bufferSupplierType->nPortIndex ==(OMX_U32) PORT_INDEX_IN) { |
| memcpy(bufferSupplierType, &m_sInBufSupplier, sizeof(m_sInBufSupplier)); |
| } else if (bufferSupplierType->nPortIndex ==(OMX_U32) PORT_INDEX_OUT) { |
| memcpy(bufferSupplierType, &m_sOutBufSupplier, sizeof(m_sOutBufSupplier)); |
| } else { |
| DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index"); |
| eRet = OMX_ErrorBadPortIndex; |
| } |
| break; |
| } |
| |
| case OMX_IndexParamVideoQuantization: |
| { |
| VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_QUANTIZATIONTYPE); |
| OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp = (OMX_VIDEO_PARAM_QUANTIZATIONTYPE*) paramData; |
| DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoQuantization"); |
| memcpy(session_qp, &m_sSessionQuantization, sizeof(m_sSessionQuantization)); |
| break; |
| } |
| |
| case OMX_QcomIndexParamVideoQPRange: |
| { |
| VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_VIDEO_PARAM_QPRANGETYPE); |
| OMX_QCOM_VIDEO_PARAM_QPRANGETYPE *qp_range = (OMX_QCOM_VIDEO_PARAM_QPRANGETYPE*) paramData; |
| DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamVideoQPRange"); |
| memcpy(qp_range, &m_sSessionQPRange, sizeof(m_sSessionQPRange)); |
| break; |
| } |
| |
| case OMX_IndexParamVideoErrorCorrection: |
| { |
| VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE); |
| OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* errorresilience = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE*)paramData; |
| DEBUG_PRINT_LOW("OMX_IndexParamVideoErrorCorrection"); |
| errorresilience->bEnableHEC = m_sErrorCorrection.bEnableHEC; |
| errorresilience->bEnableResync = m_sErrorCorrection.bEnableResync; |
| errorresilience->nResynchMarkerSpacing = m_sErrorCorrection.nResynchMarkerSpacing; |
| break; |
| } |
| case OMX_IndexParamVideoIntraRefresh: |
| { |
| VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_INTRAREFRESHTYPE); |
| OMX_VIDEO_PARAM_INTRAREFRESHTYPE* intrarefresh = (OMX_VIDEO_PARAM_INTRAREFRESHTYPE*)paramData; |
| DEBUG_PRINT_LOW("OMX_IndexParamVideoIntraRefresh"); |
| DEBUG_PRINT_ERROR("OMX_IndexParamVideoIntraRefresh GET"); |
| intrarefresh->eRefreshMode = m_sIntraRefresh.eRefreshMode; |
| intrarefresh->nCirMBs = m_sIntraRefresh.nCirMBs; |
| break; |
| } |
| case OMX_QcomIndexPortDefn: |
| //TODO |
| break; |
| case OMX_COMPONENT_CAPABILITY_TYPE_INDEX: |
| { |
| VALIDATE_OMX_PARAM_DATA(paramData, OMXComponentCapabilityFlagsType); |
| OMXComponentCapabilityFlagsType *pParam = reinterpret_cast<OMXComponentCapabilityFlagsType*>(paramData); |
| DEBUG_PRINT_LOW("get_parameter: OMX_COMPONENT_CAPABILITY_TYPE_INDEX"); |
| pParam->iIsOMXComponentMultiThreaded = OMX_TRUE; |
| pParam->iOMXComponentSupportsExternalOutputBufferAlloc = OMX_FALSE; |
| pParam->iOMXComponentSupportsExternalInputBufferAlloc = OMX_TRUE; |
| pParam->iOMXComponentSupportsMovableInputBuffers = OMX_TRUE; |
| pParam->iOMXComponentUsesNALStartCodes = OMX_TRUE; |
| pParam->iOMXComponentSupportsPartialFrames = OMX_FALSE; |
| pParam->iOMXComponentCanHandleIncompleteFrames = OMX_FALSE; |
| pParam->iOMXComponentUsesFullAVCFrames = OMX_FALSE; |
| m_use_input_pmem = OMX_TRUE; |
| DEBUG_PRINT_LOW("Supporting capability index in encoder node"); |
| break; |
| } |
| #if !defined(MAX_RES_720P) || defined(_MSM8974_) |
| case OMX_QcomIndexParamIndexExtraDataType: |
| { |
| VALIDATE_OMX_PARAM_DATA(paramData, QOMX_INDEXEXTRADATATYPE); |
| DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamIndexExtraDataType"); |
| QOMX_INDEXEXTRADATATYPE *pParam = (QOMX_INDEXEXTRADATATYPE *)paramData; |
| if (pParam->nIndex == (OMX_INDEXTYPE)OMX_ExtraDataVideoEncoderSliceInfo) { |
| if (pParam->nPortIndex == PORT_INDEX_OUT) { |
| pParam->bEnabled = |
| (OMX_BOOL)(m_sExtraData & VEN_EXTRADATA_SLICEINFO); |
| DEBUG_PRINT_HIGH("Slice Info extradata %d", pParam->bEnabled); |
| } else { |
| DEBUG_PRINT_ERROR("get_parameter: slice information is " |
| "valid for output port only"); |
| eRet =OMX_ErrorUnsupportedIndex; |
| } |
| } else if (pParam->nIndex == (OMX_INDEXTYPE)OMX_ExtraDataVideoEncoderMBInfo) { |
| if (pParam->nPortIndex == PORT_INDEX_OUT) { |
| pParam->bEnabled = |
| (OMX_BOOL)(m_sExtraData & VEN_EXTRADATA_MBINFO); |
| DEBUG_PRINT_HIGH("MB Info extradata %d", pParam->bEnabled); |
| } else { |
| DEBUG_PRINT_ERROR("get_parameter: MB information is " |
| "valid for output port only"); |
| eRet = OMX_ErrorUnsupportedIndex; |
| } |
| } |
| #ifndef _MSM8974_ |
| else if (pParam->nIndex == (OMX_INDEXTYPE)OMX_ExtraDataVideoLTRInfo) { |
| if (pParam->nPortIndex == PORT_INDEX_OUT) { |
| pParam->bEnabled = |
| (OMX_BOOL)(m_sExtraData & VEN_EXTRADATA_LTRINFO); |
| DEBUG_PRINT_HIGH("LTR Info extradata %d", pParam->bEnabled); |
| } else { |
| DEBUG_PRINT_ERROR("get_parameter: LTR information is " |
| "valid for output port only"); |
| eRet = OMX_ErrorUnsupportedIndex; |
| } |
| } |
| #endif |
| else { |
| DEBUG_PRINT_ERROR("get_parameter: unsupported extradata index (0x%x)", |
| pParam->nIndex); |
| eRet = OMX_ErrorUnsupportedIndex; |
| } |
| break; |
| } |
| case QOMX_IndexParamVideoLTRCountRangeSupported: |
| { |
| VALIDATE_OMX_PARAM_DATA(paramData, QOMX_EXTNINDEX_RANGETYPE); |
| DEBUG_PRINT_HIGH("get_parameter: QOMX_IndexParamVideoLTRCountRangeSupported"); |
| QOMX_EXTNINDEX_RANGETYPE *pParam = (QOMX_EXTNINDEX_RANGETYPE *)paramData; |
| if (pParam->nPortIndex == PORT_INDEX_OUT) { |
| OMX_U32 min = 0, max = 0, step_size = 0; |
| if (dev_get_capability_ltrcount(&min, &max, &step_size)) { |
| pParam->nMin = min; |
| pParam->nMax = max; |
| pParam->nStepSize = step_size; |
| } else { |
| DEBUG_PRINT_ERROR("get_parameter: get_capability_ltrcount failed"); |
| eRet = OMX_ErrorUndefined; |
| } |
| } else { |
| DEBUG_PRINT_ERROR("LTR count range is valid for output port only"); |
| eRet = OMX_ErrorUnsupportedIndex; |
| } |
| } |
| break; |
| case OMX_QcomIndexParamVideoLTRCount: |
| { |
| VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_VIDEO_PARAM_LTRCOUNT_TYPE); |
| DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamVideoLTRCount"); |
| OMX_QCOM_VIDEO_PARAM_LTRCOUNT_TYPE *pParam = |
| reinterpret_cast<OMX_QCOM_VIDEO_PARAM_LTRCOUNT_TYPE*>(paramData); |
| memcpy(pParam, &m_sParamLTRCount, sizeof(m_sParamLTRCount)); |
| break; |
| } |
| #endif |
| case QOMX_IndexParamVideoSyntaxHdr: |
| { |
| VALIDATE_OMX_PARAM_DATA(paramData, QOMX_EXTNINDEX_PARAMTYPE); |
| DEBUG_PRINT_HIGH("QOMX_IndexParamVideoSyntaxHdr"); |
| QOMX_EXTNINDEX_PARAMTYPE* pParam = |
| reinterpret_cast<QOMX_EXTNINDEX_PARAMTYPE*>(paramData); |
| if (pParam->pData == NULL) { |
| DEBUG_PRINT_ERROR("Error: Data buffer is NULL"); |
| eRet = OMX_ErrorBadParameter; |
| break; |
| } |
| if (get_syntaxhdr_enable == false) { |
| DEBUG_PRINT_ERROR("ERROR: get_parameter: Get syntax header disabled"); |
| eRet = OMX_ErrorUnsupportedIndex; |
| break; |
| } |
| BITMASK_SET(&m_flags, OMX_COMPONENT_LOADED_START_PENDING); |
| if (dev_loaded_start()) { |
| DEBUG_PRINT_LOW("device start successful"); |
| } else { |
| DEBUG_PRINT_ERROR("device start failed"); |
| BITMASK_CLEAR(&m_flags, OMX_COMPONENT_LOADED_START_PENDING); |
| return OMX_ErrorHardware; |
| } |
| if (dev_get_seq_hdr(pParam->pData, |
| (unsigned)(pParam->nSize - sizeof(QOMX_EXTNINDEX_PARAMTYPE)), |
| (unsigned *)(void *)&pParam->nDataSize)) { |
| DEBUG_PRINT_HIGH("get syntax header successful (hdrlen = %u)", |
| (unsigned int)pParam->nDataSize); |
| for (unsigned i = 0; i < pParam->nDataSize; i++) { |
| DEBUG_PRINT_LOW("Header[%d] = %x", i, *((char *)pParam->pData + i)); |
| } |
| } else { |
| DEBUG_PRINT_ERROR("Error returned from GetSyntaxHeader()"); |
| eRet = OMX_ErrorHardware; |
| } |
| BITMASK_SET(&m_flags, OMX_COMPONENT_LOADED_STOP_PENDING); |
| if (dev_loaded_stop()) { |
| DEBUG_PRINT_LOW("device stop successful"); |
| } else { |
| DEBUG_PRINT_ERROR("device stop failed"); |
| BITMASK_CLEAR(&m_flags, OMX_COMPONENT_LOADED_STOP_PENDING); |
| eRet = OMX_ErrorHardware; |
| } |
| break; |
| } |
| case OMX_QcomIndexHierarchicalStructure: |
| { |
| VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_HIERARCHICALLAYERS); |
| QOMX_VIDEO_HIERARCHICALLAYERS* hierp = (QOMX_VIDEO_HIERARCHICALLAYERS*) paramData; |
| DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexHierarchicalStructure"); |
| memcpy(hierp, &m_sHierLayers, sizeof(m_sHierLayers)); |
| break; |
| } |
| case OMX_QcomIndexParamPerfLevel: |
| { |
| VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_VIDEO_PARAM_PERF_LEVEL); |
| OMX_U32 perflevel; |
| OMX_QCOM_VIDEO_PARAM_PERF_LEVEL *pParam = |
| reinterpret_cast<OMX_QCOM_VIDEO_PARAM_PERF_LEVEL*>(paramData); |
| DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamPerfLevel"); |
| if (!dev_get_performance_level(&perflevel)) { |
| DEBUG_PRINT_ERROR("Invalid entry returned from get_performance_level %d", |
| pParam->ePerfLevel); |
| } else { |
| pParam->ePerfLevel = (QOMX_VIDEO_PERF_LEVEL)perflevel; |
| } |
| break; |
| } |
| case OMX_QcomIndexParamH264VUITimingInfo: |
| { |
| VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO); |
| OMX_U32 enabled; |
| OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO *pParam = |
| reinterpret_cast<OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO*>(paramData); |
| DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamH264VUITimingInfo"); |
| if (!dev_get_vui_timing_info(&enabled)) { |
| DEBUG_PRINT_ERROR("Invalid entry returned from get_vui_Timing_info %d", |
| pParam->bEnable); |
| } else { |
| pParam->bEnable = (OMX_BOOL)enabled; |
| } |
| break; |
| } |
| case OMX_QcomIndexParamPeakBitrate: |
| { |
| VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_VIDEO_PARAM_PEAK_BITRATE); |
| OMX_U32 peakbitrate; |
| OMX_QCOM_VIDEO_PARAM_PEAK_BITRATE *pParam = |
| reinterpret_cast<OMX_QCOM_VIDEO_PARAM_PEAK_BITRATE*>(paramData); |
| DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamPeakBitrate"); |
| if (!dev_get_peak_bitrate(&peakbitrate)) { |
| DEBUG_PRINT_ERROR("Invalid entry returned from get_peak_bitrate %u", |
| (unsigned int)pParam->nPeakBitrate); |
| } else { |
| pParam->nPeakBitrate = peakbitrate; |
| } |
| break; |
| } |
| case QOMX_IndexParamVideoInitialQp: |
| { |
| VALIDATE_OMX_PARAM_DATA(paramData, QOMX_EXTNINDEX_VIDEO_INITIALQP); |
| QOMX_EXTNINDEX_VIDEO_INITIALQP* initqp = |
| reinterpret_cast<QOMX_EXTNINDEX_VIDEO_INITIALQP *>(paramData); |
| memcpy(initqp, &m_sParamInitqp, sizeof(m_sParamInitqp)); |
| break; |
| } |
| case OMX_IndexParamVideoSliceFMO: |
| default: |
| { |
| DEBUG_PRINT_LOW("ERROR: get_parameter: unknown param %08x", paramIndex); |
| eRet =OMX_ErrorUnsupportedIndex; |
| break; |
| } |
| |
| } |
| |
| return eRet; |
| |
| } |
| /* ====================================================================== |
| FUNCTION |
| omx_video::GetConfig |
| |
| DESCRIPTION |
| OMX Get Config Method implementation. |
| |
| PARAMETERS |
| <TBD>. |
| |
| RETURN VALUE |
| OMX Error None if successful. |
| |
| ========================================================================== */ |
| OMX_ERRORTYPE omx_video::get_config(OMX_IN OMX_HANDLETYPE hComp, |
| OMX_IN OMX_INDEXTYPE configIndex, |
| OMX_INOUT OMX_PTR configData) |
| { |
| (void)hComp; |
| //////////////////////////////////////////////////////////////// |
| // Supported Config Index Type |
| // ============================================================= |
| // OMX_IndexConfigVideoBitrate OMX_VIDEO_CONFIG_BITRATETYPE |
| // OMX_IndexConfigVideoFramerate OMX_CONFIG_FRAMERATETYPE |
| // OMX_IndexConfigCommonRotate OMX_CONFIG_ROTATIONTYPE |
| //////////////////////////////////////////////////////////////// |
| |
| if (configData == NULL) { |
| DEBUG_PRINT_ERROR("ERROR: param is null"); |
| return OMX_ErrorBadParameter; |
| } |
| |
| if (m_state == OMX_StateInvalid) { |
| DEBUG_PRINT_ERROR("ERROR: can't be in invalid state"); |
| return OMX_ErrorIncorrectStateOperation; |
| } |
| |
| //@todo need to validate params |
| switch ((int)configIndex) { |
| case OMX_IndexConfigVideoBitrate: |
| { |
| VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_CONFIG_BITRATETYPE); |
| OMX_VIDEO_CONFIG_BITRATETYPE* pParam = reinterpret_cast<OMX_VIDEO_CONFIG_BITRATETYPE*>(configData); |
| memcpy(pParam, &m_sConfigBitrate, sizeof(m_sConfigBitrate)); |
| break; |
| } |
| case OMX_IndexConfigVideoFramerate: |
| { |
| VALIDATE_OMX_PARAM_DATA(configData, OMX_CONFIG_FRAMERATETYPE); |
| OMX_CONFIG_FRAMERATETYPE* pParam = reinterpret_cast<OMX_CONFIG_FRAMERATETYPE*>(configData); |
| memcpy(pParam, &m_sConfigFramerate, sizeof(m_sConfigFramerate)); |
| break; |
| } |
| case OMX_IndexConfigCommonRotate: |
| { |
| VALIDATE_OMX_PARAM_DATA(configData, OMX_CONFIG_ROTATIONTYPE); |
| OMX_CONFIG_ROTATIONTYPE* pParam = reinterpret_cast<OMX_CONFIG_ROTATIONTYPE*>(configData); |
| memcpy(pParam, &m_sConfigFrameRotation, sizeof(m_sConfigFrameRotation)); |
| break; |
| } |
| case QOMX_IndexConfigVideoIntraperiod: |
| { |
| DEBUG_PRINT_LOW("get_config:QOMX_IndexConfigVideoIntraperiod"); |
| VALIDATE_OMX_PARAM_DATA(configData, QOMX_VIDEO_INTRAPERIODTYPE); |
| QOMX_VIDEO_INTRAPERIODTYPE* pParam = reinterpret_cast<QOMX_VIDEO_INTRAPERIODTYPE*>(configData); |
| memcpy(pParam, &m_sIntraperiod, sizeof(m_sIntraperiod)); |
| break; |
| } |
| case OMX_IndexConfigVideoAVCIntraPeriod: |
| { |
| VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_CONFIG_AVCINTRAPERIOD); |
| OMX_VIDEO_CONFIG_AVCINTRAPERIOD *pParam = |
| reinterpret_cast<OMX_VIDEO_CONFIG_AVCINTRAPERIOD*>(configData); |
| DEBUG_PRINT_LOW("get_config: OMX_IndexConfigVideoAVCIntraPeriod"); |
| memcpy(pParam, &m_sConfigAVCIDRPeriod, sizeof(m_sConfigAVCIDRPeriod)); |
| break; |
| } |
| case OMX_IndexConfigCommonDeinterlace: |
| { |
| VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_CONFIG_DEINTERLACE); |
| OMX_VIDEO_CONFIG_DEINTERLACE *pParam = |
| reinterpret_cast<OMX_VIDEO_CONFIG_DEINTERLACE*>(configData); |
| DEBUG_PRINT_LOW("get_config: OMX_IndexConfigCommonDeinterlace"); |
| memcpy(pParam, &m_sConfigDeinterlace, sizeof(m_sConfigDeinterlace)); |
| break; |
| } |
| case OMX_IndexConfigVideoVp8ReferenceFrame: |
| { |
| VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_VP8REFERENCEFRAMETYPE); |
| OMX_VIDEO_VP8REFERENCEFRAMETYPE* pParam = |
| reinterpret_cast<OMX_VIDEO_VP8REFERENCEFRAMETYPE*>(configData); |
| DEBUG_PRINT_LOW("get_config: OMX_IndexConfigVideoVp8ReferenceFrame"); |
| memcpy(pParam, &m_sConfigVp8ReferenceFrame, sizeof(m_sConfigVp8ReferenceFrame)); |
| break; |
| } |
| case OMX_QcomIndexConfigPerfLevel: |
| { |
| VALIDATE_OMX_PARAM_DATA(configData, OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL); |
| OMX_U32 perflevel; |
| OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *pParam = |
| reinterpret_cast<OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL*>(configData); |
| DEBUG_PRINT_LOW("get_config: OMX_QcomIndexConfigPerfLevel"); |
| if (!dev_get_performance_level(&perflevel)) { |
| DEBUG_PRINT_ERROR("Invalid entry returned from get_performance_level %d", |
| pParam->ePerfLevel); |
| } else { |
| pParam->ePerfLevel = (QOMX_VIDEO_PERF_LEVEL)perflevel; |
| } |
| break; |
| } |
| default: |
| DEBUG_PRINT_ERROR("ERROR: unsupported index %d", (int) configIndex); |
| return OMX_ErrorUnsupportedIndex; |
| } |
| return OMX_ErrorNone; |
| |
| } |
| |
| /* ====================================================================== |
| FUNCTION |
| omx_video::GetExtensionIndex |
| |
| DESCRIPTION |
| OMX GetExtensionIndex method implementaion. <TBD> |
| |
| PARAMETERS |
| <TBD>. |
| |
| RETURN VALUE |
| OMX Error None if everything successful. |
| |
| ========================================================================== */ |
| OMX_ERRORTYPE omx_video::get_extension_index(OMX_IN OMX_HANDLETYPE hComp, |
| OMX_IN OMX_STRING paramName, |
| OMX_OUT OMX_INDEXTYPE* indexType) |
| { |
| (void)hComp; |
| if (m_state == OMX_StateInvalid) { |
| DEBUG_PRINT_ERROR("ERROR: Get Extension Index in Invalid State"); |
| return OMX_ErrorInvalidState; |
| } |
| #ifdef MAX_RES_1080P |
| if (!strncmp(paramName, "OMX.QCOM.index.param.SliceDeliveryMode", |
| sizeof("OMX.QCOM.index.param.SliceDeliveryMode") - 1)) { |
| *indexType = (OMX_INDEXTYPE)OMX_QcomIndexEnableSliceDeliveryMode; |
| return OMX_ErrorNone; |
| } |
| #endif |
| #ifdef _ANDROID_ICS_ |
| if (!strncmp(paramName, "OMX.google.android.index.storeMetaDataInBuffers", |
| sizeof("OMX.google.android.index.storeMetaDataInBuffers") - 1)) { |
| *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoMetaBufferMode; |
| return OMX_ErrorNone; |
| } |
| #endif |
| if (!strncmp(paramName, "OMX.google.android.index.prependSPSPPSToIDRFrames", |
| sizeof("OMX.google.android.index.prependSPSPPSToIDRFrames") - 1)) { |
| *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamSequenceHeaderWithIDR; |
| return OMX_ErrorNone; |
| } |
| return OMX_ErrorNotImplemented; |
| } |
| |
| /* ====================================================================== |
| FUNCTION |
| omx_video::GetState |
| |
| DESCRIPTION |
| Returns the state information back to the caller.<TBD> |
| |
| PARAMETERS |
| <TBD>. |
| |
| RETURN VALUE |
| Error None if everything is successful. |
| ========================================================================== */ |
| OMX_ERRORTYPE omx_video::get_state(OMX_IN OMX_HANDLETYPE hComp, |
| OMX_OUT OMX_STATETYPE* state) |
| { |
| (void)hComp; |
| *state = m_state; |
| DEBUG_PRINT_LOW("get_state: Returning the state %d",*state); |
| return OMX_ErrorNone; |
| } |
| |
| /* ====================================================================== |
| FUNCTION |
| omx_video::ComponentTunnelRequest |
| |
| DESCRIPTION |
| OMX Component Tunnel Request method implementation. <TBD> |
| |
| PARAMETERS |
| None. |
| |
| RETURN VALUE |
| OMX Error None if everything successful. |
| |
| ========================================================================== */ |
| OMX_ERRORTYPE omx_video::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp, |
| OMX_IN OMX_U32 port, |
| OMX_IN OMX_HANDLETYPE peerComponent, |
| OMX_IN OMX_U32 peerPort, |
| OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup) |
| { |
| (void) hComp, (void) port, (void) peerComponent, (void) peerPort, (void) tunnelSetup; |
| DEBUG_PRINT_ERROR("ERROR: component_tunnel_request Not Implemented"); |
| return OMX_ErrorNotImplemented; |
| } |
| |
| /* ====================================================================== |
| FUNCTION |
| omx_video::UseInputBuffer |
| |
| DESCRIPTION |
| Helper function for Use buffer in the input pin |
| |
| PARAMETERS |
| None. |
| |
| RETURN VALUE |
| true/false |
| |
| ========================================================================== */ |
| OMX_ERRORTYPE omx_video::use_input_buffer( |
| OMX_IN OMX_HANDLETYPE hComp, |
| OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, |
| OMX_IN OMX_U32 port, |
| OMX_IN OMX_PTR appData, |
| OMX_IN OMX_U32 bytes, |
| OMX_IN OMX_U8* buffer) |
| { |
| (void) hComp; |
| OMX_ERRORTYPE eRet = OMX_ErrorNone; |
| |
| unsigned i = 0; |
| unsigned char *buf_addr = NULL; |
| |
| DEBUG_PRINT_HIGH("use_input_buffer: port = %u appData = %p bytes = %u buffer = %p",(unsigned int)port,appData,(unsigned int)bytes,buffer); |
| if (bytes != m_sInPortDef.nBufferSize) { |
| DEBUG_PRINT_ERROR("ERROR: use_input_buffer: Size Mismatch!! " |
| "bytes[%u] != Port.nBufferSize[%u]", (unsigned int)bytes, (unsigned int)m_sInPortDef.nBufferSize); |
| return OMX_ErrorBadParameter; |
| } |
| |
| if (!m_inp_mem_ptr) { |
| input_use_buffer = true; |
| m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \ |
| calloc( (sizeof(OMX_BUFFERHEADERTYPE)), m_sInPortDef.nBufferCountActual); |
| if (m_inp_mem_ptr == NULL) { |
| DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_inp_mem_ptr"); |
| return OMX_ErrorInsufficientResources; |
| } |
| DEBUG_PRINT_LOW("Successfully allocated m_inp_mem_ptr = %p", m_inp_mem_ptr); |
| |
| |
| m_pInput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sInPortDef.nBufferCountActual); |
| if (m_pInput_pmem == NULL) { |
| DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_pInput_pmem"); |
| return OMX_ErrorInsufficientResources; |
| } |
| #ifdef USE_ION |
| m_pInput_ion = (struct venc_ion *) calloc(sizeof (struct venc_ion), m_sInPortDef.nBufferCountActual); |
| if (m_pInput_ion == NULL) { |
| DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_pInput_ion"); |
| return OMX_ErrorInsufficientResources; |
| } |
| #endif |
| |
| for (i=0; i< m_sInPortDef.nBufferCountActual; i++) { |
| m_pInput_pmem[i].fd = -1; |
| #ifdef USE_ION |
| m_pInput_ion[i].ion_device_fd =-1; |
| m_pInput_ion[i].fd_ion_data.fd =-1; |
| m_pInput_ion[i].ion_alloc_data.handle = 0; |
| #endif |
| } |
| |
| } |
| |
| for (i=0; i< m_sInPortDef.nBufferCountActual; i++) { |
| if (BITMASK_ABSENT(&m_inp_bm_count,i)) { |
| break; |
| } |
| } |
| |
| if (i < m_sInPortDef.nBufferCountActual) { |
| |
| *bufferHdr = (m_inp_mem_ptr + i); |
| BITMASK_SET(&m_inp_bm_count,i); |
| |
| (*bufferHdr)->pBuffer = (OMX_U8 *)buffer; |
| (*bufferHdr)->nSize = sizeof(OMX_BUFFERHEADERTYPE); |
| (*bufferHdr)->nVersion.nVersion = OMX_SPEC_VERSION; |
| (*bufferHdr)->nAllocLen = m_sInPortDef.nBufferSize; |
| (*bufferHdr)->pAppPrivate = appData; |
| (*bufferHdr)->nInputPortIndex = PORT_INDEX_IN; |
| |
| if (!m_use_input_pmem) { |
| #ifdef USE_ION |
| #ifdef _MSM8974_ |
| m_pInput_ion[i].ion_device_fd = alloc_map_ion_memory(m_sInPortDef.nBufferSize, |
| &m_pInput_ion[i].ion_alloc_data, |
| &m_pInput_ion[i].fd_ion_data,0); |
| #else |
| m_pInput_ion[i].ion_device_fd = alloc_map_ion_memory(m_sInPortDef.nBufferSize, |
| &m_pInput_ion[i].ion_alloc_data, |
| &m_pInput_ion[i].fd_ion_data,ION_FLAG_CACHED); |
| #endif |
| if (m_pInput_ion[i].ion_device_fd < 0) { |
| DEBUG_PRINT_ERROR("ERROR:ION device open() Failed"); |
| return OMX_ErrorInsufficientResources; |
| } |
| m_pInput_pmem[i].fd = m_pInput_ion[i].fd_ion_data.fd; |
| #else |
| m_pInput_pmem[i].fd = open (MEM_DEVICE,O_RDWR); |
| if (m_pInput_pmem[i].fd == 0) { |
| m_pInput_pmem[i].fd = open (MEM_DEVICE,O_RDWR); |
| } |
| |
| if (m_pInput_pmem[i] .fd < 0) { |
| DEBUG_PRINT_ERROR("ERROR: /dev/pmem_adsp open() Failed"); |
| return OMX_ErrorInsufficientResources; |
| } |
| #endif |
| m_pInput_pmem[i].size = m_sInPortDef.nBufferSize; |
| m_pInput_pmem[i].offset = 0; |
| |
| m_pInput_pmem[i].buffer = (OMX_U8 *)SECURE_BUFPTR; |
| if(!secure_session) { |
| m_pInput_pmem[i].buffer = (unsigned char *)mmap( |
| NULL,m_pInput_pmem[i].size,PROT_READ|PROT_WRITE, |
| MAP_SHARED,m_pInput_pmem[i].fd,0); |
| |
| if (m_pInput_pmem[i].buffer == MAP_FAILED) { |
| DEBUG_PRINT_ERROR("ERROR: mmap() Failed"); |
| close(m_pInput_pmem[i].fd); |
| #ifdef USE_ION |
| free_ion_memory(&m_pInput_ion[i]); |
| #endif |
| return OMX_ErrorInsufficientResources; |
| } |
| } |
| |
| } else { |
| OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pParam = reinterpret_cast<OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *>((*bufferHdr)->pAppPrivate); |
| DEBUG_PRINT_LOW("Inside qcom_ext with luma:(fd:%lu,offset:0x%x)", pParam->pmem_fd, (unsigned)pParam->offset); |
| |
| if (pParam) { |
| m_pInput_pmem[i].fd = pParam->pmem_fd; |
| m_pInput_pmem[i].offset = pParam->offset; |
| m_pInput_pmem[i].size = m_sInPortDef.nBufferSize; |
| m_pInput_pmem[i].buffer = (unsigned char *)buffer; |
| DEBUG_PRINT_LOW("DBG:: pParam->pmem_fd = %u, pParam->offset = %u", |
| (unsigned int)pParam->pmem_fd, (unsigned int)pParam->offset); |
| } else { |
| DEBUG_PRINT_ERROR("ERROR: Invalid AppData given for PMEM i/p UseBuffer case"); |
| return OMX_ErrorBadParameter; |
| } |
| } |
| |
| DEBUG_PRINT_LOW("use_inp:: bufhdr = %p, pBuffer = %p, m_pInput_pmem[i].buffer = %p", |
| (*bufferHdr), (*bufferHdr)->pBuffer, m_pInput_pmem[i].buffer); |
| if ( dev_use_buf(&m_pInput_pmem[i],PORT_INDEX_IN,i) != true) { |
| DEBUG_PRINT_ERROR("ERROR: dev_use_buf() Failed for i/p buf"); |
| return OMX_ErrorInsufficientResources; |
| } |
| } else { |
| DEBUG_PRINT_ERROR("ERROR: All buffers are already used, invalid use_buf call for " |
| "index = %u", i); |
| eRet = OMX_ErrorInsufficientResources; |
| } |
| |
| return eRet; |
| } |
| |
| |
| |
| /* ====================================================================== |
| FUNCTION |
| omx_video::UseOutputBuffer |
| |
| DESCRIPTION |
| Helper function for Use buffer in the input pin |
| |
| PARAMETERS |
| None. |
| |
| RETURN VALUE |
| true/false |
| |
| ========================================================================== */ |
| OMX_ERRORTYPE omx_video::use_output_buffer( |
| OMX_IN OMX_HANDLETYPE hComp, |
| OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, |
| OMX_IN OMX_U32 port, |
| OMX_IN OMX_PTR appData, |
| OMX_IN OMX_U32 bytes, |
| OMX_IN OMX_U8* buffer) |
| { |
| (void)hComp, (void)port; |
| OMX_ERRORTYPE eRet = OMX_ErrorNone; |
| OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header |
| unsigned i= 0; // Temporary counter |
| unsigned char *buf_addr = NULL; |
| #ifdef _MSM8974_ |
| int align_size; |
| #endif |
| |
| DEBUG_PRINT_HIGH("Inside use_output_buffer()"); |
| if (bytes != m_sOutPortDef.nBufferSize) { |
| DEBUG_PRINT_ERROR("ERROR: use_output_buffer: Size Mismatch!! " |
| "bytes[%u] != Port.nBufferSize[%u]", (unsigned int)bytes, (unsigned int)m_sOutPortDef.nBufferSize); |
| return OMX_ErrorBadParameter; |
| } |
| |
| if (!m_out_mem_ptr) { |
| output_use_buffer = true; |
| int nBufHdrSize = 0; |
| |
| DEBUG_PRINT_LOW("Allocating First Output Buffer(%u)",(unsigned int)m_sOutPortDef.nBufferCountActual); |
| nBufHdrSize = m_sOutPortDef.nBufferCountActual * sizeof(OMX_BUFFERHEADERTYPE); |
| /* |
| * Memory for output side involves the following: |
| * 1. Array of Buffer Headers |
| * 2. Bitmask array to hold the buffer allocation details |
| * In order to minimize the memory management entire allocation |
| * is done in one step. |
| */ |
| //OMX Buffer header |
| m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1); |
| if (m_out_mem_ptr == NULL) { |
| DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_out_mem_ptr"); |
| return OMX_ErrorInsufficientResources; |
| } |
| |
| m_pOutput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sOutPortDef.nBufferCountActual); |
| if (m_pOutput_pmem == NULL) { |
| DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_pOutput_pmem"); |
| return OMX_ErrorInsufficientResources; |
| } |
| #ifdef USE_ION |
| m_pOutput_ion = (struct venc_ion *) calloc(sizeof (struct venc_ion), m_sOutPortDef.nBufferCountActual); |
| if (m_pOutput_ion == NULL) { |
| DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_pOutput_ion"); |
| return OMX_ErrorInsufficientResources; |
| } |
| #endif |
| if (m_out_mem_ptr) { |
| bufHdr = m_out_mem_ptr; |
| DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr); |
| // Settting the entire storage nicely |
| for (i=0; i < m_sOutPortDef.nBufferCountActual ; i++) { |
| bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE); |
| bufHdr->nVersion.nVersion = OMX_SPEC_VERSION; |
| bufHdr->nAllocLen = bytes; |
| bufHdr->nFilledLen = 0; |
| bufHdr->pAppPrivate = appData; |
| bufHdr->nOutputPortIndex = PORT_INDEX_OUT; |
| bufHdr->pBuffer = NULL; |
| bufHdr++; |
| m_pOutput_pmem[i].fd = -1; |
| #ifdef USE_ION |
| m_pOutput_ion[i].ion_device_fd =-1; |
| m_pOutput_ion[i].fd_ion_data.fd=-1; |
| m_pOutput_ion[i].ion_alloc_data.handle = 0; |
| #endif |
| } |
| } else { |
| DEBUG_PRINT_ERROR("ERROR: Output buf mem alloc failed[0x%p]",m_out_mem_ptr); |
| eRet = OMX_ErrorInsufficientResources; |
| } |
| } |
| |
| for (i=0; i< m_sOutPortDef.nBufferCountActual; i++) { |
| if (BITMASK_ABSENT(&m_out_bm_count,i)) { |
| break; |
| } |
| } |
| |
| if (eRet == OMX_ErrorNone) { |
| if (i < m_sOutPortDef.nBufferCountActual) { |
| *bufferHdr = (m_out_mem_ptr + i ); |
| (*bufferHdr)->pBuffer = (OMX_U8 *)buffer; |
| (*bufferHdr)->pAppPrivate = appData; |
| |
| if (!m_use_output_pmem) { |
| #ifdef USE_ION |
| #ifdef _MSM8974_ |
| align_size = (m_sOutPortDef.nBufferSize + (SZ_4K - 1)) & ~(SZ_4K - 1); |
| m_pOutput_ion[i].ion_device_fd = alloc_map_ion_memory(align_size, |
| &m_pOutput_ion[i].ion_alloc_data, |
| &m_pOutput_ion[i].fd_ion_data,0); |
| #else |
| m_pOutput_ion[i].ion_device_fd = alloc_map_ion_memory( |
| m_sOutPortDef.nBufferSize, |
| &m_pOutput_ion[i].ion_alloc_data, |
| &m_pOutput_ion[i].fd_ion_data,ION_FLAG_CACHED); |
| #endif |
| if (m_pOutput_ion[i].ion_device_fd < 0) { |
| DEBUG_PRINT_ERROR("ERROR:ION device open() Failed"); |
| return OMX_ErrorInsufficientResources; |
| } |
| m_pOutput_pmem[i].fd = m_pOutput_ion[i].fd_ion_data.fd; |
| #else |
| m_pOutput_pmem[i].fd = open (MEM_DEVICE,O_RDWR); |
| |
| if (m_pOutput_pmem[i].fd == 0) { |
| m_pOutput_pmem[i].fd = open (MEM_DEVICE,O_RDWR); |
| } |
| |
| if (m_pOutput_pmem[i].fd < 0) { |
| DEBUG_PRINT_ERROR("ERROR: /dev/pmem_adsp open() Failed"); |
| return OMX_ErrorInsufficientResources; |
| } |
| #endif |
| m_pOutput_pmem[i].size = m_sOutPortDef.nBufferSize; |
| m_pOutput_pmem[i].offset = 0; |
| |
| m_pOutput_pmem[i].buffer = (OMX_U8 *)SECURE_BUFPTR; |
| if(!secure_session) { |
| #ifdef _MSM8974_ |
| m_pOutput_pmem[i].buffer = (unsigned char *)mmap(NULL, |
| align_size,PROT_READ|PROT_WRITE, |
| MAP_SHARED,m_pOutput_pmem[i].fd,0); |
| #else |
| m_pOutput_pmem[i].buffer = (unsigned char *)mmap(NULL, |
| m_pOutput_pmem[i].size,PROT_READ|PROT_WRITE, |
| MAP_SHARED,m_pOutput_pmem[i].fd,0); |
| #endif |
| if (m_pOutput_pmem[i].buffer == MAP_FAILED) { |
| DEBUG_PRINT_ERROR("ERROR: mmap() Failed"); |
| close(m_pOutput_pmem[i].fd); |
| #ifdef USE_ION |
| free_ion_memory(&m_pOutput_ion[i]); |
| #endif |
| return OMX_ErrorInsufficientResources; |
| } |
| } |
| } else { |
| OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pParam = reinterpret_cast<OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO*>((*bufferHdr)->pAppPrivate); |
| DEBUG_PRINT_LOW("Inside qcom_ext pParam: %p", pParam); |
| |
| if (pParam) { |
| DEBUG_PRINT_LOW("Inside qcom_ext with luma:(fd:%lu,offset:0x%x)", pParam->pmem_fd, (int)pParam->offset); |
| m_pOutput_pmem[i].fd = pParam->pmem_fd; |
| m_pOutput_pmem[i].offset = pParam->offset; |
| m_pOutput_pmem[i].size = m_sOutPortDef.nBufferSize; |
| m_pOutput_pmem[i].buffer = (unsigned char *)buffer; |
| } else { |
| DEBUG_PRINT_ERROR("ERROR: Invalid AppData given for PMEM o/p UseBuffer case"); |
| return OMX_ErrorBadParameter; |
| } |
| buf_addr = (unsigned char *)buffer; |
| } |
| |
| DEBUG_PRINT_LOW("use_out:: bufhdr = %p, pBuffer = %p, m_pOutput_pmem[i].buffer = %p", |
| (*bufferHdr), (*bufferHdr)->pBuffer, m_pOutput_pmem[i].buffer); |
| if (dev_use_buf(&m_pOutput_pmem[i],PORT_INDEX_OUT,i) != true) { |
| DEBUG_PRINT_ERROR("ERROR: dev_use_buf Failed for o/p buf"); |
| return OMX_ErrorInsufficientResources; |
| } |
| |
| BITMASK_SET(&m_out_bm_count,i); |
| } else { |
| DEBUG_PRINT_ERROR("ERROR: All o/p Buffers have been Used, invalid use_buf call for " |
| "index = %u", i); |
| eRet = OMX_ErrorInsufficientResources; |
| } |
| } |
| return eRet; |
| } |
| |
| |
| /* ====================================================================== |
| FUNCTION |
| omx_video::UseBuffer |
| |
| DESCRIPTION |
| OMX Use Buffer method implementation. |
| |
| PARAMETERS |
| <TBD>. |
| |
| RETURN VALUE |
| OMX Error None , if everything successful. |
| |
| ========================================================================== */ |
| OMX_ERRORTYPE omx_video::use_buffer( |
| OMX_IN OMX_HANDLETYPE hComp, |
| OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, |
| OMX_IN OMX_U32 port, |
| OMX_IN OMX_PTR appData, |
| OMX_IN OMX_U32 bytes, |
| OMX_IN OMX_U8* buffer) |
| { |
| OMX_ERRORTYPE eRet = OMX_ErrorNone; |
| if (m_state == OMX_StateInvalid) { |
| DEBUG_PRINT_ERROR("ERROR: Use Buffer in Invalid State"); |
| return OMX_ErrorInvalidState; |
| } |
| if (port == PORT_INDEX_IN) { |
| eRet = use_input_buffer(hComp,bufferHdr,port,appData,bytes,buffer); |
| } else if (port == PORT_INDEX_OUT) { |
| eRet = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); |
| } else { |
| DEBUG_PRINT_ERROR("ERROR: Invalid Port Index received %d",(int)port); |
| eRet = OMX_ErrorBadPortIndex; |
| } |
| |
| if (eRet == OMX_ErrorNone) { |
| if (allocate_done()) { |
| if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) { |
| // Send the callback now |
| BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING); |
| post_event(OMX_CommandStateSet,OMX_StateIdle, |
| OMX_COMPONENT_GENERATE_EVENT); |
| } |
| } |
| if (port == PORT_INDEX_IN && m_sInPortDef.bPopulated) { |
| if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) { |
| BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING); |
| post_event(OMX_CommandPortEnable, |
| PORT_INDEX_IN, |
| OMX_COMPONENT_GENERATE_EVENT); |
| } |
| |
| } else if (port == PORT_INDEX_OUT && m_sOutPortDef.bPopulated) { |
| if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) { |
| BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING); |
| post_event(OMX_CommandPortEnable, |
| PORT_INDEX_OUT, |
| OMX_COMPONENT_GENERATE_EVENT); |
| m_event_port_settings_sent = false; |
| } |
| } |
| } |
| return eRet; |
| } |
| |
| OMX_ERRORTYPE omx_video::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr) |
| { |
| unsigned int index = 0; |
| OMX_U8 *temp_buff ; |
| |
| if (bufferHdr == NULL || m_inp_mem_ptr == NULL) { |
| DEBUG_PRINT_ERROR("ERROR: free_input: Invalid bufferHdr[%p] or m_inp_mem_ptr[%p]", |
| bufferHdr, m_inp_mem_ptr); |
| return OMX_ErrorBadParameter; |
| } |
| |
| index = bufferHdr - ((!meta_mode_enable)?m_inp_mem_ptr:meta_buffer_hdr); |
| #ifdef _ANDROID_ICS_ |
| if (meta_mode_enable) { |
| if (index < m_sInPortDef.nBufferCountActual) { |
| memset(&meta_buffer_hdr[index], 0, sizeof(meta_buffer_hdr[index])); |
| memset(&meta_buffers[index], 0, sizeof(meta_buffers[index])); |
| } |
| if (!mUseProxyColorFormat) |
| return OMX_ErrorNone; |
| else { |
| c2d_conv.close(); |
| opaque_buffer_hdr[index] = NULL; |
| } |
| } |
| #endif |
| if (index < m_sInPortDef.nBufferCountActual && !mUseProxyColorFormat && |
| dev_free_buf(&m_pInput_pmem[index],PORT_INDEX_IN) != true) { |
| DEBUG_PRINT_LOW("ERROR: dev_free_buf() Failed for i/p buf"); |
| } |
| |
| if (index < m_sInPortDef.nBufferCountActual && m_pInput_pmem) { |
| if (m_pInput_pmem[index].fd > 0 && input_use_buffer == false) { |
| DEBUG_PRINT_LOW("FreeBuffer:: i/p AllocateBuffer case"); |
| if(!secure_session) { |
| munmap (m_pInput_pmem[index].buffer,m_pInput_pmem[index].size); |
| } else { |
| free(m_pInput_pmem[index].buffer); |
| } |
| close (m_pInput_pmem[index].fd); |
| #ifdef USE_ION |
| free_ion_memory(&m_pInput_ion[index]); |
| #endif |
| m_pInput_pmem[index].fd = -1; |
| } else if (m_pInput_pmem[index].fd > 0 && (input_use_buffer == true && |
| m_use_input_pmem == OMX_FALSE)) { |
| DEBUG_PRINT_LOW("FreeBuffer:: i/p Heap UseBuffer case"); |
| if (dev_free_buf(&m_pInput_pmem[index],PORT_INDEX_IN) != true) { |
| DEBUG_PRINT_ERROR("ERROR: dev_free_buf() Failed for i/p buf"); |
| } |
| if(!secure_session) { |
| munmap (m_pInput_pmem[index].buffer,m_pInput_pmem[index].size); |
| } |
| close (m_pInput_pmem[index].fd); |
| #ifdef USE_ION |
| free_ion_memory(&m_pInput_ion[index]); |
| #endif |
| m_pInput_pmem[index].fd = -1; |
| } else { |
| DEBUG_PRINT_ERROR("FreeBuffer:: fd is invalid or i/p PMEM UseBuffer case"); |
| } |
| } |
| return OMX_ErrorNone; |
| } |
| |
| OMX_ERRORTYPE omx_video::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr) |
| { |
| unsigned int index = 0; |
| OMX_U8 *temp_buff ; |
| |
| if (bufferHdr == NULL || m_out_mem_ptr == NULL) { |
| DEBUG_PRINT_ERROR("ERROR: free_output: Invalid bufferHdr[%p] or m_out_mem_ptr[%p]", |
| bufferHdr, m_out_mem_ptr); |
| return OMX_ErrorBadParameter; |
| } |
| index = bufferHdr - m_out_mem_ptr; |
| |
| if (index < m_sOutPortDef.nBufferCountActual && |
| dev_free_buf(&m_pOutput_pmem[index],PORT_INDEX_OUT) != true) { |
| DEBUG_PRINT_ERROR("ERROR: dev_free_buf Failed for o/p buf"); |
| } |
| |
| if (index < m_sOutPortDef.nBufferCountActual && m_pOutput_pmem) { |
| if (m_pOutput_pmem[index].fd > 0 && output_use_buffer == false ) { |
| DEBUG_PRINT_LOW("FreeBuffer:: o/p AllocateBuffer case"); |
| if(!secure_session) { |
| munmap (m_pOutput_pmem[index].buffer, |
| m_pOutput_pmem[index].size); |
| } else { |
| char *data = (char*) m_pOutput_pmem[index].buffer; |
| native_handle_t *handle = NULL; |
| memcpy(&handle, data + sizeof(OMX_U32), sizeof(native_handle_t*)); |
| native_handle_delete(handle); |
| free(m_pOutput_pmem[index].buffer); |
| } |
| close (m_pOutput_pmem[index].fd); |
| #ifdef USE_ION |
| free_ion_memory(&m_pOutput_ion[index]); |
| #endif |
| m_pOutput_pmem[index].fd = -1; |
| } else if ( m_pOutput_pmem[index].fd > 0 && (output_use_buffer == true |
| && m_use_output_pmem == OMX_FALSE)) { |
| DEBUG_PRINT_LOW("FreeBuffer:: o/p Heap UseBuffer case"); |
| if (dev_free_buf(&m_pOutput_pmem[index],PORT_INDEX_OUT) != true) { |
| DEBUG_PRINT_ERROR("ERROR: dev_free_buf Failed for o/p buf"); |
| } |
| if(!secure_session) { |
| munmap (m_pOutput_pmem[index].buffer, |
| m_pOutput_pmem[index].size); |
| } |
| close (m_pOutput_pmem[index].fd); |
| #ifdef USE_ION |
| free_ion_memory(&m_pOutput_ion[index]); |
| #endif |
| m_pOutput_pmem[index].fd = -1; |
| } else { |
| DEBUG_PRINT_LOW("FreeBuffer:: fd is invalid or o/p PMEM UseBuffer case"); |
| } |
| } |
| return OMX_ErrorNone; |
| } |
| #ifdef _ANDROID_ICS_ |
| OMX_ERRORTYPE omx_video::allocate_input_meta_buffer( |
| OMX_HANDLETYPE hComp, |
| OMX_BUFFERHEADERTYPE **bufferHdr, |
| OMX_PTR appData, |
| OMX_U32 bytes) |
| { |
| unsigned index = 0; |
| if (!bufferHdr
|