Correct reference buffer switching in Indeo 5 decoder.
Patch by Maxim ($indeo5decauthor) Originally committed as revision 22580 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
6eec969d54
commit
ace38c36bf
@ -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,
|
|||||||
*/
|
*/
|
||||||
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;
|
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->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) {
|
|
||||||
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;
|
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:
|
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)
|
|||||||
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,
|
|||||||
|
|
||||||
//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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user