diff --git a/packages/multimedia/ffmpeg/patches/v4l2-request/ffmpeg-001-v4l2-request.patch b/packages/multimedia/ffmpeg/patches/v4l2-request/ffmpeg-001-v4l2-request.patch index 18c6e2bbd3..1976ec823b 100644 --- a/packages/multimedia/ffmpeg/patches/v4l2-request/ffmpeg-001-v4l2-request.patch +++ b/packages/multimedia/ffmpeg/patches/v4l2-request/ffmpeg-001-v4l2-request.patch @@ -1,7 +1,7 @@ From 904af26693095364851bbc6c6557fca9b3437b69 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Mon, 3 Dec 2018 23:48:04 +0100 -Subject: [PATCH 01/18] avutil: add av_buffer_pool_flush() +Subject: [PATCH 01/16] avutil: add av_buffer_pool_flush() Used by V4L2 request API hwaccel @@ -12,7 +12,7 @@ Signed-off-by: Jonas Karlman 2 files changed, 18 insertions(+) diff --git a/libavutil/buffer.c b/libavutil/buffer.c -index 858633e8c7..41555d9982 100644 +index 858633e8c73b..41555d998257 100644 --- a/libavutil/buffer.c +++ b/libavutil/buffer.c @@ -305,6 +305,19 @@ static void buffer_pool_free(AVBufferPool *pool) @@ -36,7 +36,7 @@ index 858633e8c7..41555d9982 100644 { AVBufferPool *pool; diff --git a/libavutil/buffer.h b/libavutil/buffer.h -index 241a80ed67..f41363faf1 100644 +index 241a80ed6709..f41363faf1dc 100644 --- a/libavutil/buffer.h +++ b/libavutil/buffer.h @@ -315,6 +315,11 @@ AVBufferPool *av_buffer_pool_init2(size_t size, void *opaque, @@ -55,7 +55,7 @@ index 241a80ed67..f41363faf1 100644 From ec84dc22e99f544e4de7c43e7f8ef9ab7ee8e19b Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Sat, 15 Dec 2018 22:32:16 +0100 -Subject: [PATCH 02/18] Add common V4L2 request API code +Subject: [PATCH 02/16] Add common V4L2 request API code Signed-off-by: Jonas Karlman --- @@ -69,7 +69,7 @@ Signed-off-by: Jonas Karlman create mode 100644 libavcodec/v4l2_request.h diff --git a/configure b/configure -index d7a3f507e8..f2e203d134 100755 +index d7a3f507e834..f2e203d13463 100755 --- a/configure +++ b/configure @@ -279,6 +279,7 @@ External library support: @@ -141,7 +141,7 @@ index d7a3f507e8..f2e203d134 100755 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 33a280cf69..90dfffcb20 100644 +index 33a280cf6953..90dfffcb2004 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -155,6 +155,7 @@ OBJS-$(CONFIG_VP3DSP) += vp3dsp.o @@ -153,7 +153,7 @@ index 33a280cf69..90dfffcb20 100644 OBJS-$(CONFIG_WMV2DSP) += wmv2dsp.o diff --git a/libavcodec/hwconfig.h b/libavcodec/hwconfig.h -index f421dc909f..ee78d8ab8e 100644 +index f421dc909f44..ee78d8ab8e89 100644 --- a/libavcodec/hwconfig.h +++ b/libavcodec/hwconfig.h @@ -80,6 +80,8 @@ typedef struct AVCodecHWConfigInternal { @@ -167,7 +167,7 @@ index f421dc909f..ee78d8ab8e 100644 &(const AVCodecHWConfigInternal) { \ diff --git a/libavcodec/v4l2_request.c b/libavcodec/v4l2_request.c new file mode 100644 -index 0000000000..5234b5049b +index 000000000000..5234b5049b0d --- /dev/null +++ b/libavcodec/v4l2_request.c @@ -0,0 +1,984 @@ @@ -1157,7 +1157,7 @@ index 0000000000..5234b5049b +} diff --git a/libavcodec/v4l2_request.h b/libavcodec/v4l2_request.h new file mode 100644 -index 0000000000..58d2aa70af +index 000000000000..58d2aa70af80 --- /dev/null +++ b/libavcodec/v4l2_request.h @@ -0,0 +1,77 @@ @@ -1242,7 +1242,7 @@ index 0000000000..58d2aa70af From e432d3151f4c5507e40fb1fe8b3c3fb7c7a0a08c Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Wed, 20 Feb 2019 11:18:00 -0300 -Subject: [PATCH 03/18] h264dec: add idr_pic_id to slice context +Subject: [PATCH 03/16] h264dec: add idr_pic_id to slice context Used by V4L2 request API h264 hwaccel @@ -1254,7 +1254,7 @@ Signed-off-by: Jonas Karlman 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c -index 2d0605c7f4..c3a7338a70 100644 +index 2d0605c7f4f6..c3a7338a7043 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -1830,7 +1830,7 @@ static int h264_slice_header_parse(const H264Context *h, H264SliceContext *sl, @@ -1267,7 +1267,7 @@ index 2d0605c7f4..c3a7338a70 100644 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 b7b19ba4f1..0698ab95ba 100644 +index b7b19ba4f162..0698ab95ba51 100644 --- a/libavcodec/h264dec.h +++ b/libavcodec/h264dec.h @@ -336,6 +336,7 @@ typedef struct H264SliceContext { @@ -1282,7 +1282,7 @@ index b7b19ba4f1..0698ab95ba 100644 From 84564d13ec0ec40f408622ff6b0d900723bbab5b Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Wed, 22 May 2019 14:44:22 +0200 -Subject: [PATCH 04/18] h264dec: add ref_pic_marking and pic_order_cnt bit_size +Subject: [PATCH 04/16] h264dec: add ref_pic_marking and pic_order_cnt bit_size to slice context Used by V4L2 request API h264 hwaccel @@ -1295,7 +1295,7 @@ Signed-off-by: Jonas Karlman 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c -index c3a7338a70..c28b58cd5d 100644 +index c3a7338a7043..c28b58cd5d95 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -1748,7 +1748,7 @@ static int h264_slice_header_parse(const H264Context *h, H264SliceContext *sl, @@ -1336,7 +1336,7 @@ index c3a7338a70..c28b58cd5d 100644 if (sl->slice_type_nos != AV_PICTURE_TYPE_I && pps->cabac) { diff --git a/libavcodec/h264dec.h b/libavcodec/h264dec.h -index 0698ab95ba..2b39e82c3b 100644 +index 0698ab95ba51..2b39e82c3b03 100644 --- a/libavcodec/h264dec.h +++ b/libavcodec/h264dec.h @@ -329,6 +329,7 @@ typedef struct H264SliceContext { @@ -1359,7 +1359,7 @@ index 0698ab95ba..2b39e82c3b 100644 From 5a8628cf6368fe18457d02bf551d5935609efab5 Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Sat, 15 Dec 2018 22:32:16 +0100 -Subject: [PATCH 05/18] Add V4L2 request API h264 hwaccel +Subject: [PATCH 05/16] Add V4L2 request API h264 hwaccel Signed-off-by: Jernej Skrabec Signed-off-by: Jonas Karlman @@ -1374,7 +1374,7 @@ Signed-off-by: Jonas Karlman create mode 100644 libavcodec/v4l2_request_h264.c diff --git a/configure b/configure -index f2e203d134..b17e4108c1 100755 +index f2e203d13463..b17e4108c1b6 100755 --- a/configure +++ b/configure @@ -2951,6 +2951,8 @@ h264_dxva2_hwaccel_deps="dxva2" @@ -1395,7 +1395,7 @@ index f2e203d134..b17e4108c1 100755 check_headers 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 90dfffcb20..426c7528e9 100644 +index 90dfffcb2004..426c7528e904 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -935,6 +935,7 @@ OBJS-$(CONFIG_H264_D3D11VA_HWACCEL) += dxva2_h264.o @@ -1407,7 +1407,7 @@ index 90dfffcb20..426c7528e9 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 c28b58cd5d..0a10d00aad 100644 +index c28b58cd5d95..0a10d00aad9e 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -768,6 +768,7 @@ static enum AVPixelFormat get_pixel_format(H264Context *h, int force_callback) @@ -1429,7 +1429,7 @@ index c28b58cd5d..0a10d00aad 100644 if (h->avctx->codec->pix_fmts) choices = h->avctx->codec->pix_fmts; diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c -index 0a999bef43..d78e3eaee3 100644 +index 0a999bef43d9..d78e3eaee3a8 100644 --- a/libavcodec/h264dec.c +++ b/libavcodec/h264dec.c @@ -1076,6 +1076,9 @@ AVCodec ff_h264_decoder = { @@ -1443,7 +1443,7 @@ index 0a999bef43..d78e3eaee3 100644 NULL }, diff --git a/libavcodec/hwaccels.h b/libavcodec/hwaccels.h -index 8e54cf73f9..969a1da0f4 100644 +index 8e54cf73f90f..969a1da0f4bc 100644 --- a/libavcodec/hwaccels.h +++ b/libavcodec/hwaccels.h @@ -32,6 +32,7 @@ extern const AVHWAccel ff_h264_d3d11va_hwaccel; @@ -1456,7 +1456,7 @@ index 8e54cf73f9..969a1da0f4 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..88da8f0a2d +index 000000000000..88da8f0a2db0 --- /dev/null +++ b/libavcodec/v4l2_request_h264.c @@ -0,0 +1,456 @@ @@ -1920,7 +1920,7 @@ index 0000000000..88da8f0a2d From 02b8fb17c2a019463dcab4baa1cb0bec63353183 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Sat, 15 Dec 2018 22:32:16 +0100 -Subject: [PATCH 06/18] Add V4L2 request API mpeg2 hwaccel +Subject: [PATCH 06/16] Add V4L2 request API mpeg2 hwaccel Signed-off-by: Jonas Karlman --- @@ -1933,7 +1933,7 @@ Signed-off-by: Jonas Karlman create mode 100644 libavcodec/v4l2_request_mpeg2.c diff --git a/configure b/configure -index b17e4108c1..ec141fabbd 100755 +index b17e4108c1b6..ec141fabbdc1 100755 --- a/configure +++ b/configure @@ -2995,6 +2995,8 @@ mpeg2_dxva2_hwaccel_deps="dxva2" @@ -1954,7 +1954,7 @@ index b17e4108c1..ec141fabbd 100755 check_headers 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 426c7528e9..02c023a447 100644 +index 426c7528e904..02c023a44772 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -955,6 +955,7 @@ OBJS-$(CONFIG_MPEG2_D3D11VA_HWACCEL) += dxva2_mpeg2.o @@ -1966,7 +1966,7 @@ index 426c7528e9..02c023a447 100644 OBJS-$(CONFIG_MPEG2_VDPAU_HWACCEL) += vdpau_mpeg12.o OBJS-$(CONFIG_MPEG2_VIDEOTOOLBOX_HWACCEL) += videotoolbox.o diff --git a/libavcodec/hwaccels.h b/libavcodec/hwaccels.h -index 969a1da0f4..a8ae1483d8 100644 +index 969a1da0f4bc..a8ae1483d8e1 100644 --- a/libavcodec/hwaccels.h +++ b/libavcodec/hwaccels.h @@ -53,6 +53,7 @@ extern const AVHWAccel ff_mpeg2_d3d11va_hwaccel; @@ -1978,7 +1978,7 @@ index 969a1da0f4..a8ae1483d8 100644 extern const AVHWAccel ff_mpeg2_vdpau_hwaccel; extern const AVHWAccel ff_mpeg2_videotoolbox_hwaccel; diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c -index 94221da2c1..4b0176f6cb 100644 +index 94221da2c158..4b0176f6cb19 100644 --- a/libavcodec/mpeg12dec.c +++ b/libavcodec/mpeg12dec.c @@ -1147,6 +1147,9 @@ static const enum AVPixelFormat mpeg2_hwaccel_pixfmt_list_420[] = { @@ -2003,7 +2003,7 @@ index 94221da2c1..4b0176f6cb 100644 }, diff --git a/libavcodec/v4l2_request_mpeg2.c b/libavcodec/v4l2_request_mpeg2.c new file mode 100644 -index 0000000000..84d53209c7 +index 000000000000..84d53209c79d --- /dev/null +++ b/libavcodec/v4l2_request_mpeg2.c @@ -0,0 +1,159 @@ @@ -2170,7 +2170,7 @@ index 0000000000..84d53209c7 From 1cd61e5730acc12c39c964bcf13c73a54203a390 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Wed, 22 May 2019 14:46:58 +0200 -Subject: [PATCH 07/18] Add V4L2 request API vp8 hwaccel +Subject: [PATCH 07/16] Add V4L2 request API vp8 hwaccel Signed-off-by: Boris Brezillon Signed-off-by: Ezequiel Garcia @@ -2185,7 +2185,7 @@ Signed-off-by: Jonas Karlman create mode 100644 libavcodec/v4l2_request_vp8.c diff --git a/configure b/configure -index ec141fabbd..f16bed65a3 100755 +index ec141fabbdc1..f16bed65a3a3 100755 --- a/configure +++ b/configure @@ -3027,6 +3027,8 @@ vc1_vdpau_hwaccel_deps="vdpau" @@ -2206,7 +2206,7 @@ index ec141fabbd..f16bed65a3 100755 check_headers 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 02c023a447..c79d678eb3 100644 +index 02c023a44772..c79d678eb3ee 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -971,6 +971,7 @@ OBJS-$(CONFIG_VC1_QSV_HWACCEL) += qsvdec.o @@ -2218,7 +2218,7 @@ index 02c023a447..c79d678eb3 100644 OBJS-$(CONFIG_VP9_D3D11VA_HWACCEL) += dxva2_vp9.o OBJS-$(CONFIG_VP9_DXVA2_HWACCEL) += dxva2_vp9.o diff --git a/libavcodec/hwaccels.h b/libavcodec/hwaccels.h -index a8ae1483d8..9f8d41e367 100644 +index a8ae1483d8e1..9f8d41e367ed 100644 --- a/libavcodec/hwaccels.h +++ b/libavcodec/hwaccels.h @@ -69,6 +69,7 @@ extern const AVHWAccel ff_vc1_nvdec_hwaccel; @@ -2231,7 +2231,7 @@ index a8ae1483d8..9f8d41e367 100644 extern const AVHWAccel ff_vp9_d3d11va2_hwaccel; diff --git a/libavcodec/v4l2_request_vp8.c b/libavcodec/v4l2_request_vp8.c new file mode 100644 -index 0000000000..bc0fc40072 +index 000000000000..bc0fc400727a --- /dev/null +++ b/libavcodec/v4l2_request_vp8.c @@ -0,0 +1,180 @@ @@ -2416,7 +2416,7 @@ index 0000000000..bc0fc40072 + .caps_internal = HWACCEL_CAP_ASYNC_SAFE, +}; diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c -index d16e7b6aa3..8ee768d875 100644 +index d16e7b6aa34e..8ee768d875ad 100644 --- a/libavcodec/vp8.c +++ b/libavcodec/vp8.c @@ -176,6 +176,9 @@ static enum AVPixelFormat get_pixel_format(VP8Context *s) @@ -2440,10 +2440,10 @@ index d16e7b6aa3..8ee768d875 100644 NULL }, -From 0065c180f7345bef065e5704ddb9827dc18b2f4b Mon Sep 17 00:00:00 2001 +From 3c09465f9dee3355b0ef68140b86e9e66797b5fc Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Sat, 15 Dec 2018 22:32:16 +0100 -Subject: [PATCH 08/18] Add V4L2 request API hevc hwaccel +Subject: [PATCH 08/16] Add V4L2 request API hevc hwaccel Signed-off-by: Jernej Skrabec Signed-off-by: Jonas Karlman @@ -2452,12 +2452,12 @@ Signed-off-by: Jonas Karlman libavcodec/Makefile | 1 + libavcodec/hevcdec.c | 10 + libavcodec/hwaccels.h | 1 + - libavcodec/v4l2_request_hevc.c | 574 +++++++++++++++++++++++++++++++++ - 5 files changed, 589 insertions(+) + libavcodec/v4l2_request_hevc.c | 604 +++++++++++++++++++++++++++++++++ + 5 files changed, 619 insertions(+) create mode 100644 libavcodec/v4l2_request_hevc.c diff --git a/configure b/configure -index f16bed65a3..02a80cf27f 100755 +index f16bed65a3a3..02a80cf27fd7 100755 --- a/configure +++ b/configure @@ -2967,6 +2967,8 @@ hevc_dxva2_hwaccel_deps="dxva2 DXVA_PicParams_HEVC" @@ -2478,7 +2478,7 @@ index f16bed65a3..02a80cf27f 100755 check_cc vp8_v4l2_request linux/videodev2.h "int i = V4L2_PIX_FMT_VP8_FRAME;" diff --git a/libavcodec/Makefile b/libavcodec/Makefile -index c79d678eb3..0059074530 100644 +index c79d678eb3ee..0059074530c5 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -943,6 +943,7 @@ OBJS-$(CONFIG_HEVC_D3D11VA_HWACCEL) += dxva2_hevc.o @@ -2490,7 +2490,7 @@ index c79d678eb3..0059074530 100644 OBJS-$(CONFIG_HEVC_VDPAU_HWACCEL) += vdpau_hevc.o h265_profile_level.o OBJS-$(CONFIG_MJPEG_NVDEC_HWACCEL) += nvdec_mjpeg.o diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c -index 2231aed259..7507966d71 100644 +index 2231aed2599b..7507966d7160 100644 --- a/libavcodec/hevcdec.c +++ b/libavcodec/hevcdec.c @@ -392,6 +392,7 @@ static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps) @@ -2532,7 +2532,7 @@ index 2231aed259..7507966d71 100644 NULL }, diff --git a/libavcodec/hwaccels.h b/libavcodec/hwaccels.h -index 9f8d41e367..ffb9fa5087 100644 +index 9f8d41e367ed..ffb9fa5087d9 100644 --- a/libavcodec/hwaccels.h +++ b/libavcodec/hwaccels.h @@ -40,6 +40,7 @@ extern const AVHWAccel ff_hevc_d3d11va_hwaccel; @@ -2545,10 +2545,10 @@ index 9f8d41e367..ffb9fa5087 100644 extern const AVHWAccel ff_hevc_videotoolbox_hwaccel; diff --git a/libavcodec/v4l2_request_hevc.c b/libavcodec/v4l2_request_hevc.c new file mode 100644 -index 0000000000..d385c2f036 +index 000000000000..3a9d564ce20b --- /dev/null +++ b/libavcodec/v4l2_request_hevc.c -@@ -0,0 +1,574 @@ +@@ -0,0 +1,604 @@ +/* + * This file is part of FFmpeg. + * @@ -2577,6 +2577,7 @@ index 0000000000..d385c2f036 + struct v4l2_ctrl_hevc_sps sps; + struct v4l2_ctrl_hevc_pps pps; + struct v4l2_ctrl_hevc_decode_params dec_params; ++ struct v4l2_ctrl_hevc_scaling_matrix scaling_matrix; + struct v4l2_ctrl_hevc_slice_params slice_params[MAX_SLICES]; + int first_slice; + int num_slices; //TODO: this should be in control @@ -2737,6 +2738,9 @@ index 0000000000..d385c2f036 + .bit_size = 0, + .data_bit_offset = get_bits_count(&h->HEVClc->gb), + ++ /* ISO/IEC 23008-2, ITU-T Rec. H.265: General slice segment header */ ++ .slice_segment_addr = sh->slice_segment_addr, ++ + /* ISO/IEC 23008-2, ITU-T Rec. H.265: NAL unit header */ + .nal_unit_type = h->nal_unit_type, + .nuh_temporal_id_plus1 = h->temporal_id + 1, @@ -2868,11 +2872,32 @@ index 0000000000..d385c2f036 +{ + const HEVCContext *h = avctx->priv_data; + const HEVCPPS *pps = h->ps.pps; ++ const HEVCSPS *sps = h->ps.sps; ++ const ScalingList *sl = pps->scaling_list_data_present_flag ? ++ &pps->scaling_list : ++ sps->scaling_list_enable_flag ? ++ &sps->scaling_list : NULL; + V4L2RequestControlsHEVC *controls = h->ref->hwaccel_picture_private; + + fill_sps(&controls->sps, h); + fill_dec_params(&controls->dec_params, h); + ++ if (sl) { ++ for (int i = 0; i < 6; i++) { ++ for (int j = 0; j < 16; j++) ++ controls->scaling_matrix.scaling_list_4x4[i][j] = sl->sl[0][i][j]; ++ for (int j = 0; j < 64; j++) { ++ controls->scaling_matrix.scaling_list_8x8[i][j] = sl->sl[1][i][j]; ++ controls->scaling_matrix.scaling_list_16x16[i][j] = sl->sl[2][i][j]; ++ if (i < 2) ++ controls->scaling_matrix.scaling_list_32x32[i][j] = sl->sl[3][i * 3][j]; ++ } ++ controls->scaling_matrix.scaling_list_dc_coef_16x16[i] = sl->sl_dc[0][i]; ++ if (i < 2) ++ controls->scaling_matrix.scaling_list_dc_coef_32x32[i] = sl->sl_dc[1][i * 3]; ++ } ++ } ++ + /* ISO/IEC 23008-2, ITU-T Rec. H.265: Picture parameter set */ + controls->pps = (struct v4l2_ctrl_hevc_pps) { + .num_extra_slice_header_bits = pps->num_extra_slice_header_bits, @@ -2990,6 +3015,11 @@ index 0000000000..d385c2f036 + .size = sizeof(controls->dec_params), + }, + { ++ .id = V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX, ++ .ptr = &controls->scaling_matrix, ++ .size = sizeof(controls->scaling_matrix), ++ }, ++ { + .id = V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS, + .ptr = &controls->slice_params, + .size = sizeof(controls->slice_params[0]) * FFMAX(FFMIN(controls->num_slices, MAX_SLICES), ctx->max_slices), @@ -3124,23 +3154,751 @@ index 0000000000..d385c2f036 + .caps_internal = HWACCEL_CAP_ASYNC_SAFE, +}; -From 5877cc36995d4cdf012bcee11a36e9f4543d35fe Mon Sep 17 00:00:00 2001 +From 140874637c7d3d99b69e6b30f0ad32b07d4e43e8 Mon Sep 17 00:00:00 2001 +From: Boris Brezillon +Date: Thu, 12 Dec 2019 16:13:55 +0100 +Subject: [PATCH 09/16] Add V4L2 request API VP9 hwaccel + +Signed-off-by: Boris Brezillon +Signed-off-by: Jernej Skrabec +--- + configure | 3 + + libavcodec/Makefile | 1 + + libavcodec/hwaccels.h | 1 + + libavcodec/v4l2_request_vp9.c | 268 ++++++++++++++++++++++++++++++++++ + libavcodec/vp9.c | 192 +++++++++++++++++------- + libavcodec/vp9dec.h | 4 + + libavcodec/vp9shared.h | 1 + + 7 files changed, 415 insertions(+), 55 deletions(-) + create mode 100644 libavcodec/v4l2_request_vp9.c + +diff --git a/configure b/configure +index 02a80cf27fd7..0b238c051dff 100755 +--- a/configure ++++ b/configure +@@ -3041,6 +3041,8 @@ vp9_dxva2_hwaccel_deps="dxva2 DXVA_PicParams_VP9" + vp9_dxva2_hwaccel_select="vp9_decoder" + vp9_nvdec_hwaccel_deps="nvdec" + vp9_nvdec_hwaccel_select="vp9_decoder" ++vp9_v4l2request_hwaccel_deps="v4l2_request" ++vp9_v4l2request_hwaccel_select="vp9_decoder" + vp9_vaapi_hwaccel_deps="vaapi VADecPictureParameterBufferVP9_bit_depth" + vp9_vaapi_hwaccel_select="vp9_decoder" + vp9_vdpau_hwaccel_deps="vdpau VdpPictureInfoVP9" +@@ -6640,6 +6642,7 @@ 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_cc vp9_v4l2_request linux/videodev2.h "int i = V4L2_PIX_FMT_VP9_FRAME;" + + check_headers 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 0059074530c5..38edf1cfe5e5 100644 +--- a/libavcodec/Makefile ++++ b/libavcodec/Makefile +@@ -977,6 +977,7 @@ OBJS-$(CONFIG_VP8_VAAPI_HWACCEL) += vaapi_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 ++OBJS-$(CONFIG_VP9_V4L2REQUEST_HWACCEL) += v4l2_request_vp9.o + OBJS-$(CONFIG_VP9_VAAPI_HWACCEL) += vaapi_vp9.o + OBJS-$(CONFIG_VP9_VDPAU_HWACCEL) += vdpau_vp9.o + OBJS-$(CONFIG_VP8_QSV_HWACCEL) += qsvdec.o +diff --git a/libavcodec/hwaccels.h b/libavcodec/hwaccels.h +index ffb9fa5087d9..fc5d0b0479be 100644 +--- a/libavcodec/hwaccels.h ++++ b/libavcodec/hwaccels.h +@@ -76,6 +76,7 @@ extern const AVHWAccel ff_vp9_d3d11va_hwaccel; + extern const AVHWAccel ff_vp9_d3d11va2_hwaccel; + extern const AVHWAccel ff_vp9_dxva2_hwaccel; + extern const AVHWAccel ff_vp9_nvdec_hwaccel; ++extern const AVHWAccel ff_vp9_v4l2request_hwaccel; + extern const AVHWAccel ff_vp9_vaapi_hwaccel; + extern const AVHWAccel ff_vp9_vdpau_hwaccel; + extern const AVHWAccel ff_wmv3_d3d11va_hwaccel; +diff --git a/libavcodec/v4l2_request_vp9.c b/libavcodec/v4l2_request_vp9.c +new file mode 100644 +index 000000000000..9b95c76cdb82 +--- /dev/null ++++ b/libavcodec/v4l2_request_vp9.c +@@ -0,0 +1,268 @@ ++/* ++ * 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 "hwconfig.h" ++#include "v4l2_request.h" ++#include "vp9dec.h" ++ ++typedef struct V4L2RequestControlsVP9 { ++ struct v4l2_ctrl_vp9_frame decode_params; ++} V4L2RequestControlsVP9; ++ ++static int v4l2_request_vp9_set_frame_ctx(AVCodecContext *avctx) ++{ ++ VP9Context *s = avctx->priv_data; ++ struct v4l2_ctrl_vp9_compressed_hdr chp; ++ struct v4l2_ext_control control[] = { ++ { ++ .id = V4L2_CID_STATELESS_VP9_COMPRESSED_HDR, ++ .ptr = &chp, ++ .size = sizeof(chp), ++ }, ++ }; ++ ++ memset(&chp, 0, sizeof(chp)); ++ ++ chp.tx_mode = s->s.h.txfmmode; ++ memcpy(chp.tx8, s->prob_raw.p.tx8p, sizeof(s->prob_raw.p.tx8p)); ++ memcpy(chp.tx16, s->prob_raw.p.tx16p, sizeof(s->prob_raw.p.tx16p)); ++ memcpy(chp.tx32, s->prob_raw.p.tx32p, sizeof(s->prob_raw.p.tx32p)); ++ for (unsigned i = 0; i < 4; i++) { ++ for (unsigned j = 0; j < 2; j++) { ++ for (unsigned k = 0; k < 2; k++) { ++ for (unsigned l = 0; l < 6; l++) { ++ for (unsigned m = 0; m < 6; m++) { ++ memcpy(chp.coef[i][j][k][l][m], s->prob_raw.coef[i][j][k][l][m], sizeof(chp.coef[0][0][0][0][0])); ++ } ++ } ++ } ++ } ++ } ++ memcpy(chp.skip, s->prob_raw.p.skip, sizeof(s->prob_raw.p.skip)); ++ memcpy(chp.inter_mode, s->prob_raw.p.mv_mode, sizeof(s->prob_raw.p.mv_mode)); ++ memcpy(chp.interp_filter, s->prob_raw.p.filter, sizeof(s->prob_raw.p.filter)); ++ memcpy(chp.is_inter, s->prob_raw.p.intra, sizeof(s->prob_raw.p.intra)); ++ memcpy(chp.comp_mode, s->prob_raw.p.comp, sizeof(s->prob_raw.p.comp)); ++ memcpy(chp.single_ref, s->prob_raw.p.single_ref, sizeof(s->prob_raw.p.single_ref)); ++ memcpy(chp.comp_ref, s->prob_raw.p.comp_ref, sizeof(s->prob_raw.p.comp_ref)); ++ memcpy(chp.y_mode, s->prob_raw.p.y_mode, sizeof(s->prob_raw.p.y_mode)); ++ for (unsigned i = 0; i < 10; i++) ++ memcpy(chp.uv_mode[i], s->prob.p.uv_mode[i], sizeof(s->prob.p.uv_mode[0])); ++ for (unsigned i = 0; i < 4; i++) ++ memcpy(chp.partition[i * 4], s->prob_raw.p.partition[i], sizeof(s->prob_raw.p.partition[0])); ++ memcpy(chp.mv.joint, s->prob_raw.p.mv_joint, sizeof(s->prob_raw.p.mv_joint)); ++ for (unsigned i = 0; i < 2; i++) { ++ chp.mv.sign[i] = s->prob_raw.p.mv_comp[i].sign; ++ memcpy(chp.mv.classes[i], s->prob_raw.p.mv_comp[i].classes, sizeof(s->prob_raw.p.mv_comp[0].classes)); ++ chp.mv.class0_bit[i] = s->prob_raw.p.mv_comp[i].class0; ++ memcpy(chp.mv.bits[i], s->prob_raw.p.mv_comp[i].bits, sizeof(s->prob_raw.p.mv_comp[0].bits)); ++ memcpy(chp.mv.class0_fr[i], s->prob_raw.p.mv_comp[i].class0_fp, sizeof(s->prob_raw.p.mv_comp[0].class0_fp)); ++ memcpy(chp.mv.fr[i], s->prob_raw.p.mv_comp[i].fp, sizeof(s->prob_raw.p.mv_comp[0].fp)); ++ chp.mv.class0_hp[i] = s->prob_raw.p.mv_comp[i].class0_hp; ++ chp.mv.hp[i] = s->prob_raw.p.mv_comp[i].hp; ++ } ++ ++ return ff_v4l2_request_set_controls(avctx, control, FF_ARRAY_ELEMS(control)); ++} ++ ++static int v4l2_request_vp9_start_frame(AVCodecContext *avctx, ++ av_unused const uint8_t *buffer, ++ av_unused uint32_t size) ++{ ++ const VP9Context *s = avctx->priv_data; ++ const VP9Frame *f = &s->s.frames[CUR_FRAME]; ++ V4L2RequestControlsVP9 *controls = f->hwaccel_picture_private; ++ struct v4l2_ctrl_vp9_frame *dec_params = &controls->decode_params; ++ const ThreadFrame *ref; ++ int ret; ++ ++ ret = v4l2_request_vp9_set_frame_ctx(avctx); ++ if (ret) ++ return ret; ++ ++ memset(dec_params, 0, sizeof(*dec_params)); ++ ++ if (s->s.h.keyframe) ++ dec_params->flags |= V4L2_VP9_FRAME_FLAG_KEY_FRAME; ++ if (!s->s.h.invisible) ++ dec_params->flags |= V4L2_VP9_FRAME_FLAG_SHOW_FRAME; ++ if (s->s.h.errorres) ++ dec_params->flags |= V4L2_VP9_FRAME_FLAG_ERROR_RESILIENT; ++ if (s->s.h.intraonly) ++ dec_params->flags |= V4L2_VP9_FRAME_FLAG_INTRA_ONLY; ++ if (!s->s.h.keyframe && s->s.h.highprecisionmvs) ++ dec_params->flags |= V4L2_VP9_FRAME_FLAG_ALLOW_HIGH_PREC_MV; ++ if (s->s.h.refreshctx) ++ dec_params->flags |= V4L2_VP9_FRAME_FLAG_REFRESH_FRAME_CTX; ++ if (s->s.h.parallelmode) ++ dec_params->flags |= V4L2_VP9_FRAME_FLAG_PARALLEL_DEC_MODE; ++ if (s->ss_h) ++ dec_params->flags |= V4L2_VP9_FRAME_FLAG_X_SUBSAMPLING; ++ if (s->ss_v) ++ dec_params->flags |= V4L2_VP9_FRAME_FLAG_Y_SUBSAMPLING; ++ if (avctx->color_range == AVCOL_RANGE_JPEG) ++ dec_params->flags |= V4L2_VP9_FRAME_FLAG_COLOR_RANGE_FULL_SWING; ++ ++ dec_params->compressed_header_size = s->s.h.compressed_header_size; ++ dec_params->uncompressed_header_size = s->s.h.uncompressed_header_size; ++ dec_params->profile = s->s.h.profile; ++ dec_params->reset_frame_context = s->s.h.resetctx > 0 ? s->s.h.resetctx - 1 : 0; ++ dec_params->frame_context_idx = s->s.h.framectxid; ++ dec_params->bit_depth = s->s.h.bpp; ++ ++ dec_params->interpolation_filter = s->s.h.filtermode ^ (s->s.h.filtermode <= 1); ++ dec_params->tile_cols_log2 = s->s.h.tiling.log2_tile_cols; ++ dec_params->tile_rows_log2 = s->s.h.tiling.log2_tile_rows; ++ dec_params->reference_mode = s->s.h.comppredmode; ++ dec_params->frame_width_minus_1 = s->w - 1; ++ dec_params->frame_height_minus_1 = s->h - 1; ++ //dec_params->render_width_minus_1 = avctx->width - 1; ++ //dec_params->render_height_minus_1 = avctx->height - 1; ++ ++ ref = &s->s.refs[s->s.h.refidx[0]]; ++ if (ref->f && ref->f->buf[0]) ++ dec_params->last_frame_ts = ff_v4l2_request_get_capture_timestamp(ref->f); ++ ref = &s->s.refs[s->s.h.refidx[1]]; ++ if (ref->f && ref->f->buf[0]) ++ dec_params->golden_frame_ts = ff_v4l2_request_get_capture_timestamp(ref->f); ++ ref = &s->s.refs[s->s.h.refidx[2]]; ++ if (ref->f && ref->f->buf[0]) ++ dec_params->alt_frame_ts = ff_v4l2_request_get_capture_timestamp(ref->f); ++ ++ if (s->s.h.signbias[0]) ++ dec_params->ref_frame_sign_bias |= V4L2_VP9_SIGN_BIAS_LAST; ++ if (s->s.h.signbias[1]) ++ dec_params->ref_frame_sign_bias |= V4L2_VP9_SIGN_BIAS_GOLDEN; ++ if (s->s.h.signbias[2]) ++ dec_params->ref_frame_sign_bias |= V4L2_VP9_SIGN_BIAS_ALT; ++ ++ if (s->s.h.lf_delta.enabled) ++ dec_params->lf.flags |= V4L2_VP9_LOOP_FILTER_FLAG_DELTA_ENABLED; ++ if (s->s.h.lf_delta.updated) ++ dec_params->lf.flags |= V4L2_VP9_LOOP_FILTER_FLAG_DELTA_UPDATE; ++ ++ dec_params->lf.level = s->s.h.filter.level; ++ dec_params->lf.sharpness = s->s.h.filter.sharpness; ++ for (unsigned i = 0; i < 4; i++) ++ dec_params->lf.ref_deltas[i] = s->s.h.lf_delta.ref[i]; ++ for (unsigned i = 0; i < 2; i++) ++ dec_params->lf.mode_deltas[i] = s->s.h.lf_delta.mode[i]; ++ ++ dec_params->quant.base_q_idx = s->s.h.yac_qi; ++ dec_params->quant.delta_q_y_dc = s->s.h.ydc_qdelta; ++ dec_params->quant.delta_q_uv_dc = s->s.h.uvdc_qdelta; ++ dec_params->quant.delta_q_uv_ac = s->s.h.uvac_qdelta; ++ ++ if (s->s.h.segmentation.enabled) ++ dec_params->seg.flags |= V4L2_VP9_SEGMENTATION_FLAG_ENABLED; ++ if (s->s.h.segmentation.update_map) ++ dec_params->seg.flags |= V4L2_VP9_SEGMENTATION_FLAG_UPDATE_MAP; ++ if (s->s.h.segmentation.temporal) ++ dec_params->seg.flags |= V4L2_VP9_SEGMENTATION_FLAG_TEMPORAL_UPDATE; ++ if (s->s.h.segmentation.update_data) ++ dec_params->seg.flags |= V4L2_VP9_SEGMENTATION_FLAG_UPDATE_DATA; ++ if (s->s.h.segmentation.absolute_vals) ++ dec_params->seg.flags |= V4L2_VP9_SEGMENTATION_FLAG_ABS_OR_DELTA_UPDATE; ++ ++ for (unsigned i = 0; i < 7; i++) ++ dec_params->seg.tree_probs[i] = s->s.h.segmentation.prob[i]; ++ ++ if (s->s.h.segmentation.temporal) { ++ for (unsigned i = 0; i < 3; i++) ++ dec_params->seg.pred_probs[i] = s->s.h.segmentation.pred_prob[i]; ++ } else { ++ memset(dec_params->seg.pred_probs, 255, sizeof(dec_params->seg.pred_probs)); ++ } ++ ++ for (unsigned i = 0; i < 8; i++) { ++ if (s->s.h.segmentation.feat[i].q_enabled) { ++ dec_params->seg.feature_enabled[i] |= 1 << V4L2_VP9_SEG_LVL_ALT_Q; ++ dec_params->seg.feature_data[i][V4L2_VP9_SEG_LVL_ALT_Q] = s->s.h.segmentation.feat[i].q_val; ++ } ++ ++ if (s->s.h.segmentation.feat[i].lf_enabled) { ++ dec_params->seg.feature_enabled[i] |= 1 << V4L2_VP9_SEG_LVL_ALT_L; ++ dec_params->seg.feature_data[i][V4L2_VP9_SEG_LVL_ALT_L] = s->s.h.segmentation.feat[i].lf_val; ++ } ++ ++ if (s->s.h.segmentation.feat[i].ref_enabled) { ++ dec_params->seg.feature_enabled[i] |= 1 << V4L2_VP9_SEG_LVL_REF_FRAME; ++ dec_params->seg.feature_data[i][V4L2_VP9_SEG_LVL_REF_FRAME] = s->s.h.segmentation.feat[i].ref_val; ++ } ++ ++ if (s->s.h.segmentation.feat[i].skip_enabled) ++ dec_params->seg.feature_enabled[i] |= 1 << V4L2_VP9_SEG_LVL_SKIP; ++ } ++ ++ return ff_v4l2_request_reset_frame(avctx, f->tf.f); ++} ++ ++static int v4l2_request_vp9_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) ++{ ++ const VP9Context *s = avctx->priv_data; ++ const VP9Frame *f = &s->s.frames[CUR_FRAME]; ++ ++ return ff_v4l2_request_append_output_buffer(avctx, f->tf.f, buffer, size); ++} ++ ++static int v4l2_request_vp9_end_frame(AVCodecContext *avctx) ++{ ++ const VP9Context *s = avctx->priv_data; ++ const VP9Frame *f = &s->s.frames[CUR_FRAME]; ++ V4L2RequestControlsVP9 *controls = f->hwaccel_picture_private; ++ int ret; ++ ++ struct v4l2_ext_control control[] = { ++ { ++ .id = V4L2_CID_STATELESS_VP9_FRAME, ++ .ptr = &controls->decode_params, ++ .size = sizeof(controls->decode_params), ++ }, ++ }; ++ ++ ret = ff_v4l2_request_decode_frame(avctx, f->tf.f, control, FF_ARRAY_ELEMS(control)); ++ if (ret) ++ return ret; ++ ++ if (!s->s.h.refreshctx) ++ return 0; ++ ++ return 0; ++} ++ ++static int v4l2_request_vp9_init(AVCodecContext *avctx) ++{ ++ // TODO: check V4L2_CID_MPEG_VIDEO_VP9_PROFILE ++ return ff_v4l2_request_init(avctx, V4L2_PIX_FMT_VP9_FRAME, 3 * 1024 * 1024, NULL, 0); ++} ++ ++const AVHWAccel ff_vp9_v4l2request_hwaccel = { ++ .name = "vp9_v4l2request", ++ .type = AVMEDIA_TYPE_VIDEO, ++ .id = AV_CODEC_ID_VP9, ++ .pix_fmt = AV_PIX_FMT_DRM_PRIME, ++ .start_frame = v4l2_request_vp9_start_frame, ++ .decode_slice = v4l2_request_vp9_decode_slice, ++ .end_frame = v4l2_request_vp9_end_frame, ++ .frame_priv_data_size = sizeof(V4L2RequestControlsVP9), ++ .init = v4l2_request_vp9_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/vp9.c b/libavcodec/vp9.c +index 4659f94ee8b6..1b2f1eeaf69c 100644 +--- a/libavcodec/vp9.c ++++ b/libavcodec/vp9.c +@@ -191,6 +191,7 @@ static int update_size(AVCodecContext *avctx, int w, int h) + #define HWACCEL_MAX (CONFIG_VP9_DXVA2_HWACCEL + \ + CONFIG_VP9_D3D11VA_HWACCEL * 2 + \ + CONFIG_VP9_NVDEC_HWACCEL + \ ++ CONFIG_VP9_V4L2REQUEST_HWACCEL + \ + CONFIG_VP9_VAAPI_HWACCEL + \ + CONFIG_VP9_VDPAU_HWACCEL) + enum AVPixelFormat pix_fmts[HWACCEL_MAX + 2], *fmtp = pix_fmts; +@@ -223,6 +224,9 @@ static int update_size(AVCodecContext *avctx, int w, int h) + #endif + #if CONFIG_VP9_VDPAU_HWACCEL + *fmtp++ = AV_PIX_FMT_VDPAU; ++#endif ++#if CONFIG_VP9_V4L2REQUEST_HWACCEL ++ *fmtp++ = AV_PIX_FMT_DRM_PRIME; + #endif + break; + case AV_PIX_FMT_YUV420P12: +@@ -234,6 +238,9 @@ static int update_size(AVCodecContext *avctx, int w, int h) + #endif + #if CONFIG_VP9_VDPAU_HWACCEL + *fmtp++ = AV_PIX_FMT_VDPAU; ++#endif ++#if CONFIG_VP9_V4L2REQUEST_HWACCEL ++ *fmtp++ = AV_PIX_FMT_DRM_PRIME; + #endif + break; + } +@@ -382,7 +389,7 @@ static av_always_inline int inv_recenter_nonneg(int v, int m) + } + + // differential forward probability updates +-static int update_prob(VP56RangeCoder *c, int p) ++static int read_prob_delta(VP56RangeCoder *c) + { + static const uint8_t inv_map_table[255] = { + 7, 20, 33, 46, 59, 72, 85, 98, 111, 124, 137, 150, 163, 176, +@@ -436,8 +443,13 @@ static int update_prob(VP56RangeCoder *c, int p) + av_assert2(d < FF_ARRAY_ELEMS(inv_map_table)); + } + +- return p <= 128 ? 1 + inv_recenter_nonneg(inv_map_table[d], p - 1) : +- 255 - inv_recenter_nonneg(inv_map_table[d], 255 - p); ++ return inv_map_table[d]; ++} ++ ++static int update_prob(int p, int d) ++{ ++ return p <= 128 ? 1 + inv_recenter_nonneg(d, p - 1) : ++ 255 - inv_recenter_nonneg(d, 255 - p); + } + + static int read_colorspace_details(AVCodecContext *avctx) +@@ -703,7 +715,8 @@ static int decode_frame_header(AVCodecContext *avctx, + get_bits(&s->gb, 8) : 255; + } + +- if (get_bits1(&s->gb)) { ++ s->s.h.segmentation.update_data = get_bits1(&s->gb); ++ if (s->s.h.segmentation.update_data) { + s->s.h.segmentation.absolute_vals = get_bits1(&s->gb); + for (i = 0; i < 8; i++) { + if ((s->s.h.segmentation.feat[i].q_enabled = get_bits1(&s->gb))) +@@ -904,6 +917,8 @@ static int decode_frame_header(AVCodecContext *avctx, + * as explicit copies if the fw update is missing (and skip the copy upon + * fw update)? */ + s->prob.p = s->prob_ctx[c].p; ++ memset(&s->prob_raw.p, 0, sizeof(s->prob_raw.p)); ++ memset(&s->prob_raw.coef, 0, sizeof(s->prob_raw.coef)); + + // txfm updates + if (s->s.h.lossless) { +@@ -915,18 +930,25 @@ static int decode_frame_header(AVCodecContext *avctx, + + if (s->s.h.txfmmode == TX_SWITCHABLE) { + for (i = 0; i < 2; i++) +- if (vp56_rac_get_prob_branchy(&s->c, 252)) +- s->prob.p.tx8p[i] = update_prob(&s->c, s->prob.p.tx8p[i]); ++ if (vp56_rac_get_prob_branchy(&s->c, 252)) { ++ s->prob_raw.p.tx8p[i] = read_prob_delta(&s->c); ++ s->prob.p.tx8p[i] = update_prob(s->prob.p.tx8p[i], ++ s->prob_raw.p.tx8p[i]); ++ } + for (i = 0; i < 2; i++) + for (j = 0; j < 2; j++) +- if (vp56_rac_get_prob_branchy(&s->c, 252)) +- s->prob.p.tx16p[i][j] = +- update_prob(&s->c, s->prob.p.tx16p[i][j]); ++ if (vp56_rac_get_prob_branchy(&s->c, 252)) { ++ s->prob_raw.p.tx16p[i][j] = read_prob_delta(&s->c); ++ s->prob.p.tx16p[i][j] = update_prob(s->prob.p.tx16p[i][j], ++ s->prob_raw.p.tx16p[i][j]); ++ } + for (i = 0; i < 2; i++) + for (j = 0; j < 3; j++) +- if (vp56_rac_get_prob_branchy(&s->c, 252)) +- s->prob.p.tx32p[i][j] = +- update_prob(&s->c, s->prob.p.tx32p[i][j]); ++ if (vp56_rac_get_prob_branchy(&s->c, 252)) { ++ s->prob_raw.p.tx32p[i][j] = read_prob_delta(&s->c); ++ s->prob.p.tx32p[i][j] = update_prob(s->prob.p.tx32p[i][j], ++ s->prob_raw.p.tx32p[i][j]); ++ } + } + } + +@@ -938,15 +960,18 @@ static int decode_frame_header(AVCodecContext *avctx, + for (k = 0; k < 2; k++) + for (l = 0; l < 6; l++) + for (m = 0; m < 6; m++) { ++ uint8_t *pd = s->prob_raw.coef[i][j][k][l][m]; + uint8_t *p = s->prob.coef[i][j][k][l][m]; + uint8_t *r = ref[j][k][l][m]; + if (m >= 3 && l == 0) // dc only has 3 pt + break; + for (n = 0; n < 3; n++) { +- if (vp56_rac_get_prob_branchy(&s->c, 252)) +- p[n] = update_prob(&s->c, r[n]); +- else ++ if (vp56_rac_get_prob_branchy(&s->c, 252)) { ++ pd[n] = read_prob_delta(&s->c); ++ p[n] = update_prob(r[n], pd[n]); ++ } else { + p[n] = r[n]; ++ } + } + memcpy(&p[3], ff_vp9_model_pareto8[p[2]], 8); + } +@@ -961,7 +986,7 @@ static int decode_frame_header(AVCodecContext *avctx, + break; + memcpy(p, r, 3); + memcpy(&p[3], ff_vp9_model_pareto8[p[2]], 8); +- } ++ } + } + if (s->s.h.txfmmode == i) + break; +@@ -969,25 +994,37 @@ static int decode_frame_header(AVCodecContext *avctx, + + // mode updates + for (i = 0; i < 3; i++) +- if (vp56_rac_get_prob_branchy(&s->c, 252)) +- s->prob.p.skip[i] = update_prob(&s->c, s->prob.p.skip[i]); ++ if (vp56_rac_get_prob_branchy(&s->c, 252)) { ++ s->prob_raw.p.skip[i] = read_prob_delta(&s->c); ++ s->prob.p.skip[i] = update_prob(s->prob.p.skip[i], ++ s->prob_raw.p.skip[i]); ++ } + if (!s->s.h.keyframe && !s->s.h.intraonly) { + for (i = 0; i < 7; i++) + for (j = 0; j < 3; j++) +- if (vp56_rac_get_prob_branchy(&s->c, 252)) ++ if (vp56_rac_get_prob_branchy(&s->c, 252)) { ++ s->prob_raw.p.mv_mode[i][j] = read_prob_delta(&s->c); + s->prob.p.mv_mode[i][j] = +- update_prob(&s->c, s->prob.p.mv_mode[i][j]); ++ update_prob(s->prob.p.mv_mode[i][j], ++ s->prob_raw.p.mv_mode[i][j]); ++ } + + if (s->s.h.filtermode == FILTER_SWITCHABLE) + for (i = 0; i < 4; i++) + for (j = 0; j < 2; j++) +- if (vp56_rac_get_prob_branchy(&s->c, 252)) ++ if (vp56_rac_get_prob_branchy(&s->c, 252)) { ++ s->prob_raw.p.filter[i][j] = read_prob_delta(&s->c); + s->prob.p.filter[i][j] = +- update_prob(&s->c, s->prob.p.filter[i][j]); ++ update_prob(s->prob.p.filter[i][j], ++ s->prob_raw.p.filter[i][j]); ++ } + + for (i = 0; i < 4; i++) +- if (vp56_rac_get_prob_branchy(&s->c, 252)) +- s->prob.p.intra[i] = update_prob(&s->c, s->prob.p.intra[i]); ++ if (vp56_rac_get_prob_branchy(&s->c, 252)) { ++ s->prob_raw.p.intra[i] = read_prob_delta(&s->c); ++ s->prob.p.intra[i] = update_prob(s->prob.p.intra[i], ++ s->prob_raw.p.intra[i]); ++ } + + if (s->s.h.allowcompinter) { + s->s.h.comppredmode = vp8_rac_get(&s->c); +@@ -995,92 +1032,134 @@ static int decode_frame_header(AVCodecContext *avctx, + s->s.h.comppredmode += vp8_rac_get(&s->c); + if (s->s.h.comppredmode == PRED_SWITCHABLE) + for (i = 0; i < 5; i++) +- if (vp56_rac_get_prob_branchy(&s->c, 252)) ++ if (vp56_rac_get_prob_branchy(&s->c, 252)) { ++ s->prob_raw.p.comp[i] = read_prob_delta(&s->c); + s->prob.p.comp[i] = +- update_prob(&s->c, s->prob.p.comp[i]); ++ update_prob(s->prob.p.comp[i], s->prob_raw.p.comp[i]); ++ } + } else { + s->s.h.comppredmode = PRED_SINGLEREF; + } + + if (s->s.h.comppredmode != PRED_COMPREF) { + for (i = 0; i < 5; i++) { +- if (vp56_rac_get_prob_branchy(&s->c, 252)) ++ if (vp56_rac_get_prob_branchy(&s->c, 252)) { ++ s->prob_raw.p.single_ref[i][0] = read_prob_delta(&s->c); + s->prob.p.single_ref[i][0] = +- update_prob(&s->c, s->prob.p.single_ref[i][0]); +- if (vp56_rac_get_prob_branchy(&s->c, 252)) ++ update_prob(s->prob.p.single_ref[i][0], ++ s->prob_raw.p.single_ref[i][0]); ++ } ++ if (vp56_rac_get_prob_branchy(&s->c, 252)) { ++ s->prob_raw.p.single_ref[i][1] = read_prob_delta(&s->c); + s->prob.p.single_ref[i][1] = +- update_prob(&s->c, s->prob.p.single_ref[i][1]); ++ update_prob(s->prob.p.single_ref[i][1], ++ s->prob_raw.p.single_ref[i][1]); ++ } + } + } + + if (s->s.h.comppredmode != PRED_SINGLEREF) { + for (i = 0; i < 5; i++) +- if (vp56_rac_get_prob_branchy(&s->c, 252)) ++ if (vp56_rac_get_prob_branchy(&s->c, 252)) { ++ s->prob_raw.p.comp_ref[i] = read_prob_delta(&s->c); + s->prob.p.comp_ref[i] = +- update_prob(&s->c, s->prob.p.comp_ref[i]); ++ update_prob(s->prob.p.comp_ref[i], ++ s->prob_raw.p.comp_ref[i]); ++ } + } + + for (i = 0; i < 4; i++) + for (j = 0; j < 9; j++) +- if (vp56_rac_get_prob_branchy(&s->c, 252)) ++ if (vp56_rac_get_prob_branchy(&s->c, 252)) { ++ s->prob_raw.p.y_mode[i][j] = read_prob_delta(&s->c); + s->prob.p.y_mode[i][j] = +- update_prob(&s->c, s->prob.p.y_mode[i][j]); ++ update_prob(s->prob.p.y_mode[i][j], ++ s->prob_raw.p.y_mode[i][j]); ++ } + + for (i = 0; i < 4; i++) + for (j = 0; j < 4; j++) + for (k = 0; k < 3; k++) +- if (vp56_rac_get_prob_branchy(&s->c, 252)) ++ if (vp56_rac_get_prob_branchy(&s->c, 252)) { ++ s->prob_raw.p.partition[i][j][k] = read_prob_delta(&s->c); + s->prob.p.partition[3 - i][j][k] = +- update_prob(&s->c, +- s->prob.p.partition[3 - i][j][k]); ++ update_prob(s->prob.p.partition[3 - i][j][k], ++ s->prob_raw.p.partition[i][j][k]); ++ } + + // mv fields don't use the update_prob subexp model for some reason + for (i = 0; i < 3; i++) +- if (vp56_rac_get_prob_branchy(&s->c, 252)) +- s->prob.p.mv_joint[i] = (vp8_rac_get_uint(&s->c, 7) << 1) | 1; ++ if (vp56_rac_get_prob_branchy(&s->c, 252)) { ++ s->prob_raw.p.mv_joint[i] = (vp8_rac_get_uint(&s->c, 7) << 1) | 1; ++ s->prob.p.mv_joint[i] = s->prob_raw.p.mv_joint[i]; ++ } + + for (i = 0; i < 2; i++) { +- if (vp56_rac_get_prob_branchy(&s->c, 252)) ++ if (vp56_rac_get_prob_branchy(&s->c, 252)) { ++ s->prob_raw.p.mv_comp[i].sign = ++ (vp8_rac_get_uint(&s->c, 7) << 1) | 1; + s->prob.p.mv_comp[i].sign = +- (vp8_rac_get_uint(&s->c, 7) << 1) | 1; ++ s->prob_raw.p.mv_comp[i].sign; ++ } + + for (j = 0; j < 10; j++) +- if (vp56_rac_get_prob_branchy(&s->c, 252)) ++ if (vp56_rac_get_prob_branchy(&s->c, 252)) { ++ s->prob_raw.p.mv_comp[i].classes[j] = ++ (vp8_rac_get_uint(&s->c, 7) << 1) | 1; + s->prob.p.mv_comp[i].classes[j] = +- (vp8_rac_get_uint(&s->c, 7) << 1) | 1; ++ s->prob_raw.p.mv_comp[i].classes[j]; ++ } + +- if (vp56_rac_get_prob_branchy(&s->c, 252)) ++ if (vp56_rac_get_prob_branchy(&s->c, 252)) { ++ s->prob_raw.p.mv_comp[i].class0 = ++ (vp8_rac_get_uint(&s->c, 7) << 1) | 1; + s->prob.p.mv_comp[i].class0 = +- (vp8_rac_get_uint(&s->c, 7) << 1) | 1; ++ s->prob_raw.p.mv_comp[i].class0; ++ } + + for (j = 0; j < 10; j++) +- if (vp56_rac_get_prob_branchy(&s->c, 252)) ++ if (vp56_rac_get_prob_branchy(&s->c, 252)) { ++ s->prob_raw.p.mv_comp[i].bits[j] = ++ (vp8_rac_get_uint(&s->c, 7) << 1) | 1; + s->prob.p.mv_comp[i].bits[j] = +- (vp8_rac_get_uint(&s->c, 7) << 1) | 1; ++ s->prob_raw.p.mv_comp[i].bits[j]; ++ } + } + + for (i = 0; i < 2; i++) { + for (j = 0; j < 2; j++) + for (k = 0; k < 3; k++) +- if (vp56_rac_get_prob_branchy(&s->c, 252)) +- s->prob.p.mv_comp[i].class0_fp[j][k] = ++ if (vp56_rac_get_prob_branchy(&s->c, 252)) { ++ s->prob_raw.p.mv_comp[i].class0_fp[j][k] = + (vp8_rac_get_uint(&s->c, 7) << 1) | 1; ++ s->prob.p.mv_comp[i].class0_fp[j][k] = ++ s->prob_raw.p.mv_comp[i].class0_fp[j][k]; ++ } + + for (j = 0; j < 3; j++) +- if (vp56_rac_get_prob_branchy(&s->c, 252)) ++ if (vp56_rac_get_prob_branchy(&s->c, 252)) { ++ s->prob_raw.p.mv_comp[i].fp[j] = ++ (vp8_rac_get_uint(&s->c, 7) << 1) | 1; + s->prob.p.mv_comp[i].fp[j] = +- (vp8_rac_get_uint(&s->c, 7) << 1) | 1; ++ s->prob_raw.p.mv_comp[i].fp[j]; ++ } + } + + if (s->s.h.highprecisionmvs) { + for (i = 0; i < 2; i++) { +- if (vp56_rac_get_prob_branchy(&s->c, 252)) ++ if (vp56_rac_get_prob_branchy(&s->c, 252)) { ++ s->prob_raw.p.mv_comp[i].class0_hp = ++ (vp8_rac_get_uint(&s->c, 7) << 1) | 1; + s->prob.p.mv_comp[i].class0_hp = +- (vp8_rac_get_uint(&s->c, 7) << 1) | 1; ++ s->prob_raw.p.mv_comp[i].class0_hp; ++ } + +- if (vp56_rac_get_prob_branchy(&s->c, 252)) ++ if (vp56_rac_get_prob_branchy(&s->c, 252)) { ++ s->prob_raw.p.mv_comp[i].hp = ++ (vp8_rac_get_uint(&s->c, 7) << 1) | 1; + s->prob.p.mv_comp[i].hp = +- (vp8_rac_get_uint(&s->c, 7) << 1) | 1; ++ s->prob_raw.p.mv_comp[i].hp; ++ } + } + } + } +@@ -1912,6 +1991,9 @@ AVCodec ff_vp9_decoder = { + #endif + #if CONFIG_VP9_VDPAU_HWACCEL + HWACCEL_VDPAU(vp9), ++#endif ++#if CONFIG_VP9_V4L2REQUEST_HWACCEL ++ HWACCEL_V4L2REQUEST(vp9), + #endif + NULL + }, +diff --git a/libavcodec/vp9dec.h b/libavcodec/vp9dec.h +index d82b258a3d81..8d2c341e0b97 100644 +--- a/libavcodec/vp9dec.h ++++ b/libavcodec/vp9dec.h +@@ -131,6 +131,10 @@ typedef struct VP9Context { + ProbContext p; + uint8_t coef[4][2][2][6][6][11]; + } prob; ++ struct { ++ ProbContext p; ++ uint8_t coef[4][2][2][6][6][11]; ++ } prob_raw; + + // contextual (above) cache + uint8_t *above_partition_ctx; +diff --git a/libavcodec/vp9shared.h b/libavcodec/vp9shared.h +index 54726df742f9..fee3568736f7 100644 +--- a/libavcodec/vp9shared.h ++++ b/libavcodec/vp9shared.h +@@ -131,6 +131,7 @@ typedef struct VP9BitstreamHeader { + uint8_t temporal; + uint8_t absolute_vals; + uint8_t update_map; ++ uint8_t update_data; + uint8_t prob[7]; + uint8_t pred_prob[3]; + struct { + +From ae118fbbef1e287c5101d7ceaa164727d825c4c2 Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Thu, 14 Feb 2019 23:20:05 +0100 -Subject: [PATCH 09/18] Add and use private linux v5.14 headers for V4L2 +Subject: [PATCH 10/16] Add and use private linux v5.16 headers for V4L2 request API ctrls Signed-off-by: Jernej Skrabec Signed-off-by: Jonas Karlman --- configure | 2 +- - libavcodec/hevc-ctrls.h | 240 +++++++++++++++++++++++++++++++++ + libavcodec/hevc-ctrls.h | 252 +++++++++++++++++++++++++++++++++ libavcodec/v4l2_request_hevc.c | 1 + - 3 files changed, 242 insertions(+), 1 deletion(-) + 3 files changed, 254 insertions(+), 1 deletion(-) create mode 100644 libavcodec/hevc-ctrls.h diff --git a/configure b/configure -index 02a80cf27f..30ee788711 100755 +index 0b238c051dff..1c1929d2c28f 100755 --- a/configure +++ b/configure @@ -2967,7 +2967,7 @@ hevc_dxva2_hwaccel_deps="dxva2 DXVA_PicParams_HEVC" @@ -3154,10 +3912,10 @@ index 02a80cf27f..30ee788711 100755 hevc_vaapi_hwaccel_select="hevc_decoder" diff --git a/libavcodec/hevc-ctrls.h b/libavcodec/hevc-ctrls.h new file mode 100644 -index 0000000000..53c0038c79 +index 000000000000..ef63bc205756 --- /dev/null +++ b/libavcodec/hevc-ctrls.h -@@ -0,0 +1,240 @@ +@@ -0,0 +1,252 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * These are the HEVC state controls for use with stateless HEVC @@ -3179,6 +3937,7 @@ index 0000000000..53c0038c79 +#define V4L2_CID_MPEG_VIDEO_HEVC_SPS (V4L2_CID_CODEC_BASE + 1008) +#define V4L2_CID_MPEG_VIDEO_HEVC_PPS (V4L2_CID_CODEC_BASE + 1009) +#define V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS (V4L2_CID_CODEC_BASE + 1010) ++#define V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX (V4L2_CID_CODEC_BASE + 1011) +#define V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS (V4L2_CID_CODEC_BASE + 1012) +#define V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE (V4L2_CID_CODEC_BASE + 1015) +#define V4L2_CID_MPEG_VIDEO_HEVC_START_CODE (V4L2_CID_CODEC_BASE + 1016) @@ -3187,6 +3946,7 @@ index 0000000000..53c0038c79 +#define V4L2_CTRL_TYPE_HEVC_SPS 0x0120 +#define V4L2_CTRL_TYPE_HEVC_PPS 0x0121 +#define V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS 0x0122 ++#define V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX 0x0123 +#define V4L2_CTRL_TYPE_HEVC_DECODE_PARAMS 0x0124 + +enum v4l2_mpeg_video_hevc_decode_mode { @@ -3356,10 +4116,11 @@ index 0000000000..53c0038c79 + __u8 pic_struct; + + /* ISO/IEC 23008-2, ITU-T Rec. H.265: General slice segment header */ ++ __u32 slice_segment_addr; + __u8 ref_idx_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; + __u8 ref_idx_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; + -+ __u8 padding[5]; ++ __u8 padding; + + /* ISO/IEC 23008-2, ITU-T Rec. H.265: Weighted prediction parameter */ + struct v4l2_hevc_pred_weight_table pred_weight_table; @@ -3384,6 +4145,15 @@ index 0000000000..53c0038c79 + __u64 flags; +}; + ++struct v4l2_ctrl_hevc_scaling_matrix { ++ __u8 scaling_list_4x4[6][16]; ++ __u8 scaling_list_8x8[6][64]; ++ __u8 scaling_list_16x16[6][64]; ++ __u8 scaling_list_32x32[2][64]; ++ __u8 scaling_list_dc_coef_16x16[6]; ++ __u8 scaling_list_dc_coef_32x32[2]; ++}; ++ +/* MPEG-class control IDs specific to the Hantro driver as defined by V4L2 */ +#define V4L2_CID_CODEC_HANTRO_BASE (V4L2_CTRL_CLASS_CODEC | 0x1200) +/* @@ -3399,7 +4169,7 @@ index 0000000000..53c0038c79 + +#endif diff --git a/libavcodec/v4l2_request_hevc.c b/libavcodec/v4l2_request_hevc.c -index d385c2f036..ad555c3bb8 100644 +index 3a9d564ce20b..f645c538c25c 100644 --- a/libavcodec/v4l2_request_hevc.c +++ b/libavcodec/v4l2_request_hevc.c @@ -19,6 +19,7 @@ @@ -3411,10 +4181,10 @@ index d385c2f036..ad555c3bb8 100644 #define MAX_SLICES 16 -From 2cdf67404bf52fb684d1857442331f302d3a35d8 Mon Sep 17 00:00:00 2001 +From afe6727d8c300c77a72549b4e094910f09242a42 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Mon, 29 Apr 2019 22:08:59 +0000 -Subject: [PATCH 10/18] HACK: hwcontext_drm: do not require drm device +Subject: [PATCH 11/16] HACK: hwcontext_drm: do not require drm device Signed-off-by: Jonas Karlman --- @@ -3422,7 +4192,7 @@ Signed-off-by: Jonas Karlman 1 file changed, 5 insertions(+) diff --git a/libavutil/hwcontext_drm.c b/libavutil/hwcontext_drm.c -index 7a9fdbd263..6297d1f9b6 100644 +index 7a9fdbd263d4..6297d1f9b613 100644 --- a/libavutil/hwcontext_drm.c +++ b/libavutil/hwcontext_drm.c @@ -53,6 +53,11 @@ static int drm_device_create(AVHWDeviceContext *hwdev, const char *device, @@ -3438,153 +4208,10 @@ index 7a9fdbd263..6297d1f9b6 100644 if (hwctx->fd < 0) return AVERROR(errno); -From 37cbcb6ca05cea82e896e661a185dbf32da0702b Mon Sep 17 00:00:00 2001 +From bcad5ac25923b3d2395edceca821129c00b57b9e Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Sat, 15 Dec 2018 22:32:16 +0100 -Subject: [PATCH 11/18] WIP: hevc scaling matrix - -Signed-off-by: Jernej Skrabec ---- - libavcodec/hevc-ctrls.h | 11 +++++++++++ - libavcodec/v4l2_request_hevc.c | 27 +++++++++++++++++++++++++++ - 2 files changed, 38 insertions(+) - -diff --git a/libavcodec/hevc-ctrls.h b/libavcodec/hevc-ctrls.h -index 53c0038c79..0e5c4a2eec 100644 ---- a/libavcodec/hevc-ctrls.h -+++ b/libavcodec/hevc-ctrls.h -@@ -19,6 +19,7 @@ - #define V4L2_CID_MPEG_VIDEO_HEVC_SPS (V4L2_CID_CODEC_BASE + 1008) - #define V4L2_CID_MPEG_VIDEO_HEVC_PPS (V4L2_CID_CODEC_BASE + 1009) - #define V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS (V4L2_CID_CODEC_BASE + 1010) -+#define V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX (V4L2_CID_CODEC_BASE + 1011) - #define V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS (V4L2_CID_CODEC_BASE + 1012) - #define V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE (V4L2_CID_CODEC_BASE + 1015) - #define V4L2_CID_MPEG_VIDEO_HEVC_START_CODE (V4L2_CID_CODEC_BASE + 1016) -@@ -27,6 +28,7 @@ - #define V4L2_CTRL_TYPE_HEVC_SPS 0x0120 - #define V4L2_CTRL_TYPE_HEVC_PPS 0x0121 - #define V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS 0x0122 -+#define V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX 0x0123 - #define V4L2_CTRL_TYPE_HEVC_DECODE_PARAMS 0x0124 - - enum v4l2_mpeg_video_hevc_decode_mode { -@@ -224,6 +226,15 @@ struct v4l2_ctrl_hevc_decode_params { - __u64 flags; - }; - -+struct v4l2_ctrl_hevc_scaling_matrix { -+ __u8 scaling_list_4x4[6][16]; -+ __u8 scaling_list_8x8[6][64]; -+ __u8 scaling_list_16x16[6][64]; -+ __u8 scaling_list_32x32[2][64]; -+ __u8 scaling_list_dc_coef_16x16[6]; -+ __u8 scaling_list_dc_coef_32x32[2]; -+}; -+ - /* MPEG-class control IDs specific to the Hantro driver as defined by V4L2 */ - #define V4L2_CID_CODEC_HANTRO_BASE (V4L2_CTRL_CLASS_CODEC | 0x1200) - /* -diff --git a/libavcodec/v4l2_request_hevc.c b/libavcodec/v4l2_request_hevc.c -index ad555c3bb8..b6c191120e 100644 ---- a/libavcodec/v4l2_request_hevc.c -+++ b/libavcodec/v4l2_request_hevc.c -@@ -27,6 +27,7 @@ typedef struct V4L2RequestControlsHEVC { - struct v4l2_ctrl_hevc_sps sps; - struct v4l2_ctrl_hevc_pps pps; - struct v4l2_ctrl_hevc_decode_params dec_params; -+ struct v4l2_ctrl_hevc_scaling_matrix scaling_matrix; - struct v4l2_ctrl_hevc_slice_params slice_params[MAX_SLICES]; - int first_slice; - int num_slices; //TODO: this should be in control -@@ -318,11 +319,32 @@ static int v4l2_request_hevc_start_frame(AVCodecContext *avctx, - { - const HEVCContext *h = avctx->priv_data; - const HEVCPPS *pps = h->ps.pps; -+ const HEVCSPS *sps = h->ps.sps; -+ const ScalingList *sl = pps->scaling_list_data_present_flag ? -+ &pps->scaling_list : -+ sps->scaling_list_enable_flag ? -+ &sps->scaling_list : NULL; - V4L2RequestControlsHEVC *controls = h->ref->hwaccel_picture_private; - - fill_sps(&controls->sps, h); - fill_dec_params(&controls->dec_params, h); - -+ if (sl) { -+ for (int i = 0; i < 6; i++) { -+ for (int j = 0; j < 16; j++) -+ controls->scaling_matrix.scaling_list_4x4[i][j] = sl->sl[0][i][j]; -+ for (int j = 0; j < 64; j++) { -+ controls->scaling_matrix.scaling_list_8x8[i][j] = sl->sl[1][i][j]; -+ controls->scaling_matrix.scaling_list_16x16[i][j] = sl->sl[2][i][j]; -+ if (i < 2) -+ controls->scaling_matrix.scaling_list_32x32[i][j] = sl->sl[3][i * 3][j]; -+ } -+ controls->scaling_matrix.scaling_list_dc_coef_16x16[i] = sl->sl_dc[0][i]; -+ if (i < 2) -+ controls->scaling_matrix.scaling_list_dc_coef_32x32[i] = sl->sl_dc[1][i * 3]; -+ } -+ } -+ - /* ISO/IEC 23008-2, ITU-T Rec. H.265: Picture parameter set */ - controls->pps = (struct v4l2_ctrl_hevc_pps) { - .num_extra_slice_header_bits = pps->num_extra_slice_header_bits, -@@ -439,6 +461,11 @@ static int v4l2_request_hevc_queue_decode(AVCodecContext *avctx, int last_slice) - .ptr = &controls->dec_params, - .size = sizeof(controls->dec_params), - }, -+ { -+ .id = V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX, -+ .ptr = &controls->scaling_matrix, -+ .size = sizeof(controls->scaling_matrix), -+ }, - { - .id = V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS, - .ptr = &controls->slice_params, - -From ddf97421cbb8583af0f96fa53a0d7f12d9f4ed21 Mon Sep 17 00:00:00 2001 -From: Jernej Skrabec -Date: Sat, 15 Dec 2018 22:32:16 +0100 -Subject: [PATCH 12/18] WIP: hevc segment address - -Signed-off-by: Jernej Skrabec ---- - libavcodec/hevc-ctrls.h | 1 + - libavcodec/v4l2_request_hevc.c | 3 +++ - 2 files changed, 4 insertions(+) - -diff --git a/libavcodec/hevc-ctrls.h b/libavcodec/hevc-ctrls.h -index 0e5c4a2eec..42ad0fe81e 100644 ---- a/libavcodec/hevc-ctrls.h -+++ b/libavcodec/hevc-ctrls.h -@@ -198,6 +198,7 @@ struct v4l2_ctrl_hevc_slice_params { - __u8 pic_struct; - - /* ISO/IEC 23008-2, ITU-T Rec. H.265: General slice segment header */ -+ __u32 slice_segment_addr; - __u8 ref_idx_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; - __u8 ref_idx_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; - -diff --git a/libavcodec/v4l2_request_hevc.c b/libavcodec/v4l2_request_hevc.c -index b6c191120e..f645c538c2 100644 ---- a/libavcodec/v4l2_request_hevc.c -+++ b/libavcodec/v4l2_request_hevc.c -@@ -188,6 +188,9 @@ static void v4l2_request_hevc_fill_slice_params(const HEVCContext *h, - .bit_size = 0, - .data_bit_offset = get_bits_count(&h->HEVClc->gb), - -+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: General slice segment header */ -+ .slice_segment_addr = sh->slice_segment_addr, -+ - /* ISO/IEC 23008-2, ITU-T Rec. H.265: NAL unit header */ - .nal_unit_type = h->nal_unit_type, - .nuh_temporal_id_plus1 = h->temporal_id + 1, - -From 1bc89a4553c4c4f7cf4654fe1a7e39de16531126 Mon Sep 17 00:00:00 2001 -From: Jernej Skrabec -Date: Sat, 15 Dec 2018 22:32:16 +0100 -Subject: [PATCH 13/18] WIP: hevc entry point offsets +Subject: [PATCH 12/16] WIP: hevc entry point offsets Signed-off-by: Jernej Skrabec --- @@ -3593,14 +4220,14 @@ Signed-off-by: Jernej Skrabec 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/libavcodec/hevc-ctrls.h b/libavcodec/hevc-ctrls.h -index 42ad0fe81e..a249166030 100644 +index ef63bc205756..a24916603017 100644 --- a/libavcodec/hevc-ctrls.h +++ b/libavcodec/hevc-ctrls.h @@ -202,7 +202,9 @@ struct v4l2_ctrl_hevc_slice_params { __u8 ref_idx_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; __u8 ref_idx_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; -- __u8 padding[5]; +- __u8 padding; + __u32 num_entry_point_offsets; + __u32 entry_point_offset_minus1[256]; + __u8 padding[8]; @@ -3608,7 +4235,7 @@ index 42ad0fe81e..a249166030 100644 /* ISO/IEC 23008-2, ITU-T Rec. H.265: Weighted prediction parameter */ struct v4l2_hevc_pred_weight_table pred_weight_table; diff --git a/libavcodec/v4l2_request_hevc.c b/libavcodec/v4l2_request_hevc.c -index f645c538c2..601202a77d 100644 +index f645c538c25c..601202a77d7a 100644 --- a/libavcodec/v4l2_request_hevc.c +++ b/libavcodec/v4l2_request_hevc.c @@ -256,6 +256,15 @@ static void v4l2_request_hevc_fill_slice_params(const HEVCContext *h, @@ -3628,10 +4255,10 @@ index f645c538c2..601202a77d 100644 static void fill_sps(struct v4l2_ctrl_hevc_sps *ctrl, const HEVCContext *h) -From 8fde9d49bf9fbf0a1a9fdf242753c2b1b6ae377c Mon Sep 17 00:00:00 2001 +From 694b79d528295ae4d073c5972d35173116ff2b69 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Fri, 15 May 2020 16:54:05 +0000 -Subject: [PATCH 16/18] WIP: add NV15 and NV20 support +Subject: [PATCH 13/16] WIP: add NV15 and NV20 support Signed-off-by: Jonas Karlman --- @@ -3640,7 +4267,7 @@ Signed-off-by: Jonas Karlman 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c -index 0a10d00aad..45057fd049 100644 +index 0a10d00aad9e..45057fd049bd 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -794,10 +794,17 @@ static enum AVPixelFormat get_pixel_format(H264Context *h, int force_callback) @@ -3674,7 +4301,7 @@ index 0a10d00aad..45057fd049 100644 *fmt++ = AV_PIX_FMT_YUVJ422P; else diff --git a/libavcodec/v4l2_request.c b/libavcodec/v4l2_request.c -index 5234b5049b..0b294feff2 100644 +index 5234b5049b0d..0b294feff2eb 100644 --- a/libavcodec/v4l2_request.c +++ b/libavcodec/v4l2_request.c @@ -188,6 +188,13 @@ const uint32_t v4l2_request_capture_pixelformats[] = { @@ -3715,17 +4342,17 @@ index 5234b5049b..0b294feff2 100644 default: return -1; -From e60693f9f34d717a53b54768e56ccbbdda375abe Mon Sep 17 00:00:00 2001 +From dd29c8e4b504f12be27db8e188ba5bbaade7559f Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Mon, 27 Jul 2020 23:15:45 +0000 -Subject: [PATCH 17/18] HACK: define drm NV15 and NV20 format +Subject: [PATCH 14/16] HACK: define drm NV15 and NV20 format --- libavcodec/v4l2_request.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/libavcodec/v4l2_request.c b/libavcodec/v4l2_request.c -index 0b294feff2..a8f0ee79ee 100644 +index 0b294feff2eb..a8f0ee79eeef 100644 --- a/libavcodec/v4l2_request.c +++ b/libavcodec/v4l2_request.c @@ -30,6 +30,14 @@ @@ -3744,10 +4371,10 @@ index 0b294feff2..a8f0ee79ee 100644 { V4L2RequestDescriptor *req = (V4L2RequestDescriptor*)frame->data[0]; -From 688bb66bf9715c02565b63446b75933282d41805 Mon Sep 17 00:00:00 2001 +From 0d56f3e7b04a5d574d38dd885000a6eb19eff903 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Wed, 13 May 2020 22:51:21 +0000 -Subject: [PATCH 18/18] WIP: hevc rkvdec fields +Subject: [PATCH 15/16] WIP: hevc rkvdec fields Signed-off-by: Jonas Karlman --- @@ -3756,7 +4383,7 @@ Signed-off-by: Jonas Karlman 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/libavcodec/hevc-ctrls.h b/libavcodec/hevc-ctrls.h -index a249166030..cd14352668 100644 +index a24916603017..cd143526685f 100644 --- a/libavcodec/hevc-ctrls.h +++ b/libavcodec/hevc-ctrls.h @@ -58,6 +58,8 @@ enum v4l2_mpeg_video_hevc_start_code { @@ -3806,7 +4433,7 @@ index a249166030..cd14352668 100644 __u32 entry_point_offset_minus1[256]; __u8 padding[8]; diff --git a/libavcodec/v4l2_request_hevc.c b/libavcodec/v4l2_request_hevc.c -index 601202a77d..be78382444 100644 +index 601202a77d7a..be7838244447 100644 --- a/libavcodec/v4l2_request_hevc.c +++ b/libavcodec/v4l2_request_hevc.c @@ -214,6 +214,9 @@ static void v4l2_request_hevc_fill_slice_params(const HEVCContext *h, @@ -3859,3 +4486,70 @@ index 601202a77d..be78382444 100644 return ff_v4l2_request_decode_frame(avctx, h->ref->frame, control, FF_ARRAY_ELEMS(control)); } + +From eb9a3213d56d9f6a177f16e907f57e0063b23244 Mon Sep 17 00:00:00 2001 +From: Alex Bee +Date: Sun, 19 Sep 2021 13:10:55 +0200 +Subject: [PATCH 16/16] v4l2_request: validate supported framesizes + +Signed-off-by: Alex Bee +--- + libavcodec/v4l2_request.c | 38 +++++++++++++++++++++++++++++++++++++- + 1 file changed, 37 insertions(+), 1 deletion(-) + +diff --git a/libavcodec/v4l2_request.c b/libavcodec/v4l2_request.c +index a8f0ee79eeef..2fbe16634160 100644 +--- a/libavcodec/v4l2_request.c ++++ b/libavcodec/v4l2_request.c +@@ -376,6 +376,42 @@ int ff_v4l2_request_decode_frame(AVCodecContext *avctx, AVFrame *frame, struct v + return v4l2_request_queue_decode(avctx, frame, control, count, 1, 1); + } + ++static int v4l2_request_try_framesize(AVCodecContext *avctx, uint32_t pixelformat) ++{ ++ V4L2RequestContext *ctx = avctx->internal->hwaccel_priv_data; ++ struct v4l2_frmsizeenum frmsize = { ++ .index = 0, ++ .pixel_format = pixelformat, ++ }; ++ ++ if (ioctl(ctx->video_fd, VIDIOC_ENUM_FRAMESIZES, &frmsize) < 0) ++ return 0; ++ ++ /* ++ * We only validate min/max framesize for V4L2_FRMSIZE_TYPE_STEPWISE here, since the alignment ++ * which is eventually needed will be done driver-side later in VIDIOC_S_FMT and there is no need ++ * validate step_width/step_height here ++ */ ++ ++ do { ++ ++ if (frmsize.type == V4L2_FRMSIZE_TYPE_DISCRETE && frmsize.discrete.width == avctx->coded_width && ++ frmsize.discrete.height == avctx->coded_height) ++ return 0; ++ else if ((frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE || frmsize.type == V4L2_FRMSIZE_TYPE_CONTINUOUS) && ++ avctx->coded_width >= frmsize.stepwise.min_width && avctx->coded_height >= frmsize.stepwise.min_height && ++ avctx->coded_width <= frmsize.stepwise.max_width && avctx->coded_height <= frmsize.stepwise.max_height) ++ return 0; ++ ++ frmsize.index++; ++ ++ } while (ioctl(ctx->video_fd, VIDIOC_ENUM_FRAMESIZES, &frmsize) >= 0); ++ ++ av_log(avctx, AV_LOG_INFO, "%s: pixelformat %u not supported for width %u height %u\n", __func__, pixelformat, avctx->coded_width, avctx->coded_height); ++ ++ return -1; ++} ++ + static int v4l2_request_try_format(AVCodecContext *avctx, enum v4l2_buf_type type, uint32_t pixelformat) + { + V4L2RequestContext *ctx = avctx->internal->hwaccel_priv_data; +@@ -404,7 +440,7 @@ static int v4l2_request_try_format(AVCodecContext *avctx, enum v4l2_buf_type typ + + while (ioctl(ctx->video_fd, VIDIOC_ENUM_FMT, &fmtdesc) >= 0) { + if (fmtdesc.pixelformat == pixelformat) +- return 0; ++ return v4l2_request_try_framesize(avctx, pixelformat); + + fmtdesc.index++; + }