diff options
Diffstat (limited to 'mm-video-v4l2')
-rw-r--r-- | mm-video-v4l2/vidc/common/src/vidc_common.cpp | 4 | ||||
-rw-r--r-- | mm-video-v4l2/vidc/venc/inc/omx_video_base.h | 3 | ||||
-rw-r--r-- | mm-video-v4l2/vidc/venc/inc/omx_video_encoder.h | 5 | ||||
-rw-r--r-- | mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h | 5 | ||||
-rw-r--r-- | mm-video-v4l2/vidc/venc/src/omx_video_base.cpp | 24 | ||||
-rw-r--r-- | mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp | 47 | ||||
-rw-r--r-- | mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp | 111 |
7 files changed, 158 insertions, 41 deletions
diff --git a/mm-video-v4l2/vidc/common/src/vidc_common.cpp b/mm-video-v4l2/vidc/common/src/vidc_common.cpp index f960e963..db96ecef 100644 --- a/mm-video-v4l2/vidc/common/src/vidc_common.cpp +++ b/mm-video-v4l2/vidc/common/src/vidc_common.cpp @@ -1,5 +1,5 @@ /*-------------------------------------------------------------------------- -Copyright (c) 2017, The Linux Foundation. All rights reserved. +Copyright (c) 2017 - 2018 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 @@ -60,6 +60,8 @@ pl_map profile_level_converter::profile_hevc_omx_to_v4l2 ({ V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN}, {OMX_VIDEO_HEVCProfileMain10HDR10, V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10}, + {OMX_VIDEO_HEVCProfileMainStill, + V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN_STILL_PIC}, }); pl_map profile_level_converter::profile_hevc_v4l2_to_omx ({}); diff --git a/mm-video-v4l2/vidc/venc/inc/omx_video_base.h b/mm-video-v4l2/vidc/venc/inc/omx_video_base.h index 0027694d..5908843a 100644 --- a/mm-video-v4l2/vidc/venc/inc/omx_video_base.h +++ b/mm-video-v4l2/vidc/venc/inc/omx_video_base.h @@ -1,5 +1,5 @@ /*-------------------------------------------------------------------------- -Copyright (c) 2010-2017, The Linux Foundation. All rights reserved. +Copyright (c) 2010-2018, 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 @@ -730,6 +730,7 @@ class omx_video: public qc_omx_component QOMX_EXTNINDEX_VIDEO_LOW_LATENCY_MODE m_sParamLowLatency; OMX_U32 m_nOperatingRate; QOMX_ENABLETYPE m_sParamColorSpaceConversion; + OMX_VIDEO_PARAM_ANDROID_IMAGEGRIDTYPE m_sParamAndroidImageGrid; // fill this buffer queue omx_cmd_queue m_ftb_q; diff --git a/mm-video-v4l2/vidc/venc/inc/omx_video_encoder.h b/mm-video-v4l2/vidc/venc/inc/omx_video_encoder.h index cba870d9..3ac07f3d 100644 --- a/mm-video-v4l2/vidc/venc/inc/omx_video_encoder.h +++ b/mm-video-v4l2/vidc/venc/inc/omx_video_encoder.h @@ -1,5 +1,5 @@ /*-------------------------------------------------------------------------- -Copyright (c) 2010-2017, The Linux Foundation. All rights reserved. +Copyright (c) 2010-2018, 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 @@ -37,6 +37,9 @@ extern "C" { OMX_API void * get_omx_component_factory_fn(void); } +#define DEFAULT_TILE_DIMENSION 512 +#define DEFAULT_TILE_COUNT 40 + class omx_venc: public omx_video { public: diff --git a/mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h b/mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h index e7d56eff..1d2fc5ae 100644 --- a/mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h +++ b/mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h @@ -285,8 +285,9 @@ enum rc_modes { RC_CBR_CFR = BIT(3), RC_MBR_CFR = BIT(4), RC_MBR_VFR = BIT(5), + RC_CQ = BIT(6), RC_ALL = (RC_VBR_VFR | RC_VBR_CFR - | RC_CBR_VFR | RC_CBR_CFR | RC_MBR_CFR | RC_MBR_VFR) + | RC_CBR_VFR | RC_CBR_CFR | RC_MBR_CFR | RC_MBR_VFR | RC_CQ) }; class venc_dev @@ -468,7 +469,6 @@ class venc_dev bool bframe_implicitly_enabled; bool client_req_disable_temporal_layers; bool client_req_turbo_mode; - static const unsigned int QFQPMapping[21]; bool venc_query_cap(struct v4l2_queryctrl &cap); bool venc_validate_range(OMX_S32 id, OMX_S32 val); @@ -530,6 +530,7 @@ class venc_dev bool venc_set_iframesize_type(QOMX_VIDEO_IFRAMESIZE_TYPE type); unsigned long venc_get_color_format(OMX_COLOR_FORMATTYPE eColorFormat); unsigned long venc_get_codectype(OMX_VIDEO_CODINGTYPE eCompressionFormat); + bool venc_set_tile_dimension(OMX_U32 nTileDimension); OMX_U32 pmem_free(); OMX_U32 pmem_allocate(OMX_U32 size, OMX_U32 alignment, OMX_U32 count); diff --git a/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp b/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp index 00072fc2..016f5cb9 100644 --- a/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp +++ b/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp @@ -1,5 +1,5 @@ /*-------------------------------------------------------------------------- -Copyright (c) 2010-2017, Linux Foundation. All rights reserved. +Copyright (c) 2010-2018, Linux Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -1582,6 +1582,16 @@ OMX_ERRORTYPE omx_video::get_parameter(OMX_IN OMX_HANDLETYPE hComp, } memcpy(portDefn, &m_sOutPortDef, sizeof(m_sOutPortDef)); + // Tiling in HW expects output port def to be aligned to tile size + // At the same time, FWK needs original WxH for various purposes + // Sending input WxH as output port def WxH to FWK + if (m_sOutPortDef.format.video.eCompressionFormat == + OMX_VIDEO_CodingHEIC) { + portDefn->format.video.nFrameWidth = + m_sInPortDef.format.video.nFrameWidth; + portDefn->format.video.nFrameHeight = + m_sInPortDef.format.video.nFrameHeight; + } if (secure_session || allocate_native_handle) { portDefn->nBufferSize = @@ -1706,6 +1716,15 @@ OMX_ERRORTYPE omx_video::get_parameter(OMX_IN OMX_HANDLETYPE hComp, memcpy(pParam, &m_sParamTME, sizeof(m_sParamTME)); break; } + case OMX_IndexParamVideoAndroidImageGrid: + { + VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_ANDROID_IMAGEGRIDTYPE); + OMX_VIDEO_PARAM_ANDROID_IMAGEGRIDTYPE* pParam = + (OMX_VIDEO_PARAM_ANDROID_IMAGEGRIDTYPE*)paramData; + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAndroidImageGrid"); + memcpy(pParam, &m_sParamAndroidImageGrid, sizeof(m_sParamAndroidImageGrid)); + break; + } case OMX_IndexParamVideoProfileLevelQuerySupported: { VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE); @@ -4331,7 +4350,8 @@ OMX_ERRORTYPE omx_video::component_role_enum(OMX_IN OMX_HANDLETYPE hComp, DEBUG_PRINT_ERROR("ERROR: No more roles"); eRet = OMX_ErrorNoMore; } - } else if (!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.hevc", OMX_MAX_STRINGNAME_SIZE)) { + } else if (!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.hevc", OMX_MAX_STRINGNAME_SIZE) || + !strncmp((char*)m_nkind, "OMX.qcom.video.encoder.heic", OMX_MAX_STRINGNAME_SIZE)) { if ((0 == index) && role) { strlcpy((char *)role, "video_encoder.hevc", OMX_MAX_STRINGNAME_SIZE); DEBUG_PRINT_LOW("component_role_enum: role %s", role); diff --git a/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp b/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp index 540f8b5a..8181347c 100644 --- a/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp +++ b/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp @@ -1,5 +1,5 @@ /*-------------------------------------------------------------------------- -Copyright (c) 2010-2017, The Linux Foundation. All rights reserved. +Copyright (c) 2010-2018, 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: @@ -124,6 +124,10 @@ OMX_ERRORTYPE omx_venc::component_init(OMX_STRING role) OMX_MAX_STRINGNAME_SIZE)) { strlcpy((char *)m_cRole, "video_encoder.hevc", OMX_MAX_STRINGNAME_SIZE); codec_type = OMX_VIDEO_CodingHEVC; + } else if (!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.heic", \ + OMX_MAX_STRINGNAME_SIZE)) { + strlcpy((char *)m_cRole, "video_encoder.hevc", OMX_MAX_STRINGNAME_SIZE); + codec_type = OMX_VIDEO_CodingHEIC; } else if (!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.hevc.secure", \ OMX_MAX_STRINGNAME_SIZE)) { strlcpy((char *)m_cRole, "video_encoder.hevc", OMX_MAX_STRINGNAME_SIZE); @@ -264,6 +268,9 @@ OMX_ERRORTYPE omx_venc::component_init(OMX_STRING role) } else if (codec_type == OMX_VIDEO_CodingHEVC) { m_sParamProfileLevel.eProfile = (OMX_U32) OMX_VIDEO_HEVCProfileMain; m_sParamProfileLevel.eLevel = (OMX_U32) OMX_VIDEO_HEVCMainTierLevel1; + } else if (codec_type == OMX_VIDEO_CodingHEIC) { + m_sParamProfileLevel.eProfile = (OMX_U32) OMX_VIDEO_HEVCProfileMainStill; + m_sParamProfileLevel.eLevel = (OMX_U32) OMX_VIDEO_HEVCMainTierLevel1; } OMX_INIT_STRUCT(&m_sParamEntropy, QOMX_VIDEO_H264ENTROPYCODINGTYPE); @@ -313,6 +320,8 @@ OMX_ERRORTYPE omx_venc::component_init(OMX_STRING role) m_sOutPortDef.format.video.eCompressionFormat = OMX_VIDEO_CodingVP8; } else if (codec_type == OMX_VIDEO_CodingHEVC) { m_sOutPortDef.format.video.eCompressionFormat = OMX_VIDEO_CodingHEVC; + } else if (codec_type == OMX_VIDEO_CodingHEIC) { + m_sOutPortDef.format.video.eCompressionFormat = OMX_VIDEO_CodingHEIC; } else if (codec_type == (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingTME) { m_sOutPortDef.format.video.eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingTME; } @@ -344,6 +353,8 @@ OMX_ERRORTYPE omx_venc::component_init(OMX_STRING role) m_sOutPortFormat.eCompressionFormat = OMX_VIDEO_CodingVP8; } else if (codec_type == OMX_VIDEO_CodingHEVC) { m_sOutPortFormat.eCompressionFormat = OMX_VIDEO_CodingHEVC; + } else if (codec_type == OMX_VIDEO_CodingHEIC) { + m_sOutPortFormat.eCompressionFormat = OMX_VIDEO_CodingHEIC; } else if (codec_type == (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingTME) { m_sOutPortFormat.eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingTME; } @@ -405,6 +416,15 @@ OMX_ERRORTYPE omx_venc::component_init(OMX_STRING role) m_sParamTME.eLevel = QOMX_VIDEO_TMELevelInteger; m_sParamTME.ePayloadVersion = tme_payload_version; + // HEIC specific init + OMX_INIT_STRUCT(&m_sParamAndroidImageGrid, OMX_VIDEO_PARAM_ANDROID_IMAGEGRIDTYPE); + m_sParamAndroidImageGrid.nPortIndex = (OMX_U32) PORT_INDEX_OUT; + m_sParamAndroidImageGrid.bEnabled = OMX_FALSE; + m_sParamAndroidImageGrid.nTileWidth = DEFAULT_TILE_DIMENSION; + m_sParamAndroidImageGrid.nTileHeight = DEFAULT_TILE_DIMENSION; + m_sParamAndroidImageGrid.nGridRows = DEFAULT_TILE_COUNT; + m_sParamAndroidImageGrid.nGridCols = DEFAULT_TILE_COUNT; + OMX_INIT_STRUCT(&m_sParamLTRCount, QOMX_VIDEO_PARAM_LTRCOUNT_TYPE); m_sParamLTRCount.nPortIndex = (OMX_U32) PORT_INDEX_OUT; m_sParamLTRCount.nCount = 0; @@ -812,6 +832,19 @@ OMX_ERRORTYPE omx_venc::set_parameter(OMX_IN OMX_HANDLETYPE hComp, m_sParamTME.ePayloadVersion = tme_payload_version; break; } + case OMX_IndexParamVideoAndroidImageGrid: + { + VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_ANDROID_IMAGEGRIDTYPE); + DEBUG_PRINT_LOW("set_param:OMX_IndexParamVideoAndroidImageGrid"); + OMX_VIDEO_PARAM_ANDROID_IMAGEGRIDTYPE* pParam = + (OMX_VIDEO_PARAM_ANDROID_IMAGEGRIDTYPE*)paramData; + if (!handle->venc_set_param(paramData, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidImageGrid)) { + DEBUG_PRINT_ERROR("ERROR: Request for setting image grid failed"); + return OMX_ErrorUnsupportedSetting; + } + memcpy(&m_sParamAndroidImageGrid, pParam, sizeof(m_sParamAndroidImageGrid)); + break; + } case OMX_IndexParamVideoProfileLevelCurrent: { VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE); @@ -846,6 +879,8 @@ OMX_ERRORTYPE omx_venc::set_parameter(OMX_IN OMX_HANDLETYPE hComp, m_sParamVP8.eLevel); } else if (!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.hevc",\ + OMX_MAX_STRINGNAME_SIZE) || + !strncmp((char*)m_nkind, "OMX.qcom.video.encoder.heic",\ OMX_MAX_STRINGNAME_SIZE)) { m_sParamHEVC.eProfile = (OMX_VIDEO_HEVCPROFILETYPE)m_sParamProfileLevel.eProfile; m_sParamHEVC.eLevel = (OMX_VIDEO_HEVCLEVELTYPE)m_sParamProfileLevel.eLevel; @@ -901,6 +936,14 @@ OMX_ERRORTYPE omx_venc::set_parameter(OMX_IN OMX_HANDLETYPE hComp, eRet = OMX_ErrorUnsupportedSetting; } } + else if (!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.heic",OMX_MAX_STRINGNAME_SIZE)) { + if (!strncmp((const char*)comp_role->cRole,"image_encoder.heic",OMX_MAX_STRINGNAME_SIZE)) { + strlcpy((char*)m_cRole,"video_encoder.hevc",OMX_MAX_STRINGNAME_SIZE); + } else { + DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown Index %s", comp_role->cRole); + eRet = OMX_ErrorUnsupportedSetting; + } + } else if (!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.tme", OMX_MAX_STRINGNAME_SIZE)) { if (!strncmp((const char*)comp_role->cRole,"video_encoder.tme",OMX_MAX_STRINGNAME_SIZE)) { strlcpy((char*)m_cRole,"video_encoder.tme",OMX_MAX_STRINGNAME_SIZE); @@ -1596,6 +1639,8 @@ bool omx_venc::update_profile_level() m_sParamVP8.eLevel); } else if (!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.hevc",\ + OMX_MAX_STRINGNAME_SIZE) || + !strncmp((char *)m_nkind, "OMX.qcom.video.encoder.heic",\ OMX_MAX_STRINGNAME_SIZE)) { m_sParamHEVC.eProfile = (OMX_VIDEO_HEVCPROFILETYPE)eProfile; m_sParamHEVC.eLevel = (OMX_VIDEO_HEVCLEVELTYPE)eLevel; diff --git a/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp b/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp index bd1e9ef4..e798d4ff 100644 --- a/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp +++ b/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp @@ -86,10 +86,6 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define VENC_BFRAME_MAX_WIDTH 1920 #define VENC_BFRAME_MAX_HEIGHT 1088 -// Scaled quality factor - QP mapping -#define SCALED_QUALITY_FACTOR_MAX 20 -const unsigned int venc_dev::QFQPMapping[21] = {51, 47, 43, 39, 35, 31, 28, 25, 22, 19, 16, 13, 11, 9, 7, 5, 6, 4, 3, 2}; - #undef LOG_TAG #define LOG_TAG "OMX-VENC: venc_dev" @@ -948,8 +944,9 @@ OMX_ERRORTYPE venc_dev::venc_get_supported_profile_level(OMX_VIDEO_PARAM_PROFILE QOMX_VIDEO_AVCProfileMain, QOMX_VIDEO_AVCProfileConstrainedHigh, QOMX_VIDEO_AVCProfileHigh }; - int hevc_profiles[2] = { OMX_VIDEO_HEVCProfileMain, - OMX_VIDEO_HEVCProfileMain10HDR10 }; + int hevc_profiles[3] = { OMX_VIDEO_HEVCProfileMain, + OMX_VIDEO_HEVCProfileMain10HDR10, + OMX_VIDEO_HEVCProfileMainStill }; if (!profileLevelType) return OMX_ErrorBadParameter; @@ -1412,12 +1409,15 @@ bool venc_dev::venc_open(OMX_U32 codec) profile_level.level = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0; minqp = 0; maxqp = 127; - } else if (codec == OMX_VIDEO_CodingHEVC) { + } else if (codec == OMX_VIDEO_CodingHEVC || codec == OMX_VIDEO_CodingHEIC) { m_sVenc_cfg.codectype = V4L2_PIX_FMT_HEVC; idrperiod.idrperiod = 1; minqp = 0; maxqp = 51; - codec_profile.profile = V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN; + if (codec == OMX_VIDEO_CodingHEIC) + codec_profile.profile = V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN_STILL_PIC; + else + codec_profile.profile = V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN; profile_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_1; } else if (codec == QOMX_VIDEO_CodingTME) { m_sVenc_cfg.codectype = V4L2_PIX_FMT_TME; @@ -2011,9 +2011,15 @@ bool venc_dev::venc_set_param(void *paramData, OMX_INDEXTYPE index) portDefn->nPortIndex); } } else if (portDefn->nPortIndex == PORT_INDEX_OUT) { - unsigned long codectype = venc_get_codectype(portDefn->format.video.eCompressionFormat); + if (portDefn->format.video.eCompressionFormat == OMX_VIDEO_CodingHEIC) { + portDefn->format.video.nFrameWidth = DEFAULT_TILE_DIMENSION; + portDefn->format.video.nFrameHeight = DEFAULT_TILE_DIMENSION; + DEBUG_PRINT_HIGH("set_parameter: OMX_IndexParamPortDefinition: port %d, wxh (for HEIC coding type) %dx%d", + portDefn->nPortIndex, portDefn->format.video.nFrameWidth, + portDefn->format.video.nFrameHeight); + } //Don't worry about width/height if downscalar is enabled. if (((m_sVenc_cfg.dvs_height != portDefn->format.video.nFrameHeight || m_sVenc_cfg.dvs_width != portDefn->format.video.nFrameWidth) && !downscalar_enabled) || @@ -2109,14 +2115,6 @@ bool venc_dev::venc_set_param(void *paramData, OMX_INDEXTYPE index) DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoBitrate"); if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) { - // Quality factor setting - unsigned int scaledQF; - if (pParam->eControlRate == OMX_Video_ControlRateConstantQuality) { - pParam->eControlRate = OMX_Video_ControlRateDisable; - scaledQF = pParam->nQualityFactor / 5; - scaledQF = (scaledQF > SCALED_QUALITY_FACTOR_MAX) ? SCALED_QUALITY_FACTOR_MAX : scaledQF; - } - if (!venc_set_target_bitrate(pParam->nTargetBitrate)) { DEBUG_PRINT_ERROR("ERROR: Setting Target Bit Rate / Quality Factor failed"); return false; @@ -2126,18 +2124,6 @@ bool venc_dev::venc_set_param(void *paramData, OMX_INDEXTYPE index) DEBUG_PRINT_ERROR("ERROR: Rate Control setting failed"); return false; } - // Setting QP values - if (((OMX_VIDEO_PARAM_BITRATETYPE*)paramData)->eControlRate == OMX_Video_ControlRateDisable) { - if (venc_set_qp(QFQPMapping[scaledQF], - QFQPMapping[scaledQF], - QFQPMapping[scaledQF], - ENABLE_I_QP | ENABLE_P_QP | ENABLE_B_QP) == false) { - DEBUG_PRINT_ERROR("ERROR: Setting QP values failed"); - return false; - } - DEBUG_PRINT_LOW("Rate control: %u Quality factor(client): %u scaledQF: %u", - pParam->eControlRate, pParam->nQualityFactor, scaledQF); - } } else { DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoBitrate"); } @@ -2266,6 +2252,24 @@ bool venc_dev::venc_set_param(void *paramData, OMX_INDEXTYPE index) } break; } + case (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidImageGrid: + { + DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoAndroidImageGrid"); + OMX_VIDEO_PARAM_ANDROID_IMAGEGRIDTYPE* pParam = + (OMX_VIDEO_PARAM_ANDROID_IMAGEGRIDTYPE*)paramData; + + if (m_codec != OMX_VIDEO_CodingHEIC) { + DEBUG_PRINT_ERROR("OMX_IndexParamVideoAndroidImageGrid is only supported for HEIC"); + return false; + } + + if (!venc_set_tile_dimension(pParam->nTileWidth)) { + DEBUG_PRINT_ERROR("ERROR: Failed to set tile dimension %d", + pParam->nTileWidth); + return false; + } + break; + } case OMX_IndexParamVideoIntraRefresh: { DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoIntraRefresh"); @@ -4248,7 +4252,9 @@ bool venc_dev::venc_empty_buf(void *buffer, void *pmem_data_buf, unsigned index, return false; } - if (inp_width * inp_height != out_width * out_height) { + // Tiling in HEIC requires output WxH to be Tile size; difference is permitted + if (!(m_codec == OMX_VIDEO_CodingHEIC) && + inp_width * inp_height != out_width * out_height) { DEBUG_PRINT_ERROR("Downscalar is disabled and input/output dimenstions don't match"); DEBUG_PRINT_ERROR("Input WxH : %dx%d Output WxH : %dx%d",inp_width, inp_height, out_width, out_height); return false; @@ -5026,7 +5032,9 @@ bool venc_dev::venc_reconfigure_intra_period() if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC && ((codec_profile.profile == V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN) || - (codec_profile.profile == V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10))) { + (codec_profile.profile == V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10) || + (codec_profile.profile == V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN_STILL_PIC)) && + (m_codec != OMX_VIDEO_CodingHEIC)) { isValidCodec = true; } @@ -5125,6 +5133,27 @@ bool venc_dev::venc_reconfigure_intra_period() return true; } +bool venc_dev::venc_set_tile_dimension(OMX_U32 nTileDimension) +{ + int rc; + struct v4l2_control control; + + DEBUG_PRINT_LOW("venc_set_tile_dimension: nTileDimension = %u", (unsigned int)nTileDimension); + + control.id = V4L2_CID_MPEG_VIDC_IMG_GRID_DIMENSION; + control.value = nTileDimension; + rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); + + if (rc) { + DEBUG_PRINT_ERROR("Failed to set control, id %#x, value %d", control.id, control.value); + return false; + } + + DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value); + + return true; +} + bool venc_dev::venc_set_intra_period(OMX_U32 nPFrames, OMX_U32 nBFrames) { DEBUG_PRINT_LOW("venc_set_intra_period: nPFrames = %u, nBFrames: %u", (unsigned int)nPFrames, (unsigned int)nBFrames); @@ -5143,7 +5172,8 @@ bool venc_dev::_venc_set_intra_period(OMX_U32 nPFrames, OMX_U32 nBFrames) char property_value[PROPERTY_VALUE_MAX] = {0}; if (m_sVenc_cfg.codectype != V4L2_PIX_FMT_H264 && - m_sVenc_cfg.codectype != V4L2_PIX_FMT_HEVC) { + m_sVenc_cfg.codectype != V4L2_PIX_FMT_HEVC && + m_codec == OMX_VIDEO_CodingHEIC) { nBFrames = 0; } @@ -5151,6 +5181,7 @@ bool venc_dev::_venc_set_intra_period(OMX_U32 nPFrames, OMX_U32 nBFrames) (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) && (codec_profile.profile != V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN) && (codec_profile.profile != V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10) && + (codec_profile.profile != V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN_STILL_PIC) && (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)) { nBFrames = 0; } @@ -5518,7 +5549,10 @@ bool venc_dev::venc_set_target_bitrate(OMX_U32 nTargetBitrate) return true; } - control.id = V4L2_CID_MPEG_VIDEO_BITRATE; + if (rate_ctrl.rcmode == V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CQ) + control.id = V4L2_CID_MPEG_VIDC_VIDEO_FRAME_QUALITY; + else + control.id = V4L2_CID_MPEG_VIDEO_BITRATE; control.value = nTargetBitrate; DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value); @@ -5530,6 +5564,8 @@ bool venc_dev::venc_set_target_bitrate(OMX_U32 nTargetBitrate) DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value); + if (control.id == V4L2_CID_MPEG_VIDC_VIDEO_FRAME_QUALITY) + return true; m_sVenc_cfg.targetbitrate = control.value; bitrate.target_bitrate = control.value; @@ -5600,6 +5636,7 @@ unsigned long venc_dev::venc_get_codectype(OMX_VIDEO_CODINGTYPE eCompressionForm case OMX_VIDEO_CodingVP9: codectype = V4L2_PIX_FMT_VP9; break; + case OMX_VIDEO_CodingHEIC: case OMX_VIDEO_CodingHEVC: codectype = V4L2_PIX_FMT_HEVC; break; @@ -6127,6 +6164,11 @@ bool venc_dev::venc_set_ratectrl_cfg(OMX_VIDEO_CONTROLRATETYPE eControlRate) control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_MBR_VFR: status = false; break; + case OMX_Video_ControlRateConstantQuality: + (supported_rc_modes & RC_CQ) ? + control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CQ: + status = false; + break; default: status = false; break; @@ -7142,6 +7184,9 @@ bool venc_dev::venc_get_profile_level(OMX_U32 *eProfile,OMX_U32 *eLevel) case V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10: *eProfile = OMX_VIDEO_HEVCProfileMain10HDR10; break; + case V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN_STILL_PIC: + *eProfile = OMX_VIDEO_HEVCProfileMainStill; + break; default: *eProfile = OMX_VIDEO_HEVCProfileMax; status = false; |