Remove excessive debug, extend search for start
[dvblastpn.git] / demux.c
blob5c5c84f93e4b6d579551efb9ab16e27d45ce7647
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"
40 #ifdef HAVE_ICONV
41 #include <iconv.h>
42 #endif
44 #include <bitstream/mpeg/ts.h>
45 #include <bitstream/mpeg/pes.h>
46 #include <bitstream/mpeg/psi.h>
47 #include <bitstream/dvb/si.h>
48 #include <bitstream/dvb/si_print.h>
49 #include <bitstream/mpeg/psi_print.h>
51 /*****************************************************************************
52 * Local declarations
53 *****************************************************************************/
54 #define MIN_SECTION_FRAGMENT PSI_HEADER_SIZE_SYNTAX1
56 typedef struct ts_pid_t
58 int i_refcount;
59 int i_psi_refcount;
60 bool b_pes;
61 int8_t i_last_cc;
62 int i_demux_fd;
64 /* PID info and stats */
65 mtime_t i_bytes_ts;
66 unsigned long i_packets_passed;
67 ts_pid_info_t info;
69 /* biTStream PSI section gathering */
70 uint8_t *p_psi_buffer;
71 uint16_t i_psi_buffer_used;
73 output_t **pp_outputs;
74 int i_nb_outputs;
76 int i_pes_status; /* pes + unscrambled */
77 struct ev_timer timeout_watcher;
78 } ts_pid_t;
80 struct eit_sections {
81 PSI_TABLE_DECLARE(data);
84 /* EIT is carried in several separate tables, we need to track each table
85 separately, otherwise one table overwrites sections of another table */
86 #define MAX_EIT_TABLES ( EIT_TABLE_ID_SCHED_ACTUAL_LAST - EIT_TABLE_ID_PF_ACTUAL )
88 typedef struct sid_t
90 uint16_t i_sid, i_pmt_pid;
91 uint8_t *p_current_pmt;
92 struct eit_sections eit_table[MAX_EIT_TABLES];
93 } sid_t;
95 mtime_t i_wallclock = 0;
97 static ts_pid_t p_pids[MAX_PIDS];
98 static sid_t **pp_sids = NULL;
99 static int i_nb_sids = 0;
101 static PSI_TABLE_DECLARE(pp_current_pat_sections);
102 static PSI_TABLE_DECLARE(pp_next_pat_sections);
103 static PSI_TABLE_DECLARE(pp_current_cat_sections);
104 static PSI_TABLE_DECLARE(pp_next_cat_sections);
105 static PSI_TABLE_DECLARE(pp_current_nit_sections);
106 static PSI_TABLE_DECLARE(pp_next_nit_sections);
107 static PSI_TABLE_DECLARE(pp_current_sdt_sections);
108 static PSI_TABLE_DECLARE(pp_next_sdt_sections);
109 static mtime_t i_last_dts = -1;
110 static int i_demux_fd;
111 static uint64_t i_nb_packets = 0;
112 static uint64_t i_nb_invalids = 0;
113 static uint64_t i_nb_discontinuities = 0;
114 static uint64_t i_nb_errors = 0;
115 static int i_tuner_errors = 0;
116 static mtime_t i_last_error = 0;
117 static struct ev_timer print_watcher;
119 #ifdef HAVE_ICONV
120 static iconv_t iconv_handle = (iconv_t)-1;
121 #endif
123 /*****************************************************************************
124 * Local prototypes
125 *****************************************************************************/
126 static void demux_Handle( block_t *p_ts );
127 static void SetDTS( block_t *p_list );
128 static void SetPID( uint16_t i_pid );
129 static void UnsetPID( uint16_t i_pid );
130 static void StartPID( output_t *p_output, uint16_t i_pid );
131 static void StopPID( output_t *p_output, uint16_t i_pid );
132 static void SelectPID( uint16_t i_sid, uint16_t i_pid, bool b_pcr );
133 static void UnselectPID( uint16_t i_sid, uint16_t i_pid );
134 static void SelectPMT( uint16_t i_sid, uint16_t i_pid );
135 static void UnselectPMT( uint16_t i_sid, uint16_t i_pid );
136 static void GetPIDS( uint16_t **ppi_wanted_pids, int *pi_nb_wanted_pids,
137 uint16_t *pi_pcr_pid, uint16_t i_sid,
138 const uint16_t *pi_pids, int i_nb_pids );
139 static bool PIDWouldBeSelected( uint8_t *p_es );
140 static void FlushEIT( output_t *p_output, mtime_t i_dts );
141 static void SendTDT( block_t *p_ts );
142 static void NewPAT( output_t *p_output );
143 static void NewPMT( output_t *p_output );
144 static void NewNIT( output_t *p_output );
145 static void NewSDT( output_t *p_output );
146 static void HandlePSIPacket( uint8_t *p_ts, mtime_t i_dts );
147 static const char *get_pid_desc(uint16_t i_pid, uint16_t *i_sid);
150 * Remap an ES pid to a fixed value.
151 * Multiple streams of the same type use sequential pids
152 * Returns the new pid and updates the map tables
154 static uint16_t map_es_pid(output_t * p_output, uint8_t *p_es, uint16_t i_pid)
156 uint16_t i_newpid = i_pid;
157 uint16_t i_stream_type = pmtn_get_streamtype(p_es);
159 if ( !b_do_remap && !p_output->config.b_do_remap )
160 return i_pid;
162 msg_Dbg(NULL, "REMAP: Found elementary stream type 0x%02x with original PID 0x%x (%u):", i_stream_type, i_pid, i_pid);
164 switch ( i_stream_type )
166 case 0x03: /* audio MPEG-1 */
167 case 0x04: /* audio MPEG-2 */
168 case 0x0f: /* audio AAC ADTS */
169 case 0x11: /* audio AAC LATM */
170 case 0x81: /* ATSC AC-3 */
171 case 0x87: /* ATSC Enhanced AC-3 */
172 if ( b_do_remap )
173 i_newpid = pi_newpids[I_APID];
174 else
175 i_newpid = p_output->config.pi_confpids[I_APID];
176 break;
177 case 0x01: /* video MPEG-1 */
178 case 0x02: /* video MPEG-2 */
179 case 0x10: /* video MPEG-4 */
180 case 0x1b: /* video H264 */
181 case 0x24: /* video H265 */
182 case 0x42: /* video AVS */
183 if ( b_do_remap )
184 i_newpid = pi_newpids[I_VPID];
185 else
186 i_newpid = p_output->config.pi_confpids[I_VPID];
187 break;
188 case 0x06: { /* PES Private Data - We must check the descriptors */
189 /* By default, nothing identified */
190 uint8_t SubStreamType = N_MAP_PIDS;
191 uint16_t j = 0;
192 const uint8_t *p_desc;
193 /* Loop over the descriptors */
194 while ( (p_desc = descs_get_desc( pmtn_get_descs( p_es ), j )) != NULL )
196 /* Get the descriptor tag */
197 uint8_t i_tag = desc_get_tag( p_desc );
198 j++;
199 /* Check if the tag is: A/52, Enhanced A/52, DTS, AAC */
200 if (i_tag == 0x6a || i_tag == 0x7a || i_tag == 0x7b || i_tag == 0x7c)
201 SubStreamType=I_APID;
202 /* Check if the tag is: VBI + teletext, teletext, dvbsub */
203 if (i_tag == 0x46 || i_tag == 0x56 || i_tag == 0x59)
204 SubStreamType=I_SPUPID;
206 /* Audio found */
207 if (SubStreamType==I_APID) {
208 msg_Dbg(NULL, "REMAP: PES Private Data stream identified as [Audio]");
209 if ( b_do_remap )
210 i_newpid = pi_newpids[I_APID];
211 else
212 i_newpid = p_output->config.pi_confpids[I_APID];
214 /* Subtitle found */
215 if (SubStreamType==I_SPUPID) {
216 msg_Dbg(NULL, "REMAP: PES Private Data stream identified as [Subtitle]");
217 if ( b_do_remap )
218 i_newpid = pi_newpids[I_SPUPID];
219 else
220 i_newpid = p_output->config.pi_confpids[I_SPUPID];
222 break;
226 if (!i_newpid)
227 return i_pid;
229 /* Got the new base for the mapped pid. Find the next free one
230 we do this to ensure that multiple audios get unique pids */
231 while (p_output->pi_freepids[i_newpid] != UNUSED_PID)
232 i_newpid++;
233 p_output->pi_freepids[i_newpid] = i_pid; /* Mark as in use */
234 p_output->pi_newpids[i_pid] = i_newpid; /* Save the new pid */
236 msg_Dbg(NULL, "REMAP: => Elementary stream is remapped to PID 0x%x (%u)", i_newpid, i_newpid);
238 return i_newpid;
241 /*****************************************************************************
242 * FindSID
243 *****************************************************************************/
244 static inline sid_t *FindSID( uint16_t i_sid )
246 int i;
248 for ( i = 0; i < i_nb_sids; i++ )
250 sid_t *p_sid = pp_sids[i];
251 if ( p_sid->i_sid == i_sid )
252 return p_sid;
254 return NULL;
257 /*****************************************************************************
258 * Print info
259 *****************************************************************************/
260 static void PrintCb( struct ev_loop *loop, struct ev_timer *w, int revents )
262 uint64_t i_bitrate = i_nb_packets * TS_SIZE * 8 * 1000000 / i_print_period;
263 switch (i_print_type)
265 case PRINT_XML:
266 fprintf(print_fh,
267 "<STATUS type=\"bitrate\" status=\"%d\" value=\"%"PRIu64"\" />\n",
268 i_bitrate ? 1 : 0, i_bitrate);
269 break;
270 case PRINT_TEXT:
271 fprintf(print_fh, "bitrate: %"PRIu64"\n", i_bitrate);
272 break;
273 default:
274 break;
276 i_nb_packets = 0;
278 if ( i_nb_invalids )
280 switch (i_print_type)
282 case PRINT_XML:
283 fprintf(print_fh,
284 "<ERROR type=\"invalid_ts\" number=\"%"PRIu64"\" />\n",
285 i_nb_invalids);
286 break;
287 case PRINT_TEXT:
288 fprintf(print_fh, "invalids: %"PRIu64"\n", i_nb_invalids);
289 break;
290 default:
291 break;
293 i_nb_invalids = 0;
296 if ( i_nb_discontinuities )
298 switch (i_print_type)
300 case PRINT_XML:
301 fprintf(print_fh,
302 "<ERROR type=\"invalid_discontinuity\" number=\"%"PRIu64"\" />\n",
303 i_nb_discontinuities);
304 break;
305 case PRINT_TEXT:
306 fprintf(print_fh, "discontinuities: %"PRIu64"\n",
307 i_nb_discontinuities);
308 break;
309 default:
310 break;
312 i_nb_discontinuities = 0;
315 if ( i_nb_errors )
317 switch (i_print_type)
319 case PRINT_XML:
320 fprintf(print_fh,
321 "<ERROR type=\"transport_error\" number=\"%"PRIu64"\" />\n",
322 i_nb_errors);
323 break;
324 case PRINT_TEXT:
325 fprintf(print_fh, "errors: %"PRIu64"\n", i_nb_errors);
326 break;
327 default:
328 break;
330 i_nb_errors = 0;
334 static void PrintESCb( struct ev_loop *loop, struct ev_timer *w, int revents )
336 ts_pid_t *p_pid = container_of( w, ts_pid_t, timeout_watcher );
337 uint16_t i_pid = p_pid - p_pids;
339 switch (i_print_type)
341 case PRINT_XML:
342 fprintf(print_fh,
343 "<STATUS type=\"pid\" pid=\"%"PRIu16"\" status=\"0\" />\n",
344 i_pid);
345 break;
346 case PRINT_TEXT:
347 fprintf(print_fh, "pid: %"PRIu16" down\n", i_pid);
348 break;
349 default:
350 break;
353 ev_timer_stop( loop, w );
354 p_pid->i_pes_status = -1;
357 static void PrintES( uint16_t i_pid )
359 const ts_pid_t *p_pid = &p_pids[i_pid];
361 switch (i_print_type)
363 case PRINT_XML:
364 fprintf(print_fh,
365 "<STATUS type=\"pid\" pid=\"%"PRIu16"\" status=\"1\" pes=\"%d\" />\n",
366 i_pid, p_pid->i_pes_status == 1 ? 1 : 0);
367 break;
368 case PRINT_TEXT:
369 fprintf(print_fh, "pid: %"PRIu16" up%s\n",
370 i_pid, p_pid->i_pes_status == 1 ? " pes" : "");
371 break;
372 default:
373 break;
377 /*****************************************************************************
378 * demux_Open
379 *****************************************************************************/
380 void demux_Open( void )
382 int i;
384 memset( p_pids, 0, sizeof(p_pids) );
386 pf_Open();
388 for ( i = 0; i < MAX_PIDS; i++ )
390 p_pids[i].i_last_cc = -1;
391 p_pids[i].i_demux_fd = -1;
392 psi_assemble_init( &p_pids[i].p_psi_buffer,
393 &p_pids[i].i_psi_buffer_used );
394 p_pids[i].i_pes_status = -1;
397 if ( b_budget_mode )
398 i_demux_fd = pf_SetFilter(8192);
400 psi_table_init( pp_current_pat_sections );
401 psi_table_init( pp_next_pat_sections );
402 SetPID(PAT_PID);
403 p_pids[PAT_PID].i_psi_refcount++;
405 SetPID(NIT_PID);
406 p_pids[NIT_PID].i_psi_refcount++;
408 psi_table_init( pp_current_sdt_sections );
409 psi_table_init( pp_next_sdt_sections );
410 SetPID(SDT_PID);
411 p_pids[SDT_PID].i_psi_refcount++;
413 SetPID(EIT_PID);
414 p_pids[EIT_PID].i_psi_refcount++;
416 SetPID(RST_PID);
418 SetPID(TDT_PID);
420 if ( i_print_period )
422 ev_timer_init( &print_watcher, PrintCb,
423 i_print_period / 1000000., i_print_period / 1000000. );
424 ev_timer_start( event_loop, &print_watcher );
428 /*****************************************************************************
429 * demux_Close
430 *****************************************************************************/
431 void demux_Close( void )
433 int i, r;
435 psi_table_free( pp_current_pat_sections );
436 psi_table_free( pp_next_pat_sections );
437 psi_table_free( pp_current_cat_sections );
438 psi_table_free( pp_next_cat_sections );
439 psi_table_free( pp_current_nit_sections );
440 psi_table_free( pp_next_nit_sections );
441 psi_table_free( pp_current_sdt_sections );
442 psi_table_free( pp_next_sdt_sections );
444 for ( i = 0; i < MAX_PIDS; i++ )
446 ev_timer_stop( event_loop, &p_pids[i].timeout_watcher );
447 free( p_pids[i].p_psi_buffer );
448 free( p_pids[i].pp_outputs );
451 for ( i = 0; i < i_nb_sids; i++ )
453 sid_t *p_sid = pp_sids[i];
454 for ( r = 0; r < MAX_EIT_TABLES; r++ ) {
455 psi_table_free( p_sid->eit_table[r].data );
457 free( p_sid->p_current_pmt );
458 free( p_sid );
460 free( pp_sids );
462 #ifdef HAVE_ICONV
463 if (iconv_handle != (iconv_t)-1) {
464 iconv_close(iconv_handle);
465 iconv_handle = (iconv_t)-1;
467 #endif
469 if ( i_print_period )
470 ev_timer_stop( event_loop, &print_watcher );
473 /*****************************************************************************
474 * demux_Run
475 *****************************************************************************/
476 void demux_Run( block_t *p_ts )
478 i_wallclock = mdate();
479 SetDTS( p_ts );
481 while ( p_ts != NULL )
483 block_t *p_next = p_ts->p_next;
484 p_ts->p_next = NULL;
485 demux_Handle( p_ts );
486 p_ts = p_next;
490 /*****************************************************************************
491 * demux_Handle
492 *****************************************************************************/
493 static void demux_Handle( block_t *p_ts )
495 uint16_t i_pid = ts_get_pid( p_ts->p_ts );
496 ts_pid_t *p_pid = &p_pids[i_pid];
497 uint8_t i_cc = ts_get_cc( p_ts->p_ts );
498 int i;
500 i_nb_packets++;
502 if ( !ts_validate( p_ts->p_ts ) )
504 msg_Warn( NULL, "lost TS sync" );
505 block_Delete( p_ts );
506 i_nb_invalids++;
507 return;
510 if ( i_pid != PADDING_PID )
511 p_pid->info.i_scrambling = ts_get_scrambling( p_ts->p_ts );
513 p_pid->info.i_last_packet_ts = i_wallclock;
514 p_pid->info.i_packets++;
516 p_pid->i_packets_passed++;
518 /* Calculate bytes_per_sec */
519 if ( i_wallclock > p_pid->i_bytes_ts + 1000000 ) {
520 p_pid->info.i_bytes_per_sec = p_pid->i_packets_passed * TS_SIZE;
521 p_pid->i_packets_passed = 0;
522 p_pid->i_bytes_ts = i_wallclock;
525 if ( p_pid->info.i_first_packet_ts == 0 )
526 p_pid->info.i_first_packet_ts = i_wallclock;
528 if ( i_pid != PADDING_PID && p_pid->i_last_cc != -1
529 && !ts_check_duplicate( i_cc, p_pid->i_last_cc )
530 && ts_check_discontinuity( i_cc, p_pid->i_last_cc ) )
532 unsigned int expected_cc = (p_pid->i_last_cc + 1) & 0x0f;
533 uint16_t i_sid = 0;
534 const char *pid_desc = get_pid_desc(i_pid, &i_sid);
536 p_pid->info.i_cc_errors++;
537 i_nb_discontinuities++;
539 msg_Warn( NULL, "TS discontinuity on pid %4hu expected_cc %2u got %2u (%s, sid %d)",
540 i_pid, expected_cc, i_cc, pid_desc, i_sid );
543 if ( ts_get_transporterror( p_ts->p_ts ) )
545 uint16_t i_sid = 0;
546 const char *pid_desc = get_pid_desc(i_pid, &i_sid);
548 p_pid->info.i_transport_errors++;
550 msg_Warn( NULL, "transport_error_indicator on pid %hu (%s, sid %u)",
551 i_pid, pid_desc, i_sid );
553 i_nb_errors++;
554 i_tuner_errors++;
555 i_last_error = i_wallclock;
557 else if ( i_wallclock > i_last_error + WATCHDOG_WAIT )
558 i_tuner_errors = 0;
560 if ( i_tuner_errors > MAX_ERRORS )
562 i_tuner_errors = 0;
563 msg_Warn( NULL,
564 "too many transport errors, tuning again" );
565 switch (i_print_type) {
566 case PRINT_XML:
567 fprintf(print_fh, "<EVENT type=\"reset\" cause=\"transport\" />\n");
568 break;
569 case PRINT_TEXT:
570 fprintf(print_fh, "reset cause: transport\n");
571 break;
572 default:
573 break;
575 pf_Reset();
578 if ( i_es_timeout )
580 int i_pes_status = -1;
581 if ( ts_get_scrambling( p_ts->p_ts ) )
582 i_pes_status = 0;
583 else if ( ts_get_unitstart( p_ts->p_ts ) )
585 uint8_t *p_payload = ts_payload( p_ts->p_ts );
586 if ( p_payload + 3 < p_ts->p_ts + TS_SIZE )
587 i_pes_status = pes_validate( p_payload ) ? 1 : 0;
590 if ( i_pes_status != -1 )
592 if ( p_pid->i_pes_status == -1 )
594 p_pid->i_pes_status = i_pes_status;
595 PrintES( i_pid );
597 if ( i_pid != TDT_PID )
599 ev_timer_init( &p_pid->timeout_watcher, PrintESCb,
600 i_es_timeout / 1000000.,
601 i_es_timeout / 1000000. );
602 ev_timer_start( event_loop, &p_pid->timeout_watcher );
604 else
606 ev_timer_init( &p_pid->timeout_watcher, PrintESCb, 30, 30 );
607 ev_timer_start( event_loop, &p_pid->timeout_watcher );
610 else
612 if ( p_pid->i_pes_status != i_pes_status )
614 p_pid->i_pes_status = i_pes_status;
615 PrintES( i_pid );
618 ev_timer_again( event_loop, &p_pid->timeout_watcher );
623 if ( !ts_get_transporterror( p_ts->p_ts ) )
625 /* PSI parsing */
626 if ( i_pid == TDT_PID || i_pid == RST_PID )
627 SendTDT( p_ts );
628 else if ( p_pid->i_psi_refcount )
629 HandlePSIPacket( p_ts->p_ts, p_ts->i_dts );
632 p_pid->i_last_cc = i_cc;
634 /* Output */
635 for ( i = 0; i < p_pid->i_nb_outputs; i++ )
637 output_t *p_output = p_pid->pp_outputs[i];
638 if ( p_output != NULL )
640 if ( p_output->i_pcr_pid != i_pid
641 || (ts_has_adaptation(p_ts->p_ts)
642 && ts_get_adaptation(p_ts->p_ts)
643 && tsaf_has_pcr(p_ts->p_ts)) )
644 output_Put( p_output, p_ts );
646 if ( p_output->p_eit_ts_buffer != NULL
647 && p_ts->i_dts > p_output->p_eit_ts_buffer->i_dts
648 + MAX_EIT_RETENTION )
649 FlushEIT( p_output, p_ts->i_dts );
653 for ( i = 0; i < i_nb_outputs; i++ )
655 output_t *p_output = pp_outputs[i];
657 if ( !(p_output->config.i_config & OUTPUT_VALID) ||
658 !p_output->config.b_passthrough )
659 continue;
661 output_Put( p_output, p_ts );
664 if ( output_dup.config.i_config & OUTPUT_VALID )
665 output_Put( &output_dup, p_ts );
667 if ( b_passthrough )
668 fwrite(p_ts->p_ts, TS_SIZE, 1, stdout);
670 p_ts->i_refcount--;
671 if ( !p_ts->i_refcount )
672 block_Delete( p_ts );
675 /*****************************************************************************
676 * demux_Change : called from main thread
677 *****************************************************************************/
678 static bool IsIn( const uint16_t *pi_pids, int i_nb_pids, uint16_t i_pid )
680 int i;
681 for ( i = 0; i < i_nb_pids; i++ )
682 if ( i_pid == pi_pids[i] ) break;
683 return ( i != i_nb_pids );
686 void demux_Change( output_t *p_output, const output_config_t *p_config )
688 uint16_t *pi_wanted_pids, *pi_current_pids;
689 int i_nb_wanted_pids, i_nb_current_pids;
690 uint16_t i_wanted_pcr_pid, i_current_pcr_pid;
692 uint16_t i_old_sid = p_output->config.i_sid;
693 uint16_t i_sid = p_config->i_sid;
694 uint16_t *pi_old_pids = p_output->config.pi_pids;
695 uint16_t *pi_pids = p_config->pi_pids;
696 int i_old_nb_pids = p_output->config.i_nb_pids;
697 int i_nb_pids = p_config->i_nb_pids;
699 bool b_sid_change = i_sid != i_old_sid;
700 bool b_pid_change = false, b_tsid_change = false;
701 bool b_dvb_change = !!((p_output->config.i_config ^ p_config->i_config)
702 & OUTPUT_DVB);
703 bool b_epg_change = !!((p_output->config.i_config ^ p_config->i_config)
704 & OUTPUT_EPG);
705 bool b_network_change =
706 (dvb_string_cmp(&p_output->config.network_name, &p_config->network_name) ||
707 p_output->config.i_network_id != p_config->i_network_id);
708 bool b_service_name_change =
709 (dvb_string_cmp(&p_output->config.service_name, &p_config->service_name) ||
710 dvb_string_cmp(&p_output->config.provider_name, &p_config->provider_name));
711 bool b_remap_change = p_output->config.i_new_sid != p_config->i_new_sid ||
712 p_output->config.i_onid != p_config->i_onid ||
713 p_output->config.b_do_remap != p_config->b_do_remap ||
714 p_output->config.pi_confpids[I_PMTPID] != p_config->pi_confpids[I_PMTPID] ||
715 p_output->config.pi_confpids[I_APID] != p_config->pi_confpids[I_APID] ||
716 p_output->config.pi_confpids[I_VPID] != p_config->pi_confpids[I_VPID] ||
717 p_output->config.pi_confpids[I_SPUPID] != p_config->pi_confpids[I_SPUPID];
718 int i;
720 p_output->config.i_config = p_config->i_config;
721 p_output->config.i_network_id = p_config->i_network_id;
722 p_output->config.i_new_sid = p_config->i_new_sid;
723 p_output->config.i_onid = p_config->i_onid;
724 p_output->config.b_do_remap = p_config->b_do_remap;
725 memcpy(p_output->config.pi_confpids, p_config->pi_confpids,
726 sizeof(uint16_t) * N_MAP_PIDS);
728 /* Change output settings related to names. */
729 dvb_string_clean( &p_output->config.network_name );
730 dvb_string_clean( &p_output->config.service_name );
731 dvb_string_clean( &p_output->config.provider_name );
732 dvb_string_copy( &p_output->config.network_name,
733 &p_config->network_name );
734 dvb_string_copy( &p_output->config.service_name,
735 &p_config->service_name );
736 dvb_string_copy( &p_output->config.provider_name,
737 &p_config->provider_name );
739 if ( p_config->i_tsid != -1 && p_output->config.i_tsid != p_config->i_tsid )
741 p_output->i_tsid = p_output->config.i_tsid = p_config->i_tsid;
742 b_tsid_change = true;
744 if ( p_config->i_tsid == -1 && p_output->config.i_tsid != -1 )
746 p_output->config.i_tsid = p_config->i_tsid;
747 if ( psi_table_validate(pp_current_pat_sections) && !b_random_tsid )
748 p_output->i_tsid =
749 psi_table_get_tableidext(pp_current_pat_sections);
750 else
751 p_output->i_tsid = rand() & 0xffff;
752 b_tsid_change = true;
755 if ( p_config->b_passthrough == p_output->config.b_passthrough &&
756 !b_sid_change && p_config->i_nb_pids == p_output->config.i_nb_pids &&
757 (!p_config->i_nb_pids ||
758 !memcmp( p_output->config.pi_pids, p_config->pi_pids,
759 p_config->i_nb_pids * sizeof(uint16_t) )) )
760 goto out_change;
762 GetPIDS( &pi_wanted_pids, &i_nb_wanted_pids, &i_wanted_pcr_pid,
763 i_sid, pi_pids, i_nb_pids );
764 GetPIDS( &pi_current_pids, &i_nb_current_pids, &i_current_pcr_pid,
765 i_old_sid, pi_old_pids, i_old_nb_pids );
767 if ( b_sid_change && i_old_sid )
769 sid_t *p_old_sid = FindSID( i_old_sid );
770 p_output->config.i_sid = p_config->i_sid;
772 if ( p_old_sid != NULL )
774 if ( i_sid != i_old_sid )
775 UnselectPMT( i_old_sid, p_old_sid->i_pmt_pid );
779 for ( i = 0; i < i_nb_current_pids; i++ )
781 if ( !IsIn( pi_wanted_pids, i_nb_wanted_pids, pi_current_pids[i] ) )
783 StopPID( p_output, pi_current_pids[i] );
784 b_pid_change = true;
788 for ( i = 0; i < i_nb_wanted_pids; i++ )
790 if ( !IsIn( pi_current_pids, i_nb_current_pids, pi_wanted_pids[i] ) )
792 StartPID( p_output, pi_wanted_pids[i] );
793 b_pid_change = true;
797 free( pi_wanted_pids );
798 free( pi_current_pids );
799 p_output->i_pcr_pid = i_wanted_pcr_pid;
801 if ( b_sid_change && i_sid )
803 sid_t *p_sid = FindSID( i_sid );
804 p_output->config.i_sid = i_old_sid;
806 if ( p_sid != NULL )
808 if ( i_sid != i_old_sid )
809 SelectPMT( i_sid, p_sid->i_pmt_pid );
814 p_output->config.b_passthrough = p_config->b_passthrough;
815 p_output->config.i_sid = i_sid;
816 free( p_output->config.pi_pids );
817 p_output->config.pi_pids = malloc( sizeof(uint16_t) * i_nb_pids );
818 memcpy( p_output->config.pi_pids, pi_pids, sizeof(uint16_t) * i_nb_pids );
819 p_output->config.i_nb_pids = i_nb_pids;
821 out_change:
822 if ( b_sid_change || b_pid_change || b_tsid_change || b_dvb_change ||
823 b_network_change || b_service_name_change || b_remap_change )
825 msg_Dbg( NULL, "change %s%s%s%s%s%s%s",
826 b_sid_change ? "sid " : "",
827 b_pid_change ? "pid " : "",
828 b_tsid_change ? "tsid " : "",
829 b_dvb_change ? "dvb " : "",
830 b_network_change ? "network " : "",
831 b_service_name_change ? "service_name " : "",
832 b_remap_change ? "remap " : "" );
835 if ( b_sid_change || b_remap_change )
837 NewSDT( p_output );
838 NewNIT( p_output );
839 NewPAT( p_output );
840 NewPMT( p_output );
842 else
844 if ( b_tsid_change )
846 NewSDT( p_output );
847 NewNIT( p_output );
848 NewPAT( p_output );
850 else if ( b_dvb_change )
852 NewNIT( p_output );
853 NewPAT( p_output );
855 else if ( b_network_change )
856 NewNIT( p_output );
858 if ( !b_tsid_change && (b_service_name_change || b_epg_change) )
859 NewSDT( p_output );
861 if ( b_pid_change )
862 NewPMT( p_output );
866 /*****************************************************************************
867 * SetDTS
868 *****************************************************************************/
869 static void SetDTS( block_t *p_list )
871 int i_nb_ts = 0, i;
872 mtime_t i_duration;
873 block_t *p_ts = p_list;
875 while ( p_ts != NULL )
877 i_nb_ts++;
878 p_ts = p_ts->p_next;
881 /* We suppose the stream is CBR, at least between two consecutive read().
882 * This is especially true in budget mode */
883 if ( i_last_dts == -1 )
884 i_duration = 0;
885 else
886 i_duration = i_wallclock - i_last_dts;
888 p_ts = p_list;
889 i = i_nb_ts - 1;
890 while ( p_ts != NULL )
892 p_ts->i_dts = i_wallclock - i_duration * i / i_nb_ts;
893 i--;
894 p_ts = p_ts->p_next;
897 i_last_dts = i_wallclock;
900 /*****************************************************************************
901 * SetPID/UnsetPID
902 *****************************************************************************/
903 static void SetPID( uint16_t i_pid )
905 p_pids[i_pid].i_refcount++;
907 if ( !b_budget_mode && p_pids[i_pid].i_refcount
908 && p_pids[i_pid].i_demux_fd == -1 )
909 p_pids[i_pid].i_demux_fd = pf_SetFilter( i_pid );
912 static void UnsetPID( uint16_t i_pid )
914 p_pids[i_pid].i_refcount--;
916 if ( !b_budget_mode && !p_pids[i_pid].i_refcount
917 && p_pids[i_pid].i_demux_fd != -1 )
919 pf_UnsetFilter( p_pids[i_pid].i_demux_fd, i_pid );
920 p_pids[i_pid].i_demux_fd = -1;
924 /*****************************************************************************
925 * StartPID/StopPID
926 *****************************************************************************/
927 static void StartPID( output_t *p_output, uint16_t i_pid )
929 int j;
931 for ( j = 0; j < p_pids[i_pid].i_nb_outputs; j++ )
932 if ( p_pids[i_pid].pp_outputs[j] == p_output )
933 break;
935 if ( j == p_pids[i_pid].i_nb_outputs )
937 for ( j = 0; j < p_pids[i_pid].i_nb_outputs; j++ )
938 if ( p_pids[i_pid].pp_outputs[j] == NULL )
939 break;
941 if ( j == p_pids[i_pid].i_nb_outputs )
943 p_pids[i_pid].i_nb_outputs++;
944 p_pids[i_pid].pp_outputs = realloc( p_pids[i_pid].pp_outputs,
945 sizeof(output_t *)
946 * p_pids[i_pid].i_nb_outputs );
949 p_pids[i_pid].pp_outputs[j] = p_output;
950 SetPID( i_pid );
954 static void StopPID( output_t *p_output, uint16_t i_pid )
956 int j;
958 for ( j = 0; j < p_pids[i_pid].i_nb_outputs; j++ )
960 if ( p_pids[i_pid].pp_outputs[j] != NULL )
962 if ( p_pids[i_pid].pp_outputs[j] == p_output )
963 break;
967 if ( j != p_pids[i_pid].i_nb_outputs )
969 p_pids[i_pid].pp_outputs[j] = NULL;
970 UnsetPID( i_pid );
974 /*****************************************************************************
975 * SelectPID/UnselectPID
976 *****************************************************************************/
977 static void SelectPID( uint16_t i_sid, uint16_t i_pid, bool b_pcr )
979 int i;
981 for ( i = 0; i < i_nb_outputs; i++ )
983 if ( (pp_outputs[i]->config.i_config & OUTPUT_VALID)
984 && pp_outputs[i]->config.i_sid == i_sid )
986 if ( pp_outputs[i]->config.i_nb_pids &&
987 !IsIn( pp_outputs[i]->config.pi_pids,
988 pp_outputs[i]->config.i_nb_pids, i_pid ) )
990 if ( b_pcr )
991 pp_outputs[i]->i_pcr_pid = i_pid;
992 else
993 continue;
995 StartPID( pp_outputs[i], i_pid );
1000 static void UnselectPID( uint16_t i_sid, uint16_t i_pid )
1002 int i;
1004 for ( i = 0; i < i_nb_outputs; i++ )
1005 if ( (pp_outputs[i]->config.i_config & OUTPUT_VALID)
1006 && pp_outputs[i]->config.i_sid == i_sid
1007 && !pp_outputs[i]->config.i_nb_pids )
1008 StopPID( pp_outputs[i], i_pid );
1011 /*****************************************************************************
1012 * SelectPMT/UnselectPMT
1013 *****************************************************************************/
1014 static void SelectPMT( uint16_t i_sid, uint16_t i_pid )
1016 int i;
1018 p_pids[i_pid].i_psi_refcount++;
1019 p_pids[i_pid].b_pes = false;
1021 if ( b_select_pmts )
1022 SetPID( i_pid );
1023 else for ( i = 0; i < i_nb_outputs; i++ )
1024 if ( (pp_outputs[i]->config.i_config & OUTPUT_VALID)
1025 && pp_outputs[i]->config.i_sid == i_sid )
1026 SetPID( i_pid );
1029 static void UnselectPMT( uint16_t i_sid, uint16_t i_pid )
1031 int i;
1033 p_pids[i_pid].i_psi_refcount--;
1034 if ( !p_pids[i_pid].i_psi_refcount )
1035 psi_assemble_reset( &p_pids[i_pid].p_psi_buffer,
1036 &p_pids[i_pid].i_psi_buffer_used );
1038 if ( b_select_pmts )
1039 UnsetPID( i_pid );
1040 else for ( i = 0; i < i_nb_outputs; i++ )
1041 if ( (pp_outputs[i]->config.i_config & OUTPUT_VALID)
1042 && pp_outputs[i]->config.i_sid == i_sid )
1043 UnsetPID( i_pid );
1046 /*****************************************************************************
1047 * GetPIDS
1048 *****************************************************************************/
1049 static void GetPIDS( uint16_t **ppi_wanted_pids, int *pi_nb_wanted_pids,
1050 uint16_t *pi_wanted_pcr_pid, uint16_t i_sid,
1051 const uint16_t *pi_pids, int i_nb_pids )
1053 sid_t *p_sid;
1054 uint8_t *p_pmt;
1055 uint16_t i_pmt_pid, i_pcr_pid;
1056 uint8_t *p_es;
1057 uint8_t j;
1059 *pi_wanted_pcr_pid = 0;
1061 if ( i_nb_pids || i_sid == 0 )
1063 *pi_nb_wanted_pids = i_nb_pids;
1064 *ppi_wanted_pids = malloc( sizeof(uint16_t) * i_nb_pids );
1065 memcpy( *ppi_wanted_pids, pi_pids, sizeof(uint16_t) * i_nb_pids );
1066 if ( i_sid == 0 )
1067 return;
1069 else
1071 *pi_nb_wanted_pids = 0;
1072 *ppi_wanted_pids = NULL;
1075 p_sid = FindSID( i_sid );
1076 if ( p_sid == NULL )
1077 return;
1079 p_pmt = p_sid->p_current_pmt;
1080 i_pmt_pid = p_sid->i_pmt_pid;
1081 if ( p_pmt == NULL ) {
1082 msg_Dbg(NULL, "no current PMT on sid %d\n", i_sid);
1083 return;
1086 i_pcr_pid = pmt_get_pcrpid( p_pmt );
1087 j = 0;
1088 while ( (p_es = pmt_get_es( p_pmt, j )) != NULL )
1090 j++;
1092 uint16_t i_pid = pmtn_get_pid( p_es );
1093 bool b_select;
1094 if ( i_nb_pids )
1095 b_select = IsIn( pi_pids, i_nb_pids, i_pid );
1096 else
1098 b_select = PIDWouldBeSelected( p_es );
1099 if ( b_select )
1101 *ppi_wanted_pids = realloc( *ppi_wanted_pids,
1102 (*pi_nb_wanted_pids + 1) * sizeof(uint16_t) );
1103 (*ppi_wanted_pids)[(*pi_nb_wanted_pids)++] = i_pid;
1110 if ( i_pcr_pid != PADDING_PID && i_pcr_pid != i_pmt_pid
1111 && !IsIn( *ppi_wanted_pids, *pi_nb_wanted_pids, i_pcr_pid ) )
1113 *ppi_wanted_pids = realloc( *ppi_wanted_pids,
1114 (*pi_nb_wanted_pids + 1) * sizeof(uint16_t) );
1115 (*ppi_wanted_pids)[(*pi_nb_wanted_pids)++] = i_pcr_pid;
1116 /* We only need the PCR packets of this stream (incomplete) */
1117 *pi_wanted_pcr_pid = i_pcr_pid;
1118 msg_Dbg( NULL, "Requesting partial PCR PID %"PRIu16, i_pcr_pid );
1122 /*****************************************************************************
1123 * OutputPSISection
1124 *****************************************************************************/
1125 static void OutputPSISection( output_t *p_output, uint8_t *p_section,
1126 uint16_t i_pid, uint8_t *pi_cc, mtime_t i_dts,
1127 block_t **pp_ts_buffer,
1128 uint8_t *pi_ts_buffer_offset )
1130 uint16_t i_section_length = psi_get_length(p_section) + PSI_HEADER_SIZE;
1131 uint16_t i_section_offset = 0;
1135 block_t *p_block;
1136 uint8_t *p;
1137 uint8_t i_ts_offset;
1138 bool b_append = (pp_ts_buffer != NULL && *pp_ts_buffer != NULL);
1140 if ( b_append )
1142 p_block = *pp_ts_buffer;
1143 i_ts_offset = *pi_ts_buffer_offset;
1145 else
1147 p_block = block_New();
1148 p_block->i_dts = i_dts;
1149 i_ts_offset = 0;
1151 p = p_block->p_ts;
1153 psi_split_section( p, &i_ts_offset, p_section, &i_section_offset );
1155 if ( !b_append )
1157 ts_set_pid( p, i_pid );
1158 ts_set_cc( p, *pi_cc );
1159 (*pi_cc)++;
1160 *pi_cc &= 0xf;
1163 if ( i_section_offset == i_section_length )
1165 if ( i_ts_offset < TS_SIZE - MIN_SECTION_FRAGMENT
1166 && pp_ts_buffer != NULL )
1168 *pp_ts_buffer = p_block;
1169 *pi_ts_buffer_offset = i_ts_offset;
1170 break;
1172 else
1173 psi_split_end( p, &i_ts_offset );
1176 p_block->i_dts = i_dts;
1177 p_block->i_refcount--;
1178 output_Put( p_output, p_block );
1179 if ( pp_ts_buffer != NULL )
1181 *pp_ts_buffer = NULL;
1182 *pi_ts_buffer_offset = 0;
1185 while ( i_section_offset < i_section_length );
1188 /*****************************************************************************
1189 * SendPAT
1190 *****************************************************************************/
1191 static void SendPAT( mtime_t i_dts )
1193 int i;
1195 for ( i = 0; i < i_nb_outputs; i++ )
1197 output_t *p_output = pp_outputs[i];
1199 if ( !(p_output->config.i_config & OUTPUT_VALID) ||
1200 p_output->config.b_passthrough )
1201 continue;
1203 if ( p_output->p_pat_section == NULL &&
1204 psi_table_validate(pp_current_pat_sections) )
1206 /* SID doesn't exist - build an empty PAT. */
1207 uint8_t *p;
1208 p_output->i_pat_version++;
1210 p = p_output->p_pat_section = psi_allocate();
1211 pat_init( p );
1212 pat_set_length( p, 0 );
1213 pat_set_tsid( p, p_output->i_tsid );
1214 psi_set_version( p, p_output->i_pat_version );
1215 psi_set_current( p );
1216 psi_set_section( p, 0 );
1217 psi_set_lastsection( p, 0 );
1218 psi_set_crc( p_output->p_pat_section );
1222 if ( p_output->p_pat_section != NULL )
1223 OutputPSISection( p_output, p_output->p_pat_section, PAT_PID,
1224 &p_output->i_pat_cc, i_dts, NULL, NULL );
1228 /*****************************************************************************
1229 * SendPMT
1230 *****************************************************************************/
1231 static void SendPMT( sid_t *p_sid, mtime_t i_dts )
1233 int i;
1234 int i_pmt_pid = p_sid->i_pmt_pid;
1236 if ( b_do_remap )
1237 i_pmt_pid = pi_newpids[ I_PMTPID ];
1239 for ( i = 0; i < i_nb_outputs; i++ )
1241 output_t *p_output = pp_outputs[i];
1243 if ( (p_output->config.i_config & OUTPUT_VALID)
1244 && p_output->config.i_sid == p_sid->i_sid
1245 && p_output->p_pmt_section != NULL )
1247 if ( p_output->config.b_do_remap && p_output->config.pi_confpids[I_PMTPID] )
1248 i_pmt_pid = p_output->config.pi_confpids[I_PMTPID];
1250 OutputPSISection( p_output, p_output->p_pmt_section,
1251 i_pmt_pid, &p_output->i_pmt_cc, i_dts,
1252 NULL, NULL );
1257 /*****************************************************************************
1258 * SendNIT
1259 *****************************************************************************/
1260 static void SendNIT( mtime_t i_dts )
1262 int i;
1264 for ( i = 0; i < i_nb_outputs; i++ )
1266 output_t *p_output = pp_outputs[i];
1268 if ( (p_output->config.i_config & OUTPUT_VALID)
1269 && !p_output->config.b_passthrough
1270 && (p_output->config.i_config & OUTPUT_DVB)
1271 && p_output->p_nit_section != NULL )
1272 OutputPSISection( p_output, p_output->p_nit_section, NIT_PID,
1273 &p_output->i_nit_cc, i_dts, NULL, NULL );
1277 /*****************************************************************************
1278 * SendSDT
1279 *****************************************************************************/
1280 static void SendSDT( mtime_t i_dts )
1282 int i;
1284 for ( i = 0; i < i_nb_outputs; i++ )
1286 output_t *p_output = pp_outputs[i];
1288 if ( (p_output->config.i_config & OUTPUT_VALID)
1289 && !p_output->config.b_passthrough
1290 && (p_output->config.i_config & OUTPUT_DVB)
1291 && p_output->p_sdt_section != NULL )
1292 OutputPSISection( p_output, p_output->p_sdt_section, SDT_PID,
1293 &p_output->i_sdt_cc, i_dts, NULL, NULL );
1297 /*****************************************************************************
1298 * SendEIT
1299 *****************************************************************************/
1300 static bool handle_epg( int i_table_id )
1302 return (i_table_id == EIT_TABLE_ID_PF_ACTUAL ||
1303 (i_table_id >= EIT_TABLE_ID_SCHED_ACTUAL_FIRST &&
1304 i_table_id <= EIT_TABLE_ID_SCHED_ACTUAL_LAST));
1307 static void SendEIT( sid_t *p_sid, mtime_t i_dts, uint8_t *p_eit )
1309 uint8_t i_table_id = psi_get_tableid( p_eit );
1310 bool b_epg = handle_epg( i_table_id );
1311 uint16_t i_onid = eit_get_onid(p_eit);
1312 int i;
1314 for ( i = 0; i < i_nb_outputs; i++ )
1316 output_t *p_output = pp_outputs[i];
1318 if ( (p_output->config.i_config & OUTPUT_VALID)
1319 && !p_output->config.b_passthrough
1320 && (p_output->config.i_config & OUTPUT_DVB)
1321 && (!b_epg || (p_output->config.i_config & OUTPUT_EPG))
1322 && p_output->config.i_sid == p_sid->i_sid )
1324 eit_set_tsid( p_eit, p_output->i_tsid );
1326 if ( p_output->config.i_new_sid )
1327 eit_set_sid( p_eit, p_output->config.i_new_sid );
1328 else
1329 eit_set_sid( p_eit, p_output->config.i_sid );
1331 if ( p_output->config.i_onid )
1332 eit_set_onid( p_eit, p_output->config.i_onid );
1334 psi_set_crc( p_eit );
1336 OutputPSISection( p_output, p_eit, EIT_PID, &p_output->i_eit_cc,
1337 i_dts, &p_output->p_eit_ts_buffer,
1338 &p_output->i_eit_ts_buffer_offset );
1340 if ( p_output->config.i_onid )
1341 eit_set_onid( p_eit, i_onid );
1346 /*****************************************************************************
1347 * FlushEIT
1348 *****************************************************************************/
1349 static void FlushEIT( output_t *p_output, mtime_t i_dts )
1351 block_t *p_block = p_output->p_eit_ts_buffer;
1353 psi_split_end( p_block->p_ts, &p_output->i_eit_ts_buffer_offset );
1354 p_block->i_dts = i_dts;
1355 p_block->i_refcount--;
1356 output_Put( p_output, p_block );
1357 p_output->p_eit_ts_buffer = NULL;
1358 p_output->i_eit_ts_buffer_offset = 0;
1361 /*****************************************************************************
1362 * SendTDT
1363 *****************************************************************************/
1364 static void SendTDT( block_t *p_ts )
1366 int i;
1368 for ( i = 0; i < i_nb_outputs; i++ )
1370 output_t *p_output = pp_outputs[i];
1372 if ( (p_output->config.i_config & OUTPUT_VALID)
1373 && !p_output->config.b_passthrough
1374 && (p_output->config.i_config & OUTPUT_DVB)
1375 && p_output->p_sdt_section != NULL )
1376 output_Put( p_output, p_ts );
1380 /*****************************************************************************
1381 * NewPAT
1382 *****************************************************************************/
1383 static void NewPAT( output_t *p_output )
1385 const uint8_t *p_program;
1386 uint8_t *p;
1387 uint8_t k = 0;
1389 free( p_output->p_pat_section );
1390 p_output->p_pat_section = NULL;
1391 p_output->i_pat_version++;
1393 if ( !p_output->config.i_sid ) return;
1394 if ( !psi_table_validate(pp_current_pat_sections) ) return;
1396 p_program = pat_table_find_program( pp_current_pat_sections,
1397 p_output->config.i_sid );
1398 if ( p_program == NULL ) return;
1400 p = p_output->p_pat_section = psi_allocate();
1401 pat_init( p );
1402 psi_set_length( p, PSI_MAX_SIZE );
1403 pat_set_tsid( p, p_output->i_tsid );
1404 psi_set_version( p, p_output->i_pat_version );
1405 psi_set_current( p );
1406 psi_set_section( p, 0 );
1407 psi_set_lastsection( p, 0 );
1409 if ( p_output->config.i_config & OUTPUT_DVB )
1411 /* NIT */
1412 p = pat_get_program( p_output->p_pat_section, k++ );
1413 patn_init( p );
1414 patn_set_program( p, 0 );
1415 patn_set_pid( p, NIT_PID );
1418 p = pat_get_program( p_output->p_pat_section, k++ );
1419 patn_init( p );
1420 if ( p_output->config.i_new_sid )
1422 msg_Dbg( NULL, "Mapping PAT SID %d to %d", p_output->config.i_sid,
1423 p_output->config.i_new_sid );
1424 patn_set_program( p, p_output->config.i_new_sid );
1426 else
1427 patn_set_program( p, p_output->config.i_sid );
1429 if ( b_do_remap )
1431 msg_Dbg( NULL, "Mapping PMT PID %d to %d", patn_get_pid( p_program ), pi_newpids[I_PMTPID] );
1432 patn_set_pid( p, pi_newpids[I_PMTPID]);
1433 } else if ( p_output->config.b_do_remap && p_output->config.pi_confpids[I_PMTPID] ) {
1434 msg_Dbg( NULL, "Mapping PMT PID %d to %d", patn_get_pid( p_program ), p_output->config.pi_confpids[I_PMTPID] );
1435 patn_set_pid( p, p_output->config.pi_confpids[I_PMTPID]);
1436 } else {
1437 patn_set_pid( p, patn_get_pid( p_program ) );
1440 p = pat_get_program( p_output->p_pat_section, k );
1441 pat_set_length( p_output->p_pat_section,
1442 p - p_output->p_pat_section - PAT_HEADER_SIZE );
1443 psi_set_crc( p_output->p_pat_section );
1446 /*****************************************************************************
1447 * NewPMT
1448 *****************************************************************************/
1449 static void CopyDescriptors( uint8_t *p_descs, uint8_t *p_current_descs )
1451 uint8_t *p_desc;
1452 const uint8_t *p_current_desc;
1453 uint16_t j = 0, k = 0;
1455 descs_set_length( p_descs, DESCS_MAX_SIZE );
1457 while ( (p_current_desc = descs_get_desc( p_current_descs, j )) != NULL )
1459 uint8_t i_tag = desc_get_tag( p_current_desc );
1461 j++;
1462 if (i_tag == 0x9 ) continue;
1464 p_desc = descs_get_desc( p_descs, k );
1465 if ( p_desc == NULL ) continue; /* This shouldn't happen */
1466 k++;
1467 memcpy( p_desc, p_current_desc,
1468 DESC_HEADER_SIZE + desc_get_length( p_current_desc ) );
1471 p_desc = descs_get_desc( p_descs, k );
1472 if ( p_desc == NULL )
1473 /* This shouldn't happen if the incoming PMT is valid */
1474 descs_set_length( p_descs, 0 );
1475 else
1476 descs_set_length( p_descs, p_desc - p_descs - DESCS_HEADER_SIZE );
1479 static void NewPMT( output_t *p_output )
1481 sid_t *p_sid;
1482 uint8_t *p_current_pmt;
1483 uint8_t *p_es, *p_current_es;
1484 uint8_t *p;
1485 uint16_t j, k;
1486 uint16_t i_pcrpid;
1488 free( p_output->p_pmt_section );
1489 p_output->p_pmt_section = NULL;
1490 p_output->i_pmt_version++;
1492 if ( !p_output->config.i_sid ) return;
1494 p_sid = FindSID( p_output->config.i_sid );
1495 if ( p_sid == NULL ) return;
1497 if ( p_sid->p_current_pmt == NULL ) return;
1498 p_current_pmt = p_sid->p_current_pmt;
1500 p = p_output->p_pmt_section = psi_allocate();
1501 pmt_init( p );
1502 psi_set_length( p, PSI_MAX_SIZE );
1503 if ( p_output->config.i_new_sid )
1505 msg_Dbg( NULL, "Mapping PMT SID %d to %d", p_output->config.i_sid,
1506 p_output->config.i_new_sid );
1507 pmt_set_program( p, p_output->config.i_new_sid );
1509 else
1510 pmt_set_program( p, p_output->config.i_sid );
1511 psi_set_version( p, p_output->i_pmt_version );
1512 psi_set_current( p );
1513 pmt_set_desclength( p, 0 );
1514 init_pid_mapping( p_output );
1517 CopyDescriptors( pmt_get_descs( p ), pmt_get_descs( p_current_pmt ) );
1519 j = 0; k = 0;
1520 while ( (p_current_es = pmt_get_es( p_current_pmt, j )) != NULL )
1522 uint16_t i_pid = pmtn_get_pid( p_current_es );
1524 j++;
1525 if ( (p_output->config.i_nb_pids || !PIDWouldBeSelected( p_current_es ))
1526 && !IsIn( p_output->config.pi_pids, p_output->config.i_nb_pids,
1527 i_pid ) )
1528 continue;
1530 p_es = pmt_get_es( p, k );
1531 if ( p_es == NULL ) continue; /* This shouldn't happen */
1532 k++;
1533 pmtn_init( p_es );
1534 pmtn_set_streamtype( p_es, pmtn_get_streamtype( p_current_es ) );
1535 pmtn_set_pid( p_es, map_es_pid(p_output, p_current_es, i_pid) );
1536 pmtn_set_desclength( p_es, 0 );
1538 CopyDescriptors( pmtn_get_descs( p_es ),
1539 pmtn_get_descs( p_current_es ) );
1542 /* Do the pcr pid after everything else as it may have been remapped */
1543 i_pcrpid = pmt_get_pcrpid( p_current_pmt );
1544 if ( p_output->pi_newpids[i_pcrpid] != UNUSED_PID ) {
1545 msg_Dbg( NULL, "REMAP: The PCR PID was changed from 0x%x (%u) to 0x%x (%u)",
1546 i_pcrpid, i_pcrpid, p_output->pi_newpids[i_pcrpid], p_output->pi_newpids[i_pcrpid] );
1547 i_pcrpid = p_output->pi_newpids[i_pcrpid];
1548 } else {
1549 msg_Dbg( NULL, "The PCR PID has kept its original value of 0x%x (%u)", i_pcrpid, i_pcrpid);
1551 pmt_set_pcrpid( p, i_pcrpid );
1552 p_es = pmt_get_es( p, k );
1553 if ( p_es == NULL )
1554 /* This shouldn't happen if the incoming PMT is valid */
1555 pmt_set_length( p, 0 );
1556 else
1557 pmt_set_length( p, p_es - p - PMT_HEADER_SIZE );
1558 psi_set_crc( p );
1561 /*****************************************************************************
1562 * NewNIT
1563 *****************************************************************************/
1564 static void NewNIT( output_t *p_output )
1566 uint8_t *p_ts;
1567 uint8_t *p_header2;
1568 uint8_t *p;
1570 free( p_output->p_nit_section );
1571 p_output->p_nit_section = NULL;
1572 p_output->i_nit_version++;
1574 p = p_output->p_nit_section = psi_allocate();
1575 nit_init( p, true );
1576 nit_set_length( p, PSI_MAX_SIZE );
1577 nit_set_nid( p, p_output->config.i_network_id );
1578 psi_set_version( p, p_output->i_nit_version );
1579 psi_set_current( p );
1580 psi_set_section( p, 0 );
1581 psi_set_lastsection( p, 0 );
1583 if ( p_output->config.network_name.i )
1585 uint8_t *p_descs;
1586 uint8_t *p_desc;
1587 nit_set_desclength( p, DESCS_MAX_SIZE );
1588 p_descs = nit_get_descs( p );
1589 p_desc = descs_get_desc( p_descs, 0 );
1590 desc40_init( p_desc );
1591 desc40_set_networkname( p_desc, p_output->config.network_name.p,
1592 p_output->config.network_name.i );
1593 p_desc = descs_get_desc( p_descs, 1 );
1594 descs_set_length( p_descs, p_desc - p_descs - DESCS_HEADER_SIZE );
1596 else
1597 nit_set_desclength( p, 0 );
1599 p_header2 = nit_get_header2( p );
1600 nith_init( p_header2 );
1601 nith_set_tslength( p_header2, NIT_TS_SIZE );
1603 p_ts = nit_get_ts( p, 0 );
1604 nitn_init( p_ts );
1605 nitn_set_tsid( p_ts, p_output->i_tsid );
1606 if ( p_output->config.i_onid )
1607 nitn_set_onid( p_ts, p_output->config.i_onid );
1608 else
1609 nitn_set_onid( p_ts, p_output->config.i_network_id );
1610 nitn_set_desclength( p_ts, 0 );
1612 p_ts = nit_get_ts( p, 1 );
1613 if ( p_ts == NULL )
1614 /* This shouldn't happen */
1615 nit_set_length( p, 0 );
1616 else
1617 nit_set_length( p, p_ts - p - NIT_HEADER_SIZE );
1618 psi_set_crc( p_output->p_nit_section );
1621 /*****************************************************************************
1622 * NewSDT
1623 *****************************************************************************/
1624 static void NewSDT( output_t *p_output )
1626 uint8_t *p_service, *p_current_service;
1627 uint8_t *p;
1629 free( p_output->p_sdt_section );
1630 p_output->p_sdt_section = NULL;
1631 p_output->i_sdt_version++;
1633 if ( !p_output->config.i_sid ) return;
1634 if ( !psi_table_validate(pp_current_sdt_sections) ) return;
1636 p_current_service = sdt_table_find_service( pp_current_sdt_sections,
1637 p_output->config.i_sid );
1639 if ( p_current_service == NULL )
1641 if ( p_output->p_pat_section != NULL &&
1642 pat_get_program( p_output->p_pat_section, 0 ) == NULL )
1644 /* Empty PAT and no SDT anymore */
1645 free( p_output->p_pat_section );
1646 p_output->p_pat_section = NULL;
1647 p_output->i_pat_version++;
1649 return;
1652 p = p_output->p_sdt_section = psi_allocate();
1653 sdt_init( p, true );
1654 sdt_set_length( p, PSI_MAX_SIZE );
1655 sdt_set_tsid( p, p_output->i_tsid );
1656 psi_set_version( p, p_output->i_sdt_version );
1657 psi_set_current( p );
1658 psi_set_section( p, 0 );
1659 psi_set_lastsection( p, 0 );
1660 if ( p_output->config.i_onid )
1661 sdt_set_onid( p, p_output->config.i_onid );
1662 else
1663 sdt_set_onid( p,
1664 sdt_get_onid( psi_table_get_section( pp_current_sdt_sections, 0 ) ) );
1666 p_service = sdt_get_service( p, 0 );
1667 sdtn_init( p_service );
1668 if ( p_output->config.i_new_sid )
1670 msg_Dbg( NULL, "Mapping SDT SID %d to %d", p_output->config.i_sid,
1671 p_output->config.i_new_sid );
1672 sdtn_set_sid( p_service, p_output->config.i_new_sid );
1674 else
1675 sdtn_set_sid( p_service, p_output->config.i_sid );
1677 /* We always forward EITp/f */
1678 if ( sdtn_get_eitpresent(p_current_service) )
1679 sdtn_set_eitpresent(p_service);
1681 if ( (p_output->config.i_config & OUTPUT_EPG) == OUTPUT_EPG &&
1682 sdtn_get_eitschedule(p_current_service) )
1683 sdtn_set_eitschedule(p_service);
1685 sdtn_set_running( p_service, sdtn_get_running(p_current_service) );
1686 /* Do not set free_ca */
1687 sdtn_set_desclength( p_service, sdtn_get_desclength(p_current_service) );
1689 if ( !p_output->config.provider_name.i &&
1690 !p_output->config.service_name.i ) {
1691 /* Copy all descriptors unchanged */
1692 memcpy( descs_get_desc( sdtn_get_descs(p_service), 0 ),
1693 descs_get_desc( sdtn_get_descs(p_current_service), 0 ),
1694 sdtn_get_desclength(p_current_service) );
1695 } else {
1696 int j = 0, i_total_desc_len = 0;
1697 uint8_t *p_desc;
1698 uint8_t *p_new_desc = descs_get_desc( sdtn_get_descs(p_service), 0 );
1699 while ( (p_desc = descs_get_desc( sdtn_get_descs( p_current_service ), j++ )) != NULL )
1701 /* Regenerate descriptor 48 (service name) */
1702 if ( desc_get_tag( p_desc ) == 0x48 && desc48_validate( p_desc ) )
1704 uint8_t i_old_provider_len, i_old_service_len;
1705 uint8_t i_new_desc_len = 3; /* 1 byte - type, 1 byte provider_len, 1 byte service_len */
1706 const uint8_t *p_old_provider = desc48_get_provider( p_desc, &i_old_provider_len );
1707 const uint8_t *p_old_service = desc48_get_service( p_desc, &i_old_service_len );
1709 desc48_init( p_new_desc );
1710 desc48_set_type( p_new_desc, desc48_get_type( p_desc ) );
1712 if ( p_output->config.provider_name.i ) {
1713 desc48_set_provider( p_new_desc,
1714 p_output->config.provider_name.p,
1715 p_output->config.provider_name.i );
1716 i_new_desc_len += p_output->config.provider_name.i;
1717 } else {
1718 desc48_set_provider( p_new_desc, p_old_provider,
1719 i_old_provider_len );
1720 i_new_desc_len += i_old_provider_len;
1723 if ( p_output->config.service_name.i ) {
1724 desc48_set_service( p_new_desc,
1725 p_output->config.service_name.p,
1726 p_output->config.service_name.i );
1727 i_new_desc_len += p_output->config.service_name.i;
1728 } else {
1729 desc48_set_service( p_new_desc, p_old_service,
1730 i_old_service_len );
1731 i_new_desc_len += i_old_service_len;
1734 desc_set_length( p_new_desc, i_new_desc_len );
1735 i_total_desc_len += DESC_HEADER_SIZE + i_new_desc_len;
1736 p_new_desc += DESC_HEADER_SIZE + i_new_desc_len;
1737 } else {
1738 /* Copy single descriptor */
1739 int i_desc_len = DESC_HEADER_SIZE + desc_get_length( p_desc );
1740 memcpy( p_new_desc, p_desc, i_desc_len );
1741 p_new_desc += i_desc_len;
1742 i_total_desc_len += i_desc_len;
1745 sdtn_set_desclength( p_service, i_total_desc_len );
1748 p_service = sdt_get_service( p, 1 );
1749 if ( p_service == NULL )
1750 /* This shouldn't happen if the incoming SDT is valid */
1751 sdt_set_length( p, 0 );
1752 else
1753 sdt_set_length( p, p_service - p - SDT_HEADER_SIZE );
1754 psi_set_crc( p_output->p_sdt_section );
1757 /*****************************************************************************
1758 * UpdatePAT/PMT/SDT
1759 *****************************************************************************/
1760 #define DECLARE_UPDATE_FUNC( table ) \
1761 static void Update##table( uint16_t i_sid ) \
1763 int i; \
1765 for ( i = 0; i < i_nb_outputs; i++ ) \
1766 if ( ( pp_outputs[i]->config.i_config & OUTPUT_VALID ) \
1767 && pp_outputs[i]->config.i_sid == i_sid ) \
1768 New##table( pp_outputs[i] ); \
1771 DECLARE_UPDATE_FUNC(PAT)
1772 DECLARE_UPDATE_FUNC(PMT)
1773 DECLARE_UPDATE_FUNC(SDT)
1775 /*****************************************************************************
1776 * UpdateTSID
1777 *****************************************************************************/
1778 static void UpdateTSID(void)
1780 uint16_t i_tsid = psi_table_get_tableidext(pp_current_pat_sections);
1781 int i;
1783 for ( i = 0; i < i_nb_outputs; i++ )
1785 output_t *p_output = pp_outputs[i];
1787 if ( (p_output->config.i_config & OUTPUT_VALID)
1788 && p_output->config.i_tsid == -1 && !b_random_tsid )
1790 p_output->i_tsid = i_tsid;
1791 NewNIT( p_output );
1796 /*****************************************************************************
1797 * demux_PIDIsSelected
1798 *****************************************************************************/
1799 bool demux_PIDIsSelected( uint16_t i_pid )
1801 int i;
1803 for ( i = 0; i < p_pids[i_pid].i_nb_outputs; i++ )
1804 if ( p_pids[i_pid].pp_outputs[i] != NULL )
1805 return true;
1807 return false;
1810 /*****************************************************************************
1811 * PIDWouldBeSelected
1812 *****************************************************************************/
1813 static bool PIDWouldBeSelected( uint8_t *p_es )
1815 if ( b_any_type ) return true;
1817 uint8_t i_type = pmtn_get_streamtype( p_es );
1819 switch ( i_type )
1821 case 0x1: /* video MPEG-1 */
1822 case 0x2: /* video */
1823 case 0x3: /* audio MPEG-1 */
1824 case 0x4: /* audio */
1825 case 0xf: /* audio AAC ADTS */
1826 case 0x10: /* video MPEG-4 */
1827 case 0x11: /* audio AAC LATM */
1828 case 0x1b: /* video H264 */
1829 case 0x24: /* video H265 */
1830 case 0x81: /* ATSC A/52 */
1831 case 0x87: /* ATSC Enhanced A/52 */
1832 return true;
1833 break;
1835 case 0x6:
1837 uint16_t j = 0;
1838 const uint8_t *p_desc;
1840 while ( (p_desc = descs_get_desc( pmtn_get_descs( p_es ), j )) != NULL )
1842 uint8_t i_tag = desc_get_tag( p_desc );
1843 j++;
1845 if( i_tag == 0x46 /* VBI + teletext */
1846 || i_tag == 0x56 /* teletext */
1847 || i_tag == 0x59 /* dvbsub */
1848 || i_tag == 0x6a /* A/52 */
1849 || i_tag == 0x7a /* Enhanced A/52 */
1850 || i_tag == 0x7b /* DCA */
1851 || i_tag == 0x7c /* AAC */ )
1852 return true;
1854 break;
1857 default:
1858 break;
1861 /* FIXME: also parse IOD */
1862 return false;
1865 /*****************************************************************************
1866 * PIDCarriesPES
1867 *****************************************************************************/
1868 static bool PIDCarriesPES( const uint8_t *p_es )
1870 uint8_t i_type = pmtn_get_streamtype( p_es );
1872 switch ( i_type )
1874 case 0x1: /* video MPEG-1 */
1875 case 0x2: /* video */
1876 case 0x3: /* audio MPEG-1 */
1877 case 0x4: /* audio */
1878 case 0x6: /* private PES data */
1879 case 0xf: /* audio AAC */
1880 case 0x10: /* video MPEG-4 */
1881 case 0x11: /* audio AAC LATM */
1882 case 0x1b: /* video H264 */
1883 case 0x24: /* video H265 */
1884 case 0x81: /* ATSC A/52 */
1885 case 0x87: /* ATSC Enhanced A/52 */
1886 return true;
1887 break;
1889 default:
1890 return false;
1891 break;
1895 /*****************************************************************************
1896 * DeleteProgram
1897 *****************************************************************************/
1898 static void DeleteProgram( uint16_t i_sid, uint16_t i_pid )
1900 sid_t *p_sid;
1901 uint8_t *p_pmt;
1903 UnselectPMT( i_sid, i_pid );
1905 p_sid = FindSID( i_sid );
1906 if ( p_sid == NULL ) return;
1908 p_pmt = p_sid->p_current_pmt;
1910 if ( p_pmt != NULL )
1912 uint16_t i_pcr_pid = pmt_get_pcrpid( p_pmt );
1913 uint8_t *p_es;
1914 uint8_t j;
1916 if ( i_pcr_pid != PADDING_PID
1917 && i_pcr_pid != p_sid->i_pmt_pid )
1918 UnselectPID( i_sid, i_pcr_pid );
1920 j = 0;
1921 while ( (p_es = pmt_get_es( p_pmt, j )) != NULL )
1923 uint16_t i_pid = pmtn_get_pid( p_es );
1924 j++;
1926 if ( PIDWouldBeSelected( p_es ) )
1927 UnselectPID( i_sid, i_pid );
1930 free( p_pmt );
1931 p_sid->p_current_pmt = NULL;
1933 p_sid->i_sid = 0;
1934 p_sid->i_pmt_pid = 0;
1936 uint8_t r;
1937 for ( r = 0; r < MAX_EIT_TABLES; r++ ) {
1938 psi_table_free( p_sid->eit_table[r].data );
1939 psi_table_init( p_sid->eit_table[r].data );
1944 /*****************************************************************************
1945 * demux_Iconv
1946 *****************************************************************************
1947 * This code is from biTStream's examples and is under the WTFPL (see
1948 * LICENSE.WTFPL).
1949 *****************************************************************************/
1950 static char *iconv_append_null(const char *p_string, size_t i_length)
1952 char *psz_string = malloc(i_length + 1);
1953 memcpy(psz_string, p_string, i_length);
1954 psz_string[i_length] = '\0';
1955 return psz_string;
1958 char *demux_Iconv(void *_unused, const char *psz_encoding,
1959 char *p_string, size_t i_length)
1961 #ifdef HAVE_ICONV
1962 static const char *psz_current_encoding = "";
1964 char *psz_string, *p;
1965 size_t i_out_length;
1967 if (!strcmp(psz_encoding, psz_native_charset))
1968 return iconv_append_null(p_string, i_length);
1970 if (iconv_handle != (iconv_t)-1 &&
1971 strcmp(psz_encoding, psz_current_encoding)) {
1972 iconv_close(iconv_handle);
1973 iconv_handle = (iconv_t)-1;
1976 if (iconv_handle == (iconv_t)-1)
1977 iconv_handle = iconv_open(psz_native_charset, psz_encoding);
1978 if (iconv_handle == (iconv_t)-1) {
1979 msg_Warn(NULL, "couldn't open converter from %s to %s (%m)", psz_encoding,
1980 psz_native_charset);
1981 return iconv_append_null(p_string, i_length);
1983 psz_current_encoding = psz_encoding;
1985 /* converted strings can be up to six times larger */
1986 i_out_length = i_length * 6;
1987 p = psz_string = malloc(i_out_length);
1988 if (iconv(iconv_handle, &p_string, &i_length, &p, &i_out_length) == (size_t)-1) {
1989 msg_Warn(NULL, "couldn't convert from %s to %s (%m)", psz_encoding,
1990 psz_native_charset);
1991 free(psz_string);
1992 return iconv_append_null(p_string, i_length);
1994 if (i_length)
1995 msg_Warn(NULL, "partial conversion from %s to %s", psz_encoding,
1996 psz_native_charset);
1998 *p = '\0';
1999 return psz_string;
2000 #else
2001 return iconv_append_null(p_string, i_length);
2002 #endif
2005 /*****************************************************************************
2006 * demux_Print
2007 *****************************************************************************
2008 * This code is from biTStream's examples and is under the WTFPL (see
2009 * LICENSE.WTFPL).
2010 *****************************************************************************/
2011 __attribute__ ((format(printf, 2, 3)))
2012 static void demux_Print(void *_unused, const char *psz_format, ...)
2014 char psz_fmt[strlen(psz_format) + 2];
2015 va_list args;
2016 va_start(args, psz_format);
2017 strcpy(psz_fmt, psz_format);
2018 if ( i_print_type != PRINT_XML )
2019 strcat(psz_fmt, "\n");
2020 vprintf(psz_fmt, args);
2021 va_end(args);
2024 /*****************************************************************************
2025 * HandlePAT
2026 *****************************************************************************/
2027 static void HandlePAT( mtime_t i_dts )
2029 bool b_change = false;
2030 PSI_TABLE_DECLARE( pp_old_pat_sections );
2031 uint8_t i_last_section = psi_table_get_lastsection( pp_next_pat_sections );
2032 uint8_t i, r;
2034 if ( psi_table_validate( pp_current_pat_sections ) &&
2035 psi_table_compare( pp_current_pat_sections, pp_next_pat_sections ) )
2037 /* Identical PAT. Shortcut. */
2038 psi_table_free( pp_next_pat_sections );
2039 psi_table_init( pp_next_pat_sections );
2040 goto out_pat;
2043 if ( !pat_table_validate( pp_next_pat_sections ) )
2045 msg_Warn( NULL, "invalid PAT received" );
2046 switch (i_print_type) {
2047 case PRINT_XML:
2048 fprintf(print_fh, "<ERROR type=\"invalid_pat\"/>\n");
2049 break;
2050 case PRINT_TEXT:
2051 fprintf(print_fh, "error type: invalid_pat\n");
2052 break;
2053 default:
2054 break;
2056 psi_table_free( pp_next_pat_sections );
2057 psi_table_init( pp_next_pat_sections );
2058 goto out_pat;
2061 /* Switch tables. */
2062 psi_table_copy( pp_old_pat_sections, pp_current_pat_sections );
2063 psi_table_copy( pp_current_pat_sections, pp_next_pat_sections );
2064 psi_table_init( pp_next_pat_sections );
2066 if ( !psi_table_validate( pp_old_pat_sections )
2067 || psi_table_get_tableidext( pp_current_pat_sections )
2068 != psi_table_get_tableidext( pp_old_pat_sections ) )
2070 b_change = true;
2071 UpdateTSID();
2072 /* This will trigger a universal reset of everything. */
2075 for ( i = 0; i <= i_last_section; i++ )
2077 uint8_t *p_section =
2078 psi_table_get_section( pp_current_pat_sections, i );
2079 const uint8_t *p_program;
2080 int j = 0;
2082 while ( (p_program = pat_get_program( p_section, j )) != NULL )
2084 const uint8_t *p_old_program = NULL;
2085 uint16_t i_sid = patn_get_program( p_program );
2086 uint16_t i_pid = patn_get_pid( p_program );
2087 j++;
2089 if ( i_sid == 0 )
2091 if ( i_pid != NIT_PID )
2092 msg_Warn( NULL,
2093 "NIT is carried on PID %hu which isn't DVB compliant",
2094 i_pid );
2095 continue; /* NIT */
2098 if ( !psi_table_validate( pp_old_pat_sections )
2099 || (p_old_program = pat_table_find_program(
2100 pp_old_pat_sections, i_sid )) == NULL
2101 || patn_get_pid( p_old_program ) != i_pid
2102 || b_change )
2104 sid_t *p_sid;
2106 if ( p_old_program != NULL )
2107 DeleteProgram( i_sid, patn_get_pid( p_old_program ) );
2109 SelectPMT( i_sid, i_pid );
2111 p_sid = FindSID( 0 );
2112 if ( p_sid == NULL )
2114 p_sid = malloc( sizeof(sid_t) );
2115 p_sid->p_current_pmt = NULL;
2116 for ( r = 0; r < MAX_EIT_TABLES; r++ ) {
2117 psi_table_init( p_sid->eit_table[r].data );
2119 i_nb_sids++;
2120 pp_sids = realloc( pp_sids, sizeof(sid_t *) * i_nb_sids );
2121 pp_sids[i_nb_sids - 1] = p_sid;
2124 p_sid->i_sid = i_sid;
2125 p_sid->i_pmt_pid = i_pid;
2127 UpdatePAT( i_sid );
2132 if ( psi_table_validate( pp_old_pat_sections ) )
2134 i_last_section = psi_table_get_lastsection( pp_old_pat_sections );
2135 for ( i = 0; i <= i_last_section; i++ )
2137 uint8_t *p_section =
2138 psi_table_get_section( pp_old_pat_sections, i );
2139 const uint8_t *p_program;
2140 int j = 0;
2142 while ( (p_program = pat_get_program( p_section, j )) != NULL )
2144 uint16_t i_sid = patn_get_program( p_program );
2145 uint16_t i_pid = patn_get_pid( p_program );
2146 j++;
2148 if ( i_sid == 0 )
2149 continue; /* NIT */
2151 if ( pat_table_find_program( pp_current_pat_sections, i_sid )
2152 == NULL )
2154 DeleteProgram( i_sid, i_pid );
2155 UpdatePAT( i_sid );
2160 psi_table_free( pp_old_pat_sections );
2163 pat_table_print( pp_current_pat_sections, msg_Dbg, NULL, PRINT_TEXT );
2164 if ( b_print_enabled )
2166 pat_table_print( pp_current_pat_sections, demux_Print, NULL,
2167 i_print_type );
2168 if ( i_print_type == PRINT_XML )
2169 fprintf(print_fh, "\n");
2172 out_pat:
2173 SendPAT( i_dts );
2176 /*****************************************************************************
2177 * HandlePATSection
2178 *****************************************************************************/
2179 static void HandlePATSection( uint16_t i_pid, uint8_t *p_section,
2180 mtime_t i_dts )
2182 if ( i_pid != PAT_PID || !pat_validate( p_section ) )
2184 msg_Warn( NULL, "invalid PAT section received on PID %hu", i_pid );
2185 switch (i_print_type) {
2186 case PRINT_XML:
2187 fprintf(print_fh, "<ERROR type=\"invalid_pat_section\"/>\n");
2188 break;
2189 case PRINT_TEXT:
2190 fprintf(print_fh, "error type: invalid_pat_section\n");
2191 break;
2192 default:
2193 break;
2195 free( p_section );
2196 return;
2199 if ( !psi_table_section( pp_next_pat_sections, p_section ) )
2200 return;
2202 HandlePAT( i_dts );
2205 static void mark_pmt_pids( uint8_t *p_pmt, uint8_t pid_map[], uint8_t marker )
2207 uint16_t j;
2208 uint8_t *p_es;
2210 uint16_t i_pcr_pid = pmt_get_pcrpid( p_pmt );
2212 if ( i_pcr_pid != PADDING_PID )
2213 pid_map[ i_pcr_pid ] |= marker;
2215 j = 0;
2216 while ( (p_es = pmt_get_es( p_pmt, j )) != NULL )
2218 uint16_t i_pid = pmtn_get_pid( p_es );
2219 j++;
2221 if ( PIDWouldBeSelected( p_es ) )
2222 pid_map[ i_pid ] |= marker;
2224 p_pids[i_pid].b_pes = PIDCarriesPES( p_es );
2229 /*****************************************************************************
2230 * HandlePMT
2231 *****************************************************************************/
2232 static void HandlePMT( uint16_t i_pid, uint8_t *p_pmt, mtime_t i_dts )
2234 uint16_t i_sid = pmt_get_program( p_pmt );
2235 sid_t *p_sid;
2236 uint8_t pid_map[MAX_PIDS];
2238 p_sid = FindSID( i_sid );
2239 if ( p_sid == NULL )
2241 /* Unwanted SID (happens when the same PMT PID is used for several
2242 * programs). */
2243 free( p_pmt );
2244 return;
2247 if ( i_pid != p_sid->i_pmt_pid )
2249 msg_Warn( NULL, "invalid PMT section received on PID %hu", i_pid );
2250 switch (i_print_type) {
2251 case PRINT_XML:
2252 fprintf(print_fh, "<ERROR type=\"ghost_pmt\" program=\"%hu\n pid=\"%hu\"/>\n",
2253 i_sid, i_pid);
2254 break;
2255 case PRINT_TEXT:
2256 fprintf(print_fh, "error type: ghost_pmt program: %hu pid: %hu\n",
2257 i_sid, i_pid);
2258 break;
2259 default:
2260 break;
2262 free( p_pmt );
2263 return;
2266 if ( p_sid->p_current_pmt != NULL &&
2267 psi_compare( p_sid->p_current_pmt, p_pmt ) )
2269 /* Identical PMT. Shortcut. */
2270 free( p_pmt );
2271 goto out_pmt;
2274 if ( !pmt_validate( p_pmt ) )
2276 msg_Warn( NULL, "invalid PMT section received on PID %hu", i_pid );
2277 switch (i_print_type) {
2278 case PRINT_XML:
2279 fprintf(print_fh, "<ERROR type=\"invalid_pmt_section\" pid=\"%hu\"/>\n",
2280 i_pid);
2281 break;
2282 case PRINT_TEXT:
2283 fprintf(print_fh, "error type: invalid_pmt_section pid: %hu\n",
2284 i_pid);
2285 break;
2286 default:
2287 break;
2289 free( p_pmt );
2290 goto out_pmt;
2293 memset( pid_map, 0, sizeof(pid_map) );
2295 if ( p_sid->p_current_pmt != NULL )
2297 mark_pmt_pids( p_sid->p_current_pmt, pid_map, 0x02 );
2298 free( p_sid->p_current_pmt );
2301 mark_pmt_pids( p_pmt, pid_map, 0x01 );
2303 uint16_t i_pcr_pid = pmt_get_pcrpid( p_pmt );
2304 int i;
2305 for ( i = 0; i < i_nb_outputs; i++ )
2306 if ( (pp_outputs[i]->config.i_config & OUTPUT_VALID)
2307 && pp_outputs[i]->config.i_sid == i_sid )
2308 pp_outputs[i]->i_pcr_pid = 0;
2310 /* Start to stream PIDs */
2311 int pid;
2312 for ( pid = 0; pid < MAX_PIDS; pid++ )
2314 /* The pid does not exist in the old PMT and in the new PMT. Ignore this pid. */
2315 if ( !pid_map[ pid ] )
2316 continue;
2318 switch ( pid_map[ pid ] & 0x03 ) {
2319 case 0x03: /* The pid exists in the old PMT and in the new PMT. The pid was already selected in case 0x01. */
2320 continue;
2321 case 0x02: /* The pid does not exist in the new PMT but exists in the old PMT. Unselect it. */
2322 UnselectPID( i_sid, pid );
2323 break;
2324 case 0x01: /* The pid exists in new PMT. Select it. */
2325 SelectPID( i_sid, pid, pid == i_pcr_pid );
2326 break;
2330 p_sid->p_current_pmt = p_pmt;
2332 UpdatePMT( i_sid );
2334 pmt_print( p_pmt, msg_Dbg, NULL, demux_Iconv, NULL, PRINT_TEXT );
2335 if ( b_print_enabled )
2337 pmt_print( p_pmt, demux_Print, NULL, demux_Iconv, NULL,
2338 i_print_type );
2339 if ( i_print_type == PRINT_XML )
2340 fprintf(print_fh, "\n");
2343 out_pmt:
2344 SendPMT( p_sid, i_dts );
2347 /*****************************************************************************
2348 * HandleNIT
2349 *****************************************************************************/
2350 static void HandleNIT( mtime_t i_dts )
2352 if ( psi_table_validate( pp_current_nit_sections ) &&
2353 psi_table_compare( pp_current_nit_sections, pp_next_nit_sections ) )
2355 /* Identical NIT. Shortcut. */
2356 psi_table_free( pp_next_nit_sections );
2357 psi_table_init( pp_next_nit_sections );
2358 goto out_nit;
2361 if ( !nit_table_validate( pp_next_nit_sections ) )
2363 msg_Warn( NULL, "invalid NIT received" );
2364 switch (i_print_type) {
2365 case PRINT_XML:
2366 fprintf(print_fh, "<ERROR type=\"invalid_nit\"/>\n");
2367 break;
2368 case PRINT_TEXT:
2369 fprintf(print_fh, "error type: invalid_nit\n");
2370 break;
2371 default:
2372 break;
2374 psi_table_free( pp_next_nit_sections );
2375 psi_table_init( pp_next_nit_sections );
2376 goto out_nit;
2379 /* Switch tables. */
2380 psi_table_free( pp_current_nit_sections );
2381 psi_table_copy( pp_current_nit_sections, pp_next_nit_sections );
2382 psi_table_init( pp_next_nit_sections );
2384 nit_table_print( pp_current_nit_sections, msg_Dbg, NULL,
2385 demux_Iconv, NULL, PRINT_TEXT );
2386 if ( b_print_enabled )
2388 nit_table_print( pp_current_nit_sections, demux_Print, NULL,
2389 demux_Iconv, NULL, i_print_type );
2390 if ( i_print_type == PRINT_XML )
2391 fprintf(print_fh, "\n");
2394 out_nit:
2398 /*****************************************************************************
2399 * HandleNITSection
2400 *****************************************************************************/
2401 static void HandleNITSection( uint16_t i_pid, uint8_t *p_section,
2402 mtime_t i_dts )
2404 if ( i_pid != NIT_PID || !nit_validate( p_section ) )
2406 msg_Warn( NULL, "invalid NIT section received on PID %hu", i_pid );
2407 switch (i_print_type) {
2408 case PRINT_XML:
2409 fprintf(print_fh, "<ERROR type=\"invalid_nit_section\" pid=\"%hu\"/>\n",
2410 i_pid);
2411 break;
2412 case PRINT_TEXT:
2413 fprintf(print_fh, "error type: invalid_nit_section pid: %hu\n",
2414 i_pid);
2415 break;
2416 default:
2417 break;
2419 free( p_section );
2420 return;
2423 if ( psi_table_section( pp_next_nit_sections, p_section ) )
2424 HandleNIT( i_dts );
2426 /* This case is different because DVB specifies a minimum bitrate for
2427 * PID 0x10, even if we don't have any thing to send (for cheap
2428 * transport over network boundaries). */
2429 SendNIT( i_dts );
2433 /*****************************************************************************
2434 * HandleSDT
2435 *****************************************************************************/
2436 static void HandleSDT( mtime_t i_dts )
2438 PSI_TABLE_DECLARE( pp_old_sdt_sections );
2439 uint8_t i_last_section = psi_table_get_lastsection( pp_next_sdt_sections );
2440 uint8_t i;
2441 int j;
2443 if ( psi_table_validate( pp_current_sdt_sections ) &&
2444 psi_table_compare( pp_current_sdt_sections, pp_next_sdt_sections ) )
2446 /* Identical SDT. Shortcut. */
2447 psi_table_free( pp_next_sdt_sections );
2448 psi_table_init( pp_next_sdt_sections );
2449 goto out_sdt;
2452 if ( !sdt_table_validate( pp_next_sdt_sections ) )
2454 msg_Warn( NULL, "invalid SDT received" );
2455 switch (i_print_type) {
2456 case PRINT_XML:
2457 fprintf(print_fh, "<ERROR type=\"invalid_sdt\"/>\n");
2458 break;
2459 case PRINT_TEXT:
2460 fprintf(print_fh, "error type: invalid_sdt\n");
2461 break;
2462 default:
2463 break;
2465 psi_table_free( pp_next_sdt_sections );
2466 psi_table_init( pp_next_sdt_sections );
2467 goto out_sdt;
2470 /* Switch tables. */
2471 psi_table_copy( pp_old_sdt_sections, pp_current_sdt_sections );
2472 psi_table_copy( pp_current_sdt_sections, pp_next_sdt_sections );
2473 psi_table_init( pp_next_sdt_sections );
2475 for ( i = 0; i <= i_last_section; i++ )
2477 uint8_t *p_section =
2478 psi_table_get_section( pp_current_sdt_sections, i );
2479 uint8_t *p_service;
2480 j = 0;
2482 while ( (p_service = sdt_get_service( p_section, j )) != NULL )
2484 uint16_t i_sid = sdtn_get_sid( p_service );
2485 j++;
2487 UpdateSDT( i_sid );
2491 if ( psi_table_validate( pp_old_sdt_sections ) )
2493 i_last_section = psi_table_get_lastsection( pp_old_sdt_sections );
2494 for ( i = 0; i <= i_last_section; i++ )
2496 uint8_t *p_section =
2497 psi_table_get_section( pp_old_sdt_sections, i );
2498 const uint8_t *p_service;
2499 int j = 0;
2501 while ( (p_service = sdt_get_service( p_section, j )) != NULL )
2503 uint16_t i_sid = sdtn_get_sid( p_service );
2504 j++;
2506 if ( sdt_table_find_service( pp_current_sdt_sections, i_sid )
2507 == NULL )
2508 UpdateSDT( i_sid );
2512 psi_table_free( pp_old_sdt_sections );
2515 sdt_table_print( pp_current_sdt_sections, msg_Dbg, NULL,
2516 demux_Iconv, NULL, PRINT_TEXT );
2517 if ( b_print_enabled )
2519 sdt_table_print( pp_current_sdt_sections, demux_Print, NULL,
2520 demux_Iconv, NULL, i_print_type );
2521 if ( i_print_type == PRINT_XML )
2522 fprintf(print_fh, "\n");
2525 out_sdt:
2526 SendSDT( i_dts );
2529 /*****************************************************************************
2530 * HandleSDTSection
2531 *****************************************************************************/
2532 static void HandleSDTSection( uint16_t i_pid, uint8_t *p_section,
2533 mtime_t i_dts )
2535 if ( i_pid != SDT_PID || !sdt_validate( p_section ) )
2537 msg_Warn( NULL, "invalid SDT section received on PID %hu", i_pid );
2538 switch (i_print_type) {
2539 case PRINT_XML:
2540 fprintf(print_fh, "<ERROR type=\"invalid_sdt_section\" pid=\"%hu\"/>\n",
2541 i_pid);
2542 break;
2543 case PRINT_TEXT:
2544 fprintf(print_fh, "error type: invalid_sdt_section pid: %hu\n",
2545 i_pid);
2546 break;
2547 default:
2548 break;
2550 free( p_section );
2551 return;
2554 if ( !psi_table_section( pp_next_sdt_sections, p_section ) )
2555 return;
2557 HandleSDT( i_dts );
2560 /*****************************************************************************
2561 * HandleEITSection
2562 *****************************************************************************/
2563 static void HandleEIT( uint16_t i_pid, uint8_t *p_eit, mtime_t i_dts )
2565 uint8_t i_table_id = psi_get_tableid( p_eit );
2566 uint16_t i_sid = eit_get_sid( p_eit );
2567 sid_t *p_sid;
2569 p_sid = FindSID( i_sid );
2570 if ( p_sid == NULL )
2572 /* Not a selected program. */
2573 free( p_eit );
2574 return;
2577 if ( i_pid != EIT_PID || !eit_validate( p_eit ) )
2579 msg_Warn( NULL, "invalid EIT section received on PID %hu", i_pid );
2580 switch (i_print_type) {
2581 case PRINT_XML:
2582 fprintf(print_fh, "<ERROR type=\"invalid_eit_section\" pid=\"%hu\"/>\n",
2583 i_pid);
2584 break;
2585 case PRINT_TEXT:
2586 fprintf(print_fh, "error type: invalid_eit_section pid: %hu\n",
2587 i_pid);
2588 break;
2589 default:
2590 break;
2592 free( p_eit );
2593 return;
2596 bool b_epg = handle_epg( i_table_id );
2597 if ( ! b_epg )
2598 goto out_eit;
2600 /* We do not use psi_table_* primitives as the spec allows for holes in
2601 * section numbering, and there is no sure way to know whether you have
2602 * gathered all sections. */
2603 uint8_t i_section = psi_get_section(p_eit);
2604 uint8_t eit_table_id = i_table_id - EIT_TABLE_ID_PF_ACTUAL;
2605 if (eit_table_id >= MAX_EIT_TABLES)
2606 goto out_eit;
2607 if (p_sid->eit_table[eit_table_id].data[i_section] != NULL &&
2608 psi_compare(p_sid->eit_table[eit_table_id].data[i_section], p_eit)) {
2609 /* Identical section. Shortcut. */
2610 free(p_sid->eit_table[eit_table_id].data[i_section]);
2611 p_sid->eit_table[eit_table_id].data[i_section] = p_eit;
2612 goto out_eit;
2615 free(p_sid->eit_table[eit_table_id].data[i_section]);
2616 p_sid->eit_table[eit_table_id].data[i_section] = p_eit;
2618 if ( b_print_enabled && psi_get_tableid( p_eit ) == EIT_TABLE_ID_PF_ACTUAL )
2620 eit_print( p_eit, demux_Print, NULL,
2621 demux_Iconv, NULL, i_print_type );
2622 if ( i_print_type == PRINT_XML )
2623 fprintf(print_fh, "\n");
2626 out_eit:
2627 SendEIT( p_sid, i_dts, p_eit );
2628 if ( ! b_epg )
2629 free( p_eit );
2632 /*****************************************************************************
2633 * HandleSection
2634 *****************************************************************************/
2635 static void HandleSection( uint16_t i_pid, uint8_t *p_section, mtime_t i_dts )
2637 uint8_t i_table_id = psi_get_tableid( p_section );
2639 if ( !psi_validate( p_section ) )
2641 msg_Warn( NULL, "invalid section on PID %hu", i_pid );
2642 switch (i_print_type) {
2643 case PRINT_XML:
2644 fprintf(print_fh, "<ERROR type=\"invalid_section\" pid=\"%hu\"/>\n", i_pid);
2645 break;
2646 case PRINT_TEXT:
2647 fprintf(print_fh, "error type: invalid_section pid: %hu\n", i_pid);
2648 break;
2649 default:
2650 break;
2652 free( p_section );
2653 return;
2656 if ( !psi_get_current( p_section ) )
2658 /* Ignore sections which are not in use yet. */
2659 free( p_section );
2660 return;
2663 switch ( i_table_id )
2665 case PAT_TABLE_ID:
2666 HandlePATSection( i_pid, p_section, i_dts );
2667 break;
2669 case PMT_TABLE_ID:
2670 HandlePMT( i_pid, p_section, i_dts );
2671 break;
2673 case NIT_TABLE_ID_ACTUAL:
2674 HandleNITSection( i_pid, p_section, i_dts );
2675 break;
2677 case SDT_TABLE_ID_ACTUAL:
2678 HandleSDTSection( i_pid, p_section, i_dts );
2679 break;
2681 default:
2682 if ( handle_epg( i_table_id ) )
2684 HandleEIT( i_pid, p_section, i_dts );
2685 break;
2687 free( p_section );
2688 break;
2692 /*****************************************************************************
2693 * HandlePSIPacket
2694 *****************************************************************************/
2695 static void HandlePSIPacket( uint8_t *p_ts, mtime_t i_dts )
2697 uint16_t i_pid = ts_get_pid( p_ts );
2698 ts_pid_t *p_pid = &p_pids[i_pid];
2699 uint8_t i_cc = ts_get_cc( p_ts );
2700 const uint8_t *p_payload;
2701 uint8_t i_length;
2703 if ( ts_check_duplicate( i_cc, p_pid->i_last_cc )
2704 || !ts_has_payload( p_ts ) )
2705 return;
2707 if ( p_pid->i_last_cc != -1
2708 && ts_check_discontinuity( i_cc, p_pid->i_last_cc ) )
2709 psi_assemble_reset( &p_pid->p_psi_buffer, &p_pid->i_psi_buffer_used );
2711 p_payload = ts_section( p_ts );
2712 i_length = p_ts + TS_SIZE - p_payload;
2714 if ( !psi_assemble_empty( &p_pid->p_psi_buffer,
2715 &p_pid->i_psi_buffer_used ) )
2717 uint8_t *p_section = psi_assemble_payload( &p_pid->p_psi_buffer,
2718 &p_pid->i_psi_buffer_used,
2719 &p_payload, &i_length );
2720 if ( p_section != NULL )
2721 HandleSection( i_pid, p_section, i_dts );
2724 p_payload = ts_next_section( p_ts );
2725 i_length = p_ts + TS_SIZE - p_payload;
2727 while ( i_length )
2729 uint8_t *p_section = psi_assemble_payload( &p_pid->p_psi_buffer,
2730 &p_pid->i_psi_buffer_used,
2731 &p_payload, &i_length );
2732 if ( p_section != NULL )
2733 HandleSection( i_pid, p_section, i_dts );
2737 /*****************************************************************************
2738 * PID info functions
2739 *****************************************************************************/
2740 static const char *h222_stream_type_desc(uint8_t i_stream_type) {
2741 /* See ISO/IEC 13818-1 : 2000 (E) | Table 2-29 - Stream type assignments, Page 66 (48) */
2742 if (i_stream_type == 0)
2743 return "Reserved stream";
2744 switch (i_stream_type) {
2745 case 0x01: return "11172-2 video (MPEG-1)";
2746 case 0x02: return "H.262/13818-2 video (MPEG-2) or 11172-2 constrained video";
2747 case 0x03: return "11172-3 audio (MPEG-1)";
2748 case 0x04: return "13818-3 audio (MPEG-2)";
2749 case 0x05: return "H.222.0/13818-1 private sections";
2750 case 0x06: return "H.222.0/13818-1 PES private data";
2751 case 0x07: return "13522 MHEG";
2752 case 0x08: return "H.222.0/13818-1 Annex A - DSM CC";
2753 case 0x09: return "H.222.1";
2754 case 0x0A: return "13818-6 type A";
2755 case 0x0B: return "13818-6 type B";
2756 case 0x0C: return "13818-6 type C";
2757 case 0x0D: return "13818-6 type D";
2758 case 0x0E: return "H.222.0/13818-1 auxiliary";
2759 case 0x0F: return "13818-7 Audio with ADTS transport syntax";
2760 case 0x10: return "14496-2 Visual (MPEG-4 part 2 video)";
2761 case 0x11: return "14496-3 Audio with LATM transport syntax (14496-3/AMD 1)";
2762 case 0x12: return "14496-1 SL-packetized or FlexMux stream in PES packets";
2763 case 0x13: return "14496-1 SL-packetized or FlexMux stream in 14496 sections";
2764 case 0x14: return "ISO/IEC 13818-6 Synchronized Download Protocol";
2765 case 0x15: return "Metadata in PES packets";
2766 case 0x16: return "Metadata in metadata_sections";
2767 case 0x17: return "Metadata in 13818-6 Data Carousel";
2768 case 0x18: return "Metadata in 13818-6 Object Carousel";
2769 case 0x19: return "Metadata in 13818-6 Synchronized Download Protocol";
2770 case 0x1A: return "13818-11 MPEG-2 IPMP stream";
2771 case 0x1B: return "H.264/14496-10 video (MPEG-4/AVC)";
2772 case 0x24: return "H.265/23008-2 video (HEVC)";
2773 case 0x42: return "AVS Video";
2774 case 0x7F: return "IPMP stream";
2775 default : return "Unknown stream";
2779 static const char *get_pid_desc(uint16_t i_pid, uint16_t *i_sid) {
2780 int i, j, k;
2781 uint8_t i_last_section;
2782 uint8_t *p_desc;
2783 uint16_t i_nit_pid = NIT_PID, i_pcr_pid = 0;
2785 /* Simple cases */
2786 switch (i_pid)
2788 case 0x00: return "PAT";
2789 case 0x01: return "CAT";
2790 case 0x11: return "SDT";
2791 case 0x12: return "EPG";
2792 case 0x14: return "TDT/TOT";
2795 /* Detect NIT pid */
2796 if ( psi_table_validate( pp_current_pat_sections ) )
2798 i_last_section = psi_table_get_lastsection( pp_current_pat_sections );
2799 for ( i = 0; i <= i_last_section; i++ )
2801 uint8_t *p_section = psi_table_get_section( pp_current_pat_sections, i );
2802 uint8_t *p_program;
2804 j = 0;
2805 while ( (p_program = pat_get_program( p_section, j++ )) != NULL )
2807 /* Programs with PID == 0 are actually NIT */
2808 if ( patn_get_program( p_program ) == 0 )
2810 i_nit_pid = patn_get_pid( p_program );
2811 break;
2817 /* Detect streams in PMT */
2818 for ( k = 0; k < i_nb_sids; k++ )
2820 sid_t *p_sid = pp_sids[k];
2821 if ( p_sid->i_pmt_pid == i_pid )
2823 if ( i_sid )
2824 *i_sid = p_sid->i_sid;
2825 return "PMT";
2828 if ( p_sid->i_sid && p_sid->p_current_pmt != NULL )
2830 uint8_t *p_current_pmt = p_sid->p_current_pmt;
2831 uint8_t *p_current_es;
2833 /* The PCR PID can be alone or PCR can be carried in some other PIDs (mostly video)
2834 so just remember the pid and if it is alone it will be reported as PCR, otherwise
2835 stream type of the PID will be reported */
2836 if ( i_pid == pmt_get_pcrpid( p_current_pmt ) ) {
2837 if ( i_sid )
2838 *i_sid = p_sid->i_sid;
2839 i_pcr_pid = pmt_get_pcrpid( p_current_pmt );
2842 /* Look for ECMs */
2843 j = 0;
2844 while ((p_desc = descs_get_desc( pmt_get_descs( p_current_pmt ), j++ )) != NULL)
2846 if ( desc_get_tag( p_desc ) != 0x09 || !desc09_validate( p_desc ) )
2847 continue;
2849 if ( desc09_get_pid( p_desc ) == i_pid ) {
2850 if ( i_sid )
2851 *i_sid = p_sid->i_sid;
2852 return "ECM";
2856 /* Detect stream types */
2857 j = 0;
2858 while ( (p_current_es = pmt_get_es( p_current_pmt, j++ )) != NULL )
2860 if ( pmtn_get_pid( p_current_es ) == i_pid )
2862 if ( i_sid )
2863 *i_sid = p_sid->i_sid;
2864 return h222_stream_type_desc( pmtn_get_streamtype( p_current_es ) );
2870 /* Are there any other PIDs? */
2871 if (i_pid == i_nit_pid)
2872 return "NIT";
2874 if (i_pid == i_pcr_pid)
2875 return "PCR";
2877 return "...";
2880 /*****************************************************************************
2881 * Functions that return packed sections
2882 *****************************************************************************/
2883 uint8_t *demux_get_current_packed_PAT( unsigned int *pi_pack_size ) {
2884 return psi_pack_sections( pp_current_pat_sections, pi_pack_size );
2887 uint8_t *demux_get_current_packed_CAT( unsigned int *pi_pack_size ) {
2888 return psi_pack_sections( pp_current_cat_sections, pi_pack_size );
2891 uint8_t *demux_get_current_packed_NIT( unsigned int *pi_pack_size ) {
2892 return psi_pack_sections( pp_current_nit_sections, pi_pack_size );
2895 uint8_t *demux_get_current_packed_SDT( unsigned int *pi_pack_size ) {
2896 return psi_pack_sections( pp_current_sdt_sections, pi_pack_size );
2899 uint8_t *demux_get_packed_EIT( uint16_t i_sid, uint8_t start_table, uint8_t end_table, unsigned int *eit_size ) {
2900 unsigned int i, r;
2902 *eit_size = 0;
2903 sid_t *p_sid = FindSID( i_sid );
2904 if ( p_sid == NULL )
2905 return NULL;
2907 /* Calculate eit table size (sum of all sections in all tables between start_start and end_table) */
2908 for ( i = start_table; i <= end_table; i++ ) {
2909 uint8_t eit_table_idx = i - EIT_TABLE_ID_PF_ACTUAL;
2910 if ( eit_table_idx >= MAX_EIT_TABLES )
2911 continue;
2912 uint8_t **eit_sections = p_sid->eit_table[eit_table_idx].data;
2913 for ( r = 0; r < PSI_TABLE_MAX_SECTIONS; r++ ) {
2914 uint8_t *p_eit = eit_sections[r];
2915 if ( !p_eit )
2916 continue;
2917 uint16_t psi_length = psi_get_length( p_eit ) + PSI_HEADER_SIZE;
2918 *eit_size += psi_length;
2922 uint8_t *p_flat_section = malloc( *eit_size );
2923 if ( !p_flat_section )
2924 return NULL;
2926 /* Copy sections */
2927 unsigned int i_pos = 0;
2928 for ( i = start_table; i <= end_table; i++ ) {
2929 uint8_t eit_table_idx = i - EIT_TABLE_ID_PF_ACTUAL;
2930 if ( eit_table_idx >= MAX_EIT_TABLES )
2931 continue;
2932 uint8_t **eit_sections = p_sid->eit_table[eit_table_idx].data;
2933 for ( r = 0; r < PSI_TABLE_MAX_SECTIONS; r++ ) {
2934 uint8_t *p_eit = eit_sections[r];
2935 if ( !p_eit )
2936 continue;
2937 uint16_t psi_length = psi_get_length( p_eit ) + PSI_HEADER_SIZE;
2938 memcpy( p_flat_section + i_pos, p_eit, psi_length );
2939 i_pos += psi_length;
2940 /* eit_print( p_eit, msg_Dbg, NULL, demux_Iconv, NULL, PRINT_TEXT ); */
2943 return p_flat_section;
2946 uint8_t *demux_get_packed_EIT_pf( uint16_t service_id, unsigned int *pi_pack_size ) {
2947 return demux_get_packed_EIT( service_id, EIT_TABLE_ID_PF_ACTUAL, EIT_TABLE_ID_PF_ACTUAL, pi_pack_size );
2950 uint8_t *demux_get_packed_EIT_schedule( uint16_t service_id, unsigned int *pi_pack_size ) {
2951 return demux_get_packed_EIT( service_id, EIT_TABLE_ID_SCHED_ACTUAL_FIRST, EIT_TABLE_ID_SCHED_ACTUAL_LAST, pi_pack_size );
2954 uint8_t *demux_get_packed_PMT( uint16_t i_sid, unsigned int *pi_pack_size ) {
2955 sid_t *p_sid = FindSID( i_sid );
2956 if ( p_sid != NULL && p_sid->p_current_pmt && pmt_validate( p_sid->p_current_pmt ) )
2957 return psi_pack_section( p_sid->p_current_pmt, pi_pack_size );
2958 return NULL;
2961 inline void demux_get_PID_info( uint16_t i_pid, uint8_t *p_data ) {
2962 ts_pid_info_t *p_info = (ts_pid_info_t *)p_data;
2963 *p_info = p_pids[i_pid].info;
2966 inline void demux_get_PIDS_info( uint8_t *p_data ) {
2967 int i_pid;
2968 for (i_pid = 0; i_pid < MAX_PIDS; i_pid++ )
2969 demux_get_PID_info( i_pid, p_data + ( i_pid * sizeof(ts_pid_info_t) ) );