From patchwork Mon Jan 6 16:14:17 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2518 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 6212A60463 for ; Mon, 6 Jan 2020 17:14:32 +0100 (CET) Received: from pendragon.bb.dnainternet.fi (81-175-216-236.bb.dnainternet.fi [81.175.216.236]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id F3DC252F; Mon, 6 Jan 2020 17:14:31 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1578327272; bh=GuyLiI0Bdoy/6G7Asr8JP9/Nb+Pf5u1HOl6PW4PJQLc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=D94CvEoyp6GTuHo/MD9ymYXyDRwfgL+UdOX7QXshepfBZHo8wnswpHuxFbIXfbshF e2xS61/cxwzawVvtuOR4oYh3rkGkx/oDkBRdQ4Akg9/Ol+ohAUDWjvx8irFvOMwDSF duq8MSzWBx584o0oi90ajSdinMqrHbW+wcujouXY= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Mon, 6 Jan 2020 18:14:17 +0200 Message-Id: <20200106161417.19150-5-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200106161417.19150-1-laurent.pinchart@ideasonboard.com> References: <20200106161417.19150-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 4/4] v4l2: camera_proxy: Create format info array X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 06 Jan 2020 16:14:32 -0000 Create a PixelFormatInfo structure to store information about a format, and add a global array of format info for all the formats currently supported. Move the format helpers to use the information from the array. Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham Reviewed-by: Jacopo Mondi --- src/v4l2/v4l2_camera_proxy.cpp | 180 +++++++++++++-------------------- 1 file changed, 70 insertions(+), 110 deletions(-) diff --git a/src/v4l2/v4l2_camera_proxy.cpp b/src/v4l2/v4l2_camera_proxy.cpp index 6a222d702e13..b8c1a53af1c2 100644 --- a/src/v4l2/v4l2_camera_proxy.cpp +++ b/src/v4l2/v4l2_camera_proxy.cpp @@ -509,134 +509,94 @@ int V4L2CameraProxy::ioctl(unsigned long request, void *arg) return ret; } +struct PixelFormatPlaneInfo { + unsigned int bitsPerPixel; + unsigned int hSubSampling; + unsigned int vSubSampling; +}; + +struct PixelFormatInfo { + PixelFormat format; + uint32_t v4l2Format; + unsigned int numPlanes; + std::array planes; +}; + +namespace { + +constexpr std::array pixelFormatInfo = {{ + /* RGB formats. */ + { DRM_FORMAT_RGB888, V4L2_PIX_FMT_BGR24, 1, {{ { 24, 1, 1 }, { 0, 0, 0 }, { 0, 0, 0 } }} }, + { DRM_FORMAT_BGR888, V4L2_PIX_FMT_RGB24, 1, {{ { 24, 1, 1 }, { 0, 0, 0 }, { 0, 0, 0 } }} }, + { DRM_FORMAT_BGRA8888, V4L2_PIX_FMT_ARGB32, 1, {{ { 32, 1, 1 }, { 0, 0, 0 }, { 0, 0, 0 } }} }, + /* YUV packed formats. */ + { DRM_FORMAT_UYVY, V4L2_PIX_FMT_UYVY, 1, {{ { 16, 1, 1 }, { 0, 0, 0 }, { 0, 0, 0 } }} }, + { DRM_FORMAT_VYUY, V4L2_PIX_FMT_VYUY, 1, {{ { 16, 1, 1 }, { 0, 0, 0 }, { 0, 0, 0 } }} }, + { DRM_FORMAT_YUYV, V4L2_PIX_FMT_YUYV, 1, {{ { 16, 1, 1 }, { 0, 0, 0 }, { 0, 0, 0 } }} }, + { DRM_FORMAT_YVYU, V4L2_PIX_FMT_YVYU, 1, {{ { 16, 1, 1 }, { 0, 0, 0 }, { 0, 0, 0 } }} }, + /* YUY planar formats. */ + { DRM_FORMAT_NV12, V4L2_PIX_FMT_NV12, 2, {{ { 8, 1, 1 }, { 16, 2, 2 }, { 0, 0, 0 } }} }, + { DRM_FORMAT_NV21, V4L2_PIX_FMT_NV21, 2, {{ { 8, 1, 1 }, { 16, 2, 2 }, { 0, 0, 0 } }} }, + { DRM_FORMAT_NV16, V4L2_PIX_FMT_NV16, 2, {{ { 8, 1, 1 }, { 16, 2, 1 }, { 0, 0, 0 } }} }, + { DRM_FORMAT_NV61, V4L2_PIX_FMT_NV61, 2, {{ { 8, 1, 1 }, { 16, 2, 1 }, { 0, 0, 0 } }} }, + { DRM_FORMAT_NV24, V4L2_PIX_FMT_NV24, 2, {{ { 8, 1, 1 }, { 16, 2, 1 }, { 0, 0, 0 } }} }, + { DRM_FORMAT_NV42, V4L2_PIX_FMT_NV42, 2, {{ { 8, 1, 1 }, { 16, 1, 1 }, { 0, 0, 0 } }} }, +}}; + +} /* namespace */ + /* \todo make libcamera export these */ unsigned int V4L2CameraProxy::bplMultiplier(uint32_t format) { - switch (format) { - case V4L2_PIX_FMT_NV12: - case V4L2_PIX_FMT_NV21: - case V4L2_PIX_FMT_NV16: - case V4L2_PIX_FMT_NV61: - case V4L2_PIX_FMT_NV24: - case V4L2_PIX_FMT_NV42: - return 1; - case V4L2_PIX_FMT_BGR24: - case V4L2_PIX_FMT_RGB24: - return 3; - case V4L2_PIX_FMT_ARGB32: - return 4; - case V4L2_PIX_FMT_VYUY: - case V4L2_PIX_FMT_YVYU: - case V4L2_PIX_FMT_UYVY: - case V4L2_PIX_FMT_YUYV: - return 2; - default: + auto info = std::find_if(pixelFormatInfo.begin(), pixelFormatInfo.end(), + [format](const PixelFormatInfo &info) { + return info.v4l2Format == format; + }); + if (info == pixelFormatInfo.end()) return 0; - }; + + return info->planes[0].bitsPerPixel / 8; } unsigned int V4L2CameraProxy::imageSize(uint32_t format, unsigned int width, unsigned int height) { - switch (format) { - case V4L2_PIX_FMT_NV12: - case V4L2_PIX_FMT_NV21: - return width * height * 3 / 2; - case V4L2_PIX_FMT_NV16: - case V4L2_PIX_FMT_NV61: - return width * height * 2; - case V4L2_PIX_FMT_NV24: - case V4L2_PIX_FMT_NV42: - return width * height * 3; - case V4L2_PIX_FMT_BGR24: - case V4L2_PIX_FMT_RGB24: - return width * height * 3; - case V4L2_PIX_FMT_ARGB32: - return width * height * 4; - case V4L2_PIX_FMT_VYUY: - case V4L2_PIX_FMT_YVYU: - case V4L2_PIX_FMT_UYVY: - case V4L2_PIX_FMT_YUYV: - return width * height * 2; - default: + auto info = std::find_if(pixelFormatInfo.begin(), pixelFormatInfo.end(), + [format](const PixelFormatInfo &info) { + return info.v4l2Format == format; + }); + if (info == pixelFormatInfo.end()) return 0; - }; + + unsigned int multiplier = 0; + for (unsigned int i = 0; i < info->numPlanes; ++i) + multiplier += info->planes[i].bitsPerPixel + / info->planes[i].hSubSampling + / info->planes[i].vSubSampling; + + return width * height * multiplier / 8; } PixelFormat V4L2CameraProxy::v4l2ToDrm(uint32_t format) { - switch (format) { - /* RGB formats. */ - case V4L2_PIX_FMT_RGB24: - return DRM_FORMAT_BGR888; - case V4L2_PIX_FMT_BGR24: - return DRM_FORMAT_RGB888; - case V4L2_PIX_FMT_ARGB32: - return DRM_FORMAT_BGRA8888; - - /* YUV packed formats. */ - case V4L2_PIX_FMT_YUYV: - return DRM_FORMAT_YUYV; - case V4L2_PIX_FMT_YVYU: - return DRM_FORMAT_YVYU; - case V4L2_PIX_FMT_UYVY: - return DRM_FORMAT_UYVY; - case V4L2_PIX_FMT_VYUY: - return DRM_FORMAT_VYUY; - - /* YUY planar formats. */ - case V4L2_PIX_FMT_NV16: - return DRM_FORMAT_NV16; - case V4L2_PIX_FMT_NV61: - return DRM_FORMAT_NV61; - case V4L2_PIX_FMT_NV12: - return DRM_FORMAT_NV12; - case V4L2_PIX_FMT_NV21: - return DRM_FORMAT_NV21; - case V4L2_PIX_FMT_NV24: - return DRM_FORMAT_NV24; - case V4L2_PIX_FMT_NV42: - return DRM_FORMAT_NV42; - default: + auto info = std::find_if(pixelFormatInfo.begin(), pixelFormatInfo.end(), + [format](const PixelFormatInfo &info) { + return info.v4l2Format == format; + }); + if (info == pixelFormatInfo.end()) return format; - }; + + return info->format; } uint32_t V4L2CameraProxy::drmToV4L2(PixelFormat format) { - switch (format) { - /* RGB formats. */ - case DRM_FORMAT_BGR888: - return V4L2_PIX_FMT_RGB24; - case DRM_FORMAT_RGB888: - return V4L2_PIX_FMT_BGR24; - case DRM_FORMAT_BGRA8888: - return V4L2_PIX_FMT_ARGB32; - - /* YUV packed formats. */ - case DRM_FORMAT_YUYV: - return V4L2_PIX_FMT_YUYV; - case DRM_FORMAT_YVYU: - return V4L2_PIX_FMT_YVYU; - case DRM_FORMAT_UYVY: - return V4L2_PIX_FMT_UYVY; - case DRM_FORMAT_VYUY: - return V4L2_PIX_FMT_VYUY; - - /* YUY planar formats. */ - case DRM_FORMAT_NV16: - return V4L2_PIX_FMT_NV16; - case DRM_FORMAT_NV61: - return V4L2_PIX_FMT_NV61; - case DRM_FORMAT_NV12: - return V4L2_PIX_FMT_NV12; - case DRM_FORMAT_NV21: - return V4L2_PIX_FMT_NV21; - case DRM_FORMAT_NV24: - return V4L2_PIX_FMT_NV24; - case DRM_FORMAT_NV42: - return V4L2_PIX_FMT_NV42; - default: + auto info = std::find_if(pixelFormatInfo.begin(), pixelFormatInfo.end(), + [format](const PixelFormatInfo &info) { + return info.format == format; + }); + if (info == pixelFormatInfo.end()) return format; - } + + return info->v4l2Format; }