mbox series

[00/10] Venus stateful Codec API

Message ID 20190117162008.25217-1-stanimir.varbanov@linaro.org
Headers show
Series Venus stateful Codec API | expand

Message

Stanimir Varbanov Jan. 17, 2019, 4:19 p.m. UTC
Hello,

This aims to make Venus decoder compliant with stateful Codec API [1].
The patches 1-9 are preparation for the cherry on the cake patch 10
which implements the decoder state machine similar to the one in the
stateful codec API documentation.

There few things which are still TODO:
 - V4L2_DEC_CMD_START implementation as per decoder documentation.
 - Dynamic resolution change V4L2_BUF_FLAG_LAST for the last buffer
   before the resolution change.

The patches are tested with chromium VDA unittests at [2].

Note that the patchset depends on Venus various fixes at [3].

Comments are welcome!

regards,
Stan

[1] https://patchwork.kernel.org/patch/10652199/
[2] https://chromium.googlesource.com/chromium/src/+/lkgr/docs/media/gpu/vdatest_usage.md
[3] https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1894510.html

Stanimir Varbanov (10):
  venus: hfi_cmds: add more not-implemented properties
  venus: helpers: fix dynamic buffer mode for v4
  venus: helpers: export few helper functions
  venus: hfi: add type argument to hfi flush function
  venus: hfi: export few HFI functions
  venus: hfi: return an error if session_init is already called
  venus: helpers: add three more helper functions
  venus: vdec_ctrls: get real minimum buffers for capture
  venus: vdec: allow bigger sizeimage set by clients
  venus: dec: make decoder compliant with stateful codec API

 drivers/media/platform/qcom/venus/core.h      |  20 +-
 drivers/media/platform/qcom/venus/helpers.c   | 141 +++++-
 drivers/media/platform/qcom/venus/helpers.h   |  14 +
 drivers/media/platform/qcom/venus/hfi.c       |  11 +-
 drivers/media/platform/qcom/venus/hfi.h       |   2 +-
 drivers/media/platform/qcom/venus/hfi_cmds.c  |   2 +
 drivers/media/platform/qcom/venus/vdec.c      | 467 ++++++++++++++----
 .../media/platform/qcom/venus/vdec_ctrls.c    |   7 +-
 8 files changed, 535 insertions(+), 129 deletions(-)

-- 
2.17.1

Comments

Alexandre Courbot Jan. 24, 2019, 8:43 a.m. UTC | #1
On Fri, Jan 18, 2019 at 1:21 AM Stanimir Varbanov
<stanimir.varbanov@linaro.org> wrote:
>

> This adds three more helper functions:

>  * for internal buffers reallocation, applicable when we are doing

> dynamic resolution change

>  * for initial buffer processing of capture and output queue buffer

> types

>

> All of them will be needed for stateful Codec API support.

>

> Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>

> ---

>  drivers/media/platform/qcom/venus/helpers.c | 82 +++++++++++++++++++++

>  drivers/media/platform/qcom/venus/helpers.h |  2 +

>  2 files changed, 84 insertions(+)

>

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

> index f33bbfea3576..637ce7b82d94 100644

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

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

> @@ -322,6 +322,52 @@ int venus_helper_intbufs_free(struct venus_inst *inst)

>  }

>  EXPORT_SYMBOL_GPL(venus_helper_intbufs_free);

>

> +int venus_helper_intbufs_realloc(struct venus_inst *inst)


Does this function actually reallocate buffers? It seems to just free
what we had previously.


> +{

> +       enum hfi_version ver = inst->core->res->hfi_version;

> +       struct hfi_buffer_desc bd;

> +       struct intbuf *buf, *n;

> +       int ret;

> +

> +       list_for_each_entry_safe(buf, n, &inst->internalbufs, list) {

> +               if (buf->type == HFI_BUFFER_INTERNAL_PERSIST ||

> +                   buf->type == HFI_BUFFER_INTERNAL_PERSIST_1)

> +                       continue;

> +

> +               memset(&bd, 0, sizeof(bd));

> +               bd.buffer_size = buf->size;

> +               bd.buffer_type = buf->type;

> +               bd.num_buffers = 1;

> +               bd.device_addr = buf->da;

> +               bd.response_required = true;

> +

> +               ret = hfi_session_unset_buffers(inst, &bd);

> +

> +               dma_free_attrs(inst->core->dev, buf->size, buf->va, buf->da,

> +                              buf->attrs);

> +

> +               list_del_init(&buf->list);

> +               kfree(buf);

> +       }

> +

> +       ret = intbufs_set_buffer(inst, HFI_BUFFER_INTERNAL_SCRATCH(ver));

> +       if (ret)

> +               goto err;

> +

> +       ret = intbufs_set_buffer(inst, HFI_BUFFER_INTERNAL_SCRATCH_1(ver));

> +       if (ret)

> +               goto err;

> +

> +       ret = intbufs_set_buffer(inst, HFI_BUFFER_INTERNAL_SCRATCH_2(ver));

> +       if (ret)

> +               goto err;

> +

> +       return 0;

> +err:

> +       return ret;

> +}

> +EXPORT_SYMBOL_GPL(venus_helper_intbufs_realloc);

> +

>  static u32 load_per_instance(struct venus_inst *inst)

>  {

>         u32 mbs;

> @@ -1050,6 +1096,42 @@ void venus_helper_vb2_stop_streaming(struct vb2_queue *q)

>  }

>  EXPORT_SYMBOL_GPL(venus_helper_vb2_stop_streaming);

>

> +int venus_helper_process_initial_cap_bufs(struct venus_inst *inst)

> +{

> +       struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;

> +       struct v4l2_m2m_buffer *buf, *n;

> +       int ret;

> +

> +       v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, buf, n) {

> +               ret = session_process_buf(inst, &buf->vb);

> +               if (ret) {

> +                       return_buf_error(inst, &buf->vb);

> +                       return ret;

> +               }

> +       }

> +

> +       return 0;

> +}

> +EXPORT_SYMBOL_GPL(venus_helper_process_initial_cap_bufs);

> +

> +int venus_helper_process_initial_out_bufs(struct venus_inst *inst)

> +{

> +       struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;

> +       struct v4l2_m2m_buffer *buf, *n;

> +       int ret;

> +

> +       v4l2_m2m_for_each_src_buf_safe(m2m_ctx, buf, n) {

> +               ret = session_process_buf(inst, &buf->vb);

> +               if (ret) {

> +                       return_buf_error(inst, &buf->vb);

> +                       return ret;

> +               }

> +       }

> +

> +       return 0;

> +}

> +EXPORT_SYMBOL_GPL(venus_helper_process_initial_out_bufs);

> +

>  int venus_helper_vb2_start_streaming(struct venus_inst *inst)

>  {

>         struct venus_core *core = inst->core;

> diff --git a/drivers/media/platform/qcom/venus/helpers.h b/drivers/media/platform/qcom/venus/helpers.h

> index 24faae5abd93..2ec1c1a8b416 100644

> --- a/drivers/media/platform/qcom/venus/helpers.h

> +++ b/drivers/media/platform/qcom/venus/helpers.h

> @@ -69,4 +69,6 @@ int venus_helper_intbufs_realloc(struct venus_inst *inst);

>  int venus_helper_queue_dpb_bufs(struct venus_inst *inst);

>  int venus_helper_unregister_bufs(struct venus_inst *inst);

>  int venus_helper_load_scale_clocks(struct venus_core *core);

> +int venus_helper_process_initial_cap_bufs(struct venus_inst *inst);

> +int venus_helper_process_initial_out_bufs(struct venus_inst *inst);

>  #endif

> --

> 2.17.1

>
Alexandre Courbot Jan. 24, 2019, 8:43 a.m. UTC | #2
On Fri, Jan 18, 2019 at 1:21 AM Stanimir Varbanov
<stanimir.varbanov@linaro.org> wrote:
>

> In most of the cases the client will know better what could be

> the maximum size for compressed data buffers. Change the driver

> to permit the user to set bigger size for the compressed buffer

> but make reasonable sanitation.

>

> Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>

> ---

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

>  1 file changed, 13 insertions(+), 5 deletions(-)

>

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

> index 282de21cf2e1..7a9370df7515 100644

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

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

> @@ -142,6 +142,7 @@ vdec_try_fmt_common(struct venus_inst *inst, struct v4l2_format *f)

>         struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;

>         struct v4l2_plane_pix_format *pfmt = pixmp->plane_fmt;

>         const struct venus_format *fmt;

> +       u32 szimage;

>

>         memset(pfmt[0].reserved, 0, sizeof(pfmt[0].reserved));

>         memset(pixmp->reserved, 0, sizeof(pixmp->reserved));

> @@ -170,14 +171,18 @@ vdec_try_fmt_common(struct venus_inst *inst, struct v4l2_format *f)

>         pixmp->num_planes = fmt->num_planes;

>         pixmp->flags = 0;

>

> -       pfmt[0].sizeimage = venus_helper_get_framesz(pixmp->pixelformat,

> -                                                    pixmp->width,

> -                                                    pixmp->height);

> +       szimage = venus_helper_get_framesz(pixmp->pixelformat, pixmp->width,

> +                                          pixmp->height);

>

> -       if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)

