1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 1999-2016 VLC authors and VideoLAN
6 * Authors: Laurent Aimar <fenrir _AT_ videolan _DOT_ org>
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU Lesser General Public License as published by
11 * the Free Software Foundation; either version 2.1 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
31 #include <vlc_common.h>
32 #include <vlc_demux.h>
35 struct vlc_demux_chained_t
53 static void *vlc_demux_chained_Thread(void *data
)
55 vlc_demux_chained_t
*dc
= data
;
56 demux_t
*demux
= demux_NewAdvanced(dc
->fifo
, NULL
, "", dc
->name
, "",
57 dc
->fifo
, dc
->out
, false);
60 vlc_stream_Delete(dc
->fifo
);
64 /* Stream FIFO cannot apply DVB filters.
65 * Get all programs and let the E/S output sort them out. */
66 demux_Control(demux
, DEMUX_SET_GROUP
, -1, NULL
);
69 mtime_t next_update
= 0;
72 if (demux_TestAndClearFlags(demux
, UINT_MAX
) || mdate() >= next_update
)
75 int64_t newlen
, newtime
;
77 if (demux_Control(demux
, DEMUX_GET_POSITION
, &newpos
))
79 if (demux_Control(demux
, DEMUX_GET_LENGTH
, &newlen
))
81 if (demux_Control(demux
, DEMUX_GET_TIME
, &newtime
))
84 vlc_mutex_lock(&dc
->lock
);
85 dc
->stats
.position
= newpos
;
86 dc
->stats
.length
= newlen
;
87 dc
->stats
.time
= newtime
;
88 vlc_mutex_unlock(&dc
->lock
);
90 next_update
= mdate() + (CLOCK_FREQ
/ 4);
92 while (demux_Demux(demux
) > 0);
98 vlc_demux_chained_t
*vlc_demux_chained_New(vlc_object_t
*parent
,
99 const char *name
, es_out_t
*out
)
101 vlc_demux_chained_t
*dc
= malloc(sizeof (*dc
) + strlen(name
) + 1);
102 if (unlikely(dc
== NULL
))
105 dc
->fifo
= vlc_stream_fifo_New(parent
);
106 if (dc
->fifo
== NULL
)
112 dc
->stats
.position
= 0.;
113 dc
->stats
.length
= 0;
116 strcpy(dc
->name
, name
);
118 vlc_mutex_init(&dc
->lock
);
120 if (vlc_clone(&dc
->thread
, vlc_demux_chained_Thread
, dc
,
121 VLC_THREAD_PRIORITY_INPUT
))
123 vlc_stream_Delete(dc
->fifo
);
124 vlc_stream_fifo_Close(dc
->fifo
);
125 vlc_mutex_destroy(&dc
->lock
);
132 void vlc_demux_chained_Send(vlc_demux_chained_t
*dc
, block_t
*block
)
134 vlc_stream_fifo_Queue(dc
->fifo
, block
);
137 int vlc_demux_chained_ControlVa(vlc_demux_chained_t
*dc
, int query
, va_list ap
)
141 case DEMUX_GET_POSITION
:
142 vlc_mutex_lock(&dc
->lock
);
143 *va_arg(ap
, double *) = dc
->stats
.position
;
144 vlc_mutex_unlock(&dc
->lock
);
146 case DEMUX_GET_LENGTH
:
147 vlc_mutex_lock(&dc
->lock
);
148 *va_arg(ap
, int64_t *) = dc
->stats
.length
;
149 vlc_mutex_unlock(&dc
->lock
);
152 vlc_mutex_lock(&dc
->lock
);
153 *va_arg(ap
, int64_t *) = dc
->stats
.time
;
154 vlc_mutex_unlock(&dc
->lock
);
162 void vlc_demux_chained_Delete(vlc_demux_chained_t
*dc
)
164 vlc_stream_fifo_Close(dc
->fifo
);
165 vlc_join(dc
->thread
, NULL
);
166 vlc_mutex_destroy(&dc
->lock
);