aboutsummaryrefslogtreecommitdiffstats
path: root/libavcodec/eamad.c
diff options
context:
space:
mode:
authorAnton Khirnov <anton@khirnov.net>2012-11-21 21:34:46 +0100
committerAnton Khirnov <anton@khirnov.net>2013-03-08 07:38:30 +0100
commit759001c534287a96dc96d1e274665feb7059145d (patch)
tree6ace9560c20aa30db92067c5b45d7bd86e458d10 /libavcodec/eamad.c
parent6e7b50b4270116ded8b874d76cb7c5b1a0341827 (diff)
downloadffmpeg-759001c534287a96dc96d1e274665feb7059145d.tar.gz
lavc decoders: work with refcounted frames.
Diffstat (limited to 'libavcodec/eamad.c')
-rw-r--r--libavcodec/eamad.c59
1 files changed, 28 insertions, 31 deletions
diff --git a/libavcodec/eamad.c b/libavcodec/eamad.c
index f9b43a147b..e666a45360 100644
--- a/libavcodec/eamad.c
+++ b/libavcodec/eamad.c
@@ -45,7 +45,6 @@
typedef struct MadContext {
AVCodecContext *avctx;
DSPContext dsp;
- AVFrame frame;
AVFrame last_frame;
GetBitContext gb;
void *bitstream_buf;
@@ -78,34 +77,36 @@ static inline void comp(unsigned char *dst, int dst_stride,
dst[j*dst_stride + i] = av_clip_uint8(src[j*src_stride + i] + add);
}
-static inline void comp_block(MadContext *t, int mb_x, int mb_y,
+static inline void comp_block(MadContext *t, AVFrame *frame,
+ int mb_x, int mb_y,
int j, int mv_x, int mv_y, int add)
{
if (j < 4) {
- comp(t->frame.data[0] + (mb_y*16 + ((j&2)<<2))*t->frame.linesize[0] + mb_x*16 + ((j&1)<<3),
- t->frame.linesize[0],
+ comp(frame->data[0] + (mb_y*16 + ((j&2)<<2))*frame->linesize[0] + mb_x*16 + ((j&1)<<3),
+ frame->linesize[0],
t->last_frame.data[0] + (mb_y*16 + ((j&2)<<2) + mv_y)*t->last_frame.linesize[0] + mb_x*16 + ((j&1)<<3) + mv_x,
t->last_frame.linesize[0], add);
} else if (!(t->avctx->flags & CODEC_FLAG_GRAY)) {
int index = j - 3;
- comp(t->frame.data[index] + (mb_y*8)*t->frame.linesize[index] + mb_x * 8,
- t->frame.linesize[index],
+ comp(frame->data[index] + (mb_y*8)*frame->linesize[index] + mb_x * 8,
+ frame->linesize[index],
t->last_frame.data[index] + (mb_y * 8 + (mv_y/2))*t->last_frame.linesize[index] + mb_x * 8 + (mv_x/2),
t->last_frame.linesize[index], add);
}
}
-static inline void idct_put(MadContext *t, int16_t *block, int mb_x, int mb_y, int j)
+static inline void idct_put(MadContext *t, AVFrame *frame, int16_t *block,
+ int mb_x, int mb_y, int j)
{
if (j < 4) {
ff_ea_idct_put_c(
- t->frame.data[0] + (mb_y*16 + ((j&2)<<2))*t->frame.linesize[0] + mb_x*16 + ((j&1)<<3),
- t->frame.linesize[0], block);
+ frame->data[0] + (mb_y*16 + ((j&2)<<2))*frame->linesize[0] + mb_x*16 + ((j&1)<<3),
+ frame->linesize[0], block);
} else if (!(t->avctx->flags & CODEC_FLAG_GRAY)) {
int index = j - 3;
ff_ea_idct_put_c(
- t->frame.data[index] + (mb_y*8)*t->frame.linesize[index] + mb_x*8,
- t->frame.linesize[index], block);
+ frame->data[index] + (mb_y*8)*frame->linesize[index] + mb_x*8,
+ frame->linesize[index], block);
}
}
@@ -179,7 +180,7 @@ static int decode_motion(GetBitContext *gb)
return value;
}
-static void decode_mb(MadContext *s, int inter)
+static void decode_mb(MadContext *s, AVFrame *frame, int inter)
{
int mv_map = 0;
int mv_x, mv_y;
@@ -199,11 +200,11 @@ static void decode_mb(MadContext *s, int inter)
for (j=0; j<6; j++) {
if (mv_map & (1<<j)) { // mv_x and mv_y are guarded by mv_map
int add = 2*decode_motion(&s->gb);
- comp_block(s, s->mb_x, s->mb_y, j, mv_x, mv_y, add);
+ comp_block(s, frame, s->mb_x, s->mb_y, j, mv_x, mv_y, add);
} else {
s->dsp.clear_block(s->block);
decode_block_intra(s, s->block);
- idct_put(s, s->block, s->mb_x, s->mb_y, j);
+ idct_put(s, frame, s->block, s->mb_x, s->mb_y, j);
}
}
}
@@ -225,9 +226,10 @@ static int decode_frame(AVCodecContext *avctx,
int buf_size = avpkt->size;
const uint8_t *buf_end = buf+buf_size;
MadContext *s = avctx->priv_data;
+ AVFrame *frame = data;
int width, height;
int chunk_type;
- int inter;
+ int inter, ret;
if (buf_size < 17) {
av_log(avctx, AV_LOG_ERROR, "Input buffer too small\n");
@@ -251,16 +253,12 @@ static int decode_frame(AVCodecContext *avctx,
if (av_image_check_size(width, height, 0, avctx) < 0)
return -1;
avcodec_set_dimensions(avctx, width, height);
- if (s->frame.data[0])
- avctx->release_buffer(avctx, &s->frame);
+ av_frame_unref(&s->last_frame);
}
- s->frame.reference = 1;
- if (!s->frame.data[0]) {
- if (ff_get_buffer(avctx, &s->frame) < 0) {
- av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
- return -1;
- }
+ 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;
}
av_fast_padded_malloc(&s->bitstream_buf, &s->bitstream_buf_size,
@@ -272,13 +270,15 @@ static int decode_frame(AVCodecContext *avctx,
for (s->mb_y=0; s->mb_y < (avctx->height+15)/16; s->mb_y++)
for (s->mb_x=0; s->mb_x < (avctx->width +15)/16; s->mb_x++)
- decode_mb(s, inter);
+ decode_mb(s, frame, inter);
*got_frame = 1;
- *(AVFrame*)data = s->frame;
- if (chunk_type != MADe_TAG)
- FFSWAP(AVFrame, s->frame, s->last_frame);
+ if (chunk_type != MADe_TAG) {
+ av_frame_unref(&s->last_frame);
+ if ((ret = av_frame_ref(&s->last_frame, frame)) < 0)
+ return ret;
+ }
return buf_size;
}
@@ -286,10 +286,7 @@ static int decode_frame(AVCodecContext *avctx,
static av_cold int decode_end(AVCodecContext *avctx)
{
MadContext *t = avctx->priv_data;
- if (t->frame.data[0])
- avctx->release_buffer(avctx, &t->frame);
- if (t->last_frame.data[0])
- avctx->release_buffer(avctx, &t->last_frame);
+ av_frame_unref(&t->last_frame);
av_free(t->bitstream_buf);
return 0;
}