> +       if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {

> +               pfmt[0].sizeimage = szimage;

>                 pfmt[0].bytesperline = ALIGN(pixmp->width, 128);

> -       else

> +       } else {

> +               pfmt[0].sizeimage = clamp_t(u32, pfmt[0].sizeimage, 0, SZ_4M);

> +               if (szimage > pfmt[0].sizeimage)

> +                       pfmt[0].sizeimage = szimage;


pfmt[0].sizeimage = max(clamp_t(u32, pfmt[0].sizeimage, 0, SZ_4M),
                                        szimage)?

>                 pfmt[0].bytesperline = 0;

> +       }

>

>         return fmt;

>  }

> @@ -275,6 +280,7 @@ static int vdec_s_fmt(struct file *file, void *fh, struct v4l2_format *f)

>                 inst->ycbcr_enc = pixmp->ycbcr_enc;

>                 inst->quantization = pixmp->quantization;

>                 inst->xfer_func = pixmp->xfer_func;

> +               inst->input_buf_size = pixmp->plane_fmt[0].sizeimage;

>         }

>

>         memset(&format, 0, sizeof(format));

> @@ -737,6 +743,8 @@ static int vdec_queue_setup(struct vb2_queue *q,

>                 sizes[0] = venus_helper_get_framesz(inst->fmt_out->pixfmt,

>                                                     inst->out_width,

>                                                     inst->out_height);

> +               if (inst->input_buf_size > sizes[0])

> +                       sizes[0] = inst->input_buf_size;


               sizes[0] = max(venus_helper_get_framesz(inst->fmt_out->pixfmt,
                                                   inst->out_width,
                                                 inst->out_height),
                                      inst->input_buf_size)?



>                 inst->input_buf_size = sizes[0];

>                 *num_buffers = max(*num_buffers, in_num);

>                 inst->num_input_bufs = *num_buffers;

> --

> 2.17.1

>
Stanimir Varbanov Jan. 24, 2019, 8:54 a.m. UTC | #3
Hi Alex,

Thanks for the review!

On 1/24/19 10:43 AM, Alexandre Courbot wrote:
> On Fri, Jan 18, 2019 at 1:21 AM Stanimir Varbanov

> <stanimir.varbanov@linaro.org> wrote:

>>

>> This adds three more helper functions:

>>  * for internal buffers reallocation, applicable when we are doing

>> dynamic resolution change

>>  * for initial buffer processing of capture and output queue buffer

>> types

>>

>> All of them will be needed for stateful Codec API support.

>>

>> Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>

>> ---

>>  drivers/media/platform/qcom/venus/helpers.c | 82 +++++++++++++++++++++

>>  drivers/media/platform/qcom/venus/helpers.h |  2 +

>>  2 files changed, 84 insertions(+)

>>

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

>> index f33bbfea3576..637ce7b82d94 100644

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

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

>> @@ -322,6 +322,52 @@ int venus_helper_intbufs_free(struct venus_inst *inst)

>>  }

>>  EXPORT_SYMBOL_GPL(venus_helper_intbufs_free);

>>

>> +int venus_helper_intbufs_realloc(struct venus_inst *inst)

> 

> Does this function actually reallocate buffers? It seems to just free

> what we had previously.


The function free all internal buffers except PERSIST. After that the
buffers are allocated in intbufs_set_buffer function (I know that the
function name is misleading).

> 

> 

>> +{

>> +       enum hfi_version ver = inst->core->res->hfi_version;

>> +       struct hfi_buffer_desc bd;

>> +       struct intbuf *buf, *n;

>> +       int ret;

>> +

>> +       list_for_each_entry_safe(buf, n, &inst->internalbufs, list) {

>> +               if (buf->type == HFI_BUFFER_INTERNAL_PERSIST ||

>> +                   buf->type == HFI_BUFFER_INTERNAL_PERSIST_1)

>> +                       continue;

>> +

>> +               memset(&bd, 0, sizeof(bd));

>> +               bd.buffer_size = buf->size;

>> +               bd.buffer_type = buf->type;

>> +               bd.num_buffers = 1;

>> +               bd.device_addr = buf->da;

>> +               bd.response_required = true;

>> +

>> +               ret = hfi_session_unset_buffers(inst, &bd);

>> +

>> +               dma_free_attrs(inst->core->dev, buf->size, buf->va, buf->da,

>> +                              buf->attrs);

>> +

>> +               list_del_init(&buf->list);

>> +               kfree(buf);

>> +       }

>> +

>> +       ret = intbufs_set_buffer(inst, HFI_BUFFER_INTERNAL_SCRATCH(ver));

>> +       if (ret)

>> +               goto err;

>> +

>> +       ret = intbufs_set_buffer(inst, HFI_BUFFER_INTERNAL_SCRATCH_1(ver));

>> +       if (ret)

>> +               goto err;

>> +

>> +       ret = intbufs_set_buffer(inst, HFI_BUFFER_INTERNAL_SCRATCH_2(ver));

>> +       if (ret)

>> +               goto err;

>> +

>> +       return 0;

>> +err:

>> +       return ret;

>> +}

>> +EXPORT_SYMBOL_GPL(venus_helper_intbufs_realloc);

>> +



-- 
regards,
Stan
Stanimir Varbanov Jan. 24, 2019, 9:59 a.m. UTC | #4
Hi Alex,

Thanks for the comments!

On 1/24/19 10:43 AM, Alexandre Courbot wrote:
> On Fri, Jan 18, 2019 at 1:21 AM Stanimir Varbanov

> <stanimir.varbanov@linaro.org> wrote:

>>

>> Until now we returned num_output_bufs set during reqbuf but

>> that could be wrong when we implement stateful Codec API. So

>> get the minimum buffers for capture from HFI. This is supposed

>> to be called after stream header parsing, i.e. after dequeue

>> v4l2 event for change resolution.

>>

>> Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>

>> ---

>>  drivers/media/platform/qcom/venus/vdec_ctrls.c | 7 ++++++-

>>  1 file changed, 6 insertions(+), 1 deletion(-)

>>

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

>> index f4604b0cd57e..e1da87bf52bc 100644

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

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

>> @@ -16,6 +16,7 @@

>>  #include <media/v4l2-ctrls.h>

>>

>>  #include "core.h"

>> +#include "helpers.h"

>>  #include "vdec.h"

>>

>>  static int vdec_op_s_ctrl(struct v4l2_ctrl *ctrl)

>> @@ -47,7 +48,9 @@ static int vdec_op_g_volatile_ctrl(struct v4l2_ctrl *ctrl)

>>  {

>>         struct venus_inst *inst = ctrl_to_inst(ctrl);

>>         struct vdec_controls *ctr = &inst->controls.dec;

>> +       struct hfi_buffer_requirements bufreq;

>>         union hfi_get_property hprop;

>> +       enum hfi_version ver = inst->core->res->hfi_version;

>>         u32 ptype = HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT;

>>         int ret;

>>

>> @@ -71,7 +74,9 @@ static int vdec_op_g_volatile_ctrl(struct v4l2_ctrl *ctrl)

>>                 ctrl->val = ctr->post_loop_deb_mode;

>>                 break;

>>         case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:

>> -               ctrl->val = inst->num_output_bufs;

>> +               ret = venus_helper_get_bufreq(inst, HFI_BUFFER_OUTPUT, &bufreq);

>> +               if (!ret)

>> +                       ctrl->val = HFI_BUFREQ_COUNT_MIN(&bufreq, ver);

> 

> What happens if venus_helper_get_bufreq() returns an error? It seems

> that we just happily continue with whatever the previous value of

> ctrl->val was. It seems like we do the same with other controls as

> well.


I agree that this is wrong, I think no-one userspace client used that
g_ctrls controls :)

> 

> I think you can fix this globally by initializing ret to 0 at the

> beginning of the function, and then returning ret instead of 0 at the

> end. That way all errors would be propagated. Of course please check

> that this is relevant for other controls following this scheme before

> doing so. :)

> 


yes, I will do!

-- 
regards,
Stan
Stanimir Varbanov Jan. 24, 2019, 10:05 a.m. UTC | #5
Hi Alex,

Thanks for the comments!

On 1/24/19 10:43 AM, Alexandre Courbot wrote:
> On Fri, Jan 18, 2019 at 1:21 AM Stanimir Varbanov

> <stanimir.varbanov@linaro.org> wrote:

>>

>> In most of the cases the client will know better what could be

>> the maximum size for compressed data buffers. Change the driver

>> to permit the user to set bigger size for the compressed buffer

>> but make reasonable sanitation.

>>

>> Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>

>> ---

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

>>  1 file changed, 13 insertions(+), 5 deletions(-)

>>

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

>> index 282de21cf2e1..7a9370df7515 100644

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

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

>> @@ -142,6 +142,7 @@ vdec_try_fmt_common(struct venus_inst *inst, struct v4l2_format *f)

>>         struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;

>>         struct v4l2_plane_pix_format *pfmt = pixmp->plane_fmt;

>>         const struct venus_format *fmt;

>> +       u32 szimage;

>>

>>         memset(pfmt[0].reserved, 0, sizeof(pfmt[0].reserved));

>>         memset(pixmp->reserved, 0, sizeof(pixmp->reserved));

>> @@ -170,14 +171,18 @@ vdec_try_fmt_common(struct venus_inst *inst, struct v4l2_format *f)

>>         pixmp->num_planes = fmt->num_planes;

>>         pixmp->flags = 0;

>>

>> -       pfmt[0].sizeimage = venus_helper_get_framesz(pixmp->pixelformat,

>> -                                                    pixmp->width,

>> -                                                    pixmp->height);

>> +       szimage = venus_helper_get_framesz(pixmp->pixelformat, pixmp->width,

>> +                                          pixmp->height);

>>

>> -       if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)

>> +       if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {

>> +               pfmt[0].sizeimage = szimage;

>>                 pfmt[0].bytesperline = ALIGN(pixmp->width, 128);

>> -       else

>> +       } else {

>> +               pfmt[0].sizeimage = clamp_t(u32, pfmt[0].sizeimage, 0, SZ_4M);

>> +               if (szimage > pfmt[0].sizeimage)

>> +                       pfmt[0].sizeimage = szimage;

> 

> pfmt[0].sizeimage = max(clamp_t(u32, pfmt[0].sizeimage, 0, SZ_4M),

>                                         szimage)?


I'm not a big fan to that calling of macro from macro :)

What about this:

	pfmt[0].sizeimage = clamp_t(u32, pfmt[0].sizeimage, 0, SZ_4M);
	pfmt[0].sizeimage = max(pfmt[0].sizeimage, szimage);

> 

>>                 pfmt[0].bytesperline = 0;

>> +       }

>>

>>         return fmt;

>>  }

>> @@ -275,6 +280,7 @@ static int vdec_s_fmt(struct file *file, void *fh, struct v4l2_format *f)

