Commit 4f093d5b authored by Max Kellermann's avatar Max Kellermann

Merge branch 'v0.16.x'

Conflicts: Makefile.am NEWS configure.ac src/encoder/flac_encoder.c src/log.c src/pcm_buffer.c
parents 37420c34 e1b032cb
......@@ -84,7 +84,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 \
......@@ -258,7 +257,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 \
......@@ -1035,6 +1035,9 @@ test_run_decoder_SOURCES = test/run_decoder.c \
src/audio_check.c \
src/audio_format.c \
src/timer.c \
$(ARCHIVE_SRC) \
$(INPUT_SRC) \
$(TAG_SRC) \
$(DECODER_SRC)
test_read_tags_LDADD = \
......@@ -1093,6 +1096,7 @@ if ENABLE_ENCODER
noinst_PROGRAMS += test/run_encoder
test_run_encoder_SOURCES = test/run_encoder.c \
test/stdbin.h \
src/fifo_buffer.c src/growing_fifo.c \
src/conf.c src/tokenizer.c \
src/utils.c src/string_util.c \
src/tag.c src/tag_pool.c \
......@@ -1148,7 +1152,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/resolver.c \
......
......@@ -28,6 +28,21 @@ ver 0.17 (2011/??/??)
* support floating point samples
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
* mapper: fix the bogus "not a directory" error message
* mapper: check "x" and "r" permissions on music directory
* log: print reason for failure
* event_pipe: fix WIN32 regression
* define WINVER in ./configure
* WIN32: autodetect filesystem encoding
ver 0.16.5 (2010/10/09)
* configure.ac
- disable assertions in the non-debugging build
......
......@@ -65,6 +65,7 @@ AC_CANONICAL_HOST
case "$host_os" in
mingw32* | windows*)
AM_CPPFLAGS="$AM_CPPFLAGS -DWINVER=0x0501"
LIBS="$LIBS -lws2_32"
;;
esac
......
......@@ -400,13 +400,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,
......@@ -415,7 +408,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;
......
......@@ -96,6 +96,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 */
......
......@@ -46,7 +46,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 have_stat; /* not needed if ino_t == dev_t == 0 is impossible */
char path[sizeof(long)];
};
......
......@@ -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 <assert.h>
#include <string.h>
......@@ -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 immediately outputs data through 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;
}
......
......@@ -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 <assert.h>
#include <string.h>
......@@ -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;
}
......
......@@ -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 <assert.h>
#include <string.h>
......@@ -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));
......@@ -125,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;
......@@ -139,19 +141,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 +210,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 +243,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 +251,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 +276,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,
......
......@@ -21,7 +21,6 @@
#include "event_pipe.h"
#include "fd_util.h"
#include "mpd_error.h"
#include "glib_socket.h"
#include <stdbool.h>
#include <assert.h>
......@@ -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);
......
......@@ -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)
{
......@@ -66,6 +99,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)
{
......
......@@ -57,12 +57,37 @@ 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.
*/
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
* pointers.
......
/*
* 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 <assert.h>
#include <string.h>
/**
* 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);
}
/*
* 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 <stddef.h>
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
......@@ -31,6 +31,10 @@
#include <assert.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <dirent.h>
static char *music_dir;
static size_t music_dir_length;
......@@ -52,24 +56,50 @@ strdup_chop_slash(const char *path_fs)
}
static void
check_directory(const char *path)
{
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;
}
#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
DIR *dir = opendir(path);
if (dir == NULL && errno == EACCES)
g_warning("No permission to read directory: %s", path);
else
closedir(dir);
}
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)
......
......@@ -27,6 +27,11 @@
#include <assert.h>
#include <string.h>
#ifdef G_OS_WIN32
#include <windows.h> // for GetACP()
#include <stdio.h> // 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 <gstdio.h> helpers are used.
* MPD uses regular <stdio.h> functions.
* Those functions use encoding determined by GetACP(). */
char win_charset[13];
sprintf(win_charset, "cp%u", GetACP());
charset = win_charset;
#endif
}
if (charset) {
......
/*
<<<<<<< HEAD
* Copyright (C) 2003-2011 The Music Player Daemon Project
=======
* Copyright (C) 2003-2010 The Music Player Daemon Project
>>>>>>> v0.16.x
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......@@ -19,17 +23,30 @@
#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)
{
assert(buffer != NULL);
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->size = align_8k(size);
buffer->buffer = g_malloc(buffer->size);
}
assert(buffer->size >= size);
return buffer->buffer;
}
......@@ -22,6 +22,8 @@
#include <glib.h>
#include <assert.h>
/**
* 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;
......
......@@ -123,6 +123,6 @@ int stats_print(struct client *client)
(long)g_timer_elapsed(stats.timer, NULL),
(long)(pc_get_total_play_time(client->player_control) + 0.5),
stats.song_duration,
db_get_mtime());
(long)db_get_mtime());
return 0;
}
......@@ -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->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");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment