Commit 92e5876e authored by Michel Lespinasse's avatar Michel Lespinasse

Move quant matrix prescaling and chroma quant matrix selection into slice.c

The idea is that we don't want header.c to know that level of detail
about the decoder's internals.
parent 297a512b
......@@ -420,7 +420,6 @@ mpeg2dec_t * mpeg2_init (void)
return NULL;
memset (mpeg2dec->decoder.DCTblock, 0, 64 * sizeof (int16_t));
memset (mpeg2dec->quantizer_matrix, 0, 4 * 64 * sizeof (uint8_t));
mpeg2dec->chunk_buffer = (uint8_t *) mpeg2_malloc (BUFFER_SIZE + 4,
MPEG2_ALLOC_CHUNK);
......
......@@ -99,6 +99,7 @@ void mpeg2_header_state_init (mpeg2dec_t * mpeg2dec)
mpeg2dec->decoder.coding_type = I_TYPE;
mpeg2dec->decoder.convert = NULL;
mpeg2dec->decoder.convert_id = NULL;
mpeg2dec->coding.matrix_updates = 0;
mpeg2dec->picture = mpeg2dec->pictures;
mpeg2dec->fbuf[0] = &mpeg2dec->fbuf_alloc[0].fbuf;
mpeg2dec->fbuf[1] = &mpeg2dec->fbuf_alloc[1].fbuf;
......@@ -171,18 +172,17 @@ int mpeg2_header_sequence (mpeg2dec_t * mpeg2dec)
mpeg2dec->copy_matrix = 3;
if (buffer[7] & 2) {
for (i = 0; i < 64; i++)
mpeg2dec->new_quantizer_matrix[0][mpeg2_scan_norm[i]] =
mpeg2dec->new_quantizer_matrix[0][i] =
(buffer[i+7] << 7) | (buffer[i+8] >> 1);
buffer += 64;
} else
for (i = 0; i < 64; i++)
mpeg2dec->new_quantizer_matrix[0][mpeg2_scan_norm[i]] =
mpeg2dec->new_quantizer_matrix[0][i] =
default_intra_quantizer_matrix[i];
if (buffer[7] & 1)
for (i = 0; i < 64; i++)
mpeg2dec->new_quantizer_matrix[1][mpeg2_scan_norm[i]] =
buffer[i+8];
mpeg2dec->new_quantizer_matrix[1][i] = buffer[i+8];
else
memset (mpeg2dec->new_quantizer_matrix[1], 16, 64);
......@@ -408,32 +408,18 @@ int mpeg2_guess_aspect (const mpeg2_sequence_t * sequence,
return (height == 576) ? 1 : 2;
}
static void copy_matrix (mpeg2dec_t * mpeg2dec, int idx)
{
if (memcmp (mpeg2dec->quantizer_matrix[idx],
mpeg2dec->new_quantizer_matrix[idx], 64)) {
memcpy (mpeg2dec->quantizer_matrix[idx],
mpeg2dec->new_quantizer_matrix[idx], 64);
mpeg2dec->scaled[idx] = -1;
}
}
static void finalize_matrix (mpeg2dec_t * mpeg2dec)
{
mpeg2_decoder_t * decoder = &(mpeg2dec->decoder);
coding_t * coding = &(mpeg2dec->coding);
int i;
for (i = 0; i < 2; i++) {
if (mpeg2dec->copy_matrix & (1 << i))
copy_matrix (mpeg2dec, i);
if ((mpeg2dec->copy_matrix & (4 << i)) &&
memcmp (mpeg2dec->quantizer_matrix[i],
mpeg2dec->new_quantizer_matrix[i+2], 64)) {
copy_matrix (mpeg2dec, i + 2);
decoder->chroma_quantizer[i] = decoder->quantizer_prescale[i+2];
} else if (mpeg2dec->copy_matrix & (5 << i))
decoder->chroma_quantizer[i] = decoder->quantizer_prescale[i];
}
for (i = 0; i < 4; i++)
if (mpeg2dec->copy_matrix & (1 << i)) {
memcpy (coding->quantizer_matrix[i],
mpeg2dec->new_quantizer_matrix[i], 64);
coding->matrix_updates =
(coding->matrix_updates & ~(4 << i)) | (1 << i);
}
}
static mpeg2_state_t invalid_end_action (mpeg2dec_t * mpeg2dec)
......@@ -816,7 +802,7 @@ static int quant_matrix_ext (mpeg2dec_t * mpeg2dec)
for (i = 0; i < 4; i++)
if (buffer[0] & (8 >> i)) {
for (j = 0; j < 64; j++)
mpeg2dec->new_quantizer_matrix[i][mpeg2_scan_norm[j]] =
mpeg2dec->new_quantizer_matrix[i][j] =
(buffer[j] << (i+5)) | (buffer[j+1] >> (3-i));
mpeg2dec->copy_matrix |= 1 << i;
buffer += 64;
......@@ -850,28 +836,6 @@ int mpeg2_header_user_data (mpeg2dec_t * mpeg2dec)
return 0;
}
static void prescale (mpeg2dec_t * mpeg2dec, int idx)
{
static int non_linear_scale [] = {
0, 1, 2, 3, 4, 5, 6, 7,
8, 10, 12, 14, 16, 18, 20, 22,
24, 28, 32, 36, 40, 44, 48, 52,
56, 64, 72, 80, 88, 96, 104, 112
};
int i, j, k;
mpeg2_decoder_t * decoder = &(mpeg2dec->decoder);
if (mpeg2dec->scaled[idx] != decoder->q_scale_type) {
mpeg2dec->scaled[idx] = decoder->q_scale_type;
for (i = 0; i < 32; i++) {
k = decoder->q_scale_type ? non_linear_scale[i] : (i << 1);
for (j = 0; j < 64; j++)
decoder->quantizer_prescale[idx][i][j] =
k * mpeg2dec->quantizer_matrix[idx][j];
}
}
}
mpeg2_state_t mpeg2_header_slice_start (mpeg2dec_t * mpeg2dec)
{
mpeg2_decoder_t * decoder = &(mpeg2dec->decoder);
......@@ -881,17 +845,6 @@ mpeg2_state_t mpeg2_header_slice_start (mpeg2dec_t * mpeg2dec)
mpeg2dec->state == STATE_PICTURE_2ND) ?
STATE_SLICE : STATE_SLICE_1ST);
if (mpeg2dec->decoder.coding_type != D_TYPE) {
prescale (mpeg2dec, 0);
if (decoder->chroma_quantizer[0] == decoder->quantizer_prescale[2])
prescale (mpeg2dec, 2);
if (mpeg2dec->decoder.coding_type != I_TYPE) {
prescale (mpeg2dec, 1);
if (decoder->chroma_quantizer[1] == decoder->quantizer_prescale[3])
prescale (mpeg2dec, 3);
}
}
if (!(mpeg2dec->nb_decode_slices))
mpeg2dec->picture->flags |= PIC_FLAG_SKIP;
else if (mpeg2dec->convert_start) {
......
......@@ -153,6 +153,8 @@ struct mpeg2_decoder_s {
/* XXX: stuff due to xine shit */
int8_t q_scale_type;
int8_t scaled[4];
};
typedef struct {
......@@ -166,6 +168,8 @@ typedef struct {
int concealment_motion_vectors;
int intra_vlc_format;
int alternate_scan;
uint8_t quantizer_matrix[4][64];
int matrix_updates;
} coding_t;
struct mpeg2dec_s {
......@@ -230,9 +234,6 @@ struct mpeg2dec_s {
int16_t display_offset_x, display_offset_y;
int copy_matrix;
int8_t scaled[4]; /* XXX: MOVED */
//int8_t q_scale_type, scaled[4];
uint8_t quantizer_matrix[4][64];
uint8_t new_quantizer_matrix[4][64];
};
......
......@@ -1597,6 +1597,29 @@ static void motion_dummy (mpeg2_decoder_t * const decoder,
{
}
static void prescale (mpeg2_decoder_t * decoder, coding_t * coding, int idx)
{
static int non_linear_scale [] = {
0, 1, 2, 3, 4, 5, 6, 7,
8, 10, 12, 14, 16, 18, 20, 22,
24, 28, 32, 36, 40, 44, 48, 52,
56, 64, 72, 80, 88, 96, 104, 112
};
int i, j, k;
if ((coding->matrix_updates & (1 << idx)) != 0 ||
decoder->scaled[idx] != decoder->q_scale_type) {
coding->matrix_updates &= ~(1 << idx);
decoder->scaled[idx] = decoder->q_scale_type;
for (i = 0; i < 32; i++) {
k = decoder->q_scale_type ? non_linear_scale[i] : (i << 1);
for (j = 0; j < 64; j++)
decoder->quantizer_prescale[idx][i][mpeg2_scan_norm[j]] =
k * coding->quantizer_matrix[idx][j];
}
}
}
void mpeg2_init_fbuf (mpeg2_decoder_t * decoder, mpeg2_sequence_t * sequence,
mpeg2_picture_t * picture, coding_t * coding,
uint8_t * current_fbuf[3],
......@@ -1627,6 +1650,23 @@ void mpeg2_init_fbuf (mpeg2_decoder_t * decoder, mpeg2_sequence_t * sequence,
decoder->intra_vlc_format = coding->intra_vlc_format;
decoder->scan = coding->alternate_scan ? mpeg2_scan_alt : mpeg2_scan_norm;
if (coding->matrix_updates & 1)
decoder->chroma_quantizer[0] =
decoder->quantizer_prescale[(coding->matrix_updates & 4) ? 2 : 0];
if (coding->matrix_updates & 1)
decoder->chroma_quantizer[1] =
decoder->quantizer_prescale[(coding->matrix_updates & 8) ? 3 : 1];
if (decoder->coding_type != D_TYPE) {
prescale (decoder, coding, 0);
if (decoder->chroma_quantizer[0] == decoder->quantizer_prescale[2])
prescale (decoder, coding, 2);
if (decoder->coding_type != I_TYPE) {
prescale (decoder, coding, 1);
if (decoder->chroma_quantizer[1] == decoder->quantizer_prescale[3])
prescale (decoder, coding, 3);
}
}
stride = decoder->stride_frame;
bottom_field = (decoder->picture_structure == BOTTOM_FIELD);
offset = bottom_field ? stride : 0;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment