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/bink.c | 67 +++++++++++++++++++++++++------------------------------ 1 file changed, 30 insertions(+), 37 deletions(-) (limited to 'libavcodec/bink.c') diff --git a/libavcodec/bink.c b/libavcodec/bink.c index 033e9bf0a1..22e13c33dd 100644 --- a/libavcodec/bink.c +++ b/libavcodec/bink.c @@ -113,7 +113,7 @@ typedef struct BinkContext { AVCodecContext *avctx; DSPContext dsp; BinkDSPContext bdsp; - AVFrame *pic, *last; + AVFrame *last; int version; ///< internal Bink file version int has_alpha; int swap_planes; @@ -792,8 +792,8 @@ static inline void put_pixels8x8_overlapped(uint8_t *dst, uint8_t *src, int stri memcpy(dst + i*stride, tmp + i*8, 8); } -static int binkb_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, - int is_key, int is_chroma) +static int binkb_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb, + int plane_idx, int is_key, int is_chroma) { int blk, ret; int i, j, bx, by; @@ -807,13 +807,13 @@ static int binkb_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, int ybias = is_key ? -15 : 0; int qp; - const int stride = c->pic->linesize[plane_idx]; + const int stride = frame->linesize[plane_idx]; int bw = is_chroma ? (c->avctx->width + 15) >> 4 : (c->avctx->width + 7) >> 3; int bh = is_chroma ? (c->avctx->height + 15) >> 4 : (c->avctx->height + 7) >> 3; binkb_init_bundles(c); - ref_start = c->pic->data[plane_idx]; - ref_end = c->pic->data[plane_idx] + (bh * c->pic->linesize[plane_idx] + bw) * 8; + ref_start = frame->data[plane_idx]; + ref_end = frame->data[plane_idx] + (bh * frame->linesize[plane_idx] + bw) * 8; for (i = 0; i < 64; i++) coordmap[i] = (i & 7) + (i >> 3) * stride; @@ -824,7 +824,7 @@ static int binkb_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, return ret; } - dst = c->pic->data[plane_idx] + 8*by*stride; + dst = frame->data[plane_idx] + 8*by*stride; for (bx = 0; bx < bw; bx++, dst += 8) { blk = binkb_get_value(c, BINKB_SRC_BLOCK_TYPES); switch (blk) { @@ -938,8 +938,8 @@ static int binkb_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, return 0; } -static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, - int is_chroma) +static int bink_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb, + int plane_idx, int is_chroma) { int blk, ret; int i, j, bx, by; @@ -952,7 +952,7 @@ static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, LOCAL_ALIGNED_16(int32_t, dctblock, [64]); int coordmap[64]; - const int stride = c->pic->linesize[plane_idx]; + const int stride = frame->linesize[plane_idx]; int bw = is_chroma ? (c->avctx->width + 15) >> 4 : (c->avctx->width + 7) >> 3; int bh = is_chroma ? (c->avctx->height + 15) >> 4 : (c->avctx->height + 7) >> 3; int width = c->avctx->width >> is_chroma; @@ -962,7 +962,7 @@ static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, read_bundle(gb, c, i); ref_start = c->last->data[plane_idx] ? c->last->data[plane_idx] - : c->pic->data[plane_idx]; + : frame->data[plane_idx]; ref_end = ref_start + (bw - 1 + c->last->linesize[plane_idx] * (bh - 1)) * 8; @@ -991,9 +991,9 @@ static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, if (by == bh) break; - dst = c->pic->data[plane_idx] + 8*by*stride; + dst = frame->data[plane_idx] + 8*by*stride; prev = (c->last->data[plane_idx] ? c->last->data[plane_idx] - : c->pic->data[plane_idx]) + 8*by*stride; + : frame->data[plane_idx]) + 8*by*stride; for (bx = 0; bx < bw; bx++, dst += 8, prev += 8) { blk = get_value(c, BINK_SRC_BLOCK_TYPES); // 16x16 block type on odd line means part of the already decoded block, so skip it @@ -1165,30 +1165,30 @@ static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *pkt) { BinkContext * const c = avctx->priv_data; + AVFrame *frame = data; GetBitContext gb; int plane, plane_idx, ret; int bits_count = pkt->size << 3; if (c->version > 'b') { - if(c->pic->data[0]) - avctx->release_buffer(avctx, c->pic); - - if ((ret = ff_get_buffer(avctx, c->pic)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } } else { - if ((ret = avctx->reget_buffer(avctx, c->pic)) < 0) { + if ((ret = ff_reget_buffer(avctx, c->last)) < 0) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); return ret; } + if ((ret = av_frame_ref(frame, c->last)) < 0) + return ret; } init_get_bits(&gb, pkt->data, bits_count); if (c->has_alpha) { if (c->version >= 'i') skip_bits_long(&gb, 32); - if ((ret = bink_decode_plane(c, &gb, 3, 0)) < 0) + if ((ret = bink_decode_plane(c, frame, &gb, 3, 0)) < 0) return ret; } if (c->version >= 'i') @@ -1198,10 +1198,10 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac plane_idx = (!plane || !c->swap_planes) ? plane : (plane ^ 3); if (c->version > 'b') { - if ((ret = bink_decode_plane(c, &gb, plane_idx, !!plane)) < 0) + if ((ret = bink_decode_plane(c, frame, &gb, plane_idx, !!plane)) < 0) return ret; } else { - if ((ret = binkb_decode_plane(c, &gb, plane_idx, + if ((ret = binkb_decode_plane(c, frame, &gb, plane_idx, !avctx->frame_number, !!plane)) < 0) return ret; } @@ -1210,11 +1210,13 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac } emms_c(); - *got_frame = 1; - *(AVFrame*)data = *c->pic; + if (c->version > 'b') { + av_frame_unref(c->last); + if ((ret = av_frame_ref(c->last, frame)) < 0) + return ret; + } - if (c->version > 'b') - FFSWAP(AVFrame*, c->pic, c->last); + *got_frame = 1; /* always report that the buffer was completely consumed */ return pkt->size; @@ -1293,13 +1295,9 @@ static av_cold int decode_init(AVCodecContext *avctx) } c->avctx = avctx; - c->pic = avcodec_alloc_frame(); - c->last = avcodec_alloc_frame(); - if (!c->pic || !c->last) { - avcodec_free_frame(&c->pic); - avcodec_free_frame(&c->last); + c->last = av_frame_alloc(); + if (!c->last) return AVERROR(ENOMEM); - } if ((ret = av_image_check_size(avctx->width, avctx->height, 0, avctx)) < 0) return ret; @@ -1325,12 +1323,7 @@ static av_cold int decode_end(AVCodecContext *avctx) { BinkContext * const c = avctx->priv_data; - if (c->pic->data[0]) - avctx->release_buffer(avctx, c->pic); - if (c->last->data[0]) - avctx->release_buffer(avctx, c->last); - avcodec_free_frame(&c->pic); - avcodec_free_frame(&c->last); + av_frame_free(&c->last); free_bundles(c); return 0; -- cgit v1.2.3