output/Internal: move the AudioOutputSource to struct AudioOutputControl

This commit is contained in:
Max Kellermann 2017-05-23 00:03:06 +02:00
parent 58683f02ec
commit 613dd67784
7 changed files with 41 additions and 82 deletions

View File

@ -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 \

View File

@ -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
{ {

View File

@ -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;

View File

@ -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);
}

View File

@ -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.
*/ */

View File

@ -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;
} }

View File

@ -26,6 +26,7 @@
#include <chrono> #include <chrono>
struct ConfigBlock; struct ConfigBlock;
struct Tag;
template<class T> template<class T>
struct AudioOutputWrapper { struct AudioOutputWrapper {