aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2013-09-26 22:09:42 +0200
committerMax Kellermann <max@duempel.org>2013-09-26 22:21:56 +0200
commit3216f4b25753d566793173c7a4f53a126ac37744 (patch)
tree5a151a5c6f1750011279b50f0c8478787dac46e8
parentce1d8975751251d49581129193e09490ca650a8b (diff)
downloadmpd-3216f4b25753d566793173c7a4f53a126ac37744.tar.gz
mpd-3216f4b25753d566793173c7a4f53a126ac37744.tar.xz
mpd-3216f4b25753d566793173c7a4f53a126ac37744.zip
MusicBuffer: expose the C++ API
-rw-r--r--src/DecoderAPI.cxx4
-rw-r--r--src/DecoderControl.cxx5
-rw-r--r--src/DecoderControl.hxx5
-rw-r--r--src/DecoderInternal.cxx4
-rw-r--r--src/MusicBuffer.cxx52
-rw-r--r--src/MusicBuffer.hxx75
-rw-r--r--src/MusicPipe.cxx4
-rw-r--r--src/MusicPipe.hxx4
-rw-r--r--src/OutputAll.cxx19
-rw-r--r--src/OutputAll.hxx4
-rw-r--r--src/PlayerThread.cxx37
11 files changed, 95 insertions, 118 deletions
diff --git a/src/DecoderAPI.cxx b/src/DecoderAPI.cxx
index 68ccd524c..71c3d0497 100644
--- a/src/DecoderAPI.cxx
+++ b/src/DecoderAPI.cxx
@@ -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;
}
diff --git a/src/DecoderControl.cxx b/src/DecoderControl.cxx
index 8643bb916..5fea70908 100644
--- a/src/DecoderControl.cxx
+++ b/src/DecoderControl.cxx
@@ -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);
diff --git a/src/DecoderControl.hxx b/src/DecoderControl.hxx
index 7f827d996..00fddecc6 100644
--- a/src/DecoderControl.hxx
+++ b/src/DecoderControl.hxx
@@ -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_buffer *buffer;
+ MusicBuffer *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();
diff --git a/src/DecoderInternal.cxx b/src/DecoderInternal.cxx
index 4d1e9a3d3..0c9a10436 100644
--- a/src/DecoderInternal.cxx
+++ b/src/DecoderInternal.cxx
@@ -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);
diff --git a/src/MusicBuffer.cxx b/src/MusicBuffer.cxx
index eb42a0311..c811d8627 100644
--- a/src/MusicBuffer.cxx
+++ b/src/MusicBuffer.cxx
@@ -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);
}
diff --git a/src/MusicBuffer.hxx b/src/MusicBuffer.hxx
index cc03dfcb3..fe14fe300 100644
--- a/src/MusicBuffer.hxx
+++ b/src/MusicBuffer.hxx
@@ -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_return().
- *
- * @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 Return().
+ *
+ * @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_allocate() then.
- */
-void
-music_buffer_return(struct music_buffer *buffer, struct music_chunk *chunk);
+ /**
+ * Returns a chunk to the buffer. It can be reused by
+ * Allocate() then.
+ */
+ void Return(music_chunk *chunk);
+};
#endif
diff --git a/src/MusicPipe.cxx b/src/MusicPipe.cxx
index 2ff45748f..eadf526e1 100644
--- a/src/MusicPipe.cxx
+++ b/src/MusicPipe.cxx
@@ -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
diff --git a/src/MusicPipe.hxx b/src/MusicPipe.hxx
index 3d2e69d8d..2133bc086 100644
--- a/src/MusicPipe.hxx
+++ b/src/MusicPipe.hxx
@@ -30,7 +30,7 @@
#include <assert.h>
struct music_chunk;
-struct music_buffer;
+class MusicBuffer;
/**
* 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.
diff --git a/src/OutputAll.cxx b/src/OutputAll.cxx
index 928a64a91..0b110f5ee 100644
--- a/src/OutputAll.cxx
+++ b/src/OutputAll.cxx
@@ -45,9 +45,9 @@ static struct audio_output **audio_outputs;
static unsigned int num_audio_outputs;
/**
- * The #music_buffer object where consumed chunks are returned.
+ * The #MusicBuffer object where consumed chunks are returned.
*/
-static struct music_buffer *g_music_buffer;
+static MusicBuffer *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;
}
diff --git a/src/OutputAll.hxx b/src/OutputAll.hxx
index d48c44690..55bda383b 100644
--- a/src/OutputAll.hxx
+++ b/src/OutputAll.hxx
@@ -29,7 +29,7 @@
#include "replay_gain_info.h"
struct AudioFormat;
-struct music_buffer;
+class MusicBuffer;
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);
/**
diff --git a/src/PlayerThread.cxx b/src/PlayerThread.cxx
index d8fe20cf5..6cf8e556b 100644
--- a/src/PlayerThread.cxx
+++ b/src/PlayerThread.cxx
@@ -141,7 +141,7 @@ struct player {
elapsed_time(0.0) {}
};
-static struct music_buffer *player_buffer;
+static MusicBuffer *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;