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 , |