コード例 #1
0
ファイル: playlist.c プロジェクト: kallisti5/libgroove
int groove_sink_attach(struct GrooveSink *sink, struct GroovePlaylist *playlist) {
    struct GrooveSinkPrivate *s = (struct GrooveSinkPrivate *) sink;

    // cache computed audio format stuff
    int channel_count = av_get_channel_layout_nb_channels(sink->audio_format.channel_layout);
    int bytes_per_frame = channel_count *
        av_get_bytes_per_sample((enum AVSampleFormat)sink->audio_format.sample_fmt);
    sink->bytes_per_sec = bytes_per_frame * sink->audio_format.sample_rate;

    s->min_audioq_size = sink->buffer_size * bytes_per_frame;
    av_log(NULL, AV_LOG_INFO, "audio queue size: %d\n", s->min_audioq_size);

    // add the sink to the entry that matches its audio format
    struct GroovePlaylistPrivate *p = (struct GroovePlaylistPrivate *) playlist;

    pthread_mutex_lock(&p->decode_head_mutex);
    int err = add_sink_to_map(playlist, sink);
    pthread_cond_signal(&p->sink_drain_cond);
    pthread_mutex_unlock(&p->decode_head_mutex);

    if (err < 0) {
        av_log(NULL, AV_LOG_ERROR, "unable to attach device: out of memory\n");
        return err;
    }

    // in case we've called abort on the queue, reset
    groove_queue_reset(s->audioq);

    sink->playlist = playlist;

    return 0;
}
コード例 #2
0
ファイル: fingerprinter.cpp プロジェクト: mcanthony/libgroove
int groove_fingerprinter_attach(struct GrooveFingerprinter *printer,
        struct GroovePlaylist *playlist)
{
    struct GrooveFingerprinterPrivate *p = (struct GrooveFingerprinterPrivate *) printer;

    printer->playlist = playlist;
    groove_queue_reset(p->info_queue);

    p->chroma_ctx = chromaprint_new(CHROMAPRINT_ALGORITHM_DEFAULT);
    if (!p->chroma_ctx) {
        groove_fingerprinter_detach(printer);
        return GrooveErrorNoMem;
    }

    int err;
    if ((err = groove_sink_attach(p->sink, playlist))) {
        groove_fingerprinter_detach(printer);
        return err;
    }

    if (pthread_create(&p->thread_id, NULL, print_thread, printer)) {
        groove_fingerprinter_detach(printer);
        return GrooveErrorSystemResources;
    }

    return 0;
}
コード例 #3
0
ファイル: encoder.c プロジェクト: icewwn/libgroove
int groove_encoder_attach(struct GrooveEncoder *encoder, struct GroovePlaylist *playlist) {
    struct GrooveEncoderPrivate *e = (struct GrooveEncoderPrivate *) encoder;

    encoder->playlist = playlist;
    groove_queue_reset(e->audioq);

    e->oformat = av_guess_format(encoder->format_short_name,
            encoder->filename, encoder->mime_type);
    if (!e->oformat) {
        groove_encoder_detach(encoder);
        av_log(NULL, AV_LOG_ERROR, "unable to determine format\n");
        return -1;
    }

    // av_guess_codec ignores mime_type, filename, and codec_short_name. see
    // https://trac.ffmpeg.org/ticket/4706
    // because of this we do a workaround to return the correct codec based on
    // the codec_short_name.
    AVCodec *codec = NULL;
    if (encoder->codec_short_name) {
        codec = avcodec_find_encoder_by_name(encoder->codec_short_name);
        if (!codec) {
            const AVCodecDescriptor *desc =
                avcodec_descriptor_get_by_name(encoder->codec_short_name);
            if (desc) {
                codec = avcodec_find_encoder(desc->id);
            }
        }
    }
    if (!codec) {
        enum AVCodecID codec_id = av_guess_codec(e->oformat,
                encoder->codec_short_name, encoder->filename, encoder->mime_type,
                AVMEDIA_TYPE_AUDIO);
        codec = avcodec_find_encoder(codec_id);
        if (!codec) {
            groove_encoder_detach(encoder);
            av_log(NULL, AV_LOG_ERROR, "unable to find encoder\n");
            return -1;
        }
    }
    e->codec = codec;
    av_log(NULL, AV_LOG_INFO, "encoder: using codec: %s\n", codec->long_name);

    encoder->actual_audio_format.sample_fmt = closest_supported_sample_fmt(
            codec, encoder->target_audio_format.sample_fmt);
    encoder->actual_audio_format.sample_rate = closest_supported_sample_rate(
            codec, encoder->target_audio_format.sample_rate);
    encoder->actual_audio_format.channel_layout = closest_supported_channel_layout(
            codec, encoder->target_audio_format.channel_layout);

    log_audio_fmt(&encoder->actual_audio_format);

    int err = init_avcontext(encoder);
    if (err < 0) {
        groove_encoder_detach(encoder);
        return err;
    }

    e->sink->audio_format = encoder->actual_audio_format;
    e->sink->buffer_size = encoder->sink_buffer_size;
    e->sink->buffer_sample_count = (codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE) ?
        0 : e->stream->codec->frame_size;
    e->sink->gain = encoder->gain;

    if (groove_sink_attach(e->sink, playlist) < 0) {
        groove_encoder_detach(encoder);
        av_log(NULL, AV_LOG_ERROR, "unable to attach sink\n");
        return -1;
    }

    if (pthread_create(&e->thread_id, NULL, encode_thread, encoder) != 0) {
        groove_encoder_detach(encoder);
        av_log(NULL, AV_LOG_ERROR, "unable to create encoder thread\n");
        return -1;
    }

    return 0;
}