1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2024-11-21 10:55:51 +02:00

Merge commit '7c25ffe070c286874a8c3513f7504b90e1626b0c'

* commit '7c25ffe070c286874a8c3513f7504b90e1626b0c':
  mpeg1: Make intra-block decoding independent of MpegEncContext

Merged-by: Derek Buitenhuis <derek.buitenhuis@gmail.com>
This commit is contained in:
Derek Buitenhuis 2016-02-16 19:19:23 +00:00
commit 58dd885f9a
4 changed files with 123 additions and 105 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, s->block_last_index);
if (ret < 0)
return -1;
}
return 0;
}

View File

@ -243,3 +243,100 @@ int ff_mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size,
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 block_last_index[12])
{
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);
UPDATE_CACHE(re, gb);
if (((int32_t)GET_CACHE(re, gb)) <= (int32_t)0xBFFFFFFF)
goto end;
/* now quantify & encode AC coefficients */
while (1) {
int level, run, j;
GET_RL_VLC(level, run, re, gb, rl->rl_vlc[0],
TEX_VLC_BITS, 2, 0);
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);
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;
SKIP_BITS(re, gb, 8);
} else if (level == 0) {
level = SHOW_UBITS(re, gb, 8);
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;
if (((int32_t)GET_CACHE(re, gb)) <= (int32_t)0xBFFFFFFF)
break;
UPDATE_CACHE(re, gb);
}
end:
LAST_SKIP_BITS(re, gb, 2);
CLOSE_READER(re, gb);
}
if (i > MAX_INDEX)
i = AVERROR_INVALIDDATA;
block_last_index[index] = i;
return 0;
}

View File

@ -50,7 +50,12 @@ 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,
int block_last_index[12]);
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

@ -134,106 +134,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);
UPDATE_CACHE(re, &s->gb);
if (((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF)
goto end;
/* now quantify & encode AC coefficients */
while (1) {
int level, run, j;
GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0],
TEX_VLC_BITS, 2, 0);
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);
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;
SKIP_BITS(re, &s->gb, 8);
} else if (level == 0) {
level = SHOW_UBITS(re, &s->gb, 8);
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;
if (((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF)
break;
UPDATE_CACHE(re, &s->gb);
}
end:
LAST_SKIP_BITS(re, &s->gb, 2);
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)
{
@ -887,9 +787,20 @@ static int mpeg_decode_mb(MpegEncContext *s, int16_t block[12][64])
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, s->block_last_index);
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) {