Example #1
0
// fmt carries the input format. Change it to the best next-possible format
// the encoder likely accepts.
static void select_encode_format(AVCodecContext *c, struct mp_audio *fmt)
{
    int formats[AF_FORMAT_COUNT];
    af_get_best_sample_formats(fmt->format, formats);

    for (int n = 0; formats[n]; n++) {
        const enum AVSampleFormat *lf = c->codec->sample_fmts;
        for (int i = 0; lf && lf[i] != AV_SAMPLE_FMT_NONE; i++) {
            int mpfmt = af_from_avformat(lf[i]);
            if (mpfmt && mpfmt == formats[n]) {
                mp_audio_set_format(fmt, mpfmt);
                goto done_fmt;
            }
        }
    }
done_fmt: ;

    int rate =
        af_select_best_samplerate(fmt->rate, c->codec->supported_samplerates);
    if (rate > 0)
        fmt->rate = rate;

    struct mp_chmap_sel sel = {0};
    const uint64_t *lch = c->codec->channel_layouts;
    for (int n = 0; lch && lch[n]; n++) {
        struct mp_chmap chmap = {0};
        mp_chmap_from_lavc(&chmap, lch[n]);
        mp_chmap_sel_add_map(&sel, &chmap);
    }
    struct mp_chmap res = fmt->channels;
    mp_chmap_sel_adjust(&sel, &res);
    if (!mp_chmap_is_empty(&res))
        mp_audio_set_channels(fmt, &res);
}
Example #2
0
static void select_format(struct ao *ao, AVCodec *codec)
{
    int best_score = INT_MIN;
    int best_format = 0;

    // Check the encoder's list of supported formats.
    for (const enum AVSampleFormat *sampleformat = codec->sample_fmts;
         sampleformat && *sampleformat != AV_SAMPLE_FMT_NONE;
         ++sampleformat)
    {
        int fmt = af_from_avformat(*sampleformat);
        if (!fmt) {
            MP_WARN(ao, "unsupported lavc format %s",
                    av_get_sample_fmt_name(*sampleformat));
            continue;
        }
        int score = af_format_conversion_score(fmt, ao->format);
        if (score > best_score) {
            best_score = score;
            best_format = fmt;
        }
    }

    if (best_format) {
        ao->format = best_format;
    } else {
        MP_ERR(ao, "sample format not found\n"); // shouldn't happen
    }
}
Example #3
0
static int af_open(struct af_instance* af){

    af_ac3enc_t *s = af->priv;
    af->control=control;
    af->uninit=uninit;
    af->filter_frame = filter_frame;
    af->filter_out = filter_out;

    s->lavc_acodec = avcodec_find_encoder_by_name("ac3");
    if (!s->lavc_acodec) {
        MP_ERR(af, "Audio LAVC, couldn't find encoder for codec %s.\n", "ac3");
        return AF_ERROR;
    }

    s->lavc_actx = avcodec_alloc_context3(s->lavc_acodec);
    if (!s->lavc_actx) {
        MP_ERR(af, "Audio LAVC, couldn't allocate context!\n");
        return AF_ERROR;
    }
    const enum AVSampleFormat *fmts = s->lavc_acodec->sample_fmts;
    for (int i = 0; fmts[i] != AV_SAMPLE_FMT_NONE; i++) {
        s->in_sampleformat = af_from_avformat(fmts[i]);
        if (s->in_sampleformat) {
            s->lavc_actx->sample_fmt = fmts[i];
            break;
        }
    }
    if (!s->in_sampleformat) {
        MP_ERR(af, "Audio LAVC, encoder doesn't "
               "support expected sample formats!\n");
        return AF_ERROR;
    }
    MP_VERBOSE(af, "[af_lavcac3enc]: in sample format: %s\n",
           af_fmt_to_str(s->in_sampleformat));

    av_init_packet(&s->pkt);

    s->input = talloc_zero(s, struct mp_audio);

    if (s->cfg_bit_rate) {
        int i;
        for (i = 0; i < 19; i++) {
            if (ac3_bitrate_tab[i] == s->cfg_bit_rate)
                break;
        }
        if (i >= 19) {
            MP_WARN(af, "af_lavcac3enc unable set unsupported "
                    "bitrate %d, use default bitrate (check manpage to see "
                    "supported bitrates).\n", s->cfg_bit_rate);
            s->cfg_bit_rate = 0;
        }
    }

    return AF_OK;
}
Example #4
0
static bool supports_format(AVCodec *codec, int format)
{
    for (const enum AVSampleFormat *sampleformat = codec->sample_fmts;
         sampleformat && *sampleformat != AV_SAMPLE_FMT_NONE;
         ++sampleformat)
    {
        if (af_from_avformat(*sampleformat) == format)
            return true;
    }
    return false;
}
Example #5
0
static int control(struct af_instance *af, int cmd, void *arg)
{
    struct priv *p = af->priv;

    switch (cmd) {
    case AF_CONTROL_REINIT: {
        struct mp_audio *in = arg;
        struct mp_audio orig_in = *in;
        struct mp_audio *out = af->data;

        if (af_to_avformat(in->format) == AV_SAMPLE_FMT_NONE)
            mp_audio_set_format(in, AF_FORMAT_FLOAT);

        // Removing this requires fixing AVFrame.data vs. AVFrame.extended_data
        if (in->channels.num > AV_NUM_DATA_POINTERS)
            return AF_ERROR;

        if (!mp_chmap_is_lavc(&in->channels))
            mp_chmap_reorder_to_lavc(&in->channels); // will always work

        if (!recreate_graph(af, in))
            return AF_ERROR;

        AVFilterLink *l_out = p->out->inputs[0];

        out->rate = l_out->sample_rate;

        mp_audio_set_format(out, af_from_avformat(l_out->format));

        struct mp_chmap out_cm;
        mp_chmap_from_lavc(&out_cm, l_out->channel_layout);
        mp_audio_set_channels(out, &out_cm);

        if (!mp_audio_config_valid(out) || out->channels.num > AV_NUM_DATA_POINTERS)
            return AF_ERROR;

        p->timebase_out = l_out->time_base;

        return mp_audio_config_equals(in, &orig_in) ? AF_OK : AF_FALSE;
    }
    case AF_CONTROL_GET_METADATA:
        if (p->metadata) {
            *(struct mp_tags *)arg = *p->metadata;
            return CONTROL_OK;
        }
        return CONTROL_NA;
    case AF_CONTROL_RESET:
        reset(af);
        return AF_OK;
    }
    return AF_UNKNOWN;
}
Example #6
0
static int control(struct af_instance *af, int cmd, void *arg)
{
    struct priv *p = af->priv;

    switch (cmd) {
    case AF_CONTROL_REINIT: {
        struct mp_audio *in = arg;
        struct mp_audio orig_in = *in;
        struct mp_audio *out = af->data;

        if (af_to_avformat(in->format) == AV_SAMPLE_FMT_NONE)
            mp_audio_set_format(in, AF_FORMAT_FLOAT);

        if (!mp_chmap_is_lavc(&in->channels))
            mp_chmap_reorder_to_lavc(&in->channels); // will always work

        if (!recreate_graph(af, in))
            return AF_ERROR;

        AVFilterLink *l_out = p->out->inputs[0];

        out->rate = l_out->sample_rate;

        mp_audio_set_format(out, af_from_avformat(l_out->format));

        struct mp_chmap out_cm;
        mp_chmap_from_lavc(&out_cm, l_out->channel_layout);
        if (!out_cm.num || out_cm.num != l_out->channels)
            mp_chmap_from_channels(&out_cm, l_out->channels);
        mp_audio_set_channels(out, &out_cm);

        if (!mp_audio_config_valid(out))
            return AF_ERROR;

        p->timebase_out = l_out->time_base;

        // Blatantly incorrect; we don't know what the filters do.
        af->mul = out->rate / (double)in->rate;

        return mp_audio_config_equals(in, &orig_in) ? AF_OK : AF_FALSE;
    }
    }
    return AF_UNKNOWN;
}
Example #7
0
static int configure_lavrr(struct af_instance *af, struct mp_audio *in,
                           struct mp_audio *out, bool verbose)
{
    struct af_resample *s = af->priv;

