---
 libavcodec/h264.c        |  310 +++++++++++++++++++++++++++++-----------------
 libavcodec/h264.h        |    5 +
 libavcodec/h264_direct.c |    2 +-
 libavcodec/h264_refs.c   |   32 +++--
 4 files changed, 225 insertions(+), 124 deletions(-)

diff --git a/libavcodec/h264.c b/libavcodec/h264.c
index 339aecd..6f9263a 100644
--- a/libavcodec/h264.c
+++ b/libavcodec/h264.c
@@ -112,28 +112,25 @@ void ff_h264_draw_horiz_band(H264Context *h, int y, int 
height)
                        h->low_delay, h->mb_height * 16, h->mb_width * 16);
 }
 
-static void free_frame_buffer(H264Context *h, Picture *pic)
-{
-    ff_thread_release_buffer(h->avctx, &pic->f);
-    av_freep(&pic->f.hwaccel_picture_private);
-}
-
-static void free_picture(H264Context *h, Picture *pic)
+static void unref_picture(H264Context *h, Picture *pic)
 {
+    int off = offsetof(Picture, tf) + sizeof(pic->tf);
     int i;
 
-    if (pic->f.data[0])
-        free_frame_buffer(h, pic);
+    if (!pic->f.data[0])
+        return;
+
+    ff_thread_release_buffer(h->avctx, &pic->tf);
+    av_buffer_unref(&pic->hwaccel_priv_buf);
 
-    av_freep(&pic->qscale_table_base);
-    pic->qscale_table = NULL;
-    av_freep(&pic->mb_type_base);
-    pic->mb_type = NULL;
+    av_buffer_unref(&pic->qscale_table_buf);
+    av_buffer_unref(&pic->mb_type_buf);
     for (i = 0; i < 2; i++) {
-        av_freep(&pic->motion_val_base[i]);
-        av_freep(&pic->ref_index[i]);
-        pic->motion_val[i] = NULL;
+        av_buffer_unref(&pic->motion_val_buf[i]);
+        av_buffer_unref(&pic->ref_index_buf[i]);
     }
+
+    memset((uint8_t*)pic + off, 0, sizeof(*pic) - off);
 }
 
 static void release_unused_pictures(H264Context *h, int remove_current)
@@ -143,13 +140,72 @@ static void release_unused_pictures(H264Context *h, int 
remove_current)
     /* release non reference frames */
     for (i = 0; i < h->picture_count; i++) {
         if (h->DPB[i].f.data[0] && !h->DPB[i].reference &&
-            (!h->DPB[i].owner2 || h->DPB[i].owner2 == h) &&
             (remove_current || &h->DPB[i] != h->cur_pic_ptr)) {
-            free_frame_buffer(h, &h->DPB[i]);
+            unref_picture(h, &h->DPB[i]);
         }
     }
 }
 
+static int ref_picture(H264Context *h, Picture *dst, Picture *src)
+{
+    int ret, i;
+
+    av_assert0(!dst->f.buf[0]);
+    av_assert0(src->f.buf[0]);
+
+    src->tf.f = &src->f;
+    dst->tf.f = &dst->f;
+    ret = ff_thread_ref_frame(&dst->tf, &src->tf);
+    if (ret < 0)
+        goto fail;
+
+
+    dst->qscale_table_buf = av_buffer_ref(src->qscale_table_buf);
+    dst->mb_type_buf      = av_buffer_ref(src->mb_type_buf);
+    if (!dst->qscale_table_buf || !dst->mb_type_buf)
+        goto fail;
+    dst->qscale_table = src->qscale_table;
+    dst->mb_type      = src->mb_type;
+
+    for (i = 0; i < 2; i ++) {
+        dst->motion_val_buf[i] = av_buffer_ref(src->motion_val_buf[i]);
+        dst->ref_index_buf[i]  = av_buffer_ref(src->ref_index_buf[i]);
+        if (!dst->motion_val_buf[i] || !dst->ref_index_buf[i])
+            goto fail;
+        dst->motion_val[i] = src->motion_val[i];
+        dst->ref_index[i]  = src->ref_index[i];
+    }
+
+    if (src->hwaccel_picture_private) {
+        dst->hwaccel_priv_buf = av_buffer_ref(src->hwaccel_priv_buf);
+        if (!dst->hwaccel_priv_buf)
+            goto fail;
+        dst->hwaccel_picture_private = dst->hwaccel_priv_buf->data;
+    }
+
+    for (i = 0; i < 2; i++)
+        dst->field_poc[i] = src->field_poc[i];
+
+    memcpy(dst->ref_poc,   src->ref_poc,   sizeof(src->ref_poc));
+    memcpy(dst->ref_count, src->ref_count, sizeof(src->ref_count));
+
+    dst->poc                     = src->poc;
+    dst->frame_num               = src->frame_num;
+    dst->mmco_reset              = src->mmco_reset;
+    dst->pic_id                  = src->pic_id;
+    dst->long_ref                = src->long_ref;
+    dst->mbaff                   = src->mbaff;
+    dst->field_picture           = src->field_picture;
+    dst->needs_realloc           = src->needs_realloc;
+    dst->reference               = src->reference;
+
+    return 0;
+fail:
+    unref_picture(h, dst);
+    return ret;
+}
+
+
 static int alloc_scratch_buffers(H264Context *h, int linesize)
 {
     int alloc_size = FFALIGN(FFABS(linesize) + 32, 32);
@@ -171,60 +227,86 @@ static int alloc_scratch_buffers(H264Context *h, int 
linesize)
     return 0;
 }
 
