mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-04-14 00:58:38 +02:00
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:
parent
249827f736
commit
7c25ffe070
@ -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++)
|
for (n = 0; n < 6; n++) {
|
||||||
if (ff_mpeg1_decode_block_intra(s, block[n], n) < 0)
|
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++)
|
for (i = 0; i < 6; i++) {
|
||||||
if ((ret = mpeg1_decode_block_intra(s, *s->pblocks[i], i)) < 0)
|
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) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user