summaryrefslogtreecommitdiffstats
path: root/stream/stream.h
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 20:36:56 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 20:36:56 +0000
commit51de1d8436100f725f3576aefa24a2bd2057bc28 (patch)
treec6d1d5264b6d40a8d7ca34129f36b7d61e188af3 /stream/stream.h
parentInitial commit. (diff)
downloadmpv-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.h')
-rw-r--r--stream/stream.h269
1 files changed, 269 insertions, 0 deletions
diff --git a/stream/stream.h b/stream/stream.h
new file mode 100644
index 0000000..423ba12
--- /dev/null
+++ b/stream/stream.h
@@ -0,0 +1,269 @@
+/*
+ * 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/>.
+ */
+
+#ifndef MPLAYER_STREAM_H
+#define MPLAYER_STREAM_H
+
+#include "common/msg.h"
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+#include <sys/types.h>
+#include <fcntl.h>
+
+#include "misc/bstr.h"
+
+// Minimum guaranteed buffer and seek-back size. For any reads <= of this size,
+// it's guaranteed that you can seek back by <= of this size again.
+#define STREAM_BUFFER_SIZE 2048
+
+// flags for stream_open_ext (this includes STREAM_READ and STREAM_WRITE)
+
+// stream->mode
+#define STREAM_READ 0
+#define STREAM_WRITE (1 << 0)
+
+#define STREAM_SILENT (1 << 1)
+
+// Origin value for "security". This is an integer within the flags bit-field.
+#define STREAM_ORIGIN_DIRECT (1 << 2) // passed from cmdline or loadfile
+#define STREAM_ORIGIN_FS (2 << 2) // referenced from playlist on unix FS
+#define STREAM_ORIGIN_NET (3 << 2) // referenced from playlist on network
+#define STREAM_ORIGIN_UNSAFE (4 << 2) // from a grotesque source
+
+#define STREAM_ORIGIN_MASK (7 << 2) // for extracting origin value from flags
+
+#define STREAM_LOCAL_FS_ONLY (1 << 5) // stream_file only, no URLs
+#define STREAM_LESS_NOISE (1 << 6) // try to log errors only
+
+// end flags for stream_open_ext (the naming convention sucks)
+
+#define STREAM_UNSAFE -3
+#define STREAM_NO_MATCH -2
+#define STREAM_UNSUPPORTED -1
+#define STREAM_ERROR 0
+#define STREAM_OK 1
+
+enum stream_ctrl {
+ // Certain network protocols
+ STREAM_CTRL_AVSEEK,
+ STREAM_CTRL_HAS_AVSEEK,
+ STREAM_CTRL_GET_METADATA,
+
+ // Optical discs (internal interface between streams and demux_disc)
+ STREAM_CTRL_GET_TIME_LENGTH,
+ STREAM_CTRL_GET_DVD_INFO,
+ STREAM_CTRL_GET_DISC_NAME,
+ STREAM_CTRL_GET_NUM_CHAPTERS,
+ STREAM_CTRL_GET_CURRENT_TIME,
+ STREAM_CTRL_GET_CHAPTER_TIME,
+ STREAM_CTRL_SEEK_TO_TIME,
+ STREAM_CTRL_GET_ASPECT_RATIO,
+ STREAM_CTRL_GET_NUM_ANGLES,
+ STREAM_CTRL_GET_ANGLE,
+ STREAM_CTRL_SET_ANGLE,
+ STREAM_CTRL_GET_NUM_TITLES,
+ STREAM_CTRL_GET_TITLE_LENGTH, // double* (in: title number, out: len)
+ STREAM_CTRL_GET_LANG,
+ STREAM_CTRL_GET_CURRENT_TITLE,
+ STREAM_CTRL_SET_CURRENT_TITLE,
+};
+
+struct stream_lang_req {
+ int type; // STREAM_AUDIO, STREAM_SUB
+ int id;
+ char name[50];
+};
+
+struct stream_dvd_info_req {
+ unsigned int palette[16];
+ int num_subs;
+};
+
+// for STREAM_CTRL_AVSEEK
+struct stream_avseek {
+ int stream_index;
+ int64_t timestamp;
+ int flags;
+};
+
+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, const struct stream_open_args *args);
+ const char *const *protocols;
+ bool can_write; // correctly checks for READ/WRITE modes
+ bool local_fs; // supports STREAM_LOCAL_FS_ONLY
+ int stream_origin; // 0 or set of STREAM_ORIGIN_*; if 0, the same origin
+ // is set, or the stream's open() function handles it
+} stream_info_t;
+
+typedef struct stream {
+ const struct stream_info_st *info;
+
+ // Read
+ int (*fill_buffer)(struct stream *s, void *buffer, int max_len);
+ // Write
+ int (*write_buffer)(struct stream *s, void *buffer, int len);
+ // Seek
+ int (*seek)(struct stream *s, int64_t pos);
+ // Total stream size in bytes (negative if unavailable)
+ int64_t (*get_size)(struct stream *s);
+ // Control
+ int (*control)(struct stream *s, int cmd, void *arg);
+ // Close
+ void (*close)(struct stream *s);
+
+ int64_t pos;
+ int eof; // valid only after read calls that returned a short result
+ int mode; //STREAM_READ or STREAM_WRITE
+ int stream_origin; // any STREAM_ORIGIN_*
+ void *priv; // used for DVD, TV, RTSP etc
+ 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
+ bool streaming : 1; // known to be a network stream if true
+ bool seekable : 1; // presence of general byte seeking support
+ bool fast_skip : 1; // consider stream fast enough to fw-seek by skipping
+ bool is_network : 1; // I really don't know what this is for
+ bool is_local_file : 1; // from the filesystem
+ bool is_directory : 1; // directory on the filesystem
+ bool access_references : 1; // open other streams
+ struct mp_log *log;
+ struct mpv_global *global;
+
+ struct mp_cancel *cancel; // cancellation notification
+
+ // Read statistic for fill_buffer calls. All bytes read by fill_buffer() are
+ // added to this. The user can reset this as needed.
+ uint64_t total_unbuffered_read_bytes;
+ // Seek statistics. The user can reset this as needed.
+ uint64_t total_stream_seeks;
+
+ // Buffer size requested by user; s->buffer may have a different size
+ int requested_buffer_size;
+
+ // This is a ring buffer. It is reset only on seeks (or when buffers are
+ // dropped). Otherwise old contents always stay valid.
+ // The valid buffer is from buf_start to buf_end; buf_end can be larger
+ // than the buffer size (requires wrap around). buf_cur is a value in the
+ // range [buf_start, buf_end].
+ // When reading more data from the stream, buf_start is advanced as old
+ // data is overwritten with new data.
+ // Example:
+ // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
+ // +===========================+---------------------------+
+ // + 05 06 07 08 | 01 02 03 04 + 05 06 07 08 | 01 02 03 04 +
+ // +===========================+---------------------------+
+ // ^ buf_start (4) | |
+ // | ^ buf_end (12 % 8 => 4)
+ // ^ buf_cur (9 % 8 => 1)
+ // Here, the entire 8 byte buffer is filled, i.e. buf_end - buf_start = 8.
+ // buffer_mask == 7, so (x & buffer_mask) == (x % buffer_size)
+ unsigned int buf_start; // index of oldest byte in buffer (is <= buffer_mask)
+ unsigned int buf_cur; // current read pos (can be > buffer_mask)
+ unsigned int buf_end; // end position (can be > buffer_mask)
+
+ unsigned int buffer_mask; // buffer_size-1, where buffer_size == 2**n
+ uint8_t *buffer;
+} stream_t;
+
+// Non-inline version of stream_read_char().
+int stream_read_char_fallback(stream_t *s);
+
+int stream_write_buffer(stream_t *s, void *buf, int len);
+
+inline static int stream_read_char(stream_t *s)
+{
+ return s->buf_cur < s->buf_end
+ ? s->buffer[(s->buf_cur++) & s->buffer_mask]
+ : stream_read_char_fallback(s);
+}
+
+int stream_skip_bom(struct stream *s);
+
+inline static int64_t stream_tell(stream_t *s)
+{
+ return s->pos + s->buf_cur - s->buf_end;
+}
+
+bool stream_seek_skip(stream_t *s, int64_t pos);
+bool stream_seek(stream_t *s, int64_t pos);
+int stream_read(stream_t *s, void *mem, int total);
+int stream_read_partial(stream_t *s, void *buf, int buf_size);
+int stream_peek(stream_t *s, int forward_size);
+int stream_read_peek(stream_t *s, void *buf, int buf_size);
+void stream_drop_buffers(stream_t *s);
+int64_t stream_get_size(stream_t *s);
+
+struct mpv_global;
+
+struct bstr stream_read_complete(struct stream *s, void *talloc_ctx,
+ int max_size);
+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);
+
+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);
+stream_t *open_output_stream(const char *filename, struct mpv_global *global);
+
+void mp_url_unescape_inplace(char *buf);
+char *mp_url_escape(void *talloc_ctx, const char *s, const char *ok);
+
+// stream_memory.c
+struct stream *stream_memory_open(struct mpv_global *global, void *data, int len);
+
+// stream_concat.c
+struct stream *stream_concat_open(struct mpv_global *global, struct mp_cancel *c,
+ struct stream **streams, int num_streams);
+
+// stream_file.c
+char *mp_file_url_to_filename(void *talloc_ctx, bstr url);
+char *mp_file_get_path(void *talloc_ctx, bstr url);
+
+// stream_lavf.c
+struct AVDictionary;
+void mp_setup_av_network_options(struct AVDictionary **dict,
+ const char *target_fmt,
+ struct mpv_global *global,
+ struct mp_log *log);
+
+void stream_print_proto_list(struct mp_log *log);
+char **stream_get_proto_list(void);
+bool stream_has_proto(const char *proto);
+
+#endif /* MPLAYER_STREAM_H */