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/cdgraphics.c | 64 +++++++++++++++++++++++-------------------------- 1 file changed, 30 insertions(+), 34 deletions(-) (limited to 'libavcodec/cdgraphics.c') diff --git a/libavcodec/cdgraphics.c b/libavcodec/cdgraphics.c index 9f402cae21..8be14602c3 100644 --- a/libavcodec/cdgraphics.c +++ b/libavcodec/cdgraphics.c @@ -64,26 +64,18 @@ #define CDG_PALETTE_SIZE 16 typedef struct CDGraphicsContext { - AVFrame frame; + AVFrame *frame; int hscroll; int vscroll; } CDGraphicsContext; -static void cdg_init_frame(AVFrame *frame) -{ - avcodec_get_frame_defaults(frame); - frame->reference = 3; - frame->buffer_hints = FF_BUFFER_HINTS_VALID | - FF_BUFFER_HINTS_READABLE | - FF_BUFFER_HINTS_PRESERVE | - FF_BUFFER_HINTS_REUSABLE; -} - static av_cold int cdg_decode_init(AVCodecContext *avctx) { CDGraphicsContext *cc = avctx->priv_data; - cdg_init_frame(&cc->frame); + cc->frame = av_frame_alloc(); + if (!cc->frame) + return AVERROR(ENOMEM); avctx->width = CDG_FULL_WIDTH; avctx->height = CDG_FULL_HEIGHT; @@ -95,8 +87,8 @@ static av_cold int cdg_decode_init(AVCodecContext *avctx) static void cdg_border_preset(CDGraphicsContext *cc, uint8_t *data) { int y; - int lsize = cc->frame.linesize[0]; - uint8_t *buf = cc->frame.data[0]; + int lsize = cc->frame->linesize[0]; + uint8_t *buf = cc->frame->data[0]; int color = data[0] & 0x0F; if (!(data[1] & 0x0F)) { @@ -120,7 +112,7 @@ static void cdg_load_palette(CDGraphicsContext *cc, uint8_t *data, int low) uint16_t color; int i; int array_offset = low ? 0 : 8; - uint32_t *palette = (uint32_t *) cc->frame.data[1]; + uint32_t *palette = (uint32_t *) cc->frame->data[1]; for (i = 0; i < 8; i++) { color = (data[2 * i] << 6) + (data[2 * i + 1] & 0x3F); @@ -129,7 +121,7 @@ static void cdg_load_palette(CDGraphicsContext *cc, uint8_t *data, int low) b = ((color ) & 0x000F) * 17; palette[i + array_offset] = r << 16 | g << 8 | b; } - cc->frame.palette_has_changed = 1; + cc->frame->palette_has_changed = 1; } static int cdg_tile_block(CDGraphicsContext *cc, uint8_t *data, int b) @@ -138,8 +130,8 @@ static int cdg_tile_block(CDGraphicsContext *cc, uint8_t *data, int b) int color; int x, y; int ai; - int stride = cc->frame.linesize[0]; - uint8_t *buf = cc->frame.data[0]; + int stride = cc->frame->linesize[0]; + uint8_t *buf = cc->frame->data[0]; ri = (data[2] & 0x1F) * CDG_TILE_HEIGHT + cc->vscroll; ci = (data[3] & 0x3F) * CDG_TILE_WIDTH + cc->hscroll; @@ -210,8 +202,8 @@ static void cdg_scroll(CDGraphicsContext *cc, uint8_t *data, int color; int hscmd, h_off, hinc, vscmd, v_off, vinc; int y; - int stride = cc->frame.linesize[0]; - uint8_t *in = cc->frame.data[0]; + int stride = cc->frame->linesize[0]; + uint8_t *in = cc->frame->data[0]; uint8_t *out = new_frame->data[0]; color = data[0] & 0x0F; @@ -239,7 +231,7 @@ static void cdg_scroll(CDGraphicsContext *cc, uint8_t *data, if (!hinc && !vinc) return; - memcpy(new_frame->data[1], cc->frame.data[1], CDG_PALETTE_SIZE * 4); + memcpy(new_frame->data[1], cc->frame->data[1], CDG_PALETTE_SIZE * 4); for (y = FFMAX(0, vinc); y < FFMIN(CDG_FULL_HEIGHT + vinc, CDG_FULL_HEIGHT); y++) memcpy(out + FFMAX(0, hinc) + stride * y, @@ -274,7 +266,7 @@ static int cdg_decode_frame(AVCodecContext *avctx, int ret; uint8_t command, inst; uint8_t cdg_data[CDG_DATA_SIZE]; - AVFrame new_frame; + AVFrame *frame = data; CDGraphicsContext *cc = avctx->priv_data; if (buf_size < CDG_MINIMUM_PKT_SIZE) { @@ -282,13 +274,13 @@ static int cdg_decode_frame(AVCodecContext *avctx, return AVERROR(EINVAL); } - ret = avctx->reget_buffer(avctx, &cc->frame); + ret = ff_reget_buffer(avctx, cc->frame); if (ret) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); return ret; } if (!avctx->frame_number) - memset(cc->frame.data[0], 0, cc->frame.linesize[0] * avctx->height); + memset(cc->frame->data[0], 0, cc->frame->linesize[0] * avctx->height); command = bytestream_get_byte(&buf); inst = bytestream_get_byte(&buf); @@ -300,8 +292,8 @@ static int cdg_decode_frame(AVCodecContext *avctx, switch (inst) { case CDG_INST_MEMORY_PRESET: if (!(cdg_data[1] & 0x0F)) - memset(cc->frame.data[0], cdg_data[0] & 0x0F, - cc->frame.linesize[0] * CDG_FULL_HEIGHT); + memset(cc->frame->data[0], cdg_data[0] & 0x0F, + cc->frame->linesize[0] * CDG_FULL_HEIGHT); break; case CDG_INST_LOAD_PAL_LO: case CDG_INST_LOAD_PAL_HIGH: @@ -335,28 +327,33 @@ static int cdg_decode_frame(AVCodecContext *avctx, return AVERROR(EINVAL); } - cdg_init_frame(&new_frame); - ret = ff_get_buffer(avctx, &new_frame); + ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF); if (ret) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } - cdg_scroll(cc, cdg_data, &new_frame, inst == CDG_INST_SCROLL_COPY); - avctx->release_buffer(avctx, &cc->frame); - cc->frame = new_frame; + cdg_scroll(cc, cdg_data, frame, inst == CDG_INST_SCROLL_COPY); + av_frame_unref(cc->frame); + ret = av_frame_ref(cc->frame, frame); + if (ret < 0) + return ret; break; default: break; } + if (!frame->data[0]) { + ret = av_frame_ref(frame, cc->frame); + if (ret < 0) + return ret; + } *got_frame = 1; } else { *got_frame = 0; buf_size = 0; } - *(AVFrame *) data = cc->frame; return buf_size; } @@ -364,8 +361,7 @@ static av_cold int cdg_decode_end(AVCodecContext *avctx) { CDGraphicsContext *cc = avctx->priv_data; - if (cc->frame.data[0]) - avctx->release_buffer(avctx, &cc->frame); + av_frame_free(&cc->frame); return 0; } -- cgit v1.2.3