summaryrefslogtreecommitdiff
path: root/libavcodec
diff options
context:
space:
mode:
authorJames Almer <jamrial@gmail.com>2021-03-27 00:07:56 -0300
committerJames Almer <jamrial@gmail.com>2021-07-14 13:11:51 -0300
commit1349de10b22d6c8643bec43eced296ec2a126671 (patch)
treef7b6dce439768012c3f34446d19b1ddf6bae94e2 /libavcodec
parent3f5d5c1c2dd71d1b4e5fcc0496337d1b224b0794 (diff)
avcodec/libdav1d: parse sequence headers in extradata if available
This allows the decoder context to be initialized with all stream parameters before a packet is parsed. Signed-off-by: James Almer <jamrial@gmail.com>
Diffstat (limited to 'libavcodec')
-rw-r--r--libavcodec/libdav1d.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/libavcodec/libdav1d.c b/libavcodec/libdav1d.c
index c39df418d5..46436a8568 100644
--- a/libavcodec/libdav1d.c
+++ b/libavcodec/libdav1d.c
@@ -158,6 +158,45 @@ static void libdav1d_init_params(AVCodecContext *c, const Dav1dSequenceHeader *s
}
}
+static av_cold int libdav1d_parse_extradata(AVCodecContext *c)
+{
+ Dav1dSequenceHeader seq;
+ size_t offset = 0;
+ int res;
+
+ if (!c->extradata || c->extradata_size <= 0)
+ return 0;
+
+ if (c->extradata[0] & 0x80) {
+ int version = c->extradata[0] & 0x7F;
+
+ if (version != 1 || c->extradata_size < 4) {
+ int explode = !!(c->err_recognition & AV_EF_EXPLODE);
+ av_log(c, explode ? AV_LOG_ERROR : AV_LOG_WARNING,
+ "Error decoding extradata\n");
+ return explode ? AVERROR_INVALIDDATA : 0;
+ }
+
+ // Do nothing if there are no configOBUs to parse
+ if (c->extradata_size == 4)
+ return 0;
+
+ offset = 4;
+ }
+
+ res = dav1d_parse_sequence_header(&seq, c->extradata + offset,
+ c->extradata_size - offset);
+ if (res < 0)
+ return 0; // Assume no seqhdr OBUs are present
+
+ libdav1d_init_params(c, &seq);
+ res = ff_set_dimensions(c, seq.max_width, seq.max_height);
+ if (res < 0)
+ return res;
+
+ return 0;
+}
+
static av_cold int libdav1d_init(AVCodecContext *c)
{
Libdav1dContext *dav1d = c->priv_data;
@@ -192,6 +231,10 @@ static av_cold int libdav1d_init(AVCodecContext *c)
av_log(c, AV_LOG_DEBUG, "Using %d frame threads, %d tile threads\n",
s.n_frame_threads, s.n_tile_threads);
+ res = libdav1d_parse_extradata(c);
+ if (res < 0)
+ return res;
+
res = dav1d_open(&dav1d->c, &s);
if (res < 0)
return AVERROR(ENOMEM);