diff options
author | James Almer <jamrial@gmail.com> | 2021-03-27 00:07:56 -0300 |
---|---|---|
committer | James Almer <jamrial@gmail.com> | 2021-07-14 13:11:51 -0300 |
commit | 1349de10b22d6c8643bec43eced296ec2a126671 (patch) | |
tree | f7b6dce439768012c3f34446d19b1ddf6bae94e2 | |
parent | 3f5d5c1c2dd71d1b4e5fcc0496337d1b224b0794 (diff) | |
download | ffmpeg-1349de10b22d6c8643bec43eced296ec2a126671.tar.gz |
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>
-rw-r--r-- | libavcodec/libdav1d.c | 43 |
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); |