Ejemplo n.º 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);
}
Ejemplo n.º 2
0
static void select_format(struct ao *ao, AVCodec *codec)
{
    int formats[AF_FORMAT_COUNT];
    af_get_best_sample_formats(ao->format, formats);

    for (int n = 0; formats[n]; n++) {
        if (supports_format(codec, formats[n])) {
            ao->format = formats[n];
            break;
        }
    }
}
Ejemplo n.º 3
0
static int init(struct ao *ao)
{
    float position[3] = {0, 0, 0};
    float direction[6] = {0, 0, -1, 0, 1, 0};
    ALCdevice *dev = NULL;
    ALCcontext *ctx = NULL;
    ALCint freq = 0;
    ALCint attribs[] = {ALC_FREQUENCY, ao->samplerate, 0, 0};
    int i;
    struct priv *p = ao->priv;
    if (ao_data) {
        MP_FATAL(ao, "Not reentrant!\n");
        return -1;
    }
    ao_data = ao;
    struct mp_chmap_sel sel = {0};
    for (i = 0; speaker_pos[i].id != -1; i++)
        mp_chmap_sel_add_speaker(&sel, speaker_pos[i].id);
    if (!ao_chmap_sel_adjust(ao, &sel, &ao->channels))
        goto err_out;
    struct speaker speakers[MAX_CHANS];
    for (i = 0; i < ao->channels.num; i++) {
        speakers[i].id = -1;
        for (int n = 0; speaker_pos[n].id >= 0; n++) {
            if (speaker_pos[n].id == ao->channels.speaker[i])
                speakers[i] = speaker_pos[n];
        }
        if (speakers[i].id < 0) {
            MP_FATAL(ao, "Unknown channel layout\n");
            goto err_out;
        }
    }
    char *dev_name = ao->device;
    dev = alcOpenDevice(dev_name && dev_name[0] ? dev_name : NULL);
    if (!dev) {
        MP_FATAL(ao, "could not open device\n");
        goto err_out;
    }
    ctx = alcCreateContext(dev, attribs);
    alcMakeContextCurrent(ctx);
    alListenerfv(AL_POSITION, position);
    alListenerfv(AL_ORIENTATION, direction);
    alGenSources(ao->channels.num, sources);
    for (i = 0; i < ao->channels.num; i++) {
        cur_buf[i] = 0;
        unqueue_buf[i] = 0;
        alGenBuffers(NUM_BUF, buffers[i]);
        alSourcefv(sources[i], AL_POSITION, speakers[i].pos);
        alSource3f(sources[i], AL_VELOCITY, 0, 0, 0);
    }
    alcGetIntegerv(dev, ALC_FREQUENCY, 1, &freq);
    if (alcGetError(dev) == ALC_NO_ERROR && freq)
        ao->samplerate = freq;

    p->al_format = AL_FALSE;
    int try_formats[AF_FORMAT_COUNT];
    af_get_best_sample_formats(ao->format, try_formats);
    for (int n = 0; try_formats[n]; n++) {
        p->al_format = get_al_format(try_formats[n]);
        if (p->al_format != AL_FALSE) {
            ao->format = try_formats[n];
            break;
        }
    }

    if (p->al_format == AL_FALSE) {
        MP_FATAL(ao, "Can't find appropriate sample format.\n");
        uninit(ao);
        goto err_out;
    }

    p->chunk_size = CHUNK_SAMPLES * af_fmt_to_bytes(ao->format);
    return 0;

err_out:
    ao_data = NULL;
    return -1;
}