OutputThread.cxx 13.3 KB
Newer Older
1
/*
Max Kellermann's avatar
Max Kellermann committed
2
 * Copyright (C) 2003-2014 The Music Player Daemon Project
3
 * http://www.musicpd.org
4 5 6 7 8 9 10 11 12 13
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
14 15 16 17
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 19
 */

20
#include "config.h"
21
#include "Internal.hxx"
22
#include "OutputAPI.hxx"
23
#include "Domain.hxx"
Max Kellermann's avatar
Max Kellermann committed
24
#include "pcm/PcmMix.hxx"
Max Kellermann's avatar
Max Kellermann committed
25
#include "notify.hxx"
26 27 28
#include "filter/FilterInternal.hxx"
#include "filter/plugins/ConvertFilterPlugin.hxx"
#include "filter/plugins/ReplayGainFilterPlugin.hxx"
29
#include "PlayerControl.hxx"
30 31
#include "MusicPipe.hxx"
#include "MusicChunk.hxx"
32
#include "thread/Util.hxx"
33
#include "thread/Slack.hxx"
34
#include "thread/Name.hxx"
35
#include "system/FatalError.hxx"
36
#include "util/Error.hxx"
37
#include "util/ConstBuffer.hxx"
38
#include "Log.hxx"
39
#include "Compiler.h"
40

41
#include <assert.h>
Max Kellermann's avatar
Max Kellermann committed
42
#include <string.h>
43

44 45
void
AudioOutput::CommandFinished()
46
{
47 48
	assert(command != AO_COMMAND_NONE);
	command = AO_COMMAND_NONE;
49

50
	mutex.unlock();
Max Kellermann's avatar
Max Kellermann committed
51
	audio_output_client_notify.Signal();
52
	mutex.lock();
53 54
}

55 56
inline bool
AudioOutput::Enable()
57
{
58
	if (really_enabled)
59 60
		return true;

61 62 63 64
	mutex.unlock();
	Error error;
	bool success = ao_plugin_enable(this, error);
	mutex.lock();
65
	if (!success) {
66 67
		FormatError(error,
			    "Failed to enable \"%s\" [%s]",
68
			    name, plugin.name);
69 70 71
		return false;
	}

72
	really_enabled = true;
73 74 75
	return true;
}

76 77
inline void
AudioOutput::Disable()
78
{
79 80
	if (open)
		Close(false);
81

82 83
	if (really_enabled) {
		really_enabled = false;
84

85 86 87
		mutex.unlock();
		ao_plugin_disable(this);
		mutex.lock();
88 89 90
	}
}

91 92
inline AudioFormat
AudioOutput::OpenFilter(AudioFormat &format, Error &error_r)
93
{
94
	assert(format.IsValid());
95

96
	/* the replay_gain filter cannot fail here */
97 98
	if (replay_gain_filter != nullptr &&
	    !replay_gain_filter->Open(format, error_r).IsDefined())
99 100
		return AudioFormat::Undefined();

101 102 103 104
	if (other_replay_gain_filter != nullptr &&
	    !other_replay_gain_filter->Open(format, error_r).IsDefined()) {
		if (replay_gain_filter != nullptr)
			replay_gain_filter->Close();
105 106
		return AudioFormat::Undefined();
	}
107

108
	const AudioFormat af = filter->Open(format, error_r);
109
	if (!af.IsDefined()) {
110 111 112 113
		if (replay_gain_filter != nullptr)
			replay_gain_filter->Close();
		if (other_replay_gain_filter != nullptr)
			other_replay_gain_filter->Close();
114 115 116
	}

	return af;
117 118
}

119 120
void
AudioOutput::CloseFilter()
121
{
122 123 124 125
	if (replay_gain_filter != nullptr)
		replay_gain_filter->Close();
	if (other_replay_gain_filter != nullptr)
		other_replay_gain_filter->Close();
126

127
	filter->Close();
128 129
}

