Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a6db282c authored by Arun Menon's avatar Arun Menon Committed by Gerrit - the friendly Code Review server
Browse files

msm: vidc: Use bitrate to scale clocks for decoder



The Venus core's ability to handle bitrate depends on
the clock frequency it operates at. If we get spikes in
bitrate, we should scale the core clock to a higher frequency,
at which the Venus core can decode the frame within the
required time. This change calculates the instantaneous
bitrate for each input frame and scales the clock accordingly.
Without this change we will see frame drops whenever there are
spikes in bitrate.

Bitrate can be switched on and off using the following
debugfs handle - /d/msm_vidc/bitrate_clock_scaling

Change-Id: I772b132c6b8b39ae186c69b8caec1b95d108c23b
Signed-off-by: default avatarArun Menon <avmenon@codeaurora.org>
parent dec3acb0
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1172,6 +1172,7 @@ void *msm_vidc_open(int core_id, int session_type)
	inst->state = MSM_VIDC_CORE_UNINIT_DONE;
	inst->core = core;
	inst->bit_depth = MSM_VIDC_BIT_DEPTH_8;
	inst->instant_bitrate = 0;

	for (i = SESSION_MSG_INDEX(SESSION_MSG_START);
		i <= SESSION_MSG_INDEX(SESSION_MSG_END); i++) {
+18 −1
Original line number Diff line number Diff line
@@ -1871,6 +1871,7 @@ int msm_comm_scale_clocks_load(struct msm_vidc_core *core, int num_mbs_per_sec)
	int rc = 0;
	struct hfi_device *hdev;
	struct msm_vidc_inst *inst = NULL;
	unsigned long instant_bitrate = 0;

	if (!core) {
		dprintk(VIDC_ERR, "%s Invalid args: %p\n", __func__, core);
@@ -1896,13 +1897,17 @@ int msm_comm_scale_clocks_load(struct msm_vidc_core *core, int num_mbs_per_sec)
				get_hal_codec(codec),
				get_hal_domain(inst->session_type));

		if (inst->instant_bitrate > instant_bitrate)
			instant_bitrate = inst->instant_bitrate;

	}
	mutex_unlock(&core->lock);

	dprintk(VIDC_INFO, "num_mbs_per_sec = %d codecs_enabled %#x\n",
			num_mbs_per_sec, codecs_enabled);
	rc = call_hfi_op(hdev, scale_clocks,
		hdev->hfi_device_data, num_mbs_per_sec, codecs_enabled);
		hdev->hfi_device_data, num_mbs_per_sec,
		codecs_enabled, instant_bitrate);
	if (rc)
		dprintk(VIDC_ERR, "Failed to set clock rate: %d\n", rc);
	return rc;
@@ -3271,6 +3276,11 @@ static void log_frame(struct msm_vidc_inst *inst, struct vidc_frame_data *data,
				&data->device_addr, data->filled_len,
				data->timestamp, data->flags);
		msm_vidc_debugfs_update(inst, MSM_VIDC_DEBUGFS_EVENT_ETB);

		if (msm_vidc_bitrate_clock_scaling &&
			inst->session_type == MSM_VIDC_DECODER)
				inst->instant_bitrate =
					data->filled_len * 8 * inst->prop.fps;
	} else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
		dprintk(VIDC_DBG,
				"Sending ftb (%pa) to hal: size: %d, ts: %lld, flags = %#x\n",
@@ -3281,6 +3291,13 @@ static void log_frame(struct msm_vidc_inst *inst, struct vidc_frame_data *data,

	msm_dcvs_check_and_scale_clocks(inst,
			type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);

	if (msm_vidc_bitrate_clock_scaling && !inst->dcvs_mode &&
		type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
		inst->session_type == MSM_VIDC_DECODER)
		if (msm_comm_scale_clocks(inst->core))
			dprintk(VIDC_WARN,
				"Failed to scale clocks. Performance might be impacted\n");
}

static int request_seq_header(struct msm_vidc_inst *inst,
+4 −1
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ int msm_vidc_enc_dcvs_mode = 1;
int msm_vidc_sys_idle_indicator = 0;
int msm_vidc_firmware_unload_delay = 15000;
int msm_vidc_thermal_mitigation_disabled = 0;
int msm_vidc_bitrate_clock_scaling = 1;

#define MAX_DBG_BUF_SIZE 4096

@@ -173,7 +174,9 @@ struct dentry *msm_vidc_debugfs_init_drv(void)
	__debugfs_create(u32, "firmware_unload_delay",
			&msm_vidc_firmware_unload_delay) &&
	__debugfs_create(bool, "disable_thermal_mitigation",
			&msm_vidc_thermal_mitigation_disabled);
			&msm_vidc_thermal_mitigation_disabled) &&
	__debugfs_create(bool, "bitrate_clock_scaling",
			&msm_vidc_bitrate_clock_scaling);

#undef __debugfs_create

+2 −1
Original line number Diff line number Diff line
/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -65,6 +65,7 @@ extern int msm_vidc_enc_dcvs_mode;
extern int msm_vidc_sys_idle_indicator;
extern int msm_vidc_firmware_unload_delay;
extern int msm_vidc_thermal_mitigation_disabled;
extern int msm_vidc_bitrate_clock_scaling;

#define VIDC_MSG_PRIO2STRING(__level) ({ \
	char *__str; \
+1 −0
Original line number Diff line number Diff line
@@ -299,6 +299,7 @@ struct msm_vidc_inst {
	bool dcvs_mode;
	enum msm_vidc_pixel_depth bit_depth;
	struct kref kref;
	unsigned long instant_bitrate;
};

extern struct msm_vidc_drv *vidc_driver;
Loading