    close_lavrr(af);

    s->avrctx = avresample_alloc_context();
    s->avrctx_out = avresample_alloc_context();
    if (!s->avrctx || !s->avrctx_out)
        goto error;

    enum AVSampleFormat in_samplefmt = af_to_avformat(in->format);
    enum AVSampleFormat out_samplefmt = check_output_conversion(out->format);
    enum AVSampleFormat out_samplefmtp = av_get_planar_sample_fmt(out_samplefmt);

    if (in_samplefmt == AV_SAMPLE_FMT_NONE ||
        out_samplefmt == AV_SAMPLE_FMT_NONE ||
        out_samplefmtp == AV_SAMPLE_FMT_NONE)
        goto error;

    s->out_rate    = out->rate;
    s->in_rate_af  = in->rate;
    s->in_rate     = rate_from_speed(in->rate, s->playback_speed);
    s->out_format  = out->format;
    s->in_format   = in->format;
    s->out_channels= out->channels;
    s->in_channels = in->channels;

    av_opt_set_int(s->avrctx, "filter_size",        s->opts.filter_size, 0);
    av_opt_set_int(s->avrctx, "phase_shift",        s->opts.phase_shift, 0);
    av_opt_set_int(s->avrctx, "linear_interp",      s->opts.linear, 0);

    av_opt_set_double(s->avrctx, "cutoff",          s->opts.cutoff, 0);

    int normalize = s->opts.normalize;
    if (normalize < 0)
        normalize = af->opts->audio_normalize;
#if HAVE_LIBSWRESAMPLE
    av_opt_set_double(s->avrctx, "rematrix_maxval", normalize ? 1 : 1000, 0);
#else
    av_opt_set_int(s->avrctx, "normalize_mix_level", !!normalize, 0);
#endif

