From fa5e06f95dd7a96b3d188fd4bbcf085a98235bb5 Mon Sep 17 00:00:00 2001 From: Avuton Olrich Date: Sun, 9 Oct 2011 04:44:51 -0700 Subject: Modify version string to post-release version 0.16.6~git --- NEWS | 3 +++ configure.ac | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index ab2eaf4dd..933cbd8d6 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,6 @@ +ver 0.16.6 (2010/??/??) + + ver 0.16.5 (2010/10/09) * configure.ac - disable assertions in the non-debugging build diff --git a/configure.ac b/configure.ac index 0ef99704e..c47c6d9e9 100644 --- a/configure.ac +++ b/configure.ac @@ -1,5 +1,5 @@ AC_PREREQ(2.60) -AC_INIT(mpd, 0.16.5, musicpd-dev-team@lists.sourceforge.net) +AC_INIT(mpd, 0.16.6~git, musicpd-dev-team@lists.sourceforge.net) AC_CONFIG_SRCDIR([src/main.c]) AM_INIT_AUTOMAKE([foreign 1.10 dist-bzip2 subdir-objects]) AM_CONFIG_HEADER(config.h) -- cgit v1.2.3 From 04525c025924fd133fce9115057b422ecd2b5ca0 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 13 Oct 2011 09:08:37 +0200 Subject: event_pipe: fix WIN32 regression The event pipe is not a socket, and the patch that introduced g_io_channel_new_socket() to the event pipe library was wrong. --- NEWS | 1 + src/event_pipe.c | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 933cbd8d6..31bbc4ac1 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,5 @@ ver 0.16.6 (2010/??/??) +* event_pipe: fix WIN32 regression ver 0.16.5 (2010/10/09) diff --git a/src/event_pipe.c b/src/event_pipe.c index edfd40eb5..5b519984f 100644 --- a/src/event_pipe.c +++ b/src/event_pipe.c @@ -21,7 +21,6 @@ #include "event_pipe.h" #include "fd_util.h" #include "mpd_error.h" -#include "glib_socket.h" #include #include @@ -95,7 +94,11 @@ void event_pipe_init(void) if (ret < 0) MPD_ERROR("Couldn't open pipe: %s", strerror(errno)); - channel = g_io_channel_new_socket(event_pipe[0]); +#ifndef G_OS_WIN32 + channel = g_io_channel_unix_new(event_pipe[0]); +#else + channel = g_io_channel_win32_new_fd(event_pipe[0]); +#endif g_io_channel_set_encoding(channel, NULL, NULL); g_io_channel_set_buffered(channel, false); -- cgit v1.2.3 From d3940179261cd4fe3ba632cf7d012917e0fbaa87 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 13 Oct 2011 09:09:58 +0200 Subject: decoder_thread: add missing stdio.h include --- src/decoder_thread.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/decoder_thread.c b/src/decoder_thread.c index 201cd5acd..bb3ef9348 100644 --- a/src/decoder_thread.c +++ b/src/decoder_thread.c @@ -38,6 +38,7 @@ #include #include +#include /* for SEEK_SET */ #undef G_LOG_DOMAIN #define G_LOG_DOMAIN "decoder_thread" -- cgit v1.2.3 From c30c46cd5f0d1f857fc38a335ca499cc024e0c80 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 13 Oct 2011 09:23:32 +0200 Subject: configure.ac: define WINVER Ensure that WINVER is defined early enough, so other system headers won't fall back to their default value. Specifically, this solves a build failure (-Werror) with mingw-w64 ("WINVER redefined"). --- NEWS | 1 + configure.ac | 1 + src/main_win32.c | 1 - src/server_socket.c | 1 - src/socket_util.c | 1 - 5 files changed, 2 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index 31bbc4ac1..b2bd52da4 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,6 @@ ver 0.16.6 (2010/??/??) * event_pipe: fix WIN32 regression +* define WINVER in ./configure ver 0.16.5 (2010/10/09) diff --git a/configure.ac b/configure.ac index c47c6d9e9..478639e7b 100644 --- a/configure.ac +++ b/configure.ac @@ -68,6 +68,7 @@ AC_CANONICAL_HOST case "$host_os" in mingw32* | windows*) + AM_CPPFLAGS="$AM_CPPFLAGS -DWINVER=0x0501" MPD_LIBS="$MPD_LIBS -lws2_32" ;; esac diff --git a/src/main_win32.c b/src/main_win32.c index 543d8ba81..e1ddb53f5 100644 --- a/src/main_win32.c +++ b/src/main_win32.c @@ -27,7 +27,6 @@ #include -#define WINVER 0x0501 #include static int service_argc; diff --git a/src/server_socket.c b/src/server_socket.c index b4114d2d9..482e0cda1 100644 --- a/src/server_socket.c +++ b/src/server_socket.c @@ -34,7 +34,6 @@ #include #ifdef WIN32 -#define WINVER 0x0501 #include #include #else diff --git a/src/socket_util.c b/src/socket_util.c index 3f7075ed3..d1651066f 100644 --- a/src/socket_util.c +++ b/src/socket_util.c @@ -28,7 +28,6 @@ #include #include #else /* G_OS_WIN32 */ -#define WINVER 0x0501 #include #include #endif /* G_OS_WIN32 */ -- cgit v1.2.3 From 6452461c3903139c7bbed3d1eb2705bf1dde656f Mon Sep 17 00:00:00 2001 From: Denis Krjuchkov Date: Sat, 22 Oct 2011 00:57:30 +0600 Subject: path: autodetect filesystem encoding on Win32 WinAPI explicitly declares filesystem encoding. It can be determined by GetACP(). Use that instead of Glib routine that always "detects" UTF-8 on Win32, which is incorrect for MPD case. --- NEWS | 1 + src/path.c | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/NEWS b/NEWS index b2bd52da4..f91548813 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,7 @@ ver 0.16.6 (2010/??/??) * event_pipe: fix WIN32 regression * define WINVER in ./configure +* WIN32: autodetect filesystem encoding ver 0.16.5 (2010/10/09) diff --git a/src/path.c b/src/path.c index 5e39c1636..d1b9ad6ee 100644 --- a/src/path.c +++ b/src/path.c @@ -27,6 +27,11 @@ #include #include +#ifdef G_OS_WIN32 +#include // for GetACP() +#include // for sprintf() +#endif + #undef G_LOG_DOMAIN #define G_LOG_DOMAIN "path" @@ -85,11 +90,22 @@ void path_global_init(void) charset = config_get_string(CONF_FS_CHARSET, NULL); if (charset == NULL) { +#ifndef G_OS_WIN32 const gchar **encodings; g_get_filename_charsets(&encodings); if (encodings[0] != NULL && *encodings[0] != '\0') charset = encodings[0]; +#else /* G_OS_WIN32 */ + /* Glib claims that file system encoding is always utf-8 + * on native Win32 (i.e. not Cygwin). + * However this is true only if helpers are used. + * MPD uses regular functions. + * Those functions use encoding determined by GetACP(). */ + char win_charset[13]; + sprintf(win_charset, "cp%u", GetACP()); + charset = win_charset; +#endif } if (charset) { -- cgit v1.2.3 From ef40e362c9f622c8840419981c0681deeaf4509f Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Sun, 27 Nov 2011 19:19:43 +0100 Subject: decoder_api: cancel initial seek when song is not seekable Fixes assertion failure. --- NEWS | 2 ++ src/decoder_api.c | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/NEWS b/NEWS index f91548813..fc62549fb 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,6 @@ ver 0.16.6 (2010/??/??) +* decoder: + - fix assertion failure when resuming streams * event_pipe: fix WIN32 regression * define WINVER in ./configure * WIN32: autodetect filesystem encoding diff --git a/src/decoder_api.c b/src/decoder_api.c index 6dcca32c2..695ca0281 100644 --- a/src/decoder_api.c +++ b/src/decoder_api.c @@ -95,6 +95,12 @@ decoder_prepare_initial_seek(struct decoder *decoder) return true; if (decoder->initial_seek_pending) { + if (!dc->seekable) { + /* seeking is not possible */ + decoder->initial_seek_pending = false; + return false; + } + if (dc->command == DECODE_COMMAND_NONE) { /* begin initial seek */ -- cgit v1.2.3 From 624e7a447d5cdf38e176acad0ef2ec6543397f46 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Sun, 27 Nov 2011 20:07:10 +0100 Subject: stats: explicitly cast "time_t" to "long" Fixes warning on mingw32. --- src/stats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stats.c b/src/stats.c index 673d531ec..718d8633a 100644 --- a/src/stats.c +++ b/src/stats.c @@ -116,6 +116,6 @@ int stats_print(struct client *client) (long)g_timer_elapsed(stats.timer, NULL), (long)(pc_get_total_play_time() + 0.5), stats.song_duration, - db_get_mtime()); + (long)db_get_mtime()); return 0; } -- cgit v1.2.3 From 2bb5bfa74e52c3a547e5f46e25156cc8d7cade65 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Sun, 27 Nov 2011 20:10:54 +0100 Subject: directory: convert "stat" to a bool --- src/directory.h | 2 +- src/update_walk.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/directory.h b/src/directory.h index 151cf5423..5c36291eb 100644 --- a/src/directory.h +++ b/src/directory.h @@ -43,7 +43,7 @@ struct directory { time_t mtime; ino_t inode; dev_t device; - unsigned stat; /* not needed if ino_t == dev_t == 0 is impossible */ + bool stat; /* not needed if ino_t == dev_t == 0 is impossible */ char path[sizeof(long)]; }; diff --git a/src/update_walk.c b/src/update_walk.c index bf3c8f54b..76c07773b 100644 --- a/src/update_walk.c +++ b/src/update_walk.c @@ -86,7 +86,7 @@ directory_set_stat(struct directory *dir, const struct stat *st) { dir->inode = st->st_ino; dir->device = st->st_dev; - dir->stat = 1; + dir->stat = true; } static void -- cgit v1.2.3 From cd108ba3aa9f4b0b8ebea3ce463c1e6e1e5a5abe Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Sun, 27 Nov 2011 20:15:25 +0100 Subject: directory: rename attribute "stat" to "have_stat" "stat" is a macro on mingw32, which is a pretty stupid thing, and this commit works around this build failure. --- src/directory.h | 2 +- src/update_walk.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/directory.h b/src/directory.h index 5c36291eb..9c0a9b567 100644 --- a/src/directory.h +++ b/src/directory.h @@ -43,7 +43,7 @@ struct directory { time_t mtime; ino_t inode; dev_t device; - bool stat; /* not needed if ino_t == dev_t == 0 is impossible */ + bool have_stat; /* not needed if ino_t == dev_t == 0 is impossible */ char path[sizeof(long)]; }; diff --git a/src/update_walk.c b/src/update_walk.c index 76c07773b..426bd62ff 100644 --- a/src/update_walk.c +++ b/src/update_walk.c @@ -86,7 +86,7 @@ directory_set_stat(struct directory *dir, const struct stat *st) { dir->inode = st->st_ino; dir->device = st->st_dev; - dir->stat = true; + dir->have_stat = true; } static void @@ -346,7 +346,7 @@ inodeFoundInParent(struct directory *parent, ino_t inode, dev_t device) { #ifndef G_OS_WIN32 while (parent) { - if (!parent->stat && statDirectory(parent) < 0) + if (!parent->have_stat && statDirectory(parent) < 0) return -1; if (parent->inode == inode && parent->device == device) { g_debug("recursive directory found"); -- cgit v1.2.3 From f5f1bfbef1e4f777a5928da901d0ec4cb063b3f1 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Sun, 27 Nov 2011 19:54:09 +0100 Subject: pcm_buffer: un-inline pcm_buffer_get() This method is too complex for inlining. --- Makefile.am | 9 ++++++++- src/pcm_buffer.c | 35 +++++++++++++++++++++++++++++++++++ src/pcm_buffer.h | 17 +++-------------- 3 files changed, 46 insertions(+), 15 deletions(-) create mode 100644 src/pcm_buffer.c diff --git a/Makefile.am b/Makefile.am index 45dd631af..0d1c9bb3b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -144,7 +144,6 @@ mpd_headers = \ src/output/pulse_output_plugin.h \ src/output/winmm_output_plugin.h \ src/page.h \ - src/pcm_buffer.h \ src/pcm_utils.h \ src/pcm_convert.h \ src/pcm_volume.h \ @@ -300,6 +299,7 @@ src_mpd_SOURCES = \ src/path.c \ src/mapper.c \ src/page.c \ + src/pcm_buffer.c src/pcm_buffer.h \ src/pcm_convert.c \ src/pcm_volume.c \ src/pcm_mix.c \ @@ -928,6 +928,7 @@ test_run_decoder_SOURCES = test/run_decoder.c \ src/audio_check.c \ src/audio_format.c \ src/timer.c \ + src/pcm_buffer.c \ $(ARCHIVE_SRC) \ $(INPUT_SRC) \ $(TAG_SRC) \ @@ -950,6 +951,7 @@ test_read_tags_SOURCES = test/read_tags.c \ src/fd_util.c \ src/audio_check.c \ src/timer.c \ + src/pcm_buffer.c \ $(ARCHIVE_SRC) \ $(INPUT_SRC) \ $(TAG_SRC) \ @@ -968,6 +970,7 @@ test_run_filter_SOURCES = test/run_filter.c \ src/pcm_format.c src/pcm_channels.c src/pcm_dither.c \ src/pcm_pack.c \ src/pcm_resample.c src/pcm_resample_fallback.c \ + src/pcm_buffer.c \ src/audio_check.c \ src/audio_format.c \ src/audio_parser.c \ @@ -990,6 +993,7 @@ test_run_encoder_SOURCES = test/run_encoder.c \ src/audio_check.c \ src/audio_format.c \ src/audio_parser.c \ + src/pcm_buffer.c \ $(ENCODER_SRC) test_run_encoder_CPPFLAGS = $(AM_CPPFLAGS) \ $(ENCODER_CFLAGS) @@ -1019,6 +1023,7 @@ test_run_convert_SOURCES = test/run_convert.c \ src/audio_format.c \ src/audio_check.c \ src/audio_parser.c \ + src/pcm_buffer.c \ src/pcm_channels.c \ src/pcm_format.c \ src/pcm_pack.c \ @@ -1069,6 +1074,7 @@ test_run_output_SOURCES = test/run_output.c \ src/filter/normalize_filter_plugin.c \ src/filter/volume_filter_plugin.c \ src/pcm_volume.c \ + src/pcm_buffer.c \ src/AudioCompress/compress.c \ src/replay_gain_info.c \ src/replay_gain_config.c \ @@ -1087,6 +1093,7 @@ test_read_mixer_SOURCES = test/read_mixer.c \ src/filter_plugin.c \ src/filter/volume_filter_plugin.c \ src/fd_util.c \ + src/pcm_buffer.c \ $(MIXER_SRC) if ENABLE_BZIP2_TEST diff --git a/src/pcm_buffer.c b/src/pcm_buffer.c new file mode 100644 index 000000000..126a4e036 --- /dev/null +++ b/src/pcm_buffer.c @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2003-2010 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "pcm_buffer.h" + +void * +pcm_buffer_get(struct pcm_buffer *buffer, size_t size) +{ + if (buffer->size < size) { + /* free the old buffer */ + g_free(buffer->buffer); + + /* allocate a new buffer; align at 8 kB boundaries */ + buffer->size = ((size - 1) | 0x1fff) + 1; + buffer->buffer = g_malloc(buffer->size); + } + + return buffer->buffer; +} diff --git a/src/pcm_buffer.h b/src/pcm_buffer.h index 73959ea03..b1c597407 100644 --- a/src/pcm_buffer.h +++ b/src/pcm_buffer.h @@ -58,19 +58,8 @@ pcm_buffer_deinit(struct pcm_buffer *buffer) * Get the buffer, and guarantee a minimum size. This buffer becomes * invalid with the next pcm_buffer_get() call. */ -static inline void * -pcm_buffer_get(struct pcm_buffer *buffer, size_t size) -{ - if (buffer->size < size) { - /* free the old buffer */ - g_free(buffer->buffer); - - /* allocate a new buffer; align at 8 kB boundaries */ - buffer->size = ((size - 1) | 0x1fff) + 1; - buffer->buffer = g_malloc(buffer->size); - } - - return buffer->buffer; -} +G_GNUC_MALLOC +void * +pcm_buffer_get(struct pcm_buffer *buffer, size_t size); #endif -- cgit v1.2.3 From a1e824ada0a08c0065a8a85a2e2aa979f6e97121 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Sun, 27 Nov 2011 20:04:56 +0100 Subject: pcm_buffer: move formula to new function align_8k() --- src/pcm_buffer.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/pcm_buffer.c b/src/pcm_buffer.c index 126a4e036..75b76a5d3 100644 --- a/src/pcm_buffer.c +++ b/src/pcm_buffer.c @@ -19,6 +19,16 @@ #include "pcm_buffer.h" +/** + * Align the specified size to the next 8k boundary. + */ +G_GNUC_CONST +static size_t +align_8k(size_t size) +{ + return ((size - 1) | 0x1fff) + 1; +} + void * pcm_buffer_get(struct pcm_buffer *buffer, size_t size) { @@ -26,8 +36,7 @@ pcm_buffer_get(struct pcm_buffer *buffer, size_t size) /* free the old buffer */ g_free(buffer->buffer); - /* allocate a new buffer; align at 8 kB boundaries */ - buffer->size = ((size - 1) | 0x1fff) + 1; + buffer->size = align_8k(size); buffer->buffer = g_malloc(buffer->size); } -- cgit v1.2.3 From 07067f8b958d52699526f4f757bca2714da183f4 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Sun, 27 Nov 2011 20:05:57 +0100 Subject: pcm_buffer: add assertions --- src/pcm_buffer.c | 4 ++++ src/pcm_buffer.h | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/src/pcm_buffer.c b/src/pcm_buffer.c index 75b76a5d3..b0449d44e 100644 --- a/src/pcm_buffer.c +++ b/src/pcm_buffer.c @@ -32,6 +32,8 @@ align_8k(size_t size) void * pcm_buffer_get(struct pcm_buffer *buffer, size_t size) { + assert(buffer != NULL); + if (buffer->size < size) { /* free the old buffer */ g_free(buffer->buffer); @@ -40,5 +42,7 @@ pcm_buffer_get(struct pcm_buffer *buffer, size_t size) buffer->buffer = g_malloc(buffer->size); } + assert(buffer->size >= size); + return buffer->buffer; } diff --git a/src/pcm_buffer.h b/src/pcm_buffer.h index b1c597407..fe223c742 100644 --- a/src/pcm_buffer.h +++ b/src/pcm_buffer.h @@ -22,6 +22,8 @@ #include +#include + /** * Manager for a temporary buffer which grows as needed. We could * allocate a new buffer every time pcm_convert() is called, but that @@ -39,6 +41,8 @@ struct pcm_buffer { static inline void pcm_buffer_init(struct pcm_buffer *buffer) { + assert(buffer != NULL); + buffer->buffer = NULL; buffer->size = 0; } @@ -49,6 +53,8 @@ pcm_buffer_init(struct pcm_buffer *buffer) static inline void pcm_buffer_deinit(struct pcm_buffer *buffer) { + assert(buffer != NULL); + g_free(buffer->buffer); buffer->buffer = NULL; -- cgit v1.2.3 From a85af593f170f4081b44157d82e746ddc12cdc91 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Sun, 27 Nov 2011 21:11:47 +0100 Subject: fifo_buffer: add functions _capacity() and _available() --- src/fifo_buffer.c | 16 ++++++++++++++++ src/fifo_buffer.h | 13 +++++++++++++ 2 files changed, 29 insertions(+) diff --git a/src/fifo_buffer.c b/src/fifo_buffer.c index 9ac7270bb..65cb2ffdc 100644 --- a/src/fifo_buffer.c +++ b/src/fifo_buffer.c @@ -66,6 +66,22 @@ fifo_buffer_free(struct fifo_buffer *buffer) g_free(buffer); } +size_t +fifo_buffer_capacity(const struct fifo_buffer *buffer) +{ + assert(buffer != NULL); + + return buffer->size; +} + +size_t +fifo_buffer_available(const struct fifo_buffer *buffer) +{ + assert(buffer != NULL); + + return buffer->end - buffer->start; +} + void fifo_buffer_clear(struct fifo_buffer *buffer) { diff --git a/src/fifo_buffer.h b/src/fifo_buffer.h index 661dfd57e..114feec4c 100644 --- a/src/fifo_buffer.h +++ b/src/fifo_buffer.h @@ -62,6 +62,19 @@ fifo_buffer_new(size_t size); void fifo_buffer_free(struct fifo_buffer *buffer); +/** + * Return the capacity of the buffer, i.e. the size that was passed to + * fifo_buffer_new(). + */ +size_t +fifo_buffer_capacity(const struct fifo_buffer *buffer); + +/** + * Return the number of bytes currently stored in the buffer. + */ +size_t +fifo_buffer_available(const struct fifo_buffer *buffer); + /** * Clears all data currently in this #fifo_buffer object. This does * not overwrite the actuall buffer; it just resets the internal -- cgit v1.2.3 From f5468493521c0fd081dc63f920eaf613f746358c Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Sun, 27 Nov 2011 20:58:57 +0100 Subject: fifo_buffer: add function fifo_buffer_realloc() For growing FIFO buffers. --- src/fifo_buffer.c | 35 ++++++++++++++++++++++++++++++++++- src/fifo_buffer.h | 14 +++++++++++++- 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/src/fifo_buffer.c b/src/fifo_buffer.c index 65cb2ffdc..915fb0579 100644 --- a/src/fifo_buffer.c +++ b/src/fifo_buffer.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2010 The Music Player Daemon Project + * Copyright (C) 2003-2011 The Music Player Daemon Project * http://www.musicpd.org * * Redistribution and use in source and binary forms, with or without @@ -58,6 +58,39 @@ fifo_buffer_new(size_t size) return buffer; } +static void +fifo_buffer_move(struct fifo_buffer *buffer); + +struct fifo_buffer * +fifo_buffer_realloc(struct fifo_buffer *buffer, size_t new_size) +{ + if (buffer == NULL) + return new_size > 0 + ? fifo_buffer_new(new_size) + : NULL; + + /* existing data must fit in new size */ + assert(new_size >= buffer->end - buffer->start); + + if (new_size == 0) { + fifo_buffer_free(buffer); + return NULL; + } + + /* compress the buffer when we're shrinking and the tail of + the buffer would exceed the new size */ + if (buffer->end > new_size) + fifo_buffer_move(buffer); + + /* existing data must fit in new size: second check */ + assert(buffer->end <= new_size); + + buffer = g_realloc(buffer, sizeof(*buffer) - sizeof(buffer->buffer) + + new_size); + buffer->size = new_size; + return buffer; +} + void fifo_buffer_free(struct fifo_buffer *buffer) { diff --git a/src/fifo_buffer.h b/src/fifo_buffer.h index 114feec4c..3bdb23938 100644 --- a/src/fifo_buffer.h +++ b/src/fifo_buffer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2010 The Music Player Daemon Project + * Copyright (C) 2003-2011 The Music Player Daemon Project * http://www.musicpd.org * * Redistribution and use in source and binary forms, with or without @@ -56,6 +56,18 @@ struct fifo_buffer; struct fifo_buffer * fifo_buffer_new(size_t size); +/** + * Change the capacity of the #fifo_buffer, while preserving existing + * data. + * + * @param buffer the old buffer, may be NULL + * @param new_size the requested new size of the #fifo_buffer; must + * not be smaller than the data which is stored in the old buffer + * @return the new buffer, may be NULL if the requested new size is 0 + */ +struct fifo_buffer * +fifo_buffer_realloc(struct fifo_buffer *buffer, size_t new_size); + /** * Frees the resources consumed by this #fifo_buffer object. */ -- cgit v1.2.3 From 790823abb4671e6d94c8cb491f29e6448f2b1f85 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 28 Nov 2011 07:48:07 +0100 Subject: growing_fifo: new utility library for growing fifo_buffer --- Makefile.am | 4 +-- src/growing_fifo.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/growing_fifo.h | 73 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 165 insertions(+), 2 deletions(-) create mode 100644 src/growing_fifo.c create mode 100644 src/growing_fifo.h diff --git a/Makefile.am b/Makefile.am index 0d1c9bb3b..7478ffcc2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -85,7 +85,6 @@ mpd_headers = \ src/encoder_api.h \ src/exclude.h \ src/fd_util.h \ - src/fifo_buffer.h \ src/glib_compat.h \ src/update.h \ src/update_internal.h \ @@ -266,7 +265,8 @@ src_mpd_SOURCES = \ src/dirvec.c \ src/exclude.c \ src/fd_util.c \ - src/fifo_buffer.c \ + src/fifo_buffer.c src/fifo_buffer.h \ + src/growing_fifo.c src/growing_fifo.h \ src/filter_config.c \ src/filter_plugin.c \ src/filter_registry.c \ diff --git a/src/growing_fifo.c b/src/growing_fifo.c new file mode 100644 index 000000000..88431f60e --- /dev/null +++ b/src/growing_fifo.c @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2003-2011 The Music Player Daemon Project + * http://www.musicpd.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "growing_fifo.h" +#include "fifo_buffer.h" + +#include +#include + +/** + * Align buffer sizes at 8 kB boundaries. Must be a power of two. + */ +static const size_t GROWING_FIFO_ALIGN = 8192; + +/** + * Align the specified size to the next #GROWING_FIFO_ALIGN boundary. + */ +static size_t +align(size_t size) +{ + return ((size - 1) | (GROWING_FIFO_ALIGN - 1)) + 1; +} + +struct fifo_buffer * +growing_fifo_new(void) +{ + return fifo_buffer_new(GROWING_FIFO_ALIGN); +} + +void * +growing_fifo_write(struct fifo_buffer **buffer_p, size_t length) +{ + assert(buffer_p != NULL); + + struct fifo_buffer *buffer = *buffer_p; + assert(buffer != NULL); + + size_t max_length; + void *p = fifo_buffer_write(buffer, &max_length); + if (p != NULL && max_length >= length) + return p; + + /* grow */ + size_t new_size = fifo_buffer_available(buffer) + length; + assert(new_size > fifo_buffer_capacity(buffer)); + *buffer_p = buffer = fifo_buffer_realloc(buffer, align(new_size)); + + /* try again */ + p = fifo_buffer_write(buffer, &max_length); + assert(p != NULL); + assert(max_length >= length); + + return p; +} + +void +growing_fifo_append(struct fifo_buffer **buffer_p, + const void *data, size_t length) +{ + void *p = growing_fifo_write(buffer_p, length); + memcpy(p, data, length); + fifo_buffer_append(*buffer_p, length); +} diff --git a/src/growing_fifo.h b/src/growing_fifo.h new file mode 100644 index 000000000..723c3b3ff --- /dev/null +++ b/src/growing_fifo.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2003-2011 The Music Player Daemon Project + * http://www.musicpd.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** \file + * + * Helper functions for our FIFO buffer library (fifo_buffer.h) that + * allows growing the buffer on demand. + * + * This library is not thread safe. + */ + +#ifndef MPD_GROWING_FIFO_H +#define MPD_GROWING_FIFO_H + +#include + +struct fifo_buffer; + +/** + * Allocate a new #fifo_buffer with the default size. + */ +struct fifo_buffer * +growing_fifo_new(void); + +/** + * Prepares writing to the buffer, see fifo_buffer_write() for + * details. The difference is that this function will automatically + * grow the buffer if it is too small. + * + * The caller is responsible for limiting the capacity of the buffer. + * + * @param length the number of bytes that will be written + * @return a pointer to the end of the buffer (will not be NULL) + */ +void * +growing_fifo_write(struct fifo_buffer **buffer_p, size_t length); + +/** + * A helper function that combines growing_fifo_write(), memcpy(), + * fifo_buffer_append(). + */ +void +growing_fifo_append(struct fifo_buffer **buffer_p, + const void *data, size_t length); + +#endif -- cgit v1.2.3 From cee5036aca85f37a28f2d52a2fc5ad19878ad511 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 28 Nov 2011 08:00:10 +0100 Subject: encoder/flac: use fifo_buffer instead of pcm_buffer This fixes a buffer corruption bug; pcm_buffer is not designed to be a persistent buffers, and will discard anything between two consecutive calls. --- Makefile.am | 3 ++- NEWS | 2 ++ src/encoder/flac_encoder.c | 36 ++++++++++++++++++++---------------- 3 files changed, 24 insertions(+), 17 deletions(-) diff --git a/Makefile.am b/Makefile.am index 7478ffcc2..6401e3a48 100644 --- a/Makefile.am +++ b/Makefile.am @@ -994,6 +994,7 @@ test_run_encoder_SOURCES = test/run_encoder.c \ src/audio_format.c \ src/audio_parser.c \ src/pcm_buffer.c \ + src/fifo_buffer.c src/growing_fifo.c \ $(ENCODER_SRC) test_run_encoder_CPPFLAGS = $(AM_CPPFLAGS) \ $(ENCODER_CFLAGS) @@ -1057,7 +1058,7 @@ test_run_output_SOURCES = test/run_output.c \ src/audio_parser.c \ src/timer.c \ src/tag.c src/tag_pool.c \ - src/fifo_buffer.c \ + src/fifo_buffer.c src/growing_fifo.c \ src/page.c \ src/socket_util.c \ src/output_init.c src/output_list.c \ diff --git a/NEWS b/NEWS index fc62549fb..b7f0e9f2c 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,8 @@ ver 0.16.6 (2010/??/??) * decoder: - fix assertion failure when resuming streams +* encoder: + - flac: fix buffer corruption bug * event_pipe: fix WIN32 regression * define WINVER in ./configure * WIN32: autodetect filesystem encoding diff --git a/src/encoder/flac_encoder.c b/src/encoder/flac_encoder.c index c34faad00..6389513ef 100644 --- a/src/encoder/flac_encoder.c +++ b/src/encoder/flac_encoder.c @@ -22,6 +22,8 @@ #include "encoder_plugin.h" #include "audio_format.h" #include "pcm_buffer.h" +#include "fifo_buffer.h" +#include "growing_fifo.h" #include #include @@ -38,8 +40,11 @@ struct flac_encoder { struct pcm_buffer expand_buffer; - struct pcm_buffer buffer; - size_t buffer_length; + /** + * This buffer will hold encoded data from libFLAC until it is + * picked up with flac_encoder_read(). + */ + struct fifo_buffer *output_buffer; }; extern const struct encoder_plugin flac_encoder_plugin; @@ -140,11 +145,8 @@ flac_write_callback(G_GNUC_UNUSED const FLAC__StreamEncoder *fse, { struct flac_encoder *encoder = (struct flac_encoder *) client_data; - char *buffer = pcm_buffer_get(&encoder->buffer, encoder->buffer_length + bytes); - //transfer data to buffer - memcpy( buffer + encoder->buffer_length, data, bytes); - encoder->buffer_length += bytes; + growing_fifo_append(&encoder->output_buffer, data, bytes); return FLAC__STREAM_ENCODER_WRITE_STATUS_OK; } @@ -156,8 +158,8 @@ flac_encoder_close(struct encoder *_encoder) FLAC__stream_encoder_delete(encoder->fse); - pcm_buffer_deinit(&encoder->buffer); pcm_buffer_deinit(&encoder->expand_buffer); + fifo_buffer_free(encoder->output_buffer); } static bool @@ -201,10 +203,10 @@ flac_encoder_open(struct encoder *_encoder, struct audio_format *audio_format, return false; } - encoder->buffer_length = 0; - pcm_buffer_init(&encoder->buffer); pcm_buffer_init(&encoder->expand_buffer); + encoder->output_buffer = growing_fifo_new(); + /* this immediatelly outputs data throught callback */ #if !defined(FLAC_API_VERSION_CURRENT) || FLAC_API_VERSION_CURRENT <= 7 @@ -325,16 +327,18 @@ static size_t flac_encoder_read(struct encoder *_encoder, void *dest, size_t length) { struct flac_encoder *encoder = (struct flac_encoder *)_encoder; - char *buffer = pcm_buffer_get(&encoder->buffer, encoder->buffer_length); - - if (length > encoder->buffer_length) - length = encoder->buffer_length; - memcpy(dest, buffer, length); + size_t max_length; + const char *src = fifo_buffer_read(encoder->output_buffer, + &max_length); + if (src == NULL) + return 0; - encoder->buffer_length -= length; - memmove(buffer, buffer + length, encoder->buffer_length); + if (length > max_length) + length = max_length; + memcpy(dest, src, length); + fifo_buffer_consume(encoder->output_buffer, length); return length; } -- cgit v1.2.3 From 399a3abefc00f913945189fdb3a646759f082054 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 28 Nov 2011 08:09:49 +0100 Subject: encoder/wave: use fifo_buffer instead of pcm_buffer This fixes a buffer corruption bug; pcm_buffer is not designed to be a persistent buffers, and will discard anything between two consecutive calls. --- NEWS | 2 +- src/encoder/wave_encoder.c | 46 +++++++++++++++++++++++++++------------------- 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/NEWS b/NEWS index b7f0e9f2c..61257509b 100644 --- a/NEWS +++ b/NEWS @@ -2,7 +2,7 @@ ver 0.16.6 (2010/??/??) * decoder: - fix assertion failure when resuming streams * encoder: - - flac: fix buffer corruption bug + - flac, wave: fix buffer corruption bug * event_pipe: fix WIN32 regression * define WINVER in ./configure * WIN32: autodetect filesystem encoding diff --git a/src/encoder/wave_encoder.c b/src/encoder/wave_encoder.c index 938be5e5e..4e830bd14 100644 --- a/src/encoder/wave_encoder.c +++ b/src/encoder/wave_encoder.c @@ -20,7 +20,8 @@ #include "config.h" #include "encoder_api.h" #include "encoder_plugin.h" -#include "pcm_buffer.h" +#include "fifo_buffer.h" +#include "growing_fifo.h" #include #include @@ -29,8 +30,7 @@ struct wave_encoder { struct encoder encoder; unsigned bits; - struct pcm_buffer buffer; - size_t buffer_length; + struct fifo_buffer *buffer; }; struct wave_header { @@ -92,7 +92,6 @@ wave_encoder_init(G_GNUC_UNUSED const struct config_param *param, encoder = g_new(struct wave_encoder, 1); encoder_struct_init(&encoder->encoder, &wave_encoder_plugin); - pcm_buffer_init(&encoder->buffer); return &encoder->encoder; } @@ -102,7 +101,6 @@ wave_encoder_finish(struct encoder *_encoder) { struct wave_encoder *encoder = (struct wave_encoder *)_encoder; - pcm_buffer_deinit(&encoder->buffer); g_free(encoder); } @@ -112,7 +110,6 @@ wave_encoder_open(struct encoder *_encoder, G_GNUC_UNUSED GError **error) { struct wave_encoder *encoder = (struct wave_encoder *)_encoder; - void *buffer; assert(audio_format_valid(audio_format)); @@ -139,19 +136,29 @@ wave_encoder_open(struct encoder *_encoder, break; } - buffer = pcm_buffer_get(&encoder->buffer, sizeof(struct wave_header) ); + encoder->buffer = growing_fifo_new(); + struct wave_header *header = + growing_fifo_write(&encoder->buffer, sizeof(*header)); /* create PCM wave header in initial buffer */ - fill_wave_header((struct wave_header *) buffer, + fill_wave_header(header, audio_format->channels, encoder->bits, audio_format->sample_rate, (encoder->bits / 8) * audio_format->channels ); + fifo_buffer_append(encoder->buffer, sizeof(*header)); - encoder->buffer_length = sizeof(struct wave_header); return true; } +static void +wave_encoder_close(struct encoder *_encoder) +{ + struct wave_encoder *encoder = (struct wave_encoder *)_encoder; + + fifo_buffer_free(encoder->buffer); +} + static inline size_t pcm16_to_wave(uint16_t *dst16, const uint16_t *src16, size_t length) { @@ -198,9 +205,8 @@ wave_encoder_write(struct encoder *_encoder, G_GNUC_UNUSED GError **error) { struct wave_encoder *encoder = (struct wave_encoder *)_encoder; - void *dst; - dst = pcm_buffer_get(&encoder->buffer, encoder->buffer_length + length); + void *dst = growing_fifo_write(&encoder->buffer, length); #if (G_BYTE_ORDER == G_LITTLE_ENDIAN) switch (encoder->bits) { @@ -232,7 +238,7 @@ wave_encoder_write(struct encoder *_encoder, #error G_BYTE_ORDER set to G_PDP_ENDIAN is not supported by wave_encoder #endif - encoder->buffer_length += length; + fifo_buffer_append(encoder->buffer, length); return true; } @@ -240,16 +246,17 @@ static size_t wave_encoder_read(struct encoder *_encoder, void *dest, size_t length) { struct wave_encoder *encoder = (struct wave_encoder *)_encoder; - uint8_t *buffer = pcm_buffer_get(&encoder->buffer, encoder->buffer_length ); - - if (length > encoder->buffer_length) - length = encoder->buffer_length; - memcpy(dest, buffer, length); + size_t max_length; + const void *src = fifo_buffer_read(encoder->buffer, &max_length); + if (src == NULL) + return 0; - encoder->buffer_length -= length; - memmove(buffer, buffer + length, encoder->buffer_length); + if (length > max_length) + length = max_length; + memcpy(dest, src, length); + fifo_buffer_consume(encoder->buffer, length); return length; } @@ -264,6 +271,7 @@ const struct encoder_plugin wave_encoder_plugin = { .init = wave_encoder_init, .finish = wave_encoder_finish, .open = wave_encoder_open, + .close = wave_encoder_close, .write = wave_encoder_write, .read = wave_encoder_read, .get_mime_type = wave_encoder_get_mime_type, -- cgit v1.2.3 From 74beefcaf6a2a82785649752bf346e5c8fb9ec62 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 28 Nov 2011 08:27:59 +0100 Subject: encoder/null: use fifo_buffer instead of pcm_buffer This fixes a buffer corruption bug; pcm_buffer is not designed to be a persistent buffers, and will discard anything between two consecutive calls. --- NEWS | 2 +- src/encoder/null_encoder.c | 34 +++++++++++++++------------------- 2 files changed, 16 insertions(+), 20 deletions(-) diff --git a/NEWS b/NEWS index 61257509b..441aac8cb 100644 --- a/NEWS +++ b/NEWS @@ -2,7 +2,7 @@ ver 0.16.6 (2010/??/??) * decoder: - fix assertion failure when resuming streams * encoder: - - flac, wave: fix buffer corruption bug + - flac, null, wave: fix buffer corruption bug * event_pipe: fix WIN32 regression * define WINVER in ./configure * WIN32: autodetect filesystem encoding diff --git a/src/encoder/null_encoder.c b/src/encoder/null_encoder.c index bf7e61c3b..4e45f4345 100644 --- a/src/encoder/null_encoder.c +++ b/src/encoder/null_encoder.c @@ -20,7 +20,8 @@ #include "config.h" #include "encoder_api.h" #include "encoder_plugin.h" -#include "pcm_buffer.h" +#include "fifo_buffer.h" +#include "growing_fifo.h" #include #include @@ -28,8 +29,7 @@ struct null_encoder { struct encoder encoder; - struct pcm_buffer buffer; - size_t buffer_length; + struct fifo_buffer *buffer; }; extern const struct encoder_plugin null_encoder_plugin; @@ -65,7 +65,7 @@ null_encoder_close(struct encoder *_encoder) { struct null_encoder *encoder = (struct null_encoder *)_encoder; - pcm_buffer_deinit(&encoder->buffer); + fifo_buffer_free(encoder->buffer); } @@ -76,9 +76,7 @@ null_encoder_open(struct encoder *_encoder, { struct null_encoder *encoder = (struct null_encoder *)_encoder; - encoder->buffer_length = 0; - pcm_buffer_init(&encoder->buffer); - + encoder->buffer = growing_fifo_new(); return true; } @@ -88,28 +86,26 @@ null_encoder_write(struct encoder *_encoder, G_GNUC_UNUSED GError **error) { struct null_encoder *encoder = (struct null_encoder *)_encoder; - char *buffer = pcm_buffer_get(&encoder->buffer, encoder->buffer_length + length); - - memcpy(buffer+encoder->buffer_length, data, length); - encoder->buffer_length += length; - return true; + growing_fifo_append(&encoder->buffer, data, length); + return length; } static size_t null_encoder_read(struct encoder *_encoder, void *dest, size_t length) { struct null_encoder *encoder = (struct null_encoder *)_encoder; - char *buffer = pcm_buffer_get(&encoder->buffer, encoder->buffer_length); - - if (length > encoder->buffer_length) - length = encoder->buffer_length; - memcpy(dest, buffer, length); + size_t max_length; + const void *src = fifo_buffer_read(encoder->buffer, &max_length); + if (src == NULL) + return 0; - encoder->buffer_length -= length; - memmove(buffer, buffer + length, encoder->buffer_length); + if (length > max_length) + length = max_length; + memcpy(dest, src, length); + fifo_buffer_consume(encoder->buffer, length); return length; } -- cgit v1.2.3 From 0a218ee56ae37bcebeb716d5faa18f91e6e75556 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 28 Nov 2011 09:25:42 +0100 Subject: encoder/wave: support packed 24 bit samples Convert to padded 24 bit samples, instead of falling back to 16 bit. --- NEWS | 1 + src/encoder/wave_encoder.c | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/NEWS b/NEWS index 441aac8cb..8857a628d 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,7 @@ ver 0.16.6 (2010/??/??) - fix assertion failure when resuming streams * encoder: - flac, null, wave: fix buffer corruption bug + - wave: support packed 24 bit samples * event_pipe: fix WIN32 regression * define WINVER in ./configure * WIN32: autodetect filesystem encoding diff --git a/src/encoder/wave_encoder.c b/src/encoder/wave_encoder.c index 4e830bd14..3a64c5197 100644 --- a/src/encoder/wave_encoder.c +++ b/src/encoder/wave_encoder.c @@ -122,6 +122,11 @@ wave_encoder_open(struct encoder *_encoder, encoder->bits = 16; break; + case SAMPLE_FORMAT_S24: + audio_format->format = SAMPLE_FORMAT_S24_P32; + encoder->bits = 24; + break; + case SAMPLE_FORMAT_S24_P32: encoder->bits = 24; break; -- cgit v1.2.3 From a727d0bb0b2b3757a32c27caa1b794fe0b3ddf6b Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 28 Nov 2011 09:31:43 +0100 Subject: log: print reason for failure --- NEWS | 1 + src/log.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 8857a628d..28c8b1bb8 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,7 @@ ver 0.16.6 (2010/??/??) * encoder: - flac, null, wave: fix buffer corruption bug - wave: support packed 24 bit samples +* log: print reason for failure * event_pipe: fix WIN32 regression * define WINVER in ./configure * WIN32: autodetect filesystem encoding diff --git a/src/log.c b/src/log.c index 556c8b04f..99a9a8f6d 100644 --- a/src/log.c +++ b/src/log.c @@ -139,8 +139,8 @@ log_init_file(const char *path, unsigned line) out_filename = path; out_fd = open_log_file(); if (out_fd < 0) - MPD_ERROR("problem opening log file \"%s\" (config line %u) " - "for writing\n", path, line); + MPD_ERROR("failed to open log file \"%s\" (config line %u): %s", + path, line, g_strerror(errno)); g_log_set_default_handler(file_log_func, NULL); } -- cgit v1.2.3 From cf15629aeae7b2f750388c6823f43cd5918676a4 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 28 Nov 2011 09:35:50 +0100 Subject: mapper: move code to check_directory() --- src/mapper.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/mapper.c b/src/mapper.c index 108de9531..426b2980f 100644 --- a/src/mapper.c +++ b/src/mapper.c @@ -51,25 +51,28 @@ strdup_chop_slash(const char *path_fs) return g_strndup(path_fs, length); } +static void +check_directory(const char *path) +{ + if (!g_file_test(path, G_FILE_TEST_IS_DIR)) + g_warning("Not a directory: %s", path); +} + static void mapper_set_music_dir(const char *path) { + check_directory(path); + music_dir = strdup_chop_slash(path); music_dir_length = strlen(music_dir); - - if (!g_file_test(music_dir, G_FILE_TEST_IS_DIR)) - g_warning("music directory is not a directory: \"%s\"", - music_dir); } static void mapper_set_playlist_dir(const char *path) { - playlist_dir = g_strdup(path); + check_directory(path); - if (!g_file_test(playlist_dir, G_FILE_TEST_IS_DIR)) - g_warning("playlist directory is not a directory: \"%s\"", - playlist_dir); + playlist_dir = g_strdup(path); } void mapper_init(const char *_music_dir, const char *_playlist_dir) -- cgit v1.2.3 From cead5e5bd75ed2d71f3834adcb02e3d99082df7f Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 28 Nov 2011 09:37:05 +0100 Subject: mapper: fix the bogus "not a directory" error message Use stat() instead of g_file_test() to detect other types of errors, such as "permission denied". --- NEWS | 1 + src/mapper.c | 14 +++++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 28c8b1bb8..aa84dbede 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,7 @@ ver 0.16.6 (2010/??/??) * encoder: - flac, null, wave: fix buffer corruption bug - wave: support packed 24 bit samples +* mapper: fix the bogus "not a directory" error message * log: print reason for failure * event_pipe: fix WIN32 regression * define WINVER in ./configure diff --git a/src/mapper.c b/src/mapper.c index 426b2980f..30d932f95 100644 --- a/src/mapper.c +++ b/src/mapper.c @@ -31,6 +31,9 @@ #include #include +#include +#include +#include static char *music_dir; static size_t music_dir_length; @@ -54,8 +57,17 @@ strdup_chop_slash(const char *path_fs) static void check_directory(const char *path) { - if (!g_file_test(path, G_FILE_TEST_IS_DIR)) + struct stat st; + if (stat(path, &st) < 0) { + g_warning("Failed to stat directory \"%s\": %s", + path, g_strerror(errno)); + return; + } + + if (!S_ISDIR(st.st_mode)) { g_warning("Not a directory: %s", path); + return; + } } static void -- cgit v1.2.3 From 718e180423aeb84fc513858415a201905630580c Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 28 Nov 2011 09:44:36 +0100 Subject: mapper: check "x" permission on music directory This is a common support case, and hopefully, the new error message will allow the user to understand the error without requiring support. --- NEWS | 1 + src/mapper.c | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/NEWS b/NEWS index aa84dbede..223c39321 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,7 @@ ver 0.16.6 (2010/??/??) - flac, null, wave: fix buffer corruption bug - wave: support packed 24 bit samples * mapper: fix the bogus "not a directory" error message +* mapper: check "x" permission on music directory * log: print reason for failure * event_pipe: fix WIN32 regression * define WINVER in ./configure diff --git a/src/mapper.c b/src/mapper.c index 30d932f95..41ed6550b 100644 --- a/src/mapper.c +++ b/src/mapper.c @@ -68,6 +68,14 @@ check_directory(const char *path) g_warning("Not a directory: %s", path); return; } + +#ifndef WIN32 + char *x = g_build_filename(path, ".", NULL); + if (stat(x, &st) < 0 && errno == EACCES) + g_warning("No permission to traverse (\"execute\") directory: %s", + path); + g_free(x); +#endif } static void -- cgit v1.2.3 From 6f365c30eb33c40193defb827b03a8fd293bfc23 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 28 Nov 2011 09:56:03 +0100 Subject: mapper: check "r" permission on music directory Yet another common support case. --- NEWS | 2 +- src/mapper.c | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 223c39321..166541c44 100644 --- a/NEWS +++ b/NEWS @@ -5,7 +5,7 @@ ver 0.16.6 (2010/??/??) - flac, null, wave: fix buffer corruption bug - wave: support packed 24 bit samples * mapper: fix the bogus "not a directory" error message -* mapper: check "x" permission on music directory +* mapper: check "x" and "r" permissions on music directory * log: print reason for failure * event_pipe: fix WIN32 regression * define WINVER in ./configure diff --git a/src/mapper.c b/src/mapper.c index 41ed6550b..3cee41eb3 100644 --- a/src/mapper.c +++ b/src/mapper.c @@ -34,6 +34,7 @@ #include #include #include +#include static char *music_dir; static size_t music_dir_length; @@ -76,6 +77,12 @@ check_directory(const char *path) path); g_free(x); #endif + + DIR *dir = opendir(path); + if (dir == NULL && errno == EACCES) + g_warning("No permission to read directory: %s", path); + else + closedir(dir); } static void -- cgit v1.2.3 From e1b032cbad5db7698104a93c2235fb7da1f8b580 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Sun, 27 Nov 2011 23:39:21 +0100 Subject: decoder/ffmpeg: work around bogus channel count Initialize the audio_format before calling avcodec_open(), because avcodec_open() will fill bogus values. --- NEWS | 1 + src/decoder/ffmpeg_decoder_plugin.c | 20 ++++++++++++-------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/NEWS b/NEWS index 166541c44..b078b8213 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,7 @@ ver 0.16.6 (2010/??/??) * decoder: - fix assertion failure when resuming streams + - ffmpeg: work around bogus channel count * encoder: - flac, null, wave: fix buffer corruption bug - wave: support packed 24 bit samples diff --git a/src/decoder/ffmpeg_decoder_plugin.c b/src/decoder/ffmpeg_decoder_plugin.c index ba47b2c2c..34a6b3ebd 100644 --- a/src/decoder/ffmpeg_decoder_plugin.c +++ b/src/decoder/ffmpeg_decoder_plugin.c @@ -407,13 +407,6 @@ ffmpeg_decode(struct decoder *decoder, struct input_stream *input) return; } - if (avcodec_open(codec_context, codec)<0) { - g_warning("Could not open codec\n"); - av_close_input_stream(format_context); - mpd_ffmpeg_stream_close(stream); - return; - } - GError *error = NULL; struct audio_format audio_format; if (!audio_format_init_checked(&audio_format, @@ -422,7 +415,18 @@ ffmpeg_decode(struct decoder *decoder, struct input_stream *input) codec_context->channels, &error)) { g_warning("%s", error->message); g_error_free(error); - avcodec_close(codec_context); + av_close_input_stream(format_context); + mpd_ffmpeg_stream_close(stream); + return; + } + + /* the audio format must be read from AVCodecContext by now, + because avcodec_open() has been demonstrated to fill bogus + values into AVCodecContext.channels - a change that will be + reverted later by avcodec_decode_audio3() */ + + if (avcodec_open(codec_context, codec)<0) { + g_warning("Could not open codec\n"); av_close_input_stream(format_context); mpd_ffmpeg_stream_close(stream); return; -- cgit v1.2.3