Commit 852b8b16 authored by kostya's avatar kostya

Correct reference buffer switching in Indeo 5 decoder.

Patch by Maxim ($indeo5decauthor)



git-svn-id: file:///var/local/repositories/ffmpeg/trunk@22580 9553f0bf-9b14-0410-a0b8-cfaf0461ba5b
parent 6ba4b9ca
...@@ -57,8 +57,10 @@ typedef struct { ...@@ -57,8 +57,10 @@ typedef struct {
IVIPlaneDesc planes[3]; ///< color planes IVIPlaneDesc planes[3]; ///< color planes
const uint8_t *frame_data; ///< input frame data pointer const uint8_t *frame_data; ///< input frame data pointer
int buf_switch; ///< used to switch between three buffers 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 dst_buf; ///< buffer index for the currently decoded frame
int ref_buf; ///< inter frame reference buffer index int ref_buf; ///< inter frame reference buffer index
int ref2_buf; ///< temporal storage for switching buffers
uint32_t frame_size; ///< frame size in bytes uint32_t frame_size; ///< frame size in bytes
int frame_type; int frame_type;
int prev_frame_type; ///< frame type of the previous frame int prev_frame_type; ///< frame type of the previous frame
...@@ -648,53 +650,38 @@ static int decode_band(IVI5DecContext *ctx, int plane_num, ...@@ -648,53 +650,38 @@ static int decode_band(IVI5DecContext *ctx, int plane_num,
*/ */
static void switch_buffers(IVI5DecContext *ctx, AVCodecContext *avctx) static void switch_buffers(IVI5DecContext *ctx, AVCodecContext *avctx)
{ {
switch (ctx->frame_type) { switch (ctx->prev_frame_type) {
case FRAMETYPE_INTRA: case FRAMETYPE_INTRA:
ctx->buf_switch = 0;
ctx->dst_buf = 0;
ctx->ref_buf = 0;
break;
case FRAMETYPE_INTER: 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->dst_buf = ctx->buf_switch;
ctx->ref_buf = ctx->buf_switch ^ 1; ctx->ref_buf = ctx->buf_switch ^ 1;
break; break;
case FRAMETYPE_INTER_SCAL: case FRAMETYPE_INTER_SCAL:
if (ctx->prev_frame_type == FRAMETYPE_INTER_NOREF) if (!ctx->inter_scal) {
break; ctx->ref2_buf = 2;
if (ctx->prev_frame_type != FRAMETYPE_INTER_SCAL) { ctx->inter_scal = 1;
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);
} }
FFSWAP(int, ctx->dst_buf, ctx->ref2_buf);
ctx->ref_buf = ctx->ref2_buf;
break; break;
case FRAMETYPE_INTER_NOREF: case FRAMETYPE_INTER_NOREF:
if (ctx->prev_frame_type == FRAMETYPE_INTER_SCAL) { break;
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;
} }
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; break;
case FRAMETYPE_INTER_SCAL:
case FRAMETYPE_INTER_NOREF:
case FRAMETYPE_NULL: case FRAMETYPE_NULL:
return; break;
default:
av_log(avctx, AV_LOG_ERROR, "unsupported frame type: %d\n", ctx->frame_type);
} }
} }
...@@ -729,6 +716,9 @@ static av_cold int decode_init(AVCodecContext *avctx) ...@@ -729,6 +716,9 @@ static av_cold int decode_init(AVCodecContext *avctx)
return -1; return -1;
} }
ctx->buf_switch = 0;
ctx->inter_scal = 0;
avctx->pix_fmt = PIX_FMT_YUV410P; avctx->pix_fmt = PIX_FMT_YUV410P;
return 0; return 0;
...@@ -766,9 +756,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, ...@@ -766,9 +756,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
//START_TIMER; //START_TIMER;
if (ctx->frame_type == FRAMETYPE_NULL) { if (ctx->frame_type != FRAMETYPE_NULL) {
ctx->frame_type = ctx->prev_frame_type;
} else {
for (p = 0; p < 3; p++) { for (p = 0; p < 3; p++) {
for (b = 0; b < ctx->planes[p].num_bands; b++) { for (b = 0; b < ctx->planes[p].num_bands; b++) {
result = decode_band(ctx, p, &ctx->planes[p].bands[b], avctx); result = decode_band(ctx, p, &ctx->planes[p].bands[b], avctx);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment