mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2025-12-12 18:10:13 +01:00
Merge remote-tracking branch 'qatar/master'
* qatar/master: aac_latm: reconfigure decoder on audio specific config changes latmdec: fix audio specific config parsing Add avcodec_decode_audio4(). avcodec: change number of plane pointers from 4 to 8 at next major bump. Update developers documentation with coding conventions. svq1dec: avoid undefined get_bits(0) call ARM: h264dsp_neon cosmetics ARM: make some NEON macros reusable Do not memcpy raw video frames when using null muxer fate: update asf seektest vp8: flush buffers on size changes. doc: improve general documentation for MacOSX asf: use packet dts as approximation of pts asf: do not call av_read_frame rtsp: Initialize the media_type_mask in the rtp guessing demuxer Cleaned up alacenc.c Conflicts: doc/APIchanges doc/developer.texi libavcodec/8svx.c libavcodec/aacdec.c libavcodec/ac3dec.c libavcodec/avcodec.h libavcodec/nellymoserdec.c libavcodec/tta.c libavcodec/utils.c libavcodec/version.h libavcodec/wmadec.c libavformat/asfdec.c tests/ref/seek/lavf_asf Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
@@ -471,15 +471,17 @@ static int decode_ga_specific_config(AACContext *ac, AVCodecContext *avctx,
|
||||
* @param ac pointer to AACContext, may be null
|
||||
* @param avctx pointer to AVCCodecContext, used for logging
|
||||
* @param m4ac pointer to MPEG4AudioConfig, used for parsing
|
||||
* @param data pointer to AVCodecContext extradata
|
||||
* @param data_size size of AVCCodecContext extradata
|
||||
* @param data pointer to buffer holding an audio specific config
|
||||
* @param bit_size size of audio specific config or data in bits
|
||||
* @param sync_extension look for an appended sync extension
|
||||
*
|
||||
* @return Returns error status or number of consumed bits. <0 - error
|
||||
*/
|
||||
static int decode_audio_specific_config(AACContext *ac,
|
||||
AVCodecContext *avctx,
|
||||
MPEG4AudioConfig *m4ac,
|
||||
const uint8_t *data, int data_size, int asclen)
|
||||
const uint8_t *data, int bit_size,
|
||||
int sync_extension)
|
||||
{
|
||||
GetBitContext gb;
|
||||
int i;
|
||||
@@ -489,9 +491,9 @@ static int decode_audio_specific_config(AACContext *ac,
|
||||
av_dlog(avctx, "%02x ", avctx->extradata[i]);
|
||||
av_dlog(avctx, "\n");
|
||||
|
||||
init_get_bits(&gb, data, data_size * 8);
|
||||
init_get_bits(&gb, data, bit_size);
|
||||
|
||||
if ((i = avpriv_mpeg4audio_get_config(m4ac, data, asclen/8)) < 0)
|
||||
if ((i = avpriv_mpeg4audio_get_config(m4ac, data, bit_size, sync_extension)) < 0)
|
||||
return -1;
|
||||
if (m4ac->sampling_index > 12) {
|
||||
av_log(avctx, AV_LOG_ERROR, "invalid sampling rate index %d\n", m4ac->sampling_index);
|
||||
@@ -591,7 +593,7 @@ static av_cold int aac_decode_init(AVCodecContext *avctx)
|
||||
if (avctx->extradata_size > 0) {
|
||||
if (decode_audio_specific_config(ac, ac->avctx, &ac->m4ac,
|
||||
avctx->extradata,
|
||||
avctx->extradata_size, 8*avctx->extradata_size) < 0)
|
||||
avctx->extradata_size*8, 1) < 0)
|
||||
return -1;
|
||||
} else {
|
||||
int sr, i;
|
||||
@@ -665,6 +667,9 @@ static av_cold int aac_decode_init(AVCodecContext *avctx)
|
||||
|
||||
cbrt_tableinit();
|
||||
|
||||
avcodec_get_frame_defaults(&ac->frame);
|
||||
avctx->coded_frame = &ac->frame;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2132,12 +2137,12 @@ static int parse_adts_frame_header(AACContext *ac, GetBitContext *gb)
|
||||
}
|
||||
|
||||
static int aac_decode_frame_int(AVCodecContext *avctx, void *data,
|
||||
int *data_size, GetBitContext *gb)
|
||||
int *got_frame_ptr, GetBitContext *gb)
|
||||
{
|
||||
AACContext *ac = avctx->priv_data;
|
||||
ChannelElement *che = NULL, *che_prev = NULL;
|
||||
enum RawDataBlockType elem_type, elem_type_prev = TYPE_END;
|
||||
int err, elem_id, data_size_tmp;
|
||||
int err, elem_id;
|
||||
int samples = 0, multiplier, audio_found = 0;
|
||||
|
||||
if (show_bits(gb, 12) == 0xfff) {
|
||||
@@ -2250,24 +2255,26 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data,
|
||||
avctx->frame_size = samples;
|
||||
}
|
||||
|
||||
data_size_tmp = samples * avctx->channels *
|
||||
av_get_bytes_per_sample(avctx->sample_fmt);
|
||||
if (*data_size < data_size_tmp) {
|
||||
av_log(avctx, AV_LOG_ERROR,
|
||||
"Output buffer too small (%d) or trying to output too many samples (%d) for this frame.\n",
|
||||
*data_size, data_size_tmp);
|
||||
return -1;
|
||||
}
|
||||
*data_size = data_size_tmp;
|
||||
|
||||
if (samples) {
|
||||
/* get output buffer */
|
||||
ac->frame.nb_samples = samples;
|
||||
if ((err = avctx->get_buffer(avctx, &ac->frame)) < 0) {
|
||||
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
if (avctx->sample_fmt == AV_SAMPLE_FMT_FLT)
|
||||
ac->fmt_conv.float_interleave(data, (const float **)ac->output_data,
|
||||
ac->fmt_conv.float_interleave((float *)ac->frame.data[0],
|
||||
(const float **)ac->output_data,
|
||||
samples, avctx->channels);
|
||||
else
|
||||
ac->fmt_conv.float_to_int16_interleave(data, (const float **)ac->output_data,
|
||||
ac->fmt_conv.float_to_int16_interleave((int16_t *)ac->frame.data[0],
|
||||
(const float **)ac->output_data,
|
||||
samples, avctx->channels);
|
||||
|
||||
*(AVFrame *)data = ac->frame;
|
||||
}
|
||||
*got_frame_ptr = !!samples;
|
||||
|
||||
if (ac->output_configured && audio_found)
|
||||
ac->output_configured = OC_LOCKED;
|
||||
@@ -2276,7 +2283,7 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data,
|
||||
}
|
||||
|
||||
static int aac_decode_frame(AVCodecContext *avctx, void *data,
|
||||
int *data_size, AVPacket *avpkt)
|
||||
int *got_frame_ptr, AVPacket *avpkt)
|
||||
{
|
||||
const uint8_t *buf = avpkt->data;
|
||||
int buf_size = avpkt->size;
|
||||
@@ -2287,7 +2294,7 @@ static int aac_decode_frame(AVCodecContext *avctx, void *data,
|
||||
|
||||
init_get_bits(&gb, buf, buf_size * 8);
|
||||
|
||||
if ((err = aac_decode_frame_int(avctx, data, data_size, &gb)) < 0)
|
||||
if ((err = aac_decode_frame_int(avctx, data, got_frame_ptr, &gb)) < 0)
|
||||
return err;
|
||||
|
||||
buf_consumed = (get_bits_count(&gb) + 7) >> 3;
|
||||
@@ -2340,30 +2347,40 @@ static inline uint32_t latm_get_value(GetBitContext *b)
|
||||
static int latm_decode_audio_specific_config(struct LATMContext *latmctx,
|
||||
GetBitContext *gb, int asclen)
|
||||
{
|
||||
AVCodecContext *avctx = latmctx->aac_ctx.avctx;
|
||||
AACContext *ac= &latmctx->aac_ctx;
|
||||
MPEG4AudioConfig m4ac=ac->m4ac;
|
||||
int config_start_bit = get_bits_count(gb);
|
||||
int bits_consumed, esize;
|
||||
AACContext *ac = &latmctx->aac_ctx;
|
||||
AVCodecContext *avctx = ac->avctx;
|
||||
MPEG4AudioConfig m4ac = {0};
|
||||
int config_start_bit = get_bits_count(gb);
|
||||
int sync_extension = 0;
|
||||
int bits_consumed, esize;
|
||||
|
||||
if (asclen) {
|
||||
sync_extension = 1;
|
||||
asclen = FFMIN(asclen, get_bits_left(gb));
|
||||
} else
|
||||
asclen = get_bits_left(gb);
|
||||
|
||||
if (config_start_bit % 8) {
|
||||
av_log_missing_feature(latmctx->aac_ctx.avctx, "audio specific "
|
||||
"config not byte aligned.\n", 1);
|
||||
return AVERROR_INVALIDDATA;
|
||||
} else {
|
||||
bits_consumed =
|
||||
decode_audio_specific_config(ac, avctx, &m4ac,
|
||||
}
|
||||
bits_consumed = decode_audio_specific_config(NULL, avctx, &m4ac,
|
||||
gb->buffer + (config_start_bit / 8),
|
||||
get_bits_left(gb) / 8, asclen);
|
||||
asclen, sync_extension);
|
||||
|
||||
if (bits_consumed < 0)
|
||||
return AVERROR_INVALIDDATA;
|
||||
if(ac->m4ac.sample_rate != m4ac.sample_rate || m4ac.chan_config != ac->m4ac.chan_config)
|
||||
ac->m4ac= m4ac;
|
||||
if (bits_consumed < 0)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
if (ac->m4ac.sample_rate != m4ac.sample_rate ||
|
||||
ac->m4ac.chan_config != m4ac.chan_config) {
|
||||
|
||||
av_log(avctx, AV_LOG_INFO, "audio config changed\n");
|
||||
latmctx->initialized = 0;
|
||||
|
||||
esize = (bits_consumed+7) / 8;
|
||||
|
||||
if (avctx->extradata_size <= esize) {
|
||||
if (avctx->extradata_size < esize) {
|
||||
av_free(avctx->extradata);
|
||||
avctx->extradata = av_malloc(esize + FF_INPUT_BUFFER_PADDING_SIZE);
|
||||
if (!avctx->extradata)
|
||||
@@ -2373,9 +2390,8 @@ static int latm_decode_audio_specific_config(struct LATMContext *latmctx,
|
||||
avctx->extradata_size = esize;
|
||||
memcpy(avctx->extradata, gb->buffer + (config_start_bit/8), esize);
|
||||
memset(avctx->extradata+esize, 0, FF_INPUT_BUFFER_PADDING_SIZE);
|
||||
|
||||
skip_bits_long(gb, bits_consumed);
|
||||
}
|
||||
skip_bits_long(gb, bits_consumed);
|
||||
|
||||
return bits_consumed;
|
||||
}
|
||||
@@ -2512,8 +2528,8 @@ static int read_audio_mux_element(struct LATMContext *latmctx,
|
||||
}
|
||||
|
||||
|
||||
static int latm_decode_frame(AVCodecContext *avctx, void *out, int *out_size,
|
||||
AVPacket *avpkt)
|
||||
static int latm_decode_frame(AVCodecContext *avctx, void *out,
|
||||
int *got_frame_ptr, AVPacket *avpkt)
|
||||
{
|
||||
struct LATMContext *latmctx = avctx->priv_data;
|
||||
int muxlength, err;
|
||||
@@ -2535,12 +2551,12 @@ static int latm_decode_frame(AVCodecContext *avctx, void *out, int *out_size,
|
||||
|
||||
if (!latmctx->initialized) {
|
||||
if (!avctx->extradata) {
|
||||
*out_size = 0;
|
||||
*got_frame_ptr = 0;
|
||||
return avpkt->size;
|
||||
} else {
|
||||
if ((err = decode_audio_specific_config(
|
||||
&latmctx->aac_ctx, avctx, &latmctx->aac_ctx.m4ac,
|
||||
avctx->extradata, avctx->extradata_size, 8*avctx->extradata_size)) < 0)
|
||||
avctx->extradata, avctx->extradata_size*8, 1)) < 0)
|
||||
return err;
|
||||
latmctx->initialized = 1;
|
||||
}
|
||||
@@ -2553,7 +2569,7 @@ static int latm_decode_frame(AVCodecContext *avctx, void *out, int *out_size,
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
if ((err = aac_decode_frame_int(avctx, out, out_size, &gb)) < 0)
|
||||
if ((err = aac_decode_frame_int(avctx, out, got_frame_ptr, &gb)) < 0)
|
||||
return err;
|
||||
|
||||
return muxlength;
|
||||
@@ -2583,7 +2599,7 @@ AVCodec ff_aac_decoder = {
|
||||
.sample_fmts = (const enum AVSampleFormat[]) {
|
||||
AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE
|
||||
},
|
||||
.capabilities = CODEC_CAP_CHANNEL_CONF,
|
||||
.capabilities = CODEC_CAP_CHANNEL_CONF | CODEC_CAP_DR1,
|
||||
.channel_layouts = aac_channel_layout,
|
||||
};
|
||||
|
||||
@@ -2604,7 +2620,7 @@ AVCodec ff_aac_latm_decoder = {
|
||||
.sample_fmts = (const enum AVSampleFormat[]) {
|
||||
AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE
|
||||
},
|
||||
.capabilities = CODEC_CAP_CHANNEL_CONF,
|
||||
.capabilities = CODEC_CAP_CHANNEL_CONF | CODEC_CAP_DR1,
|
||||
.channel_layouts = aac_channel_layout,
|
||||
.flush = flush,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user