diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2013-09-19 14:44:06 +0400 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2013-09-19 14:44:06 +0400 |
commit | 257f11820bdf628648466ce07ee0bf67217b543e (patch) | |
tree | f328a91c1c7ba8349981596199484e768d1d2e3f | |
parent | b26ccf218d933660c551832b4b14976b2acb3f0c (diff) | |
parent | 5cdefc02079a5b899bdec09e15e2bb099cb01734 (diff) |
Merge commit '5cdefc02079a5b899bdec09e15e2bb099cb01734'
* commit '5cdefc02079a5b899bdec09e15e2bb099cb01734':
aacdec: Add support for Error Resilience syntax.
Conflicts:
Changelog
libavcodec/aacdec.c
Merged-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r-- | Changelog | 1 | ||||
-rw-r--r-- | libavcodec/aacdec.c | 112 |
2 files changed, 103 insertions, 10 deletions
@@ -27,6 +27,7 @@ version <next> - pullup filter ported from libmpcodecs - ffprobe -read_intervals option - Lossless and alpha support for WebP decoder +- Error Resilient AAC syntax (ER AAC LC) decoding version 2.0: diff --git a/libavcodec/aacdec.c b/libavcodec/aacdec.c index 12e09f02c2..5816054458 100644 --- a/libavcodec/aacdec.c +++ b/libavcodec/aacdec.c @@ -745,7 +745,7 @@ static int decode_ga_specific_config(AACContext *ac, AVCodecContext *avctx, MPEG4AudioConfig *m4ac, int channel_config) { - int extension_flag, ret; + int extension_flag, ret, ep_config, res_flags; uint8_t layout_map[MAX_ELEM_ID*4][3]; int tags = 0; @@ -791,14 +791,30 @@ static int decode_ga_specific_config(AACContext *ac, AVCodecContext *avctx, case AOT_ER_AAC_LTP: case AOT_ER_AAC_SCALABLE: case AOT_ER_AAC_LD: - skip_bits(gb, 3); /* aacSectionDataResilienceFlag - * aacScalefactorDataResilienceFlag - * aacSpectralDataResilienceFlag - */ + res_flags = get_bits(gb, 3); + if (res_flags) { + av_log(avctx, AV_LOG_ERROR, + "AAC data resilience not supported (flags %x)\n", + res_flags); + return AVERROR_PATCHWELCOME; + } break; } skip_bits1(gb); // extensionFlag3 (TBD in version 3) } + switch (m4ac->object_type) { + case AOT_ER_AAC_LC: + case AOT_ER_AAC_LTP: + case AOT_ER_AAC_SCALABLE: + case AOT_ER_AAC_LD: + ep_config = get_bits(gb, 2); + if (ep_config) { + av_log(avctx, AV_LOG_ERROR, + "epConfig %d is not supported.\n", + ep_config); + return AVERROR_PATCHWELCOME; + } + } return 0; } @@ -847,6 +863,7 @@ static int decode_audio_specific_config(AACContext *ac, case AOT_AAC_MAIN: case AOT_AAC_LC: case AOT_AAC_LTP: + case AOT_ER_AAC_LC: if ((ret = decode_ga_specific_config(ac, avctx, &gb, m4ac, m4ac->chan_config)) < 0) return ret; @@ -1127,7 +1144,8 @@ static int decode_ics_info(AACContext *ac, IndividualChannelStream *ics, if (decode_prediction(ac, ics, gb)) { goto fail; } - } else if (ac->oc[1].m4ac.object_type == AOT_AAC_LC) { + } else if (ac->oc[1].m4ac.object_type == AOT_AAC_LC || + ac->oc[1].m4ac.object_type == AOT_ER_AAC_LC) { av_log(ac->avctx, AV_LOG_ERROR, "Prediction is not allowed in AAC-LC.\n"); goto fail; @@ -1752,7 +1770,7 @@ static int decode_ics(AACContext *ac, SingleChannelElement *sce, TemporalNoiseShaping *tns = &sce->tns; IndividualChannelStream *ics = &sce->ics; float *out = sce->coeffs; - int global_gain, pulse_present = 0; + int global_gain, er_syntax, pulse_present = 0; int ret; /* This assignment is to silence a GCC warning about the variable being used @@ -1775,6 +1793,9 @@ static int decode_ics(AACContext *ac, SingleChannelElement *sce, return ret; pulse_present = 0; + er_syntax = ac->oc[1].m4ac.object_type == AOT_ER_AAC_LC || + ac->oc[1].m4ac.object_type == AOT_ER_AAC_LTP || + ac->oc[1].m4ac.object_type == AOT_ER_AAC_LD; if (!scale_flag) { if ((pulse_present = get_bits1(gb))) { if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) { @@ -1788,12 +1809,19 @@ static int decode_ics(AACContext *ac, SingleChannelElement *sce, return AVERROR_INVALIDDATA; } } - if ((tns->present = get_bits1(gb)) && decode_tns(ac, tns, gb, ics)) - return AVERROR_INVALIDDATA; + tns->present = get_bits1(gb); + if (tns->present && !er_syntax) + if (decode_tns(ac, tns, gb, ics) < 0) + return AVERROR_INVALIDDATA; if (get_bits1(gb)) { avpriv_request_sample(ac->avctx, "SSR"); return AVERROR_PATCHWELCOME; } + // I see no textual basis in the spec for this occuring after SSR gain + // control, but this is what both reference and real implmentations do + if (tns->present && er_syntax) + if (decode_tns(ac, tns, gb, ics) < 0) + return AVERROR_INVALIDDATA; } if (decode_spectrum_and_dequant(ac, out, gb, sce->sf, pulse_present, @@ -2562,6 +2590,61 @@ static int parse_adts_frame_header(AACContext *ac, GetBitContext *gb) return size; } +static int aac_decode_er_frame(AVCodecContext *avctx, void *data, + int *got_frame_ptr, GetBitContext *gb) +{ + AACContext *ac = avctx->priv_data; + ChannelElement *che; + int err, i; + int samples = 1024; + int chan_config = ac->oc[1].m4ac.chan_config; + + ac->frame = data; + + if ((err = frame_configure_elements(avctx)) < 0) + return err; + + ac->tags_mapped = 0; + + if (chan_config < 0 || chan_config >= 8) { + avpriv_request_sample(avctx, "Unknown ER channel configuration %d", + ac->oc[1].m4ac.chan_config); + return AVERROR_INVALIDDATA; + } + for (i = 0; i < tags_per_config[chan_config]; i++) { + const int elem_type = aac_channel_layout_map[chan_config-1][i][0]; + const int elem_id = aac_channel_layout_map[chan_config-1][i][1]; + if (!(che=get_che(ac, elem_type, elem_id))) { + av_log(ac->avctx, AV_LOG_ERROR, + "channel element %d.%d is not allocated\n", + elem_type, elem_id); + return AVERROR_INVALIDDATA; + } + skip_bits(gb, 4); + switch (elem_type) { + case TYPE_SCE: + err = decode_ics(ac, &che->ch[0], gb, 0, 0); + break; + case TYPE_CPE: + err = decode_cpe(ac, gb, che); + break; + case TYPE_LFE: + err = decode_ics(ac, &che->ch[0], gb, 0, 0); + break; + } + if (err < 0) + return err; + } + + spectral_to_sample(ac); + + ac->frame->nb_samples = samples; + *got_frame_ptr = 1; + + skip_bits_long(gb, get_bits_left(gb)); + return 0; +} + static int aac_decode_frame_int(AVCodecContext *avctx, void *data, int *got_frame_ptr, GetBitContext *gb, AVPacket *avpkt) { @@ -2769,7 +2852,16 @@ static int aac_decode_frame(AVCodecContext *avctx, void *data, if ((err = init_get_bits(&gb, buf, buf_size * 8)) < 0) return err; - if ((err = aac_decode_frame_int(avctx, data, got_frame_ptr, &gb, avpkt)) < 0) + switch (ac->oc[1].m4ac.object_type) { + case AOT_ER_AAC_LC: + case AOT_ER_AAC_LTP: + case AOT_ER_AAC_LD: + err = aac_decode_er_frame(avctx, data, got_frame_ptr, &gb); + break; + default: + err = aac_decode_frame_int(avctx, data, got_frame_ptr, &gb, avpkt); + } + if (err < 0) return err; buf_consumed = (get_bits_count(&gb) + 7) >> 3; |