summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--stream/stream.h1
-rw-r--r--stream/stream_dvd.c42
-rw-r--r--stream/stream_dvd_common.c29
-rw-r--r--stream/stream_dvd_common.h4
-rw-r--r--stream/stream_file.c11
5 files changed, 66 insertions, 21 deletions
diff --git a/stream/stream.h b/stream/stream.h
index 0f028e330d..28f9936fce 100644
--- a/stream/stream.h
+++ b/stream/stream.h
@@ -266,6 +266,7 @@ void mp_cancel_reset(struct mp_cancel *c);
// stream_file.c
char *mp_file_url_to_filename(void *talloc_ctx, bstr url);
+char *mp_file_get_path(void *talloc_ctx, bstr url);
void stream_print_proto_list(struct mp_log *log);
diff --git a/stream/stream_dvd.c b/stream/stream_dvd.c
index 857d144a65..eb055abc13 100644
--- a/stream/stream_dvd.c
+++ b/stream/stream_dvd.c
@@ -33,6 +33,8 @@
#include <dvdread/ifo_read.h>
#include <dvdread/nav_read.h>
+#include "osdep/io.h"
+
#include "config.h"
#include "talloc.h"
#include "common/common.h"
@@ -46,6 +48,7 @@
#include "stream.h"
#include "options/m_option.h"
#include "options/options.h"
+#include "options/path.h"
#include "stream_dvd_common.h"
@@ -913,38 +916,37 @@ fail:
return STREAM_UNSUPPORTED;
}
-static int ifo_stream_open (stream_t *stream)
+static int ifo_stream_open(stream_t *stream)
{
- char* filename;
dvd_priv_t *priv = talloc_ptrtype(stream, priv);
stream->priv = priv;
*priv = stream_priv_dflts;
- // "file://" prefix -> decode URL-style escapes
- if (strlen(stream->url) > strlen(stream->path))
- mp_url_unescape_inplace(stream->path);
+ char *path = mp_file_get_path(priv, bstr0(stream->url));
+ if (!path)
+ goto unsupported;
- int len = strlen(stream->path);
- if (len < 4 || strcasecmp (stream->path + len - 4, ".ifo"))
- return STREAM_UNSUPPORTED;
+ if (!dvd_probe(path, ".ifo", "DVDVIDEO-VTS"))
+ goto unsupported;
- MP_INFO(stream, ".IFO detected. Redirecting to dvd://\n");
+ char *base = mp_basename(path);
- filename = strdup(basename(stream->path));
+ // Only accept individual titles - use dvdnav for video_ts.ifo
+ if (strncasecmp(base, "vts_", 4))
+ goto unsupported;
- talloc_free(priv->cfg_device);
- priv->cfg_device = talloc_strdup(NULL, dirname(stream->path));
- if(!strncasecmp(filename,"vts_",4))
- {
- if(sscanf(filename+3, "_%02d_", &priv->cfg_title)!=0)
- priv->cfg_title = 0;
- }else
- priv->cfg_title = 0;
+ if (sscanf(base + 3, "_%02d_", &priv->cfg_title) != 1)
+ goto unsupported;
- free(filename);
- stream->url=talloc_strdup(stream, "dvdread://");
+ priv->cfg_device = bstrto0(priv, mp_dirname(path));
+ MP_INFO(stream, ".IFO detected. Redirecting to dvdread://\n");
return open_s(stream);
+
+unsupported:
+ talloc_free(priv);
+ stream->priv = NULL;
+ return STREAM_UNSUPPORTED;
}
const stream_info_t stream_info_dvd = {
diff --git a/stream/stream_dvd_common.c b/stream/stream_dvd_common.c
index a9a6895384..99e9067621 100644
--- a/stream/stream_dvd_common.c
+++ b/stream/stream_dvd_common.c
@@ -21,6 +21,9 @@
#include <unistd.h>
#include <stdio.h>
#include <string.h>
+#include <strings.h>
+#include <assert.h>
+
#include <libavutil/intreadwrite.h>
#include "config.h"
@@ -42,6 +45,7 @@
#include "osdep/io.h"
#include "common/msg.h"
+#include "misc/bstr.h"
#include "stream_dvd_common.h"
const char * const dvd_audio_stream_types[8] = { "ac3","unknown","mpeg1","mpeg2ext","lpcm","unknown","dts" };
@@ -134,3 +138,28 @@ int mp_dvdtimetomsec(dvd_time_t *dt)
msec += (((dt->frame_u & 0x30) >> 3) * 5 + (dt->frame_u & 0x0f)) * 100000 / framerate;
return msec;
}
+
+// Check if this is likely to be an .ifo or similar file.
+int dvd_probe(const char *path, const char *ext, const char *sig)
+{
+ if (!bstr_case_endswith(bstr0(path), bstr0(ext)))
+ return false;
+
+ FILE *temp = fopen(path, "rb");
+ if (!temp)
+ return false;
+
+ bool r = false;
+
+ char data[50];
+
+ assert(strlen(sig) <= sizeof(data));
+
+ if (fread(data, 50, 1, temp) == 1) {
+ if (memcmp(data, sig, strlen(sig)) == 0)
+ r = true;
+ }
+
+ fclose(temp);
+ return r;
+}
diff --git a/stream/stream_dvd_common.h b/stream/stream_dvd_common.h
index a2b05e8b77..96dfbb3cb3 100644
--- a/stream/stream_dvd_common.h
+++ b/stream/stream_dvd_common.h
@@ -20,7 +20,7 @@
#define MPLAYER_STREAM_DVD_COMMON_H
#include <inttypes.h>
-#include <dvdread/ifo_types.h>
+#include <stdbool.h>
#include "stream.h"
extern const char * const dvd_audio_stream_channels[6];
@@ -29,4 +29,6 @@ extern const char * const dvd_audio_stream_types[8];
void dvd_set_speed(stream_t *stream, char *device, unsigned speed);
int mp_dvdtimetomsec(dvd_time_t *dt);
+int dvd_probe(const char *path, const char *ext, const char *sig);
+
#endif /* MPLAYER_STREAM_DVD_COMMON_H */
diff --git a/stream/stream_file.c b/stream/stream_file.c
index 6a10114832..eef0dcc5cc 100644
--- a/stream/stream_file.c
+++ b/stream/stream_file.c
@@ -126,6 +126,17 @@ char *mp_file_url_to_filename(void *talloc_ctx, bstr url)
return filename;
}
+// Return talloc_strdup's filesystem path if local, otherwise NULL.
+// Unlike mp_file_url_to_filename(), doesn't return NULL if already local.
+char *mp_file_get_path(void *talloc_ctx, bstr url)
+{
+ if (mp_split_proto(url, &(bstr){0}).len) {
+ return mp_file_url_to_filename(talloc_ctx, url);
+ } else {
+ return bstrto0(talloc_ctx, url);
+ }
+}
+
#if HAVE_BSD_FSTATFS
static bool check_stream_network(stream_t *stream)
{