[FFmpeg-cvslog] ffv1dec: add code to support frame threading with gop=1 ffv1

Michael Niedermayer git at videolan.org
Sat Apr 27 16:31:08 CEST 2013


ffmpeg | branch: master | Michael Niedermayer <michaelni at gmx.at> | Sat Apr 27 16:15:33 2013 +0200| [ff0b4c08ca0c65428f9588a6ff65a1abed7a706c] | committer: Michael Niedermayer

ffv1dec: add code to support frame threading with gop=1 ffv1

CODEC_CAP_FRAME_THREADS is not added yet because that would
unconditionally enable it, breaking gop>1 files.

Signed-off-by: Michael Niedermayer <michaelni at gmx.at>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=ff0b4c08ca0c65428f9588a6ff65a1abed7a706c
---

 libavcodec/ffv1dec.c |   27 ++++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c
index c4e8f9b..28e561f 100644
--- a/libavcodec/ffv1dec.c
+++ b/libavcodec/ffv1dec.c
@@ -38,6 +38,7 @@
 #include "golomb.h"
 #include "mathops.h"
 #include "ffv1.h"
+#include "thread.h"
 
 static inline av_flatten int get_symbol_inline(RangeCoder *c, uint8_t *state,
                                                int is_signed)
@@ -733,12 +734,14 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
     int buf_size        = avpkt->size;
     FFV1Context *f      = avctx->priv_data;
     RangeCoder *const c = &f->slice_context[0]->c;
+    ThreadFrame frame = { .f = data };
     int i, ret;
     uint8_t keystate = 128;
     const uint8_t *buf_p;
     AVFrame *const p    = data;
 
     f->cur = p;
+    f->avctx = avctx;
 
     ff_init_range_decoder(c, buf, buf_size);
     ff_build_rac_states(c, 0.05 * (1LL << 32), 256 - 8);
@@ -759,8 +762,10 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
         p->key_frame = 0;
     }
 
-    if ((ret = ff_get_buffer(avctx, p, AV_GET_BUFFER_FLAG_REF)) < 0)
+    if ((ret = ff_thread_get_buffer(avctx, &frame, AV_GET_BUFFER_FLAG_REF)) < 0) {
+        av_log(avctx, AV_LOG_ERROR, "ff_thread_get_buffer() failed.\n");
         return ret;
+    }
 
     if (avctx->debug & FF_DEBUG_PICT_INFO)
         av_log(avctx, AV_LOG_DEBUG, "ver:%d keyframe:%d coder:%d ec:%d slices:%d bps:%d\n",
@@ -801,6 +806,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
         } else
             fs->c.bytestream_end = (uint8_t *)(buf_p + v);
 
+        fs->avctx = avctx;
         fs->cur = p;
     }
 
@@ -845,6 +851,24 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
     return buf_size;
 }
 
+static int init_thread_copy(AVCodecContext *avctx)
+{
+    FFV1Context *f = avctx->priv_data;
+    int ret, i;
+
+    for (i = 0; i < f->quant_table_count; i++) {
+        void *p = f->initial_states[i];
+        f->initial_states[i] = av_malloc(f->context_count[i] * sizeof(*f->initial_states[i]));
+        if (!f->initial_states[i])
+            return AVERROR(ENOMEM);
+        memcpy(f->initial_states[i], p, f->context_count[i] * sizeof(*f->initial_states[i]));
+    }
+
+    if ((ret = ffv1_init_slice_contexts(f)) < 0)
+        return ret;
+    return 0;
+}
+
 AVCodec ff_ffv1_decoder = {
     .name           = "ffv1",
     .type           = AVMEDIA_TYPE_VIDEO,
@@ -853,6 +877,7 @@ AVCodec ff_ffv1_decoder = {
     .init           = decode_init,
     .close          = ffv1_close,
     .decode         = decode_frame,
+    .init_thread_copy = init_thread_copy,
     .capabilities   = CODEC_CAP_DR1 /*| CODEC_CAP_DRAW_HORIZ_BAND*/ |
                       CODEC_CAP_SLICE_THREADS,
     .long_name      = NULL_IF_CONFIG_SMALL("FFmpeg video codec #1"),



More information about the ffmpeg-cvslog mailing list