diff mbox series

[FFmpeg-devel] avcodec/libdav1d: honor the requested skip_frame level

Message ID 20221208163101.4139-1-jamrial@gmail.com
State New
Headers show
Series [FFmpeg-devel] avcodec/libdav1d: honor the requested skip_frame level | expand

Checks

Context Check Description
yinshiyou/make_loongarch64 success Make finished
yinshiyou/make_fate_loongarch64 success Make fate finished
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished

Commit Message

James Almer Dec. 8, 2022, 4:31 p.m. UTC
This supports dropping non-intra, non-key, or all frames.

Signed-off-by: James Almer <jamrial@gmail.com>
---
 libavcodec/libdav1d.c | 51 +++++++++++++++++++++++++++----------------
 1 file changed, 32 insertions(+), 19 deletions(-)
diff mbox series

Patch

diff --git a/libavcodec/libdav1d.c b/libavcodec/libdav1d.c
index 028929404e..2f83a963e9 100644
--- a/libavcodec/libdav1d.c
+++ b/libavcodec/libdav1d.c
@@ -369,6 +369,37 @@  static int libdav1d_receive_frame(AVCodecContext *c, AVFrame *frame)
         return res;
     }
 
+#if FF_DAV1D_VERSION_AT_LEAST(5,1)
+    dav1d_get_event_flags(dav1d->c, &event_flags);
+    if (c->pix_fmt == AV_PIX_FMT_NONE ||
+        event_flags & DAV1D_EVENT_FLAG_NEW_SEQUENCE)
+#endif
+    libdav1d_init_params(c, p->seq_hdr);
+    if (c->width != p->p.w || c->height != p->p.h) {
+        res = ff_set_dimensions(c, p->p.w, p->p.h);
+        if (res < 0) {
+            dav1d_picture_unref(p);
+            return 0;
+        }
+    }
+
+    av_reduce(&c->sample_aspect_ratio.num,
+              &c->sample_aspect_ratio.den,
+              p->p.h * (int64_t)p->frame_hdr->render_width,
+              p->p.w * (int64_t)p->frame_hdr->render_height,
+              INT_MAX);
+    ff_set_sar(c, c->sample_aspect_ratio);
+
+    if ((c->skip_frame >= AVDISCARD_NONINTRA &&
+            (p->frame_hdr->frame_type != DAV1D_FRAME_TYPE_KEY &&
+             p->frame_hdr->frame_type != DAV1D_FRAME_TYPE_INTRA)) ||
+        (c->skip_frame >= AVDISCARD_NONKEY   &&
+             p->frame_hdr->frame_type != DAV1D_FRAME_TYPE_KEY) ||
+        c->skip_frame >= AVDISCARD_ALL) {
+        dav1d_picture_unref(p);
+        return 0;
+    }
+
     av_assert0(p->data[0] && p->allocator_data);
 
     // This requires the custom allocator above
@@ -385,30 +416,12 @@  static int libdav1d_receive_frame(AVCodecContext *c, AVFrame *frame)
     frame->linesize[1] = p->stride[1];
     frame->linesize[2] = p->stride[1];
 
-#if FF_DAV1D_VERSION_AT_LEAST(5,1)
-    dav1d_get_event_flags(dav1d->c, &event_flags);
-    if (c->pix_fmt == AV_PIX_FMT_NONE ||
-        event_flags & DAV1D_EVENT_FLAG_NEW_SEQUENCE)
-#endif
-    libdav1d_init_params(c, p->seq_hdr);
     res = ff_decode_frame_props(c, frame);
     if (res < 0)
         goto fail;
 
     frame->width = p->p.w;
     frame->height = p->p.h;
-    if (c->width != p->p.w || c->height != p->p.h) {
-        res = ff_set_dimensions(c, p->p.w, p->p.h);
-        if (res < 0)
-            goto fail;
-    }
-
-    av_reduce(&frame->sample_aspect_ratio.num,
-              &frame->sample_aspect_ratio.den,
-              frame->height * (int64_t)p->frame_hdr->render_width,
-              frame->width  * (int64_t)p->frame_hdr->render_height,
-              INT_MAX);
-    ff_set_sar(c, frame->sample_aspect_ratio);
 
     if (p->m.user_data.data)
         memcpy(&frame->reordered_opaque, p->m.user_data.data, sizeof(frame->reordered_opaque));
@@ -595,7 +608,7 @@  const FFCodec ff_libdav1d_decoder = {
     FF_CODEC_RECEIVE_FRAME_CB(libdav1d_receive_frame),
     .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_OTHER_THREADS,
     .caps_internal  = FF_CODEC_CAP_SETS_PKT_DTS |
-                      FF_CODEC_CAP_AUTO_THREADS,
+                      FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | FF_CODEC_CAP_AUTO_THREADS,
     .p.priv_class   = &libdav1d_class,
     .p.wrapper_name = "libdav1d",
 };