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

@@ -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;
}