diff options
Diffstat (limited to 'stream')
-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 |
19 files changed, 280 insertions, 362 deletions
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 = { + |