Bridge.cxx 13.9 KB
Newer Older
1
/*
Max Kellermann's avatar
Max Kellermann committed
2
 * Copyright 2003-2019 The Music Player Daemon Project
3 4 5 6 7 8 9 10 11 12 13
 * http://www.musicpd.org
 *
 * 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 "Bridge.hxx"
21
#include "DecoderAPI.hxx"
22 23
#include "Domain.hxx"
#include "Control.hxx"
24
#include "song/DetachedSong.hxx"
25
#include "pcm/Convert.hxx"
26 27 28
#include "MusicPipe.hxx"
#include "MusicBuffer.hxx"
#include "MusicChunk.hxx"
29
#include "tag/Tag.hxx"
30 31
#include "Log.hxx"
#include "input/InputStream.hxx"
32
#include "input/LocalOpen.hxx"
33 34
#include "input/cache/Manager.hxx"
#include "input/cache/Stream.hxx"
35
#include "fs/Path.hxx"
36
#include "util/ConstBuffer.hxx"
37
#include "util/StringBuffer.hxx"
38 39

#include <assert.h>
40 41
#include <string.h>
#include <math.h>
42

43 44 45 46 47 48
DecoderBridge::DecoderBridge(DecoderControl &_dc, bool _initial_seek_pending,
			     std::unique_ptr<Tag> _tag) noexcept
	:dc(_dc),
	 initial_seek_pending(_initial_seek_pending),
	 song_tag(std::move(_tag)) {}

49
DecoderBridge::~DecoderBridge() noexcept
50 51
{
	/* caller must flush the chunk */
52
	assert(current_chunk == nullptr);
53 54
}

55
InputStreamPtr
56
DecoderBridge::OpenLocal(Path path_fs, const char *uri_utf8)
57
{
58 59 60 61 62 63 64 65 66 67
	if (dc.input_cache != nullptr) {
		auto lease = dc.input_cache->Get(uri_utf8, true);
		if (lease) {
			auto is = std::make_unique<CacheInputStream>(std::move(lease),
								     dc.mutex);
			is->SetHandler(&dc);
			return is;
		}
	}

68 69 70
	return OpenLocalInputStream(path_fs, dc.mutex);
}

71
bool
72
DecoderBridge::CheckCancelRead() const noexcept
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
{
	if (error)
		/* this translates to DecoderCommand::STOP */
		return true;

	if (dc.command == DecoderCommand::NONE)
		return false;

	/* ignore the SEEK command during initialization, the plugin
	   should handle that after it has initialized successfully */
	if (dc.command == DecoderCommand::SEEK &&
	    (dc.state == DecoderState::START || seeking ||
	     initial_seek_running))
		return false;

	return true;
}

91 92 93 94
/**
 * All chunks are full of decoded data; wait for the player to free
 * one.
 */
95
static DecoderCommand
96
NeedChunks(DecoderControl &dc, std::unique_lock<Mutex> &lock) noexcept
97
{
98
	if (dc.command == DecoderCommand::NONE)
99
		dc.Wait(lock);
100

101
	return dc.command;
102 103
}

104
static DecoderCommand
105
LockNeedChunks(DecoderControl &dc) noexcept
106
{
107 108
	std::unique_lock<Mutex> lock(dc.mutex);
	return NeedChunks(dc, lock);
109 110
}

111
MusicChunk *
112
DecoderBridge::GetChunk() noexcept
113
{
114
	DecoderCommand cmd;
115

116
	if (current_chunk != nullptr)
117
		return current_chunk.get();
118

119
	do {
120
		current_chunk = dc.buffer->Allocate();
121 122
		if (current_chunk != nullptr) {
			current_chunk->replay_gain_serial = replay_gain_serial;
123
			if (replay_gain_serial != 0)
124
				current_chunk->replay_gain_info = replay_gain_info;
125

126
			return current_chunk.get();
127
		}
128

129
		cmd = LockNeedChunks(dc);
130
	} while (cmd == DecoderCommand::NONE);
131

132
	return nullptr;
133 134
}

135
void
136
DecoderBridge::FlushChunk() noexcept
137
{
Max Kellermann's avatar
Max Kellermann committed
138 139 140
	assert(!seeking);
	assert(!initial_seek_running);
	assert(!initial_seek_pending);
141
	assert(current_chunk != nullptr);
142

143 144 145
	auto chunk = std::move(current_chunk);
	if (!chunk->IsEmpty())
		dc.pipe->Push(std::move(chunk));
146

147
	const std::lock_guard<Mutex> protect(dc.mutex);
148
	if (dc.client_is_waiting)
149
		dc.client_cond.notify_one();
150
}
151 152

