1
0
mirror of https://github.com/mpv-player/mpv synced 2025-01-06 07:00:30 +00:00
mpv/stream/stream_memory.c
wm4 2bb5ab07b7 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.)
2019-09-29 00:46:54 +02:00

106 lines
2.7 KiB
C

/*
* 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 <http://www.gnu.org/licenses/>.
*/
#include <libavutil/common.h>
#include "common/common.h"
#include "stream.h"
struct priv {
bstr data;
};
static int fill_buffer(stream_t *s, char* buffer, int len)
{
struct priv *p = s->priv;
bstr data = p->data;
if (s->pos < 0 || s->pos > data.len)
return 0;
len = FFMIN(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 int control(stream_t *s, int cmd, void *arg)
{
struct priv *p = s->priv;
if (cmd == STREAM_CTRL_GET_SIZE) {
*(int64_t *)arg = p->data.len;
return 1;
}
return STREAM_UNSUPPORTED;
}
static int open2(stream_t *stream, struct stream_open_args *args)
{
stream->fill_buffer = fill_buffer;
stream->seek = seek;
stream->seekable = true;
stream->control = control;
stream->read_chunk = 1024 * 1024;
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://");
if (!use_hex)
bstr_eatstart0(&data, "memory://");
if (args->special_arg)
data = *(bstr *)args->special_arg;
p->data = bstrdup(stream, data);
if (use_hex && !bstr_decode_hex(stream, p->data, &p->data)) {
MP_FATAL(stream, "Invalid data.\n");
return STREAM_ERROR;
}
return STREAM_OK;
}
const stream_info_t stream_info_memory = {
.name = "memory",
.open2 = open2,
.protocols = (const char*const[]){ "memory", "hex", NULL },
};
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_with_args(&sargs, &s);
MP_HANDLE_OOM(s);
return s;
}