Re: [PATCH v8 4/5] media: rkvdec: Add the rkvdec driver

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, 2020-04-06 at 16:27 -0400, Nicolas Dufresne wrote:
> Le ven. 3 avr. 2020 à 18:14, Ezequiel Garcia <ezequiel@xxxxxxxxxxxxx> a écrit :
> > From: Boris Brezillon <boris.brezillon@xxxxxxxxxxxxx>
> > 
> > The rockchip vdec block is a stateless decoder that's able to decode
> > H264, HEVC and VP9 content. This commit adds the core infrastructure
> > and the H264 backend. Support for VP9 and HEVS will be added later on.
> > 
> > Signed-off-by: Boris Brezillon <boris.brezillon@xxxxxxxxxxxxx>
> > Signed-off-by: Ezequiel Garcia <ezequiel@xxxxxxxxxxxxx>
> 
> Sorry for the late feedback (got a comment lower) ...
> 
> Tested-by: Nicolas Dufresne <nicolas.dufresne@xxxxxxxxxxxxx>
> 

Nice, thank you.

> > --
> > v8:
> > * Fix kfree and style changes, as suggested by Andriy.
> > v7:
> > * hverkuil-cisco@xxxxxxxxx: replaced VFL_TYPE_GRABBER by _VIDEO
> > * Use macros and ARRAY_SIZE instead of magic numbers,
> >   as suggested by Mauro.
> > * Renamed M_N macro, suggested by Mauro.
> > * Use v4l2_m2m_buf_done_and_job_finish.
> > * Set buffers' zeroth plane payload in .buf_prepare
> > * Refactor try/s_fmt for spec compliance.
> > ---
> >  MAINTAINERS                                |    7 +
> >  drivers/staging/media/Kconfig              |    2 +
> >  drivers/staging/media/Makefile             |    1 +
> >  drivers/staging/media/rkvdec/Kconfig       |   15 +
> >  drivers/staging/media/rkvdec/Makefile      |    3 +
> >  drivers/staging/media/rkvdec/TODO          |   11 +
> >  drivers/staging/media/rkvdec/rkvdec-h264.c | 1156 ++++++++++++++++++++
> >  drivers/staging/media/rkvdec/rkvdec-regs.h |  223 ++++
> >  drivers/staging/media/rkvdec/rkvdec.c      | 1103 +++++++++++++++++++
> >  drivers/staging/media/rkvdec/rkvdec.h      |  121 ++
> >  10 files changed, 2642 insertions(+)
> >  create mode 100644 drivers/staging/media/rkvdec/Kconfig
> >  create mode 100644 drivers/staging/media/rkvdec/Makefile
> >  create mode 100644 drivers/staging/media/rkvdec/TODO
> >  create mode 100644 drivers/staging/media/rkvdec/rkvdec-h264.c
> >  create mode 100644 drivers/staging/media/rkvdec/rkvdec-regs.h
> >  create mode 100644 drivers/staging/media/rkvdec/rkvdec.c
> >  create mode 100644 drivers/staging/media/rkvdec/rkvdec.h
> > 
> 
[..]
> > +
> > +static void set_ps_field(u32 *buf, struct rkvdec_ps_field field, u32 value)
> > +{
> > +       u8 bit = field.offset % 32, word = field.offset / 32;
> > +       u64 mask = GENMASK_ULL(bit + field.len - 1, bit);
> > +       u64 val = ((u64)value << bit) & mask;
> > +
> > +       buf[word] &= ~mask;
> > +       buf[word] |= val;
> > +       if (bit + field.len > 32) {
> > +               buf[word + 1] &= ~(mask >> 32);
> > +               buf[word + 1] |= val >> 32;
> > +       }
> > +}
> > +
> > +static void assemble_hw_pps(struct rkvdec_ctx *ctx,
> > +                           struct rkvdec_h264_run *run)
> > +{
> > +       struct rkvdec_h264_ctx *h264_ctx = ctx->priv;
> > +       const struct v4l2_ctrl_h264_sps *sps = run->sps;
> > +       const struct v4l2_ctrl_h264_pps *pps = run->pps;
> > +       const struct v4l2_ctrl_h264_decode_params *dec_params = run->decode_params;
> > +       const struct v4l2_h264_dpb_entry *dpb = dec_params->dpb;
> > +       struct rkvdec_h264_priv_tbl *priv_tbl = h264_ctx->priv_tbl.cpu;
> > +       struct rkvdec_sps_pps_packet *hw_ps;
> > +       dma_addr_t scaling_list_address;
> > +       u32 scaling_distance;
> > +       u32 i;
> > +
> > +       /*
> > +        * HW read the SPS/PPS information from PPS packet index by PPS id.
> > +        * offset from the base can be calculated by PPS_id * 32 (size per PPS
> > +        * packet unit). so the driver copy SPS/PPS information to the exact PPS
> > +        * packet unit for HW accessing.
> > +        */
> > +       hw_ps = &priv_tbl->param_set[pps->pic_parameter_set_id];
> > +       memset(hw_ps, 0, sizeof(*hw_ps));
> > +
> > +#define WRITE_PPS(value, field) set_ps_field(hw_ps->info, field, value)
> > +       /* write sps */
> > +       WRITE_PPS(0xf, SEQ_PARAMETER_SET_ID);
> > +       WRITE_PPS(0xff, PROFILE_IDC);
> > +       WRITE_PPS(1, CONSTRAINT_SET3_FLAG);
> 
> At first I found that part rather interesting, but I see this
> hardcoding matches what Rockchip do.
> 
> https://github.com/rockchip-linux/mpp/blob/release/mpp/hal/rkdec/h264d/hal_h264d_rkv_reg.c#L266
> 
> > +       WRITE_PPS(sps->chroma_format_idc, CHROMA_FORMAT_IDC);
> 
> But here's it's not so great. This driver does not implement any kind
> of validation. In fact, if I pass 3
> here  (YCbCr 4:4:4) it will accept it, and kind of decode some frames,
> but eventually with crash and
> reboot is needed. We should (as defined in the Statelss CODEC spec)
> validate the SPS and refuse if
> an unsupported profile idc, chroma idc, luma/chroma depth or coded
> size is requested.

Perhaps we could validate that at request_validate time,
or maybe ops.try_ctrl is better.

</thinking_out_loud>

> Validating the
> S_FMT is not sufficient as one can trick the driver in allocating
> buffers that are too small.
> 

I am not sure I follow you: how do you think the driver
can be tricked like this?

> What I suspect is that we need to be careful with this HW, as it seems
> to be a bit half backed, which
> means it might be supporting more features then supported by the TRM
> or reference code, and we
> must disable this with software.
> 
> (p.s. I can provide a stream to reproduce the 4:4:4 driver failure)
> 

Thanks,
Ezequiel




[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux