Skip to content
Snippets Groups Projects
aacenc.c 43.3 KiB
Newer Older
  • Learn to ignore specific revisions
  •         for (i = 1; i <= s->chan_map[0]; i++) {
                avctx->bit_rate += s->chan_map[i] == TYPE_CPE ? 128000 : /* Pair */
                                   s->chan_map[i] == TYPE_LFE ? 16000  : /* LFE  */
                                                                69000  ; /* SCE  */
            }
        }
    
        for (i = 0; i < 16; i++)
            if (avctx->sample_rate == avpriv_mpeg4audio_sample_rates[i])
                break;
    
        s->samplerate_index = i;
        ERROR_IF(s->samplerate_index == 16 ||
                 s->samplerate_index >= ff_aac_swb_size_1024_len ||
                 s->samplerate_index >= ff_aac_swb_size_128_len,
    
                 "Unsupported sample rate %d\n", avctx->sample_rate);
    
        WARN_IF(1024.0 * avctx->bit_rate / avctx->sample_rate > 6144 * s->channels,
    
                 "Too many bits %f > %d per frame requested, clamping to max\n",
    
                 1024.0 * avctx->bit_rate / avctx->sample_rate,
                 6144 * s->channels);
    
        avctx->bit_rate = (int64_t)FFMIN(6144 * s->channels / 1024.0 * avctx->sample_rate,
                                         avctx->bit_rate);
    
        /* Profile and option setting */
        avctx->profile = avctx->profile == FF_PROFILE_UNKNOWN ? FF_PROFILE_AAC_LOW :
                         avctx->profile;
    
        for (i = 0; i < FF_ARRAY_ELEMS(aacenc_profiles); i++)
            if (avctx->profile == aacenc_profiles[i])
    
        if (avctx->profile == FF_PROFILE_MPEG2_AAC_LOW) {
            avctx->profile = FF_PROFILE_AAC_LOW;
            ERROR_IF(s->options.pred,
                     "Main prediction unavailable in the \"mpeg2_aac_low\" profile\n");
            ERROR_IF(s->options.ltp,
                     "LTP prediction unavailable in the \"mpeg2_aac_low\" profile\n");
            WARN_IF(s->options.pns,
                    "PNS unavailable in the \"mpeg2_aac_low\" profile, turning off\n");
            s->options.pns = 0;
        } else if (avctx->profile == FF_PROFILE_AAC_LTP) {
            s->options.ltp = 1;
            ERROR_IF(s->options.pred,
                     "Main prediction unavailable in the \"aac_ltp\" profile\n");
        } else if (avctx->profile == FF_PROFILE_AAC_MAIN) {
            s->options.pred = 1;
            ERROR_IF(s->options.ltp,
                     "LTP prediction unavailable in the \"aac_main\" profile\n");
        } else if (s->options.ltp) {
            avctx->profile = FF_PROFILE_AAC_LTP;
            WARN_IF(1,
                    "Chainging profile to \"aac_ltp\"\n");
            ERROR_IF(s->options.pred,
                     "Main prediction unavailable in the \"aac_ltp\" profile\n");
        } else if (s->options.pred) {
            avctx->profile = FF_PROFILE_AAC_MAIN;
            WARN_IF(1,
                    "Chainging profile to \"aac_main\"\n");
    
            ERROR_IF(s->options.ltp,
    
                     "LTP prediction unavailable in the \"aac_main\" profile\n");
    
        /* Coder limitations */
        s->coder = &ff_aac_coders[s->options.coder];
    
        if (s->options.coder == AAC_CODER_ANMR) {
    
            ERROR_IF(avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL,
    
                     "The ANMR coder is considered experimental, add -strict -2 to enable!\n");
    
            s->options.intensity_stereo = 0;
            s->options.pns = 0;
        }
    
        ERROR_IF(s->options.ltp && avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL,
                 "The LPT profile requires experimental compliance, add -strict -2 to enable!\n");
    
    
        /* M/S introduces horrible artifacts with multichannel files, this is temporary */
        if (s->channels > 3)
            s->options.mid_side = 0;
    
    
        if ((ret = dsp_init(avctx, s)) < 0)
    
        if ((ret = alloc_buffers(avctx, s)) < 0)
    
        if ((ret = put_audio_specific_config(avctx)))
            goto fail;
    
        sizes[0]   = ff_aac_swb_size_1024[s->samplerate_index];
        sizes[1]   = ff_aac_swb_size_128[s->samplerate_index];
        lengths[0] = ff_aac_num_swb_1024[s->samplerate_index];
        lengths[1] = ff_aac_num_swb_128[s->samplerate_index];
    
        for (i = 0; i < s->chan_map[0]; i++)
            grouping[i] = s->chan_map[i + 1] == TYPE_CPE;
    
        if ((ret = ff_psy_init(&s->psy, avctx, 2, sizes, lengths,
                               s->chan_map[0], grouping)) < 0)
    
            goto fail;
        s->psypp = ff_psy_preprocess_init(avctx);
    
        ff_lpc_init(&s->lpc, 2*avctx->frame_size, TNS_MAX_ORDER, FF_LPC_TYPE_LEVINSON);
    
        s->random_state = 0x1f2e3d4c;
    
        s->abs_pow34   = abs_pow34_v;
        s->quant_bands = quantize_bands;
    
        if (ARCH_X86)
            ff_aac_dsp_init_x86(s);
    
    
        if (HAVE_MIPSDSP)
    
        if ((ret = ff_thread_once(&aac_table_init, &aac_encode_init_tables)) != 0)
    
            return AVERROR_UNKNOWN;
    
        ff_af_queue_init(avctx, &s->afq);
    
    
    #define AACENC_FLAGS AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM
    static const AVOption aacenc_options[] = {
    
        {"aac_coder", "Coding algorithm", offsetof(AACEncContext, options.coder), AV_OPT_TYPE_INT, {.i64 = AAC_CODER_FAST}, 0, AAC_CODER_NB-1, AACENC_FLAGS, "coder"},
    
            {"anmr",     "ANMR method",               0, AV_OPT_TYPE_CONST, {.i64 = AAC_CODER_ANMR},    INT_MIN, INT_MAX, AACENC_FLAGS, "coder"},
            {"twoloop",  "Two loop searching method", 0, AV_OPT_TYPE_CONST, {.i64 = AAC_CODER_TWOLOOP}, INT_MIN, INT_MAX, AACENC_FLAGS, "coder"},
    
            {"fast",     "Default fast search",       0, AV_OPT_TYPE_CONST, {.i64 = AAC_CODER_FAST},    INT_MIN, INT_MAX, AACENC_FLAGS, "coder"},
    
        {"aac_ms", "Force M/S stereo coding", offsetof(AACEncContext, options.mid_side), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, AACENC_FLAGS},
    
        {"aac_is", "Intensity stereo coding", offsetof(AACEncContext, options.intensity_stereo), AV_OPT_TYPE_BOOL, {.i64 = 1}, -1, 1, AACENC_FLAGS},
        {"aac_pns", "Perceptual noise substitution", offsetof(AACEncContext, options.pns), AV_OPT_TYPE_BOOL, {.i64 = 1}, -1, 1, AACENC_FLAGS},
    
        {"aac_tns", "Temporal noise shaping", offsetof(AACEncContext, options.tns), AV_OPT_TYPE_BOOL, {.i64 = 1}, -1, 1, AACENC_FLAGS},
    
        {"aac_ltp", "Long term prediction", offsetof(AACEncContext, options.ltp), AV_OPT_TYPE_BOOL, {.i64 = 0}, -1, 1, AACENC_FLAGS},
        {"aac_pred", "AAC-Main prediction", offsetof(AACEncContext, options.pred), AV_OPT_TYPE_BOOL, {.i64 = 0}, -1, 1, AACENC_FLAGS},
    
        {"aac_pce", "Forces the use of PCEs", offsetof(AACEncContext, options.pce), AV_OPT_TYPE_BOOL, {.i64 = 0}, -1, 1, AACENC_FLAGS},
    
        {NULL}
    };
    
    static const AVClass aacenc_class = {
    
        .class_name = "AAC encoder",
        .item_name  = av_default_item_name,
        .option     = aacenc_options,
        .version    = LIBAVUTIL_VERSION_INT,
    
    static const AVCodecDefault aac_encode_defaults[] = {
        { "b", "0" },
        { NULL }
    };
    
    
        .long_name      = NULL_IF_CONFIG_SMALL("AAC (Advanced Audio Coding)"),
    
        .type           = AVMEDIA_TYPE_AUDIO,
    
        .id             = AV_CODEC_ID_AAC,
    
        .priv_data_size = sizeof(AACEncContext),
        .init           = aac_encode_init,
    
        .encode2        = aac_encode_frame,
    
        .close          = aac_encode_end,
    
        .supported_samplerates = mpeg4audio_sample_rates,
    
        .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
    
        .capabilities   = AV_CODEC_CAP_SMALL_LAST_FRAME | AV_CODEC_CAP_DELAY,
    
        .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP,
    
                                                         AV_SAMPLE_FMT_NONE },
        .priv_class     = &aacenc_class,