Bläddra i källkod

Merge "video: driver: Modify buffer_stats logic"

qctecmdr 2 år sedan
förälder
incheckning
db62f9374a

+ 2 - 2
driver/vidc/inc/msm_vidc_driver.h

@@ -588,9 +588,9 @@ int signal_session_msg_receipt(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_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,
-	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_get_input_rate(struct msm_vidc_inst *inst);
 int msm_vidc_get_frame_rate(struct msm_vidc_inst *inst);

+ 5 - 3
driver/vidc/inc/msm_vidc_internal.h

@@ -917,12 +917,14 @@ struct msm_vidc_buffer_stats {
 	u32                                fbd_time_ms;
 	u32                                data_size;
 	u32                                flags;
+	u32                                ts_offset;
 };
 
 enum msm_vidc_buffer_stats_flag {
-	MSM_VIDC_STATS_FLAG_CORRUPT     = BIT(0),
-	MSM_VIDC_STATS_FLAG_OVERFLOW    = BIT(1),
-	MSM_VIDC_STATS_FLAG_NO_OUTPUT   = BIT(2),
+	MSM_VIDC_STATS_FLAG_CORRUPT        = BIT(0),
+	MSM_VIDC_STATS_FLAG_OVERFLOW       = BIT(1),
+	MSM_VIDC_STATS_FLAG_NO_OUTPUT      = BIT(2),
+	MSM_VIDC_STATS_FLAG_SUBFRAME_INPUT = BIT(3),
 };
 
 struct msm_vidc_sort {

+ 59 - 37
driver/vidc/src/msm_vidc_driver.c

@@ -285,6 +285,9 @@ static u32 msm_vidc_get_buffer_stats_flag(struct msm_vidc_inst *inst)
 	if (inst->hfi_frame_info.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;
 }
 
@@ -326,7 +329,7 @@ static int msm_vidc_try_suspend(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_core *core;
@@ -337,6 +340,9 @@ int msm_vidc_add_buffer_stats(struct msm_vidc_inst *inst,
 	}
 	core = inst->core;
 
+	if (!(msm_vidc_debug & VIDC_STAT))
+		return 0;
+
 	/* stats applicable only to input & output buffers */
 	if (buf->type != MSM_VIDC_BUF_INPUT && buf->type != MSM_VIDC_BUF_OUTPUT)
 		return -EINVAL;
@@ -355,7 +361,8 @@ int msm_vidc_add_buffer_stats(struct msm_vidc_inst *inst,
 	list_add_tail(&stats->list, &inst->buffer_stats_list);
 
 	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;
 	if (is_decode_session(inst))
 		stats->data_size =  buf->data_size;
@@ -364,10 +371,12 @@ int msm_vidc_add_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 *prev_stats = NULL;
 	struct msm_vidc_core *core;
+	bool remove_stat = false, is_first_stat = false;;
 
 	if (!inst || !inst->core || !buf) {
 		d_vpr_e("%s: invalid params\n", __func__);
@@ -375,6 +384,9 @@ int msm_vidc_remove_buffer_stats(struct msm_vidc_inst *inst,
 	}
 	core = inst->core;
 
+	if (!(msm_vidc_debug & VIDC_STAT))
+		return 0;
+
 	/* stats applicable only to input & output buffers */
 	if (buf->type != MSM_VIDC_BUF_INPUT && buf->type != MSM_VIDC_BUF_OUTPUT)
 		return -EINVAL;
@@ -383,38 +395,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;
 
 	list_for_each_entry_safe(stats, dummy_stats, &inst->buffer_stats_list, list) {
-		if (stats->timestamp == buf->timestamp) {
-			if (buf->type == MSM_VIDC_BUF_INPUT) {
-				/* skip - already updated(multiple input - single output case) */
-				if (stats->ebd_time_ms)
-					continue;
-
-				/* ebd: update end ts and return */
-				stats->ebd_time_ms = buf->end_time_ms;
-				stats->flags |= msm_vidc_get_buffer_stats_flag(inst);
-
-				/* remove entry - no output attached */
-				if (stats->flags & MSM_VIDC_STATS_FLAG_NO_OUTPUT) {
-					list_del_init(&stats->list);
-					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 */
-				list_del_init(&stats->list);
-				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;
-
-				print_buffer_stats(VIDC_STAT, "stat", inst, stats);
-
-				msm_vidc_pool_free(inst, stats);
+		if (stats->timestamp - stats->ts_offset != timestamp)
+			continue;
+
+		remove_stat = false;
+		if (buf->type == MSM_VIDC_BUF_INPUT) {
+			/* skip - ebd already updated(multiple input - single output case) */
+			if (stats->ebd_time_ms)
+				continue;
+
+			/* ebd: update end ts and return */
+			stats->ebd_time_ms = buf->end_time_ms;
+			stats->flags |= msm_vidc_get_buffer_stats_flag(inst);
+
+			/* multi in - single out (interlace/slice decoding case) */
+			is_first_stat = list_is_first(&stats->list, &inst->buffer_stats_list);
+			if (!is_first_stat) {
+				prev_stats = list_prev_entry(stats, list);
+
+				/* add offset if FW requires more etb's to process output */
+				if (prev_stats->flags & MSM_VIDC_STATS_FLAG_SUBFRAME_INPUT)
+					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);
 		}
 	}
 
@@ -2707,9 +2732,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;
 }
 

+ 10 - 4
driver/vidc/src/venus_hfi.c

@@ -1831,6 +1831,9 @@ int venus_hfi_queue_super_buffer(struct msm_vidc_inst *inst,
 		if (rc)
 			goto unlock;
 
+		/* update start timestamp */
+		msm_vidc_add_buffer_stats(inst, buffer, hfi_buffer.timestamp);
+
 		cnt++;
 	}
 unlock:
@@ -1890,7 +1893,7 @@ int venus_hfi_queue_buffer(struct msm_vidc_inst *inst,
 {
 	int rc = 0;
 	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) {
 		d_vpr_e("%s: invalid params\n", __func__);
@@ -1926,7 +1929,7 @@ int venus_hfi_queue_buffer(struct msm_vidc_inst *inst,
 		goto unlock;
 
 	if (metabuf) {
-		rc = get_hfi_buffer(inst, metabuf, &hfi_buffer);
+		rc = get_hfi_buffer(inst, metabuf, &hfi_meta_buffer);
 		if (rc)
 			goto unlock;
 		rc = hfi_create_packet(inst->packet,
@@ -1936,8 +1939,8 @@ int venus_hfi_queue_buffer(struct msm_vidc_inst *inst,
 			HFI_PAYLOAD_STRUCTURE,
 			get_hfi_port_from_buffer_type(inst, metabuf->type),
 			core->packet_id++,
-			&hfi_buffer,
-			sizeof(hfi_buffer));
+			&hfi_meta_buffer,
+			sizeof(hfi_meta_buffer));
 		if (rc)
 			goto unlock;
 	}
@@ -1970,6 +1973,9 @@ int venus_hfi_queue_buffer(struct msm_vidc_inst *inst,
 	if (rc)
 		goto unlock;
 
+	/* update start timestamp */
+	msm_vidc_add_buffer_stats(inst, buffer, hfi_buffer.timestamp);
+
 unlock:
 	core_unlock(core, __func__);
 	return rc;

+ 5 - 3
driver/vidc/src/venus_hfi_response.c

@@ -822,6 +822,8 @@ static int handle_input_buffer(struct msm_vidc_inst *inst,
 		if (buffer->addr_offset / frame_size < batch_size - 1) {
 			i_vpr_l(inst, "%s: superframe last buffer not reached: %u, %u, %u\n",
 				__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;
 		}
 	}
@@ -848,8 +850,8 @@ static int handle_input_buffer(struct msm_vidc_inst *inst,
 	print_vidc_buffer(VIDC_HIGH, "high", "dqbuf", inst, buf);
 	msm_vidc_update_stats(inst, buf, MSM_VIDC_DEBUGFS_EVENT_EBD);
 
-	/* etd: update end timestamp and flags in stats entry */
-	msm_vidc_remove_buffer_stats(inst, buf);
+	/* ebd: update end timestamp and flags in stats entry */
+	msm_vidc_remove_buffer_stats(inst, buf, buffer->timestamp);
 
 	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);
 
 	/* fbd: print stats and remove entry */
-	msm_vidc_remove_buffer_stats(inst, buf);
+	msm_vidc_remove_buffer_stats(inst, buf, buffer->timestamp);
 
 	return rc;
 }