---
 libavcodec/mimic.c |   54 ++++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 40 insertions(+), 14 deletions(-)

diff --git a/libavcodec/mimic.c b/libavcodec/mimic.c
index 58c6b77..55b7fa6 100644
--- a/libavcodec/mimic.c
+++ b/libavcodec/mimic.c
@@ -45,6 +45,7 @@ typedef struct {
     int             prev_index;
 
     AVFrame         buf_ptrs    [16];
+    ThreadFrame     tframes     [16];
     AVPicture       flipped_ptrs[16];
 
     DECLARE_ALIGNED(16, DCTELEM, dct_block)[64];
@@ -112,7 +113,9 @@ static const uint8_t col_zag[64] = {
 static av_cold int mimic_decode_init(AVCodecContext *avctx)
 {
     MimicContext *ctx = avctx->priv_data;
-    int ret;
+    int ret, i;
+
+    avctx->internal->allocate_progress = 1;
 
     ctx->prev_index = 0;
     ctx->cur_index  = 15;
@@ -125,12 +128,16 @@ static av_cold int mimic_decode_init(AVCodecContext 
*avctx)
     ff_dsputil_init(&ctx->dsp, avctx);
     ff_init_scantable(ctx->dsp.idct_permutation, &ctx->scantable, col_zag);
 
+    for (i = 0; i < FF_ARRAY_ELEMS(ctx->tframes); i++)
+        ctx->tframes[i].f = &ctx->buf_ptrs[i];
+
     return 0;
 }
 
 static int mimic_decode_update_thread_context(AVCodecContext *avctx, const 
AVCodecContext *avctx_from)
 {
     MimicContext *dst = avctx->priv_data, *src = avctx_from->priv_data;
+    int i;
 
     if (avctx == avctx_from)
         return 0;
@@ -140,8 +147,12 @@ static int 
mimic_decode_update_thread_context(AVCodecContext *avctx, const AVCod
 
     memcpy(dst->buf_ptrs, src->buf_ptrs, sizeof(src->buf_ptrs));
     memcpy(dst->flipped_ptrs, src->flipped_ptrs, sizeof(src->flipped_ptrs));
+    memcpy(dst->tframes, src->tframes, sizeof(src->tframes));
+
+    for (i = 0; i < FF_ARRAY_ELEMS(dst->tframes); i++)
+        dst->tframes[i].f = &dst->buf_ptrs[i];
 
-    memset(&dst->buf_ptrs[dst->cur_index], 0, sizeof(AVFrame));
+    memset(&dst->buf_ptrs[dst->cur_index], 0, sizeof(dst->buf_ptrs[0]));
 
     return 0;
 }
@@ -264,7 +275,7 @@ static int decode(MimicContext *ctx, int quality, int 
num_coeffs,
                         uint8_t *p           = 
ctx->flipped_ptrs[index].data[0];
 
                         if (index != ctx->cur_index && p) {
-                            ff_thread_await_progress(&ctx->buf_ptrs[index],
+                            ff_thread_await_progress(&ctx->tframes[index],
                                                      cur_row, 0);
                             p += src -
                                  
ctx->flipped_ptrs[ctx->prev_index].data[plane];
@@ -275,7 +286,7 @@ static int decode(MimicContext *ctx, int quality, int 
num_coeffs,
                         }
                     }
                 } else {
-                    ff_thread_await_progress(&ctx->buf_ptrs[ctx->prev_index],
+                    ff_thread_await_progress(&ctx->tframes[ctx->prev_index],
                                              cur_row, 0);
                     ctx->dsp.put_pixels_tab[1][0](dst, src, stride, 8);
                 }
@@ -285,7 +296,7 @@ static int decode(MimicContext *ctx, int quality, int 
num_coeffs,
             src += (stride - ctx->num_hblocks[plane]) << 3;
             dst += (stride - ctx->num_hblocks[plane]) << 3;
 
-            ff_thread_report_progress(&ctx->buf_ptrs[ctx->cur_index],
+            ff_thread_report_progress(&ctx->tframes[ctx->cur_index],
                                       cur_row++, 0);
         }
     }
@@ -362,10 +373,10 @@ static int mimic_decode_frame(AVCodecContext *avctx, void 
*data,
         return AVERROR_INVALIDDATA;
     }
 
-    ctx->buf_ptrs[ctx->cur_index].reference = 1;
     ctx->buf_ptrs[ctx->cur_index].pict_type = is_pframe ? AV_PICTURE_TYPE_P :
-                                                          AV_PICTURE_TYPE_I;
-    if ((res = ff_thread_get_buffer(avctx, &ctx->buf_ptrs[ctx->cur_index])) < 
0) {
+                                                            AV_PICTURE_TYPE_I;
+    if ((res = ff_thread_get_buffer(avctx, &ctx->tframes[ctx->cur_index],
+                                    AV_GET_BUFFER_FLAG_REF)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return res;
     }
@@ -388,15 +399,16 @@ static int mimic_decode_frame(AVCodecContext *avctx, void 
*data,
     init_get_bits(&ctx->gb, ctx->swap_buf, swap_buf_size << 3);
 
     res = decode(ctx, quality, num_coeffs, !is_pframe);
-    ff_thread_report_progress(&ctx->buf_ptrs[ctx->cur_index], INT_MAX, 0);
+    ff_thread_report_progress(&ctx->tframes[ctx->cur_index], INT_MAX, 0);
     if (res < 0) {
         if (!(avctx->active_thread_type & FF_THREAD_FRAME)) {
-            ff_thread_release_buffer(avctx, &ctx->buf_ptrs[ctx->cur_index]);
+            ff_thread_release_buffer(avctx, &ctx->tframes[ctx->cur_index]);
             return res;
         }
     }
 
-    *(AVFrame*)data = ctx->buf_ptrs[ctx->cur_index];
+    if ((res = av_frame_ref(data, &ctx->buf_ptrs[ctx->cur_index])) < 0)
+        return res;
     *got_frame      = 1;
 
     ctx->prev_index = ctx->next_prev_index;
@@ -404,7 +416,7 @@ static int mimic_decode_frame(AVCodecContext *avctx, void 
*data,
 
     /* Only release frames that aren't used for backreferences anymore */
     if (ctx->buf_ptrs[ctx->cur_index].data[0])
-        ff_thread_release_buffer(avctx, &ctx->buf_ptrs[ctx->cur_index]);
+        ff_thread_release_buffer(avctx, &ctx->tframes[ctx->cur_index]);
 
     return buf_size;
 }
@@ -421,12 +433,25 @@ static av_cold int mimic_decode_end(AVCodecContext *avctx)
 
     for (i = 0; i < 16; i++)
         if (ctx->buf_ptrs[i].data[0])
-            ff_thread_release_buffer(avctx, &ctx->buf_ptrs[i]);
+            ff_thread_release_buffer(avctx, &ctx->tframes[i]);
     ff_free_vlc(&ctx->vlc);
 
     return 0;
 }
 
+static av_cold int mimic_init_thread_copy(AVCodecContext *avctx)
+{
+    MimicContext *ctx = avctx->priv_data;
+    int i;
+
+    avctx->internal->allocate_progress = 1;
+
+    for (i = 0; i < FF_ARRAY_ELEMS(ctx->tframes); i++)
+        ctx->tframes[i].f = &ctx->buf_ptrs[i];
+
+    return 0;
+}
+
 AVCodec ff_mimic_decoder = {
     .name                  = "mimic",
     .type                  = AVMEDIA_TYPE_VIDEO,
@@ -437,5 +462,6 @@ AVCodec ff_mimic_decoder = {
     .decode                = mimic_decode_frame,
     .capabilities          = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
     .long_name             = NULL_IF_CONFIG_SMALL("Mimic"),
-    .update_thread_context = 
ONLY_IF_THREADS_ENABLED(mimic_decode_update_thread_context)
+    .update_thread_context = 
ONLY_IF_THREADS_ENABLED(mimic_decode_update_thread_context),
+    .init_thread_copy      = ONLY_IF_THREADS_ENABLED(mimic_init_thread_copy),
 };
-- 
1.7.10.4

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to