diff options
author | James Almer <jamrial@gmail.com> | 2022-04-08 05:13:11 +0300 |
---|---|---|
committer | James Almer <jamrial@gmail.com> | 2022-04-08 22:28:29 +0300 |
commit | bfc1178f911543739fe50697998d9df69ad2f201 (patch) | |
tree | 24d020dccb0aef25b72e658af6a93199856ba3ec | |
parent | 1ec07ecba73fd5061088c8db8a09324318278756 (diff) |
obu: don't output invisible but showable key frames more than once
From section 6.8.2 in the AV1 spec:
"It is a requirement of bitstream conformance that when show_existing_frame is
used to show a previous frame with RefFrameType[ frame_to_show_map_idx ] equal
to KEY_FRAME, that the frame is output via the show_existing_frame mechanism at
most once."
-rw-r--r-- | src/obu.c | 3 | ||||
-rw-r--r-- | src/picture.c | 3 | ||||
-rw-r--r-- | src/picture.h | 4 |
3 files changed, 9 insertions, 1 deletions
@@ -1558,7 +1558,7 @@ int dav1d_parse_obus(Dav1dContext *const c, Dav1dData *const in, const int globa if (c->frame_hdr->show_existing_frame) { if (!c->refs[c->frame_hdr->existing_frame_idx].p.p.data[0]) goto error; if (c->strict_std_compliance && - !c->refs[c->frame_hdr->existing_frame_idx].p.p.frame_hdr->showable_frame) + !c->refs[c->frame_hdr->existing_frame_idx].p.showable) { goto error; } @@ -1613,6 +1613,7 @@ int dav1d_parse_obus(Dav1dContext *const c, Dav1dData *const in, const int globa } if (c->refs[c->frame_hdr->existing_frame_idx].p.p.frame_hdr->frame_type == DAV1D_FRAME_TYPE_KEY) { const int r = c->frame_hdr->existing_frame_idx; + c->refs[r].p.showable = 0; for (int i = 0; i < 8; i++) { if (i == r) continue; diff --git a/src/picture.c b/src/picture.c index 7046ed1..544828f 100644 --- a/src/picture.c +++ b/src/picture.c @@ -202,6 +202,7 @@ int dav1d_thread_picture_alloc(Dav1dContext *const c, Dav1dFrameContext *const f c->frame_flags &= flags_mask; p->visible = f->frame_hdr->show_frame; + p->showable = f->frame_hdr->showable_frame; if (have_frame_mt) { atomic_init(&p->progress[0], 0); atomic_init(&p->progress[1], 0); @@ -259,6 +260,7 @@ void dav1d_thread_picture_ref(Dav1dThreadPicture *const dst, { dav1d_picture_ref(&dst->p, &src->p); dst->visible = src->visible; + dst->showable = src->showable; dst->progress = src->progress; dst->flags = src->flags; } @@ -268,6 +270,7 @@ void dav1d_thread_picture_move_ref(Dav1dThreadPicture *const dst, { dav1d_picture_move_ref(&dst->p, &src->p); dst->visible = src->visible; + dst->showable = src->showable; dst->progress = src->progress; dst->flags = src->flags; memset(src, 0, sizeof(*src)); diff --git a/src/picture.h b/src/picture.h index 0e30d48..154c85a 100644 --- a/src/picture.h +++ b/src/picture.h @@ -52,6 +52,10 @@ enum PictureFlags { typedef struct Dav1dThreadPicture { Dav1dPicture p; int visible; + // This can be set for inter frames, non-key intra frames, or for invisible + // keyframes that have not yet been made visible using the show-existing-frame + // mechanism. + int showable; enum PictureFlags flags; // [0] block data (including segmentation map and motion vectors) // [1] pixel data |