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
3216f4b2
Commit
3216f4b2
authored
Sep 26, 2013
by
Max Kellermann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
MusicBuffer: expose the C++ API
parent
ce1d8975
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
95 additions
and
118 deletions
+95
-118
DecoderAPI.cxx
src/DecoderAPI.cxx
+2
-2
DecoderControl.cxx
src/DecoderControl.cxx
+2
-3
DecoderControl.hxx
src/DecoderControl.hxx
+3
-2
DecoderInternal.cxx
src/DecoderInternal.cxx
+2
-2
MusicBuffer.cxx
src/MusicBuffer.cxx
+13
-39
MusicBuffer.hxx
src/MusicBuffer.hxx
+40
-35
MusicPipe.cxx
src/MusicPipe.cxx
+2
-2
MusicPipe.hxx
src/MusicPipe.hxx
+2
-2
OutputAll.cxx
src/OutputAll.cxx
+9
-10
OutputAll.hxx
src/OutputAll.hxx
+2
-2
PlayerThread.cxx
src/PlayerThread.cxx
+18
-19
No files found.
src/DecoderAPI.cxx
View file @
3216f4b2
...
...
@@ -178,11 +178,11 @@ decoder_command_finished(struct decoder *decoder)
/* delete frames from the old song position */
if
(
decoder
->
chunk
!=
NULL
)
{
music_buffer_return
(
dc
->
buffer
,
decoder
->
chunk
);
dc
->
buffer
->
Return
(
decoder
->
chunk
);
decoder
->
chunk
=
NULL
;
}
dc
->
pipe
->
Clear
(
dc
->
buffer
);
dc
->
pipe
->
Clear
(
*
dc
->
buffer
);
decoder
->
timestamp
=
dc
->
seek_where
;
}
...
...
src/DecoderControl.cxx
View file @
3216f4b2
...
...
@@ -105,10 +105,9 @@ decoder_control::IsCurrentSong(const Song *_song) const
void
decoder_control
::
Start
(
Song
*
_song
,
unsigned
_start_ms
,
unsigned
_end_ms
,
music_buffer
*
_buffer
,
MusicPipe
&
_pipe
)
MusicBuffer
&
_buffer
,
MusicPipe
&
_pipe
)
{
assert
(
_song
!=
NULL
);
assert
(
_buffer
!=
NULL
);
assert
(
_pipe
.
IsEmpty
());
if
(
song
!=
nullptr
)
...
...
@@ -117,7 +116,7 @@ decoder_control::Start(Song *_song,
song
=
_song
;
start_ms
=
_start_ms
;
end_ms
=
_end_ms
;
buffer
=
_buffer
;
buffer
=
&
_buffer
;
pipe
=
&
_pipe
;
dc_command
(
this
,
DECODE_COMMAND_START
);
...
...
src/DecoderControl.hxx
View file @
3216f4b2
...
...
@@ -31,6 +31,7 @@
#include <assert.h>
struct
Song
;
class
MusicBuffer
;
class
MusicPipe
;
enum
decoder_state
{
...
...
@@ -122,7 +123,7 @@ struct decoder_control {
float
total_time
;
/** the #music_chunk allocator */
struct
music_b
uffer
*
buffer
;
MusicB
uffer
*
buffer
;
/**
* The destination pipe for decoded chunks. The caller thread
...
...
@@ -288,7 +289,7 @@ struct decoder_control {
* the caller)
*/
void
Start
(
Song
*
song
,
unsigned
start_ms
,
unsigned
end_ms
,
music_buffer
*
buffer
,
MusicPipe
&
pipe
);
MusicBuffer
&
buffer
,
MusicPipe
&
pipe
);
void
Stop
();
...
...
src/DecoderInternal.cxx
View file @
3216f4b2
...
...
@@ -70,7 +70,7 @@ decoder_get_chunk(struct decoder *decoder)
return
decoder
->
chunk
;
do
{
decoder
->
chunk
=
music_buffer_allocate
(
dc
->
buffer
);
decoder
->
chunk
=
dc
->
buffer
->
Allocate
(
);
if
(
decoder
->
chunk
!=
NULL
)
{
decoder
->
chunk
->
replay_gain_serial
=
decoder
->
replay_gain_serial
;
...
...
@@ -98,7 +98,7 @@ decoder_flush_chunk(struct decoder *decoder)
assert
(
decoder
->
chunk
!=
NULL
);
if
(
decoder
->
chunk
->
IsEmpty
())
music_buffer_return
(
dc
->
buffer
,
decoder
->
chunk
);
dc
->
buffer
->
Return
(
decoder
->
chunk
);
else
dc
->
pipe
->
Push
(
decoder
->
chunk
);
...
...
src/MusicBuffer.cxx
View file @
3216f4b2
...
...
@@ -20,60 +20,34 @@
#include "config.h"
#include "MusicBuffer.hxx"
#include "MusicChunk.hxx"
#include "thread/Mutex.hxx"
#include "util/SliceBuffer.hxx"
#include "system/FatalError.hxx"
#include <assert.h>
struct
music_buffer
:
public
SliceBuffer
<
music_chunk
>
{
/** a mutex which protects #available */
Mutex
mutex
;
music_buffer
(
unsigned
num_chunks
)
:
SliceBuffer
(
num_chunks
)
{
if
(
IsOOM
())
FatalError
(
"Failed to allocate buffer"
);
}
};
struct
music_buffer
*
music_buffer_new
(
unsigned
num_chunks
)
{
return
new
music_buffer
(
num_chunks
);
}
void
music_buffer_free
(
struct
music_buffer
*
buffer
)
{
delete
buffer
;
}
unsigned
music_buffer_size
(
const
struct
music_buffer
*
buffer
)
{
return
buffer
->
GetCapacity
();
MusicBuffer
::
MusicBuffer
(
unsigned
num_chunks
)
:
buffer
(
num_chunks
)
{
if
(
buffer
.
IsOOM
())
FatalError
(
"Failed to allocate buffer"
);
}
struct
music_chunk
*
music_buffer_allocate
(
struct
music_buffer
*
buffer
)
music_chunk
*
MusicBuffer
::
Allocate
(
)
{
const
ScopeLock
protect
(
buffer
->
mutex
);
return
buffer
->
Allocate
();
const
ScopeLock
protect
(
mutex
);
return
buffer
.
Allocate
();
}
void
music_buffer_return
(
struct
music_buffer
*
buffer
,
struct
music_chunk
*
chunk
)
MusicBuffer
::
Return
(
music_chunk
*
chunk
)
{
assert
(
buffer
!=
NULL
);
assert
(
chunk
!=
NULL
);
assert
(
chunk
!=
nullptr
);
const
ScopeLock
protect
(
buffer
->
mutex
);
const
ScopeLock
protect
(
mutex
);
if
(
chunk
->
other
!=
nullptr
)
{
assert
(
chunk
->
other
->
other
==
nullptr
);
buffer
->
Free
(
chunk
->
other
);
buffer
.
Free
(
chunk
->
other
);
}
buffer
->
Free
(
chunk
);
buffer
.
Free
(
chunk
);
}
src/MusicBuffer.hxx
View file @
3216f4b2
...
...
@@ -20,48 +20,53 @@
#ifndef MPD_MUSIC_BUFFER_HXX
#define MPD_MUSIC_BUFFER_HXX
#include "util/SliceBuffer.hxx"
#include "thread/Mutex.hxx"
struct
music_chunk
;
/**
* An allocator for #music_chunk objects.
*/
struct
music_buffer
;
class
MusicBuffer
{
/** a mutex which protects #buffer */
Mutex
mutex
;
/**
* Creates a new #music_buffer object.
*
* @param num_chunks the number of #music_chunk reserved in this
* buffer
*/
struct
music_buffer
*
music_buffer_new
(
unsigned
num_chunks
);
SliceBuffer
<
music_chunk
>
buffer
;
/**
* Frees the #music_buffer object
*/
void
music_buffer_free
(
struct
music_buffer
*
buffer
);
public
:
/**
* Creates a new #MusicBuffer object.
*
* @param num_chunks the number of #music_chunk reserved in
* this buffer
*/
MusicBuffer
(
unsigned
num_chunks
);
/**
* Returns the total number of reserved chunks in this buffer. This
* is the same value which was passed to the constructor
* music_buffer_new().
*/
unsigned
music_buffer_size
(
const
struct
music_buffer
*
buffer
);
/**
* Returns the total number of reserved chunks in this buffer. This
* is the same value which was passed to the constructor
* music_buffer_new().
*/
gcc_pure
unsigned
GetSize
()
const
{
return
buffer
.
GetCapacity
();
}
/**
* Allocates a chunk from the buffer. When it is not used anymore,
* call music_buffer_r
eturn().
*
* @return an empty chunk or NULL if there are no chunks available
*/
struct
music_chunk
*
music_buffer_allocate
(
struct
music_buffer
*
buffer
);
/**
* Allocates a chunk from the buffer. When it is not used anymore,
* call R
eturn().
*
* @return an empty chunk or nullptr if there are no chunks
* available
*/
music_chunk
*
Allocate
(
);
/**
* Returns a chunk to the buffer. It can be reused by
* music_buffer_a
llocate() then.
*/
void
music_buffer_return
(
struct
music_buffer
*
buffer
,
struct
music_chunk
*
chunk
)
;
/**
* Returns a chunk to the buffer. It can be reused by
* A
llocate() then.
*/
void
Return
(
music_chunk
*
chunk
);
}
;
#endif
src/MusicPipe.cxx
View file @
3216f4b2
...
...
@@ -73,12 +73,12 @@ MusicPipe::Shift()
}
void
MusicPipe
::
Clear
(
music_buffer
*
buffer
)
MusicPipe
::
Clear
(
MusicBuffer
&
buffer
)
{
music_chunk
*
chunk
;
while
((
chunk
=
Shift
())
!=
nullptr
)
music_buffer_return
(
buffer
,
chunk
);
buffer
.
Return
(
chunk
);
}
void
...
...
src/MusicPipe.hxx
View file @
3216f4b2
...
...
@@ -30,7 +30,7 @@
#include <assert.h>
struct
music_chunk
;
struct
music_b
uffer
;
class
MusicB
uffer
;
/**
* A queue of #music_chunk objects. One party appends chunks at the
...
...
@@ -109,7 +109,7 @@ public:
*
* @param buffer the buffer object to return the chunks to
*/
void
Clear
(
music_buffer
*
buffer
);
void
Clear
(
MusicBuffer
&
buffer
);
/**
* Pushes a chunk to the tail of the pipe.
...
...
src/OutputAll.cxx
View file @
3216f4b2
...
...
@@ -45,9 +45,9 @@ static struct audio_output **audio_outputs;
static
unsigned
int
num_audio_outputs
;
/**
* The #
music_b
uffer object where consumed chunks are returned.
* The #
MusicB
uffer object where consumed chunks are returned.
*/
static
struct
music_b
uffer
*
g_music_buffer
;
static
MusicB
uffer
*
g_music_buffer
;
/**
* The #MusicPipe object which feeds all audio outputs. It is filled
...
...
@@ -302,17 +302,16 @@ audio_output_all_play(struct music_chunk *chunk, Error &error)
bool
audio_output_all_open
(
const
AudioFormat
audio_format
,
struct
music_buffer
*
buffer
,
MusicBuffer
&
buffer
,
Error
&
error
)
{
bool
ret
=
false
,
enabled
=
false
;
unsigned
int
i
;
assert
(
buffer
!=
NULL
);
assert
(
g_music_buffer
==
NULL
||
g_music_buffer
==
buffer
);
assert
(
g_music_buffer
==
NULL
||
g_music_buffer
==
&
buffer
);
assert
((
g_mp
==
NULL
)
==
(
g_music_buffer
==
NULL
));
g_music_buffer
=
buffer
;
g_music_buffer
=
&
buffer
;
/* the audio format must be the same as existing chunks in the
pipe */
...
...
@@ -463,7 +462,7 @@ audio_output_all_check(void)
audio_outputs
[
i
]
->
mutex
.
unlock
();
/* return the chunk to the buffer */
music_buffer_return
(
g_music_buffer
,
shifted
);
g_music_buffer
->
Return
(
shifted
);
}
return
0
;
...
...
@@ -522,7 +521,7 @@ audio_output_all_cancel(void)
/* clear the music pipe and return all chunks to the buffer */
if
(
g_mp
!=
NULL
)
g_mp
->
Clear
(
g_music_buffer
);
g_mp
->
Clear
(
*
g_music_buffer
);
/* the audio outputs are now waiting for a signal, to
synchronize the cleared music pipe */
...
...
@@ -545,7 +544,7 @@ audio_output_all_close(void)
if
(
g_mp
!=
NULL
)
{
assert
(
g_music_buffer
!=
NULL
);
g_mp
->
Clear
(
g_music_buffer
);
g_mp
->
Clear
(
*
g_music_buffer
);
delete
g_mp
;
g_mp
=
NULL
;
}
...
...
@@ -568,7 +567,7 @@ audio_output_all_release(void)
if
(
g_mp
!=
NULL
)
{
assert
(
g_music_buffer
!=
NULL
);
g_mp
->
Clear
(
g_music_buffer
);
g_mp
->
Clear
(
*
g_music_buffer
);
delete
g_mp
;
g_mp
=
NULL
;
}
...
...
src/OutputAll.hxx
View file @
3216f4b2
...
...
@@ -29,7 +29,7 @@
#include "replay_gain_info.h"
struct
AudioFormat
;
struct
music_b
uffer
;
class
MusicB
uffer
;
struct
music_chunk
;
struct
player_control
;
class
Error
;
...
...
@@ -83,7 +83,7 @@ audio_output_all_enable_disable(void);
*/
bool
audio_output_all_open
(
AudioFormat
audio_format
,
struct
music_buffer
*
buffer
,
MusicBuffer
&
buffer
,
Error
&
error
);
/**
...
...
src/PlayerThread.cxx
View file @
3216f4b2
...
...
@@ -141,7 +141,7 @@ struct player {
elapsed_time
(
0.0
)
{}
};
static
struct
music_b
uffer
*
player_buffer
;
static
MusicB
uffer
*
player_buffer
;
static
void
player_command_finished_locked
(
struct
player_control
*
pc
)
...
...
@@ -180,7 +180,7 @@ player_dc_start(struct player *player, MusicPipe &pipe)
dc
->
Start
(
pc
->
next_song
->
DupDetached
(),
start_ms
,
pc
->
next_song
->
end_ms
,
player_buffer
,
pipe
);
*
player_buffer
,
pipe
);
}
/**
...
...
@@ -224,7 +224,7 @@ player_dc_stop(struct player *player)
if
(
dc
->
pipe
!=
NULL
)
{
/* clear and free the decoder pipe */
dc
->
pipe
->
Clear
(
player_buffer
);
dc
->
pipe
->
Clear
(
*
player_buffer
);
if
(
dc
->
pipe
!=
player
->
pipe
)
delete
dc
->
pipe
;
...
...
@@ -328,7 +328,7 @@ player_open_output(struct player *player)
pc
->
state
==
PLAYER_STATE_PAUSE
);
Error
error
;
if
(
audio_output_all_open
(
player
->
play_audio_format
,
player_buffer
,
if
(
audio_output_all_open
(
player
->
play_audio_format
,
*
player_buffer
,
error
))
{
player
->
output_open
=
true
;
player
->
paused
=
false
;
...
...
@@ -441,7 +441,7 @@ player_send_silence(struct player *player)
assert
(
player
->
output_open
);
assert
(
player
->
play_audio_format
.
IsDefined
());
struct
music_chunk
*
chunk
=
music_buffer_allocate
(
player_buffer
);
struct
music_chunk
*
chunk
=
player_buffer
->
Allocate
(
);
if
(
chunk
==
NULL
)
{
g_warning
(
"Failed to allocate silence buffer"
);
return
false
;
...
...
@@ -463,7 +463,7 @@ player_send_silence(struct player *player)
Error
error
;
if
(
!
audio_output_all_play
(
chunk
,
error
))
{
g_warning
(
"%s"
,
error
.
GetMessage
());
music_buffer_return
(
player_buffer
,
chunk
);
player_buffer
->
Return
(
chunk
);
return
false
;
}
...
...
@@ -493,7 +493,7 @@ static bool player_seek_decoder(struct player *player)
/* clear music chunks which might still reside in the
pipe */
player
->
pipe
->
Clear
(
player_buffer
);
player
->
pipe
->
Clear
(
*
player_buffer
);
/* re-start the decoder */
player_dc_start
(
player
,
*
player
->
pipe
);
...
...
@@ -506,7 +506,7 @@ static bool player_seek_decoder(struct player *player)
if
(
!
player_dc_at_current_song
(
player
))
{
/* the decoder is already decoding the "next" song,
but it is the same song file; exchange the pipe */
player
->
pipe
->
Clear
(
player_buffer
);
player
->
pipe
->
Clear
(
*
player_buffer
);
delete
player
->
pipe
;
player
->
pipe
=
dc
->
pipe
;
}
...
...
@@ -695,7 +695,7 @@ play_chunk(struct player_control *pc,
update_song_tag
(
song
,
*
chunk
->
tag
);
if
(
chunk
->
length
==
0
)
{
music_buffer_return
(
player_buffer
,
chunk
);
player_buffer
->
Return
(
chunk
);
return
true
;
}
...
...
@@ -776,8 +776,7 @@ play_next_chunk(struct player *player)
beginning of the new song, we can
easily recover by throwing it away
now */
music_buffer_return
(
player_buffer
,
other_chunk
);
player_buffer
->
Return
(
other_chunk
);
other_chunk
=
NULL
;
}
...
...
@@ -824,7 +823,7 @@ play_next_chunk(struct player *player)
player
->
play_audio_format
,
error
))
{
g_warning
(
"%s"
,
error
.
GetMessage
());
music_buffer_return
(
player_buffer
,
chunk
);
player_buffer
->
Return
(
chunk
);
pc
->
Lock
();
...
...
@@ -848,7 +847,7 @@ play_next_chunk(struct player *player)
dc
->
Lock
();
if
(
!
dc
->
IsIdle
()
&&
dc
->
pipe
->
GetSize
()
<=
(
pc
->
buffered_before_play
+
music_buffer_size
(
player_buffer
)
*
3
)
/
4
)
player_buffer
->
GetSize
(
)
*
3
)
/
4
)
dc
->
Signal
();
dc
->
Unlock
();
...
...
@@ -1017,7 +1016,7 @@ static void do_play(struct player_control *pc, struct decoder_control *dc)
dc
->
mixramp_prev_end
,
dc
->
out_audio_format
,
player
.
play_audio_format
,
music_buffer_size
(
player_buffer
)
-
player_buffer
->
GetSize
(
)
-
pc
->
buffered_before_play
);
if
(
player
.
cross_fade_chunks
>
0
)
{
player
.
xfade
=
XFADE_ENABLED
;
...
...
@@ -1074,7 +1073,7 @@ static void do_play(struct player_control *pc, struct decoder_control *dc)
player_dc_stop
(
&
player
);
player
.
pipe
->
Clear
(
player_buffer
);
player
.
pipe
->
Clear
(
*
player_buffer
);
delete
player
.
pipe
;
delete
player
.
cross_fade_tag
;
...
...
@@ -1107,7 +1106,7 @@ player_task(gpointer arg)
struct
decoder_control
*
dc
=
new
decoder_control
();
decoder_thread_start
(
dc
);
player_buffer
=
music_buffer_new
(
pc
->
buffer_chunks
);
player_buffer
=
new
MusicBuffer
(
pc
->
buffer_chunks
);
pc
->
Lock
();
...
...
@@ -1148,8 +1147,8 @@ player_task(gpointer arg)
/* in the DEBUG build, check for leaked
music_chunk objects by freeing the
music_buffer */
music_buffer_free
(
player_buffer
)
;
player_buffer
=
music_buffer_new
(
pc
->
buffer_chunks
);
delete
player_buffer
;
player_buffer
=
new
MusicBuffer
(
pc
->
buffer_chunks
);
#endif
break
;
...
...
@@ -1167,7 +1166,7 @@ player_task(gpointer arg)
dc
->
Quit
();
delete
dc
;
audio_output_all_close
();
music_buffer_free
(
player_buffer
)
;
delete
player_buffer
;
player_command_finished
(
pc
);
return
NULL
;
...
...
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