Ticket #1693: ssr_drop_final.patch

File ssr_drop_final.patch, 3.4 KB (added by Dale Curtis, 8 years ago)
  • libavcodec/aacdec_template.c

    From 8c74bf21a35bd5abb6b85d9121fe0842414686fe Mon Sep 17 00:00:00 2001
    From: Dale Curtis <dalecurtis@chromium.org>
    Date: Thu, 15 Feb 2018 16:22:55 -0800
    Subject: [PATCH] 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.
    
    This just pulls in the decode_gain_control() function from the
    ffmpeg summer-of-code repo (original author Robert Swain) at
    svn://svn.mplayerhq.hu/soc/aac/aac.c and adds AOT_AAC_SSR to
    decode_audio_specific_config_gb().
    
    Signed-off-by: Dale Curtis <dalecurtis@chromium.org>
    Co-authored-by: Robert Swain <robert.swain@gmail.com>
    ---
     libavcodec/aacdec_template.c | 49 +++++++++++++++++++++++++++++++++---
     1 file changed, 46 insertions(+), 3 deletions(-)
    
    diff --git a/libavcodec/aacdec_template.c b/libavcodec/aacdec_template.c
    index 6c6cdd84af..4dd521e540 100644
    a b static int decode_audio_specific_config_gb(AACContext *ac,  
    997997    switch (m4ac->object_type) {
    998998    case AOT_AAC_MAIN:
    999999    case AOT_AAC_LC:
     1000    case AOT_AAC_SSR:
    10001001    case AOT_AAC_LTP:
    10011002    case AOT_ER_AAC_LC:
    10021003    case AOT_ER_AAC_LD:
    static void apply_prediction(AACContext *ac, SingleChannelElement *sce)  
    19671968        reset_all_predictors(sce->predictor_state);
    19681969}
    19691970
     1971static int decode_gain_control(SingleChannelElement * sce, GetBitContext * gb)
     1972{
     1973    // wd_num, wd_test, aloc_size
     1974    static const int gain_mode[4][3] = {
     1975        {1, 0, 5},  // ONLY_LONG_SEQUENCE = 0,
     1976        {2, 1, 2},  // LONG_START_SEQUENCE,
     1977        {8, 0, 2},  // EIGHT_SHORT_SEQUENCE,
     1978        {2, 1, 5},  // LONG_STOP_SEQUENCE
     1979    };
     1980
     1981    // per-element gain control for SSR
     1982    struct {
     1983      int max_band;
     1984      int adjust_num[4][8];
     1985      int alev[4][8][8];
     1986      int aloc[4][8][8];
     1987    } ssr;
     1988
     1989    const int mode = sce->ics.window_sequence[0];
     1990    int bd, wd, ad;
     1991
     1992    // FIXME: Store the gain control data on |sce| and do something with it.
     1993    ssr.max_band = get_bits(gb, 2);
     1994    for (bd = 0; bd < ssr.max_band; bd++) {
     1995        for (wd = 0; wd < gain_mode[mode][0]; wd++) {
     1996            ssr.adjust_num[bd][wd] = get_bits(gb, 3);
     1997            for (ad = 0; ad < ssr.adjust_num[bd][wd]; ad++) {
     1998                ssr.alev[bd][wd][ad] = get_bits(gb, 4);
     1999                if (wd == 0 && gain_mode[mode][1])
     2000                    ssr.aloc[bd][wd][ad] = get_bits(gb, 4);
     2001                else
     2002                    ssr.aloc[bd][wd][ad] = get_bits(gb, gain_mode[mode][2]);
     2003            }
     2004        }
     2005    }
     2006    return 0;
     2007}
     2008
    19702009/**
    19712010 * Decode an individual_channel_stream payload; reference: table 4.44.
    19722011 *
    static int decode_ics(AACContext *ac, SingleChannelElement *sce,  
    20342073                goto fail;
    20352074        }
    20362075        if (!eld_syntax && get_bits1(gb)) {
    2037             avpriv_request_sample(ac->avctx, "SSR");
    2038             ret = AVERROR_PATCHWELCOME;
    2039             goto fail;
     2076            // FIXME: Do something with the gain control data...
     2077            ret = decode_gain_control(sce, gb);
     2078            if (ret < 0) {
     2079                ret = AVERROR_PATCHWELCOME;
     2080                avpriv_request_sample(ac->avctx, "SSR");
     2081                goto fail;
     2082            }
    20402083        }
    20412084        // I see no textual basis in the spec for this occurring after SSR gain
    20422085        // control, but this is what both reference and real implmentations do