1 /*
2  *  Matroska muxer
3  *  Copyright (C) 2005 Mike Matsnev
4  *  Copyright (C) 2010 Andreas Öman
5  *
6  *  tvheadend, wrapper for the builtin dvr muxer
7  *  Copyright (C) 2012 John Törnblom
8  *
9  *  code merge, fixes, enhancements
10  *  Copyright (C) 2014,2015 Jaroslav Kysela
11  *
12  *  This program is free software: you can redistribute it and/or modify
13  *  it under the terms of the GNU General Public License as published by
14  *  the Free Software Foundation, either version 3 of the License, or
15  *  (at your option) any later version.
16  *
17  *  This program is distributed in the hope that it will be useful,
18  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  *  GNU General Public License for more details.
21  *
22  *  You should have received a copy of the GNU General Public License
23  *  along with this program.  If not, see <htmlui://www.gnu.org/licenses/>.
24  */
25 
26 #include <sys/types.h>
27 #include <sys/uio.h>
28 #include <sys/stat.h>
29 #include <fcntl.h>
30 #include <unistd.h>
31 #include <assert.h>
32 #include <string.h>
33 #include <limits.h>
34 
35 #include "tvheadend.h"
36 #include "streaming.h"
37 #include "dvr/dvr.h"
38 #include "ebml.h"
39 #include "lang_codes.h"
40 #include "epg.h"
41 #include "parsers/parser_avc.h"
42 #include "parsers/parser_hevc.h"
43 #include "muxer_mkv.h"
44 
45 extern int dvr_iov_max;
46 
47 TAILQ_HEAD(mk_cue_queue, mk_cue);
48 TAILQ_HEAD(mk_chapter_queue, mk_chapter);
49 
50 #define MATROSKA_TIMESCALE 1000000 // in nS
51 
52 
53 /**
54  *
55  */
56 typedef struct mk_track {
57   int index;
58   int avc;
59   int hevc;
60   int type;
61   int tracknum;
62   int tracktype;
63   int disabled;
64   int64_t nextpts;
65 
66   uint8_t channels;
67   uint8_t sri;
68   uint8_t ext_sri;
69 
70   uint16_t aspect_num;
71   uint16_t aspect_den;
72 
73   uint8_t commercial;
74 } mk_track_t;
75 
76 /**
77  *
78  */
79 typedef struct mk_cue {
80   TAILQ_ENTRY(mk_cue) link;
81   int64_t ts;
82   int tracknum;
83   off_t cluster_pos;
84 } mk_cue_t;
85 
86 /**
87  *
88  */
89 typedef struct mk_chapter {
90   TAILQ_ENTRY(mk_chapter) link;
91   uint32_t uuid;
92   int64_t ts;
93 } mk_chapter_t;
94 
95 typedef struct mk_muxer {
96   muxer_t;
97   int fd;
98   char *filename;
99   int error;
100   off_t fdpos; // Current position in file
101   int seekable;
102 
103   mk_track_t *tracks;
104   int ntracks;
105   int has_video;
106 
107   int64_t totduration;
108 
109   htsbuf_queue_t *cluster;
110   int64_t cluster_tc;
111   off_t cluster_pos;
112   int64_t cluster_last_close;
113   int64_t cluster_maxsize;
114 
115   off_t segment_header_pos;
116 
117   off_t segment_pos;
118 
119   off_t segmentinfo_pos;
120   off_t trackinfo_pos;
121   off_t metadata_pos;
122   off_t cue_pos;
123   off_t chapters_pos;
124 
125   int addcue;
126 
127   struct mk_cue_queue cues;
128   struct mk_chapter_queue chapters;
129 
130   uint8_t uuid[16];
131   char *title;
132 
133   int webm;
134 } mk_muxer_t;
135 
136 /* --- */
137 
138 static int mk_mux_insert_chapter(mk_muxer_t *mk);
139 
140 /**
141  *
142  */
143 static htsbuf_queue_t *
mk_build_ebmlheader(mk_muxer_t * mk)144 mk_build_ebmlheader(mk_muxer_t *mk)
145 {
146   htsbuf_queue_t *q = htsbuf_queue_alloc(0);
147 
148   ebml_append_uint(q, 0x4286, 1);
149   ebml_append_uint(q, 0x42f7, 1);
150   ebml_append_uint(q, 0x42f2, 4);
151   ebml_append_uint(q, 0x42f3, 8);
152   ebml_append_string(q, 0x4282, mk->webm ? "webm" : "matroska");
153   ebml_append_uint(q, 0x4287, 2);
154   ebml_append_uint(q, 0x4285, 2);
155   return q;
156 }
157 
158 
159 /**
160  *
161  */
162 static int
mk_split_vorbis_headers(uint8_t * extradata,int extradata_size,uint8_t * header_start[3],int header_len[3])163 mk_split_vorbis_headers(uint8_t *extradata, int extradata_size,
164 			uint8_t *header_start[3],  int header_len[3])
165 {
166   int i;
167   if (extradata_size >= 3 && extradata_size < INT_MAX - 0x1ff && extradata[0] == 2) {
168     int overall_len = 3;
169     extradata++;
170     for (i=0; i<2; i++, extradata++) {
171       header_len[i] = 0;
172       for (; overall_len < extradata_size && *extradata==0xff; extradata++) {
173 	header_len[i] += 0xff;
174 	overall_len   += 0xff + 1;
175       }
176       header_len[i] += *extradata;
177       overall_len   += *extradata;
178       if (overall_len > extradata_size)
179 	return -1;
180     }
181     header_len[2] = extradata_size - overall_len;
182     header_start[0] = extradata;
183     header_start[1] = header_start[0] + header_len[0];
184     header_start[2] = header_start[1] + header_len[1];
185   } else {
186     return -1;
187   }
188   return 0;
189 }
190 
191 
192 /**
193  *
194  */
195 static htsbuf_queue_t *
mk_build_segment_info(mk_muxer_t * mk)196 mk_build_segment_info(mk_muxer_t *mk)
197 {
198   htsbuf_queue_t *q = htsbuf_queue_alloc(0);
199   char app[128];
200 
201   snprintf(app, sizeof(app), "Tvheadend %s", tvheadend_version);
202 
203   if(!mk->webm)
204     ebml_append_bin(q, 0x73a4, mk->uuid, sizeof(mk->uuid));
205 
206   if(!mk->webm)
207     ebml_append_string(q, 0x7ba9, mk->title);
208 
209   ebml_append_string(q, 0x4d80, "Tvheadend Matroska muxer");
210   ebml_append_string(q, 0x5741, app);
211   ebml_append_uint(q, 0x2ad7b1, MATROSKA_TIMESCALE);
212 
213   if(mk->totduration)
214     ebml_append_float(q, 0x4489, (float)mk->totduration);
215   else
216     ebml_append_pad(q, 7); // Must be equal to floatingpoint duration
217   return q;
218 }
219 
220 
221 /**
222  *
223  */
224 static htsbuf_queue_t *
mk_build_tracks(mk_muxer_t * mk,streaming_start_t * ss)225 mk_build_tracks(mk_muxer_t *mk, streaming_start_t *ss)
226 {
227   streaming_start_component_t *ssc;
228   const char *codec_id;
229   int i, tracktype;
230   htsbuf_queue_t *q = htsbuf_queue_alloc(0), *t;
231   int tracknum = 0;
232   uint8_t buf4[4];
233   uint32_t bit_depth = 0;
234   mk_track_t *tr;
235 
236   mk->tracks = calloc(1, sizeof(mk_track_t) * ss->ss_num_components);
237   mk->ntracks = ss->ss_num_components;
238   mk->cluster_maxsize = 4000000;
239   for(i = 0; i < ss->ss_num_components; i++) {
240     ssc = &ss->ss_components[i];
241     tr = &mk->tracks[i];
242 
243     tr->disabled = ssc->ssc_disabled;
244     tr->index = ssc->ssc_index;
245 
246     if(tr->disabled)
247       continue;
248 
249     tr->type = ssc->ssc_type;
250     tr->channels = ssc->ssc_channels;
251     tr->aspect_num = ssc->ssc_aspect_num;
252     tr->aspect_den = ssc->ssc_aspect_den;
253     tr->commercial = COMMERCIAL_UNKNOWN;
254     tr->sri = ssc->ssc_sri;
255     tr->nextpts = PTS_UNSET;
256 
257     if (mk->webm && ssc->ssc_type != SCT_VP8 && ssc->ssc_type != SCT_VORBIS)
258       tvhwarn(LS_MKV, "WEBM format supports only VP8+VORBIS streams (detected %s)",
259               streaming_component_type2txt(ssc->ssc_type));
260 
261     switch(ssc->ssc_type) {
262     case SCT_MPEG2VIDEO:
263       tracktype = 1;
264       codec_id = "V_MPEG2";
265       break;
266 
267     case SCT_H264:
268       tracktype = 1;
269       codec_id = "V_MPEG4/ISO/AVC";
270       tr->avc = 1;
271       mk->cluster_maxsize = 10000000;
272       break;
273 
274     case SCT_HEVC:
275       tracktype = 1;
276       codec_id = "V_MPEGH/ISO/HEVC";
277       mk->cluster_maxsize = 20000000;
278       tr->hevc = 1;
279       break;
280 
281     case SCT_VP8:
282       tracktype = 1;
283       codec_id = "V_VP8";
284       mk->cluster_maxsize = 10000000;
285       break;
286 
287     case SCT_VP9:
288       tracktype = 1;
289       codec_id = "V_VP9";
290       mk->cluster_maxsize = 10000000;
291       break;
292 
293     case SCT_MPEG2AUDIO:
294       tracktype = 2;
295       codec_id  = "A_MPEG/L2";
296       if (ssc->ssc_audio_version == 3)
297         codec_id = "A_MPEG/L3";
298       else if (ssc->ssc_audio_version == 1)
299         codec_id = "A_MPEG/L1";
300       break;
301 
302     case SCT_AC3:
303       tracktype = 2;
304       codec_id = "A_AC3";
305       break;
306 
307     case SCT_EAC3:
308       tracktype = 2;
309       codec_id = "A_EAC3";
310       break;
311 
312     case SCT_MP4A:
313     case SCT_AAC:
314       tracktype = 2;
315       codec_id = "A_AAC";
316       bit_depth = 16;
317       break;
318 
319     case SCT_VORBIS:
320       tracktype = 2;
321       codec_id = "A_VORBIS";
322       break;
323 
324     case SCT_DVBSUB:
325       tracktype = 0x11;
326       codec_id = "S_DVBSUB";
327       break;
328 
329     case SCT_TEXTSUB:
330       tracktype = 0x11;
331       codec_id = "S_TEXT/UTF8";
332       break;
333 
334     default:
335       ssc->ssc_muxer_disabled = 1;
336       tr->disabled = 1;
337       continue;
338     }
339 
340     tr->tracknum = ++tracknum;
341     tr->tracktype = tracktype;
342     mk->has_video |= (tracktype == 1);
343 
344     t = htsbuf_queue_alloc(0);
345 
346     ebml_append_uint(t, 0xd7, tr->tracknum);
347     ebml_append_uint(t, 0x73c5, tr->tracknum);
348     ebml_append_uint(t, 0x83, tracktype);
349     ebml_append_uint(t, 0x9c, 0); // Lacing
350     ebml_append_string(t, 0x86, codec_id);
351 
352     if(ssc->ssc_lang[0])
353       ebml_append_string(t, 0x22b59c, ssc->ssc_lang);
354 
355     switch(ssc->ssc_type) {
356     case SCT_HEVC:
357     case SCT_H264:
358     case SCT_MPEG2VIDEO:
359     case SCT_MP4A:
360     case SCT_AAC:
361       if(ssc->ssc_gh) {
362         sbuf_t hdr;
363         sbuf_init(&hdr);
364         if (tr->avc) {
365           isom_write_avcc(&hdr, pktbuf_ptr(ssc->ssc_gh),
366                                 pktbuf_len(ssc->ssc_gh));
367         } else if (tr->hevc) {
368           isom_write_hvcc(&hdr, pktbuf_ptr(ssc->ssc_gh),
369                                 pktbuf_len(ssc->ssc_gh));
370         } else {
371           sbuf_append(&hdr, pktbuf_ptr(ssc->ssc_gh),
372                             pktbuf_len(ssc->ssc_gh));
373         }
374         ebml_append_bin(t, 0x63a2, hdr.sb_data, hdr.sb_ptr);
375         sbuf_free(&hdr);
376       }
377       break;
378 
379     case SCT_VORBIS:
380       if(ssc->ssc_gh) {
381 	htsbuf_queue_t *cp;
382 	uint8_t *header_start[3];
383 	int header_len[3];
384 	int j;
385 	if(mk_split_vorbis_headers(pktbuf_ptr(ssc->ssc_gh),
386 				   pktbuf_len(ssc->ssc_gh),
387 				   header_start,
388 				   header_len) < 0)
389 	  break;
390 
391 	cp = htsbuf_queue_alloc(0);
392 
393 	ebml_append_xiph_size(cp, 2);
394 
395 	for (j = 0; j < 2; j++)
396 	  ebml_append_xiph_size(cp, header_len[j]);
397 
398 	for (j = 0; j < 3; j++)
399 	  htsbuf_append(cp, header_start[j], header_len[j]);
400 
401 	ebml_append_master(t, 0x63a2, cp);
402       }
403       break;
404 
405     case SCT_DVBSUB:
406       buf4[0] = ssc->ssc_composition_id >> 8;
407       buf4[1] = ssc->ssc_composition_id;
408       buf4[2] = ssc->ssc_ancillary_id >> 8;
409       buf4[3] = ssc->ssc_ancillary_id;
410       ebml_append_bin(t, 0x63a2, buf4, 4);
411       break;
412     }
413 
414     if(SCT_ISVIDEO(ssc->ssc_type)) {
415       htsbuf_queue_t *vi = htsbuf_queue_alloc(0);
416 
417       if(ssc->ssc_frameduration) {
418         int d = ts_rescale(ssc->ssc_frameduration, 1000000000);
419         ebml_append_uint(t, 0x23e383, d);
420       }
421       ebml_append_uint(vi, 0xb0, ssc->ssc_width);
422       ebml_append_uint(vi, 0xba, ssc->ssc_height);
423 
424       if(mk->webm && ssc->ssc_aspect_num && ssc->ssc_aspect_den) {
425 	// DAR is not supported by webm
426 	ebml_append_uint(vi, 0x54b2, 1);
427 	ebml_append_uint(vi, 0x54b0, (ssc->ssc_height * ssc->ssc_aspect_num) / ssc->ssc_aspect_den);
428 	ebml_append_uint(vi, 0x54ba, ssc->ssc_height);
429       } else if(ssc->ssc_aspect_num && ssc->ssc_aspect_den) {
430 	ebml_append_uint(vi, 0x54b2, 3); // Display width/height is in DAR
431 	ebml_append_uint(vi, 0x54b0, ssc->ssc_aspect_num);
432 	ebml_append_uint(vi, 0x54ba, ssc->ssc_aspect_den);
433       }
434 
435       ebml_append_master(t, 0xe0, vi);
436     }
437 
438     if(SCT_ISAUDIO(ssc->ssc_type)) {
439       htsbuf_queue_t *au = htsbuf_queue_alloc(0);
440 
441       ebml_append_float(au, 0xb5, sri_to_rate(ssc->ssc_sri));
442       if (ssc->ssc_ext_sri)
443         ebml_append_float(au, 0x78b5, sri_to_rate(ssc->ssc_ext_sri - 1));
444       ebml_append_uint(au, 0x9f, ssc->ssc_channels);
445       if (bit_depth)
446         ebml_append_uint(au, 0x6264, bit_depth);
447 
448       ebml_append_master(t, 0xe1, au);
449     }
450 
451 
452     ebml_append_master(q, 0xae, t);
453   }
454   return q;
455 }
456 
457 
458 /**
459  *
460  */
461 static int
mk_write_to_fd(mk_muxer_t * mk,htsbuf_queue_t * hq)462 mk_write_to_fd(mk_muxer_t *mk, htsbuf_queue_t *hq)
463 {
464   htsbuf_data_t *hd;
465   int i = 0;
466   off_t oldpos = mk->fdpos;
467 
468   TAILQ_FOREACH(hd, &hq->hq_q, hd_link)
469     i++;
470 
471   struct iovec *iov = alloca(sizeof(struct iovec) * i);
472 
473   i = 0;
474   TAILQ_FOREACH(hd, &hq->hq_q, hd_link) {
475     iov[i  ].iov_base = hd->hd_data     + hd->hd_data_off;
476     iov[i++].iov_len  = hd->hd_data_len - hd->hd_data_off;
477   }
478 
479   do {
480     ssize_t r;
481     int iovcnt = i < dvr_iov_max ? i : dvr_iov_max;
482     if((r = writev(mk->fd, iov, iovcnt)) == -1) {
483       if (ERRNO_AGAIN(errno))
484         continue;
485       mk->error = errno;
486       return -1;
487     }
488     mk->fdpos += r;
489     i -= iovcnt;
490     iov += iovcnt;
491   } while(i);
492 
493   if (mk->seekable)
494     muxer_cache_update((muxer_t *)mk, mk->fd, oldpos, 0);
495 
496   return 0;
497 }
498 
499 
500 /**
501  *
502  */
503 static void
mk_write_queue(mk_muxer_t * mk,htsbuf_queue_t * q)504 mk_write_queue(mk_muxer_t *mk, htsbuf_queue_t *q)
505 {
506   if(!mk->error && mk_write_to_fd(mk, q) && !MC_IS_EOS_ERROR(mk->error))
507     tvherror(LS_MKV, "%s: Write failed -- %s", mk->filename, strerror(errno));
508 
509   htsbuf_queue_flush(q);
510 }
511 
512 
513 /**
514  *
515  */
516 static void
mk_write_master(mk_muxer_t * mk,uint32_t id,htsbuf_queue_t * p)517 mk_write_master(mk_muxer_t *mk, uint32_t id, htsbuf_queue_t *p)
518 {
519   htsbuf_queue_t q;
520   htsbuf_queue_init(&q, 0);
521   ebml_append_master(&q, id, p);
522   mk_write_queue(mk, &q);
523 }
524 
525 
526 /**
527  *
528  */
529 static htsbuf_queue_t *
mk_build_segment_header(int64_t size)530 mk_build_segment_header(int64_t size)
531 {
532   htsbuf_queue_t *q = htsbuf_queue_alloc(0);
533   uint8_t u8[8];
534 
535   ebml_append_id(q, 0x18538067);
536 
537   u8[0] = 1;
538   if(size == 0) {
539     memset(u8+1, 0xff, 7);
540   } else {
541     u8[1] = size >> 56;
542     u8[2] = size >> 48;
543     u8[3] = size >> 32;
544     u8[4] = size >> 24;
545     u8[5] = size >> 16;
546     u8[6] = size >> 8;
547     u8[7] = size;
548   }
549   htsbuf_append(q, &u8, 8);
550 
551   return q;
552 }
553 
554 
555 /**
556  *
557  */
558 static void
mk_write_segment_header(mk_muxer_t * mk,int64_t size)559 mk_write_segment_header(mk_muxer_t *mk, int64_t size)
560 {
561   htsbuf_queue_t *q;
562   q = mk_build_segment_header(size);
563   mk_write_queue(mk, q);
564   htsbuf_queue_free(q);
565 }
566 
567 
568 /**
569  *
570  */
571 static htsbuf_queue_t *
mk_build_one_chapter(mk_chapter_t * ch)572 mk_build_one_chapter(mk_chapter_t *ch)
573 {
574   htsbuf_queue_t *q = htsbuf_queue_alloc(0);
575 
576   ebml_append_uint(q, 0x73C4, ch->uuid);
577   ebml_append_uint(q, 0x91, ch->ts * MATROSKA_TIMESCALE);
578   ebml_append_uint(q, 0x98, 0); //ChapterFlagHidden
579   ebml_append_uint(q, 0x4598, 1); //ChapterFlagEnabled
580 
581   return q;
582 }
583 
584 
585 /**
586  *
587  */
588 static htsbuf_queue_t *
mk_build_edition_entry(mk_muxer_t * mk)589 mk_build_edition_entry(mk_muxer_t *mk)
590 {
591   mk_chapter_t *ch;
592   htsbuf_queue_t *q = htsbuf_queue_alloc(0);
593 
594   ebml_append_uint(q, 0x45bd, 0); //EditionFlagHidden
595   ebml_append_uint(q, 0x45db, 1); //EditionFlagDefault
596 
597   TAILQ_FOREACH(ch, &mk->chapters, link) {
598     ebml_append_master(q, 0xB6, mk_build_one_chapter(ch));
599   }
600 
601   return q;
602 }
603 
604 
605 /**
606  *
607  */
608 static htsbuf_queue_t *
mk_build_chapters(mk_muxer_t * mk)609 mk_build_chapters(mk_muxer_t *mk)
610 {
611   htsbuf_queue_t *q = htsbuf_queue_alloc(0);
612 
613   ebml_append_master(q, 0x45b9, mk_build_edition_entry(mk));
614 
615   return q;
616 }
617 
618 /**
619  *
620  */
621 static void
mk_write_chapters(mk_muxer_t * mk)622 mk_write_chapters(mk_muxer_t *mk)
623 {
624   if(TAILQ_FIRST(&mk->chapters) == NULL)
625     return;
626 
627   mk->chapters_pos = mk->fdpos;
628   mk_write_master(mk, 0x1043a770, mk_build_chapters(mk));
629 }
630 
631 
632 /**
633  *
634  */
635 static htsbuf_queue_t *
build_tag_string(const char * name,const char * value,const char * lang,int targettype,const char * targettypename)636 build_tag_string(const char *name, const char *value, const char *lang,
637 		 int targettype, const char *targettypename)
638 {
639   htsbuf_queue_t *q = htsbuf_queue_alloc(0);
640   htsbuf_queue_t *st = htsbuf_queue_alloc(0);
641 
642   htsbuf_queue_t *t = htsbuf_queue_alloc(0);
643   ebml_append_uint(t, 0x68ca, targettype ?: 50);
644 
645   if(targettypename)
646     ebml_append_string(t, 0x63ca, targettypename);
647   ebml_append_master(q, 0x63c0, t);
648 
649   ebml_append_string(st, 0x45a3, name);
650   ebml_append_string(st, 0x4487, value);
651   ebml_append_uint(st, 0x4484, 1);
652   ebml_append_string(st, 0x447a, lang ?: "und");
653 
654   ebml_append_master(q, 0x67c8, st);
655   return q;
656 }
657 
658 
659 /**
660  *
661  */
662 static htsbuf_queue_t *
build_tag_int(const char * name,int value,int targettype,const char * targettypename)663 build_tag_int(const char *name, int value,
664 	      int targettype, const char *targettypename)
665 {
666   char str[64];
667   snprintf(str, sizeof(str), "%d", value);
668   return build_tag_string(name, str, NULL, targettype, targettypename);
669 }
670 
671 
672 /**
673  *
674  */
675 static void
addtag(htsbuf_queue_t * q,htsbuf_queue_t * t)676 addtag(htsbuf_queue_t *q, htsbuf_queue_t *t)
677 {
678   ebml_append_master(q, 0x7373, t);
679 }
680 
681 
682 /**
683  *
684  */
685 static htsbuf_queue_t *
_mk_build_metadata(const dvr_entry_t * de,const epg_broadcast_t * ebc,const char * comment)686 _mk_build_metadata(const dvr_entry_t *de, const epg_broadcast_t *ebc,
687                    const char *comment)
688 {
689   htsbuf_queue_t *q = htsbuf_queue_alloc(0);
690   char datestr[64], ctype[100];
691   const epg_genre_t *eg = NULL;
692   epg_genre_t eg0;
693   struct tm tm;
694   time_t t;
695   epg_episode_t *ee = NULL;
696   channel_t *ch = NULL;
697   lang_str_t *ls = NULL, *ls2 = NULL;
698   const char **langs, *lang;
699 
700   if (ebc)                     ee = ebc->episode;
701   else if (de && de->de_bcast) ee = de->de_bcast->episode;
702 
703   if (de)       ch = de->de_channel;
704   else if (ebc) ch = ebc->channel;
705 
706   if (de || ebc) {
707     localtime_r(de ? &de->de_start : &ebc->start, &tm);
708   } else {
709     t = time(NULL);
710     localtime_r(&t, &tm);
711   }
712   snprintf(datestr, sizeof(datestr),
713 	   "%04d-%02d-%02d %02d:%02d:%02d",
714 	   tm.tm_year + 1900,
715 	   tm.tm_mon + 1,
716 	   tm.tm_mday,
717 	   tm.tm_hour,
718 	   tm.tm_min,
719 	   tm.tm_sec);
720 
721   addtag(q, build_tag_string("DATE_BROADCASTED", datestr, NULL, 0, NULL));
722 
723   addtag(q, build_tag_string("ORIGINAL_MEDIA_TYPE", "TV", NULL, 0, NULL));
724 
725   if(de && de->de_content_type) {
726     memset(&eg0, 0, sizeof(eg0));
727     eg0.code = de->de_content_type;
728     eg = &eg0;
729   } else if (ee) {
730     eg = LIST_FIRST(&ee->genre);
731   }
732   if(eg && epg_genre_get_str(eg, 1, 0, ctype, 100, NULL))
733     addtag(q, build_tag_string("CONTENT_TYPE", ctype, NULL, 0, NULL));
734 
735   if(ch)
736     addtag(q, build_tag_string("TVCHANNEL",
737                                channel_get_name(ch), NULL, 0, NULL));
738 
739   if (ee && ee->summary)
740     ls = ee->summary;
741   else if (ebc && ebc->summary)
742     ls = ebc->summary;
743 
744   if(de && de->de_desc)
745     ls2 = de->de_desc;
746   else if (ee && ee->description)
747     ls2 = ee->description;
748   else if (ebc && ebc->description)
749     ls2 = ebc->description;
750 
751   if (!ls)
752     ls = ls2;
753 
754   if (ls) {
755     lang_str_ele_t *e;
756     RB_FOREACH(e, ls, link)
757       addtag(q, build_tag_string("SUMMARY", e->str, e->lang, 0, NULL));
758   }
759 
760   if (ls2 && ls != ls2) {
761     lang_str_ele_t *e;
762     RB_FOREACH(e, ls2, link)
763       addtag(q, build_tag_string("DESCRIPTION", e->str, e->lang, 0, NULL));
764   }
765 
766   if (ee) {
767     epg_episode_num_t num;
768     epg_episode_get_epnum(ee, &num);
769     if(num.e_num)
770       addtag(q, build_tag_int("PART_NUMBER", num.e_num,
771 			       0, NULL));
772     if(num.s_num)
773       addtag(q, build_tag_int("PART_NUMBER", num.s_num,
774 			       60, "SEASON"));
775     if(num.p_num)
776       addtag(q, build_tag_int("PART_NUMBER", num.p_num,
777 			       40, "PART"));
778     if (num.text)
779       addtag(q, build_tag_string("SYNOPSIS",
780 			       num.text, NULL, 0, NULL));
781   }
782 
783   if (comment) {
784     lang = "eng";
785     if ((langs = lang_code_split(NULL)) && langs[0])
786       lang = tvh_strdupa(langs[0]);
787     free(langs);
788 
789     addtag(q, build_tag_string("COMMENT", comment, lang, 0, NULL));
790   }
791 
792   return q;
793 }
794 
795 
796 /**
797  *
798  */
799 static htsbuf_queue_t *
mk_build_one_metaseek(mk_muxer_t * mk,uint32_t id,off_t pos)800 mk_build_one_metaseek(mk_muxer_t *mk, uint32_t id, off_t pos)
801 {
802   htsbuf_queue_t *q = htsbuf_queue_alloc(0);
803 
804   ebml_append_idid(q, 0x53ab, id);
805   ebml_append_uint(q, 0x53ac, pos - mk->segment_pos);
806   return q;
807 }
808 
809 
810 /**
811  *
812  */
813 static void
mk_append_master(mk_muxer_t * mk,htsbuf_queue_t * q,off_t id1,off_t id2,off_t val)814 mk_append_master(mk_muxer_t *mk, htsbuf_queue_t *q,
815                  off_t id1, off_t id2, off_t val)
816 {
817   ebml_append_master(q, id1, mk_build_one_metaseek(mk, id2, val));
818 
819 }
820 
821 /**
822  *
823  */
824 static htsbuf_queue_t *
mk_build_metaseek(mk_muxer_t * mk)825 mk_build_metaseek(mk_muxer_t *mk)
826 {
827   htsbuf_queue_t *q = htsbuf_queue_alloc(0);
828 
829   if(mk->segmentinfo_pos)
830     mk_append_master(mk, q, 0x4dbb, 0x1549a966, mk->segmentinfo_pos);
831   if(mk->trackinfo_pos)
832     mk_append_master(mk, q, 0x4dbb, 0x1654ae6b, mk->trackinfo_pos);
833   if(mk->metadata_pos)
834     mk_append_master(mk, q, 0x4dbb, 0x1254c367, mk->metadata_pos);
835   if(mk->cue_pos)
836     mk_append_master(mk, q, 0x4dbb, 0x1c53bb6b, mk->cue_pos);
837   if(mk->chapters_pos)
838     mk_append_master(mk, q, 0x4dbb, 0x1043a770, mk->chapters_pos);
839   return q;
840 }
841 
842 
843 /**
844  *
845  */
846 static void
mk_write_metaseek(mk_muxer_t * mk,int first)847 mk_write_metaseek(mk_muxer_t *mk, int first)
848 {
849   htsbuf_queue_t q;
850 
851   htsbuf_queue_init(&q, 0);
852 
853   ebml_append_master(&q, 0x114d9b74, mk_build_metaseek(mk));
854 
855   assert(q.hq_size < 498);
856 
857   ebml_append_pad(&q, 500 - q.hq_size);
858 
859   if(first) {
860     mk_write_to_fd(mk, &q);
861   } else if(mk->seekable) {
862     off_t prev = mk->fdpos;
863     mk->fdpos = mk->segment_pos;
864     if(lseek(mk->fd, mk->segment_pos, SEEK_SET) == (off_t) -1)
865       mk->error = errno;
866 
867     mk_write_queue(mk, &q);
868     mk->fdpos = prev;
869     if(lseek(mk->fd, mk->fdpos, SEEK_SET) == (off_t) -1)
870       mk->error = errno;
871   }
872   htsbuf_queue_flush(&q);
873 }
874 
875 
876 /**
877  *
878  */
879 static htsbuf_queue_t *
mk_build_segment(mk_muxer_t * mk,streaming_start_t * ss)880 mk_build_segment(mk_muxer_t *mk,
881 		 streaming_start_t *ss)
882 {
883   htsbuf_queue_t *p = htsbuf_queue_alloc(0);
884 
885   assert(mk->segment_pos != 0);
886 
887   // Meta seek
888   if(mk->seekable)
889     ebml_append_pad(p, 500);
890 
891   mk->segmentinfo_pos = mk->segment_pos + p->hq_size;
892   ebml_append_master(p, 0x1549a966, mk_build_segment_info(mk));
893 
894   mk->trackinfo_pos = mk->segment_pos + p->hq_size;
895   ebml_append_master(p, 0x1654ae6b, mk_build_tracks(mk, ss));
896 
897   return p;
898 }
899 
900 
901 /**
902  *
903  */
904 static void
addcue(mk_muxer_t * mk,int64_t pts,int tracknum)905 addcue(mk_muxer_t *mk, int64_t pts, int tracknum)
906 {
907   mk_cue_t *mc = malloc(sizeof(mk_cue_t));
908   mc->ts = pts;
909   mc->tracknum = tracknum;
910   mc->cluster_pos = mk->cluster_pos;
911   TAILQ_INSERT_TAIL(&mk->cues, mc, link);
912 }
913 
914 
915 /**
916  *
917  */
918 static void
mk_add_chapter0(mk_muxer_t * mk,uint32_t uuid,int64_t ts)919 mk_add_chapter0(mk_muxer_t *mk, uint32_t uuid, int64_t ts)
920 {
921   mk_chapter_t *ch;
922 
923   ch = malloc(sizeof(mk_chapter_t));
924 
925   ch->uuid = uuid;
926   ch->ts = ts;
927 
928   TAILQ_INSERT_TAIL(&mk->chapters, ch, link);
929 }
930 
931 /**
932  *
933  */
934 static void
mk_add_chapter(mk_muxer_t * mk,int64_t ts)935 mk_add_chapter(mk_muxer_t *mk, int64_t ts)
936 {
937   mk_chapter_t *ch;
938   int uuid;
939 
940   ch = TAILQ_LAST(&mk->chapters, mk_chapter_queue);
941   if(ch) {
942     /* don't add a new chapter if the previous one was added less than 5s ago */
943     if(ts - ch->ts < 5000)
944       return;
945 
946     uuid = ch->uuid + 1;
947   } else {
948     uuid = 1;
949     /* create first chapter at zero position */
950     if (ts >= 5000) {
951       mk_add_chapter0(mk, uuid++, 0);
952     } else {
953       ts = 0;
954     }
955   }
956   mk_add_chapter0(mk, uuid, ts);
957 }
958 
959 /**
960  *
961  */
962 static void
mk_close_cluster(mk_muxer_t * mk)963 mk_close_cluster(mk_muxer_t *mk)
964 {
965   if(mk->cluster != NULL)
966     mk_write_master(mk, 0x1f43b675, mk->cluster);
967   mk->cluster = NULL;
968   mk->cluster_last_close = mclk();
969 }
970 
971 
972 /**
973  *
974  */
975 static void
mk_write_frame_i(mk_muxer_t * mk,mk_track_t * t,th_pkt_t * pkt)976 mk_write_frame_i(mk_muxer_t *mk, mk_track_t *t, th_pkt_t *pkt)
977 {
978   int64_t pts = pkt->pkt_pts, delta, nxt;
979   unsigned char c_delta_flags[3];
980   const int video = t->tracktype == 1;
981   const int audio = t->tracktype == 2;
982   int keyframe = 0, skippable = 0;
983 
984   if (video) {
985     keyframe  = pkt->v.pkt_frametype < PKT_P_FRAME;
986     skippable = pkt->v.pkt_frametype == PKT_B_FRAME;
987   }
988 
989   uint8_t *data = pktbuf_ptr(pkt->pkt_payload);
990   size_t len = pktbuf_len(pkt->pkt_payload);
991 
992   if(!data || len <= 0)
993     return;
994 
995   if(pts == PTS_UNSET)
996     // This is our best guess, it might be wrong but... oh well
997     pts = t->nextpts;
998 
999   if(pts != PTS_UNSET) {
1000     t->nextpts = pts + (pkt->pkt_duration >> (video ? pkt->v.pkt_field : 0));
1001 
1002     nxt = ts_rescale(t->nextpts, 1000000000 / MATROSKA_TIMESCALE);
1003     pts = ts_rescale(pts,        1000000000 / MATROSKA_TIMESCALE);
1004 
1005     if((t->tracktype == 1 || t->tracktype == 2) && mk->totduration < nxt)
1006       mk->totduration = nxt;
1007 
1008     delta = pts - mk->cluster_tc;
1009     if((keyframe || !mk->has_video) && (delta > 30000ll || delta < -30000ll))
1010       mk_close_cluster(mk);
1011 
1012   } else {
1013     return;
1014   }
1015 
1016   if(mk->cluster) {
1017 
1018     if(keyframe &&
1019        (mk->cluster->hq_size > mk->cluster_maxsize ||
1020         mk->cluster_last_close + sec2mono(1) < mclk()))
1021       mk_close_cluster(mk);
1022 
1023     else if(!mk->has_video &&
1024             (mk->cluster->hq_size > mk->cluster_maxsize/40 ||
1025              mk->cluster_last_close + sec2mono(1) < mclk()))
1026       mk_close_cluster(mk);
1027 
1028     else if(mk->cluster->hq_size > mk->cluster_maxsize)
1029       mk_close_cluster(mk);
1030 
1031   }
1032 
1033   if(mk->cluster == NULL) {
1034     mk->cluster_tc = pts;
1035     mk->cluster = htsbuf_queue_alloc(0);
1036 
1037     mk->cluster_pos = mk->fdpos;
1038     mk->addcue = 1;
1039 
1040     ebml_append_uint(mk->cluster, 0xe7, mk->cluster_tc);
1041     delta = 0;
1042   }
1043 
1044   if(mk->addcue && keyframe) {
1045     mk->addcue = 0;
1046     addcue(mk, pts, t->tracknum);
1047   }
1048 
1049   if(t->type == SCT_AAC || t->type == SCT_MP4A) {
1050     // Skip ADTS header
1051     if(len < 7)
1052       return;
1053 
1054     len -= 7;
1055     data += 7;
1056   }
1057 
1058   ebml_append_id(mk->cluster, 0xa3 ); // SimpleBlock
1059   ebml_append_size(mk->cluster, len + 4);
1060   ebml_append_size(mk->cluster, t->tracknum);
1061 
1062   c_delta_flags[0] = delta >> 8;
1063   c_delta_flags[1] = delta;
1064   if (audio && pkt->a.pkt_keyframe) keyframe = 1;
1065   c_delta_flags[2] = (keyframe << 7) | skippable;
1066   htsbuf_append(mk->cluster, c_delta_flags, 3);
1067   htsbuf_append(mk->cluster, data, len);
1068 }
1069 
1070 
1071 /**
1072  *
1073  */
1074 static void
mk_write_cues(mk_muxer_t * mk)1075 mk_write_cues(mk_muxer_t *mk)
1076 {
1077   mk_cue_t *mc;
1078   htsbuf_queue_t *q, *c, *p;
1079 
1080   if(TAILQ_FIRST(&mk->cues) == NULL)
1081     return;
1082 
1083   q = htsbuf_queue_alloc(0);
1084 
1085   while((mc = TAILQ_FIRST(&mk->cues)) != NULL) {
1086     TAILQ_REMOVE(&mk->cues, mc, link);
1087 
1088     c = htsbuf_queue_alloc(0);
1089 
1090     ebml_append_uint(c, 0xb3, mc->ts);
1091 
1092     p = htsbuf_queue_alloc(0);
1093     ebml_append_uint(p, 0xf7, mc->tracknum);
1094     ebml_append_uint(p, 0xf1, mc->cluster_pos - mk->segment_pos);
1095 
1096     ebml_append_master(c, 0xb7, p);
1097     ebml_append_master(q, 0xbb, c);
1098     free(mc);
1099   }
1100 
1101   mk->cue_pos = mk->fdpos;
1102   mk_write_master(mk, 0x1c53bb6b, q);
1103 }
1104 
1105 
1106 /**
1107  * Append a packet to the muxer
1108  */
1109 static int
mk_mux_write_pkt(mk_muxer_t * mk,th_pkt_t * pkt)1110 mk_mux_write_pkt(mk_muxer_t *mk, th_pkt_t *pkt)
1111 {
1112   int i, mark;
1113   mk_track_t *t = NULL;
1114   th_pkt_t *opkt;
1115 
1116   for (i = 0; i < mk->ntracks; i++) {
1117     t = &mk->tracks[i];
1118     if (t->index == pkt->pkt_componentindex && !t->disabled)
1119       break;
1120   }
1121 
1122   if(i >= mk->ntracks || pkt->pkt_payload == NULL) {
1123     pkt_ref_dec(pkt);
1124     return mk->error;
1125   }
1126 
1127   mark = 0;
1128   if(SCT_ISAUDIO(pkt->pkt_type)) {
1129     if(pkt->a.pkt_channels != t->channels &&
1130        pkt->a.pkt_channels) {
1131       mark = 1;
1132       t->channels = pkt->a.pkt_channels;
1133     }
1134     if(pkt->a.pkt_sri != t->sri &&
1135        pkt->a.pkt_sri) {
1136       mark = 1;
1137       t->sri = pkt->a.pkt_sri;
1138       t->ext_sri = pkt->a.pkt_ext_sri;
1139     }
1140   } else if (SCT_ISVIDEO(pkt->pkt_type)) {
1141     if(pkt->v.pkt_aspect_num != t->aspect_num &&
1142        pkt->v.pkt_aspect_num) {
1143       mark = 1;
1144       t->aspect_num = pkt->v.pkt_aspect_num;
1145     }
1146     if(pkt->v.pkt_aspect_den != t->aspect_den &&
1147        pkt->v.pkt_aspect_den) {
1148       mark = 1;
1149       t->aspect_den = pkt->v.pkt_aspect_den;
1150     }
1151   }
1152   if(pkt->pkt_commercial != t->commercial &&
1153      pkt->pkt_commercial != COMMERCIAL_UNKNOWN) {
1154     mark = 1;
1155     t->commercial = pkt->pkt_commercial;
1156   }
1157 
1158   if(mark)
1159     mk_mux_insert_chapter(mk);
1160 
1161   if(t->hevc) {
1162     pkt = hevc_convert_pkt(opkt = pkt);
1163     pkt_ref_dec(opkt);
1164   } else if(t->avc) {
1165     pkt = avc_convert_pkt(opkt = pkt);
1166     pkt_ref_dec(opkt);
1167   }
1168 
1169   mk_write_frame_i(mk, t, pkt);
1170 
1171   pkt_ref_dec(pkt);
1172 
1173   return mk->error;
1174 }
1175 
1176 
1177 /**
1178  * Insert a new chapter at the current location
1179  */
1180 static int
mk_mux_insert_chapter(mk_muxer_t * mk)1181 mk_mux_insert_chapter(mk_muxer_t *mk)
1182 {
1183   if(mk->totduration != PTS_UNSET)
1184     mk_add_chapter(mk, mk->totduration);
1185 
1186   return mk->error;
1187 }
1188 
1189 
1190 /**
1191  * Close the muxer
1192  */
1193 static int
mk_mux_close(mk_muxer_t * mk)1194 mk_mux_close(mk_muxer_t *mk)
1195 {
1196   int64_t totsize;
1197   mk_close_cluster(mk);
1198   mk_write_cues(mk);
1199   mk_write_chapters(mk);
1200 
1201   mk_write_metaseek(mk, 0);
1202   totsize = mk->fdpos;
1203 
1204   if(mk->seekable) {
1205     // Rewrite segment info to update duration
1206     if(lseek(mk->fd, mk->segmentinfo_pos, SEEK_SET) == mk->segmentinfo_pos)
1207       mk_write_master(mk, 0x1549a966, mk_build_segment_info(mk));
1208     else {
1209       mk->error = errno;
1210       tvherror(LS_MKV, "%s: Unable to write duration, seek failed -- %s",
1211 	       mk->filename, strerror(errno));
1212     }
1213 
1214     // Rewrite segment header to update total size
1215     if(lseek(mk->fd, mk->segment_header_pos, SEEK_SET) == mk->segment_header_pos) {
1216       mk_write_segment_header(mk, totsize - mk->segment_header_pos - 12);
1217     } else {
1218       mk->error = errno;
1219       tvherror(LS_MKV, "%s: Unable to write total size, seek failed -- %s",
1220 	       mk->filename, strerror(errno));
1221     }
1222 
1223     if(close(mk->fd)) {
1224       mk->error = errno;
1225       tvherror(LS_MKV, "%s: Unable to close the file descriptor, close failed -- %s",
1226 	       mk->filename, strerror(errno));
1227     }
1228   }
1229 
1230   return mk->error;
1231 }
1232 
1233 /**
1234  * Figure out the mimetype
1235  */
1236 static const char*
mkv_muxer_mime(muxer_t * m,const struct streaming_start * ss)1237 mkv_muxer_mime(muxer_t* m, const struct streaming_start *ss)
1238 {
1239   int i;
1240   int has_audio;
1241   int has_video;
1242   const streaming_start_component_t *ssc;
1243 
1244   has_audio = 0;
1245   has_video = 0;
1246 
1247   for(i=0; i < ss->ss_num_components; i++) {
1248     ssc = &ss->ss_components[i];
1249 
1250     if(ssc->ssc_disabled)
1251       continue;
1252 
1253     has_video |= SCT_ISVIDEO(ssc->ssc_type);
1254     has_audio |= SCT_ISAUDIO(ssc->ssc_type);
1255   }
1256 
1257   if(has_video)
1258     return muxer_container_type2mime(m->m_config.m_type, 1);
1259   else if(has_audio)
1260     return muxer_container_type2mime(m->m_config.m_type, 0);
1261   else
1262     return muxer_container_type2mime(MC_UNKNOWN, 0);
1263 }
1264 
1265 /**
1266  * Init the muxer with a title and some tracks
1267  */
1268 static int
mkv_muxer_init(muxer_t * m,streaming_start_t * ss,const char * name)1269 mkv_muxer_init(muxer_t *m, streaming_start_t *ss, const char *name)
1270 {
1271   mk_muxer_t *mk = (mk_muxer_t *)m;
1272   htsbuf_queue_t q, *a;
1273 
1274   uuid_random(mk->uuid, sizeof(mk->uuid));
1275 
1276   if(name)
1277     mk->title = strdup(name);
1278   else
1279     mk->title = strdup(mk->filename);
1280 
1281   TAILQ_INIT(&mk->cues);
1282   TAILQ_INIT(&mk->chapters);
1283 
1284   htsbuf_queue_init(&q, 0);
1285 
1286   ebml_append_master(&q, 0x1a45dfa3, mk_build_ebmlheader(mk));
1287 
1288   mk->segment_header_pos = q.hq_size;
1289   a = mk_build_segment_header(0);
1290   htsbuf_appendq(&q, a);
1291   htsbuf_queue_free(a);
1292 
1293   mk->segment_pos = q.hq_size;
1294   a = mk_build_segment(mk, ss);
1295   htsbuf_appendq(&q, a);
1296   htsbuf_queue_free(a);
1297 
1298   mk_write_queue(mk, &q);
1299 
1300   htsbuf_queue_flush(&q);
1301 
1302   return mk->error;
1303 }
1304 
1305 
1306 /**
1307  * Insert a new chapter at the current location
1308  */
1309 static int
mkv_muxer_add_marker(muxer_t * m)1310 mkv_muxer_add_marker(muxer_t* m)
1311 {
1312   mk_muxer_t *mk = (mk_muxer_t*)m;
1313 
1314   if(mk_mux_insert_chapter(mk)) {
1315     mk->m_errors++;
1316     return -1;
1317   }
1318 
1319   return 0;
1320 }
1321 
1322 
1323 /**
1324  * Multisegment matroska files do exist but I am not sure if they are supported
1325  * by many media players. For now, we'll treat it as an error.
1326  */
1327 static int
mkv_muxer_reconfigure(muxer_t * m,const struct streaming_start * ss)1328 mkv_muxer_reconfigure(muxer_t* m, const struct streaming_start *ss)
1329 {
1330   mk_muxer_t *mk = (mk_muxer_t*)m;
1331 
1332   mk->m_errors++;
1333 
1334   return -1;
1335 }
1336 
1337 
1338 /**
1339  * Open the muxer as a stream muxer (using a non-seekable socket)
1340  */
1341 static int
mkv_muxer_open_stream(muxer_t * m,int fd)1342 mkv_muxer_open_stream(muxer_t *m, int fd)
1343 {
1344   mk_muxer_t *mk = (mk_muxer_t*)m;
1345 
1346   mk->filename = strdup("Live stream");
1347   mk->fd = fd;
1348   mk->cluster_maxsize = 0;
1349   mk->totduration = 0;
1350 
1351   return 0;
1352 }
1353 
1354 
1355 /**
1356  * Open a file
1357  */
1358 static int
mkv_muxer_open_file(muxer_t * m,const char * filename)1359 mkv_muxer_open_file(muxer_t *m, const char *filename)
1360 {
1361   mk_muxer_t *mk = (mk_muxer_t*)m;
1362   int fd, permissions = mk->m_config.m_file_permissions;
1363 
1364   tvhtrace(LS_MKV, "Creating file \"%s\" with file permissions \"%o\"",
1365            filename, permissions);
1366 
1367   fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, permissions);
1368 
1369   if(fd < 0) {
1370     mk->error = errno;
1371     tvherror(LS_MKV, "%s: Unable to create file, open failed -- %s",
1372 	     mk->filename, strerror(errno));
1373     mk->m_errors++;
1374     return -1;
1375   }
1376 
1377   /* bypass umask settings */
1378   if (fchmod(fd, permissions))
1379     tvherror(LS_MKV, "%s: Unable to change permissions -- %s",
1380              filename, strerror(errno));
1381 
1382   mk->filename = strdup(filename);
1383   mk->fd = fd;
1384   mk->cluster_maxsize = 2000000;
1385   mk->seekable = 1;
1386   mk->totduration = 0;
1387 
1388   return 0;
1389 }
1390 
1391 
1392 /**
1393  * Write a packet to the muxer
1394  */
1395 static int
mkv_muxer_write_pkt(muxer_t * m,streaming_message_type_t smt,void * data)1396 mkv_muxer_write_pkt(muxer_t *m, streaming_message_type_t smt, void *data)
1397 {
1398   th_pkt_t *pkt = (th_pkt_t*)data;
1399   mk_muxer_t *mk = (mk_muxer_t*)m;
1400   int r;
1401 
1402   assert(smt == SMT_PACKET);
1403 
1404   if((r = mk_mux_write_pkt(mk, pkt)) != 0) {
1405     if (MC_IS_EOS_ERROR(r))
1406       mk->m_eos = 1;
1407     mk->m_errors++;
1408     return -1;
1409   }
1410 
1411   return 0;
1412 }
1413 
1414 
1415 /**
1416  * Append meta data when a channel changes its programme
1417  */
1418 static int
mkv_muxer_write_meta(muxer_t * m,struct epg_broadcast * eb,const char * comment)1419 mkv_muxer_write_meta(muxer_t *m, struct epg_broadcast *eb,
1420                      const char *comment)
1421 {
1422   mk_muxer_t *mk = (mk_muxer_t*)m;
1423   htsbuf_queue_t q;
1424 
1425   if(!mk->metadata_pos)
1426     mk->metadata_pos = mk->fdpos;
1427 
1428   htsbuf_queue_init(&q, 0);
1429   ebml_append_master(&q, 0x1254c367, _mk_build_metadata(NULL, eb, comment));
1430   mk_write_queue(mk, &q);
1431 
1432   if (mk->error) {
1433     mk->m_errors++;
1434     return -1;
1435   }
1436 
1437   return 0;
1438 }
1439 
1440 
1441 /**
1442  * Close the muxer and append trailer to output
1443  */
1444 static int
mkv_muxer_close(muxer_t * m)1445 mkv_muxer_close(muxer_t *m)
1446 {
1447   mk_muxer_t *mk = (mk_muxer_t*)m;
1448 
1449   if(mk_mux_close(mk)) {
1450     mk->m_errors++;
1451     return -1;
1452   }
1453 
1454   return 0;
1455 }
1456 
1457 
1458 /**
1459  * Free all memory associated with the muxer
1460  */
1461 static void
mkv_muxer_destroy(muxer_t * m)1462 mkv_muxer_destroy(muxer_t *m)
1463 {
1464   mk_muxer_t *mk = (mk_muxer_t*)m;
1465   mk_chapter_t *ch;
1466 
1467   while((ch = TAILQ_FIRST(&mk->chapters)) != NULL) {
1468     TAILQ_REMOVE(&mk->chapters, ch, link);
1469     free(ch);
1470   }
1471 
1472   free(mk->filename);
1473   free(mk->tracks);
1474   free(mk->title);
1475   free(mk);
1476 }
1477 
1478 /**
1479  * Create a new builtin muxer
1480  */
1481 muxer_t*
mkv_muxer_create(const muxer_config_t * m_cfg)1482 mkv_muxer_create(const muxer_config_t *m_cfg)
1483 {
1484   mk_muxer_t *mk;
1485 
1486   if(m_cfg->m_type != MC_MATROSKA && m_cfg->m_type != MC_WEBM)
1487     return NULL;
1488 
1489   mk = calloc(1, sizeof(mk_muxer_t));
1490   mk->m_open_stream  = mkv_muxer_open_stream;
1491   mk->m_open_file    = mkv_muxer_open_file;
1492   mk->m_mime         = mkv_muxer_mime;
1493   mk->m_init         = mkv_muxer_init;
1494   mk->m_reconfigure  = mkv_muxer_reconfigure;
1495   mk->m_add_marker   = mkv_muxer_add_marker;
1496   mk->m_write_meta   = mkv_muxer_write_meta;
1497   mk->m_write_pkt    = mkv_muxer_write_pkt;
1498   mk->m_close        = mkv_muxer_close;
1499   mk->m_destroy      = mkv_muxer_destroy;
1500   mk->webm           = m_cfg->m_type == MC_WEBM;
1501   mk->fd             = -1;
1502 
1503   return (muxer_t*)mk;
1504 }
1505