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 #include "tvheadend.h"
21 #include "input.h"
22 #include "channels.h"
23 #include "tsfile_private.h"
24 #include "service_mapper.h"
25
26 /*
27 * Globals
28 */
29 pthread_mutex_t tsfile_lock;
30 mpegts_network_t *tsfile_network;
31 tsfile_input_list_t tsfile_inputs;
32
33 extern const idclass_t mpegts_service_class;
34 extern const idclass_t mpegts_network_class;
35
36 static htsmsg_t *
tsfile_service_config_save(service_t * s,char * filename,size_t fsize)37 tsfile_service_config_save ( service_t *s, char *filename, size_t fsize )
38 {
39 return NULL;
40 }
41
42 static void
tsfile_service_delete(service_t * s,int delconf)43 tsfile_service_delete ( service_t *s, int delconf )
44 {
45 mpegts_service_delete(s, 0);
46 }
47
48 /*
49 * Network definition
50 */
51 static mpegts_service_t *
tsfile_network_create_service(mpegts_mux_t * mm,uint16_t sid,uint16_t pmt_pid)52 tsfile_network_create_service
53 ( mpegts_mux_t *mm, uint16_t sid, uint16_t pmt_pid )
54 {
55 pthread_mutex_lock(&tsfile_lock);
56 mpegts_service_t *s = mpegts_service_create1(NULL, mm, sid, pmt_pid, NULL);
57
58 // TODO: HACK: REMOVE ME
59 if (s) {
60 s->s_config_save = tsfile_service_config_save;
61 s->s_delete = tsfile_service_delete;
62 pthread_mutex_unlock(&tsfile_lock);
63 channel_t *c = channel_create(NULL, NULL, NULL);
64 if (c) {
65 c->ch_dont_save = 1;
66 service_mapper_link((service_t*)s, c, NULL);
67 }
68 }
69 else
70 pthread_mutex_unlock(&tsfile_lock);
71
72 return s;
73 }
74
75 /*
76 * Initialise
77 */
tsfile_init(int tuners)78 void tsfile_init ( int tuners )
79 {
80 int i;
81 tsfile_input_t *mi;
82
83 /* Mutex - used for minor efficiency in service processing */
84 pthread_mutex_init(&tsfile_lock, NULL);
85
86 /* Shared network */
87 tsfile_network = calloc(1, sizeof(*tsfile_network));
88 mpegts_network_create0(tsfile_network, &mpegts_network_class, NULL,
89 "TSfile Network", NULL);
90 tsfile_network->mn_create_service = tsfile_network_create_service;
91
92 /* IPTV like setup */
93 if (tuners <= 0) {
94 mi = tsfile_input_create(0);
95 mpegts_input_add_network((mpegts_input_t*)mi, tsfile_network);
96 } else {
97 for (i = 0; i < tuners; i++) {
98 mi = tsfile_input_create(i+1);
99 mpegts_input_add_network((mpegts_input_t*)mi, tsfile_network);
100 }
101 }
102 }
103
104 /*
105 * Shutdown
106 */
107 void
tsfile_done(void)108 tsfile_done ( void )
109 {
110 tsfile_input_t *mi;
111 pthread_mutex_lock(&global_lock);
112 while ((mi = LIST_FIRST(&tsfile_inputs))) {
113 LIST_REMOVE(mi, tsi_link);
114 mpegts_input_stop_all((mpegts_input_t*)mi);
115 mpegts_input_delete((mpegts_input_t*)mi, 0);
116 // doesn't close the pipe!
117 }
118 mpegts_network_class_delete(&mpegts_network_class, 1);
119 pthread_mutex_unlock(&global_lock);
120 }
121
122 /*
123 * Add multiplex
124 */
tsfile_add_file(const char * path)125 void tsfile_add_file ( const char *path )
126 {
127 tsfile_input_t *mi;
128 mpegts_mux_t *mm;
129 char *uuid = NULL, *tok;
130
131 char tmp[strlen(path) + 1];
132 strcpy(tmp, path);
133
134 /* Pull UUID from info */
135 if ((tok = strstr(tmp, "::"))) {
136 *tok = '\0';
137 path = tok + 2;
138 uuid = tmp;
139 }
140
141 tvhtrace(LS_TSFILE, "add file %s (uuid:%s)", path, uuid);
142
143 /* Create logical instance */
144 mm = tsfile_mux_create(uuid, tsfile_network);
145 mm->mm_tsid_accept_zero_value = 1;
146
147 /* Create physical instance (for each tuner) */
148 LIST_FOREACH(mi, &tsfile_inputs, tsi_link)
149 tsfile_mux_instance_create(path, (mpegts_input_t*)mi, mm);
150 }
151
152 /******************************************************************************
153 * Editor Configuration
154 *
155 * vim:sts=2:ts=2:sw=2:et
156 *****************************************************************************/
157