/src/vlc/include/vlc_sout.h
Line | Count | Source (jump to first uncovered line) |
1 | | /***************************************************************************** |
2 | | * vlc_sout.h : stream output module |
3 | | ***************************************************************************** |
4 | | * Copyright (C) 2002-2008 VLC authors and VideoLAN |
5 | | * |
6 | | * Authors: Christophe Massiot <massiot@via.ecp.fr> |
7 | | * Laurent Aimar <fenrir@via.ecp.fr> |
8 | | * Eric Petit <titer@videolan.org> |
9 | | * Jean-Paul Saman <jpsaman #_at_# m2x.nl> |
10 | | * Rémi Denis-Courmont |
11 | | * |
12 | | * This program is free software; you can redistribute it and/or modify it |
13 | | * under the terms of the GNU Lesser General Public License as published by |
14 | | * the Free Software Foundation; either version 2.1 of the License, or |
15 | | * (at your option) any later version. |
16 | | * |
17 | | * This program is distributed in the hope that it will be useful, |
18 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
19 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
20 | | * GNU Lesser General Public License for more details. |
21 | | * |
22 | | * You should have received a copy of the GNU Lesser General Public License |
23 | | * along with this program; if not, write to the Free Software Foundation, |
24 | | * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. |
25 | | *****************************************************************************/ |
26 | | |
27 | | #ifndef VLC_SOUT_H_ |
28 | | #define VLC_SOUT_H_ |
29 | | |
30 | | #include <sys/types.h> |
31 | | #include <vlc_es.h> |
32 | | #include <vlc_clock.h> |
33 | | #include <vlc_tick.h> |
34 | | |
35 | | #ifdef __cplusplus |
36 | | extern "C" { |
37 | | #endif |
38 | | |
39 | | /** |
40 | | * \defgroup sout Stream output |
41 | | * \ingroup output |
42 | | * @{ |
43 | | * \file |
44 | | * Stream output modules interface |
45 | | */ |
46 | | |
47 | | /** |
48 | | * \defgroup sout_access Access output |
49 | | * Raw output byte streams |
50 | | * @{ |
51 | | */ |
52 | | |
53 | | /** Stream output access_output */ |
54 | | struct sout_access_out_t |
55 | | { |
56 | | struct vlc_object_t obj; |
57 | | |
58 | | module_t *p_module; |
59 | | char *psz_access; |
60 | | |
61 | | char *psz_path; |
62 | | void *p_sys; |
63 | | int (*pf_seek)( sout_access_out_t *, uint64_t ); |
64 | | ssize_t (*pf_read)( sout_access_out_t *, block_t * ); |
65 | | ssize_t (*pf_write)( sout_access_out_t *, block_t * ); |
66 | | int (*pf_control)( sout_access_out_t *, int, va_list ); |
67 | | |
68 | | config_chain_t *p_cfg; |
69 | | }; |
70 | | |
71 | | enum access_out_query_e |
72 | | { |
73 | | ACCESS_OUT_CONTROLS_PACE, /* arg1=bool *, can fail (assume true) */ |
74 | | ACCESS_OUT_CAN_SEEK, /* arg1=bool *, can fail (assume false) */ |
75 | | }; |
76 | | |
77 | | VLC_API sout_access_out_t * sout_AccessOutNew( vlc_object_t *, const char *psz_access, const char *psz_name ) VLC_USED; |
78 | | #define sout_AccessOutNew( obj, access, name ) \ |
79 | | sout_AccessOutNew( VLC_OBJECT(obj), access, name ) |
80 | | VLC_API void sout_AccessOutDelete( sout_access_out_t * ); |
81 | | VLC_API int sout_AccessOutSeek( sout_access_out_t *, uint64_t ); |
82 | | VLC_API ssize_t sout_AccessOutRead( sout_access_out_t *, block_t * ); |
83 | | VLC_API ssize_t sout_AccessOutWrite( sout_access_out_t *, block_t * ); |
84 | | VLC_API int sout_AccessOutControl( sout_access_out_t *, int, ... ); |
85 | | |
86 | | static inline bool sout_AccessOutCanControlPace( sout_access_out_t *p_ao ) |
87 | 0 | { |
88 | 0 | bool b; |
89 | 0 | if( sout_AccessOutControl( p_ao, ACCESS_OUT_CONTROLS_PACE, &b ) ) |
90 | 0 | return true; |
91 | 0 | return b; |
92 | 0 | } Unexecuted instantiation: webvtt.c:sout_AccessOutCanControlPace Unexecuted instantiation: h264.c:sout_AccessOutCanControlPace Unexecuted instantiation: mpeg4video.c:sout_AccessOutCanControlPace Unexecuted instantiation: dvbsub.c:sout_AccessOutCanControlPace Unexecuted instantiation: substx3g.c:sout_AccessOutCanControlPace Unexecuted instantiation: decoder.c:sout_AccessOutCanControlPace Unexecuted instantiation: input.c:sout_AccessOutCanControlPace Unexecuted instantiation: resource.c:sout_AccessOutCanControlPace Unexecuted instantiation: image.c:sout_AccessOutCanControlPace Unexecuted instantiation: stream_output.c:sout_AccessOutCanControlPace Unexecuted instantiation: vlm.c:sout_AccessOutCanControlPace Unexecuted instantiation: vlmshell.c:sout_AccessOutCanControlPace Unexecuted instantiation: es_out.c:sout_AccessOutCanControlPace |
93 | | |
94 | | /** |
95 | | * @} |
96 | | * \defgroup sout_mux Multiplexer |
97 | | * Multiplexers (file formatters) |
98 | | * @{ |
99 | | */ |
100 | | |
101 | | /** Muxer structure */ |
102 | | struct sout_mux_t |
103 | | { |
104 | | struct vlc_object_t obj; |
105 | | module_t *p_module; |
106 | | |
107 | | char *psz_mux; |
108 | | config_chain_t *p_cfg; |
109 | | |
110 | | sout_access_out_t *p_access; |
111 | | |
112 | | int (*pf_addstream)( sout_mux_t *, sout_input_t * ); |
113 | | void (*pf_delstream)( sout_mux_t *, sout_input_t * ); |
114 | | int (*pf_mux) ( sout_mux_t * ); |
115 | | int (*pf_control) ( sout_mux_t *, int, va_list ); |
116 | | |
117 | | /* here are all inputs accepted by muxer */ |
118 | | int i_nb_inputs; |
119 | | sout_input_t **pp_inputs; |
120 | | |
121 | | /* mux private */ |
122 | | void *p_sys; |
123 | | |
124 | | /* XXX private to stream_output.c */ |
125 | | /* if muxer doesn't support adding stream at any time then we first wait |
126 | | * for stream then we refuse all stream and start muxing */ |
127 | | bool b_add_stream_any_time; |
128 | | bool b_waiting_stream; |
129 | | /* we wait 1.5 second after first stream added */ |
130 | | vlc_tick_t i_add_stream_start; |
131 | | }; |
132 | | |
133 | | enum sout_mux_query_e |
134 | | { |
135 | | /* capabilities */ |
136 | | MUX_CAN_ADD_STREAM_WHILE_MUXING, /* arg1= bool *, res=cannot fail */ |
137 | | /* properties */ |
138 | | MUX_GET_MIME, /* arg1= char ** res=can fail */ |
139 | | }; |
140 | | |
141 | | struct sout_input_t |
142 | | { |
143 | | const es_format_t *p_fmt; |
144 | | block_fifo_t *p_fifo; |
145 | | void *p_sys; |
146 | | es_format_t fmt; |
147 | | }; |
148 | | |
149 | | |
150 | | VLC_API sout_mux_t * sout_MuxNew( sout_access_out_t *, const char * ) VLC_USED; |
151 | | VLC_API sout_input_t *sout_MuxAddStream( sout_mux_t *, const es_format_t * ) VLC_USED; |
152 | | VLC_API void sout_MuxDeleteStream( sout_mux_t *, sout_input_t * ); |
153 | | VLC_API void sout_MuxDelete( sout_mux_t * ); |
154 | | VLC_API int sout_MuxSendBuffer( sout_mux_t *, sout_input_t *, block_t * ); |
155 | | VLC_API int sout_MuxGetStream(sout_mux_t *, unsigned, vlc_tick_t *); |
156 | | VLC_API void sout_MuxFlush( sout_mux_t *, sout_input_t * ); |
157 | | |
158 | | static inline int sout_MuxControl( sout_mux_t *p_mux, int i_query, ... ) |
159 | 0 | { |
160 | 0 | va_list args; |
161 | 0 | int i_result; |
162 | |
|
163 | 0 | va_start( args, i_query ); |
164 | 0 | i_result = p_mux->pf_control( p_mux, i_query, args ); |
165 | 0 | va_end( args ); |
166 | 0 | return i_result; |
167 | 0 | } Unexecuted instantiation: webvtt.c:sout_MuxControl Unexecuted instantiation: h264.c:sout_MuxControl Unexecuted instantiation: mpeg4video.c:sout_MuxControl Unexecuted instantiation: dvbsub.c:sout_MuxControl Unexecuted instantiation: substx3g.c:sout_MuxControl Unexecuted instantiation: decoder.c:sout_MuxControl Unexecuted instantiation: input.c:sout_MuxControl Unexecuted instantiation: resource.c:sout_MuxControl Unexecuted instantiation: image.c:sout_MuxControl Unexecuted instantiation: stream_output.c:sout_MuxControl Unexecuted instantiation: vlm.c:sout_MuxControl Unexecuted instantiation: vlmshell.c:sout_MuxControl Unexecuted instantiation: es_out.c:sout_MuxControl |
168 | | |
169 | | /** @} */ |
170 | | |
171 | | /** |
172 | | * Stream output control list. |
173 | | * |
174 | | * Call the related actions with ::sout_StreamControl(). |
175 | | */ |
176 | | enum sout_stream_query_e |
177 | | { |
178 | | /** |
179 | | * Some ES such as closed captions are considered optional and shouldn't be |
180 | | * added to the stream output modules that return false for that query. |
181 | | * |
182 | | * \param bool* Closed caption support value, should be assumed false if the |
183 | | * control fails. |
184 | | * |
185 | | * Usage: |
186 | | * \code{c} |
187 | | * bool supports_substreams; |
188 | | * if (sout_StreamControl(stream, SOUT_STREAM_WANTS_SUBSTREAMS, &supports_substreams) != VLC_SUCCESS) |
189 | | * supports_substreams = false; |
190 | | * \endcode |
191 | | */ |
192 | | SOUT_STREAM_WANTS_SUBSTREAMS, |
193 | | |
194 | | /** |
195 | | * Signal the currently selected subtitle track that should be displayed to |
196 | | * the stream output. |
197 | | * This control should fail and do nothing if not implemented. |
198 | | * |
199 | | * \param void* Stream ID |
200 | | * \param vlc_spu_highlight_t* Selected spu data. |
201 | | * |
202 | | * Usage: |
203 | | * \code{c} |
204 | | * void *stream_id; |
205 | | * const vlc_spu_highlight_t hl_data = {... SPU infos...}; |
206 | | * sout_StreamControl(stream, SOUT_STREAM_ID_SPU_HIGHLIGHT, stream_id, &hl_data); |
207 | | * \endcode |
208 | | */ |
209 | | SOUT_STREAM_ID_SPU_HIGHLIGHT, |
210 | | |
211 | | /** |
212 | | * A synchronous stream output is a stream paced by the input clock. The |
213 | | * data will be sent at input rate if true is returned. |
214 | | * |
215 | | * \param bool* True if the stream output should be input paced. Should be |
216 | | * assumed false if the control fails. |
217 | | * |
218 | | * Usage: |
219 | | * \code{c} |
220 | | * bool is_input_paced; |
221 | | * if (sout_StreamControl(stream, SOUT_STREAM_IS_SYNCHRONOUS, &supports_substreams) != VLC_SUCCESS) |
222 | | * supports_substreams = false; |
223 | | * \endcode |
224 | | */ |
225 | | SOUT_STREAM_IS_SYNCHRONOUS, |
226 | | }; |
227 | | |
228 | | typedef struct vlc_frame_t vlc_frame_t; |
229 | | struct sout_stream_operations { |
230 | | /** |
231 | | * Implementation of ::sout_StreamIdAdd(). |
232 | | * |
233 | | * \note Mandatory callback. |
234 | | */ |
235 | | void *(*add)(sout_stream_t *, const es_format_t *, const char *); |
236 | | /** |
237 | | * Implementation of ::sout_StreamIdDel(). |
238 | | * |
239 | | * \note Mandatory callback. |
240 | | */ |
241 | | void (*del)(sout_stream_t *, void *); |
242 | | /** |
243 | | * Implementation of ::sout_StreamIdSend(). |
244 | | * |
245 | | * \note Mandatory callback. |
246 | | */ |
247 | | int (*send)(sout_stream_t *, void *, vlc_frame_t *); |
248 | | /** |
249 | | * Implementation of ::sout_StreamControl(). |
250 | | * |
251 | | * \note Optional callback. |
252 | | */ |
253 | | int (*control)( sout_stream_t *, int, va_list ); |
254 | | /** |
255 | | * Implementation of ::sout_StreamFlush(). |
256 | | * |
257 | | * \note Optional callback. |
258 | | */ |
259 | | void (*flush)( sout_stream_t *, void *); |
260 | | /** |
261 | | * Implementation of ::sout_StreamSetPCR(). |
262 | | * |
263 | | * \note Optional callback. |
264 | | */ |
265 | | void (*set_pcr)(sout_stream_t *, vlc_tick_t); |
266 | | /** |
267 | | * \note Optional callback. |
268 | | */ |
269 | | void (*close)(sout_stream_t *); |
270 | | }; |
271 | | |
272 | | struct sout_stream_t |
273 | | { |
274 | | struct vlc_object_t obj; |
275 | | |
276 | | char *psz_name; |
277 | | config_chain_t *p_cfg; |
278 | | sout_stream_t *p_next; |
279 | | |
280 | | const struct sout_stream_operations *ops; |
281 | | void *p_sys; |
282 | | }; |
283 | | |
284 | | /** |
285 | | * Allocate an empty Stream Output object. |
286 | | * |
287 | | * The object is empty, operation callbacks should be populated manually by the |
288 | | * caller. To create a stream output associated with a module, use |
289 | | * ::sout_StreamChainNew() instead. |
290 | | * |
291 | | * \note The stream should be destroyed with ::sout_StreamChainDelete(). |
292 | | * |
293 | | * \param parent The parent object of the stream output. |
294 | | * \param config A valid config chain of the object, of the form |
295 | | * "objname{option=*,option=*,...}" |
296 | | * |
297 | | * \retval An empty allocated Stream Output object. |
298 | | * \retval NULL on allocation error. |
299 | | */ |
300 | | VLC_API sout_stream_t *sout_StreamNew(vlc_object_t *parent, const char *config) VLC_USED; |
301 | | |
302 | | VLC_API void sout_StreamChainDelete(sout_stream_t *first, sout_stream_t *end); |
303 | | |
304 | | /** |
305 | | * Creates a complete "stream_out" modules chain |
306 | | * |
307 | | * Chain format: module1{option=*:option=*}[:module2{option=*:...}] |
308 | | * |
309 | | * The modules are created starting from the last one and linked together |
310 | | * |
311 | | * \retval A pointer to the first module. |
312 | | * \retval NULL if the chain creation failed. |
313 | | */ |
314 | | VLC_API sout_stream_t *sout_StreamChainNew(vlc_object_t *parent, |
315 | | const char *psz_chain, sout_stream_t *p_next) VLC_USED; |
316 | | |
317 | | /** |
318 | | * Add an ES to the stream output. |
319 | | * |
320 | | * The returned opaque identifier should be released by ::sout_StreamIdDel(). |
321 | | * |
322 | | * \param s |
323 | | * \param fmt A non-NULL es-format descriptor. |
324 | | * \param es_id A non-NULL unique string describing the ES. This string is |
325 | | * guaranteed to be valid for the whole lifetime of the ES (at |
326 | | * least until ::sout_StreamIdDel() is called). |
327 | | * Note that if stream output filters creates or duplicate a new |
328 | | * ES, they are responsible for the validity and uniqueness of the |
329 | | * string ID they pass to the next stream. |
330 | | * |
331 | | * \return An opaque pointer identifying the ES. |
332 | | * \retval NULL In case of error. |
333 | | */ |
334 | | VLC_API void *sout_StreamIdAdd(sout_stream_t *s, |
335 | | const es_format_t *fmt, |
336 | | const char *es_id) VLC_USED; |
337 | | |
338 | | /** |
339 | | * Delete an ES from the stream output. |
340 | | * |
341 | | * \param s |
342 | | * \param id An opaque pointer identifying the ES returned by |
343 | | * ::sout_StreamIdAdd(). |
344 | | */ |
345 | | VLC_API void sout_StreamIdDel(sout_stream_t *s, void *id); |
346 | | |
347 | | /** |
348 | | * Pass a \ref vlc_frame_t to the stream output. |
349 | | * |
350 | | * Takes ownership of the frame, it should be considered as invalid |
351 | | * and released after this call. |
352 | | * |
353 | | * \warning Only single frames are expected through this call, for frame chains, |
354 | | * you'll have to call this for each frames. |
355 | | * |
356 | | * \param s |
357 | | * \param id The ES identifier that sent the frame. |
358 | | * \param f a frame that will be consumed (through vlc_frame_Release) |
359 | | * |
360 | | * \retval VLC_SUCCESS on success. |
361 | | * \retval VLC_EGENERIC on non-recoverable unspecific error cases. |
362 | | * \retval (-ERRNO) A negated errno value describing the error case. |
363 | | */ |
364 | | VLC_API int sout_StreamIdSend(sout_stream_t *s, void *id, vlc_frame_t *f); |
365 | | |
366 | | /** |
367 | | * Signal a flush of an ES to the stream output. |
368 | | * |
369 | | * Flush is an optional control, if implemented, it will drop all the bufferized |
370 | | * data from ES and/or forward the Flush command to the next stream. |
371 | | * |
372 | | * \param s |
373 | | * \param id An identifier of the ES to flush. |
374 | | */ |
375 | | VLC_API void sout_StreamFlush(sout_stream_t *s, void *id); |
376 | | |
377 | | /** |
378 | | * Signal a PCR update to the stream output. |
379 | | * |
380 | | * The PCR (Program Clock Reference from the MPEG-TS spec.) gives a global |
381 | | * stream advancement timestamp. |
382 | | * The demuxer is required to: |
383 | | * - Yield a PCR value at fix and frequent interval. Even if no ES are added |
384 | | * to the stream output. |
385 | | * - Send frames that have timestamp values greater than the last PCR value. |
386 | | * |
387 | | * \note PCR resets in case of handled discontinuity are implied by a frame |
388 | | * marked by \ref VLC_FRAME_FLAG_DISCONTINUITY and/or by a ::sout_StreamFlush() |
389 | | * call. |
390 | | */ |
391 | | VLC_API void sout_StreamSetPCR(sout_stream_t *, vlc_tick_t pcr); |
392 | | |
393 | | struct vlc_sout_clock_bus; |
394 | | VLC_API struct vlc_sout_clock_bus *sout_ClockMainCreate(sout_stream_t *) VLC_USED; |
395 | | VLC_API void sout_ClockMainDelete(struct vlc_sout_clock_bus *); |
396 | | VLC_API void sout_ClockMainSetFirstPcr(struct vlc_sout_clock_bus *, vlc_tick_t pcr); |
397 | | VLC_API vlc_clock_t *sout_ClockCreate(struct vlc_sout_clock_bus *, const es_format_t *) VLC_USED; |
398 | | VLC_API void sout_ClockDelete(vlc_clock_t *); |
399 | | |
400 | | |
401 | | VLC_API int sout_StreamControlVa(sout_stream_t *, int i_query, va_list args); |
402 | | |
403 | | /** |
404 | | * Various controls forwarded through the stream output chain. |
405 | | * |
406 | | * Controls are various misc accessors or set of actions that can be used to |
407 | | * query the stream output. |
408 | | * See \ref sout_stream_query_e for the list of availables controls. |
409 | | */ |
410 | | static inline int sout_StreamControl( sout_stream_t *s, int i_query, ... ) |
411 | 0 | { |
412 | 0 | va_list args; |
413 | 0 | int i_result; |
414 | |
|
415 | 0 | va_start( args, i_query ); |
416 | 0 | i_result = sout_StreamControlVa( s, i_query, args ); |
417 | 0 | va_end( args ); |
418 | 0 | return i_result; |
419 | 0 | } Unexecuted instantiation: webvtt.c:sout_StreamControl Unexecuted instantiation: h264.c:sout_StreamControl Unexecuted instantiation: mpeg4video.c:sout_StreamControl Unexecuted instantiation: dvbsub.c:sout_StreamControl Unexecuted instantiation: substx3g.c:sout_StreamControl Unexecuted instantiation: decoder.c:sout_StreamControl Unexecuted instantiation: input.c:sout_StreamControl Unexecuted instantiation: resource.c:sout_StreamControl Unexecuted instantiation: image.c:sout_StreamControl Unexecuted instantiation: stream_output.c:sout_StreamControl Unexecuted instantiation: vlm.c:sout_StreamControl Unexecuted instantiation: vlmshell.c:sout_StreamControl Unexecuted instantiation: es_out.c:sout_StreamControl |
420 | | |
421 | | static inline bool sout_StreamIsSynchronous(sout_stream_t *s) |
422 | 0 | { |
423 | 0 | bool b; |
424 | |
|
425 | 0 | if (sout_StreamControl(s, SOUT_STREAM_IS_SYNCHRONOUS, &b)) |
426 | 0 | b = false; |
427 | |
|
428 | 0 | return b; |
429 | 0 | } Unexecuted instantiation: webvtt.c:sout_StreamIsSynchronous Unexecuted instantiation: h264.c:sout_StreamIsSynchronous Unexecuted instantiation: mpeg4video.c:sout_StreamIsSynchronous Unexecuted instantiation: dvbsub.c:sout_StreamIsSynchronous Unexecuted instantiation: substx3g.c:sout_StreamIsSynchronous Unexecuted instantiation: decoder.c:sout_StreamIsSynchronous Unexecuted instantiation: input.c:sout_StreamIsSynchronous Unexecuted instantiation: resource.c:sout_StreamIsSynchronous Unexecuted instantiation: image.c:sout_StreamIsSynchronous Unexecuted instantiation: stream_output.c:sout_StreamIsSynchronous Unexecuted instantiation: vlm.c:sout_StreamIsSynchronous Unexecuted instantiation: vlmshell.c:sout_StreamIsSynchronous Unexecuted instantiation: es_out.c:sout_StreamIsSynchronous |
430 | | |
431 | | /**************************************************************************** |
432 | | * Encoder |
433 | | ****************************************************************************/ |
434 | | |
435 | | VLC_API encoder_t * sout_EncoderCreate( vlc_object_t *, size_t ); |
436 | 0 | #define sout_EncoderCreate(o,s) sout_EncoderCreate(VLC_OBJECT(o),s) |
437 | | |
438 | | /**************************************************************************** |
439 | | * Announce handler |
440 | | ****************************************************************************/ |
441 | | VLC_API session_descriptor_t* sout_AnnounceRegisterSDP( vlc_object_t *, const char *, const char * ) VLC_USED; |
442 | | VLC_API void sout_AnnounceUnRegister(vlc_object_t *,session_descriptor_t* ); |
443 | | #define sout_AnnounceRegisterSDP(o, sdp, addr) \ |
444 | | sout_AnnounceRegisterSDP(VLC_OBJECT (o), sdp, addr) |
445 | | #define sout_AnnounceUnRegister(o, a) \ |
446 | | sout_AnnounceUnRegister(VLC_OBJECT (o), a) |
447 | | |
448 | | /** @} */ |
449 | | |
450 | | #ifdef __cplusplus |
451 | | } |
452 | | #endif |
453 | | |
454 | | #endif |