aacdec: add a decoder for AAC USAC (xHE-AAC)
This commit adds a decoder for the frequency-domain part of USAC. What works: - Mono - Stereo (no prediction) - Stereo (mid/side coding) - Stereo (complex prediction) What's left: - SBR - Speech coding Known issues: - Desync with certain sequences - Preroll crossover missing (shouldn't matter, bitrate adaptation only)
This commit is contained in:
		
							parent
							
								
									23b45d7e20
								
							
						
					
					
						commit
						eee5fa0808
					
				@ -2,6 +2,7 @@ clean::
 | 
			
		||||
		$(RM) $(CLEANSUFFIXES:%=libavcodec/aac/%)
 | 
			
		||||
 | 
			
		||||
OBJS-$(CONFIG_AAC_DECODER)          +=  aac/aacdec.o aac/aacdec_tab.o \
 | 
			
		||||
                                        aac/aacdec_float.o
 | 
			
		||||
                                        aac/aacdec_float.o aac/aacdec_usac.o \
 | 
			
		||||
                                        aac/aacdec_ac.o aac/aacdec_lpd.o
 | 
			
		||||
OBJS-$(CONFIG_AAC_FIXED_DECODER)    +=  aac/aacdec.o aac/aacdec_tab.o \
 | 
			
		||||
                                        aac/aacdec_fixed.o
 | 
			
		||||
 | 
			
		||||
@ -40,6 +40,7 @@
 | 
			
		||||
 | 
			
		||||
#include "aacdec.h"
 | 
			
		||||
#include "aacdec_tab.h"
 | 
			
		||||
#include "aacdec_usac.h"
 | 
			
		||||
 | 
			
		||||
#include "libavcodec/aac.h"
 | 
			
		||||
#include "libavcodec/aac_defines.h"
 | 
			
		||||
@ -535,6 +536,8 @@ static av_cold void flush(AVCodecContext *avctx)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ff_aac_usac_reset_state(ac, &ac->oc[1]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -993,13 +996,14 @@ static int decode_eld_specific_config(AACDecContext *ac, AVCodecContext *avctx,
 | 
			
		||||
 */
 | 
			
		||||
static int decode_audio_specific_config_gb(AACDecContext *ac,
 | 
			
		||||
                                           AVCodecContext *avctx,
 | 
			
		||||
                                           MPEG4AudioConfig *m4ac,
 | 
			
		||||
                                           OutputConfiguration *oc,
 | 
			
		||||
                                           GetBitContext *gb,
 | 
			
		||||
                                           int get_bit_alignment,
 | 
			
		||||
                                           int sync_extension)
 | 
			
		||||
{
 | 
			
		||||
    int i, ret;
 | 
			
		||||
    GetBitContext gbc = *gb;
 | 
			
		||||
    MPEG4AudioConfig *m4ac = &oc->m4ac;
 | 
			
		||||
    MPEG4AudioConfig m4ac_bak = *m4ac;
 | 
			
		||||
 | 
			
		||||
    if ((i = ff_mpeg4audio_get_config_gb(m4ac, &gbc, sync_extension, avctx)) < 0) {
 | 
			
		||||
@ -1033,14 +1037,22 @@ static int decode_audio_specific_config_gb(AACDecContext *ac,
 | 
			
		||||
    case AOT_ER_AAC_LC:
 | 
			
		||||
    case AOT_ER_AAC_LD:
 | 
			
		||||
        if ((ret = decode_ga_specific_config(ac, avctx, gb, get_bit_alignment,
 | 
			
		||||
                                            m4ac, m4ac->chan_config)) < 0)
 | 
			
		||||
                                             &oc->m4ac, m4ac->chan_config)) < 0)
 | 
			
		||||
            return ret;
 | 
			
		||||
        break;
 | 
			
		||||
    case AOT_ER_AAC_ELD:
 | 
			
		||||
        if ((ret = decode_eld_specific_config(ac, avctx, gb,
 | 
			
		||||
                                              m4ac, m4ac->chan_config)) < 0)
 | 
			
		||||
                                              &oc->m4ac, m4ac->chan_config)) < 0)
 | 
			
		||||
            return ret;
 | 
			
		||||
        break;
 | 
			
		||||
#if CONFIG_AAC_DECODER
 | 
			
		||||
    case AOT_USAC_NOSBR: /* fallthrough */
 | 
			
		||||
    case AOT_USAC:
 | 
			
		||||
        if ((ret = ff_aac_usac_config_decode(ac, avctx, gb,
 | 
			
		||||
                                             oc, m4ac->chan_config)) < 0)
 | 
			
		||||
            return ret;
 | 
			
		||||
        break;
 | 
			
		||||
