struct GrooveSink * groove_sink_create(void) { struct GrooveSinkPrivate *s = av_mallocz(sizeof(struct GrooveSinkPrivate)); if (!s) { av_log(NULL, AV_LOG_ERROR, "could not create sink: out of memory\n"); return NULL; } struct GrooveSink *sink = &s->externals; sink->buffer_size = 8192; s->audioq = groove_queue_create(); if (!s->audioq) { groove_sink_destroy(sink); av_log(NULL, AV_LOG_ERROR, "could not create audio buffer: out of memory\n"); return NULL; } s->audioq->context = sink; s->audioq->cleanup = audioq_cleanup; s->audioq->put = audioq_put; s->audioq->get = audioq_get; s->audioq->purge = audioq_purge; return sink; }
struct GrooveFingerprinter *groove_fingerprinter_create(struct Groove *groove) { struct GrooveFingerprinterPrivate *p = allocate<GrooveFingerprinterPrivate>(1); if (!p) { av_log(NULL, AV_LOG_ERROR, "unable to allocate fingerprinter\n"); return NULL; } p->abort_request.store(false); p->groove = groove; struct GrooveFingerprinter *printer = &p->externals; if (pthread_mutex_init(&p->info_head_mutex, NULL) != 0) { groove_fingerprinter_destroy(printer); av_log(NULL, AV_LOG_ERROR, "unable to create mutex\n"); return NULL; } p->info_head_mutex_inited = 1; if (pthread_cond_init(&p->drain_cond, NULL) != 0) { groove_fingerprinter_destroy(printer); av_log(NULL, AV_LOG_ERROR, "unable to create mutex condition\n"); return NULL; } p->drain_cond_inited = 1; p->info_queue = groove_queue_create(); if (!p->info_queue) { groove_fingerprinter_destroy(printer); av_log(NULL, AV_LOG_ERROR, "unable to allocate queue\n"); return NULL; } p->info_queue->context = printer; p->info_queue->cleanup = info_queue_cleanup; p->info_queue->put = info_queue_put; p->info_queue->get = info_queue_get; p->info_queue->purge = info_queue_purge; p->sink = groove_sink_create(groove); if (!p->sink) { groove_fingerprinter_destroy(printer); av_log(NULL, AV_LOG_ERROR, "unable to allocate sink\n"); return NULL; } GrooveAudioFormat audio_format; audio_format.sample_rate = 44100; audio_format.layout = *soundio_channel_layout_get_builtin(SoundIoChannelLayoutIdStereo); audio_format.format = SoundIoFormatS16NE; audio_format.is_planar = false; groove_sink_set_only_format(p->sink, &audio_format); p->sink->userdata = printer; p->sink->purge = sink_purge; p->sink->flush = sink_flush; // set some defaults printer->info_queue_size = INT_MAX; printer->sink_buffer_size_bytes = p->sink->buffer_size_bytes; return printer; }
struct GrooveEncoder *groove_encoder_create(void) { struct GrooveEncoderPrivate *e = av_mallocz(sizeof(struct GrooveEncoderPrivate)); if (!e) { av_log(NULL, AV_LOG_ERROR, "unable to allocate encoder\n"); return NULL; } struct GrooveEncoder *encoder = &e->externals; const int buffer_size = 4 * 1024; e->avio_buf = av_malloc(buffer_size); if (!e->avio_buf) { groove_encoder_destroy(encoder); av_log(NULL, AV_LOG_ERROR, "unable to allocate avio buffer\n"); return NULL; } e->avio = avio_alloc_context(e->avio_buf, buffer_size, 1, encoder, NULL, encoder_write_packet, NULL); if (!e->avio) { groove_encoder_destroy(encoder); av_log(NULL, AV_LOG_ERROR, "unable to allocate avio context\n"); return NULL; } if (pthread_mutex_init(&e->encode_head_mutex, NULL) != 0) { groove_encoder_destroy(encoder); av_log(NULL, AV_LOG_ERROR, "unable to create mutex\n"); return NULL; } e->encode_head_mutex_inited = 1; if (pthread_cond_init(&e->drain_cond, NULL) != 0) { groove_encoder_destroy(encoder); av_log(NULL, AV_LOG_ERROR, "unable to create mutex condition\n"); return NULL; } e->drain_cond_inited = 1; e->audioq = groove_queue_create(); if (!e->audioq) { groove_encoder_destroy(encoder); av_log(NULL, AV_LOG_ERROR, "unable to allocate queue\n"); return NULL; } e->audioq->context = encoder; e->audioq->cleanup = audioq_cleanup; e->audioq->put = audioq_put; e->audioq->get = audioq_get; e->audioq->purge = audioq_purge; e->sink = groove_sink_create(); if (!e->sink) { groove_encoder_destroy(encoder); av_log(NULL, AV_LOG_ERROR, "unable to allocate sink\n"); return NULL; } e->sink->userdata = encoder; e->sink->purge = sink_purge; e->sink->flush = sink_flush; // set some defaults encoder->bit_rate = 256 * 1000; encoder->target_audio_format.sample_rate = 44100; encoder->target_audio_format.sample_fmt = GROOVE_SAMPLE_FMT_S16; encoder->target_audio_format.channel_layout = GROOVE_CH_LAYOUT_STEREO; encoder->sink_buffer_size = e->sink->buffer_size; encoder->encoded_buffer_size = 16 * 1024; encoder->gain = e->sink->gain; return encoder; }