libmpv  20200718-git-96cdf53
development library for the MPV media player
Looking for a C++ dev?
I'm looking for work. Hire me!
stream_cb.h
Go to the documentation of this file.
1 /* Copyright (C) 2017 the mpv developers
2  *
3  * Permission to use, copy, modify, and/or distribute this software for any
4  * purpose with or without fee is hereby granted, provided that the above
5  * copyright notice and this permission notice appear in all copies.
6  *
7  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14  */
15 
16 #ifndef MPV_CLIENT_API_STREAM_CB_H_
17 #define MPV_CLIENT_API_STREAM_CB_H_
18 
19 #include "client.h"
20 
21 #ifdef __cplusplus
22 extern "C" {
23 #endif
24 
25 /**
26  * Warning: this API is not stable yet.
27  *
28  * Overview
29  * --------
30  *
31  * This API can be used to make mpv read from a stream with a custom
32  * implementation. This interface is inspired by funopen on BSD and
33  * fopencookie on linux. The stream is backed by user-defined callbacks
34  * which can implement customized open, read, seek, size and close behaviors.
35  *
36  * Usage
37  * -----
38  *
39  * Register your stream callbacks with the mpv_stream_cb_add_ro() function. You
40  * have to provide a mpv_stream_cb_open_ro_fn callback to it (open_fn argument).
41  *
42  * Once registered, you can `loadfile myprotocol://myfile`. Your open_fn will be
43  * invoked with the URI and you must fill out the provided mpv_stream_cb_info
44  * struct. This includes your stream callbacks (like read_fn), and an opaque
45  * cookie, which will be passed as the first argument to all the remaining
46  * stream callbacks.
47  *
48  * Note that your custom callbacks must not invoke libmpv APIs as that would
49  * cause a deadlock. (Unless you call a different mpv_handle than the one the
50  * callback was registered for, and the mpv_handles refer to different mpv
51  * instances.)
52  *
53  * Stream lifetime
54  * ---------------
55  *
56  * A stream remains valid until its close callback has been called. It's up to
57  * libmpv to call the close callback, and the libmpv user cannot close it
58  * directly with the stream_cb API.
59  *
60  * For example, if you consider your custom stream to become suddenly invalid
61  * (maybe because the underlying stream died), libmpv will continue using your
62  * stream. All you can do is returning errors from each callback, until libmpv
63  * gives up and closes it.
64  *
65  * Protocol registration and lifetime
66  * ----------------------------------
67  *
68  * Protocols remain registered until the mpv instance is terminated. This means
69  * in particular that it can outlive the mpv_handle that was used to register
70  * it, but once mpv_terminate_destroy() is called, your registered callbacks
71  * will not be called again.
72  *
73  * Protocol unregistration is finished after the mpv core has been destroyed
74  * (e.g. after mpv_terminate_destroy() has returned).
75  *
76  * If you do not call mpv_terminate_destroy() yourself (e.g. plugin-style code),
77  * you will have to deal with the registration or even streams outliving your
78  * code. Here are some possible ways to do this:
79  * - call mpv_terminate_destroy(), which destroys the core, and will make sure
80  * all streams are closed once this function returns
81  * - you refcount all resources your stream "cookies" reference, so that it
82  * doesn't matter if streams live longer than expected
83  * - create "cancellation" semantics: after your protocol has been unregistered,
84  * notify all your streams that are still opened, and make them drop all
85  * referenced resources - then return errors from the stream callbacks as
86  * long as the stream is still opened
87  *
88  */
89 
90 /**
91  * Read callback used to implement a custom stream. The semantics of the
92  * callback match read(2) in blocking mode. Short reads are allowed (you can
93  * return less bytes than requested, and libmpv will retry reading the rest
94  * with another call). If no data can be immediately read, the callback must
95  * block until there is new data. A return of 0 will be interpreted as final
96  * EOF, although libmpv might retry the read, or seek to a different position.
97  *
98  * @param cookie opaque cookie identifying the stream,
99  * returned from mpv_stream_cb_open_fn
100  * @param buf buffer to read data into
101  * @param size of the buffer
102  * @return number of bytes read into the buffer
103  * @return 0 on EOF
104  * @return -1 on error
105  */
106 typedef int64_t (*mpv_stream_cb_read_fn)(void *cookie, char *buf, uint64_t nbytes);
107 
108 /**
109  * Seek callback used to implement a custom stream.
110  *
111  * Note that mpv will issue a seek to position 0 immediately after opening. This
112  * is used to test whether the stream is seekable (since seekability might
113  * depend on the URI contents, not just the protocol). Return
114  * MPV_ERROR_UNSUPPORTED if seeking is not implemented for this stream. This
115  * seek also serves to establish the fact that streams start at position 0.
116  *
117  * This callback can be NULL, in which it behaves as if always returning
118  * MPV_ERROR_UNSUPPORTED.
119  *
120  * @param cookie opaque cookie identifying the stream,
121  * returned from mpv_stream_cb_open_fn
122  * @param offset target absolut stream position
123  * @return the resulting offset of the stream
124  * MPV_ERROR_UNSUPPORTED or MPV_ERROR_GENERIC if the seek failed
125  */
126 typedef int64_t (*mpv_stream_cb_seek_fn)(void *cookie, int64_t offset);
127 
128 /**
129  * Size callback used to implement a custom stream.
130  *
131  * Return MPV_ERROR_UNSUPPORTED if no size is known.
132  *
133  * This callback can be NULL, in which it behaves as if always returning
134  * MPV_ERROR_UNSUPPORTED.
135  *
136  * @param cookie opaque cookie identifying the stream,
137  * returned from mpv_stream_cb_open_fn
138  * @return the total size in bytes of the stream
139  */
140 typedef int64_t (*mpv_stream_cb_size_fn)(void *cookie);
141 
142 /**
143  * Close callback used to implement a custom stream.
144  *
145  * @param cookie opaque cookie identifying the stream,
146  * returned from mpv_stream_cb_open_fn
147  */
148 typedef void (*mpv_stream_cb_close_fn)(void *cookie);
149 
150 /**
151  * Cancel callback used to implement a custom stream.
152  *
153  * This callback is used to interrupt any current or future read and seek
154  * operations. It will be called from a separate thread than the demux
155  * thread, and should not block.
156  *
157  * This callback can be NULL.
158  *
159  * Available since API 1.106.
160  *
161  * @param cookie opaque cookie identifying the stream,
162  * returned from mpv_stream_cb_open_fn
163  */
164 typedef void (*mpv_stream_cb_cancel_fn)(void *cookie);
165 
166 /**
167  * See mpv_stream_cb_open_ro_fn callback.
168  */
169 typedef struct mpv_stream_cb_info {
170  /**
171  * Opaque user-provided value, which will be passed to the other callbacks.
172  * The close callback will be called to release the cookie. It is not
173  * interpreted by mpv. It doesn't even need to be a valid pointer.
174  *
175  * The user sets this in the mpv_stream_cb_open_ro_fn callback.
176  */
177  void *cookie;
178 
179  /**
180  * Callbacks set by the user in the mpv_stream_cb_open_ro_fn callback. Some
181  * of them are optional, and can be left unset.
182  *
183  * The following callbacks are mandatory: read_fn, close_fn
184  */
189  mpv_stream_cb_cancel_fn cancel_fn; /* since API 1.106 */
191 
192 /**
193  * Open callback used to implement a custom read-only (ro) stream. The user
194  * must set the callback fields in the passed info struct. The cookie field
195  * also can be set to store state associated to the stream instance.
196  *
197  * Note that the info struct is valid only for the duration of this callback.
198  * You can't change the callbacks or the pointer to the cookie at a later point.
199  *
200  * Each stream instance created by the open callback can have different
201  * callbacks.
202  *
203  * The close_fn callback will terminate the stream instance. The pointers to
204  * your callbacks and cookie will be discarded, and the callbacks will not be
205  * called again.
206  *
207  * @param user_data opaque user data provided via mpv_stream_cb_add()
208  * @param uri name of the stream to be opened (with protocol prefix)
209  * @param info fields which the user should fill
210  * @return 0 on success, MPV_ERROR_LOADING_FAILED if the URI cannot be opened.
211  */
212 typedef int (*mpv_stream_cb_open_ro_fn)(void *user_data, char *uri,
213  mpv_stream_cb_info *info);
214 
215 /**
216  * Add a custom stream protocol. This will register a protocol handler under
217  * the given protocol prefix, and invoke the given callbacks if an URI with the
218  * matching protocol prefix is opened.
219  *
220  * The "ro" is for read-only - only read-only streams can be registered with
221  * this function.
222  *
223  * The callback remains registered until the mpv core is registered.
224  *
225  * If a custom stream with the same name is already registered, then the
226  * MPV_ERROR_INVALID_PARAMETER error is returned.
227  *
228  * @param protocol protocol prefix, for example "foo" for "foo://" URIs
229  * @param user_data opaque pointer passed into the mpv_stream_cb_open_fn
230  * callback.
231  * @return error code
232  */
233 int mpv_stream_cb_add_ro(mpv_handle *ctx, const char *protocol, void *user_data,
234  mpv_stream_cb_open_ro_fn open_fn);
235 
236 #ifdef __cplusplus
237 }
238 #endif
239 
240 #endif
mpv_stream_cb_close_fn
void(* mpv_stream_cb_close_fn)(void *cookie)
Close callback used to implement a custom stream.
Definition: stream_cb.h:148
mpv_stream_cb_seek_fn
int64_t(* mpv_stream_cb_seek_fn)(void *cookie, int64_t offset)
Seek callback used to implement a custom stream.
Definition: stream_cb.h:126
mpv_stream_cb_open_ro_fn
int(* mpv_stream_cb_open_ro_fn)(void *user_data, char *uri, mpv_stream_cb_info *info)
Open callback used to implement a custom read-only (ro) stream.
Definition: stream_cb.h:212
mpv_stream_cb_read_fn
int64_t(* mpv_stream_cb_read_fn)(void *cookie, char *buf, uint64_t nbytes)
Warning: this API is not stable yet.
Definition: stream_cb.h:106
mpv_stream_cb_info::close_fn
mpv_stream_cb_close_fn close_fn
Definition: stream_cb.h:188
mpv_stream_cb_info::cancel_fn
mpv_stream_cb_cancel_fn cancel_fn
Definition: stream_cb.h:189
mpv_stream_cb_add_ro
int mpv_stream_cb_add_ro(mpv_handle *ctx, const char *protocol, void *user_data, mpv_stream_cb_open_ro_fn open_fn)
Add a custom stream protocol.
mpv_stream_cb_info::seek_fn
mpv_stream_cb_seek_fn seek_fn
Definition: stream_cb.h:186
mpv_stream_cb_info::size_fn
mpv_stream_cb_size_fn size_fn
Definition: stream_cb.h:187
mpv_handle
struct mpv_handle mpv_handle
Client context used by the client API.
Definition: client.h:256
mpv_stream_cb_size_fn
int64_t(* mpv_stream_cb_size_fn)(void *cookie)
Size callback used to implement a custom stream.
Definition: stream_cb.h:140
mpv_stream_cb_cancel_fn
void(* mpv_stream_cb_cancel_fn)(void *cookie)
Cancel callback used to implement a custom stream.
Definition: stream_cb.h:164
mpv_stream_cb_info
struct mpv_stream_cb_info mpv_stream_cb_info
See mpv_stream_cb_open_ro_fn callback.
mpv_stream_cb_info::read_fn
mpv_stream_cb_read_fn read_fn
Callbacks set by the user in the mpv_stream_cb_open_ro_fn callback.
Definition: stream_cb.h:185
mpv_stream_cb_info::cookie
void * cookie
Opaque user-provided value, which will be passed to the other callbacks.
Definition: stream_cb.h:177
mpv_stream_cb_info
See mpv_stream_cb_open_ro_fn callback.
Definition: stream_cb.h:169
client.h