Browse Source

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>
tags/n3.1
Vittorio Giovara Diego Biurrun 9 years ago
parent
commit
7c25ffe070
4 changed files with 113 additions and 98 deletions
  1. +7
    -2
      libavcodec/eatqi.c
  2. +88
    -0
      libavcodec/mpeg12.c
  3. +5
    -1
      libavcodec/mpeg12.h
  4. +13
    -95
      libavcodec/mpeg12dec.c

+ 7
- 2
libavcodec/eatqi.c 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);
if (ret < 0)
return -1;
}

return 0;
}


+ 88
- 0
libavcodec/mpeg12.c 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;
}

+ 5
- 1
libavcodec/mpeg12.h View File

@@ -50,7 +50,11 @@ 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);

void ff_mpeg1_clean_buffers(MpegEncContext *s);
int ff_mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size, AVCodecParserContext *s);



+ 13
- 95
libavcodec/mpeg12dec.c View File

@@ -138,99 +138,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);
/* 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,
int16_t *block, int n)
{
@@ -874,9 +781,20 @@ FF_ENABLE_DEPRECATION_WARNINGS
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);
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) {


Loading…
Cancel
Save