aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWarren Dukes <warren.dukes@gmail.com>2004-05-20 03:44:33 +0000
committerWarren Dukes <warren.dukes@gmail.com>2004-05-20 03:44:33 +0000
commit4db5224b4773c48d9699f21f8bb4629b176fe43b (patch)
tree077b7fc630e4e9e2a5b15291db4248bca3109a49
parent5a4022d878f8cd3a07e427344908b8226587a7f9 (diff)
downloadmpd-4db5224b4773c48d9699f21f8bb4629b176fe43b.tar.gz
mpd-4db5224b4773c48d9699f21f8bb4629b176fe43b.tar.xz
mpd-4db5224b4773c48d9699f21f8bb4629b176fe43b.zip
ogg stream playing! some non-blocking seek bug fixes
git-svn-id: https://svn.musicpd.org/mpd/trunk@1105 09075e82-0dd4-0310-85a5-a0d7c8717e4f
-rw-r--r--src/decode.c86
-rw-r--r--src/inputStream_http.c1
-rw-r--r--src/mp3_decode.c7
-rw-r--r--src/ogg_decode.c78
-rw-r--r--src/ogg_decode.h3
-rw-r--r--src/player.c1
6 files changed, 114 insertions, 62 deletions
diff --git a/src/decode.c b/src/decode.c
index af5e39259..82865b39b 100644
--- a/src/decode.c
+++ b/src/decode.c
@@ -89,6 +89,7 @@ void stopDecode(DecoderControl * dc) {
void quitDecode(PlayerControl * pc, DecoderControl * dc) {
stopDecode(dc);
pc->state = PLAYER_STATE_STOP;
+ dc->seek = 0;
pc->play = 0;
pc->stop = 0;
pc->pause = 0;
@@ -113,23 +114,34 @@ int calculateCrossFadeChunks(PlayerControl * pc, AudioFormat * af) {
}
#define handleDecodeStart() \
- if(decodeWaitedOn && dc->state==DECODE_STATE_DECODE) { \
- decodeWaitedOn = 0; \
- if(openAudioDevice(&(cb->audioFormat))<0) { \
+ if(decodeWaitedOn) { \
+ if(dc->state!=DECODE_STATE_START && *decode_pid > 0 && \
+ dc->error==DECODE_ERROR_NOERROR) \
+ { \
+ decodeWaitedOn = 0; \
+ if(openAudioDevice(&(cb->audioFormat))<0) { \
+ strncpy(pc->erroredFile,pc->file,MAXPATHLEN); \
+ pc->erroredFile[MAXPATHLEN] = '\0'; \
+ pc->error = PLAYER_ERROR_AUDIO; \
+ quitDecode(pc,dc); \
+ return; \
+ } \
+ pc->totalTime = dc->totalTime; \
+ pc->sampleRate = dc->audioFormat.sampleRate; \
+ pc->bits = dc->audioFormat.bits; \
+ pc->channels = dc->audioFormat.channels; \
+ } \
+ else if(dc->state!=DECODE_STATE_START || *decode_pid <= 0) { \
strncpy(pc->erroredFile,pc->file,MAXPATHLEN); \
pc->erroredFile[MAXPATHLEN] = '\0'; \
- pc->error = PLAYER_ERROR_AUDIO; \
+ pc->error = PLAYER_ERROR_FILE; \
quitDecode(pc,dc); \
return; \
- } \
- pc->totalTime = dc->totalTime; \
- pc->sampleRate = dc->audioFormat.sampleRate; \
- pc->bits = dc->audioFormat.bits; \
- pc->channels = dc->audioFormat.channels; \
- } \
- else if(decodeWaitedOn) { \
- my_usleep(10000); \
- continue; \
+ } \
+ else { \
+ my_usleep(10000); \
+ continue; \
+ } \
}
int waitOnDecode(PlayerControl * pc, DecoderControl * dc, OutputBuffer * cb,
@@ -226,7 +238,7 @@ int decodeSeek(PlayerControl * pc, DecoderControl * dc, OutputBuffer * cb,
if(decodeSeek(pc,dc,cb,&decodeWaitedOn) == 0) { \
doCrossFade = 0; \
nextChunk = -1; \
- bbp = 0; \
+ bbp = 0; \
seeking = 1; \
} \
} \
@@ -255,7 +267,7 @@ void decodeStart(PlayerControl * pc, OutputBuffer * cb, DecoderControl * dc) {
dc->start = 0;
while(!inputStreamAtEOF(&inStream) && bufferInputStream(&inStream) < 0
- && !dc->stop);
+ && !pc->stop);
if(dc->stop) {
dc->state = DECODE_STATE_STOP;
@@ -265,6 +277,14 @@ void decodeStart(PlayerControl * pc, OutputBuffer * cb, DecoderControl * dc) {
switch(pc->decodeType) {
case DECODE_TYPE_URL:
+#ifdef HAVE_OGG
+ if(pc->fileSuffix == DECODE_SUFFIX_OGG || (inStream.mime &&
+ 0 == strcmp(inStream.mime, "application/ogg")))
+ {
+ ret = ogg_decode(cb, dc, &inStream);
+ break;
+ }
+#endif
#ifdef HAVE_MAD
/*if(pc->fileSuffix == DECODE_SUFFIX_MP3 || (inStream.mime &&
0 == strcmp(inStream.mime, "audio/mpeg")))*/
@@ -281,6 +301,12 @@ void decodeStart(PlayerControl * pc, OutputBuffer * cb, DecoderControl * dc) {
break;
}
#endif
+#ifdef HAVE_OGG
+ if(pc->fileSuffix == DECODE_SUFFIX_OGG) {
+ ret = ogg_decode(cb, dc, &inStream);
+ break;
+ }
+#endif
#ifdef HAVE_FAAD
if(pc->fileSuffix == DECODE_SUFFIX_AAC) {
closeInputStream(&inStream);
@@ -293,13 +319,6 @@ void decodeStart(PlayerControl * pc, OutputBuffer * cb, DecoderControl * dc) {
break;
}
#endif
-#ifdef HAVE_OGG
- if(pc->fileSuffix == DECODE_SUFFIX_OGG) {
- closeInputStream(&inStream);
- ret = ogg_decode(cb,dc);
- break;
- }
-#endif
#ifdef HAVE_FLAC
if(pc->fileSuffix == DECODE_SUFFIX_FLAC) {
closeInputStream(&inStream);
@@ -321,8 +340,10 @@ void decodeStart(PlayerControl * pc, OutputBuffer * cb, DecoderControl * dc) {
strncpy(pc->erroredFile, dc->file, MAXPATHLEN);
pc->erroredFile[MAXPATHLEN] = '\0';
if(ret != DECODE_ERROR_UNKTYPE) dc->error = DECODE_ERROR_FILE;
- else closeInputStream(&inStream);
- dc->start = 0;
+ else {
+ dc->error = DECODE_ERROR_UNKTYPE;
+ closeInputStream(&inStream);
+ }
dc->stop = 0;
dc->state = DECODE_STATE_STOP;
}
@@ -341,16 +362,15 @@ int decoderInit(PlayerControl * pc, OutputBuffer * cb, DecoderControl * dc) {
unblockSignals();
while(1) {
- if(dc->start) decodeStart(pc, cb, dc);
- else if(dc->stop) {
- dc->state = DECODE_STATE_STOP;
- dc->stop = 0;
- }
- else if(dc->seek) dc->start = 1;
if(dc->cycleLogFiles) {
myfprintfCloseAndOpenLogFile();
dc->cycleLogFiles = 0;
}
+ else if(dc->start) decodeStart(pc, cb, dc);
+ else if(dc->stop) {
+ dc->state = DECODE_STATE_STOP;
+ dc->stop = 0;
+ }
else my_usleep(10000);
}
@@ -392,7 +412,7 @@ void decodeParent(PlayerControl * pc, DecoderControl * dc, OutputBuffer * cb) {
pc->play = 0;
pc->beginTime = pc->elapsedTime;
kill(getppid(),SIGUSR1);
-
+
while(*decode_pid>0 && !cb->wrap && cb->end-cb->begin<bbp &&
dc->state!=DECODE_STATE_STOP)
{
@@ -578,8 +598,10 @@ void decode() {
pc = &(getPlayerData()->playerControl);
dc = &(getPlayerData()->decoderControl);
dc->error = 0;
- dc->start = 1;
cb->next = -1;
+ dc->seek = 0;
+ dc->stop = 0;
+ dc->start = 1;
if(decode_pid==NULL || *decode_pid<=0) {
if(decoderInit(pc,cb,dc)<0) return;
diff --git a/src/inputStream_http.c b/src/inputStream_http.c
index 0080792ad..3e97b8ffa 100644
--- a/src/inputStream_http.c
+++ b/src/inputStream_http.c
@@ -41,6 +41,7 @@
#define HTTP_BUFFER_SIZE 524289
#define HTTP_PREBUFFER_SIZE (HTTP_BUFFER_SIZE >> 2)
+//#define HTTP_PREBUFFER_SIZE 0
#define HTTP_REDIRECT_MAX 10
diff --git a/src/mp3_decode.c b/src/mp3_decode.c
index 69d336e99..3836af8e2 100644
--- a/src/mp3_decode.c
+++ b/src/mp3_decode.c
@@ -556,9 +556,12 @@ int mp3_decode(OutputBuffer * cb, DecoderControl * dc, InputStream * inStream) {
mp3DecodeData data;
if(openMp3FromInputStream(inStream, &data, dc) < 0) {
- ERROR("Input does not appear to be a mp3 bit stream.\n");
closeInputStream(inStream);
- return -1;
+ if(!dc->stop) {
+ ERROR("Input does not appear to be a mp3 bit stream.\n");
+ return -1;
+ }
+ return 0;
}
initAudioFormatFromMp3DecodeData(&data, &(dc->audioFormat));
diff --git a/src/ogg_decode.c b/src/ogg_decode.c
index 6f8ffe535..9bd24de01 100644
--- a/src/ogg_decode.c
+++ b/src/ogg_decode.c
@@ -42,6 +42,11 @@
#define OGG_DECODE_USE_BIGENDIAN 0
#endif
+typedef struct _OggCallbackData {
+ InputStream * inStream;
+ DecoderControl * dc;
+} OggCallbackData;
+
/* this is just for tag parsing for db import! */
int getOggTotalTime(char * file) {
OggVorbis_File vf;
@@ -62,26 +67,42 @@ int getOggTotalTime(char * file) {
return totalTime;
}
-size_t ogg_read_cb(void * ptr, size_t size, size_t nmemb, void * inStream)
+size_t ogg_read_cb(void * ptr, size_t size, size_t nmemb, void * vdata)
{
- size_t ret;
- ret = readFromInputStream((InputStream *)inStream,ptr,size,nmemb);
+ size_t ret = 0;
+ OggCallbackData * data = (OggCallbackData *)vdata;
- if(ret<0) errno = ((InputStream *)inStream)->error;
+ while(1) {
+ ret = readFromInputStream(data->inStream,ptr,size,nmemb);
+ if(ret == 0 && !inputStreamAtEOF(data->inStream) &&
+ !data->dc->stop)
+ {
+ my_usleep(10000);
+ }
+ else break;
+ }
+ errno = 0;
+ /*if(ret<0) errno = ((InputStream *)inStream)->error;*/
return ret;
}
-int ogg_seek_cb(void * inStream, ogg_int64_t offset, int whence) {
- return seekInputStream((InputStream *)inStream,offset,whence);
+int ogg_seek_cb(void * vdata, ogg_int64_t offset, int whence) {
+ OggCallbackData * data = (OggCallbackData *)vdata;
+
+ return seekInputStream(data->inStream,offset,whence);
}
-int ogg_close_cb(void * inStream) {
- return closeInputStream((InputStream *)inStream);
+int ogg_close_cb(void * vdata) {
+ OggCallbackData * data = (OggCallbackData *)vdata;
+
+ return closeInputStream(data->inStream);
}
-long ogg_tell_cb(void * inStream) {
- return ((InputStream *)inStream)->offset;
+long ogg_tell_cb(void * vdata) {
+ OggCallbackData * data = (OggCallbackData *)vdata;
+
+ return (long)(data->inStream->offset);
}
char * ogg_parseComment(char * comment, char * needle) {
@@ -142,27 +163,27 @@ float ogg_getReplayGainScale(char ** comments) {
return 1.0;
}
-int ogg_decode(OutputBuffer * cb, DecoderControl * dc)
+int ogg_decode(OutputBuffer * cb, DecoderControl * dc, InputStream * inStream)
{
OggVorbis_File vf;
ov_callbacks callbacks;
- InputStream inStream;
-
+ OggCallbackData data;
+
+ data.inStream = inStream;
+ data.dc = dc;
callbacks.read_func = ogg_read_cb;
callbacks.seek_func = ogg_seek_cb;
callbacks.close_func = ogg_close_cb;
callbacks.tell_func = ogg_tell_cb;
- if(openInputStream(&inStream,dc->file)<0) {
- ERROR("failed to open ogg\n");
- return -1;
- }
-
- if(ov_open_callbacks(&inStream, &vf, NULL, 0, callbacks) < 0) {
- ERROR("Input does not appear to be an Ogg bit stream.\n");
- closeInputStream(&inStream);
- return -1;
+ if(ov_open_callbacks(&data, &vf, NULL, 0, callbacks) < 0) {
+ closeInputStream(inStream);
+ if(!dc->stop) {
+ ERROR("Input does not appear to be an Ogg Vorbis stream.\n");
+ return -1;
+ }
+ return 0;
}
{
@@ -190,20 +211,23 @@ int ogg_decode(OutputBuffer * cb, DecoderControl * dc)
while(!eof) {
if(dc->seek) {
- clearOutputBuffer(cb);
- chunkpos = 0;
- dc->seekChunk = cb->end;
- ov_time_seek_page(&vf,dc->seekWhere);
+ if(0 == ov_time_seek_page(&vf,dc->seekWhere)) {
+ clearOutputBuffer(cb);
+ chunkpos = 0;
+ dc->seekChunk = cb->end;
+ }
dc->seek = 0;
}
ret = ov_read(&vf, chunk+chunkpos,
OGG_CHUNK_SIZE-chunkpos,
OGG_DECODE_USE_BIGENDIAN,
2, 1, &current_section);
- if(ret<=0) {
+
+ if(ret <= 0 && ret != OV_HOLE) {
eof = 1;
break;
}
+ if(ret == OV_HOLE) ret = 0;
chunkpos+=ret;
diff --git a/src/ogg_decode.h b/src/ogg_decode.h
index 16928eac6..03f1364a5 100644
--- a/src/ogg_decode.h
+++ b/src/ogg_decode.h
@@ -22,10 +22,11 @@
#include "../config.h"
#include "playerData.h"
+#include "inputStream.h"
#include <stdio.h>
-int ogg_decode(OutputBuffer * cb, DecoderControl * dc);
+int ogg_decode(OutputBuffer * cb, DecoderControl * dc, InputStream * inStream);
int getOggTotalTime(char * file);
diff --git a/src/player.c b/src/player.c
index 82f3101cd..814509307 100644
--- a/src/player.c
+++ b/src/player.c
@@ -419,6 +419,7 @@ void playerQueueUnlock() {
}
int playerSeek(FILE * fp, Song * song, float time) {
+ printf("seek called\n");
PlayerControl * pc = &(getPlayerData()->playerControl);
char * file;
int decodeType;