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
697c3f8c
Commit
697c3f8c
authored
Nov 18, 2016
by
Max Kellermann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
decoder/Internal: rename struct Decoder to class DecoderBridge
parent
bb292f50
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
136 additions
and
134 deletions
+136
-134
Makefile.am
Makefile.am
+1
-1
Bridge.cxx
src/decoder/Bridge.cxx
+4
-4
Bridge.hxx
src/decoder/Bridge.hxx
+11
-5
DecoderAPI.cxx
src/decoder/DecoderAPI.cxx
+60
-66
DecoderThread.cxx
src/decoder/DecoderThread.cxx
+60
-58
No files found.
Makefile.am
View file @
697c3f8c
...
@@ -102,7 +102,7 @@ libmpd_a_SOURCES = \
...
@@ -102,7 +102,7 @@ libmpd_a_SOURCES = \
src/decoder/DecoderAPI.cxx src/decoder/DecoderAPI.hxx
\
src/decoder/DecoderAPI.cxx src/decoder/DecoderAPI.hxx
\
src/decoder/Client.hxx
\
src/decoder/Client.hxx
\
src/decoder/DecoderPlugin.hxx
\
src/decoder/DecoderPlugin.hxx
\
src/decoder/
DecoderInternal.cxx src/decoder/DecoderInternal
.hxx
\
src/decoder/
Bridge.cxx src/decoder/Bridge
.hxx
\
src/decoder/DecoderPrint.cxx src/decoder/DecoderPrint.hxx
\
src/decoder/DecoderPrint.cxx src/decoder/DecoderPrint.hxx
\
src/filter/FilterConfig.cxx src/filter/FilterConfig.hxx
\
src/filter/FilterConfig.cxx src/filter/FilterConfig.hxx
\
src/filter/FilterPlugin.cxx src/filter/FilterPlugin.hxx
\
src/filter/FilterPlugin.cxx src/filter/FilterPlugin.hxx
\
...
...
src/decoder/
DecoderInternal
.cxx
→
src/decoder/
Bridge
.cxx
View file @
697c3f8c
...
@@ -18,7 +18,7 @@
...
@@ -18,7 +18,7 @@
*/
*/
#include "config.h"
#include "config.h"
#include "
DecoderInternal
.hxx"
#include "
Bridge
.hxx"
#include "DecoderControl.hxx"
#include "DecoderControl.hxx"
#include "pcm/PcmConvert.hxx"
#include "pcm/PcmConvert.hxx"
#include "MusicPipe.hxx"
#include "MusicPipe.hxx"
...
@@ -28,7 +28,7 @@
...
@@ -28,7 +28,7 @@
#include <assert.h>
#include <assert.h>
Decoder
::~
Decoder
()
Decoder
Bridge
::~
DecoderBridge
()
{
{
/* caller must flush the chunk */
/* caller must flush the chunk */
assert
(
current_chunk
==
nullptr
);
assert
(
current_chunk
==
nullptr
);
...
@@ -64,7 +64,7 @@ LockNeedChunks(DecoderControl &dc)
...
@@ -64,7 +64,7 @@ LockNeedChunks(DecoderControl &dc)
}
}
MusicChunk
*
MusicChunk
*
Decoder
::
GetChunk
()
Decoder
Bridge
::
GetChunk
()
{
{
DecoderCommand
cmd
;
DecoderCommand
cmd
;
...
@@ -88,7 +88,7 @@ Decoder::GetChunk()
...
@@ -88,7 +88,7 @@ Decoder::GetChunk()
}
}
void
void
Decoder
::
FlushChunk
()
Decoder
Bridge
::
FlushChunk
()
{
{
assert
(
!
seeking
);
assert
(
!
seeking
);
assert
(
!
initial_seek_running
);
assert
(
!
initial_seek_running
);
...
...
src/decoder/
DecoderInternal
.hxx
→
src/decoder/
Bridge
.hxx
View file @
697c3f8c
...
@@ -17,8 +17,8 @@
...
@@ -17,8 +17,8 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
*/
#ifndef MPD_DECODER_
INTERNAL
_HXX
#ifndef MPD_DECODER_
BRIDGE
_HXX
#define MPD_DECODER_
INTERNAL
_HXX
#define MPD_DECODER_
BRIDGE
_HXX
#include "Client.hxx"
#include "Client.hxx"
#include "ReplayGainInfo.hxx"
#include "ReplayGainInfo.hxx"
...
@@ -30,7 +30,12 @@ struct MusicChunk;
...
@@ -30,7 +30,12 @@ struct MusicChunk;
struct
DecoderControl
;
struct
DecoderControl
;
struct
Tag
;
struct
Tag
;
struct
Decoder
final
:
DecoderClient
{
/**
* A bridge between the #DecoderClient interface and the MPD core
* (#DecoderControl, #MusicPipe etc.).
*/
class
DecoderBridge
final
:
public
DecoderClient
{
public
:
DecoderControl
&
dc
;
DecoderControl
&
dc
;
/**
/**
...
@@ -94,12 +99,13 @@ struct Decoder final : DecoderClient {
...
@@ -94,12 +99,13 @@ struct Decoder final : DecoderClient {
*/
*/
std
::
exception_ptr
error
;
std
::
exception_ptr
error
;
Decoder
(
DecoderControl
&
_dc
,
bool
_initial_seek_pending
,
Tag
*
_tag
)
DecoderBridge
(
DecoderControl
&
_dc
,
bool
_initial_seek_pending
,
Tag
*
_tag
)
:
dc
(
_dc
),
:
dc
(
_dc
),
initial_seek_pending
(
_initial_seek_pending
),
initial_seek_pending
(
_initial_seek_pending
),
song_tag
(
_tag
)
{}
song_tag
(
_tag
)
{}
~
Decoder
();
~
Decoder
Bridge
();
/**
/**
* Returns the current chunk the decoder writes to, or allocates a new
* Returns the current chunk the decoder writes to, or allocates a new
...
...
src/decoder/DecoderAPI.cxx
View file @
697c3f8c
...
@@ -27,7 +27,7 @@
...
@@ -27,7 +27,7 @@
#include "MusicBuffer.hxx"
#include "MusicBuffer.hxx"
#include "MusicPipe.hxx"
#include "MusicPipe.hxx"
#include "DecoderControl.hxx"
#include "DecoderControl.hxx"
#include "
DecoderInternal
.hxx"
#include "
Bridge
.hxx"
#include "DetachedSong.hxx"
#include "DetachedSong.hxx"
#include "input/InputStream.hxx"
#include "input/InputStream.hxx"
#include "util/ConstBuffer.hxx"
#include "util/ConstBuffer.hxx"
...
@@ -38,8 +38,8 @@
...
@@ -38,8 +38,8 @@
#include <math.h>
#include <math.h>
void
void
Decoder
::
Ready
(
const
AudioFormat
audio_format
,
Decoder
Bridge
::
Ready
(
const
AudioFormat
audio_format
,
bool
seekable
,
SignedSongTime
duration
)
bool
seekable
,
SignedSongTime
duration
)
{
{
struct
audio_format_string
af_string
;
struct
audio_format_string
af_string
;
...
@@ -89,10 +89,9 @@ Decoder::Ready(const AudioFormat audio_format,
...
@@ -89,10 +89,9 @@ Decoder::Ready(const AudioFormat audio_format,
*/
*/
gcc_pure
gcc_pure
static
bool
static
bool
decoder_prepare_initial_seek
(
Decoder
Client
&
client
)
decoder_prepare_initial_seek
(
Decoder
Bridge
&
bridge
)
{
{
auto
&
decoder
=
(
Decoder
&
)
client
;
const
DecoderControl
&
dc
=
bridge
.
dc
;
const
DecoderControl
&
dc
=
decoder
.
dc
;
assert
(
dc
.
pipe
!=
nullptr
);
assert
(
dc
.
pipe
!=
nullptr
);
if
(
dc
.
state
!=
DecoderState
::
DECODE
)
if
(
dc
.
state
!=
DecoderState
::
DECODE
)
...
@@ -101,30 +100,30 @@ decoder_prepare_initial_seek(DecoderClient &client)
...
@@ -101,30 +100,30 @@ decoder_prepare_initial_seek(DecoderClient &client)
virtual "SEEK" command */
virtual "SEEK" command */
return
false
;
return
false
;
if
(
decoder
.
initial_seek_running
)
if
(
bridge
.
initial_seek_running
)
/* initial seek has already begun - override any other
/* initial seek has already begun - override any other
command */
command */
return
true
;
return
true
;
if
(
decoder
.
initial_seek_pending
)
{
if
(
bridge
.
initial_seek_pending
)
{
if
(
!
dc
.
seekable
)
{
if
(
!
dc
.
seekable
)
{
/* seeking is not possible */
/* seeking is not possible */
decoder
.
initial_seek_pending
=
false
;
bridge
.
initial_seek_pending
=
false
;
return
false
;
return
false
;
}
}
if
(
dc
.
command
==
DecoderCommand
::
NONE
)
{
if
(
dc
.
command
==
DecoderCommand
::
NONE
)
{
/* begin initial seek */
/* begin initial seek */
decoder
.
initial_seek_pending
=
false
;
bridge
.
initial_seek_pending
=
false
;
decoder
.
initial_seek_running
=
true
;
bridge
.
initial_seek_running
=
true
;
return
true
;
return
true
;
}
}
/* skip initial seek when there's another command
/* skip initial seek when there's another command
(e.g. STOP) */
(e.g. STOP) */
decoder
.
initial_seek_pending
=
false
;
bridge
.
initial_seek_pending
=
false
;
}
}
return
false
;
return
false
;
...
@@ -137,18 +136,16 @@ decoder_prepare_initial_seek(DecoderClient &client)
...
@@ -137,18 +136,16 @@ decoder_prepare_initial_seek(DecoderClient &client)
*/
*/
gcc_pure
gcc_pure
static
DecoderCommand
static
DecoderCommand
decoder_get_virtual_command
(
Decoder
Client
&
client
)
decoder_get_virtual_command
(
Decoder
Bridge
&
bridge
)
{
{
auto
&
decoder
=
(
Decoder
&
)
client
;
if
(
bridge
.
error
)
if
(
decoder
.
error
)
/* an error has occurred: stop the decoder plugin */
/* an error has occurred: stop the decoder plugin */
return
DecoderCommand
::
STOP
;
return
DecoderCommand
::
STOP
;
const
DecoderControl
&
dc
=
decoder
.
dc
;
const
DecoderControl
&
dc
=
bridge
.
dc
;
assert
(
dc
.
pipe
!=
nullptr
);
assert
(
dc
.
pipe
!=
nullptr
);
if
(
decoder_prepare_initial_seek
(
decoder
))
if
(
decoder_prepare_initial_seek
(
bridge
))
return
DecoderCommand
::
SEEK
;
return
DecoderCommand
::
SEEK
;
return
dc
.
command
;
return
dc
.
command
;
...
@@ -156,21 +153,20 @@ decoder_get_virtual_command(DecoderClient &client)
...
@@ -156,21 +153,20 @@ decoder_get_virtual_command(DecoderClient &client)
gcc_pure
gcc_pure
static
DecoderCommand
static
DecoderCommand
decoder_lock_get_virtual_command
(
Decoder
Client
&
client
)
decoder_lock_get_virtual_command
(
Decoder
Bridge
&
bridge
)
{
{
auto
&
decoder
=
(
Decoder
&
)
client
;
const
ScopeLock
protect
(
bridge
.
dc
.
mutex
);
const
ScopeLock
protect
(
decoder
.
dc
.
mutex
);
return
decoder_get_virtual_command
(
bridge
);
return
decoder_get_virtual_command
(
decoder
);
}
}
DecoderCommand
DecoderCommand
Decoder
::
GetCommand
()
Decoder
Bridge
::
GetCommand
()
{
{
return
decoder_lock_get_virtual_command
(
*
this
);
return
decoder_lock_get_virtual_command
(
*
this
);
}
}
void
void
Decoder
::
CommandFinished
()
Decoder
Bridge
::
CommandFinished
()
{
{
const
ScopeLock
protect
(
dc
.
mutex
);
const
ScopeLock
protect
(
dc
.
mutex
);
...
@@ -210,7 +206,7 @@ Decoder::CommandFinished()
...
@@ -210,7 +206,7 @@ Decoder::CommandFinished()
}
}
SongTime
SongTime
Decoder
::
GetSeekTime
()
Decoder
Bridge
::
GetSeekTime
()
{
{
assert
(
dc
.
pipe
!=
nullptr
);
assert
(
dc
.
pipe
!=
nullptr
);
...
@@ -225,13 +221,13 @@ Decoder::GetSeekTime()
...
@@ -225,13 +221,13 @@ Decoder::GetSeekTime()
}
}
uint64_t
uint64_t
Decoder
::
GetSeekFrame
()
Decoder
Bridge
::
GetSeekFrame
()
{
{
return
GetSeekTime
().
ToScale
<
uint64_t
>
(
dc
.
in_audio_format
.
sample_rate
);
return
GetSeekTime
().
ToScale
<
uint64_t
>
(
dc
.
in_audio_format
.
sample_rate
);
}
}
void
void
Decoder
::
SeekError
()
Decoder
Bridge
::
SeekError
()
{
{
assert
(
dc
.
pipe
!=
nullptr
);
assert
(
dc
.
pipe
!=
nullptr
);
...
@@ -251,7 +247,7 @@ Decoder::SeekError()
...
@@ -251,7 +247,7 @@ Decoder::SeekError()
}
}
InputStreamPtr
InputStreamPtr
Decoder
::
OpenUri
(
const
char
*
uri
)
Decoder
Bridge
::
OpenUri
(
const
char
*
uri
)
{
{
assert
(
dc
.
state
==
DecoderState
::
START
||
assert
(
dc
.
state
==
DecoderState
::
START
||
dc
.
state
==
DecoderState
::
DECODE
);
dc
.
state
==
DecoderState
::
DECODE
);
...
@@ -280,24 +276,24 @@ Decoder::OpenUri(const char *uri)
...
@@ -280,24 +276,24 @@ Decoder::OpenUri(const char *uri)
*/
*/
gcc_pure
gcc_pure
static
inline
bool
static
inline
bool
decoder_check_cancel_read
(
const
Decoder
*
decoder
)
decoder_check_cancel_read
(
const
Decoder
Bridge
*
bridge
)
{
{
if
(
decoder
==
nullptr
)
if
(
bridge
==
nullptr
)
return
false
;
return
false
;
if
(
decoder
->
error
)
if
(
bridge
->
error
)
/* this translates to DecoderCommand::STOP */
/* this translates to DecoderCommand::STOP */
return
true
;
return
true
;
const
DecoderControl
&
dc
=
decoder
->
dc
;
const
DecoderControl
&
dc
=
bridge
->
dc
;
if
(
dc
.
command
==
DecoderCommand
::
NONE
)
if
(
dc
.
command
==
DecoderCommand
::
NONE
)
return
false
;
return
false
;
/* ignore the SEEK command during initialization, the plugin
/* ignore the SEEK command during initialization, the plugin
should handle that after it has initialized successfully */
should handle that after it has initialized successfully */
if
(
dc
.
command
==
DecoderCommand
::
SEEK
&&
if
(
dc
.
command
==
DecoderCommand
::
SEEK
&&
(
dc
.
state
==
DecoderState
::
START
||
decoder
->
seeking
||
(
dc
.
state
==
DecoderState
::
START
||
bridge
->
seeking
||
decoder
->
initial_seek_running
))
bridge
->
initial_seek_running
))
return
false
;
return
false
;
return
true
;
return
true
;
...
@@ -309,11 +305,11 @@ decoder_read(DecoderClient *client,
...
@@ -309,11 +305,11 @@ decoder_read(DecoderClient *client,
void
*
buffer
,
size_t
length
)
void
*
buffer
,
size_t
length
)
try
{
try
{
/* XXX don't allow decoder==nullptr */
/* XXX don't allow decoder==nullptr */
auto
*
decoder
=
(
Decoder
*
)
client
;
auto
*
bridge
=
(
DecoderBridge
*
)
client
;
assert
(
decoder
==
nullptr
||
assert
(
bridge
==
nullptr
||
decoder
->
dc
.
state
==
DecoderState
::
START
||
bridge
->
dc
.
state
==
DecoderState
::
START
||
decoder
->
dc
.
state
==
DecoderState
::
DECODE
);
bridge
->
dc
.
state
==
DecoderState
::
DECODE
);
assert
(
buffer
!=
nullptr
);
assert
(
buffer
!=
nullptr
);
if
(
length
==
0
)
if
(
length
==
0
)
...
@@ -322,7 +318,7 @@ try {
...
@@ -322,7 +318,7 @@ try {
ScopeLock
lock
(
is
.
mutex
);
ScopeLock
lock
(
is
.
mutex
);
while
(
true
)
{
while
(
true
)
{
if
(
decoder_check_cancel_read
(
decoder
))
if
(
decoder_check_cancel_read
(
bridge
))
return
0
;
return
0
;
if
(
is
.
IsAvailable
())
if
(
is
.
IsAvailable
())
...
@@ -336,9 +332,9 @@ try {
...
@@ -336,9 +332,9 @@ try {
return
nbytes
;
return
nbytes
;
}
catch
(
const
std
::
runtime_error
&
e
)
{
}
catch
(
const
std
::
runtime_error
&
e
)
{
auto
*
decoder
=
(
Decoder
*
)
client
;
auto
*
bridge
=
(
DecoderBridge
*
)
client
;
if
(
decoder
!=
nullptr
)
if
(
bridge
!=
nullptr
)
decoder
->
error
=
std
::
current_exception
();
bridge
->
error
=
std
::
current_exception
();
else
else
LogError
(
e
);
LogError
(
e
);
return
0
;
return
0
;
...
@@ -379,7 +375,7 @@ decoder_skip(DecoderClient *client, InputStream &is, size_t size)
...
@@ -379,7 +375,7 @@ decoder_skip(DecoderClient *client, InputStream &is, size_t size)
}
}
void
void
Decoder
::
SubmitTimestamp
(
double
t
)
Decoder
Bridge
::
SubmitTimestamp
(
double
t
)
{
{
assert
(
t
>=
0
);
assert
(
t
>=
0
);
...
@@ -388,26 +384,25 @@ Decoder::SubmitTimestamp(double t)
...
@@ -388,26 +384,25 @@ Decoder::SubmitTimestamp(double t)
/**
/**
* Sends a #tag as-is to the music pipe. Flushes the current chunk
* Sends a #tag as-is to the music pipe. Flushes the current chunk
* (
decoder.
chunk) if there is one.
* (
DecoderBridge::
chunk) if there is one.
*/
*/
static
DecoderCommand
static
DecoderCommand
do_send_tag
(
DecoderClient
&
client
,
const
Tag
&
tag
)
do_send_tag
(
DecoderClient
&
client
,
const
Tag
&
tag
)
{
{
auto
&
decoder
=
(
Decoder
&
)
client
;
auto
&
bridge
=
(
DecoderBridge
&
)
client
;
MusicChunk
*
chunk
;
if
(
decoder
.
current_chunk
!=
nullptr
)
{
if
(
bridge
.
current_chunk
!=
nullptr
)
{
/* there is a partial chunk - flush it, we want the
/* there is a partial chunk - flush it, we want the
tag in a new chunk */
tag in a new chunk */
decoder
.
FlushChunk
();
bridge
.
FlushChunk
();
}
}
assert
(
decoder
.
current_chunk
==
nullptr
);
assert
(
bridge
.
current_chunk
==
nullptr
);
chunk
=
decoder
.
GetChunk
();
auto
*
chunk
=
bridge
.
GetChunk
();
if
(
chunk
==
nullptr
)
{
if
(
chunk
==
nullptr
)
{
assert
(
decoder
.
dc
.
command
!=
DecoderCommand
::
NONE
);
assert
(
bridge
.
dc
.
command
!=
DecoderCommand
::
NONE
);
return
decoder
.
dc
.
command
;
return
bridge
.
dc
.
command
;
}
}
chunk
->
tag
=
new
Tag
(
tag
);
chunk
->
tag
=
new
Tag
(
tag
);
...
@@ -417,14 +412,13 @@ do_send_tag(DecoderClient &client, const Tag &tag)
...
@@ -417,14 +412,13 @@ do_send_tag(DecoderClient &client, const Tag &tag)
static
bool
static
bool
update_stream_tag
(
DecoderClient
&
client
,
InputStream
*
is
)
update_stream_tag
(
DecoderClient
&
client
,
InputStream
*
is
)
{
{
auto
&
decoder
=
(
Decoder
&
)
client
;
auto
&
bridge
=
(
DecoderBridge
&
)
client
;
Tag
*
tag
;
tag
=
is
!=
nullptr
auto
*
tag
=
is
!=
nullptr
?
is
->
LockReadTag
()
?
is
->
LockReadTag
()
:
nullptr
;
:
nullptr
;
if
(
tag
==
nullptr
)
{
if
(
tag
==
nullptr
)
{
tag
=
decoder
.
song_tag
;
tag
=
bridge
.
song_tag
;
if
(
tag
==
nullptr
)
if
(
tag
==
nullptr
)
return
false
;
return
false
;
...
@@ -432,19 +426,19 @@ update_stream_tag(DecoderClient &client, InputStream *is)
...
@@ -432,19 +426,19 @@ update_stream_tag(DecoderClient &client, InputStream *is)
instead */
instead */
}
else
}
else
/* discard the song tag; we don't need it */
/* discard the song tag; we don't need it */
delete
decoder
.
song_tag
;
delete
bridge
.
song_tag
;
decoder
.
song_tag
=
nullptr
;
bridge
.
song_tag
=
nullptr
;
delete
decoder
.
stream_tag
;
delete
bridge
.
stream_tag
;
decoder
.
stream_tag
=
tag
;
bridge
.
stream_tag
=
tag
;
return
true
;
return
true
;
}
}
DecoderCommand
DecoderCommand
Decoder
::
SubmitData
(
InputStream
*
is
,
Decoder
Bridge
::
SubmitData
(
InputStream
*
is
,
const
void
*
data
,
size_t
length
,
const
void
*
data
,
size_t
length
,
uint16_t
kbit_rate
)
uint16_t
kbit_rate
)
{
{
assert
(
dc
.
state
==
DecoderState
::
DECODE
);
assert
(
dc
.
state
==
DecoderState
::
DECODE
);
assert
(
dc
.
pipe
!=
nullptr
);
assert
(
dc
.
pipe
!=
nullptr
);
...
@@ -545,7 +539,7 @@ Decoder::SubmitData(InputStream *is,
...
@@ -545,7 +539,7 @@ Decoder::SubmitData(InputStream *is,
}
}
DecoderCommand
DecoderCommand
Decoder
::
SubmitTag
(
InputStream
*
is
,
Tag
&&
tag
)
Decoder
Bridge
::
SubmitTag
(
InputStream
*
is
,
Tag
&&
tag
)
{
{
DecoderCommand
cmd
;
DecoderCommand
cmd
;
...
@@ -586,7 +580,7 @@ Decoder::SubmitTag(InputStream *is, Tag &&tag)
...
@@ -586,7 +580,7 @@ Decoder::SubmitTag(InputStream *is, Tag &&tag)
}
}
void
void
Decoder
::
SubmitReplayGain
(
const
ReplayGainInfo
*
new_replay_gain_info
)
Decoder
Bridge
::
SubmitReplayGain
(
const
ReplayGainInfo
*
new_replay_gain_info
)
{
{
if
(
new_replay_gain_info
!=
nullptr
)
{
if
(
new_replay_gain_info
!=
nullptr
)
{
static
unsigned
serial
;
static
unsigned
serial
;
...
@@ -620,7 +614,7 @@ Decoder::SubmitReplayGain(const ReplayGainInfo *new_replay_gain_info)
...
@@ -620,7 +614,7 @@ Decoder::SubmitReplayGain(const ReplayGainInfo *new_replay_gain_info)
}
}
void
void
Decoder
::
SubmitMixRamp
(
MixRampInfo
&&
mix_ramp
)
Decoder
Bridge
::
SubmitMixRamp
(
MixRampInfo
&&
mix_ramp
)
{
{
dc
.
SetMixRamp
(
std
::
move
(
mix_ramp
));
dc
.
SetMixRamp
(
std
::
move
(
mix_ramp
));
}
}
src/decoder/DecoderThread.cxx
View file @
697c3f8c
...
@@ -20,7 +20,7 @@
...
@@ -20,7 +20,7 @@
#include "config.h"
#include "config.h"
#include "DecoderThread.hxx"
#include "DecoderThread.hxx"
#include "DecoderControl.hxx"
#include "DecoderControl.hxx"
#include "
DecoderInternal
.hxx"
#include "
Bridge
.hxx"
#include "DecoderError.hxx"
#include "DecoderError.hxx"
#include "DecoderPlugin.hxx"
#include "DecoderPlugin.hxx"
#include "DetachedSong.hxx"
#include "DetachedSong.hxx"
...
@@ -94,18 +94,18 @@ decoder_input_stream_open(DecoderControl &dc, Path path)
...
@@ -94,18 +94,18 @@ decoder_input_stream_open(DecoderControl &dc, Path path)
*/
*/
static
bool
static
bool
decoder_stream_decode
(
const
DecoderPlugin
&
plugin
,
decoder_stream_decode
(
const
DecoderPlugin
&
plugin
,
Decoder
&
decoder
,
Decoder
Bridge
&
bridge
,
InputStream
&
input_stream
)
InputStream
&
input_stream
)
{
{
assert
(
plugin
.
stream_decode
!=
nullptr
);
assert
(
plugin
.
stream_decode
!=
nullptr
);
assert
(
decoder
.
stream_tag
==
nullptr
);
assert
(
bridge
.
stream_tag
==
nullptr
);
assert
(
decoder
.
decoder_tag
==
nullptr
);
assert
(
bridge
.
decoder_tag
==
nullptr
);
assert
(
input_stream
.
IsReady
());
assert
(
input_stream
.
IsReady
());
assert
(
decoder
.
dc
.
state
==
DecoderState
::
START
);
assert
(
bridge
.
dc
.
state
==
DecoderState
::
START
);
FormatDebug
(
decoder_thread_domain
,
"probing plugin %s"
,
plugin
.
name
);
FormatDebug
(
decoder_thread_domain
,
"probing plugin %s"
,
plugin
.
name
);
if
(
decoder
.
dc
.
command
==
DecoderCommand
::
STOP
)
if
(
bridge
.
dc
.
command
==
DecoderCommand
::
STOP
)
throw
StopDecoder
();
throw
StopDecoder
();
/* rewind the stream, so each plugin gets a fresh start */
/* rewind the stream, so each plugin gets a fresh start */
...
@@ -115,19 +115,19 @@ decoder_stream_decode(const DecoderPlugin &plugin,
...
@@ -115,19 +115,19 @@ decoder_stream_decode(const DecoderPlugin &plugin,
}
}
{
{
const
ScopeUnlock
unlock
(
decoder
.
dc
.
mutex
);
const
ScopeUnlock
unlock
(
bridge
.
dc
.
mutex
);
FormatThreadName
(
"decoder:%s"
,
plugin
.
name
);
FormatThreadName
(
"decoder:%s"
,
plugin
.
name
);
plugin
.
StreamDecode
(
decoder
,
input_stream
);
plugin
.
StreamDecode
(
bridge
,
input_stream
);
SetThreadName
(
"decoder"
);
SetThreadName
(
"decoder"
);
}
}
assert
(
decoder
.
dc
.
state
==
DecoderState
::
START
||
assert
(
bridge
.
dc
.
state
==
DecoderState
::
START
||
decoder
.
dc
.
state
==
DecoderState
::
DECODE
);
bridge
.
dc
.
state
==
DecoderState
::
DECODE
);
return
decoder
.
dc
.
state
!=
DecoderState
::
START
;
return
bridge
.
dc
.
state
!=
DecoderState
::
START
;
}
}
/**
/**
...
@@ -137,34 +137,34 @@ decoder_stream_decode(const DecoderPlugin &plugin,
...
@@ -137,34 +137,34 @@ decoder_stream_decode(const DecoderPlugin &plugin,
*/
*/
static
bool
static
bool
decoder_file_decode
(
const
DecoderPlugin
&
plugin
,
decoder_file_decode
(
const
DecoderPlugin
&
plugin
,
Decoder
&
decoder
,
Path
path
)
Decoder
Bridge
&
bridge
,
Path
path
)
{
{
assert
(
plugin
.
file_decode
!=
nullptr
);
assert
(
plugin
.
file_decode
!=
nullptr
);
assert
(
decoder
.
stream_tag
==
nullptr
);
assert
(
bridge
.
stream_tag
==
nullptr
);
assert
(
decoder
.
decoder_tag
==
nullptr
);
assert
(
bridge
.
decoder_tag
==
nullptr
);
assert
(
!
path
.
IsNull
());
assert
(
!
path
.
IsNull
());
assert
(
path
.
IsAbsolute
());
assert
(
path
.
IsAbsolute
());
assert
(
decoder
.
dc
.
state
==
DecoderState
::
START
);
assert
(
bridge
.
dc
.
state
==
DecoderState
::
START
);
FormatDebug
(
decoder_thread_domain
,
"probing plugin %s"
,
plugin
.
name
);
FormatDebug
(
decoder_thread_domain
,
"probing plugin %s"
,
plugin
.
name
);
if
(
decoder
.
dc
.
command
==
DecoderCommand
::
STOP
)
if
(
bridge
.
dc
.
command
==
DecoderCommand
::
STOP
)
throw
StopDecoder
();
throw
StopDecoder
();
{
{
const
ScopeUnlock
unlock
(
decoder
.
dc
.
mutex
);
const
ScopeUnlock
unlock
(
bridge
.
dc
.
mutex
);
FormatThreadName
(
"decoder:%s"
,
plugin
.
name
);
FormatThreadName
(
"decoder:%s"
,
plugin
.
name
);
plugin
.
FileDecode
(
decoder
,
path
);
plugin
.
FileDecode
(
bridge
,
path
);
SetThreadName
(
"decoder"
);
SetThreadName
(
"decoder"
);
}
}
assert
(
decoder
.
dc
.
state
==
DecoderState
::
START
||
assert
(
bridge
.
dc
.
state
==
DecoderState
::
START
||
decoder
.
dc
.
state
==
DecoderState
::
DECODE
);
bridge
.
dc
.
state
==
DecoderState
::
DECODE
);
return
decoder
.
dc
.
state
!=
DecoderState
::
START
;
return
bridge
.
dc
.
state
!=
DecoderState
::
START
;
}
}
gcc_pure
gcc_pure
...
@@ -198,7 +198,7 @@ decoder_check_plugin(const DecoderPlugin &plugin, const InputStream &is,
...
@@ -198,7 +198,7 @@ decoder_check_plugin(const DecoderPlugin &plugin, const InputStream &is,
}
}
static
bool
static
bool
decoder_run_stream_plugin
(
Decoder
&
decoder
,
InputStream
&
is
,
decoder_run_stream_plugin
(
Decoder
Bridge
&
bridge
,
InputStream
&
is
,
const
char
*
suffix
,
const
char
*
suffix
,
const
DecoderPlugin
&
plugin
,
const
DecoderPlugin
&
plugin
,
bool
&
tried_r
)
bool
&
tried_r
)
...
@@ -206,14 +206,14 @@ decoder_run_stream_plugin(Decoder &decoder, InputStream &is,
...
@@ -206,14 +206,14 @@ decoder_run_stream_plugin(Decoder &decoder, InputStream &is,
if
(
!
decoder_check_plugin
(
plugin
,
is
,
suffix
))
if
(
!
decoder_check_plugin
(
plugin
,
is
,
suffix
))
return
false
;
return
false
;
decoder
.
error
=
std
::
exception_ptr
();
bridge
.
error
=
std
::
exception_ptr
();
tried_r
=
true
;
tried_r
=
true
;
return
decoder_stream_decode
(
plugin
,
decoder
,
is
);
return
decoder_stream_decode
(
plugin
,
bridge
,
is
);
}
}
static
bool
static
bool
decoder_run_stream_locked
(
Decoder
&
decoder
,
InputStream
&
is
,
decoder_run_stream_locked
(
Decoder
Bridge
&
bridge
,
InputStream
&
is
,
const
char
*
uri
,
bool
&
tried_r
)
const
char
*
uri
,
bool
&
tried_r
)
{
{
UriSuffixBuffer
suffix_buffer
;
UriSuffixBuffer
suffix_buffer
;
...
@@ -221,7 +221,7 @@ decoder_run_stream_locked(Decoder &decoder, InputStream &is,
...
@@ -221,7 +221,7 @@ decoder_run_stream_locked(Decoder &decoder, InputStream &is,
using
namespace
std
::
placeholders
;
using
namespace
std
::
placeholders
;
const
auto
f
=
std
::
bind
(
decoder_run_stream_plugin
,
const
auto
f
=
std
::
bind
(
decoder_run_stream_plugin
,
std
::
ref
(
decoder
),
std
::
ref
(
is
),
suffix
,
std
::
ref
(
bridge
),
std
::
ref
(
is
),
suffix
,
_1
,
std
::
ref
(
tried_r
));
_1
,
std
::
ref
(
tried_r
));
return
decoder_plugins_try
(
f
);
return
decoder_plugins_try
(
f
);
}
}
...
@@ -230,7 +230,7 @@ decoder_run_stream_locked(Decoder &decoder, InputStream &is,
...
@@ -230,7 +230,7 @@ decoder_run_stream_locked(Decoder &decoder, InputStream &is,
* Try decoding a stream, using the fallback plugin.
* Try decoding a stream, using the fallback plugin.
*/
*/
static
bool
static
bool
decoder_run_stream_fallback
(
Decoder
&
decoder
,
InputStream
&
is
)
decoder_run_stream_fallback
(
Decoder
Bridge
&
bridge
,
InputStream
&
is
)
{
{
const
struct
DecoderPlugin
*
plugin
;
const
struct
DecoderPlugin
*
plugin
;
...
@@ -240,7 +240,7 @@ decoder_run_stream_fallback(Decoder &decoder, InputStream &is)
...
@@ -240,7 +240,7 @@ decoder_run_stream_fallback(Decoder &decoder, InputStream &is)
plugin
=
decoder_plugin_from_name
(
"mad"
);
plugin
=
decoder_plugin_from_name
(
"mad"
);
#endif
#endif
return
plugin
!=
nullptr
&&
plugin
->
stream_decode
!=
nullptr
&&
return
plugin
!=
nullptr
&&
plugin
->
stream_decode
!=
nullptr
&&
decoder_stream_decode
(
*
plugin
,
decoder
,
is
);
decoder_stream_decode
(
*
plugin
,
bridge
,
is
);
}
}
/**
/**
...
@@ -261,25 +261,25 @@ LoadReplayGain(DecoderClient &client, InputStream &is)
...
@@ -261,25 +261,25 @@ LoadReplayGain(DecoderClient &client, InputStream &is)
* DecoderControl::mutex is not locked by caller.
* DecoderControl::mutex is not locked by caller.
*/
*/
static
bool
static
bool
decoder_run_stream
(
Decoder
&
decoder
,
const
char
*
uri
)
decoder_run_stream
(
Decoder
Bridge
&
bridge
,
const
char
*
uri
)
{
{
DecoderControl
&
dc
=
decoder
.
dc
;
DecoderControl
&
dc
=
bridge
.
dc
;
auto
input_stream
=
decoder_input_stream_open
(
dc
,
uri
);
auto
input_stream
=
decoder_input_stream_open
(
dc
,
uri
);
assert
(
input_stream
);
assert
(
input_stream
);
LoadReplayGain
(
decoder
,
*
input_stream
);
LoadReplayGain
(
bridge
,
*
input_stream
);
const
ScopeLock
protect
(
dc
.
mutex
);
const
ScopeLock
protect
(
dc
.
mutex
);
bool
tried
=
false
;
bool
tried
=
false
;
return
dc
.
command
==
DecoderCommand
::
STOP
||
return
dc
.
command
==
DecoderCommand
::
STOP
||
decoder_run_stream_locked
(
decoder
,
*
input_stream
,
uri
,
decoder_run_stream_locked
(
bridge
,
*
input_stream
,
uri
,
tried
)
||
tried
)
||
/* fallback to mp3: this is needed for bastard streams
/* fallback to mp3: this is needed for bastard streams
that don't have a suffix or set the mimeType */
that don't have a suffix or set the mimeType */
(
!
tried
&&
(
!
tried
&&
decoder_run_stream_fallback
(
decoder
,
*
input_stream
));
decoder_run_stream_fallback
(
bridge
,
*
input_stream
));
}
}
/**
/**
...
@@ -288,23 +288,23 @@ decoder_run_stream(Decoder &decoder, const char *uri)
...
@@ -288,23 +288,23 @@ decoder_run_stream(Decoder &decoder, const char *uri)
* DecoderControl::mutex is not locked by caller.
* DecoderControl::mutex is not locked by caller.
*/
*/
static
bool
static
bool
TryDecoderFile
(
Decoder
&
decoder
,
Path
path_fs
,
const
char
*
suffix
,
TryDecoderFile
(
Decoder
Bridge
&
bridge
,
Path
path_fs
,
const
char
*
suffix
,
InputStream
&
input_stream
,
InputStream
&
input_stream
,
const
DecoderPlugin
&
plugin
)
const
DecoderPlugin
&
plugin
)
{
{
if
(
!
plugin
.
SupportsSuffix
(
suffix
))
if
(
!
plugin
.
SupportsSuffix
(
suffix
))
return
false
;
return
false
;
decoder
.
error
=
std
::
exception_ptr
();
bridge
.
error
=
std
::
exception_ptr
();
DecoderControl
&
dc
=
decoder
.
dc
;
DecoderControl
&
dc
=
bridge
.
dc
;
if
(
plugin
.
file_decode
!=
nullptr
)
{
if
(
plugin
.
file_decode
!=
nullptr
)
{
const
ScopeLock
protect
(
dc
.
mutex
);
const
ScopeLock
protect
(
dc
.
mutex
);
return
decoder_file_decode
(
plugin
,
decoder
,
path_fs
);
return
decoder_file_decode
(
plugin
,
bridge
,
path_fs
);
}
else
if
(
plugin
.
stream_decode
!=
nullptr
)
{
}
else
if
(
plugin
.
stream_decode
!=
nullptr
)
{
const
ScopeLock
protect
(
dc
.
mutex
);
const
ScopeLock
protect
(
dc
.
mutex
);
return
decoder_stream_decode
(
plugin
,
decoder
,
input_stream
);
return
decoder_stream_decode
(
plugin
,
bridge
,
input_stream
);
}
else
}
else
return
false
;
return
false
;
}
}
...
@@ -315,21 +315,21 @@ TryDecoderFile(Decoder &decoder, Path path_fs, const char *suffix,
...
@@ -315,21 +315,21 @@ TryDecoderFile(Decoder &decoder, Path path_fs, const char *suffix,
* DecoderControl::mutex is not locked by caller.
* DecoderControl::mutex is not locked by caller.
*/
*/
static
bool
static
bool
decoder_run_file
(
Decoder
&
decoder
,
const
char
*
uri_utf8
,
Path
path_fs
)
decoder_run_file
(
Decoder
Bridge
&
bridge
,
const
char
*
uri_utf8
,
Path
path_fs
)
{
{
const
char
*
suffix
=
uri_get_suffix
(
uri_utf8
);
const
char
*
suffix
=
uri_get_suffix
(
uri_utf8
);
if
(
suffix
==
nullptr
)
if
(
suffix
==
nullptr
)
return
false
;
return
false
;
auto
input_stream
=
decoder_input_stream_open
(
decoder
.
dc
,
path_fs
);
auto
input_stream
=
decoder_input_stream_open
(
bridge
.
dc
,
path_fs
);
assert
(
input_stream
);
assert
(
input_stream
);
LoadReplayGain
(
decoder
,
*
input_stream
);
LoadReplayGain
(
bridge
,
*
input_stream
);
auto
&
is
=
*
input_stream
;
auto
&
is
=
*
input_stream
;
return
decoder_plugins_try
([
&
decoder
,
path_fs
,
suffix
,
return
decoder_plugins_try
([
&
bridge
,
path_fs
,
suffix
,
&
is
](
const
DecoderPlugin
&
plugin
){
&
is
](
const
DecoderPlugin
&
plugin
){
return
TryDecoderFile
(
decoder
,
return
TryDecoderFile
(
bridge
,
path_fs
,
path_fs
,
suffix
,
suffix
,
is
,
is
,
...
@@ -343,11 +343,12 @@ decoder_run_file(Decoder &decoder, const char *uri_utf8, Path path_fs)
...
@@ -343,11 +343,12 @@ decoder_run_file(Decoder &decoder, const char *uri_utf8, Path path_fs)
* DecoderControl::mutex is not locked.
* DecoderControl::mutex is not locked.
*/
*/
static
bool
static
bool
DecoderUnlockedRunUri
(
Decoder
&
decoder
,
const
char
*
real_uri
,
Path
path_fs
)
DecoderUnlockedRunUri
(
DecoderBridge
&
bridge
,
const
char
*
real_uri
,
Path
path_fs
)
try
{
try
{
return
!
path_fs
.
IsNull
()
return
!
path_fs
.
IsNull
()
?
decoder_run_file
(
decoder
,
real_uri
,
path_fs
)
?
decoder_run_file
(
bridge
,
real_uri
,
path_fs
)
:
decoder_run_stream
(
decoder
,
real_uri
);
:
decoder_run_stream
(
bridge
,
real_uri
);
}
catch
(
StopDecoder
)
{
}
catch
(
StopDecoder
)
{
return
true
;
return
true
;
}
catch
(...)
{
}
catch
(...)
{
...
@@ -369,12 +370,13 @@ static void
...
@@ -369,12 +370,13 @@ static void
decoder_run_song
(
DecoderControl
&
dc
,
decoder_run_song
(
DecoderControl
&
dc
,
const
DetachedSong
&
song
,
const
char
*
uri
,
Path
path_fs
)
const
DetachedSong
&
song
,
const
char
*
uri
,
Path
path_fs
)
{
{
Decoder
decoder
(
dc
,
dc
.
start_time
.
IsPositive
(),
DecoderBridge
bridge
(
dc
,
dc
.
start_time
.
IsPositive
(),
/* pass the song tag only if it's
/* pass the song tag only if it's
authoritative, i.e. if it's a local file -
authoritative, i.e. if it's a local
tags on "stream" songs are just remembered
file - tags on "stream" songs are just
from the last time we played it*/
remembered from the last time we
song
.
IsFile
()
?
new
Tag
(
song
.
GetTag
())
:
nullptr
);
played it*/
song
.
IsFile
()
?
new
Tag
(
song
.
GetTag
())
:
nullptr
);
dc
.
state
=
DecoderState
::
START
;
dc
.
state
=
DecoderState
::
START
;
dc
.
CommandFinishedLocked
();
dc
.
CommandFinishedLocked
();
...
@@ -383,20 +385,20 @@ decoder_run_song(DecoderControl &dc,
...
@@ -383,20 +385,20 @@ decoder_run_song(DecoderControl &dc,
{
{
const
ScopeUnlock
unlock
(
dc
.
mutex
);
const
ScopeUnlock
unlock
(
dc
.
mutex
);
AtScopeExit
(
&
decoder
)
{
AtScopeExit
(
&
bridge
)
{
/* flush the last chunk */
/* flush the last chunk */
if
(
decoder
.
current_chunk
!=
nullptr
)
if
(
bridge
.
current_chunk
!=
nullptr
)
decoder
.
FlushChunk
();
bridge
.
FlushChunk
();
};
};
success
=
DecoderUnlockedRunUri
(
decoder
,
uri
,
path_fs
);
success
=
DecoderUnlockedRunUri
(
bridge
,
uri
,
path_fs
);
}
}
if
(
decoder
.
error
)
{
if
(
bridge
.
error
)
{
/* copy the Error from struct Decoder to
/* copy the Error from struct Decoder to
DecoderControl */
DecoderControl */
std
::
rethrow_exception
(
decoder
.
error
);
std
::
rethrow_exception
(
bridge
.
error
);
}
else
if
(
success
)
}
else
if
(
success
)
dc
.
state
=
DecoderState
::
STOP
;
dc
.
state
=
DecoderState
::
STOP
;
else
{
else
{
...
...
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