>>                 inst->ycbcr_enc = pixmp->ycbcr_enc;

>>                 inst->quantization = pixmp->quantization;

>>                 inst->xfer_func = pixmp->xfer_func;

>> +               inst->input_buf_size = pixmp->plane_fmt[0].sizeimage;

>>         }

>>

>>         memset(&format, 0, sizeof(format));

>> @@ -737,6 +743,8 @@ static int vdec_queue_setup(struct vb2_queue *q,

>>                 sizes[0] = venus_helper_get_framesz(inst->fmt_out->pixfmt,

>>                                                     inst->out_width,

>>                                                     inst->out_height);

>> +               if (inst->input_buf_size > sizes[0])

>> +                       sizes[0] = inst->input_buf_size;

> 

>                sizes[0] = max(venus_helper_get_framesz(inst->fmt_out->pixfmt,

>                                                    inst->out_width,

>                                                  inst->out_height),

>                                       inst->input_buf_size)?


I think it'd be more readable that way:

		sizes[0] = max(sizes[0], inst->input_buf_size);

> 

> 

> 

>>                 inst->input_buf_size = sizes[0];

>>                 *num_buffers = max(*num_buffers, in_num);

>>                 inst->num_input_bufs = *num_buffers;

>> --

>> 2.17.1

>>


-- 
regards,
Stan
Alexandre Courbot Jan. 25, 2019, 5:36 a.m. UTC | #6
On Thu, Jan 24, 2019 at 7:05 PM Stanimir Varbanov
<stanimir.varbanov@linaro.org> wrote:
>

> Hi Alex,

>

> Thanks for the comments!

>

> On 1/24/19 10:43 AM, Alexandre Courbot wrote:

> > On Fri, Jan 18, 2019 at 1:21 AM Stanimir Varbanov

> > <stanimir.varbanov@linaro.org> wrote:

> >>

> >> In most of the cases the client will know better what could be

> >> the maximum size for compressed data buffers. Change the driver

> >> to permit the user to set bigger size for the compressed buffer

> >> but make reasonable sanitation.

> >>

> >> Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>

> >> ---

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

> >>  1 file changed, 13 insertions(+), 5 deletions(-)

> >>

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

> >> index 282de21cf2e1..7a9370df7515 100644

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

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

> >> @@ -142,6 +142,7 @@ vdec_try_fmt_common(struct venus_inst *inst, struct v4l2_format *f)

> >>         struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;

> >>         struct v4l2_plane_pix_format *pfmt = pixmp->plane_fmt;

> >>         const struct venus_format *fmt;

> >> +       u32 szimage;

> >>

> >>         memset(pfmt[0].reserved, 0, sizeof(pfmt[0].reserved));

> >>         memset(pixmp->reserved, 0, sizeof(pixmp->reserved));

> >> @@ -170,14 +171,18 @@ vdec_try_fmt_common(struct venus_inst *inst, struct v4l2_format *f)

> >>         pixmp->num_planes = fmt->num_planes;

> >>         pixmp->flags = 0;

> >>

> >> -       pfmt[0].sizeimage = venus_helper_get_framesz(pixmp->pixelformat,

> >> -                                                    pixmp->width,

> >> -                                                    pixmp->height);

> >> +       szimage = venus_helper_get_framesz(pixmp->pixelformat, pixmp->width,

> >> +                                          pixmp->height);

> >>

> >> -       if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)

> >> +       if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {

> >> +               pfmt[0].sizeimage = szimage;

> >>                 pfmt[0].bytesperline = ALIGN(pixmp->width, 128);

> >> -       else

> >> +       } else {

> >> +               pfmt[0].sizeimage = clamp_t(u32, pfmt[0].sizeimage, 0, SZ_4M);

> >> +               if (szimage > pfmt[0].sizeimage)

> >> +                       pfmt[0].sizeimage = szimage;

> >

> > pfmt[0].sizeimage = max(clamp_t(u32, pfmt[0].sizeimage, 0, SZ_4M),

> >                                         szimage)?

>

> I'm not a big fan to that calling of macro from macro :)

>

> What about this:

>

>         pfmt[0].sizeimage = clamp_t(u32, pfmt[0].sizeimage, 0, SZ_4M);

>         pfmt[0].sizeimage = max(pfmt[0].sizeimage, szimage);


Looks fine, I just wanted to make sure that we use the more expressive
"max" instead of an if statement.

>

> >

> >>                 pfmt[0].bytesperline = 0;

> >> +       }

