mpeg1: Make intra-block decoding independent of MpegEncContext

This allows untangling the eatqi decoder from the MPEG-1 decoder.

Signed-off-by: Vittorio Giovara <vittorio.giovara@gmail.com>
Signed-off-by: Diego Biurrun <diego@biurrun.de>
This commit is contained in:
Vittorio Giovara 2016-01-25 12:56:11 -05:00 committed by Diego Biurrun
parent 249827f736
commit 7c25ffe070
4 changed files with 113 additions and 98 deletions

View File

@ -66,9 +66,14 @@ static int tqi_decode_mb(MpegEncContext *s, int16_t (*block)[64])
{
int n;
s->bdsp.clear_blocks(block[0]);
for (n=0; n<6; n++)
if (ff_mpeg1_decode_block_intra(s, block[n], n) < 0)
for (n = 0; n < 6; n++) {
int ret = ff_mpeg1_decode_block_intra(&s->gb,
s->intra_matrix,
s->intra_scantable.permutated,
s->last_dc, block[n], n, 1);
if (ret < 0)
return -1;
}
return 0;
}

View File

@ -236,3 +236,91 @@ int ff_mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size,
pc->state = state;
return END_NOT_FOUND;
}
#define MAX_INDEX (64 - 1)
int ff_mpeg1_decode_block_intra(GetBitContext *gb,
const uint16_t *quant_matrix,
uint8_t *const scantable, int last_dc[3],
int16_t *block, int index, int qscale)
{
int dc, diff, i = 0, component;
RLTable *rl = &ff_rl_mpeg1;
/* DC coefficient */
component = index <= 3 ? 0 : index - 4 + 1;
diff = decode_dc(gb, component);
if (diff >= 0xffff)
return AVERROR_INVALIDDATA;
dc = last_dc[component];
dc += diff;
last_dc[component] = dc;
block[0] = dc * quant_matrix[0];
{
OPEN_READER(re, gb);
/* now quantify & encode AC coefficients */
while (1) {
int level, run, j;
UPDATE_CACHE(re, gb);
GET_RL_VLC(level, run, re, gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);
if (level == 127) {
break;
} else if (level != 0) {
i += run;
if (i > MAX_INDEX)
break;
j = scantable[i];
level = (level * qscale * quant_matrix[j]) >> 4;
level = (level - 1) | 1;
level = (level ^ SHOW_SBITS(re, gb, 1)) -
SHOW_SBITS(re, gb, 1);
LAST_SKIP_BITS(re, gb, 1);
} else {
/* escape */
run = SHOW_UBITS(re, gb, 6) + 1;
LAST_SKIP_BITS(re, gb, 6);
UPDATE_CACHE(re, gb);
level = SHOW_SBITS(re, gb, 8);
SKIP_BITS(re, gb, 8);
if (level == -128) {
level = SHOW_UBITS(re, gb, 8) - 256;
LAST_SKIP_BITS(re, gb, 8);
} else if (level == 0) {
level = SHOW_UBITS(re, gb, 8);
LAST_SKIP_BITS(re, gb, 8);
}
i += run;
if (i > MAX_INDEX)
break;
j = scantable[i];
if (level < 0) {
level = -level;
level = (level * qscale * quant_matrix[j]) >> 4;
level = (level - 1) | 1;
level = -level;
} else {
level = (level * qscale * quant_matrix[j]) >> 4;
level = (level - 1) | 1;
}
}
block[j] = level;
}
CLOSE_READER(re, gb);
}
if (i > MAX_INDEX)
i = AVERROR_INVALIDDATA;
return i;
}

View File

@ -50,7 +50,11 @@ static inline int decode_dc(GetBitContext *gb, int component)
return diff;
}
int ff_mpeg1_decode_block_intra(MpegEncContext *s, int16_t *block, int n);
int ff_mpeg1_decode_block_intra(GetBitContext *gb,
const uint16_t *quant_matrix,
uint8_t *const scantable, int last_dc[3],
int16_t *block, int index, int qscale);
void ff_mpeg1_clean_buffers(MpegEncContext *s);
int ff_mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size, AVCodecParserContext *s);

