summaryrefslogtreecommitdiffstats
path: root/stream
diff options
context:
space:
mode:
Diffstat (limited to 'stream')
-rw-r--r--stream/dvbin.h4
-rw-r--r--stream/stream.c150
-rw-r--r--stream/stream.h15
-rw-r--r--stream/stream_avdevice.c2
-rw-r--r--stream/stream_bluray.c46
-rw-r--r--stream/stream_cdda.c45
-rw-r--r--stream/stream_dvb.c84
-rw-r--r--stream/stream_dvd.c77
-rw-r--r--stream/stream_dvd.h3
-rw-r--r--stream/stream_file.c45
-rw-r--r--stream/stream_lavf.c9
-rw-r--r--stream/stream_memory.c2
-rw-r--r--stream/stream_mf.c4
-rw-r--r--stream/stream_null.c4
-rw-r--r--stream/stream_pvr.c4
-rw-r--r--stream/stream_radio.c33
-rw-r--r--stream/stream_smb.c27
-rw-r--r--stream/stream_tv.c32
-rw-r--r--stream/stream_vcd.c56
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://");
<