[vlc-commits] cdda: handle GNOME cdda: URLs (fixes #9654)
Rémi Denis-Courmont
git at videolan.org
Sat Dec 31 13:45:58 CET 2016
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sat Dec 31 14:43:24 2016 +0200| [d10557df3b558edde19996882c0ae78548d8ca6b] | committer: Rémi Denis-Courmont
cdda: handle GNOME cdda: URLs (fixes #9654)
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=d10557df3b558edde19996882c0ae78548d8ca6b
---
modules/access/cdda.c | 125 +++++++++++++++++++++++++++++++++-----------------
1 file changed, 82 insertions(+), 43 deletions(-)
diff --git a/modules/access/cdda.c b/modules/access/cdda.c
index 58d554b..4253991 100644
--- a/modules/access/cdda.c
+++ b/modules/access/cdda.c
@@ -48,6 +48,7 @@
#include <vlc_access.h>
#include <vlc_meta.h>
#include <vlc_charset.h> /* ToLocaleDup */
+#include <vlc_url.h>
#include "vcd/cdrom.h" /* For CDDA_DATA_SIZE */
@@ -56,28 +57,57 @@
#include <errno.h>
#endif
-static vcddev_t *DiscOpen(vlc_object_t *obj, const char *path)
+static vcddev_t *DiscOpen(vlc_object_t *obj, const char *location,
+ const char *path, unsigned *restrict trackp)
{
- char *filename;
+ char *devpath;
- if (path == NULL)
- filename = var_InheritString(obj, "cd-audio");
+ *trackp = var_InheritInteger(obj, "cdda-track");
+
+ if (path != NULL)
+ devpath = ToLocaleDup(path);
+ else if (location[0] != '\0')
+ {
+#if (DIR_SEP_CHAR == '/')
+ char *dec = vlc_uri_decode_duplicate(location);
+ if (dec == NULL)
+ return NULL;
+
+ /* GNOME CDDA syntax */
+ const char *sl = strrchr(dec, '/');
+ if (sl != NULL)
+ {
+ if (sscanf(sl, "/Track %2u", trackp) == 1)
+ dec[sl - dec] = '\0';
+ else
+ *trackp = 0;
+ }
+
+ if (unlikely(asprintf(&devpath, "/dev/%s", dec) == -1))
+ devpath = NULL;
+ free(dec);
+#else
+ (void) location;
+ return NULL;
+#endif
+ }
else
- filename = ToLocaleDup(path);
- if (filename == NULL)
+ devpath = var_InheritString(obj, "cd-audio");
+
+ if (devpath == NULL)
return NULL;
#if defined (_WIN32) || defined (__OS2__)
/* Trim backslash after drive letter */
- if (filename[0] != '\0' && !strcmp(&filename[1], ":\\"))
- filename[2] = '\0';
+ if (devpath[0] != '\0' && !strcmp(&devpath[1], ":" DIR_SEP))
+ devpath[2] = '\0';
#endif
/* Open CDDA */
- vcddev_t *dev = ioctl_Open(obj, filename);
+ vcddev_t *dev = ioctl_Open(obj, devpath);
if (dev == NULL)
- msg_Warn(obj, "cannot open disc %s", filename);
- free(filename);
+ msg_Warn(obj, "cannot open disc %s", devpath);
+ free(devpath);
return dev;
}
@@ -185,24 +215,28 @@ static int DemuxControl(demux_t *demux, int query, va_list args)
static int DemuxOpen(vlc_object_t *obj)
{
demux_t *demux = (demux_t *)obj;
+ unsigned track;
- unsigned track = var_InheritInteger(obj, "cdda-track");
- if (track == 0)
- return VLC_EGENERIC; /* Whole disc -> use access plugin */
+ vcddev_t *dev = DiscOpen(obj, demux->psz_location, demux->psz_file,
+ &track);
+ if (dev == NULL)
+ return VLC_EGENERIC;
+
+ if (track == 0 /* Whole disc -> use access plugin */)
+ {
+ ioctl_Close(obj, dev);
+ return VLC_EGENERIC;
+ }
demux_sys_t *sys = malloc(sizeof (*sys));
if (unlikely(sys == NULL))
- return VLC_ENOMEM;
-
- /* Open CDDA */
- sys->vcddev = DiscOpen(obj, demux->psz_file);
- if (sys->vcddev == NULL)
{
- free(sys);
- return VLC_EGENERIC;
+ ioctl_Close(obj, dev);
+ return VLC_ENOMEM;
}
- demux->p_sys = sys;
+ demux->p_sys = sys;
+ sys->vcddev = dev;
sys->start = var_InheritInteger(obj, "cdda-first-sector");
sys->length = var_InheritInteger(obj, "cdda-last-sector") - sys->start;
@@ -210,7 +244,7 @@ static int DemuxOpen(vlc_object_t *obj)
if (sys->start == (unsigned)-1 || sys->length == (unsigned)-1)
{
int *sectors = NULL; /* Track sectors */
- unsigned titles = ioctl_GetTracksMap(obj, sys->vcddev, §ors);
+ unsigned titles = ioctl_GetTracksMap(obj, dev, §ors);
if (track > titles)
{
@@ -240,7 +274,7 @@ static int DemuxOpen(vlc_object_t *obj)
return VLC_SUCCESS;
error:
- ioctl_Close(obj, sys->vcddev);
+ ioctl_Close(obj, dev);
free(sys);
return VLC_EGENERIC;
}
@@ -580,26 +614,31 @@ static int AccessControl(access_t *access, int query, va_list args)
static int AccessOpen(vlc_object_t *obj)
{
- access_t *p_access = (access_t *)obj;
+ access_t *access = (access_t *)obj;
+ unsigned track;
+
+ vcddev_t *dev = DiscOpen(obj, access->psz_location, access->psz_filepath,
+ &track);
+ if (dev == NULL)
+ return VLC_EGENERIC;
- /* Do we play a single track ? */
- if (var_InheritInteger(obj, "cdda-track") != 0)
+ if (track != 0 /* Only whole discs here */)
+ {
+ ioctl_Close(obj, dev);
return VLC_EGENERIC;
+ }
access_sys_t *sys = malloc(sizeof (*sys));
if (unlikely(sys == NULL))
- return VLC_ENOMEM;
-
- /* Open CDDA */
- sys->vcddev = DiscOpen(obj, p_access->psz_filepath);
- if (sys->vcddev == NULL)
{
- free(sys);
- return VLC_EGENERIC;
+ ioctl_Close(obj, dev);
+ return VLC_ENOMEM;
}
+
+ sys->vcddev = dev;
sys->p_sectors = NULL;
- sys->titles = ioctl_GetTracksMap(obj, sys->vcddev, &sys->p_sectors);
+ sys->titles = ioctl_GetTracksMap(obj, dev, &sys->p_sectors);
if (sys->titles < 0)
{
msg_Err(obj, "cannot count tracks");
@@ -622,24 +661,24 @@ static int AccessOpen(vlc_object_t *obj)
msg_Dbg(obj, "CDDB failure");
#endif
- if (ioctl_GetCdText(obj, sys->vcddev, &sys->cdtextv, &sys->cdtextc))
+ if (ioctl_GetCdText(obj, dev, &sys->cdtextv, &sys->cdtextc))
{
msg_Dbg(obj, "CD-TEXT information missing");
sys->cdtextv = NULL;
sys->cdtextc = 0;
}
- p_access->p_sys = sys;
- p_access->pf_read = NULL;
- p_access->pf_block = NULL;
- p_access->pf_readdir = ReadDir;
- p_access->pf_seek = NULL;
- p_access->pf_control = AccessControl;
+ access->p_sys = sys;
+ access->pf_read = NULL;
+ access->pf_block = NULL;
+ access->pf_readdir = ReadDir;
+ access->pf_seek = NULL;
+ access->pf_control = AccessControl;
return VLC_SUCCESS;
error:
free(sys->p_sectors);
- ioctl_Close(obj, sys->vcddev);
+ ioctl_Close(obj, dev);
free(sys);
return VLC_EGENERIC;
}
More information about the vlc-commits
mailing list