Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
M
mpd
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Иван Мажукин
mpd
Commits
c51ad71e
Commit
c51ad71e
authored
May 18, 2004
by
Warren Dukes
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
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
parent
6c241805
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
156 additions
and
115 deletions
+156
-115
decode.c
src/decode.c
+83
-46
decode.h
src/decode.h
+11
-8
inputStream_http.c
src/inputStream_http.c
+20
-21
mp3_decode.c
src/mp3_decode.c
+19
-26
mp3_decode.h
src/mp3_decode.h
+2
-1
player.c
src/player.c
+20
-13
player.h
src/player.h
+1
-0
No files found.
src/decode.c
View file @
c51ad71e
...
...
@@ -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,65 +214,101 @@ void decodeSeek(PlayerControl * pc, DecoderControl * dc, OutputBuffer * cb) {
return; \
}
int
decoderInit
(
PlayerControl
*
pc
,
OutputBuffer
*
cb
,
DecoderControl
*
dc
)
{
int
pid
;
int
ret
;
decode_pid
=
&
(
pc
->
decode_pid
);
void
decodeStart
(
PlayerControl
*
pc
,
OutputBuffer
*
cb
,
DecoderControl
*
dc
)
{
int
ret
;
InputStream
inStream
;
blockSignals
(
);
pid
=
fork
()
;
strncpy
(
dc
->
file
,
pc
->
file
,
MAXPATHLEN
);
dc
->
file
[
MAXPATHLEN
]
=
'\0'
;
if
(
pid
==
0
)
{
/* CHILD */
unblockSignals
();
if
(
openInputStream
(
&
inStream
,
dc
->
file
)
<
0
)
{
dc
->
error
=
DECODE_ERROR_FILE
;
dc
->
start
=
0
;
dc
->
stop
=
0
;
dc
->
state
=
DECODE_STATE_STOP
;
return
;
}
while
(
1
)
{
if
(
dc
->
start
)
{
strncpy
(
dc
->
file
,
pc
->
file
,
MAXPATHLEN
);
dc
->
file
[
MAXPATHLEN
]
=
'\0'
;
switch
(
pc
->
decodeType
)
{
while
(
!
inputStreamAtEOF
(
&
inStream
)
&&
bufferInputStream
(
&
inStream
)
<
0
);
switch
(
pc
->
decodeType
)
{
case
DECODE_TYPE_URL
:
#ifdef HAVE_MAD
case
DECODE_TYPE_MP3
:
ret
=
mp3_decode
(
cb
,
dc
);
break
;
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
case
DECODE_TYPE_AAC
:
ret
=
aac_decode
(
cb
,
dc
);
break
;
case
DECODE_TYPE_MP4
:
ret
=
mp4_decode
(
cb
,
dc
);
break
;
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
case
DECODE_TYPE_OGG
:
ret
=
ogg_decode
(
cb
,
dc
);
break
;
if
(
pc
->
fileSuffix
==
DECODE_SUFFIX_OGG
)
{
closeInputStream
(
&
inStream
);
ret
=
ogg_decode
(
cb
,
dc
);
break
;
}
#endif
#ifdef HAVE_FLAC
case
DECODE_TYPE_FLAC
:
ret
=
flac_decode
(
cb
,
dc
);
break
;
if
(
pc
->
fileSuffix
==
DECODE_SUFFIX_FLAC
)
{
closeInputStream
(
&
inStream
);
ret
=
flac_decode
(
cb
,
dc
);
break
;
}
#endif
#ifdef HAVE_AUDIOFILE
case
DECODE_TYPE_AUDIOFILE
:
ret
=
audiofile_decode
(
cb
,
dc
);
break
;
if
(
pc
->
fileSuffix
==
DECODE_SUFFIX_WAVE
)
{
closeInputStream
(
&
inStream
);
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
;
}
}
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
;
decode_pid
=
&
(
pc
->
decode_pid
);
blockSignals
();
pid
=
fork
();
if
(
pid
==
0
)
{
/* CHILD */
unblockSignals
();
while
(
1
)
{
if
(
dc
->
start
)
decodeStart
(
pc
,
cb
,
dc
);
else
if
(
dc
->
stop
)
{
dc
->
state
=
DECODE_STATE_STOP
;
dc
->
stop
=
0
;
...
...
src/decode.h
View file @
c51ad71e
...
...
@@ -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
;
...
...
src/inputStream_http.c
View file @
c51ad71e
...
...
@@ -381,11 +381,13 @@ static int getHTTPHello(InputStream * inStream) {
*
temp
=
'\r'
;
}
else
if
(
0
==
strncmp
(
cur
,
"
\r\n
Content-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
;
...
...
src/mp3_decode.c
View file @
c51ad71e
...
...
@@ -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
(
openMp3
FromInputStream
(
inStream
,
&
data
)
<
0
)
{
ERROR
(
"Input does not appear to be a mp3 bit stream.
\n
"
);
closeInputStream
(
inStream
);
return
-
1
;
}
...
...
src/mp3_decode.h
View file @
c51ad71e
...
...
@@ -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
...
...
src/player.c
View file @
c51ad71e
...
...
@@ -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_SUFFIX_OGG
;
#endif
#ifdef HAVE_OGG
if
(
hasOggSuffix
(
utf8file
))
return
DECODE_TYPE_OGG
;
#ifdef HAVE_FAAD
if
(
hasAacSuffix
(
utf8file
))
return
DECODE_SUFFIX_AAC
;
if
(
hasMp4Suffix
(
utf8file
))
return
DECODE_SUFFIX_MP4
;
#endif
#ifdef HAVE_FLAC
if
(
hasFlacSuffix
(
utf8file
))
return
DECODE_TYPE
_FLAC
;
#ifdef HAVE_FLAC
if
(
hasFlacSuffix
(
utf8file
))
return
DECODE_SUFFIX
_FLAC
;
#endif
#ifdef HAVE_AUDIOFILE
if
(
hasWaveSuffix
(
utf8file
))
return
DECODE_TYPE_AUDIOFILE
;
#endif
#ifdef HAVE_FAAD
if
(
hasAacSuffix
(
utf8file
))
return
DECODE_TYPE_AAC
;
if
(
hasMp4Suffix
(
utf8file
))
return
DECODE_TYPE_MP4
;
if
(
hasWaveSuffix
(
utf8file
))
return
DECODE_SUFFIX_WAVE
;
#endif
return
-
1
;
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'
;
...
...
src/player.h
View file @
c51ad71e
...
...
@@ -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
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment