Merge branch 'nto-signal-stats'
[dvblast.git] / demux.c
blob57bde1b9fc455af2d995a5ce2239f56fffffe124
1 /*****************************************************************************
2 * demux.c
3 *****************************************************************************
4 * Copyright (C) 2004, 2008-2011, 2015-2018 VideoLAN
6 * Authors: Christophe Massiot <massiot@via.ecp.fr>
7 * Andy Gatward <a.j.gatward@reading.ac.uk>
8 * Marian Ďurkovič <md@bts.sk>
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.
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.
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 *****************************************************************************/
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 #include <ev.h>
38 #include "dvblast.h"
39 #include "en50221.h"
40 #include "mrtg-cnt.h"
42 #ifdef HAVE_ICONV
43 #include <iconv.h>
44 #endif
46 #include <bitstream/mpeg/ts.h>
47 #include <bitstream/mpeg/pes.h>
48 #include <bitstream/mpeg/psi.h>
49 #include <bitstream/dvb/si.h>
50 #include <bitstream/dvb/si_print.h>
51 #include <bitstream/mpeg/psi_print.h>
53 /*****************************************************************************
54 * Local declarations
55 *****************************************************************************/
56 #define MIN_SECTION_FRAGMENT PSI_HEADER_SIZE_SYNTAX1
58 typedef struct ts_pid_t
60 int i_refcount;
61 int i_psi_refcount;
62 bool b_pes;
63 int8_t i_last_cc;
64 int i_demux_fd;
65 /* b_emm is set to true when PID carries EMM packet
66 and should be outputed in all services */
67 bool b_emm;
69 /* PID info and stats */
70 mtime_t i_bytes_ts;
71 unsigned long i_packets_passed;
72 ts_pid_info_t info;
74 /* biTStream PSI section gathering */
75 uint8_t *p_psi_buffer;
76 uint16_t i_psi_buffer_used;
78 output_t **pp_outputs;
79 int i_nb_outputs;
81 int i_pes_status; /* pes + unscrambled */
82 struct ev_timer timeout_watcher;
84 /* last service selecting this pid, only used for statistics */
85 uint16_t i_sid;
86 } ts_pid_t;
88 struct eit_sections {
89 PSI_TABLE_DECLARE(data);
92 /* EIT is carried in several separate tables, we need to track each table
93 separately, otherwise one table overwrites sections of another table */
94 #define MAX_EIT_TABLES ( EIT_TABLE_ID_SCHED_ACTUAL_LAST - EIT_TABLE_ID_PF_ACTUAL )
96 typedef struct sid_t
98 uint16_t i_sid, i_pmt_pid;
99 uint8_t *p_current_pmt;
100 struct eit_sections eit_table[MAX_EIT_TABLES];
101 unsigned long i_packets_passed;
102 } sid_t;
104 mtime_t i_wallclock = 0;
106 static ts_pid_t p_pids[MAX_PIDS];
107 static sid_t **pp_sids = NULL;
108 static int i_nb_sids = 0;
110 static PSI_TABLE_DECLARE(pp_current_pat_sections);
111 static PSI_TABLE_DECLARE(pp_next_pat_sections);
112 static PSI_TABLE_DECLARE(pp_current_cat_sections);
113 static PSI_TABLE_DECLARE(pp_next_cat_sections);
114 static PSI_TABLE_DECLARE(pp_current_nit_sections);
115 static PSI_TABLE_DECLARE(pp_next_nit_sections);
116 static PSI_TABLE_DECLARE(pp_current_sdt_sections);
117 static PSI_TABLE_DECLARE(pp_next_sdt_sections);
118 static mtime_t i_last_dts = -1;
119 static int i_demux_fd;
120 static uint64_t i_nb_packets = 0;
121 static uint64_t i_nb_invalids = 0;
122 static uint64_t i_nb_discontinuities = 0;
123 static uint64_t i_nb_errors = 0;
124 static int i_tuner_errors = 0;
125 static mtime_t i_last_error = 0;
126 static mtime_t i_last_reset = 0;
127 static struct ev_timer print_watcher;
129 #ifdef HAVE_ICONV
130 static iconv_t iconv_handle = (iconv_t)-1;
131 #endif
133 /*****************************************************************************
134 * Local prototypes
135 *****************************************************************************/
136 static void demux_Handle( block_t *p_ts );
137 static void SetDTS( block_t *p_list );
138 static void SetPID( uint16_t i_pid );
139 static void SetPID_EMM( uint16_t i_pid );
140 static void UnsetPID( uint16_t i_pid );
141 static void StartPID( output_t *p_output, uint16_t i_pid );
142 static void StopPID( output_t *p_output, uint16_t i_pid );
143 static void SelectPID( uint16_t i_sid, uint16_t i_pid, bool b_pcr );
144 static void UnselectPID( uint16_t i_sid, uint16_t i_pid );
145 static void SelectPMT( uint16_t i_sid, uint16_t i_pid );
146 static void UnselectPMT( uint16_t i_sid, uint16_t i_pid );
147 static void GetPIDS( uint16_t **ppi_wanted_pids, int *pi_nb_wanted_pids,
148 uint16_t *pi_pcr_pid, uint16_t i_sid,
149 const uint16_t *pi_pids, int i_nb_pids );
150 static bool SIDIsSelected( uint16_t i_sid );
151 static bool PIDWouldBeSelected( uint8_t *p_es );
152 static bool PMTNeedsDescrambling( uint8_t *p_pmt );
153 static void FlushEIT( output_t *p_output, mtime_t i_dts );
154 static void SendTDT( block_t *p_ts );
155 static void SendEMM( block_t *p_ts );
156 static void NewPAT( output_t *p_output );
157 static void NewPMT( output_t *p_output );
158 static void NewNIT( output_t *p_output );
159 static void NewSDT( output_t *p_output );
160 static void HandlePSIPacket( uint8_t *p_ts, mtime_t i_dts );
161 static const char *get_pid_desc(uint16_t i_pid, uint16_t *i_sid);
164 * Remap an ES pid to a fixed value.
165 * Multiple streams of the same type use sequential pids
166 * Returns the new pid and updates the map tables
168 static uint16_t map_es_pid(output_t * p_output, uint8_t *p_es, uint16_t i_pid)
170 uint16_t i_newpid = i_pid;
171 uint16_t i_stream_type = pmtn_get_streamtype(p_es);
173 if ( !b_do_remap && !p_output->config.b_do_remap )
174 return i_pid;
176 msg_Dbg(NULL, "REMAP: Found elementary stream type 0x%02x with original PID 0x%x (%u):", i_stream_type, i_pid, i_pid);
178 switch ( i_stream_type )
180 case 0x03: /* audio MPEG-1 */
181 case 0x04: /* audio MPEG-2 */
182 case 0x0f: /* audio AAC ADTS */
183 case 0x11: /* audio AAC LATM */
184 case 0x81: /* ATSC AC-3 */
185 case 0x87: /* ATSC Enhanced AC-3 */
186 if ( b_do_remap )
187 i_newpid = pi_newpids[I_APID];
188 else
189 i_newpid = p_output->config.pi_confpids[I_APID];
190 break;
191 case 0x01: /* video MPEG-1 */
192 case 0x02: /* video MPEG-2 */
193 case 0x10: /* video MPEG-4 */
194 case 0x1b: /* video H264 */
195 case 0x24: /* video H265 */
196 case 0x42: /* video AVS */
197 if ( b_do_remap )
198 i_newpid = pi_newpids[I_VPID];
199 else
200 i_newpid = p_output->config.pi_confpids[I_VPID];
201 break;
202 case 0x06: { /* PES Private Data - We must check the descriptors */
203 /* By default, nothing identified */
204 uint8_t SubStreamType = N_MAP_PIDS;
205 uint16_t j = 0;
206 const uint8_t *p_desc;
207 /* Loop over the descriptors */
208 while ( (p_desc = descs_get_desc( pmtn_get_descs( p_es ), j )) != NULL )
210 /* Get the descriptor tag */
211 uint8_t i_tag = desc_get_tag( p_desc );
212 j++;
213 /* Check if the tag is: A/52, Enhanced A/52, DTS, AAC */
214 if (i_tag == 0x6a || i_tag == 0x7a || i_tag == 0x7b || i_tag == 0x7c)
215 SubStreamType=I_APID;
216 /* Check if the tag is: VBI + teletext, teletext, dvbsub */
217 if (i_tag == 0x46 || i_tag == 0x56 || i_tag == 0x59)
218 SubStreamType=I_SPUPID;
220 /* Audio found */
221 if (SubStreamType==I_APID) {
222 msg_Dbg(NULL, "REMAP: PES Private Data stream identified as [Audio]");
223 if ( b_do_remap )
224 i_newpid = pi_newpids[I_APID];
225 else
226 i_newpid = p_output->config.pi_confpids[I_APID];
228 /* Subtitle found */
229 if (SubStreamType==I_SPUPID) {
230 msg_Dbg(NULL, "REMAP: PES Private Data stream identified as [Subtitle]");
231 if ( b_do_remap )
232 i_newpid = pi_newpids[I_SPUPID];
233 else
234 i_newpid = p_output->config.pi_confpids[I_SPUPID];
236 break;
240 if (!i_newpid)
241 return i_pid;
243 /* Got the new base for the mapped pid. Find the next free one
244 we do this to ensure that multiple audios get unique pids */
245 while (p_output->pi_freepids[i_newpid] != UNUSED_PID)
246 i_newpid++;
247 p_output->pi_freepids[i_newpid] = i_pid; /* Mark as in use */
248 p_output->pi_newpids[i_pid] = i_newpid; /* Save the new pid */
250 msg_Dbg(NULL, "REMAP: => Elementary stream is remapped to PID 0x%x (%u)", i_newpid, i_newpid);
252 return i_newpid;
255 /*****************************************************************************
256 * FindSID
257 *****************************************************************************/
258 static inline sid_t *FindSID( uint16_t i_sid )
260 int i;
262 for ( i = 0; i < i_nb_sids; i++ )
264 sid_t *p_sid = pp_sids[i];
265 if ( p_sid->i_sid == i_sid )
266 return p_sid;
268 return NULL;
271 /*****************************************************************************
272 * Print info
273 *****************************************************************************/
274 static void PrintCb( struct ev_loop *loop, struct ev_timer *w, int revents )
276 int i;
277 uint64_t i_bitrate = i_nb_packets * TS_SIZE * 8 * 1000000 / i_print_period;
278 switch (i_print_type)
280 case PRINT_XML:
281 fprintf(print_fh,
282 "<STATUS type=\"bitrate\" status=\"%d\" value=\"%"PRIu64"\">",
283 i_bitrate ? 1 : 0, i_bitrate);
284 break;
285 case PRINT_TEXT:
286 fprintf(print_fh, "bitrate: %"PRIu64"\n", i_bitrate);
287 break;
288 default:
289 break;
291 i_nb_packets = 0;
293 for ( i = 0; i < i_nb_sids; i++ )
295 sid_t *p_sid = pp_sids[i];
296 uint64_t i_bitrate = p_sid->i_packets_passed * TS_SIZE * 8 * 1000000 / i_print_period;
297 switch (i_print_type)
299 case PRINT_XML:
300 fprintf(print_fh,
301 "<PROGRAM number=\"%u\" bitrate=\"%"PRIu64"\"/>",
302 p_sid->i_sid, i_bitrate);
303 break;
304 case PRINT_TEXT:
305 fprintf(print_fh, " - program number %u bitrate: %"PRIu64"\n",
306 p_sid->i_sid, i_bitrate);
307 break;
308 default:
309 break;
311 p_sid->i_packets_passed = 0;
314 switch (i_print_type)
316 case PRINT_XML:
317 fprintf(print_fh, "</STATUS>\n");
318 break;
319 default:
320 break;
323 if ( i_nb_invalids )
325 switch (i_print_type)
327 case PRINT_XML:
328 fprintf(print_fh,
329 "<ERROR type=\"invalid_ts\" number=\"%"PRIu64"\" />\n",
330 i_nb_invalids);
331 break;
332 case PRINT_TEXT:
333 fprintf(print_fh, "invalids: %"PRIu64"\n", i_nb_invalids);
334 break;
335 default:
336 break;
338 i_nb_invalids = 0;
341 if ( i_nb_discontinuities )
343 switch (i_print_type)
345 case PRINT_XML:
346 fprintf(print_fh,
347 "<ERROR type=\"invalid_discontinuity\" number=\"%"PRIu64"\" />\n",
348 i_nb_discontinuities);
349 break;
350 case PRINT_TEXT:
351 fprintf(print_fh, "discontinuities: %"PRIu64"\n",
352 i_nb_discontinuities);
353 break;
354 default:
355 break;
357 i_nb_discontinuities = 0;
360 if ( i_nb_errors )
362 switch (i_print_type)
364 case PRINT_XML:
365 fprintf(print_fh,
366 "<ERROR type=\"transport_error\" number=\"%"PRIu64"\" />\n",
367 i_nb_errors);
368 break;
369 case PRINT_TEXT:
370 fprintf(print_fh, "errors: %"PRIu64"\n", i_nb_errors);
371 break;
372 default:
373 break;
375 i_nb_errors = 0;
379 static void PrintESCb( struct ev_loop *loop, struct ev_timer *w, int revents )
381 ts_pid_t *p_pid = container_of( w, ts_pid_t, timeout_watcher );
382 uint16_t i_pid = p_pid - p_pids;
384 switch (i_print_type)
386 case PRINT_XML:
387 fprintf(print_fh,
388 "<STATUS type=\"pid\" pid=\"%"PRIu16"\" status=\"0\" />\n",
389 i_pid);
390 break;
391 case PRINT_TEXT:
392 fprintf(print_fh, "pid: %"PRIu16" down\n", i_pid);
393 break;
394 default:
395 break;
398 ev_timer_stop( loop, w );
399 p_pid->i_pes_status = -1;
402 static void PrintES( uint16_t i_pid )
404 const ts_pid_t *p_pid = &p_pids[i_pid];
406 switch (i_print_type)
408 case PRINT_XML:
409 fprintf(print_fh,
410 "<STATUS type=\"pid\" pid=\"%"PRIu16"\" status=\"1\" pes=\"%d\" />\n",
411 i_pid, p_pid->i_pes_status == 1 ? 1 : 0);
412 break;
413 case PRINT_TEXT:
414 fprintf(print_fh, "pid: %"PRIu16" up%s\n",
415 i_pid, p_pid->i_pes_status == 1 ? " pes" : "");
416 break;
417 default:
418 break;
422 /*****************************************************************************
423 * demux_Open
424 *****************************************************************************/
425 void demux_Open( void )
427 int i;
429 memset( p_pids, 0, sizeof(p_pids) );
431 pf_Open();
433 for ( i = 0; i < MAX_PIDS; i++ )
435 p_pids[i].i_last_cc = -1;
436 p_pids[i].i_demux_fd = -1;
437 psi_assemble_init( &p_pids[i].p_psi_buffer,
438 &p_pids[i].i_psi_buffer_used );
439 p_pids[i].i_pes_status = -1;
442 if ( b_budget_mode )
443 i_demux_fd = pf_SetFilter(8192);
445 psi_table_init( pp_current_pat_sections );
446 psi_table_init( pp_next_pat_sections );
447 SetPID(PAT_PID);
448 p_pids[PAT_PID].i_psi_refcount++;
450 if ( b_enable_emm )
452 psi_table_init( pp_current_cat_sections );
453 psi_table_init( pp_next_cat_sections );
454 SetPID_EMM(CAT_PID);
455 p_pids[CAT_PID].i_psi_refcount++;
458 SetPID(NIT_PID);
459 p_pids[NIT_PID].i_psi_refcount++;
461 psi_table_init( pp_current_sdt_sections );
462 psi_table_init( pp_next_sdt_sections );
463 SetPID(SDT_PID);
464 p_pids[SDT_PID].i_psi_refcount++;
466 SetPID(EIT_PID);
467 p_pids[EIT_PID].i_psi_refcount++;
469 SetPID(RST_PID);
471 SetPID(TDT_PID);
473 if ( i_print_period )
475 ev_timer_init( &print_watcher, PrintCb,
476 i_print_period / 1000000., i_print_period / 1000000. );
477 ev_timer_start( event_loop, &print_watcher );
481 /*****************************************************************************
482 * demux_Close
483 *****************************************************************************/
484 void demux_Close( void )
486 int i, r;
488 psi_table_free( pp_current_pat_sections );
489 psi_table_free( pp_next_pat_sections );
490 psi_table_free( pp_current_cat_sections );
491 psi_table_free( pp_next_cat_sections );
492 psi_table_free( pp_current_nit_sections );
493 psi_table_free( pp_next_nit_sections );
494 psi_table_free( pp_current_sdt_sections );
495 psi_table_free( pp_next_sdt_sections );
497 for ( i = 0; i < MAX_PIDS; i++ )
499 ev_timer_stop( event_loop, &p_pids[i].timeout_watcher );
500 free( p_pids[i].p_psi_buffer );
501 free( p_pids[i].pp_outputs );
504 for ( i = 0; i < i_nb_sids; i++ )
506 sid_t *p_sid = pp_sids[i];
507 for ( r = 0; r < MAX_EIT_TABLES; r++ ) {
508 psi_table_free( p_sid->eit_table[r].data );
510 free( p_sid->p_current_pmt );
511 free( p_sid );
513 free( pp_sids );
515 #ifdef HAVE_ICONV
516 if (iconv_handle != (iconv_t)-1) {
517 iconv_close(iconv_handle);
518 iconv_handle = (iconv_t)-1;
520 #endif
522 if ( i_print_period )
523 ev_timer_stop( event_loop, &print_watcher );
526 /*****************************************************************************
527 * demux_Run
528 *****************************************************************************/
529 void demux_Run( block_t *p_ts )
531 i_wallclock = mdate();
532 mrtgAnalyse( p_ts );
533 SetDTS( p_ts );
535 while ( p_ts != NULL )
537 block_t *p_next = p_ts->p_next;
538 p_ts->p_next = NULL;
539 demux_Handle( p_ts );
540 p_ts = p_next;
544 /*****************************************************************************
545 * demux_Handle
546 *****************************************************************************/
547 static void demux_Handle( block_t *p_ts )
549 uint16_t i_pid = ts_get_pid( p_ts->p_ts );
550 ts_pid_t *p_pid = &p_pids[i_pid];
551 uint8_t i_cc = ts_get_cc( p_ts->p_ts );
552 int i;
554 i_nb_packets++;
556 if ( !ts_validate( p_ts->p_ts ) )
558 msg_Warn( NULL, "lost TS sync" );
559 block_Delete( p_ts );
560 i_nb_invalids++;
561 return;
564 if ( i_pid != PADDING_PID )
565 p_pid->info.i_scrambling = ts_get_scrambling( p_ts->p_ts );
567 p_pid->info.i_last_packet_ts = i_wallclock;
568 p_pid->info.i_packets++;
570 p_pid->i_packets_passed++;
572 /* Calculate bytes_per_sec */
573 if ( i_wallclock > p_pid->i_bytes_ts + 1000000 ) {
574 p_pid->info.i_bytes_per_sec = p_pid->i_packets_passed * TS_SIZE;
575 p_pid->i_packets_passed = 0;
576 p_pid->i_bytes_ts = i_wallclock;
579 if ( p_pid->info.i_first_packet_ts == 0 )
580 p_pid->info.i_first_packet_ts = i_wallclock;
582 if ( i_print_period && p_pid->i_sid > 0 )
584 sid_t *p_sid = FindSID( p_pid->i_sid );
585 if ( p_sid != NULL )
586 p_sid->i_packets_passed++;
589 if ( i_pid != PADDING_PID && p_pid->i_last_cc != -1
590 && !ts_check_duplicate( i_cc, p_pid->i_last_cc )
591 && ts_check_discontinuity( i_cc, p_pid->i_last_cc ) )
593 unsigned int expected_cc = (p_pid->i_last_cc + 1) & 0x0f;
594 uint16_t i_sid = 0;
595 const char *pid_desc = get_pid_desc(i_pid, &i_sid);
597 p_pid->info.i_cc_errors++;
598 i_nb_discontinuities++;
600 msg_Warn( NULL, "TS discontinuity on pid %4hu expected_cc %2u got %2u (%s, sid %d)",
601 i_pid, expected_cc, i_cc, pid_desc, i_sid );
604 if ( ts_get_transporterror( p_ts->p_ts ) )
606 uint16_t i_sid = 0;
607 const char *pid_desc = get_pid_desc(i_pid, &i_sid);
609 p_pid->info.i_transport_errors++;
611 msg_Warn( NULL, "transport_error_indicator on pid %hu (%s, sid %u)",
612 i_pid, pid_desc, i_sid );
614 i_nb_errors++;
615 i_tuner_errors++;
616 i_last_error = i_wallclock;
618 else if ( i_wallclock > i_last_error + WATCHDOG_WAIT )
619 i_tuner_errors = 0;
621 if ( i_tuner_errors > MAX_ERRORS )
623 i_tuner_errors = 0;
624 msg_Warn( NULL,
625 "too many transport errors, tuning again" );
626 switch (i_print_type) {
627 case PRINT_XML:
628 fprintf(print_fh, "<EVENT type=\"reset\" cause=\"transport\" />\n");
629 break;
630 case PRINT_TEXT:
631 fprintf(print_fh, "reset cause: transport\n");
632 break;
633 default:
634 break;
636 pf_Reset();
639 if ( i_es_timeout )
641 int i_pes_status = -1;
642 if ( ts_get_scrambling( p_ts->p_ts ) )
643 i_pes_status = 0;
644 else if ( ts_get_unitstart( p_ts->p_ts ) )
646 uint8_t *p_payload = ts_payload( p_ts->p_ts );
647 if ( p_payload + 3 < p_ts->p_ts + TS_SIZE )
648 i_pes_status = pes_validate( p_payload ) ? 1 : 0;
651 if ( i_pes_status != -1 )
653 if ( p_pid->i_pes_status == -1 )
655 p_pid->i_pes_status = i_pes_status;
656 PrintES( i_pid );
658 if ( i_pid != TDT_PID )
660 ev_timer_init( &p_pid->timeout_watcher, PrintESCb,
661 i_es_timeout / 1000000.,
662 i_es_timeout / 1000000. );
663 ev_timer_start( event_loop, &p_pid->timeout_watcher );
665 else
667 ev_timer_init( &p_pid->timeout_watcher, PrintESCb, 30, 30 );
668 ev_timer_start( event_loop, &p_pid->timeout_watcher );
671 else
673 if ( p_pid->i_pes_status != i_pes_status )
675 p_pid->i_pes_status = i_pes_status;
676 PrintES( i_pid );
679 ev_timer_again( event_loop, &p_pid->timeout_watcher );
684 if ( !ts_get_transporterror( p_ts->p_ts ) )
686 /* PSI parsing */
687 if ( i_pid == TDT_PID || i_pid == RST_PID )
688 SendTDT( p_ts );
689 else if ( p_pid->i_psi_refcount )
690 HandlePSIPacket( p_ts->p_ts, p_ts->i_dts );
692 if ( b_enable_emm && p_pid->b_emm )
693 SendEMM( p_ts );
696 p_pid->i_last_cc = i_cc;
698 /* Output */
699 for ( i = 0; i < p_pid->i_nb_outputs; i++ )
701 output_t *p_output = p_pid->pp_outputs[i];
702 if ( p_output != NULL )
704 if ( i_ca_handle && (p_output->config.i_config & OUTPUT_WATCH) &&
705 ts_get_unitstart( p_ts->p_ts ) )
707 uint8_t *p_payload;
709 if ( ts_get_scrambling( p_ts->p_ts ) ||
710 ( p_pid->b_pes
711 && (p_payload = ts_payload( p_ts->p_ts )) + 3
712 < p_ts->p_ts + TS_SIZE
713 && !pes_validate(p_payload) ) )
715 if ( i_wallclock >
716 i_last_reset + WATCHDOG_REFRACTORY_PERIOD )
718 p_output->i_nb_errors++;
719 p_output->i_last_error = i_wallclock;
722 else if ( i_wallclock > p_output->i_last_error + WATCHDOG_WAIT )
723 p_output->i_nb_errors = 0;
725 if ( p_output->i_nb_errors > MAX_ERRORS )
727 int j;
728 for ( j = 0; j < i_nb_outputs; j++ )
729 pp_outputs[j]->i_nb_errors = 0;
731 msg_Warn( NULL,
732 "too many errors for stream %s, resetting",
733 p_output->config.psz_displayname );
735 switch (i_print_type) {
736 case PRINT_XML:
737 fprintf(print_fh, "<EVENT type=\"reset\" cause=\"scrambling\" />\n");
738 break;
739 case PRINT_TEXT:
740 fprintf(print_fh, "reset cause: scrambling");
741 break;
742 default:
743 break;
745 i_last_reset = i_wallclock;
746 en50221_Reset();
750 if ( p_output->i_pcr_pid != i_pid
751 || (ts_has_adaptation(p_ts->p_ts)
752 && ts_get_adaptation(p_ts->p_ts)
753 && tsaf_has_pcr(p_ts->p_ts)) )
754 output_Put( p_output, p_ts );
756 if ( p_output->p_eit_ts_buffer != NULL
757 && p_ts->i_dts > p_output->p_eit_ts_buffer->i_dts
758 + MAX_EIT_RETENTION )
759 FlushEIT( p_output, p_ts->i_dts );
763 for ( i = 0; i < i_nb_outputs; i++ )
765 output_t *p_output = pp_outputs[i];
767 if ( !(p_output->config.i_config & OUTPUT_VALID) ||
768 !p_output->config.b_passthrough )
769 continue;
771 output_Put( p_output, p_ts );
774 if ( output_dup.config.i_config & OUTPUT_VALID )
775 output_Put( &output_dup, p_ts );
777 if ( b_passthrough )
778 fwrite(p_ts->p_ts, TS_SIZE, 1, stdout);
780 p_ts->i_refcount--;
781 if ( !p_ts->i_refcount )
782 block_Delete( p_ts );
785 /*****************************************************************************
786 * demux_Change : called from main thread
787 *****************************************************************************/
788 static bool IsIn( const uint16_t *pi_pids, int i_nb_pids, uint16_t i_pid )
790 int i;
791 for ( i = 0; i < i_nb_pids; i++ )
792 if ( i_pid == pi_pids[i] ) break;
793 return ( i != i_nb_pids );
796 void demux_Change( output_t *p_output, const output_config_t *p_config )
798 uint16_t *pi_wanted_pids, *pi_current_pids;
799 int i_nb_wanted_pids, i_nb_current_pids;
800 uint16_t i_wanted_pcr_pid, i_current_pcr_pid;
802 uint16_t i_old_sid = p_output->config.i_sid;
803 uint16_t i_sid = p_config->i_sid;
804 uint16_t *pi_old_pids = p_output->config.pi_pids;
805 uint16_t *pi_pids = p_config->pi_pids;
806 int i_old_nb_pids = p_output->config.i_nb_pids;
807 int i_nb_pids = p_config->i_nb_pids;
809 bool b_sid_change = i_sid != i_old_sid;
810 bool b_pid_change = false, b_tsid_change = false;
811 bool b_dvb_change = !!((p_output->config.i_config ^ p_config->i_config)
812 & OUTPUT_DVB);
813 bool b_epg_change = !!((p_output->config.i_config ^ p_config->i_config)
814 & OUTPUT_EPG);
815 bool b_network_change =
816 (dvb_string_cmp(&p_output->config.network_name, &p_config->network_name) ||
817 p_output->config.i_network_id != p_config->i_network_id);
818 bool b_service_name_change =
819 (dvb_string_cmp(&p_output->config.service_name, &p_config->service_name) ||
820 dvb_string_cmp(&p_output->config.provider_name, &p_config->provider_name));
821 bool b_remap_change = p_output->config.i_new_sid != p_config->i_new_sid ||
822 p_output->config.i_onid != p_config->i_onid ||
823 p_output->config.b_do_remap != p_config->b_do_remap ||
824 p_output->config.pi_confpids[I_PMTPID] != p_config->pi_confpids[I_PMTPID] ||
825 p_output->config.pi_confpids[I_APID] != p_config->pi_confpids[I_APID] ||
826 p_output->config.pi_confpids[I_VPID] != p_config->pi_confpids[I_VPID] ||
827 p_output->config.pi_confpids[I_SPUPID] != p_config->pi_confpids[I_SPUPID];
828 int i;
830 p_output->config.i_config = p_config->i_config;
831 p_output->config.i_network_id = p_config->i_network_id;
832 p_output->config.i_new_sid = p_config->i_new_sid;
833 p_output->config.i_onid = p_config->i_onid;
834 p_output->config.b_do_remap = p_config->b_do_remap;
835 memcpy(p_output->config.pi_confpids, p_config->pi_confpids,
836 sizeof(uint16_t) * N_MAP_PIDS);
838 /* Change output settings related to names. */
839 dvb_string_clean( &p_output->config.network_name );
840 dvb_string_clean( &p_output->config.service_name );
841 dvb_string_clean( &p_output->config.provider_name );
842 dvb_string_copy( &p_output->config.network_name,
843 &p_config->network_name );
844 dvb_string_copy( &p_output->config.service_name,
845 &p_config->service_name );
846 dvb_string_copy( &p_output->config.provider_name,
847 &p_config->provider_name );
849 if ( p_config->i_tsid != -1 && p_output->config.i_tsid != p_config->i_tsid )
851 p_output->i_tsid = p_output->config.i_tsid = p_config->i_tsid;
852 b_tsid_change = true;
854 if ( p_config->i_tsid == -1 && p_output->config.i_tsid != -1 )
856 p_output->config.i_tsid = p_config->i_tsid;
857 if ( psi_table_validate(pp_current_pat_sections) && !b_random_tsid )
858 p_output->i_tsid =
859 psi_table_get_tableidext(pp_current_pat_sections);
860 else
861 p_output->i_tsid = rand() & 0xffff;
862 b_tsid_change = true;
865 if ( p_config->b_passthrough == p_output->config.b_passthrough &&
866 !b_sid_change && p_config->i_nb_pids == p_output->config.i_nb_pids &&
867 (!p_config->i_nb_pids ||
868 !memcmp( p_output->config.pi_pids, p_config->pi_pids,
869 p_config->i_nb_pids * sizeof(uint16_t) )) )
870 goto out_change;
872 GetPIDS( &pi_wanted_pids, &i_nb_wanted_pids, &i_wanted_pcr_pid,
873 i_sid, pi_pids, i_nb_pids );
874 GetPIDS( &pi_current_pids, &i_nb_current_pids, &i_current_pcr_pid,
875 i_old_sid, pi_old_pids, i_old_nb_pids );
877 if ( b_sid_change && i_old_sid )
879 sid_t *p_old_sid = FindSID( i_old_sid );
880 p_output->config.i_sid = p_config->i_sid;
882 if ( p_old_sid != NULL )
884 if ( i_sid != i_old_sid )
885 UnselectPMT( i_old_sid, p_old_sid->i_pmt_pid );
887 if ( i_ca_handle && !SIDIsSelected( i_old_sid )
888 && p_old_sid->p_current_pmt != NULL
889 && PMTNeedsDescrambling( p_old_sid->p_current_pmt ) )
890 en50221_DeletePMT( p_old_sid->p_current_pmt );
894 for ( i = 0; i < i_nb_current_pids; i++ )
896 if ( !IsIn( pi_wanted_pids, i_nb_wanted_pids, pi_current_pids[i] ) )
898 StopPID( p_output, pi_current_pids[i] );
899 b_pid_change = true;
903 if ( b_sid_change && i_ca_handle && i_old_sid &&
904 SIDIsSelected( i_old_sid ) )
906 sid_t *p_old_sid = FindSID( i_old_sid );
907 if ( p_old_sid != NULL && p_old_sid->p_current_pmt != NULL
908 && PMTNeedsDescrambling( p_old_sid->p_current_pmt ) )
909 en50221_UpdatePMT( p_old_sid->p_current_pmt );
912 for ( i = 0; i < i_nb_wanted_pids; i++ )
914 if ( !IsIn( pi_current_pids, i_nb_current_pids, pi_wanted_pids[i] ) )
916 StartPID( p_output, pi_wanted_pids[i] );
917 b_pid_change = true;
921 free( pi_wanted_pids );
922 free( pi_current_pids );
923 p_output->i_pcr_pid = i_wanted_pcr_pid;
925 if ( b_sid_change && i_sid )
927 sid_t *p_sid = FindSID( i_sid );
928 p_output->config.i_sid = i_old_sid;
930 if ( p_sid != NULL )
932 if ( i_sid != i_old_sid )
933 SelectPMT( i_sid, p_sid->i_pmt_pid );
935 if ( i_ca_handle && !SIDIsSelected( i_sid )
936 && p_sid->p_current_pmt != NULL
937 && PMTNeedsDescrambling( p_sid->p_current_pmt ) )
938 en50221_AddPMT( p_sid->p_current_pmt );
942 if ( i_ca_handle && i_sid && SIDIsSelected( i_sid ) )
944 sid_t *p_sid = FindSID( i_sid );
945 if ( p_sid != NULL && p_sid->p_current_pmt != NULL
946 && PMTNeedsDescrambling( p_sid->p_current_pmt ) )
947 en50221_UpdatePMT( p_sid->p_current_pmt );
950 p_output->config.b_passthrough = p_config->b_passthrough;
951 p_output->config.i_sid = i_sid;
952 free( p_output->config.pi_pids );
953 p_output->config.pi_pids = malloc( sizeof(uint16_t) * i_nb_pids );
954 memcpy( p_output->config.pi_pids, pi_pids, sizeof(uint16_t) * i_nb_pids );
955 p_output->config.i_nb_pids = i_nb_pids;
957 out_change:
958 if ( b_sid_change || b_pid_change || b_tsid_change || b_dvb_change ||
959 b_network_change || b_service_name_change || b_remap_change )
961 msg_Dbg( NULL, "change %s%s%s%s%s%s%s",
962 b_sid_change ? "sid " : "",
963 b_pid_change ? "pid " : "",
964 b_tsid_change ? "tsid " : "",
965 b_dvb_change ? "dvb " : "",
966 b_network_change ? "network " : "",
967 b_service_name_change ? "service_name " : "",
968 b_remap_change ? "remap " : "" );
971 if ( b_sid_change || b_remap_change )
973 NewSDT( p_output );
974 NewNIT( p_output );
975 NewPAT( p_output );
976 NewPMT( p_output );
978 else
980 if ( b_tsid_change )
982 NewSDT( p_output );
983 NewNIT( p_output );
984 NewPAT( p_output );
986 else if ( b_dvb_change )
988 NewNIT( p_output );
989 NewPAT( p_output );
991 else if ( b_network_change )
992 NewNIT( p_output );
994 if ( !b_tsid_change && (b_service_name_change || b_epg_change) )
995 NewSDT( p_output );
997 if ( b_pid_change )
998 NewPMT( p_output );
1002 /*****************************************************************************
1003 * SetDTS
1004 *****************************************************************************/
1005 static void SetDTS( block_t *p_list )
1007 int i_nb_ts = 0, i;
1008 mtime_t i_duration;
1009 block_t *p_ts = p_list;
1011 while ( p_ts != NULL )
1013 i_nb_ts++;
1014 p_ts = p_ts->p_next;
1017 /* We suppose the stream is CBR, at least between two consecutive read().
1018 * This is especially true in budget mode */
1019 if ( i_last_dts == -1 )
1020 i_duration = 0;
1021 else
1022 i_duration = i_wallclock - i_last_dts;
1024 p_ts = p_list;
1025 i = i_nb_ts - 1;
1026 while ( p_ts != NULL )
1028 p_ts->i_dts = i_wallclock - i_duration * i / i_nb_ts;
1029 i--;
1030 p_ts = p_ts->p_next;
1033 i_last_dts = i_wallclock;
1036 /*****************************************************************************
1037 * SetPID/UnsetPID
1038 *****************************************************************************/
1039 static void SetPID( uint16_t i_pid )
1041 p_pids[i_pid].i_refcount++;
1043 if ( !b_budget_mode && p_pids[i_pid].i_refcount
1044 && p_pids[i_pid].i_demux_fd == -1 )
1045 p_pids[i_pid].i_demux_fd = pf_SetFilter( i_pid );
1048 static void SetPID_EMM( uint16_t i_pid )
1050 SetPID( i_pid );
1051 p_pids[i_pid].b_emm = true;
1054 static void UnsetPID( uint16_t i_pid )
1056 p_pids[i_pid].i_refcount--;
1058 if ( !b_budget_mode && !p_pids[i_pid].i_refcount
1059 && p_pids[i_pid].i_demux_fd != -1 )
1061 pf_UnsetFilter( p_pids[i_pid].i_demux_fd, i_pid );
1062 p_pids[i_pid].i_demux_fd = -1;
1063 p_pids[i_pid].b_emm = false;
1067 /*****************************************************************************
1068 * StartPID/StopPID
1069 *****************************************************************************/
1070 static void StartPID( output_t *p_output, uint16_t i_pid )
1072 int j;
1074 for ( j = 0; j < p_pids[i_pid].i_nb_outputs; j++ )
1075 if ( p_pids[i_pid].pp_outputs[j] == p_output )
1076 break;
1078 if ( j == p_pids[i_pid].i_nb_outputs )
1080 for ( j = 0; j < p_pids[i_pid].i_nb_outputs; j++ )
1081 if ( p_pids[i_pid].pp_outputs[j] == NULL )
1082 break;
1084 if ( j == p_pids[i_pid].i_nb_outputs )
1086 p_pids[i_pid].i_nb_outputs++;
1087 p_pids[i_pid].pp_outputs = realloc( p_pids[i_pid].pp_outputs,
1088 sizeof(output_t *)
1089 * p_pids[i_pid].i_nb_outputs );
1092 p_pids[i_pid].pp_outputs[j] = p_output;
1093 SetPID( i_pid );
1097 static void StopPID( output_t *p_output, uint16_t i_pid )
1099 int j;
1101 for ( j = 0; j < p_pids[i_pid].i_nb_outputs; j++ )
1103 if ( p_pids[i_pid].pp_outputs[j] != NULL )
1105 if ( p_pids[i_pid].pp_outputs[j] == p_output )
1106 break;
1110 if ( j != p_pids[i_pid].i_nb_outputs )
1112 p_pids[i_pid].pp_outputs[j] = NULL;
1113 UnsetPID( i_pid );
1117 /*****************************************************************************
1118 * SelectPID/UnselectPID
1119 *****************************************************************************/
1120 static void SelectPID( uint16_t i_sid, uint16_t i_pid, bool b_pcr )
1122 int i;
1124 p_pids[i_pid].i_sid = i_sid;
1126 for ( i = 0; i < i_nb_outputs; i++ )
1128 if ( (pp_outputs[i]->config.i_config & OUTPUT_VALID)
1129 && pp_outputs[i]->config.i_sid == i_sid )
1131 if ( pp_outputs[i]->config.i_nb_pids &&
1132 !IsIn( pp_outputs[i]->config.pi_pids,
1133 pp_outputs[i]->config.i_nb_pids, i_pid ) )
1135 if ( b_pcr )
1136 pp_outputs[i]->i_pcr_pid = i_pid;
1137 else
1138 continue;
1140 StartPID( pp_outputs[i], i_pid );
1145 static void UnselectPID( uint16_t i_sid, uint16_t i_pid )
1147 int i;
1149 p_pids[i_pid].i_sid = 0;
1151 for ( i = 0; i < i_nb_outputs; i++ )
1152 if ( (pp_outputs[i]->config.i_config & OUTPUT_VALID)
1153 && pp_outputs[i]->config.i_sid == i_sid
1154 && !pp_outputs[i]->config.i_nb_pids )
1155 StopPID( pp_outputs[i], i_pid );
1158 /*****************************************************************************
1159 * SelectPMT/UnselectPMT
1160 *****************************************************************************/
1161 static void SelectPMT( uint16_t i_sid, uint16_t i_pid )
1163 int i;
1165 p_pids[i_pid].i_psi_refcount++;
1166 p_pids[i_pid].b_pes = false;
1167 p_pids[i_pid].i_sid = i_sid;
1169 if ( b_select_pmts )
1170 SetPID( i_pid );
1171 else for ( i = 0; i < i_nb_outputs; i++ )
1172 if ( (pp_outputs[i]->config.i_config & OUTPUT_VALID)
1173 && pp_outputs[i]->config.i_sid == i_sid )
1174 SetPID( i_pid );
1177 static void UnselectPMT( uint16_t i_sid, uint16_t i_pid )
1179 int i;
1181 p_pids[i_pid].i_sid = 0;
1183 p_pids[i_pid].i_psi_refcount--;
1184 if ( !p_pids[i_pid].i_psi_refcount )
1185 psi_assemble_reset( &p_pids[i_pid].p_psi_buffer,
1186 &p_pids[i_pid].i_psi_buffer_used );
1188 if ( b_select_pmts )
1189 UnsetPID( i_pid );
1190 else for ( i = 0; i < i_nb_outputs; i++ )
1191 if ( (pp_outputs[i]->config.i_config & OUTPUT_VALID)
1192 && pp_outputs[i]->config.i_sid == i_sid )
1193 UnsetPID( i_pid );
1196 /*****************************************************************************
1197 * GetPIDS
1198 *****************************************************************************/
1199 static void GetPIDS( uint16_t **ppi_wanted_pids, int *pi_nb_wanted_pids,
1200 uint16_t *pi_wanted_pcr_pid, uint16_t i_sid,
1201 const uint16_t *pi_pids, int i_nb_pids )
1203 sid_t *p_sid;
1204 uint8_t *p_pmt;
1205 uint16_t i_pmt_pid, i_pcr_pid;
1206 uint8_t *p_es;
1207 uint8_t j;
1208 const uint8_t *p_desc;
1210 *pi_wanted_pcr_pid = 0;
1212 if ( i_nb_pids || i_sid == 0 )
1214 *pi_nb_wanted_pids = i_nb_pids;
1215 *ppi_wanted_pids = malloc( sizeof(uint16_t) * i_nb_pids );
1216 memcpy( *ppi_wanted_pids, pi_pids, sizeof(uint16_t) * i_nb_pids );
1217 if ( i_sid == 0 )
1218 return;
1220 else
1222 *pi_nb_wanted_pids = 0;
1223 *ppi_wanted_pids = NULL;
1226 p_sid = FindSID( i_sid );
1227 if ( p_sid == NULL )
1228 return;
1230 p_pmt = p_sid->p_current_pmt;
1231 i_pmt_pid = p_sid->i_pmt_pid;
1232 if ( p_pmt == NULL ) {
1233 msg_Dbg(NULL, "no current PMT on sid %d\n", i_sid);
1234 return;
1237 i_pcr_pid = pmt_get_pcrpid( p_pmt );
1238 j = 0;
1239 while ( (p_es = pmt_get_es( p_pmt, j )) != NULL )
1241 j++;
1243 uint16_t i_pid = pmtn_get_pid( p_es );
1244 bool b_select;
1245 if ( i_nb_pids )
1246 b_select = IsIn( pi_pids, i_nb_pids, i_pid );
1247 else
1249 b_select = PIDWouldBeSelected( p_es );
1250 if ( b_select )
1252 *ppi_wanted_pids = realloc( *ppi_wanted_pids,
1253 (*pi_nb_wanted_pids + 1) * sizeof(uint16_t) );
1254 (*ppi_wanted_pids)[(*pi_nb_wanted_pids)++] = i_pid;
1258 if ( b_select && b_enable_ecm )
1260 uint8_t k = 0;
1262 while ((p_desc = descs_get_desc( pmtn_get_descs( p_es ), k++ )) != NULL)
1264 if ( desc_get_tag( p_desc ) != 0x09 || !desc09_validate( p_desc ) )
1265 continue;
1266 *ppi_wanted_pids = realloc( *ppi_wanted_pids,
1267 (*pi_nb_wanted_pids + 1) * sizeof(uint16_t) );
1268 (*ppi_wanted_pids)[(*pi_nb_wanted_pids)++] = desc09_get_pid( p_desc );
1274 if ( b_enable_ecm )
1276 j = 0;
1278 while ((p_desc = descs_get_desc( pmt_get_descs( p_pmt ), j++ )) != NULL)
1280 if ( desc_get_tag( p_desc ) != 0x09 ||
1281 !desc09_validate( p_desc ) )
1282 continue;
1283 *ppi_wanted_pids = realloc( *ppi_wanted_pids,
1284 (*pi_nb_wanted_pids + 1) * sizeof(uint16_t) );
1285 (*ppi_wanted_pids)[(*pi_nb_wanted_pids)++] = desc09_get_pid( p_desc );
1289 if ( i_pcr_pid != PADDING_PID && i_pcr_pid != i_pmt_pid
1290 && !IsIn( *ppi_wanted_pids, *pi_nb_wanted_pids, i_pcr_pid ) )
1292 *ppi_wanted_pids = realloc( *ppi_wanted_pids,
1293 (*pi_nb_wanted_pids + 1) * sizeof(uint16_t) );
1294 (*ppi_wanted_pids)[(*pi_nb_wanted_pids)++] = i_pcr_pid;
1295 /* We only need the PCR packets of this stream (incomplete) */
1296 *pi_wanted_pcr_pid = i_pcr_pid;
1297 msg_Dbg( NULL, "Requesting partial PCR PID %"PRIu16, i_pcr_pid );
1301 /*****************************************************************************
1302 * OutputPSISection
1303 *****************************************************************************/
1304 static void OutputPSISection( output_t *p_output, uint8_t *p_section,
1305 uint16_t i_pid, uint8_t *pi_cc, mtime_t i_dts,
1306 block_t **pp_ts_buffer,
1307 uint8_t *pi_ts_buffer_offset )
1309 uint16_t i_section_length = psi_get_length(p_section) + PSI_HEADER_SIZE;
1310 uint16_t i_section_offset = 0;
1314 block_t *p_block;
1315 uint8_t *p;
1316 uint8_t i_ts_offset;
1317 bool b_append = (pp_ts_buffer != NULL && *pp_ts_buffer != NULL);
1319 if ( b_append )
1321 p_block = *pp_ts_buffer;
1322 i_ts_offset = *pi_ts_buffer_offset;
1324 else
1326 p_block = block_New();
1327 p_block->i_dts = i_dts;
1328 i_ts_offset = 0;
1330 p = p_block->p_ts;
1332 psi_split_section( p, &i_ts_offset, p_section, &i_section_offset );
1334 if ( !b_append )
1336 ts_set_pid( p, i_pid );
1337 ts_set_cc( p, *pi_cc );
1338 (*pi_cc)++;
1339 *pi_cc &= 0xf;
1342 if ( i_section_offset == i_section_length )
1344 if ( i_ts_offset < TS_SIZE - MIN_SECTION_FRAGMENT
1345 && pp_ts_buffer != NULL )
1347 *pp_ts_buffer = p_block;
1348 *pi_ts_buffer_offset = i_ts_offset;
1349 break;
1351 else
1352 psi_split_end( p, &i_ts_offset );
1355 p_block->i_dts = i_dts;
1356 p_block->i_refcount--;
1357 output_Put( p_output, p_block );
1358 if ( pp_ts_buffer != NULL )
1360 *pp_ts_buffer = NULL;
1361 *pi_ts_buffer_offset = 0;
1364 while ( i_section_offset < i_section_length );
1367 /*****************************************************************************
1368 * SendPAT
1369 *****************************************************************************/
1370 static void SendPAT( mtime_t i_dts )
1372 int i;
1374 for ( i = 0; i < i_nb_outputs; i++ )
1376 output_t *p_output = pp_outputs[i];
1378 if ( !(p_output->config.i_config & OUTPUT_VALID) ||
1379 p_output->config.b_passthrough )
1380 continue;
1382 if ( p_output->p_pat_section == NULL &&
1383 psi_table_validate(pp_current_pat_sections) )
1385 /* SID doesn't exist - build an empty PAT. */
1386 uint8_t *p;
1387 p_output->i_pat_version++;
1389 p = p_output->p_pat_section = psi_allocate();
1390 pat_init( p );
1391 pat_set_length( p, 0 );
1392 pat_set_tsid( p, p_output->i_tsid );
1393 psi_set_version( p, p_output->i_pat_version );
1394 psi_set_current( p );
1395 psi_set_section( p, 0 );
1396 psi_set_lastsection( p, 0 );
1397 psi_set_crc( p_output->p_pat_section );
1401 if ( p_output->p_pat_section != NULL )
1402 OutputPSISection( p_output, p_output->p_pat_section, PAT_PID,
1403 &p_output->i_pat_cc, i_dts, NULL, NULL );
1407 /*****************************************************************************
1408 * SendPMT
1409 *****************************************************************************/
1410 static void SendPMT( sid_t *p_sid, mtime_t i_dts )
1412 int i;
1413 int i_pmt_pid = p_sid->i_pmt_pid;
1415 if ( b_do_remap )
1416 i_pmt_pid = pi_newpids[ I_PMTPID ];
1418 for ( i = 0; i < i_nb_outputs; i++ )
1420 output_t *p_output = pp_outputs[i];
1422 if ( (p_output->config.i_config & OUTPUT_VALID)
1423 && p_output->config.i_sid == p_sid->i_sid
1424 && p_output->p_pmt_section != NULL )
1426 if ( p_output->config.b_do_remap && p_output->config.pi_confpids[I_PMTPID] )
1427 i_pmt_pid = p_output->config.pi_confpids[I_PMTPID];
1429 OutputPSISection( p_output, p_output->p_pmt_section,
1430 i_pmt_pid, &p_output->i_pmt_cc, i_dts,
1431 NULL, NULL );
1436 /*****************************************************************************
1437 * SendNIT
1438 *****************************************************************************/
1439 static void SendNIT( mtime_t i_dts )
1441 int i;
1443 for ( i = 0; i < i_nb_outputs; i++ )
1445 output_t *p_output = pp_outputs[i];
1447 if ( (p_output->config.i_config & OUTPUT_VALID)
1448 && !p_output->config.b_passthrough
1449 && (p_output->config.i_config & OUTPUT_DVB)
1450 && p_output->p_nit_section != NULL )
1451 OutputPSISection( p_output, p_output->p_nit_section, NIT_PID,
1452 &p_output->i_nit_cc, i_dts, NULL, NULL );
1456 /*****************************************************************************
1457 * SendSDT
1458 *****************************************************************************/
1459 static void SendSDT( mtime_t i_dts )
1461 int i;
1463 for ( i = 0; i < i_nb_outputs; i++ )
1465 output_t *p_output = pp_outputs[i];
1467 if ( (p_output->config.i_config & OUTPUT_VALID)
1468 && !p_output->config.b_passthrough
1469 && (p_output->config.i_config & OUTPUT_DVB)
1470 && p_output->p_sdt_section != NULL )
1471 OutputPSISection( p_output, p_output->p_sdt_section, SDT_PID,
1472 &p_output->i_sdt_cc, i_dts, NULL, NULL );
1476 /*****************************************************************************
1477 * SendEIT
1478 *****************************************************************************/
1479 static bool IsEITpf( int i_table_id )
1481 return i_table_id == EIT_TABLE_ID_PF_ACTUAL;
1484 static bool IsEPG( int i_table_id )
1486 /* We only handle EPG for the current (actual) TS, not others. */
1487 return i_table_id >= EIT_TABLE_ID_SCHED_ACTUAL_FIRST &&
1488 i_table_id <= EIT_TABLE_ID_SCHED_ACTUAL_LAST;
1491 static void SendEIT( sid_t *p_sid, mtime_t i_dts, uint8_t *p_eit )
1493 uint8_t i_table_id = psi_get_tableid( p_eit );
1494 bool b_epg = IsEPG( i_table_id );
1495 uint16_t i_onid = eit_get_onid(p_eit);
1496 int i;
1498 for ( i = 0; i < i_nb_outputs; i++ )
1500 output_t *p_output = pp_outputs[i];
1502 if ( (p_output->config.i_config & OUTPUT_VALID)
1503 && !p_output->config.b_passthrough
1504 && (p_output->config.i_config & OUTPUT_DVB)
1505 && (!b_epg || (p_output->config.i_config & OUTPUT_EPG))
1506 && p_output->config.i_sid == p_sid->i_sid )
1508 eit_set_tsid( p_eit, p_output->i_tsid );
1510 if ( p_output->config.i_new_sid )
1511 eit_set_sid( p_eit, p_output->config.i_new_sid );
1512 else
1513 eit_set_sid( p_eit, p_output->config.i_sid );
1515 if ( p_output->config.i_onid )
1516 eit_set_onid( p_eit, p_output->config.i_onid );
1518 psi_set_crc( p_eit );
1520 OutputPSISection( p_output, p_eit, EIT_PID, &p_output->i_eit_cc,
1521 i_dts, &p_output->p_eit_ts_buffer,
1522 &p_output->i_eit_ts_buffer_offset );
1524 if ( p_output->config.i_onid )
1525 eit_set_onid( p_eit, i_onid );
1530 /*****************************************************************************
1531 * FlushEIT
1532 *****************************************************************************/
1533 static void FlushEIT( output_t *p_output, mtime_t i_dts )
1535 block_t *p_block = p_output->p_eit_ts_buffer;
1537 psi_split_end( p_block->p_ts, &p_output->i_eit_ts_buffer_offset );
1538 p_block->i_dts = i_dts;
1539 p_block->i_refcount--;
1540 output_Put( p_output, p_block );
1541 p_output->p_eit_ts_buffer = NULL;
1542 p_output->i_eit_ts_buffer_offset = 0;
1545 /*****************************************************************************
1546 * SendTDT
1547 *****************************************************************************/
1548 static void SendTDT( block_t *p_ts )
1550 int i;
1552 for ( i = 0; i < i_nb_outputs; i++ )
1554 output_t *p_output = pp_outputs[i];
1556 if ( (p_output->config.i_config & OUTPUT_VALID)
1557 && !p_output->config.b_passthrough
1558 && (p_output->config.i_config & OUTPUT_DVB)
1559 && p_output->p_sdt_section != NULL )
1560 output_Put( p_output, p_ts );
1563 /*****************************************************************************
1564 * SendEMM
1565 *****************************************************************************/
1566 static void SendEMM( block_t *p_ts )
1568 int i;
1570 for ( i = 0; i < i_nb_outputs; i++ )
1572 output_t *p_output = pp_outputs[i];
1574 if ( (p_output->config.i_config & OUTPUT_VALID)
1575 && !p_output->config.b_passthrough )
1576 output_Put( p_output, p_ts );
1580 /*****************************************************************************
1581 * NewPAT
1582 *****************************************************************************/
1583 static void NewPAT( output_t *p_output )
1585 const uint8_t *p_program;
1586 uint8_t *p;
1587 uint8_t k = 0;
1589 free( p_output->p_pat_section );
1590 p_output->p_pat_section = NULL;
1591 p_output->i_pat_version++;
1593 if ( !p_output->config.i_sid ) return;
1594 if ( !psi_table_validate(pp_current_pat_sections) ) return;
1596 p_program = pat_table_find_program( pp_current_pat_sections,
1597 p_output->config.i_sid );
1598 if ( p_program == NULL ) return;
1600 p = p_output->p_pat_section = psi_allocate();
1601 pat_init( p );
1602 psi_set_length( p, PSI_MAX_SIZE );
1603 pat_set_tsid( p, p_output->i_tsid );
1604 psi_set_version( p, p_output->i_pat_version );
1605 psi_set_current( p );
1606 psi_set_section( p, 0 );
1607 psi_set_lastsection( p, 0 );
1609 if ( p_output->config.i_config & OUTPUT_DVB )
1611 /* NIT */
1612 p = pat_get_program( p_output->p_pat_section, k++ );
1613 patn_init( p );
1614 patn_set_program( p, 0 );
1615 patn_set_pid( p, NIT_PID );
1618 p = pat_get_program( p_output->p_pat_section, k++ );
1619 patn_init( p );
1620 if ( p_output->config.i_new_sid )
1622 msg_Dbg( NULL, "Mapping PAT SID %d to %d", p_output->config.i_sid,
1623 p_output->config.i_new_sid );
1624 patn_set_program( p, p_output->config.i_new_sid );
1626 else
1627 patn_set_program( p, p_output->config.i_sid );
1629 if ( b_do_remap )
1631 msg_Dbg( NULL, "Mapping PMT PID %d to %d", patn_get_pid( p_program ), pi_newpids[I_PMTPID] );
1632 patn_set_pid( p, pi_newpids[I_PMTPID]);
1633 } else if ( p_output->config.b_do_remap && p_output->config.pi_confpids[I_PMTPID] ) {
1634 msg_Dbg( NULL, "Mapping PMT PID %d to %d", patn_get_pid( p_program ), p_output->config.pi_confpids[I_PMTPID] );
1635 patn_set_pid( p, p_output->config.pi_confpids[I_PMTPID]);
1636 } else {
1637 patn_set_pid( p, patn_get_pid( p_program ) );
1640 p = pat_get_program( p_output->p_pat_section, k );
1641 pat_set_length( p_output->p_pat_section,
1642 p - p_output->p_pat_section - PAT_HEADER_SIZE );
1643 psi_set_crc( p_output->p_pat_section );
1646 /*****************************************************************************
1647 * NewPMT
1648 *****************************************************************************/
1649 static void CopyDescriptors( uint8_t *p_descs, uint8_t *p_current_descs )
1651 uint8_t *p_desc;
1652 const uint8_t *p_current_desc;
1653 uint16_t j = 0, k = 0;
1655 descs_set_length( p_descs, DESCS_MAX_SIZE );
1657 while ( (p_current_desc = descs_get_desc( p_current_descs, j )) != NULL )
1659 uint8_t i_tag = desc_get_tag( p_current_desc );
1661 j++;
1662 if ( !b_enable_ecm && i_tag == 0x9 ) continue;
1664 p_desc = descs_get_desc( p_descs, k );
1665 if ( p_desc == NULL ) continue; /* This shouldn't happen */
1666 k++;
1667 memcpy( p_desc, p_current_desc,
1668 DESC_HEADER_SIZE + desc_get_length( p_current_desc ) );
1671 p_desc = descs_get_desc( p_descs, k );
1672 if ( p_desc == NULL )
1673 /* This shouldn't happen if the incoming PMT is valid */
1674 descs_set_length( p_descs, 0 );
1675 else
1676 descs_set_length( p_descs, p_desc - p_descs - DESCS_HEADER_SIZE );
1679 static void NewPMT( output_t *p_output )
1681 sid_t *p_sid;
1682 uint8_t *p_current_pmt;
1683 uint8_t *p_es, *p_current_es;
1684 uint8_t *p;
1685 uint16_t j, k;
1686 uint16_t i_pcrpid;
1688 free( p_output->p_pmt_section );
1689 p_output->p_pmt_section = NULL;
1690 p_output->i_pmt_version++;
1692 if ( !p_output->config.i_sid ) return;
1694 p_sid = FindSID( p_output->config.i_sid );
1695 if ( p_sid == NULL ) return;
1697 if ( p_sid->p_current_pmt == NULL ) return;
1698 p_current_pmt = p_sid->p_current_pmt;
1700 p = p_output->p_pmt_section = psi_allocate();
1701 pmt_init( p );
1702 psi_set_length( p, PSI_MAX_SIZE );
1703 if ( p_output->config.i_new_sid )
1705 msg_Dbg( NULL, "Mapping PMT SID %d to %d", p_output->config.i_sid,
1706 p_output->config.i_new_sid );
1707 pmt_set_program( p, p_output->config.i_new_sid );
1709 else
1710 pmt_set_program( p, p_output->config.i_sid );
1711 psi_set_version( p, p_output->i_pmt_version );
1712 psi_set_current( p );
1713 pmt_set_desclength( p, 0 );
1714 init_pid_mapping( p_output );
1717 CopyDescriptors( pmt_get_descs( p ), pmt_get_descs( p_current_pmt ) );
1719 j = 0; k = 0;
1720 while ( (p_current_es = pmt_get_es( p_current_pmt, j )) != NULL )
1722 uint16_t i_pid = pmtn_get_pid( p_current_es );
1724 j++;
1725 if ( (p_output->config.i_nb_pids || !PIDWouldBeSelected( p_current_es ))
1726 && !IsIn( p_output->config.pi_pids, p_output->config.i_nb_pids,
1727 i_pid ) )
1728 continue;
1730 p_es = pmt_get_es( p, k );
1731 if ( p_es == NULL ) continue; /* This shouldn't happen */
1732 k++;
1733 pmtn_init( p_es );
1734 pmtn_set_streamtype( p_es, pmtn_get_streamtype( p_current_es ) );
1735 pmtn_set_pid( p_es, map_es_pid(p_output, p_current_es, i_pid) );
1736 pmtn_set_desclength( p_es, 0 );
1738 CopyDescriptors( pmtn_get_descs( p_es ),
1739 pmtn_get_descs( p_current_es ) );
1742 /* Do the pcr pid after everything else as it may have been remapped */
1743 i_pcrpid = pmt_get_pcrpid( p_current_pmt );
1744 if ( p_output->pi_newpids[i_pcrpid] != UNUSED_PID ) {
1745 msg_Dbg( NULL, "REMAP: The PCR PID was changed from 0x%x (%u) to 0x%x (%u)",
1746 i_pcrpid, i_pcrpid, p_output->pi_newpids[i_pcrpid], p_output->pi_newpids[i_pcrpid] );
1747 i_pcrpid = p_output->pi_newpids[i_pcrpid];
1748 } else {
1749 msg_Dbg( NULL, "The PCR PID has kept its original value of 0x%x (%u)", i_pcrpid, i_pcrpid);
1751 pmt_set_pcrpid( p, i_pcrpid );
1752 p_es = pmt_get_es( p, k );
1753 if ( p_es == NULL )
1754 /* This shouldn't happen if the incoming PMT is valid */
1755 pmt_set_length( p, 0 );
1756 else
1757 pmt_set_length( p, p_es - p - PMT_HEADER_SIZE );
1758 psi_set_crc( p );
1761 /*****************************************************************************
1762 * NewNIT
1763 *****************************************************************************/
1764 static void NewNIT( output_t *p_output )
1766 uint8_t *p_ts;
1767 uint8_t *p_header2;
1768 uint8_t *p;
1770 free( p_output->p_nit_section );
1771 p_output->p_nit_section = NULL;
1772 p_output->i_nit_version++;
1774 p = p_output->p_nit_section = psi_allocate();
1775 nit_init( p, true );
1776 nit_set_length( p, PSI_MAX_SIZE );
1777 nit_set_nid( p, p_output->config.i_network_id );
1778 psi_set_version( p, p_output->i_nit_version );
1779 psi_set_current( p );
1780 psi_set_section( p, 0 );
1781 psi_set_lastsection( p, 0 );
1783 if ( p_output->config.network_name.i )
1785 uint8_t *p_descs;
1786 uint8_t *p_desc;
1787 nit_set_desclength( p, DESCS_MAX_SIZE );
1788 p_descs = nit_get_descs( p );
1789 p_desc = descs_get_desc( p_descs, 0 );
1790 desc40_init( p_desc );
1791 desc40_set_networkname( p_desc, p_output->config.network_name.p,
1792 p_output->config.network_name.i );
1793 p_desc = descs_get_desc( p_descs, 1 );
1794 descs_set_length( p_descs, p_desc - p_descs - DESCS_HEADER_SIZE );
1796 else
1797 nit_set_desclength( p, 0 );
1799 p_header2 = nit_get_header2( p );
1800 nith_init( p_header2 );
1801 nith_set_tslength( p_header2, NIT_TS_SIZE );
1803 p_ts = nit_get_ts( p, 0 );
1804 nitn_init( p_ts );
1805 nitn_set_tsid( p_ts, p_output->i_tsid );
1806 if ( p_output->config.i_onid )
1807 nitn_set_onid( p_ts, p_output->config.i_onid );
1808 else
1809 nitn_set_onid( p_ts, p_output->config.i_network_id );
1810 nitn_set_desclength( p_ts, 0 );
1812 p_ts = nit_get_ts( p, 1 );
1813 if ( p_ts == NULL )
1814 /* This shouldn't happen */
1815 nit_set_length( p, 0 );
1816 else
1817 nit_set_length( p, p_ts - p - NIT_HEADER_SIZE );
1818 psi_set_crc( p_output->p_nit_section );
1821 /*****************************************************************************
1822 * NewSDT
1823 *****************************************************************************/
1824 static void NewSDT( output_t *p_output )
1826 uint8_t *p_service, *p_current_service;
1827 uint8_t *p;
1829 free( p_output->p_sdt_section );
1830 p_output->p_sdt_section = NULL;
1831 p_output->i_sdt_version++;
1833 if ( !p_output->config.i_sid ) return;
1834 if ( !psi_table_validate(pp_current_sdt_sections) ) return;
1836 p_current_service = sdt_table_find_service( pp_current_sdt_sections,
1837 p_output->config.i_sid );
1839 if ( p_current_service == NULL )
1841 if ( p_output->p_pat_section != NULL &&
1842 pat_get_program( p_output->p_pat_section, 0 ) == NULL )
1844 /* Empty PAT and no SDT anymore */
1845 free( p_output->p_pat_section );
1846 p_output->p_pat_section = NULL;
1847 p_output->i_pat_version++;
1849 return;
1852 p = p_output->p_sdt_section = psi_allocate();
1853 sdt_init( p, true );
1854 sdt_set_length( p, PSI_MAX_SIZE );
1855 sdt_set_tsid( p, p_output->i_tsid );
1856 psi_set_version( p, p_output->i_sdt_version );
1857 psi_set_current( p );
1858 psi_set_section( p, 0 );
1859 psi_set_lastsection( p, 0 );
1860 if ( p_output->config.i_onid )
1861 sdt_set_onid( p, p_output->config.i_onid );
1862 else
1863 sdt_set_onid( p,
1864 sdt_get_onid( psi_table_get_section( pp_current_sdt_sections, 0 ) ) );
1866 p_service = sdt_get_service( p, 0 );
1867 sdtn_init( p_service );
1868 if ( p_output->config.i_new_sid )
1870 msg_Dbg( NULL, "Mapping SDT SID %d to %d", p_output->config.i_sid,
1871 p_output->config.i_new_sid );
1872 sdtn_set_sid( p_service, p_output->config.i_new_sid );
1874 else
1875 sdtn_set_sid( p_service, p_output->config.i_sid );
1877 /* We always forward EITp/f */
1878 if ( sdtn_get_eitpresent(p_current_service) )
1879 sdtn_set_eitpresent(p_service);
1881 if ( (p_output->config.i_config & OUTPUT_EPG) == OUTPUT_EPG &&
1882 sdtn_get_eitschedule(p_current_service) )
1883 sdtn_set_eitschedule(p_service);
1885 sdtn_set_running( p_service, sdtn_get_running(p_current_service) );
1886 /* Do not set free_ca */
1887 sdtn_set_desclength( p_service, sdtn_get_desclength(p_current_service) );
1889 if ( !p_output->config.provider_name.i &&
1890 !p_output->config.service_name.i ) {
1891 /* Copy all descriptors unchanged */
1892 memcpy( descs_get_desc( sdtn_get_descs(p_service), 0 ),
1893 descs_get_desc( sdtn_get_descs(p_current_service), 0 ),
1894 sdtn_get_desclength(p_current_service) );
1895 } else {
1896 int j = 0, i_total_desc_len = 0;
1897 uint8_t *p_desc;
1898 uint8_t *p_new_desc = descs_get_desc( sdtn_get_descs(p_service), 0 );
1899 while ( (p_desc = descs_get_desc( sdtn_get_descs( p_current_service ), j++ )) != NULL )
1901 /* Regenerate descriptor 48 (service name) */
1902 if ( desc_get_tag( p_desc ) == 0x48 && desc48_validate( p_desc ) )
1904 uint8_t i_old_provider_len, i_old_service_len;
1905 uint8_t i_new_desc_len = 3; /* 1 byte - type, 1 byte provider_len, 1 byte service_len */
1906 const uint8_t *p_old_provider = desc48_get_provider( p_desc, &i_old_provider_len );
1907 const uint8_t *p_old_service = desc48_get_service( p_desc, &i_old_service_len );
1909 desc48_init( p_new_desc );
1910 desc48_set_type( p_new_desc, desc48_get_type( p_desc ) );
1912 if ( p_output->config.provider_name.i ) {
1913 desc48_set_provider( p_new_desc,
1914 p_output->config.provider_name.p,
1915 p_output->config.provider_name.i );
1916 i_new_desc_len += p_output->config.provider_name.i;
1917 } else {
1918 desc48_set_provider( p_new_desc, p_old_provider,
1919 i_old_provider_len );
1920 i_new_desc_len += i_old_provider_len;
1923 if ( p_output->config.service_name.i ) {
1924 desc48_set_service( p_new_desc,
1925 p_output->config.service_name.p,
1926 p_output->config.service_name.i );
1927 i_new_desc_len += p_output->config.service_name.i;
1928 } else {
1929 desc48_set_service( p_new_desc, p_old_service,
1930 i_old_service_len );
1931 i_new_desc_len += i_old_service_len;
1934 desc_set_length( p_new_desc, i_new_desc_len );
1935 i_total_desc_len += DESC_HEADER_SIZE + i_new_desc_len;
1936 p_new_desc += DESC_HEADER_SIZE + i_new_desc_len;
1937 } else {
1938 /* Copy single descriptor */
1939 int i_desc_len = DESC_HEADER_SIZE + desc_get_length( p_desc );
1940 memcpy( p_new_desc, p_desc, i_desc_len );
1941 p_new_desc += i_desc_len;
1942 i_total_desc_len += i_desc_len;
1945 sdtn_set_desclength( p_service, i_total_desc_len );
1948 p_service = sdt_get_service( p, 1 );
1949 if ( p_service == NULL )
1950 /* This shouldn't happen if the incoming SDT is valid */
1951 sdt_set_length( p, 0 );
1952 else
1953 sdt_set_length( p, p_service - p - SDT_HEADER_SIZE );
1954 psi_set_crc( p_output->p_sdt_section );
1957 /*****************************************************************************
1958 * UpdatePAT/PMT/SDT
1959 *****************************************************************************/
1960 #define DECLARE_UPDATE_FUNC( table ) \
1961 static void Update##table( uint16_t i_sid ) \
1963 int i; \
1965 for ( i = 0; i < i_nb_outputs; i++ ) \
1966 if ( ( pp_outputs[i]->config.i_config & OUTPUT_VALID ) \
1967 && pp_outputs[i]->config.i_sid == i_sid ) \
1968 New##table( pp_outputs[i] ); \
1971 DECLARE_UPDATE_FUNC(PAT)
1972 DECLARE_UPDATE_FUNC(PMT)
1973 DECLARE_UPDATE_FUNC(SDT)
1975 /*****************************************************************************
1976 * UpdateTSID
1977 *****************************************************************************/
1978 static void UpdateTSID(void)
1980 uint16_t i_tsid = psi_table_get_tableidext(pp_current_pat_sections);
1981 int i;
1983 for ( i = 0; i < i_nb_outputs; i++ )
1985 output_t *p_output = pp_outputs[i];
1987 if ( (p_output->config.i_config & OUTPUT_VALID)
1988 && p_output->config.i_tsid == -1 && !b_random_tsid )
1990 p_output->i_tsid = i_tsid;
1991 NewNIT( p_output );
1996 /*****************************************************************************
1997 * SIDIsSelected
1998 *****************************************************************************/
1999 static bool SIDIsSelected( uint16_t i_sid )
2001 int i;
2003 for ( i = 0; i < i_nb_outputs; i++ )
2004 if ( (pp_outputs[i]->config.i_config & OUTPUT_VALID)
2005 && pp_outputs[i]->config.i_sid == i_sid )
2006 return true;
2008 return false;
2011 /*****************************************************************************
2012 * demux_PIDIsSelected
2013 *****************************************************************************/
2014 bool demux_PIDIsSelected( uint16_t i_pid )
2016 int i;
2018 for ( i = 0; i < p_pids[i_pid].i_nb_outputs; i++ )
2019 if ( p_pids[i_pid].pp_outputs[i] != NULL )
2020 return true;
2022 return false;
2025 /*****************************************************************************
2026 * PIDWouldBeSelected
2027 *****************************************************************************/
2028 static bool PIDWouldBeSelected( uint8_t *p_es )
2030 if ( b_any_type ) return true;
2032 uint8_t i_type = pmtn_get_streamtype( p_es );
2034 switch ( i_type )
2036 case 0x1: /* video MPEG-1 */
2037 case 0x2: /* video */
2038 case 0x3: /* audio MPEG-1 */
2039 case 0x4: /* audio */
2040 case 0xf: /* audio AAC ADTS */
2041 case 0x10: /* video MPEG-4 */
2042 case 0x11: /* audio AAC LATM */
2043 case 0x1b: /* video H264 */
2044 case 0x24: /* video H265 */
2045 case 0x81: /* ATSC A/52 */
2046 case 0x87: /* ATSC Enhanced A/52 */
2047 return true;
2048 break;
2050 case 0x6:
2052 uint16_t j = 0;
2053 const uint8_t *p_desc;
2055 while ( (p_desc = descs_get_desc( pmtn_get_descs( p_es ), j )) != NULL )
2057 uint8_t i_tag = desc_get_tag( p_desc );
2058 j++;
2060 if( i_tag == 0x46 /* VBI + teletext */
2061 || i_tag == 0x56 /* teletext */
2062 || i_tag == 0x59 /* dvbsub */
2063 || i_tag == 0x6a /* A/52 */
2064 || i_tag == 0x7a /* Enhanced A/52 */
2065 || i_tag == 0x7b /* DCA */
2066 || i_tag == 0x7c /* AAC */ )
2067 return true;
2069 break;
2072 default:
2073 break;
2076 /* FIXME: also parse IOD */
2077 return false;
2080 /*****************************************************************************
2081 * PIDCarriesPES
2082 *****************************************************************************/
2083 static bool PIDCarriesPES( const uint8_t *p_es )
2085 uint8_t i_type = pmtn_get_streamtype( p_es );
2087 switch ( i_type )
2089 case 0x1: /* video MPEG-1 */
2090 case 0x2: /* video */
2091 case 0x3: /* audio MPEG-1 */
2092 case 0x4: /* audio */
2093 case 0x6: /* private PES data */
2094 case 0xf: /* audio AAC */
2095 case 0x10: /* video MPEG-4 */
2096 case 0x11: /* audio AAC LATM */
2097 case 0x1b: /* video H264 */
2098 case 0x24: /* video H265 */
2099 case 0x81: /* ATSC A/52 */
2100 case 0x87: /* ATSC Enhanced A/52 */
2101 return true;
2102 break;
2104 default:
2105 return false;
2106 break;
2110 /*****************************************************************************
2111 * PMTNeedsDescrambling
2112 *****************************************************************************/
2113 static bool PMTNeedsDescrambling( uint8_t *p_pmt )
2115 uint8_t i;
2116 uint16_t j;
2117 uint8_t *p_es;
2118 const uint8_t *p_desc;
2120 j = 0;
2121 while ( (p_desc = descs_get_desc( pmt_get_descs( p_pmt ), j )) != NULL )
2123 uint8_t i_tag = desc_get_tag( p_desc );
2124 j++;
2126 if ( i_tag == 0x9 ) return true;
2129 i = 0;
2130 while ( (p_es = pmt_get_es( p_pmt, i )) != NULL )
2132 i++;
2133 j = 0;
2134 while ( (p_desc = descs_get_desc( pmtn_get_descs( p_es ), j )) != NULL )
2136 uint8_t i_tag = desc_get_tag( p_desc );
2137 j++;
2139 if ( i_tag == 0x9 ) return true;
2143 return false;
2146 /*****************************************************************************
2147 * demux_ResendCAPMTs
2148 *****************************************************************************/
2149 void demux_ResendCAPMTs( void )
2151 int i;
2152 for ( i = 0; i < i_nb_sids; i++ )
2153 if ( pp_sids[i]->p_current_pmt != NULL
2154 && SIDIsSelected( pp_sids[i]->i_sid )
2155 && PMTNeedsDescrambling( pp_sids[i]->p_current_pmt ) )
2156 en50221_AddPMT( pp_sids[i]->p_current_pmt );
2159 /* Find CA descriptor that have PID i_ca_pid */
2160 static uint8_t *ca_desc_find( uint8_t *p_descl, uint16_t i_length,
2161 uint16_t i_ca_pid )
2163 int j = 0;
2164 uint8_t *p_desc;
2166 while ( (p_desc = descl_get_desc( p_descl, i_length, j++ )) != NULL ) {
2167 if ( desc_get_tag( p_desc ) != 0x09 || !desc09_validate( p_desc ) )
2168 continue;
2169 if ( desc09_get_pid( p_desc ) == i_ca_pid )
2170 return p_desc;
2173 return NULL;
2176 /*****************************************************************************
2177 * DeleteProgram
2178 *****************************************************************************/
2179 static void DeleteProgram( uint16_t i_sid, uint16_t i_pid )
2181 sid_t *p_sid;
2182 uint8_t *p_pmt;
2183 uint8_t *p_desc;
2185 UnselectPMT( i_sid, i_pid );
2187 p_sid = FindSID( i_sid );
2188 if ( p_sid == NULL ) return;
2190 p_pmt = p_sid->p_current_pmt;
2192 if ( p_pmt != NULL )
2194 uint16_t i_pcr_pid = pmt_get_pcrpid( p_pmt );
2195 uint8_t *p_es;
2196 uint8_t j;
2198 if ( i_ca_handle && SIDIsSelected( i_sid )
2199 && PMTNeedsDescrambling( p_pmt ) )
2200 en50221_DeletePMT( p_pmt );
2202 if ( i_pcr_pid != PADDING_PID
2203 && i_pcr_pid != p_sid->i_pmt_pid )
2204 UnselectPID( i_sid, i_pcr_pid );
2206 if ( b_enable_ecm )
2208 j = 0;
2210 while ((p_desc = descs_get_desc( pmt_get_descs( p_pmt ), j++ )) != NULL)
2212 if ( desc_get_tag( p_desc ) != 0x09 ||
2213 !desc09_validate( p_desc ) )
2214 continue;
2215 UnselectPID( i_sid, desc09_get_pid( p_desc ) );
2219 j = 0;
2220 while ( (p_es = pmt_get_es( p_pmt, j )) != NULL )
2222 uint16_t i_pid = pmtn_get_pid( p_es );
2223 j++;
2225 if ( PIDWouldBeSelected( p_es ) )
2226 UnselectPID( i_sid, i_pid );
2228 if ( b_enable_ecm )
2230 uint8_t k = 0;
2232 while ((p_desc = descs_get_desc( pmtn_get_descs( p_es ), k++ )) != NULL)
2234 if ( desc_get_tag( p_desc ) != 0x09 || !desc09_validate( p_desc ) )
2235 continue;
2236 UnselectPID( i_sid, desc09_get_pid( p_desc ) );
2241 free( p_pmt );
2242 p_sid->p_current_pmt = NULL;
2244 p_sid->i_sid = 0;
2245 p_sid->i_pmt_pid = 0;
2247 uint8_t r;
2248 for ( r = 0; r < MAX_EIT_TABLES; r++ ) {
2249 psi_table_free( p_sid->eit_table[r].data );
2250 psi_table_init( p_sid->eit_table[r].data );
2255 /*****************************************************************************
2256 * demux_Iconv
2257 *****************************************************************************
2258 * This code is from biTStream's examples and is under the WTFPL (see
2259 * LICENSE.WTFPL).
2260 *****************************************************************************/
2261 static char *iconv_append_null(const char *p_string, size_t i_length)
2263 char *psz_string = malloc(i_length + 1);
2264 memcpy(psz_string, p_string, i_length);
2265 psz_string[i_length] = '\0';
2266 return psz_string;
2269 char *demux_Iconv(void *_unused, const char *psz_encoding,
2270 char *p_string, size_t i_length)
2272 #ifdef HAVE_ICONV
2273 static const char *psz_current_encoding = "";
2275 char *psz_string, *p;
2276 size_t i_out_length;
2278 if (!strcmp(psz_encoding, psz_native_charset))
2279 return iconv_append_null(p_string, i_length);
2281 if (iconv_handle != (iconv_t)-1 &&
2282 strcmp(psz_encoding, psz_current_encoding)) {
2283 iconv_close(iconv_handle);
2284 iconv_handle = (iconv_t)-1;
2287 if (iconv_handle == (iconv_t)-1)
2288 iconv_handle = iconv_open(psz_native_charset, psz_encoding);
2289 if (iconv_handle == (iconv_t)-1) {
2290 msg_Warn(NULL, "couldn't open converter from %s to %s (%m)", psz_encoding,
2291 psz_native_charset);
2292 return iconv_append_null(p_string, i_length);
2294 psz_current_encoding = psz_encoding;
2296 /* converted strings can be up to six times larger */
2297 i_out_length = i_length * 6;
2298 p = psz_string = malloc(i_out_length);
2299 if (iconv(iconv_handle, &p_string, &i_length, &p, &i_out_length) == (size_t)-1) {
2300 msg_Warn(NULL, "couldn't convert from %s to %s (%m)", psz_encoding,
2301 psz_native_charset);
2302 free(psz_string);
2303 return iconv_append_null(p_string, i_length);
2305 if (i_length)
2306 msg_Warn(NULL, "partial conversion from %s to %s", psz_encoding,
2307 psz_native_charset);
2309 *p = '\0';
2310 return psz_string;
2311 #else
2312 return iconv_append_null(p_string, i_length);
2313 #endif
2316 /*****************************************************************************
2317 * demux_Print
2318 *****************************************************************************
2319 * This code is from biTStream's examples and is under the WTFPL (see
2320 * LICENSE.WTFPL).
2321 *****************************************************************************/
2322 __attribute__ ((format(printf, 2, 3)))
2323 static void demux_Print(void *_unused, const char *psz_format, ...)
2325 char psz_fmt[strlen(psz_format) + 2];
2326 va_list args;
2327 va_start(args, psz_format);
2328 strcpy(psz_fmt, psz_format);
2329 if ( i_print_type != PRINT_XML )
2330 strcat(psz_fmt, "\n");
2331 vprintf(psz_fmt, args);
2332 va_end(args);
2335 /*****************************************************************************
2336 * HandlePAT
2337 *****************************************************************************/
2338 static void HandlePAT( mtime_t i_dts )
2340 bool b_change = false;
2341 PSI_TABLE_DECLARE( pp_old_pat_sections );
2342 uint8_t i_last_section = psi_table_get_lastsection( pp_next_pat_sections );
2343 uint8_t i, r;
2345 if ( psi_table_validate( pp_current_pat_sections ) &&
2346 psi_table_compare( pp_current_pat_sections, pp_next_pat_sections ) )
2348 /* Identical PAT. Shortcut. */
2349 psi_table_free( pp_next_pat_sections );
2350 psi_table_init( pp_next_pat_sections );
2351 goto out_pat;
2354 if ( !pat_table_validate( pp_next_pat_sections ) )
2356 msg_Warn( NULL, "invalid PAT received" );
2357 switch (i_print_type) {
2358 case PRINT_XML:
2359 fprintf(print_fh, "<ERROR type=\"invalid_pat\"/>\n");
2360 break;
2361 case PRINT_TEXT:
2362 fprintf(print_fh, "error type: invalid_pat\n");
2363 break;
2364 default:
2365 break;
2367 psi_table_free( pp_next_pat_sections );
2368 psi_table_init( pp_next_pat_sections );
2369 goto out_pat;
2372 /* Switch tables. */
2373 psi_table_copy( pp_old_pat_sections, pp_current_pat_sections );
2374 psi_table_copy( pp_current_pat_sections, pp_next_pat_sections );
2375 psi_table_init( pp_next_pat_sections );
2377 if ( !psi_table_validate( pp_old_pat_sections )
2378 || psi_table_get_tableidext( pp_current_pat_sections )
2379 != psi_table_get_tableidext( pp_old_pat_sections ) )
2381 b_change = true;
2382 UpdateTSID();
2383 /* This will trigger a universal reset of everything. */
2386 for ( i = 0; i <= i_last_section; i++ )
2388 uint8_t *p_section =
2389 psi_table_get_section( pp_current_pat_sections, i );
2390 const uint8_t *p_program;
2391 int j = 0;
2393 while ( (p_program = pat_get_program( p_section, j )) != NULL )
2395 const uint8_t *p_old_program = NULL;
2396 uint16_t i_sid = patn_get_program( p_program );
2397 uint16_t i_pid = patn_get_pid( p_program );
2398 j++;
2400 if ( i_sid == 0 )
2402 if ( i_pid != NIT_PID )
2403 msg_Warn( NULL,
2404 "NIT is carried on PID %hu which isn't DVB compliant",
2405 i_pid );
2406 continue; /* NIT */
2409 if ( !psi_table_validate( pp_old_pat_sections )
2410 || (p_old_program = pat_table_find_program(
2411 pp_old_pat_sections, i_sid )) == NULL
2412 || patn_get_pid( p_old_program ) != i_pid
2413 || b_change )
2415 sid_t *p_sid;
2417 if ( p_old_program != NULL )
2418 DeleteProgram( i_sid, patn_get_pid( p_old_program ) );
2420 SelectPMT( i_sid, i_pid );
2422 p_sid = FindSID( 0 );
2423 if ( p_sid == NULL )
2425 p_sid = malloc( sizeof(sid_t) );
2426 p_sid->p_current_pmt = NULL;
2427 for ( r = 0; r < MAX_EIT_TABLES; r++ ) {
2428 psi_table_init( p_sid->eit_table[r].data );
2430 i_nb_sids++;
2431 pp_sids = realloc( pp_sids, sizeof(sid_t *) * i_nb_sids );
2432 pp_sids[i_nb_sids - 1] = p_sid;
2435 p_sid->i_sid = i_sid;
2436 p_sid->i_pmt_pid = i_pid;
2438 UpdatePAT( i_sid );
2443 if ( psi_table_validate( pp_old_pat_sections ) )
2445 i_last_section = psi_table_get_lastsection( pp_old_pat_sections );
2446 for ( i = 0; i <= i_last_section; i++ )
2448 uint8_t *p_section =
2449 psi_table_get_section( pp_old_pat_sections, i );
2450 const uint8_t *p_program;
2451 int j = 0;
2453 while ( (p_program = pat_get_program( p_section, j )) != NULL )
2455 uint16_t i_sid = patn_get_program( p_program );
2456 uint16_t i_pid = patn_get_pid( p_program );
2457 j++;
2459 if ( i_sid == 0 )
2460 continue; /* NIT */
2462 if ( pat_table_find_program( pp_current_pat_sections, i_sid )
2463 == NULL )
2465 DeleteProgram( i_sid, i_pid );
2466 UpdatePAT( i_sid );
2471 psi_table_free( pp_old_pat_sections );
2474 pat_table_print( pp_current_pat_sections, msg_Dbg, NULL, PRINT_TEXT );
2475 if ( b_print_enabled )
2477 pat_table_print( pp_current_pat_sections, demux_Print, NULL,
2478 i_print_type );
2479 if ( i_print_type == PRINT_XML )
2480 fprintf(print_fh, "\n");
2483 out_pat:
2484 SendPAT( i_dts );
2487 /*****************************************************************************
2488 * HandlePATSection
2489 *****************************************************************************/
2490 static void HandlePATSection( uint16_t i_pid, uint8_t *p_section,
2491 mtime_t i_dts )
2493 if ( i_pid != PAT_PID || !pat_validate( p_section ) )
2495 msg_Warn( NULL, "invalid PAT section received on PID %hu", i_pid );
2496 switch (i_print_type) {
2497 case PRINT_XML:
2498 fprintf(print_fh, "<ERROR type=\"invalid_pat_section\"/>\n");
2499 break;
2500 case PRINT_TEXT:
2501 fprintf(print_fh, "error type: invalid_pat_section\n");
2502 break;
2503 default:
2504 break;
2506 free( p_section );
2507 return;
2510 if ( !psi_table_section( pp_next_pat_sections, p_section ) )
2511 return;
2513 HandlePAT( i_dts );
2516 /*****************************************************************************
2517 * HandleCAT
2518 *****************************************************************************/
2519 static void HandleCAT( mtime_t i_dts )
2521 PSI_TABLE_DECLARE( pp_old_cat_sections );
2522 uint8_t i_last_section = psi_table_get_lastsection( pp_next_cat_sections );
2523 uint8_t i_last_section2;
2524 uint8_t i, r;
2525 uint8_t *p_desc;
2526 int j, k;
2528 if ( psi_table_validate( pp_current_cat_sections ) &&
2529 psi_table_compare( pp_current_cat_sections, pp_next_cat_sections ) )
2531 /* Identical CAT. Shortcut. */
2532 psi_table_free( pp_next_cat_sections );
2533 psi_table_init( pp_next_cat_sections );
2534 goto out_cat;
2537 if ( !cat_table_validate( pp_next_cat_sections ) )
2539 msg_Warn( NULL, "invalid CAT received" );
2540 switch (i_print_type) {
2541 case PRINT_XML:
2542 fprintf(print_fh, "<ERROR type=\"invalid_cat\"/>\n");
2543 break;
2544 case PRINT_TEXT:
2545 fprintf(print_fh, "error type: invalid_cat\n");
2546 break;
2547 default:
2548 break;
2550 psi_table_free( pp_next_cat_sections );
2551 psi_table_init( pp_next_cat_sections );
2552 goto out_cat;
2555 /* Switch tables. */
2556 psi_table_copy( pp_old_cat_sections, pp_current_cat_sections );
2557 psi_table_copy( pp_current_cat_sections, pp_next_cat_sections );
2558 psi_table_init( pp_next_cat_sections );
2560 for ( i = 0; i <= i_last_section; i++ )
2562 uint8_t *p_section = psi_table_get_section( pp_current_cat_sections, i );
2564 j = 0;
2565 while ( (p_desc = descl_get_desc( cat_get_descl(p_section), cat_get_desclength(p_section), j++ )) != NULL )
2567 if ( desc_get_tag( p_desc ) != 0x09 || !desc09_validate( p_desc ) )
2568 continue;
2570 SetPID_EMM( desc09_get_pid( p_desc ) );
2574 if ( psi_table_validate( pp_old_cat_sections ) )
2576 i_last_section = psi_table_get_lastsection( pp_old_cat_sections );
2577 for ( i = 0; i <= i_last_section; i++ )
2579 uint8_t *p_old_section = psi_table_get_section( pp_old_cat_sections, i );
2580 j = 0;
2581 while ( (p_desc = descl_get_desc( cat_get_descl(p_old_section), cat_get_desclength(p_old_section), j++ )) != NULL )
2583 uint16_t emm_pid;
2584 int pid_found = 0;
2586 if ( desc_get_tag( p_desc ) != 0x09 || !desc09_validate( p_desc ) )
2587 continue;
2589 emm_pid = desc09_get_pid( p_desc );
2591 // Search in current sections if the pid exists
2592 i_last_section2 = psi_table_get_lastsection( pp_current_cat_sections );
2593 for ( r = 0; r <= i_last_section2; r++ )
2595 uint8_t *p_section = psi_table_get_section( pp_current_cat_sections, r );
2597 k = 0;
2598 while ( (p_desc = descl_get_desc( cat_get_descl(p_section), cat_get_desclength(p_section), k++ )) != NULL )
2600 if ( desc_get_tag( p_desc ) != 0x09 || !desc09_validate( p_desc ) )
2601 continue;
2602 if ( ca_desc_find( cat_get_descl(p_section), cat_get_desclength(p_section), emm_pid ) != NULL )
2604 pid_found = 1;
2605 break;
2610 if ( !pid_found )
2611 UnsetPID(emm_pid);
2615 psi_table_free( pp_old_cat_sections );
2618 cat_table_print( pp_current_cat_sections, msg_Dbg, NULL, PRINT_TEXT );
2619 if ( b_print_enabled )
2621 cat_table_print( pp_current_cat_sections, demux_Print, NULL,
2622 i_print_type );
2623 if ( i_print_type == PRINT_XML )
2624 fprintf(print_fh, "\n");
2627 out_cat:
2628 return;
2631 /*****************************************************************************
2632 * HandleCATSection
2633 *****************************************************************************/
2634 static void HandleCATSection( uint16_t i_pid, uint8_t *p_section,
2635 mtime_t i_dts )
2637 if ( i_pid != CAT_PID || !cat_validate( p_section ) )
2639 msg_Warn( NULL, "invalid CAT section received on PID %hu", i_pid );
2640 switch (i_print_type) {
2641 case PRINT_XML:
2642 fprintf(print_fh, "<ERROR type=\"invalid_cat_section\"/>\n");
2643 break;
2644 case PRINT_TEXT:
2645 fprintf(print_fh, "error type: invalid_cat_section\n");
2646 break;
2647 default:
2648 break;
2650 free( p_section );
2651 return;
2654 if ( !psi_table_section( pp_next_cat_sections, p_section ) )
2655 return;
2657 HandleCAT( i_dts );
2660 static void mark_pmt_pids( uint8_t *p_pmt, uint8_t pid_map[], uint8_t marker )
2662 uint16_t j, k;
2663 uint8_t *p_es;
2664 uint8_t *p_desc;
2666 uint16_t i_pcr_pid = pmt_get_pcrpid( p_pmt );
2668 if ( b_enable_ecm )
2670 j = 0;
2671 while ( (p_desc = descs_get_desc( pmt_get_descs( p_pmt ), j++ )) != NULL )
2673 if ( desc_get_tag( p_desc ) != 0x09 || !desc09_validate( p_desc ) )
2674 continue;
2675 pid_map[ desc09_get_pid( p_desc ) ] |= marker;
2679 if ( i_pcr_pid != PADDING_PID )
2680 pid_map[ i_pcr_pid ] |= marker;
2682 j = 0;
2683 while ( (p_es = pmt_get_es( p_pmt, j )) != NULL )
2685 uint16_t i_pid = pmtn_get_pid( p_es );
2686 j++;
2688 if ( PIDWouldBeSelected( p_es ) )
2689 pid_map[ i_pid ] |= marker;
2691 p_pids[i_pid].b_pes = PIDCarriesPES( p_es );
2693 if ( b_enable_ecm )
2695 k = 0;
2696 while ( (p_desc = descs_get_desc( pmtn_get_descs( p_es ), k++ )) != NULL )
2698 if ( desc_get_tag( p_desc ) != 0x09 || !desc09_validate( p_desc ) )
2699 continue;
2700 pid_map[ desc09_get_pid( p_desc ) ] |= marker;
2706 /*****************************************************************************
2707 * HandlePMT
2708 *****************************************************************************/
2709 static void HandlePMT( uint16_t i_pid, uint8_t *p_pmt, mtime_t i_dts )
2711 uint16_t i_sid = pmt_get_program( p_pmt );
2712 sid_t *p_sid;
2713 bool b_needs_descrambling, b_needed_descrambling, b_is_selected;
2714 uint8_t pid_map[MAX_PIDS];
2716 p_sid = FindSID( i_sid );
2717 if ( p_sid == NULL )
2719 /* Unwanted SID (happens when the same PMT PID is used for several
2720 * programs). */
2721 free( p_pmt );
2722 return;
2725 if ( i_pid != p_sid->i_pmt_pid )
2727 msg_Warn( NULL, "invalid PMT section received on PID %hu", i_pid );
2728 switch (i_print_type) {
2729 case PRINT_XML:
2730 fprintf(print_fh, "<ERROR type=\"ghost_pmt\" program=\"%hu\n pid=\"%hu\"/>\n",
2731 i_sid, i_pid);
2732 break;
2733 case PRINT_TEXT:
2734 fprintf(print_fh, "error type: ghost_pmt program: %hu pid: %hu\n",
2735 i_sid, i_pid);
2736 break;
2737 default:
2738 break;
2740 free( p_pmt );
2741 return;
2744 if ( p_sid->p_current_pmt != NULL &&
2745 psi_compare( p_sid->p_current_pmt, p_pmt ) )
2747 /* Identical PMT. Shortcut. */
2748 free( p_pmt );
2749 goto out_pmt;
2752 if ( !pmt_validate( p_pmt ) )
2754 msg_Warn( NULL, "invalid PMT section received on PID %hu", i_pid );
2755 switch (i_print_type) {
2756 case PRINT_XML:
2757 fprintf(print_fh, "<ERROR type=\"invalid_pmt_section\" pid=\"%hu\"/>\n",
2758 i_pid);
2759 break;
2760 case PRINT_TEXT:
2761 fprintf(print_fh, "error type: invalid_pmt_section pid: %hu\n",
2762 i_pid);
2763 break;
2764 default:
2765 break;
2767 free( p_pmt );
2768 goto out_pmt;
2771 memset( pid_map, 0, sizeof(pid_map) );
2773 b_needs_descrambling = PMTNeedsDescrambling( p_pmt );
2774 b_needed_descrambling = p_sid->p_current_pmt != NULL ?
2775 PMTNeedsDescrambling( p_sid->p_current_pmt ) :
2776 false;
2777 b_is_selected = SIDIsSelected( i_sid );
2779 if ( i_ca_handle && b_is_selected &&
2780 !b_needs_descrambling && b_needed_descrambling )
2781 en50221_DeletePMT( p_sid->p_current_pmt );
2783 if ( p_sid->p_current_pmt != NULL )
2785 mark_pmt_pids( p_sid->p_current_pmt, pid_map, 0x02 );
2786 free( p_sid->p_current_pmt );
2789 mark_pmt_pids( p_pmt, pid_map, 0x01 );
2791 uint16_t i_pcr_pid = pmt_get_pcrpid( p_pmt );
2792 int i;
2793 for ( i = 0; i < i_nb_outputs; i++ )
2794 if ( (pp_outputs[i]->config.i_config & OUTPUT_VALID)
2795 && pp_outputs[i]->config.i_sid == i_sid )
2796 pp_outputs[i]->i_pcr_pid = 0;
2798 /* Start to stream PIDs */
2799 int pid;
2800 for ( pid = 0; pid < MAX_PIDS; pid++ )
2802 /* The pid does not exist in the old PMT and in the new PMT. Ignore this pid. */
2803 if ( !pid_map[ pid ] )
2804 continue;
2806 switch ( pid_map[ pid ] & 0x03 ) {
2807 case 0x03: /* The pid exists in the old PMT and in the new PMT. The pid was already selected in case 0x01. */
2808 continue;
2809 case 0x02: /* The pid does not exist in the new PMT but exists in the old PMT. Unselect it. */
2810 UnselectPID( i_sid, pid );
2811 break;
2812 case 0x01: /* The pid exists in new PMT. Select it. */
2813 SelectPID( i_sid, pid, pid == i_pcr_pid );
2814 break;
2818 p_sid->p_current_pmt = p_pmt;
2820 if ( i_ca_handle && b_is_selected )
2822 if ( b_needs_descrambling && !b_needed_descrambling )
2823 en50221_AddPMT( p_pmt );
2824 else if ( b_needs_descrambling && b_needed_descrambling )
2825 en50221_UpdatePMT( p_pmt );
2828 UpdatePMT( i_sid );
2830 pmt_print( p_pmt, msg_Dbg, NULL, demux_Iconv, NULL, PRINT_TEXT );
2831 if ( b_print_enabled )
2833 pmt_print( p_pmt, demux_Print, NULL, demux_Iconv, NULL,
2834 i_print_type );
2835 if ( i_print_type == PRINT_XML )
2836 fprintf(print_fh, "\n");
2839 out_pmt:
2840 SendPMT( p_sid, i_dts );
2843 /*****************************************************************************
2844 * HandleNIT
2845 *****************************************************************************/
2846 static void HandleNIT( mtime_t i_dts )
2848 if ( psi_table_validate( pp_current_nit_sections ) &&
2849 psi_table_compare( pp_current_nit_sections, pp_next_nit_sections ) )
2851 /* Identical NIT. Shortcut. */
2852 psi_table_free( pp_next_nit_sections );
2853 psi_table_init( pp_next_nit_sections );
2854 goto out_nit;
2857 if ( !nit_table_validate( pp_next_nit_sections ) )
2859 msg_Warn( NULL, "invalid NIT received" );
2860 switch (i_print_type) {
2861 case PRINT_XML:
2862 fprintf(print_fh, "<ERROR type=\"invalid_nit\"/>\n");
2863 break;
2864 case PRINT_TEXT:
2865 fprintf(print_fh, "error type: invalid_nit\n");
2866 break;
2867 default:
2868 break;
2870 psi_table_free( pp_next_nit_sections );
2871 psi_table_init( pp_next_nit_sections );
2872 goto out_nit;
2875 /* Switch tables. */
2876 psi_table_free( pp_current_nit_sections );
2877 psi_table_copy( pp_current_nit_sections, pp_next_nit_sections );
2878 psi_table_init( pp_next_nit_sections );
2880 nit_table_print( pp_current_nit_sections, msg_Dbg, NULL,
2881 demux_Iconv, NULL, PRINT_TEXT );
2882 if ( b_print_enabled )
2884 nit_table_print( pp_current_nit_sections, demux_Print, NULL,
2885 demux_Iconv, NULL, i_print_type );
2886 if ( i_print_type == PRINT_XML )
2887 fprintf(print_fh, "\n");
2890 out_nit:
2894 /*****************************************************************************
2895 * HandleNITSection
2896 *****************************************************************************/
2897 static void HandleNITSection( uint16_t i_pid, uint8_t *p_section,
2898 mtime_t i_dts )
2900 if ( i_pid != NIT_PID || !nit_validate( p_section ) )
2902 msg_Warn( NULL, "invalid NIT section received on PID %hu", i_pid );
2903 switch (i_print_type) {
2904 case PRINT_XML:
2905 fprintf(print_fh, "<ERROR type=\"invalid_nit_section\" pid=\"%hu\"/>\n",
2906 i_pid);
2907 break;
2908 case PRINT_TEXT:
2909 fprintf(print_fh, "error type: invalid_nit_section pid: %hu\n",
2910 i_pid);
2911 break;
2912 default:
2913 break;
2915 free( p_section );
2916 return;
2919 if ( psi_table_section( pp_next_nit_sections, p_section ) )
2920 HandleNIT( i_dts );
2922 /* This case is different because DVB specifies a minimum bitrate for
2923 * PID 0x10, even if we don't have any thing to send (for cheap
2924 * transport over network boundaries). */
2925 SendNIT( i_dts );
2929 /*****************************************************************************
2930 * HandleSDT
2931 *****************************************************************************/
2932 static void HandleSDT( mtime_t i_dts )
2934 PSI_TABLE_DECLARE( pp_old_sdt_sections );
2935 uint8_t i_last_section = psi_table_get_lastsection( pp_next_sdt_sections );
2936 uint8_t i;
2937 int j;
2939 if ( psi_table_validate( pp_current_sdt_sections ) &&
2940 psi_table_compare( pp_current_sdt_sections, pp_next_sdt_sections ) )
2942 /* Identical SDT. Shortcut. */
2943 psi_table_free( pp_next_sdt_sections );
2944 psi_table_init( pp_next_sdt_sections );
2945 goto out_sdt;
2948 if ( !sdt_table_validate( pp_next_sdt_sections ) )
2950 msg_Warn( NULL, "invalid SDT received" );
2951 switch (i_print_type) {
2952 case PRINT_XML:
2953 fprintf(print_fh, "<ERROR type=\"invalid_sdt\"/>\n");
2954 break;
2955 case PRINT_TEXT:
2956 fprintf(print_fh, "error type: invalid_sdt\n");
2957 break;
2958 default:
2959 break;
2961 psi_table_free( pp_next_sdt_sections );
2962 psi_table_init( pp_next_sdt_sections );
2963 goto out_sdt;
2966 /* Switch tables. */
2967 psi_table_copy( pp_old_sdt_sections, pp_current_sdt_sections );
2968 psi_table_copy( pp_current_sdt_sections, pp_next_sdt_sections );
2969 psi_table_init( pp_next_sdt_sections );
2971 for ( i = 0; i <= i_last_section; i++ )
2973 uint8_t *p_section =
2974 psi_table_get_section( pp_current_sdt_sections, i );
2975 uint8_t *p_service;
2976 j = 0;
2978 while ( (p_service = sdt_get_service( p_section, j )) != NULL )
2980 uint16_t i_sid = sdtn_get_sid( p_service );
2981 j++;
2983 UpdateSDT( i_sid );
2987 if ( psi_table_validate( pp_old_sdt_sections ) )
2989 i_last_section = psi_table_get_lastsection( pp_old_sdt_sections );
2990 for ( i = 0; i <= i_last_section; i++ )
2992 uint8_t *p_section =
2993 psi_table_get_section( pp_old_sdt_sections, i );
2994 const uint8_t *p_service;
2995 int j = 0;
2997 while ( (p_service = sdt_get_service( p_section, j )) != NULL )
2999 uint16_t i_sid = sdtn_get_sid( p_service );
3000 j++;
3002 if ( sdt_table_find_service( pp_current_sdt_sections, i_sid )
3003 == NULL )
3004 UpdateSDT( i_sid );
3008 psi_table_free( pp_old_sdt_sections );
3011 sdt_table_print( pp_current_sdt_sections, msg_Dbg, NULL,
3012 demux_Iconv, NULL, PRINT_TEXT );
3013 if ( b_print_enabled )
3015 sdt_table_print( pp_current_sdt_sections, demux_Print, NULL,
3016 demux_Iconv, NULL, i_print_type );
3017 if ( i_print_type == PRINT_XML )
3018 fprintf(print_fh, "\n");
3021 out_sdt:
3022 SendSDT( i_dts );
3025 /*****************************************************************************
3026 * HandleSDTSection
3027 *****************************************************************************/
3028 static void HandleSDTSection( uint16_t i_pid, uint8_t *p_section,
3029 mtime_t i_dts )
3031 if ( i_pid != SDT_PID || !sdt_validate( p_section ) )
3033 msg_Warn( NULL, "invalid SDT section received on PID %hu", i_pid );
3034 switch (i_print_type) {
3035 case PRINT_XML:
3036 fprintf(print_fh, "<ERROR type=\"invalid_sdt_section\" pid=\"%hu\"/>\n",
3037 i_pid);
3038 break;
3039 case PRINT_TEXT:
3040 fprintf(print_fh, "error type: invalid_sdt_section pid: %hu\n",
3041 i_pid);
3042 break;
3043 default:
3044 break;
3046 free( p_section );
3047 return;
3050 if ( !psi_table_section( pp_next_sdt_sections, p_section ) )
3051 return;
3053 HandleSDT( i_dts );
3056 /*****************************************************************************
3057 * HandleEITSection
3058 *****************************************************************************/
3059 static void HandleEIT( uint16_t i_pid, uint8_t *p_eit, mtime_t i_dts )
3061 uint8_t i_table_id = psi_get_tableid( p_eit );
3062 uint16_t i_sid = eit_get_sid( p_eit );
3063 sid_t *p_sid;
3065 p_sid = FindSID( i_sid );
3066 if ( p_sid == NULL )
3068 /* Not a selected program. */
3069 free( p_eit );
3070 return;
3073 if ( i_pid != EIT_PID || !eit_validate( p_eit ) )
3075 msg_Warn( NULL, "invalid EIT section received on PID %hu", i_pid );
3076 switch (i_print_type) {
3077 case PRINT_XML:
3078 fprintf(print_fh, "<ERROR type=\"invalid_eit_section\" pid=\"%hu\"/>\n",
3079 i_pid);
3080 break;
3081 case PRINT_TEXT:
3082 fprintf(print_fh, "error type: invalid_eit_section pid: %hu\n",
3083 i_pid);
3084 break;
3085 default:
3086 break;
3088 free( p_eit );
3089 return;
3092 /* We do not use psi_table_* primitives as the spec allows for holes in
3093 * section numbering, and there is no sure way to know whether you have
3094 * gathered all sections. */
3095 uint8_t i_section = psi_get_section(p_eit);
3096 uint8_t eit_table_id = i_table_id - EIT_TABLE_ID_PF_ACTUAL;
3097 if (eit_table_id >= MAX_EIT_TABLES)
3098 goto out_eit; /* can't happen */
3099 if (p_sid->eit_table[eit_table_id].data[i_section] != NULL &&
3100 psi_compare(p_sid->eit_table[eit_table_id].data[i_section], p_eit)) {
3101 /* Identical section. Shortcut. */
3102 free(p_sid->eit_table[eit_table_id].data[i_section]);
3103 p_sid->eit_table[eit_table_id].data[i_section] = p_eit;
3104 goto out_eit;
3107 free(p_sid->eit_table[eit_table_id].data[i_section]);
3108 p_sid->eit_table[eit_table_id].data[i_section] = p_eit;
3110 if ( b_print_enabled && psi_get_tableid( p_eit ) == EIT_TABLE_ID_PF_ACTUAL )
3112 eit_print( p_eit, demux_Print, NULL,
3113 demux_Iconv, NULL, i_print_type );
3114 if ( i_print_type == PRINT_XML )
3115 fprintf(print_fh, "\n");
3118 out_eit:
3119 SendEIT( p_sid, i_dts, p_eit );
3122 /*****************************************************************************
3123 * HandleSection
3124 *****************************************************************************/
3125 static void HandleSection( uint16_t i_pid, uint8_t *p_section, mtime_t i_dts )
3127 uint8_t i_table_id = psi_get_tableid( p_section );
3129 if ( !psi_validate( p_section ) )
3131 msg_Warn( NULL, "invalid section on PID %hu", i_pid );
3132 switch (i_print_type) {
3133 case PRINT_XML:
3134 fprintf(print_fh, "<ERROR type=\"invalid_section\" pid=\"%hu\"/>\n", i_pid);
3135 break;
3136 case PRINT_TEXT:
3137 fprintf(print_fh, "error type: invalid_section pid: %hu\n", i_pid);
3138 break;
3139 default:
3140 break;
3142 free( p_section );
3143 return;
3146 if ( !psi_get_current( p_section ) )
3148 /* Ignore sections which are not in use yet. */
3149 free( p_section );
3150 return;
3153 switch ( i_table_id )
3155 case PAT_TABLE_ID:
3156 HandlePATSection( i_pid, p_section, i_dts );
3157 break;
3159 case CAT_TABLE_ID:
3160 if ( b_enable_emm )
3161 HandleCATSection( i_pid, p_section, i_dts );
3162 break;
3164 case PMT_TABLE_ID:
3165 HandlePMT( i_pid, p_section, i_dts );
3166 break;
3168 case NIT_TABLE_ID_ACTUAL:
3169 HandleNITSection( i_pid, p_section, i_dts );
3170 break;
3172 case SDT_TABLE_ID_ACTUAL:
3173 HandleSDTSection( i_pid, p_section, i_dts );
3174 break;
3176 default:
3177 if ( IsEITpf( i_table_id ) || IsEPG( i_table_id ) )
3179 HandleEIT( i_pid, p_section, i_dts );
3180 break;
3182 free( p_section );
3183 break;
3187 /*****************************************************************************
3188 * HandlePSIPacket
3189 *****************************************************************************/
3190 static void HandlePSIPacket( uint8_t *p_ts, mtime_t i_dts )
3192 uint16_t i_pid = ts_get_pid( p_ts );
3193 ts_pid_t *p_pid = &p_pids[i_pid];
3194 uint8_t i_cc = ts_get_cc( p_ts );
3195 const uint8_t *p_payload;
3196 uint8_t i_length;
3198 if ( ts_check_duplicate( i_cc, p_pid->i_last_cc )
3199 || !ts_has_payload( p_ts ) )
3200 return;
3202 if ( p_pid->i_last_cc != -1
3203 && ts_check_discontinuity( i_cc, p_pid->i_last_cc ) )
3204 psi_assemble_reset( &p_pid->p_psi_buffer, &p_pid->i_psi_buffer_used );
3206 p_payload = ts_section( p_ts );
3207 i_length = p_ts + TS_SIZE - p_payload;
3209 if ( !psi_assemble_empty( &p_pid->p_psi_buffer,
3210 &p_pid->i_psi_buffer_used ) )
3212 uint8_t *p_section = psi_assemble_payload( &p_pid->p_psi_buffer,
3213 &p_pid->i_psi_buffer_used,
3214 &p_payload, &i_length );
3215 if ( p_section != NULL )
3216 HandleSection( i_pid, p_section, i_dts );
3219 p_payload = ts_next_section( p_ts );
3220 i_length = p_ts + TS_SIZE - p_payload;
3222 while ( i_length )
3224 uint8_t *p_section = psi_assemble_payload( &p_pid->p_psi_buffer,
3225 &p_pid->i_psi_buffer_used,
3226 &p_payload, &i_length );
3227 if ( p_section != NULL )
3228 HandleSection( i_pid, p_section, i_dts );
3232 /*****************************************************************************
3233 * PID info functions
3234 *****************************************************************************/
3235 static const char *h222_stream_type_desc(uint8_t i_stream_type) {
3236 /* See ISO/IEC 13818-1 : 2000 (E) | Table 2-29 - Stream type assignments, Page 66 (48) */
3237 if (i_stream_type == 0)
3238 return "Reserved stream";
3239 switch (i_stream_type) {
3240 case 0x01: return "11172-2 video (MPEG-1)";
3241 case 0x02: return "H.262/13818-2 video (MPEG-2) or 11172-2 constrained video";
3242 case 0x03: return "11172-3 audio (MPEG-1)";
3243 case 0x04: return "13818-3 audio (MPEG-2)";
3244 case 0x05: return "H.222.0/13818-1 private sections";
3245 case 0x06: return "H.222.0/13818-1 PES private data";
3246 case 0x07: return "13522 MHEG";
3247 case 0x08: return "H.222.0/13818-1 Annex A - DSM CC";
3248 case 0x09: return "H.222.1";
3249 case 0x0A: return "13818-6 type A";
3250 case 0x0B: return "13818-6 type B";
3251 case 0x0C: return "13818-6 type C";
3252 case 0x0D: return "13818-6 type D";
3253 case 0x0E: return "H.222.0/13818-1 auxiliary";
3254 case 0x0F: return "13818-7 Audio with ADTS transport syntax";
3255 case 0x10: return "14496-2 Visual (MPEG-4 part 2 video)";
3256 case 0x11: return "14496-3 Audio with LATM transport syntax (14496-3/AMD 1)";
3257 case 0x12: return "14496-1 SL-packetized or FlexMux stream in PES packets";
3258 case 0x13: return "14496-1 SL-packetized or FlexMux stream in 14496 sections";
3259 case 0x14: return "ISO/IEC 13818-6 Synchronized Download Protocol";
3260 case 0x15: return "Metadata in PES packets";
3261 case 0x16: return "Metadata in metadata_sections";
3262 case 0x17: return "Metadata in 13818-6 Data Carousel";
3263 case 0x18: return "Metadata in 13818-6 Object Carousel";
3264 case 0x19: return "Metadata in 13818-6 Synchronized Download Protocol";
3265 case 0x1A: return "13818-11 MPEG-2 IPMP stream";
3266 case 0x1B: return "H.264/14496-10 video (MPEG-4/AVC)";
3267 case 0x24: return "H.265/23008-2 video (HEVC)";
3268 case 0x42: return "AVS Video";
3269 case 0x7F: return "IPMP stream";
3270 default : return "Unknown stream";
3274 static const char *get_pid_desc(uint16_t i_pid, uint16_t *i_sid) {
3275 int i, j, k;
3276 uint8_t i_last_section;
3277 uint8_t *p_desc;
3278 uint16_t i_nit_pid = NIT_PID, i_pcr_pid = 0;
3280 /* Simple cases */
3281 switch (i_pid)
3283 case 0x00: return "PAT";
3284 case 0x01: return "CAT";
3285 case 0x11: return "SDT";
3286 case 0x12: return "EPG";
3287 case 0x14: return "TDT/TOT";
3290 /* Detect NIT pid */
3291 if ( psi_table_validate( pp_current_pat_sections ) )
3293 i_last_section = psi_table_get_lastsection( pp_current_pat_sections );
3294 for ( i = 0; i <= i_last_section; i++ )
3296 uint8_t *p_section = psi_table_get_section( pp_current_pat_sections, i );
3297 uint8_t *p_program;
3299 j = 0;
3300 while ( (p_program = pat_get_program( p_section, j++ )) != NULL )
3302 /* Programs with PID == 0 are actually NIT */
3303 if ( patn_get_program( p_program ) == 0 )
3305 i_nit_pid = patn_get_pid( p_program );
3306 break;
3312 /* Detect EMM pids */
3313 if ( b_enable_emm && psi_table_validate( pp_current_cat_sections ) )
3315 i_last_section = psi_table_get_lastsection( pp_current_cat_sections );
3316 for ( i = 0; i <= i_last_section; i++ )
3318 uint8_t *p_section = psi_table_get_section( pp_current_cat_sections, i );
3320 j = 0;
3321 while ( (p_desc = descl_get_desc( cat_get_descl(p_section), cat_get_desclength(p_section), j++ )) != NULL )
3323 if ( desc_get_tag( p_desc ) != 0x09 || !desc09_validate( p_desc ) )
3324 continue;
3326 if ( desc09_get_pid( p_desc ) == i_pid ) {
3327 return "EMM";
3333 /* Detect streams in PMT */
3334 for ( k = 0; k < i_nb_sids; k++ )
3336 sid_t *p_sid = pp_sids[k];
3337 if ( p_sid->i_pmt_pid == i_pid )
3339 if ( i_sid )
3340 *i_sid = p_sid->i_sid;
3341 return "PMT";
3344 if ( p_sid->i_sid && p_sid->p_current_pmt != NULL )
3346 uint8_t *p_current_pmt = p_sid->p_current_pmt;
3347 uint8_t *p_current_es;
3349 /* The PCR PID can be alone or PCR can be carried in some other PIDs (mostly video)
3350 so just remember the pid and if it is alone it will be reported as PCR, otherwise
3351 stream type of the PID will be reported */
3352 if ( i_pid == pmt_get_pcrpid( p_current_pmt ) ) {
3353 if ( i_sid )
3354 *i_sid = p_sid->i_sid;
3355 i_pcr_pid = pmt_get_pcrpid( p_current_pmt );
3358 /* Look for ECMs */
3359 j = 0;
3360 while ((p_desc = descs_get_desc( pmt_get_descs( p_current_pmt ), j++ )) != NULL)
3362 if ( desc_get_tag( p_desc ) != 0x09 || !desc09_validate( p_desc ) )
3363 continue;
3365 if ( desc09_get_pid( p_desc ) == i_pid ) {
3366 if ( i_sid )
3367 *i_sid = p_sid->i_sid;
3368 return "ECM";
3372 /* Detect stream types */
3373 j = 0;
3374 while ( (p_current_es = pmt_get_es( p_current_pmt, j++ )) != NULL )
3376 if ( pmtn_get_pid( p_current_es ) == i_pid )
3378 if ( i_sid )
3379 *i_sid = p_sid->i_sid;
3380 return h222_stream_type_desc( pmtn_get_streamtype( p_current_es ) );
3386 /* Are there any other PIDs? */
3387 if (i_pid == i_nit_pid)
3388 return "NIT";
3390 if (i_pid == i_pcr_pid)
3391 return "PCR";
3393 return "...";
3396 /*****************************************************************************
3397 * Functions that return packed sections
3398 *****************************************************************************/
3399 uint8_t *demux_get_current_packed_PAT( unsigned int *pi_pack_size ) {
3400 return psi_pack_sections( pp_current_pat_sections, pi_pack_size );
3403 uint8_t *demux_get_current_packed_CAT( unsigned int *pi_pack_size ) {
3404 return psi_pack_sections( pp_current_cat_sections, pi_pack_size );
3407 uint8_t *demux_get_current_packed_NIT( unsigned int *pi_pack_size ) {
3408 return psi_pack_sections( pp_current_nit_sections, pi_pack_size );
3411 uint8_t *demux_get_current_packed_SDT( unsigned int *pi_pack_size ) {
3412 return psi_pack_sections( pp_current_sdt_sections, pi_pack_size );
3415 uint8_t *demux_get_packed_EIT( uint16_t i_sid, uint8_t start_table, uint8_t end_table, unsigned int *eit_size ) {
3416 unsigned int i, r;
3418 *eit_size = 0;
3419 sid_t *p_sid = FindSID( i_sid );
3420 if ( p_sid == NULL )
3421 return NULL;
3423 /* Calculate eit table size (sum of all sections in all tables between start_start and end_table) */
3424 for ( i = start_table; i <= end_table; i++ ) {
3425 uint8_t eit_table_idx = i - EIT_TABLE_ID_PF_ACTUAL;
3426 if ( eit_table_idx >= MAX_EIT_TABLES )
3427 continue;
3428 uint8_t **eit_sections = p_sid->eit_table[eit_table_idx].data;
3429 for ( r = 0; r < PSI_TABLE_MAX_SECTIONS; r++ ) {
3430 uint8_t *p_eit = eit_sections[r];
3431 if ( !p_eit )
3432 continue;
3433 uint16_t psi_length = psi_get_length( p_eit ) + PSI_HEADER_SIZE;
3434 *eit_size += psi_length;
3438 uint8_t *p_flat_section = malloc( *eit_size );
3439 if ( !p_flat_section )
3440 return NULL;
3442 /* Copy sections */
3443 unsigned int i_pos = 0;
3444 for ( i = start_table; i <= end_table; i++ ) {
3445 uint8_t eit_table_idx = i - EIT_TABLE_ID_PF_ACTUAL;
3446 if ( eit_table_idx >= MAX_EIT_TABLES )
3447 continue;
3448 uint8_t **eit_sections = p_sid->eit_table[eit_table_idx].data;
3449 for ( r = 0; r < PSI_TABLE_MAX_SECTIONS; r++ ) {
3450 uint8_t *p_eit = eit_sections[r];
3451 if ( !p_eit )
3452 continue;
3453 uint16_t psi_length = psi_get_length( p_eit ) + PSI_HEADER_SIZE;
3454 memcpy( p_flat_section + i_pos, p_eit, psi_length );
3455 i_pos += psi_length;
3456 /* eit_print( p_eit, msg_Dbg, NULL, demux_Iconv, NULL, PRINT_TEXT ); */
3459 return p_flat_section;
3462 uint8_t *demux_get_packed_EIT_pf( uint16_t service_id, unsigned int *pi_pack_size ) {
3463 return demux_get_packed_EIT( service_id, EIT_TABLE_ID_PF_ACTUAL, EIT_TABLE_ID_PF_ACTUAL, pi_pack_size );
3466 uint8_t *demux_get_packed_EIT_schedule( uint16_t service_id, unsigned int *pi_pack_size ) {
3467 return demux_get_packed_EIT( service_id, EIT_TABLE_ID_SCHED_ACTUAL_FIRST, EIT_TABLE_ID_SCHED_ACTUAL_LAST, pi_pack_size );
3470 uint8_t *demux_get_packed_PMT( uint16_t i_sid, unsigned int *pi_pack_size ) {
3471 sid_t *p_sid = FindSID( i_sid );
3472 if ( p_sid != NULL && p_sid->p_current_pmt && pmt_validate( p_sid->p_current_pmt ) )
3473 return psi_pack_section( p_sid->p_current_pmt, pi_pack_size );
3474 return NULL;
3477 inline void demux_get_PID_info( uint16_t i_pid, uint8_t *p_data ) {
3478 ts_pid_info_t *p_info = (ts_pid_info_t *)p_data;
3479 *p_info = p_pids[i_pid].info;
3482 inline void demux_get_PIDS_info( uint8_t *p_data ) {
3483 int i_pid;
3484 for (i_pid = 0; i_pid < MAX_PIDS; i_pid++ )
3485 demux_get_PID_info( i_pid, p_data + ( i_pid * sizeof(ts_pid_info_t) ) );