aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--DOCS/man/en/mpv.rst2
-rw-r--r--core/m_option.c222
-rw-r--r--core/m_option.h7
-rw-r--r--stream/dvbin.h4
-rw-r--r--stream/stream.c150
-rw-r--r--stream/stream.h15
-rw-r--r--stream/stream_avdevice.c2
-rw-r--r--stream/stream_bluray.c46
-rw-r--r--stream/stream_cdda.c45
-rw-r--r--stream/stream_dvb.c84
-rw-r--r--stream/stream_dvd.c77
-rw-r--r--stream/stream_dvd.h3
-rw-r--r--stream/stream_file.c45
-rw-r--r--stream/stream_lavf.c9
-rw-r--r--stream/stream_memory.c2
-rw-r--r--stream/stream_mf.c4
-rw-r--r--stream/stream_null.c4
-rw-r--r--stream/stream_pvr.c4
-rw-r--r--stream/stream_radio.c33
-rw-r--r--stream/stream_smb.c27
-rw-r--r--stream/stream_tv.c32
-rw-r--r--stream/stream_vcd.c56
22 files changed, 281 insertions, 592 deletions
diff --git a/DOCS/man/en/mpv.rst b/DOCS/man/en/mpv.rst
index ce4fd29ca5..af905539f0 100644
--- a/DOCS/man/en/mpv.rst
+++ b/DOCS/man/en/mpv.rst
@@ -27,7 +27,7 @@ SYNOPSIS
| **mpv** [options] {group of files and options}
| **mpv** [bd]://[title][/device] [options]
| **mpv** dvd://[title|[start\_title]-end\_title][/device] [options]
-| **mpv** \vcd://track[/device]
+| **mpv** \vcd://[/device]
| **mpv** \tv://[channel][/input_id] [options]
| **mpv** radio://[channel|frequency][/capture] [options]
| **mpv** \pvr:// [options]
diff --git a/core/m_option.c b/core/m_option.c
index abcb13c038..33da609fdd 100644
--- a/core/m_option.c
+++ b/core/m_option.c
@@ -2407,225 +2407,3 @@ const m_option_type_t m_option_type_obj_settings_list = {
.copy = copy_obj_settings_list,
.free = free_obj_settings_list,
};
-
-
-/* Replace escape sequences in an URL (or a part of an URL) */
-/* works like strcpy(), but without return argument,
- except that outbuf == inbuf is allowed */
-static void url_unescape_string(char *outbuf, const char *inbuf)
-{
- unsigned char c,c1,c2;
- int i,len=strlen(inbuf);
- for (i=0;i<len;i++) {
- c = inbuf[i];
- if (c == '%' && i<len-2) { //must have 2 more chars
- c1 = toupper(inbuf[i+1]); // we need uppercase characters
- c2 = toupper(inbuf[i+2]);
- if (((c1>='0' && c1<='9') || (c1>='A' && c1<='F')) &&
- ((c2>='0' && c2<='9') || (c2>='A' && c2<='F')) )
- {
- if (c1>='0' && c1<='9')
- c1-='0';
- else
- c1-='A'-10;
- if (c2>='0' && c2<='9')
- c2-='0';
- else
- c2-='A'-10;
- c = (c1<<4) + c2;
- i=i+2; //only skip next 2 chars if valid esc
- }
- }
- *outbuf++ = c;
- }
- *outbuf++='\0'; //add nullterm to string
-}
-
-static int parse_custom_url(const m_option_t *opt, struct bstr name,
- struct bstr url, void *dst)
-{
- int r;
- m_struct_t *desc = opt->priv;
-
- if (!desc) {
- mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %.*s: Custom URL needs "
- "a pointer to a m_struct_t in the priv field.\n", BSTR_P(name));
- return M_OPT_PARSER_ERR;
- }
-
- // extract the protocol
- int idx = bstr_find0(url, "://");
- if (idx < 0) {
- // Filename only
- if (m_option_list_find(desc->fields, "filename")) {
- m_struct_set(desc, dst, "filename", url);
- return 1;
- }
- mp_msg(MSGT_CFGPARSER, MSGL_ERR,
- "Option %.*s: URL doesn't have a valid protocol!\n",
- BSTR_P(name));
- return M_OPT_INVALID;
- }
- struct bstr ptr1 = bstr_cut(url, idx + 3);
- if (m_option_list_find(desc->fields, "string")) {
- if (ptr1.len > 0) {
- m_struct_set(desc, dst, "string", ptr1);
- return 1;
- }
- }
- if (dst && m_option_list_find(desc->fields, "protocol")) {
- r = m_struct_set(desc, dst, "protocol", bstr_splice(url, 0, idx));
- if (r < 0) {
- mp_msg(MSGT_CFGPARSER, MSGL_ERR,
- "Option %.*s: Error while setting protocol.\n",
- BSTR_P(name));
- return r;
- }
- }
-
- // check if a username:password is given
- idx = bstrchr(ptr1, '/');
- if (idx < 0)
- idx = ptr1.len;
- struct bstr hostpart = bstr_splice(ptr1, 0, idx);
- struct bstr path = bstr_cut(ptr1, idx);
- idx = bstrchr(hostpart, '@');
- if (idx >= 0) {
- struct bstr userpass = bstr_splice(hostpart, 0, idx);
- hostpart = bstr_cut(hostpart, idx + 1);
- // We got something, at least a username...
- if (!m_option_list_find(desc->fields, "username")) {
- mp_msg(MSGT_CFGPARSER, MSGL_WARN,
- "Option %.*s: This URL doesn't have a username part.\n",
- BSTR_P(name));
- // skip
- } else {
- idx = bstrchr(userpass, ':');
- if (idx >= 0) {
- // We also have a password
- if (!m_option_list_find(desc->fields, "password")) {
- mp_msg(MSGT_CFGPARSER, MSGL_WARN,
- "Option %.*s: This URL doesn't have a password part.\n",
- BSTR_P(name));
- // skip
- } else { // Username and password
- if (dst) {
- r = m_struct_set(desc, dst, "username",
- bstr_splice(userpass, 0, idx));
- if (r < 0) {
- mp_msg(MSGT_CFGPARSER, MSGL_ERR,
- "Option %.*s: Error while setting username.\n",
- BSTR_P(name));
- return r;
- }
- r = m_struct_set(desc, dst, "password",
- bstr_splice(userpass, idx+1,
- userpass.len));
- if (r < 0) {
- mp_msg(MSGT_CFGPARSER, MSGL_ERR,
- "Option %.*s: Error while setting password.\n",
- BSTR_P(name));
- return r;
- }
- }
- }
- } else { // User name only
- r = m_struct_set(desc, dst, "username", userpass);
- if (r < 0) {
- mp_msg(MSGT_CFGPARSER, MSGL_ERR,
- "Option %.*s: Error while setting username.\n",
- BSTR_P(name));
- return r;
- }
- }
- }
- }
-
- // Before looking for a port number check if we have an IPv6 type
- // numeric address.
- // In an IPv6 URL the numeric address should be inside square braces.
- int idx1 = bstrchr(hostpart, '[');
- int idx2 = bstrchr(hostpart, ']');
- struct bstr portstr = hostpart;
- bool v6addr = false;
- if (idx1 >= 0 && idx2 >= 0 && idx1 < idx2) {
- // we have an IPv6 numeric address
- portstr = bstr_cut(hostpart, idx2);
- hostpart = bstr_splice(hostpart, idx1 + 1, idx2);
- v6addr = true;
- }
-
- idx = bstrchr(portstr, ':');
- if (idx >= 0) {
- if (!v6addr)
- hostpart = bstr_splice(hostpart, 0, idx);
- // We have an URL beginning like http://www.hostname.com:1212
- // Get the port number
- if (!m_option_list_find(desc->fields, "port")) {
- mp_msg(MSGT_CFGPARSER, MSGL_WARN,
- "Option %.*s: This URL doesn't have a port part.\n",
- BSTR_P(name));
- // skip
- } else {
- if (dst) {
- int p = bstrtoll(bstr_cut(portstr, idx + 1), NULL, 0);
- char tmp[100];
- snprintf(tmp, 99, "%d", p);
- r = m_struct_set(desc, dst, "port", bstr0(tmp));
- if (r < 0) {
- mp_msg(MSGT_CFGPARSER, MSGL_ERR,
- "Option %.*s: Error while setting port.\n",
- BSTR_P(name));
- return r;
- }
- }
- }
- }
- // Get the hostname
- if (hostpart.len > 0) {
- if (!m_option_list_find(desc->fields, "hostname")) {
- mp_msg(MSGT_CFGPARSER, MSGL_WARN,
- "Option %.*s: This URL doesn't have a hostname part.\n",
- BSTR_P(name));
- // skip
- } else {
- r = m_struct_set(desc, dst, "hostname", hostpart);
- if (r < 0) {
- mp_msg(MSGT_CFGPARSER, MSGL_ERR,
- "Option %.*s: Error while setting hostname.\n",
- BSTR_P(name));
- return r;
- }
- }
- }
- // Look if a path is given
- if (path.len > 1) { // not just "/"
- // copy the path/filename in the URL container
- if (!m_option_list_find(desc->fields, "filename")) {
- mp_msg(MSGT_CFGPARSER, MSGL_WARN,
- "Option %.*s: This URL doesn't have a filename part.\n",
- BSTR_P(name));
- // skip
- } else {
- if (dst) {
- char *fname = bstrdup0(NULL, bstr_cut(path, 1));
- url_unescape_string(fname, fname);
- r = m_struct_set(desc, dst, "filename", bstr0(fname));
- talloc_free(fname);
- if (r < 0) {
- mp_msg(MSGT_CFGPARSER, MSGL_ERR,
- "Option %.*s: Error while setting filename.\n",
- BSTR_P(name));
- return r;
- }
- }
- }
- }
- return 1;
-}
-
-/// TODO : Write the other needed funcs for 'normal' options
-const m_option_type_t m_option_type_custom_url = {
- .name = "Custom URL",
- .parse = parse_custom_url,
-};
diff --git a/core/m_option.h b/core/m_option.h
index 6d44ce6696..973da4daaa 100644
--- a/core/m_option.h
+++ b/core/m_option.h
@@ -155,12 +155,6 @@ int m_obj_parse_sub_config(struct bstr opt_name, struct bstr name,
struct bstr *pstr, struct m_config *config,
int flags, char ***ret);
-// Parse an URL into a struct.
-/** The option priv field (\ref m_option::priv) must point to a
- * \ref m_struct_st describing which fields of the URL must be used.
- */
-extern const m_option_type_t m_option_type_custom_url;
-
struct m_opt_choice_alternatives {
char *name;
int value;
@@ -193,7 +187,6 @@ struct m_sub_options {
#define CONF_TYPE_FOURCC (&m_option_type_fourcc)
#define CONF_TYPE_AFMT (&m_option_type_afmt)
#define CONF_TYPE_OBJ_SETTINGS_LIST (&m_option_type_obj_settings_list)
-#define CONF_TYPE_CUSTOM_URL (&m_option_type_custom_url)
#define CONF_TYPE_TIME (&m_option_type_time)
#define CONF_TYPE_CHOICE (&m_option_type_choice)
#define CONF_TYPE_INT_PAIR (&m_option_type_intpair)
diff --git a/stream/dvbin.h b/stream/dvbin.h
index ccaf0db66c..54655fdcb2 100644
--- a/stream/dvbin.h
+++ b/stream/dvbin.h
@@ -90,6 +90,10 @@ typedef struct {
int retry;
int timeout;
int last_freq;
+
+ char *cfg_prog;
+ int cfg_card;
+ int cfg_timeout;
} dvb_priv_t;
diff --git a/stream/stream.c b/stream/stream.c
index 523fcc2e8e..a4d9238d46 100644
--- a/stream/stream.c
+++ b/stream/stream.c
@@ -44,7 +44,7 @@
#include "demux/demux.h"
#include "core/m_option.h"
-#include "core/m_struct.h"
+#include "core/m_config.h"
// Includes additional padding in case sizes get rounded up by sector size.
#define TOTAL_BUFFER_SIZE (STREAM_MAX_BUFFER_SIZE + STREAM_MAX_SECTOR_SIZE)
@@ -114,40 +114,97 @@ static const stream_info_t *const auto_open_streams[] = {
NULL
};
-static stream_t *new_stream(size_t min_size);
static int stream_seek_unbuffered(stream_t *s, int64_t newpos);
+static const char *find_url_opt(struct stream *s, const char *opt)
+{
+ for (int n = 0; s->info->url_options && s->info->url_options[n][0]; n++) {
+ if (strcmp(s->info->url_options[n][0], opt) == 0)
+ return s->info->url_options[n][1];
+ }
+ return NULL;
+}
+
+static bstr split_next(bstr *s, char end, const char *delim)
+{
+ int idx = bstrcspn(*s, delim);
+ if (end && (idx >= s->len || s->start[idx] != end))
+ return (bstr){0};
+ bstr r = bstr_splice(*s, 0, idx);
+ *s = bstr_cut(*s, idx + (end ? 1 : 0));
+ return r;
+}
+
+// Parse the stream URL, syntax:
+// proto:// [<username>@]<hostname>[:<port>][/<filename>]
+// (the proto:// part is already removed from s->path)
+// This code originates from times when http code used this, but now it's
+// just relict from other stream implementations reusing this code.
+static bool parse_url(struct stream *st, struct m_config *config)
+{
+ bstr s = bstr0(st->path);
+ const char *f_names[4] = {"username", "hostname", "port", "filename"};
+ bstr f[4];
+ f[0] = split_next(&s, '@', "@:/");
+ f[1] = split_next(&s, 0, ":/");
+ f[2] = bstr_eatstart0(&s, ":") ? split_next(&s, 0, "/") : (bstr){0};
+ f[3] = bstr_eatstart0(&s, "/") ? s : (bstr){0};
+ for (int n = 0; n < 4; n++) {
+ if (f[n].len) {
+ const char *opt = find_url_opt(st, f_names[n]);
+ if (!opt) {
+ mp_tmsg(MSGT_OPEN, MSGL_ERR, "Stream type '%s' accepts no '%s' "
+ "field in URLs.\n", st->info->name, f_names[n]);
+ return false;
+ }
+ int r = m_config_set_option(config, bstr0(opt), f[n]);
+ if (r < 0) {
+ mp_tmsg(MSGT_OPEN, MSGL_ERR, "Error setting stream option: %s\n",
+ m_option_strerror(r));
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+static stream_t *new_stream(void)
+{
+ stream_t *s = talloc_size(NULL, sizeof(stream_t) + TOTAL_BUFFER_SIZE);
+ memset(s, 0, sizeof(stream_t));
+ return s;
+}
+
static stream_t *open_stream_plugin(const stream_info_t *sinfo,
- const char *filename, int mode,
+ const char *url, const char *path, int mode,
struct MPOpts *options, int *ret)
{
- void *arg = NULL;
- stream_t *s;
- m_struct_t *desc = (m_struct_t *)sinfo->opts;
+ stream_t *s = new_stream();
+ s->info = sinfo;
+ s->opts = options;
+ s->url = talloc_strdup(s, url);
+ s->path = talloc_strdup(s, path);
// Parse options
- if (desc) {
- arg = m_struct_alloc(desc);
- if (sinfo->opts_url) {
- m_option_t url_opt = { "stream url", arg, CONF_TYPE_CUSTOM_URL, 0,
- 0, 0, (void *)sinfo->opts };
- if (m_option_parse(&url_opt, bstr0("stream url"), bstr0(filename),
- arg) < 0)
- {
- mp_tmsg(MSGT_OPEN, MSGL_ERR, "URL parsing failed on url %s\n",
- filename);
- m_struct_free(desc, arg);
- *ret = STREAM_ERROR;
- return NULL;
- }
+ if (sinfo->priv_size) {
+ struct m_obj_desc desc = {
+ .priv_size = sinfo->priv_size,
+ .priv_defaults = sinfo->priv_defaults,
+ .options = sinfo->options,
+ };
+ struct m_config *config = m_config_from_obj_desc(s, &desc);
+ s->priv = config->optstruct;
+ if (s->info->url_options && !parse_url(s, config)) {
+ mp_tmsg(MSGT_OPEN, MSGL_ERR, "URL parsing failed on url %s\n", url);
+ talloc_free(s);
+ *ret = STREAM_ERROR;
+ return NULL;
}
}
- s = new_stream(0);
- s->opts = options;
- s->url = talloc_strdup(s, filename);
+
s->flags = 0;
s->mode = mode;
- *ret = sinfo->open(s, mode, arg);
+ *ret = sinfo->open(s, mode);
if ((*ret) != STREAM_OK) {
talloc_free(s);
return NULL;
@@ -165,7 +222,7 @@ static stream_t *open_stream_plugin(const stream_info_t *sinfo,
s->uncached_type = s->type;
- mp_msg(MSGT_OPEN, MSGL_V, "[stream] [%s] %s\n", sinfo->name, filename);
+ mp_msg(MSGT_OPEN, MSGL_V, "[stream] [%s] %s\n", sinfo->name, url);
if (s->mime_type)
mp_msg(MSGT_OPEN, MSGL_V, "Mime-type: '%s'\n", s->mime_type);
@@ -173,15 +230,28 @@ static stream_t *open_stream_plugin(const stream_info_t *sinfo,
return s;
}
+static const char *match_proto(const char *url, const char *proto)
+{
+ int l = strlen(proto);
+ if (l > 0) {
+ if (strncasecmp(url, proto, l) == 0 && strncmp("://", url + l, 3) == 0)
+ return url + l + 3;
+ } else {
+ // pure filenames
+ if (!strstr(url, "://"))
+ return url;
+ }
+ return NULL;
+}
-static stream_t *open_stream_full(const char *filename, int mode,
+static stream_t *open_stream_full(const char *url, int mode,
struct MPOpts *options)
{
- int i, j, l, r;
+ int i, j, r;
const stream_info_t *sinfo;
stream_t *s;
- assert(filename);
+ assert(url);
for (i = 0; auto_open_streams[i]; i++) {
sinfo = auto_open_streams[i];
@@ -192,17 +262,13 @@ static stream_t *open_stream_full(const char *filename, int mode,
continue;
}
for (j = 0; sinfo->protocols[j]; j++) {
- l = strlen(sinfo->protocols[j]);
- // l == 0 => Don't do protocol matching (ie network and filenames)
- if ((l == 0 && !strstr(filename, "://")) ||
- ((strncasecmp(sinfo->protocols[j], filename, l) == 0) &&
- (strncmp("://", filename + l, 3) == 0))) {
- s = open_stream_plugin(sinfo, filename, mode, options, &r);
+ const char *path = match_proto(url, sinfo->protocols[j]);
+ if (path) {
+ s = open_stream_plugin(sinfo, url, path, mode, options, &r);
if (s)
return s;
if (r != STREAM_UNSUPPORTED) {
- mp_tmsg(MSGT_OPEN, MSGL_ERR, "Failed to open %s.\n",
- filename);
+ mp_tmsg(MSGT_OPEN, MSGL_ERR, "Failed to open %s.\n", url);
return NULL;
}
break;
@@ -210,7 +276,7 @@ static stream_t *open_stream_full(const char *filename, int mode,
}
}
- mp_tmsg(MSGT_OPEN, MSGL_ERR, "No stream found to handle url %s\n", filename);
+ mp_tmsg(MSGT_OPEN, MSGL_ERR, "No stream found to handle url %s\n", url);
return NULL;
}
@@ -558,14 +624,6 @@ void stream_update_size(stream_t *s)
}
}
-static stream_t *new_stream(size_t min_size)
-{
- min_size = FFMAX(min_size, TOTAL_BUFFER_SIZE);
- stream_t *s = talloc_size(NULL, sizeof(stream_t) + min_size);
- memset(s, 0, sizeof(stream_t));
- return s;
-}
-
void free_stream(stream_t *s)
{
if (!s)
@@ -638,7 +696,7 @@ static int stream_enable_cache(stream_t **stream, int64_t size, int64_t min,
// Can't handle a loaded buffer.
orig->buf_len = orig->buf_pos = 0;
- stream_t *cache = new_stream(0);
+ stream_t *cache = new_stream();
cache->uncached_type = orig->type;
cache->uncached_stream = orig;
cache->flags |= MP_STREAM_SEEK;
diff --git a/stream/stream.h b/stream/stream.h
index a0cd3d58fc..9800efbafd 100644
--- a/stream/stream.h
+++ b/stream/stream.h
@@ -109,15 +109,17 @@ struct stream;
typedef struct stream_info_st {
const char *name;
// opts is set from ->opts
- int (*open)(struct stream *st, int mode, void *opts);
+ int (*open)(struct stream *st, int mode);
const char *protocols[MAX_STREAM_PROTOCOLS];
- const void *opts;
- int opts_url; /* If this is 1 we will parse the url as an option string
- * too. Otherwise options are only parsed from the
- * options string given to open_stream_plugin */
+ int priv_size;
+ const void *priv_defaults;
+ const struct m_option *options;
+ const char *url_options[][2];
} stream_info_t;
typedef struct stream {
+ const struct stream_info_st *info;
+
// Read
int (*fill_buffer)(struct stream *s, char *buffer, int max_len);
// Write
@@ -142,7 +144,8 @@ typedef struct stream {
int mode; //STREAM_READ or STREAM_WRITE
bool streaming; // known to be a network stream if true
void *priv; // used for DVD, TV, RTSP etc
- char *url; // strdup() of filename/url
+ char *url; // filename/url (possibly including protocol prefix)
+ char *path; // filename (url without protocol prefix)
char *mime_type; // when HTTP streaming is used
char *demuxer; // request demuxer to be used
char *lavf_type; // name of expected demuxer type for lavf
diff --git a/stream/stream_avdevice.c b/stream/stream_avdevice.c
index 5d94b35d70..8bf9985ff8 100644
--- a/stream/stream_avdevice.c
+++ b/stream/stream_avdevice.c
@@ -25,7 +25,7 @@ static int fill_buffer(stream_t *s, char *buffer, int max_len)
return -1;
}
-static int open_f(stream_t *stream, int mode, void *opts)
+static int open_f(stream_t *stream, int mode)
{
if (mode != STREAM_READ)
return STREAM_ERROR;
diff --git a/stream/stream_bluray.c b/stream/stream_bluray.c
index 30145203df..73b8ef61f8 100644
--- a/stream/stream_bluray.c
+++ b/stream/stream_bluray.c
@@ -38,7 +38,6 @@
#include "config.h"
#include "talloc.h"
#include "core/mp_msg.h"
-#include "core/m_struct.h"
#include "core/m_option.h"
#include "stream.h"
#include "demux/stheader.h"
@@ -61,9 +60,12 @@ struct bluray_priv_s {
BLURAY *bd;
int current_angle;
int current_title;
+
+ int cfg_title;
+ char *cfg_device;
};
-static struct stream_priv_s {
+static const struct stream_priv_s {
int title;
char *device;
} bluray_stream_priv_dflts = {
@@ -71,18 +73,11 @@ static struct stream_priv_s {
NULL
};
-#define ST_OFF(f) M_ST_OFF(struct stream_priv_s,f)
+#define OPT_BASE_STRUCT struct bluray_priv_s
static const m_option_t bluray_stream_opts_fields[] = {
- { "hostname", ST_OFF(title), CONF_TYPE_INT, M_OPT_RANGE, 0, 99999, NULL},
- { "filename", ST_OFF(device), CONF_TYPE_STRING, 0, 0 ,0, NULL},
- { NULL, NULL, 0, 0, 0, 0, NULL }
-};
-
-static const struct m_struct_st bluray_stream_opts = {
- "bluray",
- sizeof(struct stream_priv_s),
- &bluray_stream_priv_dflts,
- bluray_stream_opts_fields
+ OPT_INTRANGE("title", cfg_title, 0, 0, 99999),
+ OPT_STRING("device", cfg_device, 0),
+ {0}
};
static void bluray_stream_close(stream_t *s)
@@ -90,8 +85,6 @@ static void bluray_stream_close(stream_t *s)
struct bluray_priv_s *b = s->priv;
bd_close(b->bd);
- b->bd = NULL;
- free(b);
}
static int bluray_stream_seek(stream_t *s, int64_t pos)
@@ -292,10 +285,9 @@ static int bluray_stream_control(stream_t *s, int cmd, void *arg)
return STREAM_UNSUPPORTED;
}
-static int bluray_stream_open(stream_t *s, int mode, void *opts)
+static int bluray_stream_open(stream_t *s, int mode)
{
- struct stream_priv_s *p = opts;
- struct bluray_priv_s *b;
+ struct bluray_priv_s *b = s->priv;
BLURAY_TITLE_INFO *info = NULL;
BLURAY *bd;
@@ -310,8 +302,8 @@ static int bluray_stream_open(stream_t *s, int mode, void *opts)
int i;
/* find the requested device */
- if (p->device)
- device = p->device;
+ if (b->cfg_device)
+ device = b->cfg_device;
else if (bluray_device)
device = bluray_device;
@@ -369,7 +361,7 @@ static int bluray_stream_open(stream_t *s, int mode, void *opts)
}
/* Select current title */
- title = p->title ? p->title - 1: title_guess;
+ title = b->cfg_title ? b->cfg_title - 1: title_guess;
title = FFMIN(title, title_count - 1);
bd_select_title(bd, title);
@@ -400,7 +392,6 @@ err_no_info:
s->close = bluray_stream_close;
s->control = bluray_stream_control;
- b = calloc(1, sizeof(struct bluray_priv_s));
b->bd = bd;
b->current_angle = angle;
b->current_title = title;
@@ -409,7 +400,6 @@ err_no_info:
s->sector_size = BLURAY_SECTOR_SIZE;
s->flags = MP_STREAM_SEEK;
s->priv = b;
- s->url = strdup("br://");
mp_tmsg(MSGT_OPEN, MSGL_V, "Blu-ray successfully opened.\n");
@@ -420,6 +410,12 @@ const stream_info_t stream_info_bluray = {
"bd",
bluray_stream_open,
{ "bd", "br", "bluray", NULL },
- &bluray_stream_opts,
- 1
+ .priv_defaults = &bluray_stream_priv_dflts,
+ .priv_size = sizeof(struct bluray_priv_s),
+ .options = bluray_stream_opts_fields,
+ .url_options = {
+ {"hostname", "title"},
+ {"filename", "device"},
+ {0}
+ },
};
diff --git a/stream/stream_cdda.c b/stream/stream_cdda.c
index 1c8e2ca2d6..ff659b2d02 100644
--- a/stream/stream_cdda.c
+++ b/stream/stream_cdda.c
@@ -43,7 +43,6 @@
#include "stream.h"
#include "core/m_option.h"
-#include "core/m_struct.h"
#include "libavutil/common.h"
#include "compat/mpbswap.h"
@@ -60,9 +59,8 @@ typedef struct {
int start_sector;
int end_sector;
cd_info_t *cd_info;
-} cdda_priv;
-static struct cdda_params {
+ // options
int speed;
int paranoia_mode;
char *generic_dev;
@@ -73,23 +71,19 @@ static struct cdda_params {
int no_skip;
char *device;
int span[2];
-} cdda_dflts = {
+} cdda_priv;
+
+static cdda_priv cdda_dflts = {
.search_overlap = -1,
};
-#define ST_OFF(f) M_ST_OFF(struct cdda_params, f)
+#define OPT_BASE_STRUCT cdda_priv
static const m_option_t cdda_params_fields[] = {
- {"hostname", ST_OFF(span), CONF_TYPE_INT_PAIR, 0, 0, 0, NULL},
- {"port", ST_OFF(speed), CONF_TYPE_INT, M_OPT_RANGE, 1, 100, NULL},
- {"filename", ST_OFF(device), CONF_TYPE_STRING, 0, 0, 0, NULL},
+ OPT_INTPAIR("span", span, 0),
+ OPT_INTRANGE("speed", speed, 0, 1, 100),
+ OPT_STRING("device", device, 0),
{0}
};
-static const struct m_struct_st stream_opts = {
- "cdda",
- sizeof(struct cdda_params),
- &cdda_dflts,
- cdda_params_fields
-};
/// We keep these options but now they set the defaults
const m_option_t cdda_opts[] = {
@@ -319,20 +313,19 @@ static int control(stream_t *stream, int cmd, void *arg)
return STREAM_UNSUPPORTED;
}
-static int open_cdda(stream_t *st, int m, void *opts)
+static int open_cdda(stream_t *st, int m)
{
- struct cdda_params *p = (struct cdda_params *)opts;
+ cdda_priv *priv = st->priv;
+ cdda_priv *p = priv;
int mode = p->paranoia_mode;
int offset = p->toc_offset;
cdrom_drive_t *cdd = NULL;
- cdda_priv *priv;
cd_info_t *cd_info;
unsigned int audiolen = 0;
int last_track;
int i;
if (m != STREAM_READ) {
- m_struct_free(&stream_opts, opts);
return STREAM_UNSUPPORTED;
}
@@ -351,7 +344,6 @@ static int open_cdda(stream_t *st, int m, void *opts)
if (!cdd) {
mp_tmsg(MSGT_OPEN, MSGL_ERR, "Can't open CDDA device.\n");
- m_struct_free(&stream_opts, opts);
return STREAM_ERROR;
}
@@ -363,7 +355,6 @@ static int open_cdda(stream_t *st, int m, void *opts)
if (cdda_open(cdd) != 0) {
mp_tmsg(MSGT_OPEN, MSGL_ERR, "Can't open disc.\n");
cdda_close(cdd);
- m_struct_free(&stream_opts, opts);
return STREAM_ERROR;
}
@@ -424,7 +415,6 @@ static int open_cdda(stream_t *st, int m, void *opts)
cdda_close(cdd);
free(priv);
cd_info_free(cd_info);
- m_struct_free(&stream_opts, opts);
return STREAM_ERROR;
}
@@ -465,8 +455,6 @@ static int open_cdda(stream_t *st, int m, void *opts)
st->demuxer = "rawaudio";
- m_struct_free(&stream_opts, opts);
-
print_cdtext(st, 0);
return STREAM_OK;
@@ -476,6 +464,13 @@ const stream_info_t stream_info_cdda = {
"cdda",
open_cdda,
{"cdda", NULL },
- &stream_opts,
- .opts_url = 1,
+ .priv_size = sizeof(cdda_priv),
+ .priv_defaults = &cdda_dflts,
+ .options = cdda_params_fields,
+ .url_options = {
+ {"hostname", "span"},
+ {"port", "speed"},
+ {"filename", "device"},
+ {0}
+ },
};
diff --git a/stream/stream_dvb.c b/stream/stream_dvb.c
index bd2b174807..08f38cb23c 100644
--- a/stream/stream_dvb.c
+++ b/stream/stream_dvb.c
@@ -43,7 +43,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#include "stream.h"
#include "core/m_option.h"
-#include "core/m_struct.h"
#include "core/path.h"
#include "libavutil/avstring.h"
@@ -58,41 +57,25 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//TODO: CAMBIARE list_ptr e da globale a per_priv
-static struct stream_priv_s
-{
- char *prog;
- int card;
- int timeout;
- char *file;
-}
-stream_defaults =
-{
- "", 1, 30, NULL
+static dvb_priv_t stream_defaults = {
+ .cfg_prog = "",
+ .cfg_card = 1,
+ .cfg_timeout = 30,
};
-#define ST_OFF(f) M_ST_OFF(struct stream_priv_s, f)
+#define OPT_BASE_STRUCT dvb_priv_t
/// URL definition
static const m_option_t stream_params[] = {
- {"hostname", ST_OFF(prog), CONF_TYPE_STRING, 0, 0, 0, NULL },
- {"username", ST_OFF(card), CONF_TYPE_INT, M_OPT_RANGE, 1, 4, NULL},
- {NULL, NULL, 0, 0, 0, 0, NULL}
-};
-
-static const struct m_struct_st stream_opts = {
- "dvbin",
- sizeof(struct stream_priv_s),
- &stream_defaults,
- stream_params
+ OPT_STRING("prog", cfg_prog, 0),
+ OPT_INTRANGE("card", cfg_card, 0, 1, 4),
+ {0}
};
-
-
const m_option_t dvbin_opts_conf[] = {
- {"prog", &stream_defaults.prog, CONF_TYPE_STRING, 0, 0 ,0, NULL},
- {"card", &stream_defaults.card, CONF_TYPE_INT, M_OPT_RANGE, 1, 4, NULL},
- {"timeout", &stream_defaults.timeout, CONF_TYPE_INT, M_OPT_RANGE, 1, 30, NULL},
- {"file", &stream_defaults.file, CONF_TYPE_STRING, 0, 0 ,0, NULL},
+ {"prog", &stream_defaults.cfg_prog, CONF_TYPE_STRING, 0, 0 ,0, NULL},
+ {"card", &stream_defaults.cfg_card, CONF_TYPE_INT, M_OPT_RANGE, 1, 4, NULL},
+ {"timeout", &stream_defaults.cfg_timeout, CONF_TYPE_INT, M_OPT_RANGE, 1, 30, NULL},
{NULL, NULL, 0, 0, 0, 0, NULL}
};
@@ -540,7 +523,7 @@ int dvb_set_channel(stream_t *stream, int card, int n)
if(channel->freq != priv->last_freq)
if (! dvb_tune(priv, channel->freq, channel->pol, channel->srate, channel->diseqc, channel->tone,
- channel->inv, channel->mod, channel->gi, channel->trans, channel->bw, channel->cr, channel->cr_lp, channel->hier, priv->timeout))
+ channel->inv, channel->mod, channel->gi, channel->trans, channel->bw, channel->cr, channel->cr_lp, channel->hier, priv->cfg_timeout))
return 0;
priv->last_freq = channel->freq;
@@ -608,14 +591,15 @@ static void dvbin_close(stream_t *stream)
}
-static int dvb_streaming_start(stream_t *stream, struct stream_priv_s *opts, int tuner_type, char *progname)
+static int dvb_streaming_start(stream_t *stream, int tuner_type, char *progname)
{
int i;
dvb_channel_t *channel = NULL;
dvb_priv_t *priv = stream->priv;
+ dvb_priv_t *opts = priv;
- mp_msg(MSGT_DEMUX, MSGL_V, "\r\ndvb_streaming_start(PROG: %s, CARD: %d, FILE: %s)\r\n",
- opts->prog, opts->card, opts->file);
+ mp_msg(MSGT_DEMUX, MSGL_V, "\r\ndvb_streaming_start(PROG: %s, CARD: %d)\r\n",
+ opts->cfg_prog, opts->cfg_card);
priv->is_on = 0;
@@ -655,12 +639,12 @@ static int dvb_streaming_start(stream_t *stream, struct stream_priv_s *opts, int
-static int dvb_open(stream_t *stream, int mode, void *opts)
+static int dvb_open(stream_t *stream, int mode)
{
// I don't force the file format bacause, although it's almost always TS,
// there are some providers that stream an IP multicast with M$ Mpeg4 inside
- struct stream_priv_s* p = (struct stream_priv_s*)opts;
- dvb_priv_t *priv;
+ dvb_priv_t *priv = stream->priv;
+ dvb_priv_t *p = priv;
char *progname;
int tuner_type = 0, i;
@@ -668,11 +652,6 @@ static int dvb_open(stream_t *stream, int mode, void *opts)
if(mode != STREAM_READ)
return STREAM_UNSUPPORTED;
- stream->priv = calloc(1, sizeof(dvb_priv_t));
- if(stream->priv == NULL)
- return STREAM_ERROR;
-
- priv = (dvb_priv_t *)stream->priv;
priv->fe_fd = priv->sec_fd = priv->dvr_fd = -1;
priv->config = dvb_get_config();
if(priv->config == NULL)
@@ -685,7 +664,7 @@ static int dvb_open(stream_t *stream, int mode, void *opts)
priv->card = -1;
for(i=0; i<priv->config->count; i++)
{
- if(priv->config->cards[i].devno+1 == p->card)
+ if(priv->config->cards[i].devno+1 == p->cfg_card)
{
priv->card = i;
break;
@@ -695,10 +674,10 @@ static int dvb_open(stream_t *stream, int mode, void *opts)
if(priv->card == -1)
{
free(priv);
- mp_msg(MSGT_DEMUX, MSGL_ERR, "NO CONFIGURATION FOUND FOR CARD N. %d, exit\n", p->card);
+ mp_msg(MSGT_DEMUX, MSGL_ERR, "NO CONFIGURATION FOUND FOR CARD N. %d, exit\n", p->cfg_card);
return STREAM_ERROR;
}
- priv->timeout = p->timeout;
+ priv->timeout = p->cfg_timeout;
tuner_type = priv->config->cards[priv->card].type;
@@ -713,17 +692,17 @@ static int dvb_open(stream_t *stream, int mode, void *opts)
priv->tuner_type = tuner_type;
mp_msg(MSGT_DEMUX, MSGL_V, "OPEN_DVB: prog=%s, card=%d, type=%d\n",
- p->prog, priv->card+1, priv->tuner_type);
+ p->cfg_prog, priv->card+1, priv->tuner_type);
priv->list = priv->config->cards[priv->card].list;
- if((! strcmp(p->prog, "")) && (priv->list != NULL))
+ if((! strcmp(p->cfg_prog, "")) && (priv->list != NULL))
progname = priv->list->channels[0].name;
else
- progname = p->prog;
+ progname = p->cfg_prog;
- if(! dvb_streaming_start(stream, p, tuner_type, progname))
+ if(! dvb_streaming_start(stream, tuner_type, progname))
{
free(stream->priv);
stream->priv = NULL;
@@ -733,7 +712,6 @@ static int dvb_open(stream_t *stream, int mode, void *opts)
stream->type = STREAMTYPE_DVB;
stream->fill_buffer = dvb_streaming_read;
stream->close = dvbin_close;
- m_struct_free(&stream_opts, opts);
stream->demuxer = "lavf";
stream->lavf_type = "mpegts";
@@ -855,6 +833,12 @@ const stream_info_t stream_info_dvb = {
"dvbin",
dvb_open,
{ "dvb", NULL },
- &stream_opts,
- 1 // Urls are an option string
+ .priv_size = sizeof(dvb_priv_t),
+ .priv_defaults = &stream_defaults,
+ .options = stream_params,
+ .url_options = {
+ {"hostname", "prog"},
+ {"username", "card"},
+ {0}
+ },
};
diff --git a/stream/stream_dvd.c b/stream/stream_dvd.c
index b27e71e3ab..624ea4c672 100644
--- a/stream/stream_dvd.c
+++ b/stream/stream_dvd.c
@@ -39,7 +39,6 @@
#include "stream.h"
#include "core/m_option.h"
-#include "core/m_struct.h"
#include "stream_dvd.h"
#include "stream_dvd_common.h"
@@ -64,26 +63,16 @@ int dvd_angle=1;
#endif
-static struct stream_priv_s {
- int title;
- char* device;
-} stream_priv_dflts = {
- 1,
- NULL
+static const dvd_priv_t stream_priv_dflts = {
+ .cfg_title = 1,
};
-#define ST_OFF(f) M_ST_OFF(struct stream_priv_s,f)
+#define OPT_BASE_STRUCT dvd_priv_t
/// URL definition
static const m_option_t stream_opts_fields[] = {
- { "hostname", ST_OFF(title), CONF_TYPE_INT, M_OPT_RANGE, 1, 99, NULL},
- { "filename", ST_OFF(device), CONF_TYPE_STRING, 0, 0 ,0, NULL},
- { NULL, NULL, 0, 0, 0, 0, NULL }
-};
-static const struct m_struct_st stream_opts = {
- "dvd",
- sizeof(struct stream_priv_s),
- &stream_priv_dflts,
- stream_opts_fields
+ OPT_INTRANGE("title", cfg_title, 0, 1, 99),
+ OPT_STRING("device", cfg_device, 0),
+ {0}
};
int dvd_chapter_from_cell(dvd_priv_t* dvd,int title,int cell)
@@ -747,16 +736,15 @@ static int control(stream_t *stream,int cmd,void* arg)
}
-static int open_s(stream_t *stream,int mode, void* opts)
+static int open_s(stream_t *stream, int mode)
{
- struct stream_priv_s* p = (struct stream_priv_s*)opts;
int k;
+ dvd_priv_t *d = stream->priv;
mp_msg(MSGT_OPEN,MSGL_V,"URL: %s\n", stream->url);
- dvd_title = p->title;
+ dvd_title = d->cfg_title;
if(1){
//int ret,ret2;
- dvd_priv_t *d;
int ttn,pgc_id,pgn;
dvd_reader_t *dvd;
dvd_file_t *title;
@@ -767,8 +755,8 @@ static int open_s(stream_t *stream,int mode, void* opts)
/**
* Open the disc.
*/
- if(p->device)
- dvd_device_current = p->device;
+ if(d->cfg_device)
+ dvd_device_current = d->cfg_device;
else if(dvd_device)
dvd_device_current = dvd_device;
else
@@ -802,7 +790,6 @@ static int open_s(stream_t *stream,int mode, void* opts)
free(temp_device);
if(!dvd) {
- m_struct_free(&stream_opts,opts);
return STREAM_UNSUPPORTED;
}
} else
@@ -811,7 +798,6 @@ static int open_s(stream_t *stream,int mode, void* opts)
dvd = DVDOpen(dvd_device_current);
if(!dvd) {
mp_tmsg(MSGT_OPEN,MSGL_ERR,"Couldn't open DVD device: %s (%s)\n",dvd_device_current, strerror(errno));
- m_struct_free(&stream_opts,opts);
return STREAM_UNSUPPORTED;
}
}
@@ -826,7 +812,6 @@ static int open_s(stream_t *stream,int mode, void* opts)
if(!vmg_file) {
mp_tmsg(MSGT_OPEN,MSGL_ERR, "Can't open VMG info!\n");
DVDClose( dvd );
- m_struct_free(&stream_opts,opts);
return STREAM_UNSUPPORTED;
}
tt_srpt = vmg_file->tt_srpt;
@@ -866,7 +851,6 @@ static int open_s(stream_t *stream,int mode, void* opts)
mp_tmsg(MSGT_OPEN,MSGL_ERR, "Invalid DVD title number: %d\n", dvd_title);
ifoClose( vmg_file );
DVDClose( dvd );
- m_struct_free(&stream_opts,opts);
return STREAM_UNSUPPORTED;
}
mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_DVD_CURRENT_TITLE=%d\n", dvd_title);
@@ -901,7 +885,6 @@ static int open_s(stream_t *stream,int mode, void* opts)
mp_msg(MSGT_OPEN,MSGL_V, "DVD successfully opened.\n");
// store data
- d=malloc(sizeof(dvd_priv_t)); memset(d,0,sizeof(dvd_priv_t));
d->dvd=dvd;
d->title=title;
d->vmg_file=vmg_file;
@@ -1054,54 +1037,58 @@ static int open_s(stream_t *stream,int mode, void* opts)
fail:
ifoClose(vmg_file);
DVDClose(dvd);
- m_struct_free(&stream_opts, opts);
return STREAM_UNSUPPORTED;
}
mp_tmsg(MSGT_DVD,MSGL_ERR,"mpv was compiled without DVD support, exiting.\n");
- m_struct_free(&stream_opts,opts);
return STREAM_UNSUPPORTED;
}
-static int ifo_stream_open (stream_t *stream, int mode, void *opts)
+static int ifo_stream_open (stream_t *stream, int mode)
{
char* filename;
- struct stream_priv_s *spriv;
- int len = strlen(stream->url);
+ dvd_priv_t *priv = talloc_ptrtype(stream, priv);
+ stream->priv = priv;
+ *priv = stream_priv_dflts;
- if (len < 4 || strcasecmp (stream->url + len - 4, ".ifo"))
+ int len = strlen(stream->path);
+ if (len < 4 || strcasecmp (stream->path + len - 4, ".ifo"))
return STREAM_UNSUPPORTED;
mp_msg(MSGT_DVD, MSGL_INFO, ".IFO detected. Redirecting to dvd://\n");
- filename = strdup(basename(stream->url));
+ filename = strdup(basename(stream->path));
- spriv=calloc(1, sizeof(struct stream_priv_s));
- spriv->device = strdup(dirname(stream->url));
+ talloc_free(priv->cfg_device);
+ priv->cfg_device = talloc_strdup(NULL, dirname(stream->path));
if(!strncasecmp(filename,"vts_",4))
{
- if(sscanf(filename+3, "_%02d_", &spriv->title)!=1)
- spriv->title=1;
+ if(sscanf(filename+3, "_%02d_", &priv->cfg_title)!=1)
+ priv->cfg_title = 1;
}else
- spriv->title=1;
+ priv->cfg_title = 1;
free(filename);
stream->url=talloc_strdup(stream, "dvd://");
- return open_s(stream, mode, spriv);
+ return open_s(stream, mode);
}
const stream_info_t stream_info_dvd = {
"dvd",
open_s,
{ "dvd", NULL },
- &stream_opts,
- 1 // Urls are an option string
+ .priv_size = sizeof(dvd_priv_t),
+ .priv_defaults = &stream_priv_dflts,
+ .options = stream_opts_fields,
+ .url_options = {
+ {"hostname", "title"},
+ {"filename", "device"},
+ {0}
+ },
};
const stream_info_t stream_info_ifo = {
"ifo",
ifo_stream_open,
{ "file", "", NULL },
- NULL,
- 0
};
diff --git a/stream/stream_dvd.h b/stream/stream_dvd.h
index 984d545467..97f2c83eeb 100644
--- a/stream/stream_dvd.h
+++ b/stream/stream_dvd.h
@@ -54,6 +54,9 @@ typedef struct {
// subtitles
int nr_of_subtitles;
stream_language_t subtitles[32];
+
+ int cfg_title;
+ char *cfg_device;
} dvd_priv_t;
int dvd_number_of_subs(stream_t *stream);
diff --git a/stream/stream_file.c b/stream/stream_file.c
index b9e4f2f2e1..dc85314f71 100644
--- a/stream/stream_file.c
+++ b/stream/stream_file.c
@@ -32,34 +32,12 @@
#include "core/mp_msg.h"
#include "stream.h"
#include "core/m_option.h"
-#include "core/m_struct.h"
struct priv {
int fd;
bool close;
};
-static struct stream_priv_s {
- char* filename;
- char *filename2;
-} stream_priv_dflts = {
- NULL, NULL
-};
-
-#define ST_OFF(f) M_ST_OFF(struct stream_priv_s,f)
-/// URL definition
-static const m_option_t stream_opts_fields[] = {
- {"string", ST_OFF(filename), CONF_TYPE_STRING, 0, 0 ,0, NULL},
- {"filename", ST_OFF(filename2), CONF_TYPE_STRING, 0, 0 ,0, NULL},
- { NULL, NULL, 0, 0, 0, 0, NULL }
-};
-static const struct m_struct_st stream_opts = {
- "file",
- sizeof(struct stream_priv_s),
- &stream_priv_dflts,
- stream_opts_fields
-};
-
static int fill_buffer(stream_t *s, char* buffer, int max_len){
struct priv *p = s->priv;
int r = read(p->fd,buffer,max_len);
@@ -128,13 +106,12 @@ static void s_close(stream_t *s)
close(p->fd);
}
-static int open_f(stream_t *stream,int mode, void* opts)
+static int open_f(stream_t *stream, int mode)
{
int f;
mode_t m = 0;
int64_t len;
- unsigned char *filename;
- struct stream_priv_s* p = (struct stream_priv_s*)opts;
+ char *filename = stream->path;
struct priv *priv = talloc_ptrtype(stream, priv);
*priv = (struct priv) { .fd = -1 };
stream->priv = priv;
@@ -145,22 +122,9 @@ static int open_f(stream_t *stream,int mode, void* opts)
m = O_RDWR|O_CREAT|O_TRUNC;
else {
mp_msg(MSGT_OPEN,MSGL_ERR, "[file] Unknown open mode %d\n",mode);
- m_struct_free(&stream_opts,opts);
return STREAM_UNSUPPORTED;
}
- if(p->filename)
- filename = p->filename;
- else if(p->filename2)
- filename = p->filename2;
- else
- filename = NULL;
- if(!filename) {
- mp_msg(MSGT_OPEN,MSGL_ERR, "[file] No filename\n");
- m_struct_free(&stream_opts,opts);
- return STREAM_ERROR;
- }
-
#if HAVE_DOS_PATHS
// extract '/' from '/x:/path'
if( filename[ 0 ] == '/' && filename[ 1 ] && filename[ 2 ] == ':' )
@@ -195,7 +159,6 @@ static int open_f(stream_t *stream,int mode, void* opts)
if(f<0) {
mp_tmsg(MSGT_OPEN, MSGL_ERR, "Cannot open file '%s': %s\n", filename,
strerror(errno));
- m_struct_free(&stream_opts,opts);
return STREAM_ERROR;
}
#ifndef __MINGW32__
@@ -203,7 +166,6 @@ static int open_f(stream_t *stream,int mode, void* opts)
if (fstat(f, &st) == 0 && S_ISDIR(st.st_mode)) {
mp_tmsg(MSGT_OPEN,MSGL_ERR,"File is a directory: '%s'\n",filename);
close(f);
- m_struct_free(&stream_opts,opts);
return STREAM_ERROR;
}
#endif
@@ -234,7 +196,6 @@ static int open_f(stream_t *stream,int mode, void* opts)
stream->read_chunk = 64*1024;
stream->close = s_close;
- m_struct_free(&stream_opts,opts);
return STREAM_OK;
}
@@ -242,6 +203,4 @@ const stream_info_t stream_info_file = {
"file",
open_f,
{ "file", "", NULL },
- &stream_opts,
- 1 // Urls are an option string
};
diff --git a/stream/stream_lavf.c b/stream/stream_lavf.c
index 82241e83f3..a55b594495 100644
--- a/stream/stream_lavf.c
+++ b/stream/stream_lavf.c
@@ -25,14 +25,13 @@
#include "core/mp_msg.h"
#include "stream.h"
#include "core/m_option.h"
-#include "core/m_struct.h"
#include "cookies.h"
#include "core/bstr.h"
#include "core/mp_talloc.h"
-static int open_f(stream_t *stream, int mode, void *opts);
+static int open_f(stream_t *stream, int mode);
static char **read_icy(stream_t *stream);
static int fill_buffer(stream_t *s, char *buffer, int max_len)
@@ -114,7 +113,7 @@ static int control(stream_t *s, int cmd, void *arg)
// avio doesn't seem to support this - emulate it by reopening
close_f(s);
s->priv = NULL;
- return open_f(s, STREAM_READ, NULL);
+ return open_f(s, STREAM_READ);
}
}
return STREAM_UNSUPPORTED;
@@ -131,7 +130,7 @@ static bool mp_avio_has_opts(AVIOContext *avio)
static const char * const prefix[] = { "lavf://", "ffmpeg://" };
-static int open_f(stream_t *stream, int mode, void *opts)
+static int open_f(stream_t *stream, int mode)
{
int flags = 0;
AVIOContext *avio = NULL;
@@ -309,6 +308,4 @@ const stream_info_t stream_info_ffmpeg = {
open_f,
{ "lavf", "ffmpeg", "rtmp", "rtsp", "http", "https", "mms", "mmst", "mmsh",
"mmshttp", "udp", "ftp", "rtp", "httpproxy", NULL },
- NULL,
- 1 // Urls are an option string
};
diff --git a/stream/stream_memory.c b/stream/stream_memory.c
index 79bfea459d..4d56fb4a3f 100644
--- a/stream/stream_memory.c
+++ b/stream/stream_memory.c
@@ -54,7 +54,7 @@ static int control(stream_t *s, int cmd, void *arg)
return STREAM_UNSUPPORTED;
}
-static int open_f(stream_t *stream, int mode, void* opts)
+static int open_f(stream_t *stream, int mode)
{
stream->fill_buffer = fill_buffer;
stream->seek = seek;
diff --git a/stream/stream_mf.c b/stream/stream_mf.c
index 9f87dad6b1..720a73f836 100644
--- a/stream/stream_mf.c
+++ b/stream/stream_mf.c
@@ -29,7 +29,7 @@
#include "stream.h"
static int
-mf_stream_open (stream_t *stream, int mode, void *opts)
+mf_stream_open (stream_t *stream, int mode)
{
stream->type = STREAMTYPE_MF;
stream->demuxer = "mf";
@@ -41,6 +41,4 @@ const stream_info_t stream_info_mf = {
"mf",
mf_stream_open,
{ "mf", NULL },
- NULL,
- 1
};
diff --git a/stream/stream_null.c b/stream/stream_null.c
index 8bae12ff9d..2e2b7886f7 100644
--- a/stream/stream_null.c
+++ b/stream/stream_null.c
@@ -25,7 +25,7 @@
#include "stream.h"
-static int open_s(stream_t *stream,int mode, void* opts)
+static int open_s(stream_t *stream,int mode)
{
return 1;
}
@@ -35,6 +35,4 @@ const stream_info_t stream_info_null = {
"null",
open_s,
{ "null", NULL },
- NULL,
- 0 // Urls are an option string
};
diff --git a/stream/stream_pvr.c b/stream/stream_pvr.c
index 6038ee9221..60517e0754 100644
--- a/stream/stream_pvr.c
+++ b/stream/stream_pvr.c
@@ -1556,7 +1556,7 @@ pvr_stream_read (stream_t *stream, char *buffer, int size)
}
static int
-pvr_stream_open (stream_t *stream, int mode, void *opts)
+pvr_stream_open (stream_t *stream, int mode)
{
struct v4l2_capability vcap;
struct v4l2_ext_controls ctrls;
@@ -1760,6 +1760,4 @@ const stream_info_t stream_info_pvr = {
"pvr",
pvr_stream_open,
{ "pvr", NULL },
- NULL,
- 1
};
diff --git a/stream/stream_radio.c b/stream/stream_radio.c
index dd173175f0..56a01c7d7c 100644
--- a/stream/stream_radio.c
+++ b/stream/stream_radio.c
@@ -43,7 +43,6 @@
#include "stream.h"
#include "demux/demux.h"
-#include "core/m_struct.h"
#include "core/m_option.h"
#include "core/mp_msg.h"
#include "stream_radio.h"
@@ -118,18 +117,11 @@ typedef struct radio_driver_s {
int (*get_frequency)(radio_priv_t* priv,float* frequency);
} radio_driver_t;
-#define ST_OFF(f) M_ST_OFF(radio_param_t,f)
+#define OPT_BASE_STRUCT radio_param_t
static const m_option_t stream_opts_fields[] = {
- {"hostname", ST_OFF(freq_channel), CONF_TYPE_FLOAT, 0, 0 ,0, NULL},
- {"filename", ST_OFF(capture), CONF_TYPE_STRING, 0, 0 ,0, NULL},
- { NULL, NULL, 0, 0, 0, 0, NULL }
-};
-
-static const struct m_struct_st stream_opts = {
- "radio",
- sizeof(radio_param_t),
- &stream_radio_defaults,
- stream_opts_fields
+ OPT_FLOAT("title", freq_channel, 0),
+ OPT_STRING("device", capture, 0),
+ {0}
};
static void close_s(struct stream *stream);
@@ -824,7 +816,7 @@ static const radio_driver_t* radio_drivers[]={
* Stream initialization
* \return STREAM_OK if success, STREAM_ERROR otherwise
*/
-static int open_s(stream_t *stream,int mode, void* opts)
+static int open_s(stream_t *stream,int mode)
{
radio_priv_t* priv;
float frequency=0;
@@ -842,7 +834,8 @@ static int open_s(stream_t *stream,int mode, void* opts)
return STREAM_ERROR;
- priv->radio_param=opts;
+ priv->radio_param=stream->priv;
+ stream->priv=NULL;
#ifdef CONFIG_RADIO_CAPTURE
if (priv->radio_param->capture && strncmp("capture",priv->radio_param->capture,7)==0)
@@ -961,8 +954,6 @@ static void close_s(struct stream *stream){
close(priv->radio_fd);
}
- if(priv->radio_param)
- m_struct_free(&stream_opts,priv->radio_param);
free(priv);
stream->priv=NULL;
}
@@ -971,6 +962,12 @@ const stream_info_t stream_info_radio = {
"radio",
open_s,
{ "radio", NULL },
- &stream_opts,
- 1 // Urls are an option string
+ .priv_size = sizeof(radio_param_t),
+ .priv_defaults = &stream_radio_defaults,
+ .options = stream_opts_fields,
+ .url_options = {
+ {"hostname", "freqchannel"},
+ {"username", "capture"},
+ {0}
+ },
};
diff --git a/stream/stream_smb.c b/stream/stream_smb.c
index 91c5c615d7..a37dc659dd 100644
--- a/stream/stream_smb.c
+++ b/stream/stream_smb.c
@@ -26,29 +26,11 @@
#include "core/mp_msg.h"
#include "stream.h"
#include "core/m_option.h"
-#include "core/m_struct.h"
struct priv {
int fd;
};
-static struct stream_priv_s {
-} stream_priv_dflts = {
-};
-
-#define ST_OFF(f) M_ST_OFF(struct stream_priv_s,f)
-// URL definition
-static const m_option_t stream_opts_fields[] = {
- { NULL, NULL, 0, 0, 0, 0, NULL }
-};
-
-static const struct m_struct_st stream_opts = {
- "smb",
- sizeof(struct stream_priv_s),
- &stream_priv_dflts,
- stream_opts_fields
-};
-
static char smb_password[15];
static char smb_username[15];
@@ -126,7 +108,7 @@ static void close_f(stream_t *s){
smbc_close(p->fd);
}
-static int open_f (stream_t *stream, int mode, void *opts)
+static int open_f (stream_t *stream, int mode)
{
char *filename;
mode_t m = 0;
@@ -144,27 +126,23 @@ static int open_f (stream_t *stream, int mode, void *opts)
m = O_RDWR|O_CREAT|O_TRUNC;
else {
mp_msg(MSGT_OPEN, MSGL_ERR, "[smb] Unknown open mode %d\n", mode);
- m_struct_free (&stream_opts, opts);
return STREAM_UNSUPPORTED;
}
if(!filename) {
mp_msg(MSGT_OPEN,MSGL_ERR, "[smb] Bad url\n");
- m_struct_free(&stream_opts, opts);
return STREAM_ERROR;
}
err = smbc_init(smb_auth_fn, 1);
if (err < 0) {
mp_tmsg(MSGT_OPEN,MSGL_ERR,"Cannot init the libsmbclient library: %d\n",err);
- m_struct_free(&stream_opts, opts);
return STREAM_ERROR;
}
fd = smbc_open(filename, m,0644);
if (fd < 0) {
mp_tmsg(MSGT_OPEN,MSGL_ERR,"Could not open from LAN: '%s'\n", filename);
- m_struct_free(&stream_opts, opts);
return STREAM_ERROR;
}
@@ -185,7 +163,6 @@ static int open_f (stream_t *stream, int mode, void *opts)
stream->close = close_f;
stream->control = control;
- m_struct_free(&stream_opts, opts);
return STREAM_OK;
}
@@ -193,6 +170,4 @@ const stream_info_t stream_info_smb = {
"smb",
open_f,
{"smb", NULL},
- &stream_opts,
- 0 //Url is an option string
};
diff --git a/stream/stream_tv.c b/stream/stream_tv.c
index d9a4636b00..5a01d967e9 100644
--- a/stream/stream_tv.c
+++ b/stream/stream_tv.c
@@ -28,7 +28,6 @@
#include "stream.h"
#include "core/m_option.h"
-#include "core/m_struct.h"
#include "tv.h"
#include <stdio.h>
@@ -75,33 +74,22 @@ tv_param_t stream_tv_defaults = {
0.5, //scan_period
};
-#define ST_OFF(f) M_ST_OFF(tv_param_t,f)
+#define OPT_BASE_STRUCT tv_param_t
static const m_option_t stream_opts_fields[] = {
- {"hostname", ST_OFF(channel), CONF_TYPE_STRING, 0, 0 ,0, NULL},
- {"filename", ST_OFF(input), CONF_TYPE_INT, 0, 0 ,0, NULL},
- { NULL, NULL, 0, 0, 0, 0, NULL }
-};
-
-static const struct m_struct_st stream_opts = {
- "tv",
- sizeof(tv_param_t),
- &stream_tv_defaults,
- stream_opts_fields
+ OPT_STRING("channel", channel, 0),
+ OPT_INT("input", input, 0),
+ {0}
};
static void
tv_stream_close (stream_t *stream)
{
- if(stream->priv)
- m_struct_free(&stream_opts,stream->priv);
- stream->priv=NULL;
}
static int
-tv_stream_open (stream_t *stream, int mode, void *opts)
+tv_stream_open (stream_t *stream, int mode)
{
stream->type = STREAMTYPE_TV;
- stream->priv = opts;
stream->close=tv_stream_close;
stream->demuxer = "tv";
@@ -112,6 +100,12 @@ const stream_info_t stream_info_tv = {
"tv",
tv_stream_open,
{ "tv", NULL },
- &stream_opts,
- 1
+ .priv_size = sizeof(tv_param_t),
+ .priv_defaults = &stream_tv_defaults,
+ .options = stream_opts_fields,
+ .url_options = {
+ {"hostname", "channel"},
+ {"filename", "input"},
+ {0}
+ },
};
diff --git a/stream/stream_vcd.c b/stream/stream_vcd.c
index 38f6953b11..453e69585e 100644
--- a/stream/stream_vcd.c
+++ b/stream/stream_vcd.c
@@ -27,7 +27,6 @@
#include "core/mp_msg.h"
#include "stream.h"
#include "core/m_option.h"
-#include "core/m_struct.h"
#include <fcntl.h>
#include <stdlib.h>
@@ -59,28 +58,6 @@
extern char *cdrom_device;
-static struct stream_priv_s {
- int track;
- char* device;
-} stream_priv_dflts = {
- 1,
- NULL
-};
-
-#define ST_OFF(f) M_ST_OFF(struct stream_priv_s,f)
-/// URL definition
-static const m_option_t stream_opts_fields[] = {
- { "hostname", ST_OFF(track), CONF_TYPE_INT, M_OPT_MIN, 1, 0, NULL },
- { "filename", ST_OFF(device), CONF_TYPE_STRING, 0, 0 ,0, NULL},
- { NULL, NULL, 0, 0, 0, 0, NULL }
-};
-static const struct m_struct_st stream_opts = {
- "vcd",
- sizeof(struct stream_priv_s),
- &stream_priv_dflts,
- stream_opts_fields
-};
-
static int fill_buffer(stream_t *s, char* buffer, int max_len){
if(s->pos > s->end_pos) /// don't past end of current track
return 0;
@@ -100,9 +77,8 @@ static void close_s(stream_t *stream) {
free(stream->priv);
}
-static int open_s(stream_t *stream,int mode, void* opts)
+static int open_s(stream_t *stream,int mode)
{
- struct stream_priv_s* p = opts;
int ret,ret2,f,sect,tmp;
mp_vcd_priv_t* vcd;
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
@@ -110,7 +86,7 @@ static int open_s(stream_t *stream,int mode, void* opts)
#endif
#if defined(__MINGW32__) || defined(__CYGWIN__)
HANDLE hd;
- char device[] = "\\\\.\\?:";
+ char device[20] = "\\\\.\\?:";
#endif
if(mode != STREAM_READ
@@ -118,29 +94,31 @@ static int open_s(stream_t *stream,int mode, void* opts)
|| GetVersion() > 0x80000000 // Win9x
#endif
) {
- m_struct_free(&stream_opts,opts);
return STREAM_UNSUPPORTED;
}
- if (!p->device) {
+ char *dev = stream->url;
+ if (strncmp("vcd://", dev, 6) != 0)
+ return STREAM_UNSUPPORTED;
+ dev += 6;
+ if (!dev[0]) {
if(cdrom_device)
- p->device = talloc_strdup(NULL, cdrom_device);
+ dev = cdrom_device;
else
- p->device = talloc_strdup(NULL, DEFAULT_CDROM_DEVICE);
+ dev = DEFAULT_CDROM_DEVICE;
}
#if defined(__MINGW32__) || defined(__CYGWIN__)
- device[4] = p->device[0];
+ device[4] = dev ? dev[0] : 0;
/* open() can't be used for devices so do it the complicated way */
hd = CreateFile(device, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
f = _open_osfhandle((intptr_t)hd, _O_RDONLY);
#else
- f=open(p->device,O_RDONLY);
+ f=open(dev,O_RDONLY);
#endif
if(f<0){
- mp_tmsg(MSGT_OPEN,MSGL_ERR,"CD-ROM Device '%s' not found.\n",p->device);
- m_struct_free(&stream_opts,opts);
+ mp_tmsg(MSGT_OPEN,MSGL_ERR,"CD-ROM Device '%s' not found.\n",dev);
return STREAM_ERROR;
}
@@ -148,25 +126,22 @@ static int open_s(stream_t *stream,int mode, void* opts)
if(!vcd) {
mp_msg(MSGT_OPEN,MSGL_ERR,"Failed to get cd toc\n");
close(f);
- m_struct_free(&stream_opts,opts);
return STREAM_ERROR;
}
- ret2=vcd_get_track_end(vcd,p->track);
+ ret2=vcd_get_track_end(vcd,1);
if(ret2<0){
mp_msg(MSGT_OPEN, MSGL_ERR, "%s (get)\n",
mp_gtext("Error selecting VCD track."));
close(f);
free(vcd);
- m_struct_free(&stream_opts,opts);
return STREAM_ERROR;
}
- ret=vcd_seek_to_track(vcd,p->track);
+ ret=vcd_seek_to_track(vcd,1);
if(ret<0){
mp_msg(MSGT_OPEN, MSGL_ERR, "%s (seek)\n",
mp_gtext("Error selecting VCD track."));
close(f);
free(vcd);
- m_struct_free(&stream_opts,opts);
return STREAM_ERROR;
}
/* search forward up to at most 3 seconds to skip leading margin */
@@ -199,7 +174,6 @@ static int open_s(stream_t *stream,int mode, void* opts)
stream->close = close_s;
stream->demuxer = "lavf"; // mpegps ( or "vcd"?)
- m_struct_free(&stream_opts,opts);
return STREAM_OK;
}
@@ -207,6 +181,4 @@ const stream_info_t stream_info_vcd = {
"vcd",
open_s,
{ "vcd", NULL },
- &stream_opts,
- 1 // Urls are an option string
};