[vlc-commits] [Git][videolan/vlc][master] 4 commits: sout: switch to `vlc_frame_t` for the API
Jean-Baptiste Kempf (@jbk)
gitlab at videolan.org
Fri Jul 7 18:37:41 UTC 2023
Jean-Baptiste Kempf pushed to branch master at VideoLAN / VLC
Commits:
eda2c093 by Alaric Senat at 2023-07-07T18:21:41+00:00
sout: switch to `vlc_frame_t` for the API
Frames are suppposed to pass into the stream output instead of blocks as
we'll likely want to use ancillaries.
- - - - -
7779bf5a by Alaric Senat at 2023-07-07T18:21:41+00:00
sout: document and clean the API
- - - - -
f5872be4 by Alaric Senat at 2023-07-07T18:21:41+00:00
sout: enforce single frames in `pf_send`
The stream output API is unclear on chained frame support. Currently,
modules decide if they want to support them or not.
As it seems that the current consensus is to support single frames only,
this assert will help notifying and fixing inconsistents behavior on
that regard.
Note that it could be perfectly valid to pass frames one by one from a
chain without having to NULL every `p_next` entry for each elements so
this assert might be deleted once it is clear that all stream output
modules are fixed to support single frames only.
- - - - -
eb71e4d1 by Alaric Senat at 2023-07-07T18:21:41+00:00
sout: transcode: remove redundant assert
`frame->p_next` being NULL is now enforced by the pf_add wrapper.
- - - - -
3 changed files:
- include/vlc_sout.h
- modules/stream_out/transcode/transcode.c
- src/stream_output/stream_output.c
Changes:
=====================================
include/vlc_sout.h
=====================================
@@ -168,18 +168,98 @@ static inline int sout_MuxControl( sout_mux_t *p_mux, int i_query, ... )
/** @} */
-enum sout_stream_query_e {
- SOUT_STREAM_WANTS_SUBSTREAMS, /* arg1=bool *, res=can fail (assume false) */
- SOUT_STREAM_ID_SPU_HIGHLIGHT, /* arg1=void *, arg2=const vlc_spu_highlight_t *, res=can fail */
- SOUT_STREAM_IS_SYNCHRONOUS, /* arg1=bool *, can fail (assume false) */
+/**
+ * Stream output control list.
+ *
+ * Call the related actions with ::sout_StreamControl().
+ */
+enum sout_stream_query_e
+{
+ /**
+ * Some ES such as closed captions are considered optional and shouldn't be
+ * added to the stream output modules that return false for that query.
+ *
+ * \param bool* Closed caption support value, should be assumed false if the
+ * control fails.
+ *
+ * Usage:
+ * \code{c}
+ * bool supports_substreams;
+ * if (sout_StreamControl(stream, SOUT_STREAM_WANTS_SUBSTREAMS, &supports_substreams) != VLC_SUCCESS)
+ * supports_substreams = false;
+ * \endcode
+ */
+ SOUT_STREAM_WANTS_SUBSTREAMS,
+
+ /**
+ * Signal the currently selected subtitle track that should be displayed to
+ * the stream output.
+ * This control should fail and do nothing if not implemented.
+ *
+ * \param vlc_spu_highlight_t* Selected spu data.
+ *
+ * Usage:
+ * \code{c}
+ * const vlc_spu_highlight_t hl_data = {... SPU infos...};
+ * sout_StreamControl(stream, SOUT_STREAM_ID_SPU_HIGHLIGHT, &hl_data);
+ * \endcode
+ */
+ SOUT_STREAM_ID_SPU_HIGHLIGHT,
+
+ /**
+ * A synchronous stream output is a stream paced by the input clock. The
+ * data will be sent at input rate if true is returned.
+ *
+ * \param bool* True if the stream output should be input paced. Should be
+ * assumed false if the control fails.
+ *
+ * Usage:
+ * \code{c}
+ * bool is_input_paced;
+ * if (sout_StreamControl(stream, SOUT_STREAM_IS_SYNCHRONOUS, &supports_substreams) != VLC_SUCCESS)
+ * supports_substreams = false;
+ * \endcode
+ */
+ SOUT_STREAM_IS_SYNCHRONOUS,
};
+typedef struct vlc_frame_t vlc_frame_t;
struct sout_stream_operations {
+ /**
+ * Implementation of ::sout_StreamIdAdd().
+ *
+ * \note Mandatory callback.
+ */
void *(*add)(sout_stream_t *, const es_format_t *);
+ /**
+ * Implementation of ::sout_StreamIdDel().
+ *
+ * \note Mandatory callback.
+ */
void (*del)(sout_stream_t *, void *);
- int (*send)(sout_stream_t *, void *, block_t *);
+ /**
+ * Implementation of ::sout_StreamIdSend().
+ *
+ * \note Mandatory callback.
+ */
+ int (*send)(sout_stream_t *, void *, vlc_frame_t *);
+ /**
+ * Implementation of ::sout_StreamControl().
+ *
+ * \note Optional callback.
+ */
int (*control)( sout_stream_t *, int, va_list );
+ /**
+ * Implementation of ::sout_StreamFlush().
+ *
+ * \note Optional callback.
+ */
void (*flush)( sout_stream_t *, void *);
+ /**
+ * Implementation of ::sout_StreamSetPCR().
+ *
+ * \note Optional callback.
+ */
void (*set_pcr)(sout_stream_t *, vlc_tick_t);
};
@@ -199,12 +279,71 @@ VLC_API void sout_StreamChainDelete(sout_stream_t *first, sout_stream_t *end);
VLC_API sout_stream_t *sout_StreamChainNew(vlc_object_t *parent,
const char *psz_chain, sout_stream_t *p_next) VLC_USED;
-VLC_API void *sout_StreamIdAdd(sout_stream_t *s, const es_format_t *fmt);
-VLC_API void sout_StreamIdDel(sout_stream_t *s, void *id);
-VLC_API int sout_StreamIdSend( sout_stream_t *s, void *id, block_t *b);
-VLC_API void sout_StreamFlush(sout_stream_t *s, void *id);
-VLC_API void sout_StreamSetPCR(sout_stream_t *s, vlc_tick_t pcr);
-VLC_API int sout_StreamControlVa(sout_stream_t *s, int i_query, va_list args);
+/**
+ * Add an ES to the stream output.
+ *
+ * The returned opaque identifier should be released by ::sout_StreamIdDel().
+ *
+ * \param fmt A non-NULL es-format descriptor.
+ *
+ * \return An opaque pointer identifying the ES.
+ * \retval NULL In case of error.
+ */
+VLC_API void *sout_StreamIdAdd(sout_stream_t *, const es_format_t *fmt) VLC_USED;
+
+/**
+ * Delete an ES from the stream output.
+ *
+ * \param id An opaque pointer identifying the ES returned by
+ * ::sout_StreamIdAdd().
+ *
+ * \return An opaque pointer identifying the ES.
+ * \retval NULL In case of error.
+ */
+VLC_API void sout_StreamIdDel(sout_stream_t *, void *id);
+
+/**
+ * Pass a \ref vlc_frame_t to the stream output.
+ *
+ * Takes ownership of the frame, it should be considered as invalid
+ * and released after this call.
+ *
+ * \warning Only single frames are expected through this call, for frame chains,
+ * you'll have to call this for each frames.
+ *
+ * \param id The ES identifier that sent the frame.
+ *
+ * \retval VLC_SUCCESS on success.
+ * \retval VLC_EGENERIC on non-recoverable unspecific error cases.
+ * \retval (-ERRNO) A negated errno value describing the error case.
+ */
+VLC_API int sout_StreamIdSend(sout_stream_t *, void *id, vlc_frame_t *);
+
+/**
+ * Signal a flush of an ES to the stream output.
+ *
+ * Flush is an optional control, if implemented, it will drop all the bufferized
+ * data from ES and/or forward the Flush command to the next stream.
+ *
+ * \param id An identifier of the ES to flush.
+ */
+VLC_API void sout_StreamFlush(sout_stream_t *, void *id);
+
+/**
+ * Signal a PCR update to the stream output.
+ *
+ * The PCR (Program Clock Reference from the MPEG-TS spec.) gives a global
+ * stream advancement timestamp.
+ * The demuxer is required to:
+ * - Yield a PCR value at fix and frequent interval. Even if no ES are added
+ * to the stream output.
+ * - Send frames that have timestamp values greater than the last PCR value.
+ *
+ * \note PCR resets in case of handled discontinuity are implied by a frame
+ * marked by \ref VLC_FRAME_FLAG_DISCONTINUITY and/or by a ::sout_StreamFlush()
+ * call.
+ */
+VLC_API void sout_StreamSetPCR(sout_stream_t *, vlc_tick_t pcr);
VLC_API vlc_clock_main_t *sout_ClockMainCreate(sout_stream_t *) VLC_USED;
VLC_API void sout_ClockMainDelete(vlc_clock_main_t *);
@@ -212,6 +351,16 @@ VLC_API void sout_ClockMainSetFirstPcr(vlc_clock_main_t *, vlc_tick_t pcr);
VLC_API vlc_clock_t *sout_ClockCreate(vlc_clock_main_t *, const es_format_t *) VLC_USED;
VLC_API void sout_ClockDelete(vlc_clock_t *);
+
+VLC_API int sout_StreamControlVa(sout_stream_t *, int i_query, va_list args);
+
+/**
+ * Various controls forwarded through the stream output chain.
+ *
+ * Controls are various misc accessors or set of actions that can be used to
+ * query the stream output.
+ * See \ref sout_stream_query_e for the list of availables controls.
+ */
static inline int sout_StreamControl( sout_stream_t *s, int i_query, ... )
{
va_list args;
=====================================
modules/stream_out/transcode/transcode.c
=====================================
@@ -778,8 +778,6 @@ static int Send( sout_stream_t *p_stream, void *_id, block_t *p_buffer )
sout_stream_sys_t *sys = p_stream->p_sys;
if( p_buffer != NULL && sys->pcr_forwarding_enabled )
{
- assert( p_buffer->p_next == NULL );
-
if( !sys->pcr_sync_has_input )
sys->pcr_sync_has_input = true;
=====================================
src/stream_output/stream_output.c
=====================================
@@ -46,6 +46,7 @@
#include <vlc_meta.h>
#include <vlc_block.h>
+#include <vlc_frame.h>
#include <vlc_codec.h>
#include <vlc_modules.h>
@@ -198,14 +199,14 @@ void sout_InputFlush( sout_stream_t *p_sout,
*****************************************************************************/
int sout_InputSendBuffer( sout_stream_t *p_sout,
sout_packetizer_input_t *p_input,
- block_t *p_buffer )
+ vlc_frame_t *frame )
{
if( p_input->b_flushed )
{
- p_buffer->i_flags |= BLOCK_FLAG_DISCONTINUITY;
+ frame->i_flags |= VLC_FRAME_FLAG_DISCONTINUITY;
p_input->b_flushed = false;
}
- return sout_StreamIdSend( p_sout, p_input->id, p_buffer );
+ return sout_StreamIdSend( p_sout, p_input->id, frame );
}
#undef sout_AccessOutNew
@@ -711,12 +712,14 @@ void sout_StreamIdDel(sout_stream_t *s, void *id)
sout_StreamUnlock(s);
}
-int sout_StreamIdSend(sout_stream_t *s, void *id, block_t *b)
+int sout_StreamIdSend(sout_stream_t *s, void *id, vlc_frame_t *f)
{
int val;
+ assert(f->p_next == NULL);
+
sout_StreamLock(s);
- val = s->ops->send(s, id, b);
+ val = s->ops->send(s, id, f);
sout_StreamUnlock(s);
return val;
}
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/812aa244bd40eb5218cd2711f4d11ee8a6ca6a03...eb71e4d155bf4fabd3ed226767c60b8fed104bde
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/812aa244bd40eb5218cd2711f4d11ee8a6ca6a03...eb71e4d155bf4fabd3ed226767c60b8fed104bde
You're receiving this email because of your account on code.videolan.org.
VideoLAN code repository instance
More information about the vlc-commits
mailing list