浏览代码

video: driver: fix layer bitrate dynamic setting

Fix the issue where bitrate cap database value is
incorrectly updated to dynamically client set layer bitrate
value when layer bitarte is not set.

Change-Id: I0f66c056c8ea0d053f8347dd003b61193258687e
Signed-off-by: Akshata Sahukar <[email protected]>
Akshata Sahukar 4 年之前
父节点
当前提交
78bd0f54eb
共有 3 个文件被更改,包括 291 次插入94 次删除
  1. 24 12
      driver/platform/waipio/src/msm_vidc_waipio.c
  2. 3 1
      driver/vidc/inc/msm_vidc_control.h
  3. 264 81
      driver/vidc/src/msm_vidc_control.c

+ 24 - 12
driver/platform/waipio/src/msm_vidc_waipio.c

@@ -752,7 +752,8 @@ static struct msm_platform_inst_capability instance_data_waipio[] = {
 		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
 			CAP_FLAG_DYNAMIC_ALLOWED,
 		{0}, {0},
-		msm_vidc_adjust_bitrate, msm_vidc_set_bitrate},
+		msm_vidc_adjust_dynamic_layer_bitrate,
+		msm_vidc_set_dynamic_layer_bitrate},
 
 	{L1_BR, ENC, HEVC,
 		1, MAX_BITRATE, 1, DEFAULT_BITRATE,
@@ -761,7 +762,8 @@ static struct msm_platform_inst_capability instance_data_waipio[] = {
 		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
 			CAP_FLAG_DYNAMIC_ALLOWED,
 		{0}, {0},
-		msm_vidc_adjust_bitrate, msm_vidc_set_bitrate},
+		msm_vidc_adjust_dynamic_layer_bitrate,
+		msm_vidc_set_dynamic_layer_bitrate},
 
 	{L2_BR, ENC, HEVC,
 		1, MAX_BITRATE, 1, DEFAULT_BITRATE,
@@ -770,7 +772,8 @@ static struct msm_platform_inst_capability instance_data_waipio[] = {
 		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
 			CAP_FLAG_DYNAMIC_ALLOWED,
 		{0}, {0},
-		msm_vidc_adjust_bitrate, msm_vidc_set_bitrate},
+		msm_vidc_adjust_dynamic_layer_bitrate,
+		msm_vidc_set_dynamic_layer_bitrate},
 
 	{L3_BR, ENC, HEVC,
 		1, MAX_BITRATE, 1, DEFAULT_BITRATE,
@@ -779,7 +782,8 @@ static struct msm_platform_inst_capability instance_data_waipio[] = {
 		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
 			CAP_FLAG_DYNAMIC_ALLOWED,
 		{0}, {0},
-		msm_vidc_adjust_bitrate, msm_vidc_set_bitrate},
+		msm_vidc_adjust_dynamic_layer_bitrate,
+		msm_vidc_set_dynamic_layer_bitrate},
 
 	{L4_BR, ENC, HEVC,
 		1, MAX_BITRATE, 1, DEFAULT_BITRATE,
@@ -788,7 +792,8 @@ static struct msm_platform_inst_capability instance_data_waipio[] = {
 		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
 			CAP_FLAG_DYNAMIC_ALLOWED,
 		{0}, {0},
-		msm_vidc_adjust_bitrate, msm_vidc_set_bitrate},
+		msm_vidc_adjust_dynamic_layer_bitrate,
+		msm_vidc_set_dynamic_layer_bitrate},
 
 	{L5_BR, ENC, HEVC,
 		1, MAX_BITRATE, 1, DEFAULT_BITRATE,
@@ -797,7 +802,8 @@ static struct msm_platform_inst_capability instance_data_waipio[] = {
 		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
 			CAP_FLAG_DYNAMIC_ALLOWED,
 		{0}, {0},
-		msm_vidc_adjust_bitrate, msm_vidc_set_bitrate},
+		msm_vidc_adjust_dynamic_layer_bitrate,
+		msm_vidc_set_dynamic_layer_bitrate},
 
 	{L0_BR, ENC, H264,
 		1, MAX_BITRATE, 1, DEFAULT_BITRATE,
@@ -806,7 +812,8 @@ static struct msm_platform_inst_capability instance_data_waipio[] = {
 		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
 			CAP_FLAG_DYNAMIC_ALLOWED,
 		{0}, {0},
-		msm_vidc_adjust_bitrate, msm_vidc_set_bitrate},
+		msm_vidc_adjust_dynamic_layer_bitrate,
+		msm_vidc_set_dynamic_layer_bitrate},
 
 	{L1_BR, ENC, H264,
 		1, MAX_BITRATE, 1, DEFAULT_BITRATE,
@@ -815,7 +822,8 @@ static struct msm_platform_inst_capability instance_data_waipio[] = {
 		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
 			CAP_FLAG_DYNAMIC_ALLOWED,
 		{0}, {0},
-		msm_vidc_adjust_bitrate, msm_vidc_set_bitrate},
+		msm_vidc_adjust_dynamic_layer_bitrate,
+		msm_vidc_set_dynamic_layer_bitrate},
 
 	{L2_BR, ENC, H264,
 		1, MAX_BITRATE, 1, DEFAULT_BITRATE,
@@ -824,7 +832,8 @@ static struct msm_platform_inst_capability instance_data_waipio[] = {
 		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
 			CAP_FLAG_DYNAMIC_ALLOWED,
 		{0}, {0},
-		msm_vidc_adjust_bitrate, msm_vidc_set_bitrate},
+		msm_vidc_adjust_dynamic_layer_bitrate,
+		msm_vidc_set_dynamic_layer_bitrate},
 
 	{L3_BR, ENC, H264,
 		1, MAX_BITRATE, 1, DEFAULT_BITRATE,
@@ -833,7 +842,8 @@ static struct msm_platform_inst_capability instance_data_waipio[] = {
 		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
 			CAP_FLAG_DYNAMIC_ALLOWED,
 		{0}, {0},
-		msm_vidc_adjust_bitrate, msm_vidc_set_bitrate},
+		msm_vidc_adjust_dynamic_layer_bitrate,
+		msm_vidc_set_dynamic_layer_bitrate},
 
 	{L4_BR, ENC, H264,
 		1, MAX_BITRATE, 1, DEFAULT_BITRATE,
@@ -842,7 +852,8 @@ static struct msm_platform_inst_capability instance_data_waipio[] = {
 		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
 			CAP_FLAG_DYNAMIC_ALLOWED,
 		{0}, {0},
-		msm_vidc_adjust_bitrate, msm_vidc_set_bitrate},
+		msm_vidc_adjust_dynamic_layer_bitrate,
+		msm_vidc_set_dynamic_layer_bitrate},
 
 	{L5_BR, ENC, H264,
 		1, MAX_BITRATE, 1, DEFAULT_BITRATE,
@@ -851,7 +862,8 @@ static struct msm_platform_inst_capability instance_data_waipio[] = {
 		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
 			CAP_FLAG_DYNAMIC_ALLOWED,
 		{0}, {0},
-		msm_vidc_adjust_bitrate, msm_vidc_set_bitrate},
+		msm_vidc_adjust_dynamic_layer_bitrate,
+		msm_vidc_set_dynamic_layer_bitrate},
 
 	{ENTROPY_MODE, ENC, H264,
 		V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC,

+ 3 - 1
driver/vidc/inc/msm_vidc_control.h

@@ -19,6 +19,7 @@ int msm_vidc_ctrl_init(struct msm_vidc_inst *inst);
 int msm_vidc_ctrl_deinit(struct msm_vidc_inst *inst);
 int msm_v4l2_op_s_ctrl(struct v4l2_ctrl *ctrl);
 int msm_vidc_adjust_bitrate(void *instance, struct v4l2_ctrl *ctrl);
+int msm_vidc_adjust_dynamic_layer_bitrate(void *instance, struct v4l2_ctrl *ctrl);
 int msm_vidc_adjust_bitrate_mode(void *instance, struct v4l2_ctrl *ctrl);
 int msm_vidc_adjust_entropy_mode(void *instance, struct v4l2_ctrl *ctrl);
 int msm_vidc_adjust_profile(void *instance, struct v4l2_ctrl *ctrl);
@@ -32,7 +33,6 @@ int msm_vidc_adjust_slice_count(void *instance, struct v4l2_ctrl *ctrl);
 int msm_vidc_adjust_layer_count(void *instance, struct v4l2_ctrl *ctrl);
 int msm_vidc_adjust_gop_size(void *instance, struct v4l2_ctrl *ctrl);
 int msm_vidc_adjust_b_frame(void *instance, struct v4l2_ctrl *ctrl);
-int msm_vidc_adjust_bitrate(void *instance, struct v4l2_ctrl *ctrl);
 int msm_vidc_adjust_peak_bitrate(void *instance, struct v4l2_ctrl *ctrl);
 int msm_vidc_adjust_hevc_min_qp(void *instance, struct v4l2_ctrl *ctrl);
 int msm_vidc_adjust_hevc_max_qp(void *instance, struct v4l2_ctrl *ctrl);
@@ -65,6 +65,8 @@ int msm_vidc_set_gop_size(void *instance,
 	enum msm_vidc_inst_capability_type cap_id);
 int msm_vidc_set_bitrate(void *instance,
 	enum msm_vidc_inst_capability_type cap_id);
+int msm_vidc_set_dynamic_layer_bitrate(void *instance,
+	enum msm_vidc_inst_capability_type cap_id);
 int msm_vidc_set_u32(void *instance,
 	enum msm_vidc_inst_capability_type cap_id);
 int msm_vidc_set_u32_enum(void *instance,

+ 264 - 81
driver/vidc/src/msm_vidc_control.c

@@ -1413,15 +1413,54 @@ exit:
 	return 0;
 }
 
-int msm_vidc_adjust_bitrate(void *instance, struct v4l2_ctrl *ctrl)
+static bool msm_vidc_check_all_layer_bitrate_set(struct msm_vidc_inst *inst)
+{
+	bool layer_bitrate_set = true;
+	u32 cap_id = 0, i, enh_layer_count;
+	u32 layer_br_caps[6] = {L0_BR, L1_BR, L2_BR, L3_BR, L4_BR, L5_BR};
+
+	enh_layer_count = inst->capabilities->cap[ENH_LAYER_COUNT].value;
+
+	for (i = 0; i <= enh_layer_count; i++) {
+		if (i >= ARRAY_SIZE(layer_br_caps))
+			break;
+		cap_id = layer_br_caps[i];
+		if (!(inst->capabilities->cap[cap_id].flags & CAP_FLAG_CLIENT_SET)) {
+			layer_bitrate_set = false;
+			break;
+		}
+	}
+
+	return layer_bitrate_set;
+}
+
+static u32 msm_vidc_get_cumulative_bitrate(struct msm_vidc_inst *inst)
 {
 	int i;
-	struct msm_vidc_inst_capability *capability;
-	s32 adjusted_value;
+	u32 cap_id = 0;
+	u32 cumulative_br = 0;
+	s32 enh_layer_count;
+	u32 layer_br_caps[6] = {L0_BR, L1_BR, L2_BR, L3_BR, L4_BR, L5_BR};
+
+	enh_layer_count = inst->capabilities->cap[ENH_LAYER_COUNT].value;
+
+	for (i = 0; i <= enh_layer_count; i++) {
+		if (i >= ARRAY_SIZE(layer_br_caps))
+			break;
+		cap_id = layer_br_caps[i];
+		cumulative_br += inst->capabilities->cap[cap_id].value;
+	}
+
+	return cumulative_br;
+}
+
+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;
-	s32 rc_type = -1, enh_layer_count = -1;
-	u32 cap_id = 0, cumulative_bitrate = 0;
-	bool layer_bitrate_set = false;
+	struct msm_vidc_inst_capability *capability;
+	s32 adjusted_value, max_bitrate, 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};
 
 	if (!inst || !inst->capabilities) {
@@ -1430,72 +1469,150 @@ int msm_vidc_adjust_bitrate(void *instance, struct v4l2_ctrl *ctrl)
 	}
 	capability = inst->capabilities;
 
