Beispiel #1
0
static int init(struct ao *ao)
{
    struct priv *priv = ao->priv;

    ao->untimed = priv->untimed;

    struct mp_chmap_sel sel = {.tmp = ao};
    if (priv->channel_layouts) {
        for (int n = 0; priv->channel_layouts[n]; n++) {
            struct mp_chmap map = {0};
            if (!mp_chmap_from_str(&map, bstr0(priv->channel_layouts[n]))) {
                MP_FATAL(ao, "Invalid channel map in option.\n");
                return -1;
            }
            mp_chmap_sel_add_map(&sel, &map);
        }
    } else {
        mp_chmap_sel_add_any(&sel);
    }
    if (!ao_chmap_sel_adjust(ao, &sel, &ao->channels))
        mp_chmap_from_channels(&ao->channels, 2);

    priv->latency = priv->latency_sec * ao->samplerate;

    // A "buffer" for this many seconds of audio
    int bursts = (int)(ao->samplerate * priv->bufferlen + 1) / priv->outburst;
    priv->buffersize = priv->outburst * bursts + priv->latency;

    priv->last_time = mp_time_sec();

    return 0;
}
Beispiel #2
0
static int init(struct ao *ao)
{
    struct priv *priv = ao->priv;

    ao->untimed = priv->untimed;

    struct mp_chmap_sel sel = {.tmp = ao};
    if (priv->channel_layouts.num_chmaps) {
        for (int n = 0; n < priv->channel_layouts.num_chmaps; n++)
            mp_chmap_sel_add_map(&sel, &priv->channel_layouts.chmaps[n]);
    } else {
        mp_chmap_sel_add_any(&sel);
    }
    if (!ao_chmap_sel_adjust(ao, &sel, &ao->channels))
        mp_chmap_from_channels(&ao->channels, 2);

    priv->latency = priv->latency_sec * ao->samplerate;

    // A "buffer" for this many seconds of audio
    int bursts = (int)(ao->samplerate * priv->bufferlen + 1) / priv->outburst;
    priv->buffersize = priv->outburst * bursts + priv->latency;

    priv->last_time = mp_time_sec();

    return 0;
}
Beispiel #3
0
static int init(struct ao *ao)
{
    struct priv *priv = ao->priv;

    ao->untimed = priv->untimed;

    struct mp_chmap_sel sel = {0};
    mp_chmap_sel_add_any(&sel);
    if (!ao_chmap_sel_adjust(ao, &sel, &ao->channels))
        mp_chmap_from_channels(&ao->channels, 2);

    priv->latency = priv->latency_sec * ao->samplerate;

    // A "buffer" for this many seconds of audio
    int bursts = (int)(ao->samplerate * priv->bufferlen + 1) / priv->outburst;
    priv->buffersize = priv->outburst * bursts + priv->latency;

    priv->last_time = mp_time_sec();

    return 0;
}
Beispiel #4
0
static int init(struct ao *ao)
{
    struct priv *p = ao->priv;
    const char **matching_ports = NULL;
    char *port_name = p->cfg_port && p->cfg_port[0] ? p->cfg_port : NULL;
    jack_options_t open_options = JackNullOption;
    int port_flags = JackPortIsInput;
    int i;

    struct mp_chmap_sel sel = {0};

    if (p->stdlayout == 0) {
        mp_chmap_sel_add_waveext(&sel);
    } else if (p->stdlayout == 1) {
        mp_chmap_sel_add_alsa_def(&sel);
    } else {
        mp_chmap_sel_add_any(&sel);
    }

    if (!ao_chmap_sel_adjust(ao, &sel, &ao->channels))
        goto err_out;

    if (!p->autostart)
        open_options |= JackNoStartServer;
    p->client = jack_client_open(p->cfg_client_name, open_options, NULL);
    if (!p->client) {
        MP_FATAL(ao, "cannot open server\n");
        goto err_out;
    }
    jack_set_process_callback(p->client, outputaudio, ao);

    // list matching ports if connections should be made
    if (p->connect) {
        if (!port_name)
            port_flags |= JackPortIsPhysical;
        matching_ports = jack_get_ports(p->client, port_name, NULL, port_flags);
        if (!matching_ports || !matching_ports[0]) {
            MP_FATAL(ao, "no physical ports available\n");
            goto err_out;
        }
        i = 1;
        p->num_ports = ao->channels.num;
        while (matching_ports[i])
            i++;
        if (p->num_ports > i)
            p->num_ports = i;
    }

    // create out output ports
    for (i = 0; i < p->num_ports; i++) {
        char pname[30];
        snprintf(pname, 30, "out_%d", i);
        p->ports[i] =
            jack_port_register(p->client, pname, JACK_DEFAULT_AUDIO_TYPE,
                               JackPortIsOutput, 0);
        if (!p->ports[i]) {
            MP_FATAL(ao, "not enough ports available\n");
            goto err_out;
        }
    }
    if (jack_activate(p->client)) {
        MP_FATAL(ao, "activate failed\n");
        goto err_out;
    }
    for (i = 0; i < p->num_ports; i++) {
        if (jack_connect(p->client, jack_port_name(p->ports[i]),
                         matching_ports[i]))
        {
            MP_FATAL(ao, "connecting failed\n");
            goto err_out;
        }
    }
    ao->samplerate = jack_get_sample_rate(p->client);
    jack_latency_range_t jack_latency_range;
    jack_port_get_latency_range(p->ports[0], JackPlaybackLatency,
                                &jack_latency_range);
    p->jack_latency = (float)(jack_latency_range.max + jack_get_buffer_size(p->client))
                      / (float)ao->samplerate;
    p->callback_interval = 0;

    if (!ao_chmap_sel_get_def(ao, &sel, &ao->channels, p->num_ports))
        goto err_out;

    ao->format = AF_FORMAT_FLOAT_NE;
    int unitsize = ao->channels.num * sizeof(float);
    p->outburst = (CHUNK_SIZE + unitsize - 1) / unitsize * unitsize;
    p->ring = mp_ring_new(p, NUM_CHUNKS * p->outburst);
    free(matching_ports);
    return 0;

err_out:
    free(matching_ports);
    if (p->client)
        jack_client_close(p->client);
    return -1;
}
Beispiel #5
0
// open & setup audio device
static int init(struct ao *ao)
{
    struct priv *ac = talloc_zero(ao, struct priv);
    AVCodec *codec;

    ao->priv = ac;

    if (!encode_lavc_available(ao->encode_lavc_ctx)) {
        MP_ERR(ao, "the option --o (output file) must be specified\n");
        return -1;
    }

    pthread_mutex_lock(&ao->encode_lavc_ctx->lock);

    if (encode_lavc_alloc_stream(ao->encode_lavc_ctx,
                                 AVMEDIA_TYPE_AUDIO,
                                 &ac->stream, &ac->codec) < 0) {
      MP_ERR(ao, "could not get a new audio stream\n");
      goto fail;
    }

    codec = ao->encode_lavc_ctx->ac;

    int samplerate = af_select_best_samplerate(ao->samplerate,
                                               codec->supported_samplerates);
    if (samplerate > 0)
        ao->samplerate = samplerate;

    // TODO: Remove this redundancy with encode_lavc_alloc_stream also
    // setting the time base.
    // Using codec->time_bvase is deprecated, but needed for older lavf.
    ac->stream->time_base.num = 1;
    ac->stream->time_base.den = ao->samplerate;
    ac->codec->time_base.num = 1;
    ac->codec->time_base.den = ao->samplerate;

    ac->codec->sample_rate = ao->samplerate;

    struct mp_chmap_sel sel = {0};
    mp_chmap_sel_add_any(&sel);
    if (!ao_chmap_sel_adjust2(ao, &sel, &ao->channels, false))
        goto fail;
    mp_chmap_reorder_to_lavc(&ao->channels);
    ac->codec->channels = ao->channels.num;
    ac->codec->channel_layout = mp_chmap_to_lavc(&ao->channels);

    ac->codec->sample_fmt = AV_SAMPLE_FMT_NONE;

    select_format(ao, codec);

    ac->sample_size = af_fmt_to_bytes(ao->format);
    ac->codec->sample_fmt = af_to_avformat(ao->format);
    ac->codec->bits_per_raw_sample = ac->sample_size * 8;

    if (encode_lavc_open_codec(ao->encode_lavc_ctx, ac->codec) < 0)
        goto fail;

    ac->pcmhack = 0;
    if (ac->codec->frame_size <= 1)
        ac->pcmhack = av_get_bits_per_sample(ac->codec->codec_id) / 8;

    if (ac->pcmhack)
        ac->aframesize = 16384; // "enough"
    else
        ac->aframesize = ac->codec->frame_size;

    // enough frames for at least 0.25 seconds
    ac->framecount = ceil(ao->samplerate * 0.25 / ac->aframesize);
    // but at least one!
    ac->framecount = FFMAX(ac->framecount, 1);

    ac->savepts = AV_NOPTS_VALUE;
    ac->lastpts = AV_NOPTS_VALUE;

    ao->untimed = true;

    if (ao->channels.num > AV_NUM_DATA_POINTERS)
        goto fail;

    pthread_mutex_unlock(&ao->encode_lavc_ctx->lock);
    return 0;

fail:
    pthread_mutex_unlock(&ao->encode_lavc_ctx->lock);
    ac->shutdown = true;
    return -1;
}
Beispiel #6
0
static int init(struct ao *ao)
{
    struct priv *p = ao->priv;
    struct mp_chmap_sel sel = {0};
    jack_options_t open_options;

    ao->format = AF_FORMAT_FLOATP;

    switch (p->stdlayout) {
    case 0:
        mp_chmap_sel_add_waveext(&sel);
        break;

    case 1:
        mp_chmap_sel_add_alsa_def(&sel);
        break;

    default:
        mp_chmap_sel_add_any(&sel);
    }

    if (!ao_chmap_sel_adjust(ao, &sel, &ao->channels))
        goto err_chmap;

    open_options = JackNullOption;
    if (!p->autostart)
        open_options |= JackNoStartServer;

    p->client = jack_client_open(p->cfg_client_name, open_options, NULL);
    if (!p->client) {
        MP_FATAL(ao, "cannot open server\n");
        goto err_client_open;
    }

    if (create_ports(ao, ao->channels.num))
        goto err_create_ports;

    jack_set_process_callback(p->client, process, ao);

    if (jack_activate(p->client)) {
        MP_FATAL(ao, "activate failed\n");
        goto err_activate;
    }

    ao->samplerate = jack_get_sample_rate(p->client);

    if (p->connect)
        if (connect_to_outports(ao))
            goto err_connect;

    jack_latency_range_t jack_latency_range;
    jack_port_get_latency_range(p->ports[0], JackPlaybackLatency,
                                &jack_latency_range);
    p->jack_latency = (float)(jack_latency_range.max + jack_get_buffer_size(p->client))
                      / (float)ao->samplerate;

    if (!ao_chmap_sel_get_def(ao, &sel, &ao->channels, p->num_ports))
        goto err_chmap_sel_get_def;

    return 0;

err_chmap_sel_get_def:
err_connect:
    jack_deactivate(p->client);
err_activate:
err_create_ports:
    jack_client_close(p->client);
err_client_open:
err_chmap:
    return -1;
}
Beispiel #7
0
// open & setup audio device
static int init(struct ao *ao)
{
    struct priv *ac = talloc_zero(ao, struct priv);
    AVCodec *codec;

    ao->priv = ac;

    if (!encode_lavc_available(ao->encode_lavc_ctx)) {
        MP_ERR(ao, "the option --o (output file) must be specified\n");
        return -1;
    }

    pthread_mutex_lock(&ao->encode_lavc_ctx->lock);

    ac->stream = encode_lavc_alloc_stream(ao->encode_lavc_ctx,
                                          AVMEDIA_TYPE_AUDIO);

    if (!ac->stream) {
        MP_ERR(ao, "could not get a new audio stream\n");
        goto fail;
    }

    codec = encode_lavc_get_codec(ao->encode_lavc_ctx, ac->stream);

    // ac->stream->time_base.num = 1;
    // ac->stream->time_base.den = ao->samplerate;
    // doing this breaks mpeg2ts in ffmpeg
    // which doesn't properly force the time base to be 90000
    // furthermore, ffmpeg.c doesn't do this either and works

    ac->stream->codec->time_base.num = 1;
    ac->stream->codec->time_base.den = ao->samplerate;

    ac->stream->codec->sample_rate = ao->samplerate;

    struct mp_chmap_sel sel = {0};
    mp_chmap_sel_add_any(&sel);
    if (!ao_chmap_sel_adjust(ao, &sel, &ao->channels))
        goto fail;
    mp_chmap_reorder_to_lavc(&ao->channels);
    ac->stream->codec->channels = ao->channels.num;
    ac->stream->codec->channel_layout = mp_chmap_to_lavc(&ao->channels);

    ac->stream->codec->sample_fmt = AV_SAMPLE_FMT_NONE;

    select_format(ao, codec);

    ac->sample_size = af_fmt2bits(ao->format) / 8;
    ac->stream->codec->sample_fmt = af_to_avformat(ao->format);
    ac->stream->codec->bits_per_raw_sample = ac->sample_size * 8;

    if (encode_lavc_open_codec(ao->encode_lavc_ctx, ac->stream) < 0)
        goto fail;

    ac->pcmhack = 0;
    if (ac->stream->codec->frame_size <= 1)
        ac->pcmhack = av_get_bits_per_sample(ac->stream->codec->codec_id) / 8;

    if (ac->pcmhack) {
        ac->aframesize = 16384; // "enough"
        ac->buffer_size =
            ac->aframesize * ac->pcmhack * ao->channels.num * 2 + 200;
    } else {
        ac->aframesize = ac->stream->codec->frame_size;
        ac->buffer_size =
            ac->aframesize * ac->sample_size * ao->channels.num * 2 + 200;
    }
    if (ac->buffer_size < FF_MIN_BUFFER_SIZE)
        ac->buffer_size = FF_MIN_BUFFER_SIZE;
    ac->buffer = talloc_size(ac, ac->buffer_size);

    // enough frames for at least 0.25 seconds
    ac->framecount = ceil(ao->samplerate * 0.25 / ac->aframesize);
    // but at least one!
    ac->framecount = FFMAX(ac->framecount, 1);

    ac->savepts = MP_NOPTS_VALUE;
    ac->lastpts = MP_NOPTS_VALUE;

    ao->untimed = true;

    pthread_mutex_unlock(&ao->encode_lavc_ctx->lock);
    return 0;

fail:
    pthread_mutex_unlock(&ao->encode_lavc_ctx->lock);
    return -1;
}