Print bitrate status for each service
[dvblast.git] / demux.c
blob4d22a622993f861d78e447795c4b5475284c72af
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 handle_epg( int i_table_id )
1481 return (i_table_id == EIT_TABLE_ID_PF_ACTUAL ||
1482 (i_table_id >= EIT_TABLE_ID_SCHED_ACTUAL_FIRST &&
1483 i_table_id <= EIT_TABLE_ID_SCHED_ACTUAL_LAST));
1486 static void SendEIT( sid_t *p_sid, mtime_t i_dts, uint8_t *p_eit )
1488 uint8_t i_table_id = psi_get_tableid( p_eit );
1489 bool b_epg = handle_epg( i_table_id );
1490 uint16_t i_onid = eit_get_onid(p_eit);
1491 int i;
1493 for ( i = 0; i < i_nb_outputs; i++ )
1495 output_t *p_output = pp_outputs[i];
1497 if ( (p_output->config.i_config & OUTPUT_VALID)
1498 && !p_output->config.b_passthrough
1499 && (p_output->config.i_config & OUTPUT_DVB)
1500 && (!b_epg || (p_output->config.i_config & OUTPUT_EPG))
1501 && p_output->config.i_sid == p_sid->i_sid )
1503 eit_set_tsid( p_eit, p_output->i_tsid );
1505 if ( p_output->config.i_new_sid )
1506 eit_set_sid( p_eit, p_output->config.i_new_sid );
1507 else
1508 eit_set_sid( p_eit, p_output->config.i_sid );
1510 if ( p_output->config.i_onid )
1511 eit_set_onid( p_eit, p_output->config.i_onid );
1513 psi_set_crc( p_eit );
1515 OutputPSISection( p_output, p_eit, EIT_PID, &p_output->i_eit_cc,
1516 i_dts, &p_output->p_eit_ts_buffer,
1517 &p_output->i_eit_ts_buffer_offset );
1519 if ( p_output->config.i_onid )
1520 eit_set_onid( p_eit, i_onid );
1525 /*****************************************************************************
1526 * FlushEIT
1527 *****************************************************************************/
1528 static void FlushEIT( output_t *p_output, mtime_t i_dts )
1530 block_t *p_block = p_output->p_eit_ts_buffer;
1532 psi_split_end( p_block->p_ts, &p_output->i_eit_ts_buffer_offset );
1533 p_block->i_dts = i_dts;
1534 p_block->i_refcount--;
1535 output_Put( p_output, p_block );
1536 p_output->p_eit_ts_buffer = NULL;
1537 p_output->i_eit_ts_buffer_offset = 0;
1540 /*****************************************************************************
1541 * SendTDT
1542 *****************************************************************************/
1543 static void SendTDT( block_t *p_ts )
1545 int i;
1547 for ( i = 0; i < i_nb_outputs; i++ )
1549 output_t *p_output = pp_outputs[i];
1551 if ( (p_output->config.i_config & OUTPUT_VALID)
1552 && !p_output->config.b_passthrough
1553 && (p_output->config.i_config & OUTPUT_DVB)
1554 && p_output->p_sdt_section != NULL )
1555 output_Put( p_output, p_ts );
1558 /*****************************************************************************
1559 * SendEMM
1560 *****************************************************************************/
1561 static void SendEMM( block_t *p_ts )
1563 int i;
1565 for ( i = 0; i < i_nb_outputs; i++ )
1567 output_t *p_output = pp_outputs[i];
1569 if ( (p_output->config.i_config & OUTPUT_VALID)
1570 && !p_output->config.b_passthrough )
1571 output_Put( p_output, p_ts );
1575 /*****************************************************************************
1576 * NewPAT
1577 *****************************************************************************/
1578 static void NewPAT( output_t *p_output )
1580 const uint8_t *p_program;
1581 uint8_t *p;
1582 uint8_t k = 0;
1584 free( p_output->p_pat_section );
1585 p_output->p_pat_section = NULL;
1586 p_output->i_pat_version++;
1588 if ( !p_output->config.i_sid ) return;
1589 if ( !psi_table_validate(pp_current_pat_sections) ) return;
1591 p_program = pat_table_find_program( pp_current_pat_sections,
1592 p_output->config.i_sid );
1593 if ( p_program == NULL ) return;
1595 p = p_output->p_pat_section = psi_allocate();
1596 pat_init( p );
1597 psi_set_length( p, PSI_MAX_SIZE );
1598 pat_set_tsid( p, p_output->i_tsid );
1599 psi_set_version( p, p_output->i_pat_version );
1600 psi_set_current( p );
1601 psi_set_section( p, 0 );
1602 psi_set_lastsection( p, 0 );
1604 if ( p_output->config.i_config & OUTPUT_DVB )
1606 /* NIT */
1607 p = pat_get_program( p_output->p_pat_section, k++ );
1608 patn_init( p );
1609 patn_set_program( p, 0 );
1610 patn_set_pid( p, NIT_PID );
1613 p = pat_get_program( p_output->p_pat_section, k++ );
1614 patn_init( p );
1615 if ( p_output->config.i_new_sid )
1617 msg_Dbg( NULL, "Mapping PAT SID %d to %d", p_output->config.i_sid,
1618 p_output->config.i_new_sid );
1619 patn_set_program( p, p_output->config.i_new_sid );
1621 else
1622 patn_set_program( p, p_output->config.i_sid );
1624 if ( b_do_remap )
1626 msg_Dbg( NULL, "Mapping PMT PID %d to %d", patn_get_pid( p_program ), pi_newpids[I_PMTPID] );
1627 patn_set_pid( p, pi_newpids[I_PMTPID]);
1628 } else if ( p_output->config.b_do_remap && p_output->config.pi_confpids[I_PMTPID] ) {
1629 msg_Dbg( NULL, "Mapping PMT PID %d to %d", patn_get_pid( p_program ), p_output->config.pi_confpids[I_PMTPID] );
1630 patn_set_pid( p, p_output->config.pi_confpids[I_PMTPID]);
1631 } else {
1632 patn_set_pid( p, patn_get_pid( p_program ) );
1635 p = pat_get_program( p_output->p_pat_section, k );
1636 pat_set_length( p_output->p_pat_section,
1637 p - p_output->p_pat_section - PAT_HEADER_SIZE );
1638 psi_set_crc( p_output->p_pat_section );
1641 /*****************************************************************************
1642 * NewPMT
1643 *****************************************************************************/
1644 static void CopyDescriptors( uint8_t *p_descs, uint8_t *p_current_descs )
1646 uint8_t *p_desc;
1647 const uint8_t *p_current_desc;
1648 uint16_t j = 0, k = 0;
1650 descs_set_length( p_descs, DESCS_MAX_SIZE );
1652 while ( (p_current_desc = descs_get_desc( p_current_descs, j )) != NULL )
1654 uint8_t i_tag = desc_get_tag( p_current_desc );
1656 j++;
1657 if ( !b_enable_ecm && i_tag == 0x9 ) continue;
1659 p_desc = descs_get_desc( p_descs, k );
1660 if ( p_desc == NULL ) continue; /* This shouldn't happen */
1661 k++;
1662 memcpy( p_desc, p_current_desc,
1663 DESC_HEADER_SIZE + desc_get_length( p_current_desc ) );
1666 p_desc = descs_get_desc( p_descs, k );
1667 if ( p_desc == NULL )
1668 /* This shouldn't happen if the incoming PMT is valid */
1669 descs_set_length( p_descs, 0 );
1670 else
1671 descs_set_length( p_descs, p_desc - p_descs - DESCS_HEADER_SIZE );
1674 static void NewPMT( output_t *p_output )
1676 sid_t *p_sid;
1677 uint8_t *p_current_pmt;
1678 uint8_t *p_es, *p_current_es;
1679 uint8_t *p;
1680 uint16_t j, k;
1681 uint16_t i_pcrpid;
1683 free( p_output->p_pmt_section );
1684 p_output->p_pmt_section = NULL;
1685 p_output->i_pmt_version++;
1687 if ( !p_output->config.i_sid ) return;
1689 p_sid = FindSID( p_output->config.i_sid );
1690 if ( p_sid == NULL ) return;
1692 if ( p_sid->p_current_pmt == NULL ) return;
1693 p_current_pmt = p_sid->p_current_pmt;
1695 p = p_output->p_pmt_section = psi_allocate();
1696 pmt_init( p );
1697 psi_set_length( p, PSI_MAX_SIZE );
1698 if ( p_output->config.i_new_sid )
1700 msg_Dbg( NULL, "Mapping PMT SID %d to %d", p_output->config.i_sid,
1701 p_output->config.i_new_sid );
1702 pmt_set_program( p, p_output->config.i_new_sid );
1704 else
1705 pmt_set_program( p, p_output->config.i_sid );
1706 psi_set_version( p, p_output->i_pmt_version );
1707 psi_set_current( p );
1708 pmt_set_desclength( p, 0 );
1709 init_pid_mapping( p_output );
1712 CopyDescriptors( pmt_get_descs( p ), pmt_get_descs( p_current_pmt ) );
1714 j = 0; k = 0;
1715 while ( (p_current_es = pmt_get_es( p_current_pmt, j )) != NULL )
1717 uint16_t i_pid = pmtn_get_pid( p_current_es );
1719 j++;
1720 if ( (p_output->config.i_nb_pids || !PIDWouldBeSelected( p_current_es ))
1721 && !IsIn( p_output->config.pi_pids, p_output->config.i_nb_pids,
1722 i_pid ) )
1723 continue;
1725 p_es = pmt_get_es( p, k );
1726 if ( p_es == NULL ) continue; /* This shouldn't happen */
1727 k++;
1728 pmtn_init( p_es );
1729 pmtn_set_streamtype( p_es, pmtn_get_streamtype( p_current_es ) );
1730 pmtn_set_pid( p_es, map_es_pid(p_output, p_current_es, i_pid) );
1731 pmtn_set_desclength( p_es, 0 );
1733 CopyDescriptors( pmtn_get_descs( p_es ),
1734 pmtn_get_descs( p_current_es ) );
1737 /* Do the pcr pid after everything else as it may have been remapped */
1738 i_pcrpid = pmt_get_pcrpid( p_current_pmt );
1739 if ( p_output->pi_newpids[i_pcrpid] != UNUSED_PID ) {
1740 msg_Dbg( NULL, "REMAP: The PCR PID was changed from 0x%x (%u) to 0x%x (%u)",
1741 i_pcrpid, i_pcrpid, p_output->pi_newpids[i_pcrpid], p_output->pi_newpids[i_pcrpid] );
1742 i_pcrpid = p_output->pi_newpids[i_pcrpid];
1743 } else {
1744 msg_Dbg( NULL, "The PCR PID has kept its original value of 0x%x (%u)", i_pcrpid, i_pcrpid);
1746 pmt_set_pcrpid( p, i_pcrpid );
1747 p_es = pmt_get_es( p, k );
1748 if ( p_es == NULL )
1749 /* This shouldn't happen if the incoming PMT is valid */
1750 pmt_set_length( p, 0 );
1751 else
1752 pmt_set_length( p, p_es - p - PMT_HEADER_SIZE );
1753 psi_set_crc( p );
1756 /*****************************************************************************
1757 * NewNIT
1758 *****************************************************************************/
1759 static void NewNIT( output_t *p_output )
1761 uint8_t *p_ts;
1762 uint8_t *p_header2;
1763 uint8_t *p;
1765 free( p_output->p_nit_section );
1766 p_output->p_nit_section = NULL;
1767 p_output->i_nit_version++;
1769 p = p_output->p_nit_section = psi_allocate();
1770 nit_init( p, true );
1771 nit_set_length( p, PSI_MAX_SIZE );
1772 nit_set_nid( p, p_output->config.i_network_id );
1773 psi_set_version( p, p_output->i_nit_version );
1774 psi_set_current( p );
1775 psi_set_section( p, 0 );
1776 psi_set_lastsection( p, 0 );
1778 if ( p_output->config.network_name.i )
1780 uint8_t *p_descs;
1781 uint8_t *p_desc;
1782 nit_set_desclength( p, DESCS_MAX_SIZE );
1783 p_descs = nit_get_descs( p );
1784 p_desc = descs_get_desc( p_descs, 0 );
1785 desc40_init( p_desc );
1786 desc40_set_networkname( p_desc, p_output->config.network_name.p,
1787 p_output->config.network_name.i );
1788 p_desc = descs_get_desc( p_descs, 1 );
1789 descs_set_length( p_descs, p_desc - p_descs - DESCS_HEADER_SIZE );
1791 else
1792 nit_set_desclength( p, 0 );
1794 p_header2 = nit_get_header2( p );
1795 nith_init( p_header2 );
1796 nith_set_tslength( p_header2, NIT_TS_SIZE );
1798 p_ts = nit_get_ts( p, 0 );
1799 nitn_init( p_ts );
1800 nitn_set_tsid( p_ts, p_output->i_tsid );
1801 if ( p_output->config.i_onid )
1802 nitn_set_onid( p_ts, p_output->config.i_onid );
1803 else
1804 nitn_set_onid( p_ts, p_output->config.i_network_id );
1805 nitn_set_desclength( p_ts, 0 );
1807 p_ts = nit_get_ts( p, 1 );
1808 if ( p_ts == NULL )
1809 /* This shouldn't happen */
1810 nit_set_length( p, 0 );
1811 else
1812 nit_set_length( p, p_ts - p - NIT_HEADER_SIZE );
1813 psi_set_crc( p_output->p_nit_section );
1816 /*****************************************************************************
1817 * NewSDT
1818 *****************************************************************************/
1819 static void NewSDT( output_t *p_output )
1821 uint8_t *p_service, *p_current_service;
1822 uint8_t *p;
1824 free( p_output->p_sdt_section );
1825 p_output->p_sdt_section = NULL;
1826 p_output->i_sdt_version++;
1828 if ( !p_output->config.i_sid ) return;
1829 if ( !psi_table_validate(pp_current_sdt_sections) ) return;
1831 p_current_service = sdt_table_find_service( pp_current_sdt_sections,
1832 p_output->config.i_sid );
1834 if ( p_current_service == NULL )
1836 if ( p_output->p_pat_section != NULL &&
1837 pat_get_program( p_output->p_pat_section, 0 ) == NULL )
1839 /* Empty PAT and no SDT anymore */
1840 free( p_output->p_pat_section );
1841 p_output->p_pat_section = NULL;
1842 p_output->i_pat_version++;
1844 return;
1847 p = p_output->p_sdt_section = psi_allocate();
1848 sdt_init( p, true );
1849 sdt_set_length( p, PSI_MAX_SIZE );
1850 sdt_set_tsid( p, p_output->i_tsid );
1851 psi_set_version( p, p_output->i_sdt_version );
1852 psi_set_current( p );
1853 psi_set_section( p, 0 );
1854 psi_set_lastsection( p, 0 );
1855 if ( p_output->config.i_onid )
1856 sdt_set_onid( p, p_output->config.i_onid );
1857 else
1858 sdt_set_onid( p,
1859 sdt_get_onid( psi_table_get_section( pp_current_sdt_sections, 0 ) ) );
1861 p_service = sdt_get_service( p, 0 );
1862 sdtn_init( p_service );
1863 if ( p_output->config.i_new_sid )
1865 msg_Dbg( NULL, "Mapping SDT SID %d to %d", p_output->config.i_sid,
1866 p_output->config.i_new_sid );
1867 sdtn_set_sid( p_service, p_output->config.i_new_sid );
1869 else
1870 sdtn_set_sid( p_service, p_output->config.i_sid );
1872 /* We always forward EITp/f */
1873 if ( sdtn_get_eitpresent(p_current_service) )
1874 sdtn_set_eitpresent(p_service);
1876 if ( (p_output->config.i_config & OUTPUT_EPG) == OUTPUT_EPG &&
1877 sdtn_get_eitschedule(p_current_service) )
1878 sdtn_set_eitschedule(p_service);
1880 sdtn_set_running( p_service, sdtn_get_running(p_current_service) );
1881 /* Do not set free_ca */
1882 sdtn_set_desclength( p_service, sdtn_get_desclength(p_current_service) );
1884 if ( !p_output->config.provider_name.i &&
1885 !p_output->config.service_name.i ) {
1886 /* Copy all descriptors unchanged */
1887 memcpy( descs_get_desc( sdtn_get_descs(p_service), 0 ),
1888 descs_get_desc( sdtn_get_descs(p_current_service), 0 ),
1889 sdtn_get_desclength(p_current_service) );
1890 } else {
1891 int j = 0, i_total_desc_len = 0;
1892 uint8_t *p_desc;
1893 uint8_t *p_new_desc = descs_get_desc( sdtn_get_descs(p_service), 0 );
1894 while ( (p_desc = descs_get_desc( sdtn_get_descs( p_current_service ), j++ )) != NULL )
1896 /* Regenerate descriptor 48 (service name) */
1897 if ( desc_get_tag( p_desc ) == 0x48 && desc48_validate( p_desc ) )
1899 uint8_t i_old_provider_len, i_old_service_len;
1900 uint8_t i_new_desc_len = 3; /* 1 byte - type, 1 byte provider_len, 1 byte service_len */
1901 const uint8_t *p_old_provider = desc48_get_provider( p_desc, &i_old_provider_len );
1902 const uint8_t *p_old_service = desc48_get_service( p_desc, &i_old_service_len );
1904 desc48_init( p_new_desc );
1905 desc48_set_type( p_new_desc, desc48_get_type( p_desc ) );
1907 if ( p_output->config.provider_name.i ) {
1908 desc48_set_provider( p_new_desc,
1909 p_output->config.provider_name.p,
1910 p_output->config.provider_name.i );
1911 i_new_desc_len += p_output->config.provider_name.i;
1912 } else {
1913 desc48_set_provider( p_new_desc, p_old_provider,
1914 i_old_provider_len );
1915 i_new_desc_len += i_old_provider_len;
1918 if ( p_output->config.service_name.i ) {
1919 desc48_set_service( p_new_desc,
1920 p_output->config.service_name.p,
1921 p_output->config.service_name.i );
1922 i_new_desc_len += p_output->config.service_name.i;
1923 } else {
1924 desc48_set_service( p_new_desc, p_old_service,
1925 i_old_service_len );
1926 i_new_desc_len += i_old_service_len;
1929 desc_set_length( p_new_desc, i_new_desc_len );
1930 i_total_desc_len += DESC_HEADER_SIZE + i_new_desc_len;
1931 p_new_desc += DESC_HEADER_SIZE + i_new_desc_len;
1932 } else {
1933 /* Copy single descriptor */
1934 int i_desc_len = DESC_HEADER_SIZE + desc_get_length( p_desc );
1935 memcpy( p_new_desc, p_desc, i_desc_len );
1936 p_new_desc += i_desc_len;
1937 i_total_desc_len += i_desc_len;
1940 sdtn_set_desclength( p_service, i_total_desc_len );
1943 p_service = sdt_get_service( p, 1 );
1944 if ( p_service == NULL )
1945 /* This shouldn't happen if the incoming SDT is valid */
1946 sdt_set_length( p, 0 );
1947 else
1948 sdt_set_length( p, p_service - p - SDT_HEADER_SIZE );
1949 psi_set_crc( p_output->p_sdt_section );
1952 /*****************************************************************************
1953 * UpdatePAT/PMT/SDT
1954 *****************************************************************************/
1955 #define DECLARE_UPDATE_FUNC( table ) \
1956 static void Update##table( uint16_t i_sid ) \
1958 int i; \
1960 for ( i = 0; i < i_nb_outputs; i++ ) \
1961 if ( ( pp_outputs[i]->config.i_config & OUTPUT_VALID ) \
1962 && pp_outputs[i]->config.i_sid == i_sid ) \
1963 New##table( pp_outputs[i] ); \
1966 DECLARE_UPDATE_FUNC(PAT)
1967 DECLARE_UPDATE_FUNC(PMT)
1968 DECLARE_UPDATE_FUNC(SDT)
1970 /*****************************************************************************
1971 * UpdateTSID
1972 *****************************************************************************/
1973 static void UpdateTSID(void)
1975 uint16_t i_tsid = psi_table_get_tableidext(pp_current_pat_sections);
1976 int i;
1978 for ( i = 0; i < i_nb_outputs; i++ )
1980 output_t *p_output = pp_outputs[i];
1982 if ( (p_output->config.i_config & OUTPUT_VALID)
1983 && p_output->config.i_tsid == -1 && !b_random_tsid )
1985 p_output->i_tsid = i_tsid;
1986 NewNIT( p_output );
1991 /*****************************************************************************
1992 * SIDIsSelected
1993 *****************************************************************************/
1994 static bool SIDIsSelected( uint16_t i_sid )
1996 int i;
1998 for ( i = 0; i < i_nb_outputs; i++ )
1999 if ( (pp_outputs[i]->config.i_config & OUTPUT_VALID)
2000 && pp_outputs[i]->config.i_sid == i_sid )
2001 return true;
2003 return false;
2006 /*****************************************************************************
2007 * demux_PIDIsSelected
2008 *****************************************************************************/
2009 bool demux_PIDIsSelected( uint16_t i_pid )
2011 int i;
2013 for ( i = 0; i < p_pids[i_pid].i_nb_outputs; i++ )
2014 if ( p_pids[i_pid].pp_outputs[i] != NULL )
2015 return true;
2017 return false;
2020 /*****************************************************************************
2021 * PIDWouldBeSelected
2022 *****************************************************************************/
2023 static bool PIDWouldBeSelected( uint8_t *p_es )
2025 if ( b_any_type ) return true;
2027 uint8_t i_type = pmtn_get_streamtype( p_es );
2029 switch ( i_type )
2031 case 0x1: /* video MPEG-1 */
2032 case 0x2: /* video */
2033 case 0x3: /* audio MPEG-1 */
2034 case 0x4: /* audio */
2035 case 0xf: /* audio AAC ADTS */
2036 case 0x10: /* video MPEG-4 */
2037 case 0x11: /* audio AAC LATM */
2038 case 0x1b: /* video H264 */
2039 case 0x24: /* video H265 */
2040 case 0x81: /* ATSC A/52 */
2041 case 0x87: /* ATSC Enhanced A/52 */
2042 return true;
2043 break;
2045 case 0x6:
2047 uint16_t j = 0;
2048 const uint8_t *p_desc;
2050 while ( (p_desc = descs_get_desc( pmtn_get_descs( p_es ), j )) != NULL )
2052 uint8_t i_tag = desc_get_tag( p_desc );
2053 j++;
2055 if( i_tag == 0x46 /* VBI + teletext */
2056 || i_tag == 0x56 /* teletext */
2057 || i_tag == 0x59 /* dvbsub */
2058 || i_tag == 0x6a /* A/52 */
2059 || i_tag == 0x7a /* Enhanced A/52 */
2060 || i_tag == 0x7b /* DCA */
2061 || i_tag == 0x7c /* AAC */ )
2062 return true;
2064 break;
2067 default:
2068 break;
2071 /* FIXME: also parse IOD */
2072 return false;
2075 /*****************************************************************************
2076 * PIDCarriesPES
2077 *****************************************************************************/
2078 static bool PIDCarriesPES( const uint8_t *p_es )
2080 uint8_t i_type = pmtn_get_streamtype( p_es );
2082 switch ( i_type )
2084 case 0x1: /* video MPEG-1 */
2085 case 0x2: /* video */
2086 case 0x3: /* audio MPEG-1 */
2087 case 0x4: /* audio */
2088 case 0x6: /* private PES data */
2089 case 0xf: /* audio AAC */
2090 case 0x10: /* video MPEG-4 */
2091 case 0x11: /* audio AAC LATM */
2092 case 0x1b: /* video H264 */
2093 case 0x24: /* video H265 */
2094 case 0x81: /* ATSC A/52 */
2095 case 0x87: /* ATSC Enhanced A/52 */
2096 return true;
2097 break;
2099 default:
2100 return false;
2101 break;
2105 /*****************************************************************************
2106 * PMTNeedsDescrambling
2107 *****************************************************************************/
2108 static bool PMTNeedsDescrambling( uint8_t *p_pmt )
2110 uint8_t i;
2111 uint16_t j;
2112 uint8_t *p_es;
2113 const uint8_t *p_desc;
2115 j = 0;
2116 while ( (p_desc = descs_get_desc( pmt_get_descs( p_pmt ), j )) != NULL )
2118 uint8_t i_tag = desc_get_tag( p_desc );
2119 j++;
2121 if ( i_tag == 0x9 ) return true;
2124 i = 0;
2125 while ( (p_es = pmt_get_es( p_pmt, i )) != NULL )
2127 i++;
2128 j = 0;
2129 while ( (p_desc = descs_get_desc( pmtn_get_descs( p_es ), j )) != NULL )
2131 uint8_t i_tag = desc_get_tag( p_desc );
2132 j++;
2134 if ( i_tag == 0x9 ) return true;
2138 return false;
2141 /*****************************************************************************
2142 * demux_ResendCAPMTs
2143 *****************************************************************************/
2144 void demux_ResendCAPMTs( void )
2146 int i;
2147 for ( i = 0; i < i_nb_sids; i++ )
2148 if ( pp_sids[i]->p_current_pmt != NULL
2149 && SIDIsSelected( pp_sids[i]->i_sid )
2150 && PMTNeedsDescrambling( pp_sids[i]->p_current_pmt ) )
2151 en50221_AddPMT( pp_sids[i]->p_current_pmt );
2154 /* Find CA descriptor that have PID i_ca_pid */
2155 static uint8_t *ca_desc_find( uint8_t *p_descl, uint16_t i_length,
2156 uint16_t i_ca_pid )
2158 int j = 0;
2159 uint8_t *p_desc;
2161 while ( (p_desc = descl_get_desc( p_descl, i_length, j++ )) != NULL ) {
2162 if ( desc_get_tag( p_desc ) != 0x09 || !desc09_validate( p_desc ) )
2163 continue;
2164 if ( desc09_get_pid( p_desc ) == i_ca_pid )
2165 return p_desc;
2168 return NULL;
2171 /*****************************************************************************
2172 * DeleteProgram
2173 *****************************************************************************/
2174 static void DeleteProgram( uint16_t i_sid, uint16_t i_pid )
2176 sid_t *p_sid;
2177 uint8_t *p_pmt;
2178 uint8_t *p_desc;
2180 UnselectPMT( i_sid, i_pid );
2182 p_sid = FindSID( i_sid );
2183 if ( p_sid == NULL ) return;
2185 p_pmt = p_sid->p_current_pmt;
2187 if ( p_pmt != NULL )
2189 uint16_t i_pcr_pid = pmt_get_pcrpid( p_pmt );
2190 uint8_t *p_es;
2191 uint8_t j;
2193 if ( i_ca_handle && SIDIsSelected( i_sid )
2194 && PMTNeedsDescrambling( p_pmt ) )
2195 en50221_DeletePMT( p_pmt );
2197 if ( i_pcr_pid != PADDING_PID
2198 && i_pcr_pid != p_sid->i_pmt_pid )
2199 UnselectPID( i_sid, i_pcr_pid );
2201 if ( b_enable_ecm )
2203 j = 0;
2205 while ((p_desc = descs_get_desc( pmt_get_descs( p_pmt ), j++ )) != NULL)
2207 if ( desc_get_tag( p_desc ) != 0x09 ||
2208 !desc09_validate( p_desc ) )
2209 continue;
2210 UnselectPID( i_sid, desc09_get_pid( p_desc ) );
2214 j = 0;
2215 while ( (p_es = pmt_get_es( p_pmt, j )) != NULL )
2217 uint16_t i_pid = pmtn_get_pid( p_es );
2218 j++;
2220 if ( PIDWouldBeSelected( p_es ) )
2221 UnselectPID( i_sid, i_pid );
2223 if ( b_enable_ecm )
2225 uint8_t k = 0;
2227 while ((p_desc = descs_get_desc( pmtn_get_descs( p_es ), k++ )) != NULL)
2229 if ( desc_get_tag( p_desc ) != 0x09 || !desc09_validate( p_desc ) )
2230 continue;
2231 UnselectPID( i_sid, desc09_get_pid( p_desc ) );
2236 free( p_pmt );
2237 p_sid->p_current_pmt = NULL;
2239 p_sid->i_sid = 0;
2240 p_sid->i_pmt_pid = 0;
2242 uint8_t r;
2243 for ( r = 0; r < MAX_EIT_TABLES; r++ ) {
2244 psi_table_free( p_sid->eit_table[r].data );
2245 psi_table_init( p_sid->eit_table[r].data );
2250 /*****************************************************************************
2251 * demux_Iconv
2252 *****************************************************************************
2253 * This code is from biTStream's examples and is under the WTFPL (see
2254 * LICENSE.WTFPL).
2255 *****************************************************************************/
2256 static char *iconv_append_null(const char *p_string, size_t i_length)
2258 char *psz_string = malloc(i_length + 1);
2259 memcpy(psz_string, p_string, i_length);
2260 psz_string[i_length] = '\0';
2261 return psz_string;
2264 char *demux_Iconv(void *_unused, const char *psz_encoding,
2265 char *p_string, size_t i_length)
2267 #ifdef HAVE_ICONV
2268 static const char *psz_current_encoding = "";
2270 char *psz_string, *p;
2271 size_t i_out_length;
2273 if (!strcmp(psz_encoding, psz_native_charset))
2274 return iconv_append_null(p_string, i_length);
2276 if (iconv_handle != (iconv_t)-1 &&
2277 strcmp(psz_encoding, psz_current_encoding)) {
2278 iconv_close(iconv_handle);
2279 iconv_handle = (iconv_t)-1;
2282 if (iconv_handle == (iconv_t)-1)
2283 iconv_handle = iconv_open(psz_native_charset, psz_encoding);
2284 if (iconv_handle == (iconv_t)-1) {
2285 msg_Warn(NULL, "couldn't open converter from %s to %s (%m)", psz_encoding,
2286 psz_native_charset);
2287 return iconv_append_null(p_string, i_length);
2289 psz_current_encoding = psz_encoding;
2291 /* converted strings can be up to six times larger */
2292 i_out_length = i_length * 6;
2293 p = psz_string = malloc(i_out_length);
2294 if (iconv(iconv_handle, &p_string, &i_length, &p, &i_out_length) == -1) {
2295 msg_Warn(NULL, "couldn't convert from %s to %s (%m)", psz_encoding,
2296 psz_native_charset);
2297 free(psz_string);
2298 return iconv_append_null(p_string, i_length);
2300 if (i_length)
2301 msg_Warn(NULL, "partial conversion from %s to %s", psz_encoding,
2302 psz_native_charset);
2304 *p = '\0';
2305 return psz_string;
2306 #else
2307 return iconv_append_null(p_string, i_length);
2308 #endif
2311 /*****************************************************************************
2312 * demux_Print
2313 *****************************************************************************
2314 * This code is from biTStream's examples and is under the WTFPL (see
2315 * LICENSE.WTFPL).
2316 *****************************************************************************/
2317 __attribute__ ((format(printf, 2, 3)))
2318 static void demux_Print(void *_unused, const char *psz_format, ...)
2320 char psz_fmt[strlen(psz_format) + 2];
2321 va_list args;
2322 va_start(args, psz_format);
2323 strcpy(psz_fmt, psz_format);
2324 if ( i_print_type != PRINT_XML )
2325 strcat(psz_fmt, "\n");
2326 vprintf(psz_fmt, args);
2327 va_end(args);
2330 /*****************************************************************************
2331 * HandlePAT
2332 *****************************************************************************/
2333 static void HandlePAT( mtime_t i_dts )
2335 bool b_change = false;
2336 PSI_TABLE_DECLARE( pp_old_pat_sections );
2337 uint8_t i_last_section = psi_table_get_lastsection( pp_next_pat_sections );
2338 uint8_t i, r;
2340 if ( psi_table_validate( pp_current_pat_sections ) &&
2341 psi_table_compare( pp_current_pat_sections, pp_next_pat_sections ) )
2343 /* Identical PAT. Shortcut. */
2344 psi_table_free( pp_next_pat_sections );
2345 psi_table_init( pp_next_pat_sections );
2346 goto out_pat;
2349 if ( !pat_table_validate( pp_next_pat_sections ) )
2351 msg_Warn( NULL, "invalid PAT received" );
2352 switch (i_print_type) {
2353 case PRINT_XML:
2354 fprintf(print_fh, "<ERROR type=\"invalid_pat\"/>\n");
2355 break;
2356 case PRINT_TEXT:
2357 fprintf(print_fh, "error type: invalid_pat\n");
2358 break;
2359 default:
2360 break;
2362 psi_table_free( pp_next_pat_sections );
2363 psi_table_init( pp_next_pat_sections );
2364 goto out_pat;
2367 /* Switch tables. */
2368 psi_table_copy( pp_old_pat_sections, pp_current_pat_sections );
2369 psi_table_copy( pp_current_pat_sections, pp_next_pat_sections );
2370 psi_table_init( pp_next_pat_sections );
2372 if ( !psi_table_validate( pp_old_pat_sections )
2373 || psi_table_get_tableidext( pp_current_pat_sections )
2374 != psi_table_get_tableidext( pp_old_pat_sections ) )
2376 b_change = true;
2377 UpdateTSID();
2378 /* This will trigger a universal reset of everything. */
2381 for ( i = 0; i <= i_last_section; i++ )
2383 uint8_t *p_section =
2384 psi_table_get_section( pp_current_pat_sections, i );
2385 const uint8_t *p_program;
2386 int j = 0;
2388 while ( (p_program = pat_get_program( p_section, j )) != NULL )
2390 const uint8_t *p_old_program = NULL;
2391 uint16_t i_sid = patn_get_program( p_program );
2392 uint16_t i_pid = patn_get_pid( p_program );
2393 j++;
2395 if ( i_sid == 0 )
2397 if ( i_pid != NIT_PID )
2398 msg_Warn( NULL,
2399 "NIT is carried on PID %hu which isn't DVB compliant",
2400 i_pid );
2401 continue; /* NIT */
2404 if ( !psi_table_validate( pp_old_pat_sections )
2405 || (p_old_program = pat_table_find_program(
2406 pp_old_pat_sections, i_sid )) == NULL
2407 || patn_get_pid( p_old_program ) != i_pid
2408 || b_change )
2410 sid_t *p_sid;
2412 if ( p_old_program != NULL )
2413 DeleteProgram( i_sid, patn_get_pid( p_old_program ) );
2415 SelectPMT( i_sid, i_pid );
2417 p_sid = FindSID( 0 );
2418 if ( p_sid == NULL )
2420 p_sid = malloc( sizeof(sid_t) );
2421 p_sid->p_current_pmt = NULL;
2422 for ( r = 0; r < MAX_EIT_TABLES; r++ ) {
2423 psi_table_init( p_sid->eit_table[r].data );
2425 i_nb_sids++;
2426 pp_sids = realloc( pp_sids, sizeof(sid_t *) * i_nb_sids );
2427 pp_sids[i_nb_sids - 1] = p_sid;
2430 p_sid->i_sid = i_sid;
2431 p_sid->i_pmt_pid = i_pid;
2433 UpdatePAT( i_sid );
2438 if ( psi_table_validate( pp_old_pat_sections ) )
2440 i_last_section = psi_table_get_lastsection( pp_old_pat_sections );
2441 for ( i = 0; i <= i_last_section; i++ )
2443 uint8_t *p_section =
2444 psi_table_get_section( pp_old_pat_sections, i );
2445 const uint8_t *p_program;
2446 int j = 0;
2448 while ( (p_program = pat_get_program( p_section, j )) != NULL )
2450 uint16_t i_sid = patn_get_program( p_program );
2451 uint16_t i_pid = patn_get_pid( p_program );
2452 j++;
2454 if ( i_sid == 0 )
2455 continue; /* NIT */
2457 if ( pat_table_find_program( pp_current_pat_sections, i_sid )
2458 == NULL )
2460 DeleteProgram( i_sid, i_pid );
2461 UpdatePAT( i_sid );
2466 psi_table_free( pp_old_pat_sections );
2469 pat_table_print( pp_current_pat_sections, msg_Dbg, NULL, PRINT_TEXT );
2470 if ( b_print_enabled )
2472 pat_table_print( pp_current_pat_sections, demux_Print, NULL,
2473 i_print_type );
2474 if ( i_print_type == PRINT_XML )
2475 fprintf(print_fh, "\n");
2478 out_pat:
2479 SendPAT( i_dts );
2482 /*****************************************************************************
2483 * HandlePATSection
2484 *****************************************************************************/
2485 static void HandlePATSection( uint16_t i_pid, uint8_t *p_section,
2486 mtime_t i_dts )
2488 if ( i_pid != PAT_PID || !pat_validate( p_section ) )
2490 msg_Warn( NULL, "invalid PAT section received on PID %hu", i_pid );
2491 switch (i_print_type) {
2492 case PRINT_XML:
2493 fprintf(print_fh, "<ERROR type=\"invalid_pat_section\"/>\n");
2494 break;
2495 case PRINT_TEXT:
2496 fprintf(print_fh, "error type: invalid_pat_section\n");
2497 break;
2498 default:
2499 break;
2501 free( p_section );
2502 return;
2505 if ( !psi_table_section( pp_next_pat_sections, p_section ) )
2506 return;
2508 HandlePAT( i_dts );
2511 /*****************************************************************************
2512 * HandleCAT
2513 *****************************************************************************/
2514 static void HandleCAT( mtime_t i_dts )
2516 PSI_TABLE_DECLARE( pp_old_cat_sections );
2517 uint8_t i_last_section = psi_table_get_lastsection( pp_next_cat_sections );
2518 uint8_t i_last_section2;
2519 uint8_t i, r;
2520 uint8_t *p_desc;
2521 int j, k;
2523 if ( psi_table_validate( pp_current_cat_sections ) &&
2524 psi_table_compare( pp_current_cat_sections, pp_next_cat_sections ) )
2526 /* Identical CAT. Shortcut. */
2527 psi_table_free( pp_next_cat_sections );
2528 psi_table_init( pp_next_cat_sections );
2529 goto out_cat;
2532 if ( !cat_table_validate( pp_next_cat_sections ) )
2534 msg_Warn( NULL, "invalid CAT received" );
2535 switch (i_print_type) {
2536 case PRINT_XML:
2537 fprintf(print_fh, "<ERROR type=\"invalid_cat\"/>\n");
2538 break;
2539 case PRINT_TEXT:
2540 fprintf(print_fh, "error type: invalid_cat\n");
2541 break;
2542 default:
2543 break;
2545 psi_table_free( pp_next_cat_sections );
2546 psi_table_init( pp_next_cat_sections );
2547 goto out_cat;
2550 /* Switch tables. */
2551 psi_table_copy( pp_old_cat_sections, pp_current_cat_sections );
2552 psi_table_copy( pp_current_cat_sections, pp_next_cat_sections );
2553 psi_table_init( pp_next_cat_sections );
2555 for ( i = 0; i <= i_last_section; i++ )
2557 uint8_t *p_section = psi_table_get_section( pp_current_cat_sections, i );
2559 j = 0;
2560 while ( (p_desc = descl_get_desc( cat_get_descl(p_section), cat_get_desclength(p_section), j++ )) != NULL )
2562 if ( desc_get_tag( p_desc ) != 0x09 || !desc09_validate( p_desc ) )
2563 continue;
2565 SetPID_EMM( desc09_get_pid( p_desc ) );
2569 if ( psi_table_validate( pp_old_cat_sections ) )
2571 i_last_section = psi_table_get_lastsection( pp_old_cat_sections );
2572 for ( i = 0; i <= i_last_section; i++ )
2574 uint8_t *p_old_section = psi_table_get_section( pp_old_cat_sections, i );
2575 j = 0;
2576 while ( (p_desc = descl_get_desc( cat_get_descl(p_old_section), cat_get_desclength(p_old_section), j++ )) != NULL )
2578 uint16_t emm_pid;
2579 int pid_found = 0;
2581 if ( desc_get_tag( p_desc ) != 0x09 || !desc09_validate( p_desc ) )
2582 continue;
2584 emm_pid = desc09_get_pid( p_desc );
2586 // Search in current sections if the pid exists
2587 i_last_section2 = psi_table_get_lastsection( pp_current_cat_sections );
2588 for ( r = 0; r <= i_last_section2; r++ )
2590 uint8_t *p_section = psi_table_get_section( pp_current_cat_sections, r );
2592 k = 0;
2593 while ( (p_desc = descl_get_desc( cat_get_descl(p_section), cat_get_desclength(p_section), k++ )) != NULL )
2595 if ( desc_get_tag( p_desc ) != 0x09 || !desc09_validate( p_desc ) )
2596 continue;
2597 if ( ca_desc_find( cat_get_descl(p_section), cat_get_desclength(p_section), emm_pid ) != NULL )
2599 pid_found = 1;
2600 break;
2605 if ( !pid_found )
2606 UnsetPID(emm_pid);
2610 psi_table_free( pp_old_cat_sections );
2613 cat_table_print( pp_current_cat_sections, msg_Dbg, NULL, PRINT_TEXT );
2614 if ( b_print_enabled )
2616 cat_table_print( pp_current_cat_sections, demux_Print, NULL,
2617 i_print_type );
2618 if ( i_print_type == PRINT_XML )
2619 fprintf(print_fh, "\n");
2622 out_cat:
2623 return;
2626 /*****************************************************************************
2627 * HandleCATSection
2628 *****************************************************************************/
2629 static void HandleCATSection( uint16_t i_pid, uint8_t *p_section,
2630 mtime_t i_dts )
2632 if ( i_pid != CAT_PID || !cat_validate( p_section ) )
2634 msg_Warn( NULL, "invalid CAT section received on PID %hu", i_pid );
2635 switch (i_print_type) {
2636 case PRINT_XML:
2637 fprintf(print_fh, "<ERROR type=\"invalid_cat_section\"/>\n");
2638 break;
2639 case PRINT_TEXT:
2640 fprintf(print_fh, "error type: invalid_cat_section\n");
2641 break;
2642 default:
2643 break;
2645 free( p_section );
2646 return;
2649 if ( !psi_table_section( pp_next_cat_sections, p_section ) )
2650 return;
2652 HandleCAT( i_dts );
2655 static void mark_pmt_pids( uint8_t *p_pmt, uint8_t pid_map[], uint8_t marker )
2657 uint16_t j, k;
2658 uint8_t *p_es;
2659 uint8_t *p_desc;
2661 uint16_t i_pcr_pid = pmt_get_pcrpid( p_pmt );
2663 if ( b_enable_ecm )
2665 j = 0;
2666 while ( (p_desc = descs_get_desc( pmt_get_descs( p_pmt ), j++ )) != NULL )
2668 if ( desc_get_tag( p_desc ) != 0x09 || !desc09_validate( p_desc ) )
2669 continue;
2670 pid_map[ desc09_get_pid( p_desc ) ] |= marker;
2674 if ( i_pcr_pid != PADDING_PID )
2675 pid_map[ i_pcr_pid ] |= marker;
2677 j = 0;
2678 while ( (p_es = pmt_get_es( p_pmt, j )) != NULL )
2680 uint16_t i_pid = pmtn_get_pid( p_es );
2681 j++;
2683 if ( PIDWouldBeSelected( p_es ) )
2684 pid_map[ i_pid ] |= marker;
2686 p_pids[i_pid].b_pes = PIDCarriesPES( p_es );
2688 if ( b_enable_ecm )
2690 k = 0;
2691 while ( (p_desc = descs_get_desc( pmtn_get_descs( p_es ), k++ )) != NULL )
2693 if ( desc_get_tag( p_desc ) != 0x09 || !desc09_validate( p_desc ) )
2694 continue;
2695 pid_map[ desc09_get_pid( p_desc ) ] |= marker;
2701 /*****************************************************************************
2702 * HandlePMT
2703 *****************************************************************************/
2704 static void HandlePMT( uint16_t i_pid, uint8_t *p_pmt, mtime_t i_dts )
2706 uint16_t i_sid = pmt_get_program( p_pmt );
2707 sid_t *p_sid;
2708 bool b_needs_descrambling, b_needed_descrambling, b_is_selected;
2709 uint8_t pid_map[MAX_PIDS];
2711 p_sid = FindSID( i_sid );
2712 if ( p_sid == NULL )
2714 /* Unwanted SID (happens when the same PMT PID is used for several
2715 * programs). */
2716 free( p_pmt );
2717 return;
2720 if ( i_pid != p_sid->i_pmt_pid )
2722 msg_Warn( NULL, "invalid PMT section received on PID %hu", i_pid );
2723 switch (i_print_type) {
2724 case PRINT_XML:
2725 fprintf(print_fh, "<ERROR type=\"ghost_pmt\" program=\"%hu\n pid=\"%hu\"/>\n",
2726 i_sid, i_pid);
2727 break;
2728 case PRINT_TEXT:
2729 fprintf(print_fh, "error type: ghost_pmt program: %hu pid: %hu\n",
2730 i_sid, i_pid);
2731 break;
2732 default:
2733 break;
2735 free( p_pmt );
2736 return;
2739 if ( p_sid->p_current_pmt != NULL &&
2740 psi_compare( p_sid->p_current_pmt, p_pmt ) )
2742 /* Identical PMT. Shortcut. */
2743 free( p_pmt );
2744 goto out_pmt;
2747 if ( !pmt_validate( p_pmt ) )
2749 msg_Warn( NULL, "invalid PMT section received on PID %hu", i_pid );
2750 switch (i_print_type) {
2751 case PRINT_XML:
2752 fprintf(print_fh, "<ERROR type=\"invalid_pmt_section\" pid=\"%hu\"/>\n",
2753 i_pid);
2754 break;
2755 case PRINT_TEXT:
2756 fprintf(print_fh, "error type: invalid_pmt_section pid: %hu\n",
2757 i_pid);
2758 break;
2759 default:
2760 break;
2762 free( p_pmt );
2763 goto out_pmt;
2766 memset( pid_map, 0, sizeof(pid_map) );
2768 b_needs_descrambling = PMTNeedsDescrambling( p_pmt );
2769 b_needed_descrambling = p_sid->p_current_pmt != NULL ?
2770 PMTNeedsDescrambling( p_sid->p_current_pmt ) :
2771 false;
2772 b_is_selected = SIDIsSelected( i_sid );
2774 if ( i_ca_handle && b_is_selected &&
2775 !b_needs_descrambling && b_needed_descrambling )
2776 en50221_DeletePMT( p_sid->p_current_pmt );
2778 if ( p_sid->p_current_pmt != NULL )
2780 mark_pmt_pids( p_sid->p_current_pmt, pid_map, 0x02 );
2781 free( p_sid->p_current_pmt );
2784 mark_pmt_pids( p_pmt, pid_map, 0x01 );
2786 uint16_t i_pcr_pid = pmt_get_pcrpid( p_pmt );
2787 int i;
2788 for ( i = 0; i < i_nb_outputs; i++ )
2789 if ( (pp_outputs[i]->config.i_config & OUTPUT_VALID)
2790 && pp_outputs[i]->config.i_sid == i_sid )
2791 pp_outputs[i]->i_pcr_pid = 0;
2793 /* Start to stream PIDs */
2794 int pid;
2795 for ( pid = 0; pid < MAX_PIDS; pid++ )
2797 /* The pid does not exist in the old PMT and in the new PMT. Ignore this pid. */
2798 if ( !pid_map[ pid ] )
2799 continue;
2801 switch ( pid_map[ pid ] & 0x03 ) {
2802 case 0x03: /* The pid exists in the old PMT and in the new PMT. The pid was already selected in case 0x01. */
2803 continue;
2804 case 0x02: /* The pid does not exist in the new PMT but exists in the old PMT. Unselect it. */
2805 UnselectPID( i_sid, pid );
2806 break;
2807 case 0x01: /* The pid exists in new PMT. Select it. */
2808 SelectPID( i_sid, pid, pid == i_pcr_pid );
2809 break;
2813 p_sid->p_current_pmt = p_pmt;
2815 if ( i_ca_handle && b_is_selected )
2817 if ( b_needs_descrambling && !b_needed_descrambling )
2818 en50221_AddPMT( p_pmt );
2819 else if ( b_needs_descrambling && b_needed_descrambling )
2820 en50221_UpdatePMT( p_pmt );
2823 UpdatePMT( i_sid );
2825 pmt_print( p_pmt, msg_Dbg, NULL, demux_Iconv, NULL, PRINT_TEXT );
2826 if ( b_print_enabled )
2828 pmt_print( p_pmt, demux_Print, NULL, demux_Iconv, NULL,
2829 i_print_type );
2830 if ( i_print_type == PRINT_XML )
2831 fprintf(print_fh, "\n");
2834 out_pmt:
2835 SendPMT( p_sid, i_dts );
2838 /*****************************************************************************
2839 * HandleNIT
2840 *****************************************************************************/
2841 static void HandleNIT( mtime_t i_dts )
2843 if ( psi_table_validate( pp_current_nit_sections ) &&
2844 psi_table_compare( pp_current_nit_sections, pp_next_nit_sections ) )
2846 /* Identical NIT. Shortcut. */
2847 psi_table_free( pp_next_nit_sections );
2848 psi_table_init( pp_next_nit_sections );
2849 goto out_nit;
2852 if ( !nit_table_validate( pp_next_nit_sections ) )
2854 msg_Warn( NULL, "invalid NIT received" );
2855 switch (i_print_type) {
2856 case PRINT_XML:
2857 fprintf(print_fh, "<ERROR type=\"invalid_nit\"/>\n");
2858 break;
2859 case PRINT_TEXT:
2860 fprintf(print_fh, "error type: invalid_nit\n");
2861 break;
2862 default:
2863 break;
2865 psi_table_free( pp_next_nit_sections );
2866 psi_table_init( pp_next_nit_sections );
2867 goto out_nit;
2870 /* Switch tables. */
2871 psi_table_free( pp_current_nit_sections );
2872 psi_table_copy( pp_current_nit_sections, pp_next_nit_sections );
2873 psi_table_init( pp_next_nit_sections );
2875 nit_table_print( pp_current_nit_sections, msg_Dbg, NULL,
2876 demux_Iconv, NULL, PRINT_TEXT );
2877 if ( b_print_enabled )
2879 nit_table_print( pp_current_nit_sections, demux_Print, NULL,
2880 demux_Iconv, NULL, i_print_type );
2881 if ( i_print_type == PRINT_XML )
2882 fprintf(print_fh, "\n");
2885 out_nit:
2889 /*****************************************************************************
2890 * HandleNITSection
2891 *****************************************************************************/
2892 static void HandleNITSection( uint16_t i_pid, uint8_t *p_section,
2893 mtime_t i_dts )
2895 if ( i_pid != NIT_PID || !nit_validate( p_section ) )
2897 msg_Warn( NULL, "invalid NIT section received on PID %hu", i_pid );
2898 switch (i_print_type) {
2899 case PRINT_XML:
2900 fprintf(print_fh, "<ERROR type=\"invalid_nit_section\" pid=\"%hu\"/>\n",
2901 i_pid);
2902 break;
2903 case PRINT_TEXT:
2904 fprintf(print_fh, "error type: invalid_nit_section pid: %hu\n",
2905 i_pid);
2906 break;
2907 default:
2908 break;
2910 free( p_section );
2911 return;
2914 if ( psi_table_section( pp_next_nit_sections, p_section ) )
2915 HandleNIT( i_dts );
2917 /* This case is different because DVB specifies a minimum bitrate for
2918 * PID 0x10, even if we don't have any thing to send (for cheap
2919 * transport over network boundaries). */
2920 SendNIT( i_dts );
2924 /*****************************************************************************
2925 * HandleSDT
2926 *****************************************************************************/
2927 static void HandleSDT( mtime_t i_dts )
2929 PSI_TABLE_DECLARE( pp_old_sdt_sections );
2930 uint8_t i_last_section = psi_table_get_lastsection( pp_next_sdt_sections );
2931 uint8_t i;
2932 int j;
2934 if ( psi_table_validate( pp_current_sdt_sections ) &&
2935 psi_table_compare( pp_current_sdt_sections, pp_next_sdt_sections ) )
2937 /* Identical SDT. Shortcut. */
2938 psi_table_free( pp_next_sdt_sections );
2939 psi_table_init( pp_next_sdt_sections );
2940 goto out_sdt;
2943 if ( !sdt_table_validate( pp_next_sdt_sections ) )
2945 msg_Warn( NULL, "invalid SDT received" );
2946 switch (i_print_type) {
2947 case PRINT_XML:
2948 fprintf(print_fh, "<ERROR type=\"invalid_sdt\"/>\n");
2949 break;
2950 case PRINT_TEXT:
2951 fprintf(print_fh, "error type: invalid_sdt\n");
2952 break;
2953 default:
2954 break;
2956 psi_table_free( pp_next_sdt_sections );
2957 psi_table_init( pp_next_sdt_sections );
2958 goto out_sdt;
2961 /* Switch tables. */
2962 psi_table_copy( pp_old_sdt_sections, pp_current_sdt_sections );
2963 psi_table_copy( pp_current_sdt_sections, pp_next_sdt_sections );
2964 psi_table_init( pp_next_sdt_sections );
2966 for ( i = 0; i <= i_last_section; i++ )
2968 uint8_t *p_section =
2969 psi_table_get_section( pp_current_sdt_sections, i );
2970 uint8_t *p_service;
2971 j = 0;
2973 while ( (p_service = sdt_get_service( p_section, j )) != NULL )
2975 uint16_t i_sid = sdtn_get_sid( p_service );
2976 j++;
2978 UpdateSDT( i_sid );
2982 if ( psi_table_validate( pp_old_sdt_sections ) )
2984 i_last_section = psi_table_get_lastsection( pp_old_sdt_sections );
2985 for ( i = 0; i <= i_last_section; i++ )
2987 uint8_t *p_section =
2988 psi_table_get_section( pp_old_sdt_sections, i );
2989 const uint8_t *p_service;
2990 int j = 0;
2992 while ( (p_service = sdt_get_service( p_section, j )) != NULL )
2994 uint16_t i_sid = sdtn_get_sid( p_service );
2995 j++;
2997 if ( sdt_table_find_service( pp_current_sdt_sections, i_sid )
2998 == NULL )
2999 UpdateSDT( i_sid );
3003 psi_table_free( pp_old_sdt_sections );
3006 sdt_table_print( pp_current_sdt_sections, msg_Dbg, NULL,
3007 demux_Iconv, NULL, PRINT_TEXT );
3008 if ( b_print_enabled )
3010 sdt_table_print( pp_current_sdt_sections, demux_Print, NULL,
3011 demux_Iconv, NULL, i_print_type );
3012 if ( i_print_type == PRINT_XML )
3013 fprintf(print_fh, "\n");
3016 out_sdt:
3017 SendSDT( i_dts );
3020 /*****************************************************************************
3021 * HandleSDTSection
3022 *****************************************************************************/
3023 static void HandleSDTSection( uint16_t i_pid, uint8_t *p_section,
3024 mtime_t i_dts )
3026 if ( i_pid != SDT_PID || !sdt_validate( p_section ) )
3028 msg_Warn( NULL, "invalid SDT section received on PID %hu", i_pid );
3029 switch (i_print_type) {
3030 case PRINT_XML:
3031 fprintf(print_fh, "<ERROR type=\"invalid_sdt_section\" pid=\"%hu\"/>\n",
3032 i_pid);
3033 break;
3034 case PRINT_TEXT:
3035 fprintf(print_fh, "error type: invalid_sdt_section pid: %hu\n",
3036 i_pid);
3037 break;
3038 default:
3039 break;
3041 free( p_section );
3042 return;
3045 if ( !psi_table_section( pp_next_sdt_sections, p_section ) )
3046 return;
3048 HandleSDT( i_dts );
3051 /*****************************************************************************
3052 * HandleEITSection
3053 *****************************************************************************/
3054 static void HandleEIT( uint16_t i_pid, uint8_t *p_eit, mtime_t i_dts )
3056 uint8_t i_table_id = psi_get_tableid( p_eit );
3057 uint16_t i_sid = eit_get_sid( p_eit );
3058 sid_t *p_sid;
3060 p_sid = FindSID( i_sid );
3061 if ( p_sid == NULL )
3063 /* Not a selected program. */
3064 free( p_eit );
3065 return;
3068 if ( i_pid != EIT_PID || !eit_validate( p_eit ) )
3070 msg_Warn( NULL, "invalid EIT section received on PID %hu", i_pid );
3071 switch (i_print_type) {
3072 case PRINT_XML:
3073 fprintf(print_fh, "<ERROR type=\"invalid_eit_section\" pid=\"%hu\"/>\n",
3074 i_pid);
3075 break;
3076 case PRINT_TEXT:
3077 fprintf(print_fh, "error type: invalid_eit_section pid: %hu\n",
3078 i_pid);
3079 break;
3080 default:
3081 break;
3083 free( p_eit );
3084 return;
3087 bool b_epg = handle_epg( i_table_id );
3088 if ( ! b_epg )
3089 goto out_eit;
3091 /* We do not use psi_table_* primitives as the spec allows for holes in
3092 * section numbering, and there is no sure way to know whether you have
3093 * gathered all sections. */
3094 uint8_t i_section = psi_get_section(p_eit);
3095 uint8_t eit_table_id = i_table_id - EIT_TABLE_ID_PF_ACTUAL;
3096 if (eit_table_id >= MAX_EIT_TABLES)
3097 goto out_eit;
3098 if (p_sid->eit_table[eit_table_id].data[i_section] != NULL &&
3099 psi_compare(p_sid->eit_table[eit_table_id].data[i_section], p_eit)) {
3100 /* Identical section. Shortcut. */
3101 free(p_sid->eit_table[eit_table_id].data[i_section]);
3102 p_sid->eit_table[eit_table_id].data[i_section] = p_eit;
3103 goto out_eit;
3106 free(p_sid->eit_table[eit_table_id].data[i_section]);
3107 p_sid->eit_table[eit_table_id].data[i_section] = p_eit;
3109 if ( b_print_enabled && psi_get_tableid( p_eit ) == EIT_TABLE_ID_PF_ACTUAL )
3111 eit_print( p_eit, demux_Print, NULL,
3112 demux_Iconv, NULL, i_print_type );
3113 if ( i_print_type == PRINT_XML )
3114 fprintf(print_fh, "\n");
3117 out_eit:
3118 SendEIT( p_sid, i_dts, p_eit );
3119 if ( ! b_epg )
3120 free( p_eit );
3123 /*****************************************************************************
3124 * HandleSection
3125 *****************************************************************************/
3126 static void HandleSection( uint16_t i_pid, uint8_t *p_section, mtime_t i_dts )
3128 uint8_t i_table_id = psi_get_tableid( p_section );
3130 if ( !psi_validate( p_section ) )
3132 msg_Warn( NULL, "invalid section on PID %hu", i_pid );
3133 switch (i_print_type) {
3134 case PRINT_XML:
3135 fprintf(print_fh, "<ERROR type=\"invalid_section\" pid=\"%hu\"/>\n", i_pid);
3136 break;
3137 case PRINT_TEXT:
3138 fprintf(print_fh, "error type: invalid_section pid: %hu\n", i_pid);
3139 break;
3140 default:
3141 break;
3143 free( p_section );
3144 return;
3147 if ( !psi_get_current( p_section ) )
3149 /* Ignore sections which are not in use yet. */
3150 free( p_section );
3151 return;
3154 switch ( i_table_id )
3156 case PAT_TABLE_ID:
3157 HandlePATSection( i_pid, p_section, i_dts );
3158 break;
3160 case CAT_TABLE_ID:
3161 if ( b_enable_emm )
3162 HandleCATSection( i_pid, p_section, i_dts );
3163 break;
3165 case PMT_TABLE_ID:
3166 HandlePMT( i_pid, p_section, i_dts );
3167 break;
3169 case NIT_TABLE_ID_ACTUAL:
3170 HandleNITSection( i_pid, p_section, i_dts );
3171 break;
3173 case SDT_TABLE_ID_ACTUAL:
3174 HandleSDTSection( i_pid, p_section, i_dts );
3175 break;
3177 default:
3178 if ( handle_epg( i_table_id ) )
3180 HandleEIT( i_pid, p_section, i_dts );
3181 break;
3183 free( p_section );
3184 break;
3188 /*****************************************************************************
3189 * HandlePSIPacket
3190 *****************************************************************************/
3191 static void HandlePSIPacket( uint8_t *p_ts, mtime_t i_dts )
3193 uint16_t i_pid = ts_get_pid( p_ts );
3194 ts_pid_t *p_pid = &p_pids[i_pid];
3195 uint8_t i_cc = ts_get_cc( p_ts );
3196 const uint8_t *p_payload;
3197 uint8_t i_length;
3199 if ( ts_check_duplicate( i_cc, p_pid->i_last_cc )
3200 || !ts_has_payload( p_ts ) )
3201 return;
3203 if ( p_pid->i_last_cc != -1
3204 && ts_check_discontinuity( i_cc, p_pid->i_last_cc ) )
3205 psi_assemble_reset( &p_pid->p_psi_buffer, &p_pid->i_psi_buffer_used );
3207 p_payload = ts_section( p_ts );
3208 i_length = p_ts + TS_SIZE - p_payload;
3210 if ( !psi_assemble_empty( &p_pid->p_psi_buffer,
3211 &p_pid->i_psi_buffer_used ) )
3213 uint8_t *p_section = psi_assemble_payload( &p_pid->p_psi_buffer,
3214 &p_pid->i_psi_buffer_used,
3215 &p_payload, &i_length );
3216 if ( p_section != NULL )
3217 HandleSection( i_pid, p_section, i_dts );
3220 p_payload = ts_next_section( p_ts );
3221 i_length = p_ts + TS_SIZE - p_payload;
3223 while ( i_length )
3225 uint8_t *p_section = psi_assemble_payload( &p_pid->p_psi_buffer,
3226 &p_pid->i_psi_buffer_used,
3227 &p_payload, &i_length );
3228 if ( p_section != NULL )
3229 HandleSection( i_pid, p_section, i_dts );
3233 /*****************************************************************************
3234 * PID info functions
3235 *****************************************************************************/
3236 static const char *h222_stream_type_desc(uint8_t i_stream_type) {
3237 /* See ISO/IEC 13818-1 : 2000 (E) | Table 2-29 - Stream type assignments, Page 66 (48) */
3238 if (i_stream_type == 0)
3239 return "Reserved stream";
3240 switch (i_stream_type) {
3241 case 0x01: return "11172-2 video (MPEG-1)";
3242 case 0x02: return "H.262/13818-2 video (MPEG-2) or 11172-2 constrained video";
3243 case 0x03: return "11172-3 audio (MPEG-1)";
3244 case 0x04: return "13818-3 audio (MPEG-2)";
3245 case 0x05: return "H.222.0/13818-1 private sections";
3246 case 0x06: return "H.222.0/13818-1 PES private data";
3247 case 0x07: return "13522 MHEG";
3248 case 0x08: return "H.222.0/13818-1 Annex A - DSM CC";
3249 case 0x09: return "H.222.1";
3250 case 0x0A: return "13818-6 type A";
3251 case 0x0B: return "13818-6 type B";
3252 case 0x0C: return "13818-6 type C";
3253 case 0x0D: return "13818-6 type D";
3254 case 0x0E: return "H.222.0/13818-1 auxiliary";
3255 case 0x0F: return "13818-7 Audio with ADTS transport syntax";
3256 case 0x10: return "14496-2 Visual (MPEG-4 part 2 video)";
3257 case 0x11: return "14496-3 Audio with LATM transport syntax (14496-3/AMD 1)";
3258 case 0x12: return "14496-1 SL-packetized or FlexMux stream in PES packets";
3259 case 0x13: return "14496-1 SL-packetized or FlexMux stream in 14496 sections";
3260 case 0x14: return "ISO/IEC 13818-6 Synchronized Download Protocol";
3261 case 0x15: return "Metadata in PES packets";
3262 case 0x16: return "Metadata in metadata_sections";
3263 case 0x17: return "Metadata in 13818-6 Data Carousel";
3264 case 0x18: return "Metadata in 13818-6 Object Carousel";
3265 case 0x19: return "Metadata in 13818-6 Synchronized Download Protocol";
3266 case 0x1A: return "13818-11 MPEG-2 IPMP stream";
3267 case 0x1B: return "H.264/14496-10 video (MPEG-4/AVC)";
3268 case 0x24: return "H.265/23008-2 video (HEVC)";
3269 case 0x42: return "AVS Video";
3270 case 0x7F: return "IPMP stream";
3271 default : return "Unknown stream";
3275 static const char *get_pid_desc(uint16_t i_pid, uint16_t *i_sid) {
3276 int i, j, k;
3277 uint8_t i_last_section;
3278 uint8_t *p_desc;
3279 uint16_t i_nit_pid = NIT_PID, i_pcr_pid = 0;
3281 /* Simple cases */
3282 switch (i_pid)
3284 case 0x00: return "PAT";
3285 case 0x01: return "CAT";
3286 case 0x11: return "SDT";
3287 case 0x12: return "EPG";
3288 case 0x14: return "TDT/TOT";
3291 /* Detect NIT pid */
3292 if ( psi_table_validate( pp_current_pat_sections ) )
3294 i_last_section = psi_table_get_lastsection( pp_current_pat_sections );
3295 for ( i = 0; i <= i_last_section; i++ )
3297 uint8_t *p_section = psi_table_get_section( pp_current_pat_sections, i );
3298 uint8_t *p_program;
3300 j = 0;
3301 while ( (p_program = pat_get_program( p_section, j++ )) != NULL )
3303 /* Programs with PID == 0 are actually NIT */
3304 if ( patn_get_program( p_program ) == 0 )
3306 i_nit_pid = patn_get_pid( p_program );
3307 break;
3313 /* Detect EMM pids */
3314 if ( b_enable_emm && psi_table_validate( pp_current_cat_sections ) )
3316 i_last_section = psi_table_get_lastsection( pp_current_cat_sections );
3317 for ( i = 0; i <= i_last_section; i++ )
3319 uint8_t *p_section = psi_table_get_section( pp_current_cat_sections, i );
3321 j = 0;
3322 while ( (p_desc = descl_get_desc( cat_get_descl(p_section), cat_get_desclength(p_section), j++ )) != NULL )
3324 if ( desc_get_tag( p_desc ) != 0x09 || !desc09_validate( p_desc ) )
3325 continue;
3327 if ( desc09_get_pid( p_desc ) == i_pid ) {
3328 return "EMM";
3334 /* Detect streams in PMT */
3335 for ( k = 0; k < i_nb_sids; k++ )
3337 sid_t *p_sid = pp_sids[k];
3338 if ( p_sid->i_pmt_pid == i_pid )
3340 if ( i_sid )
3341 *i_sid = p_sid->i_sid;
3342 return "PMT";
3345 if ( p_sid->i_sid && p_sid->p_current_pmt != NULL )
3347 uint8_t *p_current_pmt = p_sid->p_current_pmt;
3348 uint8_t *p_current_es;
3350 /* The PCR PID can be alone or PCR can be carried in some other PIDs (mostly video)
3351 so just remember the pid and if it is alone it will be reported as PCR, otherwise
3352 stream type of the PID will be reported */
3353 if ( i_pid == pmt_get_pcrpid( p_current_pmt ) ) {
3354 if ( i_sid )
3355 *i_sid = p_sid->i_sid;
3356 i_pcr_pid = pmt_get_pcrpid( p_current_pmt );
3359 /* Look for ECMs */
3360 j = 0;
3361 while ((p_desc = descs_get_desc( pmt_get_descs( p_current_pmt ), j++ )) != NULL)
3363 if ( desc_get_tag( p_desc ) != 0x09 || !desc09_validate( p_desc ) )
3364 continue;
3366 if ( desc09_get_pid( p_desc ) == i_pid ) {
3367 if ( i_sid )
3368 *i_sid = p_sid->i_sid;
3369 return "ECM";
3373 /* Detect stream types */
3374 j = 0;
3375 while ( (p_current_es = pmt_get_es( p_current_pmt, j++ )) != NULL )
3377 if ( pmtn_get_pid( p_current_es ) == i_pid )
3379 if ( i_sid )
3380 *i_sid = p_sid->i_sid;
3381 return h222_stream_type_desc( pmtn_get_streamtype( p_current_es ) );
3387 /* Are there any other PIDs? */
3388 if (i_pid == i_nit_pid)
3389 return "NIT";
3391 if (i_pid == i_pcr_pid)
3392 return "PCR";
3394 return "...";
3397 /*****************************************************************************
3398 * Functions that return packed sections
3399 *****************************************************************************/
3400 uint8_t *demux_get_current_packed_PAT( unsigned int *pi_pack_size ) {
3401 return psi_pack_sections( pp_current_pat_sections, pi_pack_size );
3404 uint8_t *demux_get_current_packed_CAT( unsigned int *pi_pack_size ) {
3405 return psi_pack_sections( pp_current_cat_sections, pi_pack_size );
3408 uint8_t *demux_get_current_packed_NIT( unsigned int *pi_pack_size ) {
3409 return psi_pack_sections( pp_current_nit_sections, pi_pack_size );
3412 uint8_t *demux_get_current_packed_SDT( unsigned int *pi_pack_size ) {
3413 return psi_pack_sections( pp_current_sdt_sections, pi_pack_size );
3416 uint8_t *demux_get_packed_EIT( uint16_t i_sid, uint8_t start_table, uint8_t end_table, unsigned int *eit_size ) {
3417 unsigned int i, r;
3419 *eit_size = 0;
3420 sid_t *p_sid = FindSID( i_sid );
3421 if ( p_sid == NULL )
3422 return NULL;
3424 /* Calculate eit table size (sum of all sections in all tables between start_start and end_table) */
3425 for ( i = start_table; i <= end_table; i++ ) {
3426 uint8_t eit_table_idx = i - EIT_TABLE_ID_PF_ACTUAL;
3427 if ( eit_table_idx >= MAX_EIT_TABLES )
3428 continue;
3429 uint8_t **eit_sections = p_sid->eit_table[eit_table_idx].data;
3430 for ( r = 0; r < PSI_TABLE_MAX_SECTIONS; r++ ) {
3431 uint8_t *p_eit = eit_sections[r];
3432 if ( !p_eit )
3433 continue;
3434 uint16_t psi_length = psi_get_length( p_eit ) + PSI_HEADER_SIZE;
3435 *eit_size += psi_length;
3439 uint8_t *p_flat_section = malloc( *eit_size );
3440 if ( !p_flat_section )
3441 return NULL;
3443 /* Copy sections */
3444 unsigned int i_pos = 0;
3445 for ( i = start_table; i <= end_table; i++ ) {
3446 uint8_t eit_table_idx = i - EIT_TABLE_ID_PF_ACTUAL;
3447 if ( eit_table_idx >= MAX_EIT_TABLES )
3448 continue;
3449 uint8_t **eit_sections = p_sid->eit_table[eit_table_idx].data;
3450 for ( r = 0; r < PSI_TABLE_MAX_SECTIONS; r++ ) {
3451 uint8_t *p_eit = eit_sections[r];
3452 if ( !p_eit )
3453 continue;
3454 uint16_t psi_length = psi_get_length( p_eit ) + PSI_HEADER_SIZE;
3455 memcpy( p_flat_section + i_pos, p_eit, psi_length );
3456 i_pos += psi_length;
3457 /* eit_print( p_eit, msg_Dbg, NULL, demux_Iconv, NULL, PRINT_TEXT ); */
3460 return p_flat_section;
3463 uint8_t *demux_get_packed_EIT_pf( uint16_t service_id, unsigned int *pi_pack_size ) {
3464 return demux_get_packed_EIT( service_id, EIT_TABLE_ID_PF_ACTUAL, EIT_TABLE_ID_PF_ACTUAL, pi_pack_size );
3467 uint8_t *demux_get_packed_EIT_schedule( uint16_t service_id, unsigned int *pi_pack_size ) {
3468 return demux_get_packed_EIT( service_id, EIT_TABLE_ID_SCHED_ACTUAL_FIRST, EIT_TABLE_ID_SCHED_ACTUAL_LAST, pi_pack_size );
3471 uint8_t *demux_get_packed_PMT( uint16_t i_sid, unsigned int *pi_pack_size ) {
3472 sid_t *p_sid = FindSID( i_sid );
3473 if ( p_sid != NULL && p_sid->p_current_pmt && pmt_validate( p_sid->p_current_pmt ) )
3474 return psi_pack_section( p_sid->p_current_pmt, pi_pack_size );
3475 return NULL;
3478 inline void demux_get_PID_info( uint16_t i_pid, uint8_t *p_data ) {
3479 ts_pid_info_t *p_info = (ts_pid_info_t *)p_data;
3480 *p_info = p_pids[i_pid].info;
3483 inline void demux_get_PIDS_info( uint8_t *p_data ) {
3484 int i_pid;
3485 for (i_pid = 0; i_pid < MAX_PIDS; i_pid++ )
3486 demux_get_PID_info( i_pid, p_data + ( i_pid * sizeof(ts_pid_info_t) ) );