summaryrefslogtreecommitdiff
path: root/libavcodec/indeo5.c
diff options
context:
space:
mode:
authorMaxim Poliakovski <max_pole@gmx.de>2010-03-17 07:53:12 +0000
committerKostya Shishkov <kostya.shishkov@gmail.com>2010-03-17 07:53:12 +0000
commitace38c36bf366038c96e33a84e7525318e9da7d1 (patch)
tree79781a2fc4d36806603c2ba20cfefac99dce6c3f /libavcodec/indeo5.c
parent6eec969d5481c2554725d9c8fd30f252aaf31959 (diff)
Correct reference buffer switching in Indeo 5 decoder.
Patch by Maxim ($indeo5decauthor) Originally committed as revision 22580 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec/indeo5.c')
-rw-r--r--libavcodec/indeo5.c66
1 files changed, 27 insertions, 39 deletions
diff --git a/libavcodec/indeo5.c b/libavcodec/indeo5.c
index 383bcf9ea2..9dea301d8a 100644
--- a/libavcodec/indeo5.c
+++ b/libavcodec/indeo5.c
@@ -57,8 +57,10 @@ typedef struct {
IVIPlaneDesc planes[3]; ///< color planes
const uint8_t *frame_data; ///< input frame data pointer
int buf_switch; ///< used to switch between three buffers
+ int inter_scal; ///< signals a sequence of scalable inter frames
int dst_buf; ///< buffer index for the currently decoded frame
int ref_buf; ///< inter frame reference buffer index
+ int ref2_buf; ///< temporal storage for switching buffers
uint32_t frame_size; ///< frame size in bytes
int frame_type;
int prev_frame_type; ///< frame type of the previous frame
@@ -648,53 +650,38 @@ static int decode_band(IVI5DecContext *ctx, int plane_num,
*/
static void switch_buffers(IVI5DecContext *ctx, AVCodecContext *avctx)
{
- switch (ctx->frame_type) {
+ switch (ctx->prev_frame_type) {
case FRAMETYPE_INTRA:
- ctx->buf_switch = 0;
- ctx->dst_buf = 0;
- ctx->ref_buf = 0;
- break;
case FRAMETYPE_INTER:
- ctx->buf_switch &= 1;
- /* swap buffers only if there were no droppable frames */
- if (ctx->prev_frame_type != FRAMETYPE_INTER_NOREF &&
- ctx->prev_frame_type != FRAMETYPE_INTER_SCAL)
- ctx->buf_switch ^= 1;
+ ctx->buf_switch ^= 1;
ctx->dst_buf = ctx->buf_switch;
ctx->ref_buf = ctx->buf_switch ^ 1;
break;
case FRAMETYPE_INTER_SCAL:
- if (ctx->prev_frame_type == FRAMETYPE_INTER_NOREF)
- break;
- if (ctx->prev_frame_type != FRAMETYPE_INTER_SCAL) {
- ctx->buf_switch ^= 1;
- ctx->dst_buf = ctx->buf_switch;
- ctx->ref_buf = ctx->buf_switch ^ 1;
- } else {
- ctx->buf_switch ^= 2;
- ctx->dst_buf = 2;
- ctx->ref_buf = ctx->buf_switch & 1;
- if (!(ctx->buf_switch & 2))
- FFSWAP(int, ctx->dst_buf, ctx->ref_buf);
+ if (!ctx->inter_scal) {
+ ctx->ref2_buf = 2;
+ ctx->inter_scal = 1;
}
+ FFSWAP(int, ctx->dst_buf, ctx->ref2_buf);
+ ctx->ref_buf = ctx->ref2_buf;
break;
case FRAMETYPE_INTER_NOREF:
- if (ctx->prev_frame_type == FRAMETYPE_INTER_SCAL) {
- ctx->buf_switch ^= 2;
- ctx->dst_buf = 2;
- ctx->ref_buf = ctx->buf_switch & 1;
- if (!(ctx->buf_switch & 2))
- FFSWAP(int, ctx->dst_buf, ctx->ref_buf);
- } else {
- ctx->buf_switch ^= 1;
- ctx->dst_buf = ctx->buf_switch & 1;
- ctx->ref_buf = (ctx->buf_switch & 1) ^ 1;
- }
break;
+ }
+
+ switch (ctx->frame_type) {
+ case FRAMETYPE_INTRA:
+ ctx->buf_switch = 0;
+ /* FALLTHROUGH */
+ case FRAMETYPE_INTER:
+ ctx->inter_scal = 0;
+ ctx->dst_buf = ctx->buf_switch;
+ ctx->ref_buf = ctx->buf_switch ^ 1;
+ break;
+ case FRAMETYPE_INTER_SCAL:
+ case FRAMETYPE_INTER_NOREF:
case FRAMETYPE_NULL:
- return;
- default:
- av_log(avctx, AV_LOG_ERROR, "unsupported frame type: %d\n", ctx->frame_type);
+ break;
}
}
@@ -729,6 +716,9 @@ static av_cold int decode_init(AVCodecContext *avctx)
return -1;
}
+ ctx->buf_switch = 0;
+ ctx->inter_scal = 0;
+
avctx->pix_fmt = PIX_FMT_YUV410P;
return 0;
@@ -766,9 +756,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
//START_TIMER;
- if (ctx->frame_type == FRAMETYPE_NULL) {
- ctx->frame_type = ctx->prev_frame_type;
- } else {
+ if (ctx->frame_type != FRAMETYPE_NULL) {
for (p = 0; p < 3; p++) {
for (b = 0; b < ctx->planes[p].num_bands; b++) {
result = decode_band(ctx, p, &ctx->planes[p].bands[b], avctx);