diff --git a/driver/platform/kalama/src/msm_vidc_kalama.c b/driver/platform/kalama/src/msm_vidc_kalama.c index b6a8d836ef..21b4f935fb 100644 --- a/driver/platform/kalama/src/msm_vidc_kalama.c +++ b/driver/platform/kalama/src/msm_vidc_kalama.c @@ -19,7 +19,7 @@ #define MAX_LTR_FRAME_COUNT 2 #define MAX_BASE_LAYER_PRIORITY_ID 63 #define MAX_OP_POINT 31 -#define MAX_BITRATE 220000000 +#define MAX_BITRATE 245000000 #define DEFAULT_BITRATE 20000000 #define MINIMUM_FPS 1 #define MAXIMUM_FPS 480 @@ -66,7 +66,7 @@ static struct msm_platform_core_capability core_data_kalama[] = { {MAX_MBPS_HQ, 489600}, /* ((1920x1088)/256)@60fps */ {MAX_MBPF_B_FRAME, 32640}, /* 3840x2176/256 */ {MAX_MBPS_B_FRAME, 1958400}, /* 3840x2176/256 MBs@60fps */ - {MAX_MBPS_ALL_INTRA, 1958400}, /* 3840x2176/256 MBs@60fps */ + {MAX_MBPS_ALL_INTRA, 2088960}, /* 4096x2176/256 MBs@60fps */ {MAX_ENH_LAYER_COUNT, 5}, {NUM_VPP_PIPE, 4}, {SW_PC, 1}, @@ -483,6 +483,18 @@ static struct msm_platform_inst_capability instance_cap_data_kalama[] = { HFI_PROP_RATE_CONTROL, CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU}, + {CABAC_MAX_BITRATE, ENC, H264|HEVC, 0, + 160000000, 1, 160000000}, + + {CAVLC_MAX_BITRATE, ENC, H264, 0, + 220000000, 1, 220000000}, + + {ALLINTRA_MAX_BITRATE, ENC, H264|HEVC, 0, + 245000000, 1, 245000000}, + + {LOWLATENCY_MAX_BITRATE, ENC, H264|HEVC, 0, + 70000000, 1, 70000000}, + {LOSSLESS, ENC, HEVC, V4L2_MPEG_MSM_VIDC_DISABLE, V4L2_MPEG_MSM_VIDC_ENABLE, 1, V4L2_MPEG_MSM_VIDC_DISABLE, @@ -1846,9 +1858,16 @@ static struct msm_platform_inst_cap_dependency instance_cap_dependency_data_kala NULL, msm_vidc_set_req_sync_frame}, - {BIT_RATE, ENC, H264|HEVC, - {ENH_LAYER_COUNT, BITRATE_MODE}, - {PEAK_BITRATE}, + {BIT_RATE, ENC, H264, + {ENH_LAYER_COUNT, BITRATE_MODE, ENTROPY_MODE, + ALL_INTRA, LOWLATENCY_MODE}, + {PEAK_BITRATE, BITRATE_BOOST}, + msm_vidc_adjust_bitrate, + msm_vidc_set_bitrate}, + + {BIT_RATE, ENC, HEVC, + {ENH_LAYER_COUNT, BITRATE_MODE, ALL_INTRA, LOWLATENCY_MODE}, + {PEAK_BITRATE, BITRATE_BOOST}, msm_vidc_adjust_bitrate, msm_vidc_set_bitrate}, @@ -1928,7 +1947,7 @@ static struct msm_platform_inst_cap_dependency instance_cap_dependency_data_kala {LOWLATENCY_MODE, ENC, H264 | HEVC, {BITRATE_MODE, DELIVERY_MODE}, - {STAGE}, + {STAGE, BIT_RATE}, msm_vidc_adjust_enc_lowlatency_mode, NULL}, @@ -1987,7 +2006,7 @@ static struct msm_platform_inst_cap_dependency instance_cap_dependency_data_kala msm_vidc_set_preprocess}, {BITRATE_BOOST, ENC, H264|HEVC, - {BITRATE_MODE, MIN_QUALITY}, + {BITRATE_MODE, MIN_QUALITY, BIT_RATE}, {0}, msm_vidc_adjust_bitrate_boost_iris3, msm_vidc_set_vbr_related_properties}, @@ -2135,7 +2154,7 @@ static struct msm_platform_inst_cap_dependency instance_cap_dependency_data_kala {ENTROPY_MODE, ENC, H264, {PROFILE}, - {0}, + {BIT_RATE}, msm_vidc_adjust_entropy_mode, msm_vidc_set_u32}, @@ -2345,7 +2364,7 @@ static struct msm_platform_inst_cap_dependency instance_cap_dependency_data_kala {ALL_INTRA, ENC, H264|HEVC, {GOP_SIZE, B_FRAME}, - {LTR_COUNT, IR_PERIOD, SLICE_MODE}, + {LTR_COUNT, IR_PERIOD, SLICE_MODE, BIT_RATE}, msm_vidc_adjust_all_intra, NULL}, diff --git a/driver/variant/iris3/src/msm_vidc_iris3.c b/driver/variant/iris3/src/msm_vidc_iris3.c index 9dc8fa6222..62288ed9b8 100644 --- a/driver/variant/iris3/src/msm_vidc_iris3.c +++ b/driver/variant/iris3/src/msm_vidc_iris3.c @@ -1110,8 +1110,9 @@ int msm_vidc_decide_quality_mode_iris3(struct msm_vidc_inst* inst) if (!is_encode_session(inst)) return 0; - /* image session or lossless encode always runs at quality mode */ - if (is_image_session(inst) || capability->cap[LOSSLESS].value) { + /* image or lossless or all intra runs at quality mode */ + if (is_image_session(inst) || capability->cap[LOSSLESS].value || + capability->cap[ALL_INTRA].value) { mode = MSM_VIDC_MAX_QUALITY_MODE; goto decision_done; } @@ -1154,6 +1155,7 @@ int msm_vidc_adjust_bitrate_boost_iris3(void* instance, struct v4l2_ctrl *ctrl) s32 rc_type = -1; u32 width, height, frame_rate; struct v4l2_format *f; + u32 max_bitrate = 0, bitrate = 0; if (!inst || !inst->capabilities) { d_vpr_e("%s: invalid params\n", __func__); @@ -1201,6 +1203,16 @@ int msm_vidc_adjust_bitrate_boost_iris3(void* instance, struct v4l2_ctrl *ctrl) adjusted_value = 0; } + max_bitrate = msm_vidc_get_max_bitrate(inst); + bitrate = inst->capabilities->cap[BIT_RATE].value; + if (adjusted_value) { + if ((bitrate + bitrate / (100 / adjusted_value)) > max_bitrate) { + i_vpr_h(inst, + "%s: bitrate %d is beyond max bitrate %d, remove bitrate boost\n", + __func__, max_bitrate, bitrate); + adjusted_value = 0; + } + } adjust: msm_vidc_update_cap_value(inst, BITRATE_BOOST, adjusted_value, __func__); diff --git a/driver/vidc/inc/msm_vidc_driver.h b/driver/vidc/inc/msm_vidc_driver.h index 2c8f03ed29..998b390ad2 100644 --- a/driver/vidc/inc/msm_vidc_driver.h +++ b/driver/vidc/inc/msm_vidc_driver.h @@ -510,6 +510,7 @@ int msm_vidc_state_change_start(struct msm_vidc_inst *inst); int msm_vidc_state_change_input_psc(struct msm_vidc_inst *inst); int msm_vidc_state_change_last_flag(struct msm_vidc_inst *inst); int msm_vidc_get_mbs_per_frame(struct msm_vidc_inst *inst); +u32 msm_vidc_get_max_bitrate(struct msm_vidc_inst* inst); int msm_vidc_get_fps(struct msm_vidc_inst *inst); int msm_vidc_num_buffers(struct msm_vidc_inst *inst, enum msm_vidc_buffer_type type, enum msm_vidc_buffer_attributes attr); diff --git a/driver/vidc/inc/msm_vidc_internal.h b/driver/vidc/inc/msm_vidc_internal.h index 5892b5d219..22a52377ee 100644 --- a/driver/vidc/inc/msm_vidc_internal.h +++ b/driver/vidc/inc/msm_vidc_internal.h @@ -491,6 +491,10 @@ enum msm_vidc_inst_capability_type { INPUT_META_VIA_REQUEST, ENC_IP_CR, COMPLEXITY, + CABAC_MAX_BITRATE, + CAVLC_MAX_BITRATE, + ALLINTRA_MAX_BITRATE, + LOWLATENCY_MAX_BITRATE, /* place all root(no parent) enums before this line */ PROFILE, diff --git a/driver/vidc/src/msm_vidc_control.c b/driver/vidc/src/msm_vidc_control.c index 50cf705d07..fa69033a61 100644 --- a/driver/vidc/src/msm_vidc_control.c +++ b/driver/vidc/src/msm_vidc_control.c @@ -2079,9 +2079,10 @@ int msm_vidc_adjust_bitrate(void *instance, struct v4l2_ctrl *ctrl) int i, rc = 0; struct msm_vidc_inst *inst = (struct msm_vidc_inst *) instance; struct msm_vidc_inst_capability *capability; - s32 adjusted_value, max_bitrate, enh_layer_count; + s32 adjusted_value, enh_layer_count; u32 cumulative_bitrate = 0, cap_id = 0, cap_value = 0; u32 layer_br_caps[6] = {L0_BR, L1_BR, L2_BR, L3_BR, L4_BR, L5_BR}; + u32 max_bitrate = 0; if (!inst || !inst->capabilities) { d_vpr_e("%s: invalid params\n", __func__); @@ -2110,7 +2111,10 @@ int msm_vidc_adjust_bitrate(void *instance, struct v4l2_ctrl *ctrl) ENH_LAYER_COUNT, &enh_layer_count, __func__)) return -EINVAL; - max_bitrate = inst->capabilities->cap[BIT_RATE].max; + /* get max bit rate for current session config*/ + max_bitrate = msm_vidc_get_max_bitrate(inst); + if (inst->capabilities->cap[BIT_RATE].value > max_bitrate) + msm_vidc_update_cap_value(inst, BIT_RATE, max_bitrate, __func__); /* * ENH_LAYER_COUNT cap max is positive only if @@ -2584,6 +2588,7 @@ int msm_vidc_adjust_bitrate_boost(void *instance, struct v4l2_ctrl *ctrl) s32 adjusted_value; struct msm_vidc_inst *inst = (struct msm_vidc_inst *) instance; s32 min_quality = -1, rc_type = -1; + u32 max_bitrate = 0, bitrate = 0; if (!inst || !inst->capabilities) { d_vpr_e("%s: invalid params\n", __func__); @@ -2617,6 +2622,17 @@ int msm_vidc_adjust_bitrate_boost(void *instance, struct v4l2_ctrl *ctrl) goto adjust; } + max_bitrate = msm_vidc_get_max_bitrate(inst); + bitrate = inst->capabilities->cap[BIT_RATE].value; + if (adjusted_value) { + if ((bitrate + bitrate / (100 / adjusted_value)) > max_bitrate) { + i_vpr_h(inst, + "%s: bitrate %d is beyond max bitrate %d, remove bitrate boost\n", + __func__, max_bitrate, bitrate); + adjusted_value = 0; + } + } + adjust: msm_vidc_update_cap_value(inst, BITRATE_BOOST, adjusted_value, __func__); diff --git a/driver/vidc/src/msm_vidc_driver.c b/driver/vidc/src/msm_vidc_driver.c index 620c653712..c209dd6713 100644 --- a/driver/vidc/src/msm_vidc_driver.c +++ b/driver/vidc/src/msm_vidc_driver.c @@ -189,6 +189,10 @@ static const struct msm_vidc_cap_name cap_name_arr[] = { {INPUT_META_VIA_REQUEST, "INPUT_META_VIA_REQUEST" }, {ENC_IP_CR, "ENC_IP_CR" }, {COMPLEXITY, "COMPLEXITY" }, + {CABAC_MAX_BITRATE, "CABAC_MAX_BITRATE" }, + {CAVLC_MAX_BITRATE, "CAVLC_MAX_BITRATE" }, + {ALLINTRA_MAX_BITRATE, "ALLINTRA_MAX_BITRATE" }, + {LOWLATENCY_MAX_BITRATE, "LOWLATENCY_MAX_BITRATE" }, {PROFILE, "PROFILE" }, {ENH_LAYER_COUNT, "ENH_LAYER_COUNT" }, {BIT_RATE, "BIT_RATE" }, @@ -6137,6 +6141,43 @@ static int msm_vidc_check_inst_mbpf(struct msm_vidc_inst *inst) return 0; } +u32 msm_vidc_get_max_bitrate(struct msm_vidc_inst* inst) +{ + struct msm_vidc_inst_capability *capability; + u32 max_bitrate = 0x7fffffff; + + if (!inst || !inst->capabilities) { + d_vpr_e("%s: invalid params\n", __func__); + return -EINVAL; + } + capability = inst->capabilities; + + if (inst->capabilities->cap[LOWLATENCY_MODE].value) + max_bitrate = min(max_bitrate, + (u32)inst->capabilities->cap[LOWLATENCY_MAX_BITRATE].max); + + if (inst->capabilities->cap[ALL_INTRA].value) + max_bitrate = min(max_bitrate, + (u32)inst->capabilities->cap[ALLINTRA_MAX_BITRATE].max); + + if (inst->codec == MSM_VIDC_HEVC) { + max_bitrate = min(max_bitrate, + (u32)inst->capabilities->cap[CABAC_MAX_BITRATE].max); + } else if (inst->codec == MSM_VIDC_H264) { + if (inst->capabilities->cap[ENTROPY_MODE].value == + V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC) + max_bitrate = min(max_bitrate, + (u32)inst->capabilities->cap[CAVLC_MAX_BITRATE].max); + else + max_bitrate = min(max_bitrate, + (u32)inst->capabilities->cap[CABAC_MAX_BITRATE].max); + } + if (max_bitrate == 0x7fffffff || !max_bitrate) + max_bitrate = min(max_bitrate, (u32)inst->capabilities->cap[BIT_RATE].max); + + return max_bitrate; +} + static bool msm_vidc_allow_image_encode_session(struct msm_vidc_inst *inst) { struct msm_vidc_inst_capability *capability;