aboutsummaryrefslogtreecommitdiffstats
path: root/libavcodec/vp56.c
diff options
context:
space:
mode:
authorBen Jackson <ben@ben.com>2012-09-15 10:32:42 -0700
committerMichael Niedermayer <michaelni@gmx.at>2012-09-15 20:26:40 +0200
commit1c20fcf0b0d30b63c33e4302c3d92b66b1665b33 (patch)
tree35e5cf8f4af83f60af77911ab900c3210b5bfad1 /libavcodec/vp56.c
parenteebc11ebc8000aefc8562d17749ac2f9160fdfec (diff)
downloadffmpeg-1c20fcf0b0d30b63c33e4302c3d92b66b1665b33.tar.gz
lavc/vp56: Simplify get/release_buffer code
Rather than cleverly managing frame pointers with swaps to avoid re-using "golden" frames, just do brute-force management of the 4 AVFrames. New strategy is probably no more costly and is easier to adapt to threaded usage. Signed-off-by: Ben Jackson <ben@ben.com> Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec/vp56.c')
-rw-r--r--libavcodec/vp56.c49
1 files changed, 28 insertions, 21 deletions
diff --git a/libavcodec/vp56.c b/libavcodec/vp56.c
index 47f92f1a1c..7d771f31f7 100644
--- a/libavcodec/vp56.c
+++ b/libavcodec/vp56.c
@@ -491,9 +491,20 @@ int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
{
const uint8_t *buf = avpkt->data;
VP56Context *s = avctx->priv_data;
- AVFrame *const p = s->framep[VP56_FRAME_CURRENT];
+ AVFrame *p = 0;
int remaining_buf_size = avpkt->size;
int is_alpha, av_uninit(alpha_offset);
+ int i;
+
+ /* select a current frame from the unused frames */
+ for (i = 0; i < 4; ++i) {
+ if (!s->frames[i].data[0]) {
+ p = &s->frames[i];
+ break;
+ }
+ }
+ av_assert0(p != 0);
+ s->framep[VP56_FRAME_CURRENT] = p;
if (s->has_alpha) {
if (remaining_buf_size < 3)
@@ -620,9 +631,6 @@ int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
next:
if (p->key_frame || s->golden_frame) {
- if (s->framep[VP56_FRAME_GOLDEN]->data[0] && s->framep[VP56_FRAME_GOLDEN] != p &&
- s->framep[VP56_FRAME_GOLDEN] != s->framep[VP56_FRAME_GOLDEN2])
- avctx->release_buffer(avctx, s->framep[VP56_FRAME_GOLDEN]);
s->framep[VP56_FRAME_GOLDEN] = p;
}
@@ -634,20 +642,20 @@ int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
}
}
- if (s->framep[VP56_FRAME_PREVIOUS] == s->framep[VP56_FRAME_GOLDEN] ||
- s->framep[VP56_FRAME_PREVIOUS] == s->framep[VP56_FRAME_GOLDEN2]) {
- if (s->framep[VP56_FRAME_UNUSED] != s->framep[VP56_FRAME_GOLDEN] &&
- s->framep[VP56_FRAME_UNUSED] != s->framep[VP56_FRAME_GOLDEN2])
- FFSWAP(AVFrame *, s->framep[VP56_FRAME_PREVIOUS],
- s->framep[VP56_FRAME_UNUSED]);
- else
- FFSWAP(AVFrame *, s->framep[VP56_FRAME_PREVIOUS],
- s->framep[VP56_FRAME_UNUSED2]);
- } else if (s->framep[VP56_FRAME_PREVIOUS]->data[0])
- avctx->release_buffer(avctx, s->framep[VP56_FRAME_PREVIOUS]);
FFSWAP(AVFrame *, s->framep[VP56_FRAME_CURRENT],
s->framep[VP56_FRAME_PREVIOUS]);
+ /* release frames that aren't in use */
+ for (i = 0; i < 4; ++i) {
+ AVFrame *victim = &s->frames[i];
+ if (!victim->data[0])
+ continue;
+ if (victim != s->framep[VP56_FRAME_PREVIOUS] &&
+ victim != s->framep[VP56_FRAME_GOLDEN] &&
+ (!s->has_alpha || victim != s->framep[VP56_FRAME_GOLDEN2]))
+ avctx->release_buffer(avctx, victim);
+ }
+
p->qstride = 0;
p->qscale_table = s->qscale_table;
p->qscale_type = FF_QSCALE_TYPE_VP56;
@@ -714,16 +722,15 @@ av_cold int ff_vp56_free(AVCodecContext *avctx)
av_cold int ff_vp56_free_context(VP56Context *s)
{
AVCodecContext *avctx = s->avctx;
+ int i;
av_freep(&s->qscale_table);
av_freep(&s->above_blocks);
av_freep(&s->macroblocks);
av_freep(&s->edge_emu_buffer_alloc);
- if (s->framep[VP56_FRAME_GOLDEN]->data[0])
- avctx->release_buffer(avctx, s->framep[VP56_FRAME_GOLDEN]);
- if (s->framep[VP56_FRAME_GOLDEN2]->data[0])
- avctx->release_buffer(avctx, s->framep[VP56_FRAME_GOLDEN2]);
- if (s->framep[VP56_FRAME_PREVIOUS]->data[0])
- avctx->release_buffer(avctx, s->framep[VP56_FRAME_PREVIOUS]);
+ for (i = 0; i < 4; ++i) {
+ if (s->frames[i].data[0])
+ avctx->release_buffer(avctx, &s->frames[i]);
+ }
return 0;
}