130 131
inline void
AudioOutput::Open()
132 133
{
	bool success;
134
	Error error;
135
	struct audio_format_string af_string;
136

137 138 139 140
	assert(!open);
	assert(pipe != nullptr);
	assert(current_chunk == nullptr);
	assert(in_audio_format.IsValid());
141

142
	fail_timer.Reset();
143

144 145
	/* enable the device (just in case the last enable has failed) */

146
	if (!Enable())
147 148 149
		/* still no luck */
		return;

150 151
	/* open the filter */

152
	const AudioFormat filter_audio_format =
153
		OpenFilter(in_audio_format, error);
154
	if (!filter_audio_format.IsDefined()) {
155
		FormatError(error, "Failed to open filter for \"%s\" [%s]",
156
			    name, plugin.name);
157

158
		fail_timer.Update();
159 160 161
		return;
	}

162
	assert(filter_audio_format.IsValid());
163

164 165
	out_audio_format = filter_audio_format;
	out_audio_format.ApplyMask(config_audio_format);
166

167 168 169
	mutex.unlock();
	success = ao_plugin_open(this, out_audio_format, error);
	mutex.lock();
170

171
	assert(!open);
172 173

	if (!success) {
174
		FormatError(error, "Failed to open \"%s\" [%s]",
175
			    name, plugin.name);
176

177 178
		CloseFilter();
		fail_timer.Update();
179 180 181
		return;
	}

182
	if (!convert_filter_set(convert_filter, out_audio_format,
183 184
				error)) {
		FormatError(error, "Failed to convert for \"%s\" [%s]",
185
			    name, plugin.name);
186

187 188
		CloseFilter();
		fail_timer.Update();
189 190
		return;
	}
191

192
	open = true;
193

194 195
	FormatDebug(output_domain,
		    "opened plugin=%s name=\"%s\" audio_format=%s",
196 197
		    plugin.name, name,
		    audio_format_to_string(out_audio_format, &af_string));
198

199
	if (in_audio_format != out_audio_format)
200
		FormatDebug(output_domain, "converting from %s",
201
			    audio_format_to_string(in_audio_format,
202
						   &af_string));
203 204
}

205 206
void
AudioOutput::Close(bool drain)
207
{
208
	assert(open);
209

210
	pipe = nullptr;
211

212 213
	current_chunk = nullptr;
	open = false;
214

215
	mutex.unlock();
216

217
	if (drain)
218
		ao_plugin_drain(this);
219
	else
220
		ao_plugin_cancel(this);
221

222 223
	ao_plugin_close(this);
	CloseFilter();
224

225
	mutex.lock();
226

227
	FormatDebug(output_domain, "closed plugin=%s name=\"%s\"",
228
		    plugin.name, name);
229 230
}

231 232
void
AudioOutput::ReopenFilter()
233
{
234
	Error error;
235

236
	CloseFilter();
237
	const AudioFormat filter_audio_format =
238
		OpenFilter(in_audio_format, error);
239
	if (!filter_audio_format.IsDefined() ||
240
	    !convert_filter_set(convert_filter, out_audio_format,
241
				error)) {
242 243
		FormatError(error,
			    "Failed to open filter for \"%s\" [%s]",
244
			    name, plugin.name);
245

246
		/* this is a little code duplication from Close(),
247
		   but we cannot call this function because we must
248
		   not call filter_close(filter) again */
249

250
		pipe = nullptr;
251

252 253 254
		current_chunk = nullptr;
		open = false;
		fail_timer.Update();
255

256 257 258
		mutex.unlock();
		ao_plugin_close(this);
		mutex.lock();
259 260 261 262 263

		return;
	}
}

264 265
void
AudioOutput::Reopen()
266
{
267 268 269 270 271
	if (!config_audio_format.IsFullyDefined()) {
		if (open) {
			const MusicPipe *mp = pipe;
			Close(true);
			pipe = mp;
272 273 274 275 276
		}

		/* no audio format is configured: copy in->out, let
		   the output's open() method determine the effective
		   out_audio_format */
277 278
		out_audio_format = in_audio_format;
		out_audio_format.ApplyMask(config_audio_format);
279 280
	}

281
	if (open)
282 283
		/* the audio format has changed, and all filters have
		   to be reconfigured */
284
		ReopenFilter();
285
	else
286
		Open();
287 288
}

289 290 291 292 293 294
/**
 * Wait until the output's delay reaches zero.
 *
 * @return true if playback should be continued, false if a command
 * was issued
 */
295 296
inline bool
AudioOutput::WaitForDelay()
297 298
{
	while (true) {
299
		unsigned delay = ao_plugin_delay(this);
300 301 302
		if (delay == 0)
			return true;

303
		(void)cond.timed_wait(mutex, delay);
304

305
		if (command != AO_COMMAND_NONE)
306 307 308 309
			return false;
	}
}

310
static ConstBuffer<void>
311
ao_chunk_data(AudioOutput *ao, const MusicChunk *chunk,
312
	      Filter *replay_gain_filter,
313
	      unsigned *replay_gain_serial_p)
314
{
315
	assert(chunk != nullptr);
316 317
	assert(!chunk->IsEmpty());
	assert(chunk->CheckFormat(ao->in_audio_format));
318

319
	ConstBuffer<void> data(chunk->data, chunk->length);
320 321 322

	(void)ao;

323
	assert(data.size % ao->in_audio_format.GetFrameSize() == 0);
324

325
	if (!data.IsEmpty() && replay_gain_filter != nullptr) {
326 327 328 329
		if (chunk->replay_gain_serial != *replay_gain_serial_p) {
			replay_gain_filter_set_info(replay_gain_filter,
						    chunk->replay_gain_serial != 0
						    ? &chunk->replay_gain_info
330
						    : nullptr);
331 332 333
			*replay_gain_serial_p = chunk->replay_gain_serial;
		}

334
		Error error;
335 336
		data = replay_gain_filter->FilterPCM(data, error);
		if (data.IsNull())
337
			FormatError(error, "\"%s\" [%s] failed to filter",
338
				    ao->name, ao->plugin.name);
339 340
	}

341 342 343
	return data;
}

