OutputThread.cxx 14.3 KB
Newer Older
1
/*
Max Kellermann's avatar
Max Kellermann committed
2
 * Copyright (C) 2003-2015 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"
25
#include "pcm/Domain.hxx"
Max Kellermann's avatar
Max Kellermann committed
26
#include "notify.hxx"
27 28 29
#include "filter/FilterInternal.hxx"
#include "filter/plugins/ConvertFilterPlugin.hxx"
#include "filter/plugins/ReplayGainFilterPlugin.hxx"
30
#include "player/Control.hxx"
31 32
#include "MusicPipe.hxx"
#include "MusicChunk.hxx"
33
#include "thread/Util.hxx"
34
#include "thread/Slack.hxx"
35
#include "thread/Name.hxx"
36
#include "system/FatalError.hxx"
37
#include "util/Error.hxx"
38
#include "util/ConstBuffer.hxx"
39
#include "Log.hxx"
40
#include "Compiler.h"
41

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

45 46
void
AudioOutput::CommandFinished()
47
{
48 49
	assert(command != Command::NONE);
	command = Command::NONE;
50

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

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

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

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

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

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

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

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

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

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

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

	return af;
118 119
}

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

128
	filter->Close();
129 130
}

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

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

143
	fail_timer.Reset();
144

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

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

151 152
	/* open the filter */

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

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

163
	assert(filter_audio_format.IsValid());
164

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

168
	mutex.unlock();
169 170 171 172

	const AudioFormat retry_audio_format = out_audio_format;

 retry_without_dsd:
173 174
	success = ao_plugin_open(this, out_audio_format, error);
	mutex.lock();
175

176
	assert(!open);
177 178

	if (!success) {
179
		FormatError(error, "Failed to open \"%s\" [%s]",
180
			    name, plugin.name);
181

182
		mutex.unlock();
183
		CloseFilter();
184 185
		mutex.lock();

186
		fail_timer.Update();
187 188 189
		return;
	}

190
	if (!convert_filter_set(convert_filter, out_audio_format,
191 192
				error)) {
		FormatError(error, "Failed to convert for \"%s\" [%s]",
193
			    name, plugin.name);
194

195
		mutex.unlock();
196
		ao_plugin_close(this);
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221

		if (error.IsDomain(pcm_domain) &&
		    out_audio_format.format == SampleFormat::DSD) {
			/* if the audio output supports DSD, but not
			   the given sample rate, it asks MPD to
			   resample; resampling DSD however is not
			   implemented; our last resort is to give up
			   DSD and fall back to PCM */

			// TODO: clean up this workaround

			FormatError(output_domain, "Retrying without DSD");

			out_audio_format = retry_audio_format;
			out_audio_format.format = SampleFormat::FLOAT;

			/* clear the Error to allow reusing it */
			error.Clear();

			/* sorry for the "goto" - this is a workaround
			   for the stable branch that should be as
			   unintrusive as possible */
			goto retry_without_dsd;
		}

222
		CloseFilter();
223 224
		mutex.lock();

225
		fail_timer.Update();
226 227
		return;
	}
228

229
	open = true;
230

231 232
	FormatDebug(output_domain,
		    "opened plugin=%s name=\"%s\" audio_format=%s",
233 234
		    plugin.name, name,
		    audio_format_to_string(out_audio_format, &af_string));
235

236
	if (in_audio_format != out_audio_format)
237
		FormatDebug(output_domain, "converting from %s",
238
			    audio_format_to_string(in_audio_format,
239
						   &af_string));
240 241
}

242 243
void
AudioOutput::Close(bool drain)
244
{
245
	assert(open);
246

247
	pipe = nullptr;
248

249 250
	current_chunk = nullptr;
	open = false;
251

252
	mutex.unlock();
253

254
	CloseOutput(drain);
255
	CloseFilter();
256

257
	mutex.lock();
258

259
	FormatDebug(output_domain, "closed plugin=%s name=\"%s\"",
260
		    plugin.name, name);
261 262
}

263 264 265 266 267 268 269 270 271 272 273
inline void
AudioOutput::CloseOutput(bool drain)
{
	if (drain)
		ao_plugin_drain(this);
	else
		ao_plugin_cancel(this);

	ao_plugin_close(this);
}

274 275
void
AudioOutput::ReopenFilter()
276
{
277
	Error error;
278

279
	mutex.unlock();
280
	CloseFilter();
281 282
	mutex.lock();

283
	const AudioFormat filter_audio_format =
284
		OpenFilter(in_audio_format, error);
285
	if (!filter_audio_format.IsDefined() ||
286
	    !convert_filter_set(convert_filter, out_audio_format,
287
				error)) {
288 289
		FormatError(error,
			    "Failed to open filter for \"%s\" [%s]",
290
			    name, plugin.name);
291

292
		/* this is a little code duplication from Close(),
293
		   but we cannot call this function because we must
294
		   not call filter_close(filter) again */
295

296
		pipe = nullptr;
297

298 299 300
		current_chunk = nullptr;
		open = false;
		fail_timer.Update();
301

302 303 304
		mutex.unlock();
		ao_plugin_close(this);
		mutex.lock();
305 306 307 308 309

		return;
	}
}

