* Re: [PATCH v8 2/2] media: cedrus: Add H264 decoding support
From: Paul Kocialkowski @ 2019-04-10 13:45 UTC (permalink / raw)
To: Maxime Ripard, hans.verkuil, acourbot, sakari.ailus,
Laurent Pinchart
Cc: tfiga, posciak, Chen-Yu Tsai, linux-kernel, linux-arm-kernel,
linux-media, nicolas.dufresne, jenskuske, jernej.skrabec, jonas,
ezequiel, linux-sunxi, Thomas Petazzoni, Jernej Skrabec
In-Reply-To: <157519b5571e24c9ef4189d30f8434b5b61121b1.1554382670.git-series.maxime.ripard@bootlin.com>
Hi,
Le jeudi 04 avril 2019 à 14:59 +0200, Maxime Ripard a écrit :
> Introduce some basic H264 decoding support in cedrus. So far, only the
> baseline profile videos have been tested, and some more advanced features
> used in higher profiles are not even implemented.
With the change to rename V4L2_PIX_FMT_H264_SLICE_RAW and make it
private, this is:
Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
Cheers,
Paul
> Reviewed-by: Jernej Skrabec <jernej.skrabec@siol.net>
> Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
> ---
> drivers/staging/media/sunxi/cedrus/Makefile | 3 +-
> drivers/staging/media/sunxi/cedrus/cedrus.c | 31 +-
> drivers/staging/media/sunxi/cedrus/cedrus.h | 38 +-
> drivers/staging/media/sunxi/cedrus/cedrus_dec.c | 13 +-
> drivers/staging/media/sunxi/cedrus/cedrus_h264.c | 574 +++++++++++++++-
> drivers/staging/media/sunxi/cedrus/cedrus_hw.c | 4 +-
> drivers/staging/media/sunxi/cedrus/cedrus_regs.h | 91 ++-
> drivers/staging/media/sunxi/cedrus/cedrus_video.c | 9 +-
> 8 files changed, 761 insertions(+), 2 deletions(-)
> create mode 100644 drivers/staging/media/sunxi/cedrus/cedrus_h264.c
>
> diff --git a/drivers/staging/media/sunxi/cedrus/Makefile b/drivers/staging/media/sunxi/cedrus/Makefile
> index 808842f0119e..c85ac6db0302 100644
> --- a/drivers/staging/media/sunxi/cedrus/Makefile
> +++ b/drivers/staging/media/sunxi/cedrus/Makefile
> @@ -1,4 +1,5 @@
> # SPDX-License-Identifier: GPL-2.0
> obj-$(CONFIG_VIDEO_SUNXI_CEDRUS) += sunxi-cedrus.o
>
> -sunxi-cedrus-y = cedrus.o cedrus_video.o cedrus_hw.o cedrus_dec.o cedrus_mpeg2.o
> +sunxi-cedrus-y = cedrus.o cedrus_video.o cedrus_hw.o cedrus_dec.o \
> + cedrus_mpeg2.o cedrus_h264.o
> diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c
> index b98add3cdedd..d613f5c24a2f 100644
> --- a/drivers/staging/media/sunxi/cedrus/cedrus.c
> +++ b/drivers/staging/media/sunxi/cedrus/cedrus.c
> @@ -40,6 +40,36 @@ static const struct cedrus_control cedrus_controls[] = {
> .codec = CEDRUS_CODEC_MPEG2,
> .required = false,
> },
> + {
> + .id = V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS,
> + .elem_size = sizeof(struct v4l2_ctrl_h264_decode_params),
> + .codec = CEDRUS_CODEC_H264,
> + .required = true,
> + },
> + {
> + .id = V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS,
> + .elem_size = sizeof(struct v4l2_ctrl_h264_slice_params),
> + .codec = CEDRUS_CODEC_H264,
> + .required = true,
> + },
> + {
> + .id = V4L2_CID_MPEG_VIDEO_H264_SPS,
> + .elem_size = sizeof(struct v4l2_ctrl_h264_sps),
> + .codec = CEDRUS_CODEC_H264,
> + .required = true,
> + },
> + {
> + .id = V4L2_CID_MPEG_VIDEO_H264_PPS,
> + .elem_size = sizeof(struct v4l2_ctrl_h264_pps),
> + .codec = CEDRUS_CODEC_H264,
> + .required = true,
> + },
> + {
> + .id = V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX,
> + .elem_size = sizeof(struct v4l2_ctrl_h264_scaling_matrix),
> + .codec = CEDRUS_CODEC_H264,
> + .required = true,
> + },
> };
>
> #define CEDRUS_CONTROLS_COUNT ARRAY_SIZE(cedrus_controls)
> @@ -278,6 +308,7 @@ static int cedrus_probe(struct platform_device *pdev)
> }
>
> dev->dec_ops[CEDRUS_CODEC_MPEG2] = &cedrus_dec_ops_mpeg2;
> + dev->dec_ops[CEDRUS_CODEC_H264] = &cedrus_dec_ops_h264;
>
> mutex_init(&dev->dev_mutex);
>
> diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.h b/drivers/staging/media/sunxi/cedrus/cedrus.h
> index c57c04b41d2e..bef79f630520 100644
> --- a/drivers/staging/media/sunxi/cedrus/cedrus.h
> +++ b/drivers/staging/media/sunxi/cedrus/cedrus.h
> @@ -32,7 +32,7 @@
>
> enum cedrus_codec {
> CEDRUS_CODEC_MPEG2,
> -
> + CEDRUS_CODEC_H264,
> CEDRUS_CODEC_LAST,
> };
>
> @@ -42,6 +42,12 @@ enum cedrus_irq_status {
> CEDRUS_IRQ_OK,
> };
>
> +enum cedrus_h264_pic_type {
> + CEDRUS_H264_PIC_TYPE_FRAME = 0,
> + CEDRUS_H264_PIC_TYPE_FIELD,
> + CEDRUS_H264_PIC_TYPE_MBAFF,
> +};
> +
> struct cedrus_control {
> u32 id;
> u32 elem_size;
> @@ -49,6 +55,14 @@ struct cedrus_control {
> unsigned char required:1;
> };
>
> +struct cedrus_h264_run {
> + const struct v4l2_ctrl_h264_decode_params *decode_params;
> + const struct v4l2_ctrl_h264_pps *pps;
> + const struct v4l2_ctrl_h264_scaling_matrix *scaling_matrix;
> + const struct v4l2_ctrl_h264_slice_params *slice_params;
> + const struct v4l2_ctrl_h264_sps *sps;
> +};
> +
> struct cedrus_mpeg2_run {
> const struct v4l2_ctrl_mpeg2_slice_params *slice_params;
> const struct v4l2_ctrl_mpeg2_quantization *quantization;
> @@ -59,12 +73,20 @@ struct cedrus_run {
> struct vb2_v4l2_buffer *dst;
>
> union {
> + struct cedrus_h264_run h264;
> struct cedrus_mpeg2_run mpeg2;
> };
> };
>
> struct cedrus_buffer {
> struct v4l2_m2m_buffer m2m_buf;
> +
> + union {
> + struct {
> + unsigned int position;
> + enum cedrus_h264_pic_type pic_type;
> + } h264;
> + } codec;
> };
>
> struct cedrus_ctx {
> @@ -79,6 +101,19 @@ struct cedrus_ctx {
> struct v4l2_ctrl **ctrls;
>
> struct vb2_buffer *dst_bufs[VIDEO_MAX_FRAME];
> +
> + union {
> + struct {
> + void *mv_col_buf;
> + dma_addr_t mv_col_buf_dma;
> + ssize_t mv_col_buf_field_size;
> + ssize_t mv_col_buf_size;
> + void *pic_info_buf;
> + dma_addr_t pic_info_buf_dma;
> + void *neighbor_info_buf;
> + dma_addr_t neighbor_info_buf_dma;
> + } h264;
> + } codec;
> };
>
> struct cedrus_dec_ops {
> @@ -121,6 +156,7 @@ struct cedrus_dev {
> };
>
> extern struct cedrus_dec_ops cedrus_dec_ops_mpeg2;
> +extern struct cedrus_dec_ops cedrus_dec_ops_h264;
>
> static inline void cedrus_write(struct cedrus_dev *dev, u32 reg, u32 val)
> {
> diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
> index 4d6d602cdde6..bdad87eb9d79 100644
> --- a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
> +++ b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
> @@ -46,6 +46,19 @@ void cedrus_device_run(void *priv)
> V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION);
> break;
>
> + case V4L2_PIX_FMT_H264_SLICE_RAW:
> + run.h264.decode_params = cedrus_find_control_data(ctx,
> + V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS);
> + run.h264.pps = cedrus_find_control_data(ctx,
> + V4L2_CID_MPEG_VIDEO_H264_PPS);
> + run.h264.scaling_matrix = cedrus_find_control_data(ctx,
> + V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX);
> + run.h264.slice_params = cedrus_find_control_data(ctx,
> + V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS);
> + run.h264.sps = cedrus_find_control_data(ctx,
> + V4L2_CID_MPEG_VIDEO_H264_SPS);
> + break;
> +
> default:
> break;
> }
> diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
> new file mode 100644
> index 000000000000..2c98a3e46d2b
> --- /dev/null
> +++ b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
> @@ -0,0 +1,574 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Cedrus VPU driver
> + *
> + * Copyright (c) 2013 Jens Kuske <jenskuske@gmail.com>
> + * Copyright (c) 2018 Bootlin
> + */
> +
> +#include <linux/types.h>
> +
> +#include <media/videobuf2-dma-contig.h>
> +
> +#include "cedrus.h"
> +#include "cedrus_hw.h"
> +#include "cedrus_regs.h"
> +
> +enum cedrus_h264_sram_off {
> + CEDRUS_SRAM_H264_PRED_WEIGHT_TABLE = 0x000,
> + CEDRUS_SRAM_H264_FRAMEBUFFER_LIST = 0x100,
> + CEDRUS_SRAM_H264_REF_LIST_0 = 0x190,
> + CEDRUS_SRAM_H264_REF_LIST_1 = 0x199,
> + CEDRUS_SRAM_H264_SCALING_LIST_8x8_0 = 0x200,
> + CEDRUS_SRAM_H264_SCALING_LIST_8x8_1 = 0x210,
> + CEDRUS_SRAM_H264_SCALING_LIST_4x4 = 0x220,
> +};
> +
> +struct cedrus_h264_sram_ref_pic {
> + __le32 top_field_order_cnt;
> + __le32 bottom_field_order_cnt;
> + __le32 frame_info;
> + __le32 luma_ptr;
> + __le32 chroma_ptr;
> + __le32 mv_col_top_ptr;
> + __le32 mv_col_bot_ptr;
> + __le32 reserved;
> +} __packed;
> +
> +#define CEDRUS_H264_FRAME_NUM 18
> +
> +#define CEDRUS_NEIGHBOR_INFO_BUF_SIZE (16 * SZ_1K)
> +#define CEDRUS_PIC_INFO_BUF_SIZE (128 * SZ_1K)
> +
> +static void cedrus_h264_write_sram(struct cedrus_dev *dev,
> + enum cedrus_h264_sram_off off,
> + const void *data, size_t len)
> +{
> + const u32 *buffer = data;
> + size_t count = DIV_ROUND_UP(len, 4);
> +
> + cedrus_write(dev, VE_AVC_SRAM_PORT_OFFSET, off << 2);
> +
> + while (count--)
> + cedrus_write(dev, VE_AVC_SRAM_PORT_DATA, *buffer++);
> +}
> +
> +static dma_addr_t cedrus_h264_mv_col_buf_addr(struct cedrus_ctx *ctx,
> + unsigned int position,
> + unsigned int field)
> +{
> + dma_addr_t addr = ctx->codec.h264.mv_col_buf_dma;
> +
> + /* Adjust for the position */
> + addr += position * ctx->codec.h264.mv_col_buf_field_size * 2;
> +
> + /* Adjust for the field */
> + addr += field * ctx->codec.h264.mv_col_buf_field_size;
> +
> + return addr;
> +}
> +
> +static void cedrus_fill_ref_pic(struct cedrus_ctx *ctx,
> + struct cedrus_buffer *buf,
> + unsigned int top_field_order_cnt,
> + unsigned int bottom_field_order_cnt,
> + struct cedrus_h264_sram_ref_pic *pic)
> +{
> + struct vb2_buffer *vbuf = &buf->m2m_buf.vb.vb2_buf;
> + unsigned int position = buf->codec.h264.position;
> +
> + pic->top_field_order_cnt = top_field_order_cnt;
> + pic->bottom_field_order_cnt = bottom_field_order_cnt;
> + pic->frame_info = buf->codec.h264.pic_type << 8;
> +
> + pic->luma_ptr = cedrus_buf_addr(vbuf, &ctx->dst_fmt, 0);
> + pic->chroma_ptr = cedrus_buf_addr(vbuf, &ctx->dst_fmt, 1);
> + pic->mv_col_top_ptr = cedrus_h264_mv_col_buf_addr(ctx, position, 0);
> + pic->mv_col_bot_ptr = cedrus_h264_mv_col_buf_addr(ctx, position, 1);
> +}
> +
> +static void cedrus_write_frame_list(struct cedrus_ctx *ctx,
> + struct cedrus_run *run)
> +{
> + struct cedrus_h264_sram_ref_pic pic_list[CEDRUS_H264_FRAME_NUM];
> + const struct v4l2_ctrl_h264_decode_params *decode = run->h264.decode_params;
> + const struct v4l2_ctrl_h264_slice_params *slice = run->h264.slice_params;
> + const struct v4l2_ctrl_h264_sps *sps = run->h264.sps;
> + struct vb2_queue *cap_q = &ctx->fh.m2m_ctx->cap_q_ctx.q;
> + struct cedrus_buffer *output_buf;
> + struct cedrus_dev *dev = ctx->dev;
> + unsigned long used_dpbs = 0;
> + unsigned int position;
> + unsigned int output = 0;
> + unsigned int i;
> +
> + memset(pic_list, 0, sizeof(pic_list));
> +
> + for (i = 0; i < ARRAY_SIZE(decode->dpb); i++) {
> + const struct v4l2_h264_dpb_entry *dpb = &decode->dpb[i];
> + struct cedrus_buffer *cedrus_buf;
> + int buf_idx;
> +
> + if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_VALID))
> + continue;
> +
> + buf_idx = vb2_find_timestamp(cap_q, dpb->reference_ts, 0);
> + if (buf_idx < 0)
> + continue;
> +
> + cedrus_buf = vb2_to_cedrus_buffer(ctx->dst_bufs[buf_idx]);
> + position = cedrus_buf->codec.h264.position;
> + used_dpbs |= BIT(position);
> +
> + if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE))
> + continue;
> +
> + cedrus_fill_ref_pic(ctx, cedrus_buf,
> + dpb->top_field_order_cnt,
> + dpb->bottom_field_order_cnt,
> + &pic_list[position]);
> +
> + output = max(position, output);
> + }
> +
> + position = find_next_zero_bit(&used_dpbs, CEDRUS_H264_FRAME_NUM,
> + output);
> + if (position >= CEDRUS_H264_FRAME_NUM)
> + position = find_first_zero_bit(&used_dpbs, CEDRUS_H264_FRAME_NUM);
> +
> + output_buf = vb2_to_cedrus_buffer(&run->dst->vb2_buf);
> + output_buf->codec.h264.position = position;
> +
> + if (slice->flags & V4L2_H264_SLICE_FLAG_FIELD_PIC)
> + output_buf->codec.h264.pic_type = CEDRUS_H264_PIC_TYPE_FIELD;
> + else if (sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD)
> + output_buf->codec.h264.pic_type = CEDRUS_H264_PIC_TYPE_MBAFF;
> + else
> + output_buf->codec.h264.pic_type = CEDRUS_H264_PIC_TYPE_FRAME;
> +
> + cedrus_fill_ref_pic(ctx, output_buf,
> + decode->top_field_order_cnt,
> + decode->bottom_field_order_cnt,
> + &pic_list[position]);
> +
> + cedrus_h264_write_sram(dev, CEDRUS_SRAM_H264_FRAMEBUFFER_LIST,
> + pic_list, sizeof(pic_list));
> +
> + cedrus_write(dev, VE_H264_OUTPUT_FRAME_IDX, position);
> +}
> +
> +#define CEDRUS_MAX_REF_IDX 32
> +
> +static void _cedrus_write_ref_list(struct cedrus_ctx *ctx,
> + struct cedrus_run *run,
> + const u8 *ref_list, u8 num_ref,
> + enum cedrus_h264_sram_off sram)
> +{
> + const struct v4l2_ctrl_h264_decode_params *decode = run->h264.decode_params;
> + struct vb2_queue *cap_q = &ctx->fh.m2m_ctx->cap_q_ctx.q;
> + struct cedrus_dev *dev = ctx->dev;
> + u8 sram_array[CEDRUS_MAX_REF_IDX];
> + unsigned int i;
> + size_t size;
> +
> + memset(sram_array, 0, sizeof(sram_array));
> +
> + for (i = 0; i < num_ref; i++) {
> + const struct v4l2_h264_dpb_entry *dpb;
> + const struct cedrus_buffer *cedrus_buf;
> + const struct vb2_v4l2_buffer *ref_buf;
> + unsigned int position;
> + int buf_idx;
> + u8 dpb_idx;
> +
> + dpb_idx = ref_list[i];
> + dpb = &decode->dpb[dpb_idx];
> +
> + if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE))
> + continue;
> +
> + buf_idx = vb2_find_timestamp(cap_q, dpb->reference_ts, 0);
> + if (buf_idx < 0)
> + continue;
> +
> + ref_buf = to_vb2_v4l2_buffer(ctx->dst_bufs[buf_idx]);
> + cedrus_buf = vb2_v4l2_to_cedrus_buffer(ref_buf);
> + position = cedrus_buf->codec.h264.position;
> +
> + sram_array[i] |= position << 1;
> + if (ref_buf->field == V4L2_FIELD_BOTTOM)
> + sram_array[i] |= BIT(0);
> + }
> +
> + size = min_t(size_t, ALIGN(num_ref, 4), sizeof(sram_array));
> + cedrus_h264_write_sram(dev, sram, &sram_array, size);
> +}
> +
> +static void cedrus_write_ref_list0(struct cedrus_ctx *ctx,
> + struct cedrus_run *run)
> +{
> + const struct v4l2_ctrl_h264_slice_params *slice = run->h264.slice_params;
> +
> + _cedrus_write_ref_list(ctx, run,
> + slice->ref_pic_list0,
> + slice->num_ref_idx_l0_active_minus1 + 1,
> + CEDRUS_SRAM_H264_REF_LIST_0);
> +}
> +
> +static void cedrus_write_ref_list1(struct cedrus_ctx *ctx,
> + struct cedrus_run *run)
> +{
> + const struct v4l2_ctrl_h264_slice_params *slice = run->h264.slice_params;
> +
> + _cedrus_write_ref_list(ctx, run,
> + slice->ref_pic_list1,
> + slice->num_ref_idx_l1_active_minus1 + 1,
> + CEDRUS_SRAM_H264_REF_LIST_1);
> +}
> +
> +static void cedrus_write_scaling_lists(struct cedrus_ctx *ctx,
> + struct cedrus_run *run)
> +{
> + const struct v4l2_ctrl_h264_scaling_matrix *scaling =
> + run->h264.scaling_matrix;
> + struct cedrus_dev *dev = ctx->dev;
> +
> + cedrus_h264_write_sram(dev, CEDRUS_SRAM_H264_SCALING_LIST_8x8_0,
> + scaling->scaling_list_8x8[0],
> + sizeof(scaling->scaling_list_8x8[0]));
> +
> + cedrus_h264_write_sram(dev, CEDRUS_SRAM_H264_SCALING_LIST_8x8_1,
> + scaling->scaling_list_8x8[3],
> + sizeof(scaling->scaling_list_8x8[3]));
> +
> + cedrus_h264_write_sram(dev, CEDRUS_SRAM_H264_SCALING_LIST_4x4,
> + scaling->scaling_list_4x4,
> + sizeof(scaling->scaling_list_4x4));
> +}
> +
> +static void cedrus_write_pred_weight_table(struct cedrus_ctx *ctx,
> + struct cedrus_run *run)
> +{
> + const struct v4l2_ctrl_h264_slice_params *slice =
> + run->h264.slice_params;
> + const struct v4l2_h264_pred_weight_table *pred_weight =
> + &slice->pred_weight_table;
> + struct cedrus_dev *dev = ctx->dev;
> + int i, j, k;
> +
> + cedrus_write(dev, VE_H264_SHS_WP,
> + ((pred_weight->chroma_log2_weight_denom & 0x7) << 4) |
> + ((pred_weight->luma_log2_weight_denom & 0x7) << 0));
> +
> + cedrus_write(dev, VE_AVC_SRAM_PORT_OFFSET,
> + CEDRUS_SRAM_H264_PRED_WEIGHT_TABLE << 2);
> +
> + for (i = 0; i < ARRAY_SIZE(pred_weight->weight_factors); i++) {
> + const struct v4l2_h264_weight_factors *factors =
> + &pred_weight->weight_factors[i];
> +
> + for (j = 0; j < ARRAY_SIZE(factors->luma_weight); j++) {
> + u32 val;
> +
> + val = (((u32)factors->luma_offset[j] & 0x1ff) << 16) |
> + (factors->luma_weight[j] & 0x1ff);
> + cedrus_write(dev, VE_AVC_SRAM_PORT_DATA, val);
> + }
> +
> + for (j = 0; j < ARRAY_SIZE(factors->chroma_weight); j++) {
> + for (k = 0; k < ARRAY_SIZE(factors->chroma_weight[0]); k++) {
> + u32 val;
> +
> + val = (((u32)factors->chroma_offset[j][k] & 0x1ff) << 16) |
> + (factors->chroma_weight[j][k] & 0x1ff);
> + cedrus_write(dev, VE_AVC_SRAM_PORT_DATA, val);
> + }
> + }
> + }
> +}
> +
> +static void cedrus_set_params(struct cedrus_ctx *ctx,
> + struct cedrus_run *run)
> +{
> + const struct v4l2_ctrl_h264_decode_params *decode = run->h264.decode_params;
> + const struct v4l2_ctrl_h264_slice_params *slice = run->h264.slice_params;
> + const struct v4l2_ctrl_h264_pps *pps = run->h264.pps;
> + const struct v4l2_ctrl_h264_sps *sps = run->h264.sps;
> + struct vb2_buffer *src_buf = &run->src->vb2_buf;
> + struct cedrus_dev *dev = ctx->dev;
> + dma_addr_t src_buf_addr;
> + u32 offset = slice->header_bit_size;
> + u32 len = (slice->size * 8) - offset;
> + u32 reg;
> +
> + cedrus_write(dev, VE_H264_VLD_LEN, len);
> + cedrus_write(dev, VE_H264_VLD_OFFSET, offset);
> +
> + src_buf_addr = vb2_dma_contig_plane_dma_addr(src_buf, 0);
> + cedrus_write(dev, VE_H264_VLD_END,
> + src_buf_addr + vb2_get_plane_payload(src_buf, 0));
> + cedrus_write(dev, VE_H264_VLD_ADDR,
> + VE_H264_VLD_ADDR_VAL(src_buf_addr) |
> + VE_H264_VLD_ADDR_FIRST | VE_H264_VLD_ADDR_VALID |
> + VE_H264_VLD_ADDR_LAST);
> +
> + /*
> + * FIXME: Since the bitstream parsing is done in software, and
> + * in userspace, this shouldn't be needed anymore. But it
> + * turns out that removing it breaks the decoding process,
> + * without any clear indication why.
> + */
> + cedrus_write(dev, VE_H264_TRIGGER_TYPE,
> + VE_H264_TRIGGER_TYPE_INIT_SWDEC);
> +
> + if (((pps->flags & V4L2_H264_PPS_FLAG_WEIGHTED_PRED) &&
> + (slice->slice_type == V4L2_H264_SLICE_TYPE_P ||
> + slice->slice_type == V4L2_H264_SLICE_TYPE_SP)) ||
> + (pps->weighted_bipred_idc == 1 &&
> + slice->slice_type == V4L2_H264_SLICE_TYPE_B))
> + cedrus_write_pred_weight_table(ctx, run);
> +
> + if ((slice->slice_type == V4L2_H264_SLICE_TYPE_P) ||
> + (slice->slice_type == V4L2_H264_SLICE_TYPE_SP) ||
> + (slice->slice_type == V4L2_H264_SLICE_TYPE_B))
> + cedrus_write_ref_list0(ctx, run);
> +
> + if (slice->slice_type == V4L2_H264_SLICE_TYPE_B)
> + cedrus_write_ref_list1(ctx, run);
> +
> + // picture parameters
> + reg = 0;
> + /*
> + * FIXME: the kernel headers are allowing the default value to
> + * be passed, but the libva doesn't give us that.
> + */
> + reg |= (slice->num_ref_idx_l0_active_minus1 & 0x1f) << 10;
> + reg |= (slice->num_ref_idx_l1_active_minus1 & 0x1f) << 5;
> + reg |= (pps->weighted_bipred_idc & 0x3) << 2;
> + if (pps->flags & V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE)
> + reg |= VE_H264_PPS_ENTROPY_CODING_MODE;
> + if (pps->flags & V4L2_H264_PPS_FLAG_WEIGHTED_PRED)
> + reg |= VE_H264_PPS_WEIGHTED_PRED;
> + if (pps->flags & V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED)
> + reg |= VE_H264_PPS_CONSTRAINED_INTRA_PRED;
> + if (pps->flags & V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE)
> + reg |= VE_H264_PPS_TRANSFORM_8X8_MODE;
> + cedrus_write(dev, VE_H264_PPS, reg);
> +
> + // sequence parameters
> + reg = 0;
> + reg |= (sps->chroma_format_idc & 0x7) << 19;
> + reg |= (sps->pic_width_in_mbs_minus1 & 0xff) << 8;
> + reg |= sps->pic_height_in_map_units_minus1 & 0xff;
> + if (sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY)
> + reg |= VE_H264_SPS_MBS_ONLY;
> + if (sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD)
> + reg |= VE_H264_SPS_MB_ADAPTIVE_FRAME_FIELD;
> + if (sps->flags & V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE)
> + reg |= VE_H264_SPS_DIRECT_8X8_INFERENCE;
> + cedrus_write(dev, VE_H264_SPS, reg);
> +
> + // slice parameters
> + reg = 0;
> + reg |= decode->nal_ref_idc ? BIT(12) : 0;
> + reg |= (slice->slice_type & 0xf) << 8;
> + reg |= slice->cabac_init_idc & 0x3;
> + reg |= VE_H264_SHS_FIRST_SLICE_IN_PIC;
> + if (slice->flags & V4L2_H264_SLICE_FLAG_FIELD_PIC)
> + reg |= VE_H264_SHS_FIELD_PIC;
> + if (slice->flags & V4L2_H264_SLICE_FLAG_BOTTOM_FIELD)
> + reg |= VE_H264_SHS_BOTTOM_FIELD;
> + if (slice->flags & V4L2_H264_SLICE_FLAG_DIRECT_SPATIAL_MV_PRED)
> + reg |= VE_H264_SHS_DIRECT_SPATIAL_MV_PRED;
> + cedrus_write(dev, VE_H264_SHS, reg);
> +
> + reg = 0;
> + reg |= VE_H264_SHS2_NUM_REF_IDX_ACTIVE_OVRD;
> + reg |= (slice->num_ref_idx_l0_active_minus1 & 0x1f) << 24;
> + reg |= (slice->num_ref_idx_l1_active_minus1 & 0x1f) << 16;
> + reg |= (slice->disable_deblocking_filter_idc & 0x3) << 8;
> + reg |= (slice->slice_alpha_c0_offset_div2 & 0xf) << 4;
> + reg |= slice->slice_beta_offset_div2 & 0xf;
> + cedrus_write(dev, VE_H264_SHS2, reg);
> +
> + reg = 0;
> + reg |= (pps->second_chroma_qp_index_offset & 0x3f) << 16;
> + reg |= (pps->chroma_qp_index_offset & 0x3f) << 8;
> + reg |= (pps->pic_init_qp_minus26 + 26 + slice->slice_qp_delta) & 0x3f;
> + cedrus_write(dev, VE_H264_SHS_QP, reg);
> +
> + // clear status flags
> + cedrus_write(dev, VE_H264_STATUS, cedrus_read(dev, VE_H264_STATUS));
> +
> + // enable int
> + cedrus_write(dev, VE_H264_CTRL,
> + VE_H264_CTRL_SLICE_DECODE_INT |
> + VE_H264_CTRL_DECODE_ERR_INT |
> + VE_H264_CTRL_VLD_DATA_REQ_INT);
> +}
> +
> +static enum cedrus_irq_status
> +cedrus_h264_irq_status(struct cedrus_ctx *ctx)
> +{
> + struct cedrus_dev *dev = ctx->dev;
> + u32 reg = cedrus_read(dev, VE_H264_STATUS);
> +
> + if (reg & (VE_H264_STATUS_DECODE_ERR_INT |
> + VE_H264_STATUS_VLD_DATA_REQ_INT))
> + return CEDRUS_IRQ_ERROR;
> +
> + if (reg & VE_H264_CTRL_SLICE_DECODE_INT)
> + return CEDRUS_IRQ_OK;
> +
> + return CEDRUS_IRQ_NONE;
> +}
> +
> +static void cedrus_h264_irq_clear(struct cedrus_ctx *ctx)
> +{
> + struct cedrus_dev *dev = ctx->dev;
> +
> + cedrus_write(dev, VE_H264_STATUS,
> + VE_H264_STATUS_INT_MASK);
> +}
> +
> +static void cedrus_h264_irq_disable(struct cedrus_ctx *ctx)
> +{
> + struct cedrus_dev *dev = ctx->dev;
> + u32 reg = cedrus_read(dev, VE_H264_CTRL);
> +
> + cedrus_write(dev, VE_H264_CTRL,
> + reg & ~VE_H264_CTRL_INT_MASK);
> +}
> +
> +static void cedrus_h264_setup(struct cedrus_ctx *ctx,
> + struct cedrus_run *run)
> +{
> + struct cedrus_dev *dev = ctx->dev;
> +
> + cedrus_engine_enable(dev, CEDRUS_CODEC_H264);
> +
> + cedrus_write(dev, VE_H264_SDROT_CTRL, 0);
> + cedrus_write(dev, VE_H264_EXTRA_BUFFER1,
> + ctx->codec.h264.pic_info_buf_dma);
> + cedrus_write(dev, VE_H264_EXTRA_BUFFER2,
> + ctx->codec.h264.neighbor_info_buf_dma);
> +
> + cedrus_write_scaling_lists(ctx, run);
> + cedrus_write_frame_list(ctx, run);
> +
> + cedrus_set_params(ctx, run);
> +}
> +
> +static int cedrus_h264_start(struct cedrus_ctx *ctx)
> +{
> + struct cedrus_dev *dev = ctx->dev;
> + unsigned int field_size;
> + unsigned int mv_col_size;
> + int ret;
> +
> + /*
> + * FIXME: It seems that the H6 cedarX code is using a formula
> + * here based on the size of the frame, while all the older
> + * code is using a fixed size, so that might need to be
> + * changed at some point.
> + */
> + ctx->codec.h264.pic_info_buf =
> + dma_alloc_coherent(dev->dev, CEDRUS_PIC_INFO_BUF_SIZE,
> + &ctx->codec.h264.pic_info_buf_dma,
> + GFP_KERNEL);
> + if (!ctx->codec.h264.pic_info_buf)
> + return -ENOMEM;
> +
> + /*
> + * That buffer is supposed to be 16kiB in size, and be aligned
> + * on 16kiB as well. However, dma_alloc_coherent provides the
> + * guarantee that we'll have a CPU and DMA address aligned on
> + * the smallest page order that is greater to the requested
> + * size, so we don't have to overallocate.
> + */
> + ctx->codec.h264.neighbor_info_buf =
> + dma_alloc_coherent(dev->dev, CEDRUS_NEIGHBOR_INFO_BUF_SIZE,
> + &ctx->codec.h264.neighbor_info_buf_dma,
> + GFP_KERNEL);
> + if (!ctx->codec.h264.neighbor_info_buf) {
> + ret = -ENOMEM;
> + goto err_pic_buf;
> + }
> +
> + field_size = DIV_ROUND_UP(ctx->src_fmt.width, 16) *
> + DIV_ROUND_UP(ctx->src_fmt.height, 16) * 16;
> +
> + /*
> + * FIXME: This is actually conditional to
> + * V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE not being set, we
> + * might have to rework this if memory efficiency ever is
> + * something we need to work on.
> + */
> + field_size = field_size * 2;
> +
> + /*
> + * FIXME: This is actually conditional to
> + * V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY not being set, we might
> + * have to rework this if memory efficiency ever is something
> + * we need to work on.
> + */
> + field_size = field_size * 2;
> + ctx->codec.h264.mv_col_buf_field_size = field_size;
> +
> + mv_col_size = field_size * 2 * CEDRUS_H264_FRAME_NUM;
> + ctx->codec.h264.mv_col_buf_size = mv_col_size;
> + ctx->codec.h264.mv_col_buf = dma_alloc_coherent(dev->dev,
> + ctx->codec.h264.mv_col_buf_size,
> + &ctx->codec.h264.mv_col_buf_dma,
> + GFP_KERNEL);
> + if (!ctx->codec.h264.mv_col_buf) {
> + ret = -ENOMEM;
> + goto err_neighbor_buf;
> + }
> +
> + return 0;
> +
> +err_neighbor_buf:
> + dma_free_coherent(dev->dev, CEDRUS_NEIGHBOR_INFO_BUF_SIZE,
> + ctx->codec.h264.neighbor_info_buf,
> + ctx->codec.h264.neighbor_info_buf_dma);
> +
> +err_pic_buf:
> + dma_free_coherent(dev->dev, CEDRUS_PIC_INFO_BUF_SIZE,
> + ctx->codec.h264.pic_info_buf,
> + ctx->codec.h264.pic_info_buf_dma);
> + return ret;
> +}
> +
> +static void cedrus_h264_stop(struct cedrus_ctx *ctx)
> +{
> + struct cedrus_dev *dev = ctx->dev;
> +
> + dma_free_coherent(dev->dev, ctx->codec.h264.mv_col_buf_size,
> + ctx->codec.h264.mv_col_buf,
> + ctx->codec.h264.mv_col_buf_dma);
> + dma_free_coherent(dev->dev, CEDRUS_NEIGHBOR_INFO_BUF_SIZE,
> + ctx->codec.h264.neighbor_info_buf,
> + ctx->codec.h264.neighbor_info_buf_dma);
> + dma_free_coherent(dev->dev, CEDRUS_PIC_INFO_BUF_SIZE,
> + ctx->codec.h264.pic_info_buf,
> + ctx->codec.h264.pic_info_buf_dma);
> +}
> +
> +static void cedrus_h264_trigger(struct cedrus_ctx *ctx)
> +{
> + struct cedrus_dev *dev = ctx->dev;
> +
> + cedrus_write(dev, VE_H264_TRIGGER_TYPE,
> + VE_H264_TRIGGER_TYPE_AVC_SLICE_DECODE);
> +}
> +
> +struct cedrus_dec_ops cedrus_dec_ops_h264 = {
> + .irq_clear = cedrus_h264_irq_clear,
> + .irq_disable = cedrus_h264_irq_disable,
> + .irq_status = cedrus_h264_irq_status,
> + .setup = cedrus_h264_setup,
> + .start = cedrus_h264_start,
> + .stop = cedrus_h264_stop,
> + .trigger = cedrus_h264_trigger,
> +};
> diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_hw.c b/drivers/staging/media/sunxi/cedrus/cedrus_hw.c
> index fbfff7c1c771..748f7f673547 100644
> --- a/drivers/staging/media/sunxi/cedrus/cedrus_hw.c
> +++ b/drivers/staging/media/sunxi/cedrus/cedrus_hw.c
> @@ -46,6 +46,10 @@ int cedrus_engine_enable(struct cedrus_dev *dev, enum cedrus_codec codec)
> reg |= VE_MODE_DEC_MPEG;
> break;
>
> + case CEDRUS_CODEC_H264:
> + reg |= VE_MODE_DEC_H264;
> + break;
> +
> default:
> return -EINVAL;
> }
> diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
> index de2d6b6f64bf..3e9931416e45 100644
> --- a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
> +++ b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
> @@ -232,4 +232,95 @@
> #define VE_DEC_MPEG_ROT_LUMA (VE_ENGINE_DEC_MPEG + 0xcc)
> #define VE_DEC_MPEG_ROT_CHROMA (VE_ENGINE_DEC_MPEG + 0xd0)
>
> +#define VE_H264_SPS 0x200
> +#define VE_H264_SPS_MBS_ONLY BIT(18)
> +#define VE_H264_SPS_MB_ADAPTIVE_FRAME_FIELD BIT(17)
> +#define VE_H264_SPS_DIRECT_8X8_INFERENCE BIT(16)
> +
> +#define VE_H264_PPS 0x204
> +#define VE_H264_PPS_ENTROPY_CODING_MODE BIT(15)
> +#define VE_H264_PPS_WEIGHTED_PRED BIT(4)
> +#define VE_H264_PPS_CONSTRAINED_INTRA_PRED BIT(1)
> +#define VE_H264_PPS_TRANSFORM_8X8_MODE BIT(0)
> +
> +#define VE_H264_SHS 0x208
> +#define VE_H264_SHS_FIRST_SLICE_IN_PIC BIT(5)
> +#define VE_H264_SHS_FIELD_PIC BIT(4)
> +#define VE_H264_SHS_BOTTOM_FIELD BIT(3)
> +#define VE_H264_SHS_DIRECT_SPATIAL_MV_PRED BIT(2)
> +
> +#define VE_H264_SHS2 0x20c
> +#define VE_H264_SHS2_NUM_REF_IDX_ACTIVE_OVRD BIT(12)
> +
> +#define VE_H264_SHS_WP 0x210
> +
> +#define VE_H264_SHS_QP 0x21c
> +#define VE_H264_SHS_QP_SCALING_MATRIX_DEFAULT BIT(24)
> +
> +#define VE_H264_CTRL 0x220
> +#define VE_H264_CTRL_VLD_DATA_REQ_INT BIT(2)
> +#define VE_H264_CTRL_DECODE_ERR_INT BIT(1)
> +#define VE_H264_CTRL_SLICE_DECODE_INT BIT(0)
> +
> +#define VE_H264_CTRL_INT_MASK (VE_H264_CTRL_VLD_DATA_REQ_INT | \
> + VE_H264_CTRL_DECODE_ERR_INT | \
> + VE_H264_CTRL_SLICE_DECODE_INT)
> +
> +#define VE_H264_TRIGGER_TYPE 0x224
> +#define VE_H264_TRIGGER_TYPE_AVC_SLICE_DECODE (8 << 0)
> +#define VE_H264_TRIGGER_TYPE_INIT_SWDEC (7 << 0)
> +
> +#define VE_H264_STATUS 0x228
> +#define VE_H264_STATUS_VLD_DATA_REQ_INT VE_H264_CTRL_VLD_DATA_REQ_INT
> +#define VE_H264_STATUS_DECODE_ERR_INT VE_H264_CTRL_DECODE_ERR_INT
> +#define VE_H264_STATUS_SLICE_DECODE_INT VE_H264_CTRL_SLICE_DECODE_INT
> +
> +#define VE_H264_STATUS_INT_MASK VE_H264_CTRL_INT_MASK
> +
> +#define VE_H264_CUR_MB_NUM 0x22c
> +
> +#define VE_H264_VLD_ADDR 0x230
> +#define VE_H264_VLD_ADDR_FIRST BIT(30)
> +#define VE_H264_VLD_ADDR_LAST BIT(29)
> +#define VE_H264_VLD_ADDR_VALID BIT(28)
> +#define VE_H264_VLD_ADDR_VAL(x) (((x) & 0x0ffffff0) | ((x) >> 28))
> +
> +#define VE_H264_VLD_OFFSET 0x234
> +#define VE_H264_VLD_LEN 0x238
> +#define VE_H264_VLD_END 0x23c
> +#define VE_H264_SDROT_CTRL 0x240
> +#define VE_H264_OUTPUT_FRAME_IDX 0x24c
> +#define VE_H264_EXTRA_BUFFER1 0x250
> +#define VE_H264_EXTRA_BUFFER2 0x254
> +#define VE_H264_BASIC_BITS 0x2dc
> +#define VE_AVC_SRAM_PORT_OFFSET 0x2e0
> +#define VE_AVC_SRAM_PORT_DATA 0x2e4
> +
> +#define VE_ISP_INPUT_SIZE 0xa00
> +#define VE_ISP_INPUT_STRIDE 0xa04
> +#define VE_ISP_CTRL 0xa08
> +#define VE_ISP_INPUT_LUMA 0xa78
> +#define VE_ISP_INPUT_CHROMA 0xa7c
> +
> +#define VE_AVC_PARAM 0xb04
> +#define VE_AVC_QP 0xb08
> +#define VE_AVC_MOTION_EST 0xb10
> +#define VE_AVC_CTRL 0xb14
> +#define VE_AVC_TRIGGER 0xb18
> +#define VE_AVC_STATUS 0xb1c
> +#define VE_AVC_BASIC_BITS 0xb20
> +#define VE_AVC_UNK_BUF 0xb60
> +#define VE_AVC_VLE_ADDR 0xb80
> +#define VE_AVC_VLE_END 0xb84
> +#define VE_AVC_VLE_OFFSET 0xb88
> +#define VE_AVC_VLE_MAX 0xb8c
> +#define VE_AVC_VLE_LENGTH 0xb90
> +#define VE_AVC_REF_LUMA 0xba0
> +#define VE_AVC_REF_CHROMA 0xba4
> +#define VE_AVC_REC_LUMA 0xbb0
> +#define VE_AVC_REC_CHROMA 0xbb4
> +#define VE_AVC_REF_SLUMA 0xbb8
> +#define VE_AVC_REC_SLUMA 0xbbc
> +#define VE_AVC_MB_INFO 0xbc0
> +
> #endif
> diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_video.c b/drivers/staging/media/sunxi/cedrus/cedrus_video.c
> index 9673874ece10..e2b530b1a956 100644
> --- a/drivers/staging/media/sunxi/cedrus/cedrus_video.c
> +++ b/drivers/staging/media/sunxi/cedrus/cedrus_video.c
> @@ -38,6 +38,10 @@ static struct cedrus_format cedrus_formats[] = {
> .directions = CEDRUS_DECODE_SRC,
> },
> {
> + .pixelformat = V4L2_PIX_FMT_H264_SLICE_RAW,
> + .directions = CEDRUS_DECODE_SRC,
> + },
> + {
> .pixelformat = V4L2_PIX_FMT_SUNXI_TILED_NV12,
> .directions = CEDRUS_DECODE_DST,
> },
> @@ -100,6 +104,7 @@ static void cedrus_prepare_format(struct v4l2_pix_format *pix_fmt)
>
> switch (pix_fmt->pixelformat) {
> case V4L2_PIX_FMT_MPEG2_SLICE:
> + case V4L2_PIX_FMT_H264_SLICE_RAW:
> /* Zero bytes per line for encoded source. */
> bytesperline = 0;
>
> @@ -464,6 +469,10 @@ static int cedrus_start_streaming(struct vb2_queue *vq, unsigned int count)
> ctx->current_codec = CEDRUS_CODEC_MPEG2;
> break;
>
> + case V4L2_PIX_FMT_H264_SLICE_RAW:
> + ctx->current_codec = CEDRUS_CODEC_H264;
> + break;
> +
> default:
> return -EINVAL;
> }
--
Paul Kocialkowski, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com
^ permalink raw reply
* Re: [PATCH v8 1/2] media: uapi: Add H264 low-level decoder API compound controls.
From: Paul Kocialkowski @ 2019-04-10 13:44 UTC (permalink / raw)
To: Maxime Ripard, hans.verkuil, acourbot, sakari.ailus,
Laurent Pinchart
Cc: tfiga, posciak, Chen-Yu Tsai, linux-kernel, linux-arm-kernel,
linux-media, nicolas.dufresne, jenskuske, jernej.skrabec, jonas,
ezequiel, linux-sunxi, Thomas Petazzoni, Guenter Roeck
In-Reply-To: <f537c99d8b5a974f8687f4f0d018c025a4220f7a.1554382670.git-series.maxime.ripard@bootlin.com>
Hi,
Le jeudi 04 avril 2019 à 14:59 +0200, Maxime Ripard a écrit :
> From: Pawel Osciak <posciak@chromium.org>
>
> Stateless video codecs will require both the H264 metadata and slices in
> order to be able to decode frames.
>
> This introduces the definitions for a new pixel format for H264 slices that
> have been parsed, as well as the structures used to pass the metadata from
> the userspace to the kernel.
With V4L2_PIX_FMT_H264_SLICE_RAW renamed to V4L2_PIX_FMT_H264_SLICE and
moved to the private h264-ctrls.h, this is:
Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
Cheers,
Paul
> Reviewed-by: Tomasz Figa <tfiga@chromium.org>
> Signed-off-by: Pawel Osciak <posciak@chromium.org>
> Signed-off-by: Guenter Roeck <groeck@chromium.org>
> Co-developed-by: Maxime Ripard <maxime.ripard@bootlin.com>
> Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
> ---
> Documentation/media/uapi/v4l/biblio.rst | 9 +-
> Documentation/media/uapi/v4l/ext-ctrls-codec.rst | 569 ++++++++++++++-
> Documentation/media/uapi/v4l/pixfmt-compressed.rst | 19 +-
> Documentation/media/uapi/v4l/vidioc-queryctrl.rst | 30 +-
> Documentation/media/videodev2.h.rst.exceptions | 5 +-
> drivers/media/v4l2-core/v4l2-ctrls.c | 42 +-
> drivers/media/v4l2-core/v4l2-ioctl.c | 1 +-
> include/media/h264-ctrls.h | 192 +++++-
> include/media/v4l2-ctrls.h | 13 +-
> include/uapi/linux/videodev2.h | 1 +-
> 10 files changed, 880 insertions(+), 1 deletion(-)
> create mode 100644 include/media/h264-ctrls.h
>
> diff --git a/Documentation/media/uapi/v4l/biblio.rst b/Documentation/media/uapi/v4l/biblio.rst
> index ec33768c055e..8f4eb8823d82 100644
> --- a/Documentation/media/uapi/v4l/biblio.rst
> +++ b/Documentation/media/uapi/v4l/biblio.rst
> @@ -122,6 +122,15 @@ ITU BT.1119
>
> :author: International Telecommunication Union (http://www.itu.ch)
>
> +.. _h264:
> +
> +ITU-T Rec. H.264 Specification (04/2017 Edition)
> +================================================
> +
> +:title: ITU-T Recommendation H.264 "Advanced Video Coding for Generic Audiovisual Services"
> +
> +:author: International Telecommunication Union (http://www.itu.ch)
> +
> .. _jfif:
>
> JFIF
> diff --git a/Documentation/media/uapi/v4l/ext-ctrls-codec.rst b/Documentation/media/uapi/v4l/ext-ctrls-codec.rst
> index 67a122339c0e..fe720f239f70 100644
> --- a/Documentation/media/uapi/v4l/ext-ctrls-codec.rst
> +++ b/Documentation/media/uapi/v4l/ext-ctrls-codec.rst
> @@ -1371,6 +1371,575 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type -
> - Layer number
>
>
> +.. _v4l2-mpeg-h264:
> +
> +``V4L2_CID_MPEG_VIDEO_H264_SPS (struct)``
> + Specifies the sequence parameter set (as extracted from the
> + bitstream) for the associated H264 slice data. This includes the
> + necessary parameters for configuring a stateless hardware decoding
> + pipeline for H264. The bitstream parameters are defined according
> + to :ref:`h264`, section 7.4.2.1.1 "Sequence Parameter Set Data
> + Semantics". For further documentation, refer to the above
> + specification, unless there is an explicit comment stating
> + otherwise.
> +
> + .. note::
> +
> + This compound control is not yet part of the public kernel API and
> + it is expected to change.
> +
> +.. c:type:: v4l2_ctrl_h264_sps
> +
> +.. cssclass:: longtable
> +
> +.. flat-table:: struct v4l2_ctrl_h264_sps
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - __u8
> + - ``profile_idc``
> + -
> + * - __u8
> + - ``constraint_set_flags``
> + - See :ref:`Sequence Parameter Set Constraints Set Flags <h264_sps_constraints_set_flags>`
> + * - __u8
> + - ``level_idc``
> + -
> + * - __u8
> + - ``seq_parameter_set_id``
> + -
> + * - __u8
> + - ``chroma_format_idc``
> + -
> + * - __u8
> + - ``bit_depth_luma_minus8``
> + -
> + * - __u8
> + - ``bit_depth_chroma_minus8``
> + -
> + * - __u8
> + - ``log2_max_frame_num_minus4``
> + -
> + * - __u8
> + - ``pic_order_cnt_type``
> + -
> + * - __u8
> + - ``log2_max_pic_order_cnt_lsb_minus4``
> + -
> + * - __u8
> + - ``max_num_ref_frames``
> + -
> + * - __u8
> + - ``num_ref_frames_in_pic_order_cnt_cycle``
> + -
> + * - __s32
> + - ``offset_for_ref_frame[255]``
> + -
> + * - __s32
> + - ``offset_for_non_ref_pic``
> + -
> + * - __s32
> + - ``offset_for_top_to_bottom_field``
> + -
> + * - __u16
> + - ``pic_width_in_mbs_minus1``
> + -
> + * - __u16
> + - ``pic_height_in_map_units_minus1``
> + -
> + * - __u32
> + - ``flags``
> + - See :ref:`Sequence Parameter Set Flags <h264_sps_flags>`
> +
> +.. _h264_sps_constraints_set_flags:
> +
> +``Sequence Parameter Set Constraints Set Flags``
> +
> +.. cssclass:: longtable
> +
> +.. flat-table::
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - ``V4L2_H264_SPS_CONSTRAINT_SET0_FLAG``
> + - 0x00000001
> + -
> + * - ``V4L2_H264_SPS_CONSTRAINT_SET1_FLAG``
> + - 0x00000002
> + -
> + * - ``V4L2_H264_SPS_CONSTRAINT_SET2_FLAG``
> + - 0x00000004
> + -
> + * - ``V4L2_H264_SPS_CONSTRAINT_SET3_FLAG``
> + - 0x00000008
> + -
> + * - ``V4L2_H264_SPS_CONSTRAINT_SET4_FLAG``
> + - 0x00000010
> + -
> + * - ``V4L2_H264_SPS_CONSTRAINT_SET5_FLAG``
> + - 0x00000020
> + -
> +
> +.. _h264_sps_flags:
> +
> +``Sequence Parameter Set Flags``
> +
> +.. cssclass:: longtable
> +
> +.. flat-table::
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - ``V4L2_H264_SPS_FLAG_SEPARATE_COLOUR_PLANE``
> + - 0x00000001
> + -
> + * - ``V4L2_H264_SPS_FLAG_QPPRIME_Y_ZERO_TRANSFORM_BYPASS``
> + - 0x00000002
> + -
> + * - ``V4L2_H264_SPS_FLAG_DELTA_PIC_ORDER_ALWAYS_ZERO``
> + - 0x00000004
> + -
> + * - ``V4L2_H264_SPS_FLAG_GAPS_IN_FRAME_NUM_VALUE_ALLOWED``
> + - 0x00000008
> + -
> + * - ``V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY``
> + - 0x00000010
> + -
> + * - ``V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD``
> + - 0x00000020
> + -
> + * - ``V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE``
> + - 0x00000040
> + -
> +
> +``V4L2_CID_MPEG_VIDEO_H264_PPS (struct)``
> + Specifies the picture parameter set (as extracted from the
> + bitstream) for the associated H264 slice data. This includes the
> + necessary parameters for configuring a stateless hardware decoding
> + pipeline for H264. The bitstream parameters are defined according
> + to :ref:`h264`, section 7.4.2.2 "Picture Parameter Set RBSP
> + Semantics". For further documentation, refer to the above
> + specification, unless there is an explicit comment stating
> + otherwise.
> +
> + .. note::
> +
> + This compound control is not yet part of the public kernel API and
> + it is expected to change.
> +
> +.. c:type:: v4l2_ctrl_h264_pps
> +
> +.. cssclass:: longtable
> +
> +.. flat-table:: struct v4l2_ctrl_h264_pps
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - __u8
> + - ``pic_parameter_set_id``
> + -
> + * - __u8
> + - ``seq_parameter_set_id``
> + -
> + * - __u8
> + - ``num_slice_groups_minus1``
> + -
> + * - __u8
> + - ``num_ref_idx_l0_default_active_minus1``
> + -
> + * - __u8
> + - ``num_ref_idx_l1_default_active_minus1``
> + -
> + * - __u8
> + - ``weighted_bipred_idc``
> + -
> + * - __s8
> + - ``pic_init_qp_minus26``
> + -
> + * - __s8
> + - ``pic_init_qs_minus26``
> + -
> + * - __s8
> + - ``chroma_qp_index_offset``
> + -
> + * - __s8
> + - ``second_chroma_qp_index_offset``
> + -
> + * - __u16
> + - ``flags``
> + - See :ref:`Picture Parameter Set Flags <h264_pps_flags>`
> +
> +.. _h264_pps_flags:
> +
> +``Picture Parameter Set Flags``
> +
> +.. cssclass:: longtable
> +
> +.. flat-table::
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - ``V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE``
> + - 0x00000001
> + -
> + * - ``V4L2_H264_PPS_FLAG_BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT``
> + - 0x00000002
> + -
> + * - ``V4L2_H264_PPS_FLAG_WEIGHTED_PRED``
> + - 0x00000004
> + -
> + * - ``V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT``
> + - 0x00000008
> + -
> + * - ``V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED``
> + - 0x00000010
> + -
> + * - ``V4L2_H264_PPS_FLAG_REDUNDANT_PIC_CNT_PRESENT``
> + - 0x00000020
> + -
> + * - ``V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE``
> + - 0x00000040
> + -
> + * - ``V4L2_H264_PPS_FLAG_PIC_SCALING_MATRIX_PRESENT``
> + - 0x00000080
> + -
> +
> +``V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX (struct)``
> + Specifies the scaling matrix (as extracted from the bitstream) for
> + the associated H264 slice data. The bitstream parameters are
> + defined according to :ref:`h264`, section 7.4.2.1.1.1 "Scaling
> + List Semantics".For further documentation, refer to the above
> + specification, unless there is an explicit comment stating
> + otherwise.
> +
> + .. note::
> +
> + This compound control is not yet part of the public kernel API and
> + it is expected to change.
> +
> +.. c:type:: v4l2_ctrl_h264_scaling_matrix
> +
> +.. cssclass:: longtable
> +
> +.. flat-table:: struct v4l2_ctrl_h264_scaling_matrix
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - __u8
> + - ``scaling_list_4x4[6][16]``
> + -
> + * - __u8
> + - ``scaling_list_8x8[6][64]``
> + -
> +
> +``V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS (struct)``
> + Specifies the slice parameters (as extracted from the bitstream)
> + for the associated H264 slice data. This includes the necessary
> + parameters for configuring a stateless hardware decoding pipeline
> + for H264. The bitstream parameters are defined according to
> + :ref:`h264`, section 7.4.3 "Slice Header Semantics". For further
> + documentation, refer to the above specification, unless there is
> + an explicit comment stating otherwise.
> +
> + .. note::
> +
> + This compound control is not yet part of the public kernel API
> + and it is expected to change.
> +
> + This structure is expected to be passed as an array, with one
> + entry for each slice included in the bitstream buffer.
> +
> +.. c:type:: v4l2_ctrl_h264_slice_params
> +
> +.. cssclass:: longtable
> +
> +.. flat-table:: struct v4l2_ctrl_h264_slice_params
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - __u32
> + - ``size``
> + -
> + * - __u32
> + - ``header_bit_size``
> + -
> + * - __u16
> + - ``first_mb_in_slice``
> + -
> + * - __u8
> + - ``slice_type``
> + -
> + * - __u8
> + - ``pic_parameter_set_id``
> + -
> + * - __u8
> + - ``colour_plane_id``
> + -
> + * - __u8
> + - ``redundant_pic_cnt``
> + -
> + * - __u16
> + - ``frame_num``
> + -
> + * - __u16
> + - ``idr_pic_id``
> + -
> + * - __u16
> + - ``pic_order_cnt_lsb``
> + -
> + * - __s32
> + - ``delta_pic_order_cnt_bottom``
> + -
> + * - __s32
> + - ``delta_pic_order_cnt0``
> + -
> + * - __s32
> + - ``delta_pic_order_cnt1``
> + -
> + * - struct :c:type:`v4l2_h264_pred_weight_table`
> + - ``pred_weight_table``
> + -
> + * - __u32
> + - ``dec_ref_pic_marking_bit_size``
> + -
> + * - __u32
> + - ``pic_order_cnt_bit_size``
> + -
> + * - __u8
> + - ``cabac_init_idc``
> + -
> + * - __s8
> + - ``slice_qp_delta``
> + -
> + * - __s8
> + - ``slice_qs_delta``
> + -
> + * - __u8
> + - ``disable_deblocking_filter_idc``
> + -
> + * - __s8
> + - ``slice_alpha_c0_offset_div2``
> + -
> + * - __s8
> + - ``slice_beta_offset_div2``
> + -
> + * - __u8
> + - ``num_ref_idx_l0_active_minus1``
> + -
> + * - __u8
> + - ``num_ref_idx_l1_active_minus1``
> + -
> + * - __u32
> + - ``slice_group_change_cycle``
> + -
> + * - __u8
> + - ``ref_pic_list0[32]``
> + - Reference picture list after applying the per-slice modifications
> + * - __u8
> + - ``ref_pic_list1[32]``
> + - Reference picture list after applying the per-slice modifications
> + * - __u32
> + - ``flags``
> + - See :ref:`Slice Parameter Flags <h264_slice_flags>`
> +
> +.. _h264_slice_flags:
> +
> +``Slice Parameter Set Flags``
> +
> +.. cssclass:: longtable
> +
> +.. flat-table::
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - ``V4L2_H264_SLICE_FLAG_FIELD_PIC``
> + - 0x00000001
> + -
> + * - ``V4L2_H264_SLICE_FLAG_BOTTOM_FIELD``
> + - 0x00000002
> + -
> + * - ``V4L2_H264_SLICE_FLAG_DIRECT_SPATIAL_MV_PRED``
> + - 0x00000004
> + -
> + * - ``V4L2_H264_SLICE_FLAG_SP_FOR_SWITCH``
> + - 0x00000008
> + -
> +
> +``Prediction Weight Table``
> +
> + The bitstream parameters are defined according to :ref:`h264`,
> + section 7.4.3.2 "Prediction Weight Table Semantics". For further
> + documentation, refer to the above specification, unless there is
> + an explicit comment stating otherwise.
> +
> +.. c:type:: v4l2_h264_pred_weight_table
> +
> +.. cssclass:: longtable
> +
> +.. flat-table:: struct v4l2_h264_pred_weight_table
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - __u16
> + - ``luma_log2_weight_denom``
> + -
> + * - __u16
> + - ``chroma_log2_weight_denom``
> + -
> + * - struct :c:type:`v4l2_h264_weight_factors`
> + - ``weight_factors[2]``
> + - The weight factors at index 0 are the weight factors for the reference
> + list 0, the one at index 1 for the reference list 1.
> +
> +.. c:type:: v4l2_h264_weight_factors
> +
> +.. cssclass:: longtable
> +
> +.. flat-table:: struct v4l2_h264_weight_factors
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - __s16
> + - ``luma_weight[32]``
> + -
> + * - __s16
> + - ``luma_offset[32]``
> + -
> + * - __s16
> + - ``chroma_weight[32][2]``
> + -
> + * - __s16
> + - ``chroma_offset[32][2]``
> + -
> +
> +``V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS (struct)``
> + Specifies the decode parameters (as extracted from the bitstream)
> + for the associated H264 slice data. This includes the necessary
> + parameters for configuring a stateless hardware decoding pipeline
> + for H264. The bitstream parameters are defined according to
> + :ref:`h264`. For further documentation, refer to the above
> + specification, unless there is an explicit comment stating
> + otherwise.
> +
> + .. note::
> +
> + This compound control is not yet part of the public kernel API and
> + it is expected to change.
> +
> +.. c:type:: v4l2_ctrl_h264_decode_params
> +
> +.. cssclass:: longtable
> +
> +.. flat-table:: struct v4l2_ctrl_h264_decode_params
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - __u32
> + - ``num_slices``
> + - Number of slices needed to decode the current frame
> + * - __u32
> + - ``nal_ref_idc``
> + - NAL reference ID value coming from the NAL Unit header
> + * - __u8
> + - ``ref_pic_list_p0[32]``
> + - Backward reference list used by P-frames in the original bitstream order
> + * - __u8
> + - ``ref_pic_list_b0[32]``
> + - Backward reference list used by B-frames in the original bitstream order
> + * - __u8
> + - ``ref_pic_list_b1[32]``
> + - Forward reference list used by B-frames in the original bitstream order
> + * - __s32
> + - ``top_field_order_cnt``
> + - Picture Order Count for the coded top field
> + * - __s32
> + - ``bottom_field_order_cnt``
> + - Picture Order Count for the coded bottom field
> + * - __u32
> + - ``flags``
> + - See :ref:`Decode Parameters Flags <h264_decode_params_flags>`
> + * - struct :c:type:`v4l2_h264_dpb_entry`
> + - ``dpb[16]``
> + -
> +
> +.. _h264_decode_params_flags:
> +
> +``Decode Parameters Flags``
> +
> +.. cssclass:: longtable
> +
> +.. flat-table::
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - ``V4L2_H264_DECODE_PARAM_FLAG_IDR_PIC``
> + - 0x00000001
> + - That picture is an IDR picture
> +
> +.. c:type:: v4l2_h264_dpb_entry
> +
> +.. cssclass:: longtable
> +
> +.. flat-table:: struct v4l2_h264_dpb_entry
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - __u64
> + - ``reference_ts``
> + - Timestamp of the V4L2 capture buffer to use as reference, used
> + with B-coded and P-coded frames. The timestamp refers to the
> + ``timestamp`` field in struct :c:type:`v4l2_buffer`. Use the
> + :c:func:`v4l2_timeval_to_ns()` function to convert the struct
> + :c:type:`timeval` in struct :c:type:`v4l2_buffer` to a __u64.
> + * - __u16
> + - ``frame_num``
> + -
> + * - __u16
> + - ``pic_num``
> + -
> + * - __s32
> + - ``top_field_order_cnt``
> + -
> + * - __s32
> + - ``bottom_field_order_cnt``
> + -
> + * - __u32
> + - ``flags``
> + - See :ref:`DPB Entry Flags <h264_dpb_flags>`
> +
> +.. _h264_dpb_flags:
> +
> +``DPB Entries Flags``
> +
> +.. cssclass:: longtable
> +
> +.. flat-table::
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - ``V4L2_H264_DPB_ENTRY_FLAG_VALID``
> + - 0x00000001
> + - The DPB entry is valid and should be considered
> + * - ``V4L2_H264_DPB_ENTRY_FLAG_ACTIVE``
> + - 0x00000002
> + - The DPB entry is currently being used as a reference frame
> + * - ``V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM``
> + - 0x00000004
> + - The DPB entry is a long term reference frame
>
> .. _v4l2-mpeg-mpeg2:
>
> diff --git a/Documentation/media/uapi/v4l/pixfmt-compressed.rst b/Documentation/media/uapi/v4l/pixfmt-compressed.rst
> index 6c961cfb74da..ea0a8a68759b 100644
> --- a/Documentation/media/uapi/v4l/pixfmt-compressed.rst
> +++ b/Documentation/media/uapi/v4l/pixfmt-compressed.rst
> @@ -52,6 +52,25 @@ Compressed Formats
> - ``V4L2_PIX_FMT_H264_MVC``
> - 'M264'
> - H264 MVC video elementary stream.
> + * .. _V4L2-PIX-FMT-H264-SLICE:
> +
> + - ``V4L2_PIX_FMT_H264_SLICE_RAW``
> + - 'S264'
> + - H264 parsed slice data, as extracted from the H264 bitstream.
> + This format is adapted for stateless video decoders that
> + implement an H264 pipeline (using the :ref:`codec` and
> + :ref:`media-request-api`). Metadata associated with the frame
> + to decode are required to be passed through the
> + ``V4L2_CID_MPEG_VIDEO_H264_SPS``,
> + ``V4L2_CID_MPEG_VIDEO_H264_PPS``,
> + ``V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX``,
> + ``V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS`` and
> + ``V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS`` controls. See the
> + :ref:`associated Codec Control IDs <v4l2-mpeg-h264>`.
> + Exactly one output and one capture buffer must be provided for
> + use with this pixel format. The output buffer must contain the
> + appropriate number of macroblocks to decode a full
> + corresponding frame to the matching capture buffer.
> * .. _V4L2-PIX-FMT-H263:
>
> - ``V4L2_PIX_FMT_H263``
> diff --git a/Documentation/media/uapi/v4l/vidioc-queryctrl.rst b/Documentation/media/uapi/v4l/vidioc-queryctrl.rst
> index f824162d0ea9..dc500632095d 100644
> --- a/Documentation/media/uapi/v4l/vidioc-queryctrl.rst
> +++ b/Documentation/media/uapi/v4l/vidioc-queryctrl.rst
> @@ -443,6 +443,36 @@ See also the examples in :ref:`control`.
> - n/a
> - A struct :c:type:`v4l2_ctrl_mpeg2_quantization`, containing MPEG-2
> quantization matrices for stateless video decoders.
> + * - ``V4L2_CTRL_TYPE_H264_SPS``
> + - n/a
> + - n/a
> + - n/a
> + - A struct :c:type:`v4l2_ctrl_h264_sps`, containing H264
> + sequence parameters for stateless video decoders.
> + * - ``V4L2_CTRL_TYPE_H264_PPS``
> + - n/a
> + - n/a
> + - n/a
> + - A struct :c:type:`v4l2_ctrl_h264_pps`, containing H264
> + picture parameters for stateless video decoders.
> + * - ``V4L2_CTRL_TYPE_H264_SCALING_MATRIX``
> + - n/a
> + - n/a
> + - n/a
> + - A struct :c:type:`v4l2_ctrl_h264_scaling_matrix`, containing H264
> + scaling matrices for stateless video decoders.
> + * - ``V4L2_CTRL_TYPE_H264_SLICE_PARAMS``
> + - n/a
> + - n/a
> + - n/a
> + - A struct :c:type:`v4l2_ctrl_h264_slice_params`, containing H264
> + slice parameters for stateless video decoders.
> + * - ``V4L2_CTRL_TYPE_H264_DECODE_PARAMS``
> + - n/a
> + - n/a
> + - n/a
> + - A struct :c:type:`v4l2_ctrl_h264_decode_params`, containing H264
> + decode parameters for stateless video decoders.
>
> .. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
>
> diff --git a/Documentation/media/videodev2.h.rst.exceptions b/Documentation/media/videodev2.h.rst.exceptions
> index 64d348e67df9..55cbe324b9fc 100644
> --- a/Documentation/media/videodev2.h.rst.exceptions
> +++ b/Documentation/media/videodev2.h.rst.exceptions
> @@ -136,6 +136,11 @@ replace symbol V4L2_CTRL_TYPE_U32 :c:type:`v4l2_ctrl_type`
> replace symbol V4L2_CTRL_TYPE_U8 :c:type:`v4l2_ctrl_type`
> replace symbol V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS :c:type:`v4l2_ctrl_type`
> replace symbol V4L2_CTRL_TYPE_MPEG2_QUANTIZATION :c:type:`v4l2_ctrl_type`
> +replace symbol V4L2_CTRL_TYPE_H264_SPS :c:type:`v4l2_ctrl_type`
> +replace symbol V4L2_CTRL_TYPE_H264_PPS :c:type:`v4l2_ctrl_type`
> +replace symbol V4L2_CTRL_TYPE_H264_SCALING_MATRIX :c:type:`v4l2_ctrl_type`
> +replace symbol V4L2_CTRL_TYPE_H264_SLICE_PARAMS :c:type:`v4l2_ctrl_type`
> +replace symbol V4L2_CTRL_TYPE_H264_DECODE_PARAMS :c:type:`v4l2_ctrl_type`
>
> # V4L2 capability defines
> replace define V4L2_CAP_VIDEO_CAPTURE device-capabilities
> diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
> index b1ae2e555c68..46aec8c3acde 100644
> --- a/drivers/media/v4l2-core/v4l2-ctrls.c
> +++ b/drivers/media/v4l2-core/v4l2-ctrls.c
> @@ -828,6 +828,11 @@ const char *v4l2_ctrl_get_name(u32 id)
> case V4L2_CID_MPEG_VIDEO_H264_CONSTRAINED_INTRA_PREDICTION:
> return "H264 Constrained Intra Pred";
> case V4L2_CID_MPEG_VIDEO_H264_CHROMA_QP_INDEX_OFFSET: return "H264 Chroma QP Index Offset";
> + case V4L2_CID_MPEG_VIDEO_H264_SPS: return "H264 Sequence Parameter Set";
> + case V4L2_CID_MPEG_VIDEO_H264_PPS: return "H264 Picture Parameter Set";
> + case V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX: return "H264 Scaling Matrix";
> + case V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS: return "H264 Slice Parameters";
> + case V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS: return "H264 Decode Parameters";
> case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP: return "MPEG4 I-Frame QP Value";
> case V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP: return "MPEG4 P-Frame QP Value";
> case V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP: return "MPEG4 B-Frame QP Value";
> @@ -1309,6 +1314,21 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
> case V4L2_CID_MPEG_VIDEO_FWHT_PARAMS:
> *type = V4L2_CTRL_TYPE_FWHT_PARAMS;
> break;
> + case V4L2_CID_MPEG_VIDEO_H264_SPS:
> + *type = V4L2_CTRL_TYPE_H264_SPS;
> + break;
> + case V4L2_CID_MPEG_VIDEO_H264_PPS:
> + *type = V4L2_CTRL_TYPE_H264_PPS;
> + break;
> + case V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX:
> + *type = V4L2_CTRL_TYPE_H264_SCALING_MATRIX;
> + break;
> + case V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS:
> + *type = V4L2_CTRL_TYPE_H264_SLICE_PARAMS;
> + break;
> + case V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS:
> + *type = V4L2_CTRL_TYPE_H264_DECODE_PARAMS;
> + break;
> default:
> *type = V4L2_CTRL_TYPE_INTEGER;
> break;
> @@ -1678,6 +1698,13 @@ static int std_validate(const struct v4l2_ctrl *ctrl, u32 idx,
> case V4L2_CTRL_TYPE_FWHT_PARAMS:
> return 0;
>
> + case V4L2_CTRL_TYPE_H264_SPS:
> + case V4L2_CTRL_TYPE_H264_PPS:
> + case V4L2_CTRL_TYPE_H264_SCALING_MATRIX:
> + case V4L2_CTRL_TYPE_H264_SLICE_PARAMS:
> + case V4L2_CTRL_TYPE_H264_DECODE_PARAMS:
> + return 0;
> +
> default:
> return -EINVAL;
> }
> @@ -2261,6 +2288,21 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
> case V4L2_CTRL_TYPE_FWHT_PARAMS:
> elem_size = sizeof(struct v4l2_ctrl_fwht_params);
> break;
> + case V4L2_CTRL_TYPE_H264_SPS:
> + elem_size = sizeof(struct v4l2_ctrl_h264_sps);
> + break;
> + case V4L2_CTRL_TYPE_H264_PPS:
> + elem_size = sizeof(struct v4l2_ctrl_h264_pps);
> + break;
> + case V4L2_CTRL_TYPE_H264_SCALING_MATRIX:
> + elem_size = sizeof(struct v4l2_ctrl_h264_scaling_matrix);
> + break;
> + case V4L2_CTRL_TYPE_H264_SLICE_PARAMS:
> + elem_size = sizeof(struct v4l2_ctrl_h264_slice_params);
> + break;
> + case V4L2_CTRL_TYPE_H264_DECODE_PARAMS:
> + elem_size = sizeof(struct v4l2_ctrl_h264_decode_params);
> + break;
> default:
> if (type < V4L2_CTRL_COMPOUND_TYPES)
> elem_size = sizeof(s32);
> diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
> index ac87c3e37280..f6e1254064d2 100644
> --- a/drivers/media/v4l2-core/v4l2-ioctl.c
> +++ b/drivers/media/v4l2-core/v4l2-ioctl.c
> @@ -1325,6 +1325,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
> case V4L2_PIX_FMT_H264: descr = "H.264"; break;
> case V4L2_PIX_FMT_H264_NO_SC: descr = "H.264 (No Start Codes)"; break;
> case V4L2_PIX_FMT_H264_MVC: descr = "H.264 MVC"; break;
> + case V4L2_PIX_FMT_H264_SLICE_RAW: descr = "H.264 Parsed Slice Data"; break;
> case V4L2_PIX_FMT_H263: descr = "H.263"; break;
> case V4L2_PIX_FMT_MPEG1: descr = "MPEG-1 ES"; break;
> case V4L2_PIX_FMT_MPEG2: descr = "MPEG-2 ES"; break;
> diff --git a/include/media/h264-ctrls.h b/include/media/h264-ctrls.h
> new file mode 100644
> index 000000000000..e2f83b3cdbef
> --- /dev/null
> +++ b/include/media/h264-ctrls.h
> @@ -0,0 +1,192 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * These are the H.264 state controls for use with stateless H.264
> + * codec drivers.
> + *
> + * It turns out that these structs are not stable yet and will undergo
> + * more changes. So keep them private until they are stable and ready to
> + * become part of the official public API.
> + */
> +
> +#ifndef _H264_CTRLS_H_
> +#define _H264_CTRLS_H_
> +
> +/*
> + * This is put insanely high to avoid conflicting with controls that
> + * would be added during the phase where those controls are not
> + * stable. It should be fixed eventually.
> + */
> +#define V4L2_CID_MPEG_VIDEO_H264_SPS (V4L2_CID_MPEG_BASE+1000)
> +#define V4L2_CID_MPEG_VIDEO_H264_PPS (V4L2_CID_MPEG_BASE+1001)
> +#define V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX (V4L2_CID_MPEG_BASE+1002)
> +#define V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS (V4L2_CID_MPEG_BASE+1003)
> +#define V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS (V4L2_CID_MPEG_BASE+1004)
> +
> +/* enum v4l2_ctrl_type type values */
> +#define V4L2_CTRL_TYPE_H264_SPS 0x0110
> +#define V4L2_CTRL_TYPE_H264_PPS 0x0111
> +#define V4L2_CTRL_TYPE_H264_SCALING_MATRIX 0x0112
> +#define V4L2_CTRL_TYPE_H264_SLICE_PARAMS 0x0113
> +#define V4L2_CTRL_TYPE_H264_DECODE_PARAMS 0x0114
> +
> +#define V4L2_H264_SPS_CONSTRAINT_SET0_FLAG 0x01
> +#define V4L2_H264_SPS_CONSTRAINT_SET1_FLAG 0x02
> +#define V4L2_H264_SPS_CONSTRAINT_SET2_FLAG 0x04
> +#define V4L2_H264_SPS_CONSTRAINT_SET3_FLAG 0x08
> +#define V4L2_H264_SPS_CONSTRAINT_SET4_FLAG 0x10
> +#define V4L2_H264_SPS_CONSTRAINT_SET5_FLAG 0x20
> +
> +#define V4L2_H264_SPS_FLAG_SEPARATE_COLOUR_PLANE 0x01
> +#define V4L2_H264_SPS_FLAG_QPPRIME_Y_ZERO_TRANSFORM_BYPASS 0x02
> +#define V4L2_H264_SPS_FLAG_DELTA_PIC_ORDER_ALWAYS_ZERO 0x04
> +#define V4L2_H264_SPS_FLAG_GAPS_IN_FRAME_NUM_VALUE_ALLOWED 0x08
> +#define V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY 0x10
> +#define V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD 0x20
> +#define V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE 0x40
> +
> +struct v4l2_ctrl_h264_sps {
> + __u8 profile_idc;
> + __u8 constraint_set_flags;
> + __u8 level_idc;
> + __u8 seq_parameter_set_id;
> + __u8 chroma_format_idc;
> + __u8 bit_depth_luma_minus8;
> + __u8 bit_depth_chroma_minus8;
> + __u8 log2_max_frame_num_minus4;
> + __u8 pic_order_cnt_type;
> + __u8 log2_max_pic_order_cnt_lsb_minus4;
> + __u8 max_num_ref_frames;
> + __u8 num_ref_frames_in_pic_order_cnt_cycle;
> + __s32 offset_for_ref_frame[255];
> + __s32 offset_for_non_ref_pic;
> + __s32 offset_for_top_to_bottom_field;
> + __u16 pic_width_in_mbs_minus1;
> + __u16 pic_height_in_map_units_minus1;
> + __u32 flags;
> +};
> +
> +#define V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE 0x0001
> +#define V4L2_H264_PPS_FLAG_BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT 0x0002
> +#define V4L2_H264_PPS_FLAG_WEIGHTED_PRED 0x0004
> +#define V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT 0x0008
> +#define V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED 0x0010
> +#define V4L2_H264_PPS_FLAG_REDUNDANT_PIC_CNT_PRESENT 0x0020
> +#define V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE 0x0040
> +#define V4L2_H264_PPS_FLAG_PIC_SCALING_MATRIX_PRESENT 0x0080
> +
> +struct v4l2_ctrl_h264_pps {
> + __u8 pic_parameter_set_id;
> + __u8 seq_parameter_set_id;
> + __u8 num_slice_groups_minus1;
> + __u8 num_ref_idx_l0_default_active_minus1;
> + __u8 num_ref_idx_l1_default_active_minus1;
> + __u8 weighted_bipred_idc;
> + __s8 pic_init_qp_minus26;
> + __s8 pic_init_qs_minus26;
> + __s8 chroma_qp_index_offset;
> + __s8 second_chroma_qp_index_offset;
> + __u16 flags;
> +};
> +
> +struct v4l2_ctrl_h264_scaling_matrix {
> + __u8 scaling_list_4x4[6][16];
> + __u8 scaling_list_8x8[6][64];
> +};
> +
> +struct v4l2_h264_weight_factors {
> + __s16 luma_weight[32];
> + __s16 luma_offset[32];
> + __s16 chroma_weight[32][2];
> + __s16 chroma_offset[32][2];
> +};
> +
> +struct v4l2_h264_pred_weight_table {
> + __u16 luma_log2_weight_denom;
> + __u16 chroma_log2_weight_denom;
> + struct v4l2_h264_weight_factors weight_factors[2];
> +};
> +
> +#define V4L2_H264_SLICE_TYPE_P 0
> +#define V4L2_H264_SLICE_TYPE_B 1
> +#define V4L2_H264_SLICE_TYPE_I 2
> +#define V4L2_H264_SLICE_TYPE_SP 3
> +#define V4L2_H264_SLICE_TYPE_SI 4
> +
> +#define V4L2_H264_SLICE_FLAG_FIELD_PIC 0x01
> +#define V4L2_H264_SLICE_FLAG_BOTTOM_FIELD 0x02
> +#define V4L2_H264_SLICE_FLAG_DIRECT_SPATIAL_MV_PRED 0x04
> +#define V4L2_H264_SLICE_FLAG_SP_FOR_SWITCH 0x08
> +
> +struct v4l2_ctrl_h264_slice_params {
> + /* Size in bytes, including header */
> + __u32 size;
> + /* Offset in bits to slice_data() from the beginning of this slice. */
> + __u32 header_bit_size;
> +
> + __u16 first_mb_in_slice;
> + __u8 slice_type;
> + __u8 pic_parameter_set_id;
> + __u8 colour_plane_id;
> + __u8 redundant_pic_cnt;
> + __u16 frame_num;
> + __u16 idr_pic_id;
> + __u16 pic_order_cnt_lsb;
> + __s32 delta_pic_order_cnt_bottom;
> + __s32 delta_pic_order_cnt0;
> + __s32 delta_pic_order_cnt1;
> +
> + struct v4l2_h264_pred_weight_table pred_weight_table;
> + /* Size in bits of dec_ref_pic_marking() syntax element. */
> + __u32 dec_ref_pic_marking_bit_size;
> + /* Size in bits of pic order count syntax. */
> + __u32 pic_order_cnt_bit_size;
> +
> + __u8 cabac_init_idc;
> + __s8 slice_qp_delta;
> + __s8 slice_qs_delta;
> + __u8 disable_deblocking_filter_idc;
> + __s8 slice_alpha_c0_offset_div2;
> + __s8 slice_beta_offset_div2;
> + __u8 num_ref_idx_l0_active_minus1;
> + __u8 num_ref_idx_l1_active_minus1;
> + __u32 slice_group_change_cycle;
> +
> + /*
> + * Entries on each list are indices into
> + * v4l2_ctrl_h264_decode_params.dpb[].
> + */
> + __u8 ref_pic_list0[32];
> + __u8 ref_pic_list1[32];
> +
> + __u32 flags;
> +};
> +
> +#define V4L2_H264_DPB_ENTRY_FLAG_VALID 0x01
> +#define V4L2_H264_DPB_ENTRY_FLAG_ACTIVE 0x02
> +#define V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM 0x04
> +
> +struct v4l2_h264_dpb_entry {
> + __u64 reference_ts;
> + __u16 frame_num;
> + __u16 pic_num;
> + /* Note that field is indicated by v4l2_buffer.field */
> + __s32 top_field_order_cnt;
> + __s32 bottom_field_order_cnt;
> + __u32 flags; /* V4L2_H264_DPB_ENTRY_FLAG_* */
> +};
> +
> +#define V4L2_H264_DECODE_PARAM_FLAG_IDR_PIC 0x01
> +
> +struct v4l2_ctrl_h264_decode_params {
> + struct v4l2_h264_dpb_entry dpb[16];
> + __u16 num_slices;
> + __u16 nal_ref_idc;
> + __u8 ref_pic_list_p0[32];
> + __u8 ref_pic_list_b0[32];
> + __u8 ref_pic_list_b1[32];
> + __s32 top_field_order_cnt;
> + __s32 bottom_field_order_cnt;
> + __u32 flags; /* V4L2_H264_DECODE_PARAM_FLAG_* */
> +};
> +
> +#endif
> diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
> index bd621cec65a5..dce6f33fd749 100644
> --- a/include/media/v4l2-ctrls.h
> +++ b/include/media/v4l2-ctrls.h
> @@ -23,11 +23,12 @@
> #include <media/media-request.h>
>
> /*
> - * Include the mpeg2 and fwht stateless codec compound control definitions.
> + * Include the stateless codec compound control definitions.
> * This will move to the public headers once this API is fully stable.
> */
> #include <media/mpeg2-ctrls.h>
> #include <media/fwht-ctrls.h>
> +#include <media/h264-ctrls.h>
>
> /* forward references */
> struct file;
> @@ -51,6 +52,11 @@ struct poll_table_struct;
> * @p_mpeg2_slice_params: Pointer to a MPEG2 slice parameters structure.
> * @p_mpeg2_quantization: Pointer to a MPEG2 quantization data structure.
> * @p_fwht_params: Pointer to a FWHT stateless parameters structure.
> + * @p_h264_sps: Pointer to a struct v4l2_ctrl_h264_sps.
> + * @p_h264_pps: Pointer to a struct v4l2_ctrl_h264_pps.
> + * @p_h264_scaling_matrix: Pointer to a struct v4l2_ctrl_h264_scaling_matrix.
> + * @p_h264_slice_param: Pointer to a struct v4l2_ctrl_h264_slice_params.
> + * @p_h264_decode_param: Pointer to a struct v4l2_ctrl_h264_decode_params.
> * @p: Pointer to a compound value.
> */
> union v4l2_ctrl_ptr {
> @@ -63,6 +69,11 @@ union v4l2_ctrl_ptr {
> struct v4l2_ctrl_mpeg2_slice_params *p_mpeg2_slice_params;
> struct v4l2_ctrl_mpeg2_quantization *p_mpeg2_quantization;
> struct v4l2_ctrl_fwht_params *p_fwht_params;
> + struct v4l2_ctrl_h264_sps *p_h264_sps;
> + struct v4l2_ctrl_h264_pps *p_h264_pps;
> + struct v4l2_ctrl_h264_scaling_matrix *p_h264_scaling_matrix;
> + struct v4l2_ctrl_h264_slice_params *p_h264_slice_param;
> + struct v4l2_ctrl_h264_decode_params *p_h264_decode_param;
> void *p;
> };
>
> diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
> index 496e6453450c..838732acdefc 100644
> --- a/include/uapi/linux/videodev2.h
> +++ b/include/uapi/linux/videodev2.h
> @@ -657,6 +657,7 @@ struct v4l2_pix_format {
> #define V4L2_PIX_FMT_H264 v4l2_fourcc('H', '2', '6', '4') /* H264 with start codes */
> #define V4L2_PIX_FMT_H264_NO_SC v4l2_fourcc('A', 'V', 'C', '1') /* H264 without start codes */
> #define V4L2_PIX_FMT_H264_MVC v4l2_fourcc('M', '2', '6', '4') /* H264 MVC */
> +#define V4L2_PIX_FMT_H264_SLICE_RAW v4l2_fourcc('S', '2', '6', '4') /* H264 parsed slices */
> #define V4L2_PIX_FMT_H263 v4l2_fourcc('H', '2', '6', '3') /* H263 */
> #define V4L2_PIX_FMT_MPEG1 v4l2_fourcc('M', 'P', 'G', '1') /* MPEG-1 ES */
> #define V4L2_PIX_FMT_MPEG2 v4l2_fourcc('M', 'P', 'G', '2') /* MPEG-2 ES */
--
Paul Kocialkowski, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com
^ permalink raw reply
* Re: [PATCH 07/10] media: coda: limit frame interval enumeration to supported frame sizes
From: Hans Verkuil @ 2019-04-10 13:43 UTC (permalink / raw)
To: Philipp Zabel, linux-media; +Cc: kernel
In-Reply-To: <20190408123256.22868-7-p.zabel@pengutronix.de>
On 4/8/19 2:32 PM, Philipp Zabel wrote:
> Let VIDIOC_ENUM_FRAMEINTERVALS return -EINVAL if userspace queries
> frame intervals for unsupported frame sizes.
>
> Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
> ---
> drivers/media/platform/coda/coda-common.c | 33 ++++++++++++++++++-----
> 1 file changed, 27 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c
> index 943f003c26c4..2966eb1c4d2d 100644
> --- a/drivers/media/platform/coda/coda-common.c
> +++ b/drivers/media/platform/coda/coda-common.c
> @@ -1117,7 +1117,8 @@ static int coda_enum_frameintervals(struct file *file, void *fh,
> struct v4l2_frmivalenum *f)
> {
> struct coda_ctx *ctx = fh_to_ctx(fh);
> - int i;
> + struct coda_q_data *q_data;
> + const struct coda_codec *codec;
>
> if (f->index)
> return -EINVAL;
> @@ -1126,12 +1127,32 @@ static int coda_enum_frameintervals(struct file *file, void *fh,
> if (!ctx->vdoa && f->pixel_format == V4L2_PIX_FMT_YUYV)
> return -EINVAL;
>
> - for (i = 0; i < CODA_MAX_FORMATS; i++) {
> - if (f->pixel_format == ctx->cvd->src_formats[i] ||
> - f->pixel_format == ctx->cvd->dst_formats[i])
> - break;
> + if (ctx->inst_type == CODA_INST_ENCODER) {
> + if (coda_format_normalize_yuv(f->pixel_format) ==
> + V4L2_PIX_FMT_YUV420) {
> + q_data = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
> + codec = coda_find_codec(ctx->dev, f->pixel_format,
> + q_data->fourcc);
> + } else {
> + codec = coda_find_codec(ctx->dev, V4L2_PIX_FMT_YUV420,
> + f->pixel_format);
> + }
> + } else {
> + if (coda_format_normalize_yuv(f->pixel_format) ==
> + V4L2_PIX_FMT_YUV420) {
> + q_data = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
> + codec = coda_find_codec(ctx->dev, q_data->fourcc,
> + f->pixel_format);
> + } else {
> + codec = coda_find_codec(ctx->dev, f->pixel_format,
> + V4L2_PIX_FMT_YUV420);
> + }
> }
> - if (i == CODA_MAX_FORMATS)
> + if (!codec)
> + return -EINVAL;
> +
> + if (f->width < MIN_W || f->width > codec->max_w ||
> + f->height < MIN_H || f->height > codec->max_h)
> return -EINVAL;
>
> f->type = V4L2_FRMIVAL_TYPE_CONTINUOUS;
>
Why support VIDIOC_ENUM_FRAMEINTERVALS at all? It makes no sense for a codec.
I'd remove it altogether.
Regards,
Hans
^ permalink raw reply
* Re: [PATCH v8 1/2] media: uapi: Add H264 low-level decoder API compound controls.
From: Hans Verkuil @ 2019-04-10 13:30 UTC (permalink / raw)
To: Maxime Ripard, hans.verkuil, acourbot, sakari.ailus,
Laurent Pinchart
Cc: tfiga, posciak, Paul Kocialkowski, Chen-Yu Tsai, linux-kernel,
linux-arm-kernel, linux-media, nicolas.dufresne, jenskuske,
jernej.skrabec, jonas, ezequiel, linux-sunxi, Thomas Petazzoni,
Guenter Roeck
In-Reply-To: <f537c99d8b5a974f8687f4f0d018c025a4220f7a.1554382670.git-series.maxime.ripard@bootlin.com>
On 4/4/19 2:59 PM, Maxime Ripard wrote:
> From: Pawel Osciak <posciak@chromium.org>
>
> Stateless video codecs will require both the H264 metadata and slices in
> order to be able to decode frames.
>
> This introduces the definitions for a new pixel format for H264 slices that
> have been parsed, as well as the structures used to pass the metadata from
> the userspace to the kernel.
>
> Reviewed-by: Tomasz Figa <tfiga@chromium.org>
> Signed-off-by: Pawel Osciak <posciak@chromium.org>
> Signed-off-by: Guenter Roeck <groeck@chromium.org>
> Co-developed-by: Maxime Ripard <maxime.ripard@bootlin.com>
> Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
> ---
> Documentation/media/uapi/v4l/biblio.rst | 9 +-
> Documentation/media/uapi/v4l/ext-ctrls-codec.rst | 569 ++++++++++++++-
> Documentation/media/uapi/v4l/pixfmt-compressed.rst | 19 +-
> Documentation/media/uapi/v4l/vidioc-queryctrl.rst | 30 +-
> Documentation/media/videodev2.h.rst.exceptions | 5 +-
> drivers/media/v4l2-core/v4l2-ctrls.c | 42 +-
> drivers/media/v4l2-core/v4l2-ioctl.c | 1 +-
> include/media/h264-ctrls.h | 192 +++++-
> include/media/v4l2-ctrls.h | 13 +-
> include/uapi/linux/videodev2.h | 1 +-
> 10 files changed, 880 insertions(+), 1 deletion(-)
> create mode 100644 include/media/h264-ctrls.h
>
> diff --git a/Documentation/media/uapi/v4l/biblio.rst b/Documentation/media/uapi/v4l/biblio.rst
> index ec33768c055e..8f4eb8823d82 100644
> --- a/Documentation/media/uapi/v4l/biblio.rst
> +++ b/Documentation/media/uapi/v4l/biblio.rst
> @@ -122,6 +122,15 @@ ITU BT.1119
>
> :author: International Telecommunication Union (http://www.itu.ch)
>
> +.. _h264:
> +
> +ITU-T Rec. H.264 Specification (04/2017 Edition)
> +================================================
> +
> +:title: ITU-T Recommendation H.264 "Advanced Video Coding for Generic Audiovisual Services"
> +
> +:author: International Telecommunication Union (http://www.itu.ch)
> +
> .. _jfif:
>
> JFIF
> diff --git a/Documentation/media/uapi/v4l/ext-ctrls-codec.rst b/Documentation/media/uapi/v4l/ext-ctrls-codec.rst
> index 67a122339c0e..fe720f239f70 100644
> --- a/Documentation/media/uapi/v4l/ext-ctrls-codec.rst
> +++ b/Documentation/media/uapi/v4l/ext-ctrls-codec.rst
> @@ -1371,6 +1371,575 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type -
> - Layer number
>
>
> +.. _v4l2-mpeg-h264:
> +
> +``V4L2_CID_MPEG_VIDEO_H264_SPS (struct)``
> + Specifies the sequence parameter set (as extracted from the
> + bitstream) for the associated H264 slice data. This includes the
> + necessary parameters for configuring a stateless hardware decoding
> + pipeline for H264. The bitstream parameters are defined according
> + to :ref:`h264`, section 7.4.2.1.1 "Sequence Parameter Set Data
> + Semantics". For further documentation, refer to the above
> + specification, unless there is an explicit comment stating
> + otherwise.
> +
> + .. note::
> +
> + This compound control is not yet part of the public kernel API and
> + it is expected to change.
> +
> +.. c:type:: v4l2_ctrl_h264_sps
> +
> +.. cssclass:: longtable
> +
> +.. flat-table:: struct v4l2_ctrl_h264_sps
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - __u8
> + - ``profile_idc``
> + -
> + * - __u8
> + - ``constraint_set_flags``
> + - See :ref:`Sequence Parameter Set Constraints Set Flags <h264_sps_constraints_set_flags>`
> + * - __u8
> + - ``level_idc``
> + -
> + * - __u8
> + - ``seq_parameter_set_id``
> + -
> + * - __u8
> + - ``chroma_format_idc``
> + -
> + * - __u8
> + - ``bit_depth_luma_minus8``
> + -
> + * - __u8
> + - ``bit_depth_chroma_minus8``
> + -
> + * - __u8
> + - ``log2_max_frame_num_minus4``
> + -
> + * - __u8
> + - ``pic_order_cnt_type``
> + -
> + * - __u8
> + - ``log2_max_pic_order_cnt_lsb_minus4``
> + -
> + * - __u8
> + - ``max_num_ref_frames``
> + -
> + * - __u8
> + - ``num_ref_frames_in_pic_order_cnt_cycle``
> + -
> + * - __s32
> + - ``offset_for_ref_frame[255]``
> + -
> + * - __s32
> + - ``offset_for_non_ref_pic``
> + -
> + * - __s32
> + - ``offset_for_top_to_bottom_field``
> + -
> + * - __u16
> + - ``pic_width_in_mbs_minus1``
> + -
> + * - __u16
> + - ``pic_height_in_map_units_minus1``
> + -
> + * - __u32
> + - ``flags``
> + - See :ref:`Sequence Parameter Set Flags <h264_sps_flags>`
> +
> +.. _h264_sps_constraints_set_flags:
> +
> +``Sequence Parameter Set Constraints Set Flags``
> +
> +.. cssclass:: longtable
> +
> +.. flat-table::
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - ``V4L2_H264_SPS_CONSTRAINT_SET0_FLAG``
> + - 0x00000001
> + -
> + * - ``V4L2_H264_SPS_CONSTRAINT_SET1_FLAG``
> + - 0x00000002
> + -
> + * - ``V4L2_H264_SPS_CONSTRAINT_SET2_FLAG``
> + - 0x00000004
> + -
> + * - ``V4L2_H264_SPS_CONSTRAINT_SET3_FLAG``
> + - 0x00000008
> + -
> + * - ``V4L2_H264_SPS_CONSTRAINT_SET4_FLAG``
> + - 0x00000010
> + -
> + * - ``V4L2_H264_SPS_CONSTRAINT_SET5_FLAG``
> + - 0x00000020
> + -
> +
> +.. _h264_sps_flags:
> +
> +``Sequence Parameter Set Flags``
> +
> +.. cssclass:: longtable
> +
> +.. flat-table::
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - ``V4L2_H264_SPS_FLAG_SEPARATE_COLOUR_PLANE``
> + - 0x00000001
> + -
> + * - ``V4L2_H264_SPS_FLAG_QPPRIME_Y_ZERO_TRANSFORM_BYPASS``
> + - 0x00000002
> + -
> + * - ``V4L2_H264_SPS_FLAG_DELTA_PIC_ORDER_ALWAYS_ZERO``
> + - 0x00000004
> + -
> + * - ``V4L2_H264_SPS_FLAG_GAPS_IN_FRAME_NUM_VALUE_ALLOWED``
> + - 0x00000008
> + -
> + * - ``V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY``
> + - 0x00000010
> + -
> + * - ``V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD``
> + - 0x00000020
> + -
> + * - ``V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE``
> + - 0x00000040
> + -
> +
> +``V4L2_CID_MPEG_VIDEO_H264_PPS (struct)``
> + Specifies the picture parameter set (as extracted from the
> + bitstream) for the associated H264 slice data. This includes the
> + necessary parameters for configuring a stateless hardware decoding
> + pipeline for H264. The bitstream parameters are defined according
> + to :ref:`h264`, section 7.4.2.2 "Picture Parameter Set RBSP
> + Semantics". For further documentation, refer to the above
> + specification, unless there is an explicit comment stating
> + otherwise.
> +
> + .. note::
> +
> + This compound control is not yet part of the public kernel API and
> + it is expected to change.
> +
> +.. c:type:: v4l2_ctrl_h264_pps
> +
> +.. cssclass:: longtable
> +
> +.. flat-table:: struct v4l2_ctrl_h264_pps
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - __u8
> + - ``pic_parameter_set_id``
> + -
> + * - __u8
> + - ``seq_parameter_set_id``
> + -
> + * - __u8
> + - ``num_slice_groups_minus1``
> + -
> + * - __u8
> + - ``num_ref_idx_l0_default_active_minus1``
> + -
> + * - __u8
> + - ``num_ref_idx_l1_default_active_minus1``
> + -
> + * - __u8
> + - ``weighted_bipred_idc``
> + -
> + * - __s8
> + - ``pic_init_qp_minus26``
> + -
> + * - __s8
> + - ``pic_init_qs_minus26``
> + -
> + * - __s8
> + - ``chroma_qp_index_offset``
> + -
> + * - __s8
> + - ``second_chroma_qp_index_offset``
> + -
> + * - __u16
> + - ``flags``
> + - See :ref:`Picture Parameter Set Flags <h264_pps_flags>`
> +
> +.. _h264_pps_flags:
> +
> +``Picture Parameter Set Flags``
> +
> +.. cssclass:: longtable
> +
> +.. flat-table::
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - ``V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE``
> + - 0x00000001
> + -
> + * - ``V4L2_H264_PPS_FLAG_BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT``
> + - 0x00000002
> + -
> + * - ``V4L2_H264_PPS_FLAG_WEIGHTED_PRED``
> + - 0x00000004
> + -
> + * - ``V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT``
> + - 0x00000008
> + -
> + * - ``V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED``
> + - 0x00000010
> + -
> + * - ``V4L2_H264_PPS_FLAG_REDUNDANT_PIC_CNT_PRESENT``
> + - 0x00000020
> + -
> + * - ``V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE``
> + - 0x00000040
> + -
> + * - ``V4L2_H264_PPS_FLAG_PIC_SCALING_MATRIX_PRESENT``
> + - 0x00000080
> + -
> +
> +``V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX (struct)``
> + Specifies the scaling matrix (as extracted from the bitstream) for
> + the associated H264 slice data. The bitstream parameters are
> + defined according to :ref:`h264`, section 7.4.2.1.1.1 "Scaling
> + List Semantics".For further documentation, refer to the above
> + specification, unless there is an explicit comment stating
> + otherwise.
> +
> + .. note::
> +
> + This compound control is not yet part of the public kernel API and
> + it is expected to change.
> +
> +.. c:type:: v4l2_ctrl_h264_scaling_matrix
> +
> +.. cssclass:: longtable
> +
> +.. flat-table:: struct v4l2_ctrl_h264_scaling_matrix
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - __u8
> + - ``scaling_list_4x4[6][16]``
> + -
> + * - __u8
> + - ``scaling_list_8x8[6][64]``
> + -
> +
> +``V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS (struct)``
> + Specifies the slice parameters (as extracted from the bitstream)
> + for the associated H264 slice data. This includes the necessary
> + parameters for configuring a stateless hardware decoding pipeline
> + for H264. The bitstream parameters are defined according to
> + :ref:`h264`, section 7.4.3 "Slice Header Semantics". For further
> + documentation, refer to the above specification, unless there is
> + an explicit comment stating otherwise.
> +
> + .. note::
> +
> + This compound control is not yet part of the public kernel API
> + and it is expected to change.
> +
> + This structure is expected to be passed as an array, with one
> + entry for each slice included in the bitstream buffer.
> +
> +.. c:type:: v4l2_ctrl_h264_slice_params
> +
> +.. cssclass:: longtable
> +
> +.. flat-table:: struct v4l2_ctrl_h264_slice_params
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - __u32
> + - ``size``
> + -
> + * - __u32
> + - ``header_bit_size``
> + -
> + * - __u16
> + - ``first_mb_in_slice``
> + -
> + * - __u8
> + - ``slice_type``
> + -
> + * - __u8
> + - ``pic_parameter_set_id``
> + -
> + * - __u8
> + - ``colour_plane_id``
> + -
> + * - __u8
> + - ``redundant_pic_cnt``
> + -
> + * - __u16
> + - ``frame_num``
> + -
> + * - __u16
> + - ``idr_pic_id``
> + -
> + * - __u16
> + - ``pic_order_cnt_lsb``
> + -
> + * - __s32
> + - ``delta_pic_order_cnt_bottom``
> + -
> + * - __s32
> + - ``delta_pic_order_cnt0``
> + -
> + * - __s32
> + - ``delta_pic_order_cnt1``
> + -
> + * - struct :c:type:`v4l2_h264_pred_weight_table`
> + - ``pred_weight_table``
> + -
> + * - __u32
> + - ``dec_ref_pic_marking_bit_size``
> + -
> + * - __u32
> + - ``pic_order_cnt_bit_size``
> + -
> + * - __u8
> + - ``cabac_init_idc``
> + -
> + * - __s8
> + - ``slice_qp_delta``
> + -
> + * - __s8
> + - ``slice_qs_delta``
> + -
> + * - __u8
> + - ``disable_deblocking_filter_idc``
> + -
> + * - __s8
> + - ``slice_alpha_c0_offset_div2``
> + -
> + * - __s8
> + - ``slice_beta_offset_div2``
> + -
> + * - __u8
> + - ``num_ref_idx_l0_active_minus1``
> + -
> + * - __u8
> + - ``num_ref_idx_l1_active_minus1``
> + -
> + * - __u32
> + - ``slice_group_change_cycle``
> + -
> + * - __u8
> + - ``ref_pic_list0[32]``
> + - Reference picture list after applying the per-slice modifications
> + * - __u8
> + - ``ref_pic_list1[32]``
> + - Reference picture list after applying the per-slice modifications
> + * - __u32
> + - ``flags``
> + - See :ref:`Slice Parameter Flags <h264_slice_flags>`
> +
> +.. _h264_slice_flags:
> +
> +``Slice Parameter Set Flags``
> +
> +.. cssclass:: longtable
> +
> +.. flat-table::
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - ``V4L2_H264_SLICE_FLAG_FIELD_PIC``
> + - 0x00000001
> + -
> + * - ``V4L2_H264_SLICE_FLAG_BOTTOM_FIELD``
> + - 0x00000002
> + -
> + * - ``V4L2_H264_SLICE_FLAG_DIRECT_SPATIAL_MV_PRED``
> + - 0x00000004
> + -
> + * - ``V4L2_H264_SLICE_FLAG_SP_FOR_SWITCH``
> + - 0x00000008
> + -
> +
> +``Prediction Weight Table``
> +
> + The bitstream parameters are defined according to :ref:`h264`,
> + section 7.4.3.2 "Prediction Weight Table Semantics". For further
> + documentation, refer to the above specification, unless there is
> + an explicit comment stating otherwise.
> +
> +.. c:type:: v4l2_h264_pred_weight_table
> +
> +.. cssclass:: longtable
> +
> +.. flat-table:: struct v4l2_h264_pred_weight_table
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - __u16
> + - ``luma_log2_weight_denom``
> + -
> + * - __u16
> + - ``chroma_log2_weight_denom``
> + -
> + * - struct :c:type:`v4l2_h264_weight_factors`
> + - ``weight_factors[2]``
> + - The weight factors at index 0 are the weight factors for the reference
> + list 0, the one at index 1 for the reference list 1.
> +
> +.. c:type:: v4l2_h264_weight_factors
> +
> +.. cssclass:: longtable
> +
/> +.. flat-table:: struct v4l2_h264_weight_factors
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - __s16
> + - ``luma_weight[32]``
> + -
> + * - __s16
> + - ``luma_offset[32]``
> + -
> + * - __s16
> + - ``chroma_weight[32][2]``
> + -
> + * - __s16
> + - ``chroma_offset[32][2]``
> + -
> +
> +``V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS (struct)``
> + Specifies the decode parameters (as extracted from the bitstream)
> + for the associated H264 slice data. This includes the necessary
> + parameters for configuring a stateless hardware decoding pipeline
> + for H264. The bitstream parameters are defined according to
> + :ref:`h264`. For further documentation, refer to the above
> + specification, unless there is an explicit comment stating
> + otherwise.
> +
> + .. note::
> +
> + This compound control is not yet part of the public kernel API and
> + it is expected to change.
> +
> +.. c:type:: v4l2_ctrl_h264_decode_params
> +
> +.. cssclass:: longtable
> +
> +.. flat-table:: struct v4l2_ctrl_h264_decode_params
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - __u32
> + - ``num_slices``
> + - Number of slices needed to decode the current frame
> + * - __u32
> + - ``nal_ref_idc``
> + - NAL reference ID value coming from the NAL Unit header
> + * - __u8
> + - ``ref_pic_list_p0[32]``
> + - Backward reference list used by P-frames in the original bitstream order
> + * - __u8
> + - ``ref_pic_list_b0[32]``
> + - Backward reference list used by B-frames in the original bitstream order
> + * - __u8
> + - ``ref_pic_list_b1[32]``
> + - Forward reference list used by B-frames in the original bitstream order
> + * - __s32
> + - ``top_field_order_cnt``
> + - Picture Order Count for the coded top field
> + * - __s32
> + - ``bottom_field_order_cnt``
> + - Picture Order Count for the coded bottom field
> + * - __u32
> + - ``flags``
> + - See :ref:`Decode Parameters Flags <h264_decode_params_flags>`
> + * - struct :c:type:`v4l2_h264_dpb_entry`
> + - ``dpb[16]``
> + -
> +
> +.. _h264_decode_params_flags:
> +
> +``Decode Parameters Flags``
> +
> +.. cssclass:: longtable
> +
> +.. flat-table::
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - ``V4L2_H264_DECODE_PARAM_FLAG_IDR_PIC``
> + - 0x00000001
> + - That picture is an IDR picture
> +
> +.. c:type:: v4l2_h264_dpb_entry
> +
> +.. cssclass:: longtable
> +
> +.. flat-table:: struct v4l2_h264_dpb_entry
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - __u64
> + - ``reference_ts``
> + - Timestamp of the V4L2 capture buffer to use as reference, used
> + with B-coded and P-coded frames. The timestamp refers to the
> + ``timestamp`` field in struct :c:type:`v4l2_buffer`. Use the
> + :c:func:`v4l2_timeval_to_ns()` function to convert the struct
> + :c:type:`timeval` in struct :c:type:`v4l2_buffer` to a __u64.
> + * - __u16
> + - ``frame_num``
> + -
> + * - __u16
> + - ``pic_num``
> + -
> + * - __s32
> + - ``top_field_order_cnt``
> + -
> + * - __s32
> + - ``bottom_field_order_cnt``
> + -
> + * - __u32
> + - ``flags``
> + - See :ref:`DPB Entry Flags <h264_dpb_flags>`
> +
> +.. _h264_dpb_flags:
> +
> +``DPB Entries Flags``
> +
> +.. cssclass:: longtable
> +
> +.. flat-table::
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - ``V4L2_H264_DPB_ENTRY_FLAG_VALID``
> + - 0x00000001
> + - The DPB entry is valid and should be considered
> + * - ``V4L2_H264_DPB_ENTRY_FLAG_ACTIVE``
> + - 0x00000002
> + - The DPB entry is currently being used as a reference frame
> + * - ``V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM``
> + - 0x00000004
> + - The DPB entry is a long term reference frame
>
> .. _v4l2-mpeg-mpeg2:
>
> diff --git a/Documentation/media/uapi/v4l/pixfmt-compressed.rst b/Documentation/media/uapi/v4l/pixfmt-compressed.rst
> index 6c961cfb74da..ea0a8a68759b 100644
> --- a/Documentation/media/uapi/v4l/pixfmt-compressed.rst
> +++ b/Documentation/media/uapi/v4l/pixfmt-compressed.rst
> @@ -52,6 +52,25 @@ Compressed Formats
> - ``V4L2_PIX_FMT_H264_MVC``
> - 'M264'
> - H264 MVC video elementary stream.
> + * .. _V4L2-PIX-FMT-H264-SLICE:
Should be _V4L2-PIX-FMT-H264-SLICE-RAW.
> +
> + - ``V4L2_PIX_FMT_H264_SLICE_RAW``
> + - 'S264'
> + - H264 parsed slice data, as extracted from the H264 bitstream.
> + This format is adapted for stateless video decoders that
> + implement an H264 pipeline (using the :ref:`codec` and
codec is now mem2mem.
> + :ref:`media-request-api`). Metadata associated with the frame
> + to decode are required to be passed through the
> + ``V4L2_CID_MPEG_VIDEO_H264_SPS``,
> + ``V4L2_CID_MPEG_VIDEO_H264_PPS``,
> + ``V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX``,
> + ``V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS`` and
> + ``V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS`` controls. See the
> + :ref:`associated Codec Control IDs <v4l2-mpeg-h264>`.
> + Exactly one output and one capture buffer must be provided for
> + use with this pixel format. The output buffer must contain the
> + appropriate number of macroblocks to decode a full
> + corresponding frame to the matching capture buffer.
> * .. _V4L2-PIX-FMT-H263:
>
> - ``V4L2_PIX_FMT_H263``
> diff --git a/Documentation/media/uapi/v4l/vidioc-queryctrl.rst b/Documentation/media/uapi/v4l/vidioc-queryctrl.rst
> index f824162d0ea9..dc500632095d 100644
> --- a/Documentation/media/uapi/v4l/vidioc-queryctrl.rst
> +++ b/Documentation/media/uapi/v4l/vidioc-queryctrl.rst
> @@ -443,6 +443,36 @@ See also the examples in :ref:`control`.
> - n/a
> - A struct :c:type:`v4l2_ctrl_mpeg2_quantization`, containing MPEG-2
> quantization matrices for stateless video decoders.
> + * - ``V4L2_CTRL_TYPE_H264_SPS``
> + - n/a
> + - n/a
> + - n/a
> + - A struct :c:type:`v4l2_ctrl_h264_sps`, containing H264
> + sequence parameters for stateless video decoders.
> + * - ``V4L2_CTRL_TYPE_H264_PPS``
> + - n/a
> + - n/a
> + - n/a
> + - A struct :c:type:`v4l2_ctrl_h264_pps`, containing H264
> + picture parameters for stateless video decoders.
> + * - ``V4L2_CTRL_TYPE_H264_SCALING_MATRIX``
> + - n/a
> + - n/a
> + - n/a
> + - A struct :c:type:`v4l2_ctrl_h264_scaling_matrix`, containing H264
> + scaling matrices for stateless video decoders.
> + * - ``V4L2_CTRL_TYPE_H264_SLICE_PARAMS``
> + - n/a
> + - n/a
> + - n/a
> + - A struct :c:type:`v4l2_ctrl_h264_slice_params`, containing H264
> + slice parameters for stateless video decoders.
> + * - ``V4L2_CTRL_TYPE_H264_DECODE_PARAMS``
> + - n/a
> + - n/a
> + - n/a
> + - A struct :c:type:`v4l2_ctrl_h264_decode_params`, containing H264
> + decode parameters for stateless video decoders.
>
> .. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
>
> diff --git a/Documentation/media/videodev2.h.rst.exceptions b/Documentation/media/videodev2.h.rst.exceptions
> index 64d348e67df9..55cbe324b9fc 100644
> --- a/Documentation/media/videodev2.h.rst.exceptions
> +++ b/Documentation/media/videodev2.h.rst.exceptions
> @@ -136,6 +136,11 @@ replace symbol V4L2_CTRL_TYPE_U32 :c:type:`v4l2_ctrl_type`
> replace symbol V4L2_CTRL_TYPE_U8 :c:type:`v4l2_ctrl_type`
> replace symbol V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS :c:type:`v4l2_ctrl_type`
> replace symbol V4L2_CTRL_TYPE_MPEG2_QUANTIZATION :c:type:`v4l2_ctrl_type`
> +replace symbol V4L2_CTRL_TYPE_H264_SPS :c:type:`v4l2_ctrl_type`
> +replace symbol V4L2_CTRL_TYPE_H264_PPS :c:type:`v4l2_ctrl_type`
> +replace symbol V4L2_CTRL_TYPE_H264_SCALING_MATRIX :c:type:`v4l2_ctrl_type`
> +replace symbol V4L2_CTRL_TYPE_H264_SLICE_PARAMS :c:type:`v4l2_ctrl_type`
> +replace symbol V4L2_CTRL_TYPE_H264_DECODE_PARAMS :c:type:`v4l2_ctrl_type`
>
> # V4L2 capability defines
> replace define V4L2_CAP_VIDEO_CAPTURE device-capabilities
> diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
> index b1ae2e555c68..46aec8c3acde 100644
> --- a/drivers/media/v4l2-core/v4l2-ctrls.c
> +++ b/drivers/media/v4l2-core/v4l2-ctrls.c
> @@ -828,6 +828,11 @@ const char *v4l2_ctrl_get_name(u32 id)
> case V4L2_CID_MPEG_VIDEO_H264_CONSTRAINED_INTRA_PREDICTION:
> return "H264 Constrained Intra Pred";
> case V4L2_CID_MPEG_VIDEO_H264_CHROMA_QP_INDEX_OFFSET: return "H264 Chroma QP Index Offset";
> + case V4L2_CID_MPEG_VIDEO_H264_SPS: return "H264 Sequence Parameter Set";
> + case V4L2_CID_MPEG_VIDEO_H264_PPS: return "H264 Picture Parameter Set";
> + case V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX: return "H264 Scaling Matrix";
> + case V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS: return "H264 Slice Parameters";
> + case V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS: return "H264 Decode Parameters";
> case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP: return "MPEG4 I-Frame QP Value";
> case V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP: return "MPEG4 P-Frame QP Value";
> case V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP: return "MPEG4 B-Frame QP Value";
> @@ -1309,6 +1314,21 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
> case V4L2_CID_MPEG_VIDEO_FWHT_PARAMS:
> *type = V4L2_CTRL_TYPE_FWHT_PARAMS;
> break;
> + case V4L2_CID_MPEG_VIDEO_H264_SPS:
> + *type = V4L2_CTRL_TYPE_H264_SPS;
> + break;
> + case V4L2_CID_MPEG_VIDEO_H264_PPS:
> + *type = V4L2_CTRL_TYPE_H264_PPS;
> + break;
> + case V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX:
> + *type = V4L2_CTRL_TYPE_H264_SCALING_MATRIX;
> + break;
> + case V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS:
> + *type = V4L2_CTRL_TYPE_H264_SLICE_PARAMS;
> + break;
> + case V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS:
> + *type = V4L2_CTRL_TYPE_H264_DECODE_PARAMS;
> + break;
> default:
> *type = V4L2_CTRL_TYPE_INTEGER;
> break;
> @@ -1678,6 +1698,13 @@ static int std_validate(const struct v4l2_ctrl *ctrl, u32 idx,
> case V4L2_CTRL_TYPE_FWHT_PARAMS:
> return 0;
>
> + case V4L2_CTRL_TYPE_H264_SPS:
> + case V4L2_CTRL_TYPE_H264_PPS:
> + case V4L2_CTRL_TYPE_H264_SCALING_MATRIX:
> + case V4L2_CTRL_TYPE_H264_SLICE_PARAMS:
> + case V4L2_CTRL_TYPE_H264_DECODE_PARAMS:
> + return 0;
> +
> default:
> return -EINVAL;
> }
> @@ -2261,6 +2288,21 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
> case V4L2_CTRL_TYPE_FWHT_PARAMS:
> elem_size = sizeof(struct v4l2_ctrl_fwht_params);
> break;
> + case V4L2_CTRL_TYPE_H264_SPS:
> + elem_size = sizeof(struct v4l2_ctrl_h264_sps);
> + break;
> + case V4L2_CTRL_TYPE_H264_PPS:
> + elem_size = sizeof(struct v4l2_ctrl_h264_pps);
> + break;
> + case V4L2_CTRL_TYPE_H264_SCALING_MATRIX:
> + elem_size = sizeof(struct v4l2_ctrl_h264_scaling_matrix);
> + break;
> + case V4L2_CTRL_TYPE_H264_SLICE_PARAMS:
> + elem_size = sizeof(struct v4l2_ctrl_h264_slice_params);
> + break;
> + case V4L2_CTRL_TYPE_H264_DECODE_PARAMS:
> + elem_size = sizeof(struct v4l2_ctrl_h264_decode_params);
> + break;
> default:
> if (type < V4L2_CTRL_COMPOUND_TYPES)
> elem_size = sizeof(s32);
> diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
> index ac87c3e37280..f6e1254064d2 100644
> --- a/drivers/media/v4l2-core/v4l2-ioctl.c
> +++ b/drivers/media/v4l2-core/v4l2-ioctl.c
> @@ -1325,6 +1325,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
> case V4L2_PIX_FMT_H264: descr = "H.264"; break;
> case V4L2_PIX_FMT_H264_NO_SC: descr = "H.264 (No Start Codes)"; break;
> case V4L2_PIX_FMT_H264_MVC: descr = "H.264 MVC"; break;
> + case V4L2_PIX_FMT_H264_SLICE_RAW: descr = "H.264 Parsed Slice Data"; break;
> case V4L2_PIX_FMT_H263: descr = "H.263"; break;
> case V4L2_PIX_FMT_MPEG1: descr = "MPEG-1 ES"; break;
> case V4L2_PIX_FMT_MPEG2: descr = "MPEG-2 ES"; break;
> diff --git a/include/media/h264-ctrls.h b/include/media/h264-ctrls.h
> new file mode 100644
> index 000000000000..e2f83b3cdbef
> --- /dev/null
> +++ b/include/media/h264-ctrls.h
> @@ -0,0 +1,192 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * These are the H.264 state controls for use with stateless H.264
> + * codec drivers.
> + *
> + * It turns out that these structs are not stable yet and will undergo
> + * more changes. So keep them private until they are stable and ready to
> + * become part of the official public API.
> + */
> +
> +#ifndef _H264_CTRLS_H_
> +#define _H264_CTRLS_H_
> +
> +/*
> + * This is put insanely high to avoid conflicting with controls that
> + * would be added during the phase where those controls are not
> + * stable. It should be fixed eventually.
> + */
> +#define V4L2_CID_MPEG_VIDEO_H264_SPS (V4L2_CID_MPEG_BASE+1000)
> +#define V4L2_CID_MPEG_VIDEO_H264_PPS (V4L2_CID_MPEG_BASE+1001)
> +#define V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX (V4L2_CID_MPEG_BASE+1002)
> +#define V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS (V4L2_CID_MPEG_BASE+1003)
> +#define V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS (V4L2_CID_MPEG_BASE+1004)
> +
> +/* enum v4l2_ctrl_type type values */
> +#define V4L2_CTRL_TYPE_H264_SPS 0x0110
> +#define V4L2_CTRL_TYPE_H264_PPS 0x0111
> +#define V4L2_CTRL_TYPE_H264_SCALING_MATRIX 0x0112
> +#define V4L2_CTRL_TYPE_H264_SLICE_PARAMS 0x0113
> +#define V4L2_CTRL_TYPE_H264_DECODE_PARAMS 0x0114
> +
> +#define V4L2_H264_SPS_CONSTRAINT_SET0_FLAG 0x01
> +#define V4L2_H264_SPS_CONSTRAINT_SET1_FLAG 0x02
> +#define V4L2_H264_SPS_CONSTRAINT_SET2_FLAG 0x04
> +#define V4L2_H264_SPS_CONSTRAINT_SET3_FLAG 0x08
> +#define V4L2_H264_SPS_CONSTRAINT_SET4_FLAG 0x10
> +#define V4L2_H264_SPS_CONSTRAINT_SET5_FLAG 0x20
> +
> +#define V4L2_H264_SPS_FLAG_SEPARATE_COLOUR_PLANE 0x01
> +#define V4L2_H264_SPS_FLAG_QPPRIME_Y_ZERO_TRANSFORM_BYPASS 0x02
> +#define V4L2_H264_SPS_FLAG_DELTA_PIC_ORDER_ALWAYS_ZERO 0x04
> +#define V4L2_H264_SPS_FLAG_GAPS_IN_FRAME_NUM_VALUE_ALLOWED 0x08
> +#define V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY 0x10
> +#define V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD 0x20
> +#define V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE 0x40
> +
> +struct v4l2_ctrl_h264_sps {
> + __u8 profile_idc;
> + __u8 constraint_set_flags;
> + __u8 level_idc;
> + __u8 seq_parameter_set_id;
> + __u8 chroma_format_idc;
> + __u8 bit_depth_luma_minus8;
> + __u8 bit_depth_chroma_minus8;
> + __u8 log2_max_frame_num_minus4;
> + __u8 pic_order_cnt_type;
> + __u8 log2_max_pic_order_cnt_lsb_minus4;
> + __u8 max_num_ref_frames;
> + __u8 num_ref_frames_in_pic_order_cnt_cycle;
> + __s32 offset_for_ref_frame[255];
> + __s32 offset_for_non_ref_pic;
> + __s32 offset_for_top_to_bottom_field;
> + __u16 pic_width_in_mbs_minus1;
> + __u16 pic_height_in_map_units_minus1;
> + __u32 flags;
> +};
> +
> +#define V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE 0x0001
> +#define V4L2_H264_PPS_FLAG_BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT 0x0002
> +#define V4L2_H264_PPS_FLAG_WEIGHTED_PRED 0x0004
> +#define V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT 0x0008
> +#define V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED 0x0010
> +#define V4L2_H264_PPS_FLAG_REDUNDANT_PIC_CNT_PRESENT 0x0020
> +#define V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE 0x0040
> +#define V4L2_H264_PPS_FLAG_PIC_SCALING_MATRIX_PRESENT 0x0080
> +
> +struct v4l2_ctrl_h264_pps {
> + __u8 pic_parameter_set_id;
> + __u8 seq_parameter_set_id;
> + __u8 num_slice_groups_minus1;
> + __u8 num_ref_idx_l0_default_active_minus1;
> + __u8 num_ref_idx_l1_default_active_minus1;
> + __u8 weighted_bipred_idc;
> + __s8 pic_init_qp_minus26;
> + __s8 pic_init_qs_minus26;
> + __s8 chroma_qp_index_offset;
> + __s8 second_chroma_qp_index_offset;
> + __u16 flags;
> +};
> +
> +struct v4l2_ctrl_h264_scaling_matrix {
> + __u8 scaling_list_4x4[6][16];
> + __u8 scaling_list_8x8[6][64];
> +};
> +
> +struct v4l2_h264_weight_factors {
> + __s16 luma_weight[32];
> + __s16 luma_offset[32];
> + __s16 chroma_weight[32][2];
> + __s16 chroma_offset[32][2];
> +};
> +
> +struct v4l2_h264_pred_weight_table {
> + __u16 luma_log2_weight_denom;
> + __u16 chroma_log2_weight_denom;
> + struct v4l2_h264_weight_factors weight_factors[2];
> +};
> +
> +#define V4L2_H264_SLICE_TYPE_P 0
> +#define V4L2_H264_SLICE_TYPE_B 1
> +#define V4L2_H264_SLICE_TYPE_I 2
> +#define V4L2_H264_SLICE_TYPE_SP 3
> +#define V4L2_H264_SLICE_TYPE_SI 4
> +
> +#define V4L2_H264_SLICE_FLAG_FIELD_PIC 0x01
> +#define V4L2_H264_SLICE_FLAG_BOTTOM_FIELD 0x02
> +#define V4L2_H264_SLICE_FLAG_DIRECT_SPATIAL_MV_PRED 0x04
> +#define V4L2_H264_SLICE_FLAG_SP_FOR_SWITCH 0x08
> +
> +struct v4l2_ctrl_h264_slice_params {
> + /* Size in bytes, including header */
> + __u32 size;
> + /* Offset in bits to slice_data() from the beginning of this slice. */
> + __u32 header_bit_size;
> +
> + __u16 first_mb_in_slice;
> + __u8 slice_type;
> + __u8 pic_parameter_set_id;
> + __u8 colour_plane_id;
> + __u8 redundant_pic_cnt;
> + __u16 frame_num;
> + __u16 idr_pic_id;
> + __u16 pic_order_cnt_lsb;
> + __s32 delta_pic_order_cnt_bottom;
> + __s32 delta_pic_order_cnt0;
> + __s32 delta_pic_order_cnt1;
> +
> + struct v4l2_h264_pred_weight_table pred_weight_table;
> + /* Size in bits of dec_ref_pic_marking() syntax element. */
> + __u32 dec_ref_pic_marking_bit_size;
> + /* Size in bits of pic order count syntax. */
> + __u32 pic_order_cnt_bit_size;
> +
> + __u8 cabac_init_idc;
> + __s8 slice_qp_delta;
> + __s8 slice_qs_delta;
> + __u8 disable_deblocking_filter_idc;
> + __s8 slice_alpha_c0_offset_div2;
> + __s8 slice_beta_offset_div2;
> + __u8 num_ref_idx_l0_active_minus1;
> + __u8 num_ref_idx_l1_active_minus1;
> + __u32 slice_group_change_cycle;
> +
> + /*
> + * Entries on each list are indices into
> + * v4l2_ctrl_h264_decode_params.dpb[].
> + */
> + __u8 ref_pic_list0[32];
> + __u8 ref_pic_list1[32];
> +
> + __u32 flags;
> +};
> +
> +#define V4L2_H264_DPB_ENTRY_FLAG_VALID 0x01
> +#define V4L2_H264_DPB_ENTRY_FLAG_ACTIVE 0x02
> +#define V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM 0x04
> +
> +struct v4l2_h264_dpb_entry {
> + __u64 reference_ts;
> + __u16 frame_num;
> + __u16 pic_num;
> + /* Note that field is indicated by v4l2_buffer.field */
> + __s32 top_field_order_cnt;
> + __s32 bottom_field_order_cnt;
> + __u32 flags; /* V4L2_H264_DPB_ENTRY_FLAG_* */
> +};
> +
> +#define V4L2_H264_DECODE_PARAM_FLAG_IDR_PIC 0x01
> +
> +struct v4l2_ctrl_h264_decode_params {
> + struct v4l2_h264_dpb_entry dpb[16];
> + __u16 num_slices;
> + __u16 nal_ref_idc;
> + __u8 ref_pic_list_p0[32];
> + __u8 ref_pic_list_b0[32];
> + __u8 ref_pic_list_b1[32];
> + __s32 top_field_order_cnt;
> + __s32 bottom_field_order_cnt;
> + __u32 flags; /* V4L2_H264_DECODE_PARAM_FLAG_* */
> +};
> +
> +#endif
> diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
> index bd621cec65a5..dce6f33fd749 100644
> --- a/include/media/v4l2-ctrls.h
> +++ b/include/media/v4l2-ctrls.h
> @@ -23,11 +23,12 @@
> #include <media/media-request.h>
>
> /*
> - * Include the mpeg2 and fwht stateless codec compound control definitions.
> + * Include the stateless codec compound control definitions.
> * This will move to the public headers once this API is fully stable.
> */
> #include <media/mpeg2-ctrls.h>
> #include <media/fwht-ctrls.h>
> +#include <media/h264-ctrls.h>
>
> /* forward references */
> struct file;
> @@ -51,6 +52,11 @@ struct poll_table_struct;
> * @p_mpeg2_slice_params: Pointer to a MPEG2 slice parameters structure.
> * @p_mpeg2_quantization: Pointer to a MPEG2 quantization data structure.
> * @p_fwht_params: Pointer to a FWHT stateless parameters structure.
> + * @p_h264_sps: Pointer to a struct v4l2_ctrl_h264_sps.
> + * @p_h264_pps: Pointer to a struct v4l2_ctrl_h264_pps.
> + * @p_h264_scaling_matrix: Pointer to a struct v4l2_ctrl_h264_scaling_matrix.
> + * @p_h264_slice_param: Pointer to a struct v4l2_ctrl_h264_slice_params.
> + * @p_h264_decode_param: Pointer to a struct v4l2_ctrl_h264_decode_params.
p_h264_slice_param -> p_h264_slice_params
p_h264_decode_param -> p_h264_decode_params
> * @p: Pointer to a compound value.
> */
> union v4l2_ctrl_ptr {
> @@ -63,6 +69,11 @@ union v4l2_ctrl_ptr {
> struct v4l2_ctrl_mpeg2_slice_params *p_mpeg2_slice_params;
> struct v4l2_ctrl_mpeg2_quantization *p_mpeg2_quantization;
> struct v4l2_ctrl_fwht_params *p_fwht_params;
> + struct v4l2_ctrl_h264_sps *p_h264_sps;
> + struct v4l2_ctrl_h264_pps *p_h264_pps;
> + struct v4l2_ctrl_h264_scaling_matrix *p_h264_scaling_matrix;
> + struct v4l2_ctrl_h264_slice_params *p_h264_slice_param;
> + struct v4l2_ctrl_h264_decode_params *p_h264_decode_param;
Ditto.
Regards,
Hans
> void *p;
> };
>
> diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
> index 496e6453450c..838732acdefc 100644
> --- a/include/uapi/linux/videodev2.h
> +++ b/include/uapi/linux/videodev2.h
> @@ -657,6 +657,7 @@ struct v4l2_pix_format {
> #define V4L2_PIX_FMT_H264 v4l2_fourcc('H', '2', '6', '4') /* H264 with start codes */
> #define V4L2_PIX_FMT_H264_NO_SC v4l2_fourcc('A', 'V', 'C', '1') /* H264 without start codes */
> #define V4L2_PIX_FMT_H264_MVC v4l2_fourcc('M', '2', '6', '4') /* H264 MVC */
> +#define V4L2_PIX_FMT_H264_SLICE_RAW v4l2_fourcc('S', '2', '6', '4') /* H264 parsed slices */
> #define V4L2_PIX_FMT_H263 v4l2_fourcc('H', '2', '6', '3') /* H263 */
> #define V4L2_PIX_FMT_MPEG1 v4l2_fourcc('M', 'P', 'G', '1') /* MPEG-1 ES */
> #define V4L2_PIX_FMT_MPEG2 v4l2_fourcc('M', 'P', 'G', '2') /* MPEG-2 ES */
>
^ permalink raw reply
* [PATCH v3 9/9] arm64: dts: rockchip: add video codec for rk3328
From: ayaka @ 2019-04-10 12:42 UTC (permalink / raw)
To: linux-media
Cc: Randy Li, randy.li, hverkuil, maxime.ripard, joro, nicolas,
jernej.skrabec, paul.kocialkowski, thomas.petazzoni, mchehab,
ezequiel, posciak, groeck, linux-rockchip
In-Reply-To: <20190410124226.8612-1-ayaka@soulik.info>
From: Randy Li <ayaka@soulik.info>
Having problem with vepu2
The sclk_vdec_core for RKVDEC is in gpll at vendor kernel.
Signed-off-by: Randy Li <ayaka@soulik.info>
---
arch/arm64/boot/dts/rockchip/rk3328-evb.dts | 32 ++++++
.../arm64/boot/dts/rockchip/rk3328-rock64.dts | 32 ++++++
arch/arm64/boot/dts/rockchip/rk3328.dtsi | 108 +++++++++++++++++-
3 files changed, 170 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/rockchip/rk3328-evb.dts b/arch/arm64/boot/dts/rockchip/rk3328-evb.dts
index 8302d86d35c4..c89714f79f93 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328-evb.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3328-evb.dts
@@ -213,6 +213,18 @@
};
};
+&rkvdec {
+ status = "okay";
+};
+
+&rkvdec_mmu {
+ status = "okay";
+};
+
+&rkvdec_srv {
+ status = "okay";
+};
+
&sdio {
bus-width = <4>;
cap-sd-highspeed;
@@ -269,3 +281,23 @@
&usb_host0_ohci {
status = "okay";
};
+
+&vdpu {
+ status = "okay";
+};
+
+&vop {
+ status = "okay";
+};
+
+&vop_mmu {
+ status = "okay";
+};
+
+&vpu_mmu {
+ status = "okay";
+};
+
+&vpu_service{
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts
index 2157a528276b..520e444806cc 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts
@@ -256,6 +256,14 @@
};
};
+&h265e {
+ status = "okay";
+};
+
+&h265e_mmu {
+ status = "okay";
+};
+
&i2s1 {
status = "okay";
@@ -300,6 +308,18 @@
};
};
+&rkvdec {
+ status = "okay";
+};
+
+&rkvdec_mmu {
+ status = "okay";
+};
+
+&rkvdec_srv {
+ status = "okay";
+};
+
&sdmmc {
bus-width = <4>;
cap-mmc-highspeed;
@@ -370,6 +390,10 @@
status = "okay";
};
+&vdpu {
+ status = "okay";
+};
+
&vop {
status = "okay";
};
@@ -377,3 +401,11 @@
&vop_mmu {
status = "okay";
};
+
+&vpu_mmu {
+ status = "okay";
+};
+
+&vpu_service{
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
index 55a72abed6e7..9b3f8d22b60a 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
@@ -573,6 +573,27 @@
resets = <&cru SRST_GPU_A>;
};
+ venc_srv: venc-srv {
+ compatible = "rockchip,mpp-service";
+ status = "disabled";
+ };
+
+ h265e: h265e@ff330000 {
+ compatible = "rockchip,hevc-encoder-v1";
+ reg = <0x0 0xff330000 0 0x200>;
+ interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru ACLK_H265>, <&cru PCLK_H265>,
+ <&cru SCLK_VENC_CORE>, <&cru SCLK_VENC_DSP>,
+ <&cru ACLK_RKVENC>, <&cru ACLK_AXISRAM>;
+ clock-names = "aclk_h265", "pclk_h265", "clk_core",
+ "clk_dsp", "aclk_venc", "aclk_axi2sram";
+ iommus = <&h265e_mmu>;
+ rockchip,srv = <&venc_srv>;
+ syscon = <&grf 0x040c 0x8000800 0x80000>;
+ power-domains = <&power RK3328_PD_HEVC>;
+ status = "disabled";
+ };
+
h265e_mmu: iommu@ff330200 {
compatible = "rockchip,iommu";
reg = <0x0 0xff330200 0 0x100>;
@@ -584,6 +605,25 @@
status = "disabled";
};
+ vepu: vepu@ff340000 {
+ compatible = "rockchip,vpu-encoder-v2";
+ reg = <0x0 0xff340000 0x0 0x400>;
+ interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru ACLK_H264>, <&cru HCLK_H264>,
+ <&cru SCLK_VENC_CORE>;
+ clock-names = "aclk_vcodec", "hclk_vcodec",
+ "clk_core";
+ resets = <&cru SRST_RKVENC_H264_A>,
+ <&cru SRST_RKVENC_H264_H>;
+ reset-names = "video_a", "video_h";
+ iommus = <&vepu_mmu>;
+ rockchip,srv = <&venc_srv>;
+ syscon = <&grf 0x040c 0x8000800 0x80000>;
+ power-domains = <&power RK3328_PD_HEVC>;
+ status = "disabled";
+ };
+
+
vepu_mmu: iommu@ff340800 {
compatible = "rockchip,iommu";
reg = <0x0 0xff340800 0x0 0x40>;
@@ -595,6 +635,42 @@
status = "disabled";
};
+
+ vpu_service: vdpu-srv {
+ compatible = "rockchip,mpp-service";
+ status = "disabled";
+ };
+
+ vdpu: vpu-decoder@ff350000 {
+ compatible = "rockchip,vpu-decoder-v2";
+ reg = <0x0 0xff350400 0x0 0x400>;
+ interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "irq_dec";
+ resets = <&cru SRST_VCODEC_A>, <&cru SRST_VCODEC_H>;
+ reset-names = "video_a", "video_h";
+ clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>;
+ clock-names = "aclk_vcodec", "hclk_vcodec";
+ iommus = <&vpu_mmu>;
+ power-domains = <&power RK3328_PD_VPU>;
+ rockchip,srv = <&vpu_service>;
+ status = "disabled";
+ };
+
+ avsd: avs-decoder@ff351000 {
+ compatible = "rockchip,avs-decoder-v1";
+ reg = <0x0 0xff351000 0x0 0x200>;
+ interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "irq_dec";
+ clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>;
+ clock-names = "aclk_vcodec", "hclk_vcodec";
+ resets = <&cru SRST_VCODEC_A>, <&cru SRST_VCODEC_H>;
+ reset-names = "video_a", "video_h";
+ power-domains = <&power RK3328_PD_VPU>;
+ iommus = <&vpu_mmu>;
+ rockchip,srv = <&vpu_service>;
+ status = "disabled";
+ };
+
vpu_mmu: iommu@ff350800 {
compatible = "rockchip,iommu";
reg = <0x0 0xff350800 0x0 0x40>;
@@ -606,6 +682,34 @@
status = "disabled";
};
+ rkvdec_srv: rkvdec-srv {
+ compatible = "rockchip,mpp-service";
+ status = "disabled";
+ };
+
+ rkvdec: rkvdec@ff36000 {
+ compatible = "rockchip,video-decoder-v1";
+ reg = <0x0 0xff360000 0x0 0x400>;
+ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "irq_dec";
+ clocks = <&cru ACLK_RKVDEC>, <&cru HCLK_RKVDEC>,
+ <&cru SCLK_VDEC_CABAC>, <&cru SCLK_VDEC_CORE>;
+ clock-names = "aclk_vcodec", "hclk_vcodec", "clk_cabac",
+ "clk_core";
+ assigned-clocks = <&cru ACLK_RKVDEC_PRE>, <&cru SCLK_VDEC_CORE>;
+ assigned-clock-parents = <&cru PLL_GPLL>, <&cru PLL_GPLL>;
+ assigned-clock-rates = <500000000>, <245760000>;
+ resets = <&cru SRST_VDEC_A>, <&cru SRST_VDEC_H>,
+ <&cru SRST_VDEC_NIU_A>, <&cru SRST_VDEC_NIU_H>,
+ <&cru SRST_VDEC_CABAC>, <&cru SRST_VDEC_CORE>;
+ reset-names = "video_a", "video_h", "niu_a", "niu_h",
+ "video_cabac", "video_core";
+ iommus = <&rkvdec_mmu>;
+ power-domains = <&power RK3328_PD_VIDEO>;
+ rockchip,srv = <&rkvdec_srv>;
+ status = "disabled";
+ };
+
rkvdec_mmu: iommu@ff360480 {
compatible = "rockchip,iommu";
reg = <0x0 0xff360480 0x0 0x40>, <0x0 0xff3604c0 0x0 0x40>;
@@ -740,8 +844,8 @@
<15000000>, <15000000>,
<300000000>, <100000000>,
<400000000>, <100000000>,
- <50000000>, <100000000>,
- <100000000>, <100000000>,
+ <50000000>, <300000000>,
+ <300000000>, <300000000>,
<50000000>, <50000000>,
<50000000>, <50000000>,
<24000000>, <600000000>,
--
2.20.1
^ permalink raw reply related
* [PATCH v3 8/9] arm64: dts: rockchip: boost clocks for rk3328
From: ayaka @ 2019-04-10 12:42 UTC (permalink / raw)
To: linux-media
Cc: Randy Li, hverkuil, maxime.ripard, joro, nicolas, jernej.skrabec,
paul.kocialkowski, thomas.petazzoni, mchehab, ezequiel, posciak,
groeck, linux-rockchip
In-Reply-To: <20190410124226.8612-1-ayaka@soulik.info>
From: Randy Li <randy.li@rock-chips.com>
Or VOP won't work well.
Signed-off-by: Randy Li <randy.li@rock-chips.com>
---
arch/arm64/boot/dts/rockchip/rk3328.dtsi | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
index 84f14b132e8f..55a72abed6e7 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
@@ -738,8 +738,8 @@
<0>, <24000000>,
<24000000>, <24000000>,
<15000000>, <15000000>,
- <100000000>, <100000000>,
- <100000000>, <100000000>,
+ <300000000>, <100000000>,
+ <400000000>, <100000000>,
<50000000>, <100000000>,
<100000000>, <100000000>,
<50000000>, <50000000>,
--
2.20.1
^ permalink raw reply related
* [PATCH v3 7/9] [TEST]: rkvdec: spspps address alignment
From: ayaka @ 2019-04-10 12:42 UTC (permalink / raw)
To: linux-media
Cc: ayaka, randy.li, hverkuil, maxime.ripard, joro, nicolas,
jernej.skrabec, paul.kocialkowski, thomas.petazzoni, mchehab,
ezequiel, posciak, groeck, linux-rockchip
In-Reply-To: <20190410124226.8612-1-ayaka@soulik.info>
I found the offset for cpu access is not equal to the DMA
opeartion.
Signed-off-by: ayaka <ayaka@soulik.info>
---
drivers/staging/rockchip-mpp/mpp_dev_common.h | 3 +++
drivers/staging/rockchip-mpp/mpp_dev_rkvdec.c | 3 +++
drivers/staging/rockchip-mpp/rkvdec/avc.c | 14 +++++++-------
3 files changed, 13 insertions(+), 7 deletions(-)
diff --git a/drivers/staging/rockchip-mpp/mpp_dev_common.h b/drivers/staging/rockchip-mpp/mpp_dev_common.h
index 36770af53a95..6718bcccde1f 100644
--- a/drivers/staging/rockchip-mpp/mpp_dev_common.h
+++ b/drivers/staging/rockchip-mpp/mpp_dev_common.h
@@ -100,6 +100,9 @@ struct mpp_session {
struct v4l2_ctrl_handler ctrl_handler;
/* TODO: FIXME: slower than helper function ? */
struct v4l2_ctrl **ctrls;
+
+ void *aux_vaddr;
+ dma_addr_t aux_addr;
};
/* The context for the a task */
diff --git a/drivers/staging/rockchip-mpp/mpp_dev_rkvdec.c b/drivers/staging/rockchip-mpp/mpp_dev_rkvdec.c
index 97abfdfc344f..cc1fa9737bc1 100644
--- a/drivers/staging/rockchip-mpp/mpp_dev_rkvdec.c
+++ b/drivers/staging/rockchip-mpp/mpp_dev_rkvdec.c
@@ -382,6 +382,9 @@ static int rkvdec_open(struct file *filp)
filp->private_data = &session->fh;
pm_runtime_get_sync(mpp_dev->dev);
+ session->aux_vaddr = dmam_alloc_coherent(mpp_dev->dev, SZ_1M,
+ &session->aux_addr, GFP_KERNEL);
+
mpp_debug_leave();
return 0;
}
diff --git a/drivers/staging/rockchip-mpp/rkvdec/avc.c b/drivers/staging/rockchip-mpp/rkvdec/avc.c
index 1cb5b2208bfa..8266a990dca6 100644
--- a/drivers/staging/rockchip-mpp/rkvdec/avc.c
+++ b/drivers/staging/rockchip-mpp/rkvdec/avc.c
@@ -26,8 +26,8 @@
#include "regs.h"
#include "avc-data.h"
-static void generate_input_data(struct rkvdec_regs *p_regs,
- struct vb2_v4l2_buffer *src_buf,
+static void generate_input_data(struct mpp_session *session,
+ struct rkvdec_regs *p_regs,
const struct v4l2_ctrl_h264_sps *sps,
const struct v4l2_ctrl_h264_pps *pps,
const struct v4l2_ctrl_h264_scaling_matrix
@@ -44,8 +44,8 @@ static void generate_input_data(struct rkvdec_regs *p_regs,
stream_len = slice_param->size + 64;
- r_data = vb2_plane_vaddr(&src_buf->vb2_buf, 0);
- r_scaling_offs = ALIGN(stream_len, 16);
+ r_data = session->aux_vaddr;
+ r_scaling_offs = 0;
r_data += r_scaling_offs;
if (pps->flags & V4L2_H264_PPS_FLAG_PIC_SCALING_MATRIX_PRESENT) {
@@ -62,7 +62,7 @@ static void generate_input_data(struct rkvdec_regs *p_regs,
rkvdec_avc_write_sps(&rbsp, sps);
rkvdec_avc_write_pps(&rbsp, pps);
rkvdec_avc_write_pps_tail(&rbsp, scaling_addr, decode_param);
- p_regs->sw_pps_base = p_regs->sw_strm_rlc_base + r_sps_offs;
+ p_regs->sw_pps_base = session->aux_addr + r_sps_offs;
for (i = 1; i < 256; i++)
memset(r_data + r_sps_offs + i * 32, 0, 32);
@@ -72,7 +72,7 @@ static void generate_input_data(struct rkvdec_regs *p_regs,
r_rps_offs = ALIGN(r_rps_offs, 16);
rbsp_init(&rbsp, r_data + r_rps_offs, SZ_2M - r_rps_offs, 0);
rkvdec_avc_write_rps(&rbsp, sps, slice_param, decode_param);
- p_regs->sw_rps_base = p_regs->sw_strm_rlc_base + r_rps_offs;
+ p_regs->sw_rps_base = session->aux_addr + r_rps_offs;
}
static void init_hw_cfg(struct rkvdec_regs *p_regs)
@@ -238,7 +238,7 @@ int rkvdec_avc_gen_reg(struct mpp_session *session, void *regs,
dst_buf = v4l2_m2m_next_dst_buf(session->fh.m2m_ctx);
rkvdec_avc_gen_ref(p_regs, dst_buf, decode_param);
- generate_input_data(p_regs, src_buf, sps, pps, scaling, slice_param,
+ generate_input_data(session, p_regs, sps, pps, scaling, slice_param,
decode_param);
return 0;
--
2.20.1
^ permalink raw reply related
* [PATCH v3 6/9] [TEST]: rockchip: mpp: vdpu2: move qtable to input buffer
From: ayaka @ 2019-04-10 12:42 UTC (permalink / raw)
To: linux-media
Cc: Randy Li, hverkuil, maxime.ripard, joro, nicolas, jernej.skrabec,
paul.kocialkowski, thomas.petazzoni, mchehab, ezequiel, posciak,
groeck, linux-rockchip
In-Reply-To: <20190410124226.8612-1-ayaka@soulik.info>
From: Randy Li <randy.li@rock-chips.com>
I want the memory region !!!
It can save more time if those data are prepared in userspace.
Signed-off-by: Randy Li <randy.li@rock-chips.com>
---
drivers/staging/rockchip-mpp/mpp_dev_common.c | 3 +--
drivers/staging/rockchip-mpp/mpp_dev_common.h | 3 ---
drivers/staging/rockchip-mpp/mpp_dev_vdpu2.c | 3 +++
drivers/staging/rockchip-mpp/vdpu2/mpeg2.c | 20 +++++++++++--------
4 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/drivers/staging/rockchip-mpp/mpp_dev_common.c b/drivers/staging/rockchip-mpp/mpp_dev_common.c
index 21816ad8a43b..97c4d897f168 100644
--- a/drivers/staging/rockchip-mpp/mpp_dev_common.c
+++ b/drivers/staging/rockchip-mpp/mpp_dev_common.c
@@ -1217,8 +1217,7 @@ static int rockchip_mpp_queue_init(void *priv, struct vb2_queue *src_vq,
src_vq->io_modes = VB2_MMAP | VB2_DMABUF;
src_vq->drv_priv = session;
src_vq->mem_ops = &vb2_dma_contig_memops;
- src_vq->dma_attrs = DMA_ATTR_ALLOC_SINGLE_PAGES |
- DMA_ATTR_NO_KERNEL_MAPPING;
+ src_vq->dma_attrs = DMA_ATTR_ALLOC_SINGLE_PAGES;
src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
src_vq->min_buffers_needed = 1;
src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
diff --git a/drivers/staging/rockchip-mpp/mpp_dev_common.h b/drivers/staging/rockchip-mpp/mpp_dev_common.h
index 33d7725be67b..36770af53a95 100644
--- a/drivers/staging/rockchip-mpp/mpp_dev_common.h
+++ b/drivers/staging/rockchip-mpp/mpp_dev_common.h
@@ -100,9 +100,6 @@ struct mpp_session {
struct v4l2_ctrl_handler ctrl_handler;
/* TODO: FIXME: slower than helper function ? */
struct v4l2_ctrl **ctrls;
-
- dma_addr_t qtable_addr;
- void *qtable_vaddr;
};
/* The context for the a task */
diff --git a/drivers/staging/rockchip-mpp/mpp_dev_vdpu2.c b/drivers/staging/rockchip-mpp/mpp_dev_vdpu2.c
index 1be73ab9c2be..92d68b962fe1 100644
--- a/drivers/staging/rockchip-mpp/mpp_dev_vdpu2.c
+++ b/drivers/staging/rockchip-mpp/mpp_dev_vdpu2.c
@@ -176,6 +176,9 @@ static int rkvdpu_s_fmt_vid_out_mplane(struct file *filp, void *priv,
if (sizes >= SZ_16M)
return -EINVAL;
+ /* For those slice header data */
+ pix_mp->plane_fmt[pix_mp->num_planes - 1].sizeimage += SZ_1M;
+
if (vdpu_setup_ctrls(session, pix_mp->pixelformat))
return -EINVAL;
diff --git a/drivers/staging/rockchip-mpp/vdpu2/mpeg2.c b/drivers/staging/rockchip-mpp/vdpu2/mpeg2.c
index 837ee4a4a000..c12d1a8ef2da 100644
--- a/drivers/staging/rockchip-mpp/vdpu2/mpeg2.c
+++ b/drivers/staging/rockchip-mpp/vdpu2/mpeg2.c
@@ -113,7 +113,10 @@ int rkvdpu_mpeg2_gen_reg(struct mpp_session *session, void *regs,
const struct v4l2_ctrl_mpeg2_slice_params *params;
const struct v4l2_mpeg2_sequence *sequence;
const struct v4l2_mpeg2_picture *picture;
+ const struct v4l2_ctrl_mpeg2_quantization *quantization;
struct vdpu2_regs *p_regs = regs;
+ void *qtable = NULL;
+ size_t stream_len = 0;
params = rockchip_mpp_get_cur_ctrl(session,
V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS);
@@ -122,6 +125,8 @@ int rkvdpu_mpeg2_gen_reg(struct mpp_session *session, void *regs,
sequence = ¶ms->sequence;
picture = ¶ms->picture;
+ quantization = rockchip_mpp_get_cur_ctrl(session,
+ V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION);
init_hw_cfg(p_regs);
@@ -198,7 +203,13 @@ int rkvdpu_mpeg2_gen_reg(struct mpp_session *session, void *regs,
p_regs->sw64.rlc_vlc_base =
vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0);
p_regs->sw122.strm_start_bit = params->data_bit_offset;
- p_regs->sw51.stream_len = vb2_get_plane_payload(&src_buf->vb2_buf, 0);
+ stream_len = vb2_get_plane_payload(&src_buf->vb2_buf, 0);
+ p_regs->sw51.stream_len = stream_len;
+
+ qtable = vb2_plane_vaddr(&src_buf->vb2_buf, 0) + ALIGN(stream_len, 8);
+ mpeg2_dec_copy_qtable(qtable, quantization);
+ p_regs->sw61.qtable_base = p_regs->sw64.rlc_vlc_base
+ + ALIGN(stream_len, 8);
return 0;
}
@@ -207,7 +218,6 @@ int rkvdpu_mpeg2_prepare_buf(struct mpp_session *session, void *regs)
{
const struct v4l2_ctrl_mpeg2_slice_params *params;
const struct v4l2_mpeg2_sequence *sequence;
- const struct v4l2_ctrl_mpeg2_quantization *quantization;
const struct v4l2_mpeg2_picture *picture;
struct vb2_v4l2_buffer *dst_buf;
dma_addr_t cur_addr, fwd_addr, bwd_addr;
@@ -220,9 +230,6 @@ int rkvdpu_mpeg2_prepare_buf(struct mpp_session *session, void *regs)
picture = ¶ms->picture;
sequence = ¶ms->sequence;
- quantization = rockchip_mpp_get_cur_ctrl(session,
- V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION);
-
dst_buf = v4l2_m2m_next_dst_buf(session->fh.m2m_ctx);
cur_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
@@ -266,8 +273,5 @@ int rkvdpu_mpeg2_prepare_buf(struct mpp_session *session, void *regs)
p_regs->sw135.refer3_base = cur_addr >> 2;
}
- mpeg2_dec_copy_qtable(session->qtable_vaddr, quantization);
- p_regs->sw61.qtable_base = session->qtable_addr;
-
return 0;
}
--
2.20.1
^ permalink raw reply related
* [PATCH v3 5/9] [TEST]: rockchip: mpp: support qtable
From: ayaka @ 2019-04-10 12:42 UTC (permalink / raw)
To: linux-media
Cc: Randy Li, hverkuil, maxime.ripard, joro, nicolas, jernej.skrabec,
paul.kocialkowski, thomas.petazzoni, mchehab, ezequiel, posciak,
groeck, linux-rockchip
In-Reply-To: <20190410124226.8612-1-ayaka@soulik.info>
From: Randy Li <randy.li@rock-chips.com>
I don't care, I don't want to store buffers for a session.
I just want to use it to verify the FFmpeg.
---
drivers/staging/rockchip-mpp/mpp_dev_common.h | 3 +++
drivers/staging/rockchip-mpp/mpp_dev_vdpu2.c | 5 ++++-
drivers/staging/rockchip-mpp/vdpu2/mpeg2.c | 13 ++++++++-----
3 files changed, 15 insertions(+), 6 deletions(-)
diff --git a/drivers/staging/rockchip-mpp/mpp_dev_common.h b/drivers/staging/rockchip-mpp/mpp_dev_common.h
index 36770af53a95..33d7725be67b 100644
--- a/drivers/staging/rockchip-mpp/mpp_dev_common.h
+++ b/drivers/staging/rockchip-mpp/mpp_dev_common.h
@@ -100,6 +100,9 @@ struct mpp_session {
struct v4l2_ctrl_handler ctrl_handler;
/* TODO: FIXME: slower than helper function ? */
struct v4l2_ctrl **ctrls;
+
+ dma_addr_t qtable_addr;
+ void *qtable_vaddr;
};
/* The context for the a task */
diff --git a/drivers/staging/rockchip-mpp/mpp_dev_vdpu2.c b/drivers/staging/rockchip-mpp/mpp_dev_vdpu2.c
index dbd9f334562e..1be73ab9c2be 100644
--- a/drivers/staging/rockchip-mpp/mpp_dev_vdpu2.c
+++ b/drivers/staging/rockchip-mpp/mpp_dev_vdpu2.c
@@ -246,6 +246,9 @@ static int rkvdpu_open(struct file *filp)
if (IS_ERR_OR_NULL(session))
return PTR_ERR(session);
+ session->qtable_vaddr = dmam_alloc_coherent(mpp_dev->dev, 64 * 4,
+ &session->qtable_addr,
+ GFP_KERNEL);
filp->private_data = &session->fh;
pm_runtime_get_sync(mpp_dev->dev);
@@ -529,7 +532,7 @@ static int rockchip_mpp_rkvdpu_probe(struct platform_device *pdev)
ret = mpp_dev_register_node(mpp_dev, mpp_dev->variant->node_name,
NULL, &rkvdpu_ioctl_ops);
if (ret)
- dev_err(dev, "register char device failed: %d\n", ret);
+ dev_err(dev, "register v4l2/media device failed: %d\n", ret);
memcpy(mpp_dev->fmt_out, fmt_out_templ, sizeof(fmt_out_templ));
memcpy(mpp_dev->fmt_cap, fmt_cap_templ, sizeof(fmt_cap_templ));
diff --git a/drivers/staging/rockchip-mpp/vdpu2/mpeg2.c b/drivers/staging/rockchip-mpp/vdpu2/mpeg2.c
index d32958c4cb20..837ee4a4a000 100644
--- a/drivers/staging/rockchip-mpp/vdpu2/mpeg2.c
+++ b/drivers/staging/rockchip-mpp/vdpu2/mpeg2.c
@@ -52,7 +52,7 @@ static const u8 intra_default_q_matrix[64] = {
static void mpeg2_dec_copy_qtable(u8 * qtable, const struct v4l2_ctrl_mpeg2_quantization
*ctrl)
{
- int i, n;
+ int i;
if (!qtable || !ctrl)
return;
@@ -111,16 +111,12 @@ int rkvdpu_mpeg2_gen_reg(struct mpp_session *session, void *regs,
struct vb2_v4l2_buffer *src_buf)
{
const struct v4l2_ctrl_mpeg2_slice_params *params;
- const struct v4l2_ctrl_mpeg2_quantization *quantization;
const struct v4l2_mpeg2_sequence *sequence;
const struct v4l2_mpeg2_picture *picture;
struct vdpu2_regs *p_regs = regs;
params = rockchip_mpp_get_cur_ctrl(session,
V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS);
- quantization = rockchip_mpp_get_cur_ctrl(session,
- V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION);
-
if (!params)
return -EINVAL;
@@ -211,6 +207,7 @@ int rkvdpu_mpeg2_prepare_buf(struct mpp_session *session, void *regs)
{
const struct v4l2_ctrl_mpeg2_slice_params *params;
const struct v4l2_mpeg2_sequence *sequence;
+ const struct v4l2_ctrl_mpeg2_quantization *quantization;
const struct v4l2_mpeg2_picture *picture;
struct vb2_v4l2_buffer *dst_buf;
dma_addr_t cur_addr, fwd_addr, bwd_addr;
@@ -223,6 +220,9 @@ int rkvdpu_mpeg2_prepare_buf(struct mpp_session *session, void *regs)
picture = ¶ms->picture;
sequence = ¶ms->sequence;
+ quantization = rockchip_mpp_get_cur_ctrl(session,
+ V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION);
+
dst_buf = v4l2_m2m_next_dst_buf(session->fh.m2m_ctx);
cur_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
@@ -266,5 +266,8 @@ int rkvdpu_mpeg2_prepare_buf(struct mpp_session *session, void *regs)
p_regs->sw135.refer3_base = cur_addr >> 2;
}
+ mpeg2_dec_copy_qtable(session->qtable_vaddr, quantization);
+ p_regs->sw61.qtable_base = session->qtable_addr;
+
return 0;
}
--
2.20.1
^ permalink raw reply related
* [PATCH v3 4/9] [WIP]: rockchip: mpp: H.264 decoder ctrl data
From: ayaka @ 2019-04-10 12:42 UTC (permalink / raw)
To: linux-media
Cc: ayaka, randy.li, hverkuil, maxime.ripard, joro, nicolas,
jernej.skrabec, paul.kocialkowski, thomas.petazzoni, mchehab,
ezequiel, posciak, groeck, linux-rockchip
In-Reply-To: <20190410124226.8612-1-ayaka@soulik.info>
I really don't want to do this.
Signed-off-by: Randy Li <randy.li@rock-chips.com>
Signed-off-by: ayaka <ayaka@soulik.info>
---
drivers/staging/rockchip-mpp/Makefile | 2 +-
drivers/staging/rockchip-mpp/mpp_dev_rkvdec.c | 8 +-
.../staging/rockchip-mpp/rkvdec/avc-data.c | 239 ++++++++++++++++++
.../staging/rockchip-mpp/rkvdec/avc-data.h | 40 +++
drivers/staging/rockchip-mpp/rkvdec/avc.c | 71 +++++-
drivers/staging/rockchip-mpp/vdpu2/avc.c | 165 ++++++++++++
6 files changed, 514 insertions(+), 11 deletions(-)
create mode 100644 drivers/staging/rockchip-mpp/rkvdec/avc-data.c
create mode 100644 drivers/staging/rockchip-mpp/rkvdec/avc-data.h
create mode 100644 drivers/staging/rockchip-mpp/vdpu2/avc.c
diff --git a/drivers/staging/rockchip-mpp/Makefile b/drivers/staging/rockchip-mpp/Makefile
index 8da33fa5142d..e2c2bf297812 100644
--- a/drivers/staging/rockchip-mpp/Makefile
+++ b/drivers/staging/rockchip-mpp/Makefile
@@ -2,7 +2,7 @@
rk-mpp-service-objs := mpp_service.o
rk-mpp-device-objs := mpp_dev_common.o
rk-mpp-vdec-objs := mpp_dev_rkvdec.o
-rk-mpp-vdec-objs += rkvdec/avc.o
+rk-mpp-vdec-objs += rkvdec/avc.o rkvdec/avc-data.o
rk-mpp-vdec-objs += rkvdec/hevc.o rkvdec/hevc-data.o rkvdec/rbsp.o
rk-mpp-vdpu2-objs := mpp_dev_vdpu2.o vdpu2/mpeg2.o
diff --git a/drivers/staging/rockchip-mpp/mpp_dev_rkvdec.c b/drivers/staging/rockchip-mpp/mpp_dev_rkvdec.c
index 756821dbf829..97abfdfc344f 100644
--- a/drivers/staging/rockchip-mpp/mpp_dev_rkvdec.c
+++ b/drivers/staging/rockchip-mpp/mpp_dev_rkvdec.c
@@ -284,13 +284,15 @@ static int rkvdec_s_fmt_vid_cap_mplane(struct file *filp, void *priv,
pix_mp->plane_fmt[1].bytesperline * ALIGN(pix_mp->height,
8);
#else
- /* TODO: HEVC only request the height is aligned with 8 */
+ /*
+ * TODO: H.264 would use 16 alignment while the resolution is under HD,
+ * HEVC only request the height is aligned with 8
+ */
pix_mp->plane_fmt[0].sizeimage =
pix_mp->plane_fmt[0].bytesperline * ALIGN(pix_mp->height,
- 16);
+ 8);
/* Additional space for motion vector */
pix_mp->plane_fmt[0].sizeimage *= 2;
- pix_mp->plane_fmt[0].sizeimage += SZ_4M;
pix_mp->plane_fmt[1].sizeimage = SZ_2M;
#endif
pix_mp->num_planes = 2;
diff --git a/drivers/staging/rockchip-mpp/rkvdec/avc-data.c b/drivers/staging/rockchip-mpp/rkvdec/avc-data.c
new file mode 100644
index 000000000000..57172528f988
--- /dev/null
+++ b/drivers/staging/rockchip-mpp/rkvdec/avc-data.c
@@ -0,0 +1,239 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2019 Randy Li, <ayaka@soulik.info>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "avc-data.h"
+
+static const u32 zig_zag_4x4[16] = {
+ 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15
+};
+
+static const u32 zig_zag_8x8[64] = {
+ 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5,
+ 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28,
+ 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51,
+ 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63
+};
+
+static void fill_is_long_term(struct rbsp *rbsp, const struct v4l2_ctrl_h264_decode_param
+ *decode_param)
+{
+ u16 is_long_term = 0;
+ u8 i;
+
+ for (i = 0; i < 16; i++)
+ if (decode_param->dpb[i].
+ flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM)
+ is_long_term |= (1 << i);
+
+ rbsp_write_bits(rbsp, 16, is_long_term);
+}
+
+/* in zig-zag order */
+void rkvdec_avc_update_scaling_list(u8 * buf, const struct
+ v4l2_ctrl_h264_scaling_matrix
+ *scaling)
+{
+ u8 i, j;
+
+ for (i = 0; i < 6; i++)
+ for (j = 0; j < 16; j++)
+ buf[zig_zag_4x4[j] + (i << 4)] =
+ scaling->scaling_list_4x4[i][j];
+
+ for (i = 0; i < 2; i++)
+ for (j = 0; j < 64; j++)
+ buf[zig_zag_8x8[j] + (i << 6)] =
+ scaling->scaling_list_8x8[i][j];
+}
+
+int rkvdec_avc_write_sps(struct rbsp *rbsp,
+ const struct v4l2_ctrl_h264_sps *sps)
+{
+ /* TODO: seq_parameter_set_id */
+ rbsp_write_bits(rbsp, 4, 0);
+ rbsp_write_bits(rbsp, 8, sps->profile_idc);
+ /* constraint_set3_flag */
+ rbsp_write_flag(rbsp, sps->constraint_set_flags >> 3);
+ rbsp_write_bits(rbsp, 2, sps->chroma_format_idc);
+ /* bit_depth_luma Not used */
+ rbsp_write_bits(rbsp, 3, sps->bit_depth_luma_minus8);
+ /* bit_depth_chroma Not used */
+ rbsp_write_bits(rbsp, 3, sps->bit_depth_chroma_minus8);
+ /* TODO: qpprime_y_zero_transform_bypass_flag */
+ rbsp_write_flag(rbsp, 0);
+ rbsp_write_bits(rbsp, 4, sps->log2_max_frame_num_minus4);
+ rbsp_write_bits(rbsp, 5, sps->max_num_ref_frames);
+ rbsp_write_bits(rbsp, 2, sps->pic_order_cnt_type);
+ rbsp_write_bits(rbsp, 4, sps->log2_max_pic_order_cnt_lsb_minus4);
+ /* delta_pic_order_always_zero_flag */
+ rbsp_write_flag(rbsp,
+ sps->flags &
+ V4L2_H264_SPS_FLAG_DELTA_PIC_ORDER_ALWAYS_ZERO);
+ rbsp_write_bits(rbsp, 9, sps->pic_width_in_mbs_minus1 + 1);
+ /* TODO: check whether it work for field coding */
+ rbsp_write_bits(rbsp, 9, sps->pic_height_in_map_units_minus1 + 1);
+ rbsp_write_flag(rbsp, sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY);
+ rbsp_write_flag(rbsp, sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD);
+ rbsp_write_flag(rbsp,
+ sps->flags & V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE);
+
+ /* TODO: mvc */
+ rbsp_write_flag(rbsp, 0);
+ /* num_views_minus1 */
+ rbsp_write_bits(rbsp, 2, 0);
+ /* view_id[0] */
+ rbsp_write_bits(rbsp, 10, 0);
+ /* view_id[1] */
+ rbsp_write_bits(rbsp, 10, 0);
+ /* num_anchor_refs_l0 */
+ rbsp_write_flag(rbsp, 0);
+ /* anchor_ref_l0 */
+ rbsp_write_bits(rbsp, 10, 0);
+ rbsp_write_flag(rbsp, 0);
+ rbsp_write_bits(rbsp, 10, 0);
+ /* num_non_anchor_refs_l0 */
+ rbsp_write_flag(rbsp, 0);
+ rbsp_write_bits(rbsp, 10, 0);
+ rbsp_write_flag(rbsp, 0);
+ rbsp_write_bits(rbsp, 10, 0);
+ /* Align with 128 bit */
+ rbsp_write_bits(rbsp, 2, 0);
+
+ return 0;
+}
+
+int rkvdec_avc_write_pps(struct rbsp *rbsp,
+ const struct v4l2_ctrl_h264_pps *pps)
+{
+ /* TODO: pps_pic_parameter_set_id */
+ rbsp_write_bits(rbsp, 8, 0);
+ rbsp_write_bits(rbsp, 5, 0);
+ rbsp_write_flag(rbsp,
+ pps->flags & V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE);
+ rbsp_write_flag(rbsp,
+ pps->flags &
+ V4L2_H264_PPS_FLAG_BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT);
+ rbsp_write_bits(rbsp, 5, pps->num_ref_idx_l0_default_active_minus1);
+ rbsp_write_bits(rbsp, 5, pps->num_ref_idx_l1_default_active_minus1);
+ rbsp_write_flag(rbsp, pps->flags & V4L2_H264_PPS_FLAG_WEIGHTED_PRED);
+ rbsp_write_bits(rbsp, 2, pps->weighted_bipred_idc);
+ rbsp_write_bits(rbsp, 7, pps->pic_init_qp_minus26);
+ rbsp_write_bits(rbsp, 6, pps->pic_init_qs_minus26);
+ rbsp_write_bits(rbsp, 5, pps->chroma_qp_index_offset);
+ rbsp_write_flag(rbsp,
+ pps->flags &
+ V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT);
+ rbsp_write_flag(rbsp,
+ pps->flags & V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED);
+ rbsp_write_flag(rbsp,
+ pps->flags &
+ V4L2_H264_PPS_FLAG_REDUNDANT_PIC_CNT_PRESENT);
+ rbsp_write_flag(rbsp,
+ pps->flags & V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE);
+ rbsp_write_bits(rbsp, 5, pps->second_chroma_qp_index_offset);
+ rbsp_write_flag(rbsp,
+ pps->flags &
+ V4L2_H264_PPS_FLAG_PIC_SCALING_MATRIX_PRESENT);
+
+ return 0;
+}
+
+int rkvdec_avc_write_pps_tail(struct rbsp *rbsp, dma_addr_t scaling_addr, const struct v4l2_ctrl_h264_decode_param
+ *decode_param)
+{
+ /* scaling list buffer */
+ rbsp_write_bits(rbsp, 32, scaling_addr);
+
+ /* DPB */
+ fill_is_long_term(rbsp, decode_param);
+
+ /* TODO: VOIdx, Layer id */
+ rbsp_write_bits(rbsp, 16, 0);
+
+ /* Align with 128 bit */
+ rbsp_write_bits(rbsp, 8, 0);
+
+ return 0;
+}
+
+static inline void fill_rps_list(struct rbsp *rbsp, const struct v4l2_ctrl_h264_decode_param
+ *decode_param, const u8 * list)
+{
+ u8 i;
+
+ for (i = 0; i < 32; i++) {
+ u8 idx, active_flag;
+
+ idx = list[i];
+
+ active_flag = decode_param->dpb[idx].flags &
+ V4L2_H264_DPB_ENTRY_FLAG_ACTIVE;
+ if (!active_flag) {
+ rbsp_write_bits(rbsp, 7, 0);
+ } else {
+ rbsp_write_bits(rbsp, 5, idx | BIT(5));
+ /* TODO: bottom flag */
+ rbsp_write_flag(rbsp, 0);
+ /* TODO: view id */
+ rbsp_write_flag(rbsp, 0);
+ }
+ }
+}
+
+int rkvdec_avc_write_rps(struct rbsp *rbsp,
+ const struct v4l2_ctrl_h264_sps *sps,
+ const struct v4l2_ctrl_h264_slice_param *slice_param,
+ const struct v4l2_ctrl_h264_decode_param *decode_param)
+{
+ int max_frame_num = 1 << (sps->log2_max_frame_num_minus4 + 4);
+ u8 i;
+
+ for (i = 0; i < 16; i++) {
+ u16 frame_num = decode_param->dpb[i].frame_num;
+
+ rbsp_write_bits(rbsp, 16, frame_num > max_frame_num ?
+ frame_num - max_frame_num : frame_num);
+ }
+
+ /* reserved */
+ rbsp_write_bits(rbsp, 16, 0);
+ /* TODO: VoidX */
+ rbsp_write_bits(rbsp, 16, 0);
+
+ switch (slice_param->slice_type) {
+ case V4L2_H264_SLICE_TYPE_P:
+ fill_rps_list(rbsp, decode_param, slice_param->ref_pic_list0);
+ for (i = 0; i < 14; i++)
+ rbsp_write_bits(rbsp, 32, 0);
+ break;
+ case V4L2_H264_SLICE_TYPE_B:
+ for (i = 0; i < 7; i++)
+ rbsp_write_bits(rbsp, 32, 0);
+ fill_rps_list(rbsp, decode_param, slice_param->ref_pic_list0);
+ fill_rps_list(rbsp, decode_param, slice_param->ref_pic_list1);
+ break;
+ case V4L2_H264_SLICE_TYPE_I:
+ /* TODO: SVC */
+ default:
+ for (i = 0; i < 21; i++)
+ rbsp_write_bits(rbsp, 32, 0);
+ break;
+ }
+
+ rbsp_write_bits(rbsp, 32, 0);
+ rbsp_write_bits(rbsp, 32, 0);
+
+ return 0;
+}
diff --git a/drivers/staging/rockchip-mpp/rkvdec/avc-data.h b/drivers/staging/rockchip-mpp/rkvdec/avc-data.h
new file mode 100644
index 000000000000..38ad17273b8a
--- /dev/null
+++ b/drivers/staging/rockchip-mpp/rkvdec/avc-data.h
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2019 Randy Li, <ayaka@soulik.info>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/types.h>
+
+#include <linux/videodev2.h>
+#include <media/v4l2-ctrls.h>
+
+#include "rbsp.h"
+
+void rkvdec_avc_update_scaling_list(u8 * buf, const struct
+ v4l2_ctrl_h264_scaling_matrix
+ *scaling);
+
+int rkvdec_avc_write_sps(struct rbsp *rbsp,
+ const struct v4l2_ctrl_h264_sps *sps);
+
+int rkvdec_avc_write_pps(struct rbsp *rbsp,
+ const struct v4l2_ctrl_h264_pps *pps);
+
+int rkvdec_avc_write_pps_tail(struct rbsp *rbsp, dma_addr_t scaling_addr,
+ const struct v4l2_ctrl_h264_decode_param *decode_param);
+
+int rkvdec_avc_write_rps(struct rbsp *rbsp,
+ const struct v4l2_ctrl_h264_sps *sps,
+ const struct v4l2_ctrl_h264_slice_param *slice_param,
+ const struct v4l2_ctrl_h264_decode_param
+ *decode_param);
diff --git a/drivers/staging/rockchip-mpp/rkvdec/avc.c b/drivers/staging/rockchip-mpp/rkvdec/avc.c
index 3d91a119e533..1cb5b2208bfa 100644
--- a/drivers/staging/rockchip-mpp/rkvdec/avc.c
+++ b/drivers/staging/rockchip-mpp/rkvdec/avc.c
@@ -24,6 +24,56 @@
#include "mpp_dev_common.h"
#include "hal.h"
#include "regs.h"
+#include "avc-data.h"
+
+static void generate_input_data(struct rkvdec_regs *p_regs,
+ struct vb2_v4l2_buffer *src_buf,
+ const struct v4l2_ctrl_h264_sps *sps,
+ const struct v4l2_ctrl_h264_pps *pps,
+ const struct v4l2_ctrl_h264_scaling_matrix
+ *scaling, const struct v4l2_ctrl_h264_slice_param
+ *slice_param, const struct v4l2_ctrl_h264_decode_param
+ *decode_param)
+{
+ struct rbsp rbsp = { 0, };
+ size_t r_scaling_offs, r_sps_offs, r_rps_offs;
+ size_t stream_len = 0;
+ dma_addr_t scaling_addr = 0;
+ void *r_data = NULL;
+ int i;
+
+ stream_len = slice_param->size + 64;
+
+ r_data = vb2_plane_vaddr(&src_buf->vb2_buf, 0);
+ r_scaling_offs = ALIGN(stream_len, 16);
+ r_data += r_scaling_offs;
+
+ if (pps->flags & V4L2_H264_PPS_FLAG_PIC_SCALING_MATRIX_PRESENT) {
+ rkvdec_avc_update_scaling_list(r_data, scaling);
+ r_sps_offs = r_scaling_offs + 6 * 16 + 2 * 64 + 128;
+ r_sps_offs = ALIGN(r_sps_offs, 16);
+ scaling_addr = p_regs->sw_strm_rlc_base + r_scaling_offs;
+ } else {
+ r_sps_offs = r_scaling_offs;
+ scaling_addr = 0;
+ }
+
+ rbsp_init(&rbsp, r_data + r_sps_offs, SZ_2M - r_sps_offs, 0);
+ rkvdec_avc_write_sps(&rbsp, sps);
+ rkvdec_avc_write_pps(&rbsp, pps);
+ rkvdec_avc_write_pps_tail(&rbsp, scaling_addr, decode_param);
+ p_regs->sw_pps_base = p_regs->sw_strm_rlc_base + r_sps_offs;
+
+ for (i = 1; i < 256; i++)
+ memset(r_data + r_sps_offs + i * 32, 0, 32);
+
+ /* 256 bits */
+ r_rps_offs = r_sps_offs + 32 * 256 + 128;
+ r_rps_offs = ALIGN(r_rps_offs, 16);
+ rbsp_init(&rbsp, r_data + r_rps_offs, SZ_2M - r_rps_offs, 0);
+ rkvdec_avc_write_rps(&rbsp, sps, slice_param, decode_param);
+ p_regs->sw_rps_base = p_regs->sw_strm_rlc_base + r_rps_offs;
+}
static void init_hw_cfg(struct rkvdec_regs *p_regs)
{
@@ -152,18 +202,23 @@ int rkvdec_avc_gen_reg(struct mpp_session *session, void *regs,
{
const struct v4l2_ctrl_h264_sps *sps;
const struct v4l2_ctrl_h264_pps *pps;
+ const struct v4l2_ctrl_h264_scaling_matrix *scaling;
const struct v4l2_ctrl_h264_slice_param *slice_param;
const struct v4l2_ctrl_h264_decode_param *decode_param;
struct vb2_v4l2_buffer *dst_buf;
struct rkvdec_regs *p_regs = regs;
- size_t stream_len = 0;
sps = rockchip_mpp_get_cur_ctrl(session, V4L2_CID_MPEG_VIDEO_H264_SPS);
pps = rockchip_mpp_get_cur_ctrl(session, V4L2_CID_MPEG_VIDEO_H264_PPS);
- slice_param = rockchip_mpp_get_cur_ctrl(session,
- V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS);
- decode_param = rockchip_mpp_get_cur_ctrl(session,
- V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS);
+ scaling =
+ rockchip_mpp_get_cur_ctrl(session,
+ V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS);
+ slice_param =
+ rockchip_mpp_get_cur_ctrl(session,
+ V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS);
+ decode_param =
+ rockchip_mpp_get_cur_ctrl(session,
+ V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS);
if (!sps || !pps || !slice_param || !decode_param)
return -EINVAL;
@@ -178,12 +233,14 @@ int rkvdec_avc_gen_reg(struct mpp_session *session, void *regs,
p_regs->sw_sysctrl.strm_start_bit = slice_param->header_bit_size;
/* hardware wants a zerod memory at the stream end */
- stream_len = slice_param->size + 64;
- p_regs->sw_stream_len = stream_len;
+ p_regs->sw_stream_len = slice_param->size + 64;
dst_buf = v4l2_m2m_next_dst_buf(session->fh.m2m_ctx);
rkvdec_avc_gen_ref(p_regs, dst_buf, decode_param);
+ generate_input_data(p_regs, src_buf, sps, pps, scaling, slice_param,
+ decode_param);
+
return 0;
}
diff --git a/drivers/staging/rockchip-mpp/vdpu2/avc.c b/drivers/staging/rockchip-mpp/vdpu2/avc.c
new file mode 100644
index 000000000000..f77bb8ef810a
--- /dev/null
+++ b/drivers/staging/rockchip-mpp/vdpu2/avc.c
@@ -0,0 +1,165 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2019 Randy Li, <ayaka@soulik.info>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/types.h>
+
+#include <linux/videodev2.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/videobuf2-dma-contig.h>
+
+#include "mpp_dev_common.h"
+#include "hal.h"
+#include "regs.h"
+
+#define DEC_LITTLE_ENDIAN (1)
+
+static const u8 zigzag[64] = {
+ 0, 1, 8, 16, 9, 2, 3, 10,
+ 17, 24, 32, 25, 18, 11, 4, 5,
+ 12, 19, 26, 33, 40, 48, 41, 34,
+ 27, 20, 13, 6, 7, 14, 21, 28,
+ 35, 42, 49, 56, 57, 50, 43, 36,
+ 29, 22, 15, 23, 30, 37, 44, 51,
+ 58, 59, 52, 45, 38, 31, 39, 46,
+ 53, 60, 61, 54, 47, 55, 62, 63
+};
+
+static const u8 intra_default_q_matrix[64] = {
+ 8, 16, 19, 22, 26, 27, 29, 34,
+ 16, 16, 22, 24, 27, 29, 34, 37,
+ 19, 22, 26, 27, 29, 34, 34, 38,
+ 22, 22, 26, 27, 29, 34, 37, 40,
+ 22, 26, 27, 29, 32, 35, 40, 48,
+ 26, 27, 29, 32, 35, 40, 48, 58,
+ 26, 27, 29, 34, 38, 46, 56, 69,
+ 27, 29, 35, 38, 46, 56, 69, 83
+};
+
+static void init_hw_cfg(struct vdpu2_regs *p_regs)
+{
+ p_regs->sw54.dec_strm_wordsp = 1;
+ p_regs->sw54.dec_strendian_e = DEC_LITTLE_ENDIAN;
+ p_regs->sw54.dec_in_wordsp = 1;
+ p_regs->sw54.dec_out_wordsp = 1;
+ p_regs->sw54.dec_in_endian = DEC_LITTLE_ENDIAN; //change
+ p_regs->sw54.dec_out_endian = DEC_LITTLE_ENDIAN;
+ p_regs->sw57.dec_timeout = 1;
+ p_regs->sw57.dec_timeout_e = 1;
+
+ p_regs->sw57.dec_clk_gate_e = 1;
+ p_regs->sw57.pref_sigchan = 1;
+ p_regs->sw57.bus_pos_sel = 1;
+ p_regs->sw57.intra_dbl3t = 1;
+ p_regs->sw57.inter_dblspeed = 1;
+ p_regs->sw57.intra_dblspeed = 1;
+
+ p_regs->sw50.tiled_mode_msb = 0;
+ p_regs->sw56.dec_max_burst = 16;
+ p_regs->sw50.dec_scmd_dis = 0;
+ p_regs->sw50.dec_adv_pre_dis = 0;
+ p_regs->sw52.apf_threshold = 8;
+
+ p_regs->sw50.dec_latency = 0;
+ p_regs->sw56.dec_data_disc_e = 0;
+
+ p_regs->sw55.dec_irq = 0;
+ p_regs->sw56.dec_axi_rd_id = 0;
+ p_regs->sw56.dec_axi_wr_id = 0;
+
+ p_reg->sw59.pred_bc_tap_0_0 = 1;
+ /* -5 */
+ p_reg->sw59.pred_bc_tap_0_1 = 0x3fb;
+ p_reg->sw59.pred_bc_tap_0_2 = 20;
+
+ p_regs->sw53.dec_mode = RKVDPU2_FMT_H264D;
+}
+
+int rkvdpu_mpeg2_gen_reg(struct mpp_session *session, void *regs,
+ struct vb2_v4l2_buffer *src_buf)
+{
+ const struct v4l2_ctrl_h264_sps *sps;
+ const struct v4l2_ctrl_h264_pps *pps;
+ const struct v4l2_ctrl_h264_scaling_matrix *scaling;
+ const struct v4l2_ctrl_h264_slice_param *slice_param;
+ const struct v4l2_ctrl_h264_decode_param *decode_param;
+ struct vb2_v4l2_buffer *dst_buf;
+ struct rkvdec_regs *p_regs = regs;
+
+ sps = rockchip_mpp_get_cur_ctrl(session, V4L2_CID_MPEG_VIDEO_H264_SPS);
+ pps = rockchip_mpp_get_cur_ctrl(session, V4L2_CID_MPEG_VIDEO_H264_PPS);
+ scaling =
+ rockchip_mpp_get_cur_ctrl(session,
+ V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS);
+ slice_param =
+ rockchip_mpp_get_cur_ctrl(session,
+ V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS);
+ decode_param =
+ rockchip_mpp_get_cur_ctrl(session,
+ V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS);
+
+ if (!sps || !pps || !slice_param || !decode_param)
+ return -EINVAL;
+
+ init_hw_cfg(p_regs);
+
+ p_regs->sw120.pic_mb_width = sps->pic_width_in_mbs_minus1 + 1;
+ p_regs->sw120.pic_mb_height_p = sps->pic_height_in_map_units_minus1 + 1;
+
+#if 0
+ /* PICT_FRAME */
+ if (picture->picture_structure == 3) {
+ p_regs->sw57.pic_fieldmode_e = 0;
+ } else {
+ p_regs->sw57.pic_fieldmode_e = 1;
+ /* PICT_TOP_FIEL */
+ if (picture->picture_structure == 1)
+ p_regs->sw57.pic_topfield_e = 1;
+ }
+#endif
+ p_regs->sw51.qp_init = pps->pic_init_qp_minus26 + 26;
+ p_regs->sw114.max_refidx0 = slice_params->num_ref_idx_l0_active_minus1 + 1;
+ p_regs->sw111.max_refnum = sps->num_ref_frames;
+
+ p_regs->sw115.const_intra_en = pps->constrained_intra_pred_flag;
+
+#if 0
+ p_regs->sw112.dblk_ctrl_flag = pp->deblocking_filter_control_present_flag;
+ p_regs->sw112.rpcp_flag = pp->redundant_pic_cnt_present_flag;
+ p_regs->sw113.refpic_mk_len = p_hal->slice_long[0].drpm_used_bitlen;
+ p_regs->sw115.idr_pic_flag = p_hal->slice_long[0].idr_flag;
+ p_regs->sw113.idr_pic_id = p_hal->slice_long[0].idr_pic_id;
+ p_regs->sw114.pps_id = p_hal->slice_long[0].active_pps_id;
+ p_regs->sw114.poc_field_len = p_hal->slice_long[0].poc_used_bitlen;
+#endif
+
+ p_regs->sw52.startmb_x = 0;
+ p_regs->sw52.startmb_y = 0;
+ p_regs->sw57.dec_out_dis = 0;
+ p_regs->sw50.filtering_dis = 1;
+
+ p_regs->sw64.rlc_vlc_base =
+ vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0);
+ p_regs->sw122.strm_start_bit = params->data_bit_offset;
+ stream_len = vb2_get_plane_payload(&src_buf->vb2_buf, 0);
+ p_regs->sw51.stream_len = stream_len;
+
+ qtable = vb2_plane_vaddr(&src_buf->vb2_buf, 0) + ALIGN(stream_len, 8);
+ p_regs->sw61.qtable_base = p_regs->sw64.rlc_vlc_base
+ + ALIGN(stream_len, 8);
+
+ return 0;
+}
--
2.20.1
^ permalink raw reply related
* [PATCH v3 3/9] [WIP]: rockchip: mpp: HEVC decoder ctrl data
From: ayaka @ 2019-04-10 12:42 UTC (permalink / raw)
To: linux-media
Cc: Randy Li, hverkuil, maxime.ripard, joro, nicolas, jernej.skrabec,
paul.kocialkowski, thomas.petazzoni, mchehab, ezequiel, posciak,
groeck, linux-rockchip
In-Reply-To: <20190410124226.8612-1-ayaka@soulik.info>
From: Randy Li <randy.li@rock-chips.com>
Not done yet, not enough data.
Signed-off-by: Randy Li <randy.li@rock-chips.com>
---
drivers/staging/rockchip-mpp/Makefile | 4 +-
.../staging/rockchip-mpp/rkvdec/hevc-data.c | 208 ++++++++++++++++++
.../staging/rockchip-mpp/rkvdec/hevc-data.h | 27 +++
drivers/staging/rockchip-mpp/rkvdec/hevc.c | 2 +
4 files changed, 240 insertions(+), 1 deletion(-)
create mode 100644 drivers/staging/rockchip-mpp/rkvdec/hevc-data.c
create mode 100644 drivers/staging/rockchip-mpp/rkvdec/hevc-data.h
diff --git a/drivers/staging/rockchip-mpp/Makefile b/drivers/staging/rockchip-mpp/Makefile
index 9722b0059563..8da33fa5142d 100644
--- a/drivers/staging/rockchip-mpp/Makefile
+++ b/drivers/staging/rockchip-mpp/Makefile
@@ -1,7 +1,9 @@
# SPDX-License-Identifier: GPL-2.0
rk-mpp-service-objs := mpp_service.o
rk-mpp-device-objs := mpp_dev_common.o
-rk-mpp-vdec-objs := mpp_dev_rkvdec.o rkvdec/hevc.o rkvdec/avc.o
+rk-mpp-vdec-objs := mpp_dev_rkvdec.o
+rk-mpp-vdec-objs += rkvdec/avc.o
+rk-mpp-vdec-objs += rkvdec/hevc.o rkvdec/hevc-data.o rkvdec/rbsp.o
rk-mpp-vdpu2-objs := mpp_dev_vdpu2.o vdpu2/mpeg2.o
obj-$(CONFIG_ROCKCHIP_MPP_SERVICE) += rk-mpp-service.o
diff --git a/drivers/staging/rockchip-mpp/rkvdec/hevc-data.c b/drivers/staging/rockchip-mpp/rkvdec/hevc-data.c
new file mode 100644
index 000000000000..26694a2f46c5
--- /dev/null
+++ b/drivers/staging/rockchip-mpp/rkvdec/hevc-data.c
@@ -0,0 +1,208 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2019 Randy Li, <ayaka@soulik.info>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "hevc-data.h"
+
+/* 7.3.2.2.1 General sequence parameter set RBSP syntax */
+int rkvdec_hevc_write_sps(struct rbsp *rbsp,
+ const struct v4l2_ctrl_hevc_sps *sps)
+{
+ /* TODO: sps_video_parameter_set_id */
+ rbsp_write_bits(rbsp, 4, 0);
+ /* TODO: sps_seq_parameter_set_id */
+ rbsp_write_bits(rbsp, 4, 0);
+ /* chroma_format_idc */
+ rbsp_write_bits(rbsp, 2, sps->chroma_format_idc);
+ rbsp_write_bits(rbsp, 13, sps->pic_width_in_luma_samples);
+ rbsp_write_bits(rbsp, 13, sps->pic_height_in_luma_samples);
+ /* bit_depth_luma */
+ rbsp_write_bits(rbsp, 4, sps->bit_depth_luma_minus8 + 8);
+ rbsp_write_bits(rbsp, 4, sps->bit_depth_chroma_minus8 + 8);
+ /* log2_max_pic_order_cnt_lsb */
+ rbsp_write_bits(rbsp, 5, sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
+ /* FIXME it is 3 bits in document */
+ rbsp_write_bits(rbsp, 2, sps->log2_diff_max_min_luma_coding_block_size);
+ /* log2_min_luma_coding_block_size */
+ rbsp_write_bits(rbsp, 3,
+ sps->log2_min_luma_coding_block_size_minus3 + 3);
+ /* log2_min_transform_block_size */
+ rbsp_write_bits(rbsp, 3,
+ sps->log2_min_luma_transform_block_size_minus2 + 2);
+ rbsp_write_bits(rbsp, 2,
+ sps->log2_diff_max_min_luma_transform_block_size);
+ rbsp_write_bits(rbsp, 3, sps->max_transform_hierarchy_depth_inter);
+ rbsp_write_bits(rbsp, 3, sps->max_transform_hierarchy_depth_intra);
+
+ rbsp_write_flag(rbsp, sps->scaling_list_enabled_flag);
+ rbsp_write_flag(rbsp, sps->amp_enabled_flag);
+ rbsp_write_flag(rbsp, sps->sample_adaptive_offset_enabled_flag);
+ rbsp_write_flag(rbsp, sps->pcm_enabled_flag);
+
+ /* pcm_sample_bit_depth_luma */
+ rbsp_write_bits(rbsp, 4, sps->pcm_sample_bit_depth_luma_minus1 + 1);
+ /* pcm_sample_bit_depth_chroma */
+ rbsp_write_bits(rbsp, 4, sps->pcm_sample_bit_depth_chroma_minus1 + 1);
+ rbsp_write_flag(rbsp, sps->pcm_loop_filter_disabled_flag);
+
+ rbsp_write_bits(rbsp, 3,
+ sps->log2_diff_max_min_pcm_luma_coding_block_size);
+ /* log2_min_pcm_luma_coding_block_size */
+ rbsp_write_bits(rbsp, 3,
+ sps->log2_min_pcm_luma_coding_block_size_minus3 + 3);
+ rbsp_write_bits(rbsp, 7, sps->num_short_term_ref_pic_sets);
+ rbsp_write_flag(rbsp, sps->long_term_ref_pics_present_flag);
+ rbsp_write_bits(rbsp, 6, sps->num_long_term_ref_pics_sps);
+ rbsp_write_flag(rbsp, sps->sps_temporal_mvp_enabled_flag);
+ rbsp_write_flag(rbsp, sps->strong_intra_smoothing_enabled_flag);
+ /* Above is 100 bits total */
+#if 0
+ /* transform_skip_rotation_enabled_flag to intra_smoothing_disabled_flag */
+ rbsp_write_bits(rbsp, 7, 0);
+ /* sps_max_dec_pic_buffering_minus1 */
+ rbsp_write_bits(rbsp, 4, sps->sps_max_dec_pic_buffering_minus1);
+ rbsp_write_flag(rbsp, sps->separate_colour_plane_flag);
+ /* TODO: high_precision_offsets_enabled */
+ rbsp_write_flag(rbsp, 0);
+ /* TODO: persistent_rice_adaptation_enabled_flag */
+ rbsp_write_flag(rbsp, 0);
+ /* reserved */
+ rbsp_write_bits(rbsp, 14, 0xffffffff);
+#else
+ rbsp_write_bits(rbsp, 7, 0);
+ /* padding */
+ rbsp_write_bits(rbsp, 21, 0xffffffff);
+#endif
+
+ return 0;
+}
+
+int rkvdec_hevc_write_pps(struct rbsp *rbsp,
+ const struct v4l2_ctrl_hevc_sps *sps,
+ const struct v4l2_ctrl_hevc_pps *pps,
+ const struct v4l2_ctrl_hevc_slice_params *slice_params)
+{
+
+ u32 min_cb_log2_size_y, ctb_log2_size_y, log2_min_cu_qp_delta_size;
+ u16 column_width[20] = { 0, };
+ u16 row_height[22] = { 0, };
+ u8 i;
+
+ min_cb_log2_size_y = sps->log2_min_luma_coding_block_size_minus3 + 3;
+ ctb_log2_size_y = min_cb_log2_size_y +
+ sps->log2_diff_max_min_luma_coding_block_size;
+
+ log2_min_cu_qp_delta_size = ctb_log2_size_y - pps->diff_cu_qp_delta_depth;
+
+ /* pps_pic_parameter_set_id */
+ rbsp_write_bits(rbsp, 6, 0);
+ /* pps_seq_parameter_set_id */
+ rbsp_write_bits(rbsp, 4, 0);
+ /* dependent_slice_segments_enabled_flag */
+ rbsp_write_flag(rbsp, pps->dependent_slice_segment_flag);
+ rbsp_write_flag(rbsp, pps->output_flag_present_flag);
+ /* FIXME it is 3 bits in document */
+ rbsp_write_bits(rbsp, 13, pps->num_extra_slice_header_bits);
+ /* sign_data_hiding_flag */
+ rbsp_write_flag(rbsp, pps->sign_data_hiding_enabled_flag);
+ rbsp_write_flag(rbsp, pps->cabac_init_present_flag);
+ /* FIXME: from slice params ? */
+ rbsp_write_bits(rbsp, 4, slice_params->num_ref_idx_l0_active_minus1 + 1);
+ rbsp_write_bits(rbsp, 4, slice_params->num_ref_idx_l1_active_minus1 + 1);
+ /* FIXME it is 6 bits in document init_qp_minus26 */
+ rbsp_write_bits(rbsp, 7, pps->init_qp_minus26);
+ rbsp_write_flag(rbsp, pps->constrained_intra_pred_flag);
+ rbsp_write_flag(rbsp, pps->transform_skip_enabled_flag);
+ rbsp_write_flag(rbsp, pps->cu_qp_delta_enabled_flag);
+ /* Log2MinCuQpDeltaSize */
+ rbsp_write_bits(rbsp, 3, log2_min_cu_qp_delta_size);
+ rbsp_write_bits(rbsp, 5, pps->pps_cb_qp_offset);
+ rbsp_write_bits(rbsp, 5, pps->pps_cr_qp_offset);
+ rbsp_write_flag(rbsp, pps->pps_slice_chroma_qp_offsets_present_flag);
+ rbsp_write_flag(rbsp, pps->weighted_pred_flag);
+ rbsp_write_flag(rbsp, pps->weighted_bipred_flag);
+ rbsp_write_flag(rbsp, pps->transquant_bypass_enabled_flag);
+ rbsp_write_flag(rbsp, pps->tiles_enabled_flag);
+ rbsp_write_flag(rbsp, pps->entropy_coding_sync_enabled_flag);
+ rbsp_write_flag(rbsp, pps->pps_loop_filter_across_slices_enabled_flag);
+ rbsp_write_flag(rbsp, pps->loop_filter_across_tiles_enabled_flag);
+ rbsp_write_flag(rbsp, pps->deblocking_filter_override_enabled_flag);
+ /* pps_deblocking_filter_disabled_flag */
+ rbsp_write_flag(rbsp, pps->pps_disable_deblocking_filter_flag);
+ rbsp_write_bits(rbsp, 4, pps->pps_beta_offset_div2);
+ rbsp_write_bits(rbsp, 4, pps->pps_tc_offset_div2);
+ rbsp_write_flag(rbsp, pps->lists_modification_present_flag);
+ rbsp_write_bits(rbsp, 3, pps->log2_parallel_merge_level_minus2 + 2);
+ rbsp_write_flag(rbsp, pps->slice_segment_header_extension_present_flag);
+ /* reserved, log2_transform_skip_max_size_minus2 */
+ rbsp_write_bits(rbsp, 3, 0);
+ /* num_tile_columns */
+ rbsp_write_bits(rbsp, 5, pps->num_tile_columns_minus1 + 1);
+ /* num_tile_rows */
+ rbsp_write_bits(rbsp, 5, pps->num_tile_rows_minus1 + 1);
+ /* ? */
+ rbsp_write_bits(rbsp, 3, 2);
+ /* align 30 ? */
+ rbsp_write_bits(rbsp, 32, 0xffffffff);
+
+ /* TODO: support tile video */
+ column_width[0] = 0;
+ row_height[0] = 0;
+
+ for (i = 0; i < 20; i++) {
+ if (column_width[i])
+ column_width[i]--;
+ rbsp_write_bits(rbsp, column_width[i], 8);
+ }
+ for (i = 0; i < 22; i++) {
+ if (row_height[i])
+ row_height[i]--;
+ rbsp_write_bits(rbsp, row_height[i], 8);
+ }
+
+ /* TODO: scaleing_address */
+
+ return 0;
+}
+
+int rkvdec_hevc_write_soft_rps(struct rbsp *rbsp,
+ const struct v4l2_ctrl_hevc_slice_params *slice_params)
+{
+ int i;
+
+ for (i = 0; i < 15; i++) {
+ /* FIXME: is long term */
+ rbsp_write_flag(rbsp, 0);
+ rbsp_write_bits(rbsp, 4, slice_params->ref_idx_l0[i]);
+ }
+
+ for (i = 0; i < 15; i++) {
+ /* FIXME: is long term */
+ rbsp_write_flag(rbsp, 0);
+ rbsp_write_bits(rbsp, 4, slice_params->ref_idx_l1[i]);
+ }
+ /* TODO: lowdelay_flag */
+ rbsp_write_flag(rbsp, 1);
+
+ /* TODO: Rps_bit_offset_include_lt */
+ rbsp_write_bits(rbsp, 10, 0);
+ rbsp_write_bits(rbsp, 9, 0);
+}
+
+/* 7.3.7 Short-term reference picture set syntax */
+int rkvdec_hevc_write_rps(struct rbsp *rbsp,
+ const struct v4l2_ctrl_hevc_pps *pps)
+{
+
+}
diff --git a/drivers/staging/rockchip-mpp/rkvdec/hevc-data.h b/drivers/staging/rockchip-mpp/rkvdec/hevc-data.h
new file mode 100644
index 000000000000..6b94cd41d377
--- /dev/null
+++ b/drivers/staging/rockchip-mpp/rkvdec/hevc-data.h
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2019 Randy Li, <ayaka@soulik.info>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/types.h>
+
+#include <linux/videodev2.h>
+#include <media/v4l2-ctrls.h>
+
+#include "rbsp.h"
+
+int rkvdec_hevc_write_sps(struct rbsp *rbsp,
+ const struct v4l2_ctrl_hevc_sps *sps);
+
+int rkvdec_hevc_write_rps(struct rbsp *rbsp,
+ const struct v4l2_ctrl_hevc_pps *pps);
diff --git a/drivers/staging/rockchip-mpp/rkvdec/hevc.c b/drivers/staging/rockchip-mpp/rkvdec/hevc.c
index 78f150000128..6f74ce45533a 100644
--- a/drivers/staging/rockchip-mpp/rkvdec/hevc.c
+++ b/drivers/staging/rockchip-mpp/rkvdec/hevc.c
@@ -25,6 +25,8 @@
#include "hal.h"
#include "regs.h"
+#include "hevc-data.h"
+
static void init_hw_cfg(struct rkvdec_regs *p_regs)
{
p_regs->sw_interrupt.dec_e = 1;
--
2.20.1
^ permalink raw reply related
* [PATCH v3 2/9] rockchip: mpp: rkvdec: rbsp
From: ayaka @ 2019-04-10 12:42 UTC (permalink / raw)
To: linux-media
Cc: Randy Li, hverkuil, maxime.ripard, joro, nicolas, jernej.skrabec,
paul.kocialkowski, thomas.petazzoni, mchehab, ezequiel, posciak,
groeck, linux-rockchip
In-Reply-To: <20190410124226.8612-1-ayaka@soulik.info>
From: Randy Li <randy.li@rock-chips.com>
It is a bit writer.
Signed-off-by: Randy Li <randy.li@rock-chips.com>
---
drivers/staging/rockchip-mpp/rkvdec/rbsp.c | 96 ++++++++++++++++++++++
drivers/staging/rockchip-mpp/rkvdec/rbsp.h | 30 +++++++
2 files changed, 126 insertions(+)
create mode 100644 drivers/staging/rockchip-mpp/rkvdec/rbsp.c
create mode 100644 drivers/staging/rockchip-mpp/rkvdec/rbsp.h
diff --git a/drivers/staging/rockchip-mpp/rkvdec/rbsp.c b/drivers/staging/rockchip-mpp/rkvdec/rbsp.c
new file mode 100644
index 000000000000..3fbc50e9bca1
--- /dev/null
+++ b/drivers/staging/rockchip-mpp/rkvdec/rbsp.c
@@ -0,0 +1,96 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2012 Vista Silicon S.L.
+ * Copyright (C) 2019 Randy Li <ayaka@soulik.info>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <asm-generic/errno-base.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+#include "rbsp.h"
+
+int rbsp_init(struct rbsp *rbsp, void *buf, int size, int bit_pos)
+{
+ if (!buf)
+ return -EINVAL;
+ if (DIV_ROUND_UP(bit_pos, 32) >= size)
+ return -EINVAL;
+
+ rbsp->buf = buf;
+ rbsp->size = size >> 2;
+ rbsp->pos = bit_pos;
+
+ return 0;
+}
+
+static inline int rbsp_read_bit(struct rbsp *rbsp)
+{
+ int shift = rbsp->pos % 32;
+ int ofs = rbsp->pos++ / 32;
+
+ if (ofs >= rbsp->size)
+ return -EINVAL;
+
+ return (rbsp->buf[ofs] >> shift) & 1;
+}
+
+static inline int rbsp_write_bit(struct rbsp *rbsp, int bit)
+{
+ int shift = rbsp->pos % 32;
+ int ofs = rbsp->pos++ / 32;
+
+ if (ofs >= rbsp->size)
+ return -EINVAL;
+
+ rbsp->buf[ofs] &= ~(1 << shift);
+ rbsp->buf[ofs] |= bit << shift;
+
+ return 0;
+}
+
+int rbsp_write_bits(struct rbsp *rbsp, int num, int value)
+{
+ int shift = rbsp->pos % 32;
+ int ofs = rbsp->pos / 32;
+
+ if (ofs >= rbsp->size)
+ return -EINVAL;
+
+ if (num + shift >= 32) {
+ u32 lbits = 32 - shift;
+ u32 hbits = num + shift - 32;
+
+ rbsp->buf[ofs] &= ~(((1 << lbits) - 1) << shift);
+ rbsp->buf[ofs] |= value << shift;
+
+ value >>= (32 - shift);
+ rbsp->buf[ofs + 1] &= ~(((1 << hbits) - 1));
+ rbsp->buf[ofs + 1] |= value;
+ } else {
+ rbsp->buf[ofs] &= ~(((1 << num) - 1) << shift);
+ rbsp->buf[ofs] |= value << shift;
+ }
+
+ rbsp->pos += num;
+
+ return 0;
+}
+
+int rbsp_write_flag(struct rbsp *rbsp, int value)
+{
+ if (value)
+ return rbsp_write_bit(rbsp, BIT(0));
+ else
+ return rbsp_write_bit(rbsp, 0);
+}
diff --git a/drivers/staging/rockchip-mpp/rkvdec/rbsp.h b/drivers/staging/rockchip-mpp/rkvdec/rbsp.h
new file mode 100644
index 000000000000..d87c582bfd41
--- /dev/null
+++ b/drivers/staging/rockchip-mpp/rkvdec/rbsp.h
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2012 Vista Silicon S.L.
+ * Copyright (C) 2019 Randy Li <ayaka@soulik.info>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _RBSP_H_
+#define _RBSP_H_
+
+struct rbsp {
+ u32 *buf;
+ int size;
+ int pos;
+};
+
+int rbsp_init(struct rbsp *rbsp, void *buf, int size, int bit_pos);
+int rbsp_write_flag(struct rbsp *rbsp, int bit);
+int rbsp_write_bits(struct rbsp *rbsp, int num, int value);
+
+#endif
--
2.20.1
^ permalink raw reply related
* [PATCH v3 0/9] [WIP]: rockchip mpp for v4l2 video deocder
From: ayaka @ 2019-04-10 12:42 UTC (permalink / raw)
To: linux-media
Cc: Randy 'ayaka' Li, randy.li, hverkuil, maxime.ripard, joro,
nicolas, jernej.skrabec, paul.kocialkowski, thomas.petazzoni,
mchehab, ezequiel, posciak, groeck, linux-rockchip
From: Randy 'ayaka' Li <ayaka@soulik.info>
Although I really hate the bitstream construction in kernel and I think
many people realise its problems, I still take the advise from ndufresne to
release this version. This should be released in a early week but
I was sick that time.
After reviewed the documents from Rockchip and I have confirmed that with
some rockchip staff, those documents are not update to date. So you may
find some part is different comparing to official document.
The v4l2-request-test from bootlin won't work. Its slice data doesn't
have a start code which making it not a complete nal unit. And I found
its slice header information may not be correct. Even comparing to the
Big buck bunny's origin files, neither the slice data nor sequence
information matches.
I extracted a slice data from Rockchip mpp to verify my driver, it work
fine, you can find it on my github. I only verified the I slice now,
I have not verified P or B slice. Hopefully it would work.
I have the same problem with v4l2-request-test on HEVC as well so even
this version shipped with HEVC bitstream construction, I didn't know
whether it would work.
I need some time to prepare the userspace tool or it is really hard for
HEVC to write slice info manually.
Changlog
v3: add AVC support for rkvdec
v2: add MPEG-2 support for vdpu2
v1: inital version
Randy Li (7):
staging: video: rockchip: add v4l2 decoder
rockchip: mpp: rkvdec: rbsp
[WIP]: rockchip: mpp: HEVC decoder ctrl data
[TEST]: rockchip: mpp: support qtable
[TEST]: rockchip: mpp: vdpu2: move qtable to input buffer
arm64: dts: rockchip: boost clocks for rk3328
arm64: dts: rockchip: add video codec for rk3328
ayaka (2):
[WIP]: rockchip: mpp: H.264 decoder ctrl data
[TEST]: rkvdec: spspps address alignment
arch/arm64/boot/dts/rockchip/rk3328-evb.dts | 32 +
.../arm64/boot/dts/rockchip/rk3328-rock64.dts | 32 +
arch/arm64/boot/dts/rockchip/rk3328.dtsi | 112 +-
drivers/staging/Kconfig | 2 +
drivers/staging/Makefile | 1 +
drivers/staging/rockchip-mpp/Kconfig | 33 +
drivers/staging/rockchip-mpp/Makefile | 12 +
drivers/staging/rockchip-mpp/mpp_debug.h | 87 +
drivers/staging/rockchip-mpp/mpp_dev_common.c | 1390 +++++++
drivers/staging/rockchip-mpp/mpp_dev_common.h | 215 +
drivers/staging/rockchip-mpp/mpp_dev_rkvdec.c | 924 +++++
drivers/staging/rockchip-mpp/mpp_dev_vdpu2.c | 607 +++
drivers/staging/rockchip-mpp/mpp_service.c | 197 +
drivers/staging/rockchip-mpp/mpp_service.h | 38 +
.../staging/rockchip-mpp/rkvdec/avc-data.c | 239 ++
.../staging/rockchip-mpp/rkvdec/avc-data.h | 40 +
drivers/staging/rockchip-mpp/rkvdec/avc.c | 259 ++
drivers/staging/rockchip-mpp/rkvdec/cabac.h | 3614 +++++++++++++++++
drivers/staging/rockchip-mpp/rkvdec/hal.h | 70 +
.../staging/rockchip-mpp/rkvdec/hevc-data.c | 208 +
.../staging/rockchip-mpp/rkvdec/hevc-data.h | 27 +
drivers/staging/rockchip-mpp/rkvdec/hevc.c | 169 +
drivers/staging/rockchip-mpp/rkvdec/rbsp.c | 96 +
drivers/staging/rockchip-mpp/rkvdec/rbsp.h | 30 +
drivers/staging/rockchip-mpp/rkvdec/regs.h | 377 ++
drivers/staging/rockchip-mpp/vdpu2/avc.c | 165 +
drivers/staging/rockchip-mpp/vdpu2/hal.h | 52 +
drivers/staging/rockchip-mpp/vdpu2/mpeg2.c | 277 ++
drivers/staging/rockchip-mpp/vdpu2/regs.h | 670 +++
include/uapi/video/rk_vpu_service.h | 101 +
30 files changed, 10072 insertions(+), 4 deletions(-)
create mode 100644 drivers/staging/rockchip-mpp/Kconfig
create mode 100644 drivers/staging/rockchip-mpp/Makefile
create mode 100644 drivers/staging/rockchip-mpp/mpp_debug.h
create mode 100644 drivers/staging/rockchip-mpp/mpp_dev_common.c
create mode 100644 drivers/staging/rockchip-mpp/mpp_dev_common.h
create mode 100644 drivers/staging/rockchip-mpp/mpp_dev_rkvdec.c
create mode 100644 drivers/staging/rockchip-mpp/mpp_dev_vdpu2.c
create mode 100644 drivers/staging/rockchip-mpp/mpp_service.c
create mode 100644 drivers/staging/rockchip-mpp/mpp_service.h
create mode 100644 drivers/staging/rockchip-mpp/rkvdec/avc-data.c
create mode 100644 drivers/staging/rockchip-mpp/rkvdec/avc-data.h
create mode 100644 drivers/staging/rockchip-mpp/rkvdec/avc.c
create mode 100644 drivers/staging/rockchip-mpp/rkvdec/cabac.h
create mode 100644 drivers/staging/rockchip-mpp/rkvdec/hal.h
create mode 100644 drivers/staging/rockchip-mpp/rkvdec/hevc-data.c
create mode 100644 drivers/staging/rockchip-mpp/rkvdec/hevc-data.h
create mode 100644 drivers/staging/rockchip-mpp/rkvdec/hevc.c
create mode 100644 drivers/staging/rockchip-mpp/rkvdec/rbsp.c
create mode 100644 drivers/staging/rockchip-mpp/rkvdec/rbsp.h
create mode 100644 drivers/staging/rockchip-mpp/rkvdec/regs.h
create mode 100644 drivers/staging/rockchip-mpp/vdpu2/avc.c
create mode 100644 drivers/staging/rockchip-mpp/vdpu2/hal.h
create mode 100644 drivers/staging/rockchip-mpp/vdpu2/mpeg2.c
create mode 100644 drivers/staging/rockchip-mpp/vdpu2/regs.h
create mode 100644 include/uapi/video/rk_vpu_service.h
--
2.20.1
^ permalink raw reply
* [GIT PULL FOR v5.2] Remove deprecated zoran driver
From: Hans Verkuil @ 2019-04-10 12:33 UTC (permalink / raw)
To: Linux Media Mailing List
Remove the deprecated zoran driver.
Regards,
Hans
The following changes since commit 1c3ec30bb23023d738b538e64ac3028902d53692:
media: index.rst: exclude Indexes section from latex/pdf output (2019-03-30 09:42:35 -0400)
are available in the Git repository at:
git://linuxtv.org/hverkuil/media_tree.git tags/br-zoran
for you to fetch changes up to 54af579ead7b55c803b28f122bce0f08ec525810:
zoran: remove deprecated driver (2019-04-10 13:02:49 +0200)
----------------------------------------------------------------
Tag branch
----------------------------------------------------------------
Hans Verkuil (1):
zoran: remove deprecated driver
Documentation/media/v4l-drivers/index.rst | 1 -
Documentation/media/v4l-drivers/zoran.rst | 583 ------------
drivers/staging/media/Kconfig | 2 -
drivers/staging/media/Makefile | 1 -
drivers/staging/media/zoran/Kconfig | 75 --
drivers/staging/media/zoran/Makefile | 7 -
drivers/staging/media/zoran/TODO | 4 -
drivers/staging/media/zoran/videocodec.c | 391 --------
drivers/staging/media/zoran/videocodec.h | 349 --------
drivers/staging/media/zoran/zoran.h | 402 ---------
drivers/staging/media/zoran/zoran_card.c | 1524 --------------------------------
drivers/staging/media/zoran/zoran_card.h | 50 --
drivers/staging/media/zoran/zoran_device.c | 1619 ---------------------------------
drivers/staging/media/zoran/zoran_device.h | 91 --
drivers/staging/media/zoran/zoran_driver.c | 2850 -----------------------------------------------------------
drivers/staging/media/zoran/zoran_procfs.c | 221 -----
drivers/staging/media/zoran/zoran_procfs.h | 32 -
drivers/staging/media/zoran/zr36016.c | 516 -----------
drivers/staging/media/zoran/zr36016.h | 107 ---
drivers/staging/media/zoran/zr36050.c | 896 -------------------
drivers/staging/media/zoran/zr36050.h | 179 ----
drivers/staging/media/zoran/zr36057.h | 164 ----
drivers/staging/media/zoran/zr36060.c | 1006 ---------------------
drivers/staging/media/zoran/zr36060.h | 216 -----
24 files changed, 11286 deletions(-)
delete mode 100644 Documentation/media/v4l-drivers/zoran.rst
delete mode 100644 drivers/staging/media/zoran/Kconfig
delete mode 100644 drivers/staging/media/zoran/Makefile
delete mode 100644 drivers/staging/media/zoran/TODO
delete mode 100644 drivers/staging/media/zoran/videocodec.c
delete mode 100644 drivers/staging/media/zoran/videocodec.h
delete mode 100644 drivers/staging/media/zoran/zoran.h
delete mode 100644 drivers/staging/media/zoran/zoran_card.c
delete mode 100644 drivers/staging/media/zoran/zoran_card.h
delete mode 100644 drivers/staging/media/zoran/zoran_device.c
delete mode 100644 drivers/staging/media/zoran/zoran_device.h
delete mode 100644 drivers/staging/media/zoran/zoran_driver.c
delete mode 100644 drivers/staging/media/zoran/zoran_procfs.c
delete mode 100644 drivers/staging/media/zoran/zoran_procfs.h
delete mode 100644 drivers/staging/media/zoran/zr36016.c
delete mode 100644 drivers/staging/media/zoran/zr36016.h
delete mode 100644 drivers/staging/media/zoran/zr36050.c
delete mode 100644 drivers/staging/media/zoran/zr36050.h
delete mode 100644 drivers/staging/media/zoran/zr36057.h
delete mode 100644 drivers/staging/media/zoran/zr36060.c
delete mode 100644 drivers/staging/media/zoran/zr36060.h
^ permalink raw reply
* [GIT PULL FOR v5.2] Various fixes
From: Hans Verkuil @ 2019-04-10 12:26 UTC (permalink / raw)
To: Linux Media Mailing List
The following changes since commit 1c3ec30bb23023d738b538e64ac3028902d53692:
media: index.rst: exclude Indexes section from latex/pdf output (2019-03-30 09:42:35 -0400)
are available in the Git repository at:
git://linuxtv.org/hverkuil/media_tree.git tags/br-v5.2d2
for you to fetch changes up to 94448dbf89f7c05bd1ff7d9990491065f8aeb976:
vb2: add waiting_in_dqbuf flag (2019-04-10 12:51:16 +0200)
----------------------------------------------------------------
Tag branch
----------------------------------------------------------------
Alexander Potapenko (1):
media: vivid: use vfree() instead of kfree() for dev->bitmap_cap
Dan Carpenter (1):
media: pvrusb2: Prevent a buffer overflow
Hans Verkuil (2):
videobuf2-v4l2.c: move up STATE_DEQUEUED check
vb2: add waiting_in_dqbuf flag
Jernej Skrabec (1):
media: cedrus: Fix initialization order
Maoguang Meng (1):
media: mtk-vcodec: fix vp9 content playback error with show exist frame
drivers/media/common/videobuf2/videobuf2-core.c | 22 ++++++++++++++++++++++
drivers/media/common/videobuf2/videobuf2-v4l2.c | 11 ++++++-----
drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c | 16 +++++++---------
drivers/media/platform/vivid/vivid-vid-cap.c | 2 +-
drivers/media/usb/pvrusb2/pvrusb2-hdw.c | 2 ++
drivers/media/usb/pvrusb2/pvrusb2-hdw.h | 1 +
drivers/staging/media/sunxi/cedrus/cedrus.c | 24 ++++++++++++------------
include/media/videobuf2-core.h | 1 +
8 files changed, 52 insertions(+), 27 deletions(-)
^ permalink raw reply
* Re: [bug report] [media] mxb: fix audio handling
From: Dan Carpenter @ 2019-04-10 11:39 UTC (permalink / raw)
To: Hans Verkuil; +Cc: hans.verkuil, linux-media
In-Reply-To: <9b5791ce-6de7-c769-ac14-2b155a44a438@xs4all.nl>
On Wed, Apr 10, 2019 at 01:24:44PM +0200, Hans Verkuil wrote:
> On 4/10/19 1:09 PM, Dan Carpenter wrote:
> > [ Hi Hans,
> >
> > This might not really be your bug, but I just respect you a lot and
> > so I always come to you with questions and for advice. -dan ]
>
> Hmm, in other words, I'm too nice!
>
Indeed.
> > 657 if (mxb->cur_audinput != a->index) {
> > 658 mxb->cur_audinput = a->index;
> > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> > Now here's the complication. We also use a->index as an index into the
> > mxb_inputs[] array which only has MXB_INPUTS (4) elements, so just
>
> We do? Where does that happen? I don't see that in the code. That would be
> a bug since mxb_inputs are the video inputs, whereas s_audio deals with
> audio inputs.
>
Oh, you're right. But then there is a smaller problem because we use
it as in index into the mxb_audios[] array and that array only has 6
elements so we're still out of bounds. The bigger array has a mute
element at the end.
regards,
dan carpenter
^ permalink raw reply
* Re: [bug report] [media] mxb: fix audio handling
From: Hans Verkuil @ 2019-04-10 11:24 UTC (permalink / raw)
To: Dan Carpenter, hans.verkuil; +Cc: linux-media
In-Reply-To: <20190410110934.GA3459@kadam>
On 4/10/19 1:09 PM, Dan Carpenter wrote:
> [ Hi Hans,
>
> This might not really be your bug, but I just respect you a lot and
> so I always come to you with questions and for advice. -dan ]
Hmm, in other words, I'm too nice!
>
> Hello Hans Verkuil,
>
> The patch 6680427791c9: "[media] mxb: fix audio handling" from Apr
> 30, 2012, leads to the following static checker warning:
>
> drivers/media/pci/saa7146/mxb.c:196 tea6420_route()
> warn: uncapped user index 'TEA6420_cd[idx]'
>
> drivers/media/pci/saa7146/mxb.c
> 194 static inline void tea6420_route(struct mxb *mxb, int idx)
> 195 {
> --> 196 v4l2_subdev_call(mxb->tea6420_1, audio, s_routing,
> 197 TEA6420_cd[idx][0].input, TEA6420_cd[idx][0].output, 0);
> ^^^
> Index overflow. The TEA6420_cd[] array has MXB_AUDIOS + 1 (which is 7
> altogether) elements.
>
> 198 v4l2_subdev_call(mxb->tea6420_2, audio, s_routing,
> 199 TEA6420_cd[idx][1].input, TEA6420_cd[idx][1].output, 0);
> 200 v4l2_subdev_call(mxb->tea6420_1, audio, s_routing,
> 201 TEA6420_line[idx][0].input, TEA6420_line[idx][0].output, 0);
> 202 v4l2_subdev_call(mxb->tea6420_2, audio, s_routing,
> 203 TEA6420_line[idx][1].input, TEA6420_line[idx][1].output, 0);
> 204 }
>
> [ snip ]
>
> 650 static int vidioc_s_audio(struct file *file, void *fh, const struct v4l2_audio *a)
> 651 {
> 652 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
> 653 struct mxb *mxb = (struct mxb *)dev->ext_priv;
> 654
> 655 DEB_D("VIDIOC_S_AUDIO %d\n", a->index);
> 656 if (mxb_inputs[mxb->cur_input].audioset & (1 << a->index)) {
>
> This a->index comes from the ioctl and it's a u32 so the shift can wrap.
> The .audioset variable is always 0x3f. In other words BIT(6) is the
> highest valid bit so we could add a check:
>
> if (a->index > MXB_AUDIOS)
> return;
That's correct.
>
> 657 if (mxb->cur_audinput != a->index) {
> 658 mxb->cur_audinput = a->index;
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> Now here's the complication. We also use a->index as an index into the
> mxb_inputs[] array which only has MXB_INPUTS (4) elements, so just
We do? Where does that happen? I don't see that in the code. That would be
a bug since mxb_inputs are the video inputs, whereas s_audio deals with
audio inputs.
Regards,
Hans
> adding the limit would still lead to a different array out of bounds
> later...
>
> 659 tea6420_route(mxb, a->index);
> 660 if (mxb->cur_audinput == 0)
> 661 mxb_update_audmode(mxb);
> 662 }
> 663 return 0;
> 664 }
> 665 return -EINVAL;
> 666 }
>
> regards,
> dan carpenter
>
^ permalink raw reply
* Re: [PATCH] media: omap_vout: potential buffer overflow in vidioc_dqbuf()
From: Dan Carpenter @ 2019-04-10 11:14 UTC (permalink / raw)
To: Hans Verkuil
Cc: Mauro Carvalho Chehab, Amber Jain, Niklas Söderlund,
Philipp Zabel, Benoit Parrot, linux-media, kernel-janitors,
Andrzej Hajda
In-Reply-To: <eb4fe291-85b5-540b-c210-5e9fb051f2cc@xs4all.nl>
On Wed, Apr 10, 2019 at 12:50:31PM +0200, Hans Verkuil wrote:
> On 4/9/19 1:29 PM, Dan Carpenter wrote:
> > diff --git a/drivers/media/platform/omap/omap_vout.c b/drivers/media/platform/omap/omap_vout.c
> > index 37f0d7146dfa..15e38990e85a 100644
> > --- a/drivers/media/platform/omap/omap_vout.c
> > +++ b/drivers/media/platform/omap/omap_vout.c
> > @@ -1527,8 +1527,6 @@ static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
> > unsigned long size;
> > struct videobuf_buffer *vb;
> >
> > - vb = q->bufs[b->index];
> > -
> > if (!vout->streaming)
> > return -EINVAL;
> >
> > @@ -1539,6 +1537,8 @@ static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
> > /* Call videobuf_dqbuf for blocking mode */
> > ret = videobuf_dqbuf(q, (struct v4l2_buffer *)b, 0);
>
> We need a:
>
> if (ret)
> return ret;
>
> here. Or alternatively, add 'if (!ret)' around the next five lines.
>
> b->index is only valid if the videobuf_dqbuf call returned 0.
>
Doh. Thanks.
regards,
dan carpenter
^ permalink raw reply
* [bug report] [media] mxb: fix audio handling
From: Dan Carpenter @ 2019-04-10 11:09 UTC (permalink / raw)
To: hans.verkuil; +Cc: linux-media
[ Hi Hans,
This might not really be your bug, but I just respect you a lot and
so I always come to you with questions and for advice. -dan ]
Hello Hans Verkuil,
The patch 6680427791c9: "[media] mxb: fix audio handling" from Apr
30, 2012, leads to the following static checker warning:
drivers/media/pci/saa7146/mxb.c:196 tea6420_route()
warn: uncapped user index 'TEA6420_cd[idx]'
drivers/media/pci/saa7146/mxb.c
194 static inline void tea6420_route(struct mxb *mxb, int idx)
195 {
--> 196 v4l2_subdev_call(mxb->tea6420_1, audio, s_routing,
197 TEA6420_cd[idx][0].input, TEA6420_cd[idx][0].output, 0);
^^^
Index overflow. The TEA6420_cd[] array has MXB_AUDIOS + 1 (which is 7
altogether) elements.
198 v4l2_subdev_call(mxb->tea6420_2, audio, s_routing,
199 TEA6420_cd[idx][1].input, TEA6420_cd[idx][1].output, 0);
200 v4l2_subdev_call(mxb->tea6420_1, audio, s_routing,
201 TEA6420_line[idx][0].input, TEA6420_line[idx][0].output, 0);
202 v4l2_subdev_call(mxb->tea6420_2, audio, s_routing,
203 TEA6420_line[idx][1].input, TEA6420_line[idx][1].output, 0);
204 }
[ snip ]
650 static int vidioc_s_audio(struct file *file, void *fh, const struct v4l2_audio *a)
651 {
652 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
653 struct mxb *mxb = (struct mxb *)dev->ext_priv;
654
655 DEB_D("VIDIOC_S_AUDIO %d\n", a->index);
656 if (mxb_inputs[mxb->cur_input].audioset & (1 << a->index)) {
This a->index comes from the ioctl and it's a u32 so the shift can wrap.
The .audioset variable is always 0x3f. In other words BIT(6) is the
highest valid bit so we could add a check:
if (a->index > MXB_AUDIOS)
return;
657 if (mxb->cur_audinput != a->index) {
658 mxb->cur_audinput = a->index;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Now here's the complication. We also use a->index as an index into the
mxb_inputs[] array which only has MXB_INPUTS (4) elements, so just
adding the limit would still lead to a different array out of bounds
later...
659 tea6420_route(mxb, a->index);
660 if (mxb->cur_audinput == 0)
661 mxb_update_audmode(mxb);
662 }
663 return 0;
664 }
665 return -EINVAL;
666 }
regards,
dan carpenter
^ permalink raw reply
* [GIT PULL for 5.2] Mipid02, ImgU and sensor driver patches
From: Sakari Ailus @ 2019-04-10 10:51 UTC (permalink / raw)
To: linux-media
Hi Mauro,
Here's another set of sensor driver patches for 5.2. Included are also a
new driver for ST mipid02 CSI-2 to parallel converter as well as some
improvements for the ImgU driver.
Please pull.
The following changes since commit 1c3ec30bb23023d738b538e64ac3028902d53692:
media: index.rst: exclude Indexes section from latex/pdf output (2019-03-30 09:42:35 -0400)
are available in the git repository at:
ssh://linuxtv.org/git/sailus/media_tree.git tags/for-5.1-4-signed
for you to fetch changes up to 895be0bf180177f15a92f668b6599d2bb8dc0f19:
ipu3-imgu: Use %u for formatting unsigned values (not %d) (2019-04-10 13:49:37 +0300)
----------------------------------------------------------------
mipid02 + cio2 + sensor patches
----------------------------------------------------------------
Akinobu Mita (2):
media: ov2659: make S_FMT ioctl succeed even if requested format doesn't match
media: ov2659: fix unbalanced mutex_lock/unlock
Bingbu Cao (1):
media:staging/intel-ipu3: parameter buffer refactoring
Janusz Krzysztofik (3):
media: ov6650: Fix sensor possibly not detected on probe
media: ov6650: Move v4l2_clk_get() to ov6650_video_probe() helper
media: ov6650: Register with asynchronous subdevice framework
Mickael Guene (3):
media: uapi: Add MEDIA_BUS_FMT_BGR888_3X8 media bus format
dt-bindings: Document MIPID02 bindings
media: st-mipid02: MIPID02 CSI-2 to PARALLEL bridge driver
Sakari Ailus (1):
ipu3-imgu: Use %u for formatting unsigned values (not %d)
.../bindings/media/i2c/st,st-mipid02.txt | 82 ++
Documentation/media/uapi/v4l/subdev-formats.rst | 107 ++
MAINTAINERS | 8 +
drivers/media/i2c/Kconfig | 13 +
drivers/media/i2c/Makefile | 1 +
drivers/media/i2c/ov2659.c | 8 +-
drivers/media/i2c/ov6650.c | 43 +-
drivers/media/i2c/st-mipid02.c | 1033 ++++++++++++++++++++
drivers/staging/media/ipu3/ipu3-css.c | 5 -
drivers/staging/media/ipu3/ipu3-v4l2.c | 86 +-
drivers/staging/media/ipu3/ipu3.c | 30 +
include/uapi/linux/media-bus-format.h | 3 +-
12 files changed, 1345 insertions(+), 74 deletions(-)
create mode 100644 Documentation/devicetree/bindings/media/i2c/st,st-mipid02.txt
create mode 100644 drivers/media/i2c/st-mipid02.c
--
Sakari Ailus
^ permalink raw reply
* Re: [PATCH] media: omap_vout: potential buffer overflow in vidioc_dqbuf()
From: Hans Verkuil @ 2019-04-10 10:50 UTC (permalink / raw)
To: Dan Carpenter, Mauro Carvalho Chehab, Amber Jain
Cc: Niklas Söderlund, Philipp Zabel, Benoit Parrot, linux-media,
kernel-janitors, Andrzej Hajda
In-Reply-To: <20190409112924.GA13643@kadam>
On 4/9/19 1:29 PM, Dan Carpenter wrote:
> The "b->index" is a u32 the comes from the user in the ioctl. It hasn't
> been checked. We aren't supposed to use it but we're instead supposed
> to use the value that gets written to it when we call videobuf_dqbuf().
>
> The videobuf_dqbuf() first memsets it to zero and then re-initializes it
> inside the videobuf_status() function. It's this final value which we
> want.
>
> Fixes: 72915e851da9 ("[media] V4L2: OMAP: VOUT: dma map and unmap v4l2 buffers in qbuf and dqbuf")
> Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
> ---
> UNTESTED! I think I understand this code now, but I have struggled to
> read it correctly in the past. Please review carefully.
>
>
> drivers/media/platform/omap/omap_vout.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/media/platform/omap/omap_vout.c b/drivers/media/platform/omap/omap_vout.c
> index 37f0d7146dfa..15e38990e85a 100644
> --- a/drivers/media/platform/omap/omap_vout.c
> +++ b/drivers/media/platform/omap/omap_vout.c
> @@ -1527,8 +1527,6 @@ static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
> unsigned long size;
> struct videobuf_buffer *vb;
>
> - vb = q->bufs[b->index];
> -
> if (!vout->streaming)
> return -EINVAL;
>
> @@ -1539,6 +1537,8 @@ static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
> /* Call videobuf_dqbuf for blocking mode */
> ret = videobuf_dqbuf(q, (struct v4l2_buffer *)b, 0);
We need a:
if (ret)
return ret;
here. Or alternatively, add 'if (!ret)' around the next five lines.
b->index is only valid if the videobuf_dqbuf call returned 0.
Regards,
Hans
>
> + vb = q->bufs[b->index];
> +
> addr = (unsigned long) vout->buf_phy_addr[vb->i];
> size = (unsigned long) vb->size;
> dma_unmap_single(vout->vid_dev->v4l2_dev.dev, addr,
>
^ permalink raw reply
* Re: [PATCH] staging: media: zoran: fix trailing whitespaces
From: Hans Verkuil @ 2019-04-10 10:44 UTC (permalink / raw)
To: Dan Carpenter, Arthur Moraes do Lago
Cc: mchehab, gregkh, mjpeg-users, linux-media, devel, linux-kernel,
lkcamp
In-Reply-To: <20190408065103.GA6095@kadam>
On 4/8/19 8:51 AM, Dan Carpenter wrote:
> On Mon, Apr 08, 2019 at 01:35:30AM -0300, Arthur Moraes do Lago wrote:
>> There were several form feeds(^L) in the file, this patch removes them
>> to conform with the coding style.
>>
>> Signed-off-by: Arthur Moraes do Lago <arthurmoraeslago@gmail.com>
>> ---
>> drivers/staging/media/zoran/videocodec.h | 10 +++++-----
>> 1 file changed, 5 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/staging/media/zoran/videocodec.h b/drivers/staging/media/zoran/videocodec.h
>> index 4946791fce0d..c37c0e4fb624 100644
>> --- a/drivers/staging/media/zoran/videocodec.h
>> +++ b/drivers/staging/media/zoran/videocodec.h
>> @@ -49,7 +49,7 @@
>> device dependent and vary between MJPEG/MPEG/WAVELET/... devices. (!!!!)
>> ----------------------------------------------------------------------------
>> */
>> -\f
>> +
>>
>
> Checkpatch also complains if you have two consecutive blank lines so
> really we should just delete the lines entirely... But this driver is
> scheduled for deletion in May. Let's not bother with cleaning it up.
>
> regards,
> dan carpenter
>
I will in fact post a pull request to remove this driver today.
Regards,
Hans
^ permalink raw reply
* Re: [PATCH v5 03/13] media: v4l2-fwnode: add initial connector parsing support
From: Marco Felsch @ 2019-04-10 10:31 UTC (permalink / raw)
To: Jacopo Mondi
Cc: mchehab, sakari.ailus, hans.verkuil, jacopo+renesas, robh+dt,
p.zabel, javierm, laurent.pinchart, linux-media, devicetree,
kernel
In-Reply-To: <20190405130631.nl2magnbtasxoqle@uno.localdomain>
Hi Jacopo,
On 19-04-05 15:06, Jacopo Mondi wrote:
> Hi Marco,
> thanks for the patch
thanks for the fast response =)
> On Fri, Apr 05, 2019 at 08:03:07AM +0200, Marco Felsch wrote:
> > The patch adds the initial connector parsing code, so we can move from a
> > driver specific parsing code to a generic one. Currently only the
> > generic fields and the analog-connector specific fields are parsed. Parsing
> > the other connector specific fields can be added by a simple callbacks.
> >
> > Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
> > ---
> >
> > [1] https://patchwork.kernel.org/cover/10794703/
> >
> > v5:
> > - s/strlcpy/strscpy/
> >
> > v2-v4:
> > - nothing since the patch was squashed from series [1] into this
> > series.
> >
> > drivers/media/v4l2-core/v4l2-fwnode.c | 113 ++++++++++++++++++++++++++
> > include/media/v4l2-fwnode.h | 16 ++++
> > 2 files changed, 129 insertions(+)
> >
> > diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c
> > index 20571846e636..a6bbe42ca518 100644
> > --- a/drivers/media/v4l2-core/v4l2-fwnode.c
> > +++ b/drivers/media/v4l2-core/v4l2-fwnode.c
> > @@ -592,6 +592,119 @@ void v4l2_fwnode_put_link(struct v4l2_fwnode_link *link)
> > }
> > EXPORT_SYMBOL_GPL(v4l2_fwnode_put_link);
> >
> > +static const struct v4l2_fwnode_connector_conv {
> > + enum v4l2_connector_type type;
> > + const char *name;
> > +} connectors[] = {
> > + {
> > + .type = V4L2_CON_COMPOSITE,
> > + .name = "composite-video-connector",
> > + }, {
> > + .type = V4L2_CON_SVIDEO,
> > + .name = "svideo-connector",
> > + }, {
> > + .type = V4L2_CON_VGA,
> > + .name = "vga-connector",
> > + }, {
> > + .type = V4L2_CON_DVI,
> > + .name = "dvi-connector",
> > + }, {
> > + .type = V4L2_CON_HDMI,
> > + .name = "hdmi-connector"
> > + }
> > +};
> > +
> > +static enum v4l2_connector_type
> > +v4l2_fwnode_string_to_connector_type(const char *con_str)
> > +{
> > + int i;
>
> unsigned int
Okay.
> > +
> > + for (i = 0; i < ARRAY_SIZE(connectors); i++)
> > + if (!strcmp(con_str, connectors[i].name))
> > + return connectors[i].type;
> > +
> > + /* no valid connector found */
> > + return V4L2_CON_UNKNOWN;
> > +}
> > +
> > +static int
> > +v4l2_fwnode_connector_parse_analog(struct fwnode_handle *fwnode,
> > + struct v4l2_fwnode_connector *vc)
> > +{
> > + u32 tvnorms;
> > + int ret;
> > +
> > + ret = fwnode_property_read_u32(fwnode, "tvnorms", &tvnorms);
> > +
> > + /* set it to V4L2_STD_ALL in case of not specified tvnorms */
>
> Is this comment needed?
Nope, let me reword it to: "tvnorms is optional"
> > + vc->connector.analog.supported_tvnorms = ret ? V4L2_STD_ALL : tvnorms;
>
> empty line before return?
Yes.
> > + return 0;
> > +}
> > +
> > +int v4l2_fwnode_parse_connector(struct fwnode_handle *__fwnode,
> > + struct v4l2_fwnode_connector *connector)
> > +{
> > + struct fwnode_handle *fwnode;
> > + struct fwnode_endpoint __ep;
> > + const char *c_type_str, *label;
> > + int ret;
> > +
> > + memset(connector, 0, sizeof(*connector));
> > +
> > + fwnode = fwnode_graph_get_remote_port_parent(__fwnode);
>
> You should fwnode_handle_put(fwnode) when done and in the error path
Of course.
> > +
> > + /* 1st parse all common properties */
> > + /* connector-type is stored within the compatible string */
> > + ret = fwnode_property_read_string(fwnode, "compatible", &c_type_str);
> > + if (ret)
> > + return -EINVAL;
> > +
> > + connector->type = v4l2_fwnode_string_to_connector_type(c_type_str);
> > +
> > + fwnode_graph_parse_endpoint(__fwnode, &__ep);
> > + connector->remote_port = __ep.port;
> > + connector->remote_id = __ep.id;
> > +
> > + ret = fwnode_property_read_string(fwnode, "label", &label);
> > + if (!ret) {
> > + /* ensure label doesn't exceed V4L2_CONNECTOR_MAX_LABEL size */
> > + strscpy(connector->label, label, V4L2_CONNECTOR_MAX_LABEL);
> > + } else {
> > + /*
> > + * labels are optional, if no one is given create one:
>
> s/no one/none.
Okay.
> > + * <connector-type-string>@port<endpoint_port>/ep<endpoint_id>
> > + */
> > + snprintf(connector->label, V4L2_CONNECTOR_MAX_LABEL,
> > + "%s@port%u/ep%u", c_type_str, connector->remote_port,
> > + connector->remote_id);
> > + }
> > +
> > + /* now parse the connector specific properties */
> > + switch (connector->type) {
> > + /* fall through */
>
> Could you move the /* fall through */ comment below case?
Yes.
> > + case V4L2_CON_COMPOSITE:
> here
> > + case V4L2_CON_SVIDEO:
> > + ret = v4l2_fwnode_connector_parse_analog(fwnode, connector);
> > + break;
> > + /* fall through */
> > + case V4L2_CON_VGA:
> here
> > + case V4L2_CON_DVI:
> here
> > + case V4L2_CON_HDMI:
> > + pr_warn("Connector specific parsing is currently not supported for %s\n",
> > + c_type_str);
> > + ret = 0;
> > + break;
> > + /* fall through */
> > + case V4L2_CON_UNKNOWN:
> and here
> > + default:
> > + pr_err("Unknown connector type\n");
> > + ret = -EINVAL;
> > + };
> > +
> > + return ret;
> > +}
> > +EXPORT_SYMBOL_GPL(v4l2_fwnode_parse_connector);
> > +
> > static int
> > v4l2_async_notifier_fwnode_parse_endpoint(struct device *dev,
> > struct v4l2_async_notifier *notifier,
> > diff --git a/include/media/v4l2-fwnode.h b/include/media/v4l2-fwnode.h
> > index 04344b71656f..aa8bbef8589b 100644
> > --- a/include/media/v4l2-fwnode.h
> > +++ b/include/media/v4l2-fwnode.h
> > @@ -269,6 +269,22 @@ int v4l2_fwnode_parse_link(struct fwnode_handle *fwnode,
> > */
> > void v4l2_fwnode_put_link(struct v4l2_fwnode_link *link);
> >
> > +/**
> > + * v4l2_fwnode_parse_connector() - parse the connector on endpoint
> > + * @fwnode: pointer to the endpoint's fwnode handle where the connector is
> > + * connected to.
>
> No full stop please (even if this is highly unconsistent in this
> header, some lines have it, some don't, but it seems to me the most of
> them do not)
Yes I see it.. damn.
> > + * @connector: pointer to the V4L2 fwnode connector data structure
> > + *
> > + * Fill the connector data structure with the connector type, label and the
> > + * endpoint id and port where the connector belongs to. If no label is present
> > + * a unique one will be created. Labels with more than 40 characters are cut.
> > + *
> > + * Return: %0 on success or a negative error code on failure:
> > + * %-EINVAL on parsing failure
>
> This matches the other function's documentation style. Nice!
>
> > + */
> > +int v4l2_fwnode_parse_connector(struct fwnode_handle *fwnode,
> > + struct v4l2_fwnode_connector *connector);
> > +
>
> All minor comments:
> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
Thanks for the review, I will add it in the next version.
> Thanks
> j
>
Regards,
Marco
> > /**
> > * typedef parse_endpoint_func - Driver's callback function to be called on
> > * each V4L2 fwnode endpoint.
> > --
> > 2.20.1
> >
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply
* Re: [PATCH v5 02/13] media: v4l2-fwnode: add v4l2_fwnode_connector
From: Marco Felsch @ 2019-04-10 9:51 UTC (permalink / raw)
To: Jacopo Mondi
Cc: mchehab, sakari.ailus, hans.verkuil, jacopo+renesas, robh+dt,
p.zabel, javierm, laurent.pinchart, linux-media, devicetree,
kernel
In-Reply-To: <20190405124303.lkfdd3pqnlxinke4@uno.localdomain>
Hi Jacopo,
On 19-04-05 14:43, Jacopo Mondi wrote:
> Hi Marco,
>
> On Fri, Apr 05, 2019 at 08:03:06AM +0200, Marco Felsch wrote:
> > Currently every driver needs to parse the connector endpoints by it self.
> > This is the initial work to make this generic. The generic connector has
> > some common fields and some connector specific parts. The generic one
> > includes:
> > - type
> > - label
> > - remote_port (the port where the connector is connected to)
> > - remote_id (the endpoint where the connector is connected to)
> >
> > The specific fields are within a union, since only one of them can be
> > available at the time. Since this is the initial support the patch adds
> > only the analog-connector specific ones.
> >
> > Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
> > ---
> > include/media/v4l2-connector.h | 34 ++++++++++++++++++++++++++++++++++
> > include/media/v4l2-fwnode.h | 33 +++++++++++++++++++++++++++++++++
> > 2 files changed, 67 insertions(+)
> > create mode 100644 include/media/v4l2-connector.h
> >
> > diff --git a/include/media/v4l2-connector.h b/include/media/v4l2-connector.h
> > new file mode 100644
> > index 000000000000..967336e38215
> > --- /dev/null
> > +++ b/include/media/v4l2-connector.h
> > @@ -0,0 +1,34 @@
> > +/* SPDX-License-Identifier: GPL-2.0-only */
> > +/*
> > + * v4l2-connector.h
> > + *
> > + * V4L2 connector types.
> > + *
> > + * Copyright 2019 Pengutronix, Marco Felsch <kernel@pengutronix.de>
> > + */
> > +
> > +#ifndef V4L2_CONNECTOR_H
> > +#define V4L2_CONNECTOR_H
> > +
> > +#define V4L2_CONNECTOR_MAX_LABEL 41
> > +
> > +/**
> > + * enum v4l2_connector_type - connector type
> > + * @V4L2_CON_UNKNOWN: unknown connector type, no V4L2 connetor configuration
> > + * @V4L2_CON_COMPOSITE: analog composite connector
> > + * @V4L2_CON_SVIDEO: analog svideo connector
> > + * @V4L2_CON_VGA: analog vga connector
> > + * @V4L2_CON_DVI: analog or digital dvi connector
> > + * @V4L2_CON_HDMI: digital hdmi connetor
> > + */
> > +enum v4l2_connector_type {
> > + V4L2_CON_UNKNOWN,
> > + V4L2_CON_COMPOSITE,
> > + V4L2_CON_SVIDEO,
> > + V4L2_CON_VGA,
> > + V4L2_CON_DVI,
> > + V4L2_CON_HDMI,
> > +};
> > +
> > +#endif /* V4L2_CONNECTOR_H */
> > +
> > diff --git a/include/media/v4l2-fwnode.h b/include/media/v4l2-fwnode.h
> > index 6c07825e18b9..04344b71656f 100644
> > --- a/include/media/v4l2-fwnode.h
> > +++ b/include/media/v4l2-fwnode.h
> > @@ -22,6 +22,7 @@
> > #include <linux/list.h>
> > #include <linux/types.h>
> >
> > +#include <media/v4l2-connector.h>
> > #include <media/v4l2-mediabus.h>
> > #include <media/v4l2-subdev.h>
> >
> > @@ -126,6 +127,38 @@ struct v4l2_fwnode_link {
> > unsigned int remote_port;
> > };
> >
> > +/**
> > + * struct v4l2_fwnode_connector_analog - analog connector data structure
> > + * @supported_tvnorms: tv norms this connector supports, set to V4L2_STD_ALL
> > + * if no restrictions are specified.
> > + */
> > +struct v4l2_fwnode_connector_analog {
> > + v4l2_std_id supported_tvnorms;
> > +};
> > +
> > +/** struct v4l2_fwnode_connector - the connector data structure
>
> Break the line please
Yes, missed that.
> > + * @remote_port: identifier of the port the remote endpoint belongs to
>
> I liked best the description in the commmit message:
> @remote_port: identifier of the remote endpoint port the connector connects to
>
> but I see the exact same sentence you used already in an existing
> comment, so feel free to chose the one you prefer.
Let me change this. I was inspired by the v4l2_fwnode_link description.
I think the commit description is a bit intuitiver.
> > + * @remote_id: identifier of the id the remote endpoint belongs to
>
> identifier of the remote endpoint the connector connect/belong to?
Here too.
> > + * @label: connetor label
> > + * @type: connector type
> > + * @connector: union with connector configuration data struct
>
> just "connector configuration" ?
Yes that sounds better.
> > + * @connector.analog: embedded &struct v4l2_fwnode_connector_analog.
> > + * Used if connector is of type analog.
>
> just "analog connector configuration" ?
>
The connector and connetor.analog description is inspired by the
v4l2_fwnode_endpoint description. Your sounds a bit more natural so I
will pick them.
> > + */
> > +struct v4l2_fwnode_connector {
> > + /* common fields for all v4l2_fwnode_connectors */
>
> I would drop this
Okay, I will drop both commit messages.
> > + unsigned int remote_port;
> > + unsigned int remote_id;
> > + char label[V4L2_CONNECTOR_MAX_LABEL];
> > + enum v4l2_connector_type type;
> > +
> > + /* connector specific fields */
>
> and this too :)
>
> All minor stuff, feel free to pick what you like from the comments.
Thanks a lot for the review =) I will add your Reviewed-by tag in the
next verion.
> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
>
> Thanks
> j
Regards,
Marco
> > + union {
> > + struct v4l2_fwnode_connector_analog analog;
> > + /* future connectors */
> > + } connector;
> > +};
> > +
> > /**
> > * v4l2_fwnode_endpoint_parse() - parse all fwnode node properties
> > * @fwnode: pointer to the endpoint's fwnode handle
> > --
> > 2.20.1
> >
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply
* Re: [PATCHv2 7/7] cros-ec-cec: decrement HDMI device refcount
From: Neil Armstrong @ 2019-04-10 9:30 UTC (permalink / raw)
To: Hans Verkuil, linux-media
Cc: Sylwester Nawrocki, Benjamin Gaignard, Thierry Reding,
Ettore Chimenti, Wen Yang
In-Reply-To: <20190410091334.8654-8-hverkuil-cisco@xs4all.nl>
On 10/04/2019 11:13, Hans Verkuil wrote:
> The CrosEC CEC driver never decremented the HDMI device refcount.
> CEC drivers only need the HDMI device pointer as a key in the
> notifier list, it never accesses the device, so there is no
> need to keep a reference.
>
> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
> ---
> drivers/media/platform/cros-ec-cec/cros-ec-cec.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/media/platform/cros-ec-cec/cros-ec-cec.c b/drivers/media/platform/cros-ec-cec/cros-ec-cec.c
> index 7bc4d8a9af28..068df9888dbf 100644
> --- a/drivers/media/platform/cros-ec-cec/cros-ec-cec.c
> +++ b/drivers/media/platform/cros-ec-cec/cros-ec-cec.c
> @@ -236,6 +236,7 @@ static int cros_ec_cec_get_notifier(struct device *dev,
> return -EPROBE_DEFER;
>
> *notify = cec_notifier_get_conn(d, m->conn);
> + put_device(d);
> return 0;
> }
> }
>
Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox