int groove_encoder_detach(struct GrooveEncoder *encoder) { struct GrooveEncoderPrivate *e = (struct GrooveEncoderPrivate *) encoder; e->abort_request = 1; groove_sink_detach(e->sink); groove_queue_flush(e->audioq); groove_queue_abort(e->audioq); pthread_cond_signal(&e->drain_cond); pthread_join(e->thread_id, NULL); e->abort_request = 0; cleanup_avcontext(e); e->oformat = NULL; e->codec = NULL; encoder->playlist = NULL; return 0; }
int groove_sink_detach(struct GrooveSink *sink) { struct GroovePlaylist *playlist = sink->playlist; if (!playlist) return -1; struct GrooveSinkPrivate *s = (struct GrooveSinkPrivate *) sink; if (s->audioq) { groove_queue_abort(s->audioq); groove_queue_flush(s->audioq); } struct GroovePlaylistPrivate *p = (struct GroovePlaylistPrivate *) playlist; pthread_mutex_lock(&p->decode_head_mutex); int err = remove_sink_from_map(sink); pthread_mutex_unlock(&p->decode_head_mutex); sink->playlist = NULL; return err; }
int groove_fingerprinter_detach(struct GrooveFingerprinter *printer) { struct GrooveFingerprinterPrivate *p = (struct GrooveFingerprinterPrivate *) printer; p->abort_request.store(true); groove_sink_detach(p->sink); groove_queue_flush(p->info_queue); groove_queue_abort(p->info_queue); pthread_cond_signal(&p->drain_cond); pthread_join(p->thread_id, NULL); printer->playlist = NULL; if (p->chroma_ctx) { chromaprint_free(p->chroma_ctx); p->chroma_ctx = NULL; } p->abort_request.store(false); p->info_head = NULL; p->info_pos = 0; p->track_duration = 0.0; return 0; }