Merge "video: driver: Add support for enc auto framerate"

This commit is contained in:
qctecmdr
2021-06-18 10:32:00 -07:00
committed by Gerrit - the friendly Code Review server
10 changed files with 87 additions and 12 deletions

View File

@@ -93,6 +93,7 @@ static struct msm_platform_core_capability core_data_waipio[] = {
{DECODE_BATCH_TIMEOUT, 200}, {DECODE_BATCH_TIMEOUT, 200},
{AV_SYNC_WINDOW_SIZE, 40}, {AV_SYNC_WINDOW_SIZE, 40},
{NON_FATAL_FAULTS, 1}, {NON_FATAL_FAULTS, 1},
{ENC_AUTO_FRAMERATE, 1},
}; };
static struct msm_platform_inst_capability instance_data_waipio[] = { static struct msm_platform_inst_capability instance_data_waipio[] = {

View File

@@ -48,7 +48,7 @@ u64 msm_vidc_calc_freq_iris2(struct msm_vidc_inst *inst, u32 data_size)
mbpf = msm_vidc_get_mbs_per_frame(inst); mbpf = msm_vidc_get_mbs_per_frame(inst);
fps = msm_vidc_get_fps(inst); fps = msm_vidc_get_fps(inst);
buf_timetamps_fps = msm_vidc_calc_framerate(inst); buf_timetamps_fps = msm_vidc_calc_window_avg_framerate(inst);
/* /*
* when buffer detected fps is more than client set value by 10%, * when buffer detected fps is more than client set value by 10%,

View File

@@ -411,7 +411,8 @@ int msm_vidc_check_session_supported(struct msm_vidc_inst *inst);
int msm_vidc_check_core_mbps(struct msm_vidc_inst *inst); int msm_vidc_check_core_mbps(struct msm_vidc_inst *inst);
int msm_vidc_check_scaling_supported(struct msm_vidc_inst *inst); int msm_vidc_check_scaling_supported(struct msm_vidc_inst *inst);
int msm_vidc_update_timestamp(struct msm_vidc_inst *inst, u64 timestamp); int msm_vidc_update_timestamp(struct msm_vidc_inst *inst, u64 timestamp);
int msm_vidc_calc_framerate(struct msm_vidc_inst *inst); int msm_vidc_set_auto_framerate(struct msm_vidc_inst *inst, u64 timestamp);
int msm_vidc_calc_window_avg_framerate(struct msm_vidc_inst *inst);
int msm_vidc_flush_ts(struct msm_vidc_inst *inst); int msm_vidc_flush_ts(struct msm_vidc_inst *inst);
const char *buf_name(enum msm_vidc_buffer_type type); const char *buf_name(enum msm_vidc_buffer_type type);
void msm_vidc_free_capabililty_list(struct msm_vidc_inst *inst, void msm_vidc_free_capabililty_list(struct msm_vidc_inst *inst,

View File

@@ -147,5 +147,6 @@ struct msm_vidc_inst {
u32 max_input_data_size; u32 max_input_data_size;
u32 dpb_list_payload[MAX_DPB_LIST_ARRAY_SIZE]; u32 dpb_list_payload[MAX_DPB_LIST_ARRAY_SIZE];
u32 max_map_output_count; u32 max_map_output_count;
u32 auto_framerate;
}; };
#endif // _MSM_VIDC_INST_H_ #endif // _MSM_VIDC_INST_H_

View File

@@ -69,6 +69,8 @@
#define MAX_SUPPORTED_MIN_QUALITY 70 #define MAX_SUPPORTED_MIN_QUALITY 70
#define DCVS_WINDOW 16 #define DCVS_WINDOW 16
#define ENC_FPS_WINDOW 3
#define DEC_FPS_WINDOW 10
/* Superframe can have maximum of 32 frames */ /* Superframe can have maximum of 32 frames */
#define VIDC_SUPERFRAME_MAX 32 #define VIDC_SUPERFRAME_MAX 32
#define COLOR_RANGE_UNSPECIFIED (-1) #define COLOR_RANGE_UNSPECIFIED (-1)
@@ -327,6 +329,7 @@ enum msm_vidc_core_capability_type {
AV_SYNC_WINDOW_SIZE, AV_SYNC_WINDOW_SIZE,
CLK_FREQ_THRESHOLD, CLK_FREQ_THRESHOLD,
NON_FATAL_FAULTS, NON_FATAL_FAULTS,
ENC_AUTO_FRAMERATE,
CORE_CAP_MAX, CORE_CAP_MAX,
}; };

View File

@@ -1604,6 +1604,7 @@ set_default:
"%s: failed to set frame rate to fw\n", __func__); "%s: failed to set frame rate to fw\n", __func__);
goto exit; goto exit;
} }
inst->auto_framerate = q16_rate;
} }
return 0; return 0;

