X-Git-Url: https://git.piment-noir.org/?p=deb_ffmpeg.git;a=blobdiff_plain;f=ffmpeg%2Flibavcodec%2Fmlpdec.c;h=490d107e780ca39353163f308e7e23cf94a11dc8;hp=ed6a7fb58caa3f7c280a860f8cd5b4083edea235;hb=f6fa7814ccfe3e76514b36cf04f5cd3cb657c8cf;hpb=2ba45a602cbfa7b771effba9b11bb4245c21bc00 diff --git a/ffmpeg/libavcodec/mlpdec.c b/ffmpeg/libavcodec/mlpdec.c index ed6a7fb..490d107 100644 --- a/ffmpeg/libavcodec/mlpdec.c +++ b/ffmpeg/libavcodec/mlpdec.c @@ -105,7 +105,7 @@ typedef struct SubStream { /// Whether the LSBs of the matrix output are encoded in the bitstream. uint8_t lsb_bypass[MAX_MATRICES]; /// Matrix coefficients, stored as 2.14 fixed point. - int32_t matrix_coeff[MAX_MATRICES][MAX_CHANNELS]; + DECLARE_ALIGNED(32, int32_t, matrix_coeff)[MAX_MATRICES][MAX_CHANNELS]; /// Left shift to apply to noise values in 0x31eb substreams. uint8_t matrix_noise_shift[MAX_MATRICES]; //@} @@ -132,6 +132,9 @@ typedef struct MLPDecodeContext { /// Current access unit being read has a major sync. int is_major_sync_unit; + /// Size of the major sync unit, in bytes + int major_sync_header_size; + /// Set if a valid major sync block has been read. Otherwise no decoding is possible. uint8_t params_valid; @@ -156,7 +159,7 @@ typedef struct MLPDecodeContext { int8_t noise_buffer[MAX_BLOCKSIZE_POW2]; int8_t bypassed_lsbs[MAX_BLOCKSIZE][MAX_CHANNELS]; - int32_t sample_buffer[MAX_BLOCKSIZE][MAX_CHANNELS]; + DECLARE_ALIGNED(32, int32_t, sample_buffer)[MAX_BLOCKSIZE][MAX_CHANNELS]; MLPDSPContext dsp; } MLPDecodeContext; @@ -349,11 +352,15 @@ static int read_major_sync(MLPDecodeContext *m, GetBitContext *gb) return AVERROR_PATCHWELCOME; } + m->major_sync_header_size = mh.header_size; + m->access_unit_size = mh.access_unit_size; m->access_unit_size_pow2 = mh.access_unit_size_pow2; m->num_substreams = mh.num_substreams; - m->max_decoded_substream = m->num_substreams - 1; + + /* limit to decoding 3 substreams, as the 4th is used by Dolby Atmos for non-audio data */ + m->max_decoded_substream = FFMIN(m->num_substreams - 1, 2); m->avctx->sample_rate = mh.group1_samplerate; m->avctx->frame_size = mh.access_unit_size; @@ -576,7 +583,7 @@ FF_ENABLE_DEPRECATION_WARNINGS ch_assign = av_get_channel_layout_channel_index(s->ch_layout, channel); } - if ((unsigned)ch_assign > s->max_matrix_channel) { + if (ch_assign < 0 || ch_assign > s->max_matrix_channel) { avpriv_request_sample(m->avctx, "Assignment of matrix channel %d to invalid output channel %d", ch, ch_assign); @@ -1031,15 +1038,27 @@ static void fill_noise_buffer(MLPDecodeContext *m, unsigned int substr) s->noisegen_seed = seed; } +/** Write the audio data into the output buffer. */ -/** Apply the channel matrices in turn to reconstruct the original audio - * samples. */ - -static void rematrix_channels(MLPDecodeContext *m, unsigned int substr) +static int output_data(MLPDecodeContext *m, unsigned int substr, + AVFrame *frame, int *got_frame_ptr) { + AVCodecContext *avctx = m->avctx; SubStream *s = &m->substream[substr]; unsigned int mat; unsigned int maxchan; + int ret; + int is32 = (m->avctx->sample_fmt == AV_SAMPLE_FMT_S32); + + if (m->avctx->channels != s->max_matrix_channel + 1) { + av_log(m->avctx, AV_LOG_ERROR, "channel count mismatch\n"); + return AVERROR_INVALIDDATA; + } + + if (!s->blockpos) { + av_log(avctx, AV_LOG_ERROR, "No samples to output.\n"); + return AVERROR_INVALIDDATA; + } maxchan = s->max_matrix_channel; if (!s->noise_type) { @@ -1049,6 +1068,8 @@ static void rematrix_channels(MLPDecodeContext *m, unsigned int substr) fill_noise_buffer(m, substr); } + /* Apply the channel matrices in turn to reconstruct the original audio + * samples. */ for (mat = 0; mat < s->num_primitive_matrices; mat++) { unsigned int dest_ch = s->matrix_out_ch[mat]; m->dsp.mlp_rematrix_channel(&m->sample_buffer[0][0], @@ -1063,27 +1084,6 @@ static void rematrix_channels(MLPDecodeContext *m, unsigned int substr) m->access_unit_size_pow2, MSB_MASK(s->quant_step_size[dest_ch])); } -} - -/** Write the audio data into the output buffer. */ - -static int output_data(MLPDecodeContext *m, unsigned int substr, - AVFrame *frame, int *got_frame_ptr) -{ - AVCodecContext *avctx = m->avctx; - SubStream *s = &m->substream[substr]; - int ret; - int is32 = (m->avctx->sample_fmt == AV_SAMPLE_FMT_S32); - - if (m->avctx->channels != s->max_matrix_channel + 1) { - av_log(m->avctx, AV_LOG_ERROR, "channel count mismatch\n"); - return AVERROR_INVALIDDATA; - } - - if (!s->blockpos) { - av_log(avctx, AV_LOG_ERROR, "No samples to output.\n"); - return AVERROR_INVALIDDATA; - } /* get output buffer */ frame->nb_samples = s->blockpos; @@ -1142,7 +1142,7 @@ static int read_access_unit(AVCodecContext *avctx, void* data, if (read_major_sync(m, &gb) < 0) goto error; m->is_major_sync_unit = 1; - header_size += 28; + header_size += m->major_sync_header_size; } if (!m->params_valid) { @@ -1291,8 +1291,6 @@ next_substr: buf += substream_data_len[substr]; } - rematrix_channels(m, m->max_decoded_substream); - if ((ret = output_data(m, m->max_decoded_substream, data, got_frame_ptr)) < 0) return ret;