# HG changeset patch # User kostya # Date 1268812392 0 # Node ID d44678e484a3319596a304360374fd83477b8b85 # Parent 5536f1bacb4887b84f73c194dd817e0987f75012 Correct reference buffer switching in Indeo 5 decoder. Patch by Maxim ($indeo5decauthor) diff -r 5536f1bacb48 -r d44678e484a3 indeo5.c --- a/indeo5.c Wed Mar 17 07:49:36 2010 +0000 +++ b/indeo5.c Wed Mar 17 07:53:12 2010 +0000 @@ -57,8 +57,10 @@ 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 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 @@ return -1; } + ctx->buf_switch = 0; + ctx->inter_scal = 0; + avctx->pix_fmt = PIX_FMT_YUV410P; return 0; @@ -766,9 +756,7 @@ //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);