mirror of
https://github.com/nyanmisaka/ffmpeg-rockchip.git
synced 2025-10-13 12:34:26 +08: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:

committed by
Diego Biurrun

parent
249827f736
commit
7c25ffe070
@@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user