mirror of
https://github.com/LibreELEC/LibreELEC.tv.git
synced 2025-07-30 22:26:42 +00:00
Merge pull request #3972 from jernejsk/cedrus_update
Allwinner: Rework HW decoding
This commit is contained in:
commit
d6c13231e5
@ -1,7 +1,7 @@
|
||||
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] avutil: add av_buffer_pool_flush()
|
||||
Subject: [PATCH 01/12] avutil: add av_buffer_pool_flush()
|
||||
|
||||
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
||||
---
|
||||
@ -49,3 +49,6 @@ index 73b6bd0b14..0678fa4bea 100644
|
||||
/**
|
||||
* 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.24.0
|
||||
|
||||
|
@ -1,16 +1,16 @@
|
||||
From b810081f898fc4faec35519c6e7e9d275bf2bbcf Mon Sep 17 00:00:00 2001
|
||||
From 457a74f059e5467f7f24f15be1b0e87a34e8cabc Mon Sep 17 00:00:00 2001
|
||||
From: Jonas Karlman <jonas@kwiboo.se>
|
||||
Date: Sat, 15 Dec 2018 22:32:16 +0100
|
||||
Subject: [PATCH] Add common V4L2 request API code
|
||||
Subject: [PATCH 02/12] 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 | 919 ++++++++++++++++++++++++++++++++++++++
|
||||
libavcodec/v4l2_request.h | 69 +++
|
||||
5 files changed, 1003 insertions(+)
|
||||
libavcodec/v4l2_request.c | 943 ++++++++++++++++++++++++++++++++++++++
|
||||
libavcodec/v4l2_request.h | 72 +++
|
||||
5 files changed, 1030 insertions(+)
|
||||
create mode 100644 libavcodec/v4l2_request.c
|
||||
create mode 100644 libavcodec/v4l2_request.h
|
||||
|
||||
@ -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..bf9d049eff
|
||||
index 0000000000..1dabf77689
|
||||
--- /dev/null
|
||||
+++ b/libavcodec/v4l2_request.c
|
||||
@@ -0,0 +1,919 @@
|
||||
@@ -0,0 +1,943 @@
|
||||
+/*
|
||||
+ * This file is part of FFmpeg.
|
||||
+ *
|
||||
@ -216,7 +216,7 @@ index 0000000000..bf9d049eff
|
||||
+ return control.default_value;
|
||||
+}
|
||||
+
|
||||
+static int v4l2_request_queue_buffer(V4L2RequestContext *ctx, int request_fd, V4L2RequestBuffer *buf)
|
||||
+static int v4l2_request_queue_buffer(V4L2RequestContext *ctx, int request_fd, V4L2RequestBuffer *buf, uint32_t flags)
|
||||
+{
|
||||
+ struct v4l2_plane planes[1] = {};
|
||||
+ struct v4l2_buffer buffer = {
|
||||
@ -226,7 +226,7 @@ index 0000000000..bf9d049eff
|
||||
+ .timestamp.tv_usec = buf->index + 1,
|
||||
+ .bytesused = buf->used,
|
||||
+ .request_fd = request_fd,
|
||||
+ .flags = (request_fd >= 0) ? V4L2_BUF_FLAG_REQUEST_FD : 0,
|
||||
+ .flags = ((request_fd >= 0) ? V4L2_BUF_FLAG_REQUEST_FD : 0) | flags,
|
||||
+ };
|
||||
+
|
||||
+ if (V4L2_TYPE_IS_MULTIPLANAR(buf->buffer.type)) {
|
||||
@ -308,7 +308,7 @@ index 0000000000..bf9d049eff
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int ff_v4l2_request_decode_frame(AVCodecContext *avctx, AVFrame *frame, struct v4l2_ext_control *control, int count)
|
||||
+static int v4l2_request_queue_decode(AVCodecContext *avctx, AVFrame *frame, struct v4l2_ext_control *control, int count, int first_slice, int last_slice)
|
||||
+{
|
||||
+ V4L2RequestContext *ctx = avctx->internal->hwaccel_priv_data;
|
||||
+ V4L2RequestDescriptor *req = (V4L2RequestDescriptor*)frame->data[0];
|
||||
@ -316,7 +316,7 @@ index 0000000000..bf9d049eff
|
||||
+ fd_set except_fds;
|
||||
+ int ret;
|
||||
+
|
||||
+ av_log(avctx, AV_LOG_DEBUG, "%s: avctx=%p used=%u controls=%d index=%d fd=%d request_fd=%d\n", __func__, avctx, req->output.used, count, req->capture.index, req->capture.fd, req->request_fd);
|
||||
+ av_log(avctx, AV_LOG_DEBUG, "%s: avctx=%p used=%u controls=%d index=%d fd=%d request_fd=%d first_slice=%d last_slice=%d\n", __func__, avctx, req->output.used, count, req->capture.index, req->capture.fd, req->request_fd, first_slice, last_slice);
|
||||
+
|
||||
+ ret = v4l2_request_set_controls(ctx, req->request_fd, control, count);
|
||||
+ if (ret < 0) {
|
||||
@ -326,16 +326,18 @@ index 0000000000..bf9d049eff
|
||||
+
|
||||
+ memset(req->output.addr + req->output.used, 0, AV_INPUT_BUFFER_PADDING_SIZE);
|
||||
+
|
||||
+ ret = v4l2_request_queue_buffer(ctx, req->request_fd, &req->output);
|
||||
+ ret = v4l2_request_queue_buffer(ctx, req->request_fd, &req->output, last_slice ? 0 : V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF);
|
||||
+ if (ret < 0) {
|
||||
+ av_log(avctx, AV_LOG_ERROR, "%s: queue output buffer %d failed for request %d, %s (%d)\n", __func__, req->output.index, req->request_fd, strerror(errno), errno);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ ret = v4l2_request_queue_buffer(ctx, -1, &req->capture);
|
||||
+ if (ret < 0) {
|
||||
+ av_log(avctx, AV_LOG_ERROR, "%s: queue capture buffer %d failed for request %d, %s (%d)\n", __func__, req->capture.index, req->request_fd, strerror(errno), errno);
|
||||
+ return -1;
|
||||
+ if (first_slice) {
|
||||
+ ret = v4l2_request_queue_buffer(ctx, -1, &req->capture, 0);
|
||||
+ if (ret < 0) {
|
||||
+ av_log(avctx, AV_LOG_ERROR, "%s: queue capture buffer %d failed for request %d, %s (%d)\n", __func__, req->capture.index, req->request_fd, strerror(errno), errno);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // NOTE: do we need to dequeue when request fails/timeout?
|
||||
@ -365,10 +367,12 @@ index 0000000000..bf9d049eff
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ ret = v4l2_request_dequeue_buffer(ctx, &req->capture);
|
||||
+ if (ret < 0) {
|
||||
+ av_log(avctx, AV_LOG_ERROR, "%s: dequeue capture buffer %d failed for request %d, %s (%d)\n", __func__, req->capture.index, req->request_fd, strerror(errno), errno);
|
||||
+ return -1;
|
||||
+ if (last_slice) {
|
||||
+ ret = v4l2_request_dequeue_buffer(ctx, &req->capture);
|
||||
+ if (ret < 0) {
|
||||
+ av_log(avctx, AV_LOG_ERROR, "%s: dequeue capture buffer %d failed for request %d, %s (%d)\n", __func__, req->capture.index, req->request_fd, strerror(errno), errno);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // TODO: check errors
|
||||
@ -380,7 +384,10 @@ index 0000000000..bf9d049eff
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ return v4l2_request_set_drm_descriptor(req, &ctx->format);
|
||||
+ if (last_slice)
|
||||
+ return v4l2_request_set_drm_descriptor(req, &ctx->format);
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+fail:
|
||||
+ ret = v4l2_request_dequeue_buffer(ctx, &req->output);
|
||||
@ -398,6 +405,22 @@ index 0000000000..bf9d049eff
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
+int ff_v4l2_request_decode_slice(AVCodecContext *avctx, AVFrame *frame, struct v4l2_ext_control *control, int count, int first_slice, int last_slice)
|
||||
+{
|
||||
+ V4L2RequestDescriptor *req = (V4L2RequestDescriptor*)frame->data[0];
|
||||
+
|
||||
+ // fall back to queue each slice as a full frame
|
||||
+ if ((req->output.capabilities & V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF) != V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF)
|
||||
+ return v4l2_request_queue_decode(avctx, frame, control, count, 1, 1);
|
||||
+
|
||||
+ return v4l2_request_queue_decode(avctx, frame, control, count, first_slice, last_slice);
|
||||
+}
|
||||
+
|
||||
+int ff_v4l2_request_decode_frame(AVCodecContext *avctx, AVFrame *frame, struct v4l2_ext_control *control, int count)
|
||||
+{
|
||||
+ return v4l2_request_queue_decode(avctx, frame, control, count, 1, 1);
|
||||
+}
|
||||
+
|
||||
+static int v4l2_request_try_format(AVCodecContext *avctx, enum v4l2_buf_type type, uint32_t pixelformat)
|
||||
+{
|
||||
+ V4L2RequestContext *ctx = avctx->internal->hwaccel_priv_data;
|
||||
@ -866,6 +889,7 @@ index 0000000000..bf9d049eff
|
||||
+ }
|
||||
+
|
||||
+ buf->index = buffers.index;
|
||||
+ buf->capabilities = buffers.capabilities;
|
||||
+ buf->used = 0;
|
||||
+
|
||||
+ buf->buffer.type = type;
|
||||
@ -1037,10 +1061,10 @@ index 0000000000..bf9d049eff
|
||||
+}
|
||||
diff --git a/libavcodec/v4l2_request.h b/libavcodec/v4l2_request.h
|
||||
new file mode 100644
|
||||
index 0000000000..1f45772d8b
|
||||
index 0000000000..d4146bd4ee
|
||||
--- /dev/null
|
||||
+++ b/libavcodec/v4l2_request.h
|
||||
@@ -0,0 +1,69 @@
|
||||
@@ -0,0 +1,72 @@
|
||||
+/*
|
||||
+ * This file is part of FFmpeg.
|
||||
+ *
|
||||
@ -1081,6 +1105,7 @@ index 0000000000..1f45772d8b
|
||||
+ uint32_t height;
|
||||
+ uint32_t size;
|
||||
+ uint32_t used;
|
||||
+ uint32_t capabilities;
|
||||
+ struct v4l2_buffer buffer;
|
||||
+} V4L2RequestBuffer;
|
||||
+
|
||||
@ -1101,6 +1126,8 @@ index 0000000000..1f45772d8b
|
||||
+
|
||||
+int ff_v4l2_request_query_control_default_value(AVCodecContext *avctx, uint32_t id);
|
||||
+
|
||||
+int ff_v4l2_request_decode_slice(AVCodecContext *avctx, AVFrame *frame, struct v4l2_ext_control *control, int count, int first_slice, int last_slice);
|
||||
+
|
||||
+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);
|
||||
@ -1110,3 +1137,6 @@ index 0000000000..1f45772d8b
|
||||
+int ff_v4l2_request_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx);
|
||||
+
|
||||
+#endif /* AVCODEC_V4L2_REQUEST_H */
|
||||
--
|
||||
2.24.0
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
From f31319e29405004b84f17e30602f77dae671b53e Mon Sep 17 00:00:00 2001
|
||||
From d46c4def125a142419db249051fbaa8e743e3e53 Mon Sep 17 00:00:00 2001
|
||||
From: Jonas Karlman <jonas@kwiboo.se>
|
||||
Date: Sat, 15 Dec 2018 22:32:16 +0100
|
||||
Subject: [PATCH] Add V4L2 request API mpeg2 hwaccel
|
||||
Subject: [PATCH 03/12] Add V4L2 request API mpeg2 hwaccel
|
||||
|
||||
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
||||
---
|
||||
@ -242,3 +242,6 @@ index 0000000000..782b9c2471
|
||||
+ .frame_params = ff_v4l2_request_frame_params,
|
||||
+ .caps_internal = HWACCEL_CAP_ASYNC_SAFE,
|
||||
+};
|
||||
--
|
||||
2.24.0
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 389f6557715439d5fa974f0cc55e1fa68735ec61 Mon Sep 17 00:00:00 2001
|
||||
From fb59440a268d956bffa40604e4422420453b4605 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] Add V4L2 request API h264 hwaccel
|
||||
Subject: [PATCH 04/12] Add V4L2 request API h264 hwaccel
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
||||
@ -11,8 +11,8 @@ 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 | 420 +++++++++++++++++++++++++++++++++
|
||||
6 files changed, 432 insertions(+)
|
||||
libavcodec/v4l2_request_h264.c | 443 +++++++++++++++++++++++++++++++++
|
||||
6 files changed, 455 insertions(+)
|
||||
create mode 100644 libavcodec/v4l2_request_h264.c
|
||||
|
||||
diff --git a/configure b/configure
|
||||
@ -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..fb9913922d
|
||||
index 0000000000..81b3c4b092
|
||||
--- /dev/null
|
||||
+++ b/libavcodec/v4l2_request_h264.c
|
||||
@@ -0,0 +1,420 @@
|
||||
@@ -0,0 +1,443 @@
|
||||
+/*
|
||||
+ * This file is part of FFmpeg.
|
||||
+ *
|
||||
@ -130,6 +130,7 @@ index 0000000000..fb9913922d
|
||||
+ struct v4l2_ctrl_h264_scaling_matrix scaling_matrix;
|
||||
+ struct v4l2_ctrl_h264_decode_params decode_params;
|
||||
+ struct v4l2_ctrl_h264_slice_params slice_params[16];
|
||||
+ int first_slice;
|
||||
+} V4L2RequestControlsH264;
|
||||
+
|
||||
+typedef struct V4L2RequestContextH264 {
|
||||
@ -297,13 +298,22 @@ index 0000000000..fb9913922d
|
||||
+{
|
||||
+ const H264Context *h = avctx->priv_data;
|
||||
+ const PPS *pps = h->ps.pps;
|
||||
+ const SPS *sps = h->ps.sps;
|
||||
+ V4L2RequestControlsH264 *controls = h->cur_pic_ptr->hwaccel_picture_private;
|
||||
+
|
||||
+ fill_sps(&controls->sps, h);
|
||||
+ fill_pps(&controls->pps, h);
|
||||
+
|
||||
+ memcpy(controls->scaling_matrix.scaling_list_4x4, pps->scaling_matrix4, sizeof(controls->scaling_matrix.scaling_list_4x4));
|
||||
+ memcpy(controls->scaling_matrix.scaling_list_8x8, pps->scaling_matrix8, sizeof(controls->scaling_matrix.scaling_list_8x8));
|
||||
+ memcpy(controls->scaling_matrix.scaling_list_8x8[0], pps->scaling_matrix8[0], sizeof(controls->scaling_matrix.scaling_list_8x8[0]));
|
||||
+ memcpy(controls->scaling_matrix.scaling_list_8x8[1], pps->scaling_matrix8[3], sizeof(controls->scaling_matrix.scaling_list_8x8[1]));
|
||||
+
|
||||
+ if (sps->chroma_format_idc == 3) {
|
||||
+ memcpy(controls->scaling_matrix.scaling_list_8x8[2], pps->scaling_matrix8[1], sizeof(controls->scaling_matrix.scaling_list_8x8[2]));
|
||||
+ memcpy(controls->scaling_matrix.scaling_list_8x8[3], pps->scaling_matrix8[4], sizeof(controls->scaling_matrix.scaling_list_8x8[3]));
|
||||
+ memcpy(controls->scaling_matrix.scaling_list_8x8[4], pps->scaling_matrix8[2], sizeof(controls->scaling_matrix.scaling_list_8x8[4]));
|
||||
+ memcpy(controls->scaling_matrix.scaling_list_8x8[5], pps->scaling_matrix8[5], sizeof(controls->scaling_matrix.scaling_list_8x8[5]));
|
||||
+ }
|
||||
+
|
||||
+ controls->decode_params = (struct v4l2_ctrl_h264_decode_params) {
|
||||
+ .num_slices = 0,
|
||||
@ -317,13 +327,16 @@ index 0000000000..fb9913922d
|
||||
+
|
||||
+ fill_dpb(&controls->decode_params, h);
|
||||
+
|
||||
+ controls->first_slice = !FIELD_PICTURE(h) || h->first_field;
|
||||
+
|
||||
+ return ff_v4l2_request_reset_frame(avctx, h->cur_pic_ptr->f);
|
||||
+}
|
||||
+
|
||||
+static int v4l2_request_h264_end_frame(AVCodecContext *avctx)
|
||||
+static int v4l2_request_h264_queue_decode(AVCodecContext *avctx, int last_slice)
|
||||
+{
|
||||
+ const H264Context *h = avctx->priv_data;
|
||||
+ V4L2RequestControlsH264 *controls = h->cur_pic_ptr->hwaccel_picture_private;
|
||||
+ V4L2RequestContextH264 *ctx = avctx->internal->hwaccel_priv_data;
|
||||
+
|
||||
+ struct v4l2_ext_control control[] = {
|
||||
+ {
|
||||
@ -353,6 +366,9 @@ index 0000000000..fb9913922d
|
||||
+ },
|
||||
+ };
|
||||
+
|
||||
+ if (ctx->decode_mode == V4L2_MPEG_VIDEO_H264_DECODE_MODE_SLICE_BASED)
|
||||
+ return ff_v4l2_request_decode_slice(avctx, h->cur_pic_ptr->f, control, FF_ARRAY_ELEMS(control), controls->first_slice, last_slice);
|
||||
+
|
||||
+ return ff_v4l2_request_decode_frame(avctx, h->cur_pic_ptr->f, control, FF_ARRAY_ELEMS(control));
|
||||
+}
|
||||
+
|
||||
@ -367,12 +383,13 @@ index 0000000000..fb9913922d
|
||||
+ 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);
|
||||
+ ret = v4l2_request_h264_queue_decode(avctx, 0);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ff_v4l2_request_reset_frame(avctx, h->cur_pic_ptr->f);
|
||||
+ slice = controls->decode_params.num_slices = 0;
|
||||
+ controls->first_slice = 0;
|
||||
+ }
|
||||
+
|
||||
+ controls->slice_params[slice] = (struct v4l2_ctrl_h264_slice_params) {
|
||||
@ -448,6 +465,12 @@ index 0000000000..fb9913922d
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int v4l2_request_h264_end_frame(AVCodecContext *avctx)
|
||||
+{
|
||||
+ const H264Context *h = avctx->priv_data;
|
||||
+ return v4l2_request_h264_queue_decode(avctx, !FIELD_PICTURE(h) || !h->first_field);
|
||||
+}
|
||||
+
|
||||
+static int v4l2_request_h264_set_controls(AVCodecContext *avctx)
|
||||
+{
|
||||
+ V4L2RequestContextH264 *ctx = avctx->internal->hwaccel_priv_data;
|
||||
@ -522,3 +545,6 @@ index 0000000000..fb9913922d
|
||||
+ .frame_params = ff_v4l2_request_frame_params,
|
||||
+ .caps_internal = HWACCEL_CAP_ASYNC_SAFE,
|
||||
+};
|
||||
--
|
||||
2.24.0
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 0cd5948e34df8acdbc84efc7ce662eee03ce88e3 Mon Sep 17 00:00:00 2001
|
||||
From 2511b50434e37a56af86bd38b76a6b5cf4d3117b 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] Add V4L2 request API hevc hwaccel
|
||||
Subject: [PATCH 05/12] Add V4L2 request API hevc hwaccel
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
||||
@ -10,8 +10,8 @@ Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
||||
libavcodec/Makefile | 1 +
|
||||
libavcodec/hevcdec.c | 10 +
|
||||
libavcodec/hwaccels.h | 1 +
|
||||
libavcodec/v4l2_request_hevc.c | 391 +++++++++++++++++++++++++++++++++
|
||||
5 files changed, 406 insertions(+)
|
||||
libavcodec/v4l2_request_hevc.c | 527 +++++++++++++++++++++++++++++++++
|
||||
5 files changed, 542 insertions(+)
|
||||
create mode 100644 libavcodec/v4l2_request_hevc.c
|
||||
|
||||
diff --git a/configure b/configure
|
||||
@ -103,10 +103,10 @@ index 003200edea..d183675abe 100644
|
||||
extern const AVHWAccel ff_hevc_videotoolbox_hwaccel;
|
||||
diff --git a/libavcodec/v4l2_request_hevc.c b/libavcodec/v4l2_request_hevc.c
|
||||
new file mode 100644
|
||||
index 0000000000..38969d77fb
|
||||
index 0000000000..da1fd666d7
|
||||
--- /dev/null
|
||||
+++ b/libavcodec/v4l2_request_hevc.c
|
||||
@@ -0,0 +1,391 @@
|
||||
@@ -0,0 +1,527 @@
|
||||
+/*
|
||||
+ * This file is part of FFmpeg.
|
||||
+ *
|
||||
@ -133,9 +133,17 @@ index 0000000000..38969d77fb
|
||||
+ struct v4l2_ctrl_hevc_sps sps;
|
||||
+ struct v4l2_ctrl_hevc_pps pps;
|
||||
+ struct v4l2_ctrl_hevc_scaling_matrix scaling_matrix;
|
||||
+ struct v4l2_ctrl_hevc_slice_params slice_params;
|
||||
+ struct v4l2_ctrl_hevc_slice_params slice_params[16];
|
||||
+ int first_slice;
|
||||
+ int num_slices; //TODO: this should be in control
|
||||
+} V4L2RequestControlsHEVC;
|
||||
+
|
||||
+typedef struct V4L2RequestContextHEVC {
|
||||
+ V4L2RequestContext base;
|
||||
+ int decode_mode;
|
||||
+ int start_code;
|
||||
+} V4L2RequestContextHEVC;
|
||||
+
|
||||
+static void v4l2_request_hevc_fill_pred_table(const HEVCContext *h, struct v4l2_hevc_pred_weight_table *table)
|
||||
+{
|
||||
+ int32_t luma_weight_denom, chroma_weight_denom;
|
||||
@ -233,6 +241,9 @@ index 0000000000..38969d77fb
|
||||
+ .bit_size = 0,
|
||||
+ .data_bit_offset = get_bits_count(&h->HEVClc->gb),
|
||||
+
|
||||
+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: General slice segment header */
|
||||
+ .slice_segment_addr = sh->slice_segment_addr,
|
||||
+
|
||||
+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: NAL unit header */
|
||||
+ .nal_unit_type = h->nal_unit_type,
|
||||
+ .nuh_temporal_id_plus1 = h->temporal_id + 1,
|
||||
@ -241,27 +252,18 @@ index 0000000000..38969d77fb
|
||||
+ .slice_type = sh->slice_type,
|
||||
+ .colour_plane_id = sh->colour_plane_id,
|
||||
+ .slice_pic_order_cnt = pic->poc,
|
||||
+ .slice_sao_luma_flag = sh->slice_sample_adaptive_offset_flag[0],
|
||||
+ .slice_sao_chroma_flag = sh->slice_sample_adaptive_offset_flag[1],
|
||||
+ .slice_temporal_mvp_enabled_flag = sh->slice_temporal_mvp_enabled_flag,
|
||||
+ .num_ref_idx_l0_active_minus1 = sh->nb_refs[L0] ? sh->nb_refs[L0] - 1 : 0,
|
||||
+ .num_ref_idx_l1_active_minus1 = sh->nb_refs[L1] ? sh->nb_refs[L1] - 1 : 0,
|
||||
+ .mvd_l1_zero_flag = sh->mvd_l1_zero_flag,
|
||||
+ .cabac_init_flag = sh->cabac_init_flag,
|
||||
+ .collocated_from_l0_flag = sh->collocated_list == L0 ? 1 : 0,
|
||||
+ .collocated_ref_idx = sh->slice_temporal_mvp_enabled_flag ? sh->collocated_ref_idx : 0,
|
||||
+ .five_minus_max_num_merge_cand = sh->slice_type == HEVC_SLICE_I ? 0 : 5 - sh->max_num_merge_cand,
|
||||
+ .use_integer_mv_flag = 0,
|
||||
+ .slice_qp_delta = sh->slice_qp_delta,
|
||||
+ .slice_cb_qp_offset = sh->slice_cb_qp_offset,
|
||||
+ .slice_cr_qp_offset = sh->slice_cr_qp_offset,
|
||||
+ .slice_act_y_qp_offset = 0,
|
||||
+ .slice_act_cb_qp_offset = 0,
|
||||
+ .slice_act_cr_qp_offset = 0,
|
||||
+ .slice_deblocking_filter_disabled_flag = sh->disable_deblocking_filter_flag,
|
||||
+ .slice_beta_offset_div2 = sh->beta_offset / 2,
|
||||
+ .slice_tc_offset_div2 = sh->tc_offset / 2,
|
||||
+ .slice_loop_filter_across_slices_enabled_flag = sh->slice_loop_filter_across_slices_enabled_flag,
|
||||
+
|
||||
+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: Picture timing SEI message */
|
||||
+ .pic_struct = h->sei.picture_timing.picture_struct,
|
||||
@ -270,11 +272,32 @@ index 0000000000..38969d77fb
|
||||
+ .num_rps_poc_st_curr_before = h->rps[ST_CURR_BEF].nb_refs,
|
||||
+ .num_rps_poc_st_curr_after = h->rps[ST_CURR_AFT].nb_refs,
|
||||
+ .num_rps_poc_lt_curr = h->rps[LT_CURR].nb_refs,
|
||||
+
|
||||
+ .slice_segment_addr = sh->slice_segment_addr,
|
||||
+ .first_slice_segment_in_pic_flag = sh->first_slice_in_pic_flag,
|
||||
+ };
|
||||
+
|
||||
+ if (sh->slice_sample_adaptive_offset_flag[0])
|
||||
+ slice_params->flags |= V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_SAO_LUMA;
|
||||
+
|
||||
+ if (sh->slice_sample_adaptive_offset_flag[1])
|
||||
+ slice_params->flags |= V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_SAO_CHROMA;
|
||||
+
|
||||
+ if (sh->slice_temporal_mvp_enabled_flag)
|
||||
+ slice_params->flags |= V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_TEMPORAL_MVP_ENABLED;
|
||||
+
|
||||
+ if (sh->mvd_l1_zero_flag)
|
||||
+ slice_params->flags |= V4L2_HEVC_SLICE_PARAMS_FLAG_MVD_L1_ZERO;
|
||||
+
|
||||
+ if (sh->cabac_init_flag)
|
||||
+ slice_params->flags |= V4L2_HEVC_SLICE_PARAMS_FLAG_CABAC_INIT;
|
||||
+
|
||||
+ if (sh->collocated_list == L0)
|
||||
+ slice_params->flags |= V4L2_HEVC_SLICE_PARAMS_FLAG_COLLOCATED_FROM_L0;
|
||||
+
|
||||
+ if (sh->disable_deblocking_filter_flag)
|
||||
+ slice_params->flags |= V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_DEBLOCKING_FILTER_DISABLED;
|
||||
+
|
||||
+ if (sh->slice_loop_filter_across_slices_enabled_flag)
|
||||
+ slice_params->flags |= V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_LOOP_FILTER_ACROSS_SLICES_ENABLED;
|
||||
+
|
||||
+ for (i = 0; i < FF_ARRAY_ELEMS(h->DPB); i++) {
|
||||
+ const HEVCFrame *frame = &h->DPB[i];
|
||||
+ if (frame != pic && (frame->flags & (HEVC_FRAME_FLAG_LONG_REF | HEVC_FRAME_FLAG_SHORT_REF))) {
|
||||
@ -332,7 +355,6 @@ index 0000000000..38969d77fb
|
||||
+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: Sequence parameter set */
|
||||
+ controls->sps = (struct v4l2_ctrl_hevc_sps) {
|
||||
+ .chroma_format_idc = sps->chroma_format_idc,
|
||||
+ .separate_colour_plane_flag = sps->separate_colour_plane_flag,
|
||||
+ .pic_width_in_luma_samples = sps->width,
|
||||
+ .pic_height_in_luma_samples = sps->height,
|
||||
+ .bit_depth_luma_minus8 = sps->bit_depth - 8,
|
||||
@ -347,22 +369,41 @@ index 0000000000..38969d77fb
|
||||
+ .log2_diff_max_min_luma_transform_block_size = sps->log2_max_trafo_size - sps->log2_min_tb_size,
|
||||
+ .max_transform_hierarchy_depth_inter = sps->max_transform_hierarchy_depth_inter,
|
||||
+ .max_transform_hierarchy_depth_intra = sps->max_transform_hierarchy_depth_intra,
|
||||
+ .scaling_list_enabled_flag = sps->scaling_list_enable_flag,
|
||||
+ .amp_enabled_flag = sps->amp_enabled_flag,
|
||||
+ .sample_adaptive_offset_enabled_flag = sps->sao_enabled,
|
||||
+ .pcm_enabled_flag = sps->pcm_enabled_flag,
|
||||
+ .pcm_sample_bit_depth_luma_minus1 = sps->pcm.bit_depth - 1,
|
||||
+ .pcm_sample_bit_depth_chroma_minus1 = sps->pcm.bit_depth_chroma - 1,
|
||||
+ .log2_min_pcm_luma_coding_block_size_minus3 = sps->pcm.log2_min_pcm_cb_size - 3,
|
||||
+ .log2_diff_max_min_pcm_luma_coding_block_size = sps->pcm.log2_max_pcm_cb_size - sps->pcm.log2_min_pcm_cb_size,
|
||||
+ .pcm_loop_filter_disabled_flag = sps->pcm.loop_filter_disable_flag,
|
||||
+ .num_short_term_ref_pic_sets = sps->nb_st_rps,
|
||||
+ .long_term_ref_pics_present_flag = sps->long_term_ref_pics_present_flag,
|
||||
+ .num_long_term_ref_pics_sps = sps->num_long_term_ref_pics_sps,
|
||||
+ .sps_temporal_mvp_enabled_flag = sps->sps_temporal_mvp_enabled_flag,
|
||||
+ .strong_intra_smoothing_enabled_flag = sps->sps_strong_intra_smoothing_enable_flag,
|
||||
+ };
|
||||
+
|
||||
+ if (sps->separate_colour_plane_flag)
|
||||
+ controls->sps.flags |= V4L2_HEVC_SPS_FLAG_SEPARATE_COLOUR_PLANE;
|
||||
+
|
||||
+ if (sps->scaling_list_enable_flag)
|
||||
+ controls->sps.flags |= V4L2_HEVC_SPS_FLAG_SCALING_LIST_ENABLED;
|
||||
+
|
||||
+ if (sps->amp_enabled_flag)
|
||||
+ controls->sps.flags |= V4L2_HEVC_SPS_FLAG_AMP_ENABLED;
|
||||
+
|
||||
+ if (sps->sao_enabled)
|
||||
+ controls->sps.flags |= V4L2_HEVC_SPS_FLAG_SAMPLE_ADAPTIVE_OFFSET;
|
||||
+
|
||||
+ if (sps->pcm_enabled_flag)
|
||||
+ controls->sps.flags |= V4L2_HEVC_SPS_FLAG_PCM_ENABLED;
|
||||
+
|
||||
+ if (sps->pcm.loop_filter_disable_flag)
|
||||
+ controls->sps.flags |= V4L2_HEVC_SPS_FLAG_PCM_LOOP_FILTER_DISABLED;
|
||||
+
|
||||
+ if (sps->long_term_ref_pics_present_flag)
|
||||
+ controls->sps.flags |= V4L2_HEVC_SPS_FLAG_LONG_TERM_REF_PICS_PRESENT;
|
||||
+
|
||||
+ if (sps->sps_temporal_mvp_enabled_flag)
|
||||
+ controls->sps.flags |= V4L2_HEVC_SPS_FLAG_SPS_TEMPORAL_MVP_ENABLED;
|
||||
+
|
||||
+ if (sps->sps_strong_intra_smoothing_enable_flag)
|
||||
+ controls->sps.flags |= V4L2_HEVC_SPS_FLAG_STRONG_INTRA_SMOOTHING_ENABLED;
|
||||
+
|
||||
+ if (sl) {
|
||||
+ for (int i = 0; i < 6; i++) {
|
||||
+ for (int j = 0; j < 16; j++)
|
||||
@ -381,41 +422,79 @@ index 0000000000..38969d77fb
|
||||
+
|
||||
+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: Picture parameter set */
|
||||
+ controls->pps = (struct v4l2_ctrl_hevc_pps) {
|
||||
+ .dependent_slice_segment_flag = pps->dependent_slice_segments_enabled_flag,
|
||||
+ .output_flag_present_flag = pps->output_flag_present_flag,
|
||||
+ .num_extra_slice_header_bits = pps->num_extra_slice_header_bits,
|
||||
+ .sign_data_hiding_enabled_flag = pps->sign_data_hiding_flag,
|
||||
+ .cabac_init_present_flag = pps->cabac_init_present_flag,
|
||||
+ .init_qp_minus26 = pps->pic_init_qp_minus26,
|
||||
+ .constrained_intra_pred_flag = pps->constrained_intra_pred_flag,
|
||||
+ .transform_skip_enabled_flag = pps->transform_skip_enabled_flag,
|
||||
+ .cu_qp_delta_enabled_flag = pps->cu_qp_delta_enabled_flag,
|
||||
+ .diff_cu_qp_delta_depth = pps->diff_cu_qp_delta_depth,
|
||||
+ .pps_cb_qp_offset = pps->cb_qp_offset,
|
||||
+ .pps_cr_qp_offset = pps->cr_qp_offset,
|
||||
+ .pps_slice_chroma_qp_offsets_present_flag = pps->pic_slice_level_chroma_qp_offsets_present_flag,
|
||||
+ .weighted_pred_flag = pps->weighted_pred_flag,
|
||||
+ .weighted_bipred_flag = pps->weighted_bipred_flag,
|
||||
+ .transquant_bypass_enabled_flag = pps->transquant_bypass_enable_flag,
|
||||
+ .tiles_enabled_flag = pps->tiles_enabled_flag,
|
||||
+ .entropy_coding_sync_enabled_flag = pps->entropy_coding_sync_enabled_flag,
|
||||
+ .loop_filter_across_tiles_enabled_flag = pps->loop_filter_across_tiles_enabled_flag,
|
||||
+ .pps_loop_filter_across_slices_enabled_flag = pps->seq_loop_filter_across_slices_enabled_flag,
|
||||
+ .deblocking_filter_override_enabled_flag = pps->deblocking_filter_override_enabled_flag,
|
||||
+ .pps_disable_deblocking_filter_flag = pps->disable_dbf,
|
||||
+ .pps_beta_offset_div2 = pps->beta_offset / 2,
|
||||
+ .pps_tc_offset_div2 = pps->tc_offset / 2,
|
||||
+ .lists_modification_present_flag = pps->lists_modification_present_flag,
|
||||
+ .log2_parallel_merge_level_minus2 = pps->log2_parallel_merge_level - 2,
|
||||
+ .slice_segment_header_extension_present_flag = pps->slice_header_extension_present_flag,
|
||||
+ .scaling_list_enable_flag = pps->scaling_list_data_present_flag, // pps_scaling_list_data_present_flag
|
||||
+ };
|
||||
+
|
||||
+ if (pps->dependent_slice_segments_enabled_flag)
|
||||
+ controls->pps.flags |= V4L2_HEVC_PPS_FLAG_DEPENDENT_SLICE_SEGMENT;
|
||||
+
|
||||
+ if (pps->output_flag_present_flag)
|
||||
+ controls->pps.flags |= V4L2_HEVC_PPS_FLAG_OUTPUT_FLAG_PRESENT;
|
||||
+
|
||||
+ if (pps->sign_data_hiding_flag)
|
||||
+ controls->pps.flags |= V4L2_HEVC_PPS_FLAG_SIGN_DATA_HIDING_ENABLED;
|
||||
+
|
||||
+ if (pps->cabac_init_present_flag)
|
||||
+ controls->pps.flags |= V4L2_HEVC_PPS_FLAG_CABAC_INIT_PRESENT;
|
||||
+
|
||||
+ if (pps->constrained_intra_pred_flag)
|
||||
+ controls->pps.flags |= V4L2_HEVC_PPS_FLAG_CONSTRAINED_INTRA_PRED;
|
||||
+
|
||||
+ if (pps->transform_skip_enabled_flag)
|
||||
+ controls->pps.flags |= V4L2_HEVC_PPS_FLAG_TRANSFORM_SKIP_ENABLED;
|
||||
+
|
||||
+ if (pps->cu_qp_delta_enabled_flag)
|
||||
+ controls->pps.flags |= V4L2_HEVC_PPS_FLAG_CU_QP_DELTA_ENABLED;
|
||||
+
|
||||
+ if (pps->pic_slice_level_chroma_qp_offsets_present_flag)
|
||||
+ controls->pps.flags |= V4L2_HEVC_PPS_FLAG_PPS_SLICE_CHROMA_QP_OFFSETS_PRESENT;
|
||||
+
|
||||
+ if (pps->weighted_pred_flag)
|
||||
+ controls->pps.flags |= V4L2_HEVC_PPS_FLAG_WEIGHTED_PRED;
|
||||
+
|
||||
+ if (pps->weighted_bipred_flag)
|
||||
+ controls->pps.flags |= V4L2_HEVC_PPS_FLAG_WEIGHTED_BIPRED;
|
||||
+
|
||||
+ if (pps->transquant_bypass_enable_flag)
|
||||
+ controls->pps.flags |= V4L2_HEVC_PPS_FLAG_TRANSQUANT_BYPASS_ENABLED;
|
||||
+
|
||||
+ if (pps->tiles_enabled_flag)
|
||||
+ controls->pps.flags |= V4L2_HEVC_PPS_FLAG_TILES_ENABLED;
|
||||
+
|
||||
+ if (pps->entropy_coding_sync_enabled_flag)
|
||||
+ controls->pps.flags |= V4L2_HEVC_PPS_FLAG_ENTROPY_CODING_SYNC_ENABLED;
|
||||
+
|
||||
+ if (pps->loop_filter_across_tiles_enabled_flag)
|
||||
+ controls->pps.flags |= V4L2_HEVC_PPS_FLAG_LOOP_FILTER_ACROSS_TILES_ENABLED;
|
||||
+
|
||||
+ if (pps->seq_loop_filter_across_slices_enabled_flag)
|
||||
+ controls->pps.flags |= V4L2_HEVC_PPS_FLAG_PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED;
|
||||
+
|
||||
+ if (pps->deblocking_filter_override_enabled_flag)
|
||||
+ controls->pps.flags |= V4L2_HEVC_PPS_FLAG_DEBLOCKING_FILTER_OVERRIDE_ENABLED;
|
||||
+
|
||||
+ if (pps->disable_dbf)
|
||||
+ controls->pps.flags |= V4L2_HEVC_PPS_FLAG_PPS_DISABLE_DEBLOCKING_FILTER;
|
||||
+
|
||||
+ if (pps->lists_modification_present_flag)
|
||||
+ controls->pps.flags |= V4L2_HEVC_PPS_FLAG_LISTS_MODIFICATION_PRESENT;
|
||||
+
|
||||
+ if (pps->slice_header_extension_present_flag)
|
||||
+ controls->pps.flags |= V4L2_HEVC_PPS_FLAG_SLICE_SEGMENT_HEADER_EXTENSION_PRESENT;
|
||||
+
|
||||
+ if (pps->tiles_enabled_flag) {
|
||||
+ controls->pps.num_tile_columns_minus1 = pps->num_tile_columns - 1;
|
||||
+ controls->pps.num_tile_rows_minus1 = pps->num_tile_rows - 1;
|
||||
+
|
||||
+ av_log(avctx, AV_LOG_DEBUG, "%s: avctx=%p tiles_enabled_flag=%d num_tile_columns=%d num_tile_rows=%d\n", __func__, avctx, pps->tiles_enabled_flag, pps->num_tile_columns, pps->num_tile_rows);
|
||||
+ av_log(avctx, AV_LOG_DEBUG, "%s: avctx=%p tiles_enabled_flag=%d num_tile_columns=%d num_tile_rows=%d\n",
|
||||
+ __func__, avctx, pps->tiles_enabled_flag, pps->num_tile_columns, pps->num_tile_rows);
|
||||
+
|
||||
+ for (int i = 0; i < pps->num_tile_columns; i++)
|
||||
+ controls->pps.column_width_minus1[i] = pps->column_width[i] - 1;
|
||||
@ -424,14 +503,17 @@ index 0000000000..38969d77fb
|
||||
+ controls->pps.row_height_minus1[i] = pps->row_height[i] - 1;
|
||||
+ }
|
||||
+
|
||||
+ controls->first_slice = 1;
|
||||
+ controls->num_slices = 0;
|
||||
+
|
||||
+ return ff_v4l2_request_reset_frame(avctx, h->ref->frame);
|
||||
+}
|
||||
+
|
||||
+static int v4l2_request_hevc_end_frame(AVCodecContext *avctx)
|
||||
+static int v4l2_request_hevc_queue_decode(AVCodecContext *avctx, int last_slice)
|
||||
+{
|
||||
+ const HEVCContext *h = avctx->priv_data;
|
||||
+ V4L2RequestControlsHEVC *controls = h->ref->hwaccel_picture_private;
|
||||
+ V4L2RequestDescriptor *req = (V4L2RequestDescriptor*)h->ref->frame->data[0];
|
||||
+ V4L2RequestContextHEVC *ctx = avctx->internal->hwaccel_priv_data;
|
||||
+
|
||||
+ struct v4l2_ext_control control[] = {
|
||||
+ {
|
||||
@ -452,35 +534,89 @@ index 0000000000..38969d77fb
|
||||
+ {
|
||||
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS,
|
||||
+ .ptr = &controls->slice_params,
|
||||
+ .size = sizeof(controls->slice_params),
|
||||
+ .size = sizeof(controls->slice_params[0]) * FFMIN(controls->num_slices, 16),
|
||||
+ },
|
||||
+ };
|
||||
+
|
||||
+ controls->slice_params.bit_size = req->output.used * 8;
|
||||
+ if (ctx->decode_mode == V4L2_MPEG_VIDEO_HEVC_DECODE_MODE_SLICE_BASED)
|
||||
+ return ff_v4l2_request_decode_slice(avctx, h->ref->frame, control, FF_ARRAY_ELEMS(control), controls->first_slice, last_slice);
|
||||
+
|
||||
+ return ff_v4l2_request_decode_frame(avctx, h->ref->frame, control, FF_ARRAY_ELEMS(control));
|
||||
+}
|
||||
+
|
||||
+static int v4l2_request_hevc_end_frame(AVCodecContext *avctx)
|
||||
+{
|
||||
+ return v4l2_request_hevc_queue_decode(avctx, 1);
|
||||
+}
|
||||
+
|
||||
+static int v4l2_request_hevc_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
|
||||
+{
|
||||
+ const HEVCContext *h = avctx->priv_data;
|
||||
+ V4L2RequestControlsHEVC *controls = h->ref->hwaccel_picture_private;
|
||||
+ V4L2RequestDescriptor *req = (V4L2RequestDescriptor*)h->ref->frame->data[0];
|
||||
+ V4L2RequestContextHEVC *ctx = avctx->internal->hwaccel_priv_data;
|
||||
+ int ret, slice = FFMIN(controls->num_slices, 15);
|
||||
+
|
||||
+ // HACK: trigger decode per slice
|
||||
+ if (req->output.used) {
|
||||
+ v4l2_request_hevc_end_frame(avctx);
|
||||
+ ff_v4l2_request_reset_frame(avctx, h->ref->frame);
|
||||
+ if (ctx->decode_mode == V4L2_MPEG_VIDEO_HEVC_DECODE_MODE_SLICE_BASED && slice) {
|
||||
+ ret = v4l2_request_hevc_queue_decode(avctx, 0);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ff_v4l2_request_reset_frame(avctx, h->ref->frame);
|
||||
+ slice = controls->num_slices = 0;
|
||||
+ controls->first_slice = 0;
|
||||
+ }
|
||||
+
|
||||
+ v4l2_request_hevc_fill_slice_params(h, &controls->slice_params);
|
||||
+ v4l2_request_hevc_fill_slice_params(h, &controls->slice_params[slice]);
|
||||
+
|
||||
+ return ff_v4l2_request_append_output_buffer(avctx, h->ref->frame, buffer, size);
|
||||
+ ret = ff_v4l2_request_append_output_buffer(avctx, h->ref->frame, buffer, size);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ controls->slice_params[slice].bit_size = req->output.used * 8; //FIXME
|
||||
+ controls->num_slices++;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int v4l2_request_hevc_set_controls(AVCodecContext *avctx)
|
||||
+{
|
||||
+ V4L2RequestContextHEVC *ctx = avctx->internal->hwaccel_priv_data;
|
||||
+
|
||||
+ struct v4l2_ext_control control[] = {
|
||||
+ { .id = V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE, },
|
||||
+ { .id = V4L2_CID_MPEG_VIDEO_HEVC_START_CODE, },
|
||||
+ };
|
||||
+
|
||||
+ ctx->decode_mode = ff_v4l2_request_query_control_default_value(avctx, V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE);
|
||||
+ if (ctx->decode_mode != V4L2_MPEG_VIDEO_HEVC_DECODE_MODE_SLICE_BASED &&
|
||||
+ ctx->decode_mode != V4L2_MPEG_VIDEO_HEVC_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_HEVC_START_CODE);
|
||||
+ if (ctx->start_code != V4L2_MPEG_VIDEO_HEVC_START_CODE_NONE &&
|
||||
+ ctx->start_code != V4L2_MPEG_VIDEO_HEVC_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_hevc_init(AVCodecContext *avctx)
|
||||
+{
|
||||
+ return ff_v4l2_request_init(avctx, V4L2_PIX_FMT_HEVC_SLICE, 3 * 1024 * 1024, NULL, 0);
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = ff_v4l2_request_init(avctx, V4L2_PIX_FMT_HEVC_SLICE, 3 * 1024 * 1024, NULL, 0);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ return v4l2_request_hevc_set_controls(avctx);
|
||||
+}
|
||||
+
|
||||
+const AVHWAccel ff_hevc_v4l2request_hwaccel = {
|
||||
@ -494,7 +630,10 @@ index 0000000000..38969d77fb
|
||||
+ .frame_priv_data_size = sizeof(V4L2RequestControlsHEVC),
|
||||
+ .init = v4l2_request_hevc_init,
|
||||
+ .uninit = ff_v4l2_request_uninit,
|
||||
+ .priv_data_size = sizeof(V4L2RequestContext),
|
||||
+ .priv_data_size = sizeof(V4L2RequestContextHEVC),
|
||||
+ .frame_params = ff_v4l2_request_frame_params,
|
||||
+ .caps_internal = HWACCEL_CAP_ASYNC_SAFE,
|
||||
+};
|
||||
--
|
||||
2.24.0
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 2537bdd10973c0fc3f757cab01fd71dd0ef6b1e1 Mon Sep 17 00:00:00 2001
|
||||
From 13e487a5da1f64901391b99aa094a697fd2889aa 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
|
||||
Subject: [PATCH 06/12] Add V4L2 request API vp8 hwaccel
|
||||
|
||||
Need to fix the STREAMOFF/STREAMON issue in a proper way.
|
||||
|
||||
@ -280,3 +280,6 @@ index 62b9f8bc2d..55966b9d56 100644
|
||||
#endif
|
||||
NULL
|
||||
},
|
||||
--
|
||||
2.24.0
|
||||
|
||||
|
@ -1,20 +1,21 @@
|
||||
From be39d2e3e5228cdc2cf355d85f5566205f6cb65d Mon Sep 17 00:00:00 2001
|
||||
From 23e7417b7ceb66f2ff4a98da5b1785d24994f865 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] Add and use private linux headers for V4L2 request API ctrls
|
||||
Subject: [PATCH 07/12] Add and use private linux headers for V4L2 request API
|
||||
ctrls
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
---
|
||||
configure | 6 +-
|
||||
libavcodec/h264-ctrls.h | 210 ++++++++++++++++++++++++++++++++
|
||||
libavcodec/hevc-ctrls.h | 203 ++++++++++++++++++++++++++++++
|
||||
libavcodec/mpeg2-ctrls.h | 82 +++++++++++++
|
||||
libavcodec/h264-ctrls.h | 210 +++++++++++++++++++++++++++++
|
||||
libavcodec/hevc-ctrls.h | 229 ++++++++++++++++++++++++++++++++
|
||||
libavcodec/mpeg2-ctrls.h | 82 ++++++++++++
|
||||
libavcodec/v4l2_request_h264.c | 1 +
|
||||
libavcodec/v4l2_request_hevc.c | 1 +
|
||||
libavcodec/v4l2_request_mpeg2.c | 1 +
|
||||
libavcodec/v4l2_request_vp8.c | 1 +
|
||||
libavcodec/vp8-ctrls.h | 112 +++++++++++++++++
|
||||
9 files changed, 614 insertions(+), 3 deletions(-)
|
||||
libavcodec/vp8-ctrls.h | 112 ++++++++++++++++
|
||||
9 files changed, 640 insertions(+), 3 deletions(-)
|
||||
create mode 100644 libavcodec/h264-ctrls.h
|
||||
create mode 100644 libavcodec/hevc-ctrls.h
|
||||
create mode 100644 libavcodec/mpeg2-ctrls.h
|
||||
@ -269,10 +270,10 @@ index 0000000000..e877bf1d53
|
||||
+#endif
|
||||
diff --git a/libavcodec/hevc-ctrls.h b/libavcodec/hevc-ctrls.h
|
||||
new file mode 100644
|
||||
index 0000000000..eee4479c7a
|
||||
index 0000000000..d1b094c8aa
|
||||
--- /dev/null
|
||||
+++ b/libavcodec/hevc-ctrls.h
|
||||
@@ -0,0 +1,203 @@
|
||||
@@ -0,0 +1,229 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0 */
|
||||
+/*
|
||||
+ * These are the HEVC state controls for use with stateless HEVC
|
||||
@ -295,6 +296,8 @@ index 0000000000..eee4479c7a
|
||||
+#define V4L2_CID_MPEG_VIDEO_HEVC_PPS (V4L2_CID_MPEG_BASE + 1009)
|
||||
+#define V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS (V4L2_CID_MPEG_BASE + 1010)
|
||||
+#define V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX (V4L2_CID_MPEG_BASE + 1011)
|
||||
+#define V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE (V4L2_CID_MPEG_BASE + 1015)
|
||||
+#define V4L2_CID_MPEG_VIDEO_HEVC_START_CODE (V4L2_CID_MPEG_BASE + 1016)
|
||||
+
|
||||
+/* enum v4l2_ctrl_type type values */
|
||||
+#define V4L2_CTRL_TYPE_HEVC_SPS 0x0120
|
||||
@ -302,15 +305,33 @@ index 0000000000..eee4479c7a
|
||||
+#define V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS 0x0122
|
||||
+#define V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX 0x0123
|
||||
+
|
||||
+enum v4l2_mpeg_video_hevc_decode_mode {
|
||||
+ V4L2_MPEG_VIDEO_HEVC_DECODE_MODE_SLICE_BASED,
|
||||
+ V4L2_MPEG_VIDEO_HEVC_DECODE_MODE_FRAME_BASED,
|
||||
+};
|
||||
+
|
||||
+enum v4l2_mpeg_video_hevc_start_code {
|
||||
+ V4L2_MPEG_VIDEO_HEVC_START_CODE_NONE,
|
||||
+ V4L2_MPEG_VIDEO_HEVC_START_CODE_ANNEX_B,
|
||||
+};
|
||||
+
|
||||
+#define V4L2_HEVC_SLICE_TYPE_B 0
|
||||
+#define V4L2_HEVC_SLICE_TYPE_P 1
|
||||
+#define V4L2_HEVC_SLICE_TYPE_I 2
|
||||
+
|
||||
+#define V4L2_HEVC_SPS_FLAG_SEPARATE_COLOUR_PLANE (1ULL << 0)
|
||||
+#define V4L2_HEVC_SPS_FLAG_SCALING_LIST_ENABLED (1ULL << 1)
|
||||
+#define V4L2_HEVC_SPS_FLAG_AMP_ENABLED (1ULL << 2)
|
||||
+#define V4L2_HEVC_SPS_FLAG_SAMPLE_ADAPTIVE_OFFSET (1ULL << 3)
|
||||
+#define V4L2_HEVC_SPS_FLAG_PCM_ENABLED (1ULL << 4)
|
||||
+#define V4L2_HEVC_SPS_FLAG_PCM_LOOP_FILTER_DISABLED (1ULL << 5)
|
||||
+#define V4L2_HEVC_SPS_FLAG_LONG_TERM_REF_PICS_PRESENT (1ULL << 6)
|
||||
+#define V4L2_HEVC_SPS_FLAG_SPS_TEMPORAL_MVP_ENABLED (1ULL << 7)
|
||||
+#define V4L2_HEVC_SPS_FLAG_STRONG_INTRA_SMOOTHING_ENABLED (1ULL << 8)
|
||||
+
|
||||
+/* The controls are not stable at the moment and will likely be reworked. */
|
||||
+struct v4l2_ctrl_hevc_sps {
|
||||
+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: Sequence parameter set */
|
||||
+ __u8 chroma_format_idc;
|
||||
+ __u8 separate_colour_plane_flag;
|
||||
+ __u16 pic_width_in_luma_samples;
|
||||
+ __u16 pic_height_in_luma_samples;
|
||||
+ __u8 bit_depth_luma_minus8;
|
||||
@ -325,56 +346,56 @@ index 0000000000..eee4479c7a
|
||||
+ __u8 log2_diff_max_min_luma_transform_block_size;
|
||||
+ __u8 max_transform_hierarchy_depth_inter;
|
||||
+ __u8 max_transform_hierarchy_depth_intra;
|
||||
+ __u8 scaling_list_enabled_flag;
|
||||
+ __u8 amp_enabled_flag;
|
||||
+ __u8 sample_adaptive_offset_enabled_flag;
|
||||
+ __u8 pcm_enabled_flag;
|
||||
+ __u8 pcm_sample_bit_depth_luma_minus1;
|
||||
+ __u8 pcm_sample_bit_depth_chroma_minus1;
|
||||
+ __u8 log2_min_pcm_luma_coding_block_size_minus3;
|
||||
+ __u8 log2_diff_max_min_pcm_luma_coding_block_size;
|
||||
+ __u8 pcm_loop_filter_disabled_flag;
|
||||
+ __u8 num_short_term_ref_pic_sets;
|
||||
+ __u8 long_term_ref_pics_present_flag;
|
||||
+ __u8 num_long_term_ref_pics_sps;
|
||||
+ __u8 sps_temporal_mvp_enabled_flag;
|
||||
+ __u8 strong_intra_smoothing_enabled_flag;
|
||||
+ __u8 chroma_format_idc;
|
||||
+
|
||||
+ __u8 padding;
|
||||
+
|
||||
+ __u64 flags;
|
||||
+};
|
||||
+
|
||||
+#define V4L2_HEVC_PPS_FLAG_DEPENDENT_SLICE_SEGMENT (1ULL << 0)
|
||||
+#define V4L2_HEVC_PPS_FLAG_OUTPUT_FLAG_PRESENT (1ULL << 1)
|
||||
+#define V4L2_HEVC_PPS_FLAG_SIGN_DATA_HIDING_ENABLED (1ULL << 2)
|
||||
+#define V4L2_HEVC_PPS_FLAG_CABAC_INIT_PRESENT (1ULL << 3)
|
||||
+#define V4L2_HEVC_PPS_FLAG_CONSTRAINED_INTRA_PRED (1ULL << 4)
|
||||
+#define V4L2_HEVC_PPS_FLAG_TRANSFORM_SKIP_ENABLED (1ULL << 5)
|
||||
+#define V4L2_HEVC_PPS_FLAG_CU_QP_DELTA_ENABLED (1ULL << 6)
|
||||
+#define V4L2_HEVC_PPS_FLAG_PPS_SLICE_CHROMA_QP_OFFSETS_PRESENT (1ULL << 7)
|
||||
+#define V4L2_HEVC_PPS_FLAG_WEIGHTED_PRED (1ULL << 8)
|
||||
+#define V4L2_HEVC_PPS_FLAG_WEIGHTED_BIPRED (1ULL << 9)
|
||||
+#define V4L2_HEVC_PPS_FLAG_TRANSQUANT_BYPASS_ENABLED (1ULL << 10)
|
||||
+#define V4L2_HEVC_PPS_FLAG_TILES_ENABLED (1ULL << 11)
|
||||
+#define V4L2_HEVC_PPS_FLAG_ENTROPY_CODING_SYNC_ENABLED (1ULL << 12)
|
||||
+#define V4L2_HEVC_PPS_FLAG_LOOP_FILTER_ACROSS_TILES_ENABLED (1ULL << 13)
|
||||
+#define V4L2_HEVC_PPS_FLAG_PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED (1ULL << 14)
|
||||
+#define V4L2_HEVC_PPS_FLAG_DEBLOCKING_FILTER_OVERRIDE_ENABLED (1ULL << 15)
|
||||
+#define V4L2_HEVC_PPS_FLAG_PPS_DISABLE_DEBLOCKING_FILTER (1ULL << 16)
|
||||
+#define V4L2_HEVC_PPS_FLAG_LISTS_MODIFICATION_PRESENT (1ULL << 17)
|
||||
+#define V4L2_HEVC_PPS_FLAG_SLICE_SEGMENT_HEADER_EXTENSION_PRESENT (1ULL << 18)
|
||||
+
|
||||
+struct v4l2_ctrl_hevc_pps {
|
||||
+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: Picture parameter set */
|
||||
+ __u8 dependent_slice_segment_flag;
|
||||
+ __u8 output_flag_present_flag;
|
||||
+ __u8 num_extra_slice_header_bits;
|
||||
+ __u8 sign_data_hiding_enabled_flag;
|
||||
+ __u8 cabac_init_present_flag;
|
||||
+ __s8 init_qp_minus26;
|
||||
+ __u8 constrained_intra_pred_flag;
|
||||
+ __u8 transform_skip_enabled_flag;
|
||||
+ __u8 cu_qp_delta_enabled_flag;
|
||||
+ __u8 diff_cu_qp_delta_depth;
|
||||
+ __s8 pps_cb_qp_offset;
|
||||
+ __s8 pps_cr_qp_offset;
|
||||
+ __u8 pps_slice_chroma_qp_offsets_present_flag;
|
||||
+ __u8 weighted_pred_flag;
|
||||
+ __u8 weighted_bipred_flag;
|
||||
+ __u8 transquant_bypass_enabled_flag;
|
||||
+ __u8 tiles_enabled_flag;
|
||||
+ __u8 entropy_coding_sync_enabled_flag;
|
||||
+ __u8 num_tile_columns_minus1;
|
||||
+ __u8 num_tile_rows_minus1;
|
||||
+ __u8 column_width_minus1[20];
|
||||
+ __u8 row_height_minus1[22];
|
||||
+ __u8 loop_filter_across_tiles_enabled_flag;
|
||||
+ __u8 pps_loop_filter_across_slices_enabled_flag;
|
||||
+ __u8 deblocking_filter_override_enabled_flag;
|
||||
+ __u8 pps_disable_deblocking_filter_flag;
|
||||
+ __s8 pps_beta_offset_div2;
|
||||
+ __s8 pps_tc_offset_div2;
|
||||
+ __u8 lists_modification_present_flag;
|
||||
+ __u8 log2_parallel_merge_level_minus2;
|
||||
+ __u8 slice_segment_header_extension_present_flag;
|
||||
+ __u8 scaling_list_enable_flag;
|
||||
+
|
||||
+ __u8 padding[4];
|
||||
+ __u64 flags;
|
||||
+};
|
||||
+
|
||||
+#define V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_BEFORE 0x01
|
||||
@ -392,9 +413,6 @@ index 0000000000..eee4479c7a
|
||||
+};
|
||||
+
|
||||
+struct v4l2_hevc_pred_weight_table {
|
||||
+ __u8 luma_log2_weight_denom;
|
||||
+ __s8 delta_chroma_log2_weight_denom;
|
||||
+
|
||||
+ __s8 delta_luma_weight_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
|
||||
+ __s8 luma_offset_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
|
||||
+ __s8 delta_chroma_weight_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX][2];
|
||||
@ -405,13 +423,30 @@ index 0000000000..eee4479c7a
|
||||
+ __s8 delta_chroma_weight_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX][2];
|
||||
+ __s8 chroma_offset_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX][2];
|
||||
+
|
||||
+ __u8 padding[2];
|
||||
+ __u8 padding[6];
|
||||
+
|
||||
+ __u8 luma_log2_weight_denom;
|
||||
+ __s8 delta_chroma_log2_weight_denom;
|
||||
+};
|
||||
+
|
||||
+#define V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_SAO_LUMA (1ULL << 0)
|
||||
+#define V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_SAO_CHROMA (1ULL << 1)
|
||||
+#define V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_TEMPORAL_MVP_ENABLED (1ULL << 2)
|
||||
+#define V4L2_HEVC_SLICE_PARAMS_FLAG_MVD_L1_ZERO (1ULL << 3)
|
||||
+#define V4L2_HEVC_SLICE_PARAMS_FLAG_CABAC_INIT (1ULL << 4)
|
||||
+#define V4L2_HEVC_SLICE_PARAMS_FLAG_COLLOCATED_FROM_L0 (1ULL << 5)
|
||||
+#define V4L2_HEVC_SLICE_PARAMS_FLAG_USE_INTEGER_MV (1ULL << 6)
|
||||
+#define V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_DEBLOCKING_FILTER_DISABLED (1ULL << 7)
|
||||
+#define V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_LOOP_FILTER_ACROSS_SLICES_ENABLED (1ULL << 8)
|
||||
+
|
||||
+struct v4l2_ctrl_hevc_slice_params {
|
||||
+ __u32 bit_size;
|
||||
+ __u32 data_bit_offset;
|
||||
+
|
||||
+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: General slice segment header */
|
||||
+ __u32 slice_segment_addr;
|
||||
+ __u32 num_entry_point_offsets;
|
||||
+
|
||||
+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: NAL unit header */
|
||||
+ __u8 nal_unit_type;
|
||||
+ __u8 nuh_temporal_id_plus1;
|
||||
@ -420,33 +455,23 @@ index 0000000000..eee4479c7a
|
||||
+ __u8 slice_type;
|
||||
+ __u8 colour_plane_id;
|
||||
+ __u16 slice_pic_order_cnt;
|
||||
+ __u8 slice_sao_luma_flag;
|
||||
+ __u8 slice_sao_chroma_flag;
|
||||
+ __u8 slice_temporal_mvp_enabled_flag;
|
||||
+ __u8 num_ref_idx_l0_active_minus1;
|
||||
+ __u8 num_ref_idx_l1_active_minus1;
|
||||
+ __u8 mvd_l1_zero_flag;
|
||||
+ __u8 cabac_init_flag;
|
||||
+ __u8 collocated_from_l0_flag;
|
||||
+ __u8 collocated_ref_idx;
|
||||
+ __u8 five_minus_max_num_merge_cand;
|
||||
+ __u8 use_integer_mv_flag;
|
||||
+ __s8 slice_qp_delta;
|
||||
+ __s8 slice_cb_qp_offset;
|
||||
+ __s8 slice_cr_qp_offset;
|
||||
+ __s8 slice_act_y_qp_offset;
|
||||
+ __s8 slice_act_cb_qp_offset;
|
||||
+ __s8 slice_act_cr_qp_offset;
|
||||
+ __u8 slice_deblocking_filter_disabled_flag;
|
||||
+ __s8 slice_beta_offset_div2;
|
||||
+ __s8 slice_tc_offset_div2;
|
||||
+ __u8 slice_loop_filter_across_slices_enabled_flag;
|
||||
+
|
||||
+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: Picture timing SEI message */
|
||||
+ __u8 pic_struct;
|
||||
+
|
||||
+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: General slice segment header */
|
||||
+ struct v4l2_hevc_dpb_entry dpb[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
|
||||
+ __u8 num_active_dpb_entries;
|
||||
+ __u8 ref_idx_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
|
||||
+ __u8 ref_idx_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
|
||||
@ -455,15 +480,17 @@ index 0000000000..eee4479c7a
|
||||
+ __u8 num_rps_poc_st_curr_after;
|
||||
+ __u8 num_rps_poc_lt_curr;
|
||||
+
|
||||
+ __u8 padding;
|
||||
+
|
||||
+ __u32 entry_point_offset_minus1[256];
|
||||
+
|
||||
+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: General slice segment header */
|
||||
+ struct v4l2_hevc_dpb_entry dpb[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
|
||||
+
|
||||
+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: Weighted prediction parameter */
|
||||
+ struct v4l2_hevc_pred_weight_table pred_weight_table;
|
||||
+
|
||||
+ __u32 slice_segment_addr;
|
||||
+ __u32 num_entry_point_offsets;
|
||||
+ __u32 entry_point_offset_minus1[256];
|
||||
+ __u8 first_slice_segment_in_pic_flag;
|
||||
+
|
||||
+ __u8 padding;
|
||||
+ __u64 flags;
|
||||
+};
|
||||
+
|
||||
+struct v4l2_ctrl_hevc_scaling_matrix {
|
||||
@ -565,7 +592,7 @@ index 0000000000..6601455b3d
|
||||
+
|
||||
+#endif
|
||||
diff --git a/libavcodec/v4l2_request_h264.c b/libavcodec/v4l2_request_h264.c
|
||||
index fb9913922d..b826c9d356 100644
|
||||
index 81b3c4b092..ca306b6a3f 100644
|
||||
--- a/libavcodec/v4l2_request_h264.c
|
||||
+++ b/libavcodec/v4l2_request_h264.c
|
||||
@@ -19,6 +19,7 @@
|
||||
@ -577,7 +604,7 @@ index fb9913922d..b826c9d356 100644
|
||||
typedef struct V4L2RequestControlsH264 {
|
||||
struct v4l2_ctrl_h264_sps sps;
|
||||
diff --git a/libavcodec/v4l2_request_hevc.c b/libavcodec/v4l2_request_hevc.c
|
||||
index 38969d77fb..b73eb2ab03 100644
|
||||
index da1fd666d7..94977c5d0e 100644
|
||||
--- a/libavcodec/v4l2_request_hevc.c
|
||||
+++ b/libavcodec/v4l2_request_hevc.c
|
||||
@@ -19,6 +19,7 @@
|
||||
@ -730,3 +757,6 @@ index 0000000000..53cba826e4
|
||||
+};
|
||||
+
|
||||
+#endif
|
||||
--
|
||||
2.24.0
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 0c4c87e72463da1a4bf45032e4db3c2c86d6d8d8 Mon Sep 17 00:00:00 2001
|
||||
From 6b20e11c96907fb474b1bf33615223bf79eba9c0 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
|
||||
Subject: [PATCH 08/12] hwcontext_drm: do not require drm device
|
||||
|
||||
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
||||
---
|
||||
@ -24,3 +24,6 @@ index 32cbde82eb..aa4794c5e6 100644
|
||||
hwctx->fd = open(device, O_RDWR);
|
||||
if (hwctx->fd < 0)
|
||||
return AVERROR(errno);
|
||||
--
|
||||
2.24.0
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 3d50f433609688b6d4ffb2bcec41507f7f507dc2 Mon Sep 17 00:00:00 2001
|
||||
From 4c1ce1fde5ca6d3e80bb0d5ab44f2e05f8372db0 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
|
||||
Subject: [PATCH 09/12] avcodec/h264: parse idr_pic_id
|
||||
|
||||
Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
|
||||
---
|
||||
@ -37,10 +37,10 @@ index b0b42b7672..38efab5c60 100644
|
||||
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
|
||||
index ca306b6a3f..f21c8b3508 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 *
|
||||
@@ -301,7 +301,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,
|
||||
@ -49,3 +49,6 @@ index b826c9d356..a49773b228 100644
|
||||
.pic_order_cnt_lsb = sl->poc_lsb,
|
||||
.delta_pic_order_cnt_bottom = sl->delta_poc_bottom,
|
||||
.delta_pic_order_cnt0 = sl->delta_poc[0],
|
||||
--
|
||||
2.24.0
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 2f915e957c6bc5887cc24a8762fdadea17359f57 Mon Sep 17 00:00:00 2001
|
||||
From 0a7b4a2cffae5d37b753b3e4cc8cadd7204ef5f5 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
|
||||
Subject: [PATCH 10/12] avcodec/h264: parse ref_pic_marking_size_in_bits and
|
||||
pic_order_cnt_bit_size
|
||||
|
||||
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
|
||||
@ -71,10 +71,10 @@ index 38efab5c60..8e894f565b 100644
|
||||
int max_pic_num;
|
||||
} H264SliceContext;
|
||||
diff --git a/libavcodec/v4l2_request_h264.c b/libavcodec/v4l2_request_h264.c
|
||||
index a49773b228..229df6969d 100644
|
||||
index f21c8b3508..1a7fb873a0 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 *
|
||||
@@ -309,9 +309,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. */
|
||||
@ -86,3 +86,6 @@ index a49773b228..229df6969d 100644
|
||||
|
||||
.cabac_init_idc = sl->cabac_init_idc,
|
||||
.slice_qp_delta = sl->qscale - pps->init_qp,
|
||||
--
|
||||
2.24.0
|
||||
|
||||
|
@ -1,7 +1,8 @@
|
||||
From 45df99d31062e068073cf899dce559e334c9127f Mon Sep 17 00:00:00 2001
|
||||
From 1a2197eea4da8f118726963e0c74647532029306 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
|
||||
Subject: [PATCH 11/12] HACK: add dpb flags for reference usage and field
|
||||
picture
|
||||
|
||||
This or something similar needs to be upstreamed to kernel h264 ctrls
|
||||
|
||||
@ -27,10 +28,10 @@ index e877bf1d53..76020ebd1e 100644
|
||||
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
|
||||
index 1a7fb873a0..13fac3f6f9 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
|
||||
@@ -66,10 +66,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;
|
||||
@ -44,7 +45,7 @@ index 229df6969d..7f345b1955 100644
|
||||
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
|
||||
@@ -109,7 +112,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)
|
||||
@ -54,3 +55,6 @@ index 229df6969d..7f345b1955 100644
|
||||
}
|
||||
|
||||
return 0;
|
||||
--
|
||||
2.24.0
|
||||
|
||||
|
@ -0,0 +1,72 @@
|
||||
From a205c82e430dafd90485b804ce40c1b42cbf9edf Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Sat, 9 Nov 2019 10:02:43 +0000
|
||||
Subject: [PATCH 12/12] WIP: v4l2-request: rolling timestamps
|
||||
|
||||
---
|
||||
libavcodec/v4l2_request.c | 10 +++++++---
|
||||
libavcodec/v4l2_request.h | 1 +
|
||||
2 files changed, 8 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/libavcodec/v4l2_request.c b/libavcodec/v4l2_request.c
|
||||
index 1dabf77689..611c22f8b6 100644
|
||||
--- a/libavcodec/v4l2_request.c
|
||||
+++ b/libavcodec/v4l2_request.c
|
||||
@@ -105,12 +105,14 @@ static int v4l2_request_queue_buffer(V4L2RequestContext *ctx, int request_fd, V4
|
||||
.type = buf->buffer.type,
|
||||
.memory = buf->buffer.memory,
|
||||
.index = buf->index,
|
||||
- .timestamp.tv_usec = buf->index + 1,
|
||||
+ .timestamp.tv_usec = ctx->timestamp,
|
||||
.bytesused = buf->used,
|
||||
.request_fd = request_fd,
|
||||
.flags = ((request_fd >= 0) ? V4L2_BUF_FLAG_REQUEST_FD : 0) | flags,
|
||||
};
|
||||
|
||||
+ buf->buffer.timestamp = buffer.timestamp;
|
||||
+
|
||||
if (V4L2_TYPE_IS_MULTIPLANAR(buf->buffer.type)) {
|
||||
planes[0].bytesused = buf->used;
|
||||
buffer.bytesused = 0;
|
||||
@@ -200,6 +202,9 @@ static int v4l2_request_queue_decode(AVCodecContext *avctx, AVFrame *frame, stru
|
||||
|
||||
av_log(avctx, AV_LOG_DEBUG, "%s: avctx=%p used=%u controls=%d index=%d fd=%d request_fd=%d first_slice=%d last_slice=%d\n", __func__, avctx, req->output.used, count, req->capture.index, req->capture.fd, req->request_fd, first_slice, last_slice);
|
||||
|
||||
+ if (first_slice)
|
||||
+ ctx->timestamp++;
|
||||
+
|
||||
ret = v4l2_request_set_controls(ctx, req->request_fd, control, count);
|
||||
if (ret < 0) {
|
||||
av_log(avctx, AV_LOG_ERROR, "%s: set controls failed for request %d, %s (%d)\n", __func__, req->request_fd, strerror(errno), errno);
|
||||
@@ -651,6 +656,7 @@ int ff_v4l2_request_init(AVCodecContext *avctx, uint32_t pixelformat, uint32_t b
|
||||
|
||||
ctx->media_fd = -1;
|
||||
ctx->video_fd = -1;
|
||||
+ ctx->timestamp = 0;
|
||||
|
||||
udev = udev_new();
|
||||
if (!udev) {
|
||||
@@ -784,8 +790,6 @@ static int v4l2_request_buffer_alloc(AVCodecContext *avctx, V4L2RequestBuffer *b
|
||||
return ret;
|
||||
}
|
||||
|
||||
- buf->buffer.timestamp.tv_usec = buf->index + 1;
|
||||
-
|
||||
if (V4L2_TYPE_IS_OUTPUT(type)) {
|
||||
void *addr = mmap(NULL, buf->size, PROT_READ | PROT_WRITE, MAP_SHARED, ctx->video_fd, V4L2_TYPE_IS_MULTIPLANAR(type) ? buf->buffer.m.planes[0].m.mem_offset : buf->buffer.m.offset);
|
||||
if (addr == MAP_FAILED) {
|
||||
diff --git a/libavcodec/v4l2_request.h b/libavcodec/v4l2_request.h
|
||||
index d4146bd4ee..72698f6f3c 100644
|
||||
--- a/libavcodec/v4l2_request.h
|
||||
+++ b/libavcodec/v4l2_request.h
|
||||
@@ -28,6 +28,7 @@ typedef struct V4L2RequestContext {
|
||||
int media_fd;
|
||||
enum v4l2_buf_type output_type;
|
||||
struct v4l2_format format;
|
||||
+ int timestamp;
|
||||
} V4L2RequestContext;
|
||||
|
||||
typedef struct V4L2RequestBuffer {
|
||||
--
|
||||
2.24.0
|
||||
|
@ -1,20 +1,20 @@
|
||||
From d117460aed81ee5cd384045a1189c9de758d17c6 Mon Sep 17 00:00:00 2001
|
||||
From 60808cc1810d47f91c368de8ffb7db59cabceaf9 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Tue, 28 May 2019 21:05:34 +0200
|
||||
Subject: [PATCH] 10-bit HEVC hack
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
---
|
||||
drivers/staging/media/sunxi/cedrus/cedrus_h265.c | 12 ++++++++++++
|
||||
drivers/staging/media/sunxi/cedrus/cedrus_regs.h | 4 ++++
|
||||
drivers/staging/media/sunxi/cedrus/cedrus_video.c | 13 +++++++++++--
|
||||
3 files changed, 27 insertions(+), 2 deletions(-)
|
||||
.../staging/media/sunxi/cedrus/cedrus_h265.c | 12 +++++++++++
|
||||
.../staging/media/sunxi/cedrus/cedrus_regs.h | 4 ++++
|
||||
.../staging/media/sunxi/cedrus/cedrus_video.c | 20 ++++++++++++++-----
|
||||
3 files changed, 31 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
|
||||
index 8bbbe69ae51f..04ba7d60ebcd 100644
|
||||
index 97dce6ffbbc5..d866662cd5a5 100644
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
|
||||
@@ -453,6 +453,18 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
|
||||
@@ -520,6 +520,18 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
|
||||
|
||||
cedrus_write(dev, VE_DEC_H265_DEC_PCM_CTRL, reg);
|
||||
|
||||
@ -30,14 +30,14 @@ index 8bbbe69ae51f..04ba7d60ebcd 100644
|
||||
+ cedrus_write(dev, VE_DEC_H265_10BIT_CONFIGURE, ALIGN(reg, 32));
|
||||
+ }
|
||||
+
|
||||
/* PPS. */
|
||||
|
||||
reg = VE_DEC_H265_DEC_PPS_CTRL0_PPS_CR_QP_OFFSET(pps->pps_cr_qp_offset) |
|
||||
VE_DEC_H265_DEC_PPS_CTRL0_PPS_CB_QP_OFFSET(pps->pps_cb_qp_offset) |
|
||||
VE_DEC_H265_DEC_PPS_CTRL0_INIT_QP_MINUS26(pps->init_qp_minus26) |
|
||||
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
|
||||
index d1f010ae49ef..dd69031a2779 100644
|
||||
index df1cceef8d93..150eae2d92d2 100644
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
|
||||
@@ -505,6 +505,10 @@
|
||||
@@ -498,6 +498,10 @@
|
||||
|
||||
#define VE_DEC_H265_LOW_ADDR (VE_ENGINE_DEC_H265 + 0x80)
|
||||
|
||||
@ -46,25 +46,25 @@ index d1f010ae49ef..dd69031a2779 100644
|
||||
+#define VE_DEC_H265_10BIT_CONFIGURE (VE_ENGINE_DEC_H265 + 0x8c)
|
||||
+
|
||||
#define VE_DEC_H265_LOW_ADDR_PRIMARY_CHROMA(a) \
|
||||
(((a) << 24) & GENMASK(31, 24))
|
||||
SHIFT_AND_MASK_BITS(a, 31, 24)
|
||||
#define VE_DEC_H265_LOW_ADDR_SECONDARY_CHROMA(a) \
|
||||
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_video.c b/drivers/staging/media/sunxi/cedrus/cedrus_video.c
|
||||
index d27a9e82ff91..2c2288319c9d 100644
|
||||
index 497b1199d3fe..178ad45b79d8 100644
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus_video.c
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_video.c
|
||||
@@ -372,6 +372,7 @@ static int cedrus_queue_setup(struct vb2_queue *vq, unsigned int *nbufs,
|
||||
@@ -367,17 +367,27 @@ static int cedrus_queue_setup(struct vb2_queue *vq, unsigned int *nbufs,
|
||||
{
|
||||
struct cedrus_ctx *ctx = vb2_get_drv_priv(vq);
|
||||
struct cedrus_dev *dev = ctx->dev;
|
||||
struct v4l2_pix_format *pix_fmt;
|
||||
+ unsigned int extra_size = 0;
|
||||
u32 directions;
|
||||
|
||||
if (V4L2_TYPE_IS_OUTPUT(vq->type)) {
|
||||
@@ -380,6 +381,14 @@ static int cedrus_queue_setup(struct vb2_queue *vq, unsigned int *nbufs,
|
||||
} else {
|
||||
directions = CEDRUS_DECODE_DST;
|
||||
- if (V4L2_TYPE_IS_OUTPUT(vq->type))
|
||||
+ if (V4L2_TYPE_IS_OUTPUT(vq->type)) {
|
||||
pix_fmt = &ctx->src_fmt;
|
||||
- else
|
||||
+ } else {
|
||||
pix_fmt = &ctx->dst_fmt;
|
||||
+
|
||||
|
||||
+ /* The HEVC decoder needs extra size on the output buffer. */
|
||||
+ if (ctx->src_fmt.pixelformat == V4L2_PIX_FMT_HEVC_SLICE) {
|
||||
+ extra_size = DIV_ROUND_UP(pix_fmt->width, 4);
|
||||
@ -72,20 +72,19 @@ index d27a9e82ff91..2c2288319c9d 100644
|
||||
+ extra_size *= ALIGN(pix_fmt->height, 16) * 3;
|
||||
+ extra_size /= 2;
|
||||
+ }
|
||||
}
|
||||
|
||||
if (!cedrus_check_format(pix_fmt->pixelformat, directions,
|
||||
@@ -387,8 +396,8 @@ static int cedrus_queue_setup(struct vb2_queue *vq, unsigned int *nbufs,
|
||||
return -EINVAL;
|
||||
|
||||
+ }
|
||||
+
|
||||
if (*nplanes) {
|
||||
- if (sizes[0] < pix_fmt->sizeimage)
|
||||
- return -EINVAL;
|
||||
+ if (sizes[0] < (pix_fmt->sizeimage + extra_size))
|
||||
+ sizes[0] = pix_fmt->sizeimage + extra_size;
|
||||
} else {
|
||||
sizes[0] = pix_fmt->sizeimage;
|
||||
- sizes[0] = pix_fmt->sizeimage;
|
||||
+ sizes[0] = pix_fmt->sizeimage + extra_size;
|
||||
*nplanes = 1;
|
||||
}
|
||||
|
||||
--
|
||||
2.21.0
|
||||
2.23.0
|
||||
|
||||
|
@ -5800,3 +5800,845 @@ index 95c312ae94cf..7646636f2d18 100644
|
||||
--
|
||||
2.23.0
|
||||
|
||||
From de8145452eebe5510bd2b142b31560db548d6abb Mon Sep 17 00:00:00 2001
|
||||
From: Ezequiel Garcia <ezequiel@collabora.com>
|
||||
Date: Thu, 11 Jul 2019 16:26:41 -0400
|
||||
Subject: [PATCH] media: v4l2-ctrl: Move compound control validation
|
||||
|
||||
Rework std_validate moving the compound controls to
|
||||
its own validation function.
|
||||
|
||||
While here, fix the pointer math to account the index parameter.
|
||||
|
||||
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/media/v4l2-core/v4l2-ctrls.c | 126 +++++++++++++++------------
|
||||
1 file changed, 69 insertions(+), 57 deletions(-)
|
||||
|
||||
diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
|
||||
index 371537dd8cd3..739418aa9108 100644
|
||||
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
|
||||
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
|
||||
@@ -1629,10 +1629,77 @@ static void std_log(const struct v4l2_ctrl *ctrl)
|
||||
})
|
||||
|
||||
/* Validate a new control */
|
||||
+static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx,
|
||||
+ union v4l2_ctrl_ptr ptr)
|
||||
+{
|
||||
+ struct v4l2_ctrl_mpeg2_slice_params *p_mpeg2_slice_params;
|
||||
+ void *p = ptr.p + idx * ctrl->elem_size;
|
||||
+
|
||||
+ switch ((u32)ctrl->type) {
|
||||
+ case V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS:
|
||||
+ p_mpeg2_slice_params = p;
|
||||
+
|
||||
+ switch (p_mpeg2_slice_params->sequence.chroma_format) {
|
||||
+ case 1: /* 4:2:0 */
|
||||
+ case 2: /* 4:2:2 */
|
||||
+ case 3: /* 4:4:4 */
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ switch (p_mpeg2_slice_params->picture.intra_dc_precision) {
|
||||
+ case 0: /* 8 bits */
|
||||
+ case 1: /* 9 bits */
|
||||
+ case 2: /* 10 bits */
|
||||
+ case 3: /* 11 bits */
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ switch (p_mpeg2_slice_params->picture.picture_structure) {
|
||||
+ case 1: /* interlaced top field */
|
||||
+ case 2: /* interlaced bottom field */
|
||||
+ case 3: /* progressive */
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ switch (p_mpeg2_slice_params->picture.picture_coding_type) {
|
||||
+ case V4L2_MPEG2_PICTURE_CODING_TYPE_I:
|
||||
+ case V4L2_MPEG2_PICTURE_CODING_TYPE_P:
|
||||
+ case V4L2_MPEG2_PICTURE_CODING_TYPE_B:
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ break;
|
||||
+
|
||||
+ case V4L2_CTRL_TYPE_MPEG2_QUANTIZATION:
|
||||
+ break;
|
||||
+
|
||||
+ case V4L2_CTRL_TYPE_FWHT_PARAMS:
|
||||
+ break;
|
||||
+
|
||||
+ 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:
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int std_validate(const struct v4l2_ctrl *ctrl, u32 idx,
|
||||
union v4l2_ctrl_ptr ptr)
|
||||
{
|
||||
- struct v4l2_ctrl_mpeg2_slice_params *p_mpeg2_slice_params;
|
||||
size_t len;
|
||||
u64 offset;
|
||||
s64 val;
|
||||
@@ -1695,63 +1762,8 @@ static int std_validate(const struct v4l2_ctrl *ctrl, u32 idx,
|
||||
return -ERANGE;
|
||||
return 0;
|
||||
|
||||
- case V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS:
|
||||
- p_mpeg2_slice_params = ptr.p;
|
||||
-
|
||||
- switch (p_mpeg2_slice_params->sequence.chroma_format) {
|
||||
- case 1: /* 4:2:0 */
|
||||
- case 2: /* 4:2:2 */
|
||||
- case 3: /* 4:4:4 */
|
||||
- break;
|
||||
- default:
|
||||
- return -EINVAL;
|
||||
- }
|
||||
-
|
||||
- switch (p_mpeg2_slice_params->picture.intra_dc_precision) {
|
||||
- case 0: /* 8 bits */
|
||||
- case 1: /* 9 bits */
|
||||
- case 2: /* 10 bits */
|
||||
- case 3: /* 11 bits */
|
||||
- break;
|
||||
- default:
|
||||
- return -EINVAL;
|
||||
- }
|
||||
-
|
||||
- switch (p_mpeg2_slice_params->picture.picture_structure) {
|
||||
- case 1: /* interlaced top field */
|
||||
- case 2: /* interlaced bottom field */
|
||||
- case 3: /* progressive */
|
||||
- break;
|
||||
- default:
|
||||
- return -EINVAL;
|
||||
- }
|
||||
-
|
||||
- switch (p_mpeg2_slice_params->picture.picture_coding_type) {
|
||||
- case V4L2_MPEG2_PICTURE_CODING_TYPE_I:
|
||||
- case V4L2_MPEG2_PICTURE_CODING_TYPE_P:
|
||||
- case V4L2_MPEG2_PICTURE_CODING_TYPE_B:
|
||||
- break;
|
||||
- default:
|
||||
- return -EINVAL;
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
-
|
||||
- case V4L2_CTRL_TYPE_MPEG2_QUANTIZATION:
|
||||
- return 0;
|
||||
-
|
||||
- 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;
|
||||
+ return std_validate_compound(ctrl, idx, ptr);
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
2.23.0
|
||||
|
||||
From a57d6acaf352d91e52271704f45c72e14cd2d98a Mon Sep 17 00:00:00 2001
|
||||
From: Pawel Osciak <posciak@chromium.org>
|
||||
Date: Thu, 11 Jul 2019 16:26:42 -0400
|
||||
Subject: [PATCH] media: uapi: Add VP8 stateless decoder API
|
||||
|
||||
Add the parsed VP8 frame pixel format and controls, to be used
|
||||
with the new stateless decoder API for VP8 to provide parameters
|
||||
for accelerator (aka stateless) codecs.
|
||||
|
||||
Reviewed-by: Tomasz Figa <tfiga@chromium.org>
|
||||
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
|
||||
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
|
||||
Signed-off-by: Pawel Osciak <posciak@chromium.org>
|
||||
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>
|
||||
---
|
||||
Documentation/media/uapi/v4l/biblio.rst | 10 +
|
||||
.../media/uapi/v4l/ext-ctrls-codec.rst | 323 ++++++++++++++++++
|
||||
.../media/uapi/v4l/pixfmt-compressed.rst | 20 ++
|
||||
drivers/media/v4l2-core/v4l2-ctrls.c | 10 +
|
||||
drivers/media/v4l2-core/v4l2-ioctl.c | 1 +
|
||||
include/media/v4l2-ctrls.h | 3 +
|
||||
include/media/vp8-ctrls.h | 110 ++++++
|
||||
7 files changed, 477 insertions(+)
|
||||
create mode 100644 include/media/vp8-ctrls.h
|
||||
|
||||
diff --git a/Documentation/media/uapi/v4l/biblio.rst b/Documentation/media/uapi/v4l/biblio.rst
|
||||
index 8f4eb8823d82..ad2ff258afa8 100644
|
||||
--- a/Documentation/media/uapi/v4l/biblio.rst
|
||||
+++ b/Documentation/media/uapi/v4l/biblio.rst
|
||||
@@ -395,3 +395,13 @@ colimg
|
||||
:title: Color Imaging: Fundamentals and Applications
|
||||
|
||||
:author: Erik Reinhard et al.
|
||||
+
|
||||
+.. _vp8:
|
||||
+
|
||||
+VP8
|
||||
+===
|
||||
+
|
||||
+
|
||||
+:title: RFC 6386: "VP8 Data Format and Decoding Guide"
|
||||
+
|
||||
+:author: J. Bankoski et al.
|
||||
diff --git a/Documentation/media/uapi/v4l/ext-ctrls-codec.rst b/Documentation/media/uapi/v4l/ext-ctrls-codec.rst
|
||||
index d6ea2ffd65c5..c5f39dd50043 100644
|
||||
--- a/Documentation/media/uapi/v4l/ext-ctrls-codec.rst
|
||||
+++ b/Documentation/media/uapi/v4l/ext-ctrls-codec.rst
|
||||
@@ -2234,6 +2234,329 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type -
|
||||
Quantization parameter for a P frame for FWHT. Valid range: from 1
|
||||
to 31.
|
||||
|
||||
+.. _v4l2-mpeg-vp8:
|
||||
+
|
||||
+``V4L2_CID_MPEG_VIDEO_VP8_FRAME_HEADER (struct)``
|
||||
+ Specifies the frame parameters for the associated VP8 parsed frame data.
|
||||
+ This includes the necessary parameters for
|
||||
+ configuring a stateless hardware decoding pipeline for VP8.
|
||||
+ The bitstream parameters are defined according to :ref:`vp8`.
|
||||
+
|
||||
+ .. note::
|
||||
+
|
||||
+ This compound control is not yet part of the public kernel API and
|
||||
+ it is expected to change.
|
||||
+
|
||||
+.. c:type:: v4l2_ctrl_vp8_frame_header
|
||||
+
|
||||
+.. cssclass:: longtable
|
||||
+
|
||||
+.. tabularcolumns:: |p{5.8cm}|p{4.8cm}|p{6.6cm}|
|
||||
+
|
||||
+.. flat-table:: struct v4l2_ctrl_vp8_frame_header
|
||||
+ :header-rows: 0
|
||||
+ :stub-columns: 0
|
||||
+ :widths: 1 1 2
|
||||
+
|
||||
+ * - struct :c:type:`v4l2_vp8_segment_header`
|
||||
+ - ``segment_header``
|
||||
+ - Structure with segment-based adjustments metadata.
|
||||
+ * - struct :c:type:`v4l2_vp8_loopfilter_header`
|
||||
+ - ``loopfilter_header``
|
||||
+ - Structure with loop filter level adjustments metadata.
|
||||
+ * - struct :c:type:`v4l2_vp8_quantization_header`
|
||||
+ - ``quant_header``
|
||||
+ - Structure with VP8 dequantization indices metadata.
|
||||
+ * - struct :c:type:`v4l2_vp8_entropy_header`
|
||||
+ - ``entropy_header``
|
||||
+ - Structure with VP8 entropy coder probabilities metadata.
|
||||
+ * - struct :c:type:`v4l2_vp8_entropy_coder_state`
|
||||
+ - ``coder_state``
|
||||
+ - Structure with VP8 entropy coder state.
|
||||
+ * - __u16
|
||||
+ - ``width``
|
||||
+ - The width of the frame. Must be set for all frames.
|
||||
+ * - __u16
|
||||
+ - ``height``
|
||||
+ - The height of the frame. Must be set for all frames.
|
||||
+ * - __u8
|
||||
+ - ``horizontal_scale``
|
||||
+ - Horizontal scaling factor.
|
||||
+ * - __u8
|
||||
+ - ``vertical_scaling factor``
|
||||
+ - Vertical scale.
|
||||
+ * - __u8
|
||||
+ - ``version``
|
||||
+ - Bitstream version.
|
||||
+ * - __u8
|
||||
+ - ``prob_skip_false``
|
||||
+ - Indicates the probability that the macroblock is not skipped.
|
||||
+ * - __u8
|
||||
+ - ``prob_intra``
|
||||
+ - Indicates the probability that a macroblock is intra-predicted.
|
||||
+ * - __u8
|
||||
+ - ``prob_last``
|
||||
+ - Indicates the probability that the last reference frame is used
|
||||
+ for inter-prediction
|
||||
+ * - __u8
|
||||
+ - ``prob_gf``
|
||||
+ - Indicates the probability that the golden reference frame is used
|
||||
+ for inter-prediction
|
||||
+ * - __u8
|
||||
+ - ``num_dct_parts``
|
||||
+ - Number of DCT coefficients partitions. Must be one of: 1, 2, 4, or 8.
|
||||
+ * - __u32
|
||||
+ - ``first_part_size``
|
||||
+ - Size of the first partition, i.e. the control partition.
|
||||
+ * - __u32
|
||||
+ - ``first_part_header_bits``
|
||||
+ - Size in bits of the first partition header portion.
|
||||
+ * - __u32
|
||||
+ - ``dct_part_sizes[8]``
|
||||
+ - DCT coefficients sizes.
|
||||
+ * - __u64
|
||||
+ - ``last_frame_ts``
|
||||
+ - Timestamp for the V4L2 capture buffer to use as last reference frame, used
|
||||
+ with inter-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.
|
||||
+ * - __u64
|
||||
+ - ``golden_frame_ts``
|
||||
+ - Timestamp for the V4L2 capture buffer to use as last reference frame, used
|
||||
+ with inter-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.
|
||||
+ * - __u64
|
||||
+ - ``alt_frame_ts``
|
||||
+ - Timestamp for the V4L2 capture buffer to use as alternate reference frame, used
|
||||
+ with inter-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.
|
||||
+ * - __u64
|
||||
+ - ``flags``
|
||||
+ - See :ref:`Frame Header Flags <vp8_frame_header_flags>`
|
||||
+
|
||||
+.. _vp8_frame_header_flags:
|
||||
+
|
||||
+``Frame Header Flags``
|
||||
+
|
||||
+.. cssclass:: longtable
|
||||
+
|
||||
+.. flat-table::
|
||||
+ :header-rows: 0
|
||||
+ :stub-columns: 0
|
||||
+ :widths: 1 1 2
|
||||
+
|
||||
+ * - ``V4L2_VP8_FRAME_HEADER_FLAG_KEY_FRAME``
|
||||
+ - 0x01
|
||||
+ - Indicates if the frame is a key frame.
|
||||
+ * - ``V4L2_VP8_FRAME_HEADER_FLAG_EXPERIMENTAL``
|
||||
+ - 0x02
|
||||
+ - Experimental bitstream.
|
||||
+ * - ``V4L2_VP8_FRAME_HEADER_FLAG_SHOW_FRAME``
|
||||
+ - 0x04
|
||||
+ - Show frame flag, indicates if the frame is for display.
|
||||
+ * - ``V4L2_VP8_FRAME_HEADER_FLAG_MB_NO_SKIP_COEFF``
|
||||
+ - 0x08
|
||||
+ - Enable/disable skipping of macroblocks with no non-zero coefficients.
|
||||
+ * - ``V4L2_VP8_FRAME_HEADER_FLAG_SIGN_BIAS_GOLDEN``
|
||||
+ - 0x10
|
||||
+ - Sign of motion vectors when the golden frame is referenced.
|
||||
+ * - ``V4L2_VP8_FRAME_HEADER_FLAG_SIGN_BIAS_ALT``
|
||||
+ - 0x20
|
||||
+ - Sign of motion vectors when the alt frame is referenced.
|
||||
+
|
||||
+.. c:type:: v4l2_vp8_entropy_coder_state
|
||||
+
|
||||
+.. cssclass:: longtable
|
||||
+
|
||||
+.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
|
||||
+
|
||||
+.. flat-table:: struct v4l2_vp8_entropy_coder_state
|
||||
+ :header-rows: 0
|
||||
+ :stub-columns: 0
|
||||
+ :widths: 1 1 2
|
||||
+
|
||||
+ * - __u8
|
||||
+ - ``range``
|
||||
+ -
|
||||
+ * - __u8
|
||||
+ - ``value``
|
||||
+ -
|
||||
+ * - __u8
|
||||
+ - ``bit_count``
|
||||
+ -
|
||||
+ * - __u8
|
||||
+ - ``padding``
|
||||
+ - Applications and drivers must set this to zero.
|
||||
+
|
||||
+.. c:type:: v4l2_vp8_segment_header
|
||||
+
|
||||
+.. cssclass:: longtable
|
||||
+
|
||||
+.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
|
||||
+
|
||||
+.. flat-table:: struct v4l2_vp8_segment_header
|
||||
+ :header-rows: 0
|
||||
+ :stub-columns: 0
|
||||
+ :widths: 1 1 2
|
||||
+
|
||||
+ * - __s8
|
||||
+ - ``quant_update[4]``
|
||||
+ - Signed quantizer value update.
|
||||
+ * - __s8
|
||||
+ - ``lf_update[4]``
|
||||
+ - Signed loop filter level value update.
|
||||
+ * - __u8
|
||||
+ - ``segment_probs[3]``
|
||||
+ - Segment probabilities.
|
||||
+ * - __u8
|
||||
+ - ``padding``
|
||||
+ - Applications and drivers must set this to zero.
|
||||
+ * - __u32
|
||||
+ - ``flags``
|
||||
+ - See :ref:`Segment Header Flags <vp8_segment_header_flags>`
|
||||
+
|
||||
+.. _vp8_segment_header_flags:
|
||||
+
|
||||
+``Segment Header Flags``
|
||||
+
|
||||
+.. cssclass:: longtable
|
||||
+
|
||||
+.. flat-table::
|
||||
+ :header-rows: 0
|
||||
+ :stub-columns: 0
|
||||
+ :widths: 1 1 2
|
||||
+
|
||||
+ * - ``V4L2_VP8_SEGMENT_HEADER_FLAG_ENABLED``
|
||||
+ - 0x01
|
||||
+ - Enable/disable segment-based adjustments.
|
||||
+ * - ``V4L2_VP8_SEGMENT_HEADER_FLAG_UPDATE_MAP``
|
||||
+ - 0x02
|
||||
+ - Indicates if the macroblock segmentation map is updated in this frame.
|
||||
+ * - ``V4L2_VP8_SEGMENT_HEADER_FLAG_UPDATE_FEATURE_DATA``
|
||||
+ - 0x04
|
||||
+ - Indicates if the segment feature data is updated in this frame.
|
||||
+ * - ``V4L2_VP8_SEGMENT_HEADER_FLAG_DELTA_VALUE_MODE``
|
||||
+ - 0x08
|
||||
+ - If is set, the segment feature data mode is delta-value.
|
||||
+ If cleared, it's absolute-value.
|
||||
+
|
||||
+.. c:type:: v4l2_vp8_loopfilter_header
|
||||
+
|
||||
+.. cssclass:: longtable
|
||||
+
|
||||
+.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
|
||||
+
|
||||
+.. flat-table:: struct v4l2_vp8_loopfilter_header
|
||||
+ :header-rows: 0
|
||||
+ :stub-columns: 0
|
||||
+ :widths: 1 1 2
|
||||
+
|
||||
+ * - __s8
|
||||
+ - ``ref_frm_delta[4]``
|
||||
+ - Reference adjustment (signed) delta value.
|
||||
+ * - __s8
|
||||
+ - ``mb_mode_delta[4]``
|
||||
+ - Macroblock prediction mode adjustment (signed) delta value.
|
||||
+ * - __u8
|
||||
+ - ``sharpness_level``
|
||||
+ - Sharpness level
|
||||
+ * - __u8
|
||||
+ - ``level``
|
||||
+ - Filter level
|
||||
+ * - __u16
|
||||
+ - ``padding``
|
||||
+ - Applications and drivers must set this to zero.
|
||||
+ * - __u32
|
||||
+ - ``flags``
|
||||
+ - See :ref:`Loopfilter Header Flags <vp8_loopfilter_header_flags>`
|
||||
+
|
||||
+.. _vp8_loopfilter_header_flags:
|
||||
+
|
||||
+``Loopfilter Header Flags``
|
||||
+
|
||||
+.. cssclass:: longtable
|
||||
+
|
||||
+.. flat-table::
|
||||
+ :header-rows: 0
|
||||
+ :stub-columns: 0
|
||||
+ :widths: 1 1 2
|
||||
+
|
||||
+ * - ``V4L2_VP8_LF_HEADER_ADJ_ENABLE``
|
||||
+ - 0x01
|
||||
+ - Enable/disable macroblock-level loop filter adjustment.
|
||||
+ * - ``V4L2_VP8_LF_HEADER_DELTA_UPDATE``
|
||||
+ - 0x02
|
||||
+ - Indicates if the delta values used in an adjustment are updated.
|
||||
+ * - ``V4L2_VP8_LF_FILTER_TYPE_SIMPLE``
|
||||
+ - 0x04
|
||||
+ - If set, indicates the filter type is simple.
|
||||
+ If cleared, the filter type is normal.
|
||||
+
|
||||
+.. c:type:: v4l2_vp8_quantization_header
|
||||
+
|
||||
+.. cssclass:: longtable
|
||||
+
|
||||
+.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
|
||||
+
|
||||
+.. flat-table:: struct v4l2_vp8_quantization_header
|
||||
+ :header-rows: 0
|
||||
+ :stub-columns: 0
|
||||
+ :widths: 1 1 2
|
||||
+
|
||||
+ * - __u8
|
||||
+ - ``y_ac_qi``
|
||||
+ - Luma AC coefficient table index.
|
||||
+ * - __s8
|
||||
+ - ``y_dc_delta``
|
||||
+ - Luma DC delta vaue.
|
||||
+ * - __s8
|
||||
+ - ``y2_dc_delta``
|
||||
+ - Y2 block DC delta value.
|
||||
+ * - __s8
|
||||
+ - ``y2_ac_delta``
|
||||
+ - Y2 block AC delta value.
|
||||
+ * - __s8
|
||||
+ - ``uv_dc_delta``
|
||||
+ - Chroma DC delta value.
|
||||
+ * - __s8
|
||||
+ - ``uv_ac_delta``
|
||||
+ - Chroma AC delta value.
|
||||
+ * - __u16
|
||||
+ - ``padding``
|
||||
+ - Applications and drivers must set this to zero.
|
||||
+
|
||||
+.. c:type:: v4l2_vp8_entropy_header
|
||||
+
|
||||
+.. cssclass:: longtable
|
||||
+
|
||||
+.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
|
||||
+
|
||||
+.. flat-table:: struct v4l2_vp8_entropy_header
|
||||
+ :header-rows: 0
|
||||
+ :stub-columns: 0
|
||||
+ :widths: 1 1 2
|
||||
+
|
||||
+ * - __u8
|
||||
+ - ``coeff_probs[4][8][3][11]``
|
||||
+ - Coefficient update probabilities.
|
||||
+ * - __u8
|
||||
+ - ``y_mode_probs[4]``
|
||||
+ - Luma mode update probabilities.
|
||||
+ * - __u8
|
||||
+ - ``uv_mode_probs[3]``
|
||||
+ - Chroma mode update probabilities.
|
||||
+ * - __u8
|
||||
+ - ``mv_probs[2][19]``
|
||||
+ - MV decoding update probabilities.
|
||||
+ * - __u8
|
||||
+ - ``padding[3]``
|
||||
+ - Applications and drivers must set this to zero.
|
||||
+
|
||||
.. raw:: latex
|
||||
|
||||
\normalsize
|
||||
diff --git a/Documentation/media/uapi/v4l/pixfmt-compressed.rst b/Documentation/media/uapi/v4l/pixfmt-compressed.rst
|
||||
index 4b701fc7653e..f52a7b67023d 100644
|
||||
--- a/Documentation/media/uapi/v4l/pixfmt-compressed.rst
|
||||
+++ b/Documentation/media/uapi/v4l/pixfmt-compressed.rst
|
||||
@@ -133,6 +133,26 @@ Compressed Formats
|
||||
- ``V4L2_PIX_FMT_VP8``
|
||||
- 'VP80'
|
||||
- VP8 video elementary stream.
|
||||
+ * .. _V4L2-PIX-FMT-VP8-FRAME:
|
||||
+
|
||||
+ - ``V4L2_PIX_FMT_VP8_FRAME``
|
||||
+ - 'VP8F'
|
||||
+ - VP8 parsed frame, as extracted from the container.
|
||||
+ This format is adapted for stateless video decoders that implement a
|
||||
+ VP8 pipeline (using the :ref:`mem2mem` and :ref:`media-request-api`).
|
||||
+ Metadata associated with the frame to decode is required to be passed
|
||||
+ through the ``V4L2_CID_MPEG_VIDEO_VP8_FRAME_HEADER`` control.
|
||||
+ See the :ref:`associated Codec Control IDs <v4l2-mpeg-vp8>`.
|
||||
+ 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.
|
||||
+
|
||||
+ .. note::
|
||||
+
|
||||
+ This format is not yet part of the public kernel API and it
|
||||
+ is expected to change.
|
||||
+
|
||||
* .. _V4L2-PIX-FMT-VP9:
|
||||
|
||||
- ``V4L2_PIX_FMT_VP9``
|
||||
diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
|
||||
index 739418aa9108..b2c9f5816c4a 100644
|
||||
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
|
||||
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
|
||||
@@ -885,6 +885,7 @@ const char *v4l2_ctrl_get_name(u32 id)
|
||||
case V4L2_CID_MPEG_VIDEO_VPX_P_FRAME_QP: return "VPX P-Frame QP Value";
|
||||
case V4L2_CID_MPEG_VIDEO_VP8_PROFILE: return "VP8 Profile";
|
||||
case V4L2_CID_MPEG_VIDEO_VP9_PROFILE: return "VP9 Profile";
|
||||
+ case V4L2_CID_MPEG_VIDEO_VP8_FRAME_HEADER: return "VP8 Frame Header";
|
||||
|
||||
/* HEVC controls */
|
||||
case V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP: return "HEVC I-Frame QP Value";
|
||||
@@ -1345,6 +1346,9 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
|
||||
case V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS:
|
||||
*type = V4L2_CTRL_TYPE_H264_DECODE_PARAMS;
|
||||
break;
|
||||
+ case V4L2_CID_MPEG_VIDEO_VP8_FRAME_HEADER:
|
||||
+ *type = V4L2_CTRL_TYPE_VP8_FRAME_HEADER;
|
||||
+ break;
|
||||
default:
|
||||
*type = V4L2_CTRL_TYPE_INTEGER;
|
||||
break;
|
||||
@@ -1690,6 +1694,9 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx,
|
||||
case V4L2_CTRL_TYPE_H264_SLICE_PARAMS:
|
||||
case V4L2_CTRL_TYPE_H264_DECODE_PARAMS:
|
||||
break;
|
||||
+
|
||||
+ case V4L2_CTRL_TYPE_VP8_FRAME_HEADER:
|
||||
+ break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -2360,6 +2367,9 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
|
||||
case V4L2_CTRL_TYPE_H264_DECODE_PARAMS:
|
||||
elem_size = sizeof(struct v4l2_ctrl_h264_decode_params);
|
||||
break;
|
||||
+ case V4L2_CTRL_TYPE_VP8_FRAME_HEADER:
|
||||
+ elem_size = sizeof(struct v4l2_ctrl_vp8_frame_header);
|
||||
+ 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 20cc23ef730e..80efc581e3f9 100644
|
||||
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
|
||||
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
|
||||
@@ -1348,6 +1348,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
|
||||
case V4L2_PIX_FMT_VC1_ANNEX_G: descr = "VC-1 (SMPTE 412M Annex G)"; break;
|
||||
case V4L2_PIX_FMT_VC1_ANNEX_L: descr = "VC-1 (SMPTE 412M Annex L)"; break;
|
||||
case V4L2_PIX_FMT_VP8: descr = "VP8"; break;
|
||||
+ case V4L2_PIX_FMT_VP8_FRAME: descr = "VP8 Frame"; break;
|
||||
case V4L2_PIX_FMT_VP9: descr = "VP9"; break;
|
||||
case V4L2_PIX_FMT_HEVC: descr = "HEVC"; break; /* aka H.265 */
|
||||
case V4L2_PIX_FMT_FWHT: descr = "FWHT"; break; /* used in vicodec */
|
||||
diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
|
||||
index b4433483af23..6e9dc9c44bb1 100644
|
||||
--- a/include/media/v4l2-ctrls.h
|
||||
+++ b/include/media/v4l2-ctrls.h
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <media/mpeg2-ctrls.h>
|
||||
#include <media/fwht-ctrls.h>
|
||||
#include <media/h264-ctrls.h>
|
||||
+#include <media/vp8-ctrls.h>
|
||||
|
||||
/* forward references */
|
||||
struct file;
|
||||
@@ -48,6 +49,7 @@ struct poll_table_struct;
|
||||
* @p_h264_scaling_matrix: Pointer to a struct v4l2_ctrl_h264_scaling_matrix.
|
||||
* @p_h264_slice_params: Pointer to a struct v4l2_ctrl_h264_slice_params.
|
||||
* @p_h264_decode_params: Pointer to a struct v4l2_ctrl_h264_decode_params.
|
||||
+ * @p_vp8_frame_header: Pointer to a VP8 frame header structure.
|
||||
* @p: Pointer to a compound value.
|
||||
*/
|
||||
union v4l2_ctrl_ptr {
|
||||
@@ -65,6 +67,7 @@ union v4l2_ctrl_ptr {
|
||||
struct v4l2_ctrl_h264_scaling_matrix *p_h264_scaling_matrix;
|
||||
struct v4l2_ctrl_h264_slice_params *p_h264_slice_params;
|
||||
struct v4l2_ctrl_h264_decode_params *p_h264_decode_params;
|
||||
+ struct v4l2_ctrl_vp8_frame_header *p_vp8_frame_header;
|
||||
void *p;
|
||||
};
|
||||
|
||||
diff --git a/include/media/vp8-ctrls.h b/include/media/vp8-ctrls.h
|
||||
new file mode 100644
|
||||
index 000000000000..6cc2eeea4c90
|
||||
--- /dev/null
|
||||
+++ b/include/media/vp8-ctrls.h
|
||||
@@ -0,0 +1,110 @@
|
||||
+/* 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_
|
||||
+
|
||||
+#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
|
||||
--
|
||||
2.23.0
|
||||
|
||||
From 298c62d3856111e6ef41c9c00a233aecf2d19651 Mon Sep 17 00:00:00 2001
|
||||
From: Ezequiel Garcia <ezequiel@collabora.com>
|
||||
Date: Thu, 11 Jul 2019 16:26:43 -0400
|
||||
Subject: [PATCH] media: v4l2-ctrl: Validate VP8 stateless decoder controls
|
||||
|
||||
Only one field needs to be validated: 'num_dct_parts'.
|
||||
This field is used to iterate over the user-provided array
|
||||
'dct_part_sizes'.
|
||||
|
||||
Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
|
||||
[hverkuil-cisco@xs4all.nl: s -> (s) in zero_padding macro]
|
||||
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
||||
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
||||
---
|
||||
drivers/media/v4l2-core/v4l2-ctrls.c | 21 +++++++++++++++++++++
|
||||
1 file changed, 21 insertions(+)
|
||||
|
||||
diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
|
||||
index b2c9f5816c4a..13236c191796 100644
|
||||
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
|
||||
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
|
||||
@@ -1633,10 +1633,15 @@ static void std_log(const struct v4l2_ctrl *ctrl)
|
||||
})
|
||||
|
||||
/* Validate a new control */
|
||||
+
|
||||
+#define zero_padding(s) \
|
||||
+ memset(&(s).padding, 0, sizeof((s).padding))
|
||||
+
|
||||
static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx,
|
||||
union v4l2_ctrl_ptr ptr)
|
||||
{
|
||||
struct v4l2_ctrl_mpeg2_slice_params *p_mpeg2_slice_params;
|
||||
+ struct v4l2_ctrl_vp8_frame_header *p_vp8_frame_header;
|
||||
void *p = ptr.p + idx * ctrl->elem_size;
|
||||
|
||||
switch ((u32)ctrl->type) {
|
||||
@@ -1696,6 +1701,22 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx,
|
||||
break;
|
||||
|
||||
case V4L2_CTRL_TYPE_VP8_FRAME_HEADER:
|
||||
+ p_vp8_frame_header = p;
|
||||
+
|
||||
+ switch (p_vp8_frame_header->num_dct_parts) {
|
||||
+ case 1:
|
||||
+ case 2:
|
||||
+ case 4:
|
||||
+ case 8:
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ zero_padding(p_vp8_frame_header->segment_header);
|
||||
+ zero_padding(p_vp8_frame_header->lf_header);
|
||||
+ zero_padding(p_vp8_frame_header->quant_header);
|
||||
+ zero_padding(p_vp8_frame_header->entropy_header);
|
||||
+ zero_padding(p_vp8_frame_header->coder_state);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
--
|
||||
2.23.0
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
1407
projects/Allwinner/patches/linux/0005-cedrus-improvements.patch
Normal file
1407
projects/Allwinner/patches/linux/0005-cedrus-improvements.patch
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,76 +0,0 @@
|
||||
From 443ca53cf78c635aa5bebe9f115721e55fe9ca38 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Sat, 25 May 2019 12:33:05 +0200
|
||||
Subject: [PATCH] media: cedrus: Fix decoding for some H264 videos
|
||||
|
||||
It seems that for some H264 videos at least one bitstream parsing
|
||||
trigger must be called in order to be decoded correctly. There is no
|
||||
explanation why this helps, but it was observed that two sample videos
|
||||
with this fix are now decoded correctly and there is no regression with
|
||||
others.
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
---
|
||||
.../staging/media/sunxi/cedrus/cedrus_h264.c | 22 ++++++++++++++++---
|
||||
1 file changed, 19 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
|
||||
index a30bb283f69f..fab14de1815a 100644
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
|
||||
@@ -6,6 +6,7 @@
|
||||
* Copyright (c) 2018 Bootlin
|
||||
*/
|
||||
|
||||
+#include <linux/delay.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#include <media/videobuf2-dma-contig.h>
|
||||
@@ -289,6 +290,20 @@ static void cedrus_write_pred_weight_table(struct cedrus_ctx *ctx,
|
||||
}
|
||||
}
|
||||
|
||||
+static void cedrus_skip_bits(struct cedrus_dev *dev, int num)
|
||||
+{
|
||||
+ for (; num > 32; num -= 32) {
|
||||
+ cedrus_write(dev, VE_H264_TRIGGER_TYPE, 0x3 | (32 << 8));
|
||||
+ while (cedrus_read(dev, VE_H264_STATUS) & (1 << 8))
|
||||
+ udelay(1);
|
||||
+ }
|
||||
+ if (num > 0) {
|
||||
+ cedrus_write(dev, VE_H264_TRIGGER_TYPE, 0x3 | (num << 8));
|
||||
+ while (cedrus_read(dev, VE_H264_STATUS) & (1 << 8))
|
||||
+ udelay(1);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void cedrus_set_params(struct cedrus_ctx *ctx,
|
||||
struct cedrus_run *run)
|
||||
{
|
||||
@@ -299,12 +314,11 @@ static void cedrus_set_params(struct cedrus_ctx *ctx,
|
||||
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 len = slice->size * 8;
|
||||
u32 reg;
|
||||
|
||||
cedrus_write(dev, VE_H264_VLD_LEN, len);
|
||||
- cedrus_write(dev, VE_H264_VLD_OFFSET, offset);
|
||||
+ cedrus_write(dev, VE_H264_VLD_OFFSET, 0);
|
||||
|
||||
src_buf_addr = vb2_dma_contig_plane_dma_addr(src_buf, 0);
|
||||
cedrus_write(dev, VE_H264_VLD_END,
|
||||
@@ -323,6 +337,8 @@ static void cedrus_set_params(struct cedrus_ctx *ctx,
|
||||
cedrus_write(dev, VE_H264_TRIGGER_TYPE,
|
||||
VE_H264_TRIGGER_TYPE_INIT_SWDEC);
|
||||
|
||||
+ cedrus_skip_bits(dev, slice->header_bit_size);
|
||||
+
|
||||
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)) ||
|
||||
--
|
||||
2.21.0
|
||||
|
@ -1,36 +0,0 @@
|
||||
From fce7f7e700176b402b303d2a62813cc0cdd061e0 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Sat, 25 May 2019 13:18:50 +0200
|
||||
Subject: [PATCH 2/5] media: cedrus: Fix H264 default reference index count
|
||||
|
||||
Reference index count in VE_H264_PPS should come from PPS control.
|
||||
However, this is not really important, because reference index count is
|
||||
in our case always overridden by that from slice header.
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
---
|
||||
drivers/staging/media/sunxi/cedrus/cedrus_h264.c | 8 ++------
|
||||
1 file changed, 2 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
|
||||
index fab14de1815a..d0ee3f90ff46 100644
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
|
||||
@@ -356,12 +356,8 @@ static void cedrus_set_params(struct cedrus_ctx *ctx,
|
||||
|
||||
// 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->num_ref_idx_l0_default_active_minus1 & 0x1f) << 10;
|
||||
+ reg |= (pps->num_ref_idx_l1_default_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;
|
||||
--
|
||||
2.21.0
|
||||
|
@ -1,124 +0,0 @@
|
||||
From 9714cf1bc8c5b48f21af3500e34497621b51a4b1 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Thu, 14 Feb 2019 22:50:12 +0100
|
||||
Subject: [PATCH 3/5] media: cedrus: WIP H264 improvements
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
---
|
||||
.../staging/media/sunxi/cedrus/cedrus_h264.c | 37 ++++++++++++++-----
|
||||
1 file changed, 27 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
|
||||
index d0ee3f90ff46..dcb8d3837869 100644
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
|
||||
@@ -39,7 +39,7 @@ struct cedrus_h264_sram_ref_pic {
|
||||
#define CEDRUS_H264_FRAME_NUM 18
|
||||
|
||||
#define CEDRUS_NEIGHBOR_INFO_BUF_SIZE (16 * SZ_1K)
|
||||
-#define CEDRUS_PIC_INFO_BUF_SIZE (128 * SZ_1K)
|
||||
+#define CEDRUS_PIC_INFO_BUF_SIZE (336 * SZ_1K)
|
||||
|
||||
static void cedrus_h264_write_sram(struct cedrus_dev *dev,
|
||||
enum cedrus_h264_sram_off off,
|
||||
@@ -102,7 +102,7 @@ static void cedrus_write_frame_list(struct cedrus_ctx *ctx,
|
||||
struct cedrus_dev *dev = ctx->dev;
|
||||
unsigned long used_dpbs = 0;
|
||||
unsigned int position;
|
||||
- unsigned int output = 0;
|
||||
+ int output = -1;
|
||||
unsigned int i;
|
||||
|
||||
memset(pic_list, 0, sizeof(pic_list));
|
||||
@@ -123,6 +123,11 @@ static void cedrus_write_frame_list(struct cedrus_ctx *ctx,
|
||||
position = cedrus_buf->codec.h264.position;
|
||||
used_dpbs |= BIT(position);
|
||||
|
||||
+ if (run->dst->vb2_buf.timestamp == dpb->reference_ts) {
|
||||
+ output = position;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE))
|
||||
continue;
|
||||
|
||||
@@ -130,13 +135,11 @@ static void cedrus_write_frame_list(struct cedrus_ctx *ctx,
|
||||
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)
|
||||
+ if (output >= 0)
|
||||
+ position = output;
|
||||
+ else
|
||||
position = find_first_zero_bit(&used_dpbs, CEDRUS_H264_FRAME_NUM);
|
||||
|
||||
output_buf = vb2_to_cedrus_buffer(&run->dst->vb2_buf);
|
||||
@@ -162,6 +165,10 @@ static void cedrus_write_frame_list(struct cedrus_ctx *ctx,
|
||||
|
||||
#define CEDRUS_MAX_REF_IDX 32
|
||||
|
||||
+#define REF_IDX(v) (v & GENMASK(5, 0))
|
||||
+#define REF_FIELD(v) (v >> 6)
|
||||
+#define REF_FIELD_BOTTOM 2
|
||||
+
|
||||
static void _cedrus_write_ref_list(struct cedrus_ctx *ctx,
|
||||
struct cedrus_run *run,
|
||||
const u8 *ref_list, u8 num_ref,
|
||||
@@ -184,7 +191,7 @@ static void _cedrus_write_ref_list(struct cedrus_ctx *ctx,
|
||||
int buf_idx;
|
||||
u8 dpb_idx;
|
||||
|
||||
- dpb_idx = ref_list[i];
|
||||
+ dpb_idx = REF_IDX(ref_list[i]);
|
||||
dpb = &decode->dpb[dpb_idx];
|
||||
|
||||
if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE))
|
||||
@@ -199,7 +206,8 @@ static void _cedrus_write_ref_list(struct cedrus_ctx *ctx,
|
||||
position = cedrus_buf->codec.h264.position;
|
||||
|
||||
sram_array[i] |= position << 1;
|
||||
- if (ref_buf->field == V4L2_FIELD_BOTTOM)
|
||||
+ /* set bottom field flag when reference is to bottom field */
|
||||
+ if (REF_FIELD(ref_list[i]) == REF_FIELD_BOTTOM)
|
||||
sram_array[i] |= BIT(0);
|
||||
}
|
||||
|
||||
@@ -315,6 +323,8 @@ static void cedrus_set_params(struct cedrus_ctx *ctx,
|
||||
struct cedrus_dev *dev = ctx->dev;
|
||||
dma_addr_t src_buf_addr;
|
||||
u32 len = slice->size * 8;
|
||||
+ unsigned int pic_width_in_mbs;
|
||||
+ bool mbaff_picture;
|
||||
u32 reg;
|
||||
|
||||
cedrus_write(dev, VE_H264_VLD_LEN, len);
|
||||
@@ -382,12 +392,19 @@ static void cedrus_set_params(struct cedrus_ctx *ctx,
|
||||
reg |= VE_H264_SPS_DIRECT_8X8_INFERENCE;
|
||||
cedrus_write(dev, VE_H264_SPS, reg);
|
||||
|
||||
+ mbaff_picture = !(slice->flags & V4L2_H264_SLICE_FLAG_FIELD_PIC) &&
|
||||
+ (sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD);
|
||||
+ pic_width_in_mbs = sps->pic_width_in_mbs_minus1 + 1;
|
||||
+
|
||||
// slice parameters
|
||||
reg = 0;
|
||||
+ reg |= ((slice->first_mb_in_slice % pic_width_in_mbs) & 0xff) << 24;
|
||||
+ reg |= (((slice->first_mb_in_slice / pic_width_in_mbs) * (mbaff_picture ? 2 : 1)) & 0xff) << 16;
|
||||
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 (decode->num_slices == 1)
|
||||
+ 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)
|
||||
--
|
||||
2.21.0
|
||||
|
@ -1,781 +0,0 @@
|
||||
From c6582c38df2f78dc9d4f8fd920780a82a01e4d8e Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Sat, 25 May 2019 13:58:17 +0200
|
||||
Subject: [PATCH 2/3] WIP: HEVC improvements
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
---
|
||||
drivers/media/v4l2-core/v4l2-ctrls.c | 8 +
|
||||
drivers/staging/media/sunxi/cedrus/cedrus.c | 6 +
|
||||
drivers/staging/media/sunxi/cedrus/cedrus.h | 11 +-
|
||||
.../staging/media/sunxi/cedrus/cedrus_dec.c | 2 +
|
||||
.../staging/media/sunxi/cedrus/cedrus_h265.c | 348 +++++++++++++-----
|
||||
.../staging/media/sunxi/cedrus/cedrus_regs.h | 3 +
|
||||
.../staging/media/sunxi/cedrus/cedrus_video.c | 12 +-
|
||||
include/media/hevc-ctrls.h | 20 +-
|
||||
8 files changed, 301 insertions(+), 109 deletions(-)
|
||||
|
||||
diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
|
||||
index 1107698b9d06..aed7a4526193 100644
|
||||
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
|
||||
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
|
||||
@@ -947,6 +947,7 @@ const char *v4l2_ctrl_get_name(u32 id)
|
||||
case V4L2_CID_MPEG_VIDEO_HEVC_SPS: return "HEVC Sequence Parameter Set";
|
||||
case V4L2_CID_MPEG_VIDEO_HEVC_PPS: return "HEVC Picture Parameter Set";
|
||||
case V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS: return "HEVC Slice Parameters";
|
||||
+ case V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX: return "HEVC Scaling Matrix";
|
||||
|
||||
/* CAMERA controls */
|
||||
/* Keep the order of the 'case's the same as in v4l2-controls.h! */
|
||||
@@ -1368,6 +1369,9 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
|
||||
case V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS:
|
||||
*type = V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS;
|
||||
break;
|
||||
+ case V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX:
|
||||
+ *type = V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX;
|
||||
+ break;
|
||||
default:
|
||||
*type = V4L2_CTRL_TYPE_INTEGER;
|
||||
break;
|
||||
@@ -1747,6 +1751,7 @@ static int std_validate(const struct v4l2_ctrl *ctrl, u32 idx,
|
||||
case V4L2_CTRL_TYPE_HEVC_SPS:
|
||||
case V4L2_CTRL_TYPE_HEVC_PPS:
|
||||
case V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS:
|
||||
+ case V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX:
|
||||
return 0;
|
||||
|
||||
default:
|
||||
@@ -2356,6 +2361,9 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
|
||||
case V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS:
|
||||
elem_size = sizeof(struct v4l2_ctrl_hevc_slice_params);
|
||||
break;
|
||||
+ case V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX:
|
||||
+ elem_size = sizeof(struct v4l2_ctrl_hevc_scaling_matrix);
|
||||
+ break;
|
||||
default:
|
||||
if (type < V4L2_CTRL_COMPOUND_TYPES)
|
||||
elem_size = sizeof(s32);
|
||||
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c
|
||||
index 70642834f351..01860f247aa6 100644
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus.c
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus.c
|
||||
@@ -88,6 +88,13 @@ static const struct cedrus_control cedrus_controls[] = {
|
||||
.codec = CEDRUS_CODEC_H265,
|
||||
.required = true,
|
||||
},
|
||||
+ {
|
||||
+ .cfg = {
|
||||
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX,
|
||||
+ },
|
||||
+ .codec = CEDRUS_CODEC_H265,
|
||||
+ .required = true,
|
||||
+ },
|
||||
};
|
||||
|
||||
#define CEDRUS_CONTROLS_COUNT ARRAY_SIZE(cedrus_controls)
|
||||
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.h b/drivers/staging/media/sunxi/cedrus/cedrus.h
|
||||
index f19be772d78b..b518c5613fdf 100644
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus.h
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus.h
|
||||
@@ -74,6 +74,7 @@ struct cedrus_h265_run {
|
||||
const struct v4l2_ctrl_hevc_sps *sps;
|
||||
const struct v4l2_ctrl_hevc_pps *pps;
|
||||
const struct v4l2_ctrl_hevc_slice_params *slice_params;
|
||||
+ const struct v4l2_ctrl_hevc_scaling_matrix *scaling_matrix;
|
||||
};
|
||||
|
||||
struct cedrus_run {
|
||||
@@ -90,6 +91,10 @@ struct cedrus_run {
|
||||
struct cedrus_buffer {
|
||||
struct v4l2_m2m_buffer m2m_buf;
|
||||
|
||||
+ void *mv_col_buf;
|
||||
+ dma_addr_t mv_col_buf_dma;
|
||||
+ ssize_t mv_col_buf_size;
|
||||
+
|
||||
union {
|
||||
struct {
|
||||
unsigned int position;
|
||||
@@ -123,12 +128,10 @@ struct cedrus_ctx {
|
||||
dma_addr_t neighbor_info_buf_dma;
|
||||
} h264;
|
||||
struct {
|
||||
- void *mv_col_buf;
|
||||
- dma_addr_t mv_col_buf_addr;
|
||||
- ssize_t mv_col_buf_size;
|
||||
- ssize_t mv_col_buf_unit_size;
|
||||
void *neighbor_info_buf;
|
||||
dma_addr_t neighbor_info_buf_addr;
|
||||
+ void *entry_points_buf;
|
||||
+ dma_addr_t entry_points_buf_addr;
|
||||
} h265;
|
||||
} codec;
|
||||
};
|
||||
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
|
||||
index c6d0ef66cdd0..104adb08492c 100644
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
|
||||
@@ -66,6 +66,8 @@ void cedrus_device_run(void *priv)
|
||||
V4L2_CID_MPEG_VIDEO_HEVC_PPS);
|
||||
run.h265.slice_params = cedrus_find_control_data(ctx,
|
||||
V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS);
|
||||
+ run.h265.scaling_matrix = cedrus_find_control_data(ctx,
|
||||
+ V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX);
|
||||
break;
|
||||
|
||||
default:
|
||||
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
|
||||
index fd4d86b02156..82d29c59b787 100644
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
|
||||
@@ -77,24 +77,32 @@ static void cedrus_h265_sram_write_offset(struct cedrus_dev *dev, u32 offset)
|
||||
cedrus_write(dev, VE_DEC_H265_SRAM_OFFSET, offset);
|
||||
}
|
||||
|
||||
-static void cedrus_h265_sram_write_data(struct cedrus_dev *dev, void *data,
|
||||
+static void cedrus_h265_sram_write_data(struct cedrus_dev *dev, const void *data,
|
||||
unsigned int size)
|
||||
{
|
||||
- u32 *word = data;
|
||||
+ size_t count = DIV_ROUND_UP(size, 4);
|
||||
+ const u32 *word = data;
|
||||
|
||||
- while (size >= sizeof(u32)) {
|
||||
+ while (count--)
|
||||
cedrus_write(dev, VE_DEC_H265_SRAM_DATA, *word++);
|
||||
- size -= sizeof(u32);
|
||||
- }
|
||||
}
|
||||
|
||||
static inline dma_addr_t
|
||||
cedrus_h265_frame_info_mv_col_buf_addr(struct cedrus_ctx *ctx,
|
||||
- unsigned int index, unsigned int field)
|
||||
+ unsigned int index)
|
||||
{
|
||||
- return ctx->codec.h265.mv_col_buf_addr + index *
|
||||
- ctx->codec.h265.mv_col_buf_unit_size +
|
||||
- field * ctx->codec.h265.mv_col_buf_unit_size / 2;
|
||||
+ struct cedrus_buffer *cedrus_buf = NULL;
|
||||
+ struct vb2_buffer *buf = NULL;
|
||||
+ struct vb2_queue *vq;
|
||||
+
|
||||
+ vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
|
||||
+ if (vq)
|
||||
+ buf = vb2_get_buffer(vq, index);
|
||||
+
|
||||
+ if (buf)
|
||||
+ cedrus_buf = vb2_to_cedrus_buffer(buf);
|
||||
+
|
||||
+ return cedrus_buf ? cedrus_buf->mv_col_buf_dma : 0;
|
||||
}
|
||||
|
||||
static void cedrus_h265_frame_info_write_single(struct cedrus_ctx *ctx,
|
||||
@@ -107,9 +108,8 @@ static void cedrus_h265_frame_info_write_single(struct cedrus_ctx *ctx,
|
||||
dma_addr_t dst_luma_addr = cedrus_dst_buf_addr(ctx, buffer_index, 0);
|
||||
dma_addr_t dst_chroma_addr = cedrus_dst_buf_addr(ctx, buffer_index, 1);
|
||||
dma_addr_t mv_col_buf_addr[2] = {
|
||||
- cedrus_h265_frame_info_mv_col_buf_addr(ctx, buffer_index, 0),
|
||||
- cedrus_h265_frame_info_mv_col_buf_addr(ctx, buffer_index,
|
||||
- field_pic ? 1 : 0)
|
||||
+ cedrus_h265_frame_info_mv_col_buf_addr(ctx, buffer_index),
|
||||
+ cedrus_h265_frame_info_mv_col_buf_addr(ctx, buffer_index)
|
||||
};
|
||||
u32 offset = VE_DEC_H265_SRAM_OFFSET_FRAME_INFO +
|
||||
VE_DEC_H265_SRAM_OFFSET_FRAME_INFO_UNIT * index;
|
||||
@@ -158,28 +158,24 @@ static void cedrus_h265_ref_pic_list_write(struct cedrus_dev *dev,
|
||||
u8 num_ref_idx_active,
|
||||
u32 sram_offset)
|
||||
{
|
||||
+ u8 sram_array[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
|
||||
unsigned int i;
|
||||
- u32 word = 0;
|
||||
+
|
||||
+ memset(sram_array, 0, sizeof(sram_array));
|
||||
+ num_ref_idx_active = min(num_ref_idx_active,
|
||||
+ (u8)V4L2_HEVC_DPB_ENTRIES_NUM_MAX);
|
||||
|
||||
cedrus_h265_sram_write_offset(dev, sram_offset);
|
||||
|
||||
for (i = 0; i < num_ref_idx_active; i++) {
|
||||
- unsigned int shift = (i % 4) * 8;
|
||||
unsigned int index = list[i];
|
||||
- u8 value = list[i];
|
||||
|
||||
+ sram_array[i] = index;
|
||||
if (dpb[index].rps == V4L2_HEVC_DPB_ENTRY_RPS_LT_CURR)
|
||||
- value |= VE_DEC_H265_SRAM_REF_PIC_LIST_LT_REF;
|
||||
-
|
||||
- /* Each SRAM word gathers up to 4 references. */
|
||||
- word |= value << shift;
|
||||
-
|
||||
- /* Write the word to SRAM and clear it for the next batch. */
|
||||
- if ((i % 4) == 3 || i == (num_ref_idx_active - 1)) {
|
||||
- cedrus_h265_sram_write_data(dev, &word, sizeof(word));
|
||||
- word = 0;
|
||||
- }
|
||||
+ sram_array[i] |= VE_DEC_H265_SRAM_REF_PIC_LIST_LT_REF;
|
||||
}
|
||||
+
|
||||
+ cedrus_h265_sram_write_data(dev, &sram_array, num_ref_idx_active);
|
||||
}
|
||||
|
||||
static void cedrus_h265_pred_weight_write(struct cedrus_dev *dev,
|
||||
@@ -220,6 +216,131 @@ static void cedrus_h265_pred_weight_write(struct cedrus_dev *dev,
|
||||
}
|
||||
}
|
||||
|
||||
+static void cedrus_h265_write_scaling_list(struct cedrus_ctx *ctx,
|
||||
+ struct cedrus_run *run)
|
||||
+{
|
||||
+ const struct v4l2_ctrl_hevc_scaling_matrix *scaling;
|
||||
+ struct cedrus_dev *dev = ctx->dev;
|
||||
+ u32 i, j, k, val;
|
||||
+
|
||||
+ scaling = run->h265.scaling_matrix;
|
||||
+
|
||||
+ cedrus_write(dev, VE_DEC_H265_SCALING_LIST_DC_COEF0,
|
||||
+ (scaling->scaling_list_dc_coef_32x32[1] << 24) |
|
||||
+ (scaling->scaling_list_dc_coef_32x32[0] << 16) |
|
||||
+ (scaling->scaling_list_dc_coef_16x16[1] << 8) |
|
||||
+ (scaling->scaling_list_dc_coef_16x16[0] << 0));
|
||||
+
|
||||
+ cedrus_write(dev, VE_DEC_H265_SCALING_LIST_DC_COEF1,
|
||||
+ (scaling->scaling_list_dc_coef_16x16[5] << 24) |
|
||||
+ (scaling->scaling_list_dc_coef_16x16[4] << 16) |
|
||||
+ (scaling->scaling_list_dc_coef_16x16[3] << 8) |
|
||||
+ (scaling->scaling_list_dc_coef_16x16[2] << 0));
|
||||
+
|
||||
+ cedrus_h265_sram_write_offset(dev, VE_DEC_H265_SRAM_OFFSET_SCALING_LISTS);
|
||||
+
|
||||
+ for (i = 0; i < 6; i++)
|
||||
+ for (j = 0; j < 8; j++)
|
||||
+ for (k = 0; k < 8; k += 4) {
|
||||
+ val = ((u32)scaling->scaling_list_8x8[i][j + (k + 3) * 8] << 24) |
|
||||
+ ((u32)scaling->scaling_list_8x8[i][j + (k + 2) * 8] << 16) |
|
||||
+ ((u32)scaling->scaling_list_8x8[i][j + (k + 1) * 8] << 8) |
|
||||
+ scaling->scaling_list_8x8[i][j + k * 8];
|
||||
+ cedrus_write(dev, VE_DEC_H265_SRAM_DATA, val);
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < 2; i++)
|
||||
+ for (j = 0; j < 8; j++)
|
||||
+ for (k = 0; k < 8; k += 4) {
|
||||
+ val = ((u32)scaling->scaling_list_32x32[i][j + (k + 3) * 8] << 24) |
|
||||
+ ((u32)scaling->scaling_list_32x32[i][j + (k + 2) * 8] << 16) |
|
||||
+ ((u32)scaling->scaling_list_32x32[i][j + (k + 1) * 8] << 8) |
|
||||
+ scaling->scaling_list_32x32[i][j + k * 8];
|
||||
+ cedrus_write(dev, VE_DEC_H265_SRAM_DATA, val);
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < 6; i++)
|
||||
+ for (j = 0; j < 8; j++)
|
||||
+ for (k = 0; k < 8; k += 4) {
|
||||
+ val = ((u32)scaling->scaling_list_16x16[i][j + (k + 3) * 8] << 24) |
|
||||
+ ((u32)scaling->scaling_list_16x16[i][j + (k + 2) * 8] << 16) |
|
||||
+ ((u32)scaling->scaling_list_16x16[i][j + (k + 1) * 8] << 8) |
|
||||
+ scaling->scaling_list_16x16[i][j + k * 8];
|
||||
+ cedrus_write(dev, VE_DEC_H265_SRAM_DATA, val);
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < 6; i++)
|
||||
+ for (j = 0; j < 4; j++) {
|
||||
+ val = ((u32)scaling->scaling_list_4x4[i][j + 12] << 24) |
|
||||
+ ((u32)scaling->scaling_list_4x4[i][j + 8] << 16) |
|
||||
+ ((u32)scaling->scaling_list_4x4[i][j + 4] << 8) |
|
||||
+ scaling->scaling_list_4x4[i][j];
|
||||
+ cedrus_write(dev, VE_DEC_H265_SRAM_DATA, val);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void write_entry_point_list(struct cedrus_ctx *ctx,
|
||||
+ struct cedrus_run *run)
|
||||
+{
|
||||
+ const struct v4l2_ctrl_hevc_slice_params *slice_params;
|
||||
+ unsigned int ctb_size_luma, width_in_ctb_luma;
|
||||
+ unsigned int log2_max_luma_coding_block_size;
|
||||
+ const struct v4l2_ctrl_hevc_pps *pps;
|
||||
+ const struct v4l2_ctrl_hevc_sps *sps;
|
||||
+ struct cedrus_dev *dev = ctx->dev;
|
||||
+ uint32_t *entry_points;
|
||||
+ int i, x, tx, y, ty;
|
||||
+
|
||||
+ pps = run->h265.pps;
|
||||
+ sps = run->h265.sps;
|
||||
+ slice_params = run->h265.slice_params;
|
||||
+
|
||||
+ log2_max_luma_coding_block_size =
|
||||
+ sps->log2_min_luma_coding_block_size_minus3 + 3 +
|
||||
+ sps->log2_diff_max_min_luma_coding_block_size;
|
||||
+ ctb_size_luma = 1 << log2_max_luma_coding_block_size;
|
||||
+ width_in_ctb_luma = DIV_ROUND_UP(sps->pic_width_in_luma_samples, ctb_size_luma);
|
||||
+
|
||||
+ for (x = 0, tx = 0; tx < pps->num_tile_columns_minus1 + 1; tx++) {
|
||||
+ if (x + pps->column_width_minus1[tx] + 1 > (slice_params->slice_segment_addr % width_in_ctb_luma))
|
||||
+ break;
|
||||
+
|
||||
+ x += pps->column_width_minus1[tx] + 1;
|
||||
+ }
|
||||
+
|
||||
+ for (y = 0, ty = 0; ty < pps->num_tile_rows_minus1 + 1; ty++) {
|
||||
+ if (y + pps->row_height_minus1[ty] + 1 > (slice_params->slice_segment_addr / width_in_ctb_luma))
|
||||
+ break;
|
||||
+
|
||||
+ y += pps->row_height_minus1[ty] + 1;
|
||||
+ }
|
||||
+
|
||||
+ cedrus_write(dev, VE_DEC_H265_TILE_START_CTB, (y << 16) | (x << 0));
|
||||
+ cedrus_write(dev, VE_DEC_H265_TILE_END_CTB,
|
||||
+ ((y + pps->row_height_minus1[ty]) << 16) |
|
||||
+ ((x + pps->column_width_minus1[tx]) << 0));
|
||||
+
|
||||
+ entry_points = ctx->codec.h265.entry_points_buf;
|
||||
+ if (pps->entropy_coding_sync_enabled_flag) {
|
||||
+ for (i = 0; i < slice_params->num_entry_point_offsets; i++)
|
||||
+ entry_points[i] = slice_params->entry_point_offset_minus1[i] + 1;
|
||||
+ } else {
|
||||
+ for (i = 0; i < slice_params->num_entry_point_offsets; i++) {
|
||||
+ if (tx + 1 >= pps->num_tile_columns_minus1 + 1) {
|
||||
+ x = tx = 0;
|
||||
+ y += pps->row_height_minus1[ty++] + 1;
|
||||
+ } else {
|
||||
+ x += pps->column_width_minus1[tx++] + 1;
|
||||
+ }
|
||||
+
|
||||
+ entry_points[i * 4 + 0] = slice_params->entry_point_offset_minus1[i] + 1;
|
||||
+ entry_points[i * 4 + 1] = 0x0;
|
||||
+ entry_points[i * 4 + 2] = (y << 16) | (x << 0);
|
||||
+ entry_points[i * 4 + 3] = ((y + pps->row_height_minus1[ty]) << 16) | ((x + pps->column_width_minus1[tx]) << 0);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void cedrus_h265_setup(struct cedrus_ctx *ctx,
|
||||
struct cedrus_run *run)
|
||||
{
|
||||
@@ -228,6 +349,7 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
|
||||
const struct v4l2_ctrl_hevc_pps *pps;
|
||||
const struct v4l2_ctrl_hevc_slice_params *slice_params;
|
||||
const struct v4l2_hevc_pred_weight_table *pred_weight_table;
|
||||
+ struct cedrus_buffer *cedrus_buf;
|
||||
dma_addr_t src_buf_addr;
|
||||
dma_addr_t src_buf_end_addr;
|
||||
u32 chroma_log2_weight_denom;
|
||||
@@ -240,43 +362,10 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
|
||||
slice_params = run->h265.slice_params;
|
||||
pred_weight_table = &slice_params->pred_weight_table;
|
||||
|
||||
- /* MV column buffer size and allocation. */
|
||||
- if (!ctx->codec.h265.mv_col_buf_size) {
|
||||
- unsigned int num_buffers =
|
||||
- run->dst->vb2_buf.vb2_queue->num_buffers;
|
||||
- unsigned int log2_max_luma_coding_block_size =
|
||||
- sps->log2_min_luma_coding_block_size_minus3 + 3 +
|
||||
- sps->log2_diff_max_min_luma_coding_block_size;
|
||||
- unsigned int ctb_size_luma =
|
||||
- 1 << log2_max_luma_coding_block_size;
|
||||
-
|
||||
- /*
|
||||
- * Each CTB requires a MV col buffer with a specific unit size.
|
||||
- * Since the address is given with missing lsb bits, 1 KiB is
|
||||
- * added to each buffer to ensure proper alignment.
|
||||
- */
|
||||
- ctx->codec.h265.mv_col_buf_unit_size =
|
||||
- DIV_ROUND_UP(ctx->src_fmt.width, ctb_size_luma) *
|
||||
- DIV_ROUND_UP(ctx->src_fmt.height, ctb_size_luma) *
|
||||
- CEDRUS_H265_MV_COL_BUF_UNIT_CTB_SIZE + SZ_1K;
|
||||
-
|
||||
- ctx->codec.h265.mv_col_buf_size = num_buffers *
|
||||
- ctx->codec.h265.mv_col_buf_unit_size;
|
||||
-
|
||||
- ctx->codec.h265.mv_col_buf =
|
||||
- dma_alloc_coherent(dev->dev,
|
||||
- ctx->codec.h265.mv_col_buf_size,
|
||||
- &ctx->codec.h265.mv_col_buf_addr,
|
||||
- GFP_KERNEL);
|
||||
- if (!ctx->codec.h265.mv_col_buf) {
|
||||
- ctx->codec.h265.mv_col_buf_size = 0;
|
||||
- // TODO: Abort the process here.
|
||||
- return;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
/* Activate H265 engine. */
|
||||
cedrus_engine_enable(dev, CEDRUS_CODEC_H265);
|
||||
+ if (sps->pic_width_in_luma_samples > 2048)
|
||||
+ cedrus_write(dev, VE_MODE, cedrus_read(dev, VE_MODE) | BIT(21));
|
||||
|
||||
/* Source offset and length in bits. */
|
||||
|
||||
@@ -300,18 +389,35 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
|
||||
src_buf_end_addr = src_buf_addr +
|
||||
DIV_ROUND_UP(slice_params->bit_size, 8);
|
||||
|
||||
- reg = VE_DEC_H265_BITS_END_ADDR_BASE(src_buf_end_addr);
|
||||
+ reg = VE_DEC_H265_BITS_END_ADDR_BASE(ALIGN(src_buf_end_addr, 1024) - 1);
|
||||
cedrus_write(dev, VE_DEC_H265_BITS_END_ADDR, reg);
|
||||
|
||||
- /* Coding tree block address: start at the beginning. */
|
||||
- reg = VE_DEC_H265_DEC_CTB_ADDR_X(0) | VE_DEC_H265_DEC_CTB_ADDR_Y(0);
|
||||
- cedrus_write(dev, VE_DEC_H265_DEC_CTB_ADDR, reg);
|
||||
-
|
||||
cedrus_write(dev, VE_DEC_H265_TILE_START_CTB, 0);
|
||||
cedrus_write(dev, VE_DEC_H265_TILE_END_CTB, 0);
|
||||
|
||||
+ if (pps->tiles_enabled_flag || pps->entropy_coding_sync_enabled_flag)
|
||||
+ write_entry_point_list(ctx, run);
|
||||
+
|
||||
+ /* Coding tree block address */
|
||||
+ reg = 0;
|
||||
+ if (!slice_params->first_slice_segment_in_pic_flag) {
|
||||
+ unsigned int ctb_size_luma, width_in_ctb_luma;
|
||||
+ unsigned int log2_max_luma_coding_block_size;
|
||||
+
|
||||
+ log2_max_luma_coding_block_size =
|
||||
+ sps->log2_min_luma_coding_block_size_minus3 + 3 +
|
||||
+ sps->log2_diff_max_min_luma_coding_block_size;
|
||||
+ ctb_size_luma = 1 << log2_max_luma_coding_block_size;
|
||||
+ width_in_ctb_luma = DIV_ROUND_UP(sps->pic_width_in_luma_samples, ctb_size_luma);
|
||||
+
|
||||
+ reg = VE_DEC_H265_DEC_CTB_ADDR_X(slice_params->slice_segment_addr % width_in_ctb_luma);
|
||||
+ reg |= VE_DEC_H265_DEC_CTB_ADDR_Y(slice_params->slice_segment_addr / width_in_ctb_luma);
|
||||
+ }
|
||||
+ cedrus_write(dev, VE_DEC_H265_DEC_CTB_ADDR, reg);
|
||||
+
|
||||
/* Clear the number of correctly-decoded coding tree blocks. */
|
||||
- cedrus_write(dev, VE_DEC_H265_DEC_CTB_NUM, 0);
|
||||
+ if (slice_params->first_slice_segment_in_pic_flag)
|
||||
+ cedrus_write(dev, VE_DEC_H265_DEC_CTB_NUM, 0);
|
||||
|
||||
/* Initialize bitstream access. */
|
||||
cedrus_write(dev, VE_DEC_H265_TRIGGER, VE_DEC_H265_TRIGGER_INIT_SWDEC);
|
||||
@@ -334,6 +440,7 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
|
||||
VE_DEC_H265_DEC_SPS_HDR_LOG2_DIFF_MAX_MIN_LUMA_CODING_BLOCK_SIZE(sps->log2_diff_max_min_luma_coding_block_size) |
|
||||
VE_DEC_H265_DEC_SPS_HDR_LOG2_MIN_LUMA_CODING_BLOCK_SIZE_MINUS3(sps->log2_min_luma_coding_block_size_minus3) |
|
||||
VE_DEC_H265_DEC_SPS_HDR_BIT_DEPTH_CHROMA_MINUS8(sps->bit_depth_chroma_minus8) |
|
||||
+ VE_DEC_H265_DEC_SPS_HDR_BIT_DEPTH_LUMA_MINUS8(sps->bit_depth_luma_minus8) |
|
||||
VE_DEC_H265_DEC_SPS_HDR_SEPARATE_COLOUR_PLANE_FLAG(sps->separate_colour_plane_flag) |
|
||||
VE_DEC_H265_DEC_SPS_HDR_CHROMA_FORMAT_IDC(sps->chroma_format_idc);
|
||||
|
||||
@@ -363,7 +470,7 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
|
||||
VE_DEC_H265_DEC_PPS_CTRL1_PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED_FLAG(pps->pps_loop_filter_across_slices_enabled_flag) |
|
||||
VE_DEC_H265_DEC_PPS_CTRL1_LOOP_FILTER_ACROSS_TILES_ENABLED_FLAG(pps->loop_filter_across_tiles_enabled_flag) |
|
||||
VE_DEC_H265_DEC_PPS_CTRL1_ENTROPY_CODING_SYNC_ENABLED_FLAG(pps->entropy_coding_sync_enabled_flag) |
|
||||
- VE_DEC_H265_DEC_PPS_CTRL1_TILES_ENABLED_FLAG(0) |
|
||||
+ VE_DEC_H265_DEC_PPS_CTRL1_TILES_ENABLED_FLAG(pps->tiles_enabled_flag) |
|
||||
VE_DEC_H265_DEC_PPS_CTRL1_TRANSQUANT_BYPASS_ENABLE_FLAG(pps->transquant_bypass_enabled_flag) |
|
||||
VE_DEC_H265_DEC_PPS_CTRL1_WEIGHTED_BIPRED_FLAG(pps->weighted_bipred_flag) |
|
||||
VE_DEC_H265_DEC_PPS_CTRL1_WEIGHTED_PRED_FLAG(pps->weighted_pred_flag);
|
||||
@@ -384,7 +491,7 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
|
||||
VE_DEC_H265_DEC_SLICE_HDR_INFO0_COLOUR_PLANE_ID(slice_params->colour_plane_id) |
|
||||
VE_DEC_H265_DEC_SLICE_HDR_INFO0_SLICE_TYPE(slice_params->slice_type) |
|
||||
VE_DEC_H265_DEC_SLICE_HDR_INFO0_DEPENDENT_SLICE_SEGMENT_FLAG(pps->dependent_slice_segment_flag) |
|
||||
- VE_DEC_H265_DEC_SLICE_HDR_INFO0_FIRST_SLICE_SEGMENT_IN_PIC_FLAG(1);
|
||||
+ VE_DEC_H265_DEC_SLICE_HDR_INFO0_FIRST_SLICE_SEGMENT_IN_PIC_FLAG(slice_params->first_slice_segment_in_pic_flag);
|
||||
|
||||
cedrus_write(dev, VE_DEC_H265_DEC_SLICE_HDR_INFO0, reg);
|
||||
|
||||
@@ -401,34 +508,68 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
|
||||
|
||||
chroma_log2_weight_denom = pred_weight_table->luma_log2_weight_denom +
|
||||
pred_weight_table->delta_chroma_log2_weight_denom;
|
||||
- reg = VE_DEC_H265_DEC_SLICE_HDR_INFO2_NUM_ENTRY_POINT_OFFSETS(0) |
|
||||
+ reg = VE_DEC_H265_DEC_SLICE_HDR_INFO2_NUM_ENTRY_POINT_OFFSETS(slice_params->num_entry_point_offsets) |
|
||||
VE_DEC_H265_DEC_SLICE_HDR_INFO2_CHROMA_LOG2_WEIGHT_DENOM(chroma_log2_weight_denom) |
|
||||
VE_DEC_H265_DEC_SLICE_HDR_INFO2_LUMA_LOG2_WEIGHT_DENOM(pred_weight_table->luma_log2_weight_denom);
|
||||
|
||||
cedrus_write(dev, VE_DEC_H265_DEC_SLICE_HDR_INFO2, reg);
|
||||
|
||||
+ cedrus_write(dev, VE_DEC_H265_ENTRY_POINT_OFFSET_ADDR, ctx->codec.h265.entry_points_buf_addr >> 8);
|
||||
+
|
||||
/* Decoded picture size. */
|
||||
|
||||
- reg = VE_DEC_H265_DEC_PIC_SIZE_WIDTH(ctx->src_fmt.width) |
|
||||
- VE_DEC_H265_DEC_PIC_SIZE_HEIGHT(ctx->src_fmt.height);
|
||||
+ reg = VE_DEC_H265_DEC_PIC_SIZE_WIDTH(sps->pic_width_in_luma_samples) |
|
||||
+ VE_DEC_H265_DEC_PIC_SIZE_HEIGHT(sps->pic_height_in_luma_samples);
|
||||
|
||||
cedrus_write(dev, VE_DEC_H265_DEC_PIC_SIZE, reg);
|
||||
|
||||
- /* Scaling list. */
|
||||
+ /* Scaling list */
|
||||
|
||||
- reg = VE_DEC_H265_SCALING_LIST_CTRL0_DEFAULT;
|
||||
+ if (sps->scaling_list_enabled_flag) {
|
||||
+ cedrus_h265_write_scaling_list(ctx, run);
|
||||
+ reg = VE_DEC_H265_SCALING_LIST_CTRL0_ENABLED_FLAG(1);
|
||||
+ } else {
|
||||
+ reg = VE_DEC_H265_SCALING_LIST_CTRL0_DEFAULT;
|
||||
+ }
|
||||
cedrus_write(dev, VE_DEC_H265_SCALING_LIST_CTRL0, reg);
|
||||
|
||||
/* Neightbor information address. */
|
||||
reg = VE_DEC_H265_NEIGHBOR_INFO_ADDR_BASE(ctx->codec.h265.neighbor_info_buf_addr);
|
||||
cedrus_write(dev, VE_DEC_H265_NEIGHBOR_INFO_ADDR, reg);
|
||||
|
||||
+ cedrus_write(dev, VE_DEC_H265_LOW_ADDR, 0);
|
||||
+
|
||||
/* Write decoded picture buffer in pic list. */
|
||||
cedrus_h265_frame_info_write_dpb(ctx, run->dst->vb2_buf.index, slice_params->dpb,
|
||||
slice_params->num_active_dpb_entries);
|
||||
|
||||
/* Output frame. */
|
||||
|
||||
+ 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;
|
||||
+
|
||||
+ log2_max_luma_coding_block_size =
|
||||
+ sps->log2_min_luma_coding_block_size_minus3 + 3 +
|
||||
+ sps->log2_diff_max_min_luma_coding_block_size;
|
||||
+ ctb_size_luma = 1 << log2_max_luma_coding_block_size;
|
||||
+ width_in_ctb_luma = DIV_ROUND_UP(sps->pic_width_in_luma_samples, ctb_size_luma);
|
||||
+
|
||||
+ cedrus_buf->mv_col_buf_size = ALIGN(width_in_ctb_luma *
|
||||
+ DIV_ROUND_UP(sps->pic_height_in_luma_samples, ctb_size_luma) *
|
||||
+ CEDRUS_H265_MV_COL_BUF_UNIT_CTB_SIZE, 1024);
|
||||
+
|
||||
+ cedrus_buf->mv_col_buf =
|
||||
+ dma_alloc_coherent(dev->dev,
|
||||
+ cedrus_buf->mv_col_buf_size,
|
||||
+ &cedrus_buf->mv_col_buf_dma,
|
||||
+ GFP_KERNEL);
|
||||
+
|
||||
+ if (!cedrus_buf->mv_col_buf)
|
||||
+ cedrus_buf->mv_col_buf_size = 0;
|
||||
+ }
|
||||
+
|
||||
output_pic_list_index = V4L2_HEVC_DPB_ENTRIES_NUM_MAX;
|
||||
pic_order_cnt[0] = slice_params->slice_pic_order_cnt;
|
||||
pic_order_cnt[1] = slice_params->slice_pic_order_cnt;
|
||||
@@ -444,36 +585,36 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
|
||||
if (slice_params->slice_type != V4L2_HEVC_SLICE_TYPE_I) {
|
||||
cedrus_h265_ref_pic_list_write(dev, slice_params->dpb,
|
||||
slice_params->ref_idx_l0,
|
||||
- slice_params->num_ref_idx_l0_active_minus1 + 1,
|
||||
- VE_DEC_H265_SRAM_OFFSET_REF_PIC_LIST0);
|
||||
+ slice_params->num_ref_idx_l0_active_minus1 + 1,
|
||||
+ VE_DEC_H265_SRAM_OFFSET_REF_PIC_LIST0);
|
||||
|
||||
if (pps->weighted_pred_flag || pps->weighted_bipred_flag)
|
||||
cedrus_h265_pred_weight_write(dev,
|
||||
- pred_weight_table->delta_luma_weight_l0,
|
||||
- pred_weight_table->luma_offset_l0,
|
||||
- pred_weight_table->delta_chroma_weight_l0,
|
||||
- pred_weight_table->chroma_offset_l0,
|
||||
- slice_params->num_ref_idx_l0_active_minus1 + 1,
|
||||
- VE_DEC_H265_SRAM_OFFSET_PRED_WEIGHT_LUMA_L0,
|
||||
- VE_DEC_H265_SRAM_OFFSET_PRED_WEIGHT_CHROMA_L0);
|
||||
+ pred_weight_table->delta_luma_weight_l0,
|
||||
+ pred_weight_table->luma_offset_l0,
|
||||
+ pred_weight_table->delta_chroma_weight_l0,
|
||||
+ pred_weight_table->chroma_offset_l0,
|
||||
+ slice_params->num_ref_idx_l0_active_minus1 + 1,
|
||||
+ VE_DEC_H265_SRAM_OFFSET_PRED_WEIGHT_LUMA_L0,
|
||||
+ VE_DEC_H265_SRAM_OFFSET_PRED_WEIGHT_CHROMA_L0);
|
||||
}
|
||||
|
||||
/* Reference picture list 1 (for B frames). */
|
||||
if (slice_params->slice_type == V4L2_HEVC_SLICE_TYPE_B) {
|
||||
cedrus_h265_ref_pic_list_write(dev, slice_params->dpb,
|
||||
slice_params->ref_idx_l1,
|
||||
- slice_params->num_ref_idx_l1_active_minus1 + 1,
|
||||
- VE_DEC_H265_SRAM_OFFSET_REF_PIC_LIST1);
|
||||
+ slice_params->num_ref_idx_l1_active_minus1 + 1,
|
||||
+ VE_DEC_H265_SRAM_OFFSET_REF_PIC_LIST1);
|
||||
|
||||
if (pps->weighted_bipred_flag)
|
||||
cedrus_h265_pred_weight_write(dev,
|
||||
- pred_weight_table->delta_luma_weight_l1,
|
||||
- pred_weight_table->luma_offset_l1,
|
||||
- pred_weight_table->delta_chroma_weight_l1,
|
||||
- pred_weight_table->chroma_offset_l1,
|
||||
- slice_params->num_ref_idx_l1_active_minus1 + 1,
|
||||
- VE_DEC_H265_SRAM_OFFSET_PRED_WEIGHT_LUMA_L1,
|
||||
- VE_DEC_H265_SRAM_OFFSET_PRED_WEIGHT_CHROMA_L1);
|
||||
+ pred_weight_table->delta_luma_weight_l1,
|
||||
+ pred_weight_table->luma_offset_l1,
|
||||
+ pred_weight_table->delta_chroma_weight_l1,
|
||||
+ pred_weight_table->chroma_offset_l1,
|
||||
+ slice_params->num_ref_idx_l1_active_minus1 + 1,
|
||||
+ VE_DEC_H265_SRAM_OFFSET_PRED_WEIGHT_LUMA_L1,
|
||||
+ VE_DEC_H265_SRAM_OFFSET_PRED_WEIGHT_CHROMA_L1);
|
||||
}
|
||||
|
||||
/* Enable appropriate interruptions. */
|
||||
@@ -484,9 +625,6 @@ static int cedrus_h265_start(struct cedrus_ctx *ctx)
|
||||
{
|
||||
struct cedrus_dev *dev = ctx->dev;
|
||||
|
||||
- /* The buffer size is calculated at setup time. */
|
||||
- ctx->codec.h265.mv_col_buf_size = 0;
|
||||
-
|
||||
ctx->codec.h265.neighbor_info_buf =
|
||||
dma_alloc_coherent(dev->dev, CEDRUS_H265_NEIGHBOR_INFO_BUF_SIZE,
|
||||
&ctx->codec.h265.neighbor_info_buf_addr,
|
||||
@@ -494,6 +632,17 @@ static int cedrus_h265_start(struct cedrus_ctx *ctx)
|
||||
if (!ctx->codec.h265.neighbor_info_buf)
|
||||
return -ENOMEM;
|
||||
|
||||
+ ctx->codec.h265.entry_points_buf =
|
||||
+ dma_alloc_coherent(dev->dev, CEDRUS_H265_ENTRY_POINTS_BUF_SIZE,
|
||||
+ &ctx->codec.h265.entry_points_buf_addr,
|
||||
+ GFP_KERNEL);
|
||||
+ if (!ctx->codec.h265.entry_points_buf) {
|
||||
+ dma_free_coherent(dev->dev, CEDRUS_H265_NEIGHBOR_INFO_BUF_SIZE,
|
||||
+ ctx->codec.h265.neighbor_info_buf,
|
||||
+ ctx->codec.h265.neighbor_info_buf_addr);
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -501,17 +650,12 @@ static void cedrus_h265_stop(struct cedrus_ctx *ctx)
|
||||
{
|
||||
struct cedrus_dev *dev = ctx->dev;
|
||||
|
||||
- if (ctx->codec.h265.mv_col_buf_size > 0) {
|
||||
- dma_free_coherent(dev->dev, ctx->codec.h265.mv_col_buf_size,
|
||||
- ctx->codec.h265.mv_col_buf,
|
||||
- ctx->codec.h265.mv_col_buf_addr);
|
||||
-
|
||||
- ctx->codec.h265.mv_col_buf_size = 0;
|
||||
- }
|
||||
-
|
||||
dma_free_coherent(dev->dev, CEDRUS_H265_NEIGHBOR_INFO_BUF_SIZE,
|
||||
ctx->codec.h265.neighbor_info_buf,
|
||||
ctx->codec.h265.neighbor_info_buf_addr);
|
||||
+ dma_free_coherent(dev->dev, CEDRUS_H265_ENTRY_POINTS_BUF_SIZE,
|
||||
+ ctx->codec.h265.entry_points_buf,
|
||||
+ ctx->codec.h265.entry_points_buf_addr);
|
||||
}
|
||||
|
||||
static void cedrus_h265_trigger(struct cedrus_ctx *ctx)
|
||||
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
|
||||
index 87651d6b6227..8d153dbe4f83 100644
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
|
||||
@@ -496,6 +496,9 @@
|
||||
#define VE_DEC_H265_TILE_START_CTB (VE_ENGINE_DEC_H265 + 0x68)
|
||||
#define VE_DEC_H265_TILE_END_CTB (VE_ENGINE_DEC_H265 + 0x6c)
|
||||
|
||||
+#define VE_DEC_H265_SCALING_LIST_DC_COEF0 (VE_ENGINE_DEC_H265 + 0x78)
|
||||
+#define VE_DEC_H265_SCALING_LIST_DC_COEF1 (VE_ENGINE_DEC_H265 + 0x7c)
|
||||
+
|
||||
#define VE_DEC_H265_LOW_ADDR (VE_ENGINE_DEC_H265 + 0x80)
|
||||
|
||||
#define VE_DEC_H265_LOW_ADDR_PRIMARY_CHROMA(a) \
|
||||
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_video.c b/drivers/staging/media/sunxi/cedrus/cedrus_video.c
|
||||
index dbe6f9510641..a0817cae1d69 100644
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus_video.c
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_video.c
|
||||
@@ -433,6 +433,24 @@ static void cedrus_queue_cleanup(struct vb2_queue *vq, u32 state)
|
||||
}
|
||||
}
|
||||
|
||||
+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(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);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
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
|
||||
+++ b/include/media/hevc-ctrls.h
|
||||
@@ -17,11 +17,13 @@
|
||||
#define V4L2_CID_MPEG_VIDEO_HEVC_SPS (V4L2_CID_MPEG_BASE + 1008)
|
||||
#define V4L2_CID_MPEG_VIDEO_HEVC_PPS (V4L2_CID_MPEG_BASE + 1009)
|
||||
#define V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS (V4L2_CID_MPEG_BASE + 1010)
|
||||
+#define V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX (V4L2_CID_MPEG_BASE + 1011)
|
||||
|
||||
/* enum v4l2_ctrl_type type values */
|
||||
#define V4L2_CTRL_TYPE_HEVC_SPS 0x0120
|
||||
#define V4L2_CTRL_TYPE_HEVC_PPS 0x0121
|
||||
#define V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS 0x0122
|
||||
+#define V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX 0x0123
|
||||
|
||||
#define V4L2_HEVC_SLICE_TYPE_B 0
|
||||
#define V4L2_HEVC_SLICE_TYPE_P 1
|
||||
@@ -95,7 +97,7 @@ struct v4l2_ctrl_hevc_pps {
|
||||
__u8 lists_modification_present_flag;
|
||||
__u8 log2_parallel_merge_level_minus2;
|
||||
__u8 slice_segment_header_extension_present_flag;
|
||||
- __u8 padding;
|
||||
+ __u8 scaling_list_enable_flag;
|
||||
};
|
||||
|
||||
#define V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_BEFORE 0x01
|
||||
@@ -179,7 +181,21 @@ struct v4l2_ctrl_hevc_slice_params {
|
||||
/* ISO/IEC 23008-2, ITU-T Rec. H.265: Weighted prediction parameter */
|
||||
struct v4l2_hevc_pred_weight_table pred_weight_table;
|
||||
|
||||
- __u8 padding[2];
|
||||
+ __u32 slice_segment_addr;
|
||||
+ __u32 num_entry_point_offsets;
|
||||
+ __u32 entry_point_offset_minus1[256];
|
||||
+ __u8 first_slice_segment_in_pic_flag;
|
||||
+
|
||||
+ __u8 padding;
|
||||
+};
|
||||
+
|
||||
+struct v4l2_ctrl_hevc_scaling_matrix {
|
||||
+ __u8 scaling_list_4x4[6][16];
|
||||
+ __u8 scaling_list_8x8[6][64];
|
||||
+ __u8 scaling_list_16x16[6][64];
|
||||
+ __u8 scaling_list_32x32[2][64];
|
||||
+ __u8 scaling_list_dc_coef_16x16[6];
|
||||
+ __u8 scaling_list_dc_coef_32x32[2];
|
||||
};
|
||||
|
||||
#endif
|
||||
--
|
||||
2.21.0
|
||||
|
||||
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.h b/drivers/staging/media/sunxi/cedrus/cedrus.h
|
||||
index 2f017a651848..7ca216591c9c 100644
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus.h
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus.h
|
||||
@@ -179,12 +179,16 @@ static inline dma_addr_t cedrus_buf_addr(struct vb2_buffer *buf,
|
||||
static inline dma_addr_t cedrus_dst_buf_addr(struct cedrus_ctx *ctx,
|
||||
int index, unsigned int plane)
|
||||
{
|
||||
- struct vb2_buffer *buf;
|
||||
+ struct vb2_buffer *buf = NULL;
|
||||
+ struct vb2_queue *vq;
|
||||
|
||||
if (index < 0)
|
||||
return 0;
|
||||
|
||||
- buf = ctx->fh.m2m_ctx->cap_q_ctx.q.bufs[index];
|
||||
+ vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
|
||||
+ if (vq)
|
||||
+ buf = vb2_get_buffer(vq, index);
|
||||
+
|
||||
return buf ? cedrus_buf_addr(buf, &ctx->dst_fmt, plane) : 0;
|
||||
}
|
||||
|
@ -1,349 +0,0 @@
|
||||
From 6a900f36a70f921886f05373846368ca6f09446e Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Sat, 25 May 2019 14:16:55 +0200
|
||||
Subject: [PATCH 5/5] cedrus h264 4k
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
---
|
||||
drivers/staging/media/sunxi/cedrus/cedrus.h | 12 +-
|
||||
.../staging/media/sunxi/cedrus/cedrus_h264.c | 117 +++++++++++-------
|
||||
.../staging/media/sunxi/cedrus/cedrus_h265.c | 4 +-
|
||||
.../staging/media/sunxi/cedrus/cedrus_hw.c | 11 +-
|
||||
.../staging/media/sunxi/cedrus/cedrus_hw.h | 3 +-
|
||||
.../staging/media/sunxi/cedrus/cedrus_mpeg2.c | 2 +-
|
||||
.../staging/media/sunxi/cedrus/cedrus_regs.h | 4 +
|
||||
.../staging/media/sunxi/cedrus/cedrus_video.c | 4 +-
|
||||
8 files changed, 98 insertions(+), 59 deletions(-)
|
||||
|
||||
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.h b/drivers/staging/media/sunxi/cedrus/cedrus.h
|
||||
index b518c5613fdf..ee00449d3345 100644
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus.h
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus.h
|
||||
@@ -118,14 +118,18 @@ struct cedrus_ctx {
|
||||
|
||||
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;
|
||||
+
|
||||
+ void *deblk_buf;
|
||||
+ dma_addr_t deblk_buf_dma;
|
||||
+ ssize_t deblk_buf_size;
|
||||
+
|
||||
+ void *intra_pred_buf;
|
||||
+ dma_addr_t intra_pred_buf_dma;
|
||||
+ ssize_t intra_pred_buf_size;
|
||||
} h264;
|
||||
struct {
|
||||
void *neighbor_info_buf;
|
||||
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
|
||||
index dcb8d3837869..4fafaf2c6c0a 100644
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
|
||||
@@ -55,16 +55,14 @@ static void cedrus_h264_write_sram(struct cedrus_dev *dev,
|
||||
}
|
||||
|
||||
static dma_addr_t cedrus_h264_mv_col_buf_addr(struct cedrus_ctx *ctx,
|
||||
- unsigned int position,
|
||||
+ struct cedrus_buffer *buf,
|
||||
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;
|
||||
+ dma_addr_t addr = buf->mv_col_buf_dma;
|
||||
|
||||
/* Adjust for the field */
|
||||
- addr += field * ctx->codec.h264.mv_col_buf_field_size;
|
||||
+ if (field)
|
||||
+ addr += buf->mv_col_buf_size / 2;
|
||||
|
||||
return addr;
|
||||
}
|
||||
@@ -76,7 +74,6 @@ static void cedrus_fill_ref_pic(struct cedrus_ctx *ctx,
|
||||
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 = cpu_to_le32(top_field_order_cnt);
|
||||
pic->bottom_field_order_cnt = cpu_to_le32(bottom_field_order_cnt);
|
||||
@@ -85,9 +82,9 @@ static void cedrus_fill_ref_pic(struct cedrus_ctx *ctx,
|
||||
pic->luma_ptr = cpu_to_le32(cedrus_buf_addr(vbuf, &ctx->dst_fmt, 0));
|
||||
pic->chroma_ptr = cpu_to_le32(cedrus_buf_addr(vbuf, &ctx->dst_fmt, 1));
|
||||
pic->mv_col_top_ptr =
|
||||
- cpu_to_le32(cedrus_h264_mv_col_buf_addr(ctx, position, 0));
|
||||
+ cpu_to_le32(cedrus_h264_mv_col_buf_addr(ctx, buf, 0));
|
||||
pic->mv_col_bot_ptr =
|
||||
- cpu_to_le32(cedrus_h264_mv_col_buf_addr(ctx, position, 1));
|
||||
+ cpu_to_le32(cedrus_h264_mv_col_buf_addr(ctx, buf, 1));
|
||||
}
|
||||
|
||||
static void cedrus_write_frame_list(struct cedrus_ctx *ctx,
|
||||
@@ -145,6 +142,28 @@ static void cedrus_write_frame_list(struct cedrus_ctx *ctx,
|
||||
output_buf = vb2_to_cedrus_buffer(&run->dst->vb2_buf);
|
||||
output_buf->codec.h264.position = position;
|
||||
|
||||
+ if (!output_buf->mv_col_buf_size) {
|
||||
+ const struct v4l2_ctrl_h264_sps *sps = run->h264.sps;
|
||||
+ unsigned int field_size;
|
||||
+
|
||||
+ field_size = DIV_ROUND_UP(ctx->src_fmt.width, 16) *
|
||||
+ DIV_ROUND_UP(ctx->src_fmt.height, 16) * 16;
|
||||
+ if (!(sps->flags & V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE))
|
||||
+ field_size = field_size * 2;
|
||||
+ if (!(sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY))
|
||||
+ field_size = field_size * 2;
|
||||
+
|
||||
+ output_buf->mv_col_buf_size = field_size * 2;
|
||||
+ output_buf->mv_col_buf =
|
||||
+ dma_alloc_coherent(dev->dev,
|
||||
+ output_buf->mv_col_buf_size,
|
||||
+ &output_buf->mv_col_buf_dma,
|
||||
+ GFP_KERNEL);
|
||||
+
|
||||
+ if (!output_buf->mv_col_buf)
|
||||
+ output_buf->mv_col_buf_size = 0;
|
||||
+ }
|
||||
+
|
||||
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)
|
||||
@@ -338,6 +357,14 @@ static void cedrus_set_params(struct cedrus_ctx *ctx,
|
||||
VE_H264_VLD_ADDR_FIRST | VE_H264_VLD_ADDR_VALID |
|
||||
VE_H264_VLD_ADDR_LAST);
|
||||
|
||||
+ if (((sps->pic_width_in_mbs_minus1 + 1) * 16) > 2048) {
|
||||
+ cedrus_write(dev, VE_DBLK_INTRAPRED_BUF_CTRL, 0x5);
|
||||
+ cedrus_write(dev, VE_DBLK_DRAM_BUF_ADDR,
|
||||
+ ctx->codec.h264.deblk_buf_dma);
|
||||
+ cedrus_write(dev, VE_INTRAPRED_DRAM_BUF_ADDR,
|
||||
+ ctx->codec.h264.intra_pred_buf_dma);
|
||||
+ }
|
||||
+
|
||||
/*
|
||||
* FIXME: Since the bitstream parsing is done in software, and
|
||||
* in userspace, this shouldn't be needed anymore. But it
|
||||
@@ -476,7 +503,8 @@ static void cedrus_h264_setup(struct cedrus_ctx *ctx,
|
||||
{
|
||||
struct cedrus_dev *dev = ctx->dev;
|
||||
|
||||
- cedrus_engine_enable(dev, CEDRUS_CODEC_H264);
|
||||
+ cedrus_engine_enable(dev, CEDRUS_CODEC_H264,
|
||||
+ ctx->src_fmt.width);
|
||||
|
||||
cedrus_write(dev, VE_H264_SDROT_CTRL, 0);
|
||||
cedrus_write(dev, VE_H264_EXTRA_BUFFER1,
|
||||
@@ -493,8 +521,6 @@ static void cedrus_h264_setup(struct cedrus_ctx *ctx,
|
||||
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;
|
||||
|
||||
/*
|
||||
@@ -526,44 +552,42 @@ static int cedrus_h264_start(struct cedrus_ctx *ctx)
|
||||
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;
|
||||
+ if (ctx->src_fmt.width > 2048) {
|
||||
+ ctx->codec.h264.deblk_buf_size =
|
||||
+ ALIGN(ctx->src_fmt.width, 32) * 12;
|
||||
+ ctx->codec.h264.deblk_buf =
|
||||
+ dma_alloc_coherent(dev->dev,
|
||||
+ ctx->codec.h264.deblk_buf_size,
|
||||
+ &ctx->codec.h264.deblk_buf_dma,
|
||||
+ GFP_KERNEL);
|
||||
+ if (!ctx->codec.h264.deblk_buf) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto err_neighbor_buf;
|
||||
+ }
|
||||
|
||||
- /*
|
||||
- * 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;
|
||||
+ ctx->codec.h264.intra_pred_buf_size =
|
||||
+ ALIGN(ctx->src_fmt.width, 64) * 5;
|
||||
+ ctx->codec.h264.intra_pred_buf =
|
||||
+ dma_alloc_coherent(dev->dev,
|
||||
+ ctx->codec.h264.intra_pred_buf_size,
|
||||
+ &ctx->codec.h264.intra_pred_buf_dma,
|
||||
+ GFP_KERNEL);
|
||||
+ if (!ctx->codec.h264.intra_pred_buf) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto err_deblk_buf;
|
||||
+ }
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
+err_deblk_buf:
|
||||
+ dma_free_coherent(dev->dev, ctx->codec.h264.deblk_buf_size,
|
||||
+ ctx->codec.h264.deblk_buf,
|
||||
+ ctx->codec.h264.deblk_buf_dma);
|
||||
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,
|
||||
@@ -575,15 +599,20 @@ 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);
|
||||
+ if (ctx->codec.h264.deblk_buf_size)
|
||||
+ dma_free_coherent(dev->dev, ctx->codec.h264.deblk_buf_size,
|
||||
+ ctx->codec.h264.deblk_buf,
|
||||
+ ctx->codec.h264.deblk_buf_dma);
|
||||
+ if (ctx->codec.h264.intra_pred_buf_size)
|
||||
+ dma_free_coherent(dev->dev, ctx->codec.h264.intra_pred_buf_size,
|
||||
+ ctx->codec.h264.intra_pred_buf,
|
||||
+ ctx->codec.h264.intra_pred_buf_dma);
|
||||
}
|
||||
|
||||
static void cedrus_h264_trigger(struct cedrus_ctx *ctx)
|
||||
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
|
||||
index 51ee459b2d21..f915429e9c88 100644
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
|
||||
@@ -337,9 +337,7 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
|
||||
pred_weight_table = &slice_params->pred_weight_table;
|
||||
|
||||
/* Activate H265 engine. */
|
||||
- cedrus_engine_enable(dev, CEDRUS_CODEC_H265);
|
||||
- if (sps->pic_width_in_luma_samples > 2048)
|
||||
- cedrus_write(dev, VE_MODE, cedrus_read(dev, VE_MODE) | BIT(21));
|
||||
+ cedrus_engine_enable(dev, CEDRUS_CODEC_H265, ctx->src_fmt.width);
|
||||
|
||||
/* Source offset and length in bits. */
|
||||
|
||||
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_hw.c b/drivers/staging/media/sunxi/cedrus/cedrus_hw.c
|
||||
index 7d2f6eedfc28..9503d395855b 100644
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus_hw.c
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_hw.c
|
||||
@@ -30,7 +30,8 @@
|
||||
#include "cedrus_hw.h"
|
||||
#include "cedrus_regs.h"
|
||||
|
||||
-int cedrus_engine_enable(struct cedrus_dev *dev, enum cedrus_codec codec)
|
||||
+int cedrus_engine_enable(struct cedrus_dev *dev, enum cedrus_codec codec,
|
||||
+ unsigned int width)
|
||||
{
|
||||
u32 reg = 0;
|
||||
|
||||
@@ -58,6 +59,11 @@ int cedrus_engine_enable(struct cedrus_dev *dev, enum cedrus_codec codec)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
+ if (width >= 4096)
|
||||
+ reg |= BIT(22);
|
||||
+ if (width > 2048)
|
||||
+ reg |= BIT(21);
|
||||
+
|
||||
cedrus_write(dev, VE_MODE, reg);
|
||||
|
||||
return 0;
|
||||
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_hw.h b/drivers/staging/media/sunxi/cedrus/cedrus_hw.h
|
||||
index 27d0882397aa..0e67c69812be 100644
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus_hw.h
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_hw.h
|
||||
@@ -16,7 +16,8 @@
|
||||
#ifndef _CEDRUS_HW_H_
|
||||
#define _CEDRUS_HW_H_
|
||||
|
||||
-int cedrus_engine_enable(struct cedrus_dev *dev, enum cedrus_codec codec);
|
||||
+int cedrus_engine_enable(struct cedrus_dev *dev, enum cedrus_codec codec,
|
||||
+ unsigned int width);
|
||||
void cedrus_engine_disable(struct cedrus_dev *dev);
|
||||
|
||||
void cedrus_dst_format_set(struct cedrus_dev *dev,
|
||||
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c b/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c
|
||||
index 13c34927bad5..fc00a2cbf9bf 100644
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c
|
||||
@@ -96,7 +96,7 @@ static void cedrus_mpeg2_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
|
||||
quantization = run->mpeg2.quantization;
|
||||
|
||||
/* Activate MPEG engine. */
|
||||
- cedrus_engine_enable(dev, CEDRUS_CODEC_MPEG2);
|
||||
+ cedrus_engine_enable(dev, CEDRUS_CODEC_MPEG2, ctx->src_fmt.width);
|
||||
|
||||
/* Set intra quantization matrix. */
|
||||
|
||||
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
|
||||
index a2931f322c7a..df000b7c99be 100644
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
|
||||
@@ -41,6 +41,10 @@
|
||||
#define VE_MODE_DEC_H264 (0x01 << 0)
|
||||
#define VE_MODE_DEC_MPEG (0x00 << 0)
|
||||
|
||||
+#define VE_DBLK_INTRAPRED_BUF_CTRL 0x50
|
||||
+#define VE_DBLK_DRAM_BUF_ADDR 0x54
|
||||
+#define VE_INTRAPRED_DRAM_BUF_ADDR 0x58
|
||||
+
|
||||
#define VE_PRIMARY_CHROMA_BUF_LEN 0xc4
|
||||
#define VE_PRIMARY_FB_LINE_STRIDE 0xc8
|
||||
|
||||
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_video.c b/drivers/staging/media/sunxi/cedrus/cedrus_video.c
|
||||
index a0817cae1d69..d27a9e82ff91 100644
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus_video.c
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_video.c
|
||||
@@ -29,8 +29,8 @@
|
||||
|
||||
#define CEDRUS_MIN_WIDTH 16U
|
||||
#define CEDRUS_MIN_HEIGHT 16U
|
||||
-#define CEDRUS_MAX_WIDTH 3840U
|
||||
-#define CEDRUS_MAX_HEIGHT 2160U
|
||||
+#define CEDRUS_MAX_WIDTH 4096U
|
||||
+#define CEDRUS_MAX_HEIGHT 2768U
|
||||
|
||||
static struct cedrus_format cedrus_formats[] = {
|
||||
{
|
||||
--
|
||||
2.21.0
|
||||
|
Loading…
x
Reference in New Issue
Block a user