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
2a83ccdb
Commit
2a83ccdb
authored
Aug 26, 2008
by
Max Kellermann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
added decoder_data()
Moved all of the player-waiting code to decoder_data(), to make OutputBuffer more generic.
parent
8814c0c8
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
177 additions
and
136 deletions
+177
-136
decoder_api.c
src/decoder_api.c
+80
-0
decoder_api.h
src/decoder_api.h
+15
-0
_flac_common.h
src/inputPlugins/_flac_common.h
+5
-6
aac_plugin.c
src/inputPlugins/aac_plugin.c
+3
-3
audiofile_plugin.c
src/inputPlugins/audiofile_plugin.c
+7
-7
mod_plugin.c
src/inputPlugins/mod_plugin.c
+3
-3
mp3_plugin.c
src/inputPlugins/mp3_plugin.c
+16
-15
mp4_plugin.c
src/inputPlugins/mp4_plugin.c
+3
-3
mpc_plugin.c
src/inputPlugins/mpc_plugin.c
+8
-8
oggvorbis_plugin.c
src/inputPlugins/oggvorbis_plugin.c
+9
-10
wavpack_plugin.c
src/inputPlugins/wavpack_plugin.c
+4
-4
outputBuffer.c
src/outputBuffer.c
+16
-66
outputBuffer.h
src/outputBuffer.h
+8
-11
No files found.
src/decoder_api.c
View file @
2a83ccdb
...
...
@@ -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
;
}
src/decoder_api.h
View file @
2a83ccdb
...
...
@@ -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
src/inputPlugins/_flac_common.h
View file @
2a83ccdb
...
...
@@ -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
;
...
...
src/inputPlugins/aac_plugin.c
View file @
2a83ccdb
...
...
@@ -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
();
...
...
src/inputPlugins/audiofile_plugin.c
View file @
2a83ccdb
...
...
@@ -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
;
}
...
...
src/inputPlugins/mod_plugin.c
View file @
2a83ccdb
...
...
@@ -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
();
...
...
src/inputPlugins/mp3_plugin.c
View file @
2a83ccdb
...
...
@@ -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
)
...
...
src/inputPlugins/mp4_plugin.c
View file @
2a83ccdb
...
...
@@ -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
;
...
...
src/inputPlugins/mpc_plugin.c
View file @
2a83ccdb
...
...
@@ -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
();
...
...
src/inputPlugins/oggvorbis_plugin.c
View file @
2a83ccdb
...
...
@@ -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
)
...
...
src/inputPlugins/wavpack_plugin.c
View file @
2a83ccdb
...
...
@@ -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
);
...
...
src/outputBuffer.c
View file @
2a83ccdb
...
...
@@ -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
)
...
...
src/outputBuffer.h
View file @
2a83ccdb
...
...
@@ -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
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