-static int alloc_picture(H264Context *h, Picture *pic)
+static int init_table_pools(H264Context *h)
 {
     const int big_mb_num    = h->mb_stride * (h->mb_height + 1) + 1;
     const int mb_array_size = h->mb_stride * h->mb_height;
     const int b4_stride     = h->mb_width * 4 + 1;
     const int b4_array_size = b4_stride * h->mb_height * 4;
+
+    h->qscale_table_pool = av_buffer_pool_init(big_mb_num + h->mb_stride,
+                                               av_buffer_allocz);
+    h->mb_type_pool      = av_buffer_pool_init((big_mb_num + h->mb_stride) *
+                                               sizeof(uint32_t), 
av_buffer_allocz);
+    h->motion_val_pool = av_buffer_pool_init(2 * (b4_array_size + 4) *
+                                             sizeof(int16_t), 
av_buffer_allocz);
+    h->ref_index_pool  = av_buffer_pool_init(4 * mb_array_size, 
av_buffer_allocz);
+
+    if (!h->qscale_table_pool || !h->mb_type_pool || !h->motion_val_pool ||
+        !h->ref_index_pool) {
+        av_buffer_pool_uninit(&h->qscale_table_pool);
+        av_buffer_pool_uninit(&h->mb_type_pool);
+        av_buffer_pool_uninit(&h->motion_val_pool);
+        av_buffer_pool_uninit(&h->ref_index_pool);
+        return AVERROR(ENOMEM);
+    }
+
+    return 0;
+}
+
+static int alloc_picture(H264Context *h, Picture *pic)
+{
     int i, ret = 0;
 
     av_assert0(!pic->f.data[0]);
 
     if (h->avctx->hwaccel) {
         const AVHWAccel *hwaccel = h->avctx->hwaccel;
-        av_assert0(!pic->f.hwaccel_picture_private);
+        av_assert0(!pic->hwaccel_picture_private);
         if (hwaccel->priv_data_size) {
-            pic->f.hwaccel_picture_private = 
av_mallocz(hwaccel->priv_data_size);
-            if (!pic->f.hwaccel_picture_private)
+            pic->hwaccel_priv_buf = av_buffer_allocz(hwaccel->priv_data_size);
+            if (!pic->hwaccel_priv_buf)
                 return AVERROR(ENOMEM);
+            pic->hwaccel_picture_private = pic->hwaccel_priv_buf->data;
         }
     }
-    ret = ff_thread_get_buffer(h->avctx, &pic->f);
+    pic->tf.f = &pic->f;
+    ret = ff_thread_get_buffer(h->avctx, &pic->tf, pic->reference ?
+                                                   AV_GET_BUFFER_FLAG_REF : 0);
     if (ret < 0)
         goto fail;
 
     h->linesize   = pic->f.linesize[0];
     h->uvlinesize = pic->f.linesize[1];
 
-    if (pic->qscale_table == NULL) {
-        FF_ALLOCZ_OR_GOTO(h->avctx, pic->qscale_table_base,
-                          (big_mb_num + h->mb_stride) * sizeof(uint8_t),
-                          fail)
-        FF_ALLOCZ_OR_GOTO(h->avctx, pic->mb_type_base,
-                          (big_mb_num + h->mb_stride) * sizeof(uint32_t),
-                          fail)
-        pic->mb_type = pic->mb_type_base + 2 * h->mb_stride + 1;
-        pic->qscale_table = pic->qscale_table_base + 2 * h->mb_stride + 1;
+    if (!h->qscale_table_pool) {
+        ret = init_table_pools(h);
+        if (ret < 0)
+            goto fail;
+    }
 
-        for (i = 0; i < 2; i++) {
-            FF_ALLOCZ_OR_GOTO(h->avctx, pic->motion_val_base[i],
-                              2 * (b4_array_size + 4) * sizeof(int16_t),
-                              fail)
-            pic->motion_val[i] = pic->motion_val_base[i] + 4;
-            FF_ALLOCZ_OR_GOTO(h->avctx, pic->ref_index[i],
-                              4 * mb_array_size * sizeof(uint8_t), fail)
-        }
-        pic->f.motion_subsample_log2 = 2;
+    pic->qscale_table_buf = av_buffer_alloc_pool(h->qscale_table_pool);
+    pic->mb_type_buf      = av_buffer_alloc_pool(h->mb_type_pool);
+    if (!pic->qscale_table_buf || !pic->mb_type_buf)
+        goto fail;
 
-        pic->f.qstride = h->mb_stride;
-    }
+    pic->mb_type      = (uint32_t*)pic->mb_type_buf->data + 2 * h->mb_stride + 
1;
+    pic->qscale_table = pic->qscale_table_buf->data + 2 * h->mb_stride + 1;
 
-    pic->owner2 = h;
+    for (i = 0; i < 2; i++) {
+        pic->motion_val_buf[i] = av_buffer_alloc_pool(h->motion_val_pool);
+        pic->ref_index_buf[i]  = av_buffer_alloc_pool(h->ref_index_pool);
+        if (!pic->motion_val_buf[i] || !pic->ref_index_buf[i])
+            goto fail;
+
+        pic->motion_val[i] = (int16_t (*)[2])pic->motion_val_buf[i]->data + 4;
+        pic->ref_index[i]  = pic->ref_index_buf[i]->data;
+    }
+    pic->f.motion_subsample_log2 = 2;
 
     return 0;
 fail:
-    free_frame_buffer(h, pic);
+    unref_picture(h, pic);
     return (ret < 0) ? ret : AVERROR(ENOMEM);
 }
 
