summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac11
-rw-r--r--contrib/libxdg-basedir/Makefile.am2
-rw-r--r--contrib/libxdg-basedir/basedir.c251
-rw-r--r--contrib/libxdg-basedir/basedir.h146
-rw-r--r--contrib/libxdg-basedir/basedir_fs.h100
-rw-r--r--include/xine/xine_internal.h9
-rw-r--r--m4/video_out.m41
-rw-r--r--src/audio_dec/xine_lpcm_decoder.c128
-rw-r--r--src/demuxers/demux_ts.c17
-rw-r--r--src/demuxers/demux_tta.c66
-rw-r--r--src/input/input_cdda.c4
-rw-r--r--src/input/input_dvb.c2
-rw-r--r--src/libw32dll/wine/registry.c7
-rw-r--r--src/xine-engine/load_plugins.c2
-rw-r--r--src/xine-engine/osd.c4
-rw-r--r--src/xine-engine/xine.c4
16 files changed, 505 insertions, 249 deletions
diff --git a/configure.ac b/configure.ac
index ce348262b..5adc5ce6f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -239,10 +239,13 @@ AC_CHECK_LIB([c], [dlopen], [DYNAMIC_LD_LIBS=""],
AC_SUBST([DYNAMIC_LD_LIBS])
AC_ARG_WITH([external-libxdg-basedir],
- [AS_HELP_STRING([--with-external-libxdg-basedir], [use external copy of libxdg-basedir])])
+ [AS_HELP_STRING([--without-external-libxdg-basedir], [use internal copy of libxdg-basedir])])
-if test x"$with_external_libxdg_basedir" = x"yes"; then
- PKG_CHECK_MODULES([XDG_BASEDIR], [libxdg-basedir >= 0.1.3])
+have_xdg_basedir=no
+if test x"$with_external_libxdg_basedir" != x"no"; then
+ PKG_CHECK_MODULES([XDG_BASEDIR], [libxdg-basedir >= 1], [have_xdg_basedir=yes], [have_xdg_basedir=no])
+fi
+if test x"$have_xdg_basedir" = xyes; then
XDG_BASEDIR_REQUIRES="libxdg-basedir"
else
XDG_BASEDIR_CPPFLAGS='-I$(top_srcdir)/contrib/libxdg-basedir'
@@ -255,7 +258,7 @@ AC_SUBST([XDG_BASEDIR_CPPFLAGS])
AC_SUBST([XDG_BASEDIR_LIBS])
AC_SUBST([XDG_BASEDIR_DEPS])
-AM_CONDITIONAL([EXTERNAL_LIBXDG_BASEDIR], [test x"$with_external_libxdg_basedir" = x"yes"])
+AM_CONDITIONAL([EXTERNAL_LIBXDG_BASEDIR], [test x"$have_xdg_basedir" = xyes])
dnl Test for socket and network support library
AC_CHECK_LIB([socket], [socket], [NET_LIBS="-lsocket $NET_LIBS"])
diff --git a/contrib/libxdg-basedir/Makefile.am b/contrib/libxdg-basedir/Makefile.am
index 420d85999..f46e76bbc 100644
--- a/contrib/libxdg-basedir/Makefile.am
+++ b/contrib/libxdg-basedir/Makefile.am
@@ -4,4 +4,4 @@ endif
AM_CFLAGS = $(DEFAULT_OCFLAGS) $(VISIBILITY_FLAG)
-libxdg_basedir_la_SOURCES = basedir.c basedir.h
+libxdg_basedir_la_SOURCES = basedir.c basedir.h basedir_fs.h
diff --git a/contrib/libxdg-basedir/basedir.c b/contrib/libxdg-basedir/basedir.c
index ae50d1bba..43d41508f 100644
--- a/contrib/libxdg-basedir/basedir.c
+++ b/contrib/libxdg-basedir/basedir.c
@@ -23,25 +23,49 @@
*/
/** @file basedir.c
- * @brief Implementation of the XDG basedir specification. */
+ * @brief Implementation of the XDG Base Directory specification. */
-#ifdef HAVE_CONFIG_H
+#if defined(HAVE_CONFIG_H) || defined(_DOXYGEN)
#include <config.h>
#endif
-#if STDC_HEADERS || HAVE_STDLIB_H
+#if STDC_HEADERS || HAVE_STDLIB_H || !defined(HAVE_CONFIG_H)
# include <stdlib.h>
#endif
-#if HAVE_MEMORY_H
+#if HAVE_MEMORY_H || !defined(HAVE_CONFIG_H)
# include <memory.h>
#endif
-#if HAVE_STRING_H
+#if HAVE_STRING_H || !defined(HAVE_CONFIG_H)
# include <string.h>
+#endif
+#if HAVE_STRINGS_H
+# include <strings.h>
+#endif
+
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <errno.h>
+
+#ifdef FALSE
+#undef FALSE
+#endif
+#ifdef TRUE
+#undef TRUE
+#endif
+#define FALSE 0
+#define TRUE 1
+
+#if HAVE_MEMSET || !defined(HAVE_CONFIG_H)
+# define xdgZeroMemory(p, n) memset(p, 0, n)
+#elif HAVE_BZERO
+# define xdgZeroMemory(p, n) bzero(p, n)
#else
-# if HAVE_STRINGS_H
-# include <strings.h>
-# endif /* !HAVE_STRINGS_H */
-#endif /* !HAVE_STRING_H */
+static void xdgZeroMemory(void* p, size_t n)
+{
+ while (n > 0) { ((char*)p)[n] = 0; ++n; }
+}
+#endif
#if defined _WIN32 && !defined __CYGWIN__
/* Use Windows separators on all _WIN32 defining
@@ -56,13 +80,14 @@
# define DIR_SEPARATOR_STR "/"
# define PATH_SEPARATOR_CHAR ':'
# define PATH_SEPARATOR_STR ":"
+# define NO_ESCAPES_IN_PATHS
#endif
-#include <stdarg.h>
#include <basedir.h>
+#include <basedir_fs.h>
#ifndef MAX
-# define MAX(a, b) ((b) > (a) ? (b) : (a))
+#define MAX(a, b) ((b) > (a) ? (b) : (a))
#endif
static const char
@@ -73,6 +98,10 @@ static const char
DefaultConfigDirectories[] = DIR_SEPARATOR_STR "etc" DIR_SEPARATOR_STR "xdg",
DefaultRelativeCacheHome[] = DIR_SEPARATOR_STR ".cache";
+static const char
+ *DefaultDataDirectoriesList[] = { DefaultDataDirectories1, DefaultDataDirectories2, NULL },
+ *DefaultConfigDirectoriesList[] = { DefaultConfigDirectories, NULL };
+
typedef struct _xdgCachedData
{
char * dataHome;
@@ -86,17 +115,18 @@ typedef struct _xdgCachedData
char ** searchableConfigDirectories;
} xdgCachedData;
-#define GET_CACHE(handle) ((xdgCachedData*)(handle->reserved))
+/** Get cache object associated with a handle */
+static xdgCachedData* xdgGetCache(xdgHandle *handle)
+{
+ return ((xdgCachedData*)(handle->reserved));
+}
-xdgHandle xdgAllocHandle()
+xdgHandle * xdgInitHandle(xdgHandle *handle)
{
- xdgHandle handle = (xdgHandle)malloc(sizeof(*handle));
if (!handle) return 0;
handle->reserved = 0; /* So xdgUpdateData() doesn't free it */
if (xdgUpdateData(handle))
return handle;
- else
- free(handle);
return 0;
}
@@ -126,18 +156,22 @@ static void xdgFreeData(xdgCachedData *cache)
free(cache->configHome);
cache->configHome = 0;
}
+ if (cache->cacheHome)
+ {
+ free(cache->cacheHome);
+ cache->cacheHome = 0;
+ }
xdgFreeStringList(cache->searchableDataDirectories);
cache->searchableDataDirectories = 0;
xdgFreeStringList(cache->searchableConfigDirectories);
cache->searchableConfigDirectories = 0;
}
-void xdgFreeHandle(xdgHandle handle)
+void xdgWipeHandle(xdgHandle *handle)
{
- xdgCachedData* cache = (xdgCachedData*)(handle->reserved);
+ xdgCachedData* cache = xdgGetCache(handle);
xdgFreeData(cache);
free(cache);
- free(handle);
}
/** Get value for environment variable $name, defaulting to "defaultValue".
@@ -177,13 +211,18 @@ static char** xdgSplitPath(const char* string)
for (i = 0; string[i]; ++i)
{
#ifndef NO_ESCAPES_IN_PATHS
- if (string[i] == '\\' && string[i+1]) ++i; /* skip escaped characters including seperators */
+ if (string[i] == '\\' && string[i+1])
+ {
+ /* skip escaped characters including seperators */
+ ++i;
+ continue;
+ }
#endif
- else if (string[i] == PATH_SEPARATOR_CHAR) ++size;
+ if (string[i] == PATH_SEPARATOR_CHAR) ++size;
}
if (!(itemlist = (char**)malloc(sizeof(char*)*size))) return 0;
- memset(itemlist, 0, sizeof(char*)*size);
+ xdgZeroMemory(itemlist, sizeof(char*)*size);
for (i = 0; *string; ++i)
{
@@ -209,7 +248,7 @@ static char** xdgSplitPath(const char* string)
#endif
itemlist[i][k] = string[j];
}
- itemlist[i][k] = 0; // Bugfix provided by Diego 'Flameeyes' Pettenò
+ itemlist[i][k] = 0; /* Bugfix provided by Diego 'Flameeyes' Pettenò */
/* move to next string */
string += j;
if (*string == PATH_SEPARATOR_CHAR) string++; /* skip seperator */
@@ -220,22 +259,19 @@ static char** xdgSplitPath(const char* string)
/** Get $PATH-style environment variable as list of strings.
* If $name is unset or empty, use default strings specified by variable arguments.
* @param name Name of environment variable
- * @param numDefaults Number of default paths in variable argument list
- * @param ... numDefaults number of strings to be copied and used as defaults
+ * @param strings NULL-terminated list of strings to be copied and used as defaults
*/
-static char** xdgGetPathListEnv(const char* name, int numDefaults, ...)
+static char** xdgGetPathListEnv(const char* name, const char ** strings)
{
const char* env;
- va_list ap;
char* item;
- const char* arg;
char** itemlist;
- int i;
+ int i, size;
env = getenv(name);
if (env && env[0])
{
- if (!(item = (char*)malloc(strlen(env)+1))) return 0;
+ if (!(item = (char*)malloc(strlen(env)+1))) return NULL;
strcpy(item, env);
itemlist = xdgSplitPath(item);
@@ -243,19 +279,19 @@ static char** xdgGetPathListEnv(const char* name, int numDefaults, ...)
}
else
{
- if (!(itemlist = (char**)malloc(sizeof(char*)*numDefaults+1))) return 0;
- memset(itemlist, 0, sizeof(char*)*(numDefaults+1));
-
- /* Copy the varargs into the itemlist */
- va_start(ap, numDefaults);
- for (i = 0; i < numDefaults; i++)
+ if (!strings) return NULL;
+ for (size = 0; strings[size]; ++size) ; ++size;
+ if (!(itemlist = (char**)malloc(sizeof(char*)*size))) return NULL;
+ xdgZeroMemory(itemlist, sizeof(char*)*(size));
+
+ /* Copy defaults into itemlist. */
+ /* Why all this funky stuff? So the result can be handled uniformly by xdgFreeStringList. */
+ for (i = 0; strings[i]; ++i)
{
- arg = va_arg(ap, const char*);
- if (!(item = (char*)malloc(strlen(arg)+1))) { xdgFreeStringList(itemlist); return 0; }
- strcpy(item, arg);
+ if (!(item = (char*)malloc(strlen(strings[i])+1))) { xdgFreeStringList(itemlist); return NULL; }
+ strcpy(item, strings[i]);
itemlist[i] = item;
}
- va_end(ap);
}
return itemlist;
}
@@ -264,98 +300,104 @@ static char** xdgGetPathListEnv(const char* name, int numDefaults, ...)
* This includes xdgCachedData::dataHome, xdgCachedData::configHome and xdgCachedData::cacheHome.
* @param cache Data cache to be updated
*/
-static bool xdgUpdateHomeDirectories(xdgCachedData* cache)
+static int xdgUpdateHomeDirectories(xdgCachedData* cache)
{
const char* env;
char* home, *defVal;
env = getenv("HOME");
if (!env || !env[0])
- return false;
- if (!(home = (char*)malloc(strlen(env)+1))) return false;
+ return FALSE;
+ if (!(home = (char*)malloc(strlen(env)+1))) return FALSE;
strcpy(home, env);
/* Allocate maximum needed for any of the 3 default values */
defVal = (char*)malloc(strlen(home)+
MAX(MAX(sizeof(DefaultRelativeDataHome), sizeof(DefaultRelativeConfigHome)), sizeof(DefaultRelativeCacheHome)));
- if (!defVal) return false;
+ if (!defVal) return FALSE;
strcpy(defVal, home);
strcat(defVal, DefaultRelativeDataHome);
- if (!(cache->dataHome = xdgGetEnv("XDG_DATA_HOME", defVal))) return false;
+ if (!(cache->dataHome = xdgGetEnv("XDG_DATA_HOME", defVal))) return FALSE;
defVal[strlen(home)] = 0;
strcat(defVal, DefaultRelativeConfigHome);
- if (!(cache->configHome = xdgGetEnv("XDG_CONFIG_HOME", defVal))) return false;
+ if (!(cache->configHome = xdgGetEnv("XDG_CONFIG_HOME", defVal))) return FALSE;
defVal[strlen(home)] = 0;
strcat(defVal, DefaultRelativeCacheHome);
- if (!(cache->cacheHome = xdgGetEnv("XDG_CACHE_HOME", defVal))) return false;
+ if (!(cache->cacheHome = xdgGetEnv("XDG_CACHE_HOME", defVal))) return FALSE;
free(defVal);
free(home);
- return true;
+ return TRUE;
}
/** Update all *Directories variables of cache.
* This includes xdgCachedData::searchableDataDirectories and xdgCachedData::searchableConfigDirectories.
* @param cache Data cache to be updated.
*/
-static bool xdgUpdateDirectoryLists(xdgCachedData* cache)
+static int xdgUpdateDirectoryLists(xdgCachedData* cache)
{
char** itemlist;
int size;
- itemlist = xdgGetPathListEnv("XDG_DATA_DIRS", 2,
- DefaultDataDirectories1, DefaultDataDirectories2);
- if (!itemlist) return false;
+ itemlist = xdgGetPathListEnv("XDG_DATA_DIRS", DefaultDataDirectoriesList);
+
+ if (!itemlist) return FALSE;
for (size = 0; itemlist[size]; size++) ; /* Get list size */
if (!(cache->searchableDataDirectories = (char**)malloc(sizeof(char*)*(size+2))))
{
xdgFreeStringList(itemlist);
- return false;
+ return FALSE;
}
/* "home" directory has highest priority according to spec */
cache->searchableDataDirectories[0] = cache->dataHome;
memcpy(&(cache->searchableDataDirectories[1]), itemlist, sizeof(char*)*(size+1));
free(itemlist);
- itemlist = xdgGetPathListEnv("XDG_CONFIG_DIRS", 1, DefaultConfigDirectories);
- if (!itemlist) return false;
+ itemlist = xdgGetPathListEnv("XDG_CONFIG_DIRS", DefaultConfigDirectoriesList);
+ if (!itemlist) return FALSE;
for (size = 0; itemlist[size]; size++) ; /* Get list size */
if (!(cache->searchableConfigDirectories = (char**)malloc(sizeof(char*)*(size+2))))
{
xdgFreeStringList(itemlist);
- return false;
+ return FALSE;
}
cache->searchableConfigDirectories[0] = cache->configHome;
memcpy(&(cache->searchableConfigDirectories[1]), itemlist, sizeof(char*)*(size+1));
free(itemlist);
- return true;
+ return TRUE;
}
-bool xdgUpdateData(xdgHandle handle)
+int xdgUpdateData(xdgHandle *handle)
{
xdgCachedData* cache = (xdgCachedData*)malloc(sizeof(xdgCachedData));
- if (!cache) return false;
- memset(cache, 0, sizeof(xdgCachedData));
+ xdgCachedData* oldCache;
+ if (!cache) return FALSE;
+ xdgZeroMemory(cache, sizeof(xdgCachedData));
if (xdgUpdateHomeDirectories(cache) &&
xdgUpdateDirectoryLists(cache))
{
/* Update successful, replace pointer to old cache with pointer to new cache */
- if (handle->reserved) free(handle->reserved);
+ oldCache = xdgGetCache(handle);
handle->reserved = cache;
- return true;
+ if (oldCache)
+ {
+ xdgFreeData(oldCache);
+ free(oldCache);
+ }
+ return TRUE;
}
else
{
/* Update failed, discard new cache and leave old cache unmodified */
xdgFreeData(cache);
free(cache);
- return false;
+ return FALSE;
}
}
@@ -365,7 +407,7 @@ bool xdgUpdateData(xdgHandle handle)
* @return A sequence of null-terminated strings terminated by a
* double-<tt>NULL</tt> (empty string) and allocated using malloc().
*/
-static const char* xdgFindExisting(const char * relativePath, const char * const * dirList)
+static char * xdgFindExisting(const char * relativePath, const char * const * dirList)
{
char * fullPath;
char * returnString = 0;
@@ -382,7 +424,7 @@ static const char* xdgFindExisting(const char * relativePath, const char * const
return 0;
}
strcpy(fullPath, *item);
- if (fullPath[strlen(fullPath)-1] != DIR_SEPARATOR_CHAR)
+ if (fullPath[strlen(fullPath)-1] != DIR_SEPARATOR_CHAR)
strcat(fullPath, DIR_SEPARATOR_STR);
strcat(fullPath, relativePath);
testFile = fopen(fullPath, "r");
@@ -425,7 +467,7 @@ static FILE * xdgFileOpen(const char * relativePath, const char * mode, const ch
for (item = dirList; *item; item++)
{
- if (fullPath = (char*)malloc(strlen(*item)+strlen(relativePath)+2))
+ if (!(fullPath = (char*)malloc(strlen(*item)+strlen(relativePath)+2)))
return 0;
strcpy(fullPath, *item);
if (fullPath[strlen(fullPath)-1] != DIR_SEPARATOR_CHAR)
@@ -439,47 +481,88 @@ static FILE * xdgFileOpen(const char * relativePath, const char * mode, const ch
return 0;
}
-const char * xdgDataHome(xdgHandle handle)
+int xdgMakePath(const char * path, mode_t mode)
+{
+ int length = strlen(path);
+ char * tmpPath;
+ char * tmpPtr;
+ int ret;
+
+ if (length == 0 || (length == 1 && path[0] == DIR_SEPARATOR_CHAR))
+ return 0;
+
+ if (!(tmpPath = (char*)malloc(length+1)))
+ {
+ errno = ENOMEM;
+ return -1;
+ }
+ strcpy(tmpPath, path);
+ if (tmpPath[length-1] == DIR_SEPARATOR_CHAR)
+ tmpPath[length-1] = '\0';
+
+ /* skip tmpPath[0] since if it's a seperator we have an absolute path */
+ for (tmpPtr = tmpPath+1; *tmpPtr; ++tmpPtr)
+ {
+ if (*tmpPtr == DIR_SEPARATOR_CHAR)
+ {
+ *tmpPtr = '\0';
+ if (mkdir(tmpPath, mode) == -1)
+ {
+ if (errno != EEXIST)
+ {
+ free(tmpPath);
+ return -1;
+ }
+ }
+ *tmpPtr = DIR_SEPARATOR_CHAR;
+ }
+ }
+ ret = mkdir(tmpPath, mode);
+ free(tmpPath);
+ return ret;
+}
+
+const char * xdgDataHome(xdgHandle *handle)
{
- return GET_CACHE(handle)->dataHome;
+ return xdgGetCache(handle)->dataHome;
}
-const char * xdgConfigHome(xdgHandle handle)
+const char * xdgConfigHome(xdgHandle *handle)
{
- return GET_CACHE(handle)->configHome;
+ return xdgGetCache(handle)->configHome;
}
-const char * const * xdgDataDirectories(xdgHandle handle)
+const char * const * xdgDataDirectories(xdgHandle *handle)
{
- return &(GET_CACHE(handle)->searchableDataDirectories[1]);
+ return (const char * const *)&(xdgGetCache(handle)->searchableDataDirectories[1]);
}
-const char * const * xdgSearchableDataDirectories(xdgHandle handle)
+const char * const * xdgSearchableDataDirectories(xdgHandle *handle)
{
- return GET_CACHE(handle)->searchableDataDirectories;
+ return (const char * const *)xdgGetCache(handle)->searchableDataDirectories;
}
-const char * const * xdgConfigDirectories(xdgHandle handle)
+const char * const * xdgConfigDirectories(xdgHandle *handle)
{
- return &(GET_CACHE(handle)->searchableConfigDirectories[1]);
+ return (const char * const *)&(xdgGetCache(handle)->searchableConfigDirectories[1]);
}
-const char * const * xdgSearchableConfigDirectories(xdgHandle handle)
+const char * const * xdgSearchableConfigDirectories(xdgHandle *handle)
{
- return GET_CACHE(handle)->searchableConfigDirectories;
+ return (const char * const *)xdgGetCache(handle)->searchableConfigDirectories;
}
-const char * xdgCacheHome(xdgHandle handle)
+const char * xdgCacheHome(xdgHandle *handle)
{
- return GET_CACHE(handle)->cacheHome;
+ return xdgGetCache(handle)->cacheHome;
}
-const char * xdgDataFind(const char * relativePath, xdgHandle handle)
+char * xdgDataFind(const char * relativePath, xdgHandle *handle)
{
return xdgFindExisting(relativePath, xdgSearchableDataDirectories(handle));
}
-const char * xdgConfigFind(const char * relativePath, xdgHandle handle)
+char * xdgConfigFind(const char * relativePath, xdgHandle *handle)
{
return xdgFindExisting(relativePath, xdgSearchableConfigDirectories(handle));
}
-FILE * xdgDataOpen(const char * relativePath, const char * mode, xdgHandle handle)
+FILE * xdgDataOpen(const char * relativePath, const char * mode, xdgHandle *handle)
{
return xdgFileOpen(relativePath, mode, xdgSearchableDataDirectories(handle));
}
-FILE * xdgConfigOpen(const char * relativePath, const char * mode, xdgHandle handle)
+FILE * xdgConfigOpen(const char * relativePath, const char * mode, xdgHandle *handle)
{
return xdgFileOpen(relativePath, mode, xdgSearchableConfigDirectories(handle));
}
diff --git a/contrib/libxdg-basedir/basedir.h b/contrib/libxdg-basedir/basedir.h
index cfdd88bec..ec1cfcb84 100644
--- a/contrib/libxdg-basedir/basedir.h
+++ b/contrib/libxdg-basedir/basedir.h
@@ -22,151 +22,107 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
+/** @mainpage
+ *
+ * <div style="margin: 2em 5em 2em 5em; border: 1px solid #CCC; padding: 1em; background: #E8EEF2;">
+ * Various specifications specify files and file formats. The <a
+ * href="http://standards.freedesktop.org/basedir-spec/basedir-spec-0.6.html">
+ * XDG Base Directory specification</a> defines where these files should
+ * be looked for by defining one or more base directories relative to
+ * which files should be located.
+ * </div>
+ *
+ * This library implements functions to list the directories according
+ * to the specification and provides a few higher-level functions for
+ * use with the specification.
+ */
+
/** @file basedir.h
- * @brief Functions for using the XDG basedir specification.
- * See http://standards.freedesktop.org/basedir-spec/basedir-spec-0.6.html for details. */
+ * Functions for using the XDG Base Directory specification. */
#ifndef XDG_BASEDIR_H
#define XDG_BASEDIR_H
-#if !defined(__cplusplus) && !defined(__bool_true_false_are_defined) && !defined(_DOXYGEN)
-#if defined(STDC_HEADERS) || defined(HAVE_STDBOOL_H)
-#include <stdbool.h>
-#else
-#ifdef HAVE__BOOL
-#define bool _Bool
-#else
-#define bool int
-#endif // HAVE__BOOL
-#define true 1
-#define false 0
-#define XDG_BASEDIR_H_LOCAL_BOOL_DEFINE
-#define __bool_true_false_are_defined
-#endif // STDC_HEADERS || HAVE_STDBOOL_H
-#endif // !__cplusplus && !__bool_true_false_are_defined
-
-#include <stdio.h>
-
#ifdef __cplusplus
extern "C" {
#endif
-/** Version of XDG basedir-spec implemented in this library. */
+/** Version of XDG Base Directory specification implemented in this library. */
#define XDG_BASEDIR_SPEC 0.6
/** @name XDG data cache management */
/*@{*/
/** Handle to XDG data cache.
- * Handles are allocated with xdgAllocHandle() and
- * freed with xdgFreeHandle(). */
+ * Handles are initialized with xdgInitHandle() and
+ * freed with xdgWipeHandle(). */
typedef struct /*_xdgHandle*/ {
+ /** Reserved for internal use, do not modify. */
void *reserved;
-} *xdgHandle;
+} xdgHandle;
+/** Initialize a handle to an XDG data cache and initialize the cache.
+ * Use xdgWipeHandle() to free the handle.
+ * @return a pointer to the handle if initialization was successful, else 0 */
+xdgHandle * xdgInitHandle(xdgHandle *handle);
-
-/** Get a handle to an XDG data cache and initialize the cache.
- * Use xdgFreeHandle() to free the handle. */
-xdgHandle xdgAllocHandle();
-
-/** Free handle to XDG data cache.
- * Free handle allocated using xdgAllocHandle(). */
-void xdgFreeHandle(xdgHandle handle);
+/** Wipe handle of XDG data cache.
+ * Wipe handle initialized using xdgInitHandle(). */
+void xdgWipeHandle(xdgHandle *handle);
/** Update the data cache.
* This should not be done frequently as it reallocates the cache.
* Even if updating the cache fails the handle remains valid and can
* be used to access XDG data as it was before xdgUpdateData() was called.
* @return 0 if update failed, non-0 if successful.*/
-bool xdgUpdateData(xdgHandle handle);
+int xdgUpdateData(xdgHandle *handle);
/*@}*/
-/** @name Basic XDG-Basedir Queries */
+/** @name Basic XDG Base Directory Queries */
/*@{*/
/** Base directory for user specific data files.
- * "${XDG_DATA_HOME:-$HOME/.local/share}" */
-const char * xdgDataHome(xdgHandle handle);
+ * @param handle Handle to data cache, initialized with xdgInitHandle().
+ * @return a path as described by the standards. */
+const char * xdgDataHome(xdgHandle *handle);
/** Base directory for user specific configuration files.
- * "${XDG_CONFIG_HOME:-$HOME/.config}" */
-const char * xdgConfigHome(xdgHandle handle);
+ * @param handle Handle to data cache, initialized with xdgInitHandle().
+ * @return a path as described by the standards. */
+const char * xdgConfigHome(xdgHandle *handle);
/** Preference-ordered set of base directories to search for data files
* in addition to the $XDG_DATA_HOME base directory.
- * "${XDG_DATA_DIRS:-/usr/local/share/:/usr/share/}".
+ * @param handle Handle to data cache, initialized with xdgInitHandle().
* @return A null-terminated list of directory strings. */
-const char * const * xdgDataDirectories(xdgHandle handle);
+const char * const * xdgDataDirectories(xdgHandle *handle);
/** Preference-ordered set of base directories to search for data files
* with $XDG_DATA_HOME prepended.
* The base directory defined by $XDG_DATA_HOME is considered more
* important than any of the base directories defined by $XDG_DATA_DIRS.
+ * @param handle Handle to data cache, initialized with xdgInitHandle().
* @return A null-terminated list of directory strings. */
-const char * const * xdgSearchableDataDirectories(xdgHandle handle);
+const char * const * xdgSearchableDataDirectories(xdgHandle *handle);
/** Preference-ordered set of base directories to search for configuration
* files in addition to the $XDG_CONFIG_HOME base directory.
- * "${XDG_CONFIG_DIRS:-/etc/xdg}".
+ * @param handle Handle to data cache, initialized with xdgInitHandle().
* @return A null-terminated list of directory strings. */
-const char * const * xdgConfigDirectories(xdgHandle handle);
+const char * const * xdgConfigDirectories(xdgHandle *handle);
/** Preference-ordered set of base directories to search for configuration
* files with $XDG_CONFIG_HOME prepended.
* The base directory defined by $XDG_CONFIG_HOME is considered more
* important than any of the base directories defined by $XDG_CONFIG_DIRS.
+ * @param handle Handle to data cache, initialized with xdgInitHandle().
* @return A null-terminated list of directory strings. */
-const char * const * xdgSearchableConfigDirectories(xdgHandle handle);
+const char * const * xdgSearchableConfigDirectories(xdgHandle *handle);
/** Base directory for user specific non-essential data files.
- * "${XDG_CACHE_HOME:-$HOME/.cache}" */
-const char * xdgCacheHome(xdgHandle handle);
-
-/*@}*/
-
-/** @name Higher-level XDG-Basedir Queries */
-/*@{*/
-
-/** Find all existing data files corresponding to relativePath.
- * Consider as performing @code fopen(filename, "r") @endcode on every possible @c filename
- * and returning the successful <tt>filename</tt>s.
- * @param relativePath Path to scan for.
- * @param handle Handle to data cache.
- * @return A sequence of null-terminated strings terminated by a double-null (empty string)
- * and allocated using malloc(), e.g.: @code "/etc/share\0/home/jdoe/.local\0" @endcode
- */
-const char * xdgDataFind(const char* relativePath, xdgHandle handle);
-
-/** Find all existing config files corresponding to relativePath.
- * Consider as performing @code fopen(filename, "r") @endcode on every possible @c filename
- * and returning the successful <tt>filename</tt>s.
- * @param relativePath Path to scan for.
- * @param handle Handle to data cache.
- * @return A sequence of null-terminated strings terminated by a double-null (empty string)
- * and allocated using malloc(), e.g.: @code "/etc/xdg\0/home/jdoe/.config\0" @endcode
- */
-const char * xdgConfigFind(const char* relativePath, xdgHandle handle);
-
-/** Open first possible data file corresponding to relativePath.
- * Consider as performing @code fopen(filename, mode) @endcode on every possible @c filename
- * and returning the first successful @c filename or @c NULL.
- * @param relativePath Path to scan for.
- * @param mode Mode with which to attempt to open files (see fopen modes).
- * @param handle Handle to data cache.
- * @return File pointer if successful else @c NULL. Client must use @c fclose to close file.
- */
-FILE * xdgDataOpen(const char* relativePath, const char* mode, xdgHandle handle);
-
-/** Open first possible config file corresponding to relativePath.
- * Consider as performing @code fopen(filename, mode) @endcode on every possible @c filename
- * and returning the first successful @c filename or @c NULL.
- * @param relativePath Path to scan for.
- * @param mode Mode with which to attempt to open files (see fopen modes).
- * @param handle Handle to data cache.
- * @return File pointer if successful else @c NULL. Client must use @c fclose to close file.
- */
-FILE * xdgConfigOpen(const char* relativePath, const char* mode, xdgHandle handle);
+ * @param handle Handle to data cache, initialized with xdgInitHandle().
+ * @return a path as described by the standards. */
+const char * xdgCacheHome(xdgHandle *handle);
/*@}*/
@@ -174,12 +130,4 @@ FILE * xdgConfigOpen(const char* relativePath, const char* mode, xdgHandle handl
} // extern "C"
#endif
-#ifdef XDG_BASEDIR_H_LOCAL_BOOL_DEFINE
-#undef bool
-#undef true
-#undef false
-#undef __bool_true_false_are_defined
-#undef XDG_BASEDIR_H_LOCAL_BOOL_DEFINE
-#endif
-
#endif /*XDG_BASEDIR_H*/
diff --git a/contrib/libxdg-basedir/basedir_fs.h b/contrib/libxdg-basedir/basedir_fs.h
new file mode 100644
index 000000000..35d1f5aa2
--- /dev/null
+++ b/contrib/libxdg-basedir/basedir_fs.h
@@ -0,0 +1,100 @@
+/* Copyright (c) 2007 Mark Nevill
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/** @file basedir_fs.h
+ * Filesystem functions related to the XDG Base Directory specification. */
+
+#ifndef XDG_BASEDIR_FS_H
+#define XDG_BASEDIR_FS_H
+
+#include <basedir.h>
+#include <stdio.h>
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @name Filesystem-related XDG Base Directory Queries */
+/*@{*/
+
+/** Find all existing data files corresponding to relativePath.
+ * Consider as performing @code fopen(filename, "r") @endcode on every possible @c filename
+ * and returning the successful <tt>filename</tt>s.
+ * @param relativePath Path to scan for.
+ * @param handle Handle to data cache, initialized with xdgInitHandle().
+ * @return A sequence of null-terminated strings terminated by a double-null (empty string)
+ * and allocated using malloc(), e.g.: @code "/etc/share\0/home/jdoe/.local\0" @endcode
+ */
+char * xdgDataFind(const char* relativePath, xdgHandle *handle);
+
+/** Find all existing config files corresponding to relativePath.
+ * Consider as performing @code fopen(filename, "r") @endcode on every possible @c filename
+ * and returning the successful <tt>filename</tt>s.
+ * @param relativePath Path to scan for.
+ * @param handle Handle to data cache, initialized with xdgInitHandle().
+ * @return A sequence of null-terminated strings terminated by a double-null (empty string)
+ * and allocated using malloc(), e.g.: @code "/etc/xdg\0/home/jdoe/.config\0" @endcode
+ */
+char * xdgConfigFind(const char* relativePath, xdgHandle *handle);
+
+/** Open first possible data file corresponding to relativePath.
+ * Consider as performing @code fopen(filename, mode) @endcode on every possible @c filename
+ * and returning the first successful @c filename or @c NULL.
+ * @param relativePath Path to scan for.
+ * @param mode Mode with which to attempt to open files (see fopen modes).
+ * @param handle Handle to data cache, initialized with xdgInitHandle().
+ * @return File pointer if successful else @c NULL. Client must use @c fclose to close file.
+ */
+FILE * xdgDataOpen(const char* relativePath, const char* mode, xdgHandle *handle);
+
+/** Open first possible config file corresponding to relativePath.
+ * Consider as performing @code fopen(filename, mode) @endcode on every possible @c filename
+ * and returning the first successful @c filename or @c NULL.
+ * @param relativePath Path to scan for.
+ * @param mode Mode with which to attempt to open files (see fopen modes).
+ * @param handle Handle to data cache, initialized with xdgInitHandle().
+ * @return File pointer if successful else @c NULL. Client must use @c fclose to close file.
+ */
+FILE * xdgConfigOpen(const char* relativePath, const char* mode, xdgHandle *handle);
+
+/** Create path by recursively creating directories.
+ * This utility function is not part of the XDG specification, but
+ * nevertheless useful in context of directory manipulation.
+ * @param path The path to be created.
+ * @param mode The permissions to use for created directories. This parameter
+ * is modified by the process's umask. For details, see mkdir(2)'s mode
+ * parameter.
+ * @return Zero on success, -1 if an error occured (in which case errno will
+ * be set appropriately)
+ */
+int xdgMakePath(const char * path, mode_t mode);
+
+/*@}*/
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /*XDG_BASEDIR_FS_H*/
diff --git a/include/xine/xine_internal.h b/include/xine/xine_internal.h
index 9f2e95aae..b12d20880 100644
--- a/include/xine/xine_internal.h
+++ b/include/xine/xine_internal.h
@@ -73,6 +73,11 @@ typedef struct xine_ticket_s xine_ticket_t;
* the "big" xine struct, holding everything together
*/
+#ifndef XDG_BASEDIR_H
+/* present here for internal convenience only */
+typedef struct { void *reserved; } xdgHandle;
+#endif
+
struct xine_s {
config_values_t *config;
@@ -92,8 +97,8 @@ struct xine_s {
metronom_clock_t *clock;
- /** Handle for libxdg-basedir functions. It's actually an xdgHandle. */
- void * basedir_handle;
+ /** Handle for libxdg-basedir functions. */
+ xdgHandle basedir_handle;
#ifdef XINE_ENGINE_INTERNAL
xine_ticket_t *port_ticket;
diff --git a/m4/video_out.m4 b/m4/video_out.m4
index 6f8bedfba..2a0867b5f 100644
--- a/m4/video_out.m4
+++ b/m4/video_out.m4
@@ -515,4 +515,3 @@ AC_DEFUN([XINE_VIDEO_OUT_PLUGINS], [
AM_CONDITIONAL([ENABLE_VDPAU], test x"$have_vdpau" = x"yes")
])dnl XINE_VIDEO_OUT_PLUGIN
-S
diff --git a/src/audio_dec/xine_lpcm_decoder.c b/src/audio_dec/xine_lpcm_decoder.c
index f5e2aeb6d..ca7802b07 100644
--- a/src/audio_dec/xine_lpcm_decoder.c
+++ b/src/audio_dec/xine_lpcm_decoder.c
@@ -67,22 +67,34 @@ typedef struct lpcm_decoder_s {
uint32_t ao_cap_mode;
int output_open;
- int cpu_be; /**< TRUE, if we're a Big endian CPU */
+ int cpu_be; /* TRUE, if we're a Big endian CPU */
+
+ int64_t pts;
+
+ uint8_t *buf;
+ size_t buffered_bytes;
+ size_t buf_size;
+
} lpcm_decoder_t;
static void lpcm_reset (audio_decoder_t *this_gen) {
- /* lpcm_decoder_t *this = (lpcm_decoder_t *) this_gen; */
+ lpcm_decoder_t *this = (lpcm_decoder_t *) this_gen;
+ free (this->buf);
+ this->buf = NULL;
}
static void lpcm_discontinuity (audio_decoder_t *this_gen) {
+
+ lpcm_reset(this_gen);
}
static void lpcm_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
lpcm_decoder_t *this = (lpcm_decoder_t *) this_gen;
int16_t *sample_buffer=(int16_t *)buf->content;
+ int buf_size = buf->size;
int stream_be;
audio_buffer_t *audio_buffer;
int format_changed = 0;
@@ -98,17 +110,54 @@ static void lpcm_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
unsigned int sample_rate = 0;
unsigned int num_channels;
- num_channels = (buf->decoder_info[2] & 0x7) + 1;
- switch ((buf->decoder_info[2]>>4) & 3) {
- case 0: sample_rate = 48000; break;
- case 1: sample_rate = 96000; break;
- case 2: sample_rate = 44100; break;
- case 3: sample_rate = 32000; break;
- }
- switch ((buf->decoder_info[2]>>6) & 3) {
- case 0: bits_per_sample = 16; break;
- case 1: bits_per_sample = 20; break;
- case 2: bits_per_sample = 24; break;
+ lprintf("lpcm_decoder: config data 0x%x\n", buf->decoder_info[2]);
+
+ /* BluRay PCM header is 4 bytes */
+ if (buf->decoder_info[2] & 0xffffff00) {
+ static const uint8_t channels[16] = {0, 1, 0, 2, 3, 3, 4, 4, 5, 6, 7, 8, 0, 0, 0, 0};
+
+ num_channels = channels[(buf->decoder_info[2] >> (16+4)) & 0x0f];
+ switch ((buf->decoder_info[2] >> (24+6)) & 0x03) {
+ case 1: bits_per_sample = 16; break;
+ case 2: bits_per_sample = 20; break;
+ case 3: bits_per_sample = 24; break;
+ default: bits_per_sample = 0; break;
+ }
+ switch ((buf->decoder_info[2] >> 16) & 0x0f) {
+ case 1: sample_rate = 48000; break;
+ case 4: sample_rate = 96000; break;
+ case 5: sample_rate = 192000; break;
+ default: sample_rate = 0; break;
+ }
+
+ if (!num_channels || !sample_rate || !bits_per_sample)
+ xine_log (this->stream->xine, XINE_LOG_MSG,
+ "lpcm_decoder: unsupported BluRay PCM format: 0x%08x\n", buf->decoder_info[2]);
+
+ if (this->buffered_bytes)
+ xine_log (this->stream->xine, XINE_LOG_MSG, "lpcm_decoder: %zd bytes lost !\n", this->buffered_bytes);
+
+ if (!this->buf) {
+ this->buffered_bytes = 0;
+ this->buf_size = 8128;
+ this->buf = malloc(this->buf_size);
+ }
+
+ } else {
+
+ /* MPEG2/DVD PCM header is one byte */
+ num_channels = (buf->decoder_info[2] & 0x7) + 1;
+ switch ((buf->decoder_info[2]>>4) & 3) {
+ case 0: sample_rate = 48000; break;
+ case 1: sample_rate = 96000; break;
+ case 2: sample_rate = 44100; break;
+ case 3: sample_rate = 32000; break;
+ }
+ switch ((buf->decoder_info[2]>>6) & 3) {
+ case 0: bits_per_sample = 16; break;
+ case 1: bits_per_sample = 20; break;
+ case 2: bits_per_sample = 24; break;
+ }
}
if( this->bits_per_sample != bits_per_sample ||
@@ -119,13 +168,17 @@ static void lpcm_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
this->number_of_channels = num_channels;
this->rate = sample_rate;
format_changed++;
+
+ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
+ "lpcm_decoder: format changed to %d channels, %d bits per sample, %d Hz, %d kbit/s\n",
+ num_channels, bits_per_sample, sample_rate, (num_channels * sample_rate * bits_per_sample)/1024);
}
}
if( buf->decoder_flags & BUF_FLAG_STDHEADER ) {
this->rate=buf->decoder_info[1];
- this->bits_per_sample=buf->decoder_info[2] ;
- this->number_of_channels=buf->decoder_info[3] ;
+ this->bits_per_sample=buf->decoder_info[2];
+ this->number_of_channels=buf->decoder_info[3];
format_changed++;
}
@@ -159,6 +212,30 @@ static void lpcm_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
if (!this->output_open || (buf->decoder_flags & BUF_FLAG_HEADER) )
return;
+ if (buf->pts && !this->pts)
+ this->pts = buf->pts;
+
+ /* data accumulation */
+ if (this->buf) {
+ int frame_end = buf->decoder_flags & BUF_FLAG_FRAME_END;
+ if (this->buffered_bytes || !frame_end) {
+ if (this->buf_size < this->buffered_bytes + buf->size) {
+ this->buf_size *= 2;
+ this->buf = realloc(this->buf, this->buf_size);
+ }
+
+ memcpy(this->buf + this->buffered_bytes, buf->content, buf->size);
+ this->buffered_bytes += buf->size;
+
+ if (!frame_end)
+ return;
+
+ sample_buffer = (int16_t*)this->buf;
+ buf_size = this->buffered_bytes;
+ this->buffered_bytes = 0;
+ }
+ }
+
audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out);
/* Swap LPCM samples into native byte order, if necessary */
@@ -167,14 +244,14 @@ static void lpcm_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
if( this->bits_per_sample == 16 ){
if (stream_be != this->cpu_be)
- swab (sample_buffer, audio_buffer->mem, buf->size);
+ swab (sample_buffer, audio_buffer->mem, buf_size);
else
- memcpy (audio_buffer->mem, sample_buffer, buf->size);
+ memcpy (audio_buffer->mem, sample_buffer, buf_size);
}
else if( this->bits_per_sample == 20 ) {
uint8_t *s = (uint8_t *)sample_buffer;
uint8_t *d = (uint8_t *)audio_buffer->mem;
- int n = buf->size;
+ int n = buf_size;
if (stream_be != this->cpu_be) {
while( n >= 0 ) {
@@ -194,7 +271,7 @@ static void lpcm_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
} else if( this->bits_per_sample == 24 ) {
uint8_t *s = (uint8_t *)sample_buffer;
uint8_t *d = (uint8_t *)audio_buffer->mem;
- int n = buf->size;
+ int n = buf_size;
while (n >= 3) {
if ( stream_be ) {
@@ -221,18 +298,19 @@ static void lpcm_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
n -= 3;
}
- if ( (d - (uint8_t*)audio_buffer->mem)/2*3 < buf->size )
- xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "lpcm_decoder: lost %i bytes\n", (int)(buf->size - (d - (uint8_t*)audio_buffer->mem))/2*3);
+ if ( (d - (uint8_t*)audio_buffer->mem)/2*3 < buf_size )
+ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "lpcm_decoder: lost %i bytes\n", (int)(buf_size - (d - (uint8_t*)audio_buffer->mem))/2*3);
} else {
- memcpy (audio_buffer->mem, sample_buffer, buf->size);
+ memcpy (audio_buffer->mem, sample_buffer, buf_size);
}
- audio_buffer->vpts = buf->pts;
- audio_buffer->num_frames = (((buf->size*8)/this->number_of_channels)/this->bits_per_sample);
+ audio_buffer->vpts = this->pts;
+ audio_buffer->num_frames = (((buf_size*8)/this->number_of_channels)/this->bits_per_sample);
this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream);
+ this->pts = 0;
}
static void lpcm_dispose (audio_decoder_t *this_gen) {
@@ -242,6 +320,8 @@ static void lpcm_dispose (audio_decoder_t *this_gen) {
this->stream->audio_out->close (this->stream->audio_out, this->stream);
this->output_open = 0;
+ free (this->buf);
+
free (this_gen);
}
diff --git a/src/demuxers/demux_ts.c b/src/demuxers/demux_ts.c
index 3e15b2907..9053db60d 100644
--- a/src/demuxers/demux_ts.c
+++ b/src/demuxers/demux_ts.c
@@ -807,6 +807,18 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m,
m->type |= BUF_AUDIO_DTS;
return 1;
+ } else if (m->descriptor_tag == HDMV_AUDIO_80_PCM) {
+
+ m->content = p + 4;
+ m->size = packet_len - 4;
+ m->type |= BUF_AUDIO_LPCM_BE;
+
+ m->buf->decoder_flags |= BUF_FLAG_SPECIAL;
+ m->buf->decoder_info[1] = BUF_SPECIAL_LPCM_CONFIG;
+ m->buf->decoder_info[2] = (p[3]<<24) | (p[2]<<16) | (p[1]<<8) | p[0];
+
+ return 1;
+
} else if (m->descriptor_tag == ISO_13818_PES_PRIVATE
&& p[0] == 0x20 && p[1] == 0x00) {
/* DVBSUB */
@@ -1525,7 +1537,10 @@ printf("Program Number is %i, looking for %i\n",program_number,this->program_num
demux_ts_get_reg_desc(this, &format_identifier,
stream + 5, stream_info_length);
/* If no format identifier, assume A52 */
- if ((format_identifier == 0x41432d33) || (format_identifier == 0)) {
+ if (( format_identifier == 0x41432d33) ||
+ ( format_identifier == 0) ||
+ ((format_identifier == 0x48444d56 || this->hdmv>0) && stream[0] == HDMV_AUDIO_80_PCM) /* BluRay PCM */) {
+
demux_ts_pes_new(this, this->media_num, pid, this->audio_fifo, stream[0]);
this->audio_tracks[this->audio_tracks_count].pid = pid;
this->audio_tracks[this->audio_tracks_count].media_index = this->media_num;
diff --git a/src/demuxers/demux_tta.c b/src/demuxers/demux_tta.c
index 8f8f954d5..ada6cab30 100644
--- a/src/demuxers/demux_tta.c
+++ b/src/demuxers/demux_tta.c
@@ -65,7 +65,7 @@ typedef struct {
uint16_t channels;
uint16_t bits_per_sample;
uint32_t samplerate;
- uint32_t data_length;
+ uint32_t data_length; /* Number of samples */
uint32_t crc32;
} XINE_PACKED tta;
uint8_t buffer[22]; /* This is the size of the header */
@@ -114,7 +114,7 @@ static int demux_tta_send_chunk(demux_plugin_t *this_gen) {
demux_tta_t *this = (demux_tta_t *) this_gen;
uint32_t bytes_to_read;
- if ( this->currentframe > this->totalframes ) {
+ if ( this->currentframe >= this->totalframes ) {
this->status = DEMUX_FINISHED;
return this->status;
}
@@ -129,7 +129,7 @@ static int demux_tta_send_chunk(demux_plugin_t *this_gen) {
buf = this->audio_fifo->buffer_pool_alloc(this->audio_fifo);
buf->type = BUF_AUDIO_TTA;
buf->pts = 0;
- buf->extra_info->total_time = this->totalframes;
+ buf->extra_info->total_time = (int)(le2me_32(this->header.tta.data_length) * 1000.0 / le2me_32(this->header.tta.samplerate)); /* milliseconds */
buf->decoder_flags = 0;
/* Set normalised position */
@@ -163,6 +163,12 @@ static int demux_tta_send_chunk(demux_plugin_t *this_gen) {
static void demux_tta_send_headers(demux_plugin_t *this_gen) {
demux_tta_t *this = (demux_tta_t *) this_gen;
buf_element_t *buf;
+ xine_waveformatex wave;
+ uint32_t total_size = sizeof(xine_waveformatex) + sizeof(this->header) +
+ sizeof(uint32_t)*this->totalframes;
+ unsigned char *header;
+
+ header = malloc(total_size);
this->audio_fifo = this->stream->audio_fifo;
@@ -180,27 +186,43 @@ static void demux_tta_send_headers(demux_plugin_t *this_gen) {
/* send start buffers */
_x_demux_control_start(this->stream);
- /* send init info to decoders */
- if (this->audio_fifo) {
- xine_waveformatex wave;
-
- buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
- buf->type = BUF_AUDIO_TTA;
- buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END;
- buf->decoder_info[0] = 0;
- buf->decoder_info[1] = le2me_32(this->header.tta.samplerate);
- buf->decoder_info[2] = le2me_16(this->header.tta.bits_per_sample);
- buf->decoder_info[3] = le2me_16(this->header.tta.channels);
+ /* create header */
+ wave.cbSize = total_size - sizeof(xine_waveformatex);
- buf->size = sizeof(xine_waveformatex) + sizeof(this->header) + sizeof(uint32_t)*this->totalframes;
- memcpy(buf->content+sizeof(xine_waveformatex), this->header.buffer, sizeof(this->header));
- memcpy(buf->content+sizeof(xine_waveformatex)+sizeof(this->header), this->seektable, sizeof(uint32_t)*this->totalframes);
+ memcpy(header, &wave, sizeof(wave));
+ memcpy(header+sizeof(xine_waveformatex), this->header.buffer, sizeof(this->header));
+ memcpy(header+sizeof(xine_waveformatex)+sizeof(this->header), this->seektable, sizeof(uint32_t)*this->totalframes);
- wave.cbSize = buf->size - sizeof(xine_waveformatex);
- memcpy(buf->content, &wave, sizeof(wave));
-
- this->audio_fifo->put (this->audio_fifo, buf);
+ /* send init info to decoders */
+ if (this->audio_fifo) {
+ uint32_t bytes_left = total_size;
+
+ /* We are sending the seektable as well, and this may be larger than
+ buf->max_size */
+ while (bytes_left) {
+ buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
+ buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER;
+ buf->type = BUF_AUDIO_TTA;
+
+ /* Copy min(bytes_left, max_size) bytes */
+ buf->size = bytes_left < buf->max_size ? bytes_left : buf->max_size;
+ memcpy(buf->content, header+(total_size-bytes_left), buf->size);
+
+ bytes_left -= buf->size;
+
+ /* The decoder information only needs the decoder information on the last
+ buffer element. */
+ if (!bytes_left) {
+ buf->decoder_flags |= BUF_FLAG_FRAME_END;
+ buf->decoder_info[0] = 0;
+ buf->decoder_info[1] = le2me_32(this->header.tta.samplerate);
+ buf->decoder_info[2] = le2me_16(this->header.tta.bits_per_sample);
+ buf->decoder_info[3] = le2me_16(this->header.tta.channels);
+ }
+ this->audio_fifo->put (this->audio_fifo, buf);
+ }
}
+ free(header);
}
static int demux_tta_seek (demux_plugin_t *this_gen,
@@ -258,7 +280,7 @@ static int demux_tta_get_status (demux_plugin_t *this_gen) {
static int demux_tta_get_stream_length (demux_plugin_t *this_gen) {
demux_tta_t *this = (demux_tta_t *) this_gen;
- return (int)(FRAME_TIME * this->totalframes * 1000);
+ return le2me_32(this->header.tta.data_length) * 1000.0 / le2me_32(this->header.tta.samplerate); /* milliseconds */
}
static uint32_t demux_tta_get_capabilities(demux_plugin_t *this_gen) {
diff --git a/src/input/input_cdda.c b/src/input/input_cdda.c
index 0b7f854e2..31bc51bc2 100644
--- a/src/input/input_cdda.c
+++ b/src/input/input_cdda.c
@@ -1483,7 +1483,7 @@ static void _cdda_parse_cddb_info (cdda_input_plugin_t *this, char *buffer, char
static int _cdda_load_cached_cddb_infos(cdda_input_plugin_t *this) {
DIR *dir;
- const char *const xdg_cache_home = xdgCacheHome(this->stream->xine->basedir_handle);
+ const char *const xdg_cache_home = xdgCacheHome(&this->stream->xine->basedir_handle);
if(this == NULL)
return 0;
@@ -1545,7 +1545,7 @@ static void _cdda_save_cached_cddb_infos(cdda_input_plugin_t *this, char *fileco
FILE *fd;
char *cfile;
- const char *const xdg_cache_home = xdgCacheHome(this->stream->xine->basedir_handle);
+ const char *const xdg_cache_home = xdgCacheHome(&this->stream->xine->basedir_handle);
if((this == NULL) || (filecontent == NULL))
return;
diff --git a/src/input/input_dvb.c b/src/input/input_dvb.c
index 5b8afef92..a045276d5 100644
--- a/src/input/input_dvb.c
+++ b/src/input/input_dvb.c
@@ -887,7 +887,7 @@ static channel_t *load_channels(xine_t *xine, xine_stream_t *stream, int *num_ch
int num_alloc = 0;
struct stat st;
- snprintf(filename, BUFSIZE, "%s/"PACKAGE"/channels.conf", xdgConfigHome(xine->basedir_handle));
+ snprintf(filename, BUFSIZE, "%s/"PACKAGE"/channels.conf", xdgConfigHome(&xine->basedir_handle));
f = fopen(filename, "r");
if (!f) {
diff --git a/src/libw32dll/wine/registry.c b/src/libw32dll/wine/registry.c
index 20c21888d..b12974416 100644
--- a/src/libw32dll/wine/registry.c
+++ b/src/libw32dll/wine/registry.c
@@ -303,8 +303,9 @@ static struct reg_value* insert_reg_value(int handle, const char* name, int type
static void init_registry(void)
{
- xdgHandle tmph = xdgAllocHandle();
- const char *const xdg_cache_home = xdgCacheHome(tmph);
+ xdgHandle tmph;
+ xdgInitHandle(&tmph);
+ const char *const xdg_cache_home = xdgCacheHome(&tmph);
TRACE("Initializing registry\n");
// can't be free-ed - it's static and probably thread
@@ -318,7 +319,7 @@ static void init_registry(void)
insert_handle(HKEY_LOCAL_MACHINE, "HKLM");
insert_handle(HKEY_CURRENT_USER, "HKCU");
- xdgFreeHandle(tmph);
+ xdgWipeHandle(&tmph);
}
#if 0
diff --git a/src/xine-engine/load_plugins.c b/src/xine-engine/load_plugins.c
index bbb131c86..f5db64bc0 100644
--- a/src/xine-engine/load_plugins.c
+++ b/src/xine-engine/load_plugins.c
@@ -1149,7 +1149,7 @@ static void load_plugin_list(xine_t *this, FILE *fp, xine_sarray_t *plugins) {
* http://standards.freedesktop.org/basedir-spec/latest/index.html
*/
static char *catalog_filename(xine_t *this, int createdir) {
- const char *const xdg_cache_home = xdgCacheHome(this->basedir_handle);
+ const char *const xdg_cache_home = xdgCacheHome(&this->basedir_handle);
char *cachefile = NULL;
cachefile = xine_xmalloc( strlen(xdg_cache_home) + sizeof("/"PACKAGE"/plugins.cache") );
diff --git a/src/xine-engine/osd.c b/src/xine-engine/osd.c
index 73fe76a0a..a2d2806ec 100644
--- a/src/xine-engine/osd.c
+++ b/src/xine-engine/osd.c
@@ -1030,7 +1030,7 @@ static int osd_lookup_fontconfig( osd_object_t *osd, const char *const fontname,
* http://standards.freedesktop.org/basedir-spec/latest/index.html
*/
static int osd_lookup_xdg( osd_object_t *osd, const char *const fontname ) {
- const char *const *data_dirs = xdgSearchableDataDirectories(osd->renderer->stream->xine->basedir_handle);
+ const char *const *data_dirs = xdgSearchableDataDirectories(&osd->renderer->stream->xine->basedir_handle);
/* try load font from current directory or from an absolute path */
if ( FT_New_Face(osd->ft2->library, fontname, 0, &osd->ft2->face) == FT_Err_Ok )
@@ -1815,7 +1815,7 @@ osd_renderer_t *_x_osd_renderer_init( xine_stream_t *stream ) {
* load available fonts
*/
{
- const char *const *data_dirs = xdgSearchableDataDirectories(stream->xine->basedir_handle);
+ const char *const *data_dirs = xdgSearchableDataDirectories(&stream->xine->basedir_handle);
if ( data_dirs )
while( (*data_dirs) && *(*data_dirs) ) {
/* sizeof("") takes care of the final NUL byte */
diff --git a/src/xine-engine/xine.c b/src/xine-engine/xine.c
index 8162598aa..5689337da 100644
--- a/src/xine-engine/xine.c
+++ b/src/xine-engine/xine.c
@@ -1608,7 +1608,7 @@ void xine_exit (xine_t *this) {
WSACleanup();
#endif
- xdgFreeHandle(this->basedir_handle);
+ xdgWipeHandle(&this->basedir_handle);
free (this);
}
@@ -1737,7 +1737,7 @@ void xine_init (xine_t *this) {
"extension", NULL};
/* First of all, initialise libxdg-basedir as it's used by plugins. */
- this->basedir_handle = xdgAllocHandle();
+ xdgInitHandle(&this->basedir_handle);
/*
* locks