diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 20:36:56 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 20:36:56 +0000 |
commit | 51de1d8436100f725f3576aefa24a2bd2057bc28 (patch) | |
tree | c6d1d5264b6d40a8d7ca34129f36b7d61e188af3 /stream/stream_cb.c | |
parent | Initial commit. (diff) | |
download | mpv-51de1d8436100f725f3576aefa24a2bd2057bc28.tar.xz mpv-51de1d8436100f725f3576aefa24a2bd2057bc28.zip |
Adding upstream version 0.37.0.upstream/0.37.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'stream/stream_cb.c')
-rw-r--r-- | stream/stream_cb.c | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/stream/stream_cb.c b/stream/stream_cb.c new file mode 100644 index 0000000..29e5563 --- /dev/null +++ b/stream/stream_cb.c @@ -0,0 +1,108 @@ +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <errno.h> + +#include "osdep/io.h" + +#include "common/common.h" +#include "common/msg.h" +#include "common/global.h" +#include "stream.h" +#include "options/m_option.h" +#include "options/path.h" +#include "player/client.h" +#include "libmpv/stream_cb.h" +#include "misc/thread_tools.h" + +struct priv { + mpv_stream_cb_info info; + struct mp_cancel *cancel; +}; + +static int fill_buffer(stream_t *s, void *buffer, int max_len) +{ + struct priv *p = s->priv; + return (int)p->info.read_fn(p->info.cookie, buffer, (size_t)max_len); +} + +static int seek(stream_t *s, int64_t newpos) +{ + struct priv *p = s->priv; + return p->info.seek_fn(p->info.cookie, newpos) >= 0; +} + +static int64_t get_size(stream_t *s) +{ + struct priv *p = s->priv; + + if (p->info.size_fn) { + int64_t size = p->info.size_fn(p->info.cookie); + if (size >= 0) + return size; + } + + return -1; +} + +static void s_close(stream_t *s) +{ + struct priv *p = s->priv; + p->info.close_fn(p->info.cookie); +} + +static int open_cb(stream_t *stream) +{ + struct priv *p = talloc_ptrtype(stream, p); + stream->priv = p; + + bstr bproto = mp_split_proto(bstr0(stream->url), NULL); + char *proto = bstrto0(stream, bproto); + + void *user_data; + mpv_stream_cb_open_ro_fn open_fn; + + if (!mp_streamcb_lookup(stream->global, proto, &user_data, &open_fn)) + return STREAM_UNSUPPORTED; + + mpv_stream_cb_info info = {0}; + + int r = open_fn(user_data, stream->url, &info); + if (r < 0) { + if (r != MPV_ERROR_LOADING_FAILED) + MP_WARN(stream, "unknown error from user callback\n"); + return STREAM_ERROR; + } + + if (!info.read_fn || !info.close_fn) { + MP_FATAL(stream, "required read_fn or close_fn callbacks not set.\n"); + return STREAM_ERROR; + } + + p->info = info; + + if (p->info.seek_fn && p->info.seek_fn(p->info.cookie, 0) >= 0) { + stream->seek = seek; + stream->seekable = true; + } + stream->fast_skip = true; + stream->fill_buffer = fill_buffer; + stream->get_size = get_size; + stream->close = s_close; + + if (p->info.cancel_fn && stream->cancel) { + p->cancel = mp_cancel_new(p); + mp_cancel_set_parent(p->cancel, stream->cancel); + mp_cancel_set_cb(p->cancel, p->info.cancel_fn, p->info.cookie); + } + + return STREAM_OK; +} + +const stream_info_t stream_info_cb = { + .name = "stream_callback", + .open = open_cb, + .stream_origin = STREAM_ORIGIN_UNSAFE, +}; |