/src/vlc/modules/demux/mpeg/ts_streams.c
Line | Count | Source |
1 | | /***************************************************************************** |
2 | | * ts_streams.c: Transport Stream input module for VLC. |
3 | | ***************************************************************************** |
4 | | * Copyright (C) 2004-2016 VLC authors and VideoLAN |
5 | | * |
6 | | * This program is free software; you can redistribute it and/or modify it |
7 | | * under the terms of the GNU Lesser General Public License as published by |
8 | | * the Free Software Foundation; either version 2.1 of the License, or |
9 | | * (at your option) any later version. |
10 | | * |
11 | | * This program is distributed in the hope that it will be useful, |
12 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | | * GNU Lesser General Public License for more details. |
15 | | * |
16 | | * You should have received a copy of the GNU General Public License |
17 | | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
18 | | *****************************************************************************/ |
19 | | #ifdef HAVE_CONFIG_H |
20 | | # include "config.h" |
21 | | #endif |
22 | | |
23 | | #include <vlc_common.h> |
24 | | |
25 | | #include "ts_pid.h" |
26 | | #include "ts_streams.h" |
27 | | #include "ts_streams_private.h" |
28 | | |
29 | | #include <vlc_demux.h> |
30 | | #include <vlc_es.h> |
31 | | #include <vlc_es_out.h> |
32 | | |
33 | | #include "sections.h" |
34 | | #include "ts_pid.h" |
35 | | #include "ts.h" |
36 | | |
37 | | #include "ts_psi.h" |
38 | | #include "ts_si.h" |
39 | | #include "ts_psip.h" |
40 | | |
41 | | ts_pat_t *ts_pat_New( demux_t *p_demux ) |
42 | 11.1k | { |
43 | 11.1k | ts_pat_t *pat = malloc( sizeof( ts_pat_t ) ); |
44 | 11.1k | if( !pat ) |
45 | 0 | return NULL; |
46 | | |
47 | 11.1k | pat->p_ctx = ts_psi_context_New( p_demux ); |
48 | 11.1k | if( !pat->p_ctx ) |
49 | 0 | { |
50 | 0 | free( pat ); |
51 | 0 | return NULL; |
52 | 0 | } |
53 | | |
54 | 11.1k | pat->i_version = -1; |
55 | 11.1k | pat->i_ts_id = -1; |
56 | 11.1k | pat->b_generated = false; |
57 | 11.1k | ARRAY_INIT( pat->programs ); |
58 | | |
59 | 11.1k | return pat; |
60 | 11.1k | } |
61 | | |
62 | | void ts_pat_Del( demux_t *p_demux, ts_pat_t *pat ) |
63 | 11.1k | { |
64 | 11.1k | ts_psi_context_Delete( pat->p_ctx ); |
65 | 23.9k | for( int i=0; i<pat->programs.i_size; i++ ) |
66 | 12.7k | PIDRelease( p_demux, pat->programs.p_elems[i] ); |
67 | 11.1k | ARRAY_RESET( pat->programs ); |
68 | 11.1k | free( pat ); |
69 | 11.1k | } |
70 | | |
71 | | ts_pmt_t *ts_pat_Get_pmt( ts_pat_t *pat, uint16_t i_number ) |
72 | 441 | { |
73 | 441 | ts_pmt_t *p_pmt = NULL; |
74 | 1.16k | for( int i=0; i<pat->programs.i_size; i++ ) |
75 | 1.01k | { |
76 | 1.01k | p_pmt = pat->programs.p_elems[i]->u.p_pmt; |
77 | 1.01k | if( p_pmt->i_number == i_number ) |
78 | 286 | break; |
79 | 1.01k | } |
80 | 441 | return p_pmt; |
81 | 441 | } |
82 | | |
83 | | ts_pmt_t *ts_pmt_New( demux_t *p_demux ) |
84 | 12.9k | { |
85 | 12.9k | ts_pmt_t *pmt = malloc( sizeof( ts_pmt_t ) ); |
86 | 12.9k | if( !pmt ) |
87 | 0 | return NULL; |
88 | | |
89 | 12.9k | pmt->p_ctx = ts_psi_context_New( p_demux ); |
90 | 12.9k | if( !pmt->p_ctx ) |
91 | 0 | { |
92 | 0 | free( pmt ); |
93 | 0 | return NULL; |
94 | 0 | } |
95 | | |
96 | 12.9k | ARRAY_INIT( pmt->e_streams ); |
97 | | |
98 | | //pmt->pmtcache = NULL; |
99 | 12.9k | pmt->i_version = -1; |
100 | 12.9k | pmt->i_number = -1; |
101 | 12.9k | pmt->i_pid_pcr = 0x1FFF; |
102 | 12.9k | pmt->b_selected = false; |
103 | 12.9k | pmt->iod = NULL; |
104 | 12.9k | pmt->od.i_version = -1; |
105 | 12.9k | ARRAY_INIT( pmt->od.objects ); |
106 | | |
107 | 12.9k | pmt->i_last_dts = VLC_TICK_INVALID; |
108 | 12.9k | pmt->i_last_dts_byte = 0; |
109 | 12.9k | pmt->b_last_dts_probed = false; |
110 | | |
111 | 12.9k | pmt->p_atsc_si_basepid = NULL; |
112 | 12.9k | pmt->p_si_sdt_pid = NULL; |
113 | | |
114 | 12.9k | pmt->pcr.i_current = VLC_TICK_INVALID; |
115 | 12.9k | pmt->pcr.i_first = VLC_TICK_INVALID; |
116 | 12.9k | pmt->pcr.b_disable = false; |
117 | 12.9k | pmt->pcr.i_first_dts = VLC_TICK_INVALID; |
118 | 12.9k | pmt->pcr.i_pcroffset = -1; |
119 | | |
120 | 12.9k | pmt->pcr.b_fix_done = false; |
121 | | |
122 | 12.9k | pmt->eit.i_event_length = 0; |
123 | 12.9k | pmt->eit.i_event_start = 0; |
124 | | |
125 | 12.9k | pmt->arib.i_download_id = -1; |
126 | 12.9k | pmt->arib.i_logo_id = -1; |
127 | | |
128 | 12.9k | return pmt; |
129 | 12.9k | } |
130 | | |
131 | | void ts_pmt_Del( demux_t *p_demux, ts_pmt_t *pmt ) |
132 | 12.9k | { |
133 | 12.9k | ts_psi_context_Delete( pmt->p_ctx ); |
134 | 53.9k | for( int i=0; i<pmt->e_streams.i_size; i++ ) |
135 | 40.9k | PIDRelease( p_demux, pmt->e_streams.p_elems[i] ); |
136 | 12.9k | ARRAY_RESET( pmt->e_streams ); |
137 | 12.9k | if( pmt->p_atsc_si_basepid ) |
138 | 71 | PIDRelease( p_demux, pmt->p_atsc_si_basepid ); |
139 | 12.9k | if( pmt->p_si_sdt_pid ) |
140 | 10.2k | PIDRelease( p_demux, pmt->p_si_sdt_pid ); |
141 | 12.9k | if( pmt->iod ) |
142 | 8.92k | ODFree( pmt->iod ); |
143 | 27.6k | for( int i=0; i<pmt->od.objects.i_size; i++ ) |
144 | 14.6k | ODFree( pmt->od.objects.p_elems[i] ); |
145 | 12.9k | ARRAY_RESET( pmt->od.objects ); |
146 | 12.9k | if( pmt->i_number > -1 ) |
147 | 12.9k | es_out_Control( p_demux->out, ES_OUT_DEL_GROUP, pmt->i_number ); |
148 | | |
149 | 12.9k | free( pmt ); |
150 | 12.9k | } |
151 | | |
152 | | ts_es_t * ts_es_New( ts_pmt_t *p_program ) |
153 | 41.0k | { |
154 | 41.0k | ts_es_t *p_es = malloc( sizeof(*p_es) ); |
155 | 41.0k | if( p_es ) |
156 | 41.0k | { |
157 | 41.0k | p_es->p_program = p_program; |
158 | 41.0k | p_es->id = NULL; |
159 | 41.0k | p_es->i_sl_es_id = 0; |
160 | 41.0k | p_es->i_next_block_flags = 0; |
161 | 41.0k | p_es->p_extraes = NULL; |
162 | 41.0k | p_es->p_next = NULL; |
163 | 41.0k | p_es->b_interlaced = false; |
164 | 41.0k | es_format_Init( &p_es->fmt, UNKNOWN_ES, 0 ); |
165 | 41.0k | p_es->fmt.i_group = p_program->i_number; |
166 | 41.0k | p_es->metadata.i_application_format_identifier = 0; |
167 | 41.0k | p_es->metadata.i_format_identifier = 0; |
168 | 41.0k | p_es->metadata.i_service_id = 0; |
169 | 41.0k | } |
170 | 41.0k | return p_es; |
171 | 41.0k | } |
172 | | |
173 | | static void ts_pes_es_Clean( demux_t *p_demux, ts_es_t *p_es ) |
174 | 41.0k | { |
175 | 41.0k | demux_sys_t *p_sys = p_demux->p_sys; |
176 | | |
177 | 41.0k | if( p_es->id ) |
178 | 17.5k | { |
179 | | /* Ensure we don't wait for overlap hacks #14257 */ |
180 | 17.5k | es_out_Control( p_demux->out, ES_OUT_SET_ES_STATE, p_es->id, false ); |
181 | 17.5k | es_out_Del( p_demux->out, p_es->id ); |
182 | 17.5k | p_sys->i_pmt_es--; |
183 | 17.5k | } |
184 | 41.0k | es_format_Clean( &p_es->fmt ); |
185 | 41.0k | } |
186 | | |
187 | | void ts_stream_Add_es( ts_stream_t *p_pes, ts_es_t *p_es, bool b_extra ) |
188 | 0 | { |
189 | 0 | ts_es_t **pp_es = (b_extra && p_pes->p_es) ? /* Ensure extra has main es */ |
190 | 0 | &p_pes->p_es->p_extraes : |
191 | 0 | &p_pes->p_es; |
192 | 0 | if( likely(!*pp_es) ) |
193 | 0 | { |
194 | 0 | *pp_es = p_es; |
195 | 0 | } |
196 | 0 | else |
197 | 0 | { |
198 | 0 | ts_es_t *p_next = (*pp_es)->p_next; |
199 | 0 | (*pp_es)->p_next = p_es; |
200 | 0 | p_es->p_next = p_next; |
201 | 0 | } |
202 | 0 | } |
203 | | |
204 | | ts_es_t * ts_stream_Find_es( ts_stream_t *p_pes, const ts_pmt_t *p_pmt ) |
205 | 0 | { |
206 | 0 | for( ts_es_t *p_es = p_pes->p_es; p_es; p_es = p_es->p_next ) |
207 | 0 | { |
208 | 0 | if( p_es->p_program == p_pmt ) |
209 | 0 | return p_es; |
210 | 0 | } |
211 | 0 | return NULL; |
212 | 0 | } |
213 | | |
214 | | ts_es_t * ts_stream_Extract_es( ts_stream_t *p_pes, const ts_pmt_t *p_pmt ) |
215 | 0 | { |
216 | 0 | ts_es_t **pp_prev = &p_pes->p_es; |
217 | 0 | for( ts_es_t *p_es = p_pes->p_es; p_es; p_es = p_es->p_next ) |
218 | 0 | { |
219 | 0 | if( p_es->p_program == p_pmt ) |
220 | 0 | { |
221 | 0 | *pp_prev = p_es->p_next; |
222 | 0 | p_es->p_next = NULL; |
223 | 0 | return p_es; |
224 | 0 | } |
225 | 0 | pp_prev = &p_es->p_next; |
226 | 0 | } |
227 | 0 | return NULL; |
228 | 0 | } |
229 | | |
230 | | size_t ts_Count_es( const ts_es_t *p_es, bool b_active, const ts_pmt_t *p_pmt ) |
231 | 0 | { |
232 | 0 | size_t i=0; |
233 | 0 | for( ; p_es; p_es = p_es->p_next ) |
234 | 0 | { |
235 | 0 | i += ( b_active ) ? !!p_es->id : ( ( !p_pmt || p_pmt == p_es->p_program ) ? 1 : 0 ); |
236 | 0 | i += ts_Count_es( p_es->p_extraes, b_active, p_pmt ); |
237 | 0 | } |
238 | 0 | return i; |
239 | 0 | } |
240 | | |
241 | | static void ts_pes_ChainDelete_es( demux_t *p_demux, ts_es_t *p_es ) |
242 | 82.1k | { |
243 | 123k | while( p_es ) |
244 | 41.0k | { |
245 | 41.0k | ts_es_t *p_next = p_es->p_next; |
246 | 41.0k | ts_pes_ChainDelete_es( p_demux, p_es->p_extraes ); |
247 | 41.0k | ts_pes_es_Clean( p_demux, p_es ); |
248 | 41.0k | free( p_es ); |
249 | 41.0k | p_es = p_next; |
250 | 41.0k | } |
251 | 82.1k | } |
252 | | |
253 | | ts_stream_t *ts_stream_New( demux_t *p_demux, ts_pmt_t *p_program ) |
254 | 40.9k | { |
255 | 40.9k | VLC_UNUSED(p_demux); |
256 | 40.9k | ts_stream_t *pes = malloc( sizeof( ts_stream_t ) ); |
257 | 40.9k | if( !pes ) |
258 | 0 | return NULL; |
259 | | |
260 | 40.9k | pes->p_es = ts_es_New( p_program ); |
261 | 40.9k | if( !pes->p_es ) |
262 | 0 | { |
263 | 0 | free( pes ); |
264 | 0 | return NULL; |
265 | 0 | } |
266 | 40.9k | pes->i_stream_type = 0; |
267 | 40.9k | pes->transport = TS_TRANSPORT_PES; |
268 | 40.9k | pes->gather.i_data_size = 0; |
269 | 40.9k | pes->gather.i_gathered = 0; |
270 | 40.9k | pes->gather.p_data = NULL; |
271 | 40.9k | pes->gather.pp_last = &pes->gather.p_data; |
272 | 40.9k | pes->gather.i_saved = 0; |
273 | 40.9k | pes->gather.i_block_flags = 0; |
274 | 40.9k | pes->gather.i_append_pcr = TS_90KHZ_INVALID; |
275 | 40.9k | pes->b_broken_PUSI_conformance = false; |
276 | 40.9k | pes->b_always_receive = false; |
277 | 40.9k | pes->p_sections_proc = NULL; |
278 | 40.9k | pes->p_proc = NULL; |
279 | 40.9k | pes->prepcr.p_head = NULL; |
280 | 40.9k | pes->prepcr.pp_last = &pes->prepcr.p_head; |
281 | 40.9k | pes->i_last_dts = VLC_TICK_INVALID; |
282 | | |
283 | 40.9k | return pes; |
284 | 40.9k | } |
285 | | |
286 | | void ts_stream_Del( demux_t *p_demux, ts_stream_t *pes ) |
287 | 40.9k | { |
288 | 40.9k | ts_pes_ChainDelete_es( p_demux, pes->p_es ); |
289 | | |
290 | 40.9k | if( pes->gather.p_data ) |
291 | 5.54k | block_ChainRelease( pes->gather.p_data ); |
292 | | |
293 | 40.9k | if( pes->p_sections_proc ) |
294 | 17.8k | ts_sections_processor_ChainDelete( pes->p_sections_proc ); |
295 | | |
296 | 40.9k | if( pes->p_proc ) |
297 | 17.8k | ts_stream_processor_Delete( pes->p_proc ); |
298 | | |
299 | 40.9k | if( pes->prepcr.p_head ) |
300 | 395 | block_ChainRelease( pes->prepcr.p_head ); |
301 | | |
302 | 40.9k | free( pes ); |
303 | 40.9k | } |
304 | | |
305 | | ts_si_t *ts_si_New( demux_t *p_demux ) |
306 | 10.4k | { |
307 | 10.4k | ts_si_t *si = malloc( sizeof( ts_si_t ) ); |
308 | 10.4k | if( !si ) |
309 | 0 | return NULL; |
310 | | |
311 | 10.4k | si->p_ctx = ts_si_context_New( p_demux ); |
312 | 10.4k | if( !si->p_ctx ) |
313 | 0 | { |
314 | 0 | free( si ); |
315 | 0 | return NULL; |
316 | 0 | } |
317 | | |
318 | 10.4k | si->eitpid = NULL; |
319 | 10.4k | si->tdtpid = NULL; |
320 | 10.4k | si->cdtpid = NULL; |
321 | | |
322 | 10.4k | return si; |
323 | 10.4k | } |
324 | | |
325 | | void ts_si_Del( demux_t *p_demux, ts_si_t *si ) |
326 | 10.4k | { |
327 | 10.4k | ts_si_context_Delete( si->p_ctx ); |
328 | 10.4k | if( si->eitpid ) |
329 | 89 | PIDRelease( p_demux, si->eitpid ); |
330 | 10.4k | if( si->tdtpid ) |
331 | 89 | PIDRelease( p_demux, si->tdtpid ); |
332 | 10.4k | if( si->cdtpid ) |
333 | 0 | PIDRelease( p_demux, si->cdtpid ); |
334 | 10.4k | free( si ); |
335 | 10.4k | } |
336 | | |
337 | | void ts_psip_Del( demux_t *p_demux, ts_psip_t *psip ) |
338 | 71 | { |
339 | 71 | ts_psip_context_Delete( psip->p_ctx ); |
340 | | |
341 | 71 | ts_pes_ChainDelete_es( p_demux, psip->p_eas_es ); |
342 | | |
343 | 71 | for( int i=0; i<psip->eit.i_size; i++ ) |
344 | 0 | PIDRelease( p_demux, psip->eit.p_elems[i] ); |
345 | 71 | ARRAY_RESET( psip->eit ); |
346 | | |
347 | 71 | free( psip ); |
348 | 71 | } |
349 | | |
350 | | ts_psip_t *ts_psip_New( demux_t *p_demux ) |
351 | 71 | { |
352 | 71 | ts_psip_t *psip = malloc( sizeof( ts_psip_t ) ); |
353 | 71 | if( !psip ) |
354 | 0 | return NULL; |
355 | | |
356 | 71 | psip->p_ctx = ts_psip_context_New( p_demux ); |
357 | 71 | if( !psip->p_ctx ) |
358 | 0 | { |
359 | 0 | free( psip ); |
360 | 0 | return NULL; |
361 | 0 | } |
362 | | |
363 | 71 | ARRAY_INIT( psip->eit ); |
364 | 71 | psip->p_eas_es = NULL; |
365 | | |
366 | 71 | return psip; |
367 | 71 | } |