bool
153
DecoderBridge::PrepareInitialSeek() noexcept
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
{
	assert(dc.pipe != nullptr);

	if (dc.state != DecoderState::DECODE)
		/* wait until the decoder has finished initialisation
		   (reading file headers etc.) before emitting the
		   virtual "SEEK" command */
		return false;

	if (initial_seek_running)
		/* initial seek has already begun - override any other
		   command */
		return true;

	if (initial_seek_pending) {
		if (!dc.seekable) {
			/* seeking is not possible */
			initial_seek_pending = false;
			return false;
		}

		if (dc.command == DecoderCommand::NONE) {
			/* begin initial seek */

			initial_seek_pending = false;
			initial_seek_running = true;
			return true;
		}

		/* skip initial seek when there's another command
		   (e.g. STOP) */

		initial_seek_pending = false;
	}

	return false;
}

DecoderCommand
193
DecoderBridge::GetVirtualCommand() noexcept
194 195 196 197 198 199 200 201 202 203 204 205 206 207
{
	if (error)
		/* an error has occurred: stop the decoder plugin */
		return DecoderCommand::STOP;

	assert(dc.pipe != nullptr);

	if (PrepareInitialSeek())
		return DecoderCommand::SEEK;

	return dc.command;
}

DecoderCommand
208
DecoderBridge::LockGetVirtualCommand() noexcept
209
{
210
	const std::lock_guard<Mutex> protect(dc.mutex);
211 212 213 214
	return GetVirtualCommand();
}

DecoderCommand
215
DecoderBridge::DoSendTag(const Tag &tag) noexcept
216 217 218 219 220 221 222 223 224 225 226 227 228 229 230
{
	if (current_chunk != nullptr) {
		/* there is a partial chunk - flush it, we want the
		   tag in a new chunk */
		FlushChunk();
	}

	assert(current_chunk == nullptr);

	auto *chunk = GetChunk();
	if (chunk == nullptr) {
		assert(dc.command != DecoderCommand::NONE);
		return dc.command;
	}

231
	chunk->tag = std::make_unique<Tag>(tag);
232 233 234 235
	return DecoderCommand::NONE;
}

bool
236
DecoderBridge::UpdateStreamTag(InputStream *is) noexcept
237
{
238 239
	auto tag = is != nullptr
		? is->LockReadTag()
240 241
		: nullptr;
	if (tag == nullptr) {
242
		tag = std::move(song_tag);
243 244 245 246 247 248 249
		if (tag == nullptr)
			return false;

		/* no stream tag present - submit the song tag
		   instead */
	} else
		/* discard the song tag; we don't need it */
250
		song_tag.reset();
251

252
	stream_tag = std::move(tag);
253 254 255 256 257
	return true;
}

void
DecoderBridge::Ready(const AudioFormat audio_format,
258
		     bool seekable, SignedSongTime duration) noexcept
259 260 261 262 263 264 265
{
	assert(convert == nullptr);
	assert(stream_tag == nullptr);
	assert(decoder_tag == nullptr);
	assert(!seeking);

	FormatDebug(decoder_domain, "audio_format=%s, seekable=%s",
266
		    ToString(audio_format).c_str(),
267 268
		    seekable ? "true" : "false");

269
	{
270
		const std::lock_guard<Mutex> protect(dc.mutex);
271 272 273
		dc.SetReady(audio_format, seekable, duration);
	}

274 275
	if (dc.in_audio_format != dc.out_audio_format) {
		FormatDebug(decoder_domain, "converting to %s",
276
			    ToString(dc.out_audio_format).c_str());
277 278

		try {
279 280
			convert = std::make_unique<PcmConvert>(dc.in_audio_format,
							       dc.out_audio_format);
281 282 283 284 285 286 287
		} catch (...) {
			error = std::current_exception();
		}
	}
}

DecoderCommand
288
DecoderBridge::GetCommand() noexcept
289 290 291 292 293
{
	return LockGetVirtualCommand();
}

void
294
DecoderBridge::CommandFinished() noexcept
295
{
296
	const std::lock_guard<Mutex> protect(dc.mutex);
297 298 299 300 301 302 303 304 305 306 307 308 309

	assert(dc.command != DecoderCommand::NONE || initial_seek_running);
	assert(dc.command != DecoderCommand::SEEK ||
	       initial_seek_running ||
	       dc.seek_error || seeking);
	assert(dc.pipe != nullptr);

	if (initial_seek_running) {
		assert(!seeking);
		assert(current_chunk == nullptr);
		assert(dc.pipe->IsEmpty());

		initial_seek_running = false;
310
		timestamp = std::chrono::duration_cast<FloatDuration>(dc.start_time);
311
		absolute_frame = dc.start_time.ToScale<uint64_t>(dc.in_audio_format.sample_rate);
312 313 314 315 316 317 318 319
		return;
	}

	if (seeking) {
		seeking = false;

		/* delete frames from the old song position */

320
		current_chunk.reset();
321

322
		dc.pipe->Clear();
323

324 325 326
		if (convert != nullptr)
			convert->Reset();

327
		timestamp = std::chrono::duration_cast<FloatDuration>(dc.seek_time);
328
		absolute_frame = dc.seek_time.ToScale<uint64_t>(dc.in_audio_format.sample_rate);
329 330 331
	}

	dc.command = DecoderCommand::NONE;
332
	dc.client_cond.notify_one();
333 334 335
}

