From 88ed3507266a373ad844f703d1361880feeeb9d9 Mon Sep 17 00:00:00 2001
From: Stanislav Dolganov <dolganov@qst.hk>
Date: Mon, 28 Mar 2016 13:38:00 +0300
Subject: [PATCH 3/4] thread bug semi-fix

---
 libavcodec/ffv1.c    |  8 ++++++--
 libavcodec/ffv1dec.c | 28 +++++++++++++++++++++++++---
 2 files changed, 31 insertions(+), 5 deletions(-)

diff --git a/libavcodec/ffv1.c b/libavcodec/ffv1.c
index 428bc8d..d9f8881 100644
--- a/libavcodec/ffv1.c
+++ b/libavcodec/ffv1.c
@@ -60,6 +60,8 @@ av_cold int ff_ffv1_common_init(AVCodecContext *avctx)
 
     s->c_image_line_buf = av_mallocz_array(sizeof(*s->c_image_line_buf), s->width);
     s->p_image_line_buf = av_mallocz_array(sizeof(*s->p_image_line_buf), s->width);
+    if (!s->c_image_line_buf || !s->p_image_line_buf)
+        return AVERROR(ENOMEM);
 
     // defaults
     s->num_h_slices = 1;
@@ -234,8 +236,10 @@ av_cold int ff_ffv1_close(AVCodecContext *avctx)
         av_freep(&fs->sample_buffer);
     }
 
-    av_freep(&s->c_image_line_buf);
-    av_freep(&s->p_image_line_buf);
+    if (s->p_image_line_buf)
+        av_freep(&s->p_image_line_buf);
+    if (s->c_image_line_buf)
+        av_freep(&s->c_image_line_buf);
 
     av_freep(&avctx->stats_out);
     for (j = 0; j < s->quant_table_count; j++) {
diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c
index 5b923f0..b1aaeea 100644
--- a/libavcodec/ffv1dec.c
+++ b/libavcodec/ffv1dec.c
@@ -1092,15 +1092,19 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
                           fs->slice_height);
         }
     }
-    ff_thread_report_progress(&f->picture, INT_MAX, 0);
+    /*ff_thread_report_progress(&f->picture, INT_MAX, 0);
 
-    f->picture_number++;
+    f->picture_number++;*/
 
     if (!p->key_frame) {
         if ((ret = ff_predict_frame(avctx, f)) < 0)
             return ret;
     }
 
+    ff_thread_report_progress(&f->picture, INT_MAX, 0);
+
+    f->picture_number++;
+
     if (f->last_picture.f)
         ff_thread_release_buffer(avctx, &f->last_picture);
     f->cur = NULL;
@@ -1121,10 +1125,14 @@ static int init_thread_copy(AVCodecContext *avctx)
 
     f->picture.f      = NULL;
     f->last_picture.f = NULL;
+    f->residual.f     = NULL;
     f->sample_buffer  = NULL;
     f->max_slice_count = 0;
     f->slice_count = 0;
 
+    f->p_image_line_buf = NULL;
+    f->c_image_line_buf = NULL;
+
     for (i = 0; i < f->quant_table_count; i++) {
         av_assert0(f->version > 1);
         f->initial_states[i] = av_memdup(f->initial_states[i],
@@ -1133,6 +1141,16 @@ static int init_thread_copy(AVCodecContext *avctx)
 
     f->picture.f      = av_frame_alloc();
     f->last_picture.f = av_frame_alloc();
+    f->residual.f     = av_frame_alloc();
+
+    if (!f->picture.f || !f->last_picture.f || !f->residual.f)
+        return AVERROR(ENOMEM);
+
+    f->p_image_line_buf = av_mallocz_array(sizeof(*f->p_image_line_buf), f->width);
+    f->c_image_line_buf = av_mallocz_array(sizeof(*f->c_image_line_buf), f->width);
+
+    if (!f->p_image_line_buf || !f->c_image_line_buf)
+        return AVERROR(ENOMEM);
 
     if ((ret = ff_ffv1_init_slice_contexts(f)) < 0)
         return ret;
@@ -1180,7 +1198,8 @@ static int update_thread_context(AVCodecContext *dst, const AVCodecContext *src)
         return 0;
 
     {
-        ThreadFrame picture = fdst->picture, last_picture = fdst->last_picture;
+        ThreadFrame picture = fdst->picture, last_picture = fdst->last_picture, residual = fdst->residual;
+        uint16_t *c_image_line_buf = fdst->c_image_line_buf, *p_image_line_buf = fdst->p_image_line_buf;
         uint8_t (*initial_states[MAX_QUANT_TABLES])[32];
         struct FFV1Context *slice_context[MAX_SLICES];
         memcpy(initial_states, fdst->initial_states, sizeof(fdst->initial_states));
@@ -1191,6 +1210,9 @@ static int update_thread_context(AVCodecContext *dst, const AVCodecContext *src)
         memcpy(fdst->slice_context,  slice_context , sizeof(fdst->slice_context));
         fdst->picture      = picture;
         fdst->last_picture = last_picture;
+        fdst->residual     = residual;
+        fdst->p_image_line_buf = p_image_line_buf;
+        fdst->c_image_line_buf = c_image_line_buf;
         for (i = 0; i<fdst->num_h_slices * fdst->num_v_slices; i++) {
             FFV1Context *fssrc = fsrc->slice_context[i];
             FFV1Context *fsdst = fdst->slice_context[i];
-- 
2.6.4 (Apple Git-63)

