ffmpeg: update v4l2 request api patches

This commit is contained in:
Jonas Karlman 2019-09-18 17:00:04 +00:00 committed by Jernej Skrabec
parent a0e265e3fa
commit 3b04b84995
11 changed files with 823 additions and 95 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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