Merge pull request #3852 from jernejsk/cedrus_update

Allwinner: ffmpeg: Update v4l2 request api chain
This commit is contained in:
Jonas Karlman 2019-09-19 21:45:36 +02:00 committed by GitHub
commit c44ba726c2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 1684 additions and 116 deletions

View File

@ -1,7 +1,7 @@
From 7ab07a6b9a8ac8a91213bcbba4a63dc9db03cb53 Mon Sep 17 00:00:00 2001
From e6cec3f54693e7e2c10b6b7bc8f72daa6e9a77dc Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Mon, 3 Dec 2018 23:48:04 +0100
Subject: [PATCH 1/6] avutil: add av_buffer_pool_reclaim()
Subject: [PATCH] avutil: add av_buffer_pool_flush()
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
---
@ -10,14 +10,14 @@ Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
2 files changed, 18 insertions(+)
diff --git a/libavutil/buffer.c b/libavutil/buffer.c
index 8d1aa5fa84..9c5d530c7a 100644
index 8d1aa5fa84..58160f62f3 100644
--- a/libavutil/buffer.c
+++ b/libavutil/buffer.c
@@ -272,6 +272,19 @@ static void buffer_pool_free(AVBufferPool *pool)
av_freep(&pool);
}
+void av_buffer_pool_reclaim(AVBufferPool *pool)
+void av_buffer_pool_flush(AVBufferPool *pool)
+{
+ ff_mutex_lock(&pool->mutex);
+ while (pool->pool) {
@ -34,7 +34,7 @@ index 8d1aa5fa84..9c5d530c7a 100644
{
AVBufferPool *pool;
diff --git a/libavutil/buffer.h b/libavutil/buffer.h
index 73b6bd0b14..fab745f853 100644
index 73b6bd0b14..0678fa4bea 100644
--- a/libavutil/buffer.h
+++ b/libavutil/buffer.h
@@ -266,6 +266,11 @@ AVBufferPool *av_buffer_pool_init2(int size, void *opaque,
@ -44,11 +44,8 @@ index 73b6bd0b14..fab745f853 100644
+/**
+ * Free all available buffers in a buffer pool.
+ */
+ void av_buffer_pool_reclaim(AVBufferPool *pool);
+ void av_buffer_pool_flush(AVBufferPool *pool);
+
/**
* Mark the pool as being available for freeing. It will actually be freed only
* once all the allocated buffers associated with the pool are released. Thus it
--
2.21.0

View File

@ -1,21 +1,21 @@
From 0ba3c868e1d828520b8facaa4ce36d9b80339cc6 Mon Sep 17 00:00:00 2001
From b810081f898fc4faec35519c6e7e9d275bf2bbcf Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Sat, 15 Dec 2018 22:32:16 +0100
Subject: [PATCH 2/6] Add common V4L2 request API code
Subject: [PATCH] Add common V4L2 request API code
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
---
configure | 12 +
libavcodec/Makefile | 1 +
libavcodec/hwaccel.h | 2 +
libavcodec/v4l2_request.c | 888 ++++++++++++++++++++++++++++++++++++++
libavcodec/v4l2_request.h | 65 +++
5 files changed, 968 insertions(+)
libavcodec/v4l2_request.c | 919 ++++++++++++++++++++++++++++++++++++++
libavcodec/v4l2_request.h | 69 +++
5 files changed, 1003 insertions(+)
create mode 100644 libavcodec/v4l2_request.c
create mode 100644 libavcodec/v4l2_request.h
diff --git a/configure b/configure
index 172611bb4a..6401cae9e7 100755
index 15e6c321b1..7f9e7e7b25 100755
--- a/configure
+++ b/configure
@@ -264,6 +264,7 @@ External library support:
@ -112,10 +112,10 @@ index 3aaa92571c..2eefc91e7e 100644
#endif /* AVCODEC_HWACCEL_H */
diff --git a/libavcodec/v4l2_request.c b/libavcodec/v4l2_request.c
new file mode 100644
index 0000000000..4589209e60
index 0000000000..bf9d049eff
--- /dev/null
+++ b/libavcodec/v4l2_request.c
@@ -0,0 +1,888 @@
@@ -0,0 +1,919 @@
+/*
+ * This file is part of FFmpeg.
+ *
@ -185,6 +185,37 @@ index 0000000000..4589209e60
+ return ioctl(ctx->video_fd, VIDIOC_S_EXT_CTRLS, &controls);
+}
+
+int ff_v4l2_request_set_controls(AVCodecContext *avctx, struct v4l2_ext_control *control, int count)
+{
+ V4L2RequestContext *ctx = avctx->internal->hwaccel_priv_data;
+ int ret;
+
+ ret = v4l2_request_set_controls(ctx, -1, control, count);
+ if (ret < 0) {
+ av_log(avctx, AV_LOG_ERROR, "%s: set controls failed, %s (%d)\n", __func__, strerror(errno), errno);
+ return AVERROR(EINVAL);
+ }
+
+ return ret;
+}
+
+int ff_v4l2_request_query_control_default_value(AVCodecContext *avctx, uint32_t id)
+{
+ int ret;
+ V4L2RequestContext *ctx = avctx->internal->hwaccel_priv_data;
+ struct v4l2_queryctrl control = {
+ .id = id,
+ };
+
+ ret = ioctl(ctx->video_fd, VIDIOC_QUERYCTRL, &control);
+ if (ret < 0) {
+ av_log(avctx, AV_LOG_ERROR, "%s: query control failed, %s (%d)\n", __func__, strerror(errno), errno);
+ return AVERROR(EINVAL);
+ }
+
+ return control.default_value;
+}
+
+static int v4l2_request_queue_buffer(V4L2RequestContext *ctx, int request_fd, V4L2RequestBuffer *buf)
+{
+ struct v4l2_plane planes[1] = {};
@ -779,7 +810,7 @@ index 0000000000..4589209e60
+
+ if (avctx->hw_frames_ctx) {
+ AVHWFramesContext *hwfc = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
+ av_buffer_pool_reclaim(hwfc->pool);
+ av_buffer_pool_flush(hwfc->pool);
+ }
+
+ if (ctx->video_fd >= 0)
@ -962,7 +993,7 @@ index 0000000000..4589209e60
+{
+ av_log(NULL, AV_LOG_DEBUG, "%s: hwfc=%p pool=%p\n", __func__, hwfc, hwfc->pool);
+
+ av_buffer_pool_reclaim(hwfc->pool);
+ av_buffer_pool_flush(hwfc->pool);
+ av_buffer_pool_uninit(&hwfc->pool);
+}
+
@ -1006,10 +1037,10 @@ index 0000000000..4589209e60
+}
diff --git a/libavcodec/v4l2_request.h b/libavcodec/v4l2_request.h
new file mode 100644
index 0000000000..688962ca94
index 0000000000..1f45772d8b
--- /dev/null
+++ b/libavcodec/v4l2_request.h
@@ -0,0 +1,65 @@
@@ -0,0 +1,69 @@
+/*
+ * This file is part of FFmpeg.
+ *
@ -1066,6 +1097,10 @@ index 0000000000..688962ca94
+
+int ff_v4l2_request_append_output_buffer(AVCodecContext *avctx, AVFrame *frame, const uint8_t *data, uint32_t size);
+
+int ff_v4l2_request_set_controls(AVCodecContext *avctx, struct v4l2_ext_control *control, int count);
+
+int ff_v4l2_request_query_control_default_value(AVCodecContext *avctx, uint32_t id);
+
+int ff_v4l2_request_decode_frame(AVCodecContext *avctx, AVFrame *frame, struct v4l2_ext_control *control, int count);
+
+int ff_v4l2_request_init(AVCodecContext *avctx, uint32_t pixelformat, uint32_t buffersize, struct v4l2_ext_control *control, int count);
@ -1075,6 +1110,3 @@ index 0000000000..688962ca94
+int ff_v4l2_request_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx);
+
+#endif /* AVCODEC_V4L2_REQUEST_H */
--
2.21.0

View File

@ -1,7 +1,7 @@
From f4f6c74953b0bfaadec93b01d855a15f08c558a2 Mon Sep 17 00:00:00 2001
From f31319e29405004b84f17e30602f77dae671b53e Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Sat, 15 Dec 2018 22:32:16 +0100
Subject: [PATCH 3/6] Add V4L2 request API mpeg2 hwaccel
Subject: [PATCH] Add V4L2 request API mpeg2 hwaccel
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
---
@ -14,7 +14,7 @@ Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
create mode 100644 libavcodec/v4l2_request_mpeg2.c
diff --git a/configure b/configure
index 6401cae9e7..b163ed8dbe 100755
index 7f9e7e7b25..6088e8d00c 100755
--- a/configure
+++ b/configure
@@ -2846,6 +2846,8 @@ mpeg2_dxva2_hwaccel_deps="dxva2"
@ -242,6 +242,3 @@ index 0000000000..782b9c2471
+ .frame_params = ff_v4l2_request_frame_params,
+ .caps_internal = HWACCEL_CAP_ASYNC_SAFE,
+};
--
2.21.0

View File

@ -1,7 +1,7 @@
From 250fab0e761f4956c009a6333c6799f63440b091 Mon Sep 17 00:00:00 2001
From 389f6557715439d5fa974f0cc55e1fa68735ec61 Mon Sep 17 00:00:00 2001
From: Jernej Skrabec <jernej.skrabec@siol.net>
Date: Sat, 15 Dec 2018 22:32:16 +0100
Subject: [PATCH 4/6] Add V4L2 request API h264 hwaccel
Subject: [PATCH] Add V4L2 request API h264 hwaccel
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
@ -11,12 +11,12 @@ Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
libavcodec/h264_slice.c | 4 +
libavcodec/h264dec.c | 3 +
libavcodec/hwaccels.h | 1 +
libavcodec/v4l2_request_h264.c | 367 +++++++++++++++++++++++++++++++++
6 files changed, 379 insertions(+)
libavcodec/v4l2_request_h264.c | 420 +++++++++++++++++++++++++++++++++
6 files changed, 432 insertions(+)
create mode 100644 libavcodec/v4l2_request_h264.c
diff --git a/configure b/configure
index b163ed8dbe..698a91d5dc 100755
index 6088e8d00c..a967ae0afb 100755
--- a/configure
+++ b/configure
@@ -2804,6 +2804,8 @@ h264_dxva2_hwaccel_deps="dxva2"
@ -32,7 +32,7 @@ index b163ed8dbe..698a91d5dc 100755
check_cc vp9_v4l2_m2m linux/videodev2.h "int i = V4L2_PIX_FMT_VP9;"
check_func_headers "linux/media.h linux/videodev2.h" v4l2_timeval_to_ns
+check_cc h264_v4l2_request linux/videodev2.h "int i = V4L2_PIX_FMT_H264_SLICE_RAW;"
+check_cc h264_v4l2_request linux/videodev2.h "int i = V4L2_PIX_FMT_H264_SLICE;"
check_cc mpeg2_v4l2_request linux/videodev2.h "int i = V4L2_PIX_FMT_MPEG2_SLICE;"
check_header sys/videoio.h
@ -49,7 +49,7 @@ index 9b945e3f64..2bdfaabb5f 100644
OBJS-$(CONFIG_H264_VDPAU_HWACCEL) += vdpau_h264.o
OBJS-$(CONFIG_H264_VIDEOTOOLBOX_HWACCEL) += videotoolbox.o
diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c
index f78f9f87b0..688d6c4ac2 100644
index af9ec9789b..f1e11003af 100644
--- a/libavcodec/h264_slice.c
+++ b/libavcodec/h264_slice.c
@@ -758,6 +758,7 @@ static enum AVPixelFormat get_pixel_format(H264Context *h, int force_callback)
@ -98,10 +98,10 @@ index ef54de2a3b..003200edea 100644
extern const AVHWAccel ff_h264_videotoolbox_hwaccel;
diff --git a/libavcodec/v4l2_request_h264.c b/libavcodec/v4l2_request_h264.c
new file mode 100644
index 0000000000..3687325fad
index 0000000000..fb9913922d
--- /dev/null
+++ b/libavcodec/v4l2_request_h264.c
@@ -0,0 +1,367 @@
@@ -0,0 +1,420 @@
+/*
+ * This file is part of FFmpeg.
+ *
@ -129,9 +129,17 @@ index 0000000000..3687325fad
+ struct v4l2_ctrl_h264_pps pps;
+ struct v4l2_ctrl_h264_scaling_matrix scaling_matrix;
+ struct v4l2_ctrl_h264_decode_params decode_params;
+ struct v4l2_ctrl_h264_slice_params slice_params;
+ struct v4l2_ctrl_h264_slice_params slice_params[16];
+} V4L2RequestControlsH264;
+
+typedef struct V4L2RequestContextH264 {
+ V4L2RequestContext base;
+ int decode_mode;
+ int start_code;
+} V4L2RequestContextH264;
+
+static uint8_t nalu_slice_start_code[] = { 0x00, 0x00, 0x01 };
+
+static void fill_weight_factors(struct v4l2_h264_weight_factors *factors, int list, const H264SliceContext *sl)
+{
+ for (int i = 0; i < sl->ref_count[list]; i++) {
@ -203,8 +211,7 @@ index 0000000000..3687325fad
+ struct v4l2_h264_dpb_entry *entry = &decode->dpb[i];
+ if ((entry->flags & V4L2_H264_DPB_ENTRY_FLAG_VALID) &&
+ entry->reference_ts == timestamp)
+ // TODO: signal reference type, possible using top 2 bits
+ return i | ((ref->reference & 3) << 6);
+ return i;
+ }
+
+ return 0;
@ -317,7 +324,6 @@ index 0000000000..3687325fad
+{
+ const H264Context *h = avctx->priv_data;
+ V4L2RequestControlsH264 *controls = h->cur_pic_ptr->hwaccel_picture_private;
+ V4L2RequestDescriptor *req = (V4L2RequestDescriptor*)h->cur_pic_ptr->f->data[0];
+
+ struct v4l2_ext_control control[] = {
+ {
@ -338,7 +344,7 @@ index 0000000000..3687325fad
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS,
+ .ptr = &controls->slice_params,
+ .size = sizeof(controls->slice_params),
+ .size = sizeof(controls->slice_params[0]) * FFMIN(controls->decode_params.num_slices, 16),
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS,
@ -347,8 +353,6 @@ index 0000000000..3687325fad
+ },
+ };
+
+ controls->slice_params.size = req->output.used;
+
+ return ff_v4l2_request_decode_frame(avctx, h->cur_pic_ptr->f, control, FF_ARRAY_ELEMS(control));
+}
+
@ -358,20 +362,23 @@ index 0000000000..3687325fad
+ const PPS *pps = h->ps.pps;
+ const H264SliceContext *sl = &h->slice_ctx[0];
+ V4L2RequestControlsH264 *controls = h->cur_pic_ptr->hwaccel_picture_private;
+ V4L2RequestContextH264 *ctx = avctx->internal->hwaccel_priv_data;
+ V4L2RequestDescriptor *req = (V4L2RequestDescriptor*)h->cur_pic_ptr->f->data[0];
+ int i, count;
+ int i, ret, count, slice = FFMIN(controls->decode_params.num_slices, 15);
+
+ if (ctx->decode_mode == V4L2_MPEG_VIDEO_H264_DECODE_MODE_SLICE_BASED && slice) {
+ ret = v4l2_request_h264_end_frame(avctx);
+ if (ret)
+ return ret;
+
+ // HACK: trigger decode per slice
+ if (req->output.used) {
+ v4l2_request_h264_end_frame(avctx);
+ ff_v4l2_request_reset_frame(avctx, h->cur_pic_ptr->f);
+ slice = controls->decode_params.num_slices = 0;
+ }
+
+ controls->decode_params.num_slices++;
+
+ controls->slice_params = (struct v4l2_ctrl_h264_slice_params) {
+ controls->slice_params[slice] = (struct v4l2_ctrl_h264_slice_params) {
+ /* Size in bytes, including header */
+ .size = 0,
+ .start_byte_offset = req->output.used,
+ /* Offset in bits to slice_data() from the beginning of this slice. */
+ .header_bit_size = get_bits_count(&sl->gb),
+
@ -405,28 +412,69 @@ index 0000000000..3687325fad
+ };
+
+ if (FIELD_PICTURE(h))
+ controls->slice_params.flags |= V4L2_H264_SLICE_FLAG_FIELD_PIC;
+ controls->slice_params[slice].flags |= V4L2_H264_SLICE_FLAG_FIELD_PIC;
+ if (h->picture_structure == PICT_BOTTOM_FIELD)
+ controls->slice_params.flags |= V4L2_H264_SLICE_FLAG_BOTTOM_FIELD;
+ controls->slice_params[slice].flags |= V4L2_H264_SLICE_FLAG_BOTTOM_FIELD;
+ if (sl->slice_type == AV_PICTURE_TYPE_B && sl->direct_spatial_mv_pred)
+ controls->slice_params.flags |= V4L2_H264_SLICE_FLAG_DIRECT_SPATIAL_MV_PRED;
+ controls->slice_params[slice].flags |= V4L2_H264_SLICE_FLAG_DIRECT_SPATIAL_MV_PRED;
+
+ controls->slice_params.pred_weight_table.chroma_log2_weight_denom = sl->pwt.chroma_log2_weight_denom;
+ controls->slice_params.pred_weight_table.luma_log2_weight_denom = sl->pwt.luma_log2_weight_denom;
+ controls->slice_params[slice].pred_weight_table.chroma_log2_weight_denom = sl->pwt.chroma_log2_weight_denom;
+ controls->slice_params[slice].pred_weight_table.luma_log2_weight_denom = sl->pwt.luma_log2_weight_denom;
+
+ count = sl->list_count > 0 ? sl->ref_count[0] : 0;
+ for (i = 0; i < count; i++)
+ controls->slice_params.ref_pic_list0[i] = get_dpb_index(&controls->decode_params, &sl->ref_list[0][i]);
+ controls->slice_params[slice].ref_pic_list0[i] = get_dpb_index(&controls->decode_params, &sl->ref_list[0][i]);
+ if (count)
+ fill_weight_factors(&controls->slice_params.pred_weight_table.weight_factors[0], 0, sl);
+ fill_weight_factors(&controls->slice_params[slice].pred_weight_table.weight_factors[0], 0, sl);
+
+ count = sl->list_count > 1 ? sl->ref_count[1] : 0;
+ for (i = 0; i < count; i++)
+ controls->slice_params.ref_pic_list1[i] = get_dpb_index(&controls->decode_params, &sl->ref_list[1][i]);
+ controls->slice_params[slice].ref_pic_list1[i] = get_dpb_index(&controls->decode_params, &sl->ref_list[1][i]);
+ if (count)
+ fill_weight_factors(&controls->slice_params.pred_weight_table.weight_factors[1], 1, sl);
+ fill_weight_factors(&controls->slice_params[slice].pred_weight_table.weight_factors[1], 1, sl);
+
+ return ff_v4l2_request_append_output_buffer(avctx, h->cur_pic_ptr->f, buffer, size);
+ if (ctx->start_code == V4L2_MPEG_VIDEO_H264_START_CODE_ANNEX_B) {
+ ret = ff_v4l2_request_append_output_buffer(avctx, h->cur_pic_ptr->f, nalu_slice_start_code, 3);
+ if (ret)
+ return ret;
+ }
+
+ ret = ff_v4l2_request_append_output_buffer(avctx, h->cur_pic_ptr->f, buffer, size);
+ if (ret)
+ return ret;
+
+ controls->slice_params[slice].size = req->output.used - controls->slice_params[slice].start_byte_offset;
+ controls->decode_params.num_slices++;
+ return 0;
+}
+
+static int v4l2_request_h264_set_controls(AVCodecContext *avctx)
+{
+ V4L2RequestContextH264 *ctx = avctx->internal->hwaccel_priv_data;
+
+ struct v4l2_ext_control control[] = {
+ { .id = V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE, },
+ { .id = V4L2_CID_MPEG_VIDEO_H264_START_CODE, },
+ };
+
+ ctx->decode_mode = ff_v4l2_request_query_control_default_value(avctx, V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE);
+ if (ctx->decode_mode != V4L2_MPEG_VIDEO_H264_DECODE_MODE_SLICE_BASED &&
+ ctx->decode_mode != V4L2_MPEG_VIDEO_H264_DECODE_MODE_FRAME_BASED) {
+ av_log(avctx, AV_LOG_ERROR, "%s: unsupported decode mode, %d\n", __func__, ctx->decode_mode);
+ return AVERROR(EINVAL);
+ }
+
+ ctx->start_code = ff_v4l2_request_query_control_default_value(avctx, V4L2_CID_MPEG_VIDEO_H264_START_CODE);
+ if (ctx->start_code != V4L2_MPEG_VIDEO_H264_START_CODE_NONE &&
+ ctx->start_code != V4L2_MPEG_VIDEO_H264_START_CODE_ANNEX_B) {
+ av_log(avctx, AV_LOG_ERROR, "%s: unsupported start code, %d\n", __func__, ctx->start_code);
+ return AVERROR(EINVAL);
+ }
+
+ control[0].value = ctx->decode_mode;
+ control[1].value = ctx->start_code;
+
+ return ff_v4l2_request_set_controls(avctx, control, FF_ARRAY_ELEMS(control));
+}
+
+static int v4l2_request_h264_init(AVCodecContext *avctx)
@ -434,6 +482,7 @@ index 0000000000..3687325fad
+ const H264Context *h = avctx->priv_data;
+ struct v4l2_ctrl_h264_sps sps;
+ struct v4l2_ctrl_h264_pps pps;
+ int ret;
+
+ struct v4l2_ext_control control[] = {
+ {
@ -451,7 +500,11 @@ index 0000000000..3687325fad
+ fill_sps(&sps, h);
+ fill_pps(&pps, h);
+
+ return ff_v4l2_request_init(avctx, V4L2_PIX_FMT_H264_SLICE_RAW, 2 * 1024 * 1024, control, FF_ARRAY_ELEMS(control));
+ ret = ff_v4l2_request_init(avctx, V4L2_PIX_FMT_H264_SLICE, 2 * 1024 * 1024, control, FF_ARRAY_ELEMS(control));
+ if (ret)
+ return ret;
+
+ return v4l2_request_h264_set_controls(avctx);
+}
+
+const AVHWAccel ff_h264_v4l2request_hwaccel = {
@ -465,10 +518,7 @@ index 0000000000..3687325fad
+ .frame_priv_data_size = sizeof(V4L2RequestControlsH264),
+ .init = v4l2_request_h264_init,
+ .uninit = ff_v4l2_request_uninit,
+ .priv_data_size = sizeof(V4L2RequestContext),
+ .priv_data_size = sizeof(V4L2RequestContextH264),
+ .frame_params = ff_v4l2_request_frame_params,
+ .caps_internal = HWACCEL_CAP_ASYNC_SAFE,
+};
--
2.21.0

View File

@ -1,7 +1,7 @@
From 55751072c14f2ef678489be3d527f34604bb5602 Mon Sep 17 00:00:00 2001
From 0cd5948e34df8acdbc84efc7ce662eee03ce88e3 Mon Sep 17 00:00:00 2001
From: Jernej Skrabec <jernej.skrabec@siol.net>
Date: Sat, 15 Dec 2018 22:32:16 +0100
Subject: [PATCH 5/6] Add V4L2 request API hevc hwaccel
Subject: [PATCH] Add V4L2 request API hevc hwaccel
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
@ -15,7 +15,7 @@ Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
create mode 100644 libavcodec/v4l2_request_hevc.c
diff --git a/configure b/configure
index 698a91d5dc..2d39cecbdf 100755
index a967ae0afb..d07cd27d88 100755
--- a/configure
+++ b/configure
@@ -2820,6 +2820,8 @@ hevc_dxva2_hwaccel_deps="dxva2 DXVA_PicParams_HEVC"
@ -30,7 +30,7 @@ index 698a91d5dc..2d39cecbdf 100755
@@ -6246,6 +6248,7 @@ check_cc vp9_v4l2_m2m linux/videodev2.h "int i = V4L2_PIX_FMT_VP9;"
check_func_headers "linux/media.h linux/videodev2.h" v4l2_timeval_to_ns
check_cc h264_v4l2_request linux/videodev2.h "int i = V4L2_PIX_FMT_H264_SLICE_RAW;"
check_cc h264_v4l2_request linux/videodev2.h "int i = V4L2_PIX_FMT_H264_SLICE;"
+check_cc hevc_v4l2_request linux/videodev2.h "int i = V4L2_PIX_FMT_HEVC_SLICE;"
check_cc mpeg2_v4l2_request linux/videodev2.h "int i = V4L2_PIX_FMT_MPEG2_SLICE;"
@ -48,7 +48,7 @@ index 2bdfaabb5f..a4c959e0f5 100644
OBJS-$(CONFIG_HEVC_VDPAU_HWACCEL) += vdpau_hevc.o
OBJS-$(CONFIG_MJPEG_NVDEC_HWACCEL) += nvdec_mjpeg.o
diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c
index c8877626d2..df33433150 100644
index 2c33a1ff57..d717850eeb 100644
--- a/libavcodec/hevcdec.c
+++ b/libavcodec/hevcdec.c
@@ -362,6 +362,7 @@ static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps)
@ -79,7 +79,7 @@ index c8877626d2..df33433150 100644
#endif
break;
case AV_PIX_FMT_YUV420P12:
@@ -3556,6 +3563,9 @@ AVCodec ff_hevc_decoder = {
@@ -3566,6 +3573,9 @@ AVCodec ff_hevc_decoder = {
#endif
#if CONFIG_HEVC_VIDEOTOOLBOX_HWACCEL
HWACCEL_VIDEOTOOLBOX(hevc),
@ -498,6 +498,3 @@ index 0000000000..38969d77fb
+ .frame_params = ff_v4l2_request_frame_params,
+ .caps_internal = HWACCEL_CAP_ASYNC_SAFE,
+};
--
2.21.0

View File

@ -0,0 +1,282 @@
From 2537bdd10973c0fc3f757cab01fd71dd0ef6b1e1 Mon Sep 17 00:00:00 2001
From: Boris Brezillon <boris.brezillon@collabora.com>
Date: Wed, 22 May 2019 14:46:58 +0200
Subject: [PATCH] Add V4L2 request API vp8 hwaccel
Need to fix the STREAMOFF/STREAMON issue in a proper way.
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
---
configure | 3 +
libavcodec/Makefile | 1 +
libavcodec/hwaccels.h | 1 +
libavcodec/v4l2_request_vp8.c | 180 ++++++++++++++++++++++++++++++++++
libavcodec/vp8.c | 8 +-
5 files changed, 192 insertions(+), 1 deletion(-)
create mode 100644 libavcodec/v4l2_request_vp8.c
diff --git a/configure b/configure
index d07cd27d88..46bcf32d3d 100755
--- a/configure
+++ b/configure
@@ -2884,6 +2884,8 @@ vp8_nvdec_hwaccel_deps="nvdec"
vp8_nvdec_hwaccel_select="vp8_decoder"
vp8_vaapi_hwaccel_deps="vaapi VAPictureParameterBufferVP8"
vp8_vaapi_hwaccel_select="vp8_decoder"
+vp8_v4l2request_hwaccel_deps="v4l2_request vp8_v4l2_request"
+vp8_v4l2request_hwaccel_select="vp8_decoder"
vp9_d3d11va_hwaccel_deps="d3d11va DXVA_PicParams_VP9"
vp9_d3d11va_hwaccel_select="vp9_decoder"
vp9_d3d11va2_hwaccel_deps="d3d11va DXVA_PicParams_VP9"
@@ -6250,6 +6252,7 @@ check_func_headers "linux/media.h linux/videodev2.h" v4l2_timeval_to_ns
check_cc h264_v4l2_request linux/videodev2.h "int i = V4L2_PIX_FMT_H264_SLICE;"
check_cc hevc_v4l2_request linux/videodev2.h "int i = V4L2_PIX_FMT_HEVC_SLICE;"
check_cc mpeg2_v4l2_request linux/videodev2.h "int i = V4L2_PIX_FMT_MPEG2_SLICE;"
+check_cc vp8_v4l2_request linux/videodev2.h "int i = V4L2_PIX_FMT_VP8_FRAME;"
check_header sys/videoio.h
test_code cc sys/videoio.h "struct v4l2_frmsizeenum vfse; vfse.discrete.width = 0;" && enable_sanitized struct_v4l2_frmivalenum_discrete
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index a4c959e0f5..0249defb4f 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -890,6 +890,7 @@ OBJS-$(CONFIG_VC1_VAAPI_HWACCEL) += vaapi_vc1.o
OBJS-$(CONFIG_VC1_VDPAU_HWACCEL) += vdpau_vc1.o
OBJS-$(CONFIG_VP8_NVDEC_HWACCEL) += nvdec_vp8.o
OBJS-$(CONFIG_VP8_VAAPI_HWACCEL) += vaapi_vp8.o
+OBJS-$(CONFIG_VP8_V4L2REQUEST_HWACCEL) += v4l2_request_vp8.o
OBJS-$(CONFIG_VP9_D3D11VA_HWACCEL) += dxva2_vp9.o
OBJS-$(CONFIG_VP9_DXVA2_HWACCEL) += dxva2_vp9.o
OBJS-$(CONFIG_VP9_NVDEC_HWACCEL) += nvdec_vp9.o
diff --git a/libavcodec/hwaccels.h b/libavcodec/hwaccels.h
index d183675abe..0fca5be557 100644
--- a/libavcodec/hwaccels.h
+++ b/libavcodec/hwaccels.h
@@ -66,6 +66,7 @@ extern const AVHWAccel ff_vc1_vaapi_hwaccel;
extern const AVHWAccel ff_vc1_vdpau_hwaccel;
extern const AVHWAccel ff_vp8_nvdec_hwaccel;
extern const AVHWAccel ff_vp8_vaapi_hwaccel;
+extern const AVHWAccel ff_vp8_v4l2request_hwaccel;
extern const AVHWAccel ff_vp9_d3d11va_hwaccel;
extern const AVHWAccel ff_vp9_d3d11va2_hwaccel;
extern const AVHWAccel ff_vp9_dxva2_hwaccel;
diff --git a/libavcodec/v4l2_request_vp8.c b/libavcodec/v4l2_request_vp8.c
new file mode 100644
index 0000000000..d24252c5e5
--- /dev/null
+++ b/libavcodec/v4l2_request_vp8.c
@@ -0,0 +1,180 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "hwaccel.h"
+#include "v4l2_request.h"
+#include "vp8.h"
+
+typedef struct V4L2RequestControlsVP8 {
+ struct v4l2_ctrl_vp8_frame_header ctrl;
+} V4L2RequestControlsVP8;
+
+static int v4l2_request_vp8_start_frame(AVCodecContext *avctx,
+ av_unused const uint8_t *buffer,
+ av_unused uint32_t size)
+{
+ const VP8Context *s = avctx->priv_data;
+ V4L2RequestControlsVP8 *controls = s->framep[VP56_FRAME_CURRENT]->hwaccel_picture_private;
+
+ memset(&controls->ctrl, 0, sizeof(controls->ctrl));
+ return ff_v4l2_request_reset_frame(avctx, s->framep[VP56_FRAME_CURRENT]->tf.f);
+}
+
+static int v4l2_request_vp8_end_frame(AVCodecContext *avctx)
+{
+ const VP8Context *s = avctx->priv_data;
+ V4L2RequestControlsVP8 *controls = s->framep[VP56_FRAME_CURRENT]->hwaccel_picture_private;
+ struct v4l2_ext_control control[] = {
+ {
+ .id = V4L2_CID_MPEG_VIDEO_VP8_FRAME_HEADER,
+ .ptr = &controls->ctrl,
+ .size = sizeof(controls->ctrl),
+ },
+ };
+
+ return ff_v4l2_request_decode_frame(avctx, s->framep[VP56_FRAME_CURRENT]->tf.f,
+ control, FF_ARRAY_ELEMS(control));
+}
+
+static int v4l2_request_vp8_decode_slice(AVCodecContext *avctx,
+ const uint8_t *buffer,
+ uint32_t size)
+{
+ const VP8Context *s = avctx->priv_data;
+ V4L2RequestControlsVP8 *controls = s->framep[VP56_FRAME_CURRENT]->hwaccel_picture_private;
+ struct v4l2_ctrl_vp8_frame_header *hdr = &controls->ctrl;
+ const uint8_t *data = buffer + 3 + 7 * s->keyframe;
+ unsigned int i, j, k;
+
+ hdr->version = s->profile & 0x3;
+ hdr->width = avctx->width;
+ hdr->height = avctx->height;
+ /* FIXME: set ->xx_scale */
+ hdr->prob_skip_false = s->prob->mbskip;
+ hdr->prob_intra = s->prob->intra;
+ hdr->prob_gf = s->prob->golden;
+ hdr->prob_last = s->prob->last;
+ hdr->first_part_size = s->header_partition_size;
+ hdr->first_part_header_bits = (8 * (s->coder_state_at_header_end.input - data) -
+ s->coder_state_at_header_end.bit_count - 8);
+ hdr->num_dct_parts = s->num_coeff_partitions;
+ for (i = 0; i < 8; i++)
+ hdr->dct_part_sizes[i] = s->coeff_partition_size[i];
+
+ hdr->coder_state.range = s->coder_state_at_header_end.range;
+ hdr->coder_state.value = s->coder_state_at_header_end.value;
+ hdr->coder_state.bit_count = s->coder_state_at_header_end.bit_count;
+ if (s->framep[VP56_FRAME_PREVIOUS])
+ hdr->last_frame_ts = ff_v4l2_request_get_capture_timestamp(s->framep[VP56_FRAME_PREVIOUS]->tf.f);
+ if (s->framep[VP56_FRAME_GOLDEN])
+ hdr->golden_frame_ts = ff_v4l2_request_get_capture_timestamp(s->framep[VP56_FRAME_GOLDEN]->tf.f);
+ if (s->framep[VP56_FRAME_GOLDEN2])
+ hdr->alt_frame_ts = ff_v4l2_request_get_capture_timestamp(s->framep[VP56_FRAME_GOLDEN2]->tf.f);
+ hdr->flags |= s->invisible ? 0 : V4L2_VP8_FRAME_HEADER_FLAG_SHOW_FRAME;
+ hdr->flags |= s->mbskip_enabled ? V4L2_VP8_FRAME_HEADER_FLAG_MB_NO_SKIP_COEFF : 0;
+ hdr->flags |= (s->profile & 0x4) ? V4L2_VP8_FRAME_HEADER_FLAG_EXPERIMENTAL : 0;
+ hdr->flags |= s->keyframe ? V4L2_VP8_FRAME_HEADER_FLAG_KEY_FRAME : 0;
+ hdr->flags |= s->sign_bias[VP56_FRAME_GOLDEN] ? V4L2_VP8_FRAME_HEADER_FLAG_SIGN_BIAS_GOLDEN : 0;
+ hdr->flags |= s->sign_bias[VP56_FRAME_GOLDEN2] ? V4L2_VP8_FRAME_HEADER_FLAG_SIGN_BIAS_ALT : 0;
+ hdr->segment_header.flags |= s->segmentation.enabled ? V4L2_VP8_SEGMENT_HEADER_FLAG_ENABLED : 0;
+ hdr->segment_header.flags |= s->segmentation.update_map ? V4L2_VP8_SEGMENT_HEADER_FLAG_UPDATE_MAP : 0;
+ hdr->segment_header.flags |= s->segmentation.update_feature_data ? V4L2_VP8_SEGMENT_HEADER_FLAG_UPDATE_FEATURE_DATA : 0;
+ hdr->segment_header.flags |= s->segmentation.absolute_vals ? 0 : V4L2_VP8_SEGMENT_HEADER_FLAG_DELTA_VALUE_MODE;
+ for (i = 0; i < 4; i++) {
+ hdr->segment_header.quant_update[i] = s->segmentation.base_quant[i];
+ hdr->segment_header.lf_update[i] = s->segmentation.filter_level[i];
+ }
+
+ for (i = 0; i < 3; i++)
+ hdr->segment_header.segment_probs[i] = s->prob->segmentid[i];
+
+ hdr->lf_header.level = s->filter.level;
+ hdr->lf_header.sharpness_level = s->filter.sharpness;
+ hdr->lf_header.flags |= s->lf_delta.enabled ? V4L2_VP8_LF_HEADER_ADJ_ENABLE : 0;
+ hdr->lf_header.flags |= s->lf_delta.update ? V4L2_VP8_LF_HEADER_DELTA_UPDATE : 0;
+ hdr->lf_header.flags |= s->filter.simple ? V4L2_VP8_LF_FILTER_TYPE_SIMPLE : 0;
+ for (i = 0; i < 4; i++) {
+ hdr->lf_header.ref_frm_delta[i] = s->lf_delta.ref[i];
+ hdr->lf_header.mb_mode_delta[i] = s->lf_delta.mode[i + MODE_I4x4];
+ }
+
+ // Probabilites
+ if (s->keyframe) {
+ static const uint8_t keyframe_y_mode_probs[4] = {
+ 145, 156, 163, 128
+ };
+ static const uint8_t keyframe_uv_mode_probs[3] = {
+ 142, 114, 183
+ };
+
+ memcpy(hdr->entropy_header.y_mode_probs, keyframe_y_mode_probs, 4);
+ memcpy(hdr->entropy_header.uv_mode_probs, keyframe_uv_mode_probs, 3);
+ } else {
+ for (i = 0; i < 4; i++)
+ hdr->entropy_header.y_mode_probs[i] = s->prob->pred16x16[i];
+ for (i = 0; i < 3; i++)
+ hdr->entropy_header.uv_mode_probs[i] = s->prob->pred8x8c[i];
+ }
+ for (i = 0; i < 2; i++)
+ for (j = 0; j < 19; j++)
+ hdr->entropy_header.mv_probs[i][j] = s->prob->mvc[i][j];
+
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 8; j++) {
+ static const int coeff_bands_inverse[8] = {
+ 0, 1, 2, 3, 5, 6, 4, 15
+ };
+ int coeff_pos = coeff_bands_inverse[j];
+
+ for (k = 0; k < 3; k++) {
+ memcpy(hdr->entropy_header.coeff_probs[i][j][k],
+ s->prob->token[i][coeff_pos][k], 11);
+ }
+ }
+ }
+
+ hdr->quant_header.y_ac_qi = s->quant.yac_qi;
+ hdr->quant_header.y_dc_delta = s->quant.ydc_delta;
+ hdr->quant_header.y2_dc_delta = s->quant.y2dc_delta;
+ hdr->quant_header.y2_ac_delta = s->quant.y2ac_delta;
+ hdr->quant_header.uv_dc_delta = s->quant.uvdc_delta;
+ hdr->quant_header.uv_ac_delta = s->quant.uvac_delta;
+
+ return ff_v4l2_request_append_output_buffer(avctx, s->framep[VP56_FRAME_CURRENT]->tf.f, buffer, size);
+}
+
+static int v4l2_request_vp8_init(AVCodecContext *avctx)
+{
+ return ff_v4l2_request_init(avctx, V4L2_PIX_FMT_VP8_FRAME, 1024 * 1024, NULL, 0);
+}
+
+const AVHWAccel ff_vp8_v4l2request_hwaccel = {
+ .name = "vp8_v4l2request",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_VP8,
+ .pix_fmt = AV_PIX_FMT_DRM_PRIME,
+ .start_frame = v4l2_request_vp8_start_frame,
+ .decode_slice = v4l2_request_vp8_decode_slice,
+ .end_frame = v4l2_request_vp8_end_frame,
+ .frame_priv_data_size = sizeof(V4L2RequestControlsVP8),
+ .init = v4l2_request_vp8_init,
+ .uninit = ff_v4l2_request_uninit,
+ .priv_data_size = sizeof(V4L2RequestContext),
+ .frame_params = ff_v4l2_request_frame_params,
+ .caps_internal = HWACCEL_CAP_ASYNC_SAFE,
+};
diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c
index 62b9f8bc2d..55966b9d56 100644
--- a/libavcodec/vp8.c
+++ b/libavcodec/vp8.c
@@ -175,6 +175,9 @@ static enum AVPixelFormat get_pixel_format(VP8Context *s)
#endif
#if CONFIG_VP8_NVDEC_HWACCEL
AV_PIX_FMT_CUDA,
+#endif
+#if CONFIG_VP8_V4L2REQUEST_HWACCEL
+ AV_PIX_FMT_DRM_PRIME,
#endif
AV_PIX_FMT_YUV420P,
AV_PIX_FMT_NONE,
@@ -198,7 +201,7 @@ int update_dimensions(VP8Context *s, int width, int height, int is_vp7)
return ret;
}
- if (!s->actually_webp && !is_vp7) {
+ if (!s->actually_webp && !is_vp7 && s->pix_fmt == AV_PIX_FMT_NONE) {
s->pix_fmt = get_pixel_format(s);
if (s->pix_fmt < 0)
return AVERROR(EINVAL);
@@ -2969,6 +2972,9 @@ AVCodec ff_vp8_decoder = {
#endif
#if CONFIG_VP8_NVDEC_HWACCEL
HWACCEL_NVDEC(vp8),
+#endif
+#if CONFIG_VP8_V4L2REQUEST_HWACCEL
+ HWACCEL_V4L2REQUEST(vp8),
#endif
NULL
},

View File

@ -1,24 +1,27 @@
From d80cbc949372d6f19dc8c3b5f97b336864bd259c Mon Sep 17 00:00:00 2001
From be39d2e3e5228cdc2cf355d85f5566205f6cb65d Mon Sep 17 00:00:00 2001
From: Jernej Skrabec <jernej.skrabec@siol.net>
Date: Thu, 14 Feb 2019 23:20:05 +0100
Subject: [PATCH 6/6] Add and use private linux headers for V4L2 request API
ctrls
Subject: [PATCH] Add and use private linux headers for V4L2 request API ctrls
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
configure | 4 +-
libavcodec/h264-ctrls.h | 197 +++++++++++++++++++++++++++++++
libavcodec/hevc-ctrls.h | 203 ++++++++++++++++++++++++++++++++
configure | 6 +-
libavcodec/h264-ctrls.h | 210 ++++++++++++++++++++++++++++++++
libavcodec/hevc-ctrls.h | 203 ++++++++++++++++++++++++++++++
libavcodec/mpeg2-ctrls.h | 82 +++++++++++++
libavcodec/v4l2_request_h264.c | 1 +
libavcodec/v4l2_request_hevc.c | 1 +
libavcodec/v4l2_request_mpeg2.c | 1 +
7 files changed, 487 insertions(+), 2 deletions(-)
libavcodec/v4l2_request_vp8.c | 1 +
libavcodec/vp8-ctrls.h | 112 +++++++++++++++++
9 files changed, 614 insertions(+), 3 deletions(-)
create mode 100644 libavcodec/h264-ctrls.h
create mode 100644 libavcodec/hevc-ctrls.h
create mode 100644 libavcodec/mpeg2-ctrls.h
create mode 100644 libavcodec/vp8-ctrls.h
diff --git a/configure b/configure
index 2d39cecbdf..23b1e57882 100755
index 46bcf32d3d..0c842b920f 100755
--- a/configure
+++ b/configure
@@ -2804,7 +2804,7 @@ h264_dxva2_hwaccel_deps="dxva2"
@ -39,12 +42,21 @@ index 2d39cecbdf..23b1e57882 100755
hevc_v4l2request_hwaccel_select="hevc_decoder"
hevc_vaapi_hwaccel_deps="vaapi VAPictureParameterBufferHEVC"
hevc_vaapi_hwaccel_select="hevc_decoder"
@@ -2884,7 +2884,7 @@ vp8_nvdec_hwaccel_deps="nvdec"
vp8_nvdec_hwaccel_select="vp8_decoder"
vp8_vaapi_hwaccel_deps="vaapi VAPictureParameterBufferVP8"
vp8_vaapi_hwaccel_select="vp8_decoder"
-vp8_v4l2request_hwaccel_deps="v4l2_request vp8_v4l2_request"
+vp8_v4l2request_hwaccel_deps="v4l2_request"
vp8_v4l2request_hwaccel_select="vp8_decoder"
vp9_d3d11va_hwaccel_deps="d3d11va DXVA_PicParams_VP9"
vp9_d3d11va_hwaccel_select="vp9_decoder"
diff --git a/libavcodec/h264-ctrls.h b/libavcodec/h264-ctrls.h
new file mode 100644
index 0000000000..e1404d78d6
index 0000000000..e877bf1d53
--- /dev/null
+++ b/libavcodec/h264-ctrls.h
@@ -0,0 +1,197 @@
@@ -0,0 +1,210 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * These are the H.264 state controls for use with stateless H.264
@ -61,7 +73,7 @@ index 0000000000..e1404d78d6
+#include <linux/videodev2.h>
+
+/* Our pixel format isn't stable at the moment */
+#define V4L2_PIX_FMT_H264_SLICE_RAW v4l2_fourcc('S', '2', '6', '4') /* H264 parsed slices */
+#define V4L2_PIX_FMT_H264_SLICE v4l2_fourcc('S', '2', '6', '4') /* H264 parsed slices */
+
+/*
+ * This is put insanely high to avoid conflicting with controls that
@ -73,6 +85,8 @@ index 0000000000..e1404d78d6
+#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)
+#define V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE (V4L2_CID_MPEG_BASE+1005)
+#define V4L2_CID_MPEG_VIDEO_H264_START_CODE (V4L2_CID_MPEG_BASE+1006)
+
+/* enum v4l2_ctrl_type type values */
+#define V4L2_CTRL_TYPE_H264_SPS 0x0110
@ -81,6 +95,16 @@ index 0000000000..e1404d78d6
+#define V4L2_CTRL_TYPE_H264_SLICE_PARAMS 0x0113
+#define V4L2_CTRL_TYPE_H264_DECODE_PARAMS 0x0114
+
+enum v4l2_mpeg_video_h264_decode_mode {
+ V4L2_MPEG_VIDEO_H264_DECODE_MODE_SLICE_BASED,
+ V4L2_MPEG_VIDEO_H264_DECODE_MODE_FRAME_BASED,
+};
+
+enum v4l2_mpeg_video_h264_start_code {
+ V4L2_MPEG_VIDEO_H264_START_CODE_NONE,
+ V4L2_MPEG_VIDEO_H264_START_CODE_ANNEX_B,
+};
+
+#define V4L2_H264_SPS_CONSTRAINT_SET0_FLAG 0x01
+#define V4L2_H264_SPS_CONSTRAINT_SET1_FLAG 0x02
+#define V4L2_H264_SPS_CONSTRAINT_SET2_FLAG 0x04
@ -172,6 +196,10 @@ index 0000000000..e1404d78d6
+struct v4l2_ctrl_h264_slice_params {
+ /* Size in bytes, including header */
+ __u32 size;
+
+ /* Offset in bytes to the start of slice in the OUTPUT buffer. */
+ __u32 start_byte_offset;
+
+ /* Offset in bits to slice_data() from the beginning of this slice. */
+ __u32 header_bit_size;
+
@ -233,9 +261,6 @@ index 0000000000..e1404d78d6
+ 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_* */
@ -540,7 +565,7 @@ index 0000000000..6601455b3d
+
+#endif
diff --git a/libavcodec/v4l2_request_h264.c b/libavcodec/v4l2_request_h264.c
index 3687325fad..2145a974eb 100644
index fb9913922d..b826c9d356 100644
--- a/libavcodec/v4l2_request_h264.c
+++ b/libavcodec/v4l2_request_h264.c
@@ -19,6 +19,7 @@
@ -575,6 +600,133 @@ index 782b9c2471..37a4eae62c 100644
typedef struct V4L2RequestControlsMPEG2 {
struct v4l2_ctrl_mpeg2_slice_params slice_params;
--
2.21.0
diff --git a/libavcodec/v4l2_request_vp8.c b/libavcodec/v4l2_request_vp8.c
index d24252c5e5..c290fe8b9a 100644
--- a/libavcodec/v4l2_request_vp8.c
+++ b/libavcodec/v4l2_request_vp8.c
@@ -19,6 +19,7 @@
#include "hwaccel.h"
#include "v4l2_request.h"
#include "vp8.h"
+#include "vp8-ctrls.h"
typedef struct V4L2RequestControlsVP8 {
struct v4l2_ctrl_vp8_frame_header ctrl;
diff --git a/libavcodec/vp8-ctrls.h b/libavcodec/vp8-ctrls.h
new file mode 100644
index 0000000000..53cba826e4
--- /dev/null
+++ b/libavcodec/vp8-ctrls.h
@@ -0,0 +1,112 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * These are the VP8 state controls for use with stateless VP8
+ * 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 _VP8_CTRLS_H_
+#define _VP8_CTRLS_H_
+
+#include <linux/types.h>
+
+#define V4L2_PIX_FMT_VP8_FRAME v4l2_fourcc('V', 'P', '8', 'F')
+
+#define V4L2_CID_MPEG_VIDEO_VP8_FRAME_HEADER (V4L2_CID_MPEG_BASE + 2000)
+#define V4L2_CTRL_TYPE_VP8_FRAME_HEADER 0x301
+
+#define V4L2_VP8_SEGMENT_HEADER_FLAG_ENABLED 0x01
+#define V4L2_VP8_SEGMENT_HEADER_FLAG_UPDATE_MAP 0x02
+#define V4L2_VP8_SEGMENT_HEADER_FLAG_UPDATE_FEATURE_DATA 0x04
+#define V4L2_VP8_SEGMENT_HEADER_FLAG_DELTA_VALUE_MODE 0x08
+
+struct v4l2_vp8_segment_header {
+ __s8 quant_update[4];
+ __s8 lf_update[4];
+ __u8 segment_probs[3];
+ __u8 padding;
+ __u32 flags;
+};
+
+#define V4L2_VP8_LF_HEADER_ADJ_ENABLE 0x01
+#define V4L2_VP8_LF_HEADER_DELTA_UPDATE 0x02
+#define V4L2_VP8_LF_FILTER_TYPE_SIMPLE 0x04
+struct v4l2_vp8_loopfilter_header {
+ __s8 ref_frm_delta[4];
+ __s8 mb_mode_delta[4];
+ __u8 sharpness_level;
+ __u8 level;
+ __u16 padding;
+ __u32 flags;
+};
+
+struct v4l2_vp8_quantization_header {
+ __u8 y_ac_qi;
+ __s8 y_dc_delta;
+ __s8 y2_dc_delta;
+ __s8 y2_ac_delta;
+ __s8 uv_dc_delta;
+ __s8 uv_ac_delta;
+ __u16 padding;
+};
+
+struct v4l2_vp8_entropy_header {
+ __u8 coeff_probs[4][8][3][11];
+ __u8 y_mode_probs[4];
+ __u8 uv_mode_probs[3];
+ __u8 mv_probs[2][19];
+ __u8 padding[3];
+};
+
+struct v4l2_vp8_entropy_coder_state {
+ __u8 range;
+ __u8 value;
+ __u8 bit_count;
+ __u8 padding;
+};
+
+#define V4L2_VP8_FRAME_HEADER_FLAG_KEY_FRAME 0x01
+#define V4L2_VP8_FRAME_HEADER_FLAG_EXPERIMENTAL 0x02
+#define V4L2_VP8_FRAME_HEADER_FLAG_SHOW_FRAME 0x04
+#define V4L2_VP8_FRAME_HEADER_FLAG_MB_NO_SKIP_COEFF 0x08
+#define V4L2_VP8_FRAME_HEADER_FLAG_SIGN_BIAS_GOLDEN 0x10
+#define V4L2_VP8_FRAME_HEADER_FLAG_SIGN_BIAS_ALT 0x20
+
+#define VP8_FRAME_IS_KEY_FRAME(hdr) \
+ (!!((hdr)->flags & V4L2_VP8_FRAME_HEADER_FLAG_KEY_FRAME))
+
+struct v4l2_ctrl_vp8_frame_header {
+ struct v4l2_vp8_segment_header segment_header;
+ struct v4l2_vp8_loopfilter_header lf_header;
+ struct v4l2_vp8_quantization_header quant_header;
+ struct v4l2_vp8_entropy_header entropy_header;
+ struct v4l2_vp8_entropy_coder_state coder_state;
+
+ __u16 width;
+ __u16 height;
+
+ __u8 horizontal_scale;
+ __u8 vertical_scale;
+
+ __u8 version;
+ __u8 prob_skip_false;
+ __u8 prob_intra;
+ __u8 prob_last;
+ __u8 prob_gf;
+ __u8 num_dct_parts;
+
+ __u32 first_part_size;
+ __u32 first_part_header_bits;
+ __u32 dct_part_sizes[8];
+
+ __u64 last_frame_ts;
+ __u64 golden_frame_ts;
+ __u64 alt_frame_ts;
+
+ __u64 flags;
+};
+
+#endif

View File

@ -0,0 +1,26 @@
From 0c4c87e72463da1a4bf45032e4db3c2c86d6d8d8 Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Mon, 29 Apr 2019 22:08:59 +0000
Subject: [PATCH] hwcontext_drm: do not require drm device
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
---
libavutil/hwcontext_drm.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/libavutil/hwcontext_drm.c b/libavutil/hwcontext_drm.c
index 32cbde82eb..aa4794c5e6 100644
--- a/libavutil/hwcontext_drm.c
+++ b/libavutil/hwcontext_drm.c
@@ -43,6 +43,11 @@ static int drm_device_create(AVHWDeviceContext *hwdev, const char *device,
AVDRMDeviceContext *hwctx = hwdev->hwctx;
drmVersionPtr version;
+ if (device == NULL) {
+ hwctx->fd = -1;
+ return 0;
+ }
+
hwctx->fd = open(device, O_RDWR);
if (hwctx->fd < 0)
return AVERROR(errno);

View File

@ -0,0 +1,51 @@
From 3d50f433609688b6d4ffb2bcec41507f7f507dc2 Mon Sep 17 00:00:00 2001
From: Ezequiel Garcia <ezequiel@collabora.com>
Date: Wed, 20 Feb 2019 11:18:00 -0300
Subject: [PATCH] avcodec/h264: parse idr_pic_id
Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
---
libavcodec/h264_slice.c | 2 +-
libavcodec/h264dec.h | 2 ++
libavcodec/v4l2_request_h264.c | 2 +-
3 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c
index f1e11003af..a795fcf66d 100644
--- a/libavcodec/h264_slice.c
+++ b/libavcodec/h264_slice.c
@@ -1768,7 +1768,7 @@ static int h264_slice_header_parse(const H264Context *h, H264SliceContext *sl,
}
if (nal->type == H264_NAL_IDR_SLICE)
- get_ue_golomb_long(&sl->gb); /* idr_pic_id */
+ sl->idr_pic_id = get_ue_golomb_long(&sl->gb);
if (sps->poc_type == 0) {
sl->poc_lsb = get_bits(&sl->gb, sps->log2_max_poc_lsb);
diff --git a/libavcodec/h264dec.h b/libavcodec/h264dec.h
index b0b42b7672..38efab5c60 100644
--- a/libavcodec/h264dec.h
+++ b/libavcodec/h264dec.h
@@ -184,6 +184,8 @@ typedef struct H264SliceContext {
int slice_type_nos; ///< S free slice type (SI/SP are remapped to I/P)
int slice_type_fixed;
+ int idr_pic_id;
+
int qscale;
int chroma_qp[2]; // QPc
int qp_thresh; ///< QP threshold to skip loopfilter
diff --git a/libavcodec/v4l2_request_h264.c b/libavcodec/v4l2_request_h264.c
index b826c9d356..a49773b228 100644
--- a/libavcodec/v4l2_request_h264.c
+++ b/libavcodec/v4l2_request_h264.c
@@ -284,7 +284,7 @@ static int v4l2_request_h264_decode_slice(AVCodecContext *avctx, const uint8_t *
.pic_parameter_set_id = sl->pps_id,
.colour_plane_id = 0, /* what is this? */
.frame_num = h->poc.frame_num,
- .idr_pic_id = 0, /* what is this? */
+ .idr_pic_id = sl->idr_pic_id,
.pic_order_cnt_lsb = sl->poc_lsb,
.delta_pic_order_cnt_bottom = sl->delta_poc_bottom,
.delta_pic_order_cnt0 = sl->delta_poc[0],

View File

@ -0,0 +1,88 @@
From 2f915e957c6bc5887cc24a8762fdadea17359f57 Mon Sep 17 00:00:00 2001
From: Boris Brezillon <boris.brezillon@collabora.com>
Date: Wed, 22 May 2019 14:44:22 +0200
Subject: [PATCH] avcodec/h264: parse ref_pic_marking_size_in_bits and
pic_order_cnt_bit_size
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
---
libavcodec/h264_slice.c | 6 +++++-
libavcodec/h264dec.h | 2 ++
libavcodec/v4l2_request_h264.c | 4 ++--
3 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c
index a795fcf66d..9059e98a16 100644
--- a/libavcodec/h264_slice.c
+++ b/libavcodec/h264_slice.c
@@ -1680,7 +1680,7 @@ static int h264_slice_header_parse(const H264Context *h, H264SliceContext *sl,
unsigned int slice_type, tmp, i;
int field_pic_flag, bottom_field_flag;
int first_slice = sl == h->slice_ctx && !h->current_slice;
- int picture_structure;
+ int picture_structure, pos;
if (first_slice)
av_assert0(!h->setup_finished);
@@ -1770,6 +1770,7 @@ static int h264_slice_header_parse(const H264Context *h, H264SliceContext *sl,
if (nal->type == H264_NAL_IDR_SLICE)
sl->idr_pic_id = get_ue_golomb_long(&sl->gb);
+ pos = sl->gb.index;
if (sps->poc_type == 0) {
sl->poc_lsb = get_bits(&sl->gb, sps->log2_max_poc_lsb);
@@ -1783,6 +1784,7 @@ static int h264_slice_header_parse(const H264Context *h, H264SliceContext *sl,
if (pps->pic_order_present == 1 && picture_structure == PICT_FRAME)
sl->delta_poc[1] = get_se_golomb(&sl->gb);
}
+ sl->pic_order_cnt_bit_size = sl->gb.index - pos;
sl->redundant_pic_count = 0;
if (pps->redundant_pic_cnt_present)
@@ -1822,9 +1824,11 @@ static int h264_slice_header_parse(const H264Context *h, H264SliceContext *sl,
sl->explicit_ref_marking = 0;
if (nal->ref_idc) {
+ int bit_pos = sl->gb.index;
ret = ff_h264_decode_ref_pic_marking(sl, &sl->gb, nal, h->avctx);
if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE))
return AVERROR_INVALIDDATA;
+ sl->ref_pic_marking_size_in_bits = sl->gb.index - bit_pos;
}
if (sl->slice_type_nos != AV_PICTURE_TYPE_I && pps->cabac) {
diff --git a/libavcodec/h264dec.h b/libavcodec/h264dec.h
index 38efab5c60..8e894f565b 100644
--- a/libavcodec/h264dec.h
+++ b/libavcodec/h264dec.h
@@ -324,11 +324,13 @@ typedef struct H264SliceContext {
MMCO mmco[MAX_MMCO_COUNT];
int nb_mmco;
int explicit_ref_marking;
+ int ref_pic_marking_size_in_bits;
int frame_num;
int poc_lsb;
int delta_poc_bottom;
int delta_poc[2];
+ int pic_order_cnt_bit_size;
int curr_pic_num;
int max_pic_num;
} H264SliceContext;
diff --git a/libavcodec/v4l2_request_h264.c b/libavcodec/v4l2_request_h264.c
index a49773b228..229df6969d 100644
--- a/libavcodec/v4l2_request_h264.c
+++ b/libavcodec/v4l2_request_h264.c
@@ -292,9 +292,9 @@ static int v4l2_request_h264_decode_slice(AVCodecContext *avctx, const uint8_t *
.redundant_pic_cnt = sl->redundant_pic_count,
/* Size in bits of dec_ref_pic_marking() syntax element. */
- .dec_ref_pic_marking_bit_size = 0,
+ .dec_ref_pic_marking_bit_size = sl->ref_pic_marking_size_in_bits,
/* Size in bits of pic order count syntax. */
- .pic_order_cnt_bit_size = 0,
+ .pic_order_cnt_bit_size = sl->pic_order_cnt_bit_size,
.cabac_init_idc = sl->cabac_init_idc,
.slice_qp_delta = sl->qscale - pps->init_qp,

View File

@ -0,0 +1,56 @@
From 45df99d31062e068073cf899dce559e334c9127f Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Fri, 24 May 2019 22:58:24 +0000
Subject: [PATCH] HACK: add dpb flags for reference usage and field picture
This or something similar needs to be upstreamed to kernel h264 ctrls
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
---
libavcodec/h264-ctrls.h | 4 ++++
libavcodec/v4l2_request_h264.c | 6 +++++-
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/libavcodec/h264-ctrls.h b/libavcodec/h264-ctrls.h
index e877bf1d53..76020ebd1e 100644
--- a/libavcodec/h264-ctrls.h
+++ b/libavcodec/h264-ctrls.h
@@ -185,6 +185,10 @@ struct v4l2_ctrl_h264_slice_params {
#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
+#define V4L2_H264_DPB_ENTRY_FLAG_FIELD_PICTURE 0x08
+#define V4L2_H264_DPB_ENTRY_FLAG_REF_TOP 0x10
+#define V4L2_H264_DPB_ENTRY_FLAG_REF_BOTTOM 0x20
+#define V4L2_H264_DPB_ENTRY_FLAG_REF_FRAME 0x30
struct v4l2_h264_dpb_entry {
__u64 reference_ts;
diff --git a/libavcodec/v4l2_request_h264.c b/libavcodec/v4l2_request_h264.c
index 229df6969d..7f345b1955 100644
--- a/libavcodec/v4l2_request_h264.c
+++ b/libavcodec/v4l2_request_h264.c
@@ -65,10 +65,13 @@ static void fill_dpb_entry(struct v4l2_h264_dpb_entry *entry, const H264Picture
entry->frame_num = pic->frame_num;
entry->pic_num = pic->pic_id;
entry->flags = V4L2_H264_DPB_ENTRY_FLAG_VALID;
+ entry->flags |= (pic->reference & 3) << 4;
if (pic->reference)
entry->flags |= V4L2_H264_DPB_ENTRY_FLAG_ACTIVE;
if (pic->long_ref)
entry->flags |= V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM;
+ if (pic->field_picture)
+ entry->flags |= V4L2_H264_DPB_ENTRY_FLAG_FIELD_PICTURE;
if (pic->field_poc[0] != INT_MAX)
entry->top_field_order_cnt = pic->field_poc[0];
if (pic->field_poc[1] != INT_MAX)
@@ -108,7 +111,8 @@ static uint8_t get_dpb_index(struct v4l2_ctrl_h264_decode_params *decode, const
struct v4l2_h264_dpb_entry *entry = &decode->dpb[i];
if ((entry->flags & V4L2_H264_DPB_ENTRY_FLAG_VALID) &&
entry->reference_ts == timestamp)
- return i;
+ // TODO: signal reference type, possible using top 2 bits
+ return i | ((ref->reference & 3) << 6);
}
return 0;

View File

@ -4862,3 +4862,826 @@ index a6a3f772fdf0..d0a8d5810c0a 100644
--
2.23.0
From 633eadc9ba1e9a56be09ef94f14578a9839d3634 Mon Sep 17 00:00:00 2001
From: Jernej Skrabec <jernej.skrabec@siol.net>
Date: Thu, 30 May 2019 18:15:13 -0300
Subject: [PATCH] media: cedrus: Remove dst_bufs from context
This array is just duplicated capture buffer queue. Remove it and adjust
code to look into capture buffer queue instead.
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
Acked-by: Maxime Ripard <maxime.ripard@bootlin.com>
Acked-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
Reviewed-by: Ezequiel Garcia <ezequiel@collabora.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
---
drivers/staging/media/sunxi/cedrus/cedrus.h | 4 +---
.../staging/media/sunxi/cedrus/cedrus_h264.c | 4 ++--
.../staging/media/sunxi/cedrus/cedrus_video.c | 22 -------------------
3 files changed, 3 insertions(+), 27 deletions(-)
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.h b/drivers/staging/media/sunxi/cedrus/cedrus.h
index 3f476d0fd981..d8e6777e5e27 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus.h
+++ b/drivers/staging/media/sunxi/cedrus/cedrus.h
@@ -100,8 +100,6 @@ struct cedrus_ctx {
struct v4l2_ctrl_handler hdl;
struct v4l2_ctrl **ctrls;
- struct vb2_buffer *dst_bufs[VIDEO_MAX_FRAME];
-
union {
struct {
void *mv_col_buf;
@@ -187,7 +185,7 @@ static inline dma_addr_t cedrus_dst_buf_addr(struct cedrus_ctx *ctx,
if (index < 0)
return 0;
- buf = ctx->dst_bufs[index];
+ buf = ctx->fh.m2m_ctx->cap_q_ctx.q.bufs[index];
return buf ? cedrus_buf_addr(buf, &ctx->dst_fmt, plane) : 0;
}
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
index a30bb283f69f..d6a782703c9b 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
@@ -118,7 +118,7 @@ static void cedrus_write_frame_list(struct cedrus_ctx *ctx,
if (buf_idx < 0)
continue;
- cedrus_buf = vb2_to_cedrus_buffer(ctx->dst_bufs[buf_idx]);
+ cedrus_buf = vb2_to_cedrus_buffer(cap_q->bufs[buf_idx]);
position = cedrus_buf->codec.h264.position;
used_dpbs |= BIT(position);
@@ -193,7 +193,7 @@ static void _cedrus_write_ref_list(struct cedrus_ctx *ctx,
if (buf_idx < 0)
continue;
- ref_buf = to_vb2_v4l2_buffer(ctx->dst_bufs[buf_idx]);
+ ref_buf = to_vb2_v4l2_buffer(cap_q->bufs[buf_idx]);
cedrus_buf = vb2_v4l2_to_cedrus_buffer(ref_buf);
position = cedrus_buf->codec.h264.position;
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_video.c b/drivers/staging/media/sunxi/cedrus/cedrus_video.c
index e2b530b1a956..681dfe3367a6 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus_video.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_video.c
@@ -411,26 +411,6 @@ static void cedrus_queue_cleanup(struct vb2_queue *vq, u32 state)
}
}
-static int cedrus_buf_init(struct vb2_buffer *vb)
-{
- struct vb2_queue *vq = vb->vb2_queue;
- struct cedrus_ctx *ctx = vb2_get_drv_priv(vq);
-
- if (!V4L2_TYPE_IS_OUTPUT(vq->type))
- ctx->dst_bufs[vb->index] = vb;
-
- return 0;
-}
-
-static void cedrus_buf_cleanup(struct vb2_buffer *vb)
-{
- struct vb2_queue *vq = vb->vb2_queue;
- struct cedrus_ctx *ctx = vb2_get_drv_priv(vq);
-
- if (!V4L2_TYPE_IS_OUTPUT(vq->type))
- ctx->dst_bufs[vb->index] = NULL;
-}
-
static int cedrus_buf_out_validate(struct vb2_buffer *vb)
{
struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
@@ -517,8 +497,6 @@ static void cedrus_buf_request_complete(struct vb2_buffer *vb)
static struct vb2_ops cedrus_qops = {
.queue_setup = cedrus_queue_setup,
.buf_prepare = cedrus_buf_prepare,
- .buf_init = cedrus_buf_init,
- .buf_cleanup = cedrus_buf_cleanup,
.buf_queue = cedrus_buf_queue,
.buf_out_validate = cedrus_buf_out_validate,
.buf_request_complete = cedrus_buf_request_complete,
--
2.23.0
From 7bb3c32abd7bafd346f667cccb7dfe9686f14ddd Mon Sep 17 00:00:00 2001
From: Ezequiel Garcia <ezequiel@collabora.com>
Date: Fri, 16 Aug 2019 13:01:23 -0300
Subject: [PATCH] media: uapi: h264: Rename pixel format
The V4L2_PIX_FMT_H264_SLICE_RAW name was originally suggested
because the pixel format would represent H264 slices without any
start code.
However, as we will now introduce a start code menu control,
give the pixel format a more meaningful name, while it's
still early enough to do so.
Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
Tested-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
---
Documentation/media/uapi/v4l/pixfmt-compressed.rst | 4 ++--
drivers/media/v4l2-core/v4l2-ioctl.c | 2 +-
drivers/staging/media/sunxi/cedrus/cedrus_dec.c | 2 +-
drivers/staging/media/sunxi/cedrus/cedrus_video.c | 6 +++---
include/media/h264-ctrls.h | 2 +-
5 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/Documentation/media/uapi/v4l/pixfmt-compressed.rst b/Documentation/media/uapi/v4l/pixfmt-compressed.rst
index f52a7b67023d..9b65473a2288 100644
--- a/Documentation/media/uapi/v4l/pixfmt-compressed.rst
+++ b/Documentation/media/uapi/v4l/pixfmt-compressed.rst
@@ -52,9 +52,9 @@ Compressed Formats
- ``V4L2_PIX_FMT_H264_MVC``
- 'M264'
- H264 MVC video elementary stream.
- * .. _V4L2-PIX-FMT-H264-SLICE-RAW:
+ * .. _V4L2-PIX-FMT-H264-SLICE:
- - ``V4L2_PIX_FMT_H264_SLICE_RAW``
+ - ``V4L2_PIX_FMT_H264_SLICE``
- 'S264'
- H264 parsed slice data, without the start code and as
extracted from the H264 bitstream. This format is adapted for
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
index bb5b4926538a..39f10621c91b 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -1343,7 +1343,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_H264_SLICE: 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/drivers/staging/media/sunxi/cedrus/cedrus_dec.c b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
index bdad87eb9d79..56ca4c9ad01c 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
@@ -46,7 +46,7 @@ void cedrus_device_run(void *priv)
V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION);
break;
- case V4L2_PIX_FMT_H264_SLICE_RAW:
+ case V4L2_PIX_FMT_H264_SLICE:
run.h264.decode_params = cedrus_find_control_data(ctx,
V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS);
run.h264.pps = cedrus_find_control_data(ctx,
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_video.c b/drivers/staging/media/sunxi/cedrus/cedrus_video.c
index 681dfe3367a6..eeee3efd247b 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus_video.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_video.c
@@ -38,7 +38,7 @@ static struct cedrus_format cedrus_formats[] = {
.directions = CEDRUS_DECODE_SRC,
},
{
- .pixelformat = V4L2_PIX_FMT_H264_SLICE_RAW,
+ .pixelformat = V4L2_PIX_FMT_H264_SLICE,
.directions = CEDRUS_DECODE_SRC,
},
{
@@ -104,7 +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:
+ case V4L2_PIX_FMT_H264_SLICE:
/* Zero bytes per line for encoded source. */
bytesperline = 0;
@@ -449,7 +449,7 @@ 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:
+ case V4L2_PIX_FMT_H264_SLICE:
ctx->current_codec = CEDRUS_CODEC_H264;
break;
diff --git a/include/media/h264-ctrls.h b/include/media/h264-ctrls.h
index e1404d78d6ff..6160a69c0143 100644
--- a/include/media/h264-ctrls.h
+++ b/include/media/h264-ctrls.h
@@ -14,7 +14,7 @@
#include <linux/videodev2.h>
/* Our pixel format isn't stable at the moment */
-#define V4L2_PIX_FMT_H264_SLICE_RAW v4l2_fourcc('S', '2', '6', '4') /* H264 parsed slices */
+#define V4L2_PIX_FMT_H264_SLICE v4l2_fourcc('S', '2', '6', '4') /* H264 parsed slices */
/*
* This is put insanely high to avoid conflicting with controls that
--
2.23.0
From 3f715c64be6e6e1e1bb140fb1179ab0a712f94c3 Mon Sep 17 00:00:00 2001
From: Ezequiel Garcia <ezequiel@collabora.com>
Date: Fri, 16 Aug 2019 13:01:27 -0300
Subject: [PATCH] media: cedrus: Cleanup control initialization
In order to introduce other controls, the control initialization
needs to support an initial struct v4l2_ctrl_control.
While here, let's cleanup the control initialization,
removing unneeded fields.
Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
---
drivers/staging/media/sunxi/cedrus/cedrus.c | 45 +++++++++++----------
drivers/staging/media/sunxi/cedrus/cedrus.h | 3 +-
2 files changed, 25 insertions(+), 23 deletions(-)
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c
index 370937edfc14..7bdc413bf727 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus.c
@@ -29,44 +29,51 @@
static const struct cedrus_control cedrus_controls[] = {
{
- .id = V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS,
- .elem_size = sizeof(struct v4l2_ctrl_mpeg2_slice_params),
+ .cfg = {
+ .id = V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS,
+ },
.codec = CEDRUS_CODEC_MPEG2,
.required = true,
},
{
- .id = V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION,
- .elem_size = sizeof(struct v4l2_ctrl_mpeg2_quantization),
+ .cfg = {
+ .id = V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION,
+ },
.codec = CEDRUS_CODEC_MPEG2,
.required = false,
},
{
- .id = V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS,
- .elem_size = sizeof(struct v4l2_ctrl_h264_decode_params),
+ .cfg = {
+ .id = V4L2_CID_MPEG_VIDEO_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),
+ .cfg = {
+ .id = V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS,
+ },
.codec = CEDRUS_CODEC_H264,
.required = true,
},
{
- .id = V4L2_CID_MPEG_VIDEO_H264_SPS,
- .elem_size = sizeof(struct v4l2_ctrl_h264_sps),
+ .cfg = {
+ .id = V4L2_CID_MPEG_VIDEO_H264_SPS,
+ },
.codec = CEDRUS_CODEC_H264,
.required = true,
},
{
- .id = V4L2_CID_MPEG_VIDEO_H264_PPS,
- .elem_size = sizeof(struct v4l2_ctrl_h264_pps),
+ .cfg = {
+ .id = V4L2_CID_MPEG_VIDEO_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),
+ .cfg = {
+ .id = V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX,
+ },
.codec = CEDRUS_CODEC_H264,
.required = true,
},
@@ -106,12 +113,8 @@ static int cedrus_init_ctrls(struct cedrus_dev *dev, struct cedrus_ctx *ctx)
return -ENOMEM;
for (i = 0; i < CEDRUS_CONTROLS_COUNT; i++) {
- struct v4l2_ctrl_config cfg = {};
-
- cfg.elem_size = cedrus_controls[i].elem_size;
- cfg.id = cedrus_controls[i].id;
-
- ctrl = v4l2_ctrl_new_custom(hdl, &cfg, NULL);
+ ctrl = v4l2_ctrl_new_custom(hdl, &cedrus_controls[i].cfg,
+ NULL);
if (hdl->error) {
v4l2_err(&dev->v4l2_dev,
"Failed to create new custom control\n");
@@ -178,7 +181,7 @@ static int cedrus_request_validate(struct media_request *req)
continue;
ctrl_test = v4l2_ctrl_request_hdl_ctrl_find(hdl,
- cedrus_controls[i].id);
+ cedrus_controls[i].cfg.id);
if (!ctrl_test) {
v4l2_info(&ctx->dev->v4l2_dev,
"Missing required codec control\n");
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.h b/drivers/staging/media/sunxi/cedrus/cedrus.h
index d8e6777e5e27..2f017a651848 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus.h
+++ b/drivers/staging/media/sunxi/cedrus/cedrus.h
@@ -49,8 +49,7 @@ enum cedrus_h264_pic_type {
};
struct cedrus_control {
- u32 id;
- u32 elem_size;
+ struct v4l2_ctrl_config cfg;
enum cedrus_codec codec;
unsigned char required:1;
};
--
2.23.0
From 341772b82a3b83e7a7a2c0605c8c728e81b38319 Mon Sep 17 00:00:00 2001
From: Ezequiel Garcia <ezequiel@collabora.com>
Date: Fri, 16 Aug 2019 13:01:28 -0300
Subject: [PATCH] media: cedrus: Specify H264 startcode and decoding mode
The cedrus VPU is slice-based and expects V4L2_PIX_FMT_H264_SLICE
buffers to contain H264 slices with no start code.
Expose this to userspace with the newly added menu control.
These two controls are specified as mandatory for applications,
but we mark them as non-required on the driver side for
backwards compatibility.
Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
---
drivers/staging/media/sunxi/cedrus/cedrus.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c
index 7bdc413bf727..2d3ea8b74dfd 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus.c
@@ -77,6 +77,24 @@ static const struct cedrus_control cedrus_controls[] = {
.codec = CEDRUS_CODEC_H264,
.required = true,
},
+ {
+ .cfg = {
+ .id = V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE,
+ .max = V4L2_MPEG_VIDEO_H264_DECODE_MODE_SLICE_BASED,
+ .def = V4L2_MPEG_VIDEO_H264_DECODE_MODE_SLICE_BASED,
+ },
+ .codec = CEDRUS_CODEC_H264,
+ .required = false,
+ },
+ {
+ .cfg = {
+ .id = V4L2_CID_MPEG_VIDEO_H264_START_CODE,
+ .max = V4L2_MPEG_VIDEO_H264_START_CODE_NONE,
+ .def = V4L2_MPEG_VIDEO_H264_START_CODE_NONE,
+ },
+ .codec = CEDRUS_CODEC_H264,
+ .required = false,
+ },
};
#define CEDRUS_CONTROLS_COUNT ARRAY_SIZE(cedrus_controls)
--
2.23.0
From 5604be66a56867a784e162299a48c214921ffa1b Mon Sep 17 00:00:00 2001
From: Boris Brezillon <boris.brezillon@collabora.com>
Date: Fri, 16 Aug 2019 13:01:24 -0300
Subject: [PATCH] media: uapi: h264: Add the concept of decoding mode
Some stateless decoders don't support per-slice decoding granularity
(or at least not in a way that would make them efficient or easy to use).
Expose a menu to control the supported decoding modes. Drivers are
allowed to support only one decoding but they can support both too.
To fully specify the decoding operation, we need to introduce
a start_byte_offset, to indicate where slices start.
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
Tested-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
---
.../media/uapi/v4l/ext-ctrls-codec.rst | 57 ++++++++++++++++++-
.../media/uapi/v4l/pixfmt-compressed.rst | 6 +-
drivers/media/v4l2-core/v4l2-ctrls.c | 9 +++
include/media/h264-ctrls.h | 10 ++++
4 files changed, 79 insertions(+), 3 deletions(-)
diff --git a/Documentation/media/uapi/v4l/ext-ctrls-codec.rst b/Documentation/media/uapi/v4l/ext-ctrls-codec.rst
index c5f39dd50043..1da17a2c94d7 100644
--- a/Documentation/media/uapi/v4l/ext-ctrls-codec.rst
+++ b/Documentation/media/uapi/v4l/ext-ctrls-codec.rst
@@ -1747,6 +1747,14 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type -
* - __u32
- ``size``
-
+ * - __u32
+ - ``start_byte_offset``
+ Offset (in bytes) from the beginning of the OUTPUT buffer to the start
+ of the slice. If the slice starts with a start code, then this is the
+ offset to such start code. When operating in slice-based decoding mode
+ (see :c:type:`v4l2_mpeg_video_h264_decode_mode`), this field should
+ be set to 0. When operating in frame-based decoding mode, this field
+ should be 0 for the first slice.
* - __u32
- ``header_bit_size``
-
@@ -1930,7 +1938,10 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type -
-
* - __u16
- ``num_slices``
- - Number of slices needed to decode the current frame
+ - Number of slices needed to decode the current frame/field. When
+ operating in slice-based decoding mode (see
+ :c:type:`v4l2_mpeg_video_h264_decode_mode`), this field
+ should always be set to one.
* - __u16
- ``nal_ref_idc``
- NAL reference ID value coming from the NAL Unit header
@@ -2021,6 +2032,50 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type -
- 0x00000004
- The DPB entry is a long term reference frame
+``V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE (enum)``
+ Specifies the decoding mode to use. Currently exposes slice-based and
+ frame-based decoding but new modes might be added later on.
+ This control is used as a modifier for V4L2_PIX_FMT_H264_SLICE
+ pixel format. Applications that support V4L2_PIX_FMT_H264_SLICE
+ are required to set this control in order to specify the decoding mode
+ that is expected for the buffer.
+ Drivers may expose a single or multiple decoding modes, depending
+ on what they can support.
+
+ .. note::
+
+ This menu control is not yet part of the public kernel API and
+ it is expected to change.
+
+.. c:type:: v4l2_mpeg_video_h264_decode_mode
+
+.. cssclass:: longtable
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+ :widths: 1 1 2
+
+ * - ``V4L2_MPEG_VIDEO_H264_DECODE_MODE_SLICE_BASED``
+ - 0
+ - Decoding is done at the slice granularity.
+ In this mode, ``num_slices`` field in struct
+ :c:type:`v4l2_ctrl_h264_decode_params` should be set to 1,
+ and ``start_byte_offset`` in struct
+ :c:type:`v4l2_ctrl_h264_slice_params` should be set to 0.
+ The OUTPUT buffer must contain a single slice.
+ * - ``V4L2_MPEG_VIDEO_H264_DECODE_MODE_FRAME_BASED``
+ - 1
+ - Decoding is done at the frame granularity.
+ In this mode, ``num_slices`` field in struct
+ :c:type:`v4l2_ctrl_h264_decode_params` should be set to the number
+ of slices in the frame, and ``start_byte_offset`` in struct
+ :c:type:`v4l2_ctrl_h264_slice_params` should be set accordingly
+ for each slice. For the first slice, ``start_byte_offset`` should
+ be zero.
+ The OUTPUT buffer must contain all slices needed to decode the
+ frame. The OUTPUT buffer must also contain both fields.
+
.. _v4l2-mpeg-mpeg2:
``V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS (struct)``
diff --git a/Documentation/media/uapi/v4l/pixfmt-compressed.rst b/Documentation/media/uapi/v4l/pixfmt-compressed.rst
index 9b65473a2288..d666eb51741a 100644
--- a/Documentation/media/uapi/v4l/pixfmt-compressed.rst
+++ b/Documentation/media/uapi/v4l/pixfmt-compressed.rst
@@ -60,8 +60,10 @@ Compressed Formats
extracted from the H264 bitstream. This format is adapted for
stateless video decoders that implement an H264 pipeline
(using the :ref:`mem2mem` 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``,
+ This pixelformat has a modifier that must be set at least once
+ through the ``V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE`` control.
+ In addition, 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
diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
index cd1ae016706f..2c67f9fc4d5b 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
@@ -402,6 +402,11 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
"Explicit",
NULL,
};
+ static const char * const h264_decode_mode[] = {
+ "Slice-Based",
+ "Frame-Based",
+ NULL,
+ };
static const char * const mpeg_mpeg2_level[] = {
"Low",
"Main",
@@ -633,6 +638,8 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
return h264_fp_arrangement_type;
case V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE:
return h264_fmo_map_type;
+ case V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE:
+ return h264_decode_mode;
case V4L2_CID_MPEG_VIDEO_MPEG2_LEVEL:
return mpeg_mpeg2_level;
case V4L2_CID_MPEG_VIDEO_MPEG2_PROFILE:
@@ -852,6 +859,7 @@ const char *v4l2_ctrl_get_name(u32 id)
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_H264_DECODE_MODE: return "H264 Decode Mode";
case V4L2_CID_MPEG_VIDEO_MPEG2_LEVEL: return "MPEG2 Level";
case V4L2_CID_MPEG_VIDEO_MPEG2_PROFILE: return "MPEG2 Profile";
case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP: return "MPEG4 I-Frame QP Value";
@@ -1220,6 +1228,7 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC:
case V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE:
case V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE:
+ case V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE:
case V4L2_CID_MPEG_VIDEO_MPEG2_LEVEL:
case V4L2_CID_MPEG_VIDEO_MPEG2_PROFILE:
case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL:
diff --git a/include/media/h264-ctrls.h b/include/media/h264-ctrls.h
index 6160a69c0143..928c48c57282 100644
--- a/include/media/h264-ctrls.h
+++ b/include/media/h264-ctrls.h
@@ -26,6 +26,7 @@
#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)
+#define V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE (V4L2_CID_MPEG_BASE+1005)
/* enum v4l2_ctrl_type type values */
#define V4L2_CTRL_TYPE_H264_SPS 0x0110
@@ -34,6 +35,11 @@
#define V4L2_CTRL_TYPE_H264_SLICE_PARAMS 0x0113
#define V4L2_CTRL_TYPE_H264_DECODE_PARAMS 0x0114
+enum v4l2_mpeg_video_h264_decode_mode {
+ V4L2_MPEG_VIDEO_H264_DECODE_MODE_SLICE_BASED,
+ V4L2_MPEG_VIDEO_H264_DECODE_MODE_FRAME_BASED,
+};
+
#define V4L2_H264_SPS_CONSTRAINT_SET0_FLAG 0x01
#define V4L2_H264_SPS_CONSTRAINT_SET1_FLAG 0x02
#define V4L2_H264_SPS_CONSTRAINT_SET2_FLAG 0x04
@@ -125,6 +131,10 @@ struct v4l2_h264_pred_weight_table {
struct v4l2_ctrl_h264_slice_params {
/* Size in bytes, including header */
__u32 size;
+
+ /* Offset in bytes to the start of slice in the OUTPUT buffer. */
+ __u32 start_byte_offset;
+
/* Offset in bits to slice_data() from the beginning of this slice. */
__u32 header_bit_size;
--
2.23.0
From 8cae93e090113e46bd29a99c1727d8f13ea12fdf Mon Sep 17 00:00:00 2001
From: Ezequiel Garcia <ezequiel@collabora.com>
Date: Fri, 16 Aug 2019 13:01:25 -0300
Subject: [PATCH] media: uapi: h264: Add the concept of start code
Stateless decoders have different expectations about the
start code that is prepended on H264 slices. Add a
menu control to express the supported start code types
(including no start code).
Drivers are allowed to support only one start code type,
but they can support both too.
Note that this is independent of the H264 decoding mode,
which specifies the granularity of the decoding operations.
Either in frame-based or slice-based mode, this new control
will allow to define the start code expected on H264 slices.
Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
Tested-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
---
.../media/uapi/v4l/ext-ctrls-codec.rst | 33 +++++++++++++++++++
.../media/uapi/v4l/pixfmt-compressed.rst | 5 +--
drivers/media/v4l2-core/v4l2-ctrls.c | 9 +++++
include/media/h264-ctrls.h | 6 ++++
4 files changed, 51 insertions(+), 2 deletions(-)
diff --git a/Documentation/media/uapi/v4l/ext-ctrls-codec.rst b/Documentation/media/uapi/v4l/ext-ctrls-codec.rst
index 1da17a2c94d7..810ae9bb6f7c 100644
--- a/Documentation/media/uapi/v4l/ext-ctrls-codec.rst
+++ b/Documentation/media/uapi/v4l/ext-ctrls-codec.rst
@@ -2076,6 +2076,39 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type -
The OUTPUT buffer must contain all slices needed to decode the
frame. The OUTPUT buffer must also contain both fields.
+``V4L2_CID_MPEG_VIDEO_H264_START_CODE (enum)``
+ Specifies the H264 slice start code expected for each slice.
+ This control is used as a modifier for V4L2_PIX_FMT_H264_SLICE
+ pixel format. Applications that support V4L2_PIX_FMT_H264_SLICE
+ are required to set this control in order to specify the start code
+ that is expected for the buffer.
+ Drivers may expose a single or multiple start codes, depending
+ on what they can support.
+
+ .. note::
+
+ This menu control is not yet part of the public kernel API and
+ it is expected to change.
+
+.. c:type:: v4l2_mpeg_video_h264_start_code
+
+.. cssclass:: longtable
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+ :widths: 1 1 2
+
+ * - ``V4L2_MPEG_VIDEO_H264_START_CODE_NONE``
+ - 0
+ - Selecting this value specifies that H264 slices are passed
+ to the driver without any start code.
+ * - ``V4L2_MPEG_VIDEO_H264_START_CODE_ANNEX_B``
+ - 1
+ - Selecting this value specifies that H264 slices are expected
+ to be prefixed by Annex B start codes. According to :ref:`h264`
+ valid start codes can be 3-bytes 0x000001 or 4-bytes 0x00000001.
+
.. _v4l2-mpeg-mpeg2:
``V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS (struct)``
diff --git a/Documentation/media/uapi/v4l/pixfmt-compressed.rst b/Documentation/media/uapi/v4l/pixfmt-compressed.rst
index d666eb51741a..493b6020107d 100644
--- a/Documentation/media/uapi/v4l/pixfmt-compressed.rst
+++ b/Documentation/media/uapi/v4l/pixfmt-compressed.rst
@@ -60,8 +60,9 @@ Compressed Formats
extracted from the H264 bitstream. This format is adapted for
stateless video decoders that implement an H264 pipeline
(using the :ref:`mem2mem` and :ref:`media-request-api`).
- This pixelformat has a modifier that must be set at least once
- through the ``V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE`` control.
+ This pixelformat has two modifiers that must be set at least once
+ through the ``V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE``
+ and ``V4L2_CID_MPEG_VIDEO_H264_START_CODE`` controls.
In addition, 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``,
diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
index 2c67f9fc4d5b..1d8f38824631 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
@@ -407,6 +407,11 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
"Frame-Based",
NULL,
};
+ static const char * const h264_start_code[] = {
+ "No Start Code",
+ "Annex B Start Code",
+ NULL,
+ };
static const char * const mpeg_mpeg2_level[] = {
"Low",
"Main",
@@ -640,6 +645,8 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
return h264_fmo_map_type;
case V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE:
return h264_decode_mode;
+ case V4L2_CID_MPEG_VIDEO_H264_START_CODE:
+ return h264_start_code;
case V4L2_CID_MPEG_VIDEO_MPEG2_LEVEL:
return mpeg_mpeg2_level;
case V4L2_CID_MPEG_VIDEO_MPEG2_PROFILE:
@@ -860,6 +867,7 @@ const char *v4l2_ctrl_get_name(u32 id)
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_H264_DECODE_MODE: return "H264 Decode Mode";
+ case V4L2_CID_MPEG_VIDEO_H264_START_CODE: return "H264 Start Code";
case V4L2_CID_MPEG_VIDEO_MPEG2_LEVEL: return "MPEG2 Level";
case V4L2_CID_MPEG_VIDEO_MPEG2_PROFILE: return "MPEG2 Profile";
case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP: return "MPEG4 I-Frame QP Value";
@@ -1229,6 +1237,7 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
case V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE:
case V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE:
case V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE:
+ case V4L2_CID_MPEG_VIDEO_H264_START_CODE:
case V4L2_CID_MPEG_VIDEO_MPEG2_LEVEL:
case V4L2_CID_MPEG_VIDEO_MPEG2_PROFILE:
case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL:
diff --git a/include/media/h264-ctrls.h b/include/media/h264-ctrls.h
index 928c48c57282..ba2876a64cf6 100644
--- a/include/media/h264-ctrls.h
+++ b/include/media/h264-ctrls.h
@@ -27,6 +27,7 @@
#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)
#define V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE (V4L2_CID_MPEG_BASE+1005)
+#define V4L2_CID_MPEG_VIDEO_H264_START_CODE (V4L2_CID_MPEG_BASE+1006)
/* enum v4l2_ctrl_type type values */
#define V4L2_CTRL_TYPE_H264_SPS 0x0110
@@ -40,6 +41,11 @@ enum v4l2_mpeg_video_h264_decode_mode {
V4L2_MPEG_VIDEO_H264_DECODE_MODE_FRAME_BASED,
};
+enum v4l2_mpeg_video_h264_start_code {
+ V4L2_MPEG_VIDEO_H264_START_CODE_NONE,
+ V4L2_MPEG_VIDEO_H264_START_CODE_ANNEX_B,
+};
+
#define V4L2_H264_SPS_CONSTRAINT_SET0_FLAG 0x01
#define V4L2_H264_SPS_CONSTRAINT_SET1_FLAG 0x02
#define V4L2_H264_SPS_CONSTRAINT_SET2_FLAG 0x04
--
2.23.0
From c3adb85745ca6cc19532b2ee197d7abece1ac732 Mon Sep 17 00:00:00 2001
From: Boris Brezillon <boris.brezillon@collabora.com>
Date: Fri, 16 Aug 2019 13:01:26 -0300
Subject: [PATCH] media: uapi: h264: Get rid of the p0/b0/b1 ref-lists
Those lists can be extracted from the dpb, let's simplify userspace
life and build that list kernel-side (generic helpers will be provided
for drivers that need this list).
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Reviewed-by: Ezequiel Garcia <ezequiel@collabora.com>
Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
Tested-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
---
Documentation/media/uapi/v4l/ext-ctrls-codec.rst | 9 ---------
include/media/h264-ctrls.h | 3 ---
2 files changed, 12 deletions(-)
diff --git a/Documentation/media/uapi/v4l/ext-ctrls-codec.rst b/Documentation/media/uapi/v4l/ext-ctrls-codec.rst
index 810ae9bb6f7c..bc5dd8e76567 100644
--- a/Documentation/media/uapi/v4l/ext-ctrls-codec.rst
+++ b/Documentation/media/uapi/v4l/ext-ctrls-codec.rst
@@ -1945,15 +1945,6 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type -
* - __u16
- ``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
diff --git a/include/media/h264-ctrls.h b/include/media/h264-ctrls.h
index ba2876a64cf6..e877bf1d537c 100644
--- a/include/media/h264-ctrls.h
+++ b/include/media/h264-ctrls.h
@@ -202,9 +202,6 @@ 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_* */
--
2.23.0

View File

@ -964,25 +964,28 @@ diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media
index 370937edfc14..70642834f351 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus.c
@@ -70,6 +70,24 @@ static const struct cedrus_control cedrus_controls[] = {
@@ -70,6 +70,27 @@ static const struct cedrus_control cedrus_controls[] = {
.codec = CEDRUS_CODEC_H264,
.required = true,
},
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_SPS,
+ .elem_size = sizeof(struct v4l2_ctrl_hevc_sps),
+ .cfg = {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_SPS,
+ },
+ .codec = CEDRUS_CODEC_H265,
+ .required = true,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_PPS,
+ .elem_size = sizeof(struct v4l2_ctrl_hevc_pps),
+ .cfg = {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_PPS,
+ },
+ .codec = CEDRUS_CODEC_H265,
+ .required = true,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS,
+ .elem_size = sizeof(struct v4l2_ctrl_hevc_slice_params),
+ .cfg = {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS,
+ },
+ .codec = CEDRUS_CODEC_H265,
+ .required = true,
+ },
@ -1995,7 +1998,7 @@ index e2b530b1a956..6cc65d85cf98 100644
@@ -105,6 +110,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:
case V4L2_PIX_FMT_H264_SLICE:
+ case V4L2_PIX_FMT_HEVC_SLICE:
/* Zero bytes per line for encoded source. */
bytesperline = 0;

View File

@ -59,13 +59,14 @@ diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media
index 70642834f351..01860f247aa6 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus.c
@@ -88,6 +88,12 @@ static const struct cedrus_control cedrus_controls[] = {
@@ -88,6 +88,13 @@ static const struct cedrus_control cedrus_controls[] = {
.codec = CEDRUS_CODEC_H265,
.required = true,
},
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX,
+ .elem_size = sizeof(struct v4l2_ctrl_hevc_scaling_matrix),
+ .cfg = {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX,
+ },
+ .codec = CEDRUS_CODEC_H265,
+ .required = true,
+ },
@ -156,7 +157,7 @@ index fd4d86b02156..82d29c59b787 100644
- field * ctx->codec.h265.mv_col_buf_unit_size / 2;
+ struct cedrus_buffer *cedrus_buf;
+
+ cedrus_buf = vb2_to_cedrus_buffer(ctx->dst_bufs[index]);
+ cedrus_buf = vb2_to_cedrus_buffer(ctx->fh.m2m_ctx->cap_q_ctx.q.bufs[index]);
+
+ return cedrus_buf->mv_col_buf_dma;
}
@ -512,7 +513,7 @@ index fd4d86b02156..82d29c59b787 100644
/* Output frame. */
+ cedrus_buf = vb2_to_cedrus_buffer(ctx->dst_bufs[run->dst->vb2_buf.index]);
+ cedrus_buf = vb2_to_cedrus_buffer(ctx->fh.m2m_ctx->cap_q_ctx.q.bufs[run->dst->vb2_buf.index]);
+ if (!cedrus_buf->mv_col_buf_size) {
+ unsigned int ctb_size_luma, width_in_ctb_luma;
+ unsigned int log2_max_luma_coding_block_size;
@ -662,26 +663,39 @@ diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_video.c b/drivers/staging
index dbe6f9510641..a0817cae1d69 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus_video.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_video.c
@@ -433,8 +433,18 @@ static void cedrus_buf_cleanup(struct vb2_buffer *vb)
struct vb2_queue *vq = vb->vb2_queue;
struct cedrus_ctx *ctx = vb2_get_drv_priv(vq);
@@ -433,6 +433,24 @@ static void cedrus_queue_cleanup(struct vb2_queue *vq, u32 state)
}
}
- if (!V4L2_TYPE_IS_OUTPUT(vq->type))
+static void cedrus_buf_cleanup(struct vb2_buffer *vb)
+{
+ struct vb2_queue *vq = vb->vb2_queue;
+ struct cedrus_ctx *ctx = vb2_get_drv_priv(vq);
+
+ if (!V4L2_TYPE_IS_OUTPUT(vq->type)) {
+ struct cedrus_buffer *cedrus_buf;
+
+ cedrus_buf = vb2_to_cedrus_buffer(ctx->dst_bufs[vb->index]);
+ cedrus_buf = vb2_to_cedrus_buffer(vq->bufs[vb->index]);
+
+ if (cedrus_buf->mv_col_buf_size)
+ dma_free_coherent(ctx->dev->dev,
+ cedrus_buf->mv_col_buf_size,
+ cedrus_buf->mv_col_buf,
+ cedrus_buf->mv_col_buf_dma);
ctx->dst_bufs[vb->index] = NULL;
+ }
}
+}
+
static int cedrus_buf_out_validate(struct vb2_buffer *vb)
{
struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
@@ -517,6 +497,7 @@ static void cedrus_buf_request_complete(struct vb2_buffer *vb)
static struct vb2_ops cedrus_qops = {
.queue_setup = cedrus_queue_setup,
.buf_prepare = cedrus_buf_prepare,
+ .buf_cleanup = cedrus_buf_cleanup,
.buf_queue = cedrus_buf_queue,
.buf_out_validate = cedrus_buf_out_validate,
.buf_request_complete = cedrus_buf_request_complete,
diff --git a/include/media/hevc-ctrls.h b/include/media/hevc-ctrls.h
index 2de83d9f6d47..19469097c6d4 100644
--- a/include/media/hevc-ctrls.h