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:
parent
3f773d8d02
commit
79c568dd4e
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user