Coverage Report

Created: 2026-05-16 07:24

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/mpv/stream/stream.h
Line
Count
Source
1
/*
2
 * This file is part of mpv.
3
 *
4
 * mpv is free software; you can redistribute it and/or
5
 * modify it under the terms of the GNU Lesser General Public
6
 * License as published by the Free Software Foundation; either
7
 * version 2.1 of the License, or (at your option) any later version.
8
 *
9
 * mpv is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU Lesser General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU Lesser General Public
15
 * License along with mpv.  If not, see <http://www.gnu.org/licenses/>.
16
 */
17
18
#ifndef MPLAYER_STREAM_H
19
#define MPLAYER_STREAM_H
20
21
#include "common/msg.h"
22
#include <stdbool.h>
23
#include <stdio.h>
24
#include <string.h>
25
#include <inttypes.h>
26
#include <sys/types.h>
27
#include <fcntl.h>
28
29
#include "misc/bstr.h"
30
31
// Minimum guaranteed buffer and seek-back size. For any reads <= of this size,
32
// it's guaranteed that you can seek back by <= of this size again.
33
192k
#define STREAM_BUFFER_SIZE 2048
34
35
// Maximum size of a complete read.
36
35.4k
#define STREAM_MAX_READ_SIZE (INT_MAX - 1)
37
38
// flags for stream_open_ext (this includes STREAM_READ and STREAM_WRITE)
39
40
// stream->mode
41
684k
#define STREAM_READ               0
42
1.64M
#define STREAM_WRITE              (1 << 0)
43
44
536k
#define STREAM_SILENT             (1 << 1)
45
46
// Origin value for "security". This is an integer within the flags bit-field.
47
755k
#define STREAM_ORIGIN_DIRECT      (1 << 2) // passed from cmdline or loadfile
48
61.1k
#define STREAM_ORIGIN_FS          (2 << 2) // referenced from playlist on unix FS
49
73.9k
#define STREAM_ORIGIN_NET         (3 << 2) // referenced from playlist on network
50
108k
#define STREAM_ORIGIN_UNSAFE      (4 << 2) // from a grotesque source
51
52
354k
#define STREAM_ORIGIN_MASK        (7 << 2) // for extracting origin value from flags
53
54
1.56M
#define STREAM_LOCAL_FS_ONLY      (1 << 5) // stream_file only, no URLs
55
354k
#define STREAM_LESS_NOISE         (1 << 6) // try to log errors only
56
354k
#define STREAM_ALLOW_PARTIAL_READ (1 << 7) // allows partial read with stream_read_file()
57
58
// Default flags used by stream_read_file().
59
#define STREAM_READ_FILE_FLAGS_DEFAULT \
60
0
    (STREAM_ORIGIN_DIRECT | STREAM_READ | STREAM_LOCAL_FS_ONLY | STREAM_LESS_NOISE)
61
62
// end flags for stream_open_ext (the naming convention sucks)
63
64
81.3k
#define STREAM_UNSAFE -3
65
3.93M
#define STREAM_NO_MATCH -2
66
6.75M
#define STREAM_UNSUPPORTED -1
67
29.4k
#define STREAM_ERROR 0
68
2.30M
#define STREAM_OK    1
69
70
// EOF value returned by stream_read_char()
71
3.39M
#define STREAM_EOF (-256)
72
73
enum stream_ctrl {
74
    // Certain network protocols
75
    STREAM_CTRL_AVSEEK,
76
    STREAM_CTRL_HAS_AVSEEK,
77
    STREAM_CTRL_GET_METADATA,
78
79
    // Optical discs (internal interface between streams and demux_disc)
80
    STREAM_CTRL_GET_TIME_LENGTH,
81
    STREAM_CTRL_GET_DVD_INFO,
82
    STREAM_CTRL_GET_DISC_NAME,
83
    STREAM_CTRL_GET_NUM_CHAPTERS,
84
    STREAM_CTRL_GET_CURRENT_TIME,
85
    STREAM_CTRL_GET_CHAPTER_TIME,
86
    STREAM_CTRL_SEEK_TO_TIME,
87
    STREAM_CTRL_GET_ASPECT_RATIO,
88
    STREAM_CTRL_GET_NUM_ANGLES,
89
    STREAM_CTRL_GET_ANGLE,
90
    STREAM_CTRL_SET_ANGLE,
91
    STREAM_CTRL_GET_NUM_TITLES,
92
    STREAM_CTRL_GET_TITLE_LENGTH,    // double* (in: title number, out: len)
93
    STREAM_CTRL_GET_TITLE_PLAYLIST,  // double* (in: title number, out: playlist)
94
    STREAM_CTRL_GET_LANG,
95
    STREAM_CTRL_GET_CURRENT_TITLE,
96
    STREAM_CTRL_SET_CURRENT_TITLE,
97
};
98
99
struct stream_lang_req {
100
    int type;     // STREAM_AUDIO, STREAM_SUB
101
    int id;
102
    char name[50];
103
};
104
105
struct stream_dvd_info_req {
106
    unsigned int palette[16];
107
    int num_subs;
108
};
109
110
// for STREAM_CTRL_AVSEEK
111
struct stream_avseek {
112
    int stream_index;
113
    int64_t timestamp;
114
    int flags;
115
};
116
117
struct stream;
118
struct stream_open_args;
119
typedef struct stream_info_st {
120
    const char *name;
121
    // opts is set from ->opts
122
    int (*open)(struct stream *st);
123
    // Alternative to open(). Only either open() or open2() can be set.
124
    int (*open2)(struct stream *st, const struct stream_open_args *args);
125
    const char *const *protocols;
126
    // Alternative to protocols. For stream_lavf.
127
    char **(*get_protocols)(void);
128
    bool can_write;     // correctly checks for READ/WRITE modes
129
    bool local_fs;      // supports STREAM_LOCAL_FS_ONLY
130
    int stream_origin;  // 0 or set of STREAM_ORIGIN_*; if 0, the same origin
131
                        // is set, or the stream's open() function handles it
132
} stream_info_t;
133
134
typedef struct stream {
135
    const struct stream_info_st *info;
136
137
    // Read
138
    int (*fill_buffer)(struct stream *s, void *buffer, int max_len);
139
    // Write
140
    int (*write_buffer)(struct stream *s, void *buffer, int len);
141
    // Seek
142
    int (*seek)(struct stream *s, int64_t pos);
143
    // Total stream size in bytes (negative if unavailable)
144
    int64_t (*get_size)(struct stream *s);
145
    // Control
146
    int (*control)(struct stream *s, int cmd, void *arg);
147
    // Close
148
    void (*close)(struct stream *s);
149
150
    int64_t pos;
151
    int eof; // valid only after read calls that returned a short result
152
    int mode; //STREAM_READ or STREAM_WRITE
153
    int stream_origin; // any STREAM_ORIGIN_*
154
    void *priv; // used for DVD, TV, RTSP etc
155
    char *url;  // filename/url (possibly including protocol prefix)
156
    char *path; // filename (url without protocol prefix)
157
    char *mime_type; // when HTTP streaming is used
158
    char *demuxer; // request demuxer to be used
159
    char *lavf_type; // name of expected demuxer type for lavf
160
    bool streaming : 1; // known to be a network stream if true
161
    bool seekable : 1; // presence of general byte seeking support
162
    bool fast_skip : 1; // consider stream fast enough to fw-seek by skipping
163
    bool is_network : 1; // I really don't know what this is for
164
    bool is_local_fs : 1; // from the filesystem
165
    bool is_directory : 1; // directory on the filesystem
166
    bool is_regular : 1; // regular file
167
    bool access_references : 1; // open other streams
168
    bool allow_partial_read : 1; // allows partial read with stream_read_file()
169
    struct mp_log *log;
170
    struct mpv_global *global;
171
172
    struct mp_cancel *cancel;   // cancellation notification
173
174
    // Read statistic for fill_buffer calls. All bytes read by fill_buffer() are
175
    // added to this. The user can reset this as needed.
176
    uint64_t total_unbuffered_read_bytes;
177
    // Seek statistics. The user can reset this as needed.
178
    uint64_t total_stream_seeks;
179
180
    // Buffer size requested by user; s->buffer may have a different size
181
    int requested_buffer_size;
182
183
    // This is a ring buffer. It is reset only on seeks (or when buffers are
184
    // dropped). Otherwise old contents always stay valid.
185
    // The valid buffer is from buf_start to buf_end; buf_end can be larger
186
    // than the buffer size (requires wrap around). buf_cur is a value in the
187
    // range [buf_start, buf_end].
188
    // When reading more data from the stream, buf_start is advanced as old
189
    // data is overwritten with new data.
190
    // Example:
191
    //    0  1  2  3    4  5  6  7    8  9  10 11   12 13 14 15
192
    //  +===========================+---------------------------+
193
    //  + 05 06 07 08 | 01 02 03 04 + 05 06 07 08 | 01 02 03 04 +
194
    //  +===========================+---------------------------+
195
    //                  ^ buf_start (4)  |          |
196
    //                                   |          ^ buf_end (12 % 8 => 4)
197
    //                                   ^ buf_cur (9 % 8 => 1)
198
    // Here, the entire 8 byte buffer is filled, i.e. buf_end - buf_start = 8.
199
    // buffer_mask == 7, so (x & buffer_mask) == (x % buffer_size)
200
    unsigned int buf_start; // index of oldest byte in buffer (is <= buffer_mask)
201
    unsigned int buf_cur;   // current read pos (can be > buffer_mask)
202
    unsigned int buf_end;   // end position (can be > buffer_mask)
203
204
    unsigned int buffer_mask; // buffer_size-1, where buffer_size == 2**n
205
    uint8_t *buffer;
206
} stream_t;
207
208
// Non-inline version of stream_read_char().
209
int stream_read_char_fallback(stream_t *s);
210
211
int stream_write_buffer(stream_t *s, void *buf, int len);
212
213
inline static int stream_read_char(stream_t *s)
214
88.5M
{
215
88.5M
    return s->buf_cur < s->buf_end
216
88.5M
        ? s->buffer[(s->buf_cur++) & s->buffer_mask]
217
88.5M
        : stream_read_char_fallback(s);
218
88.5M
}
Unexecuted instantiation: client.c:stream_read_char
Unexecuted instantiation: command.c:stream_read_char
Unexecuted instantiation: configfiles.c:stream_read_char
Unexecuted instantiation: loadfile.c:stream_read_char
Unexecuted instantiation: misc.c:stream_read_char
Unexecuted instantiation: osd.c:stream_read_char
Unexecuted instantiation: playloop.c:stream_read_char
Unexecuted instantiation: screenshot.c:stream_read_char
Unexecuted instantiation: sub.c:stream_read_char
Unexecuted instantiation: video.c:stream_read_char
Unexecuted instantiation: stream.c:stream_read_char
Unexecuted instantiation: stream_avdevice.c:stream_read_char
Unexecuted instantiation: stream_cb.c:stream_read_char
Unexecuted instantiation: stream_edl.c:stream_read_char
Unexecuted instantiation: stream_file.c:stream_read_char
Unexecuted instantiation: stream_lavf.c:stream_read_char
Unexecuted instantiation: stream_memory.c:stream_read_char
Unexecuted instantiation: stream_mf.c:stream_read_char
Unexecuted instantiation: stream_mpv.c:stream_read_char
Unexecuted instantiation: stream_null.c:stream_read_char
Unexecuted instantiation: stream_slice.c:stream_read_char
Unexecuted instantiation: vo_gpu_next.c:stream_read_char
Unexecuted instantiation: stream_dvb.c:stream_read_char
Unexecuted instantiation: utils.c:stream_read_char
Unexecuted instantiation: encode_lavc.c:stream_read_char
Unexecuted instantiation: playlist.c:stream_read_char
Unexecuted instantiation: demux.c:stream_read_char
Unexecuted instantiation: demux_cue.c:stream_read_char
Unexecuted instantiation: demux_disc.c:stream_read_char
Unexecuted instantiation: demux_edl.c:stream_read_char
Unexecuted instantiation: demux_lavf.c:stream_read_char
Unexecuted instantiation: demux_mf.c:stream_read_char
demux_mkv.c:stream_read_char
Line
Count
Source
214
868k
{
215
868k
    return s->buf_cur < s->buf_end
216
868k
        ? s->buffer[(s->buf_cur++) & s->buffer_mask]
217
868k
        : stream_read_char_fallback(s);
218
868k
}
Unexecuted instantiation: demux_mkv_timeline.c:stream_read_char
Unexecuted instantiation: demux_mpv.c:stream_read_char
Unexecuted instantiation: demux_null.c:stream_read_char
demux_playlist.c:stream_read_char
Line
Count
Source
214
2.54M
{
215
2.54M
    return s->buf_cur < s->buf_end
216
2.54M
        ? s->buffer[(s->buf_cur++) & s->buffer_mask]
217
2.54M
        : stream_read_char_fallback(s);
218
2.54M
}
Unexecuted instantiation: demux_raw.c:stream_read_char
Unexecuted instantiation: demux_timeline.c:stream_read_char
ebml.c:stream_read_char
Line
Count
Source
214
85.0M
{
215
85.0M
    return s->buf_cur < s->buf_end
216
85.0M
        ? s->buffer[(s->buf_cur++) & s->buffer_mask]
217
85.0M
        : stream_read_char_fallback(s);
218
85.0M
}
Unexecuted instantiation: packet.c:stream_read_char
Unexecuted instantiation: timeline.c:stream_read_char
Unexecuted instantiation: input.c:stream_read_char
Unexecuted instantiation: options.c:stream_read_char
Unexecuted instantiation: parse_configfile.c:stream_read_char
Unexecuted instantiation: cookies.c:stream_read_char
Unexecuted instantiation: stream_concat.c:stream_read_char
Unexecuted instantiation: ass_mp.c:stream_read_char
Unexecuted instantiation: dvb_tune.c:stream_read_char
Unexecuted instantiation: lcms.c:stream_read_char
Unexecuted instantiation: shader_cache.c:stream_read_char
219
220
int stream_skip_bom(struct stream *s);
221
222
inline static int64_t stream_tell(stream_t *s)
223
19.8M
{
224
19.8M
    return s->pos + s->buf_cur - s->buf_end;
225
19.8M
}
Unexecuted instantiation: client.c:stream_tell
Unexecuted instantiation: command.c:stream_tell
Unexecuted instantiation: configfiles.c:stream_tell
Unexecuted instantiation: loadfile.c:stream_tell
Unexecuted instantiation: misc.c:stream_tell
Unexecuted instantiation: osd.c:stream_tell
Unexecuted instantiation: playloop.c:stream_tell
Unexecuted instantiation: screenshot.c:stream_tell
Unexecuted instantiation: sub.c:stream_tell
Unexecuted instantiation: video.c:stream_tell
stream.c:stream_tell
Line
Count
Source
223
7.06M
{
224
7.06M
    return s->pos + s->buf_cur - s->buf_end;
225
7.06M
}
Unexecuted instantiation: stream_avdevice.c:stream_tell
Unexecuted instantiation: stream_cb.c:stream_tell
Unexecuted instantiation: stream_edl.c:stream_tell
Unexecuted instantiation: stream_file.c:stream_tell
Unexecuted instantiation: stream_lavf.c:stream_tell
Unexecuted instantiation: stream_memory.c:stream_tell
Unexecuted instantiation: stream_mf.c:stream_tell
Unexecuted instantiation: stream_mpv.c:stream_tell
Unexecuted instantiation: stream_null.c:stream_tell
Unexecuted instantiation: stream_slice.c:stream_tell
Unexecuted instantiation: vo_gpu_next.c:stream_tell
Unexecuted instantiation: stream_dvb.c:stream_tell
Unexecuted instantiation: utils.c:stream_tell
Unexecuted instantiation: encode_lavc.c:stream_tell
Unexecuted instantiation: playlist.c:stream_tell
Unexecuted instantiation: demux.c:stream_tell
Unexecuted instantiation: demux_cue.c:stream_tell
Unexecuted instantiation: demux_disc.c:stream_tell
Unexecuted instantiation: demux_edl.c:stream_tell
demux_lavf.c:stream_tell
Line
Count
Source
223
1.55M
{
224
1.55M
    return s->pos + s->buf_cur - s->buf_end;
225
1.55M
}
demux_mf.c:stream_tell
Line
Count
Source
223
31.5k
{
224
31.5k
    return s->pos + s->buf_cur - s->buf_end;
225
31.5k
}
demux_mkv.c:stream_tell
Line
Count
Source
223
8.86M
{
224
8.86M
    return s->pos + s->buf_cur - s->buf_end;
225
8.86M
}
Unexecuted instantiation: demux_mkv_timeline.c:stream_tell
Unexecuted instantiation: demux_mpv.c:stream_tell
Unexecuted instantiation: demux_null.c:stream_tell
demux_playlist.c:stream_tell
Line
Count
Source
223
1.59M
{
224
1.59M
    return s->pos + s->buf_cur - s->buf_end;
225
1.59M
}
Unexecuted instantiation: demux_raw.c:stream_tell
Unexecuted instantiation: demux_timeline.c:stream_tell
ebml.c:stream_tell
Line
Count
Source
223
719k
{
224
719k
    return s->pos + s->buf_cur - s->buf_end;
225
719k
}
Unexecuted instantiation: packet.c:stream_tell
Unexecuted instantiation: timeline.c:stream_tell
Unexecuted instantiation: input.c:stream_tell
Unexecuted instantiation: options.c:stream_tell
Unexecuted instantiation: parse_configfile.c:stream_tell
Unexecuted instantiation: cookies.c:stream_tell
Unexecuted instantiation: stream_concat.c:stream_tell
Unexecuted instantiation: ass_mp.c:stream_tell
Unexecuted instantiation: dvb_tune.c:stream_tell
Unexecuted instantiation: lcms.c:stream_tell
Unexecuted instantiation: shader_cache.c:stream_tell
226
227
bool stream_seek_skip(stream_t *s, int64_t pos);
228
bool stream_seek(stream_t *s, int64_t pos);
229
int stream_read(stream_t *s, void *mem, int total);
230
int stream_read_partial(stream_t *s, void *buf, int buf_size);
231
int stream_peek(stream_t *s, int forward_size);
232
int stream_read_peek(stream_t *s, void *buf, int buf_size);
233
void stream_drop_buffers(stream_t *s);
234
int64_t stream_get_size(stream_t *s);
235
236
struct mpv_global;
237
238
struct bstr stream_read_complete(struct stream *s, void *talloc_ctx,
239
                                 int max_size);
240
struct bstr stream_read_file(const char *filename, void *talloc_ctx,
241
                             struct mpv_global *global, int max_size);
242
// Like stream_read_file(), but allows specifying flags like with stream_create().
243
struct bstr stream_read_file2(const char *filename, void *talloc_ctx,
244
                              int flags, struct mpv_global *global, int max_size);
245
246
int stream_control(stream_t *s, int cmd, void *arg);
247
void free_stream(stream_t *s);
248
249
struct stream_open_args {
250
    struct mpv_global *global;
251
    struct mp_cancel *cancel;   // aborting stream access (used directly)
252
    const char *url;
253
    int flags;                  // STREAM_READ etc.
254
    const stream_info_t *sinfo; // NULL = autoprobe, otherwise force stream impl.
255
    void *special_arg;          // specific to impl., use only with sinfo
256
};
257
258
int stream_create_with_args(struct stream_open_args *args, struct stream **ret);
259
struct stream *stream_create(const char *url, int flags,
260
                             struct mp_cancel *c, struct mpv_global *global);
261
stream_t *open_output_stream(const char *filename, struct mpv_global *global);
262
263
void mp_url_unescape_inplace(char *buf);
264
char *mp_url_unescape(void *talloc_ctx, const char *url);
265
char *mp_url_escape(void *talloc_ctx, const char *s, const char *ok);
266
267
// stream_memory.c
268
struct stream *stream_memory_open(struct mpv_global *global, void *data, int len);
269
270
// stream_concat.c
271
struct stream *stream_concat_open(struct mpv_global *global, struct mp_cancel *c,
272
                                  struct stream **streams, int num_streams);
273
274
// stream_file.c
275
char *mp_file_url_to_filename(void *talloc_ctx, bstr url);
276
char *mp_file_get_path(void *talloc_ctx, bstr url);
277
278
// stream_lavf.c
279
struct AVDictionary;
280
void mp_setup_av_network_options(struct AVDictionary **dict,
281
                                 const char *target_fmt,
282
                                 struct mpv_global *global,
283
                                 struct mp_log *log);
284
285
void stream_print_proto_list(struct mp_log *log);
286
char **stream_get_proto_list(bool safe_only);
287
bool stream_has_proto(const char *proto);
288
289
#endif /* MPLAYER_STREAM_H */