Commit c1f8b2cc authored by Dikshita Agarwal's avatar Dikshita Agarwal Committed by Hans Verkuil
Browse files

media: iris: handle streamoff/on from client in dynamic resolution change



The decoder is stopped after it completes the dynamic resolution change
sequence. Handle VIDIOC_STREAMOFF() and VIDIOC_STREAMON() on the CAPTURE
queue to resume the decoding process.

Tested-by: Stefan Schmidt <stefan.schmidt@linaro.org> # x1e80100 (Dell XPS 13 9345)
Reviewed-by: default avatarStefan Schmidt <stefan.schmidt@linaro.org>
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-QRD
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-HDK
Signed-off-by: default avatarDikshita Agarwal <quic_dikshita@quicinc.com>
Signed-off-by: default avatarHans Verkuil <hverkuil@xs4all.nl>
parent 84e17ada
Loading
Loading
Loading
Loading
+58 −0
Original line number Diff line number Diff line
@@ -404,6 +404,47 @@ int iris_destroy_internal_buffers(struct iris_inst *inst, u32 plane)
	return 0;
}

static int iris_release_internal_buffers(struct iris_inst *inst,
					 enum iris_buffer_type buffer_type)
{
	const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
	struct iris_buffers *buffers = &inst->buffers[buffer_type];
	struct iris_buffer *buffer, *next;
	int ret;

	list_for_each_entry_safe(buffer, next, &buffers->list, list) {
		if (buffer->attr & BUF_ATTR_PENDING_RELEASE)
			continue;
		if (!(buffer->attr & BUF_ATTR_QUEUED))
			continue;
		ret = hfi_ops->session_release_buf(inst, buffer);
		if (ret)
			return ret;
		buffer->attr |= BUF_ATTR_PENDING_RELEASE;
	}

	return 0;
}

static int iris_release_input_internal_buffers(struct iris_inst *inst)
{
	const struct iris_platform_data *platform_data = inst->core->iris_platform_data;
	const u32 *internal_buf_type;
	u32 internal_buffer_count, i;
	int ret;

	internal_buf_type = platform_data->dec_ip_int_buf_tbl;
	internal_buffer_count = platform_data->dec_ip_int_buf_tbl_size;

	for (i = 0; i < internal_buffer_count; i++) {
		ret = iris_release_internal_buffers(inst, internal_buf_type[i]);
		if (ret)
			return ret;
	}

	return 0;
}

int iris_alloc_and_queue_persist_bufs(struct iris_inst *inst)
{
	struct iris_buffers *buffers = &inst->buffers[BUF_PERSIST];
@@ -435,6 +476,23 @@ int iris_alloc_and_queue_persist_bufs(struct iris_inst *inst)
	return 0;
}

int iris_alloc_and_queue_input_int_bufs(struct iris_inst *inst)
{
	int ret;

	iris_get_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);

	ret = iris_release_input_internal_buffers(inst);
	if (ret)
		return ret;

	ret = iris_create_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
	if (ret)
		return ret;

	return iris_queue_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
}

int iris_queue_deferred_buffers(struct iris_inst *inst, enum iris_buffer_type buf_type)
{
	struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
+1 −0
Original line number Diff line number Diff line
@@ -108,6 +108,7 @@ int iris_queue_internal_buffers(struct iris_inst *inst, u32 plane);
int iris_destroy_internal_buffer(struct iris_inst *inst, struct iris_buffer *buffer);
int iris_destroy_internal_buffers(struct iris_inst *inst, u32 plane);
int iris_alloc_and_queue_persist_bufs(struct iris_inst *inst);
int iris_alloc_and_queue_input_int_bufs(struct iris_inst *inst);
int iris_queue_buffer(struct iris_inst *inst, struct iris_buffer *buf);
int iris_queue_deferred_buffers(struct iris_inst *inst, enum iris_buffer_type buf_type);
int iris_vb2_buffer_done(struct iris_inst *inst, struct iris_buffer *buf);
+2 −0
Original line number Diff line number Diff line
@@ -118,6 +118,8 @@ struct iris_hfi_command_ops {
	int (*session_start)(struct iris_inst *inst, u32 plane);
	int (*session_queue_buf)(struct iris_inst *inst, struct iris_buffer *buffer);
	int (*session_release_buf)(struct iris_inst *inst, struct iris_buffer *buffer);
	int (*session_pause)(struct iris_inst *inst, u32 plane);
	int (*session_resume_drc)(struct iris_inst *inst, u32 plane);
	int (*session_stop)(struct iris_inst *inst, u32 plane);
	int (*session_close)(struct iris_inst *inst);
};
+10 −0
Original line number Diff line number Diff line
@@ -205,6 +205,15 @@ static int iris_hfi_gen1_session_stop(struct iris_inst *inst, u32 plane)
	return ret;
}

static int iris_hfi_gen1_session_continue(struct iris_inst *inst, u32 plane)
{
	struct hfi_session_pkt packet;

	iris_hfi_gen1_packet_session_cmd(inst, &packet, HFI_CMD_SESSION_CONTINUE);

	return iris_hfi_queue_cmd_write(inst->core, &packet, packet.shdr.hdr.size);
}

static int iris_hfi_gen1_queue_input_buffer(struct iris_inst *inst, struct iris_buffer *buf)
{
	struct hfi_session_empty_buffer_compressed_pkt ip_pkt;
@@ -778,6 +787,7 @@ static const struct iris_hfi_command_ops iris_hfi_gen1_command_ops = {
	.session_start = iris_hfi_gen1_session_start,
	.session_queue_buf = iris_hfi_gen1_session_queue_buffer,
	.session_release_buf = iris_hfi_gen1_session_unset_buffers,
	.session_resume_drc = iris_hfi_gen1_session_continue,
	.session_stop = iris_hfi_gen1_session_stop,
	.session_close = iris_hfi_gen1_session_close,
};
+1 −0
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@
#define HFI_CMD_SESSION_FLUSH				0x211008
#define HFI_CMD_SESSION_RELEASE_BUFFERS			0x21100b
#define HFI_CMD_SESSION_RELEASE_RESOURCES		0x21100c
#define HFI_CMD_SESSION_CONTINUE			0x21100d

#define HFI_ERR_SESSION_UNSUPPORTED_SETTING		0x1008
#define HFI_ERR_SESSION_UNSUPPORTED_STREAM		0x100d
Loading