Message ID | 20200520171457.11937-1-jernej.skrabec@siol.net (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | media: cedrus: Add support for additional output formats | expand |
Hello Jernej, Thanks for the patch. On Wed, 20 May 2020 at 14:12, Jernej Skrabec <jernej.skrabec@siol.net> wrote: > > If VPU supports untiled output, it actually supports several different > YUV 4:2:0 layouts, namely NV12, NV21, YUV420 and YVU420. > > Add support for all of them. > > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net> > --- > drivers/staging/media/sunxi/cedrus/cedrus_hw.c | 18 +++++++++++++++++- > .../staging/media/sunxi/cedrus/cedrus_video.c | 18 ++++++++++++++++++ > 2 files changed, 35 insertions(+), 1 deletion(-) > > diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_hw.c b/drivers/staging/media/sunxi/cedrus/cedrus_hw.c > index daf5f244f93b..c119fd8c4b92 100644 > --- a/drivers/staging/media/sunxi/cedrus/cedrus_hw.c > +++ b/drivers/staging/media/sunxi/cedrus/cedrus_hw.c > @@ -83,9 +83,25 @@ void cedrus_dst_format_set(struct cedrus_dev *dev, > > switch (fmt->pixelformat) { > case V4L2_PIX_FMT_NV12: > + case V4L2_PIX_FMT_NV21: > + case V4L2_PIX_FMT_YUV420: > + case V4L2_PIX_FMT_YVU420: > chroma_size = ALIGN(width, 16) * ALIGN(height, 16) / 2; > > - reg = VE_PRIMARY_OUT_FMT_NV12; > + switch (fmt->pixelformat) { > + case V4L2_PIX_FMT_NV12: > + reg = VE_PRIMARY_OUT_FMT_NV12; > + break; > + case V4L2_PIX_FMT_NV21: > + reg = VE_PRIMARY_OUT_FMT_NV21; > + break; > + case V4L2_PIX_FMT_YUV420: > + reg = VE_PRIMARY_OUT_FMT_YU12; > + break; > + case V4L2_PIX_FMT_YVU420: > + reg = VE_PRIMARY_OUT_FMT_YV12; > + break; > + } > cedrus_write(dev, VE_PRIMARY_OUT_FMT, reg); > I think it would result in a cleaner code if you extend cedrus_format to include the hw_format. Something along these lines (not a complete patch): diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_video.c b/drivers/staging/media/sunxi/cedrus/cedrus_video.c index 15cf1f10221b..618daaa65a82 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus_video.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus_video.c @@ -48,10 +48,12 @@ static struct cedrus_format cedrus_formats[] = { }, { .pixelformat = V4L2_PIX_FMT_SUNXI_TILED_NV12, + .hw_format = VE_PRIMARY_OUT_FMT_TILED_32_NV12, .directions = CEDRUS_DECODE_DST, }, { .pixelformat = V4L2_PIX_FMT_NV12, + .hw_format = VE_PRIMARY_OUT_FMT_NV12, .directions = CEDRUS_DECODE_DST, .capabilities = CEDRUS_CAPABILITY_UNTILED, }, @@ -274,6 +276,7 @@ static int cedrus_s_fmt_vid_cap(struct file *file, void *priv, { struct cedrus_ctx *ctx = cedrus_file2ctx(file); struct cedrus_dev *dev = ctx->dev; + struct cedrus_format *fmt; struct vb2_queue *vq; int ret; @@ -287,7 +290,10 @@ static int cedrus_s_fmt_vid_cap(struct file *file, void *priv, ctx->dst_fmt = f->fmt.pix; - cedrus_dst_format_set(dev, &ctx->dst_fmt); + fmt = cedrus_find_format(ctx->dst_fmt.pixelformat, + CEDRUS_DECODE_DST, + dev->capabilities); + cedrus_dst_format_set(dev, fmt); return 0; } So then in cedrus_dst_format_set() you can just write VE_PRIMARY_OUT_FMT with fmt->hw_format. > reg = chroma_size / 2; > diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_video.c b/drivers/staging/media/sunxi/cedrus/cedrus_video.c > index 15cf1f10221b..016021d71df2 100644 > --- a/drivers/staging/media/sunxi/cedrus/cedrus_video.c > +++ b/drivers/staging/media/sunxi/cedrus/cedrus_video.c > @@ -55,6 +55,21 @@ static struct cedrus_format cedrus_formats[] = { > .directions = CEDRUS_DECODE_DST, > .capabilities = CEDRUS_CAPABILITY_UNTILED, > }, > + { > + .pixelformat = V4L2_PIX_FMT_NV21, > + .directions = CEDRUS_DECODE_DST, > + .capabilities = CEDRUS_CAPABILITY_UNTILED, > + }, > + { > + .pixelformat = V4L2_PIX_FMT_YUV420, > + .directions = CEDRUS_DECODE_DST, > + .capabilities = CEDRUS_CAPABILITY_UNTILED, > + }, > + { > + .pixelformat = V4L2_PIX_FMT_YVU420, > + .directions = CEDRUS_DECODE_DST, > + .capabilities = CEDRUS_CAPABILITY_UNTILED, > + }, > }; > > #define CEDRUS_FORMATS_COUNT ARRAY_SIZE(cedrus_formats) > @@ -130,6 +145,9 @@ void cedrus_prepare_format(struct v4l2_pix_format *pix_fmt) > break; > > case V4L2_PIX_FMT_NV12: > + case V4L2_PIX_FMT_NV21: > + case V4L2_PIX_FMT_YUV420: > + case V4L2_PIX_FMT_YVU420: > /* 16-aligned stride. */ > bytesperline = ALIGN(width, 16); > > -- > 2.26.2 > Thanks, Ezequiel
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_hw.c b/drivers/staging/media/sunxi/cedrus/cedrus_hw.c index daf5f244f93b..c119fd8c4b92 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus_hw.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus_hw.c @@ -83,9 +83,25 @@ void cedrus_dst_format_set(struct cedrus_dev *dev, switch (fmt->pixelformat) { case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV21: + case V4L2_PIX_FMT_YUV420: + case V4L2_PIX_FMT_YVU420: chroma_size = ALIGN(width, 16) * ALIGN(height, 16) / 2; - reg = VE_PRIMARY_OUT_FMT_NV12; + switch (fmt->pixelformat) { + case V4L2_PIX_FMT_NV12: + reg = VE_PRIMARY_OUT_FMT_NV12; + break; + case V4L2_PIX_FMT_NV21: + reg = VE_PRIMARY_OUT_FMT_NV21; + break; + case V4L2_PIX_FMT_YUV420: + reg = VE_PRIMARY_OUT_FMT_YU12; + break; + case V4L2_PIX_FMT_YVU420: + reg = VE_PRIMARY_OUT_FMT_YV12; + break; + } cedrus_write(dev, VE_PRIMARY_OUT_FMT, reg); reg = chroma_size / 2; diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_video.c b/drivers/staging/media/sunxi/cedrus/cedrus_video.c index 15cf1f10221b..016021d71df2 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus_video.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus_video.c @@ -55,6 +55,21 @@ static struct cedrus_format cedrus_formats[] = { .directions = CEDRUS_DECODE_DST, .capabilities = CEDRUS_CAPABILITY_UNTILED, }, + { + .pixelformat = V4L2_PIX_FMT_NV21, + .directions = CEDRUS_DECODE_DST, + .capabilities = CEDRUS_CAPABILITY_UNTILED, + }, + { + .pixelformat = V4L2_PIX_FMT_YUV420, + .directions = CEDRUS_DECODE_DST, + .capabilities = CEDRUS_CAPABILITY_UNTILED, + }, + { + .pixelformat = V4L2_PIX_FMT_YVU420, + .directions = CEDRUS_DECODE_DST, + .capabilities = CEDRUS_CAPABILITY_UNTILED, + }, }; #define CEDRUS_FORMATS_COUNT ARRAY_SIZE(cedrus_formats) @@ -130,6 +145,9 @@ void cedrus_prepare_format(struct v4l2_pix_format *pix_fmt) break; case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV21: + case V4L2_PIX_FMT_YUV420: + case V4L2_PIX_FMT_YVU420: /* 16-aligned stride. */ bytesperline = ALIGN(width, 16);
If VPU supports untiled output, it actually supports several different YUV 4:2:0 layouts, namely NV12, NV21, YUV420 and YVU420. Add support for all of them. Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net> --- drivers/staging/media/sunxi/cedrus/cedrus_hw.c | 18 +++++++++++++++++- .../staging/media/sunxi/cedrus/cedrus_video.c | 18 ++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-)