On 2013-01-08 15:38:15 +0100, Anton Khirnov wrote:
> ---
>  libavcodec/vp8.c |  204 
> ++++++++++++++++++++++++++++++------------------------
>  libavcodec/vp8.h |   27 ++++----
>  2 files changed, 128 insertions(+), 103 deletions(-)
> 
> diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c
> index 3b8f7d2..9e40ca8 100644
> --- a/libavcodec/vp8.c
> +++ b/libavcodec/vp8.c
> @@ -52,64 +52,61 @@ static void free_buffers(VP8Context *s)
>      s->macroblocks = NULL;
>  }
>  
> -static int vp8_alloc_frame(VP8Context *s, AVFrame *f)
> +static int vp8_alloc_frame(VP8Context *s, VP8Frame *f, int ref)
>  {
>      int ret;
> -    if ((ret = ff_thread_get_buffer(s->avctx, f)) < 0)
> +    if ((ret = ff_thread_get_buffer(s->avctx, &f->tf,
> +                                    ref ? AV_GET_BUFFER_FLAG_REF : 0)) < 0)
>          return ret;
> -    if (s->num_maps_to_be_freed && !s->maps_are_invalid) {
> -        f->ref_index[0] = s->segmentation_maps[--s->num_maps_to_be_freed];
> -    } else if (!(f->ref_index[0] = av_mallocz(s->mb_width * s->mb_height))) {
> -        ff_thread_release_buffer(s->avctx, f);
> +    if (!(f->seg_map = av_buffer_alloc(s->mb_width * s->mb_height))) {
> +        ff_thread_release_buffer(s->avctx, &f->tf);
>          return AVERROR(ENOMEM);
>      }
> +    memset(f->seg_map->data, 0, f->seg_map->size);
> +
>      return 0;
>  }
>  
> -static void vp8_release_frame(VP8Context *s, AVFrame *f, int 
> prefer_delayed_free, int can_direct_free)
> +static void vp8_release_frame(VP8Context *s, VP8Frame *f)
>  {
> -    if (f->ref_index[0]) {
> -        if (prefer_delayed_free) {
> -            /* Upon a size change, we want to free the maps but other 
> threads may still
> -             * be using them, so queue them. Upon a seek, all threads are 
> inactive so
> -             * we want to cache one to prevent re-allocation in the next 
> decoding
> -             * iteration, but the rest we can free directly. */
> -            int max_queued_maps = can_direct_free ? 1 : 
> FF_ARRAY_ELEMS(s->segmentation_maps);
> -            if (s->num_maps_to_be_freed < max_queued_maps) {
> -                s->segmentation_maps[s->num_maps_to_be_freed++] = 
> f->ref_index[0];
> -            } else if (can_direct_free) /* vp8_decode_flush(), but our queue 
> is full */ {
> -                av_free(f->ref_index[0]);
> -            } /* else: MEMLEAK (should never happen, but better that than 
> crash) */
> -            f->ref_index[0] = NULL;
> -        } else /* vp8_decode_free() */ {
> -            av_free(f->ref_index[0]);
> -        }
> +    av_buffer_unref(&f->seg_map);
> +    ff_thread_release_buffer(s->avctx, &f->tf);
> +}
> +
> +static int vp8_ref_frame(VP8Context *s, VP8Frame *dst, VP8Frame *src)
> +{
> +    int ret;
> +
> +    vp8_release_frame(s, dst);
> +
> +    if ((ret = ff_thread_ref_frame(&dst->tf, &src->tf)) < 0)
> +        return ret;
> +    if (src->seg_map &&
> +        !(dst->seg_map = av_buffer_ref(src->seg_map))) {
> +        vp8_release_frame(s, dst);
> +        return AVERROR(ENOMEM);
>      }
> -    ff_thread_release_buffer(s->avctx, f);
> +
> +    return 0;
>  }
>  
> -static void vp8_decode_flush_impl(AVCodecContext *avctx,
> -                                  int prefer_delayed_free, int 
> can_direct_free, int free_mem)
> +
> +static void vp8_decode_flush_impl(AVCodecContext *avctx, int free_mem)
>  {
>      VP8Context *s = avctx->priv_data;
>      int i;
>  
> -    if (!avctx->internal->is_copy) {
> -        for (i = 0; i < 5; i++)
> -            if (s->frames[i].data[0])
> -                vp8_release_frame(s, &s->frames[i], prefer_delayed_free, 
> can_direct_free);
> -    }
> +    for (i = 0; i < FF_ARRAY_ELEMS(s->frames); i++)
> +        vp8_release_frame(s, &s->frames[i]);
>      memset(s->framep, 0, sizeof(s->framep));
>  
> -    if (free_mem) {
> +    if (free_mem)
>          free_buffers(s);
> -        s->maps_are_invalid = 1;
> -    }
>  }
>  
>  static void vp8_decode_flush(AVCodecContext *avctx)
>  {
> -    vp8_decode_flush_impl(avctx, 1, 1, 0);
> +    vp8_decode_flush_impl(avctx, 0);
>  }
>  
>  static int update_dimensions(VP8Context *s, int width, int height)
> @@ -122,7 +119,7 @@ static int update_dimensions(VP8Context *s, int width, 
> int height)
>          if (av_image_check_size(width, height, 0, s->avctx))
>              return AVERROR_INVALIDDATA;
>  
> -        vp8_decode_flush_impl(s->avctx, 1, 0, 1);
> +        vp8_decode_flush_impl(s->avctx, 1);
>  
>          avcodec_set_dimensions(s->avctx, width, height);
>      }
> @@ -1178,12 +1175,12 @@ static const uint8_t subpel_idx[3][8] = {
>   */
>  static av_always_inline
>  void vp8_mc_luma(VP8Context *s, VP8ThreadData *td, uint8_t *dst,
> -                 AVFrame *ref, const VP56mv *mv,
> +                 ThreadFrame *ref, const VP56mv *mv,
>                   int x_off, int y_off, int block_w, int block_h,
>                   int width, int height, int linesize,
>                   vp8_mc_func mc_func[3][3])
>  {
> -    uint8_t *src = ref->data[0];
> +    uint8_t *src = ref->f->data[0];
>  
>      if (AV_RN32A(mv)) {
>  
> @@ -1229,11 +1226,11 @@ void vp8_mc_luma(VP8Context *s, VP8ThreadData *td, 
> uint8_t *dst,
>   */
>  static av_always_inline
>  void vp8_mc_chroma(VP8Context *s, VP8ThreadData *td, uint8_t *dst1, uint8_t 
> *dst2,
> -                   AVFrame *ref, const VP56mv *mv, int x_off, int y_off,
> +                   ThreadFrame *ref, const VP56mv *mv, int x_off, int y_off,
>                     int block_w, int block_h, int width, int height, int 
> linesize,
>                     vp8_mc_func mc_func[3][3])
>  {
> -    uint8_t *src1 = ref->data[1], *src2 = ref->data[2];
> +    uint8_t *src1 = ref->f->data[1], *src2 = ref->f->data[2];
>  
>      if (AV_RN32A(mv)) {
>          int mx = mv->x&7, mx_idx = subpel_idx[0][mx];
> @@ -1272,7 +1269,7 @@ void vp8_mc_chroma(VP8Context *s, VP8ThreadData *td, 
> uint8_t *dst1, uint8_t *dst
>  
>  static av_always_inline
>  void vp8_mc_part(VP8Context *s, VP8ThreadData *td, uint8_t *dst[3],
> -                 AVFrame *ref_frame, int x_off, int y_off,
> +                 ThreadFrame *ref_frame, int x_off, int y_off,
>                   int bx_off, int by_off,
>                   int block_w, int block_h,
>                   int width, int height, VP56mv *mv)
> @@ -1310,7 +1307,7 @@ static av_always_inline void prefetch_motion(VP8Context 
> *s, VP8Macroblock *mb, i
>          int x_off = mb_x << 4, y_off = mb_y << 4;
>          int mx = (mb->mv.x>>2) + x_off + 8;
>          int my = (mb->mv.y>>2) + y_off;
> -        uint8_t **src= s->framep[ref]->data;
> +        uint8_t **src= s->framep[ref]->tf.f->data;
>          int off= mx + (my + (mb_x&3)*4)*s->linesize + 64;
>          /* For threading, a ff_thread_await_progress here might be useful, 
> but
>           * it actually slows down the decoder. Since a bad prefetch doesn't
> @@ -1330,7 +1327,7 @@ void inter_predict(VP8Context *s, VP8ThreadData *td, 
> uint8_t *dst[3],
>  {
>      int x_off = mb_x << 4, y_off = mb_y << 4;
>      int width = 16*s->mb_width, height = 16*s->mb_height;
> -    AVFrame *ref = s->framep[mb->ref_frame];
> +    ThreadFrame *ref = &s->framep[mb->ref_frame]->tf;
>      VP56mv *bmv = mb->bmv;
>  
>      switch (mb->partitioning) {
> @@ -1589,17 +1586,9 @@ static av_always_inline void 
> filter_mb_simple(VP8Context *s, uint8_t *dst, VP8Fi
>      }
>  }
>  
> -static void release_queued_segmaps(VP8Context *s, int is_close)
> -{
> -    int leave_behind = is_close ? 0 : !s->maps_are_invalid;
> -    while (s->num_maps_to_be_freed > leave_behind)
> -        av_freep(&s->segmentation_maps[--s->num_maps_to_be_freed]);
> -    s->maps_are_invalid = 0;
> -}
> -
>  #define MARGIN (16 << 2)
> -static void vp8_decode_mv_mb_modes(AVCodecContext *avctx, AVFrame *curframe,
> -                                   AVFrame *prev_frame)
> +static void vp8_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *curframe,
> +                                   VP8Frame *prev_frame)
>  {
>      VP8Context *s = avctx->priv_data;
>      int mb_x, mb_y;
> @@ -1617,8 +1606,9 @@ static void vp8_decode_mv_mb_modes(AVCodecContext 
> *avctx, AVFrame *curframe,
>          for (mb_x = 0; mb_x < s->mb_width; mb_x++, mb_xy++, mb++) {
>              if (mb_y == 0)
>                  AV_WN32A((mb-s->mb_width-1)->intra4x4_pred_mode_top, 
> DC_PRED*0x01010101);
> -            decode_mb_mode(s, mb, mb_x, mb_y, curframe->ref_index[0] + mb_xy,
> -                           prev_frame && prev_frame->ref_index[0] ? 
> prev_frame->ref_index[0] + mb_xy : NULL, 1);
> +            decode_mb_mode(s, mb, mb_x, mb_y, curframe->seg_map->data + 
> mb_xy,
> +                           prev_frame && prev_frame->seg_map ?
> +                           prev_frame->seg_map->data + mb_xy : NULL, 1);
>              s->mv_min.x -= 64;
>              s->mv_max.x -= 64;
>          }
> @@ -1672,13 +1662,13 @@ static void 
> vp8_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata,
>      int mb_y = td->thread_mb_pos>>16;
>      int i, y, mb_x, mb_xy = mb_y*s->mb_width;
>      int num_jobs = s->num_jobs;
> -    AVFrame *curframe = s->curframe, *prev_frame = s->prev_frame;
> +    VP8Frame *curframe = s->curframe, *prev_frame = s->prev_frame;
>      VP56RangeCoder *c = &s->coeff_partition[mb_y & 
> (s->num_coeff_partitions-1)];
>      VP8Macroblock *mb;
>      uint8_t *dst[3] = {
> -        curframe->data[0] + 16*mb_y*s->linesize,
> -        curframe->data[1] +  8*mb_y*s->uvlinesize,
> -        curframe->data[2] +  8*mb_y*s->uvlinesize
> +        curframe->tf.f->data[0] + 16*mb_y*s->linesize,
> +        curframe->tf.f->data[1] +  8*mb_y*s->uvlinesize,
> +        curframe->tf.f->data[2] +  8*mb_y*s->uvlinesize
>      };
>      if (mb_y == 0) prev_td = td;
>      else           prev_td = &s->thread_data[(jobnr + num_jobs - 
> 1)%num_jobs];
> @@ -1697,7 +1687,7 @@ static void vp8_decode_mb_row_no_filter(AVCodecContext 
> *avctx, void *tdata,
>      if (!(avctx->flags & CODEC_FLAG_EMU_EDGE)) {
>          for (i = 0; i < 3; i++)
>              for (y = 0; y < 16>>!!i; y++)
> -                dst[i][y*curframe->linesize[i]-1] = 129;
> +                dst[i][y*curframe->tf.f->linesize[i]-1] = 129;
>          if (mb_y == 1) {
>              s->top_border[0][15] = s->top_border[0][23] = 
> s->top_border[0][31] = 129;
>          }
> @@ -1720,8 +1710,9 @@ static void vp8_decode_mb_row_no_filter(AVCodecContext 
> *avctx, void *tdata,
>          s->vdsp.prefetch(dst[1] + (mb_x&7)*s->uvlinesize + 64, dst[2] - 
> dst[1], 2);
>  
>          if (!s->mb_layout)
> -            decode_mb_mode(s, mb, mb_x, mb_y, curframe->ref_index[0] + mb_xy,
> -                           prev_frame && prev_frame->ref_index[0] ? 
> prev_frame->ref_index[0] + mb_xy : NULL, 0);
> +            decode_mb_mode(s, mb, mb_x, mb_y, curframe->seg_map->data + 
> mb_xy,
> +                           prev_frame && prev_frame->seg_map ?
> +                           prev_frame->seg_map->data + mb_xy : NULL, 0);
>  
>          prefetch_motion(s, mb, mb_x, mb_y, mb_xy, VP56_FRAME_PREVIOUS);
>  
> @@ -1780,7 +1771,7 @@ static void vp8_filter_mb_row(AVCodecContext *avctx, 
> void *tdata,
>      VP8Context *s = avctx->priv_data;
>      VP8ThreadData *td = &s->thread_data[threadnr];
>      int mb_x, mb_y = td->thread_mb_pos>>16, num_jobs = s->num_jobs;
> -    AVFrame *curframe = s->curframe;
> +    AVFrame *curframe = s->curframe->tf.f;
>      VP8Macroblock *mb;
>      VP8ThreadData *prev_td, *next_td;
>      uint8_t *dst[3] = {
> @@ -1834,7 +1825,7 @@ static int vp8_decode_mb_row_sliced(AVCodecContext 
> *avctx, void *tdata,
>      VP8Context *s = avctx->priv_data;
>      VP8ThreadData *td = &s->thread_data[jobnr];
>      VP8ThreadData *next_td = NULL, *prev_td = NULL;
> -    AVFrame *curframe = s->curframe;
> +    VP8Frame *curframe = s->curframe;
>      int mb_y, num_jobs = s->num_jobs;
>      td->thread_nr = threadnr;
>      for (mb_y = jobnr; mb_y < s->mb_height; mb_y += num_jobs) {
> @@ -1849,7 +1840,7 @@ static int vp8_decode_mb_row_sliced(AVCodecContext 
> *avctx, void *tdata,
>          s->mv_max.y -= 64;
>  
>          if (avctx->active_thread_type == FF_THREAD_FRAME)
> -            ff_thread_report_progress(curframe, mb_y, 0);
> +            ff_thread_report_progress(&curframe->tf, mb_y, 0);
>      }
>  
>      return 0;
> @@ -1861,9 +1852,7 @@ static int vp8_decode_frame(AVCodecContext *avctx, void 
> *data, int *got_frame,
>      VP8Context *s = avctx->priv_data;
>      int ret, i, referenced, num_jobs;
>      enum AVDiscard skip_thresh;
> -    AVFrame *av_uninit(curframe), *prev_frame;
> -
> -    release_queued_segmaps(s, 0);
> +    VP8Frame *av_uninit(curframe), *prev_frame;
>  
>      if ((ret = decode_frame_header(s, avpkt->data, avpkt->size)) < 0)
>          goto err;
> @@ -1885,12 +1874,12 @@ static int vp8_decode_frame(AVCodecContext *avctx, 
> void *data, int *got_frame,
>  
>      // release no longer referenced frames
>      for (i = 0; i < 5; i++)
> -        if (s->frames[i].data[0] &&
> +        if (s->frames[i].tf.f->data[0] &&
>              &s->frames[i] != prev_frame &&
>              &s->frames[i] != s->framep[VP56_FRAME_PREVIOUS] &&
>              &s->frames[i] != s->framep[VP56_FRAME_GOLDEN] &&
>              &s->frames[i] != s->framep[VP56_FRAME_GOLDEN2])
> -            vp8_release_frame(s, &s->frames[i], 1, 0);
> +            vp8_release_frame(s, &s->frames[i]);
>  
>      // find a free buffer
>      for (i = 0; i < 5; i++)
> @@ -1905,8 +1894,8 @@ static int vp8_decode_frame(AVCodecContext *avctx, void 
> *data, int *got_frame,
>          av_log(avctx, AV_LOG_FATAL, "Ran out of free frames!\n");
>          abort();
>      }
> -    if (curframe->data[0])
> -        vp8_release_frame(s, curframe, 1, 0);
> +    if (curframe->tf.f->data[0])
> +        vp8_release_frame(s, curframe);
>  
>      // Given that arithmetic probabilities are updated every frame, it's 
> quite likely
>      // that the values we have on a random interframe are complete junk if 
> we didn't
> @@ -1919,10 +1908,9 @@ static int vp8_decode_frame(AVCodecContext *avctx, 
> void *data, int *got_frame,
>          goto err;
>      }
>  
> -    curframe->key_frame = s->keyframe;
> -    curframe->pict_type = s->keyframe ? AV_PICTURE_TYPE_I : 
> AV_PICTURE_TYPE_P;
> -    curframe->reference = referenced ? 3 : 0;
> -    if ((ret = vp8_alloc_frame(s, curframe))) {
> +    curframe->tf.f->key_frame = s->keyframe;
> +    curframe->tf.f->pict_type = s->keyframe ? AV_PICTURE_TYPE_I : 
> AV_PICTURE_TYPE_P;
> +    if ((ret = vp8_alloc_frame(s, curframe, referenced))) {
>          av_log(avctx, AV_LOG_ERROR, "get_buffer() failed!\n");
>          goto err;
>      }
> @@ -1947,8 +1935,8 @@ static int vp8_decode_frame(AVCodecContext *avctx, void 
> *data, int *got_frame,
>  
>      ff_thread_finish_setup(avctx);
>  
> -    s->linesize   = curframe->linesize[0];
> -    s->uvlinesize = curframe->linesize[1];
> +    s->linesize   = curframe->tf.f->linesize[0];
> +    s->uvlinesize = curframe->tf.f->linesize[1];
>  
>      if (!s->thread_data[0].edge_emu_buffer)
>          for (i = 0; i < MAX_THREADS; i++)
> @@ -1973,7 +1961,7 @@ static int vp8_decode_frame(AVCodecContext *avctx, void 
> *data, int *got_frame,
>      // Make sure the previous frame has read its segmentation map,
>      // if we re-use the same map.
>      if (prev_frame && s->segmentation.enabled && !s->segmentation.update_map)
> -        ff_thread_await_progress(prev_frame, 1, 0);
> +        ff_thread_await_progress(&prev_frame->tf, 1, 0);
>  
>      if (s->mb_layout == 1)
>          vp8_decode_mv_mb_modes(avctx, curframe, prev_frame);
> @@ -1993,7 +1981,7 @@ static int vp8_decode_frame(AVCodecContext *avctx, void 
> *data, int *got_frame,
>      }
>      avctx->execute2(avctx, vp8_decode_mb_row_sliced, s->thread_data, NULL, 
> num_jobs);
>  
> -    ff_thread_report_progress(curframe, INT_MAX, 0);
> +    ff_thread_report_progress(&curframe->tf, INT_MAX, 0);
>      memcpy(&s->framep[0], &s->next_framep[0], sizeof(s->framep[0]) * 4);
>  
>  skip_decode:
> @@ -2003,7 +1991,8 @@ skip_decode:
>          s->prob[0] = s->prob[1];
>  
>      if (!s->invisible) {
> -        *(AVFrame*)data = *curframe;
> +        if ((ret = av_frame_ref(data, curframe->tf.f)) < 0)
> +            return ret;
>          *got_frame      = 1;
>      }
>  
> @@ -2013,32 +2002,62 @@ err:
>      return ret;
>  }
>  
> +static av_cold int vp8_decode_free(AVCodecContext *avctx)
> +{
> +    VP8Context *s = avctx->priv_data;
> +    int i;
> +
> +    vp8_decode_flush_impl(avctx, 1);
> +    for (i = 0; i < FF_ARRAY_ELEMS(s->frames); i++)
> +        av_frame_free(&s->frames[i].tf.f);
> +
> +    return 0;
> +}
> +
> +static av_cold int vp8_init_frames(VP8Context *s)
> +{
> +    int i;
> +    for (i = 0; i < FF_ARRAY_ELEMS(s->frames); i++) {
> +        s->frames[i].tf.f = av_frame_alloc();
> +        if (!s->frames[i].tf.f)
> +            return AVERROR(ENOMEM);
> +    }
> +    return 0;
> +}
> +
>  static av_cold int vp8_decode_init(AVCodecContext *avctx)
>  {
>      VP8Context *s = avctx->priv_data;
> +    int ret;
>  
>      s->avctx = avctx;
>      avctx->pix_fmt = AV_PIX_FMT_YUV420P;
> +    avctx->internal->allocate_progress = 1;
>  
>      ff_videodsp_init(&s->vdsp, 8);
>      ff_h264_pred_init(&s->hpc, AV_CODEC_ID_VP8, 8, 1);
>      ff_vp8dsp_init(&s->vp8dsp);
>  
> -    return 0;
> -}
> +    if ((ret = vp8_init_frames(s)) < 0) {
> +        vp8_decode_free(avctx);
> +        return ret;
> +    }
>  
> -static av_cold int vp8_decode_free(AVCodecContext *avctx)
> -{
> -    vp8_decode_flush_impl(avctx, 0, 1, 1);
> -    release_queued_segmaps(avctx->priv_data, 1);
>      return 0;
>  }
>  
>  static av_cold int vp8_decode_init_thread_copy(AVCodecContext *avctx)
>  {
>      VP8Context *s = avctx->priv_data;
> +    int ret;
>  
>      s->avctx = avctx;
> +    avctx->internal->allocate_progress = 1;
> +
> +    if ((ret = vp8_init_frames(s)) < 0) {
> +        vp8_decode_free(avctx);
> +        return ret;
> +    }
>  
>      return 0;
>  }
> @@ -2049,11 +2068,11 @@ static av_cold int 
> vp8_decode_init_thread_copy(AVCodecContext *avctx)
>  static int vp8_decode_update_thread_context(AVCodecContext *dst, const 
> AVCodecContext *src)
>  {
>      VP8Context *s = dst->priv_data, *s_src = src->priv_data;
> +    int i;
>  
>      if (s->macroblocks_base &&
>          (s_src->mb_width != s->mb_width || s_src->mb_height != 
> s->mb_height)) {
>          free_buffers(s);
> -        s->maps_are_invalid = 1;
>          s->mb_width  = s_src->mb_width;
>          s->mb_height = s_src->mb_height;
>      }
> @@ -2063,7 +2082,14 @@ static int 
> vp8_decode_update_thread_context(AVCodecContext *dst, const AVCodecCo
>      s->lf_delta = s_src->lf_delta;
>      memcpy(s->sign_bias, s_src->sign_bias, sizeof(s->sign_bias));
>  
> -    memcpy(&s->frames, &s_src->frames, sizeof(s->frames));
> +    for (i = 0; i < FF_ARRAY_ELEMS(s_src->frames); i++) {
> +        if (s_src->frames[i].tf.f->data[0]) {
> +            int ret = vp8_ref_frame(s, &s->frames[i], &s_src->frames[i]);
> +            if (ret < 0)
> +                return ret;
> +        }
> +    }
> +
>      s->framep[0] = REBASE(s_src->next_framep[0]);
>      s->framep[1] = REBASE(s_src->next_framep[1]);
>      s->framep[2] = REBASE(s_src->next_framep[2]);
> diff --git a/libavcodec/vp8.h b/libavcodec/vp8.h
> index 4a85541..484cefe 100644
> --- a/libavcodec/vp8.h
> +++ b/libavcodec/vp8.h
> @@ -26,10 +26,13 @@
>  #ifndef AVCODEC_VP8_H
>  #define AVCODEC_VP8_H
>  
> +#include "libavutil/buffer.h"
> +
>  #include "vp56.h"
>  #include "vp56data.h"
>  #include "vp8dsp.h"
>  #include "h264pred.h"
> +#include "thread.h"
>  #if HAVE_PTHREADS
>  #include <pthread.h>
>  #elif HAVE_W32THREADS
> @@ -122,14 +125,19 @@ typedef struct VP8ThreadData {
>      VP8FilterStrength *filter_strength;
>  } VP8ThreadData;
>  
> +typedef struct VP8Frame {
> +    ThreadFrame tf;
> +    AVBufferRef *seg_map;
> +} VP8Frame;
> +
>  #define MAX_THREADS 8
>  typedef struct VP8Context {
>      VP8ThreadData *thread_data;
>      AVCodecContext *avctx;
> -    AVFrame *framep[4];
> -    AVFrame *next_framep[4];
> -    AVFrame *curframe;
> -    AVFrame *prev_frame;
> +    VP8Frame *framep[4];
> +    VP8Frame *next_framep[4];
> +    VP8Frame *curframe;
> +    VP8Frame *prev_frame;
>  
>      uint16_t mb_width;   /* number of horizontal MB */
>      uint16_t mb_height;  /* number of vertical MB */
> @@ -251,17 +259,8 @@ typedef struct VP8Context {
>      VP8DSPContext vp8dsp;
>      H264PredContext hpc;
>      vp8_mc_func put_pixels_tab[3][3][3];
> -    AVFrame frames[5];
> +    VP8Frame frames[5];
>  
> -    /**
> -     * A list of segmentation_map buffers that are to be free()'ed in
> -     * the next decoding iteration. We can't free() them right away
> -     * because the map may still be used by subsequent decoding threads.
> -     * Unused if frame threading is off.
> -     */
> -    uint8_t *segmentation_maps[5];
> -    int num_maps_to_be_freed;
> -    int maps_are_invalid;
>      int num_jobs;
>      /**
>       * This describes the macroblock memory layout.

lgtm although I'm a little surprised that it adds more lines than it
deletes.

Janne

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

Reply via email to