From 615439701b2e0ce08c7e6458ecebc8f6ae6eef41 Mon Sep 17 00:00:00 2001 From: Deva Ramasubramanian Date: Mon, 28 Jan 2013 20:15:29 -0800 Subject: [PATCH] mm-video: vidc: Add support for picture order count Add support for picture order count. By default PicOrderType is set to 2 for H264 encode. Setting this parameter in the sps/pps to 2 causes the decoder to return the first I-frame immediately after decode, as opposed to holding onto it until the next frame. Apps can configure it via OMX Get/Set API. Change-Id: I57c6287603747ef7e838e7017e2378a6c9e736af Signed-off-by: spezi77 Conflicts: mm-core/inc/OMX_QCOMExtns.h mm-video/vidc/venc/inc/omx_video_base.h mm-video/vidc/venc/inc/video_encoder_device.h mm-video/vidc/venc/src/omx_video_base.cpp mm-video/vidc/venc/src/omx_video_encoder.cpp mm-video/vidc/venc/src/video_encoder_device.cpp --- mm-core/inc/OMX_QCOMExtns.h | 32 +- mm-video/vidc/venc/inc/omx_video_base.h | 3 +- mm-video/vidc/venc/inc/video_encoder_device.h | 336 +- mm-video/vidc/venc/src/omx_video_base.cpp | 9240 +++++++++-------- mm-video/vidc/venc/src/omx_video_encoder.cpp | 3497 ++++--- .../vidc/venc/src/video_encoder_device.cpp | 58 + 6 files changed, 6988 insertions(+), 6178 deletions(-) diff --git a/mm-core/inc/OMX_QCOMExtns.h b/mm-core/inc/OMX_QCOMExtns.h index 134b82e..323a38f 100644 --- a/mm-core/inc/OMX_QCOMExtns.h +++ b/mm-core/inc/OMX_QCOMExtns.h @@ -361,7 +361,22 @@ enum OMX_QCOM_EXTN_INDEXTYPE OMX_QcomIndexEnableExtnUserData = 0x7F000020, /*"OMX.QCOM.index.param.video.EnableSmoothStreaming"*/ - OMX_QcomIndexParamEnableSmoothStreaming = 0x7F000021, + OMX_QcomIndexParamEnableSmoothStreaming = 0x7F000022, + + /*"OMX.QCOM.index.param.video.QPRange" */ + OMX_QcomIndexParamVideoQPRange = 0x7F000023, + + OMX_QcomIndexParamEnableVUIStreamRestrictFlag = 0x7F000024, + + /*"OMX.QCOM.index.config.TurboMode"*/ + OMX_QcomIndexConfigTurboMode = 0x7F000025, + + /*"OMX.QCOM.index.param.video.PerformanceLevel" */ + OMX_QcomIndexParamVideoPerformanceLevel = 0x7F000026, + + OMX_GoogleAndroidIndexPrepareForAdaptivePlayback = 0x7F00002D, + + OMX_QcomIndexParamPictureOrderCountType = 0x7F000054, }; /** @@ -874,6 +889,21 @@ typedef enum { QOMX_VIDEO_CONTENT_RL_VIEW = 2, } QOMX_VIDEO_CONTENT_INTERPRETATION; +// A pointer to this struct is passed to OMX_SetParameter when the extension +// index for the 'OMX.google.android.index.setVUIStreamRestrictFlag' extension +// is given. +typedef struct QOMX_VUI_BITSTREAM_RESTRICT { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_BOOL bEnable; +} QOMX_VUI_BITSTREAM_RESTRICT; + +typedef struct QOMX_PICTURE_ORDER_COUNT_TYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nType; +} QOMX_PICTURE_ORDER_COUNT_TYPE; + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/mm-video/vidc/venc/inc/omx_video_base.h b/mm-video/vidc/venc/inc/omx_video_base.h index ee050ec..d8be6ec 100644 --- a/mm-video/vidc/venc/inc/omx_video_base.h +++ b/mm-video/vidc/venc/inc/omx_video_base.h @@ -527,7 +527,8 @@ class omx_video: public qc_omx_component OMX_VIDEO_PARAM_INTRAREFRESHTYPE m_sIntraRefresh; OMX_U32 m_sExtraData; OMX_U32 m_sDebugSliceinfo; - + OMX_U32 m_input_msg_id; + QOMX_PICTURE_ORDER_COUNT_TYPE m_sPicureOrderCount; // fill this buffer queue omx_cmd_queue m_ftb_q; // Command Q for rest of the events diff --git a/mm-video/vidc/venc/inc/video_encoder_device.h b/mm-video/vidc/venc/inc/video_encoder_device.h index 25df71f..96cf162 100755 --- a/mm-video/vidc/venc/inc/video_encoder_device.h +++ b/mm-video/vidc/venc/inc/video_encoder_device.h @@ -1,161 +1,175 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2010-2012, Code Aurora Forum. 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 Code Aurora 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. ---------------------------------------------------------------------------*/ -#ifndef __OMX_VENC_DEV__ -#define __OMX_VENC_DEV__ - -#include "OMX_Types.h" -#include "OMX_Core.h" -#include "OMX_QCOMExtns.h" -#include "qc_omx_component.h" -#include "omx_video_common.h" -#include -#include -#include -#include -#define TIMEOUT 5000 -#define MAX_RECON_BUFFERS 4 - -void* async_venc_message_thread (void *); - -class venc_dev -{ -public: - venc_dev(class omx_venc *venc_class); //constructor - ~venc_dev(); //des - - bool venc_open(OMX_U32); - void venc_close(); - unsigned venc_stop(void); - unsigned venc_pause(void); - unsigned venc_start(void); - unsigned venc_flush(unsigned); -#ifdef _ANDROID_ICS_ - bool venc_set_meta_mode(bool); -#endif - unsigned venc_resume(void); - unsigned venc_start_done(void); - unsigned venc_stop_done(void); - bool venc_use_buf(void*, unsigned,unsigned); - bool venc_free_buf(void*, unsigned); - bool venc_empty_buf(void *, void *,unsigned,unsigned); - bool venc_fill_buf(void *, void *,unsigned,unsigned); - - bool venc_get_buf_req(unsigned long *,unsigned long *, - unsigned long *,unsigned long); - bool venc_set_buf_req(unsigned long *,unsigned long *, - unsigned long *,unsigned long); - bool venc_set_param(void *,OMX_INDEXTYPE); - bool venc_set_config(void *configData, OMX_INDEXTYPE index); - bool venc_get_profile_level(OMX_U32 *eProfile,OMX_U32 *eLevel); - bool venc_max_allowed_bitrate_check(OMX_U32 nTargetBitrate); - bool venc_get_seq_hdr(void *, unsigned, unsigned *); - bool venc_loaded_start(void); - bool venc_loaded_stop(void); - bool venc_loaded_start_done(void); - bool venc_loaded_stop_done(void); - OMX_U32 m_nDriver_fd; - bool m_profile_set; - bool m_level_set; - pthread_mutex_t loaded_start_stop_mlock; - pthread_cond_t loaded_start_stop_cond; - - struct recon_buffer { - unsigned char* virtual_address; - int pmem_fd; - int size; - int alignment; - int offset; -#ifdef USE_ION - int ion_device_fd; - struct ion_allocation_data alloc_data; - struct ion_fd_data ion_alloc_fd; -#endif - }; - - recon_buffer recon_buff[MAX_RECON_BUFFERS]; - int recon_buffers_count; - bool m_max_allowed_bitrate_check; - int m_eProfile; - int m_eLevel; - int etb_count; -private: - struct venc_basecfg m_sVenc_cfg; - struct venc_ratectrlcfg rate_ctrl; - struct venc_targetbitrate bitrate; - struct venc_intraperiod intra_period; - struct venc_profile codec_profile; - struct ven_profilelevel profile_level; - struct venc_switch set_param; - struct venc_voptimingcfg time_inc; - struct venc_allocatorproperty m_sInput_buff_property; - struct venc_allocatorproperty m_sOutput_buff_property; - struct venc_sessionqp session_qp; - struct venc_multiclicecfg multislice; - struct venc_entropycfg entropy; - struct venc_dbcfg dbkfilter; - struct venc_intrarefresh intra_refresh; - struct venc_headerextension hec; - struct venc_voptimingcfg voptimecfg; - struct venc_seqheader seqhdr; - - bool venc_set_profile_level(OMX_U32 eProfile,OMX_U32 eLevel); - bool venc_set_intra_period(OMX_U32 nPFrames, OMX_U32 nBFrames); - bool venc_set_target_bitrate(OMX_U32 nTargetBitrate, OMX_U32 config); - bool venc_set_ratectrl_cfg(OMX_VIDEO_CONTROLRATETYPE eControlRate); - bool venc_set_session_qp(OMX_U32 i_frame_qp, OMX_U32 p_frame_qp); - bool venc_set_extradata(OMX_U32 extra_data); - bool venc_set_encode_framerate(OMX_U32 encode_framerate, OMX_U32 config); - bool venc_set_intra_vop_refresh(OMX_BOOL intra_vop_refresh); - bool venc_set_color_format(OMX_COLOR_FORMATTYPE color_format); - bool venc_validate_profile_level(OMX_U32 *eProfile, OMX_U32 *eLevel); - bool venc_set_multislice_cfg(OMX_INDEXTYPE codec, OMX_U32 slicesize); - bool venc_set_entropy_config(OMX_BOOL enable, OMX_U32 i_cabac_level); - bool venc_set_inloop_filter(OMX_VIDEO_AVCLOOPFILTERTYPE loop_filter); - bool venc_set_intra_refresh (OMX_VIDEO_INTRAREFRESHTYPE intrarefresh, OMX_U32 nMBs); - bool venc_set_error_resilience(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* error_resilience); - bool venc_set_voptiming_cfg(OMX_U32 nTimeIncRes); - void venc_config_print(); - bool venc_set_slice_delivery_mode(OMX_BOOL enable); -#ifdef MAX_RES_1080P - OMX_U32 pmem_free(); - OMX_U32 pmem_allocate(OMX_U32 size, OMX_U32 alignment, OMX_U32 count); - OMX_U32 venc_allocate_recon_buffers(); - inline int clip2(int x) - { - x = x -1; - x = x | x >> 1; - x = x | x >> 2; - x = x | x >> 4; - x = x | x >> 16; - x = x + 1; - return x; - } -#endif -}; - -#endif +/*-------------------------------------------------------------------------- +Copyright (c) 2010-2013, 2015, The 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. +--------------------------------------------------------------------------*/ +#ifndef __OMX_VENC_DEV__ +#define __OMX_VENC_DEV__ + +#include "OMX_Types.h" +#include "OMX_Core.h" +#include "OMX_QCOMExtns.h" +#include "qc_omx_component.h" +#include "omx_video_common.h" +#include +#include +#include +#include +#define TIMEOUT 5000 +#define MAX_RECON_BUFFERS 4 +/* 1080P video hardware does not support slice size less than */ +/* 1900 bits for multi slice settings in bits mode */ +#define MIN_SLICE_BITS_1080P 1900 + +void* async_venc_message_thread (void *); + +class venc_dev +{ +public: + venc_dev(class omx_venc *venc_class); //constructor + ~venc_dev(); //des + + bool venc_open(OMX_U32); + void venc_close(); + unsigned venc_stop(void); + unsigned venc_pause(void); + unsigned venc_start(void); + unsigned venc_flush(unsigned); +#ifdef _ANDROID_ICS_ + bool venc_set_meta_mode(bool); +#endif + unsigned venc_resume(void); + unsigned venc_start_done(void); + unsigned venc_stop_done(void); + bool venc_use_buf(void*, unsigned,unsigned); + bool venc_free_buf(void*, unsigned); + bool venc_empty_buf(void *, void *,unsigned,unsigned); + bool venc_fill_buf(void *, void *,unsigned,unsigned); + + bool venc_get_buf_req(unsigned long *,unsigned long *, + unsigned long *,unsigned long); + bool venc_set_buf_req(unsigned long *,unsigned long *, + unsigned long *,unsigned long); + bool venc_get_curr_perf_lvl(OMX_PTR); + bool venc_set_param(void *,OMX_INDEXTYPE); + bool venc_set_config(void *configData, OMX_INDEXTYPE index); + bool venc_get_profile_level(OMX_U32 *eProfile,OMX_U32 *eLevel); + bool venc_max_allowed_bitrate_check(OMX_U32 nTargetBitrate); + bool venc_get_seq_hdr(void *, unsigned, unsigned *); + bool venc_loaded_start(void); + bool venc_loaded_stop(void); + bool venc_loaded_start_done(void); + bool venc_loaded_stop_done(void); + bool venc_get_uncache_flag(void); + OMX_U32 m_nDriver_fd; + bool m_profile_set; + bool m_level_set; + pthread_mutex_t loaded_start_stop_mlock; + pthread_cond_t loaded_start_stop_cond; + + struct recon_buffer { + unsigned char* virtual_address; + int pmem_fd; + int size; + int alignment; + int offset; +#ifdef USE_ION + int ion_device_fd; + struct ion_allocation_data alloc_data; + struct ion_fd_data ion_alloc_fd; +#endif + }; + + recon_buffer recon_buff[MAX_RECON_BUFFERS]; + int recon_buffers_count; + bool m_max_allowed_bitrate_check; + int m_eProfile; + int m_eLevel; + int etb_count; + bool m_use_uncache_buffers; + +private: + class omx_venc *venc_encoder; + struct venc_basecfg m_sVenc_cfg; + struct venc_ratectrlcfg rate_ctrl; + struct venc_targetbitrate bitrate; + struct venc_intraperiod intra_period; + struct venc_profile codec_profile; + struct ven_profilelevel profile_level; + struct venc_switch set_param; + struct venc_voptimingcfg time_inc; + struct venc_allocatorproperty m_sInput_buff_property; + struct venc_allocatorproperty m_sOutput_buff_property; + struct venc_sessionqp session_qp; + struct venc_qprange qp_range; + struct venc_multiclicecfg multislice; + struct venc_entropycfg entropy; + struct venc_dbcfg dbkfilter; + struct venc_intrarefresh intra_refresh; + struct venc_headerextension hec; + struct venc_voptimingcfg voptimecfg; + struct venc_seqheader seqhdr; + + bool venc_set_profile_level(OMX_U32 eProfile,OMX_U32 eLevel); + bool venc_set_intra_period(OMX_U32 nPFrames, OMX_U32 nBFrames); + bool venc_set_target_bitrate(OMX_U32 nTargetBitrate, OMX_U32 config); + bool venc_set_ratectrl_cfg(OMX_VIDEO_CONTROLRATETYPE eControlRate); + bool venc_set_session_qp(OMX_U32 i_frame_qp, OMX_U32 p_frame_qp); + bool venc_set_qp_range(OMX_U32 min_qp, OMX_U32 max_qp); + bool venc_set_extradata(OMX_U32 extra_data); + bool venc_set_encode_framerate(OMX_U32 encode_framerate, OMX_U32 config); + bool venc_set_intra_vop_refresh(OMX_BOOL intra_vop_refresh); + bool venc_set_color_format(OMX_COLOR_FORMATTYPE color_format); + bool venc_validate_profile_level(OMX_U32 *eProfile, OMX_U32 *eLevel); + bool venc_set_multislice_cfg(OMX_INDEXTYPE codec, OMX_U32 slicesize); + bool venc_set_entropy_config(OMX_BOOL enable, OMX_U32 i_cabac_level); + bool venc_set_inloop_filter(OMX_VIDEO_AVCLOOPFILTERTYPE loop_filter); + bool venc_set_intra_refresh (OMX_VIDEO_INTRAREFRESHTYPE intrarefresh, OMX_U32 nMBs); + bool venc_set_error_resilience(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* error_resilience); + bool venc_set_voptiming_cfg(OMX_U32 nTimeIncRes); + void venc_config_print(); + bool venc_set_slice_delivery_mode(OMX_BOOL enable); + bool venc_set_inband_video_header(OMX_BOOL enable); + bool venc_set_bitstream_restrict_in_vui(OMX_BOOL enable); + bool venc_set_picture_order_count_type(OMX_U32 type); + +#ifdef MAX_RES_1080P + OMX_U32 pmem_free(); + OMX_U32 pmem_allocate(OMX_U32 size, OMX_U32 alignment, OMX_U32 count); + OMX_U32 venc_allocate_recon_buffers(); + inline int clip2(int x) + { + x = x -1; + x = x | x >> 1; + x = x | x >> 2; + x = x | x >> 4; + x = x | x >> 16; + x = x + 1; + return x; + } +#endif +}; + +#endif diff --git a/mm-video/vidc/venc/src/omx_video_base.cpp b/mm-video/vidc/venc/src/omx_video_base.cpp index 93d03cd..a5cf88f 100644 --- a/mm-video/vidc/venc/src/omx_video_base.cpp +++ b/mm-video/vidc/venc/src/omx_video_base.cpp @@ -1,4339 +1,4901 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2010-2012, Code Aurora Forum. 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 Code Aurora 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 -////////////////////////////////////////////////////////////////////////////// - -#include -#include "omx_video_base.h" -#include -#include -#include -#include -#include -#ifdef _ANDROID_ICS_ -#include -#include -#endif -#ifndef _ANDROID_ -#include -#define strlcpy g_strlcpy -#endif -#define H264_SUPPORTED_WIDTH (480) -#define H264_SUPPORTED_HEIGHT (368) - -#define MPEG4_SUPPORTED_WIDTH (480) -#define MPEG4_SUPPORTED_HEIGHT (368) - -#define VC1_SP_MP_START_CODE 0xC5000000 -#define VC1_SP_MP_START_CODE_MASK 0xFF000000 -#define VC1_AP_START_CODE 0x00000100 -#define VC1_AP_START_CODE_MASK 0xFFFFFF00 -#define VC1_STRUCT_C_PROFILE_MASK 0xF0 -#define VC1_STRUCT_B_LEVEL_MASK 0xE0000000 -#define VC1_SIMPLE_PROFILE 0 -#define VC1_MAIN_PROFILE 1 -#define VC1_ADVANCE_PROFILE 3 -#define VC1_SIMPLE_PROFILE_LOW_LEVEL 0 -#define VC1_SIMPLE_PROFILE_MED_LEVEL 2 -#define VC1_STRUCT_C_LEN 4 -#define VC1_STRUCT_C_POS 8 -#define VC1_STRUCT_A_POS 12 -#define VC1_STRUCT_B_POS 24 -#define VC1_SEQ_LAYER_SIZE 36 - -typedef struct OMXComponentCapabilityFlagsType -{ - ////////////////// OMX COMPONENT CAPABILITY RELATED MEMBERS - 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 - -#ifdef OUTPUT_BUFFER_LOG -extern FILE *outputBufferFile1; -#endif - -void* message_thread(void *input) -{ - omx_video* omx = reinterpret_cast(input); - unsigned char id; - int n; - - DEBUG_PRINT_LOW("omx_venc: message thread start\n"); - prctl(PR_SET_NAME, (unsigned long)"VideoEncMsgThread", 0, 0, 0); - while(1) - { - n = read(omx->m_pipe_in, &id, 1); - if(0 == n) - { - break; - } - - if(1 == n) - { - omx->process_event_cb(omx, id); - } -#ifdef QLE_BUILD - if(n < 0) break; -#else - if((n < 0) && (errno != EINTR)) break; -#endif - } - DEBUG_PRINT_LOW("omx_venc: message thread stop\n"); - return 0; -} - -void post_message(omx_video *omx, unsigned char id) -{ - DEBUG_PRINT_LOW("omx_venc: post_message %d\n", id); - write(omx->m_pipe_out, &id, 1); -} - -// omx_cmd_queue destructor -omx_video::omx_cmd_queue::~omx_cmd_queue() -{ - // Nothing to do -} - -// omx cmd queue constructor -omx_video::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0) -{ - memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE); -} - -// omx cmd queue insert -bool omx_video::omx_cmd_queue::insert_entry(unsigned p1, unsigned p2, unsigned 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\n"); - } - return ret; -} - -// omx cmd queue pop -bool omx_video::omx_cmd_queue::pop_entry(unsigned *p1, unsigned *p2, unsigned *id) -{ - bool ret = true; - if(m_size > 0) - { - *id = m_q[m_read].id; - *p1 = m_q[m_read].param1; - *p2 = m_q[m_read].param2; - // Move the read pointer ahead - ++m_read; - --m_size; - if(m_read >= OMX_CORE_CONTROL_CMDQ_SIZE) - { - m_read = 0; - } - } - else - { - ret = false; - } - return ret; -} - -// Retrieve the first mesg type in the queue -unsigned omx_video::omx_cmd_queue::get_q_msg_type() -{ - return m_q[m_read].id; -} - - - -#ifdef _ANDROID_ -VideoHeap::VideoHeap(int fd, size_t size, void* base) -{ - // dup file descriptor, map once, use pmem - init(dup(fd), base, size, 0 , MEM_DEVICE); -} -#endif // _ANDROID_ - -/* ====================================================================== -FUNCTION - omx_venc::omx_venc - -DESCRIPTION - Constructor - -PARAMETERS - None - -RETURN VALUE - None. -========================================================================== */ -omx_video::omx_video(): m_state(OMX_StateInvalid), - m_app_data(NULL), - m_inp_mem_ptr(NULL), - m_out_mem_ptr(NULL), - m_pInput_pmem(NULL), - m_pOutput_pmem(NULL), -#ifdef USE_ION - m_pInput_ion(NULL), - m_pOutput_ion(NULL), -#endif - pending_input_buffers(0), - pending_output_buffers(0), - m_out_bm_count(0), - m_inp_bm_count(0), - m_flags(0), - m_event_port_settings_sent(false), - output_flush_progress (false), - input_flush_progress (false), - input_use_buffer (false), - output_use_buffer (false), - m_use_input_pmem(OMX_FALSE), - m_use_output_pmem(OMX_FALSE), - m_etb_count(0), - m_fbd_count(0), - m_error_propogated(false) -{ - DEBUG_PRINT_HIGH("\n omx_video(): Inside Constructor()"); - memset(&m_cmp,0,sizeof(m_cmp)); - memset(&m_pCallbacks,0,sizeof(m_pCallbacks)); - - - pthread_mutex_init(&m_lock, NULL); - sem_init(&m_cmd_lock,0,0); -} - - -/* ====================================================================== -FUNCTION - omx_venc::~omx_venc - -DESCRIPTION - Destructor - -PARAMETERS - None - -RETURN VALUE - None. -========================================================================== */ -omx_video::~omx_video() -{ - DEBUG_PRINT_HIGH("\n ~omx_video(): Inside Destructor()"); - if(m_pipe_in) close(m_pipe_in); - if(m_pipe_out) close(m_pipe_out); - DEBUG_PRINT_HIGH("omx_video: Waiting on Msg Thread exit\n"); - pthread_join(msg_thread_id,NULL); - DEBUG_PRINT_HIGH("omx_video: Waiting on Async Thread exit\n"); - pthread_join(async_thread_id,NULL); - pthread_mutex_destroy(&m_lock); - sem_destroy(&m_cmd_lock); - DEBUG_PRINT_HIGH("\n m_etb_count = %u, m_fbd_count = %u\n", m_etb_count, - m_fbd_count); - DEBUG_PRINT_HIGH("omx_video: Destructor exit\n"); - DEBUG_PRINT_HIGH("Exiting 7x30 OMX Video Encoder ...\n"); -} - -/* ====================================================================== -FUNCTION - omx_venc::OMXCntrlProcessMsgCb - -DESCRIPTION - IL Client callbacks are generated through this routine. The decoder - provides the thread context for this routine. - -PARAMETERS - ctxt -- Context information related to the self. - id -- Event identifier. This could be any of the following: - 1. Command completion event - 2. Buffer done callback event - 3. Frame done callback event - -RETURN VALUE - None. - -========================================================================== */ -void omx_video::process_event_cb(void *ctxt, unsigned char id) -{ - unsigned p1; // Parameter - 1 - unsigned p2; // Parameter - 2 - unsigned ident; - unsigned qsize=0; // qsize - omx_video *pThis = (omx_video *) ctxt; - - if(!pThis) - { - DEBUG_PRINT_ERROR("ERROR:ProcessMsgCb:Context is incorrect; bailing out\n"); - return; - } - - // Protect the shared queue data structure - do - { - /*Read the message id's from the queue*/ - - pthread_mutex_lock(&pThis->m_lock); - qsize = pThis->m_cmd_q.m_size; - if(qsize) - { - pThis->m_cmd_q.pop_entry(&p1,&p2,&ident); - } - - if(qsize == 0) - { - qsize = pThis->m_ftb_q.m_size; - if(qsize) - { - pThis->m_ftb_q.pop_entry(&p1,&p2,&ident); - } - } - - if(qsize == 0) - { - qsize = pThis->m_etb_q.m_size; - if(qsize) - { - pThis->m_etb_q.pop_entry(&p1,&p2,&ident); - } - } - - pthread_mutex_unlock(&pThis->m_lock); - - /*process message if we have one*/ - if(qsize > 0) - { - id = ident; - switch(id) - { - case OMX_COMPONENT_GENERATE_EVENT: - if(pThis->m_pCallbacks.EventHandler) - { - switch(p1) - { - case OMX_CommandStateSet: - pThis->m_state = (OMX_STATETYPE) p2; - DEBUG_PRINT_LOW("Process -> state set to %d \n", pThis->m_state); - pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, - OMX_EventCmdComplete, p1, p2, NULL); - break; - - case OMX_EventError: - DEBUG_PRINT_ERROR("\nERROR: OMX_EventError: p2 = %d\n", p2); - if(p2 == 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, NULL, NULL ); - - } - break; - - case OMX_CommandPortDisable: - DEBUG_PRINT_LOW("Process -> Port %d set to PORT_STATE_DISABLED" \ - "state \n", 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 %d set PORT_STATE_ENABLED state\n" \ - , p2); - pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,\ - OMX_EventCmdComplete, p1, p2, NULL ); - break; - - default: - DEBUG_PRINT_LOW("\n process_event_cb forwarding EventCmdComplete %d \n", 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\n"); - } - break; - - case OMX_COMPONENT_GENERATE_ETB: - if(pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\ - (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) - { - DEBUG_PRINT_ERROR("\nERROR: ETBProxy() failed!\n"); - 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("\nERROR: FTBProxy() failed!\n"); - 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("\nERROR: empty_buffer_done() failed!\n"); - 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("\nERROR: fill_buffer_done() failed!\n"); - pThis->omx_report_error (); - } - break; - - case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH: - - pThis->input_flush_progress = false; - DEBUG_PRINT_HIGH("\nm_etb_count at i/p flush = %u", 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("\n dev_stop called after input flush complete\n"); - if(dev_stop() != 0) - { - DEBUG_PRINT_ERROR("\nERROR: dev_stop() failed in i/p flush!\n"); - pThis->omx_report_error (); - } - } - } - } - - break; - - case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH: - - pThis->output_flush_progress = false; - DEBUG_PRINT_HIGH("\nm_fbd_count at o/p flush = %u", 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("\n dev_stop called after Output flush complete\n"); - if(!pThis->input_flush_progress) - { - if(dev_stop() != 0) - { - DEBUG_PRINT_ERROR("\nERROR: dev_stop() failed in o/p flush!\n"); - pThis->omx_report_error (); - } - } - } - } - break; - - case OMX_COMPONENT_GENERATE_START_DONE: - DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE msg"); - - if(pThis->m_pCallbacks.EventHandler) - { - DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE Success"); - if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) - { - DEBUG_PRINT_LOW("\n 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("\nERROR: dev_pause() failed in Start Done!\n"); - 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("\nERROR: unknown flags=%x\n",pThis->m_flags); - } - } - else - { - DEBUG_PRINT_LOW("\n Event Handler callback is NULL"); - } - break; - - case OMX_COMPONENT_GENERATE_PAUSE_DONE: - DEBUG_PRINT_LOW("\n 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\n"); - 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("\n 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("\n 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("\nERROR: unknown flags=%x\n",pThis->m_flags); - } - } - - break; - - case OMX_COMPONENT_GENERATE_HARDWARE_ERROR: - DEBUG_PRINT_ERROR("\nERROR: OMX_COMPONENT_GENERATE_HARDWARE_ERROR!\n"); - pThis->omx_report_error (); - break; - - default: - DEBUG_PRINT_LOW("\n process_event_cb unknown msg id 0x%02x", id); - break; - } - } - - pthread_mutex_lock(&pThis->m_lock); - qsize = pThis->m_cmd_q.m_size + pThis->m_ftb_q.m_size +\ - pThis->m_etb_q.m_size; - - pthread_mutex_unlock(&pThis->m_lock); - - } - while(qsize>0); - DEBUG_PRINT_LOW("\n exited the while loop\n"); - -} - - - - -/* ====================================================================== -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 -) -{ - if(m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("ERROR: Get Comp Version in Invalid State\n"); - 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 - ) -{ - if(m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State\n"); - return OMX_ErrorInvalidState; - } - - if(cmd == OMX_CommandFlush || cmd == OMX_CommandPortDisable || cmd == OMX_CommandPortEnable) - { - if((param1 != PORT_INDEX_IN) && (param1 != PORT_INDEX_OUT) && (param1 != PORT_INDEX_BOTH)) - { - DEBUG_PRINT_ERROR("ERROR: omx_video::send_command-->bad port index\n"); - return OMX_ErrorBadPortIndex; - } - } - if(cmd == OMX_CommandMarkBuffer) - { - if(param1 != PORT_INDEX_IN) - { - DEBUG_PRINT_ERROR("ERROR: omx_video::send_command-->bad port index \n"); - return OMX_ErrorBadPortIndex; - } - if(!cmdData) - { - DEBUG_PRINT_ERROR("ERROR: omx_video::send_command-->param is null"); - return OMX_ErrorBadParameter; - } - } - - post_event((unsigned)cmd,(unsigned)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 - ) -{ - 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\n"); - } - else - { - DEBUG_PRINT_LOW("OMXCORE-SM: Loaded-->Idle-Pending\n"); - 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\n"); - 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\n"); - } - /* Requesting transition from Loaded to Executing */ - else if(eState == OMX_StateExecuting) - { - DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Executing\n"); - 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\n"); - 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\n"); - post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorInvalidState; - } - else - { - DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->%d Not Handled\n",\ - 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\n"); - if(dev_stop() != 0) - { - DEBUG_PRINT_ERROR("\nERROR: dev_stop() failed at Idle --> Loaded"); - eRet = OMX_ErrorHardware; - } - } - else - { - DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Loaded-Pending\n"); - 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("\nERROR: dev_start() failed in SCP on Idle --> Exe\n"); - omx_report_error (); - eRet = OMX_ErrorHardware; - } - else - { - BITMASK_SET(&m_flags,OMX_COMPONENT_EXECUTE_PENDING); - DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Executing\n"); - bFlag = 0; - } - - dev_start_done(); - } - /* Requesting transition from Idle to Idle */ - else if(eState == OMX_StateIdle) - { - DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle-->Idle\n"); - 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\n"); - 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("\nERROR: dev_start() failed in SCP on Idle --> Pause\n"); - omx_report_error (); - eRet = OMX_ErrorHardware; - } - else - { - BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING); - DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Pause\n"); - bFlag = 0; - } - } - /* Requesting transition from Idle to Invalid */ - else if(eState == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle-->Invalid\n"); - post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorInvalidState; - } - else - { - DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle --> %d Not Handled\n",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("\n OMXCORE-SM: Executing --> Idle \n"); - //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; - dev_stop_done(); - } - /* Requesting transition from Executing to Paused */ - else if(eState == OMX_StatePause) - { - - if(dev_pause()) - { - DEBUG_PRINT_ERROR("\nERROR: dev_pause() failed in SCP on Exe --> Pause\n"); - 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\n"); - bFlag = 0; - } - } - /* Requesting transition from Executing to Loaded */ - else if(eState == OMX_StateLoaded) - { - DEBUG_PRINT_ERROR("\nERROR: OMXCORE-SM: Executing --> Loaded \n"); - 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("\nERROR: OMXCORE-SM: Executing --> WaitForResources \n"); - 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("\nERROR: OMXCORE-SM: Executing --> Executing \n"); - 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("\nERROR: OMXCORE-SM: Executing --> Invalid \n"); - post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorInvalidState; - } - else - { - DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Executing --> %d Not Handled\n",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("\n Pause --> Executing \n"); - 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\n"); - post_event (NULL, NULL, 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("\n Pause --> Idle \n"); - 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("\nERROR: Pause --> loaded \n"); - 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("\nERROR: Pause --> WaitForResources \n"); - 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("\nERROR: Pause --> Pause \n"); - 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("\nERROR: Pause --> Invalid \n"); - post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorInvalidState; - } - else - { - DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Paused --> %d Not Handled\n",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\n"); - } - /* Requesting transition from WaitForResources to WaitForResources */ - else if(eState == OMX_StateWaitForResources) - { - DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->WaitForResources\n"); - 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\n"); - 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\n"); - 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\n"); - 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)\n",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\n"); - 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\n"); - 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\n"); - 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)\n",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("\n execute_omx_flush - %d\n", flushType); - if(flushType == 0 || flushType == OMX_ALL) - { - input_flush_progress = true; - //flush input only - bRet = execute_input_flush(); - } - if(flushType == 1 || flushType == OMX_ALL) - { - //flush output only - output_flush_progress = true; - bRet = execute_output_flush(); - } - 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 p1 = 0; // Parameter - 1 - unsigned p2 = 0; // Parameter - 2 - unsigned ident = 0; - bool bRet = true; - - /*Generate FBD for all Buffers in the FTBq*/ - DEBUG_PRINT_LOW("\n execute_output_flush\n"); - pthread_mutex_lock(&m_lock); - while(m_ftb_q.m_size) - { - m_ftb_q.pop_entry(&p1,&p2,&ident); - - if(ident == OMX_COMPONENT_GENERATE_FTB ) - { - pending_output_buffers++; - fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2); - } - else if(ident == OMX_COMPONENT_GENERATE_FBD) - { - fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1); - } - } - - pthread_mutex_unlock(&m_lock); - /*Check if there are buffers with the Driver*/ - if(dev_flush(PORT_INDEX_OUT)) - { - DEBUG_PRINT_ERROR("\nERROR: 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 p1 = 0; // Parameter - 1 - unsigned p2 = 0; // Parameter - 2 - unsigned ident = 0; - bool bRet = true; - - /*Generate EBD for all Buffers in the ETBq*/ - DEBUG_PRINT_LOW("\n execute_input_flush\n"); - - pthread_mutex_lock(&m_lock); - while(m_etb_q.m_size) - { - m_etb_q.pop_entry(&p1,&p2,&ident); - if(ident == OMX_COMPONENT_GENERATE_ETB) - { - pending_input_buffers++; - empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2); - } - else if(ident == OMX_COMPONENT_GENERATE_EBD) - { - empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1); - } - } - - pthread_mutex_unlock(&m_lock); - /*Check if there are buffers with the Driver*/ - if(dev_flush(PORT_INDEX_IN)) - { - DEBUG_PRINT_ERROR("\nERROR: i/p 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 int p1, - unsigned int p2, - unsigned int id) -{ - bool bRet = false; - - - pthread_mutex_lock(&m_lock); - - if( id == OMX_COMPONENT_GENERATE_FTB || \ - (id == OMX_COMPONENT_GENERATE_FRAME_DONE)) - { - m_ftb_q.insert_entry(p1,p2,id); - } - else if((id == OMX_COMPONENT_GENERATE_ETB) \ - || (id == OMX_COMPONENT_GENERATE_EBD)) - { - m_etb_q.insert_entry(p1,p2,id); - } - else - { - m_cmd_q.insert_entry(p1,p2,id); - } - - bRet = true; - DEBUG_PRINT_LOW("\n Value of this pointer in post_event %p",this); - post_message(this, id); - pthread_mutex_unlock(&m_lock); - - return bRet; -} - -/* ====================================================================== -FUNCTION - omx_venc::GetParameter - -DESCRIPTION - OMX Get Parameter method implementation - -PARAMETERS - . - -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) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - unsigned int height=0,width = 0; - - DEBUG_PRINT_LOW("get_parameter: \n"); - if(m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("ERROR: Get Param in Invalid State\n"); - return OMX_ErrorInvalidState; - } - if(paramData == NULL) - { - DEBUG_PRINT_ERROR("ERROR: Get Param in Invalid paramData \n"); - return OMX_ErrorBadParameter; - } - switch(paramIndex) - { - case OMX_IndexParamPortDefinition: - { - OMX_PARAM_PORTDEFINITIONTYPE *portDefn; - portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData; - - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition\n"); - if(portDefn->nPortIndex == (OMX_U32) PORT_INDEX_IN) - { - DEBUG_PRINT_LOW("m_sInPortDef: size = %d, min cnt = %d, actual cnt = %d", - m_sInPortDef.nBufferSize, m_sInPortDef.nBufferCountMin, - m_sInPortDef.nBufferCountActual); - memcpy(portDefn, &m_sInPortDef, sizeof(m_sInPortDef)); -#ifdef _ANDROID_ICS_ - if(meta_mode_enable) - { - portDefn->nBufferSize = sizeof(encoder_media_buffer_type); - } - - if (mUseProxyColorFormat) { - portDefn->format.video.eColorFormat = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FormatAndroidOpaque; - } -#endif - } - else if(portDefn->nPortIndex == (OMX_U32) PORT_INDEX_OUT) - { - dev_get_buf_req (&m_sOutPortDef.nBufferCountMin, - &m_sOutPortDef.nBufferCountActual, - &m_sOutPortDef.nBufferSize, - m_sOutPortDef.nPortIndex); - DEBUG_PRINT_LOW("m_sOutPortDef: size = %d, min cnt = %d, actual cnt = %d", - m_sOutPortDef.nBufferSize, m_sOutPortDef.nBufferCountMin, - m_sOutPortDef.nBufferCountActual); - memcpy(portDefn, &m_sOutPortDef, sizeof(m_sOutPortDef)); - } - else - { - DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index"); - eRet = OMX_ErrorBadPortIndex; - } - break; - } - case OMX_IndexParamVideoInit: - { - OMX_PORT_PARAM_TYPE *portParamType = - (OMX_PORT_PARAM_TYPE *) paramData; - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit\n"); - - memcpy(portParamType, &m_sPortParam, sizeof(m_sPortParam)); - break; - } - case OMX_IndexParamVideoPortFormat: - { - OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt = - (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData; - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat\n"); - - if(portFmt->nPortIndex == (OMX_U32) PORT_INDEX_IN) - { - int index = portFmt->nIndex; - if(index > 1) - eRet = OMX_ErrorNoMore; - else { - memcpy(portFmt, &m_sInPortFormat, sizeof(m_sInPortFormat)); -#ifdef _ANDROID_ICS_ - if (index == 1) { - //we support two formats - //index 0 - YUV420SP - //index 1 - opaque which internally maps to YUV420SP. - //this can be extended in the future - portFmt->nIndex = index; //restore index set from client - portFmt->eColorFormat = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FormatAndroidOpaque; - } -#endif - } - } - 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: - { - OMX_VIDEO_PARAM_BITRATETYPE* pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData; - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoBitrate\n"); - - 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: - { - OMX_VIDEO_PARAM_MPEG4TYPE* pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData; - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4\n"); - memcpy(pParam, &m_sParamMPEG4, sizeof(m_sParamMPEG4)); - break; - } - case OMX_IndexParamVideoH263: - { - OMX_VIDEO_PARAM_H263TYPE* pParam = (OMX_VIDEO_PARAM_H263TYPE*)paramData; - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263\n"); - memcpy(pParam, &m_sParamH263, sizeof(m_sParamH263)); - break; - } - case OMX_IndexParamVideoAvc: - { - OMX_VIDEO_PARAM_AVCTYPE* pParam = (OMX_VIDEO_PARAM_AVCTYPE*)paramData; - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc\n"); - memcpy(pParam, &m_sParamAVC, sizeof(m_sParamAVC)); - break; - } - case OMX_IndexParamVideoProfileLevelQuerySupported: - { - OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData; - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported\n"); - eRet = get_supported_profile_level(pParam); - if(eRet) - DEBUG_PRINT_ERROR("Invalid entry returned from get_supported_profile_level %d, %d", - pParam->eProfile, pParam->eLevel); - break; - } - case OMX_IndexParamVideoProfileLevelCurrent: - { - OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData; - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelCurrent\n"); - memcpy(pParam, &m_sParamProfileLevel, sizeof(m_sParamProfileLevel)); - break; - } - /*Component should support this port definition*/ - case OMX_IndexParamAudioInit: - { - OMX_PORT_PARAM_TYPE *audioPortParamType = (OMX_PORT_PARAM_TYPE *) paramData; - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit\n"); - memcpy(audioPortParamType, &m_sPortParam_audio, sizeof(m_sPortParam_audio)); - break; - } - /*Component should support this port definition*/ - case OMX_IndexParamImageInit: - { - OMX_PORT_PARAM_TYPE *imagePortParamType = (OMX_PORT_PARAM_TYPE *) paramData; - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit\n"); - 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\n", paramIndex); - eRet =OMX_ErrorUnsupportedIndex; - break; - } - case OMX_IndexParamStandardComponentRole: - { - 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\n",paramIndex); - if(NULL != comp_role->cRole) - { - strlcpy((char*)comp_role->cRole,(const char*)m_cRole,OMX_MAX_STRINGNAME_SIZE); - } - else - { - DEBUG_PRINT_ERROR("ERROR: Getparameter: OMX_IndexParamStandardComponentRole %d is passed with NULL parameter for role\n",paramIndex); - eRet =OMX_ErrorBadParameter; - } - break; - } - /* Added for parameter test */ - case OMX_IndexParamPriorityMgmt: - { - - OMX_PRIORITYMGMTTYPE *priorityMgmType = (OMX_PRIORITYMGMTTYPE *) paramData; - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt\n"); - memcpy(priorityMgmType, &m_sPriorityMgmt, sizeof(m_sPriorityMgmt)); - break; - } - /* Added for parameter test */ - case OMX_IndexParamCompBufferSupplier: - { - OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData; - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier\n"); - 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: - { - OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp = (OMX_VIDEO_PARAM_QUANTIZATIONTYPE*) paramData; - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoQuantization\n"); - memcpy(session_qp, &m_sSessionQuantization, sizeof(m_sSessionQuantization)); - break; - } - - case OMX_IndexParamVideoErrorCorrection: - { - OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* errorresilience = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE*)paramData; - DEBUG_PRINT_LOW("OMX_IndexParamVideoErrorCorrection\n"); - errorresilience->bEnableHEC = m_sErrorCorrection.bEnableHEC; - errorresilience->bEnableResync = m_sErrorCorrection.bEnableResync; - errorresilience->nResynchMarkerSpacing = m_sErrorCorrection.nResynchMarkerSpacing; - break; - } - case OMX_IndexParamVideoIntraRefresh: - { - OMX_VIDEO_PARAM_INTRAREFRESHTYPE* intrarefresh = (OMX_VIDEO_PARAM_INTRAREFRESHTYPE*)paramData; - DEBUG_PRINT_LOW("OMX_IndexParamVideoIntraRefresh\n"); - DEBUG_PRINT_ERROR("OMX_IndexParamVideoIntraRefresh GET\n"); - intrarefresh->eRefreshMode = m_sIntraRefresh.eRefreshMode; - intrarefresh->nCirMBs = m_sIntraRefresh.nCirMBs; - break; - } - case OMX_QcomIndexPortDefn: - //TODO - break; - case OMX_COMPONENT_CAPABILITY_TYPE_INDEX: - { - OMXComponentCapabilityFlagsType *pParam = reinterpret_cast(paramData); - DEBUG_PRINT_LOW("get_parameter: OMX_COMPONENT_CAPABILITY_TYPE_INDEX\n"); - 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; - } -#ifndef MAX_RES_720P - case OMX_QcomIndexParamIndexExtraDataType: - { - DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamIndexExtraDataType"); - QOMX_INDEXEXTRADATATYPE *pParam = (QOMX_INDEXEXTRADATATYPE *)paramData; - if (pParam->nIndex == (OMX_INDEXTYPE)OMX_ExtraDataVideoEncoderSliceInfo) - { - if (pParam->nPortIndex == PORT_INDEX_OUT) - { - pParam->bEnabled = - (OMX_BOOL)((m_sExtraData & VEN_EXTRADATA_SLICEINFO) ? 1 : 0); - 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 - { - DEBUG_PRINT_ERROR("get_parameter: unsupported index (%x), " - "only slice information extradata is supported", pParam->nIndex); - eRet =OMX_ErrorUnsupportedIndex; - } - break; - } -#endif - case QOMX_IndexParamVideoSyntaxHdr: - { - DEBUG_PRINT_HIGH("QOMX_IndexParamVideoSyntaxHdr"); - QOMX_EXTNINDEX_PARAMTYPE* pParam = - reinterpret_cast(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: unknown param %08x\n", paramIndex); - 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 *)&pParam->nDataSize)) - { - DEBUG_PRINT_HIGH("get syntax header successful (hdrlen = %d)", - 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_IndexParamVideoSliceFMO: - default: - { - DEBUG_PRINT_LOW("ERROR: get_parameter: unknown param %08x\n", paramIndex); - eRet =OMX_ErrorUnsupportedIndex; - break; - } - - } - - return eRet; - -} -/* ====================================================================== -FUNCTION - omx_video::GetConfig - -DESCRIPTION - OMX Get Config Method implementation. - -PARAMETERS - . - -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) -{ - //////////////////////////////////////////////////////////////// - // Supported Config Index Type - // ============================================================= - // OMX_IndexConfigVideoBitrate OMX_VIDEO_CONFIG_BITRATETYPE - // OMX_IndexConfigVideoFramerate OMX_CONFIG_FRAMERATETYPE - // OMX_IndexConfigCommonRotate OMX_CONFIG_ROTATIONTYPE - //////////////////////////////////////////////////////////////// - - if(configData == NULL) - { - DEBUG_PRINT_ERROR("ERROR: param is null"); - return OMX_ErrorBadParameter; - } - - if(m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("ERROR: can't be in invalid state"); - return OMX_ErrorIncorrectStateOperation; - } - - //@todo need to validate params - switch(configIndex) - { - case OMX_IndexConfigVideoBitrate: - { - OMX_VIDEO_CONFIG_BITRATETYPE* pParam = reinterpret_cast(configData); - memcpy(pParam, &m_sConfigBitrate, sizeof(m_sConfigBitrate)); - break; - } - case OMX_IndexConfigVideoFramerate: - { - OMX_CONFIG_FRAMERATETYPE* pParam = reinterpret_cast(configData); - memcpy(pParam, &m_sConfigFramerate, sizeof(m_sConfigFramerate)); - break; - } - case OMX_IndexConfigCommonRotate: - { - OMX_CONFIG_ROTATIONTYPE* pParam = reinterpret_cast(configData); - memcpy(pParam, &m_sConfigFrameRotation, sizeof(m_sConfigFrameRotation)); - break; - } - case QOMX_IndexConfigVideoIntraperiod: - { - DEBUG_PRINT_LOW("get_config:QOMX_IndexConfigVideoIntraperiod\n"); - QOMX_VIDEO_INTRAPERIODTYPE* pParam = reinterpret_cast(configData); - memcpy(pParam, &m_sIntraperiod, sizeof(m_sIntraperiod)); - break; - } - default: - DEBUG_PRINT_ERROR("ERROR: unsupported index %d", (int) configIndex); - return OMX_ErrorUnsupportedIndex; - } - return OMX_ErrorNone; - -} - -/* ====================================================================== -FUNCTION - omx_video::GetExtensionIndex - -DESCRIPTION - OMX GetExtensionIndex method implementaion. - -PARAMETERS - . - -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) -{ - if(m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("ERROR: Get Extension Index in Invalid State\n"); - return OMX_ErrorInvalidState; - } -#ifdef MAX_RES_1080P - if (!strncmp(paramName, "OMX.QCOM.index.param.SliceDeliveryMode", - sizeof("OMX.QCOM.index.param.SliceDeliveryMode") - 1)) { - *indexType = (OMX_INDEXTYPE)OMX_QcomIndexEnableSliceDeliveryMode; - return OMX_ErrorNone; - } -#endif -#ifdef _ANDROID_ICS_ - if (!strncmp(paramName, "OMX.google.android.index.storeMetaDataInBuffers",sizeof("OMX.google.android.index.storeMetaDataInBuffers") - 1)) { - *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoEncodeMetaBufferMode; - return OMX_ErrorNone; - } -#endif - return OMX_ErrorNotImplemented; -} - -/* ====================================================================== -FUNCTION - omx_video::GetState - -DESCRIPTION - Returns the state information back to the caller. - -PARAMETERS - . - -RETURN VALUE - Error None if everything is successful. -========================================================================== */ -OMX_ERRORTYPE omx_video::get_state(OMX_IN OMX_HANDLETYPE hComp, - OMX_OUT OMX_STATETYPE* state) -{ - *state = m_state; - DEBUG_PRINT_LOW("get_state: Returning the state %d\n",*state); - return OMX_ErrorNone; -} - -/* ====================================================================== -FUNCTION - omx_video::ComponentTunnelRequest - -DESCRIPTION - OMX Component Tunnel Request method implementation. - -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) -{ - DEBUG_PRINT_ERROR("ERROR: component_tunnel_request Not Implemented\n"); - 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) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - - unsigned i = 0; - unsigned char *buf_addr = NULL; - - DEBUG_PRINT_HIGH("use_input_buffer: port = %d appData = %p bytes = %d buffer = %p",port,appData,bytes,buffer); - if(bytes != m_sInPortDef.nBufferSize) - { - DEBUG_PRINT_ERROR("\nERROR: use_input_buffer: Size Mismatch!! " - "bytes[%d] != Port.nBufferSize[%d]", bytes, 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("\nERROR: calloc() Failed for m_inp_mem_ptr"); - return OMX_ErrorInsufficientResources; - } - - - m_pInput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sInPortDef.nBufferCountActual); - if(m_pInput_pmem == NULL) - { - DEBUG_PRINT_ERROR("\nERROR: 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("\nERROR: 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=NULL; -#endif - } - - } - - for(i=0; i< m_sInPortDef.nBufferCountActual; i++) - { - if(BITMASK_ABSENT(&m_inp_bm_count,i)) - { - break; - } - } - - if(i < m_sInPortDef.nBufferCountActual) - { - - *bufferHdr = (m_inp_mem_ptr + i); - BITMASK_SET(&m_inp_bm_count,i); - - (*bufferHdr)->pBuffer = (OMX_U8 *)buffer; - (*bufferHdr)->nSize = sizeof(OMX_BUFFERHEADERTYPE); - (*bufferHdr)->nVersion.nVersion = OMX_SPEC_VERSION; - (*bufferHdr)->nAllocLen = m_sInPortDef.nBufferSize; - (*bufferHdr)->pAppPrivate = appData; - (*bufferHdr)->nInputPortIndex = PORT_INDEX_IN; - - if(!m_use_input_pmem) - { -#ifdef USE_ION - 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,CACHED); - if(m_pInput_ion[i].ion_device_fd < 0) { - DEBUG_PRINT_ERROR("\nERROR: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("\nERROR: /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 = (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("\nERROR: mmap() Failed"); - close(m_pInput_pmem[i].fd); -#ifdef USE_ION - free_ion_memory(&m_pInput_ion[i]); -#endif - return OMX_ErrorInsufficientResources; - } - } - else - { - OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pParam = reinterpret_cast((*bufferHdr)->pAppPrivate); - DEBUG_PRINT_LOW("Inside qcom_ext with luma:(fd:%d,offset:0x%x)", pParam->pmem_fd, 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("\n DBG:: pParam->pmem_fd = %u, pParam->offset = %u", - pParam->pmem_fd, pParam->offset); - } - else - { - DEBUG_PRINT_ERROR("ERROR: Invalid AppData given for PMEM i/p UseBuffer case"); - return OMX_ErrorBadParameter; - } - } - - DEBUG_PRINT_LOW("\nuse_inp:: bufhdr = %p, pBuffer = %p, m_pInput_pmem[i].buffer = %p", - (*bufferHdr), (*bufferHdr)->pBuffer, m_pInput_pmem[i].buffer); - if( dev_use_buf(&m_pInput_pmem[i],PORT_INDEX_IN,i) != true) - { - DEBUG_PRINT_ERROR("\nERROR: dev_use_buf() Failed for i/p buf"); - return OMX_ErrorInsufficientResources; - } - } - else - { - DEBUG_PRINT_ERROR("\nERROR: All buffers are already used, invalid use_buf call for " - "index = %u", i); - eRet = OMX_ErrorInsufficientResources; - } - - return eRet; -} - - - -/* ====================================================================== -FUNCTION - omx_video::UseOutputBuffer - -DESCRIPTION - Helper function for Use buffer in the input pin - -PARAMETERS - None. - -RETURN VALUE - true/false - -========================================================================== */ -OMX_ERRORTYPE omx_video::use_output_buffer( - OMX_IN OMX_HANDLETYPE hComp, - OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, - OMX_IN OMX_U32 port, - OMX_IN OMX_PTR appData, - OMX_IN OMX_U32 bytes, - OMX_IN OMX_U8* buffer) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header - unsigned i= 0; // Temporary counter - unsigned char *buf_addr = NULL; -#ifdef _MSM8974_ - int align_size; -#endif - - DEBUG_PRINT_HIGH("\n Inside use_output_buffer()"); - if(bytes != m_sOutPortDef.nBufferSize) - { - DEBUG_PRINT_ERROR("\nERROR: use_output_buffer: Size Mismatch!! " - "bytes[%d] != Port.nBufferSize[%d]", bytes, m_sOutPortDef.nBufferSize); - return OMX_ErrorBadParameter; - } - - if(!m_out_mem_ptr) - { - output_use_buffer = true; - int nBufHdrSize = 0; - - DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)\n",m_sOutPortDef.nBufferCountActual); - nBufHdrSize = m_sOutPortDef.nBufferCountActual * sizeof(OMX_BUFFERHEADERTYPE); - /* - * Memory for output side involves the following: - * 1. Array of Buffer Headers - * 2. Bitmask array to hold the buffer allocation details - * In order to minimize the memory management entire allocation - * is done in one step. - */ - //OMX Buffer header - m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1); - if(m_out_mem_ptr == NULL) - { - DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_out_mem_ptr"); - return OMX_ErrorInsufficientResources; - } - - m_pOutput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sOutPortDef.nBufferCountActual); - if(m_pOutput_pmem == NULL) - { - DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pOutput_pmem"); - return OMX_ErrorInsufficientResources; - } -#ifdef USE_ION - m_pOutput_ion = (struct venc_ion *) calloc(sizeof (struct venc_ion), m_sOutPortDef.nBufferCountActual); - if(m_pOutput_ion == NULL) - { - DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pOutput_ion"); - return OMX_ErrorInsufficientResources; - } -#endif - if(m_out_mem_ptr) - { - bufHdr = m_out_mem_ptr; - DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr); - // Settting the entire storage nicely - for(i=0; i < m_sOutPortDef.nBufferCountActual ; i++) - { - bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE); - bufHdr->nVersion.nVersion = OMX_SPEC_VERSION; - bufHdr->nAllocLen = bytes; - bufHdr->nFilledLen = 0; - bufHdr->pAppPrivate = appData; - bufHdr->nOutputPortIndex = PORT_INDEX_OUT; - bufHdr->pBuffer = NULL; - bufHdr++; - m_pOutput_pmem[i].fd = -1; -#ifdef USE_ION - m_pOutput_ion[i].ion_device_fd =-1; - m_pOutput_ion[i].fd_ion_data.fd=-1; - m_pOutput_ion[i].ion_alloc_data.handle =NULL; -#endif - } - } - else - { - DEBUG_PRINT_ERROR("ERROR: Output buf mem alloc failed[0x%x]\n",m_out_mem_ptr); - eRet = OMX_ErrorInsufficientResources; - } - } - - for(i=0; i< m_sOutPortDef.nBufferCountActual; i++) - { - if(BITMASK_ABSENT(&m_out_bm_count,i)) - { - break; - } - } - - if(eRet == OMX_ErrorNone) - { - if(i < m_sOutPortDef.nBufferCountActual) - { - *bufferHdr = (m_out_mem_ptr + i ); - (*bufferHdr)->pBuffer = (OMX_U8 *)buffer; - (*bufferHdr)->pAppPrivate = appData; - BITMASK_SET(&m_out_bm_count,i); - - if(!m_use_output_pmem) - { -#ifdef USE_ION -#ifdef _MSM8974_ - align_size = ((m_sOutPortDef.nBufferSize + 4095)/4096) * 4096; - m_pOutput_ion[i].ion_device_fd = alloc_map_ion_memory(align_size, - &m_pOutput_ion[i].ion_alloc_data, - &m_pOutput_ion[i].fd_ion_data,UNCACHED); -#else - m_pOutput_ion[i].ion_device_fd = alloc_map_ion_memory( - m_sOutPortDef.nBufferSize, - &m_pOutput_ion[i].ion_alloc_data, - &m_pOutput_ion[i].fd_ion_data,CACHED); -#endif - if(m_pOutput_ion[i].ion_device_fd < 0) { - DEBUG_PRINT_ERROR("\nERROR:ION device open() Failed"); - return OMX_ErrorInsufficientResources; - } - m_pOutput_pmem[i].fd = m_pOutput_ion[i].fd_ion_data.fd; -#else - m_pOutput_pmem[i].fd = open (MEM_DEVICE,O_RDWR); - - if(m_pOutput_pmem[i].fd == 0) - { - m_pOutput_pmem[i].fd = open (MEM_DEVICE,O_RDWR); - } - - if(m_pOutput_pmem[i].fd < 0) - { - DEBUG_PRINT_ERROR("\nERROR: /dev/pmem_adsp open() Failed"); - return OMX_ErrorInsufficientResources; - } -#endif - m_pOutput_pmem[i].size = m_sOutPortDef.nBufferSize; - m_pOutput_pmem[i].offset = 0; -#ifdef _MSM8974_ - m_pOutput_pmem[i].buffer = (unsigned char *)mmap(NULL,align_size,PROT_READ|PROT_WRITE, - MAP_SHARED,m_pOutput_pmem[i].fd,0); -#else - m_pOutput_pmem[i].buffer = (unsigned char *)mmap(NULL,m_pOutput_pmem[i].size,PROT_READ|PROT_WRITE, - MAP_SHARED,m_pOutput_pmem[i].fd,0); -#endif - if(m_pOutput_pmem[i].buffer == MAP_FAILED) - { - DEBUG_PRINT_ERROR("\nERROR: mmap() Failed"); - close(m_pOutput_pmem[i].fd); -#ifdef USE_ION - free_ion_memory(&m_pOutput_ion[i]); -#endif - return OMX_ErrorInsufficientResources; - } - } - else - { - OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pParam = reinterpret_cast((*bufferHdr)->pAppPrivate); - DEBUG_PRINT_LOW("Inside qcom_ext pParam:0x%x )", pParam); - - if(pParam) - { - DEBUG_PRINT_LOW("Inside qcom_ext with luma:(fd:%d,offset:0x%x)", pParam->pmem_fd, pParam->offset); - m_pOutput_pmem[i].fd = pParam->pmem_fd; - m_pOutput_pmem[i].offset = pParam->offset; - m_pOutput_pmem[i].size = m_sOutPortDef.nBufferSize; - m_pOutput_pmem[i].buffer = (unsigned char *)buffer; - } - else - { - DEBUG_PRINT_ERROR("ERROR: Invalid AppData given for PMEM o/p UseBuffer case"); - return OMX_ErrorBadParameter; - } - buf_addr = (unsigned char *)buffer; - } - - DEBUG_PRINT_LOW("\n use_out:: bufhdr = %p, pBuffer = %p, m_pOutput_pmem[i].buffer = %p", - (*bufferHdr), (*bufferHdr)->pBuffer, m_pOutput_pmem[i].buffer); - if(dev_use_buf(&m_pOutput_pmem[i],PORT_INDEX_OUT,i) != true) - { - DEBUG_PRINT_ERROR("ERROR: dev_use_buf Failed for o/p buf"); - return OMX_ErrorInsufficientResources; - } - } - else - { - DEBUG_PRINT_ERROR("ERROR: All o/p Buffers have been Used, invalid use_buf call for " - "index = %u", i); - eRet = OMX_ErrorInsufficientResources; - } - } - return eRet; -} - - -/* ====================================================================== -FUNCTION - omx_video::UseBuffer - -DESCRIPTION - OMX Use Buffer method implementation. - -PARAMETERS - . - -RETURN VALUE - OMX Error None , if everything successful. - -========================================================================== */ -OMX_ERRORTYPE omx_video::use_buffer( - OMX_IN OMX_HANDLETYPE hComp, - OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, - OMX_IN OMX_U32 port, - OMX_IN OMX_PTR appData, - OMX_IN OMX_U32 bytes, - OMX_IN OMX_U8* buffer) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - if(m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("ERROR: Use Buffer in Invalid State\n"); - return OMX_ErrorInvalidState; - } - if(port == PORT_INDEX_IN) - { - eRet = use_input_buffer(hComp,bufferHdr,port,appData,bytes,buffer); - } - else if(port == PORT_INDEX_OUT) - { - eRet = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); - } - else - { - DEBUG_PRINT_ERROR("ERROR: Invalid Port Index received %d\n",(int)port); - eRet = OMX_ErrorBadPortIndex; - } - - if(eRet == OMX_ErrorNone) - { - if(allocate_done()) - { - if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) - { - // Send the callback now - BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING); - post_event(OMX_CommandStateSet,OMX_StateIdle, - OMX_COMPONENT_GENERATE_EVENT); - } - } - if(port == PORT_INDEX_IN && m_sInPortDef.bPopulated) - { - if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) - { - BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING); - post_event(OMX_CommandPortEnable, - PORT_INDEX_IN, - OMX_COMPONENT_GENERATE_EVENT); - } - - } - else if(port == PORT_INDEX_OUT && m_sOutPortDef.bPopulated) - { - if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) - { - BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING); - post_event(OMX_CommandPortEnable, - PORT_INDEX_OUT, - OMX_COMPONENT_GENERATE_EVENT); - m_event_port_settings_sent = false; - } - } - } - return eRet; -} - -OMX_ERRORTYPE omx_video::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr) -{ - unsigned int index = 0; - OMX_U8 *temp_buff ; - - if(bufferHdr == NULL || m_inp_mem_ptr == NULL) - { - DEBUG_PRINT_ERROR("ERROR: free_input: Invalid bufferHdr[%p] or m_inp_mem_ptr[%p]", - bufferHdr, m_inp_mem_ptr); - return OMX_ErrorBadParameter; - } - - index = bufferHdr - m_inp_mem_ptr; -#ifdef _ANDROID_ICS_ - if(meta_mode_enable) - { - if(index < m_sInPortDef.nBufferCountActual) - { - memset(&meta_buffer_hdr[index], 0, sizeof(meta_buffer_hdr[index])); - memset(&meta_buffers[index], 0, sizeof(meta_buffers[index])); - } - return OMX_ErrorNone; - } -#endif - if(index < m_sInPortDef.nBufferCountActual && - dev_free_buf(&m_pInput_pmem[index],PORT_INDEX_IN) != true) - { - DEBUG_PRINT_ERROR("\nERROR: dev_free_buf() Failed for i/p buf"); - } - - if(index < m_sInPortDef.nBufferCountActual && m_pInput_pmem) - { - if(m_pInput_pmem[index].fd > 0 && input_use_buffer == false) - { - DEBUG_PRINT_LOW("\n FreeBuffer:: i/p AllocateBuffer case"); - munmap (m_pInput_pmem[index].buffer,m_pInput_pmem[index].size); - close (m_pInput_pmem[index].fd); -#ifdef USE_ION - free_ion_memory(&m_pInput_ion[index]); -#endif - m_pInput_pmem[index].fd = -1; - } - else if(m_pInput_pmem[index].fd > 0 && (input_use_buffer == true && - m_use_input_pmem == OMX_FALSE)) - { - DEBUG_PRINT_LOW("\n FreeBuffer:: i/p Heap UseBuffer case"); - if(dev_free_buf(&m_pInput_pmem[index],PORT_INDEX_IN) != true) - { - DEBUG_PRINT_ERROR("\nERROR: dev_free_buf() Failed for i/p buf"); - } - munmap (m_pInput_pmem[index].buffer,m_pInput_pmem[index].size); - close (m_pInput_pmem[index].fd); -#ifdef USE_ION - free_ion_memory(&m_pInput_ion[index]); -#endif - m_pInput_pmem[index].fd = -1; - } - else - { - DEBUG_PRINT_LOW("\n FreeBuffer:: fd is invalid or i/p PMEM UseBuffer case"); - } - } - return OMX_ErrorNone; -} - -OMX_ERRORTYPE omx_video::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr) -{ - unsigned int index = 0; - OMX_U8 *temp_buff ; - - if(bufferHdr == NULL || m_out_mem_ptr == NULL) - { - DEBUG_PRINT_ERROR("ERROR: free_output: Invalid bufferHdr[%p] or m_out_mem_ptr[%p]", - bufferHdr, m_out_mem_ptr); - return OMX_ErrorBadParameter; - } - index = bufferHdr - m_out_mem_ptr; - - if(index < m_sOutPortDef.nBufferCountActual && - dev_free_buf(&m_pOutput_pmem[index],PORT_INDEX_OUT) != true) - { - DEBUG_PRINT_ERROR("ERROR: dev_free_buf Failed for o/p buf"); - } - - if(index < m_sOutPortDef.nBufferCountActual && m_pOutput_pmem) - { - if(m_pOutput_pmem[index].fd > 0 && output_use_buffer == false ) - { - DEBUG_PRINT_LOW("\n FreeBuffer:: o/p AllocateBuffer case"); - munmap (m_pOutput_pmem[index].buffer,m_pOutput_pmem[index].size); - close (m_pOutput_pmem[index].fd); -#ifdef USE_ION - free_ion_memory(&m_pOutput_ion[index]); -#endif - m_pOutput_pmem[index].fd = -1; - } - else if( m_pOutput_pmem[index].fd > 0 && (output_use_buffer == true - && m_use_output_pmem == OMX_FALSE)) - { - DEBUG_PRINT_LOW("\n FreeBuffer:: o/p Heap UseBuffer case"); - if(dev_free_buf(&m_pOutput_pmem[index],PORT_INDEX_OUT) != true) - { - DEBUG_PRINT_ERROR("ERROR: dev_free_buf Failed for o/p buf"); - } - munmap (m_pOutput_pmem[index].buffer,m_pOutput_pmem[index].size); - close (m_pOutput_pmem[index].fd); -#ifdef USE_ION - free_ion_memory(&m_pOutput_ion[index]); -#endif - m_pOutput_pmem[index].fd = -1; - } - else - { - DEBUG_PRINT_LOW("\n FreeBuffer:: fd is invalid or o/p PMEM UseBuffer case"); - } - } - return OMX_ErrorNone; -} -#ifdef _ANDROID_ICS_ -OMX_ERRORTYPE omx_video::allocate_input_meta_buffer( - OMX_BUFFERHEADERTYPE **bufferHdr, - OMX_PTR appData, - OMX_U32 bytes) -{ - unsigned index = 0; - if(!bufferHdr || bytes != sizeof(encoder_media_buffer_type)) - { - DEBUG_PRINT_ERROR("wrong params allocate_input_meta_buffer Hdr %p len %d", - bufferHdr,bytes); - return OMX_ErrorBadParameter; - } - if(!m_inp_mem_ptr) - m_inp_mem_ptr = meta_buffer_hdr; - for(index = 0;((index < m_sInPortDef.nBufferCountActual) && - meta_buffer_hdr[index].pBuffer); index++); - if(index == m_sInPortDef.nBufferCountActual) - { - DEBUG_PRINT_ERROR("All buffers are allocated input_meta_buffer"); - return OMX_ErrorBadParameter; - } - BITMASK_SET(&m_inp_bm_count,index); - *bufferHdr = &meta_buffer_hdr[index]; - memset(&meta_buffer_hdr[index], 0, sizeof(meta_buffer_hdr[index])); - meta_buffer_hdr[index].nSize = sizeof(meta_buffer_hdr[index]); - meta_buffer_hdr[index].nAllocLen = bytes; - meta_buffer_hdr[index].nVersion.nVersion = OMX_SPEC_VERSION; - meta_buffer_hdr[index].nInputPortIndex = PORT_INDEX_IN; - meta_buffer_hdr[index].pBuffer = (OMX_U8*)&meta_buffers[index]; - meta_buffer_hdr[index].pAppPrivate = appData; - return OMX_ErrorNone; -} -#endif -/* ====================================================================== -FUNCTION - omx_venc::AllocateInputBuffer - -DESCRIPTION - Helper function for allocate buffer in the input pin - -PARAMETERS - None. - -RETURN VALUE - true/false - -========================================================================== */ -OMX_ERRORTYPE omx_video::allocate_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_ERRORTYPE eRet = OMX_ErrorNone; - unsigned i = 0; - - DEBUG_PRINT_HIGH("\n allocate_input_buffer()::"); - if(bytes != m_sInPortDef.nBufferSize) - { - DEBUG_PRINT_ERROR("\nERROR: Buffer size mismatch error: bytes[%u] != nBufferSize[%u]\n", - bytes, m_sInPortDef.nBufferSize); - return OMX_ErrorBadParameter; - } - - if(!m_inp_mem_ptr) - { - DEBUG_PRINT_HIGH("%s: size = %d, actual cnt %d", __FUNCTION__, - m_sInPortDef.nBufferSize, m_sInPortDef.nBufferCountActual); - m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \ - calloc( (sizeof(OMX_BUFFERHEADERTYPE)), m_sInPortDef.nBufferCountActual); - if(m_inp_mem_ptr == NULL) - { - DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_inp_mem_ptr"); - return OMX_ErrorInsufficientResources; - } - - m_pInput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sInPortDef.nBufferCountActual); - - if(m_pInput_pmem == NULL) - { - DEBUG_PRINT_ERROR("\nERROR: 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("\nERROR: 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=NULL; -#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); - (*bufferHdr)->nSize = sizeof(OMX_BUFFERHEADERTYPE); - (*bufferHdr)->nVersion.nVersion = OMX_SPEC_VERSION; - (*bufferHdr)->nAllocLen = m_sInPortDef.nBufferSize; - (*bufferHdr)->pAppPrivate = appData; - (*bufferHdr)->nInputPortIndex = PORT_INDEX_IN; - -#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,CACHED); - if(m_pInput_ion[i].ion_device_fd < 0) { - DEBUG_PRINT_ERROR("\nERROR: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("\nERROR: /dev/pmem_adsp open() Failed\n"); - return OMX_ErrorInsufficientResources; - } -#endif - m_pInput_pmem[i].size = m_sInPortDef.nBufferSize; - m_pInput_pmem[i].offset = 0; - - 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("\nERROR: mmap FAILED= %d\n", errno); - close(m_pInput_pmem[i].fd); -#ifdef USE_ION - free_ion_memory(&m_pInput_ion[i]); -#endif - return OMX_ErrorInsufficientResources; - } - - (*bufferHdr)->pBuffer = (OMX_U8 *)m_pInput_pmem[i].buffer; - - BITMASK_SET(&m_inp_bm_count,i); - //here change the I/P param here from buf_adr to pmem - if( dev_use_buf(&m_pInput_pmem[i],PORT_INDEX_IN,i) != true) - { - DEBUG_PRINT_ERROR("\nERROR: dev_use_buf FAILED for i/p buf\n"); - return OMX_ErrorInsufficientResources; - } - } - else - { - DEBUG_PRINT_ERROR("\nERROR: All i/p buffers are allocated, invalid allocate buf call" - "for index [%d]\n", i); - eRet = OMX_ErrorInsufficientResources; - } - - return eRet; -} - - -/* ====================================================================== -FUNCTION - omx_venc::AllocateOutputBuffer - -DESCRIPTION - Helper fn for AllocateBuffer in the output pin - -PARAMETERS - . - -RETURN VALUE - OMX Error None if everything went well. - -========================================================================== */ -OMX_ERRORTYPE omx_video::allocate_output_buffer( - OMX_IN OMX_HANDLETYPE hComp, - OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, - OMX_IN OMX_U32 port, - OMX_IN OMX_PTR appData, - OMX_IN OMX_U32 bytes) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header - unsigned i= 0; // Temporary counter -#ifdef _MSM8974_ - int align_size; -#endif - DEBUG_PRINT_HIGH("\n allocate_output_buffer()for %d bytes", bytes); - if(!m_out_mem_ptr) - { - int nBufHdrSize = 0; - DEBUG_PRINT_HIGH("%s: size = %d, actual cnt %d", __FUNCTION__, - m_sOutPortDef.nBufferSize, m_sOutPortDef.nBufferCountActual); - nBufHdrSize = m_sOutPortDef.nBufferCountActual * sizeof(OMX_BUFFERHEADERTYPE); - - /* - * Memory for output side involves the following: - * 1. Array of Buffer Headers - * 2. Bitmask array to hold the buffer allocation details - * In order to minimize the memory management entire allocation - * is done in one step. - */ - m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1); - -#ifdef USE_ION - m_pOutput_ion = (struct venc_ion *) calloc(sizeof (struct venc_ion), m_sOutPortDef.nBufferCountActual); - if(m_pOutput_ion == NULL) - { - DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pOutput_ion"); - return OMX_ErrorInsufficientResources; - } -#endif - m_pOutput_pmem = (struct pmem *) calloc(sizeof(struct pmem), m_sOutPortDef.nBufferCountActual); - if(m_pOutput_pmem == NULL) - { - DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pOutput_pmem"); - return OMX_ErrorInsufficientResources; - } - if(m_out_mem_ptr && m_pOutput_pmem) - { - bufHdr = m_out_mem_ptr; - - for(i=0; i < m_sOutPortDef.nBufferCountActual ; i++) - { - bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE); - bufHdr->nVersion.nVersion = OMX_SPEC_VERSION; - // Set the values when we determine the right HxW param - bufHdr->nAllocLen = bytes; - bufHdr->nFilledLen = 0; - bufHdr->pAppPrivate = appData; - bufHdr->nOutputPortIndex = PORT_INDEX_OUT; - bufHdr->pBuffer = NULL; - bufHdr++; - m_pOutput_pmem[i].fd = -1; -#ifdef USE_ION - m_pOutput_ion[i].ion_device_fd =-1; - m_pOutput_ion[i].fd_ion_data.fd=-1; - m_pOutput_ion[i].ion_alloc_data.handle =NULL; -#endif - } - } - else - { - DEBUG_PRINT_ERROR("ERROR: calloc() failed for m_out_mem_ptr/m_pOutput_pmem"); - eRet = OMX_ErrorInsufficientResources; - } - } - - DEBUG_PRINT_HIGH("\n actual cnt = %u", m_sOutPortDef.nBufferCountActual); - for(i=0; i< m_sOutPortDef.nBufferCountActual; i++) - { - if(BITMASK_ABSENT(&m_out_bm_count,i)) - { - DEBUG_PRINT_LOW("\n Found a Free Output Buffer %d",i); - break; - } - } - if(eRet == OMX_ErrorNone) - { - if(i < m_sOutPortDef.nBufferCountActual) - { -#ifdef USE_ION -#ifdef _MSM8974_ - align_size = ((m_sOutPortDef.nBufferSize + 4095)/4096) * 4096; - m_pOutput_ion[i].ion_device_fd = alloc_map_ion_memory(align_size, - &m_pOutput_ion[i].ion_alloc_data, - &m_pOutput_ion[i].fd_ion_data,UNCACHED); -#else - m_pOutput_ion[i].ion_device_fd = alloc_map_ion_memory(m_sOutPortDef.nBufferSize, - &m_pOutput_ion[i].ion_alloc_data, - &m_pOutput_ion[i].fd_ion_data,CACHED); -#endif - if(m_pOutput_ion[i].ion_device_fd < 0) { - DEBUG_PRINT_ERROR("\nERROR:ION device open() Failed"); - return OMX_ErrorInsufficientResources; - } - - m_pOutput_pmem[i].fd = m_pOutput_ion[i].fd_ion_data.fd; -#else - m_pOutput_pmem[i].fd = open (MEM_DEVICE,O_RDWR); - if(m_pOutput_pmem[i].fd == 0) - { - m_pOutput_pmem[i].fd = open (MEM_DEVICE,O_RDWR); - } - - if(m_pOutput_pmem[i].fd < 0) - { - DEBUG_PRINT_ERROR("\nERROR: /dev/pmem_adsp open() failed"); - return OMX_ErrorInsufficientResources; - } -#endif - m_pOutput_pmem[i].size = m_sOutPortDef.nBufferSize; - m_pOutput_pmem[i].offset = 0; -#ifdef _MSM8974_ - m_pOutput_pmem[i].buffer = (unsigned char *)mmap(NULL,align_size,PROT_READ|PROT_WRITE, - MAP_SHARED,m_pOutput_pmem[i].fd,0); -#else - m_pOutput_pmem[i].buffer = (unsigned char *)mmap(NULL,m_pOutput_pmem[i].size,PROT_READ|PROT_WRITE, - MAP_SHARED,m_pOutput_pmem[i].fd,0); -#endif - if(m_pOutput_pmem[i].buffer == MAP_FAILED) - { - DEBUG_PRINT_ERROR("\nERROR: MMAP_FAILED in o/p alloc buffer"); - close (m_pOutput_pmem[i].fd); -#ifdef USE_ION - free_ion_memory(&m_pOutput_ion[i]); -#endif - return OMX_ErrorInsufficientResources; - } - - *bufferHdr = (m_out_mem_ptr + i ); - (*bufferHdr)->pBuffer = (OMX_U8 *)m_pOutput_pmem[i].buffer; - (*bufferHdr)->pAppPrivate = appData; - - BITMASK_SET(&m_out_bm_count,i); - - if(dev_use_buf(&m_pOutput_pmem[i],PORT_INDEX_OUT,i) != true) - { - DEBUG_PRINT_ERROR("\nERROR: dev_use_buf FAILED for o/p buf"); - return OMX_ErrorInsufficientResources; - } - } - else - { - DEBUG_PRINT_ERROR("\nERROR: All o/p buffers are allocated, invalid allocate buf call" - "for index [%d]\n", i); - } - } - - return eRet; -} - - -// AllocateBuffer -- API Call -/* ====================================================================== -FUNCTION - omx_video::AllocateBuffer - -DESCRIPTION - Returns zero if all the buffers released.. - -PARAMETERS - None. - -RETURN VALUE - true/false - -========================================================================== */ -OMX_ERRORTYPE omx_video::allocate_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_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type - - DEBUG_PRINT_LOW("\n Allocate buffer of size = %d on port %d \n", bytes, (int)port); - if(m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("ERROR: Allocate Buf in Invalid State\n"); - return OMX_ErrorInvalidState; - } - - // What if the client calls again. - if(port == PORT_INDEX_IN) - { -#ifdef _ANDROID_ICS_ - if(meta_mode_enable) - eRet = allocate_input_meta_buffer(bufferHdr,appData,bytes); - else -#endif - eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes); - } - else if(port == PORT_INDEX_OUT) - { - eRet = allocate_output_buffer(hComp,bufferHdr,port,appData,bytes); - } - else - { - DEBUG_PRINT_ERROR("ERROR: Invalid Port Index received %d\n",(int)port); - eRet = OMX_ErrorBadPortIndex; - } - DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done"); - if(eRet == OMX_ErrorNone) - { - if(allocate_done()) - { - if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) - { - // Send the callback now - BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING); - post_event(OMX_CommandStateSet,OMX_StateIdle, - OMX_COMPONENT_GENERATE_EVENT); - } - } - if(port == PORT_INDEX_IN && m_sInPortDef.bPopulated) - { - if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) - { - BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING); - post_event(OMX_CommandPortEnable, - PORT_INDEX_IN, - OMX_COMPONENT_GENERATE_EVENT); - } - } - if(port == PORT_INDEX_OUT && m_sOutPortDef.bPopulated) - { - if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) - { - BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING); - post_event(OMX_CommandPortEnable, - PORT_INDEX_OUT, - OMX_COMPONENT_GENERATE_EVENT); - m_event_port_settings_sent = false; - } - } - } - DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d\n",eRet); - return eRet; -} - - -// Free Buffer - API call -/* ====================================================================== -FUNCTION - omx_video::FreeBuffer - -DESCRIPTION - -PARAMETERS - None. - -RETURN VALUE - true/false - -========================================================================== */ -OMX_ERRORTYPE omx_video::free_buffer(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_U32 port, - OMX_IN OMX_BUFFERHEADERTYPE* buffer) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - unsigned int nPortIndex; - - DEBUG_PRINT_LOW("In for decoder free_buffer \n"); - - if(m_state == OMX_StateIdle && - (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) - { - DEBUG_PRINT_LOW(" free buffer while Component in Loading pending\n"); - } - else if((m_sInPortDef.bEnabled == OMX_FALSE && port == PORT_INDEX_IN)|| - (m_sOutPortDef.bEnabled == OMX_FALSE && port == PORT_INDEX_OUT)) - { - DEBUG_PRINT_LOW("Free Buffer while port %d disabled\n", port); - } - else if(m_state == OMX_StateExecuting || m_state == OMX_StatePause) - { - DEBUG_PRINT_ERROR("ERROR: Invalid state to free buffer,ports need to be disabled\n"); - post_event(OMX_EventError, - OMX_ErrorPortUnpopulated, - OMX_COMPONENT_GENERATE_EVENT); - - return eRet; - } - else - { - DEBUG_PRINT_ERROR("ERROR: Invalid state to free buffer,port lost Buffers\n"); - post_event(OMX_EventError, - OMX_ErrorPortUnpopulated, - OMX_COMPONENT_GENERATE_EVENT); - } - - if(port == PORT_INDEX_IN) - { - // check if the buffer is valid - nPortIndex = buffer - m_inp_mem_ptr; - - DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d, actual cnt %d \n", - nPortIndex, m_sInPortDef.nBufferCountActual); - if(nPortIndex < m_sInPortDef.nBufferCountActual) - { - // Clear the bit associated with it. - BITMASK_CLEAR(&m_inp_bm_count,nPortIndex); - free_input_buffer (buffer); - m_sInPortDef.bPopulated = OMX_FALSE; - - /*Free the Buffer Header*/ - if(release_input_done() -#ifdef _ANDROID_ICS_ - && !meta_mode_enable -#endif - ) - { - input_use_buffer = false; - if(m_inp_mem_ptr) - { - DEBUG_PRINT_LOW("Freeing m_inp_mem_ptr\n"); - free (m_inp_mem_ptr); - m_inp_mem_ptr = NULL; - } - if(m_pInput_pmem) - { - DEBUG_PRINT_LOW("Freeing m_pInput_pmem\n"); - free(m_pInput_pmem); - m_pInput_pmem = NULL; - } -#ifdef USE_ION - if(m_pInput_ion) - { - DEBUG_PRINT_LOW("Freeing m_pInput_ion\n"); - free(m_pInput_ion); - m_pInput_ion = NULL; - } -#endif - } - } - else - { - DEBUG_PRINT_ERROR("ERROR: free_buffer ,Port Index Invalid\n"); - eRet = OMX_ErrorBadPortIndex; - } - - if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING) - && release_input_done()) - { - DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n"); - BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING); - post_event(OMX_CommandPortDisable, - PORT_INDEX_IN, - OMX_COMPONENT_GENERATE_EVENT); - } - } - else if(port == PORT_INDEX_OUT) - { - // check if the buffer is valid - nPortIndex = buffer - (OMX_BUFFERHEADERTYPE*)m_out_mem_ptr; - - DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d, actual cnt %d \n", - nPortIndex, m_sOutPortDef.nBufferCountActual); - if(nPortIndex < m_sOutPortDef.nBufferCountActual) - { - // Clear the bit associated with it. - BITMASK_CLEAR(&m_out_bm_count,nPortIndex); - m_sOutPortDef.bPopulated = OMX_FALSE; - free_output_buffer (buffer); - - if(release_output_done()) - { - output_use_buffer = false; - if(m_out_mem_ptr) - { - DEBUG_PRINT_LOW("Freeing m_out_mem_ptr\n"); - free (m_out_mem_ptr); - m_out_mem_ptr = NULL; - } - if(m_pOutput_pmem) - { - DEBUG_PRINT_LOW("Freeing m_pOutput_pmem\n"); - free(m_pOutput_pmem); - m_pOutput_pmem = NULL; - } -#ifdef USE_ION - if(m_pOutput_ion) - { - DEBUG_PRINT_LOW("Freeing m_pOutput_ion\n"); - free(m_pOutput_ion); - m_pOutput_ion = NULL; - } -#endif - } - } - else - { - DEBUG_PRINT_ERROR("ERROR: free_buffer , Port Index Invalid\n"); - eRet = OMX_ErrorBadPortIndex; - } - if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING) - && release_output_done() ) - { - DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it\n"); - - DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n"); - BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING); - post_event(OMX_CommandPortDisable, - PORT_INDEX_OUT, - OMX_COMPONENT_GENERATE_EVENT); - - } - } - else - { - eRet = OMX_ErrorBadPortIndex; - } - if((eRet == OMX_ErrorNone) && - (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) - { - if(release_done()) - { - if(dev_stop() != 0) - { - DEBUG_PRINT_ERROR("ERROR: dev_stop() FAILED\n"); - eRet = OMX_ErrorHardware; - } - // Send the callback now - BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING); - post_event(OMX_CommandStateSet, OMX_StateLoaded, - OMX_COMPONENT_GENERATE_EVENT); - } - } - - return eRet; -} - - -/* ====================================================================== -FUNCTION - omx_video::EmptyThisBuffer - -DESCRIPTION - This routine is used to push the encoded video frames to - the video decoder. - -PARAMETERS - None. - -RETURN VALUE - OMX Error None if everything went successful. - -========================================================================== */ -OMX_ERRORTYPE omx_video::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_BUFFERHEADERTYPE* buffer) -{ - OMX_ERRORTYPE ret1 = OMX_ErrorNone; - unsigned int nBufferIndex ; - - DEBUG_PRINT_LOW("\n ETB: buffer = %p, buffer->pBuffer[%p]\n", buffer, buffer->pBuffer); - if(m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("ERROR: Empty this buffer in Invalid State\n"); - return OMX_ErrorInvalidState; - } - - if (buffer == NULL || (buffer->nSize != sizeof(OMX_BUFFERHEADERTYPE))) - { - DEBUG_PRINT_ERROR("\nERROR: omx_video::etb--> buffer is null or buffer size is invalid"); - return OMX_ErrorBadParameter; - } - - if(buffer->nVersion.nVersion != OMX_SPEC_VERSION) - { - DEBUG_PRINT_ERROR("\nERROR: omx_video::etb--> OMX Version Invalid"); - return OMX_ErrorVersionMismatch; - } - - if (buffer->nInputPortIndex != (OMX_U32)PORT_INDEX_IN) - { - DEBUG_PRINT_ERROR("\nERROR: Bad port index to call empty_this_buffer"); - return OMX_ErrorBadPortIndex; - } - if(!m_sInPortDef.bEnabled) - { - DEBUG_PRINT_ERROR("\nERROR: Cannot call empty_this_buffer while I/P port is disabled"); - return OMX_ErrorIncorrectStateOperation; - } - - nBufferIndex = buffer - m_inp_mem_ptr; - - if(nBufferIndex > m_sInPortDef.nBufferCountActual ) - { - DEBUG_PRINT_ERROR("ERROR: ETB: Invalid buffer index[%d]\n", nBufferIndex); - return OMX_ErrorBadParameter; - } - - m_etb_count++; - DEBUG_PRINT_LOW("\n DBG: i/p nTimestamp = %u", (unsigned)buffer->nTimeStamp); - post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB); - return OMX_ErrorNone; -} - - -/* ====================================================================== -FUNCTION - omx_video::empty_this_buffer_proxy - -DESCRIPTION - This routine is used to push the encoded video frames to - the video decoder. - -PARAMETERS - None. - -RETURN VALUE - OMX Error None if everything went successful. - -========================================================================== */ -OMX_ERRORTYPE omx_video::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_BUFFERHEADERTYPE* buffer) -{ - OMX_U8 *pmem_data_buf = NULL; - int push_cnt = 0; - unsigned nBufIndex = 0; - OMX_ERRORTYPE ret = OMX_ErrorNone; - - DEBUG_PRINT_LOW("\n ETBProxy: buffer->pBuffer[%p]\n", buffer->pBuffer); - - if(buffer == NULL) - { - DEBUG_PRINT_ERROR("\nERROR: ETBProxy: Invalid buffer[%p]\n", buffer); - return OMX_ErrorBadParameter; - } - - nBufIndex = buffer - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr); - - if(nBufIndex >= m_sInPortDef.nBufferCountActual) - { - DEBUG_PRINT_ERROR("\nERROR: ETBProxy: Invalid bufindex = %u\n", nBufIndex); - return OMX_ErrorBadParameter; - } - - pending_input_buffers++; - if(input_flush_progress == true) - { - post_event ((unsigned int)buffer,0, - OMX_COMPONENT_GENERATE_EBD); - DEBUG_PRINT_ERROR("\nERROR: ETBProxy: Input flush in progress"); - return OMX_ErrorNone; - } -#ifdef _ANDROID_ICS_ - if(meta_mode_enable) - { - encoder_media_buffer_type *media_buffer; - bool met_error = false; - media_buffer = (encoder_media_buffer_type *)meta_buffer_hdr[nBufIndex].pBuffer; - if(media_buffer) - { - if (media_buffer->buffer_type != kMetadataBufferTypeCameraSource && - media_buffer->buffer_type != kMetadataBufferTypeGrallocSource) { - met_error = true; - } else { - if(media_buffer->buffer_type == kMetadataBufferTypeCameraSource) - { - if(media_buffer->meta_handle == NULL) { - met_error = true; - } - else if((media_buffer->meta_handle->numFds != 1 && - media_buffer->meta_handle->numInts != 2)) - { - met_error = true; - } - } - } - } else { - met_error = true; - } - if(met_error) - { - DEBUG_PRINT_ERROR("\nERROR: Unkown source/metahandle in ETB call"); - post_event ((unsigned int)buffer,0,OMX_COMPONENT_GENERATE_EBD); - return OMX_ErrorBadParameter; - } - - struct pmem Input_pmem_info; - if(media_buffer->buffer_type == kMetadataBufferTypeCameraSource) - { - Input_pmem_info.buffer = media_buffer; - Input_pmem_info.fd = media_buffer->meta_handle->data[0]; - Input_pmem_info.offset = media_buffer->meta_handle->data[1]; - Input_pmem_info.size = media_buffer->meta_handle->data[2]; - DEBUG_PRINT_LOW("ETB fd = %d, offset = %d, size = %d",Input_pmem_info.fd, - Input_pmem_info.offset, - Input_pmem_info.size); - - } else { - private_handle_t *handle = (private_handle_t *)media_buffer->meta_handle; - Input_pmem_info.buffer = media_buffer; - Input_pmem_info.fd = handle->fd; - Input_pmem_info.offset = 0; - Input_pmem_info.size = handle->size; - } - if(dev_use_buf(&Input_pmem_info,PORT_INDEX_IN,0) != true) { - DEBUG_PRINT_ERROR("\nERROR: in dev_use_buf"); - post_event ((unsigned int)buffer,0,OMX_COMPONENT_GENERATE_EBD); - return OMX_ErrorBadParameter; - } - } - else if(input_use_buffer && !m_use_input_pmem) -#else - if(input_use_buffer && !m_use_input_pmem) -#endif - { - DEBUG_PRINT_LOW("\n Heap UseBuffer case, so memcpy the data"); - pmem_data_buf = (OMX_U8 *)m_pInput_pmem[nBufIndex].buffer; - - memcpy (pmem_data_buf, (buffer->pBuffer + buffer->nOffset), - buffer->nFilledLen); - DEBUG_PRINT_LOW("memcpy() done in ETBProxy for i/p Heap UseBuf"); - } -#ifdef _MSM8974_ - if(dev_empty_buf(buffer, pmem_data_buf,nBufIndex,m_pInput_pmem[nBufIndex].fd) != true) -#else - if(dev_empty_buf(buffer, pmem_data_buf,0,0) != true) -#endif - { - DEBUG_PRINT_ERROR("\nERROR: ETBProxy: dev_empty_buf failed"); -#ifdef _ANDROID_ICS_ - omx_release_meta_buffer(buffer); -#endif - post_event ((unsigned int)buffer,0,OMX_COMPONENT_GENERATE_EBD); - /*Generate an async error and move to invalid state*/ - pending_input_buffers--; - return OMX_ErrorBadParameter; - } - - return ret; -} - -/* ====================================================================== -FUNCTION - omx_video::FillThisBuffer - -DESCRIPTION - IL client uses this method to release the frame buffer - after displaying them. - -PARAMETERS - None. - -RETURN VALUE - true/false - -========================================================================== */ -OMX_ERRORTYPE omx_video::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_BUFFERHEADERTYPE* buffer) -{ - DEBUG_PRINT_LOW("\n FTB: buffer->pBuffer[%p]\n", buffer->pBuffer); - if(m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("ERROR: FTB in Invalid State\n"); - return OMX_ErrorInvalidState; - } - - if (buffer == NULL ||(buffer->nSize != sizeof(OMX_BUFFERHEADERTYPE))) - { - DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->Invalid buffer or size\n"); - return OMX_ErrorBadParameter; - } - - if(buffer->nVersion.nVersion != OMX_SPEC_VERSION) - { - DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->OMX Version Invalid\n"); - return OMX_ErrorVersionMismatch; - } - - if (buffer->nOutputPortIndex != (OMX_U32)PORT_INDEX_OUT) - { - DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->Bad port index\n"); - return OMX_ErrorBadPortIndex; - } - - if(!m_sOutPortDef.bEnabled) - { - DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->port is disabled\n"); - return OMX_ErrorIncorrectStateOperation; - } - - post_event((unsigned) hComp, (unsigned)buffer,OMX_COMPONENT_GENERATE_FTB); - return OMX_ErrorNone; -} - -/* ====================================================================== -FUNCTION - omx_video::fill_this_buffer_proxy - -DESCRIPTION - IL client uses this method to release the frame buffer - after displaying them. - -PARAMETERS - None. - -RETURN VALUE - true/false - -========================================================================== */ -OMX_ERRORTYPE omx_video::fill_this_buffer_proxy( - OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd) -{ - OMX_U8 *pmem_data_buf = NULL; - OMX_ERRORTYPE nRet = OMX_ErrorNone; - - DEBUG_PRINT_LOW("\n FTBProxy: bufferAdd->pBuffer[%p]\n", bufferAdd->pBuffer); - - if(bufferAdd == NULL || ((bufferAdd - m_out_mem_ptr) >= m_sOutPortDef.nBufferCountActual) ) - { - DEBUG_PRINT_ERROR("\nERROR: FTBProxy: Invalid i/p params\n"); - return OMX_ErrorBadParameter; - } - - pending_output_buffers++; - /*Return back the output buffer to client*/ - if( m_sOutPortDef.bEnabled != OMX_TRUE || output_flush_progress == true) - { - DEBUG_PRINT_LOW("\n o/p port is Disabled or Flush in Progress"); - post_event ((unsigned int)bufferAdd,0, - OMX_COMPONENT_GENERATE_FBD); - return OMX_ErrorNone; - } - - if(output_use_buffer && !m_use_output_pmem) - { - DEBUG_PRINT_LOW("\n Heap UseBuffer case"); - pmem_data_buf = (OMX_U8 *)m_pOutput_pmem[bufferAdd - m_out_mem_ptr].buffer; - } - - if(dev_fill_buf(bufferAdd, pmem_data_buf,(bufferAdd - m_out_mem_ptr),m_pOutput_pmem[bufferAdd - m_out_mem_ptr].fd) != true) - { - DEBUG_PRINT_ERROR("\nERROR: dev_fill_buf() Failed"); - post_event ((unsigned int)bufferAdd,0,OMX_COMPONENT_GENERATE_FBD); - pending_output_buffers--; - return OMX_ErrorBadParameter; - } - - return OMX_ErrorNone; -} - -/* ====================================================================== -FUNCTION - omx_video::SetCallbacks - -DESCRIPTION - Set the callbacks. - -PARAMETERS - None. - -RETURN VALUE - OMX Error None if everything successful. - -========================================================================== */ -OMX_ERRORTYPE omx_video::set_callbacks(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_CALLBACKTYPE* callbacks, - OMX_IN OMX_PTR appData) -{ - - m_pCallbacks = *callbacks; - DEBUG_PRINT_LOW("\n Callbacks Set %p %p %p",m_pCallbacks.EmptyBufferDone,\ - m_pCallbacks.EventHandler,m_pCallbacks.FillBufferDone); - m_app_data = appData; - return OMX_ErrorNotImplemented; -} - - -/* ====================================================================== -FUNCTION - omx_venc::UseEGLImage - -DESCRIPTION - OMX Use EGL Image method implementation . - -PARAMETERS - . - -RETURN VALUE - Not Implemented error. - -========================================================================== */ -OMX_ERRORTYPE omx_video::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp, - OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, - OMX_IN OMX_U32 port, - OMX_IN OMX_PTR appData, - OMX_IN void* eglImage) -{ - DEBUG_PRINT_ERROR("ERROR: use_EGL_image: Not Implemented \n"); - return OMX_ErrorNotImplemented; -} - -/* ====================================================================== -FUNCTION - omx_venc::ComponentRoleEnum - -DESCRIPTION - OMX Component Role Enum method implementation. - -PARAMETERS - . - -RETURN VALUE - OMX Error None if everything is successful. -========================================================================== */ -OMX_ERRORTYPE omx_video::component_role_enum(OMX_IN OMX_HANDLETYPE hComp, - OMX_OUT OMX_U8* role, - OMX_IN OMX_U32 index) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - if(!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) - { - if((0 == index) && role) - { - strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE); - DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); - } - else - { - eRet = OMX_ErrorNoMore; - } - } - else if(!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) - { - if((0 == index) && role) - { - strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE); - DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); - } - else - { - DEBUG_PRINT_ERROR("\nERROR: No more roles \n"); - eRet = OMX_ErrorNoMore; - } - } - else if(!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) - { - if((0 == index) && role) - { - strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE); - DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); - } - else - { - DEBUG_PRINT_ERROR("\nERROR: No more roles \n"); - eRet = OMX_ErrorNoMore; - } - } - else if(!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) - { - if((0 == index) && role) - { - strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE); - DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); - } - else - { - DEBUG_PRINT_ERROR("\nERROR: No more roles \n"); - eRet = OMX_ErrorNoMore; - } - } - if(!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) - { - if((0 == index) && role) - { - strlcpy((char *)role, "video_encoder.mpeg4",OMX_MAX_STRINGNAME_SIZE); - DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); - } - else - { - eRet = OMX_ErrorNoMore; - } - } - else if(!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.h263",OMX_MAX_STRINGNAME_SIZE)) - { - if((0 == index) && role) - { - strlcpy((char *)role, "video_encoder.h263",OMX_MAX_STRINGNAME_SIZE); - DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); - } - else - { - DEBUG_PRINT_ERROR("\nERROR: No more roles \n"); - eRet = OMX_ErrorNoMore; - } - } - else if(!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.avc",OMX_MAX_STRINGNAME_SIZE)) - { - if((0 == index) && role) - { - strlcpy((char *)role, "video_encoder.avc",OMX_MAX_STRINGNAME_SIZE); - DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); - } - else - { - DEBUG_PRINT_ERROR("\nERROR: No more roles \n"); - eRet = OMX_ErrorNoMore; - } - } -#ifdef _MSM8974_ - else if(!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.vp8",OMX_MAX_STRINGNAME_SIZE)) - { - if((0 == index) && role) - { - strlcpy((char *)role, "video_encoder.vp8",OMX_MAX_STRINGNAME_SIZE); - DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); - } - else - { - DEBUG_PRINT_ERROR("\nERROR: No more roles \n"); - eRet = OMX_ErrorNoMore; - } - } -#endif - else - { - DEBUG_PRINT_ERROR("\nERROR: Querying Role on Unknown Component\n"); - eRet = OMX_ErrorInvalidComponentName; - } - return eRet; -} - - - - -/* ====================================================================== -FUNCTION - omx_venc::AllocateDone - -DESCRIPTION - Checks if entire buffer pool is allocated by IL Client or not. - Need this to move to IDLE state. - -PARAMETERS - None. - -RETURN VALUE - true/false. - -========================================================================== */ -bool omx_video::allocate_done(void) -{ - bool bRet = false; - bool bRet_In = false; - bool bRet_Out = false; - - bRet_In = allocate_input_done(); - bRet_Out = allocate_output_done(); - - if(bRet_In && bRet_Out) - { - bRet = true; - } - - return bRet; -} -/* ====================================================================== -FUNCTION - omx_venc::AllocateInputDone - -DESCRIPTION - Checks if I/P buffer pool is allocated by IL Client or not. - -PARAMETERS - None. - -RETURN VALUE - true/false. - -========================================================================== */ -bool omx_video::allocate_input_done(void) -{ - bool bRet = false; - unsigned i=0; - - if(m_inp_mem_ptr == NULL) - { - return bRet; - } - if(m_inp_mem_ptr ) - { - for(;ipBuffer[%p], flags=0x%x", - buffer->pBuffer, buffer->nFlags); - if(buffer == NULL || ((buffer - m_out_mem_ptr) > m_sOutPortDef.nBufferCountActual)) - { - return OMX_ErrorBadParameter; - } - - pending_output_buffers--; - - extra_data_handle.create_extra_data(buffer); - - if (m_sDebugSliceinfo) { - if(buffer->nFlags & OMX_BUFFERFLAG_EXTRADATA) { - DEBUG_PRINT_HIGH("parsing extradata"); - extra_data_handle.parse_extra_data(buffer); - } - } - /* For use buffer we need to copy the data */ - if(m_pCallbacks.FillBufferDone) - { - if(buffer->nFilledLen > 0) - { - m_fbd_count++; - -#ifdef OUTPUT_BUFFER_LOG - if(outputBufferFile1) - { - fwrite((const char *)buffer->pBuffer, buffer->nFilledLen, 1, outputBufferFile1); - } -#endif - } - m_pCallbacks.FillBufferDone (hComp,m_app_data,buffer); - } - else - { - return OMX_ErrorBadParameter; - } - return OMX_ErrorNone; -} - -OMX_ERRORTYPE omx_video::empty_buffer_done(OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE* buffer) -{ - DEBUG_PRINT_LOW("empty_buffer_done: buffer->pBuffer[%p]", buffer->pBuffer); - if(buffer == NULL || ((buffer - m_inp_mem_ptr) > m_sInPortDef.nBufferCountActual)) - { - return OMX_ErrorBadParameter; - } - - pending_input_buffers--; - - if(m_pCallbacks.EmptyBufferDone) - { - m_pCallbacks.EmptyBufferDone(hComp ,m_app_data, buffer); - } - return OMX_ErrorNone; -} - -void omx_video::complete_pending_buffer_done_cbs() -{ - unsigned p1; - unsigned p2; - unsigned ident; - omx_cmd_queue tmp_q, pending_bd_q; - pthread_mutex_lock(&m_lock); - // pop all pending GENERATE FDB from ftb queue - while (m_ftb_q.m_size) - { - m_ftb_q.pop_entry(&p1,&p2,&ident); - if(ident == OMX_COMPONENT_GENERATE_FBD) - { - pending_bd_q.insert_entry(p1,p2,ident); - } - else - { - tmp_q.insert_entry(p1,p2,ident); - } - } - //return all non GENERATE FDB to ftb queue - while(tmp_q.m_size) - { - tmp_q.pop_entry(&p1,&p2,&ident); - m_ftb_q.insert_entry(p1,p2,ident); - } - // pop all pending GENERATE EDB from etb queue - while (m_etb_q.m_size) - { - m_etb_q.pop_entry(&p1,&p2,&ident); - if(ident == OMX_COMPONENT_GENERATE_EBD) - { - pending_bd_q.insert_entry(p1,p2,ident); - } - else - { - tmp_q.insert_entry(p1,p2,ident); - } - } - //return all non GENERATE FDB to etb queue - while(tmp_q.m_size) - { - tmp_q.pop_entry(&p1,&p2,&ident); - m_etb_q.insert_entry(p1,p2,ident); - } - pthread_mutex_unlock(&m_lock); - // process all pending buffer dones - while(pending_bd_q.m_size) - { - pending_bd_q.pop_entry(&p1,&p2,&ident); - switch(ident) - { - case OMX_COMPONENT_GENERATE_EBD: - if(empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) - { - DEBUG_PRINT_ERROR("\nERROR: empty_buffer_done() failed!\n"); - omx_report_error (); - } - break; - - case OMX_COMPONENT_GENERATE_FBD: - if(fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) - { - DEBUG_PRINT_ERROR("\nERROR: fill_buffer_done() failed!\n"); - omx_report_error (); - } - break; - } - } -} - -#ifdef MAX_RES_720P -OMX_ERRORTYPE omx_video::get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - if(!profileLevelType) - return OMX_ErrorBadParameter; - - if(profileLevelType->nPortIndex == 1) { - if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingAVC) - { - if (profileLevelType->nProfileIndex == 0) - { - profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline; - profileLevelType->eLevel = OMX_VIDEO_AVCLevel31; - } - else if (profileLevelType->nProfileIndex == 1) - { - profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain; - profileLevelType->eLevel = OMX_VIDEO_AVCLevel31; - } - else if(profileLevelType->nProfileIndex == 2) - { - profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh; - profileLevelType->eLevel = OMX_VIDEO_AVCLevel31; - } - else - { - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", - profileLevelType->nProfileIndex); - eRet = OMX_ErrorNoMore; - } - } - else if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingH263) - { - if (profileLevelType->nProfileIndex == 0) - { - profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline; - profileLevelType->eLevel = OMX_VIDEO_H263Level70; - } - else - { - DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex); - eRet = OMX_ErrorNoMore; - } - } - else if(m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingMPEG4) - { - if (profileLevelType->nProfileIndex == 0) - { - profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple; - profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5; - } - else if(profileLevelType->nProfileIndex == 1) - { - profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple; - profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5; - } - else - { - DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex); - eRet = OMX_ErrorNoMore; - } - } - } - else - { - DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %d\n", profileLevelType->nPortIndex); - eRet = OMX_ErrorBadPortIndex; - } - DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported for Input port returned Profile:%d, Level:%d\n", - profileLevelType->eProfile,profileLevelType->eLevel); - return eRet; -} -#endif - -#ifdef MAX_RES_1080P -OMX_ERRORTYPE omx_video::get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - if(!profileLevelType) - return OMX_ErrorBadParameter; - - if(profileLevelType->nPortIndex == 1) { - if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingAVC) - { - if (profileLevelType->nProfileIndex == 0) - { - profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline; - profileLevelType->eLevel = OMX_VIDEO_AVCLevel4; - - } - else if (profileLevelType->nProfileIndex == 1) - { - profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain; - profileLevelType->eLevel = OMX_VIDEO_AVCLevel4; - } - else if(profileLevelType->nProfileIndex == 2) - { - profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh; - profileLevelType->eLevel = OMX_VIDEO_AVCLevel4; - } - else - { - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", - profileLevelType->nProfileIndex); - eRet = OMX_ErrorNoMore; - } - } - else if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingH263) - { - if (profileLevelType->nProfileIndex == 0) - { - profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline; - profileLevelType->eLevel = OMX_VIDEO_H263Level70; - } - else - { - DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex); - eRet = OMX_ErrorNoMore; - } - } - else if(m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingMPEG4) - { - if (profileLevelType->nProfileIndex == 0) - { - profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple; - profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5; - } - else if(profileLevelType->nProfileIndex == 1) - { - profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple; - profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5; - } - else - { - DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex); - eRet = OMX_ErrorNoMore; - } - } - } - else - { - DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %d\n", profileLevelType->nPortIndex); - eRet = OMX_ErrorBadPortIndex; - } - DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported for Input port returned Profile:%d, Level:%d\n", - profileLevelType->eProfile,profileLevelType->eLevel); - return eRet; -} -#endif - -#ifdef USE_ION -int omx_video::alloc_map_ion_memory(int size,struct ion_allocation_data *alloc_data, - struct ion_fd_data *fd_data,int flag) -{ - struct venc_ion buf_ion_info; - int ion_device_fd =-1,rc=0,ion_dev_flags = 0; - if (size <=0 || !alloc_data || !fd_data) { - DEBUG_PRINT_ERROR("\nInvalid input to alloc_map_ion_memory"); - return -EINVAL; - } - if(flag == CACHED) { - ion_dev_flags = O_RDONLY; - } else if(flag == UNCACHED) { - ion_dev_flags = O_RDONLY | O_DSYNC; - } - ion_device_fd = open (MEM_DEVICE,ion_dev_flags); - if(ion_device_fd < 0) - { - DEBUG_PRINT_ERROR("\nERROR: ION Device open() Failed"); - return ion_device_fd; - } - alloc_data->len = size; - alloc_data->align = 4096; -#ifdef MAX_RES_720P - alloc_data->len = (size + (alloc_data->align - 1)) & ~(alloc_data->align - 1); - alloc_data->flags = ION_HEAP(MEM_HEAP_ID); -#else - alloc_data->flags = (ION_HEAP(MEM_HEAP_ID) | - ION_HEAP(ION_IOMMU_HEAP_ID)); -#endif - rc = ioctl(ion_device_fd,ION_IOC_ALLOC,alloc_data); - if(rc || !alloc_data->handle) { - DEBUG_PRINT_ERROR("\n ION ALLOC memory failed "); - alloc_data->handle =NULL; - close(ion_device_fd); - ion_device_fd = -1; - return ion_device_fd; - } - fd_data->handle = alloc_data->handle; - rc = ioctl(ion_device_fd,ION_IOC_MAP,fd_data); - if(rc) { - DEBUG_PRINT_ERROR("\n ION MAP failed "); - buf_ion_info.ion_alloc_data = *alloc_data; - buf_ion_info.ion_device_fd = ion_device_fd; - buf_ion_info.fd_ion_data = *fd_data; - free_ion_memory(&buf_ion_info); - fd_data->fd =-1; - ion_device_fd =-1; - } - return ion_device_fd; -} - -void omx_video::free_ion_memory(struct venc_ion *buf_ion_info) -{ - if (!buf_ion_info) { - DEBUG_PRINT_ERROR("\n Invalid input to free_ion_memory"); - return; - } - if (ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE, - &buf_ion_info->ion_alloc_data.handle)) { - DEBUG_PRINT_ERROR("\n ION free failed "); - return; - } - close(buf_ion_info->ion_device_fd); - buf_ion_info->ion_alloc_data.handle = NULL; - buf_ion_info->ion_device_fd = -1; - buf_ion_info->fd_ion_data.fd = -1; -} -#endif - -#ifdef _ANDROID_ICS_ -void omx_video::omx_release_meta_buffer(OMX_BUFFERHEADERTYPE *buffer) -{ - if(buffer && meta_mode_enable) - { - encoder_media_buffer_type *media_ptr; - struct pmem Input_pmem; - bool meta_error = false; - media_ptr = (encoder_media_buffer_type *) buffer->pBuffer; - if(media_ptr && media_ptr->meta_handle) - { - if(media_ptr->buffer_type == kMetadataBufferTypeCameraSource && - media_ptr->meta_handle->numFds == 1 && - media_ptr->meta_handle->numInts == 2) { - Input_pmem.fd = media_ptr->meta_handle->data[0]; - Input_pmem.buffer = media_ptr; - Input_pmem.size = media_ptr->meta_handle->data[2]; - Input_pmem.offset = media_ptr->meta_handle->data[1]; - DEBUG_PRINT_LOW("EBD fd = %d, offset = %d, size = %d",Input_pmem.fd, - Input_pmem.offset, - Input_pmem.size); - } else if(media_ptr->buffer_type == kMetadataBufferTypeGrallocSource) { - private_handle_t *handle = (private_handle_t *)media_ptr->meta_handle; - Input_pmem.buffer = media_ptr; - Input_pmem.fd = handle->fd; - Input_pmem.offset = 0; - Input_pmem.size = handle->size; - } else { - meta_error = true; - DEBUG_PRINT_ERROR(" Meta Error set in EBD"); - } - if(!meta_error) - meta_error = !dev_free_buf(&Input_pmem,PORT_INDEX_IN); - if(meta_error) - { - DEBUG_PRINT_ERROR(" Warning dev_free_buf failed flush value is %d", - input_flush_progress); - } - } - } -} -#endif +/*-------------------------------------------------------------------------- +Copyright (c) 2010-2013, 2015, The 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 +////////////////////////////////////////////////////////////////////////////// + +#include +#include "omx_video_base.h" +#include +#include +#include +#include +#include +#ifdef _ANDROID_ICS_ +#include +#include +#endif +#ifndef _ANDROID_ +#include +#define strlcpy g_strlcpy +#endif +#define H264_SUPPORTED_WIDTH (480) +#define H264_SUPPORTED_HEIGHT (368) + +#define MPEG4_SUPPORTED_WIDTH (480) +#define MPEG4_SUPPORTED_HEIGHT (368) + +#define VC1_SP_MP_START_CODE 0xC5000000 +#define VC1_SP_MP_START_CODE_MASK 0xFF000000 +#define VC1_AP_START_CODE 0x00000100 +#define VC1_AP_START_CODE_MASK 0xFFFFFF00 +#define VC1_STRUCT_C_PROFILE_MASK 0xF0 +#define VC1_STRUCT_B_LEVEL_MASK 0xE0000000 +#define VC1_SIMPLE_PROFILE 0 +#define VC1_MAIN_PROFILE 1 +#define VC1_ADVANCE_PROFILE 3 +#define VC1_SIMPLE_PROFILE_LOW_LEVEL 0 +#define VC1_SIMPLE_PROFILE_MED_LEVEL 2 +#define VC1_STRUCT_C_LEN 4 +#define VC1_STRUCT_C_POS 8 +#define VC1_STRUCT_A_POS 12 +#define VC1_STRUCT_B_POS 24 +#define VC1_SEQ_LAYER_SIZE 36 + +#ifndef MAX_RES_720P +#define IS_NOT_ALIGNED( num, to) (num & (to-1)) +#define ALIGN( num, to ) (((num) + (to-1)) & (~(to-1))) +#define SZ_2K (2048) +#endif + +typedef struct OMXComponentCapabilityFlagsType +{ + ////////////////// OMX COMPONENT CAPABILITY RELATED MEMBERS + 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 +#ifdef OUTPUT_BUFFER_LOG +extern FILE *outputBufferFile1; +#endif + +int omx_video::m_venc_num_instances = 0; +int omx_video::m_venc_ion_devicefd = 0; +pthread_mutex_t omx_video::m_venc_ionlock; + +void* message_thread(void *input) +{ + omx_video* omx = reinterpret_cast(input); + unsigned char id; + int n; + + DEBUG_PRINT_LOW("omx_venc: message thread start\n"); + prctl(PR_SET_NAME, (unsigned long)"VideoEncMsgThread", 0, 0, 0); + while(1) + { + n = read(omx->m_pipe_in, &id, 1); + if(0 == n) + { + break; + } + + if(1 == n) + { + omx->process_event_cb(omx, id); + } +#ifdef QLE_BUILD + if(n < 0) break; +#else + if((n < 0) && (errno != EINTR)) break; +#endif + } + DEBUG_PRINT_LOW("omx_venc: message thread stop\n"); + return 0; +} + +void post_message(omx_video *omx, unsigned char id) +{ + DEBUG_PRINT_LOW("omx_venc: post_message %d\n", id); + write(omx->m_pipe_out, &id, 1); +} + +// omx_cmd_queue destructor +omx_video::omx_cmd_queue::~omx_cmd_queue() +{ + // Nothing to do +} + +// omx cmd queue constructor +omx_video::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0) +{ + memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE); +} + +// omx cmd queue insert +bool omx_video::omx_cmd_queue::insert_entry(unsigned p1, unsigned p2, unsigned 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\n"); + } + return ret; +} + +// omx cmd queue pop +bool omx_video::omx_cmd_queue::pop_entry(unsigned *p1, unsigned *p2, unsigned *id) +{ + bool ret = true; + if(m_size > 0) + { + *id = m_q[m_read].id; + *p1 = m_q[m_read].param1; + *p2 = m_q[m_read].param2; + // Move the read pointer ahead + ++m_read; + --m_size; + if(m_read >= OMX_CORE_CONTROL_CMDQ_SIZE) + { + m_read = 0; + } + } + else + { + ret = false; + } + return ret; +} + +// Retrieve the first mesg type in the queue +unsigned omx_video::omx_cmd_queue::get_q_msg_type() +{ + return m_q[m_read].id; +} + + + +#ifdef _ANDROID_ +VideoHeap::VideoHeap(int fd, size_t size, void* base) +{ + // dup file descriptor, map once, use pmem + init(dup(fd), base, size, 0 , MEM_DEVICE); +} +#endif // _ANDROID_ + +/* ====================================================================== +FUNCTION + omx_venc::omx_venc + +DESCRIPTION + Constructor + +PARAMETERS + None + +RETURN VALUE + None. +========================================================================== */ +omx_video::omx_video(): m_state(OMX_StateInvalid), + m_app_data(NULL), + m_inp_mem_ptr(NULL), + m_out_mem_ptr(NULL), + m_pInput_pmem(NULL), + m_pOutput_pmem(NULL), +#ifdef USE_ION + m_pInput_ion(NULL), + m_pOutput_ion(NULL), +#endif + pending_input_buffers(0), + pending_output_buffers(0), + m_out_bm_count(0), + m_inp_bm_count(0), + m_flags(0), + m_event_port_settings_sent(false), + output_flush_progress (false), + input_flush_progress (false), + input_use_buffer (false), + output_use_buffer (false), + m_use_input_pmem(OMX_FALSE), + m_use_output_pmem(OMX_FALSE), + m_etb_count(0), + m_fbd_count(0), + m_error_propogated(false), + m_input_msg_id(OMX_COMPONENT_GENERATE_ETB), + psource_frame(NULL), + pdest_frame(NULL), + c2d_opened(false), + secure_session(false) +{ + DEBUG_PRINT_HIGH("\n omx_video(): Inside Constructor()"); + memset(&m_cmp,0,sizeof(m_cmp)); + memset(&m_pCallbacks,0,sizeof(m_pCallbacks)); + secure_color_format = (int) OMX_COLOR_FormatYUV420SemiPlanar; + pthread_mutex_init(&m_lock, NULL); + sem_init(&m_cmd_lock,0,0); + if (!m_venc_num_instances) + { + m_venc_ion_devicefd = open(MEM_DEVICE, O_RDONLY); + if (m_venc_ion_devicefd < 0) + { + DEBUG_PRINT_ERROR("Open() venc ion device failed, errno = %d\n", + errno); + m_venc_ion_devicefd = 0; + } + DEBUG_PRINT_HIGH("Successfully opened venc ion device fd = %d", + m_venc_ion_devicefd); + pthread_mutex_init(&m_venc_ionlock, NULL); + DEBUG_PRINT_HIGH("Successfully created venc ionlock"); + } + m_venc_num_instances++; + DEBUG_PRINT_HIGH("Venc instance = %d, ion device fd = %d", + m_venc_num_instances, m_venc_ion_devicefd); +} + + +/* ====================================================================== +FUNCTION + omx_venc::~omx_venc + +DESCRIPTION + Destructor + +PARAMETERS + None + +RETURN VALUE + None. +========================================================================== */ +omx_video::~omx_video() +{ + DEBUG_PRINT_HIGH("In OMX Venc Destructor() for instance = %d", + m_venc_num_instances); + if(m_pipe_in) close(m_pipe_in); + if(m_pipe_out) close(m_pipe_out); + DEBUG_PRINT_HIGH("omx_video: Waiting on Msg Thread exit\n"); + pthread_join(msg_thread_id,NULL); + DEBUG_PRINT_HIGH("omx_video: Waiting on Async Thread exit\n"); + pthread_join(async_thread_id,NULL); + pthread_mutex_destroy(&m_lock); + sem_destroy(&m_cmd_lock); + + m_venc_num_instances--; + if (!m_venc_num_instances) + { + DEBUG_PRINT_HIGH("Calling close() on venc ion device fd = %d", + m_venc_ion_devicefd); + close(m_venc_ion_devicefd); + m_venc_ion_devicefd = 0; + pthread_mutex_destroy(&m_venc_ionlock); + DEBUG_PRINT_HIGH("Successfully destroyed venc ionlock"); + } + DEBUG_PRINT_HIGH("m_etb_count = %u, m_fbd_count = %u", m_etb_count, + m_fbd_count); + DEBUG_PRINT_HIGH("Exiting OMX Video Encoder ...\n"); +} + +/* ====================================================================== +FUNCTION + omx_venc::OMXCntrlProcessMsgCb + +DESCRIPTION + IL Client callbacks are generated through this routine. The decoder + provides the thread context for this routine. + +PARAMETERS + ctxt -- Context information related to the self. + id -- Event identifier. This could be any of the following: + 1. Command completion event + 2. Buffer done callback event + 3. Frame done callback event + +RETURN VALUE + None. + +========================================================================== */ +void omx_video::process_event_cb(void *ctxt, unsigned char id) +{ + unsigned p1; // Parameter - 1 + unsigned p2; // Parameter - 2 + unsigned ident; + unsigned qsize=0; // qsize + omx_video *pThis = (omx_video *) ctxt; + + if(!pThis) + { + DEBUG_PRINT_ERROR("ERROR:ProcessMsgCb:Context is incorrect; bailing out\n"); + return; + } + + // Protect the shared queue data structure + do + { + /*Read the message id's from the queue*/ + + pthread_mutex_lock(&pThis->m_lock); + qsize = pThis->m_cmd_q.m_size; + if(qsize) + { + pThis->m_cmd_q.pop_entry(&p1,&p2,&ident); + } + + if(qsize == 0) + { + qsize = pThis->m_ftb_q.m_size; + if(qsize) + { + pThis->m_ftb_q.pop_entry(&p1,&p2,&ident); + } + } + + if(qsize == 0) + { + qsize = pThis->m_etb_q.m_size; + if(qsize) + { + pThis->m_etb_q.pop_entry(&p1,&p2,&ident); + } + } + + pthread_mutex_unlock(&pThis->m_lock); + + /*process message if we have one*/ + if(qsize > 0) + { + id = ident; + switch(id) + { + case OMX_COMPONENT_GENERATE_EVENT: + if(pThis->m_pCallbacks.EventHandler) + { + switch(p1) + { + case OMX_CommandStateSet: + pThis->m_state = (OMX_STATETYPE) p2; + DEBUG_PRINT_LOW("Process -> state set to %d \n", pThis->m_state); + pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, + OMX_EventCmdComplete, p1, p2, NULL); + break; + + case OMX_EventError: + DEBUG_PRINT_ERROR("\nERROR: OMX_EventError: p2 = %d\n", p2); + if(p2 == 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, NULL, NULL ); + + } + break; + + case OMX_CommandPortDisable: + DEBUG_PRINT_LOW("Process -> Port %d set to PORT_STATE_DISABLED" \ + "state \n", 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 %d set PORT_STATE_ENABLED state\n" \ + , p2); + pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,\ + OMX_EventCmdComplete, p1, p2, NULL ); + break; + + default: + DEBUG_PRINT_LOW("\n process_event_cb forwarding EventCmdComplete %d \n", 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\n"); + } + break; + case OMX_COMPONENT_GENERATE_ETB_OPQ: + DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_ETB_OPQ\n"); + if(pThis->empty_this_buffer_opaque((OMX_HANDLETYPE)p1,\ + (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) + { + DEBUG_PRINT_ERROR("\nERROR: ETBProxy() failed!\n"); + pThis->omx_report_error (); + } + break; + case OMX_COMPONENT_GENERATE_ETB: + DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_ETB\n"); + if(pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\ + (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) + { + DEBUG_PRINT_ERROR("\nERROR: ETBProxy() failed!\n"); + 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("\nERROR: FTBProxy() failed!\n"); + 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("\nERROR: empty_buffer_done() failed!\n"); + 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("\nERROR: fill_buffer_done() failed!\n"); + pThis->omx_report_error (); + } + break; + + case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH: + + pThis->input_flush_progress = false; + DEBUG_PRINT_HIGH("\nm_etb_count at i/p flush = %u", m_etb_count); + m_etb_count = 0; + if(pThis->m_pCallbacks.EventHandler) + { + /*Check if we need generate event for Flush done*/ + if(BITMASK_PRESENT_U32(pThis->m_flags, + OMX_COMPONENT_INPUT_FLUSH_PENDING)) + { + pThis->m_flags = BITMASK_CLEAR_U32(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_U32(pThis->m_flags, + OMX_COMPONENT_IDLE_PENDING)) + { + if(!pThis->output_flush_progress) + { + DEBUG_PRINT_LOW("\n dev_stop called after input flush complete\n"); + if(dev_stop() != 0) + { + DEBUG_PRINT_ERROR("\nERROR: dev_stop() failed in i/p flush!\n"); + pThis->omx_report_error (); + } + } + } + } + + break; + + case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH: + + pThis->output_flush_progress = false; + DEBUG_PRINT_HIGH("\nm_fbd_count at o/p flush = %u", m_fbd_count); + m_fbd_count = 0; + if(pThis->m_pCallbacks.EventHandler) + { + /*Check if we need generate event for Flush done*/ + if(BITMASK_PRESENT_U32(pThis->m_flags, + OMX_COMPONENT_OUTPUT_FLUSH_PENDING)) + { + pThis->m_flags = BITMASK_CLEAR_U32(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_U32(pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING)) + { + DEBUG_PRINT_LOW("\n dev_stop called after Output flush complete\n"); + if(!pThis->input_flush_progress) + { + if(dev_stop() != 0) + { + DEBUG_PRINT_ERROR("\nERROR: dev_stop() failed in o/p flush!\n"); + pThis->omx_report_error (); + } + } + } + } + break; + + case OMX_COMPONENT_GENERATE_START_DONE: + DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE msg"); + + if(pThis->m_pCallbacks.EventHandler) + { + DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE Success"); + if(BITMASK_PRESENT_U32(pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) + { + DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE Move to \ + executing"); + // Send the callback now + pThis->m_flags = BITMASK_CLEAR_U32(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_U32(pThis->m_flags, + OMX_COMPONENT_PAUSE_PENDING)) + { + if(dev_pause()) + { + DEBUG_PRINT_ERROR("\nERROR: dev_pause() failed in Start Done!\n"); + pThis->omx_report_error (); + } + } + else if (BITMASK_PRESENT_U32(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 (); + } + pThis->m_flags = BITMASK_CLEAR_U32(pThis->m_flags,OMX_COMPONENT_LOADED_START_PENDING); + } + else + { + DEBUG_PRINT_LOW("\nERROR: unknown flags=%x\n",pThis->m_flags); + } + } + else + { + DEBUG_PRINT_LOW("\n Event Handler callback is NULL"); + } + break; + + case OMX_COMPONENT_GENERATE_PAUSE_DONE: + DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_PAUSE_DONE msg"); + if(pThis->m_pCallbacks.EventHandler) + { + if(BITMASK_PRESENT_U32(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\n"); + pThis->m_flags = BITMASK_CLEAR_U32(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("\n OMX_COMPONENT_GENERATE_RESUME_DONE msg"); + if(pThis->m_pCallbacks.EventHandler) + { + if(BITMASK_PRESENT_U32(pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) + { + // Send the callback now + pThis->m_flags = BITMASK_CLEAR_U32(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("\n OMX_COMPONENT_GENERATE_STOP_DONE msg"); + if(pThis->m_pCallbacks.EventHandler) + { + pThis->complete_pending_buffer_done_cbs(); + if(BITMASK_PRESENT_U32(pThis->m_flags,OMX_COMPONENT_IDLE_PENDING)) + { + // Send the callback now + pThis->m_flags = BITMASK_CLEAR_U32(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_U32(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 (); + } + pThis->m_flags = BITMASK_CLEAR_U32(pThis->m_flags,OMX_COMPONENT_LOADED_STOP_PENDING); + } + else + { + DEBUG_PRINT_LOW("\nERROR: unknown flags=%x\n",pThis->m_flags); + } + } + + break; + + case OMX_COMPONENT_GENERATE_HARDWARE_ERROR: + DEBUG_PRINT_ERROR("\nERROR: OMX_COMPONENT_GENERATE_HARDWARE_ERROR!\n"); + pThis->omx_report_error (); + break; + + default: + DEBUG_PRINT_LOW("\n process_event_cb unknown msg id 0x%02x", id); + break; + } + } + + pthread_mutex_lock(&pThis->m_lock); + qsize = pThis->m_cmd_q.m_size + pThis->m_ftb_q.m_size +\ + pThis->m_etb_q.m_size; + + pthread_mutex_unlock(&pThis->m_lock); + + } + while(qsize>0); + +} + + + + +/* ====================================================================== +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 +) +{ + if(m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("ERROR: Get Comp Version in Invalid State\n"); + 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 + ) +{ + if(m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State\n"); + return OMX_ErrorInvalidState; + } + + if(cmd == OMX_CommandFlush || cmd == OMX_CommandPortDisable || cmd == OMX_CommandPortEnable) + { + if((param1 != PORT_INDEX_IN) && (param1 != PORT_INDEX_OUT) && (param1 != PORT_INDEX_BOTH)) + { + DEBUG_PRINT_ERROR("ERROR: omx_video::send_command-->bad port index\n"); + return OMX_ErrorBadPortIndex; + } + } + if(cmd == OMX_CommandMarkBuffer) + { + if(param1 != PORT_INDEX_IN) + { + DEBUG_PRINT_ERROR("ERROR: omx_video::send_command-->bad port index \n"); + return OMX_ErrorBadPortIndex; + } + if(!cmdData) + { + DEBUG_PRINT_ERROR("ERROR: omx_video::send_command-->param is null"); + return OMX_ErrorBadParameter; + } + } + + post_event((unsigned)cmd,(unsigned)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 + ) +{ + 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\n"); + } + else + { + DEBUG_PRINT_LOW("OMXCORE-SM: Loaded-->Idle-Pending\n"); + m_flags = BITMASK_SET_U32(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\n"); + 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\n"); + } + /* Requesting transition from Loaded to Executing */ + else if(eState == OMX_StateExecuting) + { + DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Executing\n"); + 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\n"); + 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\n"); + post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorInvalidState; + } + else + { + DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->%d Not Handled\n",\ + 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\n"); + if(dev_stop() != 0) + { + DEBUG_PRINT_ERROR("\nERROR: dev_stop() failed at Idle --> Loaded"); + eRet = OMX_ErrorHardware; + } + } + else + { + DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Loaded-Pending\n"); + m_flags = BITMASK_SET_U32(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("\nERROR: dev_start() failed in SCP on Idle --> Exe\n"); + omx_report_error (); + eRet = OMX_ErrorHardware; + } + else + { + m_flags = BITMASK_SET_U32(m_flags,OMX_COMPONENT_EXECUTE_PENDING); + DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Executing\n"); + bFlag = 0; + } + + dev_start_done(); + } + /* Requesting transition from Idle to Idle */ + else if(eState == OMX_StateIdle) + { + DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle-->Idle\n"); + 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\n"); + 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("\nERROR: dev_start() failed in SCP on Idle --> Pause\n"); + omx_report_error (); + eRet = OMX_ErrorHardware; + } + else + { + m_flags = BITMASK_SET_U32(m_flags,OMX_COMPONENT_PAUSE_PENDING); + DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Pause\n"); + bFlag = 0; + } + } + /* Requesting transition from Idle to Invalid */ + else if(eState == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle-->Invalid\n"); + post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorInvalidState; + } + else + { + DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle --> %d Not Handled\n",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("\n OMXCORE-SM: Executing --> Idle \n"); + //here this should be Pause-Idle pending and should be cleared when flush is complete and change the state to Idle + m_flags = BITMASK_SET_U32(m_flags,OMX_COMPONENT_IDLE_PENDING); + execute_omx_flush(OMX_ALL); + bFlag = 0; + dev_stop_done(); + } + /* Requesting transition from Executing to Paused */ + else if(eState == OMX_StatePause) + { + + if(dev_pause()) + { + DEBUG_PRINT_ERROR("\nERROR: dev_pause() failed in SCP on Exe --> Pause\n"); + post_event(OMX_EventError,OMX_ErrorHardware,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorHardware; + } + else + { + m_flags = BITMASK_SET_U32(m_flags,OMX_COMPONENT_PAUSE_PENDING); + DEBUG_PRINT_LOW("OMXCORE-SM: Executing-->Pause\n"); + bFlag = 0; + } + } + /* Requesting transition from Executing to Loaded */ + else if(eState == OMX_StateLoaded) + { + DEBUG_PRINT_ERROR("\nERROR: OMXCORE-SM: Executing --> Loaded \n"); + 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("\nERROR: OMXCORE-SM: Executing --> WaitForResources \n"); + 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("\nERROR: OMXCORE-SM: Executing --> Executing \n"); + 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("\nERROR: OMXCORE-SM: Executing --> Invalid \n"); + post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorInvalidState; + } + else + { + DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Executing --> %d Not Handled\n",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("\n Pause --> Executing \n"); + if( dev_resume() ) + { + post_event(OMX_EventError,OMX_ErrorHardware,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorHardware; + } + else + { + m_flags = BITMASK_SET_U32(m_flags,OMX_COMPONENT_EXECUTE_PENDING); + DEBUG_PRINT_LOW("OMXCORE-SM: Pause-->Executing\n"); + post_event (NULL, NULL, 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("\n Pause --> Idle \n"); + m_flags = BITMASK_SET_U32(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("\nERROR: Pause --> loaded \n"); + 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("\nERROR: Pause --> WaitForResources \n"); + 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("\nERROR: Pause --> Pause \n"); + 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("\nERROR: Pause --> Invalid \n"); + post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorInvalidState; + } + else + { + DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Paused --> %d Not Handled\n",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\n"); + } + /* Requesting transition from WaitForResources to WaitForResources */ + else if(eState == OMX_StateWaitForResources) + { + DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->WaitForResources\n"); + 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\n"); + 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\n"); + 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\n"); + 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)\n",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\n"); + post_event(OMX_EventError,OMX_ErrorInvalidState,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorInvalidState; + } + } + else if(cmd == OMX_CommandFlush) + { + if(0 == param1 || OMX_ALL == param1) + { + m_flags = BITMASK_SET_U32(m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING); + } + if(1 == param1 || OMX_ALL == param1) + { + //generate output flush event only. + m_flags = BITMASK_SET_U32(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_U32(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\n"); + m_flags = BITMASK_SET_U32(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_U32(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\n"); + m_flags = BITMASK_SET_U32(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 + { + m_flags = BITMASK_SET_U32(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 + { + m_flags = BITMASK_SET_U32(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)\n",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("\n execute_omx_flush - %d\n", flushType); + if(flushType == 0 || flushType == OMX_ALL) + { + input_flush_progress = true; + //flush input only + bRet = execute_input_flush(); + } + if(flushType == 1 || flushType == OMX_ALL) + { + //flush output only + output_flush_progress = true; + bRet = execute_output_flush(); + } + 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 p1 = 0; // Parameter - 1 + unsigned p2 = 0; // Parameter - 2 + unsigned ident = 0; + bool bRet = true; + + /*Generate FBD for all Buffers in the FTBq*/ + DEBUG_PRINT_LOW("\n execute_output_flush\n"); + pthread_mutex_lock(&m_lock); + while(m_ftb_q.m_size) + { + m_ftb_q.pop_entry(&p1,&p2,&ident); + + if(ident == OMX_COMPONENT_GENERATE_FTB ) + { + pending_output_buffers++; + fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2); + } + else if(ident == OMX_COMPONENT_GENERATE_FBD) + { + fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1); + } + } + + pthread_mutex_unlock(&m_lock); + /*Check if there are buffers with the Driver*/ + if(dev_flush(PORT_INDEX_OUT)) + { + DEBUG_PRINT_ERROR("\nERROR: 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 p1 = 0; // Parameter - 1 + unsigned p2 = 0; // Parameter - 2 + unsigned ident = 0; + bool bRet = true; + + /*Generate EBD for all Buffers in the ETBq*/ + DEBUG_PRINT_LOW("\n execute_input_flush\n"); + + pthread_mutex_lock(&m_lock); + while(m_etb_q.m_size) + { + m_etb_q.pop_entry(&p1,&p2,&ident); + if(ident == OMX_COMPONENT_GENERATE_ETB) + { + pending_input_buffers++; + empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2); + } + else if(ident == OMX_COMPONENT_GENERATE_EBD) + { + empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1); + } + else if(ident == OMX_COMPONENT_GENERATE_ETB_OPQ) + { + m_pCallbacks.EmptyBufferDone(&m_cmp,m_app_data,(OMX_BUFFERHEADERTYPE *)p2); + } + } + if(mUseProxyColorFormat) { + if(psource_frame) { + m_pCallbacks.EmptyBufferDone(&m_cmp,m_app_data,psource_frame); + psource_frame = NULL; + } + while(m_opq_meta_q.m_size) { + unsigned 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 int)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("\nERROR: i/p 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 int p1, + unsigned int p2, + unsigned int 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 == m_input_msg_id) || + (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("\n Value of this pointer in post_event %p",this); + post_message(this, id); + pthread_mutex_unlock(&m_lock); + + return bRet; +} + +/* ====================================================================== +FUNCTION + omx_venc::GetParameter + +DESCRIPTION + OMX Get Parameter method implementation + +PARAMETERS + . + +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) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + unsigned int height=0,width = 0; + + DEBUG_PRINT_LOW("get_parameter: \n"); + if(m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("ERROR: Get Param in Invalid State\n"); + return OMX_ErrorInvalidState; + } + if(paramData == NULL) + { + DEBUG_PRINT_ERROR("ERROR: Get Param in Invalid paramData \n"); + return OMX_ErrorBadParameter; + } + switch(paramIndex) + { + case OMX_IndexParamPortDefinition: + { + OMX_PARAM_PORTDEFINITIONTYPE *portDefn; + portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData; + + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition\n"); + if(portDefn->nPortIndex == (OMX_U32) PORT_INDEX_IN) + { + DEBUG_PRINT_LOW("m_sInPortDef: size = %d, min cnt = %d, actual cnt = %d", + m_sInPortDef.nBufferSize, m_sInPortDef.nBufferCountMin, + m_sInPortDef.nBufferCountActual); + memcpy(portDefn, &m_sInPortDef, sizeof(m_sInPortDef)); +#ifdef _ANDROID_ICS_ + if(meta_mode_enable) + { + portDefn->nBufferSize = sizeof(encoder_media_buffer_type); + } + if(secure_session) { + portDefn->format.video.eColorFormat = + (OMX_COLOR_FORMATTYPE)secure_color_format; + } + else if (mUseProxyColorFormat) { + portDefn->format.video.eColorFormat = + (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FormatAndroidOpaque; + } +#ifdef MAX_RES_1080P + else + { + portDefn->format.video.eColorFormat = + m_sInPortFormat.eColorFormat; + DEBUG_PRINT_HIGH("get port definition: color_format = 0x%x", + m_sInPortFormat.eColorFormat); + } +#endif +#endif + } + else if(portDefn->nPortIndex == (OMX_U32) PORT_INDEX_OUT) + { + dev_get_buf_req (&m_sOutPortDef.nBufferCountMin, + &m_sOutPortDef.nBufferCountActual, + &m_sOutPortDef.nBufferSize, + m_sOutPortDef.nPortIndex); + DEBUG_PRINT_LOW("m_sOutPortDef: size = %d, min cnt = %d, actual cnt = %d", + m_sOutPortDef.nBufferSize, m_sOutPortDef.nBufferCountMin, + m_sOutPortDef.nBufferCountActual); + memcpy(portDefn, &m_sOutPortDef, sizeof(m_sOutPortDef)); + } + else + { + DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index"); + eRet = OMX_ErrorBadPortIndex; + } + break; + } + case OMX_IndexParamVideoInit: + { + OMX_PORT_PARAM_TYPE *portParamType = + (OMX_PORT_PARAM_TYPE *) paramData; + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit\n"); + + memcpy(portParamType, &m_sPortParam, sizeof(m_sPortParam)); + break; + } + case OMX_IndexParamVideoPortFormat: + { + OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt = + (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData; + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat\n"); + + if(portFmt->nPortIndex == (OMX_U32) PORT_INDEX_IN) + { + int index = portFmt->nIndex; + //we support following formats + //index 0 - YUV420SP32m + //index 1 - opaque which internally maps to YUV420SP. + //index 2 - YUV420SP + //this can be extended in the future + int supportedFormats[] = { + [0] = QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m, + [1] = QOMX_COLOR_FormatAndroidOpaque, + [2] = OMX_COLOR_FormatYUV420SemiPlanar, + }; + + if (index > sizeof(supportedFormats)/sizeof(*supportedFormats)) { + eRet = OMX_ErrorNoMore; + } else { + memcpy(portFmt, &m_sInPortFormat, sizeof(m_sInPortFormat)); + portFmt->nIndex = index; //restore index set from client + portFmt->eColorFormat = + (OMX_COLOR_FORMATTYPE)supportedFormats[index]; + } + } + else if(portFmt->nPortIndex == (OMX_U32) PORT_INDEX_OUT) + { + memcpy(portFmt, &m_sOutPortFormat, sizeof(m_sOutPortFormat)); + } + else + { + DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index"); + eRet = OMX_ErrorBadPortIndex; + } + break; + } + case OMX_IndexParamVideoBitrate: + { + OMX_VIDEO_PARAM_BITRATETYPE* pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData; + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoBitrate\n"); + + 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: + { + OMX_VIDEO_PARAM_MPEG4TYPE* pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData; + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4\n"); + memcpy(pParam, &m_sParamMPEG4, sizeof(m_sParamMPEG4)); + break; + } + case OMX_IndexParamVideoH263: + { + OMX_VIDEO_PARAM_H263TYPE* pParam = (OMX_VIDEO_PARAM_H263TYPE*)paramData; + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263\n"); + memcpy(pParam, &m_sParamH263, sizeof(m_sParamH263)); + break; + } + case OMX_IndexParamVideoAvc: + { + OMX_VIDEO_PARAM_AVCTYPE* pParam = (OMX_VIDEO_PARAM_AVCTYPE*)paramData; + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc\n"); + memcpy(pParam, &m_sParamAVC, sizeof(m_sParamAVC)); + break; + } + case OMX_IndexParamVideoProfileLevelQuerySupported: + { + OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData; + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported\n"); + eRet = get_supported_profile_level(pParam); + if(eRet) + DEBUG_PRINT_ERROR("Invalid entry returned from get_supported_profile_level %d, %d", + pParam->eProfile, pParam->eLevel); + break; + } + case OMX_IndexParamVideoProfileLevelCurrent: + { + OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData; + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelCurrent\n"); + memcpy(pParam, &m_sParamProfileLevel, sizeof(m_sParamProfileLevel)); + break; + } + /*Component should support this port definition*/ + case OMX_IndexParamAudioInit: + { + OMX_PORT_PARAM_TYPE *audioPortParamType = (OMX_PORT_PARAM_TYPE *) paramData; + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit\n"); + memcpy(audioPortParamType, &m_sPortParam_audio, sizeof(m_sPortParam_audio)); + break; + } + /*Component should support this port definition*/ + case OMX_IndexParamImageInit: + { + OMX_PORT_PARAM_TYPE *imagePortParamType = (OMX_PORT_PARAM_TYPE *) paramData; + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit\n"); + 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\n", paramIndex); + eRet =OMX_ErrorUnsupportedIndex; + break; + } + case OMX_IndexParamStandardComponentRole: + { + 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\n",paramIndex); + if(NULL != comp_role->cRole) + { + strlcpy((char*)comp_role->cRole,(const char*)m_cRole,OMX_MAX_STRINGNAME_SIZE); + } + else + { + DEBUG_PRINT_ERROR("ERROR: Getparameter: OMX_IndexParamStandardComponentRole %d is passed with NULL parameter for role\n",paramIndex); + eRet =OMX_ErrorBadParameter; + } + break; + } + /* Added for parameter test */ + case OMX_IndexParamPriorityMgmt: + { + + OMX_PRIORITYMGMTTYPE *priorityMgmType = (OMX_PRIORITYMGMTTYPE *) paramData; + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt\n"); + memcpy(priorityMgmType, &m_sPriorityMgmt, sizeof(m_sPriorityMgmt)); + break; + } + /* Added for parameter test */ + case OMX_IndexParamCompBufferSupplier: + { + OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData; + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier\n"); + 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: + { + OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp = (OMX_VIDEO_PARAM_QUANTIZATIONTYPE*) paramData; + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoQuantization\n"); + memcpy(session_qp, &m_sSessionQuantization, sizeof(m_sSessionQuantization)); + break; + } + + case OMX_QcomIndexParamVideoQPRange: + { + OMX_QCOM_VIDEO_PARAM_QPRANGETYPE *qp_range = (OMX_QCOM_VIDEO_PARAM_QPRANGETYPE*) paramData; + DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamVideoQPRange\n"); + memcpy(qp_range, &m_sSessionQPRange, sizeof(m_sSessionQPRange)); + break; + } + + case OMX_IndexParamVideoErrorCorrection: + { + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* errorresilience = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE*)paramData; + DEBUG_PRINT_LOW("OMX_IndexParamVideoErrorCorrection\n"); + errorresilience->bEnableHEC = m_sErrorCorrection.bEnableHEC; + errorresilience->bEnableResync = m_sErrorCorrection.bEnableResync; + errorresilience->nResynchMarkerSpacing = m_sErrorCorrection.nResynchMarkerSpacing; + break; + } + case OMX_IndexParamVideoIntraRefresh: + { + OMX_VIDEO_PARAM_INTRAREFRESHTYPE* intrarefresh = (OMX_VIDEO_PARAM_INTRAREFRESHTYPE*)paramData; + DEBUG_PRINT_LOW("OMX_IndexParamVideoIntraRefresh\n"); + DEBUG_PRINT_ERROR("OMX_IndexParamVideoIntraRefresh GET\n"); + intrarefresh->eRefreshMode = m_sIntraRefresh.eRefreshMode; + intrarefresh->nCirMBs = m_sIntraRefresh.nCirMBs; + break; + } + case OMX_QcomIndexPortDefn: + //TODO + break; + case OMX_COMPONENT_CAPABILITY_TYPE_INDEX: + { + OMXComponentCapabilityFlagsType *pParam = reinterpret_cast(paramData); + DEBUG_PRINT_LOW("get_parameter: OMX_COMPONENT_CAPABILITY_TYPE_INDEX\n"); + 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; + } +#ifndef MAX_RES_720P + case OMX_QcomIndexParamIndexExtraDataType: + { + DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamIndexExtraDataType"); + QOMX_INDEXEXTRADATATYPE *pParam = (QOMX_INDEXEXTRADATATYPE *)paramData; + if (pParam->nIndex == (OMX_INDEXTYPE)OMX_ExtraDataVideoEncoderSliceInfo) + { + if (pParam->nPortIndex == PORT_INDEX_OUT) + { + pParam->bEnabled = + (OMX_BOOL)((m_sExtraData & VEN_EXTRADATA_SLICEINFO) ? 1 : 0); + 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 + { + DEBUG_PRINT_ERROR("get_parameter: unsupported index (%x), " + "only slice information extradata is supported", pParam->nIndex); + eRet =OMX_ErrorUnsupportedIndex; + } + break; + } +#endif + case QOMX_IndexParamVideoSyntaxHdr: + { + DEBUG_PRINT_HIGH("QOMX_IndexParamVideoSyntaxHdr"); + QOMX_EXTNINDEX_PARAMTYPE* pParam = + reinterpret_cast(paramData); + m_flags = BITMASK_SET_U32(m_flags, OMX_COMPONENT_LOADED_START_PENDING); + if(dev_loaded_start()) + { + DEBUG_PRINT_LOW("device start successful"); + } + else + { + DEBUG_PRINT_ERROR("device start failed"); + m_flags = BITMASK_CLEAR_U32(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 *)&pParam->nDataSize)) + { + DEBUG_PRINT_HIGH("get syntax header successful (hdrlen = %d)", + 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; + } + m_flags = BITMASK_SET_U32(m_flags, OMX_COMPONENT_LOADED_STOP_PENDING); + if(dev_loaded_stop()) + { + DEBUG_PRINT_LOW("device stop successful"); + } + else + { + DEBUG_PRINT_ERROR("device stop failed"); + m_flags = BITMASK_CLEAR_U32(m_flags, OMX_COMPONENT_LOADED_STOP_PENDING); + eRet = OMX_ErrorHardware; + } + break; + } + case OMX_QcomIndexParamPictureOrderCountType: + { + QOMX_PICTURE_ORDER_COUNT_TYPE *pParam = (QOMX_PICTURE_ORDER_COUNT_TYPE *)paramData; + memcpy(pParam, &m_sPicureOrderCount, sizeof(m_sPicureOrderCount)); + break; + } + case OMX_IndexParamVideoSliceFMO: + default: + { + DEBUG_PRINT_LOW("ERROR: get_parameter: unknown param %08x\n", paramIndex); + eRet =OMX_ErrorUnsupportedIndex; + break; + } + + } + + return eRet; + +} +/* ====================================================================== +FUNCTION + omx_video::GetConfig + +DESCRIPTION + OMX Get Config Method implementation. + +PARAMETERS + . + +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) +{ + //////////////////////////////////////////////////////////////// + // Supported Config Index Type + // ============================================================= + // OMX_IndexConfigVideoBitrate OMX_VIDEO_CONFIG_BITRATETYPE + // OMX_IndexConfigVideoFramerate OMX_CONFIG_FRAMERATETYPE + // OMX_IndexConfigCommonRotate OMX_CONFIG_ROTATIONTYPE + //////////////////////////////////////////////////////////////// + + if(configData == NULL) + { + DEBUG_PRINT_ERROR("ERROR: param is null"); + return OMX_ErrorBadParameter; + } + + if(m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("ERROR: can't be in invalid state"); + return OMX_ErrorIncorrectStateOperation; + } + + //@todo need to validate params + switch(configIndex) + { + case OMX_IndexConfigVideoBitrate: + { + OMX_VIDEO_CONFIG_BITRATETYPE* pParam = reinterpret_cast(configData); + memcpy(pParam, &m_sConfigBitrate, sizeof(m_sConfigBitrate)); + break; + } + case OMX_IndexConfigVideoFramerate: + { + OMX_CONFIG_FRAMERATETYPE* pParam = reinterpret_cast(configData); + memcpy(pParam, &m_sConfigFramerate, sizeof(m_sConfigFramerate)); + break; + } + case OMX_IndexConfigCommonRotate: + { + OMX_CONFIG_ROTATIONTYPE* pParam = reinterpret_cast(configData); + memcpy(pParam, &m_sConfigFrameRotation, sizeof(m_sConfigFrameRotation)); + break; + } + case QOMX_IndexConfigVideoIntraperiod: + { + DEBUG_PRINT_LOW("get_config:QOMX_IndexConfigVideoIntraperiod\n"); + QOMX_VIDEO_INTRAPERIODTYPE* pParam = reinterpret_cast(configData); + memcpy(pParam, &m_sIntraperiod, sizeof(m_sIntraperiod)); + break; + } + case OMX_QcomIndexParamVideoPerformanceLevel: + { + DEBUG_PRINT_LOW("get_config:OMX_QcomIndexParamVideoPerformanceLevel\n"); + OMX_QCOM_QUERY_PERFORMANCE *pParam = reinterpret_cast(configData); + pParam->performance = m_curr_perf; + break; + } + default: + DEBUG_PRINT_ERROR("ERROR: unsupported index %d", (int) configIndex); + return OMX_ErrorUnsupportedIndex; + } + return OMX_ErrorNone; + +} + +/* ====================================================================== +FUNCTION + omx_video::GetExtensionIndex + +DESCRIPTION + OMX GetExtensionIndex method implementaion. + +PARAMETERS + . + +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) +{ + char *extns[] = { + "OMX.QCOM.index.param.SliceDeliveryMode", + "OMX.google.android.index.storeMetaDataInBuffers", + "OMX.google.android.index.prependSPSPPSToIDRFrames", + "OMX.google.android.index.setVUIStreamRestrictFlag" + }; + + if(m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("ERROR: Get Extension Index in Invalid State\n"); + return OMX_ErrorInvalidState; + } +#ifdef MAX_RES_1080P + if (!strncmp(paramName, extns[0], strlen(extns[0]))) { + *indexType = (OMX_INDEXTYPE)OMX_QcomIndexEnableSliceDeliveryMode; + return OMX_ErrorNone; + } +#endif +#ifdef _ANDROID_ICS_ + if (!strncmp(paramName, extns[1], strlen(extns[1]))) { + *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoEncodeMetaBufferMode; + return OMX_ErrorNone; + } else if (!strncmp(paramName, extns[2], strlen(extns[2]))) { + *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamSequenceHeaderWithIDR; + return OMX_ErrorNone; + } else if (!strncmp(paramName, extns[3], strlen(extns[3]))) { + *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamEnableVUIStreamRestrictFlag; + return OMX_ErrorNone; + } +#endif + return OMX_ErrorNotImplemented; +} + +/* ====================================================================== +FUNCTION + omx_video::GetState + +DESCRIPTION + Returns the state information back to the caller. + +PARAMETERS + . + +RETURN VALUE + Error None if everything is successful. +========================================================================== */ +OMX_ERRORTYPE omx_video::get_state(OMX_IN OMX_HANDLETYPE hComp, + OMX_OUT OMX_STATETYPE* state) +{ + *state = m_state; + DEBUG_PRINT_LOW("get_state: Returning the state %d\n",*state); + return OMX_ErrorNone; +} + +/* ====================================================================== +FUNCTION + omx_video::ComponentTunnelRequest + +DESCRIPTION + OMX Component Tunnel Request method implementation. + +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) +{ + DEBUG_PRINT_ERROR("ERROR: component_tunnel_request Not Implemented\n"); + 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) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + + unsigned i = 0; + unsigned char *buf_addr = NULL; + + DEBUG_PRINT_HIGH("use_input_buffer: port = %d appData = %p bytes = %d buffer = %p",port,appData,bytes,buffer); + if(bytes != m_sInPortDef.nBufferSize || secure_session) + { + DEBUG_PRINT_ERROR("\nERROR: use_input_buffer: Size Mismatch!! " + "bytes[%d] != Port.nBufferSize[%d]", bytes, 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("\nERROR: calloc() Failed for m_inp_mem_ptr"); + return OMX_ErrorInsufficientResources; + } + + + m_pInput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sInPortDef.nBufferCountActual); + if(m_pInput_pmem == NULL) + { + DEBUG_PRINT_ERROR("\nERROR: 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("\nERROR: 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=NULL; +#endif + } + + } + + for(i=0; i< m_sInPortDef.nBufferCountActual; i++) + { + if(BITMASK_ABSENT_U32(m_inp_bm_count,i)) + { + break; + } + } + + if(i < m_sInPortDef.nBufferCountActual) + { + + *bufferHdr = (m_inp_mem_ptr + i); + m_inp_bm_count = BITMASK_SET_U32(m_inp_bm_count,i); + + (*bufferHdr)->pBuffer = (OMX_U8 *)buffer; + (*bufferHdr)->nSize = sizeof(OMX_BUFFERHEADERTYPE); + (*bufferHdr)->nVersion.nVersion = OMX_SPEC_VERSION; + (*bufferHdr)->nAllocLen = m_sInPortDef.nBufferSize; + (*bufferHdr)->pAppPrivate = appData; + (*bufferHdr)->nInputPortIndex = PORT_INDEX_IN; + + if(!m_use_input_pmem) + { +#ifdef USE_ION + m_pInput_ion[i].ion_device_fd = alloc_map_ion_memory(m_sInPortDef.nBufferSize, + &m_pInput_ion[i].ion_alloc_data, + &m_pInput_ion[i].fd_ion_data,ION_FLAG_CACHED); + if(m_pInput_ion[i].ion_device_fd < 0) { + DEBUG_PRINT_ERROR("\nERROR: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("\nERROR: /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 = (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("\nERROR: mmap() Failed"); +#ifndef USE_ION + close(m_pInput_pmem[i].fd); +#else + free_ion_memory(&m_pInput_ion[i]); +#endif + m_pInput_pmem[i].fd = -1; + return OMX_ErrorInsufficientResources; + } + } + else + { + OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pParam = reinterpret_cast((*bufferHdr)->pAppPrivate); + DEBUG_PRINT_LOW("Inside qcom_ext with luma:(fd:%d,offset:0x%x)", pParam->pmem_fd, 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("\n DBG:: pParam->pmem_fd = %u, pParam->offset = %u", + pParam->pmem_fd, pParam->offset); + } + else + { + DEBUG_PRINT_ERROR("ERROR: Invalid AppData given for PMEM i/p UseBuffer case"); + return OMX_ErrorBadParameter; + } + } + + DEBUG_PRINT_LOW("\nuse_inp:: bufhdr = %p, pBuffer = %p, m_pInput_pmem[i].buffer = %p", + (*bufferHdr), (*bufferHdr)->pBuffer, m_pInput_pmem[i].buffer); + if( dev_use_buf(&m_pInput_pmem[i],PORT_INDEX_IN,i) != true) + { + DEBUG_PRINT_ERROR("\nERROR: dev_use_buf() Failed for i/p buf"); + return OMX_ErrorInsufficientResources; + } + } + else + { + DEBUG_PRINT_ERROR("\nERROR: All buffers are already used, invalid use_buf call for " + "index = %u", i); + eRet = OMX_ErrorInsufficientResources; + } + + return eRet; +} + + + +/* ====================================================================== +FUNCTION + omx_video::UseOutputBuffer + +DESCRIPTION + Helper function for Use buffer in the input pin + +PARAMETERS + None. + +RETURN VALUE + true/false + +========================================================================== */ +OMX_ERRORTYPE omx_video::use_output_buffer( + OMX_IN OMX_HANDLETYPE hComp, + OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, + OMX_IN OMX_U32 port, + OMX_IN OMX_PTR appData, + OMX_IN OMX_U32 bytes, + OMX_IN OMX_U8* buffer) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header + unsigned i= 0; // Temporary counter + unsigned char *buf_addr = NULL; + + DEBUG_PRINT_HIGH("\n Inside use_output_buffer()"); + if(bytes != m_sOutPortDef.nBufferSize || secure_session) + { + DEBUG_PRINT_ERROR("\nERROR: use_output_buffer: Size Mismatch!! " + "bytes[%d] != Port.nBufferSize[%d]", bytes, m_sOutPortDef.nBufferSize); + return OMX_ErrorBadParameter; + } + + if(!m_out_mem_ptr) + { + output_use_buffer = true; + int nBufHdrSize = 0; + + DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)\n",m_sOutPortDef.nBufferCountActual); + nBufHdrSize = m_sOutPortDef.nBufferCountActual * sizeof(OMX_BUFFERHEADERTYPE); + /* + * Memory for output side involves the following: + * 1. Array of Buffer Headers + * 2. Bitmask array to hold the buffer allocation details + * In order to minimize the memory management entire allocation + * is done in one step. + */ + //OMX Buffer header + m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1); + if(m_out_mem_ptr == NULL) + { + DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_out_mem_ptr"); + return OMX_ErrorInsufficientResources; + } + + m_pOutput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sOutPortDef.nBufferCountActual); + if(m_pOutput_pmem == NULL) + { + DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pOutput_pmem"); + return OMX_ErrorInsufficientResources; + } +#ifdef USE_ION + m_pOutput_ion = (struct venc_ion *) calloc(sizeof (struct venc_ion), m_sOutPortDef.nBufferCountActual); + if(m_pOutput_ion == NULL) + { + DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pOutput_ion"); + return OMX_ErrorInsufficientResources; + } +#endif + if(m_out_mem_ptr) + { + bufHdr = m_out_mem_ptr; + DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr); + // Settting the entire storage nicely + for(i=0; i < m_sOutPortDef.nBufferCountActual ; i++) + { + bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE); + bufHdr->nVersion.nVersion = OMX_SPEC_VERSION; + bufHdr->nAllocLen = bytes; + bufHdr->nFilledLen = 0; + bufHdr->pAppPrivate = appData; + bufHdr->nOutputPortIndex = PORT_INDEX_OUT; + bufHdr->pBuffer = NULL; + bufHdr++; + m_pOutput_pmem[i].fd = -1; +#ifdef USE_ION + m_pOutput_ion[i].ion_device_fd =-1; + m_pOutput_ion[i].fd_ion_data.fd=-1; + m_pOutput_ion[i].ion_alloc_data.handle =NULL; +#endif + } + } + else + { + DEBUG_PRINT_ERROR("ERROR: Output buf mem alloc failed[0x%x]\n",m_out_mem_ptr); + eRet = OMX_ErrorInsufficientResources; + } + } + + for(i=0; i< m_sOutPortDef.nBufferCountActual; i++) + { + if(BITMASK_ABSENT_U32(m_out_bm_count,i)) + { + break; + } + } + + if(eRet == OMX_ErrorNone) + { + if(i < m_sOutPortDef.nBufferCountActual) + { + *bufferHdr = (m_out_mem_ptr + i ); + (*bufferHdr)->pBuffer = (OMX_U8 *)buffer; + (*bufferHdr)->pAppPrivate = appData; + m_out_bm_count = BITMASK_SET_U32(m_out_bm_count,i); + + if(!m_use_output_pmem) + { +#ifdef USE_ION + m_pOutput_ion[i].ion_device_fd = alloc_map_ion_memory( + m_sOutPortDef.nBufferSize, + &m_pOutput_ion[i].ion_alloc_data, + &m_pOutput_ion[i].fd_ion_data,ION_FLAG_CACHED); + if(m_pOutput_ion[i].ion_device_fd < 0) { + DEBUG_PRINT_ERROR("\nERROR:ION device open() Failed"); + return OMX_ErrorInsufficientResources; + } + m_pOutput_pmem[i].fd = m_pOutput_ion[i].fd_ion_data.fd; +#else + m_pOutput_pmem[i].fd = open (MEM_DEVICE,O_RDWR); + + if(m_pOutput_pmem[i].fd == 0) + { + m_pOutput_pmem[i].fd = open (MEM_DEVICE,O_RDWR); + } + + if(m_pOutput_pmem[i].fd < 0) + { + DEBUG_PRINT_ERROR("\nERROR: /dev/pmem_adsp open() Failed"); + return OMX_ErrorInsufficientResources; + } +#endif + m_pOutput_pmem[i].size = m_sOutPortDef.nBufferSize; + m_pOutput_pmem[i].offset = 0; + m_pOutput_pmem[i].buffer = (unsigned char *)mmap(NULL,m_pOutput_pmem[i].size,PROT_READ|PROT_WRITE, + MAP_SHARED,m_pOutput_pmem[i].fd,0); + if(m_pOutput_pmem[i].buffer == MAP_FAILED) + { + DEBUG_PRINT_ERROR("\nERROR: mmap() Failed"); +#ifndef USE_ION + close(m_pOutput_pmem[i].fd); +#else + free_ion_memory(&m_pOutput_ion[i]); +#endif + m_pOutput_pmem[i].fd = -1; + return OMX_ErrorInsufficientResources; + } + } + else + { + OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pParam = reinterpret_cast((*bufferHdr)->pAppPrivate); + DEBUG_PRINT_LOW("Inside qcom_ext pParam:0x%x )", pParam); + + if(pParam) + { + DEBUG_PRINT_LOW("Inside qcom_ext with luma:(fd:%d,offset:0x%x)", pParam->pmem_fd, pParam->offset); + m_pOutput_pmem[i].fd = pParam->pmem_fd; + m_pOutput_pmem[i].offset = pParam->offset; + m_pOutput_pmem[i].size = m_sOutPortDef.nBufferSize; + m_pOutput_pmem[i].buffer = (unsigned char *)buffer; + } + else + { + DEBUG_PRINT_ERROR("ERROR: Invalid AppData given for PMEM o/p UseBuffer case"); + return OMX_ErrorBadParameter; + } + buf_addr = (unsigned char *)buffer; + } + + DEBUG_PRINT_LOW("\n use_out:: bufhdr = %p, pBuffer = %p, m_pOutput_pmem[i].buffer = %p", + (*bufferHdr), (*bufferHdr)->pBuffer, m_pOutput_pmem[i].buffer); + if(dev_use_buf(&m_pOutput_pmem[i],PORT_INDEX_OUT,i) != true) + { + DEBUG_PRINT_ERROR("ERROR: dev_use_buf Failed for o/p buf"); + return OMX_ErrorInsufficientResources; + } + } + else + { + DEBUG_PRINT_ERROR("ERROR: All o/p Buffers have been Used, invalid use_buf call for " + "index = %u", i); + eRet = OMX_ErrorInsufficientResources; + } + } + return eRet; +} + + +/* ====================================================================== +FUNCTION + omx_video::UseBuffer + +DESCRIPTION + OMX Use Buffer method implementation. + +PARAMETERS + . + +RETURN VALUE + OMX Error None , if everything successful. + +========================================================================== */ +OMX_ERRORTYPE omx_video::use_buffer( + OMX_IN OMX_HANDLETYPE hComp, + OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, + OMX_IN OMX_U32 port, + OMX_IN OMX_PTR appData, + OMX_IN OMX_U32 bytes, + OMX_IN OMX_U8* buffer) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + if(m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("ERROR: Use Buffer in Invalid State\n"); + return OMX_ErrorInvalidState; + } + if(port == PORT_INDEX_IN) + { + eRet = use_input_buffer(hComp,bufferHdr,port,appData,bytes,buffer); + } + else if(port == PORT_INDEX_OUT) + { + eRet = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); + } + else + { + DEBUG_PRINT_ERROR("ERROR: Invalid Port Index received %d\n",(int)port); + eRet = OMX_ErrorBadPortIndex; + } + + if(eRet == OMX_ErrorNone) + { + if(allocate_done()) + { + if(BITMASK_PRESENT_U32(m_flags,OMX_COMPONENT_IDLE_PENDING)) + { + // Send the callback now + m_flags = BITMASK_CLEAR_U32(m_flags,OMX_COMPONENT_IDLE_PENDING); + post_event(OMX_CommandStateSet,OMX_StateIdle, + OMX_COMPONENT_GENERATE_EVENT); + } + } + if(port == PORT_INDEX_IN && m_sInPortDef.bPopulated) + { + if(BITMASK_PRESENT_U32(m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) + { + m_flags = BITMASK_CLEAR_U32(m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING); + post_event(OMX_CommandPortEnable, + PORT_INDEX_IN, + OMX_COMPONENT_GENERATE_EVENT); + } + + } + else if(port == PORT_INDEX_OUT && m_sOutPortDef.bPopulated) + { + if(BITMASK_PRESENT_U32(m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) + { + m_flags = BITMASK_CLEAR_U32(m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING); + post_event(OMX_CommandPortEnable, + PORT_INDEX_OUT, + OMX_COMPONENT_GENERATE_EVENT); + m_event_port_settings_sent = false; + } + } + } + return eRet; +} + +OMX_ERRORTYPE omx_video::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr) +{ + unsigned int index = 0; + OMX_U8 *temp_buff ; + + if(bufferHdr == NULL || m_inp_mem_ptr == NULL) + { + DEBUG_PRINT_ERROR("ERROR: free_input: Invalid bufferHdr[%p] or m_inp_mem_ptr[%p]", + bufferHdr, m_inp_mem_ptr); + return OMX_ErrorBadParameter; + } + + index = bufferHdr - ((!mUseProxyColorFormat)?m_inp_mem_ptr:meta_buffer_hdr); +#ifdef _ANDROID_ICS_ + if(meta_mode_enable) + { + if(index < m_sInPortDef.nBufferCountActual) + { + memset(&meta_buffer_hdr[index], 0, sizeof(meta_buffer_hdr[index])); + memset(&meta_buffers[index], 0, sizeof(meta_buffers[index])); + } + if(!mUseProxyColorFormat) + return OMX_ErrorNone; + else { + c2d_conv.close(); + opaque_buffer_hdr[index] = NULL; + } + } +#endif + if(index < m_sInPortDef.nBufferCountActual && !mUseProxyColorFormat && + dev_free_buf(&m_pInput_pmem[index],PORT_INDEX_IN) != true) + { + DEBUG_PRINT_LOW("\nERROR: dev_free_buf() Failed for i/p buf"); + } + + if(index < m_sInPortDef.nBufferCountActual && m_pInput_pmem) + { + if(m_pInput_pmem[index].fd > 0 && input_use_buffer == false) + { + DEBUG_PRINT_LOW("\n FreeBuffer:: i/p AllocateBuffer case"); + munmap (m_pInput_pmem[index].buffer,m_pInput_pmem[index].size); +#ifndef USE_ION + close (m_pInput_pmem[index].fd); +#else + free_ion_memory(&m_pInput_ion[index]); +#endif + m_pInput_pmem[index].fd = -1; + } + else if(m_pInput_pmem[index].fd > 0 && (input_use_buffer == true && + m_use_input_pmem == OMX_FALSE)) + { + DEBUG_PRINT_LOW("\n FreeBuffer:: i/p Heap UseBuffer case"); + if(dev_free_buf(&m_pInput_pmem[index],PORT_INDEX_IN) != true) + { + DEBUG_PRINT_ERROR("\nERROR: dev_free_buf() Failed for i/p buf"); + } + munmap (m_pInput_pmem[index].buffer,m_pInput_pmem[index].size); +#ifndef USE_ION + close (m_pInput_pmem[index].fd); +#else + free_ion_memory(&m_pInput_ion[index]); +#endif + m_pInput_pmem[index].fd = -1; + } + else + { + DEBUG_PRINT_ERROR("\n FreeBuffer:: fd is invalid or i/p PMEM UseBuffer case"); + } + } + return OMX_ErrorNone; +} + +OMX_ERRORTYPE omx_video::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr) +{ + unsigned int index = 0; + OMX_U8 *temp_buff ; + + if(bufferHdr == NULL || m_out_mem_ptr == NULL) + { + DEBUG_PRINT_ERROR("ERROR: free_output: Invalid bufferHdr[%p] or m_out_mem_ptr[%p]", + bufferHdr, m_out_mem_ptr); + return OMX_ErrorBadParameter; + } + index = bufferHdr - m_out_mem_ptr; + + if(index < m_sOutPortDef.nBufferCountActual && + dev_free_buf(&m_pOutput_pmem[index],PORT_INDEX_OUT) != true) + { + DEBUG_PRINT_ERROR("ERROR: dev_free_buf Failed for o/p buf"); + } + + if(index < m_sOutPortDef.nBufferCountActual && m_pOutput_pmem) + { + if(m_pOutput_pmem[index].fd > 0 && output_use_buffer == false ) + { + DEBUG_PRINT_LOW("\n FreeBuffer:: o/p AllocateBuffer case"); + if(!secure_session) + munmap (m_pOutput_pmem[index].buffer,m_pOutput_pmem[index].size); +#ifndef USE_ION + close (m_pOutput_pmem[index].fd); +#else + free_ion_memory(&m_pOutput_ion[index]); +#endif + m_pOutput_pmem[index].fd = -1; + } + else if( m_pOutput_pmem[index].fd > 0 && (output_use_buffer == true + && m_use_output_pmem == OMX_FALSE)) + { + DEBUG_PRINT_LOW("\n FreeBuffer:: o/p Heap UseBuffer case"); + if(dev_free_buf(&m_pOutput_pmem[index],PORT_INDEX_OUT) != true) + { + DEBUG_PRINT_ERROR("ERROR: dev_free_buf Failed for o/p buf"); + } + munmap (m_pOutput_pmem[index].buffer,m_pOutput_pmem[index].size); +#ifndef USE_ION + close (m_pOutput_pmem[index].fd); +#else + free_ion_memory(&m_pOutput_ion[index]); +#endif + m_pOutput_pmem[index].fd = -1; + } + else + { + DEBUG_PRINT_LOW("\n FreeBuffer:: fd is invalid or o/p PMEM UseBuffer case"); + } + } + return OMX_ErrorNone; +} +#ifdef _ANDROID_ICS_ +OMX_ERRORTYPE omx_video::allocate_input_meta_buffer( + OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE **bufferHdr, + OMX_PTR appData, + OMX_U32 bytes) +{ + unsigned index = 0; + if(!bufferHdr || bytes != sizeof(encoder_media_buffer_type)) + { + DEBUG_PRINT_ERROR("wrong params allocate_input_meta_buffer Hdr %p len %d", + bufferHdr,bytes); + return OMX_ErrorBadParameter; + } + if(!m_inp_mem_ptr && !mUseProxyColorFormat) + m_inp_mem_ptr = meta_buffer_hdr; + for(index = 0;((index < m_sInPortDef.nBufferCountActual) && + meta_buffer_hdr[index].pBuffer); index++); + if(index == m_sInPortDef.nBufferCountActual) + { + DEBUG_PRINT_ERROR("All buffers are allocated input_meta_buffer"); + return OMX_ErrorBadParameter; + } + if(mUseProxyColorFormat){ + if(opaque_buffer_hdr[index]){ + DEBUG_PRINT_ERROR("All buffers are allocated opaque_buffer_hdr"); + return OMX_ErrorBadParameter; + } + if(allocate_input_buffer(hComp,&opaque_buffer_hdr[index], + PORT_INDEX_IN,appData,m_sInPortDef.nBufferSize) != OMX_ErrorNone) { + DEBUG_PRINT_ERROR("All buffers are allocated opaque_buffer_hdr"); + return OMX_ErrorBadParameter; + } + } + m_inp_bm_count = BITMASK_SET_U32(m_inp_bm_count,index); + *bufferHdr = &meta_buffer_hdr[index]; + memset(&meta_buffer_hdr[index], 0, sizeof(meta_buffer_hdr[index])); + meta_buffer_hdr[index].nSize = sizeof(meta_buffer_hdr[index]); + meta_buffer_hdr[index].nAllocLen = bytes; + meta_buffer_hdr[index].nVersion.nVersion = OMX_SPEC_VERSION; + meta_buffer_hdr[index].nInputPortIndex = PORT_INDEX_IN; + meta_buffer_hdr[index].pBuffer = (OMX_U8*)&meta_buffers[index]; + meta_buffer_hdr[index].pAppPrivate = appData; + if(mUseProxyColorFormat) { + m_opq_pmem_q.insert_entry((unsigned int)opaque_buffer_hdr[index],0,0); + DEBUG_PRINT_HIGH("\n opaque_buffer_hdr insert %p", opaque_buffer_hdr[index]); + } + return OMX_ErrorNone; +} +#endif +/* ====================================================================== +FUNCTION + omx_venc::AllocateInputBuffer + +DESCRIPTION + Helper function for allocate buffer in the input pin + +PARAMETERS + None. + +RETURN VALUE + true/false + +========================================================================== */ +OMX_ERRORTYPE omx_video::allocate_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_ERRORTYPE eRet = OMX_ErrorNone; + unsigned i = 0; + int flags = 0; + + DEBUG_PRINT_HIGH("\n allocate_input_buffer()::"); + if(bytes != m_sInPortDef.nBufferSize || secure_session) + { + DEBUG_PRINT_ERROR("\nERROR: Buffer size mismatch error: bytes[%u] != nBufferSize[%u]\n", + bytes, m_sInPortDef.nBufferSize); + return OMX_ErrorBadParameter; + } + + if(!m_inp_mem_ptr) + { + DEBUG_PRINT_HIGH("%s: size = %d, actual cnt %d", __FUNCTION__, + m_sInPortDef.nBufferSize, m_sInPortDef.nBufferCountActual); + m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \ + calloc( (sizeof(OMX_BUFFERHEADERTYPE)), m_sInPortDef.nBufferCountActual); + if(m_inp_mem_ptr == NULL) + { + DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_inp_mem_ptr"); + return OMX_ErrorInsufficientResources; + } + + m_pInput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sInPortDef.nBufferCountActual); + + if(m_pInput_pmem == NULL) + { + DEBUG_PRINT_ERROR("\nERROR: 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("\nERROR: 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=NULL; +#endif + } + } + + for(i=0; i< m_sInPortDef.nBufferCountActual; i++) + { + if(BITMASK_ABSENT_U32(m_inp_bm_count,i)) + { + break; + } + } + if(i < m_sInPortDef.nBufferCountActual) + { + + *bufferHdr = (m_inp_mem_ptr + i); + (*bufferHdr)->nSize = sizeof(OMX_BUFFERHEADERTYPE); + (*bufferHdr)->nVersion.nVersion = OMX_SPEC_VERSION; + (*bufferHdr)->nAllocLen = m_sInPortDef.nBufferSize; + (*bufferHdr)->pAppPrivate = appData; + (*bufferHdr)->nInputPortIndex = PORT_INDEX_IN; +#ifdef USE_ION + if (dev_get_uncache_flag()) + { + flags = 0; + DEBUG_PRINT_HIGH("uncache buffers requested"); + } + else + { + flags = ION_FLAG_CACHED; + } + + 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, flags); + if(m_pInput_ion[i].ion_device_fd < 0) { + DEBUG_PRINT_ERROR("\nERROR: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("\nERROR: /dev/pmem_adsp open() Failed\n"); + return OMX_ErrorInsufficientResources; + } +#endif + m_pInput_pmem[i].size = m_sInPortDef.nBufferSize; + m_pInput_pmem[i].offset = 0; + + 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("\nERROR: mmap FAILED= %d\n", errno); +#ifndef USE_ION + close(m_pInput_pmem[i].fd); +#else + free_ion_memory(&m_pInput_ion[i]); +#endif + m_pInput_pmem[i].fd = -1; + return OMX_ErrorInsufficientResources; + } + + (*bufferHdr)->pBuffer = (OMX_U8 *)m_pInput_pmem[i].buffer; + DEBUG_PRINT_LOW("\n Virtual address in allocate buffer is %p", m_pInput_pmem[i].buffer); + m_inp_bm_count = BITMASK_SET_U32(m_inp_bm_count,i); + //here change the I/P param here from buf_adr to pmem + if(!mUseProxyColorFormat && (dev_use_buf(&m_pInput_pmem[i],PORT_INDEX_IN,i) != true)) + { + DEBUG_PRINT_ERROR("\nERROR: dev_use_buf FAILED for i/p buf\n"); + return OMX_ErrorInsufficientResources; + } + } + else + { + DEBUG_PRINT_ERROR("\nERROR: All i/p buffers are allocated, invalid allocate buf call" + "for index [%d]\n", i); + eRet = OMX_ErrorInsufficientResources; + } + + return eRet; +} + + +/* ====================================================================== +FUNCTION + omx_venc::AllocateOutputBuffer + +DESCRIPTION + Helper fn for AllocateBuffer in the output pin + +PARAMETERS + . + +RETURN VALUE + OMX Error None if everything went well. + +========================================================================== */ +OMX_ERRORTYPE omx_video::allocate_output_buffer( + OMX_IN OMX_HANDLETYPE hComp, + OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, + OMX_IN OMX_U32 port, + OMX_IN OMX_PTR appData, + OMX_IN OMX_U32 bytes) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header + unsigned i= 0; // Temporary counter + + if(!m_out_mem_ptr) + { + int nBufHdrSize = 0; + DEBUG_PRINT_HIGH("%s: size = %d, actual cnt %d", __FUNCTION__, + m_sOutPortDef.nBufferSize, m_sOutPortDef.nBufferCountActual); + nBufHdrSize = m_sOutPortDef.nBufferCountActual * sizeof(OMX_BUFFERHEADERTYPE); + + /* + * Memory for output side involves the following: + * 1. Array of Buffer Headers + * 2. Bitmask array to hold the buffer allocation details + * In order to minimize the memory management entire allocation + * is done in one step. + */ + m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1); + +#ifdef USE_ION + m_pOutput_ion = (struct venc_ion *) calloc(sizeof (struct venc_ion), m_sOutPortDef.nBufferCountActual); + if(m_pOutput_ion == NULL) + { + DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pOutput_ion"); + return OMX_ErrorInsufficientResources; + } +#endif + m_pOutput_pmem = (struct pmem *) calloc(sizeof(struct pmem), m_sOutPortDef.nBufferCountActual); + if(m_pOutput_pmem == NULL) + { + DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pOutput_pmem"); + return OMX_ErrorInsufficientResources; + } + if(m_out_mem_ptr && m_pOutput_pmem) + { + bufHdr = m_out_mem_ptr; + + for(i=0; i < m_sOutPortDef.nBufferCountActual ; i++) + { + bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE); + bufHdr->nVersion.nVersion = OMX_SPEC_VERSION; + // Set the values when we determine the right HxW param + bufHdr->nAllocLen = bytes; + bufHdr->nFilledLen = 0; + bufHdr->pAppPrivate = appData; + bufHdr->nOutputPortIndex = PORT_INDEX_OUT; + bufHdr->pBuffer = NULL; + bufHdr++; + m_pOutput_pmem[i].fd = -1; +#ifdef USE_ION + m_pOutput_ion[i].ion_device_fd =-1; + m_pOutput_ion[i].fd_ion_data.fd=-1; + m_pOutput_ion[i].ion_alloc_data.handle =NULL; +#endif + } + } + else + { + DEBUG_PRINT_ERROR("ERROR: calloc() failed for m_out_mem_ptr/m_pOutput_pmem"); + eRet = OMX_ErrorInsufficientResources; + } + } + + for(i=0; i< m_sOutPortDef.nBufferCountActual; i++) + { + if(BITMASK_ABSENT_U32(m_out_bm_count,i)) + { + DEBUG_PRINT_LOW("\n Found a Free Output Buffer %d",i); + break; + } + } + if(eRet == OMX_ErrorNone) + { + if(i < m_sOutPortDef.nBufferCountActual) + { +#ifdef USE_ION + m_pOutput_ion[i].ion_device_fd = alloc_map_ion_memory(m_sOutPortDef.nBufferSize, + &m_pOutput_ion[i].ion_alloc_data, + &m_pOutput_ion[i].fd_ion_data,ION_FLAG_CACHED); + if(m_pOutput_ion[i].ion_device_fd < 0) { + DEBUG_PRINT_ERROR("\nERROR:ION device open() Failed"); + return OMX_ErrorInsufficientResources; + } + m_pOutput_pmem[i].fd = m_pOutput_ion[i].fd_ion_data.fd; +#else + m_pOutput_pmem[i].fd = open (MEM_DEVICE,O_RDWR); + if(m_pOutput_pmem[i].fd == 0) + { + m_pOutput_pmem[i].fd = open (MEM_DEVICE,O_RDWR); + } + + if(m_pOutput_pmem[i].fd < 0) + { + DEBUG_PRINT_ERROR("\nERROR: /dev/pmem_adsp open() failed"); + return OMX_ErrorInsufficientResources; + } +#endif + m_pOutput_pmem[i].size = m_sOutPortDef.nBufferSize; + m_pOutput_pmem[i].offset = 0; + if(!secure_session) { + m_pOutput_pmem[i].buffer = (unsigned char *)mmap(NULL,m_pOutput_pmem[i].size,PROT_READ|PROT_WRITE, + MAP_SHARED,m_pOutput_pmem[i].fd,0); + if(m_pOutput_pmem[i].buffer == MAP_FAILED) + { + DEBUG_PRINT_ERROR("\nERROR: MMAP_FAILED in o/p alloc buffer"); +#ifndef USE_ION + close (m_pOutput_pmem[i].fd); +#else + free_ion_memory(&m_pOutput_ion[i]); +#endif + m_pOutput_pmem[i].fd = -1; + return OMX_ErrorInsufficientResources; + } + } + + *bufferHdr = (m_out_mem_ptr + i ); + if(!secure_session) + (*bufferHdr)->pBuffer = (OMX_U8 *)m_pOutput_pmem[i].buffer; + else { + m_pOutput_pmem[i].buffer = (OMX_U8 *)(i + 12345); + (*bufferHdr)->pBuffer = (OMX_U8 *)(i + 12345); + } + (*bufferHdr)->pAppPrivate = appData; + + m_out_bm_count = BITMASK_SET_U32(m_out_bm_count,i); +#ifdef USE_ION + DEBUG_PRINT_HIGH("alloc_output: idx = %d, fd = %d, addr = %p, offset = %d, " + "ion_device_fd = %d, ion_handle = %p, length = %d", i, + m_pOutput_pmem[i].fd, m_pOutput_pmem[i].buffer, m_pOutput_pmem[i].offset, + m_pOutput_ion[i].ion_device_fd, m_pOutput_ion[i].ion_alloc_data.handle, + m_pOutput_pmem[i].size); +#endif + if(dev_use_buf(&m_pOutput_pmem[i],PORT_INDEX_OUT,i) != true) + { + DEBUG_PRINT_ERROR("\nERROR: dev_use_buf FAILED for o/p buf"); + return OMX_ErrorInsufficientResources; + } + } + else + { + DEBUG_PRINT_ERROR("\nERROR: All o/p buffers are allocated, invalid allocate buf call" + "for index [%d]\n", i); + } + } + + return eRet; +} + + +// AllocateBuffer -- API Call +/* ====================================================================== +FUNCTION + omx_video::AllocateBuffer + +DESCRIPTION + Returns zero if all the buffers released.. + +PARAMETERS + None. + +RETURN VALUE + true/false + +========================================================================== */ +OMX_ERRORTYPE omx_video::allocate_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_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type + + DEBUG_PRINT_LOW("\n Allocate buffer of size = %d on port %d \n", bytes, (int)port); + if(m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("ERROR: Allocate Buf in Invalid State\n"); + return OMX_ErrorInvalidState; + } + + // What if the client calls again. + if(port == PORT_INDEX_IN) + { +#ifdef _ANDROID_ICS_ + if(meta_mode_enable) + eRet = allocate_input_meta_buffer(hComp,bufferHdr,appData,bytes); + else +#endif + eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes); + } + else if(port == PORT_INDEX_OUT) + { + eRet = allocate_output_buffer(hComp,bufferHdr,port,appData,bytes); + } + else + { + DEBUG_PRINT_ERROR("ERROR: Invalid Port Index received %d\n",(int)port); + eRet = OMX_ErrorBadPortIndex; + } + DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done"); + if(eRet == OMX_ErrorNone) + { + if(allocate_done()) + { + if(BITMASK_PRESENT_U32(m_flags,OMX_COMPONENT_IDLE_PENDING)) + { + // Send the callback now + m_flags = BITMASK_CLEAR_U32(m_flags,OMX_COMPONENT_IDLE_PENDING); + post_event(OMX_CommandStateSet,OMX_StateIdle, + OMX_COMPONENT_GENERATE_EVENT); + } + } + if(port == PORT_INDEX_IN && m_sInPortDef.bPopulated) + { + if(BITMASK_PRESENT_U32(m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) + { + m_flags = BITMASK_CLEAR_U32(m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING); + post_event(OMX_CommandPortEnable, + PORT_INDEX_IN, + OMX_COMPONENT_GENERATE_EVENT); + } + } + if(port == PORT_INDEX_OUT && m_sOutPortDef.bPopulated) + { + if(BITMASK_PRESENT_U32(m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) + { + m_flags = BITMASK_CLEAR_U32(m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING); + post_event(OMX_CommandPortEnable, + PORT_INDEX_OUT, + OMX_COMPONENT_GENERATE_EVENT); + m_event_port_settings_sent = false; + } + } + } + DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d\n",eRet); + return eRet; +} + + +// Free Buffer - API call +/* ====================================================================== +FUNCTION + omx_video::FreeBuffer + +DESCRIPTION + +PARAMETERS + None. + +RETURN VALUE + true/false + +========================================================================== */ +OMX_ERRORTYPE omx_video::free_buffer(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_U32 port, + OMX_IN OMX_BUFFERHEADERTYPE* buffer) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + unsigned int nPortIndex; + + DEBUG_PRINT_LOW("In for decoder free_buffer \n"); + + if(m_state == OMX_StateIdle && + (BITMASK_PRESENT_U32(m_flags ,OMX_COMPONENT_LOADING_PENDING))) + { + DEBUG_PRINT_LOW(" free buffer while Component in Loading pending\n"); + } + else if((m_sInPortDef.bEnabled == OMX_FALSE && port == PORT_INDEX_IN)|| + (m_sOutPortDef.bEnabled == OMX_FALSE && port == PORT_INDEX_OUT)) + { + DEBUG_PRINT_LOW("Free Buffer while port %d disabled\n", port); + } + else if(m_state == OMX_StateExecuting || m_state == OMX_StatePause) + { + DEBUG_PRINT_ERROR("ERROR: Invalid state to free buffer,ports need to be disabled\n"); + post_event(OMX_EventError, + OMX_ErrorPortUnpopulated, + OMX_COMPONENT_GENERATE_EVENT); + + return eRet; + } + else + { + DEBUG_PRINT_ERROR("ERROR: Invalid state to free buffer,port lost Buffers\n"); + post_event(OMX_EventError, + OMX_ErrorPortUnpopulated, + OMX_COMPONENT_GENERATE_EVENT); + } + + if(port == PORT_INDEX_IN) + { + // check if the buffer is valid + nPortIndex = buffer - ((!mUseProxyColorFormat)?m_inp_mem_ptr:meta_buffer_hdr); + + DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d, actual cnt %d \n", + nPortIndex, m_sInPortDef.nBufferCountActual); + if(nPortIndex < m_sInPortDef.nBufferCountActual) + { + // Clear the bit associated with it. + m_inp_bm_count = BITMASK_CLEAR_U32(m_inp_bm_count,nPortIndex); + free_input_buffer (buffer); + m_sInPortDef.bPopulated = OMX_FALSE; + + /*Free the Buffer Header*/ + if(release_input_done() +#ifdef _ANDROID_ICS_ + && !meta_mode_enable +#endif + ) + { + input_use_buffer = false; + if(m_inp_mem_ptr) + { + DEBUG_PRINT_LOW("Freeing m_inp_mem_ptr\n"); + free (m_inp_mem_ptr); + m_inp_mem_ptr = NULL; + } + if(m_pInput_pmem) + { + DEBUG_PRINT_LOW("Freeing m_pInput_pmem\n"); + free(m_pInput_pmem); + m_pInput_pmem = NULL; + } +#ifdef USE_ION + if(m_pInput_ion) + { + DEBUG_PRINT_LOW("Freeing m_pInput_ion\n"); + free(m_pInput_ion); + m_pInput_ion = NULL; + } +#endif + } + } + else + { + DEBUG_PRINT_ERROR("ERROR: free_buffer ,Port Index Invalid\n"); + eRet = OMX_ErrorBadPortIndex; + } + + if(BITMASK_PRESENT_U32(m_flags,OMX_COMPONENT_INPUT_DISABLE_PENDING) + && release_input_done()) + { + DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n"); + m_flags = BITMASK_CLEAR_U32(m_flags,OMX_COMPONENT_INPUT_DISABLE_PENDING); + post_event(OMX_CommandPortDisable, + PORT_INDEX_IN, + OMX_COMPONENT_GENERATE_EVENT); + } + } + else if(port == PORT_INDEX_OUT) + { + // check if the buffer is valid + nPortIndex = buffer - (OMX_BUFFERHEADERTYPE*)m_out_mem_ptr; + + DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d, actual cnt %d \n", + nPortIndex, m_sOutPortDef.nBufferCountActual); + if(nPortIndex < m_sOutPortDef.nBufferCountActual) + { + // Clear the bit associated with it. + m_out_bm_count = BITMASK_CLEAR_U32(m_out_bm_count,nPortIndex); + m_sOutPortDef.bPopulated = OMX_FALSE; + free_output_buffer (buffer); + + if(release_output_done()) + { + output_use_buffer = false; + if(m_out_mem_ptr) + { + DEBUG_PRINT_LOW("Freeing m_out_mem_ptr\n"); + free (m_out_mem_ptr); + m_out_mem_ptr = NULL; + } + if(m_pOutput_pmem) + { + DEBUG_PRINT_LOW("Freeing m_pOutput_pmem\n"); + free(m_pOutput_pmem); + m_pOutput_pmem = NULL; + } +#ifdef USE_ION + if(m_pOutput_ion) + { + DEBUG_PRINT_LOW("Freeing m_pOutput_ion\n"); + free(m_pOutput_ion); + m_pOutput_ion = NULL; + } +#endif + } + } + else + { + DEBUG_PRINT_ERROR("ERROR: free_buffer , Port Index Invalid\n"); + eRet = OMX_ErrorBadPortIndex; + } + if(BITMASK_PRESENT_U32(m_flags,OMX_COMPONENT_OUTPUT_DISABLE_PENDING) + && release_output_done() ) + { + DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it\n"); + + DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n"); + m_flags = BITMASK_CLEAR_U32(m_flags,OMX_COMPONENT_OUTPUT_DISABLE_PENDING); + post_event(OMX_CommandPortDisable, + PORT_INDEX_OUT, + OMX_COMPONENT_GENERATE_EVENT); + + } + } + else + { + eRet = OMX_ErrorBadPortIndex; + } + if((eRet == OMX_ErrorNone) && + (BITMASK_PRESENT_U32(m_flags ,OMX_COMPONENT_LOADING_PENDING))) + { + if(release_done()) + { + if(dev_stop() != 0) + { + DEBUG_PRINT_ERROR("ERROR: dev_stop() FAILED\n"); + eRet = OMX_ErrorHardware; + } + // Send the callback now + m_flags = BITMASK_CLEAR_U32(m_flags,OMX_COMPONENT_LOADING_PENDING); + post_event(OMX_CommandStateSet, OMX_StateLoaded, + OMX_COMPONENT_GENERATE_EVENT); + } + } + + return eRet; +} + + +/* ====================================================================== +FUNCTION + omx_video::EmptyThisBuffer + +DESCRIPTION + This routine is used to push the encoded video frames to + the video decoder. + +PARAMETERS + None. + +RETURN VALUE + OMX Error None if everything went successful. + +========================================================================== */ +OMX_ERRORTYPE omx_video::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_BUFFERHEADERTYPE* buffer) +{ + OMX_ERRORTYPE ret1 = OMX_ErrorNone; + unsigned int nBufferIndex ; + + DEBUG_PRINT_LOW("\n ETB: buffer = %p, buffer->pBuffer[%p]\n", buffer, buffer->pBuffer); + if(m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("ERROR: Empty this buffer in Invalid State\n"); + return OMX_ErrorInvalidState; + } + + if (buffer == NULL || (buffer->nSize != sizeof(OMX_BUFFERHEADERTYPE))) + { + DEBUG_PRINT_ERROR("\nERROR: omx_video::etb--> buffer is null or buffer size is invalid"); + return OMX_ErrorBadParameter; + } + + if(buffer->nVersion.nVersion != OMX_SPEC_VERSION) + { + DEBUG_PRINT_ERROR("\nERROR: omx_video::etb--> OMX Version Invalid"); + return OMX_ErrorVersionMismatch; + } + + if (buffer->nInputPortIndex != (OMX_U32)PORT_INDEX_IN) + { + DEBUG_PRINT_ERROR("\nERROR: Bad port index to call empty_this_buffer"); + return OMX_ErrorBadPortIndex; + } + if(!m_sInPortDef.bEnabled) + { + DEBUG_PRINT_ERROR("\nERROR: Cannot call empty_this_buffer while I/P port is disabled"); + return OMX_ErrorIncorrectStateOperation; + } + + nBufferIndex = buffer - ((!mUseProxyColorFormat)?m_inp_mem_ptr:meta_buffer_hdr); + + if(nBufferIndex > m_sInPortDef.nBufferCountActual ) + { + DEBUG_PRINT_ERROR("ERROR: ETB: Invalid buffer index[%d]\n", nBufferIndex); + return OMX_ErrorBadParameter; + } + + m_etb_count++; + DEBUG_PRINT_LOW("\n DBG: i/p nTimestamp = %u", (unsigned)buffer->nTimeStamp); + post_event ((unsigned)hComp,(unsigned)buffer,m_input_msg_id); + return OMX_ErrorNone; +} +/* ====================================================================== +FUNCTION + omx_video::empty_this_buffer_proxy + +DESCRIPTION + This routine is used to push the encoded video frames to + the video decoder. + +PARAMETERS + None. + +RETURN VALUE + OMX Error None if everything went successful. + +========================================================================== */ +OMX_ERRORTYPE omx_video::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_BUFFERHEADERTYPE* buffer) +{ + OMX_U8 *pmem_data_buf = NULL; + int push_cnt = 0; + unsigned nBufIndex = 0,nBufIndex_meta = 0; + OMX_ERRORTYPE ret = OMX_ErrorNone; + + DEBUG_PRINT_LOW("\n ETBProxy: buffer[%p]\n", buffer); + + if(buffer == NULL) + { + DEBUG_PRINT_ERROR("\nERROR: ETBProxy: Invalid buffer[%p]\n", buffer); + return OMX_ErrorBadParameter; + } + + nBufIndex = buffer - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr); + nBufIndex_meta = buffer - meta_buffer_hdr; + if(nBufIndex >= m_sInPortDef.nBufferCountActual && + nBufIndex_meta >= m_sInPortDef.nBufferCountActual) + { + DEBUG_PRINT_ERROR("\nERROR: ETBProxy: Invalid bufindex = %u\n", nBufIndex); + return OMX_ErrorBadParameter; + } + + pending_input_buffers++; + if(input_flush_progress == true) + { + post_event ((unsigned int)buffer,0, + OMX_COMPONENT_GENERATE_EBD); + DEBUG_PRINT_ERROR("\nERROR: ETBProxy: Input flush in progress"); + return OMX_ErrorNone; + } +#ifdef _ANDROID_ICS_ + if(meta_mode_enable && !mUseProxyColorFormat) + { + encoder_media_buffer_type *media_buffer; + bool met_error = false; + media_buffer = (encoder_media_buffer_type *)meta_buffer_hdr[nBufIndex].pBuffer; + if(media_buffer) + { + if (media_buffer->buffer_type != kMetadataBufferTypeCameraSource && + media_buffer->buffer_type != kMetadataBufferTypeGrallocSource) { + met_error = true; + } else { + if(media_buffer->buffer_type == kMetadataBufferTypeCameraSource) + { + if(media_buffer->meta_handle == NULL) { + met_error = true; + } + else if((media_buffer->meta_handle->numFds != 1 && + media_buffer->meta_handle->numInts != 2)) + { + met_error = true; + } + } + } + } else { + met_error = true; + } + if(met_error) + { + DEBUG_PRINT_ERROR("\nERROR: Unkown source/metahandle in ETB call"); + post_event ((unsigned int)buffer,0,OMX_COMPONENT_GENERATE_EBD); + return OMX_ErrorBadParameter; + } + + struct pmem Input_pmem_info; + if(media_buffer->buffer_type == kMetadataBufferTypeCameraSource) + { + Input_pmem_info.buffer = media_buffer; + Input_pmem_info.fd = media_buffer->meta_handle->data[0]; + Input_pmem_info.offset = media_buffer->meta_handle->data[1]; + Input_pmem_info.size = media_buffer->meta_handle->data[2]; + DEBUG_PRINT_LOW("ETB fd = %d, offset = %d, size = %d",Input_pmem_info.fd, + Input_pmem_info.offset, + Input_pmem_info.size); + + } else { + private_handle_t *handle = (private_handle_t *)media_buffer->meta_handle; + if(handle->format != HAL_PIXEL_FORMAT_NV12_ENCODEABLE) { + DEBUG_PRINT_ERROR("\n Incorrect pixel format"); + post_event ((unsigned int)buffer,0,OMX_COMPONENT_GENERATE_EBD); + return OMX_ErrorBadParameter; + } + Input_pmem_info.buffer = media_buffer; + Input_pmem_info.fd = handle->fd; + Input_pmem_info.offset = 0; + Input_pmem_info.size = handle->size; + } + if(dev_use_buf(&Input_pmem_info,PORT_INDEX_IN,0) != true) { + DEBUG_PRINT_ERROR("\nERROR: in dev_use_buf"); + post_event ((unsigned int)buffer,0,OMX_COMPONENT_GENERATE_EBD); + return OMX_ErrorBadParameter; + } + } + else if(input_use_buffer && !m_use_input_pmem) +#else + if(input_use_buffer && !m_use_input_pmem) +#endif + { + DEBUG_PRINT_LOW("\n Heap UseBuffer case, so memcpy the data"); + pmem_data_buf = (OMX_U8 *)m_pInput_pmem[nBufIndex].buffer; + + memcpy (pmem_data_buf, (buffer->pBuffer + buffer->nOffset), + buffer->nFilledLen); + DEBUG_PRINT_LOW("memcpy() done in ETBProxy for i/p Heap UseBuf"); +#ifndef MAX_RES_720P + } else if (m_sInPortDef.format.video.eColorFormat == + OMX_COLOR_FormatYUV420SemiPlanar) { + //For the case where YUV420SP buffers are qeueued to component + //by sources other than camera (Apps via MediaCodec), alignment + //of chroma-plane to 2K is necessary. + //For RGB buffers, color-conversion takes care of alignment + OMX_U32 width = m_sInPortDef.format.video.nFrameWidth; + OMX_U32 height = m_sInPortDef.format.video.nFrameHeight; + OMX_U32 chromaOffset = width * height; + if (IS_NOT_ALIGNED(chromaOffset, SZ_2K)) { + OMX_U32 chromaSize = (width * height)/2; + chromaOffset = ALIGN(chromaOffset,SZ_2K); + if (buffer->nAllocLen >= chromaOffset + chromaSize) { + OMX_U8* buf = buffer->pBuffer; + memmove(buf + chromaOffset, buf + (width*height), chromaSize); + } else { + DEBUG_PRINT_ERROR("Failed to align Chroma. from %u to %u : \ + Insufficient bufferLen=%u v/s Required=%u", + (width*height), chromaOffset, buffer->nAllocLen, + chromaOffset+chromaSize); + } + } +#endif + } +#ifdef _COPPER_ + if(dev_empty_buf(buffer, pmem_data_buf,nBufIndex,m_pInput_pmem[nBufIndex].fd) != true) +#else + if(dev_empty_buf(buffer, pmem_data_buf,0,0) != true) +#endif + { + DEBUG_PRINT_ERROR("\nERROR: ETBProxy: dev_empty_buf failed"); +#ifdef _ANDROID_ICS_ + omx_release_meta_buffer(buffer); +#endif + post_event ((unsigned int)buffer,0,OMX_COMPONENT_GENERATE_EBD); + /*Generate an async error and move to invalid state*/ + pending_input_buffers--; + return OMX_ErrorBadParameter; + } + + return ret; +} + +/* ====================================================================== +FUNCTION + omx_video::FillThisBuffer + +DESCRIPTION + IL client uses this method to release the frame buffer + after displaying them. + +PARAMETERS + None. + +RETURN VALUE + true/false + +========================================================================== */ +OMX_ERRORTYPE omx_video::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_BUFFERHEADERTYPE* buffer) +{ + DEBUG_PRINT_LOW("\n FTB: buffer->pBuffer[%p]\n", buffer->pBuffer); + if(m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("ERROR: FTB in Invalid State\n"); + return OMX_ErrorInvalidState; + } + + if (buffer == NULL ||(buffer->nSize != sizeof(OMX_BUFFERHEADERTYPE))) + { + DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->Invalid buffer or size\n"); + return OMX_ErrorBadParameter; + } + + if(buffer->nVersion.nVersion != OMX_SPEC_VERSION) + { + DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->OMX Version Invalid\n"); + return OMX_ErrorVersionMismatch; + } + + if (buffer->nOutputPortIndex != (OMX_U32)PORT_INDEX_OUT) + { + DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->Bad port index\n"); + return OMX_ErrorBadPortIndex; + } + + if(!m_sOutPortDef.bEnabled) + { + DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->port is disabled\n"); + return OMX_ErrorIncorrectStateOperation; + } + + post_event((unsigned) hComp, (unsigned)buffer,OMX_COMPONENT_GENERATE_FTB); + return OMX_ErrorNone; +} + +/* ====================================================================== +FUNCTION + omx_video::fill_this_buffer_proxy + +DESCRIPTION + IL client uses this method to release the frame buffer + after displaying them. + +PARAMETERS + None. + +RETURN VALUE + true/false + +========================================================================== */ +OMX_ERRORTYPE omx_video::fill_this_buffer_proxy( + OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd) +{ + OMX_U8 *pmem_data_buf = NULL; + OMX_ERRORTYPE nRet = OMX_ErrorNone; + + DEBUG_PRINT_LOW("\n FTBProxy: bufferAdd->pBuffer[%p]\n", bufferAdd->pBuffer); + + if(bufferAdd == NULL || ((bufferAdd - m_out_mem_ptr) >= m_sOutPortDef.nBufferCountActual) ) + { + DEBUG_PRINT_ERROR("\nERROR: FTBProxy: Invalid i/p params\n"); + return OMX_ErrorBadParameter; + } + + pending_output_buffers++; + /*Return back the output buffer to client*/ + if( m_sOutPortDef.bEnabled != OMX_TRUE || output_flush_progress == true) + { + DEBUG_PRINT_LOW("\n o/p port is Disabled or Flush in Progress"); + post_event ((unsigned int)bufferAdd,0, + OMX_COMPONENT_GENERATE_FBD); + return OMX_ErrorNone; + } + + if(output_use_buffer && !m_use_output_pmem) + { + DEBUG_PRINT_LOW("\n Heap UseBuffer case"); + pmem_data_buf = (OMX_U8 *)m_pOutput_pmem[bufferAdd - m_out_mem_ptr].buffer; + } + + if(dev_fill_buf(bufferAdd, pmem_data_buf,(bufferAdd - m_out_mem_ptr),m_pOutput_pmem[bufferAdd - m_out_mem_ptr].fd) != true) + { + DEBUG_PRINT_ERROR("\nERROR: dev_fill_buf() Failed"); + post_event ((unsigned int)bufferAdd,0,OMX_COMPONENT_GENERATE_FBD); + pending_output_buffers--; + return OMX_ErrorBadParameter; + } + + return OMX_ErrorNone; +} + +/* ====================================================================== +FUNCTION + omx_video::SetCallbacks + +DESCRIPTION + Set the callbacks. + +PARAMETERS + None. + +RETURN VALUE + OMX Error None if everything successful. + +========================================================================== */ +OMX_ERRORTYPE omx_video::set_callbacks(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_CALLBACKTYPE* callbacks, + OMX_IN OMX_PTR appData) +{ + + m_pCallbacks = *callbacks; + DEBUG_PRINT_LOW("\n Callbacks Set %p %p %p",m_pCallbacks.EmptyBufferDone,\ + m_pCallbacks.EventHandler,m_pCallbacks.FillBufferDone); + m_app_data = appData; + return OMX_ErrorNotImplemented; +} + + +/* ====================================================================== +FUNCTION + omx_venc::UseEGLImage + +DESCRIPTION + OMX Use EGL Image method implementation . + +PARAMETERS + . + +RETURN VALUE + Not Implemented error. + +========================================================================== */ +OMX_ERRORTYPE omx_video::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp, + OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, + OMX_IN OMX_U32 port, + OMX_IN OMX_PTR appData, + OMX_IN void* eglImage) +{ + DEBUG_PRINT_ERROR("ERROR: use_EGL_image: Not Implemented \n"); + return OMX_ErrorNotImplemented; +} + +/* ====================================================================== +FUNCTION + omx_venc::ComponentRoleEnum + +DESCRIPTION + OMX Component Role Enum method implementation. + +PARAMETERS + . + +RETURN VALUE + OMX Error None if everything is successful. +========================================================================== */ +OMX_ERRORTYPE omx_video::component_role_enum(OMX_IN OMX_HANDLETYPE hComp, + OMX_OUT OMX_U8* role, + OMX_IN OMX_U32 index) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + if(!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) + { + if((0 == index) && role) + { + strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE); + DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); + } + else + { + eRet = OMX_ErrorNoMore; + } + } + else if(!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) + { + if((0 == index) && role) + { + strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE); + DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); + } + else + { + DEBUG_PRINT_ERROR("\nERROR: No more roles \n"); + eRet = OMX_ErrorNoMore; + } + } + else if(!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) + { + if((0 == index) && role) + { + strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE); + DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); + } + else + { + DEBUG_PRINT_ERROR("\nERROR: No more roles \n"); + eRet = OMX_ErrorNoMore; + } + } + else if(!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) + { + if((0 == index) && role) + { + strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE); + DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); + } + else + { + DEBUG_PRINT_ERROR("\nERROR: No more roles \n"); + eRet = OMX_ErrorNoMore; + } + } + if(!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) + { + if((0 == index) && role) + { + strlcpy((char *)role, "video_encoder.mpeg4",OMX_MAX_STRINGNAME_SIZE); + DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); + } + else + { + eRet = OMX_ErrorNoMore; + } + } + else if(!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.h263",OMX_MAX_STRINGNAME_SIZE)) + { + if((0 == index) && role) + { + strlcpy((char *)role, "video_encoder.h263",OMX_MAX_STRINGNAME_SIZE); + DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); + } + else + { + DEBUG_PRINT_ERROR("\nERROR: No more roles \n"); + eRet = OMX_ErrorNoMore; + } + } + else if(!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.avc",OMX_MAX_STRINGNAME_SIZE)) + { + if((0 == index) && role) + { + strlcpy((char *)role, "video_encoder.avc",OMX_MAX_STRINGNAME_SIZE); + DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); + } + else + { + DEBUG_PRINT_ERROR("\nERROR: No more roles \n"); + eRet = OMX_ErrorNoMore; + } + } + else + { + DEBUG_PRINT_ERROR("\nERROR: Querying Role on Unknown Component\n"); + eRet = OMX_ErrorInvalidComponentName; + } + return eRet; +} + + + + +/* ====================================================================== +FUNCTION + omx_venc::AllocateDone + +DESCRIPTION + Checks if entire buffer pool is allocated by IL Client or not. + Need this to move to IDLE state. + +PARAMETERS + None. + +RETURN VALUE + true/false. + +========================================================================== */ +bool omx_video::allocate_done(void) +{ + bool bRet = false; + bool bRet_In = false; + bool bRet_Out = false; + + bRet_In = allocate_input_done(); + bRet_Out = allocate_output_done(); + + if(bRet_In && bRet_Out) + { + bRet = true; + } + + return bRet; +} +/* ====================================================================== +FUNCTION + omx_venc::AllocateInputDone + +DESCRIPTION + Checks if I/P buffer pool is allocated by IL Client or not. + +PARAMETERS + None. + +RETURN VALUE + true/false. + +========================================================================== */ +bool omx_video::allocate_input_done(void) +{ + bool bRet = false; + unsigned i=0; + + if(m_inp_mem_ptr == NULL) + { + return bRet; + } + if(m_inp_mem_ptr ) + { + for(;ipBuffer[%p], flags=0x%x size = %d", + buffer->pBuffer, buffer->nFlags,buffer->nFilledLen); + if(buffer == NULL || ((buffer - m_out_mem_ptr) > m_sOutPortDef.nBufferCountActual)) + { + DEBUG_PRINT_ERROR("\n ERR: buffer = %p, idx = %d, act_count = %d", + buffer, idx, m_sOutPortDef.nBufferCountActual); + return OMX_ErrorBadParameter; + } + + pending_output_buffers--; + if(!secure_session) + { + extra_data_handle.create_extra_data(buffer); + } + + if (!secure_session && (buffer->nFlags & OMX_BUFFERFLAG_EXTRADATA)) + { + extra_data_handle.parse_extra_data(buffer, extradata_offset[idx]); + } + + /* For use buffer we need to copy the data */ + if(m_pCallbacks.FillBufferDone) + { + if(buffer->nFilledLen > 0) + { + m_fbd_count++; + +#ifdef OUTPUT_BUFFER_LOG + if(outputBufferFile1) + { + fwrite((const char *)buffer->pBuffer, buffer->nFilledLen, 1, outputBufferFile1); + } +#endif + } + m_pCallbacks.FillBufferDone (hComp,m_app_data,buffer); + } + else + { + DEBUG_PRINT_ERROR("\n ERR: m_pCallbacks.FillBufferDone is NULL"); + return OMX_ErrorBadParameter; + } + return OMX_ErrorNone; +} + +OMX_ERRORTYPE omx_video::empty_buffer_done(OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE* buffer) +{ + int buffer_index = -1; + int buffer_index_meta = -1; + + buffer_index = (buffer - m_inp_mem_ptr); + buffer_index_meta = (buffer - meta_buffer_hdr); + DEBUG_PRINT_LOW("\n empty_buffer_done: buffer[%p]", buffer); + if(buffer == NULL || + ((buffer_index > m_sInPortDef.nBufferCountActual) && + (buffer_index_meta > m_sInPortDef.nBufferCountActual))) + { + DEBUG_PRINT_ERROR("\n ERROR in empty_buffer_done due to index buffer"); + return OMX_ErrorBadParameter; + } + + pending_input_buffers--; + + if(mUseProxyColorFormat && (buffer_index < m_sInPortDef.nBufferCountActual)) { + if(!pdest_frame && !input_flush_progress) { + pdest_frame = buffer; + DEBUG_PRINT_LOW("\n empty_buffer_done pdest_frame address is %p",pdest_frame); + return push_input_buffer(hComp); + + } else { + DEBUG_PRINT_LOW("\n empty_buffer_done insert address is %p",buffer); + if (!m_opq_pmem_q.insert_entry((unsigned int)buffer, 0, 0)) { + DEBUG_PRINT_ERROR("\n empty_buffer_done: pmem queue is full"); + return OMX_ErrorBadParameter; + } + } + } else if(m_pCallbacks.EmptyBufferDone) { + m_pCallbacks.EmptyBufferDone(hComp ,m_app_data, buffer); + } + return OMX_ErrorNone; +} + +void omx_video::complete_pending_buffer_done_cbs() +{ + unsigned p1; + unsigned p2; + unsigned ident; + omx_cmd_queue tmp_q, pending_bd_q; + pthread_mutex_lock(&m_lock); + // pop all pending GENERATE FDB from ftb queue + while (m_ftb_q.m_size) + { + m_ftb_q.pop_entry(&p1,&p2,&ident); + if(ident == OMX_COMPONENT_GENERATE_FBD) + { + pending_bd_q.insert_entry(p1,p2,ident); + } + else + { + tmp_q.insert_entry(p1,p2,ident); + } + } + //return all non GENERATE FDB to ftb queue + while(tmp_q.m_size) + { + tmp_q.pop_entry(&p1,&p2,&ident); + m_ftb_q.insert_entry(p1,p2,ident); + } + // pop all pending GENERATE EDB from etb queue + while (m_etb_q.m_size) + { + m_etb_q.pop_entry(&p1,&p2,&ident); + if(ident == OMX_COMPONENT_GENERATE_EBD) + { + pending_bd_q.insert_entry(p1,p2,ident); + } + else + { + tmp_q.insert_entry(p1,p2,ident); + } + } + //return all non GENERATE FDB to etb queue + while(tmp_q.m_size) + { + tmp_q.pop_entry(&p1,&p2,&ident); + m_etb_q.insert_entry(p1,p2,ident); + } + pthread_mutex_unlock(&m_lock); + // process all pending buffer dones + while(pending_bd_q.m_size) + { + pending_bd_q.pop_entry(&p1,&p2,&ident); + switch(ident) + { + case OMX_COMPONENT_GENERATE_EBD: + if(empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) + { + DEBUG_PRINT_ERROR("\nERROR: empty_buffer_done() failed!\n"); + omx_report_error (); + } + break; + + case OMX_COMPONENT_GENERATE_FBD: + if(fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) + { + DEBUG_PRINT_ERROR("\nERROR: fill_buffer_done() failed!\n"); + omx_report_error (); + } + break; + } + } +} + +#ifdef MAX_RES_720P +OMX_ERRORTYPE omx_video::get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + if(!profileLevelType) + return OMX_ErrorBadParameter; + + if(profileLevelType->nPortIndex == 1) { + if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingAVC) + { + if (profileLevelType->nProfileIndex == 0) + { + profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline; + profileLevelType->eLevel = OMX_VIDEO_AVCLevel31; + } + else if (profileLevelType->nProfileIndex == 1) + { + profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain; + profileLevelType->eLevel = OMX_VIDEO_AVCLevel31; + } + else if(profileLevelType->nProfileIndex == 2) + { + profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh; + profileLevelType->eLevel = OMX_VIDEO_AVCLevel31; + } + else + { + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", + profileLevelType->nProfileIndex); + eRet = OMX_ErrorNoMore; + } + } + else if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingH263) + { + if (profileLevelType->nProfileIndex == 0) + { + profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline; + profileLevelType->eLevel = OMX_VIDEO_H263Level70; + } + else + { + DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex); + eRet = OMX_ErrorNoMore; + } + } + else if(m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingMPEG4) + { + if (profileLevelType->nProfileIndex == 0) + { + profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple; + profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5; + } + else if(profileLevelType->nProfileIndex == 1) + { + profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple; + profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5; + } + else + { + DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex); + eRet = OMX_ErrorNoMore; + } + } + } + else + { + DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %d\n", profileLevelType->nPortIndex); + eRet = OMX_ErrorBadPortIndex; + } + DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported for Input port returned Profile:%d, Level:%d\n", + profileLevelType->eProfile,profileLevelType->eLevel); + return eRet; +} +#endif + +#ifdef MAX_RES_1080P +OMX_ERRORTYPE omx_video::get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + if(!profileLevelType) + return OMX_ErrorBadParameter; + + if(profileLevelType->nPortIndex == 1) { + if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingAVC) + { + if (profileLevelType->nProfileIndex == 0) + { + profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline; + profileLevelType->eLevel = OMX_VIDEO_AVCLevel4; + + } + else if (profileLevelType->nProfileIndex == 1) + { + profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain; + profileLevelType->eLevel = OMX_VIDEO_AVCLevel4; + } + else if(profileLevelType->nProfileIndex == 2) + { + profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh; + profileLevelType->eLevel = OMX_VIDEO_AVCLevel4; + } + else + { + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", + profileLevelType->nProfileIndex); + eRet = OMX_ErrorNoMore; + } + } + else if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingH263) + { + if (profileLevelType->nProfileIndex == 0) + { + profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline; + profileLevelType->eLevel = OMX_VIDEO_H263Level70; + } + else + { + DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex); + eRet = OMX_ErrorNoMore; + } + } + else if(m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingMPEG4) + { + if (profileLevelType->nProfileIndex == 0) + { + profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple; + profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5; + } + else if(profileLevelType->nProfileIndex == 1) + { + profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple; + profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5; + } + else + { + DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex); + eRet = OMX_ErrorNoMore; + } + } + else + { + DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported ret NoMore\n"); + eRet = OMX_ErrorNoMore; + } + } + else + { + DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %d\n", profileLevelType->nPortIndex); + eRet = OMX_ErrorBadPortIndex; + } + DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported for Input port returned Profile:%d, Level:%d\n", + profileLevelType->eProfile,profileLevelType->eLevel); + return eRet; +} +#endif + +#ifdef USE_ION +int omx_video::alloc_map_ion_memory(int size,struct ion_allocation_data *alloc_data, + struct ion_fd_data *fd_data,int flag) +{ + struct venc_ion buf_ion_info; + int ion_device_fd =-1,rc=0; + if (size <=0 || !alloc_data || !fd_data) { + DEBUG_PRINT_ERROR("\nInvalid input to alloc_map_ion_memory"); + return -EINVAL; + } + ion_device_fd = m_venc_ion_devicefd; + if(ion_device_fd <= 0) { + DEBUG_PRINT_ERROR("\nERROR: Invalid ION Device fd = %d", ion_device_fd); + return ion_device_fd; + } + alloc_data->len = size; + alloc_data->align = 4096; + alloc_data->flags = 0; + if(!secure_session && (flag & ION_FLAG_CACHED)) + { + alloc_data->flags = ION_FLAG_CACHED; + } + if (dev_get_uncache_flag() && + (alloc_data->flags & ION_FLAG_CACHED)) + { + alloc_data->flags &= ~ION_FLAG_CACHED; + DEBUG_PRINT_HIGH("uncache buffers requested, flags = 0x%x", + alloc_data->flags); + } + + if (secure_session) + alloc_data->heap_id_mask = (ION_HEAP(MEM_HEAP_ID) | ION_SECURE); + else +#ifdef MAX_RES_720P + alloc_data->heap_id_mask = ION_HEAP(MEM_HEAP_ID); +#else + alloc_data->heap_id_mask = (ION_HEAP(MEM_HEAP_ID) | + ION_HEAP(ION_IOMMU_HEAP_ID)); +#endif + pthread_mutex_lock(&m_venc_ionlock); + rc = ioctl(ion_device_fd,ION_IOC_ALLOC,alloc_data); + if(rc || !alloc_data->handle) { + DEBUG_PRINT_ERROR("\n ION ALLOC failed, fd = %d, rc = %d, handle = 0x%p, " + "errno = %d", ion_device_fd, rc, alloc_data->handle, errno); + alloc_data->handle =NULL; + goto error_case; + } + fd_data->handle = alloc_data->handle; + rc = ioctl(ion_device_fd,ION_IOC_MAP,fd_data); + if(rc) { + DEBUG_PRINT_ERROR("\n ION MAP failed, fd = %d, handle = 0x%p, " + "errno = %d", ion_device_fd, fd_data->handle, errno); + fd_data->fd =-1; + goto error_case; + } + DEBUG_PRINT_HIGH("ion_alloc: device_fd = %d, len = %d, align = %d, " + "flags = 0x%x, heap_id_mask = 0x%x, handle = %p, fd = %d", ion_device_fd, + alloc_data->len, alloc_data->align, alloc_data->flags, + alloc_data->heap_id_mask, fd_data->handle, fd_data->fd); + pthread_mutex_unlock(&m_venc_ionlock); + return ion_device_fd; + +error_case: + if (alloc_data->handle) { + if(ioctl(ion_device_fd, ION_IOC_FREE, alloc_data->handle)) { + DEBUG_PRINT_ERROR("ION: free failed, fd = %d, handle = 0x%p, " + "errno = %d", ion_device_fd, alloc_data->handle, errno); + } + } + pthread_mutex_unlock(&m_venc_ionlock); + return -1; +} + +void omx_video::free_ion_memory(struct venc_ion *buf_ion_info) +{ + if (!buf_ion_info) { + DEBUG_PRINT_ERROR("\n Invalid input to free_ion_memory"); + return; + } + pthread_mutex_lock(&m_venc_ionlock); + if (close(buf_ion_info->fd_ion_data.fd)) { + DEBUG_PRINT_ERROR("\n ION: close(%d) failed, errno = %d", + buf_ion_info->fd_ion_data.fd, errno); + } + if (ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE, + &buf_ion_info->ion_alloc_data.handle)) { + DEBUG_PRINT_ERROR("\n ION: free failed, dev_fd = %d, handle = 0x%p", + buf_ion_info->ion_device_fd, buf_ion_info->ion_alloc_data.handle); + return; + } + buf_ion_info->ion_alloc_data.handle = NULL; + buf_ion_info->ion_device_fd = -1; + buf_ion_info->fd_ion_data.fd = -1; + pthread_mutex_unlock(&m_venc_ionlock); +} +#endif +#ifdef _ANDROID_ICS_ +void omx_video::omx_release_meta_buffer(OMX_BUFFERHEADERTYPE *buffer) +{ + if(buffer && meta_mode_enable) + { + encoder_media_buffer_type *media_ptr; + struct pmem Input_pmem; + unsigned int index_pmem = 0; + bool meta_error = false; + + index_pmem = (buffer - m_inp_mem_ptr); + if(mUseProxyColorFormat && + (index_pmem < m_sInPortDef.nBufferCountActual)) { + if(!dev_free_buf((&m_pInput_pmem[index_pmem]),PORT_INDEX_IN)){ + DEBUG_PRINT_ERROR("\n omx_release_meta_buffer dev free failed"); + } + } else { + media_ptr = (encoder_media_buffer_type *) buffer->pBuffer; + if(media_ptr && media_ptr->meta_handle) + { + if(media_ptr->buffer_type == kMetadataBufferTypeCameraSource && + media_ptr->meta_handle->numFds == 1 && + media_ptr->meta_handle->numInts == 2) { + Input_pmem.fd = media_ptr->meta_handle->data[0]; + Input_pmem.buffer = media_ptr; + Input_pmem.size = media_ptr->meta_handle->data[2]; + Input_pmem.offset = media_ptr->meta_handle->data[1]; + DEBUG_PRINT_LOW("EBD fd = %d, offset = %d, size = %d",Input_pmem.fd, + Input_pmem.offset, + Input_pmem.size); + } else if(media_ptr->buffer_type == kMetadataBufferTypeGrallocSource) { + private_handle_t *handle = (private_handle_t *)media_ptr->meta_handle; + Input_pmem.buffer = media_ptr; + Input_pmem.fd = handle->fd; + Input_pmem.offset = 0; + Input_pmem.size = handle->size; + } else { + meta_error = true; + DEBUG_PRINT_ERROR(" Meta Error set in EBD"); + } + if(!meta_error) + meta_error = !dev_free_buf(&Input_pmem,PORT_INDEX_IN); + if(meta_error) + { + DEBUG_PRINT_ERROR(" Warning dev_free_buf failed flush value is %d", + input_flush_progress); + } + } + } + } +} +#endif +omx_video::omx_c2d_conv::omx_c2d_conv() +{ + c2dcc = NULL; + mLibHandle = NULL; + mConvertOpen = NULL; + mConvertClose = NULL; + src_format = NV12_2K; +} + +bool omx_video::omx_c2d_conv::init() { + bool status = true; + if(mLibHandle || mConvertOpen || mConvertClose) { + DEBUG_PRINT_ERROR("\n omx_c2d_conv::init called twice"); + status = false; + } + if(status) { + mLibHandle = dlopen("libc2dcolorconvert.so", RTLD_LAZY); + if(mLibHandle){ + mConvertOpen = (createC2DColorConverter_t *) + dlsym(mLibHandle,"createC2DColorConverter"); + mConvertClose = (destroyC2DColorConverter_t *) + dlsym(mLibHandle,"destroyC2DColorConverter"); + if(!mConvertOpen || !mConvertClose) + status = false; + } else + status = false; + } + if(!status && mLibHandle){ + dlclose(mLibHandle); + mLibHandle = NULL; + mConvertOpen = NULL; + mConvertClose = NULL; + } + return status; +} + +bool omx_video::omx_c2d_conv::convert(int src_fd, void *src_viraddr, + int dest_fd,void *dest_viraddr) +{ + int result; + if(!src_viraddr || !dest_viraddr || !c2dcc){ + DEBUG_PRINT_ERROR("\n Invalid arguments omx_c2d_conv::convert"); + return false; + } + result = c2dcc->convertC2D(src_fd,src_viraddr, + dest_fd,dest_viraddr); + DEBUG_PRINT_LOW("\n Color convert status %d",result); + return ((result < 0)?false:true); +} + +bool omx_video::omx_c2d_conv::open(unsigned int height,unsigned int width, + ColorConvertFormat src, ColorConvertFormat dest, unsigned int stride) +{ + bool status = false; + if(!c2dcc) { + c2dcc = mConvertOpen(width, height, width, height, + src,dest,0,stride); + if(c2dcc) { + src_format = src; + status = true; + } else + DEBUG_PRINT_ERROR("\n mConvertOpen failed"); + } + return status; +} +void omx_video::omx_c2d_conv::close() +{ + if(mLibHandle) { + if(mConvertClose && c2dcc) + mConvertClose(c2dcc); + c2dcc = NULL; + } +} +omx_video::omx_c2d_conv::~omx_c2d_conv() +{ + DEBUG_PRINT_ERROR("\n Destroy C2D instance"); + if(mLibHandle) { + if(mConvertClose && c2dcc) + mConvertClose(c2dcc); + dlclose(mLibHandle); + } + c2dcc = NULL; + mLibHandle = NULL; + mConvertOpen = NULL; + mConvertClose = NULL; +} +int omx_video::omx_c2d_conv::get_src_format() +{ + int format = -1; + if(src_format == NV12_2K) { + format = HAL_PIXEL_FORMAT_NV12_ENCODEABLE; + } else if(src_format == RGBA8888) { + format = HAL_PIXEL_FORMAT_RGBA_8888; + } + return format; +} +bool omx_video::omx_c2d_conv::get_buffer_size(int port,unsigned int &buf_size) +{ + int cret = 0; + bool ret = false; + C2DBuffReq bufferreq; + if(c2dcc){ + bufferreq.size = 0; + cret = c2dcc->getBuffReq(port,&bufferreq); + DEBUG_PRINT_LOW("\n Status of getbuffer is %d", cret); + ret = (cret)?false:true; + buf_size = bufferreq.size; + } + return ret; +} +OMX_ERRORTYPE omx_video::empty_this_buffer_opaque(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_BUFFERHEADERTYPE* buffer) +{ + unsigned nBufIndex = 0; + OMX_ERRORTYPE ret = OMX_ErrorNone; + encoder_media_buffer_type *media_buffer; + DEBUG_PRINT_LOW("\n ETBProxyOpaque: buffer[%p]\n", buffer); + + if(buffer == NULL) { + DEBUG_PRINT_ERROR("\nERROR: ETBProxyA: Invalid buffer[%p]\n",buffer); + return OMX_ErrorBadParameter; + } + nBufIndex = buffer - meta_buffer_hdr; + if(nBufIndex >= m_sInPortDef.nBufferCountActual) { + DEBUG_PRINT_ERROR("\nERROR: ETBProxyA: Invalid bufindex = %u\n", + nBufIndex); + return OMX_ErrorBadParameter; + } + media_buffer = (encoder_media_buffer_type *)buffer->pBuffer; + private_handle_t *handle = (private_handle_t *)media_buffer->meta_handle; + /*Enable following code once private handle color format is + updated correctly*/ + + if(buffer->nFilledLen > 0) { + if(c2d_opened && handle->format != c2d_conv.get_src_format()) { + c2d_conv.close(); + c2d_opened = false; + } + if(!c2d_opened) { + if(handle->format == HAL_PIXEL_FORMAT_RGBA_8888) { + DEBUG_PRINT_ERROR("\n open Color conv for RGBA888"); + if(!c2d_conv.open(m_sInPortDef.format.video.nFrameHeight, + m_sInPortDef.format.video.nFrameWidth,RGBA8888,NV12_2K,(unsigned int)handle->width)){ + m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer); + DEBUG_PRINT_ERROR("\n Color conv open failed"); + return OMX_ErrorBadParameter; + } + c2d_opened = true; + } else if(handle->format != HAL_PIXEL_FORMAT_NV12_ENCODEABLE) { + DEBUG_PRINT_ERROR("\n Incorrect color format"); + m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer); + return OMX_ErrorBadParameter; + } + } + } + + if(input_flush_progress == true) + { + m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer); + DEBUG_PRINT_ERROR("\nERROR: ETBProxyA: Input flush in progress"); + return OMX_ErrorNone; + } + + if(!psource_frame) { + psource_frame = buffer; + ret = push_input_buffer(hComp); + } else { + if (!m_opq_meta_q.insert_entry((unsigned)buffer,0,0)) { + DEBUG_PRINT_ERROR("\nERROR: ETBProxy: Queue is full"); + ret = OMX_ErrorBadParameter; + } + } + if(ret != OMX_ErrorNone) { + m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer); + DEBUG_PRINT_LOW("\nERROR: ETBOpaque failed:"); + } + return ret; +} +OMX_ERRORTYPE omx_video::queue_meta_buffer(OMX_HANDLETYPE hComp, + struct pmem &Input_pmem_info) { + + OMX_ERRORTYPE ret = OMX_ErrorNone; + unsigned address = 0,p2,id; + + DEBUG_PRINT_LOW("\n In queue Meta Buffer"); + if(!psource_frame || !pdest_frame) { + DEBUG_PRINT_ERROR("\n convert_queue_buffer invalid params"); + return OMX_ErrorBadParameter; + } + + if(psource_frame->nFilledLen > 0) { + if(dev_use_buf(&Input_pmem_info,PORT_INDEX_IN,0) != true) { + DEBUG_PRINT_ERROR("\nERROR: in dev_use_buf"); + post_event ((unsigned int)psource_frame,0,OMX_COMPONENT_GENERATE_EBD); + ret = OMX_ErrorBadParameter; + } + } + + if(ret == OMX_ErrorNone) + ret = empty_this_buffer_proxy(hComp,psource_frame); + + if(ret == OMX_ErrorNone) { + psource_frame = NULL; + if(!psource_frame && m_opq_meta_q.m_size) { + m_opq_meta_q.pop_entry(&address,&p2,&id); + psource_frame = (OMX_BUFFERHEADERTYPE* ) address; + } + } + return ret; +} + +OMX_ERRORTYPE omx_video::convert_queue_buffer(OMX_HANDLETYPE hComp, + struct pmem &Input_pmem_info,unsigned &index){ + + unsigned char *uva; + OMX_ERRORTYPE ret = OMX_ErrorNone; + unsigned address = 0,p2,id; + + DEBUG_PRINT_LOW("\n In Convert and queue Meta Buffer"); + if(!psource_frame || !pdest_frame) { + DEBUG_PRINT_ERROR("\n convert_queue_buffer invalid params"); + return OMX_ErrorBadParameter; + } + + if(!psource_frame->nFilledLen){ + if(psource_frame->nFlags & OMX_BUFFERFLAG_EOS){ + pdest_frame->nFilledLen = psource_frame->nFilledLen; + pdest_frame->nTimeStamp = psource_frame->nTimeStamp; + pdest_frame->nFlags = psource_frame->nFlags; + DEBUG_PRINT_HIGH("\n Skipping color conversion for empty EOS \ + Buffer header=%p filled-len=%d", pdest_frame,pdest_frame->nFilledLen); + } else { + pdest_frame->nOffset = 0; + pdest_frame->nFilledLen = 0; + pdest_frame->nTimeStamp = psource_frame->nTimeStamp; + pdest_frame->nFlags = psource_frame->nFlags; + DEBUG_PRINT_LOW("\n Buffer header %p Filled len size %d", + pdest_frame,pdest_frame->nFilledLen); + } + } else { + uva = (unsigned char *)mmap(NULL, Input_pmem_info.size, + PROT_READ|PROT_WRITE, + MAP_SHARED,Input_pmem_info.fd,0); + if(uva == MAP_FAILED) { + ret = OMX_ErrorBadParameter; + } else { + if(!c2d_conv.convert(Input_pmem_info.fd,uva, + m_pInput_pmem[index].fd,pdest_frame->pBuffer)) { + DEBUG_PRINT_ERROR("\n Color Conversion failed"); + ret = OMX_ErrorBadParameter; + } else { + unsigned int buf_size = 0; + if (!c2d_conv.get_buffer_size(C2D_OUTPUT,buf_size)) + ret = OMX_ErrorBadParameter; + else { + pdest_frame->nOffset = 0; + if(!buf_size || buf_size > pdest_frame->nAllocLen) { + DEBUG_PRINT_ERROR("\n convert_queue_buffer buffer" + "size mismatch buf size %d alloc size %d", + buf_size, pdest_frame->nAllocLen); + ret = OMX_ErrorBadParameter; + buf_size = 0; + } + pdest_frame->nFilledLen = buf_size; + pdest_frame->nTimeStamp = psource_frame->nTimeStamp; + pdest_frame->nFlags = psource_frame->nFlags; + DEBUG_PRINT_LOW("\n Buffer header %p Filled len size %d", + pdest_frame,pdest_frame->nFilledLen); + } + } + munmap(uva,Input_pmem_info.size); + } + } + if((ret == OMX_ErrorNone) && + dev_use_buf(&m_pInput_pmem[index],PORT_INDEX_IN,0) != true) { + DEBUG_PRINT_ERROR("\nERROR: in dev_use_buf"); + post_event ((unsigned int)pdest_frame,0,OMX_COMPONENT_GENERATE_EBD); + ret = OMX_ErrorBadParameter; + } + if(ret == OMX_ErrorNone) + ret = empty_this_buffer_proxy(hComp,pdest_frame); + if(ret == OMX_ErrorNone) { + m_pCallbacks.EmptyBufferDone(hComp ,m_app_data, psource_frame); + psource_frame = NULL; + pdest_frame = NULL; + if(!psource_frame && m_opq_meta_q.m_size) { + m_opq_meta_q.pop_entry(&address,&p2,&id); + psource_frame = (OMX_BUFFERHEADERTYPE* ) address; + } + if(!pdest_frame && m_opq_pmem_q.m_size) { + m_opq_pmem_q.pop_entry(&address,&p2,&id); + pdest_frame = (OMX_BUFFERHEADERTYPE* ) address; + DEBUG_PRINT_LOW("\n pdest_frame pop address is %p",pdest_frame); + } + } + return ret; +} + +OMX_ERRORTYPE omx_video::push_input_buffer(OMX_HANDLETYPE hComp) +{ + unsigned address = 0,p2,id, index = 0; + OMX_ERRORTYPE ret = OMX_ErrorNone; + + if(!psource_frame && m_opq_meta_q.m_size) { + m_opq_meta_q.pop_entry(&address,&p2,&id); + psource_frame = (OMX_BUFFERHEADERTYPE* ) address; + } + if(!pdest_frame && m_opq_pmem_q.m_size) { + m_opq_pmem_q.pop_entry(&address,&p2,&id); + pdest_frame = (OMX_BUFFERHEADERTYPE* ) address; + } + while(psource_frame != NULL && pdest_frame != NULL && + ret == OMX_ErrorNone) { + struct pmem Input_pmem_info; + encoder_media_buffer_type *media_buffer; + index = pdest_frame - m_inp_mem_ptr; + if(index >= m_sInPortDef.nBufferCountActual){ + DEBUG_PRINT_ERROR("\n Output buffer index is wrong %d act count %d", + index,m_sInPortDef.nBufferCountActual); + return OMX_ErrorBadParameter; + } + media_buffer = (encoder_media_buffer_type *)psource_frame->pBuffer; + /*Will enable to verify camcorder in current TIPS can be removed*/ + if(media_buffer->buffer_type == kMetadataBufferTypeCameraSource) { + Input_pmem_info.buffer = media_buffer; + Input_pmem_info.fd = media_buffer->meta_handle->data[0]; + Input_pmem_info.offset = media_buffer->meta_handle->data[1]; + Input_pmem_info.size = media_buffer->meta_handle->data[2]; + DEBUG_PRINT_LOW("ETB fd = %d, offset = %d, size = %d",Input_pmem_info.fd, + Input_pmem_info.offset, + Input_pmem_info.size); + ret = queue_meta_buffer(hComp,Input_pmem_info); + } else if((psource_frame->nFlags & OMX_BUFFERFLAG_EOS) && mUseProxyColorFormat) { + ret = convert_queue_buffer(hComp,Input_pmem_info,index); + } else { + private_handle_t *handle = (private_handle_t *)media_buffer->meta_handle; + Input_pmem_info.buffer = media_buffer; + Input_pmem_info.fd = handle->fd; + Input_pmem_info.offset = 0; + Input_pmem_info.size = handle->size; + if(handle->format == HAL_PIXEL_FORMAT_RGBA_8888) + ret = convert_queue_buffer(hComp,Input_pmem_info,index); + else if(handle->format == HAL_PIXEL_FORMAT_NV12_ENCODEABLE) + ret = queue_meta_buffer(hComp,Input_pmem_info); + else + ret = OMX_ErrorBadParameter; + } + } + return ret; +} diff --git a/mm-video/vidc/venc/src/omx_video_encoder.cpp b/mm-video/vidc/venc/src/omx_video_encoder.cpp index 6f77c0b..133ef7d 100644 --- a/mm-video/vidc/venc/src/omx_video_encoder.cpp +++ b/mm-video/vidc/venc/src/omx_video_encoder.cpp @@ -1,1676 +1,1821 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2010-2012, Code Aurora Forum. 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 Code Aurora 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. ---------------------------------------------------------------------------*/ -#include "omx_video_encoder.h" -#include -#include "video_encoder_device.h" -#include -#ifdef _ANDROID_ICS_ -#include -#endif -#ifdef _ANDROID_ -#include -#endif -#ifndef _ANDROID_ -#include -#define strlcpy g_strlcpy -#endif -/*---------------------------------------------------------------------------- -* Preprocessor Definitions and Constants -* -------------------------------------------------------------------------*/ - -#define OMX_SPEC_VERSION 0x00000101 -#define OMX_INIT_STRUCT(_s_, _name_) \ - memset((_s_), 0x0, sizeof(_name_)); \ - (_s_)->nSize = sizeof(_name_); \ - (_s_)->nVersion.nVersion = OMX_SPEC_VERSION - -extern int m_pipe; - -// factory function executed by the core to create instances -void *get_omx_component_factory_fn(void) -{ - return(new omx_venc); -} - -//constructor - -omx_venc::omx_venc() -{ -#ifdef _ANDROID_ICS_ - get_syntaxhdr_enable == false; - meta_mode_enable = false; - memset(meta_buffer_hdr,0,sizeof(meta_buffer_hdr)); - memset(meta_buffers,0,sizeof(meta_buffers)); - mUseProxyColorFormat = false; -#endif -} - -omx_venc::~omx_venc() -{ - get_syntaxhdr_enable == false; - //nothing to do -} - -/* ====================================================================== -FUNCTION - omx_venc::ComponentInit - -DESCRIPTION - Initialize the component. - -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. - -========================================================================== */ -OMX_ERRORTYPE omx_venc::component_init(OMX_STRING role) -{ - - OMX_ERRORTYPE eRet = OMX_ErrorNone; - - int fds[2]; - int r; - - OMX_VIDEO_CODINGTYPE codec_type; - - DEBUG_PRINT_HIGH("\n omx_venc(): Inside component_init()"); - // Copy the role information which provides the decoder m_nkind - strlcpy((char *)m_nkind,role,OMX_MAX_STRINGNAME_SIZE); - - if(!strncmp((char *)m_nkind,"OMX.qcom.video.encoder.mpeg4",\ - OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char *)m_cRole, "video_encoder.mpeg4",\ - OMX_MAX_STRINGNAME_SIZE); - codec_type = OMX_VIDEO_CodingMPEG4; - } - else if(!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.h263",\ - OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char *)m_cRole, "video_encoder.h263",OMX_MAX_STRINGNAME_SIZE); - codec_type = OMX_VIDEO_CodingH263; - } - else if(!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.avc",\ - OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char *)m_cRole, "video_encoder.avc",OMX_MAX_STRINGNAME_SIZE); - codec_type = OMX_VIDEO_CodingAVC; - } -#ifdef _MSM8974_ - else if(!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.vp8", \ - OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char *)m_cRole, "video_encoder.vp8",OMX_MAX_STRINGNAME_SIZE); - codec_type = OMX_VIDEO_CodingVPX; - } -#endif - else - { - DEBUG_PRINT_ERROR("\nERROR: Unknown Component\n"); - eRet = OMX_ErrorInvalidComponentName; - } - - - if(eRet != OMX_ErrorNone) - { - return eRet; - } -#ifdef ENABLE_GET_SYNTAX_HDR - get_syntaxhdr_enable = true; -#endif - - handle = new venc_dev(this); - - if(handle == NULL) - { - DEBUG_PRINT_ERROR("\nERROR: handle is NULL"); - return OMX_ErrorInsufficientResources; - } - - if(handle->venc_open(codec_type) != true) - { - DEBUG_PRINT_ERROR("\nERROR: venc_open failed"); - return OMX_ErrorInsufficientResources; - } - - //Intialise the OMX layer variables - memset(&m_pCallbacks,0,sizeof(OMX_CALLBACKTYPE)); - - OMX_INIT_STRUCT(&m_sPortParam, OMX_PORT_PARAM_TYPE); - m_sPortParam.nPorts = 0x2; - m_sPortParam.nStartPortNumber = (OMX_U32) PORT_INDEX_IN; - - OMX_INIT_STRUCT(&m_sPortParam_audio, OMX_PORT_PARAM_TYPE); - m_sPortParam_audio.nPorts = 0; - m_sPortParam_audio.nStartPortNumber = 0; - - OMX_INIT_STRUCT(&m_sPortParam_img, OMX_PORT_PARAM_TYPE); - m_sPortParam_img.nPorts = 0; - m_sPortParam_img.nStartPortNumber = 0; - - OMX_INIT_STRUCT(&m_sParamBitrate, OMX_VIDEO_PARAM_BITRATETYPE); - m_sParamBitrate.nPortIndex = (OMX_U32) PORT_INDEX_OUT; - m_sParamBitrate.eControlRate = OMX_Video_ControlRateVariableSkipFrames; - m_sParamBitrate.nTargetBitrate = 64000; - - OMX_INIT_STRUCT(&m_sConfigBitrate, OMX_VIDEO_CONFIG_BITRATETYPE); - m_sConfigBitrate.nPortIndex = (OMX_U32) PORT_INDEX_OUT; - m_sConfigBitrate.nEncodeBitrate = 64000; - - OMX_INIT_STRUCT(&m_sConfigFramerate, OMX_CONFIG_FRAMERATETYPE); - m_sConfigFramerate.nPortIndex = (OMX_U32) PORT_INDEX_OUT; - m_sConfigFramerate.xEncodeFramerate = 30 << 16; - - OMX_INIT_STRUCT(&m_sConfigIntraRefreshVOP, OMX_CONFIG_INTRAREFRESHVOPTYPE); - m_sConfigIntraRefreshVOP.nPortIndex = (OMX_U32) PORT_INDEX_OUT; - m_sConfigIntraRefreshVOP.IntraRefreshVOP = OMX_FALSE; - - OMX_INIT_STRUCT(&m_sConfigFrameRotation, OMX_CONFIG_ROTATIONTYPE); - m_sConfigFrameRotation.nPortIndex = (OMX_U32) PORT_INDEX_IN; - m_sConfigFrameRotation.nRotation = 0; - - OMX_INIT_STRUCT(&m_sSessionQuantization, OMX_VIDEO_PARAM_QUANTIZATIONTYPE); - m_sSessionQuantization.nPortIndex = (OMX_U32) PORT_INDEX_OUT; - m_sSessionQuantization.nQpI = 9; - m_sSessionQuantization.nQpP = 6; - m_sSessionQuantization.nQpB = 2; - - OMX_INIT_STRUCT(&m_sAVCSliceFMO, OMX_VIDEO_PARAM_AVCSLICEFMO); - m_sAVCSliceFMO.nPortIndex = (OMX_U32) PORT_INDEX_OUT; - m_sAVCSliceFMO.eSliceMode = OMX_VIDEO_SLICEMODE_AVCDefault; - m_sAVCSliceFMO.nNumSliceGroups = 0; - m_sAVCSliceFMO.nSliceGroupMapType = 0; - OMX_INIT_STRUCT(&m_sParamProfileLevel, OMX_VIDEO_PARAM_PROFILELEVELTYPE); - m_sParamProfileLevel.nPortIndex = (OMX_U32) PORT_INDEX_OUT; - - OMX_INIT_STRUCT(&m_sIntraperiod, QOMX_VIDEO_INTRAPERIODTYPE); - m_sIntraperiod.nPortIndex = (OMX_U32) PORT_INDEX_OUT; - m_sIntraperiod.nPFrames = (m_sConfigFramerate.xEncodeFramerate * 2) - 1; - - OMX_INIT_STRUCT(&m_sErrorCorrection, OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE); - m_sErrorCorrection.nPortIndex = (OMX_U32) PORT_INDEX_OUT; - m_sErrorCorrection.bEnableDataPartitioning = OMX_FALSE; - m_sErrorCorrection.bEnableHEC = OMX_FALSE; - m_sErrorCorrection.bEnableResync = OMX_FALSE; - m_sErrorCorrection.bEnableRVLC = OMX_FALSE; - m_sErrorCorrection.nResynchMarkerSpacing = 0; - - OMX_INIT_STRUCT(&m_sIntraRefresh, OMX_VIDEO_PARAM_INTRAREFRESHTYPE); - m_sIntraRefresh.nPortIndex = (OMX_U32) PORT_INDEX_OUT; - m_sIntraRefresh.eRefreshMode = OMX_VIDEO_IntraRefreshMax; - - if(codec_type == OMX_VIDEO_CodingMPEG4) - { - m_sParamProfileLevel.eProfile = (OMX_U32) OMX_VIDEO_MPEG4ProfileSimple; - m_sParamProfileLevel.eLevel = (OMX_U32) OMX_VIDEO_MPEG4Level0; - } - else if(codec_type == OMX_VIDEO_CodingH263) - { - m_sParamProfileLevel.eProfile = (OMX_U32) OMX_VIDEO_H263ProfileBaseline; - m_sParamProfileLevel.eLevel = (OMX_U32) OMX_VIDEO_H263Level10; - } - else if(codec_type == OMX_VIDEO_CodingAVC) - { - m_sParamProfileLevel.eProfile = (OMX_U32) OMX_VIDEO_AVCProfileBaseline; - m_sParamProfileLevel.eLevel = (OMX_U32) OMX_VIDEO_AVCLevel1; - } - - // Initialize the video parameters for input port - OMX_INIT_STRUCT(&m_sInPortDef, OMX_PARAM_PORTDEFINITIONTYPE); - m_sInPortDef.nPortIndex= (OMX_U32) PORT_INDEX_IN; - m_sInPortDef.bEnabled = OMX_TRUE; - m_sInPortDef.bPopulated = OMX_FALSE; - m_sInPortDef.eDomain = OMX_PortDomainVideo; - m_sInPortDef.eDir = OMX_DirInput; - m_sInPortDef.format.video.cMIMEType = "YUV420"; - m_sInPortDef.format.video.nFrameWidth = OMX_CORE_QCIF_WIDTH; - m_sInPortDef.format.video.nFrameHeight = OMX_CORE_QCIF_HEIGHT; - m_sInPortDef.format.video.nStride = OMX_CORE_QCIF_WIDTH; - m_sInPortDef.format.video.nSliceHeight = OMX_CORE_QCIF_HEIGHT; - m_sInPortDef.format.video.nBitrate = 64000; - m_sInPortDef.format.video.xFramerate = 15 << 16; - m_sInPortDef.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; - m_sInPortDef.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; - - if(dev_get_buf_req(&m_sInPortDef.nBufferCountMin, - &m_sInPortDef.nBufferCountActual, - &m_sInPortDef.nBufferSize, - m_sInPortDef.nPortIndex) != true) - { - eRet = OMX_ErrorUndefined; - - } - - // Initialize the video parameters for output port - OMX_INIT_STRUCT(&m_sOutPortDef, OMX_PARAM_PORTDEFINITIONTYPE); - m_sOutPortDef.nPortIndex = (OMX_U32) PORT_INDEX_OUT; - m_sOutPortDef.bEnabled = OMX_TRUE; - m_sOutPortDef.bPopulated = OMX_FALSE; - m_sOutPortDef.eDomain = OMX_PortDomainVideo; - m_sOutPortDef.eDir = OMX_DirOutput; - m_sOutPortDef.format.video.nFrameWidth = OMX_CORE_QCIF_WIDTH; - m_sOutPortDef.format.video.nFrameHeight = OMX_CORE_QCIF_HEIGHT; - m_sOutPortDef.format.video.nBitrate = 64000; - m_sOutPortDef.format.video.xFramerate = 15 << 16; - m_sOutPortDef.format.video.eColorFormat = OMX_COLOR_FormatUnused; - if(codec_type == OMX_VIDEO_CodingMPEG4) - { - m_sOutPortDef.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4; - } - else if(codec_type == OMX_VIDEO_CodingH263) - { - m_sOutPortDef.format.video.eCompressionFormat = OMX_VIDEO_CodingH263; - } - else - { - m_sOutPortDef.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC; - } - if(dev_get_buf_req(&m_sOutPortDef.nBufferCountMin, - &m_sOutPortDef.nBufferCountActual, - &m_sOutPortDef.nBufferSize, - m_sOutPortDef.nPortIndex) != true) - { - eRet = OMX_ErrorUndefined; - } - - // Initialize the video color format for input port - OMX_INIT_STRUCT(&m_sInPortFormat, OMX_VIDEO_PARAM_PORTFORMATTYPE); - m_sInPortFormat.nPortIndex = (OMX_U32) PORT_INDEX_IN; - m_sInPortFormat.nIndex = 0; - m_sInPortFormat.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; - m_sInPortFormat.eCompressionFormat = OMX_VIDEO_CodingUnused; - - - // Initialize the compression format for output port - OMX_INIT_STRUCT(&m_sOutPortFormat, OMX_VIDEO_PARAM_PORTFORMATTYPE); - m_sOutPortFormat.nPortIndex = (OMX_U32) PORT_INDEX_OUT; - m_sOutPortFormat.nIndex = 0; - m_sOutPortFormat.eColorFormat = OMX_COLOR_FormatUnused; - if(codec_type == OMX_VIDEO_CodingMPEG4) - { - m_sOutPortFormat.eCompressionFormat = OMX_VIDEO_CodingMPEG4; - } - else if(codec_type == OMX_VIDEO_CodingH263) - { - m_sOutPortFormat.eCompressionFormat = OMX_VIDEO_CodingH263; - } - else - { - m_sOutPortFormat.eCompressionFormat = OMX_VIDEO_CodingAVC; - } - - // mandatory Indices for kronos test suite - OMX_INIT_STRUCT(&m_sPriorityMgmt, OMX_PRIORITYMGMTTYPE); - - OMX_INIT_STRUCT(&m_sInBufSupplier, OMX_PARAM_BUFFERSUPPLIERTYPE); - m_sInBufSupplier.nPortIndex = (OMX_U32) PORT_INDEX_IN; - - OMX_INIT_STRUCT(&m_sOutBufSupplier, OMX_PARAM_BUFFERSUPPLIERTYPE); - m_sOutBufSupplier.nPortIndex = (OMX_U32) PORT_INDEX_OUT; - - - // mp4 specific init - OMX_INIT_STRUCT(&m_sParamMPEG4, OMX_VIDEO_PARAM_MPEG4TYPE); - m_sParamMPEG4.nPortIndex = (OMX_U32) PORT_INDEX_OUT; - m_sParamMPEG4.eProfile = OMX_VIDEO_MPEG4ProfileSimple; - m_sParamMPEG4.eLevel = OMX_VIDEO_MPEG4Level0; - m_sParamMPEG4.nSliceHeaderSpacing = 0; - m_sParamMPEG4.bSVH = OMX_FALSE; - m_sParamMPEG4.bGov = OMX_FALSE; - m_sParamMPEG4.nPFrames = (m_sOutPortFormat.xFramerate * 2 - 1); // 2 second intra period for default outport fps - m_sParamMPEG4.bACPred = OMX_TRUE; - m_sParamMPEG4.nTimeIncRes = 30; // delta = 2 @ 15 fps - m_sParamMPEG4.nAllowedPictureTypes = 2; // pframe and iframe - m_sParamMPEG4.nHeaderExtension = 1; // number of video packet headers per vop - m_sParamMPEG4.bReversibleVLC = OMX_FALSE; - - // h263 specific init - OMX_INIT_STRUCT(&m_sParamH263, OMX_VIDEO_PARAM_H263TYPE); - m_sParamH263.nPortIndex = (OMX_U32) PORT_INDEX_OUT; - m_sParamH263.nPFrames = (m_sOutPortFormat.xFramerate * 2 - 1); // 2 second intra period for default outport fps - m_sParamH263.nBFrames = 0; - m_sParamH263.eProfile = OMX_VIDEO_H263ProfileBaseline; - m_sParamH263.eLevel = OMX_VIDEO_H263Level10; - m_sParamH263.bPLUSPTYPEAllowed = OMX_FALSE; - m_sParamH263.nAllowedPictureTypes = 2; - m_sParamH263.bForceRoundingTypeToZero = OMX_TRUE; - m_sParamH263.nPictureHeaderRepetition = 0; - m_sParamH263.nGOBHeaderInterval = 1; - - // h264 specific init - OMX_INIT_STRUCT(&m_sParamAVC, OMX_VIDEO_PARAM_AVCTYPE); - m_sParamAVC.nPortIndex = (OMX_U32) PORT_INDEX_OUT; - m_sParamAVC.nSliceHeaderSpacing = 0; - m_sParamAVC.nPFrames = (m_sOutPortFormat.xFramerate * 2 - 1); // 2 second intra period for default outport fps - m_sParamAVC.nBFrames = 0; - m_sParamAVC.bUseHadamard = OMX_FALSE; - m_sParamAVC.nRefFrames = 1; - m_sParamAVC.nRefIdx10ActiveMinus1 = 1; - m_sParamAVC.nRefIdx11ActiveMinus1 = 0; - m_sParamAVC.bEnableUEP = OMX_FALSE; - m_sParamAVC.bEnableFMO = OMX_FALSE; - m_sParamAVC.bEnableASO = OMX_FALSE; - m_sParamAVC.bEnableRS = OMX_FALSE; - m_sParamAVC.eProfile = OMX_VIDEO_AVCProfileBaseline; - m_sParamAVC.eLevel = OMX_VIDEO_AVCLevel1; - m_sParamAVC.nAllowedPictureTypes = 2; - m_sParamAVC.bFrameMBsOnly = OMX_FALSE; - m_sParamAVC.bMBAFF = OMX_FALSE; - m_sParamAVC.bEntropyCodingCABAC = OMX_FALSE; - m_sParamAVC.bWeightedPPrediction = OMX_FALSE; - m_sParamAVC.nWeightedBipredicitonMode = 0; - m_sParamAVC.bconstIpred = OMX_FALSE; - m_sParamAVC.bDirect8x8Inference = OMX_FALSE; - m_sParamAVC.bDirectSpatialTemporal = OMX_FALSE; - m_sParamAVC.nCabacInitIdc = 0; - m_sParamAVC.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable; - - m_state = OMX_StateLoaded; - m_sExtraData = 0; - m_sDebugSliceinfo = 0; -#ifdef _ANDROID_ - char value[PROPERTY_VALUE_MAX] = {0}; - property_get("vidc.venc.debug.sliceinfo", value, "0"); - m_sDebugSliceinfo = (OMX_U32)atoi(value); - DEBUG_PRINT_HIGH("vidc.venc.debug.sliceinfo value is %d", m_sDebugSliceinfo); -#endif - - if(eRet == OMX_ErrorNone) - { - if(pipe(fds)) - { - DEBUG_PRINT_ERROR("ERROR: pipe creation failed\n"); - eRet = OMX_ErrorInsufficientResources; - } - else - { - if(fds[0] == 0 || fds[1] == 0) - { - if(pipe(fds)) - { - DEBUG_PRINT_ERROR("ERROR: pipe creation failed\n"); - eRet = OMX_ErrorInsufficientResources; - } - } - if(eRet == OMX_ErrorNone) - { - m_pipe_in = fds[0]; - m_pipe_out = fds[1]; - } - } - r = pthread_create(&msg_thread_id,0,message_thread,this); - - if(r < 0) - { - eRet = OMX_ErrorInsufficientResources; - } - else - { - r = pthread_create(&async_thread_id,0,async_venc_message_thread,this); - if(r < 0) - { - eRet = OMX_ErrorInsufficientResources; - } - } - } - - DEBUG_PRINT_HIGH("\n Component_init return value = 0x%x", eRet); - return eRet; -} - - -/* ====================================================================== -FUNCTION - omx_venc::Setparameter - -DESCRIPTION - OMX Set Parameter method implementation. - -PARAMETERS - . - -RETURN VALUE - OMX Error None if successful. - -========================================================================== */ -OMX_ERRORTYPE omx_venc::set_parameter(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_INDEXTYPE paramIndex, - OMX_IN OMX_PTR paramData) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - - - if(m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("ERROR: Set Param in Invalid State\n"); - return OMX_ErrorInvalidState; - } - if(paramData == NULL) - { - DEBUG_PRINT_ERROR("ERROR: Get Param in Invalid paramData \n"); - return OMX_ErrorBadParameter; - } - - /*set_parameter can be called in loaded state - or disabled port */ - if(m_state == OMX_StateLoaded - || m_sInPortDef.bEnabled == OMX_FALSE - || m_sOutPortDef.bEnabled == OMX_FALSE) - { - DEBUG_PRINT_LOW("Set Parameter called in valid state"); - } - else - { - DEBUG_PRINT_ERROR("ERROR: Set Parameter called in Invalid State\n"); - return OMX_ErrorIncorrectStateOperation; - } - - switch(paramIndex) - { - case OMX_IndexParamPortDefinition: - { - OMX_PARAM_PORTDEFINITIONTYPE *portDefn; - portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData; - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d\n", - (int)portDefn->format.video.nFrameHeight, - (int)portDefn->format.video.nFrameWidth); - - if(PORT_INDEX_IN == portDefn->nPortIndex) - { - DEBUG_PRINT_LOW("\n i/p actual cnt requested = %d\n", portDefn->nBufferCountActual); - DEBUG_PRINT_LOW("\n i/p min cnt requested = %d\n", portDefn->nBufferCountMin); - DEBUG_PRINT_LOW("\n i/p buffersize requested = %d\n", portDefn->nBufferSize); - if(handle->venc_set_param(paramData,OMX_IndexParamPortDefinition) != true) - { - DEBUG_PRINT_ERROR("\nERROR: venc_set_param input failed"); - return OMX_ErrorUnsupportedSetting; - } - - DEBUG_PRINT_LOW("\n i/p previous actual cnt = %d\n", m_sInPortDef.nBufferCountActual); - DEBUG_PRINT_LOW("\n i/p previous min cnt = %d\n", m_sInPortDef.nBufferCountMin); - memcpy(&m_sInPortDef, portDefn,sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); - -#ifdef _ANDROID_ICS_ - if (portDefn->format.video.eColorFormat == (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FormatAndroidOpaque) { - m_sInPortDef.format.video.eColorFormat = - OMX_COLOR_FormatYUV420SemiPlanar; - mUseProxyColorFormat = true; - } //else case not needed as color format is already updated in the memcpy above -#endif - /*Query Input Buffer Requirements*/ - dev_get_buf_req (&m_sInPortDef.nBufferCountMin, - &m_sInPortDef.nBufferCountActual, - &m_sInPortDef.nBufferSize, - m_sInPortDef.nPortIndex); - - /*Query ouput Buffer Requirements*/ - dev_get_buf_req (&m_sOutPortDef.nBufferCountMin, - &m_sOutPortDef.nBufferCountActual, - &m_sOutPortDef.nBufferSize, - m_sOutPortDef.nPortIndex); - m_sInPortDef.nBufferCountActual = portDefn->nBufferCountActual; - } - else if(PORT_INDEX_OUT == portDefn->nPortIndex) - { - DEBUG_PRINT_LOW("\n o/p actual cnt requested = %d\n", portDefn->nBufferCountActual); - DEBUG_PRINT_LOW("\n o/p min cnt requested = %d\n", portDefn->nBufferCountMin); - DEBUG_PRINT_LOW("\n o/p buffersize requested = %d\n", portDefn->nBufferSize); - if(handle->venc_set_param(paramData,OMX_IndexParamPortDefinition) != true) - { - DEBUG_PRINT_ERROR("\nERROR: venc_set_param output failed"); - return OMX_ErrorUnsupportedSetting; - } - memcpy(&m_sOutPortDef,portDefn,sizeof(struct OMX_PARAM_PORTDEFINITIONTYPE)); - update_profile_level(); //framerate , bitrate - - DEBUG_PRINT_LOW("\n o/p previous actual cnt = %d\n", m_sOutPortDef.nBufferCountActual); - DEBUG_PRINT_LOW("\n o/p previous min cnt = %d\n", m_sOutPortDef.nBufferCountMin); - m_sOutPortDef.nBufferCountActual = portDefn->nBufferCountActual; - } - else - { - DEBUG_PRINT_ERROR("ERROR: Set_parameter: Bad Port idx %d", - (int)portDefn->nPortIndex); - eRet = OMX_ErrorBadPortIndex; - } - m_sConfigFramerate.xEncodeFramerate = portDefn->format.video.xFramerate; - m_sConfigBitrate.nEncodeBitrate = portDefn->format.video.nBitrate; - m_sParamBitrate.nTargetBitrate = portDefn->format.video.nBitrate; - } - break; - - case OMX_IndexParamVideoPortFormat: - { - OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt = - (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData; - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d\n", - portFmt->eColorFormat); - //set the driver with the corresponding values - if(PORT_INDEX_IN == portFmt->nPortIndex) - { - if(handle->venc_set_param(paramData,OMX_IndexParamVideoPortFormat) != true) - { - return OMX_ErrorUnsupportedSetting; - } - - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d\n", - portFmt->eColorFormat); - update_profile_level(); //framerate - -#ifdef _ANDROID_ICS_ - if (portFmt->eColorFormat == - (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FormatAndroidOpaque) { - m_sInPortFormat.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; - mUseProxyColorFormat = true; - } - else -#endif - { - m_sInPortFormat.eColorFormat = portFmt->eColorFormat; - } - m_sInPortFormat.xFramerate = portFmt->xFramerate; - } - //TODO if no use case for O/P port,delet m_sOutPortFormat - } - break; - case OMX_IndexParamVideoInit: - { //TODO, do we need this index set param - OMX_PORT_PARAM_TYPE* pParam = (OMX_PORT_PARAM_TYPE*)(paramData); - DEBUG_PRINT_LOW("\n Set OMX_IndexParamVideoInit called"); - break; - } - - case OMX_IndexParamVideoBitrate: - { - OMX_VIDEO_PARAM_BITRATETYPE* pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData; - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoBitrate"); - if(handle->venc_set_param(paramData,OMX_IndexParamVideoBitrate) != true) - { - return OMX_ErrorUnsupportedSetting; - } - m_sParamBitrate.nTargetBitrate = pParam->nTargetBitrate; - m_sParamBitrate.eControlRate = pParam->eControlRate; - update_profile_level(); //bitrate - m_sConfigBitrate.nEncodeBitrate = pParam->nTargetBitrate; - m_sInPortDef.format.video.nBitrate = pParam->nTargetBitrate; - m_sOutPortDef.format.video.nBitrate = pParam->nTargetBitrate; - DEBUG_PRINT_LOW("\nbitrate = %u", m_sOutPortDef.format.video.nBitrate); - break; - } - case OMX_IndexParamVideoMpeg4: - { - OMX_VIDEO_PARAM_MPEG4TYPE* pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData; - OMX_VIDEO_PARAM_MPEG4TYPE mp4_param; - memcpy(&mp4_param, pParam, sizeof(struct OMX_VIDEO_PARAM_MPEG4TYPE)); - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4"); - if(pParam->eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) - { -#ifdef MAX_RES_1080P - if(pParam->nBFrames) - { - DEBUG_PRINT_HIGH("INFO: Only 1 Bframe is supported"); - mp4_param.nBFrames = 1; - } -#else - if(pParam->nBFrames) - { - DEBUG_PRINT_ERROR("Warning: B frames not supported\n"); - mp4_param.nBFrames = 0; - } -#endif - } - else - { - if(pParam->nBFrames) - { - DEBUG_PRINT_ERROR("Warning: B frames not supported\n"); - mp4_param.nBFrames = 0; - } - } - if(handle->venc_set_param(&mp4_param,OMX_IndexParamVideoMpeg4) != true) - { - return OMX_ErrorUnsupportedSetting; - } - memcpy(&m_sParamMPEG4,pParam, sizeof(struct OMX_VIDEO_PARAM_MPEG4TYPE)); - break; - } - case OMX_IndexParamVideoH263: - { - OMX_VIDEO_PARAM_H263TYPE* pParam = (OMX_VIDEO_PARAM_H263TYPE*)paramData; - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263"); - if(handle->venc_set_param(paramData,OMX_IndexParamVideoH263) != true) - { - return OMX_ErrorUnsupportedSetting; - } - memcpy(&m_sParamH263,pParam, sizeof(struct OMX_VIDEO_PARAM_H263TYPE)); - break; - } - case OMX_IndexParamVideoAvc: - { - OMX_VIDEO_PARAM_AVCTYPE* pParam = (OMX_VIDEO_PARAM_AVCTYPE*)paramData; - OMX_VIDEO_PARAM_AVCTYPE avc_param; - memcpy(&avc_param, pParam, sizeof( struct OMX_VIDEO_PARAM_AVCTYPE)); - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc"); - - if((pParam->eProfile == OMX_VIDEO_AVCProfileHigh)|| - (pParam->eProfile == OMX_VIDEO_AVCProfileMain)) - { -#ifdef MAX_RES_1080P - if(pParam->nBFrames) - { - DEBUG_PRINT_HIGH("INFO: Only 1 Bframe is supported"); - avc_param.nBFrames = 1; - } - if(pParam->nRefFrames != 2) - { - DEBUG_PRINT_ERROR("Warning: 2 RefFrames are needed, changing RefFrames from %d to 2", pParam->nRefFrames); - avc_param.nRefFrames = 2; - } -#else - if(pParam->nBFrames) - { - DEBUG_PRINT_ERROR("Warning: B frames not supported\n"); - avc_param.nBFrames = 0; - } - if(pParam->nRefFrames != 1) - { - DEBUG_PRINT_ERROR("Warning: Only 1 RefFrame is supported, changing RefFrame from %d to 1)", pParam->nRefFrames); - avc_param.nRefFrames = 1; - } -#endif - } - else - { - if(pParam->nRefFrames != 1) - { - DEBUG_PRINT_ERROR("Warning: Only 1 RefFrame is supported, changing RefFrame from %d to 1)", pParam->nRefFrames); - avc_param.nRefFrames = 1; - } - if(pParam->nBFrames) - { - DEBUG_PRINT_ERROR("Warning: B frames not supported\n"); - avc_param.nBFrames = 0; - } - } - if(handle->venc_set_param(&avc_param,OMX_IndexParamVideoAvc) != true) - { - return OMX_ErrorUnsupportedSetting; - } - memcpy(&m_sParamAVC,pParam, sizeof(struct OMX_VIDEO_PARAM_AVCTYPE)); - break; - } - case OMX_IndexParamVideoProfileLevelCurrent: - { - OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData; - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoProfileLevelCurrent"); - if(handle->venc_set_param(pParam,OMX_IndexParamVideoProfileLevelCurrent) != true) - { - DEBUG_PRINT_ERROR("set_parameter: OMX_IndexParamVideoProfileLevelCurrent failed for Profile: %d " - "Level :%d", pParam->eProfile, pParam->eLevel); - return OMX_ErrorUnsupportedSetting; - } - m_sParamProfileLevel.eProfile = pParam->eProfile; - m_sParamProfileLevel.eLevel = pParam->eLevel; - - if(!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.mpeg4",\ - OMX_MAX_STRINGNAME_SIZE)) - { - m_sParamMPEG4.eProfile = (OMX_VIDEO_MPEG4PROFILETYPE)m_sParamProfileLevel.eProfile; - m_sParamMPEG4.eLevel = (OMX_VIDEO_MPEG4LEVELTYPE)m_sParamProfileLevel.eLevel; - DEBUG_PRINT_LOW("\n MPEG4 profile = %d, level = %d", m_sParamMPEG4.eProfile, - m_sParamMPEG4.eLevel); - } - else if(!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.h263",\ - OMX_MAX_STRINGNAME_SIZE)) - { - m_sParamH263.eProfile = (OMX_VIDEO_H263PROFILETYPE)m_sParamProfileLevel.eProfile; - m_sParamH263.eLevel = (OMX_VIDEO_H263LEVELTYPE)m_sParamProfileLevel.eLevel; - DEBUG_PRINT_LOW("\n H263 profile = %d, level = %d", m_sParamH263.eProfile, - m_sParamH263.eLevel); - } - else if(!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.avc",\ - OMX_MAX_STRINGNAME_SIZE)) - { - m_sParamAVC.eProfile = (OMX_VIDEO_AVCPROFILETYPE)m_sParamProfileLevel.eProfile; - m_sParamAVC.eLevel = (OMX_VIDEO_AVCLEVELTYPE)m_sParamProfileLevel.eLevel; - DEBUG_PRINT_LOW("\n AVC profile = %d, level = %d", m_sParamAVC.eProfile, - m_sParamAVC.eLevel); - } - break; - } - case OMX_IndexParamStandardComponentRole: - { - OMX_PARAM_COMPONENTROLETYPE *comp_role; - comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData; - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s\n", - comp_role->cRole); - - if((m_state == OMX_StateLoaded)&& - !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) - { - DEBUG_PRINT_LOW("Set Parameter called in valid state"); - } - else - { - DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n"); - return OMX_ErrorIncorrectStateOperation; - } - - if(!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.avc",OMX_MAX_STRINGNAME_SIZE)) - { - if(!strncmp((char*)comp_role->cRole,"video_encoder.avc",OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char*)m_cRole,"video_encoder.avc",OMX_MAX_STRINGNAME_SIZE); - } - else - { - DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown Index %s\n", comp_role->cRole); - eRet =OMX_ErrorUnsupportedSetting; - } - } - else if(!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) - { - if(!strncmp((const char*)comp_role->cRole,"video_encoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char*)m_cRole,"video_encoder.mpeg4",OMX_MAX_STRINGNAME_SIZE); - } - else - { - DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown Index %s\n", comp_role->cRole); - eRet = OMX_ErrorUnsupportedSetting; - } - } - else if(!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.h263",OMX_MAX_STRINGNAME_SIZE)) - { - if(!strncmp((const char*)comp_role->cRole,"video_encoder.h263",OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char*)m_cRole,"video_encoder.h263",OMX_MAX_STRINGNAME_SIZE); - } - else - { - DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown Index %s\n", comp_role->cRole); - eRet =OMX_ErrorUnsupportedSetting; - } - } -#ifdef _MSM8974_ - else if(!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.vp8",OMX_MAX_STRINGNAME_SIZE)) - { - if(!strncmp((const char*)comp_role->cRole,"video_encoder.vp8",OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char*)m_cRole,"video_encoder.vp8",OMX_MAX_STRINGNAME_SIZE); - } - else - { - DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown Index %s\n", comp_role->cRole); - eRet =OMX_ErrorUnsupportedSetting; - } - } -#endif - else - { - DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown param %s\n", m_nkind); - eRet = OMX_ErrorInvalidComponentName; - } - break; - } - - case OMX_IndexParamPriorityMgmt: - { - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt"); - if(m_state != OMX_StateLoaded) - { - DEBUG_PRINT_ERROR("ERROR: Set Parameter called in Invalid State\n"); - return OMX_ErrorIncorrectStateOperation; - } - OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData; - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %d\n", - priorityMgmtype->nGroupID); - - DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %d\n", - priorityMgmtype->nGroupPriority); - - m_sPriorityMgmt.nGroupID = priorityMgmtype->nGroupID; - m_sPriorityMgmt.nGroupPriority = priorityMgmtype->nGroupPriority; - - break; - } - - case OMX_IndexParamCompBufferSupplier: - { - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier"); - OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData; - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d\n", - bufferSupplierType->eBufferSupplier); - if(bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1) - m_sInBufSupplier.eBufferSupplier = bufferSupplierType->eBufferSupplier; - - else - - eRet = OMX_ErrorBadPortIndex; - - break; - - } - case OMX_IndexParamVideoQuantization: - { - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoQuantization\n"); - OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp = (OMX_VIDEO_PARAM_QUANTIZATIONTYPE*) paramData; - if(session_qp->nPortIndex == PORT_INDEX_OUT) - { - if(handle->venc_set_param(paramData, OMX_IndexParamVideoQuantization) != true) - { - return OMX_ErrorUnsupportedSetting; - } - m_sSessionQuantization.nQpI = session_qp->nQpI; - m_sSessionQuantization.nQpP = session_qp->nQpP; - } - else - { - DEBUG_PRINT_ERROR("\nERROR: Unsupported port Index for Session QP setting\n"); - eRet = OMX_ErrorBadPortIndex; - } - break; - } - - case OMX_QcomIndexPortDefn: - { - OMX_QCOM_PARAM_PORTDEFINITIONTYPE* pParam = - (OMX_QCOM_PARAM_PORTDEFINITIONTYPE*)paramData; - DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexPortDefn"); - if(pParam->nPortIndex == (OMX_U32)PORT_INDEX_IN) - { - if(pParam->nMemRegion > OMX_QCOM_MemRegionInvalid && - pParam->nMemRegion < OMX_QCOM_MemRegionMax) - { - m_use_input_pmem = OMX_TRUE; - } - else - { - m_use_input_pmem = OMX_FALSE; - } - } - else if (pParam->nPortIndex == (OMX_U32)PORT_INDEX_OUT) - { - if(pParam->nMemRegion > OMX_QCOM_MemRegionInvalid && - pParam->nMemRegion < OMX_QCOM_MemRegionMax) - { - m_use_output_pmem = OMX_TRUE; - } - else - { - m_use_output_pmem = OMX_FALSE; - } - } - else - { - DEBUG_PRINT_ERROR("ERROR: SetParameter called on unsupported Port Index for QcomPortDefn"); - return OMX_ErrorBadPortIndex; - } - break; - } - - case OMX_IndexParamVideoErrorCorrection: - { - DEBUG_PRINT_LOW("OMX_IndexParamVideoErrorCorrection\n"); - OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* pParam = - (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE*)paramData; - if(!handle->venc_set_param(paramData, OMX_IndexParamVideoErrorCorrection)) - { - DEBUG_PRINT_ERROR("\nERROR: Request for setting Error Resilience failed"); - return OMX_ErrorUnsupportedSetting; - } - memcpy(&m_sErrorCorrection,pParam, sizeof(m_sErrorCorrection)); - break; - } - case OMX_IndexParamVideoIntraRefresh: - { - DEBUG_PRINT_LOW("set_param:OMX_IndexParamVideoIntraRefresh\n"); - OMX_VIDEO_PARAM_INTRAREFRESHTYPE* pParam = - (OMX_VIDEO_PARAM_INTRAREFRESHTYPE*)paramData; - if(!handle->venc_set_param(paramData,OMX_IndexParamVideoIntraRefresh)) - { - DEBUG_PRINT_ERROR("\nERROR: Request for setting intra refresh failed"); - return OMX_ErrorUnsupportedSetting; - } - memcpy(&m_sIntraRefresh, pParam, sizeof(m_sIntraRefresh)); - break; - } -#ifdef _ANDROID_ICS_ - case OMX_QcomIndexParamVideoEncodeMetaBufferMode: - { - StoreMetaDataInBuffersParams *pParam = - (StoreMetaDataInBuffersParams*)paramData; - if(pParam->nPortIndex == PORT_INDEX_IN) - { - if(pParam->bStoreMetaData != meta_mode_enable) - { - if(!handle->venc_set_meta_mode(pParam->bStoreMetaData)) - { - DEBUG_PRINT_ERROR("\nERROR: set Metabuffer mode %d fail", - pParam->bStoreMetaData); - return OMX_ErrorUnsupportedSetting; - } - meta_mode_enable = pParam->bStoreMetaData; - if(meta_mode_enable) { - m_sInPortDef.nBufferCountActual = 4; - if(handle->venc_set_param(&m_sInPortDef,OMX_IndexParamPortDefinition) != true) - { - DEBUG_PRINT_ERROR("\nERROR: venc_set_param input failed"); - return OMX_ErrorUnsupportedSetting; - } - } else { - /*TODO: reset encoder driver Meta mode*/ - dev_get_buf_req (&m_sOutPortDef.nBufferCountMin, - &m_sOutPortDef.nBufferCountActual, - &m_sOutPortDef.nBufferSize, - m_sOutPortDef.nPortIndex); - } - } - } - break; - } -#endif -#ifndef MAX_RES_720P - case OMX_QcomIndexParamIndexExtraDataType: - { - DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamIndexExtraDataType"); - QOMX_INDEXEXTRADATATYPE *pParam = (QOMX_INDEXEXTRADATATYPE *)paramData; - if (pParam->nIndex == (OMX_INDEXTYPE)OMX_ExtraDataVideoEncoderSliceInfo) - { - if (pParam->nPortIndex == PORT_INDEX_OUT) - { - if (pParam->bEnabled == OMX_TRUE) - m_sExtraData |= VEN_EXTRADATA_SLICEINFO; - else - m_sExtraData &= ~VEN_EXTRADATA_SLICEINFO; - DEBUG_PRINT_HIGH("set_param: m_sExtraData=%x", m_sExtraData); - if(handle->venc_set_param(&m_sExtraData, - (OMX_INDEXTYPE)OMX_ExtraDataVideoEncoderSliceInfo) != true) - { - DEBUG_PRINT_ERROR("ERROR: Setting " - "OMX_QcomIndexParamIndexExtraDataType failed"); - return OMX_ErrorUnsupportedSetting; - } - else - { - m_sOutPortDef.nPortIndex = PORT_INDEX_OUT; - dev_get_buf_req(&m_sOutPortDef.nBufferCountMin, - &m_sOutPortDef.nBufferCountActual, - &m_sOutPortDef.nBufferSize, - m_sOutPortDef.nPortIndex); - DEBUG_PRINT_HIGH("updated out_buf_req: buffer cnt=%d, " - "count min=%d, buffer size=%d", - m_sOutPortDef.nBufferCountActual, - m_sOutPortDef.nBufferCountMin, - m_sOutPortDef.nBufferSize); - } - } - else - { - DEBUG_PRINT_ERROR("set_parameter: slice information is " - "valid for output port only"); - eRet = OMX_ErrorUnsupportedIndex; - } - } - else - { - DEBUG_PRINT_ERROR("set_parameter: unsupported index (%x), " - "only slice information extradata is supported", pParam->nIndex); - eRet = OMX_ErrorUnsupportedIndex; - } - break; - } -#endif - case OMX_QcomIndexParamVideoMaxAllowedBitrateCheck: - { - QOMX_EXTNINDEX_PARAMTYPE* pParam = - (QOMX_EXTNINDEX_PARAMTYPE*)paramData; - if(pParam->nPortIndex == PORT_INDEX_OUT) - { - handle->m_max_allowed_bitrate_check = - ((pParam->bEnable == OMX_TRUE) ? true : false); - DEBUG_PRINT_HIGH("set_parameter: max allowed bitrate check %s", - ((pParam->bEnable == OMX_TRUE) ? "enabled" : "disabled")); - } - else - { - DEBUG_PRINT_ERROR("ERROR: OMX_QcomIndexParamVideoMaxAllowedBitrateCheck " - " called on wrong port(%d)", pParam->nPortIndex); - return OMX_ErrorBadPortIndex; - } - break; - } -#ifdef MAX_RES_1080P - case OMX_QcomIndexEnableSliceDeliveryMode: - { - QOMX_EXTNINDEX_PARAMTYPE* pParam = - (QOMX_EXTNINDEX_PARAMTYPE*)paramData; - if(pParam->nPortIndex == PORT_INDEX_OUT) - { - if(!handle->venc_set_param(paramData, - (OMX_INDEXTYPE)OMX_QcomIndexEnableSliceDeliveryMode)) - { - DEBUG_PRINT_ERROR("ERROR: Request for setting slice delivery mode failed"); - return OMX_ErrorUnsupportedSetting; - } - } - else - { - DEBUG_PRINT_ERROR("ERROR: OMX_QcomIndexEnableSliceDeliveryMode " - "called on wrong port(%d)", pParam->nPortIndex); - return OMX_ErrorBadPortIndex; - } - break; - } -#endif - case OMX_IndexParamVideoSliceFMO: - default: - { - DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown param %d\n", paramIndex); - eRet = OMX_ErrorUnsupportedIndex; - break; - } - } - return eRet; -} - -bool omx_venc::update_profile_level() -{ - OMX_U32 eProfile, eLevel; - - if(!handle->venc_get_profile_level(&eProfile,&eLevel)) - { - DEBUG_PRINT_ERROR("\nFailed to update the profile_level\n"); - return false; - } - - m_sParamProfileLevel.eProfile = (OMX_VIDEO_MPEG4PROFILETYPE)eProfile; - m_sParamProfileLevel.eLevel = (OMX_VIDEO_MPEG4LEVELTYPE)eLevel; - - if(!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.mpeg4",\ - OMX_MAX_STRINGNAME_SIZE)) - { - m_sParamMPEG4.eProfile = (OMX_VIDEO_MPEG4PROFILETYPE)eProfile; - m_sParamMPEG4.eLevel = (OMX_VIDEO_MPEG4LEVELTYPE)eLevel; - DEBUG_PRINT_LOW("\n MPEG4 profile = %d, level = %d", m_sParamMPEG4.eProfile, - m_sParamMPEG4.eLevel); - } - else if(!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.h263",\ - OMX_MAX_STRINGNAME_SIZE)) - { - m_sParamH263.eProfile = (OMX_VIDEO_H263PROFILETYPE)eProfile; - m_sParamH263.eLevel = (OMX_VIDEO_H263LEVELTYPE)eLevel; - DEBUG_PRINT_LOW("\n H263 profile = %d, level = %d", m_sParamH263.eProfile, - m_sParamH263.eLevel); - } - else if(!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.avc",\ - OMX_MAX_STRINGNAME_SIZE)) - { - m_sParamAVC.eProfile = (OMX_VIDEO_AVCPROFILETYPE)eProfile; - m_sParamAVC.eLevel = (OMX_VIDEO_AVCLEVELTYPE)eLevel; - DEBUG_PRINT_LOW("\n AVC profile = %d, level = %d", m_sParamAVC.eProfile, - m_sParamAVC.eLevel); - } - return true; -} -/* ====================================================================== -FUNCTION - omx_video::SetConfig - -DESCRIPTION - OMX Set Config method implementation - -PARAMETERS - . - -RETURN VALUE - OMX Error None if successful. -========================================================================== */ -OMX_ERRORTYPE omx_venc::set_config(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_INDEXTYPE configIndex, - OMX_IN OMX_PTR configData) -{ - if(configData == NULL) - { - DEBUG_PRINT_ERROR("ERROR: param is null"); - return OMX_ErrorBadParameter; - } - - if(m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("ERROR: config called in Invalid state"); - return OMX_ErrorIncorrectStateOperation; - } - - // params will be validated prior to venc_init - switch(configIndex) - { - case OMX_IndexConfigVideoBitrate: - { - OMX_VIDEO_CONFIG_BITRATETYPE* pParam = - reinterpret_cast(configData); - DEBUG_PRINT_LOW("\n omx_venc:: set_config(): OMX_IndexConfigVideoBitrate"); - - if(pParam->nPortIndex == PORT_INDEX_OUT) - { - if(handle->venc_set_config(configData, OMX_IndexConfigVideoBitrate) != true) - { - DEBUG_PRINT_ERROR("ERROR: Setting OMX_IndexConfigVideoBitrate failed"); - return OMX_ErrorUnsupportedSetting; - } - - m_sConfigBitrate.nEncodeBitrate = pParam->nEncodeBitrate; - m_sParamBitrate.nTargetBitrate = pParam->nEncodeBitrate; - m_sOutPortDef.format.video.nBitrate = pParam->nEncodeBitrate; - } - else - { - DEBUG_PRINT_ERROR("ERROR: Unsupported port index: %u", pParam->nPortIndex); - return OMX_ErrorBadPortIndex; - } - break; - } - case OMX_IndexConfigVideoFramerate: - { - OMX_CONFIG_FRAMERATETYPE* pParam = - reinterpret_cast(configData); - DEBUG_PRINT_LOW("\n omx_venc:: set_config(): OMX_IndexConfigVideoFramerate"); - - if(pParam->nPortIndex == PORT_INDEX_OUT) - { - if(handle->venc_set_config(configData, OMX_IndexConfigVideoFramerate) != true) - { - DEBUG_PRINT_ERROR("ERROR: Setting OMX_IndexConfigVideoFramerate failed"); - return OMX_ErrorUnsupportedSetting; - } - - m_sConfigFramerate.xEncodeFramerate = pParam->xEncodeFramerate; - m_sOutPortDef.format.video.xFramerate = pParam->xEncodeFramerate; - m_sOutPortFormat.xFramerate = pParam->xEncodeFramerate; - } - else - { - DEBUG_PRINT_ERROR("ERROR: Unsupported port index: %u", pParam->nPortIndex); - return OMX_ErrorBadPortIndex; - } - - break; - } - case QOMX_IndexConfigVideoIntraperiod: - { - QOMX_VIDEO_INTRAPERIODTYPE* pParam = - reinterpret_cast(configData); - - if(pParam->nPortIndex == PORT_INDEX_OUT) - { -#ifdef MAX_RES_720P - if(pParam->nBFrames > 0) - { - DEBUG_PRINT_ERROR("B frames not supported\n"); - return OMX_ErrorUnsupportedSetting; - } -#endif - if(handle->venc_set_config(configData, (OMX_INDEXTYPE) QOMX_IndexConfigVideoIntraperiod) != true) - { - DEBUG_PRINT_ERROR("ERROR: Setting QOMX_IndexConfigVideoIntraperiod failed"); - return OMX_ErrorUnsupportedSetting; - } - m_sIntraperiod.nPFrames = pParam->nPFrames; - m_sIntraperiod.nBFrames = pParam->nBFrames; - m_sIntraperiod.nIDRPeriod = pParam->nIDRPeriod; - - if(m_sOutPortFormat.eCompressionFormat == OMX_VIDEO_CodingMPEG4) - { - m_sParamMPEG4.nPFrames = pParam->nPFrames; - if(m_sParamMPEG4.eProfile != OMX_VIDEO_MPEG4ProfileSimple) - m_sParamMPEG4.nBFrames = pParam->nBFrames; - else - m_sParamMPEG4.nBFrames = 0; - } - else if(m_sOutPortFormat.eCompressionFormat == OMX_VIDEO_CodingH263) - { - m_sParamH263.nPFrames = pParam->nPFrames; - } - else - { - m_sParamAVC.nPFrames = pParam->nPFrames; - if(m_sParamAVC.eProfile != OMX_VIDEO_AVCProfileBaseline) - m_sParamAVC.nBFrames = pParam->nBFrames; - else - m_sParamAVC.nBFrames = 0; - } - } - else - { - DEBUG_PRINT_ERROR("ERROR: (QOMX_IndexConfigVideoIntraperiod) Unsupported port index: %u", pParam->nPortIndex); - return OMX_ErrorBadPortIndex; - } - - break; - } - - case OMX_IndexConfigVideoIntraVOPRefresh: - { - OMX_CONFIG_INTRAREFRESHVOPTYPE* pParam = - reinterpret_cast(configData); - - if(pParam->nPortIndex == PORT_INDEX_OUT) - { - if(handle->venc_set_config(configData, - OMX_IndexConfigVideoIntraVOPRefresh) != true) - { - DEBUG_PRINT_ERROR("ERROR: Setting OMX_IndexConfigVideoIntraVOPRefresh failed"); - return OMX_ErrorUnsupportedSetting; - } - - m_sConfigIntraRefreshVOP.IntraRefreshVOP = pParam->IntraRefreshVOP; - } - else - { - DEBUG_PRINT_ERROR("ERROR: Unsupported port index: %u", pParam->nPortIndex); - return OMX_ErrorBadPortIndex; - } - - break; - } - case OMX_IndexConfigCommonRotate: - { - OMX_CONFIG_ROTATIONTYPE *pParam = - reinterpret_cast(configData); - OMX_S32 nRotation; - - if(pParam->nPortIndex != PORT_INDEX_IN){ - DEBUG_PRINT_ERROR("ERROR: Unsupported port index: %u", pParam->nPortIndex); - return OMX_ErrorBadPortIndex; - } - if( pParam->nRotation == 0 || - pParam->nRotation == 90 || - pParam->nRotation == 180 || - pParam->nRotation == 270 ) { - DEBUG_PRINT_HIGH("\nset_config: Rotation Angle %u", pParam->nRotation); - } else { - DEBUG_PRINT_ERROR("ERROR: un supported Rotation %u", pParam->nRotation); - return OMX_ErrorUnsupportedSetting; - } - nRotation = pParam->nRotation - m_sConfigFrameRotation.nRotation; - if(nRotation < 0) - nRotation = -nRotation; - if(nRotation == 90 || nRotation == 270) { - DEBUG_PRINT_HIGH("\nset_config: updating device Dims"); - if(handle->venc_set_config(configData, - OMX_IndexConfigCommonRotate) != true) { - DEBUG_PRINT_ERROR("ERROR: Set OMX_IndexConfigCommonRotate failed"); - return OMX_ErrorUnsupportedSetting; - } else { - OMX_U32 nFrameWidth; - - DEBUG_PRINT_HIGH("\nset_config: updating port Dims"); - - nFrameWidth = m_sInPortDef.format.video.nFrameWidth; - m_sInPortDef.format.video.nFrameWidth = - m_sInPortDef.format.video.nFrameHeight; - m_sInPortDef.format.video.nFrameHeight = nFrameWidth; - - m_sOutPortDef.format.video.nFrameWidth = - m_sInPortDef.format.video.nFrameWidth; - m_sOutPortDef.format.video.nFrameHeight = - m_sInPortDef.format.video.nFrameHeight; - m_sConfigFrameRotation.nRotation = pParam->nRotation; - } - } else { - m_sConfigFrameRotation.nRotation = pParam->nRotation; - } - break; - } - case OMX_QcomIndexConfigVideoFramePackingArrangement: - { - if(m_sOutPortFormat.eCompressionFormat == OMX_VIDEO_CodingAVC) - { - OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt = - (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData; - extra_data_handle.set_frame_pack_data(configFmt); - } - else - { - DEBUG_PRINT_ERROR("ERROR: FramePackingData not supported for non AVC compression"); - } - break; - } - default: - DEBUG_PRINT_ERROR("ERROR: unsupported index %d", (int) configIndex); - break; - } - - return OMX_ErrorNone; -} - -/* ====================================================================== -FUNCTION - omx_venc::ComponentDeInit - -DESCRIPTION - Destroys the component and release memory allocated to the heap. - -PARAMETERS - . - -RETURN VALUE - OMX Error None if everything successful. - -========================================================================== */ -OMX_ERRORTYPE omx_venc::component_deinit(OMX_IN OMX_HANDLETYPE hComp) -{ - OMX_U32 i = 0; - DEBUG_PRINT_HIGH("\n omx_venc(): Inside component_deinit()"); - if(OMX_StateLoaded != m_state) - { - DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d\n",\ - m_state); - } - if(m_out_mem_ptr) - { - DEBUG_PRINT_LOW("Freeing the Output Memory\n"); - for(i=0; i< m_sOutPortDef.nBufferCountActual; i++ ) - { - free_output_buffer (&m_out_mem_ptr[i]); - } - free(m_out_mem_ptr); - m_out_mem_ptr = NULL; - } - - /*Check if the input buffers have to be cleaned up*/ - if(m_inp_mem_ptr -#ifdef _ANDROID_ICS_ - && !meta_mode_enable -#endif - ) - { - DEBUG_PRINT_LOW("Freeing the Input Memory\n"); - for(i=0; ivenc_close(); - DEBUG_PRINT_HIGH("Deleting HANDLE[%p]\n", handle); - delete (handle); - DEBUG_PRINT_HIGH("OMX_Venc:Component Deinit\n"); - return OMX_ErrorNone; -} - - -OMX_U32 omx_venc::dev_stop( void) -{ - return handle->venc_stop(); -} - - -OMX_U32 omx_venc::dev_pause(void) -{ - return handle->venc_pause(); -} - -OMX_U32 omx_venc::dev_start(void) -{ - return handle->venc_start(); -} - -OMX_U32 omx_venc::dev_flush(unsigned port) -{ - return handle->venc_flush(port); -} -OMX_U32 omx_venc::dev_resume(void) -{ - return handle->venc_resume(); -} - -OMX_U32 omx_venc::dev_start_done(void) -{ - return handle->venc_start_done(); -} - -OMX_U32 omx_venc::dev_stop_done(void) -{ - return handle->venc_stop_done(); -} - -bool omx_venc::dev_use_buf(void *buf_addr,unsigned port,unsigned index) -{ - return handle->venc_use_buf(buf_addr,port,index); -} - -bool omx_venc::dev_free_buf(void *buf_addr,unsigned port) -{ - return handle->venc_free_buf(buf_addr,port); -} - -bool omx_venc::dev_empty_buf(void *buffer, void *pmem_data_buf,unsigned index,unsigned fd) -{ - return handle->venc_empty_buf(buffer, pmem_data_buf,index,fd); -} - -bool omx_venc::dev_fill_buf(void *buffer, void *pmem_data_buf,unsigned index,unsigned fd) -{ - return handle->venc_fill_buf(buffer, pmem_data_buf,index,fd); -} - -bool omx_venc::dev_get_seq_hdr(void *buffer, unsigned size, unsigned *hdrlen) -{ - return handle->venc_get_seq_hdr(buffer, size, hdrlen); -} - -bool omx_venc::dev_loaded_start() -{ - return handle->venc_loaded_start(); -} - -bool omx_venc::dev_loaded_stop() -{ - return handle->venc_loaded_stop(); -} - -bool omx_venc::dev_loaded_start_done() -{ - return handle->venc_loaded_start_done(); -} - -bool omx_venc::dev_loaded_stop_done() -{ - return handle->venc_loaded_stop_done(); -} - -bool omx_venc::dev_get_buf_req(OMX_U32 *min_buff_count, - OMX_U32 *actual_buff_count, - OMX_U32 *buff_size, - OMX_U32 port) -{ - return handle->venc_get_buf_req(min_buff_count, - actual_buff_count, - buff_size, - port); - -} - -bool omx_venc::dev_set_buf_req(OMX_U32 *min_buff_count, - OMX_U32 *actual_buff_count, - OMX_U32 *buff_size, - OMX_U32 port) -{ - return handle->venc_set_buf_req(min_buff_count, - actual_buff_count, - buff_size, - port); - -} - -int omx_venc::async_message_process (void *context, void* message) -{ - omx_video* omx = NULL; - struct venc_msg *m_sVenc_msg = NULL; - OMX_BUFFERHEADERTYPE* omxhdr = NULL; - struct venc_buffer *temp_buff = NULL; - - if(context == NULL || message == NULL) - { - DEBUG_PRINT_ERROR("\nERROR: omx_venc::async_message_process invalid i/p params"); - return -1; - } - m_sVenc_msg = (struct venc_msg *)message; - - omx = reinterpret_cast(context); - - if(m_sVenc_msg->statuscode != VEN_S_SUCCESS) - { - DEBUG_PRINT_ERROR("\nERROR: async_msg_process() - Error statuscode = %d\n", - m_sVenc_msg->statuscode); - omx->omx_report_error(); - } - - DEBUG_PRINT_LOW("\n omx_venc::async_message_process- msgcode = %d\n", - m_sVenc_msg->msgcode); - switch(m_sVenc_msg->msgcode) - { - - case VEN_MSG_START: - omx->post_event (NULL,m_sVenc_msg->statuscode,\ - OMX_COMPONENT_GENERATE_START_DONE); - break; - - case VEN_MSG_STOP: - omx->post_event (NULL,m_sVenc_msg->statuscode,\ - OMX_COMPONENT_GENERATE_STOP_DONE); - break; - - case VEN_MSG_RESUME: - omx->post_event (NULL,m_sVenc_msg->statuscode,\ - OMX_COMPONENT_GENERATE_RESUME_DONE); - break; - - case VEN_MSG_PAUSE: - omx->post_event (NULL,m_sVenc_msg->statuscode,\ - OMX_COMPONENT_GENERATE_PAUSE_DONE); - - break; - - case VEN_MSG_FLUSH_INPUT_DONE: - - omx->post_event (NULL,m_sVenc_msg->statuscode,\ - OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH); - break; - case VEN_MSG_FLUSH_OUPUT_DONE: - omx->post_event (NULL,m_sVenc_msg->statuscode,\ - OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH); - break; - case VEN_MSG_INPUT_BUFFER_DONE: - omxhdr = (OMX_BUFFERHEADERTYPE* )\ - m_sVenc_msg->buf.clientdata; - - if(omxhdr == NULL || - ((OMX_U32)(omxhdr - omx->m_inp_mem_ptr) > omx->m_sInPortDef.nBufferCountActual) ) - { - omxhdr = NULL; - m_sVenc_msg->statuscode = VEN_S_EFAIL; - } -#ifdef _ANDROID_ICS_ - omx->omx_release_meta_buffer(omxhdr); -#endif - omx->post_event ((unsigned int)omxhdr,m_sVenc_msg->statuscode, - OMX_COMPONENT_GENERATE_EBD); - break; - case VEN_MSG_OUTPUT_BUFFER_DONE: - - omxhdr = (OMX_BUFFERHEADERTYPE*)m_sVenc_msg->buf.clientdata; - - if( (omxhdr != NULL) && - ((OMX_U32)(omxhdr - omx->m_out_mem_ptr) < omx->m_sOutPortDef.nBufferCountActual)) - { - if(m_sVenc_msg->buf.len <= omxhdr->nAllocLen) - { - omxhdr->nFilledLen = m_sVenc_msg->buf.len; - omxhdr->nOffset = m_sVenc_msg->buf.offset; - omxhdr->nTimeStamp = m_sVenc_msg->buf.timestamp; - DEBUG_PRINT_LOW("\n o/p TS = %u", (OMX_U32)m_sVenc_msg->buf.timestamp); - omxhdr->nFlags = m_sVenc_msg->buf.flags; - - /*Use buffer case*/ - if(omx->output_use_buffer && !omx->m_use_output_pmem) - { - DEBUG_PRINT_LOW("\n memcpy() for o/p Heap UseBuffer"); - memcpy(omxhdr->pBuffer, - (m_sVenc_msg->buf.ptrbuffer), - m_sVenc_msg->buf.len); - } - } - else - { - omxhdr->nFilledLen = 0; - } - - } - else - { - omxhdr = NULL; - m_sVenc_msg->statuscode = VEN_S_EFAIL; - } - - omx->post_event ((unsigned int)omxhdr,m_sVenc_msg->statuscode, - OMX_COMPONENT_GENERATE_FBD); - break; - case VEN_MSG_NEED_OUTPUT_BUFFER: - //TBD what action needs to be done here?? - break; - default: - break; - } - return 0; -} +/*-------------------------------------------------------------------------- +Copyright (c) 2010-2013, The 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. +--------------------------------------------------------------------------*/ +#include "omx_video_encoder.h" +#include +#include "video_encoder_device.h" +#include +#ifdef _ANDROID_ICS_ +#include +#endif +#ifdef _ANDROID_ +#include +#endif +#ifndef _ANDROID_ +#include +#define strlcpy g_strlcpy +#endif +/*---------------------------------------------------------------------------- +* Preprocessor Definitions and Constants +* -------------------------------------------------------------------------*/ + +#define OMX_SPEC_VERSION 0x00000101 +#define OMX_INIT_STRUCT(_s_, _name_) \ + memset((_s_), 0x0, sizeof(_name_)); \ + (_s_)->nSize = sizeof(_name_); \ + (_s_)->nVersion.nVersion = OMX_SPEC_VERSION + +extern int m_pipe; + +// factory function executed by the core to create instances +void *get_omx_component_factory_fn(void) +{ + return(new omx_venc); +} + +//constructor + +omx_venc::omx_venc() +{ +#ifdef _ANDROID_ICS_ + meta_mode_enable = false; + memset(meta_buffer_hdr,0,sizeof(meta_buffer_hdr)); + memset(meta_buffers,0,sizeof(meta_buffers)); + memset(opaque_buffer_hdr,0,sizeof(opaque_buffer_hdr)); + mUseProxyColorFormat = false; +#endif +} + +omx_venc::~omx_venc() +{ + //nothing to do +} + +/* ====================================================================== +FUNCTION + omx_venc::ComponentInit + +DESCRIPTION + Initialize the component. + +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. + +========================================================================== */ +OMX_ERRORTYPE omx_venc::component_init(OMX_STRING role) +{ + + OMX_ERRORTYPE eRet = OMX_ErrorNone; + + int fds[2]; + int r; + + OMX_VIDEO_CODINGTYPE codec_type; + + DEBUG_PRINT_HIGH("\n omx_venc(): Inside component_init()"); + // Copy the role information which provides the decoder m_nkind + strlcpy((char *)m_nkind,role,OMX_MAX_STRINGNAME_SIZE); + + if(!strncmp((char *)m_nkind,"OMX.qcom.video.encoder.mpeg4",\ + OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char *)m_cRole, "video_encoder.mpeg4",\ + OMX_MAX_STRINGNAME_SIZE); + codec_type = OMX_VIDEO_CodingMPEG4; + } + else if(!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.h263",\ + OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char *)m_cRole, "video_encoder.h263",OMX_MAX_STRINGNAME_SIZE); + codec_type = OMX_VIDEO_CodingH263; + } + else if(!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.avc",\ + OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char *)m_cRole, "video_encoder.avc",OMX_MAX_STRINGNAME_SIZE); + codec_type = OMX_VIDEO_CodingAVC; + } + else if(!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.avc.secure",\ + OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char *)m_cRole, "video_encoder.avc",OMX_MAX_STRINGNAME_SIZE); + codec_type = OMX_VIDEO_CodingAVC; + secure_session = true; + } + else + { + DEBUG_PRINT_ERROR("\nERROR: Unknown Component\n"); + eRet = OMX_ErrorInvalidComponentName; + } + + + if(eRet != OMX_ErrorNone) + { + return eRet; + } + + handle = new venc_dev(this); + + if(handle == NULL) + { + DEBUG_PRINT_ERROR("\nERROR: handle is NULL"); + return OMX_ErrorInsufficientResources; + } + + if(handle->venc_open(codec_type) != true) + { + DEBUG_PRINT_ERROR("\nERROR: venc_open failed"); + return OMX_ErrorInsufficientResources; + } + + //Getting current performance level + m_curr_perf = 0; + dev_get_curr_perf_lvl(&m_curr_perf); + + //Intialise the OMX layer variables + memset(&m_pCallbacks,0,sizeof(OMX_CALLBACKTYPE)); + + OMX_INIT_STRUCT(&m_sPortParam, OMX_PORT_PARAM_TYPE); + m_sPortParam.nPorts = 0x2; + m_sPortParam.nStartPortNumber = (OMX_U32) PORT_INDEX_IN; + + OMX_INIT_STRUCT(&m_sPortParam_audio, OMX_PORT_PARAM_TYPE); + m_sPortParam_audio.nPorts = 0; + m_sPortParam_audio.nStartPortNumber = 0; + + OMX_INIT_STRUCT(&m_sPortParam_img, OMX_PORT_PARAM_TYPE); + m_sPortParam_img.nPorts = 0; + m_sPortParam_img.nStartPortNumber = 0; + + OMX_INIT_STRUCT(&m_sParamBitrate, OMX_VIDEO_PARAM_BITRATETYPE); + m_sParamBitrate.nPortIndex = (OMX_U32) PORT_INDEX_OUT; + m_sParamBitrate.eControlRate = OMX_Video_ControlRateVariableSkipFrames; + m_sParamBitrate.nTargetBitrate = 64000; + + OMX_INIT_STRUCT(&m_sConfigBitrate, OMX_VIDEO_CONFIG_BITRATETYPE); + m_sConfigBitrate.nPortIndex = (OMX_U32) PORT_INDEX_OUT; + m_sConfigBitrate.nEncodeBitrate = 64000; + + OMX_INIT_STRUCT(&m_sConfigFramerate, OMX_CONFIG_FRAMERATETYPE); + m_sConfigFramerate.nPortIndex = (OMX_U32) PORT_INDEX_OUT; + m_sConfigFramerate.xEncodeFramerate = 30 << 16; + + OMX_INIT_STRUCT(&m_sConfigIntraRefreshVOP, OMX_CONFIG_INTRAREFRESHVOPTYPE); + m_sConfigIntraRefreshVOP.nPortIndex = (OMX_U32) PORT_INDEX_OUT; + m_sConfigIntraRefreshVOP.IntraRefreshVOP = OMX_FALSE; + + OMX_INIT_STRUCT(&m_sConfigFrameRotation, OMX_CONFIG_ROTATIONTYPE); + m_sConfigFrameRotation.nPortIndex = (OMX_U32) PORT_INDEX_IN; + m_sConfigFrameRotation.nRotation = 0; + + OMX_INIT_STRUCT(&m_sSessionQuantization, OMX_VIDEO_PARAM_QUANTIZATIONTYPE); + m_sSessionQuantization.nPortIndex = (OMX_U32) PORT_INDEX_OUT; + m_sSessionQuantization.nQpI = 9; + m_sSessionQuantization.nQpP = 6; + m_sSessionQuantization.nQpB = 2; + + OMX_INIT_STRUCT(&m_sSessionQPRange, OMX_QCOM_VIDEO_PARAM_QPRANGETYPE); + m_sSessionQPRange.nPortIndex = (OMX_U32) PORT_INDEX_OUT; + m_sSessionQPRange.minQP = 2; + if(codec_type == OMX_VIDEO_CodingAVC) + m_sSessionQPRange.maxQP = 51; + else + m_sSessionQPRange.maxQP = 31; + + OMX_INIT_STRUCT(&m_sAVCSliceFMO, OMX_VIDEO_PARAM_AVCSLICEFMO); + m_sAVCSliceFMO.nPortIndex = (OMX_U32) PORT_INDEX_OUT; + m_sAVCSliceFMO.eSliceMode = OMX_VIDEO_SLICEMODE_AVCDefault; + m_sAVCSliceFMO.nNumSliceGroups = 0; + m_sAVCSliceFMO.nSliceGroupMapType = 0; + OMX_INIT_STRUCT(&m_sParamProfileLevel, OMX_VIDEO_PARAM_PROFILELEVELTYPE); + m_sParamProfileLevel.nPortIndex = (OMX_U32) PORT_INDEX_OUT; + + OMX_INIT_STRUCT(&m_sIntraperiod, QOMX_VIDEO_INTRAPERIODTYPE); + m_sIntraperiod.nPortIndex = (OMX_U32) PORT_INDEX_OUT; + m_sIntraperiod.nPFrames = (m_sConfigFramerate.xEncodeFramerate * 2) - 1; + + OMX_INIT_STRUCT(&m_sErrorCorrection, OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE); + m_sErrorCorrection.nPortIndex = (OMX_U32) PORT_INDEX_OUT; + m_sErrorCorrection.bEnableDataPartitioning = OMX_FALSE; + m_sErrorCorrection.bEnableHEC = OMX_FALSE; + m_sErrorCorrection.bEnableResync = OMX_FALSE; + m_sErrorCorrection.bEnableRVLC = OMX_FALSE; + m_sErrorCorrection.nResynchMarkerSpacing = 0; + + OMX_INIT_STRUCT(&m_sIntraRefresh, OMX_VIDEO_PARAM_INTRAREFRESHTYPE); + m_sIntraRefresh.nPortIndex = (OMX_U32) PORT_INDEX_OUT; + m_sIntraRefresh.eRefreshMode = OMX_VIDEO_IntraRefreshMax; + + if(codec_type == OMX_VIDEO_CodingMPEG4) + { + m_sParamProfileLevel.eProfile = (OMX_U32) OMX_VIDEO_MPEG4ProfileSimple; + m_sParamProfileLevel.eLevel = (OMX_U32) OMX_VIDEO_MPEG4Level0; + } + else if(codec_type == OMX_VIDEO_CodingH263) + { + m_sParamProfileLevel.eProfile = (OMX_U32) OMX_VIDEO_H263ProfileBaseline; + m_sParamProfileLevel.eLevel = (OMX_U32) OMX_VIDEO_H263Level10; + } + else if(codec_type == OMX_VIDEO_CodingAVC) + { + m_sParamProfileLevel.eProfile = (OMX_U32) OMX_VIDEO_AVCProfileBaseline; + m_sParamProfileLevel.eLevel = (OMX_U32) OMX_VIDEO_AVCLevel1; + } + + OMX_INIT_STRUCT(&m_sPicureOrderCount, QOMX_PICTURE_ORDER_COUNT_TYPE); + if(codec_type == OMX_VIDEO_CodingAVC) + m_sPicureOrderCount.nType = 2; + + // Initialize the video parameters for input port + OMX_INIT_STRUCT(&m_sInPortDef, OMX_PARAM_PORTDEFINITIONTYPE); + m_sInPortDef.nPortIndex= (OMX_U32) PORT_INDEX_IN; + m_sInPortDef.bEnabled = OMX_TRUE; + m_sInPortDef.bPopulated = OMX_FALSE; + m_sInPortDef.eDomain = OMX_PortDomainVideo; + m_sInPortDef.eDir = OMX_DirInput; + m_sInPortDef.format.video.cMIMEType = "YUV420"; + m_sInPortDef.format.video.nFrameWidth = OMX_CORE_QCIF_WIDTH; + m_sInPortDef.format.video.nFrameHeight = OMX_CORE_QCIF_HEIGHT; + m_sInPortDef.format.video.nStride = OMX_CORE_QCIF_WIDTH; + m_sInPortDef.format.video.nSliceHeight = OMX_CORE_QCIF_HEIGHT; + m_sInPortDef.format.video.nBitrate = 64000; + m_sInPortDef.format.video.xFramerate = 15 << 16; + m_sInPortDef.format.video.eColorFormat = (OMX_COLOR_FORMATTYPE) + QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m; + m_sInPortDef.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; + + if(dev_get_buf_req(&m_sInPortDef.nBufferCountMin, + &m_sInPortDef.nBufferCountActual, + &m_sInPortDef.nBufferSize, + m_sInPortDef.nPortIndex) != true) + { + eRet = OMX_ErrorUndefined; + + } + + // Initialize the video parameters for output port + OMX_INIT_STRUCT(&m_sOutPortDef, OMX_PARAM_PORTDEFINITIONTYPE); + m_sOutPortDef.nPortIndex = (OMX_U32) PORT_INDEX_OUT; + m_sOutPortDef.bEnabled = OMX_TRUE; + m_sOutPortDef.bPopulated = OMX_FALSE; + m_sOutPortDef.eDomain = OMX_PortDomainVideo; + m_sOutPortDef.eDir = OMX_DirOutput; + m_sOutPortDef.format.video.nFrameWidth = OMX_CORE_QCIF_WIDTH; + m_sOutPortDef.format.video.nFrameHeight = OMX_CORE_QCIF_HEIGHT; + m_sOutPortDef.format.video.nBitrate = 64000; + m_sOutPortDef.format.video.xFramerate = 15 << 16; + m_sOutPortDef.format.video.eColorFormat = OMX_COLOR_FormatUnused; + if(codec_type == OMX_VIDEO_CodingMPEG4) + { + m_sOutPortDef.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4; + } + else if(codec_type == OMX_VIDEO_CodingH263) + { + m_sOutPortDef.format.video.eCompressionFormat = OMX_VIDEO_CodingH263; + } + else + { + m_sOutPortDef.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC; + } + if(dev_get_buf_req(&m_sOutPortDef.nBufferCountMin, + &m_sOutPortDef.nBufferCountActual, + &m_sOutPortDef.nBufferSize, + m_sOutPortDef.nPortIndex) != true) + { + eRet = OMX_ErrorUndefined; + } + + // Initialize the video color format for input port + OMX_INIT_STRUCT(&m_sInPortFormat, OMX_VIDEO_PARAM_PORTFORMATTYPE); + m_sInPortFormat.nPortIndex = (OMX_U32) PORT_INDEX_IN; + m_sInPortFormat.nIndex = 0; + m_sInPortFormat.eColorFormat = (OMX_COLOR_FORMATTYPE) + QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m; + m_sInPortFormat.eCompressionFormat = OMX_VIDEO_CodingUnused; + + + // Initialize the compression format for output port + OMX_INIT_STRUCT(&m_sOutPortFormat, OMX_VIDEO_PARAM_PORTFORMATTYPE); + m_sOutPortFormat.nPortIndex = (OMX_U32) PORT_INDEX_OUT; + m_sOutPortFormat.nIndex = 0; + m_sOutPortFormat.eColorFormat = OMX_COLOR_FormatUnused; + if(codec_type == OMX_VIDEO_CodingMPEG4) + { + m_sOutPortFormat.eCompressionFormat = OMX_VIDEO_CodingMPEG4; + } + else if(codec_type == OMX_VIDEO_CodingH263) + { + m_sOutPortFormat.eCompressionFormat = OMX_VIDEO_CodingH263; + } + else + { + m_sOutPortFormat.eCompressionFormat = OMX_VIDEO_CodingAVC; + } + + // mandatory Indices for kronos test suite + OMX_INIT_STRUCT(&m_sPriorityMgmt, OMX_PRIORITYMGMTTYPE); + + OMX_INIT_STRUCT(&m_sInBufSupplier, OMX_PARAM_BUFFERSUPPLIERTYPE); + m_sInBufSupplier.nPortIndex = (OMX_U32) PORT_INDEX_IN; + + OMX_INIT_STRUCT(&m_sOutBufSupplier, OMX_PARAM_BUFFERSUPPLIERTYPE); + m_sOutBufSupplier.nPortIndex = (OMX_U32) PORT_INDEX_OUT; + + + // mp4 specific init + OMX_INIT_STRUCT(&m_sParamMPEG4, OMX_VIDEO_PARAM_MPEG4TYPE); + m_sParamMPEG4.nPortIndex = (OMX_U32) PORT_INDEX_OUT; + m_sParamMPEG4.eProfile = OMX_VIDEO_MPEG4ProfileSimple; + m_sParamMPEG4.eLevel = OMX_VIDEO_MPEG4Level0; + m_sParamMPEG4.nSliceHeaderSpacing = 0; + m_sParamMPEG4.bSVH = OMX_FALSE; + m_sParamMPEG4.bGov = OMX_FALSE; + m_sParamMPEG4.nPFrames = (m_sOutPortFormat.xFramerate * 2 - 1); // 2 second intra period for default outport fps + m_sParamMPEG4.bACPred = OMX_TRUE; + m_sParamMPEG4.nTimeIncRes = 30; // delta = 2 @ 15 fps + m_sParamMPEG4.nAllowedPictureTypes = 2; // pframe and iframe + m_sParamMPEG4.nHeaderExtension = 1; // number of video packet headers per vop + m_sParamMPEG4.bReversibleVLC = OMX_FALSE; + + // h263 specific init + OMX_INIT_STRUCT(&m_sParamH263, OMX_VIDEO_PARAM_H263TYPE); + m_sParamH263.nPortIndex = (OMX_U32) PORT_INDEX_OUT; + m_sParamH263.nPFrames = (m_sOutPortFormat.xFramerate * 2 - 1); // 2 second intra period for default outport fps + m_sParamH263.nBFrames = 0; + m_sParamH263.eProfile = OMX_VIDEO_H263ProfileBaseline; + m_sParamH263.eLevel = OMX_VIDEO_H263Level10; + m_sParamH263.bPLUSPTYPEAllowed = OMX_FALSE; + m_sParamH263.nAllowedPictureTypes = 2; + m_sParamH263.bForceRoundingTypeToZero = OMX_TRUE; + m_sParamH263.nPictureHeaderRepetition = 0; + m_sParamH263.nGOBHeaderInterval = 1; + + // h264 specific init + OMX_INIT_STRUCT(&m_sParamAVC, OMX_VIDEO_PARAM_AVCTYPE); + m_sParamAVC.nPortIndex = (OMX_U32) PORT_INDEX_OUT; + m_sParamAVC.nSliceHeaderSpacing = 0; + m_sParamAVC.nPFrames = (m_sOutPortFormat.xFramerate * 2 - 1); // 2 second intra period for default outport fps + m_sParamAVC.nBFrames = 0; + m_sParamAVC.bUseHadamard = OMX_FALSE; + m_sParamAVC.nRefFrames = 1; + m_sParamAVC.nRefIdx10ActiveMinus1 = 1; + m_sParamAVC.nRefIdx11ActiveMinus1 = 0; + m_sParamAVC.bEnableUEP = OMX_FALSE; + m_sParamAVC.bEnableFMO = OMX_FALSE; + m_sParamAVC.bEnableASO = OMX_FALSE; + m_sParamAVC.bEnableRS = OMX_FALSE; + m_sParamAVC.eProfile = OMX_VIDEO_AVCProfileBaseline; + m_sParamAVC.eLevel = OMX_VIDEO_AVCLevel1; + m_sParamAVC.nAllowedPictureTypes = 2; + m_sParamAVC.bFrameMBsOnly = OMX_FALSE; + m_sParamAVC.bMBAFF = OMX_FALSE; + m_sParamAVC.bEntropyCodingCABAC = OMX_FALSE; + m_sParamAVC.bWeightedPPrediction = OMX_FALSE; + m_sParamAVC.nWeightedBipredicitonMode = 0; + m_sParamAVC.bconstIpred = OMX_FALSE; + m_sParamAVC.bDirect8x8Inference = OMX_FALSE; + m_sParamAVC.bDirectSpatialTemporal = OMX_FALSE; + m_sParamAVC.nCabacInitIdc = 0; + m_sParamAVC.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable; + + m_state = OMX_StateLoaded; + m_sExtraData = 0; + + if(eRet == OMX_ErrorNone) + { + if(pipe(fds)) + { + DEBUG_PRINT_ERROR("ERROR: pipe creation failed\n"); + eRet = OMX_ErrorInsufficientResources; + } + else + { + if(fds[0] == 0 || fds[1] == 0) + { + if(pipe(fds)) + { + DEBUG_PRINT_ERROR("ERROR: pipe creation failed\n"); + eRet = OMX_ErrorInsufficientResources; + } + } + if(eRet == OMX_ErrorNone) + { + m_pipe_in = fds[0]; + m_pipe_out = fds[1]; + } + } + r = pthread_create(&msg_thread_id,0,message_thread,this); + + if(r < 0) + { + eRet = OMX_ErrorInsufficientResources; + } + else + { + r = pthread_create(&async_thread_id,0,async_venc_message_thread,this); + if(r < 0) + { + eRet = OMX_ErrorInsufficientResources; + } + } + } + DEBUG_PRINT_HIGH("\n Component_init return value = 0x%x", eRet); + return eRet; +} + + +/* ====================================================================== +FUNCTION + omx_venc::Setparameter + +DESCRIPTION + OMX Set Parameter method implementation. + +PARAMETERS + . + +RETURN VALUE + OMX Error None if successful. + +========================================================================== */ +OMX_ERRORTYPE omx_venc::set_parameter(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_INDEXTYPE paramIndex, + OMX_IN OMX_PTR paramData) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + + + if(m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("ERROR: Set Param in Invalid State\n"); + return OMX_ErrorInvalidState; + } + if(paramData == NULL) + { + DEBUG_PRINT_ERROR("ERROR: Get Param in Invalid paramData \n"); + return OMX_ErrorBadParameter; + } + + /*set_parameter can be called in loaded state + or disabled port */ + if(m_state == OMX_StateLoaded + || m_sInPortDef.bEnabled == OMX_FALSE + || m_sOutPortDef.bEnabled == OMX_FALSE) + { + DEBUG_PRINT_LOW("Set Parameter called in valid state"); + } + else + { + DEBUG_PRINT_ERROR("ERROR: Set Parameter called in Invalid State\n"); + return OMX_ErrorIncorrectStateOperation; + } + + switch(paramIndex) + { + case OMX_IndexParamPortDefinition: + { + OMX_PARAM_PORTDEFINITIONTYPE *portDefn; + portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData; + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d\n", + (int)portDefn->format.video.nFrameHeight, + (int)portDefn->format.video.nFrameWidth); + + if(PORT_INDEX_IN == portDefn->nPortIndex) + { + DEBUG_PRINT_LOW("\n i/p actual cnt requested = %d\n", portDefn->nBufferCountActual); + DEBUG_PRINT_LOW("\n i/p min cnt requested = %d\n", portDefn->nBufferCountMin); + DEBUG_PRINT_LOW("\n i/p buffersize requested = %d\n", portDefn->nBufferSize); + if(handle->venc_set_param(paramData,OMX_IndexParamPortDefinition) != true) + { + DEBUG_PRINT_ERROR("\nERROR: venc_set_param input failed"); + return OMX_ErrorUnsupportedSetting; + } + + DEBUG_PRINT_LOW("\n i/p previous actual cnt = %d\n", m_sInPortDef.nBufferCountActual); + DEBUG_PRINT_LOW("\n i/p previous min cnt = %d\n", m_sInPortDef.nBufferCountMin); + memcpy(&m_sInPortDef, portDefn,sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); + +#ifdef _ANDROID_ICS_ + if (portDefn->format.video.eColorFormat == (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FormatAndroidOpaque) { + m_sInPortDef.format.video.eColorFormat = (OMX_COLOR_FORMATTYPE) + QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m; + if(secure_session) { + secure_color_format = (int) QOMX_COLOR_FormatAndroidOpaque; + mUseProxyColorFormat = false; + m_input_msg_id = OMX_COMPONENT_GENERATE_ETB; + } else if(!mUseProxyColorFormat){ + if (!c2d_conv.init()) { + DEBUG_PRINT_ERROR("\n C2D init failed"); + return OMX_ErrorUnsupportedSetting; + } + DEBUG_PRINT_ERROR("\nC2D init is successful"); + mUseProxyColorFormat = true; + m_input_msg_id = OMX_COMPONENT_GENERATE_ETB_OPQ; + } + } else + mUseProxyColorFormat = false; +#endif + /*Query Input Buffer Requirements*/ + dev_get_buf_req (&m_sInPortDef.nBufferCountMin, + &m_sInPortDef.nBufferCountActual, + &m_sInPortDef.nBufferSize, + m_sInPortDef.nPortIndex); + + /*Query ouput Buffer Requirements*/ + dev_get_buf_req (&m_sOutPortDef.nBufferCountMin, + &m_sOutPortDef.nBufferCountActual, + &m_sOutPortDef.nBufferSize, + m_sOutPortDef.nPortIndex); + m_sInPortDef.nBufferCountActual = portDefn->nBufferCountActual; + } + else if(PORT_INDEX_OUT == portDefn->nPortIndex) + { + DEBUG_PRINT_LOW("\n o/p actual cnt requested = %d\n", portDefn->nBufferCountActual); + DEBUG_PRINT_LOW("\n o/p min cnt requested = %d\n", portDefn->nBufferCountMin); + DEBUG_PRINT_LOW("\n o/p buffersize requested = %d\n", portDefn->nBufferSize); + if(handle->venc_set_param(paramData,OMX_IndexParamPortDefinition) != true) + { + DEBUG_PRINT_ERROR("\nERROR: venc_set_param output failed"); + return OMX_ErrorUnsupportedSetting; + } + memcpy(&m_sOutPortDef,portDefn,sizeof(struct OMX_PARAM_PORTDEFINITIONTYPE)); + update_profile_level(); //framerate , bitrate + + DEBUG_PRINT_LOW("\n o/p previous actual cnt = %d\n", m_sOutPortDef.nBufferCountActual); + DEBUG_PRINT_LOW("\n o/p previous min cnt = %d\n", m_sOutPortDef.nBufferCountMin); + m_sOutPortDef.nBufferCountActual = portDefn->nBufferCountActual; + } + else + { + DEBUG_PRINT_ERROR("ERROR: Set_parameter: Bad Port idx %d", + (int)portDefn->nPortIndex); + eRet = OMX_ErrorBadPortIndex; + } + m_sConfigFramerate.xEncodeFramerate = portDefn->format.video.xFramerate; + m_sConfigBitrate.nEncodeBitrate = portDefn->format.video.nBitrate; + m_sParamBitrate.nTargetBitrate = portDefn->format.video.nBitrate; + } + break; + + case OMX_IndexParamVideoPortFormat: + { + OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt = + (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData; + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d\n", + portFmt->eColorFormat); + //set the driver with the corresponding values + if(PORT_INDEX_IN == portFmt->nPortIndex) + { + if(handle->venc_set_param(paramData,OMX_IndexParamVideoPortFormat) != true) + { + return OMX_ErrorUnsupportedSetting; + } + + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d\n", + portFmt->eColorFormat); + update_profile_level(); //framerate + +#ifdef _ANDROID_ICS_ + if (portFmt->eColorFormat == + (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FormatAndroidOpaque) { + m_sInPortFormat.eColorFormat = (OMX_COLOR_FORMATTYPE) + QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m; + if(secure_session) { + secure_color_format = (int) QOMX_COLOR_FormatAndroidOpaque; + mUseProxyColorFormat = false; + m_input_msg_id = OMX_COMPONENT_GENERATE_ETB; + } else if(!mUseProxyColorFormat){ + if (!c2d_conv.init()) { + DEBUG_PRINT_ERROR("\n C2D init failed"); + return OMX_ErrorUnsupportedSetting; + } + DEBUG_PRINT_ERROR("\nC2D init is successful"); + mUseProxyColorFormat = true; + m_input_msg_id = OMX_COMPONENT_GENERATE_ETB_OPQ; + } + } + else +#endif + { + m_sInPortFormat.eColorFormat = portFmt->eColorFormat; + m_input_msg_id = OMX_COMPONENT_GENERATE_ETB; + mUseProxyColorFormat = false; + } + m_sInPortFormat.xFramerate = portFmt->xFramerate; + } + //TODO if no use case for O/P port,delet m_sOutPortFormat + } + break; + case OMX_IndexParamVideoInit: + { //TODO, do we need this index set param + OMX_PORT_PARAM_TYPE* pParam = (OMX_PORT_PARAM_TYPE*)(paramData); + DEBUG_PRINT_LOW("\n Set OMX_IndexParamVideoInit called"); + break; + } + + case OMX_IndexParamVideoBitrate: + { + OMX_VIDEO_PARAM_BITRATETYPE* pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData; + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoBitrate"); + if(handle->venc_set_param(paramData,OMX_IndexParamVideoBitrate) != true) + { + return OMX_ErrorUnsupportedSetting; + } + m_sParamBitrate.nTargetBitrate = pParam->nTargetBitrate; + m_sParamBitrate.eControlRate = pParam->eControlRate; + update_profile_level(); //bitrate + m_sConfigBitrate.nEncodeBitrate = pParam->nTargetBitrate; + m_sInPortDef.format.video.nBitrate = pParam->nTargetBitrate; + m_sOutPortDef.format.video.nBitrate = pParam->nTargetBitrate; + DEBUG_PRINT_LOW("\nbitrate = %u", m_sOutPortDef.format.video.nBitrate); + break; + } + case OMX_IndexParamVideoMpeg4: + { + OMX_VIDEO_PARAM_MPEG4TYPE* pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData; + OMX_VIDEO_PARAM_MPEG4TYPE mp4_param; + memcpy(&mp4_param, pParam, sizeof(struct OMX_VIDEO_PARAM_MPEG4TYPE)); + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4"); + if(pParam->eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) + { +#ifdef MAX_RES_1080P + if(pParam->nBFrames) + { + DEBUG_PRINT_HIGH("INFO: Only 1 Bframe is supported"); + mp4_param.nBFrames = 1; + } +#else + if(pParam->nBFrames) + { + DEBUG_PRINT_ERROR("Warning: B frames not supported\n"); + mp4_param.nBFrames = 0; + } +#endif + } + else + { + if(pParam->nBFrames) + { + DEBUG_PRINT_ERROR("Warning: B frames not supported\n"); + mp4_param.nBFrames = 0; + } + } + if(handle->venc_set_param(&mp4_param,OMX_IndexParamVideoMpeg4) != true) + { + return OMX_ErrorUnsupportedSetting; + } + memcpy(&m_sParamMPEG4,pParam, sizeof(struct OMX_VIDEO_PARAM_MPEG4TYPE)); + m_sIntraperiod.nPFrames = m_sParamMPEG4.nPFrames; + m_sIntraperiod.nBFrames = m_sParamMPEG4.nBFrames; + break; + } + case OMX_IndexParamVideoH263: + { + OMX_VIDEO_PARAM_H263TYPE* pParam = (OMX_VIDEO_PARAM_H263TYPE*)paramData; + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263"); + if(handle->venc_set_param(paramData,OMX_IndexParamVideoH263) != true) + { + return OMX_ErrorUnsupportedSetting; + } + memcpy(&m_sParamH263,pParam, sizeof(struct OMX_VIDEO_PARAM_H263TYPE)); + m_sIntraperiod.nPFrames = m_sParamH263.nPFrames; + m_sIntraperiod.nBFrames = m_sParamH263.nBFrames; + break; + } + case OMX_IndexParamVideoAvc: + { + OMX_VIDEO_PARAM_AVCTYPE* pParam = (OMX_VIDEO_PARAM_AVCTYPE*)paramData; + OMX_VIDEO_PARAM_AVCTYPE avc_param; + memcpy(&avc_param, pParam, sizeof( struct OMX_VIDEO_PARAM_AVCTYPE)); + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc"); + + if((pParam->eProfile == OMX_VIDEO_AVCProfileHigh)|| + (pParam->eProfile == OMX_VIDEO_AVCProfileMain)) + { +#ifdef MAX_RES_1080P + if(pParam->nBFrames) + { + DEBUG_PRINT_HIGH("INFO: Only 1 Bframe is supported"); + avc_param.nBFrames = 1; + } + if(pParam->nRefFrames != 2) + { + DEBUG_PRINT_ERROR("Warning: 2 RefFrames are needed, changing RefFrames from %d to 2", pParam->nRefFrames); + avc_param.nRefFrames = 2; + } +#else + if(pParam->nBFrames) + { + DEBUG_PRINT_ERROR("Warning: B frames not supported\n"); + avc_param.nBFrames = 0; + } + if(pParam->nRefFrames != 1) + { + DEBUG_PRINT_ERROR("Warning: Only 1 RefFrame is supported, changing RefFrame from %d to 1)", pParam->nRefFrames); + avc_param.nRefFrames = 1; + } +#endif + } + else + { + if(pParam->nRefFrames != 1) + { + DEBUG_PRINT_ERROR("Warning: Only 1 RefFrame is supported, changing RefFrame from %d to 1)", pParam->nRefFrames); + avc_param.nRefFrames = 1; + } + if(pParam->nBFrames) + { + DEBUG_PRINT_ERROR("Warning: B frames not supported\n"); + avc_param.nBFrames = 0; + } + +#ifdef MAX_RES_1080P + // These settings are geared toward the WFD usecase + if (pParam->eProfile == OMX_VIDEO_AVCProfileBaseline) + { + //set the BITSTREAM_RESTRICT flag in the vui + QOMX_VUI_BITSTREAM_RESTRICT br; + OMX_INIT_STRUCT(&br, QOMX_VUI_BITSTREAM_RESTRICT); + br.bEnable = OMX_TRUE; + if (!handle->venc_set_param((OMX_PTR)&br, + (OMX_INDEXTYPE)OMX_QcomIndexParamEnableVUIStreamRestrictFlag)) { + DEBUG_PRINT_ERROR("Unable to set EnableVUIStreamRestrictFlag as default"); + return OMX_ErrorHardware; + } + } + if (m_sOutPortFormat.eCompressionFormat == OMX_VIDEO_CodingAVC) + { + //set the PIC_ORDER_CNT_TYPE flag in the sps + if (!handle->venc_set_param((OMX_PTR)&m_sPicureOrderCount, + (OMX_INDEXTYPE)OMX_QcomIndexParamPictureOrderCountType)) { + DEBUG_PRINT_ERROR("Unable to set PictureOrderCountType as default"); + return OMX_ErrorHardware; + } + } +#endif + } + + if(handle->venc_set_param(&avc_param,OMX_IndexParamVideoAvc) != true) + { + return OMX_ErrorUnsupportedSetting; + } + + memcpy(&m_sParamAVC,pParam, sizeof(struct OMX_VIDEO_PARAM_AVCTYPE)); + m_sIntraperiod.nPFrames = m_sParamAVC.nPFrames; + m_sIntraperiod.nBFrames = m_sParamAVC.nBFrames; + break; + } + case OMX_IndexParamVideoProfileLevelCurrent: + { + OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData; + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoProfileLevelCurrent"); + if(handle->venc_set_param(pParam,OMX_IndexParamVideoProfileLevelCurrent) != true) + { + DEBUG_PRINT_ERROR("set_parameter: OMX_IndexParamVideoProfileLevelCurrent failed for Profile: %d " + "Level :%d", pParam->eProfile, pParam->eLevel); + return OMX_ErrorUnsupportedSetting; + } + m_sParamProfileLevel.eProfile = pParam->eProfile; + m_sParamProfileLevel.eLevel = pParam->eLevel; + + if(!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.mpeg4",\ + OMX_MAX_STRINGNAME_SIZE)) + { + m_sParamMPEG4.eProfile = (OMX_VIDEO_MPEG4PROFILETYPE)m_sParamProfileLevel.eProfile; + m_sParamMPEG4.eLevel = (OMX_VIDEO_MPEG4LEVELTYPE)m_sParamProfileLevel.eLevel; + DEBUG_PRINT_LOW("\n MPEG4 profile = %d, level = %d", m_sParamMPEG4.eProfile, + m_sParamMPEG4.eLevel); + } + else if(!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.h263",\ + OMX_MAX_STRINGNAME_SIZE)) + { + m_sParamH263.eProfile = (OMX_VIDEO_H263PROFILETYPE)m_sParamProfileLevel.eProfile; + m_sParamH263.eLevel = (OMX_VIDEO_H263LEVELTYPE)m_sParamProfileLevel.eLevel; + DEBUG_PRINT_LOW("\n H263 profile = %d, level = %d", m_sParamH263.eProfile, + m_sParamH263.eLevel); + } + else if(!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.avc",\ + OMX_MAX_STRINGNAME_SIZE)) + { + m_sParamAVC.eProfile = (OMX_VIDEO_AVCPROFILETYPE)m_sParamProfileLevel.eProfile; + m_sParamAVC.eLevel = (OMX_VIDEO_AVCLEVELTYPE)m_sParamProfileLevel.eLevel; + DEBUG_PRINT_LOW("\n AVC profile = %d, level = %d", m_sParamAVC.eProfile, + m_sParamAVC.eLevel); + } + break; + } + case OMX_IndexParamStandardComponentRole: + { + OMX_PARAM_COMPONENTROLETYPE *comp_role; + comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData; + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s\n", + comp_role->cRole); + + if((m_state == OMX_StateLoaded)&& + !BITMASK_PRESENT_U32(m_flags,OMX_COMPONENT_IDLE_PENDING)) + { + DEBUG_PRINT_LOW("Set Parameter called in valid state"); + } + else + { + DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n"); + return OMX_ErrorIncorrectStateOperation; + } + + if(!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.avc",OMX_MAX_STRINGNAME_SIZE)) + { + if(!strncmp((char*)comp_role->cRole,"video_encoder.avc",OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char*)m_cRole,"video_encoder.avc",OMX_MAX_STRINGNAME_SIZE); + } + else + { + DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown Index %s\n", comp_role->cRole); + eRet =OMX_ErrorUnsupportedSetting; + } + } + else if(!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) + { + if(!strncmp((const char*)comp_role->cRole,"video_encoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char*)m_cRole,"video_encoder.mpeg4",OMX_MAX_STRINGNAME_SIZE); + } + else + { + DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown Index %s\n", comp_role->cRole); + eRet = OMX_ErrorUnsupportedSetting; + } + } + else if(!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.h263",OMX_MAX_STRINGNAME_SIZE)) + { + if(!strncmp((const char*)comp_role->cRole,"video_encoder.h263",OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char*)m_cRole,"video_encoder.h263",OMX_MAX_STRINGNAME_SIZE); + } + else + { + DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown Index %s\n", comp_role->cRole); + eRet =OMX_ErrorUnsupportedSetting; + } + } + else + { + DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown param %s\n", m_nkind); + eRet = OMX_ErrorInvalidComponentName; + } + break; + } + + case OMX_IndexParamPriorityMgmt: + { + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt"); + if(m_state != OMX_StateLoaded) + { + DEBUG_PRINT_ERROR("ERROR: Set Parameter called in Invalid State\n"); + return OMX_ErrorIncorrectStateOperation; + } + OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData; + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %d\n", + priorityMgmtype->nGroupID); + + DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %d\n", + priorityMgmtype->nGroupPriority); + + m_sPriorityMgmt.nGroupID = priorityMgmtype->nGroupID; + m_sPriorityMgmt.nGroupPriority = priorityMgmtype->nGroupPriority; + + break; + } + + case OMX_IndexParamCompBufferSupplier: + { + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier"); + OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData; + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d\n", + bufferSupplierType->eBufferSupplier); + if(bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1) + m_sInBufSupplier.eBufferSupplier = bufferSupplierType->eBufferSupplier; + + else + + eRet = OMX_ErrorBadPortIndex; + + break; + + } + case OMX_IndexParamVideoQuantization: + { + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoQuantization\n"); + OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp = (OMX_VIDEO_PARAM_QUANTIZATIONTYPE*) paramData; + if(session_qp->nPortIndex == PORT_INDEX_OUT) + { + if(handle->venc_set_param(paramData, OMX_IndexParamVideoQuantization) != true) + { + return OMX_ErrorUnsupportedSetting; + } + m_sSessionQuantization.nQpI = session_qp->nQpI; + m_sSessionQuantization.nQpP = session_qp->nQpP; + } + else + { + DEBUG_PRINT_ERROR("\nERROR: Unsupported port Index for Session QP setting\n"); + eRet = OMX_ErrorBadPortIndex; + } + break; + } + + case OMX_QcomIndexParamVideoQPRange: + { + DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoQPRange\n"); + OMX_QCOM_VIDEO_PARAM_QPRANGETYPE *qp_range = (OMX_QCOM_VIDEO_PARAM_QPRANGETYPE*) paramData; + if(qp_range->nPortIndex == PORT_INDEX_OUT) + { + if(handle->venc_set_param(paramData, + (OMX_INDEXTYPE)OMX_QcomIndexParamVideoQPRange) != true) + { + return OMX_ErrorUnsupportedSetting; + } + m_sSessionQPRange.minQP= qp_range->minQP; + m_sSessionQPRange.maxQP= qp_range->maxQP; + } + else + { + DEBUG_PRINT_ERROR("\nERROR: Unsupported port Index for QP range setting\n"); + eRet = OMX_ErrorBadPortIndex; + } + break; + } + + case OMX_QcomIndexPortDefn: + { + OMX_QCOM_PARAM_PORTDEFINITIONTYPE* pParam = + (OMX_QCOM_PARAM_PORTDEFINITIONTYPE*)paramData; + DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexPortDefn"); + if(pParam->nPortIndex == (OMX_U32)PORT_INDEX_IN) + { + if(pParam->nMemRegion > OMX_QCOM_MemRegionInvalid && + pParam->nMemRegion < OMX_QCOM_MemRegionMax) + { + m_use_input_pmem = OMX_TRUE; + } + else + { + m_use_input_pmem = OMX_FALSE; + } + } + else if (pParam->nPortIndex == (OMX_U32)PORT_INDEX_OUT) + { + if(pParam->nMemRegion > OMX_QCOM_MemRegionInvalid && + pParam->nMemRegion < OMX_QCOM_MemRegionMax) + { + m_use_output_pmem = OMX_TRUE; + } + else + { + m_use_output_pmem = OMX_FALSE; + } + } + else + { + DEBUG_PRINT_ERROR("ERROR: SetParameter called on unsupported Port Index for QcomPortDefn"); + return OMX_ErrorBadPortIndex; + } + break; + } + + case OMX_IndexParamVideoErrorCorrection: + { + DEBUG_PRINT_LOW("OMX_IndexParamVideoErrorCorrection\n"); + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* pParam = + (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE*)paramData; + if(!handle->venc_set_param(paramData, OMX_IndexParamVideoErrorCorrection)) + { + DEBUG_PRINT_ERROR("\nERROR: Request for setting Error Resilience failed"); + return OMX_ErrorUnsupportedSetting; + } + memcpy(&m_sErrorCorrection,pParam, sizeof(m_sErrorCorrection)); + break; + } + case OMX_IndexParamVideoIntraRefresh: + { + DEBUG_PRINT_LOW("set_param:OMX_IndexParamVideoIntraRefresh\n"); + OMX_VIDEO_PARAM_INTRAREFRESHTYPE* pParam = + (OMX_VIDEO_PARAM_INTRAREFRESHTYPE*)paramData; + if(!handle->venc_set_param(paramData,OMX_IndexParamVideoIntraRefresh)) + { + DEBUG_PRINT_ERROR("\nERROR: Request for setting intra refresh failed"); + return OMX_ErrorUnsupportedSetting; + } + memcpy(&m_sIntraRefresh, pParam, sizeof(m_sIntraRefresh)); + break; + } +#ifdef _ANDROID_ICS_ + case OMX_QcomIndexParamVideoEncodeMetaBufferMode: + { + StoreMetaDataInBuffersParams *pParam = + (StoreMetaDataInBuffersParams*)paramData; + if(pParam->nPortIndex == PORT_INDEX_IN) + { + if(pParam->bStoreMetaData != meta_mode_enable) + { + if(!handle->venc_set_meta_mode(pParam->bStoreMetaData)) + { + DEBUG_PRINT_ERROR("\nERROR: set Metabuffer mode %d fail", + pParam->bStoreMetaData); + return OMX_ErrorUnsupportedSetting; + } + meta_mode_enable = pParam->bStoreMetaData; + if(meta_mode_enable) { + m_sInPortDef.nBufferCountActual = 4; + if(handle->venc_set_param(&m_sInPortDef,OMX_IndexParamPortDefinition) != true) + { + DEBUG_PRINT_ERROR("\nERROR: venc_set_param input failed"); + return OMX_ErrorUnsupportedSetting; + } + } else { + /*TODO: reset encoder driver Meta mode*/ + dev_get_buf_req (&m_sOutPortDef.nBufferCountMin, + &m_sOutPortDef.nBufferCountActual, + &m_sOutPortDef.nBufferSize, + m_sOutPortDef.nPortIndex); + } + } + } + break; + } +#endif +#ifndef MAX_RES_720P + case OMX_QcomIndexParamIndexExtraDataType: + { + DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamIndexExtraDataType"); + QOMX_INDEXEXTRADATATYPE *pParam = (QOMX_INDEXEXTRADATATYPE *)paramData; + if (pParam->nIndex == (OMX_INDEXTYPE)OMX_ExtraDataVideoEncoderSliceInfo) + { + if (pParam->nPortIndex == PORT_INDEX_OUT) + { + if (pParam->bEnabled == OMX_TRUE) + m_sExtraData |= VEN_EXTRADATA_SLICEINFO; + else + m_sExtraData &= ~VEN_EXTRADATA_SLICEINFO; + DEBUG_PRINT_HIGH("set_param: m_sExtraData=%x", m_sExtraData); + if(handle->venc_set_param(&m_sExtraData, + (OMX_INDEXTYPE)OMX_ExtraDataVideoEncoderSliceInfo) != true) + { + DEBUG_PRINT_ERROR("ERROR: Setting " + "OMX_QcomIndexParamIndexExtraDataType failed"); + return OMX_ErrorUnsupportedSetting; + } + else + { + m_sOutPortDef.nPortIndex = PORT_INDEX_OUT; + dev_get_buf_req(&m_sOutPortDef.nBufferCountMin, + &m_sOutPortDef.nBufferCountActual, + &m_sOutPortDef.nBufferSize, + m_sOutPortDef.nPortIndex); + DEBUG_PRINT_HIGH("updated out_buf_req: buffer cnt=%d, " + "count min=%d, buffer size=%d", + m_sOutPortDef.nBufferCountActual, + m_sOutPortDef.nBufferCountMin, + m_sOutPortDef.nBufferSize); + } + } + else + { + DEBUG_PRINT_ERROR("set_parameter: slice information is " + "valid for output port only"); + eRet = OMX_ErrorUnsupportedIndex; + } + } + else + { + DEBUG_PRINT_ERROR("set_parameter: unsupported index (%x), " + "only slice information extradata is supported", pParam->nIndex); + eRet = OMX_ErrorUnsupportedIndex; + } + break; + } +#endif + case OMX_QcomIndexParamVideoMaxAllowedBitrateCheck: + { + QOMX_EXTNINDEX_PARAMTYPE* pParam = + (QOMX_EXTNINDEX_PARAMTYPE*)paramData; + if(pParam->nPortIndex == PORT_INDEX_OUT) + { + handle->m_max_allowed_bitrate_check = + ((pParam->bEnable == OMX_TRUE) ? true : false); + DEBUG_PRINT_HIGH("set_parameter: max allowed bitrate check %s", + ((pParam->bEnable == OMX_TRUE) ? "enabled" : "disabled")); + } + else + { + DEBUG_PRINT_ERROR("ERROR: OMX_QcomIndexParamVideoMaxAllowedBitrateCheck " + " called on wrong port(%d)", pParam->nPortIndex); + return OMX_ErrorBadPortIndex; + } + break; + } +#ifdef MAX_RES_1080P + case OMX_QcomIndexEnableSliceDeliveryMode: + { + QOMX_EXTNINDEX_PARAMTYPE* pParam = + (QOMX_EXTNINDEX_PARAMTYPE*)paramData; + if(pParam->nPortIndex == PORT_INDEX_OUT) + { + if(!handle->venc_set_param(paramData, + (OMX_INDEXTYPE)OMX_QcomIndexEnableSliceDeliveryMode)) + { + DEBUG_PRINT_ERROR("ERROR: Request for setting slice delivery mode failed"); + return OMX_ErrorUnsupportedSetting; + } + } + else + { + DEBUG_PRINT_ERROR("ERROR: OMX_QcomIndexEnableSliceDeliveryMode " + "called on wrong port(%d)", pParam->nPortIndex); + return OMX_ErrorBadPortIndex; + } + break; + } +#endif + case OMX_QcomIndexParamSequenceHeaderWithIDR: + { + if(!handle->venc_set_param(paramData, + (OMX_INDEXTYPE)OMX_QcomIndexParamSequenceHeaderWithIDR)) + { + DEBUG_PRINT_ERROR("ERROR: Request for setting inband sps/pps failed"); + return OMX_ErrorUnsupportedSetting; + } + break; + } + case OMX_QcomIndexParamEnableVUIStreamRestrictFlag: + { + if(!handle->venc_set_param(paramData, + (OMX_INDEXTYPE)OMX_QcomIndexParamEnableVUIStreamRestrictFlag)) + { + DEBUG_PRINT_ERROR("ERROR: Request for enabling bitstream_restrict " + "flag in VUI failed"); + return OMX_ErrorUnsupportedSetting; + } + break; + } + case OMX_QcomIndexParamPictureOrderCountType: + { + if(!handle->venc_set_param(paramData, + (OMX_INDEXTYPE)OMX_QcomIndexParamPictureOrderCountType)) + { + DEBUG_PRINT_ERROR("ERROR: Request for setting poc failed"); + return OMX_ErrorUnsupportedSetting; + } + memcpy(&m_sPicureOrderCount, (QOMX_PICTURE_ORDER_COUNT_TYPE *)paramData, + sizeof(m_sPicureOrderCount)); + break; + } + case OMX_IndexParamVideoSliceFMO: + default: + { + DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown param %d\n", paramIndex); + eRet = OMX_ErrorUnsupportedIndex; + break; + } + } + return eRet; +} + +bool omx_venc::update_profile_level() +{ + OMX_U32 eProfile, eLevel; + + if(!handle->venc_get_profile_level(&eProfile,&eLevel)) + { + DEBUG_PRINT_ERROR("\nFailed to update the profile_level\n"); + return false; + } + + m_sParamProfileLevel.eProfile = (OMX_VIDEO_MPEG4PROFILETYPE)eProfile; + m_sParamProfileLevel.eLevel = (OMX_VIDEO_MPEG4LEVELTYPE)eLevel; + + if(!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.mpeg4",\ + OMX_MAX_STRINGNAME_SIZE)) + { + m_sParamMPEG4.eProfile = (OMX_VIDEO_MPEG4PROFILETYPE)eProfile; + m_sParamMPEG4.eLevel = (OMX_VIDEO_MPEG4LEVELTYPE)eLevel; + DEBUG_PRINT_LOW("\n MPEG4 profile = %d, level = %d", m_sParamMPEG4.eProfile, + m_sParamMPEG4.eLevel); + } + else if(!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.h263",\ + OMX_MAX_STRINGNAME_SIZE)) + { + m_sParamH263.eProfile = (OMX_VIDEO_H263PROFILETYPE)eProfile; + m_sParamH263.eLevel = (OMX_VIDEO_H263LEVELTYPE)eLevel; + DEBUG_PRINT_LOW("\n H263 profile = %d, level = %d", m_sParamH263.eProfile, + m_sParamH263.eLevel); + } + else if(!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.avc",\ + OMX_MAX_STRINGNAME_SIZE)) + { + m_sParamAVC.eProfile = (OMX_VIDEO_AVCPROFILETYPE)eProfile; + m_sParamAVC.eLevel = (OMX_VIDEO_AVCLEVELTYPE)eLevel; + DEBUG_PRINT_LOW("\n AVC profile = %d, level = %d", m_sParamAVC.eProfile, + m_sParamAVC.eLevel); + } + return true; +} +/* ====================================================================== +FUNCTION + omx_video::SetConfig + +DESCRIPTION + OMX Set Config method implementation + +PARAMETERS + . + +RETURN VALUE + OMX Error None if successful. +========================================================================== */ +OMX_ERRORTYPE omx_venc::set_config(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_INDEXTYPE configIndex, + OMX_IN OMX_PTR configData) +{ + if(configData == NULL) + { + DEBUG_PRINT_ERROR("ERROR: param is null"); + return OMX_ErrorBadParameter; + } + + if(m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("ERROR: config called in Invalid state"); + return OMX_ErrorIncorrectStateOperation; + } + + // params will be validated prior to venc_init + switch(configIndex) + { + case OMX_IndexConfigVideoBitrate: + { + OMX_VIDEO_CONFIG_BITRATETYPE* pParam = + reinterpret_cast(configData); + DEBUG_PRINT_HIGH("set_config(): OMX_IndexConfigVideoBitrate (%u)", pParam->nEncodeBitrate); + + if(pParam->nPortIndex == PORT_INDEX_OUT) + { + if(handle->venc_set_config(configData, OMX_IndexConfigVideoBitrate) != true) + { + DEBUG_PRINT_ERROR("ERROR: Setting OMX_IndexConfigVideoBitrate failed"); + return OMX_ErrorUnsupportedSetting; + } + + m_sConfigBitrate.nEncodeBitrate = pParam->nEncodeBitrate; + m_sParamBitrate.nTargetBitrate = pParam->nEncodeBitrate; + m_sOutPortDef.format.video.nBitrate = pParam->nEncodeBitrate; + } + else + { + DEBUG_PRINT_ERROR("ERROR: Unsupported port index: %u", pParam->nPortIndex); + return OMX_ErrorBadPortIndex; + } + break; + } + case OMX_IndexConfigVideoFramerate: + { + OMX_CONFIG_FRAMERATETYPE* pParam = + reinterpret_cast(configData); + DEBUG_PRINT_HIGH("set_config(): OMX_IndexConfigVideoFramerate (0x%x)", pParam->xEncodeFramerate); + + if(pParam->nPortIndex == PORT_INDEX_OUT) + { + if(handle->venc_set_config(configData, OMX_IndexConfigVideoFramerate) != true) + { + DEBUG_PRINT_ERROR("ERROR: Setting OMX_IndexConfigVideoFramerate failed"); + return OMX_ErrorUnsupportedSetting; + } + + m_sConfigFramerate.xEncodeFramerate = pParam->xEncodeFramerate; + m_sOutPortDef.format.video.xFramerate = pParam->xEncodeFramerate; + m_sOutPortFormat.xFramerate = pParam->xEncodeFramerate; + } + else + { + DEBUG_PRINT_ERROR("ERROR: Unsupported port index: %u", pParam->nPortIndex); + return OMX_ErrorBadPortIndex; + } + + break; + } + case QOMX_IndexConfigVideoIntraperiod: + { + QOMX_VIDEO_INTRAPERIODTYPE* pParam = + reinterpret_cast(configData); + DEBUG_PRINT_HIGH("set_config(): QOMX_IndexConfigVideoIntraperiod"); + + if(pParam->nPortIndex == PORT_INDEX_OUT) + { +#ifdef MAX_RES_720P + if(pParam->nBFrames > 0) + { + DEBUG_PRINT_ERROR("B frames not supported\n"); + return OMX_ErrorUnsupportedSetting; + } +#endif + DEBUG_PRINT_HIGH("Old: P/B frames = %d/%d, New: P/B frames = %d/%d", + m_sIntraperiod.nPFrames, m_sIntraperiod.nBFrames, + pParam->nPFrames, pParam->nBFrames); + if (m_sIntraperiod.nBFrames != pParam->nBFrames) + { + DEBUG_PRINT_HIGH("Dynamically changing B-frames not supported"); + return OMX_ErrorUnsupportedSetting; + } + if(handle->venc_set_config(configData, (OMX_INDEXTYPE) QOMX_IndexConfigVideoIntraperiod) != true) + { + DEBUG_PRINT_ERROR("ERROR: Setting QOMX_IndexConfigVideoIntraperiod failed"); + return OMX_ErrorUnsupportedSetting; + } + m_sIntraperiod.nPFrames = pParam->nPFrames; + m_sIntraperiod.nBFrames = pParam->nBFrames; + m_sIntraperiod.nIDRPeriod = pParam->nIDRPeriod; + + if(m_sOutPortFormat.eCompressionFormat == OMX_VIDEO_CodingMPEG4) + { + m_sParamMPEG4.nPFrames = pParam->nPFrames; + if(m_sParamMPEG4.eProfile != OMX_VIDEO_MPEG4ProfileSimple) + m_sParamMPEG4.nBFrames = pParam->nBFrames; + else + m_sParamMPEG4.nBFrames = 0; + } + else if(m_sOutPortFormat.eCompressionFormat == OMX_VIDEO_CodingH263) + { + m_sParamH263.nPFrames = pParam->nPFrames; + } + else + { + m_sParamAVC.nPFrames = pParam->nPFrames; + if(m_sParamAVC.eProfile != OMX_VIDEO_AVCProfileBaseline) + m_sParamAVC.nBFrames = pParam->nBFrames; + else + m_sParamAVC.nBFrames = 0; + } + } + else + { + DEBUG_PRINT_ERROR("ERROR: (QOMX_IndexConfigVideoIntraperiod) Unsupported port index: %u", pParam->nPortIndex); + return OMX_ErrorBadPortIndex; + } + + break; + } + + case OMX_IndexConfigVideoIntraVOPRefresh: + { + OMX_CONFIG_INTRAREFRESHVOPTYPE* pParam = + reinterpret_cast(configData); + DEBUG_PRINT_HIGH("set_config(): OMX_IndexConfigVideoIntraVOPRefresh"); + + if(pParam->nPortIndex == PORT_INDEX_OUT) + { + if(handle->venc_set_config(configData, + OMX_IndexConfigVideoIntraVOPRefresh) != true) + { + DEBUG_PRINT_ERROR("ERROR: Setting OMX_IndexConfigVideoIntraVOPRefresh failed"); + return OMX_ErrorUnsupportedSetting; + } + + m_sConfigIntraRefreshVOP.IntraRefreshVOP = pParam->IntraRefreshVOP; + } + else + { + DEBUG_PRINT_ERROR("ERROR: Unsupported port index: %u", pParam->nPortIndex); + return OMX_ErrorBadPortIndex; + } + + break; + } + case OMX_IndexConfigCommonRotate: + { + OMX_CONFIG_ROTATIONTYPE *pParam = + reinterpret_cast(configData); + OMX_S32 nRotation; + + if(pParam->nPortIndex != PORT_INDEX_IN){ + DEBUG_PRINT_ERROR("ERROR: Unsupported port index: %u", pParam->nPortIndex); + return OMX_ErrorBadPortIndex; + } + if( pParam->nRotation == 0 || + pParam->nRotation == 90 || + pParam->nRotation == 180 || + pParam->nRotation == 270 ) { + DEBUG_PRINT_HIGH("\nset_config: Rotation Angle %u", pParam->nRotation); + } else { + DEBUG_PRINT_ERROR("ERROR: un supported Rotation %u", pParam->nRotation); + return OMX_ErrorUnsupportedSetting; + } + nRotation = pParam->nRotation - m_sConfigFrameRotation.nRotation; + if(nRotation < 0) + nRotation = -nRotation; + if(nRotation == 90 || nRotation == 270) { + DEBUG_PRINT_HIGH("\nset_config: updating device Dims"); + if(handle->venc_set_config(configData, + OMX_IndexConfigCommonRotate) != true) { + DEBUG_PRINT_ERROR("ERROR: Set OMX_IndexConfigCommonRotate failed"); + return OMX_ErrorUnsupportedSetting; + } else { + OMX_U32 nFrameWidth; + + DEBUG_PRINT_HIGH("\nset_config: updating port Dims"); + + nFrameWidth = m_sInPortDef.format.video.nFrameWidth; + m_sInPortDef.format.video.nFrameWidth = + m_sInPortDef.format.video.nFrameHeight; + m_sInPortDef.format.video.nFrameHeight = nFrameWidth; + + m_sOutPortDef.format.video.nFrameWidth = + m_sInPortDef.format.video.nFrameWidth; + m_sOutPortDef.format.video.nFrameHeight = + m_sInPortDef.format.video.nFrameHeight; + m_sConfigFrameRotation.nRotation = pParam->nRotation; + } + } else { + m_sConfigFrameRotation.nRotation = pParam->nRotation; + } + break; + } + case OMX_QcomIndexConfigVideoFramePackingArrangement: + { + DEBUG_PRINT_HIGH("set_config(): OMX_QcomIndexConfigVideoFramePackingArrangement"); + if(m_sOutPortFormat.eCompressionFormat == OMX_VIDEO_CodingAVC) + { + OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt = + (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData; + extra_data_handle.set_frame_pack_data(configFmt); + } + else + { + DEBUG_PRINT_ERROR("ERROR: FramePackingData not supported for non AVC compression"); + } + break; + } + default: + DEBUG_PRINT_ERROR("ERROR: unsupported index %d", (int) configIndex); + break; + } + + return OMX_ErrorNone; +} + +/* ====================================================================== +FUNCTION + omx_venc::ComponentDeInit + +DESCRIPTION + Destroys the component and release memory allocated to the heap. + +PARAMETERS + . + +RETURN VALUE + OMX Error None if everything successful. + +========================================================================== */ +OMX_ERRORTYPE omx_venc::component_deinit(OMX_IN OMX_HANDLETYPE hComp) +{ + OMX_U32 i = 0; + DEBUG_PRINT_HIGH("\n omx_venc(): Inside component_deinit()"); + if(OMX_StateLoaded != m_state) + { + DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d\n",\ + m_state); + } + if(m_out_mem_ptr) + { + DEBUG_PRINT_LOW("Freeing the Output Memory\n"); + for(i=0; i< m_sOutPortDef.nBufferCountActual; i++ ) + { + free_output_buffer (&m_out_mem_ptr[i]); + } + free(m_out_mem_ptr); + m_out_mem_ptr = NULL; + } + + /*Check if the input buffers have to be cleaned up*/ + if(m_inp_mem_ptr +#ifdef _ANDROID_ICS_ + && !meta_mode_enable +#endif + ) + { + DEBUG_PRINT_LOW("Freeing the Input Memory\n"); + for(i=0; ivenc_close(); + DEBUG_PRINT_HIGH("Deleting HANDLE[%p]\n", handle); + delete (handle); + DEBUG_PRINT_HIGH("OMX_Venc:Component Deinit\n"); + return OMX_ErrorNone; +} + + +OMX_U32 omx_venc::dev_stop( void) +{ + return handle->venc_stop(); +} + + +OMX_U32 omx_venc::dev_pause(void) +{ + return handle->venc_pause(); +} + +OMX_U32 omx_venc::dev_start(void) +{ + return handle->venc_start(); +} + +OMX_U32 omx_venc::dev_flush(unsigned port) +{ + return handle->venc_flush(port); +} +OMX_U32 omx_venc::dev_resume(void) +{ + return handle->venc_resume(); +} + +OMX_U32 omx_venc::dev_start_done(void) +{ + return handle->venc_start_done(); +} + +OMX_U32 omx_venc::dev_stop_done(void) +{ + return handle->venc_stop_done(); +} + +bool omx_venc::dev_use_buf(void *buf_addr,unsigned port,unsigned index) +{ + return handle->venc_use_buf(buf_addr,port,index); +} + +bool omx_venc::dev_free_buf(void *buf_addr,unsigned port) +{ + return handle->venc_free_buf(buf_addr,port); +} + +bool omx_venc::dev_empty_buf(void *buffer, void *pmem_data_buf,unsigned index,unsigned fd) +{ + return handle->venc_empty_buf(buffer, pmem_data_buf,index,fd); +} + +bool omx_venc::dev_fill_buf(void *buffer, void *pmem_data_buf,unsigned index,unsigned fd) +{ + return handle->venc_fill_buf(buffer, pmem_data_buf,index,fd); +} + +bool omx_venc::dev_get_seq_hdr(void *buffer, unsigned size, unsigned *hdrlen) +{ + return handle->venc_get_seq_hdr(buffer, size, hdrlen); +} + +bool omx_venc::dev_loaded_start() +{ + return handle->venc_loaded_start(); +} + +bool omx_venc::dev_loaded_stop() +{ + return handle->venc_loaded_stop(); +} + +bool omx_venc::dev_loaded_start_done() +{ + return handle->venc_loaded_start_done(); +} + +bool omx_venc::dev_loaded_stop_done() +{ + return handle->venc_loaded_stop_done(); +} + +bool omx_venc::dev_get_buf_req(OMX_U32 *min_buff_count, + OMX_U32 *actual_buff_count, + OMX_U32 *buff_size, + OMX_U32 port) +{ + return handle->venc_get_buf_req(min_buff_count, + actual_buff_count, + buff_size, + port); + +} + +bool omx_venc::dev_get_curr_perf_lvl(OMX_PTR curr_perf) +{ + return handle->venc_get_curr_perf_lvl(curr_perf); +} + +bool omx_venc::dev_set_buf_req(OMX_U32 *min_buff_count, + OMX_U32 *actual_buff_count, + OMX_U32 *buff_size, + OMX_U32 port) +{ + return handle->venc_set_buf_req(min_buff_count, + actual_buff_count, + buff_size, + port); + +} + +int omx_venc::async_message_process (void *context, void* message) +{ + omx_video* omx = NULL; + struct venc_msg *m_sVenc_msg = NULL; + OMX_BUFFERHEADERTYPE* omxhdr = NULL; + struct venc_buffer *temp_buff = NULL; + + if(context == NULL || message == NULL) + { + DEBUG_PRINT_ERROR("\nERROR: omx_venc::async_message_process invalid i/p params"); + return -1; + } + m_sVenc_msg = (struct venc_msg *)message; + + omx = reinterpret_cast(context); + + if(m_sVenc_msg->statuscode != VEN_S_SUCCESS) + { + DEBUG_PRINT_ERROR("\nERROR: async_msg_process() - Error statuscode = %d\n", + m_sVenc_msg->statuscode); + omx->omx_report_error(); + } + + DEBUG_PRINT_LOW("\n omx_venc::async_message_process- msgcode = %d\n", + m_sVenc_msg->msgcode); + switch(m_sVenc_msg->msgcode) + { + + case VEN_MSG_START: + omx->post_event (NULL,m_sVenc_msg->statuscode,\ + OMX_COMPONENT_GENERATE_START_DONE); + break; + + case VEN_MSG_STOP: + omx->post_event (NULL,m_sVenc_msg->statuscode,\ + OMX_COMPONENT_GENERATE_STOP_DONE); + break; + + case VEN_MSG_RESUME: + omx->post_event (NULL,m_sVenc_msg->statuscode,\ + OMX_COMPONENT_GENERATE_RESUME_DONE); + break; + + case VEN_MSG_PAUSE: + omx->post_event (NULL,m_sVenc_msg->statuscode,\ + OMX_COMPONENT_GENERATE_PAUSE_DONE); + + break; + + case VEN_MSG_FLUSH_INPUT_DONE: + + omx->post_event (NULL,m_sVenc_msg->statuscode,\ + OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH); + break; + case VEN_MSG_FLUSH_OUPUT_DONE: + omx->post_event (NULL,m_sVenc_msg->statuscode,\ + OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH); + break; + case VEN_MSG_INPUT_BUFFER_DONE: + omxhdr = (OMX_BUFFERHEADERTYPE* )\ + m_sVenc_msg->buf.clientdata; + + if(omxhdr == NULL || + (((OMX_U32)(omxhdr - omx->m_inp_mem_ptr) > omx->m_sInPortDef.nBufferCountActual) && + ((OMX_U32)(omxhdr - omx->meta_buffer_hdr) > omx->m_sInPortDef.nBufferCountActual))) + { + omxhdr = NULL; + m_sVenc_msg->statuscode = VEN_S_EFAIL; + } + +#ifdef _ANDROID_ICS_ + omx->omx_release_meta_buffer(omxhdr); +#endif + omx->post_event ((unsigned int)omxhdr,m_sVenc_msg->statuscode, + OMX_COMPONENT_GENERATE_EBD); + break; + case VEN_MSG_OUTPUT_BUFFER_DONE: + + omxhdr = (OMX_BUFFERHEADERTYPE*)m_sVenc_msg->buf.clientdata; + + if( (omxhdr != NULL) && + ((OMX_U32)(omxhdr - omx->m_out_mem_ptr) < omx->m_sOutPortDef.nBufferCountActual)) + { + if(m_sVenc_msg->buf.len <= omxhdr->nAllocLen) + { + int idx = omxhdr - omx->m_out_mem_ptr; + omxhdr->nFilledLen = m_sVenc_msg->buf.len; + omxhdr->nOffset = m_sVenc_msg->buf.offset; + omxhdr->nTimeStamp = m_sVenc_msg->buf.timestamp; + omxhdr->nFlags = m_sVenc_msg->buf.flags; + omx->extradata_len[idx] = m_sVenc_msg->buf.metadata_len; + omx->extradata_offset[idx] = m_sVenc_msg->buf.metadata_offset; + DEBUG_PRINT_LOW("[RespBufDone]: pBuffer = 0x%x, nFilledLen = %d, "\ + "nAllocLen = %d, Ts = %lld, nFlags = 0x%x, nOffset = %d, "\ + "Extradata Info: Idx = %d, Offset(%d), len(%d)", + omxhdr->pBuffer, omxhdr->nFilledLen, omxhdr->nAllocLen, + omxhdr->nTimeStamp, omxhdr->nFlags, omxhdr->nOffset, + idx, omx->extradata_offset[idx], omx->extradata_len[idx]); + + /*Use buffer case*/ + if(omx->output_use_buffer && !omx->m_use_output_pmem) + { + DEBUG_PRINT_LOW("\n memcpy() for o/p Heap UseBuffer"); + memcpy(omxhdr->pBuffer, + (m_sVenc_msg->buf.ptrbuffer), + m_sVenc_msg->buf.len); + } + } + else + { + DEBUG_PRINT_HIGH("nFilledLen[%d] is more than nAllocLen[%d]", + omxhdr->nFilledLen, omxhdr->nAllocLen); + omxhdr->nFilledLen = 0; + } + + } + else + { + omxhdr = NULL; + m_sVenc_msg->statuscode = VEN_S_EFAIL; + } + + omx->post_event ((unsigned int)omxhdr,m_sVenc_msg->statuscode, + OMX_COMPONENT_GENERATE_FBD); + break; + case VEN_MSG_NEED_OUTPUT_BUFFER: + //TBD what action needs to be done here?? + break; + default: + break; + } + return 0; +} +bool omx_venc::is_secure_session() +{ + return secure_session; +} + +bool omx_venc::dev_get_uncache_flag() +{ + return handle->venc_get_uncache_flag(); +} + diff --git a/mm-video/vidc/venc/src/video_encoder_device.cpp b/mm-video/vidc/venc/src/video_encoder_device.cpp index 63b9d98..fc2109c 100755 --- a/mm-video/vidc/venc/src/video_encoder_device.cpp +++ b/mm-video/vidc/venc/src/video_encoder_device.cpp @@ -982,6 +982,42 @@ bool venc_dev::venc_set_param(void *paramData,OMX_INDEXTYPE index ) } break; } + case OMX_QcomIndexParamSequenceHeaderWithIDR: + { + PrependSPSPPSToIDRFramesParams * pParam = + (PrependSPSPPSToIDRFramesParams *)paramData; + + if(venc_set_inband_video_header(pParam->bEnable) == false) + { + DEBUG_PRINT_ERROR("Setting inband sps/pps failed"); + return false; + } + break; + } + case OMX_QcomIndexParamEnableVUIStreamRestrictFlag: + { + QOMX_VUI_BITSTREAM_RESTRICT *pParam = + (QOMX_VUI_BITSTREAM_RESTRICT *)paramData; + + if(venc_set_bitstream_restrict_in_vui(pParam->bEnable) == false) + { + DEBUG_PRINT_ERROR("Setting bitstream_restrict flag in VUI failed"); + return false; + } + break; + } + case OMX_QcomIndexParamPictureOrderCountType: + { + QOMX_PICTURE_ORDER_COUNT_TYPE *pParam = + (QOMX_PICTURE_ORDER_COUNT_TYPE *)paramData; + + if(venc_set_picture_order_count_type(pParam->nType) == false) + { + DEBUG_PRINT_ERROR("Setting poc type failed"); + return false; + } + break; + } case OMX_IndexParamVideoSliceFMO: default: DEBUG_PRINT_ERROR("\nERROR: Unsupported parameter in venc_set_param: %u", @@ -2921,3 +2957,25 @@ bool venc_dev::venc_set_meta_mode(bool mode) return true; } #endif + +bool venc_dev::venc_get_uncache_flag() +{ + DEBUG_PRINT_LOW("%s: m_use_uncache_buffers = %d", __func__, + m_use_uncache_buffers); + return m_use_uncache_buffers; +} + +bool venc_dev::venc_set_picture_order_count_type(OMX_U32 type) +{ + venc_poctype temp; + venc_ioctl_msg ioctl_msg = {&temp, NULL}; + + temp.poc_type = type; + DEBUG_PRINT_HIGH("Setting poc type: %d", type); + if(ioctl(m_nDriver_fd, VEN_IOCTL_SET_PIC_ORDER_CNT_TYPE, (void *)&ioctl_msg) < 0) + { + DEBUG_PRINT_ERROR("Request for setting poc type failed"); + return false; + } + return true; +}