From 759001c534287a96dc96d1e274665feb7059145d Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 21 Nov 2012 21:34:46 +0100 Subject: lavc decoders: work with refcounted frames. --- libavcodec/ffv1dec.c | 43 +++++++++++++++++++++---------------------- 1 file changed, 21 insertions(+), 22 deletions(-) (limited to 'libavcodec/ffv1dec.c') diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c index a1b3db360c..f9b094dab7 100644 --- a/libavcodec/ffv1dec.c +++ b/libavcodec/ffv1dec.c @@ -316,16 +316,16 @@ static int decode_slice_header(FFV1Context *f, FFV1Context *fs) ps = get_symbol(c, state, 0); if (ps == 1) { - f->picture.interlaced_frame = 1; - f->picture.top_field_first = 1; + f->cur->interlaced_frame = 1; + f->cur->top_field_first = 1; } else if (ps == 2) { - f->picture.interlaced_frame = 1; - f->picture.top_field_first = 0; + f->cur->interlaced_frame = 1; + f->cur->top_field_first = 0; } else if (ps == 3) { - f->picture.interlaced_frame = 0; + f->cur->interlaced_frame = 0; } - f->picture.sample_aspect_ratio.num = get_symbol(c, state, 0); - f->picture.sample_aspect_ratio.den = get_symbol(c, state, 0); + f->cur->sample_aspect_ratio.num = get_symbol(c, state, 0); + f->cur->sample_aspect_ratio.den = get_symbol(c, state, 0); return 0; } @@ -338,7 +338,7 @@ static int decode_slice(AVCodecContext *c, void *arg) const int ps = (av_pix_fmt_desc_get(c->pix_fmt)->flags & PIX_FMT_PLANAR) ? (c->bits_per_raw_sample > 8) + 1 : 4; - AVFrame *const p = &f->picture; + AVFrame *const p = f->cur; if (f->version > 2) { if (decode_slice_header(f, fs) < 0) { @@ -348,7 +348,7 @@ static int decode_slice(AVCodecContext *c, void *arg) } if ((ret = ffv1_init_slice_state(f, fs)) < 0) return ret; - if (f->picture.key_frame) + if (f->cur->key_frame) ffv1_clear_slice_state(f, fs); width = fs->slice_width; height = fs->slice_height; @@ -799,16 +799,12 @@ static int ffv1_decode_frame(AVCodecContext *avctx, void *data, int buf_size = avpkt->size; FFV1Context *f = avctx->priv_data; RangeCoder *const c = &f->slice_context[0]->c; - AVFrame *const p = &f->picture; int i, ret; uint8_t keystate = 128; const uint8_t *buf_p; + AVFrame *const p = data; - AVFrame *picture = data; - - /* release previously stored data */ - if (p->data[0]) - avctx->release_buffer(avctx, p); + f->cur = p; ff_init_range_decoder(c, buf, buf_size); ff_build_rac_states(c, 0.05 * (1LL << 32), 256 - 8); @@ -829,8 +825,7 @@ static int ffv1_decode_frame(AVCodecContext *avctx, void *data, p->key_frame = 0; } - p->reference = 3; //for error concealment - if ((ret = ff_get_buffer(avctx, p)) < 0) { + if ((ret = ff_get_buffer(avctx, p, AV_GET_BUFFER_FLAG_REF)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } @@ -869,6 +864,8 @@ static int ffv1_decode_frame(AVCodecContext *avctx, void *data, ff_init_range_decoder(&fs->c, buf_p, v); } else fs->c.bytestream_end = (uint8_t *)(buf_p + v); + + fs->cur = p; } avctx->execute(avctx, decode_slice, &f->slice_context[0], NULL, @@ -884,13 +881,13 @@ static int ffv1_decode_frame(AVCodecContext *avctx, void *data, for (j = 0; j < 4; j++) { int sh = (j == 1 || j == 2) ? f->chroma_h_shift : 0; int sv = (j == 1 || j == 2) ? f->chroma_v_shift : 0; - dst[j] = f->picture.data[j] + f->picture.linesize[j] * + dst[j] = p->data[j] + p->linesize[j] * (fs->slice_y >> sv) + (fs->slice_x >> sh); src[j] = f->last_picture.data[j] + f->last_picture.linesize[j] * (fs->slice_y >> sv) + (fs->slice_x >> sh); } - av_image_copy(dst, f->picture.linesize, (const uint8_t **)src, + av_image_copy(dst, p->linesize, (const uint8_t **)src, f->last_picture.linesize, avctx->pix_fmt, fs->slice_width, fs->slice_height); @@ -899,10 +896,12 @@ static int ffv1_decode_frame(AVCodecContext *avctx, void *data, f->picture_number++; - *picture = *p; - *got_frame = 1; + av_frame_unref(&f->last_picture); + if ((ret = av_frame_ref(&f->last_picture, p)) < 0) + return ret; + f->cur = NULL; - FFSWAP(AVFrame, f->picture, f->last_picture); + *got_frame = 1; return buf_size; } -- cgit v1.2.3