Moved all of the player-waiting code to decoder_data(), to make
OutputBuffer more generic.
---

 src/decoder_api.c                   |   80 ++++++++++++++++++++++++++++++++++
 src/decoder_api.h                   |   15 ++++++
 src/inputPlugins/_flac_common.h     |   11 ++---
 src/inputPlugins/aac_plugin.c       |    6 +--
 src/inputPlugins/audiofile_plugin.c |   14 +++---
 src/inputPlugins/mod_plugin.c       |    6 +--
 src/inputPlugins/mp3_plugin.c       |   31 +++++++------
 src/inputPlugins/mp4_plugin.c       |    6 +--
 src/inputPlugins/mpc_plugin.c       |   16 +++----
 src/inputPlugins/oggvorbis_plugin.c |   19 ++++----
 src/inputPlugins/wavpack_plugin.c   |    8 ++-
 src/outputBuffer.c                  |   82 +++++++----------------------------
 src/outputBuffer.h                  |   19 +++-----
 13 files changed, 177 insertions(+), 136 deletions(-)

diff --git a/src/decoder_api.c b/src/decoder_api.c
index dfd1850..681f593 100644
--- a/src/decoder_api.c
+++ b/src/decoder_api.c
@@ -19,6 +19,8 @@
 
 #include "decoder_api.h"
 
+#include "utils.h"
+#include "normalize.h"
 #include "playerData.h"
 #include "gcc.h"
 
@@ -29,3 +31,81 @@ void decoder_initialized(mpd_unused struct decoder * decoder)
        dc.state = DECODE_STATE_DECODE;
        notify_signal(&pc.notify);
 }
+
+/**
+ * All chunks are full of decoded data; wait for the player to free
+ * one.
+ */
+static int need_chunks(InputStream * inStream, int seekable)
+{
+       if (dc.command == DECODE_COMMAND_STOP)
+               return OUTPUT_BUFFER_DC_STOP;
+
+       if (dc.command == DECODE_COMMAND_SEEK) {
+               if (seekable) {
+                       return OUTPUT_BUFFER_DC_SEEK;
+               } else {
+                       dc.seekError = 1;
+                       dc_command_finished();
+               }
+       }
+
+       if (!inStream ||
+           bufferInputStream(inStream) <= 0) {
+               notify_wait(&dc.notify);
+               notify_signal(&pc.notify);
+       }
+
+       return 0;
+}
+
+int decoder_data(mpd_unused struct decoder *decoder, InputStream * inStream,
+                int seekable,
+                void *dataIn, size_t dataInLen,
+                float data_time, mpd_uint16 bitRate,
+                ReplayGainInfo * replayGainInfo)
+{
+       size_t nbytes;
+       char *data;
+       size_t datalen;
+       static char *convBuffer;
+       static size_t convBufferLen;
+       int ret;
+
+       if (cmpAudioFormat(&(ob.audioFormat), &(dc.audioFormat)) == 0) {
+               data = dataIn;
+               datalen = dataInLen;
+       } else {
+               datalen = pcm_sizeOfConvBuffer(&(dc.audioFormat), dataInLen,
+                                              &(ob.audioFormat));
+               if (datalen > convBufferLen) {
+                       if (convBuffer != NULL)
+                               free(convBuffer);
+                       convBuffer = xmalloc(datalen);
+                       convBufferLen = datalen;
+               }
+               data = convBuffer;
+               datalen = pcm_convertAudioFormat(&(dc.audioFormat), dataIn,
+                                                dataInLen, &(ob.audioFormat),
+                                                data, &(ob.convState));
+       }
+
+       if (replayGainInfo != NULL && (replayGainState != REPLAYGAIN_OFF))
+               doReplayGain(replayGainInfo, data, datalen, &ob.audioFormat);
+       else if (normalizationEnabled)
+               normalizeData(data, datalen, &ob.audioFormat);
+
+       while (datalen > 0) {
+               nbytes = ob_append(data, datalen, data_time, bitRate);
+               datalen -= nbytes;
+               data += nbytes;
+
+               if (datalen > 0) {
+                       ret = need_chunks(inStream, seekable);
+                       if (ret != 0)
+                               return ret;
+               }
+       }
+
+       return 0;
+}
diff --git a/src/decoder_api.h b/src/decoder_api.h
index c9ab3eb..a56b7ef 100644
--- a/src/decoder_api.h
+++ b/src/decoder_api.h
@@ -27,6 +27,8 @@
  */
 
 #include "inputPlugin.h"
