Add Rockchip VPU JPEG encoder
Subsystems (3)
v2 cover Add Rockchip VPU JPEG encoder
This series adds support for JPEG encoding via the VPU block present in Rockchip platforms. Currently, support for RK3288 and RK3399 is included.
The hardware produces a Raw JPEG format (i.e. works as a JPEG accelerator). It requires quantization tables provided by the application, and uses standard huffman tables, as recommended by the JPEG specification.
In order to support this, the series introduces a new pixel format, and a new pair of controls, V4L2_CID_JPEG_{LUMA,CHROMA}_QUANTIZATION allowing userspace to specify the quantization tables.
Userspace is then responsible to add the required headers and tables to the produced raw payload, to produce a JPEG image.
Compliance
==========
# v4l2-compliance -d 0 -s
Ezequiel Garcia (1):
media: add Rockchip VPU driver
Shunqian Zheng (2):
media: Add JPEG_RAW format
media: Add controls for jpeg quantization tables
.../media/uapi/v4l/pixfmt-compressed.rst | 5 + drivers/media/platform/Kconfig | 12 + drivers/media/platform/Makefile | 1 + drivers/media/platform/rockchip/vpu/Makefile | 8 + .../platform/rockchip/vpu/rk3288_vpu_hw.c | 127 +++ .../rockchip/vpu/rk3288_vpu_hw_jpege.c | 156 ++++ .../platform/rockchip/vpu/rk3288_vpu_regs.h | 442 ++++++++++ .../platform/rockchip/vpu/rk3399_vpu_hw.c | 127 +++ .../rockchip/vpu/rk3399_vpu_hw_jpege.c | 165 ++++ .../platform/rockchip/vpu/rk3399_vpu_regs.h | 601 ++++++++++++++ .../platform/rockchip/vpu/rockchip_vpu.h | 270 +++++++ .../platform/rockchip/vpu/rockchip_vpu_drv.c | 416 ++++++++++ .../platform/rockchip/vpu/rockchip_vpu_enc.c | 763 ++++++++++++++++++ .../platform/rockchip/vpu/rockchip_vpu_enc.h | 25 + .../platform/rockchip/vpu/rockchip_vpu_hw.h | 67 ++ drivers/media/v4l2-core/v4l2-ctrls.c | 4 + drivers/media/v4l2-core/v4l2-ioctl.c | 1 + include/uapi/linux/v4l2-controls.h | 3 + include/uapi/linux/videodev2.h | 1 + 19 files changed, 3194 insertions(+) create mode 100644 drivers/media/platform/rockchip/vpu/Makefile create mode 100644 drivers/media/platform/rockchip/vpu/rk3288_vpu_hw.c create mode 100644 drivers/media/platform/rockchip/vpu/rk3288_vpu_hw_jpege.c create mode 100644 drivers/media/platform/rockchip/vpu/rk3288_vpu_regs.h create mode 100644 drivers/media/platform/rockchip/vpu/rk3399_vpu_hw.c create mode 100644 drivers/media/platform/rockchip/vpu/rk3399_vpu_hw_jpege.c create mode 100644 drivers/media/platform/rockchip/vpu/rk3399_vpu_regs.h create mode 100644 drivers/media/platform/rockchip/vpu/rockchip_vpu.h create mode 100644 drivers/media/platform/rockchip/vpu/rockchip_vpu_drv.c create mode 100644 drivers/media/platform/rockchip/vpu/rockchip_vpu_enc.c create mode 100644 drivers/media/platform/rockchip/vpu/rockchip_vpu_enc.h create mode 100644 drivers/media/platform/rockchip/vpu/rockchip_vpu_hw.h
Signature · 1 line
2.18.0.rc2
PATCH v2 1/3 media: Add JPEG_RAW format
From: Shunqian Zheng <[email protected]>
Add V4L2_PIX_FMT_JPEG_RAW format that does not contain JPEG header in the output frame.
--- Documentation/media/uapi/v4l/pixfmt-compressed.rst | 5 +++++ drivers/media/v4l2-core/v4l2-ioctl.c | 1 + include/uapi/linux/videodev2.h | 1 + 3 files changed, 7 insertions(+)
Documentation/media/uapi/v4l/pixfmt-compressed.rst +5 -0
@@ -23,6 +23,11 @@ Compressed Formats - 'JPEG' - TBD. See also :ref:`VIDIOC_G_JPEGCOMP <VIDIOC_G_JPEGCOMP>`, :ref:`VIDIOC_S_JPEGCOMP <VIDIOC_G_JPEGCOMP>`. + * .. _V4L2-PIX-FMT-JPEG-RAW: + + - ``V4L2_PIX_FMT_JPEG_RAW`` + - 'Raw JPEG' + - JPEG without any headers. * .. _V4L2-PIX-FMT-MPEG: - ``V4L2_PIX_FMT_MPEG``
drivers/media/v4l2-core/v4l2-ioctl.c +1 -0
@@ -1259,6 +1259,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)/* Max description length mask: descr = "0123456789012345678901234567890" */ case V4L2_PIX_FMT_MJPEG : descr ="Motion-JPEG" ;break ;case V4L2_PIX_FMT_JPEG : descr ="JFIF JPEG" ;break ; +case V4L2_PIX_FMT_JPEG_RAW : descr ="Raw JPEG" ;break ;case V4L2_PIX_FMT_DV : descr ="1394" ;break ;case V4L2_PIX_FMT_MPEG : descr ="MPEG-1/2/4" ;break ;case V4L2_PIX_FMT_H264 : descr ="H.264" ;break ;
include/uapi/linux/videodev2.h +1 -0
@@ -621,6 +621,7 @@ struct v4l2_pix_format {/* compressed formats */ #define V4L2_PIX_FMT_MJPEG v4l2_fourcc('M', 'J', 'P', 'G')/* Motion-JPEG */ #define V4L2_PIX_FMT_JPEG v4l2_fourcc('J', 'P', 'E', 'G')/* JFIF JPEG */ +#define V4L2_PIX_FMT_JPEG_RAW v4l2_fourcc('J', 'P', 'G', 'R')/* JFIF JPEG RAW without headers */ #define V4L2_PIX_FMT_DV v4l2_fourcc('d', 'v', 's', 'd')/* 1394 */ #define V4L2_PIX_FMT_MPEG v4l2_fourcc('M', 'P', 'E', 'G')/* MPEG-1/2/4 Multiplexed */ #define V4L2_PIX_FMT_H264 v4l2_fourcc('H', '2', '6', '4')/* H264 with start codes */
Signature · 1 line
2.18.0.rc2
PATCH v2 2/3 media: Add controls for jpeg quantization tables
In reply to Ezequiel GarciaFrom: Shunqian Zheng <[email protected]>
Add V4L2_CID_JPEG_LUMA/CHROMA_QUANTIZATION controls to allow userspace configure the JPEG quantization tables.
--- drivers/media/v4l2-core/v4l2-ctrls.c | 4 ++++ include/uapi/linux/v4l2-controls.h | 3 +++ 2 files changed, 7 insertions(+)
drivers/media/v4l2-core/v4l2-ctrls.c +4 -0
@@ -980,6 +980,8 @@ const char *v4l2_ctrl_get_name(u32 id)case V4L2_CID_JPEG_RESTART_INTERVAL :return "Restart Interval" ;case V4L2_CID_JPEG_COMPRESSION_QUALITY :return "Compression Quality" ;case V4L2_CID_JPEG_ACTIVE_MARKER :return "Active Markers" ; +case V4L2_CID_JPEG_LUMA_QUANTIZATION :return "Luminance Quantization Matrix" ; +case V4L2_CID_JPEG_CHROMA_QUANTIZATION :return "Chrominance Quantization Matrix" ;/* Image source controls */ /* Keep the order of the 'case's the same as in v4l2-controls.h! */
@@ -1263,6 +1265,8 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type, *flags |=V4L2_CTRL_FLAG_READ_ONLY ;break ;case V4L2_CID_DETECT_MD_REGION_GRID : +case V4L2_CID_JPEG_LUMA_QUANTIZATION : +case V4L2_CID_JPEG_CHROMA_QUANTIZATION : *type =V4L2_CTRL_TYPE_U8 ;break ;case V4L2_CID_DETECT_MD_THRESHOLD_GRID :
include/uapi/linux/v4l2-controls.h +3 -0
@@ -971,6 +971,9 @@ enum v4l2_jpeg_chroma_subsampling {#define V4L2_JPEG_ACTIVE_MARKER_DQT (1 << 17)#define V4L2_JPEG_ACTIVE_MARKER_DHT (1 << 18) +#define V4L2_CID_JPEG_LUMA_QUANTIZATION (V4L2_CID_JPEG_CLASS_BASE + 5) +#define V4L2_CID_JPEG_CHROMA_QUANTIZATION (V4L2_CID_JPEG_CLASS_BASE + 6) +/* Image source controls */ #define V4L2_CID_IMAGE_SOURCE_CLASS_BASE (V4L2_CTRL_CLASS_IMAGE_SOURCE | 0x900)
Signature · 1 line
2.18.0.rc2
PATCH v2 3/3 media: add Rockchip VPU driver
In reply to Ezequiel GarciaAdd a mem2mem driver for the VPU available on Rockchip SoCs. Currently only JPEG encoding is supported, for RK3399 and RK3288 platforms.
--- drivers/media/platform/Kconfig | 12 + drivers/media/platform/Makefile | 1 + drivers/media/platform/rockchip/vpu/Makefile | 8 + .../platform/rockchip/vpu/rk3288_vpu_hw.c | 127 +++ .../rockchip/vpu/rk3288_vpu_hw_jpege.c | 156 ++++ .../platform/rockchip/vpu/rk3288_vpu_regs.h | 442 ++++++++++ .../platform/rockchip/vpu/rk3399_vpu_hw.c | 127 +++ .../rockchip/vpu/rk3399_vpu_hw_jpege.c | 165 ++++ .../platform/rockchip/vpu/rk3399_vpu_regs.h | 601 ++++++++++++++ .../platform/rockchip/vpu/rockchip_vpu.h | 270 +++++++ .../platform/rockchip/vpu/rockchip_vpu_drv.c | 416 ++++++++++ .../platform/rockchip/vpu/rockchip_vpu_enc.c | 763 ++++++++++++++++++ .../platform/rockchip/vpu/rockchip_vpu_enc.h | 25 + .../platform/rockchip/vpu/rockchip_vpu_hw.h | 67 ++ 14 files changed, 3180 insertions(+) create mode 100644 drivers/media/platform/rockchip/vpu/Makefile create mode 100644 drivers/media/platform/rockchip/vpu/rk3288_vpu_hw.c create mode 100644 drivers/media/platform/rockchip/vpu/rk3288_vpu_hw_jpege.c create mode 100644 drivers/media/platform/rockchip/vpu/rk3288_vpu_regs.h create mode 100644 drivers/media/platform/rockchip/vpu/rk3399_vpu_hw.c create mode 100644 drivers/media/platform/rockchip/vpu/rk3399_vpu_hw_jpege.c create mode 100644 drivers/media/platform/rockchip/vpu/rk3399_vpu_regs.h create mode 100644 drivers/media/platform/rockchip/vpu/rockchip_vpu.h create mode 100644 drivers/media/platform/rockchip/vpu/rockchip_vpu_drv.c create mode 100644 drivers/media/platform/rockchip/vpu/rockchip_vpu_enc.c create mode 100644 drivers/media/platform/rockchip/vpu/rockchip_vpu_enc.h create mode 100644 drivers/media/platform/rockchip/vpu/rockchip_vpu_hw.h
drivers/media/platform/Kconfig +12 -0
@@ -448,6 +448,18 @@ config VIDEO_ROCKCHIP_RGA To compile this driver as a module choose m here. +config VIDEO_ROCKCHIP_VPU + tristate "Rockchip VPU driver" + depends on VIDEO_DEV && VIDEO_V4L2 + depends on ARCH_ROCKCHIP || COMPILE_TEST + select VIDEOBUF2_DMA_CONTIG + select V4L2_MEM2MEM_DEV + default n + ---help--- + Support for the VPU video codec found on Rockchip SoC. + To compile this driver as a module, choose M here: the module + will be called rockchip-vpu. + config VIDEO_TI_VPE tristate "TI VPE (Video Processing Engine) driver" depends on VIDEO_DEV && VIDEO_V4L2
drivers/media/platform/Makefile +1 -0
@@ -66,6 +66,7 @@ obj-$(CONFIG_VIDEO_RENESAS_JPU) += rcar_jpu.o obj-$(CONFIG_VIDEO_RENESAS_VSP1) += vsp1/ obj-$(CONFIG_VIDEO_ROCKCHIP_RGA) += rockchip/rga/ +obj-$(CONFIG_VIDEO_ROCKCHIP_VPU) += rockchip/vpu/ obj-y += omap/
drivers/media/platform/rockchip/vpu/Makefile new file +8 -0
@@ -0,0 +1,8 @@ +obj-$(CONFIG_VIDEO_ROCKCHIP_VPU) += rockchip-vpu.o + +rockchip-vpu-y += rockchip_vpu_drv.o \ + rockchip_vpu_enc.o \ + rk3288_vpu_hw.o \ + rk3288_vpu_hw_jpege.o \ + rk3399_vpu_hw.o \ + rk3399_vpu_hw_jpege.o
drivers/media/platform/rockchip/vpu/rk3288_vpu_hw.c new file +127 -0
127 lines not on this page · raw message
drivers/media/platform/rockchip/vpu/rk3288_vpu_hw_jpege.c new file +156 -0
156 lines not on this page · raw message
drivers/media/platform/rockchip/vpu/rk3288_vpu_regs.h new file +442 -0
442 lines not on this page · raw message
drivers/media/platform/rockchip/vpu/rk3399_vpu_hw.c new file +127 -0
127 lines not on this page · raw message
drivers/media/platform/rockchip/vpu/rk3399_vpu_hw_jpege.c new file +165 -0
165 lines not on this page · raw message
drivers/media/platform/rockchip/vpu/rk3399_vpu_regs.h new file +601 -0
601 lines not on this page · raw message
drivers/media/platform/rockchip/vpu/rockchip_vpu.h new file +270 -0
270 lines not on this page · raw message
drivers/media/platform/rockchip/vpu/rockchip_vpu_drv.c new file +416 -0
416 lines not on this page · raw message
drivers/media/platform/rockchip/vpu/rockchip_vpu_enc.c new file +763 -0
663 lines not on this page · raw message
drivers/media/platform/rockchip/vpu/rockchip_vpu_enc.h new file +25 -0
Lines of this file are not shown. View the raw message.
drivers/media/platform/rockchip/vpu/rockchip_vpu_hw.h new file +67 -0
67 lines not on this page · raw message
The rest of this diff is not shown. View the raw message.
Signature · 1 line
2.18.0.rc2
Part of the diff is not shown here. View the raw message.
Re: [PATCH 3/3] media: add Rockchip VPU driver
Quoted 5 lines · Ezequiel Garcia
Add a mem2mem driver for the VPU available on Rockchip SoCs. Currently only JPEG encoding is supported, for RK3399 and RK3288 platforms.
Signed-off-by Ezequiel Garcia <ezequiel-ZGY8ohtN/[email protected]>
Quoted 15 lines
--- drivers/media/platform/Kconfig | 12 + drivers/media/platform/Makefile | 1 + drivers/media/platform/rockchip/vpu/Makefile | 8 + .../platform/rockchip/vpu/rk3288_vpu_hw.c | 127 +++ .../rockchip/vpu/rk3288_vpu_hw_jpege.c | 156 ++++ .../platform/rockchip/vpu/rk3288_vpu_regs.h | 442 ++++++++++ .../platform/rockchip/vpu/rk3399_vpu_hw.c | 127 +++ .../rockchip/vpu/rk3399_vpu_hw_jpege.c | 165 ++++ .../platform/rockchip/vpu/rk3399_vpu_regs.h | 601 ++++++++++++++ .../platform/rockchip/vpu/rockchip_vpu.h | 270 +++++++ .../platform/rockchip/vpu/rockchip_vpu_drv.c | 416 ++++++++++ .../platform/rockchip/vpu/rockchip_vpu_enc.c | 763 ++++++++++++++++++ .../platform/rockchip/vpu/rockchip_vpu_enc.h | 25 + .../platform/rockchip/vpu/rockchip_vpu_hw.h | 67 ++
There is no update for the MAINTAINERS file, please add an entry there.
Quoted 82 lines
14 files changed, 3180 insertions(+) create mode 100644 drivers/media/platform/rockchip/vpu/Makefile create mode 100644 drivers/media/platform/rockchip/vpu/rk3288_vpu_hw.c create mode 100644 drivers/media/platform/rockchip/vpu/rk3288_vpu_hw_jpege.c create mode 100644 drivers/media/platform/rockchip/vpu/rk3288_vpu_regs.h create mode 100644 drivers/media/platform/rockchip/vpu/rk3399_vpu_hw.c create mode 100644 drivers/media/platform/rockchip/vpu/rk3399_vpu_hw_jpege.c create mode 100644 drivers/media/platform/rockchip/vpu/rk3399_vpu_regs.h create mode 100644 drivers/media/platform/rockchip/vpu/rockchip_vpu.h create mode 100644 drivers/media/platform/rockchip/vpu/rockchip_vpu_drv.c create mode 100644 drivers/media/platform/rockchip/vpu/rockchip_vpu_enc.c create mode 100644 drivers/media/platform/rockchip/vpu/rockchip_vpu_enc.h create mode 100644 drivers/media/platform/rockchip/vpu/rockchip_vpu_hw.hdrivers/media/platform/Kconfig +12
-0@@ -448,6 +448,18 @@ config VIDEO_ROCKCHIP_RGA To compile this driver as a module choose m here. +config VIDEO_ROCKCHIP_VPU + tristate "Rockchip VPU driver" + depends on VIDEO_DEV && VIDEO_V4L2 + depends on ARCH_ROCKCHIP || COMPILE_TEST + select VIDEOBUF2_DMA_CONTIG + select V4L2_MEM2MEM_DEV + default n + ---help--- + Support for the VPU video codec found on Rockchip SoC. + To compile this driver as a module, choose M here: the module + will be called rockchip-vpu. + config VIDEO_TI_VPE tristate "TI VPE (Video Processing Engine) driver" depends on VIDEO_DEV && VIDEO_V4L2drivers/media/platform/Makefile +1
-0@@ -66,6 +66,7 @@ obj-$(CONFIG_VIDEO_RENESAS_JPU) += rcar_jpu.o obj-$(CONFIG_VIDEO_RENESAS_VSP1) += vsp1/ obj-$(CONFIG_VIDEO_ROCKCHIP_RGA) += rockchip/rga/ +obj-$(CONFIG_VIDEO_ROCKCHIP_VPU) += rockchip/vpu/ obj-y += omap/drivers/media/platform/rockchip/vpu/Makefile new file +8
-0@@ -0,0 +1,8 @@ +obj-$(CONFIG_VIDEO_ROCKCHIP_VPU) += rockchip-vpu.o + +rockchip-vpu-y += rockchip_vpu_drv.o \ + rockchip_vpu_enc.o \ + rk3288_vpu_hw.o \ + rk3288_vpu_hw_jpege.o \ + rk3399_vpu_hw.o \ + rk3399_vpu_hw_jpege.odrivers/media/platform/rockchip/vpu/rk3288_vpu_hw.c new file +13
-0@@ -0,0 +1,127 @@ +// SPDX-License-Identifier: GPL-2.0 +/* +* Rockchip VPU codec driver +* +* Copyright (C) 2018 Rockchip Electronics Co., Ltd. +* Jeffy Chen <[email protected]> +*/ + +#include <linux/clk.h> + +#include "rockchip_vpu.h" +#include "rk3288_vpu_regs.h" +
drivers/media/platform/rockchip/vpu/rk3288_vpu_hw.c line 23
Quoted 10 lines
drivers/media/platform/rockchip/vpu/rk3288_vpu_hw.c new file +10
-0+#define RK3288_ACLK_MAX_FREQ (400 * 1000 * 1000) + +/* +* Supported formats. +*/ + +static const struct rockchip_vpu_fmt rk3288_vpu_enc_fmts[] = { +/* Source formats. */ + { + .name ="4:2:0 3 planes Y/Cb/Cr" ,
Please drop the name field. This is filled in by v4l2-ioctl.c in its enum_fmt implementation.
Quoted 46 lines
drivers/media/platform/rockchip/vpu/rk3288_vpu_hw.c new file +46
-0+ .fourcc = V4L2_PIX_FMT_YUV420M, + .codec_mode = RK_VPU_CODEC_NONE, + .num_planes = 3, + .depth = { 8, 4, 4 }, + .enc_fmt = RK3288_VPU_ENC_FMT_YUV420P, + }, + { + .name ="4:2:0 2 plane Y/CbCr" , + .fourcc = V4L2_PIX_FMT_NV12M, + .codec_mode = RK_VPU_CODEC_NONE, + .num_planes = 2, + .depth = { 8, 8 }, + .enc_fmt = RK3288_VPU_ENC_FMT_YUV420SP, + }, + { + .name ="4:2:2 1 plane YUYV" , + .fourcc = V4L2_PIX_FMT_YUYV, + .codec_mode = RK_VPU_CODEC_NONE, + .num_planes = 1, + .depth = { 16 }, + .enc_fmt = RK3288_VPU_ENC_FMT_YUYV422, + }, + { + .name ="4:2:2 1 plane UYVY" , + .fourcc = V4L2_PIX_FMT_UYVY, + .codec_mode = RK_VPU_CODEC_NONE, + .num_planes = 1, + .depth = { 16 }, + .enc_fmt = RK3288_VPU_ENC_FMT_UYVY422, + }, + /* Destination formats. */ + { + .name ="JPEG Encoded Stream" , + .fourcc = V4L2_PIX_FMT_JPEG_RAW, + .codec_mode = RK_VPU_CODEC_JPEGE, + .num_planes = 1, + .frmsize = { + .min_width =96 , + .max_width = 8192, + .step_width = MB_DIM, + .min_height = 32, + .max_height = 8192, + .step_height = MB_DIM, + }, + }, +};
<snip>
Quoted 95 lines
drivers/media/platform/rockchip/vpu/rockchip_vpu_enc.c new file +89
-0@@ -0,0 +1,763 @@ +// SPDX-License-Identifier: GPL-2.0 +/* +* Rockchip VPU codec driver +* +* Copyright (C) 2018 Collabora, Ltd. +* Copyright (C) 2018 Rockchip Electronics Co., Ltd. +* Alpha Lin <[email protected]> +* Jeffy Chen <[email protected]> +* +* Copyright (C) 2018 Google, Inc. +* Tomasz Figa <[email protected]> +* +* Based on s5p-mfc driver by Samsung Electronics Co., Ltd. +* Copyright (C) 2010-2011 Samsung Electronics Co., Ltd. +*/ + +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/pm_runtime.h> +#include <linux/videodev2.h> +#include <linux/workqueue.h> +#include <media/v4l2-ctrls.h> +#include <media/v4l2-event.h> +#include <media/v4l2-mem2mem.h> +#include <media/videobuf2-core.h> +#include <media/videobuf2-dma-sg.h> + +#include "rockchip_vpu.h" +#include "rockchip_vpu_enc.h" +#include "rockchip_vpu_hw.h" + +#define JPEG_MAX_BYTES_PER_PIXEL 2 + +static const struct rockchip_vpu_fmt * +rockchip_vpu_find_format (struct rockchip_vpu_dev *dev,u32 fourcc) +{ +const struct rockchip_vpu_fmt *formats = dev->variant->enc_fmts; +unsigned int i; + +for (i =0 ; i < dev->variant->num_enc_fmts; i++) { +if (formats[i].fourcc == fourcc) +return &formats[i]; + } + +return NULL ; +} + +static const struct rockchip_vpu_fmt * +rockchip_vpu_get_default_fmt (struct rockchip_vpu_dev *dev,bool bitstream) +{ +const struct rockchip_vpu_fmt *formats = dev->variant->enc_fmts; +unsigned int i; + +for (i =0 ; i < dev->variant->num_enc_fmts; i++) { +if (bitstream == (formats[i].codec_mode !=RK_VPU_CODEC_NONE )) +return &formats[i]; + } + +/* There must be at least one raw and one coded format in the array. */ +BUG_ON (i >= dev->variant->num_enc_fmts); +return NULL ; +} + +static const struct v4l2_ctrl_config controls[] = { + [ROCKCHIP_VPU_ENC_CTRL_Y_QUANT_TBL ] = { + .id =V4L2_CID_JPEG_LUMA_QUANTIZATION , + .type =V4L2_CTRL_TYPE_U8 , + .step =1 , + .def =0x00 , + .min =0x00 , + .max =0xff , + .dims = {8 ,8 } + }, + [ROCKCHIP_VPU_ENC_CTRL_C_QUANT_TBL ] = { + .id =V4L2_CID_JPEG_CHROMA_QUANTIZATION , + .type =V4L2_CTRL_TYPE_U8 , + .step =1 , + .def =0x00 , + .min =0x00 , + .max =0xff , + .dims = {8 ,8 } + }, +}; + +static int vidioc_querycap (struct file *file,void *priv, +struct v4l2_capability *cap) +{ +struct rockchip_vpu_dev *vpu =video_drvdata (file);
drivers/media/platform/rockchip/vpu/rockchip_vpu_enc.c line 99
Quoted 10 lines
drivers/media/platform/rockchip/vpu/rockchip_vpu_enc.c new file +10
-0+ +strlcpy (cap->driver, vpu->dev->driver->name,sizeof (cap->driver)); +strlcpy (cap->card, vpu->vfd->name,sizeof (cap->card)); +snprintf (cap->bus_info,sizeof (cap->bus_info),"platform: %s" , + vpu->dev->driver->name); + +/* +* This is only a mem-to-mem video device. +*/ + cap->device_caps =V4L2_CAP_VIDEO_M2M_MPLANE |V4L2_CAP_STREAMING ;
Just set device_caps in struct video_device and you can drop this and the next line from this function.
Quoted 40 lines
drivers/media/platform/rockchip/vpu/rockchip_vpu_enc.c new file +40
-0+ cap->capabilities = cap->device_caps |V4L2_CAP_DEVICE_CAPS ; + +return 0 ; +} + +static int vidioc_enum_framesizes (struct file *file,void *prov, +struct v4l2_frmsizeenum *fsize) +{ +struct rockchip_vpu_dev *dev =video_drvdata (file); +const struct rockchip_vpu_fmt *fmt; + +if (fsize->index !=0 ) { +vpu_debug (0 ,"invalid frame size index (expected 0, got %d)\n" , + fsize->index); +return -EINVAL ; + } + + fmt =rockchip_vpu_find_format (dev, fsize->pixel_format); +if (!fmt) { +vpu_debug (0 ,"unsupported bitstream format (%08x)\n" , + fsize->pixel_format); +return -EINVAL ; + } + +/* This only makes sense for codec formats */ +if (fmt->codec_mode ==RK_VPU_CODEC_NONE ) +return -ENOTTY ; + + fsize->type =V4L2_FRMSIZE_TYPE_STEPWISE ; + fsize->stepwise = fmt->frmsize; + +return 0 ; +} + +static int vidioc_enum_fmt_vid_cap_mplane (struct file *file,void *priv, +struct v4l2_fmtdesc *f) +{ +struct rockchip_vpu_dev *dev =video_drvdata (file); +const struct rockchip_vpu_fmt *fmt; +const struct rockchip_vpu_fmt *formats = dev->variant->enc_fmts;
drivers/media/platform/rockchip/vpu/rockchip_vpu_enc.c line 149
Quoted 10 lines
drivers/media/platform/rockchip/vpu/rockchip_vpu_enc.c new file +10
-0+int i, j =0 ; + +for (i =0 ; i < dev->variant->num_enc_fmts; i++) { +/* Skip uncompressed formats */ +if (formats[i].codec_mode ==RK_VPU_CODEC_NONE ) +continue ; +if (j == f->index) { + fmt = &formats[i]; +strlcpy (f->description, + fmt->name,sizeof (f->description));
Drop this,
drivers/media/platform/rockchip/vpu/rockchip_vpu_enc.c line 152
Quoted 3 lines
drivers/media/platform/rockchip/vpu/rockchip_vpu_enc.c new file +3
-0+ f->pixelformat = fmt->fourcc; + f->flags =0 ; + f->flags |=V4L2_FMT_FLAG_COMPRESSED ;
and this. Both fields are assigned for you in v4l2-ioctl.c.
Quoted 14 lines
drivers/media/platform/rockchip/vpu/rockchip_vpu_enc.c new file +14
-0+return 0 ; + } + ++j; + } +return -EINVAL ; +} + +static int vidioc_enum_fmt_vid_out_mplane (struct file *file,void *priv, +struct v4l2_fmtdesc *f) +{ +struct rockchip_vpu_dev *dev =video_drvdata (file); +const struct rockchip_vpu_fmt *fmt; +const struct rockchip_vpu_fmt *formats = dev->variant->enc_fmts; +int i, j =0 ;
drivers/media/platform/rockchip/vpu/rockchip_vpu_enc.c line 176
Quoted 10 lines
drivers/media/platform/rockchip/vpu/rockchip_vpu_enc.c new file +10
-0+ +for (i =0 ; i < dev->variant->num_enc_fmts; i++) { +if (formats[i].codec_mode !=RK_VPU_CODEC_NONE ) +continue ; +if (j == f->index) { + fmt = &formats[i]; +strlcpy (f->description, + fmt->name,sizeof (f->description)); + f->pixelformat = fmt->fourcc; + f->flags =0 ;
Ditto.
Quoted 215 lines
drivers/media/platform/rockchip/vpu/rockchip_vpu_enc.c new file +215
-0+return 0 ; + } + ++j; + } +return -EINVAL ; +} + +static int vidioc_g_fmt_out (struct file *file,void *priv, +struct v4l2_format *f) +{ +struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; +struct rockchip_vpu_ctx *ctx =fh_to_ctx (priv); + +vpu_debug (4 ,"f->type = %d\n" , f->type); + + *pix_mp = ctx->src_fmt; + pix_mp->colorspace = ctx->colorspace; + pix_mp->ycbcr_enc = ctx->ycbcr_enc; + pix_mp->xfer_func = ctx->xfer_func; + pix_mp->quantization = ctx->quantization; + +return 0 ; +} + +static int vidioc_g_fmt_cap (struct file *file,void *priv, +struct v4l2_format *f) +{ +struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; +struct rockchip_vpu_ctx *ctx =fh_to_ctx (priv); + +vpu_debug (4 ,"f->type = %d\n" , f->type); + + *pix_mp = ctx->dst_fmt; + pix_mp->colorspace = ctx->colorspace; + pix_mp->ycbcr_enc = ctx->ycbcr_enc; + pix_mp->xfer_func = ctx->xfer_func; + pix_mp->quantization = ctx->quantization; + +return 0 ; +} + +static void calculate_plane_sizes (const struct rockchip_vpu_fmt *fmt, +struct v4l2_pix_format_mplane *pix_mp) +{ +unsigned int w = pix_mp->width; +unsigned int h = pix_mp->height; +int i; + +for (i =0 ; i < fmt->num_planes; ++i) { +memset (pix_mp->plane_fmt[i].reserved,0 , +sizeof (pix_mp->plane_fmt[i].reserved)); + pix_mp->plane_fmt[i].bytesperline = w * fmt->depth[i] /8 ; + pix_mp->plane_fmt[i].sizeimage = h * + pix_mp->plane_fmt[i].bytesperline; +/* +* All of multiplanar formats we support have chroma +* planes subsampled by 2 vertically. +*/ +if (i !=0 ) + pix_mp->plane_fmt[i].sizeimage /=2 ; + } +} + +static int vidioc_try_fmt_cap (struct file *file,void *priv,struct v4l2_format *f) +{ +struct rockchip_vpu_dev *dev =video_drvdata (file); +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; +char str[5 ]; + +vpu_debug (4 ,"%s\n" ,fmt2str (pix_mp->pixelformat, str)); + + fmt =rockchip_vpu_find_format (dev, pix_mp->pixelformat); +if (!fmt) { + fmt =rockchip_vpu_get_default_fmt (dev, true); + f->fmt.pix.pixelformat = fmt->fourcc; + } + +/* Limit to hardware min/max. */ + pix_mp->width =clamp (pix_mp->width, + ctx->vpu_dst_fmt->frmsize.min_width, + ctx->vpu_dst_fmt->frmsize.max_width); + pix_mp->height =clamp (pix_mp->height, + ctx->vpu_dst_fmt->frmsize.min_height, + ctx->vpu_dst_fmt->frmsize.max_height); + pix_mp->num_planes = fmt->num_planes; + + pix_mp->plane_fmt[0 ].sizeimage = + pix_mp->width * pix_mp->height *JPEG_MAX_BYTES_PER_PIXEL ; +memset (pix_mp->plane_fmt[0 ].reserved,0 , +sizeof (pix_mp->plane_fmt[0 ].reserved)); + pix_mp->field =V4L2_FIELD_NONE ; + +return 0 ; +} + +static int vidioc_try_fmt_out (struct file *file,void *priv,struct v4l2_format *f) +{ +struct rockchip_vpu_dev *dev =video_drvdata (file); +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; +char str[5 ]; +unsigned long dma_align; +bool need_alignment; +int i; + +vpu_debug (4 ,"%s\n" ,fmt2str (pix_mp->pixelformat, str)); + + fmt =rockchip_vpu_find_format (dev, pix_mp->pixelformat); +if (!fmt) { + fmt =rockchip_vpu_get_default_fmt (dev, false); + f->fmt.pix.pixelformat = fmt->fourcc; + } + +/* Limit to hardware min/max. */ + pix_mp->width =clamp (pix_mp->width, + ctx->vpu_dst_fmt->frmsize.min_width, + ctx->vpu_dst_fmt->frmsize.max_width); + pix_mp->height =clamp (pix_mp->height, + ctx->vpu_dst_fmt->frmsize.min_height, + ctx->vpu_dst_fmt->frmsize.max_height); +/* Round up to macroblocks. */ + pix_mp->width =round_up (pix_mp->width,MB_DIM ); + pix_mp->height =round_up (pix_mp->height,MB_DIM ); + pix_mp->num_planes = fmt->num_planes; + pix_mp->field =V4L2_FIELD_NONE ; + +vpu_debug (0 ,"OUTPUT codec mode: %d\n" , fmt->codec_mode); +vpu_debug (0 ,"fmt - w: %d, h: %d, mb - w: %d, h: %d\n" , + pix_mp->width, pix_mp->height, +MB_WIDTH (pix_mp->width), +MB_HEIGHT (pix_mp->height)); + +/* Fill remaining fields */ +calculate_plane_sizes (fmt, pix_mp); + + dma_align =dma_get_cache_alignment (); + need_alignment = false; +for (i =0 ; i < fmt->num_planes; i++) { +if (!IS_ALIGNED (pix_mp->plane_fmt[i].sizeimage, + dma_align)) { + need_alignment = true; +break ; + } + } +if (!need_alignment) +return 0 ; + + pix_mp->height =round_up (pix_mp->height, dma_align *4 /MB_DIM ); +if (pix_mp->height > ctx->vpu_dst_fmt->frmsize.max_height) { +vpu_err ("Aligned height higher than maximum.\n" ); +return -EINVAL ; + } +/* Fill in remaining fields, again */ +calculate_plane_sizes (fmt, pix_mp); +return 0 ; +} + +static void rockchip_vpu_reset_dst_fmt (struct rockchip_vpu_dev *vpu, +struct rockchip_vpu_ctx *ctx) +{ +struct v4l2_pix_format_mplane *fmt = &ctx->dst_fmt; + + ctx->vpu_dst_fmt =rockchip_vpu_get_default_fmt (vpu, true); + +memset (fmt,0 ,sizeof (*fmt)); + + fmt->width = ctx->vpu_dst_fmt->frmsize.min_width; + fmt->height = ctx->vpu_dst_fmt->frmsize.min_height; + fmt->pixelformat = ctx->vpu_dst_fmt->fourcc; + fmt->num_planes = ctx->vpu_dst_fmt->num_planes; + fmt->plane_fmt[0 ].sizeimage = + fmt->width * fmt->height *JPEG_MAX_BYTES_PER_PIXEL ; + + fmt->field =V4L2_FIELD_NONE ; + + fmt->colorspace = ctx->colorspace; + fmt->ycbcr_enc = ctx->ycbcr_enc; + fmt->xfer_func = ctx->xfer_func; + fmt->quantization = ctx->quantization; +} + +static void rockchip_vpu_reset_src_fmt (struct rockchip_vpu_dev *vpu, +struct rockchip_vpu_ctx *ctx) +{ +struct v4l2_pix_format_mplane *fmt = &ctx->src_fmt; + + ctx->vpu_src_fmt =rockchip_vpu_get_default_fmt (vpu, false); + +memset (fmt,0 ,sizeof (*fmt)); + + fmt->width = ctx->vpu_dst_fmt->frmsize.min_width; + fmt->height = ctx->vpu_dst_fmt->frmsize.min_height; + fmt->pixelformat = ctx->vpu_src_fmt->fourcc; + fmt->num_planes = ctx->vpu_src_fmt->num_planes; + + fmt->field =V4L2_FIELD_NONE ; + + fmt->colorspace = ctx->colorspace; + fmt->ycbcr_enc = ctx->ycbcr_enc; + fmt->xfer_func = ctx->xfer_func; + fmt->quantization = ctx->quantization; + +calculate_plane_sizes (ctx->vpu_src_fmt, fmt); +} + +static int vidioc_s_fmt_out (struct file *file,void *priv,struct v4l2_format *f) +{ +struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; +struct rockchip_vpu_ctx *ctx =fh_to_ctx (priv); +struct rockchip_vpu_dev *vpu = ctx->dev; +struct vb2_queue *vq, *peer_vq; +int ret;
drivers/media/platform/rockchip/vpu/rockchip_vpu_enc.c line 401
Quoted 10 lines
drivers/media/platform/rockchip/vpu/rockchip_vpu_enc.c new file +10
-0+ +/* Change not allowed if queue is streaming. */ + vq =v4l2_m2m_get_vq (ctx->fh.m2m_ctx, f->type); +if (vb2_is_streaming (vq)) +return -EBUSY ; + + ctx->colorspace = pix_mp->colorspace; + ctx->ycbcr_enc = pix_mp->ycbcr_enc; + ctx->xfer_func = pix_mp->xfer_func; + ctx->quantization = pix_mp->quantization;
See my comments about this in my reply to your v1 cover letter.
Does the HW support limited to full range (or vv) conversion? If so, then you need to handle quantization in the driver. If not, then this code is fine.
Quoted 136 lines
drivers/media/platform/rockchip/vpu/rockchip_vpu_enc.c new file +136
-0+ +/* +* Pixel format change is not allowed when the other queue has +* buffers allocated. +*/ + peer_vq =v4l2_m2m_get_vq (ctx->fh.m2m_ctx, +V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ); +if (vb2_is_busy (peer_vq) && + pix_mp->pixelformat != ctx->src_fmt.pixelformat) +return -EBUSY ; + + ret =vidioc_try_fmt_out (file, priv, f); +if (ret) +return ret; + + ctx->vpu_src_fmt =rockchip_vpu_find_format (vpu, + pix_mp->pixelformat); + +/* Reset crop rectangle. */ + ctx->src_crop.width = pix_mp->width; + ctx->src_crop.height = pix_mp->height; + ctx->src_fmt = *pix_mp; + +return 0 ; +} + +static int vidioc_s_fmt_cap (struct file *file,void *priv,struct v4l2_format *f) +{ +struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; +struct rockchip_vpu_ctx *ctx =fh_to_ctx (priv); +struct rockchip_vpu_dev *vpu = ctx->dev; +struct vb2_queue *vq, *peer_vq; +int ret; + +/* Change not allowed if queue is streaming. */ + vq =v4l2_m2m_get_vq (ctx->fh.m2m_ctx, f->type); +if (vb2_is_streaming (vq)) +return -EBUSY ; + + ctx->colorspace = pix_mp->colorspace; + ctx->ycbcr_enc = pix_mp->ycbcr_enc; + ctx->xfer_func = pix_mp->xfer_func; + ctx->quantization = pix_mp->quantization; + +/* +* Pixel format change is not allowed when the other queue has +* buffers allocated. +*/ + peer_vq =v4l2_m2m_get_vq (ctx->fh.m2m_ctx, +V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ); +if (vb2_is_busy (peer_vq) && + pix_mp->pixelformat != ctx->dst_fmt.pixelformat) +return -EBUSY ; + + ret =vidioc_try_fmt_cap (file, priv, f); +if (ret) +return ret; + + ctx->vpu_dst_fmt =rockchip_vpu_find_format (vpu, pix_mp->pixelformat); + ctx->dst_fmt = *pix_mp; + +/* +* Current raw format might have become invalid with newly +* selected codec, so reset it to default just to be safe and +* keep internal driver state sane. User is mandated to set +* the raw format again after we return, so we don't need +* anything smarter. +*/ +rockchip_vpu_reset_src_fmt (vpu, ctx); + +return 0 ; +} + +static int vidioc_cropcap (struct file *file,void *priv, +struct v4l2_cropcap *cap) +{ +struct rockchip_vpu_ctx *ctx =fh_to_ctx (priv); +struct v4l2_pix_format_mplane *fmt = &ctx->src_fmt; + +/* Crop only supported on source. */ +if (cap->type !=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ) +return -EINVAL ; + + cap->bounds.left =0 ; + cap->bounds.top =0 ; + cap->bounds.width = fmt->width; + cap->bounds.height = fmt->height; + cap->defrect = cap->bounds; + cap->pixelaspect.numerator =1 ; + cap->pixelaspect.denominator =1 ; + +return 0 ; +} + +static int vidioc_g_crop (struct file *file,void *priv,struct v4l2_crop *crop) +{ +struct rockchip_vpu_ctx *ctx =fh_to_ctx (priv); +int ret =0 ; + +/* Crop only supported on source. */ +if (crop->type !=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ) +return -EINVAL ; + + crop->c = ctx->src_crop; + +return ret; +} + +static int vidioc_s_crop (struct file *file,void *priv, +const struct v4l2_crop *crop) +{ +struct rockchip_vpu_ctx *ctx =fh_to_ctx (priv); +struct v4l2_pix_format_mplane *fmt = &ctx->src_fmt; +const struct v4l2_rect *rect = &crop->c; +struct vb2_queue *vq; + +/* Crop only supported on source. */ +if (crop->type !=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ) +return -EINVAL ; + +/* Change not allowed if the queue is streaming. */ + vq =v4l2_m2m_get_vq (ctx->fh.m2m_ctx, crop->type); +if (vb2_is_streaming (vq)) +return -EBUSY ; + +/* We do not support offsets. */ +if (rect->left !=0 || rect->top !=0 ) + goto fallback; + +/* We can crop only inside right- or bottom-most macroblocks. */ +if (round_up (rect->width,MB_DIM ) != fmt->width + ||round_up (rect->height,MB_DIM ) != fmt->height) + goto fallback; + +/* We support widths aligned to 4 pixels and arbitrary heights. */ + ctx->src_crop.width =round_up (rect->width,4 );
drivers/media/platform/rockchip/vpu/rockchip_vpu_enc.c line 547
Quoted 10 lines
drivers/media/platform/rockchip/vpu/rockchip_vpu_enc.c new file +10
-0+ ctx->src_crop.height = rect->height; + +return 0 ; + +fallback: +/* Default to full frame for incorrect settings. */ + ctx->src_crop.width = fmt->width; + ctx->src_crop.height = fmt->height; +return 0 ; +}
Use selection API. I'm sure I've asked for this before.
I stop reviewing here since I wonder if this is really the v2 source code. I see too many things I've commented about in v1. Did you accidentally post the v1 again?
Regards,
Hans
Re: [PATCH 3/3] media: add Rockchip VPU driver
Quoted 6 lines · Hans Verkuil
Quoted 5 lines · Ezequiel Garcia
Add a mem2mem driver for the VPU available on Rockchip SoCs. Currently only JPEG encoding is supported, for RK3399 and RK3288 platforms.
Signed-off-by Ezequiel Garcia <[email protected]>
[..]
Quoted 5 lines
I stop reviewing here since I wonder if this is really the v2 source code. I see too many things I've commented about in v1. Did you accidentally post the v1 again?
Yes, that seems to be the case!
Signature · 7 lines
Ezequiel García, VanguardiaSur www.vanguardiasur.com.ar _______________________________________________ Linux-rockchip mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-rockchip