diff --git a/meson.build b/meson.build
index a3435b255b..b848cb4985 100644
--- a/meson.build
+++ b/meson.build
@@ -199,6 +199,7 @@ sources = files(
'stream/stream_mpv.c',
'stream/stream_null.c',
'stream/stream_slice.c',
+ 'stream/stream_bstr.c',
## Subtitles
'sub/ass_mp.c',
diff --git a/stream/stream_bstr.c b/stream/stream_bstr.c
new file mode 100644
index 0000000000..c09a1c7ee6
--- /dev/null
+++ b/stream/stream_bstr.c
@@ -0,0 +1,61 @@
+/*
+ * This file is part of mpv.
+ *
+ * mpv is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * mpv is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with mpv. If not, see .
+ */
+
+#include "stream_bstr.h"
+#include "common/common.h"
+
+struct priv {
+ bstr data;
+};
+
+static int bs_fill_buffer(stream_t *s, void *buffer, int len)
+{
+ struct priv *p = s->priv;
+ bstr data = p->data;
+ if (s->pos < 0 || s->pos > data.len)
+ return 0;
+ len = MPMIN(len, data.len - s->pos);
+ memcpy(buffer, data.start + s->pos, len);
+ return len;
+}
+
+static int bs_seek(stream_t *s, int64_t newpos)
+{
+ return 1;
+}
+
+static int64_t bs_get_size(stream_t *s)
+{
+ struct priv *p = s->priv;
+ return p->data.len;
+}
+
+int stream_bstr_open2(stream_t *s, const struct stream_open_args *args, bstr data)
+{
+ s->fill_buffer = bs_fill_buffer;
+ s->seek = bs_seek;
+ s->seekable = true;
+ s->get_size = bs_get_size;
+
+ struct priv *p = talloc_zero(s, struct priv);
+ s->priv = p;
+
+ ta_set_parent(data.start, p);
+ p->data = data;
+
+ return STREAM_OK;
+}
diff --git a/stream/stream_bstr.h b/stream/stream_bstr.h
new file mode 100644
index 0000000000..cb931c72a5
--- /dev/null
+++ b/stream/stream_bstr.h
@@ -0,0 +1,23 @@
+/*
+ * This file is part of mpv.
+ *
+ * mpv is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * mpv is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with mpv. If not, see .
+ */
+
+#include "misc/bstr.h"
+#include "stream.h"
+
+// Takes ownership of data.
+int stream_bstr_open2(stream_t *stream, const struct stream_open_args *args,
+ bstr data);
diff --git a/stream/stream_memory.c b/stream/stream_memory.c
index 0d8800e672..7571d644f7 100644
--- a/stream/stream_memory.c
+++ b/stream/stream_memory.c
@@ -16,44 +16,10 @@
*/
#include "common/common.h"
-#include "stream.h"
-
-struct priv {
- bstr data;
-};
-
-static int fill_buffer(stream_t *s, void *buffer, int len)
-{
- struct priv *p = s->priv;
- bstr data = p->data;
- if (s->pos < 0 || s->pos > data.len)
- return 0;
- len = MPMIN(len, data.len - s->pos);
- memcpy(buffer, data.start + s->pos, len);
- return len;
-}
-
-static int seek(stream_t *s, int64_t newpos)
-{
- return 1;
-}
-
-static int64_t get_size(stream_t *s)
-{
- struct priv *p = s->priv;
- return p->data.len;
-}
+#include "stream_bstr.h"
static int open2(stream_t *stream, const struct stream_open_args *args)
{
- stream->fill_buffer = fill_buffer;
- stream->seek = seek;
- stream->seekable = true;
- stream->get_size = get_size;
-
- struct priv *p = talloc_zero(stream, struct priv);
- stream->priv = p;
-
// Initial data
bstr data = bstr0(stream->url);
bool use_hex = bstr_eatstart0(&data, "hex://");
@@ -63,14 +29,14 @@ static int open2(stream_t *stream, const struct stream_open_args *args)
if (args->special_arg)
data = *(bstr *)args->special_arg;
- p->data = bstrdup(stream, data);
+ data = bstrdup(stream, data);
- if (use_hex && !bstr_decode_hex(stream, p->data, &p->data)) {
+ if (use_hex && !bstr_decode_hex(stream, data, &data)) {
MP_FATAL(stream, "Invalid data.\n");
return STREAM_ERROR;
}
- return STREAM_OK;
+ return stream_bstr_open2(stream, args, data);
}
const stream_info_t stream_info_memory = {