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
0ea4c970
Commit
0ea4c970
authored
Jul 20, 2011
by
Max Kellermann
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'v0.16.x'
Conflicts: src/player_thread.c src/playlist_control.c
parents
57936a13
838f7cd2
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
102 additions
and
39 deletions
+102
-39
NEWS
NEWS
+7
-0
wavpack_decoder_plugin.c
src/decoder/wavpack_decoder_plugin.c
+18
-29
vorbis_encoder.c
src/encoder/vorbis_encoder.c
+11
-0
encoder_plugin.h
src/encoder_plugin.h
+24
-0
alsa_plugin.c
src/output/alsa_plugin.c
+8
-0
httpd_output_plugin.c
src/output/httpd_output_plugin.c
+3
-2
shout_plugin.c
src/output/shout_plugin.c
+1
-1
output_thread.c
src/output_thread.c
+6
-1
pipe.c
src/pipe.c
+4
-1
pipe.h
src/pipe.h
+5
-0
player_thread.c
src/player_thread.c
+2
-0
playlist_control.c
src/playlist_control.c
+5
-3
update_walk.c
src/update_walk.c
+8
-2
No files found.
NEWS
View file @
0ea4c970
...
@@ -21,9 +21,16 @@ ver 0.17 (2011/??/??)
...
@@ -21,9 +21,16 @@ ver 0.17 (2011/??/??)
ver 0.16.4 (2011/??/??)
ver 0.16.4 (2011/??/??)
* fix memory leaks
* fix memory leaks
* don't resume playback when seeking to another song while paused
* apply follow_inside_symlinks to absolute symlinks
* decoder:
* decoder:
- ffmpeg: workaround for semantic API change in recent ffmpeg versions
- ffmpeg: workaround for semantic API change in recent ffmpeg versions
- flac: validate the sample rate when scanning the tag
- flac: validate the sample rate when scanning the tag
- wavpack: obey all decoder commands, stop at CUE track border
* encoder:
- vorbis: don't send end-of-stream on flush
* output:
- alsa: fix SIGFPE when alsa announces a period size of 0
ver 0.16.3 (2011/06/04)
ver 0.16.3 (2011/06/04)
...
...
src/decoder/wavpack_decoder_plugin.c
View file @
0ea4c970
...
@@ -34,9 +34,6 @@
...
@@ -34,9 +34,6 @@
#undef G_LOG_DOMAIN
#undef G_LOG_DOMAIN
#define G_LOG_DOMAIN "wavpack"
#define G_LOG_DOMAIN "wavpack"
/* pick 1020 since its devisible for 8,16,24, and 32-bit audio */
#define CHUNK_SIZE 1020
#define ERRORLEN 80
#define ERRORLEN 80
static
struct
{
static
struct
{
...
@@ -162,8 +159,6 @@ wavpack_decode(struct decoder *decoder, WavpackContext *wpc, bool can_seek)
...
@@ -162,8 +159,6 @@ wavpack_decode(struct decoder *decoder, WavpackContext *wpc, bool can_seek)
enum
sample_format
sample_format
;
enum
sample_format
sample_format
;
struct
audio_format
audio_format
;
struct
audio_format
audio_format
;
format_samples_t
format_samples
;
format_samples_t
format_samples
;
char
chunk
[
CHUNK_SIZE
];
int
samples_requested
,
samples_got
;
float
total_time
;
float
total_time
;
int
bytes_per_sample
,
output_sample_size
;
int
bytes_per_sample
,
output_sample_size
;
...
@@ -193,12 +188,15 @@ wavpack_decode(struct decoder *decoder, WavpackContext *wpc, bool can_seek)
...
@@ -193,12 +188,15 @@ wavpack_decode(struct decoder *decoder, WavpackContext *wpc, bool can_seek)
output_sample_size
=
audio_format_frame_size
(
&
audio_format
);
output_sample_size
=
audio_format_frame_size
(
&
audio_format
);
/* wavpack gives us all kind of samples in a 32-bit space */
/* wavpack gives us all kind of samples in a 32-bit space */
samples_requested
=
sizeof
(
chunk
)
/
(
4
*
audio_format
.
channels
);
int32_t
chunk
[
1024
];
const
uint32_t
samples_requested
=
G_N_ELEMENTS
(
chunk
)
/
audio_format
.
channels
;
decoder_initialized
(
decoder
,
&
audio_format
,
can_seek
,
total_time
);
decoder_initialized
(
decoder
,
&
audio_format
,
can_seek
,
total_time
);
do
{
enum
decoder_command
cmd
=
decoder_get_command
(
decoder
);
if
(
decoder_get_command
(
decoder
)
==
DECODE_COMMAND_SEEK
)
{
while
(
cmd
!=
DECODE_COMMAND_STOP
)
{
if
(
cmd
==
DECODE_COMMAND_SEEK
)
{
if
(
can_seek
)
{
if
(
can_seek
)
{
unsigned
where
=
decoder_seek_where
(
decoder
)
*
unsigned
where
=
decoder_seek_where
(
decoder
)
*
audio_format
.
sample_rate
;
audio_format
.
sample_rate
;
...
@@ -213,29 +211,20 @@ wavpack_decode(struct decoder *decoder, WavpackContext *wpc, bool can_seek)
...
@@ -213,29 +211,20 @@ wavpack_decode(struct decoder *decoder, WavpackContext *wpc, bool can_seek)
}
}
}
}
if
(
decoder_get_command
(
decoder
)
==
DECODE_COMMAND_STOP
)
{
uint32_t
samples_got
=
WavpackUnpackSamples
(
wpc
,
chunk
,
samples_requested
);
if
(
samples_got
==
0
)
break
;
break
;
}
samples_got
=
WavpackUnpackSamples
(
int
bitrate
=
(
int
)(
WavpackGetInstantBitrate
(
wpc
)
/
1000
+
wpc
,
(
int32_t
*
)
chunk
,
samples_requested
0
.
5
);
);
format_samples
(
bytes_per_sample
,
chunk
,
if
(
samples_got
>
0
)
{
samples_got
*
audio_format
.
channels
);
int
bitrate
=
(
int
)(
WavpackGetInstantBitrate
(
wpc
)
/
1000
+
0
.
5
);
cmd
=
decoder_data
(
decoder
,
NULL
,
chunk
,
samples_got
*
output_sample_size
,
format_samples
(
bitrate
);
bytes_per_sample
,
chunk
,
}
samples_got
*
audio_format
.
channels
);
decoder_data
(
decoder
,
NULL
,
chunk
,
samples_got
*
output_sample_size
,
bitrate
);
}
}
while
(
samples_got
>
0
);
}
}
/**
/**
...
...
src/encoder/vorbis_encoder.c
View file @
0ea4c970
...
@@ -266,6 +266,15 @@ vorbis_encoder_flush(struct encoder *_encoder, G_GNUC_UNUSED GError **error)
...
@@ -266,6 +266,15 @@ vorbis_encoder_flush(struct encoder *_encoder, G_GNUC_UNUSED GError **error)
{
{
struct
vorbis_encoder
*
encoder
=
(
struct
vorbis_encoder
*
)
_encoder
;
struct
vorbis_encoder
*
encoder
=
(
struct
vorbis_encoder
*
)
_encoder
;
encoder
->
flush
=
true
;
return
true
;
}
static
bool
vorbis_encoder_pre_tag
(
struct
encoder
*
_encoder
,
G_GNUC_UNUSED
GError
**
error
)
{
struct
vorbis_encoder
*
encoder
=
(
struct
vorbis_encoder
*
)
_encoder
;
vorbis_analysis_wrote
(
&
encoder
->
vd
,
0
);
vorbis_analysis_wrote
(
&
encoder
->
vd
,
0
);
vorbis_encoder_blockout
(
encoder
);
vorbis_encoder_blockout
(
encoder
);
...
@@ -366,6 +375,7 @@ vorbis_encoder_read(struct encoder *_encoder, void *_dest, size_t length)
...
@@ -366,6 +375,7 @@ vorbis_encoder_read(struct encoder *_encoder, void *_dest, size_t length)
if
(
ret
==
0
&&
encoder
->
flush
)
{
if
(
ret
==
0
&&
encoder
->
flush
)
{
encoder
->
flush
=
false
;
encoder
->
flush
=
false
;
ret
=
ogg_stream_flush
(
&
encoder
->
os
,
&
page
);
ret
=
ogg_stream_flush
(
&
encoder
->
os
,
&
page
);
}
}
if
(
ret
==
0
)
if
(
ret
==
0
)
...
@@ -398,6 +408,7 @@ const struct encoder_plugin vorbis_encoder_plugin = {
...
@@ -398,6 +408,7 @@ const struct encoder_plugin vorbis_encoder_plugin = {
.
open
=
vorbis_encoder_open
,
.
open
=
vorbis_encoder_open
,
.
close
=
vorbis_encoder_close
,
.
close
=
vorbis_encoder_close
,
.
flush
=
vorbis_encoder_flush
,
.
flush
=
vorbis_encoder_flush
,
.
pre_tag
=
vorbis_encoder_pre_tag
,
.
tag
=
vorbis_encoder_tag
,
.
tag
=
vorbis_encoder_tag
,
.
write
=
vorbis_encoder_write
,
.
write
=
vorbis_encoder_write
,
.
read
=
vorbis_encoder_read
,
.
read
=
vorbis_encoder_read
,
...
...
src/encoder_plugin.h
View file @
0ea4c970
...
@@ -50,6 +50,8 @@ struct encoder_plugin {
...
@@ -50,6 +50,8 @@ struct encoder_plugin {
bool
(
*
flush
)(
struct
encoder
*
encoder
,
GError
**
error
);
bool
(
*
flush
)(
struct
encoder
*
encoder
,
GError
**
error
);
bool
(
*
pre_tag
)(
struct
encoder
*
encoder
,
GError
**
error
);
bool
(
*
tag
)(
struct
encoder
*
encoder
,
const
struct
tag
*
tag
,
bool
(
*
tag
)(
struct
encoder
*
encoder
,
const
struct
tag
*
tag
,
GError
**
error
);
GError
**
error
);
...
@@ -148,8 +150,30 @@ encoder_flush(struct encoder *encoder, GError **error)
...
@@ -148,8 +150,30 @@ encoder_flush(struct encoder *encoder, GError **error)
}
}
/**
/**
* Prepare for sending a tag to the encoder. This is used by some
* encoders to flush the previous sub-stream, in preparation to begin
* a new one.
*
* @param encoder the encoder
* @param tag the tag object
* @param error location to store the error occuring, or NULL to ignore errors.
* @return true on success
*/
static
inline
bool
encoder_pre_tag
(
struct
encoder
*
encoder
,
GError
**
error
)
{
/* this method is optional */
return
encoder
->
plugin
->
pre_tag
!=
NULL
?
encoder
->
plugin
->
pre_tag
(
encoder
,
error
)
:
true
;
}
/**
* Sends a tag to the encoder.
* Sends a tag to the encoder.
*
*
* Instructions: call encoder_pre_tag(); then obtain flushed data with
* encoder_read(); finally call encoder_tag().
*
* @param encoder the encoder
* @param encoder the encoder
* @param tag the tag object
* @param tag the tag object
* @param error location to store the error occurring, or NULL to ignore errors.
* @param error location to store the error occurring, or NULL to ignore errors.
...
...
src/output/alsa_plugin.c
View file @
0ea4c970
...
@@ -508,6 +508,14 @@ configure_hw:
...
@@ -508,6 +508,14 @@ configure_hw:
g_debug
(
"buffer_size=%u period_size=%u"
,
g_debug
(
"buffer_size=%u period_size=%u"
,
(
unsigned
)
alsa_buffer_size
,
(
unsigned
)
alsa_period_size
);
(
unsigned
)
alsa_buffer_size
,
(
unsigned
)
alsa_period_size
);
if
(
alsa_period_size
==
0
)
/* this works around a SIGFPE bug that occurred when
an ALSA driver indicated period_size==0; this
caused a division by zero in alsa_play(). By using
the fallback "1", we make sure that this won't
happen again. */
alsa_period_size
=
1
;
ad
->
period_frames
=
alsa_period_size
;
ad
->
period_frames
=
alsa_period_size
;
ad
->
period_position
=
0
;
ad
->
period_position
=
0
;
...
...
src/output/httpd_output_plugin.c
View file @
0ea4c970
...
@@ -493,7 +493,8 @@ httpd_output_pause(void *data)
...
@@ -493,7 +493,8 @@ httpd_output_pause(void *data)
if
(
has_clients
)
{
if
(
has_clients
)
{
static
const
char
silence
[
1020
];
static
const
char
silence
[
1020
];
return
httpd_output_play
(
data
,
silence
,
sizeof
(
silence
),
NULL
);
return
httpd_output_play
(
data
,
silence
,
sizeof
(
silence
),
NULL
)
>
0
;
}
else
{
}
else
{
g_usleep
(
100000
);
g_usleep
(
100000
);
return
true
;
return
true
;
...
@@ -522,7 +523,7 @@ httpd_output_tag(void *data, const struct tag *tag)
...
@@ -522,7 +523,7 @@ httpd_output_tag(void *data, const struct tag *tag)
/* flush the current stream, and end it */
/* flush the current stream, and end it */
encoder_
flush
(
httpd
->
encoder
,
NULL
);
encoder_
pre_tag
(
httpd
->
encoder
,
NULL
);
httpd_output_encoder_to_clients
(
httpd
);
httpd_output_encoder_to_clients
(
httpd
);
/* send the tag to the encoder - which starts a new
/* send the tag to the encoder - which starts a new
...
...
src/output/shout_plugin.c
View file @
0ea4c970
...
@@ -518,7 +518,7 @@ static void my_shout_set_tag(void *data,
...
@@ -518,7 +518,7 @@ static void my_shout_set_tag(void *data,
if
(
sd
->
encoder
->
plugin
->
tag
!=
NULL
)
{
if
(
sd
->
encoder
->
plugin
->
tag
!=
NULL
)
{
/* encoder plugin supports stream tags */
/* encoder plugin supports stream tags */
ret
=
encoder_
flush
(
sd
->
encoder
,
&
error
);
ret
=
encoder_
pre_tag
(
sd
->
encoder
,
&
error
);
if
(
!
ret
)
{
if
(
!
ret
)
{
g_warning
(
"%s"
,
error
->
message
);
g_warning
(
"%s"
,
error
->
message
);
g_error_free
(
error
);
g_error_free
(
error
);
...
...
src/output_thread.c
View file @
0ea4c970
...
@@ -641,8 +641,13 @@ static gpointer audio_output_task(gpointer arg)
...
@@ -641,8 +641,13 @@ static gpointer audio_output_task(gpointer arg)
case
AO_COMMAND_CANCEL
:
case
AO_COMMAND_CANCEL
:
ao
->
chunk
=
NULL
;
ao
->
chunk
=
NULL
;
if
(
ao
->
open
)
if
(
ao
->
open
)
{
g_mutex_unlock
(
ao
->
mutex
);
ao_plugin_cancel
(
ao
->
plugin
,
ao
->
data
);
ao_plugin_cancel
(
ao
->
plugin
,
ao
->
data
);
g_mutex_lock
(
ao
->
mutex
);
}
ao_command_finished
(
ao
);
ao_command_finished
(
ao
);
/* the player thread will now clear our music
/* the player thread will now clear our music
...
...
src/pipe.c
View file @
0ea4c970
...
@@ -187,5 +187,8 @@ music_pipe_push(struct music_pipe *mp, struct music_chunk *chunk)
...
@@ -187,5 +187,8 @@ music_pipe_push(struct music_pipe *mp, struct music_chunk *chunk)
unsigned
unsigned
music_pipe_size
(
const
struct
music_pipe
*
mp
)
music_pipe_size
(
const
struct
music_pipe
*
mp
)
{
{
return
mp
->
size
;
g_mutex_lock
(
mp
->
mutex
);
unsigned
size
=
mp
->
size
;
g_mutex_unlock
(
mp
->
mutex
);
return
size
;
}
}
src/pipe.h
View file @
0ea4c970
...
@@ -20,6 +20,7 @@
...
@@ -20,6 +20,7 @@
#ifndef MPD_PIPE_H
#ifndef MPD_PIPE_H
#define MPD_PIPE_H
#define MPD_PIPE_H
#include <glib.h>
#include <stdbool.h>
#include <stdbool.h>
#ifndef NDEBUG
#ifndef NDEBUG
...
@@ -38,6 +39,7 @@ struct music_pipe;
...
@@ -38,6 +39,7 @@ struct music_pipe;
/**
/**
* Creates a new #music_pipe object. It is empty.
* Creates a new #music_pipe object. It is empty.
*/
*/
G_GNUC_MALLOC
struct
music_pipe
*
struct
music_pipe
*
music_pipe_new
(
void
);
music_pipe_new
(
void
);
...
@@ -70,6 +72,7 @@ music_pipe_contains(const struct music_pipe *mp,
...
@@ -70,6 +72,7 @@ music_pipe_contains(const struct music_pipe *mp,
* Returns the first #music_chunk from the pipe. Returns NULL if the
* Returns the first #music_chunk from the pipe. Returns NULL if the
* pipe is empty.
* pipe is empty.
*/
*/
G_GNUC_PURE
const
struct
music_chunk
*
const
struct
music_chunk
*
music_pipe_peek
(
const
struct
music_pipe
*
mp
);
music_pipe_peek
(
const
struct
music_pipe
*
mp
);
...
@@ -96,9 +99,11 @@ music_pipe_push(struct music_pipe *mp, struct music_chunk *chunk);
...
@@ -96,9 +99,11 @@ music_pipe_push(struct music_pipe *mp, struct music_chunk *chunk);
/**
/**
* Returns the number of chunks currently in this pipe.
* Returns the number of chunks currently in this pipe.
*/
*/
G_GNUC_PURE
unsigned
unsigned
music_pipe_size
(
const
struct
music_pipe
*
mp
);
music_pipe_size
(
const
struct
music_pipe
*
mp
);
G_GNUC_PURE
static
inline
bool
static
inline
bool
music_pipe_empty
(
const
struct
music_pipe
*
mp
)
music_pipe_empty
(
const
struct
music_pipe
*
mp
)
{
{
...
...
src/player_thread.c
View file @
0ea4c970
...
@@ -628,7 +628,9 @@ play_chunk(struct player_control *pc,
...
@@ -628,7 +628,9 @@ play_chunk(struct player_control *pc,
return
true
;
return
true
;
}
}
player_lock
(
pc
);
pc
->
bit_rate
=
chunk
->
bit_rate
;
pc
->
bit_rate
=
chunk
->
bit_rate
;
player_unlock
(
pc
);
/* send the chunk to the audio outputs */
/* send the chunk to the audio outputs */
...
...
src/playlist_control.c
View file @
0ea4c970
...
@@ -230,10 +230,12 @@ playlist_seek_song(struct playlist *playlist, struct player_control *pc,
...
@@ -230,10 +230,12 @@ playlist_seek_song(struct playlist *playlist, struct player_control *pc,
playlist
->
error_count
=
0
;
playlist
->
error_count
=
0
;
if
(
!
playlist
->
playing
||
(
unsigned
)
playlist
->
current
!=
i
)
{
if
(
!
playlist
->
playing
||
(
unsigned
)
playlist
->
current
!=
i
)
{
/* seeking is not within the current song - first
/* seeking is not within the current song - prepare
start playing the new song */
song change */
playlist
->
playing
=
true
;
playlist
->
current
=
i
;
playlist_play_order
(
playlist
,
pc
,
i
);
queued
=
NULL
;
queued
=
NULL
;
}
}
...
...
src/update_walk.c
View file @
0ea4c970
...
@@ -714,8 +714,14 @@ skip_symlink(const struct directory *directory, const char *utf8_name)
...
@@ -714,8 +714,14 @@ skip_symlink(const struct directory *directory, const char *utf8_name)
return
false
;
return
false
;
}
}
if
(
buffer
[
0
]
==
'/'
)
if
(
g_path_is_absolute
(
buffer
))
{
return
!
follow_outside_symlinks
;
/* if the symlink points to an absolute path, see if
that path is inside the music directory */
const
char
*
relative
=
map_to_relative_path
(
buffer
);
return
relative
>
buffer
?
!
follow_inside_symlinks
:
!
follow_outside_symlinks
;
}
p
=
buffer
;
p
=
buffer
;
while
(
*
p
==
'.'
)
{
while
(
*
p
==
'.'
)
{
...
...
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