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 "file.h"
9 #include "queue.h"
10 #include "buffer.h"
11
12 #include <libavutil/opt.h>
13 #include <libavutil/channel_layout.h>
14 #include <libavformat/avformat.h>
15 #include <libavfilter/avfilter.h>
16 #include <libavfilter/buffersink.h>
17 #include <libavfilter/buffersrc.h>
18
19 #include <pthread.h>
20
21 struct GrooveSinkPrivate {
22 struct GrooveSink externals;
23 struct GrooveQueue *audioq;
24 int audioq_size; // in bytes
25 int min_audioq_size; // in bytes
26 };
27
28 struct SinkStack {
29 struct GrooveSink *sink;
30 struct SinkStack *next;
31 };
32
33 struct SinkMap {
34 struct SinkStack *stack_head;
35 AVFilterContext *abuffersink_ctx;
36 struct SinkMap *next;
37 };
38
39 struct GroovePlaylistPrivate {
40 struct GroovePlaylist externals;
41 pthread_t thread_id;
42 int abort_request;
43
44 AVPacket audio_pkt_temp;
45 AVFrame *in_frame;
46 int paused;
47
48 int in_sample_rate;
49 uint64_t in_channel_layout;
50 enum AVSampleFormat in_sample_fmt;
51 AVRational in_time_base;
52
53 char strbuf[512];
54 AVFilterGraph *filter_graph;
55 AVFilterContext *abuffer_ctx;
56
57 const AVFilter *volume_filter;
58 const AVFilter *compand_filter;
59 const AVFilter *abuffer_filter;
60 const AVFilter *asplit_filter;
61 const AVFilter *aformat_filter;
62 const AVFilter *abuffersink_filter;
63
64 pthread_mutex_t drain_cond_mutex;
65 int drain_cond_mutex_inited;
66
67 // this mutex applies to the variables in this block
68 pthread_mutex_t decode_head_mutex;
69 int decode_head_mutex_inited;
70 // decode_thread waits on this cond when the decode_head is NULL
71 pthread_cond_t decode_head_cond;
72 int decode_head_cond_inited;
73 // decode_thread waits on this cond when every sink is full
74 // should also signal when the first sink is attached.
75 pthread_cond_t sink_drain_cond;
76 int sink_drain_cond_inited;
77 // pointer to current playlist item being decoded
78 struct GroovePlaylistItem *decode_head;
79 // desired volume for the volume filter
80 double volume;
81 // known true peak value
82 double peak;
83 // set to 1 to trigger a rebuild
84 int rebuild_filter_graph_flag;
85 // map audio format to list of sinks
86 // for each map entry, use the first sink in the stack as the example
87 // of the audio format in that stack
88 struct SinkMap *sink_map;
89 int sink_map_count;
90
91 // the value that was used to construct the filter graph
92 double filter_volume;
93 double filter_peak;
94
95 // only touched by decode_thread, tells whether we have sent the end_of_q_sentinel
96 int sent_end_of_q;
97
98 struct GroovePlaylistItem *purge_item; // set temporarily
99
100 int (*detect_full_sinks)(struct GroovePlaylist*);
101 };
102
103 // this is used to tell the difference between a buffer underrun
104 // and the end of the playlist.
105 static struct GrooveBuffer *end_of_q_sentinel = NULL;
106
frame_size(const AVFrame * frame)107 static int frame_size(const AVFrame *frame) {
108 return av_get_channel_layout_nb_channels(frame->channel_layout) *
109 av_get_bytes_per_sample(frame->format) *
110 frame->nb_samples;
111 }
112
frame_to_groove_buffer(struct GroovePlaylist * playlist,struct GrooveSink * sink,AVFrame * frame)113 static struct GrooveBuffer * frame_to_groove_buffer(struct GroovePlaylist *playlist,
114 struct GrooveSink *sink, AVFrame *frame)
115 {
116 struct GrooveBufferPrivate *b = av_mallocz(sizeof(struct GrooveBufferPrivate));
117
118 if (!b) {
119 av_log(NULL, AV_LOG_ERROR, "unable to allocate buffer\n");
120 return NULL;
121 }
122
123 struct GrooveBuffer *buffer = &b->externals;
124
125 if (pthread_mutex_init(&b->mutex, NULL) != 0) {
126 av_free(b);
127 av_log(NULL, AV_LOG_ERROR, "unable to create mutex\n");
128 return NULL;
129 }
130
131 struct GroovePlaylistPrivate *p = (struct GroovePlaylistPrivate *) playlist;
132 struct GrooveFile *file = p->decode_head->file;
133
134 struct GrooveFilePrivate *f = (struct GrooveFilePrivate *) file;
135
136 buffer->item = p->decode_head;
137 buffer->pos = f->audio_clock;
138
139 buffer->data = frame->extended_data;
140 buffer->frame_count = frame->nb_samples;
141 buffer->format.channel_layout = frame->channel_layout;
142 buffer->format.sample_fmt = frame->format;
143 buffer->format.sample_rate = frame->sample_rate;
144 buffer->size = frame_size(frame);
145 buffer->pts = frame->pts;
146
147 b->frame = frame;
148
149 return buffer;
150 }
151
152
153 // decode one audio packet and return its uncompressed size
audio_decode_frame(struct GroovePlaylist * playlist,struct GrooveFile * file)154 static int audio_decode_frame(struct GroovePlaylist *playlist, struct GrooveFile *file) {
155 struct GroovePlaylistPrivate *p = (struct GroovePlaylistPrivate *) playlist;
156 struct GrooveFilePrivate *f = (struct GrooveFilePrivate *) file;
157
158 AVPacket *pkt = &f->audio_pkt;
159 AVCodecContext *dec = f->audio_st->codec;
160
161 AVPacket *pkt_temp = &p->audio_pkt_temp;
162 *pkt_temp = *pkt;
163
164 // update the audio clock with the pts if we can
165 if (pkt->pts != AV_NOPTS_VALUE)
166 f->audio_clock = av_q2d(f->audio_st->time_base) * pkt->pts;
167
168 int max_data_size = 0;
169 int len1, got_frame;
170 int new_packet = 1;
171 AVFrame *in_frame = p->in_frame;
172
173 // NOTE: the audio packet can contain several frames
174 while (pkt_temp->size > 0 || (!pkt_temp->data && new_packet)) {
175 new_packet = 0;
176
177 len1 = avcodec_decode_audio4(dec, in_frame, &got_frame, pkt_temp);
178 if (len1 < 0) {
179 // if error, we skip the frame
180 pkt_temp->size = 0;
181 return -1;
182 }
183
184 pkt_temp->data += len1;
185 pkt_temp->size -= len1;
186
187 if (!got_frame) {
188 // stop sending empty packets if the decoder is finished
189 if (!pkt_temp->data && dec->codec->capabilities & AV_CODEC_CAP_DELAY)
190 return 0;
191 continue;
192 }
193
194 // push the audio data from decoded frame into the filtergraph
195 int err = av_buffersrc_write_frame(p->abuffer_ctx, in_frame);
196 if (err < 0) {
197 av_strerror(err, p->strbuf, sizeof(p->strbuf));
198 av_log(NULL, AV_LOG_ERROR, "error writing frame to buffersrc: %s\n",
199 p->strbuf);
200 return -1;
201 }
202
203 // for each data format in the sink map, pull filtered audio from its
204 // buffersink, turn it into a GrooveBuffer and then increment the ref
205 // count for each sink in that stack.
206 struct SinkMap *map_item = p->sink_map;
207 double clock_adjustment = 0;
208 while (map_item) {
209 struct GrooveSink *example_sink = map_item->stack_head->sink;
210 int data_size = 0;
211 for (;;) {
212 AVFrame *oframe = av_frame_alloc();
213 int err = example_sink->buffer_sample_count == 0 ?
214 av_buffersink_get_frame(map_item->abuffersink_ctx, oframe) :
215 av_buffersink_get_samples(map_item->abuffersink_ctx, oframe, example_sink->buffer_sample_count);
216 if (err == AVERROR_EOF || err == AVERROR(EAGAIN)) {
217 av_frame_free(&oframe);
218 break;
219 }
220 if (err < 0) {
221 av_frame_free(&oframe);
222 av_log(NULL, AV_LOG_ERROR, "error reading buffer from buffersink\n");
223 return -1;
224 }
225 struct GrooveBuffer *buffer = frame_to_groove_buffer(playlist, example_sink, oframe);
226 if (!buffer) {
227 av_frame_free(&oframe);
228 return -1;
229 }
230 data_size += buffer->size;
231 struct SinkStack *stack_item = map_item->stack_head;
232 // we hold this reference to avoid cleanups until at least this loop
233 // is done and we call unref after it.
234 groove_buffer_ref(buffer);
235 while (stack_item) {
236 struct GrooveSink *sink = stack_item->sink;
237 struct GrooveSinkPrivate *s = (struct GrooveSinkPrivate *) sink;
238 // as soon as we call groove_queue_put, this buffer could be unref'd.
239 // so we ref before putting it in the queue, and unref if it failed.
240 groove_buffer_ref(buffer);
241 if (groove_queue_put(s->audioq, buffer) < 0) {
242 av_log(NULL, AV_LOG_ERROR, "unable to put buffer in queue\n");
243 groove_buffer_unref(buffer);
244 }
245 stack_item = stack_item->next;
246 }
247 groove_buffer_unref(buffer);
248 }
249 if (data_size > max_data_size) {
250 max_data_size = data_size;
251 clock_adjustment = data_size / (double)example_sink->bytes_per_sec;
252 }
253 map_item = map_item->next;
254 }
255
256 // if no pts, then estimate it
257 if (pkt->pts == AV_NOPTS_VALUE)
258 f->audio_clock += clock_adjustment;
259 return max_data_size;
260 }
261 return max_data_size;
262 }
263
264 static const double dB_scale = 0.1151292546497023; // log(10) * 0.05
265
gain_to_dB(double gain)266 static double gain_to_dB(double gain) {
267 return log(gain) / dB_scale;
268 }
269
create_volume_filter(struct GroovePlaylistPrivate * p,AVFilterContext ** audio_src_ctx,double vol,double amp_vol)270 static int create_volume_filter(struct GroovePlaylistPrivate *p, AVFilterContext **audio_src_ctx,
271 double vol, double amp_vol)
272 {
273 int err;
274
275 if (vol < 0.0) vol = 0.0;
276 if (amp_vol < 1.0) {
277 snprintf(p->strbuf, sizeof(p->strbuf), "volume=%f", vol);
278 av_log(NULL, AV_LOG_INFO, "volume: %s\n", p->strbuf);
279 AVFilterContext *volume_ctx;
280 err = avfilter_graph_create_filter(&volume_ctx, p->volume_filter, NULL,
281 p->strbuf, NULL, p->filter_graph);
282 if (err < 0) {
283 av_log(NULL, AV_LOG_ERROR, "error initializing volume filter\n");
284 return err;
285 }
286 err = avfilter_link(*audio_src_ctx, 0, volume_ctx, 0);
287 if (err < 0) {
288 av_strerror(err, p->strbuf, sizeof(p->strbuf));
289 av_log(NULL, AV_LOG_ERROR, "unable to link volume filter: %s\n", p->strbuf);
290 return err;
291 }
292 *audio_src_ctx = volume_ctx;
293 } else if (amp_vol > 1.0) {
294 double attack = 0.1;
295 double decay = 0.2;
296 const char *points = "-2/-2";
297 double soft_knee = 0.02;
298 double gain = gain_to_dB(vol);
299 double volume_param = 0.0;
300 double delay = 0.2;
301 snprintf(p->strbuf, sizeof(p->strbuf), "%f:%f:%s:%f:%f:%f:%f",
302 attack, decay, points, soft_knee, gain, volume_param, delay);
303 av_log(NULL, AV_LOG_INFO, "compand: %s\n", p->strbuf);
304 AVFilterContext *compand_ctx;
305 err = avfilter_graph_create_filter(&compand_ctx, p->compand_filter, NULL,
306 p->strbuf, NULL, p->filter_graph);
307 if (err < 0) {
308 av_log(NULL, AV_LOG_ERROR, "error initializing compand filter\n");
309 return err;
310 }
311 err = avfilter_link(*audio_src_ctx, 0, compand_ctx, 0);
312 if (err < 0) {
313 av_strerror(err, p->strbuf, sizeof(p->strbuf));
314 av_log(NULL, AV_LOG_ERROR, "unable to link compand filter: %s\n", p->strbuf);
315 return err;
316 }
317 *audio_src_ctx = compand_ctx;
318 }
319 return 0;
320 }
321
322 // abuffer -> volume -> asplit for each audio format
323 // -> volume -> aformat -> abuffersink
324 // if the volume gain is > 1.0, we use a compand filter instead
325 // for soft limiting.
init_filter_graph(struct GroovePlaylist * playlist,struct GrooveFile * file)326 static int init_filter_graph(struct GroovePlaylist *playlist, struct GrooveFile *file) {
327 struct GroovePlaylistPrivate *p = (struct GroovePlaylistPrivate *) playlist;
328 struct GrooveFilePrivate *f = (struct GrooveFilePrivate *) file;
329
330 // destruct old graph
331 avfilter_graph_free(&p->filter_graph);
332
333 // create new graph
334 p->filter_graph = avfilter_graph_alloc();
335 if (!p->filter_graph) {
336 av_log(NULL, AV_LOG_ERROR, "unable to create filter graph: out of memory\n");
337 return -1;
338 }
339
340 int err;
341 // create abuffer filter
342 AVCodecContext *avctx = f->audio_st->codec;
343 AVRational time_base = f->audio_st->time_base;
344 snprintf(p->strbuf, sizeof(p->strbuf),
345 "time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=0x%"PRIx64,
346 time_base.num, time_base.den, avctx->sample_rate,
347 av_get_sample_fmt_name(avctx->sample_fmt),
348 avctx->channel_layout);
349 av_log(NULL, AV_LOG_INFO, "abuffer: %s\n", p->strbuf);
350 // save these values so we can compare later and check
351 // whether we have to reconstruct the graph
352 p->in_sample_rate = avctx->sample_rate;
353 p->in_channel_layout = avctx->channel_layout;
354 p->in_sample_fmt = avctx->sample_fmt;
355 p->in_time_base = time_base;
356 err = avfilter_graph_create_filter(&p->abuffer_ctx, p->abuffer_filter,
357 NULL, p->strbuf, NULL, p->filter_graph);
358 if (err < 0) {
359 av_log(NULL, AV_LOG_ERROR, "error initializing abuffer filter\n");
360 return err;
361 }
362 // as we create filters, this points the next source to link to
363 AVFilterContext *audio_src_ctx = p->abuffer_ctx;
364
365 // save the volume value so we can compare later and check
366 // whether we have to reconstruct the graph
367 p->filter_volume = p->volume;
368 p->filter_peak = p->peak;
369 // if volume is < 1.0, create volume filter
370 // == 1.0, do not create a filter
371 // > 1.0, create a compand filter (for soft limiting)
372 double vol = p->volume;
373 // adjust for the known true peak of the playlist item. In other words, if
374 // we know that the song peaks at 0.8, and we want to amplify by 1.2, that
375 // comes out to 0.96 so we know that we can safely amplify by 1.2 even
376 // though it's greater than 1.0.
377 double amp_vol = vol * (p->peak > 1.0 ? 1.0 : p->peak);
378 err = create_volume_filter(p, &audio_src_ctx, vol, amp_vol);
379 if (err < 0)
380 return err;
381
382 // if only one sink, no need for asplit
383 if (p->sink_map_count >= 2) {
384 AVFilterContext *asplit_ctx;
385 snprintf(p->strbuf, sizeof(p->strbuf), "%d", p->sink_map_count);
386 av_log(NULL, AV_LOG_INFO, "asplit: %s\n", p->strbuf);
387 err = avfilter_graph_create_filter(&asplit_ctx, p->asplit_filter,
388 NULL, p->strbuf, NULL, p->filter_graph);
389 if (err < 0) {
390 av_log(NULL, AV_LOG_ERROR, "unable to create asplit filter\n");
391 return err;
392 }
393 err = avfilter_link(audio_src_ctx, 0, asplit_ctx, 0);
394 if (err < 0) {
395 av_log(NULL, AV_LOG_ERROR, "unable to link to asplit\n");
396 return err;
397 }
398 audio_src_ctx = asplit_ctx;
399 }
400
401 // for each audio format, create aformat and abuffersink filters
402 struct SinkMap *map_item = p->sink_map;
403 int pad_index = 0;
404 while (map_item) {
405 struct GrooveSink *example_sink = map_item->stack_head->sink;
406 struct GrooveAudioFormat *audio_format = &example_sink->audio_format;
407
408 AVFilterContext *inner_audio_src_ctx = audio_src_ctx;
409
410 // create volume filter
411 err = create_volume_filter(p, &inner_audio_src_ctx, example_sink->gain, example_sink->gain);
412 if (err < 0)
413 return err;
414
415 if (!example_sink->disable_resample) {
416 AVFilterContext *aformat_ctx;
417 // create aformat filter
418 snprintf(p->strbuf, sizeof(p->strbuf),
419 "sample_fmts=%s:sample_rates=%d:channel_layouts=0x%"PRIx64,
420 av_get_sample_fmt_name((enum AVSampleFormat)audio_format->sample_fmt),
421 audio_format->sample_rate, audio_format->channel_layout);
422 av_log(NULL, AV_LOG_INFO, "aformat: %s\n", p->strbuf);
423 err = avfilter_graph_create_filter(&aformat_ctx, p->aformat_filter,
424 NULL, p->strbuf, NULL, p->filter_graph);
425 if (err < 0) {
426 av_strerror(err, p->strbuf, sizeof(p->strbuf));
427 av_log(NULL, AV_LOG_ERROR, "unable to create aformat filter: %s\n",
428 p->strbuf);
429 return err;
430 }
431 err = avfilter_link(inner_audio_src_ctx, pad_index, aformat_ctx, 0);
432 if (err < 0) {
433 av_strerror(err, p->strbuf, sizeof(p->strbuf));
434 av_log(NULL, AV_LOG_ERROR, "unable to link aformat filter: %s\n", p->strbuf);
435 return err;
436 }
437 inner_audio_src_ctx = aformat_ctx;
438 }
439
440 // create abuffersink filter
441 err = avfilter_graph_create_filter(&map_item->abuffersink_ctx, p->abuffersink_filter,
442 NULL, NULL, NULL, p->filter_graph);
443 if (err < 0) {
444 av_log(NULL, AV_LOG_ERROR, "unable to create abuffersink filter\n");
445 return err;
446 }
447 err = avfilter_link(inner_audio_src_ctx, 0, map_item->abuffersink_ctx, 0);
448 if (err < 0) {
449 av_strerror(err, p->strbuf, sizeof(p->strbuf));
450 av_log(NULL, AV_LOG_ERROR, "unable to link abuffersink filter: %s\n", p->strbuf);
451 return err;
452 }
453
454 pad_index += 1;
455 map_item = map_item->next;
456 }
457
458 err = avfilter_graph_config(p->filter_graph, NULL);
459 if (err < 0) {
460 av_strerror(err, p->strbuf, sizeof(p->strbuf));
461 av_log(NULL, AV_LOG_ERROR, "error configuring the filter graph: %s\n",
462 p->strbuf);
463 return err;
464 }
465
466 p->rebuild_filter_graph_flag = 0;
467
468 return 0;
469 }
470
maybe_init_filter_graph(struct GroovePlaylist * playlist,struct GrooveFile * file)471 static int maybe_init_filter_graph(struct GroovePlaylist *playlist, struct GrooveFile *file) {
472 struct GroovePlaylistPrivate *p = (struct GroovePlaylistPrivate *) playlist;
473 struct GrooveFilePrivate *f = (struct GrooveFilePrivate *) file;
474 AVCodecContext *avctx = f->audio_st->codec;
475 AVRational time_base = f->audio_st->time_base;
476
477 // if the input format stuff has changed, then we need to re-build the graph
478 if (!p->filter_graph || p->rebuild_filter_graph_flag ||
479 p->in_sample_rate != avctx->sample_rate ||
480 p->in_channel_layout != avctx->channel_layout ||
481 p->in_sample_fmt != avctx->sample_fmt ||
482 p->in_time_base.num != time_base.num ||
483 p->in_time_base.den != time_base.den ||
484 p->volume != p->filter_volume ||
485 p->peak != p->filter_peak)
486 {
487 return init_filter_graph(playlist, file);
488 }
489
490 return 0;
491 }
492
every_sink(struct GroovePlaylist * playlist,int (* func)(struct GrooveSink *),int default_value)493 static int every_sink(struct GroovePlaylist *playlist, int (*func)(struct GrooveSink *), int default_value) {
494 struct GroovePlaylistPrivate *p = (struct GroovePlaylistPrivate *) playlist;
495 struct SinkMap *map_item = p->sink_map;
496 while (map_item) {
497 struct SinkStack *stack_item = map_item->stack_head;
498 while (stack_item) {
499 struct GrooveSink *sink = stack_item->sink;
500 int value = func(sink);
501 if (value != default_value)
502 return value;
503 stack_item = stack_item->next;
504 }
505 map_item = map_item->next;
506 }
507 return default_value;
508 }
509
sink_is_full(struct GrooveSink * sink)510 static int sink_is_full(struct GrooveSink *sink) {
511 struct GrooveSinkPrivate *s = (struct GrooveSinkPrivate *) sink;
512 return s->audioq_size >= s->min_audioq_size;
513 }
514
every_sink_full(struct GroovePlaylist * playlist)515 static int every_sink_full(struct GroovePlaylist *playlist) {
516 return every_sink(playlist, sink_is_full, 1);
517 }
518
any_sink_full(struct GroovePlaylist * playlist)519 static int any_sink_full(struct GroovePlaylist *playlist) {
520 return every_sink(playlist, sink_is_full, 0);
521 }
522
sink_signal_end(struct GrooveSink * sink)523 static int sink_signal_end(struct GrooveSink *sink) {
524 struct GrooveSinkPrivate *s = (struct GrooveSinkPrivate *) sink;
525 groove_queue_put(s->audioq, end_of_q_sentinel);
526 return 0;
527 }
528
every_sink_signal_end(struct GroovePlaylist * playlist)529 static void every_sink_signal_end(struct GroovePlaylist *playlist) {
530 every_sink(playlist, sink_signal_end, 0);
531 }
532
sink_flush(struct GrooveSink * sink)533 static int sink_flush(struct GrooveSink *sink) {
534 struct GrooveSinkPrivate *s = (struct GrooveSinkPrivate *) sink;
535
536 groove_queue_flush(s->audioq);
537 if (sink->flush)
538 sink->flush(sink);
539
540 return 0;
541 }
542
every_sink_flush(struct GroovePlaylist * playlist)543 static void every_sink_flush(struct GroovePlaylist *playlist) {
544 every_sink(playlist, sink_flush, 0);
545 }
546
decode_one_frame(struct GroovePlaylist * playlist,struct GrooveFile * file)547 static int decode_one_frame(struct GroovePlaylist *playlist, struct GrooveFile *file) {
548 struct GrooveFilePrivate *f = (struct GrooveFilePrivate *) file;
549 AVPacket *pkt = &f->audio_pkt;
550
551 // abort_request is set if we are destroying the file
552 if (f->abort_request)
553 return -1;
554
555 // might need to rebuild the filter graph if certain things changed
556 if (maybe_init_filter_graph(playlist, file) < 0)
557 return -1;
558
559 // handle seek requests
560 pthread_mutex_lock(&f->seek_mutex);
561 if (f->seek_pos >= 0) {
562 if (av_seek_frame(f->ic, f->audio_stream_index, f->seek_pos, 0) < 0) {
563 av_log(NULL, AV_LOG_ERROR, "%s: error while seeking\n", f->ic->filename);
564 } else if (f->seek_flush) {
565 every_sink_flush(playlist);
566 }
567 avcodec_flush_buffers(f->audio_st->codec);
568 f->seek_pos = -1;
569 f->eof = 0;
570 }
571 pthread_mutex_unlock(&f->seek_mutex);
572
573 if (f->eof) {
574 if (f->audio_st->codec->codec->capabilities & AV_CODEC_CAP_DELAY) {
575 av_init_packet(pkt);
576 pkt->data = NULL;
577 pkt->size = 0;
578 pkt->stream_index = f->audio_stream_index;
579 if (audio_decode_frame(playlist, file) > 0) {
580 // keep flushing
581 return 0;
582 }
583 }
584 // this file is complete. move on
585 return -1;
586 }
587 int err = av_read_frame(f->ic, pkt);
588 if (err < 0) {
589 // treat all errors as EOF, but log non-EOF errors.
590 if (err != AVERROR_EOF) {
591 av_log(NULL, AV_LOG_WARNING, "error reading frames\n");
592 }
593 f->eof = 1;
594 return 0;
595 }
596 if (pkt->stream_index != f->audio_stream_index) {
597 // we're only interested in the One True Audio Stream
598 av_free_packet(pkt);
599 return 0;
600 }
601 audio_decode_frame(playlist, file);
602 av_free_packet(pkt);
603 return 0;
604 }
605
audioq_put(struct GrooveQueue * queue,void * obj)606 static void audioq_put(struct GrooveQueue *queue, void *obj) {
607 struct GrooveBuffer *buffer = obj;
608 if (buffer == end_of_q_sentinel)
609 return;
610 struct GrooveSinkPrivate *s = queue->context;
611 s->audioq_size += buffer->size;
612 }
613
audioq_get(struct GrooveQueue * queue,void * obj)614 static void audioq_get(struct GrooveQueue *queue, void *obj) {
615 struct GrooveBuffer *buffer = obj;
616 if (buffer == end_of_q_sentinel)
617 return;
618 struct GrooveSink *sink = queue->context;
619 struct GrooveSinkPrivate *s = (struct GrooveSinkPrivate *) sink;
620 s->audioq_size -= buffer->size;
621
622 struct GroovePlaylist *playlist = sink->playlist;
623 struct GroovePlaylistPrivate *p = (struct GroovePlaylistPrivate *) playlist;
624 if (s->audioq_size < s->min_audioq_size) {
625 pthread_mutex_lock(&p->drain_cond_mutex);
626 pthread_cond_signal(&p->sink_drain_cond);
627 pthread_mutex_unlock(&p->drain_cond_mutex);
628 }
629 }
630
audioq_cleanup(struct GrooveQueue * queue,void * obj)631 static void audioq_cleanup(struct GrooveQueue *queue, void *obj) {
632 struct GrooveBuffer *buffer = obj;
633 if (buffer == end_of_q_sentinel)
634 return;
635 struct GrooveSink *sink = queue->context;
636 struct GrooveSinkPrivate *s = (struct GrooveSinkPrivate *) sink;
637 s->audioq_size -= buffer->size;
638 groove_buffer_unref(buffer);
639 }
640
audioq_purge(struct GrooveQueue * queue,void * obj)641 static int audioq_purge(struct GrooveQueue *queue, void *obj) {
642 struct GrooveBuffer *buffer = obj;
643 if (buffer == end_of_q_sentinel)
644 return 0;
645 struct GrooveSink *sink = queue->context;
646 struct GroovePlaylist *playlist = sink->playlist;
647 struct GroovePlaylistPrivate *p = (struct GroovePlaylistPrivate *) playlist;
648 struct GroovePlaylistItem *item = p->purge_item;
649 return buffer->item == item;
650 }
651
update_playlist_volume(struct GroovePlaylist * playlist)652 static void update_playlist_volume(struct GroovePlaylist *playlist) {
653 struct GroovePlaylistPrivate *p = (struct GroovePlaylistPrivate *) playlist;
654 struct GroovePlaylistItem *item = p->decode_head;
655 p->volume = playlist->gain * item->gain;
656 p->peak = item->peak;
657 }
658
659 // this thread is responsible for decoding and inserting buffers of decoded
660 // audio into each sink
decode_thread(void * arg)661 static void *decode_thread(void *arg) {
662 struct GroovePlaylistPrivate *p = arg;
663 struct GroovePlaylist *playlist = &p->externals;
664
665 while (!p->abort_request) {
666 pthread_mutex_lock(&p->decode_head_mutex);
667
668 // if we don't have anything to decode, wait until we do
669 if (!p->decode_head) {
670 if (!p->sent_end_of_q) {
671 every_sink_signal_end(playlist);
672 p->sent_end_of_q = 1;
673 }
674 pthread_cond_wait(&p->decode_head_cond, &p->decode_head_mutex);
675 pthread_mutex_unlock(&p->decode_head_mutex);
676 continue;
677 }
678 p->sent_end_of_q = 0;
679
680 // if all sinks are filled up, no need to read more
681 struct GrooveFile *file = p->decode_head->file;
682 struct GrooveFilePrivate *f = (struct GrooveFilePrivate *) file;
683
684 pthread_mutex_lock(&p->drain_cond_mutex);
685 if (p->detect_full_sinks(playlist) && (f->seek_pos < 0 || !f->seek_flush)) {
686 if (!f->paused) {
687 av_read_pause(f->ic);
688 f->paused = 1;
689 }
690 pthread_mutex_unlock(&p->decode_head_mutex);
691 pthread_cond_wait(&p->sink_drain_cond, &p->drain_cond_mutex);
692 pthread_mutex_unlock(&p->drain_cond_mutex);
693 continue;
694 }
695 pthread_mutex_unlock(&p->drain_cond_mutex);
696 if (f->paused) {
697 av_read_play(f->ic);
698 f->paused = 0;
699 }
700
701 update_playlist_volume(playlist);
702
703 if (decode_one_frame(playlist, file) < 0) {
704 p->decode_head = p->decode_head->next;
705 // seek to beginning of next song
706 if (p->decode_head) {
707 struct GrooveFile *next_file = p->decode_head->file;
708 struct GrooveFilePrivate *next_f = (struct GrooveFilePrivate *) next_file;
709 pthread_mutex_lock(&next_f->seek_mutex);
710 next_f->seek_pos = 0;
711 next_f->seek_flush = 0;
712 pthread_mutex_unlock(&next_f->seek_mutex);
713 }
714 }
715
716 pthread_mutex_unlock(&p->decode_head_mutex);
717 }
718
719 return NULL;
720 }
721
sink_formats_compatible(const struct GrooveSink * example_sink,const struct GrooveSink * test_sink)722 static int sink_formats_compatible(const struct GrooveSink *example_sink,
723 const struct GrooveSink *test_sink)
724 {
725 // buffer_sample_count 0 means we don't care
726 if (test_sink->buffer_sample_count != 0 &&
727 example_sink->buffer_sample_count != test_sink->buffer_sample_count)
728 {
729 return 0;
730 }
731 if (example_sink->gain != test_sink->gain)
732 return 0;
733 if (!test_sink->disable_resample &&
734 (example_sink->audio_format.sample_rate != test_sink->audio_format.sample_rate ||
735 example_sink->audio_format.channel_layout != test_sink->audio_format.channel_layout ||
736 example_sink->audio_format.sample_fmt != test_sink->audio_format.sample_fmt))
737 {
738 return 0;
739 }
740 return 1;
741 }
742
remove_sink_from_map(struct GrooveSink * sink)743 static int remove_sink_from_map(struct GrooveSink *sink) {
744 struct GroovePlaylist *playlist = sink->playlist;
745 struct GroovePlaylistPrivate *p = (struct GroovePlaylistPrivate *) playlist;
746
747 struct SinkMap *map_item = p->sink_map;
748 struct SinkMap *prev_map_item = NULL;
749 while (map_item) {
750 struct SinkMap *next_map_item = map_item->next;
751 struct SinkStack *stack_item = map_item->stack_head;
752 struct SinkStack *prev_stack_item = NULL;
753 while (stack_item) {
754 struct SinkStack *next_stack_item = stack_item->next;
755 struct GrooveSink *item_sink = stack_item->sink;
756 if (item_sink == sink) {
757 av_free(stack_item);
758 if (prev_stack_item) {
759 prev_stack_item->next = next_stack_item;
760 } else if (next_stack_item) {
761 map_item->stack_head = next_stack_item;
762 } else {
763 // the stack is empty; delete the map item
764 av_free(map_item);
765 p->sink_map_count -= 1;
766 if (prev_map_item) {
767 prev_map_item->next = next_map_item;
768 } else {
769 p->sink_map = next_map_item;
770 }
771 }
772 return 0;
773 }
774
775 prev_stack_item = stack_item;
776 stack_item = next_stack_item;
777 }
778 prev_map_item = map_item;
779 map_item = next_map_item;
780 }
781
782 return -1;
783 }
784
add_sink_to_map(struct GroovePlaylist * playlist,struct GrooveSink * sink)785 static int add_sink_to_map(struct GroovePlaylist *playlist, struct GrooveSink *sink) {
786 struct GroovePlaylistPrivate *p = (struct GroovePlaylistPrivate *) playlist;
787
788 struct SinkStack *stack_entry = av_mallocz(sizeof(struct SinkStack));
789
790 if (!stack_entry)
791 return -1;
792
793 stack_entry->sink = sink;
794
795 struct SinkMap *map_item = p->sink_map;
796 while (map_item) {
797 // if our sink matches the example sink from this map entry,
798 // push our sink onto the stack and we're done
799 struct GrooveSink *example_sink = map_item->stack_head->sink;
800 if (sink_formats_compatible(example_sink, sink)) {
801 stack_entry->next = map_item->stack_head->next;
802 map_item->stack_head->next = stack_entry;
803 return 0;
804 }
805 // maybe we need to swap the example sink with the new sink to make
806 // it work. In this case we need to rebuild the filter graph.
807 if (sink_formats_compatible(sink, example_sink)) {
808 stack_entry->next = map_item->stack_head;
809 map_item->stack_head = stack_entry;
810 p->rebuild_filter_graph_flag = 1;
811 return 0;
812 }
813 map_item = map_item->next;
814 }
815 // we did not find somewhere to put it, so push it onto the stack.
816 struct SinkMap *map_entry = av_mallocz(sizeof(struct SinkMap));
817 map_entry->stack_head = stack_entry;
818 if (!map_entry) {
819 av_free(stack_entry);
820 return -1;
821 }
822 if (p->sink_map) {
823 map_entry->next = p->sink_map;
824 p->sink_map = map_entry;
825 } else {
826 p->sink_map = map_entry;
827 }
828 p->rebuild_filter_graph_flag = 1;
829 p->sink_map_count += 1;
830 return 0;
831 }
832
groove_sink_play(struct GrooveSink * sink)833 static int groove_sink_play(struct GrooveSink *sink) {
834 if (sink->play)
835 sink->play(sink);
836
837 return 0;
838 }
839
groove_sink_pause(struct GrooveSink * sink)840 static int groove_sink_pause(struct GrooveSink *sink) {
841 if (sink->pause)
842 sink->pause(sink);
843
844 return 0;
845 }
846
groove_sink_detach(struct GrooveSink * sink)847 int groove_sink_detach(struct GrooveSink *sink) {
848 struct GroovePlaylist *playlist = sink->playlist;
849
850 if (!playlist)
851 return -1;
852
853 struct GrooveSinkPrivate *s = (struct GrooveSinkPrivate *) sink;
854
855 if (s->audioq) {
856 groove_queue_abort(s->audioq);
857 groove_queue_flush(s->audioq);
858 }
859
860 struct GroovePlaylistPrivate *p = (struct GroovePlaylistPrivate *) playlist;
861
862 pthread_mutex_lock(&p->decode_head_mutex);
863 int err = remove_sink_from_map(sink);
864 pthread_mutex_unlock(&p->decode_head_mutex);
865
866 sink->playlist = NULL;
867
868 return err;
869 }
870
groove_sink_attach(struct GrooveSink * sink,struct GroovePlaylist * playlist)871 int groove_sink_attach(struct GrooveSink *sink, struct GroovePlaylist *playlist) {
872 struct GrooveSinkPrivate *s = (struct GrooveSinkPrivate *) sink;
873
874 // cache computed audio format stuff
875 int channel_count = av_get_channel_layout_nb_channels(sink->audio_format.channel_layout);
876 int bytes_per_frame = channel_count *
877 av_get_bytes_per_sample((enum AVSampleFormat)sink->audio_format.sample_fmt);
878 sink->bytes_per_sec = bytes_per_frame * sink->audio_format.sample_rate;
879
880 s->min_audioq_size = sink->buffer_size * bytes_per_frame;
881 av_log(NULL, AV_LOG_INFO, "audio queue size: %d\n", s->min_audioq_size);
882
883 // add the sink to the entry that matches its audio format
884 struct GroovePlaylistPrivate *p = (struct GroovePlaylistPrivate *) playlist;
885
886 // must do this above add_sink_to_map to avid race condition
887 sink->playlist = playlist;
888
889 pthread_mutex_lock(&p->decode_head_mutex);
890 int err = add_sink_to_map(playlist, sink);
891 pthread_mutex_lock(&p->drain_cond_mutex);
892 pthread_cond_signal(&p->sink_drain_cond);
893 pthread_mutex_unlock(&p->drain_cond_mutex);
894 pthread_mutex_unlock(&p->decode_head_mutex);
895
896 if (err < 0) {
897 sink->playlist = NULL;
898 av_log(NULL, AV_LOG_ERROR, "unable to attach device: out of memory\n");
899 return err;
900 }
901
902 // in case we've called abort on the queue, reset
903 groove_queue_reset(s->audioq);
904
905 return 0;
906 }
907
groove_sink_buffer_get(struct GrooveSink * sink,struct GrooveBuffer ** buffer,int block)908 int groove_sink_buffer_get(struct GrooveSink *sink, struct GrooveBuffer **buffer, int block) {
909 struct GrooveSinkPrivate *s = (struct GrooveSinkPrivate *) sink;
910
911 if (groove_queue_get(s->audioq, (void**)buffer, block) == 1) {
912 if (*buffer == end_of_q_sentinel) {
913 *buffer = NULL;
914 return GROOVE_BUFFER_END;
915 } else {
916 return GROOVE_BUFFER_YES;
917 }
918 } else {
919 *buffer = NULL;
920 return GROOVE_BUFFER_NO;
921 }
922 }
923
groove_sink_buffer_peek(struct GrooveSink * sink,int block)924 int groove_sink_buffer_peek(struct GrooveSink *sink, int block) {
925 struct GrooveSinkPrivate *s = (struct GrooveSinkPrivate *) sink;
926 return groove_queue_peek(s->audioq, block);
927 }
928
groove_playlist_create(void)929 struct GroovePlaylist * groove_playlist_create(void) {
930 struct GroovePlaylistPrivate *p = av_mallocz(sizeof(struct GroovePlaylistPrivate));
931 if (!p) {
932 av_log(NULL, AV_LOG_ERROR, "unable to allocate playlist\n");
933 return NULL;
934 }
935 struct GroovePlaylist *playlist = &p->externals;
936
937 // the one that the playlist can read
938 playlist->gain = 1.0;
939 // the other volume multiplied by the playlist item's gain
940 p->volume = 1.0;
941
942 // set this flag to true so that a race condition does not send the end of
943 // queue sentinel early.
944 p->sent_end_of_q = 1;
945
946 p->detect_full_sinks = every_sink_full;
947
948 if (pthread_mutex_init(&p->decode_head_mutex, NULL) != 0) {
949 groove_playlist_destroy(playlist);
950 av_log(NULL, AV_LOG_ERROR, "unable to allocate decode head mutex\n");
951 return NULL;
952 }
953 p->decode_head_mutex_inited = 1;
954
955 if (pthread_mutex_init(&p->drain_cond_mutex, NULL) != 0) {
956 groove_playlist_destroy(playlist);
957 av_log(NULL, AV_LOG_ERROR, "unable to allocate drain cond mutex\n");
958 return NULL;
959 }
960 p->drain_cond_mutex_inited = 1;
961
962 if (pthread_cond_init(&p->decode_head_cond, NULL) != 0) {
963 groove_playlist_destroy(playlist);
964 av_log(NULL, AV_LOG_ERROR, "unable to allocate decode head mutex condition\n");
965 return NULL;
966 }
967 p->decode_head_cond_inited = 1;
968
969 if (pthread_cond_init(&p->sink_drain_cond, NULL) != 0) {
970 groove_playlist_destroy(playlist);
971 av_log(NULL, AV_LOG_ERROR, "unable to allocate sink drain mutex condition\n");
972 return NULL;
973 }
974 p->sink_drain_cond_inited = 1;
975
976 p->in_frame = av_frame_alloc();
977
978 if (!p->in_frame) {
979 groove_playlist_destroy(playlist);
980 av_log(NULL, AV_LOG_ERROR, "unable to allocate frame\n");
981 return NULL;
982 }
983
984 if (pthread_create(&p->thread_id, NULL, decode_thread, playlist) != 0) {
985 groove_playlist_destroy(playlist);
986 av_log(NULL, AV_LOG_ERROR, "unable to create playlist thread\n");
987 return NULL;
988 }
989
990 p->volume_filter = avfilter_get_by_name("volume");
991 if (!p->volume_filter) {
992 groove_playlist_destroy(playlist);
993 av_log(NULL, AV_LOG_ERROR, "unable to get volume filter\n");
994 return NULL;
995 }
996
997 p->compand_filter = avfilter_get_by_name("compand");
998 if (!p->compand_filter) {
999 groove_playlist_destroy(playlist);
1000 av_log(NULL, AV_LOG_ERROR, "unable to get compand filter\n");
1001 return NULL;
1002 }
1003
1004 p->abuffer_filter = avfilter_get_by_name("abuffer");
1005 if (!p->abuffer_filter) {
1006 groove_playlist_destroy(playlist);
1007 av_log(NULL, AV_LOG_ERROR, "unable to get abuffer filter\n");
1008 return NULL;
1009 }
1010
1011 p->asplit_filter = avfilter_get_by_name("asplit");
1012 if (!p->asplit_filter) {
1013 groove_playlist_destroy(playlist);
1014 av_log(NULL, AV_LOG_ERROR, "unable to get asplit filter\n");
1015 return NULL;
1016 }
1017
1018 p->aformat_filter = avfilter_get_by_name("aformat");
1019 if (!p->aformat_filter) {
1020 groove_playlist_destroy(playlist);
1021 av_log(NULL, AV_LOG_ERROR, "unable to get aformat filter\n");
1022 return NULL;
1023 }
1024
1025 p->abuffersink_filter = avfilter_get_by_name("abuffersink");
1026 if (!p->abuffersink_filter) {
1027 groove_playlist_destroy(playlist);
1028 av_log(NULL, AV_LOG_ERROR, "unable to get abuffersink filter\n");
1029 return NULL;
1030 }
1031
1032 return playlist;
1033 }
1034
groove_playlist_destroy(struct GroovePlaylist * playlist)1035 void groove_playlist_destroy(struct GroovePlaylist *playlist) {
1036 groove_playlist_clear(playlist);
1037
1038 struct GroovePlaylistPrivate *p = (struct GroovePlaylistPrivate *) playlist;
1039
1040 // wait for decode thread to finish
1041 p->abort_request = 1;
1042 pthread_cond_signal(&p->decode_head_cond);
1043 pthread_cond_signal(&p->sink_drain_cond);
1044 pthread_join(p->thread_id, NULL);
1045
1046 every_sink(playlist, groove_sink_detach, 0);
1047
1048 avfilter_graph_free(&p->filter_graph);
1049 av_frame_free(&p->in_frame);
1050
1051 if (p->decode_head_mutex_inited)
1052 pthread_mutex_destroy(&p->decode_head_mutex);
1053
1054 if (p->drain_cond_mutex_inited)
1055 pthread_mutex_destroy(&p->drain_cond_mutex);
1056
1057 if (p->decode_head_cond_inited)
1058 pthread_cond_destroy(&p->decode_head_cond);
1059
1060 if (p->sink_drain_cond_inited)
1061 pthread_cond_destroy(&p->sink_drain_cond);
1062
1063 av_free(p);
1064 }
1065
groove_playlist_play(struct GroovePlaylist * playlist)1066 void groove_playlist_play(struct GroovePlaylist *playlist) {
1067 struct GroovePlaylistPrivate *p = (struct GroovePlaylistPrivate *) playlist;
1068 // no mutex needed for this boolean flag
1069 if (p->paused == 0)
1070 return;
1071 p->paused = 0;
1072 every_sink(playlist, groove_sink_play, 0);
1073 }
1074
groove_playlist_pause(struct GroovePlaylist * playlist)1075 void groove_playlist_pause(struct GroovePlaylist *playlist) {
1076 struct GroovePlaylistPrivate *p = (struct GroovePlaylistPrivate *) playlist;
1077 // no mutex needed for this boolean flag
1078 if (p->paused == 1)
1079 return;
1080 p->paused = 1;
1081 every_sink(playlist, groove_sink_pause, 0);
1082 }
1083
groove_playlist_seek(struct GroovePlaylist * playlist,struct GroovePlaylistItem * item,double seconds)1084 void groove_playlist_seek(struct GroovePlaylist *playlist, struct GroovePlaylistItem *item, double seconds) {
1085 struct GrooveFile * file = item->file;
1086 struct GrooveFilePrivate *f = (struct GrooveFilePrivate *) file;
1087
1088 int64_t ts = seconds * f->audio_st->time_base.den / f->audio_st->time_base.num;
1089 if (f->ic->start_time != AV_NOPTS_VALUE)
1090 ts += f->ic->start_time;
1091
1092 struct GroovePlaylistPrivate *p = (struct GroovePlaylistPrivate *) playlist;
1093
1094 pthread_mutex_lock(&p->decode_head_mutex);
1095 pthread_mutex_lock(&f->seek_mutex);
1096
1097 f->seek_pos = ts;
1098 f->seek_flush = 1;
1099
1100 pthread_mutex_unlock(&f->seek_mutex);
1101
1102 p->decode_head = item;
1103 pthread_cond_signal(&p->decode_head_cond);
1104 pthread_mutex_unlock(&p->decode_head_mutex);
1105 }
1106
groove_playlist_insert(struct GroovePlaylist * playlist,struct GrooveFile * file,double gain,double peak,struct GroovePlaylistItem * next)1107 struct GroovePlaylistItem *groove_playlist_insert(struct GroovePlaylist *playlist,
1108 struct GrooveFile *file, double gain, double peak, struct GroovePlaylistItem *next)
1109 {
1110 struct GroovePlaylistItem * item = av_mallocz(sizeof(struct GroovePlaylistItem));
1111 if (!item)
1112 return NULL;
1113
1114 item->file = file;
1115 item->next = next;
1116 item->gain = gain;
1117 item->peak = peak;
1118
1119 struct GroovePlaylistPrivate *p = (struct GroovePlaylistPrivate *) playlist;
1120 struct GrooveFilePrivate *f = (struct GrooveFilePrivate *) file;
1121
1122 // lock decode_head_mutex so that decode_head cannot point to a new item
1123 // while we're screwing around with the queue
1124 pthread_mutex_lock(&p->decode_head_mutex);
1125
1126 if (next) {
1127 if (next->prev) {
1128 item->prev = next->prev;
1129 item->prev->next = item;
1130 next->prev = item;
1131 } else {
1132 playlist->head = item;
1133 }
1134 } else if (!playlist->head) {
1135 playlist->head = item;
1136 playlist->tail = item;
1137
1138 pthread_mutex_lock(&f->seek_mutex);
1139 f->seek_pos = 0;
1140 f->seek_flush = 0;
1141 pthread_mutex_unlock(&f->seek_mutex);
1142
1143 p->decode_head = playlist->head;
1144 pthread_cond_signal(&p->decode_head_cond);
1145 } else {
1146 item->prev = playlist->tail;
1147 playlist->tail->next = item;
1148 playlist->tail = item;
1149 }
1150
1151 pthread_mutex_unlock(&p->decode_head_mutex);
1152 return item;
1153 }
1154
purge_sink(struct GrooveSink * sink)1155 static int purge_sink(struct GrooveSink *sink) {
1156 struct GrooveSinkPrivate *s = (struct GrooveSinkPrivate *) sink;
1157
1158 groove_queue_purge(s->audioq);
1159
1160 struct GroovePlaylist *playlist = sink->playlist;
1161 struct GroovePlaylistPrivate *p = (struct GroovePlaylistPrivate *) playlist;
1162 struct GroovePlaylistItem *item = p->purge_item;
1163
1164 if (sink->purge)
1165 sink->purge(sink, item);
1166
1167 return 0;
1168 }
1169
groove_playlist_remove(struct GroovePlaylist * playlist,struct GroovePlaylistItem * item)1170 void groove_playlist_remove(struct GroovePlaylist *playlist, struct GroovePlaylistItem *item) {
1171 struct GroovePlaylistPrivate *p = (struct GroovePlaylistPrivate *) playlist;
1172
1173 pthread_mutex_lock(&p->decode_head_mutex);
1174
1175 // if it's currently being played, seek to the next item
1176 if (item == p->decode_head) {
1177 p->decode_head = item->next;
1178 }
1179
1180 if (item->prev) {
1181 item->prev->next = item->next;
1182 } else {
1183 playlist->head = item->next;
1184 }
1185 if (item->next) {
1186 item->next->prev = item->prev;
1187 } else {
1188 playlist->tail = item->prev;
1189 }
1190
1191 // in each sink,
1192 // we must be absolutely sure to purge the audio buffer queue
1193 // of references to item before freeing it at the bottom of this method
1194 p->purge_item = item;
1195 every_sink(playlist, purge_sink, 0);
1196 p->purge_item = NULL;
1197
1198 pthread_mutex_lock(&p->drain_cond_mutex);
1199 pthread_cond_signal(&p->sink_drain_cond);
1200 pthread_mutex_unlock(&p->drain_cond_mutex);
1201 pthread_mutex_unlock(&p->decode_head_mutex);
1202
1203 av_free(item);
1204 }
1205
groove_playlist_clear(struct GroovePlaylist * playlist)1206 void groove_playlist_clear(struct GroovePlaylist *playlist) {
1207 struct GroovePlaylistItem * node = playlist->head;
1208 if (!node) return;
1209 while (node) {
1210 struct GroovePlaylistItem *next = node->next;
1211 groove_playlist_remove(playlist, node);
1212 node = next;
1213 }
1214 }
1215
groove_playlist_count(struct GroovePlaylist * playlist)1216 int groove_playlist_count(struct GroovePlaylist *playlist) {
1217 struct GroovePlaylistItem * node = playlist->head;
1218 int count = 0;
1219 while (node) {
1220 count += 1;
1221 node = node->next;
1222 }
1223 return count;
1224 }
1225
groove_playlist_set_item_gain(struct GroovePlaylist * playlist,struct GroovePlaylistItem * item,double gain)1226 void groove_playlist_set_item_gain(struct GroovePlaylist *playlist, struct GroovePlaylistItem *item,
1227 double gain)
1228 {
1229 struct GroovePlaylistPrivate *p = (struct GroovePlaylistPrivate *) playlist;
1230
1231 pthread_mutex_lock(&p->decode_head_mutex);
1232 item->gain = gain;
1233 if (item == p->decode_head) {
1234 update_playlist_volume(playlist);
1235 }
1236 pthread_mutex_unlock(&p->decode_head_mutex);
1237 }
1238
groove_playlist_set_item_peak(struct GroovePlaylist * playlist,struct GroovePlaylistItem * item,double peak)1239 void groove_playlist_set_item_peak(struct GroovePlaylist *playlist, struct GroovePlaylistItem *item,
1240 double peak)
1241 {
1242 struct GroovePlaylistPrivate *p = (struct GroovePlaylistPrivate *) playlist;
1243
1244 pthread_mutex_lock(&p->decode_head_mutex);
1245 item->peak = peak;
1246 if (item == p->decode_head) {
1247 update_playlist_volume(playlist);
1248 }
1249 pthread_mutex_unlock(&p->decode_head_mutex);
1250 }
1251
groove_playlist_position(struct GroovePlaylist * playlist,struct GroovePlaylistItem ** item,double * seconds)1252 void groove_playlist_position(struct GroovePlaylist *playlist, struct GroovePlaylistItem **item,
1253 double *seconds)
1254 {
1255 struct GroovePlaylistPrivate *p = (struct GroovePlaylistPrivate *) playlist;
1256
1257 pthread_mutex_lock(&p->decode_head_mutex);
1258 if (item)
1259 *item = p->decode_head;
1260
1261 if (seconds) {
1262 if (p->decode_head) {
1263 struct GrooveFile *file = p->decode_head->file;
1264 struct GrooveFilePrivate *f = (struct GrooveFilePrivate *) file;
1265 *seconds = f->audio_clock;
1266 } else {
1267 *seconds = -1.0;
1268 }
1269 }
1270 pthread_mutex_unlock(&p->decode_head_mutex);
1271 }
1272
groove_playlist_set_gain(struct GroovePlaylist * playlist,double gain)1273 void groove_playlist_set_gain(struct GroovePlaylist *playlist, double gain) {
1274 struct GroovePlaylistPrivate *p = (struct GroovePlaylistPrivate *) playlist;
1275
1276 pthread_mutex_lock(&p->decode_head_mutex);
1277 playlist->gain = gain;
1278 if (p->decode_head)
1279 update_playlist_volume(playlist);
1280 pthread_mutex_unlock(&p->decode_head_mutex);
1281 }
1282
groove_playlist_playing(struct GroovePlaylist * playlist)1283 int groove_playlist_playing(struct GroovePlaylist *playlist) {
1284 struct GroovePlaylistPrivate *p = (struct GroovePlaylistPrivate *) playlist;
1285 return !p->paused;
1286 }
1287
groove_sink_create(void)1288 struct GrooveSink * groove_sink_create(void) {
1289 struct GrooveSinkPrivate *s = av_mallocz(sizeof(struct GrooveSinkPrivate));
1290
1291 if (!s) {
1292 av_log(NULL, AV_LOG_ERROR, "could not create sink: out of memory\n");
1293 return NULL;
1294 }
1295
1296 struct GrooveSink *sink = &s->externals;
1297
1298 sink->buffer_size = 8192;
1299 sink->gain = 1.0;
1300
1301 s->audioq = groove_queue_create();
1302
1303 if (!s->audioq) {
1304 groove_sink_destroy(sink);
1305 av_log(NULL, AV_LOG_ERROR, "could not create audio buffer: out of memory\n");
1306 return NULL;
1307 }
1308
1309 s->audioq->context = sink;
1310 s->audioq->cleanup = audioq_cleanup;
1311 s->audioq->put = audioq_put;
1312 s->audioq->get = audioq_get;
1313 s->audioq->purge = audioq_purge;
1314
1315 return sink;
1316 }
1317
groove_sink_destroy(struct GrooveSink * sink)1318 void groove_sink_destroy(struct GrooveSink *sink) {
1319 if (!sink)
1320 return;
1321
1322 struct GrooveSinkPrivate *s = (struct GrooveSinkPrivate *) sink;
1323
1324 if (s->audioq)
1325 groove_queue_destroy(s->audioq);
1326
1327 av_free(s);
1328 }
1329
groove_sink_set_gain(struct GrooveSink * sink,double gain)1330 int groove_sink_set_gain(struct GrooveSink *sink, double gain) {
1331 // we must re-create the sink mapping and the filter graph
1332 // if the gain changes
1333
1334 struct GroovePlaylist *playlist = sink->playlist;
1335 struct GroovePlaylistPrivate *p = (struct GroovePlaylistPrivate *) playlist;
1336
1337
1338 pthread_mutex_lock(&p->decode_head_mutex);
1339 sink->gain = gain;
1340 int err = remove_sink_from_map(sink);
1341 if (err) {
1342 pthread_mutex_unlock(&p->decode_head_mutex);
1343 return err;
1344 }
1345 err = add_sink_to_map(playlist, sink);
1346 if (err) {
1347 pthread_mutex_unlock(&p->decode_head_mutex);
1348 return err;
1349 }
1350 p->rebuild_filter_graph_flag = 1;
1351 pthread_mutex_unlock(&p->decode_head_mutex);
1352 return 0;
1353 }
1354
groove_playlist_set_fill_mode(struct GroovePlaylist * playlist,int mode)1355 void groove_playlist_set_fill_mode(struct GroovePlaylist *playlist, int mode) {
1356 struct GroovePlaylistPrivate *p = (struct GroovePlaylistPrivate *) playlist;
1357
1358 pthread_mutex_lock(&p->decode_head_mutex);
1359
1360 if (mode == GROOVE_EVERY_SINK_FULL) {
1361 p->detect_full_sinks = every_sink_full;
1362 } else {
1363 p->detect_full_sinks = any_sink_full;
1364 }
1365
1366 pthread_mutex_unlock(&p->decode_head_mutex);
1367 }
1368