diff mbox series

media: venus: preserve DRC state across seeks

Message ID 20201202053424.3286774-1-acourbot@chromium.org
State Accepted
Commit d5ee32d7e5929592ad9b6e7a919dcdf89d05221b
Headers show
Series media: venus: preserve DRC state across seeks | expand

Commit Message

Alexandre Courbot Dec. 2, 2020, 5:34 a.m. UTC
DRC events can happen virtually at anytime, including when we are
starting a seek. Should this happen, we must make sure to return to the
DRC state, otherwise the firmware will expect buffers of the new
resolution whereas userspace will still work with the old one.

Returning to the DRC state upon resume for seeking makes sure that the
client will get the DRC event and will reallocate the buffers to fit the
firmware's expectations.

Signed-off-by: Alexandre Courbot <acourbot@chromium.org>
---
 drivers/media/platform/qcom/venus/vdec.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

Comments

Stanimir Varbanov Dec. 17, 2020, 9:46 a.m. UTC | #1
Hi Alex,


On 12/2/20 7:34 AM, Alexandre Courbot wrote:
> DRC events can happen virtually at anytime, including when we are

> starting a seek. Should this happen, we must make sure to return to the

> DRC state, otherwise the firmware will expect buffers of the new

> resolution whereas userspace will still work with the old one.

> 

> Returning to the DRC state upon resume for seeking makes sure that the

> client will get the DRC event and will reallocate the buffers to fit the

> firmware's expectations.

> 

> Signed-off-by: Alexandre Courbot <acourbot@chromium.org>

> ---

>  drivers/media/platform/qcom/venus/vdec.c | 11 +++++++++--

>  1 file changed, 9 insertions(+), 2 deletions(-)

> 

> diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c

> index 8488411204c3..e3d0df7fd765 100644

> --- a/drivers/media/platform/qcom/venus/vdec.c

> +++ b/drivers/media/platform/qcom/venus/vdec.c

> @@ -972,7 +972,10 @@ static int vdec_start_output(struct venus_inst *inst)

>  

>  	if (inst->codec_state == VENUS_DEC_STATE_SEEK) {

>  		ret = venus_helper_process_initial_out_bufs(inst);

> -		inst->codec_state = VENUS_DEC_STATE_DECODING;

> +		if (inst->next_buf_last)

> +			inst->codec_state = VENUS_DEC_STATE_DRC;

> +		else

> +			inst->codec_state = VENUS_DEC_STATE_DECODING;

>  		goto done;

>  	}

>  

> @@ -1077,8 +1080,10 @@ static int vdec_stop_capture(struct venus_inst *inst)

>  		ret = hfi_session_flush(inst, HFI_FLUSH_ALL, true);

>  		fallthrough;

>  	case VENUS_DEC_STATE_DRAIN:

> -		vdec_cancel_dst_buffers(inst);

>  		inst->codec_state = VENUS_DEC_STATE_STOPPED;

> +		fallthrough;

> +	case VENUS_DEC_STATE_SEEK:

> +		vdec_cancel_dst_buffers(inst);

>  		break;

>  	case VENUS_DEC_STATE_DRC:

>  		WARN_ON(1);

> @@ -1102,6 +1107,7 @@ static int vdec_stop_output(struct venus_inst *inst)

>  	case VENUS_DEC_STATE_DECODING:

>  	case VENUS_DEC_STATE_DRAIN:

>  	case VENUS_DEC_STATE_STOPPED:

> +	case VENUS_DEC_STATE_DRC:

>  		ret = hfi_session_flush(inst, HFI_FLUSH_ALL, true);

>  		inst->codec_state = VENUS_DEC_STATE_SEEK;

>  		break;

> @@ -1371,6 +1377,7 @@ static void vdec_event_change(struct venus_inst *inst,

>  			dev_dbg(dev, VDBGH "flush output error %d\n", ret);

>  	}

>  

> +	inst->next_buf_last = true;


Setting next_buf_last unconditionally makes me think can we reuse
inst->reconfig instead?

>  	inst->reconfig = true;

>  	v4l2_event_queue_fh(&inst->fh, &ev);

>  	wake_up(&inst->reconf_wait);

> 


-- 
regards,
Stan
diff mbox series

Patch

diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c
index 8488411204c3..e3d0df7fd765 100644
--- a/drivers/media/platform/qcom/venus/vdec.c
+++ b/drivers/media/platform/qcom/venus/vdec.c
@@ -972,7 +972,10 @@  static int vdec_start_output(struct venus_inst *inst)
 
 	if (inst->codec_state == VENUS_DEC_STATE_SEEK) {
 		ret = venus_helper_process_initial_out_bufs(inst);
-		inst->codec_state = VENUS_DEC_STATE_DECODING;
+		if (inst->next_buf_last)
+			inst->codec_state = VENUS_DEC_STATE_DRC;
+		else
+			inst->codec_state = VENUS_DEC_STATE_DECODING;
 		goto done;
 	}
 
@@ -1077,8 +1080,10 @@  static int vdec_stop_capture(struct venus_inst *inst)
 		ret = hfi_session_flush(inst, HFI_FLUSH_ALL, true);
 		fallthrough;
 	case VENUS_DEC_STATE_DRAIN:
-		vdec_cancel_dst_buffers(inst);
 		inst->codec_state = VENUS_DEC_STATE_STOPPED;
+		fallthrough;
+	case VENUS_DEC_STATE_SEEK:
+		vdec_cancel_dst_buffers(inst);
 		break;
 	case VENUS_DEC_STATE_DRC:
 		WARN_ON(1);
@@ -1102,6 +1107,7 @@  static int vdec_stop_output(struct venus_inst *inst)
 	case VENUS_DEC_STATE_DECODING:
 	case VENUS_DEC_STATE_DRAIN:
 	case VENUS_DEC_STATE_STOPPED:
+	case VENUS_DEC_STATE_DRC:
 		ret = hfi_session_flush(inst, HFI_FLUSH_ALL, true);
 		inst->codec_state = VENUS_DEC_STATE_SEEK;
 		break;
@@ -1371,6 +1377,7 @@  static void vdec_event_change(struct venus_inst *inst,
 			dev_dbg(dev, VDBGH "flush output error %d\n", ret);
 	}
 
+	inst->next_buf_last = true;
 	inst->reconfig = true;
 	v4l2_event_queue_fh(&inst->fh, &ev);
 	wake_up(&inst->reconf_wait);