This commit adds support for hardware accelerated decoding to
the decoder.
The previous commits already refactored the decoder, this commit
simply adds calls to hooks to decode.
---
 libavcodec/ffv1.h    |  1 +
 libavcodec/ffv1dec.c | 62 +++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 59 insertions(+), 4 deletions(-)

diff --git a/libavcodec/ffv1.h b/libavcodec/ffv1.h
index 6b4ffca3f9..93174bd45e 100644
--- a/libavcodec/ffv1.h
+++ b/libavcodec/ffv1.h
@@ -121,6 +121,7 @@ typedef struct FFV1Context {
     int64_t picture_number;
     int key_frame;
     ProgressFrame picture, last_picture;
+    void *hwaccel_picture_private, *hwaccel_last_picture_private;
     uint32_t crcref;
     enum AVPixelFormat pix_fmt;
 
diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c
index 83c5975550..e05f2e6109 100644
--- a/libavcodec/ffv1dec.c
+++ b/libavcodec/ffv1dec.c
@@ -41,6 +41,9 @@
 #include "libavutil/refstruct.h"
 #include "thread.h"
 #include "decode.h"
+#include "hwconfig.h"
+#include "hwaccel_internal.h"
+#include "config_components.h"
 
 static inline av_flatten int get_symbol_inline(RangeCoder *c, uint8_t *state,
                                                int is_signed)
@@ -1037,6 +1040,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame 
*rframe,
     FFV1Context *f      = avctx->priv_data;
     int ret;
     AVFrame *p;
+    const FFHWAccel *hwaccel = NULL;
 
     /* This is copied onto the first slice's range coder context */
     RangeCoder c;
@@ -1044,7 +1048,6 @@ static int decode_frame(AVCodecContext *avctx, AVFrame 
*rframe,
     ff_progress_frame_unref(&f->last_picture);
     FFSWAP(ProgressFrame, f->picture, f->last_picture);
 
-
     f->avctx = avctx;
     f->frame_damaged = 0;
 
@@ -1052,11 +1055,18 @@ static int decode_frame(AVCodecContext *avctx, AVFrame 
*rframe,
     if (ret < 0)
         return ret;
 
+    if (avctx->hwaccel)
+        hwaccel = ffhwaccel(avctx->hwaccel);
+
     ret = ff_progress_frame_get_buffer(avctx, &f->picture,
                                        AV_GET_BUFFER_FLAG_REF);
     if (ret < 0)
         return ret;
 
+    ret = ff_hwaccel_frame_priv_alloc(avctx, &f->hwaccel_picture_private);
+    if (ret < 0)
+        return ret;
+
     p = f->picture.f;
 
     p->pict_type = AV_PICTURE_TYPE_I; //FIXME I vs. P
@@ -1073,15 +1083,53 @@ static int decode_frame(AVCodecContext *avctx, AVFrame 
*rframe,
         av_log(avctx, AV_LOG_DEBUG, "ver:%d keyframe:%d coder:%d ec:%d 
slices:%d bps:%d\n",
                f->version, !!(p->flags & AV_FRAME_FLAG_KEY), f->ac, f->ec, 
f->slice_count, f->avctx->bits_per_raw_sample);
 
+    /* Start */
+    if (hwaccel) {
+        ret = hwaccel->start_frame(avctx, avpkt->data, avpkt->size);
+        if (ret < 0)
+            return ret;
+    }
+
     ff_thread_finish_setup(avctx);
 
-    ret = decode_slices(avctx, c, avpkt);
-    if (ret < 0)
-        return ret;
+    /* Decode slices */
+    if (hwaccel) {
+        uint8_t *buf_end = avpkt->data + avpkt->size;
+
+        if (!(p->flags & AV_FRAME_FLAG_KEY) && f->last_picture.f)
+            ff_progress_frame_await(&f->last_picture, f->slice_count - 1);
+
+        for (int i = f->slice_count - 1; i >= 0; i--) {
+            uint8_t *pos;
+            uint32_t len;
+            ret = find_next_slice(avctx, avpkt->data, buf_end, i,
+                                  &pos, &len);
+            if (ret < 0)
+                return ret;
+
+            buf_end -= len;
+
+            ret = hwaccel->decode_slice(avctx, pos, len);
+            if (ret < 0)
+                return ret;
+        }
+    } else {
+        ret = decode_slices(avctx, c, avpkt);
+        if (ret < 0)
+            return ret;
+    }
+
+    /* Finalize */
+    if (hwaccel) {
+        ret = hwaccel->end_frame(avctx);
+        if (ret < 0)
+            return ret;
+    }
 
     ff_progress_frame_report(&f->picture, INT_MAX);
 
     ff_progress_frame_unref(&f->last_picture);
+    av_refstruct_unref(&f->hwaccel_last_picture_private);
     if ((ret = av_frame_ref(rframe, f->picture.f)) < 0)
         return ret;
 
@@ -1153,7 +1201,10 @@ static av_cold int ffv1_decode_close(AVCodecContext 
*avctx)
     FFV1Context *const s = avctx->priv_data;
 
     ff_progress_frame_unref(&s->picture);
+    av_refstruct_unref(&s->hwaccel_picture_private);
+
     ff_progress_frame_unref(&s->last_picture);
+    av_refstruct_unref(&s->hwaccel_last_picture_private);
 
     return ff_ffv1_close(avctx);
 }
@@ -1172,4 +1223,7 @@ const FFCodec ff_ffv1_decoder = {
                       AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_SLICE_THREADS,
     .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP |
                       FF_CODEC_CAP_USES_PROGRESSFRAMES,
+    .hw_configs     = (const AVCodecHWConfigInternal *const []) {
+        NULL
+    },
 };
-- 
2.45.2
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Reply via email to