1 /*
2  *  tvheadend, simple muxer that just passes the input along
3  *  Copyright (C) 2012 John Törnblom
4  *
5  *  This program is free software: you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation, either version 3 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program.  If not, see <htmlui://www.gnu.org/licenses/>.
17  */
18 
19 #include <string.h>
20 #include <unistd.h>
21 #include <fcntl.h>
22 #include <assert.h>
23 #include <sys/stat.h>
24 
25 #include "tvheadend.h"
26 #include "streaming.h"
27 #include "epg.h"
28 #include "service.h"
29 #include "input/mpegts/dvb.h"
30 #include "muxer_pass.h"
31 #include "dvr/dvr.h"
32 
33 typedef struct pass_muxer {
34   muxer_t;
35 
36   /* File descriptor stuff */
37   off_t pm_off;
38   int   pm_fd;
39   int   pm_seekable;
40   int   pm_error;
41 
42   /* Filename is also used for logging */
43   char *pm_filename;
44 
45   /* Streaming components */
46   streaming_start_t *pm_ss;
47 
48   /* TS muxing */
49   uint8_t  pm_rewrite_sdt;
50   uint8_t  pm_rewrite_eit;
51 
52   uint16_t pm_pmt_pid;
53   uint16_t pm_service_id;
54 
55   mpegts_psi_table_t pm_pat;
56   mpegts_psi_table_t pm_pmt;
57   mpegts_psi_table_t pm_sdt;
58   mpegts_psi_table_t pm_eit;
59 
60 } pass_muxer_t;
61 
62 
63 static void
64 pass_muxer_write(muxer_t *m, const void *data, size_t size);
65 
66 /*
67  * Rewrite a PAT packet to only include the service included in the transport stream.
68  */
69 
70 static void
pass_muxer_pat_cb(mpegts_psi_table_t * mt,const uint8_t * buf,int len)71 pass_muxer_pat_cb(mpegts_psi_table_t *mt, const uint8_t *buf, int len)
72 {
73   pass_muxer_t *pm;
74   uint8_t out[16], *ob;
75   int ol, l;
76 
77   if (buf[0])
78     return;
79 
80   pm = (pass_muxer_t*)mt->mt_opaque;
81 
82   memcpy(out, buf, 5 + 3);
83 
84   out[1] = 0x80;
85   out[2] = 13; /* section_length (number of bytes after this field, including CRC) */
86   out[7] = 0;
87 
88   out[8] = (pm->pm_service_id & 0xff00) >> 8;
89   out[9] = pm->pm_service_id & 0x00ff;
90   out[10] = 0xe0 | ((pm->pm_pmt_pid & 0x1f00) >> 8);
91   out[11] = pm->pm_pmt_pid & 0x00ff;
92 
93   ol = dvb_table_append_crc32(out, 12, sizeof(out));
94 
95   if (ol > 0 && (l = dvb_table_remux(mt, out, ol, &ob)) > 0) {
96     pass_muxer_write((muxer_t *)pm, ob, l);
97     free(ob);
98   }
99 }
100 
101 /*
102  *
103  */
104 static void
pass_muxer_pmt_cb(mpegts_psi_table_t * mt,const uint8_t * buf,int len)105 pass_muxer_pmt_cb(mpegts_psi_table_t *mt, const uint8_t *buf, int len)
106 {
107   pass_muxer_t *pm;
108   uint8_t out[1024], *ob;
109   uint16_t sid, pid;
110   int l, ol, i;
111   const streaming_start_component_t *ssc;
112 
113   memcpy(out, buf, ol = 3);
114   buf += ol;
115   len -= ol;
116 
117   sid = (buf[0] << 8) | buf[1];
118   l = (buf[7] & 0x0f) << 8 | buf[8];
119 
120   if (l > len - 9)
121     return;
122 
123   pm = (pass_muxer_t*)mt->mt_opaque;
124   if (sid != pm->pm_service_id)
125     return;
126 
127   memcpy(out + ol, buf, 9);
128 
129   ol  += 9;     /* skip common descriptors */
130   buf += 9 + l;
131   len -= 9 + l;
132 
133   /* no common descriptors */
134   out[7+3] &= 0xf0;
135   out[8+3] = 0;
136 
137   while (len >= 5) {
138     pid = (buf[1] & 0x1f) << 8 | buf[2];
139     l   = (buf[3] & 0xf) << 8 | buf[4];
140 
141     if (l > len - 5)
142       return;
143 
144     if (sizeof(out) < ol + l + 5 + 4 /* crc */) {
145       tvherror(LS_PASS, "PMT entry too long (%i)", l);
146       return;
147     }
148 
149     for (i = 0; i < pm->pm_ss->ss_num_components; i++) {
150       ssc = &pm->pm_ss->ss_components[i];
151       if (ssc->ssc_pid == pid)
152         break;
153     }
154     if (i < pm->pm_ss->ss_num_components) {
155       memcpy(out + ol, buf, 5 + l);
156       ol += 5 + l;
157     }
158 
159     buf += 5 + l;
160     len -= 5 + l;
161   }
162 
163   /* update section length */
164   out[1] = (out[1] & 0xf0) | ((ol + 4 - 3) >> 8);
165   out[2] = (ol + 4 - 3) & 0xff;
166 
167   ol = dvb_table_append_crc32(out, ol, sizeof(out));
168 
169   if (ol > 0 && (l = dvb_table_remux(mt, out, ol, &ob)) > 0) {
170     pass_muxer_write((muxer_t *)pm, ob, l);
171     free(ob);
172   }
173 }
174 
175 /*
176  *
177  */
178 static void
pass_muxer_sdt_cb(mpegts_psi_table_t * mt,const uint8_t * buf,int len)179 pass_muxer_sdt_cb(mpegts_psi_table_t *mt, const uint8_t *buf, int len)
180 {
181   pass_muxer_t *pm;
182   uint8_t out[1024], *ob;
183   uint16_t sid;
184   int l, ol;
185 
186   /* filter out the other transponders */
187   if (buf[0] != 0x42)
188     return;
189 
190   pm = (pass_muxer_t*)mt->mt_opaque;
191   ol   = 8 + 3;
192   memcpy(out, buf, ol);
193   buf += ol;
194   len -= ol;
195   while (len >= 5) {
196     sid = (buf[0] << 8) | buf[1];
197     l = (buf[3] & 0x0f) << 8 | buf[4];
198     if (sid != pm->pm_service_id) {
199       buf += l + 5;
200       len -= l + 5;
201       continue;
202     }
203     if (sizeof(out) < ol + l + 5 + 4 /* crc */) {
204       tvherror(LS_PASS, "SDT entry too long (%i)", l);
205       return;
206     }
207     memcpy(out + ol, buf, l + 5);
208     /* set free CA */
209     out[ol + 3] = out[ol + 3] & ~0x10;
210     ol += l + 5;
211     break;
212   }
213 
214   /* update section length */
215   out[1] = (out[1] & 0xf0) | ((ol + 4 - 3) >> 8);
216   out[2] = (ol + 4 - 3) & 0xff;
217 
218   ol = dvb_table_append_crc32(out, ol, sizeof(out));
219 
220   if (ol > 0 && (l = dvb_table_remux(mt, out, ol, &ob)) > 0) {
221     pass_muxer_write((muxer_t *)pm, ob, l);
222     free(ob);
223   }
224 }
225 
226 /*
227  *
228  */
229 static void
pass_muxer_eit_cb(mpegts_psi_table_t * mt,const uint8_t * buf,int len)230 pass_muxer_eit_cb(mpegts_psi_table_t *mt, const uint8_t *buf, int len)
231 {
232   pass_muxer_t *pm;
233   uint16_t sid;
234   uint8_t *out;
235   int olen;
236 
237   /* filter out the other transponders */
238   if ((buf[0] < 0x50 && buf[0] != 0x4e) || buf[0] > 0x5f || len < 14)
239     return;
240 
241   pm = (pass_muxer_t*)mt->mt_opaque;
242   sid = (buf[3] << 8) | buf[4];
243   if (sid != pm->pm_service_id)
244     return;
245 
246   /* TODO: set free_CA_mode bit to zero */
247 
248   len = dvb_table_append_crc32((uint8_t *)buf, len, len + 4);
249 
250   if (len > 0 && (olen = dvb_table_remux(mt, buf, len, &out)) > 0) {
251     pass_muxer_write((muxer_t *)pm, out, olen);
252     free(out);
253   }
254 }
255 
256 /**
257  * Figure out the mime-type for the muxed data stream
258  */
259 static const char*
pass_muxer_mime(muxer_t * m,const struct streaming_start * ss)260 pass_muxer_mime(muxer_t* m, const struct streaming_start *ss)
261 {
262   int i;
263   int has_audio;
264   int has_video;
265   muxer_container_type_t mc;
266   const streaming_start_component_t *ssc;
267   const source_info_t *si = &ss->ss_si;
268 
269   has_audio = 0;
270   has_video = 0;
271 
272   for(i=0; i < ss->ss_num_components; i++) {
273     ssc = &ss->ss_components[i];
274 
275     if(ssc->ssc_disabled)
276       continue;
277 
278     has_video |= SCT_ISVIDEO(ssc->ssc_type);
279     has_audio |= SCT_ISAUDIO(ssc->ssc_type);
280   }
281 
282   if(si->si_type == S_MPEG_TS)
283     mc = MC_MPEGTS;
284   else if(si->si_type == S_MPEG_PS)
285     mc = MC_MPEGPS;
286   else
287     mc = MC_UNKNOWN;
288 
289   if(has_video)
290     return muxer_container_type2mime(mc, 1);
291   else if(has_audio)
292     return muxer_container_type2mime(mc, 0);
293   else
294     return muxer_container_type2mime(MC_UNKNOWN, 0);
295 }
296 
297 
298 /**
299  * Generate the pmt and pat from a streaming start message
300  */
301 static int
pass_muxer_reconfigure(muxer_t * m,const struct streaming_start * ss)302 pass_muxer_reconfigure(muxer_t* m, const struct streaming_start *ss)
303 {
304   pass_muxer_t *pm = (pass_muxer_t*)m;
305   const streaming_start_component_t *ssc;
306   int i;
307 
308   pm->pm_service_id = ss->ss_service_id;
309   pm->pm_pmt_pid    = ss->ss_pmt_pid;
310   pm->pm_rewrite_sdt = !!pm->m_config.m_rewrite_sdt;
311   pm->pm_rewrite_eit = !!pm->m_config.m_rewrite_eit;
312 
313   for(i=0; i < ss->ss_num_components; i++) {
314     ssc = &ss->ss_components[i];
315     if (!SCT_ISVIDEO(ssc->ssc_type) && !SCT_ISAUDIO(ssc->ssc_type))
316       continue;
317     if (ssc->ssc_pid == DVB_SDT_PID && pm->pm_rewrite_sdt) {
318       tvhwarn(LS_PASS, "SDT PID shared with A/V, rewrite disabled");
319       pm->pm_rewrite_sdt = 0;
320     }
321     if (ssc->ssc_pid == DVB_EIT_PID && pm->pm_rewrite_eit) {
322       tvhwarn(LS_PASS, "EIT PID shared with A/V, rewrite disabled");
323       pm->pm_rewrite_eit = 0;
324     }
325   }
326 
327 
328   if (pm->m_config.m_rewrite_pmt) {
329 
330     if (pm->pm_ss)
331       streaming_start_unref(pm->pm_ss);
332     pm->pm_ss = streaming_start_copy(ss);
333 
334     dvb_table_parse_done(&pm->pm_pmt);
335     dvb_table_parse_init(&pm->pm_pmt, "pass-pmt", LS_TBL_PASS, pm->pm_pmt_pid,
336                          DVB_PMT_BASE, DVB_PMT_MASK, pm);
337   }
338 
339   return 0;
340 }
341 
342 
343 /**
344  * Init the passthrough muxer with streams
345  */
346 static int
pass_muxer_init(muxer_t * m,struct streaming_start * ss,const char * name)347 pass_muxer_init(muxer_t* m, struct streaming_start *ss, const char *name)
348 {
349   return pass_muxer_reconfigure(m, ss);
350 }
351 
352 
353 /**
354  * Open the muxer as a stream muxer (using a non-seekable socket)
355  */
356 static int
pass_muxer_open_stream(muxer_t * m,int fd)357 pass_muxer_open_stream(muxer_t *m, int fd)
358 {
359   pass_muxer_t *pm = (pass_muxer_t*)m;
360 
361   pm->pm_off      = 0;
362   pm->pm_fd       = fd;
363   pm->pm_seekable = 0;
364   pm->pm_filename = strdup("Live stream");
365 
366   return 0;
367 }
368 
369 
370 /**
371  * Open the file and set the file descriptor
372  */
373 static int
pass_muxer_open_file(muxer_t * m,const char * filename)374 pass_muxer_open_file(muxer_t *m, const char *filename)
375 {
376   int fd;
377   pass_muxer_t *pm = (pass_muxer_t*)m;
378 
379   tvhtrace(LS_PASS, "Creating file \"%s\" with file permissions \"%o\"", filename, pm->m_config.m_file_permissions);
380 
381   fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, pm->m_config.m_file_permissions);
382 
383   if(fd < 0) {
384     pm->pm_error = errno;
385     tvherror(LS_PASS, "%s: Unable to create file, open failed -- %s",
386 	     filename, strerror(errno));
387     pm->m_errors++;
388     return -1;
389   }
390 
391   /* bypass umask settings */
392   if (fchmod(fd, pm->m_config.m_file_permissions))
393     tvherror(LS_PASS, "%s: Unable to change permissions -- %s",
394              filename, strerror(errno));
395 
396   pm->pm_off      = 0;
397   pm->pm_seekable = 1;
398   pm->pm_fd       = fd;
399   pm->pm_filename = strdup(filename);
400   return 0;
401 }
402 
403 
404 /**
405  * Write data to the file descriptor
406  */
407 static void
pass_muxer_write(muxer_t * m,const void * data,size_t size)408 pass_muxer_write(muxer_t *m, const void *data, size_t size)
409 {
410   pass_muxer_t *pm = (pass_muxer_t*)m;
411 
412   if(pm->pm_error) {
413     pm->m_errors++;
414   } else if(tvh_write(pm->pm_fd, data, size)) {
415     pm->pm_error = errno;
416     if (!MC_IS_EOS_ERROR(errno))
417       tvherror(LS_PASS, "%s: Write failed -- %s", pm->pm_filename,
418 	       strerror(errno));
419     else
420       /* this is an end-of-streaming notification */
421       m->m_eos = 1;
422     m->m_errors++;
423     if (pm->pm_seekable) {
424       muxer_cache_update(m, pm->pm_fd, pm->pm_off, 0);
425       pm->pm_off = lseek(pm->pm_fd, 0, SEEK_CUR);
426     }
427   } else {
428     if (pm->pm_seekable)
429       muxer_cache_update(m, pm->pm_fd, pm->pm_off, 0);
430     pm->pm_off += size;
431   }
432 }
433 
434 
435 /**
436  * Write TS packets to the file descriptor
437  */
438 static void
pass_muxer_write_ts(muxer_t * m,pktbuf_t * pb)439 pass_muxer_write_ts(muxer_t *m, pktbuf_t *pb)
440 {
441   pass_muxer_t *pm = (pass_muxer_t*)m;
442   int l, pid;
443   uint8_t *tsb, *pkt = pktbuf_ptr(pb);
444   size_t  len = pktbuf_len(pb), len2;
445 
446   /* Rewrite PAT/PMT in operation */
447   if (pm->m_config.m_rewrite_pat || pm->m_config.m_rewrite_pmt ||
448       pm->pm_rewrite_sdt || pm->pm_rewrite_eit) {
449 
450     for (tsb = pktbuf_ptr(pb), len2 = pktbuf_len(pb), len = 0;
451          len2 > 0; tsb += l, len2 -= l) {
452 
453       pid = (tsb[1] & 0x1f) << 8 | tsb[2];
454       l = mpegts_word_count(tsb, len2, 0x001FFF00);
455 
456       /* Process */
457       if ( (pm->m_config.m_rewrite_pat && pid == DVB_PAT_PID) ||
458            (pm->m_config.m_rewrite_pmt && pid == pm->pm_pmt_pid) ||
459            (pm->pm_rewrite_sdt && pid == DVB_SDT_PID) ||
460            (pm->pm_rewrite_eit && pid == DVB_EIT_PID) ) {
461 
462         /* Flush */
463         if (len)
464           pass_muxer_write(m, pkt, len);
465 
466         /* Store new start point (after these packets) */
467         pkt = tsb + l;
468         len = 0;
469 
470         /* PAT */
471         if (pid == DVB_PAT_PID) {
472 
473           dvb_table_parse(&pm->pm_pat, "-", tsb, l, 1, 0, pass_muxer_pat_cb);
474 
475         /* SDT */
476         } else if (pid == DVB_SDT_PID) {
477 
478           dvb_table_parse(&pm->pm_sdt, "-", tsb, l, 1, 0, pass_muxer_sdt_cb);
479 
480         /* EIT */
481         } else if (pid == DVB_EIT_PID) {
482 
483           dvb_table_parse(&pm->pm_eit, "-", tsb, l, 1, 0, pass_muxer_eit_cb);
484 
485         /* PMT */
486         } else {
487 
488           dvb_table_parse(&pm->pm_pmt, "-", tsb, l, 1, 0, pass_muxer_pmt_cb);
489 
490         }
491 
492       /* Record */
493       } else {
494         len += l;
495       }
496     }
497   }
498 
499   if (len)
500     pass_muxer_write(m, pkt, len);
501 }
502 
503 
504 /**
505  * Write a packet directly to the file descriptor
506  */
507 static int
pass_muxer_write_pkt(muxer_t * m,streaming_message_type_t smt,void * data)508 pass_muxer_write_pkt(muxer_t *m, streaming_message_type_t smt, void *data)
509 {
510   pktbuf_t *pb = (pktbuf_t*)data;
511   pass_muxer_t *pm = (pass_muxer_t*)m;
512 
513   assert(smt == SMT_MPEGTS);
514 
515   switch(smt) {
516   case SMT_MPEGTS:
517     pass_muxer_write_ts(m, pb);
518     break;
519   default:
520     //TODO: add support for v4l (MPEG-PS)
521     break;
522   }
523 
524   pktbuf_ref_dec(pb);
525 
526   return pm->pm_error;
527 }
528 
529 
530 /**
531  * NOP
532  */
533 static int
pass_muxer_write_meta(muxer_t * m,struct epg_broadcast * eb,const char * comment)534 pass_muxer_write_meta(muxer_t *m, struct epg_broadcast *eb, const char *comment)
535 {
536   return 0;
537 }
538 
539 
540 /**
541  * Close the file descriptor
542  */
543 static int
pass_muxer_close(muxer_t * m)544 pass_muxer_close(muxer_t *m)
545 {
546   pass_muxer_t *pm = (pass_muxer_t*)m;
547 
548   if(pm->pm_seekable && close(pm->pm_fd)) {
549     pm->pm_error = errno;
550     tvherror(LS_PASS, "%s: Unable to close file, close failed -- %s",
551 	     pm->pm_filename, strerror(errno));
552     pm->m_errors++;
553     return -1;
554   }
555 
556   return 0;
557 }
558 
559 
560 /**
561  * Free all memory associated with the muxer
562  */
563 static void
pass_muxer_destroy(muxer_t * m)564 pass_muxer_destroy(muxer_t *m)
565 {
566   pass_muxer_t *pm = (pass_muxer_t*)m;
567 
568   if(pm->pm_filename)
569     free(pm->pm_filename);
570 
571   if (pm->pm_ss)
572     streaming_start_unref(pm->pm_ss);
573 
574   dvb_table_parse_done(&pm->pm_pat);
575   dvb_table_parse_done(&pm->pm_pmt);
576   dvb_table_parse_done(&pm->pm_sdt);
577   dvb_table_parse_done(&pm->pm_eit);
578 
579   free(pm);
580 }
581 
582 
583 /**
584  * Create a new passthrough muxer
585  */
586 muxer_t*
pass_muxer_create(const muxer_config_t * m_cfg)587 pass_muxer_create(const muxer_config_t *m_cfg)
588 {
589   pass_muxer_t *pm;
590 
591   if(m_cfg->m_type != MC_PASS && m_cfg->m_type != MC_RAW)
592     return NULL;
593 
594   pm = calloc(1, sizeof(pass_muxer_t));
595   pm->m_open_stream  = pass_muxer_open_stream;
596   pm->m_open_file    = pass_muxer_open_file;
597   pm->m_init         = pass_muxer_init;
598   pm->m_reconfigure  = pass_muxer_reconfigure;
599   pm->m_mime         = pass_muxer_mime;
600   pm->m_write_meta   = pass_muxer_write_meta;
601   pm->m_write_pkt    = pass_muxer_write_pkt;
602   pm->m_close        = pass_muxer_close;
603   pm->m_destroy      = pass_muxer_destroy;
604   pm->pm_fd          = -1;
605 
606   dvb_table_parse_init(&pm->pm_pat, "pass-pat", LS_TBL_PASS, DVB_PAT_PID,
607                        DVB_PAT_BASE, DVB_PAT_MASK, pm);
608   dvb_table_parse_init(&pm->pm_pmt, "pass-pmt", LS_TBL_PASS, 100,
609                        DVB_PMT_BASE, DVB_PMT_MASK, pm);
610   dvb_table_parse_init(&pm->pm_sdt, "pass-sdt", LS_TBL_PASS, DVB_SDT_PID,
611                        DVB_SDT_BASE, DVB_SDT_MASK, pm);
612   dvb_table_parse_init(&pm->pm_eit, "pass-eit", LS_TBL_PASS, DVB_EIT_PID,
613                        0, 0, pm);
614 
615   return (muxer_t *)pm;
616 }
617 
618