Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/videolan/dav1d.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Almer <jamrial@gmail.com>2022-04-08 05:13:11 +0300
committerJames Almer <jamrial@gmail.com>2022-04-08 22:28:29 +0300
commitbfc1178f911543739fe50697998d9df69ad2f201 (patch)
tree24d020dccb0aef25b72e658af6a93199856ba3ec
parent1ec07ecba73fd5061088c8db8a09324318278756 (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.c3
-rw-r--r--src/picture.c3
-rw-r--r--src/picture.h4
3 files changed, 9 insertions, 1 deletions
diff --git a/src/obu.c b/src/obu.c
index d0f8fcf..6d06a10 100644
--- a/src/obu.c
+++ b/src/obu.c
@@ -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