    if (mp_set_avopts(af->log, s->avrctx, s->avopts) < 0)
        goto error;

    struct mp_chmap map_in = in->channels;
    struct mp_chmap map_out = out->channels;

    // Try not to do any remixing if at least one is "unknown".
    if (mp_chmap_is_unknown(&map_in) || mp_chmap_is_unknown(&map_out)) {
        mp_chmap_set_unknown(&map_in, map_in.num);
        mp_chmap_set_unknown(&map_out, map_out.num);
    }

    // unchecked: don't take any channel reordering into account
    uint64_t in_ch_layout = mp_chmap_to_lavc_unchecked(&map_in);
    uint64_t out_ch_layout = mp_chmap_to_lavc_unchecked(&map_out);

    struct mp_chmap in_lavc, out_lavc;
    mp_chmap_from_lavc(&in_lavc, in_ch_layout);
    mp_chmap_from_lavc(&out_lavc, out_ch_layout);

    if (verbose && !mp_chmap_equals(&in_lavc, &out_lavc)) {
        MP_VERBOSE(af, "Remix: %s -> %s\n", mp_chmap_to_str(&in_lavc),
                                            mp_chmap_to_str(&out_lavc));
    }

    if (in_lavc.num != map_in.num) {
        // For handling NA channels, we would have to add a planarization step.
        MP_FATAL(af, "Unsupported channel remapping.\n");
        goto error;
    }

    mp_chmap_get_reorder(s->reorder_in, &map_in, &in_lavc);
    transpose_order(s->reorder_in, map_in.num);

    if (mp_chmap_equals(&out_lavc, &map_out)) {
        // No intermediate step required - output new format directly.
        out_samplefmtp = out_samplefmt;
    } else {
        // Verify that we really just reorder and/or insert NA channels.
        struct mp_chmap withna = out_lavc;
        mp_chmap_fill_na(&withna, map_out.num);
        if (withna.num != map_out.num)
            goto error;
    }
    mp_chmap_get_reorder(s->reorder_out, &out_lavc, &map_out);

    s->avrctx_fmt = *out;
    mp_audio_set_channels(&s->avrctx_fmt, &out_lavc);
    mp_audio_set_format(&s->avrctx_fmt, af_from_avformat(out_samplefmtp));

    s->pre_out_fmt = *out;
    mp_audio_set_format(&s->pre_out_fmt, af_from_avformat(out_samplefmt));

    // If there are NA channels, the final output will have more channels than
    // the avrctx output. Also, avrctx will output planar (out_samplefmtp was
    // not overwritten). Allocate the output frame with more channels, so the
    // NA channels can be trivially added.
    s->pool_fmt = s->avrctx_fmt;
    if (map_out.num > out_lavc.num)
        mp_audio_set_channels(&s->pool_fmt, &map_out);

    out_ch_layout = fudge_layout_conversion(af, in_ch_layout, out_ch_layout);

    // Real conversion; output is input to avrctx_out.
    av_opt_set_int(s->avrctx, "in_channel_layout",  in_ch_layout, 0);
    av_opt_set_int(s->avrctx, "out_channel_layout", out_ch_layout, 0);
    av_opt_set_int(s->avrctx, "in_sample_rate",     s->in_rate, 0);
    av_opt_set_int(s->avrctx, "out_sample_rate",    s->out_rate, 0);
    av_opt_set_int(s->avrctx, "in_sample_fmt",      in_samplefmt, 0);
    av_opt_set_int(s->avrctx, "out_sample_fmt",     out_samplefmtp, 0);

    // Just needs the correct number of channels for deplanarization.
    struct mp_chmap fake_chmap;
    mp_chmap_set_unknown(&fake_chmap, map_out.num);
    uint64_t fake_out_ch_layout = mp_chmap_to_lavc_unchecked(&fake_chmap);
    if (!fake_out_ch_layout)
        goto error;
    av_opt_set_int(s->avrctx_out, "in_channel_layout",  fake_out_ch_layout, 0);
    av_opt_set_int(s->avrctx_out, "out_channel_layout", fake_out_ch_layout, 0);

    av_opt_set_int(s->avrctx_out, "in_sample_fmt",      out_samplefmtp, 0);
    av_opt_set_int(s->avrctx_out, "out_sample_fmt",     out_samplefmt, 0);
    av_opt_set_int(s->avrctx_out, "in_sample_rate",     s->out_rate, 0);
    av_opt_set_int(s->avrctx_out, "out_sample_rate",    s->out_rate, 0);

    // API has weird requirements, quoting avresample.h:
    //  * This function can only be called when the allocated context is not open.
    //  * Also, the input channel layout must have already been set.
    avresample_set_channel_mapping(s->avrctx, s->reorder_in);

    if (avresample_open(s->avrctx) < 0 || avresample_open(s->avrctx_out) < 0) {
        MP_ERR(af, "Cannot open Libavresample Context. \n");
        goto error;
    }
    return AF_OK;

error:
    close_lavrr(af);
    return AF_ERROR;
}