1 /*
2  * Copyright (c) 2013 Andrew Kelley
3  *
4  * This file is part of libgroove, which is MIT licensed.
5  * See http://opensource.org/licenses/MIT
6  */
7 
8 #include "encoder.h"
9 #include "queue.h"
10 #include "buffer.h"
11 
12 #include <libavutil/mem.h>
13 #include <libavutil/log.h>
14 #include <libavutil/channel_layout.h>
15 #include <libavutil/dict.h>
16 #include <libavcodec/avcodec.h>
17 #include <libavformat/avformat.h>
18 #include <libavformat/avio.h>
19 #include <string.h>
20 #include <pthread.h>
21 
22 struct GrooveEncoderPrivate {
23     struct GrooveEncoder externals;
24     struct GrooveQueue *audioq;
25     struct GrooveSink *sink;
26     AVFormatContext *fmt_ctx;
27     AVOutputFormat *oformat;
28     AVCodec *codec;
29     AVStream *stream;
30     AVPacket pkt;
31     int audioq_size; // in bytes
32     int abort_request;
33 
34     // set temporarily
35     struct GroovePlaylistItem *purge_item;
36 
37     // encode_head_mutex applies to variables inside this block.
38     pthread_mutex_t encode_head_mutex;
39     char encode_head_mutex_inited;
40     // encode_thread waits on this when the encoded audio buffer queue
41     // is full.
42     pthread_cond_t drain_cond;
43     char drain_cond_inited;
44     struct GroovePlaylistItem *encode_head;
45     double encode_pos;
46     uint64_t encode_pts;
47 
48     struct GrooveAudioFormat encode_format;
49 
50     pthread_t thread_id;
51 
52     AVIOContext *avio;
53     unsigned char *avio_buf;
54 
55     int sent_header;
56     char strbuf[512];
57 
58     AVDictionary *metadata;
59 
60     uint64_t next_pts;
61 };
62 
63 static struct GrooveBuffer *end_of_q_sentinel = NULL;
64 
encode_buffer(struct GrooveEncoder * encoder,struct GrooveBuffer * buffer)65 static int encode_buffer(struct GrooveEncoder *encoder, struct GrooveBuffer *buffer) {
66     struct GrooveEncoderPrivate *e = (struct GrooveEncoderPrivate *) encoder;
67 
68     av_init_packet(&e->pkt);
69 
70     AVFrame *frame = NULL;
71     if (buffer) {
72         e->encode_head = buffer->item;
73         e->encode_pos = buffer->pos;
74         e->encode_format = buffer->format;
75 
76         struct GrooveBufferPrivate *b = (struct GrooveBufferPrivate *) buffer;
77         frame = b->frame;
78         frame->pts = e->next_pts;
79         e->encode_pts = e->next_pts;
80         e->next_pts += buffer->frame_count + 1;
81     }
82 
83     int got_packet = 0;
84     int errcode = avcodec_encode_audio2(e->stream->codec, &e->pkt, frame, &got_packet);
85     if (errcode < 0) {
86         av_strerror(errcode, e->strbuf, sizeof(e->strbuf));
87         av_log(NULL, AV_LOG_ERROR, "error encoding audio frame: %s\n", e->strbuf);
88         return -1;
89     }
90     if (!got_packet)
91         return -1;
92 
93     av_write_frame(e->fmt_ctx, &e->pkt);
94     av_free_packet(&e->pkt);
95 
96     return 0;
97 }
98 
cleanup_avcontext(struct GrooveEncoderPrivate * e)99 static void cleanup_avcontext(struct GrooveEncoderPrivate *e) {
100     if (e->stream) {
101         avcodec_close(e->stream->codec);
102         // stream is freed by freeing the AVFormatContext
103         e->stream = NULL;
104     }
105 
106     if (e->fmt_ctx) {
107         avformat_free_context(e->fmt_ctx);
108         e->fmt_ctx = NULL;
109     }
110 
111     e->sent_header = 0;
112     e->encode_head = NULL;
113     e->encode_pos = -1.0;
114     e->encode_pts = 0;
115     e->next_pts = 0;
116 }
117 
init_avcontext(struct GrooveEncoder * encoder)118 static int init_avcontext(struct GrooveEncoder *encoder) {
119     struct GrooveEncoderPrivate *e = (struct GrooveEncoderPrivate *) encoder;
120     e->fmt_ctx = avformat_alloc_context();
121     if (!e->fmt_ctx) {
122         av_log(NULL, AV_LOG_ERROR, "unable to allocate format context\n");
123         return -1;
124     }
125     e->fmt_ctx->pb = e->avio;
126     e->fmt_ctx->oformat = e->oformat;
127 
128     e->stream = avformat_new_stream(e->fmt_ctx, e->codec);
129     if (!e->stream) {
130         av_log(NULL, AV_LOG_ERROR, "unable to create output stream\n");
131         return -1;
132     }
133 
134     AVCodecContext *codec_ctx = e->stream->codec;
135     codec_ctx->bit_rate = encoder->bit_rate;
136     codec_ctx->sample_fmt = (enum AVSampleFormat)encoder->actual_audio_format.sample_fmt;
137     codec_ctx->sample_rate = encoder->actual_audio_format.sample_rate;
138     codec_ctx->channel_layout = encoder->actual_audio_format.channel_layout;
139     codec_ctx->channels = av_get_channel_layout_nb_channels(encoder->actual_audio_format.channel_layout);
140     codec_ctx->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
141 
142     int err = avcodec_open2(codec_ctx, e->codec, NULL);
143     if (err < 0) {
144         av_strerror(err, e->strbuf, sizeof(e->strbuf));
145         av_log(NULL, AV_LOG_ERROR, "unable to open codec: %s\n", e->strbuf);
146         return -1;
147     }
148     e->stream->codec = codec_ctx;
149 
150     return 0;
151 }
152 
encode_thread(void * arg)153 static void *encode_thread(void *arg) {
154     struct GrooveEncoder *encoder = arg;
155     struct GrooveEncoderPrivate *e = (struct GrooveEncoderPrivate *) encoder;
156 
157     struct GrooveBuffer *buffer;
158     while (!e->abort_request) {
159         pthread_mutex_lock(&e->encode_head_mutex);
160 
161         if (e->audioq_size >= encoder->encoded_buffer_size) {
162             pthread_cond_wait(&e->drain_cond, &e->encode_head_mutex);
163             pthread_mutex_unlock(&e->encode_head_mutex);
164             continue;
165         }
166 
167         // we definitely want to unlock the mutex while we wait for the
168         // next buffer. Otherwise there will be a deadlock when sink_flush or
169         // sink_purge is called.
170         pthread_mutex_unlock(&e->encode_head_mutex);
171 
172         int result = groove_sink_buffer_get(e->sink, &buffer, 1);
173 
174         pthread_mutex_lock(&e->encode_head_mutex);
175 
176         if (result == GROOVE_BUFFER_END) {
177             // flush encoder with empty packets
178             while (encode_buffer(encoder, NULL) >= 0) {}
179             // then flush format context with empty packets
180             while (av_write_frame(e->fmt_ctx, NULL) == 0) {}
181 
182             // send trailer
183             avio_flush(e->avio);
184             av_log(NULL, AV_LOG_INFO, "encoder: writing trailer\n");
185             if (av_write_trailer(e->fmt_ctx) < 0) {
186                 av_log(NULL, AV_LOG_ERROR, "could not write trailer\n");
187             }
188             avio_flush(e->avio);
189 
190             groove_queue_put(e->audioq, end_of_q_sentinel);
191 
192             cleanup_avcontext(e);
193             init_avcontext(encoder);
194 
195             pthread_mutex_unlock(&e->encode_head_mutex);
196             continue;
197         }
198 
199         if (result != GROOVE_BUFFER_YES) {
200             pthread_mutex_unlock(&e->encode_head_mutex);
201             break;
202         }
203 
204         if (!e->sent_header) {
205             avio_flush(e->avio);
206 
207             // copy metadata to format context
208             av_dict_free(&e->fmt_ctx->metadata);
209             AVDictionaryEntry *tag = NULL;
210             while((tag = av_dict_get(e->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) {
211                 av_dict_set(&e->fmt_ctx->metadata, tag->key, tag->value, AV_DICT_IGNORE_SUFFIX);
212             }
213 
214             av_log(NULL, AV_LOG_INFO, "encoder: writing header\n");
215             if (avformat_write_header(e->fmt_ctx, NULL) < 0) {
216                 av_log(NULL, AV_LOG_ERROR, "could not write header\n");
217             }
218             avio_flush(e->avio);
219             e->sent_header = 1;
220         }
221 
222         encode_buffer(encoder, buffer);
223         pthread_mutex_unlock(&e->encode_head_mutex);
224         groove_buffer_unref(buffer);
225     }
226     return NULL;
227 }
228 
sink_purge(struct GrooveSink * sink,struct GroovePlaylistItem * item)229 static void sink_purge(struct GrooveSink *sink, struct GroovePlaylistItem *item) {
230     struct GrooveEncoder *encoder = sink->userdata;
231     struct GrooveEncoderPrivate *e = (struct GrooveEncoderPrivate *) encoder;
232 
233     pthread_mutex_lock(&e->encode_head_mutex);
234     e->purge_item = item;
235     groove_queue_purge(e->audioq);
236     e->purge_item = NULL;
237 
238     if (e->encode_head == item) {
239         e->encode_head = NULL;
240         e->encode_pos = -1.0;
241     }
242     pthread_cond_signal(&e->drain_cond);
243     pthread_mutex_unlock(&e->encode_head_mutex);
244 }
245 
sink_flush(struct GrooveSink * sink)246 static void sink_flush(struct GrooveSink *sink) {
247     struct GrooveEncoder *encoder = sink->userdata;
248     struct GrooveEncoderPrivate *e = (struct GrooveEncoderPrivate *) encoder;
249 
250     pthread_mutex_lock(&e->encode_head_mutex);
251     groove_queue_flush(e->audioq);
252 
253     cleanup_avcontext(e);
254     init_avcontext(encoder);
255     groove_queue_put(e->audioq, end_of_q_sentinel);
256 
257     pthread_cond_signal(&e->drain_cond);
258     pthread_mutex_unlock(&e->encode_head_mutex);
259 }
260 
audioq_purge(struct GrooveQueue * queue,void * obj)261 static int audioq_purge(struct GrooveQueue* queue, void *obj) {
262     struct GrooveBuffer *buffer = obj;
263     if (buffer == end_of_q_sentinel)
264         return 0;
265     struct GrooveEncoderPrivate *e = queue->context;
266     return buffer->item == e->purge_item;
267 }
268 
audioq_cleanup(struct GrooveQueue * queue,void * obj)269 static void audioq_cleanup(struct GrooveQueue* queue, void *obj) {
270     struct GrooveBuffer *buffer = obj;
271     if (buffer == end_of_q_sentinel)
272         return;
273     struct GrooveEncoderPrivate *e = queue->context;
274     e->audioq_size -= buffer->size;
275     groove_buffer_unref(buffer);
276 }
277 
audioq_put(struct GrooveQueue * queue,void * obj)278 static void audioq_put(struct GrooveQueue *queue, void *obj) {
279     struct GrooveBuffer *buffer = obj;
280     if (buffer == end_of_q_sentinel)
281         return;
282     struct GrooveEncoderPrivate *e = queue->context;
283     e->audioq_size += buffer->size;
284 }
285 
audioq_get(struct GrooveQueue * queue,void * obj)286 static void audioq_get(struct GrooveQueue *queue, void *obj) {
287     struct GrooveBuffer *buffer = obj;
288     if (buffer == end_of_q_sentinel)
289         return;
290     struct GrooveEncoderPrivate *e = queue->context;
291     struct GrooveEncoder *encoder = &e->externals;
292     e->audioq_size -= buffer->size;
293 
294     if (e->audioq_size < encoder->encoded_buffer_size)
295         pthread_cond_signal(&e->drain_cond);
296 }
297 
encoder_write_packet(void * opaque,uint8_t * buf,int buf_size)298 static int encoder_write_packet(void *opaque, uint8_t *buf, int buf_size) {
299     struct GrooveEncoderPrivate *e = opaque;
300 
301     struct GrooveBufferPrivate *b = av_mallocz(sizeof(struct GrooveBufferPrivate));
302 
303     if (!b) {
304         av_log(NULL, AV_LOG_ERROR, "unable to allocate buffer\n");
305         return -1;
306     }
307 
308     struct GrooveBuffer *buffer = &b->externals;
309 
310     if (pthread_mutex_init(&b->mutex, NULL) != 0) {
311         av_free(b);
312         av_log(NULL, AV_LOG_ERROR, "unable to create mutex\n");
313         return -1;
314     }
315 
316     buffer->item = e->encode_head;
317     buffer->pos = e->encode_pos;
318     buffer->pts = e->encode_pts;
319     buffer->format = e->encode_format;
320 
321     b->is_packet = 1;
322     b->data = av_malloc(buf_size);
323     if (!b->data) {
324         av_free(buffer);
325         av_free(b);
326         pthread_mutex_destroy(&b->mutex);
327         av_log(NULL, AV_LOG_ERROR, "unable to create data buffer\n");
328         return -1;
329     }
330     memcpy(b->data, buf, buf_size);
331 
332     buffer->data = &b->data;
333     buffer->size = buf_size;
334 
335     b->ref_count = 1;
336 
337     groove_queue_put(e->audioq, buffer);
338 
339     return 0;
340 }
341 
groove_encoder_create(void)342 struct GrooveEncoder *groove_encoder_create(void) {
343     struct GrooveEncoderPrivate *e = av_mallocz(sizeof(struct GrooveEncoderPrivate));
344 
345     if (!e) {
346         av_log(NULL, AV_LOG_ERROR, "unable to allocate encoder\n");
347         return NULL;
348     }
349     struct GrooveEncoder *encoder = &e->externals;
350 
351     const int buffer_size = 4 * 1024;
352     e->avio_buf = av_malloc(buffer_size);
353     if (!e->avio_buf) {
354         groove_encoder_destroy(encoder);
355         av_log(NULL, AV_LOG_ERROR, "unable to allocate avio buffer\n");
356         return NULL;
357     }
358 
359     e->avio = avio_alloc_context(e->avio_buf, buffer_size, 1, encoder, NULL,
360             encoder_write_packet, NULL);
361     if (!e->avio) {
362         groove_encoder_destroy(encoder);
363         av_log(NULL, AV_LOG_ERROR, "unable to allocate avio context\n");
364         return NULL;
365     }
366 
367     if (pthread_mutex_init(&e->encode_head_mutex, NULL) != 0) {
368         groove_encoder_destroy(encoder);
369         av_log(NULL, AV_LOG_ERROR, "unable to create mutex\n");
370         return NULL;
371     }
372     e->encode_head_mutex_inited = 1;
373 
374     if (pthread_cond_init(&e->drain_cond, NULL) != 0) {
375         groove_encoder_destroy(encoder);
376         av_log(NULL, AV_LOG_ERROR, "unable to create mutex condition\n");
377         return NULL;
378     }
379     e->drain_cond_inited = 1;
380 
381     e->audioq = groove_queue_create();
382     if (!e->audioq) {
383         groove_encoder_destroy(encoder);
384         av_log(NULL, AV_LOG_ERROR, "unable to allocate queue\n");
385         return NULL;
386     }
387     e->audioq->context = encoder;
388     e->audioq->cleanup = audioq_cleanup;
389     e->audioq->put = audioq_put;
390     e->audioq->get = audioq_get;
391     e->audioq->purge = audioq_purge;
392 
393     e->sink = groove_sink_create();
394     if (!e->sink) {
395         groove_encoder_destroy(encoder);
396         av_log(NULL, AV_LOG_ERROR, "unable to allocate sink\n");
397         return NULL;
398     }
399 
400     e->sink->userdata = encoder;
401     e->sink->purge = sink_purge;
402     e->sink->flush = sink_flush;
403 
404     // set some defaults
405     encoder->bit_rate = 256 * 1000;
406     encoder->target_audio_format.sample_rate = 44100;
407     encoder->target_audio_format.sample_fmt = GROOVE_SAMPLE_FMT_S16;
408     encoder->target_audio_format.channel_layout = GROOVE_CH_LAYOUT_STEREO;
409     encoder->sink_buffer_size = e->sink->buffer_size;
410     encoder->encoded_buffer_size = 16 * 1024;
411     encoder->gain = e->sink->gain;
412 
413     return encoder;
414 }
415 
groove_encoder_destroy(struct GrooveEncoder * encoder)416 void groove_encoder_destroy(struct GrooveEncoder *encoder) {
417     struct GrooveEncoderPrivate *e = (struct GrooveEncoderPrivate *) encoder;
418 
419     if (e->sink)
420         groove_sink_destroy(e->sink);
421 
422     if (e->audioq)
423         groove_queue_destroy(e->audioq);
424 
425     if (e->encode_head_mutex_inited)
426         pthread_mutex_destroy(&e->encode_head_mutex);
427 
428     if (e->drain_cond_inited)
429         pthread_cond_destroy(&e->drain_cond);
430 
431     if (e->avio)
432         av_free(e->avio);
433 
434     if (e->avio_buf)
435         av_free(e->avio_buf);
436 
437     if (e->metadata)
438         av_dict_free(&e->metadata);
439 
440     av_free(e);
441 }
442 
abs_diff(int a,int b)443 static int abs_diff(int a, int b) {
444     int n = a - b;
445     return n >= 0 ? n : -n;
446 }
447 
codec_supports_fmt(AVCodec * codec,enum GrooveSampleFormat fmt)448 static int codec_supports_fmt(AVCodec *codec, enum GrooveSampleFormat fmt) {
449     const enum GrooveSampleFormat *p = (enum GrooveSampleFormat*) codec->sample_fmts;
450 
451     while (*p != GROOVE_SAMPLE_FMT_NONE) {
452         if (*p == fmt)
453             return 1;
454         p += 1;
455     }
456 
457     return 0;
458 }
459 
closest_supported_sample_fmt(AVCodec * codec,enum GrooveSampleFormat target)460 static enum GrooveSampleFormat closest_supported_sample_fmt(AVCodec *codec,
461         enum GrooveSampleFormat target)
462 {
463     // if we can, return exact match. otherwise, return the format with the
464     // next highest sample byte count
465 
466     if (!codec->sample_fmts)
467         return target;
468 
469     int target_size = av_get_bytes_per_sample((enum AVSampleFormat)target);
470     const enum GrooveSampleFormat *p = (enum GrooveSampleFormat*) codec->sample_fmts;
471     enum GrooveSampleFormat best = *p;
472     int best_size = av_get_bytes_per_sample((enum AVSampleFormat)best);
473     while (*p != GROOVE_SAMPLE_FMT_NONE) {
474         if (*p == target)
475             return target;
476 
477         int size = av_get_bytes_per_sample((enum AVSampleFormat)*p);
478         if ((best_size < target_size && size > best_size) ||
479             (size >= target_size &&
480              abs_diff(target_size, size) < abs_diff(target_size, best_size)))
481         {
482             best_size = size;
483             best = *p;
484         }
485 
486         p += 1;
487     }
488 
489     // prefer interleaved format
490     enum GrooveSampleFormat packed_best = (enum GrooveSampleFormat)av_get_packed_sample_fmt((enum AVSampleFormat)best);
491     return codec_supports_fmt(codec, packed_best) ? packed_best : best;
492 }
493 
closest_supported_sample_rate(AVCodec * codec,int target)494 static int closest_supported_sample_rate(AVCodec *codec, int target) {
495     // if we can, return exact match. otherwise, return the minimum sample
496     // rate >= target
497 
498     if (!codec->supported_samplerates)
499         return target;
500 
501     const int *p = codec->supported_samplerates;
502     int best = *p;
503 
504     while (*p) {
505         if (*p == target)
506             return target;
507 
508         if ((best < target && *p > best) || (*p >= target &&
509                     abs_diff(target, *p) < abs_diff(target, best)))
510         {
511             best = *p;
512         }
513 
514         p += 1;
515     }
516 
517     return best;
518 }
519 
closest_supported_channel_layout(AVCodec * codec,uint64_t target)520 static uint64_t closest_supported_channel_layout(AVCodec *codec, uint64_t target) {
521     // if we can, return exact match. otherwise, return the layout with the
522     // minimum number of channels >= target
523 
524     if (!codec->channel_layouts)
525         return target;
526 
527     int target_count = av_get_channel_layout_nb_channels(target);
528     const uint64_t *p = codec->channel_layouts;
529     uint64_t best = *p;
530     int best_count = av_get_channel_layout_nb_channels(best);
531     while (*p) {
532         if (*p == target)
533             return target;
534 
535         int count = av_get_channel_layout_nb_channels(*p);
536         if ((best_count < target_count && count > best_count) ||
537             (count >= target_count &&
538              abs_diff(target_count, count) < abs_diff(target_count, best_count)))
539         {
540             best_count = count;
541             best = *p;
542         }
543 
544         p += 1;
545     }
546 
547     return best;
548 }
549 
log_audio_fmt(const struct GrooveAudioFormat * fmt)550 static void log_audio_fmt(const struct GrooveAudioFormat *fmt) {
551     char buf[128];
552 
553     av_get_channel_layout_string(buf, sizeof(buf), 0, fmt->channel_layout);
554     av_log(NULL, AV_LOG_INFO, "encoder: using audio format: %s, %d Hz, %s\n",
555             av_get_sample_fmt_name((enum AVSampleFormat)fmt->sample_fmt),
556             fmt->sample_rate, buf);
557 }
558 
groove_encoder_attach(struct GrooveEncoder * encoder,struct GroovePlaylist * playlist)559 int groove_encoder_attach(struct GrooveEncoder *encoder, struct GroovePlaylist *playlist) {
560     struct GrooveEncoderPrivate *e = (struct GrooveEncoderPrivate *) encoder;
561 
562     encoder->playlist = playlist;
563     groove_queue_reset(e->audioq);
564 
565     e->oformat = av_guess_format(encoder->format_short_name,
566             encoder->filename, encoder->mime_type);
567     if (!e->oformat) {
568         groove_encoder_detach(encoder);
569         av_log(NULL, AV_LOG_ERROR, "unable to determine format\n");
570         return -1;
571     }
572 
573     // av_guess_codec ignores mime_type, filename, and codec_short_name. see
574     // https://bugzilla.libav.org/show_bug.cgi?id=580
575     // because of this we do a workaround to return the correct codec based on
576     // the codec_short_name.
577     AVCodec *codec = NULL;
578     if (encoder->codec_short_name) {
579         codec = avcodec_find_encoder_by_name(encoder->codec_short_name);
580         if (!codec) {
581             const AVCodecDescriptor *desc =
582                 avcodec_descriptor_get_by_name(encoder->codec_short_name);
583             if (desc) {
584                 codec = avcodec_find_encoder(desc->id);
585             }
586         }
587     }
588     if (!codec) {
589         enum AVCodecID codec_id = av_guess_codec(e->oformat,
590                 encoder->codec_short_name, encoder->filename, encoder->mime_type,
591                 AVMEDIA_TYPE_AUDIO);
592         codec = avcodec_find_encoder(codec_id);
593         if (!codec) {
594             groove_encoder_detach(encoder);
595             av_log(NULL, AV_LOG_ERROR, "unable to find encoder\n");
596             return -1;
597         }
598     }
599     e->codec = codec;
600     av_log(NULL, AV_LOG_INFO, "encoder: using codec: %s\n", codec->long_name);
601 
602     encoder->actual_audio_format.sample_fmt = closest_supported_sample_fmt(
603             codec, encoder->target_audio_format.sample_fmt);
604     encoder->actual_audio_format.sample_rate = closest_supported_sample_rate(
605             codec, encoder->target_audio_format.sample_rate);
606     encoder->actual_audio_format.channel_layout = closest_supported_channel_layout(
607             codec, encoder->target_audio_format.channel_layout);
608 
609     log_audio_fmt(&encoder->actual_audio_format);
610 
611     int err = init_avcontext(encoder);
612     if (err < 0) {
613         groove_encoder_detach(encoder);
614         return err;
615     }
616 
617     e->sink->audio_format = encoder->actual_audio_format;
618     e->sink->buffer_size = encoder->sink_buffer_size;
619     e->sink->buffer_sample_count = (codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE) ?
620         0 : e->stream->codec->frame_size;
621     e->sink->gain = encoder->gain;
622 
623     if (groove_sink_attach(e->sink, playlist) < 0) {
624         groove_encoder_detach(encoder);
625         av_log(NULL, AV_LOG_ERROR, "unable to attach sink\n");
626         return -1;
627     }
628 
629     if (pthread_create(&e->thread_id, NULL, encode_thread, encoder) != 0) {
630         groove_encoder_detach(encoder);
631         av_log(NULL, AV_LOG_ERROR, "unable to create encoder thread\n");
632         return -1;
633     }
634 
635     return 0;
636 }
637 
groove_encoder_detach(struct GrooveEncoder * encoder)638 int groove_encoder_detach(struct GrooveEncoder *encoder) {
639     struct GrooveEncoderPrivate *e = (struct GrooveEncoderPrivate *) encoder;
640 
641     e->abort_request = 1;
642     groove_sink_detach(e->sink);
643     groove_queue_flush(e->audioq);
644     groove_queue_abort(e->audioq);
645     pthread_cond_signal(&e->drain_cond);
646     pthread_join(e->thread_id, NULL);
647     e->abort_request = 0;
648 
649     cleanup_avcontext(e);
650     e->oformat = NULL;
651     e->codec = NULL;
652 
653     encoder->playlist = NULL;
654     return 0;
655 }
656 
groove_encoder_buffer_get(struct GrooveEncoder * encoder,struct GrooveBuffer ** buffer,int block)657 int groove_encoder_buffer_get(struct GrooveEncoder *encoder,
658         struct GrooveBuffer **buffer, int block)
659 {
660     struct GrooveEncoderPrivate *e = (struct GrooveEncoderPrivate *) encoder;
661 
662     if (groove_queue_get(e->audioq, (void**)buffer, block) == 1) {
663         if (*buffer == end_of_q_sentinel) {
664             *buffer = NULL;
665             return GROOVE_BUFFER_END;
666         } else {
667             return GROOVE_BUFFER_YES;
668         }
669     } else {
670         *buffer = NULL;
671         return GROOVE_BUFFER_NO;
672     }
673 }
674 
groove_encoder_metadata_get(struct GrooveEncoder * encoder,const char * key,const struct GrooveTag * prev,int flags)675 struct GrooveTag *groove_encoder_metadata_get(struct GrooveEncoder *encoder, const char *key,
676         const struct GrooveTag *prev, int flags)
677 {
678     struct GrooveEncoderPrivate *e = (struct GrooveEncoderPrivate *) encoder;
679     const AVDictionaryEntry *entry = (const AVDictionaryEntry *) prev;
680     return (struct GrooveTag *) av_dict_get(e->metadata, key, entry, flags|AV_DICT_IGNORE_SUFFIX);
681 }
682 
groove_encoder_metadata_set(struct GrooveEncoder * encoder,const char * key,const char * value,int flags)683 int groove_encoder_metadata_set(struct GrooveEncoder *encoder, const char *key,
684         const char *value, int flags)
685 {
686     struct GrooveEncoderPrivate *e = (struct GrooveEncoderPrivate *) encoder;
687     return av_dict_set(&e->metadata, key, value, flags|AV_DICT_IGNORE_SUFFIX);
688 }
689 
groove_encoder_buffer_peek(struct GrooveEncoder * encoder,int block)690 int groove_encoder_buffer_peek(struct GrooveEncoder *encoder, int block) {
691     struct GrooveEncoderPrivate *e = (struct GrooveEncoderPrivate *) encoder;
692     return groove_queue_peek(e->audioq, block);
693 }
694 
groove_encoder_position(struct GrooveEncoder * encoder,struct GroovePlaylistItem ** item,double * seconds)695 void groove_encoder_position(struct GrooveEncoder *encoder,
696         struct GroovePlaylistItem **item, double *seconds)
697 {
698     struct GrooveEncoderPrivate *e = (struct GrooveEncoderPrivate *) encoder;
699 
700     pthread_mutex_lock(&e->encode_head_mutex);
701 
702     if (item)
703         *item = e->encode_head;
704 
705     if (seconds)
706         *seconds = e->encode_pos;
707 
708     pthread_mutex_unlock(&e->encode_head_mutex);
709 }
710 
groove_encoder_set_gain(struct GrooveEncoder * encoder,double gain)711 int groove_encoder_set_gain(struct GrooveEncoder *encoder, double gain) {
712     struct GrooveEncoderPrivate *e = (struct GrooveEncoderPrivate *) encoder;
713     encoder->gain = gain;
714     return groove_sink_set_gain(e->sink, gain);
715 }
716