aboutsummaryrefslogtreecommitdiffstats
path: root/src/decoder_api.c
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2008-08-26 08:27:05 +0200
committerMax Kellermann <max@duempel.org>2008-08-26 08:27:05 +0200
commit2a83ccdb8f71d224341ea5a6ddbc002693d887fb (patch)
tree7a6c3f2a480739e2951fe3141c8ca8a1aacc0db7 /src/decoder_api.c
parent8814c0c898162f25ef4851df5cf8c9e68ff83942 (diff)
downloadmpd-2a83ccdb8f71d224341ea5a6ddbc002693d887fb.tar.gz
mpd-2a83ccdb8f71d224341ea5a6ddbc002693d887fb.tar.xz
mpd-2a83ccdb8f71d224341ea5a6ddbc002693d887fb.zip
added decoder_data()
Moved all of the player-waiting code to decoder_data(), to make OutputBuffer more generic.
Diffstat (limited to 'src/decoder_api.c')
-rw-r--r--src/decoder_api.c80
1 files changed, 80 insertions, 0 deletions
diff --git a/src/decoder_api.c b/src/decoder_api.c
index dfd1850b5..681f593f8 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;
+}