From 3b04b84995e74770bfab6f8337406e7eac232d78 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Wed, 18 Sep 2019 17:00:04 +0000 Subject: [PATCH 1/2] ffmpeg: update v4l2 request api patches --- ...001-avutil-add-av_buffer_pool_flush.patch} | 15 +- ...002-Add-common-V4L2-request-API-code.patch | 62 +++- ...3-Add-V4L2-request-API-mpeg2-hwaccel.patch | 9 +- ...04-Add-V4L2-request-API-h264-hwaccel.patch | 126 +++++--- ...05-Add-V4L2-request-API-hevc-hwaccel.patch | 15 +- ...006-Add-V4L2-request-API-vp8-hwaccel.patch | 282 ++++++++++++++++++ ...te-linux-headers-for-V4L2-request-A.patch} | 188 ++++++++++-- ...ontext_drm-do-not-require-drm-device.patch | 26 ++ ...5.0009-avcodec-h264-parse-idr_pic_id.patch | 51 ++++ ...se-ref_pic_marking_size_in_bits-and-.patch | 88 ++++++ ...gs-for-reference-usage-and-field-pic.patch | 56 ++++ 11 files changed, 823 insertions(+), 95 deletions(-) rename packages/multimedia/ffmpeg/patches/v4l2-request-api/{ffmpeg-95.0001-avutil-add-av_buffer_pool_reclaim.patch => ffmpeg-95.0001-avutil-add-av_buffer_pool_flush.patch} (81%) create mode 100644 packages/multimedia/ffmpeg/patches/v4l2-request-api/ffmpeg-95.0006-Add-V4L2-request-API-vp8-hwaccel.patch rename packages/multimedia/ffmpeg/patches/v4l2-request-api/{ffmpeg-95.0006-Add-and-use-private-linux-headers-for-V4L2-request-A.patch => ffmpeg-95.0007-Add-and-use-private-linux-headers-for-V4L2-request-A.patch} (78%) create mode 100644 packages/multimedia/ffmpeg/patches/v4l2-request-api/ffmpeg-95.0008-hwcontext_drm-do-not-require-drm-device.patch create mode 100644 packages/multimedia/ffmpeg/patches/v4l2-request-api/ffmpeg-95.0009-avcodec-h264-parse-idr_pic_id.patch create mode 100644 packages/multimedia/ffmpeg/patches/v4l2-request-api/ffmpeg-95.0010-avcodec-h264-parse-ref_pic_marking_size_in_bits-and-.patch create mode 100644 packages/multimedia/ffmpeg/patches/v4l2-request-api/ffmpeg-95.0011-HACK-add-dpb-flags-for-reference-usage-and-field-pic.patch diff --git a/packages/multimedia/ffmpeg/patches/v4l2-request-api/ffmpeg-95.0001-avutil-add-av_buffer_pool_reclaim.patch b/packages/multimedia/ffmpeg/patches/v4l2-request-api/ffmpeg-95.0001-avutil-add-av_buffer_pool_flush.patch similarity index 81% rename from packages/multimedia/ffmpeg/patches/v4l2-request-api/ffmpeg-95.0001-avutil-add-av_buffer_pool_reclaim.patch rename to packages/multimedia/ffmpeg/patches/v4l2-request-api/ffmpeg-95.0001-avutil-add-av_buffer_pool_flush.patch index c7d8dd8d9b..188ab13706 100644 --- a/packages/multimedia/ffmpeg/patches/v4l2-request-api/ffmpeg-95.0001-avutil-add-av_buffer_pool_reclaim.patch +++ b/packages/multimedia/ffmpeg/patches/v4l2-request-api/ffmpeg-95.0001-avutil-add-av_buffer_pool_flush.patch @@ -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 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 --- @@ -10,14 +10,14 @@ Signed-off-by: Jonas Karlman 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 - diff --git a/packages/multimedia/ffmpeg/patches/v4l2-request-api/ffmpeg-95.0002-Add-common-V4L2-request-API-code.patch b/packages/multimedia/ffmpeg/patches/v4l2-request-api/ffmpeg-95.0002-Add-common-V4L2-request-API-code.patch index d0d66ff5cf..1a9b43e240 100644 --- a/packages/multimedia/ffmpeg/patches/v4l2-request-api/ffmpeg-95.0002-Add-common-V4L2-request-API-code.patch +++ b/packages/multimedia/ffmpeg/patches/v4l2-request-api/ffmpeg-95.0002-Add-common-V4L2-request-API-code.patch @@ -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 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 --- 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 - diff --git a/packages/multimedia/ffmpeg/patches/v4l2-request-api/ffmpeg-95.0003-Add-V4L2-request-API-mpeg2-hwaccel.patch b/packages/multimedia/ffmpeg/patches/v4l2-request-api/ffmpeg-95.0003-Add-V4L2-request-API-mpeg2-hwaccel.patch index 166243192e..fc109896e3 100644 --- a/packages/multimedia/ffmpeg/patches/v4l2-request-api/ffmpeg-95.0003-Add-V4L2-request-API-mpeg2-hwaccel.patch +++ b/packages/multimedia/ffmpeg/patches/v4l2-request-api/ffmpeg-95.0003-Add-V4L2-request-API-mpeg2-hwaccel.patch @@ -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 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 --- @@ -14,7 +14,7 @@ Signed-off-by: Jonas Karlman 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 - diff --git a/packages/multimedia/ffmpeg/patches/v4l2-request-api/ffmpeg-95.0004-Add-V4L2-request-API-h264-hwaccel.patch b/packages/multimedia/ffmpeg/patches/v4l2-request-api/ffmpeg-95.0004-Add-V4L2-request-API-h264-hwaccel.patch index 3d9399156c..917e385a9c 100644 --- a/packages/multimedia/ffmpeg/patches/v4l2-request-api/ffmpeg-95.0004-Add-V4L2-request-API-h264-hwaccel.patch +++ b/packages/multimedia/ffmpeg/patches/v4l2-request-api/ffmpeg-95.0004-Add-V4L2-request-API-h264-hwaccel.patch @@ -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 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 Signed-off-by: Jonas Karlman @@ -11,12 +11,12 @@ Signed-off-by: Jonas Karlman 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 - diff --git a/packages/multimedia/ffmpeg/patches/v4l2-request-api/ffmpeg-95.0005-Add-V4L2-request-API-hevc-hwaccel.patch b/packages/multimedia/ffmpeg/patches/v4l2-request-api/ffmpeg-95.0005-Add-V4L2-request-API-hevc-hwaccel.patch index 68164154dc..17b2063613 100644 --- a/packages/multimedia/ffmpeg/patches/v4l2-request-api/ffmpeg-95.0005-Add-V4L2-request-API-hevc-hwaccel.patch +++ b/packages/multimedia/ffmpeg/patches/v4l2-request-api/ffmpeg-95.0005-Add-V4L2-request-API-hevc-hwaccel.patch @@ -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 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 Signed-off-by: Jonas Karlman @@ -15,7 +15,7 @@ Signed-off-by: Jonas Karlman 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 - diff --git a/packages/multimedia/ffmpeg/patches/v4l2-request-api/ffmpeg-95.0006-Add-V4L2-request-API-vp8-hwaccel.patch b/packages/multimedia/ffmpeg/patches/v4l2-request-api/ffmpeg-95.0006-Add-V4L2-request-API-vp8-hwaccel.patch new file mode 100644 index 0000000000..ffcf5ceeac --- /dev/null +++ b/packages/multimedia/ffmpeg/patches/v4l2-request-api/ffmpeg-95.0006-Add-V4L2-request-API-vp8-hwaccel.patch @@ -0,0 +1,282 @@ +From 2537bdd10973c0fc3f757cab01fd71dd0ef6b1e1 Mon Sep 17 00:00:00 2001 +From: Boris Brezillon +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 +Signed-off-by: Ezequiel Garcia +--- + 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 + }, diff --git a/packages/multimedia/ffmpeg/patches/v4l2-request-api/ffmpeg-95.0006-Add-and-use-private-linux-headers-for-V4L2-request-A.patch b/packages/multimedia/ffmpeg/patches/v4l2-request-api/ffmpeg-95.0007-Add-and-use-private-linux-headers-for-V4L2-request-A.patch similarity index 78% rename from packages/multimedia/ffmpeg/patches/v4l2-request-api/ffmpeg-95.0006-Add-and-use-private-linux-headers-for-V4L2-request-A.patch rename to packages/multimedia/ffmpeg/patches/v4l2-request-api/ffmpeg-95.0007-Add-and-use-private-linux-headers-for-V4L2-request-A.patch index c93892288f..ccd7670c68 100644 --- a/packages/multimedia/ffmpeg/patches/v4l2-request-api/ffmpeg-95.0006-Add-and-use-private-linux-headers-for-V4L2-request-A.patch +++ b/packages/multimedia/ffmpeg/patches/v4l2-request-api/ffmpeg-95.0007-Add-and-use-private-linux-headers-for-V4L2-request-A.patch @@ -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 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 --- - 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 + +/* 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 ++ ++#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 diff --git a/packages/multimedia/ffmpeg/patches/v4l2-request-api/ffmpeg-95.0008-hwcontext_drm-do-not-require-drm-device.patch b/packages/multimedia/ffmpeg/patches/v4l2-request-api/ffmpeg-95.0008-hwcontext_drm-do-not-require-drm-device.patch new file mode 100644 index 0000000000..b8a4cc14ff --- /dev/null +++ b/packages/multimedia/ffmpeg/patches/v4l2-request-api/ffmpeg-95.0008-hwcontext_drm-do-not-require-drm-device.patch @@ -0,0 +1,26 @@ +From 0c4c87e72463da1a4bf45032e4db3c2c86d6d8d8 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 29 Apr 2019 22:08:59 +0000 +Subject: [PATCH] hwcontext_drm: do not require drm device + +Signed-off-by: Jonas Karlman +--- + 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); diff --git a/packages/multimedia/ffmpeg/patches/v4l2-request-api/ffmpeg-95.0009-avcodec-h264-parse-idr_pic_id.patch b/packages/multimedia/ffmpeg/patches/v4l2-request-api/ffmpeg-95.0009-avcodec-h264-parse-idr_pic_id.patch new file mode 100644 index 0000000000..085c87328a --- /dev/null +++ b/packages/multimedia/ffmpeg/patches/v4l2-request-api/ffmpeg-95.0009-avcodec-h264-parse-idr_pic_id.patch @@ -0,0 +1,51 @@ +From 3d50f433609688b6d4ffb2bcec41507f7f507dc2 Mon Sep 17 00:00:00 2001 +From: Ezequiel Garcia +Date: Wed, 20 Feb 2019 11:18:00 -0300 +Subject: [PATCH] avcodec/h264: parse idr_pic_id + +Signed-off-by: Ezequiel Garcia +--- + 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], diff --git a/packages/multimedia/ffmpeg/patches/v4l2-request-api/ffmpeg-95.0010-avcodec-h264-parse-ref_pic_marking_size_in_bits-and-.patch b/packages/multimedia/ffmpeg/patches/v4l2-request-api/ffmpeg-95.0010-avcodec-h264-parse-ref_pic_marking_size_in_bits-and-.patch new file mode 100644 index 0000000000..55103f97cb --- /dev/null +++ b/packages/multimedia/ffmpeg/patches/v4l2-request-api/ffmpeg-95.0010-avcodec-h264-parse-ref_pic_marking_size_in_bits-and-.patch @@ -0,0 +1,88 @@ +From 2f915e957c6bc5887cc24a8762fdadea17359f57 Mon Sep 17 00:00:00 2001 +From: Boris Brezillon +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 +--- + 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, diff --git a/packages/multimedia/ffmpeg/patches/v4l2-request-api/ffmpeg-95.0011-HACK-add-dpb-flags-for-reference-usage-and-field-pic.patch b/packages/multimedia/ffmpeg/patches/v4l2-request-api/ffmpeg-95.0011-HACK-add-dpb-flags-for-reference-usage-and-field-pic.patch new file mode 100644 index 0000000000..5c13116c3c --- /dev/null +++ b/packages/multimedia/ffmpeg/patches/v4l2-request-api/ffmpeg-95.0011-HACK-add-dpb-flags-for-reference-usage-and-field-pic.patch @@ -0,0 +1,56 @@ +From 45df99d31062e068073cf899dce559e334c9127f Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +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 +--- + 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; From 232099ee9fefb239c1da35dab8d0472df1f7abc9 Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Wed, 18 Sep 2019 22:58:37 +0200 Subject: [PATCH 2/2] Allwinner: Update Cedrus patches --- .../linux/0001-backport-from-5.4.patch | 823 ++++++++++++++++++ .../patches/linux/0005-cedrus-hevc.patch | 19 +- .../linux/0010-WIP-HEVC-improvements.patch | 40 +- 3 files changed, 861 insertions(+), 21 deletions(-) diff --git a/projects/Allwinner/patches/linux/0001-backport-from-5.4.patch b/projects/Allwinner/patches/linux/0001-backport-from-5.4.patch index b6f5424261..ee957d068e 100644 --- a/projects/Allwinner/patches/linux/0001-backport-from-5.4.patch +++ b/projects/Allwinner/patches/linux/0001-backport-from-5.4.patch @@ -4862,3 +4862,826 @@ index a6a3f772fdf0..d0a8d5810c0a 100644 -- 2.23.0 +From 633eadc9ba1e9a56be09ef94f14578a9839d3634 Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec +Date: Thu, 30 May 2019 18:15:13 -0300 +Subject: [PATCH] media: cedrus: Remove dst_bufs from context + +This array is just duplicated capture buffer queue. Remove it and adjust +code to look into capture buffer queue instead. + +Signed-off-by: Jernej Skrabec +Acked-by: Maxime Ripard +Acked-by: Paul Kocialkowski +Reviewed-by: Ezequiel Garcia +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +--- + drivers/staging/media/sunxi/cedrus/cedrus.h | 4 +--- + .../staging/media/sunxi/cedrus/cedrus_h264.c | 4 ++-- + .../staging/media/sunxi/cedrus/cedrus_video.c | 22 ------------------- + 3 files changed, 3 insertions(+), 27 deletions(-) + +diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.h b/drivers/staging/media/sunxi/cedrus/cedrus.h +index 3f476d0fd981..d8e6777e5e27 100644 +--- a/drivers/staging/media/sunxi/cedrus/cedrus.h ++++ b/drivers/staging/media/sunxi/cedrus/cedrus.h +@@ -100,8 +100,6 @@ struct cedrus_ctx { + struct v4l2_ctrl_handler hdl; + struct v4l2_ctrl **ctrls; + +- struct vb2_buffer *dst_bufs[VIDEO_MAX_FRAME]; +- + union { + struct { + void *mv_col_buf; +@@ -187,7 +185,7 @@ static inline dma_addr_t cedrus_dst_buf_addr(struct cedrus_ctx *ctx, + if (index < 0) + return 0; + +- buf = ctx->dst_bufs[index]; ++ buf = ctx->fh.m2m_ctx->cap_q_ctx.q.bufs[index]; + return buf ? cedrus_buf_addr(buf, &ctx->dst_fmt, plane) : 0; + } + +diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c +index a30bb283f69f..d6a782703c9b 100644 +--- a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c ++++ b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c +@@ -118,7 +118,7 @@ static void cedrus_write_frame_list(struct cedrus_ctx *ctx, + if (buf_idx < 0) + continue; + +- cedrus_buf = vb2_to_cedrus_buffer(ctx->dst_bufs[buf_idx]); ++ cedrus_buf = vb2_to_cedrus_buffer(cap_q->bufs[buf_idx]); + position = cedrus_buf->codec.h264.position; + used_dpbs |= BIT(position); + +@@ -193,7 +193,7 @@ static void _cedrus_write_ref_list(struct cedrus_ctx *ctx, + if (buf_idx < 0) + continue; + +- ref_buf = to_vb2_v4l2_buffer(ctx->dst_bufs[buf_idx]); ++ ref_buf = to_vb2_v4l2_buffer(cap_q->bufs[buf_idx]); + cedrus_buf = vb2_v4l2_to_cedrus_buffer(ref_buf); + position = cedrus_buf->codec.h264.position; + +diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_video.c b/drivers/staging/media/sunxi/cedrus/cedrus_video.c +index e2b530b1a956..681dfe3367a6 100644 +--- a/drivers/staging/media/sunxi/cedrus/cedrus_video.c ++++ b/drivers/staging/media/sunxi/cedrus/cedrus_video.c +@@ -411,26 +411,6 @@ static void cedrus_queue_cleanup(struct vb2_queue *vq, u32 state) + } + } + +-static int cedrus_buf_init(struct vb2_buffer *vb) +-{ +- struct vb2_queue *vq = vb->vb2_queue; +- struct cedrus_ctx *ctx = vb2_get_drv_priv(vq); +- +- if (!V4L2_TYPE_IS_OUTPUT(vq->type)) +- ctx->dst_bufs[vb->index] = vb; +- +- return 0; +-} +- +-static void cedrus_buf_cleanup(struct vb2_buffer *vb) +-{ +- struct vb2_queue *vq = vb->vb2_queue; +- struct cedrus_ctx *ctx = vb2_get_drv_priv(vq); +- +- if (!V4L2_TYPE_IS_OUTPUT(vq->type)) +- ctx->dst_bufs[vb->index] = NULL; +-} +- + static int cedrus_buf_out_validate(struct vb2_buffer *vb) + { + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); +@@ -517,8 +497,6 @@ static void cedrus_buf_request_complete(struct vb2_buffer *vb) + static struct vb2_ops cedrus_qops = { + .queue_setup = cedrus_queue_setup, + .buf_prepare = cedrus_buf_prepare, +- .buf_init = cedrus_buf_init, +- .buf_cleanup = cedrus_buf_cleanup, + .buf_queue = cedrus_buf_queue, + .buf_out_validate = cedrus_buf_out_validate, + .buf_request_complete = cedrus_buf_request_complete, +-- +2.23.0 + +From 7bb3c32abd7bafd346f667cccb7dfe9686f14ddd Mon Sep 17 00:00:00 2001 +From: Ezequiel Garcia +Date: Fri, 16 Aug 2019 13:01:23 -0300 +Subject: [PATCH] media: uapi: h264: Rename pixel format + +The V4L2_PIX_FMT_H264_SLICE_RAW name was originally suggested +because the pixel format would represent H264 slices without any +start code. + +However, as we will now introduce a start code menu control, +give the pixel format a more meaningful name, while it's +still early enough to do so. + +Signed-off-by: Ezequiel Garcia +Tested-by: Philipp Zabel +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +--- + Documentation/media/uapi/v4l/pixfmt-compressed.rst | 4 ++-- + drivers/media/v4l2-core/v4l2-ioctl.c | 2 +- + drivers/staging/media/sunxi/cedrus/cedrus_dec.c | 2 +- + drivers/staging/media/sunxi/cedrus/cedrus_video.c | 6 +++--- + include/media/h264-ctrls.h | 2 +- + 5 files changed, 8 insertions(+), 8 deletions(-) + +diff --git a/Documentation/media/uapi/v4l/pixfmt-compressed.rst b/Documentation/media/uapi/v4l/pixfmt-compressed.rst +index f52a7b67023d..9b65473a2288 100644 +--- a/Documentation/media/uapi/v4l/pixfmt-compressed.rst ++++ b/Documentation/media/uapi/v4l/pixfmt-compressed.rst +@@ -52,9 +52,9 @@ Compressed Formats + - ``V4L2_PIX_FMT_H264_MVC`` + - 'M264' + - H264 MVC video elementary stream. +- * .. _V4L2-PIX-FMT-H264-SLICE-RAW: ++ * .. _V4L2-PIX-FMT-H264-SLICE: + +- - ``V4L2_PIX_FMT_H264_SLICE_RAW`` ++ - ``V4L2_PIX_FMT_H264_SLICE`` + - 'S264' + - H264 parsed slice data, without the start code and as + extracted from the H264 bitstream. This format is adapted for +diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c +index bb5b4926538a..39f10621c91b 100644 +--- a/drivers/media/v4l2-core/v4l2-ioctl.c ++++ b/drivers/media/v4l2-core/v4l2-ioctl.c +@@ -1343,7 +1343,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) + case V4L2_PIX_FMT_H264: descr = "H.264"; break; + case V4L2_PIX_FMT_H264_NO_SC: descr = "H.264 (No Start Codes)"; break; + case V4L2_PIX_FMT_H264_MVC: descr = "H.264 MVC"; break; +- case V4L2_PIX_FMT_H264_SLICE_RAW: descr = "H.264 Parsed Slice Data"; break; ++ case V4L2_PIX_FMT_H264_SLICE: descr = "H.264 Parsed Slice Data"; break; + case V4L2_PIX_FMT_H263: descr = "H.263"; break; + case V4L2_PIX_FMT_MPEG1: descr = "MPEG-1 ES"; break; + case V4L2_PIX_FMT_MPEG2: descr = "MPEG-2 ES"; break; +diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c +index bdad87eb9d79..56ca4c9ad01c 100644 +--- a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c ++++ b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c +@@ -46,7 +46,7 @@ void cedrus_device_run(void *priv) + V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION); + break; + +- case V4L2_PIX_FMT_H264_SLICE_RAW: ++ case V4L2_PIX_FMT_H264_SLICE: + run.h264.decode_params = cedrus_find_control_data(ctx, + V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS); + run.h264.pps = cedrus_find_control_data(ctx, +diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_video.c b/drivers/staging/media/sunxi/cedrus/cedrus_video.c +index 681dfe3367a6..eeee3efd247b 100644 +--- a/drivers/staging/media/sunxi/cedrus/cedrus_video.c ++++ b/drivers/staging/media/sunxi/cedrus/cedrus_video.c +@@ -38,7 +38,7 @@ static struct cedrus_format cedrus_formats[] = { + .directions = CEDRUS_DECODE_SRC, + }, + { +- .pixelformat = V4L2_PIX_FMT_H264_SLICE_RAW, ++ .pixelformat = V4L2_PIX_FMT_H264_SLICE, + .directions = CEDRUS_DECODE_SRC, + }, + { +@@ -104,7 +104,7 @@ static void cedrus_prepare_format(struct v4l2_pix_format *pix_fmt) + + switch (pix_fmt->pixelformat) { + case V4L2_PIX_FMT_MPEG2_SLICE: +- case V4L2_PIX_FMT_H264_SLICE_RAW: ++ case V4L2_PIX_FMT_H264_SLICE: + /* Zero bytes per line for encoded source. */ + bytesperline = 0; + +@@ -449,7 +449,7 @@ static int cedrus_start_streaming(struct vb2_queue *vq, unsigned int count) + ctx->current_codec = CEDRUS_CODEC_MPEG2; + break; + +- case V4L2_PIX_FMT_H264_SLICE_RAW: ++ case V4L2_PIX_FMT_H264_SLICE: + ctx->current_codec = CEDRUS_CODEC_H264; + break; + +diff --git a/include/media/h264-ctrls.h b/include/media/h264-ctrls.h +index e1404d78d6ff..6160a69c0143 100644 +--- a/include/media/h264-ctrls.h ++++ b/include/media/h264-ctrls.h +@@ -14,7 +14,7 @@ + #include + + /* Our pixel format isn't stable at the moment */ +-#define V4L2_PIX_FMT_H264_SLICE_RAW v4l2_fourcc('S', '2', '6', '4') /* H264 parsed slices */ ++#define V4L2_PIX_FMT_H264_SLICE v4l2_fourcc('S', '2', '6', '4') /* H264 parsed slices */ + + /* + * This is put insanely high to avoid conflicting with controls that +-- +2.23.0 + +From 3f715c64be6e6e1e1bb140fb1179ab0a712f94c3 Mon Sep 17 00:00:00 2001 +From: Ezequiel Garcia +Date: Fri, 16 Aug 2019 13:01:27 -0300 +Subject: [PATCH] media: cedrus: Cleanup control initialization + +In order to introduce other controls, the control initialization +needs to support an initial struct v4l2_ctrl_control. + +While here, let's cleanup the control initialization, +removing unneeded fields. + +Signed-off-by: Ezequiel Garcia +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +--- + drivers/staging/media/sunxi/cedrus/cedrus.c | 45 +++++++++++---------- + drivers/staging/media/sunxi/cedrus/cedrus.h | 3 +- + 2 files changed, 25 insertions(+), 23 deletions(-) + +diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c +index 370937edfc14..7bdc413bf727 100644 +--- a/drivers/staging/media/sunxi/cedrus/cedrus.c ++++ b/drivers/staging/media/sunxi/cedrus/cedrus.c +@@ -29,44 +29,51 @@ + + static const struct cedrus_control cedrus_controls[] = { + { +- .id = V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS, +- .elem_size = sizeof(struct v4l2_ctrl_mpeg2_slice_params), ++ .cfg = { ++ .id = V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS, ++ }, + .codec = CEDRUS_CODEC_MPEG2, + .required = true, + }, + { +- .id = V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION, +- .elem_size = sizeof(struct v4l2_ctrl_mpeg2_quantization), ++ .cfg = { ++ .id = V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION, ++ }, + .codec = CEDRUS_CODEC_MPEG2, + .required = false, + }, + { +- .id = V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS, +- .elem_size = sizeof(struct v4l2_ctrl_h264_decode_params), ++ .cfg = { ++ .id = V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS, ++ }, + .codec = CEDRUS_CODEC_H264, + .required = true, + }, + { +- .id = V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS, +- .elem_size = sizeof(struct v4l2_ctrl_h264_slice_params), ++ .cfg = { ++ .id = V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS, ++ }, + .codec = CEDRUS_CODEC_H264, + .required = true, + }, + { +- .id = V4L2_CID_MPEG_VIDEO_H264_SPS, +- .elem_size = sizeof(struct v4l2_ctrl_h264_sps), ++ .cfg = { ++ .id = V4L2_CID_MPEG_VIDEO_H264_SPS, ++ }, + .codec = CEDRUS_CODEC_H264, + .required = true, + }, + { +- .id = V4L2_CID_MPEG_VIDEO_H264_PPS, +- .elem_size = sizeof(struct v4l2_ctrl_h264_pps), ++ .cfg = { ++ .id = V4L2_CID_MPEG_VIDEO_H264_PPS, ++ }, + .codec = CEDRUS_CODEC_H264, + .required = true, + }, + { +- .id = V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX, +- .elem_size = sizeof(struct v4l2_ctrl_h264_scaling_matrix), ++ .cfg = { ++ .id = V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX, ++ }, + .codec = CEDRUS_CODEC_H264, + .required = true, + }, +@@ -106,12 +113,8 @@ static int cedrus_init_ctrls(struct cedrus_dev *dev, struct cedrus_ctx *ctx) + return -ENOMEM; + + for (i = 0; i < CEDRUS_CONTROLS_COUNT; i++) { +- struct v4l2_ctrl_config cfg = {}; +- +- cfg.elem_size = cedrus_controls[i].elem_size; +- cfg.id = cedrus_controls[i].id; +- +- ctrl = v4l2_ctrl_new_custom(hdl, &cfg, NULL); ++ ctrl = v4l2_ctrl_new_custom(hdl, &cedrus_controls[i].cfg, ++ NULL); + if (hdl->error) { + v4l2_err(&dev->v4l2_dev, + "Failed to create new custom control\n"); +@@ -178,7 +181,7 @@ static int cedrus_request_validate(struct media_request *req) + continue; + + ctrl_test = v4l2_ctrl_request_hdl_ctrl_find(hdl, +- cedrus_controls[i].id); ++ cedrus_controls[i].cfg.id); + if (!ctrl_test) { + v4l2_info(&ctx->dev->v4l2_dev, + "Missing required codec control\n"); +diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.h b/drivers/staging/media/sunxi/cedrus/cedrus.h +index d8e6777e5e27..2f017a651848 100644 +--- a/drivers/staging/media/sunxi/cedrus/cedrus.h ++++ b/drivers/staging/media/sunxi/cedrus/cedrus.h +@@ -49,8 +49,7 @@ enum cedrus_h264_pic_type { + }; + + struct cedrus_control { +- u32 id; +- u32 elem_size; ++ struct v4l2_ctrl_config cfg; + enum cedrus_codec codec; + unsigned char required:1; + }; +-- +2.23.0 + +From 341772b82a3b83e7a7a2c0605c8c728e81b38319 Mon Sep 17 00:00:00 2001 +From: Ezequiel Garcia +Date: Fri, 16 Aug 2019 13:01:28 -0300 +Subject: [PATCH] media: cedrus: Specify H264 startcode and decoding mode + +The cedrus VPU is slice-based and expects V4L2_PIX_FMT_H264_SLICE +buffers to contain H264 slices with no start code. + +Expose this to userspace with the newly added menu control. + +These two controls are specified as mandatory for applications, +but we mark them as non-required on the driver side for +backwards compatibility. + +Signed-off-by: Ezequiel Garcia +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +--- + drivers/staging/media/sunxi/cedrus/cedrus.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c +index 7bdc413bf727..2d3ea8b74dfd 100644 +--- a/drivers/staging/media/sunxi/cedrus/cedrus.c ++++ b/drivers/staging/media/sunxi/cedrus/cedrus.c +@@ -77,6 +77,24 @@ static const struct cedrus_control cedrus_controls[] = { + .codec = CEDRUS_CODEC_H264, + .required = true, + }, ++ { ++ .cfg = { ++ .id = V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE, ++ .max = V4L2_MPEG_VIDEO_H264_DECODE_MODE_SLICE_BASED, ++ .def = V4L2_MPEG_VIDEO_H264_DECODE_MODE_SLICE_BASED, ++ }, ++ .codec = CEDRUS_CODEC_H264, ++ .required = false, ++ }, ++ { ++ .cfg = { ++ .id = V4L2_CID_MPEG_VIDEO_H264_START_CODE, ++ .max = V4L2_MPEG_VIDEO_H264_START_CODE_NONE, ++ .def = V4L2_MPEG_VIDEO_H264_START_CODE_NONE, ++ }, ++ .codec = CEDRUS_CODEC_H264, ++ .required = false, ++ }, + }; + + #define CEDRUS_CONTROLS_COUNT ARRAY_SIZE(cedrus_controls) +-- +2.23.0 + +From 5604be66a56867a784e162299a48c214921ffa1b Mon Sep 17 00:00:00 2001 +From: Boris Brezillon +Date: Fri, 16 Aug 2019 13:01:24 -0300 +Subject: [PATCH] media: uapi: h264: Add the concept of decoding mode + +Some stateless decoders don't support per-slice decoding granularity +(or at least not in a way that would make them efficient or easy to use). + +Expose a menu to control the supported decoding modes. Drivers are +allowed to support only one decoding but they can support both too. + +To fully specify the decoding operation, we need to introduce +a start_byte_offset, to indicate where slices start. + +Signed-off-by: Boris Brezillon +Reviewed-by: Paul Kocialkowski +Tested-by: Philipp Zabel +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +--- + .../media/uapi/v4l/ext-ctrls-codec.rst | 57 ++++++++++++++++++- + .../media/uapi/v4l/pixfmt-compressed.rst | 6 +- + drivers/media/v4l2-core/v4l2-ctrls.c | 9 +++ + include/media/h264-ctrls.h | 10 ++++ + 4 files changed, 79 insertions(+), 3 deletions(-) + +diff --git a/Documentation/media/uapi/v4l/ext-ctrls-codec.rst b/Documentation/media/uapi/v4l/ext-ctrls-codec.rst +index c5f39dd50043..1da17a2c94d7 100644 +--- a/Documentation/media/uapi/v4l/ext-ctrls-codec.rst ++++ b/Documentation/media/uapi/v4l/ext-ctrls-codec.rst +@@ -1747,6 +1747,14 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - + * - __u32 + - ``size`` + - ++ * - __u32 ++ - ``start_byte_offset`` ++ Offset (in bytes) from the beginning of the OUTPUT buffer to the start ++ of the slice. If the slice starts with a start code, then this is the ++ offset to such start code. When operating in slice-based decoding mode ++ (see :c:type:`v4l2_mpeg_video_h264_decode_mode`), this field should ++ be set to 0. When operating in frame-based decoding mode, this field ++ should be 0 for the first slice. + * - __u32 + - ``header_bit_size`` + - +@@ -1930,7 +1938,10 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - + - + * - __u16 + - ``num_slices`` +- - Number of slices needed to decode the current frame ++ - Number of slices needed to decode the current frame/field. When ++ operating in slice-based decoding mode (see ++ :c:type:`v4l2_mpeg_video_h264_decode_mode`), this field ++ should always be set to one. + * - __u16 + - ``nal_ref_idc`` + - NAL reference ID value coming from the NAL Unit header +@@ -2021,6 +2032,50 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - + - 0x00000004 + - The DPB entry is a long term reference frame + ++``V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE (enum)`` ++ Specifies the decoding mode to use. Currently exposes slice-based and ++ frame-based decoding but new modes might be added later on. ++ This control is used as a modifier for V4L2_PIX_FMT_H264_SLICE ++ pixel format. Applications that support V4L2_PIX_FMT_H264_SLICE ++ are required to set this control in order to specify the decoding mode ++ that is expected for the buffer. ++ Drivers may expose a single or multiple decoding modes, depending ++ on what they can support. ++ ++ .. note:: ++ ++ This menu control is not yet part of the public kernel API and ++ it is expected to change. ++ ++.. c:type:: v4l2_mpeg_video_h264_decode_mode ++ ++.. cssclass:: longtable ++ ++.. flat-table:: ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 1 1 2 ++ ++ * - ``V4L2_MPEG_VIDEO_H264_DECODE_MODE_SLICE_BASED`` ++ - 0 ++ - Decoding is done at the slice granularity. ++ In this mode, ``num_slices`` field in struct ++ :c:type:`v4l2_ctrl_h264_decode_params` should be set to 1, ++ and ``start_byte_offset`` in struct ++ :c:type:`v4l2_ctrl_h264_slice_params` should be set to 0. ++ The OUTPUT buffer must contain a single slice. ++ * - ``V4L2_MPEG_VIDEO_H264_DECODE_MODE_FRAME_BASED`` ++ - 1 ++ - Decoding is done at the frame granularity. ++ In this mode, ``num_slices`` field in struct ++ :c:type:`v4l2_ctrl_h264_decode_params` should be set to the number ++ of slices in the frame, and ``start_byte_offset`` in struct ++ :c:type:`v4l2_ctrl_h264_slice_params` should be set accordingly ++ for each slice. For the first slice, ``start_byte_offset`` should ++ be zero. ++ The OUTPUT buffer must contain all slices needed to decode the ++ frame. The OUTPUT buffer must also contain both fields. ++ + .. _v4l2-mpeg-mpeg2: + + ``V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS (struct)`` +diff --git a/Documentation/media/uapi/v4l/pixfmt-compressed.rst b/Documentation/media/uapi/v4l/pixfmt-compressed.rst +index 9b65473a2288..d666eb51741a 100644 +--- a/Documentation/media/uapi/v4l/pixfmt-compressed.rst ++++ b/Documentation/media/uapi/v4l/pixfmt-compressed.rst +@@ -60,8 +60,10 @@ Compressed Formats + extracted from the H264 bitstream. This format is adapted for + stateless video decoders that implement an H264 pipeline + (using the :ref:`mem2mem` and :ref:`media-request-api`). +- Metadata associated with the frame to decode are required to +- be passed through the ``V4L2_CID_MPEG_VIDEO_H264_SPS``, ++ This pixelformat has a modifier that must be set at least once ++ through the ``V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE`` control. ++ In addition, metadata associated with the frame to decode are ++ required to be passed through the ``V4L2_CID_MPEG_VIDEO_H264_SPS``, + ``V4L2_CID_MPEG_VIDEO_H264_PPS``, + ``V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX``, + ``V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS`` and +diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c +index cd1ae016706f..2c67f9fc4d5b 100644 +--- a/drivers/media/v4l2-core/v4l2-ctrls.c ++++ b/drivers/media/v4l2-core/v4l2-ctrls.c +@@ -402,6 +402,11 @@ const char * const *v4l2_ctrl_get_menu(u32 id) + "Explicit", + NULL, + }; ++ static const char * const h264_decode_mode[] = { ++ "Slice-Based", ++ "Frame-Based", ++ NULL, ++ }; + static const char * const mpeg_mpeg2_level[] = { + "Low", + "Main", +@@ -633,6 +638,8 @@ const char * const *v4l2_ctrl_get_menu(u32 id) + return h264_fp_arrangement_type; + case V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE: + return h264_fmo_map_type; ++ case V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE: ++ return h264_decode_mode; + case V4L2_CID_MPEG_VIDEO_MPEG2_LEVEL: + return mpeg_mpeg2_level; + case V4L2_CID_MPEG_VIDEO_MPEG2_PROFILE: +@@ -852,6 +859,7 @@ const char *v4l2_ctrl_get_name(u32 id) + case V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX: return "H264 Scaling Matrix"; + case V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS: return "H264 Slice Parameters"; + case V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS: return "H264 Decode Parameters"; ++ case V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE: return "H264 Decode Mode"; + case V4L2_CID_MPEG_VIDEO_MPEG2_LEVEL: return "MPEG2 Level"; + case V4L2_CID_MPEG_VIDEO_MPEG2_PROFILE: return "MPEG2 Profile"; + case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP: return "MPEG4 I-Frame QP Value"; +@@ -1220,6 +1228,7 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type, + case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC: + case V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE: + case V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE: ++ case V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE: + case V4L2_CID_MPEG_VIDEO_MPEG2_LEVEL: + case V4L2_CID_MPEG_VIDEO_MPEG2_PROFILE: + case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL: +diff --git a/include/media/h264-ctrls.h b/include/media/h264-ctrls.h +index 6160a69c0143..928c48c57282 100644 +--- a/include/media/h264-ctrls.h ++++ b/include/media/h264-ctrls.h +@@ -26,6 +26,7 @@ + #define V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX (V4L2_CID_MPEG_BASE+1002) + #define V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS (V4L2_CID_MPEG_BASE+1003) + #define V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS (V4L2_CID_MPEG_BASE+1004) ++#define V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE (V4L2_CID_MPEG_BASE+1005) + + /* enum v4l2_ctrl_type type values */ + #define V4L2_CTRL_TYPE_H264_SPS 0x0110 +@@ -34,6 +35,11 @@ + #define V4L2_CTRL_TYPE_H264_SLICE_PARAMS 0x0113 + #define V4L2_CTRL_TYPE_H264_DECODE_PARAMS 0x0114 + ++enum v4l2_mpeg_video_h264_decode_mode { ++ V4L2_MPEG_VIDEO_H264_DECODE_MODE_SLICE_BASED, ++ V4L2_MPEG_VIDEO_H264_DECODE_MODE_FRAME_BASED, ++}; ++ + #define V4L2_H264_SPS_CONSTRAINT_SET0_FLAG 0x01 + #define V4L2_H264_SPS_CONSTRAINT_SET1_FLAG 0x02 + #define V4L2_H264_SPS_CONSTRAINT_SET2_FLAG 0x04 +@@ -125,6 +131,10 @@ struct v4l2_h264_pred_weight_table { + struct v4l2_ctrl_h264_slice_params { + /* Size in bytes, including header */ + __u32 size; ++ ++ /* Offset in bytes to the start of slice in the OUTPUT buffer. */ ++ __u32 start_byte_offset; ++ + /* Offset in bits to slice_data() from the beginning of this slice. */ + __u32 header_bit_size; + +-- +2.23.0 + +From 8cae93e090113e46bd29a99c1727d8f13ea12fdf Mon Sep 17 00:00:00 2001 +From: Ezequiel Garcia +Date: Fri, 16 Aug 2019 13:01:25 -0300 +Subject: [PATCH] media: uapi: h264: Add the concept of start code + +Stateless decoders have different expectations about the +start code that is prepended on H264 slices. Add a +menu control to express the supported start code types +(including no start code). + +Drivers are allowed to support only one start code type, +but they can support both too. + +Note that this is independent of the H264 decoding mode, +which specifies the granularity of the decoding operations. +Either in frame-based or slice-based mode, this new control +will allow to define the start code expected on H264 slices. + +Signed-off-by: Ezequiel Garcia +Tested-by: Philipp Zabel +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +--- + .../media/uapi/v4l/ext-ctrls-codec.rst | 33 +++++++++++++++++++ + .../media/uapi/v4l/pixfmt-compressed.rst | 5 +-- + drivers/media/v4l2-core/v4l2-ctrls.c | 9 +++++ + include/media/h264-ctrls.h | 6 ++++ + 4 files changed, 51 insertions(+), 2 deletions(-) + +diff --git a/Documentation/media/uapi/v4l/ext-ctrls-codec.rst b/Documentation/media/uapi/v4l/ext-ctrls-codec.rst +index 1da17a2c94d7..810ae9bb6f7c 100644 +--- a/Documentation/media/uapi/v4l/ext-ctrls-codec.rst ++++ b/Documentation/media/uapi/v4l/ext-ctrls-codec.rst +@@ -2076,6 +2076,39 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - + The OUTPUT buffer must contain all slices needed to decode the + frame. The OUTPUT buffer must also contain both fields. + ++``V4L2_CID_MPEG_VIDEO_H264_START_CODE (enum)`` ++ Specifies the H264 slice start code expected for each slice. ++ This control is used as a modifier for V4L2_PIX_FMT_H264_SLICE ++ pixel format. Applications that support V4L2_PIX_FMT_H264_SLICE ++ are required to set this control in order to specify the start code ++ that is expected for the buffer. ++ Drivers may expose a single or multiple start codes, depending ++ on what they can support. ++ ++ .. note:: ++ ++ This menu control is not yet part of the public kernel API and ++ it is expected to change. ++ ++.. c:type:: v4l2_mpeg_video_h264_start_code ++ ++.. cssclass:: longtable ++ ++.. flat-table:: ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 1 1 2 ++ ++ * - ``V4L2_MPEG_VIDEO_H264_START_CODE_NONE`` ++ - 0 ++ - Selecting this value specifies that H264 slices are passed ++ to the driver without any start code. ++ * - ``V4L2_MPEG_VIDEO_H264_START_CODE_ANNEX_B`` ++ - 1 ++ - Selecting this value specifies that H264 slices are expected ++ to be prefixed by Annex B start codes. According to :ref:`h264` ++ valid start codes can be 3-bytes 0x000001 or 4-bytes 0x00000001. ++ + .. _v4l2-mpeg-mpeg2: + + ``V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS (struct)`` +diff --git a/Documentation/media/uapi/v4l/pixfmt-compressed.rst b/Documentation/media/uapi/v4l/pixfmt-compressed.rst +index d666eb51741a..493b6020107d 100644 +--- a/Documentation/media/uapi/v4l/pixfmt-compressed.rst ++++ b/Documentation/media/uapi/v4l/pixfmt-compressed.rst +@@ -60,8 +60,9 @@ Compressed Formats + extracted from the H264 bitstream. This format is adapted for + stateless video decoders that implement an H264 pipeline + (using the :ref:`mem2mem` and :ref:`media-request-api`). +- This pixelformat has a modifier that must be set at least once +- through the ``V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE`` control. ++ This pixelformat has two modifiers that must be set at least once ++ through the ``V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE`` ++ and ``V4L2_CID_MPEG_VIDEO_H264_START_CODE`` controls. + In addition, metadata associated with the frame to decode are + required to be passed through the ``V4L2_CID_MPEG_VIDEO_H264_SPS``, + ``V4L2_CID_MPEG_VIDEO_H264_PPS``, +diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c +index 2c67f9fc4d5b..1d8f38824631 100644 +--- a/drivers/media/v4l2-core/v4l2-ctrls.c ++++ b/drivers/media/v4l2-core/v4l2-ctrls.c +@@ -407,6 +407,11 @@ const char * const *v4l2_ctrl_get_menu(u32 id) + "Frame-Based", + NULL, + }; ++ static const char * const h264_start_code[] = { ++ "No Start Code", ++ "Annex B Start Code", ++ NULL, ++ }; + static const char * const mpeg_mpeg2_level[] = { + "Low", + "Main", +@@ -640,6 +645,8 @@ const char * const *v4l2_ctrl_get_menu(u32 id) + return h264_fmo_map_type; + case V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE: + return h264_decode_mode; ++ case V4L2_CID_MPEG_VIDEO_H264_START_CODE: ++ return h264_start_code; + case V4L2_CID_MPEG_VIDEO_MPEG2_LEVEL: + return mpeg_mpeg2_level; + case V4L2_CID_MPEG_VIDEO_MPEG2_PROFILE: +@@ -860,6 +867,7 @@ const char *v4l2_ctrl_get_name(u32 id) + case V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS: return "H264 Slice Parameters"; + case V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS: return "H264 Decode Parameters"; + case V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE: return "H264 Decode Mode"; ++ case V4L2_CID_MPEG_VIDEO_H264_START_CODE: return "H264 Start Code"; + case V4L2_CID_MPEG_VIDEO_MPEG2_LEVEL: return "MPEG2 Level"; + case V4L2_CID_MPEG_VIDEO_MPEG2_PROFILE: return "MPEG2 Profile"; + case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP: return "MPEG4 I-Frame QP Value"; +@@ -1229,6 +1237,7 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type, + case V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE: + case V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE: + case V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE: ++ case V4L2_CID_MPEG_VIDEO_H264_START_CODE: + case V4L2_CID_MPEG_VIDEO_MPEG2_LEVEL: + case V4L2_CID_MPEG_VIDEO_MPEG2_PROFILE: + case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL: +diff --git a/include/media/h264-ctrls.h b/include/media/h264-ctrls.h +index 928c48c57282..ba2876a64cf6 100644 +--- a/include/media/h264-ctrls.h ++++ b/include/media/h264-ctrls.h +@@ -27,6 +27,7 @@ + #define V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS (V4L2_CID_MPEG_BASE+1003) + #define V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS (V4L2_CID_MPEG_BASE+1004) + #define V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE (V4L2_CID_MPEG_BASE+1005) ++#define V4L2_CID_MPEG_VIDEO_H264_START_CODE (V4L2_CID_MPEG_BASE+1006) + + /* enum v4l2_ctrl_type type values */ + #define V4L2_CTRL_TYPE_H264_SPS 0x0110 +@@ -40,6 +41,11 @@ enum v4l2_mpeg_video_h264_decode_mode { + V4L2_MPEG_VIDEO_H264_DECODE_MODE_FRAME_BASED, + }; + ++enum v4l2_mpeg_video_h264_start_code { ++ V4L2_MPEG_VIDEO_H264_START_CODE_NONE, ++ V4L2_MPEG_VIDEO_H264_START_CODE_ANNEX_B, ++}; ++ + #define V4L2_H264_SPS_CONSTRAINT_SET0_FLAG 0x01 + #define V4L2_H264_SPS_CONSTRAINT_SET1_FLAG 0x02 + #define V4L2_H264_SPS_CONSTRAINT_SET2_FLAG 0x04 +-- +2.23.0 + +From c3adb85745ca6cc19532b2ee197d7abece1ac732 Mon Sep 17 00:00:00 2001 +From: Boris Brezillon +Date: Fri, 16 Aug 2019 13:01:26 -0300 +Subject: [PATCH] media: uapi: h264: Get rid of the p0/b0/b1 ref-lists + +Those lists can be extracted from the dpb, let's simplify userspace +life and build that list kernel-side (generic helpers will be provided +for drivers that need this list). + +Signed-off-by: Boris Brezillon +Reviewed-by: Nicolas Dufresne +Reviewed-by: Ezequiel Garcia +Reviewed-by: Paul Kocialkowski +Tested-by: Philipp Zabel +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +--- + Documentation/media/uapi/v4l/ext-ctrls-codec.rst | 9 --------- + include/media/h264-ctrls.h | 3 --- + 2 files changed, 12 deletions(-) + +diff --git a/Documentation/media/uapi/v4l/ext-ctrls-codec.rst b/Documentation/media/uapi/v4l/ext-ctrls-codec.rst +index 810ae9bb6f7c..bc5dd8e76567 100644 +--- a/Documentation/media/uapi/v4l/ext-ctrls-codec.rst ++++ b/Documentation/media/uapi/v4l/ext-ctrls-codec.rst +@@ -1945,15 +1945,6 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - + * - __u16 + - ``nal_ref_idc`` + - NAL reference ID value coming from the NAL Unit header +- * - __u8 +- - ``ref_pic_list_p0[32]`` +- - Backward reference list used by P-frames in the original bitstream order +- * - __u8 +- - ``ref_pic_list_b0[32]`` +- - Backward reference list used by B-frames in the original bitstream order +- * - __u8 +- - ``ref_pic_list_b1[32]`` +- - Forward reference list used by B-frames in the original bitstream order + * - __s32 + - ``top_field_order_cnt`` + - Picture Order Count for the coded top field +diff --git a/include/media/h264-ctrls.h b/include/media/h264-ctrls.h +index ba2876a64cf6..e877bf1d537c 100644 +--- a/include/media/h264-ctrls.h ++++ b/include/media/h264-ctrls.h +@@ -202,9 +202,6 @@ struct v4l2_ctrl_h264_decode_params { + struct v4l2_h264_dpb_entry dpb[16]; + __u16 num_slices; + __u16 nal_ref_idc; +- __u8 ref_pic_list_p0[32]; +- __u8 ref_pic_list_b0[32]; +- __u8 ref_pic_list_b1[32]; + __s32 top_field_order_cnt; + __s32 bottom_field_order_cnt; + __u32 flags; /* V4L2_H264_DECODE_PARAM_FLAG_* */ +-- +2.23.0 + diff --git a/projects/Allwinner/patches/linux/0005-cedrus-hevc.patch b/projects/Allwinner/patches/linux/0005-cedrus-hevc.patch index a5184d98a5..73a89c6287 100644 --- a/projects/Allwinner/patches/linux/0005-cedrus-hevc.patch +++ b/projects/Allwinner/patches/linux/0005-cedrus-hevc.patch @@ -964,25 +964,28 @@ diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media index 370937edfc14..70642834f351 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus.c -@@ -70,6 +70,24 @@ static const struct cedrus_control cedrus_controls[] = { +@@ -70,6 +70,27 @@ static const struct cedrus_control cedrus_controls[] = { .codec = CEDRUS_CODEC_H264, .required = true, }, + { -+ .id = V4L2_CID_MPEG_VIDEO_HEVC_SPS, -+ .elem_size = sizeof(struct v4l2_ctrl_hevc_sps), ++ .cfg = { ++ .id = V4L2_CID_MPEG_VIDEO_HEVC_SPS, ++ }, + .codec = CEDRUS_CODEC_H265, + .required = true, + }, + { -+ .id = V4L2_CID_MPEG_VIDEO_HEVC_PPS, -+ .elem_size = sizeof(struct v4l2_ctrl_hevc_pps), ++ .cfg = { ++ .id = V4L2_CID_MPEG_VIDEO_HEVC_PPS, ++ }, + .codec = CEDRUS_CODEC_H265, + .required = true, + }, + { -+ .id = V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS, -+ .elem_size = sizeof(struct v4l2_ctrl_hevc_slice_params), ++ .cfg = { ++ .id = V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS, ++ }, + .codec = CEDRUS_CODEC_H265, + .required = true, + }, @@ -1995,7 +1998,7 @@ index e2b530b1a956..6cc65d85cf98 100644 @@ -105,6 +110,7 @@ static void cedrus_prepare_format(struct v4l2_pix_format *pix_fmt) switch (pix_fmt->pixelformat) { case V4L2_PIX_FMT_MPEG2_SLICE: - case V4L2_PIX_FMT_H264_SLICE_RAW: + case V4L2_PIX_FMT_H264_SLICE: + case V4L2_PIX_FMT_HEVC_SLICE: /* Zero bytes per line for encoded source. */ bytesperline = 0; diff --git a/projects/Allwinner/patches/linux/0010-WIP-HEVC-improvements.patch b/projects/Allwinner/patches/linux/0010-WIP-HEVC-improvements.patch index 96c0a6da59..d8e13a8918 100644 --- a/projects/Allwinner/patches/linux/0010-WIP-HEVC-improvements.patch +++ b/projects/Allwinner/patches/linux/0010-WIP-HEVC-improvements.patch @@ -59,13 +59,14 @@ diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media index 70642834f351..01860f247aa6 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus.c -@@ -88,6 +88,12 @@ static const struct cedrus_control cedrus_controls[] = { +@@ -88,6 +88,13 @@ static const struct cedrus_control cedrus_controls[] = { .codec = CEDRUS_CODEC_H265, .required = true, }, + { -+ .id = V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX, -+ .elem_size = sizeof(struct v4l2_ctrl_hevc_scaling_matrix), ++ .cfg = { ++ .id = V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX, ++ }, + .codec = CEDRUS_CODEC_H265, + .required = true, + }, @@ -156,7 +157,7 @@ index fd4d86b02156..82d29c59b787 100644 - field * ctx->codec.h265.mv_col_buf_unit_size / 2; + struct cedrus_buffer *cedrus_buf; + -+ cedrus_buf = vb2_to_cedrus_buffer(ctx->dst_bufs[index]); ++ cedrus_buf = vb2_to_cedrus_buffer(ctx->fh.m2m_ctx->cap_q_ctx.q.bufs[index]); + + return cedrus_buf->mv_col_buf_dma; } @@ -512,7 +513,7 @@ index fd4d86b02156..82d29c59b787 100644 /* Output frame. */ -+ cedrus_buf = vb2_to_cedrus_buffer(ctx->dst_bufs[run->dst->vb2_buf.index]); ++ cedrus_buf = vb2_to_cedrus_buffer(ctx->fh.m2m_ctx->cap_q_ctx.q.bufs[run->dst->vb2_buf.index]); + if (!cedrus_buf->mv_col_buf_size) { + unsigned int ctb_size_luma, width_in_ctb_luma; + unsigned int log2_max_luma_coding_block_size; @@ -662,26 +663,39 @@ diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_video.c b/drivers/staging index dbe6f9510641..a0817cae1d69 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus_video.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus_video.c -@@ -433,8 +433,18 @@ static void cedrus_buf_cleanup(struct vb2_buffer *vb) - struct vb2_queue *vq = vb->vb2_queue; - struct cedrus_ctx *ctx = vb2_get_drv_priv(vq); +@@ -433,6 +433,24 @@ static void cedrus_queue_cleanup(struct vb2_queue *vq, u32 state) + } + } -- if (!V4L2_TYPE_IS_OUTPUT(vq->type)) ++static void cedrus_buf_cleanup(struct vb2_buffer *vb) ++{ ++ struct vb2_queue *vq = vb->vb2_queue; ++ struct cedrus_ctx *ctx = vb2_get_drv_priv(vq); ++ + if (!V4L2_TYPE_IS_OUTPUT(vq->type)) { + struct cedrus_buffer *cedrus_buf; + -+ cedrus_buf = vb2_to_cedrus_buffer(ctx->dst_bufs[vb->index]); ++ cedrus_buf = vb2_to_cedrus_buffer(vq->bufs[vb->index]); + + if (cedrus_buf->mv_col_buf_size) + dma_free_coherent(ctx->dev->dev, + cedrus_buf->mv_col_buf_size, + cedrus_buf->mv_col_buf, + cedrus_buf->mv_col_buf_dma); - ctx->dst_bufs[vb->index] = NULL; + } - } - ++} ++ static int cedrus_buf_out_validate(struct vb2_buffer *vb) + { + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); +@@ -517,6 +497,7 @@ static void cedrus_buf_request_complete(struct vb2_buffer *vb) + static struct vb2_ops cedrus_qops = { + .queue_setup = cedrus_queue_setup, + .buf_prepare = cedrus_buf_prepare, ++ .buf_cleanup = cedrus_buf_cleanup, + .buf_queue = cedrus_buf_queue, + .buf_out_validate = cedrus_buf_out_validate, + .buf_request_complete = cedrus_buf_request_complete, diff --git a/include/media/hevc-ctrls.h b/include/media/hevc-ctrls.h index 2de83d9f6d47..19469097c6d4 100644 --- a/include/media/hevc-ctrls.h