output/Multiple: make chunk_is_consumed_in() an AudioOutput method

This commit is contained in:
Max Kellermann 2016-12-11 21:59:28 +01:00
parent 57dd344f3b
commit dc05dd7ca1
4 changed files with 62 additions and 30 deletions

View File

@ -1328,6 +1328,7 @@ OUTPUT_LIBS = \
OUTPUT_API_SRC = \
src/output/OutputAPI.hxx \
src/output/Internal.cxx \
src/output/Internal.hxx \
src/output/Wrapper.hxx \
src/output/Registry.cxx src/output/Registry.hxx \

45
src/output/Internal.cxx Normal file
View File

@ -0,0 +1,45 @@
/*
* Copyright 2003-2016 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"
#include "MusicPipe.hxx"
#include "MusicChunk.hxx"
#include <assert.h>
bool
AudioOutput::IsChunkConsumed(const MusicChunk &chunk) const
{
if (!open)
return true;
if (current_chunk == nullptr)
return false;
assert(&chunk == current_chunk ||
pipe->Contains(current_chunk));
if (&chunk != current_chunk) {
assert(chunk.next != nullptr);
return true;
}
return current_chunk_finished && chunk.next == nullptr;
}

View File

@ -394,6 +394,20 @@ public:
*/
void LockAllowPlay();
/**
* Did we already consumed this chunk?
*
* Caller must lock the mutex.
*/
gcc_pure
bool IsChunkConsumed(const MusicChunk &chunk) const;
gcc_pure
bool LockIsChunkConsumed(const MusicChunk &chunk) {
const ScopeLock protect(mutex);
return IsChunkConsumed(chunk);
}
private:
void CommandFinished();

View File

@ -251,40 +251,12 @@ MultipleOutputs::Open(const AudioFormat audio_format,
}
}
/**
* Has the specified audio output already consumed this chunk?
*/
gcc_pure
static bool
chunk_is_consumed_in(const AudioOutput *ao,
gcc_unused const MusicPipe *pipe,
const MusicChunk *chunk)
{
if (!ao->open)
return true;
if (ao->current_chunk == nullptr)
return false;
assert(chunk == ao->current_chunk ||
pipe->Contains(ao->current_chunk));
if (chunk != ao->current_chunk) {
assert(chunk->next != nullptr);
return true;
}
return ao->current_chunk_finished && chunk->next == nullptr;
}
bool
MultipleOutputs::IsChunkConsumed(const MusicChunk *chunk) const
{
for (auto ao : outputs) {
const ScopeLock protect(ao->mutex);
if (!chunk_is_consumed_in(ao, pipe, chunk))
for (auto ao : outputs)
if (!ao->LockIsChunkConsumed(*chunk))
return false;
}
return true;
}