1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | /* |
3 | * This file contains the logic to work with MPEG Program-Specific Information. |
4 | * These are defined both in ISO/IEC 13818-1 (systems) and ETSI EN 300 468. |
5 | * PSI is carried in the form of table structures, and although each table might |
6 | * technically be broken into one or more sections, we do not do this here, |
7 | * hence 'table' and 'section' are interchangeable for vidtv. |
8 | * |
9 | * Copyright (C) 2020 Daniel W. S. Almeida |
10 | */ |
11 | |
12 | #ifndef VIDTV_PSI_H |
13 | #define VIDTV_PSI_H |
14 | |
15 | #include <linux/types.h> |
16 | |
17 | /* |
18 | * all section lengths start immediately after the 'section_length' field |
19 | * see ISO/IEC 13818-1 : 2000 and ETSI EN 300 468 V 1.10.1 for |
20 | * reference |
21 | */ |
22 | #define PAT_LEN_UNTIL_LAST_SECTION_NUMBER 5 |
23 | #define PMT_LEN_UNTIL_PROGRAM_INFO_LENGTH 9 |
24 | #define SDT_LEN_UNTIL_RESERVED_FOR_FUTURE_USE 8 |
25 | #define NIT_LEN_UNTIL_NETWORK_DESCRIPTOR_LEN 7 |
26 | #define EIT_LEN_UNTIL_LAST_TABLE_ID 11 |
27 | #define MAX_SECTION_LEN 1021 |
28 | #define EIT_MAX_SECTION_LEN 4093 /* see ETSI 300 468 v.1.10.1 p. 26 */ |
29 | #define VIDTV_PAT_PID 0 /* mandated by the specs */ |
30 | #define VIDTV_SDT_PID 0x0011 /* mandated by the specs */ |
31 | #define VIDTV_NIT_PID 0x0010 /* mandated by the specs */ |
32 | #define VIDTV_EIT_PID 0x0012 /*mandated by the specs */ |
33 | |
34 | enum vidtv_psi_descriptors { |
35 | REGISTRATION_DESCRIPTOR = 0x05, /* See ISO/IEC 13818-1 section 2.6.8 */ |
36 | NETWORK_NAME_DESCRIPTOR = 0x40, /* See ETSI EN 300 468 section 6.2.27 */ |
37 | SERVICE_LIST_DESCRIPTOR = 0x41, /* See ETSI EN 300 468 section 6.2.35 */ |
38 | SERVICE_DESCRIPTOR = 0x48, /* See ETSI EN 300 468 section 6.2.33 */ |
39 | SHORT_EVENT_DESCRIPTOR = 0x4d, /* See ETSI EN 300 468 section 6.2.37 */ |
40 | }; |
41 | |
42 | enum vidtv_psi_stream_types { |
43 | STREAM_PRIVATE_DATA = 0x06, /* see ISO/IEC 13818-1 2000 p. 48 */ |
44 | }; |
45 | |
46 | /* |
47 | * struct vidtv_psi_desc - A generic PSI descriptor type. |
48 | * The descriptor length is an 8-bit field specifying the total number of bytes of the data portion |
49 | * of the descriptor following the byte defining the value of this field. |
50 | */ |
51 | struct vidtv_psi_desc { |
52 | struct vidtv_psi_desc *next; |
53 | u8 type; |
54 | u8 length; |
55 | u8 data[]; |
56 | } __packed; |
57 | |
58 | /* |
59 | * struct vidtv_psi_desc_service - Service descriptor. |
60 | * See ETSI EN 300 468 section 6.2.33. |
61 | */ |
62 | struct vidtv_psi_desc_service { |
63 | struct vidtv_psi_desc *next; |
64 | u8 type; |
65 | u8 length; |
66 | |
67 | u8 service_type; |
68 | u8 provider_name_len; |
69 | char *provider_name; |
70 | u8 service_name_len; |
71 | char *service_name; |
72 | } __packed; |
73 | |
74 | /* |
75 | * struct vidtv_psi_desc_registration - A registration descriptor. |
76 | * See ISO/IEC 13818-1 section 2.6.8 |
77 | */ |
78 | struct vidtv_psi_desc_registration { |
79 | struct vidtv_psi_desc *next; |
80 | u8 type; |
81 | u8 length; |
82 | |
83 | /* |
84 | * The format_identifier is a 32-bit value obtained from a Registration |
85 | * Authority as designated by ISO/IEC JTC 1/SC 29. |
86 | */ |
87 | __be32 format_id; |
88 | /* |
89 | * The meaning of additional_identification_info bytes, if any, are |
90 | * defined by the assignee of that format_identifier, and once defined |
91 | * they shall not change. |
92 | */ |
93 | u8 additional_identification_info[]; |
94 | } __packed; |
95 | |
96 | /* |
97 | * struct vidtv_psi_desc_network_name - A network name descriptor |
98 | * see ETSI EN 300 468 v1.15.1 section 6.2.27 |
99 | */ |
100 | struct vidtv_psi_desc_network_name { |
101 | struct vidtv_psi_desc *next; |
102 | u8 type; |
103 | u8 length; |
104 | char *network_name; |
105 | } __packed; |
106 | |
107 | struct vidtv_psi_desc_service_list_entry { |
108 | __be16 service_id; |
109 | u8 service_type; |
110 | struct vidtv_psi_desc_service_list_entry *next; |
111 | } __packed; |
112 | |
113 | /* |
114 | * struct vidtv_psi_desc_service_list - A service list descriptor |
115 | * see ETSI EN 300 468 v1.15.1 section 6.2.35 |
116 | */ |
117 | struct vidtv_psi_desc_service_list { |
118 | struct vidtv_psi_desc *next; |
119 | u8 type; |
120 | u8 length; |
121 | struct vidtv_psi_desc_service_list_entry *service_list; |
122 | } __packed; |
123 | |
124 | /* |
125 | * struct vidtv_psi_desc_short_event - A short event descriptor |
126 | * see ETSI EN 300 468 v1.15.1 section 6.2.37 |
127 | */ |
128 | struct vidtv_psi_desc_short_event { |
129 | struct vidtv_psi_desc *next; |
130 | u8 type; |
131 | u8 length; |
132 | char *iso_language_code; |
133 | u8 event_name_len; |
134 | char *event_name; |
135 | u8 text_len; |
136 | char *text; |
137 | } __packed; |
138 | |
139 | struct vidtv_psi_desc_short_event |
140 | *vidtv_psi_short_event_desc_init(struct vidtv_psi_desc *head, |
141 | char *iso_language_code, |
142 | char *event_name, |
143 | char *text); |
144 | |
145 | /* |
146 | * struct vidtv_psi_table_header - A header that is present for all PSI tables. |
147 | */ |
148 | struct { |
149 | u8 ; |
150 | |
151 | __be16 ; /* syntax: 1, zero: 1, one: 2, section_length: 13 */ |
152 | |
153 | __be16 ; /* TS ID */ |
154 | u8 :1; |
155 | u8 :5; |
156 | u8 :2; |
157 | u8 ; /* section_number */ |
158 | u8 ; /* last_section_number */ |
159 | } __packed; |
160 | |
161 | /* |
162 | * struct vidtv_psi_table_pat_program - A single program in the PAT |
163 | * See ISO/IEC 13818-1 : 2000 p.43 |
164 | */ |
165 | struct vidtv_psi_table_pat_program { |
166 | __be16 service_id; |
167 | __be16 bitfield; /* reserved: 3, program_map_pid/network_pid: 13 */ |
168 | struct vidtv_psi_table_pat_program *next; |
169 | } __packed; |
170 | |
171 | /* |
172 | * struct vidtv_psi_table_pat - The Program Allocation Table (PAT) |
173 | * See ISO/IEC 13818-1 : 2000 p.43 |
174 | */ |
175 | struct vidtv_psi_table_pat { |
176 | struct vidtv_psi_table_header ; |
177 | u16 num_pat; |
178 | u16 num_pmt; |
179 | struct vidtv_psi_table_pat_program *program; |
180 | } __packed; |
181 | |
182 | /* |
183 | * struct vidtv_psi_table_sdt_service - Represents a service in the SDT. |
184 | * see ETSI EN 300 468 v1.15.1 section 5.2.3. |
185 | */ |
186 | struct vidtv_psi_table_sdt_service { |
187 | __be16 service_id; |
188 | u8 EIT_present_following:1; |
189 | u8 EIT_schedule:1; |
190 | u8 reserved:6; |
191 | __be16 bitfield; /* running_status: 3, free_ca:1, desc_loop_len:12 */ |
192 | struct vidtv_psi_desc *descriptor; |
193 | struct vidtv_psi_table_sdt_service *next; |
194 | } __packed; |
195 | |
196 | /* |
197 | * struct vidtv_psi_table_sdt - Represents the Service Description Table |
198 | * see ETSI EN 300 468 v1.15.1 section 5.2.3. |
199 | */ |
200 | |
201 | struct vidtv_psi_table_sdt { |
202 | struct vidtv_psi_table_header ; |
203 | __be16 network_id; /* original_network_id */ |
204 | u8 reserved; |
205 | struct vidtv_psi_table_sdt_service *service; |
206 | } __packed; |
207 | |
208 | /* |
209 | * enum service_running_status - Status of a SDT service. |
210 | * see ETSI EN 300 468 v1.15.1 section 5.2.3 table 6. |
211 | */ |
212 | enum service_running_status { |
213 | RUNNING = 0x4, |
214 | }; |
215 | |
216 | /* |
217 | * enum service_type - The type of a SDT service. |
218 | * see ETSI EN 300 468 v1.15.1 section 6.2.33, table 81. |
219 | */ |
220 | enum service_type { |
221 | /* see ETSI EN 300 468 v1.15.1 p. 77 */ |
222 | DIGITAL_TELEVISION_SERVICE = 0x1, |
223 | DIGITAL_RADIO_SOUND_SERVICE = 0X2, |
224 | }; |
225 | |
226 | /* |
227 | * struct vidtv_psi_table_pmt_stream - A single stream in the PMT. |
228 | * See ISO/IEC 13818-1 : 2000 p.46. |
229 | */ |
230 | struct vidtv_psi_table_pmt_stream { |
231 | u8 type; |
232 | __be16 bitfield; /* reserved: 3, elementary_pid: 13 */ |
233 | __be16 bitfield2; /*reserved: 4, zero: 2, desc_length: 10 */ |
234 | struct vidtv_psi_desc *descriptor; |
235 | struct vidtv_psi_table_pmt_stream *next; |
236 | } __packed; |
237 | |
238 | /* |
239 | * struct vidtv_psi_table_pmt - The Program Map Table (PMT). |
240 | * See ISO/IEC 13818-1 : 2000 p.46. |
241 | */ |
242 | struct vidtv_psi_table_pmt { |
243 | struct vidtv_psi_table_header ; |
244 | __be16 bitfield; /* reserved:3, pcr_pid: 13 */ |
245 | __be16 bitfield2; /* reserved: 4, zero: 2, desc_len: 10 */ |
246 | struct vidtv_psi_desc *descriptor; |
247 | struct vidtv_psi_table_pmt_stream *stream; |
248 | } __packed; |
249 | |
250 | /** |
251 | * struct psi_write_args - Arguments for the PSI packetizer. |
252 | * @dest_buf: The buffer to write into. |
253 | * @from: PSI data to be copied. |
254 | * @len: How much to write. |
255 | * @dest_offset: where to start writing in the dest_buffer. |
256 | * @pid: TS packet ID. |
257 | * @new_psi_section: Set when starting a table section. |
258 | * @continuity_counter: Incremented on every new packet. |
259 | * @is_crc: Set when writing the CRC at the end. |
260 | * @dest_buf_sz: The size of the dest_buffer |
261 | * @crc: a pointer to store the crc for this chunk |
262 | */ |
263 | struct psi_write_args { |
264 | void *dest_buf; |
265 | void *from; |
266 | size_t len; |
267 | u32 dest_offset; |
268 | u16 pid; |
269 | bool new_psi_section; |
270 | u8 *continuity_counter; |
271 | bool is_crc; |
272 | u32 dest_buf_sz; |
273 | u32 *crc; |
274 | }; |
275 | |
276 | /** |
277 | * struct desc_write_args - Arguments in order to write a descriptor. |
278 | * @dest_buf: The buffer to write into. |
279 | * @dest_offset: where to start writing in the dest_buffer. |
280 | * @desc: A pointer to the descriptor |
281 | * @pid: TS packet ID. |
282 | * @continuity_counter: Incremented on every new packet. |
283 | * @dest_buf_sz: The size of the dest_buffer |
284 | * @crc: a pointer to store the crc for this chunk |
285 | */ |
286 | struct desc_write_args { |
287 | void *dest_buf; |
288 | u32 dest_offset; |
289 | struct vidtv_psi_desc *desc; |
290 | u16 pid; |
291 | u8 *continuity_counter; |
292 | u32 dest_buf_sz; |
293 | u32 *crc; |
294 | }; |
295 | |
296 | /** |
297 | * struct crc32_write_args - Arguments in order to write the CRC at the end of |
298 | * the PSI tables. |
299 | * @dest_buf: The buffer to write into. |
300 | * @dest_offset: where to start writing in the dest_buffer. |
301 | * @crc: the CRC value to write |
302 | * @pid: TS packet ID. |
303 | * @continuity_counter: Incremented on every new packet. |
304 | * @dest_buf_sz: The size of the dest_buffer |
305 | */ |
306 | struct crc32_write_args { |
307 | void *dest_buf; |
308 | u32 dest_offset; |
309 | __be32 crc; |
310 | u16 pid; |
311 | u8 *continuity_counter; |
312 | u32 dest_buf_sz; |
313 | }; |
314 | |
315 | /** |
316 | * struct header_write_args - Arguments in order to write the common table |
317 | * header |
318 | * @dest_buf: The buffer to write into. |
319 | * @dest_offset: where to start writing in the dest_buffer. |
320 | * @h: a pointer to the header. |
321 | * @pid: TS packet ID. |
322 | * @continuity_counter: Incremented on every new packet. |
323 | * @dest_buf_sz: The size of the dest_buffer |
324 | * @crc: a pointer to store the crc for this chunk |
325 | */ |
326 | struct { |
327 | void *; |
328 | u32 ; |
329 | struct vidtv_psi_table_header *; |
330 | u16 ; |
331 | u8 *; |
332 | u32 ; |
333 | u32 *; |
334 | }; |
335 | |
336 | struct vidtv_psi_desc_service *vidtv_psi_service_desc_init(struct vidtv_psi_desc *head, |
337 | enum service_type service_type, |
338 | char *service_name, |
339 | char *provider_name); |
340 | |
341 | struct vidtv_psi_desc_registration |
342 | *vidtv_psi_registration_desc_init(struct vidtv_psi_desc *head, |
343 | __be32 format_id, |
344 | u8 *additional_ident_info, |
345 | u32 additional_info_len); |
346 | |
347 | struct vidtv_psi_desc_network_name |
348 | *vidtv_psi_network_name_desc_init(struct vidtv_psi_desc *head, char *network_name); |
349 | |
350 | struct vidtv_psi_desc_service_list |
351 | *vidtv_psi_service_list_desc_init(struct vidtv_psi_desc *head, |
352 | struct vidtv_psi_desc_service_list_entry *entry); |
353 | |
354 | struct vidtv_psi_table_pat_program |
355 | *vidtv_psi_pat_program_init(struct vidtv_psi_table_pat_program *head, |
356 | u16 service_id, |
357 | u16 program_map_pid); |
358 | |
359 | struct vidtv_psi_table_pmt_stream* |
360 | vidtv_psi_pmt_stream_init(struct vidtv_psi_table_pmt_stream *head, |
361 | enum vidtv_psi_stream_types stream_type, |
362 | u16 es_pid); |
363 | |
364 | struct vidtv_psi_table_pat *vidtv_psi_pat_table_init(u16 transport_stream_id); |
365 | |
366 | struct vidtv_psi_table_pmt *vidtv_psi_pmt_table_init(u16 program_number, |
367 | u16 pcr_pid); |
368 | |
369 | struct vidtv_psi_table_sdt *vidtv_psi_sdt_table_init(u16 network_id, |
370 | u16 transport_stream_id); |
371 | |
372 | struct vidtv_psi_table_sdt_service* |
373 | vidtv_psi_sdt_service_init(struct vidtv_psi_table_sdt_service *head, |
374 | u16 service_id, |
375 | bool eit_schedule, |
376 | bool eit_present_following); |
377 | |
378 | void |
379 | vidtv_psi_desc_destroy(struct vidtv_psi_desc *desc); |
380 | |
381 | void |
382 | vidtv_psi_pat_program_destroy(struct vidtv_psi_table_pat_program *p); |
383 | |
384 | void |
385 | vidtv_psi_pat_table_destroy(struct vidtv_psi_table_pat *p); |
386 | |
387 | void |
388 | vidtv_psi_pmt_stream_destroy(struct vidtv_psi_table_pmt_stream *s); |
389 | |
390 | void |
391 | vidtv_psi_pmt_table_destroy(struct vidtv_psi_table_pmt *pmt); |
392 | |
393 | void |
394 | vidtv_psi_sdt_table_destroy(struct vidtv_psi_table_sdt *sdt); |
395 | |
396 | void |
397 | vidtv_psi_sdt_service_destroy(struct vidtv_psi_table_sdt_service *service); |
398 | |
399 | /** |
400 | * vidtv_psi_sdt_service_assign - Assigns the service loop to the SDT. |
401 | * @sdt: The SDT to assign to. |
402 | * @service: The service loop (one or more services) |
403 | * |
404 | * This will free the previous service loop in the table. |
405 | * This will assign ownership of the service loop to the table, i.e. the table |
406 | * will free this service loop when a call to its destroy function is made. |
407 | */ |
408 | void |
409 | vidtv_psi_sdt_service_assign(struct vidtv_psi_table_sdt *sdt, |
410 | struct vidtv_psi_table_sdt_service *service); |
411 | |
412 | /** |
413 | * vidtv_psi_desc_assign - Assigns a descriptor loop at some point |
414 | * @to: Where to assign this descriptor loop to |
415 | * @desc: The descriptor loop that will be assigned. |
416 | * |
417 | * This will free the loop in 'to', if any. |
418 | */ |
419 | void vidtv_psi_desc_assign(struct vidtv_psi_desc **to, |
420 | struct vidtv_psi_desc *desc); |
421 | |
422 | /** |
423 | * vidtv_pmt_desc_assign - Assigns a descriptor loop at some point in a PMT section. |
424 | * @pmt: The PMT section that will contain the descriptor loop |
425 | * @to: Where in the PMT to assign this descriptor loop to |
426 | * @desc: The descriptor loop that will be assigned. |
427 | * |
428 | * This will free the loop in 'to', if any. |
429 | * This will assign ownership of the loop to the table, i.e. the table |
430 | * will free this loop when a call to its destroy function is made. |
431 | */ |
432 | void vidtv_pmt_desc_assign(struct vidtv_psi_table_pmt *pmt, |
433 | struct vidtv_psi_desc **to, |
434 | struct vidtv_psi_desc *desc); |
435 | |
436 | /** |
437 | * vidtv_sdt_desc_assign - Assigns a descriptor loop at some point in a SDT. |
438 | * @sdt: The SDT that will contain the descriptor loop |
439 | * @to: Where in the PMT to assign this descriptor loop to |
440 | * @desc: The descriptor loop that will be assigned. |
441 | * |
442 | * This will free the loop in 'to', if any. |
443 | * This will assign ownership of the loop to the table, i.e. the table |
444 | * will free this loop when a call to its destroy function is made. |
445 | */ |
446 | void vidtv_sdt_desc_assign(struct vidtv_psi_table_sdt *sdt, |
447 | struct vidtv_psi_desc **to, |
448 | struct vidtv_psi_desc *desc); |
449 | |
450 | /** |
451 | * vidtv_psi_pat_program_assign - Assigns the program loop to the PAT. |
452 | * @pat: The PAT to assign to. |
453 | * @p: The program loop (one or more programs) |
454 | * |
455 | * This will free the previous program loop in the table. |
456 | * This will assign ownership of the program loop to the table, i.e. the table |
457 | * will free this program loop when a call to its destroy function is made. |
458 | */ |
459 | void vidtv_psi_pat_program_assign(struct vidtv_psi_table_pat *pat, |
460 | struct vidtv_psi_table_pat_program *p); |
461 | |
462 | /** |
463 | * vidtv_psi_pmt_stream_assign - Assigns the stream loop to the PAT. |
464 | * @pmt: The PMT to assign to. |
465 | * @s: The stream loop (one or more streams) |
466 | * |
467 | * This will free the previous stream loop in the table. |
468 | * This will assign ownership of the stream loop to the table, i.e. the table |
469 | * will free this stream loop when a call to its destroy function is made. |
470 | */ |
471 | void vidtv_psi_pmt_stream_assign(struct vidtv_psi_table_pmt *pmt, |
472 | struct vidtv_psi_table_pmt_stream *s); |
473 | |
474 | struct vidtv_psi_desc *vidtv_psi_desc_clone(struct vidtv_psi_desc *desc); |
475 | |
476 | /** |
477 | * vidtv_psi_pmt_create_sec_for_each_pat_entry - Create a PMT section for each |
478 | * program found in the PAT |
479 | * @pat: The PAT to look for programs. |
480 | * @pcr_pid: packet ID for the PCR to be used for the program described in this |
481 | * PMT section |
482 | */ |
483 | struct vidtv_psi_table_pmt** |
484 | vidtv_psi_pmt_create_sec_for_each_pat_entry(struct vidtv_psi_table_pat *pat, u16 pcr_pid); |
485 | |
486 | /** |
487 | * vidtv_psi_pmt_get_pid - Get the TS PID for a PMT section. |
488 | * @section: The PMT section whose PID we want to retrieve. |
489 | * @pat: The PAT table to look into. |
490 | * |
491 | * Returns: the TS PID for 'section' |
492 | */ |
493 | u16 vidtv_psi_pmt_get_pid(struct vidtv_psi_table_pmt *section, |
494 | struct vidtv_psi_table_pat *pat); |
495 | |
496 | /** |
497 | * vidtv_psi_pat_table_update_sec_len - Recompute and update the PAT section length. |
498 | * @pat: The PAT whose length is to be updated. |
499 | * |
500 | * This will traverse the table and accumulate the length of its components, |
501 | * which is then used to replace the 'section_length' field. |
502 | * |
503 | * If section_length > MAX_SECTION_LEN, the operation fails. |
504 | */ |
505 | void vidtv_psi_pat_table_update_sec_len(struct vidtv_psi_table_pat *pat); |
506 | |
507 | /** |
508 | * vidtv_psi_pmt_table_update_sec_len - Recompute and update the PMT section length. |
509 | * @pmt: The PMT whose length is to be updated. |
510 | * |
511 | * This will traverse the table and accumulate the length of its components, |
512 | * which is then used to replace the 'section_length' field. |
513 | * |
514 | * If section_length > MAX_SECTION_LEN, the operation fails. |
515 | */ |
516 | void vidtv_psi_pmt_table_update_sec_len(struct vidtv_psi_table_pmt *pmt); |
517 | |
518 | /** |
519 | * vidtv_psi_sdt_table_update_sec_len - Recompute and update the SDT section length. |
520 | * @sdt: The SDT whose length is to be updated. |
521 | * |
522 | * This will traverse the table and accumulate the length of its components, |
523 | * which is then used to replace the 'section_length' field. |
524 | * |
525 | * If section_length > MAX_SECTION_LEN, the operation fails. |
526 | */ |
527 | void vidtv_psi_sdt_table_update_sec_len(struct vidtv_psi_table_sdt *sdt); |
528 | |
529 | /** |
530 | * struct vidtv_psi_pat_write_args - Arguments for writing a PAT table |
531 | * @buf: The destination buffer. |
532 | * @offset: The offset into the destination buffer. |
533 | * @pat: A pointer to the PAT. |
534 | * @buf_sz: The size of the destination buffer. |
535 | * @continuity_counter: A pointer to the CC. Incremented on every new packet. |
536 | * |
537 | */ |
538 | struct vidtv_psi_pat_write_args { |
539 | char *buf; |
540 | u32 offset; |
541 | struct vidtv_psi_table_pat *pat; |
542 | u32 buf_sz; |
543 | u8 *continuity_counter; |
544 | }; |
545 | |
546 | /** |
547 | * vidtv_psi_pat_write_into - Write PAT as MPEG-TS packets into a buffer. |
548 | * @args: An instance of struct vidtv_psi_pat_write_args |
549 | * |
550 | * This function writes the MPEG TS packets for a PAT table into a buffer. |
551 | * Calling code will usually generate the PAT via a call to its init function |
552 | * and thus is responsible for freeing it. |
553 | * |
554 | * Return: The number of bytes written into the buffer. This is NOT |
555 | * equal to the size of the PAT, since more space is needed for TS headers during TS |
556 | * encapsulation. |
557 | */ |
558 | u32 vidtv_psi_pat_write_into(struct vidtv_psi_pat_write_args *args); |
559 | |
560 | /** |
561 | * struct vidtv_psi_sdt_write_args - Arguments for writing a SDT table |
562 | * @buf: The destination buffer. |
563 | * @offset: The offset into the destination buffer. |
564 | * @sdt: A pointer to the SDT. |
565 | * @buf_sz: The size of the destination buffer. |
566 | * @continuity_counter: A pointer to the CC. Incremented on every new packet. |
567 | * |
568 | */ |
569 | |
570 | struct vidtv_psi_sdt_write_args { |
571 | char *buf; |
572 | u32 offset; |
573 | struct vidtv_psi_table_sdt *sdt; |
574 | u32 buf_sz; |
575 | u8 *continuity_counter; |
576 | }; |
577 | |
578 | /** |
579 | * vidtv_psi_sdt_write_into - Write SDT as MPEG-TS packets into a buffer. |
580 | * @args: an instance of struct vidtv_psi_sdt_write_args |
581 | * |
582 | * This function writes the MPEG TS packets for a SDT table into a buffer. |
583 | * Calling code will usually generate the SDT via a call to its init function |
584 | * and thus is responsible for freeing it. |
585 | * |
586 | * Return: The number of bytes written into the buffer. This is NOT |
587 | * equal to the size of the SDT, since more space is needed for TS headers during TS |
588 | * encapsulation. |
589 | */ |
590 | u32 vidtv_psi_sdt_write_into(struct vidtv_psi_sdt_write_args *args); |
591 | |
592 | /** |
593 | * struct vidtv_psi_pmt_write_args - Arguments for writing a PMT section |
594 | * @buf: The destination buffer. |
595 | * @offset: The offset into the destination buffer. |
596 | * @pmt: A pointer to the PMT. |
597 | * @pid: Program ID |
598 | * @buf_sz: The size of the destination buffer. |
599 | * @continuity_counter: A pointer to the CC. Incremented on every new packet. |
600 | * @pcr_pid: The TS PID used for the PSI packets. All channels will share the |
601 | * same PCR. |
602 | */ |
603 | struct vidtv_psi_pmt_write_args { |
604 | char *buf; |
605 | u32 offset; |
606 | struct vidtv_psi_table_pmt *pmt; |
607 | u16 pid; |
608 | u32 buf_sz; |
609 | u8 *continuity_counter; |
610 | u16 pcr_pid; |
611 | }; |
612 | |
613 | /** |
614 | * vidtv_psi_pmt_write_into - Write PMT as MPEG-TS packets into a buffer. |
615 | * @args: an instance of struct vidtv_psi_pmt_write_args |
616 | * |
617 | * This function writes the MPEG TS packets for a PMT section into a buffer. |
618 | * Calling code will usually generate the PMT section via a call to its init function |
619 | * and thus is responsible for freeing it. |
620 | * |
621 | * Return: The number of bytes written into the buffer. This is NOT |
622 | * equal to the size of the PMT section, since more space is needed for TS headers |
623 | * during TS encapsulation. |
624 | */ |
625 | u32 vidtv_psi_pmt_write_into(struct vidtv_psi_pmt_write_args *args); |
626 | |
627 | /** |
628 | * vidtv_psi_find_pmt_sec - Finds the PMT section for 'program_num' |
629 | * @pmt_sections: The sections to look into. |
630 | * @nsections: The number of sections. |
631 | * @program_num: The 'program_num' from PAT pointing to a PMT section. |
632 | * |
633 | * Return: A pointer to the PMT, if found, or NULL. |
634 | */ |
635 | struct vidtv_psi_table_pmt *vidtv_psi_find_pmt_sec(struct vidtv_psi_table_pmt **pmt_sections, |
636 | u16 nsections, |
637 | u16 program_num); |
638 | |
639 | u16 vidtv_psi_get_pat_program_pid(struct vidtv_psi_table_pat_program *p); |
640 | u16 vidtv_psi_pmt_stream_get_elem_pid(struct vidtv_psi_table_pmt_stream *s); |
641 | |
642 | /** |
643 | * struct vidtv_psi_table_transport - A entry in the TS loop for the NIT and/or other tables. |
644 | * See ETSI 300 468 section 5.2.1 |
645 | * @transport_id: The TS ID being described |
646 | * @network_id: The network_id that contains the TS ID |
647 | * @bitfield: Contains the descriptor loop length |
648 | * @descriptor: A descriptor loop |
649 | * @next: Pointer to the next entry |
650 | * |
651 | */ |
652 | struct vidtv_psi_table_transport { |
653 | __be16 transport_id; |
654 | __be16 network_id; |
655 | __be16 bitfield; /* desc_len: 12, reserved: 4 */ |
656 | struct vidtv_psi_desc *descriptor; |
657 | struct vidtv_psi_table_transport *next; |
658 | } __packed; |
659 | |
660 | /** |
661 | * struct vidtv_psi_table_nit - A Network Information Table (NIT). See ETSI 300 |
662 | * 468 section 5.2.1 |
663 | * @header: A PSI table header |
664 | * @bitfield: Contains the network descriptor length |
665 | * @descriptor: A descriptor loop describing the network |
666 | * @bitfield2: Contains the transport stream loop length |
667 | * @transport: The transport stream loop |
668 | * |
669 | */ |
670 | struct vidtv_psi_table_nit { |
671 | struct vidtv_psi_table_header ; |
672 | __be16 bitfield; /* network_desc_len: 12, reserved:4 */ |
673 | struct vidtv_psi_desc *descriptor; |
674 | __be16 bitfield2; /* ts_loop_len: 12, reserved: 4 */ |
675 | struct vidtv_psi_table_transport *transport; |
676 | } __packed; |
677 | |
678 | struct vidtv_psi_table_nit |
679 | *vidtv_psi_nit_table_init(u16 network_id, |
680 | u16 transport_stream_id, |
681 | char *network_name, |
682 | struct vidtv_psi_desc_service_list_entry *service_list); |
683 | |
684 | /** |
685 | * struct vidtv_psi_nit_write_args - Arguments for writing a NIT section |
686 | * @buf: The destination buffer. |
687 | * @offset: The offset into the destination buffer. |
688 | * @nit: A pointer to the NIT |
689 | * @buf_sz: The size of the destination buffer. |
690 | * @continuity_counter: A pointer to the CC. Incremented on every new packet. |
691 | * |
692 | */ |
693 | struct vidtv_psi_nit_write_args { |
694 | char *buf; |
695 | u32 offset; |
696 | struct vidtv_psi_table_nit *nit; |
697 | u32 buf_sz; |
698 | u8 *continuity_counter; |
699 | }; |
700 | |
701 | /** |
702 | * vidtv_psi_nit_write_into - Write NIT as MPEG-TS packets into a buffer. |
703 | * @args: an instance of struct vidtv_psi_nit_write_args |
704 | * |
705 | * This function writes the MPEG TS packets for a NIT table into a buffer. |
706 | * Calling code will usually generate the NIT via a call to its init function |
707 | * and thus is responsible for freeing it. |
708 | * |
709 | * Return: The number of bytes written into the buffer. This is NOT |
710 | * equal to the size of the NIT, since more space is needed for TS headers during TS |
711 | * encapsulation. |
712 | */ |
713 | u32 vidtv_psi_nit_write_into(struct vidtv_psi_nit_write_args *args); |
714 | |
715 | void vidtv_psi_nit_table_destroy(struct vidtv_psi_table_nit *nit); |
716 | |
717 | /* |
718 | * struct vidtv_psi_desc_short_event - A short event descriptor |
719 | * see ETSI EN 300 468 v1.15.1 section 6.2.37 |
720 | */ |
721 | struct vidtv_psi_table_eit_event { |
722 | __be16 event_id; |
723 | u8 start_time[5]; |
724 | u8 duration[3]; |
725 | __be16 bitfield; /* desc_length: 12, free_CA_mode: 1, running_status: 1 */ |
726 | struct vidtv_psi_desc *descriptor; |
727 | struct vidtv_psi_table_eit_event *next; |
728 | } __packed; |
729 | |
730 | /* |
731 | * struct vidtv_psi_table_eit - A Event Information Table (EIT) |
732 | * See ETSI 300 468 section 5.2.4 |
733 | */ |
734 | struct vidtv_psi_table_eit { |
735 | struct vidtv_psi_table_header ; |
736 | __be16 transport_id; |
737 | __be16 network_id; |
738 | u8 last_segment; |
739 | u8 last_table_id; |
740 | struct vidtv_psi_table_eit_event *event; |
741 | } __packed; |
742 | |
743 | struct vidtv_psi_table_eit |
744 | *vidtv_psi_eit_table_init(u16 network_id, |
745 | u16 transport_stream_id, |
746 | __be16 service_id); |
747 | |
748 | /** |
749 | * struct vidtv_psi_eit_write_args - Arguments for writing an EIT section |
750 | * @buf: The destination buffer. |
751 | * @offset: The offset into the destination buffer. |
752 | * @eit: A pointer to the EIT |
753 | * @buf_sz: The size of the destination buffer. |
754 | * @continuity_counter: A pointer to the CC. Incremented on every new packet. |
755 | * |
756 | */ |
757 | struct vidtv_psi_eit_write_args { |
758 | char *buf; |
759 | u32 offset; |
760 | struct vidtv_psi_table_eit *eit; |
761 | u32 buf_sz; |
762 | u8 *continuity_counter; |
763 | }; |
764 | |
765 | /** |
766 | * vidtv_psi_eit_write_into - Write EIT as MPEG-TS packets into a buffer. |
767 | * @args: an instance of struct vidtv_psi_nit_write_args |
768 | * |
769 | * This function writes the MPEG TS packets for a EIT table into a buffer. |
770 | * Calling code will usually generate the EIT via a call to its init function |
771 | * and thus is responsible for freeing it. |
772 | * |
773 | * Return: The number of bytes written into the buffer. This is NOT |
774 | * equal to the size of the EIT, since more space is needed for TS headers during TS |
775 | * encapsulation. |
776 | */ |
777 | u32 vidtv_psi_eit_write_into(struct vidtv_psi_eit_write_args *args); |
778 | |
779 | void vidtv_psi_eit_table_destroy(struct vidtv_psi_table_eit *eit); |
780 | |
781 | /** |
782 | * vidtv_psi_eit_table_update_sec_len - Recompute and update the EIT section length. |
783 | * @eit: The EIT whose length is to be updated. |
784 | * |
785 | * This will traverse the table and accumulate the length of its components, |
786 | * which is then used to replace the 'section_length' field. |
787 | * |
788 | * If section_length > EIT_MAX_SECTION_LEN, the operation fails. |
789 | */ |
790 | void vidtv_psi_eit_table_update_sec_len(struct vidtv_psi_table_eit *eit); |
791 | |
792 | /** |
793 | * vidtv_psi_eit_event_assign - Assigns the event loop to the EIT. |
794 | * @eit: The EIT to assign to. |
795 | * @e: The event loop |
796 | * |
797 | * This will free the previous event loop in the table. |
798 | * This will assign ownership of the stream loop to the table, i.e. the table |
799 | * will free this stream loop when a call to its destroy function is made. |
800 | */ |
801 | void vidtv_psi_eit_event_assign(struct vidtv_psi_table_eit *eit, |
802 | struct vidtv_psi_table_eit_event *e); |
803 | |
804 | struct vidtv_psi_table_eit_event |
805 | *vidtv_psi_eit_event_init(struct vidtv_psi_table_eit_event *head, u16 event_id); |
806 | |
807 | void vidtv_psi_eit_event_destroy(struct vidtv_psi_table_eit_event *e); |
808 | |
809 | #endif // VIDTV_PSI_H |
810 | |