View File

@@ -434,6 +434,7 @@ int msm_vidc_qbuf(void *instance, struct media_device *mdev,
int rc = 0; int rc = 0;
struct msm_vidc_inst *inst = instance; struct msm_vidc_inst *inst = instance;
struct vb2_queue *q; struct vb2_queue *q;
u64 timestamp_us = 0;
if (!inst || !inst->core || !b || !valid_v4l2_buffer(b, inst)) { if (!inst || !inst->core || !b || !valid_v4l2_buffer(b, inst)) {
d_vpr_e("%s: invalid params %pK %pK\n", __func__, inst, b); d_vpr_e("%s: invalid params %pK %pK\n", __func__, inst, b);
@@ -445,6 +446,12 @@ int msm_vidc_qbuf(void *instance, struct media_device *mdev,
rc = -EINVAL; rc = -EINVAL;
goto exit; goto exit;
} }
if (is_encode_session(inst) && b->type == INPUT_MPLANE) {
timestamp_us = (u64)((b->timestamp.tv_sec * USEC_PER_SEC) +
b->timestamp.tv_usec);
msm_vidc_set_auto_framerate(inst, timestamp_us);
}
inst->last_qbuf_time_ns = ktime_get_ns(); inst->last_qbuf_time_ns = ktime_get_ns();
rc = vb2_qbuf(q, mdev, b); rc = vb2_qbuf(q, mdev, b);
@@ -776,6 +783,7 @@ void *msm_vidc_open(void *vidc_core, u32 session_type)
inst->request = false; inst->request = false;
inst->ipsc_properties_set = false; inst->ipsc_properties_set = false;
inst->opsc_properties_set = false; inst->opsc_properties_set = false;
inst->auto_framerate = DEFAULT_FPS << 16;
kref_init(&inst->kref); kref_init(&inst->kref);
mutex_init(&inst->lock); mutex_init(&inst->lock);
msm_vidc_update_debug_str(inst); msm_vidc_update_debug_str(inst);

View File

@@ -40,8 +40,6 @@ extern struct msm_vidc_core *g_core;
#define SSR_ADDR_ID 0xFFFFFFFF00000000 #define SSR_ADDR_ID 0xFFFFFFFF00000000
#define SSR_ADDR_SHIFT 32 #define SSR_ADDR_SHIFT 32
#define FPS_WINDOW 10
struct msm_vidc_cap_name { struct msm_vidc_cap_name {
enum msm_vidc_inst_capability_type cap; enum msm_vidc_inst_capability_type cap;
char *name; char *name;
@@ -2019,7 +2017,67 @@ int msm_vidc_memory_unmap_completely(struct msm_vidc_inst *inst,
return rc; return rc;
} }
int msm_vidc_calc_framerate(struct msm_vidc_inst *inst) int msm_vidc_set_auto_framerate(struct msm_vidc_inst *inst, u64 timestamp)
{
struct msm_vidc_core *core;
struct msm_vidc_timestamp *ts;
struct msm_vidc_timestamp *prev = NULL;
u32 counter = 0, prev_fr = 0, curr_fr = 0;
u64 ts_ms = 0;
int rc = 0;
if (!inst || !inst->core || !inst->capabilities) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
core = inst->core;
if (!core->capabilities[ENC_AUTO_FRAMERATE].value ||
is_image_session(inst) || msm_vidc_is_super_buffer(inst))
goto exit;
rc = msm_vidc_update_timestamp(inst, timestamp);
if (rc)
goto exit;
list_for_each_entry(ts, &inst->timestamps.list, sort.list) {
if (prev) {
ts_ms = div_u64(ts->sort.val - prev->sort.val, 1000);
prev_fr = curr_fr;
curr_fr = ts_ms ? div_u64(MSEC_PER_SEC, ts_ms) << 16 :
inst->auto_framerate;
if (curr_fr > inst->capabilities->cap[FRAME_RATE].max)
curr_fr = inst->capabilities->cap[FRAME_RATE].max;
}
prev = ts;
counter++;
}
if (counter < ENC_FPS_WINDOW)
goto exit;
/* if framerate changed and stable for 2 frames, set to firmware */
if (curr_fr == prev_fr && curr_fr != inst->auto_framerate) {
i_vpr_l(inst, "%s: updated fps to %u\n", __func__, curr_fr >> 16);
rc = venus_hfi_session_property(inst,
HFI_PROP_FRAME_RATE,
HFI_HOST_FLAGS_NONE,
HFI_PORT_BITSTREAM,
HFI_PAYLOAD_Q16,
&curr_fr,
sizeof(u32));
if (rc) {
i_vpr_e(inst, "%s: set auto frame rate failed\n",
__func__);
goto exit;
}
inst->auto_framerate = curr_fr;
}
exit:
return rc;
}
int msm_vidc_calc_window_avg_framerate(struct msm_vidc_inst *inst)
{ {
struct msm_vidc_timestamp *ts; struct msm_vidc_timestamp *ts;
struct msm_vidc_timestamp *prev = NULL; struct msm_vidc_timestamp *prev = NULL;
@@ -2129,6 +2187,7 @@ int msm_vidc_update_timestamp(struct msm_vidc_inst *inst, u64 timestamp)
{ {
struct msm_vidc_timestamp *ts; struct msm_vidc_timestamp *ts;
int rc = 0; int rc = 0;
u32 window_size = 0;
if (!inst) { if (!inst) {
d_vpr_e("%s: Invalid params\n", __func__); d_vpr_e("%s: Invalid params\n", __func__);
@@ -2149,8 +2208,13 @@ int msm_vidc_update_timestamp(struct msm_vidc_inst *inst, u64 timestamp)
return rc; return rc;
inst->timestamps.count++; inst->timestamps.count++;
/* keep sliding window of 10 ts nodes */ if (is_encode_session(inst))
if (inst->timestamps.count > FPS_WINDOW) { window_size = ENC_FPS_WINDOW;
else
window_size = DEC_FPS_WINDOW;
/* keep sliding window */
if (inst->timestamps.count > window_size) {
ts = msm_vidc_get_least_rank_ts(inst); ts = msm_vidc_get_least_rank_ts(inst);
if (!ts) { if (!ts) {
i_vpr_e(inst, "%s: least rank ts is NULL\n", __func__); i_vpr_e(inst, "%s: least rank ts is NULL\n", __func__);

View File

@@ -223,7 +223,7 @@ int msm_vidc_scale_buses(struct msm_vidc_inst *inst)
vote_data->lcu_size = (codec == V4L2_PIX_FMT_HEVC || vote_data->lcu_size = (codec == V4L2_PIX_FMT_HEVC ||
codec == V4L2_PIX_FMT_VP9) ? 32 : 16; codec == V4L2_PIX_FMT_VP9) ? 32 : 16;
vote_data->fps = msm_vidc_get_fps(inst); vote_data->fps = msm_vidc_get_fps(inst);
buf_ts_fps = msm_vidc_calc_framerate(inst); buf_ts_fps = msm_vidc_calc_window_avg_framerate(inst);
if (buf_ts_fps > vote_data->fps) { if (buf_ts_fps > vote_data->fps) {
i_vpr_l(inst, "%s: bitstream: fps %d, client rate %u\n", __func__, i_vpr_l(inst, "%s: bitstream: fps %d, client rate %u\n", __func__,
buf_ts_fps, vote_data->fps); buf_ts_fps, vote_data->fps);

View File

@@ -3399,7 +3399,6 @@ int venus_hfi_queue_super_buffer(struct msm_vidc_inst *inst,
/* Create yuv packet */ /* Create yuv packet */
update_offset(hfi_buffer.addr_offset, (cnt ? frame_size : 0u)); update_offset(hfi_buffer.addr_offset, (cnt ? frame_size : 0u));
update_timestamp(hfi_buffer.timestamp, (cnt ? ts_delta_us : 0u)); update_timestamp(hfi_buffer.timestamp, (cnt ? ts_delta_us : 0u));
msm_vidc_update_timestamp(inst, hfi_buffer.timestamp);
rc = hfi_create_packet(inst->packet, rc = hfi_create_packet(inst->packet,
inst->packet_size, inst->packet_size,
HFI_CMD_BUFFER, HFI_CMD_BUFFER,
@@ -3467,9 +3466,6 @@ int venus_hfi_queue_buffer(struct msm_vidc_inst *inst,
if (rc) if (rc)
goto unlock; goto unlock;
if (is_encode_session(inst) && is_input_buffer(buffer->type))
msm_vidc_update_timestamp(inst, hfi_buffer.timestamp);
rc = hfi_create_header(inst->packet, inst->packet_size, rc = hfi_create_header(inst->packet, inst->packet_size,
inst->session_id, core->header_id++); inst->session_id, core->header_id++);
if (rc) if (rc)