vlc | branch: master | Rémi Denis-Courmont <[email protected]> | Thu Jun 30 21:10:22 2016 +0300| [4bc7a87939eac8ca9475823f7bd3c835eda2838b] | committer: Rémi Denis-Courmont
input: add chained demux functions This provides the same functionality as stream_Demux using stream FIFO underneath. > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=4bc7a87939eac8ca9475823f7bd3c835eda2838b --- include/vlc_demux.h | 79 ++++++++++++++++++++++ src/Makefile.am | 1 + src/input/demux_chained.c | 161 +++++++++++++++++++++++++++++++++++++++++++++ src/libvlccore.sym | 4 ++ 4 files changed, 245 insertions(+) diff --git a/include/vlc_demux.h b/include/vlc_demux.h index 9200a64..4af382c 100644 --- a/include/vlc_demux.h +++ b/include/vlc_demux.h @@ -441,6 +441,85 @@ VLC_API void demux_PacketizerDestroy( decoder_t *p_packetizer ); } while(0) /** + * \defgroup chained_demux Chained demultiplexer + * Demultiplexers wrapped by another demultiplexer + * @{ + */ + +typedef struct vlc_demux_chained_t vlc_demux_chained_t; + +/** + * Creates a chained demuxer. + * + * This creates a thread running a demuxer whose input stream is generated + * directly by the caller. This typically handles some sort of stream within a + * stream, e.g. MPEG-TS within something else. + * + * \note There are a number of limitations to this approach. The chained + * demuxer is run asynchronously in a separate thread. Most demuxer controls + * are synchronous and therefore unavailable in this case. Also the input + * stream is a simple FIFO, so the chained demuxer cannot perform seeks. + * Lastly, most errors cannot be detected. + * + * \param parent parent VLC object + * \param name chained demux module name (e.g. "ts") + * \param out elementary stream output for the chained demux + * \return a non-NULL pointer on success, NULL on failure. + */ +VLC_API vlc_demux_chained_t *vlc_demux_chained_New(vlc_object_t *parent, + const char *name, + es_out_t *out); + +/** + * Destroys a chained demuxer. + * + * Sends an end-of-stream to the chained demuxer, and releases all underlying + * allocated resources. + */ +VLC_API void vlc_demux_chained_Delete(vlc_demux_chained_t *); + +/** + * Sends data to a chained demuxer. + * + * This queues data for a chained demuxer to consume. + * + * \param block data block to queue + */ +VLC_API void vlc_demux_chained_Send(vlc_demux_chained_t *, block_t *block); + +/** + * Controls a chained demuxer. + * + * This performs a <b>demux</b> (i.e. DEMUX_...) control request on a chained + * demux. + * + * \note In most cases, vlc_demux_chained_Control() should be used instead. + * \warning As per vlc_demux_chained_New(), most demux controls are not, and + * cannot be, supported; VLC_EGENERIC is returned. + * + * \param query demux control (see \ref demux_query_e) + * \param args variable arguments (depending on the query) + */ +VLC_API int vlc_demux_chained_ControlVa(vlc_demux_chained_t *, int query, + va_list args); + +static inline int vlc_demux_chained_Control(vlc_demux_chained_t *dc, int query, + ...) +{ + va_list ap; + int ret; + + va_start(ap, query); + ret = vlc_demux_chained_ControlVa(dc, query, ap); + va_end(ap); + return ret; +} + +/** + * @} + */ + +/** * @} */ diff --git a/src/Makefile.am b/src/Makefile.am index 2720564..6f387f9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -358,6 +358,7 @@ SOURCES_libvlc_common = \ input/decoder.c \ input/decoder_synchro.c \ input/demux.c \ + input/demux_chained.c \ input/es_out.c \ input/es_out_timeshift.c \ input/event.c \ diff --git a/src/input/demux_chained.c b/src/input/demux_chained.c new file mode 100644 index 0000000..270c603 --- /dev/null +++ b/src/input/demux_chained.c @@ -0,0 +1,161 @@ +/***************************************************************************** + * demux_chained.c + ***************************************************************************** + * Copyright (C) 1999-2016 VLC authors and VideoLAN + * + * Authors: Laurent Aimar <fenrir _AT_ videolan _DOT_ org> + * Rémi Denis-Courmont + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + *****************************************************************************/ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <limits.h> +#include <stdlib.h> +#include <string.h> +#include <vlc_common.h> +#include <vlc_demux.h> +#include "demux.h" + +struct vlc_demux_chained_t +{ + stream_t *fifo; + + vlc_thread_t thread; + vlc_mutex_t lock; + + struct + { + double position; + int64_t length; + int64_t time; + } stats; + + es_out_t *out; + char name[]; +}; + +static void *vlc_demux_chained_Thread(void *data) +{ + vlc_demux_chained_t *dc = data; + demux_t *demux = demux_NewAdvanced(dc->fifo, NULL, "", dc->name, "", + dc->fifo, dc->out, false); + if (demux == NULL) + return NULL; + + /* Stream FIFO cannot apply DVB filters. + * Get all programs and let the E/S output sort them out. */ + demux_Control(demux, DEMUX_SET_GROUP, -1, NULL); + + /* Main loop */ + mtime_t next_update = 0; + + do + if (demux_TestAndClearFlags(demux, UINT_MAX) || mdate() >= next_update) + { + double newpos; + int64_t newlen, newtime; + + if (demux_Control(demux, DEMUX_GET_POSITION, &newpos)) + newpos = 0.; + if (demux_Control(demux, DEMUX_GET_LENGTH, &newlen)) + newlen = 0; + if (demux_Control(demux, DEMUX_GET_TIME, &newtime)) + newtime = 0; + + vlc_mutex_lock(&dc->lock); + dc->stats.position = newpos; + dc->stats.length = newlen; + dc->stats.time = newtime; + vlc_mutex_unlock(&dc->lock); + + next_update = mdate() + (CLOCK_FREQ / 4); + } + while (demux_Demux(demux) > 0); + + demux_Delete(demux); + return NULL; +} + +vlc_demux_chained_t *vlc_demux_chained_New(vlc_object_t *parent, + const char *name, es_out_t *out) +{ + vlc_demux_chained_t *dc = malloc(sizeof (*dc) + strlen(name) + 1); + if (unlikely(dc == NULL)) + return NULL; + + dc->fifo = vlc_stream_fifo_New(parent); + if (dc->fifo == NULL) + { + free(dc); + return NULL; + } + + dc->stats.position = 0.; + dc->stats.length = 0; + dc->stats.time = 0; + dc->out = out; + strcpy(dc->name, name); + + if (vlc_clone(&dc->thread, vlc_demux_chained_Thread, dc, + VLC_THREAD_PRIORITY_INPUT)) + { + stream_Delete(dc->fifo); + vlc_stream_fifo_Close(dc->fifo); + free(dc); + dc = NULL; + } + return dc; +} + +void vlc_demux_chained_Send(vlc_demux_chained_t *dc, block_t *block) +{ + vlc_stream_fifo_Queue(dc->fifo, block); +} + +int vlc_demux_chained_ControlVa(vlc_demux_chained_t *dc, int query, va_list ap) +{ + switch (query) + { + case DEMUX_GET_POSITION: + vlc_mutex_lock(&dc->lock); + *va_arg(ap, double *) = dc->stats.position; + vlc_mutex_unlock(&dc->lock); + break; + case DEMUX_GET_LENGTH: + vlc_mutex_lock(&dc->lock); + *va_arg(ap, int64_t *) = dc->stats.length; + vlc_mutex_unlock(&dc->lock); + break; + case DEMUX_GET_TIME: + vlc_mutex_lock(&dc->lock); + *va_arg(ap, int64_t *) = dc->stats.time; + vlc_mutex_unlock(&dc->lock); + break; + default: + return VLC_EGENERIC; + } + return VLC_SUCCESS; +} + +void vlc_demux_chained_Delete(vlc_demux_chained_t *dc) +{ + vlc_stream_fifo_Close(dc->fifo); + vlc_join(dc->thread, NULL); + free(dc); +} diff --git a/src/libvlccore.sym b/src/libvlccore.sym index c2f270b..ba9f581 100644 --- a/src/libvlccore.sym +++ b/src/libvlccore.sym @@ -97,6 +97,10 @@ demux_PacketizerNew demux_New demux_vaControl demux_vaControlHelper +vlc_demux_chained_New +vlc_demux_chained_Send +vlc_demux_chained_ControlVa +vlc_demux_chained_Delete EndMD5 es_format_Clean es_format_Copy _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