@@ -233,8 +315,7 @@ static inline int pic_is_unused(H264Context *h, Picture 
*pic)
     if (pic->f.data[0] == NULL)
         return 1;
     if (pic->needs_realloc && !(pic->reference & DELAYED_PIC_REF))
-        if (!pic->owner2 || pic->owner2 == h)
-            return 1;
+        return 1;
     return 0;
 }
 
@@ -242,17 +323,14 @@ static int find_unused_picture(H264Context *h)
 {
     int i;
 
-    for (i = h->picture_range_start; i < h->picture_range_end; i++) {
+    for (i = 0; i < h->picture_count; i++) {
         if (pic_is_unused(h, &h->DPB[i]))
             break;
     }
-    if (i == h->picture_range_end)
-        return AVERROR_INVALIDDATA;
 
     if (h->DPB[i].needs_realloc) {
         h->DPB[i].needs_realloc = 0;
-        free_picture(h, &h->DPB[i]);
-        avcodec_get_frame_defaults(&h->DPB[i].f);
+        unref_picture(h, &h->DPB[i]);
     }
 
     return i;
@@ -503,7 +581,7 @@ static inline void get_lowest_part_y(H264Context *h, int 
refs[2][48], int n,
         // Error resilience puts the current picture in the ref list.
         // Don't try to wait on these as it will cause a deadlock.
         // Fields can wait on each other, though.
-        if (ref->f.thread_opaque   != h->cur_pic.f.thread_opaque ||
+        if (ref->tf.progress->data   != h->cur_pic.tf.progress->data ||
             (ref->reference & 3) != h->picture_structure) {
             my = get_lowest_part_list_y(h, ref, n, height, y_offset, 0);
             if (refs[0][ref_n] < 0)
@@ -516,7 +594,7 @@ static inline void get_lowest_part_y(H264Context *h, int 
refs[2][48], int n,
         int ref_n    = h->ref_cache[1][scan8[n]];
         Picture *ref = &h->ref_list[1][ref_n];
 
-        if (ref->f.thread_opaque   != h->cur_pic.f.thread_opaque ||
+        if (ref->tf.progress->data != h->cur_pic.tf.progress->data ||
             (ref->reference & 3) != h->picture_structure) {
             my = get_lowest_part_list_y(h, ref, n, height, y_offset, 1);
             if (refs[1][ref_n] < 0)
@@ -614,24 +692,24 @@ static void await_references(H264Context *h)
                 nrefs[list]--;
 
                 if (!FIELD_PICTURE && ref_field_picture) { // frame 
referencing two fields
-                    ff_thread_await_progress(&ref_pic->f,
+                    ff_thread_await_progress(&ref_pic->tf,
                                              FFMIN((row >> 1) - !(row & 1),
                                                    pic_height - 1),
                                              1);
-                    ff_thread_await_progress(&ref_pic->f,
+                    ff_thread_await_progress(&ref_pic->tf,
                                              FFMIN((row >> 1), pic_height - 1),
                                              0);
                 } else if (FIELD_PICTURE && !ref_field_picture) { // field 
referencing one field of a frame
-                    ff_thread_await_progress(&ref_pic->f,
+                    ff_thread_await_progress(&ref_pic->tf,
                                              FFMIN(row * 2 + ref_field,
                                                    pic_height - 1),
                                              0);
                 } else if (FIELD_PICTURE) {
-                    ff_thread_await_progress(&ref_pic->f,
+                    ff_thread_await_progress(&ref_pic->tf,
                                              FFMIN(row, pic_height - 1),
                                              ref_field);
                 } else {
-                    ff_thread_await_progress(&ref_pic->f,
+                    ff_thread_await_progress(&ref_pic->tf,
                                              FFMIN(row, pic_height - 1),
                                              0);
                 }
@@ -951,9 +1029,14 @@ static void free_tables(H264Context *h, int free_rbsp)
     av_freep(&h->mb2b_xy);
     av_freep(&h->mb2br_xy);
 
+    av_buffer_pool_uninit(&h->qscale_table_pool);
+    av_buffer_pool_uninit(&h->mb_type_pool);
+    av_buffer_pool_uninit(&h->motion_val_pool);
+    av_buffer_pool_uninit(&h->ref_index_pool);
+
     if (free_rbsp) {
-        for (i = 0; i < h->picture_count && !h->avctx->internal->is_copy; i++)
-            free_picture(h, &h->DPB[i]);
+        for (i = 0; i < h->picture_count; i++)
+            unref_picture(h, &h->DPB[i]);
         av_freep(&h->DPB);
         h->picture_count = 0;
     } else if (h->DPB) {
@@ -1106,7 +1189,7 @@ int ff_h264_alloc_tables(H264Context *h)
         init_dequant_tables(h);
 
     if (!h->DPB) {
-        h->picture_count = MAX_PICTURE_COUNT * FFMAX(1, 
h->avctx->thread_count);
+        h->picture_count = MAX_PICTURE_COUNT;
         h->DPB = av_mallocz_array(h->picture_count, sizeof(*h->DPB));
         if (!h->DPB)
             return AVERROR(ENOMEM);
@@ -1306,8 +1389,6 @@ av_cold int ff_h264_decode_init(AVCodecContext *avctx)
     common_init(h);
 
     h->picture_structure   = PICT_FRAME;
-    h->picture_range_start = 0;
-    h->picture_range_end   = MAX_PICTURE_COUNT;
     h->slice_context_count = 1;
     h->workaround_bugs     = avctx->workaround_bugs;
     h->flags               = avctx->flags;
@@ -1347,6 +1428,8 @@ av_cold int ff_h264_decode_init(AVCodecContext *avctx)
         h->low_delay           = 0;
     }
 
+    avctx->internal->allocate_progress = 1;
+
     return 0;
 }
 
@@ -1398,6 +1481,8 @@ static int decode_init_thread_copy(AVCodecContext *avctx)
 
     h->context_initialized = 0;
 
+    avctx->internal->allocate_progress = 1;
+
     return 0;
 }
 
@@ -1414,7 +1499,7 @@ static int decode_update_thread_context(AVCodecContext 
*dst,
 {
     H264Context *h = dst->priv_data, *h1 = src->priv_data;
     int inited = h->context_initialized, err = 0;
-    int i;
+    int i, ret;
 
     if (dst == src || !h1->context_initialized)
         return 0;
@@ -1468,12 +1553,16 @@ static int decode_update_thread_context(AVCodecContext 
*dst,
         memset(&h->me, 0, sizeof(h->me));
         h->context_initialized = 0;
 
-        h->picture_range_start  += MAX_PICTURE_COUNT;
-        h->picture_range_end    += MAX_PICTURE_COUNT;
+        memset(&h->cur_pic, 0, sizeof(h->cur_pic));
+        avcodec_get_frame_defaults(&h->cur_pic.f);
+        h->cur_pic.tf.f = &h->cur_pic.f;
 
         h->avctx = dst;
         h->DPB   = NULL;
-        h->cur_pic.f.extended_data = h->cur_pic.f.data;
+        h->qscale_table_pool = NULL;
+        h->mb_type_pool = NULL;
+        h->ref_index_pool = NULL;
+        h->motion_val_pool = NULL;
 
         if (ff_h264_alloc_tables(h) < 0) {
             av_log(dst, AV_LOG_ERROR, "Could not allocate memory for h264\n");
@@ -1507,15 +1596,17 @@ static int decode_update_thread_context(AVCodecContext 
*dst,
     h->data_partitioning    = h1->data_partitioning;
     h->low_delay            = h1->low_delay;
 
-    memcpy(h->DPB, h1->DPB, h1->picture_count * sizeof(*h1->DPB));
-
-    // reset s->picture[].f.extended_data to s->picture[].f.data
-    for (i = 0; i < h->picture_count; i++)
-        h->DPB[i].f.extended_data = h->DPB[i].f.data;
+    for (i = 0; i < h->picture_count; i++) {
+        unref_picture(h, &h->DPB[i]);
+        if (h1->DPB[i].f.data[0] &&
+            (ret = ref_picture(h, &h->DPB[i], &h1->DPB[i])) < 0)
+            return ret;
+    }
 
     h->cur_pic_ptr     = REBASE_PICTURE(h1->cur_pic_ptr, h, h1);
-    h->cur_pic = h1->cur_pic;
-    h->cur_pic.f.extended_data = h->cur_pic.f.data;
+    unref_picture(h, &h->cur_pic);
+    if ((ret = ref_picture(h, &h->cur_pic, &h1->cur_pic)) < 0)
+        return ret;
 
     h->workaround_bugs = h1->workaround_bugs;
     h->low_delay       = h1->low_delay;
@@ -1613,8 +1704,9 @@ int ff_h264_frame_start(H264Context *h)
         return ret;
 
     h->cur_pic_ptr = pic;
-    h->cur_pic     = *h->cur_pic_ptr;
-    h->cur_pic.f.extended_data = h->cur_pic.f.data;
+    unref_picture(h, &h->cur_pic);
+    if ((ret = ref_picture(h, &h->cur_pic, h->cur_pic_ptr)) < 0)
+        return ret;
 
     ff_er_frame_start(&h->er);
 
@@ -1681,7 +1773,6 @@ static void decode_postinit(H264Context *h, int 
setup_finished)
     int i, pics, out_of_order, out_idx;
     int invalid = 0, cnt = 0;
 
-    h->cur_pic_ptr->f.qscale_type = FF_QSCALE_TYPE_H264;
     h->cur_pic_ptr->f.pict_type   = h->pict_type;
 
     if (h->next_output_pic)
@@ -1854,7 +1945,6 @@ static void decode_postinit(H264Context *h, int 
setup_finished)
         out->reference &= ~DELAYED_PIC_REF;
         // for frame threading, the owner must be the second field's thread or
         // else the first thread can release the picture and reuse it unsafely
-        out->owner2       = h;
         for (i = out_idx; h->delayed_pic[i]; i++)
             h->delayed_pic[i] = h->delayed_pic[i + 1];
     }
@@ -2477,11 +2567,10 @@ static void flush_dpb(AVCodecContext *avctx)
 
     flush_change(h);
 
-    for (i = 0; i < h->picture_count; i++) {
-        if (h->DPB[i].f.data[0])
-            free_frame_buffer(h, &h->DPB[i]);
-    }
+    for (i = 0; i < h->picture_count; i++)
+        unref_picture(h, &h->DPB[i]);
     h->cur_pic_ptr = NULL;
+    unref_picture(h, &h->cur_pic);
 
     h->mb_x = h->mb_y = 0;
 
@@ -2614,7 +2703,7 @@ static int field_end(H264Context *h, int in_setup)
     h->mb_y = 0;
 
     if (!in_setup && !h->droppable)
-        ff_thread_report_progress(&h->cur_pic_ptr->f, INT_MAX,
+        ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX,
                                   h->picture_structure == PICT_BOTTOM_FIELD);
 
     if (CONFIG_H264_VDPAU_DECODER &&
@@ -2974,9 +3063,8 @@ static int decode_slice_header(H264Context *h, 
H264Context *h0)
 
         h0->current_slice = 0;
         if (!h0->first_field) {
-            if (h->cur_pic_ptr && !h->droppable &&
-                h->cur_pic_ptr->owner2 == h) {
-                ff_thread_report_progress(&h->cur_pic_ptr->f, INT_MAX,
+            if (h->cur_pic_ptr && !h->droppable) {
+                ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX,
                                           h->picture_structure == 
PICT_BOTTOM_FIELD);
             }
             h->cur_pic_ptr = NULL;
@@ -3201,8 +3289,8 @@ static int decode_slice_header(H264Context *h, 
H264Context *h0)
             assert(h0->cur_pic_ptr->reference != DELAYED_PIC_REF);
 
             /* Mark old field/frame as completed */
-            if (!last_pic_droppable && h0->cur_pic_ptr->owner2 == h0) {
-                ff_thread_report_progress(&h0->cur_pic_ptr->f, INT_MAX,
+            if (!last_pic_droppable) {
+                ff_thread_report_progress(&h0->cur_pic_ptr->tf, INT_MAX,
                                           last_pic_structure == 
PICT_BOTTOM_FIELD);
             }
 
@@ -3211,7 +3299,7 @@ static int decode_slice_header(H264Context *h, 
H264Context *h0)
                 /* Previous field is unmatched. Don't display it, but let it
                  * remain for reference if marked as such. */
                 if (!last_pic_droppable && last_pic_structure != PICT_FRAME) {
-                    ff_thread_report_progress(&h0->cur_pic_ptr->f, INT_MAX,
+                    ff_thread_report_progress(&h0->cur_pic_ptr->tf, INT_MAX,
                                               last_pic_structure == 
PICT_TOP_FIELD);
                 }
             } else {
@@ -3221,7 +3309,7 @@ static int decode_slice_header(H264Context *h, 
H264Context *h0)
                      * pair. Throw away previous field except for reference
                      * purposes. */
                     if (!last_pic_droppable && last_pic_structure != 
PICT_FRAME) {
-                        ff_thread_report_progress(&h0->cur_pic_ptr->f, INT_MAX,
+                        ff_thread_report_progress(&h0->cur_pic_ptr->tf, 
INT_MAX,
                                                   last_pic_structure == 
PICT_TOP_FIELD);
                     }
                 } else {
@@ -3244,14 +3332,6 @@ static int decode_slice_header(H264Context *h, 
H264Context *h0)
                         h->droppable         = last_pic_droppable;
                         return AVERROR_PATCHWELCOME;
                     }
-
-                    /* Take ownership of this buffer. Note that if another 
thread owned
-                     * the first field of this buffer, we're not operating on 
that pointer,
-                     * so the original thread is still responsible for 
reporting progress
-                     * on that first field (or if that was us, we just did 
that above).
-                     * By taking ownership, we assign responsibility to 
ourselves to
-                     * report progress on the second field. */
-                    h0->cur_pic_ptr->owner2 = h0;
                 }
             }
         }
@@ -3266,8 +3346,8 @@ static int decode_slice_header(H264Context *h, 
H264Context *h0)
             h->prev_frame_num++;
             h->prev_frame_num %= 1 << h->sps.log2_max_frame_num;
             h->cur_pic_ptr->frame_num = h->prev_frame_num;
-            ff_thread_report_progress(&h->cur_pic_ptr->f, INT_MAX, 0);
-            ff_thread_report_progress(&h->cur_pic_ptr->f, INT_MAX, 1);
+            ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, 0);
+            ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, 1);
             if ((ret = ff_generate_sliding_window_mmcos(h, 1)) < 0 &&
                 h->avctx->err_recognition & AV_EF_EXPLODE)
                 return ret;
@@ -3561,16 +3641,16 @@ static int decode_slice_header(H264Context *h, 
H264Context *h0)
         int *ref2frm = h->ref2frm[h->slice_num & (MAX_SLICES - 1)][j];
         for (i = 0; i < 16; i++) {
             id_list[i] = 60;
-            if (h->ref_list[j][i].f.data[0]) {
+            if (i < h->ref_count[j] && h->ref_list[j][i].f.buf[0]) {
                 int k;
-                uint8_t *base = h->ref_list[j][i].f.base[0];
+                AVBuffer *buf = h->ref_list[j][i].f.buf[0]->buffer;
                 for (k = 0; k < h->short_ref_count; k++)
-                    if (h->short_ref[k]->f.base[0] == base) {
+                    if (h->short_ref[k]->f.buf[0]->buffer == buf) {
                         id_list[i] = k;
                         break;
                     }
                 for (k = 0; k < h->long_ref_count; k++)
-                    if (h->long_ref[k] && h->long_ref[k]->f.base[0] == base) {
+                    if (h->long_ref[k] && h->long_ref[k]->f.buf[0]->buffer == 
buf) {
                         id_list[i] = h->short_ref_count + k;
                         break;
                     }
@@ -3976,7 +4056,7 @@ static void decode_finish_row(H264Context *h)
     if (h->droppable)
         return;
 
-    ff_thread_report_progress(&h->cur_pic_ptr->f, top + height - 1,
+    ff_thread_report_progress(&h->cur_pic_ptr->tf, top + height - 1,
                               h->picture_structure == PICT_BOTTOM_FIELD);
 }
 
@@ -4475,9 +4555,8 @@ again:
 
 end:
     /* clean up */
-    if (h->cur_pic_ptr && h->cur_pic_ptr->owner2 == h &&
-        !h->droppable) {
-        ff_thread_report_progress(&h->cur_pic_ptr->f, INT_MAX,
+    if (h->cur_pic_ptr && !h->droppable) {
+        ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX,
                                   h->picture_structure == PICT_BOTTOM_FIELD);
     }
 
@@ -4505,6 +4584,7 @@ static int decode_frame(AVCodecContext *avctx, void *data,
     H264Context *h     = avctx->priv_data;
     AVFrame *pict      = data;
     int buf_index      = 0;
+    int ret;
 
     h->flags  = avctx->flags;
 
@@ -4533,8 +4613,9 @@ out:
             h->delayed_pic[i] = h->delayed_pic[i + 1];
 
         if (out) {
+            if ((ret = av_frame_ref(pict, &out->f)) < 0)
+                return ret;
             *got_frame = 1;
-            *pict      = out->f;
         }
 
         return buf_index;
@@ -4568,8 +4649,9 @@ out:
             /* Wait for second field. */
             *got_frame = 0;
         } else {
+            if ((ret = av_frame_ref(pict, &h->next_output_pic->f)) < 0)
+                return ret;
             *got_frame = 1;
-            *pict      = h->next_output_pic->f;
         }
     }
 
@@ -4598,13 +4680,15 @@ static av_cold int h264_decode_end(AVCodecContext 
*avctx)
 
     ff_h264_free_context(h);
 
-    if (h->DPB && !h->avctx->internal->is_copy) {
+    if (h->DPB) {
         for (i = 0; i < h->picture_count; i++) {
-            free_picture(h, &h->DPB[i]);
+            unref_picture(h, &h->DPB[i]);
         }
     }
     av_freep(&h->DPB);
 
+    unref_picture(h, &h->cur_pic);
+
     return 0;
 }
 
diff --git a/libavcodec/h264.h b/libavcodec/h264.h
index 0a8d259..0f7c1f1 100644
--- a/libavcodec/h264.h
+++ b/libavcodec/h264.h
@@ -621,6 +621,11 @@ typedef struct H264Context {
     uint8_t *bipred_scratchpad;
     uint8_t *edge_emu_buffer;
     int16_t *dc_val_base;
+
+    AVBufferPool *qscale_table_pool;
+    AVBufferPool *mb_type_pool;
+    AVBufferPool *motion_val_pool;
+    AVBufferPool *ref_index_pool;
 } H264Context;
 
 extern const uint8_t ff_h264_chroma_qp[3][QP_MAX_NUM + 1]; ///< One chroma qp 
table for each supported bit depth (8, 9, 10).
diff --git a/libavcodec/h264_direct.c b/libavcodec/h264_direct.c
index b22f321..6c2f175 100644
--- a/libavcodec/h264_direct.c
+++ b/libavcodec/h264_direct.c
@@ -154,7 +154,7 @@ static void await_reference_mb_row(H264Context * const h, 
Picture *ref, int mb_y
     //FIXME it can be safe to access mb stuff
     //even if pixels aren't deblocked yet
 
-    ff_thread_await_progress(&ref->f,
+    ff_thread_await_progress(&ref->tf,
                              FFMIN(16 * mb_y >> ref_field_picture, ref_height 
- 1),
                              ref_field_picture && ref_field);
 }
diff --git a/libavcodec/h264_refs.c b/libavcodec/h264_refs.c
index 95b4f83..a283a24 100644
--- a/libavcodec/h264_refs.c
+++ b/libavcodec/h264_refs.c
@@ -34,6 +34,13 @@
 //#undef NDEBUG
 #include <assert.h>
 
+#define COPY_PICTURE(dst, src) \
+do {\
+    *(dst) = *(src);\
+    (dst)->f.extended_data = (dst)->f.data;\
+    (dst)->tf.f = &(dst)->f;\
+} while (0)
+
 
 static void pic_as_field(Picture *pic, const int parity){
     int i;
@@ -51,7 +58,7 @@ static int split_field_copy(Picture *dest, Picture *src,
     int match = !!(src->reference & parity);
 
     if (match) {
-        *dest = *src;
+        COPY_PICTURE(dest, src);
         if(parity != PICT_FRAME){
             pic_as_field(dest, parity);
             dest->pic_id *= 2;
@@ -133,8 +140,12 @@ int ff_h264_fill_default_ref_list(H264Context *h){
 
         if(lens[0] == lens[1] && lens[1] > 1){
             for (i = 0; h->default_ref_list[0][i].f.data[0] == 
h->default_ref_list[1][i].f.data[0] && i < lens[0]; i++);
-            if(i == lens[0])
-                FFSWAP(Picture, h->default_ref_list[1][0], 
h->default_ref_list[1][1]);
+            if (i == lens[0]) {
+                Picture tmp;
+                COPY_PICTURE(&tmp, &h->default_ref_list[1][0]);
+                COPY_PICTURE(&h->default_ref_list[1][0], 
&h->default_ref_list[1][1]);
+                COPY_PICTURE(&h->default_ref_list[1][1], &tmp);
+            }
         }
     }else{
         len = build_def_list(h->default_ref_list[0]    , h->short_ref, 
h->short_ref_count, 0, h->picture_structure);
@@ -182,13 +193,14 @@ static int pic_num_extract(H264Context *h, int pic_num, 
int *structure){
 }
 
 int ff_h264_decode_ref_pic_list_reordering(H264Context *h){
-    int list, index, pic_structure;
+    int list, index, pic_structure, i;
 
     print_short_term(h);
     print_long_term(h);
 
     for(list=0; list<h->list_count; list++){
-        memcpy(h->ref_list[list], h->default_ref_list[list], 
sizeof(Picture)*h->ref_count[list]);
+        for (i = 0; i < h->ref_count[list]; i++)
+            COPY_PICTURE(&h->ref_list[list][i], &h->default_ref_list[list][i]);
 
         if(get_bits1(&h->gb)){
             int pred= h->curr_pic_num;
@@ -265,9 +277,9 @@ int ff_h264_decode_ref_pic_list_reordering(H264Context *h){
                                 break;
                         }
                         for(; i > index; i--){
-                            h->ref_list[list][i]= h->ref_list[list][i-1];
+                            COPY_PICTURE(&h->ref_list[list][i], 
&h->ref_list[list][i - 1]);
                         }
-                        h->ref_list[list][index]= *ref;
+                        COPY_PICTURE(&h->ref_list[list][index], ref);
                         if (FIELD_PICTURE){
                             pic_as_field(&h->ref_list[list][index], 
pic_structure);
                         }
@@ -284,7 +296,7 @@ int ff_h264_decode_ref_pic_list_reordering(H264Context *h){
             if (!h->ref_list[list][index].f.data[0]) {
                 av_log(h->avctx, AV_LOG_ERROR, "Missing reference picture\n");
                 if (h->default_ref_list[list][0].f.data[0])
-                    h->ref_list[list][index]= h->default_ref_list[list][0];
+                    COPY_PICTURE(&h->ref_list[list][index], 
&h->default_ref_list[list][0]);
                 else
                     return -1;
             }
@@ -300,12 +312,12 @@ void ff_h264_fill_mbaff_ref_list(H264Context *h){
         for(i=0; i<h->ref_count[list]; i++){
             Picture *frame = &h->ref_list[list][i];
             Picture *field = &h->ref_list[list][16+2*i];
-            field[0] = *frame;
+            COPY_PICTURE(field, frame);
             for(j=0; j<3; j++)
                 field[0].f.linesize[j] <<= 1;
             field[0].reference = PICT_TOP_FIELD;
             field[0].poc= field[0].field_poc[0];
-            field[1] = field[0];
+            COPY_PICTURE(field + 1, field);
             for(j=0; j<3; j++)
                 field[1].f.data[j] += frame->f.linesize[j];
             field[1].reference = PICT_BOTTOM_FIELD;
-- 
1.7.10.4

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

Reply via email to