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
8c342a76
Commit
8c342a76
authored
Nov 21, 2016
by
Max Kellermann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
decoder/API: move functions into class DecoderBridge
parent
697c3f8c
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
63 additions
and
62 deletions
+63
-62
Bridge.hxx
src/decoder/Bridge.hxx
+23
-0
DecoderAPI.cxx
src/decoder/DecoderAPI.cxx
+40
-62
No files found.
src/decoder/Bridge.hxx
View file @
8c342a76
...
...
@@ -138,6 +138,29 @@ public:
DecoderCommand
SubmitTag
(
InputStream
*
is
,
Tag
&&
tag
)
override
;
void
SubmitReplayGain
(
const
ReplayGainInfo
*
replay_gain_info
)
override
;
void
SubmitMixRamp
(
MixRampInfo
&&
mix_ramp
)
override
;
private
:
/**
* Checks if we need an "initial seek". If so, then the
* initial seek is prepared, and the function returns true.
*/
bool
PrepareInitialSeek
();
/**
* Returns the current decoder command. May return a
* "virtual" synthesized command, e.g. to seek to the
* beginning of the CUE track.
*/
DecoderCommand
GetVirtualCommand
();
DecoderCommand
LockGetVirtualCommand
();
/**
* Sends a #Tag as-is to the #MusicPipe. Flushes the current
* chunk (DecoderBridge::chunk) if there is one.
*/
DecoderCommand
DoSendTag
(
const
Tag
&
tag
);
bool
UpdateStreamTag
(
InputStream
*
is
);
};
#endif
src/decoder/DecoderAPI.cxx
View file @
8c342a76
...
...
@@ -83,15 +83,9 @@ DecoderBridge::Ready(const AudioFormat audio_format,
dc
.
client_cond
.
signal
();
}
/**
* Checks if we need an "initial seek". If so, then the initial seek
* is prepared, and the function returns true.
*/
gcc_pure
static
bool
decoder_prepare_initial_seek
(
DecoderBridge
&
bridge
)
bool
DecoderBridge
::
PrepareInitialSeek
()
{
const
DecoderControl
&
dc
=
bridge
.
dc
;
assert
(
dc
.
pipe
!=
nullptr
);
if
(
dc
.
state
!=
DecoderState
::
DECODE
)
...
...
@@ -100,69 +94,61 @@ decoder_prepare_initial_seek(DecoderBridge &bridge)
virtual "SEEK" command */
return
false
;
if
(
bridge
.
initial_seek_running
)
if
(
initial_seek_running
)
/* initial seek has already begun - override any other
command */
return
true
;
if
(
bridge
.
initial_seek_pending
)
{
if
(
initial_seek_pending
)
{
if
(
!
dc
.
seekable
)
{
/* seeking is not possible */
bridge
.
initial_seek_pending
=
false
;
initial_seek_pending
=
false
;
return
false
;
}
if
(
dc
.
command
==
DecoderCommand
::
NONE
)
{
/* begin initial seek */
bridge
.
initial_seek_pending
=
false
;
bridge
.
initial_seek_running
=
true
;
initial_seek_pending
=
false
;
initial_seek_running
=
true
;
return
true
;
}
/* skip initial seek when there's another command
(e.g. STOP) */
bridge
.
initial_seek_pending
=
false
;
initial_seek_pending
=
false
;
}
return
false
;
}
/**
* Returns the current decoder command. May return a "virtual"
* synthesized command, e.g. to seek to the beginning of the CUE
* track.
*/
gcc_pure
static
DecoderCommand
decoder_get_virtual_command
(
DecoderBridge
&
bridge
)
DecoderCommand
DecoderBridge
::
GetVirtualCommand
()
{
if
(
bridge
.
error
)
if
(
error
)
/* an error has occurred: stop the decoder plugin */
return
DecoderCommand
::
STOP
;
const
DecoderControl
&
dc
=
bridge
.
dc
;
assert
(
dc
.
pipe
!=
nullptr
);
if
(
decoder_prepare_initial_seek
(
bridge
))
if
(
PrepareInitialSeek
(
))
return
DecoderCommand
::
SEEK
;
return
dc
.
command
;
}
gcc_pure
static
DecoderCommand
decoder_lock_get_virtual_command
(
DecoderBridge
&
bridge
)
DecoderCommand
DecoderBridge
::
LockGetVirtualCommand
()
{
const
ScopeLock
protect
(
bridge
.
dc
.
mutex
);
return
decoder_get_virtual_command
(
bridge
);
const
ScopeLock
protect
(
dc
.
mutex
);
return
GetVirtualCommand
(
);
}
DecoderCommand
DecoderBridge
::
GetCommand
()
{
return
decoder_lock_get_virtual_command
(
*
this
);
return
LockGetVirtualCommand
(
);
}
void
...
...
@@ -382,43 +368,35 @@ DecoderBridge::SubmitTimestamp(double t)
timestamp
=
t
;
}
/**
* Sends a #tag as-is to the music pipe. Flushes the current chunk
* (DecoderBridge::chunk) if there is one.
*/
static
DecoderCommand
do_send_tag
(
DecoderClient
&
client
,
const
Tag
&
tag
)
DecoderCommand
DecoderBridge
::
DoSendTag
(
const
Tag
&
tag
)
{
auto
&
bridge
=
(
DecoderBridge
&
)
client
;
if
(
bridge
.
current_chunk
!=
nullptr
)
{
if
(
current_chunk
!=
nullptr
)
{
/* there is a partial chunk - flush it, we want the
tag in a new chunk */
bridge
.
FlushChunk
();
FlushChunk
();
}
assert
(
bridge
.
current_chunk
==
nullptr
);
assert
(
current_chunk
==
nullptr
);
auto
*
chunk
=
bridge
.
GetChunk
();
auto
*
chunk
=
GetChunk
();
if
(
chunk
==
nullptr
)
{
assert
(
bridge
.
dc
.
command
!=
DecoderCommand
::
NONE
);
return
bridge
.
dc
.
command
;
assert
(
dc
.
command
!=
DecoderCommand
::
NONE
);
return
dc
.
command
;
}
chunk
->
tag
=
new
Tag
(
tag
);
return
DecoderCommand
::
NONE
;
}
static
bool
update_stream_tag
(
DecoderClient
&
client
,
InputStream
*
is
)
bool
DecoderBridge
::
UpdateStreamTag
(
InputStream
*
is
)
{
auto
&
bridge
=
(
DecoderBridge
&
)
client
;
auto
*
tag
=
is
!=
nullptr
?
is
->
LockReadTag
()
:
nullptr
;
if
(
tag
==
nullptr
)
{
tag
=
bridge
.
song_tag
;
tag
=
song_tag
;
if
(
tag
==
nullptr
)
return
false
;
...
...
@@ -426,12 +404,12 @@ update_stream_tag(DecoderClient &client, InputStream *is)
instead */
}
else
/* discard the song tag; we don't need it */
delete
bridge
.
song_tag
;
delete
song_tag
;
bridge
.
song_tag
=
nullptr
;
song_tag
=
nullptr
;
delete
bridge
.
stream_tag
;
bridge
.
stream_tag
=
tag
;
delete
stream_tag
;
stream_tag
=
tag
;
return
true
;
}
...
...
@@ -444,7 +422,7 @@ DecoderBridge::SubmitData(InputStream *is,
assert
(
dc
.
pipe
!=
nullptr
);
assert
(
length
%
dc
.
in_audio_format
.
GetFrameSize
()
==
0
);
DecoderCommand
cmd
=
decoder_lock_get_virtual_command
(
*
this
);
DecoderCommand
cmd
=
LockGetVirtualCommand
(
);
if
(
cmd
==
DecoderCommand
::
STOP
||
cmd
==
DecoderCommand
::
SEEK
||
length
==
0
)
...
...
@@ -455,16 +433,16 @@ DecoderBridge::SubmitData(InputStream *is,
/* send stream tags */
if
(
update_stream_tag
(
*
this
,
is
))
{
if
(
UpdateStreamTag
(
is
))
{
if
(
decoder_tag
!=
nullptr
)
{
/* merge with tag from decoder plugin */
Tag
*
tag
=
Tag
::
Merge
(
*
decoder_tag
,
*
stream_tag
);
cmd
=
do_send_tag
(
*
this
,
*
tag
);
cmd
=
DoSendTag
(
*
tag
);
delete
tag
;
}
else
/* send only the stream tag */
cmd
=
do_send_tag
(
*
this
,
*
stream_tag
);
cmd
=
DoSendTag
(
*
stream_tag
);
if
(
cmd
!=
DecoderCommand
::
NONE
)
return
cmd
;
...
...
@@ -553,11 +531,11 @@ DecoderBridge::SubmitTag(InputStream *is, Tag &&tag)
/* check for a new stream tag */
update_stream_tag
(
*
this
,
is
);
UpdateStreamTag
(
is
);
/* check if we're seeking */
if
(
decoder_prepare_initial_seek
(
*
this
))
if
(
PrepareInitialSeek
(
))
/* during initial seek, no music chunk must be created
until seeking is finished; skip the rest of the
function here */
...
...
@@ -570,11 +548,11 @@ DecoderBridge::SubmitTag(InputStream *is, Tag &&tag)
Tag
*
merged
;
merged
=
Tag
::
Merge
(
*
stream_tag
,
*
decoder_tag
);
cmd
=
do_send_tag
(
*
this
,
*
merged
);
cmd
=
DoSendTag
(
*
merged
);
delete
merged
;
}
else
/* send only the decoder tag */
cmd
=
do_send_tag
(
*
this
,
*
decoder_tag
);
cmd
=
DoSendTag
(
*
decoder_tag
);
return
cmd
;
}
...
...
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