rework stuff so that we can use mime-type of streams to detect type of file

git-svn-id: https://svn.musicpd.org/mpd/trunk@1062 09075e82-0dd4-0310-85a5-a0d7c8717e4f
This commit is contained in:
Warren Dukes 2004-05-18 13:13:55 +00:00
parent 6c24180516
commit c51ad71efa
7 changed files with 157 additions and 116 deletions

View File

@ -26,6 +26,7 @@
#include "path.h"
#include "log.h"
#include "sig_handlers.h"
#include "ls.h"
#ifdef HAVE_MAD
#include "mp3_decode.h"
@ -213,10 +214,90 @@ void decodeSeek(PlayerControl * pc, DecoderControl * dc, OutputBuffer * cb) {
return; \
}
void decodeStart(PlayerControl * pc, OutputBuffer * cb, DecoderControl * dc) {
int ret;
InputStream inStream;
strncpy(dc->file,pc->file,MAXPATHLEN);
dc->file[MAXPATHLEN] = '\0';
if(openInputStream(&inStream,dc->file) < 0) {
dc->error = DECODE_ERROR_FILE;
dc->start = 0;
dc->stop = 0;
dc->state = DECODE_STATE_STOP;
return;
}
while(!inputStreamAtEOF(&inStream) && bufferInputStream(&inStream) < 0);
switch(pc->decodeType) {
case DECODE_TYPE_URL:
#ifdef HAVE_MAD
if(pc->fileSuffix == DECODE_SUFFIX_MP3 || (inStream.mime &&
0 == strcmp(inStream.mime, "audio/mpeg")))
{
ret = mp3_decode(cb,dc,&inStream);
}
else ret = DECODE_ERROR_UNKTYPE;
break;
#endif
case DECODE_TYPE_FILE:
#ifdef HAVE_MAD
if(pc->fileSuffix == DECODE_SUFFIX_MP3) {
ret = mp3_decode(cb, dc, &inStream);
break;
}
#endif
#ifdef HAVE_FAAD
if(pc->fileSuffix == DECODE_SUFFIX_AAC) {
closeInputStream(&inStream);
ret = aac_decode(cb,dc);
break;
}
if(pc->fileSuffix == DECODE_SUFFIX_MP4) {
closeInputStream(&inStream);
ret = mp4_decode(cb,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);
ret = flac_decode(cb,dc);
break;
}
#endif
#ifdef HAVE_AUDIOFILE
if(pc->fileSuffix == DECODE_SUFFIX_WAVE) {
closeInputStream(&inStream);
ret = audiofile_decode(cb,dc);
break;
}
#endif
default:
ret = DECODE_ERROR_UNKTYPE;
}
if(ret<0) {
strncpy(pc->erroredFile, dc->file, MAXPATHLEN);
pc->erroredFile[MAXPATHLEN] = '\0';
if(ret != DECODE_ERROR_UNKTYPE) dc->error = DECODE_ERROR_FILE;
dc->start = 0;
dc->stop = 0;
dc->state = DECODE_STATE_STOP;
}
}
int decoderInit(PlayerControl * pc, OutputBuffer * cb, DecoderControl * dc) {
int pid;
int ret;
decode_pid = &(pc->decode_pid);
blockSignals();
@ -227,51 +308,7 @@ int decoderInit(PlayerControl * pc, OutputBuffer * cb, DecoderControl * dc) {
unblockSignals();
while(1) {
if(dc->start) {
strncpy(dc->file,pc->file,MAXPATHLEN);
dc->file[MAXPATHLEN] = '\0';
switch(pc->decodeType) {
#ifdef HAVE_MAD
case DECODE_TYPE_MP3:
ret = mp3_decode(cb,dc);
break;
#endif
#ifdef HAVE_FAAD
case DECODE_TYPE_AAC:
ret = aac_decode(cb,dc);
break;
case DECODE_TYPE_MP4:
ret = mp4_decode(cb,dc);
break;
#endif
#ifdef HAVE_OGG
case DECODE_TYPE_OGG:
ret = ogg_decode(cb,dc);
break;
#endif
#ifdef HAVE_FLAC
case DECODE_TYPE_FLAC:
ret = flac_decode(cb,dc);
break;
#endif
#ifdef HAVE_AUDIOFILE
case DECODE_TYPE_AUDIOFILE:
ret = audiofile_decode(cb,dc);
break;
#endif
default:
ret = DECODE_ERROR_UNKTYPE;
strncpy(pc->erroredFile,dc->file,
MAXPATHLEN);
pc->erroredFile[MAXPATHLEN] = '\0';
}
if(ret<0) {
dc->error = DECODE_ERROR_FILE;
dc->start = 0;
dc->stop = 0;
dc->state = DECODE_STATE_STOP;
}
}
if(dc->start) decodeStart(pc, cb, dc);
else if(dc->stop) {
dc->state = DECODE_STATE_STOP;
dc->stop = 0;

View File

@ -27,19 +27,22 @@
#include <stdio.h>
#include <sys/param.h>
#define DECODE_TYPE_MP3 0
#define DECODE_TYPE_OGG 1
#define DECODE_TYPE_FLAC 2
#define DECODE_TYPE_AUDIOFILE 3
#define DECODE_TYPE_MP4 4
#define DECODE_TYPE_AAC 5
#define DECODE_TYPE_FILE 0
#define DECODE_TYPE_URL 1
#define DECODE_STATE_STOP 0
#define DECODE_STATE_DECODE 1
#define DECODE_ERROR_NOERROR 0
#define DECODE_ERROR_UNKTYPE 1
#define DECODE_ERROR_FILE 2
#define DECODE_ERROR_UNKTYPE -10
#define DECODE_ERROR_FILE -20
#define DECODE_SUFFIX_MP3 1
#define DECODE_SUFFIX_OGG 2
#define DECODE_SUFFIX_FLAC 3
#define DECODE_SUFFIX_AAC 4
#define DECODE_SUFFIX_MP4 5
#define DECODE_SUFFIX_WAVE 6
typedef struct _DecoderControl {
volatile mpd_sint8 state;

View File

@ -381,11 +381,13 @@ static int getHTTPHello(InputStream * inStream) {
*temp = '\r';
}
else if(0 == strncmp(cur, "\r\nContent-Type:", 15)) {
char * temp = strstr(cur+15,"\r\n");
char * temp2 = cur+15;
char * temp = strstr(temp2,"\r\n");
if(!temp) break;
while(*temp2 && *temp2==' ') temp2++;
*temp = '\0';
if(inStream->mime) free(inStream->mime);
inStream->mime = strdup(cur+15);
inStream->mime = strdup(temp2);
*temp = '\r';
}
@ -455,13 +457,15 @@ size_t inputStream_httpRead(InputStream * inStream, void * ptr, size_t size,
return 0;
}
readed = inlen > data->buflen ? data->buflen : inlen;
if(data->buflen > 0) {
readed = inlen > data->buflen ? data->buflen : inlen;
memcpy(ptr, data->buffer, readed);
data->buflen -= readed;
memmove(data->buffer, data->buffer+readed, data->buflen);
memcpy(ptr, data->buffer, readed);
data->buflen -= readed;
memmove(data->buffer, data->buffer+readed, data->buflen);
inStream->offset+= readed;
inStream->offset+= readed;
}
return readed;
}
@ -536,22 +540,17 @@ int inputStream_httpBuffer(InputStream * inStream) {
return 0;
}
if(ret == 1) {
readed = recv(data->sock,
data->buffer+data->buflen,
HTTP_BUFFER_SIZE-1-data->buflen, 0);
if(ret == 0) return 0;
if(readed < 0 && (errno == EAGAIN ||
errno == EINTR))
{
readed = 0;
}
else if(readed <= 0) {
close(data->sock);
data->connState = HTTP_CONN_STATE_CLOSED;
}
else data->buflen += readed;
readed = recv(data->sock, data->buffer+data->buflen,
HTTP_BUFFER_SIZE-1-data->buflen, 0);
if(readed < 0 && (errno == EAGAIN || errno == EINTR));
else if(readed <= 0) {
close(data->sock);
data->connState = HTTP_CONN_STATE_CLOSED;
}
else data->buflen += readed;
}
return 0;

View File

@ -133,16 +133,10 @@ typedef struct _mp3DecodeData {
long currentFrame;
int flush;
unsigned long bitRate;
InputStream inStream;
InputStream * inStream;
} mp3DecodeData;
int initMp3DecodeData(mp3DecodeData * data, char * file) {
int ret;
/*while(((*/ret = openInputStream(&(data->inStream),file)/*)<0)) &&
data->inStream.error==EINTR)*/;
if(ret<0) return -1;
void initMp3DecodeData(mp3DecodeData * data, InputStream * inStream) {
data->outputPtr = data->outputBuffer;
data->outputBufferEnd = data->outputBuffer+MP3_DATA_OUTPUT_BUFFER_SIZE;
data->muteFrame = 0;
@ -152,14 +146,13 @@ int initMp3DecodeData(mp3DecodeData * data, char * file) {
data->times = NULL;
data->currentFrame = 0;
data->flush = 1;
data->inStream = inStream;
mad_stream_init(&data->stream);
data->stream.options |= MAD_OPTION_IGNORECRC;
mad_frame_init(&data->frame);
mad_synth_init(&data->synth);
mad_timer_reset(&data->timer);
return 0;
}
int fillMp3InputBuffer(mp3DecodeData * data, long offset) {
@ -169,7 +162,7 @@ int fillMp3InputBuffer(mp3DecodeData * data, long offset) {
unsigned char * readStart;
if(offset>=0) {
if(seekInputStream(&(data->inStream),offset,SEEK_SET) < 0) {
if(seekInputStream(data->inStream,offset,SEEK_SET) < 0) {
return -1;
}
}
@ -187,8 +180,8 @@ int fillMp3InputBuffer(mp3DecodeData * data, long offset) {
}
readed = 0;
while(readed == 0 && !inputStreamAtEOF(&(data->inStream))) {
readed = readFromInputStream(&(data->inStream), readStart, 1,
while(readed == 0 && !inputStreamAtEOF(data->inStream)) {
readed = readFromInputStream(data->inStream, readStart, 1,
readSize);
}
if(readed<=0) return -1;
@ -359,7 +352,7 @@ int decodeFirstFrame(mp3DecodeData * data) {
}
}
else {
size_t offset = data->inStream.offset;
size_t offset = data->inStream->offset;
mad_timer_t duration = data->frame.header.duration;
float frameTime = ((float)mad_timer_count(duration,
MAD_UNITS_MILLISECONDS))/1000;
@ -369,8 +362,9 @@ int decodeFirstFrame(mp3DecodeData * data) {
else {
offset-= data->stream.bufend-data->stream.buffer;
}
data->totalTime = ((data->inStream.size-offset)*8.0)/
data->totalTime = ((data->inStream->size-offset)*8.0)/
(data->frame).header.bitrate;
if(data->totalTime < 0) data->totalTime = 0;
data->maxFrames = data->totalTime/frameTime+FRAMES_CUSHION;
}
@ -385,18 +379,19 @@ void mp3DecodeDataFinalize(mp3DecodeData * data) {
mad_frame_finish(&data->frame);
mad_stream_finish(&data->stream);
while(closeInputStream(&(data->inStream))<0 &&
data->inStream.error==EINTR);
closeInputStream(data->inStream);
if(data->frameOffset) free(data->frameOffset);
if(data->times) free(data->times);
}
/* this is primarily used for getting total time for tags */
int getMp3TotalTime(char * file) {
InputStream inStream;
mp3DecodeData data;
int ret;
if(initMp3DecodeData(&data,file)<0) return -1;
if(openInputStream(&inStream, file) < 0) return -1;
initMp3DecodeData(&data,&inStream);
if(decodeFirstFrame(&data)<0) ret = -1;
else ret = data.totalTime+0.5;
mp3DecodeDataFinalize(&data);
@ -404,11 +399,8 @@ int getMp3TotalTime(char * file) {
return ret;
}
int openMp3(char * file, mp3DecodeData * data) {
if(initMp3DecodeData(data,file) < 0) {
ERROR("problems opening \"%s\"\n",file);
return -1;
}
int openMp3FromInputStream(InputStream * inStream, mp3DecodeData * data) {
initMp3DecodeData(data, inStream);
if(decodeFirstFrame(data)<0) {
mp3DecodeDataFinalize(data);
return -1;
@ -428,7 +420,7 @@ int mp3Read(mp3DecodeData * data, OutputBuffer * cb, DecoderControl * dc) {
{
mad_timer_add(&data->timer,(data->frame).header.duration);
data->bitRate = (data->frame).header.bitrate;
data->frameOffset[data->currentFrame] = data->inStream.offset;
data->frameOffset[data->currentFrame] = data->inStream->offset;
if(data->stream.this_frame!=NULL) {
data->frameOffset[data->currentFrame]-=
data->stream.bufend-
@ -535,11 +527,12 @@ void initAudioFormatFromMp3DecodeData(mp3DecodeData * data, AudioFormat * af) {
af->channels = MAD_NCHANNELS(&(data->frame).header);
}
int mp3_decode(OutputBuffer * cb, DecoderControl * dc) {
int mp3_decode(OutputBuffer * cb, DecoderControl * dc, InputStream * inStream) {
mp3DecodeData data;
if(openMp3(dc->file,&data) < 0) {
if(openMp3FromInputStream(inStream, &data) < 0) {
ERROR("Input does not appear to be a mp3 bit stream.\n");
closeInputStream(inStream);
return -1;
}

View File

@ -24,11 +24,12 @@
#ifdef HAVE_MAD
#include "playerData.h"
#include "inputStream.h"
/* this is primarily used in tag.c */
int getMp3TotalTime(char * file);
int mp3_decode(OutputBuffer * cb, DecoderControl * dc);
int mp3_decode(OutputBuffer * cb, DecoderControl * dc, InputStream * inStream);
#endif

View File

@ -161,25 +161,29 @@ int playerInit() {
}
int playerGetDecodeType(char * utf8file) {
if(isRemoteUrl(utf8file)) return DECODE_TYPE_MP3;
if(!isFile(utf8file,NULL)) return -1;
if(isRemoteUrl(utf8file)) return DECODE_TYPE_URL;
if(isFile(utf8file,NULL)) return DECODE_TYPE_FILE;
return -1;
}
int playerGetSuffix(char * utf8file) {
#ifdef HAVE_MAD
if(hasMp3Suffix(utf8file)) return DECODE_TYPE_MP3;
if(hasMp3Suffix(utf8file)) return DECODE_SUFFIX_MP3;
#endif
#ifdef HAVE_OGG
if(hasOggSuffix(utf8file)) return DECODE_TYPE_OGG;
#endif
#ifdef HAVE_FLAC
if(hasFlacSuffix(utf8file)) return DECODE_TYPE_FLAC;
#endif
#ifdef HAVE_AUDIOFILE
if(hasWaveSuffix(utf8file)) return DECODE_TYPE_AUDIOFILE;
#ifdef HAVE_OGG
if(hasOggSuffix(utf8file)) return DECODE_SUFFIX_OGG;
#endif
#ifdef HAVE_FAAD
if(hasAacSuffix(utf8file)) return DECODE_TYPE_AAC;
if(hasMp4Suffix(utf8file)) return DECODE_TYPE_MP4;
if(hasAacSuffix(utf8file)) return DECODE_SUFFIX_AAC;
if(hasMp4Suffix(utf8file)) return DECODE_SUFFIX_MP4;
#endif
return -1;
#ifdef HAVE_FLAC
if(hasFlacSuffix(utf8file)) return DECODE_SUFFIX_FLAC;
#endif
#ifdef HAVE_AUDIOFILE
if(hasWaveSuffix(utf8file)) return DECODE_SUFFIX_WAVE;
#endif
return -1;
}
int playerPlay(FILE * fp, char * utf8file) {
@ -208,6 +212,7 @@ int playerPlay(FILE * fp, char * utf8file) {
return 0;
}
pc->decodeType = decodeType;
pc->fileSuffix = playerGetSuffix(utf8file);
if(isRemoteUrl(utf8file)) {
strncpy(pc->file,utf8file,MAXPATHLEN);
@ -366,6 +371,7 @@ int queueSong(char * utf8file) {
decodeType = playerGetDecodeType(utf8file);
if(decodeType < 0) return -1;
pc->decodeType = decodeType;
pc->fileSuffix = playerGetSuffix(utf8file);
pc->queueState = PLAYER_QUEUE_FULL;
return 0;
@ -428,6 +434,7 @@ int playerSeek(FILE * fp, char * utf8file, float time) {
return -1;
}
pc->decodeType = decodeType;
pc->fileSuffix = playerGetSuffix(utf8file);
strncpy(pc->file,file,MAXPATHLEN);
pc->file[MAXPATHLEN] = '\0';

View File

@ -52,6 +52,7 @@
typedef struct _PlayerControl {
volatile mpd_sint8 decodeType;
volatile mpd_sint8 fileSuffix;
volatile mpd_sint8 stop;
volatile mpd_sint8 play;
volatile mpd_sint8 pause;