SongTime
336
DecoderBridge::GetSeekTime() noexcept
337 338 339 340 341 342 343 344 345 346 347 348 349 350
{
	assert(dc.pipe != nullptr);

	if (initial_seek_running)
		return dc.start_time;

	assert(dc.command == DecoderCommand::SEEK);

	seeking = true;

	return dc.seek_time;
}

uint64_t
351
DecoderBridge::GetSeekFrame() noexcept
352 353 354 355 356
{
	return GetSeekTime().ToScale<uint64_t>(dc.in_audio_format.sample_rate);
}

void
357
DecoderBridge::SeekError() noexcept
358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384
{
	assert(dc.pipe != nullptr);

	if (initial_seek_running) {
		/* d'oh, we can't seek to the sub-song start position,
		   what now? - no idea, ignoring the problem for now. */
		initial_seek_running = false;
		return;
	}

	assert(dc.command == DecoderCommand::SEEK);

	dc.seek_error = true;
	seeking = false;

	CommandFinished();
}

InputStreamPtr
DecoderBridge::OpenUri(const char *uri)
{
	assert(dc.state == DecoderState::START ||
	       dc.state == DecoderState::DECODE);

	Mutex &mutex = dc.mutex;
	Cond &cond = dc.cond;

385 386
	auto is = InputStream::Open(uri, mutex);
	is->SetHandler(&dc);
387

388
	std::unique_lock<Mutex> lock(mutex);
389
	while (true) {
390 391 392
		if (dc.command == DecoderCommand::STOP)
			throw StopDecoder();

393
		is->Update();
394 395
		if (is->IsReady()) {
			is->Check();
396
			return is;
397
		}
398

399
		cond.wait(lock);
400 401 402
	}
}

403
size_t
404
DecoderBridge::Read(InputStream &is, void *buffer, size_t length) noexcept
405 406 407 408 409 410 411 412
try {
	assert(buffer != nullptr);
	assert(dc.state == DecoderState::START ||
	       dc.state == DecoderState::DECODE);

	if (length == 0)
		return 0;

413
	std::unique_lock<Mutex> lock(is.mutex);
414 415 416 417 418 419 420 421

	while (true) {
		if (CheckCancelRead())
			return 0;

		if (is.IsAvailable())
			break;

422
		dc.cond.wait(lock);
423 424
	}

425
	size_t nbytes = is.Read(lock, buffer, length);
426 427 428
	assert(nbytes > 0 || is.IsEOF());

	return nbytes;
429
} catch (...) {
430 431 432 433
	error = std::current_exception();
	return 0;
}

434
void
435
DecoderBridge::SubmitTimestamp(FloatDuration t) noexcept
436
{
437
	assert(t.count() >= 0);
438 439

	timestamp = t;
440
	absolute_frame = uint64_t(t.count() * dc.in_audio_format.sample_rate);
441 442 443 444 445
}

DecoderCommand
DecoderBridge::SubmitData(InputStream *is,
			  const void *data, size_t length,
446
			  uint16_t kbit_rate) noexcept
447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463
{
	assert(dc.state == DecoderState::DECODE);
	assert(dc.pipe != nullptr);
	assert(length % dc.in_audio_format.GetFrameSize() == 0);

	DecoderCommand cmd = LockGetVirtualCommand();

	if (cmd == DecoderCommand::STOP || cmd == DecoderCommand::SEEK ||
	    length == 0)
		return cmd;

	assert(!initial_seek_pending);
	assert(!initial_seek_running);

	/* send stream tags */

	if (UpdateStreamTag(is)) {
464
		if (decoder_tag != nullptr)
465
			/* merge with tag from decoder plugin */
466 467 468
			cmd = DoSendTag(*Tag::Merge(*decoder_tag,
						    *stream_tag));
		else
469 470 471 472 473 474 475
			/* send only the stream tag */
			cmd = DoSendTag(*stream_tag);

		if (cmd != DecoderCommand::NONE)
			return cmd;
	}

476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498
	cmd = DecoderCommand::NONE;

	const size_t frame_size = dc.in_audio_format.GetFrameSize();
	size_t data_frames = length / frame_size;

	if (dc.end_time.IsPositive()) {
		/* enforce the given end time */

		const uint64_t end_frame =
			dc.end_time.ToScale<uint64_t>(dc.in_audio_format.sample_rate);
		if (absolute_frame >= end_frame)
			return DecoderCommand::STOP;

		const uint64_t remaining_frames = end_frame - absolute_frame;
		if (data_frames >= remaining_frames) {
			/* past the end of the range: truncate this
			   data submission and stop the decoder */
			data_frames = remaining_frames;
			length = data_frames * frame_size;
			cmd = DecoderCommand::STOP;
		}
	}

499 500 501 502 503 504 505
	if (convert != nullptr) {
		assert(dc.in_audio_format != dc.out_audio_format);

		try {
			auto result = convert->Convert({data, length});
			data = result.data;
			length = result.size;
506
		} catch (...) {
507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527
			/* the PCM conversion has failed - stop
			   playback, since we have no better way to
			   bail out */
			error = std::current_exception();
			return DecoderCommand::STOP;
		}
	} else {
		assert(dc.in_audio_format == dc.out_audio_format);
	}

	while (length > 0) {
		bool full;

		auto *chunk = GetChunk();
		if (chunk == nullptr) {
			assert(dc.command != DecoderCommand::NONE);
			return dc.command;
		}

		const auto dest =
			chunk->Write(dc.out_audio_format,
528
				     SongTime::Cast(timestamp) -
529 530
				     dc.song->GetStartTime(),
				     kbit_rate);
531
		if (dest.empty()) {
532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553
			/* the chunk is full, flush it */
			FlushChunk();
			continue;
		}

		const size_t nbytes = std::min(dest.size, length);

		/* copy the buffer */

		memcpy(dest.data, data, nbytes);

		/* expand the music pipe chunk */

		full = chunk->Expand(dc.out_audio_format, nbytes);
		if (full) {
			/* the chunk is full, flush it */
			FlushChunk();
		}

		data = (const uint8_t *)data + nbytes;
		length -= nbytes;

554
		timestamp += dc.out_audio_format.SizeToTime<FloatDuration>(nbytes);
555 556
	}

557 558 559
	absolute_frame += data_frames;

	return cmd;
560 561 562
}

DecoderCommand
563
DecoderBridge::SubmitTag(InputStream *is, Tag &&tag) noexcept
564 565 566 567 568 569 570 571
{
	DecoderCommand cmd;

	assert(dc.state == DecoderState::DECODE);
	assert(dc.pipe != nullptr);

	/* save the tag */

572
	decoder_tag = std::make_unique<Tag>(std::move(tag));
573 574 575 576 577 578 579 580 581 582 583 584 585 586 587

	/* check for a new stream tag */

	UpdateStreamTag(is);

	/* check if we're seeking */

	if (PrepareInitialSeek())
		/* during initial seek, no music chunk must be created
		   until seeking is finished; skip the rest of the
		   function here */
		return DecoderCommand::SEEK;

	/* send tag to music pipe */

588
	if (stream_tag != nullptr)
589
		/* merge with tag from input stream */
590 591
		cmd = DoSendTag(*Tag::Merge(*stream_tag, *decoder_tag));
	else
592 593 594 595 596 597 598
		/* send only the decoder tag */
		cmd = DoSendTag(*decoder_tag);

	return cmd;
}

void
599
DecoderBridge::SubmitReplayGain(const ReplayGainInfo *new_replay_gain_info) noexcept
600 601 602 603 604 605
{
	if (new_replay_gain_info != nullptr) {
		static unsigned serial;
		if (++serial == 0)
			serial = 1;

606 607
		if (ReplayGainMode::OFF != dc.replay_gain_mode) {
			ReplayGainMode rgm = dc.replay_gain_mode;
608 609
			if (rgm != ReplayGainMode::ALBUM)
				rgm = ReplayGainMode::TRACK;
610

611
			const auto &tuple = new_replay_gain_info->Get(rgm);
612
			const auto scale =
613
				tuple.CalculateScale(dc.replay_gain_config);
614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630
			dc.replay_gain_db = 20.0 * log10f(scale);
		}

		replay_gain_info = *new_replay_gain_info;
		replay_gain_serial = serial;

		if (current_chunk != nullptr) {
			/* flush the current chunk because the new
			   replay gain values affect the following
			   samples */
			FlushChunk();
		}
	} else
		replay_gain_serial = 0;
}

void
631
DecoderBridge::SubmitMixRamp(MixRampInfo &&mix_ramp) noexcept
632 633 634
{
	dc.SetMixRamp(std::move(mix_ramp));
}