[FFmpeg-devel] [PATCH 1/2] avcodec/libdav1d: try to set decoder context parameters during init()
James Almer
jamrial at gmail.com
Mon May 11 17:27:55 EEST 2020
If extradata is available, use it to initialize the AVCodecContext before
packet data is seen. Also, don't constantly overwrite it after it's set.
Signed-off-by: James Almer <jamrial at gmail.com>
---
The main benefit from this is using ff_decode_frame_props() to fill frame
props, which includes copying any relevant side data that may be present in
packets, like for example container mastering metadata propagated by a demuxer.
libavcodec/libdav1d.c | 102 +++++++++++++++++++++++++++++-------------
1 file changed, 71 insertions(+), 31 deletions(-)
diff --git a/libavcodec/libdav1d.c b/libavcodec/libdav1d.c
index 5248e3f9f5..72f06c550e 100644
--- a/libavcodec/libdav1d.c
+++ b/libavcodec/libdav1d.c
@@ -42,6 +42,8 @@ typedef struct Libdav1dContext {
int apply_grain;
int operating_point;
int all_layers;
+
+ int inited;
} Libdav1dContext;
static const enum AVPixelFormat pix_fmt[][3] = {
@@ -117,9 +119,59 @@ static void libdav1d_picture_release(Dav1dPicture *p, void *cookie)
av_buffer_unref(&buf);
}
+static int libdav1d_init_params(AVCodecContext *c, Dav1dSequenceHeader *seq)
+{
+ Libdav1dContext *dav1d = c->priv_data;
+ int res;
+
+ if (dav1d->inited)
+ return 0;
+
+ c->profile = seq->profile;
+ c->level = ((seq->operating_points[0].major_level - 2) << 2)
+ | seq->operating_points[0].minor_level;
+
+ res = ff_set_dimensions(c, seq->max_width, seq->max_height);
+ if (res < 0)
+ return res;
+
+ switch (seq->chr) {
+ case DAV1D_CHR_VERTICAL:
+ c->chroma_sample_location = AVCHROMA_LOC_LEFT;
+ break;
+ case DAV1D_CHR_COLOCATED:
+ c->chroma_sample_location = AVCHROMA_LOC_TOPLEFT;
+ break;
+ }
+ c->colorspace = (enum AVColorSpace) seq->mtrx;
+ c->color_primaries = (enum AVColorPrimaries) seq->pri;
+ c->color_trc = (enum AVColorTransferCharacteristic) seq->trc;
+ c->color_range = seq->color_range ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
+
+ if (seq->layout == DAV1D_PIXEL_LAYOUT_I444 &&
+ seq->mtrx == DAV1D_MC_IDENTITY &&
+ seq->pri == DAV1D_COLOR_PRI_BT709 &&
+ seq->trc == DAV1D_TRC_SRGB)
+ c->pix_fmt = pix_fmt_rgb[seq->hbd];
+ else
+ c->pix_fmt = pix_fmt[seq->layout][seq->hbd];
+
+ if (seq->num_units_in_tick && seq->time_scale) {
+ av_reduce(&c->framerate.den, &c->framerate.num,
+ seq->num_units_in_tick, seq->time_scale, INT_MAX);
+ if (seq->equal_picture_interval)
+ c->ticks_per_frame = seq->num_ticks_per_picture;
+ }
+
+ dav1d->inited = 1;
+
+ return 0;
+}
+
static av_cold int libdav1d_init(AVCodecContext *c)
{
Libdav1dContext *dav1d = c->priv_data;
+ Dav1dSequenceHeader seq;
Dav1dSettings s;
int threads = (c->thread_count ? c->thread_count : av_cpu_count()) * 3 / 2;
int res;
@@ -153,6 +205,16 @@ static av_cold int libdav1d_init(AVCodecContext *c)
if (res < 0)
return AVERROR(ENOMEM);
+ if (c->extradata && c->extradata_size) {
+ res = dav1d_parse_sequence_header(&seq, c->extradata, c->extradata_size);
+ if (res < 0)
+ return AVERROR_INVALIDDATA;
+
+ res = libdav1d_init_params(c, &seq);
+ if (res < 0)
+ return res;
+ }
+
return 0;
}
@@ -162,6 +224,7 @@ static void libdav1d_flush(AVCodecContext *c)
dav1d_data_unref(&dav1d->data);
dav1d_flush(dav1d->c);
+ dav1d->inited = 0;
}
static void libdav1d_data_free(const uint8_t *data, void *opaque) {
@@ -256,9 +319,14 @@ static int libdav1d_receive_frame(AVCodecContext *c, AVFrame *frame)
frame->linesize[1] = p->stride[1];
frame->linesize[2] = p->stride[1];
- 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;
+ res = libdav1d_init_params(c, p->seq_hdr);
+ if (res < 0)
+ return res;
+
+ res = ff_decode_frame_props(c, frame);
+ if (res < 0)
+ return res;
+
frame->width = p->p.w;
frame->height = p->p.h;
if (c->width != p->p.w || c->height != p->p.h) {
@@ -267,39 +335,11 @@ static int libdav1d_receive_frame(AVCodecContext *c, AVFrame *frame)
goto fail;
}
- switch (p->seq_hdr->chr) {
- case DAV1D_CHR_VERTICAL:
- frame->chroma_location = c->chroma_sample_location = AVCHROMA_LOC_LEFT;
- break;
- case DAV1D_CHR_COLOCATED:
- frame->chroma_location = c->chroma_sample_location = AVCHROMA_LOC_TOPLEFT;
- break;
- }
- frame->colorspace = c->colorspace = (enum AVColorSpace) p->seq_hdr->mtrx;
- frame->color_primaries = c->color_primaries = (enum AVColorPrimaries) p->seq_hdr->pri;
- frame->color_trc = c->color_trc = (enum AVColorTransferCharacteristic) p->seq_hdr->trc;
- frame->color_range = c->color_range = p->seq_hdr->color_range ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
-
- if (p->p.layout == DAV1D_PIXEL_LAYOUT_I444 &&
- p->seq_hdr->mtrx == DAV1D_MC_IDENTITY &&
- p->seq_hdr->pri == DAV1D_COLOR_PRI_BT709 &&
- p->seq_hdr->trc == DAV1D_TRC_SRGB)
- frame->format = c->pix_fmt = pix_fmt_rgb[p->seq_hdr->hbd];
- else
- frame->format = c->pix_fmt = pix_fmt[p->p.layout][p->seq_hdr->hbd];
-
if (p->m.user_data.data)
memcpy(&frame->reordered_opaque, p->m.user_data.data, sizeof(frame->reordered_opaque));
else
frame->reordered_opaque = AV_NOPTS_VALUE;
- if (p->seq_hdr->num_units_in_tick && p->seq_hdr->time_scale) {
- av_reduce(&c->framerate.den, &c->framerate.num,
- p->seq_hdr->num_units_in_tick, p->seq_hdr->time_scale, INT_MAX);
- if (p->seq_hdr->equal_picture_interval)
- c->ticks_per_frame = p->seq_hdr->num_ticks_per_picture;
- }
-
// match timestamps and packet size
frame->pts = frame->best_effort_timestamp = p->m.timestamp;
#if FF_API_PKT_PTS
--
2.26.2
More information about the ffmpeg-devel
mailing list