From f93de3ef234c010a8e3788985ed9d0ae2e5b0aca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Branstett?= Date: Fri, 17 Mar 2023 11:48:19 +0100 Subject: [PATCH] stream/demux: move remaining callbacks to their respective ops struct This commit moves the remaining callbacks of stream/demux: pf_read/ pf_block/pf_seek/pf_readdir and pf_demux into their operations table, aiming at unifying all the callbacks under a unique place. This is a follow-up to the introduction of typed controls callbacks for stream and demux. Like for the typed controls callbacks if no operation is provided (ie, stream_t/demux_t.ops is NULL) by a module, the legacy pf_* will be used instead as a fallback. The commit doesn't migrate any of modules yet. --- include/vlc_stream.h | 20 ++++++++++++++++++++ src/input/access.c | 5 ++++- src/input/demux.c | 14 ++++++++++---- src/input/input.c | 16 +++++++++++----- src/input/stream.c | 32 +++++++++++++++++++------------- src/input/stream_filter.c | 4 +++- 6 files changed, 67 insertions(+), 24 deletions(-) diff --git a/include/vlc_stream.h b/include/vlc_stream.h index 311c9c078e..f4ada541a0 100644 --- a/include/vlc_stream.h +++ b/include/vlc_stream.h @@ -60,6 +60,11 @@ struct vlc_stream_operations { union { struct { bool (*can_fastseek)(stream_t *); + + ssize_t (*read)(stream_t *, void *buf, size_t len); + block_t *(*block)(stream_t *, bool *restrict eof); + int (*readdir)(stream_t *, input_item_node_t *); + int (*seek)(stream_t *, uint64_t); int (*get_title)(stream_t *, unsigned *); int (*get_seekpoint)(stream_t *, unsigned *); @@ -76,6 +81,9 @@ struct vlc_stream_operations { struct { bool (*can_record)(demux_t *); bool (*can_control_rate)(demux_t *); + + int (*demux)(demux_t *); + int (*readdir)(demux_t *, input_item_node_t *); bool (*has_unsupported_meta)(demux_t *); @@ -149,6 +157,9 @@ struct stream_t * * Callback to read data from the stream into a caller-supplied buffer. * + * This is the legacy implementor, using \ref vlc_stream_operations + * should be prefered. + * * This may be NULL if the stream is actually a directory rather than a * byte stream, or if \ref stream_t.pf_block is non-NULL. * @@ -170,6 +181,9 @@ struct stream_t * for buffers. In such case, this callback should be provided instead of * \ref stream_t.pf_read; otherwise, this should be NULL. * + * This is the legacy implementor, using \ref vlc_stream_operations + * should be prefered. + * * \param eof storage space for end-of-stream flag [OUT] * (*eof is always false when invoking pf_block(); pf_block() should set * *eof to true if it detects the end of the stream) @@ -185,6 +199,9 @@ struct stream_t * Callback to fill an item node from a directory * (see doc/browsing.txt for details). * + * This is the legacy implementor, using \ref vlc_stream_operations + * should be prefered. + * * NULL if the stream is not a directory. */ int (*pf_readdir)(stream_t *, input_item_node_t *); @@ -196,6 +213,9 @@ struct stream_t * * Callback to set the stream pointer (in bytes from start). * + * This is the legacy implementor, using \ref vlc_stream_operations + * should be prefered. + * * May be NULL if seeking is not supported. */ int (*pf_seek)(stream_t *, uint64_t); diff --git a/src/input/access.c b/src/input/access.c index 0d0362c23f..bd0903e6e4 100644 --- a/src/input/access.c +++ b/src/input/access.c @@ -290,7 +290,10 @@ stream_t *stream_AccessNew(vlc_object_t *parent, input_thread_t *input, stream_t *s; - if (access->pf_block != NULL || access->pf_read != NULL) + // TODO: handle access->ops != NULL + // if ((access->ops != NULL && (access->ops->stream.block != NULL || access->ops->stream.read != NULL)) + // || (access->ops == NULL && (access->pf_block != NULL || access->pf_read != NULL))) + if (access->ops == NULL && (access->pf_block != NULL || access->pf_read != NULL)) { struct vlc_access_stream_private *priv; s = vlc_stream_CustomNew(VLC_OBJECT(access), AStreamDestroy, diff --git a/src/input/demux.c b/src/input/demux.c index da65f83f4e..8a2547e3c5 100644 --- a/src/input/demux.c +++ b/src/input/demux.c @@ -207,18 +207,24 @@ error: return NULL; } +static int demux_ReadDir( stream_t *s, input_item_node_t *p_node ) +{ + assert(s->pf_readdir != NULL || (s->ops != NULL && s->ops->demux.readdir != NULL)); + return (s->ops != NULL ? s->ops->demux.readdir : s->pf_readdir)( s, p_node ); +} + int demux_Demux(demux_t *demux) { - if (demux->pf_demux != NULL) - return demux->pf_demux(demux); + if (demux->pf_demux != NULL || (demux->ops != NULL && demux->ops->demux.demux != NULL)) + return (demux->ops != NULL ? demux->ops->demux.demux : demux->pf_demux)(demux); - if (demux->pf_readdir != NULL && demux->p_input_item != NULL) { + if ((demux->pf_readdir != NULL || (demux->ops != NULL && demux->ops->demux.readdir != NULL)) && demux->p_input_item != NULL) { input_item_node_t *node = input_item_node_Create(demux->p_input_item); if (unlikely(node == NULL)) return VLC_DEMUXER_EGENERIC; - if (vlc_stream_ReadDir(demux, node)) { + if (demux_ReadDir(demux, node)) { input_item_node_Delete(node); return VLC_DEMUXER_EGENERIC; } diff --git a/src/input/input.c b/src/input/input.c index a986b4d5c2..a3729ccd1a 100644 --- a/src/input/input.c +++ b/src/input/input.c @@ -624,8 +624,9 @@ static void MainLoop( input_thread_t *p_input, bool b_interactive ) bool b_paused_at_eof = false; demux_t *p_demux = input_priv(p_input)->master->p_demux; - const bool b_can_demux = p_demux->pf_demux != NULL - || p_demux->pf_readdir != NULL; + const bool b_can_demux = p_demux->ops != NULL ? + (p_demux->ops->demux.demux != NULL || p_demux->ops->demux.readdir != NULL) : + (p_demux->pf_demux != NULL || p_demux->pf_readdir != NULL); while( !input_Stopped( p_input ) && input_priv(p_input)->i_state != ERROR_S ) { @@ -2534,8 +2535,10 @@ static demux_t *InputDemuxNew( input_thread_t *p_input, es_out_t *p_es_out, p_stream = stream_FilterAutoNew( p_stream ); - if( p_stream->pf_read == NULL && p_stream->pf_block == NULL - && p_stream->pf_readdir == NULL ) + if(( p_stream->ops != NULL && (p_stream->ops->stream.read == NULL && + p_stream->ops->stream.block == NULL && p_stream->ops->stream.readdir == NULL)) + || ( p_stream->ops == NULL && (p_stream->pf_read == NULL && p_stream->pf_block == NULL && + p_stream->pf_readdir == NULL)) ) { /* Combined access/demux, no stream filtering */ MRLSections( psz_anchor, &p_source->i_title_start, &p_source->i_title_end, @@ -2750,8 +2753,11 @@ static int InputSourceInit( input_source_t *in, input_thread_t *p_input, &in->b_can_pace_control ) ) in->b_can_pace_control = false; + const bool b_can_demux = in->p_demux->ops != NULL ? + in->p_demux->ops->demux.demux != NULL : in->p_demux->pf_demux != NULL; + /* Threaded and directory demuxers do not have pace control */ - assert( in->p_demux->pf_demux != NULL || !in->b_can_pace_control ); + assert( b_can_demux || !in->b_can_pace_control ); if( !in->b_can_pace_control ) { diff --git a/src/input/stream.c b/src/input/stream.c index 753e65115a..83c014eb05 100644 --- a/src/input/stream.c +++ b/src/input/stream.c @@ -202,7 +202,8 @@ char *vlc_stream_ReadLine( stream_t *s ) stream_priv_t *priv = stream_priv(s); /* Let's fail quickly if this is a readdir access */ - if( s->pf_read == NULL && s->pf_block == NULL ) + if( (s->ops != NULL && s->ops->stream.read == NULL && s->ops->stream.block == NULL) || + (s->ops == NULL && s->pf_read == NULL && s->pf_block == NULL) ) return NULL; /* BOM detection */ @@ -439,7 +440,7 @@ static ssize_t vlc_stream_ReadRaw(stream_t *s, void *buf, size_t len) if (vlc_killed()) return 0; - if (s->pf_read != NULL) + if ((s->ops != NULL && s->ops->stream.read != NULL) || (s->ops == NULL && s->pf_read != NULL)) { assert(priv->block == NULL); if (buf == NULL) @@ -448,10 +449,10 @@ static ssize_t vlc_stream_ReadRaw(stream_t *s, void *buf, size_t len) return 0; char dummy[256]; - ret = s->pf_read(s, dummy, len <= 256 ? len : 256); + ret = (s->ops != NULL ? s->ops->stream.read : s->pf_read)(s, dummy, len <= 256 ? len : 256); } else - ret = s->pf_read(s, buf, len); + ret = (s->ops != NULL ? s->ops->stream.read : s->pf_read)(s, buf, len); return ret; } @@ -459,11 +460,11 @@ static ssize_t vlc_stream_ReadRaw(stream_t *s, void *buf, size_t len) if (ret >= 0) return ret; - if (s->pf_block != NULL) + if ((s->ops != NULL && s->ops->stream.block != NULL) || (s->ops == NULL && s->pf_block != NULL)) { bool eof = false; - priv->block = s->pf_block(s, &eof); + priv->block = (s->ops != NULL ? s->ops->stream.block : s->pf_block)(s, &eof); ret = vlc_stream_CopyBlock(&priv->block, buf, len); if (ret >= 0) return ret; @@ -592,10 +593,10 @@ block_t *vlc_stream_ReadBlock(stream_t *s) block = priv->block; priv->block = NULL; } - else if (s->pf_block != NULL) + else if ((s->ops != NULL && s->ops->stream.block != NULL) || (s->ops == NULL && s->pf_block != NULL)) { priv->eof = false; - block = s->pf_block(s, &priv->eof); + block = (s->ops != NULL ? s->ops->stream.block : s->pf_block)(s, &priv->eof); } else { @@ -603,7 +604,7 @@ block_t *vlc_stream_ReadBlock(stream_t *s) if (unlikely(block == NULL)) return NULL; - ssize_t ret = s->pf_read(s, block->p_buffer, block->i_buffer); + ssize_t ret = (s->ops != NULL ? s->ops->stream.read : s->pf_read)(s, block->p_buffer, block->i_buffer); if (ret > 0) block->i_buffer = ret; else @@ -668,10 +669,15 @@ int vlc_stream_Seek(stream_t *s, uint64_t offset) return VLC_SUCCESS; /* Nothing to do! */ } - if (s->pf_seek == NULL) + int ret; + if (s->ops == NULL && s->pf_seek != NULL) { + ret = s->pf_seek(s, offset); + } else if (s->ops != NULL && s->ops->stream.seek != NULL) { + ret = s->ops->stream.seek(s, offset); + } else { return VLC_EGENERIC; + } - int ret = s->pf_seek(s, offset); if (ret != VLC_SUCCESS) return ret; @@ -919,6 +925,6 @@ block_t *vlc_stream_Block( stream_t *s, size_t size ) int vlc_stream_ReadDir( stream_t *s, input_item_node_t *p_node ) { - assert(s->pf_readdir != NULL); - return s->pf_readdir( s, p_node ); + assert(s->pf_readdir != NULL || (s->ops != NULL && s->ops->stream.readdir != NULL)); + return (s->ops != NULL ? s->ops->stream.readdir : s->pf_readdir)( s, p_node ); } diff --git a/src/input/stream_filter.c b/src/input/stream_filter.c index 40ccbeaf82..5bdfab815f 100644 --- a/src/input/stream_filter.c +++ b/src/input/stream_filter.c @@ -53,7 +53,9 @@ stream_t *vlc_stream_FilterNew( stream_t *p_source, assert(p_source != NULL); /* Stream filters can only filter byte streams. */ - if (p_source->pf_read == NULL && p_source->pf_block == NULL) + if ((p_source->ops != NULL && + p_source->ops->stream.read == NULL && p_source->ops->stream.block == NULL) || + (p_source->ops == NULL && p_source->pf_read == NULL && p_source->pf_block == NULL)) return NULL; struct vlc_stream_filter_private *priv;