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