Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
M
mpd
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Иван Мажукин
mpd
Commits
c40354bb
Commit
c40354bb
authored
Dec 29, 2017
by
Max Kellermann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
player/Outputs: abstract interface wrapping class MultipleOutputs
parent
c04aafb4
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
148 additions
and
90 deletions
+148
-90
Makefile.am
Makefile.am
+1
-0
MultipleOutputs.cxx
src/output/MultipleOutputs.cxx
+1
-1
MultipleOutputs.hxx
src/output/MultipleOutputs.hxx
+18
-78
Control.cxx
src/player/Control.cxx
+4
-4
Control.hxx
src/player/Control.hxx
+3
-3
Outputs.hxx
src/player/Outputs.hxx
+117
-0
Thread.cxx
src/player/Thread.cxx
+4
-4
No files found.
Makefile.am
View file @
c40354bb
...
...
@@ -143,6 +143,7 @@ libmpd_a_SOURCES = \
src/player/Thread.cxx src/player/Thread.hxx
\
src/player/Control.cxx src/player/Control.hxx
\
src/player/Listener.hxx
\
src/player/Outputs.hxx
\
src/PlaylistError.cxx src/PlaylistError.hxx
\
src/PlaylistPrint.cxx src/PlaylistPrint.hxx
\
src/PlaylistSave.cxx src/PlaylistSave.hxx
\
...
...
src/output/MultipleOutputs.cxx
View file @
c40354bb
...
...
@@ -315,7 +315,7 @@ MultipleOutputs::ClearTailChunk(const MusicChunk *chunk,
}
unsigned
MultipleOutputs
::
Check
()
noexcept
MultipleOutputs
::
Check
Pipe
()
noexcept
{
const
MusicChunk
*
chunk
;
bool
is_tail
;
...
...
src/output/MultipleOutputs.hxx
View file @
c40354bb
...
...
@@ -27,6 +27,7 @@
#define OUTPUT_ALL_H
#include "Control.hxx"
#include "player/Outputs.hxx"
#include "AudioFormat.hxx"
#include "ReplayGainMode.hxx"
#include "Chrono.hxx"
...
...
@@ -44,7 +45,7 @@ class AudioOutputClient;
struct
MusicChunk
;
struct
ReplayGainConfig
;
class
MultipleOutputs
{
class
MultipleOutputs
final
:
public
PlayerOutputs
{
MixerListener
&
mixer_listener
;
std
::
vector
<
AudioOutputControl
*>
outputs
;
...
...
@@ -115,86 +116,9 @@ public:
gcc_pure
AudioOutputControl
*
FindByName
(
const
char
*
name
)
noexcept
;
/**
* Checks the "enabled" flag of all audio outputs, and if one has
* changed, commit the change.
*/
void
EnableDisable
();
/**
* Opens all audio outputs which are not disabled.
*
* Throws #std::runtime_error on error.
*
* @param audio_format the preferred audio format
* @param _buffer the #music_buffer where consumed #MusicChunk objects
* should be returned
*/
void
Open
(
const
AudioFormat
audio_format
,
MusicBuffer
&
_buffer
);
/**
* Closes all audio outputs.
*/
void
Close
()
noexcept
;
/**
* Closes all audio outputs. Outputs with the "always_on"
* flag are put into pause mode.
*/
void
Release
()
noexcept
;
void
SetReplayGainMode
(
ReplayGainMode
mode
)
noexcept
;
/**
* Enqueue a #MusicChunk object for playing, i.e. pushes it to a
* #MusicPipe.
*
* Throws #std::runtime_error on error (all closed then).
*
* @param chunk the #MusicChunk object to be played
*/
void
Play
(
MusicChunk
*
chunk
);
/**
* Checks if the output devices have drained their music pipe, and
* returns the consumed music chunks to the #music_buffer.
*
* @return the number of chunks to play left in the #MusicPipe
*/
unsigned
Check
()
noexcept
;
/**
* Puts all audio outputs into pause mode. Most implementations will
* simply close it then.
*/
void
Pause
()
noexcept
;
/**
* Drain all audio outputs.
*/
void
Drain
()
noexcept
;
/**
* Try to cancel data which may still be in the device's buffers.
*/
void
Cancel
()
noexcept
;
/**
* Indicate that a new song will begin now.
*/
void
SongBorder
()
noexcept
;
/**
* Returns the "elapsed_time" stamp of the most recently finished
* chunk. A negative value is returned when no chunk has been
* finished yet.
*/
gcc_pure
SignedSongTime
GetElapsedTime
()
const
noexcept
{
return
elapsed_time
;
}
/**
* Returns the average volume of all available mixers (range
* 0..100). Returns -1 if no mixer can be queried.
*/
...
...
@@ -259,6 +183,22 @@ private:
* reference.
*/
void
ClearTailChunk
(
const
MusicChunk
*
chunk
,
bool
*
locked
)
noexcept
;
/* virtual methods from class PlayerOutputs */
void
EnableDisable
()
override
;
void
Open
(
const
AudioFormat
audio_format
,
MusicBuffer
&
_buffer
)
override
;
void
Close
()
noexcept
override
;
void
Release
()
noexcept
override
;
void
Play
(
MusicChunk
*
chunk
)
override
;
unsigned
CheckPipe
()
noexcept
override
;
void
Pause
()
noexcept
override
;
void
Drain
()
noexcept
override
;
void
Cancel
()
noexcept
override
;
void
SongBorder
()
noexcept
override
;
SignedSongTime
GetElapsedTime
()
const
noexcept
override
{
return
elapsed_time
;
}
};
#endif
src/player/Control.cxx
View file @
c40354bb
...
...
@@ -19,16 +19,16 @@
#include "config.h"
#include "Control.hxx"
#include "Outputs.hxx"
#include "Idle.hxx"
#include "DetachedSong.hxx"
#include "output/MultipleOutputs.hxx"
#include <algorithm>
#include <assert.h>
PlayerControl
::
PlayerControl
(
PlayerListener
&
_listener
,
Multiple
Outputs
&
_outputs
,
Player
Outputs
&
_outputs
,
unsigned
_buffer_chunks
,
unsigned
_buffered_before_play
,
AudioFormat
_configured_audio_format
,
...
...
@@ -50,10 +50,10 @@ PlayerControl::~PlayerControl() noexcept
bool
PlayerControl
::
WaitOutputConsumed
(
unsigned
threshold
)
noexcept
{
bool
result
=
outputs
.
Check
()
<
threshold
;
bool
result
=
outputs
.
Check
Pipe
()
<
threshold
;
if
(
!
result
&&
command
==
PlayerCommand
::
NONE
)
{
Wait
();
result
=
outputs
.
Check
()
<
threshold
;
result
=
outputs
.
Check
Pipe
()
<
threshold
;
}
return
result
;
...
...
src/player/Control.hxx
View file @
c40354bb
...
...
@@ -36,7 +36,7 @@
#include <stdint.h>
class
PlayerListener
;
class
Multiple
Outputs
;
class
Player
Outputs
;
class
DetachedSong
;
enum
class
PlayerState
:
uint8_t
{
...
...
@@ -108,7 +108,7 @@ struct player_status {
struct
PlayerControl
final
:
AudioOutputClient
{
PlayerListener
&
listener
;
Multiple
Outputs
&
outputs
;
Player
Outputs
&
outputs
;
const
unsigned
buffer_chunks
;
...
...
@@ -223,7 +223,7 @@ struct PlayerControl final : AudioOutputClient {
double
total_play_time
=
0
;
PlayerControl
(
PlayerListener
&
_listener
,
Multiple
Outputs
&
_outputs
,
Player
Outputs
&
_outputs
,
unsigned
buffer_chunks
,
unsigned
buffered_before_play
,
AudioFormat
_configured_audio_format
,
...
...
src/player/Outputs.hxx
0 → 100644
View file @
c40354bb
/*
* 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.
*/
#ifndef MPD_PLAYER_OUTPUT_INTERFACE_HXX
#define MPD_PLAYER_OUTPUT_INTERFACE_HXX
#include "Chrono.hxx"
#include "Compiler.h"
struct
AudioFormat
;
struct
MusicChunk
;
class
MusicBuffer
;
/**
* An interface for the player thread to control all outputs. This
* interface is implemented only by #MultipleOutputs, and exists only
* to decouple the player code from the output code, to be able to
* unit-test the player code.
*/
class
PlayerOutputs
{
public
:
/**
* Checks the "enabled" flag of all audio outputs, and if one has
* changed, commit the change.
*
* Throws on error.
*/
virtual
void
EnableDisable
()
=
0
;
/**
* Opens all audio outputs which are not disabled.
*
* Throws on error.
*
* @param audio_format the preferred audio format
* @param buffer the #MusicBuffer where consumed #MusicChunk
* objects should be returned
*/
virtual
void
Open
(
const
AudioFormat
audio_format
,
MusicBuffer
&
buffer
)
=
0
;
/**
* Closes all audio outputs.
*/
virtual
void
Close
()
noexcept
=
0
;
/**
* Closes all audio outputs. Outputs with the "always_on"
* flag are put into pause mode.
*/
virtual
void
Release
()
noexcept
=
0
;
/**
* Enqueue a #MusicChunk object for playing, i.e. pushes it to a
* #MusicPipe.
*
* Throws on error (all closed then).
*
* @param chunk the #MusicChunk object to be played
*/
virtual
void
Play
(
MusicChunk
*
chunk
)
=
0
;
/**
* Checks if the output devices have drained their music pipe, and
* returns the consumed music chunks to the #music_buffer.
*
* @return the number of chunks to play left in the #MusicPipe
*/
virtual
unsigned
CheckPipe
()
noexcept
=
0
;
/**
* Puts all audio outputs into pause mode. Most implementations will
* simply close it then.
*/
virtual
void
Pause
()
noexcept
=
0
;
/**
* Drain all audio outputs.
*/
virtual
void
Drain
()
noexcept
=
0
;
/**
* Try to cancel data which may still be in the device's buffers.
*/
virtual
void
Cancel
()
noexcept
=
0
;
/**
* Indicate that a new song will begin now.
*/
virtual
void
SongBorder
()
noexcept
=
0
;
/**
* Returns the "elapsed_time" stamp of the most recently finished
* chunk. A negative value is returned when no chunk has been
* finished yet.
*/
gcc_pure
virtual
SignedSongTime
GetElapsedTime
()
const
noexcept
=
0
;
};
#endif
src/player/Thread.cxx
View file @
c40354bb
...
...
@@ -19,6 +19,7 @@
#include "config.h"
#include "Thread.hxx"
#include "Outputs.hxx"
#include "Listener.hxx"
#include "decoder/DecoderThread.hxx"
#include "decoder/DecoderControl.hxx"
...
...
@@ -29,7 +30,6 @@
#include "DetachedSong.hxx"
#include "CrossFade.hxx"
#include "Control.hxx"
#include "output/MultipleOutputs.hxx"
#include "tag/Tag.hxx"
#include "Idle.hxx"
#include "system/PeriodClock.hxx"
...
...
@@ -334,7 +334,7 @@ private:
unsigned
UnlockCheckOutputs
()
noexcept
{
const
ScopeUnlock
unlock
(
pc
.
mutex
);
return
pc
.
outputs
.
Check
();
return
pc
.
outputs
.
Check
Pipe
();
}
/**
...
...
@@ -750,7 +750,7 @@ Player::ProcessCommand() noexcept
case
PlayerCommand
:
:
REFRESH
:
if
(
output_open
&&
!
paused
)
{
const
ScopeUnlock
unlock
(
pc
.
mutex
);
pc
.
outputs
.
Check
();
pc
.
outputs
.
Check
Pipe
();
}
pc
.
elapsed_time
=
!
pc
.
outputs
.
GetElapsedTime
().
IsNegative
()
...
...
@@ -1004,7 +1004,7 @@ Player::Run() noexcept
{
const
ScopeUnlock
unlock
(
pc
.
mutex
);
if
(
!
paused
&&
output_open
&&
pc
.
outputs
.
Check
()
<
4
&&
pc
.
outputs
.
Check
Pipe
()
<
4
&&
!
SendSilence
())
break
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment