1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2024-12-23 12:43:46 +02:00

avcodec/mlpenc: add proper support for output bit shift

This commit is contained in:
Paul B Mahol 2023-10-20 16:28:08 +02:00
parent 3f773d8d02
commit 79c568dd4e

View File

@ -54,6 +54,7 @@ typedef struct RestartHeader {
uint8_t max_channel; ///< The index of the last channel coded in this substream.
uint8_t max_matrix_channel; ///< The number of channels input into the rematrix stage.
int8_t max_shift;
uint8_t noise_shift; ///< The left shift applied to random noise in 0x31ea substreams.
uint32_t noisegen_seed; ///< The current seed value for the pseudorandom noise generator(s).
@ -84,7 +85,7 @@ typedef struct MatrixParams {
typedef struct DecodingParams {
uint16_t blocksize; ///< number of PCM samples in current audio block
uint8_t quant_step_size[MAX_CHANNELS]; ///< left shift to apply to Huffman-decoded residuals
uint8_t output_shift[MAX_CHANNELS]; ///< Left shift to apply to decoded PCM values to get final 24-bit output.
int8_t output_shift[MAX_CHANNELS]; ///< Left shift to apply to decoded PCM values to get final 24-bit output.
MatrixParams matrix_params;
@ -383,11 +384,13 @@ static void copy_restart_frame_params(MLPEncodeContext *ctx, MLPSubstream *s)
copy_matrix_params(&dp->matrix_params, &s->b[1].decoding_params.matrix_params);
for (int ch = 0; ch <= rh->max_matrix_channel; ch++)
dp->output_shift[ch] = s->b[1].decoding_params.output_shift[ch];
for (int ch = 0; ch <= rh->max_channel; ch++) {
ChannelParams *cp = &s->b[index].channel_params[ch];
dp->quant_step_size[ch] = s->b[1].decoding_params.quant_step_size[ch];
dp->output_shift[ch] = s->b[1].decoding_params.output_shift[ch];
if (index)
for (unsigned int filter = 0; filter < NUM_FILTERS; filter++)
@ -758,7 +761,7 @@ static void write_restart_header(MLPEncodeContext *ctx, MLPSubstream *s,
put_bits(pb, 4, rh->max_matrix_channel);
put_bits(pb, 4, rh->noise_shift );
put_bits(pb, 23, rh->noisegen_seed );
put_bits(pb, 4, 0 ); /* TODO max_shift */
put_bits(pb, 4, rh->max_shift );
put_bits(pb, 5, rh->max_huff_lsbs );
put_bits(pb, 5, rh->max_output_bits );
put_bits(pb, 5, rh->max_output_bits );
@ -1253,6 +1256,41 @@ static int number_trailing_zeroes(int32_t sample, unsigned int max, unsigned int
return sample ? FFMIN(max, ff_ctz(sample)) : def;
}
static void determine_output_shift(MLPEncodeContext *ctx, MLPSubstream *s)
{
RestartHeader *rh = s->cur_restart_header;
DecodingParams *dp1 = &s->b[1].decoding_params;
int32_t sample_mask[MAX_CHANNELS];
memset(sample_mask, 0, sizeof(sample_mask));
for (int j = 0; j <= ctx->cur_restart_interval; j++) {
DecodingParams *dp = &s->b[j].decoding_params;
for (int ch = 0; ch <= rh->max_matrix_channel; ch++) {
int32_t *sample_buffer = dp->sample_buffer[ch];
for (int i = 0; i < dp->blocksize; i++)
sample_mask[ch] |= sample_buffer[i];
}
}
for (int ch = 0; ch <= rh->max_matrix_channel; ch++)
dp1->output_shift[ch] = number_trailing_zeroes(sample_mask[ch], 7, 0);
for (int j = 0; j <= ctx->cur_restart_interval; j++) {
DecodingParams *dp = &s->b[j].decoding_params;
for (int ch = 0; ch <= rh->max_matrix_channel; ch++) {
int32_t *sample_buffer = dp->sample_buffer[ch];
const int shift = dp1->output_shift[ch];
for (int i = 0; i < dp->blocksize; i++)
sample_buffer[i] >>= shift;
}
}
}
/** Determines how many bits are zero at the end of all samples so they can be
* shifted out.
*/
@ -2016,14 +2054,21 @@ static void set_major_params(MLPEncodeContext *ctx, MLPSubstream *s)
{
RestartHeader *rh = s->cur_restart_header;
uint8_t max_huff_lsbs = 0, max_output_bits = 0;
int8_t max_shift = 0;
for (int index = 0; index < s->b[ctx->restart_intervals-1].seq_size; index++) {
memcpy(&s->b[index].major_decoding_params,
&s->b[index].decoding_params, sizeof(DecodingParams));
for (int ch = 0; ch <= rh->max_matrix_channel; ch++) {
int8_t shift = s->b[index].decoding_params.output_shift[ch];
max_shift = FFMAX(max_shift, shift);
}
for (int ch = rh->min_channel; ch <= rh->max_channel; ch++) {
uint8_t huff_lsbs = s->b[index].channel_params[ch].huff_lsbs;
if (max_huff_lsbs < huff_lsbs)
max_huff_lsbs = huff_lsbs;
max_huff_lsbs = FFMAX(max_huff_lsbs, huff_lsbs);
memcpy(&s->b[index].major_channel_params[ch],
&s->b[index].channel_params[ch],
sizeof(ChannelParams));
@ -2031,6 +2076,7 @@ static void set_major_params(MLPEncodeContext *ctx, MLPSubstream *s)
}
rh->max_huff_lsbs = max_huff_lsbs;
rh->max_shift = max_shift;
for (int index = 0; index < ctx->number_of_frames; index++)
if (max_output_bits < s->b[index].max_output_bits)
@ -2065,6 +2111,7 @@ static void analyze_sample_buffer(MLPEncodeContext *ctx, MLPSubstream *s)
s->b[1].decoding_params.blocksize -= 8;
input_to_sample_buffer (ctx, s);
determine_output_shift (ctx, s);
generate_2_noise_channels(ctx, s);
lossless_matrix_coeffs (ctx, s);
rematrix_channels (ctx, s);