Commit 1e5f57f4 authored by Led's avatar Led

0.14-beta1

parent 1a029af0
......@@ -27,6 +27,9 @@ Patrik Weiskircher <pat@icore.at>
Laszlo Ashin <kodest@gmail.com>
WavPack support
Viliam Mateicka <viliam.mateicka@gmail.com>
FFmpeg support
Former Developers
-----------------
tw-nym
......
......@@ -39,8 +39,7 @@ host_triplet = @host@
DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in $(srcdir)/config.h.in \
$(top_srcdir)/configure AUTHORS COPYING INSTALL NEWS TODO \
compile config.guess config.sub depcomp install-sh ltmain.sh \
missing
compile config.guess config.sub depcomp install-sh missing
subdir = .
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/acx_pthread.m4 \
......@@ -178,6 +177,8 @@ HAVE_SHOUT_OGG_TRUE = @HAVE_SHOUT_OGG_TRUE@
HAVE_SHOUT_TRUE = @HAVE_SHOUT_TRUE@
HAVE_WAVPACK_FALSE = @HAVE_WAVPACK_FALSE@
HAVE_WAVPACK_TRUE = @HAVE_WAVPACK_TRUE@
HAVE_XMLTO_FALSE = @HAVE_XMLTO_FALSE@
HAVE_XMLTO_TRUE = @HAVE_XMLTO_TRUE@
HAVE_ZEROCONF_FALSE = @HAVE_ZEROCONF_FALSE@
HAVE_ZEROCONF_TRUE = @HAVE_ZEROCONF_TRUE@
ID3TAG_CFLAGS = @ID3TAG_CFLAGS@
......@@ -235,6 +236,7 @@ VORBISENC_CFLAGS = @VORBISENC_CFLAGS@
VORBISENC_LIBS = @VORBISENC_LIBS@
WAVPACK_CFLAGS = @WAVPACK_CFLAGS@
WAVPACK_LIBS = @WAVPACK_LIBS@
XMLTO = @XMLTO@
ac_ct_CC = @ac_ct_CC@
acx_pthread_config = @acx_pthread_config@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
......
......@@ -84,29 +84,6 @@ do
fi
done
if test -n "$LIBTOOLIZE"
then
echo "LIBTOOLIZE=$LIBTOOLIZE in environment," \
"will not attempt to auto-detect"
else
printf "checking for libtoolize ... "
for x in libtoolize glibtoolize
do
($x --version < /dev/null > /dev/null 2>&1) > /dev/null 2>&1
if test $? -eq 0
then
echo $x
LIBTOOLIZE=$x
break
fi
done
fi
if test -z "$LIBTOOLIZE"
then
DIE="$DIE libtoolize(libtool)"
fi
if test -n "$DIE"
then
echo "You must have the following installed to compile $package:"
......@@ -148,9 +125,6 @@ $ACLOCAL $ACLOCAL_FLAGS || exit 1
echo " $AUTOHEADER"
$AUTOHEADER || exit 1
echo " $LIBTOOLIZE --automake"
$LIBTOOLIZE --automake || exit 1
echo " $AUTOMAKE --add-missing $AUTOMAKE_FLAGS"
$AUTOMAKE --add-missing $AUTOMAKE_FLAGS || exit 1
......
......@@ -37,6 +37,9 @@
/* Define if FAAD2 uses buflen in function calls */
#undef HAVE_FAAD_BUFLEN_FUNCS
/* Define if faad.h uses the broken "unsigned long" pointers */
#undef HAVE_FAAD_LONG
/* Define for FFMPEG support */
#undef HAVE_FFMPEG
......
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.63 for mpd 0.14~alpha3.
# Generated by GNU Autoconf 2.63 for mpd 0.14~beta1.
#
# Report bugs to <musicpd-dev-team@lists.sourceforge.net>.
#
......@@ -596,8 +596,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
# Identity of this package.
PACKAGE_NAME='mpd'
PACKAGE_TARNAME='mpd'
PACKAGE_VERSION='0.14~alpha3'
PACKAGE_STRING='mpd 0.14~alpha3'
PACKAGE_VERSION='0.14~beta1'
PACKAGE_STRING='mpd 0.14~beta1'
PACKAGE_BUGREPORT='musicpd-dev-team@lists.sourceforge.net'
ac_unique_file="src/main.c"
......@@ -639,6 +639,9 @@ ac_includes_default="\
ac_subst_vars='LTLIBOBJS
LIBOBJS
HAVE_XMLTO_FALSE
HAVE_XMLTO_TRUE
XMLTO
HAVE_ZEROCONF_FALSE
HAVE_ZEROCONF_TRUE
AVAHI_LIBS
......@@ -1478,7 +1481,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
\`configure' configures mpd 0.14~alpha3 to adapt to many kinds of systems.
\`configure' configures mpd 0.14~beta1 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
......@@ -1548,7 +1551,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of mpd 0.14~alpha3:";;
short | recursive ) echo "Configuration of mpd 0.14~beta1:";;
esac
cat <<\_ACEOF
......@@ -1746,7 +1749,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
mpd configure 0.14~alpha3
mpd configure 0.14~beta1
generated by GNU Autoconf 2.63
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
......@@ -1760,7 +1763,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by mpd $as_me 0.14~alpha3, which was
It was created by mpd $as_me 0.14~beta1, which was
generated by GNU Autoconf 2.63. Invocation command line was
$ $0 $@
......@@ -2457,7 +2460,7 @@ fi
# Define the identity of the package.
PACKAGE='mpd'
VERSION='0.14~alpha3'
VERSION='0.14~beta1'
cat >>confdefs.h <<_ACEOF
......@@ -9989,6 +9992,71 @@ fi
if test x$enable_aac = xyes; then
oldcflags=$CFLAGS
oldlibs=$LIBS
oldcppflags=$CPPFLAGS
CFLAGS="$CFLAGS $MPD_CFLAGS $FAAD_CFLAGS -Werror"
LIBS="$LIBS $MPD_LIBS $FAAD_LIBS"
CPPFLAGS=$CFLAGS
{ $as_echo "$as_me:$LINENO: checking for broken libfaad headers" >&5
$as_echo_n "checking for broken libfaad headers... " >&6; }
cat >conftest.$ac_ext <<_ACEOF
#include <faad.h>
#include <stddef.h>
#include <stdint.h>
int main() {
unsigned char channels;
uint32_t sample_rate;
faacDecInit2(NULL, NULL, 0, &sample_rate, &channels);
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (ac_try="$ac_compile"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
$as_echo "$ac_try_echo") >&5
(eval "$ac_compile") 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
$as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } && {
test -z "$ac_c_werror_flag" ||
test ! -s conftest.err
} && test -s conftest.$ac_objext; then
{ $as_echo "$as_me:$LINENO: result: correct" >&5
$as_echo "correct" >&6; }
else
$as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
{ $as_echo "$as_me:$LINENO: result: broken" >&5
$as_echo "broken" >&6; };
cat >>confdefs.h <<\_ACEOF
#define HAVE_FAAD_LONG 1
_ACEOF
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
CFLAGS=$oldcflags
LIBS=$oldlibs
CPPFLAGS=$oldcppflags
fi
if test x$enable_aac = xyes; then
enable_mp4=yes
MP4FF_LIBS="-lmp4ff"
......@@ -11678,6 +11746,70 @@ fi
{ $as_echo "$as_me:$LINENO: checking for xmlto (DocBook processing)" >&5
$as_echo_n "checking for xmlto (DocBook processing)... " >&6; }
# Extract the first word of "xmlto", so it can be a program name with args.
set dummy xmlto; ac_word=$2
{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if test "${ac_cv_path_XMLTO+set}" = set; then
$as_echo_n "(cached) " >&6
else
case $XMLTO in
[\\/]* | ?:[\\/]*)
ac_cv_path_XMLTO="$XMLTO" # Let the user override the test with a path.
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
ac_cv_path_XMLTO="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
;;
esac
fi
XMLTO=$ac_cv_path_XMLTO
if test -n "$XMLTO"; then
{ $as_echo "$as_me:$LINENO: result: $XMLTO" >&5
$as_echo "$XMLTO" >&6; }
else
{ $as_echo "$as_me:$LINENO: result: no" >&5
$as_echo "no" >&6; }
fi
if test x$XMLTO != x; then
{ $as_echo "$as_me:$LINENO: result: $XMLTO" >&5
$as_echo "$XMLTO" >&6; }
else
{ $as_echo "$as_me:$LINENO: result: no" >&5
$as_echo "no" >&6; }
fi
if test x$XMLTO != x; then
HAVE_XMLTO_TRUE=
HAVE_XMLTO_FALSE='#'
else
HAVE_XMLTO_TRUE='#'
HAVE_XMLTO_FALSE=
fi
if test "x$ENABLE_WERROR" = xyes; then
MPD_CFLAGS="$MPD_CFLAGS -Werror -pedantic-errors"
fi
......@@ -12615,6 +12747,13 @@ $as_echo "$as_me: error: conditional \"HAVE_ZEROCONF\" was never defined.
Usually this means the macro was only invoked conditionally." >&2;}
{ (exit 1); exit 1; }; }
fi
if test -z "${HAVE_XMLTO_TRUE}" && test -z "${HAVE_XMLTO_FALSE}"; then
{ { $as_echo "$as_me:$LINENO: error: conditional \"HAVE_XMLTO\" was never defined.
Usually this means the macro was only invoked conditionally." >&5
$as_echo "$as_me: error: conditional \"HAVE_XMLTO\" was never defined.
Usually this means the macro was only invoked conditionally." >&2;}
{ (exit 1); exit 1; }; }
fi
: ${CONFIG_STATUS=./config.status}
ac_write_fail=0
......@@ -12937,7 +13076,7 @@ exec 6>&1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by mpd $as_me 0.14~alpha3, which was
This file was extended by mpd $as_me 0.14~beta1, which was
generated by GNU Autoconf 2.63. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
......@@ -13000,7 +13139,7 @@ Report bugs to <bug-autoconf@gnu.org>."
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_version="\\
mpd config.status 0.14~alpha3
mpd config.status 0.14~beta1
configured by $0, generated by GNU Autoconf 2.63,
with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
......
AC_PREREQ(2.60)
AC_INIT(mpd, 0.14~alpha3, musicpd-dev-team@lists.sourceforge.net)
AC_INIT(mpd, 0.14~beta1, musicpd-dev-team@lists.sourceforge.net)
AC_CONFIG_SRCDIR([src/main.c])
AM_INIT_AUTOMAKE([foreign 1.9 dist-bzip2])
AM_CONFIG_HEADER(config.h)
......@@ -623,6 +623,37 @@ fi
AM_CONDITIONAL(HAVE_FAAD, test x$enable_aac = xyes)
if test x$enable_aac = xyes; then
oldcflags=$CFLAGS
oldlibs=$LIBS
oldcppflags=$CPPFLAGS
CFLAGS="$CFLAGS $MPD_CFLAGS $FAAD_CFLAGS -Werror"
LIBS="$LIBS $MPD_LIBS $FAAD_LIBS"
CPPFLAGS=$CFLAGS
AC_MSG_CHECKING(for broken libfaad headers)
AC_COMPILE_IFELSE([
#include <faad.h>
#include <stddef.h>
#include <stdint.h>
int main() {
unsigned char channels;
uint32_t sample_rate;
faacDecInit2(NULL, NULL, 0, &sample_rate, &channels);
return 0;
}
],
[AC_MSG_RESULT(correct)],
[AC_MSG_RESULT(broken);
AC_DEFINE(HAVE_FAAD_LONG, 1, [Define if faad.h uses the broken "unsigned long" pointers])])
CFLAGS=$oldcflags
LIBS=$oldlibs
CPPFLAGS=$oldcppflags
fi
if test x$enable_aac = xyes; then
enable_mp4=yes
MP4FF_LIBS="-lmp4ff"
......@@ -822,6 +853,22 @@ AM_CONDITIONAL(HAVE_ZEROCONF, test x$with_zeroconf != xno)
dnl
dnl Documentation
dnl
AC_MSG_CHECKING([for xmlto (DocBook processing)])
AC_PATH_PROG(XMLTO, xmlto)
if test x$XMLTO != x; then
AC_SUBST(XMLTO)
AC_MSG_RESULT($XMLTO)
else
AC_MSG_RESULT(no)
fi
AM_CONDITIONAL(HAVE_XMLTO, test x$XMLTO != x)
dnl
dnl build options
dnl
......
DOCBOOK_FILES = protocol.xml
DOCBOOK_HTML = $(patsubst %.xml,%.html,$(DOCBOOK_FILES))
man_MANS = mpd.1 mpd.conf.5
doc_DATA = COMMANDS mpdconf.example
EXTRA_DIST = $(man_MANS) $(doc_DATA)
doc_DATA = mpdconf.example
EXTRA_DIST = $(man_MANS) $(DOCBOOK_FILES) mpdconf.example
MOSTLYCLEANFILES = $(DOCBOOK_HTML)
if HAVE_XMLTO
doc_DATA += $(DOCBOOK_HTML)
$(DOCBOOK_HTML): %.html: %.xml
$(XMLTO) html-nochunks $<
endif
......@@ -36,6 +36,7 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
@HAVE_XMLTO_TRUE@am__append_1 = $(DOCBOOK_HTML)
subdir = doc
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
......@@ -158,6 +159,8 @@ HAVE_SHOUT_OGG_TRUE = @HAVE_SHOUT_OGG_TRUE@
HAVE_SHOUT_TRUE = @HAVE_SHOUT_TRUE@
HAVE_WAVPACK_FALSE = @HAVE_WAVPACK_FALSE@
HAVE_WAVPACK_TRUE = @HAVE_WAVPACK_TRUE@
HAVE_XMLTO_FALSE = @HAVE_XMLTO_FALSE@
HAVE_XMLTO_TRUE = @HAVE_XMLTO_TRUE@
HAVE_ZEROCONF_FALSE = @HAVE_ZEROCONF_FALSE@
HAVE_ZEROCONF_TRUE = @HAVE_ZEROCONF_TRUE@
ID3TAG_CFLAGS = @ID3TAG_CFLAGS@
......@@ -215,6 +218,7 @@ VORBISENC_CFLAGS = @VORBISENC_CFLAGS@
VORBISENC_LIBS = @VORBISENC_LIBS@
WAVPACK_CFLAGS = @WAVPACK_CFLAGS@
WAVPACK_LIBS = @WAVPACK_LIBS@
XMLTO = @XMLTO@
ac_ct_CC = @ac_ct_CC@
acx_pthread_config = @acx_pthread_config@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
......@@ -259,9 +263,12 @@ sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
DOCBOOK_FILES = protocol.xml
DOCBOOK_HTML = $(patsubst %.xml,%.html,$(DOCBOOK_FILES))
man_MANS = mpd.1 mpd.conf.5
doc_DATA = COMMANDS mpdconf.example
EXTRA_DIST = $(man_MANS) $(doc_DATA)
doc_DATA = mpdconf.example $(am__append_1)
EXTRA_DIST = $(man_MANS) $(DOCBOOK_FILES) mpdconf.example
MOSTLYCLEANFILES = $(DOCBOOK_HTML)
all: all-am
.SUFFIXES:
......@@ -458,6 +465,7 @@ install-strip:
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
-test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
clean-generic:
......@@ -526,6 +534,9 @@ uninstall-man: uninstall-man1 uninstall-man5
uninstall-docDATA uninstall-info-am uninstall-man \
uninstall-man1 uninstall-man5
@HAVE_XMLTO_TRUE@$(DOCBOOK_HTML): %.html: %.xml
@HAVE_XMLTO_TRUE@ $(XMLTO) html-nochunks $<
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*-
#
# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
# Written by Gary V. Vaughan, 2004
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
# serial 6 ltsugar.m4
# This is to help aclocal find these macros, as it can't see m4_define.
AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
# lt_join(SEP, ARG1, [ARG2...])
# -----------------------------
# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their
# associated separator.
# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier
# versions in m4sugar had bugs.
m4_define([lt_join],
[m4_if([$#], [1], [],
[$#], [2], [[$2]],
[m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])
m4_define([_lt_join],
[m4_if([$#$2], [2], [],
[m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])
# lt_car(LIST)
# lt_cdr(LIST)
# ------------
# Manipulate m4 lists.
# These macros are necessary as long as will still need to support
# Autoconf-2.59 which quotes differently.
m4_define([lt_car], [[$1]])
m4_define([lt_cdr],
[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
[$#], 1, [],
[m4_dquote(m4_shift($@))])])
m4_define([lt_unquote], $1)
# lt_append(MACRO-NAME, STRING, [SEPARATOR])
# ------------------------------------------
# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'.
# Note that neither SEPARATOR nor STRING are expanded; they are appended
# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
# No SEPARATOR is output if MACRO-NAME was previously undefined (different
# than defined and empty).
#
# This macro is needed until we can rely on Autoconf 2.62, since earlier
# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.
m4_define([lt_append],
[m4_define([$1],
m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
# ----------------------------------------------------------
# Produce a SEP delimited list of all paired combinations of elements of
# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list
# has the form PREFIXmINFIXSUFFIXn.
# Needed until we can rely on m4_combine added in Autoconf 2.62.
m4_define([lt_combine],
[m4_if(m4_eval([$# > 3]), [1],
[m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl
[[m4_foreach([_Lt_prefix], [$2],
[m4_foreach([_Lt_suffix],
]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,
[_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])
# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])
# -----------------------------------------------------------------------
# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited
# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
m4_define([lt_if_append_uniq],
[m4_ifdef([$1],
[m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
[lt_append([$1], [$2], [$3])$4],
[$5])],
[lt_append([$1], [$2], [$3])$4])])
# lt_dict_add(DICT, KEY, VALUE)
# -----------------------------
m4_define([lt_dict_add],
[m4_define([$1($2)], [$3])])
# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)
# --------------------------------------------
m4_define([lt_dict_add_subkey],
[m4_define([$1($2:$3)], [$4])])
# lt_dict_fetch(DICT, KEY, [SUBKEY])
# ----------------------------------
m4_define([lt_dict_fetch],
[m4_ifval([$3],
m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),
m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])
# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])
# -----------------------------------------------------------------
m4_define([lt_if_dict_fetch],
[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],
[$5],
[$6])])
# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])
# --------------------------------------------------------------
m4_define([lt_dict_filter],
[m4_if([$5], [], [],
[lt_join(m4_quote(m4_default([$4], [[, ]])),
lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),
[lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl
])
# ltversion.m4 -- version numbers -*- Autoconf -*-
#
# Copyright (C) 2004 Free Software Foundation, Inc.
# Written by Scott James Remnant, 2004
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
# Generated from ltversion.in.
# serial 3012 ltversion.m4
# This file is part of GNU Libtool
m4_define([LT_PACKAGE_VERSION], [2.2.6])
m4_define([LT_PACKAGE_REVISION], [1.3012])
AC_DEFUN([LTVERSION_VERSION],
[macro_version='2.2.6'
macro_revision='1.3012'
_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
_LT_DECL(, macro_revision, 0)
])
# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*-
#
# Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc.
# Written by Scott James Remnant, 2004.
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
# serial 4 lt~obsolete.m4
# These exist entirely to fool aclocal when bootstrapping libtool.
#
# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN)
# which have later been changed to m4_define as they aren't part of the
# exported API, or moved to Autoconf or Automake where they belong.
#
# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN
# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us
# using a macro with the same name in our local m4/libtool.m4 it'll
# pull the old libtool.m4 in (it doesn't see our shiny new m4_define
# and doesn't know about Autoconf macros at all.)
#
# So we provide this file, which has a silly filename so it's always
# included after everything else. This provides aclocal with the
# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
# because those macros already exist, or will be overwritten later.
# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6.
#
# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
# Yes, that means every name once taken will need to remain here until
# we give up compatibility with versions before 1.7, at which point
# we need to keep only those names which we still refer to.
# This is to help aclocal find these macros, as it can't see m4_define.
AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])
m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])
m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])])
m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])
m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])])
m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])
m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])])
m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])])
m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])
m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])])
m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])])
m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])])
m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])
m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])
m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])
m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])
m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])])
m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])])
m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])
m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])
m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])])
m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])])
m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])
m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])
m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])
m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])
m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])
m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])
m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])
m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])])
m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])])
m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])])
m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])])
m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])])
m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])])
m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])])
m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])])
m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])
m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])])
m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])])
m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])])
m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])])
m4_ifndef([AC_LIBTOOL_RC], [AC_DEFUN([AC_LIBTOOL_RC])])
m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])
m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])
m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])])
m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])])
......@@ -315,6 +315,8 @@ HAVE_SHOUT_OGG_TRUE = @HAVE_SHOUT_OGG_TRUE@
HAVE_SHOUT_TRUE = @HAVE_SHOUT_TRUE@
HAVE_WAVPACK_FALSE = @HAVE_WAVPACK_FALSE@
HAVE_WAVPACK_TRUE = @HAVE_WAVPACK_TRUE@
HAVE_XMLTO_FALSE = @HAVE_XMLTO_FALSE@
HAVE_XMLTO_TRUE = @HAVE_XMLTO_TRUE@
HAVE_ZEROCONF_FALSE = @HAVE_ZEROCONF_FALSE@
HAVE_ZEROCONF_TRUE = @HAVE_ZEROCONF_TRUE@
ID3TAG_CFLAGS = @ID3TAG_CFLAGS@
......@@ -372,6 +374,7 @@ VORBISENC_CFLAGS = @VORBISENC_CFLAGS@
VORBISENC_LIBS = @VORBISENC_LIBS@
WAVPACK_CFLAGS = @WAVPACK_CFLAGS@
WAVPACK_LIBS = @WAVPACK_LIBS@
XMLTO = @XMLTO@
ac_ct_CC = @ac_ct_CC@
acx_pthread_config = @acx_pthread_config@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
......
......@@ -40,6 +40,17 @@ static inline bool audio_format_defined(const struct audio_format *af)
return af->sample_rate != 0;
}
/**
* Returns false if the format is not valid for playback with MPD.
* This function performs some basic validity checks.
*/
static inline bool audio_format_valid(const struct audio_format *af)
{
return af->sample_rate > 0 &&
(af->bits == 8 || af->bits == 16 || af->bits == 24) &&
af->channels >= 1;
}
static inline bool audio_format_equals(const struct audio_format *a,
const struct audio_format *b)
{
......
......@@ -91,6 +91,9 @@ struct client {
/** idle flags pending on this client, to be sent as soon as
the client enters "idle" */
unsigned idle_flags;
/** idle flags that the client wants to receive */
unsigned idle_subscriptions;
};
static LIST_HEAD(clients);
......@@ -766,16 +769,6 @@ mpd_fprintf void client_printf(struct client *client, const char *fmt, ...)
va_end(args);
}
static const char *const idle_names[] = {
"database",
"stored_playlist",
"playlist",
"player",
"mixer",
"output",
"options",
};
/**
* Send "idle" response to this client.
*/
......@@ -783,6 +776,7 @@ static void
client_idle_notify(struct client *client)
{
unsigned flags, i;
const char *const* idle_names;
assert(client->idle_waiting);
assert(client->idle_flags != 0);
......@@ -791,10 +785,9 @@ client_idle_notify(struct client *client)
client->idle_flags = 0;
client->idle_waiting = false;
for (i = 0; i < sizeof(idle_names) / sizeof(idle_names[0]); ++i) {
assert(idle_names[i] != NULL);
if (flags & (1 << i))
idle_names = idle_get_names();
for (i = 0; idle_names[i]; ++i) {
if (flags & (1 << i) & client->idle_subscriptions)
client_printf(client, "changed: %s\n",
idle_names[i]);
}
......@@ -814,20 +807,22 @@ void client_manager_idle_add(unsigned flags)
continue;
client->idle_flags |= flags;
if (client->idle_waiting) {
if (client->idle_waiting
&& (client->idle_flags & client->idle_subscriptions)) {
client_idle_notify(client);
client_write_output(client);
}
}
}
bool client_idle_wait(struct client *client)
bool client_idle_wait(struct client *client, unsigned flags)
{
assert(!client->idle_waiting);
client->idle_waiting = true;
client->idle_subscriptions = flags;
if (client->idle_flags != 0) {
if (client->idle_flags & client->idle_subscriptions) {
client_idle_notify(client);
return true;
} else
......
......@@ -78,6 +78,6 @@ void client_manager_idle_add(unsigned flags);
* sent immediately and "true" is returned". If no, it puts the
* client into waiting mode and returns false.
*/
bool client_idle_wait(struct client *client);
bool client_idle_wait(struct client *client, unsigned flags);
#endif
......@@ -39,6 +39,7 @@
#include "tag_print.h"
#include "path.h"
#include "os_compat.h"
#include "idle.h"
#define COMMAND_STATUS_VOLUME "volume"
#define COMMAND_STATUS_STATE "state"
......@@ -204,7 +205,7 @@ print_playlist_result(struct client *client,
return COMMAND_RETURN_OK;
case PLAYLIST_RESULT_ERRNO:
command_error(client, ACK_ERROR_SYSTEM, strerror(errno));
command_error(client, ACK_ERROR_SYSTEM, "%s", strerror(errno));
return COMMAND_RETURN_ERROR;
case PLAYLIST_RESULT_DENIED:
......@@ -1253,8 +1254,28 @@ static enum command_return
handle_idle(struct client *client,
mpd_unused int argc, mpd_unused char *argv[])
{
unsigned flags = 0, j;
int i;
const char *const* idle_names;
idle_names = idle_get_names();
for (i = 1; i < argc; ++i) {
if (!argv[i])
continue;
for (j = 0; idle_names[j]; ++j) {
if (!strcasecmp(argv[i], idle_names[j])) {
flags |= (1 << j);
}
}
}
/* No argument means that the client wants to receive everything */
if (flags == 0)
flags = ~0;
/* enable "idle" mode on this client */
client_idle_wait(client);
client_idle_wait(client, flags);
/* return value is "1" so the caller won't print "OK" */
return 1;
......@@ -1280,7 +1301,7 @@ static const struct command commands[] = {
{ "disableoutput", PERMISSION_ADMIN, 1, 1, handle_disableoutput },
{ "enableoutput", PERMISSION_ADMIN, 1, 1, handle_enableoutput },
{ "find", PERMISSION_READ, 2, -1, handle_find },
{ "idle", PERMISSION_READ, 0, 0, handle_idle },
{ "idle", PERMISSION_READ, 0, -1, handle_idle },
{ "kill", PERMISSION_ADMIN, -1, -1, handle_kill },
{ "list", PERMISSION_READ, 1, -1, handle_list },
{ "listall", PERMISSION_READ, 0, 1, handle_listall },
......
......@@ -20,7 +20,6 @@
*/
#include "_flac_common.h"
#include "../log.h"
#include <FLAC/format.h>
#include <FLAC/metadata.h>
......@@ -177,16 +176,16 @@ void flac_error_common_cb(const char *plugin,
switch (status) {
case FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC:
ERROR("%s lost sync\n", plugin);
g_warning("%s lost sync\n", plugin);
break;
case FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER:
ERROR("bad %s header\n", plugin);
g_warning("bad %s header\n", plugin);
break;
case FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH:
ERROR("%s crc mismatch\n", plugin);
g_warning("%s crc mismatch\n", plugin);
break;
default:
ERROR("unknown %s error\n", plugin);
g_warning("unknown %s error\n", plugin);
}
}
......
......@@ -24,6 +24,11 @@
#include "../decoder_api.h"
#include <glib.h>
#undef G_LOG_DOMAIN
#define G_LOG_DOMAIN "flac"
#include <FLAC/export.h>
#if !defined(FLAC_API_VERSION_CURRENT) || FLAC_API_VERSION_CURRENT <= 7
# include <FLAC/seekable_stream_decoder.h>
......
......@@ -20,11 +20,13 @@
#define AAC_MAX_CHANNELS 6
#include "../utils.h"
#include "../log.h"
#include <assert.h>
#include <unistd.h>
#include <faad.h>
#include <glib.h>
#undef G_LOG_DOMAIN
#define G_LOG_DOMAIN "aac"
/* all code here is either based on or copied from FAAD2's frontend code */
typedef struct {
......@@ -186,7 +188,7 @@ static void aac_parse_header(AacBuffer * b, float *length)
if (length)
*length = -1;
fileread = b->inStream->size;
fileread = b->inStream->size >= 0 ? b->inStream->size : 0;
fillAacBuffer(b);
......@@ -252,6 +254,14 @@ static float getAacFloatTotalTime(const char *file)
faacDecHandle decoder;
faacDecConfigurationPtr config;
uint32_t sample_rate;
#ifdef HAVE_FAAD_LONG
/* neaacdec.h declares all arguments as "unsigned long", but
internally expects uint32_t pointers. To avoid gcc
warnings, use this workaround. */
unsigned long *sample_rate_r = (unsigned long *)(void *)&sample_rate;
#else
uint32_t *sample_rate_r = &sample_rate;
#endif
unsigned char channels;
struct input_stream inStream;
long bread;
......@@ -272,9 +282,9 @@ static float getAacFloatTotalTime(const char *file)
fillAacBuffer(&b);
#ifdef HAVE_FAAD_BUFLEN_FUNCS
bread = faacDecInit(decoder, b.buffer, b.bytesIntoBuffer,
&sample_rate, &channels);
sample_rate_r, &channels);
#else
bread = faacDecInit(decoder, b.buffer, &sample_rate, &channels);
bread = faacDecInit(decoder, b.buffer, sample_rate_r, &channels);
#endif
if (bread >= 0 && sample_rate > 0 && channels > 0)
length = 0;
......@@ -282,8 +292,6 @@ static float getAacFloatTotalTime(const char *file)
faacDecClose(decoder);
}
if (b.buffer)
free(b.buffer);
input_stream_close(&inStream);
return length;
......@@ -310,6 +318,14 @@ aac_stream_decode(struct decoder *mpd_decoder, struct input_stream *inStream)
faacDecConfigurationPtr config;
long bread;
uint32_t sample_rate;
#ifdef HAVE_FAAD_LONG
/* neaacdec.h declares all arguments as "unsigned long", but
internally expects uint32_t pointers. To avoid gcc
warnings, use this workaround. */
unsigned long *sample_rate_r = (unsigned long *)(void *)&sample_rate;
#else
uint32_t *sample_rate_r = &sample_rate;
#endif
unsigned char channels;
unsigned int sampleCount;
char *sampleBuffer;
......@@ -340,20 +356,17 @@ aac_stream_decode(struct decoder *mpd_decoder, struct input_stream *inStream)
fillAacBuffer(&b);
adts_find_frame(&b);
fillAacBuffer(&b);
my_usleep(10000);
}
#ifdef HAVE_FAAD_BUFLEN_FUNCS
bread = faacDecInit(decoder, b.buffer, b.bytesIntoBuffer,
&sample_rate, &channels);
sample_rate_r, &channels);
#else
bread = faacDecInit(decoder, b.buffer, &sample_rate, &channels);
bread = faacDecInit(decoder, b.buffer, sample_rate_r, &channels);
#endif
if (bread < 0) {
ERROR("Error not a AAC stream.\n");
g_warning("Error not a AAC stream.\n");
faacDecClose(decoder);
if (b.buffer)
free(b.buffer);
return;
}
......@@ -377,9 +390,8 @@ aac_stream_decode(struct decoder *mpd_decoder, struct input_stream *inStream)
#endif
if (frameInfo.error > 0) {
ERROR("error decoding AAC stream\n");
ERROR("faad2 error: %s\n",
faacDecGetErrorMessage(frameInfo.error));
g_warning("error decoding AAC stream: %s\n",
faacDecGetErrorMessage(frameInfo.error));
break;
}
#ifdef HAVE_FAACDECFRAMEINFO_SAMPLERATE
......@@ -393,6 +405,11 @@ aac_stream_decode(struct decoder *mpd_decoder, struct input_stream *inStream)
.sample_rate = sample_rate,
};
if (!audio_format_valid(&audio_format)) {
g_warning("aac: invalid audio format\n");
break;
}
decoder_initialized(mpd_decoder, &audio_format,
false, totalTime);
initialized = true;
......@@ -433,8 +450,8 @@ static struct tag *aacTagDup(const char *file)
ret = tag_new();
ret->time = file_time;
} else {
DEBUG("aacTagDup: Failed to get total song time from: %s\n",
file);
g_debug("aacTagDup: Failed to get total song time from: %s\n",
file);
}
return ret;
......
......@@ -19,10 +19,13 @@
*/
#include "../decoder_api.h"
#include "../log.h"
#include <sys/stat.h>
#include <audiofile.h>
#include <glib.h>
#undef G_LOG_DOMAIN
#define G_LOG_DOMAIN "audiofile"
/* pick 1020 since its devisible for 8,16,24, and 32-bit audio */
#define CHUNK_SIZE 1020
......@@ -55,13 +58,13 @@ audiofile_decode(struct decoder *decoder, const char *path)
char chunk[CHUNK_SIZE];
if (stat(path, &st) < 0) {
ERROR("failed to stat: %s\n", path);
g_warning("failed to stat: %s\n", path);
return;
}
af_fp = afOpenFile(path, "r", NULL);
if (af_fp == AF_NULL_FILEHANDLE) {
ERROR("failed to open: %s\n", path);
g_warning("failed to open: %s\n", path);
return;
}
......@@ -74,19 +77,20 @@ audiofile_decode(struct decoder *decoder, const char *path)
audio_format.channels =
(uint8_t)afGetVirtualChannels(af_fp, AF_DEFAULT_TRACK);
if (!audio_format_valid(&audio_format)) {
g_warning("Invalid audio format: %u:%u:%u\n",
audio_format.sample_rate, audio_format.bits,
audio_format.channels);
afCloseFile(af_fp);
return;
}
frame_count = afGetFrameCount(af_fp, AF_DEFAULT_TRACK);
total_time = ((float)frame_count / (float)audio_format.sample_rate);
bitRate = (uint16_t)(st.st_size * 8.0 / total_time / 1000.0 + 0.5);
if (audio_format.bits != 8 && audio_format.bits != 16) {
ERROR("Only 8 and 16-bit files are supported. %s is %i-bit\n",
path, audio_format.bits);
afCloseFile(af_fp);
return;
}
fs = (int)afGetVirtualFrameSize(af_fp, AF_DEFAULT_TRACK, 1);
decoder_initialized(decoder, &audio_format, true, total_time);
......@@ -120,13 +124,11 @@ static struct tag *audiofileTagDup(const char *file)
int total_time = getAudiofileTotalTime(file);
if (total_time >= 0) {
if (!ret)
ret = tag_new();
ret = tag_new();
ret->time = total_time;
} else {
DEBUG
("audiofileTagDup: Failed to get total song time from: %s\n",
file);
g_debug("Failed to get total song time from: %s\n",
file);
}
return ret;
......
......@@ -17,7 +17,6 @@
*/
#include "../decoder_api.h"
#include "../log.h"
#include <assert.h>
#include <stdio.h>
......@@ -27,6 +26,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <glib.h>
#ifdef OLD_FFMPEG_INCLUDES
#include <avcodec.h>
......@@ -38,6 +38,9 @@
#include <libavformat/avio.h>
#endif
#undef G_LOG_DOMAIN
#define G_LOG_DOMAIN "ffmpeg"
struct ffmpeg_context {
int audio_stream;
AVFormatContext *format_context;
......@@ -89,9 +92,15 @@ static int mpd_ffmpeg_read(URLContext *h, unsigned char *buf, int size)
static int64_t mpd_ffmpeg_seek(URLContext *h, int64_t pos, int whence)
{
struct ffmpeg_stream *stream = (struct ffmpeg_stream *) h->priv_data;
if (whence != AVSEEK_SIZE) { //only ftell
(void) input_stream_seek(stream->input, pos, whence);
}
bool ret;
if (whence == AVSEEK_SIZE)
return stream->input->size;
ret = input_stream_seek(stream->input, pos, whence);
if (!ret)
return -1;
return stream->input->offset;
}
......@@ -150,18 +159,18 @@ ffmpeg_helper(struct input_stream *input,
//ffmpeg works with ours "fileops" helper
if (av_open_input_file(&format_context, stream.url, NULL, 0, NULL) != 0) {
ERROR("Open failed!\n");
g_warning("Open failed\n");
return false;
}
if (av_find_stream_info(format_context)<0) {
ERROR("Couldn't find stream info!\n");
g_warning("Couldn't find stream info\n");
return false;
}
audio_stream = ffmpeg_find_audio_stream(format_context);
if (audio_stream == -1) {
ERROR("No audio stream inside!\n");
g_warning("No audio stream inside\n");
return false;
}
......@@ -169,12 +178,12 @@ ffmpeg_helper(struct input_stream *input,
codec = avcodec_find_decoder(codec_context->codec_id);
if (!codec) {
ERROR("Unsupported audio codec!\n");
g_warning("Unsupported audio codec\n");
return false;
}
if (avcodec_open(codec_context, codec)<0) {
ERROR("Could not open codec!\n");
g_warning("Could not open codec\n");
return false;
}
......@@ -213,7 +222,7 @@ ffmpeg_send_packet(struct decoder *decoder, struct input_stream *is,
packet->data, packet->size);
if (len < 0) {
WARNING("skipping frame!\n");
g_message("skipping frame\n");
return decoder_get_command(decoder);
}
......@@ -246,6 +255,13 @@ ffmpeg_decode_internal(struct ffmpeg_context *ctx)
audio_format.sample_rate = (unsigned int)codec_context->sample_rate;
audio_format.channels = codec_context->channels;
if (!audio_format_valid(&audio_format)) {
g_warning("Invalid audio format: %u:%u:%u\n",
audio_format.sample_rate, audio_format.bits,
audio_format.channels);
return false;
}
//there is some problem with this on some demux (mp3 at least)
if (format_context->duration != (int)AV_NOPTS_VALUE) {
total_time = format_context->duration / AV_TIME_BASE;
......@@ -295,11 +311,22 @@ ffmpeg_decode(struct decoder *decoder, struct input_stream *input)
static bool ffmpeg_tag_internal(struct ffmpeg_context *ctx)
{
struct tag *tag = (struct tag *) ctx->tag;
if (ctx->format_context->duration != (int)AV_NOPTS_VALUE) {
tag->time = ctx->format_context->duration / AV_TIME_BASE;
} else {
tag->time = 0;
const AVFormatContext *f = ctx->format_context;
tag->time = 0;
if (f->duration != (int)AV_NOPTS_VALUE)
tag->time = f->duration / AV_TIME_BASE;
if (f->author[0])
tag_add_item(tag, TAG_ITEM_ARTIST, f->author);
if (f->title[0])
tag_add_item(tag, TAG_ITEM_TITLE, f->title);
if (f->album[0])
tag_add_item(tag, TAG_ITEM_ALBUM, f->album);
if (f->track > 0) {
char buffer[16];
snprintf(buffer, sizeof(buffer), "%d", f->track);
tag_add_item(tag, TAG_ITEM_TRACK, buffer);
}
return true;
......@@ -313,7 +340,7 @@ static struct tag *ffmpeg_tag(const char *file)
bool ret;
if (!input_stream_open(&input, file)) {
ERROR("failed to open %s\n", file);
g_warning("failed to open %s\n", file);
return NULL;
}
......
......@@ -17,8 +17,6 @@
*/
#include "_flac_common.h"
#include "../utils.h"
#include "../log.h"
#include <assert.h>
......@@ -75,6 +73,9 @@ static flac_length_status flacLength(mpd_unused const flac_decoder * flacDec,
{
FlacData *data = (FlacData *) fdata;
if (data->inStream->size < 0)
return flac_length_status_unsupported;
*length = (size_t) (data->inStream->size);
return flac_length_status_ok;
......@@ -125,7 +126,8 @@ static void flacPrintErroredState(FLAC__SeekableStreamDecoderState state)
case FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED:
str = "decoder uninitialized";
}
ERROR("flac %s\n", str);
g_warning("%s\n", str);
}
static int flac_init(FLAC__SeekableStreamDecoder *dec,
......@@ -183,7 +185,8 @@ static void flacPrintErroredState(FLAC__StreamDecoderState state)
case FLAC__STREAM_DECODER_UNINITIALIZED:
str = "decoder uninitialized";
}
ERROR("flac %s\n", str);
g_warning("%s\n", str);
}
#endif /* FLAC_API_VERSION_CURRENT >= 7 */
......@@ -248,9 +251,8 @@ flacMetadataDup(const char *file, bool *vorbisCommentFound)
default:
err = FLAC__Metadata_SimpleIteratorStatusString[s];
}
DEBUG("flacMetadataDup: Reading '%s' "
"metadata gave the following error: %s\n",
file, err);
g_debug("Reading '%s' metadata gave the following error: %s\n",
file, err);
FLAC__metadata_simple_iterator_delete(it);
return ret;
}
......@@ -285,8 +287,7 @@ static struct tag *flacTagDup(const char *file)
ret = flacMetadataDup(file, &foundVorbisComment);
if (!ret) {
DEBUG("flacTagDup: Failed to grab information from: %s\n",
file);
g_debug("Failed to grab information from: %s\n", file);
return NULL;
}
if (!foundVorbisComment) {
......@@ -316,7 +317,7 @@ flac_decode_internal(struct decoder * decoder, struct input_stream *inStream,
#if defined(FLAC_API_VERSION_CURRENT) && FLAC_API_VERSION_CURRENT > 7
if(!FLAC__stream_decoder_set_metadata_respond(flacDec, FLAC__METADATA_TYPE_VORBIS_COMMENT))
{
DEBUG(__FILE__": Failed to set metadata respond\n");
g_debug("Failed to set metadata respond\n");
}
#endif
......@@ -342,6 +343,14 @@ flac_decode_internal(struct decoder * decoder, struct input_stream *inStream,
goto fail;
}
if (!audio_format_valid(&data.audio_format)) {
g_warning("Invalid audio format: %u:%u:%u\n",
data.audio_format.sample_rate,
data.audio_format.bits,
data.audio_format.channels);
goto fail;
}
decoder_initialized(decoder, &data.audio_format,
inStream->seekable, data.total_time);
......@@ -373,11 +382,8 @@ fail:
if (flacDec)
flac_delete(flacDec);
if (err) {
ERROR("flac %s\n", err);
return;
}
return;
if (err)
g_warning("%s\n", err);
}
static void
......
......@@ -112,6 +112,14 @@ mp4_decode(struct decoder *mpd_decoder, struct input_stream *input_stream)
unsigned char *mp4_buffer;
unsigned int mp4_buffer_size;
uint32_t sample_rate;
#ifdef HAVE_FAAD_LONG
/* neaacdec.h declares all arguments as "unsigned long", but
internally expects uint32_t pointers. To avoid gcc
warnings, use this workaround. */
unsigned long *sample_rate_r = (unsigned long*)&sample_rate;
#else
uint32_t *sample_rate_r = &sample_rate;
#endif
unsigned char channels;
long sample_id;
long num_samples;
......@@ -160,7 +168,7 @@ mp4_decode(struct decoder *mpd_decoder, struct input_stream *input_stream)
mp4ff_get_decoder_config(mp4fh, track, &mp4_buffer, &mp4_buffer_size);
if (faacDecInit2(decoder, mp4_buffer, mp4_buffer_size,
&sample_rate, &channels) < 0) {
sample_rate_r, &channels) < 0) {
g_warning("Not an AAC stream.\n");
faacDecClose(decoder);
mp4ff_close(mp4fh);
......@@ -267,6 +275,15 @@ mp4_decode(struct decoder *mpd_decoder, struct input_stream *input_stream)
scale = frame_info.samplerate;
#endif
audio_format.sample_rate = scale;
if (!audio_format_valid(&audio_format)) {
g_warning("Invalid audio format: %u:%u:%u\n",
audio_format.sample_rate,
audio_format.bits,
audio_format.channels);
break;
}
decoder_initialized(mpd_decoder, &audio_format,
input_stream->seekable,
total_time);
......
......@@ -155,6 +155,14 @@ mpc_decode(struct decoder *mpd_decoder, struct input_stream *inStream)
audio_format.channels = info.channels;
audio_format.sample_rate = info.sample_freq;
if (!audio_format_valid(&audio_format)) {
g_warning("Invalid audio format: %u:%u:%u\n",
audio_format.sample_rate,
audio_format.bits,
audio_format.channels);
return;
}
replayGainInfo = replay_gain_info_new();
replayGainInfo->tuples[REPLAY_GAIN_ALBUM].gain = info.gain_album * 0.01;
replayGainInfo->tuples[REPLAY_GAIN_ALBUM].peak = info.peak_album / 32767.0;
......
......@@ -22,9 +22,6 @@
#include "_flac_common.h"
#include "_ogg_common.h"
#include "../utils.h"
#include "../log.h"
#include <OggFLAC/seekable_stream_decoder.h>
static void oggflac_cleanup(FlacData * data,
......@@ -92,6 +89,9 @@ static OggFLAC__SeekableStreamDecoderLengthStatus of_length_cb(mpd_unused const
{
FlacData *data = (FlacData *) fdata;
if (data->inStream->size < 0)
return OggFLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR;
*length = (size_t) (data->inStream->size);
return OggFLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK;
......@@ -117,25 +117,25 @@ static void oggflacPrintErroredState(OggFLAC__SeekableStreamDecoderState state)
{
switch (state) {
case OggFLAC__SEEKABLE_STREAM_DECODER_MEMORY_ALLOCATION_ERROR:
ERROR("oggflac allocation error\n");
g_warning("oggflac allocation error\n");
break;
case OggFLAC__SEEKABLE_STREAM_DECODER_READ_ERROR:
ERROR("oggflac read error\n");
g_warning("oggflac read error\n");
break;
case OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR:
ERROR("oggflac seek error\n");
g_warning("oggflac seek error\n");
break;
case OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR:
ERROR("oggflac seekable stream error\n");
g_warning("oggflac seekable stream error\n");
break;
case OggFLAC__SEEKABLE_STREAM_DECODER_ALREADY_INITIALIZED:
ERROR("oggflac decoder already initialized\n");
g_warning("oggflac decoder already initialized\n");
break;
case OggFLAC__SEEKABLE_STREAM_DECODER_INVALID_CALLBACK:
ERROR("invalid oggflac callback\n");
g_warning("invalid oggflac callback\n");
break;
case OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED:
ERROR("oggflac decoder uninitialized\n");
g_warning("oggflac decoder uninitialized\n");
break;
case OggFLAC__SEEKABLE_STREAM_DECODER_OK:
case OggFLAC__SEEKABLE_STREAM_DECODER_SEEKING:
......@@ -230,17 +230,17 @@ static OggFLAC__SeekableStreamDecoder
(void *)data);
if (!s) {
ERROR("oggflac problem before init()\n");
g_warning("oggflac problem before init()\n");
goto fail;
}
if (OggFLAC__seekable_stream_decoder_init(decoder) !=
OggFLAC__SEEKABLE_STREAM_DECODER_OK) {
ERROR("oggflac problem doing init()\n");
g_warning("oggflac problem doing init()\n");
goto fail;
}
if (!OggFLAC__seekable_stream_decoder_process_until_end_of_metadata
(decoder)) {
ERROR("oggflac problem reading metadata\n");
g_warning("oggflac problem reading metadata\n");
goto fail;
}
......@@ -294,6 +294,14 @@ oggflac_decode(struct decoder * mpd_decoder, struct input_stream *inStream)
goto fail;
}
if (!audio_format_valid(&data.audio_format)) {
g_warning("Invalid audio format: %u:%u:%u\n",
data.audio_format.sample_rate,
data.audio_format.bits,
data.audio_format.channels);
goto fail;
}
decoder_initialized(mpd_decoder, &data.audio_format,
inStream->seekable, data.total_time);
......
......@@ -214,7 +214,6 @@ oggvorbis_decode(struct decoder *decoder, struct input_stream *inStream)
long test;
struct replay_gain_info *replayGainInfo = NULL;
char **comments;
const char *errorStr;
bool initialized = false;
enum decoder_command cmd = DECODE_COMMAND_NONE;
......@@ -233,6 +232,8 @@ oggvorbis_decode(struct decoder *decoder, struct input_stream *inStream)
callbacks.close_func = ogg_close_cb;
callbacks.tell_func = ogg_tell_cb;
if ((ret = ov_open_callbacks(&data, &vf, NULL, 0, callbacks)) < 0) {
const char *errorStr;
if (decoder_get_command(decoder) != DECODE_COMMAND_NONE)
return;
......@@ -274,6 +275,12 @@ oggvorbis_decode(struct decoder *decoder, struct input_stream *inStream)
ret = ov_read(&vf, chunk, sizeof(chunk),
OGG_DECODE_USE_BIGENDIAN, 2, 1, &current_section);
if (ret == OV_HOLE) /* bad packet */
ret = 0;
else if (ret <= 0)
/* break on EOF or other error */
break;
if (current_section != prev_section) {
/*printf("new song!\n"); */
vorbis_info *vi = ov_info(&vf, -1);
......@@ -281,6 +288,15 @@ oggvorbis_decode(struct decoder *decoder, struct input_stream *inStream)
audio_format.channels = vi->channels;
audio_format.sample_rate = vi->rate;
if (!audio_format_valid(&audio_format)) {
g_warning("Invalid audio format: %u:%u:%u\n",
audio_format.sample_rate,
audio_format.bits,
audio_format.channels);
break;
}
if (!initialized) {
float total_time = ov_time_total(&vf, -1);
if (total_time < 0)
......@@ -303,13 +319,6 @@ oggvorbis_decode(struct decoder *decoder, struct input_stream *inStream)
prev_section = current_section;
if (ret <= 0) {
if (ret == OV_HOLE) /* bad packet */
ret = 0;
else /* break on EOF or other error */
break;
}
if ((test = ov_bitrate_instant(&vf)) > 0)
bitRate = test / 1000;
......
......@@ -20,6 +20,7 @@
#include "../decoder_api.h"
#include "../path.h"
#include "../utils.h"
#include <wavpack/wavpack.h>
#include <glib.h>
......@@ -71,7 +72,7 @@ format_samples_int(int bytes_per_sample, void *buffer, uint32_t count)
* of the output samples never can be greater than the size
* of the input ones. Otherwise we would have an overflow.
*/
assert(sizeof(uchar) <= sizeof(uint32_t));
assert_static(sizeof(*dst) <= sizeof(*src));
/* pass through and align 8-bit samples */
while (count--) {
......@@ -81,7 +82,7 @@ format_samples_int(int bytes_per_sample, void *buffer, uint32_t count)
}
case 2: {
uint16_t *dst = buffer;
assert(sizeof(uint16_t) <= sizeof(uint32_t));
assert_static(sizeof(*dst) <= sizeof(*src));
/* pass through and align 16-bit samples */
while (count--) {
......@@ -94,7 +95,7 @@ format_samples_int(int bytes_per_sample, void *buffer, uint32_t count)
break;
case 4: {
uint32_t *dst = buffer;
assert(sizeof(uint32_t) <= sizeof(uint32_t));
assert_static(sizeof(*dst) <= sizeof(*src));
/* downsample to 24-bit */
while (count--) {
......@@ -114,7 +115,7 @@ format_samples_float(mpd_unused int bytes_per_sample, void *buffer,
{
int32_t *dst = buffer;
float *src = buffer;
assert(sizeof(int32_t) <= sizeof(float));
assert_static(sizeof(*dst) <= sizeof(*src));
while (count--) {
*dst++ = (int32_t)(*src++ + 0.5f);
......@@ -148,6 +149,14 @@ wavpack_decode(struct decoder *decoder, WavpackContext *wpc, bool can_seek,
audio_format.bits = 24;
}
if (!audio_format_valid(&audio_format)) {
g_warning("Invalid audio format: %u:%u:%u\n",
audio_format.sample_rate,
audio_format.bits,
audio_format.channels);
return;
}
if ((WavpackGetMode(wpc) & MODE_FLOAT) == MODE_FLOAT) {
format_samples = format_samples_float;
} else {
......@@ -157,12 +166,7 @@ wavpack_decode(struct decoder *decoder, WavpackContext *wpc, bool can_seek,
total_time = WavpackGetNumSamples(wpc);
total_time /= audio_format.sample_rate;
bytes_per_sample = WavpackGetBytesPerSample(wpc);
output_sample_size = bytes_per_sample;
if (output_sample_size == 3) {
output_sample_size = 4;
}
output_sample_size *= audio_format.channels;
output_sample_size = audio_format_frame_size(&audio_format);
/* wavpack gives us all kind of samples in a 32-bit space */
samples_requested = sizeof(chunk) / (4 * audio_format.channels);
......@@ -410,6 +414,9 @@ wavpack_input_push_back_byte(void *id, int c)
static uint32_t
wavpack_input_get_length(void *id)
{
if (wpin(id)->is->size < 0)
return 0;
return wpin(id)->is->size;
}
......
......@@ -40,6 +40,7 @@ void decoder_initialized(struct decoder * decoder,
assert(!decoder->seeking);
assert(audio_format != NULL);
assert(audio_format_defined(audio_format));
assert(audio_format_valid(audio_format));
pcm_convert_init(&decoder->conv_state);
......@@ -106,6 +107,9 @@ size_t decoder_read(struct decoder *decoder,
assert(is != NULL);
assert(buffer != NULL);
if (length == 0)
return 0;
while (true) {
/* XXX don't allow decoder==NULL */
if (decoder != NULL &&
......@@ -191,7 +195,8 @@ decoder_data(struct decoder *decoder,
assert(dc.state == DECODE_STATE_DECODE);
if (dc.command == DECODE_COMMAND_STOP ||
dc.command == DECODE_COMMAND_SEEK)
dc.command == DECODE_COMMAND_SEEK ||
length == 0)
return dc.command;
if (is != NULL && !decoder->stream_tag_sent) {
......@@ -229,13 +234,14 @@ decoder_data(struct decoder *decoder,
if (audio_format_equals(&dc.in_audio_format, &dc.out_audio_format)) {
data = _data;
} else {
length = pcm_convert_size(&dc.in_audio_format, length,
&dc.out_audio_format);
if (length > conv_buffer_size) {
size_t out_length =
pcm_convert_size(&dc.in_audio_format, length,
&dc.out_audio_format);
if (out_length > conv_buffer_size) {
if (conv_buffer != NULL)
free(conv_buffer);
conv_buffer = xmalloc(length);
conv_buffer_size = length;
conv_buffer = xmalloc(out_length);
conv_buffer_size = out_length;
}
data = conv_buffer;
......
......@@ -109,7 +109,7 @@ static void decoder_run(void)
will be available then */
while (!input_stream.ready) {
if (dc.command != DECODE_COMMAND_NONE) {
if (dc.command == DECODE_COMMAND_STOP) {
input_stream_close(&input_stream);
dc.state = DECODE_STATE_STOP;
return;
......
......@@ -30,6 +30,18 @@
static unsigned idle_flags;
static pthread_mutex_t idle_mutex = PTHREAD_MUTEX_INITIALIZER;
static const char *const idle_names[] = {
"database",
"stored_playlist",
"playlist",
"player",
"mixer",
"output",
"options",
"elapsed",
NULL
};
void
idle_add(unsigned flags)
{
......@@ -54,3 +66,9 @@ idle_get(void)
return flags;
}
const char*const*
idle_get_names(void)
{
return idle_names;
}
......@@ -61,4 +61,10 @@ idle_add(unsigned flags);
unsigned
idle_get(void);
/**
* Get idle names
*/
const char*const*
idle_get_names(void);
#endif
......@@ -155,12 +155,14 @@ input_curl_multi_info_read(struct input_stream *is)
while ((msg = curl_multi_info_read(c->multi,
&msgs_in_queue)) != NULL) {
if (msg->msg == CURLMSG_DONE &&
msg->data.result != CURLE_OK) {
g_warning("curl failed: %s\n", c->error);
is->error = -1;
if (msg->msg == CURLMSG_DONE) {
c->eof = true;
return false;
if (msg->data.result != CURLE_OK) {
g_warning("curl failed: %s\n", c->error);
is->error = -1;
return false;
}
}
}
......@@ -205,6 +207,31 @@ input_curl_select(struct input_curl *c)
return ret;
}
/**
* Mark a part of the buffer object as consumed.
*/
static void
consume_buffer(struct buffer *buffer, size_t length,
struct list_head *rewind_head)
{
assert(buffer != NULL);
assert(buffer->consumed < buffer->size);
buffer->consumed += length;
if (buffer->consumed < buffer->size)
return;
assert(buffer->consumed == buffer->size);
list_del(&buffer->siblings);
if (rewind_head != NULL)
/* append this buffer to the rewind buffer list */
list_add_tail(&buffer->siblings, rewind_head);
else
g_free(buffer);
}
static size_t
read_from_buffer(struct buffer *buffer, void *dest, size_t length,
struct list_head *rewind_head)
......@@ -216,18 +243,7 @@ read_from_buffer(struct buffer *buffer, void *dest, size_t length,
length = buffer->size - buffer->consumed;
memcpy(dest, buffer->data + buffer->consumed, length);
buffer->consumed += length;
if (buffer->consumed == buffer->size) {
list_del(&buffer->siblings);
if (rewind_head != NULL)
/* append this buffer to the rewind buffer list */
list_add_tail(&buffer->siblings, rewind_head);
else
g_free(buffer);
}
consume_buffer(buffer, length, rewind_head);
return length;
}
......@@ -266,8 +282,6 @@ input_curl_read(struct input_stream *is, void *ptr, size_t size)
bret = input_curl_multi_info_read(is);
if (!bret)
return 0;
c->eof = running_handles == 0;
}
/* send buffer contents */
......@@ -345,8 +359,6 @@ input_curl_buffer(struct input_stream *is)
if (!ret)
return -1;
c->eof = running_handles == 0;
return c->buffered;
}
......@@ -480,8 +492,6 @@ input_curl_send_request(struct input_curl *c)
mcode = curl_multi_perform(c->multi, &running_handles);
} while (mcode == CURLM_CALL_MULTI_PERFORM);
c->eof = running_handles == 0;
if (mcode != CURLM_OK) {
g_warning("curl_multi_perform() failed: %s\n",
curl_multi_strerror(mcode));
......@@ -573,28 +583,66 @@ input_curl_seek(struct input_stream *is, off_t offset, int whence)
switch (whence) {
case SEEK_SET:
is->offset = offset;
break;
case SEEK_CUR:
is->offset += offset;
offset += is->offset;
break;
case SEEK_END:
is->offset = is->size + offset;
if (is->size < 0)
/* stream size is not known */
return false;
offset += is->size;
break;
default:
return false;
}
if (is->offset < 0)
if (offset < 0)
return false;
/* check if we can fast-forward the buffer */
while (offset > is->offset && !list_empty(&c->buffers)) {
struct list_head *rewind_head;
struct buffer *buffer = (struct buffer *)c->buffers.next;
size_t length;
if (!list_empty(&c->rewind) || is->offset == 0)
/* at the beginning or already writing the rewind
buffer list */
rewind_head = &c->rewind;
else
/* we don't need the rewind buffers anymore */
rewind_head = NULL;
length = buffer->size - buffer->consumed;
if (offset - is->offset < (off_t)length)
length = offset - is->offset;
consume_buffer(buffer, length, rewind_head);
is->offset += length;
}
if (offset == is->offset)
return true;
/* close the old connection and open a new one */
input_curl_easy_free(c);
is->offset = offset;
if (is->offset == is->size) {
/* seek to EOF: simulate empty result; avoid
triggering a "416 Requested Range Not Satisfiable"
response */
c->eof = true;
return true;
}
ret = input_curl_easy_init(is);
if (!ret)
return false;
......@@ -610,7 +658,7 @@ input_curl_seek(struct input_stream *is, off_t offset, int whence)
if (!ret)
return false;
return true;
return input_curl_multi_info_read(is);
}
static bool
......
......@@ -26,6 +26,7 @@
#endif
#include <glib.h>
#include <assert.h>
static const struct input_plugin *const input_plugins[] = {
&input_plugin_file,
......@@ -57,7 +58,7 @@ input_stream_open(struct input_stream *is, const char *url)
is->seekable = false;
is->ready = false;
is->offset = 0;
is->size = 0;
is->size = -1;
is->error = 0;
is->mime = NULL;
is->meta_name = NULL;
......@@ -84,6 +85,9 @@ input_stream_seek(struct input_stream *is, off_t offset, int whence)
size_t
input_stream_read(struct input_stream *is, void *ptr, size_t size)
{
assert(ptr != NULL);
assert(size > 0);
return is->plugin->read(is, ptr, size);
}
......
......@@ -67,7 +67,7 @@ static const char *log_date(void)
}
static void
mpd_log_func(G_GNUC_UNUSED const gchar *log_domain,
mpd_log_func(const gchar *log_domain,
G_GNUC_UNUSED GLogLevelFlags log_level,
const gchar *message, G_GNUC_UNUSED gpointer user_data)
{
......@@ -87,8 +87,12 @@ mpd_log_func(G_GNUC_UNUSED const gchar *log_domain,
} else
converted = NULL;
fprintf(file, "%s%s",
if (log_domain == NULL)
log_domain = "";
fprintf(file, "%s%s%s%s",
stdout_mode ? "" : log_date(),
log_domain, *log_domain == 0 ? "" : ": ",
message);
g_free(converted);
......
......@@ -383,6 +383,7 @@ int main(int argc, char *argv[])
{
Options options;
clock_t start;
GTimer *save_state_timer;
#ifdef HAVE_LOCALE
/* initialize locale */
......@@ -446,6 +447,8 @@ int main(int argc, char *argv[])
player_create();
read_state_file();
save_state_timer = g_timer_new();
while (COMMAND_RETURN_KILL != client_manager_io() &&
COMMAND_RETURN_KILL != handlePendingSignals()) {
unsigned flags;
......@@ -459,6 +462,12 @@ int main(int argc, char *argv[])
flags = idle_get();
if (flags != 0)
client_manager_idle_add(flags);
if (g_timer_elapsed(save_state_timer, NULL) >= 5 * 60) {
g_debug("Saving state file\n");
write_state_file();
g_timer_start(save_state_timer);
}
}
write_state_file();
......
......@@ -109,7 +109,7 @@ map_directory_child_fs(const struct directory *directory, const char *name,
if (parent_fs == NULL)
return NULL;
utf8_to_fs_charset(buffer, name);
name = utf8_to_fs_charset(buffer, name);
pfx_dir(buffer, name, strlen(name),
parent_fs, strlen(parent_fs));
return buffer;
......
......@@ -33,7 +33,7 @@ char *fs_charset_to_utf8(char *dst, const char *str)
GError *error = NULL;
p = g_convert(str, -1,
fs_charset, "utf-8",
"utf-8", fs_charset,
NULL, NULL, &error);
if (p == NULL) {
/* no fallback */
......@@ -52,7 +52,7 @@ char *utf8_to_fs_charset(char *dst, const char *str)
GError *error = NULL;
p = g_convert(str, -1,
"utf-8", fs_charset,
fs_charset, "utf-8",
NULL, NULL, &error);
if (p == NULL) {
/* fall back to UTF-8 */
......
......@@ -67,7 +67,7 @@ void music_pipe_free(void)
/** return the index of the chunk after i */
static inline unsigned successor(unsigned i)
{
assert(i <= music_pipe.num_chunks);
assert(i < music_pipe.num_chunks);
++i;
return i == music_pipe.num_chunks ? 0 : i;
......
......@@ -389,12 +389,11 @@ updateDirectory(struct directory *directory, const struct stat *st)
char *utf8;
struct stat st2;
if (skip_path(ent->d_name) ||
skip_symlink(directory, ent->d_name))
if (skip_path(ent->d_name))
continue;
utf8 = fs_charset_to_utf8(path_max_tmp, ent->d_name);
if (!utf8)
if (utf8 == NULL || skip_symlink(directory, utf8))
continue;
if (stat_directory_child(directory, utf8, &st2) == 0)
......@@ -413,7 +412,7 @@ static struct directory *
directory_make_child_checked(struct directory *parent, const char *path)
{
struct directory *directory;
char *basename;
char *base;
struct stat st;
struct song *conflicting;
......@@ -421,21 +420,21 @@ directory_make_child_checked(struct directory *parent, const char *path)
if (directory != NULL)
return directory;
basename = g_path_get_basename(path);
base = g_path_get_basename(path);
if (stat_directory_child(parent, basename, &st) < 0 ||
if (stat_directory_child(parent, base, &st) < 0 ||
inodeFoundInParent(parent, st.st_ino, st.st_dev)) {
g_free(basename);
g_free(base);
return NULL;
}
/* if we're adding directory paths, make sure to delete filenames
with potentially the same name */
conflicting = songvec_find(&parent->songs, basename);
conflicting = songvec_find(&parent->songs, base);
if (conflicting)
delete_song(parent, conflicting);
g_free(basename);
g_free(base);
directory = directory_new_child(parent, path);
directory_set_stat(directory, &st);
......
......@@ -29,6 +29,15 @@
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
#ifndef assert_static
/* Compile time assertion developed by Ralf Holly */
/* http://pera-software.com/articles/compile-time-assertions.pdf */
#define assert_static(e) \
do { \
enum { assert_static__ = 1/(e) }; \
} while (0)
#endif /* !assert_static */
char *myFgets(char *buffer, int bufferSize, FILE * fp);
void stripReturnChar(char *string);
......
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