1 /*
2  * Copyright (c) 2011-2012 - Mauro Carvalho Chehab
3  * Copyright (c) 2012 - Andre Roth <neolynx@gmail.com>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU Lesser General Public License as published by
7  * the Free Software Foundation version 2.1 of the License.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
18  *
19  */
20 
21 /**
22  * @file pmt.h
23  * @ingroup dvb_table
24  * @brief Provides the descriptors for PMT MPEG-TS table
25  * @copyright GNU Lesser General Public License version 2.1 (LGPLv2.1)
26  * @author Mauro Carvalho Chehab
27  * @author Andre Roth
28  *
29  * @par Relevant specs
30  * The table described herein is defined at:
31  * - ISO/IEC 13818-1
32  *
33  * @see http://www.etherguidesystems.com/help/sdos/mpeg/syntax/tablesections/pmts.aspx
34  *
35  * @par Bug Report
36  * Please submit bug reports and patches to linux-media@vger.kernel.org
37  */
38 
39 #ifndef _PMT_H
40 #define _PMT_H
41 
42 #include <stdint.h>
43 #include <unistd.h> /* ssize_t */
44 
45 #include <libdvbv5/header.h>
46 
47 /**
48  * @def DVB_TABLE_PMT
49  *	@brief PMT table ID
50  *	@ingroup dvb_table
51  */
52 #define DVB_TABLE_PMT      0x02
53 
54 /**
55  * @enum dvb_streams
56  * @brief Add support for MPEG-TS Stream types
57  * @ingroup dvb_table
58  *
59  * @var stream_reserved0
60  *	@brief	ITU-T | ISO/IEC Reserved
61  * @var stream_video
62  *	@brief	ISO/IEC 11172 Video
63  * @var stream_video_h262
64  *	@brief	ITU-T Rec. H.262 | ISO/IEC 13818-2 Video or ISO/IEC 11172-2 constrained parameter video stream
65  * @var stream_audio
66  *	@brief	ISO/IEC 11172 Audio
67  * @var stream_audio_13818_3
68  *	@brief	ISO/IEC 13818-3 Audio
69  * @var stream_private_sections
70  *	@brief	ITU-T Rec. H.222.0 | ISO/IEC 13818-1 private_sections
71  * @var stream_private_data
72  *	@brief	ITU-T Rec. H.222.0 | ISO/IEC 13818-1 PES packets containing private data
73  * @var stream_mheg
74  *	@brief	ISO/IEC 13522 MHEG
75  * @var stream_h222
76  *	@brief	ITU-T Rec. H.222.0 | ISO/IEC 13818-1 Annex A DSM-CC
77  * @var stream_h222_1
78  *	@brief	ITU-T Rec. H.222.1
79  * @var stream_13818_6_A
80  *	@brief	ISO/IEC 13818-6 type A
81  * @var stream_13818_6_B
82  *	@brief	ISO/IEC 13818-6 type B
83  * @var stream_13818_6_C
84  *	@brief	ISO/IEC 13818-6 type C
85  * @var stream_13818_6_D
86  *	@brief	ISO/IEC 13818-6 type D
87  * @var stream_h222_aux
88  *	@brief	ITU-T Rec. H.222.0 | ISO/IEC 13818-1 auxiliary
89  * @var stream_audio_adts
90  *	@brief	ISO/IEC 13818-7 Audio with ADTS transport syntax
91  * @var stream_video_14496_2
92  *	@brief	ISO/IEC 14496-2 Visual
93  * @var stream_audio_latm
94  *	@brief	ISO/IEC 14496-3 Audio with the LATM transport syntax as defined in ISO/IEC 14496-3 / AMD 1
95  * @var stream_14496_1_pes
96  *	@brief	ISO/IEC 14496-1 SL-packetized stream or FlexMux stream carried in PES packets
97  * @var stream_14496_1_iso
98  *	@brief	ISO/IEC 14496-1 SL-packetized stream or FlexMux stream carried in ISO/IEC14496_sections.
99  * @var stream_download
100  *	@brief	ISO/IEC 13818-6 Synchronized Download Protocol
101  * @var stream_reserved
102  *	@brief	ITU-T Rec. H.222.0 | ISO/IEC 13818-1 Reserved (from 0x15 to 0x7f)
103  * @var stream_private
104  *	@brief	User Private (from 0x80 to 0xff)
105  */
106 enum dvb_streams {
107 	stream_video		= 0x01,
108 	stream_video_h262	= 0x02,
109 	stream_audio		= 0x03,
110 	stream_audio_13818_3	= 0x04,
111 	stream_private_sections	= 0x05,
112 	stream_private_data	= 0x06,
113 	stream_mheg		= 0x07,
114 	stream_h222		= 0x08,
115 	stream_h222_1		= 0x09,
116 	stream_13818_6_A	= 0x0A,
117 	stream_13818_6_B	= 0x0B,
118 	stream_13818_6_C	= 0x0C,
119 	stream_13818_6_D	= 0x0D,
120 	stream_h222_aux		= 0x0E,
121 	stream_audio_adts	= 0x0F,
122 	stream_video_14496_2	= 0x10,
123 	stream_audio_latm	= 0x11,
124 	stream_14496_1_pes	= 0x12,
125 	stream_14496_1_iso	= 0x13,
126 	stream_download		= 0x14,
127 	stream_video_h264	= 0x1b,
128 	stream_audio_14496_3	= 0x1c,
129 	stream_video_hevc	= 0x24,
130 	stream_video_cavs	= 0x42,
131 	stream_video_moto	= 0x80,
132 	stream_audio_a52	= 0x81,
133 	stream_scte_27		= 0x82,
134 	stream_audio_sdds	= 0x84,
135 	stream_audio_dts_hdmv	= 0x85,
136 	stream_audio_e_ac3	= 0x87,
137 	stream_audio_dts	= 0x8a,
138 	stream_audio_a52_vls	= 0x91,
139 	stream_spu_vls		= 0x92,
140 	stream_audio_sdds2	= 0x94,
141 };
142 
143 /**
144  * @brief Converts from enum dvb_streams into a string
145  * @ingroup dvb_table
146  */
147 extern const char *pmt_stream_name[];
148 
149 /**
150  * @struct dvb_table_pmt_stream
151  * @brief MPEG-TS PMT stream table
152  * @ingroup dvb_table
153  *
154  * @param type			stream type
155  * @param elementary_pid	elementary pid
156  * @param desc_length		descriptor length
157  * @param zero			zero
158  * @param descriptor		pointer to struct dvb_desc
159  * @param next			pointer to struct dvb_table_pmt_stream
160 
161  *
162  * This structure is used to store the original PMT stream table,
163  * converting the integer fields to the CPU endianness.
164  *
165  * The undocumented parameters are used only internally by the API and/or
166  * are fields that are reserved. They shouldn't be used, as they may change
167  * on future API releases.
168  *
169  * Everything after dvb_table_pmt_stream::descriptor (including it) won't be
170  * bit-mapped to the data parsed from the MPEG TS. So, metadata are added there.
171  */
172 struct dvb_table_pmt_stream {
173 	uint8_t type;
174 	union {
175 		uint16_t bitfield;
176 		struct {
177 			uint16_t elementary_pid:13;
178 			uint16_t reserved:3;
179 		} __attribute__((packed));
180 	} __attribute__((packed));
181 	union {
182 		uint16_t bitfield2;
183 		struct {
184 			uint16_t desc_length:10;
185 			uint16_t zero:2;
186 			uint16_t reserved2:4;
187 		} __attribute__((packed));
188 	} __attribute__((packed));
189 	struct dvb_desc *descriptor;
190 	struct dvb_table_pmt_stream *next;
191 } __attribute__((packed));
192 
193 /**
194  * @struct dvb_table_pmt
195  * @brief MPEG-TS PMT table
196  * @ingroup dvb_table
197  *
198  * @param header	struct dvb_table_header content
199  * @param pcr_pid	PCR PID
200  * @param desc_length	descriptor length
201  * @param descriptor	pointer to struct dvb_desc
202  * @param stream	pointer to struct dvb_table_pmt_stream
203  *
204  * This structure is used to store the original PMT stream table,
205  * converting the integer fields to the CPU endianness.
206  *
207  * The undocumented parameters are used only internally by the API and/or
208  * are fields that are reserved. They shouldn't be used, as they may change
209  * on future API releases.
210  *
211  * Everything after dvb_table_pmt::descriptor (including it) won't be
212  * bit-mapped to the data parsed from the MPEG TS. So, metadata are added there.
213  */
214 struct dvb_table_pmt {
215 	struct dvb_table_header header;
216 	union {
217 		uint16_t bitfield;
218 		struct {
219 			uint16_t pcr_pid:13;
220 			uint16_t reserved2:3;
221 		} __attribute__((packed));
222 	} __attribute__((packed));
223 
224 	union {
225 		uint16_t bitfield2;
226 		struct {
227 			uint16_t desc_length:10;
228 			uint16_t zero3:2;
229 			uint16_t reserved3:4;
230 		} __attribute__((packed));
231 	} __attribute__((packed));
232 	struct dvb_desc *descriptor;
233 	struct dvb_table_pmt_stream *stream;
234 } __attribute__((packed));
235 
236 /** @brief First field at the struct */
237 #define dvb_pmt_field_first header
238 
239 /** @brief First field that are not part of the received data */
240 #define dvb_pmt_field_last descriptor
241 
242 /**
243  * @brief Macro used to find streams on a PMT table
244  * @ingroup dvb_table
245  *
246  * @param _stream	stream to seek
247  * @param _pmt		pointer to struct dvb_table_pmt_stream
248  */
249 #define dvb_pmt_stream_foreach(_stream, _pmt) \
250 	if (_pmt && _pmt->stream) \
251 		for (struct dvb_table_pmt_stream *_stream = _pmt->stream; _stream; _stream = _stream->next) \
252 
253 struct dvb_v5_fe_parms;
254 
255 #ifdef __cplusplus
256 extern "C" {
257 #endif
258 
259 /**
260  * @brief Initializes and parses PMT table
261  * @ingroup dvb_table
262  *
263  * @param parms	struct dvb_v5_fe_parms pointer to the opened device
264  * @param buf buffer containing the PMT raw data
265  * @param buflen length of the buffer
266  * @param table pointer to struct dvb_table_pmt to be allocated and filled
267  *
268  * This function allocates a PMT table and fills the fields inside
269  * the struct. It also makes sure that all fields will follow the CPU
270  * endianness. Due to that, the content of the buffer may change.
271  *
272  * @return On success, it returns the size of the allocated struct.
273  *	   A negative value indicates an error.
274  */
275 ssize_t dvb_table_pmt_init (struct dvb_v5_fe_parms *parms, const uint8_t *buf,
276 			    ssize_t buflen, struct dvb_table_pmt **table);
277 
278 /**
279  * @brief Frees all data allocated by the PMT table parser
280  * @ingroup dvb_table
281  *
282  * @param table pointer to struct dvb_table_pmt to be freed
283  */
284 void dvb_table_pmt_free(struct dvb_table_pmt *table);
285 
286 /**
287  * @brief Prints the content of the PAT table
288  * @ingroup dvb_table
289  *
290  * @param parms	struct dvb_v5_fe_parms pointer to the opened device
291  * @param table pointer to struct dvb_table_pmt
292  */
293 void dvb_table_pmt_print(struct dvb_v5_fe_parms *parms,
294 			 const struct dvb_table_pmt *table);
295 
296 #ifdef __cplusplus
297 }
298 #endif
299 
300 #endif
301