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
32799fef
Commit
32799fef
authored
Jan 21, 2013
by
Max Kellermann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
DecoderControl: move functions into the class
parent
e1b03b4a
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
281 additions
and
360 deletions
+281
-360
DecoderAPI.cxx
src/DecoderAPI.cxx
+9
-9
DecoderControl.cxx
src/DecoderControl.cxx
+75
-101
DecoderControl.hxx
src/DecoderControl.hxx
+135
-188
DecoderInternal.cxx
src/DecoderInternal.cxx
+3
-3
DecoderThread.cxx
src/DecoderThread.cxx
+28
-28
PlayerThread.cxx
src/PlayerThread.cxx
+31
-31
No files found.
src/DecoderAPI.cxx
View file @
32799fef
...
@@ -64,10 +64,10 @@ decoder_initialized(struct decoder *decoder,
...
@@ -64,10 +64,10 @@ decoder_initialized(struct decoder *decoder,
dc
->
seekable
=
seekable
;
dc
->
seekable
=
seekable
;
dc
->
total_time
=
total_time
;
dc
->
total_time
=
total_time
;
d
ecoder_lock
(
dc
);
d
c
->
Lock
(
);
dc
->
state
=
DECODE_STATE_DECODE
;
dc
->
state
=
DECODE_STATE_DECODE
;
g_cond_signal
(
dc
->
client_cond
);
g_cond_signal
(
dc
->
client_cond
);
d
ecoder_unlock
(
dc
);
d
c
->
Unlock
(
);
g_debug
(
"audio_format=%s, seekable=%s"
,
g_debug
(
"audio_format=%s, seekable=%s"
,
audio_format_to_string
(
&
dc
->
in_audio_format
,
&
af_string
),
audio_format_to_string
(
&
dc
->
in_audio_format
,
&
af_string
),
...
@@ -155,7 +155,7 @@ decoder_command_finished(struct decoder *decoder)
...
@@ -155,7 +155,7 @@ decoder_command_finished(struct decoder *decoder)
{
{
struct
decoder_control
*
dc
=
decoder
->
dc
;
struct
decoder_control
*
dc
=
decoder
->
dc
;
d
ecoder_lock
(
dc
);
d
c
->
Lock
(
);
assert
(
dc
->
command
!=
DECODE_COMMAND_NONE
||
assert
(
dc
->
command
!=
DECODE_COMMAND_NONE
||
decoder
->
initial_seek_running
);
decoder
->
initial_seek_running
);
...
@@ -171,7 +171,7 @@ decoder_command_finished(struct decoder *decoder)
...
@@ -171,7 +171,7 @@ decoder_command_finished(struct decoder *decoder)
decoder
->
initial_seek_running
=
false
;
decoder
->
initial_seek_running
=
false
;
decoder
->
timestamp
=
dc
->
start_ms
/
1000.
;
decoder
->
timestamp
=
dc
->
start_ms
/
1000.
;
d
ecoder_unlock
(
dc
);
d
c
->
Unlock
(
);
return
;
return
;
}
}
...
@@ -192,7 +192,7 @@ decoder_command_finished(struct decoder *decoder)
...
@@ -192,7 +192,7 @@ decoder_command_finished(struct decoder *decoder)
dc
->
command
=
DECODE_COMMAND_NONE
;
dc
->
command
=
DECODE_COMMAND_NONE
;
g_cond_signal
(
dc
->
client_cond
);
g_cond_signal
(
dc
->
client_cond
);
d
ecoder_unlock
(
dc
);
d
c
->
Unlock
(
);
}
}
double
decoder_seek_where
(
G_GNUC_UNUSED
struct
decoder
*
decoder
)
double
decoder_seek_where
(
G_GNUC_UNUSED
struct
decoder
*
decoder
)
...
@@ -377,9 +377,9 @@ decoder_data(struct decoder *decoder,
...
@@ -377,9 +377,9 @@ decoder_data(struct decoder *decoder,
assert
(
dc
->
pipe
!=
NULL
);
assert
(
dc
->
pipe
!=
NULL
);
assert
(
length
%
audio_format_frame_size
(
&
dc
->
in_audio_format
)
==
0
);
assert
(
length
%
audio_format_frame_size
(
&
dc
->
in_audio_format
)
==
0
);
d
ecoder_lock
(
dc
);
d
c
->
Lock
(
);
cmd
=
decoder_get_virtual_command
(
decoder
);
cmd
=
decoder_get_virtual_command
(
decoder
);
d
ecoder_unlock
(
dc
);
d
c
->
Unlock
(
);
if
(
cmd
==
DECODE_COMMAND_STOP
||
cmd
==
DECODE_COMMAND_SEEK
||
if
(
cmd
==
DECODE_COMMAND_STOP
||
cmd
==
DECODE_COMMAND_SEEK
||
length
==
0
)
length
==
0
)
...
@@ -564,6 +564,6 @@ decoder_mixramp(struct decoder *decoder,
...
@@ -564,6 +564,6 @@ decoder_mixramp(struct decoder *decoder,
struct
decoder_control
*
dc
=
decoder
->
dc
;
struct
decoder_control
*
dc
=
decoder
->
dc
;
assert
(
dc
!=
NULL
);
assert
(
dc
!=
NULL
);
dc
_mixramp_start
(
dc
,
mixramp_start
);
dc
->
MixRampStart
(
mixramp_start
);
dc
_mixramp_end
(
dc
,
mixramp_end
);
dc
->
MixRampEnd
(
mixramp_end
);
}
}
src/DecoderControl.cxx
View file @
32799fef
...
@@ -27,46 +27,30 @@
...
@@ -27,46 +27,30 @@
#undef G_LOG_DOMAIN
#undef G_LOG_DOMAIN
#define G_LOG_DOMAIN "decoder_control"
#define G_LOG_DOMAIN "decoder_control"
struct
decoder_control
*
decoder_control
::
decoder_control
()
dc_new
()
:
thread
(
nullptr
),
mutex
(
g_mutex_new
()),
cond
(
g_cond_new
()),
client_cond
(
g_cond_new
()),
state
(
DECODE_STATE_STOP
),
command
(
DECODE_COMMAND_NONE
),
song
(
nullptr
),
replay_gain_db
(
0
),
replay_gain_prev_db
(
0
),
mixramp_start
(
nullptr
),
mixramp_end
(
nullptr
),
mixramp_prev_end
(
nullptr
)
{}
decoder_control
::~
decoder_control
()
{
{
struct
decoder_control
*
dc
=
g_new
(
struct
decoder_control
,
1
);
ClearError
(
);
dc
->
thread
=
NULL
;
if
(
song
!=
NULL
)
song_free
(
song
);
dc
->
mutex
=
g_mutex_new
();
g_cond_free
(
client_cond
);
dc
->
cond
=
g_cond_new
();
g_cond_free
(
cond
);
dc
->
client_cond
=
g_cond_new
();
g_mutex_free
(
mutex
);
g_free
(
mixramp_start
);
dc
->
state
=
DECODE_STATE_STOP
;
g_free
(
mixramp_end
);
dc
->
command
=
DECODE_COMMAND_NONE
;
g_free
(
mixramp_prev_end
);
dc
->
song
=
NULL
;
dc
->
replay_gain_db
=
0
;
dc
->
replay_gain_prev_db
=
0
;
dc
->
mixramp_start
=
NULL
;
dc
->
mixramp_end
=
NULL
;
dc
->
mixramp_prev_end
=
NULL
;
return
dc
;
}
void
dc_free
(
struct
decoder_control
*
dc
)
{
dc_clear_error
(
dc
);
if
(
dc
->
song
!=
NULL
)
song_free
(
dc
->
song
);
g_cond_free
(
dc
->
client_cond
);
g_cond_free
(
dc
->
cond
);
g_mutex_free
(
dc
->
mutex
);
g_free
(
dc
->
mixramp_start
);
g_free
(
dc
->
mixramp_end
);
g_free
(
dc
->
mixramp_prev_end
);
g_free
(
dc
);
}
}
static
void
static
void
...
@@ -80,45 +64,43 @@ static void
...
@@ -80,45 +64,43 @@ static void
dc_command_locked
(
struct
decoder_control
*
dc
,
enum
decoder_command
cmd
)
dc_command_locked
(
struct
decoder_control
*
dc
,
enum
decoder_command
cmd
)
{
{
dc
->
command
=
cmd
;
dc
->
command
=
cmd
;
d
ecoder_signal
(
dc
);
d
c
->
Signal
(
);
dc_command_wait_locked
(
dc
);
dc_command_wait_locked
(
dc
);
}
}
static
void
static
void
dc_command
(
struct
decoder_control
*
dc
,
enum
decoder_command
cmd
)
dc_command
(
struct
decoder_control
*
dc
,
enum
decoder_command
cmd
)
{
{
d
ecoder_lock
(
dc
);
d
c
->
Lock
(
);
dc
_clear_error
(
dc
);
dc
->
ClearError
(
);
dc_command_locked
(
dc
,
cmd
);
dc_command_locked
(
dc
,
cmd
);
d
ecoder_unlock
(
dc
);
d
c
->
Unlock
(
);
}
}
static
void
static
void
dc_command_async
(
struct
decoder_control
*
dc
,
enum
decoder_command
cmd
)
dc_command_async
(
struct
decoder_control
*
dc
,
enum
decoder_command
cmd
)
{
{
d
ecoder_lock
(
dc
);
d
c
->
Lock
(
);
dc
->
command
=
cmd
;
dc
->
command
=
cmd
;
d
ecoder_signal
(
dc
);
d
c
->
Signal
(
);
d
ecoder_unlock
(
dc
);
d
c
->
Unlock
(
);
}
}
bool
bool
decoder_is_current_song
(
const
struct
decoder_control
*
dc
,
decoder_control
::
IsCurrentSong
(
const
struct
song
*
_song
)
const
const
struct
song
*
song
)
{
{
assert
(
dc
!=
NULL
);
assert
(
_song
!=
NULL
);
assert
(
song
!=
NULL
);
switch
(
dc
->
state
)
{
switch
(
state
)
{
case
DECODE_STATE_STOP
:
case
DECODE_STATE_STOP
:
case
DECODE_STATE_ERROR
:
case
DECODE_STATE_ERROR
:
return
false
;
return
false
;
case
DECODE_STATE_START
:
case
DECODE_STATE_START
:
case
DECODE_STATE_DECODE
:
case
DECODE_STATE_DECODE
:
return
song_equals
(
dc
->
song
,
song
);
return
song_equals
(
song
,
_
song
);
}
}
assert
(
false
);
assert
(
false
);
...
@@ -126,99 +108,91 @@ decoder_is_current_song(const struct decoder_control *dc,
...
@@ -126,99 +108,91 @@ decoder_is_current_song(const struct decoder_control *dc,
}
}
void
void
d
c_start
(
struct
decoder_control
*
dc
,
struct
song
*
song
,
d
ecoder_control
::
Start
(
struct
song
*
_
song
,
unsigned
start_ms
,
unsigned
end_ms
,
unsigned
_start_ms
,
unsigned
_
end_ms
,
struct
music_buffer
*
buffer
,
struct
music_pipe
*
pipe
)
music_buffer
*
_buffer
,
music_pipe
*
_
pipe
)
{
{
assert
(
song
!=
NULL
);
assert
(
_
song
!=
NULL
);
assert
(
buffer
!=
NULL
);
assert
(
buffer
!=
NULL
);
assert
(
pipe
!=
NULL
);
assert
(
pipe
!=
NULL
);
assert
(
music_pipe_empty
(
pipe
));
assert
(
music_pipe_empty
(
pipe
));
if
(
dc
->
song
!=
NULL
)
if
(
song
!=
nullptr
)
song_free
(
dc
->
song
);
song_free
(
song
);
song
=
_song
;
start_ms
=
_start_ms
;
end_ms
=
_end_ms
;
buffer
=
_buffer
;
pipe
=
_pipe
;
dc
->
song
=
song
;
dc_command
(
this
,
DECODE_COMMAND_START
);
dc
->
start_ms
=
start_ms
;
dc
->
end_ms
=
end_ms
;
dc
->
buffer
=
buffer
;
dc
->
pipe
=
pipe
;
dc_command
(
dc
,
DECODE_COMMAND_START
);
}
}
void
void
d
c_stop
(
struct
decoder_control
*
dc
)
d
ecoder_control
::
Stop
(
)
{
{
decoder_lock
(
dc
);
Lock
(
);
if
(
dc
->
command
!=
DECODE_COMMAND_NONE
)
if
(
command
!=
DECODE_COMMAND_NONE
)
/* Attempt to cancel the current command. If it's too
/* Attempt to cancel the current command. If it's too
late and the decoder thread is already executing
late and the decoder thread is already executing
the old command, we'll call STOP again in this
the old command, we'll call STOP again in this
function (see below). */
function (see below). */
dc_command_locked
(
dc
,
DECODE_COMMAND_STOP
);
dc_command_locked
(
this
,
DECODE_COMMAND_STOP
);
if
(
dc
->
state
!=
DECODE_STATE_STOP
&&
dc
->
state
!=
DECODE_STATE_ERROR
)
if
(
state
!=
DECODE_STATE_STOP
&&
state
!=
DECODE_STATE_ERROR
)
dc_command_locked
(
dc
,
DECODE_COMMAND_STOP
);
dc_command_locked
(
this
,
DECODE_COMMAND_STOP
);
decoder_unlock
(
dc
);
Unlock
(
);
}
}
bool
bool
d
c_seek
(
struct
decoder_control
*
dc
,
double
where
)
d
ecoder_control
::
Seek
(
double
where
)
{
{
assert
(
dc
->
state
!=
DECODE_STATE_START
);
assert
(
state
!=
DECODE_STATE_START
);
assert
(
where
>=
0.0
);
assert
(
where
>=
0.0
);
if
(
dc
->
state
==
DECODE_STATE_STOP
||
if
(
state
==
DECODE_STATE_STOP
||
dc
->
state
==
DECODE_STATE_ERROR
||
!
dc
->
seekable
)
state
==
DECODE_STATE_ERROR
||
!
seekable
)
return
false
;
return
false
;
dc
->
seek_where
=
where
;
seek_where
=
where
;
dc
->
seek_error
=
false
;
seek_error
=
false
;
dc_command
(
dc
,
DECODE_COMMAND_SEEK
);
dc_command
(
this
,
DECODE_COMMAND_SEEK
);
if
(
dc
->
seek_error
)
return
false
;
return
true
;
return
!
seek_error
;
}
}
void
void
d
c_quit
(
struct
decoder_control
*
dc
)
d
ecoder_control
::
Quit
(
)
{
{
assert
(
dc
->
thread
!=
NULL
);
assert
(
thread
!=
nullptr
);
dc
->
quit
=
true
;
quit
=
true
;
dc_command_async
(
dc
,
DECODE_COMMAND_STOP
);
dc_command_async
(
this
,
DECODE_COMMAND_STOP
);
g_thread_join
(
dc
->
thread
);
g_thread_join
(
thread
);
dc
->
thread
=
NULL
;
thread
=
nullptr
;
}
}
void
void
d
c_mixramp_start
(
struct
decoder_control
*
dc
,
char
*
mixramp_start
)
d
ecoder_control
::
MixRampStart
(
char
*
_
mixramp_start
)
{
{
assert
(
dc
!=
NULL
);
g_free
(
mixramp_start
);
mixramp_start
=
_mixramp_start
;
g_free
(
dc
->
mixramp_start
);
dc
->
mixramp_start
=
mixramp_start
;
}
}
void
void
d
c_mixramp_end
(
struct
decoder_control
*
dc
,
char
*
mixramp_end
)
d
ecoder_control
::
MixRampEnd
(
char
*
_
mixramp_end
)
{
{
assert
(
dc
!=
NULL
);
g_free
(
mixramp_end
);
mixramp_end
=
_mixramp_end
;
g_free
(
dc
->
mixramp_end
);
dc
->
mixramp_end
=
mixramp_end
;
}
}
void
void
d
c_mixramp_prev_end
(
struct
decoder_control
*
dc
,
char
*
mixramp_prev_end
)
d
ecoder_control
::
MixRampPrevEnd
(
char
*
_
mixramp_prev_end
)
{
{
assert
(
dc
!=
NULL
);
g_free
(
mixramp_prev_end
);
mixramp_prev_end
=
_mixramp_prev_end
;
g_free
(
dc
->
mixramp_prev_end
);
dc
->
mixramp_prev_end
=
mixramp_prev_end
;
}
}
src/DecoderControl.hxx
View file @
32799fef
...
@@ -130,6 +130,41 @@ struct decoder_control {
...
@@ -130,6 +130,41 @@ struct decoder_control {
char
*
mixramp_end
;
char
*
mixramp_end
;
char
*
mixramp_prev_end
;
char
*
mixramp_prev_end
;
decoder_control
();
~
decoder_control
();
/**
* Locks the object.
*/
void
Lock
()
const
{
g_mutex_lock
(
mutex
);
}
/**
* Unlocks the object.
*/
void
Unlock
()
const
{
g_mutex_unlock
(
mutex
);
}
/**
* Signals the object. This function is only valid in the
* player thread. The object should be locked prior to
* calling this function.
*/
void
Signal
()
{
g_cond_signal
(
cond
);
}
/**
* Waits for a signal on the #decoder_control object. This function
* is only valid in the decoder thread. The object must be locked
* prior to calling this function.
*/
void
Wait
()
{
g_cond_wait
(
cond
,
mutex
);
}
/**
/**
* Waits for a signal from the decoder thread. This object
* Waits for a signal from the decoder thread. This object
* must be locked prior to calling this function. This method
* must be locked prior to calling this function. This method
...
@@ -138,211 +173,123 @@ struct decoder_control {
...
@@ -138,211 +173,123 @@ struct decoder_control {
void
WaitForDecoder
()
{
void
WaitForDecoder
()
{
g_cond_wait
(
client_cond
,
mutex
);
g_cond_wait
(
client_cond
,
mutex
);
}
}
};
G_GNUC_MALLOC
struct
decoder_control
*
dc_new
();
void
bool
IsIdle
()
const
{
dc_free
(
struct
decoder_control
*
dc
);
return
state
==
DECODE_STATE_STOP
||
state
==
DECODE_STATE_ERROR
;
/**
* Locks the #decoder_control object.
*/
static
inline
void
decoder_lock
(
struct
decoder_control
*
dc
)
{
g_mutex_lock
(
dc
->
mutex
);
}
/**
* Unlocks the #decoder_control object.
*/
static
inline
void
decoder_unlock
(
struct
decoder_control
*
dc
)
{
g_mutex_unlock
(
dc
->
mutex
);
}
/**
* Waits for a signal on the #decoder_control object. This function
* is only valid in the decoder thread. The object must be locked
* prior to calling this function.
*/
static
inline
void
decoder_wait
(
struct
decoder_control
*
dc
)
{
g_cond_wait
(
dc
->
cond
,
dc
->
mutex
);
}
/**
* Signals the #decoder_control object. This function is only valid
* in the player thread. The object should be locked prior to calling
* this function.
*/
static
inline
void
decoder_signal
(
struct
decoder_control
*
dc
)
{
g_cond_signal
(
dc
->
cond
);
}
static
inline
bool
decoder_is_idle
(
const
struct
decoder_control
*
dc
)
{
return
dc
->
state
==
DECODE_STATE_STOP
||
dc
->
state
==
DECODE_STATE_ERROR
;
}
static
inline
bool
decoder_is_starting
(
const
struct
decoder_control
*
dc
)
{
return
dc
->
state
==
DECODE_STATE_START
;
}
static
inline
bool
decoder_has_failed
(
const
struct
decoder_control
*
dc
)
{
assert
(
dc
->
command
==
DECODE_COMMAND_NONE
);
return
dc
->
state
==
DECODE_STATE_ERROR
;
}
/**
* Checks whether an error has occurred, and if so, returns a newly
* allocated copy of the #GError object.
*
* Caller must lock the object.
*/
static
inline
GError
*
dc_get_error
(
const
struct
decoder_control
*
dc
)
{
assert
(
dc
!=
NULL
);
assert
(
dc
->
command
==
DECODE_COMMAND_NONE
);
assert
(
dc
->
state
!=
DECODE_STATE_ERROR
||
dc
->
error
!=
NULL
);
return
dc
->
state
==
DECODE_STATE_ERROR
?
g_error_copy
(
dc
->
error
)
:
NULL
;
}
/**
* Like dc_get_error(), but locks and unlocks the object.
*/
static
inline
GError
*
dc_lock_get_error
(
struct
decoder_control
*
dc
)
{
decoder_lock
(
dc
);
GError
*
error
=
dc_get_error
(
dc
);
decoder_unlock
(
dc
);
return
error
;
}
/**
* Clear the error condition and free the #GError object (if any).
*
* Caller must lock the object.
*/
static
inline
void
dc_clear_error
(
struct
decoder_control
*
dc
)
{
if
(
dc
->
state
==
DECODE_STATE_ERROR
)
{
g_error_free
(
dc
->
error
);
dc
->
state
=
DECODE_STATE_STOP
;
}
}
}
static
inline
bool
gcc_pure
decoder_lock_is_idle
(
struct
decoder_control
*
dc
)
bool
LockIsIdle
()
const
{
{
Lock
();
bool
ret
;
bool
result
=
IsIdle
();
Unlock
();
return
result
;
}
decoder_lock
(
dc
);
bool
IsStarting
()
const
{
ret
=
decoder_is_idle
(
dc
)
;
return
state
==
DECODE_STATE_START
;
decoder_unlock
(
dc
);
}
return
ret
;
gcc_pure
}
bool
LockIsStarting
()
const
{
Lock
();
bool
result
=
IsStarting
();
Unlock
();
return
result
;
}
static
inline
bool
bool
HasFailed
()
const
{
decoder_lock_is_starting
(
struct
decoder_control
*
dc
)
assert
(
command
==
DECODE_COMMAND_NONE
);
{
bool
ret
;
decoder_lock
(
dc
);
return
state
==
DECODE_STATE_ERROR
;
ret
=
decoder_is_starting
(
dc
);
}
decoder_unlock
(
dc
);
return
ret
;
gcc_pure
}
bool
LockHasFailed
()
const
{
Lock
();
bool
result
=
HasFailed
();
Unlock
();
return
result
;
}
static
inline
bool
/**
decoder_lock_has_failed
(
struct
decoder_control
*
dc
)
* Checks whether an error has occurred, and if so, returns a newly
{
* allocated copy of the #GError object.
bool
ret
;
*
* Caller must lock the object.
*/
GError
*
GetError
()
const
{
assert
(
command
==
DECODE_COMMAND_NONE
);
assert
(
state
!=
DECODE_STATE_ERROR
||
error
!=
nullptr
);
decoder_lock
(
dc
);
return
state
==
DECODE_STATE_ERROR
ret
=
decoder_has_failed
(
dc
);
?
g_error_copy
(
error
)
decoder_unlock
(
dc
);
:
nullptr
;
}
return
ret
;
/**
}
* Like dc_get_error(), but locks and unlocks the object.
*/
GError
*
LockGetError
()
const
{
Lock
();
GError
*
result
=
GetError
();
Unlock
();
return
result
;
}
/**
/**
* Check if the specified song is currently being decoded. If the
* Clear the error condition and free the #GError object (if any).
* decoder is not running currently (or being started), then this
*
* function returns false in any case.
* Caller must lock the object.
*
*/
* Caller must lock the object.
void
ClearError
()
{
*/
if
(
state
==
DECODE_STATE_ERROR
)
{
gcc_pure
g_error_free
(
error
);
bool
state
=
DECODE_STATE_STOP
;
decoder_is_current_song
(
const
struct
decoder_control
*
dc
,
}
const
struct
song
*
song
);
}
gcc_pure
static
inline
bool
decoder_lock_is_current_song
(
struct
decoder_control
*
dc
,
const
struct
song
*
song
)
{
decoder_lock
(
dc
);
const
bool
result
=
decoder_is_current_song
(
dc
,
song
);
decoder_unlock
(
dc
);
return
result
;
}
/**
* Start the decoder.
*
* @param the decoder
* @param song the song to be decoded; the given instance will be
* owned and freed by the decoder
* @param start_ms see #decoder_control
* @param end_ms see #decoder_control
* @param pipe the pipe which receives the decoded chunks (owned by
* the caller)
*/
void
dc_start
(
struct
decoder_control
*
dc
,
struct
song
*
song
,
unsigned
start_ms
,
unsigned
end_ms
,
struct
music_buffer
*
buffer
,
struct
music_pipe
*
pipe
);
void
/**
dc_stop
(
struct
decoder_control
*
dc
);
* Check if the specified song is currently being decoded. If the
* decoder is not running currently (or being started), then this
* function returns false in any case.
*
* Caller must lock the object.
*/
gcc_pure
bool
IsCurrentSong
(
const
struct
song
*
_song
)
const
;
gcc_pure
bool
LockIsCurrentSong
(
const
struct
song
*
_song
)
const
{
Lock
();
const
bool
result
=
IsCurrentSong
(
_song
);
Unlock
();
return
result
;
}
bool
/**
dc_seek
(
struct
decoder_control
*
dc
,
double
where
);
* Start the decoder.
*
* @param song the song to be decoded; the given instance will be
* owned and freed by the decoder
* @param start_ms see #decoder_control
* @param end_ms see #decoder_control
* @param pipe the pipe which receives the decoded chunks (owned by
* the caller)
*/
void
Start
(
struct
song
*
song
,
unsigned
start_ms
,
unsigned
end_ms
,
music_buffer
*
buffer
,
music_pipe
*
pipe
);
void
void
Stop
();
dc_quit
(
struct
decoder_control
*
dc
);
void
bool
Seek
(
double
where
);
dc_mixramp_start
(
struct
decoder_control
*
dc
,
char
*
mixramp_start
);
void
void
Quit
();
dc_mixramp_end
(
struct
decoder_control
*
dc
,
char
*
mixramp_end
);
void
void
MixRampStart
(
char
*
_mixramp_start
);
dc_mixramp_prev_end
(
struct
decoder_control
*
dc
,
char
*
mixramp_prev_end
);
void
MixRampEnd
(
char
*
_mixramp_end
);
void
MixRampPrevEnd
(
char
*
_mixramp_prev_end
);
};
#endif
#endif
src/DecoderInternal.cxx
View file @
32799fef
...
@@ -57,7 +57,7 @@ need_chunks(struct decoder_control *dc, bool do_wait)
...
@@ -57,7 +57,7 @@ need_chunks(struct decoder_control *dc, bool do_wait)
return
dc
->
command
;
return
dc
->
command
;
if
(
do_wait
)
{
if
(
do_wait
)
{
d
ecoder_wait
(
dc
);
d
c
->
Wait
(
);
g_cond_signal
(
dc
->
client_cond
);
g_cond_signal
(
dc
->
client_cond
);
return
dc
->
command
;
return
dc
->
command
;
...
@@ -89,9 +89,9 @@ decoder_get_chunk(struct decoder *decoder)
...
@@ -89,9 +89,9 @@ decoder_get_chunk(struct decoder *decoder)
return
decoder
->
chunk
;
return
decoder
->
chunk
;
}
}
d
ecoder_lock
(
dc
);
d
c
->
Lock
(
);
cmd
=
need_chunks
(
dc
,
true
);
cmd
=
need_chunks
(
dc
,
true
);
d
ecoder_unlock
(
dc
);
d
c
->
Unlock
(
);
}
while
(
cmd
==
DECODE_COMMAND_NONE
);
}
while
(
cmd
==
DECODE_COMMAND_NONE
);
return
NULL
;
return
NULL
;
...
...
src/DecoderThread.cxx
View file @
32799fef
...
@@ -91,18 +91,18 @@ decoder_input_stream_open(struct decoder_control *dc, const char *uri)
...
@@ -91,18 +91,18 @@ decoder_input_stream_open(struct decoder_control *dc, const char *uri)
/* wait for the input stream to become ready; its metadata
/* wait for the input stream to become ready; its metadata
will be available then */
will be available then */
d
ecoder_lock
(
dc
);
d
c
->
Lock
(
);
input_stream_update
(
is
);
input_stream_update
(
is
);
while
(
!
is
->
ready
&&
while
(
!
is
->
ready
&&
dc
->
command
!=
DECODE_COMMAND_STOP
)
{
dc
->
command
!=
DECODE_COMMAND_STOP
)
{
d
ecoder_wait
(
dc
);
d
c
->
Wait
(
);
input_stream_update
(
is
);
input_stream_update
(
is
);
}
}
if
(
!
input_stream_check
(
is
,
&
error
))
{
if
(
!
input_stream_check
(
is
,
&
error
))
{
d
ecoder_unlock
(
dc
);
d
c
->
Unlock
(
);
g_warning
(
"%s"
,
error
->
message
);
g_warning
(
"%s"
,
error
->
message
);
g_error_free
(
error
);
g_error_free
(
error
);
...
@@ -110,7 +110,7 @@ decoder_input_stream_open(struct decoder_control *dc, const char *uri)
...
@@ -110,7 +110,7 @@ decoder_input_stream_open(struct decoder_control *dc, const char *uri)
return
NULL
;
return
NULL
;
}
}
d
ecoder_unlock
(
dc
);
d
c
->
Unlock
(
);
return
is
;
return
is
;
}
}
...
@@ -137,11 +137,11 @@ decoder_stream_decode(const struct decoder_plugin *plugin,
...
@@ -137,11 +137,11 @@ decoder_stream_decode(const struct decoder_plugin *plugin,
/* rewind the stream, so each plugin gets a fresh start */
/* rewind the stream, so each plugin gets a fresh start */
input_stream_seek
(
input_stream
,
0
,
SEEK_SET
,
NULL
);
input_stream_seek
(
input_stream
,
0
,
SEEK_SET
,
NULL
);
decoder
_unlock
(
decoder
->
dc
);
decoder
->
dc
->
Unlock
(
);
decoder_plugin_stream_decode
(
plugin
,
decoder
,
input_stream
);
decoder_plugin_stream_decode
(
plugin
,
decoder
,
input_stream
);
decoder
_lock
(
decoder
->
dc
);
decoder
->
dc
->
Lock
(
);
assert
(
decoder
->
dc
->
state
==
DECODE_STATE_START
||
assert
(
decoder
->
dc
->
state
==
DECODE_STATE_START
||
decoder
->
dc
->
state
==
DECODE_STATE_DECODE
);
decoder
->
dc
->
state
==
DECODE_STATE_DECODE
);
...
@@ -167,11 +167,11 @@ decoder_file_decode(const struct decoder_plugin *plugin,
...
@@ -167,11 +167,11 @@ decoder_file_decode(const struct decoder_plugin *plugin,
if
(
decoder
->
dc
->
command
==
DECODE_COMMAND_STOP
)
if
(
decoder
->
dc
->
command
==
DECODE_COMMAND_STOP
)
return
true
;
return
true
;
decoder
_unlock
(
decoder
->
dc
);
decoder
->
dc
->
Unlock
(
);
decoder_plugin_file_decode
(
plugin
,
decoder
,
path
);
decoder_plugin_file_decode
(
plugin
,
decoder
,
path
);
decoder
_lock
(
decoder
->
dc
);
decoder
->
dc
->
Lock
(
);
assert
(
decoder
->
dc
->
state
==
DECODE_STATE_START
||
assert
(
decoder
->
dc
->
state
==
DECODE_STATE_START
||
decoder
->
dc
->
state
==
DECODE_STATE_DECODE
);
decoder
->
dc
->
state
==
DECODE_STATE_DECODE
);
...
@@ -280,15 +280,15 @@ decoder_run_stream(struct decoder *decoder, const char *uri)
...
@@ -280,15 +280,15 @@ decoder_run_stream(struct decoder *decoder, const char *uri)
struct
input_stream
*
input_stream
;
struct
input_stream
*
input_stream
;
bool
success
;
bool
success
;
d
ecoder_unlock
(
dc
);
d
c
->
Unlock
(
);
input_stream
=
decoder_input_stream_open
(
dc
,
uri
);
input_stream
=
decoder_input_stream_open
(
dc
,
uri
);
if
(
input_stream
==
NULL
)
{
if
(
input_stream
==
NULL
)
{
d
ecoder_lock
(
dc
);
d
c
->
Lock
(
);
return
false
;
return
false
;
}
}
d
ecoder_lock
(
dc
);
d
c
->
Lock
(
);
GSList
*
tried
=
NULL
;
GSList
*
tried
=
NULL
;
...
@@ -305,9 +305,9 @@ decoder_run_stream(struct decoder *decoder, const char *uri)
...
@@ -305,9 +305,9 @@ decoder_run_stream(struct decoder *decoder, const char *uri)
g_slist_free
(
tried
);
g_slist_free
(
tried
);
d
ecoder_unlock
(
dc
);
d
c
->
Unlock
(
);
input_stream_close
(
input_stream
);
input_stream_close
(
input_stream
);
d
ecoder_lock
(
dc
);
d
c
->
Lock
(
);
return
success
;
return
success
;
}
}
...
@@ -337,18 +337,18 @@ decoder_run_file(struct decoder *decoder, const char *path_fs)
...
@@ -337,18 +337,18 @@ decoder_run_file(struct decoder *decoder, const char *path_fs)
if
(
suffix
==
NULL
)
if
(
suffix
==
NULL
)
return
false
;
return
false
;
d
ecoder_unlock
(
dc
);
d
c
->
Unlock
(
);
decoder_load_replay_gain
(
decoder
,
path_fs
);
decoder_load_replay_gain
(
decoder
,
path_fs
);
while
((
plugin
=
decoder_plugin_from_suffix
(
suffix
,
plugin
))
!=
NULL
)
{
while
((
plugin
=
decoder_plugin_from_suffix
(
suffix
,
plugin
))
!=
NULL
)
{
if
(
plugin
->
file_decode
!=
NULL
)
{
if
(
plugin
->
file_decode
!=
NULL
)
{
d
ecoder_lock
(
dc
);
d
c
->
Lock
(
);
if
(
decoder_file_decode
(
plugin
,
decoder
,
path_fs
))
if
(
decoder_file_decode
(
plugin
,
decoder
,
path_fs
))
return
true
;
return
true
;
d
ecoder_unlock
(
dc
);
d
c
->
Unlock
(
);
}
else
if
(
plugin
->
stream_decode
!=
NULL
)
{
}
else
if
(
plugin
->
stream_decode
!=
NULL
)
{
struct
input_stream
*
input_stream
;
struct
input_stream
*
input_stream
;
bool
success
;
bool
success
;
...
@@ -357,23 +357,23 @@ decoder_run_file(struct decoder *decoder, const char *path_fs)
...
@@ -357,23 +357,23 @@ decoder_run_file(struct decoder *decoder, const char *path_fs)
if
(
input_stream
==
NULL
)
if
(
input_stream
==
NULL
)
continue
;
continue
;
d
ecoder_lock
(
dc
);
d
c
->
Lock
(
);
success
=
decoder_stream_decode
(
plugin
,
decoder
,
success
=
decoder_stream_decode
(
plugin
,
decoder
,
input_stream
);
input_stream
);
d
ecoder_unlock
(
dc
);
d
c
->
Unlock
(
);
input_stream_close
(
input_stream
);
input_stream_close
(
input_stream
);
if
(
success
)
{
if
(
success
)
{
d
ecoder_lock
(
dc
);
d
c
->
Lock
(
);
return
true
;
return
true
;
}
}
}
}
}
}
d
ecoder_lock
(
dc
);
d
c
->
Lock
(
);
return
false
;
return
false
;
}
}
...
@@ -394,14 +394,14 @@ decoder_run_song(struct decoder_control *dc,
...
@@ -394,14 +394,14 @@ decoder_run_song(struct decoder_control *dc,
?
decoder_run_file
(
&
decoder
,
uri
)
?
decoder_run_file
(
&
decoder
,
uri
)
:
decoder_run_stream
(
&
decoder
,
uri
);
:
decoder_run_stream
(
&
decoder
,
uri
);
d
ecoder_unlock
(
dc
);
d
c
->
Unlock
(
);
/* flush the last chunk */
/* flush the last chunk */
if
(
decoder
.
chunk
!=
NULL
)
if
(
decoder
.
chunk
!=
NULL
)
decoder_flush_chunk
(
&
decoder
);
decoder_flush_chunk
(
&
decoder
);
d
ecoder_lock
(
dc
);
d
c
->
Lock
(
);
if
(
ret
)
if
(
ret
)
dc
->
state
=
DECODE_STATE_STOP
;
dc
->
state
=
DECODE_STATE_STOP
;
...
@@ -424,7 +424,7 @@ decoder_run_song(struct decoder_control *dc,
...
@@ -424,7 +424,7 @@ decoder_run_song(struct decoder_control *dc,
static
void
static
void
decoder_run
(
struct
decoder_control
*
dc
)
decoder_run
(
struct
decoder_control
*
dc
)
{
{
dc
_clear_error
(
dc
);
dc
->
ClearError
(
);
const
struct
song
*
song
=
dc
->
song
;
const
struct
song
*
song
=
dc
->
song
;
char
*
uri
;
char
*
uri
;
...
@@ -455,7 +455,7 @@ decoder_task(gpointer arg)
...
@@ -455,7 +455,7 @@ decoder_task(gpointer arg)
{
{
struct
decoder_control
*
dc
=
(
struct
decoder_control
*
)
arg
;
struct
decoder_control
*
dc
=
(
struct
decoder_control
*
)
arg
;
d
ecoder_lock
(
dc
);
d
c
->
Lock
(
);
do
{
do
{
assert
(
dc
->
state
==
DECODE_STATE_STOP
||
assert
(
dc
->
state
==
DECODE_STATE_STOP
||
...
@@ -463,8 +463,8 @@ decoder_task(gpointer arg)
...
@@ -463,8 +463,8 @@ decoder_task(gpointer arg)
switch
(
dc
->
command
)
{
switch
(
dc
->
command
)
{
case
DECODE_COMMAND_START
:
case
DECODE_COMMAND_START
:
dc
_mixramp_start
(
dc
,
NULL
);
dc
->
MixRampStart
(
nullptr
);
dc
_mixramp_prev_end
(
dc
,
dc
->
mixramp_end
);
dc
->
MixRampPrevEnd
(
dc
->
mixramp_end
);
dc
->
mixramp_end
=
NULL
;
/* Don't free, it's copied above. */
dc
->
mixramp_end
=
NULL
;
/* Don't free, it's copied above. */
dc
->
replay_gain_prev_db
=
dc
->
replay_gain_db
;
dc
->
replay_gain_prev_db
=
dc
->
replay_gain_db
;
dc
->
replay_gain_db
=
0
;
dc
->
replay_gain_db
=
0
;
...
@@ -480,12 +480,12 @@ decoder_task(gpointer arg)
...
@@ -480,12 +480,12 @@ decoder_task(gpointer arg)
break
;
break
;
case
DECODE_COMMAND_NONE
:
case
DECODE_COMMAND_NONE
:
d
ecoder_wait
(
dc
);
d
c
->
Wait
(
);
break
;
break
;
}
}
}
while
(
dc
->
command
!=
DECODE_COMMAND_NONE
||
!
dc
->
quit
);
}
while
(
dc
->
command
!=
DECODE_COMMAND_NONE
||
!
dc
->
quit
);
d
ecoder_unlock
(
dc
);
d
c
->
Unlock
(
);
return
NULL
;
return
NULL
;
}
}
...
...
src/PlayerThread.cxx
View file @
32799fef
...
@@ -176,9 +176,9 @@ player_dc_start(struct player *player, struct music_pipe *pipe)
...
@@ -176,9 +176,9 @@ player_dc_start(struct player *player, struct music_pipe *pipe)
if
(
pc
->
command
==
PLAYER_COMMAND_SEEK
)
if
(
pc
->
command
==
PLAYER_COMMAND_SEEK
)
start_ms
+=
(
unsigned
)(
pc
->
seek_where
*
1000
);
start_ms
+=
(
unsigned
)(
pc
->
seek_where
*
1000
);
dc
_start
(
dc
,
song_dup_detached
(
pc
->
next_song
),
dc
->
Start
(
song_dup_detached
(
pc
->
next_song
),
start_ms
,
pc
->
next_song
->
end_ms
,
start_ms
,
pc
->
next_song
->
end_ms
,
player_buffer
,
pipe
);
player_buffer
,
pipe
);
}
}
/**
/**
...
@@ -217,7 +217,7 @@ player_dc_stop(struct player *player)
...
@@ -217,7 +217,7 @@ player_dc_stop(struct player *player)
{
{
struct
decoder_control
*
dc
=
player
->
dc
;
struct
decoder_control
*
dc
=
player
->
dc
;
dc
_stop
(
dc
);
dc
->
Stop
(
);
if
(
dc
->
pipe
!=
NULL
)
{
if
(
dc
->
pipe
!=
NULL
)
{
/* clear and free the decoder pipe */
/* clear and free the decoder pipe */
...
@@ -249,7 +249,7 @@ player_wait_for_decoder(struct player *player)
...
@@ -249,7 +249,7 @@ player_wait_for_decoder(struct player *player)
player
->
queued
=
false
;
player
->
queued
=
false
;
GError
*
error
=
dc
_lock_get_error
(
dc
);
GError
*
error
=
dc
->
LockGetError
(
);
if
(
error
!=
NULL
)
{
if
(
error
!=
NULL
)
{
pc
->
Lock
();
pc
->
Lock
();
pc
->
SetError
(
PLAYER_ERROR_DECODER
,
error
);
pc
->
SetError
(
PLAYER_ERROR_DECODER
,
error
);
...
@@ -369,22 +369,22 @@ player_check_decoder_startup(struct player *player)
...
@@ -369,22 +369,22 @@ player_check_decoder_startup(struct player *player)
assert
(
player
->
decoder_starting
);
assert
(
player
->
decoder_starting
);
d
ecoder_lock
(
dc
);
d
c
->
Lock
(
);
GError
*
error
=
dc
_get_error
(
dc
);
GError
*
error
=
dc
->
GetError
(
);
if
(
error
!=
NULL
)
{
if
(
error
!=
NULL
)
{
/* the decoder failed */
/* the decoder failed */
d
ecoder_unlock
(
dc
);
d
c
->
Unlock
(
);
pc
->
Lock
();
pc
->
Lock
();
pc
->
SetError
(
PLAYER_ERROR_DECODER
,
error
);
pc
->
SetError
(
PLAYER_ERROR_DECODER
,
error
);
pc
->
Unlock
();
pc
->
Unlock
();
return
false
;
return
false
;
}
else
if
(
!
d
ecoder_is_starting
(
dc
))
{
}
else
if
(
!
d
c
->
IsStarting
(
))
{
/* the decoder is ready and ok */
/* the decoder is ready and ok */
d
ecoder_unlock
(
dc
);
d
c
->
Unlock
(
);
if
(
player
->
output_open
&&
if
(
player
->
output_open
&&
!
audio_output_all_wait
(
pc
,
1
))
!
audio_output_all_wait
(
pc
,
1
))
...
@@ -414,7 +414,7 @@ player_check_decoder_startup(struct player *player)
...
@@ -414,7 +414,7 @@ player_check_decoder_startup(struct player *player)
/* the decoder is not yet ready; wait
/* the decoder is not yet ready; wait
some more */
some more */
dc
->
WaitForDecoder
();
dc
->
WaitForDecoder
();
d
ecoder_unlock
(
dc
);
d
c
->
Unlock
(
);
return
true
;
return
true
;
}
}
...
@@ -480,7 +480,7 @@ static bool player_seek_decoder(struct player *player)
...
@@ -480,7 +480,7 @@ static bool player_seek_decoder(struct player *player)
const
unsigned
start_ms
=
song
->
start_ms
;
const
unsigned
start_ms
=
song
->
start_ms
;
if
(
!
d
ecoder_lock_is_current_song
(
dc
,
song
))
{
if
(
!
d
c
->
LockIsCurrentSong
(
song
))
{
/* the decoder is already decoding the "next" song -
/* the decoder is already decoding the "next" song -
stop it and start the previous song again */
stop it and start the previous song again */
...
@@ -529,7 +529,7 @@ static bool player_seek_decoder(struct player *player)
...
@@ -529,7 +529,7 @@ static bool player_seek_decoder(struct player *player)
if
(
where
<
0.0
)
if
(
where
<
0.0
)
where
=
0.0
;
where
=
0.0
;
if
(
!
dc
_seek
(
dc
,
where
+
start_ms
/
1000.0
))
{
if
(
!
dc
->
Seek
(
where
+
start_ms
/
1000.0
))
{
/* decoder failure */
/* decoder failure */
player_command_finished
(
pc
);
player_command_finished
(
pc
);
return
false
;
return
false
;
...
@@ -782,19 +782,19 @@ play_next_chunk(struct player *player)
...
@@ -782,19 +782,19 @@ play_next_chunk(struct player *player)
}
else
{
}
else
{
/* there are not enough decoded chunks yet */
/* there are not enough decoded chunks yet */
d
ecoder_lock
(
dc
);
d
c
->
Lock
(
);
if
(
d
ecoder_is_idle
(
dc
))
{
if
(
d
c
->
IsIdle
(
))
{
/* the decoder isn't running, abort
/* the decoder isn't running, abort
cross fading */
cross fading */
d
ecoder_unlock
(
dc
);
d
c
->
Unlock
(
);
player
->
xfade
=
XFADE_DISABLED
;
player
->
xfade
=
XFADE_DISABLED
;
}
else
{
}
else
{
/* wait for the decoder */
/* wait for the decoder */
d
ecoder_signal
(
dc
);
d
c
->
Signal
(
);
dc
->
WaitForDecoder
();
dc
->
WaitForDecoder
();
d
ecoder_unlock
(
dc
);
d
c
->
Unlock
(
);
return
true
;
return
true
;
}
}
...
@@ -840,12 +840,12 @@ play_next_chunk(struct player *player)
...
@@ -840,12 +840,12 @@ play_next_chunk(struct player *player)
/* this formula should prevent that the decoder gets woken up
/* this formula should prevent that the decoder gets woken up
with each chunk; it is more efficient to make it decode a
with each chunk; it is more efficient to make it decode a
larger block at a time */
larger block at a time */
d
ecoder_lock
(
dc
);
d
c
->
Lock
(
);
if
(
!
d
ecoder_is_idle
(
dc
)
&&
if
(
!
d
c
->
IsIdle
(
)
&&
music_pipe_size
(
dc
->
pipe
)
<=
(
pc
->
buffered_before_play
+
music_pipe_size
(
dc
->
pipe
)
<=
(
pc
->
buffered_before_play
+
music_buffer_size
(
player_buffer
)
*
3
)
/
4
)
music_buffer_size
(
player_buffer
)
*
3
)
/
4
)
d
ecoder_signal
(
dc
);
d
c
->
Signal
(
);
d
ecoder_unlock
(
dc
);
d
c
->
Unlock
(
);
return
true
;
return
true
;
}
}
...
@@ -940,7 +940,7 @@ static void do_play(struct player_control *pc, struct decoder_control *dc)
...
@@ -940,7 +940,7 @@ static void do_play(struct player_control *pc, struct decoder_control *dc)
prevent stuttering on slow machines */
prevent stuttering on slow machines */
if
(
music_pipe_size
(
player
.
pipe
)
<
pc
->
buffered_before_play
&&
if
(
music_pipe_size
(
player
.
pipe
)
<
pc
->
buffered_before_play
&&
!
d
ecoder_lock_is_idle
(
dc
))
{
!
d
c
->
LockIsIdle
(
))
{
/* not enough decoded buffer space yet */
/* not enough decoded buffer space yet */
if
(
!
player
.
paused
&&
if
(
!
player
.
paused
&&
...
@@ -949,10 +949,10 @@ static void do_play(struct player_control *pc, struct decoder_control *dc)
...
@@ -949,10 +949,10 @@ static void do_play(struct player_control *pc, struct decoder_control *dc)
!
player_send_silence
(
&
player
))
!
player_send_silence
(
&
player
))
break
;
break
;
d
ecoder_lock
(
dc
);
d
c
->
Lock
(
);
/* XXX race condition: check decoder again */
/* XXX race condition: check decoder again */
dc
->
WaitForDecoder
();
dc
->
WaitForDecoder
();
d
ecoder_unlock
(
dc
);
d
c
->
Unlock
(
);
pc
->
Lock
();
pc
->
Lock
();
continue
;
continue
;
}
else
{
}
else
{
...
@@ -979,7 +979,7 @@ static void do_play(struct player_control *pc, struct decoder_control *dc)
...
@@ -979,7 +979,7 @@ static void do_play(struct player_control *pc, struct decoder_control *dc)
*/
*/
#endif
#endif
if
(
d
ecoder_lock_is_idle
(
dc
)
&&
player
.
queued
&&
if
(
d
c
->
LockIsIdle
(
)
&&
player
.
queued
&&
dc
->
pipe
==
player
.
pipe
)
{
dc
->
pipe
==
player
.
pipe
)
{
/* the decoder has finished the current song;
/* the decoder has finished the current song;
make it decode the next song */
make it decode the next song */
...
@@ -994,7 +994,7 @@ static void do_play(struct player_control *pc, struct decoder_control *dc)
...
@@ -994,7 +994,7 @@ static void do_play(struct player_control *pc, struct decoder_control *dc)
!
pc
->
border_pause
&&
!
pc
->
border_pause
&&
player_dc_at_next_song
(
&
player
)
&&
player_dc_at_next_song
(
&
player
)
&&
player
.
xfade
==
XFADE_UNKNOWN
&&
player
.
xfade
==
XFADE_UNKNOWN
&&
!
d
ecoder_lock_is_starting
(
dc
))
{
!
d
c
->
LockIsStarting
(
))
{
/* enable cross fading in this song? if yes,
/* enable cross fading in this song? if yes,
calculate how many chunks will be required
calculate how many chunks will be required
for it */
for it */
...
@@ -1042,7 +1042,7 @@ static void do_play(struct player_control *pc, struct decoder_control *dc)
...
@@ -1042,7 +1042,7 @@ static void do_play(struct player_control *pc, struct decoder_control *dc)
if
(
!
player_song_border
(
&
player
))
if
(
!
player_song_border
(
&
player
))
break
;
break
;
}
else
if
(
d
ecoder_lock_is_idle
(
dc
))
{
}
else
if
(
d
c
->
LockIsIdle
(
))
{
/* check the size of the pipe again, because
/* check the size of the pipe again, because
the decoder thread may have added something
the decoder thread may have added something
since we last checked */
since we last checked */
...
@@ -1096,7 +1096,7 @@ player_task(gpointer arg)
...
@@ -1096,7 +1096,7 @@ player_task(gpointer arg)
{
{
struct
player_control
*
pc
=
(
struct
player_control
*
)
arg
;
struct
player_control
*
pc
=
(
struct
player_control
*
)
arg
;
struct
decoder_control
*
dc
=
dc_new
();
struct
decoder_control
*
dc
=
new
decoder_control
();
decoder_thread_start
(
dc
);
decoder_thread_start
(
dc
);
player_buffer
=
music_buffer_new
(
pc
->
buffer_chunks
);
player_buffer
=
music_buffer_new
(
pc
->
buffer_chunks
);
...
@@ -1156,8 +1156,8 @@ player_task(gpointer arg)
...
@@ -1156,8 +1156,8 @@ player_task(gpointer arg)
case
PLAYER_COMMAND_EXIT
:
case
PLAYER_COMMAND_EXIT
:
pc
->
Unlock
();
pc
->
Unlock
();
dc
_quit
(
dc
);
dc
->
Quit
(
);
d
c_free
(
dc
)
;
d
elete
dc
;
audio_output_all_close
();
audio_output_all_close
();
music_buffer_free
(
player_buffer
);
music_buffer_free
(
player_buffer
);
...
...
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