| /*-------------------------------------------------------------------------- |
| Copyright (c) 2010-2018, 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> |
| #include <sys/ioctl.h> |
| #ifdef _ANDROID_ICS_ |
| #include <media/hardware/HardwareAPI.h> |
| #include <gralloc_priv.h> |
| #endif |
| #ifdef _USE_GLIB_ |
| #include <glib.h> |
| #define strlcpy g_strlcpy |
| #endif |
| #define H264_SUPPORTED_WIDTH (480) |
| #define H264_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 |
| #undef ALIGN |
| #define ALIGN(x, to_align) ((((unsigned long) x) + (to_align - 1)) & ~(to_align - 1)) |
| |
| #ifndef ION_FLAG_CP_BITSTREAM |
| #define ION_FLAG_CP_BITSTREAM 0 |
| #endif |
| |
| #ifndef ION_FLAG_CP_PIXEL |
| #define ION_FLAG_CP_PIXEL 0 |
| #endif |
| |
| #undef MEM_HEAP_ID |
| |
| #ifdef MASTER_SIDE_CP |
| |
| #define MEM_HEAP_ID ION_SECURE_HEAP_ID |
| #define SECURE_ALIGN SZ_4K |
| #define SECURE_FLAGS_INPUT_BUFFER (ION_SECURE | ION_FLAG_CP_PIXEL) |
| #define SECURE_FLAGS_OUTPUT_BUFFER (ION_SECURE | ION_FLAG_CP_BITSTREAM) |
| |
| #else //SLAVE_SIDE_CP |
| |
| #define MEM_HEAP_ID ION_CP_MM_HEAP_ID |
| #define SECURE_ALIGN SZ_1M |
| #define SECURE_FLAGS_INPUT_BUFFER ION_SECURE |
| #define SECURE_FLAGS_OUTPUT_BUFFER ION_SECURE |
| |
| #endif |
| |
| // Gralloc flag to indicate UBWC |
| #define GRALLOC1_CONSUMER_USAGE_UBWC_FLAG GRALLOC1_CONSUMER_USAGE_PRIVATE_0 |
| |
| 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_enc(void *input) |
| { |
| omx_video* omx = reinterpret_cast<omx_video*>(input); |
| int ret; |
| |
| DEBUG_PRINT_HIGH("omx_venc: message thread start"); |
| prctl(PR_SET_NAME, (unsigned long)"VideoEncMsgThread", 0, 0, 0); |
| while (!omx->msg_thread_stop) { |
| ret = omx->signal.wait(2 * 1000000000); |
| if (ret == ETIMEDOUT || omx->msg_thread_stop) { |
| continue; |
| } else if (ret) { |
| DEBUG_PRINT_ERROR("omx_venc: message_thread_enc wait on condition failed, exiting"); |
| break; |
| } |
| omx->process_event_cb(omx); |
| } |
| DEBUG_PRINT_HIGH("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); |
| omx->signal.signal(); |
| } |
| |
| // 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; |
| } |
| |
| |
| /* ====================================================================== |
| 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), |
| mUsesColorConversion(false), |
| mC2dSrcFmt(NO_COLOR_FORMAT), |
| mC2dDestFmt(NO_COLOR_FORMAT), |
| mC2DFrameHeight(0), |
| mC2DFrameWidth(0), |
| 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_sExtraData(0), |
| m_sParamConsumerUsage(0), |
| m_input_msg_id(OMX_COMPONENT_GENERATE_ETB), |
| m_inp_mem_ptr(NULL), |
| m_out_mem_ptr(NULL), |
| m_client_output_extradata_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), |
| allocate_native_handle(false), |
| m_out_bm_count(0), |
| m_client_out_bm_count(0), |
| m_client_in_bm_count(0), |
| m_inp_bm_count(0), |
| m_out_extradata_bm_count(0), |
| m_flags(0), |
| m_etb_count(0), |
| m_fbd_count(0), |
| m_event_port_settings_sent(false), |
| hw_overload(false), |
| m_graphicbuffer_size(0), |
| m_buffer_freed(0) |
| { |
| 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; |
| msg_thread_stop = false; |
| |
| OMX_INIT_STRUCT(&m_blurInfo, OMX_QTI_VIDEO_CONFIG_BLURINFO); |
| m_blurInfo.nPortIndex == (OMX_U32)PORT_INDEX_IN; |
| |
| mMapPixelFormat2Converter.insert({ |
| {HAL_PIXEL_FORMAT_RGBA_8888, RGBA8888}, |
| }); |
| |
| pthread_mutex_init(&m_lock, NULL); |
| pthread_mutex_init(&m_TimeStampInfo.m_lock, NULL); |
| m_TimeStampInfo.deferred_inbufq.m_size=0; |
| m_TimeStampInfo.deferred_inbufq.m_read = m_TimeStampInfo.deferred_inbufq.m_write = 0; |
| sem_init(&m_cmd_lock,0,0); |
| DEBUG_PRINT_LOW("meta_buffer_hdr = %p", meta_buffer_hdr); |
| |
| memset(m_platform, 0, sizeof(m_platform)); |
| #ifdef _ANDROID_ |
| char platform_name[PROPERTY_VALUE_MAX] = {0}; |
| property_get("ro.board.platform", platform_name, "0"); |
| strlcpy(m_platform, platform_name, sizeof(m_platform)); |
| #endif |
| |
| pthread_mutex_init(&m_buf_lock, NULL); |
| } |
| |
| |
| /* ====================================================================== |
| FUNCTION |
| omx_venc::~omx_venc |
| |
| DESCRIPTION |
| Destructor |
| |
| PARAMETERS |
| None |
| |
| RETURN VALUE |
| None. |
| ========================================================================== */ |
| omx_video::~omx_video() |
| { |
| DEBUG_PRINT_HIGH("~omx_video(): Inside Destructor()"); |
| if (msg_thread_created) { |
| msg_thread_stop = true; |
| post_message(this, OMX_COMPONENT_CLOSE_MSG); |
| DEBUG_PRINT_HIGH("omx_video: Waiting on Msg Thread exit"); |
| 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*/ |
| pthread_mutex_destroy(&m_lock); |
| pthread_mutex_destroy(&m_TimeStampInfo.m_lock); |
| sem_destroy(&m_cmd_lock); |
| DEBUG_PRINT_HIGH("m_etb_count = %" PRIu64 ", m_fbd_count = %" PRIu64, m_etb_count, |
| m_fbd_count); |
| |
| pthread_mutex_destroy(&m_buf_lock); |
| 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 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) { |
| switch (ident) { |
| 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); |
| if (pThis->m_state == OMX_StateLoaded) { |
| m_buffer_freed = false; |
| } |
| 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; |
| case OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING: |
| DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING"); |
| pThis->omx_report_unsupported_setting(); |
| break; |
| |
| case OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD: |
| DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD"); |
| pThis->omx_report_hw_overload(); |
| break; |
| |
| default: |
| DEBUG_PRINT_LOW("process_event_cb unknown msg id 0x%02x", (unsigned int)ident); |
| 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); |
| /* 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(); |
| 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++; |
| VIDC_TRACE_INT_LOW("FTB-pending", 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++; |
| VIDC_TRACE_INT_LOW("ETB-pending", 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); |
| } |
| } |
| while (m_TimeStampInfo.deferred_inbufq.m_size) { |
| m_TimeStampInfo.deferred_inbufq.pop_entry(&p1,&p2,&ident); |
| m_pCallbacks.EmptyBufferDone(&m_cmp,m_app_data,(OMX_BUFFERHEADERTYPE *)p1); |
| } |
| 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 |
| ==========================================================================*/ |
| 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++; |
| VIDC_TRACE_INT_LOW("ETB-pending", 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); |
| } |
| } |
| |
| while (m_TimeStampInfo.deferred_inbufq.m_size) { |
| m_TimeStampInfo.deferred_inbufq.pop_entry(&p1,&p2,&ident); |
| m_pCallbacks.EmptyBufferDone(&m_cmp,m_app_data,(OMX_BUFFERHEADERTYPE *)p1); |
| } |
| |
| 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++; |
| VIDC_TRACE_INT_LOW("FTB-pending", 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; |
| } |
| |
| /* ====================================================================== |
| 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; |
| } |
| |
| bool omx_video::reject_param_for_TME_mode(int index) { |
| int allowed_params[] = { |
| OMX_IndexParamPortDefinition, |
| OMX_IndexParamVideoPortFormat, |
| OMX_IndexParamVideoInit, |
| OMX_IndexParamAudioInit, |
| OMX_IndexParamImageInit, |
| OMX_IndexParamOtherInit, |
| OMX_IndexParamStandardComponentRole, |
| OMX_IndexParamPriorityMgmt, |
| OMX_IndexParamCompBufferSupplier, |
| OMX_GoogleAndroidIndexAllocateNativeHandle, |
| OMX_QcomIndexPortDefn, |
| OMX_QcomIndexParamVideoMetaBufferMode, |
| OMX_QTIIndexParamLowLatencyMode, |
| OMX_IndexParamVideoTme, |
| OMX_IndexParamVideoProfileLevelQuerySupported, |
| OMX_IndexParamConsumerUsageBits |
| }; |
| |
| if (m_sOutPortFormat.eCompressionFormat != (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingTME) { |
| return false; |
| } |
| |
| for (unsigned i = 0; i < (sizeof(allowed_params) / sizeof(int)); i++) { |
| if (index == allowed_params[i]) { |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| bool omx_video::reject_config_for_TME_mode(int index) { |
| int allowed_configs[] = { |
| OMX_IndexConfigVideoFramerate, |
| OMX_IndexConfigPriority, |
| OMX_IndexConfigOperatingRate, |
| OMX_IndexConfigTimePosition, |
| OMX_QcomIndexConfigPerfLevel, |
| OMX_QTIIndexConfigDescribeColorAspects, |
| OMX_IndexConfigAndroidVendorExtension |
| }; |
| |
| if (m_sOutPortFormat.eCompressionFormat != (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingTME) { |
| return false; |
| } |
| |
| for (unsigned i = 0; i < (sizeof(allowed_configs) / sizeof(int)); i++) { |
| if (index == allowed_configs[i]) { |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| /* ====================================================================== |
| 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; |
| |
| 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; |
| } |
| |
| if (reject_param_for_TME_mode(paramIndex)) { |
| DEBUG_PRINT_ERROR("ERROR: Set Parameter 0x%x rejected in TME mode", (int)paramIndex); |
| return OMX_ErrorNone; |
| } |
| |
| 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: port %d", portDefn->nPortIndex); |
| if (portDefn->nPortIndex == (OMX_U32) PORT_INDEX_IN) { |
| dev_get_buf_req (&m_sInPortDef.nBufferCountMin, |
| &m_sInPortDef.nBufferCountActual, |
| &m_sInPortDef.nBufferSize, |
| m_sInPortDef.nPortIndex); |
| |
| memcpy(portDefn, &m_sInPortDef, sizeof(m_sInPortDef)); |
| #ifdef _ANDROID_ICS_ |
| if (meta_mode_enable) { |
| // request size of largest metadata (happens to be NativeHandleSource) since |
| // we do not know the exact metadata-type yet |
| portDefn->nBufferSize = sizeof(LEGACY_CAM_METADATA_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); |
| dev_get_dimensions(m_sOutPortDef.nPortIndex, |
| &m_sOutPortDef.format.video.nFrameWidth, |
| &m_sOutPortDef.format.video.nFrameHeight); |
| } |
| |
| memcpy(portDefn, &m_sOutPortDef, sizeof(m_sOutPortDef)); |
| // Tiling in HW expects output port def to be aligned to tile size |
| // At the same time, FWK needs original WxH for various purposes |
| // Sending input WxH as output port def WxH to FWK |
| if (m_sOutPortDef.format.video.eCompressionFormat == |
| OMX_VIDEO_CodingHEIC) { |
| portDefn->format.video.nFrameWidth = |
| m_sInPortDef.format.video.nFrameWidth; |
| portDefn->format.video.nFrameHeight = |
| m_sInPortDef.format.video.nFrameHeight; |
| } |
| |
| if (secure_session || allocate_native_handle) { |
| portDefn->nBufferSize = |
| sizeof(native_handle_t) + (sizeof(int) * (1/*numFds*/ + 3/*numInts*/)); |
| } |
| } else if (portDefn->nPortIndex == (OMX_U32) PORT_INDEX_EXTRADATA_OUT) { |
| portDefn->nBufferSize = m_client_out_extradata_info.getSize(); |
| portDefn->nBufferCountMin= m_sOutPortDef.nBufferCountMin; |
| portDefn->nBufferCountActual = m_client_out_extradata_info.getBufferCount(); |
| portDefn->eDir = OMX_DirOutput; |
| DEBUG_PRINT_LOW("extradata port: size = %u, min cnt = %u, actual cnt = %u", |
| (unsigned int)portDefn->nBufferSize, (unsigned int)portDefn->nBufferCountMin, |
| (unsigned int)portDefn->nBufferCountActual); |
| } else { |
| DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index"); |
| eRet = OMX_ErrorBadPortIndex; |
| } |
| |
| DEBUG_PRINT_HIGH("get_parameter: OMX_IndexParamPortDefinition: port %d, wxh %dx%d, min %d, actual %d, size %d, colorformat %#x, compression format %#x", |
| portDefn->nPortIndex, portDefn->format.video.nFrameWidth, |
| portDefn->format.video.nFrameHeight, portDefn->nBufferCountMin, |
| portDefn->nBufferCountActual, portDefn->nBufferSize, |
| portDefn->format.video.eColorFormat, portDefn->format.video.eCompressionFormat); |
| |
| 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; |
| OMX_U32 colorFormat = OMX_COLOR_FormatUnused; |
| if(dev_get_supported_color_format(index, &colorFormat)) { |
| memcpy(portFmt, &m_sInPortFormat, sizeof(m_sInPortFormat)); |
| portFmt->nIndex = index; //restore index set from client |
| portFmt->eColorFormat = (OMX_COLOR_FORMATTYPE)colorFormat; |
| } else { |
| eRet = OMX_ErrorNoMore; |
| } |
| } 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_INDEXTYPE)OMX_IndexParamVideoTme: |
| { |
| VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_PARAM_TMETYPE); |
| QOMX_VIDEO_PARAM_TMETYPE* pParam = (QOMX_VIDEO_PARAM_TMETYPE*)paramData; |
| DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoTme"); |
| memcpy(pParam, &m_sParamTME, sizeof(m_sParamTME)); |
| break; |
| } |
| case OMX_IndexParamVideoAndroidImageGrid: |
| { |
| VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_ANDROID_IMAGEGRIDTYPE); |
| OMX_VIDEO_PARAM_ANDROID_IMAGEGRIDTYPE* pParam = |
| (OMX_VIDEO_PARAM_ANDROID_IMAGEGRIDTYPE*)paramData; |
| DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAndroidImageGrid"); |
| memcpy(pParam, &m_sParamAndroidImageGrid, sizeof(m_sParamAndroidImageGrid)); |
| 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 = dev_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; |
| } |
| case OMX_QcomIndexConfigH264EntropyCodingCabac: |
| { |
| VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_H264ENTROPYCODINGTYPE); |
| QOMX_VIDEO_H264ENTROPYCODINGTYPE * pParam = (QOMX_VIDEO_H264ENTROPYCODINGTYPE*)paramData; |
| DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexConfigH264EntropyCodingCabac"); |
| memcpy(pParam, &m_sParamEntropy, sizeof(m_sParamEntropy)); |
| 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 QOMX_IndexParamVideoInitialQp: |
| { |
| VALIDATE_OMX_PARAM_DATA(paramData, QOMX_EXTNINDEX_VIDEO_INITIALQP); |
| QOMX_EXTNINDEX_VIDEO_INITIALQP *initial_qp = (QOMX_EXTNINDEX_VIDEO_INITIALQP*) paramData; |
| DEBUG_PRINT_LOW("get_parameter: QOMX_IndexParamVideoInitialQp"); |
| initial_qp->nQpI = m_sSessionQuantization.nQpI; |
| initial_qp->nQpP = m_sSessionQuantization.nQpP; |
| initial_qp->nQpB = m_sSessionQuantization.nQpB; |
| initial_qp->bEnableInitQp = m_QPSet; |
| break; |
| } |
| |
| case OMX_QcomIndexParamVideoIPBQPRange: |
| { |
| VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_VIDEO_PARAM_IPB_QPRANGETYPE); |
| OMX_QCOM_VIDEO_PARAM_IPB_QPRANGETYPE *qp_range = (OMX_QCOM_VIDEO_PARAM_IPB_QPRANGETYPE*) paramData; |
| DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamVideoIPBQPRange"); |
| 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; |
| } |
| 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 & VENC_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 & VENC_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; |
| } |
| } else if (pParam->nIndex == (OMX_INDEXTYPE)OMX_ExtraDataFrameDimension) { |
| if (pParam->nPortIndex == PORT_INDEX_IN) { |
| pParam->bEnabled = |
| (OMX_BOOL)((m_sExtraData & VENC_EXTRADATA_FRAMEDIMENSION) ? 1 : 0); |
| DEBUG_PRINT_HIGH("Frame dimension extradata %d", pParam->bEnabled); |
| } else { |
| DEBUG_PRINT_ERROR("get_parameter: frame dimension is " |
| "valid for input port only"); |
| eRet = OMX_ErrorUnsupportedIndex; |
| } |
| } else if (pParam->nIndex == (OMX_INDEXTYPE)OMX_ExtraDataVideoLTRInfo) { |
| if (pParam->nPortIndex == PORT_INDEX_OUT) { |
| pParam->bEnabled = |
| (OMX_BOOL)(m_sExtraData & VENC_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; |
| } |
| } else { |
| DEBUG_PRINT_ERROR("get_parameter: unsupported extradata index (0x%x)", |
| pParam->nPortIndex); |
| eRet = OMX_ErrorUnsupportedIndex; |
| } |
| break; |
| } |
| case OMX_QTIIndexParamVideoClientExtradata: |
| { |
| VALIDATE_OMX_PARAM_DATA(paramData, QOMX_EXTRADATA_ENABLE); |
| DEBUG_PRINT_LOW("get_parameter: OMX_QTIIndexParamVideoClientExtradata"); |
| QOMX_EXTRADATA_ENABLE *pParam = |
| (QOMX_EXTRADATA_ENABLE *)paramData; |
| if (pParam->nPortIndex == PORT_INDEX_EXTRADATA_OUT) { |
| OMX_U32 output_extradata_mask = VENC_EXTRADATA_SLICEINFO | VENC_EXTRADATA_LTRINFO | |
| VENC_EXTRADATA_MBINFO; |
| pParam->bEnable = (m_sExtraData & output_extradata_mask) ? OMX_TRUE : OMX_FALSE; |
| eRet = OMX_ErrorNone; |
| } else { |
| DEBUG_PRINT_ERROR("get_parameter: unsupported extradata index (0x%x)", |
| pParam->nPortIndex); |
| 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; |
| } |
| 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_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_QTIIndexParamVQZIPSEIType: |
| { |
| VALIDATE_OMX_PARAM_DATA(paramData, OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE); |
| OMX_U32 enabled; |
| OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE *pParam = |
| reinterpret_cast<OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE*>(paramData); |
| DEBUG_PRINT_LOW("get_parameter: OMX_QTIIndexParamVQZIPSEIType"); |
| if (!dev_get_vqzip_sei_info(&enabled)) { |
| DEBUG_PRINT_ERROR("Invalid entry returned from get_vqzip_sei_type %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 OMX_QcomIndexParamBatchSize: |
| { |
| VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_U32TYPE); |
| OMX_PARAM_U32TYPE* batch = |
| reinterpret_cast<OMX_PARAM_U32TYPE *>(paramData); |
| |
| DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamBatchSize"); |
| if (!dev_get_batch_size(&batch->nU32)) { |
| DEBUG_PRINT_ERROR("Invalid entry returned from dev_get_batch_size %u", |
| (unsigned int)batch->nSize); |
| eRet = OMX_ErrorUnsupportedIndex; |
| break; |
| } |
| |
| batch->nPortIndex = PORT_INDEX_IN; |
| break; |
| } |
| case OMX_QcomIndexParamSequenceHeaderWithIDR: |
| { |
| VALIDATE_OMX_PARAM_DATA(paramData, PrependSPSPPSToIDRFramesParams); |
| PrependSPSPPSToIDRFramesParams * pParam = |
| reinterpret_cast<PrependSPSPPSToIDRFramesParams *>(paramData); |
| DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamSequenceHeaderWithIDR"); |
| memcpy(pParam, &m_sPrependSPSPPS, sizeof(m_sPrependSPSPPS)); |
| break; |
| } |
| case OMX_QcomIndexParamVencAspectRatio: |
| { |
| VALIDATE_OMX_PARAM_DATA(paramData, QOMX_EXTNINDEX_VIDEO_VENC_SAR); |
| QOMX_EXTNINDEX_VIDEO_VENC_SAR * pParam = |
| reinterpret_cast<QOMX_EXTNINDEX_VIDEO_VENC_SAR *>(paramData); |
| memcpy(pParam, &m_sSar, sizeof(m_sSar)); |
| break; |
| } |
| case OMX_IndexParamAndroidVideoTemporalLayering: |
| { |
| VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE); |
| OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE *pLayerInfo = |
| reinterpret_cast<OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE*>(paramData); |
| if (!dev_get_temporal_layer_caps(&m_sParamTemporalLayers.nLayerCountMax, |
| &m_sParamTemporalLayers.nBLayerCountMax, &m_sParamTemporalLayers.eSupportedPatterns)) { |
| DEBUG_PRINT_ERROR("Failed to get temporal layer capabilities"); |
| eRet = OMX_ErrorHardware; |
| } |
| memcpy(pLayerInfo, &m_sParamTemporalLayers, sizeof(m_sParamTemporalLayers)); |
| break; |
| } |
| case OMX_QcomIndexParamVideoDownScalar: |
| { |
| VALIDATE_OMX_PARAM_DATA(paramData, QOMX_INDEXDOWNSCALAR); |
| QOMX_INDEXDOWNSCALAR *pDownScalarParam = |
| reinterpret_cast<QOMX_INDEXDOWNSCALAR *>(paramData); |
| memcpy(pDownScalarParam, &m_sParamDownScalar, sizeof(m_sParamDownScalar)); |
| break; |
| } |
| case OMX_IndexParamConsumerUsageBits: |
| { |
| if (paramData == NULL) { return OMX_ErrorBadParameter; } |
| OMX_U32 *consumerUsage = (OMX_U32 *)paramData; |
| OMX_U32 eProfile = 0; |
| DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamConsumerUsageBits"); |
| bool hevc = dev_get_hevc_profile(&eProfile); |
| if(hevc && eProfile == (OMX_U32)OMX_VIDEO_HEVCProfileMain10HDR10) { |
| DEBUG_PRINT_INFO("Setting TP10 consumer usage bits"); |
| m_sParamConsumerUsage |= GRALLOC1_CONSUMER_USAGE_PRIVATE_10BIT_TP; |
| m_sParamConsumerUsage |= GRALLOC1_CONSUMER_USAGE_UBWC_FLAG; |
| } |
| memcpy(consumerUsage, &m_sParamConsumerUsage, sizeof(m_sParamConsumerUsage)); |
| 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; |
| } |
| |
| if (reject_config_for_TME_mode(configIndex)) { |
| DEBUG_PRINT_ERROR("ERROR: config 0x%x rejected in TME mode", configIndex); |
| return OMX_ErrorNone; |
| } |
| |
| //@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 OMX_IndexConfigCommonMirror: |
| { |
| VALIDATE_OMX_PARAM_DATA(configData, OMX_CONFIG_MIRRORTYPE); |
| OMX_CONFIG_MIRRORTYPE* pParam = reinterpret_cast<OMX_CONFIG_MIRRORTYPE*>(configData); |
| memcpy(pParam, &m_sConfigFrameMirror, sizeof(m_sConfigFrameMirror)); |
| 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_QcomIndexConfigNumHierPLayers: |
| { |
| VALIDATE_OMX_PARAM_DATA(configData, QOMX_EXTNINDEX_VIDEO_HIER_P_LAYERS); |
| QOMX_EXTNINDEX_VIDEO_HIER_P_LAYERS* pParam = |
| reinterpret_cast<QOMX_EXTNINDEX_VIDEO_HIER_P_LAYERS*>(configData); |
| DEBUG_PRINT_LOW("get_config: OMX_QcomIndexConfigNumHierPLayers"); |
| memcpy(pParam, &m_sHPlayers, sizeof(m_sHPlayers)); |
| break; |
| } |
| case OMX_QcomIndexConfigQp: |
| { |
| VALIDATE_OMX_PARAM_DATA(configData, OMX_SKYPE_VIDEO_CONFIG_QP); |
| OMX_SKYPE_VIDEO_CONFIG_QP* pParam = |
| reinterpret_cast<OMX_SKYPE_VIDEO_CONFIG_QP*>(configData); |
| DEBUG_PRINT_LOW("get_config: OMX_QcomIndexConfigQp"); |
| memcpy(pParam, &m_sConfigQP, sizeof(m_sConfigQP)); |
| break; |
| } |
| case OMX_QcomIndexConfigBaseLayerId: |
| { |
| VALIDATE_OMX_PARAM_DATA(configData, OMX_SKYPE_VIDEO_CONFIG_BASELAYERPID); |
| OMX_SKYPE_VIDEO_CONFIG_BASELAYERPID* pParam = |
| reinterpret_cast<OMX_SKYPE_VIDEO_CONFIG_BASELAYERPID*>(configData); |
| DEBUG_PRINT_LOW("get_config: OMX_QcomIndexConfigBaseLayerId"); |
| memcpy(pParam, &m_sBaseLayerID, sizeof(m_sBaseLayerID)); |
| break; |
| } |
| case OMX_IndexConfigAndroidIntraRefresh: |
| { |
| VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE); |
| OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE* pParam = |
| reinterpret_cast<OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE*>(configData); |
| DEBUG_PRINT_LOW("get_config: OMX_IndexConfigAndroidIntraRefresh"); |
| memcpy(pParam, &m_sConfigIntraRefresh, sizeof(m_sConfigIntraRefresh)); |
| break; |
| } |
| case OMX_IndexConfigOperatingRate: |
| { |
| VALIDATE_OMX_PARAM_DATA(configData, OMX_PARAM_U32TYPE); |
| OMX_PARAM_U32TYPE* pParam = |
| reinterpret_cast<OMX_PARAM_U32TYPE*>(configData); |
| DEBUG_PRINT_LOW("get_config: OMX_IndexConfigOperatingRate"); |
| pParam->nU32 = m_nOperatingRate; |
| break; |
| } |
| case OMX_QTIIndexConfigVideoBlurResolution: |
| { |
| VALIDATE_OMX_PARAM_DATA(configData, OMX_QTI_VIDEO_CONFIG_BLURINFO); |
| OMX_QTI_VIDEO_CONFIG_BLURINFO* pParam = |
| reinterpret_cast<OMX_QTI_VIDEO_CONFIG_BLURINFO*>(configData); |
| DEBUG_PRINT_LOW("get_config: OMX_QTIIndexConfigVideoBlurResolution"); |
| memcpy(pParam, &m_blurInfo, sizeof(m_blurInfo)); |
| break; |
| } |
| case OMX_QTIIndexConfigDescribeColorAspects: |
| { |
| VALIDATE_OMX_PARAM_DATA(configData, DescribeColorAspectsParams); |
| DescribeColorAspectsParams* pParam = |
| reinterpret_cast<DescribeColorAspectsParams*>(configData); |
| DEBUG_PRINT_LOW("get_config: OMX_QTIIndexConfigDescribeColorAspects"); |
| if (pParam->bRequestingDataSpace) { |
| DEBUG_PRINT_ERROR("Does not handle dataspace request"); |
| return OMX_ErrorUnsupportedSetting; |
| } |
| if (pParam->bDataSpaceChanged == OMX_TRUE) { |
| |
| print_debug_color_aspects(&(pParam->sAspects), "get_config (dataspace changed) Client says"); |
| // If the dataspace says RGB, recommend 601-limited; |
| // since that is the destination colorspace that C2D or Venus will convert to. |
| if (pParam->nPixelFormat == HAL_PIXEL_FORMAT_RGBA_8888) { |
| DEBUG_PRINT_INFO("get_config (dataspace changed): ColorSpace: Recommend 601-limited for RGBA8888"); |
| pParam->sAspects.mPrimaries = ColorAspects::PrimariesBT601_6_625; |
| pParam->sAspects.mRange = ColorAspects::RangeLimited; |
| pParam->sAspects.mTransfer = ColorAspects::TransferSMPTE170M; |
| pParam->sAspects.mMatrixCoeffs = ColorAspects::MatrixBT601_6; |
| } else { |
| // For IMPLEMENTATION_DEFINED (or anything else), stick to client's defaults. |
| DEBUG_PRINT_INFO("get_config (dataspace changed): ColorSpace: use client-default for format=%x", |
| pParam->nPixelFormat); |
| } |
| print_debug_color_aspects(&(pParam->sAspects), "get_config (dataspace changed) recommended"); |
| } else { |
| memcpy(pParam, &m_sConfigColorAspects, sizeof(m_sConfigColorAspects)); |
| print_debug_color_aspects(&(pParam->sAspects), "get_config"); |
| } |
| break; |
| } |
| case OMX_IndexConfigAndroidVideoTemporalLayering: |
| { |
| VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE); |
| OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE *layerConfig = |
| (OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE *)configData; |
| DEBUG_PRINT_LOW("get_config: OMX_IndexConfigAndroidVideoTemporalLayering"); |
| memcpy(configData, &m_sConfigTemporalLayers, sizeof(m_sConfigTemporalLayers)); |
| break; |
| } |
| case OMX_IndexConfigAndroidVendorExtension: |
| { |
| VALIDATE_OMX_PARAM_DATA(configData, OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE); |
| |
| OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext = |
| reinterpret_cast<OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *>(configData); |
| VALIDATE_OMX_VENDOR_EXTENSION_PARAM_DATA(ext); |
| return get_vendor_extension_config(ext); |
| } |
| |
| default: |
| DEBUG_PRINT_ERROR("ERROR: unsupported index %d", (int) configIndex); |
| return OMX_ErrorUnsupportedIndex; |
| } |
| return OMX_ErrorNone; |
| |
| } |
| |
| #define extn_equals(param, extn) (!strcmp(param, extn)) |
| |
| /* ====================================================================== |
| 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; |
| } |
| if (extn_equals(paramName, "OMX.QCOM.index.param.SliceDeliveryMode")) { |
| *indexType = (OMX_INDEXTYPE)OMX_QcomIndexEnableSliceDeliveryMode; |
| return OMX_ErrorNone; |
| } |
| #ifdef _ANDROID_ICS_ |
| if (extn_equals(paramName, "OMX.google.android.index.storeMetaDataInBuffers")) { |
| *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoMetaBufferMode; |
| return OMX_ErrorNone; |
| } |
| #endif |
| if (extn_equals(paramName, "OMX.google.android.index.prependSPSPPSToIDRFrames")) { |
| *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamSequenceHeaderWithIDR; |
| return OMX_ErrorNone; |
| } |
| |
| if (extn_equals(paramName, "OMX.QCOM.index.param.video.HierStructure")) { |
| *indexType = (OMX_INDEXTYPE)OMX_QcomIndexHierarchicalStructure; |
| return OMX_ErrorNone; |
| } |
| |
| if (extn_equals(paramName, "OMX.QCOM.index.param.video.LTRCount")) { |
| *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoLTRCount; |
| return OMX_ErrorNone; |
| } |
| |
| if (extn_equals(paramName, "OMX.QCOM.index.param.video.LTRPeriod")) { |
| return OMX_ErrorNone; |
| } |
| |
| if (extn_equals(paramName, "OMX.QCOM.index.config.video.LTRUse")) { |
| *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigVideoLTRUse; |
| return OMX_ErrorNone; |
| } |
| |
| if (extn_equals(paramName, "OMX.QCOM.index.config.video.LTRMark")) { |
| *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigVideoLTRMark; |
| return OMX_ErrorNone; |
| } |
| |
| if (extn_equals(paramName, "OMX.QCOM.index.config.video.hierplayers")) { |
| *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigNumHierPLayers; |
| return OMX_ErrorNone; |
| } |
| |
| if (extn_equals(paramName, "OMX.QCOM.index.param.video.baselayerid")) { |
| *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigBaseLayerId; |
| return OMX_ErrorNone; |
| } |
| |
| if (extn_equals(paramName, "OMX.QCOM.index.config.video.qp")) { |
| *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigQp; |
| return OMX_ErrorNone; |
| } |
| |
| if (extn_equals(paramName, "OMX.QCOM.index.param.video.sar")) { |
| *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVencAspectRatio; |
| return OMX_ErrorNone; |
| } |
| |
| if (extn_equals(paramName, "OMX.QCOM.index.param.video.InputBatch")) { |
| *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamBatchSize; |
| return OMX_ErrorNone; |
| } |
| |
| if (extn_equals(paramName, OMX_QTI_INDEX_CONFIG_VIDEO_SETTIMEDATA)) { |
| *indexType = (OMX_INDEXTYPE)OMX_IndexConfigTimePosition; |
| return OMX_ErrorNone; |
| } |
| |
| if (extn_equals(paramName, OMX_QTI_INDEX_PARAM_VIDEO_ENABLE_ROIINFO)) { |
| *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamVideoEnableRoiInfo; |
| return OMX_ErrorNone; |
| } |
| |
| if (extn_equals(paramName, OMX_QTI_INDEX_CONFIG_VIDEO_ROIINFO)) { |
| *indexType = (OMX_INDEXTYPE)OMX_QTIIndexConfigVideoRoiInfo; |
| return OMX_ErrorNone; |
| } |
| |
| if (extn_equals(paramName, OMX_QTI_INDEX_CONFIG_VIDEO_BLURINFO)) { |
| *indexType = (OMX_INDEXTYPE)OMX_QTIIndexConfigVideoBlurResolution; |
| return OMX_ErrorNone; |
| } |
| |
| if (extn_equals(paramName, "OMX.google.android.index.describeColorAspects")) { |
| *indexType = (OMX_INDEXTYPE)OMX_QTIIndexConfigDescribeColorAspects; |
| return OMX_ErrorNone; |
| } |
| |
| if (extn_equals(paramName, "OMX.google.android.index.allocateNativeHandle")) { |
| *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexAllocateNativeHandle; |
| return OMX_ErrorNone; |
| } |
| |
| if (extn_equals(paramName, OMX_QTI_INDEX_PARAM_VIDEO_CLIENT_EXTRADATA)) { |
| *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamVideoClientExtradata; |
| return OMX_ErrorNone; |
| } |
| |
| if (extn_equals(paramName, OMX_QTI_INDEX_PARAM_TME)) { |
| *indexType = (OMX_INDEXTYPE)OMX_IndexParamVideoTme; |
| 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); |
| BITMASK_SET(&m_client_in_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 |
| 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, |
| secure_session ? SECURE_FLAGS_INPUT_BUFFER : 0); |
| 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 = NULL; |
| 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"); |
| m_pInput_pmem[i].buffer = NULL; |
| 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; |
| } |
|