aboutsummaryrefslogtreecommitdiffstats
path: root/libavcodec/ffv1dec.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/ffv1dec.c
parent6e7b50b4270116ded8b874d76cb7c5b1a0341827 (diff)
downloadffmpeg-759001c534287a96dc96d1e274665feb7059145d.tar.gz
lavc decoders: work with refcounted frames.
Diffstat (limited to 'libavcodec/ffv1dec.c')
-rw-r--r--libavcodec/ffv1dec.c43
1 files changed, 21 insertions, 22 deletions
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;
}