diff options
-rw-r--r-- | DOCS/man/en/mpv.rst | 2 | ||||
-rw-r--r-- | core/m_option.c | 222 | ||||
-rw-r--r-- | core/m_option.h | 7 | ||||
-rw-r--r-- | stream/dvbin.h | 4 | ||||
-rw-r--r-- | stream/stream.c | 150 | ||||
-rw-r--r-- | stream/stream.h | 15 | ||||
-rw-r--r-- | stream/stream_avdevice.c | 2 | ||||
-rw-r--r-- | stream/stream_bluray.c | 46 | ||||
-rw-r--r-- | stream/stream_cdda.c | 45 | ||||
-rw-r--r-- | stream/stream_dvb.c | 84 | ||||
-rw-r--r-- | stream/stream_dvd.c | 77 | ||||
-rw-r--r-- | stream/stream_dvd.h | 3 | ||||
-rw-r--r-- | stream/stream_file.c | 45 | ||||
-rw-r--r-- | stream/stream_lavf.c | 9 | ||||
-rw-r--r-- | stream/stream_memory.c | 2 | ||||
-rw-r--r-- | stream/stream_mf.c | 4 | ||||
-rw-r--r-- | stream/stream_null.c | 4 | ||||
-rw-r--r-- | stream/stream_pvr.c | 4 | ||||
-rw-r--r-- | stream/stream_radio.c | 33 | ||||
-rw-r--r-- | stream/stream_smb.c | 27 | ||||
-rw-r--r-- | stream/stream_tv.c | 32 | ||||
-rw-r--r-- | stream/stream_vcd.c | 56 |
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 }; |