View File

@ -138,99 +138,6 @@ static int mpeg_decode_motion(MpegEncContext *s, int fcode, int pred)
} \
} while (0)
static inline int mpeg1_decode_block_intra(MpegEncContext *s,
int16_t *block, int index)
{
int dc, diff, i = 0, component;
RLTable *rl = &ff_rl_mpeg1;
uint8_t *const scantable = s->intra_scantable.permutated;
const uint16_t *quant_matrix = s->intra_matrix;
const int qscale = s->qscale;
/* DC coefficient */
component = index <= 3 ? 0 : index - 4 + 1;
diff = decode_dc(&s->gb, component);
if (diff >= 0xffff)
return AVERROR_INVALIDDATA;
dc = s->last_dc[component];
dc += diff;
s->last_dc[component] = dc;
block[0] = dc * quant_matrix[0];
{
OPEN_READER(re, &s->gb);
/* now quantify & encode AC coefficients */
while (1) {
int level, run, j;
UPDATE_CACHE(re, &s->gb);
GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0],
TEX_VLC_BITS, 2, 0);
if (level == 127) {
break;
} else if (level != 0) {
i += run;
if (i > MAX_INDEX)
break;
j = scantable[i];
level = (level * qscale * quant_matrix[j]) >> 4;
level = (level - 1) | 1;
level = (level ^ SHOW_SBITS(re, &s->gb, 1)) -
SHOW_SBITS(re, &s->gb, 1);
LAST_SKIP_BITS(re, &s->gb, 1);
} else {
/* escape */
run = SHOW_UBITS(re, &s->gb, 6) + 1;
LAST_SKIP_BITS(re, &s->gb, 6);
UPDATE_CACHE(re, &s->gb);
level = SHOW_SBITS(re, &s->gb, 8);
SKIP_BITS(re, &s->gb, 8);
if (level == -128) {
level = SHOW_UBITS(re, &s->gb, 8) - 256;
LAST_SKIP_BITS(re, &s->gb, 8);
} else if (level == 0) {
level = SHOW_UBITS(re, &s->gb, 8);
LAST_SKIP_BITS(re, &s->gb, 8);
}
i += run;
if (i > MAX_INDEX)
break;
j = scantable[i];
if (level < 0) {
level = -level;
level = (level * qscale * quant_matrix[j]) >> 4;
level = (level - 1) | 1;
level = -level;
} else {
level = (level * qscale * quant_matrix[j]) >> 4;
level = (level - 1) | 1;
}
}
block[j] = level;
}
CLOSE_READER(re, &s->gb);
}
check_scantable_index(s, i);
s->block_last_index[index] = i;
return 0;
}
int ff_mpeg1_decode_block_intra(MpegEncContext *s, int16_t *block, int index)
{
return mpeg1_decode_block_intra(s, block, index);
}
static inline int mpeg1_decode_block_inter(MpegEncContext *s,
int16_t *block, int n)
{
@ -874,9 +781,20 @@ FF_ENABLE_DEPRECATION_WARNINGS
return ret;
}
} else {
for (i = 0; i < 6; i++)
if ((ret = mpeg1_decode_block_intra(s, *s->pblocks[i], i)) < 0)
for (i = 0; i < 6; i++) {
ret = ff_mpeg1_decode_block_intra(&s->gb,
s->intra_matrix,
s->intra_scantable.permutated,
s->last_dc, *s->pblocks[i],
i, s->qscale);
if (ret < 0) {
av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n",
s->mb_x, s->mb_y);
return ret;
}
s->block_last_index[i] = ret;
}
}
} else {
if (mb_type & MB_TYPE_ZERO_MV) {