]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - drivers/staging/media/rockchip/vpu/rockchip_vpu_enc.c
media: rockchip/vpu: Use v4l2_apply_frmsize_constraints() where appropriate
[linux.git] / drivers / staging / media / rockchip / vpu / rockchip_vpu_enc.c
index fb5e36aedd8c5e58feda0b675eba83e038e309b3..aa00df9a7ecbd8c84119fc9b537efda4103e8dd4 100644 (file)
 #include "rockchip_vpu_hw.h"
 #include "rockchip_vpu_common.h"
 
-/**
- * struct v4l2_format_info - information about a V4L2 format
- * @format: 4CC format identifier (V4L2_PIX_FMT_*)
- * @header_size: Size of header, optional and used by compressed formats
- * @num_planes: Number of planes (1 to 3)
- * @cpp: Number of bytes per pixel (per plane)
- * @hsub: Horizontal chroma subsampling factor
- * @vsub: Vertical chroma subsampling factor
- * @is_compressed: Is it a compressed format?
- * @multiplanar: Is it a multiplanar variant format? (e.g. NV12M)
- */
-struct rockchip_vpu_v4l2_format_info {
-       u32 format;
-       u32 header_size;
-       u8 num_planes;
-       u8 cpp[3];
-       u8 hsub;
-       u8 vsub;
-       u8 is_compressed;
-       u8 multiplanar;
-};
-
-static const struct rockchip_vpu_v4l2_format_info *
-rockchip_vpu_v4l2_format_info(u32 format)
-{
-       static const struct rockchip_vpu_v4l2_format_info formats[] = {
-               { .format = V4L2_PIX_FMT_YUV420M,       .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 2, .vsub = 2, .multiplanar = 1 },
-               { .format = V4L2_PIX_FMT_NV12M,         .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 2, .multiplanar = 1 },
-               { .format = V4L2_PIX_FMT_YUYV,          .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1 },
-               { .format = V4L2_PIX_FMT_UYVY,          .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1 },
-       };
-       unsigned int i;
-
-       for (i = 0; i < ARRAY_SIZE(formats); ++i) {
-               if (formats[i].format == format)
-                       return &formats[i];
-       }
-
-       vpu_err("Unsupported V4L 4CC format (%08x)\n", format);
-       return NULL;
-}
-
-static void
-fill_pixfmt_mp(struct v4l2_pix_format_mplane *pixfmt,
-              int pixelformat, int width, int height)
-{
-       const struct rockchip_vpu_v4l2_format_info *info;
-       struct v4l2_plane_pix_format *plane;
-       int i;
-
-       info = rockchip_vpu_v4l2_format_info(pixelformat);
-       if (!info)
-               return;
-
-       pixfmt->width = width;
-       pixfmt->height = height;
-       pixfmt->pixelformat = pixelformat;
-
-       if (!info->multiplanar) {
-               pixfmt->num_planes = 1;
-               plane = &pixfmt->plane_fmt[0];
-               plane->bytesperline = info->is_compressed ?
-                                       0 : width * info->cpp[0];
-               plane->sizeimage = info->header_size;
-               for (i = 0; i < info->num_planes; i++) {
-                       unsigned int hsub = (i == 0) ? 1 : info->hsub;
-                       unsigned int vsub = (i == 0) ? 1 : info->vsub;
-
-                       plane->sizeimage += info->cpp[i] *
-                               DIV_ROUND_UP(width, hsub) *
-                               DIV_ROUND_UP(height, vsub);
-               }
-       } else {
-               pixfmt->num_planes = info->num_planes;
-               for (i = 0; i < info->num_planes; i++) {
-                       unsigned int hsub = (i == 0) ? 1 : info->hsub;
-                       unsigned int vsub = (i == 0) ? 1 : info->vsub;
-
-                       plane = &pixfmt->plane_fmt[i];
-                       plane->bytesperline =
-                               info->cpp[i] * DIV_ROUND_UP(width, hsub);
-                       plane->sizeimage =
-                               plane->bytesperline * DIV_ROUND_UP(height, vsub);
-               }
-       }
-}
-
 static const struct rockchip_vpu_fmt *
 rockchip_vpu_find_format(struct rockchip_vpu_ctx *ctx, u32 fourcc)
 {
@@ -152,9 +65,10 @@ static int vidioc_querycap(struct file *file, void *priv,
                           struct v4l2_capability *cap)
 {
        struct rockchip_vpu_dev *vpu = video_drvdata(file);
+       struct video_device *vdev = video_devdata(file);
 
        strscpy(cap->driver, vpu->dev->driver->name, sizeof(cap->driver));
-       strscpy(cap->card, vpu->vfd_enc->name, sizeof(cap->card));
+       strscpy(cap->card, vdev->name, sizeof(cap->card));
        snprintf(cap->bus_info, sizeof(cap->bus_info), "platform: %s",
                 vpu->dev->driver->name);
        return 0;
@@ -283,15 +197,9 @@ vidioc_try_fmt_cap_mplane(struct file *file, void *priv, struct v4l2_format *f)
 
        pix_mp->num_planes = 1;
        pix_mp->field = V4L2_FIELD_NONE;
-       pix_mp->width = clamp(pix_mp->width,
-                             fmt->frmsize.min_width,
-                             fmt->frmsize.max_width);
-       pix_mp->height = clamp(pix_mp->height,
-                              fmt->frmsize.min_height,
-                              fmt->frmsize.max_height);
-       /* Round up to macroblocks. */
-       pix_mp->width = round_up(pix_mp->width, JPEG_MB_DIM);
-       pix_mp->height = round_up(pix_mp->height, JPEG_MB_DIM);
+
+       v4l2_apply_frmsize_constraints(&pix_mp->width, &pix_mp->height,
+                                      &fmt->frmsize);
 
        /*
         * For compressed formats the application can specify
@@ -312,7 +220,6 @@ vidioc_try_fmt_out_mplane(struct file *file, void *priv, struct v4l2_format *f)
        struct rockchip_vpu_ctx *ctx = fh_to_ctx(priv);
        struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
        const struct rockchip_vpu_fmt *fmt;
-       unsigned int width, height;
        int i;
 
        vpu_debug(4, "%c%c%c%c\n",
@@ -328,18 +235,13 @@ vidioc_try_fmt_out_mplane(struct file *file, void *priv, struct v4l2_format *f)
        }
 
        pix_mp->field = V4L2_FIELD_NONE;
-       width = clamp(pix_mp->width,
-                     ctx->vpu_dst_fmt->frmsize.min_width,
-                     ctx->vpu_dst_fmt->frmsize.max_width);
-       height = clamp(pix_mp->height,
-                      ctx->vpu_dst_fmt->frmsize.min_height,
-                      ctx->vpu_dst_fmt->frmsize.max_height);
-       /* Round up to macroblocks. */
-       width = round_up(width, JPEG_MB_DIM);
-       height = round_up(height, JPEG_MB_DIM);
+
+       v4l2_apply_frmsize_constraints(&pix_mp->width, &pix_mp->height,
+                                      &ctx->vpu_dst_fmt->frmsize);
 
        /* Fill remaining fields */
-       fill_pixfmt_mp(pix_mp, fmt->fourcc, width, height);
+       v4l2_fill_pixfmt_mp(pix_mp, fmt->fourcc, pix_mp->width,
+                           pix_mp->height);
 
        for (i = 0; i < pix_mp->num_planes; i++) {
                memset(pix_mp->plane_fmt[i].reserved, 0,
@@ -358,10 +260,8 @@ void rockchip_vpu_enc_reset_dst_fmt(struct rockchip_vpu_dev *vpu,
        memset(fmt, 0, sizeof(*fmt));
 
        fmt->num_planes = 1;
-       fmt->width = clamp(fmt->width, ctx->vpu_dst_fmt->frmsize.min_width,
-                          ctx->vpu_dst_fmt->frmsize.max_width);
-       fmt->height = clamp(fmt->height, ctx->vpu_dst_fmt->frmsize.min_height,
-                           ctx->vpu_dst_fmt->frmsize.max_height);
+       v4l2_apply_frmsize_constraints(&fmt->width, &fmt->height,
+                                      &ctx->vpu_dst_fmt->frmsize);
        fmt->pixelformat = ctx->vpu_dst_fmt->fourcc;
        fmt->field = V4L2_FIELD_NONE;
        fmt->colorspace = V4L2_COLORSPACE_JPEG,
@@ -377,23 +277,21 @@ void rockchip_vpu_enc_reset_src_fmt(struct rockchip_vpu_dev *vpu,
                                    struct rockchip_vpu_ctx *ctx)
 {
        struct v4l2_pix_format_mplane *fmt = &ctx->src_fmt;
-       unsigned int width, height;
 
        ctx->vpu_src_fmt = rockchip_vpu_get_default_fmt(ctx, false);
 
        memset(fmt, 0, sizeof(*fmt));
 
-       width = clamp(fmt->width, ctx->vpu_dst_fmt->frmsize.min_width,
-                     ctx->vpu_dst_fmt->frmsize.max_width);
-       height = clamp(fmt->height, ctx->vpu_dst_fmt->frmsize.min_height,
-                      ctx->vpu_dst_fmt->frmsize.max_height);
+       v4l2_apply_frmsize_constraints(&fmt->width, &fmt->height,
+                                      &ctx->vpu_src_fmt->frmsize);
        fmt->field = V4L2_FIELD_NONE;
        fmt->colorspace = V4L2_COLORSPACE_JPEG,
        fmt->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
        fmt->quantization = V4L2_QUANTIZATION_DEFAULT;
        fmt->xfer_func = V4L2_XFER_FUNC_DEFAULT;
 
-       fill_pixfmt_mp(fmt, ctx->vpu_src_fmt->fourcc, width, height);
+       v4l2_fill_pixfmt_mp(fmt, ctx->vpu_src_fmt->fourcc, fmt->width,
+                           fmt->height);
 }
 
 static int
@@ -425,10 +323,8 @@ vidioc_s_fmt_out_mplane(struct file *file, void *priv, struct v4l2_format *f)
        ctx->dst_fmt.height = pix_mp->height;
 
        vpu_debug(0, "OUTPUT codec mode: %d\n", ctx->vpu_src_fmt->codec_mode);
-       vpu_debug(0, "fmt - w: %d, h: %d, mb - w: %d, h: %d\n",
-                 pix_mp->width, pix_mp->height,
-                 JPEG_MB_WIDTH(pix_mp->width),
-                 JPEG_MB_HEIGHT(pix_mp->height));
+       vpu_debug(0, "fmt - w: %d, h: %d\n",
+                 pix_mp->width, pix_mp->height);
        return 0;
 }
 
@@ -467,10 +363,8 @@ vidioc_s_fmt_cap_mplane(struct file *file, void *priv, struct v4l2_format *f)
        ctx->dst_fmt = *pix_mp;
 
        vpu_debug(0, "CAPTURE codec mode: %d\n", ctx->vpu_dst_fmt->codec_mode);
-       vpu_debug(0, "fmt - w: %d, h: %d, mb - w: %d, h: %d\n",
-                 pix_mp->width, pix_mp->height,
-                 JPEG_MB_WIDTH(pix_mp->width),
-                 JPEG_MB_HEIGHT(pix_mp->height));
+       vpu_debug(0, "fmt - w: %d, h: %d\n",
+                 pix_mp->width, pix_mp->height);
 
        /*
         * Current raw format might have become invalid with newly
@@ -605,6 +499,7 @@ static int rockchip_vpu_start_streaming(struct vb2_queue *q, unsigned int count)
 {
        struct rockchip_vpu_ctx *ctx = vb2_get_drv_priv(q);
        enum rockchip_vpu_codec_mode codec_mode;
+       int ret = 0;
 
        if (V4L2_TYPE_IS_OUTPUT(q->type))
                ctx->sequence_out = 0;
@@ -617,17 +512,10 @@ static int rockchip_vpu_start_streaming(struct vb2_queue *q, unsigned int count)
        vpu_debug(4, "Codec mode = %d\n", codec_mode);
        ctx->codec_ops = &ctx->dev->variant->codec_ops[codec_mode];
 
-       /* A bounce buffer is needed for the JPEG payload */
-       if (!V4L2_TYPE_IS_OUTPUT(q->type)) {
-               ctx->bounce_size = ctx->dst_fmt.plane_fmt[0].sizeimage -
-                                 ctx->vpu_dst_fmt->header_size;
-               ctx->bounce_buf = dma_alloc_attrs(ctx->dev->dev,
-                                                 ctx->bounce_size,
-                                                 &ctx->bounce_dma_addr,
-                                                 GFP_KERNEL,
-                                                 DMA_ATTR_ALLOC_SINGLE_PAGES);
-       }
-       return 0;
+       if (!V4L2_TYPE_IS_OUTPUT(q->type))
+               if (ctx->codec_ops && ctx->codec_ops->init)
+                       ret = ctx->codec_ops->init(ctx);
+       return ret;
 }
 
 static void rockchip_vpu_stop_streaming(struct vb2_queue *q)
@@ -635,11 +523,8 @@ static void rockchip_vpu_stop_streaming(struct vb2_queue *q)
        struct rockchip_vpu_ctx *ctx = vb2_get_drv_priv(q);
 
        if (!V4L2_TYPE_IS_OUTPUT(q->type))
-               dma_free_attrs(ctx->dev->dev,
-                              ctx->bounce_size,
-                              ctx->bounce_buf,
-                              ctx->bounce_dma_addr,
-                              DMA_ATTR_ALLOC_SINGLE_PAGES);
+               if (ctx->codec_ops && ctx->codec_ops->exit)
+                       ctx->codec_ops->exit(ctx);
 
        /*
         * The mem2mem framework calls v4l2_m2m_cancel_job before