Bug Summary

File:demux.c
Location:line 723, column 32
Description:Call to 'malloc' has an allocation size of 0 bytes

Annotated Source Code

1/*****************************************************************************
2 * demux.c
3 *****************************************************************************
4 * Copyright (C) 2004, 2008-2011 VideoLAN
5 *
6 * Authors: Christophe Massiot <massiot@via.ecp.fr>
7 * Andy Gatward <a.j.gatward@reading.ac.uk>
8 * Marian Ďurkovič <md@bts.sk>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23 *****************************************************************************/
24
25#include <stdlib.h>
26#include <stdio.h>
27#include <stdint.h>
28#include <stdbool.h>
29#include <stddef.h>
30#include <string.h>
31#include <stdarg.h>
32#include <inttypes.h>
33#include <sys/socket.h>
34#include <netinet/in.h>
35#include <arpa/inet.h>
36
37#include "dvblast.h"
38#include "en50221.h"
39
40#ifdef HAVE_ICONV
41#include <iconv.h>
42#endif
43
44#include <bitstream/mpeg/ts.h>
45#include <bitstream/mpeg/pes.h>
46#include <bitstream/mpeg/psi.h>
47#include <bitstream/dvb/si.h>
48#include <bitstream/dvb/si_print.h>
49#include <bitstream/mpeg/psi_print.h>
50
51extern bool_Bool b_enable_emm;
52extern bool_Bool b_enable_ecm;
53
54/*****************************************************************************
55 * Local declarations
56 *****************************************************************************/
57#define MIN_SECTION_FRAGMENT8 PSI_HEADER_SIZE_SYNTAX18
58
59typedef struct ts_pid_t
60{
61 int i_refcount;
62 int i_psi_refcount;
63 bool_Bool b_pes;
64 int8_t i_last_cc;
65 int i_demux_fd;
66 /* b_emm is set to true when PID carries EMM packet
67 and should be outputed in all services */
68 bool_Bool b_emm;
69
70 /* PID info and stats */
71 mtime_t i_bytes_ts;
72 unsigned long i_packets_passed;
73 ts_pid_info_t info;
74
75 /* biTStream PSI section gathering */
76 uint8_t *p_psi_buffer;
77 uint16_t i_psi_buffer_used;
78
79 output_t **pp_outputs;
80 int i_nb_outputs;
81} ts_pid_t;
82
83typedef struct sid_t
84{
85 uint16_t i_sid, i_pmt_pid;
86 uint8_t *p_current_pmt;
87} sid_t;
88
89ts_pid_t p_pids[MAX_PIDS8192];
90static sid_t **pp_sids = NULL((void*)0);
91static int i_nb_sids = 0;
92
93static PSI_TABLE_DECLARE(pp_current_pat_sections)uint8_t *pp_current_pat_sections[256];
94static PSI_TABLE_DECLARE(pp_next_pat_sections)uint8_t *pp_next_pat_sections[256];
95static PSI_TABLE_DECLARE(pp_current_cat_sections)uint8_t *pp_current_cat_sections[256];
96static PSI_TABLE_DECLARE(pp_next_cat_sections)uint8_t *pp_next_cat_sections[256];
97static PSI_TABLE_DECLARE(pp_current_nit_sections)uint8_t *pp_current_nit_sections[256];
98static PSI_TABLE_DECLARE(pp_next_nit_sections)uint8_t *pp_next_nit_sections[256];
99static PSI_TABLE_DECLARE(pp_current_sdt_sections)uint8_t *pp_current_sdt_sections[256];
100static PSI_TABLE_DECLARE(pp_next_sdt_sections)uint8_t *pp_next_sdt_sections[256];
101static mtime_t i_last_dts = -1;
102static int i_demux_fd;
103static int i_nb_errors = 0;
104static mtime_t i_last_error = 0;
105static mtime_t i_last_reset = 0;
106
107#ifdef HAVE_ICONV
108static iconv_t iconv_handle = (iconv_t)-1;
109#endif
110
111/*****************************************************************************
112 * Local prototypes
113 *****************************************************************************/
114static void demux_Handle( block_t *p_ts );
115static void SetDTS( block_t *p_list );
116static void SetPID( uint16_t i_pid );
117static void SetPID_EMM( uint16_t i_pid );
118static void UnsetPID( uint16_t i_pid );
119static void StartPID( output_t *p_output, uint16_t i_pid );
120static void StopPID( output_t *p_output, uint16_t i_pid );
121static void SelectPID( uint16_t i_sid, uint16_t i_pid );
122static void UnselectPID( uint16_t i_sid, uint16_t i_pid );
123static void SelectPMT( uint16_t i_sid, uint16_t i_pid );
124static void UnselectPMT( uint16_t i_sid, uint16_t i_pid );
125static void GetPIDS( uint16_t **ppi_wanted_pids, int *pi_nb_wanted_pids,
126 uint16_t i_sid,
127 const uint16_t *pi_pids, int i_nb_pids );
128static bool_Bool SIDIsSelected( uint16_t i_sid );
129static bool_Bool PIDWouldBeSelected( uint8_t *p_es );
130static bool_Bool PMTNeedsDescrambling( uint8_t *p_pmt );
131static void FlushEIT( output_t *p_output, mtime_t i_dts );
132static void SendTDT( block_t *p_ts );
133static void SendEMM( block_t *p_ts );
134static void NewPAT( output_t *p_output );
135static void NewPMT( output_t *p_output );
136static void NewNIT( output_t *p_output );
137static void NewSDT( output_t *p_output );
138static void HandlePSIPacket( uint8_t *p_ts, mtime_t i_dts );
139static const char *get_pid_desc(uint16_t i_pid, uint16_t *i_sid);
140
141/*
142 * Remap an ES pid to a fixed value.
143 * Multiple streams of the same type use sequential pids
144 * Returns the new pid and updates the map tables
145*/
146static uint16_t map_es_pid(output_t * p_output, uint8_t *p_es, uint16_t i_pid)
147{
148 uint16_t i_newpid = i_pid;
149 uint16_t i_stream_type = pmtn_get_streamtype(p_es);
150
151 if ( !b_do_remap && !p_output->config.b_do_remap )
152 return i_pid;
153
154 msg_Dbg(NULL((void*)0), "REMAP: Found elementary stream type 0x%02x with original PID 0x%x (%u):", i_stream_type, i_pid, i_pid);
155
156 switch ( i_stream_type )
157 {
158 case 0x03: /* audio MPEG-1 */
159 case 0x04: /* audio */
160 case 0x0f: /* audio AAC ADTS */
161 case 0x11: /* audio AAC LATM */
162 case 0x81: /* ATSC AC-3 */
163 case 0x87: /* ATSC Enhanced AC-3 */
164 if ( b_do_remap )
165 i_newpid = pi_newpids[I_APID];
166 else
167 i_newpid = p_output->config.pi_confpids[I_APID];
168 break;
169 case 0x01: /* video MPEG-1 */
170 case 0x02: /* video */
171 case 0x10: /* video MPEG-4 */
172 case 0x1b: /* video H264 */
173 if ( b_do_remap )
174 i_newpid = pi_newpids[I_VPID];
175 else
176 i_newpid = p_output->config.pi_confpids[I_VPID];
177 break;
178 case 0x06: { /* PES Private Data - We must check the descriptors */
179 /* By default, nothing identified */
180 uint8_t SubStreamType = N_MAP_PIDS4;
181 uint16_t j = 0;
182 const uint8_t *p_desc;
183 /* Loop over the descriptors */
184 while ( (p_desc = descs_get_desc( pmtn_get_descs( p_es ), j )) != NULL((void*)0) )
185 {
186 /* Get the descriptor tag */
187 uint8_t i_tag = desc_get_tag( p_desc );
188 j++;
189 /* Check if the tag is: A/52, Enhanced A/52, DTS, AAC */
190 if (i_tag == 0x6a || i_tag == 0x7a || i_tag == 0x7b || i_tag == 0x7c)
191 SubStreamType=I_APID;
192 /* Check if the tag is: VBI + teletext, teletext, dvbsub */
193 if (i_tag == 0x46 || i_tag == 0x56 || i_tag == 0x59)
194 SubStreamType=I_SPUPID;
195 }
196 /* Audio found */
197 if (SubStreamType==I_APID) {
198 msg_Dbg(NULL((void*)0), "REMAP: PES Private Data stream identified as [Audio]");
199 if ( b_do_remap )
200 i_newpid = pi_newpids[I_APID];
201 else
202 i_newpid = p_output->config.pi_confpids[I_APID];
203 }
204 /* Subtitle found */
205 if (SubStreamType==I_SPUPID) {
206 msg_Dbg(NULL((void*)0), "REMAP: PES Private Data stream identified as [Subtitle]");
207 if ( b_do_remap )
208 i_newpid = pi_newpids[I_SPUPID];
209 else
210 i_newpid = p_output->config.pi_confpids[I_SPUPID];
211 }
212 break;
213 }
214 }
215
216 if (!i_newpid)
217 return i_pid;
218
219 /* Got the new base for the mapped pid. Find the next free one
220 we do this to ensure that multiple audios get unique pids */
221 while (p_output->pi_freepids[i_newpid] != UNUSED_PID(8192 + 1))
222 i_newpid++;
223 p_output->pi_freepids[i_newpid] = i_pid; /* Mark as in use */
224 p_output->pi_newpids[i_pid] = i_newpid; /* Save the new pid */
225
226 msg_Dbg(NULL((void*)0), "REMAP: => Elementary stream is remapped to PID 0x%x (%u)", i_newpid, i_newpid);
227
228 return i_newpid;
229}
230
231/*****************************************************************************
232 * FindSID
233 *****************************************************************************/
234static inline sid_t *FindSID( uint16_t i_sid )
235{
236 int i;
237
238 for ( i = 0; i < i_nb_sids; i++ )
239 {
240 sid_t *p_sid = pp_sids[i];
241 if ( p_sid->i_sid == i_sid )
242 return p_sid;
243 }
244 return NULL((void*)0);
245}
246
247/*****************************************************************************
248 * demux_Open
249 *****************************************************************************/
250void demux_Open( void )
251{
252 int i;
253
254 memset( p_pids, 0, sizeof(p_pids) );
255
256 pf_Open();
257
258 for ( i = 0; i < MAX_PIDS8192; i++ )
259 {
260 p_pids[i].i_last_cc = -1;
261 p_pids[i].i_demux_fd = -1;
262 psi_assemble_init( &p_pids[i].p_psi_buffer,
263 &p_pids[i].i_psi_buffer_used );
264 }
265
266 if ( b_budget_mode )
267 i_demux_fd = pf_SetFilter(8192);
268
269 psi_table_init( pp_current_pat_sections );
270 psi_table_init( pp_next_pat_sections );
271 SetPID(PAT_PID0x0);
272 p_pids[PAT_PID0x0].i_psi_refcount++;
273
274 if ( b_enable_emm )
275 {
276 psi_table_init( pp_current_cat_sections );
277 psi_table_init( pp_next_cat_sections );
278 SetPID_EMM(CAT_PID0x01);
279 p_pids[CAT_PID0x01].i_psi_refcount++;
280 }
281
282 SetPID(NIT_PID0x10);
283 p_pids[NIT_PID0x10].i_psi_refcount++;
284
285 psi_table_init( pp_current_sdt_sections );
286 psi_table_init( pp_next_sdt_sections );
287 SetPID(SDT_PID0x11);
288 p_pids[SDT_PID0x11].i_psi_refcount++;
289
290 SetPID(EIT_PID0x12);
291 p_pids[EIT_PID0x12].i_psi_refcount++;
292
293 SetPID(RST_PID0x13);
294
295 SetPID(TDT_PID0x14);
296}
297
298/*****************************************************************************
299 * demux_Close
300 *****************************************************************************/
301void demux_Close( void )
302{
303 int i;
304
305 psi_table_free( pp_current_pat_sections );
306 psi_table_free( pp_next_pat_sections );
307 psi_table_free( pp_current_cat_sections );
308 psi_table_free( pp_next_cat_sections );
309 psi_table_free( pp_current_nit_sections );
310 psi_table_free( pp_next_nit_sections );
311 psi_table_free( pp_current_sdt_sections );
312 psi_table_free( pp_next_sdt_sections );
313
314 for ( i = 0; i < MAX_PIDS8192; i++ )
315 {
316 free( p_pids[i].p_psi_buffer );
317 free( p_pids[i].pp_outputs );
318 }
319
320 for ( i = 0; i < i_nb_sids; i++ )
321 {
322 sid_t *p_sid = pp_sids[i];
323 free( p_sid->p_current_pmt );
324 free( p_sid );
325 }
326 free( pp_sids );
327
328#ifdef HAVE_ICONV
329 if (iconv_handle != (iconv_t)-1) {
330 iconv_close(iconv_handle);
331 iconv_handle = (iconv_t)-1;
332 }
333#endif
334}
335
336/*****************************************************************************
337 * demux_Run
338 *****************************************************************************/
339void demux_Run( block_t *p_ts )
340{
341 SetDTS( p_ts );
342
343 while ( p_ts != NULL((void*)0) )
344 {
345 block_t *p_next = p_ts->p_next;
346 p_ts->p_next = NULL((void*)0);
347 demux_Handle( p_ts );
348 p_ts = p_next;
349 }
350}
351
352/*****************************************************************************
353 * demux_Handle
354 *****************************************************************************/
355static void demux_Handle( block_t *p_ts )
356{
357 uint16_t i_pid = ts_get_pid( p_ts->p_ts );
358 uint8_t i_cc = ts_get_cc( p_ts->p_ts );
359 int i;
360
361 if ( !ts_validate( p_ts->p_ts ) )
362 {
363 msg_Warn( NULL((void*)0), "lost TS sync" );
364 switch ( i_print_type )
365 {
366 case PRINT_XML:
367 printf("<ERROR type=\"invalid_ts\"/>\n");
368 break;
369 case PRINT_TEXT:
370 printf("lost TS sync\n");
371 break;
372 default:
373 break;
374 }
375
376 block_Delete( p_ts );
377 return;
378 }
379
380 if ( i_pid != PADDING_PID8191 )
381 p_pids[i_pid].info.i_scrambling = ts_get_scrambling( p_ts->p_ts );
382
383 p_pids[i_pid].info.i_last_packet_ts = i_wallclock;
384 p_pids[i_pid].info.i_packets++;
385
386 p_pids[i_pid].i_packets_passed++;
387
388 /* Calculate bytes_per_sec */
389 if ( i_wallclock > p_pids[i_pid].i_bytes_ts + 1000000 ) {
390 p_pids[i_pid].info.i_bytes_per_sec = p_pids[i_pid].i_packets_passed * TS_SIZE188;
391 p_pids[i_pid].i_packets_passed = 0;
392 p_pids[i_pid].i_bytes_ts = i_wallclock;
393 }
394
395 if ( p_pids[i_pid].info.i_first_packet_ts == 0 )
396 p_pids[i_pid].info.i_first_packet_ts = i_wallclock;
397
398 if ( i_pid != PADDING_PID8191 && p_pids[i_pid].i_last_cc != -1
399 && !ts_check_duplicate( i_cc, p_pids[i_pid].i_last_cc )
400 && ts_check_discontinuity( i_cc, p_pids[i_pid].i_last_cc ) )
401 {
402 unsigned int expected_cc = (p_pids[i_pid].i_last_cc + 1) & 0x0f;
403 uint16_t i_sid = 0;
404 const char *pid_desc = get_pid_desc(i_pid, &i_sid);
405
406 p_pids[i_pid].info.i_cc_errors++;
407
408 msg_Warn( NULL((void*)0), "TS discontinuity on pid %4hu expected_cc %2u got %2u (%s, sid %d)",
409 i_pid, expected_cc, i_cc, pid_desc, i_sid );
410
411 switch ( i_print_type )
412 {
413 case PRINT_XML:
414 printf("<ERROR type=\"invalid_discontinuity\" pid=\"%hu\" expected_cc=\"%u\" got_cc=\"%u\" pid_carries=\"%s\" sid=\"%u\" />\n",
415 i_pid, expected_cc, i_cc, pid_desc, i_sid );
416 break;
417 case PRINT_TEXT:
418 printf("TS discontinuity (PID=%hu) (expected_cc=%u) (got_cc=%u) (PID_carries=%s) (sid=%d)\n",
419 i_pid, expected_cc, i_cc, pid_desc, i_sid );
420 break;
421 default:
422 break;
423 }
424 }
425
426 if ( ts_get_transporterror( p_ts->p_ts ) )
427 {
428 uint16_t i_sid = 0;
429 const char *pid_desc = get_pid_desc(i_pid, &i_sid);
430
431 p_pids[i_pid].info.i_transport_errors++;
432
433 msg_Warn( NULL((void*)0), "transport_error_indicator on pid %hu (%s, sid %u)",
434 i_pid, pid_desc, i_sid );
435 switch ( i_print_type )
436 {
437 case PRINT_XML:
438 printf("<ERROR type=\"transport_error\" pid=\"%hu\" pid_carries=\"%s\" sid=\"%u\" />\n",
439 i_pid, pid_desc, i_sid );
440 break;
441 case PRINT_TEXT:
442 printf("transport_error_indicator (PID=%hu) (PID_carries=%s) (sid=%u)\n",
443 i_pid, pid_desc, i_sid );
444 break;
445 default:
446 break;
447 }
448
449 i_nb_errors++;
450 i_last_error = i_wallclock;
451 }
452 else if ( i_wallclock > i_last_error + WATCHDOG_WAIT10000000LL )
453 i_nb_errors = 0;
454
455 if ( i_nb_errors > MAX_ERRORS1000 )
456 {
457 i_nb_errors = 0;
458 switch (i_print_type) {
459 case PRINT_XML:
460 printf("<EVENT type=\"reset\" cause=\"transport\" />\n");
461 break;
462 default:
463 msg_Warn( NULL((void*)0),
464 "too many transport errors, tuning again" );
465 }
466 pf_Reset();
467 }
468
469 if ( !ts_get_transporterror( p_ts->p_ts ) )
470 {
471 /* PSI parsing */
472 if ( i_pid == TDT_PID0x14 || i_pid == RST_PID0x13 )
473 SendTDT( p_ts );
474 else if ( p_pids[i_pid].i_psi_refcount )
475 HandlePSIPacket( p_ts->p_ts, p_ts->i_dts );
476
477 if ( b_enable_emm && p_pids[i_pid].b_emm )
478 SendEMM( p_ts );
479
480 /* PCR handling */
481 if ( ts_has_adaptation( p_ts->p_ts )
482 && ts_get_adaptation( p_ts->p_ts )
483 && tsaf_has_pcr( p_ts->p_ts ) )
484 {
485 mtime_t i_timestamp = tsaf_get_pcr( p_ts->p_ts );
486 int j;
487
488 for ( j = 0; j < i_nb_sids; j++ )
489 {
490 sid_t *p_sid = pp_sids[j];
491 if ( p_sid->i_sid && p_sid->p_current_pmt != NULL((void*)0)
492 && pmt_get_pcrpid( p_sid->p_current_pmt ) == i_pid )
493 {
494 for ( i = 0; i < i_nb_outputs; i++ )
495 {
496 output_t *p_output = pp_outputs[i];
497 if ( p_output->config.i_sid == p_sid->i_sid )
498 {
499 p_output->i_ref_timestamp = i_timestamp;
500 p_output->i_ref_wallclock = p_ts->i_dts;
501 }
502 }
503 }
504 }
505 }
506 }
507
508 p_pids[i_pid].i_last_cc = i_cc;
509
510 /* Output */
511 for ( i = 0; i < p_pids[i_pid].i_nb_outputs; i++ )
512 {
513 output_t *p_output = p_pids[i_pid].pp_outputs[i];
514 if ( p_output != NULL((void*)0) )
515 {
516 if ( i_ca_handle && (p_output->config.i_config & OUTPUT_WATCH0x01) &&
517 ts_get_unitstart( p_ts->p_ts ) )
518 {
519 uint8_t *p_payload;
520
521 if ( ts_get_scrambling( p_ts->p_ts ) ||
522 ( p_pids[i_pid].b_pes
523 && (p_payload = ts_payload( p_ts->p_ts )) + 3
524 < p_ts->p_ts + TS_SIZE188
525 && !pes_validate(p_payload) ) )
526 {
527 if ( i_wallclock >
528 i_last_reset + WATCHDOG_REFRACTORY_PERIOD60000000LL )
529 {
530 p_output->i_nb_errors++;
531 p_output->i_last_error = i_wallclock;
532 }
533 }
534 else if ( i_wallclock > p_output->i_last_error + WATCHDOG_WAIT10000000LL )
535 p_output->i_nb_errors = 0;
536
537 if ( p_output->i_nb_errors > MAX_ERRORS1000 )
538 {
539 int j;
540 for ( j = 0; j < i_nb_outputs; j++ )
541 pp_outputs[j]->i_nb_errors = 0;
542
543 switch (i_print_type) {
544 case PRINT_XML:
545 printf("<EVENT type=\"reset\" cause=\"scrambling\" />\n");
546 break;
547 default:
548 msg_Warn( NULL((void*)0),
549 "too many errors for stream %s, resetting",
550 p_output->config.psz_displayname );
551 }
552 i_last_reset = i_wallclock;
553 en50221_Reset();
554 }
555 }
556
557 output_Put( p_output, p_ts );
558
559 if ( p_output->p_eit_ts_buffer != NULL((void*)0)
560 && p_ts->i_dts > p_output->p_eit_ts_buffer->i_dts
561 + MAX_EIT_RETENTION500000 )
562 FlushEIT( p_output, p_ts->i_dts );
563 }
564 }
565
566 if ( output_dup.config.i_config & OUTPUT_VALID0x04 )
567 output_Put( &output_dup, p_ts );
568
569 p_ts->i_refcount--;
570 if ( !p_ts->i_refcount )
571 block_Delete( p_ts );
572}
573
574/*****************************************************************************
575 * demux_Change : called from main thread
576 *****************************************************************************/
577static int IsIn( uint16_t *pi_pids, int i_nb_pids, uint16_t i_pid )
578{
579 int i;
580 for ( i = 0; i < i_nb_pids; i++ )
581 if ( i_pid == pi_pids[i] ) break;
582 return ( i != i_nb_pids );
583}
584
585void demux_Change( output_t *p_output, const output_config_t *p_config )
586{
587 uint16_t *pi_wanted_pids, *pi_current_pids;
588 int i_nb_wanted_pids, i_nb_current_pids;
589
590 uint16_t i_old_sid = p_output->config.i_sid;
591 uint16_t i_sid = p_config->i_sid;
592 uint16_t *pi_old_pids = p_output->config.pi_pids;
593 uint16_t *pi_pids = p_config->pi_pids;
594 int i_old_nb_pids = p_output->config.i_nb_pids;
595 int i_nb_pids = p_config->i_nb_pids;
596
597 bool_Bool b_sid_change = i_sid != i_old_sid;
598 bool_Bool b_pid_change = false0, b_tsid_change = false0;
599 bool_Bool b_dvb_change = !!((p_output->config.i_config ^ p_config->i_config)
600 & OUTPUT_DVB0x20);
601 bool_Bool b_service_name_change =
602 (!streq(p_output->config.psz_service_name, p_config->psz_service_name) ||
603 !streq(p_output->config.psz_service_provider, p_config->psz_service_provider));
604 bool_Bool b_remap_change = p_output->config.i_new_sid != p_config->i_new_sid ||
605 p_output->config.b_do_remap != p_config->b_do_remap ||
606 p_output->config.pi_confpids[I_PMTPID] != p_config->pi_confpids[I_PMTPID] ||
607 p_output->config.pi_confpids[I_APID] != p_config->pi_confpids[I_APID] ||
608 p_output->config.pi_confpids[I_VPID] != p_config->pi_confpids[I_VPID] ||
609 p_output->config.pi_confpids[I_SPUPID] != p_config->pi_confpids[I_SPUPID];
610 int i;
611
612 p_output->config.i_config = p_config->i_config;
613 p_output->config.i_new_sid = p_config->i_new_sid;
614 p_output->config.b_do_remap = p_config->b_do_remap;
615 memcpy(p_output->config.pi_confpids, p_config->pi_confpids,
616 sizeof(uint16_t) * N_MAP_PIDS4);
617
618 /* Change output settings related to service_name and service_provider . */
619 free( p_output->config.psz_service_name );
620 free( p_output->config.psz_service_provider );
621 p_output->config.psz_service_name = xstrdup( p_config->psz_service_name );
622 p_output->config.psz_service_provider = xstrdup( p_config->psz_service_provider );
623
624 if ( p_config->i_tsid != -1 && p_output->config.i_tsid != p_config->i_tsid )
625 {
626 p_output->i_tsid = p_config->i_tsid;
627 b_tsid_change = true1;
628 }
629 if ( p_config->i_tsid == -1 && p_output->config.i_tsid != -1 )
1
Taking false branch
630 {
631 if ( psi_table_validate(pp_current_pat_sections) && !b_random_tsid )
632 p_output->i_tsid =
633 psi_table_get_tableidext(pp_current_pat_sections)psi_get_tableidext(pp_current_pat_sections[0]);
634 else
635 p_output->i_tsid = rand() & 0xffff;
636 b_tsid_change = true1;
637 }
638
639 if ( !b_sid_change && p_config->i_nb_pids == p_output->config.i_nb_pids &&
2
Assuming 'b_sid_change' is not equal to 0
640 (!p_config->i_nb_pids ||
641 !memcmp( p_output->config.pi_pids, p_config->pi_pids,
642 p_config->i_nb_pids * sizeof(uint16_t) )) )
643 goto out_change;
644
645 GetPIDS( &pi_wanted_pids, &i_nb_wanted_pids, i_sid, pi_pids, i_nb_pids );
646 GetPIDS( &pi_current_pids, &i_nb_current_pids, i_old_sid, pi_old_pids,
647 i_old_nb_pids );
648
649 if ( b_sid_change && i_old_sid )
3
Taking false branch
650 {
651 sid_t *p_old_sid = FindSID( i_old_sid );
652 p_output->config.i_sid = p_config->i_sid;
653
654 if ( p_old_sid != NULL((void*)0) )
655 {
656 if ( i_sid != i_old_sid )
657 UnselectPMT( i_old_sid, p_old_sid->i_pmt_pid );
658
659 if ( i_ca_handle && !SIDIsSelected( i_old_sid )
660 && p_old_sid->p_current_pmt != NULL((void*)0)
661 && PMTNeedsDescrambling( p_old_sid->p_current_pmt ) )
662 en50221_DeletePMT( p_old_sid->p_current_pmt );
663 }
664 }
665
666 for ( i = 0; i < i_nb_current_pids; i++ )
4
Assuming 'i' is >= 'i_nb_current_pids'
5
Loop condition is false. Execution continues on line 675
667 {
668 if ( !IsIn( pi_wanted_pids, i_nb_wanted_pids, pi_current_pids[i] ) )
669 {
670 StopPID( p_output, pi_current_pids[i] );
671 b_pid_change = true1;
672 }
673 }
674
675 if ( b_sid_change && i_ca_handle && i_old_sid &&
676 SIDIsSelected( i_old_sid ) )
677 {
678 sid_t *p_old_sid = FindSID( i_old_sid );
679 if ( p_old_sid != NULL((void*)0) && p_old_sid->p_current_pmt != NULL((void*)0)
680 && PMTNeedsDescrambling( p_old_sid->p_current_pmt ) )
681 en50221_UpdatePMT( p_old_sid->p_current_pmt );
682 }
683
684 for ( i = 0; i < i_nb_wanted_pids; i++ )
6
Loop condition is false. Execution continues on line 693
685 {
686 if ( !IsIn( pi_current_pids, i_nb_current_pids, pi_wanted_pids[i] ) )
687 {
688 StartPID( p_output, pi_wanted_pids[i] );
689 b_pid_change = true1;
690 }
691 }
692
693 free( pi_wanted_pids );
694 free( pi_current_pids );
695
696 if ( b_sid_change && i_sid )
7
Taking true branch
697 {
698 sid_t *p_sid = FindSID( i_sid );
699 p_output->config.i_sid = i_old_sid;
700
701 if ( p_sid != NULL((void*)0) )
8
Assuming 'p_sid' is equal to null
9
Taking false branch
702 {
703 if ( i_sid != i_old_sid )
704 SelectPMT( i_sid, p_sid->i_pmt_pid );
705
706 if ( i_ca_handle && !SIDIsSelected( i_sid )
707 && p_sid->p_current_pmt != NULL((void*)0)
708 && PMTNeedsDescrambling( p_sid->p_current_pmt ) )
709 en50221_AddPMT( p_sid->p_current_pmt );
710 }
711 }
712
713 if ( i_ca_handle && i_sid && SIDIsSelected( i_sid ) )
714 {
715 sid_t *p_sid = FindSID( i_sid );
716 if ( p_sid != NULL((void*)0) && p_sid->p_current_pmt != NULL((void*)0)
717 && PMTNeedsDescrambling( p_sid->p_current_pmt ) )
718 en50221_UpdatePMT( p_sid->p_current_pmt );
719 }
720
721 p_output->config.i_sid = i_sid;
722 free( p_output->config.pi_pids );
723 p_output->config.pi_pids = malloc( sizeof(uint16_t) * i_nb_pids );
10
Call to 'malloc' has an allocation size of 0 bytes
724 memcpy( p_output->config.pi_pids, pi_pids, sizeof(uint16_t) * i_nb_pids );
725 p_output->config.i_nb_pids = i_nb_pids;
726
727out_change:
728 if ( b_sid_change || b_remap_change )
729 {
730 NewSDT( p_output );
731 NewNIT( p_output );
732 NewPAT( p_output );
733 NewPMT( p_output );
734 }
735 else
736 {
737 if ( b_tsid_change )
738 {
739 NewSDT( p_output );
740 NewNIT( p_output );
741 NewPAT( p_output );
742 }
743 else if ( b_dvb_change )
744 {
745 NewNIT( p_output );
746 NewPAT( p_output );
747 }
748
749 if ( b_pid_change )
750 NewPMT( p_output );
751
752 if ( !b_sid_change && b_service_name_change )
753 NewSDT( p_output );
754 }
755}
756
757/*****************************************************************************
758 * SetDTS
759 *****************************************************************************/
760static void SetDTS( block_t *p_list )
761{
762 int i_nb_ts = 0, i;
763 mtime_t i_duration;
764 block_t *p_ts = p_list;
765
766 while ( p_ts != NULL((void*)0) )
767 {
768 i_nb_ts++;
769 p_ts = p_ts->p_next;
770 }
771
772 /* We suppose the stream is CBR, at least between two consecutive read().
773 * This is especially true in budget mode */
774 if ( i_last_dts == -1 )
775 i_duration = 0;
776 else
777 i_duration = i_wallclock - i_last_dts;
778
779 p_ts = p_list;
780 i = i_nb_ts - 1;
781 while ( p_ts != NULL((void*)0) )
782 {
783 p_ts->i_dts = i_wallclock - i_duration * i / i_nb_ts;
784 i--;
785 p_ts = p_ts->p_next;
786 }
787
788 i_last_dts = i_wallclock;
789}
790
791/*****************************************************************************
792 * SetPID/UnsetPID
793 *****************************************************************************/
794static void SetPID( uint16_t i_pid )
795{
796 p_pids[i_pid].i_refcount++;
797
798 if ( !b_budget_mode && p_pids[i_pid].i_refcount
799 && p_pids[i_pid].i_demux_fd == -1 )
800 p_pids[i_pid].i_demux_fd = pf_SetFilter( i_pid );
801}
802
803static void SetPID_EMM( uint16_t i_pid )
804{
805 SetPID( i_pid );
806 p_pids[i_pid].b_emm = true1;
807}
808
809static void UnsetPID( uint16_t i_pid )
810{
811 p_pids[i_pid].i_refcount--;
812
813 if ( !b_budget_mode && !p_pids[i_pid].i_refcount
814 && p_pids[i_pid].i_demux_fd != -1 )
815 {
816 pf_UnsetFilter( p_pids[i_pid].i_demux_fd, i_pid );
817 p_pids[i_pid].i_demux_fd = -1;
818 p_pids[i_pid].b_emm = false0;
819 }
820}
821
822/*****************************************************************************
823 * StartPID/StopPID
824 *****************************************************************************/
825static void StartPID( output_t *p_output, uint16_t i_pid )
826{
827 int j;
828
829 for ( j = 0; j < p_pids[i_pid].i_nb_outputs; j++ )
830 if ( p_pids[i_pid].pp_outputs[j] == p_output )
831 break;
832
833 if ( j == p_pids[i_pid].i_nb_outputs )
834 {
835 for ( j = 0; j < p_pids[i_pid].i_nb_outputs; j++ )
836 if ( p_pids[i_pid].pp_outputs[j] == NULL((void*)0) )
837 break;
838
839 if ( j == p_pids[i_pid].i_nb_outputs )
840 {
841 p_pids[i_pid].i_nb_outputs++;
842 p_pids[i_pid].pp_outputs = realloc( p_pids[i_pid].pp_outputs,
843 sizeof(output_t *)
844 * p_pids[i_pid].i_nb_outputs );
845 }
846
847 p_pids[i_pid].pp_outputs[j] = p_output;
848 SetPID( i_pid );
849 }
850}
851
852static void StopPID( output_t *p_output, uint16_t i_pid )
853{
854 int j;
855
856 for ( j = 0; j < p_pids[i_pid].i_nb_outputs; j++ )
857 {
858 if ( p_pids[i_pid].pp_outputs[j] != NULL((void*)0) )
859 {
860 if ( p_pids[i_pid].pp_outputs[j] == p_output )
861 break;
862 }
863 }
864
865 if ( j != p_pids[i_pid].i_nb_outputs )
866 {
867 p_pids[i_pid].pp_outputs[j] = NULL((void*)0);
868 UnsetPID( i_pid );
869 }
870}
871
872/*****************************************************************************
873 * SelectPID/UnselectPID
874 *****************************************************************************/
875static void SelectPID( uint16_t i_sid, uint16_t i_pid )
876{
877 int i;
878
879 for ( i = 0; i < i_nb_outputs; i++ )
880 if ( (pp_outputs[i]->config.i_config & OUTPUT_VALID0x04)
881 && pp_outputs[i]->config.i_sid == i_sid
882 && !pp_outputs[i]->config.i_nb_pids )
883 StartPID( pp_outputs[i], i_pid );
884}
885
886static void UnselectPID( uint16_t i_sid, uint16_t i_pid )
887{
888 int i;
889
890 for ( i = 0; i < i_nb_outputs; i++ )
891 if ( (pp_outputs[i]->config.i_config & OUTPUT_VALID0x04)
892 && pp_outputs[i]->config.i_sid == i_sid
893 && !pp_outputs[i]->config.i_nb_pids )
894 StopPID( pp_outputs[i], i_pid );
895}
896
897/*****************************************************************************
898 * SelectPMT/UnselectPMT
899 *****************************************************************************/
900static void SelectPMT( uint16_t i_sid, uint16_t i_pid )
901{
902 int i;
903
904 p_pids[i_pid].i_psi_refcount++;
905 p_pids[i_pid].b_pes = false0;
906
907 if ( b_select_pmts )
908 SetPID( i_pid );
909 else for ( i = 0; i < i_nb_outputs; i++ )
910 if ( (pp_outputs[i]->config.i_config & OUTPUT_VALID0x04)
911 && pp_outputs[i]->config.i_sid == i_sid )
912 SetPID( i_pid );
913}
914
915static void UnselectPMT( uint16_t i_sid, uint16_t i_pid )
916{
917 int i;
918
919 p_pids[i_pid].i_psi_refcount--;
920 if ( !p_pids[i_pid].i_psi_refcount )
921 psi_assemble_reset( &p_pids[i_pid].p_psi_buffer,
922 &p_pids[i_pid].i_psi_buffer_used );
923
924 if ( b_select_pmts )
925 UnsetPID( i_pid );
926 else for ( i = 0; i < i_nb_outputs; i++ )
927 if ( (pp_outputs[i]->config.i_config & OUTPUT_VALID0x04)
928 && pp_outputs[i]->config.i_sid == i_sid )
929 UnsetPID( i_pid );
930}
931
932/*****************************************************************************
933 * GetPIDS
934 *****************************************************************************/
935static void GetPIDS( uint16_t **ppi_wanted_pids, int *pi_nb_wanted_pids,
936 uint16_t i_sid,
937 const uint16_t *pi_pids, int i_nb_pids )
938{
939 sid_t *p_sid;
940 uint8_t *p_pmt;
941 uint16_t i_pmt_pid, i_pcr_pid;
942 uint8_t *p_es;
943 uint8_t j;
944
945 if ( i_nb_pids || i_sid == 0 )
946 {
947 *pi_nb_wanted_pids = i_nb_pids;
948 *ppi_wanted_pids = malloc( sizeof(uint16_t) * i_nb_pids );
949 memcpy( *ppi_wanted_pids, pi_pids, sizeof(uint16_t) * i_nb_pids );
950 return;
951 }
952
953 *pi_nb_wanted_pids = 0;
954 *ppi_wanted_pids = NULL((void*)0);
955
956 p_sid = FindSID( i_sid );
957 if ( p_sid == NULL((void*)0) )
958 return;
959
960 p_pmt = p_sid->p_current_pmt;
961 i_pmt_pid = p_sid->i_pmt_pid;
962 if ( p_pmt == NULL((void*)0) ) {
963 msg_Dbg(NULL((void*)0), "no current PMT on sid %d\n", i_sid);
964 return;
965 }
966
967 i_pcr_pid = pmt_get_pcrpid( p_pmt );
968 j = 0;
969 while ( (p_es = pmt_get_es( p_pmt, j )) != NULL((void*)0) )
970 {
971 j++;
972 if ( PIDWouldBeSelected( p_es ) )
973 {
974 *ppi_wanted_pids = realloc( *ppi_wanted_pids,
975 (*pi_nb_wanted_pids + 1) * sizeof(uint16_t) );
976 (*ppi_wanted_pids)[(*pi_nb_wanted_pids)++] = pmtn_get_pid( p_es );
977 }
978 }
979
980 if ( i_pcr_pid != PADDING_PID8191 && i_pcr_pid != i_pmt_pid
981 && !IsIn( *ppi_wanted_pids, *pi_nb_wanted_pids, i_pcr_pid ) )
982 {
983 *ppi_wanted_pids = realloc( *ppi_wanted_pids,
984 (*pi_nb_wanted_pids + 1) * sizeof(uint16_t) );
985 (*ppi_wanted_pids)[(*pi_nb_wanted_pids)++] = i_pcr_pid;
986 }
987}
988
989/*****************************************************************************
990 * OutputPSISection
991 *****************************************************************************/
992static void OutputPSISection( output_t *p_output, uint8_t *p_section,
993 uint16_t i_pid, uint8_t *pi_cc, mtime_t i_dts,
994 block_t **pp_ts_buffer,
995 uint8_t *pi_ts_buffer_offset )
996{
997 uint16_t i_section_length = psi_get_length(p_section) + PSI_HEADER_SIZE3;
998 uint16_t i_section_offset = 0;
999
1000 do
1001 {
1002 block_t *p_block;
1003 uint8_t *p;
1004 uint8_t i_ts_offset;
1005 bool_Bool b_append = (pp_ts_buffer != NULL((void*)0) && *pp_ts_buffer != NULL((void*)0));
1006
1007 if ( b_append )
1008 {
1009 p_block = *pp_ts_buffer;
1010 i_ts_offset = *pi_ts_buffer_offset;
1011 }
1012 else
1013 {
1014 p_block = block_New();
1015 p_block->i_dts = i_dts;
1016 i_ts_offset = 0;
1017 }
1018 p = p_block->p_ts;
1019
1020 psi_split_section( p, &i_ts_offset, p_section, &i_section_offset );
1021
1022 if ( !b_append )
1023 {
1024 ts_set_pid( p, i_pid );
1025 ts_set_cc( p, *pi_cc );
1026 (*pi_cc)++;
1027 *pi_cc &= 0xf;
1028 }
1029
1030 if ( i_section_offset == i_section_length )
1031 {
1032 if ( i_ts_offset < TS_SIZE188 - MIN_SECTION_FRAGMENT8
1033 && pp_ts_buffer != NULL((void*)0) )
1034 {
1035 *pp_ts_buffer = p_block;
1036 *pi_ts_buffer_offset = i_ts_offset;
1037 break;
1038 }
1039 else
1040 psi_split_end( p, &i_ts_offset );
1041 }
1042
1043 p_block->i_dts = i_dts;
1044 p_block->i_refcount--;
1045 output_Put( p_output, p_block );
1046 if ( pp_ts_buffer != NULL((void*)0) )
1047 {
1048 *pp_ts_buffer = NULL((void*)0);
1049 *pi_ts_buffer_offset = 0;
1050 }
1051 }
1052 while ( i_section_offset < i_section_length );
1053}
1054
1055/*****************************************************************************
1056 * SendPAT
1057 *****************************************************************************/
1058static void SendPAT( mtime_t i_dts )
1059{
1060 int i;
1061
1062 for ( i = 0; i < i_nb_outputs; i++ )
1063 {
1064 output_t *p_output = pp_outputs[i];
1065
1066 if ( !(p_output->config.i_config & OUTPUT_VALID0x04) )
1067 continue;
1068
1069 if ( p_output->p_pat_section == NULL((void*)0) &&
1070 psi_table_validate(pp_current_pat_sections) )
1071 {
1072 /* SID doesn't exist - build an empty PAT. */
1073 uint8_t *p;
1074 p_output->i_pat_version++;
1075
1076 p = p_output->p_pat_section = psi_allocate();
1077 pat_init( p );
1078 pat_set_length( p, 0 );
1079 pat_set_tsidpsi_set_tableidext( p, p_output->i_tsid );
1080 psi_set_version( p, p_output->i_pat_version );
1081 psi_set_current( p );
1082 psi_set_section( p, 0 );
1083 psi_set_lastsection( p, 0 );
1084 psi_set_crc( p_output->p_pat_section );
1085 }
1086
1087
1088 if ( p_output->p_pat_section != NULL((void*)0) )
1089 OutputPSISection( p_output, p_output->p_pat_section, PAT_PID0x0,
1090 &p_output->i_pat_cc, i_dts, NULL((void*)0), NULL((void*)0) );
1091 }
1092}
1093
1094/*****************************************************************************
1095 * SendPMT
1096 *****************************************************************************/
1097static void SendPMT( sid_t *p_sid, mtime_t i_dts )
1098{
1099 int i;
1100 int i_pmt_pid = p_sid->i_pmt_pid;
1101
1102 if ( b_do_remap )
1103 i_pmt_pid = pi_newpids[ I_PMTPID ];
1104
1105 for ( i = 0; i < i_nb_outputs; i++ )
1106 {
1107 output_t *p_output = pp_outputs[i];
1108
1109 if ( (p_output->config.i_config & OUTPUT_VALID0x04)
1110 && p_output->config.i_sid == p_sid->i_sid
1111 && p_output->p_pmt_section != NULL((void*)0) )
1112 {
1113 if ( p_output->config.b_do_remap && p_output->config.pi_confpids[I_PMTPID] )
1114 i_pmt_pid = p_output->config.pi_confpids[I_PMTPID];
1115
1116 OutputPSISection( p_output, p_output->p_pmt_section,
1117 i_pmt_pid, &p_output->i_pmt_cc, i_dts,
1118 NULL((void*)0), NULL((void*)0) );
1119 }
1120 }
1121}
1122
1123/*****************************************************************************
1124 * SendNIT
1125 *****************************************************************************/
1126static void SendNIT( mtime_t i_dts )
1127{
1128 int i;
1129
1130 for ( i = 0; i < i_nb_outputs; i++ )
1131 {
1132 output_t *p_output = pp_outputs[i];
1133
1134 if ( (p_output->config.i_config & OUTPUT_VALID0x04)
1135 && (p_output->config.i_config & OUTPUT_DVB0x20)
1136 && p_output->p_nit_section != NULL((void*)0) )
1137 OutputPSISection( p_output, p_output->p_nit_section, NIT_PID0x10,
1138 &p_output->i_nit_cc, i_dts, NULL((void*)0), NULL((void*)0) );
1139 }
1140}
1141
1142/*****************************************************************************
1143 * SendSDT
1144 *****************************************************************************/
1145static void SendSDT( mtime_t i_dts )
1146{
1147 int i;
1148
1149 for ( i = 0; i < i_nb_outputs; i++ )
1150 {
1151 output_t *p_output = pp_outputs[i];
1152
1153 if ( (p_output->config.i_config & OUTPUT_VALID0x04)
1154 && (p_output->config.i_config & OUTPUT_DVB0x20)
1155 && p_output->p_sdt_section != NULL((void*)0) )
1156 OutputPSISection( p_output, p_output->p_sdt_section, SDT_PID0x11,
1157 &p_output->i_sdt_cc, i_dts, NULL((void*)0), NULL((void*)0) );
1158 }
1159}
1160
1161/*****************************************************************************
1162 * SendEIT
1163 *****************************************************************************/
1164static void SendEIT( sid_t *p_sid, mtime_t i_dts, uint8_t *p_eit )
1165{
1166 uint8_t i_table_id = psi_get_tableid( p_eit );
1167 bool_Bool b_epg = i_table_id >= EIT_TABLE_ID_SCHED_ACTUAL_FIRST0x50 &&
1168 i_table_id <= EIT_TABLE_ID_SCHED_ACTUAL_LAST0x5f;
1169 int i;
1170
1171 for ( i = 0; i < i_nb_outputs; i++ )
1172 {
1173 output_t *p_output = pp_outputs[i];
1174
1175 if ( (p_output->config.i_config & OUTPUT_VALID0x04)
1176 && (p_output->config.i_config & OUTPUT_DVB0x20)
1177 && (!b_epg || (p_output->config.i_config & OUTPUT_EPG0x40))
1178 && p_output->config.i_sid == p_sid->i_sid )
1179 {
1180 eit_set_tsid( p_eit, p_output->i_tsid );
1181
1182 if ( p_output->config.i_new_sid )
1183 eit_set_sidpsi_set_tableidext( p_eit, p_output->config.i_new_sid );
1184 else
1185 eit_set_sidpsi_set_tableidext( p_eit, p_output->config.i_sid );
1186
1187 psi_set_crc( p_eit );
1188
1189 OutputPSISection( p_output, p_eit, EIT_PID0x12, &p_output->i_eit_cc,
1190 i_dts, &p_output->p_eit_ts_buffer,
1191 &p_output->i_eit_ts_buffer_offset );
1192 }
1193 }
1194}
1195
1196/*****************************************************************************
1197 * FlushEIT
1198 *****************************************************************************/
1199static void FlushEIT( output_t *p_output, mtime_t i_dts )
1200{
1201 block_t *p_block = p_output->p_eit_ts_buffer;
1202
1203 psi_split_end( p_block->p_ts, &p_output->i_eit_ts_buffer_offset );
1204 p_block->i_dts = i_dts;
1205 p_block->i_refcount--;
1206 output_Put( p_output, p_block );
1207 p_output->p_eit_ts_buffer = NULL((void*)0);
1208 p_output->i_eit_ts_buffer_offset = 0;
1209}
1210
1211/*****************************************************************************
1212 * SendTDT
1213 *****************************************************************************/
1214static void SendTDT( block_t *p_ts )
1215{
1216 int i;
1217
1218 for ( i = 0; i < i_nb_outputs; i++ )
1219 {
1220 output_t *p_output = pp_outputs[i];
1221
1222 if ( (p_output->config.i_config & OUTPUT_VALID0x04)
1223 && (p_output->config.i_config & OUTPUT_DVB0x20)
1224 && p_output->p_sdt_section != NULL((void*)0) )
1225 output_Put( p_output, p_ts );
1226 }
1227}
1228/*****************************************************************************
1229 * SendEMM
1230 *****************************************************************************/
1231static void SendEMM( block_t *p_ts )
1232{
1233 int i;
1234
1235 for ( i = 0; i < i_nb_outputs; i++ )
1236 {
1237 output_t *p_output = pp_outputs[i];
1238
1239 if ( (p_output->config.i_config & OUTPUT_VALID0x04) )
1240 output_Put( p_output, p_ts );
1241 }
1242}
1243
1244/*****************************************************************************
1245 * NewPAT
1246 *****************************************************************************/
1247static void NewPAT( output_t *p_output )
1248{
1249 const uint8_t *p_program;
1250 uint8_t *p;
1251 uint8_t k = 0;
1252
1253 free( p_output->p_pat_section );
1254 p_output->p_pat_section = NULL((void*)0);
1255 p_output->i_pat_version++;
1256
1257 if ( !p_output->config.i_sid ) return;
1258 if ( !psi_table_validate(pp_current_pat_sections) ) return;
1259
1260 p_program = pat_table_find_program( pp_current_pat_sections,
1261 p_output->config.i_sid );
1262 if ( p_program == NULL((void*)0) ) return;
1263
1264 p = p_output->p_pat_section = psi_allocate();
1265 pat_init( p );
1266 psi_set_length( p, PSI_MAX_SIZE1021 );
1267 pat_set_tsidpsi_set_tableidext( p, p_output->i_tsid );
1268 psi_set_version( p, p_output->i_pat_version );
1269 psi_set_current( p );
1270 psi_set_section( p, 0 );
1271 psi_set_lastsection( p, 0 );
1272
1273 if ( p_output->config.i_config & OUTPUT_DVB0x20 )
1274 {
1275 /* NIT */
1276 p = pat_get_program( p_output->p_pat_section, k++ );
1277 patn_init( p );
1278 patn_set_program( p, 0 );
1279 patn_set_pid( p, NIT_PID0x10 );
1280 }
1281
1282 p = pat_get_program( p_output->p_pat_section, k++ );
1283 patn_init( p );
1284 if ( p_output->config.i_new_sid )
1285 {
1286 msg_Dbg( NULL((void*)0), "Mapping PAT SID %d to %d", p_output->config.i_sid,
1287 p_output->config.i_new_sid );
1288 patn_set_program( p, p_output->config.i_new_sid );
1289 }
1290 else
1291 patn_set_program( p, p_output->config.i_sid );
1292
1293 if ( b_do_remap )
1294 {
1295 msg_Dbg( NULL((void*)0), "Mapping PMT PID %d to %d", patn_get_pid( p_program ), pi_newpids[I_PMTPID] );
1296 patn_set_pid( p, pi_newpids[I_PMTPID]);
1297 } else if ( p_output->config.b_do_remap && p_output->config.pi_confpids[I_PMTPID] ) {
1298 msg_Dbg( NULL((void*)0), "Mapping PMT PID %d to %d", patn_get_pid( p_program ), p_output->config.pi_confpids[I_PMTPID] );
1299 patn_set_pid( p, p_output->config.pi_confpids[I_PMTPID]);
1300 } else {
1301 patn_set_pid( p, patn_get_pid( p_program ) );
1302 }
1303
1304 p = pat_get_program( p_output->p_pat_section, k );
1305 pat_set_length( p_output->p_pat_section,
1306 p - p_output->p_pat_section - PAT_HEADER_SIZE8 );
1307 psi_set_crc( p_output->p_pat_section );
1308}
1309
1310/*****************************************************************************
1311 * NewPMT
1312 *****************************************************************************/
1313static void CopyDescriptors( uint8_t *p_descs, uint8_t *p_current_descs )
1314{
1315 uint8_t *p_desc;
1316 const uint8_t *p_current_desc;
1317 uint16_t j = 0, k = 0;
1318
1319 descs_set_length( p_descs, DESCS_MAX_SIZE4095 );
1320
1321 while ( (p_current_desc = descs_get_desc( p_current_descs, j )) != NULL((void*)0) )
1322 {
1323 uint8_t i_tag = desc_get_tag( p_current_desc );
1324
1325 j++;
1326 if ( !b_enable_ecm && i_tag == 0x9 ) continue;
1327
1328 p_desc = descs_get_desc( p_descs, k );
1329 if ( p_desc == NULL((void*)0) ) continue; /* This shouldn't happen */
1330 k++;
1331 memcpy( p_desc, p_current_desc,
1332 DESC_HEADER_SIZE2 + desc_get_length( p_current_desc ) );
1333 }
1334
1335 p_desc = descs_get_desc( p_descs, k );
1336 if ( p_desc == NULL((void*)0) )
1337 /* This shouldn't happen if the incoming PMT is valid */
1338 descs_set_length( p_descs, 0 );
1339 else
1340 descs_set_length( p_descs, p_desc - p_descs - DESCS_HEADER_SIZE2 );
1341}
1342
1343static void NewPMT( output_t *p_output )
1344{
1345 sid_t *p_sid;
1346 uint8_t *p_current_pmt;
1347 uint8_t *p_es, *p_current_es;
1348 uint8_t *p;
1349 uint16_t j, k;
1350 uint16_t i_pcrpid;
1351
1352 free( p_output->p_pmt_section );
1353 p_output->p_pmt_section = NULL((void*)0);
1354 p_output->i_pmt_version++;
1355
1356 if ( !p_output->config.i_sid ) return;
1357
1358 p_sid = FindSID( p_output->config.i_sid );
1359 if ( p_sid == NULL((void*)0) ) return;
1360
1361 if ( p_sid->p_current_pmt == NULL((void*)0) ) return;
1362 p_current_pmt = p_sid->p_current_pmt;
1363
1364 p = p_output->p_pmt_section = psi_allocate();
1365 pmt_init( p );
1366 psi_set_length( p, PSI_MAX_SIZE1021 );
1367 if ( p_output->config.i_new_sid )
1368 {
1369 msg_Dbg( NULL((void*)0), "Mapping PMT SID %d to %d", p_output->config.i_sid,
1370 p_output->config.i_new_sid );
1371 pmt_set_programpsi_set_tableidext( p, p_output->config.i_new_sid );
1372 }
1373 else
1374 pmt_set_programpsi_set_tableidext( p, p_output->config.i_sid );
1375 psi_set_version( p, p_output->i_pmt_version );
1376 psi_set_current( p );
1377 pmt_set_desclength( p, 0 );
1378 init_pid_mapping( p_output );
1379
1380
1381 CopyDescriptors( pmt_get_descs( p ), pmt_get_descs( p_current_pmt ) );
1382
1383 j = 0; k = 0;
1384 while ( (p_current_es = pmt_get_es( p_current_pmt, j )) != NULL((void*)0) )
1385 {
1386 uint16_t i_pid = pmtn_get_pid( p_current_es );
1387
1388 j++;
1389 if ( (p_output->config.i_nb_pids || !PIDWouldBeSelected( p_current_es ))
1390 && !IsIn( p_output->config.pi_pids, p_output->config.i_nb_pids,
1391 i_pid ) )
1392 continue;
1393
1394 p_es = pmt_get_es( p, k );
1395 if ( p_es == NULL((void*)0) ) continue; /* This shouldn't happen */
1396 k++;
1397 pmtn_init( p_es );
1398 pmtn_set_streamtype( p_es, pmtn_get_streamtype( p_current_es ) );
1399 pmtn_set_pid( p_es, map_es_pid(p_output, p_current_es, i_pid) );
1400 pmtn_set_desclength( p_es, 0 );
1401
1402 CopyDescriptors( pmtn_get_descs( p_es ),
1403 pmtn_get_descs( p_current_es ) );
1404 }
1405
1406 /* Do the pcr pid after everything else as it may have been remapped */
1407 i_pcrpid = pmt_get_pcrpid( p_current_pmt );
1408 if ( p_output->pi_newpids[i_pcrpid] != UNUSED_PID(8192 + 1) ) {
1409 msg_Dbg( NULL((void*)0), "REMAP: The PCR PID was changed from 0x%x (%u) to 0x%x (%u)",
1410 i_pcrpid, i_pcrpid, p_output->pi_newpids[i_pcrpid], p_output->pi_newpids[i_pcrpid] );
1411 i_pcrpid = p_output->pi_newpids[i_pcrpid];
1412 } else {
1413 msg_Dbg( NULL((void*)0), "The PCR PID has kept its original value of 0x%x (%u)", i_pcrpid, i_pcrpid);
1414 }
1415 pmt_set_pcrpid( p, i_pcrpid );
1416 p_es = pmt_get_es( p, k );
1417 if ( p_es == NULL((void*)0) )
1418 /* This shouldn't happen if the incoming PMT is valid */
1419 pmt_set_length( p, 0 );
1420 else
1421 pmt_set_length( p, p_es - p - PMT_HEADER_SIZE(8 + 4) );
1422 psi_set_crc( p );
1423}
1424
1425/*****************************************************************************
1426 * NewNIT
1427 *****************************************************************************/
1428static void NewNIT( output_t *p_output )
1429{
1430 uint8_t *p_ts;
1431 uint8_t *p_header2;
1432 uint8_t *p;
1433
1434 free( p_output->p_nit_section );
1435 p_output->p_nit_section = NULL((void*)0);
1436 p_output->i_nit_version++;
1437
1438 p = p_output->p_nit_section = psi_allocate();
1439 nit_init( p, true1 );
1440 nit_set_length( p, PSI_MAX_SIZE1021 );
1441 nit_set_nidpsi_set_tableidext( p, i_network_id );
1442 psi_set_version( p, p_output->i_nit_version );
1443 psi_set_current( p );
1444 psi_set_section( p, 0 );
1445 psi_set_lastsection( p, 0 );
1446
1447 if ( p_network_name != NULL((void*)0) )
1448 {
1449 uint8_t *p_descs;
1450 uint8_t *p_desc;
1451 nit_set_desclength( p, DESCS_MAX_SIZE4095 );
1452 p_descs = nit_get_descs( p );
1453 p_desc = descs_get_desc( p_descs, 0 );
1454 desc40_init( p_desc );
1455 desc40_set_networkname( p_desc, p_network_name, i_network_name_size );
1456 p_desc = descs_get_desc( p_descs, 1 );
1457 descs_set_length( p_descs, p_desc - p_descs - DESCS_HEADER_SIZE2 );
1458 }
1459 else
1460 nit_set_desclength( p, 0 );
1461
1462 p_header2 = nit_get_header2( p );
1463 nith_init( p_header2 );
1464 nith_set_tslength( p_header2, NIT_TS_SIZE6 );
1465
1466 p_ts = nit_get_ts( p, 0 );
1467 nitn_init( p_ts );
1468 nitn_set_tsid( p_ts, p_output->i_tsid );
1469 nitn_set_onid( p_ts, i_network_id );
1470 nitn_set_desclength( p_ts, 0 );
1471
1472 p_ts = nit_get_ts( p, 1 );
1473 if ( p_ts == NULL((void*)0) )
1474 /* This shouldn't happen */
1475 nit_set_length( p, 0 );
1476 else
1477 nit_set_length( p, p_ts - p - NIT_HEADER_SIZE(8 + 2) );
1478 psi_set_crc( p_output->p_nit_section );
1479}
1480
1481/*****************************************************************************
1482 * NewSDT
1483 *****************************************************************************/
1484static void NewSDT( output_t *p_output )
1485{
1486 uint8_t *p_service, *p_current_service;
1487 uint8_t *p;
1488
1489 free( p_output->p_sdt_section );
1490 p_output->p_sdt_section = NULL((void*)0);
1491 p_output->i_sdt_version++;
1492
1493 if ( !p_output->config.i_sid ) return;
1494 if ( !psi_table_validate(pp_current_sdt_sections) ) return;
1495
1496 p_current_service = sdt_table_find_service( pp_current_sdt_sections,
1497 p_output->config.i_sid );
1498
1499 if ( p_current_service == NULL((void*)0) )
1500 {
1501 if ( p_output->p_pat_section != NULL((void*)0) &&
1502 pat_get_program( p_output->p_pat_section, 0 ) == NULL((void*)0) )
1503 {
1504 /* Empty PAT and no SDT anymore */
1505 free( p_output->p_pat_section );
1506 p_output->p_pat_section = NULL((void*)0);
1507 p_output->i_pat_version++;
1508 }
1509 return;
1510 }
1511
1512 p = p_output->p_sdt_section = psi_allocate();
1513 sdt_init( p, true1 );
1514 sdt_set_length( p, PSI_MAX_SIZE1021 );
1515 sdt_set_tsidpsi_set_tableidext( p, p_output->i_tsid );
1516 psi_set_version( p, p_output->i_sdt_version );
1517 psi_set_current( p );
1518 psi_set_section( p, 0 );
1519 psi_set_lastsection( p, 0 );
1520 sdt_set_onid( p,
1521 sdt_get_onid( psi_table_get_section( pp_current_sdt_sections, 0 ) ) );
1522
1523 p_service = sdt_get_service( p, 0 );
1524 sdtn_init( p_service );
1525 if ( p_output->config.i_new_sid )
1526 {
1527 msg_Dbg( NULL((void*)0), "Mapping SDT SID %d to %d", p_output->config.i_sid,
1528 p_output->config.i_new_sid );
1529 sdtn_set_sid( p_service, p_output->config.i_new_sid );
1530 }
1531 else
1532 sdtn_set_sid( p_service, p_output->config.i_sid );
1533
1534 if ( (p_output->config.i_config & OUTPUT_EPG0x40) == OUTPUT_EPG0x40 )
1535 {
1536 sdtn_set_eitschedule(p_service);
1537 sdtn_set_eitpresent(p_service);
1538 } else {
1539 if ( sdtn_get_eitschedule(p_current_service) )
1540 sdtn_set_eitschedule(p_service);
1541 if ( sdtn_get_eitpresent(p_current_service) )
1542 sdtn_set_eitpresent(p_service);
1543 }
1544
1545 sdtn_set_running( p_service, sdtn_get_running(p_current_service) );
1546 /* Do not set free_ca */
1547 sdtn_set_desclength( p_service, sdtn_get_desclength(p_current_service) );
1548
1549 char *p_new_provider = p_output->config.psz_service_provider;
1550 char *p_new_service = p_output->config.psz_service_name;
1551
1552 if ( !p_new_provider && !p_new_service ) {
1553 /* Copy all descriptors unchanged */
1554 memcpy( descs_get_desc( sdtn_get_descs(p_service), 0 ),
1555 descs_get_desc( sdtn_get_descs(p_current_service), 0 ),
1556 sdtn_get_desclength(p_current_service) );
1557 } else {
1558 int j = 0, i_total_desc_len = 0;
1559 uint8_t *p_desc;
1560 uint8_t *p_new_desc = descs_get_desc( sdtn_get_descs(p_service), 0 );
1561 while ( (p_desc = descs_get_desc( sdtn_get_descs( p_current_service ), j++ )) != NULL((void*)0) )
1562 {
1563 /* Regenerate descriptor 48 (service name) */
1564 if ( desc_get_tag( p_desc ) == 0x48 && desc48_validate( p_desc ) )
1565 {
1566 uint8_t i_old_provider_len, i_old_service_len;
1567 uint8_t i_new_desc_len = 3; /* 1 byte - type, 1 byte provider_len, 1 byte service_len */
1568 char *p_new_provider = p_output->config.psz_service_provider;
1569 char *p_new_service = p_output->config.psz_service_name;
1570 const uint8_t *p_old_provider = desc48_get_provider( p_desc, &i_old_provider_len );
1571 const uint8_t *p_old_service = desc48_get_service( p_desc, &i_old_service_len );
1572
1573 desc48_init( p_new_desc );
1574 desc48_set_type( p_new_desc, desc48_get_type( p_desc ) );
1575
1576 if ( p_new_provider ) {
1577 desc48_set_provider( p_new_desc, (uint8_t *)p_new_provider, strlen( p_new_provider ) );
1578 i_new_desc_len += strlen( p_new_provider );
1579 } else {
1580 desc48_set_provider( p_new_desc, p_old_provider, i_old_provider_len );
1581 i_new_desc_len += i_old_provider_len;
1582 }
1583
1584 if ( p_new_service ) {
1585 desc48_set_service( p_new_desc, (uint8_t *)p_new_service, strlen( p_new_service ) );
1586 i_new_desc_len += strlen( p_new_service );
1587 } else {
1588 desc48_set_service( p_new_desc, p_old_service, i_old_service_len );
1589 i_new_desc_len += i_old_service_len;
1590 }
1591 desc_set_length( p_new_desc, i_new_desc_len );
1592 i_total_desc_len += DESC_HEADER_SIZE2 + i_new_desc_len;
1593 p_new_desc += DESC_HEADER_SIZE2 + i_new_desc_len;
1594 } else {
1595 /* Copy single descriptor */
1596 int i_desc_len = DESC_HEADER_SIZE2 + desc_get_length( p_desc );
1597 memcpy( p_new_desc, p_desc, i_desc_len );
1598 p_new_desc += i_desc_len;
1599 i_total_desc_len += i_desc_len;
1600 }
1601 }
1602 sdtn_set_desclength( p_service, i_total_desc_len );
1603 }
1604
1605 p_service = sdt_get_service( p, 1 );
1606 if ( p_service == NULL((void*)0) )
1607 /* This shouldn't happen if the incoming SDT is valid */
1608 sdt_set_length( p, 0 );
1609 else
1610 sdt_set_length( p, p_service - p - SDT_HEADER_SIZE(8 + 3) );
1611 psi_set_crc( p_output->p_sdt_section );
1612}
1613
1614/*****************************************************************************
1615 * UpdatePAT/PMT/SDT
1616 *****************************************************************************/
1617#define DECLARE_UPDATE_FUNC( table )static void Updatetable( uint16_t i_sid ) { int i; for ( i = 0
; i < i_nb_outputs; i++ ) if ( ( pp_outputs[i]->config.
i_config & 0x04 ) && pp_outputs[i]->config.i_sid
== i_sid ) Newtable( pp_outputs[i] ); }
\
1618static void Update##table( uint16_t i_sid ) \
1619{ \
1620 int i; \
1621 \
1622 for ( i = 0; i < i_nb_outputs; i++ ) \
1623 if ( ( pp_outputs[i]->config.i_config & OUTPUT_VALID0x04 ) \
1624 && pp_outputs[i]->config.i_sid == i_sid ) \
1625 New##table( pp_outputs[i] ); \
1626}
1627
1628DECLARE_UPDATE_FUNC(PAT)static void UpdatePAT( uint16_t i_sid ) { int i; for ( i = 0;
i < i_nb_outputs; i++ ) if ( ( pp_outputs[i]->config.i_config
& 0x04 ) && pp_outputs[i]->config.i_sid == i_sid
) NewPAT( pp_outputs[i] ); }
1629DECLARE_UPDATE_FUNC(PMT)static void UpdatePMT( uint16_t i_sid ) { int i; for ( i = 0;
i < i_nb_outputs; i++ ) if ( ( pp_outputs[i]->config.i_config
& 0x04 ) && pp_outputs[i]->config.i_sid == i_sid
) NewPMT( pp_outputs[i] ); }
1630DECLARE_UPDATE_FUNC(SDT)static void UpdateSDT( uint16_t i_sid ) { int i; for ( i = 0;
i < i_nb_outputs; i++ ) if ( ( pp_outputs[i]->config.i_config
& 0x04 ) && pp_outputs[i]->config.i_sid == i_sid
) NewSDT( pp_outputs[i] ); }
1631
1632/*****************************************************************************
1633 * UpdateTSID
1634 *****************************************************************************/
1635static void UpdateTSID(void)
1636{
1637 uint16_t i_tsid = psi_table_get_tableidext(pp_current_pat_sections)psi_get_tableidext(pp_current_pat_sections[0]);
1638 int i;
1639
1640 for ( i = 0; i < i_nb_outputs; i++ )
1641 {
1642 output_t *p_output = pp_outputs[i];
1643
1644 if ( (p_output->config.i_config & OUTPUT_VALID0x04)
1645 && p_output->config.i_tsid == -1 && !b_random_tsid )
1646 {
1647 p_output->i_tsid = i_tsid;
1648 NewNIT( p_output );
1649 }
1650 }
1651}
1652
1653/*****************************************************************************
1654 * SIDIsSelected
1655 *****************************************************************************/
1656static bool_Bool SIDIsSelected( uint16_t i_sid )
1657{
1658 int i;
1659
1660 for ( i = 0; i < i_nb_outputs; i++ )
1661 if ( (pp_outputs[i]->config.i_config & OUTPUT_VALID0x04)
1662 && pp_outputs[i]->config.i_sid == i_sid )
1663 return true1;
1664
1665 return false0;
1666}
1667
1668/*****************************************************************************
1669 * demux_PIDIsSelected
1670 *****************************************************************************/
1671bool_Bool demux_PIDIsSelected( uint16_t i_pid )
1672{
1673 int i;
1674
1675 for ( i = 0; i < p_pids[i_pid].i_nb_outputs; i++ )
1676 if ( p_pids[i_pid].pp_outputs[i] != NULL((void*)0) )
1677 return true1;
1678
1679 return false0;
1680}
1681
1682/*****************************************************************************
1683 * PIDWouldBeSelected
1684 *****************************************************************************/
1685static bool_Bool PIDWouldBeSelected( uint8_t *p_es )
1686{
1687 if ( b_any_type ) return true1;
1688
1689 uint8_t i_type = pmtn_get_streamtype( p_es );
1690
1691 switch ( i_type )
1692 {
1693 case 0x1: /* video MPEG-1 */
1694 case 0x2: /* video */
1695 case 0x3: /* audio MPEG-1 */
1696 case 0x4: /* audio */
1697 case 0xf: /* audio AAC ADTS */
1698 case 0x10: /* video MPEG-4 */
1699 case 0x11: /* audio AAC LATM */
1700 case 0x1b: /* video H264 */
1701 case 0x81: /* ATSC A/52 */
1702 case 0x87: /* ATSC Enhanced A/52 */
1703 return true1;
1704 break;
1705
1706 case 0x6:
1707 {
1708 uint16_t j = 0;
1709 const uint8_t *p_desc;
1710
1711 while ( (p_desc = descs_get_desc( pmtn_get_descs( p_es ), j )) != NULL((void*)0) )
1712 {
1713 uint8_t i_tag = desc_get_tag( p_desc );
1714 j++;
1715
1716 if( i_tag == 0x46 /* VBI + teletext */
1717 || i_tag == 0x56 /* teletext */
1718 || i_tag == 0x59 /* dvbsub */
1719 || i_tag == 0x6a /* A/52 */
1720 || i_tag == 0x7a /* Enhanced A/52 */
1721 || i_tag == 0x7b /* DCA */
1722 || i_tag == 0x7c /* AAC */ )
1723 return true1;
1724 }
1725 break;
1726 }
1727
1728 default:
1729 break;
1730 }
1731
1732 /* FIXME: also parse IOD */
1733 return false0;
1734}
1735
1736/*****************************************************************************
1737 * PIDCarriesPES
1738 *****************************************************************************/
1739static bool_Bool PIDCarriesPES( const uint8_t *p_es )
1740{
1741 uint8_t i_type = pmtn_get_streamtype( p_es );
1742
1743 switch ( i_type )
1744 {
1745 case 0x1: /* video MPEG-1 */
1746 case 0x2: /* video */
1747 case 0x3: /* audio MPEG-1 */
1748 case 0x4: /* audio */
1749 case 0x6: /* private PES data */
1750 case 0xf: /* audio AAC */
1751 case 0x10: /* video MPEG-4 */
1752 case 0x11: /* audio AAC LATM */
1753 case 0x1b: /* video H264 */
1754 case 0x81: /* ATSC A/52 */
1755 case 0x87: /* ATSC Enhanced A/52 */
1756 return true1;
1757 break;
1758
1759 default:
1760 return false0;
1761 break;
1762 }
1763}
1764
1765/*****************************************************************************
1766 * PMTNeedsDescrambling
1767 *****************************************************************************/
1768static bool_Bool PMTNeedsDescrambling( uint8_t *p_pmt )
1769{
1770 uint8_t i;
1771 uint16_t j;
1772 uint8_t *p_es;
1773 const uint8_t *p_desc;
1774
1775 j = 0;
1776 while ( (p_desc = descs_get_desc( pmt_get_descs( p_pmt ), j )) != NULL((void*)0) )
1777 {
1778 uint8_t i_tag = desc_get_tag( p_desc );
1779 j++;
1780
1781 if ( i_tag == 0x9 ) return true1;
1782 }
1783
1784 i = 0;
1785 while ( (p_es = pmt_get_es( p_pmt, i )) != NULL((void*)0) )
1786 {
1787 i++;
1788 j = 0;
1789 while ( (p_desc = descs_get_desc( pmtn_get_descs( p_es ), j )) != NULL((void*)0) )
1790 {
1791 uint8_t i_tag = desc_get_tag( p_desc );
1792 j++;
1793
1794 if ( i_tag == 0x9 ) return true1;
1795 }
1796 }
1797
1798 return false0;
1799}
1800
1801/*****************************************************************************
1802 * demux_ResendCAPMTs
1803 *****************************************************************************/
1804void demux_ResendCAPMTs( void )
1805{
1806 int i;
1807 for ( i = 0; i < i_nb_sids; i++ )
1808 if ( pp_sids[i]->p_current_pmt != NULL((void*)0)
1809 && SIDIsSelected( pp_sids[i]->i_sid )
1810 && PMTNeedsDescrambling( pp_sids[i]->p_current_pmt ) )
1811 en50221_AddPMT( pp_sids[i]->p_current_pmt );
1812}
1813
1814/* Find CA descriptor that have PID i_ca_pid */
1815static uint8_t *ca_desc_find( uint8_t *p_descl, uint16_t i_length,
1816 uint16_t i_ca_pid )
1817{
1818 int j = 0;
1819 uint8_t *p_desc;
1820
1821 while ( (p_desc = descl_get_desc( p_descl, i_length, j++ )) != NULL((void*)0) ) {
1822 if ( desc_get_tag( p_desc ) != 0x09 || !desc09_validate( p_desc ) )
1823 continue;
1824 if ( desc09_get_pid( p_desc ) == i_ca_pid )
1825 return p_desc;
1826 }
1827
1828 return NULL((void*)0);
1829}
1830
1831/*****************************************************************************
1832 * DeleteProgram
1833 *****************************************************************************/
1834static void DeleteProgram( uint16_t i_sid, uint16_t i_pid )
1835{
1836 sid_t *p_sid;
1837 uint8_t *p_pmt;
1838 uint8_t *p_desc;
1839
1840 UnselectPMT( i_sid, i_pid );
1841
1842 p_sid = FindSID( i_sid );
1843 if ( p_sid == NULL((void*)0) ) return;
1844
1845 p_pmt = p_sid->p_current_pmt;
1846
1847 if ( p_pmt != NULL((void*)0) )
1848 {
1849 uint16_t i_pcr_pid = pmt_get_pcrpid( p_pmt );
1850 uint8_t *p_es;
1851 uint8_t j;
1852
1853 if ( i_ca_handle && SIDIsSelected( i_sid )
1854 && PMTNeedsDescrambling( p_pmt ) )
1855 en50221_DeletePMT( p_pmt );
1856
1857 if ( i_pcr_pid != PADDING_PID8191
1858 && i_pcr_pid != p_sid->i_pmt_pid )
1859 UnselectPID( i_sid, i_pcr_pid );
1860
1861 if ( b_enable_ecm )
1862 {
1863 j = 0;
1864
1865 while ((p_desc = descs_get_desc( pmt_get_descs( p_pmt ), j++ )) != NULL((void*)0))
1866 {
1867 if ( desc_get_tag( p_desc ) != 0x09 ||
1868 !desc09_validate( p_desc ) )
1869 continue;
1870 UnselectPID( i_sid, desc09_get_pid( p_desc ) );
1871 }
1872 }
1873
1874 j = 0;
1875 while ( (p_es = pmt_get_es( p_pmt, j )) != NULL((void*)0) )
1876 {
1877 uint16_t i_pid = pmtn_get_pid( p_es );
1878 j++;
1879
1880 if ( PIDWouldBeSelected( p_es ) )
1881 UnselectPID( i_sid, i_pid );
1882
1883 if ( b_enable_ecm )
1884 {
1885 uint8_t k = 0;
1886
1887 while ((p_desc = descs_get_desc( pmtn_get_descs( p_es ), k++ )) != NULL((void*)0))
1888 {
1889 if ( desc_get_tag( p_desc ) != 0x09 || !desc09_validate( p_desc ) )
1890 continue;
1891 UnselectPID( i_sid, desc09_get_pid( p_desc ) );
1892 }
1893 }
1894 }
1895
1896 free( p_pmt );
1897 p_sid->p_current_pmt = NULL((void*)0);
1898 }
1899 p_sid->i_sid = 0;
1900 p_sid->i_pmt_pid = 0;
1901}
1902
1903/*****************************************************************************
1904 * demux_Iconv
1905 *****************************************************************************
1906 * This code is from biTStream's examples and is under the WTFPL (see
1907 * LICENSE.WTFPL).
1908 *****************************************************************************/
1909static char *iconv_append_null(const char *p_string, size_t i_length)
1910{
1911 char *psz_string = malloc(i_length + 1);
1912 memcpy(psz_string, p_string, i_length);
1913 psz_string[i_length] = '\0';
1914 return psz_string;
1915}
1916
1917char *demux_Iconv(void *_unused, const char *psz_encoding,
1918 char *p_string, size_t i_length)
1919{
1920#ifdef HAVE_ICONV
1921 static const char *psz_current_encoding = "";
1922
1923 char *psz_string, *p;
1924 size_t i_out_length;
1925
1926 if (!strcmp(psz_encoding, psz_native_charset)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(psz_encoding) && __builtin_constant_p (psz_native_charset
) && (__s1_len = strlen (psz_encoding), __s2_len = strlen
(psz_native_charset), (!((size_t)(const void *)((psz_encoding
) + 1) - (size_t)(const void *)(psz_encoding) == 1) || __s1_len
>= 4) && (!((size_t)(const void *)((psz_native_charset
) + 1) - (size_t)(const void *)(psz_native_charset) == 1) || __s2_len
>= 4)) ? __builtin_strcmp (psz_encoding, psz_native_charset
) : (__builtin_constant_p (psz_encoding) && ((size_t)
(const void *)((psz_encoding) + 1) - (size_t)(const void *)(psz_encoding
) == 1) && (__s1_len = strlen (psz_encoding), __s1_len
< 4) ? (__builtin_constant_p (psz_native_charset) &&
((size_t)(const void *)((psz_native_charset) + 1) - (size_t)
(const void *)(psz_native_charset) == 1) ? __builtin_strcmp (
psz_encoding, psz_native_charset) : (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) (psz_native_charset
); int __result = (((const unsigned char *) (const char *) (psz_encoding
))[0] - __s2[0]); if (__s1_len > 0 && __result == 0
) { __result = (((const unsigned char *) (const char *) (psz_encoding
))[1] - __s2[1]); if (__s1_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) (psz_encoding
))[2] - __s2[2]); if (__s1_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) (psz_encoding
))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p (
psz_native_charset) && ((size_t)(const void *)((psz_native_charset
) + 1) - (size_t)(const void *)(psz_native_charset) == 1) &&
(__s2_len = strlen (psz_native_charset), __s2_len < 4) ? (
__builtin_constant_p (psz_encoding) && ((size_t)(const
void *)((psz_encoding) + 1) - (size_t)(const void *)(psz_encoding
) == 1) ? __builtin_strcmp (psz_encoding, psz_native_charset)
: (- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (psz_encoding); int __result = (((const
unsigned char *) (const char *) (psz_native_charset))[0] - __s2
[0]); if (__s2_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) (psz_native_charset
))[1] - __s2[1]); if (__s2_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) (psz_native_charset
))[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) (psz_native_charset
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (psz_encoding
, psz_native_charset)))); })
)
1927 return iconv_append_null(p_string, i_length);
1928
1929 if (iconv_handle != (iconv_t)-1 &&
1930 strcmp(psz_encoding, psz_current_encoding)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(psz_encoding) && __builtin_constant_p (psz_current_encoding
) && (__s1_len = strlen (psz_encoding), __s2_len = strlen
(psz_current_encoding), (!((size_t)(const void *)((psz_encoding
) + 1) - (size_t)(const void *)(psz_encoding) == 1) || __s1_len
>= 4) && (!((size_t)(const void *)((psz_current_encoding
) + 1) - (size_t)(const void *)(psz_current_encoding) == 1) ||
__s2_len >= 4)) ? __builtin_strcmp (psz_encoding, psz_current_encoding
) : (__builtin_constant_p (psz_encoding) && ((size_t)
(const void *)((psz_encoding) + 1) - (size_t)(const void *)(psz_encoding
) == 1) && (__s1_len = strlen (psz_encoding), __s1_len
< 4) ? (__builtin_constant_p (psz_current_encoding) &&
((size_t)(const void *)((psz_current_encoding) + 1) - (size_t
)(const void *)(psz_current_encoding) == 1) ? __builtin_strcmp
(psz_encoding, psz_current_encoding) : (__extension__ ({ const
unsigned char *__s2 = (const unsigned char *) (const char *)
(psz_current_encoding); int __result = (((const unsigned char
*) (const char *) (psz_encoding))[0] - __s2[0]); if (__s1_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) (psz_encoding))[1] - __s2[1]); if (__s1_len
> 1 && __result == 0) { __result = (((const unsigned
char *) (const char *) (psz_encoding))[2] - __s2[2]); if (__s1_len
> 2 && __result == 0) __result = (((const unsigned
char *) (const char *) (psz_encoding))[3] - __s2[3]); } } __result
; }))) : (__builtin_constant_p (psz_current_encoding) &&
((size_t)(const void *)((psz_current_encoding) + 1) - (size_t
)(const void *)(psz_current_encoding) == 1) && (__s2_len
= strlen (psz_current_encoding), __s2_len < 4) ? (__builtin_constant_p
(psz_encoding) && ((size_t)(const void *)((psz_encoding
) + 1) - (size_t)(const void *)(psz_encoding) == 1) ? __builtin_strcmp
(psz_encoding, psz_current_encoding) : (- (__extension__ ({ const
unsigned char *__s2 = (const unsigned char *) (const char *)
(psz_encoding); int __result = (((const unsigned char *) (const
char *) (psz_current_encoding))[0] - __s2[0]); if (__s2_len >
0 && __result == 0) { __result = (((const unsigned char
*) (const char *) (psz_current_encoding))[1] - __s2[1]); if (
__s2_len > 1 && __result == 0) { __result = (((const
unsigned char *) (const char *) (psz_current_encoding))[2] -
__s2[2]); if (__s2_len > 2 && __result == 0) __result
= (((const unsigned char *) (const char *) (psz_current_encoding
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (psz_encoding
, psz_current_encoding)))); })
) {
1931 iconv_close(iconv_handle);
1932 iconv_handle = (iconv_t)-1;
1933 }
1934
1935 if (iconv_handle == (iconv_t)-1)
1936 iconv_handle = iconv_open(psz_native_charset, psz_encoding);
1937 if (iconv_handle == (iconv_t)-1) {
1938 msg_Warn(NULL((void*)0), "couldn't open converter from %s to %s (%m)", psz_encoding,
1939 psz_native_charset);
1940 return iconv_append_null(p_string, i_length);
1941 }
1942
1943 /* converted strings can be up to six times larger */
1944 i_out_length = i_length * 6;
1945 p = psz_string = malloc(i_out_length);
1946 if (iconv(iconv_handle, &p_string, &i_length, &p, &i_out_length) == -1) {
1947 msg_Warn(NULL((void*)0), "couldn't convert from %s to %s (%m)", psz_encoding,
1948 psz_native_charset);
1949 free(psz_string);
1950 return iconv_append_null(p_string, i_length);
1951 }
1952 if (i_length)
1953 msg_Warn(NULL((void*)0), "partial conversion from %s to %s", psz_encoding,
1954 psz_native_charset);
1955
1956 *p = '\0';
1957 return psz_string;
1958#else
1959 return iconv_append_null(p_string, i_length);
1960#endif
1961}
1962
1963/*****************************************************************************
1964 * demux_Print
1965 *****************************************************************************
1966 * This code is from biTStream's examples and is under the WTFPL (see
1967 * LICENSE.WTFPL).
1968 *****************************************************************************/
1969__attribute__ ((format(printf, 2, 3)))
1970static void demux_Print(void *_unused, const char *psz_format, ...)
1971{
1972 char psz_fmt[strlen(psz_format) + 2];
1973 va_list args;
1974 va_start(args, psz_format)__builtin_va_start(args, psz_format);
1975 strcpy(psz_fmt, psz_format);
1976 if ( i_print_type != PRINT_XML )
1977 strcat(psz_fmt, "\n");
1978 vprintf(psz_fmt, args);
1979 va_end(args)__builtin_va_end(args);
1980}
1981
1982/*****************************************************************************
1983 * HandlePAT
1984 *****************************************************************************/
1985static void HandlePAT( mtime_t i_dts )
1986{
1987 bool_Bool b_change = false0;
1988 PSI_TABLE_DECLARE( pp_old_pat_sections )uint8_t *pp_old_pat_sections[256];
1989 uint8_t i_last_section = psi_table_get_lastsection( pp_next_pat_sections )psi_get_lastsection(pp_next_pat_sections[0]);
1990 uint8_t i;
1991
1992 if ( psi_table_validate( pp_current_pat_sections ) &&
1993 psi_table_compare( pp_current_pat_sections, pp_next_pat_sections ) )
1994 {
1995 /* Identical PAT. Shortcut. */
1996 psi_table_free( pp_next_pat_sections );
1997 psi_table_init( pp_next_pat_sections );
1998 goto out_pat;
1999 }
2000
2001 if ( !pat_table_validate( pp_next_pat_sections ) )
2002 {
2003 msg_Warn( NULL((void*)0), "invalid PAT received" );
2004 switch (i_print_type) {
2005 case PRINT_XML:
2006 printf("<ERROR type=\"invalid_pat\"/>\n");
2007 break;
2008 default:
2009 printf("invalid PAT received\n");
2010 }
2011 psi_table_free( pp_next_pat_sections );
2012 psi_table_init( pp_next_pat_sections );
2013 goto out_pat;
2014 }
2015
2016 /* Switch tables. */
2017 psi_table_copy( pp_old_pat_sections, pp_current_pat_sections );
2018 psi_table_copy( pp_current_pat_sections, pp_next_pat_sections );
2019 psi_table_init( pp_next_pat_sections );
2020
2021 if ( !psi_table_validate( pp_old_pat_sections )
2022 || psi_table_get_tableidext( pp_current_pat_sections )psi_get_tableidext(pp_current_pat_sections[0])
2023 != psi_table_get_tableidext( pp_old_pat_sections )psi_get_tableidext(pp_old_pat_sections[0]) )
2024 {
2025 b_change = true1;
2026 UpdateTSID();
2027 /* This will trigger a universal reset of everything. */
2028 }
2029
2030 for ( i = 0; i <= i_last_section; i++ )
2031 {
2032 uint8_t *p_section =
2033 psi_table_get_section( pp_current_pat_sections, i );
2034 const uint8_t *p_program;
2035 int j = 0;
2036
2037 while ( (p_program = pat_get_program( p_section, j )) != NULL((void*)0) )
2038 {
2039 const uint8_t *p_old_program = NULL((void*)0);
2040 uint16_t i_sid = patn_get_program( p_program );
2041 uint16_t i_pid = patn_get_pid( p_program );
2042 j++;
2043
2044 if ( i_sid == 0 )
2045 {
2046 if ( i_pid != NIT_PID0x10 )
2047 msg_Warn( NULL((void*)0),
2048 "NIT is carried on PID %hu which isn't DVB compliant",
2049 i_pid );
2050 continue; /* NIT */
2051 }
2052
2053 if ( !psi_table_validate( pp_old_pat_sections )
2054 || (p_old_program = pat_table_find_program(
2055 pp_old_pat_sections, i_sid )) == NULL((void*)0)
2056 || patn_get_pid( p_old_program ) != i_pid
2057 || b_change )
2058 {
2059 sid_t *p_sid;
2060
2061 if ( p_old_program != NULL((void*)0) )
2062 DeleteProgram( i_sid, patn_get_pid( p_old_program ) );
2063
2064 SelectPMT( i_sid, i_pid );
2065
2066 p_sid = FindSID( 0 );
2067 if ( p_sid == NULL((void*)0) )
2068 {
2069 p_sid = malloc( sizeof(sid_t) );
2070 p_sid->p_current_pmt = NULL((void*)0);
2071 i_nb_sids++;
2072 pp_sids = realloc( pp_sids, sizeof(sid_t *) * i_nb_sids );
2073 pp_sids[i_nb_sids - 1] = p_sid;
2074 }
2075
2076 p_sid->i_sid = i_sid;
2077 p_sid->i_pmt_pid = i_pid;
2078
2079 UpdatePAT( i_sid );
2080 }
2081 }
2082 }
2083
2084 if ( psi_table_validate( pp_old_pat_sections ) )
2085 {
2086 i_last_section = psi_table_get_lastsection( pp_old_pat_sections )psi_get_lastsection(pp_old_pat_sections[0]);
2087 for ( i = 0; i <= i_last_section; i++ )
2088 {
2089 uint8_t *p_section =
2090 psi_table_get_section( pp_old_pat_sections, i );
2091 const uint8_t *p_program;
2092 int j = 0;
2093
2094 while ( (p_program = pat_get_program( p_section, j )) != NULL((void*)0) )
2095 {
2096 uint16_t i_sid = patn_get_program( p_program );
2097 uint16_t i_pid = patn_get_pid( p_program );
2098 j++;
2099
2100 if ( i_sid == 0 )
2101 continue; /* NIT */
2102
2103 if ( pat_table_find_program( pp_current_pat_sections, i_sid )
2104 == NULL((void*)0) )
2105 {
2106 DeleteProgram( i_sid, i_pid );
2107 UpdatePAT( i_sid );
2108 }
2109 }
2110 }
2111
2112 psi_table_free( pp_old_pat_sections );
2113 }
2114
2115 pat_table_print( pp_current_pat_sections, msg_Dbg, NULL((void*)0), PRINT_TEXT );
2116 if ( b_print_enabled )
2117 {
2118 pat_table_print( pp_current_pat_sections, demux_Print, NULL((void*)0),
2119 i_print_type );
2120 if ( i_print_type == PRINT_XML )
2121 printf("\n");
2122 }
2123
2124out_pat:
2125 SendPAT( i_dts );
2126}
2127
2128/*****************************************************************************
2129 * HandlePATSection
2130 *****************************************************************************/
2131static void HandlePATSection( uint16_t i_pid, uint8_t *p_section,
2132 mtime_t i_dts )
2133{
2134 if ( i_pid != PAT_PID0x0 || !pat_validate( p_section ) )
2135 {
2136 msg_Warn( NULL((void*)0), "invalid PAT section received on PID %hu", i_pid );
2137 switch (i_print_type) {
2138 case PRINT_XML:
2139 printf("<ERROR type=\"invalid_pat_section\"/>\n");
2140 break;
2141 default:
2142 printf("invalid PAT section received on PID %hu\n", i_pid);
2143 }
2144 free( p_section );
2145 return;
2146 }
2147
2148 if ( !psi_table_section( pp_next_pat_sections, p_section ) )
2149 return;
2150
2151 HandlePAT( i_dts );
2152}
2153
2154/*****************************************************************************
2155 * HandleCAT
2156 *****************************************************************************/
2157static void HandleCAT( mtime_t i_dts )
2158{
2159 PSI_TABLE_DECLARE( pp_old_cat_sections )uint8_t *pp_old_cat_sections[256];
2160 uint8_t i_last_section = psi_table_get_lastsection( pp_next_cat_sections )psi_get_lastsection(pp_next_cat_sections[0]);
2161 uint8_t i_last_section2;
2162 uint8_t i, r;
2163 uint8_t *p_desc;
2164 int j, k;
2165
2166 if ( psi_table_validate( pp_current_cat_sections ) &&
2167 psi_table_compare( pp_current_cat_sections, pp_next_cat_sections ) )
2168 {
2169 /* Identical CAT. Shortcut. */
2170 psi_table_free( pp_next_cat_sections );
2171 psi_table_init( pp_next_cat_sections );
2172 goto out_cat;
2173 }
2174
2175 if ( !cat_table_validate( pp_next_cat_sections ) )
2176 {
2177 msg_Warn( NULL((void*)0), "invalid CAT received" );
2178 switch (i_print_type) {
2179 case PRINT_XML:
2180 printf("<ERROR type=\"invalid_cat\"/>\n");
2181 break;
2182 default:
2183 printf("invalid CAT received\n");
2184 }
2185 psi_table_free( pp_next_cat_sections );
2186 psi_table_init( pp_next_cat_sections );
2187 goto out_cat;
2188 }
2189
2190 /* Switch tables. */
2191 psi_table_copy( pp_old_cat_sections, pp_current_cat_sections );
2192 psi_table_copy( pp_current_cat_sections, pp_next_cat_sections );
2193 psi_table_init( pp_next_cat_sections );
2194
2195 for ( i = 0; i <= i_last_section; i++ )
2196 {
2197 uint8_t *p_section = psi_table_get_section( pp_current_cat_sections, i );
2198
2199 j = 0;
2200 while ( (p_desc = descl_get_desc( cat_get_descl(p_section), cat_get_desclength(p_section), j++ )) != NULL((void*)0) )
2201 {
2202 if ( desc_get_tag( p_desc ) != 0x09 || !desc09_validate( p_desc ) )
2203 continue;
2204
2205 SetPID_EMM( desc09_get_pid( p_desc ) );
2206 }
2207 }
2208
2209 if ( psi_table_validate( pp_old_cat_sections ) )
2210 {
2211 i_last_section = psi_table_get_lastsection( pp_old_cat_sections )psi_get_lastsection(pp_old_cat_sections[0]);
2212 for ( i = 0; i <= i_last_section; i++ )
2213 {
2214 uint8_t *p_old_section = psi_table_get_section( pp_old_cat_sections, i );
2215 j = 0;
2216 while ( (p_desc = descl_get_desc( cat_get_descl(p_old_section), cat_get_desclength(p_old_section), j++ )) != NULL((void*)0) )
2217 {
2218 uint16_t emm_pid;
2219 int pid_found = 0;
2220
2221 if ( desc_get_tag( p_desc ) != 0x09 || !desc09_validate( p_desc ) )
2222 continue;
2223
2224 emm_pid = desc09_get_pid( p_desc );
2225
2226 // Search in current sections if the pid exists
2227 i_last_section2 = psi_table_get_lastsection( pp_current_cat_sections )psi_get_lastsection(pp_current_cat_sections[0]);
2228 for ( r = 0; r <= i_last_section2; r++ )
2229 {
2230 uint8_t *p_section = psi_table_get_section( pp_current_cat_sections, r );
2231
2232 k = 0;
2233 while ( (p_desc = descl_get_desc( cat_get_descl(p_section), cat_get_desclength(p_section), k++ )) != NULL((void*)0) )
2234 {
2235 if ( desc_get_tag( p_desc ) != 0x09 || !desc09_validate( p_desc ) )
2236 continue;
2237 if ( ca_desc_find( cat_get_descl(p_section), cat_get_desclength(p_section), emm_pid ) != NULL((void*)0) )
2238 {
2239 pid_found = 1;
2240 break;
2241 }
2242 }
2243 }
2244
2245 if ( !pid_found )
2246 UnsetPID(emm_pid);
2247 }
2248 }
2249
2250 psi_table_free( pp_old_cat_sections );
2251 }
2252
2253 cat_table_print( pp_current_cat_sections, msg_Dbg, NULL((void*)0), PRINT_TEXT );
2254 if ( b_print_enabled )
2255 {
2256 cat_table_print( pp_current_cat_sections, demux_Print, NULL((void*)0),
2257 i_print_type );
2258 if ( i_print_type == PRINT_XML )
2259 printf("\n");
2260 }
2261
2262out_cat:
2263 return;
2264}
2265
2266/*****************************************************************************
2267 * HandleCATSection
2268 *****************************************************************************/
2269static void HandleCATSection( uint16_t i_pid, uint8_t *p_section,
2270 mtime_t i_dts )
2271{
2272 if ( i_pid != CAT_PID0x01 || !cat_validate( p_section ) )
2273 {
2274 msg_Warn( NULL((void*)0), "invalid CAT section received on PID %hu", i_pid );
2275 switch (i_print_type) {
2276 case PRINT_XML:
2277 printf("<ERROR type=\"invalid_cat_section\"/>\n");
2278 break;
2279 default:
2280 printf("invalid CAT section received on PID %hu\n", i_pid);
2281 }
2282 free( p_section );
2283 return;
2284 }
2285
2286 if ( !psi_table_section( pp_next_cat_sections, p_section ) )
2287 return;
2288
2289 HandleCAT( i_dts );
2290}
2291
2292static void mark_pmt_pids( uint8_t *p_pmt, uint8_t pid_map[], uint8_t marker )
2293{
2294 uint16_t j, k;
2295 uint8_t *p_es;
2296 uint8_t *p_desc;
2297
2298 uint16_t i_pcr_pid = pmt_get_pcrpid( p_pmt );
2299
2300 if ( b_enable_ecm )
2301 {
2302 j = 0;
2303 while ( (p_desc = descs_get_desc( pmt_get_descs( p_pmt ), j++ )) != NULL((void*)0) )
2304 {
2305 if ( desc_get_tag( p_desc ) != 0x09 || !desc09_validate( p_desc ) )
2306 continue;
2307 pid_map[ desc09_get_pid( p_desc ) ] |= marker;
2308 }
2309 }
2310
2311 if ( i_pcr_pid != PADDING_PID8191 )
2312 pid_map[ i_pcr_pid ] |= marker;
2313
2314 j = 0;
2315 while ( (p_es = pmt_get_es( p_pmt, j )) != NULL((void*)0) )
2316 {
2317 uint16_t i_pid = pmtn_get_pid( p_es );
2318 j++;
2319
2320 if ( PIDWouldBeSelected( p_es ) )
2321 pid_map[ i_pid ] |= marker;
2322
2323 p_pids[i_pid].b_pes = PIDCarriesPES( p_es );
2324
2325 if ( b_enable_ecm )
2326 {
2327 k = 0;
2328 while ( (p_desc = descs_get_desc( pmtn_get_descs( p_es ), k++ )) != NULL((void*)0) )
2329 {
2330 if ( desc_get_tag( p_desc ) != 0x09 || !desc09_validate( p_desc ) )
2331 continue;
2332 pid_map[ desc09_get_pid( p_desc ) ] |= marker;
2333 }
2334 }
2335 }
2336}
2337
2338/*****************************************************************************
2339 * HandlePMT
2340 *****************************************************************************/
2341static void HandlePMT( uint16_t i_pid, uint8_t *p_pmt, mtime_t i_dts )
2342{
2343 uint16_t i_sid = pmt_get_programpsi_get_tableidext( p_pmt );
2344 sid_t *p_sid;
2345 bool_Bool b_needs_descrambling, b_needed_descrambling, b_is_selected;
2346 uint8_t pid_map[MAX_PIDS8192];
2347
2348 p_sid = FindSID( i_sid );
2349 if ( p_sid == NULL((void*)0) )
2350 {
2351 /* Unwanted SID (happens when the same PMT PID is used for several
2352 * programs). */
2353 free( p_pmt );
2354 return;
2355 }
2356
2357 if ( i_pid != p_sid->i_pmt_pid )
2358 {
2359 msg_Warn( NULL((void*)0), "invalid PMT section received on PID %hu", i_pid );
2360 switch (i_print_type) {
2361 case PRINT_XML:
2362 printf("<ERROR type=\"ghost_pmt\" program=\"%hu\n pid=\"%hu\"/>\n",
2363 i_sid, i_pid);
2364 break;
2365 default:
2366 printf("ghost PMT for service %hu carried on PID %hu\n", i_sid,
2367 i_pid);
2368 }
2369 free( p_pmt );
2370 return;
2371 }
2372
2373 if ( p_sid->p_current_pmt != NULL((void*)0) &&
2374 psi_compare( p_sid->p_current_pmt, p_pmt ) )
2375 {
2376 /* Identical PMT. Shortcut. */
2377 free( p_pmt );
2378 goto out_pmt;
2379 }
2380
2381 if ( !pmt_validate( p_pmt ) )
2382 {
2383 msg_Warn( NULL((void*)0), "invalid PMT section received on PID %hu", i_pid );
2384 switch (i_print_type) {
2385 case PRINT_XML:
2386 printf("<ERROR type=\"invalid_pmt_section\" pid=\"%hu\"/>\n",
2387 i_pid);
2388 break;
2389 default:
2390 printf("invalid PMT section received on PID %hu\n", i_pid);
2391 }
2392 free( p_pmt );
2393 goto out_pmt;
2394 }
2395
2396 memset( pid_map, 0, sizeof(pid_map) );
2397
2398 b_needs_descrambling = PMTNeedsDescrambling( p_pmt );
2399 b_needed_descrambling = p_sid->p_current_pmt != NULL((void*)0) ?
2400 PMTNeedsDescrambling( p_sid->p_current_pmt ) :
2401 false0;
2402 b_is_selected = SIDIsSelected( i_sid );
2403
2404 if ( i_ca_handle && b_is_selected &&
2405 !b_needs_descrambling && b_needed_descrambling )
2406 en50221_DeletePMT( p_sid->p_current_pmt );
2407
2408 if ( p_sid->p_current_pmt != NULL((void*)0) )
2409 {
2410 mark_pmt_pids( p_sid->p_current_pmt, pid_map, 0x02 );
2411 free( p_sid->p_current_pmt );
2412 }
2413
2414 mark_pmt_pids( p_pmt, pid_map, 0x01 );
2415
2416 /* Start to stream PIDs */
2417 int pid;
2418 for ( pid = 0; pid < MAX_PIDS8192; pid++ )
2419 {
2420 /* The pid does not exist in the old PMT and in the new PMT. Ignore this pid. */
2421 if ( !pid_map[ pid ] )
2422 continue;
2423
2424 switch ( pid_map[ pid ] & 0x03 ) {
2425 case 0x03: /* The pid exists in the old PMT and in the new PMT. The pid was already selected in case 0x01. */
2426 continue;
2427 case 0x02: /* The pid does not exist in the new PMT but exists in the old PMT. Unselect it. */
2428 UnselectPID( i_sid, pid );
2429 break;
2430 case 0x01: /* The pid exists in new PMT. Select it. */
2431 SelectPID( i_sid, pid );
2432 break;
2433 }
2434 }
2435
2436 p_sid->p_current_pmt = p_pmt;
2437
2438 if ( i_ca_handle && b_is_selected )
2439 {
2440 if ( b_needs_descrambling && !b_needed_descrambling )
2441 en50221_AddPMT( p_pmt );
2442 else if ( b_needs_descrambling && b_needed_descrambling )
2443 en50221_UpdatePMT( p_pmt );
2444 }
2445
2446 UpdatePMT( i_sid );
2447
2448 pmt_print( p_pmt, msg_Dbg, NULL((void*)0), demux_Iconv, NULL((void*)0), PRINT_TEXT );
2449 if ( b_print_enabled )
2450 {
2451 pmt_print( p_pmt, demux_Print, NULL((void*)0), demux_Iconv, NULL((void*)0),
2452 i_print_type );
2453 if ( i_print_type == PRINT_XML )
2454 printf("\n");
2455 }
2456
2457out_pmt:
2458 SendPMT( p_sid, i_dts );
2459}
2460
2461/*****************************************************************************
2462 * HandleNIT
2463 *****************************************************************************/
2464static void HandleNIT( mtime_t i_dts )
2465{
2466 if ( psi_table_validate( pp_current_nit_sections ) &&
2467 psi_table_compare( pp_current_nit_sections, pp_next_nit_sections ) )
2468 {
2469 /* Identical NIT. Shortcut. */
2470 psi_table_free( pp_next_nit_sections );
2471 psi_table_init( pp_next_nit_sections );
2472 goto out_nit;
2473 }
2474
2475 if ( !nit_table_validate( pp_next_nit_sections ) )
2476 {
2477 msg_Warn( NULL((void*)0), "invalid NIT received" );
2478 switch (i_print_type) {
2479 case PRINT_XML:
2480 printf("<ERROR type=\"invalid_nit\"/>\n");
2481 break;
2482 default:
2483 printf("invalid NIT received\n");
2484 }
2485 psi_table_free( pp_next_nit_sections );
2486 psi_table_init( pp_next_nit_sections );
2487 goto out_nit;
2488 }
2489
2490 /* Switch tables. */
2491 psi_table_free( pp_current_nit_sections );
2492 psi_table_copy( pp_current_nit_sections, pp_next_nit_sections );
2493 psi_table_init( pp_next_nit_sections );
2494
2495 nit_table_print( pp_current_nit_sections, msg_Dbg, NULL((void*)0),
2496 demux_Iconv, NULL((void*)0), PRINT_TEXT );
2497 if ( b_print_enabled )
2498 {
2499 nit_table_print( pp_current_nit_sections, demux_Print, NULL((void*)0),
2500 demux_Iconv, NULL((void*)0), i_print_type );
2501 if ( i_print_type == PRINT_XML )
2502 printf("\n");
2503 }
2504
2505out_nit:
2506 ;
2507}
2508
2509/*****************************************************************************
2510 * HandleNITSection
2511 *****************************************************************************/
2512static void HandleNITSection( uint16_t i_pid, uint8_t *p_section,
2513 mtime_t i_dts )
2514{
2515 if ( i_pid != NIT_PID0x10 || !nit_validate( p_section ) )
2516 {
2517 msg_Warn( NULL((void*)0), "invalid NIT section received on PID %hu", i_pid );
2518 switch (i_print_type) {
2519 case PRINT_XML:
2520 printf("<ERROR type=\"invalid_nit_section\" pid=\"%hu\"/>\n",
2521 i_pid);
2522 break;
2523 default:
2524 printf("invalid NIT section received on PID %hu\n", i_pid);
2525 }
2526 free( p_section );
2527 return;
2528 }
2529
2530 if ( psi_table_section( pp_next_nit_sections, p_section ) )
2531 HandleNIT( i_dts );
2532
2533 /* This case is different because DVB specifies a minimum bitrate for
2534 * PID 0x10, even if we don't have any thing to send (for cheap
2535 * transport over network boundaries). */
2536 SendNIT( i_dts );
2537}
2538
2539
2540/*****************************************************************************
2541 * HandleSDT
2542 *****************************************************************************/
2543static void HandleSDT( mtime_t i_dts )
2544{
2545 PSI_TABLE_DECLARE( pp_old_sdt_sections )uint8_t *pp_old_sdt_sections[256];
2546 uint8_t i_last_section = psi_table_get_lastsection( pp_next_sdt_sections )psi_get_lastsection(pp_next_sdt_sections[0]);
2547 uint8_t i;
2548 int j;
2549
2550 if ( psi_table_validate( pp_current_sdt_sections ) &&
2551 psi_table_compare( pp_current_sdt_sections, pp_next_sdt_sections ) )
2552 {
2553 /* Identical SDT. Shortcut. */
2554 psi_table_free( pp_next_sdt_sections );
2555 psi_table_init( pp_next_sdt_sections );
2556 goto out_sdt;
2557 }
2558
2559 if ( !sdt_table_validate( pp_next_sdt_sections ) )
2560 {
2561 msg_Warn( NULL((void*)0), "invalid SDT received" );
2562 switch (i_print_type) {
2563 case PRINT_XML:
2564 printf("<ERROR type=\"invalid_sdt\"/>\n");
2565 break;
2566 default:
2567 printf("invalid SDT received\n");
2568 }
2569 psi_table_free( pp_next_sdt_sections );
2570 psi_table_init( pp_next_sdt_sections );
2571 goto out_sdt;
2572 }
2573
2574 /* Switch tables. */
2575 psi_table_copy( pp_old_sdt_sections, pp_current_sdt_sections );
2576 psi_table_copy( pp_current_sdt_sections, pp_next_sdt_sections );
2577 psi_table_init( pp_next_sdt_sections );
2578
2579 for ( i = 0; i <= i_last_section; i++ )
2580 {
2581 uint8_t *p_section =
2582 psi_table_get_section( pp_current_sdt_sections, i );
2583 uint8_t *p_service;
2584 j = 0;
2585
2586 while ( (p_service = sdt_get_service( p_section, j )) != NULL((void*)0) )
2587 {
2588 uint16_t i_sid = sdtn_get_sid( p_service );
2589 j++;
2590
2591 UpdateSDT( i_sid );
2592 }
2593 }
2594
2595 if ( psi_table_validate( pp_old_sdt_sections ) )
2596 {
2597 i_last_section = psi_table_get_lastsection( pp_old_sdt_sections )psi_get_lastsection(pp_old_sdt_sections[0]);
2598 for ( i = 0; i <= i_last_section; i++ )
2599 {
2600 uint8_t *p_section =
2601 psi_table_get_section( pp_old_sdt_sections, i );
2602 const uint8_t *p_service;
2603 int j = 0;
2604
2605 while ( (p_service = sdt_get_service( p_section, j )) != NULL((void*)0) )
2606 {
2607 uint16_t i_sid = sdtn_get_sid( p_service );
2608 j++;
2609
2610 if ( sdt_table_find_service( pp_current_sdt_sections, i_sid )
2611 == NULL((void*)0) )
2612 UpdateSDT( i_sid );
2613 }
2614 }
2615
2616 psi_table_free( pp_old_sdt_sections );
2617 }
2618
2619 sdt_table_print( pp_current_sdt_sections, msg_Dbg, NULL((void*)0),
2620 demux_Iconv, NULL((void*)0), PRINT_TEXT );
2621 if ( b_print_enabled )
2622 {
2623 sdt_table_print( pp_current_sdt_sections, demux_Print, NULL((void*)0),
2624 demux_Iconv, NULL((void*)0), i_print_type );
2625 if ( i_print_type == PRINT_XML )
2626 printf("\n");
2627 }
2628
2629out_sdt:
2630 SendSDT( i_dts );
2631}
2632
2633/*****************************************************************************
2634 * HandleSDTSection
2635 *****************************************************************************/
2636static void HandleSDTSection( uint16_t i_pid, uint8_t *p_section,
2637 mtime_t i_dts )
2638{
2639 if ( i_pid != SDT_PID0x11 || !sdt_validate( p_section ) )
2640 {
2641 msg_Warn( NULL((void*)0), "invalid SDT section received on PID %hu", i_pid );
2642 switch (i_print_type) {
2643 case PRINT_XML:
2644 printf("<ERROR type=\"invalid_sdt_section\" pid=\"%hu\"/>\n",
2645 i_pid);
2646 break;
2647 default:
2648 printf("invalid SDT section received on PID %hu\n", i_pid);
2649 }
2650 free( p_section );
2651 return;
2652 }
2653
2654 if ( !psi_table_section( pp_next_sdt_sections, p_section ) )
2655 return;
2656
2657 HandleSDT( i_dts );
2658}
2659
2660/*****************************************************************************
2661 * HandleEITSection
2662 *****************************************************************************/
2663static void HandleEIT( uint16_t i_pid, uint8_t *p_eit, mtime_t i_dts )
2664{
2665 uint16_t i_sid = eit_get_sidpsi_get_tableidext( p_eit );
2666 sid_t *p_sid;
2667
2668 p_sid = FindSID( i_sid );
2669 if ( p_sid == NULL((void*)0) )
2670 {
2671 /* Not a selected program. */
2672 free( p_eit );
2673 return;
2674 }
2675
2676 if ( i_pid != EIT_PID0x12 || !eit_validate( p_eit ) )
2677 {
2678/*
2679 msg_Warn( NULL, "invalid EIT section received on PID %hu", i_pid );
2680 switch (i_print_type) {
2681 case PRINT_XML:
2682 printf("<ERROR type=\"invalid_eit_section\" pid=\"%hu\"/>\n",
2683 i_pid);
2684 break;
2685 default:
2686 printf("invalid EIT section received on PID %hu\n", i_pid);
2687 }
2688*/
2689 free( p_eit );
2690 return;
2691 }
2692
2693 SendEIT( p_sid, i_dts, p_eit );
2694 free( p_eit );
2695}
2696
2697/*****************************************************************************
2698 * HandleSection
2699 *****************************************************************************/
2700static void HandleSection( uint16_t i_pid, uint8_t *p_section, mtime_t i_dts )
2701{
2702 uint8_t i_table_id = psi_get_tableid( p_section );
2703
2704 if ( !psi_validate( p_section ) )
2705 {
2706/*
2707 msg_Warn( NULL, "invalid section on PID %hu", i_pid );
2708 switch (i_print_type) {
2709 case PRINT_XML:
2710 printf("<ERROR type=\"invalid_section\" pid=\"%hu\"/>\n", i_pid);
2711 break;
2712 default:
2713 printf("invalid section on PID %hu\n", i_pid);
2714 }
2715*/
2716 free( p_section );
2717 return;
2718 }
2719
2720 if ( !psi_get_current( p_section ) )
2721 {
2722 /* Ignore sections which are not in use yet. */
2723 free( p_section );
2724 return;
2725 }
2726
2727 switch ( i_table_id )
2728 {
2729 case PAT_TABLE_ID0x0:
2730 HandlePATSection( i_pid, p_section, i_dts );
2731 break;
2732
2733 case CAT_TABLE_ID0x01:
2734 if ( b_enable_emm )
2735 HandleCATSection( i_pid, p_section, i_dts );
2736 break;
2737
2738 case PMT_TABLE_ID0x2:
2739 HandlePMT( i_pid, p_section, i_dts );
2740 break;
2741
2742 case NIT_TABLE_ID_ACTUAL0x40:
2743 HandleNITSection( i_pid, p_section, i_dts );
2744 break;
2745
2746 case SDT_TABLE_ID_ACTUAL0x42:
2747 HandleSDTSection( i_pid, p_section, i_dts );
2748 break;
2749
2750 default:
2751 if ( i_table_id == EIT_TABLE_ID_PF_ACTUAL0x4e ||
2752 (i_table_id >= EIT_TABLE_ID_SCHED_ACTUAL_FIRST0x50 &&
2753 i_table_id <= EIT_TABLE_ID_SCHED_ACTUAL_LAST0x5f) )
2754 {
2755 HandleEIT( i_pid, p_section, i_dts );
2756 break;
2757 }
2758 free( p_section );
2759 break;
2760 }
2761}
2762
2763/*****************************************************************************
2764 * HandlePSIPacket
2765 *****************************************************************************/
2766static void HandlePSIPacket( uint8_t *p_ts, mtime_t i_dts )
2767{
2768 uint16_t i_pid = ts_get_pid( p_ts );
2769 ts_pid_t *p_pid = &p_pids[i_pid];
2770 uint8_t i_cc = ts_get_cc( p_ts );
2771 const uint8_t *p_payload;
2772 uint8_t i_length;
2773
2774 if ( ts_check_duplicate( i_cc, p_pid->i_last_cc )
2775 || !ts_has_payload( p_ts ) )
2776 return;
2777
2778 if ( p_pid->i_last_cc != -1
2779 && ts_check_discontinuity( i_cc, p_pid->i_last_cc ) )
2780 psi_assemble_reset( &p_pid->p_psi_buffer, &p_pid->i_psi_buffer_used );
2781
2782 p_payload = ts_section( p_ts );
2783 i_length = p_ts + TS_SIZE188 - p_payload;
2784
2785 if ( !psi_assemble_empty( &p_pid->p_psi_buffer,
2786 &p_pid->i_psi_buffer_used ) )
2787 {
2788 uint8_t *p_section = psi_assemble_payload( &p_pid->p_psi_buffer,
2789 &p_pid->i_psi_buffer_used,
2790 &p_payload, &i_length );
2791 if ( p_section != NULL((void*)0) )
2792 HandleSection( i_pid, p_section, i_dts );
2793 }
2794
2795 p_payload = ts_next_section( p_ts );
2796 i_length = p_ts + TS_SIZE188 - p_payload;
2797
2798 while ( i_length )
2799 {
2800 uint8_t *p_section = psi_assemble_payload( &p_pid->p_psi_buffer,
2801 &p_pid->i_psi_buffer_used,
2802 &p_payload, &i_length );
2803 if ( p_section != NULL((void*)0) )
2804 HandleSection( i_pid, p_section, i_dts );
2805 }
2806}
2807
2808/*****************************************************************************
2809 * PID info functions
2810 *****************************************************************************/
2811static const char *h222_stream_type_desc(uint8_t i_stream_type) {
2812 /* See ISO/IEC 13818-1 : 2000 (E) | Table 2-29 - Stream type assignments, Page 66 (48) */
2813 if (i_stream_type == 0)
2814 return "Reserved stream";
2815 switch (i_stream_type) {
2816 case 0x01: return "11172-2 video (MPEG-1)";
2817 case 0x02: return "H.262/13818-2 video (MPEG-2) or 11172-2 constrained video";
2818 case 0x03: return "11172-3 audio (MPEG-1)";
2819 case 0x04: return "13818-3 audio (MPEG-2)";
2820 case 0x05: return "H.222.0/13818-1 private sections";
2821 case 0x06: return "H.222.0/13818-1 PES private data";
2822 case 0x07: return "13522 MHEG";
2823 case 0x08: return "H.222.0/13818-1 Annex A - DSM CC";
2824 case 0x09: return "H.222.1";
2825 case 0x0A: return "13818-6 type A";
2826 case 0x0B: return "13818-6 type B";
2827 case 0x0C: return "13818-6 type C";
2828 case 0x0D: return "13818-6 type D";
2829 case 0x0E: return "H.222.0/13818-1 auxiliary";
2830 case 0x0F: return "13818-7 Audio with ADTS transport syntax";
2831 case 0x10: return "14496-2 Visual (MPEG-4 part 2 video)";
2832 case 0x11: return "14496-3 Audio with LATM transport syntax (14496-3/AMD 1)";
2833 case 0x12: return "14496-1 SL-packetized or FlexMux stream in PES packets";
2834 case 0x13: return "14496-1 SL-packetized or FlexMux stream in 14496 sections";
2835 case 0x14: return "ISO/IEC 13818-6 Synchronized Download Protocol";
2836 case 0x15: return "Metadata in PES packets";
2837 case 0x16: return "Metadata in metadata_sections";
2838 case 0x17: return "Metadata in 13818-6 Data Carousel";
2839 case 0x18: return "Metadata in 13818-6 Object Carousel";
2840 case 0x19: return "Metadata in 13818-6 Synchronized Download Protocol";
2841 case 0x1A: return "13818-11 MPEG-2 IPMP stream";
2842 case 0x1B: return "H.264/14496-10 video (MPEG-4/AVC)";
2843 case 0x42: return "AVS Video";
2844 case 0x7F: return "IPMP stream";
2845 default : return "Unknown stream";
2846 }
2847}
2848
2849static const char *get_pid_desc(uint16_t i_pid, uint16_t *i_sid) {
2850 int i, j, k;
2851 uint8_t i_last_section;
2852 uint8_t *p_desc;
2853 uint16_t i_nit_pid = NIT_PID0x10, i_pcr_pid = 0;
2854
2855 /* Simple cases */
2856 switch (i_pid)
2857 {
2858 case 0x00: return "PAT";
2859 case 0x01: return "CAT";
2860 case 0x11: return "SDT";
2861 case 0x12: return "EPG";
2862 case 0x14: return "TDT/TOT";
2863 }
2864
2865 /* Detect NIT pid */
2866 if ( psi_table_validate( pp_current_pat_sections ) )
2867 {
2868 i_last_section = psi_table_get_lastsection( pp_current_pat_sections )psi_get_lastsection(pp_current_pat_sections[0]);
2869 for ( i = 0; i <= i_last_section; i++ )
2870 {
2871 uint8_t *p_section = psi_table_get_section( pp_current_pat_sections, i );
2872 uint8_t *p_program;
2873
2874 j = 0;
2875 while ( (p_program = pat_get_program( p_section, j++ )) != NULL((void*)0) )
2876 {
2877 /* Programs with PID == 0 are actually NIT */
2878 if ( patn_get_program( p_program ) == 0 )
2879 {
2880 i_nit_pid = patn_get_pid( p_program );
2881 break;
2882 }
2883 }
2884 }
2885 }
2886
2887 /* Detect EMM pids */
2888 if ( b_enable_emm && psi_table_validate( pp_current_cat_sections ) )
2889 {
2890 i_last_section = psi_table_get_lastsection( pp_current_cat_sections )psi_get_lastsection(pp_current_cat_sections[0]);
2891 for ( i = 0; i <= i_last_section; i++ )
2892 {
2893 uint8_t *p_section = psi_table_get_section( pp_current_cat_sections, i );
2894
2895 j = 0;
2896 while ( (p_desc = descl_get_desc( cat_get_descl(p_section), cat_get_desclength(p_section), j++ )) != NULL((void*)0) )
2897 {
2898 if ( desc_get_tag( p_desc ) != 0x09 || !desc09_validate( p_desc ) )
2899 continue;
2900
2901 if ( desc09_get_pid( p_desc ) == i_pid ) {
2902 return "EMM";
2903 }
2904 }
2905 }
2906 }
2907
2908 /* Detect streams in PMT */
2909 for ( k = 0; k < i_nb_sids; k++ )
2910 {
2911 sid_t *p_sid = pp_sids[k];
2912 if ( p_sid->i_pmt_pid == i_pid )
2913 {
2914 if ( i_sid )
2915 *i_sid = p_sid->i_sid;
2916 return "PMT";
2917 }
2918
2919 if ( p_sid->i_sid && p_sid->p_current_pmt != NULL((void*)0) )
2920 {
2921 uint8_t *p_current_pmt = p_sid->p_current_pmt;
2922 uint8_t *p_current_es;
2923
2924 /* The PCR PID can be alone or PCR can be carried in some other PIDs (mostly video)
2925 so just remember the pid and if it is alone it will be reported as PCR, otherwise
2926 stream type of the PID will be reported */
2927 if ( i_pid == pmt_get_pcrpid( p_current_pmt ) ) {
2928 if ( i_sid )
2929 *i_sid = p_sid->i_sid;
2930 i_pcr_pid = pmt_get_pcrpid( p_current_pmt );
2931 }
2932
2933 /* Look for ECMs */
2934 j = 0;
2935 while ((p_desc = descs_get_desc( pmt_get_descs( p_current_pmt ), j++ )) != NULL((void*)0))
2936 {
2937 if ( desc_get_tag( p_desc ) != 0x09 || !desc09_validate( p_desc ) )
2938 continue;
2939
2940 if ( desc09_get_pid( p_desc ) == i_pid ) {
2941 if ( i_sid )
2942 *i_sid = p_sid->i_sid;
2943 return "ECM";
2944 }
2945 }
2946
2947 /* Detect stream types */
2948 j = 0;
2949 while ( (p_current_es = pmt_get_es( p_current_pmt, j++ )) != NULL((void*)0) )
2950 {
2951 if ( pmtn_get_pid( p_current_es ) == i_pid )
2952 {
2953 if ( i_sid )
2954 *i_sid = p_sid->i_sid;
2955 return h222_stream_type_desc( pmtn_get_streamtype( p_current_es ) );
2956 }
2957 }
2958 }
2959 }
2960
2961 /* Are there any other PIDs? */
2962 if (i_pid == i_nit_pid)
2963 return "NIT";
2964
2965 if (i_pid == i_pcr_pid)
2966 return "PCR";
2967
2968 return "...";
2969}
2970
2971/*****************************************************************************
2972 * Functions that return packed sections
2973 *****************************************************************************/
2974uint8_t *demux_get_current_packed_PAT( unsigned int *pi_pack_size ) {
2975 return psi_pack_sections( pp_current_pat_sections, pi_pack_size );
2976}
2977
2978uint8_t *demux_get_current_packed_CAT( unsigned int *pi_pack_size ) {
2979 return psi_pack_sections( pp_current_cat_sections, pi_pack_size );
2980}
2981
2982uint8_t *demux_get_current_packed_NIT( unsigned int *pi_pack_size ) {
2983 return psi_pack_sections( pp_current_nit_sections, pi_pack_size );
2984}
2985
2986uint8_t *demux_get_current_packed_SDT( unsigned int *pi_pack_size ) {
2987 return psi_pack_sections( pp_current_sdt_sections, pi_pack_size );
2988}
2989
2990uint8_t *demux_get_packed_PMT( uint16_t i_sid, unsigned int *pi_pack_size ) {
2991 sid_t *p_sid = FindSID( i_sid );
2992 if ( p_sid != NULL((void*)0) && p_sid->p_current_pmt && pmt_validate( p_sid->p_current_pmt ) )
2993 return psi_pack_section( p_sid->p_current_pmt, pi_pack_size );
2994 return NULL((void*)0);
2995}
2996
2997inline void demux_get_PID_info( uint16_t i_pid, uint8_t *p_data ) {
2998 ts_pid_info_t *p_info = (ts_pid_info_t *)p_data;
2999 *p_info = p_pids[i_pid].info;
3000}
3001
3002inline void demux_get_PIDS_info( uint8_t *p_data ) {
3003 int i_pid;
3004 for (i_pid = 0; i_pid < MAX_PIDS8192; i_pid++ )
3005 demux_get_PID_info( i_pid, p_data + ( i_pid * sizeof(ts_pid_info_t) ) );
3006}