mirror of
https://github.com/mpv-player/mpv
synced 2025-03-25 04:38:01 +00:00
stream: rearrange open functions
Add yet another variant of the stream open function. This time, make it so that it's possible to add new open parameters in an extendable way, which should put an end to having to change this every other year. Effectively get rid of the overly special stream_create_instance() function and use the new one instead, which requires changes in stream_concat.c and stream_memory.c. The function is still in private in stream.c, but I preferred to make the mentioned users go through the new function for orthogonality. The error handling (mostly logging) was adjusted accordingly. This should not have any functional changes. (To preempt any excuses, I didn't actually test stream_concat and stream_memory.)
This commit is contained in:
parent
a7158ceec0
commit
2bb5ab07b7
115
stream/stream.c
115
stream/stream.c
@ -213,10 +213,13 @@ static void stream_resize_buffer(struct stream *s, int new)
|
||||
}
|
||||
}
|
||||
|
||||
int stream_create_instance(const stream_info_t *sinfo, const char *url, int flags,
|
||||
struct mp_cancel *c, struct mpv_global *global,
|
||||
void *arg, struct stream **ret)
|
||||
static int stream_create_instance(const stream_info_t *sinfo,
|
||||
struct stream_open_args *args,
|
||||
struct stream **ret)
|
||||
{
|
||||
const char *url = args->url;
|
||||
int flags = args->flags;
|
||||
|
||||
*ret = NULL;
|
||||
|
||||
if (!sinfo->is_safe && (flags & STREAM_SAFE_ONLY))
|
||||
@ -235,21 +238,21 @@ int stream_create_instance(const stream_info_t *sinfo, const char *url, int flag
|
||||
return STREAM_NO_MATCH;
|
||||
|
||||
stream_t *s = talloc_zero(NULL, stream_t);
|
||||
s->global = args->global;
|
||||
if (flags & STREAM_SILENT) {
|
||||
s->log = mp_null_log;
|
||||
} else {
|
||||
s->log = mp_log_new(s, global->log, sinfo->name);
|
||||
s->log = mp_log_new(s, s->global->log, sinfo->name);
|
||||
}
|
||||
s->info = sinfo;
|
||||
s->cancel = c;
|
||||
s->global = global;
|
||||
s->cancel = args->cancel;
|
||||
s->url = talloc_strdup(s, url);
|
||||
s->path = talloc_strdup(s, path);
|
||||
s->is_network = sinfo->is_network;
|
||||
s->mode = flags & (STREAM_READ | STREAM_WRITE);
|
||||
|
||||
int opt;
|
||||
mp_read_option_raw(global, "access-references", &m_option_type_flag, &opt);
|
||||
mp_read_option_raw(s->global, "access-references", &m_option_type_flag, &opt);
|
||||
s->access_references = opt;
|
||||
|
||||
MP_VERBOSE(s, "Opening %s\n", url);
|
||||
@ -268,8 +271,8 @@ int stream_create_instance(const stream_info_t *sinfo, const char *url, int flag
|
||||
|
||||
int r = STREAM_UNSUPPORTED;
|
||||
if (sinfo->open2) {
|
||||
r = sinfo->open2(s, arg);
|
||||
} else if (!arg) {
|
||||
r = sinfo->open2(s, args);
|
||||
} else if (!args->special_arg) {
|
||||
r = (sinfo->open)(s);
|
||||
}
|
||||
if (r != STREAM_OK) {
|
||||
@ -294,49 +297,63 @@ int stream_create_instance(const stream_info_t *sinfo, const char *url, int flag
|
||||
return STREAM_OK;
|
||||
}
|
||||
|
||||
int stream_create_with_args(struct stream_open_args *args, struct stream **ret)
|
||||
|
||||
{
|
||||
assert(args->url);
|
||||
|
||||
int r = STREAM_NO_MATCH;
|
||||
*ret = NULL;
|
||||
|
||||
// Open stream proper
|
||||
if (args->sinfo) {
|
||||
r = stream_create_instance(args->sinfo, args, ret);
|
||||
} else {
|
||||
for (int i = 0; stream_list[i]; i++) {
|
||||
r = stream_create_instance(stream_list[i], args, ret);
|
||||
if (r == STREAM_OK)
|
||||
break;
|
||||
if (r == STREAM_NO_MATCH || r == STREAM_UNSUPPORTED)
|
||||
continue;
|
||||
if (r == STREAM_UNSAFE)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!*ret && !(args->flags & STREAM_SILENT) && !mp_cancel_test(args->cancel))
|
||||
{
|
||||
struct mp_log *log = mp_log_new(NULL, args->global->log, "!stream");
|
||||
|
||||
if (r == STREAM_UNSAFE) {
|
||||
mp_err(log, "\nRefusing to load potentially unsafe URL from a playlist.\n"
|
||||
"Use --playlist=file or the --load-unsafe-playlists option to "
|
||||
"load it anyway.\n\n");
|
||||
} else if (r == STREAM_NO_MATCH || r == STREAM_UNSUPPORTED) {
|
||||
mp_err(log, "No protocol handler found to open URL %s\n", args->url);
|
||||
mp_err(log, "The protocol is either unsupported, or was disabled "
|
||||
"at compile-time.\n");
|
||||
} else {
|
||||
mp_err(log, "Failed to open %s.\n", args->url);
|
||||
}
|
||||
|
||||
talloc_free(log);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
struct stream *stream_create(const char *url, int flags,
|
||||
struct mp_cancel *c, struct mpv_global *global)
|
||||
{
|
||||
struct mp_log *log = mp_log_new(NULL, global->log, "!stream");
|
||||
struct stream *s = NULL;
|
||||
assert(url);
|
||||
|
||||
// Open stream proper
|
||||
bool unsafe = false;
|
||||
for (int i = 0; stream_list[i]; i++) {
|
||||
int r = stream_create_instance(stream_list[i], url, flags, c, global,
|
||||
NULL, &s);
|
||||
if (r == STREAM_OK)
|
||||
break;
|
||||
if (r == STREAM_NO_MATCH || r == STREAM_UNSUPPORTED)
|
||||
continue;
|
||||
if (r == STREAM_UNSAFE) {
|
||||
unsafe = true;
|
||||
continue;
|
||||
}
|
||||
if (r != STREAM_OK) {
|
||||
if (!mp_cancel_test(c))
|
||||
mp_err(log, "Failed to open %s.\n", url);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
if (!s && unsafe) {
|
||||
mp_err(log, "\nRefusing to load potentially unsafe URL from a playlist.\n"
|
||||
"Use --playlist=file or the --load-unsafe-playlists option to "
|
||||
"load it anyway.\n\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!s) {
|
||||
mp_err(log, "No protocol handler found to open URL %s\n", url);
|
||||
mp_err(log, "The protocol is either unsupported, or was disabled "
|
||||
"at compile-time.\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
done:
|
||||
talloc_free(log);
|
||||
struct stream_open_args args = {
|
||||
.global = global,
|
||||
.cancel = c,
|
||||
.flags = flags,
|
||||
.url = url,
|
||||
};
|
||||
struct stream *s;
|
||||
stream_create_with_args(&args, &s);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
@ -66,12 +66,13 @@ struct stream_avseek {
|
||||
};
|
||||
|
||||
struct stream;
|
||||
struct stream_open_args;
|
||||
typedef struct stream_info_st {
|
||||
const char *name;
|
||||
// opts is set from ->opts
|
||||
int (*open)(struct stream *st);
|
||||
// Alternative to open(). Only either open() or open2() can be set.
|
||||
int (*open2)(struct stream *st, void *arg);
|
||||
int (*open2)(struct stream *st, struct stream_open_args *args);
|
||||
const char *const *protocols;
|
||||
bool can_write; // correctly checks for READ/WRITE modes
|
||||
bool is_safe; // opening is no security issue, even with remote provided URLs
|
||||
@ -165,9 +166,17 @@ struct bstr stream_read_file(const char *filename, void *talloc_ctx,
|
||||
struct mpv_global *global, int max_size);
|
||||
int stream_control(stream_t *s, int cmd, void *arg);
|
||||
void free_stream(stream_t *s);
|
||||
int stream_create_instance(const stream_info_t *sinfo, const char *url, int flags,
|
||||
struct mp_cancel *c, struct mpv_global *global,
|
||||
void *arg, struct stream **ret);
|
||||
|
||||
struct stream_open_args {
|
||||
struct mpv_global *global;
|
||||
struct mp_cancel *cancel; // aborting stream access (used directly)
|
||||
const char *url;
|
||||
int flags; // STREAM_READ etc.
|
||||
const stream_info_t *sinfo; // NULL = autoprobe, otherwise force stream impl.
|
||||
void *special_arg; // specific to impl., use only with sinfo
|
||||
};
|
||||
|
||||
int stream_create_with_args(struct stream_open_args *args, struct stream **ret);
|
||||
struct stream *stream_create(const char *url, int flags,
|
||||
struct mp_cancel *c, struct mpv_global *global);
|
||||
struct stream *stream_open(const char *filename, struct mpv_global *global);
|
||||
|
@ -91,7 +91,7 @@ static void s_close(struct stream *s)
|
||||
free_stream(p->streams[n]);
|
||||
}
|
||||
|
||||
static int open2(struct stream *stream, void *arg)
|
||||
static int open2(struct stream *stream, struct stream_open_args *args)
|
||||
{
|
||||
struct priv *p = talloc_zero(stream, struct priv);
|
||||
stream->priv = p;
|
||||
@ -102,7 +102,7 @@ static int open2(struct stream *stream, void *arg)
|
||||
|
||||
stream->seekable = true;
|
||||
|
||||
struct priv *list = arg;
|
||||
struct priv *list = args->special_arg;
|
||||
if (!list || !list->num_streams) {
|
||||
MP_FATAL(stream, "No sub-streams.\n");
|
||||
return STREAM_ERROR;
|
||||
@ -153,8 +153,16 @@ struct stream *stream_concat_open(struct mpv_global *global, struct mp_cancel *c
|
||||
.num_streams = num_streams,
|
||||
};
|
||||
|
||||
struct stream_open_args sargs = {
|
||||
.global = global,
|
||||
.cancel = c,
|
||||
.url = "concat://",
|
||||
.flags = STREAM_READ | STREAM_SILENT,
|
||||
.sinfo = &stream_info_concat,
|
||||
.special_arg = &arg,
|
||||
};
|
||||
|
||||
struct stream *s = NULL;
|
||||
stream_create_instance(&stream_info_concat, "concat://",
|
||||
STREAM_READ | STREAM_SILENT, c, global, &arg, &s);
|
||||
stream_create_with_args(&sargs, &s);
|
||||
return s;
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ static int control(stream_t *s, int cmd, void *arg)
|
||||
return STREAM_UNSUPPORTED;
|
||||
}
|
||||
|
||||
static int open2(stream_t *stream, void *arg)
|
||||
static int open2(stream_t *stream, struct stream_open_args *args)
|
||||
{
|
||||
stream->fill_buffer = fill_buffer;
|
||||
stream->seek = seek;
|
||||
@ -67,8 +67,8 @@ static int open2(stream_t *stream, void *arg)
|
||||
if (!use_hex)
|
||||
bstr_eatstart0(&data, "memory://");
|
||||
|
||||
if (arg)
|
||||
data = *(bstr *)arg;
|
||||
if (args->special_arg)
|
||||
data = *(bstr *)args->special_arg;
|
||||
|
||||
p->data = bstrdup(stream, data);
|
||||
|
||||
@ -90,10 +90,16 @@ struct stream *stream_memory_open(struct mpv_global *global, void *data, int len
|
||||
{
|
||||
assert(len >= 0);
|
||||
|
||||
struct stream_open_args sargs = {
|
||||
.global = global,
|
||||
.url = "memory://",
|
||||
.flags = STREAM_READ | STREAM_SILENT,
|
||||
.sinfo = &stream_info_memory,
|
||||
.special_arg = &(bstr){data, len},
|
||||
};
|
||||
|
||||
struct stream *s = NULL;
|
||||
stream_create_instance(&stream_info_memory, "memory://",
|
||||
STREAM_READ | STREAM_SILENT, NULL, global,
|
||||
&(bstr){data, len}, &s);
|
||||
stream_create_with_args(&sargs, &s);
|
||||
MP_HANDLE_OOM(s);
|
||||
return s;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user