#endif
 | 
			
		||||
    default:
 | 
			
		||||
        avpriv_report_missing_feature(avctx,
 | 
			
		||||
                                      "Audio object type %s%d",
 | 
			
		||||
@ -1060,7 +1072,7 @@ static int decode_audio_specific_config_gb(AACDecContext *ac,
 | 
			
		||||
 | 
			
		||||
static int decode_audio_specific_config(AACDecContext *ac,
 | 
			
		||||
                                        AVCodecContext *avctx,
 | 
			
		||||
                                        MPEG4AudioConfig *m4ac,
 | 
			
		||||
                                        OutputConfiguration *oc,
 | 
			
		||||
                                        const uint8_t *data, int64_t bit_size,
 | 
			
		||||
                                        int sync_extension)
 | 
			
		||||
{
 | 
			
		||||
@ -1080,7 +1092,7 @@ static int decode_audio_specific_config(AACDecContext *ac,
 | 
			
		||||
    if ((ret = init_get_bits(&gb, data, bit_size)) < 0)
 | 
			
		||||
        return ret;
 | 
			
		||||
 | 
			
		||||
    return decode_audio_specific_config_gb(ac, avctx, m4ac, &gb, 0,
 | 
			
		||||
    return decode_audio_specific_config_gb(ac, avctx, oc, &gb, 0,
 | 
			
		||||
                                           sync_extension);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1104,6 +1116,15 @@ static av_cold int decode_close(AVCodecContext *avctx)
 | 
			
		||||
{
 | 
			
		||||
    AACDecContext *ac = avctx->priv_data;
 | 
			
		||||
 | 
			
		||||
    for (int i = 0; i < 2; i++) {
 | 
			
		||||
        OutputConfiguration *oc = &ac->oc[i];
 | 
			
		||||
        AACUSACConfig *usac = &oc->usac;
 | 
			
		||||
        for (int j = 0; j < usac->nb_elems; j++) {
 | 
			
		||||
            AACUsacElemConfig *ec = &usac->elems[i];
 | 
			
		||||
            av_freep(&ec->ext.pl_data);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (int type = 0; type < FF_ARRAY_ELEMS(ac->che); type++) {
 | 
			
		||||
        for (int i = 0; i < MAX_ELEM_ID; i++) {
 | 
			
		||||
            if (ac->che[type][i]) {
 | 
			
		||||
@ -1181,7 +1202,7 @@ av_cold int ff_aac_decode_init(AVCodecContext *avctx)
 | 
			
		||||
    ac->oc[1].m4ac.sample_rate = avctx->sample_rate;
 | 
			
		||||
 | 
			
		||||
    if (avctx->extradata_size > 0) {
 | 
			
		||||
        if ((ret = decode_audio_specific_config(ac, ac->avctx, &ac->oc[1].m4ac,
 | 
			
		||||
        if ((ret = decode_audio_specific_config(ac, ac->avctx, &ac->oc[1],
 | 
			
		||||
                                                avctx->extradata,
 | 
			
		||||
                                                avctx->extradata_size * 8LL,
 | 
			
		||||
                                                1)) < 0)
 | 
			
		||||
@ -1549,9 +1570,16 @@ static int decode_pulses(Pulse *pulse, GetBitContext *gb,
 | 
			
		||||
int ff_aac_decode_tns(AACDecContext *ac, TemporalNoiseShaping *tns,
 | 
			
		||||
                      GetBitContext *gb, const IndividualChannelStream *ics)
 | 
			
		||||
{
 | 
			
		||||
    int tns_max_order = INT32_MAX;
 | 
			
		||||
    const int is_usac = ac->oc[1].m4ac.object_type == AOT_USAC ||
 | 
			
		||||
                        ac->oc[1].m4ac.object_type == AOT_USAC_NOSBR;
 | 
			
		||||
    int w, filt, i, coef_len, coef_res, coef_compress;
 | 
			
		||||
    const int is8 = ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE;
 | 
			
		||||
    const int tns_max_order = is8 ? 7 : ac->oc[1].m4ac.object_type == AOT_AAC_MAIN ? 20 : 12;
 | 
			
		||||
 | 
			
		||||
    /* USAC doesn't seem to have a limit */
 | 
			
		||||
    if (!is_usac)
 | 
			
		||||
        tns_max_order = is8 ? 7 : ac->oc[1].m4ac.object_type == AOT_AAC_MAIN ? 20 : 12;
 | 
			
		||||
 | 
			
		||||
    for (w = 0; w < ics->num_windows; w++) {
 | 
			
		||||
        if ((tns->n_filt[w] = get_bits(gb, 2 - is8))) {
 | 
			
		||||
            coef_res = get_bits1(gb);
 | 
			
		||||
@ -1560,7 +1588,12 @@ int ff_aac_decode_tns(AACDecContext *ac, TemporalNoiseShaping *tns,
 | 
			
		||||
                int tmp2_idx;
 | 
			
		||||
                tns->length[w][filt] = get_bits(gb, 6 - 2 * is8);
 | 
			
		||||
 | 
			
		||||
                if ((tns->order[w][filt] = get_bits(gb, 5 - 2 * is8)) > tns_max_order) {
 | 
			
		||||
                if (is_usac)
 | 
			
		||||
                    tns->order[w][filt] = get_bits(gb, 4 - is8);
 | 
			
		||||
                else
 | 
			
		||||
                    tns->order[w][filt] = get_bits(gb, 5 - (2 * is8));
 | 
			
		||||
 | 
			
		||||
                if (tns->order[w][filt] > tns_max_order) {
 | 
			
		||||
                    av_log(ac->avctx, AV_LOG_ERROR,
 | 
			
		||||
                           "TNS filter order %d is greater than maximum %d.\n",
 | 
			
		||||
                           tns->order[w][filt], tns_max_order);
 | 
			
		||||
@ -1598,6 +1631,7 @@ static void decode_mid_side_stereo(ChannelElement *cpe, GetBitContext *gb,
 | 
			
		||||
{
 | 
			
		||||
    int idx;
 | 
			
		||||
    int max_idx = cpe->ch[0].ics.num_window_groups * cpe->ch[0].ics.max_sfb;
 | 
			
		||||
    cpe->max_sfb_ste = cpe->ch[0].ics.max_sfb;
 | 
			
		||||
    if (ms_present == 1) {
 | 
			
		||||
        for (idx = 0; idx < max_idx; idx++)
 | 
			
		||||
            cpe->ms_mask[idx] = get_bits1(gb);
 | 
			
		||||
@ -2182,42 +2216,19 @@ static int aac_decode_er_frame(AVCodecContext *avctx, AVFrame *frame,
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int aac_decode_frame_int(AVCodecContext *avctx, AVFrame *frame,
 | 
			
		||||
                                int *got_frame_ptr, GetBitContext *gb,
 | 
			
		||||
                                const AVPacket *avpkt)
 | 
			
		||||
static int decode_frame_ga(AVCodecContext *avctx, AACDecContext *ac,
 | 
			
		||||
                           GetBitContext *gb, int *got_frame_ptr)
 | 
			
		||||
{
 | 
			
		||||
    AACDecContext *ac = avctx->priv_data;
 | 
			
		||||
    ChannelElement *che = NULL, *che_prev = NULL;
 | 
			
		||||
    int err;
 | 
			
		||||
    int is_dmono;
 | 
			
		||||
    int elem_id;
 | 
			
		||||
    enum RawDataBlockType elem_type, che_prev_type = TYPE_END;
 | 
			
		||||
    int err, elem_id;
 | 
			
		||||
    int samples = 0, multiplier, audio_found = 0, pce_found = 0;
 | 
			
		||||
    int is_dmono, sce_count = 0;
 | 
			
		||||
    int payload_alignment;
 | 
			
		||||
    uint8_t che_presence[4][MAX_ELEM_ID] = {{0}};
 | 
			
		||||
    ChannelElement *che = NULL, *che_prev = NULL;
 | 
			
		||||
    int samples = 0, multiplier, audio_found = 0, pce_found = 0, sce_count = 0;
 | 
			
		||||
    AVFrame *frame = ac->frame;
 | 
			
		||||
 | 
			
		||||
    ac->frame = frame;
 | 
			
		||||
 | 
			
		||||
    if (show_bits(gb, 12) == 0xfff) {
 | 
			
		||||
        if ((err = parse_adts_frame_header(ac, gb)) < 0) {
 | 
			
		||||
            av_log(avctx, AV_LOG_ERROR, "Error decoding AAC frame header.\n");
 | 
			
		||||
            goto fail;
 | 
			
		||||
        }
 | 
			
		||||
        if (ac->oc[1].m4ac.sampling_index > 12) {
 | 
			
		||||
            av_log(ac->avctx, AV_LOG_ERROR, "invalid sampling rate index %d\n", ac->oc[1].m4ac.sampling_index);
 | 
			
		||||
            err = AVERROR_INVALIDDATA;
 | 
			
		||||
            goto fail;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ((err = frame_configure_elements(avctx)) < 0)
 | 
			
		||||
        goto fail;
 | 
			
		||||
 | 
			
		||||
    // The AV_PROFILE_AAC_* defines are all object_type - 1
 | 
			
		||||
    // This may lead to an undefined profile being signaled
 | 
			
		||||
    ac->avctx->profile = ac->oc[1].m4ac.object_type - 1;
 | 
			
		||||
 | 
			
		||||
    payload_alignment = get_bits_count(gb);
 | 
			
		||||
    ac->tags_mapped = 0;
 | 
			
		||||
    int payload_alignment = get_bits_count(gb);
 | 
			
		||||
    // parse
 | 
			
		||||
    while ((elem_type = get_bits(gb, 3)) != TYPE_END) {
 | 
			
		||||
        elem_id = get_bits(gb, 4);
 | 
			
		||||
@ -2225,28 +2236,23 @@ static int aac_decode_frame_int(AVCodecContext *avctx, AVFrame *frame,
 | 
			
		||||
        if (avctx->debug & FF_DEBUG_STARTCODE)
 | 
			
		||||
            av_log(avctx, AV_LOG_DEBUG, "Elem type:%x id:%x\n", elem_type, elem_id);
 | 
			
		||||
 | 
			
		||||
        if (!avctx->ch_layout.nb_channels && elem_type != TYPE_PCE) {
 | 
			
		||||
            err = AVERROR_INVALIDDATA;
 | 
			
		||||
            goto fail;
 | 
			
		||||
        }
 | 
			
		||||
        if (!avctx->ch_layout.nb_channels && elem_type != TYPE_PCE)
 | 
			
		||||
            return AVERROR_INVALIDDATA;
 | 
			
		||||
 | 
			
		||||
        if (elem_type < TYPE_DSE) {
 | 
			
		||||
            if (che_presence[elem_type][elem_id]) {
 | 
			
		||||
                int error = che_presence[elem_type][elem_id] > 1;
 | 
			
		||||
                av_log(ac->avctx, error ? AV_LOG_ERROR : AV_LOG_DEBUG, "channel element %d.%d duplicate\n",
 | 
			
		||||
                       elem_type, elem_id);
 | 
			
		||||
                if (error) {
 | 
			
		||||
                    err = AVERROR_INVALIDDATA;
 | 
			
		||||
                    goto fail;
 | 
			
		||||
                }
 | 
			
		||||
                if (error)
 | 
			
		||||
                    return AVERROR_INVALIDDATA;
 | 
			
		||||
            }
 | 
			
		||||
            che_presence[elem_type][elem_id]++;
 | 
			
		||||
 | 
			
		||||
            if (!(che=ff_aac_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);
 | 
			
		||||
                err = AVERROR_INVALIDDATA;
 | 
			
		||||
                goto fail;
 | 
			
		||||
                return AVERROR_INVALIDDATA;
 | 
			
		||||
            }
 | 
			
		||||
            samples = ac->oc[1].m4ac.frame_length_short ? 960 : 1024;
 | 
			
		||||
            che->present = 1;
 | 
			
		||||
@ -2283,10 +2289,8 @@ static int aac_decode_frame_int(AVCodecContext *avctx, AVFrame *frame,
 | 
			
		||||
            int tags;
 | 
			
		||||
 | 
			
		||||
            int pushed = push_output_configuration(ac);
 | 
			
		||||
            if (pce_found && !pushed) {
 | 
			
		||||
                err = AVERROR_INVALIDDATA;
 | 
			
		||||
                goto fail;
 | 
			
		||||
            }
 | 
			
		||||
            if (pce_found && !pushed)
 | 
			
		||||
                return AVERROR_INVALIDDATA;
 | 
			
		||||
 | 
			
		||||
            tags = decode_pce(avctx, &ac->oc[1].m4ac, layout_map, gb,
 | 
			
		||||
                              payload_alignment);
 | 
			
		||||
@ -2312,8 +2316,7 @@ static int aac_decode_frame_int(AVCodecContext *avctx, AVFrame *frame,
 | 
			
		||||
                elem_id += get_bits(gb, 8) - 1;
 | 
			
		||||
            if (get_bits_left(gb) < 8 * elem_id) {
 | 
			
		||||
                    av_log(avctx, AV_LOG_ERROR, "TYPE_FIL: "overread_err);
 | 
			
		||||
                    err = AVERROR_INVALIDDATA;
 | 
			
		||||
                    goto fail;
 | 
			
		||||
                    return AVERROR_INVALIDDATA;
 | 
			
		||||
            }
 | 
			
		||||
            err = 0;
 | 
			
		||||
            while (elem_id > 0) {
 | 
			
		||||
@ -2337,19 +2340,16 @@ static int aac_decode_frame_int(AVCodecContext *avctx, AVFrame *frame,
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (err)
 | 
			
		||||
            goto fail;
 | 
			
		||||
            return err;
 | 
			
		||||
 | 
			
		||||
        if (get_bits_left(gb) < 3) {
 | 
			
		||||
            av_log(avctx, AV_LOG_ERROR, overread_err);
 | 
			
		||||
            err = AVERROR_INVALIDDATA;
 | 
			
		||||
            goto fail;
 | 
			
		||||
            return AVERROR_INVALIDDATA;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!avctx->ch_layout.nb_channels) {
 | 
			
		||||
        *got_frame_ptr = 0;
 | 
			
		||||
    if (!avctx->ch_layout.nb_channels)
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    multiplier = (ac->oc[1].m4ac.sbr == 1) ? ac->oc[1].m4ac.ext_sample_rate > ac->oc[1].m4ac.sample_rate : 0;
 | 
			
		||||
    samples <<= multiplier;
 | 
			
		||||
@ -2364,16 +2364,17 @@ static int aac_decode_frame_int(AVCodecContext *avctx, AVFrame *frame,
 | 
			
		||||
 | 
			
		||||
    if (!ac->frame->data[0] && samples) {
 | 
			
		||||
        av_log(avctx, AV_LOG_ERROR, "no frame data found\n");
 | 
			
		||||
        err = AVERROR_INVALIDDATA;
 | 
			
		||||
        goto fail;
 | 
			
		||||
        return AVERROR_INVALIDDATA;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (samples) {
 | 
			
		||||
        ac->frame->nb_samples = samples;
 | 
			
		||||
        ac->frame->sample_rate = avctx->sample_rate;
 | 
			
		||||
    } else
 | 
			
		||||
        *got_frame_ptr = 1;
 | 
			
		||||
    } else {
 | 
			
		||||
        av_frame_unref(ac->frame);
 | 
			
		||||
    *got_frame_ptr = !!samples;
 | 
			
		||||
        *got_frame_ptr = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* for dual-mono audio (SCE + SCE) */
 | 
			
		||||
    is_dmono = ac->dmono_mode && sce_count == 2 &&
 | 
			
		||||
@ -2387,6 +2388,59 @@ static int aac_decode_frame_int(AVCodecContext *avctx, AVFrame *frame,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int aac_decode_frame_int(AVCodecContext *avctx, AVFrame *frame,
 | 
			
		||||
                                int *got_frame_ptr, GetBitContext *gb,
 | 
			
		||||
                                const AVPacket *avpkt)
 | 
			
		||||
{
 | 
			
		||||
    int err;
 | 
			
		||||
    AACDecContext *ac = avctx->priv_data;
 | 
			
		||||
 | 
			
		||||
    ac->frame = frame;
 | 
			
		||||
    *got_frame_ptr = 0;
 | 
			
		||||
 | 
			
		||||
    if (show_bits(gb, 12) == 0xfff) {
 | 
			
		||||
        if ((err = parse_adts_frame_header(ac, gb)) < 0) {
 | 
			
		||||
            av_log(avctx, AV_LOG_ERROR, "Error decoding AAC frame header.\n");
 | 
			
		||||
            goto fail;
 | 
			
		||||
        }
 | 
			
		||||
        if (ac->oc[1].m4ac.sampling_index > 12) {
 | 
			
		||||
            av_log(ac->avctx, AV_LOG_ERROR, "invalid sampling rate index %d\n", ac->oc[1].m4ac.sampling_index);
 | 
			
		||||
            err = AVERROR_INVALIDDATA;
 | 
			
		||||
            goto fail;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ((err = frame_configure_elements(avctx)) < 0)
 | 
			
		||||
        goto fail;
 | 
			
		||||
 | 
			
		||||
    // The AV_PROFILE_AAC_* defines are all object_type - 1
 | 
			
		||||
    // This may lead to an undefined profile being signaled
 | 
			
		||||
    ac->avctx->profile = ac->oc[1].m4ac.object_type - 1;
 | 
			
		||||
 | 
			
		||||
    ac->tags_mapped = 0;
 | 
			
		||||
 | 
			
		||||
    if ((ac->oc[1].m4ac.object_type == AOT_USAC) ||
 | 
			
		||||
        (ac->oc[1].m4ac.object_type == AOT_USAC_NOSBR)) {
 | 
			
		||||
        if (ac->is_fixed) {
 | 
			
		||||
            avpriv_report_missing_feature(ac->avctx,
 | 
			
		||||
                                          "AAC USAC fixed-point decoding");
 | 
			
		||||
            return AVERROR_PATCHWELCOME;
 | 
			
		||||
        }
 | 
			
		||||
#if CONFIG_AAC_DECODER
 | 
			
		||||
        err = ff_aac_usac_decode_frame(avctx, ac, gb, got_frame_ptr);
 | 
			
		||||
        if (err < 0)
 | 
			
		||||
            goto fail;
 | 
			
		||||
#endif
 | 
			
		||||
    } else {
 | 
			
		||||
        err = decode_frame_ga(avctx, ac, gb, got_frame_ptr);
 | 
			
		||||
        if (err < 0)
 | 
			
		||||
            goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return err;
 | 
			
		||||
 | 
			
		||||
fail:
 | 
			
		||||
    pop_output_configuration(ac);
 | 
			
		||||
    return err;
 | 
			
		||||
@ -2414,7 +2468,7 @@ static int aac_decode_frame(AVCodecContext *avctx, AVFrame *frame,
 | 
			
		||||
    if (new_extradata) {
 | 
			
		||||
        /* discard previous configuration */
 | 
			
		||||
        ac->oc[1].status = OC_NONE;
 | 
			
		||||
        err = decode_audio_specific_config(ac, ac->avctx, &ac->oc[1].m4ac,
 | 
			
		||||
        err = decode_audio_specific_config(ac, ac->avctx, &ac->oc[1],
 | 
			
		||||
                                           new_extradata,
 | 
			
		||||
                                           new_extradata_size * 8LL, 1);
 | 
			
		||||
        if (err < 0) {
 | 
			
		||||
 | 
			
		||||
@ -42,6 +42,8 @@
 | 
			
		||||
#include "libavcodec/avcodec.h"
 | 
			
		||||
#include "libavcodec/mpeg4audio.h"
 | 
			
		||||
 | 
			
		||||
#include "aacdec_ac.h"
 | 
			
		||||
 | 
			
		||||
typedef struct AACDecContext AACDecContext;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -69,6 +71,32 @@ enum CouplingPoint {
 | 
			
		||||
    AFTER_IMDCT = 3,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum AACUsacElem {
 | 
			
		||||
    ID_USAC_SCE = 0,
 | 
			
		||||
    ID_USAC_CPE = 1,
 | 
			
		||||
    ID_USAC_LFE = 2,
 | 
			
		||||
    ID_USAC_EXT = 3,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum ExtensionHeaderType {
 | 
			
		||||
    ID_CONFIG_EXT_FILL = 0,
 | 
			
		||||
    ID_CONFIG_EXT_LOUDNESS_INFO = 2,
 | 
			
		||||
    ID_CONFIG_EXT_STREAM_ID = 7,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum AACUsacExtension {
 | 
			
		||||
    ID_EXT_ELE_FILL,
 | 
			
		||||
    ID_EXT_ELE_MPEGS,
 | 
			
		||||
    ID_EXT_ELE_SAOC,
 | 
			
		||||
    ID_EXT_ELE_AUDIOPREROLL,
 | 
			
		||||
    ID_EXT_ELE_UNI_DRC,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum AACUSACLoudnessExt {
 | 
			
		||||
    UNIDRCLOUDEXT_TERM = 0x0,
 | 
			
		||||
    UNIDRCLOUDEXT_EQ = 0x1,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Supposed to be equal to AAC_RENAME() in case of USE_FIXED.
 | 
			
		||||
#define RENAME_FIXED(name) name ## _fixed
 | 
			
		||||
 | 
			
		||||
@ -93,6 +121,40 @@ typedef struct LongTermPrediction {
 | 
			
		||||
    int8_t used[MAX_LTP_LONG_SFB];
 | 
			
		||||
} LongTermPrediction;
 | 
			
		||||
 | 
			
		||||
/* Per channel core mode */
 | 
			
		||||
typedef struct AACUsacElemData {
 | 
			
		||||
    uint8_t core_mode;
 | 
			
		||||
    uint8_t scale_factor_grouping;
 | 
			
		||||
 | 
			
		||||
    /* Timewarping ratio */
 | 
			
		||||
#define NUM_TW_NODES 16
 | 
			
		||||
    uint8_t tw_ratio[NUM_TW_NODES];
 | 
			
		||||
 | 
			
		||||
    struct {
 | 
			
		||||
        uint8_t acelp_core_mode : 3;
 | 
			
		||||
        uint8_t lpd_mode : 5;
 | 
			
		||||
 | 
			
		||||
        uint8_t bpf_control_info : 1;
 | 
			
		||||
        uint8_t core_mode_last : 1;
 | 
			
		||||
        uint8_t fac_data_present : 1;
 | 
			
		||||
 | 
			
		||||
        int last_lpd_mode;
 | 
			
		||||
    } ldp;
 | 
			
		||||
 | 
			
		||||
    struct {
 | 
			
		||||
        unsigned int seed;
 | 
			
		||||
        uint8_t level : 3;
 | 
			
		||||
        uint8_t offset : 5;
 | 
			
		||||
    } noise;
 | 
			
		||||
 | 
			
		||||
    struct {
 | 
			
		||||
        uint8_t gain;
 | 
			
		||||
        uint32_t kv[8 /* (1024 / 16) / 8 */][8];
 | 
			
		||||
    } fac;
 | 
			
		||||
 | 
			
		||||
    AACArithState ac;
 | 
			
		||||
} AACUsacElemData;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Individual Channel Stream
 | 
			
		||||
 */
 | 
			
		||||
@ -145,11 +207,13 @@ typedef struct ChannelCoupling {
 | 
			
		||||
 */
 | 
			
		||||
typedef struct SingleChannelElement {
 | 
			
		||||
    IndividualChannelStream ics;
 | 
			
		||||
    AACUsacElemData ue;                             ///< USAC element data
 | 
			
		||||
    TemporalNoiseShaping tns;
 | 
			
		||||
    enum BandType band_type[128];                   ///< band types
 | 
			
		||||
    int sfo[128];                                   ///< scalefactor offsets
 | 
			
		||||
    INTFLOAT_UNION(sf, [128]);                      ///< scalefactors (8 windows * 16 sfb max)
 | 
			
		||||
    INTFLOAT_ALIGNED_UNION(32, coeffs,    1024);    ///< coefficients for IMDCT, maybe processed
 | 
			
		||||
    INTFLOAT_ALIGNED_UNION(32, prev_coeffs, 1024);  ///< unscaled previous contents of coeffs[] for USAC
 | 
			
		||||
    INTFLOAT_ALIGNED_UNION(32, saved,     1536);    ///< overlap
 | 
			
		||||
    INTFLOAT_ALIGNED_UNION(32, ret_buf,   2048);    ///< PCM output buffer
 | 
			
		||||
    INTFLOAT_ALIGNED_UNION(16, ltp_state, 3072);    ///< time signal for LTP
 | 
			
		||||
@ -163,25 +227,148 @@ typedef struct SingleChannelElement {
 | 
			
		||||
    };
 | 
			
		||||
} SingleChannelElement;
 | 
			
		||||
 | 
			
		||||
typedef struct AACUsacStereo {
 | 
			
		||||
    uint8_t common_window;
 | 
			
		||||
    uint8_t common_tw;
 | 
			
		||||
 | 
			
		||||
    uint8_t ms_mask_mode;
 | 
			
		||||
    uint8_t config_idx;
 | 
			
		||||
 | 
			
		||||
    /* Complex prediction */
 | 
			
		||||
    uint8_t use_prev_frame;
 | 
			
		||||
    uint8_t pred_dir;
 | 
			
		||||
    uint8_t complex_coef;
 | 
			
		||||
 | 
			
		||||
    uint8_t pred_used[128];
 | 
			
		||||
 | 
			
		||||
    INTFLOAT_ALIGNED_UNION(32, alpha_q_re, 1024);
 | 
			
		||||
    INTFLOAT_ALIGNED_UNION(32, alpha_q_im, 1024);
 | 
			
		||||
    INTFLOAT_ALIGNED_UNION(32, prev_alpha_q_re, 1024);
 | 
			
		||||
    INTFLOAT_ALIGNED_UNION(32, prev_alpha_q_im, 1024);
 | 
			
		||||
 | 
			
		||||
    INTFLOAT_ALIGNED_UNION(32, dmix_re, 1024);
 | 
			
		||||
    INTFLOAT_ALIGNED_UNION(32, prev_dmix_re, 1024); /* Recalculated on every frame */
 | 
			
		||||
    INTFLOAT_ALIGNED_UNION(32, dmix_im, 1024); /* Final prediction data */
 | 
			
		||||
} AACUsacStereo;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * channel element - generic struct for SCE/CPE/CCE/LFE
 | 
			
		||||
 */
 | 
			
		||||
typedef struct ChannelElement {
 | 
			
		||||
    int present;
 | 
			
		||||
    // CPE specific
 | 
			
		||||
    uint8_t max_sfb_ste;      ///< (USAC) Maximum of both max_sfb values
 | 
			
		||||
    uint8_t ms_mask[128];     ///< Set if mid/side stereo is used for each scalefactor window band
 | 
			
		||||
    // shared
 | 
			
		||||
    SingleChannelElement ch[2];
 | 
			
		||||
    // CCE specific
 | 
			
		||||
    ChannelCoupling coup;
 | 
			
		||||
    // USAC stereo coupling data
 | 
			
		||||
    AACUsacStereo us;
 | 
			
		||||
} ChannelElement;
 | 
			
		||||
 | 
			
		||||
typedef struct AACUSACLoudnessInfo {
 | 
			
		||||
    uint8_t drc_set_id : 6;
 | 
			
		||||
    uint8_t downmix_id : 7;
 | 
			
		||||
    struct {
 | 
			
		||||
        uint16_t lvl : 12;
 | 
			
		||||
        uint8_t present : 1;
 | 
			
		||||
    } sample_peak;
 | 
			
		||||
 | 
			
		||||
    struct {
 | 
			
		||||
        uint16_t lvl : 12;
 | 
			
		||||
        uint8_t measurement : 4;
 | 
			
		||||
        uint8_t reliability : 2;
 | 
			
		||||
        uint8_t present : 1;
 | 
			
		||||
    } true_peak;
 | 
			
		||||
 | 
			
		||||
    uint8_t nb_measurements : 4;
 | 
			
		||||
    struct {
 | 
			
		||||
        uint8_t method_def : 4;
 | 
			
		||||
        uint8_t method_val;
 | 
			
		||||
        uint8_t measurement : 4;
 | 
			
		||||
        uint8_t reliability : 2;
 | 
			
		||||
    } measurements[16];
 | 
			
		||||
} AACUSACLoudnessInfo;
 | 
			
		||||
 | 
			
		||||
typedef struct AACUsacElemConfig {
 | 
			
		||||
    enum AACUsacElem type;
 | 
			
		||||
 | 
			
		||||
    uint8_t tw_mdct : 1;
 | 
			
		||||
    uint8_t noise_fill : 1;
 | 
			
		||||
 | 
			
		||||
    uint8_t stereo_config_index;
 | 
			
		||||
 | 
			
		||||
    struct {
 | 
			
		||||
        int ratio;
 | 
			
		||||
 | 
			
		||||
        uint8_t harmonic_sbr : 1; /* harmonicSBR */
 | 
			
		||||
        uint8_t bs_intertes : 1; /* bs_interTes */
 | 
			
		||||
        uint8_t bs_pvc : 1; /* bs_pvc */
 | 
			
		||||
 | 
			
		||||
        struct {
 | 
			
		||||
            uint8_t start_freq; /* dflt_start_freq */
 | 
			
		||||
            uint8_t stop_freq; /* dflt_stop_freq */
 | 
			
		||||
 | 
			
		||||
            uint8_t freq_scale; /* dflt_freq_scale */
 | 
			
		||||
            uint8_t alter_scale : 1; /* dflt_alter_scale */
 | 
			
		||||
            uint8_t noise_scale; /* dflt_noise_scale */
 | 
			
		||||
 | 
			
		||||
            uint8_t limiter_bands; /* dflt_limiter_bands */
 | 
			
		||||
            uint8_t limiter_gains; /* dflt_limiter_gains */
 | 
			
		||||
            uint8_t interpol_freq : 1; /* dflt_interpol_freq */
 | 
			
		||||
            uint8_t smoothing_mode : 1; /* dflt_smoothing_mode */
 | 
			
		||||
        } dflt;
 | 
			
		||||
    } sbr;
 | 
			
		||||
 | 
			
		||||
    struct {
 | 
			
		||||
        uint8_t freq_res; /* bsFreqRes */
 | 
			
		||||
        uint8_t fixed_gain; /* bsFixedGainDMX */
 | 
			
		||||
        uint8_t temp_shape_config; /* bsTempShapeConfig */
 | 
			
		||||
        uint8_t decorr_config; /* bsDecorrConfig */
 | 
			
		||||
        uint8_t high_rate_mode : 1; /* bsHighRateMode */
 | 
			
		||||
        uint8_t phase_coding : 1; /* bsPhaseCoding */
 | 
			
		||||
 | 
			
		||||
        uint8_t otts_bands_phase; /* bsOttBandsPhase */
 | 
			
		||||
        uint8_t residual_coding; /* bsResidualCoding */
 | 
			
		||||
        uint8_t residual_bands; /* bsResidualBands */
 | 
			
		||||
        uint8_t pseudo_lr : 1; /* bsPseudoLr */
 | 
			
		||||
        uint8_t env_quant_mode : 1; /* bsEnvQuantMode */
 | 
			
		||||
    } mps;
 | 
			
		||||
 | 
			
		||||
    struct {
 | 
			
		||||
        enum AACUsacExtension type;
 | 
			
		||||
        uint8_t payload_frag;
 | 
			
		||||
        uint32_t default_len;
 | 
			
		||||
        uint32_t pl_data_offset;
 | 
			
		||||
        uint8_t *pl_data;
 | 
			
		||||
    } ext;
 | 
			
		||||
} AACUsacElemConfig;
 | 
			
		||||
 | 
			
		||||
typedef struct AACUSACConfig {
 | 
			
		||||
    uint8_t core_sbr_frame_len_idx; /* coreSbrFrameLengthIndex */
 | 
			
		||||
    uint8_t rate_idx;
 | 
			
		||||
    uint16_t core_frame_len;
 | 
			
		||||
    uint16_t stream_identifier;
 | 
			
		||||
 | 
			
		||||
    AACUsacElemConfig elems[64];
 | 
			
		||||
    int nb_elems;
 | 
			
		||||
 | 
			
		||||
    struct {
 | 
			
		||||
        uint8_t nb_album;
 | 
			
		||||
        AACUSACLoudnessInfo album_info[64];
 | 
			
		||||
        uint8_t nb_info;
 | 
			
		||||
        AACUSACLoudnessInfo info[64];
 | 
			
		||||
    } loudness;
 | 
			
		||||
} AACUSACConfig;
 | 
			
		||||
 | 
			
		||||
typedef struct OutputConfiguration {
 | 
			
		||||
    MPEG4AudioConfig m4ac;
 | 
			
		||||
    uint8_t layout_map[MAX_ELEM_ID*4][3];
 | 
			
		||||
    int layout_map_tags;
 | 
			
		||||
    AVChannelLayout ch_layout;
 | 
			
		||||
    enum OCStatus status;
 | 
			
		||||
    AACUSACConfig usac;
 | 
			
		||||
} OutputConfiguration;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										208
									
								
								libavcodec/aac/aacdec_ac.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										208
									
								
								libavcodec/aac/aacdec_ac.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,208 @@
 | 
			
		||||
/*
 | 
			
		||||
 * AAC definitions and structures
 | 
			
		||||
 * Copyright (c) 2024 Lynne
 | 
			
		||||
 *
 | 
			
		||||
 * This file is part of FFmpeg.
 | 
			
		||||
 *
 | 
			
		||||
 * FFmpeg is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2.1 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * FFmpeg is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with FFmpeg; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "libavcodec/aactab.h"
 | 
			
		||||
#include "aacdec_ac.h"
 | 
			
		||||
 | 
			
		||||
uint32_t ff_aac_ac_map_process(AACArithState *state, int reset, int N)
 | 
			
		||||
{
 | 
			
		||||
    float ratio;
 | 
			
		||||
    if (reset) {
 | 
			
		||||
        memset(state->last, 0, sizeof(state->last));
 | 
			
		||||
        state->last_len = N;
 | 
			
		||||
    } else if (state->last_len != N) {
 | 
			
		||||
        int i;
 | 
			
		||||
        uint8_t last[512 /* 2048 / 4 */];
 | 
			
		||||
        memcpy(last, state->last, sizeof(last));
 | 
			
		||||
 | 
			
		||||
        ratio = state->last_len / (float)N;
 | 
			
		||||
        for (i = 0; i < N/2; i++) {
 | 
			
		||||
            int k = (int)(i * ratio);
 | 
			
		||||
            state->last[i] = last[k];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (; i < FF_ARRAY_ELEMS(state->last); i++)
 | 
			
		||||
            state->last[i] = 0;
 | 
			
		||||
 | 
			
		||||
        state->last_len = N;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    state->cur[3] = 0;
 | 
			
		||||
    state->cur[2] = 0;
 | 
			
		||||
    state->cur[1] = 0;
 | 
			
		||||
    state->cur[0] = 1;
 | 
			
		||||
 | 
			
		||||
    state->state_pre = state->last[0] << 12;
 | 
			
		||||
    return state->last[0] << 12;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t ff_aac_ac_get_context(AACArithState *state, uint32_t c, int i, int N)
 | 
			
		||||
{
 | 
			
		||||
    c = state->state_pre >> 8;
 | 
			
		||||
    c = c + (state->last[i + 1] << 8);
 | 
			
		||||
    c = (c << 4);
 | 
			
		||||
    c += state->cur[1];
 | 
			
		||||
 | 
			
		||||
    state->state_pre = c;
 | 
			
		||||
 | 
			
		||||
    if (i > 3 &&
 | 
			
		||||
        ((state->cur[3] + state->cur[2] + state->cur[1]) < 5))
 | 
			
		||||
        return c + 0x10000;
 | 
			
		||||
 | 
			
		||||
    return c;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t ff_aac_ac_get_pk(uint32_t c)
 | 
			
		||||
{
 | 
			
		||||
    int i_min = -1;
 | 
			
		||||
    int i, j;
 | 
			
		||||
    int i_max = FF_ARRAY_ELEMS(ff_aac_ac_lookup_m) - 1;
 | 
			
		||||
    while ((i_max - i_min) > 1) {
 | 
			
		||||
        i = i_min + ((i_max - i_min) / 2);
 | 
			
		||||
        j = ff_aac_ac_hash_m[i];
 | 
			
		||||
        if (c < (j >> 8))
 | 
			
		||||
            i_max = i;
 | 
			
		||||
        else if (c > (j >> 8))
 | 
			
		||||
            i_min = i;
 | 
			
		||||
        else
 | 
			
		||||
            return (j & 0xFF);
 | 
			
		||||
    }
 | 
			
		||||
    return ff_aac_ac_lookup_m[i_max];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ff_aac_ac_update_context(AACArithState *state, int idx,
 | 
			
		||||
                              uint16_t a, uint16_t b)
 | 
			
		||||
{
 | 
			
		||||
    state->cur[0] = a + b + 1;
 | 
			
		||||
    if (state->cur[0] > 0xF)
 | 
			
		||||
        state->cur[0] = 0xF;
 | 
			
		||||
 | 
			
		||||
    state->cur[3] = state->cur[2];
 | 
			
		||||
    state->cur[2] = state->cur[1];
 | 
			
		||||
    state->cur[1] = state->cur[0];
 | 
			
		||||
 | 
			
		||||
    state->last[idx] = state->cur[0];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Initialize AC */
 | 
			
		||||
void ff_aac_ac_init(AACArith *ac, GetBitContext *gb)
 | 
			
		||||
{
 | 
			
		||||
    ac->low = 0;
 | 
			
		||||
    ac->high = UINT16_MAX;
 | 
			
		||||
    ac->val = get_bits(gb, 16);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint16_t ff_aac_ac_decode(AACArith *ac, GetBitContext *gb,
 | 
			
		||||
                          const uint16_t *cdf, uint16_t cdf_len)
 | 
			
		||||
{
 | 
			
		||||
    int val = ac->val;
 | 
			
		||||
    int low = ac->low;
 | 
			
		||||
    int high = ac->high;
 | 
			
		||||
 | 
			
		||||
    int sym;
 | 
			
		||||
    int rng = high - low + 1;
 | 
			
		||||
    int c = ((((int)(val - low + 1)) << 14) - ((int)1));
 | 
			
		||||
 | 
			
		||||
    const uint16_t *p = cdf - 1;
 | 
			
		||||
 | 
			
		||||
    /* One for each possible CDF length in the spec */
 | 
			
		||||
    switch (cdf_len) {
 | 
			
		||||
    case 2:
 | 
			
		||||
        if ((p[1] * rng) > c)
 | 
			
		||||
            p += 1;
 | 
			
		||||
        break;
 | 
			
		||||
    case 4:
 | 
			
		||||
        if ((p[2] * rng) > c)
 | 
			
		||||
            p += 2;
 | 
			
		||||
        if ((p[1] * rng) > c)
 | 
			
		||||
            p += 1;
 | 
			
		||||
        break;
 | 
			
		||||
    case 17:
 | 
			
		||||
        /* First check if the current probability is even met at all */
 | 
			
		||||
        if ((p[1] * rng) <= c)
 | 
			
		||||
            break;
 | 
			
		||||
        p += 1;
 | 
			
		||||
        for (int i = 8; i >= 1; i >>= 1)
 | 
			
		||||
            if ((p[i] * rng) > c)
 | 
			
		||||
                p += i;
 | 
			
		||||
        break;
 | 
			
		||||
    case 27:
 | 
			
		||||
        if ((p[16] * rng) > c)
 | 
			
		||||
            p += 16;
 | 
			
		||||
        if ((p[8] * rng) > c)
 | 
			
		||||
            p += 8;
 | 
			
		||||
        if (p != (cdf - 1 + 24))
 | 
			
		||||
            if ((p[4] * rng) > c)
 | 
			
		||||
                p += 4;
 | 
			
		||||
        if ((p[2] * rng) > c)
 | 
			
		||||
            p += 2;
 | 
			
		||||
 | 
			
		||||
        if (p != (cdf - 1 + 24 + 2))
 | 
			
		||||
            if ((p[1] * rng) > c)
 | 
			
		||||
                p += 1;
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        /* This should never happen */
 | 
			
		||||
        av_assert2(0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    sym = (int)((ptrdiff_t)(p - cdf)) + 1;
 | 
			
		||||
    if (sym)
 | 
			
		||||
        high = low + ((rng * cdf[sym - 1]) >> 14) - 1;
 | 
			
		||||
    low += (rng * cdf[sym]) >> 14;
 | 
			
		||||
 | 
			
		||||
    /* This loop could be done faster */
 | 
			
		||||
    while (1) {
 | 
			
		||||
        if (high < 32768) {
 | 
			
		||||
            ;
 | 
			
		||||
        } else if (low >= 32768) {
 | 
			
		||||
            val -= 32768;
 | 
			
		||||
            low -= 32768;
 | 
			
		||||
            high -= 32768;
 | 
			
		||||
        } else if (low >= 16384 && high < 49152) {
 | 
			
		||||
            val -= 16384;
 | 
			
		||||
            low -= 16384;
 | 
			
		||||
            high -= 16384;
 | 
			
		||||
        } else {
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        low += low;
 | 
			
		||||
        high += high + 1;
 | 
			
		||||
        val = (val << 1) | get_bits1(gb);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    ac->low = low;
 | 
			
		||||
    ac->high = high;
 | 
			
		||||
    ac->val = val;
 | 
			
		||||
 | 
			
		||||
    return sym;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ff_aac_ac_finish(AACArithState *state, int offset, int N)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
    for (i = offset; i < N/2; i++)
 | 
			
		||||
        state->last[i] = 1;
 | 
			
		||||
 | 
			
		||||
    for (; i < FF_ARRAY_ELEMS(state->last); i++)
 | 
			
		||||
        state->last[i] = 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										54
									
								
								libavcodec/aac/aacdec_ac.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								libavcodec/aac/aacdec_ac.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,54 @@
 | 
			
		||||
/*
 | 
			
		||||
 * AAC definitions and structures
 | 
			
		||||
 * Copyright (c) 2024 Lynne
 | 
			
		||||
 *
 | 
			
		||||
 * This file is part of FFmpeg.
 | 
			
		||||
 *
 | 
			
		||||
 * FFmpeg is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2.1 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * FFmpeg is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with FFmpeg; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef AVCODEC_AAC_AACDEC_AC_H
 | 
			
		||||
#define AVCODEC_AAC_AACDEC_AC_H
 | 
			
		||||
 | 
			
		||||
#include "libavcodec/get_bits.h"
 | 
			
		||||
 | 
			
		||||
typedef struct AACArithState {
 | 
			
		||||
    uint8_t last[512 /* 2048 / 4 */];
 | 
			
		||||
    int last_len;
 | 
			
		||||
    uint8_t cur[4];
 | 
			
		||||
    uint16_t state_pre;
 | 
			
		||||
} AACArithState;
 | 
			
		||||
 | 
			
		||||
typedef struct AACArith {
 | 
			
		||||
    uint16_t low;
 | 
			
		||||
    uint16_t high;
 | 
			
		||||
    uint16_t val;
 | 
			
		||||
} AACArith;
 | 
			
		||||
 | 
			
		||||
#define FF_AAC_AC_ESCAPE 16
 | 
			
		||||
 | 
			
		||||
uint32_t ff_aac_ac_map_process(AACArithState *state, int reset, int len);
 | 
			
		||||
uint32_t ff_aac_ac_get_context(AACArithState *state, uint32_t old_c, int idx, int len);
 | 
			
		||||
uint32_t ff_aac_ac_get_pk(uint32_t c);
 | 
			
		||||
 | 
			
		||||
void ff_aac_ac_update_context(AACArithState *state, int idx, uint16_t a, uint16_t b);
 | 
			
		||||
void ff_aac_ac_init(AACArith *ac, GetBitContext *gb);
 | 
			
		||||
 | 
			
		||||
uint16_t ff_aac_ac_decode(AACArith *ac, GetBitContext *gb,
 | 
			
		||||
                          const uint16_t *cdf, uint16_t cdf_len);
 | 
			
		||||
 | 
			
		||||
void ff_aac_ac_finish(AACArithState *state, int offset, int nb);
 | 
			
		||||
 | 
			
		||||
#endif /* AVCODEC_AACDEC_AC_H */
 | 
			
		||||
@ -88,8 +88,8 @@ static void AAC_RENAME(apply_mid_side_stereo)(AACDecContext *ac, ChannelElement
 | 
			
		||||
    INTFLOAT *ch1 = cpe->ch[1].AAC_RENAME(coeffs);
 | 
			
		||||
    const uint16_t *offsets = ics->swb_offset;
 | 
			
		||||
    for (int g = 0; g < ics->num_window_groups; g++) {
 | 
			
		||||
        for (int sfb = 0; sfb < ics->max_sfb; sfb++) {
 | 
			
		||||
            const int idx = g*ics->max_sfb + sfb;
 | 
			
		||||
        for (int sfb = 0; sfb < cpe->max_sfb_ste; sfb++) {
 | 
			
		||||
            const int idx = g*cpe->max_sfb_ste + sfb;
 | 
			
		||||
            if (cpe->ms_mask[idx] &&
 | 
			
		||||
                cpe->ch[0].band_type[idx] < NOISE_BT &&
 | 
			
		||||
                cpe->ch[1].band_type[idx] < NOISE_BT) {
 | 
			
		||||
 | 
			
		||||
@ -56,7 +56,8 @@ static int latm_decode_audio_specific_config(struct LATMContext *latmctx,
 | 
			
		||||
{
 | 
			
		||||
    AACDecContext *ac     = &latmctx->aac_ctx;
 | 
			
		||||
    AVCodecContext *avctx = ac->avctx;
 | 
			
		||||
    MPEG4AudioConfig m4ac = { 0 };
 | 
			
		||||
    OutputConfiguration oc = { 0 };
 | 
			
		||||
    MPEG4AudioConfig *m4ac = &oc.m4ac;
 | 
			
		||||
    GetBitContext gbc;
 | 
			
		||||
    int config_start_bit  = get_bits_count(gb);
 | 
			
		||||
    int sync_extension    = 0;
 | 
			
		||||
@ -76,7 +77,7 @@ static int latm_decode_audio_specific_config(struct LATMContext *latmctx,
 | 
			
		||||
    if (get_bits_left(gb) <= 0)
 | 
			
		||||
        return AVERROR_INVALIDDATA;
 | 
			
		||||
 | 
			
		||||
    bits_consumed = decode_audio_specific_config_gb(NULL, avctx, &m4ac,
 | 
			
		||||
    bits_consumed = decode_audio_specific_config_gb(NULL, avctx, &oc,
 | 
			
		||||
                                                    &gbc, config_start_bit,
 | 
			
		||||
                                                    sync_extension);
 | 
			
		||||
 | 
			
		||||
@ -88,11 +89,12 @@ static int latm_decode_audio_specific_config(struct LATMContext *latmctx,
 | 
			
		||||
      asclen = bits_consumed;
 | 
			
		||||
 | 
			
		||||
    if (!latmctx->initialized ||
 | 
			
		||||
        ac->oc[1].m4ac.sample_rate != m4ac.sample_rate ||
 | 
			
		||||
        ac->oc[1].m4ac.chan_config != m4ac.chan_config) {
 | 
			
		||||
        ac->oc[1].m4ac.sample_rate != m4ac->sample_rate ||
 | 
			
		||||
        ac->oc[1].m4ac.chan_config != m4ac->chan_config) {
 | 
			
		||||
 | 
			
		||||
        if (latmctx->initialized) {
 | 
			
		||||
            av_log(avctx, AV_LOG_INFO, "audio config changed (sample_rate=%d, chan_config=%d)\n", m4ac.sample_rate, m4ac.chan_config);
 | 
			
		||||
            av_log(avctx, AV_LOG_INFO, "audio config changed (sample_rate=%d, chan_config=%d)\n",
 | 
			
		||||
                   m4ac->sample_rate, m4ac->chan_config);
 | 
			
		||||
        } else {
 | 
			
		||||
            av_log(avctx, AV_LOG_DEBUG, "initializing latmctx\n");
 | 
			
		||||
        }
 | 
			
		||||
@ -280,7 +282,7 @@ static int latm_decode_frame(AVCodecContext *avctx, AVFrame *out,
 | 
			
		||||
        } else {
 | 
			
		||||
            push_output_configuration(&latmctx->aac_ctx);
 | 
			
		||||
            if ((err = decode_audio_specific_config(
 | 
			
		||||
                    &latmctx->aac_ctx, avctx, &latmctx->aac_ctx.oc[1].m4ac,
 | 
			
		||||
                    &latmctx->aac_ctx, avctx, &latmctx->aac_ctx.oc[1],
 | 
			
		||||
                    avctx->extradata, avctx->extradata_size*8LL, 1)) < 0) {
 | 
			
		||||
                pop_output_configuration(&latmctx->aac_ctx);
 | 
			
		||||
                return err;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										198
									
								
								libavcodec/aac/aacdec_lpd.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										198
									
								
								libavcodec/aac/aacdec_lpd.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,198 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2024 Lynne <dev@lynne.ee>
 | 
			
		||||
 *
 | 
			
		||||
 * This file is part of FFmpeg.
 | 
			
		||||
 *
 | 
			
		||||
 * FFmpeg is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2.1 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * FFmpeg is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with FFmpeg; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "aacdec_lpd.h"
 | 
			
		||||
#include "aacdec_usac.h"
 | 
			
		||||
#include "libavcodec/unary.h"
 | 
			
		||||
 | 
			
		||||
const uint8_t ff_aac_lpd_mode_tab[32][4] = {
 | 
			
		||||
    { 0, 0, 0, 0 },
 | 
			
		||||
    { 1, 0, 0, 0 },
 | 
			
		||||
    { 0, 1, 0, 0 },
 | 
			
		||||
    { 1, 1, 0, 0 },
 | 
			
		||||
    { 0, 0, 1, 0 },
 | 
			
		||||
    { 1, 0, 1, 0 },
 | 
			
		||||
    { 0, 1, 1, 0 },
 | 
			
		||||
    { 1, 1, 1, 0 },
 | 
			
		||||
    { 0, 0, 0, 1 },
 | 
			
		||||
    { 1, 0, 0, 1 },
 | 
			
		||||
    { 0, 1, 0, 1 },
 | 
			
		||||
    { 1, 1, 0, 1 },
 | 
			
		||||
    { 0, 0, 1, 1 },
 | 
			
		||||
    { 1, 0, 1, 1 },
 | 
			
		||||
    { 0, 1, 1, 1 },
 | 
			
		||||
    { 1, 1, 1, 1 },
 | 
			
		||||
    { 2, 2, 0, 0 },
 | 
			
		||||
    { 2, 2, 1, 0 },
 | 
			
		||||
    { 2, 2, 0, 1 },
 | 
			
		||||
    { 2, 2, 1, 1 },
 | 
			
		||||
    { 0, 0, 2, 2 },
 | 
			
		||||
    { 1, 0, 2, 2 },
 | 
			
		||||
    { 0, 1, 2, 2 },
 | 
			
		||||
    { 1, 1, 2, 2 },
 | 
			
		||||
    { 2, 2, 2, 2 },
 | 
			
		||||
    { 3, 3, 3, 3 },
 | 
			
		||||
    /* Larger values are reserved, but permit them for resilience */
 | 
			
		||||
    { 0, 0, 0, 0 },
 | 
			
		||||
    { 0, 0, 0, 0 },
 | 
			
		||||
    { 0, 0, 0, 0 },
 | 
			
		||||
    { 0, 0, 0, 0 },
 | 
			
		||||
    { 0, 0, 0, 0 },
 | 
			
		||||
    { 0, 0, 0, 0 },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void parse_qn(GetBitContext *gb, int *qn, int nk_mode, int no_qn)
 | 
			
		||||
{
 | 
			
		||||
    if (nk_mode == 1) {
 | 
			
		||||
        for (int k = 0; k < no_qn; k++) {
 | 
			
		||||
            qn[k] = get_unary(gb, 0, INT32_MAX); // TODO: find proper ranges
 | 
			
		||||
            if (qn[k])
 | 
			
		||||
                qn[k]++;
 | 
			
		||||
        }
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (int k = 0; k < no_qn; k++)
 | 
			
		||||
        qn[k] = get_bits(gb, 2) + 2;
 | 
			
		||||
 | 
			
		||||
    if (nk_mode == 2) {
 | 
			
		||||
        for (int k = 0; k < no_qn; k++) {
 | 
			
		||||
            if (qn[k] > 4) {
 | 
			
		||||
                qn[k] = get_unary(gb, 0, INT32_MAX);;
 | 
			
		||||
                if (qn[k])
 | 
			
		||||
                    qn[k] += 4;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (int k = 0; k < no_qn; k++) {
 | 
			
		||||
        if (qn[k] > 4) {
 | 
			
		||||
            int qn_ext = get_unary(gb, 0, INT32_MAX);;
 | 
			
		||||
            switch (qn_ext) {
 | 
			
		||||
            case 0: qn[k] = 5; break;
 | 
			
		||||
            case 1: qn[k] = 6; break;
 | 
			
		||||
            case 2: qn[k] = 0; break;
 | 
			
		||||
            default: qn[k] = qn_ext + 4; break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int parse_codebook_idx(GetBitContext *gb, uint32_t *kv,
 | 
			
		||||
                              int nk_mode, int no_qn)
 | 
			
		||||
{
 | 
			
		||||
    int idx, n, nk;
 | 
			
		||||
 | 
			
		||||
    int qn[2];
 | 
			
		||||
    parse_qn(gb, qn, nk_mode, no_qn);
 | 
			
		||||
 | 
			
		||||
    for (int k = 0; k < no_qn; k++) {
 | 
			
		||||
        if (qn[k] > 4) {
 | 
			
		||||
            nk = (qn[k] - 3) / 2;
 | 
			
		||||
            n = qn[k] - nk*2;
 | 
			
		||||
        } else {
 | 
			
		||||
            nk = 0;
 | 
			
		||||
            n = qn[k];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    idx = get_bits(gb, 4*n);
 | 
			
		||||
 | 
			
		||||
    if (nk > 0)
 | 
			
		||||
        for (int i = 0; i < 8; i++)
 | 
			
		||||
            kv[i] = get_bits(gb, nk);
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int ff_aac_parse_fac_data(AACUsacElemData *ce, GetBitContext *gb,
 | 
			
		||||
                          int use_gain, int len)
 | 
			
		||||
{
 | 
			
		||||
    int ret;
 | 
			
		||||
    if (use_gain)
 | 
			
		||||
        ce->fac.gain = get_bits(gb, 7);
 | 
			
		||||
 | 
			
		||||
    for (int i = 0; i < len/8; i++) {
 | 
			
		||||
        ret = parse_codebook_idx(gb, ce->fac.kv[i], 1, 1);
 | 
			
		||||
        if (ret < 0)
 | 
			
		||||
            return ret;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int ff_aac_ldp_parse_channel_stream(AACDecContext *ac, AACUSACConfig *usac,
 | 
			
		||||
                                    AACUsacElemData *ce, GetBitContext *gb)
 | 
			
		||||
{
 | 
			
		||||
    int k;
 | 
			
		||||
    const uint8_t *mod;
 | 
			
		||||
    int first_ldp_flag;
 | 
			
		||||
    int first_tcx_flag;
 | 
			
		||||
 | 
			
		||||
    ce->ldp.acelp_core_mode = get_bits(gb, 3);
 | 
			
		||||
    ce->ldp.lpd_mode = get_bits(gb, 5);
 | 
			
		||||
 | 
			
		||||
    ce->ldp.bpf_control_info = get_bits1(gb);
 | 
			
		||||
    ce->ldp.core_mode_last = get_bits1(gb);
 | 
			
		||||
    ce->ldp.fac_data_present = get_bits1(gb);
 | 
			
		||||
 | 
			
		||||
    mod = ff_aac_lpd_mode_tab[ce->ldp.lpd_mode];
 | 
			
		||||
 | 
			
		||||
    first_ldp_flag = !ce->ldp.core_mode_last;
 | 
			
		||||
    first_tcx_flag = 1;
 | 
			
		||||
    if (first_ldp_flag)
 | 
			
		||||
        ce->ldp.last_lpd_mode = -1; /* last_ldp_mode is a **STATEFUL** value */
 | 
			
		||||
 | 
			
		||||
    k = 0;
 | 
			
		||||
    while (k < 0) {
 | 
			
		||||
        if (!k) {
 | 
			
		||||
            if (ce->ldp.core_mode_last && ce->ldp.fac_data_present)
 | 
			
		||||
                ff_aac_parse_fac_data(ce, gb, 0, usac->core_frame_len/8);
 | 
			
		||||
        } else {
 | 
			
		||||
            if (!ce->ldp.last_lpd_mode && mod[k] > 0 ||
 | 
			
		||||
                ce->ldp.last_lpd_mode && !mod[k])
 | 
			
		||||
                ff_aac_parse_fac_data(ce, gb, 0, usac->core_frame_len/8);
 | 
			
		||||
        }
 | 
			
		||||
        if (!mod[k]) {
 | 
			
		||||
//            parse_acelp_coding();
 | 
			
		||||
            ce->ldp.last_lpd_mode = 0;
 | 
			
		||||
            k++;
 | 
			
		||||
        } else {
 | 
			
		||||
//            parse_tcx_coding();
 | 
			
		||||
            ce->ldp.last_lpd_mode = mod[k];
 | 
			
		||||
            k += (1 << (mod[k] - 1));
 | 
			
		||||
            first_tcx_flag = 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
//    parse_lpc_data(first_lpd_flag);
 | 
			
		||||
 | 
			
		||||
    if (!ce->ldp.core_mode_last && ce->ldp.fac_data_present) {
 | 
			
		||||
        uint16_t len_8 = usac->core_frame_len / 8;
 | 
			
		||||
        uint16_t len_16 = usac->core_frame_len / 16;
 | 
			
		||||
        uint16_t fac_len = get_bits1(gb) /* short_fac_flag */ ? len_8 : len_16;
 | 
			
		||||
        int ret = ff_aac_parse_fac_data(ce, gb, 1, fac_len);
 | 
			
		||||
        if (ret < 0)
 | 
			
		||||
            return ret;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										33
									
								
								libavcodec/aac/aacdec_lpd.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								libavcodec/aac/aacdec_lpd.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,33 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2024 Lynne <dev@lynne.ee>
 | 
			
		||||
 *
 | 
			
		||||
 * This file is part of FFmpeg.
 | 
			
		||||
 *
 | 
			
		||||
 * FFmpeg is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2.1 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * FFmpeg is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with FFmpeg; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef AVCODEC_AAC_AACDEC_LPD_H
 | 
			
		||||
#define AVCODEC_AAC_AACDEC_LPD_H
 | 
			
		||||
 | 
			
		||||
#include "aacdec.h"
 | 
			
		||||
#include "libavcodec/get_bits.h"
 | 
			
		||||
 | 
			
		||||
int ff_aac_parse_fac_data(AACUsacElemData *ce, GetBitContext *gb,
 | 
			
		||||
                          int use_gain, int len);
 | 
			
		||||
 | 
			
		||||
int ff_aac_ldp_parse_channel_stream(AACDecContext *ac, AACUSACConfig *usac,
 | 
			
		||||
                                    AACUsacElemData *ce, GetBitContext *gb);
 | 
			
		||||
 | 
			
		||||
#endif /* AVCODEC_AAC_AACDEC_LPD_H */
 | 
			
		||||
							
								
								
									
										1608
									
								
								libavcodec/aac/aacdec_usac.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1608
									
								
								libavcodec/aac/aacdec_usac.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										37
									
								
								libavcodec/aac/aacdec_usac.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								libavcodec/aac/aacdec_usac.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,37 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2024 Lynne <dev@lynne.ee>
 | 
			
		||||
 *
 | 
			
		||||
 * This file is part of FFmpeg.
 | 
			
		||||
 *
 | 
			
		||||
 * FFmpeg is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2.1 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * FFmpeg is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with FFmpeg; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef AVCODEC_AAC_AACDEC_USAC_H
 | 
			
		||||
#define AVCODEC_AAC_AACDEC_USAC_H
 | 
			
		||||
 | 
			
		||||
#include "aacdec.h"
 | 
			
		||||
 | 
			
		||||
#include "libavcodec/get_bits.h"
 | 
			
		||||
 | 
			
		||||
int ff_aac_usac_config_decode(AACDecContext *ac, AVCodecContext *avctx,
 | 
			
		||||
                              GetBitContext *gb, OutputConfiguration *oc,
 | 
			
		||||
                              int channel_config);
 | 
			
		||||
 | 
			
		||||
int ff_aac_usac_reset_state(AACDecContext *ac, OutputConfiguration *oc);
 | 
			
		||||
 | 
			
		||||
int ff_aac_usac_decode_frame(AVCodecContext *avctx, AACDecContext *ac,
 | 
			
		||||
                             GetBitContext *gb, int *got_frame_ptr);
 | 
			
		||||
 | 
			
		||||
#endif /* AVCODEC_AAC_AACDEC_USAC_H */
 | 
			
		||||
@ -1998,6 +1998,11 @@ const uint8_t ff_tns_max_bands_128[] = {
 | 
			
		||||
};
 | 
			
		||||
// @}
 | 
			
		||||
 | 
			
		||||
const uint8_t ff_usac_noise_fill_start_offset[2][2] = {
 | 
			
		||||
    { 160, 20 },
 | 
			
		||||
    { 120, 15 },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const DECLARE_ALIGNED(32, float, ff_aac_eld_window_512)[1920] = {
 | 
			
		||||
     0.00338834,  0.00567745,  0.00847677,  0.01172641,
 | 
			
		||||
     0.01532555,  0.01917664,  0.02318809,  0.02729259,
 | 
			
		||||
@ -3895,3 +3900,40 @@ DECLARE_ALIGNED(16, const float, ff_aac_deemph_weights)[16] = {
 | 
			
		||||
    0,
 | 
			
		||||
    USAC_EMPH_COEFF,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const int ff_aac_usac_samplerate[32] = {
 | 
			
		||||
    96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
 | 
			
		||||
    16000, 12000, 11025,  8000,  7350,    -1,    -1, 57600,
 | 
			
		||||
    51200, 40000, 38400, 34150, 28800, 25600, 20000, 19200,
 | 
			
		||||
    17075, 14400, 12800, 9600,     -1,    -1,    -1,    -1,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Window type (only long+eight, start/stop/stopstart), sine+sine, kbd+kbd, sine+kbd, kbd+sine */
 | 
			
		||||
const float ff_aac_usac_mdst_filt_cur[4 /* Window */][4 /* Shape */][7] =
 | 
			
		||||
{
 | 
			
		||||
    { { 0.000000,  0.000000,  0.500000, 0.000000, -0.500000,  0.000000,  0.000000 },
 | 
			
		||||
      { 0.091497,  0.000000,  0.581427, 0.000000, -0.581427,  0.000000, -0.091497 },
 | 
			
		||||
      { 0.045748,  0.057238,  0.540714, 0.000000, -0.540714, -0.057238, -0.045748 },
 | 
			
		||||
      { 0.045748, -0.057238,  0.540714, 0.000000, -0.540714,  0.057238, -0.045748 } },
 | 
			
		||||
    { { 0.102658,  0.103791,  0.567149, 0.000000, -0.567149, -0.103791, -0.102658 },
 | 
			
		||||
      { 0.150512,  0.047969,  0.608574, 0.000000, -0.608574, -0.047969, -0.150512 },
 | 
			
		||||
      { 0.104763,  0.105207,  0.567861, 0.000000, -0.567861, -0.105207, -0.104763 },
 | 
			
		||||
      { 0.148406,  0.046553,  0.607863, 0.000000, -0.607863, -0.046553, -0.148406 } },
 | 
			
		||||
    { { 0.102658, -0.103791,  0.567149, 0.000000, -0.567149,  0.103791, -0.102658 },
 | 
			
		||||
      { 0.150512, -0.047969,  0.608574, 0.000000, -0.608574,  0.047969, -0.150512 },
 | 
			
		||||
      { 0.148406, -0.046553,  0.607863, 0.000000, -0.607863,  0.046553, -0.148406 },
 | 
			
		||||
      { 0.104763, -0.105207,  0.567861, 0.000000, -0.567861,  0.105207, -0.104763 } },
 | 
			
		||||
    { { 0.205316,  0.000000,  0.634298, 0.000000, -0.634298,  0.000000, -0.205316 },
 | 
			
		||||
      { 0.209526,  0.000000,  0.635722, 0.000000, -0.635722,  0.000000, -0.209526 },
 | 
			
		||||
      { 0.207421,  0.001416,  0.635010, 0.000000, -0.635010, -0.001416, -0.207421 },
 | 
			
		||||
      { 0.207421, -0.001416,  0.635010, 0.000000, -0.635010,  0.001416, -0.207421 } }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Window type (everything/longstop+stopstart), sine or kbd */
 | 
			
		||||
const float ff_aac_usac_mdst_filt_prev[2 /* Window */][2 /* sine/kbd */][7] =
 | 
			
		||||
{
 | 
			
		||||
    { { 0.000000, 0.106103, 0.250000, 0.318310, 0.250000, 0.106103, 0.000000 },
 | 
			
		||||
      { 0.059509, 0.123714, 0.186579, 0.213077, 0.186579, 0.123714, 0.059509 } },
 | 
			
		||||
    { { 0.038498, 0.039212, 0.039645, 0.039790, 0.039645, 0.039212, 0.038498 },
 | 
			
		||||
      { 0.026142, 0.026413, 0.026577, 0.026631, 0.026577, 0.026413, 0.026142 } }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -115,4 +115,14 @@ extern const uint8_t ff_tns_max_bands_512 [13];
 | 
			
		||||
extern const uint8_t ff_tns_max_bands_480 [13];
 | 
			
		||||
extern const uint8_t ff_tns_max_bands_128 [13];
 | 
			
		||||
 | 
			
		||||
/* [x][y], x == 1 -> frame len is 768 frames, y == 1 -> is eight_short */
 | 
			
		||||
extern const uint8_t ff_usac_noise_fill_start_offset[2][2];
 | 
			
		||||
 | 
			
		||||
extern const int ff_aac_usac_samplerate[32];
 | 
			
		||||
 | 
			
		||||
/* Window type (only long+eight, start/stop/stopstart), sine+sine, kbd+kbd, sine+kbd, kbd+sine */
 | 
			
		||||
extern const float ff_aac_usac_mdst_filt_cur[4 /* Window */][4 /* Shape */][7];
 | 
			
		||||
/* Window type (everything/longstop+stopstart), sine or kbd */
 | 
			
		||||
extern const float ff_aac_usac_mdst_filt_prev[2 /* Window */][2 /* sine/kbd */][7];
 | 
			
		||||
 | 
			
		||||
#endif /* AVCODEC_AACTAB_H */
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user