+#include "inputStream.h"
+#include "replayGain.h"
 
 /**
  * Opaque handle which the decoder plugin passes to the functions in
@@ -40,4 +42,17 @@ struct decoder;
  */
 void decoder_initialized(struct decoder * decoder);
 
+/**
+ * This function is called by the decoder plugin when it has
+ * successfully decoded block of input data.
+ *
+ * We send inStream for buffering the inputStream while waiting to
+ * send the next chunk
+ */
+int decoder_data(struct decoder *decoder, InputStream * inStream,
+                int seekable,
+                void *data, size_t datalen,
+                float data_time, mpd_uint16 bitRate,
+                ReplayGainInfo * replayGainInfo);
+
 #endif
diff --git a/src/inputPlugins/_flac_common.h b/src/inputPlugins/_flac_common.h
index 2d59f4d..9eb916b 100644
--- a/src/inputPlugins/_flac_common.h
+++ b/src/inputPlugins/_flac_common.h
@@ -165,12 +165,11 @@ MpdTag *copyVorbisCommentBlockToMpdTag(const 
FLAC__StreamMetadata * block,
 /* keep this inlined, this is just macro but prettier :) */
 static inline int flacSendChunk(FlacData * data)
 {
-       if (ob_send(data->inStream,
-                                  1, data->chunk,
-                                  data->chunk_length, data->time,
-                                  data->bitRate,
-                                  data->replayGainInfo) ==
-           OUTPUT_BUFFER_DC_STOP)
+       if (decoder_data(data->decoder, data->inStream,
+                        1, data->chunk,
+                        data->chunk_length, data->time,
+                        data->bitRate,
+                        data->replayGainInfo) == OUTPUT_BUFFER_DC_STOP)
                return -1;
 
        return 0;
diff --git a/src/inputPlugins/aac_plugin.c b/src/inputPlugins/aac_plugin.c
index d03826c..c6bd998 100644
--- a/src/inputPlugins/aac_plugin.c
+++ b/src/inputPlugins/aac_plugin.c
@@ -391,9 +391,9 @@ static int aac_decode(struct decoder * mpd_decoder, char 
*path)
 
                sampleBufferLen = sampleCount * 2;
 
-               ob_send(NULL, 0, sampleBuffer,
-                       sampleBufferLen, file_time,
-                       bitRate, NULL);
+               decoder_data(mpd_decoder, NULL, 0, sampleBuffer,
+                            sampleBufferLen, file_time,
+                            bitRate, NULL);
                if (dc.command == DECODE_COMMAND_SEEK) {
                        dc.seekError = 1;
                        dc_command_finished();
diff --git a/src/inputPlugins/audiofile_plugin.c 
b/src/inputPlugins/audiofile_plugin.c
index faa58fe..fc25726 100644
--- a/src/inputPlugins/audiofile_plugin.c
+++ b/src/inputPlugins/audiofile_plugin.c
@@ -106,13 +106,13 @@ static int audiofile_decode(struct decoder * decoder, 
char *path)
                                eof = 1;
                        else {
                                current += ret;
-                               ob_send(NULL,
-                                       1,
-                                       chunk, ret * fs,
-                                       (float)current /
-                                       (float)dc.audioFormat.
-                                       sampleRate, bitRate,
-                                       NULL);
+                               decoder_data(decoder, NULL,
+                                            1,
+                                            chunk, ret * fs,
+                                            (float)current /
+                                            (float)dc.audioFormat.
+                                            sampleRate, bitRate,
+                                            NULL);
                                if (dc.command == DECODE_COMMAND_STOP)
                                        break;
                        }
diff --git a/src/inputPlugins/mod_plugin.c b/src/inputPlugins/mod_plugin.c
index c09803e..792cb0c 100644
--- a/src/inputPlugins/mod_plugin.c
+++ b/src/inputPlugins/mod_plugin.c
@@ -200,9 +200,9 @@ static int mod_decode(struct decoder * decoder, char *path)
 
                ret = VC_WriteBytes(data->audio_buffer, MIKMOD_FRAME_SIZE);
                total_time += ret * secPerByte;
-               ob_send(NULL, 0,
-                                      (char *)data->audio_buffer, ret,
-                                      total_time, 0, NULL);
+               decoder_data(decoder, NULL, 0,
+                            (char *)data->audio_buffer, ret,
+                            total_time, 0, NULL);
        }
 
        ob_flush();
diff --git a/src/inputPlugins/mp3_plugin.c b/src/inputPlugins/mp3_plugin.c
index f918953..399491d 100644
--- a/src/inputPlugins/mp3_plugin.c
+++ b/src/inputPlugins/mp3_plugin.c
@@ -812,7 +812,8 @@ static int openMp3FromInputStream(InputStream * inStream, 
mp3DecodeData * data,
        return 0;
 }
 
-static int mp3Read(mp3DecodeData * data, ReplayGainInfo ** replayGainInfo)
+static int mp3Read(mp3DecodeData * data, struct decoder *decoder,
+                  ReplayGainInfo ** replayGainInfo)
 {
        int samplesPerFrame;
        int samplesLeft;
@@ -926,13 +927,13 @@ static int mp3Read(mp3DecodeData * data, ReplayGainInfo 
** replayGainInfo)
                        }
 
                        if (data->outputPtr >= data->outputBufferEnd) {
-                               ret = ob_send(data->inStream,
-                                                            
data->inStream->seekable,
-                                                            data->outputBuffer,
-                                                            data->outputPtr - 
data->outputBuffer,
-                                                            data->elapsedTime,
-                                                            data->bitRate / 
1000,
-                                                            (replayGainInfo != 
NULL) ? *replayGainInfo : NULL);
+                               ret = decoder_data(decoder, data->inStream,
+                                                  data->inStream->seekable,
+                                                  data->outputBuffer,
+                                                  data->outputPtr - 
data->outputBuffer,
+                                                  data->elapsedTime,
+                                                  data->bitRate / 1000,
+                                                  (replayGainInfo != NULL) ? 
*replayGainInfo : NULL);
                                if (ret == OUTPUT_BUFFER_DC_STOP) {
                                        data->flush = 0;
                                        return DECODE_BREAK;
@@ -1063,16 +1064,16 @@ static int mp3_decode(struct decoder * decoder, 
InputStream * inStream)
 
        decoder_initialized(decoder);
 
-       while (mp3Read(&data, &replayGainInfo) != DECODE_BREAK) ;
+       while (mp3Read(&data, decoder, &replayGainInfo) != DECODE_BREAK) ;
        /* send last little bit if not DECODE_COMMAND_STOP */
        if (dc.command != DECODE_COMMAND_STOP &&
            data.outputPtr != data.outputBuffer && data.flush) {
-               ob_send(NULL,
-                                      data.inStream->seekable,
-                                      data.outputBuffer,
-                                      data.outputPtr - data.outputBuffer,
-                                      data.elapsedTime, data.bitRate / 1000,
-                                      replayGainInfo);
+               decoder_data(decoder, NULL,
+                            data.inStream->seekable,
+                            data.outputBuffer,
+                            data.outputPtr - data.outputBuffer,
+                            data.elapsedTime, data.bitRate / 1000,
+                            replayGainInfo);
        }
 
        if (replayGainInfo)
diff --git a/src/inputPlugins/mp4_plugin.c b/src/inputPlugins/mp4_plugin.c
index de65851..197d006 100644
--- a/src/inputPlugins/mp4_plugin.c
+++ b/src/inputPlugins/mp4_plugin.c
@@ -270,9 +270,9 @@ static int mp4_decode(struct decoder * mpd_decoder, 
InputStream * inStream)
 
                sampleBuffer += offset * channels * 2;
 
-               ob_send(inStream, 1, sampleBuffer,
-                       sampleBufferLen, file_time,
-                       bitRate, NULL);
+               decoder_data(mpd_decoder, inStream, 1, sampleBuffer,
+                            sampleBufferLen, file_time,
+                            bitRate, NULL);
                if (dc.command == DECODE_COMMAND_STOP) {
                        eof = 1;
                        break;
diff --git a/src/inputPlugins/mpc_plugin.c b/src/inputPlugins/mpc_plugin.c
index d4ee40f..abdf44c 100644
--- a/src/inputPlugins/mpc_plugin.c
+++ b/src/inputPlugins/mpc_plugin.c
@@ -215,11 +215,11 @@ static int mpc_decode(struct decoder * mpd_decoder, 
InputStream * inStream)
                                bitRate = vbrUpdateBits *
                                    dc.audioFormat.sampleRate / 1152 / 1000;
 
-                               ob_send(inStream,
-                                                      inStream->seekable,
-                                                      chunk, chunkpos,
-                                                      total_time,
-                                                      bitRate, replayGainInfo);
+                               decoder_data(mpd_decoder, inStream,
+                                            inStream->seekable,
+                                            chunk, chunkpos,
+                                            total_time,
+                                            bitRate, replayGainInfo);
 
                                chunkpos = 0;
                                s16 = (mpd_sint16 *) chunk;
@@ -237,9 +237,9 @@ static int mpc_decode(struct decoder * mpd_decoder, 
InputStream * inStream)
                bitRate =
                    vbrUpdateBits * dc.audioFormat.sampleRate / 1152 / 1000;
 
-               ob_send(NULL, inStream->seekable,
-                                      chunk, chunkpos, total_time, bitRate,
-                                      replayGainInfo);
+               decoder_data(mpd_decoder, NULL, inStream->seekable,
+                            chunk, chunkpos, total_time, bitRate,
+                            replayGainInfo);
        }
 
        ob_flush();
diff --git a/src/inputPlugins/oggvorbis_plugin.c 
b/src/inputPlugins/oggvorbis_plugin.c
index 0867de6..1333bc1 100644
--- a/src/inputPlugins/oggvorbis_plugin.c
+++ b/src/inputPlugins/oggvorbis_plugin.c
@@ -309,12 +309,11 @@ static int oggvorbis_decode(struct decoder * decoder, 
InputStream * inStream)
                        if ((test = ov_bitrate_instant(&vf)) > 0) {
                                bitRate = test / 1000;
                        }
-                       ob_send(inStream,
-                                              inStream->seekable,
-                                              chunk, chunkpos,
-                                              ov_pcm_tell(&vf) /
-                                              dc.audioFormat.sampleRate,
-                                              bitRate, replayGainInfo);
+                       decoder_data(decoder, inStream,
+                                    inStream->seekable,
+                                    chunk, chunkpos,
+                                    ov_pcm_tell(&vf) / 
dc.audioFormat.sampleRate,
+                                    bitRate, replayGainInfo);
                        chunkpos = 0;
                        if (dc.command == DECODE_COMMAND_STOP)
                                break;
@@ -322,10 +321,10 @@ static int oggvorbis_decode(struct decoder * decoder, 
InputStream * inStream)
        }
 
        if (dc.command != DECODE_COMMAND_STOP && chunkpos > 0) {
-               ob_send(NULL, inStream->seekable,
-                                      chunk, chunkpos,
-                                      ov_time_tell(&vf), bitRate,
-                                      replayGainInfo);
+               decoder_data(decoder, NULL, inStream->seekable,
+                            chunk, chunkpos,
+                            ov_time_tell(&vf), bitRate,
+                            replayGainInfo);
        }
 
        if (replayGainInfo)
diff --git a/src/inputPlugins/wavpack_plugin.c 
b/src/inputPlugins/wavpack_plugin.c
index cd832fd..e4134bb 100644
--- a/src/inputPlugins/wavpack_plugin.c
+++ b/src/inputPlugins/wavpack_plugin.c
@@ -207,10 +207,10 @@ static void wavpack_decode(struct decoder * decoder,
                        format_samples(Bps, chunk,
                                       samplesgot * dc.audioFormat.channels);
 
-                       ob_send(NULL, 0, chunk,
-                                              samplesgot * outsamplesize,
-                                              file_time, bitrate,
-                                              replayGainInfo);
+                       decoder_data(decoder, NULL, 0, chunk,
+                                    samplesgot * outsamplesize,
+                                    file_time, bitrate,
+                                    replayGainInfo);
                }
        } while (samplesgot == samplesreq);
 
diff --git a/src/outputBuffer.c b/src/outputBuffer.c
index ff8cf75..97a9e78 100644
--- a/src/outputBuffer.c
+++ b/src/outputBuffer.c
@@ -17,10 +17,9 @@
  */
 
 #include "outputBuffer.h"
+#include "playerData.h"
 
 #include "utils.h"
-#include "normalize.h"
-#include "playerData.h"
 
 void ob_init(unsigned int size)
 {
@@ -148,16 +147,12 @@ ob_chunk * ob_get_chunk(const unsigned i)
 }
 
 /**
- * Return the tail chunk which has room for additional data.  If there
- * is no room in the queue, this function blocks until the player
- * thread has finished playing its current chunk.
+ * Return the tail chunk which has room for additional data.
  *
- * @return the positive index of the new chunk; OUTPUT_BUFFER_DC_SEEK
- * if another thread requested seeking; OUTPUT_BUFFER_DC_STOP if
- * another thread requested stopping the decoder.
+ * @return the positive index of the new chunk; -1 if there is no
+ * room.
  */
-static int tailChunk(InputStream * inStream,
-                    int seekable, float data_time, mpd_uint16 bitRate)
+static int tailChunk(float data_time, mpd_uint16 bitRate)
 {
        unsigned int next;
        ob_chunk *chunk;
@@ -167,26 +162,9 @@ static int tailChunk(InputStream * inStream,
        if (chunk->chunkSize == sizeof(chunk->data)) {
                /* this chunk is full; allocate a new chunk */
                next = successor(ob.end);
-               while (ob.begin == next) {
-                       /* all chunks are full of decoded data; wait
-                          for the player to free one */
-
-                       if (dc.command == DECODE_COMMAND_STOP)
-                               return OUTPUT_BUFFER_DC_STOP;
-
-                       if (dc.command == DECODE_COMMAND_SEEK) {
-                               if (seekable) {
-                                       return OUTPUT_BUFFER_DC_SEEK;
-                               } else {
-                                       dc.seekError = 1;
-                                       dc_command_finished();
-                               }
-                       }
-                       if (!inStream || bufferInputStream(inStream) <= 0) {
-                               notify_wait(&dc.notify);
-                               notify_signal(&pc.notify);
-                       }
-               }
+               if (ob.begin == next)
+                       /* no chunks available */
+                       return -1;
 
                output_buffer_expand(next);
                chunk = ob_get_chunk(next);
@@ -204,46 +182,17 @@ static int tailChunk(InputStream * inStream,
        return ob.end;
 }
 
-int ob_send(InputStream * inStream,
-                          int seekable, void *dataIn,
-                          size_t dataInLen, float data_time, mpd_uint16 
bitRate,
-                          ReplayGainInfo * replayGainInfo)
+size_t ob_append(const void *data0, size_t datalen,
+                float data_time, mpd_uint16 bitRate)
 {
-       size_t dataToSend;
-       char *data;
-       size_t datalen;
-       static char *convBuffer;
-       static size_t convBufferLen;
+       const unsigned char *data = data0;
+       size_t ret = 0, dataToSend;
        ob_chunk *chunk = NULL;
 
-       if (cmpAudioFormat(&(ob.audioFormat), &(dc.audioFormat)) == 0) {
-               data = dataIn;
-               datalen = dataInLen;
-       } else {
-               datalen = pcm_sizeOfConvBuffer(&(dc.audioFormat), dataInLen,
-                                              &(ob.audioFormat));
-               if (datalen > convBufferLen) {
-                       if (convBuffer != NULL)
-                               free(convBuffer);
-                       convBuffer = xmalloc(datalen);
-                       convBufferLen = datalen;
-               }
-               data = convBuffer;
-               datalen = pcm_convertAudioFormat(&(dc.audioFormat), dataIn,
-                                                dataInLen, &(ob.audioFormat),
-                                                data, &(ob.convState));
-       }
-
-       if (replayGainInfo && (replayGainState != REPLAYGAIN_OFF))
-               doReplayGain(replayGainInfo, data, datalen, &ob.audioFormat);
-       else if (normalizationEnabled)
-               normalizeData(data, datalen, &ob.audioFormat);
-
        while (datalen) {
-               int chunk_index = tailChunk(inStream, seekable,
-                                           data_time, bitRate);
+               int chunk_index = tailChunk(data_time, bitRate);
                if (chunk_index < 0)
-                       return chunk_index;
+                       return ret;
 
                chunk = ob_get_chunk(chunk_index);
 
@@ -255,12 +204,13 @@ int ob_send(InputStream * inStream,
                chunk->chunkSize += dataToSend;
                datalen -= dataToSend;
                data += dataToSend;
+               ret += dataToSend;
        }
 
        if (chunk != NULL && chunk->chunkSize == sizeof(chunk->data))
                ob_flush();
 
-       return 0;
+       return ret;
 }
 
 void ob_skip(unsigned num)
diff --git a/src/outputBuffer.h b/src/outputBuffer.h
index da574f4..ebbc0d2 100644
--- a/src/outputBuffer.h
+++ b/src/outputBuffer.h
@@ -20,9 +20,6 @@
 #define OUTPUT_BUFFER_H
 
 #include "pcm_utils.h"
-#include "mpd_types.h"
-#include "inputStream.h"
-#include "replayGain.h"
 
 #define OUTPUT_BUFFER_DC_STOP   -1
 #define OUTPUT_BUFFER_DC_SEEK   -2
@@ -98,15 +95,15 @@ int ob_absolute(const unsigned relative);
 
 ob_chunk * ob_get_chunk(const unsigned i);
 
-/* we send inStream for buffering the inputStream while waiting to
-   send the next chunk */
-int ob_send(InputStream * inStream,
-                          int seekable,
-                          void *data,
-                          size_t datalen,
-                          float data_time,
-                          mpd_uint16 bitRate, ReplayGainInfo * replayGainInfo);
+/**
+ * Append a data block to the buffer.
+ *
+ * @return the number of bytes actually written
+ */
+size_t ob_append(const void *data, size_t datalen,
+                float data_time, mpd_uint16 bitRate);
 
 void ob_skip(unsigned num);
 
 #endif
+


-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Musicpd-dev-team mailing list
Musicpd-dev-team@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/musicpd-dev-team

Reply via email to