diff options
author | Ben Jackson <ben@ben.com> | 2012-09-15 10:32:42 -0700 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2012-09-15 20:26:40 +0200 |
commit | 1c20fcf0b0d30b63c33e4302c3d92b66b1665b33 (patch) | |
tree | 35e5cf8f4af83f60af77911ab900c3210b5bfad1 /libavcodec/vp56.c | |
parent | eebc11ebc8000aefc8562d17749ac2f9160fdfec (diff) | |
download | ffmpeg-streaming-1c20fcf0b0d30b63c33e4302c3d92b66b1665b33.zip ffmpeg-streaming-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.c | 49 |
1 files changed, 28 insertions, 21 deletions
diff --git a/libavcodec/vp56.c b/libavcodec/vp56.c index 47f92f1..7d771f3 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; } |