1 /*
2 * Tvheadend - TS file input system
3 *
4 * Copyright (C) 2013 Adam Sutton
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #ifndef __TVH_MPEGTS_H__
21 #define __TVH_MPEGTS_H__
22
23 #ifndef __TVH_INPUT_H__
24 #error "Use header file input.h not input/mpegts.h"
25 #endif
26
27 #include "atomic.h"
28 #include "input.h"
29 #include "service.h"
30 #include "mpegts/dvb.h"
31 #include "subscriptions.h"
32
33 #define MPEGTS_ONID_NONE 0xFFFF
34 #define MPEGTS_TSID_NONE 0xFFFF
35 #define MPEGTS_FULLMUX_PID 0x2000
36 #define MPEGTS_TABLES_PID 0x2001
37 #define MPEGTS_PID_NONE 0xFFFF
38
39 /* Types */
40 typedef struct mpegts_apid mpegts_apid_t;
41 typedef struct mpegts_apids mpegts_apids_t;
42 typedef struct mpegts_table mpegts_table_t;
43 typedef struct mpegts_network mpegts_network_t;
44 typedef struct mpegts_mux mpegts_mux_t;
45 typedef struct mpegts_service mpegts_service_t;
46 typedef struct mpegts_mux_instance mpegts_mux_instance_t;
47 typedef struct mpegts_mux_sub mpegts_mux_sub_t;
48 typedef struct mpegts_input mpegts_input_t;
49 typedef struct mpegts_table_feed mpegts_table_feed_t;
50 typedef struct mpegts_network_link mpegts_network_link_t;
51 typedef struct mpegts_packet mpegts_packet_t;
52 typedef struct mpegts_pcr mpegts_pcr_t;
53 typedef struct mpegts_buffer mpegts_buffer_t;
54
55 /* Lists */
56 typedef LIST_HEAD (,mpegts_network) mpegts_network_list_t;
57 typedef LIST_HEAD (,mpegts_input) mpegts_input_list_t;
58 typedef TAILQ_HEAD(mpegts_mux_queue,mpegts_mux) mpegts_mux_queue_t;
59 typedef LIST_HEAD (,mpegts_mux) mpegts_mux_list_t;
60 typedef LIST_HEAD (,mpegts_network_link) mpegts_network_link_list_t;
61 typedef TAILQ_HEAD(mpegts_table_feed_queue, mpegts_table_feed)
62 mpegts_table_feed_queue_t;
63
64 /* Classes */
65 extern const idclass_t mpegts_network_class;
66 extern const idclass_t mpegts_mux_class;
67 extern const idclass_t mpegts_mux_instance_class;
68 extern const idclass_t mpegts_service_class;
69 extern const idclass_t mpegts_service_raw_class;
70 extern const idclass_t mpegts_input_class;
71
72 /* **************************************************************************
73 * Setup / Tear down
74 * *************************************************************************/
75
76 void mpegts_init ( int linuxdvb_mask, int nosatip, str_list_t *satip_client,
77 str_list_t *tsfiles, int tstuners );
78 void mpegts_done ( void );
79
80 /* **************************************************************************
81 * PIDs
82 * *************************************************************************/
83
84 struct mpegts_apid {
85 uint16_t pid;
86 uint16_t weight;
87 };
88
89 struct mpegts_apids {
90 mpegts_apid_t *pids;
91 int alloc;
92 int count;
93 int all;
94 int sorted;
95 };
96
97 int mpegts_pid_init ( mpegts_apids_t *pids );
98 void mpegts_pid_done ( mpegts_apids_t *pids );
99 mpegts_apids_t *mpegts_pid_alloc ( void );
100 void mpegts_pid_destroy ( mpegts_apids_t **pids );
101 void mpegts_pid_reset ( mpegts_apids_t *pids );
102 int mpegts_pid_add ( mpegts_apids_t *pids, uint16_t pid, uint16_t weight );
103 int mpegts_pid_add_group ( mpegts_apids_t *pids, mpegts_apids_t *vals );
104 int mpegts_pid_del ( mpegts_apids_t *pids, uint16_t pid, uint16_t weight );
105 int mpegts_pid_del_group ( mpegts_apids_t *pids, mpegts_apids_t *vals );
106 int mpegts_pid_find_windex ( mpegts_apids_t *pids, uint16_t pid, uint16_t weight );
107 int mpegts_pid_find_rindex ( mpegts_apids_t *pids, uint16_t pid );
mpegts_pid_wexists(mpegts_apids_t * pids,uint16_t pid,uint16_t weight)108 static inline int mpegts_pid_wexists ( mpegts_apids_t *pids, uint16_t pid, uint16_t weight )
109 { return pids && (pids->all || mpegts_pid_find_windex(pids, pid, weight) >= 0); }
mpegts_pid_rexists(mpegts_apids_t * pids,uint16_t pid)110 static inline int mpegts_pid_rexists ( mpegts_apids_t *pids, uint16_t pid )
111 { return pids && (pids->all || mpegts_pid_find_rindex(pids, pid) >= 0); }
112 int mpegts_pid_copy ( mpegts_apids_t *dst, mpegts_apids_t *src );
113 int mpegts_pid_compare ( mpegts_apids_t *dst, mpegts_apids_t *src,
114 mpegts_apids_t *add, mpegts_apids_t *del );
115 int mpegts_pid_weighted( mpegts_apids_t *dst, mpegts_apids_t *src, int limit );
116 int mpegts_pid_dump ( mpegts_apids_t *pids, char *buf, int len, int wflag, int raw );
117
118 /* **************************************************************************
119 * Data / SI processing
120 * *************************************************************************/
121
122 struct mpegts_packet
123 {
124 TAILQ_ENTRY(mpegts_packet) mp_link;
125 size_t mp_len;
126 mpegts_mux_t *mp_mux;
127 uint8_t mp_cc_restart;
128 uint8_t mp_data[0];
129 };
130
131 struct mpegts_pcr {
132 int64_t pcr_first;
133 int64_t pcr_last;
134 uint16_t pcr_pid;
135 };
136
137 #define MPEGTS_DATA_CC_RESTART (1<<0)
138 #define MPEGTS_DATA_REMOVE_SCRAMBLED (1<<1)
139
140 typedef int (*mpegts_table_callback_t)
141 ( mpegts_table_t*, const uint8_t *buf, int len, int tableid );
142
143 struct mpegts_table_mux_cb
144 {
145 int tag;
146 int (*cb) ( mpegts_table_t*, mpegts_mux_t *mm, uint16_t nbid,
147 const uint8_t dtag, const uint8_t *dptr, int dlen );
148 };
149
150 typedef struct mpegts_pid_sub
151 {
152 RB_ENTRY(mpegts_pid_sub) mps_link;
153 LIST_ENTRY(mpegts_pid_sub) mps_raw_link;
154 LIST_ENTRY(mpegts_pid_sub) mps_svcraw_link;
155 #define MPS_NONE 0x00
156 #define MPS_ALL 0x01
157 #define MPS_RAW 0x02
158 #define MPS_STREAM 0x04
159 #define MPS_SERVICE 0x08
160 #define MPS_TABLE 0x10
161 #define MPS_FTABLE 0x20
162 #define MPS_TABLES 0x40
163 int mps_type;
164 #define MPS_WEIGHT_PAT 1000
165 #define MPS_WEIGHT_CAT 999
166 #define MPS_WEIGHT_SDT 999
167 #define MPS_WEIGHT_NIT 999
168 #define MPS_WEIGHT_BAT 999
169 #define MPS_WEIGHT_VCT 999
170 #define MPS_WEIGHT_EIT 999
171 #define MPS_WEIGHT_ETT 999
172 #define MPS_WEIGHT_MGT 999
173 #define MPS_WEIGHT_PMT 998
174 #define MPS_WEIGHT_PCR 997
175 #define MPS_WEIGHT_CA 996
176 #define MPS_WEIGHT_VIDEO 900
177 #define MPS_WEIGHT_AUDIO 800
178 #define MPS_WEIGHT_SUBTITLE 700
179 #define MPS_WEIGHT_ESOTHER 500
180 #define MPS_WEIGHT_RAW 400
181 #define MPS_WEIGHT_NIT2 300
182 #define MPS_WEIGHT_SDT2 300
183 #define MPS_WEIGHT_TDT 101
184 #define MPS_WEIGHT_STT 101
185 #define MPS_WEIGHT_PMT_SCAN 100
186 int mps_weight;
187 void *mps_owner;
188 } mpegts_pid_sub_t;
189
190 typedef struct mpegts_pid
191 {
192 int mp_pid;
193 int mp_type; // mask for all subscribers
194 int8_t mp_cc;
195 RB_HEAD(,mpegts_pid_sub) mp_subs; // subscribers to pid
196 LIST_HEAD(,mpegts_pid_sub) mp_raw_subs;
197 LIST_HEAD(,mpegts_pid_sub) mp_svc_subs;
198 RB_ENTRY(mpegts_pid) mp_link;
199 } mpegts_pid_t;
200
201 struct mpegts_table
202 {
203 mpegts_psi_table_t;
204
205 /**
206 * Flags, must never be changed after creation.
207 * We inspect it without holding global_lock
208 */
209 int mt_flags;
210
211 #define MT_CRC 0x0001
212 #define MT_FULL 0x0002
213 #define MT_QUICKREQ 0x0004
214 #define MT_FASTSWITCH 0x0008
215 #define MT_ONESHOT 0x0010
216 #define MT_RECORD 0x0020
217 #define MT_SKIPSUBS 0x0040
218 #define MT_SCANSUBS 0x0080
219 #define MT_FAST 0x0100
220 #define MT_SLOW 0x0200
221 #define MT_DEFER 0x0400
222
223 /**
224 * PID subscription weight
225 */
226 int mt_weight;
227
228 /**
229 * Cycle queue
230 * Tables that did not get a fd or filter in hardware will end up here
231 * waiting for any other table to be received so it can reuse that fd.
232 * Only linked if fd == -1
233 */
234 TAILQ_ENTRY(mpegts_table) mt_pending_link;
235
236 /**
237 * File descriptor for filter
238 */
239
240 TAILQ_ENTRY(mpegts_table) mt_defer_link;
241 mpegts_mux_t *mt_mux;
242
243 void *mt_bat;
244 mpegts_table_callback_t mt_callback;
245
246 uint8_t mt_subscribed;
247 uint8_t mt_defer_cmd;
248
249 #define MT_DEFER_OPEN_PID 1
250 #define MT_DEFER_CLOSE_PID 2
251
252 int mt_working;
253
254 int mt_count;
255
256 int mt_id;
257
258 int mt_destroyed; // Refcounting
259 int mt_arefcount;
260
261 struct mpegts_table_mux_cb *mt_mux_cb;
262
263 mpegts_service_t *mt_service;
264
265 void (*mt_destroy) (mpegts_table_t *mt); // Allow customisable destroy hook
266 // useful for dynamic allocation of
267 // the opaque field
268 };
269
270 /**
271 * When in raw mode we need to enqueue raw TS packet
272 * to a different thread because we need to hold
273 * global_lock when doing delivery of the tables
274 */
275
276 struct mpegts_table_feed {
277 TAILQ_ENTRY(mpegts_table_feed) mtf_link;
278 int mtf_len;
279 mpegts_mux_t *mtf_mux;
280 uint8_t mtf_tsb[0];
281 };
282
283 /* **************************************************************************
284 * Logical network
285 * *************************************************************************/
286
287 typedef enum {
288 MN_DISCOVERY_DISABLE = 0,
289 MN_DISCOVERY_NEW = 1,
290 MN_DISCOVERY_CHANGE = 2
291 } mpegts_discovery_t;
292
293 /* Network/Input linkage */
294 struct mpegts_network_link
295 {
296 int mnl_mark;
297 mpegts_input_t *mnl_input;
298 mpegts_network_t *mnl_network;
299 LIST_ENTRY(mpegts_network_link) mnl_mn_link;
300 LIST_ENTRY(mpegts_network_link) mnl_mi_link;
301 };
302
303 /* Network */
304 struct mpegts_network
305 {
306 idnode_t mn_id;
307 LIST_ENTRY(mpegts_network) mn_global_link;
308
309 /*
310 * Identification
311 */
312 char *mn_network_name;
313 char *mn_provider_network_name;
314 int mn_wizard;
315 uint8_t mn_wizard_free;
316
317 /*
318 * Inputs
319 */
320 mpegts_network_link_list_t mn_inputs;
321
322 /*
323 * Multiplexes
324 */
325 mpegts_mux_list_t mn_muxes;
326
327 /*
328 * Scanning
329 */
330 mpegts_mux_queue_t mn_scan_pend; // Pending muxes
331 mpegts_mux_queue_t mn_scan_active; // Active muxes
332 mtimer_t mn_scan_timer; // Timer for activity
333
334 /*
335 * Functions
336 */
337 void (*mn_delete) (mpegts_network_t*, int delconf);
338 void (*mn_display_name) (mpegts_network_t*, char *buf, size_t len);
339 htsmsg_t * (*mn_config_save) (mpegts_network_t*, char *filename, size_t fsize);
340 mpegts_mux_t* (*mn_create_mux)
341 (mpegts_network_t*, void *origin, uint16_t onid, uint16_t tsid,
342 void *conf, int force);
343 mpegts_service_t* (*mn_create_service)
344 (mpegts_mux_t*, uint16_t sid, uint16_t pmt_pid);
345 const idclass_t* (*mn_mux_class) (mpegts_network_t*);
346 mpegts_mux_t * (*mn_mux_create2) (mpegts_network_t *mn, htsmsg_t *conf);
347
348 /*
349 * Configuration
350 */
351 uint16_t mn_nid;
352 uint16_t mn_satip_source;
353 int mn_autodiscovery;
354 int mn_skipinitscan;
355 char *mn_charset;
356 int mn_idlescan;
357 int mn_ignore_chnum;
358 int mn_sid_chnum;
359 int mn_localtime;
360 int mn_satpos;
361 };
362
363 typedef enum mpegts_mux_scan_state
364 {
365 MM_SCAN_STATE_IDLE, // Nothing
366 MM_SCAN_STATE_PEND, // Queue'd pending scan
367 MM_SCAN_STATE_ACTIVE, // Scan is active
368 } mpegts_mux_scan_state_t;
369
370 typedef enum mpegts_mux_scan_result
371 {
372 MM_SCAN_NONE,
373 MM_SCAN_OK,
374 MM_SCAN_FAIL,
375 MM_SCAN_PARTIAL,
376 MM_SCAN_IGNORE,
377 } mpegts_mux_scan_result_t;
378
379 #define MM_SCAN_CHECK_OK(mm) \
380 ((mm)->mm_scan_result == MM_SCAN_OK || (mm)->mm_scan_result == MM_SCAN_PARTIAL)
381
382 enum mpegts_mux_enable
383 {
384 MM_IGNORE = -1,
385 MM_DISABLE = 0,
386 MM_ENABLE = 1,
387 };
388
389 enum mpegts_mux_epg_flag
390 {
391 MM_EPG_DISABLE,
392 MM_EPG_ENABLE,
393 MM_EPG_FORCE,
394 MM_EPG_ONLY_EIT,
395 MM_EPG_ONLY_UK_FREESAT,
396 MM_EPG_ONLY_UK_FREEVIEW,
397 MM_EPG_ONLY_VIASAT_BALTIC,
398 MM_EPG_ONLY_OPENTV_SKY_UK,
399 MM_EPG_ONLY_OPENTV_SKY_ITALIA,
400 MM_EPG_ONLY_OPENTV_SKY_AUSAT,
401 MM_EPG_ONLY_BULSATCOM_39E,
402 MM_EPG_ONLY_PSIP,
403 };
404 #define MM_EPG_LAST MM_EPG_ONLY_PSIP
405
406 enum mpegts_mux_ac3_flag
407 {
408 MM_AC3_STANDARD,
409 MM_AC3_PMT_06,
410 MM_AC3_PMT_N05,
411 };
412
413 typedef struct tsdebug_packet {
414 TAILQ_ENTRY(tsdebug_packet) link;
415 uint8_t pkt[188];
416 off_t pos;
417 } tsdebug_packet_t;
418
419 /* Multiplex */
420 struct mpegts_mux
421 {
422 idnode_t mm_id;
423 int mm_refcount;
424
425 /*
426 * Identification
427 */
428
429 LIST_ENTRY(mpegts_mux) mm_network_link;
430 mpegts_network_t *mm_network;
431 char *mm_provider_network_name;
432 uint16_t mm_onid;
433 uint16_t mm_tsid;
434 int mm_tsid_checks;
435 int mm_tsid_accept_zero_value;
436 tvhlog_limit_t mm_tsid_loglimit;
437 int64_t mm_start_monoclock;
438
439 int mm_update_pids_flag;
440 mtimer_t mm_update_pids_timer;
441
442 /*
443 * Services
444 */
445
446 LIST_HEAD(,mpegts_service) mm_services;
447
448 /*
449 * Scanning
450 */
451
452 mpegts_mux_scan_result_t mm_scan_result; ///< Result of last scan
453 int mm_scan_weight; ///< Scan priority
454 int mm_scan_flags; ///< Subscription flags
455 int mm_scan_init; ///< Flag to timeout handler
456 mtimer_t mm_scan_timeout; ///< Timer to handle timeout
457 TAILQ_ENTRY(mpegts_mux) mm_scan_link; ///< Link to Queue
458 mpegts_mux_scan_state_t mm_scan_state; ///< Scanning state
459
460 #if 0
461 enum {
462 MM_ORIG_USER, ///< Manually added
463 MM_ORIG_FILE, ///< Added from scan file
464 MM_ORIG_AUTO ///< From NIT
465 } mm_dmc_origin2;
466 #endif
467 void *mm_dmc_origin;
468 int64_t mm_dmc_origin_expire;
469
470 char *mm_fastscan_muxes;
471
472 /*
473 * Physical instances
474 */
475
476 LIST_HEAD(, mpegts_mux_instance) mm_instances;
477 mpegts_mux_instance_t *mm_active;
478 LIST_HEAD(,service) mm_transports;
479
480 /*
481 * Raw subscriptions
482 */
483
484 LIST_HEAD(, th_subscription) mm_raw_subs;
485
486 /*
487 * Data processing
488 */
489
490 RB_HEAD(, mpegts_pid) mm_pids;
491 LIST_HEAD(, mpegts_pid_sub) mm_all_subs;
492 int mm_last_pid;
493 mpegts_pid_t *mm_last_mp;
494
495 int mm_num_tables;
496 LIST_HEAD(, mpegts_table) mm_tables;
497 TAILQ_HEAD(, mpegts_table) mm_defer_tables;
498 pthread_mutex_t mm_tables_lock;
499 TAILQ_HEAD(, mpegts_table) mm_table_queue;
500
501 LIST_HEAD(, caid) mm_descrambler_caids;
502 TAILQ_HEAD(, descrambler_table) mm_descrambler_tables;
503 TAILQ_HEAD(, descrambler_emm) mm_descrambler_emms;
504 pthread_mutex_t mm_descrambler_lock;
505 int mm_descrambler_flush;
506
507 /*
508 * Functions
509 */
510
511 void (*mm_delete) (mpegts_mux_t *mm, int delconf);
512 void (*mm_free) (mpegts_mux_t *mm);
513 htsmsg_t *(*mm_config_save) (mpegts_mux_t *mm, char *filename, size_t fsize);
514 void (*mm_display_name) (mpegts_mux_t*, char *buf, size_t len);
515 int (*mm_is_enabled) (mpegts_mux_t *mm);
516 void (*mm_stop) (mpegts_mux_t *mm, int force, int reason);
517 void (*mm_open_table) (mpegts_mux_t*,mpegts_table_t*,int subscribe);
518 void (*mm_unsubscribe_table)(mpegts_mux_t*,mpegts_table_t*);
519 void (*mm_close_table) (mpegts_mux_t*,mpegts_table_t*);
520 void (*mm_create_instances) (mpegts_mux_t*);
521 int (*mm_is_epg) (mpegts_mux_t*);
522
523 /*
524 * Configuration
525 */
526 char *mm_crid_authority;
527 int mm_enabled;
528 int mm_epg;
529 char *mm_charset;
530 int mm_pmt_ac3;
531 int mm_eit_tsid_nocheck;
532 uint16_t mm_sid_filter;
533
534 /*
535 * TSDEBUG
536 */
537 #if ENABLE_TSDEBUG
538 int mm_tsdebug_fd;
539 int mm_tsdebug_fd2;
540 off_t mm_tsdebug_pos;
541 TAILQ_HEAD(, tsdebug_packet) mm_tsdebug_packets;
542 #endif
543 };
544
545 #define PREFCAPID_OFF 0
546 #define PREFCAPID_ON 1
547 #define PREFCAPID_FORCE 2
548
549 /* Service */
550 struct mpegts_service
551 {
552 service_t; // Parent
553
554 int (*s_update_pids)(mpegts_service_t *t, struct mpegts_apids *pids);
555 int (*s_link)(mpegts_service_t *master, mpegts_service_t *slave);
556 int (*s_unlink)(mpegts_service_t *master, mpegts_service_t *slave);
557
558 int s_dvb_subscription_flags;
559 int s_dvb_subscription_weight;
560
561 mpegts_apids_t *s_pids;
562 idnode_set_t s_masters;
563 LIST_HEAD(, mpegts_service) s_slaves;
564 LIST_ENTRY(mpegts_service) s_slaves_link;
565 mpegts_apids_t *s_slaves_pids;
566
567 /*
568 * Fields defined by DVB standard EN 300 468
569 */
570
571 uint32_t s_dvb_channel_num;
572 uint16_t s_dvb_channel_minor;
573 uint8_t s_dvb_channel_dtag;
574 uint16_t s_dvb_service_id;
575 char *s_dvb_svcname;
576 char *s_dvb_provider;
577 char *s_dvb_cridauth;
578 uint16_t s_dvb_servicetype;
579 int s_dvb_ignore_eit;
580 char *s_dvb_charset;
581 uint16_t s_dvb_prefcapid;
582 int s_dvb_prefcapid_lock;
583 time_t s_dvb_created;
584 time_t s_dvb_last_seen;
585 time_t s_dvb_check_seen;
586
587 /*
588 * EIT/EPG control
589 */
590
591 int s_dvb_eit_enable;
592 uint64_t s_dvb_opentv_chnum;
593 uint16_t s_dvb_opentv_id;
594 uint16_t s_atsc_source_id;
595
596 /*
597 * Link to carrying multiplex and active adapter
598 */
599
600 LIST_ENTRY(mpegts_service) s_dvb_mux_link;
601 mpegts_mux_t *s_dvb_mux;
602 mpegts_input_t *s_dvb_active_input;
603
604 /*
605 * Streaming elements
606 *
607 * see service.h for locking rules
608 */
609
610 /**
611 * When a subscription request SMT_MPEGTS, chunk them togeather
612 * in order to recude load.
613 */
614 sbuf_t s_tsbuf;
615 int64_t s_tsbuf_last;
616
617 /**
618 * PCR drift compensation. This should really be per-packet.
619 */
620 int64_t s_pcr_drift;
621
622 /**
623 * PMT/CAT monitoring
624 */
625
626 mpegts_table_t *s_pmt_mon; ///< Table entry for monitoring PMT
627 mpegts_table_t *s_cat_mon; ///< Table entry for monitoring CAT
628
629 };
630
631 /* **************************************************************************
632 * Physical Network
633 * *************************************************************************/
634
635 /* Physical mux instance */
636 struct mpegts_mux_instance
637 {
638 tvh_input_instance_t;
639
640 LIST_ENTRY(mpegts_mux_instance) mmi_mux_link;
641 LIST_ENTRY(mpegts_mux_instance) mmi_active_link;
642
643 streaming_pad_t mmi_streaming_pad;
644
645 mpegts_mux_t *mmi_mux;
646 mpegts_input_t *mmi_input;
647
648 int mmi_start_weight;
649 int mmi_tune_failed;
650 };
651
652 struct mpegts_mux_sub
653 {
654 RB_ENTRY(mpegts_mux_sub) mms_link;
655 void *mms_src;
656 int mms_weight;
657 };
658
659 enum mpegts_input_is_enabled {
660 MI_IS_ENABLED_RETRY = -1,
661 MI_IS_ENABLED_NEVER = 0,
662 MI_IS_ENABLED_OK = 1,
663 };
664
665 /* Input source */
666 struct mpegts_input
667 {
668 tvh_input_t;
669
670 int mi_enabled;
671
672 int mi_instance;
673
674 char *mi_name;
675
676 int mi_priority;
677 int mi_streaming_priority;
678
679 int mi_ota_epg;
680
681 int mi_initscan;
682 int mi_idlescan;
683 uint32_t mi_free_weight;
684
685 char *mi_linked;
686
687 LIST_ENTRY(mpegts_input) mi_global_link;
688
689 mpegts_network_link_list_t mi_networks;
690
691 LIST_HEAD(,tvh_input_instance) mi_mux_instances;
692
693
694 /*
695 * Status
696 */
697 mtimer_t mi_status_timer;
698
699 /*
700 * Input processing
701 */
702
703 int mi_running; /* threads running */
704 int64_t mi_last_dispatch;
705
706 /* Data input */
707 // Note: this section is protected by mi_input_lock
708 pthread_t mi_input_tid;
709 mtimer_t mi_input_thread_start;
710 pthread_mutex_t mi_input_lock;
711 tvh_cond_t mi_input_cond;
712 TAILQ_HEAD(,mpegts_packet) mi_input_queue;
713 uint64_t mi_input_queue_size;
714 tvhlog_limit_t mi_input_queue_loglimit;
715 int mi_remove_scrambled_bits;
716
717 /* Data processing/output */
718 // Note: this lock (mi_output_lock) protects all the remaining
719 // data fields (excluding the callback functions)
720 pthread_mutex_t mi_output_lock;
721
722 /* Active sources */
723 LIST_HEAD(,mpegts_mux_instance) mi_mux_active;
724
725 /* Table processing */
726 pthread_t mi_table_tid;
727 tvh_cond_t mi_table_cond;
728 mpegts_table_feed_queue_t mi_table_queue;
729 uint64_t mi_table_queue_size;
730 tvhlog_limit_t mi_table_queue_loglimit;
731
732 /* DBus */
733 #if ENABLE_DBUS_1
734 int64_t mi_dbus_subs;
735 #endif
736
737 /*
738 * Functions
739 */
740 int (*mi_is_enabled) (mpegts_input_t*, mpegts_mux_t *mm, int flags, int weight);
741 void (*mi_enabled_updated)(mpegts_input_t*);
742 void (*mi_display_name) (mpegts_input_t*, char *buf, size_t len);
743 int (*mi_get_weight) (mpegts_input_t*, mpegts_mux_t *mm, int flags, int weight);
744 int (*mi_get_priority) (mpegts_input_t*, mpegts_mux_t *mm, int flags);
745 int (*mi_get_grace) (mpegts_input_t*, mpegts_mux_t *mm);
746 int (*mi_warm_mux) (mpegts_input_t*,mpegts_mux_instance_t*);
747 int (*mi_start_mux) (mpegts_input_t*,mpegts_mux_instance_t*, int weight);
748 void (*mi_stop_mux) (mpegts_input_t*,mpegts_mux_instance_t*);
749 void (*mi_open_service) (mpegts_input_t*,mpegts_service_t*, int flags, int first, int weight);
750 void (*mi_close_service) (mpegts_input_t*,mpegts_service_t*);
751 void (*mi_update_pids) (mpegts_input_t*,mpegts_mux_t*);
752 void (*mi_create_mux_instance) (mpegts_input_t*,mpegts_mux_t*);
753 void (*mi_started_mux) (mpegts_input_t*,mpegts_mux_instance_t*);
754 void (*mi_stopping_mux) (mpegts_input_t*,mpegts_mux_instance_t*);
755 void (*mi_stopped_mux) (mpegts_input_t*,mpegts_mux_instance_t*);
756 int (*mi_has_subscription) (mpegts_input_t*, mpegts_mux_t *mm);
757 void (*mi_tuning_error) (mpegts_input_t*, mpegts_mux_t *);
758 void (*mi_empty_status) (mpegts_input_t*, tvh_input_stream_t *);
759 idnode_set_t *(*mi_network_list) (mpegts_input_t*);
760 };
761
762 /* ****************************************************************************
763 * Lists
764 * ***************************************************************************/
765
766 extern mpegts_network_list_t mpegts_network_all;
767
768 typedef struct mpegts_network_builder {
769 LIST_ENTRY(mpegts_network_builder) link;
770 const idclass_t *idc;
771 mpegts_network_t * (*build) ( const idclass_t *idc, htsmsg_t *conf );
772 } mpegts_network_builder_t;
773
774
775 typedef LIST_HEAD(,mpegts_network_builder) mpegts_network_builder_list_t;
776
777 extern mpegts_network_builder_list_t mpegts_network_builders;
778
779 extern mpegts_input_list_t mpegts_input_all;
780
781 /* ****************************************************************************
782 * Functions
783 * ***************************************************************************/
784
785 mpegts_input_t *mpegts_input_create0
786 ( mpegts_input_t *mi, const idclass_t *idc, const char *uuid, htsmsg_t *c );
787
788 #define mpegts_input_create(t, u, c)\
789 (struct t*)mpegts_input_create0(calloc(1, sizeof(struct t)), &t##_class, u, c)
790
791 #define mpegts_input_create1(u, c)\
792 mpegts_input_create0(calloc(1, sizeof(mpegts_input_t)),\
793 &mpegts_input_class, u, c)
794
795 void mpegts_input_stop_all ( mpegts_input_t *mi );
796
797 void mpegts_input_delete ( mpegts_input_t *mi, int delconf );
798
mpegts_input_find(const char * uuid)799 static inline mpegts_input_t *mpegts_input_find(const char *uuid)
800 { return idnode_find(uuid, &mpegts_input_class, NULL); }
801
802 int mpegts_input_set_networks ( mpegts_input_t *mi, htsmsg_t *msg );
803
804 int mpegts_input_add_network ( mpegts_input_t *mi, mpegts_network_t *mn );
805
806 void mpegts_input_open_service ( mpegts_input_t *mi, mpegts_service_t *s, int flags, int init, int weight );
807 void mpegts_input_close_service ( mpegts_input_t *mi, mpegts_service_t *s );
808
809 void mpegts_input_status_timer ( void *p );
810
811 int mpegts_input_grace ( mpegts_input_t * mi, mpegts_mux_t * mm );
812
813 int mpegts_input_is_enabled ( mpegts_input_t * mi, mpegts_mux_t *mm, int flags, int weight );
814
815 void mpegts_input_set_enabled ( mpegts_input_t *mi, int enabled );
816
817 void mpegts_input_empty_status ( mpegts_input_t *mi, tvh_input_stream_t *st );
818
819
820 /* TODO: exposing these class methods here is a bit of a hack */
821 const void *mpegts_input_class_network_get ( void *o );
822 int mpegts_input_class_network_set ( void *o, const void *p );
823 htsmsg_t *mpegts_input_class_network_enum ( void *o, const char *lang );
824 char *mpegts_input_class_network_rend ( void *o, const char *lang );
825 const void *mpegts_input_class_active_get ( void *o );
826
827 int mpegts_mps_weight(elementary_stream_t *st);
828
829 int mpegts_mps_cmp( mpegts_pid_sub_t *a, mpegts_pid_sub_t *b );
830
831 void mpegts_network_register_builder
832 ( const idclass_t *idc,
833 mpegts_network_t *(*build)(const idclass_t *idc, htsmsg_t *conf) );
834
835 void mpegts_network_unregister_builder
836 ( const idclass_t *idc );
837
838 mpegts_network_builder_t *mpegts_network_builder_find ( const char *clazz );
839
840 mpegts_network_t *mpegts_network_build
841 ( const char *clazz, htsmsg_t *conf );
842
843 mpegts_network_t *mpegts_network_create0
844 ( mpegts_network_t *mn, const idclass_t *idc, const char *uuid,
845 const char *name, htsmsg_t *conf );
846
847 #define mpegts_network_create(t, u, n, c)\
848 (struct t*)mpegts_network_create0(calloc(1, sizeof(struct t)), &t##_class, u, n, c)
849
850 extern const idclass_t mpegts_network_class;
851
mpegts_network_find(const char * uuid)852 static inline mpegts_network_t *mpegts_network_find(const char *uuid)
853 { return idnode_find(uuid, &mpegts_network_class, NULL); }
854
855 mpegts_mux_t *mpegts_network_find_mux
856 (mpegts_network_t *mn, uint16_t onid, uint16_t tsid, int check);
857
858 mpegts_service_t *mpegts_network_find_active_service
859 (mpegts_network_t *mn, uint16_t sid, mpegts_mux_t **rmm);
860
861 void mpegts_network_class_delete ( const idclass_t *idc, int delconf );
862
863 void mpegts_network_delete ( mpegts_network_t *mn, int delconf );
864
865 int mpegts_network_set_nid ( mpegts_network_t *mn, uint16_t nid );
866 int mpegts_network_set_network_name ( mpegts_network_t *mn, const char *name );
867 void mpegts_network_scan ( mpegts_network_t *mn );
868 void mpegts_network_get_type_str( mpegts_network_t *mn, char *buf, size_t buflen );
869
870 htsmsg_t * mpegts_network_wizard_get ( mpegts_input_t *mi, const idclass_t *idc,
871 mpegts_network_t *mn, const char *lang );
872 void mpegts_network_wizard_create ( const char *clazz, htsmsg_t **nlist, const char *lang );
873
874 mpegts_mux_t *mpegts_mux_create0
875 ( mpegts_mux_t *mm, const idclass_t *class, const char *uuid,
876 mpegts_network_t *mn, uint16_t onid, uint16_t tsid,
877 htsmsg_t *conf );
878
879 #define mpegts_mux_create(type, uuid, mn, onid, tsid, conf)\
880 (struct type*)mpegts_mux_create0(calloc(1, sizeof(struct type)),\
881 &type##_class, uuid,\
882 mn, onid, tsid, conf)
883 #define mpegts_mux_create1(uuid, mn, onid, tsid, conf)\
884 mpegts_mux_create0(calloc(1, sizeof(mpegts_mux_t)), &mpegts_mux_class, uuid,\
885 mn, onid, tsid, conf)
886
mpegts_mux_find(const char * uuid)887 static inline mpegts_mux_t *mpegts_mux_find(const char *uuid)
888 { return idnode_find(uuid, &mpegts_mux_class, NULL); }
889
890 #define mpegts_mux_delete_by_uuid(u, delconf)\
891 { mpegts_mux_t *mm = mpegts_mux_find(u); if (mm) mm->mm_delete(mm, delconf); }
892
893 void mpegts_mux_delete ( mpegts_mux_t *mm, int delconf );
894
895 void mpegts_mux_free ( mpegts_mux_t *mm );
896
mpegts_mux_grab(mpegts_mux_t * mm)897 static inline void mpegts_mux_grab ( mpegts_mux_t *mm )
898 {
899 int v = atomic_add(&mm->mm_refcount, 1);
900 assert(v > 0);
901 }
902
mpegts_mux_release(mpegts_mux_t * mm)903 static inline int mpegts_mux_release ( mpegts_mux_t *mm )
904 {
905 int v = atomic_dec(&mm->mm_refcount, 1);
906 assert(v > 0);
907 if (v == 1) {
908 mm->mm_free(mm);
909 return 1;
910 }
911 return 0;
912 }
913
914 void mpegts_mux_save ( mpegts_mux_t *mm, htsmsg_t *c );
915
916 void mpegts_mux_tuning_error( const char *mux_uuid, mpegts_mux_instance_t *mmi_match );
917
918 mpegts_mux_instance_t *mpegts_mux_instance_create0
919 ( mpegts_mux_instance_t *mmi, const idclass_t *class, const char *uuid,
920 mpegts_input_t *mi, mpegts_mux_t *mm );
921
922 mpegts_service_t *mpegts_mux_find_service(mpegts_mux_t *ms, uint16_t sid);
923
924 #define mpegts_mux_instance_create(type, uuid, mi, mm)\
925 (struct type*)mpegts_mux_instance_create0(calloc(1, sizeof(struct type)),\
926 &type##_class, uuid,\
927 mi, mm);
928
929 void mpegts_mux_instance_delete ( tvh_input_instance_t *tii );
930
931 int mpegts_mux_instance_start
932 ( mpegts_mux_instance_t **mmiptr, service_t *t, int weight );
933
934 int mpegts_mux_instance_weight ( mpegts_mux_instance_t *mmi );
935
936 int mpegts_mux_set_network_name ( mpegts_mux_t *mm, const char *name );
937 int mpegts_mux_set_tsid ( mpegts_mux_t *mm, uint16_t tsid, int force );
938 int mpegts_mux_set_onid ( mpegts_mux_t *mm, uint16_t onid );
939 int mpegts_mux_set_crid_authority ( mpegts_mux_t *mm, const char *defauth );
940
941 void mpegts_mux_open_table ( mpegts_mux_t *mm, mpegts_table_t *mt, int subscribe );
942 void mpegts_mux_unsubscribe_table ( mpegts_mux_t *mm, mpegts_table_t *mt );
943 void mpegts_mux_close_table ( mpegts_mux_t *mm, mpegts_table_t *mt );
944
945 void mpegts_mux_remove_subscriber(mpegts_mux_t *mm, th_subscription_t *s, int reason);
946 int mpegts_mux_subscribe(mpegts_mux_t *mm, mpegts_input_t *mi,
947 const char *name, int weight, int flags);
948 void mpegts_mux_unsubscribe_by_name(mpegts_mux_t *mm, const char *name);
949 th_subscription_t *mpegts_mux_find_subscription_by_name(mpegts_mux_t *mm, const char *name);
950
951 void mpegts_mux_unsubscribe_linked(mpegts_input_t *mi, service_t *t);
952
953 void mpegts_mux_scan_done ( mpegts_mux_t *mm, const char *buf, int res );
954
955 void mpegts_mux_bouquet_rescan ( const char *src, const char *extra );
956
957 void mpegts_mux_nice_name( mpegts_mux_t *mm, char *buf, size_t len );
958
959 int mpegts_mux_class_scan_state_set ( void *, const void * );
960
mpegts_mux_scan_state_set(mpegts_mux_t * m,int state)961 static inline int mpegts_mux_scan_state_set ( mpegts_mux_t *m, int state )
962 { return mpegts_mux_class_scan_state_set ( m, &state ); }
963
964 mpegts_pid_t *mpegts_mux_find_pid_(mpegts_mux_t *mm, int pid, int create);
965
966 static inline mpegts_pid_t *
mpegts_mux_find_pid(mpegts_mux_t * mm,int pid,int create)967 mpegts_mux_find_pid(mpegts_mux_t *mm, int pid, int create)
968 {
969 if (mm->mm_last_pid != pid)
970 return mpegts_mux_find_pid_(mm, pid, create);
971 else
972 return mm->mm_last_mp;
973 }
974
975 void mpegts_mux_update_pids ( mpegts_mux_t *mm );
976
977 int mpegts_mux_compare ( mpegts_mux_t *a, mpegts_mux_t *b );
978
979 void mpegts_input_recv_packets
980 (mpegts_input_t *mi, mpegts_mux_instance_t *mmi, sbuf_t *sb,
981 int flags, mpegts_pcr_t *pcr);
982
983 int mpegts_input_get_weight ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags, int weight );
984 int mpegts_input_get_priority ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags );
985 int mpegts_input_get_grace ( mpegts_input_t *mi, mpegts_mux_t *mm );
986 int mpegts_input_warm_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi );
987
988 void mpegts_input_save ( mpegts_input_t *mi, htsmsg_t *c );
989
990 void mpegts_input_flush_mux ( mpegts_input_t *mi, mpegts_mux_t *mm );
991
992 mpegts_pid_t * mpegts_input_open_pid
993 ( mpegts_input_t *mi, mpegts_mux_t *mm, int pid, int type, int weight, void *owner, int reopen );
994
995 int mpegts_input_close_pid
996 ( mpegts_input_t *mi, mpegts_mux_t *mm, int pid, int type, int weight, void *owner );
997
998 void mpegts_input_close_pids
999 ( mpegts_input_t *mi, mpegts_mux_t *mm, void *owner, int all );
1000
1001 static inline void
tsdebug_write(mpegts_mux_t * mm,uint8_t * buf,size_t len)1002 tsdebug_write(mpegts_mux_t *mm, uint8_t *buf, size_t len)
1003 {
1004 #if ENABLE_TSDEBUG
1005 if (mm && mm->mm_tsdebug_fd2 >= 0)
1006 if (write(mm->mm_tsdebug_fd2, buf, len) != len)
1007 tvherror(LS_TSDEBUG, "unable to write input data (%i)", errno);
1008 #endif
1009 }
1010
1011 static inline ssize_t
sbuf_tsdebug_read(mpegts_mux_t * mm,sbuf_t * sb,int fd)1012 sbuf_tsdebug_read(mpegts_mux_t *mm, sbuf_t *sb, int fd)
1013 {
1014 #if ENABLE_TSDEBUG
1015 ssize_t r = sbuf_read(sb, fd);
1016 tsdebug_write(mm, sb->sb_data + sb->sb_ptr - r, r);
1017 return r;
1018 #else
1019 return sbuf_read(sb, fd);
1020 #endif
1021 }
1022
1023 void mpegts_table_dispatch
1024 (const uint8_t *sec, size_t r, void *mt);
mpegts_table_grab(mpegts_table_t * mt)1025 static inline void mpegts_table_grab
1026 (mpegts_table_t *mt)
1027 {
1028 int v = atomic_add(&mt->mt_arefcount, 1);
1029 assert(v > 0);
1030 }
1031 void mpegts_table_release_
1032 (mpegts_table_t *mt);
mpegts_table_release(mpegts_table_t * mt)1033 static inline int mpegts_table_release
1034 (mpegts_table_t *mt)
1035 {
1036 int v = atomic_dec(&mt->mt_arefcount, 1);
1037 assert(v > 0);
1038 if (v == 1) {
1039 assert(mt->mt_destroyed == 1);
1040 mpegts_table_release_(mt);
1041 return 1;
1042 }
1043 return 0;
1044 }
1045 int mpegts_table_type
1046 ( mpegts_table_t *mt );
1047 mpegts_table_t *mpegts_table_add
1048 (mpegts_mux_t *mm, int tableid, int mask,
1049 mpegts_table_callback_t callback, void *opaque,
1050 const char *name, int subsys, int flags, int pid, int weight);
1051 void mpegts_table_flush_all
1052 (mpegts_mux_t *mm);
1053 void mpegts_table_destroy ( mpegts_table_t *mt );
1054
1055 void mpegts_table_consistency_check( mpegts_mux_t *mm );
1056
1057 void dvb_bat_destroy
1058 (struct mpegts_table *mt);
1059
1060 int dvb_pat_callback
1061 (struct mpegts_table *mt, const uint8_t *ptr, int len, int tableid);
1062 int dvb_cat_callback
1063 (struct mpegts_table *mt, const uint8_t *ptr, int len, int tableid);
1064 int dvb_pmt_callback
1065 (struct mpegts_table *mt, const uint8_t *ptr, int len, int tabelid);
1066 int dvb_nit_callback
1067 (struct mpegts_table *mt, const uint8_t *ptr, int len, int tableid);
1068 int dvb_bat_callback
1069 (struct mpegts_table *mt, const uint8_t *ptr, int len, int tableid);
1070 int dvb_fs_sdt_callback
1071 (struct mpegts_table *mt, const uint8_t *ptr, int len, int tableid);
1072 int dvb_sdt_callback
1073 (struct mpegts_table *mt, const uint8_t *ptr, int len, int tableid);
1074 int dvb_tdt_callback
1075 (struct mpegts_table *mt, const uint8_t *ptr, int len, int tableid);
1076 int dvb_tot_callback
1077 (struct mpegts_table *mt, const uint8_t *ptr, int len, int tableid);
1078 int atsc_vct_callback
1079 (struct mpegts_table *mt, const uint8_t *ptr, int len, int tableid);
1080 int atsc_stt_callback
1081 (struct mpegts_table *mt, const uint8_t *ptr, int len, int tableid);
1082
1083 void psi_tables_install
1084 (mpegts_input_t *mi, mpegts_mux_t *mm, dvb_fe_delivery_system_t delsys);
1085
1086 mpegts_service_t *mpegts_service_create0
1087 ( mpegts_service_t *ms, const idclass_t *class, const char *uuid,
1088 mpegts_mux_t *mm, uint16_t sid, uint16_t pmt_pid, htsmsg_t *conf );
1089
1090 #define mpegts_service_create(t, u, m, s, p, c)\
1091 (struct t*)mpegts_service_create0(calloc(1, sizeof(struct t)),\
1092 &t##_class, u, m, s, p, c)
1093
1094 #define mpegts_service_create1(u, m, s, p, c)\
1095 mpegts_service_create0(calloc(1, sizeof(mpegts_service_t)),\
1096 &mpegts_service_class, u, m, s, p, c)
1097
1098 mpegts_service_t *mpegts_service_create_raw(mpegts_mux_t *mm);
1099
1100 mpegts_service_t *mpegts_service_find
1101 ( mpegts_mux_t *mm, uint16_t sid, uint16_t pmt_pid, int create, int *save );
1102
1103 service_t *
1104 mpegts_service_find_e2
1105 ( uint32_t stype, uint32_t sid, uint32_t tsid, uint32_t onid, uint32_t hash);
1106
1107 mpegts_service_t *
1108 mpegts_service_find_by_pid ( mpegts_mux_t *mm, int pid );
1109
1110 void mpegts_service_update_slave_pids ( mpegts_service_t *t, int del );
1111
mpegts_service_find_by_uuid(const char * uuid)1112 static inline mpegts_service_t *mpegts_service_find_by_uuid(const char *uuid)
1113 { return idnode_find(uuid, &mpegts_service_class, NULL); }
1114
1115 void mpegts_service_unref ( service_t *s );
1116
1117 void mpegts_service_delete ( service_t *s, int delconf );
1118
1119 int64_t mpegts_service_channel_number ( service_t *s );
1120
1121 /*
1122 * MPEG-TS event handler
1123 */
1124
1125 typedef struct mpegts_listener
1126 {
1127 LIST_ENTRY(mpegts_listener) ml_link;
1128 void *ml_opaque;
1129 void (*ml_mux_start) (mpegts_mux_t *mm, void *p);
1130 void (*ml_mux_stop) (mpegts_mux_t *mm, void *p, int reason);
1131 void (*ml_mux_create) (mpegts_mux_t *mm, void *p);
1132 void (*ml_mux_delete) (mpegts_mux_t *mm, void *p);
1133 } mpegts_listener_t;
1134
1135 extern LIST_HEAD(mpegts_listeners, mpegts_listener) mpegts_listeners;
1136
1137 #define mpegts_add_listener(ml)\
1138 LIST_INSERT_HEAD(&mpegts_listeners, ml, ml_link)
1139
1140 #define mpegts_rem_listener(ml)\
1141 LIST_REMOVE(ml, ml_link)
1142
1143 #define mpegts_fire_event(t, op)\
1144 {\
1145 mpegts_listener_t *ml;\
1146 LIST_FOREACH(ml, &mpegts_listeners, ml_link)\
1147 if (ml->op) ml->op(t, ml->ml_opaque);\
1148 } (void)0
1149
1150 #define mpegts_fire_event1(t, op, arg1)\
1151 {\
1152 mpegts_listener_t *ml;\
1153 LIST_FOREACH(ml, &mpegts_listeners, ml_link)\
1154 if (ml->op) ml->op(t, ml->ml_opaque, arg1);\
1155 } (void)0
1156
1157 #endif /* __TVH_MPEGTS_H__ */
1158
1159 /******************************************************************************
1160 * Editor Configuration
1161 *
1162 * vim:sts=2:ts=2:sw=2:et
1163 *****************************************************************************/
1164
1165