| /*-------------------------------------------------------------------------- |
| Copyright (c) 2014-2017, 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_swvenc_mpeg4.h" |
| |
| /* def: StoreMetaDataInBuffersParams */ |
| #include <media/hardware/HardwareAPI.h> |
| |
| /* def: VENUS_BUFFER_SIZE, VENUS_Y_STRIDE etc */ |
| #include <media/msm_media_info.h> |
| |
| /* def: private_handle_t*/ |
| #include <gralloc_priv.h> |
| |
| #include "PlatformConfig.h" |
| |
| /* use GraphicBuffer for rotation */ |
| #include <ui/GraphicBufferAllocator.h> |
| #include <gralloc.h> |
| |
| /* def: GET_VT_TIMESTAMP */ |
| #include <qdMetaData.h> |
| |
| /*---------------------------------------------------------------------------- |
| * 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 |
| |
| #define ENTER_FUNC() DEBUG_PRINT_HIGH("ENTERING: %s",__FUNCTION__) |
| #define EXIT_FUNC() DEBUG_PRINT_HIGH("EXITING: %s",__FUNCTION__) |
| #define RETURN(x) EXIT_FUNC(); return x; |
| #undef ALIGN |
| #define ALIGN(value,alignment) (((value) + (alignment-1)) & (~(alignment-1))) |
| |
| #define BUFFER_LOG_LOC "/data/vendor/media" |
| |
| /* factory function executed by the core to create instances */ |
| void *get_omx_component_factory_fn(void) |
| { |
| RETURN((new omx_venc)); |
| } |
| |
| omx_venc::omx_venc() |
| { |
| ENTER_FUNC(); |
| |
| char property_value[PROPERTY_VALUE_MAX] = {0}; |
| |
| memset(&m_debug,0,sizeof(m_debug)); |
| |
| property_value[0] = '\0'; |
| property_get("vendor.vidc.debug.level", property_value, "1"); |
| debug_level = atoi(property_value); |
| |
| Platform::Config::getInt32(Platform::vidc_enc_log_in, |
| (int32_t *)&m_debug.in_buffer_log, 0); |
| Platform::Config::getInt32(Platform::vidc_enc_log_out, |
| (int32_t *)&m_debug.out_buffer_log, 0); |
| |
| property_value[0] = '\0'; |
| property_get("vendor.vidc.enc.log.in", property_value, "0"); |
| m_debug.in_buffer_log = atoi(property_value); |
| |
| property_value[0] = '\0'; |
| property_get("vendor.vidc.enc.log.out", property_value, "0"); |
| m_debug.out_buffer_log = atoi(property_value); |
| |
| snprintf(m_debug.log_loc, PROPERTY_VALUE_MAX, "%s", BUFFER_LOG_LOC); |
| property_value[0] = '\0'; |
| property_get("vendor.vidc.log.loc", property_value, ""); |
| if (*property_value) |
| { |
| strlcpy(m_debug.log_loc, property_value, PROPERTY_VALUE_MAX); |
| } |
| |
| memset(meta_buffer_hdr,0,sizeof(meta_buffer_hdr)); |
| 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; |
| get_syntaxhdr_enable = false; |
| m_bSeqHdrRequested = false; |
| m_bDimensionsNeedFlip = false; |
| m_bIsRotationSupported = false; |
| m_bIsInFrameSizeSet = false; |
| m_bIsOutFrameSizeSet = false; |
| m_bIsInFlipDone = false; |
| m_bIsOutFlipDone = false; |
| m_bUseAVTimerTimestamps = false; |
| m_pIpbuffers = nullptr; |
| set_format = false; |
| |
| EXIT_FUNC(); |
| } |
| |
| omx_venc::~omx_venc() |
| { |
| ENTER_FUNC(); |
| get_syntaxhdr_enable = false; |
| EXIT_FUNC(); |
| } |
| |
| OMX_ERRORTYPE omx_venc::component_init(OMX_STRING role) |
| { |
| ENTER_FUNC(); |
| |
| OMX_ERRORTYPE eRet = OMX_ErrorNone; |
| SWVENC_STATUS Ret = SWVENC_S_SUCCESS; |
| SWVENC_CALLBACK callBackInfo; |
| OMX_VIDEO_CODINGTYPE codec_type; |
| SWVENC_PROPERTY Prop; |
| int fds[2]; |
| |
| strlcpy((char *)m_nkind,role,OMX_MAX_STRINGNAME_SIZE); |
| secure_session = false; |
| |
| if (!strncmp( (char *)m_nkind,"OMX.qcom.video.encoder.mpeg4sw", |
| OMX_MAX_STRINGNAME_SIZE)) |
| { |
| strlcpy((char *)m_cRole, "video_encoder.mpeg4",\ |
| OMX_MAX_STRINGNAME_SIZE); |
| codec_type = OMX_VIDEO_CodingMPEG4; |
| m_codec = SWVENC_CODEC_MPEG4; |
| } |
| else if (!strncmp( (char *)m_nkind,"OMX.qcom.video.encoder.h263sw", |
| OMX_MAX_STRINGNAME_SIZE)) |
| { |
| strlcpy((char *)m_cRole, "video_encoder.h263",\ |
| OMX_MAX_STRINGNAME_SIZE); |
| codec_type = OMX_VIDEO_CodingH263; |
| m_codec = SWVENC_CODEC_H263; |
| } |
| else |
| { |
| DEBUG_PRINT_ERROR("ERROR: Unknown Component"); |
| eRet = OMX_ErrorInvalidComponentName; |
| RETURN(eRet); |
| } |
| |
| #ifdef ENABLE_GET_SYNTAX_HDR |
| get_syntaxhdr_enable = true; |
| DEBUG_PRINT_HIGH("Get syntax header enabled"); |
| #endif |
| |
| callBackInfo.pfn_empty_buffer_done = swvenc_empty_buffer_done_cb; |
| callBackInfo.pfn_fill_buffer_done = swvenc_fill_buffer_done_cb; |
| callBackInfo.pfn_event_notification = swvenc_handle_event_cb; |
| callBackInfo.p_client = (void*)this; |
| |
| SWVENC_STATUS sRet = swvenc_init(&m_hSwVenc, m_codec, &callBackInfo); |
| if (sRet != SWVENC_S_SUCCESS) |
| { |
| DEBUG_PRINT_ERROR("swvenc_init returned %d, ret insufficient resources", |
| sRet); |
| RETURN(OMX_ErrorInsufficientResources); |
| } |
| |
| m_stopped = true; |
| |
| //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_IPB_QPRANGETYPE); |
| m_sSessionQPRange.nPortIndex = (OMX_U32) PORT_INDEX_OUT; |
| m_sSessionQPRange.minIQP = 2; |
| m_sSessionQPRange.minPQP = 2; |
| m_sSessionQPRange.minBQP = 2; |
| |
| 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; |
| } |
| |
| /* set the profile and level */ |
| Ret = swvenc_set_profile_level(m_sParamProfileLevel.eProfile, |
| m_sParamProfileLevel.eLevel); |
| if (Ret != SWVENC_S_SUCCESS) |
| { |
| DEBUG_PRINT_ERROR("%s, swvenc_set_rc_mode failed (%d)", |
| __FUNCTION__, Ret); |
| RETURN(OMX_ErrorUndefined); |
| } |
| |
| // 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 = (char *)"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; |
| |
| /* set the frame size */ |
| Prop.id = SWVENC_PROPERTY_ID_FRAME_SIZE; |
| Prop.info.frame_size.height = m_sInPortDef.format.video.nFrameHeight; |
| Prop.info.frame_size.width = m_sInPortDef.format.video.nFrameWidth; |
| |
| Ret = swvenc_setproperty(m_hSwVenc, &Prop); |
| if (Ret != SWVENC_S_SUCCESS) |
| { |
| DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)", |
| __FUNCTION__, Ret); |
| RETURN(OMX_ErrorUnsupportedSetting); |
| } |
| |
| /* set the frame attributes */ |
| Prop.id = SWVENC_PROPERTY_ID_FRAME_ATTRIBUTES; |
| Prop.info.frame_attributes.stride_luma = m_sInPortDef.format.video.nStride; |
| Prop.info.frame_attributes.stride_chroma = m_sInPortDef.format.video.nStride; |
| Prop.info.frame_attributes.offset_luma = 0; |
| Prop.info.frame_attributes.offset_chroma = |
| (m_sInPortDef.format.video.nSliceHeight * m_sInPortDef.format.video.nStride); |
| Prop.info.frame_attributes.size = (Prop.info.frame_attributes.offset_chroma * 3) >> 1; |
| |
| Ret = swvenc_setproperty(m_hSwVenc, &Prop); |
| if (Ret != SWVENC_S_SUCCESS) |
| { |
| DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)", |
| __FUNCTION__, Ret); |
| RETURN(OMX_ErrorUndefined); |
| } |
| |
| Ret = swvenc_get_buffer_req(&m_sInPortDef.nBufferCountMin, |
| &m_sInPortDef.nBufferCountActual, |
| &m_sInPortDef.nBufferSize, |
| &m_sInPortDef.nBufferAlignment, |
| PORT_INDEX_IN); |
| if (Ret != SWVENC_S_SUCCESS) |
| { |
| DEBUG_PRINT_ERROR("ERROR: %s, swvenc_get_buffer_req failed (%d)", __FUNCTION__, |
| Ret); |
| RETURN(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; |
| } |
| |
| Ret = swvenc_get_buffer_req(&m_sOutPortDef.nBufferCountMin, |
| &m_sOutPortDef.nBufferCountActual, |
| &m_sOutPortDef.nBufferSize, |
| &m_sOutPortDef.nBufferAlignment, |
| PORT_INDEX_OUT); |
| if (Ret != SWVENC_S_SUCCESS) |
| { |
| DEBUG_PRINT_ERROR("ERROR: %s, swvenc_get_buffer_req failed (%d)", __FUNCTION__, |
| Ret); |
| RETURN(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; |
| } |
| |
| // 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; |
| |
| OMX_INIT_STRUCT(&m_sConfigQP, OMX_QCOM_VIDEO_CONFIG_QP); |
| m_sConfigQP.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; |
| // 2 second intra period for default outport fps |
| m_sParamMPEG4.nPFrames = (m_sOutPortFormat.xFramerate * 2 - 1); |
| m_sParamMPEG4.bACPred = OMX_TRUE; |
| // delta = 2 @ 15 fps |
| m_sParamMPEG4.nTimeIncRes = 30; |
| // pframe and iframe |
| m_sParamMPEG4.nAllowedPictureTypes = 2; |
| // number of video packet headers per vop |
| m_sParamMPEG4.nHeaderExtension = 1; |
| 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; |
| // 2 second intra period for default outport fps |
| m_sParamH263.nPFrames = (m_sOutPortFormat.xFramerate * 2 - 1); |
| 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; |
| |
| // av-timer init (for ims-vt) |
| OMX_INIT_STRUCT(&m_sParamAVTimerTimestampMode, QOMX_ENABLETYPE); |
| m_sParamAVTimerTimestampMode.bEnable = OMX_FALSE; |
| |
| m_state = OMX_StateLoaded; |
| m_sExtraData = 0; |
| m_sParamConsumerUsage |= (OMX_U32)GRALLOC_USAGE_SW_READ_OFTEN; |
| |
| if (codec_type == OMX_VIDEO_CodingMPEG4) |
| { |
| m_capability.max_height = OMX_CORE_720P_HEIGHT; |
| m_capability.max_width = OMX_CORE_720P_WIDTH; |
| } |
| else if (codec_type == OMX_VIDEO_CodingH263) |
| { |
| m_capability.max_height = OMX_CORE_FWVGA_HEIGHT; |
| m_capability.max_width = OMX_CORE_FWVGA_WIDTH; |
| } |
| |
| m_capability.min_height = 32; |
| m_capability.min_width = 32; |
| |
| if (eRet == OMX_ErrorNone) |
| { |
| if (pipe(fds)) |
| { |
| DEBUG_PRINT_ERROR("ERROR: pipe creation failed"); |
| eRet = OMX_ErrorInsufficientResources; |
| } |
| else |
| { |
| if ((fds[0] == 0) || (fds[1] == 0)) |
| { |
| if (pipe(fds)) |
| { |
| DEBUG_PRINT_ERROR("ERROR: pipe creation failed"); |
| eRet = OMX_ErrorInsufficientResources; |
| } |
| } |
| if (eRet == OMX_ErrorNone) |
| { |
| m_pipe_in = fds[0]; |
| m_pipe_out = fds[1]; |
| } |
| } |
| |
| if (pthread_create(&msg_thread_id,0, message_thread_enc, this) < 0) |
| { |
| eRet = OMX_ErrorInsufficientResources; |
| msg_thread_created = false; |
| } |
| else |
| { |
| msg_thread_created = true; |
| } |
| } |
| |
| DEBUG_PRINT_HIGH("Component_init return value = 0x%x", eRet); |
| |
| EXIT_FUNC(); |
| |
| { |
| VendorExtensionStore *extStore = const_cast<VendorExtensionStore *>(&mVendorExtensionStore); |
| init_sw_vendor_extensions(*extStore); |
| mVendorExtensionStore.dumpExtensions((const char *)m_nkind); |
| } |
| |
| RETURN(eRet); |
| } |
| |
| OMX_ERRORTYPE omx_venc::set_parameter |
| ( |
| OMX_IN OMX_HANDLETYPE hComp, |
| OMX_IN OMX_INDEXTYPE paramIndex, |
| OMX_IN OMX_PTR paramData |
| ) |
| { |
| ENTER_FUNC(); |
| |
| OMX_ERRORTYPE eRet = OMX_ErrorNone; |
| SWVENC_STATUS Ret = SWVENC_S_SUCCESS; |
| SWVENC_PROPERTY Prop; |
| bool bResult; |
| unsigned int stride, scanlines; |
| |
| (void)hComp; |
| |
| if (m_state == OMX_StateInvalid) |
| { |
| DEBUG_PRINT_ERROR("ERROR: Set Param in Invalid State"); |
| RETURN(OMX_ErrorInvalidState); |
| } |
| if (paramData == NULL) |
| { |
| DEBUG_PRINT_ERROR("ERROR: Get Param in Invalid paramData"); |
| 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"); |
| RETURN(OMX_ErrorIncorrectStateOperation); |
| } |
| |
| switch ((int)paramIndex) |
| { |
| case OMX_IndexParamPortDefinition: |
| { |
| OMX_PARAM_PORTDEFINITIONTYPE *portDefn; |
| portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData; |
| DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d", |
| (int)portDefn->format.video.nFrameHeight, |
| (int)portDefn->format.video.nFrameWidth); |
| |
| if (PORT_INDEX_IN == portDefn->nPortIndex) |
| { |
| if (!dev_is_video_session_supported(portDefn->format.video.nFrameWidth, |
| portDefn->format.video.nFrameHeight)) |
| { |
| DEBUG_PRINT_ERROR("video session not supported"); |
| omx_report_unsupported_setting(); |
| RETURN(OMX_ErrorUnsupportedSetting); |
| } |
| DEBUG_PRINT_LOW("i/p actual cnt requested = %u", portDefn->nBufferCountActual); |
| DEBUG_PRINT_LOW("i/p min cnt requested = %u", portDefn->nBufferCountMin); |
| DEBUG_PRINT_LOW("i/p buffersize requested = %u", portDefn->nBufferSize); |
| if (portDefn->nBufferCountMin > portDefn->nBufferCountActual) |
| { |
| DEBUG_PRINT_ERROR("ERROR: (In_PORT) Min buffers (%u) > actual count (%u)", |
| portDefn->nBufferCountMin, portDefn->nBufferCountActual); |
| RETURN(OMX_ErrorUnsupportedSetting); |
| } |
| |
| /* set the frame size */ |
| Prop.id = SWVENC_PROPERTY_ID_FRAME_SIZE; |
| Prop.info.frame_size.height = portDefn->format.video.nFrameHeight; |
| Prop.info.frame_size.width = portDefn->format.video.nFrameWidth; |
| |
| Ret = swvenc_setproperty(m_hSwVenc, &Prop); |
| if (Ret != SWVENC_S_SUCCESS) |
| { |
| DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)", |
| __FUNCTION__, Ret); |
| RETURN(OMX_ErrorUnsupportedSetting); |
| } |
| |
| /* set the input frame-rate */ |
| if (portDefn->format.video.xFramerate != 0) |
| { |
| Ret = swvenc_set_frame_rate(portDefn->format.video.xFramerate >> 16); |
| if (Ret != SWVENC_S_SUCCESS) |
| { |
| DEBUG_PRINT_ERROR("%s, swvenc_set_frame_rate failed (%d)", |
| __FUNCTION__, Ret); |
| RETURN(OMX_ErrorUnsupportedSetting); |
| } |
| } |
| |
| /* set the frame attributes */ |
| stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, portDefn->format.video.nFrameWidth); |
| //Slice height doesn't get updated so chroma offset calculation becomes incorrect . |
| //Using FrameHeight Instead , just for omx-test-app . |
| //scanlines = VENUS_Y_SCANLINES(COLOR_FMT_NV12, portDefn->format.video.nSliceHeight); |
| scanlines = VENUS_Y_SCANLINES(COLOR_FMT_NV12, portDefn->format.video.nFrameHeight); |
| Prop.id = SWVENC_PROPERTY_ID_FRAME_ATTRIBUTES; |
| Prop.info.frame_attributes.stride_luma = stride; |
| Prop.info.frame_attributes.stride_chroma = stride; |
| Prop.info.frame_attributes.offset_luma = 0; |
| Prop.info.frame_attributes.offset_chroma = scanlines * stride; |
| Prop.info.frame_attributes.size = |
| VENUS_BUFFER_SIZE(COLOR_FMT_NV12, |
| portDefn->format.video.nFrameWidth, |
| portDefn->format.video.nFrameHeight); |
| |
| Ret = swvenc_setproperty(m_hSwVenc, &Prop); |
| if (Ret != SWVENC_S_SUCCESS) |
| { |
| DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)", |
| __FUNCTION__, Ret); |
| RETURN(OMX_ErrorUnsupportedSetting); |
| } |
| |
| DEBUG_PRINT_LOW("i/p previous actual cnt = %u", m_sInPortDef.nBufferCountActual); |
| DEBUG_PRINT_LOW("i/p previous min cnt = %u", m_sInPortDef.nBufferCountMin); |
| DEBUG_PRINT_LOW("i/p previous buffersize = %u", m_sInPortDef.nBufferSize); |
| |
| memcpy(&m_sInPortDef, portDefn,sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); |
| |
| /* update the input buffer requirement */ |
| Ret = swvenc_get_buffer_req(&m_sInPortDef.nBufferCountMin, |
| &m_sInPortDef.nBufferCountActual, |
| &m_sInPortDef.nBufferSize, |
| &m_sInPortDef.nBufferAlignment, |
| portDefn->nPortIndex); |
| if (Ret != SWVENC_S_SUCCESS) |
| { |
| DEBUG_PRINT_ERROR("ERROR: %s, swvenc_get_buffer_req failed (%d)", __FUNCTION__, |
| Ret); |
| RETURN(OMX_ErrorUndefined); |
| } |
| |
| if (portDefn->nBufferCountActual > m_sInPortDef.nBufferCountActual) |
| { |
| m_sInPortDef.nBufferCountActual = portDefn->nBufferCountActual; |
| } |
| if (portDefn->nBufferSize > m_sInPortDef.nBufferSize) |
| { |
| m_sInPortDef.nBufferSize = portDefn->nBufferSize; |
| } |
| |
| DEBUG_PRINT_LOW("i/p new actual cnt = %u", m_sInPortDef.nBufferCountActual); |
| DEBUG_PRINT_LOW("i/p new min cnt = %u", m_sInPortDef.nBufferCountMin); |
| DEBUG_PRINT_LOW("i/p new buffersize = %u", m_sInPortDef.nBufferSize); |
| |
| // when rotation is setting before portdefinition, if need flip dimensions |
| // in port flip will be set here |
| if (m_bDimensionsNeedFlip && !m_bIsInFlipDone) { |
| DEBUG_PRINT_HIGH("flip in port dimension(for swcodec) in portdefinition"); |
| OMX_ERRORTYPE err = swvenc_do_flip_inport(); |
| if (err != OMX_ErrorNone) { |
| DEBUG_PRINT_ERROR("%s, swvenc_do_flip_inport falied (%d)", |
| __FUNCTION__, err); |
| RETURN(err); |
| } |
| m_bIsInFlipDone = true; |
| } |
| m_bIsInFrameSizeSet = true; |
| } |
| else if (PORT_INDEX_OUT == portDefn->nPortIndex) |
| { |
| DEBUG_PRINT_LOW("o/p actual cnt requested = %u", portDefn->nBufferCountActual); |
| DEBUG_PRINT_LOW("o/p min cnt requested = %u", portDefn->nBufferCountMin); |
| DEBUG_PRINT_LOW("o/p buffersize requested = %u", portDefn->nBufferSize); |
| if (portDefn->nBufferCountMin > portDefn->nBufferCountActual) |
| { |
| DEBUG_PRINT_ERROR("ERROR: (Out_PORT) Min buffers (%u) > actual count (%u)", |
| portDefn->nBufferCountMin, portDefn->nBufferCountActual); |
| RETURN(OMX_ErrorUnsupportedSetting); |
| } |
| |
| /* set the output bit-rate */ |
| Ret = swvenc_set_bit_rate(portDefn->format.video.nBitrate); |
| if (Ret != SWVENC_S_SUCCESS) |
| { |
| DEBUG_PRINT_ERROR("%s, swvenc_set_bit_rate failed (%d)", |
| __FUNCTION__, Ret); |
| RETURN(OMX_ErrorUnsupportedSetting); |
| } |
| |
| DEBUG_PRINT_LOW("o/p previous actual cnt = %u", m_sOutPortDef.nBufferCountActual); |
| DEBUG_PRINT_LOW("o/p previous min cnt = %u", m_sOutPortDef.nBufferCountMin); |
| DEBUG_PRINT_LOW("o/p previous buffersize = %u", m_sOutPortDef.nBufferSize); |
| |
| /* set the buffer requirement */ |
| bResult = dev_set_buf_req(&portDefn->nBufferCountMin, |
| &portDefn->nBufferCountActual, |
| &portDefn->nBufferSize, |
| portDefn->nPortIndex); |
| if (bResult != true) |
| { |
| DEBUG_PRINT_ERROR("%s, dev_set_buf_req failed", |
| __FUNCTION__); |
| RETURN(OMX_ErrorUnsupportedSetting); |
| } |
| memcpy(&m_sOutPortDef, portDefn,sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); |
| |
| /* update the output buffer requirement */ |
| Ret = swvenc_get_buffer_req(&m_sOutPortDef.nBufferCountMin, |
| &m_sOutPortDef.nBufferCountActual, |
| &m_sOutPortDef.nBufferSize, |
| &m_sOutPortDef.nBufferAlignment, |
| portDefn->nPortIndex); |
| if (Ret != SWVENC_S_SUCCESS) |
| { |
| DEBUG_PRINT_ERROR("ERROR: %s, swvenc_get_buffer_req failed (%d)", __FUNCTION__, |
| Ret); |
| RETURN(OMX_ErrorUndefined); |
| } |
| |
| if (portDefn->nBufferCountActual > m_sOutPortDef.nBufferCountActual) |
| { |
| m_sOutPortDef.nBufferCountActual = portDefn->nBufferCountActual; |
| } |
| if (portDefn->nBufferSize > m_sOutPortDef.nBufferSize) |
| { |
| m_sOutPortDef.nBufferSize = portDefn->nBufferSize; |
| } |
| |
| DEBUG_PRINT_LOW("o/p new actual cnt = %u", m_sOutPortDef.nBufferCountActual); |
| DEBUG_PRINT_LOW("o/p new min cnt = %u", m_sOutPortDef.nBufferCountMin); |
| DEBUG_PRINT_LOW("o/p new buffersize = %u", m_sOutPortDef.nBufferSize); |
| // when rotation is setting before portdefinition, if need flip dimensions |
| // out port flip will be set here |
| if (m_bDimensionsNeedFlip && !m_bIsOutFlipDone) { |
| DEBUG_PRINT_HIGH("flip out port dimension in portdefinition"); |
| OMX_ERRORTYPE err = swvenc_do_flip_outport(); |
| m_bIsOutFlipDone = true; |
| DEBUG_PRINT_HIGH("Out Port Definition: rotation (%d), flipped WxH (%d x %d)", |
| m_sConfigFrameRotation.nRotation, |
| m_sOutPortDef.format.video.nFrameWidth, |
| m_sOutPortDef.format.video.nFrameHeight); |
| } |
| m_bIsOutFrameSizeSet = true; |
| } |
| 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", |
| portFmt->eColorFormat); |
| SWVENC_COLOR_FORMAT color_format; |
| |
| /* set the driver with the corresponding values */ |
| if (PORT_INDEX_IN == portFmt->nPortIndex) |
| { |
| if (portFmt->eColorFormat == |
| ((OMX_COLOR_FORMATTYPE) QOMX_COLOR_FormatAndroidOpaque)) |
| { |
| /* meta_mode = 2 (kMetadataBufferTypeGrallocSource) */ |
| m_sInPortFormat.eColorFormat = |
| (OMX_COLOR_FORMATTYPE) QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m; |
| color_format = SWVENC_COLOR_FORMAT_NV12; |
| mUseProxyColorFormat = true; |
| m_input_msg_id = OMX_COMPONENT_GENERATE_ETB_OPQ; |
| } |
| else |
| { |
| m_sInPortFormat.eColorFormat = portFmt->eColorFormat; |
| if ((portFmt->eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) || |
| (portFmt->eColorFormat == |
| ((OMX_COLOR_FORMATTYPE) QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m))) |
| { |
| color_format = SWVENC_COLOR_FORMAT_NV12; |
| } |
| else if (portFmt->eColorFormat == |
| ((OMX_COLOR_FORMATTYPE) QOMX_COLOR_FormatYVU420SemiPlanar)) |
| { |
| color_format = SWVENC_COLOR_FORMAT_NV21; |
| } |
| else |
| { |
| DEBUG_PRINT_ERROR("%s: OMX_IndexParamVideoPortFormat %d invalid", |
| __FUNCTION__, |
| portFmt->eColorFormat); |
| RETURN(OMX_ErrorBadParameter); |
| } |
| m_input_msg_id = OMX_COMPONENT_GENERATE_ETB; |
| mUseProxyColorFormat = false; |
| } |
| m_sInPortDef.format.video.eColorFormat = m_sInPortFormat.eColorFormat; |
| /* set the input color format */ |
| Prop.id = SWVENC_PROPERTY_ID_COLOR_FORMAT; |
| Prop.info.color_format = color_format; |
| Ret = swvenc_setproperty(m_hSwVenc, &Prop); |
| if (Ret != SWVENC_S_SUCCESS) |
| { |
| DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)", |
| __FUNCTION__, Ret); |
| RETURN(OMX_ErrorUnsupportedSetting); |
| } |
| |
| /* set the input frame-rate */ |
| if (portFmt->xFramerate != 0) |
| { |
| Ret = swvenc_set_frame_rate(portFmt->xFramerate >> 16); |
| if (Ret != SWVENC_S_SUCCESS) |
| { |
| DEBUG_PRINT_ERROR("%s, swvenc_set_frame_rate failed (%d)", |
| __FUNCTION__, Ret); |
| //RETURN(OMX_ErrorUnsupportedSetting); |
| } |
| m_sInPortFormat.xFramerate = portFmt->xFramerate; |
| } |
| } |
| break; |
| } |
| |
| case OMX_IndexParamVideoInit: |
| { |
| OMX_PORT_PARAM_TYPE* pParam = (OMX_PORT_PARAM_TYPE*)(paramData); |
| DEBUG_PRINT_LOW("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 (m_max_allowed_bitrate_check) |
| { |
| //TBD: to add bitrate check |
| } |
| |
| /* set the output bit-rate */ |
| Ret = swvenc_set_bit_rate(pParam->nTargetBitrate); |
| if (Ret != SWVENC_S_SUCCESS) |
| { |
| DEBUG_PRINT_ERROR("%s, swvenc_set_bit_rate failed (%d)", |
| __FUNCTION__, Ret); |
| RETURN(OMX_ErrorUnsupportedSetting); |
| } |
| |
| /* set the RC-mode */ |
| Ret = swvenc_set_rc_mode(pParam->eControlRate); |
| if (Ret != SWVENC_S_SUCCESS) |
| { |
| DEBUG_PRINT_ERROR("%s, swvenc_set_rc_mode failed (%d)", |
| __FUNCTION__, Ret); |
| RETURN(OMX_ErrorUnsupportedSetting); |
| } |
| |
| m_sParamBitrate.nTargetBitrate = pParam->nTargetBitrate; |
| m_sParamBitrate.eControlRate = pParam->eControlRate; |
| m_sConfigBitrate.nEncodeBitrate = pParam->nTargetBitrate; |
| m_sInPortDef.format.video.nBitrate = pParam->nTargetBitrate; |
| m_sOutPortDef.format.video.nBitrate = pParam->nTargetBitrate; |
| DEBUG_PRINT_LOW("bitrate = %u", m_sOutPortDef.format.video.nBitrate); |
| break; |
| } |
| |
| case OMX_IndexParamVideoMpeg4: |
| { |
| OMX_VIDEO_PARAM_MPEG4TYPE* pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData; |
| |
| DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4"); |
| |
| if (pParam->nBFrames) |
| { |
| DEBUG_PRINT_ERROR("Warning: B frames not supported"); |
| } |
| |
| /* set the intra period */ |
| Ret = swvenc_set_intra_period(pParam->nPFrames,pParam->nBFrames); |
| if (Ret != SWVENC_S_SUCCESS) |
| { |
| DEBUG_PRINT_ERROR("%s, swvenc_set_intra_period failed (%d)", |
| __FUNCTION__, Ret); |
| RETURN(OMX_ErrorUnsupportedSetting); |
| } |
| else |
| { |
| m_sIntraperiod.nPFrames = pParam->nPFrames; |
| m_sIntraperiod.nBFrames = pParam->nBFrames; |
| } |
| |
| /* set profile/level */ |
| if (pParam->eProfile && pParam->eLevel) |
| { |
| DEBUG_PRINT_LOW("pParam->eProfile : %d, pParam->eLevel : %d", pParam->eProfile, pParam->eLevel); |
| Ret = swvenc_set_profile_level(pParam->eProfile, pParam->eLevel); |
| if (Ret != SWVENC_S_SUCCESS) |
| { |
| DEBUG_PRINT_ERROR("%sm swvenc_set_profile_level failed (%d)", |
| __FUNCTION__, Ret); |
| RETURN(OMX_ErrorUnsupportedSetting); |
| } |
| else |
| { |
| m_sParamProfileLevel.eProfile = pParam->eProfile; |
| m_sParamProfileLevel.eLevel = pParam->eLevel; |
| } |
| } |
| |
| // NOTE: m_sParamMPEG4.eProfile/eLevel may be overwritten to 0 if client didn't set them |
| 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"); |
| |
| /* set the intra period */ |
| Ret = swvenc_set_intra_period(pParam->nPFrames,pParam->nBFrames); |
| if (Ret != SWVENC_S_SUCCESS) |
| { |
| DEBUG_PRINT_ERROR("%s, swvenc_set_intra_period failed (%d)", |
| __FUNCTION__, Ret); |
| RETURN(OMX_ErrorUnsupportedSetting); |
| } |
| else |
| { |
| m_sIntraperiod.nPFrames = pParam->nPFrames; |
| m_sIntraperiod.nBFrames = pParam->nBFrames; |
| } |
| |
| /* set profile/level */ |
| if (pParam->eProfile && pParam->eLevel) |
| { |
| DEBUG_PRINT_LOW("pParam->eProfile : %d, pParam->eLevel : %d", pParam->eProfile, pParam->eLevel); |
| Ret = swvenc_set_profile_level(pParam->eProfile, pParam->eLevel); |
| if (Ret != SWVENC_S_SUCCESS) |
| { |
| DEBUG_PRINT_ERROR("%sm swvenc_set_profile_level failed (%d)", |
| __FUNCTION__, Ret); |
| RETURN(OMX_ErrorUnsupportedSetting); |
| } |
| else |
| { |
| m_sParamProfileLevel.eProfile = pParam->eProfile; |
| m_sParamProfileLevel.eLevel = pParam->eLevel; |
| } |
| } |
| |
| // NOTE: m_sParamH263.eProfile/eLevel may be overwritten to 0 if client didn't set them |
| memcpy(&m_sParamH263,pParam, sizeof(struct OMX_VIDEO_PARAM_H263TYPE)); |
| break; |
| } |
| |
| case OMX_IndexParamVideoProfileLevelCurrent: |
| { |
| OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData; |
| |
| DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoProfileLevelCurrent"); |
| |
| /* set the profile and level */ |
| Ret = swvenc_set_profile_level(pParam->eProfile,pParam->eLevel); |
| if (Ret != SWVENC_S_SUCCESS) |
| { |
| DEBUG_PRINT_ERROR("%s, swvenc_set_rc_mode failed (%d)", |
| __FUNCTION__, Ret); |
| RETURN(OMX_ErrorUnsupportedSetting); |
| } |
| |
| |
| m_sParamProfileLevel.eProfile = pParam->eProfile; |
| m_sParamProfileLevel.eLevel = pParam->eLevel; |
| |
| if (SWVENC_CODEC_MPEG4 == m_codec) |
| { |
| m_sParamMPEG4.eProfile = (OMX_VIDEO_MPEG4PROFILETYPE)m_sParamProfileLevel.eProfile; |
| m_sParamMPEG4.eLevel = (OMX_VIDEO_MPEG4LEVELTYPE)m_sParamProfileLevel.eLevel; |
| DEBUG_PRINT_LOW("MPEG4 profile = %d, level = %d", m_sParamMPEG4.eProfile, |
| m_sParamMPEG4.eLevel); |
| } |
| else if (SWVENC_CODEC_H263 == m_codec) |
| { |
| m_sParamH263.eProfile = (OMX_VIDEO_H263PROFILETYPE)m_sParamProfileLevel.eProfile; |
| m_sParamH263.eLevel = (OMX_VIDEO_H263LEVELTYPE)m_sParamProfileLevel.eLevel; |
| DEBUG_PRINT_LOW("H263 profile = %d, level = %d", m_sParamH263.eProfile, |
| m_sParamH263.eLevel); |
| } |
| break; |
| } |
| |
| case OMX_IndexParamStandardComponentRole: |
| { |
| OMX_PARAM_COMPONENTROLETYPE *comp_role; |
| comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData; |
| DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s", |
| 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"); |
| RETURN(OMX_ErrorIncorrectStateOperation); |
| } |
| |
| if (SWVENC_CODEC_MPEG4 == m_codec) |
| { |
| 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", comp_role->cRole); |
| eRet = OMX_ErrorUnsupportedSetting; |
| } |
| } |
| else if (SWVENC_CODEC_H263 == m_codec) |
| { |
| 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", comp_role->cRole); |
| eRet =OMX_ErrorUnsupportedSetting; |
| } |
| } |
| else |
| { |
| DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown param %s", 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"); |
| RETURN(OMX_ErrorIncorrectStateOperation); |
| } |
| OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData; |
| DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %u", |
| priorityMgmtype->nGroupID); |
| |
| DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %u", |
| 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", |
| bufferSupplierType->eBufferSupplier); |
| if ( (bufferSupplierType->nPortIndex == 0) || |
| (bufferSupplierType->nPortIndex ==1) |
| ) |
| { |
| m_sInBufSupplier.eBufferSupplier = bufferSupplierType->eBufferSupplier; |
| } |
| else |
| { |
| eRet = OMX_ErrorBadPortIndex; |
| } |
| |
| break; |
| |
| } |
| |
| case OMX_IndexParamVideoQuantization: |
| { |
| // this is applicable only for RC-off case |
| DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoQuantization"); |
| OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp = (OMX_VIDEO_PARAM_QUANTIZATIONTYPE*) paramData; |
| if (session_qp->nPortIndex == PORT_INDEX_OUT) |
| { |
| Prop.id = SWVENC_PROPERTY_ID_QP; |
| Prop.info.qp.qp_i = session_qp->nQpI; |
| Prop.info.qp.qp_p = session_qp->nQpP; |
| Prop.info.qp.qp_b = session_qp->nQpB; |
| |
| Ret = swvenc_setproperty(m_hSwVenc, &Prop); |
| if (Ret != SWVENC_S_SUCCESS) |
| { |
| DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)", |
| __FUNCTION__, Ret); |
| RETURN(OMX_ErrorUnsupportedSetting); |
| } |
| |
| m_sSessionQuantization.nQpI = session_qp->nQpI; |
| m_sSessionQuantization.nQpP = session_qp->nQpP; |
| m_sSessionQuantization.nQpB = session_qp->nQpB; |
| } |
| else |
| { |
| DEBUG_PRINT_ERROR("ERROR: Unsupported port Index for Session QP setting"); |
| eRet = OMX_ErrorBadPortIndex; |
| } |
| break; |
| } |
| |
| case OMX_QcomIndexParamVideoIPBQPRange: |
| { |
| DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoIPBQPRange"); |
| OMX_QCOM_VIDEO_PARAM_IPB_QPRANGETYPE *session_qp_range = (OMX_QCOM_VIDEO_PARAM_IPB_QPRANGETYPE*) paramData; |
| if (session_qp_range->nPortIndex == PORT_INDEX_OUT) |
| { |
| Prop.id = SWVENC_PROPERTY_ID_QP_RANGE; |
| Prop.info.qp_range.min_qp_packed = ((session_qp_range->minBQP << 16) | |
| (session_qp_range->minPQP << 8) | |
| (session_qp_range->minIQP << 0)); |
| Prop.info.qp_range.max_qp_packed = ((session_qp_range->maxBQP << 16) | |
| (session_qp_range->maxPQP << 8) | |
| (session_qp_range->maxIQP << 0)); |
| |
| Ret = swvenc_setproperty(m_hSwVenc, &Prop); |
| if (Ret != SWVENC_S_SUCCESS) |
| { |
| DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)", |
| __FUNCTION__, Ret); |
| RETURN(OMX_ErrorUnsupportedSetting); |
| } |
| |
| m_sSessionQPRange.minIQP = session_qp_range->minIQP; |
| m_sSessionQPRange.maxIQP = session_qp_range->maxIQP; |
| m_sSessionQPRange.minPQP = session_qp_range->minPQP; |
| m_sSessionQPRange.maxPQP = session_qp_range->maxPQP; |
| m_sSessionQPRange.minBQP = session_qp_range->minBQP; |
| m_sSessionQPRange.maxBQP = session_qp_range->maxBQP; |
| } |
| else |
| { |
| DEBUG_PRINT_ERROR("ERROR: Unsupported port Index for Session QP range setting"); |
| 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"); |
| OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* pParam = |
| (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE*)paramData; |
| |
| /* HEC */ |
| if (m_codec == SWVENC_CODEC_MPEG4) |
| { |
| Prop.id = SWVENC_PROPERTY_ID_MPEG4_HEC; |
| Prop.info.mpeg4_hec = pParam->bEnableHEC; |
| |
| Ret = swvenc_setproperty(m_hSwVenc, &Prop); |
| if (Ret != SWVENC_S_SUCCESS) |
| { |
| DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)", |
| __FUNCTION__, Ret); |
| RETURN(OMX_ErrorUndefined); |
| } |
| |
| /* Data partitioning */ |
| Prop.id = SWVENC_PROPERTY_ID_MPEG4_DP; |
| Prop.info.mpeg4_dp = pParam->bEnableDataPartitioning; |
| |
| Ret = swvenc_setproperty(m_hSwVenc, &Prop); |
| if (Ret != SWVENC_S_SUCCESS) |
| { |
| DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)", |
| __FUNCTION__, Ret); |
| RETURN(OMX_ErrorUndefined); |
| } |
| } |
| |
| /* RVLC */ |
| if (pParam->bEnableRVLC) |
| { |
| DEBUG_PRINT_ERROR("%s, RVLC not support", __FUNCTION__); |
| } |
| |
| /* Re-sync Marker */ |
| Prop.id = SWVENC_PROPERTY_ID_SLICE_CONFIG; |
| if ( (m_codec != SWVENC_CODEC_H263) && (pParam->bEnableDataPartitioning) ) |
| { |
| DEBUG_PRINT_ERROR("DataPartioning are not Supported for this codec"); |
| break; |
| } |
| if ( (m_codec != SWVENC_CODEC_H263) && (pParam->nResynchMarkerSpacing) ) |
| { |
| Prop.info.slice_config.mode = SWVENC_SLICE_MODE_BYTE; |
| Prop.info.slice_config.size = pParam->nResynchMarkerSpacing; |
| } |
| else if ( (SWVENC_CODEC_H263 == m_codec) && (pParam->bEnableResync) ) |
| { |
| Prop.info.slice_config.mode = SWVENC_SLICE_MODE_GOB; |
| Prop.info.slice_config.size = 0; |
| Ret = swvenc_setproperty(m_hSwVenc, &Prop); |
| if (Ret != SWVENC_S_SUCCESS) |
| { |
| DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)", |
| __FUNCTION__, Ret); |
| RETURN(OMX_ErrorUndefined); |
| } |
| } |
| else |
| { |
| Prop.info.slice_config.mode = SWVENC_SLICE_MODE_OFF; |
| Prop.info.slice_config.size = 0; |
| } |
| |
| memcpy(&m_sErrorCorrection,pParam, sizeof(m_sErrorCorrection)); |
| break; |
| } |
| |
| case OMX_IndexParamVideoIntraRefresh: |
| { |
| DEBUG_PRINT_LOW("set_param:OMX_IndexParamVideoIntraRefresh"); |
| OMX_VIDEO_PARAM_INTRAREFRESHTYPE* pParam = |
| (OMX_VIDEO_PARAM_INTRAREFRESHTYPE*)paramData; |
| |
| Ret = swvenc_set_intra_refresh(pParam); |
| if (Ret != SWVENC_S_SUCCESS) |
| { |
| DEBUG_PRINT_ERROR("%s, swvenc_set_intra_refresh failed (%d)", |
| __FUNCTION__, Ret); |
| RETURN(OMX_ErrorUnsupportedSetting); |
| } |
| |
| memcpy(&m_sIntraRefresh, pParam, sizeof(m_sIntraRefresh)); |
| break; |
| } |
| |
| case OMX_QcomIndexParamVideoMetaBufferMode: |
| { |
| StoreMetaDataInBuffersParams *pParam = |
| (StoreMetaDataInBuffersParams*)paramData; |
| DEBUG_PRINT_HIGH("set_parameter:OMX_QcomIndexParamVideoMetaBufferMode: " |
| "port_index = %u, meta_mode = %d", pParam->nPortIndex, pParam->bStoreMetaData); |
| |
| if (pParam->nPortIndex == PORT_INDEX_IN) |
| { |
| if (pParam->bStoreMetaData != meta_mode_enable) |
| { |
| meta_mode_enable = pParam->bStoreMetaData; |
| if (!meta_mode_enable) |
| { |
| Ret = swvenc_get_buffer_req(&m_sOutPortDef.nBufferCountMin, |
| &m_sOutPortDef.nBufferCountActual, |
| &m_sOutPortDef.nBufferSize, |
| &m_sOutPortDef.nBufferAlignment, |
| m_sOutPortDef.nPortIndex); |
| if (Ret != SWVENC_S_SUCCESS) |
| { |
| DEBUG_PRINT_ERROR("ERROR: %s, swvenc_get_buffer_req failed (%d)", __FUNCTION__, |
| Ret); |
| eRet = OMX_ErrorUndefined; |
| break; |
| } |
| } |
| } |
| } |
| else if (pParam->nPortIndex == PORT_INDEX_OUT && secure_session) |
| { |
| if (pParam->bStoreMetaData != meta_mode_enable) |
| { |
| meta_mode_enable = pParam->bStoreMetaData; |
| } |
| } |
| else |
| { |
| if (pParam->bStoreMetaData) |
| { |
| DEBUG_PRINT_ERROR("set_parameter: metamode is " |
| "valid for input port only"); |
| eRet = OMX_ErrorUnsupportedIndex; |
| } |
| } |
| } |
| break; |
| |
| case OMX_QcomIndexParamIndexExtraDataType: |
| { |
| DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamIndexExtraDataType"); |
| QOMX_INDEXEXTRADATATYPE *pParam = (QOMX_INDEXEXTRADATATYPE *)paramData; |
| OMX_U32 mask = 0; |
| |
| if (pParam->nIndex == (OMX_INDEXTYPE)OMX_ExtraDataVideoEncoderSliceInfo) |
| { |
| if (pParam->nPortIndex == PORT_INDEX_OUT) |
| { |
| mask = VEN_EXTRADATA_SLICEINFO; |
| |
| DEBUG_PRINT_HIGH("SliceInfo extradata %s", |
| ((pParam->bEnabled == OMX_TRUE) ? "enabled" : "disabled")); |
| } |
| else |
| { |
| DEBUG_PRINT_ERROR("set_parameter: Slice information is " |
| "valid for output port only"); |
| eRet = OMX_ErrorUnsupportedIndex; |
| break; |
| } |
| } |
| else if (pParam->nIndex == (OMX_INDEXTYPE)OMX_ExtraDataVideoEncoderMBInfo) |
| { |
| if (pParam->nPortIndex == PORT_INDEX_OUT) |
| { |
| mask = VEN_EXTRADATA_MBINFO; |
| |
| DEBUG_PRINT_HIGH("MBInfo extradata %s", |
| ((pParam->bEnabled == OMX_TRUE) ? "enabled" : "disabled")); |
| } |
| else |
| { |
| DEBUG_PRINT_ERROR("set_parameter: MB information is " |
| "valid for output port only"); |
| eRet = OMX_ErrorUnsupportedIndex; |
| break; |
| } |
| } |
| else |
| { |
| DEBUG_PRINT_ERROR("set_parameter: unsupported extrdata index (%x)", |
| pParam->nIndex); |
| eRet = OMX_ErrorUnsupportedIndex; |
| break; |
| } |
| |
| |
| if (pParam->bEnabled == OMX_TRUE) |
| { |
| m_sExtraData |= mask; |
| } |
| else |
| { |
| m_sExtraData &= ~mask; |
| } |
| |
| #if 0 |
| // TBD: add setprop to swvenc once the support is added |
| if (handle->venc_set_param((OMX_PTR)!!(m_sExtraData & mask), |
| (OMX_INDEXTYPE)pParam->nIndex) != true) |
| { |
| DEBUG_PRINT_ERROR("ERROR: Setting Extradata (%x) failed", pParam->nIndex); |
| RETURN(OMX_ErrorUnsupportedSetting); |
| } |
| else |
| #endif |
| { |
| m_sOutPortDef.nPortIndex = PORT_INDEX_OUT; |
| bResult = dev_get_buf_req(&m_sOutPortDef.nBufferCountMin, |
| &m_sOutPortDef.nBufferCountActual, |
| &m_sOutPortDef.nBufferSize, |
| m_sOutPortDef.nPortIndex); |
| if (false == bResult) |
| { |
| DEBUG_PRINT_ERROR("dev_get_buf_req failed"); |
| eRet = OMX_ErrorUndefined; |
| break; |
| } |
| |
| DEBUG_PRINT_HIGH("updated out_buf_req: buffer cnt=%u, " |
| "count min=%u, buffer size=%u", |
| m_sOutPortDef.nBufferCountActual, |
| m_sOutPortDef.nBufferCountMin, |
| m_sOutPortDef.nBufferSize); |
| } |
| break; |
| } |
| |
| case OMX_QcomIndexParamVideoMaxAllowedBitrateCheck: |
| { |
| QOMX_EXTNINDEX_PARAMTYPE* pParam = |
| (QOMX_EXTNINDEX_PARAMTYPE*)paramData; |
| if (pParam->nPortIndex == PORT_INDEX_OUT) |
| { |
| 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(%u)", pParam->nPortIndex); |
| RETURN(OMX_ErrorBadPortIndex); |
| } |
| break; |
| } |
| |
| case OMX_QcomIndexEnableSliceDeliveryMode: |
| { |
| QOMX_EXTNINDEX_PARAMTYPE* pParam = |
| (QOMX_EXTNINDEX_PARAMTYPE*)paramData; |
| if (pParam->nPortIndex == PORT_INDEX_OUT) |
| { |
| //TBD: add setprop to swvenc once the support is added |
| #if 0 |
| if (!handle->venc_set_param(paramData, |
| (OMX_INDEXTYPE)OMX_QcomIndexEnableSliceDeliveryMode)) { |
| DEBUG_PRINT_ERROR("ERROR: Request for setting slice delivery mode failed"); |
| RETURN( OMX_ErrorUnsupportedSetting; |
| } |
| #endif |
| { |
| 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(%u)", pParam->nPortIndex); |
| RETURN(OMX_ErrorBadPortIndex); |
| } |
| break; |
| } |
| |
| case OMX_QcomIndexEnableH263PlusPType: |
| { |
| QOMX_EXTNINDEX_PARAMTYPE* pParam = |
| (QOMX_EXTNINDEX_PARAMTYPE*)paramData; |
| DEBUG_PRINT_LOW("OMX_QcomIndexEnableH263PlusPType"); |
| if (pParam->nPortIndex == PORT_INDEX_OUT) |
| { |
| DEBUG_PRINT_ERROR("ERROR: Request for setting PlusPType failed"); |
| RETURN(OMX_ErrorUnsupportedSetting); |
| } |
| else |
| { |
| DEBUG_PRINT_ERROR("ERROR: OMX_QcomIndexEnableH263PlusPType " |
| "called on wrong port(%u)", pParam->nPortIndex); |
| RETURN(OMX_ErrorBadPortIndex); |
| } |
| break; |
| } |
| |
| case OMX_QcomIndexParamPeakBitrate: |
| { |
| DEBUG_PRINT_ERROR("ERROR: Setting peak bitrate"); |
| RETURN(OMX_ErrorUnsupportedSetting); |
| break; |
| } |
| |
| case QOMX_IndexParamVideoInitialQp: |
| { |
| // TBD: applicable to RC-on case only |
| DEBUG_PRINT_ERROR("ERROR: Setting Initial QP for RC-on case"); |
| RETURN(OMX_ErrorNone); |
| break; |
| } |
| |
| |
| case OMX_QcomIndexParamSetMVSearchrange: |
| { |
| DEBUG_PRINT_ERROR("ERROR: Setting Searchrange"); |
| RETURN(OMX_ErrorUnsupportedSetting); |
| break; |
| } |
| |
| case OMX_QTIIndexParamEnableAVTimerTimestamps: |
| { |
| VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE); |
| QOMX_ENABLETYPE *pParam = (QOMX_ENABLETYPE *)paramData; |
| m_bUseAVTimerTimestamps = pParam->bEnable == OMX_TRUE; |
| DEBUG_PRINT_INFO("AVTimer timestamps %s", m_bUseAVTimerTimestamps ? "enabled" : "disabled"); |
| break; |
| } |
| |
| default: |
| { |
| DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown param %d", paramIndex); |
| eRet = OMX_ErrorUnsupportedIndex; |
| break; |
| } |
| } |
| |
| RETURN(eRet); |
| } |
| |
| OMX_ERRORTYPE omx_venc::set_config |
| ( |
| OMX_IN OMX_HANDLETYPE hComp, |
| OMX_IN OMX_INDEXTYPE configIndex, |
| OMX_IN OMX_PTR configData |
| ) |
| { |
| ENTER_FUNC(); |
| |
| SWVENC_STATUS SwStatus; |
| |
| (void)hComp; |
| |
| 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); |
| } |
| |
| switch ((int)configIndex) |
| { |
| case OMX_IndexConfigVideoBitrate: |
| { |
| OMX_VIDEO_CONFIG_BITRATETYPE* pParam = |
| reinterpret_cast<OMX_VIDEO_CONFIG_BITRATETYPE*>(configData); |
| DEBUG_PRINT_HIGH("set_config(): OMX_IndexConfigVideoBitrate (%u)", pParam->nEncodeBitrate); |
| |
| if (pParam->nPortIndex == PORT_INDEX_OUT) |
| { |
| SwStatus = swvenc_set_bit_rate(pParam->nEncodeBitrate); |
| if (SwStatus != SWVENC_S_SUCCESS) |
| { |
| DEBUG_PRINT_ERROR("%s, swvenc_set_bit_rate failed (%d)", |
| __FUNCTION__, SwStatus); |
| 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<OMX_CONFIG_FRAMERATETYPE*>(configData); |
| DEBUG_PRINT_HIGH("set_config(): OMX_IndexConfigVideoFramerate (0x%x)", pParam->xEncodeFramerate); |
| |
| if (pParam->nPortIndex == PORT_INDEX_OUT) |
| { |
| SwStatus = swvenc_set_frame_rate(pParam->xEncodeFramerate >> 16); |
| if (SwStatus != SWVENC_S_SUCCESS) |
| { |
| DEBUG_PRINT_ERROR("%s, swvenc_set_frame_rate failed (%d)", |
| __FUNCTION__, SwStatus); |
| 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<QOMX_VIDEO_INTRAPERIODTYPE*>(configData); |
| DEBUG_PRINT_HIGH("set_config(): QOMX_IndexConfigVideoIntraperiod"); |
| |
| if (pParam->nPortIndex == PORT_INDEX_OUT) |
| { |
| if (pParam->nBFrames > 0) |
| { |
| DEBUG_PRINT_ERROR("B frames not supported"); |
| RETURN(OMX_ErrorUnsupportedSetting); |
| } |
| |
| DEBUG_PRINT_HIGH("Old: P/B frames = %u/%u, New: P/B frames = %u/%u", |
| 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); |
| } |
| |
| /* set the intra period */ |
| SwStatus = swvenc_set_intra_period(pParam->nPFrames,pParam->nBFrames); |
| if (SwStatus != SWVENC_S_SUCCESS) |
| { |
| DEBUG_PRINT_ERROR("%s, swvenc_set_intra_period failed (%d)", |
| __FUNCTION__, SwStatus); |
| 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 |
| { |
| 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<OMX_CONFIG_INTRAREFRESHVOPTYPE*>(configData); |
| DEBUG_PRINT_HIGH("set_config(): OMX_IndexConfigVideoIntraVOPRefresh"); |
| |
| if (pParam->nPortIndex == PORT_INDEX_OUT) |
| { |
| |
| SWVENC_PROPERTY Prop; |
| |
| Prop.id = SWVENC_PROPERTY_ID_IFRAME_REQUEST; |
| |
| SwStatus = swvenc_setproperty(m_hSwVenc, &Prop); |
| if (SwStatus != SWVENC_S_SUCCESS) |
| { |
| DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)", |
| __FUNCTION__, SwStatus); |
| 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: |
| { |
| if (m_codec == SWVENC_CODEC_H263) { |
| OMX_CONFIG_ROTATIONTYPE *pParam = |
| reinterpret_cast<OMX_CONFIG_ROTATIONTYPE *>(configData); |
| DEBUG_PRINT_HIGH("set_config(): OMX_IndexConfigCommonRotate"); |
| m_bIsRotationSupported = true; |
| |
| // XXX: diffrent from h/w encoder rotation, h/w encoder only need to update out |
| // port info. For h/w encoder, rotation is processed in h/w encoder firmware, this |
| // is after ETB, so input info doesn't change. While s/w encoder rotation is |
| // processed before ETB, so need to change in port info. |
| if (pParam->nPortIndex != PORT_INDEX_IN) { |
| DEBUG_PRINT_ERROR("ERROR: Unsupported port index: %u", |
| (unsigned int)pParam->nPortIndex); |
| RETURN(OMX_ErrorBadPortIndex); |
| } |
| if (pParam->nRotation == 0 || |
| pParam->nRotation == 90 || |
| pParam->nRotation == 180 || |
| pParam->nRotation == 270) { |
| DEBUG_PRINT_HIGH("set_config(): Rotation Angle %u", |
| (unsigned int)pParam->nRotation); |
| if (m_pIpbuffers == nullptr) { |
| // m_pIpbuffers is used to store original ipbuffer, because after rotation, |
| // will send new rotated ipbuffer to encoder, in EBD will also get new |
| // ipbuffer. so we can restore original ipbuffer from to m_pIpbuffers and |
| // return it to framework |
| m_pIpbuffers = new SWVENC_IPBUFFER[m_sInPortDef.nBufferCountActual]; |
| } |
| if (m_pIpbuffers == nullptr) { |
| DEBUG_PRINT_ERROR("create ipbuffer array failed"); |
| return OMX_ErrorUndefined; |
| } |
| } else { |
| DEBUG_PRINT_ERROR("ERROR: Unsupported Rotation Angle %u", |
| (unsigned int)pParam->nRotation); |
| RETURN(OMX_ErrorUnsupportedSetting); |
| } |
| if (m_sConfigFrameRotation.nRotation == pParam->nRotation) { |
| DEBUG_PRINT_HIGH("set_config(): rotation (%d) not changed", pParam->nRotation); |
| break; |
| } |
| |
| OMX_S32 rotation_diff = pParam->nRotation - m_sConfigFrameRotation.nRotation; |
| if (rotation_diff < 0) |
| rotation_diff = -rotation_diff; |
| if (rotation_diff == 90 || rotation_diff == 270) { |
| // in the case that rotation angle is 90 or 270 degree, if original buffer size |
| // is 640x480, after rotation, rotated buffer size will be 480x640, so need to |
| // flip dimensions in such cases. |
| m_bDimensionsNeedFlip = true; |
| OMX_ERRORTYPE err = OMX_ErrorNone; |
| // flip and set new dimensions must be called after real dimension set |
| if (m_bIsInFrameSizeSet && !m_bIsInFlipDone) { |
| err = swvenc_do_flip_inport(); |
| if (err != OMX_ErrorNone) { |
| DEBUG_PRINT_ERROR("set_config(): flipping failed"); |
| RETURN(err); |
| } |
| |
| m_bIsInFlipDone = true; |
| } else { |
| DEBUG_PRINT_HIGH("set_config(): in port frame size isn't set, will do flip later"); |
| } |
| if (m_bIsOutFrameSizeSet && !m_bIsOutFlipDone) { |
| err = swvenc_do_flip_outport(); |
| m_bIsOutFlipDone = true; |
| DEBUG_PRINT_HIGH("set_config(): out port flip done, rotation (%d), flipped WxH (%d x %d)", |
| pParam->nRotation, |
| m_sOutPortDef.format.video.nFrameWidth, |
| m_sOutPortDef.format.video.nFrameHeight); |
| } else { |
| DEBUG_PRINT_HIGH("set_config(): out port frame size isn't set, will do flip later"); |
| } |
| } else { |
| m_bDimensionsNeedFlip = false; |
| DEBUG_PRINT_HIGH("set_config(): rotation (%d), no need to flip WxH", |
| pParam->nRotation); |
| } |
| |
| // save rotation angle |
| m_sConfigFrameRotation.nRotation = pParam->nRotation; |
| break; |
| } else { |
| DEBUG_PRINT_ERROR("ERROR: rotation is not supported for current codec"); |
| RETURN(OMX_ErrorUnsupportedSetting); |
| |
| |
| } |
| } |
| case OMX_IndexConfigAndroidVendorExtension: |
| { |
| OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext = |
| reinterpret_cast<OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *>(configData); |
| OMX_ERRORTYPE err = set_vendor_extension_config(ext); |
| RETURN(err); |
| } |
| default: |
| DEBUG_PRINT_ERROR("ERROR: unsupported index %d", (int) configIndex); |
| RETURN(OMX_ErrorUnsupportedSetting); |
| break; |
| } |
| |
| EXIT_FUNC(); |
| |
| RETURN(OMX_ErrorNone); |
| } |
| |
| OMX_ERRORTYPE omx_venc::swvenc_do_flip_inport() { |
| ENTER_FUNC(); |
| OMX_U32 inWidth = m_sInPortDef.format.video.nFrameWidth; |
| OMX_U32 inHeight = m_sInPortDef.format.video.nFrameHeight; |
| |
| // set new dimensions to encoder |
| SWVENC_PROPERTY Prop; |
| SWVENC_STATUS Ret = SWVENC_S_SUCCESS; |
| Prop.id = SWVENC_PROPERTY_ID_FRAME_SIZE; |
| Prop.info.frame_size.height = inWidth; |
| Prop.info.frame_size.width = inHeight; |
| |
| DEBUG_PRINT_HIGH("setting flipped dimensions to swencoder, WxH (%d x %d)", |
| inWidth, inHeight); |
| Ret = swvenc_setproperty(m_hSwVenc, &Prop); |
| if (Ret != SWVENC_S_SUCCESS) { |
| // currently, set dimensions to encoder can only be called when encoder is |
| // in init state, while setVendorParameter() in ACodec can be called when |
| // OMX component is in Executing state, in this case, encoder is in ready |
| // state, will report unsupported error. |
| DEBUG_PRINT_ERROR("ERROR: setting new dimension to encoder failed (%d)", |
| Ret); |
| return OMX_ErrorUnsupportedSetting; |
| } |
| |
| // don't flip in port dimensions m_sInPortDef.format.video.nFrameWidth(mFrameHeight) |
| // app may require this dimensions by get_parameter |
| |
| // update attributes, here dimensions are flipped, so use inHeight for calculating |
| // stride, inWidth for scanlines, and swapp parameters in venus size calculation |
| int stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, inHeight); |
| int scanlines = VENUS_Y_SCANLINES(COLOR_FMT_NV12, inWidth); |
| Prop.id = SWVENC_PROPERTY_ID_FRAME_ATTRIBUTES; |
| Prop.info.frame_attributes.stride_luma = stride; |
| Prop.info.frame_attributes.stride_chroma = stride; |
| Prop.info.frame_attributes.offset_luma = 0; |
| Prop.info.frame_attributes.offset_chroma = scanlines * stride; |
| Prop.info.frame_attributes.size = |
| VENUS_BUFFER_SIZE(COLOR_FMT_NV12, inHeight, inWidth); |
| |
| Ret = swvenc_setproperty(m_hSwVenc, &Prop); |
| if (Ret != SWVENC_S_SUCCESS) { |
| DEBUG_PRINT_ERROR("ERROR: update frame attributes failed (%d)", Ret); |
| return OMX_ErrorUnsupportedSetting; |
| } |
| |
| // till now, attributes of omx input port is different from sw encoder input port, |
| // omx input port stores original attributes, sw encoder input port stores flipped |
| // attributes. no need to update buffer requirements from sw encoder here, but need |
| // to update in output port, omx output port should also store flipped attrinutes |
| |
| EXIT_FUNC(); |
| return OMX_ErrorNone; |
| } |
| |
| OMX_ERRORTYPE omx_venc::swvenc_do_flip_outport() { |
| ENTER_FUNC(); |
| // for out port, no need to set dimensions to encoder |
| OMX_U32 outWidth = m_sOutPortDef.format.video.nFrameWidth; |
| OMX_U32 outHeight = m_sOutPortDef.format.video.nFrameHeight; |
| |
| // update out port info |
| m_sOutPortDef.format.video.nFrameWidth = outHeight; |
| m_sOutPortDef.format.video.nFrameHeight = outWidth; |
| |
| // attributes in sw encoder has been updated after flipping dimensions, so need to update |
| // omx out port buffer requirements, they should have the same attributes |
| DEBUG_PRINT_LOW("flip outport, o/p previous actual cnt = %u", m_sOutPortDef.nBufferCountActual); |
| DEBUG_PRINT_LOW("flip outport, o/p previous min cnt = %u", m_sOutPortDef.nBufferCountMin); |
| DEBUG_PRINT_LOW("flip outport, o/p previous buffersize = %u", m_sOutPortDef.nBufferSize); |
| |
| SWVENC_STATUS Ret = SWVENC_S_SUCCESS; |
| Ret = swvenc_get_buffer_req(&m_sOutPortDef.nBufferCountMin, |
| &m_sOutPortDef.nBufferCountActual, |
| &m_sOutPortDef.nBufferSize, |
| &m_sOutPortDef.nBufferAlignment, |
| PORT_INDEX_OUT); |
| if (Ret != SWVENC_S_SUCCESS) { |
| DEBUG_PRINT_ERROR("ERROR: %s, flip outport swvenc_get_buffer_req failed(%d)", __FUNCTION__, |
| Ret); |
| return OMX_ErrorUndefined; |
| } |
| |
| DEBUG_PRINT_LOW("flip outport, o/p new actual cnt = %u", m_sOutPortDef.nBufferCountActual); |
| DEBUG_PRINT_LOW("flip outport, o/p new min cnt = %u", m_sOutPortDef.nBufferCountMin); |
| DEBUG_PRINT_LOW("flip outport, o/p new buffersize = %u", m_sOutPortDef.nBufferSize); |
| |
| EXIT_FUNC(); |
| return OMX_ErrorNone; |
| } |
| |
| bool omx_venc::swvenc_do_rotate(int fd, SWVENC_IPBUFFER & ipbuffer, OMX_U32 index) { |
| // declarations and definitions of variables rotation needs |
| private_handle_t *privateHandle = nullptr; |
| |
| int s_width = m_sInPortDef.format.video.nFrameWidth; |
| int s_height = m_sInPortDef.format.video.nFrameHeight; |
| int d_width = m_bDimensionsNeedFlip ? s_height : s_width; |
| int d_height = m_bDimensionsNeedFlip ? s_width : s_height; |
| |
| uint32_t rotation = m_sConfigFrameRotation.nRotation; |
| |
| uint32_t usage = GraphicBuffer::USAGE_HW_TEXTURE | GraphicBuffer::USAGE_SW_READ_OFTEN | |
| GraphicBuffer::USAGE_SW_WRITE_OFTEN | GraphicBuffer::USAGE_HW_RENDER; |
| uint32_t dstusage = GraphicBuffer::USAGE_HW_TEXTURE | GraphicBuffer::USAGE_HW_VIDEO_ENCODER | |
| GraphicBuffer::USAGE_HW_RENDER | GraphicBuffer::USAGE_SW_READ_OFTEN | |
| GraphicBuffer::USAGE_SW_WRITE_OFTEN; |
| |
| int src_stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, s_width); |
| int src_scanlines = VENUS_Y_SCANLINES(COLOR_FMT_NV12, s_height); |
| int src_size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, s_width, s_height); |
| int dst_size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, d_width, d_height); |
| |
| uint32_t format = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS; |
| |
| // privateHandle is created for creating GraphicBuffer in rotation case |
| privateHandle = new private_handle_t(fd, ipbuffer.size, usage, BUFFER_TYPE_VIDEO, format, |
| src_stride, src_scanlines); |
| if (privateHandle == nullptr) { |
| DEBUG_PRINT_ERROR("failed to create private handle"); |
| return false; |
| } |
| |
| sp<GraphicBuffer> srcBuffer = new GraphicBuffer(s_width, s_height, format, 1, usage, |
| src_stride, (native_handle_t *)privateHandle, false); |
| if (srcBuffer.get() == NULL) { |
| DEBUG_PRINT_ERROR("create source buffer failed"); |
| swvenc_delete_pointer(privateHandle); |
| return false; |
| } |
| |
| // reuse dstBuffer |
| if (dstBuffer.get() == NULL) { |
| dstBuffer = new GraphicBuffer(d_width, d_height, format, dstusage); |
| } |
| if (dstBuffer.get() == NULL) { |
| DEBUG_PRINT_ERROR("create destination buffer failed"); |
| swvenc_delete_pointer(privateHandle); |
| return false; |
| } |
| SWVENC_STATUS ret = swvenc_rotateFrame(s_width, s_height, d_height, d_width, |
| rotation, srcBuffer->getNativeBuffer(), dstBuffer->getNativeBuffer()); |
| |
| if (ret == SWVENC_S_SUCCESS) { |
| void *buf = nullptr; |
| if (dstBuffer->lock(dstusage, &buf) == 0 && buf != nullptr) { |
| DEBUG_PRINT_HIGH("store original ipbuffer[p_buffer(%p), size(%d), filled_length(%d)], new ipbuffer[p_buffer(%p), size(%d), filled_length(%d)]", |
| ipbuffer.p_buffer, |
| ipbuffer.size, |
| ipbuffer.filled_length, |
| (unsigned char *)buf, |
| dst_size, |
| dst_size); |
| if (index >= m_sInPortDef.nBufferCountActual) { |
| DEBUG_PRINT_ERROR("incorrect buffer index"); |
| swvenc_delete_pointer(privateHandle); |
| return false; |
| } |
| m_pIpbuffers[index].size = ipbuffer.size; |
| m_pIpbuffers[index].filled_length = ipbuffer.filled_length; |
| m_pIpbuffers[index].p_buffer = ipbuffer.p_buffer; |
| ipbuffer.size = dst_size; |
| ipbuffer.filled_length = dst_size; |
| ipbuffer.p_buffer = (unsigned char *)buf; |
| dstBuffer->unlock(); |
| DEBUG_PRINT_HIGH("copy rotated buffer successfully"); |
| } else { |
| DEBUG_PRINT_ERROR("copy rotated buffer failed"); |
| swvenc_delete_pointer(privateHandle); |
| return false; |
| } |
| } else { |
| DEBUG_PRINT_ERROR("rotate failed"); |
| swvenc_delete_pointer(privateHandle); |
| return false; |
| } |
| |
| swvenc_delete_pointer(privateHandle); |
| return true; |
| } |
| |
| OMX_ERRORTYPE omx_venc::component_deinit(OMX_IN OMX_HANDLETYPE hComp) |
| { |
| ENTER_FUNC(); |
| |
| OMX_U32 i = 0; |
| DEBUG_PRINT_HIGH("omx_venc(): Inside component_deinit()"); |
| |
| (void)hComp; |
| |
| if (m_bIsRotationSupported) { |
| swvenc_rotation_deinit(); |
| if (m_pIpbuffers != nullptr) { |
| delete [] m_pIpbuffers; |
| } |
| } |
| |
| if (OMX_StateLoaded != m_state) |
| { |
| DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d", |
| m_state); |
| } |
| if (m_out_mem_ptr) |
| { |
| DEBUG_PRINT_LOW("Freeing the Output Memory"); |
| 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 && !meta_mode_enable ) |
| { |
| DEBUG_PRINT_LOW("Freeing the Input Memory"); |
| for (i=0; i<m_sInPortDef.nBufferCountActual; i++) |
| { |
| free_input_buffer (&m_inp_mem_ptr[i]); |
| } |
| |
| free(m_inp_mem_ptr); |
| m_inp_mem_ptr = NULL; |
| } |
| |
| /* Reset counters in msg queues */ |
| m_ftb_q.m_size=0; |
| m_cmd_q.m_size=0; |
| m_etb_q.m_size=0; |
| m_ftb_q.m_read = m_ftb_q.m_write =0; |
| m_cmd_q.m_read = m_cmd_q.m_write =0; |
| m_etb_q.m_read = m_etb_q.m_write =0; |
| |
| DEBUG_PRINT_HIGH("Calling swvenc_deinit()"); |
| swvenc_deinit(m_hSwVenc); |
| |
| DEBUG_PRINT_HIGH("OMX_Venc:Component Deinit"); |
| |
| RETURN(OMX_ErrorNone); |
| } |
| |
| OMX_U32 omx_venc::dev_stop(void) |
| { |
| ENTER_FUNC(); |
| |
| SWVENC_STATUS Ret; |
| |
| if (false == m_stopped) |
| { |
| Ret = swvenc_stop(m_hSwVenc); |
| if (Ret != SWVENC_S_SUCCESS) |
| { |
| DEBUG_PRINT_ERROR("%s, swvenc_stop failed (%d)", |
| __FUNCTION__, Ret); |
| RETURN(-1); |
| } |
| set_format = false; |
| m_stopped = true; |
| |
| /* post STOP_DONE event as start is synchronus */ |
| post_event (0, OMX_ErrorNone, OMX_COMPONENT_GENERATE_STOP_DONE); |
| } |
| |
| RETURN(0); |
| } |
| |
| OMX_U32 omx_venc::dev_pause(void) |
| { |
| ENTER_FUNC(); |
| // nothing to be done for sw encoder |
| |
| RETURN(true); |
| } |
| |
| OMX_U32 omx_venc::dev_resume(void) |
| { |
| ENTER_FUNC(); |
| // nothing to be done for sw encoder |
| |
| RETURN(true); |
| } |
| |
| OMX_U32 omx_venc::dev_start(void) |
| { |
| ENTER_FUNC(); |
| SWVENC_STATUS Ret; |
| Ret = swvenc_start(m_hSwVenc); |
| if (Ret != SWVENC_S_SUCCESS) |
| { |
| DEBUG_PRINT_ERROR("%s, swvenc_start failed (%d)", |
| __FUNCTION__, Ret); |
| RETURN(-1); |
| } |
| |
| m_stopped = false; |
| if (m_bIsRotationSupported){ |
| Ret = swvenc_rotation_init(); |
| if (Ret == SWVENC_S_UNSUPPORTED) { |
| DEBUG_PRINT_ERROR("ERROR: Rotation not supported for this target"); |
| m_bIsRotationSupported = false; |
| } |
| } |
| RETURN(0); |
| } |
| |
| OMX_U32 omx_venc::dev_flush(unsigned port) |
| { |
| ENTER_FUNC(); |
| SWVENC_STATUS Ret; |
| |
| (void)port; |
| Ret = swvenc_flush(m_hSwVenc); |
| if (Ret != SWVENC_S_SUCCESS) |
| { |
| DEBUG_PRINT_ERROR("%s, swvenc_flush failed (%d)", |
| __FUNCTION__, Ret); |
| RETURN(-1); |
| } |
| |
| RETURN(0); |
| } |
| |
| OMX_U32 omx_venc::dev_start_done(void) |
| { |
| ENTER_FUNC(); |
| |
| /* post START_DONE event as start is synchronus */ |
| post_event (0, OMX_ErrorNone, OMX_COMPONENT_GENERATE_START_DONE); |
| |
| RETURN(0); |
| } |
| |
| OMX_U32 omx_venc::dev_set_message_thread_id(pthread_t tid) |
| { |
| ENTER_FUNC(); |
| |
| // nothing to be done for sw encoder |
| (void)tid; |
| |
| RETURN(true); |
| } |
| |
| bool omx_venc::dev_use_buf(unsigned port) |
| { |
| ENTER_FUNC(); |
| (void)port; |
| RETURN(true); |
| } |
| |
| bool omx_venc::dev_handle_empty_eos_buffer(void) |
| { |
| ENTER_FUNC(); |
| SWVENC_STATUS Ret; |
| SWVENC_IPBUFFER ipbuffer; |
| ipbuffer.p_buffer = NULL; |
| ipbuffer.filled_length =0; |
| ipbuffer.flags = SWVENC_FLAG_EOS; |
| Ret = swvenc_emptythisbuffer(m_hSwVenc, &ipbuffer); |
| if (Ret != SWVENC_S_SUCCESS) |
| { |
| DEBUG_PRINT_ERROR("%s, swvenc_emptythisbuffer failed (%d)", |
| __FUNCTION__, Ret); |
| RETURN(false); |
| } |
| RETURN(true); |
| } |
| |
| bool omx_venc::dev_free_buf(void *buf_addr,unsigned port) |
| { |
| ENTER_FUNC(); |
| |
| (void)buf_addr; |
| (void)port; |
| |
| RETURN(true); |
| } |
| |
| bool omx_venc::dev_empty_buf |
| ( |
| void *buffer, |
| void *pmem_data_buf, |
| unsigned index, |
| unsigned fd |
| ) |
| { |
| ENTER_FUNC(); |
| |
| SWVENC_STATUS Ret; |
| SWVENC_IPBUFFER ipbuffer; |
| OMX_BUFFERHEADERTYPE *bufhdr = (OMX_BUFFERHEADERTYPE *)buffer; |
| unsigned int size = 0, filled_length, offset = 0; |
| SWVENC_COLOR_FORMAT color_format; |
| SWVENC_PROPERTY prop; |
| |
| (void)pmem_data_buf; |
| (void)index; |
| |
| if (meta_mode_enable) |
| { |
| LEGACY_CAM_METADATA_TYPE *meta_buf = NULL; |
| meta_buf = (LEGACY_CAM_METADATA_TYPE *)bufhdr->pBuffer; |
| if(m_sInPortDef.format.video.eColorFormat == ((OMX_COLOR_FORMATTYPE) QOMX_COLOR_FormatAndroidOpaque)) |
| { |
| DEBUG_PRINT_LOW("dev_empty_buf: color_format is QOMX_COLOR_FormatAndroidOpaque"); |
| set_format = true; |
| } |
| if(!meta_buf) |
| { |
| if (!bufhdr->nFilledLen && (bufhdr->nFlags & OMX_BUFFERFLAG_EOS)) |
| { |
| ipbuffer.p_buffer= bufhdr->pBuffer; |
| ipbuffer.size = bufhdr->nAllocLen; |
| ipbuffer.filled_length = bufhdr->nFilledLen; |
| DEBUG_PRINT_LOW("dev_empty_buf: empty EOS buffer"); |
| } |
| else |
| { |
| return false; |
| } |
| } |
| else |
| { |
| if (meta_buf->buffer_type == LEGACY_CAM_SOURCE) |
| { |
| offset = meta_buf->meta_handle->data[1]; |
| size = meta_buf->meta_handle->data[2]; |
| if (set_format && (meta_buf->meta_handle->numFds + meta_buf->meta_handle->numInts > 5)) |
| { |
| m_sInPortFormat.eColorFormat = (OMX_COLOR_FORMATTYPE)meta_buf->meta_handle->data[5]; |
| } |
| ipbuffer.p_buffer = (unsigned char *)mmap(NULL, size, PROT_READ|PROT_WRITE,MAP_SHARED, fd, offset); |
| if (ipbuffer.p_buffer == MAP_FAILED) |
| { |
| DEBUG_PRINT_ERROR("mmap() failed for fd %d of size %d",fd,size); |
| RETURN(false); |
| } |
| ipbuffer.size = size; |
| ipbuffer.filled_length = size; |
| } |
| else if (meta_buf->buffer_type == kMetadataBufferTypeGrallocSource) |
| { |
| VideoGrallocMetadata *meta_buf = (VideoGrallocMetadata *)bufhdr->pBuffer; |
| private_handle_t *handle = (private_handle_t *)meta_buf->pHandle; |
| size = handle->size; |
| if (m_bUseAVTimerTimestamps) { |
| uint64_t avTimerTimestampNs = bufhdr->nTimeStamp * 1000; |
| if (getMetaData(handle, GET_VT_TIMESTAMP, &avTimerTimestampNs) == 0 |
| && avTimerTimestampNs > 0) { |
| bufhdr->nTimeStamp = avTimerTimestampNs / 1000; |
| DEBUG_PRINT_LOW("AVTimer TS: %llu us", (unsigned long long)bufhdr->nTimeStamp); |
| } |
| } |
| if (set_format) |
| { |
| DEBUG_PRINT_LOW("color format = 0x%x",handle->format); |
| if (((OMX_COLOR_FORMATTYPE)handle->format) != m_sInPortFormat.eColorFormat) |
| { |
| if(handle->format == HAL_PIXEL_FORMAT_NV12_ENCODEABLE) |
| { |
| m_sInPortFormat.eColorFormat = (OMX_COLOR_FORMATTYPE) |
| QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m; |
| } |
| else |
| { |
| DEBUG_PRINT_ERROR("%s: OMX_IndexParamVideoPortFormat 0x%x invalid", |
| __FUNCTION__,handle->format); |
| RETURN(false); |
| } |
| } |
| } |
| ipbuffer.p_buffer = (unsigned char *)mmap(NULL, size, PROT_READ|PROT_WRITE,MAP_SHARED, fd, offset); |
| if (ipbuffer.p_buffer == MAP_FAILED) |
| { |
| DEBUG_PRINT_ERROR("mmap() failed for fd %d of size %d",fd,size); |
| RETURN(false); |
| } |
| ipbuffer.size = size; |
| ipbuffer.filled_length = size; |
| } |
| else |
| { |
| //handles the use case for surface encode |
| ipbuffer.p_buffer = bufhdr->pBuffer; |
| ipbuffer.size = bufhdr->nAllocLen; |
| ipbuffer.filled_length = bufhdr->nFilledLen; |
| } |
| if (set_format) |
| { |
| set_format = false; |
| m_sInPortDef.format.video.eColorFormat = m_sInPortFormat.eColorFormat; |
| Ret = swvenc_set_color_format(m_sInPortFormat.eColorFormat); |
| if (Ret != SWVENC_S_SUCCESS) |
| { |
| DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)", |
| __FUNCTION__, Ret); |
| RETURN(false); |
| } |
| } |
| } |
| } |
| else |
| { |
| ipbuffer.p_buffer = bufhdr->pBuffer; |
| ipbuffer.size = bufhdr->nAllocLen; |
| ipbuffer.filled_length = bufhdr->nFilledLen; |
| } |
| ipbuffer.flags = 0; |
| if (bufhdr->nFlags & OMX_BUFFERFLAG_EOS) |
| { |
| ipbuffer.flags |= SWVENC_FLAG_EOS; |
| } |
| ipbuffer.timestamp = bufhdr->nTimeStamp; |
| ipbuffer.p_client_data = (unsigned char *)bufhdr; |
| |
| DEBUG_PRINT_LOW("ETB: p_buffer (%p) size (%d) filled_len (%d) flags (0x%X) timestamp (%lld) clientData (%p)", |
| ipbuffer.p_buffer, |
| ipbuffer.size, |
| ipbuffer.filled_length, |
| (unsigned int)ipbuffer.flags, |
| ipbuffer.timestamp, |
| ipbuffer.p_client_data); |
| |
| if (m_debug.in_buffer_log) |
| { |
| swvenc_input_log_buffers((const char*)ipbuffer.p_buffer, ipbuffer.filled_length); |
| } |
| |
| if (m_bIsRotationSupported && m_sConfigFrameRotation.nRotation != 0) { |
| if(!swvenc_do_rotate((int)fd, ipbuffer, (OMX_U32)index)) { |
| DEBUG_PRINT_ERROR("rotate failed"); |
| return OMX_ErrorUndefined; |
| } |
| } |
| |
| Ret = swvenc_emptythisbuffer(m_hSwVenc, &ipbuffer); |
| if (Ret != SWVENC_S_SUCCESS) |
| { |
| DEBUG_PRINT_ERROR("%s, swvenc_emptythisbuffer failed (%d)", |
| __FUNCTION__, Ret); |
| RETURN(false); |
| } |
| |
| RETURN(true); |
| } |
| |
| bool omx_venc::dev_fill_buf |
| ( |
| void *buffer, |
| void *pmem_data_buf, |
| unsigned index, |
| unsigned fd |
| ) |
| { |
| ENTER_FUNC(); |
| |
| SWVENC_STATUS Ret; |
| |
| SWVENC_OPBUFFER opbuffer; |
| OMX_BUFFERHEADERTYPE *bufhdr = (OMX_BUFFERHEADERTYPE *)buffer; |
| |
| (void)pmem_data_buf; |
| (void)index; |
| (void)fd; |
| |
| opbuffer.p_buffer = bufhdr->pBuffer; |
| opbuffer.size = bufhdr->nAllocLen; |
| opbuffer.filled_length = bufhdr->nFilledLen; |
| opbuffer.flags = bufhdr->nFlags; |
| opbuffer.timestamp = bufhdr->nTimeStamp; |
| opbuffer.p_client_data = (unsigned char *)bufhdr; |
| opbuffer.frame_type = SWVENC_FRAME_TYPE_I; |
| |
| DEBUG_PRINT_LOW("FTB: p_buffer (%p) size (%d) filled_len (%d) flags (0x%X) timestamp (%lld) clientData (%p)", |
| opbuffer.p_buffer, |
| opbuffer.size, |
| opbuffer.filled_length, |
| opbuffer.flags, |
| opbuffer.timestamp, |
| opbuffer.p_client_data); |
| |
| if ( false == m_bSeqHdrRequested) |
| { |
| if (dev_get_seq_hdr(opbuffer.p_buffer, opbuffer.size, &opbuffer.filled_length)) |
| { |
| bufhdr->nFilledLen = opbuffer.filled_length; |
| bufhdr->nOffset = 0; |
| bufhdr->nTimeStamp = 0; |
| bufhdr->nFlags = OMX_BUFFERFLAG_CODECCONFIG; |
| |
| DEBUG_PRINT_LOW("sending FBD with codec config"); |
| m_bSeqHdrRequested = true; |
| post_event ((unsigned long)bufhdr,0,OMX_COMPONENT_GENERATE_FBD); |
| } |
| else |
| { |
| DEBUG_PRINT_ERROR("ERROR: couldn't get sequence header"); |
| post_event(OMX_EventError,OMX_ErrorUndefined,OMX_COMPONENT_GENERATE_EVENT); |
| } |
| } |
| else |
| { |
| Ret = swvenc_fillthisbuffer(m_hSwVenc, &opbuffer); |
| if (Ret != SWVENC_S_SUCCESS) |
| { |
| DEBUG_PRINT_ERROR("%s, swvenc_fillthisbuffer failed (%d)", |
| __FUNCTION__, Ret); |
| RETURN(false); |
| } |
| } |
| |
| RETURN(true); |
| } |
| |
| bool omx_venc::dev_get_seq_hdr |
| ( |
| void *buffer, |
| unsigned size, |
| unsigned *hdrlen |
| ) |
| { |
| ENTER_FUNC(); |
| |
| SWVENC_STATUS Ret; |
| SWVENC_OPBUFFER Buffer; |
| |
| Buffer.p_buffer = (unsigned char*) buffer; |
| Buffer.size = size; |
| |
| Ret = swvenc_getsequenceheader(m_hSwVenc, &Buffer); |
| if (Ret != SWVENC_S_SUCCESS) |
| { |
| DEBUG_PRINT_ERROR("%s, swvenc_getsequenceheader failed (%d)", |
| __FUNCTION__, Ret); |
| RETURN(false); |
| } |
| |
| *hdrlen = Buffer.filled_length; |
| |
| RETURN(true); |
| } |
| |
| bool omx_venc::dev_get_capability_ltrcount |
| ( |
| OMX_U32 *min, |
| OMX_U32 *max, |
| OMX_U32 *step_size |
| ) |
| { |
| ENTER_FUNC(); |
| |
| (void)min; |
| (void)max; |
| (void)step_size; |
| |
| DEBUG_PRINT_ERROR("Get Capability LTR Count is not supported"); |
| |
| RETURN(false); |
| } |
| |
| bool omx_venc::dev_get_vui_timing_info(OMX_U32 *enabled) |
| { |
| ENTER_FUNC(); |
| |
| (void)enabled; |
| DEBUG_PRINT_ERROR("Get vui timing information is not supported"); |
| |
| RETURN(false); |
| } |
| |
| bool omx_venc::dev_get_vqzip_sei_info(OMX_U32 *enabled) |
| { |
| ENTER_FUNC(); |
| |
| (void)enabled; |
| DEBUG_PRINT_ERROR("Get vqzip sei info is not supported"); |
| |
| RETURN(false); |
| } |
| |
| bool omx_venc::dev_get_peak_bitrate(OMX_U32 *peakbitrate) |
| { |
| //TBD: store the peak bitrate in class and return here; |
| ENTER_FUNC(); |
| |
| (void)peakbitrate; |
| DEBUG_PRINT_ERROR("Get peak bitrate is not supported"); |
| |
| RETURN(false); |
| } |
| |
| bool omx_venc::dev_get_batch_size(OMX_U32 *size) |
| { |
| ENTER_FUNC(); |
| |
| (void)size; |
| |
| DEBUG_PRINT_ERROR("Get batch size is not supported"); |
| |
| RETURN(false); |
| } |
| |
| OMX_ERRORTYPE omx_venc::dev_get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType) |
| { |
| ENTER_FUNC(); |
| OMX_ERRORTYPE eRet = OMX_ErrorNone; |
| |
| if (profileLevelType == NULL) |
| { |
| DEBUG_PRINT_ERROR("p_profilelevel = NULL"); |
| return OMX_ErrorBadParameter; |
| } |
| |
| if (profileLevelType->nPortIndex == 1) { |
| if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingH263) |
| { |
| if (profileLevelType->nProfileIndex == 0) |
| { |
| profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline; |
| profileLevelType->eLevel = OMX_VIDEO_H263Level70; |
| |
| DEBUG_PRINT_HIGH("H.263 baseline profile, level 70"); |
| } |
| else |
| { |
| DEBUG_PRINT_LOW("dev_get_supported_profile_level:nProfileIndex ret NoMore %u", |
| (unsigned int)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_MPEG4Level6; |
| |
| DEBUG_PRINT_LOW("MPEG-4 simple profile, level 6"); |
| } |
| else |
| { |
| DEBUG_PRINT_LOW("dev_get_supported_profile_level:nProfileIndex ret NoMore %u", |
| (unsigned int)profileLevelType->nProfileIndex); |
| eRet = OMX_ErrorNoMore; |
| } |
| } |
| else |
| { |
| DEBUG_PRINT_ERROR("get_parameter: dev_get_supported_profile_level ret NoMore"); |
| eRet = OMX_ErrorNoMore; |
| } |
| } |
| else |
| { |
| DEBUG_PRINT_ERROR("get_parameter: dev_get_supported_profile_level should be queried on Input port only %u", |
| (unsigned int)profileLevelType->nPortIndex); |
| eRet = OMX_ErrorBadPortIndex; |
| } |
| return eRet; |
| } |
| |
| bool omx_venc::dev_get_supported_color_format(unsigned index, OMX_U32 *colorFormat) { |
| // we support two formats |
| // index 0 - Venus flavour of YUV420SP |
| // index 1 - opaque which internally maps to YUV420SP |
| // index 2 - vannilla YUV420SP |
| // this can be extended in the future |
| int supportedFormats[] = { |
| [0] = QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m, |
| [1] = QOMX_COLOR_FormatYVU420SemiPlanar, |
| [2] = QOMX_COLOR_FormatAndroidOpaque, |
| [3] = OMX_COLOR_FormatYUV420SemiPlanar, |
| }; |
| |
| if (index > (sizeof(supportedFormats)/sizeof(*supportedFormats) - 1)) |
| return false; |
| *colorFormat = supportedFormats[index]; |
| return true; |
| } |
| |
| bool omx_venc::dev_loaded_start() |
| { |
| ENTER_FUNC(); |
| RETURN(true); |
| } |
| |
| bool omx_venc::dev_loaded_stop() |
| { |
| ENTER_FUNC(); |
| RETURN(true); |
| } |
| |
| bool omx_venc::dev_loaded_start_done() |
| { |
| ENTER_FUNC(); |
| RETURN(true); |
| } |
| |
| bool omx_venc::dev_loaded_stop_done() |
| { |
| ENTER_FUNC(); |
| RETURN(true); |
| } |
| |
| bool omx_venc::is_streamon_done(OMX_U32 port) |
| { |
| if (PORT_INDEX_OUT <= port) |
| ENTER_FUNC(); |
| RETURN(false); |
| } |
| |
| bool omx_venc::dev_get_buf_req(OMX_U32 *min_buff_count, |
| OMX_U32 *actual_buff_count, |
| OMX_U32 *buff_size, |
| OMX_U32 port) |
| { |
| ENTER_FUNC(); |
| |
| bool bRet = true; |
| OMX_PARAM_PORTDEFINITIONTYPE *PortDef; |
| |
| if (PORT_INDEX_IN == port) |
| { |
| PortDef = &m_sInPortDef; |
| } |
| else if (PORT_INDEX_OUT == port) |
| { |
| PortDef = &m_sOutPortDef; |
| } |
| else |
| { |
| DEBUG_PRINT_ERROR("ERROR: %s, Unsupported parameter", __FUNCTION__); |
| bRet = false; |
| } |
| |
| if (true == bRet) |
| { |
| *min_buff_count = PortDef->nBufferCountMin; |
| *actual_buff_count = PortDef->nBufferCountActual; |
| *buff_size = PortDef->nBufferSize; |
| } |
| |
| RETURN(true); |
| } |
| |
| bool omx_venc::dev_set_buf_req |
| ( |
| OMX_U32 const *min_buff_count, |
| OMX_U32 const *actual_buff_count, |
| OMX_U32 const *buff_size, |
| OMX_U32 port |
| ) |
| { |
| ENTER_FUNC(); |
| |
| SWVENC_STATUS Ret; |
| OMX_PARAM_PORTDEFINITIONTYPE *PortDef; |
| |
| (void)min_buff_count; |
| if (PORT_INDEX_IN == port) |
| { |
| PortDef = &m_sInPortDef; |
| } |
| else if (PORT_INDEX_OUT == port) |
| { |
| PortDef = &m_sOutPortDef; |
| } |
| else |
| { |
| DEBUG_PRINT_ERROR("ERROR: %s, Unsupported parameter", __FUNCTION__); |
| RETURN(false); |
| } |
| |
| if (*actual_buff_count < PortDef->nBufferCountMin) |
| { |
| DEBUG_PRINT_ERROR("ERROR: %s, (actual,min) buffer count (%d, %d)", |
| __FUNCTION__, *actual_buff_count, PortDef->nBufferCountMin); |
| RETURN(false); |
| } |
| if (false == meta_mode_enable) |
| { |
| if (*buff_size < PortDef->nBufferSize) |
| { |
| DEBUG_PRINT_ERROR("ERROR: %s, (new,old) buffer count (%d, %d)", |
| __FUNCTION__, *actual_buff_count, PortDef->nBufferCountMin); |
| RETURN(false); |
| } |
| } |
| |
| RETURN(true); |
| } |
| |
| bool omx_venc::dev_is_video_session_supported(OMX_U32 width, OMX_U32 height) |
| { |
| ENTER_FUNC(); |
| |
| if ( (width * height < m_capability.min_width * m_capability.min_height) || |
| (width * height > m_capability.max_width * m_capability.max_height) |
| ) |
| { |
| DEBUG_PRINT_ERROR( |
| "Unsupported Resolution WxH = (%u)x(%u) Supported Range = min (%d)x(%d) - max (%d)x(%d)", |
| width, height, |
| m_capability.min_width, m_capability.min_height, |
| m_capability.max_width, m_capability.max_height); |
| RETURN(false); |
| } |
| |
| RETURN(true); |
| } |
| |
| bool omx_venc::dev_buffer_ready_to_queue(OMX_BUFFERHEADERTYPE *buffer) |
| { |
| ENTER_FUNC(); |
| |
| (void)buffer; |
| RETURN(true); |
| } |
| int omx_venc::dev_handle_output_extradata(void *buffer, int fd) |
| { |
| ENTER_FUNC(); |
| |
| (void)buffer; |
| (void)fd; |
| |
| RETURN(true); |
| } |
| |
| int omx_venc::dev_handle_input_extradata(void *buffer, int fd, int index) |
| { |
| ENTER_FUNC(); |
| |
| (void)buffer; |
| (void)fd; |
| (void)index; |
| |
| RETURN(true); |
| } |
| |
| void omx_venc::dev_set_extradata_cookie(void *buffer) |
| { |
| ENTER_FUNC(); |
| |
| (void)buffer; |
| } |
| |
| int omx_venc::dev_set_format(int color) |
| { |
| ENTER_FUNC(); |
| |
| (void)color; |
| |
| RETURN(true); |
| //return handle->venc_set_format(color); |
| } |
| |
| bool omx_venc::dev_get_dimensions(OMX_U32 index, OMX_U32 *width, OMX_U32 *height) |
| { |
| ENTER_FUNC(); |
| |
| (void)index; |
| (void)width; |
| (void)height; |
| |
| RETURN(true); |
| } |
| |
| bool omx_venc::dev_color_align(OMX_BUFFERHEADERTYPE *buffer, |
| OMX_U32 width, OMX_U32 height) |
| { |
| ENTER_FUNC(); |
| |
| if(secure_session) { |
| DEBUG_PRINT_ERROR("Cannot align colors in secure session."); |
| RETURN(false); |
| } |
| return swvenc_color_align(buffer, width,height); |
| } |
| |
| bool omx_venc::is_secure_session() |
| { |
| ENTER_FUNC(); |
| |
| RETURN(secure_session); |
| } |
| |
| bool omx_venc::dev_get_output_log_flag() |
| { |
| ENTER_FUNC(); |
| |
| RETURN(m_debug.out_buffer_log == 1); |
| } |
| |
| int omx_venc::dev_output_log_buffers(const char *buffer, int bufferlen, uint64_t ts) |
| { |
| (void) ts; |
| ENTER_FUNC(); |
| |
| if (m_debug.out_buffer_log && !m_debug.outfile) |
| { |
| int size = 0; |
| int width = m_sInPortDef.format.video.nFrameWidth; |
| int height = m_sInPortDef.format.video.nFrameHeight; |
| if(SWVENC_CODEC_MPEG4 == m_codec) |
| { |
| size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, |
| "%s/output_enc_%d_%d_%p.m4v", |
| m_debug.log_loc, width, height, this); |
| } |
| else if(SWVENC_CODEC_H263 == m_codec) |
| { |
| size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, |
| "%s/output_enc_%d_%d_%p.263", |
| m_debug.log_loc, width, height, this); |
| } |
| if ((size > PROPERTY_VALUE_MAX) || (size < 0)) |
| { |
| DEBUG_PRINT_ERROR("Failed to open output file: %s for logging as size:%d", |
| m_debug.outfile_name, size); |
| RETURN(-1); |
| } |
| DEBUG_PRINT_LOW("output filename = %s", m_debug.outfile_name); |
| m_debug.outfile = fopen(m_debug.outfile_name, "ab"); |
| if (!m_debug.outfile) |
| { |
| DEBUG_PRINT_ERROR("Failed to open output file: %s for logging errno:%d", |
| m_debug.outfile_name, errno); |
| m_debug.outfile_name[0] = '\0'; |
| RETURN(-1); |
| } |
| } |
| if (m_debug.outfile && buffer && bufferlen) |
| { |
| DEBUG_PRINT_LOW("%s buffer length: %d", __func__, bufferlen); |
| fwrite(buffer, bufferlen, 1, m_debug.outfile); |
| } |
| |
| RETURN(0); |
| } |
| |
| int omx_venc::swvenc_input_log_buffers(const char *buffer, int bufferlen) |
| { |
| int width = m_sInPortDef.format.video.nFrameWidth; |
| int height = m_sInPortDef.format.video.nFrameHeight; |
| int stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, width); |
| int scanlines = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height); |
| char *temp = (char*)buffer; |
| |
| if (!m_debug.infile) |
| { |
| int size = snprintf(m_debug.infile_name, PROPERTY_VALUE_MAX, |
| "%s/input_enc_%d_%d_%p.yuv", |
| m_debug.log_loc, width, height, this); |
| if ((size > PROPERTY_VALUE_MAX) || (size < 0)) |
| { |
| DEBUG_PRINT_ERROR("Failed to open input file: %s for logging size:%d", |
| m_debug.infile_name, size); |
| RETURN(-1); |
| } |
| DEBUG_PRINT_LOW("input filename = %s", m_debug.infile_name); |
| m_debug.infile = fopen (m_debug.infile_name, "ab"); |
| if (!m_debug.infile) |
| { |
| DEBUG_PRINT_HIGH("Failed to open input file: %s for logging", |
| m_debug.infile_name); |
| m_debug.infile_name[0] = '\0'; |
| RETURN(-1); |
| } |
| } |
| if (m_debug.infile && buffer && bufferlen) |
| { |
| DEBUG_PRINT_LOW("%s buffer length: %d", __func__, bufferlen); |
| for (int i = 0; i < height; i++) |
| { |
| fwrite(temp, width, 1, m_debug.infile); |
| temp += stride; |
| } |
| temp = (char*)(buffer + (stride * scanlines)); |
| for(int i = 0; i < height/2; i++) |
| { |
| fwrite(temp, width, 1, m_debug.infile); |
| temp += stride; |
| } |
| } |
| |
| RETURN(0); |
| } |
| |
| int omx_venc::dev_extradata_log_buffers(char *buffer) |
| { |
| ENTER_FUNC(); |
| |
| (void)buffer; |
| |
| RETURN(true); |
| //return handle->venc_extradata_log_buffers(buffer); |
| } |
| |
| SWVENC_STATUS omx_venc::swvenc_get_buffer_req |
| ( |
| OMX_U32 *min_buff_count, |
| OMX_U32 *actual_buff_count, |
| OMX_U32 *buff_size, |
| OMX_U32 *buff_alignment, |
| OMX_U32 port |
| ) |
| { |
| ENTER_FUNC(); |
| |
| SWVENC_PROPERTY Prop; |
| SWVENC_STATUS Ret; |
| OMX_PARAM_PORTDEFINITIONTYPE *PortDef; |
| |
| Prop.id = SWVENC_PROPERTY_ID_BUFFER_REQ; |
| if (PORT_INDEX_IN == port) |
| { |
| Prop.info.buffer_req.type = SWVENC_BUFFER_INPUT; |
| } |
| else if (PORT_INDEX_OUT == port) |
| { |
| Prop.info.buffer_req.type = SWVENC_BUFFER_OUTPUT; |
| } |
| else |
| { |
| DEBUG_PRINT_ERROR("ERROR: %s, Unsupported parameter", __FUNCTION__); |
| RETURN(SWVENC_S_INVALID_PARAMETERS); |
| } |
| |
| Ret = swvenc_getproperty(m_hSwVenc, &Prop); |
| if (Ret != SWVENC_S_SUCCESS) |
| { |
| DEBUG_PRINT_ERROR("ERROR: %s, swvenc_setproperty failed (%d)", __FUNCTION__, |
| Ret); |
| RETURN(SWVENC_S_INVALID_PARAMETERS); |
| } |
| |
| *buff_size = Prop.info.buffer_req.size; |
| *min_buff_count = Prop.info.buffer_req.mincount; |
| *actual_buff_count = Prop.info.buffer_req.mincount; |
| *buff_alignment = Prop.info.buffer_req.alignment; |
| |
| RETURN(Ret); |
| } |
| |
| SWVENC_STATUS omx_venc::swvenc_empty_buffer_done_cb |
| ( |
| SWVENC_HANDLE swvenc, |
| SWVENC_IPBUFFER *p_ipbuffer, |
| void *p_client |
| ) |
| { |
| ENTER_FUNC(); |
| |
| (void)swvenc; |
| SWVENC_STATUS eRet = SWVENC_S_SUCCESS; |
| omx_venc *omx = reinterpret_cast<omx_venc*>(p_client); |
| |
| if (p_ipbuffer == NULL) |
| { |
| eRet = SWVENC_S_FAILURE; |
| } |
| else |
| { |
| omx->swvenc_empty_buffer_done(p_ipbuffer); |
| } |
| return eRet; |
| } |
| |
| SWVENC_STATUS omx_venc::swvenc_empty_buffer_done |
| ( |
| SWVENC_IPBUFFER *p_ipbuffer |
| ) |
| { |
| SWVENC_STATUS eRet = SWVENC_S_SUCCESS; |
| OMX_ERRORTYPE error = OMX_ErrorNone; |
| OMX_BUFFERHEADERTYPE* omxhdr = NULL; |
| |
| //omx_video *omx = reinterpret_cast<omx_video*>(p_client); |
| omxhdr = (OMX_BUFFERHEADERTYPE*)p_ipbuffer->p_client_data; |
| |
| DEBUG_PRINT_LOW("EBD: clientData (%p)", p_ipbuffer->p_client_data); |
| |
| if ( (omxhdr == NULL) || |
| ( ((OMX_U32)(omxhdr - m_inp_mem_ptr) >m_sInPortDef.nBufferCountActual) && |
| ((OMX_U32)(omxhdr - meta_buffer_hdr) >m_sInPortDef.nBufferCountActual) |
| ) |
| ) |
| { |
| omxhdr = NULL; |
| error = OMX_ErrorUndefined; |
| } |
| |
| if (m_pIpbuffers != nullptr) { |
| int index = omxhdr - ((mUseProxyColorFormat && !mUsesColorConversion) ? meta_buffer_hdr : m_inp_mem_ptr); |
| DEBUG_PRINT_HIGH("restore ipbuffer[p_buffer(%p), size(%d), filled_length(%d)] to original ipbuffer[p_buffer(%p), size(%d), filled_length(%d)]", |
| p_ipbuffer->p_buffer, |
| p_ipbuffer->size, |
| p_ipbuffer->filled_length, |
| m_pIpbuffers[index].p_buffer, |
| m_pIpbuffers[index].size, |
| m_pIpbuffers[index].filled_length); |
| p_ipbuffer->size = m_pIpbuffers[index].size; |
| p_ipbuffer->filled_length = m_pIpbuffers[index].filled_length; |
| p_ipbuffer->p_buffer = m_pIpbuffers[index].p_buffer; |
| } |
| |
| if (omxhdr != NULL) |
| { |
| // unmap the input buffer->pBuffer |
| omx_release_meta_buffer(omxhdr); |
| #ifdef _ANDROID_ICS_ |
| if (meta_mode_enable) |
| { |
| LEGACY_CAM_METADATA_TYPE *meta_buf = NULL; |
| unsigned int size = 0; |
| meta_buf = (LEGACY_CAM_METADATA_TYPE *)omxhdr->pBuffer; |
| if (meta_buf) |
| { |
| if (meta_buf->buffer_type == LEGACY_CAM_SOURCE) |
| { |
| size = meta_buf->meta_handle->data[2]; |
| } |
| else if (meta_buf->buffer_type == kMetadataBufferTypeGrallocSource) |
| { |
| VideoGrallocMetadata *meta_buf = (VideoGrallocMetadata *)omxhdr->pBuffer; |
| private_handle_t *handle = (private_handle_t *)meta_buf->pHandle; |
| size = handle->size; |
| } |
| } |
| int status = munmap(p_ipbuffer->p_buffer, size); |
| DEBUG_PRINT_HIGH("Unmapped pBuffer <%p> size <%d> status <%d>", p_ipbuffer->p_buffer, size, status); |
| } |
| #endif |
| post_event ((unsigned long)omxhdr,error,OMX_COMPONENT_GENERATE_EBD); |
| } |
| |
| RETURN(eRet); |
| } |
| |
| SWVENC_STATUS omx_venc::swvenc_fill_buffer_done_cb |
| ( |
| SWVENC_HANDLE swvenc, |
| SWVENC_OPBUFFER *p_opbuffer, |
| void *p_client |
| ) |
| { |
| ENTER_FUNC(); |
| |
| SWVENC_STATUS eRet = SWVENC_S_SUCCESS; |
| OMX_ERRORTYPE error = OMX_ErrorNone; |
| OMX_BUFFERHEADERTYPE* omxhdr = NULL; |
| omx_video *omx = reinterpret_cast<omx_video*>(p_client); |
| |
| (void)swvenc; |
| |
| if (p_opbuffer != NULL) |
| { |
| omxhdr = (OMX_BUFFERHEADERTYPE*)p_opbuffer->p_client_data; |
| } |
| |
| if ( (p_opbuffer != NULL) && |
| ((OMX_U32)(omxhdr - omx->m_out_mem_ptr) < omx->m_sOutPortDef.nBufferCountActual) |
| ) |
| { |
| DEBUG_PRINT_LOW("FBD: clientData (%p) buffer (%p) filled_lengh (%d) flags (0x%x) ts (%lld)", |
| p_opbuffer->p_client_data, |
| p_opbuffer->p_buffer, |
| p_opbuffer->filled_length, |
| p_opbuffer->flags, |
| p_opbuffer->timestamp); |
| |
| if (p_opbuffer->filled_length <= omxhdr->nAllocLen) |
| { |
| omxhdr->pBuffer = p_opbuffer->p_buffer; |
| omxhdr->nFilledLen = p_opbuffer->filled_length; |
| omxhdr->nOffset = 0; |
| omxhdr->nTimeStamp = p_opbuffer->timestamp; |
| omxhdr->nFlags = 0; |
| if (SWVENC_FRAME_TYPE_I == p_opbuffer->frame_type) |
| { |
| omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME; |
| } |
| if (SWVENC_FLAG_EOS & p_opbuffer->flags) |
| { |
| omxhdr->nFlags |= OMX_BUFFERFLAG_EOS; |
| } |
| if(omxhdr->nFilledLen) |
| { |
| omxhdr->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; |
| } |
| DEBUG_PRINT_LOW("o/p flag = 0x%x", omxhdr->nFlags); |
| |
| /* Use buffer case */ |
| if (omx->output_use_buffer && !omx->m_use_output_pmem) |
| { |
| DEBUG_PRINT_LOW("memcpy() for o/p Heap UseBuffer"); |
| memcpy( omxhdr->pBuffer, |
| (p_opbuffer->p_buffer), |
| p_opbuffer->filled_length ); |
| } |
| } |
| else |
| { |
| omxhdr->nFilledLen = 0; |
| } |
| |
| } |
| else |
| { |
| omxhdr = NULL; |
| error = OMX_ErrorUndefined; |
| } |
| |
| omx->post_event ((unsigned long)omxhdr,error,OMX_COMPONENT_GENERATE_FBD); |
| |
| RETURN(eRet); |
| } |
| |
| SWVENC_STATUS omx_venc::swvenc_handle_event_cb |
| ( |
| SWVENC_HANDLE swvenc, |
| SWVENC_EVENT event, |
| void *p_client |
| ) |
| { |
| ENTER_FUNC(); |
| |
| SWVENC_STATUS eRet = SWVENC_S_SUCCESS; |
| omx_video *omx = reinterpret_cast<omx_video*>(p_client); |
| |
| OMX_BUFFERHEADERTYPE* omxhdr = NULL; |
| |
| (void)swvenc; |
| |
| if (omx == NULL || p_client == NULL) |
| { |
| DEBUG_PRINT_ERROR("ERROR: %s invalid i/p params", __FUNCTION__); |
| RETURN(SWVENC_S_NULL_POINTER); |
| } |
| |
| DEBUG_PRINT_LOW("swvenc_handle_event_cb - event = %d", event); |
| |
| switch (event) |
| { |
| case SWVENC_EVENT_FLUSH_DONE: |
| { |
| DEBUG_PRINT_ERROR("SWVENC_EVENT_FLUSH_DONE input_flush_progress %d output_flush_progress %d", |
| omx->input_flush_progress, omx->output_flush_progress); |
| if (omx->input_flush_progress) |
| { |
| omx->post_event ((unsigned)NULL, SWVENC_S_SUCCESS, |
| OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH); |
| } |
| if (omx->output_flush_progress) |
| { |
| omx->post_event ((unsigned)NULL, SWVENC_S_SUCCESS, |
| OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH); |
| } |
| break; |
| } |
| |
| case SWVENC_EVENT_FATAL_ERROR: |
| { |
| DEBUG_PRINT_ERROR("ERROR: SWVENC_EVENT_FATAL_ERROR"); |
| omx->omx_report_error(); |
| break; |
| } |
| |
| default: |
| DEBUG_PRINT_HIGH("Unknown event received : %d", event); |
| break; |
| } |
| |
| RETURN(eRet); |
| } |
| |
| SWVENC_STATUS omx_venc::swvenc_set_rc_mode |
| ( |
| OMX_VIDEO_CONTROLRATETYPE eControlRate |
| ) |
| { |
| ENTER_FUNC(); |
| |
| SWVENC_STATUS Ret = SWVENC_S_SUCCESS; |
| SWVENC_RC_MODE rc_mode; |
| SWVENC_PROPERTY Prop; |
| |
| switch (eControlRate) |
| { |
| case OMX_Video_ControlRateDisable: |
| rc_mode = SWVENC_RC_MODE_NONE; |
| break; |
| case OMX_Video_ControlRateVariableSkipFrames: |
| rc_mode = SWVENC_RC_MODE_VBR_VFR; |
| break; |
| case OMX_Video_ControlRateVariable: |
| rc_mode = SWVENC_RC_MODE_VBR_CFR; |
| break; |
| case OMX_Video_ControlRateConstantSkipFrames: |
| rc_mode = SWVENC_RC_MODE_CBR_VFR; |
| break; |
| case OMX_Video_ControlRateConstant: |
| rc_mode = SWVENC_RC_MODE_CBR_CFR; |
| break; |
| default: |
| DEBUG_PRINT_ERROR("ERROR: UNKNOWN RC MODE"); |
| Ret = SWVENC_S_FAILURE; |
| break; |
| } |
| |
| if (SWVENC_S_SUCCESS == Ret) |
| { |
| Prop.id = SWVENC_PROPERTY_ID_RC_MODE; |
| Prop.info.rc_mode = rc_mode; |
| Ret = swvenc_setproperty(m_hSwVenc, &Prop); |
| if (Ret != SWVENC_S_SUCCESS) |
| { |
| DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)", |
| __FUNCTION__, Ret); |
| RETURN(SWVENC_S_FAILURE); |
| } |
| } |
| |
| RETURN(Ret); |
| } |
| |
| SWVENC_STATUS omx_venc::swvenc_set_profile_level |
| ( |
| OMX_U32 eProfile, |
| OMX_U32 eLevel |
| ) |
| { |
| ENTER_FUNC(); |
| |
| SWVENC_STATUS Ret = SWVENC_S_SUCCESS; |
| SWVENC_PROPERTY Prop; |
| SWVENC_PROFILE Profile; |
| SWVENC_LEVEL Level; |
| |
| /* set the profile */ |
| if (SWVENC_CODEC_MPEG4 == m_codec) |
| { |
| switch (eProfile) |
| { |
| case OMX_VIDEO_MPEG4ProfileSimple: |
| Profile.mpeg4 = SWVENC_PROFILE_MPEG4_SIMPLE; |
| break; |
| case OMX_VIDEO_MPEG4ProfileAdvancedSimple: |
| Profile.mpeg4 = SWVENC_PROFILE_MPEG4_ADVANCED_SIMPLE; |
| break; |
| default: |
| DEBUG_PRINT_ERROR("ERROR: UNKNOWN PROFILE"); |
| Ret = SWVENC_S_FAILURE; |
| break; |
| } |
| switch (eLevel) |
| { |
| case OMX_VIDEO_MPEG4Level0: |
| Level.mpeg4 = SWVENC_LEVEL_MPEG4_0; |
| break; |
| case OMX_VIDEO_MPEG4Level0b: |
| Level.mpeg4 = SWVENC_LEVEL_MPEG4_0B; |
| break; |
| case OMX_VIDEO_MPEG4Level1: |
| Level.mpeg4 = SWVENC_LEVEL_MPEG4_1; |
| break; |
| case OMX_VIDEO_MPEG4Level2: |
| Level.mpeg4 = SWVENC_LEVEL_MPEG4_2; |
| break; |
| case OMX_VIDEO_MPEG4Level3: |
| Level.mpeg4 = SWVENC_LEVEL_MPEG4_3; |
| break; |
| case OMX_VIDEO_MPEG4Level4: |
| Level.mpeg4 = SWVENC_LEVEL_MPEG4_4; |
| break; |
| case OMX_VIDEO_MPEG4Level4a: |
| Level.mpeg4 = SWVENC_LEVEL_MPEG4_4A; |
| break; |
| case OMX_VIDEO_MPEG4Level5: |
| Level.mpeg4 = SWVENC_LEVEL_MPEG4_5; |
| break; |
| case OMX_VIDEO_MPEG4Level6: |
| Level.mpeg4 = SWVENC_LEVEL_MPEG4_6; |
| break; |
| default: |
| DEBUG_PRINT_ERROR("ERROR: UNKNOWN LEVEL"); |
| Ret = SWVENC_S_FAILURE; |
| break; |
| } |
| } |
| else if (SWVENC_CODEC_H263 == m_codec) |
| { |
| switch (eProfile) |
| { |
| case OMX_VIDEO_H263ProfileBaseline: |
| Profile.h263 = SWVENC_PROFILE_H263_BASELINE; |
| break; |
| default: |
| DEBUG_PRINT_ERROR("ERROR: UNKNOWN PROFILE"); |
| Ret = SWVENC_S_FAILURE; |
| break; |
| } |
| switch (eLevel) |
| { |
| case OMX_VIDEO_H263Level10: |
| Level.h263 = SWVENC_LEVEL_H263_10; |
| break; |
| case OMX_VIDEO_H263Level20: |
| Level.h263 = SWVENC_LEVEL_H263_20; |
| break; |
| case OMX_VIDEO_H263Level30: |
| Level.h263 = SWVENC_LEVEL_H263_30; |
| break; |
| case OMX_VIDEO_H263Level40: |
| Level.h263 = SWVENC_LEVEL_H263_40; |
| break; |
| case OMX_VIDEO_H263Level50: |
| Level.h263 = SWVENC_LEVEL_H263_50; |
| break; |
| case OMX_VIDEO_H263Level60: |
| Level.h263 = SWVENC_LEVEL_H263_60; |
| break; |
| case OMX_VIDEO_H263Level70: |
| Level.h263 = SWVENC_LEVEL_H263_70; |
| break; |
| default: |
| DEBUG_PRINT_ERROR("ERROR: UNKNOWN LEVEL"); |
| Ret = SWVENC_S_FAILURE; |
| break; |
| } |
| } |
| else |
| { |
| DEBUG_PRINT_ERROR("ERROR: UNSUPPORTED CODEC"); |
| Ret = SWVENC_S_FAILURE; |
| } |
| |
| if (SWVENC_S_SUCCESS == Ret) |
| { |
| Prop.id = SWVENC_PROPERTY_ID_PROFILE; |
| Prop.info.profile = Profile; |
| |
| /* set the profile */ |
| Ret = swvenc_setproperty(m_hSwVenc, &Prop); |
| if (Ret != SWVENC_S_SUCCESS) |
| { |
| DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)", |
| __FUNCTION__, Ret); |
| RETURN(SWVENC_S_FAILURE); |
| } |
| |
| /* set the level */ |
| Prop.id = SWVENC_PROPERTY_ID_LEVEL; |
| Prop.info.level = Level; |
| |
| Ret = swvenc_setproperty(m_hSwVenc, &Prop); |
| if (Ret != SWVENC_S_SUCCESS) |
| { |
| DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)", |
| __FUNCTION__, Ret); |
| RETURN(SWVENC_S_FAILURE); |
| } |
| } |
| |
| RETURN(Ret); |
| } |
| |
| SWVENC_STATUS omx_venc::swvenc_set_intra_refresh |
| ( |
| OMX_VIDEO_PARAM_INTRAREFRESHTYPE *IntraRefresh |
| ) |
| { |
| ENTER_FUNC(); |
| |
| SWVENC_STATUS Ret = SWVENC_S_SUCCESS; |
| SWVENC_IR_CONFIG ir_config; |
| SWVENC_PROPERTY Prop; |
| |
| switch (IntraRefresh->eRefreshMode) |
| { |
| case OMX_VIDEO_IntraRefreshCyclic: |
| Prop.info.ir_config.mode = SWVENC_IR_MODE_CYCLIC; |
| break; |
| case OMX_VIDEO_IntraRefreshAdaptive: |
| Prop.info.ir_config.mode = SWVENC_IR_MODE_ADAPTIVE; |
| break; |
| case OMX_VIDEO_IntraRefreshBoth: |
| Prop.info.ir_config.mode = SWVENC_IR_MODE_CYCLIC_ADAPTIVE; |
| break; |
| case OMX_VIDEO_IntraRefreshRandom: |
| Prop.info.ir_config.mode = SWVENC_IR_MODE_RANDOM; |
| break; |
| default: |
| DEBUG_PRINT_ERROR("ERROR: UNKNOWN INTRA REFRESH MODE"); |
| Ret = SWVENC_S_FAILURE; |
| break; |
| } |
| |
| if (SWVENC_S_SUCCESS == Ret) |
| { |
| Prop.id = SWVENC_PROPERTY_ID_IR_CONFIG; |
| Prop.info.ir_config.cir_mbs = IntraRefresh->nCirMBs; |
| |
| Ret = swvenc_setproperty(m_hSwVenc, &Prop); |
| if (Ret != SWVENC_S_SUCCESS) |
| { |
| DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)", |
| __FUNCTION__, Ret); |
| Ret = SWVENC_S_FAILURE; |
| } |
| } |
| |
| RETURN(Ret); |
| } |
| |
| SWVENC_STATUS omx_venc::swvenc_set_frame_rate |
| ( |
| OMX_U32 nFrameRate |
| ) |
| { |
| ENTER_FUNC(); |
| |
| SWVENC_STATUS Ret = SWVENC_S_SUCCESS; |
| SWVENC_PROPERTY Prop; |
| |
| Prop.id = SWVENC_PROPERTY_ID_FRAME_RATE; |
| Prop.info.frame_rate = nFrameRate; |
| |
| Ret = swvenc_setproperty(m_hSwVenc, &Prop); |
| if (Ret != SWVENC_S_SUCCESS) |
| { |
| DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)", |
| __FUNCTION__, Ret); |
| Ret = SWVENC_S_FAILURE; |
| } |
| |
| RETURN(Ret); |
| } |
| |
| SWVENC_STATUS omx_venc::swvenc_set_bit_rate |
| ( |
| OMX_U32 nTargetBitrate |
| ) |
| { |
| ENTER_FUNC(); |
| |
| SWVENC_STATUS Ret = SWVENC_S_SUCCESS; |
| SWVENC_PROPERTY Prop; |
| |
| Prop.id = SWVENC_PROPERTY_ID_TARGET_BITRATE; |
| Prop.info.target_bitrate = nTargetBitrate; |
| |
| Ret = swvenc_setproperty(m_hSwVenc, &Prop); |
| if (Ret != SWVENC_S_SUCCESS) |
| { |
| DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)", |
| __FUNCTION__, Ret); |
| Ret = SWVENC_S_FAILURE; |
| } |
| |
| RETURN(Ret); |
| } |
| |
| SWVENC_STATUS omx_venc::swvenc_set_intra_period |
| ( |
| OMX_U32 nPFrame, |
| OMX_U32 nBFrame |
| ) |
| { |
| ENTER_FUNC(); |
| |
| SWVENC_STATUS Ret = SWVENC_S_SUCCESS; |
| SWVENC_PROPERTY Prop; |
| |
| Prop.id = SWVENC_PROPERTY_ID_INTRA_PERIOD; |
| Prop.info.intra_period.pframes = nPFrame; |
| Prop.info.intra_period.bframes = nBFrame; |
| |
| Ret = swvenc_setproperty(m_hSwVenc, &Prop); |
| if (Ret != SWVENC_S_SUCCESS) |
| { |
| DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)", |
| __FUNCTION__, Ret); |
| Ret = SWVENC_S_FAILURE; |
| } |
| |
| RETURN(Ret); |
| } |
| |
| bool omx_venc::swvenc_color_align(OMX_BUFFERHEADERTYPE *buffer, OMX_U32 width, |
| OMX_U32 height) |
| { |
| OMX_U32 y_stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, width), |
| y_scanlines = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height), |
| uv_stride = VENUS_UV_STRIDE(COLOR_FMT_NV12, width), |
| uv_scanlines = VENUS_UV_SCANLINES(COLOR_FMT_NV12, height), |
| src_chroma_offset = width * height; |
| |
| if (buffer->nAllocLen >= VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height)) { |
| OMX_U8* src_buf = buffer->pBuffer, *dst_buf = buffer->pBuffer; |
| //Do chroma first, so that we can convert it in-place |
| src_buf += width * height; |
| dst_buf += y_stride * y_scanlines; |
| for (int line = height / 2 - 1; line >= 0; --line) { |
| memmove(dst_buf + line * uv_stride, |
| src_buf + line * width, |
| width); |
| } |
| |
| dst_buf = src_buf = buffer->pBuffer; |
| //Copy the Y next |
| for (int line = height - 1; line > 0; --line) { |
| memmove(dst_buf + line * y_stride, |
| src_buf + line * width, |
| width); |
| } |
| } else { |
| DEBUG_PRINT_ERROR("Failed to align Chroma. from %u to %u : \ |
| Insufficient bufferLen=%u v/s Required=%u", |
| (unsigned int)(width*height), (unsigned int)src_chroma_offset, (unsigned int)buffer->nAllocLen, |
| VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height)); |
| return false; |
| } |
| |
| return true; |
| } |
| |
| SWVENC_STATUS omx_venc::swvenc_set_color_format |
| ( |
| OMX_COLOR_FORMATTYPE color_format |
| ) |
| { |
| ENTER_FUNC(); |
| SWVENC_STATUS Ret = SWVENC_S_SUCCESS; |
| SWVENC_COLOR_FORMAT swvenc_color_format; |
| SWVENC_PROPERTY Prop; |
| if ((color_format == OMX_COLOR_FormatYUV420SemiPlanar) || |
| (color_format == ((OMX_COLOR_FORMATTYPE) QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m))) |
| { |
| swvenc_color_format = SWVENC_COLOR_FORMAT_NV12; |
| } |
| else if (color_format == ((OMX_COLOR_FORMATTYPE) QOMX_COLOR_FormatYVU420SemiPlanar)) |
| { |
| swvenc_color_format = SWVENC_COLOR_FORMAT_NV21; |
| } |
| else |
| { |
| DEBUG_PRINT_ERROR("%s: color_format %d invalid",__FUNCTION__,color_format); |
| RETURN(SWVENC_S_FAILURE); |
| } |
| /* set the input color format */ |
| Prop.id = SWVENC_PROPERTY_ID_COLOR_FORMAT; |
| Prop.info.color_format = swvenc_color_format; |
| Ret = swvenc_setproperty(m_hSwVenc, &Prop); |
| if (Ret != SWVENC_S_SUCCESS) |
| { |
| DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)", |
| __FUNCTION__, Ret); |
| Ret = SWVENC_S_FAILURE; |
| } |
| RETURN(Ret); |
| } |
| |
| // don't use init_vendor_extensions() from omx_video_extensions.hpp, sw component doesn't support |
| // all the vendor extensions like hw component |
| void omx_venc::init_sw_vendor_extensions(VendorExtensionStore &store) { |
| ADD_EXTENSION("qti-ext-enc-preprocess-rotate", OMX_IndexConfigCommonRotate, OMX_DirOutput) |
| ADD_PARAM_END("angle", OMX_AndroidVendorValueInt32) |
| |
| ADD_EXTENSION("qti-ext-enc-timestamp-source-avtimer", OMX_QTIIndexParamEnableAVTimerTimestamps, |
| OMX_DirOutput) |
| ADD_PARAM_END("enable", OMX_AndroidVendorValueInt32) |
| } |