1 /*
2  *  tvheadend, generic muxing utils
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 #ifndef MUXER_H_
20 #define MUXER_H_
21 
22 #include "htsmsg.h"
23 
24 #define MC_IS_EOS_ERROR(e) ((e) == EPIPE || (e) == ECONNRESET)
25 
26 typedef enum {
27   MC_UNKNOWN     = 0,
28   MC_MATROSKA    = 1,
29   MC_MPEGTS      = 2,
30   MC_MPEGPS      = 3,
31   MC_PASS        = 4,
32   MC_RAW         = 5,
33   MC_WEBM        = 6,
34   MC_AVMATROSKA  = 7,
35   MC_AVWEBM      = 8,
36   MC_AVMP4       = 9,
37   MC_MPEG2AUDIO  = 10,
38   MC_AC3         = 11,
39   MC_AAC         = 12,
40   MC_MP4A        = 13,
41   MC_VORBIS      = 14
42 } muxer_container_type_t;
43 
44 typedef enum {
45   MC_CACHE_UNKNOWN      = 0,
46   MC_CACHE_SYSTEM       = 1,
47   MC_CACHE_DONTKEEP     = 2,
48   MC_CACHE_SYNC         = 3,
49   MC_CACHE_SYNCDONTKEEP = 4,
50   MC_CACHE_LAST         = MC_CACHE_SYNCDONTKEEP
51 } muxer_cache_type_t;
52 
53 /* Muxer configuration used when creating a muxer. */
54 typedef struct muxer_config {
55   int                  m_type; /* MC_* */
56 
57   int                  m_rewrite_pat;
58   int                  m_rewrite_pmt;
59   int                  m_rewrite_sdt;
60   int                  m_rewrite_eit;
61   int                  m_cache;
62 
63   int                  m_force_type;
64   int                  m_index;
65 
66 /*
67  * directory_permissions should really be in dvr.h as it's not really needed for the muxer
68  * but it's kept with file_permissions for neatness
69  */
70 
71   int                  m_file_permissions;
72   int                  m_directory_permissions;
73 } muxer_config_t;
74 
75 struct muxer;
76 struct streaming_start;
77 struct th_pkt;
78 struct epg_broadcast;
79 struct service;
80 
81 typedef struct muxer {
82   int         (*m_open_stream)(struct muxer *, int fd);                 /* Open for socket streaming */
83   int         (*m_open_file)  (struct muxer *, const char *filename);   /* Open for file storage */
84   const char* (*m_mime)       (struct muxer *,                          /* Figure out the mimetype */
85 			       const struct streaming_start *);
86   int         (*m_init)       (struct muxer *,                          /* Init The muxer with streams */
87 			       struct streaming_start *,
88 			       const char *);
89   int         (*m_reconfigure)(struct muxer *,                          /* Reconfigure the muxer on */
90 			       const struct streaming_start *);           /* stream changes */
91   int         (*m_close)      (struct muxer *);                         /* Close the muxer */
92   void        (*m_destroy)    (struct muxer *);                         /* Free the memory */
93   int         (*m_write_meta) (struct muxer *, struct epg_broadcast *,
94                                const char *comment);                    /* Append epg data */
95   int         (*m_write_pkt)  (struct muxer *,                          /* Append a media packet */
96 			       streaming_message_type_t,
97 			       void *);
98   int         (*m_add_marker) (struct muxer *);                         /* Add a marker (or chapter) */
99 
100   int                    m_eos;        /* End of stream */
101   int                    m_errors;     /* Number of errors */
102   muxer_config_t         m_config;     /* general configuration */
103 } muxer_t;
104 
105 
106 /* type <==> string converters */
107 const char *           muxer_container_type2txt  (muxer_container_type_t mc);
108 const char*            muxer_container_type2mime (muxer_container_type_t mc, int video);
109 const char*            muxer_container_filename2mime (const char *filename, int video);
110 
111 muxer_container_type_t muxer_container_txt2type  (const char *str);
112 muxer_container_type_t muxer_container_mime2type (const char *str);
113 
114 const char*            muxer_container_suffix(muxer_container_type_t mc, int video);
115 
116 /* Muxer factory */
117 muxer_t *muxer_create(const muxer_config_t *m_cfg);
118 
119 /* Wrapper functions */
muxer_open_file(muxer_t * m,const char * filename)120 static inline int muxer_open_file (muxer_t *m, const char *filename)
121   { if(m && filename) return m->m_open_file(m, filename); return -1; }
122 
muxer_open_stream(muxer_t * m,int fd)123 static inline int muxer_open_stream (muxer_t *m, int fd)
124   { if(m && fd >= 0) return m->m_open_stream(m, fd); return -1; }
125 
muxer_init(muxer_t * m,struct streaming_start * ss,const char * name)126 static inline int muxer_init (muxer_t *m, struct streaming_start *ss, const char *name)
127   { if(m && ss) return m->m_init(m, ss, name); return -1; }
128 
muxer_reconfigure(muxer_t * m,const struct streaming_start * ss)129 static inline int muxer_reconfigure (muxer_t *m, const struct streaming_start *ss)
130   { if(m && ss) return m->m_reconfigure(m, ss); return -1; }
131 
muxer_add_marker(muxer_t * m)132 static inline int muxer_add_marker (muxer_t *m)
133   { if (m && m->m_add_marker) return m->m_add_marker(m); return -1; }
134 
muxer_close(muxer_t * m)135 static inline int muxer_close (muxer_t *m)
136   { if (m) return m->m_close(m); return -1; }
137 
muxer_destroy(muxer_t * m)138 static inline int muxer_destroy (muxer_t *m)
139   { if (m) { m->m_destroy(m); return 0; } return -1; }
140 
muxer_write_meta(muxer_t * m,struct epg_broadcast * eb,const char * comment)141 static inline int muxer_write_meta (muxer_t *m, struct epg_broadcast *eb, const char *comment)
142   { if (m) return m->m_write_meta(m, eb, comment); return -1; }
143 
muxer_write_pkt(muxer_t * m,streaming_message_type_t smt,void * data)144 static inline int muxer_write_pkt (muxer_t *m, streaming_message_type_t smt, void *data)
145   { if (m && data) return m->m_write_pkt(m, smt, data); return -1; }
146 
muxer_mime(muxer_t * m,const struct streaming_start * ss)147 static inline const char* muxer_mime (muxer_t *m, const struct streaming_start *ss)
148   { if (m && ss) return m->m_mime(m, ss); return NULL; }
149 
150 const char* muxer_suffix      (muxer_t *m, const struct streaming_start *ss);
151 
152 /* Cache */
153 const char *       muxer_cache_type2txt(muxer_cache_type_t t);
154 muxer_cache_type_t muxer_cache_txt2type(const char *str);
155 void               muxer_cache_update(muxer_t *m, int fd, off_t off, size_t size);
156 int                muxer_cache_list(htsmsg_t *array);
157 
158 #endif
159