output/Internal: move the AudioOutputSource to struct AudioOutputControl
This commit is contained in:
parent
58683f02ec
commit
613dd67784
@ -1370,7 +1370,6 @@ OUTPUT_LIBS = \
|
|||||||
OUTPUT_API_SRC = \
|
OUTPUT_API_SRC = \
|
||||||
src/output/Client.hxx \
|
src/output/Client.hxx \
|
||||||
src/output/OutputAPI.hxx \
|
src/output/OutputAPI.hxx \
|
||||||
src/output/Internal.cxx \
|
|
||||||
src/output/Internal.hxx \
|
src/output/Internal.hxx \
|
||||||
src/output/Wrapper.hxx \
|
src/output/Wrapper.hxx \
|
||||||
src/output/Registry.cxx src/output/Registry.hxx \
|
src/output/Registry.cxx src/output/Registry.hxx \
|
||||||
|
@ -245,15 +245,19 @@ AudioOutputControl::LockUpdate(const AudioFormat audio_format,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
AudioOutputControl::LockIsChunkConsumed(const MusicChunk &chunk) const noexcept
|
AudioOutputControl::IsChunkConsumed(const MusicChunk &chunk) const noexcept
|
||||||
{
|
{
|
||||||
return output->LockIsChunkConsumed(chunk);
|
if (!output->open)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return source.IsChunkConsumed(chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
bool
|
||||||
AudioOutputControl::ClearTailChunk(const MusicChunk &chunk) noexcept
|
AudioOutputControl::LockIsChunkConsumed(const MusicChunk &chunk) const noexcept
|
||||||
{
|
{
|
||||||
output->ClearTailChunk(chunk);
|
const std::lock_guard<Mutex> protect(mutex);
|
||||||
|
return IsChunkConsumed(chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -334,12 +338,6 @@ AudioOutputControl::LockCloseWait() noexcept
|
|||||||
CloseWait();
|
CloseWait();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
AudioOutputControl::SetReplayGainMode(ReplayGainMode _mode) noexcept
|
|
||||||
{
|
|
||||||
return output->SetReplayGainMode(_mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
AudioOutputControl::StopThread() noexcept
|
AudioOutputControl::StopThread() noexcept
|
||||||
{
|
{
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#ifndef MPD_OUTPUT_CONTROL_HXX
|
#ifndef MPD_OUTPUT_CONTROL_HXX
|
||||||
#define MPD_OUTPUT_CONTROL_HXX
|
#define MPD_OUTPUT_CONTROL_HXX
|
||||||
|
|
||||||
|
#include "Source.hxx"
|
||||||
#include "AudioFormat.hxx"
|
#include "AudioFormat.hxx"
|
||||||
#include "thread/Thread.hxx"
|
#include "thread/Thread.hxx"
|
||||||
#include "thread/Cond.hxx"
|
#include "thread/Cond.hxx"
|
||||||
@ -56,6 +57,11 @@ class AudioOutputControl {
|
|||||||
*/
|
*/
|
||||||
AudioOutputClient &client;
|
AudioOutputClient &client;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Source of audio data.
|
||||||
|
*/
|
||||||
|
AudioOutputSource source;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The error that occurred in the output thread. It is
|
* The error that occurred in the output thread. It is
|
||||||
* cleared whenever the output is opened successfully.
|
* cleared whenever the output is opened successfully.
|
||||||
@ -327,7 +333,9 @@ public:
|
|||||||
*/
|
*/
|
||||||
void LockRelease() noexcept;
|
void LockRelease() noexcept;
|
||||||
|
|
||||||
void SetReplayGainMode(ReplayGainMode _mode) noexcept;
|
void SetReplayGainMode(ReplayGainMode _mode) noexcept {
|
||||||
|
source.SetReplayGainMode(_mode);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Caller must lock the mutex.
|
* Caller must lock the mutex.
|
||||||
@ -345,10 +353,20 @@ public:
|
|||||||
const MusicPipe &mp,
|
const MusicPipe &mp,
|
||||||
bool force) noexcept;
|
bool force) noexcept;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Did we already consumed this chunk?
|
||||||
|
*
|
||||||
|
* Caller must lock the mutex.
|
||||||
|
*/
|
||||||
|
gcc_pure
|
||||||
|
bool IsChunkConsumed(const MusicChunk &chunk) const noexcept;
|
||||||
|
|
||||||
gcc_pure
|
gcc_pure
|
||||||
bool LockIsChunkConsumed(const MusicChunk &chunk) const noexcept;
|
bool LockIsChunkConsumed(const MusicChunk &chunk) const noexcept;
|
||||||
|
|
||||||
void ClearTailChunk(const MusicChunk &chunk) noexcept;
|
void ClearTailChunk(const MusicChunk &chunk) {
|
||||||
|
source.ClearTailChunk(chunk);
|
||||||
|
}
|
||||||
|
|
||||||
void LockPlay() noexcept;
|
void LockPlay() noexcept;
|
||||||
void LockDrainAsync() noexcept;
|
void LockDrainAsync() noexcept;
|
||||||
|
@ -1,30 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2003-2017 The Music Player Daemon Project
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
#include "Internal.hxx"
|
|
||||||
|
|
||||||
bool
|
|
||||||
AudioOutput::IsChunkConsumed(const MusicChunk &chunk) const noexcept
|
|
||||||
{
|
|
||||||
if (!open)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return source.IsChunkConsumed(chunk);
|
|
||||||
}
|
|
@ -20,7 +20,6 @@
|
|||||||
#ifndef MPD_OUTPUT_INTERNAL_HXX
|
#ifndef MPD_OUTPUT_INTERNAL_HXX
|
||||||
#define MPD_OUTPUT_INTERNAL_HXX
|
#define MPD_OUTPUT_INTERNAL_HXX
|
||||||
|
|
||||||
#include "Source.hxx"
|
|
||||||
#include "AudioFormat.hxx"
|
#include "AudioFormat.hxx"
|
||||||
#include "filter/Observer.hxx"
|
#include "filter/Observer.hxx"
|
||||||
#include "thread/Mutex.hxx"
|
#include "thread/Mutex.hxx"
|
||||||
@ -122,11 +121,6 @@ struct AudioOutput {
|
|||||||
*/
|
*/
|
||||||
mutable Mutex mutex;
|
mutable Mutex mutex;
|
||||||
|
|
||||||
/**
|
|
||||||
* Source of audio data.
|
|
||||||
*/
|
|
||||||
AudioOutputSource source;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Throws #std::runtime_error on error.
|
* Throws #std::runtime_error on error.
|
||||||
*/
|
*/
|
||||||
@ -158,28 +152,6 @@ public:
|
|||||||
return open;
|
return open;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetReplayGainMode(ReplayGainMode _mode) noexcept {
|
|
||||||
source.SetReplayGainMode(_mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Did we already consumed this chunk?
|
|
||||||
*
|
|
||||||
* Caller must lock the mutex.
|
|
||||||
*/
|
|
||||||
gcc_pure
|
|
||||||
bool IsChunkConsumed(const MusicChunk &chunk) const noexcept;
|
|
||||||
|
|
||||||
gcc_pure
|
|
||||||
bool LockIsChunkConsumed(const MusicChunk &chunk) noexcept {
|
|
||||||
const std::lock_guard<Mutex> protect(mutex);
|
|
||||||
return IsChunkConsumed(chunk);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClearTailChunk(const MusicChunk &chunk) {
|
|
||||||
source.ClearTailChunk(chunk);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Throws #std::runtime_error on error.
|
* Throws #std::runtime_error on error.
|
||||||
*/
|
*/
|
||||||
|
@ -217,7 +217,6 @@ AudioOutputControl::InternalOpen(const AudioFormat in_audio_format,
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
try {
|
try {
|
||||||
auto &source = output->source;
|
|
||||||
f = source.Open(in_audio_format, pipe,
|
f = source.Open(in_audio_format, pipe,
|
||||||
output->prepared_replay_gain_filter,
|
output->prepared_replay_gain_filter,
|
||||||
output->prepared_other_replay_gain_filter,
|
output->prepared_other_replay_gain_filter,
|
||||||
@ -230,7 +229,7 @@ AudioOutputControl::InternalOpen(const AudioFormat in_audio_format,
|
|||||||
try {
|
try {
|
||||||
output->Open(f);
|
output->Open(f);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
output->source.Close();
|
source.Close();
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
} catch (const std::runtime_error &e) {
|
} catch (const std::runtime_error &e) {
|
||||||
@ -253,7 +252,7 @@ AudioOutputControl::InternalClose(bool drain) noexcept
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
output->Close(drain);
|
output->Close(drain);
|
||||||
output->source.Close();
|
source.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -307,7 +306,7 @@ AudioOutputControl::WaitForDelay() noexcept
|
|||||||
bool
|
bool
|
||||||
AudioOutputControl::FillSourceOrClose()
|
AudioOutputControl::FillSourceOrClose()
|
||||||
try {
|
try {
|
||||||
return output->source.Fill(mutex);
|
return source.Fill(mutex);
|
||||||
} catch (const std::runtime_error &e) {
|
} catch (const std::runtime_error &e) {
|
||||||
FormatError(e, "Failed to filter for output \"%s\" [%s]",
|
FormatError(e, "Failed to filter for output \"%s\" [%s]",
|
||||||
GetName(), output->plugin.name);
|
GetName(), output->plugin.name);
|
||||||
@ -324,7 +323,7 @@ inline bool
|
|||||||
AudioOutputControl::PlayChunk() noexcept
|
AudioOutputControl::PlayChunk() noexcept
|
||||||
{
|
{
|
||||||
if (tags) {
|
if (tags) {
|
||||||
const auto *tag = output->source.ReadTag();
|
const auto *tag = source.ReadTag();
|
||||||
if (tag != nullptr) {
|
if (tag != nullptr) {
|
||||||
const ScopeUnlock unlock(mutex);
|
const ScopeUnlock unlock(mutex);
|
||||||
try {
|
try {
|
||||||
@ -337,7 +336,7 @@ AudioOutputControl::PlayChunk() noexcept
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (command == Command::NONE) {
|
while (command == Command::NONE) {
|
||||||
const auto data = output->source.PeekData();
|
const auto data = source.PeekData();
|
||||||
if (data.IsEmpty())
|
if (data.IsEmpty())
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -372,7 +371,7 @@ AudioOutputControl::PlayChunk() noexcept
|
|||||||
|
|
||||||
assert(nbytes % output->out_audio_format.GetFrameSize() == 0);
|
assert(nbytes % output->out_audio_format.GetFrameSize() == 0);
|
||||||
|
|
||||||
output->source.ConsumeData(nbytes);
|
source.ConsumeData(nbytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -457,8 +456,10 @@ AudioOutputControl::InternalPause() noexcept
|
|||||||
if (!WaitForDelay())
|
if (!WaitForDelay())
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (!output->IteratePause())
|
if (!output->IteratePause()) {
|
||||||
|
source.Close();
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
} while (command == Command::NONE);
|
} while (command == Command::NONE);
|
||||||
|
|
||||||
pause = false;
|
pause = false;
|
||||||
@ -535,7 +536,7 @@ AudioOutputControl::Task()
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
case Command::CANCEL:
|
case Command::CANCEL:
|
||||||
output->source.Cancel();
|
source.Cancel();
|
||||||
|
|
||||||
if (output->open) {
|
if (output->open) {
|
||||||
const ScopeUnlock unlock(mutex);
|
const ScopeUnlock unlock(mutex);
|
||||||
@ -547,7 +548,7 @@ AudioOutputControl::Task()
|
|||||||
|
|
||||||
case Command::KILL:
|
case Command::KILL:
|
||||||
InternalDisable();
|
InternalDisable();
|
||||||
output->source.Cancel();
|
source.Cancel();
|
||||||
CommandFinished();
|
CommandFinished();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
|
||||||
struct ConfigBlock;
|
struct ConfigBlock;
|
||||||
|
struct Tag;
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
struct AudioOutputWrapper {
|
struct AudioOutputWrapper {
|
||||||
|
Loading…
Reference in New Issue
Block a user