summaryrefslogtreecommitdiffstats
path: root/libavcodec/aacdec_template.c
diff options
context:
space:
mode:
authorDale Curtis <dalecurtis@chromium.org>2018-02-15 16:22:55 -0800
committerAlex Converse <alex.converse@gmail.com>2018-02-21 18:17:24 -0800
commita246701e9abe8ef7cb9b0dd9fb5fa877e78334ef (patch)
tree0092f0aacfdabda773e99d757173f567e9e4776a /libavcodec/aacdec_template.c
parentcd98f20b4abac8241ef7f922eb85ba6fe3fe230b (diff)
downloadffmpeg-streaming-a246701e9abe8ef7cb9b0dd9fb5fa877e78334ef.zip
ffmpeg-streaming-a246701e9abe8ef7cb9b0dd9fb5fa877e78334ef.tar.gz
Parse and drop gain control data, so that SSR packets decode.
This will result in poor quality audio for SSR streams, but they will at least demux and decode without error; partially fixing ticket #1693. This pulls in the decode_gain_control() function from the ffmpeg summer-of-code repo (original author Maxim Gavrilov) at svn://svn.mplayerhq.hu/soc/aac/aac.c with some minor modifications and adds AOT_AAC_SSR to decode_audio_specific_config_gb(). Signed-off-by: Dale Curtis <dalecurtis@chromium.org> Co-authored-by: Maxim Gavrilov <maxim.gavrilov@gmail.com>
Diffstat (limited to 'libavcodec/aacdec_template.c')
-rw-r--r--libavcodec/aacdec_template.c36
1 files changed, 33 insertions, 3 deletions
diff --git a/libavcodec/aacdec_template.c b/libavcodec/aacdec_template.c
index c2d9802..cf97181 100644
--- a/libavcodec/aacdec_template.c
+++ b/libavcodec/aacdec_template.c
@@ -997,6 +997,7 @@ static int decode_audio_specific_config_gb(AACContext *ac,
switch (m4ac->object_type) {
case AOT_AAC_MAIN:
case AOT_AAC_LC:
+ case AOT_AAC_SSR:
case AOT_AAC_LTP:
case AOT_ER_AAC_LC:
case AOT_ER_AAC_LD:
@@ -1967,6 +1968,33 @@ static void apply_prediction(AACContext *ac, SingleChannelElement *sce)
reset_all_predictors(sce->predictor_state);
}
+static void decode_gain_control(SingleChannelElement * sce, GetBitContext * gb)
+{
+ // wd_num, wd_test, aloc_size
+ static const uint8_t gain_mode[4][3] = {
+ {1, 0, 5}, // ONLY_LONG_SEQUENCE = 0,
+ {2, 1, 2}, // LONG_START_SEQUENCE,
+ {8, 0, 2}, // EIGHT_SHORT_SEQUENCE,
+ {2, 1, 5}, // LONG_STOP_SEQUENCE
+ };
+
+ const int mode = sce->ics.window_sequence[0];
+ uint8_t bd, wd, ad;
+
+ // FIXME: Store the gain control data on |sce| and do something with it.
+ uint8_t max_band = get_bits(gb, 2);
+ for (bd = 0; bd < max_band; bd++) {
+ for (wd = 0; wd < gain_mode[mode][0]; wd++) {
+ uint8_t adjust_num = get_bits(gb, 3);
+ for (ad = 0; ad < adjust_num; ad++) {
+ skip_bits(gb, 4 + ((wd == 0 && gain_mode[mode][1])
+ ? 4
+ : gain_mode[mode][2]));
+ }
+ }
+ }
+}
+
/**
* Decode an individual_channel_stream payload; reference: table 4.44.
*
@@ -2034,9 +2062,11 @@ static int decode_ics(AACContext *ac, SingleChannelElement *sce,
goto fail;
}
if (!eld_syntax && get_bits1(gb)) {
- avpriv_request_sample(ac->avctx, "SSR");
- ret = AVERROR_PATCHWELCOME;
- goto fail;
+ decode_gain_control(sce, gb);
+ if (!ac->warned_gain_control) {
+ avpriv_report_missing_feature(ac->avctx, "Gain control");
+ ac->warned_gain_control = 1;
+ }
}
// I see no textual basis in the spec for this occurring after SSR gain
// control, but this is what both reference and real implmentations do
OpenPOWER on IntegriCloud