> >>

> >>         return fmt;

> >>  }

> >> @@ -275,6 +280,7 @@ static int vdec_s_fmt(struct file *file, void *fh, struct v4l2_format *f)

> >>                 inst->ycbcr_enc = pixmp->ycbcr_enc;

> >>                 inst->quantization = pixmp->quantization;

> >>                 inst->xfer_func = pixmp->xfer_func;

> >> +               inst->input_buf_size = pixmp->plane_fmt[0].sizeimage;

> >>         }

> >>

> >>         memset(&format, 0, sizeof(format));

> >> @@ -737,6 +743,8 @@ static int vdec_queue_setup(struct vb2_queue *q,

> >>                 sizes[0] = venus_helper_get_framesz(inst->fmt_out->pixfmt,

> >>                                                     inst->out_width,

> >>                                                     inst->out_height);

> >> +               if (inst->input_buf_size > sizes[0])

> >> +                       sizes[0] = inst->input_buf_size;

> >

> >                sizes[0] = max(venus_helper_get_framesz(inst->fmt_out->pixfmt,

> >                                                    inst->out_width,

> >                                                  inst->out_height),

> >                                       inst->input_buf_size)?

>

> I think it'd be more readable that way:

>

>                 sizes[0] = max(sizes[0], inst->input_buf_size);


Ditto.
Alexandre Courbot Jan. 28, 2019, 4:16 a.m. UTC | #7
On Fri, Jan 25, 2019 at 7:35 PM Stanimir Varbanov
<stanimir.varbanov@linaro.org> wrote:
>

> Hi Alex,

>

> On 1/25/19 7:34 AM, Alexandre Courbot wrote:

> > On Thu, Jan 24, 2019 at 7:13 PM Stanimir Varbanov

> > <stanimir.varbanov@linaro.org> wrote:

> >>

> >> Hi Alex,

> >>

> >> Thank you for review and valuable comments!

> >>

> >> On 1/24/19 10:43 AM, Alexandre Courbot wrote:

> >>> Hi Stanimir,

> >>>

> >>> On Fri, Jan 18, 2019 at 1:20 AM Stanimir Varbanov

> >>> <stanimir.varbanov@linaro.org> wrote:

> >>>>

> >>>> Hello,

> >>>>

> >>>> This aims to make Venus decoder compliant with stateful Codec API [1].

> >>>> The patches 1-9 are preparation for the cherry on the cake patch 10

> >>>> which implements the decoder state machine similar to the one in the

> >>>> stateful codec API documentation.

> >>>

> >>> Thanks *a lot* for this series! I am still stress-testing it against

> >>> the Chromium decoder tests, but so far it has been rock-solid. I have

> >>> a few inline comments on some patches ; I will also want to review the

> >>> state machine more thoroughly after refreshing my mind on Tomasz doc,

> >>> but this looks pretty promising already.

> >>

> >> I'm expecting problems with ResetAfterFirstConfigInfo. I don't know why

> >> but this test case is very dirty. I'd appreciate any help to decipher

> >> what is the sequence of v4l2 calls made by this unittest case.

> >

> > I did not see any issue with ResetAfterFirstConfigInfo, however

> > ResourceExhaustion seems to hang once in a while. But I could already

> > see this behavior with the older patchset.

>

> Is it hangs badly?


It just stops processing, no crash. I need to investigate more closely.

> >

> > In any case I plan to thoroughly review the state machine. I agree it

> > is a bit complex to grasp.

>

> yes the state machine isn't simple and I blamed Tomasz many times for

> that :)


If I feel inspired I may try to extract the useful part of your patch
into a framework that we can use everywhere. :) We don't want every
driver to reimplement this complex state machine and introduce new
bugs every time.