mirror of
https://github.com/LibreELEC/LibreELEC.tv.git
synced 2025-07-29 13:46:49 +00:00
ffmpeg: drop all local patches
Signed-off-by: Matthias Reichl <hias@horus.com>
This commit is contained in:
parent
54ea2ebba8
commit
d5d98b3f7b
@ -24,7 +24,6 @@ if [ "${V4L2_SUPPORT}" = "yes" ]; then
|
||||
PKG_FFMPEG_V4L2="--enable-v4l2_m2m --enable-libdrm"
|
||||
|
||||
if [ "${PROJECT}" = "RPi" ]; then
|
||||
PKG_PATCH_DIRS+=" v4l2-rpi"
|
||||
PKG_FFMPEG_RPI="--disable-rpi --disable-mmal"
|
||||
if [ "${DEVICE}" = "RPi4" ]; then
|
||||
PKG_DEPENDS_TARGET+=" systemd"
|
||||
@ -35,8 +34,6 @@ if [ "${V4L2_SUPPORT}" = "yes" ]; then
|
||||
--disable-hwaccel=mpeg2_v4l2request \
|
||||
--disable-hwaccel=vp8_v4l2request"
|
||||
fi
|
||||
else
|
||||
PKG_PATCH_DIRS+=" v4l2"
|
||||
fi
|
||||
else
|
||||
PKG_FFMPEG_V4L2="--disable-v4l2_m2m"
|
||||
@ -61,7 +58,6 @@ fi
|
||||
if [ "${PROJECT}" = "Allwinner" -o "${PROJECT}" = "Rockchip" ]; then
|
||||
PKG_DEPENDS_TARGET+=" libdrm systemd" # systemd is needed for libudev
|
||||
PKG_NEED_UNPACK+=" $(get_pkg_directory libdrm) $(get_pkg_directory systemd)"
|
||||
PKG_PATCH_DIRS+=" v4l2-request-api"
|
||||
PKG_FFMPEG_V4L2_REQUEST="--enable-v4l2-request --enable-libudev --enable-libdrm"
|
||||
fi
|
||||
|
||||
|
@ -1,47 +0,0 @@
|
||||
From 85417a4ba42360248b4999e458a6e05c1c2f9b17 Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Sat, 4 Mar 2017 19:24:02 +0000
|
||||
Subject: [PATCH] ffmpeg: Call get_format to fix an issue with MMAL rendering
|
||||
|
||||
---
|
||||
libavcodec/dvdec.c | 6 ++++++
|
||||
libavcodec/rv34.c | 6 +++++-
|
||||
2 files changed, 11 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libavcodec/dvdec.c b/libavcodec/dvdec.c
|
||||
index 89864f2edc..b5f9224d72 100644
|
||||
--- a/libavcodec/dvdec.c
|
||||
+++ b/libavcodec/dvdec.c
|
||||
@@ -197,6 +197,12 @@ static av_cold int dvvideo_decode_init(AVCodecContext *avctx)
|
||||
s->idct_put[0] = idsp.idct_put;
|
||||
s->idct_put[1] = ff_simple_idct248_put;
|
||||
|
||||
+ static const enum AVPixelFormat pix_fmts[] = {
|
||||
+ AV_PIX_FMT_YUV420P,
|
||||
+ AV_PIX_FMT_NONE
|
||||
+ };
|
||||
+ avctx->pix_fmt = ff_get_format(avctx, pix_fmts);
|
||||
+
|
||||
return ff_dvvideo_init(avctx);
|
||||
}
|
||||
|
||||
diff --git a/libavcodec/rv34.c b/libavcodec/rv34.c
|
||||
index d171e6e1bd..f6f0aa1f74 100644
|
||||
--- a/libavcodec/rv34.c
|
||||
+++ b/libavcodec/rv34.c
|
||||
@@ -1499,7 +1499,11 @@ av_cold int ff_rv34_decode_init(AVCodecContext *avctx)
|
||||
ff_mpv_decode_init(s, avctx);
|
||||
s->out_format = FMT_H263;
|
||||
|
||||
- avctx->pix_fmt = AV_PIX_FMT_YUV420P;
|
||||
+ static const enum AVPixelFormat pix_fmts[] = {
|
||||
+ AV_PIX_FMT_YUV420P,
|
||||
+ AV_PIX_FMT_NONE
|
||||
+ };
|
||||
+ avctx->pix_fmt = ff_get_format(avctx, pix_fmts);
|
||||
avctx->has_b_frames = 1;
|
||||
s->low_delay = 0;
|
||||
|
||||
--
|
||||
2.20.1
|
||||
|
@ -1,48 +0,0 @@
|
||||
From 848de6c1923820f1de49ed7875d6c8877d0c321c Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Fri, 5 Jun 2015 22:48:33 +0100
|
||||
Subject: [PATCH] mpeg4video: Signal unsupported GMC with more than one warp
|
||||
point
|
||||
|
||||
---
|
||||
libavcodec/avcodec.h | 1 +
|
||||
libavcodec/mpeg4videodec.c | 4 ++++
|
||||
2 files changed, 5 insertions(+)
|
||||
|
||||
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
|
||||
index a36b675fba..880284d5bd 100644
|
||||
--- a/libavcodec/avcodec.h
|
||||
+++ b/libavcodec/avcodec.h
|
||||
@@ -2612,6 +2612,7 @@ typedef struct AVCodecContext {
|
||||
#define FF_BUG_MS 8192 ///< Work around various bugs in Microsoft's broken decoders.
|
||||
#define FF_BUG_TRUNCATED 16384
|
||||
#define FF_BUG_IEDGE 32768
|
||||
+#define FF_BUG_GMC_UNSUPPORTED (1<<30)
|
||||
|
||||
/**
|
||||
* strictly follow the standard (MPEG-4, ...).
|
||||
diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c
|
||||
index 055afabc7e..fa208660c8 100644
|
||||
--- a/libavcodec/mpeg4videodec.c
|
||||
+++ b/libavcodec/mpeg4videodec.c
|
||||
@@ -2662,6 +2662,9 @@ int ff_mpeg4_workaround_bugs(AVCodecContext *avctx)
|
||||
|
||||
if (ctx->divx_version >= 0)
|
||||
s->workaround_bugs |= FF_BUG_HPEL_CHROMA;
|
||||
+
|
||||
+ if (ctx->num_sprite_warping_points > 1)
|
||||
+ s->workaround_bugs |= FF_BUG_GMC_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if (s->workaround_bugs & FF_BUG_STD_QPEL) {
|
||||
@@ -2686,6 +2689,7 @@ int ff_mpeg4_workaround_bugs(AVCodecContext *avctx)
|
||||
s->workaround_bugs, ctx->lavc_build, ctx->xvid_build,
|
||||
ctx->divx_version, ctx->divx_build, s->divx_packed ? "p" : "");
|
||||
|
||||
+ avctx->workaround_bugs = s->workaround_bugs;
|
||||
if (CONFIG_MPEG4_DECODER && ctx->xvid_build >= 0 &&
|
||||
s->codec_id == AV_CODEC_ID_MPEG4 &&
|
||||
avctx->idct_algo == FF_IDCT_AUTO) {
|
||||
--
|
||||
2.20.1
|
||||
|
@ -1,269 +0,0 @@
|
||||
From a853a9c70339c30ea4d5081366fee4bb84bc09c5 Mon Sep 17 00:00:00 2001
|
||||
From: Hendrik Leppkes <h.leppkes@gmail.com>
|
||||
Date: Sat, 9 Jan 2016 16:34:09 +0100
|
||||
Subject: [PATCH 1/4] avcodec: add h264_mvc codec id and profiles
|
||||
|
||||
---
|
||||
libavcodec/avcodec.h | 3 +++
|
||||
libavcodec/codec_desc.c | 7 +++++++
|
||||
libavcodec/profiles.c | 1 +
|
||||
libavformat/mpegts.c | 2 +-
|
||||
4 files changed, 12 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
|
||||
index 880284d5bd..88e01645cd 100644
|
||||
--- a/libavcodec/avcodec.h
|
||||
+++ b/libavcodec/avcodec.h
|
||||
@@ -458,6 +458,8 @@ enum AVCodecID {
|
||||
AV_CODEC_ID_LSCR,
|
||||
AV_CODEC_ID_VP4,
|
||||
|
||||
+ AV_CODEC_ID_H264_MVC,
|
||||
+
|
||||
/* various PCM "codecs" */
|
||||
AV_CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs
|
||||
AV_CODEC_ID_PCM_S16LE = 0x10000,
|
||||
@@ -2950,6 +2952,7 @@ typedef struct AVCodecContext {
|
||||
#define FF_PROFILE_H264_HIGH_444_PREDICTIVE 244
|
||||
#define FF_PROFILE_H264_HIGH_444_INTRA (244|FF_PROFILE_H264_INTRA)
|
||||
#define FF_PROFILE_H264_CAVLC_444 44
|
||||
+#define FF_PROFILE_H264_MULTIVIEW_HIGH_DEPTH 138
|
||||
|
||||
#define FF_PROFILE_VC1_SIMPLE 0
|
||||
#define FF_PROFILE_VC1_MAIN 1
|
||||
diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c
|
||||
index 4d033c20ff..def006e033 100644
|
||||
--- a/libavcodec/codec_desc.c
|
||||
+++ b/libavcodec/codec_desc.c
|
||||
@@ -1726,6 +1726,13 @@ static const AVCodecDescriptor codec_descriptors[] = {
|
||||
.long_name = NULL_IF_CONFIG_SMALL("On2 VP4"),
|
||||
.props = AV_CODEC_PROP_LOSSY,
|
||||
},
|
||||
+ {
|
||||
+ .id = AV_CODEC_ID_H264_MVC,
|
||||
+ .type = AVMEDIA_TYPE_VIDEO,
|
||||
+ .name = "h264_mvc",
|
||||
+ .long_name = NULL_IF_CONFIG_SMALL("H264 MVC"),
|
||||
+ .props = AV_CODEC_PROP_LOSSY,
|
||||
+ },
|
||||
|
||||
/* various PCM "codecs" */
|
||||
{
|
||||
diff --git a/libavcodec/profiles.c b/libavcodec/profiles.c
|
||||
index eaf0d68d32..fc1e152420 100644
|
||||
--- a/libavcodec/profiles.c
|
||||
+++ b/libavcodec/profiles.c
|
||||
@@ -71,6 +71,7 @@ const AVProfile ff_h264_profiles[] = {
|
||||
{ FF_PROFILE_H264_CAVLC_444, "CAVLC 4:4:4" },
|
||||
{ FF_PROFILE_H264_MULTIVIEW_HIGH, "Multiview High" },
|
||||
{ FF_PROFILE_H264_STEREO_HIGH, "Stereo High" },
|
||||
+ { FF_PROFILE_H264_MULTIVIEW_HIGH_DEPTH, "Multiview High Depth" },
|
||||
{ FF_PROFILE_UNKNOWN },
|
||||
};
|
||||
|
||||
diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
|
||||
index 0415ceea02..264bf9718b 100644
|
||||
--- a/libavformat/mpegts.c
|
||||
+++ b/libavformat/mpegts.c
|
||||
@@ -798,7 +798,7 @@ static const StreamType ISO_types[] = {
|
||||
#endif
|
||||
{ 0x1b, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_H264 },
|
||||
{ 0x1c, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AAC },
|
||||
- { 0x20, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_H264 },
|
||||
+ { 0x20, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_H264_MVC },
|
||||
{ 0x21, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_JPEG2000 },
|
||||
{ 0x24, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_HEVC },
|
||||
{ 0x42, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_CAVS },
|
||||
--
|
||||
2.20.1
|
||||
|
||||
|
||||
From 8d479b1b5395f97a8e5ee0eddab6680941edfb5b Mon Sep 17 00:00:00 2001
|
||||
From: Hendrik Leppkes <h.leppkes@gmail.com>
|
||||
Date: Sat, 9 Jan 2016 16:34:40 +0100
|
||||
Subject: [PATCH 2/4] h264_parser: add support for parsing h264 mvc NALUs
|
||||
|
||||
---
|
||||
libavcodec/h264_parser.c | 34 ++++++++++++++++++++++++++++++----
|
||||
libavcodec/parsers.c | 1 +
|
||||
2 files changed, 31 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c
|
||||
index 5f9a9c46ef..991e8e82f3 100644
|
||||
--- a/libavcodec/h264_parser.c
|
||||
+++ b/libavcodec/h264_parser.c
|
||||
@@ -62,6 +62,7 @@ typedef struct H264ParseContext {
|
||||
int parse_last_mb;
|
||||
int64_t reference_dts;
|
||||
int last_frame_num, last_picture_structure;
|
||||
+ int is_mvc;
|
||||
} H264ParseContext;
|
||||
|
||||
|
||||
@@ -109,14 +110,18 @@ static int h264_find_frame_end(H264ParseContext *p, const uint8_t *buf,
|
||||
} else if (state <= 5) {
|
||||
int nalu_type = buf[i] & 0x1F;
|
||||
if (nalu_type == H264_NAL_SEI || nalu_type == H264_NAL_SPS ||
|
||||
- nalu_type == H264_NAL_PPS || nalu_type == H264_NAL_AUD) {
|
||||
+ nalu_type == H264_NAL_PPS || nalu_type == H264_NAL_AUD ||
|
||||
+ nalu_type == H264_NAL_SUB_SPS) {
|
||||
if (pc->frame_start_found) {
|
||||
i++;
|
||||
goto found;
|
||||
}
|
||||
} else if (nalu_type == H264_NAL_SLICE || nalu_type == H264_NAL_DPA ||
|
||||
- nalu_type == H264_NAL_IDR_SLICE) {
|
||||
+ nalu_type == H264_NAL_IDR_SLICE || (p->is_mvc && nalu_type == H264_NAL_EXTEN_SLICE)) {
|
||||
state += 8;
|
||||
+
|
||||
+ if (nalu_type == H264_NAL_EXTEN_SLICE)
|
||||
+ i += 3; // skip mvc extension
|
||||
continue;
|
||||
}
|
||||
state = 7;
|
||||
@@ -604,7 +609,8 @@ static int h264_parse(AVCodecParserContext *s,
|
||||
}
|
||||
}
|
||||
|
||||
- parse_nal_units(s, avctx, buf, buf_size);
|
||||
+ if (!p->is_mvc)
|
||||
+ parse_nal_units(s, avctx, buf, buf_size);
|
||||
|
||||
if (avctx->framerate.num)
|
||||
avctx->time_base = av_inv_q(av_mul_q(avctx->framerate, (AVRational){avctx->ticks_per_frame, 1}));
|
||||
@@ -661,7 +667,7 @@ static int h264_split(AVCodecContext *avctx,
|
||||
if ((state & 0xFFFFFF00) != 0x100)
|
||||
break;
|
||||
nalu_type = state & 0x1F;
|
||||
- if (nalu_type == H264_NAL_SPS) {
|
||||
+ if (nalu_type == H264_NAL_SPS || nalu_type == H264_NAL_SUB_SPS) {
|
||||
has_sps = 1;
|
||||
} else if (nalu_type == H264_NAL_PPS)
|
||||
has_pps = 1;
|
||||
@@ -713,3 +719,23 @@ AVCodecParser ff_h264_parser = {
|
||||
.parser_close = h264_close,
|
||||
.split = h264_split,
|
||||
};
|
||||
+
|
||||
+static av_cold int init_mvc(AVCodecParserContext *s)
|
||||
+{
|
||||
+ H264ParseContext *p = s->priv_data;
|
||||
+ int ret = init(s);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ p->is_mvc = 1;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+AVCodecParser ff_h264_mvc_parser = {
|
||||
+ .codec_ids = { AV_CODEC_ID_H264_MVC },
|
||||
+ .priv_data_size = sizeof(H264ParseContext),
|
||||
+ .parser_init = init_mvc,
|
||||
+ .parser_parse = h264_parse,
|
||||
+ .parser_close = h264_close,
|
||||
+ .split = h264_split,
|
||||
+};
|
||||
diff --git a/libavcodec/parsers.c b/libavcodec/parsers.c
|
||||
index 33a71de8a0..80b269b324 100644
|
||||
--- a/libavcodec/parsers.c
|
||||
+++ b/libavcodec/parsers.c
|
||||
@@ -47,6 +47,7 @@ extern AVCodecParser ff_gsm_parser;
|
||||
extern AVCodecParser ff_h261_parser;
|
||||
extern AVCodecParser ff_h263_parser;
|
||||
extern AVCodecParser ff_h264_parser;
|
||||
+extern AVCodecParser ff_h264_mvc_parser;
|
||||
extern AVCodecParser ff_hevc_parser;
|
||||
extern AVCodecParser ff_mjpeg_parser;
|
||||
extern AVCodecParser ff_mlp_parser;
|
||||
--
|
||||
2.20.1
|
||||
|
||||
|
||||
From e2cad00490c9cd339b9266e8b9fe5d86afe2abe1 Mon Sep 17 00:00:00 2001
|
||||
From: Hendrik Leppkes <h.leppkes@gmail.com>
|
||||
Date: Tue, 28 Nov 2017 16:12:12 +0000
|
||||
Subject: [PATCH 3/4] h264_parser: force grabing a new timestamp until a frame
|
||||
start was found
|
||||
|
||||
---
|
||||
libavcodec/h264_parser.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c
|
||||
index 991e8e82f3..f573bd8629 100644
|
||||
--- a/libavcodec/h264_parser.c
|
||||
+++ b/libavcodec/h264_parser.c
|
||||
@@ -597,6 +597,9 @@ static int h264_parse(AVCodecParserContext *s,
|
||||
} else {
|
||||
next = h264_find_frame_end(p, buf, buf_size, avctx);
|
||||
|
||||
+ if (next == END_NOT_FOUND && pc->frame_start_found == 0)
|
||||
+ s->fetch_timestamp = 1;
|
||||
+
|
||||
if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
|
||||
*poutbuf = NULL;
|
||||
*poutbuf_size = 0;
|
||||
--
|
||||
2.20.1
|
||||
|
||||
|
||||
From fc2954e5eba1791443016cdd17fcea280f464db5 Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Mon, 28 May 2018 13:35:36 +0100
|
||||
Subject: [PATCH 4/4] fixup
|
||||
|
||||
---
|
||||
libavcodec/extract_extradata_bsf.c | 8 +++++---
|
||||
1 file changed, 5 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/libavcodec/extract_extradata_bsf.c b/libavcodec/extract_extradata_bsf.c
|
||||
index 85cf615ffa..b5f1657528 100644
|
||||
--- a/libavcodec/extract_extradata_bsf.c
|
||||
+++ b/libavcodec/extract_extradata_bsf.c
|
||||
@@ -138,7 +138,7 @@ static int extract_extradata_h2645(AVBSFContext *ctx, AVPacket *pkt,
|
||||
HEVC_NAL_VPS, HEVC_NAL_SPS, HEVC_NAL_PPS,
|
||||
};
|
||||
static const int extradata_nal_types_h264[] = {
|
||||
- H264_NAL_SPS, H264_NAL_PPS,
|
||||
+ H264_NAL_SPS, H264_NAL_SUB_SPS, H264_NAL_PPS,
|
||||
};
|
||||
|
||||
ExtractExtradataContext *s = ctx->priv_data;
|
||||
@@ -169,7 +169,7 @@ static int extract_extradata_h2645(AVBSFContext *ctx, AVPacket *pkt,
|
||||
if (nal->type == HEVC_NAL_SPS) has_sps = 1;
|
||||
if (nal->type == HEVC_NAL_VPS) has_vps = 1;
|
||||
} else {
|
||||
- if (nal->type == H264_NAL_SPS) has_sps = 1;
|
||||
+ if (nal->type == H264_NAL_SPS || nal->type == H264_NAL_SUB_SPS) has_sps = 1;
|
||||
}
|
||||
} else if (s->remove) {
|
||||
filtered_size += nal->raw_size + 3;
|
||||
@@ -178,7 +178,7 @@ static int extract_extradata_h2645(AVBSFContext *ctx, AVPacket *pkt,
|
||||
|
||||
if (extradata_size &&
|
||||
((ctx->par_in->codec_id == AV_CODEC_ID_HEVC && has_sps && has_vps) ||
|
||||
- (ctx->par_in->codec_id == AV_CODEC_ID_H264 && has_sps))) {
|
||||
+ ((ctx->par_in->codec_id == AV_CODEC_ID_H264 || ctx->par_in->codec_id == AV_CODEC_ID_H264_MVC) && has_sps))) {
|
||||
AVBufferRef *filtered_buf = NULL;
|
||||
uint8_t *extradata, *filtered_data;
|
||||
|
||||
@@ -334,6 +334,7 @@ static const struct {
|
||||
{ AV_CODEC_ID_AVS2, extract_extradata_mpeg4 },
|
||||
{ AV_CODEC_ID_CAVS, extract_extradata_mpeg4 },
|
||||
{ AV_CODEC_ID_H264, extract_extradata_h2645 },
|
||||
+ { AV_CODEC_ID_H264_MVC, extract_extradata_h2645 },
|
||||
{ AV_CODEC_ID_HEVC, extract_extradata_h2645 },
|
||||
{ AV_CODEC_ID_MPEG1VIDEO, extract_extradata_mpeg12 },
|
||||
{ AV_CODEC_ID_MPEG2VIDEO, extract_extradata_mpeg12 },
|
||||
@@ -401,6 +402,7 @@ static const enum AVCodecID codec_ids[] = {
|
||||
AV_CODEC_ID_AVS2,
|
||||
AV_CODEC_ID_CAVS,
|
||||
AV_CODEC_ID_H264,
|
||||
+ AV_CODEC_ID_H264_MVC,
|
||||
AV_CODEC_ID_HEVC,
|
||||
AV_CODEC_ID_MPEG1VIDEO,
|
||||
AV_CODEC_ID_MPEG2VIDEO,
|
||||
--
|
||||
2.20.1
|
||||
|
@ -1,45 +0,0 @@
|
||||
commit 578b5ee8c0fe7d9ef09ef91ffcafc916f1d7d97b
|
||||
Author: Lukas Rusak <lorusak@gmail.com>
|
||||
Date: Wed Apr 10 13:39:21 2019 -0700
|
||||
|
||||
libavcodec/libdav1d: add libdav1d_get_format method to call ff_get_format
|
||||
|
||||
This will allow applications to properly init the decoder in
|
||||
cases where a hardware decoder is tried first and and software
|
||||
decoder is tried after by calling the get_format callback.
|
||||
|
||||
Even though there is no hardware pixel formats available
|
||||
we still need to return the software pixel format.
|
||||
|
||||
Tested with Kodi by checking if multithreaded software
|
||||
decoding is properly activated.
|
||||
|
||||
diff --git a/libavcodec/libdav1d.c b/libavcodec/libdav1d.c
|
||||
index 12c63245f8..1bbb83eda3 100644
|
||||
--- a/libavcodec/libdav1d.c
|
||||
+++ b/libavcodec/libdav1d.c
|
||||
@@ -53,6 +53,16 @@ static const enum AVPixelFormat pix_fmt_rgb[3] = {
|
||||
AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRP12,
|
||||
};
|
||||
|
||||
+static enum AVPixelFormat libdav1d_get_format(AVCodecContext *avctx, const Dav1dPicture *p)
|
||||
+{
|
||||
+ enum AVPixelFormat pix_fmts[2], *fmt = pix_fmts;
|
||||
+
|
||||
+ *fmt++ = pix_fmt[p->p.layout][p->seq_hdr->hbd];
|
||||
+ *fmt = AV_PIX_FMT_NONE;
|
||||
+
|
||||
+ return ff_get_format(avctx, pix_fmts);
|
||||
+}
|
||||
+
|
||||
static void libdav1d_log_callback(void *opaque, const char *fmt, va_list vl)
|
||||
{
|
||||
AVCodecContext *c = opaque;
|
||||
@@ -229,6 +239,7 @@ static int libdav1d_receive_frame(AVCodecContext *c, AVFrame *frame)
|
||||
c->profile = p->seq_hdr->profile;
|
||||
c->level = ((p->seq_hdr->operating_points[0].major_level - 2) << 2)
|
||||
| p->seq_hdr->operating_points[0].minor_level;
|
||||
+ frame->format = c->pix_fmt = libdav1d_get_format(c, p);
|
||||
frame->width = p->p.w;
|
||||
frame->height = p->p.h;
|
||||
if (c->width != p->p.w || c->height != p->p.h) {
|
@ -1,13 +0,0 @@
|
||||
--- a/libswscale/yuv2rgb.c 2018-07-22 10:00:00.000000000 +0100
|
||||
+++ b/libswscale/yuv2rgb.c 2018-08-20 11:55:46.391543992 +0100
|
||||
@@ -687,10 +687,6 @@ SwsFunc ff_yuv2rgb_get_func_ptr(SwsConte
|
||||
if (t)
|
||||
return t;
|
||||
|
||||
- av_log(c, AV_LOG_WARNING,
|
||||
- "No accelerated colorspace conversion found from %s to %s.\n",
|
||||
- av_get_pix_fmt_name(c->srcFormat), av_get_pix_fmt_name(c->dstFormat));
|
||||
-
|
||||
switch (c->dstFormat) {
|
||||
case AV_PIX_FMT_BGR48BE:
|
||||
case AV_PIX_FMT_BGR48LE:
|
File diff suppressed because it is too large
Load Diff
@ -1,51 +0,0 @@
|
||||
From 3710124dd57ede7588884ecc86cbcaee5d530498 Mon Sep 17 00:00:00 2001
|
||||
From: Jonas Karlman <jonas@kwiboo.se>
|
||||
Date: Mon, 3 Dec 2018 23:48:04 +0100
|
||||
Subject: [PATCH 01/12] avutil: add av_buffer_pool_flush()
|
||||
|
||||
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
||||
---
|
||||
libavutil/buffer.c | 13 +++++++++++++
|
||||
libavutil/buffer.h | 5 +++++
|
||||
2 files changed, 18 insertions(+)
|
||||
|
||||
diff --git a/libavutil/buffer.c b/libavutil/buffer.c
|
||||
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_flush(AVBufferPool *pool)
|
||||
+{
|
||||
+ ff_mutex_lock(&pool->mutex);
|
||||
+ while (pool->pool) {
|
||||
+ BufferPoolEntry *buf = pool->pool;
|
||||
+ pool->pool = buf->next;
|
||||
+
|
||||
+ buf->free(buf->opaque, buf->data);
|
||||
+ av_freep(&buf);
|
||||
+ }
|
||||
+ ff_mutex_unlock(&pool->mutex);
|
||||
+}
|
||||
+
|
||||
void av_buffer_pool_uninit(AVBufferPool **ppool)
|
||||
{
|
||||
AVBufferPool *pool;
|
||||
diff --git a/libavutil/buffer.h b/libavutil/buffer.h
|
||||
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,
|
||||
AVBufferRef* (*alloc)(void *opaque, int size),
|
||||
void (*pool_free)(void *opaque));
|
||||
|
||||
+/**
|
||||
+ * Free all available buffers in a buffer 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
|
File diff suppressed because it is too large
Load Diff
@ -1,244 +0,0 @@
|
||||
From 279092b1ef7cb944c513167dd55861ff2f2bb473 Mon Sep 17 00:00:00 2001
|
||||
From: Jonas Karlman <jonas@kwiboo.se>
|
||||
Date: Sat, 15 Dec 2018 22:32:16 +0100
|
||||
Subject: [PATCH 03/12] Add V4L2 request API mpeg2 hwaccel
|
||||
|
||||
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
||||
---
|
||||
configure | 3 +
|
||||
libavcodec/Makefile | 1 +
|
||||
libavcodec/hwaccels.h | 1 +
|
||||
libavcodec/mpeg12dec.c | 6 ++
|
||||
libavcodec/v4l2_request_mpeg2.c | 154 ++++++++++++++++++++++++++++++++
|
||||
5 files changed, 165 insertions(+)
|
||||
create mode 100644 libavcodec/v4l2_request_mpeg2.c
|
||||
|
||||
diff --git a/configure b/configure
|
||||
index 6b41344dfd..e88c201cce 100755
|
||||
--- a/configure
|
||||
+++ b/configure
|
||||
@@ -2937,6 +2937,8 @@ mpeg2_dxva2_hwaccel_deps="dxva2"
|
||||
mpeg2_dxva2_hwaccel_select="mpeg2video_decoder"
|
||||
mpeg2_nvdec_hwaccel_deps="nvdec"
|
||||
mpeg2_nvdec_hwaccel_select="mpeg2video_decoder"
|
||||
+mpeg2_v4l2request_hwaccel_deps="v4l2_request mpeg2_v4l2_request"
|
||||
+mpeg2_v4l2request_hwaccel_select="mpeg2video_decoder"
|
||||
mpeg2_vaapi_hwaccel_deps="vaapi"
|
||||
mpeg2_vaapi_hwaccel_select="mpeg2video_decoder"
|
||||
mpeg2_vdpau_hwaccel_deps="vdpau"
|
||||
@@ -6455,6 +6457,7 @@ check_cc vp8_v4l2_m2m linux/videodev2.h "int i = V4L2_PIX_FMT_VP8;"
|
||||
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 mpeg2_v4l2_request linux/videodev2.h "int i = V4L2_PIX_FMT_MPEG2_SLICE;"
|
||||
|
||||
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 9e847eeadc..864f24a2af 100644
|
||||
--- a/libavcodec/Makefile
|
||||
+++ b/libavcodec/Makefile
|
||||
@@ -891,6 +891,7 @@ OBJS-$(CONFIG_MPEG2_D3D11VA_HWACCEL) += dxva2_mpeg2.o
|
||||
OBJS-$(CONFIG_MPEG2_DXVA2_HWACCEL) += dxva2_mpeg2.o
|
||||
OBJS-$(CONFIG_MPEG2_NVDEC_HWACCEL) += nvdec_mpeg12.o
|
||||
OBJS-$(CONFIG_MPEG2_QSV_HWACCEL) += qsvdec_other.o
|
||||
+OBJS-$(CONFIG_MPEG2_V4L2REQUEST_HWACCEL) += v4l2_request_mpeg2.o
|
||||
OBJS-$(CONFIG_MPEG2_VAAPI_HWACCEL) += vaapi_mpeg2.o
|
||||
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 7d73da8676..ef54de2a3b 100644
|
||||
--- a/libavcodec/hwaccels.h
|
||||
+++ b/libavcodec/hwaccels.h
|
||||
@@ -47,6 +47,7 @@ extern const AVHWAccel ff_mpeg2_d3d11va_hwaccel;
|
||||
extern const AVHWAccel ff_mpeg2_d3d11va2_hwaccel;
|
||||
extern const AVHWAccel ff_mpeg2_nvdec_hwaccel;
|
||||
extern const AVHWAccel ff_mpeg2_dxva2_hwaccel;
|
||||
+extern const AVHWAccel ff_mpeg2_v4l2request_hwaccel;
|
||||
extern const AVHWAccel ff_mpeg2_vaapi_hwaccel;
|
||||
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 83e537884b..305127bc94 100644
|
||||
--- a/libavcodec/mpeg12dec.c
|
||||
+++ b/libavcodec/mpeg12dec.c
|
||||
@@ -1156,6 +1156,9 @@ static const enum AVPixelFormat mpeg2_hwaccel_pixfmt_list_420[] = {
|
||||
#endif
|
||||
#if CONFIG_MPEG2_VIDEOTOOLBOX_HWACCEL
|
||||
AV_PIX_FMT_VIDEOTOOLBOX,
|
||||
+#endif
|
||||
+#if CONFIG_MPEG2_V4L2REQUEST_HWACCEL
|
||||
+ AV_PIX_FMT_DRM_PRIME,
|
||||
#endif
|
||||
AV_PIX_FMT_YUV420P,
|
||||
AV_PIX_FMT_NONE
|
||||
@@ -2941,6 +2944,9 @@ AVCodec ff_mpeg2video_decoder = {
|
||||
#endif
|
||||
#if CONFIG_MPEG2_XVMC_HWACCEL
|
||||
HWACCEL_XVMC(mpeg2),
|
||||
+#endif
|
||||
+#if CONFIG_MPEG2_V4L2REQUEST_HWACCEL
|
||||
+ HWACCEL_V4L2REQUEST(mpeg2),
|
||||
#endif
|
||||
NULL
|
||||
},
|
||||
diff --git a/libavcodec/v4l2_request_mpeg2.c b/libavcodec/v4l2_request_mpeg2.c
|
||||
new file mode 100644
|
||||
index 0000000000..782b9c2471
|
||||
--- /dev/null
|
||||
+++ b/libavcodec/v4l2_request_mpeg2.c
|
||||
@@ -0,0 +1,154 @@
|
||||
+/*
|
||||
+ * 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 "mpegvideo.h"
|
||||
+#include "v4l2_request.h"
|
||||
+
|
||||
+typedef struct V4L2RequestControlsMPEG2 {
|
||||
+ struct v4l2_ctrl_mpeg2_slice_params slice_params;
|
||||
+ struct v4l2_ctrl_mpeg2_quantization quantization;
|
||||
+} V4L2RequestControlsMPEG2;
|
||||
+
|
||||
+static int v4l2_request_mpeg2_start_frame(AVCodecContext *avctx,
|
||||
+ av_unused const uint8_t *buffer,
|
||||
+ av_unused uint32_t size)
|
||||
+{
|
||||
+ const MpegEncContext *s = avctx->priv_data;
|
||||
+ V4L2RequestControlsMPEG2 *controls = s->current_picture_ptr->hwaccel_picture_private;
|
||||
+ V4L2RequestDescriptor *req = (V4L2RequestDescriptor*)s->current_picture_ptr->f->data[0];
|
||||
+
|
||||
+ controls->slice_params = (struct v4l2_ctrl_mpeg2_slice_params) {
|
||||
+ .bit_size = 0,
|
||||
+ .data_bit_offset = 0,
|
||||
+
|
||||
+ /* ISO/IEC 13818-2, ITU-T Rec. H.262: Slice */
|
||||
+ .quantiser_scale_code = s->qscale >> 1,
|
||||
+
|
||||
+ .sequence = {
|
||||
+ /* ISO/IEC 13818-2, ITU-T Rec. H.262: Sequence header */
|
||||
+ .horizontal_size = s->width,
|
||||
+ .vertical_size = s->height,
|
||||
+ .vbv_buffer_size = req->output.size,
|
||||
+
|
||||
+ /* ISO/IEC 13818-2, ITU-T Rec. H.262: Sequence extension */
|
||||
+ .profile_and_level_indication = 0,
|
||||
+ .progressive_sequence = s->progressive_sequence,
|
||||
+ .chroma_format = s->chroma_format,
|
||||
+ },
|
||||
+
|
||||
+ .picture = {
|
||||
+ /* ISO/IEC 13818-2, ITU-T Rec. H.262: Picture header */
|
||||
+ .picture_coding_type = s->pict_type,
|
||||
+
|
||||
+ /* ISO/IEC 13818-2, ITU-T Rec. H.262: Picture coding extension */
|
||||
+ .f_code[0][0] = s->mpeg_f_code[0][0],
|
||||
+ .f_code[0][1] = s->mpeg_f_code[0][1],
|
||||
+ .f_code[1][0] = s->mpeg_f_code[1][0],
|
||||
+ .f_code[1][1] = s->mpeg_f_code[1][1],
|
||||
+ .intra_dc_precision = s->intra_dc_precision,
|
||||
+ .picture_structure = s->picture_structure,
|
||||
+ .top_field_first = s->top_field_first,
|
||||
+ .frame_pred_frame_dct = s->frame_pred_frame_dct,
|
||||
+ .concealment_motion_vectors = s->concealment_motion_vectors,
|
||||
+ .q_scale_type = s->q_scale_type,
|
||||
+ .intra_vlc_format = s->intra_vlc_format,
|
||||
+ .alternate_scan = s->alternate_scan,
|
||||
+ .repeat_first_field = s->repeat_first_field,
|
||||
+ .progressive_frame = s->progressive_frame,
|
||||
+ },
|
||||
+ };
|
||||
+
|
||||
+ switch (s->pict_type) {
|
||||
+ case AV_PICTURE_TYPE_B:
|
||||
+ controls->slice_params.backward_ref_ts = ff_v4l2_request_get_capture_timestamp(s->next_picture.f);
|
||||
+ // fall-through
|
||||
+ case AV_PICTURE_TYPE_P:
|
||||
+ controls->slice_params.forward_ref_ts = ff_v4l2_request_get_capture_timestamp(s->last_picture.f);
|
||||
+ }
|
||||
+
|
||||
+ controls->quantization = (struct v4l2_ctrl_mpeg2_quantization) {
|
||||
+ /* ISO/IEC 13818-2, ITU-T Rec. H.262: Quant matrix extension */
|
||||
+ .load_intra_quantiser_matrix = 1,
|
||||
+ .load_non_intra_quantiser_matrix = 1,
|
||||
+ .load_chroma_intra_quantiser_matrix = 1,
|
||||
+ .load_chroma_non_intra_quantiser_matrix = 1,
|
||||
+ };
|
||||
+
|
||||
+ for (int i = 0; i < 64; i++) {
|
||||
+ int n = s->idsp.idct_permutation[ff_zigzag_direct[i]];
|
||||
+ controls->quantization.intra_quantiser_matrix[i] = s->intra_matrix[n];
|
||||
+ controls->quantization.non_intra_quantiser_matrix[i] = s->inter_matrix[n];
|
||||
+ controls->quantization.chroma_intra_quantiser_matrix[i] = s->chroma_intra_matrix[n];
|
||||
+ controls->quantization.chroma_non_intra_quantiser_matrix[i] = s->chroma_inter_matrix[n];
|
||||
+ }
|
||||
+
|
||||
+ return ff_v4l2_request_reset_frame(avctx, s->current_picture_ptr->f);
|
||||
+}
|
||||
+
|
||||
+static int v4l2_request_mpeg2_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
|
||||
+{
|
||||
+ const MpegEncContext *s = avctx->priv_data;
|
||||
+
|
||||
+ return ff_v4l2_request_append_output_buffer(avctx, s->current_picture_ptr->f, buffer, size);
|
||||
+}
|
||||
+
|
||||
+static int v4l2_request_mpeg2_end_frame(AVCodecContext *avctx)
|
||||
+{
|
||||
+ const MpegEncContext *s = avctx->priv_data;
|
||||
+ V4L2RequestControlsMPEG2 *controls = s->current_picture_ptr->hwaccel_picture_private;
|
||||
+ V4L2RequestDescriptor *req = (V4L2RequestDescriptor*)s->current_picture_ptr->f->data[0];
|
||||
+
|
||||
+ struct v4l2_ext_control control[] = {
|
||||
+ {
|
||||
+ .id = V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS,
|
||||
+ .ptr = &controls->slice_params,
|
||||
+ .size = sizeof(controls->slice_params),
|
||||
+ },
|
||||
+ {
|
||||
+ .id = V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION,
|
||||
+ .ptr = &controls->quantization,
|
||||
+ .size = sizeof(controls->quantization),
|
||||
+ },
|
||||
+ };
|
||||
+
|
||||
+ controls->slice_params.bit_size = req->output.used * 8;
|
||||
+
|
||||
+ return ff_v4l2_request_decode_frame(avctx, s->current_picture_ptr->f, control, FF_ARRAY_ELEMS(control));
|
||||
+}
|
||||
+
|
||||
+static int v4l2_request_mpeg2_init(AVCodecContext *avctx)
|
||||
+{
|
||||
+ return ff_v4l2_request_init(avctx, V4L2_PIX_FMT_MPEG2_SLICE, 1024 * 1024, NULL, 0);
|
||||
+}
|
||||
+
|
||||
+const AVHWAccel ff_mpeg2_v4l2request_hwaccel = {
|
||||
+ .name = "mpeg2_v4l2request",
|
||||
+ .type = AVMEDIA_TYPE_VIDEO,
|
||||
+ .id = AV_CODEC_ID_MPEG2VIDEO,
|
||||
+ .pix_fmt = AV_PIX_FMT_DRM_PRIME,
|
||||
+ .start_frame = v4l2_request_mpeg2_start_frame,
|
||||
+ .decode_slice = v4l2_request_mpeg2_decode_slice,
|
||||
+ .end_frame = v4l2_request_mpeg2_end_frame,
|
||||
+ .frame_priv_data_size = sizeof(V4L2RequestControlsMPEG2),
|
||||
+ .init = v4l2_request_mpeg2_init,
|
||||
+ .uninit = ff_v4l2_request_uninit,
|
||||
+ .priv_data_size = sizeof(V4L2RequestContext),
|
||||
+ .frame_params = ff_v4l2_request_frame_params,
|
||||
+ .caps_internal = HWACCEL_CAP_ASYNC_SAFE,
|
||||
+};
|
@ -1,547 +0,0 @@
|
||||
From da483a0eb4802714d9ad3a07ea17c2ec0f65c2a5 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Sat, 15 Dec 2018 22:32:16 +0100
|
||||
Subject: [PATCH 04/12] Add V4L2 request API h264 hwaccel
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
||||
---
|
||||
configure | 3 +
|
||||
libavcodec/Makefile | 1 +
|
||||
libavcodec/h264_slice.c | 4 +
|
||||
libavcodec/h264dec.c | 3 +
|
||||
libavcodec/hwaccels.h | 1 +
|
||||
libavcodec/v4l2_request_h264.c | 443 +++++++++++++++++++++++++++++++++
|
||||
6 files changed, 455 insertions(+)
|
||||
create mode 100644 libavcodec/v4l2_request_h264.c
|
||||
|
||||
diff --git a/configure b/configure
|
||||
index e88c201cce..576a79ff09 100755
|
||||
--- a/configure
|
||||
+++ b/configure
|
||||
@@ -2895,6 +2895,8 @@ h264_dxva2_hwaccel_deps="dxva2"
|
||||
h264_dxva2_hwaccel_select="h264_decoder"
|
||||
h264_nvdec_hwaccel_deps="nvdec"
|
||||
h264_nvdec_hwaccel_select="h264_decoder"
|
||||
+h264_v4l2request_hwaccel_deps="v4l2_request h264_v4l2_request"
|
||||
+h264_v4l2request_hwaccel_select="h264_decoder"
|
||||
h264_vaapi_hwaccel_deps="vaapi"
|
||||
h264_vaapi_hwaccel_select="h264_decoder"
|
||||
h264_vdpau_hwaccel_deps="vdpau"
|
||||
@@ -6457,6 +6459,7 @@ check_cc vp8_v4l2_m2m linux/videodev2.h "int i = V4L2_PIX_FMT_VP8;"
|
||||
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;"
|
||||
check_cc mpeg2_v4l2_request linux/videodev2.h "int i = V4L2_PIX_FMT_MPEG2_SLICE;"
|
||||
|
||||
check_headers sys/videoio.h
|
||||
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
|
||||
index 864f24a2af..58bd444934 100644
|
||||
--- a/libavcodec/Makefile
|
||||
+++ b/libavcodec/Makefile
|
||||
@@ -872,6 +872,7 @@ OBJS-$(CONFIG_H264_D3D11VA_HWACCEL) += dxva2_h264.o
|
||||
OBJS-$(CONFIG_H264_DXVA2_HWACCEL) += dxva2_h264.o
|
||||
OBJS-$(CONFIG_H264_NVDEC_HWACCEL) += nvdec_h264.o
|
||||
OBJS-$(CONFIG_H264_QSV_HWACCEL) += qsvdec_h2645.o
|
||||
+OBJS-$(CONFIG_H264_V4L2REQUEST_HWACCEL) += v4l2_request_h264.o
|
||||
OBJS-$(CONFIG_H264_VAAPI_HWACCEL) += vaapi_h264.o
|
||||
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 fc4e65bf01..9912ede703 100644
|
||||
--- a/libavcodec/h264_slice.c
|
||||
+++ b/libavcodec/h264_slice.c
|
||||
@@ -765,6 +765,7 @@ static enum AVPixelFormat get_pixel_format(H264Context *h, int force_callback)
|
||||
#define HWACCEL_MAX (CONFIG_H264_DXVA2_HWACCEL + \
|
||||
(CONFIG_H264_D3D11VA_HWACCEL * 2) + \
|
||||
CONFIG_H264_NVDEC_HWACCEL + \
|
||||
+ CONFIG_H264_V4L2REQUEST_HWACCEL + \
|
||||
CONFIG_H264_VAAPI_HWACCEL + \
|
||||
CONFIG_H264_VIDEOTOOLBOX_HWACCEL + \
|
||||
CONFIG_H264_VDPAU_HWACCEL)
|
||||
@@ -849,6 +850,9 @@ static enum AVPixelFormat get_pixel_format(H264Context *h, int force_callback)
|
||||
#endif
|
||||
#if CONFIG_H264_VIDEOTOOLBOX_HWACCEL
|
||||
*fmt++ = AV_PIX_FMT_VIDEOTOOLBOX;
|
||||
+#endif
|
||||
+#if CONFIG_H264_V4L2REQUEST_HWACCEL
|
||||
+ *fmt++ = AV_PIX_FMT_DRM_PRIME;
|
||||
#endif
|
||||
if (h->avctx->codec->pix_fmts)
|
||||
choices = h->avctx->codec->pix_fmts;
|
||||
diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c
|
||||
index 03c87b59bd..dbcceb915a 100644
|
||||
--- a/libavcodec/h264dec.c
|
||||
+++ b/libavcodec/h264dec.c
|
||||
@@ -1081,6 +1081,9 @@ AVCodec ff_h264_decoder = {
|
||||
#endif
|
||||
#if CONFIG_H264_VIDEOTOOLBOX_HWACCEL
|
||||
HWACCEL_VIDEOTOOLBOX(h264),
|
||||
+#endif
|
||||
+#if CONFIG_H264_V4L2REQUEST_HWACCEL
|
||||
+ HWACCEL_V4L2REQUEST(h264),
|
||||
#endif
|
||||
NULL
|
||||
},
|
||||
diff --git a/libavcodec/hwaccels.h b/libavcodec/hwaccels.h
|
||||
index ef54de2a3b..003200edea 100644
|
||||
--- a/libavcodec/hwaccels.h
|
||||
+++ b/libavcodec/hwaccels.h
|
||||
@@ -27,6 +27,7 @@ extern const AVHWAccel ff_h264_d3d11va_hwaccel;
|
||||
extern const AVHWAccel ff_h264_d3d11va2_hwaccel;
|
||||
extern const AVHWAccel ff_h264_dxva2_hwaccel;
|
||||
extern const AVHWAccel ff_h264_nvdec_hwaccel;
|
||||
+extern const AVHWAccel ff_h264_v4l2request_hwaccel;
|
||||
extern const AVHWAccel ff_h264_vaapi_hwaccel;
|
||||
extern const AVHWAccel ff_h264_vdpau_hwaccel;
|
||||
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..81b3c4b092
|
||||
--- /dev/null
|
||||
+++ b/libavcodec/v4l2_request_h264.c
|
||||
@@ -0,0 +1,443 @@
|
||||
+/*
|
||||
+ * 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 "h264dec.h"
|
||||
+#include "hwaccel.h"
|
||||
+#include "v4l2_request.h"
|
||||
+
|
||||
+typedef struct V4L2RequestControlsH264 {
|
||||
+ struct v4l2_ctrl_h264_sps sps;
|
||||
+ 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[16];
|
||||
+ int first_slice;
|
||||
+} 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++) {
|
||||
+ if (sl->pwt.luma_weight_flag[list]) {
|
||||
+ factors->luma_weight[i] = sl->pwt.luma_weight[i][list][0];
|
||||
+ factors->luma_offset[i] = sl->pwt.luma_weight[i][list][1];
|
||||
+ } else {
|
||||
+ factors->luma_weight[i] = 1 << sl->pwt.luma_log2_weight_denom;
|
||||
+ factors->luma_offset[i] = 0;
|
||||
+ }
|
||||
+ for (int j = 0; j < 2; j++) {
|
||||
+ if (sl->pwt.chroma_weight_flag[list]) {
|
||||
+ factors->chroma_weight[i][j] = sl->pwt.chroma_weight[i][list][j][0];
|
||||
+ factors->chroma_offset[i][j] = sl->pwt.chroma_weight[i][list][j][1];
|
||||
+ } else {
|
||||
+ factors->chroma_weight[i][j] = 1 << sl->pwt.chroma_log2_weight_denom;
|
||||
+ factors->chroma_offset[i][j] = 0;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void fill_dpb_entry(struct v4l2_h264_dpb_entry *entry, const H264Picture *pic)
|
||||
+{
|
||||
+ entry->reference_ts = ff_v4l2_request_get_capture_timestamp(pic->f);
|
||||
+ entry->frame_num = pic->frame_num;
|
||||
+ entry->pic_num = pic->pic_id;
|
||||
+ entry->flags = V4L2_H264_DPB_ENTRY_FLAG_VALID;
|
||||
+ 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_poc[0] != INT_MAX)
|
||||
+ entry->top_field_order_cnt = pic->field_poc[0];
|
||||
+ if (pic->field_poc[1] != INT_MAX)
|
||||
+ entry->bottom_field_order_cnt = pic->field_poc[1];
|
||||
+}
|
||||
+
|
||||
+static void fill_dpb(struct v4l2_ctrl_h264_decode_params *decode, const H264Context *h)
|
||||
+{
|
||||
+ int entries = 0;
|
||||
+
|
||||
+ for (int i = 0; i < h->short_ref_count; i++) {
|
||||
+ const H264Picture *pic = h->short_ref[i];
|
||||
+ if (pic && (pic->field_poc[0] != INT_MAX || pic->field_poc[1] != INT_MAX))
|
||||
+ fill_dpb_entry(&decode->dpb[entries++], pic);
|
||||
+ }
|
||||
+
|
||||
+ if (!h->long_ref_count)
|
||||
+ return;
|
||||
+
|
||||
+ for (int i = 0; i < FF_ARRAY_ELEMS(h->long_ref); i++) {
|
||||
+ const H264Picture *pic = h->long_ref[i];
|
||||
+ if (pic && (pic->field_poc[0] != INT_MAX || pic->field_poc[1] != INT_MAX))
|
||||
+ fill_dpb_entry(&decode->dpb[entries++], pic);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static uint8_t get_dpb_index(struct v4l2_ctrl_h264_decode_params *decode, const H264Ref *ref)
|
||||
+{
|
||||
+ uint64_t timestamp;
|
||||
+
|
||||
+ if (!ref->parent)
|
||||
+ return 0;
|
||||
+
|
||||
+ timestamp = ff_v4l2_request_get_capture_timestamp(ref->parent->f);
|
||||
+
|
||||
+ for (uint8_t i = 0; i < FF_ARRAY_ELEMS(decode->dpb); i++) {
|
||||
+ struct v4l2_h264_dpb_entry *entry = &decode->dpb[i];
|
||||
+ if ((entry->flags & V4L2_H264_DPB_ENTRY_FLAG_VALID) &&
|
||||
+ entry->reference_ts == timestamp)
|
||||
+ return i;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void fill_sps(struct v4l2_ctrl_h264_sps *ctrl, const H264Context *h)
|
||||
+{
|
||||
+ const SPS *sps = h->ps.sps;
|
||||
+
|
||||
+ *ctrl = (struct v4l2_ctrl_h264_sps) {
|
||||
+ .profile_idc = sps->profile_idc,
|
||||
+ .constraint_set_flags = sps->constraint_set_flags,
|
||||
+ .level_idc = sps->level_idc,
|
||||
+ .seq_parameter_set_id = sps->sps_id,
|
||||
+ .chroma_format_idc = sps->chroma_format_idc,
|
||||
+ .bit_depth_luma_minus8 = sps->bit_depth_luma - 8,
|
||||
+ .bit_depth_chroma_minus8 = sps->bit_depth_chroma - 8,
|
||||
+ .log2_max_frame_num_minus4 = sps->log2_max_frame_num - 4,
|
||||
+ .pic_order_cnt_type = sps->poc_type,
|
||||
+ .log2_max_pic_order_cnt_lsb_minus4 = sps->log2_max_poc_lsb - 4,
|
||||
+ .max_num_ref_frames = sps->ref_frame_count,
|
||||
+ .num_ref_frames_in_pic_order_cnt_cycle = sps->poc_cycle_length,
|
||||
+ //.offset_for_ref_frame[255] - not required? not set by libva-v4l2-request - copy sps->offset_for_ref_frame
|
||||
+ .offset_for_non_ref_pic = sps->offset_for_non_ref_pic,
|
||||
+ .offset_for_top_to_bottom_field = sps->offset_for_top_to_bottom_field,
|
||||
+ .pic_width_in_mbs_minus1 = h->mb_width - 1,
|
||||
+ .pic_height_in_map_units_minus1 = sps->frame_mbs_only_flag ? h->mb_height - 1 : h->mb_height / 2 - 1,
|
||||
+ };
|
||||
+
|
||||
+ if (sps->residual_color_transform_flag)
|
||||
+ ctrl->flags |= V4L2_H264_SPS_FLAG_SEPARATE_COLOUR_PLANE;
|
||||
+ if (sps->transform_bypass)
|
||||
+ ctrl->flags |= V4L2_H264_SPS_FLAG_QPPRIME_Y_ZERO_TRANSFORM_BYPASS;
|
||||
+ if (sps->delta_pic_order_always_zero_flag)
|
||||
+ ctrl->flags |= V4L2_H264_SPS_FLAG_DELTA_PIC_ORDER_ALWAYS_ZERO;
|
||||
+ if (sps->gaps_in_frame_num_allowed_flag)
|
||||
+ ctrl->flags |= V4L2_H264_SPS_FLAG_GAPS_IN_FRAME_NUM_VALUE_ALLOWED;
|
||||
+ if (sps->frame_mbs_only_flag)
|
||||
+ ctrl->flags |= V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY;
|
||||
+ if (sps->mb_aff)
|
||||
+ ctrl->flags |= V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD;
|
||||
+ if (sps->direct_8x8_inference_flag)
|
||||
+ ctrl->flags |= V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE;
|
||||
+}
|
||||
+
|
||||
+static void fill_pps(struct v4l2_ctrl_h264_pps *ctrl, const H264Context *h)
|
||||
+{
|
||||
+ const PPS *pps = h->ps.pps;
|
||||
+ const H264SliceContext *sl = &h->slice_ctx[0];
|
||||
+
|
||||
+ *ctrl = (struct v4l2_ctrl_h264_pps) {
|
||||
+ .pic_parameter_set_id = sl->pps_id,
|
||||
+ .seq_parameter_set_id = pps->sps_id,
|
||||
+ .num_slice_groups_minus1 = pps->slice_group_count - 1,
|
||||
+ .num_ref_idx_l0_default_active_minus1 = pps->ref_count[0] - 1,
|
||||
+ .num_ref_idx_l1_default_active_minus1 = pps->ref_count[1] - 1,
|
||||
+ .weighted_bipred_idc = pps->weighted_bipred_idc,
|
||||
+ .pic_init_qp_minus26 = pps->init_qp - 26,
|
||||
+ .pic_init_qs_minus26 = pps->init_qs - 26,
|
||||
+ .chroma_qp_index_offset = pps->chroma_qp_index_offset[0],
|
||||
+ .second_chroma_qp_index_offset = pps->chroma_qp_index_offset[1],
|
||||
+ };
|
||||
+
|
||||
+ if (pps->cabac)
|
||||
+ ctrl->flags |= V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE;
|
||||
+ if (pps->pic_order_present)
|
||||
+ ctrl->flags |= V4L2_H264_PPS_FLAG_BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT;
|
||||
+ if (pps->weighted_pred)
|
||||
+ ctrl->flags |= V4L2_H264_PPS_FLAG_WEIGHTED_PRED;
|
||||
+ if (pps->deblocking_filter_parameters_present)
|
||||
+ ctrl->flags |= V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT;
|
||||
+ if (pps->constrained_intra_pred)
|
||||
+ ctrl->flags |= V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED;
|
||||
+ if (pps->redundant_pic_cnt_present)
|
||||
+ ctrl->flags |= V4L2_H264_PPS_FLAG_REDUNDANT_PIC_CNT_PRESENT;
|
||||
+ if (pps->transform_8x8_mode)
|
||||
+ ctrl->flags |= V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE;
|
||||
+}
|
||||
+
|
||||
+static int v4l2_request_h264_start_frame(AVCodecContext *avctx,
|
||||
+ av_unused const uint8_t *buffer,
|
||||
+ av_unused uint32_t size)
|
||||
+{
|
||||
+ const H264Context *h = avctx->priv_data;
|
||||
+ const PPS *pps = h->ps.pps;
|
||||
+ const SPS *sps = h->ps.sps;
|
||||
+ V4L2RequestControlsH264 *controls = h->cur_pic_ptr->hwaccel_picture_private;
|
||||
+
|
||||
+ fill_sps(&controls->sps, h);
|
||||
+ fill_pps(&controls->pps, h);
|
||||
+
|
||||
+ memcpy(controls->scaling_matrix.scaling_list_4x4, pps->scaling_matrix4, sizeof(controls->scaling_matrix.scaling_list_4x4));
|
||||
+ memcpy(controls->scaling_matrix.scaling_list_8x8[0], pps->scaling_matrix8[0], sizeof(controls->scaling_matrix.scaling_list_8x8[0]));
|
||||
+ memcpy(controls->scaling_matrix.scaling_list_8x8[1], pps->scaling_matrix8[3], sizeof(controls->scaling_matrix.scaling_list_8x8[1]));
|
||||
+
|
||||
+ if (sps->chroma_format_idc == 3) {
|
||||
+ memcpy(controls->scaling_matrix.scaling_list_8x8[2], pps->scaling_matrix8[1], sizeof(controls->scaling_matrix.scaling_list_8x8[2]));
|
||||
+ memcpy(controls->scaling_matrix.scaling_list_8x8[3], pps->scaling_matrix8[4], sizeof(controls->scaling_matrix.scaling_list_8x8[3]));
|
||||
+ memcpy(controls->scaling_matrix.scaling_list_8x8[4], pps->scaling_matrix8[2], sizeof(controls->scaling_matrix.scaling_list_8x8[4]));
|
||||
+ memcpy(controls->scaling_matrix.scaling_list_8x8[5], pps->scaling_matrix8[5], sizeof(controls->scaling_matrix.scaling_list_8x8[5]));
|
||||
+ }
|
||||
+
|
||||
+ controls->decode_params = (struct v4l2_ctrl_h264_decode_params) {
|
||||
+ .num_slices = 0,
|
||||
+ .nal_ref_idc = h->nal_ref_idc,
|
||||
+ .top_field_order_cnt = h->cur_pic_ptr->field_poc[0] != INT_MAX ? h->cur_pic_ptr->field_poc[0] : 0,
|
||||
+ .bottom_field_order_cnt = h->cur_pic_ptr->field_poc[1] != INT_MAX ? h->cur_pic_ptr->field_poc[1] : 0,
|
||||
+ };
|
||||
+
|
||||
+ if (h->picture_idr)
|
||||
+ controls->decode_params.flags |= V4L2_H264_DECODE_PARAM_FLAG_IDR_PIC;
|
||||
+
|
||||
+ fill_dpb(&controls->decode_params, h);
|
||||
+
|
||||
+ controls->first_slice = !FIELD_PICTURE(h) || h->first_field;
|
||||
+
|
||||
+ return ff_v4l2_request_reset_frame(avctx, h->cur_pic_ptr->f);
|
||||
+}
|
||||
+
|
||||
+static int v4l2_request_h264_queue_decode(AVCodecContext *avctx, int last_slice)
|
||||
+{
|
||||
+ const H264Context *h = avctx->priv_data;
|
||||
+ V4L2RequestControlsH264 *controls = h->cur_pic_ptr->hwaccel_picture_private;
|
||||
+ V4L2RequestContextH264 *ctx = avctx->internal->hwaccel_priv_data;
|
||||
+
|
||||
+ struct v4l2_ext_control control[] = {
|
||||
+ {
|
||||
+ .id = V4L2_CID_MPEG_VIDEO_H264_SPS,
|
||||
+ .ptr = &controls->sps,
|
||||
+ .size = sizeof(controls->sps),
|
||||
+ },
|
||||
+ {
|
||||
+ .id = V4L2_CID_MPEG_VIDEO_H264_PPS,
|
||||
+ .ptr = &controls->pps,
|
||||
+ .size = sizeof(controls->pps),
|
||||
+ },
|
||||
+ {
|
||||
+ .id = V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX,
|
||||
+ .ptr = &controls->scaling_matrix,
|
||||
+ .size = sizeof(controls->scaling_matrix),
|
||||
+ },
|
||||
+ {
|
||||
+ .id = V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS,
|
||||
+ .ptr = &controls->slice_params,
|
||||
+ .size = sizeof(controls->slice_params[0]) * FFMIN(controls->decode_params.num_slices, 16),
|
||||
+ },
|
||||
+ {
|
||||
+ .id = V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS,
|
||||
+ .ptr = &controls->decode_params,
|
||||
+ .size = sizeof(controls->decode_params),
|
||||
+ },
|
||||
+ };
|
||||
+
|
||||
+ if (ctx->decode_mode == V4L2_MPEG_VIDEO_H264_DECODE_MODE_SLICE_BASED)
|
||||
+ return ff_v4l2_request_decode_slice(avctx, h->cur_pic_ptr->f, control, FF_ARRAY_ELEMS(control), controls->first_slice, last_slice);
|
||||
+
|
||||
+ return ff_v4l2_request_decode_frame(avctx, h->cur_pic_ptr->f, control, FF_ARRAY_ELEMS(control));
|
||||
+}
|
||||
+
|
||||
+static int v4l2_request_h264_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
|
||||
+{
|
||||
+ const H264Context *h = avctx->priv_data;
|
||||
+ 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, 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_queue_decode(avctx, 0);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ff_v4l2_request_reset_frame(avctx, h->cur_pic_ptr->f);
|
||||
+ slice = controls->decode_params.num_slices = 0;
|
||||
+ controls->first_slice = 0;
|
||||
+ }
|
||||
+
|
||||
+ controls->slice_params[slice] = (struct v4l2_ctrl_h264_slice_params) {
|
||||
+ /* 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),
|
||||
+
|
||||
+ .first_mb_in_slice = sl->first_mb_addr,
|
||||
+ .slice_type = ff_h264_get_slice_type(sl),
|
||||
+ .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? */
|
||||
+ .pic_order_cnt_lsb = sl->poc_lsb,
|
||||
+ .delta_pic_order_cnt_bottom = sl->delta_poc_bottom,
|
||||
+ .delta_pic_order_cnt0 = sl->delta_poc[0],
|
||||
+ .delta_pic_order_cnt1 = sl->delta_poc[1],
|
||||
+ .redundant_pic_cnt = sl->redundant_pic_count,
|
||||
+
|
||||
+ /* Size in bits of dec_ref_pic_marking() syntax element. */
|
||||
+ .dec_ref_pic_marking_bit_size = 0,
|
||||
+ /* Size in bits of pic order count syntax. */
|
||||
+ .pic_order_cnt_bit_size = 0,
|
||||
+
|
||||
+ .cabac_init_idc = sl->cabac_init_idc,
|
||||
+ .slice_qp_delta = sl->qscale - pps->init_qp,
|
||||
+ .slice_qs_delta = 0, /* XXX not implemented by FFmpeg */
|
||||
+ .disable_deblocking_filter_idc = sl->deblocking_filter < 2 ? !sl->deblocking_filter : sl->deblocking_filter,
|
||||
+ .slice_alpha_c0_offset_div2 = sl->slice_alpha_c0_offset / 2,
|
||||
+ .slice_beta_offset_div2 = sl->slice_beta_offset / 2,
|
||||
+ .slice_group_change_cycle = 0, /* what is this? */
|
||||
+
|
||||
+ .num_ref_idx_l0_active_minus1 = sl->list_count > 0 ? sl->ref_count[0] - 1 : 0,
|
||||
+ .num_ref_idx_l1_active_minus1 = sl->list_count > 1 ? sl->ref_count[1] - 1 : 0,
|
||||
+ };
|
||||
+
|
||||
+ if (FIELD_PICTURE(h))
|
||||
+ controls->slice_params[slice].flags |= V4L2_H264_SLICE_FLAG_FIELD_PIC;
|
||||
+ if (h->picture_structure == PICT_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[slice].flags |= V4L2_H264_SLICE_FLAG_DIRECT_SPATIAL_MV_PRED;
|
||||
+
|
||||
+ 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[slice].ref_pic_list0[i] = get_dpb_index(&controls->decode_params, &sl->ref_list[0][i]);
|
||||
+ if (count)
|
||||
+ 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[slice].ref_pic_list1[i] = get_dpb_index(&controls->decode_params, &sl->ref_list[1][i]);
|
||||
+ if (count)
|
||||
+ fill_weight_factors(&controls->slice_params[slice].pred_weight_table.weight_factors[1], 1, sl);
|
||||
+
|
||||
+ 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_end_frame(AVCodecContext *avctx)
|
||||
+{
|
||||
+ const H264Context *h = avctx->priv_data;
|
||||
+ return v4l2_request_h264_queue_decode(avctx, !FIELD_PICTURE(h) || !h->first_field);
|
||||
+}
|
||||
+
|
||||
+static int v4l2_request_h264_set_controls(AVCodecContext *avctx)
|
||||
+{
|
||||
+ V4L2RequestContextH264 *ctx = avctx->internal->hwaccel_priv_data;
|
||||
+
|
||||
+ 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)
|
||||
+{
|
||||
+ 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[] = {
|
||||
+ {
|
||||
+ .id = V4L2_CID_MPEG_VIDEO_H264_SPS,
|
||||
+ .ptr = &sps,
|
||||
+ .size = sizeof(sps),
|
||||
+ },
|
||||
+ {
|
||||
+ .id = V4L2_CID_MPEG_VIDEO_H264_PPS,
|
||||
+ .ptr = &pps,
|
||||
+ .size = sizeof(pps),
|
||||
+ },
|
||||
+ };
|
||||
+
|
||||
+ fill_sps(&sps, h);
|
||||
+ fill_pps(&pps, h);
|
||||
+
|
||||
+ 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 = {
|
||||
+ .name = "h264_v4l2request",
|
||||
+ .type = AVMEDIA_TYPE_VIDEO,
|
||||
+ .id = AV_CODEC_ID_H264,
|
||||
+ .pix_fmt = AV_PIX_FMT_DRM_PRIME,
|
||||
+ .start_frame = v4l2_request_h264_start_frame,
|
||||
+ .decode_slice = v4l2_request_h264_decode_slice,
|
||||
+ .end_frame = v4l2_request_h264_end_frame,
|
||||
+ .frame_priv_data_size = sizeof(V4L2RequestControlsH264),
|
||||
+ .init = v4l2_request_h264_init,
|
||||
+ .uninit = ff_v4l2_request_uninit,
|
||||
+ .priv_data_size = sizeof(V4L2RequestContextH264),
|
||||
+ .frame_params = ff_v4l2_request_frame_params,
|
||||
+ .caps_internal = HWACCEL_CAP_ASYNC_SAFE,
|
||||
+};
|
@ -1,636 +0,0 @@
|
||||
From 521d06aec85d55a28e946a222f591747a1d3f2f5 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Sat, 15 Dec 2018 22:32:16 +0100
|
||||
Subject: [PATCH 05/12] Add V4L2 request API hevc hwaccel
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
||||
---
|
||||
configure | 3 +
|
||||
libavcodec/Makefile | 1 +
|
||||
libavcodec/hevcdec.c | 10 +
|
||||
libavcodec/hwaccels.h | 1 +
|
||||
libavcodec/v4l2_request_hevc.c | 527 +++++++++++++++++++++++++++++++++
|
||||
5 files changed, 542 insertions(+)
|
||||
create mode 100644 libavcodec/v4l2_request_hevc.c
|
||||
|
||||
diff --git a/configure b/configure
|
||||
index 576a79ff09..d51ee62a70 100755
|
||||
--- a/configure
|
||||
+++ b/configure
|
||||
@@ -2911,6 +2911,8 @@ hevc_dxva2_hwaccel_deps="dxva2 DXVA_PicParams_HEVC"
|
||||
hevc_dxva2_hwaccel_select="hevc_decoder"
|
||||
hevc_nvdec_hwaccel_deps="nvdec"
|
||||
hevc_nvdec_hwaccel_select="hevc_decoder"
|
||||
+hevc_v4l2request_hwaccel_deps="v4l2_request hevc_v4l2_request"
|
||||
+hevc_v4l2request_hwaccel_select="hevc_decoder"
|
||||
hevc_vaapi_hwaccel_deps="vaapi VAPictureParameterBufferHEVC"
|
||||
hevc_vaapi_hwaccel_select="hevc_decoder"
|
||||
hevc_vdpau_hwaccel_deps="vdpau VdpPictureInfoHEVC"
|
||||
@@ -6460,6 +6462,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;"
|
||||
+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_headers sys/videoio.h
|
||||
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
|
||||
index 58bd444934..2b53d2b650 100644
|
||||
--- a/libavcodec/Makefile
|
||||
+++ b/libavcodec/Makefile
|
||||
@@ -880,6 +880,7 @@ OBJS-$(CONFIG_HEVC_D3D11VA_HWACCEL) += dxva2_hevc.o
|
||||
OBJS-$(CONFIG_HEVC_DXVA2_HWACCEL) += dxva2_hevc.o
|
||||
OBJS-$(CONFIG_HEVC_NVDEC_HWACCEL) += nvdec_hevc.o
|
||||
OBJS-$(CONFIG_HEVC_QSV_HWACCEL) += qsvdec_h2645.o
|
||||
+OBJS-$(CONFIG_HEVC_V4L2REQUEST_HWACCEL) += v4l2_request_hevc.o
|
||||
OBJS-$(CONFIG_HEVC_VAAPI_HWACCEL) += vaapi_hevc.o
|
||||
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 8f1c162ace..4c9c92bfc2 100644
|
||||
--- a/libavcodec/hevcdec.c
|
||||
+++ b/libavcodec/hevcdec.c
|
||||
@@ -373,6 +373,7 @@ static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps)
|
||||
#define HWACCEL_MAX (CONFIG_HEVC_DXVA2_HWACCEL + \
|
||||
CONFIG_HEVC_D3D11VA_HWACCEL * 2 + \
|
||||
CONFIG_HEVC_NVDEC_HWACCEL + \
|
||||
+ CONFIG_HEVC_V4L2REQUEST_HWACCEL + \
|
||||
CONFIG_HEVC_VAAPI_HWACCEL + \
|
||||
CONFIG_HEVC_VIDEOTOOLBOX_HWACCEL + \
|
||||
CONFIG_HEVC_VDPAU_HWACCEL)
|
||||
@@ -399,6 +400,9 @@ static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps)
|
||||
#endif
|
||||
#if CONFIG_HEVC_VIDEOTOOLBOX_HWACCEL
|
||||
*fmt++ = AV_PIX_FMT_VIDEOTOOLBOX;
|
||||
+#endif
|
||||
+#if CONFIG_HEVC_V4L2REQUEST_HWACCEL
|
||||
+ *fmt++ = AV_PIX_FMT_DRM_PRIME;
|
||||
#endif
|
||||
break;
|
||||
case AV_PIX_FMT_YUV420P10:
|
||||
@@ -417,6 +421,9 @@ static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps)
|
||||
#endif
|
||||
#if CONFIG_HEVC_NVDEC_HWACCEL
|
||||
*fmt++ = AV_PIX_FMT_CUDA;
|
||||
+#endif
|
||||
+#if CONFIG_HEVC_V4L2REQUEST_HWACCEL
|
||||
+ *fmt++ = AV_PIX_FMT_DRM_PRIME;
|
||||
#endif
|
||||
break;
|
||||
case AV_PIX_FMT_YUV444P:
|
||||
@@ -3592,6 +3599,9 @@ AVCodec ff_hevc_decoder = {
|
||||
#endif
|
||||
#if CONFIG_HEVC_VIDEOTOOLBOX_HWACCEL
|
||||
HWACCEL_VIDEOTOOLBOX(hevc),
|
||||
+#endif
|
||||
+#if CONFIG_HEVC_V4L2REQUEST_HWACCEL
|
||||
+ HWACCEL_V4L2REQUEST(hevc),
|
||||
#endif
|
||||
NULL
|
||||
},
|
||||
diff --git a/libavcodec/hwaccels.h b/libavcodec/hwaccels.h
|
||||
index 003200edea..d183675abe 100644
|
||||
--- a/libavcodec/hwaccels.h
|
||||
+++ b/libavcodec/hwaccels.h
|
||||
@@ -35,6 +35,7 @@ extern const AVHWAccel ff_hevc_d3d11va_hwaccel;
|
||||
extern const AVHWAccel ff_hevc_d3d11va2_hwaccel;
|
||||
extern const AVHWAccel ff_hevc_dxva2_hwaccel;
|
||||
extern const AVHWAccel ff_hevc_nvdec_hwaccel;
|
||||
+extern const AVHWAccel ff_hevc_v4l2request_hwaccel;
|
||||
extern const AVHWAccel ff_hevc_vaapi_hwaccel;
|
||||
extern const AVHWAccel ff_hevc_vdpau_hwaccel;
|
||||
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..da1fd666d7
|
||||
--- /dev/null
|
||||
+++ b/libavcodec/v4l2_request_hevc.c
|
||||
@@ -0,0 +1,527 @@
|
||||
+/*
|
||||
+ * 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 "hevcdec.h"
|
||||
+#include "hwaccel.h"
|
||||
+#include "v4l2_request.h"
|
||||
+
|
||||
+typedef struct V4L2RequestControlsHEVC {
|
||||
+ struct v4l2_ctrl_hevc_sps sps;
|
||||
+ struct v4l2_ctrl_hevc_pps pps;
|
||||
+ struct v4l2_ctrl_hevc_scaling_matrix scaling_matrix;
|
||||
+ struct v4l2_ctrl_hevc_slice_params slice_params[16];
|
||||
+ int first_slice;
|
||||
+ int num_slices; //TODO: this should be in control
|
||||
+} V4L2RequestControlsHEVC;
|
||||
+
|
||||
+typedef struct V4L2RequestContextHEVC {
|
||||
+ V4L2RequestContext base;
|
||||
+ int decode_mode;
|
||||
+ int start_code;
|
||||
+} V4L2RequestContextHEVC;
|
||||
+
|
||||
+static void v4l2_request_hevc_fill_pred_table(const HEVCContext *h, struct v4l2_hevc_pred_weight_table *table)
|
||||
+{
|
||||
+ int32_t luma_weight_denom, chroma_weight_denom;
|
||||
+ const SliceHeader *sh = &h->sh;
|
||||
+
|
||||
+ if (sh->slice_type == HEVC_SLICE_I ||
|
||||
+ (sh->slice_type == HEVC_SLICE_P && !h->ps.pps->weighted_pred_flag) ||
|
||||
+ (sh->slice_type == HEVC_SLICE_B && !h->ps.pps->weighted_bipred_flag))
|
||||
+ return;
|
||||
+
|
||||
+ table->luma_log2_weight_denom = sh->luma_log2_weight_denom;
|
||||
+
|
||||
+ if (h->ps.sps->chroma_format_idc)
|
||||
+ table->delta_chroma_log2_weight_denom = sh->chroma_log2_weight_denom - sh->luma_log2_weight_denom;
|
||||
+
|
||||
+ luma_weight_denom = (1 << sh->luma_log2_weight_denom);
|
||||
+ chroma_weight_denom = (1 << sh->chroma_log2_weight_denom);
|
||||
+
|
||||
+ for (int i = 0; i < 15 && i < sh->nb_refs[L0]; i++) {
|
||||
+ table->delta_luma_weight_l0[i] = sh->luma_weight_l0[i] - luma_weight_denom;
|
||||
+ table->luma_offset_l0[i] = sh->luma_offset_l0[i];
|
||||
+ table->delta_chroma_weight_l0[i][0] = sh->chroma_weight_l0[i][0] - chroma_weight_denom;
|
||||
+ table->delta_chroma_weight_l0[i][1] = sh->chroma_weight_l0[i][1] - chroma_weight_denom;
|
||||
+ table->chroma_offset_l0[i][0] = sh->chroma_offset_l0[i][0];
|
||||
+ table->chroma_offset_l0[i][1] = sh->chroma_offset_l0[i][1];
|
||||
+ }
|
||||
+
|
||||
+ if (sh->slice_type != HEVC_SLICE_B)
|
||||
+ return;
|
||||
+
|
||||
+ for (int i = 0; i < 15 && i < sh->nb_refs[L1]; i++) {
|
||||
+ table->delta_luma_weight_l1[i] = sh->luma_weight_l1[i] - luma_weight_denom;
|
||||
+ table->luma_offset_l1[i] = sh->luma_offset_l1[i];
|
||||
+ table->delta_chroma_weight_l1[i][0] = sh->chroma_weight_l1[i][0] - chroma_weight_denom;
|
||||
+ table->delta_chroma_weight_l1[i][1] = sh->chroma_weight_l1[i][1] - chroma_weight_denom;
|
||||
+ table->chroma_offset_l1[i][0] = sh->chroma_offset_l1[i][0];
|
||||
+ table->chroma_offset_l1[i][1] = sh->chroma_offset_l1[i][1];
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int find_frame_rps_type(const HEVCContext *h, uint64_t timestamp)
|
||||
+{
|
||||
+ const HEVCFrame *frame;
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < h->rps[ST_CURR_BEF].nb_refs; i++) {
|
||||
+ frame = h->rps[ST_CURR_BEF].ref[i];
|
||||
+ if (frame && timestamp == ff_v4l2_request_get_capture_timestamp(frame->frame))
|
||||
+ return V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_BEFORE;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < h->rps[ST_CURR_AFT].nb_refs; i++) {
|
||||
+ frame = h->rps[ST_CURR_AFT].ref[i];
|
||||
+ if (frame && timestamp == ff_v4l2_request_get_capture_timestamp(frame->frame))
|
||||
+ return V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_AFTER;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < h->rps[LT_CURR].nb_refs; i++) {
|
||||
+ frame = h->rps[LT_CURR].ref[i];
|
||||
+ if (frame && timestamp == ff_v4l2_request_get_capture_timestamp(frame->frame))
|
||||
+ return V4L2_HEVC_DPB_ENTRY_RPS_LT_CURR;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static uint8_t get_ref_pic_index(const HEVCContext *h, const HEVCFrame *frame,
|
||||
+ struct v4l2_ctrl_hevc_slice_params *slice_params)
|
||||
+{
|
||||
+ uint64_t timestamp;
|
||||
+
|
||||
+ if (!frame)
|
||||
+ return 0;
|
||||
+
|
||||
+ timestamp = ff_v4l2_request_get_capture_timestamp(frame->frame);
|
||||
+
|
||||
+ for (uint8_t i = 0; i < slice_params->num_active_dpb_entries; i++) {
|
||||
+ struct v4l2_hevc_dpb_entry *entry = &slice_params->dpb[i];
|
||||
+ if (entry->timestamp == timestamp)
|
||||
+ return i;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void v4l2_request_hevc_fill_slice_params(const HEVCContext *h,
|
||||
+ struct v4l2_ctrl_hevc_slice_params *slice_params)
|
||||
+{
|
||||
+ const HEVCFrame *pic = h->ref;
|
||||
+ const SliceHeader *sh = &h->sh;
|
||||
+ int i, entries = 0;
|
||||
+ RefPicList *rpl;
|
||||
+
|
||||
+ *slice_params = (struct v4l2_ctrl_hevc_slice_params) {
|
||||
+ .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,
|
||||
+
|
||||
+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: General slice segment header */
|
||||
+ .slice_type = sh->slice_type,
|
||||
+ .colour_plane_id = sh->colour_plane_id,
|
||||
+ .slice_pic_order_cnt = pic->poc,
|
||||
+ .num_ref_idx_l0_active_minus1 = sh->nb_refs[L0] ? sh->nb_refs[L0] - 1 : 0,
|
||||
+ .num_ref_idx_l1_active_minus1 = sh->nb_refs[L1] ? sh->nb_refs[L1] - 1 : 0,
|
||||
+ .collocated_ref_idx = sh->slice_temporal_mvp_enabled_flag ? sh->collocated_ref_idx : 0,
|
||||
+ .five_minus_max_num_merge_cand = sh->slice_type == HEVC_SLICE_I ? 0 : 5 - sh->max_num_merge_cand,
|
||||
+ .slice_qp_delta = sh->slice_qp_delta,
|
||||
+ .slice_cb_qp_offset = sh->slice_cb_qp_offset,
|
||||
+ .slice_cr_qp_offset = sh->slice_cr_qp_offset,
|
||||
+ .slice_act_y_qp_offset = 0,
|
||||
+ .slice_act_cb_qp_offset = 0,
|
||||
+ .slice_act_cr_qp_offset = 0,
|
||||
+ .slice_beta_offset_div2 = sh->beta_offset / 2,
|
||||
+ .slice_tc_offset_div2 = sh->tc_offset / 2,
|
||||
+
|
||||
+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: Picture timing SEI message */
|
||||
+ .pic_struct = h->sei.picture_timing.picture_struct,
|
||||
+
|
||||
+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: General slice segment header */
|
||||
+ .num_rps_poc_st_curr_before = h->rps[ST_CURR_BEF].nb_refs,
|
||||
+ .num_rps_poc_st_curr_after = h->rps[ST_CURR_AFT].nb_refs,
|
||||
+ .num_rps_poc_lt_curr = h->rps[LT_CURR].nb_refs,
|
||||
+ };
|
||||
+
|
||||
+ if (sh->slice_sample_adaptive_offset_flag[0])
|
||||
+ slice_params->flags |= V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_SAO_LUMA;
|
||||
+
|
||||
+ if (sh->slice_sample_adaptive_offset_flag[1])
|
||||
+ slice_params->flags |= V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_SAO_CHROMA;
|
||||
+
|
||||
+ if (sh->slice_temporal_mvp_enabled_flag)
|
||||
+ slice_params->flags |= V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_TEMPORAL_MVP_ENABLED;
|
||||
+
|
||||
+ if (sh->mvd_l1_zero_flag)
|
||||
+ slice_params->flags |= V4L2_HEVC_SLICE_PARAMS_FLAG_MVD_L1_ZERO;
|
||||
+
|
||||
+ if (sh->cabac_init_flag)
|
||||
+ slice_params->flags |= V4L2_HEVC_SLICE_PARAMS_FLAG_CABAC_INIT;
|
||||
+
|
||||
+ if (sh->collocated_list == L0)
|
||||
+ slice_params->flags |= V4L2_HEVC_SLICE_PARAMS_FLAG_COLLOCATED_FROM_L0;
|
||||
+
|
||||
+ if (sh->disable_deblocking_filter_flag)
|
||||
+ slice_params->flags |= V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_DEBLOCKING_FILTER_DISABLED;
|
||||
+
|
||||
+ if (sh->slice_loop_filter_across_slices_enabled_flag)
|
||||
+ slice_params->flags |= V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_LOOP_FILTER_ACROSS_SLICES_ENABLED;
|
||||
+
|
||||
+ for (i = 0; i < FF_ARRAY_ELEMS(h->DPB); i++) {
|
||||
+ const HEVCFrame *frame = &h->DPB[i];
|
||||
+ if (frame != pic && (frame->flags & (HEVC_FRAME_FLAG_LONG_REF | HEVC_FRAME_FLAG_SHORT_REF))) {
|
||||
+ struct v4l2_hevc_dpb_entry *entry = &slice_params->dpb[entries++];
|
||||
+
|
||||
+ entry->timestamp = ff_v4l2_request_get_capture_timestamp(frame->frame);
|
||||
+ entry->rps = find_frame_rps_type(h, entry->timestamp);
|
||||
+ entry->field_pic = frame->frame->interlaced_frame;
|
||||
+
|
||||
+ /* TODO: Interleaved: Get the POC for each field. */
|
||||
+ entry->pic_order_cnt[0] = frame->poc;
|
||||
+ entry->pic_order_cnt[1] = frame->poc;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ slice_params->num_active_dpb_entries = entries;
|
||||
+
|
||||
+ if (sh->slice_type != HEVC_SLICE_I) {
|
||||
+ rpl = &h->ref->refPicList[0];
|
||||
+ for (i = 0; i < rpl->nb_refs; i++)
|
||||
+ slice_params->ref_idx_l0[i] = get_ref_pic_index(h, rpl->ref[i], slice_params);
|
||||
+ }
|
||||
+
|
||||
+ if (sh->slice_type == HEVC_SLICE_B) {
|
||||
+ rpl = &h->ref->refPicList[1];
|
||||
+ for (i = 0; i < rpl->nb_refs; i++)
|
||||
+ slice_params->ref_idx_l1[i] = get_ref_pic_index(h, rpl->ref[i], slice_params);
|
||||
+ }
|
||||
+
|
||||
+ v4l2_request_hevc_fill_pred_table(h, &slice_params->pred_weight_table);
|
||||
+
|
||||
+ slice_params->num_entry_point_offsets = sh->num_entry_point_offsets;
|
||||
+ if (slice_params->num_entry_point_offsets > 256) {
|
||||
+ slice_params->num_entry_point_offsets = 256;
|
||||
+ av_log(NULL, AV_LOG_ERROR, "%s: Currently only 256 entry points are supported, but slice has %d entry points.\n", __func__, sh->num_entry_point_offsets);
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < slice_params->num_entry_point_offsets; i++)
|
||||
+ slice_params->entry_point_offset_minus1[i] = sh->entry_point_offset[i] - 1;
|
||||
+}
|
||||
+
|
||||
+static int v4l2_request_hevc_start_frame(AVCodecContext *avctx,
|
||||
+ av_unused const uint8_t *buffer,
|
||||
+ av_unused uint32_t size)
|
||||
+{
|
||||
+ const HEVCContext *h = avctx->priv_data;
|
||||
+ const HEVCSPS *sps = h->ps.sps;
|
||||
+ const HEVCPPS *pps = h->ps.pps;
|
||||
+ 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;
|
||||
+
|
||||
+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: Sequence parameter set */
|
||||
+ controls->sps = (struct v4l2_ctrl_hevc_sps) {
|
||||
+ .chroma_format_idc = sps->chroma_format_idc,
|
||||
+ .pic_width_in_luma_samples = sps->width,
|
||||
+ .pic_height_in_luma_samples = sps->height,
|
||||
+ .bit_depth_luma_minus8 = sps->bit_depth - 8,
|
||||
+ .bit_depth_chroma_minus8 = sps->bit_depth - 8,
|
||||
+ .log2_max_pic_order_cnt_lsb_minus4 = sps->log2_max_poc_lsb - 4,
|
||||
+ .sps_max_dec_pic_buffering_minus1 = sps->temporal_layer[sps->max_sub_layers - 1].max_dec_pic_buffering - 1,
|
||||
+ .sps_max_num_reorder_pics = sps->temporal_layer[sps->max_sub_layers - 1].num_reorder_pics,
|
||||
+ .sps_max_latency_increase_plus1 = sps->temporal_layer[sps->max_sub_layers - 1].max_latency_increase + 1,
|
||||
+ .log2_min_luma_coding_block_size_minus3 = sps->log2_min_cb_size - 3,
|
||||
+ .log2_diff_max_min_luma_coding_block_size = sps->log2_diff_max_min_coding_block_size,
|
||||
+ .log2_min_luma_transform_block_size_minus2 = sps->log2_min_tb_size - 2,
|
||||
+ .log2_diff_max_min_luma_transform_block_size = sps->log2_max_trafo_size - sps->log2_min_tb_size,
|
||||
+ .max_transform_hierarchy_depth_inter = sps->max_transform_hierarchy_depth_inter,
|
||||
+ .max_transform_hierarchy_depth_intra = sps->max_transform_hierarchy_depth_intra,
|
||||
+ .pcm_sample_bit_depth_luma_minus1 = sps->pcm.bit_depth - 1,
|
||||
+ .pcm_sample_bit_depth_chroma_minus1 = sps->pcm.bit_depth_chroma - 1,
|
||||
+ .log2_min_pcm_luma_coding_block_size_minus3 = sps->pcm.log2_min_pcm_cb_size - 3,
|
||||
+ .log2_diff_max_min_pcm_luma_coding_block_size = sps->pcm.log2_max_pcm_cb_size - sps->pcm.log2_min_pcm_cb_size,
|
||||
+ .num_short_term_ref_pic_sets = sps->nb_st_rps,
|
||||
+ .num_long_term_ref_pics_sps = sps->num_long_term_ref_pics_sps,
|
||||
+ };
|
||||
+
|
||||
+ if (sps->separate_colour_plane_flag)
|
||||
+ controls->sps.flags |= V4L2_HEVC_SPS_FLAG_SEPARATE_COLOUR_PLANE;
|
||||
+
|
||||
+ if (sps->scaling_list_enable_flag)
|
||||
+ controls->sps.flags |= V4L2_HEVC_SPS_FLAG_SCALING_LIST_ENABLED;
|
||||
+
|
||||
+ if (sps->amp_enabled_flag)
|
||||
+ controls->sps.flags |= V4L2_HEVC_SPS_FLAG_AMP_ENABLED;
|
||||
+
|
||||
+ if (sps->sao_enabled)
|
||||
+ controls->sps.flags |= V4L2_HEVC_SPS_FLAG_SAMPLE_ADAPTIVE_OFFSET;
|
||||
+
|
||||
+ if (sps->pcm_enabled_flag)
|
||||
+ controls->sps.flags |= V4L2_HEVC_SPS_FLAG_PCM_ENABLED;
|
||||
+
|
||||
+ if (sps->pcm.loop_filter_disable_flag)
|
||||
+ controls->sps.flags |= V4L2_HEVC_SPS_FLAG_PCM_LOOP_FILTER_DISABLED;
|
||||
+
|
||||
+ if (sps->long_term_ref_pics_present_flag)
|
||||
+ controls->sps.flags |= V4L2_HEVC_SPS_FLAG_LONG_TERM_REF_PICS_PRESENT;
|
||||
+
|
||||
+ if (sps->sps_temporal_mvp_enabled_flag)
|
||||
+ controls->sps.flags |= V4L2_HEVC_SPS_FLAG_SPS_TEMPORAL_MVP_ENABLED;
|
||||
+
|
||||
+ if (sps->sps_strong_intra_smoothing_enable_flag)
|
||||
+ controls->sps.flags |= V4L2_HEVC_SPS_FLAG_STRONG_INTRA_SMOOTHING_ENABLED;
|
||||
+
|
||||
+ if (sl) {
|
||||
+ for (int i = 0; i < 6; i++) {
|
||||
+ for (int j = 0; j < 16; j++)
|
||||
+ 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,
|
||||
+ .init_qp_minus26 = pps->pic_init_qp_minus26,
|
||||
+ .diff_cu_qp_delta_depth = pps->diff_cu_qp_delta_depth,
|
||||
+ .pps_cb_qp_offset = pps->cb_qp_offset,
|
||||
+ .pps_cr_qp_offset = pps->cr_qp_offset,
|
||||
+ .pps_beta_offset_div2 = pps->beta_offset / 2,
|
||||
+ .pps_tc_offset_div2 = pps->tc_offset / 2,
|
||||
+ .log2_parallel_merge_level_minus2 = pps->log2_parallel_merge_level - 2,
|
||||
+ };
|
||||
+
|
||||
+ if (pps->dependent_slice_segments_enabled_flag)
|
||||
+ controls->pps.flags |= V4L2_HEVC_PPS_FLAG_DEPENDENT_SLICE_SEGMENT;
|
||||
+
|
||||
+ if (pps->output_flag_present_flag)
|
||||
+ controls->pps.flags |= V4L2_HEVC_PPS_FLAG_OUTPUT_FLAG_PRESENT;
|
||||
+
|
||||
+ if (pps->sign_data_hiding_flag)
|
||||
+ controls->pps.flags |= V4L2_HEVC_PPS_FLAG_SIGN_DATA_HIDING_ENABLED;
|
||||
+
|
||||
+ if (pps->cabac_init_present_flag)
|
||||
+ controls->pps.flags |= V4L2_HEVC_PPS_FLAG_CABAC_INIT_PRESENT;
|
||||
+
|
||||
+ if (pps->constrained_intra_pred_flag)
|
||||
+ controls->pps.flags |= V4L2_HEVC_PPS_FLAG_CONSTRAINED_INTRA_PRED;
|
||||
+
|
||||
+ if (pps->transform_skip_enabled_flag)
|
||||
+ controls->pps.flags |= V4L2_HEVC_PPS_FLAG_TRANSFORM_SKIP_ENABLED;
|
||||
+
|
||||
+ if (pps->cu_qp_delta_enabled_flag)
|
||||
+ controls->pps.flags |= V4L2_HEVC_PPS_FLAG_CU_QP_DELTA_ENABLED;
|
||||
+
|
||||
+ if (pps->pic_slice_level_chroma_qp_offsets_present_flag)
|
||||
+ controls->pps.flags |= V4L2_HEVC_PPS_FLAG_PPS_SLICE_CHROMA_QP_OFFSETS_PRESENT;
|
||||
+
|
||||
+ if (pps->weighted_pred_flag)
|
||||
+ controls->pps.flags |= V4L2_HEVC_PPS_FLAG_WEIGHTED_PRED;
|
||||
+
|
||||
+ if (pps->weighted_bipred_flag)
|
||||
+ controls->pps.flags |= V4L2_HEVC_PPS_FLAG_WEIGHTED_BIPRED;
|
||||
+
|
||||
+ if (pps->transquant_bypass_enable_flag)
|
||||
+ controls->pps.flags |= V4L2_HEVC_PPS_FLAG_TRANSQUANT_BYPASS_ENABLED;
|
||||
+
|
||||
+ if (pps->tiles_enabled_flag)
|
||||
+ controls->pps.flags |= V4L2_HEVC_PPS_FLAG_TILES_ENABLED;
|
||||
+
|
||||
+ if (pps->entropy_coding_sync_enabled_flag)
|
||||
+ controls->pps.flags |= V4L2_HEVC_PPS_FLAG_ENTROPY_CODING_SYNC_ENABLED;
|
||||
+
|
||||
+ if (pps->loop_filter_across_tiles_enabled_flag)
|
||||
+ controls->pps.flags |= V4L2_HEVC_PPS_FLAG_LOOP_FILTER_ACROSS_TILES_ENABLED;
|
||||
+
|
||||
+ if (pps->seq_loop_filter_across_slices_enabled_flag)
|
||||
+ controls->pps.flags |= V4L2_HEVC_PPS_FLAG_PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED;
|
||||
+
|
||||
+ if (pps->deblocking_filter_override_enabled_flag)
|
||||
+ controls->pps.flags |= V4L2_HEVC_PPS_FLAG_DEBLOCKING_FILTER_OVERRIDE_ENABLED;
|
||||
+
|
||||
+ if (pps->disable_dbf)
|
||||
+ controls->pps.flags |= V4L2_HEVC_PPS_FLAG_PPS_DISABLE_DEBLOCKING_FILTER;
|
||||
+
|
||||
+ if (pps->lists_modification_present_flag)
|
||||
+ controls->pps.flags |= V4L2_HEVC_PPS_FLAG_LISTS_MODIFICATION_PRESENT;
|
||||
+
|
||||
+ if (pps->slice_header_extension_present_flag)
|
||||
+ controls->pps.flags |= V4L2_HEVC_PPS_FLAG_SLICE_SEGMENT_HEADER_EXTENSION_PRESENT;
|
||||
+
|
||||
+ if (pps->tiles_enabled_flag) {
|
||||
+ controls->pps.num_tile_columns_minus1 = pps->num_tile_columns - 1;
|
||||
+ controls->pps.num_tile_rows_minus1 = pps->num_tile_rows - 1;
|
||||
+
|
||||
+ av_log(avctx, AV_LOG_DEBUG, "%s: avctx=%p tiles_enabled_flag=%d num_tile_columns=%d num_tile_rows=%d\n",
|
||||
+ __func__, avctx, pps->tiles_enabled_flag, pps->num_tile_columns, pps->num_tile_rows);
|
||||
+
|
||||
+ for (int i = 0; i < pps->num_tile_columns; i++)
|
||||
+ controls->pps.column_width_minus1[i] = pps->column_width[i] - 1;
|
||||
+
|
||||
+ for (int i = 0; i < pps->num_tile_rows; i++)
|
||||
+ controls->pps.row_height_minus1[i] = pps->row_height[i] - 1;
|
||||
+ }
|
||||
+
|
||||
+ controls->first_slice = 1;
|
||||
+ controls->num_slices = 0;
|
||||
+
|
||||
+ return ff_v4l2_request_reset_frame(avctx, h->ref->frame);
|
||||
+}
|
||||
+
|
||||
+static int v4l2_request_hevc_queue_decode(AVCodecContext *avctx, int last_slice)
|
||||
+{
|
||||
+ const HEVCContext *h = avctx->priv_data;
|
||||
+ V4L2RequestControlsHEVC *controls = h->ref->hwaccel_picture_private;
|
||||
+ V4L2RequestContextHEVC *ctx = avctx->internal->hwaccel_priv_data;
|
||||
+
|
||||
+ struct v4l2_ext_control control[] = {
|
||||
+ {
|
||||
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_SPS,
|
||||
+ .ptr = &controls->sps,
|
||||
+ .size = sizeof(controls->sps),
|
||||
+ },
|
||||
+ {
|
||||
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_PPS,
|
||||
+ .ptr = &controls->pps,
|
||||
+ .size = sizeof(controls->pps),
|
||||
+ },
|
||||
+ {
|
||||
+ .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]) * FFMIN(controls->num_slices, 16),
|
||||
+ },
|
||||
+ };
|
||||
+
|
||||
+ if (ctx->decode_mode == V4L2_MPEG_VIDEO_HEVC_DECODE_MODE_SLICE_BASED)
|
||||
+ return ff_v4l2_request_decode_slice(avctx, h->ref->frame, control, FF_ARRAY_ELEMS(control), controls->first_slice, last_slice);
|
||||
+
|
||||
+ return ff_v4l2_request_decode_frame(avctx, h->ref->frame, control, FF_ARRAY_ELEMS(control));
|
||||
+}
|
||||
+
|
||||
+static int v4l2_request_hevc_end_frame(AVCodecContext *avctx)
|
||||
+{
|
||||
+ return v4l2_request_hevc_queue_decode(avctx, 1);
|
||||
+}
|
||||
+
|
||||
+static int v4l2_request_hevc_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
|
||||
+{
|
||||
+ const HEVCContext *h = avctx->priv_data;
|
||||
+ V4L2RequestControlsHEVC *controls = h->ref->hwaccel_picture_private;
|
||||
+ V4L2RequestDescriptor *req = (V4L2RequestDescriptor*)h->ref->frame->data[0];
|
||||
+ V4L2RequestContextHEVC *ctx = avctx->internal->hwaccel_priv_data;
|
||||
+ int ret, slice = FFMIN(controls->num_slices, 15);
|
||||
+
|
||||
+ if (ctx->decode_mode == V4L2_MPEG_VIDEO_HEVC_DECODE_MODE_SLICE_BASED && slice) {
|
||||
+ ret = v4l2_request_hevc_queue_decode(avctx, 0);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ff_v4l2_request_reset_frame(avctx, h->ref->frame);
|
||||
+ slice = controls->num_slices = 0;
|
||||
+ controls->first_slice = 0;
|
||||
+ }
|
||||
+
|
||||
+ v4l2_request_hevc_fill_slice_params(h, &controls->slice_params[slice]);
|
||||
+
|
||||
+ ret = ff_v4l2_request_append_output_buffer(avctx, h->ref->frame, buffer, size);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ controls->slice_params[slice].bit_size = req->output.used * 8; //FIXME
|
||||
+ controls->num_slices++;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int v4l2_request_hevc_set_controls(AVCodecContext *avctx)
|
||||
+{
|
||||
+ V4L2RequestContextHEVC *ctx = avctx->internal->hwaccel_priv_data;
|
||||
+
|
||||
+ struct v4l2_ext_control control[] = {
|
||||
+ { .id = V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE, },
|
||||
+ { .id = V4L2_CID_MPEG_VIDEO_HEVC_START_CODE, },
|
||||
+ };
|
||||
+
|
||||
+ ctx->decode_mode = ff_v4l2_request_query_control_default_value(avctx, V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE);
|
||||
+ if (ctx->decode_mode != V4L2_MPEG_VIDEO_HEVC_DECODE_MODE_SLICE_BASED &&
|
||||
+ ctx->decode_mode != V4L2_MPEG_VIDEO_HEVC_DECODE_MODE_FRAME_BASED) {
|
||||
+ av_log(avctx, AV_LOG_ERROR, "%s: unsupported decode mode, %d\n", __func__, ctx->decode_mode);
|
||||
+ return AVERROR(EINVAL);
|
||||
+ }
|
||||
+
|
||||
+ ctx->start_code = ff_v4l2_request_query_control_default_value(avctx, V4L2_CID_MPEG_VIDEO_HEVC_START_CODE);
|
||||
+ if (ctx->start_code != V4L2_MPEG_VIDEO_HEVC_START_CODE_NONE &&
|
||||
+ ctx->start_code != V4L2_MPEG_VIDEO_HEVC_START_CODE_ANNEX_B) {
|
||||
+ av_log(avctx, AV_LOG_ERROR, "%s: unsupported start code, %d\n", __func__, ctx->start_code);
|
||||
+ return AVERROR(EINVAL);
|
||||
+ }
|
||||
+
|
||||
+ control[0].value = ctx->decode_mode;
|
||||
+ control[1].value = ctx->start_code;
|
||||
+
|
||||
+ return ff_v4l2_request_set_controls(avctx, control, FF_ARRAY_ELEMS(control));
|
||||
+}
|
||||
+
|
||||
+static int v4l2_request_hevc_init(AVCodecContext *avctx)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = ff_v4l2_request_init(avctx, V4L2_PIX_FMT_HEVC_SLICE, 3 * 1024 * 1024, NULL, 0);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ return v4l2_request_hevc_set_controls(avctx);
|
||||
+}
|
||||
+
|
||||
+const AVHWAccel ff_hevc_v4l2request_hwaccel = {
|
||||
+ .name = "hevc_v4l2request",
|
||||
+ .type = AVMEDIA_TYPE_VIDEO,
|
||||
+ .id = AV_CODEC_ID_HEVC,
|
||||
+ .pix_fmt = AV_PIX_FMT_DRM_PRIME,
|
||||
+ .start_frame = v4l2_request_hevc_start_frame,
|
||||
+ .decode_slice = v4l2_request_hevc_decode_slice,
|
||||
+ .end_frame = v4l2_request_hevc_end_frame,
|
||||
+ .frame_priv_data_size = sizeof(V4L2RequestControlsHEVC),
|
||||
+ .init = v4l2_request_hevc_init,
|
||||
+ .uninit = ff_v4l2_request_uninit,
|
||||
+ .priv_data_size = sizeof(V4L2RequestContextHEVC),
|
||||
+ .frame_params = ff_v4l2_request_frame_params,
|
||||
+ .caps_internal = HWACCEL_CAP_ASYNC_SAFE,
|
||||
+};
|
@ -1,282 +0,0 @@
|
||||
From 1084cad0a91e33a95150ff82f1d4ce2a0c180e2c Mon Sep 17 00:00:00 2001
|
||||
From: Boris Brezillon <boris.brezillon@collabora.com>
|
||||
Date: Wed, 22 May 2019 14:46:58 +0200
|
||||
Subject: [PATCH 06/12] Add V4L2 request API vp8 hwaccel
|
||||
|
||||
Need to fix the STREAMOFF/STREAMON issue in a proper way.
|
||||
|
||||
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
|
||||
Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
|
||||
---
|
||||
configure | 3 +
|
||||
libavcodec/Makefile | 1 +
|
||||
libavcodec/hwaccels.h | 1 +
|
||||
libavcodec/v4l2_request_vp8.c | 180 ++++++++++++++++++++++++++++++++++
|
||||
libavcodec/vp8.c | 8 +-
|
||||
5 files changed, 192 insertions(+), 1 deletion(-)
|
||||
create mode 100644 libavcodec/v4l2_request_vp8.c
|
||||
|
||||
diff --git a/configure b/configure
|
||||
index d51ee62a70..6bdfe6fd95 100755
|
||||
--- a/configure
|
||||
+++ b/configure
|
||||
@@ -2975,6 +2975,8 @@ vp8_nvdec_hwaccel_deps="nvdec"
|
||||
vp8_nvdec_hwaccel_select="vp8_decoder"
|
||||
vp8_vaapi_hwaccel_deps="vaapi"
|
||||
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"
|
||||
@@ -6464,6 +6466,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_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 2b53d2b650..55fa28548b 100644
|
||||
--- a/libavcodec/Makefile
|
||||
+++ b/libavcodec/Makefile
|
||||
@@ -910,6 +910,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 3ddc349a4d..d4289320a9 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);
|
||||
@@ -2981,6 +2984,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
|
||||
},
|
@ -1,759 +0,0 @@
|
||||
From e19fbf3c8c161a24e039b93dee2281d5b22e2ca8 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Thu, 14 Feb 2019 23:20:05 +0100
|
||||
Subject: [PATCH 07/12] Add and use private linux headers for V4L2 request API
|
||||
ctrls
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
---
|
||||
configure | 6 +-
|
||||
libavcodec/h264-ctrls.h | 210 +++++++++++++++++++++++++++++
|
||||
libavcodec/hevc-ctrls.h | 229 ++++++++++++++++++++++++++++++++
|
||||
libavcodec/mpeg2-ctrls.h | 82 ++++++++++++
|
||||
libavcodec/v4l2_request_h264.c | 1 +
|
||||
libavcodec/v4l2_request_hevc.c | 1 +
|
||||
libavcodec/v4l2_request_mpeg2.c | 1 +
|
||||
libavcodec/v4l2_request_vp8.c | 1 +
|
||||
libavcodec/vp8-ctrls.h | 112 ++++++++++++++++
|
||||
9 files changed, 640 insertions(+), 3 deletions(-)
|
||||
create mode 100644 libavcodec/h264-ctrls.h
|
||||
create mode 100644 libavcodec/hevc-ctrls.h
|
||||
create mode 100644 libavcodec/mpeg2-ctrls.h
|
||||
create mode 100644 libavcodec/vp8-ctrls.h
|
||||
|
||||
diff --git a/configure b/configure
|
||||
index 6bdfe6fd95..e3a3d82395 100755
|
||||
--- a/configure
|
||||
+++ b/configure
|
||||
@@ -2895,7 +2895,7 @@ h264_dxva2_hwaccel_deps="dxva2"
|
||||
h264_dxva2_hwaccel_select="h264_decoder"
|
||||
h264_nvdec_hwaccel_deps="nvdec"
|
||||
h264_nvdec_hwaccel_select="h264_decoder"
|
||||
-h264_v4l2request_hwaccel_deps="v4l2_request h264_v4l2_request"
|
||||
+h264_v4l2request_hwaccel_deps="v4l2_request"
|
||||
h264_v4l2request_hwaccel_select="h264_decoder"
|
||||
h264_vaapi_hwaccel_deps="vaapi"
|
||||
h264_vaapi_hwaccel_select="h264_decoder"
|
||||
@@ -2911,7 +2911,7 @@ hevc_dxva2_hwaccel_deps="dxva2 DXVA_PicParams_HEVC"
|
||||
hevc_dxva2_hwaccel_select="hevc_decoder"
|
||||
hevc_nvdec_hwaccel_deps="nvdec"
|
||||
hevc_nvdec_hwaccel_select="hevc_decoder"
|
||||
-hevc_v4l2request_hwaccel_deps="v4l2_request hevc_v4l2_request"
|
||||
+hevc_v4l2request_hwaccel_deps="v4l2_request"
|
||||
hevc_v4l2request_hwaccel_select="hevc_decoder"
|
||||
hevc_vaapi_hwaccel_deps="vaapi VAPictureParameterBufferHEVC"
|
||||
hevc_vaapi_hwaccel_select="hevc_decoder"
|
||||
@@ -2975,7 +2975,7 @@ vp8_nvdec_hwaccel_deps="nvdec"
|
||||
vp8_nvdec_hwaccel_select="vp8_decoder"
|
||||
vp8_vaapi_hwaccel_deps="vaapi"
|
||||
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..e877bf1d53
|
||||
--- /dev/null
|
||||
+++ b/libavcodec/h264-ctrls.h
|
||||
@@ -0,0 +1,210 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0 */
|
||||
+/*
|
||||
+ * These are the H.264 state controls for use with stateless H.264
|
||||
+ * 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 _H264_CTRLS_H_
|
||||
+#define _H264_CTRLS_H_
|
||||
+
|
||||
+#include <linux/videodev2.h>
|
||||
+
|
||||
+/* Our pixel format isn't stable at the moment */
|
||||
+#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
|
||||
+ * would be added during the phase where those controls are not
|
||||
+ * stable. It should be fixed eventually.
|
||||
+ */
|
||||
+#define V4L2_CID_MPEG_VIDEO_H264_SPS (V4L2_CID_MPEG_BASE+1000)
|
||||
+#define V4L2_CID_MPEG_VIDEO_H264_PPS (V4L2_CID_MPEG_BASE+1001)
|
||||
+#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
|
||||
+#define V4L2_CTRL_TYPE_H264_PPS 0x0111
|
||||
+#define V4L2_CTRL_TYPE_H264_SCALING_MATRIX 0x0112
|
||||
+#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
|
||||
+#define V4L2_H264_SPS_CONSTRAINT_SET3_FLAG 0x08
|
||||
+#define V4L2_H264_SPS_CONSTRAINT_SET4_FLAG 0x10
|
||||
+#define V4L2_H264_SPS_CONSTRAINT_SET5_FLAG 0x20
|
||||
+
|
||||
+#define V4L2_H264_SPS_FLAG_SEPARATE_COLOUR_PLANE 0x01
|
||||
+#define V4L2_H264_SPS_FLAG_QPPRIME_Y_ZERO_TRANSFORM_BYPASS 0x02
|
||||
+#define V4L2_H264_SPS_FLAG_DELTA_PIC_ORDER_ALWAYS_ZERO 0x04
|
||||
+#define V4L2_H264_SPS_FLAG_GAPS_IN_FRAME_NUM_VALUE_ALLOWED 0x08
|
||||
+#define V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY 0x10
|
||||
+#define V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD 0x20
|
||||
+#define V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE 0x40
|
||||
+
|
||||
+struct v4l2_ctrl_h264_sps {
|
||||
+ __u8 profile_idc;
|
||||
+ __u8 constraint_set_flags;
|
||||
+ __u8 level_idc;
|
||||
+ __u8 seq_parameter_set_id;
|
||||
+ __u8 chroma_format_idc;
|
||||
+ __u8 bit_depth_luma_minus8;
|
||||
+ __u8 bit_depth_chroma_minus8;
|
||||
+ __u8 log2_max_frame_num_minus4;
|
||||
+ __u8 pic_order_cnt_type;
|
||||
+ __u8 log2_max_pic_order_cnt_lsb_minus4;
|
||||
+ __u8 max_num_ref_frames;
|
||||
+ __u8 num_ref_frames_in_pic_order_cnt_cycle;
|
||||
+ __s32 offset_for_ref_frame[255];
|
||||
+ __s32 offset_for_non_ref_pic;
|
||||
+ __s32 offset_for_top_to_bottom_field;
|
||||
+ __u16 pic_width_in_mbs_minus1;
|
||||
+ __u16 pic_height_in_map_units_minus1;
|
||||
+ __u32 flags;
|
||||
+};
|
||||
+
|
||||
+#define V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE 0x0001
|
||||
+#define V4L2_H264_PPS_FLAG_BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT 0x0002
|
||||
+#define V4L2_H264_PPS_FLAG_WEIGHTED_PRED 0x0004
|
||||
+#define V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT 0x0008
|
||||
+#define V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED 0x0010
|
||||
+#define V4L2_H264_PPS_FLAG_REDUNDANT_PIC_CNT_PRESENT 0x0020
|
||||
+#define V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE 0x0040
|
||||
+#define V4L2_H264_PPS_FLAG_PIC_SCALING_MATRIX_PRESENT 0x0080
|
||||
+
|
||||
+struct v4l2_ctrl_h264_pps {
|
||||
+ __u8 pic_parameter_set_id;
|
||||
+ __u8 seq_parameter_set_id;
|
||||
+ __u8 num_slice_groups_minus1;
|
||||
+ __u8 num_ref_idx_l0_default_active_minus1;
|
||||
+ __u8 num_ref_idx_l1_default_active_minus1;
|
||||
+ __u8 weighted_bipred_idc;
|
||||
+ __s8 pic_init_qp_minus26;
|
||||
+ __s8 pic_init_qs_minus26;
|
||||
+ __s8 chroma_qp_index_offset;
|
||||
+ __s8 second_chroma_qp_index_offset;
|
||||
+ __u16 flags;
|
||||
+};
|
||||
+
|
||||
+struct v4l2_ctrl_h264_scaling_matrix {
|
||||
+ __u8 scaling_list_4x4[6][16];
|
||||
+ __u8 scaling_list_8x8[6][64];
|
||||
+};
|
||||
+
|
||||
+struct v4l2_h264_weight_factors {
|
||||
+ __s16 luma_weight[32];
|
||||
+ __s16 luma_offset[32];
|
||||
+ __s16 chroma_weight[32][2];
|
||||
+ __s16 chroma_offset[32][2];
|
||||
+};
|
||||
+
|
||||
+struct v4l2_h264_pred_weight_table {
|
||||
+ __u16 luma_log2_weight_denom;
|
||||
+ __u16 chroma_log2_weight_denom;
|
||||
+ struct v4l2_h264_weight_factors weight_factors[2];
|
||||
+};
|
||||
+
|
||||
+#define V4L2_H264_SLICE_TYPE_P 0
|
||||
+#define V4L2_H264_SLICE_TYPE_B 1
|
||||
+#define V4L2_H264_SLICE_TYPE_I 2
|
||||
+#define V4L2_H264_SLICE_TYPE_SP 3
|
||||
+#define V4L2_H264_SLICE_TYPE_SI 4
|
||||
+
|
||||
+#define V4L2_H264_SLICE_FLAG_FIELD_PIC 0x01
|
||||
+#define V4L2_H264_SLICE_FLAG_BOTTOM_FIELD 0x02
|
||||
+#define V4L2_H264_SLICE_FLAG_DIRECT_SPATIAL_MV_PRED 0x04
|
||||
+#define V4L2_H264_SLICE_FLAG_SP_FOR_SWITCH 0x08
|
||||
+
|
||||
+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;
|
||||
+
|
||||
+ __u16 first_mb_in_slice;
|
||||
+ __u8 slice_type;
|
||||
+ __u8 pic_parameter_set_id;
|
||||
+ __u8 colour_plane_id;
|
||||
+ __u8 redundant_pic_cnt;
|
||||
+ __u16 frame_num;
|
||||
+ __u16 idr_pic_id;
|
||||
+ __u16 pic_order_cnt_lsb;
|
||||
+ __s32 delta_pic_order_cnt_bottom;
|
||||
+ __s32 delta_pic_order_cnt0;
|
||||
+ __s32 delta_pic_order_cnt1;
|
||||
+
|
||||
+ struct v4l2_h264_pred_weight_table pred_weight_table;
|
||||
+ /* Size in bits of dec_ref_pic_marking() syntax element. */
|
||||
+ __u32 dec_ref_pic_marking_bit_size;
|
||||
+ /* Size in bits of pic order count syntax. */
|
||||
+ __u32 pic_order_cnt_bit_size;
|
||||
+
|
||||
+ __u8 cabac_init_idc;
|
||||
+ __s8 slice_qp_delta;
|
||||
+ __s8 slice_qs_delta;
|
||||
+ __u8 disable_deblocking_filter_idc;
|
||||
+ __s8 slice_alpha_c0_offset_div2;
|
||||
+ __s8 slice_beta_offset_div2;
|
||||
+ __u8 num_ref_idx_l0_active_minus1;
|
||||
+ __u8 num_ref_idx_l1_active_minus1;
|
||||
+ __u32 slice_group_change_cycle;
|
||||
+
|
||||
+ /*
|
||||
+ * Entries on each list are indices into
|
||||
+ * v4l2_ctrl_h264_decode_params.dpb[].
|
||||
+ */
|
||||
+ __u8 ref_pic_list0[32];
|
||||
+ __u8 ref_pic_list1[32];
|
||||
+
|
||||
+ __u32 flags;
|
||||
+};
|
||||
+
|
||||
+#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
|
||||
+
|
||||
+struct v4l2_h264_dpb_entry {
|
||||
+ __u64 reference_ts;
|
||||
+ __u16 frame_num;
|
||||
+ __u16 pic_num;
|
||||
+ /* Note that field is indicated by v4l2_buffer.field */
|
||||
+ __s32 top_field_order_cnt;
|
||||
+ __s32 bottom_field_order_cnt;
|
||||
+ __u32 flags; /* V4L2_H264_DPB_ENTRY_FLAG_* */
|
||||
+};
|
||||
+
|
||||
+#define V4L2_H264_DECODE_PARAM_FLAG_IDR_PIC 0x01
|
||||
+
|
||||
+struct v4l2_ctrl_h264_decode_params {
|
||||
+ struct v4l2_h264_dpb_entry dpb[16];
|
||||
+ __u16 num_slices;
|
||||
+ __u16 nal_ref_idc;
|
||||
+ __s32 top_field_order_cnt;
|
||||
+ __s32 bottom_field_order_cnt;
|
||||
+ __u32 flags; /* V4L2_H264_DECODE_PARAM_FLAG_* */
|
||||
+};
|
||||
+
|
||||
+#endif
|
||||
diff --git a/libavcodec/hevc-ctrls.h b/libavcodec/hevc-ctrls.h
|
||||
new file mode 100644
|
||||
index 0000000000..d1b094c8aa
|
||||
--- /dev/null
|
||||
+++ b/libavcodec/hevc-ctrls.h
|
||||
@@ -0,0 +1,229 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0 */
|
||||
+/*
|
||||
+ * These are the HEVC state controls for use with stateless HEVC
|
||||
+ * 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 _HEVC_CTRLS_H_
|
||||
+#define _HEVC_CTRLS_H_
|
||||
+
|
||||
+#include <linux/videodev2.h>
|
||||
+
|
||||
+/* The pixel format isn't stable at the moment and will likely be renamed. */
|
||||
+#define V4L2_PIX_FMT_HEVC_SLICE v4l2_fourcc('S', '2', '6', '5') /* HEVC parsed slices */
|
||||
+
|
||||
+#define V4L2_CID_MPEG_VIDEO_HEVC_SPS (V4L2_CID_MPEG_BASE + 1008)
|
||||
+#define V4L2_CID_MPEG_VIDEO_HEVC_PPS (V4L2_CID_MPEG_BASE + 1009)
|
||||
+#define V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS (V4L2_CID_MPEG_BASE + 1010)
|
||||
+#define V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX (V4L2_CID_MPEG_BASE + 1011)
|
||||
+#define V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE (V4L2_CID_MPEG_BASE + 1015)
|
||||
+#define V4L2_CID_MPEG_VIDEO_HEVC_START_CODE (V4L2_CID_MPEG_BASE + 1016)
|
||||
+
|
||||
+/* enum v4l2_ctrl_type type values */
|
||||
+#define V4L2_CTRL_TYPE_HEVC_SPS 0x0120
|
||||
+#define V4L2_CTRL_TYPE_HEVC_PPS 0x0121
|
||||
+#define V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS 0x0122
|
||||
+#define V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX 0x0123
|
||||
+
|
||||
+enum v4l2_mpeg_video_hevc_decode_mode {
|
||||
+ V4L2_MPEG_VIDEO_HEVC_DECODE_MODE_SLICE_BASED,
|
||||
+ V4L2_MPEG_VIDEO_HEVC_DECODE_MODE_FRAME_BASED,
|
||||
+};
|
||||
+
|
||||
+enum v4l2_mpeg_video_hevc_start_code {
|
||||
+ V4L2_MPEG_VIDEO_HEVC_START_CODE_NONE,
|
||||
+ V4L2_MPEG_VIDEO_HEVC_START_CODE_ANNEX_B,
|
||||
+};
|
||||
+
|
||||
+#define V4L2_HEVC_SLICE_TYPE_B 0
|
||||
+#define V4L2_HEVC_SLICE_TYPE_P 1
|
||||
+#define V4L2_HEVC_SLICE_TYPE_I 2
|
||||
+
|
||||
+#define V4L2_HEVC_SPS_FLAG_SEPARATE_COLOUR_PLANE (1ULL << 0)
|
||||
+#define V4L2_HEVC_SPS_FLAG_SCALING_LIST_ENABLED (1ULL << 1)
|
||||
+#define V4L2_HEVC_SPS_FLAG_AMP_ENABLED (1ULL << 2)
|
||||
+#define V4L2_HEVC_SPS_FLAG_SAMPLE_ADAPTIVE_OFFSET (1ULL << 3)
|
||||
+#define V4L2_HEVC_SPS_FLAG_PCM_ENABLED (1ULL << 4)
|
||||
+#define V4L2_HEVC_SPS_FLAG_PCM_LOOP_FILTER_DISABLED (1ULL << 5)
|
||||
+#define V4L2_HEVC_SPS_FLAG_LONG_TERM_REF_PICS_PRESENT (1ULL << 6)
|
||||
+#define V4L2_HEVC_SPS_FLAG_SPS_TEMPORAL_MVP_ENABLED (1ULL << 7)
|
||||
+#define V4L2_HEVC_SPS_FLAG_STRONG_INTRA_SMOOTHING_ENABLED (1ULL << 8)
|
||||
+
|
||||
+/* The controls are not stable at the moment and will likely be reworked. */
|
||||
+struct v4l2_ctrl_hevc_sps {
|
||||
+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: Sequence parameter set */
|
||||
+ __u16 pic_width_in_luma_samples;
|
||||
+ __u16 pic_height_in_luma_samples;
|
||||
+ __u8 bit_depth_luma_minus8;
|
||||
+ __u8 bit_depth_chroma_minus8;
|
||||
+ __u8 log2_max_pic_order_cnt_lsb_minus4;
|
||||
+ __u8 sps_max_dec_pic_buffering_minus1;
|
||||
+ __u8 sps_max_num_reorder_pics;
|
||||
+ __u8 sps_max_latency_increase_plus1;
|
||||
+ __u8 log2_min_luma_coding_block_size_minus3;
|
||||
+ __u8 log2_diff_max_min_luma_coding_block_size;
|
||||
+ __u8 log2_min_luma_transform_block_size_minus2;
|
||||
+ __u8 log2_diff_max_min_luma_transform_block_size;
|
||||
+ __u8 max_transform_hierarchy_depth_inter;
|
||||
+ __u8 max_transform_hierarchy_depth_intra;
|
||||
+ __u8 pcm_sample_bit_depth_luma_minus1;
|
||||
+ __u8 pcm_sample_bit_depth_chroma_minus1;
|
||||
+ __u8 log2_min_pcm_luma_coding_block_size_minus3;
|
||||
+ __u8 log2_diff_max_min_pcm_luma_coding_block_size;
|
||||
+ __u8 num_short_term_ref_pic_sets;
|
||||
+ __u8 num_long_term_ref_pics_sps;
|
||||
+ __u8 chroma_format_idc;
|
||||
+
|
||||
+ __u8 padding;
|
||||
+
|
||||
+ __u64 flags;
|
||||
+};
|
||||
+
|
||||
+#define V4L2_HEVC_PPS_FLAG_DEPENDENT_SLICE_SEGMENT (1ULL << 0)
|
||||
+#define V4L2_HEVC_PPS_FLAG_OUTPUT_FLAG_PRESENT (1ULL << 1)
|
||||
+#define V4L2_HEVC_PPS_FLAG_SIGN_DATA_HIDING_ENABLED (1ULL << 2)
|
||||
+#define V4L2_HEVC_PPS_FLAG_CABAC_INIT_PRESENT (1ULL << 3)
|
||||
+#define V4L2_HEVC_PPS_FLAG_CONSTRAINED_INTRA_PRED (1ULL << 4)
|
||||
+#define V4L2_HEVC_PPS_FLAG_TRANSFORM_SKIP_ENABLED (1ULL << 5)
|
||||
+#define V4L2_HEVC_PPS_FLAG_CU_QP_DELTA_ENABLED (1ULL << 6)
|
||||
+#define V4L2_HEVC_PPS_FLAG_PPS_SLICE_CHROMA_QP_OFFSETS_PRESENT (1ULL << 7)
|
||||
+#define V4L2_HEVC_PPS_FLAG_WEIGHTED_PRED (1ULL << 8)
|
||||
+#define V4L2_HEVC_PPS_FLAG_WEIGHTED_BIPRED (1ULL << 9)
|
||||
+#define V4L2_HEVC_PPS_FLAG_TRANSQUANT_BYPASS_ENABLED (1ULL << 10)
|
||||
+#define V4L2_HEVC_PPS_FLAG_TILES_ENABLED (1ULL << 11)
|
||||
+#define V4L2_HEVC_PPS_FLAG_ENTROPY_CODING_SYNC_ENABLED (1ULL << 12)
|
||||
+#define V4L2_HEVC_PPS_FLAG_LOOP_FILTER_ACROSS_TILES_ENABLED (1ULL << 13)
|
||||
+#define V4L2_HEVC_PPS_FLAG_PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED (1ULL << 14)
|
||||
+#define V4L2_HEVC_PPS_FLAG_DEBLOCKING_FILTER_OVERRIDE_ENABLED (1ULL << 15)
|
||||
+#define V4L2_HEVC_PPS_FLAG_PPS_DISABLE_DEBLOCKING_FILTER (1ULL << 16)
|
||||
+#define V4L2_HEVC_PPS_FLAG_LISTS_MODIFICATION_PRESENT (1ULL << 17)
|
||||
+#define V4L2_HEVC_PPS_FLAG_SLICE_SEGMENT_HEADER_EXTENSION_PRESENT (1ULL << 18)
|
||||
+
|
||||
+struct v4l2_ctrl_hevc_pps {
|
||||
+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: Picture parameter set */
|
||||
+ __u8 num_extra_slice_header_bits;
|
||||
+ __s8 init_qp_minus26;
|
||||
+ __u8 diff_cu_qp_delta_depth;
|
||||
+ __s8 pps_cb_qp_offset;
|
||||
+ __s8 pps_cr_qp_offset;
|
||||
+ __u8 num_tile_columns_minus1;
|
||||
+ __u8 num_tile_rows_minus1;
|
||||
+ __u8 column_width_minus1[20];
|
||||
+ __u8 row_height_minus1[22];
|
||||
+ __s8 pps_beta_offset_div2;
|
||||
+ __s8 pps_tc_offset_div2;
|
||||
+ __u8 log2_parallel_merge_level_minus2;
|
||||
+
|
||||
+ __u8 padding[4];
|
||||
+ __u64 flags;
|
||||
+};
|
||||
+
|
||||
+#define V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_BEFORE 0x01
|
||||
+#define V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_AFTER 0x02
|
||||
+#define V4L2_HEVC_DPB_ENTRY_RPS_LT_CURR 0x03
|
||||
+
|
||||
+#define V4L2_HEVC_DPB_ENTRIES_NUM_MAX 16
|
||||
+
|
||||
+struct v4l2_hevc_dpb_entry {
|
||||
+ __u64 timestamp;
|
||||
+ __u8 rps;
|
||||
+ __u8 field_pic;
|
||||
+ __u16 pic_order_cnt[2];
|
||||
+ __u8 padding[2];
|
||||
+};
|
||||
+
|
||||
+struct v4l2_hevc_pred_weight_table {
|
||||
+ __s8 delta_luma_weight_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
|
||||
+ __s8 luma_offset_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
|
||||
+ __s8 delta_chroma_weight_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX][2];
|
||||
+ __s8 chroma_offset_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX][2];
|
||||
+
|
||||
+ __s8 delta_luma_weight_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
|
||||
+ __s8 luma_offset_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
|
||||
+ __s8 delta_chroma_weight_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX][2];
|
||||
+ __s8 chroma_offset_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX][2];
|
||||
+
|
||||
+ __u8 padding[6];
|
||||
+
|
||||
+ __u8 luma_log2_weight_denom;
|
||||
+ __s8 delta_chroma_log2_weight_denom;
|
||||
+};
|
||||
+
|
||||
+#define V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_SAO_LUMA (1ULL << 0)
|
||||
+#define V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_SAO_CHROMA (1ULL << 1)
|
||||
+#define V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_TEMPORAL_MVP_ENABLED (1ULL << 2)
|
||||
+#define V4L2_HEVC_SLICE_PARAMS_FLAG_MVD_L1_ZERO (1ULL << 3)
|
||||
+#define V4L2_HEVC_SLICE_PARAMS_FLAG_CABAC_INIT (1ULL << 4)
|
||||
+#define V4L2_HEVC_SLICE_PARAMS_FLAG_COLLOCATED_FROM_L0 (1ULL << 5)
|
||||
+#define V4L2_HEVC_SLICE_PARAMS_FLAG_USE_INTEGER_MV (1ULL << 6)
|
||||
+#define V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_DEBLOCKING_FILTER_DISABLED (1ULL << 7)
|
||||
+#define V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_LOOP_FILTER_ACROSS_SLICES_ENABLED (1ULL << 8)
|
||||
+
|
||||
+struct v4l2_ctrl_hevc_slice_params {
|
||||
+ __u32 bit_size;
|
||||
+ __u32 data_bit_offset;
|
||||
+
|
||||
+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: General slice segment header */
|
||||
+ __u32 slice_segment_addr;
|
||||
+ __u32 num_entry_point_offsets;
|
||||
+
|
||||
+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: NAL unit header */
|
||||
+ __u8 nal_unit_type;
|
||||
+ __u8 nuh_temporal_id_plus1;
|
||||
+
|
||||
+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: General slice segment header */
|
||||
+ __u8 slice_type;
|
||||
+ __u8 colour_plane_id;
|
||||
+ __u16 slice_pic_order_cnt;
|
||||
+ __u8 num_ref_idx_l0_active_minus1;
|
||||
+ __u8 num_ref_idx_l1_active_minus1;
|
||||
+ __u8 collocated_ref_idx;
|
||||
+ __u8 five_minus_max_num_merge_cand;
|
||||
+ __s8 slice_qp_delta;
|
||||
+ __s8 slice_cb_qp_offset;
|
||||
+ __s8 slice_cr_qp_offset;
|
||||
+ __s8 slice_act_y_qp_offset;
|
||||
+ __s8 slice_act_cb_qp_offset;
|
||||
+ __s8 slice_act_cr_qp_offset;
|
||||
+ __s8 slice_beta_offset_div2;
|
||||
+ __s8 slice_tc_offset_div2;
|
||||
+
|
||||
+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: Picture timing SEI message */
|
||||
+ __u8 pic_struct;
|
||||
+
|
||||
+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: General slice segment header */
|
||||
+ __u8 num_active_dpb_entries;
|
||||
+ __u8 ref_idx_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
|
||||
+ __u8 ref_idx_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
|
||||
+
|
||||
+ __u8 num_rps_poc_st_curr_before;
|
||||
+ __u8 num_rps_poc_st_curr_after;
|
||||
+ __u8 num_rps_poc_lt_curr;
|
||||
+
|
||||
+ __u8 padding;
|
||||
+
|
||||
+ __u32 entry_point_offset_minus1[256];
|
||||
+
|
||||
+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: General slice segment header */
|
||||
+ struct v4l2_hevc_dpb_entry dpb[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
|
||||
+
|
||||
+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: Weighted prediction parameter */
|
||||
+ struct v4l2_hevc_pred_weight_table pred_weight_table;
|
||||
+
|
||||
+ __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];
|
||||
+};
|
||||
+
|
||||
+#endif
|
||||
diff --git a/libavcodec/mpeg2-ctrls.h b/libavcodec/mpeg2-ctrls.h
|
||||
new file mode 100644
|
||||
index 0000000000..6601455b3d
|
||||
--- /dev/null
|
||||
+++ b/libavcodec/mpeg2-ctrls.h
|
||||
@@ -0,0 +1,82 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0 */
|
||||
+/*
|
||||
+ * These are the MPEG2 state controls for use with stateless MPEG-2
|
||||
+ * 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 _MPEG2_CTRLS_H_
|
||||
+#define _MPEG2_CTRLS_H_
|
||||
+
|
||||
+#define V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS (V4L2_CID_MPEG_BASE+250)
|
||||
+#define V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION (V4L2_CID_MPEG_BASE+251)
|
||||
+
|
||||
+/* enum v4l2_ctrl_type type values */
|
||||
+#define V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS 0x0103
|
||||
+#define V4L2_CTRL_TYPE_MPEG2_QUANTIZATION 0x0104
|
||||
+
|
||||
+#define V4L2_MPEG2_PICTURE_CODING_TYPE_I 1
|
||||
+#define V4L2_MPEG2_PICTURE_CODING_TYPE_P 2
|
||||
+#define V4L2_MPEG2_PICTURE_CODING_TYPE_B 3
|
||||
+#define V4L2_MPEG2_PICTURE_CODING_TYPE_D 4
|
||||
+
|
||||
+struct v4l2_mpeg2_sequence {
|
||||
+ /* ISO/IEC 13818-2, ITU-T Rec. H.262: Sequence header */
|
||||
+ __u16 horizontal_size;
|
||||
+ __u16 vertical_size;
|
||||
+ __u32 vbv_buffer_size;
|
||||
+
|
||||
+ /* ISO/IEC 13818-2, ITU-T Rec. H.262: Sequence extension */
|
||||
+ __u16 profile_and_level_indication;
|
||||
+ __u8 progressive_sequence;
|
||||
+ __u8 chroma_format;
|
||||
+};
|
||||
+
|
||||
+struct v4l2_mpeg2_picture {
|
||||
+ /* ISO/IEC 13818-2, ITU-T Rec. H.262: Picture header */
|
||||
+ __u8 picture_coding_type;
|
||||
+
|
||||
+ /* ISO/IEC 13818-2, ITU-T Rec. H.262: Picture coding extension */
|
||||
+ __u8 f_code[2][2];
|
||||
+ __u8 intra_dc_precision;
|
||||
+ __u8 picture_structure;
|
||||
+ __u8 top_field_first;
|
||||
+ __u8 frame_pred_frame_dct;
|
||||
+ __u8 concealment_motion_vectors;
|
||||
+ __u8 q_scale_type;
|
||||
+ __u8 intra_vlc_format;
|
||||
+ __u8 alternate_scan;
|
||||
+ __u8 repeat_first_field;
|
||||
+ __u16 progressive_frame;
|
||||
+};
|
||||
+
|
||||
+struct v4l2_ctrl_mpeg2_slice_params {
|
||||
+ __u32 bit_size;
|
||||
+ __u32 data_bit_offset;
|
||||
+ __u64 backward_ref_ts;
|
||||
+ __u64 forward_ref_ts;
|
||||
+
|
||||
+ struct v4l2_mpeg2_sequence sequence;
|
||||
+ struct v4l2_mpeg2_picture picture;
|
||||
+
|
||||
+ /* ISO/IEC 13818-2, ITU-T Rec. H.262: Slice */
|
||||
+ __u32 quantiser_scale_code;
|
||||
+};
|
||||
+
|
||||
+struct v4l2_ctrl_mpeg2_quantization {
|
||||
+ /* ISO/IEC 13818-2, ITU-T Rec. H.262: Quant matrix extension */
|
||||
+ __u8 load_intra_quantiser_matrix;
|
||||
+ __u8 load_non_intra_quantiser_matrix;
|
||||
+ __u8 load_chroma_intra_quantiser_matrix;
|
||||
+ __u8 load_chroma_non_intra_quantiser_matrix;
|
||||
+
|
||||
+ __u8 intra_quantiser_matrix[64];
|
||||
+ __u8 non_intra_quantiser_matrix[64];
|
||||
+ __u8 chroma_intra_quantiser_matrix[64];
|
||||
+ __u8 chroma_non_intra_quantiser_matrix[64];
|
||||
+};
|
||||
+
|
||||
+#endif
|
||||
diff --git a/libavcodec/v4l2_request_h264.c b/libavcodec/v4l2_request_h264.c
|
||||
index 81b3c4b092..ca306b6a3f 100644
|
||||
--- a/libavcodec/v4l2_request_h264.c
|
||||
+++ b/libavcodec/v4l2_request_h264.c
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "h264dec.h"
|
||||
#include "hwaccel.h"
|
||||
#include "v4l2_request.h"
|
||||
+#include "h264-ctrls.h"
|
||||
|
||||
typedef struct V4L2RequestControlsH264 {
|
||||
struct v4l2_ctrl_h264_sps sps;
|
||||
diff --git a/libavcodec/v4l2_request_hevc.c b/libavcodec/v4l2_request_hevc.c
|
||||
index da1fd666d7..94977c5d0e 100644
|
||||
--- a/libavcodec/v4l2_request_hevc.c
|
||||
+++ b/libavcodec/v4l2_request_hevc.c
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "hevcdec.h"
|
||||
#include "hwaccel.h"
|
||||
#include "v4l2_request.h"
|
||||
+#include "hevc-ctrls.h"
|
||||
|
||||
typedef struct V4L2RequestControlsHEVC {
|
||||
struct v4l2_ctrl_hevc_sps sps;
|
||||
diff --git a/libavcodec/v4l2_request_mpeg2.c b/libavcodec/v4l2_request_mpeg2.c
|
||||
index 782b9c2471..37a4eae62c 100644
|
||||
--- a/libavcodec/v4l2_request_mpeg2.c
|
||||
+++ b/libavcodec/v4l2_request_mpeg2.c
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "hwaccel.h"
|
||||
#include "mpegvideo.h"
|
||||
#include "v4l2_request.h"
|
||||
+#include "mpeg2-ctrls.h"
|
||||
|
||||
typedef struct V4L2RequestControlsMPEG2 {
|
||||
struct v4l2_ctrl_mpeg2_slice_params slice_params;
|
||||
diff --git a/libavcodec/v4l2_request_vp8.c b/libavcodec/v4l2_request_vp8.c
|
||||
index d24252c5e5..c290fe8b9a 100644
|
||||
--- a/libavcodec/v4l2_request_vp8.c
|
||||
+++ b/libavcodec/v4l2_request_vp8.c
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "hwaccel.h"
|
||||
#include "v4l2_request.h"
|
||||
#include "vp8.h"
|
||||
+#include "vp8-ctrls.h"
|
||||
|
||||
typedef struct V4L2RequestControlsVP8 {
|
||||
struct v4l2_ctrl_vp8_frame_header ctrl;
|
||||
diff --git a/libavcodec/vp8-ctrls.h b/libavcodec/vp8-ctrls.h
|
||||
new file mode 100644
|
||||
index 0000000000..53cba826e4
|
||||
--- /dev/null
|
||||
+++ b/libavcodec/vp8-ctrls.h
|
||||
@@ -0,0 +1,112 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0 */
|
||||
+/*
|
||||
+ * These are the VP8 state controls for use with stateless VP8
|
||||
+ * codec drivers.
|
||||
+ *
|
||||
+ * It turns out that these structs are not stable yet and will undergo
|
||||
+ * more changes. So keep them private until they are stable and ready to
|
||||
+ * become part of the official public API.
|
||||
+ */
|
||||
+
|
||||
+#ifndef _VP8_CTRLS_H_
|
||||
+#define _VP8_CTRLS_H_
|
||||
+
|
||||
+#include <linux/types.h>
|
||||
+
|
||||
+#define V4L2_PIX_FMT_VP8_FRAME v4l2_fourcc('V', 'P', '8', 'F')
|
||||
+
|
||||
+#define V4L2_CID_MPEG_VIDEO_VP8_FRAME_HEADER (V4L2_CID_MPEG_BASE + 2000)
|
||||
+#define V4L2_CTRL_TYPE_VP8_FRAME_HEADER 0x301
|
||||
+
|
||||
+#define V4L2_VP8_SEGMENT_HEADER_FLAG_ENABLED 0x01
|
||||
+#define V4L2_VP8_SEGMENT_HEADER_FLAG_UPDATE_MAP 0x02
|
||||
+#define V4L2_VP8_SEGMENT_HEADER_FLAG_UPDATE_FEATURE_DATA 0x04
|
||||
+#define V4L2_VP8_SEGMENT_HEADER_FLAG_DELTA_VALUE_MODE 0x08
|
||||
+
|
||||
+struct v4l2_vp8_segment_header {
|
||||
+ __s8 quant_update[4];
|
||||
+ __s8 lf_update[4];
|
||||
+ __u8 segment_probs[3];
|
||||
+ __u8 padding;
|
||||
+ __u32 flags;
|
||||
+};
|
||||
+
|
||||
+#define V4L2_VP8_LF_HEADER_ADJ_ENABLE 0x01
|
||||
+#define V4L2_VP8_LF_HEADER_DELTA_UPDATE 0x02
|
||||
+#define V4L2_VP8_LF_FILTER_TYPE_SIMPLE 0x04
|
||||
+struct v4l2_vp8_loopfilter_header {
|
||||
+ __s8 ref_frm_delta[4];
|
||||
+ __s8 mb_mode_delta[4];
|
||||
+ __u8 sharpness_level;
|
||||
+ __u8 level;
|
||||
+ __u16 padding;
|
||||
+ __u32 flags;
|
||||
+};
|
||||
+
|
||||
+struct v4l2_vp8_quantization_header {
|
||||
+ __u8 y_ac_qi;
|
||||
+ __s8 y_dc_delta;
|
||||
+ __s8 y2_dc_delta;
|
||||
+ __s8 y2_ac_delta;
|
||||
+ __s8 uv_dc_delta;
|
||||
+ __s8 uv_ac_delta;
|
||||
+ __u16 padding;
|
||||
+};
|
||||
+
|
||||
+struct v4l2_vp8_entropy_header {
|
||||
+ __u8 coeff_probs[4][8][3][11];
|
||||
+ __u8 y_mode_probs[4];
|
||||
+ __u8 uv_mode_probs[3];
|
||||
+ __u8 mv_probs[2][19];
|
||||
+ __u8 padding[3];
|
||||
+};
|
||||
+
|
||||
+struct v4l2_vp8_entropy_coder_state {
|
||||
+ __u8 range;
|
||||
+ __u8 value;
|
||||
+ __u8 bit_count;
|
||||
+ __u8 padding;
|
||||
+};
|
||||
+
|
||||
+#define V4L2_VP8_FRAME_HEADER_FLAG_KEY_FRAME 0x01
|
||||
+#define V4L2_VP8_FRAME_HEADER_FLAG_EXPERIMENTAL 0x02
|
||||
+#define V4L2_VP8_FRAME_HEADER_FLAG_SHOW_FRAME 0x04
|
||||
+#define V4L2_VP8_FRAME_HEADER_FLAG_MB_NO_SKIP_COEFF 0x08
|
||||
+#define V4L2_VP8_FRAME_HEADER_FLAG_SIGN_BIAS_GOLDEN 0x10
|
||||
+#define V4L2_VP8_FRAME_HEADER_FLAG_SIGN_BIAS_ALT 0x20
|
||||
+
|
||||
+#define VP8_FRAME_IS_KEY_FRAME(hdr) \
|
||||
+ (!!((hdr)->flags & V4L2_VP8_FRAME_HEADER_FLAG_KEY_FRAME))
|
||||
+
|
||||
+struct v4l2_ctrl_vp8_frame_header {
|
||||
+ struct v4l2_vp8_segment_header segment_header;
|
||||
+ struct v4l2_vp8_loopfilter_header lf_header;
|
||||
+ struct v4l2_vp8_quantization_header quant_header;
|
||||
+ struct v4l2_vp8_entropy_header entropy_header;
|
||||
+ struct v4l2_vp8_entropy_coder_state coder_state;
|
||||
+
|
||||
+ __u16 width;
|
||||
+ __u16 height;
|
||||
+
|
||||
+ __u8 horizontal_scale;
|
||||
+ __u8 vertical_scale;
|
||||
+
|
||||
+ __u8 version;
|
||||
+ __u8 prob_skip_false;
|
||||
+ __u8 prob_intra;
|
||||
+ __u8 prob_last;
|
||||
+ __u8 prob_gf;
|
||||
+ __u8 num_dct_parts;
|
||||
+
|
||||
+ __u32 first_part_size;
|
||||
+ __u32 first_part_header_bits;
|
||||
+ __u32 dct_part_sizes[8];
|
||||
+
|
||||
+ __u64 last_frame_ts;
|
||||
+ __u64 golden_frame_ts;
|
||||
+ __u64 alt_frame_ts;
|
||||
+
|
||||
+ __u64 flags;
|
||||
+};
|
||||
+
|
||||
+#endif
|
@ -1,26 +0,0 @@
|
||||
From 60383b61fa64aa0e2806de0b8cf8a3f8d85c41e4 Mon Sep 17 00:00:00 2001
|
||||
From: Jonas Karlman <jonas@kwiboo.se>
|
||||
Date: Mon, 29 Apr 2019 22:08:59 +0000
|
||||
Subject: [PATCH 08/12] hwcontext_drm: do not require drm device
|
||||
|
||||
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
||||
---
|
||||
libavutil/hwcontext_drm.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/libavutil/hwcontext_drm.c b/libavutil/hwcontext_drm.c
|
||||
index 32cbde82eb..aa4794c5e6 100644
|
||||
--- a/libavutil/hwcontext_drm.c
|
||||
+++ b/libavutil/hwcontext_drm.c
|
||||
@@ -43,6 +43,11 @@ static int drm_device_create(AVHWDeviceContext *hwdev, const char *device,
|
||||
AVDRMDeviceContext *hwctx = hwdev->hwctx;
|
||||
drmVersionPtr version;
|
||||
|
||||
+ if (device == NULL) {
|
||||
+ hwctx->fd = -1;
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
hwctx->fd = open(device, O_RDWR);
|
||||
if (hwctx->fd < 0)
|
||||
return AVERROR(errno);
|
@ -1,51 +0,0 @@
|
||||
From 4e1a25f7cbbe9978548680171580afdfbf84d603 Mon Sep 17 00:00:00 2001
|
||||
From: Ezequiel Garcia <ezequiel@collabora.com>
|
||||
Date: Wed, 20 Feb 2019 11:18:00 -0300
|
||||
Subject: [PATCH 09/12] avcodec/h264: parse idr_pic_id
|
||||
|
||||
Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
|
||||
---
|
||||
libavcodec/h264_slice.c | 2 +-
|
||||
libavcodec/h264dec.h | 2 ++
|
||||
libavcodec/v4l2_request_h264.c | 2 +-
|
||||
3 files changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c
|
||||
index 9912ede703..18ba196246 100644
|
||||
--- a/libavcodec/h264_slice.c
|
||||
+++ b/libavcodec/h264_slice.c
|
||||
@@ -1824,7 +1824,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 ca306b6a3f..f21c8b3508 100644
|
||||
--- a/libavcodec/v4l2_request_h264.c
|
||||
+++ b/libavcodec/v4l2_request_h264.c
|
||||
@@ -301,7 +301,7 @@ static int v4l2_request_h264_decode_slice(AVCodecContext *avctx, const uint8_t *
|
||||
.pic_parameter_set_id = sl->pps_id,
|
||||
.colour_plane_id = 0, /* what is this? */
|
||||
.frame_num = h->poc.frame_num,
|
||||
- .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],
|
@ -1,88 +0,0 @@
|
||||
From 8309a49f4049b6ec8d4fd76a5dc18f8d23f8315c Mon Sep 17 00:00:00 2001
|
||||
From: Boris Brezillon <boris.brezillon@collabora.com>
|
||||
Date: Wed, 22 May 2019 14:44:22 +0200
|
||||
Subject: [PATCH 10/12] avcodec/h264: parse ref_pic_marking_size_in_bits and
|
||||
pic_order_cnt_bit_size
|
||||
|
||||
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
|
||||
---
|
||||
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 18ba196246..1bd3388f1e 100644
|
||||
--- a/libavcodec/h264_slice.c
|
||||
+++ b/libavcodec/h264_slice.c
|
||||
@@ -1736,7 +1736,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);
|
||||
@@ -1826,6 +1826,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);
|
||||
|
||||
@@ -1839,6 +1840,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)
|
||||
@@ -1878,9 +1880,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 f21c8b3508..1a7fb873a0 100644
|
||||
--- a/libavcodec/v4l2_request_h264.c
|
||||
+++ b/libavcodec/v4l2_request_h264.c
|
||||
@@ -309,9 +309,9 @@ static int v4l2_request_h264_decode_slice(AVCodecContext *avctx, const uint8_t *
|
||||
.redundant_pic_cnt = sl->redundant_pic_count,
|
||||
|
||||
/* Size in bits of dec_ref_pic_marking() syntax element. */
|
||||
- .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,
|
@ -1,57 +0,0 @@
|
||||
From ace9eff28953b97fc1832913d4655c0f4227ea16 Mon Sep 17 00:00:00 2001
|
||||
From: Jonas Karlman <jonas@kwiboo.se>
|
||||
Date: Fri, 24 May 2019 22:58:24 +0000
|
||||
Subject: [PATCH 11/12] HACK: add dpb flags for reference usage and field
|
||||
picture
|
||||
|
||||
This or something similar needs to be upstreamed to kernel h264 ctrls
|
||||
|
||||
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
||||
---
|
||||
libavcodec/h264-ctrls.h | 4 ++++
|
||||
libavcodec/v4l2_request_h264.c | 6 +++++-
|
||||
2 files changed, 9 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libavcodec/h264-ctrls.h b/libavcodec/h264-ctrls.h
|
||||
index e877bf1d53..76020ebd1e 100644
|
||||
--- a/libavcodec/h264-ctrls.h
|
||||
+++ b/libavcodec/h264-ctrls.h
|
||||
@@ -185,6 +185,10 @@ struct v4l2_ctrl_h264_slice_params {
|
||||
#define V4L2_H264_DPB_ENTRY_FLAG_VALID 0x01
|
||||
#define V4L2_H264_DPB_ENTRY_FLAG_ACTIVE 0x02
|
||||
#define V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM 0x04
|
||||
+#define V4L2_H264_DPB_ENTRY_FLAG_FIELD_PICTURE 0x08
|
||||
+#define V4L2_H264_DPB_ENTRY_FLAG_REF_TOP 0x10
|
||||
+#define V4L2_H264_DPB_ENTRY_FLAG_REF_BOTTOM 0x20
|
||||
+#define V4L2_H264_DPB_ENTRY_FLAG_REF_FRAME 0x30
|
||||
|
||||
struct v4l2_h264_dpb_entry {
|
||||
__u64 reference_ts;
|
||||
diff --git a/libavcodec/v4l2_request_h264.c b/libavcodec/v4l2_request_h264.c
|
||||
index 1a7fb873a0..13fac3f6f9 100644
|
||||
--- a/libavcodec/v4l2_request_h264.c
|
||||
+++ b/libavcodec/v4l2_request_h264.c
|
||||
@@ -66,10 +66,13 @@ static void fill_dpb_entry(struct v4l2_h264_dpb_entry *entry, const H264Picture
|
||||
entry->frame_num = pic->frame_num;
|
||||
entry->pic_num = pic->pic_id;
|
||||
entry->flags = V4L2_H264_DPB_ENTRY_FLAG_VALID;
|
||||
+ 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)
|
||||
@@ -109,7 +112,8 @@ static uint8_t get_dpb_index(struct v4l2_ctrl_h264_decode_params *decode, const
|
||||
struct v4l2_h264_dpb_entry *entry = &decode->dpb[i];
|
||||
if ((entry->flags & V4L2_H264_DPB_ENTRY_FLAG_VALID) &&
|
||||
entry->reference_ts == timestamp)
|
||||
- return i;
|
||||
+ // TODO: signal reference type, possible using top 2 bits
|
||||
+ return i | ((ref->reference & 3) << 6);
|
||||
}
|
||||
|
||||
return 0;
|
@ -1,69 +0,0 @@
|
||||
From fa3f88530ec9083ff15d9637a9019a8a9408435b Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Sat, 9 Nov 2019 10:02:43 +0000
|
||||
Subject: [PATCH 12/12] WIP: v4l2-request: rolling timestamps
|
||||
|
||||
---
|
||||
libavcodec/v4l2_request.c | 10 +++++++---
|
||||
libavcodec/v4l2_request.h | 1 +
|
||||
2 files changed, 8 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/libavcodec/v4l2_request.c b/libavcodec/v4l2_request.c
|
||||
index 1dabf77689..611c22f8b6 100644
|
||||
--- a/libavcodec/v4l2_request.c
|
||||
+++ b/libavcodec/v4l2_request.c
|
||||
@@ -105,12 +105,14 @@ static int v4l2_request_queue_buffer(V4L2RequestContext *ctx, int request_fd, V4
|
||||
.type = buf->buffer.type,
|
||||
.memory = buf->buffer.memory,
|
||||
.index = buf->index,
|
||||
- .timestamp.tv_usec = buf->index + 1,
|
||||
+ .timestamp.tv_usec = ctx->timestamp,
|
||||
.bytesused = buf->used,
|
||||
.request_fd = request_fd,
|
||||
.flags = ((request_fd >= 0) ? V4L2_BUF_FLAG_REQUEST_FD : 0) | flags,
|
||||
};
|
||||
|
||||
+ buf->buffer.timestamp = buffer.timestamp;
|
||||
+
|
||||
if (V4L2_TYPE_IS_MULTIPLANAR(buf->buffer.type)) {
|
||||
planes[0].bytesused = buf->used;
|
||||
buffer.bytesused = 0;
|
||||
@@ -200,6 +202,9 @@ static int v4l2_request_queue_decode(AVCodecContext *avctx, AVFrame *frame, stru
|
||||
|
||||
av_log(avctx, AV_LOG_DEBUG, "%s: avctx=%p used=%u controls=%d index=%d fd=%d request_fd=%d first_slice=%d last_slice=%d\n", __func__, avctx, req->output.used, count, req->capture.index, req->capture.fd, req->request_fd, first_slice, last_slice);
|
||||
|
||||
+ if (first_slice)
|
||||
+ ctx->timestamp++;
|
||||
+
|
||||
ret = v4l2_request_set_controls(ctx, req->request_fd, control, count);
|
||||
if (ret < 0) {
|
||||
av_log(avctx, AV_LOG_ERROR, "%s: set controls failed for request %d, %s (%d)\n", __func__, req->request_fd, strerror(errno), errno);
|
||||
@@ -651,6 +656,7 @@ int ff_v4l2_request_init(AVCodecContext *avctx, uint32_t pixelformat, uint32_t b
|
||||
|
||||
ctx->media_fd = -1;
|
||||
ctx->video_fd = -1;
|
||||
+ ctx->timestamp = 0;
|
||||
|
||||
udev = udev_new();
|
||||
if (!udev) {
|
||||
@@ -784,8 +790,6 @@ static int v4l2_request_buffer_alloc(AVCodecContext *avctx, V4L2RequestBuffer *b
|
||||
return ret;
|
||||
}
|
||||
|
||||
- buf->buffer.timestamp.tv_usec = buf->index + 1;
|
||||
-
|
||||
if (V4L2_TYPE_IS_OUTPUT(type)) {
|
||||
void *addr = mmap(NULL, buf->size, PROT_READ | PROT_WRITE, MAP_SHARED, ctx->video_fd, V4L2_TYPE_IS_MULTIPLANAR(type) ? buf->buffer.m.planes[0].m.mem_offset : buf->buffer.m.offset);
|
||||
if (addr == MAP_FAILED) {
|
||||
diff --git a/libavcodec/v4l2_request.h b/libavcodec/v4l2_request.h
|
||||
index d4146bd4ee..72698f6f3c 100644
|
||||
--- a/libavcodec/v4l2_request.h
|
||||
+++ b/libavcodec/v4l2_request.h
|
||||
@@ -28,6 +28,7 @@ typedef struct V4L2RequestContext {
|
||||
int media_fd;
|
||||
enum v4l2_buf_type output_type;
|
||||
struct v4l2_format format;
|
||||
+ int timestamp;
|
||||
} V4L2RequestContext;
|
||||
|
||||
typedef struct V4L2RequestBuffer {
|
@ -1,121 +0,0 @@
|
||||
From 2756ad266f18d546551a3eab0650c95ddb62e0ff Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Sat, 14 Mar 2020 22:21:42 +0000
|
||||
Subject: [PATCH] v4l2 request hevc: Set SPS control at initialization
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
---
|
||||
libavcodec/v4l2_request_hevc.c | 61 ++++++++++++++++++++++------------
|
||||
1 file changed, 40 insertions(+), 21 deletions(-)
|
||||
|
||||
diff --git a/libavcodec/v4l2_request_hevc.c b/libavcodec/v4l2_request_hevc.c
|
||||
index 94977c5d0e..0ab1c201b0 100644
|
||||
--- a/libavcodec/v4l2_request_hevc.c
|
||||
+++ b/libavcodec/v4l2_request_hevc.c
|
||||
@@ -231,21 +231,12 @@ static void v4l2_request_hevc_fill_slice_params(const HEVCContext *h,
|
||||
slice_params->entry_point_offset_minus1[i] = sh->entry_point_offset[i] - 1;
|
||||
}
|
||||
|
||||
-static int v4l2_request_hevc_start_frame(AVCodecContext *avctx,
|
||||
- av_unused const uint8_t *buffer,
|
||||
- av_unused uint32_t size)
|
||||
+static void fill_sps(struct v4l2_ctrl_hevc_sps *ctrl, const HEVCContext *h)
|
||||
{
|
||||
- const HEVCContext *h = avctx->priv_data;
|
||||
const HEVCSPS *sps = h->ps.sps;
|
||||
- const HEVCPPS *pps = h->ps.pps;
|
||||
- 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;
|
||||
|
||||
/* ISO/IEC 23008-2, ITU-T Rec. H.265: Sequence parameter set */
|
||||
- controls->sps = (struct v4l2_ctrl_hevc_sps) {
|
||||
+ *ctrl = (struct v4l2_ctrl_hevc_sps) {
|
||||
.chroma_format_idc = sps->chroma_format_idc,
|
||||
.pic_width_in_luma_samples = sps->width,
|
||||
.pic_height_in_luma_samples = sps->height,
|
||||
@@ -270,31 +261,47 @@ static int v4l2_request_hevc_start_frame(AVCodecContext *avctx,
|
||||
};
|
||||
|
||||
if (sps->separate_colour_plane_flag)
|
||||
- controls->sps.flags |= V4L2_HEVC_SPS_FLAG_SEPARATE_COLOUR_PLANE;
|
||||
+ ctrl->flags |= V4L2_HEVC_SPS_FLAG_SEPARATE_COLOUR_PLANE;
|
||||
|
||||
if (sps->scaling_list_enable_flag)
|
||||
- controls->sps.flags |= V4L2_HEVC_SPS_FLAG_SCALING_LIST_ENABLED;
|
||||
+ ctrl->flags |= V4L2_HEVC_SPS_FLAG_SCALING_LIST_ENABLED;
|
||||
|
||||
if (sps->amp_enabled_flag)
|
||||
- controls->sps.flags |= V4L2_HEVC_SPS_FLAG_AMP_ENABLED;
|
||||
+ ctrl->flags |= V4L2_HEVC_SPS_FLAG_AMP_ENABLED;
|
||||
|
||||
if (sps->sao_enabled)
|
||||
- controls->sps.flags |= V4L2_HEVC_SPS_FLAG_SAMPLE_ADAPTIVE_OFFSET;
|
||||
+ ctrl->flags |= V4L2_HEVC_SPS_FLAG_SAMPLE_ADAPTIVE_OFFSET;
|
||||
|
||||
if (sps->pcm_enabled_flag)
|
||||
- controls->sps.flags |= V4L2_HEVC_SPS_FLAG_PCM_ENABLED;
|
||||
+ ctrl->flags |= V4L2_HEVC_SPS_FLAG_PCM_ENABLED;
|
||||
|
||||
if (sps->pcm.loop_filter_disable_flag)
|
||||
- controls->sps.flags |= V4L2_HEVC_SPS_FLAG_PCM_LOOP_FILTER_DISABLED;
|
||||
+ ctrl->flags |= V4L2_HEVC_SPS_FLAG_PCM_LOOP_FILTER_DISABLED;
|
||||
|
||||
if (sps->long_term_ref_pics_present_flag)
|
||||
- controls->sps.flags |= V4L2_HEVC_SPS_FLAG_LONG_TERM_REF_PICS_PRESENT;
|
||||
+ ctrl->flags |= V4L2_HEVC_SPS_FLAG_LONG_TERM_REF_PICS_PRESENT;
|
||||
|
||||
if (sps->sps_temporal_mvp_enabled_flag)
|
||||
- controls->sps.flags |= V4L2_HEVC_SPS_FLAG_SPS_TEMPORAL_MVP_ENABLED;
|
||||
+ ctrl->flags |= V4L2_HEVC_SPS_FLAG_SPS_TEMPORAL_MVP_ENABLED;
|
||||
|
||||
if (sps->sps_strong_intra_smoothing_enable_flag)
|
||||
- controls->sps.flags |= V4L2_HEVC_SPS_FLAG_STRONG_INTRA_SMOOTHING_ENABLED;
|
||||
+ ctrl->flags |= V4L2_HEVC_SPS_FLAG_STRONG_INTRA_SMOOTHING_ENABLED;
|
||||
+}
|
||||
+
|
||||
+static int v4l2_request_hevc_start_frame(AVCodecContext *avctx,
|
||||
+ av_unused const uint8_t *buffer,
|
||||
+ av_unused uint32_t size)
|
||||
+{
|
||||
+ const HEVCContext *h = avctx->priv_data;
|
||||
+ const HEVCSPS *sps = h->ps.sps;
|
||||
+ const HEVCPPS *pps = h->ps.pps;
|
||||
+ 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);
|
||||
|
||||
if (sl) {
|
||||
for (int i = 0; i < 6; i++) {
|
||||
@@ -502,9 +509,21 @@ static int v4l2_request_hevc_set_controls(AVCodecContext *avctx)
|
||||
|
||||
static int v4l2_request_hevc_init(AVCodecContext *avctx)
|
||||
{
|
||||
+ const HEVCContext *h = avctx->priv_data;
|
||||
+ struct v4l2_ctrl_hevc_sps sps;
|
||||
int ret;
|
||||
|
||||
- ret = ff_v4l2_request_init(avctx, V4L2_PIX_FMT_HEVC_SLICE, 3 * 1024 * 1024, NULL, 0);
|
||||
+ struct v4l2_ext_control control[] = {
|
||||
+ {
|
||||
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_SPS,
|
||||
+ .ptr = &sps,
|
||||
+ .size = sizeof(sps),
|
||||
+ }
|
||||
+ };
|
||||
+
|
||||
+ fill_sps(&sps, h);
|
||||
+
|
||||
+ ret = ff_v4l2_request_init(avctx, V4L2_PIX_FMT_HEVC_SLICE, 3 * 1024 * 1024, control, FF_ARRAY_ELEMS(control));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
--
|
||||
2.25.1
|
||||
|
@ -1,78 +0,0 @@
|
||||
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
|
||||
index fd87481a1c..d234271c5b 100644
|
||||
--- a/libavcodec/avcodec.h
|
||||
+++ b/libavcodec/avcodec.h
|
||||
@@ -2612,7 +2612,6 @@ typedef struct AVCodecContext {
|
||||
#define FF_BUG_MS 8192 ///< Work around various bugs in Microsoft's broken decoders.
|
||||
#define FF_BUG_TRUNCATED 16384
|
||||
#define FF_BUG_IEDGE 32768
|
||||
-#define FF_BUG_GMC_UNSUPPORTED (1<<30)
|
||||
|
||||
/**
|
||||
* strictly follow the standard (MPEG-4, ...).
|
||||
diff --git a/libavcodec/libdav1d.c b/libavcodec/libdav1d.c
|
||||
index 1bbb83eda3..12c63245f8 100644
|
||||
--- a/libavcodec/libdav1d.c
|
||||
+++ b/libavcodec/libdav1d.c
|
||||
@@ -53,16 +53,6 @@ static const enum AVPixelFormat pix_fmt_rgb[3] = {
|
||||
AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRP12,
|
||||
};
|
||||
|
||||
-static enum AVPixelFormat libdav1d_get_format(AVCodecContext *avctx, const Dav1dPicture *p)
|
||||
-{
|
||||
- enum AVPixelFormat pix_fmts[2], *fmt = pix_fmts;
|
||||
-
|
||||
- *fmt++ = pix_fmt[p->p.layout][p->seq_hdr->hbd];
|
||||
- *fmt = AV_PIX_FMT_NONE;
|
||||
-
|
||||
- return ff_get_format(avctx, pix_fmts);
|
||||
-}
|
||||
-
|
||||
static void libdav1d_log_callback(void *opaque, const char *fmt, va_list vl)
|
||||
{
|
||||
AVCodecContext *c = opaque;
|
||||
@@ -239,7 +229,6 @@ static int libdav1d_receive_frame(AVCodecContext *c, AVFrame *frame)
|
||||
c->profile = p->seq_hdr->profile;
|
||||
c->level = ((p->seq_hdr->operating_points[0].major_level - 2) << 2)
|
||||
| p->seq_hdr->operating_points[0].minor_level;
|
||||
- frame->format = c->pix_fmt = libdav1d_get_format(c, p);
|
||||
frame->width = p->p.w;
|
||||
frame->height = p->p.h;
|
||||
if (c->width != p->p.w || c->height != p->p.h) {
|
||||
diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c
|
||||
index fa208660c8..055afabc7e 100644
|
||||
--- a/libavcodec/mpeg4videodec.c
|
||||
+++ b/libavcodec/mpeg4videodec.c
|
||||
@@ -2662,9 +2662,6 @@ int ff_mpeg4_workaround_bugs(AVCodecContext *avctx)
|
||||
|
||||
if (ctx->divx_version >= 0)
|
||||
s->workaround_bugs |= FF_BUG_HPEL_CHROMA;
|
||||
-
|
||||
- if (ctx->num_sprite_warping_points > 1)
|
||||
- s->workaround_bugs |= FF_BUG_GMC_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if (s->workaround_bugs & FF_BUG_STD_QPEL) {
|
||||
@@ -2689,7 +2686,6 @@ int ff_mpeg4_workaround_bugs(AVCodecContext *avctx)
|
||||
s->workaround_bugs, ctx->lavc_build, ctx->xvid_build,
|
||||
ctx->divx_version, ctx->divx_build, s->divx_packed ? "p" : "");
|
||||
|
||||
- avctx->workaround_bugs = s->workaround_bugs;
|
||||
if (CONFIG_MPEG4_DECODER && ctx->xvid_build >= 0 &&
|
||||
s->codec_id == AV_CODEC_ID_MPEG4 &&
|
||||
avctx->idct_algo == FF_IDCT_AUTO) {
|
||||
diff --git a/libswscale/yuv2rgb.c b/libswscale/yuv2rgb.c
|
||||
index 6fb32fac77..d0df061e4d 100644
|
||||
--- a/libswscale/yuv2rgb.c
|
||||
+++ b/libswscale/yuv2rgb.c
|
||||
@@ -687,6 +687,10 @@ SwsFunc ff_yuv2rgb_get_func_ptr(SwsContext *c)
|
||||
if (t)
|
||||
return t;
|
||||
|
||||
+ av_log(c, AV_LOG_WARNING,
|
||||
+ "No accelerated colorspace conversion found from %s to %s.\n",
|
||||
+ av_get_pix_fmt_name(c->srcFormat), av_get_pix_fmt_name(c->dstFormat));
|
||||
+
|
||||
switch (c->dstFormat) {
|
||||
case AV_PIX_FMT_BGR48BE:
|
||||
case AV_PIX_FMT_BGR48LE:
|
File diff suppressed because it is too large
Load Diff
@ -1,73 +0,0 @@
|
||||
From 7134be3260ca6b885aa20447a06d35cab380a09e Mon Sep 17 00:00:00 2001
|
||||
From: Lukas Rusak <lorusak@gmail.com>
|
||||
Date: Tue, 24 Apr 2018 22:48:23 -0700
|
||||
Subject: [PATCH 01/14] libavcodec: v4l2m2m: fix indentation and add
|
||||
M2MDEC_CLASS
|
||||
|
||||
This just makes the M2MDEC_CLASS similar to how it is done in rkmpp. It looks
|
||||
clean and has proper indentation
|
||||
---
|
||||
libavcodec/v4l2_m2m_dec.c | 46 ++++++++++++++++++++-------------------
|
||||
1 file changed, 24 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/libavcodec/v4l2_m2m_dec.c b/libavcodec/v4l2_m2m_dec.c
|
||||
index d0601f0e2f..e1b6925771 100644
|
||||
--- a/libavcodec/v4l2_m2m_dec.c
|
||||
+++ b/libavcodec/v4l2_m2m_dec.c
|
||||
@@ -209,29 +209,31 @@ static const AVOption options[] = {
|
||||
{ NULL},
|
||||
};
|
||||
|
||||
+#define M2MDEC_CLASS(NAME) \
|
||||
+ static const AVClass v4l2_m2m_ ## NAME ## _dec_class = { \
|
||||
+ .class_name = #NAME "_v4l2_m2m_decoder", \
|
||||
+ .item_name = av_default_item_name, \
|
||||
+ .option = options, \
|
||||
+ .version = LIBAVUTIL_VERSION_INT, \
|
||||
+ };
|
||||
+
|
||||
#define M2MDEC(NAME, LONGNAME, CODEC, bsf_name) \
|
||||
-static const AVClass v4l2_m2m_ ## NAME ## _dec_class = {\
|
||||
- .class_name = #NAME "_v4l2_m2m_decoder",\
|
||||
- .item_name = av_default_item_name,\
|
||||
- .option = options,\
|
||||
- .version = LIBAVUTIL_VERSION_INT,\
|
||||
-};\
|
||||
-\
|
||||
-AVCodec ff_ ## NAME ## _v4l2m2m_decoder = { \
|
||||
- .name = #NAME "_v4l2m2m" ,\
|
||||
- .long_name = NULL_IF_CONFIG_SMALL("V4L2 mem2mem " LONGNAME " decoder wrapper"),\
|
||||
- .type = AVMEDIA_TYPE_VIDEO,\
|
||||
- .id = CODEC ,\
|
||||
- .priv_data_size = sizeof(V4L2m2mPriv),\
|
||||
- .priv_class = &v4l2_m2m_ ## NAME ## _dec_class,\
|
||||
- .init = v4l2_decode_init,\
|
||||
- .receive_frame = v4l2_receive_frame,\
|
||||
- .close = ff_v4l2_m2m_codec_end,\
|
||||
- .bsfs = bsf_name, \
|
||||
- .capabilities = AV_CODEC_CAP_HARDWARE | AV_CODEC_CAP_DELAY | \
|
||||
- AV_CODEC_CAP_AVOID_PROBING, \
|
||||
- .wrapper_name = "v4l2m2m", \
|
||||
-};
|
||||
+ M2MDEC_CLASS(NAME) \
|
||||
+ AVCodec ff_ ## NAME ## _v4l2m2m_decoder = { \
|
||||
+ .name = #NAME "_v4l2m2m" , \
|
||||
+ .long_name = NULL_IF_CONFIG_SMALL("V4L2 mem2mem " LONGNAME " decoder wrapper"), \
|
||||
+ .type = AVMEDIA_TYPE_VIDEO, \
|
||||
+ .id = CODEC , \
|
||||
+ .priv_data_size = sizeof(V4L2m2mPriv), \
|
||||
+ .priv_class = &v4l2_m2m_ ## NAME ## _dec_class, \
|
||||
+ .init = v4l2_decode_init, \
|
||||
+ .receive_frame = v4l2_receive_frame, \
|
||||
+ .close = ff_v4l2_m2m_codec_end, \
|
||||
+ .bsfs = bsf_name, \
|
||||
+ .capabilities = AV_CODEC_CAP_HARDWARE | AV_CODEC_CAP_DELAY, \
|
||||
+ AV_CODEC_CAP_AVOID_PROBING, \
|
||||
+ .wrapper_name = "v4l2m2m", \
|
||||
+ };
|
||||
|
||||
M2MDEC(h264, "H.264", AV_CODEC_ID_H264, "h264_mp4toannexb");
|
||||
M2MDEC(hevc, "HEVC", AV_CODEC_ID_HEVC, "hevc_mp4toannexb");
|
||||
--
|
||||
2.24.1
|
||||
|
@ -1,511 +0,0 @@
|
||||
From bf9fb2d576488ba08832e7cb7b10fe05a08665a5 Mon Sep 17 00:00:00 2001
|
||||
From: Lukas Rusak <lorusak@gmail.com>
|
||||
Date: Tue, 24 Apr 2018 23:00:23 -0700
|
||||
Subject: [PATCH 02/14] libavcodec: v4l2m2m: output AVDRMFrameDescriptor
|
||||
|
||||
This allows for a zero-copy output by exporting the v4l2 buffer then wrapping that buffer
|
||||
in the AVDRMFrameDescriptor like it is done in rkmpp.
|
||||
|
||||
This has been in use for quite some time with great success on many platforms including:
|
||||
- Amlogic S905
|
||||
- Raspberry Pi
|
||||
- i.MX6
|
||||
- Dragonboard 410c
|
||||
|
||||
This was developed in conjunction with Kodi to allow handling the zero-copy buffer rendering.
|
||||
A simply utility for testing is also available here: https://github.com/BayLibre/ffmpeg-drm
|
||||
|
||||
todo:
|
||||
- allow selecting pixel format output from decoder
|
||||
- allow configuring amount of output and capture buffers
|
||||
|
||||
V2:
|
||||
- allow selecting AV_PIX_FMT_DRM_PRIME
|
||||
|
||||
V3:
|
||||
- use get_format to select AV_PIX_FMT_DRM_PRIME
|
||||
- use hw_configs
|
||||
- add handling of AV_PIX_FMT_YUV420P format (for raspberry pi)
|
||||
- add handling of AV_PIX_FMT_YUYV422 format (for i.MX6 coda decoder)
|
||||
---
|
||||
libavcodec/v4l2_buffers.c | 216 ++++++++++++++++++++++++++++++++------
|
||||
libavcodec/v4l2_buffers.h | 4 +
|
||||
libavcodec/v4l2_context.c | 40 ++++++-
|
||||
libavcodec/v4l2_m2m.c | 4 +-
|
||||
libavcodec/v4l2_m2m.h | 3 +
|
||||
libavcodec/v4l2_m2m_dec.c | 23 ++++
|
||||
6 files changed, 253 insertions(+), 37 deletions(-)
|
||||
|
||||
diff --git a/libavcodec/v4l2_buffers.c b/libavcodec/v4l2_buffers.c
|
||||
index aef911f3bb..e5c46ac81e 100644
|
||||
--- a/libavcodec/v4l2_buffers.c
|
||||
+++ b/libavcodec/v4l2_buffers.c
|
||||
@@ -21,6 +21,7 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
+#include <drm/drm_fourcc.h>
|
||||
#include <linux/videodev2.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/mman.h>
|
||||
@@ -29,6 +30,7 @@
|
||||
#include <poll.h>
|
||||
#include "libavcodec/avcodec.h"
|
||||
#include "libavcodec/internal.h"
|
||||
+#include "libavutil/hwcontext.h"
|
||||
#include "v4l2_context.h"
|
||||
#include "v4l2_buffers.h"
|
||||
#include "v4l2_m2m.h"
|
||||
@@ -203,7 +205,79 @@ static enum AVColorTransferCharacteristic v4l2_get_color_trc(V4L2Buffer *buf)
|
||||
return AVCOL_TRC_UNSPECIFIED;
|
||||
}
|
||||
|
||||
-static void v4l2_free_buffer(void *opaque, uint8_t *unused)
|
||||
+static uint8_t * v4l2_get_drm_frame(V4L2Buffer *avbuf)
|
||||
+{
|
||||
+ AVDRMFrameDescriptor *drm_desc = &avbuf->drm_frame;
|
||||
+ AVDRMLayerDescriptor *layer;
|
||||
+
|
||||
+ /* fill the DRM frame descriptor */
|
||||
+ drm_desc->nb_objects = avbuf->num_planes;
|
||||
+ drm_desc->nb_layers = 1;
|
||||
+
|
||||
+ layer = &drm_desc->layers[0];
|
||||
+ layer->nb_planes = avbuf->num_planes;
|
||||
+
|
||||
+ for (int i = 0; i < avbuf->num_planes; i++) {
|
||||
+ layer->planes[i].object_index = i;
|
||||
+ layer->planes[i].offset = 0;
|
||||
+ layer->planes[i].pitch = avbuf->plane_info[i].bytesperline;
|
||||
+ }
|
||||
+
|
||||
+ switch (avbuf->context->av_pix_fmt) {
|
||||
+ case AV_PIX_FMT_YUYV422:
|
||||
+
|
||||
+ layer->format = DRM_FORMAT_YUYV;
|
||||
+ layer->nb_planes = 1;
|
||||
+
|
||||
+ break;
|
||||
+
|
||||
+ case AV_PIX_FMT_NV12:
|
||||
+ case AV_PIX_FMT_NV21:
|
||||
+
|
||||
+ layer->format = avbuf->context->av_pix_fmt == AV_PIX_FMT_NV12 ?
|
||||
+ DRM_FORMAT_NV12 : DRM_FORMAT_NV21;
|
||||
+
|
||||
+ if (avbuf->num_planes > 1)
|
||||
+ break;
|
||||
+
|
||||
+ layer->nb_planes = 2;
|
||||
+
|
||||
+ layer->planes[1].object_index = 0;
|
||||
+ layer->planes[1].offset = avbuf->plane_info[0].bytesperline *
|
||||
+ avbuf->context->format.fmt.pix.height;
|
||||
+ layer->planes[1].pitch = avbuf->plane_info[0].bytesperline;
|
||||
+ break;
|
||||
+
|
||||
+ case AV_PIX_FMT_YUV420P:
|
||||
+
|
||||
+ layer->format = DRM_FORMAT_YUV420;
|
||||
+
|
||||
+ if (avbuf->num_planes > 1)
|
||||
+ break;
|
||||
+
|
||||
+ layer->nb_planes = 3;
|
||||
+
|
||||
+ layer->planes[1].object_index = 0;
|
||||
+ layer->planes[1].offset = avbuf->plane_info[0].bytesperline *
|
||||
+ avbuf->context->format.fmt.pix.height;
|
||||
+ layer->planes[1].pitch = avbuf->plane_info[0].bytesperline >> 1;
|
||||
+
|
||||
+ layer->planes[2].object_index = 0;
|
||||
+ layer->planes[2].offset = layer->planes[1].offset +
|
||||
+ ((avbuf->plane_info[0].bytesperline *
|
||||
+ avbuf->context->format.fmt.pix.height) >> 2);
|
||||
+ layer->planes[2].pitch = avbuf->plane_info[0].bytesperline >> 1;
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ drm_desc->nb_layers = 0;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return (uint8_t *) drm_desc;
|
||||
+}
|
||||
+
|
||||
+static void v4l2_free_buffer(void *opaque, uint8_t *data)
|
||||
{
|
||||
V4L2Buffer* avbuf = opaque;
|
||||
V4L2m2mContext *s = buf_to_m2mctx(avbuf);
|
||||
@@ -227,27 +301,47 @@ static void v4l2_free_buffer(void *opaque, uint8_t *unused)
|
||||
}
|
||||
}
|
||||
|
||||
-static int v4l2_buf_to_bufref(V4L2Buffer *in, int plane, AVBufferRef **buf)
|
||||
+static int v4l2_buffer_export_drm(V4L2Buffer* avbuf)
|
||||
{
|
||||
- V4L2m2mContext *s = buf_to_m2mctx(in);
|
||||
+ struct v4l2_exportbuffer expbuf;
|
||||
+ int i, ret;
|
||||
|
||||
- if (plane >= in->num_planes)
|
||||
- return AVERROR(EINVAL);
|
||||
+ for (i = 0; i < avbuf->num_planes; i++) {
|
||||
+ memset(&expbuf, 0, sizeof(expbuf));
|
||||
|
||||
- /* even though most encoders return 0 in data_offset encoding vp8 does require this value */
|
||||
- *buf = av_buffer_create((char *)in->plane_info[plane].mm_addr + in->planes[plane].data_offset,
|
||||
- in->plane_info[plane].length, v4l2_free_buffer, in, 0);
|
||||
- if (!*buf)
|
||||
- return AVERROR(ENOMEM);
|
||||
+ expbuf.index = avbuf->buf.index;
|
||||
+ expbuf.type = avbuf->buf.type;
|
||||
+ expbuf.plane = i;
|
||||
+
|
||||
+ ret = ioctl(buf_to_m2mctx(avbuf)->fd, VIDIOC_EXPBUF, &expbuf);
|
||||
+ if (ret < 0)
|
||||
+ return AVERROR(errno);
|
||||
+
|
||||
+ if (V4L2_TYPE_IS_MULTIPLANAR(avbuf->buf.type)) {
|
||||
+ /* drm frame */
|
||||
+ avbuf->drm_frame.objects[i].size = avbuf->buf.m.planes[i].length;
|
||||
+ avbuf->drm_frame.objects[i].fd = expbuf.fd;
|
||||
+ } else {
|
||||
+ /* drm frame */
|
||||
+ avbuf->drm_frame.objects[0].size = avbuf->buf.length;
|
||||
+ avbuf->drm_frame.objects[0].fd = expbuf.fd;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int v4l2_buf_increase_ref(V4L2Buffer *in)
|
||||
+{
|
||||
+ V4L2m2mContext *s = buf_to_m2mctx(in);
|
||||
|
||||
if (in->context_ref)
|
||||
atomic_fetch_add(&in->context_refcount, 1);
|
||||
else {
|
||||
in->context_ref = av_buffer_ref(s->self_ref);
|
||||
- if (!in->context_ref) {
|
||||
- av_buffer_unref(buf);
|
||||
+ if (!in->context_ref)
|
||||
return AVERROR(ENOMEM);
|
||||
- }
|
||||
+
|
||||
in->context_refcount = 1;
|
||||
}
|
||||
|
||||
@@ -257,6 +351,46 @@ static int v4l2_buf_to_bufref(V4L2Buffer *in, int plane, AVBufferRef **buf)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int v4l2_buf_to_bufref_drm(V4L2Buffer *in, AVBufferRef **buf)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ *buf = av_buffer_create((uint8_t *) &in->drm_frame,
|
||||
+ sizeof(in->drm_frame),
|
||||
+ v4l2_free_buffer,
|
||||
+ in, AV_BUFFER_FLAG_READONLY);
|
||||
+ if (!*buf)
|
||||
+ return AVERROR(ENOMEM);
|
||||
+
|
||||
+ ret = v4l2_buf_increase_ref(in);
|
||||
+ if (ret)
|
||||
+ av_buffer_unref(buf);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int v4l2_buf_to_bufref(V4L2Buffer *in, int plane, AVBufferRef **buf)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ if (plane >= in->num_planes)
|
||||
+ return AVERROR(EINVAL);
|
||||
+
|
||||
+ /* most encoders return 0 in data_offset but vp8 does require this value */
|
||||
+ *buf = av_buffer_create((char *)in->plane_info[plane].mm_addr + in->planes[plane].data_offset,
|
||||
+ in->plane_info[plane].length,
|
||||
+ v4l2_free_buffer,
|
||||
+ in, 0);
|
||||
+ if (!*buf)
|
||||
+ return AVERROR(ENOMEM);
|
||||
+
|
||||
+ ret = v4l2_buf_increase_ref(in);
|
||||
+ if (ret)
|
||||
+ av_buffer_unref(buf);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static int v4l2_bufref_to_buf(V4L2Buffer *out, int plane, const uint8_t* data, int size, AVBufferRef* bref)
|
||||
{
|
||||
unsigned int bytesused, length;
|
||||
@@ -308,31 +442,43 @@ int ff_v4l2_buffer_buf_to_avframe(AVFrame *frame, V4L2Buffer *avbuf)
|
||||
|
||||
av_frame_unref(frame);
|
||||
|
||||
- /* 1. get references to the actual data */
|
||||
- for (i = 0; i < avbuf->num_planes; i++) {
|
||||
- ret = v4l2_buf_to_bufref(avbuf, i, &frame->buf[i]);
|
||||
+ if (buf_to_m2mctx(avbuf)->output_drm) {
|
||||
+ /* 1. get references to the actual data */
|
||||
+ ret = v4l2_buf_to_bufref_drm(avbuf, &frame->buf[0]);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- frame->linesize[i] = avbuf->plane_info[i].bytesperline;
|
||||
- frame->data[i] = frame->buf[i]->data;
|
||||
- }
|
||||
+ frame->data[0] = (uint8_t *) v4l2_get_drm_frame(avbuf);
|
||||
+ frame->format = AV_PIX_FMT_DRM_PRIME;
|
||||
+ } else {
|
||||
+ /* 1. get references to the actual data */
|
||||
+ for (i = 0; i < avbuf->num_planes; i++) {
|
||||
+ ret = v4l2_buf_to_bufref(avbuf, i, &frame->buf[i]);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ frame->linesize[i] = avbuf->plane_info[i].bytesperline;
|
||||
+ frame->data[i] = frame->buf[i]->data;
|
||||
+ }
|
||||
|
||||
- /* 1.1 fixup special cases */
|
||||
- switch (avbuf->context->av_pix_fmt) {
|
||||
- case AV_PIX_FMT_NV12:
|
||||
- if (avbuf->num_planes > 1)
|
||||
+ /* 1.1 fixup special cases */
|
||||
+ switch (avbuf->context->av_pix_fmt) {
|
||||
+ case AV_PIX_FMT_NV12:
|
||||
+ if (avbuf->num_planes > 1)
|
||||
+ break;
|
||||
+ frame->linesize[1] = avbuf->plane_info[0].bytesperline;
|
||||
+ frame->data[1] = frame->buf[0]->data +
|
||||
+ avbuf->plane_info[0].bytesperline *
|
||||
+ avbuf->context->format.fmt.pix.height;
|
||||
break;
|
||||
- frame->linesize[1] = avbuf->plane_info[0].bytesperline;
|
||||
- frame->data[1] = frame->buf[0]->data + avbuf->plane_info[0].bytesperline * avbuf->context->format.fmt.pix_mp.height;
|
||||
- break;
|
||||
- default:
|
||||
- break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+ frame->format = avbuf->context->av_pix_fmt;
|
||||
}
|
||||
|
||||
/* 2. get frame information */
|
||||
frame->key_frame = !!(avbuf->buf.flags & V4L2_BUF_FLAG_KEYFRAME);
|
||||
- frame->format = avbuf->context->av_pix_fmt;
|
||||
frame->color_primaries = v4l2_get_color_primaries(avbuf);
|
||||
frame->colorspace = v4l2_get_color_space(avbuf);
|
||||
frame->color_range = v4l2_get_color_range(avbuf);
|
||||
@@ -447,9 +593,6 @@ int ff_v4l2_buffer_initialize(V4L2Buffer* avbuf, int index)
|
||||
|
||||
avbuf->status = V4L2BUF_AVAILABLE;
|
||||
|
||||
- if (V4L2_TYPE_IS_OUTPUT(ctx->type))
|
||||
- return 0;
|
||||
-
|
||||
if (V4L2_TYPE_IS_MULTIPLANAR(ctx->type)) {
|
||||
avbuf->buf.m.planes = avbuf->planes;
|
||||
avbuf->buf.length = avbuf->num_planes;
|
||||
@@ -459,6 +602,15 @@ int ff_v4l2_buffer_initialize(V4L2Buffer* avbuf, int index)
|
||||
avbuf->buf.length = avbuf->planes[0].length;
|
||||
}
|
||||
|
||||
+ if (V4L2_TYPE_IS_OUTPUT(ctx->type))
|
||||
+ return 0;
|
||||
+
|
||||
+ if (buf_to_m2mctx(avbuf)->output_drm) {
|
||||
+ ret = v4l2_buffer_export_drm(avbuf);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
return ff_v4l2_buffer_enqueue(avbuf);
|
||||
}
|
||||
|
||||
diff --git a/libavcodec/v4l2_buffers.h b/libavcodec/v4l2_buffers.h
|
||||
index 7a57caf949..19324541d0 100644
|
||||
--- a/libavcodec/v4l2_buffers.h
|
||||
+++ b/libavcodec/v4l2_buffers.h
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <stdatomic.h>
|
||||
#include <linux/videodev2.h>
|
||||
|
||||
+#include "libavutil/hwcontext_drm.h"
|
||||
#include "avcodec.h"
|
||||
|
||||
enum V4L2Buffer_status {
|
||||
@@ -42,6 +43,9 @@ typedef struct V4L2Buffer {
|
||||
/* each buffer needs to have a reference to its context */
|
||||
struct V4L2Context *context;
|
||||
|
||||
+ /* DRM descriptor */
|
||||
+ AVDRMFrameDescriptor drm_frame;
|
||||
+
|
||||
/* This object is refcounted per-plane, so we need to keep track
|
||||
* of how many context-refs we are holding. */
|
||||
AVBufferRef *context_ref;
|
||||
diff --git a/libavcodec/v4l2_context.c b/libavcodec/v4l2_context.c
|
||||
index efcb0426e4..9457fadb1e 100644
|
||||
--- a/libavcodec/v4l2_context.c
|
||||
+++ b/libavcodec/v4l2_context.c
|
||||
@@ -393,22 +393,54 @@ static int v4l2_release_buffers(V4L2Context* ctx)
|
||||
struct v4l2_requestbuffers req = {
|
||||
.memory = V4L2_MEMORY_MMAP,
|
||||
.type = ctx->type,
|
||||
- .count = 0, /* 0 -> unmaps buffers from the driver */
|
||||
+ .count = 0, /* 0 -> unmap all buffers from the driver */
|
||||
};
|
||||
- int i, j;
|
||||
+ int ret, i, j;
|
||||
|
||||
for (i = 0; i < ctx->num_buffers; i++) {
|
||||
V4L2Buffer *buffer = &ctx->buffers[i];
|
||||
|
||||
for (j = 0; j < buffer->num_planes; j++) {
|
||||
struct V4L2Plane_info *p = &buffer->plane_info[j];
|
||||
+
|
||||
+ if (V4L2_TYPE_IS_OUTPUT(ctx->type)) {
|
||||
+ /* output buffers are not EXPORTED */
|
||||
+ goto unmap;
|
||||
+ }
|
||||
+
|
||||
+ if (ctx_to_m2mctx(ctx)->output_drm) {
|
||||
+ /* use the DRM frame to close */
|
||||
+ if (buffer->drm_frame.objects[j].fd >= 0) {
|
||||
+ if (close(buffer->drm_frame.objects[j].fd) < 0) {
|
||||
+ av_log(logger(ctx), AV_LOG_ERROR, "%s close drm fd "
|
||||
+ "[buffer=%2d, plane=%d, fd=%2d] - %s \n",
|
||||
+ ctx->name, i, j, buffer->drm_frame.objects[j].fd,
|
||||
+ av_err2str(AVERROR(errno)));
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+unmap:
|
||||
if (p->mm_addr && p->length)
|
||||
if (munmap(p->mm_addr, p->length) < 0)
|
||||
- av_log(logger(ctx), AV_LOG_ERROR, "%s unmap plane (%s))\n", ctx->name, av_err2str(AVERROR(errno)));
|
||||
+ av_log(logger(ctx), AV_LOG_ERROR, "%s unmap plane (%s))\n",
|
||||
+ ctx->name, av_err2str(AVERROR(errno)));
|
||||
}
|
||||
}
|
||||
|
||||
- return ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_REQBUFS, &req);
|
||||
+ ret = ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_REQBUFS, &req);
|
||||
+ if (ret < 0) {
|
||||
+ av_log(logger(ctx), AV_LOG_ERROR, "release all %s buffers (%s)\n",
|
||||
+ ctx->name, av_err2str(AVERROR(errno)));
|
||||
+
|
||||
+ if (ctx_to_m2mctx(ctx)->output_drm)
|
||||
+ av_log(logger(ctx), AV_LOG_ERROR,
|
||||
+ "Make sure the DRM client releases all FB/GEM objects before closing the codec (ie):\n"
|
||||
+ "for all buffers: \n"
|
||||
+ " 1. drmModeRmFB(..)\n"
|
||||
+ " 2. drmIoctl(.., DRM_IOCTL_GEM_CLOSE,... )\n");
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
static inline int v4l2_try_raw_format(V4L2Context* ctx, enum AVPixelFormat pixfmt)
|
||||
diff --git a/libavcodec/v4l2_m2m.c b/libavcodec/v4l2_m2m.c
|
||||
index 427e165f58..7896326e80 100644
|
||||
--- a/libavcodec/v4l2_m2m.c
|
||||
+++ b/libavcodec/v4l2_m2m.c
|
||||
@@ -159,7 +159,9 @@ static int v4l2_configure_contexts(V4L2m2mContext* s)
|
||||
goto error;
|
||||
}
|
||||
|
||||
- /* decoder's buffers need to be updated at a later stage */
|
||||
+ /* decoder's capture buffers are updated during v4l2_try_start once we find
|
||||
+ * the valid format.
|
||||
+ */
|
||||
if (!av_codec_is_decoder(s->avctx->codec)) {
|
||||
ret = ff_v4l2_context_init(&s->capture);
|
||||
if (ret) {
|
||||
diff --git a/libavcodec/v4l2_m2m.h b/libavcodec/v4l2_m2m.h
|
||||
index 0d4671beb1..043a81a86a 100644
|
||||
--- a/libavcodec/v4l2_m2m.h
|
||||
+++ b/libavcodec/v4l2_m2m.h
|
||||
@@ -59,6 +59,9 @@ typedef struct V4L2m2mContext {
|
||||
|
||||
/* Reference to self; only valid while codec is active. */
|
||||
AVBufferRef *self_ref;
|
||||
+
|
||||
+ /* generate DRM frames */
|
||||
+ int output_drm;
|
||||
} V4L2m2mContext;
|
||||
|
||||
typedef struct V4L2m2mPriv
|
||||
diff --git a/libavcodec/v4l2_m2m_dec.c b/libavcodec/v4l2_m2m_dec.c
|
||||
index e1b6925771..b28f4e236a 100644
|
||||
--- a/libavcodec/v4l2_m2m_dec.c
|
||||
+++ b/libavcodec/v4l2_m2m_dec.c
|
||||
@@ -23,12 +23,18 @@
|
||||
|
||||
#include <linux/videodev2.h>
|
||||
#include <sys/ioctl.h>
|
||||
+
|
||||
+#include "libavutil/hwcontext.h"
|
||||
+#include "libavutil/hwcontext_drm.h"
|
||||
#include "libavutil/pixfmt.h"
|
||||
#include "libavutil/pixdesc.h"
|
||||
#include "libavutil/opt.h"
|
||||
#include "libavcodec/avcodec.h"
|
||||
#include "libavcodec/decode.h"
|
||||
|
||||
+#include "libavcodec/hwaccel.h"
|
||||
+#include "libavcodec/internal.h"
|
||||
+
|
||||
#include "v4l2_context.h"
|
||||
#include "v4l2_m2m.h"
|
||||
#include "v4l2_fmt.h"
|
||||
@@ -186,6 +192,15 @@ static av_cold int v4l2_decode_init(AVCodecContext *avctx)
|
||||
capture->av_codec_id = AV_CODEC_ID_RAWVIDEO;
|
||||
capture->av_pix_fmt = avctx->pix_fmt;
|
||||
|
||||
+ /* the client requests the codec to generate DRM frames:
|
||||
+ * - data[0] will therefore point to the returned AVDRMFrameDescriptor
|
||||
+ * check the ff_v4l2_buffer_to_avframe conversion function.
|
||||
+ * - the DRM frame format is passed in the DRM frame descriptor layer.
|
||||
+ * check the v4l2_get_drm_frame function.
|
||||
+ */
|
||||
+ if (ff_get_format(avctx, avctx->codec->pix_fmts) == AV_PIX_FMT_DRM_PRIME)
|
||||
+ s->output_drm = 1;
|
||||
+
|
||||
ret = ff_v4l2_m2m_codec_init(avctx);
|
||||
if (ret) {
|
||||
V4L2m2mPriv *priv = avctx->priv_data;
|
||||
@@ -209,6 +224,11 @@ static const AVOption options[] = {
|
||||
{ NULL},
|
||||
};
|
||||
|
||||
+static const AVCodecHWConfigInternal *v4l2_m2m_hw_configs[] = {
|
||||
+ HW_CONFIG_INTERNAL(DRM_PRIME),
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
#define M2MDEC_CLASS(NAME) \
|
||||
static const AVClass v4l2_m2m_ ## NAME ## _dec_class = { \
|
||||
.class_name = #NAME "_v4l2_m2m_decoder", \
|
||||
@@ -229,7 +249,10 @@ static const AVOption options[] = {
|
||||
.init = v4l2_decode_init, \
|
||||
.receive_frame = v4l2_receive_frame, \
|
||||
.close = ff_v4l2_m2m_codec_end, \
|
||||
+ .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_DRM_PRIME, \
|
||||
+ AV_PIX_FMT_NONE}, \
|
||||
.bsfs = bsf_name, \
|
||||
+ .hw_configs = v4l2_m2m_hw_configs, \
|
||||
.capabilities = AV_CODEC_CAP_HARDWARE | AV_CODEC_CAP_DELAY, \
|
||||
AV_CODEC_CAP_AVOID_PROBING, \
|
||||
.wrapper_name = "v4l2m2m", \
|
||||
--
|
||||
2.24.1
|
||||
|
@ -1,106 +0,0 @@
|
||||
From ebcfd47d8411fcc91d8058643b151068b5a7fedc Mon Sep 17 00:00:00 2001
|
||||
From: Lukas Rusak <lorusak@gmail.com>
|
||||
Date: Tue, 8 May 2018 22:40:23 -0700
|
||||
Subject: [PATCH 03/14] libavcodec: v4l2m2m: adjust formatting
|
||||
|
||||
just some simple formatting fixes that unify the code quality
|
||||
---
|
||||
libavcodec/v4l2_buffers.c | 23 +++++++++++++++--------
|
||||
libavcodec/v4l2_buffers.h | 1 -
|
||||
2 files changed, 15 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/libavcodec/v4l2_buffers.c b/libavcodec/v4l2_buffers.c
|
||||
index e5c46ac81e..897c3c4636 100644
|
||||
--- a/libavcodec/v4l2_buffers.c
|
||||
+++ b/libavcodec/v4l2_buffers.c
|
||||
@@ -401,7 +401,8 @@ static int v4l2_bufref_to_buf(V4L2Buffer *out, int plane, const uint8_t* data, i
|
||||
bytesused = FFMIN(size, out->plane_info[plane].length);
|
||||
length = out->plane_info[plane].length;
|
||||
|
||||
- memcpy(out->plane_info[plane].mm_addr, data, FFMIN(size, out->plane_info[plane].length));
|
||||
+ memcpy(out->plane_info[plane].mm_addr, data,
|
||||
+ FFMIN(size, out->plane_info[plane].length));
|
||||
|
||||
if (V4L2_TYPE_IS_MULTIPLANAR(out->buf.type)) {
|
||||
out->planes[plane].bytesused = bytesused;
|
||||
@@ -425,7 +426,10 @@ int ff_v4l2_buffer_avframe_to_buf(const AVFrame *frame, V4L2Buffer* out)
|
||||
int i, ret;
|
||||
|
||||
for(i = 0; i < out->num_planes; i++) {
|
||||
- ret = v4l2_bufref_to_buf(out, i, frame->buf[i]->data, frame->buf[i]->size, frame->buf[i]);
|
||||
+ ret = v4l2_bufref_to_buf(out, i,
|
||||
+ frame->buf[i]->data,
|
||||
+ frame->buf[i]->size,
|
||||
+ frame->buf[i]);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
@@ -480,8 +484,8 @@ int ff_v4l2_buffer_buf_to_avframe(AVFrame *frame, V4L2Buffer *avbuf)
|
||||
/* 2. get frame information */
|
||||
frame->key_frame = !!(avbuf->buf.flags & V4L2_BUF_FLAG_KEYFRAME);
|
||||
frame->color_primaries = v4l2_get_color_primaries(avbuf);
|
||||
- frame->colorspace = v4l2_get_color_space(avbuf);
|
||||
frame->color_range = v4l2_get_color_range(avbuf);
|
||||
+ frame->colorspace = v4l2_get_color_space(avbuf);
|
||||
frame->color_trc = v4l2_get_color_trc(avbuf);
|
||||
frame->pts = v4l2_get_pts(avbuf);
|
||||
|
||||
@@ -507,7 +511,8 @@ int ff_v4l2_buffer_buf_to_avpkt(AVPacket *pkt, V4L2Buffer *avbuf)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- pkt->size = V4L2_TYPE_IS_MULTIPLANAR(avbuf->buf.type) ? avbuf->buf.m.planes[0].bytesused : avbuf->buf.bytesused;
|
||||
+ pkt->size = V4L2_TYPE_IS_MULTIPLANAR(avbuf->buf.type) ?
|
||||
+ avbuf->buf.m.planes[0].bytesused : avbuf->buf.bytesused;
|
||||
pkt->data = pkt->buf->data;
|
||||
|
||||
if (avbuf->buf.flags & V4L2_BUF_FLAG_KEYFRAME)
|
||||
@@ -563,6 +568,7 @@ int ff_v4l2_buffer_initialize(V4L2Buffer* avbuf, int index)
|
||||
/* in MP, the V4L2 API states that buf.length means num_planes */
|
||||
if (avbuf->num_planes >= avbuf->buf.length)
|
||||
break;
|
||||
+
|
||||
if (avbuf->buf.m.planes[avbuf->num_planes].length)
|
||||
avbuf->num_planes++;
|
||||
}
|
||||
@@ -579,12 +585,14 @@ int ff_v4l2_buffer_initialize(V4L2Buffer* avbuf, int index)
|
||||
avbuf->plane_info[i].length = avbuf->buf.m.planes[i].length;
|
||||
avbuf->plane_info[i].mm_addr = mmap(NULL, avbuf->buf.m.planes[i].length,
|
||||
PROT_READ | PROT_WRITE, MAP_SHARED,
|
||||
- buf_to_m2mctx(avbuf)->fd, avbuf->buf.m.planes[i].m.mem_offset);
|
||||
+ buf_to_m2mctx(avbuf)->fd,
|
||||
+ avbuf->buf.m.planes[i].m.mem_offset);
|
||||
} else {
|
||||
avbuf->plane_info[i].length = avbuf->buf.length;
|
||||
avbuf->plane_info[i].mm_addr = mmap(NULL, avbuf->buf.length,
|
||||
PROT_READ | PROT_WRITE, MAP_SHARED,
|
||||
- buf_to_m2mctx(avbuf)->fd, avbuf->buf.m.offset);
|
||||
+ buf_to_m2mctx(avbuf)->fd,
|
||||
+ avbuf->buf.m.offset);
|
||||
}
|
||||
|
||||
if (avbuf->plane_info[i].mm_addr == MAP_FAILED)
|
||||
@@ -594,9 +602,8 @@ int ff_v4l2_buffer_initialize(V4L2Buffer* avbuf, int index)
|
||||
avbuf->status = V4L2BUF_AVAILABLE;
|
||||
|
||||
if (V4L2_TYPE_IS_MULTIPLANAR(ctx->type)) {
|
||||
- avbuf->buf.m.planes = avbuf->planes;
|
||||
avbuf->buf.length = avbuf->num_planes;
|
||||
-
|
||||
+ avbuf->buf.m.planes = avbuf->planes;
|
||||
} else {
|
||||
avbuf->buf.bytesused = avbuf->planes[0].bytesused;
|
||||
avbuf->buf.length = avbuf->planes[0].length;
|
||||
diff --git a/libavcodec/v4l2_buffers.h b/libavcodec/v4l2_buffers.h
|
||||
index 19324541d0..b6072baec8 100644
|
||||
--- a/libavcodec/v4l2_buffers.h
|
||||
+++ b/libavcodec/v4l2_buffers.h
|
||||
@@ -131,5 +131,4 @@ int ff_v4l2_buffer_initialize(V4L2Buffer* avbuf, int index);
|
||||
*/
|
||||
int ff_v4l2_buffer_enqueue(V4L2Buffer* avbuf);
|
||||
|
||||
-
|
||||
#endif // AVCODEC_V4L2_BUFFERS_H
|
||||
--
|
||||
2.24.1
|
||||
|
@ -1,84 +0,0 @@
|
||||
From db39d4579d36266a3f3b87312303d5097543633d Mon Sep 17 00:00:00 2001
|
||||
From: Jorge Ramirez-Ortiz <jramirez@baylibre.com>
|
||||
Date: Sun, 6 May 2018 19:56:30 +0200
|
||||
Subject: [PATCH 04/14] libavcodec: v4l2m2m: fix error handling during buffer
|
||||
init
|
||||
|
||||
Signed-off-by: Jorge Ramirez-Ortiz <jramirez@baylibre.com>
|
||||
---
|
||||
libavcodec/v4l2_context.c | 19 ++++++++++++++++---
|
||||
libavcodec/v4l2_m2m_dec.c | 9 +++++++--
|
||||
2 files changed, 23 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/libavcodec/v4l2_context.c b/libavcodec/v4l2_context.c
|
||||
index 9457fadb1e..12d40d597e 100644
|
||||
--- a/libavcodec/v4l2_context.c
|
||||
+++ b/libavcodec/v4l2_context.c
|
||||
@@ -263,6 +263,12 @@ static V4L2Buffer* v4l2_dequeue_v4l2buf(V4L2Context *ctx, int timeout)
|
||||
/* if we are draining and there are no more capture buffers queued in the driver we are done */
|
||||
if (!V4L2_TYPE_IS_OUTPUT(ctx->type) && ctx_to_m2mctx(ctx)->draining) {
|
||||
for (i = 0; i < ctx->num_buffers; i++) {
|
||||
+ /* capture buffer initialization happens during decode hence
|
||||
+ * detection happens at runtime
|
||||
+ */
|
||||
+ if (!ctx->buffers)
|
||||
+ break;
|
||||
+
|
||||
if (ctx->buffers[i].status == V4L2BUF_IN_DRIVER)
|
||||
goto start;
|
||||
}
|
||||
@@ -724,9 +730,8 @@ int ff_v4l2_context_init(V4L2Context* ctx)
|
||||
ctx->buffers[i].context = ctx;
|
||||
ret = ff_v4l2_buffer_initialize(&ctx->buffers[i], i);
|
||||
if (ret < 0) {
|
||||
- av_log(logger(ctx), AV_LOG_ERROR, "%s buffer initialization (%s)\n", ctx->name, av_err2str(ret));
|
||||
- av_free(ctx->buffers);
|
||||
- return ret;
|
||||
+ av_log(logger(ctx), AV_LOG_ERROR, "%s buffer[%d] initialization (%s)\n", ctx->name, i, av_err2str(ret));
|
||||
+ goto error;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -739,4 +744,12 @@ int ff_v4l2_context_init(V4L2Context* ctx)
|
||||
V4L2_TYPE_IS_MULTIPLANAR(ctx->type) ? ctx->format.fmt.pix_mp.plane_fmt[0].bytesperline : ctx->format.fmt.pix.bytesperline);
|
||||
|
||||
return 0;
|
||||
+
|
||||
+error:
|
||||
+ v4l2_release_buffers(ctx);
|
||||
+
|
||||
+ av_free(ctx->buffers);
|
||||
+ ctx->buffers = NULL;
|
||||
+
|
||||
+ return ret;
|
||||
}
|
||||
diff --git a/libavcodec/v4l2_m2m_dec.c b/libavcodec/v4l2_m2m_dec.c
|
||||
index b28f4e236a..fb5406a74e 100644
|
||||
--- a/libavcodec/v4l2_m2m_dec.c
|
||||
+++ b/libavcodec/v4l2_m2m_dec.c
|
||||
@@ -92,8 +92,8 @@ static int v4l2_try_start(AVCodecContext *avctx)
|
||||
if (!capture->buffers) {
|
||||
ret = ff_v4l2_context_init(capture);
|
||||
if (ret) {
|
||||
- av_log(avctx, AV_LOG_DEBUG, "can't request output buffers\n");
|
||||
- return ret;
|
||||
+ av_log(avctx, AV_LOG_ERROR, "can't request capture buffers\n");
|
||||
+ return AVERROR(ENOMEM);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,6 +157,11 @@ static int v4l2_receive_frame(AVCodecContext *avctx, AVFrame *frame)
|
||||
ret = v4l2_try_start(avctx);
|
||||
if (ret) {
|
||||
av_packet_unref(&avpkt);
|
||||
+
|
||||
+ /* cant recover */
|
||||
+ if (ret == AVERROR(ENOMEM))
|
||||
+ return ret;
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
--
|
||||
2.24.1
|
||||
|
@ -1,38 +0,0 @@
|
||||
From 86a709f752d430166b9c1e26fa639886710b79ad Mon Sep 17 00:00:00 2001
|
||||
From: Lukas Rusak <lorusak@gmail.com>
|
||||
Date: Thu, 16 Aug 2018 21:09:40 -0700
|
||||
Subject: [PATCH 05/14] libavcodec: v4l2m2m: depends on libdrm
|
||||
|
||||
---
|
||||
configure | 1 +
|
||||
libavcodec/v4l2_buffers.c | 2 +-
|
||||
2 files changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/configure b/configure
|
||||
index 34c2adb4a4..b72f1d6270 100755
|
||||
--- a/configure
|
||||
+++ b/configure
|
||||
@@ -3343,6 +3343,7 @@ sndio_indev_deps="sndio"
|
||||
sndio_outdev_deps="sndio"
|
||||
v4l2_indev_deps_any="linux_videodev2_h sys_videoio_h"
|
||||
v4l2_indev_suggest="libv4l2"
|
||||
+v4l2_outdev_deps="libdrm"
|
||||
v4l2_outdev_deps_any="linux_videodev2_h sys_videoio_h"
|
||||
v4l2_outdev_suggest="libv4l2"
|
||||
vfwcap_indev_deps="vfw32 vfwcap_defines"
|
||||
diff --git a/libavcodec/v4l2_buffers.c b/libavcodec/v4l2_buffers.c
|
||||
index 897c3c4636..d6838866b7 100644
|
||||
--- a/libavcodec/v4l2_buffers.c
|
||||
+++ b/libavcodec/v4l2_buffers.c
|
||||
@@ -21,7 +21,7 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
-#include <drm/drm_fourcc.h>
|
||||
+#include <drm_fourcc.h>
|
||||
#include <linux/videodev2.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/mman.h>
|
||||
--
|
||||
2.24.1
|
||||
|
@ -1,30 +0,0 @@
|
||||
From e657b496a21056d51f17f187dfdf0c62d1da13f2 Mon Sep 17 00:00:00 2001
|
||||
From: Lukas Rusak <lorusak@gmail.com>
|
||||
Date: Thu, 16 Aug 2018 21:10:13 -0700
|
||||
Subject: [PATCH 06/14] libavcodec: v4l2m2m: set format_modifier to
|
||||
DRM_FORMAT_MOD_LINEAR
|
||||
|
||||
---
|
||||
libavcodec/v4l2_buffers.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/libavcodec/v4l2_buffers.c b/libavcodec/v4l2_buffers.c
|
||||
index d6838866b7..d879aab7b1 100644
|
||||
--- a/libavcodec/v4l2_buffers.c
|
||||
+++ b/libavcodec/v4l2_buffers.c
|
||||
@@ -321,10 +321,12 @@ static int v4l2_buffer_export_drm(V4L2Buffer* avbuf)
|
||||
/* drm frame */
|
||||
avbuf->drm_frame.objects[i].size = avbuf->buf.m.planes[i].length;
|
||||
avbuf->drm_frame.objects[i].fd = expbuf.fd;
|
||||
+ avbuf->drm_frame.objects[i].format_modifier = DRM_FORMAT_MOD_LINEAR;
|
||||
} else {
|
||||
/* drm frame */
|
||||
avbuf->drm_frame.objects[0].size = avbuf->buf.length;
|
||||
avbuf->drm_frame.objects[0].fd = expbuf.fd;
|
||||
+ avbuf->drm_frame.objects[0].format_modifier = DRM_FORMAT_MOD_LINEAR;
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
2.24.1
|
||||
|
@ -1,50 +0,0 @@
|
||||
From 013503bba6eefa10caffe2451fe375b31ed1584a Mon Sep 17 00:00:00 2001
|
||||
From: Lukas Rusak <lorusak@gmail.com>
|
||||
Date: Thu, 16 Aug 2018 21:10:53 -0700
|
||||
Subject: [PATCH 07/14] libavcodec: v4l2m2m: only mmap the buffer when it is
|
||||
output type and drm prime is used
|
||||
|
||||
---
|
||||
libavcodec/v4l2_buffers.c | 24 ++++++++++++++++--------
|
||||
1 file changed, 16 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/libavcodec/v4l2_buffers.c b/libavcodec/v4l2_buffers.c
|
||||
index d879aab7b1..ee19bb5b6f 100644
|
||||
--- a/libavcodec/v4l2_buffers.c
|
||||
+++ b/libavcodec/v4l2_buffers.c
|
||||
@@ -585,16 +585,24 @@ int ff_v4l2_buffer_initialize(V4L2Buffer* avbuf, int index)
|
||||
|
||||
if (V4L2_TYPE_IS_MULTIPLANAR(ctx->type)) {
|
||||
avbuf->plane_info[i].length = avbuf->buf.m.planes[i].length;
|
||||
- avbuf->plane_info[i].mm_addr = mmap(NULL, avbuf->buf.m.planes[i].length,
|
||||
- PROT_READ | PROT_WRITE, MAP_SHARED,
|
||||
- buf_to_m2mctx(avbuf)->fd,
|
||||
- avbuf->buf.m.planes[i].m.mem_offset);
|
||||
+
|
||||
+ if ((V4L2_TYPE_IS_OUTPUT(ctx->type) && buf_to_m2mctx(avbuf)->output_drm) ||
|
||||
+ !buf_to_m2mctx(avbuf)->output_drm) {
|
||||
+ avbuf->plane_info[i].mm_addr = mmap(NULL, avbuf->buf.m.planes[i].length,
|
||||
+ PROT_READ | PROT_WRITE, MAP_SHARED,
|
||||
+ buf_to_m2mctx(avbuf)->fd,
|
||||
+ avbuf->buf.m.planes[i].m.mem_offset);
|
||||
+ }
|
||||
} else {
|
||||
avbuf->plane_info[i].length = avbuf->buf.length;
|
||||
- avbuf->plane_info[i].mm_addr = mmap(NULL, avbuf->buf.length,
|
||||
- PROT_READ | PROT_WRITE, MAP_SHARED,
|
||||
- buf_to_m2mctx(avbuf)->fd,
|
||||
- avbuf->buf.m.offset);
|
||||
+
|
||||
+ if ((V4L2_TYPE_IS_OUTPUT(ctx->type) && buf_to_m2mctx(avbuf)->output_drm) ||
|
||||
+ !buf_to_m2mctx(avbuf)->output_drm) {
|
||||
+ avbuf->plane_info[i].mm_addr = mmap(NULL, avbuf->buf.length,
|
||||
+ PROT_READ | PROT_WRITE, MAP_SHARED,
|
||||
+ buf_to_m2mctx(avbuf)->fd,
|
||||
+ avbuf->buf.m.offset);
|
||||
+ }
|
||||
}
|
||||
|
||||
if (avbuf->plane_info[i].mm_addr == MAP_FAILED)
|
||||
--
|
||||
2.24.1
|
||||
|
@ -1,42 +0,0 @@
|
||||
From f3df44dbdf5e7ca66064c0ac9ae0f84bbcc245e9 Mon Sep 17 00:00:00 2001
|
||||
From: Lukas Rusak <lorusak@gmail.com>
|
||||
Date: Thu, 16 Aug 2018 21:11:38 -0700
|
||||
Subject: [PATCH 08/14] libavcodec: v4l2m2m: allow using software pixel formats
|
||||
|
||||
---
|
||||
libavcodec/v4l2_m2m_dec.c | 11 ++++++++++-
|
||||
1 file changed, 10 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libavcodec/v4l2_m2m_dec.c b/libavcodec/v4l2_m2m_dec.c
|
||||
index fb5406a74e..8834b3d6fc 100644
|
||||
--- a/libavcodec/v4l2_m2m_dec.c
|
||||
+++ b/libavcodec/v4l2_m2m_dec.c
|
||||
@@ -203,8 +203,16 @@ static av_cold int v4l2_decode_init(AVCodecContext *avctx)
|
||||
* - the DRM frame format is passed in the DRM frame descriptor layer.
|
||||
* check the v4l2_get_drm_frame function.
|
||||
*/
|
||||
- if (ff_get_format(avctx, avctx->codec->pix_fmts) == AV_PIX_FMT_DRM_PRIME)
|
||||
+ switch (ff_get_format(avctx, avctx->codec->pix_fmts)) {
|
||||
+ case AV_PIX_FMT_DRM_PRIME:
|
||||
s->output_drm = 1;
|
||||
+ break;
|
||||
+ case AV_PIX_FMT_NONE:
|
||||
+ return 0;
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
ret = ff_v4l2_m2m_codec_init(avctx);
|
||||
if (ret) {
|
||||
@@ -255,6 +263,7 @@ static const AVCodecHWConfigInternal *v4l2_m2m_hw_configs[] = {
|
||||
.receive_frame = v4l2_receive_frame, \
|
||||
.close = ff_v4l2_m2m_codec_end, \
|
||||
.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_DRM_PRIME, \
|
||||
+ AV_PIX_FMT_NV12, \
|
||||
AV_PIX_FMT_NONE}, \
|
||||
.bsfs = bsf_name, \
|
||||
.hw_configs = v4l2_m2m_hw_configs, \
|
||||
--
|
||||
2.24.1
|
||||
|
@ -1,26 +0,0 @@
|
||||
From 3af2830856f4356acb9bf1655adf632759782aac Mon Sep 17 00:00:00 2001
|
||||
From: Lukas Rusak <lorusak@gmail.com>
|
||||
Date: Mon, 24 Sep 2018 13:38:46 -0700
|
||||
Subject: [PATCH 09/14] libavcodec: v4l2m2m: fix decoder capabilities
|
||||
|
||||
---
|
||||
libavcodec/v4l2_m2m_dec.c | 3 +--
|
||||
1 file changed, 1 insertion(+), 2 deletions(-)
|
||||
|
||||
diff --git a/libavcodec/v4l2_m2m_dec.c b/libavcodec/v4l2_m2m_dec.c
|
||||
index 8834b3d6fc..0087de35d0 100644
|
||||
--- a/libavcodec/v4l2_m2m_dec.c
|
||||
+++ b/libavcodec/v4l2_m2m_dec.c
|
||||
@@ -267,8 +267,7 @@ static const AVCodecHWConfigInternal *v4l2_m2m_hw_configs[] = {
|
||||
AV_PIX_FMT_NONE}, \
|
||||
.bsfs = bsf_name, \
|
||||
.hw_configs = v4l2_m2m_hw_configs, \
|
||||
- .capabilities = AV_CODEC_CAP_HARDWARE | AV_CODEC_CAP_DELAY, \
|
||||
- AV_CODEC_CAP_AVOID_PROBING, \
|
||||
+ .capabilities = AV_CODEC_CAP_HARDWARE | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING, \
|
||||
.wrapper_name = "v4l2m2m", \
|
||||
};
|
||||
|
||||
--
|
||||
2.24.1
|
||||
|
@ -1,101 +0,0 @@
|
||||
From 8b7ec4eae175835a806619b0bba98eb6d7252a13 Mon Sep 17 00:00:00 2001
|
||||
From: Lukas Rusak <lorusak@gmail.com>
|
||||
Date: Mon, 24 Sep 2018 13:39:31 -0700
|
||||
Subject: [PATCH 10/14] libavcodec: v4l2m2m: implement hwcontext
|
||||
|
||||
---
|
||||
libavcodec/v4l2_buffers.c | 22 ++++++++++++++++++++++
|
||||
libavcodec/v4l2_context.h | 2 ++
|
||||
libavcodec/v4l2_m2m.h | 2 ++
|
||||
libavcodec/v4l2_m2m_dec.c | 9 +++++++++
|
||||
4 files changed, 35 insertions(+)
|
||||
|
||||
diff --git a/libavcodec/v4l2_buffers.c b/libavcodec/v4l2_buffers.c
|
||||
index ee19bb5b6f..27820905b2 100644
|
||||
--- a/libavcodec/v4l2_buffers.c
|
||||
+++ b/libavcodec/v4l2_buffers.c
|
||||
@@ -456,6 +456,7 @@ int ff_v4l2_buffer_buf_to_avframe(AVFrame *frame, V4L2Buffer *avbuf)
|
||||
|
||||
frame->data[0] = (uint8_t *) v4l2_get_drm_frame(avbuf);
|
||||
frame->format = AV_PIX_FMT_DRM_PRIME;
|
||||
+ frame->hw_frames_ctx = av_buffer_ref(avbuf->context->frames_ref);
|
||||
} else {
|
||||
/* 1. get references to the actual data */
|
||||
for (i = 0; i < avbuf->num_planes; i++) {
|
||||
@@ -555,6 +556,27 @@ int ff_v4l2_buffer_initialize(V4L2Buffer* avbuf, int index)
|
||||
avbuf->buf.type = ctx->type;
|
||||
avbuf->buf.index = index;
|
||||
|
||||
+ if (buf_to_m2mctx(avbuf)->output_drm) {
|
||||
+ AVHWFramesContext *hwframes;
|
||||
+
|
||||
+ av_buffer_unref(&ctx->frames_ref);
|
||||
+
|
||||
+ ctx->frames_ref = av_hwframe_ctx_alloc(buf_to_m2mctx(avbuf)->device_ref);
|
||||
+ if (!ctx->frames_ref) {
|
||||
+ ret = AVERROR(ENOMEM);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ hwframes = (AVHWFramesContext*)ctx->frames_ref->data;
|
||||
+ hwframes->format = AV_PIX_FMT_DRM_PRIME;
|
||||
+ hwframes->sw_format = ctx->av_pix_fmt;
|
||||
+ hwframes->width = ctx->width;
|
||||
+ hwframes->height = ctx->height;
|
||||
+ ret = av_hwframe_ctx_init(ctx->frames_ref);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
if (V4L2_TYPE_IS_MULTIPLANAR(ctx->type)) {
|
||||
avbuf->buf.length = VIDEO_MAX_PLANES;
|
||||
avbuf->buf.m.planes = avbuf->planes;
|
||||
diff --git a/libavcodec/v4l2_context.h b/libavcodec/v4l2_context.h
|
||||
index 632f1d0aac..9a1dbbea60 100644
|
||||
--- a/libavcodec/v4l2_context.h
|
||||
+++ b/libavcodec/v4l2_context.h
|
||||
@@ -91,6 +91,8 @@ typedef struct V4L2Context {
|
||||
*/
|
||||
int done;
|
||||
|
||||
+ AVBufferRef *frames_ref;
|
||||
+
|
||||
} V4L2Context;
|
||||
|
||||
/**
|
||||
diff --git a/libavcodec/v4l2_m2m.h b/libavcodec/v4l2_m2m.h
|
||||
index 043a81a86a..4475618392 100644
|
||||
--- a/libavcodec/v4l2_m2m.h
|
||||
+++ b/libavcodec/v4l2_m2m.h
|
||||
@@ -60,6 +60,8 @@ typedef struct V4L2m2mContext {
|
||||
/* Reference to self; only valid while codec is active. */
|
||||
AVBufferRef *self_ref;
|
||||
|
||||
+ AVBufferRef *device_ref;
|
||||
+
|
||||
/* generate DRM frames */
|
||||
int output_drm;
|
||||
} V4L2m2mContext;
|
||||
diff --git a/libavcodec/v4l2_m2m_dec.c b/libavcodec/v4l2_m2m_dec.c
|
||||
index 0087de35d0..fffeb49092 100644
|
||||
--- a/libavcodec/v4l2_m2m_dec.c
|
||||
+++ b/libavcodec/v4l2_m2m_dec.c
|
||||
@@ -214,6 +214,15 @@ static av_cold int v4l2_decode_init(AVCodecContext *avctx)
|
||||
break;
|
||||
}
|
||||
|
||||
+ s->device_ref = av_hwdevice_ctx_alloc(AV_HWDEVICE_TYPE_DRM);
|
||||
+ if (!s->device_ref) {
|
||||
+ ret = AVERROR(ENOMEM);
|
||||
+ return ret;
|
||||
+ }
|
||||
+ ret = av_hwdevice_ctx_init(s->device_ref);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
ret = ff_v4l2_m2m_codec_init(avctx);
|
||||
if (ret) {
|
||||
V4L2m2mPriv *priv = avctx->priv_data;
|
||||
--
|
||||
2.24.1
|
||||
|
@ -1,50 +0,0 @@
|
||||
From 799aa17fbaa5a5dda7fd8a04c71df905e363f6f3 Mon Sep 17 00:00:00 2001
|
||||
From: Lukas Rusak <lorusak@gmail.com>
|
||||
Date: Mon, 24 Sep 2018 13:39:56 -0700
|
||||
Subject: [PATCH 11/14] libavcodec: v4l2m2m: implement flush
|
||||
|
||||
---
|
||||
libavcodec/v4l2_m2m_dec.c | 20 ++++++++++++++++++++
|
||||
1 file changed, 20 insertions(+)
|
||||
|
||||
diff --git a/libavcodec/v4l2_m2m_dec.c b/libavcodec/v4l2_m2m_dec.c
|
||||
index fffeb49092..47ac53df00 100644
|
||||
--- a/libavcodec/v4l2_m2m_dec.c
|
||||
+++ b/libavcodec/v4l2_m2m_dec.c
|
||||
@@ -236,6 +236,25 @@ static av_cold int v4l2_decode_init(AVCodecContext *avctx)
|
||||
return v4l2_prepare_decoder(s);
|
||||
}
|
||||
|
||||
+static void v4l2_flush(AVCodecContext *avctx)
|
||||
+{
|
||||
+ V4L2m2mPriv *priv = avctx->priv_data;
|
||||
+ V4L2m2mContext* s = priv->context;
|
||||
+ int ret;
|
||||
+
|
||||
+ /* wait for pending buffer references */
|
||||
+ if (atomic_load(&s->refcount))
|
||||
+ while(sem_wait(&s->refsync) == -1 && errno == EINTR);
|
||||
+
|
||||
+ ret = ff_v4l2_context_set_status(&s->output, VIDIOC_STREAMOFF);
|
||||
+ if (ret)
|
||||
+ av_log(avctx, AV_LOG_ERROR, "VIDIOC_STREAMOFF %s\n", s->output.name);
|
||||
+
|
||||
+ ret = ff_v4l2_context_set_status(&s->capture, VIDIOC_STREAMOFF);
|
||||
+ if (ret)
|
||||
+ av_log(avctx, AV_LOG_ERROR, "VIDIOC_STREAMOFF %s\n", s->capture.name);
|
||||
+}
|
||||
+
|
||||
#define OFFSET(x) offsetof(V4L2m2mPriv, x)
|
||||
#define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
|
||||
|
||||
@@ -271,6 +290,7 @@ static const AVCodecHWConfigInternal *v4l2_m2m_hw_configs[] = {
|
||||
.init = v4l2_decode_init, \
|
||||
.receive_frame = v4l2_receive_frame, \
|
||||
.close = ff_v4l2_m2m_codec_end, \
|
||||
+ .flush = v4l2_flush, \
|
||||
.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_DRM_PRIME, \
|
||||
AV_PIX_FMT_NV12, \
|
||||
AV_PIX_FMT_NONE}, \
|
||||
--
|
||||
2.24.1
|
||||
|
@ -1,63 +0,0 @@
|
||||
From f91c0f01a4c563129acd388272e0ac4795b83435 Mon Sep 17 00:00:00 2001
|
||||
From: Lukas Rusak <lorusak@gmail.com>
|
||||
Date: Fri, 31 Jan 2020 08:33:02 -0800
|
||||
Subject: [PATCH 12/14] libavcodec: v4l2m2m: aspect ratio
|
||||
|
||||
---
|
||||
libavcodec/v4l2_context.c | 26 +++++++++++++++++++++++++-
|
||||
1 file changed, 25 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libavcodec/v4l2_context.c b/libavcodec/v4l2_context.c
|
||||
index 12d40d597e..5c51399a4c 100644
|
||||
--- a/libavcodec/v4l2_context.c
|
||||
+++ b/libavcodec/v4l2_context.c
|
||||
@@ -539,6 +539,24 @@ static int v4l2_get_coded_format(V4L2Context* ctx, uint32_t *p)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static AVRational v4l2_get_sar(V4L2Context* ctx)
|
||||
+{
|
||||
+ struct AVRational sar = { 1, 1 };
|
||||
+ struct v4l2_cropcap cropcap;
|
||||
+ int ret;
|
||||
+
|
||||
+ memset(&cropcap, 0, sizeof(cropcap));
|
||||
+ cropcap.type = ctx->type;
|
||||
+
|
||||
+ ret = ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_CROPCAP, &cropcap);
|
||||
+ if (ret)
|
||||
+ return sar;
|
||||
+
|
||||
+ sar.num = cropcap.pixelaspect.numerator;
|
||||
+ sar.den = cropcap.pixelaspect.denominator;
|
||||
+ return sar;
|
||||
+}
|
||||
+
|
||||
/*****************************************************************************
|
||||
*
|
||||
* V4L2 Context Interface
|
||||
@@ -612,6 +630,7 @@ int ff_v4l2_context_enqueue_packet(V4L2Context* ctx, const AVPacket* pkt)
|
||||
int ff_v4l2_context_dequeue_frame(V4L2Context* ctx, AVFrame* frame)
|
||||
{
|
||||
V4L2Buffer* avbuf = NULL;
|
||||
+ int ret;
|
||||
|
||||
/*
|
||||
* blocks until:
|
||||
@@ -626,7 +645,12 @@ int ff_v4l2_context_dequeue_frame(V4L2Context* ctx, AVFrame* frame)
|
||||
return AVERROR(EAGAIN);
|
||||
}
|
||||
|
||||
- return ff_v4l2_buffer_buf_to_avframe(frame, avbuf);
|
||||
+ ret = ff_v4l2_buffer_buf_to_avframe(frame, avbuf);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ frame->sample_aspect_ratio = v4l2_get_sar(ctx);
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
int ff_v4l2_context_dequeue_packet(V4L2Context* ctx, AVPacket* pkt)
|
||||
--
|
||||
2.24.1
|
||||
|
@ -1,62 +0,0 @@
|
||||
From da24c4a08dd820804d9bd0709815d954836277d8 Mon Sep 17 00:00:00 2001
|
||||
From: Lukas Rusak <lorusak@gmail.com>
|
||||
Date: Fri, 31 Jan 2020 08:35:37 -0800
|
||||
Subject: [PATCH 13/14] libavcodec: v4l2m2m: save pkt
|
||||
|
||||
---
|
||||
libavcodec/v4l2_m2m_dec.c | 18 ++++++++++++++----
|
||||
1 file changed, 14 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/libavcodec/v4l2_m2m_dec.c b/libavcodec/v4l2_m2m_dec.c
|
||||
index 47ac53df00..cf48ff4b22 100644
|
||||
--- a/libavcodec/v4l2_m2m_dec.c
|
||||
+++ b/libavcodec/v4l2_m2m_dec.c
|
||||
@@ -131,6 +131,8 @@ static int v4l2_prepare_decoder(V4L2m2mContext *s)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static AVPacket saved_avpkt = { 0 };
|
||||
+
|
||||
static int v4l2_receive_frame(AVCodecContext *avctx, AVFrame *frame)
|
||||
{
|
||||
V4L2m2mContext *s = ((V4L2m2mPriv*)avctx->priv_data)->context;
|
||||
@@ -139,9 +141,14 @@ static int v4l2_receive_frame(AVCodecContext *avctx, AVFrame *frame)
|
||||
AVPacket avpkt = {0};
|
||||
int ret;
|
||||
|
||||
- ret = ff_decode_get_packet(avctx, &avpkt);
|
||||
- if (ret < 0 && ret != AVERROR_EOF)
|
||||
- return ret;
|
||||
+ if (saved_avpkt.size) {
|
||||
+ avpkt = saved_avpkt;
|
||||
+ memset(&saved_avpkt, 0, sizeof(saved_avpkt));
|
||||
+ } else {
|
||||
+ ret = ff_decode_get_packet(avctx, &avpkt);
|
||||
+ if (ret < 0 && ret != AVERROR_EOF)
|
||||
+ return ret;
|
||||
+ }
|
||||
|
||||
if (s->draining)
|
||||
goto dequeue;
|
||||
@@ -150,6 +157,8 @@ static int v4l2_receive_frame(AVCodecContext *avctx, AVFrame *frame)
|
||||
if (ret < 0) {
|
||||
if (ret != AVERROR(ENOMEM))
|
||||
return ret;
|
||||
+
|
||||
+ saved_avpkt = avpkt;
|
||||
/* no input buffers available, continue dequeing */
|
||||
}
|
||||
|
||||
@@ -167,7 +176,8 @@ static int v4l2_receive_frame(AVCodecContext *avctx, AVFrame *frame)
|
||||
}
|
||||
|
||||
dequeue:
|
||||
- av_packet_unref(&avpkt);
|
||||
+ if (!saved_avpkt.size)
|
||||
+ av_packet_unref(&avpkt);
|
||||
return ff_v4l2_context_dequeue_frame(capture, frame);
|
||||
}
|
||||
|
||||
--
|
||||
2.24.1
|
||||
|
@ -1,25 +0,0 @@
|
||||
From d317cac9ec2470bcdb44f92a82b64e4d132aeb51 Mon Sep 17 00:00:00 2001
|
||||
From: Lukas Rusak <lorusak@gmail.com>
|
||||
Date: Fri, 31 Jan 2020 09:00:51 -0800
|
||||
Subject: [PATCH 14/14] libavcodec: v4l2m2m: only use a few output buffers
|
||||
|
||||
---
|
||||
libavcodec/v4l2_m2m.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libavcodec/v4l2_m2m.h b/libavcodec/v4l2_m2m.h
|
||||
index 4475618392..7e075e7e80 100644
|
||||
--- a/libavcodec/v4l2_m2m.h
|
||||
+++ b/libavcodec/v4l2_m2m.h
|
||||
@@ -38,7 +38,7 @@
|
||||
|
||||
#define V4L_M2M_DEFAULT_OPTS \
|
||||
{ "num_output_buffers", "Number of buffers in the output context",\
|
||||
- OFFSET(num_output_buffers), AV_OPT_TYPE_INT, { .i64 = 16 }, 6, INT_MAX, FLAGS }
|
||||
+ OFFSET(num_output_buffers), AV_OPT_TYPE_INT, { .i64 = 2 }, 1, INT_MAX, FLAGS }
|
||||
|
||||
typedef struct V4L2m2mContext {
|
||||
char devname[PATH_MAX];
|
||||
--
|
||||
2.24.1
|
||||
|
Loading…
x
Reference in New Issue
Block a user