video: driver: Modify buffer_stats logic
For super buffer usecase, All the ETB's gets queued with updated timestamp in hfi_buffer, therefore all the fbd's being recieved are of different timestamp. And only the last EBD is considered for dequeued flag and hence for remove_buffer_stat. Therefore when first FBD arrives which has the matched TS to the stat's TS will get skipped since last EBD in the batch has not arrived yet and rest all FBDs are with updated TS, hence the buffer stat doesn't get's removed from the list. Modified the logic to add stats during hfi_buffer queue and add stats for all sub-frames in super buffer usecase. Modified the logic for Multi-In single-Out usecase as well. Change-Id: I0643e6f64bdfc3cbfa67baeb1cf9157de92ce569 Signed-off-by: Vedang Nagar <quic_vnagar@quicinc.com>
This commit is contained in:
@@ -599,9 +599,9 @@ int signal_session_msg_receipt(struct msm_vidc_inst *inst,
|
|||||||
int msm_vidc_get_properties(struct msm_vidc_inst *inst);
|
int msm_vidc_get_properties(struct msm_vidc_inst *inst);
|
||||||
int msm_vidc_update_input_rate(struct msm_vidc_inst *inst, u64 time_us);
|
int msm_vidc_update_input_rate(struct msm_vidc_inst *inst, u64 time_us);
|
||||||
int msm_vidc_add_buffer_stats(struct msm_vidc_inst *inst,
|
int msm_vidc_add_buffer_stats(struct msm_vidc_inst *inst,
|
||||||
struct msm_vidc_buffer *buf);
|
struct msm_vidc_buffer *buf, u64 timestamp);
|
||||||
int msm_vidc_remove_buffer_stats(struct msm_vidc_inst *inst,
|
int msm_vidc_remove_buffer_stats(struct msm_vidc_inst *inst,
|
||||||
struct msm_vidc_buffer *buf);
|
struct msm_vidc_buffer *buf, u64 timestamp);
|
||||||
int msm_vidc_flush_buffer_stats(struct msm_vidc_inst *inst);
|
int msm_vidc_flush_buffer_stats(struct msm_vidc_inst *inst);
|
||||||
int msm_vidc_get_input_rate(struct msm_vidc_inst *inst);
|
int msm_vidc_get_input_rate(struct msm_vidc_inst *inst);
|
||||||
int msm_vidc_get_frame_rate(struct msm_vidc_inst *inst);
|
int msm_vidc_get_frame_rate(struct msm_vidc_inst *inst);
|
||||||
|
@@ -917,12 +917,14 @@ struct msm_vidc_buffer_stats {
|
|||||||
u32 fbd_time_ms;
|
u32 fbd_time_ms;
|
||||||
u32 data_size;
|
u32 data_size;
|
||||||
u32 flags;
|
u32 flags;
|
||||||
|
u32 ts_offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum msm_vidc_buffer_stats_flag {
|
enum msm_vidc_buffer_stats_flag {
|
||||||
MSM_VIDC_STATS_FLAG_CORRUPT = BIT(0),
|
MSM_VIDC_STATS_FLAG_CORRUPT = BIT(0),
|
||||||
MSM_VIDC_STATS_FLAG_OVERFLOW = BIT(1),
|
MSM_VIDC_STATS_FLAG_OVERFLOW = BIT(1),
|
||||||
MSM_VIDC_STATS_FLAG_NO_OUTPUT = BIT(2),
|
MSM_VIDC_STATS_FLAG_NO_OUTPUT = BIT(2),
|
||||||
|
MSM_VIDC_STATS_FLAG_SUBFRAME_INPUT = BIT(3),
|
||||||
};
|
};
|
||||||
|
|
||||||
struct msm_vidc_sort {
|
struct msm_vidc_sort {
|
||||||
|
@@ -318,6 +318,9 @@ static u32 msm_vidc_get_buffer_stats_flag(struct msm_vidc_inst *inst)
|
|||||||
if (inst->hfi_frame_info.no_output)
|
if (inst->hfi_frame_info.no_output)
|
||||||
flags |= MSM_VIDC_STATS_FLAG_NO_OUTPUT;
|
flags |= MSM_VIDC_STATS_FLAG_NO_OUTPUT;
|
||||||
|
|
||||||
|
if (inst->hfi_frame_info.subframe_input)
|
||||||
|
flags |= MSM_VIDC_STATS_FLAG_SUBFRAME_INPUT;
|
||||||
|
|
||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -359,7 +362,7 @@ static int msm_vidc_try_suspend(struct msm_vidc_inst *inst)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int msm_vidc_add_buffer_stats(struct msm_vidc_inst *inst,
|
int msm_vidc_add_buffer_stats(struct msm_vidc_inst *inst,
|
||||||
struct msm_vidc_buffer *buf)
|
struct msm_vidc_buffer *buf, u64 timestamp)
|
||||||
{
|
{
|
||||||
struct msm_vidc_buffer_stats *stats = NULL;
|
struct msm_vidc_buffer_stats *stats = NULL;
|
||||||
struct msm_vidc_core *core;
|
struct msm_vidc_core *core;
|
||||||
@@ -370,6 +373,9 @@ int msm_vidc_add_buffer_stats(struct msm_vidc_inst *inst,
|
|||||||
}
|
}
|
||||||
core = inst->core;
|
core = inst->core;
|
||||||
|
|
||||||
|
if (!(msm_vidc_debug & VIDC_STAT))
|
||||||
|
return 0;
|
||||||
|
|
||||||
/* stats applicable only to input & output buffers */
|
/* stats applicable only to input & output buffers */
|
||||||
if (buf->type != MSM_VIDC_BUF_INPUT && buf->type != MSM_VIDC_BUF_OUTPUT)
|
if (buf->type != MSM_VIDC_BUF_INPUT && buf->type != MSM_VIDC_BUF_OUTPUT)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@@ -388,7 +394,8 @@ int msm_vidc_add_buffer_stats(struct msm_vidc_inst *inst,
|
|||||||
list_add_tail(&stats->list, &inst->buffer_stats_list);
|
list_add_tail(&stats->list, &inst->buffer_stats_list);
|
||||||
|
|
||||||
stats->frame_num = inst->debug_count.etb;
|
stats->frame_num = inst->debug_count.etb;
|
||||||
stats->timestamp = buf->timestamp;
|
stats->timestamp = timestamp;
|
||||||
|
stats->ts_offset = 0;
|
||||||
stats->etb_time_ms = buf->start_time_ms;
|
stats->etb_time_ms = buf->start_time_ms;
|
||||||
if (is_decode_session(inst))
|
if (is_decode_session(inst))
|
||||||
stats->data_size = buf->data_size;
|
stats->data_size = buf->data_size;
|
||||||
@@ -397,10 +404,12 @@ int msm_vidc_add_buffer_stats(struct msm_vidc_inst *inst,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int msm_vidc_remove_buffer_stats(struct msm_vidc_inst *inst,
|
int msm_vidc_remove_buffer_stats(struct msm_vidc_inst *inst,
|
||||||
struct msm_vidc_buffer *buf)
|
struct msm_vidc_buffer *buf, u64 timestamp)
|
||||||
{
|
{
|
||||||
struct msm_vidc_buffer_stats *stats = NULL, *dummy_stats = NULL;
|
struct msm_vidc_buffer_stats *stats = NULL, *dummy_stats = NULL;
|
||||||
|
struct msm_vidc_buffer_stats *prev_stats = NULL;
|
||||||
struct msm_vidc_core *core;
|
struct msm_vidc_core *core;
|
||||||
|
bool remove_stat = false, is_first_stat = false;;
|
||||||
|
|
||||||
if (!inst || !inst->core || !buf) {
|
if (!inst || !inst->core || !buf) {
|
||||||
d_vpr_e("%s: invalid params\n", __func__);
|
d_vpr_e("%s: invalid params\n", __func__);
|
||||||
@@ -408,6 +417,9 @@ int msm_vidc_remove_buffer_stats(struct msm_vidc_inst *inst,
|
|||||||
}
|
}
|
||||||
core = inst->core;
|
core = inst->core;
|
||||||
|
|
||||||
|
if (!(msm_vidc_debug & VIDC_STAT))
|
||||||
|
return 0;
|
||||||
|
|
||||||
/* stats applicable only to input & output buffers */
|
/* stats applicable only to input & output buffers */
|
||||||
if (buf->type != MSM_VIDC_BUF_INPUT && buf->type != MSM_VIDC_BUF_OUTPUT)
|
if (buf->type != MSM_VIDC_BUF_INPUT && buf->type != MSM_VIDC_BUF_OUTPUT)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@@ -416,38 +428,51 @@ int msm_vidc_remove_buffer_stats(struct msm_vidc_inst *inst,
|
|||||||
buf->end_time_ms = (ktime_get_ns() / 1000 - inst->initial_time_us) / 1000;
|
buf->end_time_ms = (ktime_get_ns() / 1000 - inst->initial_time_us) / 1000;
|
||||||
|
|
||||||
list_for_each_entry_safe(stats, dummy_stats, &inst->buffer_stats_list, list) {
|
list_for_each_entry_safe(stats, dummy_stats, &inst->buffer_stats_list, list) {
|
||||||
if (stats->timestamp == buf->timestamp) {
|
if (stats->timestamp - stats->ts_offset != timestamp)
|
||||||
if (buf->type == MSM_VIDC_BUF_INPUT) {
|
continue;
|
||||||
/* skip - already updated(multiple input - single output case) */
|
|
||||||
if (stats->ebd_time_ms)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* ebd: update end ts and return */
|
remove_stat = false;
|
||||||
stats->ebd_time_ms = buf->end_time_ms;
|
if (buf->type == MSM_VIDC_BUF_INPUT) {
|
||||||
stats->flags |= msm_vidc_get_buffer_stats_flag(inst);
|
/* skip - ebd already updated(multiple input - single output case) */
|
||||||
|
if (stats->ebd_time_ms)
|
||||||
|
continue;
|
||||||
|
|
||||||
/* remove entry - no output attached */
|
/* ebd: update end ts and return */
|
||||||
if (stats->flags & MSM_VIDC_STATS_FLAG_NO_OUTPUT) {
|
stats->ebd_time_ms = buf->end_time_ms;
|
||||||
list_del_init(&stats->list);
|
stats->flags |= msm_vidc_get_buffer_stats_flag(inst);
|
||||||
msm_vidc_pool_free(inst, stats);
|
|
||||||
}
|
|
||||||
} else if (buf->type == MSM_VIDC_BUF_OUTPUT) {
|
|
||||||
/* skip - ebd not arrived(single input - multiple output case) */
|
|
||||||
if (!stats->ebd_time_ms)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* fbd: update end ts and remove entry */
|
/* multi in - single out (interlace/slice decoding case) */
|
||||||
list_del_init(&stats->list);
|
is_first_stat = list_is_first(&stats->list, &inst->buffer_stats_list);
|
||||||
stats->ftb_time_ms = buf->start_time_ms;
|
if (!is_first_stat) {
|
||||||
stats->fbd_time_ms = buf->end_time_ms;
|
prev_stats = list_prev_entry(stats, list);
|
||||||
stats->flags |= msm_vidc_get_buffer_stats_flag(inst);
|
|
||||||
if (is_encode_session(inst))
|
|
||||||
stats->data_size = buf->data_size;
|
|
||||||
|
|
||||||
print_buffer_stats(VIDC_STAT, "stat", inst, stats);
|
/* add offset if FW requires more etb's to process output */
|
||||||
|
if (prev_stats->flags & MSM_VIDC_STATS_FLAG_SUBFRAME_INPUT)
|
||||||
msm_vidc_pool_free(inst, stats);
|
stats->ts_offset = stats->timestamp - prev_stats->timestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* remove entry - no output attached */
|
||||||
|
remove_stat = !!(stats->flags & MSM_VIDC_STATS_FLAG_NO_OUTPUT);
|
||||||
|
remove_stat |= stats->ebd_time_ms && stats->fbd_time_ms;
|
||||||
|
} else if (buf->type == MSM_VIDC_BUF_OUTPUT) {
|
||||||
|
/* skip - ebd already updated(encoder superframe case) */
|
||||||
|
if (stats->fbd_time_ms)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* fbd: update end ts */
|
||||||
|
stats->ftb_time_ms = buf->start_time_ms;
|
||||||
|
stats->fbd_time_ms = buf->end_time_ms;
|
||||||
|
stats->flags |= msm_vidc_get_buffer_stats_flag(inst);
|
||||||
|
if (is_encode_session(inst))
|
||||||
|
stats->data_size = buf->data_size;
|
||||||
|
|
||||||
|
remove_stat |= stats->ebd_time_ms && stats->fbd_time_ms;
|
||||||
|
}
|
||||||
|
/* remove stats node */
|
||||||
|
if (remove_stat) {
|
||||||
|
list_del_init(&stats->list);
|
||||||
|
print_buffer_stats(VIDC_STAT, "stat", inst, stats);
|
||||||
|
msm_vidc_pool_free(inst, stats);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2832,9 +2857,6 @@ struct msm_vidc_buffer *msm_vidc_get_driver_buf(struct msm_vidc_inst *inst,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* update start timestamp */
|
|
||||||
msm_vidc_add_buffer_stats(inst, buf);
|
|
||||||
|
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1825,6 +1825,9 @@ int venus_hfi_queue_super_buffer(struct msm_vidc_inst *inst,
|
|||||||
if (rc)
|
if (rc)
|
||||||
goto unlock;
|
goto unlock;
|
||||||
|
|
||||||
|
/* update start timestamp */
|
||||||
|
msm_vidc_add_buffer_stats(inst, buffer, hfi_buffer.timestamp);
|
||||||
|
|
||||||
cnt++;
|
cnt++;
|
||||||
}
|
}
|
||||||
unlock:
|
unlock:
|
||||||
@@ -1884,7 +1887,7 @@ int venus_hfi_queue_buffer(struct msm_vidc_inst *inst,
|
|||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
struct msm_vidc_core *core;
|
struct msm_vidc_core *core;
|
||||||
struct hfi_buffer hfi_buffer;
|
struct hfi_buffer hfi_buffer, hfi_meta_buffer;
|
||||||
|
|
||||||
if (!inst || !inst->core || !inst->packet || !inst->capabilities) {
|
if (!inst || !inst->core || !inst->packet || !inst->capabilities) {
|
||||||
d_vpr_e("%s: invalid params\n", __func__);
|
d_vpr_e("%s: invalid params\n", __func__);
|
||||||
@@ -1920,7 +1923,7 @@ int venus_hfi_queue_buffer(struct msm_vidc_inst *inst,
|
|||||||
goto unlock;
|
goto unlock;
|
||||||
|
|
||||||
if (metabuf) {
|
if (metabuf) {
|
||||||
rc = get_hfi_buffer(inst, metabuf, &hfi_buffer);
|
rc = get_hfi_buffer(inst, metabuf, &hfi_meta_buffer);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto unlock;
|
goto unlock;
|
||||||
rc = hfi_create_packet(inst->packet,
|
rc = hfi_create_packet(inst->packet,
|
||||||
@@ -1930,8 +1933,8 @@ int venus_hfi_queue_buffer(struct msm_vidc_inst *inst,
|
|||||||
HFI_PAYLOAD_STRUCTURE,
|
HFI_PAYLOAD_STRUCTURE,
|
||||||
get_hfi_port_from_buffer_type(inst, metabuf->type),
|
get_hfi_port_from_buffer_type(inst, metabuf->type),
|
||||||
core->packet_id++,
|
core->packet_id++,
|
||||||
&hfi_buffer,
|
&hfi_meta_buffer,
|
||||||
sizeof(hfi_buffer));
|
sizeof(hfi_meta_buffer));
|
||||||
if (rc)
|
if (rc)
|
||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
@@ -1964,6 +1967,9 @@ int venus_hfi_queue_buffer(struct msm_vidc_inst *inst,
|
|||||||
if (rc)
|
if (rc)
|
||||||
goto unlock;
|
goto unlock;
|
||||||
|
|
||||||
|
/* update start timestamp */
|
||||||
|
msm_vidc_add_buffer_stats(inst, buffer, hfi_buffer.timestamp);
|
||||||
|
|
||||||
unlock:
|
unlock:
|
||||||
core_unlock(core, __func__);
|
core_unlock(core, __func__);
|
||||||
return rc;
|
return rc;
|
||||||
|
@@ -822,6 +822,8 @@ static int handle_input_buffer(struct msm_vidc_inst *inst,
|
|||||||
if (buffer->addr_offset / frame_size < batch_size - 1) {
|
if (buffer->addr_offset / frame_size < batch_size - 1) {
|
||||||
i_vpr_l(inst, "%s: superframe last buffer not reached: %u, %u, %u\n",
|
i_vpr_l(inst, "%s: superframe last buffer not reached: %u, %u, %u\n",
|
||||||
__func__, buffer->addr_offset, frame_size, batch_size);
|
__func__, buffer->addr_offset, frame_size, batch_size);
|
||||||
|
/* remove buffer stats for all the subframes in a superframe */
|
||||||
|
msm_vidc_remove_buffer_stats(inst, buf, buffer->timestamp);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -848,8 +850,8 @@ static int handle_input_buffer(struct msm_vidc_inst *inst,
|
|||||||
print_vidc_buffer(VIDC_HIGH, "high", "dqbuf", inst, buf);
|
print_vidc_buffer(VIDC_HIGH, "high", "dqbuf", inst, buf);
|
||||||
msm_vidc_update_stats(inst, buf, MSM_VIDC_DEBUGFS_EVENT_EBD);
|
msm_vidc_update_stats(inst, buf, MSM_VIDC_DEBUGFS_EVENT_EBD);
|
||||||
|
|
||||||
/* etd: update end timestamp and flags in stats entry */
|
/* ebd: update end timestamp and flags in stats entry */
|
||||||
msm_vidc_remove_buffer_stats(inst, buf);
|
msm_vidc_remove_buffer_stats(inst, buf, buffer->timestamp);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@@ -1026,7 +1028,7 @@ static int handle_output_buffer(struct msm_vidc_inst *inst,
|
|||||||
msm_vidc_update_stats(inst, buf, MSM_VIDC_DEBUGFS_EVENT_FBD);
|
msm_vidc_update_stats(inst, buf, MSM_VIDC_DEBUGFS_EVENT_FBD);
|
||||||
|
|
||||||
/* fbd: print stats and remove entry */
|
/* fbd: print stats and remove entry */
|
||||||
msm_vidc_remove_buffer_stats(inst, buf);
|
msm_vidc_remove_buffer_stats(inst, buf, buffer->timestamp);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
Viittaa uudesa ongelmassa
Block a user