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>tags/n3.1
@@ -66,9 +66,14 @@ static int tqi_decode_mb(MpegEncContext *s, int16_t (*block)[64]) | |||||
{ | { | ||||
int n; | int n; | ||||
s->bdsp.clear_blocks(block[0]); | 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 -1; | ||||
} | |||||
return 0; | return 0; | ||||
} | } | ||||
@@ -236,3 +236,91 @@ int ff_mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size, | |||||
pc->state = state; | pc->state = state; | ||||
return END_NOT_FOUND; | 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; | |||||
} |
@@ -50,7 +50,11 @@ static inline int decode_dc(GetBitContext *gb, int component) | |||||
return diff; | 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); | void ff_mpeg1_clean_buffers(MpegEncContext *s); | ||||
int ff_mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size, AVCodecParserContext *s); | int ff_mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size, AVCodecParserContext *s); | ||||
@@ -138,99 +138,6 @@ static int mpeg_decode_motion(MpegEncContext *s, int fcode, int pred) | |||||
} \ | } \ | ||||
} while (0) | } 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, | static inline int mpeg1_decode_block_inter(MpegEncContext *s, | ||||
int16_t *block, int n) | int16_t *block, int n) | ||||
{ | { | ||||
@@ -874,9 +781,20 @@ FF_ENABLE_DEPRECATION_WARNINGS | |||||
return ret; | return ret; | ||||
} | } | ||||
} else { | } 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; | return ret; | ||||
} | |||||
s->block_last_index[i] = ret; | |||||
} | |||||
} | } | ||||
} else { | } else { | ||||
if (mb_type & MB_TYPE_ZERO_MV) { | if (mb_type & MB_TYPE_ZERO_MV) { | ||||