310 311
void
AudioOutput::Reopen()
312
{
313 314 315 316 317
	if (!config_audio_format.IsFullyDefined()) {
		if (open) {
			const MusicPipe *mp = pipe;
			Close(true);
			pipe = mp;
318 319 320 321 322
		}

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

327
	if (open)
328 329
		/* the audio format has changed, and all filters have
		   to be reconfigured */
330
		ReopenFilter();
331
	else
332
		Open();
333 334
}

335 336 337 338 339 340
/**
 * Wait until the output's delay reaches zero.
 *
 * @return true if playback should be continued, false if a command
 * was issued
 */
341 342
inline bool
AudioOutput::WaitForDelay()
343 344
{
	while (true) {
345
		unsigned delay = ao_plugin_delay(this);
346 347 348
		if (delay == 0)
			return true;

349
		(void)cond.timed_wait(mutex, delay);
350

351
		if (command != Command::NONE)
352 353 354 355
			return false;
	}
}

356
static ConstBuffer<void>
357
ao_chunk_data(AudioOutput *ao, const MusicChunk *chunk,
358
	      Filter *replay_gain_filter,
359
	      unsigned *replay_gain_serial_p)
360
{
361
	assert(chunk != nullptr);
362 363
	assert(!chunk->IsEmpty());
	assert(chunk->CheckFormat(ao->in_audio_format));
364

365
	ConstBuffer<void> data(chunk->data, chunk->length);
366 367 368

	(void)ao;

369
	assert(data.size % ao->in_audio_format.GetFrameSize() == 0);
370

371
	if (!data.IsEmpty() && replay_gain_filter != nullptr) {
372 373 374 375
		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
376
						    : nullptr);
377 378 379
			*replay_gain_serial_p = chunk->replay_gain_serial;
		}

380
		Error error;
381 382
		data = replay_gain_filter->FilterPCM(data, error);
		if (data.IsNull())
383
			FormatError(error, "\"%s\" [%s] failed to filter",
384
				    ao->name, ao->plugin.name);
385 386
	}

387 388 389
	return data;
}

390 391
static ConstBuffer<void>
ao_filter_chunk(AudioOutput *ao, const MusicChunk *chunk)
392
{
393 394 395 396
	ConstBuffer<void> data =
		ao_chunk_data(ao, chunk, ao->replay_gain_filter,
			      &ao->replay_gain_serial);
	if (data.IsEmpty())
397
		return data;
398

399 400
	/* cross-fade */

401
	if (chunk->other != nullptr) {
402
		ConstBuffer<void> other_data =
403 404
			ao_chunk_data(ao, chunk->other,
				      ao->other_replay_gain_filter,
405 406
				      &ao->other_replay_gain_serial);
		if (other_data.IsNull())
407
			return nullptr;
408

409
		if (other_data.IsEmpty())
410 411 412 413 414 415 416
			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 */

417 418
		if (data.size > other_data.size)
			data.size = other_data.size;
419

Max Kellermann's avatar
Max Kellermann committed
420 421 422 423 424 425 426 427 428
		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;

429 430 431
		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,
432
			     ao->in_audio_format.format,
Max Kellermann's avatar
Max Kellermann committed
433
			     mix_ratio)) {
434 435 436
			FormatError(output_domain,
				    "Cannot cross-fade format %s",
				    sample_format_to_string(ao->in_audio_format.format));
437
			return nullptr;
438
		}
439

440 441
		data.data = dest;
		data.size = other_data.size;
442 443
	}

444
	/* apply filter chain */
445

446
	Error error;
447 448
	data = ao->filter->FilterPCM(data, error);
	if (data.IsNull()) {
449
		FormatError(error, "\"%s\" [%s] failed to filter",
450
			    ao->name, ao->plugin.name);
451
		return nullptr;
452 453 454 455 456
	}

	return data;
}

457
inline bool
458
AudioOutput::PlayChunk(const MusicChunk *chunk)
459
{
460
	assert(filter != nullptr);
461

462 463
	if (tags && gcc_unlikely(chunk->tag != nullptr)) {
		mutex.unlock();
464
		ao_plugin_send_tag(this, *chunk->tag);
465
		mutex.lock();
466 467
	}

468 469
	auto data = ConstBuffer<char>::FromVoid(ao_filter_chunk(this, chunk));
	if (data.IsNull()) {
470
		Close(false);
471 472 473

		/* don't automatically reopen this device for 10
		   seconds */
474
		fail_timer.Update();
475
		return false;
476 477
	}

478 479
	Error error;

480
	while (!data.IsEmpty() && command == Command::NONE) {
481
		if (!WaitForDelay())
482 483
			break;

484
		mutex.unlock();
485 486
		size_t nbytes = ao_plugin_play(this, data.data, data.size,
					       error);
487
		mutex.lock();
488 489
		if (nbytes == 0) {
			/* play()==0 means failure */
490
			FormatError(error, "\"%s\" [%s] failed to play",
491
				    name, plugin.name);
492

493
			Close(false);
494 495 496

			/* don't automatically reopen this device for
			   10 seconds */
497 498
			assert(!fail_timer.IsDefined());
			fail_timer.Update();
499

500
			return false;
501 502
		}

503
		assert(nbytes <= data.size);
504
		assert(nbytes % out_audio_format.GetFrameSize() == 0);
505

506 507
		data.data += nbytes;
		data.size -= nbytes;
508 509
	}

510 511 512
	return true;
}

