Received: by 2002:ac0:a874:0:0:0:0:0 with SMTP id c49csp603972ima; Fri, 15 Mar 2019 09:47:08 -0700 (PDT) X-Google-Smtp-Source: APXvYqzt5YxUUJMfyfBDBnCFU9xC1zqdcvDILN6MUW1DNqK5kmEkYSOAGffcEbrm/PahaCi6iD3t X-Received: by 2002:a65:63d9:: with SMTP id n25mr4377342pgv.243.1552668428566; Fri, 15 Mar 2019 09:47:08 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1552668428; cv=none; d=google.com; s=arc-20160816; b=eqMJLMd1e3MD4MpMDsC199E1gcdUfb6AkWg8Ic517NyN37tynrAYVZDmhirOuCGXgL sd8Y0KoqYlzyRm6ktLqYnyf8oI2J+SvFWUKPl3QhXk8oOwFT4ZhXZ0tDyRIVHHTQgWDR utDCAeWJpEpMyrDGYp0CVE5oRG28sVT4o335bYS2I2ZDaP0Z/pzk+gCDOIgQxXxqwNCt 4pEOBBtTCYTaJ5+mEi2dD98CbN6IzNn+dwOPYSxGoTZWn5V1MamWzpZg3ShLxpDtRgUP jAVeEhlh48WqnEq+S/cNB5L/4YqnzhqJ4tZlXUkQxFFzVXGfvwhUJntVE1Hv0jrbPnBK U3mw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=rO8S1b+oP9ClEkZF2TZMn9xWvb0FAawYEjIIxrj+pYk=; b=trKEOKBn9X3guPBJolH74gj2s3u8mYyD5hPtHvr+Oas86HVaE9NY0DRNeQBblcBcOf VLkjPlDT2oKawvOkkiJuerOrdsMBFJMvcAsU7jSjorMGmXE7xQhWRVmFKU3vCqF0rxWS 0TGn+9qnLnRiCkcMBUPTHH1nD8dU8Sqvbb5XvIPOZ0GqYyMqry7oCC5KzAkH7vksHSYR s6KoFPdB9eVWFy3LDjCJRp2e0RXOBdmFj33tqUBm+Wfd5ZDHn+uNyJsvlWDw9dbyC7Qh aBykeTrIYEVSY3z5Y8GHF/0Hy52+i6Ck9sL4zWT1+htLukKBgk3fw4uCeRiybcZYj6m3 FeEA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=collabora.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id f3si2163622pgq.206.2019.03.15.09.46.48; Fri, 15 Mar 2019 09:47:08 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=collabora.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729867AbfCOQpt (ORCPT + 99 others); Fri, 15 Mar 2019 12:45:49 -0400 Received: from bhuna.collabora.co.uk ([46.235.227.227]:49078 "EHLO bhuna.collabora.co.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729853AbfCOQpq (ORCPT ); Fri, 15 Mar 2019 12:45:46 -0400 Received: from [127.0.0.1] (localhost [127.0.0.1]) (Authenticated sender: tonyk) with ESMTPSA id EA100260215 From: =?UTF-8?q?Andr=C3=A9=20Almeida?= To: linux-media@vger.kernel.org Cc: mchehab@kernel.org, hverkuil@xs4all.nl, helen.koike@collabora.com, lucmaga@gmail.com, linux-kernel@vger.kernel.org, kernel@collabora.com Subject: [PATCH 14/16] media: vimc: sca: Add support for multiplanar formats Date: Fri, 15 Mar 2019 13:43:57 -0300 Message-Id: <20190315164359.626-15-andrealmeid@collabora.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190315164359.626-1-andrealmeid@collabora.com> References: <20190315164359.626-1-andrealmeid@collabora.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Change the scaling functions in order to scale planes. This change makes easier to support multiplanar pixel formats. Signed-off-by: André Almeida --- drivers/media/platform/vimc/vimc-scaler.c | 110 ++++++++++++++-------- 1 file changed, 69 insertions(+), 41 deletions(-) diff --git a/drivers/media/platform/vimc/vimc-scaler.c b/drivers/media/platform/vimc/vimc-scaler.c index 65519495ecca..15fbb0914056 100644 --- a/drivers/media/platform/vimc/vimc-scaler.c +++ b/drivers/media/platform/vimc/vimc-scaler.c @@ -35,10 +35,14 @@ MODULE_PARM_DESC(sca_mult, " the image size multiplier"); #define IS_SRC(pad) (pad) #define MAX_ZOOM 8 +/* TODO: enum only scalable formats */ static const u32 vimc_sca_supported_pixfmt[] = { V4L2_PIX_FMT_BGR24, V4L2_PIX_FMT_RGB24, V4L2_PIX_FMT_ARGB32, + V4L2_PIX_FMT_YUV420, + V4L2_PIX_FMT_YUV420M, + V4L2_PIX_FMT_NV12M, }; struct vimc_sca_device { @@ -51,8 +55,8 @@ struct vimc_sca_device { struct v4l2_mbus_framefmt sink_fmt; /* Values calculated when the stream starts */ struct vimc_frame src_frame; - unsigned int src_line_size; - unsigned int bpp; + unsigned int src_line_size[TPG_MAX_PLANES]; + unsigned int bpp[TPG_MAX_PLANES]; }; static const struct v4l2_mbus_framefmt sink_fmt_default = { @@ -207,10 +211,10 @@ static const struct v4l2_subdev_pad_ops vimc_sca_pad_ops = { static int vimc_sca_s_stream(struct v4l2_subdev *sd, int enable) { struct vimc_sca_device *vsca = v4l2_get_subdevdata(sd); + unsigned int i; if (enable) { u32 pixelformat = vsca->ved.stream->producer_pixfmt; - const struct v4l2_format_info *pix_info; unsigned int frame_size; if (!vimc_sca_is_pixfmt_supported(pixelformat)) { @@ -219,32 +223,41 @@ static int vimc_sca_s_stream(struct v4l2_subdev *sd, int enable) return -EINVAL; } - /* Save the bytes per pixel of the sink */ - pix_info = v4l2_format_info(pixelformat); - vsca->bpp = pix_info->bpp[0]; - - /* Calculate the width in bytes of the src frame */ - vsca->src_line_size = vsca->sink_fmt.width * - sca_mult * vsca->bpp; - - /* Calculate the frame size of the source pad */ - frame_size = vsca->src_line_size * vsca->sink_fmt.height * - sca_mult; - - /* Allocate the frame buffer. Use vmalloc to be able to - * allocate a large amount of memory - */ - vsca->src_frame.plane_addr[0] = vmalloc(frame_size); - vsca->src_frame.sizeimage[0] = frame_size; - if (!vsca->src_frame.plane_addr[0]) - return -ENOMEM; + vimc_fill_frame(&vsca->src_frame, pixelformat, + vsca->sink_fmt.width, vsca->sink_fmt.height); + + for (i = 0; i < vsca->src_frame.num_planes; i++) { + /* Save the bytes per pixel of the sink */ + vsca->bpp[i] = vsca->src_frame.bpp[i]; + + /* Calculate the width in bytes of the src frame */ + vsca->src_line_size[i] = + vsca->src_frame.bytesperline[i] * sca_mult; + + /* Calculate the frame size of the source pad */ + frame_size = vsca->src_frame.sizeimage[i] * + sca_mult * sca_mult; + + /* Allocate the frame buffer. Use vmalloc to be able to + * allocate a large amount of memory + */ + vsca->src_frame.plane_addr[i] = vmalloc(frame_size); + if (!vsca->src_frame.plane_addr[i]) { + for (i -= 1; i >= 0; i--) + vfree(vsca->src_frame.plane_addr[i]); + return -ENOMEM; + } + vsca->src_frame.sizeimage[i] = frame_size; + } } else { if (!vsca->src_frame.plane_addr[0]) return 0; - vfree(vsca->src_frame.plane_addr[0]); - vsca->src_frame.plane_addr[0] = NULL; + for (i = 0; i < vsca->src_frame.num_planes; i++) { + vfree(vsca->src_frame.plane_addr[i]); + vsca->src_frame.plane_addr[i] = NULL; + } } return 0; @@ -270,18 +283,19 @@ static void vimc_sca_fill_pix(u8 *const ptr, ptr[i] = pixel[i]; } -static void vimc_sca_scale_pix(const struct vimc_sca_device *const vsca, +/* TODO: parallelize this function */ +static void vimc_sca_scale_plane(const struct vimc_sca_device *const vsca, const unsigned int lin, const unsigned int col, - const u8 *const sink_frame) + const struct vimc_frame *sink_frame, + u8 num_plane, u32 width) + { unsigned int i, j, index; const u8 *pixel; /* Point to the pixel value in position (lin, col) in the sink frame */ - index = VIMC_FRAME_INDEX(lin, col, - vsca->sink_fmt.width, - vsca->bpp); - pixel = &sink_frame[index]; + index = VIMC_FRAME_INDEX(lin, col, width, vsca->bpp[num_plane]); + pixel = &sink_frame->plane_addr[num_plane][index]; dev_dbg(vsca->dev, "sca: %s: --- scale_pix sink pos %dx%d, index %d ---\n", @@ -291,7 +305,7 @@ static void vimc_sca_scale_pix(const struct vimc_sca_device *const vsca, * in the scaled src frame */ index = VIMC_FRAME_INDEX(lin * sca_mult, col * sca_mult, - vsca->sink_fmt.width * sca_mult, vsca->bpp); + width * sca_mult, vsca->bpp[num_plane]); dev_dbg(vsca->dev, "sca: %s: scale_pix src pos %dx%d, index %d\n", vsca->sd.name, lin * sca_mult, col * sca_mult, index); @@ -301,32 +315,46 @@ static void vimc_sca_scale_pix(const struct vimc_sca_device *const vsca, /* Iterate through each beginning of a * pixel repetition in a line */ - for (j = 0; j < sca_mult * vsca->bpp; j += vsca->bpp) { + unsigned int bpp = vsca->bpp[num_plane]; + + for (j = 0; j < sca_mult * bpp; j += bpp) { dev_dbg(vsca->dev, "sca: %s: sca: scale_pix src pos %d\n", vsca->sd.name, index + j); /* copy the pixel to the position index + j */ vimc_sca_fill_pix( - &vsca->src_frame.plane_addr[0][index + j], - pixel, vsca->bpp); + &vsca->src_frame.plane_addr[num_plane][index + j], + pixel, bpp); } /* move the index to the next line */ - index += vsca->src_line_size; + index += vsca->src_line_size[num_plane]; } } static void vimc_sca_fill_src_frame(const struct vimc_sca_device *const vsca, - const u8 *const sink_frame) + const struct vimc_frame *sink_frame) { - unsigned int i, j; + u32 i, j, width, height; + unsigned int num_plane; + const struct v4l2_format_info *info; + + info = v4l2_format_info(sink_frame->pixelformat); /* Scale each pixel from the original sink frame */ /* TODO: implement scale down, only scale up is supported for now */ - for (i = 0; i < vsca->sink_fmt.height; i++) - for (j = 0; j < vsca->sink_fmt.width; j++) - vimc_sca_scale_pix(vsca, i, j, sink_frame); + for (num_plane = 0; num_plane < info->comp_planes; num_plane++) { + width = vsca->sink_fmt.width / + ((num_plane == 0) ? 1 : info->vdiv); + height = vsca->sink_fmt.height / + ((num_plane == 0) ? 1 : info->hdiv); + + for (i = 0; i < height; i++) + for (j = 0; j < width; j++) + vimc_sca_scale_plane(vsca, i, j, sink_frame, + num_plane, width); + } } static struct vimc_frame *vimc_sca_process_frame(struct vimc_ent_device *ved, @@ -339,7 +367,7 @@ static struct vimc_frame *vimc_sca_process_frame(struct vimc_ent_device *ved, if (!ved->stream) return ERR_PTR(-EINVAL); - vimc_sca_fill_src_frame(vsca, sink_frame->plane_addr[0]); + vimc_sca_fill_src_frame(vsca, sink_frame); return &vsca->src_frame; }; -- 2.21.0