-	adjusted_value = ctrl ? ctrl->val :
-		capability->cap[BIT_RATE].value;
-
 	/* ignore layer bitrate when total bitrate is set */
-	if (capability->cap[BIT_RATE].flags & CAP_FLAG_CLIENT_SET)
-		goto exit;
+	if (capability->cap[BIT_RATE].flags & CAP_FLAG_CLIENT_SET) {
+		/*
+		 * For static case, ctrl is null.
+		 * For dynamic case, only BIT_RATE cap uses this adjust function.
+		 * Hence, no need to check for ctrl id to be BIT_RATE control, and not
+		 * any of layer bitrate controls.
+		 */
+		adjusted_value = ctrl ? ctrl->val : capability->cap[BIT_RATE].value;
+		msm_vidc_update_cap_value(inst, BIT_RATE, adjusted_value, __func__);
+
+		return 0;
+	}
+
+	if (inst->vb2q[OUTPUT_PORT].streaming)
+		return 0;
 
 	if (msm_vidc_get_parent_value(inst, BIT_RATE,
 		ENH_LAYER_COUNT, &enh_layer_count, __func__))
 		return -EINVAL;
 
-	if (msm_vidc_get_parent_value(inst, BIT_RATE,
-		BITRATE_MODE, &rc_type, __func__))
-		return -EINVAL;
+	max_bitrate = inst->capabilities->cap[BIT_RATE].max;
 
 	/*
 	 * ENH_LAYER_COUNT cap max is positive only if
-	 * layer encoding is enabled for static setting
+	 * layer encoding is enabled during streamon.
 	 */
 	if (capability->cap[ENH_LAYER_COUNT].max) {
-		layer_bitrate_set = true;
-		for (i = 0; i <= enh_layer_count; i++) {
-			if (i >= ARRAY_SIZE(layer_br_caps))
-				break;
-			cap_id = layer_br_caps[i];
-			if (!(capability->cap[cap_id].flags & CAP_FLAG_CLIENT_SET)) {
-				layer_bitrate_set = false;
-				break;
-			}
-			cumulative_bitrate += capability->cap[cap_id].value;
-		}
-
-		/* layer bitrate supported only for CBR rc */
-		if (layer_bitrate_set &&
-			(rc_type == HFI_RC_CBR_CFR || rc_type == HFI_RC_CBR_VFR)) {
-			if (cumulative_bitrate > capability->cap[BIT_RATE].max)
-				cumulative_bitrate =
-					capability->cap[BIT_RATE].max;
-			adjusted_value = cumulative_bitrate;
+		if (!msm_vidc_check_all_layer_bitrate_set(inst)) {
 			i_vpr_h(inst,
-				"%s: update BIT_RATE with cumulative bitrate\n",
+				"%s: client did not set all layer bitrates\n",
 				__func__);
+			return 0;
 		}
-	} else {
-		for (i = 0; i < sizeof(layer_br_caps) / sizeof(u32); i++) {
-			if (i >= ARRAY_SIZE(layer_br_caps))
-				break;
-			cap_id = layer_br_caps[i];
-			/*
-			 * layer bitrate cannot be set
-			 * when layer encoding is disabled
-			 */
-			if (capability->cap[cap_id].flags &
-					CAP_FLAG_CLIENT_SET) {
-				i_vpr_e(inst,
-					"%s: invalid layer bitrate set\n",
-					__func__);
-				return -EINVAL;
+
+		cumulative_bitrate = msm_vidc_get_cumulative_bitrate(inst);
+
+		/* cap layer bitrates to max supported bitrate */
+		if (cumulative_bitrate > max_bitrate) {
+			u32 decrement_in_value = 0;
+			u32 decrement_in_percent = ((cumulative_bitrate - max_bitrate) * 100) /
+				max_bitrate;
+
+			cumulative_bitrate = 0;
+			for (i = 0; i <= enh_layer_count; i++) {
+				if (i >= ARRAY_SIZE(layer_br_caps))
+					break;
+				cap_id = layer_br_caps[i];
+				cap_value = inst->capabilities->cap[cap_id].value;
+
+				decrement_in_value = (cap_value *
+					decrement_in_percent) / 100;
+				cumulative_bitrate += (cap_value - decrement_in_value);
+
+				/*
+				 * cap value for the L*_BR is changed. Hence, update cap,
+				 * and add to FW_LIST to set new values to firmware.
+				 */
+				msm_vidc_update_cap_value(inst, cap_id,
+					(cap_value - decrement_in_value), __func__);
 			}
 		}
+
+		i_vpr_h(inst,
+			"%s: update BIT_RATE with cumulative bitrate\n",
+			__func__);
+		msm_vidc_update_cap_value(inst, BIT_RATE,
+			cumulative_bitrate, __func__);
 	}
 
-exit:
+	return rc;
+}
+
+int msm_vidc_adjust_dynamic_layer_bitrate(void *instance, struct v4l2_ctrl *ctrl)
+{
+	int rc = 0;
+	struct msm_vidc_inst *inst = (struct msm_vidc_inst *) instance;
+	struct msm_vidc_inst_capability *capability;
+	u32 cumulative_bitrate = 0;
+	u32 client_set_cap_id = INST_CAP_NONE;
+	u32 old_br = 0, new_br = 0, exceeded_br = 0;
+	s32 max_bitrate;
+
+	if (!inst || !inst->capabilities || !ctrl) {
+		d_vpr_e("%s: invalid params\n", __func__);
+		return -EINVAL;
+	}
+	capability = inst->capabilities;
+
+	/* ignore layer bitrate when total bitrate is set */
+	if (capability->cap[BIT_RATE].flags & CAP_FLAG_CLIENT_SET)
+		return 0;
+
+	if (!inst->vb2q[OUTPUT_PORT].streaming)
+		return 0;
+
+	/*
+	 * ENH_LAYER_COUNT cap max is positive only if
+	 * layer encoding is enabled during streamon.
+	 */
+	if (!capability->cap[ENH_LAYER_COUNT].max) {
+		i_vpr_e(inst, "%s: layers not enabled\n", __func__);
+		return -EINVAL;
+	}
+
+	if (!msm_vidc_check_all_layer_bitrate_set(inst)) {
+		i_vpr_h(inst,
+			"%s: client did not set all layer bitrates\n",
+			__func__);
+		return 0;
+	}
+
+	client_set_cap_id = msm_vidc_get_cap_id(inst, ctrl->id);
+	if (client_set_cap_id == INST_CAP_NONE) {
+		i_vpr_e(inst, "%s: could not find cap_id for ctrl %s\n",
+			__func__, ctrl->name);
+		return -EINVAL;
+	}
+
+	cumulative_bitrate = msm_vidc_get_cumulative_bitrate(inst);
+	max_bitrate = inst->capabilities->cap[BIT_RATE].max;
+	old_br = capability->cap[client_set_cap_id].value;
+	new_br = ctrl->val;
+
+	/*
+	 * new bitrate is not supposed to cause cumulative bitrate to
+	 * exceed max supported bitrate
+	 */
+
+	if ((cumulative_bitrate - old_br + new_br) > max_bitrate) {
+		/* adjust new bitrate */
+		exceeded_br = (cumulative_bitrate - old_br + new_br) - max_bitrate;
+		new_br = ctrl->val - exceeded_br;
+	}
+	msm_vidc_update_cap_value(inst, client_set_cap_id, new_br, __func__);
+
+	/* adjust totol bitrate cap */
+	i_vpr_h(inst,
+		"%s: update BIT_RATE with cumulative bitrate\n",
+		__func__);
 	msm_vidc_update_cap_value(inst, BIT_RATE,
-		adjusted_value, __func__);
-	return 0;
+		msm_vidc_get_cumulative_bitrate(inst), __func__);
+
+	return rc;
 }
 
 int msm_vidc_adjust_peak_bitrate(void *instance, struct v4l2_ctrl *ctrl)
@@ -2403,7 +2520,6 @@ int msm_vidc_set_bitrate(void *instance,
 	u32 hfi_value = 0;
 	s32 rc_type = -1, enh_layer_count = -1;
 	u32 layer_br_caps[6] = {L0_BR, L1_BR, L2_BR, L3_BR, L4_BR, L5_BR};
-	bool layer_bitrate_set = false;
 
 	if (!inst || !inst->capabilities) {
 		d_vpr_e("%s: invalid params\n", __func__);
@@ -2414,44 +2530,50 @@ int msm_vidc_set_bitrate(void *instance,
 	if (inst->capabilities->cap[BIT_RATE].flags & CAP_FLAG_CLIENT_SET)
 		goto set_total_bitrate;
 
+	/*
+	 * During runtime, if BIT_RATE cap CLIENT_SET flag is not set,
+	 * then this function will be called due to change in ENH_LAYER_COUNT.
+	 * In this case, client did not change bitrate, hence, no need to set
+	 * to fw.
+	 */
+	if (inst->vb2q[OUTPUT_PORT].streaming)
+		return 0;
+
 	if (msm_vidc_get_parent_value(inst, BIT_RATE,
-		ENH_LAYER_COUNT, &enh_layer_count, __func__))
+		BITRATE_MODE, &rc_type, __func__))
 		return -EINVAL;
 
+	if (rc_type != HFI_RC_CBR_CFR && rc_type != HFI_RC_CBR_VFR) {
+		i_vpr_h(inst, "%s: set total bitrate for non CBR rc type\n",
+			__func__);
+		goto set_total_bitrate;
+	}
+
 	if (msm_vidc_get_parent_value(inst, BIT_RATE,
-		BITRATE_MODE, &rc_type, __func__))
+		ENH_LAYER_COUNT, &enh_layer_count, __func__))
 		return -EINVAL;
 
-	if (inst->capabilities->cap[ENH_LAYER_COUNT].max &&
-		(rc_type == HFI_RC_CBR_CFR ||
-		rc_type == HFI_RC_CBR_VFR)) {
-		layer_bitrate_set = true;
+	/*
+	 * ENH_LAYER_COUNT cap max is positive only if
+	 *    layer encoding is enabled during streamon.
+	 */
+	if (inst->capabilities->cap[ENH_LAYER_COUNT].max) {
+		if (!msm_vidc_check_all_layer_bitrate_set(inst))
+			goto set_total_bitrate;
+
+		/* set Layer Bitrate */
 		for (i = 0; i <= enh_layer_count; i++) {
 			if (i >= ARRAY_SIZE(layer_br_caps))
 				break;
 			cap_id = layer_br_caps[i];
-			if (!(inst->capabilities->cap[cap_id].flags &
-					CAP_FLAG_CLIENT_SET)) {
-				layer_bitrate_set = false;
-				break;
-			}
-		}
-
-		if (layer_bitrate_set) {
-			/* set Layer Bitrate */
-			for (i = 0; i <= enh_layer_count; i++) {
-				if (i >= ARRAY_SIZE(layer_br_caps))
-					break;
-				cap_id = layer_br_caps[i];
-				hfi_value = inst->capabilities->cap[cap_id].value;
-				rc = msm_vidc_packetize_control(inst, cap_id,
-					HFI_PAYLOAD_U32, &hfi_value,
-					sizeof(u32), __func__);
-				if (rc)
-					return rc;
-			}
-			goto exit;
+			hfi_value = inst->capabilities->cap[cap_id].value;
+			rc = msm_vidc_packetize_control(inst, cap_id,
+				HFI_PAYLOAD_U32, &hfi_value,
+				sizeof(u32), __func__);
+			if (rc)
+				return rc;
 		}
+		goto exit;
 	}
 
 set_total_bitrate:
@@ -2464,6 +2586,67 @@ exit:
 	return rc;
 }
 
+int msm_vidc_set_dynamic_layer_bitrate(void *instance,
+	enum msm_vidc_inst_capability_type cap_id)
+{
+	int rc = 0;
+	struct msm_vidc_inst *inst = (struct msm_vidc_inst *)instance;
+	u32 hfi_value = 0;
+	s32 rc_type = -1;
+
+	if (!inst || !inst->capabilities) {
+		d_vpr_e("%s: invalid params\n", __func__);
+		return -EINVAL;
+	}
+
+	if (!inst->vb2q[OUTPUT_PORT].streaming)
+		return 0;
+
+	/* set Total Bitrate */
+	if (inst->capabilities->cap[BIT_RATE].flags & CAP_FLAG_CLIENT_SET) {
+		i_vpr_h(inst,
+			"%s: Total bitrate is set, ignore layer bitrate\n",
+			__func__);
+		return 0;
+	}
+
+	/*
+	 * ENH_LAYER_COUNT cap max is positive only if
+	 *    layer encoding is enabled during streamon.
+	 */
+	if (!inst->capabilities->cap[ENH_LAYER_COUNT].max ||
+		!msm_vidc_check_all_layer_bitrate_set(inst)) {
+		i_vpr_h(inst,
+			"%s: invalid layer bitrate, ignore setting to fw\n",
+			__func__);
+		return 0;
+	}
+
+	if (inst->hfi_rc_type == HFI_RC_CBR_CFR ||
+		rc_type == HFI_RC_CBR_VFR) {
+		/* set layer bitrate for the client set layer */
+		hfi_value = inst->capabilities->cap[cap_id].value;
+		rc = msm_vidc_packetize_control(inst, cap_id,
+			HFI_PAYLOAD_U32, &hfi_value,
+			sizeof(u32), __func__);
+		if (rc)
+			return rc;
+	} else {
+		/*
+		 * All layer bitartes set for unsupported rc type.
+		 * Hence accept layer bitrates, but set total bitrate prop
+		 * with cumulative bitrate.
+		 */
+		hfi_value = inst->capabilities->cap[BIT_RATE].value;
+		rc = msm_vidc_packetize_control(inst, BIT_RATE, HFI_PAYLOAD_U32,
+				&hfi_value, sizeof(u32), __func__);
+		if (rc)
+			return rc;
+	}
+
+	return rc;
+}
+
 int msm_vidc_set_session_priority(void *instance,
 		enum msm_vidc_inst_capability_type cap_id)
 {