513
inline const MusicChunk *
514
AudioOutput::GetNextChunk() const
515
{
516
	return current_chunk != nullptr
517
		/* continue the previous play() call */
518
		? current_chunk->next
519
		/* get the first chunk from the pipe */
520
		: pipe->Peek();
521 522
}

523 524
inline bool
AudioOutput::Play()
525
{
526
	assert(pipe != nullptr);
527

528
	const MusicChunk *chunk = GetNextChunk();
529
	if (chunk == nullptr)
530 531
		/* no chunk available */
		return false;
532

533
	current_chunk_finished = false;
534

535 536
	assert(!in_playback_loop);
	in_playback_loop = true;
537

538
	while (chunk != nullptr && command == Command::NONE) {
539
		assert(!current_chunk_finished);
540

541
		current_chunk = chunk;
542

543 544
		if (!PlayChunk(chunk)) {
			assert(current_chunk == nullptr);
545 546 547
			break;
		}

548
		assert(current_chunk == chunk);
549 550 551
		chunk = chunk->next;
	}

552 553
	assert(in_playback_loop);
	in_playback_loop = false;
554

555
	current_chunk_finished = true;
556

557 558 559
	mutex.unlock();
	player_control->LockSignal();
	mutex.lock();
560 561

	return true;
562 563
}

564 565
inline void
AudioOutput::Pause()
566
{
567 568 569
	mutex.unlock();
	ao_plugin_cancel(this);
	mutex.lock();
570

571 572
	pause = true;
	CommandFinished();
573 574

	do {
575
		if (!WaitForDelay())
576 577
			break;

578 579 580
		mutex.unlock();
		bool success = ao_plugin_pause(this);
		mutex.lock();
581

582 583
		if (!success) {
			Close(false);
584 585
			break;
		}
586
	} while (command == Command::NONE);
587

588
	pause = false;
589 590
}

591 592
inline void
AudioOutput::Task()
593
{
594
	FormatThreadName("output:%s", name);
595

596
	SetThreadRealtime();
597
	SetThreadTimerSlackUS(100);
598

599
	mutex.lock();
600

601
	while (1) {
602
		switch (command) {
603
		case Command::NONE:
604 605
			break;

606
		case Command::ENABLE:
607 608
			Enable();
			CommandFinished();
609 610
			break;

611
		case Command::DISABLE:
612 613
			Disable();
			CommandFinished();
614 615
			break;

616
		case Command::OPEN:
617 618
			Open();
			CommandFinished();
619 620
			break;

621
		case Command::REOPEN:
622 623
			Reopen();
			CommandFinished();
624 625
			break;

626
		case Command::CLOSE:
627 628
			assert(open);
			assert(pipe != nullptr);
629

630 631
			Close(false);
			CommandFinished();
632 633
			break;

634
		case Command::PAUSE:
635
			if (!open) {
636 637 638 639
				/* the output has failed after
				   audio_output_all_pause() has
				   submitted the PAUSE command; bail
				   out */
640
				CommandFinished();
641 642 643
				break;
			}

644
			Pause();
645
			/* don't "break" here: this might cause
646
			   Play() to be called when command==CLOSE
647 648 649
			   ends the paused state - "continue" checks
			   the new command first */
			continue;
650

651
		case Command::DRAIN:
652 653 654
			if (open) {
				assert(current_chunk == nullptr);
				assert(pipe->Peek() == nullptr);
655

656 657 658
				mutex.unlock();
				ao_plugin_drain(this);
				mutex.lock();
659 660
			}

661
			CommandFinished();
662 663
			continue;

664
		case Command::CANCEL:
665
			current_chunk = nullptr;
666

667 668 669 670
			if (open) {
				mutex.unlock();
				ao_plugin_cancel(this);
				mutex.lock();
671 672
			}

673
			CommandFinished();
674
			continue;
675

676
		case Command::KILL:
677 678 679
			current_chunk = nullptr;
			CommandFinished();
			mutex.unlock();
680
			return;
681 682
		}

683
		if (open && allow_play && Play())
684 685 686
			/* don't wait for an event if there are more
			   chunks in the pipe */
			continue;
687

688
		if (command == Command::NONE) {
689 690
			woken_for_play = false;
			cond.wait(mutex);
691
		}
692 693 694
	}
}

695 696 697 698 699 700 701
void
AudioOutput::Task(void *arg)
{
	AudioOutput *ao = (AudioOutput *)arg;
	ao->Task();
}

702 703
void
AudioOutput::StartThread()
704
{
705
	assert(command == Command::NONE);
706

707
	Error error;
708
	if (!thread.Start(Task, this, error))
709
		FatalError(error);
710
}