344 345
static ConstBuffer<void>
ao_filter_chunk(AudioOutput *ao, const MusicChunk *chunk)
346
{
347 348 349 350
	ConstBuffer<void> data =
		ao_chunk_data(ao, chunk, ao->replay_gain_filter,
			      &ao->replay_gain_serial);
	if (data.IsEmpty())
351
		return data;
352

353 354
	/* cross-fade */

355
	if (chunk->other != nullptr) {
356
		ConstBuffer<void> other_data =
357 358
			ao_chunk_data(ao, chunk->other,
				      ao->other_replay_gain_filter,
359 360
				      &ao->other_replay_gain_serial);
		if (other_data.IsNull())
361
			return nullptr;
362

363
		if (other_data.IsEmpty())
364 365 366 367 368 369 370
			return data;

		/* if the "other" chunk is longer, then that trailer
		   is used as-is, without mixing; it is part of the
		   "next" song being faded in, and if there's a rest,
		   it means cross-fading ends here */

371 372
		if (data.size > other_data.size)
			data.size = other_data.size;
373

Max Kellermann's avatar
Max Kellermann committed
374 375 376 377 378 379 380 381 382
		float mix_ratio = chunk->mix_ratio;
		if (mix_ratio >= 0)
			/* reverse the mix ratio (because the
			   arguments to pcm_mix() are reversed), but
			   only if the mix ratio is non-negative; a
			   negative mix ratio is a MixRamp special
			   case */
			mix_ratio = 1.0 - mix_ratio;

383 384 385
		void *dest = ao->cross_fade_buffer.Get(other_data.size);
		memcpy(dest, other_data.data, other_data.size);
		if (!pcm_mix(ao->cross_fade_dither, dest, data.data, data.size,
386
			     ao->in_audio_format.format,
Max Kellermann's avatar
Max Kellermann committed
387
			     mix_ratio)) {
388 389 390
			FormatError(output_domain,
				    "Cannot cross-fade format %s",
				    sample_format_to_string(ao->in_audio_format.format));
391
			return nullptr;
392
		}
393

394 395
		data.data = dest;
		data.size = other_data.size;
396 397
	}

398
	/* apply filter chain */
399

400
	Error error;
401 402
	data = ao->filter->FilterPCM(data, error);
	if (data.IsNull()) {
403
		FormatError(error, "\"%s\" [%s] failed to filter",
404
			    ao->name, ao->plugin.name);
405
		return nullptr;
406 407 408 409 410
	}

	return data;
}

411
inline bool
412
AudioOutput::PlayChunk(const MusicChunk *chunk)
413
{
414
	assert(filter != nullptr);
415

416 417 418 419
	if (tags && gcc_unlikely(chunk->tag != nullptr)) {
		mutex.unlock();
		ao_plugin_send_tag(this, chunk->tag);
		mutex.lock();
420 421
	}

422 423
	auto data = ConstBuffer<char>::FromVoid(ao_filter_chunk(this, chunk));
	if (data.IsNull()) {
424
		Close(false);
425 426 427

		/* don't automatically reopen this device for 10
		   seconds */
428
		fail_timer.Update();
429
		return false;
430 431
	}

432 433
	Error error;

434
	while (!data.IsEmpty() && command == AO_COMMAND_NONE) {
435
		if (!WaitForDelay())
436 437
			break;

438
		mutex.unlock();
439 440
		size_t nbytes = ao_plugin_play(this, data.data, data.size,
					       error);
441
		mutex.lock();
442 443
		if (nbytes == 0) {
			/* play()==0 means failure */
444
			FormatError(error, "\"%s\" [%s] failed to play",
445
				    name, plugin.name);
446

447
			Close(false);
448 449 450

			/* don't automatically reopen this device for
			   10 seconds */
451 452
			assert(!fail_timer.IsDefined());
			fail_timer.Update();
453

454
			return false;
455 456
		}

457
		assert(nbytes <= data.size);
458
		assert(nbytes % out_audio_format.GetFrameSize() == 0);
459

460 461
		data.data += nbytes;
		data.size -= nbytes;
462 463
	}

464 465 466
	return true;
}

467
inline const MusicChunk *
468
AudioOutput::GetNextChunk() const
469
{
470
	return current_chunk != nullptr
471
		/* continue the previous play() call */
472
		? current_chunk->next
473
		/* get the first chunk from the pipe */
474
		: pipe->Peek();
475 476
}

477 478
inline bool
AudioOutput::Play()
479
{
480
	assert(pipe != nullptr);
481

482
	const MusicChunk *chunk = GetNextChunk();
483
	if (chunk == nullptr)
484 485
		/* no chunk available */
		return false;
486

487
	current_chunk_finished = false;
488

489 490
	assert(!in_playback_loop);
	in_playback_loop = true;
491

492 493
	while (chunk != nullptr && command == AO_COMMAND_NONE) {
		assert(!current_chunk_finished);
494

495
		current_chunk = chunk;
496

497 498
		if (!PlayChunk(chunk)) {
			assert(current_chunk == nullptr);
499 500 501
			break;
		}

502
		assert(current_chunk == chunk);
503 504 505
		chunk = chunk->next;
	}

506 507
	assert(in_playback_loop);
	in_playback_loop = false;
508

509
	current_chunk_finished = true;
510

511 512 513
	mutex.unlock();
	player_control->LockSignal();
	mutex.lock();
514 515

	return true;
516 517
}

518 519
inline void
AudioOutput::Pause()
520
{
521 522 523
	mutex.unlock();
	ao_plugin_cancel(this);
	mutex.lock();
524

525 526
	pause = true;
	CommandFinished();
527 528

	do {
529
		if (!WaitForDelay())
530 531
			break;

532 533 534
		mutex.unlock();
		bool success = ao_plugin_pause(this);
		mutex.lock();
535

536 537
		if (!success) {
			Close(false);
538 539
			break;
		}
540
	} while (command == AO_COMMAND_NONE);
541

542
	pause = false;
543 544
}

545 546
inline void
AudioOutput::Task()
547
{
548
	FormatThreadName("output:%s", name);
549

550
	SetThreadRealtime();
551
	SetThreadTimerSlackUS(100);
552

553
	mutex.lock();
554

555
	while (1) {
556
		switch (command) {
557 558 559
		case AO_COMMAND_NONE:
			break;

560
		case AO_COMMAND_ENABLE:
561 562
			Enable();
			CommandFinished();
563 564 565
			break;

		case AO_COMMAND_DISABLE:
566 567
			Disable();
			CommandFinished();
568 569
			break;

570
		case AO_COMMAND_OPEN:
571 572
			Open();
			CommandFinished();
573 574
			break;

575
		case AO_COMMAND_REOPEN:
576 577
			Reopen();
			CommandFinished();
578 579
			break;

580
		case AO_COMMAND_CLOSE:
581 582
			assert(open);
			assert(pipe != nullptr);
583

584 585
			Close(false);
			CommandFinished();
586 587
			break;

588
		case AO_COMMAND_PAUSE:
589
			if (!open) {
590 591 592 593
				/* the output has failed after
				   audio_output_all_pause() has
				   submitted the PAUSE command; bail
				   out */
594
				CommandFinished();
595 596 597
				break;
			}

598
			Pause();
599
			/* don't "break" here: this might cause
600
			   Play() to be called when command==CLOSE
601 602 603
			   ends the paused state - "continue" checks
			   the new command first */
			continue;
604

605
		case AO_COMMAND_DRAIN:
606 607 608
			if (open) {
				assert(current_chunk == nullptr);
				assert(pipe->Peek() == nullptr);
609

610 611 612
				mutex.unlock();
				ao_plugin_drain(this);
				mutex.lock();
613 614
			}

615
			CommandFinished();
616 617
			continue;

618
		case AO_COMMAND_CANCEL:
619
			current_chunk = nullptr;
620

621 622 623 624
			if (open) {
				mutex.unlock();
				ao_plugin_cancel(this);
				mutex.lock();
625 626
			}

627
			CommandFinished();
628
			continue;
629 630

		case AO_COMMAND_KILL:
631 632 633
			current_chunk = nullptr;
			CommandFinished();
			mutex.unlock();
634
			return;
635 636
		}

637
		if (open && allow_play && Play())
638 639 640
			/* don't wait for an event if there are more
			   chunks in the pipe */
			continue;
641

642 643 644
		if (command == AO_COMMAND_NONE) {
			woken_for_play = false;
			cond.wait(mutex);
645
		}
646 647 648
	}
}

649 650 651 652 653 654 655
void
AudioOutput::Task(void *arg)
{
	AudioOutput *ao = (AudioOutput *)arg;
	ao->Task();
}

656 657
void
AudioOutput::StartThread()
658
{
659
	assert(command == AO_COMMAND_NONE);
660

661
	Error error;
662
	if (!thread.Start(Task, this, error))
663
		FatalError(error);
664
}