1 /*****************************************************************************
2 * pmt.c: PMT decoder/generator
3 *----------------------------------------------------------------------------
4 * Copyright (C) 2001-2011 VideoLAN
5 * $Id$
6 *
7 * Authors: Arnaud de Bossoreille de Ribou <bozo@via.ecp.fr>
8 * Jean-Paul Saman <jpsaman@videolan.org>
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 *
24 *----------------------------------------------------------------------------
25 *
26 *****************************************************************************/
27
28 #include "config.h"
29
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <stdbool.h>
33 #include <string.h>
34
35 #if defined(HAVE_INTTYPES_H)
36 #include <inttypes.h>
37 #elif defined(HAVE_STDINT_H)
38 #include <stdint.h>
39 #endif
40
41 #include <assert.h>
42
43 #include "../dvbpsi.h"
44 #include "../dvbpsi_private.h"
45 #include "../psi.h"
46 #include "../descriptor.h"
47 #include "pmt.h"
48 #include "pmt_private.h"
49
50 /*****************************************************************************
51 * dvbpsi_pmt_attach
52 *****************************************************************************
53 * Initialize a PMT decoder and return a handle on it.
54 *****************************************************************************/
dvbpsi_pmt_attach(dvbpsi_t * p_dvbpsi,uint16_t i_program_number,dvbpsi_pmt_callback pf_callback,void * p_cb_data)55 bool dvbpsi_pmt_attach(dvbpsi_t *p_dvbpsi, uint16_t i_program_number,
56 dvbpsi_pmt_callback pf_callback, void* p_cb_data)
57 {
58 assert(p_dvbpsi);
59 assert(p_dvbpsi->p_decoder == NULL);
60
61 dvbpsi_pmt_decoder_t* p_pmt_decoder;
62 p_pmt_decoder = (dvbpsi_pmt_decoder_t*) dvbpsi_decoder_new(&dvbpsi_pmt_sections_gather,
63 1024, true, sizeof(dvbpsi_pmt_decoder_t));
64 if (p_pmt_decoder == NULL)
65 return false;
66
67 p_dvbpsi->p_decoder = DVBPSI_DECODER(p_pmt_decoder);
68
69 /* PMT decoder configuration */
70 p_pmt_decoder->i_program_number = i_program_number;
71 p_pmt_decoder->pf_pmt_callback = pf_callback;
72 p_pmt_decoder->p_cb_data = p_cb_data;
73 p_pmt_decoder->p_building_pmt = NULL;
74
75 return true;
76 }
77
78 /*****************************************************************************
79 * dvbpsi_pmt_detach
80 *****************************************************************************
81 * Close a PMT decoder. The handle isn't valid any more.
82 *****************************************************************************/
dvbpsi_pmt_detach(dvbpsi_t * p_dvbpsi)83 void dvbpsi_pmt_detach(dvbpsi_t *p_dvbpsi)
84 {
85 assert(p_dvbpsi);
86 assert(p_dvbpsi->p_decoder);
87
88 dvbpsi_pmt_decoder_t* p_pmt_decoder;
89 p_pmt_decoder = (dvbpsi_pmt_decoder_t*)p_dvbpsi->p_decoder;
90 if (p_pmt_decoder->p_building_pmt)
91 dvbpsi_pmt_delete(p_pmt_decoder->p_building_pmt);
92 p_pmt_decoder->p_building_pmt = NULL;
93
94 dvbpsi_decoder_delete(p_dvbpsi->p_decoder);
95 p_dvbpsi->p_decoder = NULL;
96 }
97
98 /*****************************************************************************
99 * dvbpsi_pmt_init
100 *****************************************************************************
101 * Initialize a pre-allocated dvbpsi_pmt_t structure.
102 *****************************************************************************/
dvbpsi_pmt_init(dvbpsi_pmt_t * p_pmt,uint16_t i_program_number,uint8_t i_version,bool b_current_next,uint16_t i_pcr_pid)103 void dvbpsi_pmt_init(dvbpsi_pmt_t* p_pmt, uint16_t i_program_number,
104 uint8_t i_version, bool b_current_next, uint16_t i_pcr_pid)
105 {
106 assert(p_pmt);
107
108 p_pmt->i_program_number = i_program_number;
109 p_pmt->i_version = i_version;
110 p_pmt->b_current_next = b_current_next;
111 p_pmt->i_pcr_pid = i_pcr_pid;
112 p_pmt->p_first_descriptor = NULL;
113 p_pmt->p_first_es = NULL;
114 }
115
116 /*****************************************************************************
117 * dvbpsi_pmt_new
118 *****************************************************************************
119 * Allocate and Initialize a new dvbpsi_pmt_t structure.
120 *****************************************************************************/
dvbpsi_pmt_new(uint16_t i_program_number,uint8_t i_version,bool b_current_next,uint16_t i_pcr_pid)121 dvbpsi_pmt_t* dvbpsi_pmt_new(uint16_t i_program_number, uint8_t i_version,
122 bool b_current_next, uint16_t i_pcr_pid)
123 {
124 dvbpsi_pmt_t *p_pmt = (dvbpsi_pmt_t*)malloc(sizeof(dvbpsi_pmt_t));
125 if(p_pmt != NULL)
126 dvbpsi_pmt_init(p_pmt, i_program_number, i_version,
127 b_current_next, i_pcr_pid);
128 return p_pmt;
129 }
130
131 /*****************************************************************************
132 * dvbpsi_pmt_empty
133 *****************************************************************************
134 * Clean a dvbpsi_pmt_t structure.
135 *****************************************************************************/
dvbpsi_pmt_empty(dvbpsi_pmt_t * p_pmt)136 void dvbpsi_pmt_empty(dvbpsi_pmt_t* p_pmt)
137 {
138 dvbpsi_pmt_es_t* p_es = p_pmt->p_first_es;
139
140 dvbpsi_DeleteDescriptors(p_pmt->p_first_descriptor);
141
142 while(p_es != NULL)
143 {
144 dvbpsi_pmt_es_t* p_tmp = p_es->p_next;
145 dvbpsi_DeleteDescriptors(p_es->p_first_descriptor);
146 free(p_es);
147 p_es = p_tmp;
148 }
149
150 p_pmt->p_first_descriptor = NULL;
151 p_pmt->p_first_es = NULL;
152 }
153
154 /*****************************************************************************
155 * dvbpsi_pmt_delete
156 *****************************************************************************
157 * Clean a dvbpsi_pmt_t structure.
158 *****************************************************************************/
dvbpsi_pmt_delete(dvbpsi_pmt_t * p_pmt)159 void dvbpsi_pmt_delete(dvbpsi_pmt_t* p_pmt)
160 {
161 if (p_pmt)
162 dvbpsi_pmt_empty(p_pmt);
163 free(p_pmt);
164 }
165
166 /*****************************************************************************
167 * dvbpsi_pmt_descriptor_add
168 *****************************************************************************
169 * Add a descriptor in the PMT.
170 *****************************************************************************/
dvbpsi_pmt_descriptor_add(dvbpsi_pmt_t * p_pmt,uint8_t i_tag,uint8_t i_length,uint8_t * p_data)171 dvbpsi_descriptor_t* dvbpsi_pmt_descriptor_add(dvbpsi_pmt_t* p_pmt,
172 uint8_t i_tag, uint8_t i_length,
173 uint8_t* p_data)
174 {
175 dvbpsi_descriptor_t* p_descriptor;
176 p_descriptor = dvbpsi_NewDescriptor(i_tag, i_length, p_data);
177 if (p_descriptor == NULL)
178 return NULL;
179
180 p_pmt->p_first_descriptor = dvbpsi_AddDescriptor(p_pmt->p_first_descriptor,
181 p_descriptor);
182 assert(p_pmt->p_first_descriptor);
183 if (p_pmt->p_first_descriptor == NULL)
184 return NULL;
185
186 return p_descriptor;
187 }
188
189 /*****************************************************************************
190 * dvbpsi_pmt_es_add
191 *****************************************************************************
192 * Add an ES in the PMT.
193 *****************************************************************************/
dvbpsi_pmt_es_add(dvbpsi_pmt_t * p_pmt,uint8_t i_type,uint16_t i_pid)194 dvbpsi_pmt_es_t* dvbpsi_pmt_es_add(dvbpsi_pmt_t* p_pmt,
195 uint8_t i_type, uint16_t i_pid)
196 {
197 dvbpsi_pmt_es_t* p_es = (dvbpsi_pmt_es_t*)malloc(sizeof(dvbpsi_pmt_es_t));
198 if (p_es == NULL)
199 return NULL;
200
201 p_es->i_type = i_type;
202 p_es->i_pid = i_pid;
203 p_es->p_first_descriptor = NULL;
204 p_es->p_next = NULL;
205
206 if (p_pmt->p_first_es == NULL)
207 p_pmt->p_first_es = p_es;
208 else
209 {
210 dvbpsi_pmt_es_t* p_last_es = p_pmt->p_first_es;
211 while (p_last_es->p_next != NULL)
212 p_last_es = p_last_es->p_next;
213 p_last_es->p_next = p_es;
214 }
215 return p_es;
216 }
217
218 /*****************************************************************************
219 * dvbpsi_pmt_es_descriptor_add
220 *****************************************************************************
221 * Add a descriptor in the PMT ES.
222 *****************************************************************************/
dvbpsi_pmt_es_descriptor_add(dvbpsi_pmt_es_t * p_es,uint8_t i_tag,uint8_t i_length,uint8_t * p_data)223 dvbpsi_descriptor_t* dvbpsi_pmt_es_descriptor_add(dvbpsi_pmt_es_t* p_es,
224 uint8_t i_tag, uint8_t i_length,
225 uint8_t* p_data)
226 {
227 dvbpsi_descriptor_t* p_descriptor;
228 p_descriptor = dvbpsi_NewDescriptor(i_tag, i_length, p_data);
229 if (p_descriptor == NULL)
230 return NULL;
231
232 if (p_es->p_first_descriptor == NULL)
233 p_es->p_first_descriptor = p_descriptor;
234 else
235 {
236 dvbpsi_descriptor_t* p_last_descriptor = p_es->p_first_descriptor;
237 while(p_last_descriptor->p_next != NULL)
238 p_last_descriptor = p_last_descriptor->p_next;
239 p_last_descriptor->p_next = p_descriptor;
240 }
241 return p_descriptor;
242 }
243
244 /* */
dvbpsi_ReInitPMT(dvbpsi_pmt_decoder_t * p_decoder,const bool b_force)245 static void dvbpsi_ReInitPMT(dvbpsi_pmt_decoder_t* p_decoder, const bool b_force)
246 {
247 assert(p_decoder);
248
249 dvbpsi_decoder_reset(DVBPSI_DECODER(p_decoder), b_force);
250
251 /* Force redecoding */
252 if (b_force)
253 {
254 /* Free structures */
255 if (p_decoder->p_building_pmt)
256 dvbpsi_pmt_delete(p_decoder->p_building_pmt);
257 }
258 p_decoder->p_building_pmt = NULL;
259 }
260
dvbpsi_CheckPMT(dvbpsi_t * p_dvbpsi,dvbpsi_psi_section_t * p_section)261 static bool dvbpsi_CheckPMT(dvbpsi_t *p_dvbpsi, dvbpsi_psi_section_t *p_section)
262 {
263 bool b_reinit = false;
264 assert(p_dvbpsi->p_decoder);
265
266 dvbpsi_pmt_decoder_t* p_pmt_decoder;
267 p_pmt_decoder = (dvbpsi_pmt_decoder_t *)p_dvbpsi->p_decoder;
268
269 if (p_pmt_decoder->p_building_pmt->i_version != p_section->i_version)
270 {
271 /* version_number */
272 dvbpsi_error(p_dvbpsi, "PMT decoder",
273 "'version_number' differs"
274 " whereas no discontinuity has occured");
275 b_reinit = true;
276 }
277 else if (p_pmt_decoder->i_last_section_number != p_section->i_last_number)
278 {
279 /* last_section_number */
280 dvbpsi_error(p_dvbpsi, "PMT decoder",
281 "'last_section_number' differs"
282 " whereas no discontinuity has occured");
283 b_reinit = true;
284 }
285
286 return b_reinit;
287 }
288
dvbpsi_AddSectionPMT(dvbpsi_t * p_dvbpsi,dvbpsi_pmt_decoder_t * p_pmt_decoder,dvbpsi_psi_section_t * p_section)289 static bool dvbpsi_AddSectionPMT(dvbpsi_t *p_dvbpsi, dvbpsi_pmt_decoder_t *p_pmt_decoder,
290 dvbpsi_psi_section_t* p_section)
291 {
292 assert(p_dvbpsi);
293 assert(p_pmt_decoder);
294 assert(p_section);
295
296 /* Initialize the structures if it's the first section received */
297 if (p_pmt_decoder->p_building_pmt == NULL)
298 {
299 p_pmt_decoder->p_building_pmt = dvbpsi_pmt_new(p_pmt_decoder->i_program_number,
300 p_section->i_version, p_section->b_current_next,
301 ((uint16_t)(p_section->p_payload_start[0] & 0x1f) << 8)
302 | p_section->p_payload_start[1]);
303 if (p_pmt_decoder->p_building_pmt == NULL)
304 return false;
305
306 p_pmt_decoder->i_last_section_number = p_section->i_last_number;
307 }
308
309 /* Add to linked list of sections */
310 if (dvbpsi_decoder_psi_section_add(DVBPSI_DECODER(p_pmt_decoder), p_section))
311 dvbpsi_debug(p_dvbpsi, "PMT decoder", "overwrite section number %d",
312 p_section->i_number);
313
314 return true;
315 }
316
317 /*****************************************************************************
318 * dvbpsi_GatherPMTSections
319 *****************************************************************************
320 * Callback for the PSI decoder.
321 *****************************************************************************/
dvbpsi_pmt_sections_gather(dvbpsi_t * p_dvbpsi,dvbpsi_psi_section_t * p_section)322 void dvbpsi_pmt_sections_gather(dvbpsi_t *p_dvbpsi, dvbpsi_psi_section_t* p_section)
323 {
324 assert(p_dvbpsi);
325 assert(p_dvbpsi->p_decoder);
326
327 if (!dvbpsi_CheckPSISection(p_dvbpsi, p_section, 0x02, "PMT decoder"))
328 {
329 dvbpsi_DeletePSISections(p_section);
330 return;
331 }
332
333 /* */
334 dvbpsi_pmt_decoder_t* p_pmt_decoder = (dvbpsi_pmt_decoder_t*)p_dvbpsi->p_decoder;
335 assert(p_pmt_decoder);
336
337 /* We have a valid PMT section */
338 if (p_pmt_decoder->i_program_number != p_section->i_extension)
339 {
340 /* Invalid program_number */
341 dvbpsi_debug(p_dvbpsi, "PMT decoder", "ignoring section %d not belonging to 'program_number' %d",
342 p_section->i_extension, p_pmt_decoder->i_program_number);
343 dvbpsi_DeletePSISections(p_section);
344 return;
345 }
346
347 /* TS discontinuity check */
348 if (p_pmt_decoder->b_discontinuity)
349 {
350 dvbpsi_ReInitPMT(p_pmt_decoder, true);
351 p_pmt_decoder->b_discontinuity = false;
352 }
353 else
354 {
355 /* Perform some few sanity checks */
356 if (p_pmt_decoder->p_building_pmt)
357 {
358 if (dvbpsi_CheckPMT(p_dvbpsi, p_section))
359 dvbpsi_ReInitPMT(p_pmt_decoder, true);
360 }
361 else
362 {
363 if( (p_pmt_decoder->b_current_valid)
364 && (p_pmt_decoder->current_pmt.i_version == p_section->i_version)
365 && (p_pmt_decoder->current_pmt.b_current_next ==
366 p_section->b_current_next))
367 {
368 /* Don't decode since this version is already decoded */
369 dvbpsi_debug(p_dvbpsi, "PMT decoder",
370 "ignoring already decoded section %d",
371 p_section->i_number);
372 dvbpsi_DeletePSISections(p_section);
373 return;
374 }
375 }
376 }
377
378 /* Add section to PMT */
379 if (!dvbpsi_AddSectionPMT(p_dvbpsi, p_pmt_decoder, p_section))
380 {
381 dvbpsi_error(p_dvbpsi, "PMT decoder", "failed decoding section %d",
382 p_section->i_number);
383 dvbpsi_DeletePSISections(p_section);
384 return;
385 }
386
387 if (dvbpsi_decoder_psi_sections_completed(DVBPSI_DECODER(p_pmt_decoder)))
388 {
389 assert(p_pmt_decoder->pf_pmt_callback);
390
391 /* Save the current information */
392 p_pmt_decoder->current_pmt = *p_pmt_decoder->p_building_pmt;
393 p_pmt_decoder->b_current_valid = true;
394 /* Decode the sections */
395 dvbpsi_pmt_sections_decode(p_pmt_decoder->p_building_pmt,
396 p_pmt_decoder->p_sections);
397 /* signal the new PMT */
398 p_pmt_decoder->pf_pmt_callback(p_pmt_decoder->p_cb_data,
399 p_pmt_decoder->p_building_pmt);
400 /* Delete sections and Reinitialize the structures */
401 dvbpsi_ReInitPMT(p_pmt_decoder, false);
402 assert(p_pmt_decoder->p_sections == NULL);
403 }
404 }
405
406 /*****************************************************************************
407 * dvbpsi_pmt_sections_decode
408 *****************************************************************************
409 * PMT decoder.
410 *****************************************************************************/
dvbpsi_pmt_sections_decode(dvbpsi_pmt_t * p_pmt,dvbpsi_psi_section_t * p_section)411 void dvbpsi_pmt_sections_decode(dvbpsi_pmt_t* p_pmt,
412 dvbpsi_psi_section_t* p_section)
413 {
414 uint8_t* p_byte, * p_end;
415
416 while (p_section)
417 {
418 /* - PMT descriptors */
419 p_byte = p_section->p_payload_start + 4;
420 p_end = p_byte + ( ((uint16_t)(p_section->p_payload_start[2] & 0x0f) << 8)
421 | p_section->p_payload_start[3]);
422 while (p_byte + 2 <= p_end)
423 {
424 uint8_t i_tag = p_byte[0];
425 uint8_t i_length = p_byte[1];
426 if (i_length + 2 <= p_end - p_byte)
427 dvbpsi_pmt_descriptor_add(p_pmt, i_tag, i_length, p_byte + 2);
428 p_byte += 2 + i_length;
429 }
430
431 /* - ESs */
432 for (p_byte = p_end; p_byte + 5 <= p_section->p_payload_end;)
433 {
434 uint8_t i_type = p_byte[0];
435 uint16_t i_pid = ((uint16_t)(p_byte[1] & 0x1f) << 8) | p_byte[2];
436 uint16_t i_es_length = ((uint16_t)(p_byte[3] & 0x0f) << 8) | p_byte[4];
437 dvbpsi_pmt_es_t* p_es = dvbpsi_pmt_es_add(p_pmt, i_type, i_pid);
438 /* - ES descriptors */
439 p_byte += 5;
440 p_end = p_byte + i_es_length;
441 if (p_end > p_section->p_payload_end)
442 {
443 p_end = p_section->p_payload_end;
444 }
445 while (p_byte + 2 <= p_end)
446 {
447 uint8_t i_tag = p_byte[0];
448 uint8_t i_length = p_byte[1];
449 if (i_length + 2 <= p_end - p_byte)
450 dvbpsi_pmt_es_descriptor_add(p_es, i_tag, i_length, p_byte + 2);
451 p_byte += 2 + i_length;
452 }
453 }
454 p_section = p_section->p_next;
455 }
456 }
457
458 /*****************************************************************************
459 * dvbpsi_pmt_sections_generate
460 *****************************************************************************
461 * Generate PMT sections based on the dvbpsi_pmt_t structure.
462 *****************************************************************************/
dvbpsi_pmt_sections_generate(dvbpsi_t * p_dvbpsi,dvbpsi_pmt_t * p_pmt)463 dvbpsi_psi_section_t* dvbpsi_pmt_sections_generate(dvbpsi_t *p_dvbpsi, dvbpsi_pmt_t* p_pmt)
464 {
465 dvbpsi_psi_section_t* p_result = dvbpsi_NewPSISection(1024);
466 dvbpsi_psi_section_t* p_current = p_result;
467 dvbpsi_psi_section_t* p_prev;
468 dvbpsi_descriptor_t* p_descriptor = p_pmt->p_first_descriptor;
469 dvbpsi_pmt_es_t* p_es = p_pmt->p_first_es;
470 uint16_t i_info_length;
471
472 p_current->i_table_id = 0x02;
473 p_current->b_syntax_indicator = true;
474 p_current->b_private_indicator = false;
475 p_current->i_length = 13; /* header + CRC_32 */
476 p_current->i_extension = p_pmt->i_program_number;
477 p_current->i_version = p_pmt->i_version;
478 p_current->b_current_next = p_pmt->b_current_next;
479 p_current->i_number = 0;
480 p_current->p_payload_end += 12; /* just after the header */
481 p_current->p_payload_start = p_current->p_data + 8;
482
483 /* PCR_PID */
484 p_current->p_data[8] = (p_pmt->i_pcr_pid >> 8) | 0xe0;
485 p_current->p_data[9] = p_pmt->i_pcr_pid;
486
487 /* PMT descriptors */
488 while (p_descriptor != NULL)
489 {
490 /* New section if needed */
491 /* written_data_length + descriptor_length + 2 > 1024 - CRC_32_length */
492 if ((p_current->p_payload_end - p_current->p_data)
493 + p_descriptor->i_length > 1018)
494 {
495 /* program_info_length */
496 i_info_length = (p_current->p_payload_end - p_current->p_data) - 12;
497 p_current->p_data[10] = (i_info_length >> 8) | 0xf0;
498 p_current->p_data[11] = i_info_length;
499
500 p_prev = p_current;
501 p_current = dvbpsi_NewPSISection(1024);
502 p_prev->p_next = p_current;
503
504 p_current->i_table_id = 0x02;
505 p_current->b_syntax_indicator = true;
506 p_current->b_private_indicator = false;
507 p_current->i_length = 13; /* header + CRC_32 */
508 p_current->i_extension = p_pmt->i_program_number;
509 p_current->i_version = p_pmt->i_version;
510 p_current->b_current_next = p_pmt->b_current_next;
511 p_current->i_number = p_prev->i_number + 1;
512 p_current->p_payload_end += 12; /* just after the header */
513 p_current->p_payload_start = p_current->p_data + 8;
514
515 /* PCR_PID */
516 p_current->p_data[8] = (p_pmt->i_pcr_pid >> 8) | 0xe0;
517 p_current->p_data[9] = p_pmt->i_pcr_pid;
518 }
519
520 /* p_payload_end is where the descriptor begins */
521 p_current->p_payload_end[0] = p_descriptor->i_tag;
522 p_current->p_payload_end[1] = p_descriptor->i_length;
523 memcpy(p_current->p_payload_end + 2,
524 p_descriptor->p_data,
525 p_descriptor->i_length);
526
527 /* Increase length by descriptor_length + 2 */
528 p_current->p_payload_end += p_descriptor->i_length + 2;
529 p_current->i_length += p_descriptor->i_length + 2;
530
531 p_descriptor = p_descriptor->p_next;
532 }
533
534 /* program_info_length */
535 i_info_length = (p_current->p_payload_end - p_current->p_data) - 12;
536 p_current->p_data[10] = (i_info_length >> 8) | 0xf0;
537 p_current->p_data[11] = i_info_length;
538
539 /* PMT ESs */
540 while (p_es != NULL)
541 {
542 uint8_t* p_es_start = p_current->p_payload_end;
543 uint16_t i_es_length = 5;
544
545 /* Can the current section carry all the descriptors ? */
546 p_descriptor = p_es->p_first_descriptor;
547 while( (p_descriptor != NULL)
548 && ((p_es_start - p_current->p_data) + i_es_length <= 1020))
549 {
550 i_es_length += p_descriptor->i_length + 2;
551 p_descriptor = p_descriptor->p_next;
552 }
553
554 /* If _no_ and the current section isn't empty and an empty section
555 may carry one more descriptor
556 then create a new section */
557 if( (p_descriptor != NULL)
558 && (p_es_start - p_current->p_data != 12)
559 && (i_es_length <= 1008))
560 {
561 /* will put more descriptors in an empty section */
562 dvbpsi_debug(p_dvbpsi, "PMT generator",
563 "create a new section to carry more ES descriptors");
564
565 p_prev = p_current;
566 p_current = dvbpsi_NewPSISection(1024);
567 p_prev->p_next = p_current;
568
569 p_current->i_table_id = 0x02;
570 p_current->b_syntax_indicator = true;
571 p_current->b_private_indicator = false;
572 p_current->i_length = 13; /* header + CRC_32 */
573 p_current->i_extension = p_pmt->i_program_number;
574 p_current->i_version = p_pmt->i_version;
575 p_current->b_current_next = p_pmt->b_current_next;
576 p_current->i_number = p_prev->i_number + 1;
577 p_current->p_payload_end += 12; /* just after the header */
578 p_current->p_payload_start = p_current->p_data + 8;
579
580 /* PCR_PID */
581 p_current->p_data[8] = (p_pmt->i_pcr_pid >> 8) | 0xe0;
582 p_current->p_data[9] = p_pmt->i_pcr_pid;
583
584 /* program_info_length */
585 i_info_length = 0;
586 p_current->p_data[10] = 0xf0;
587 p_current->p_data[11] = 0x00;
588
589 p_es_start = p_current->p_payload_end;
590 }
591
592 /* p_es_start is where the ES begins */
593 p_es_start[0] = p_es->i_type;
594 p_es_start[1] = (p_es->i_pid >> 8) | 0xe0;
595 p_es_start[2] = p_es->i_pid;
596
597 /* Increase the length by 5 */
598 p_current->p_payload_end += 5;
599 p_current->i_length += 5;
600
601 /* ES descriptors */
602 p_descriptor = p_es->p_first_descriptor;
603 while( (p_descriptor != NULL)
604 && ( (p_current->p_payload_end - p_current->p_data)
605 + p_descriptor->i_length <= 1018))
606 {
607 /* p_payload_end is where the descriptor begins */
608 p_current->p_payload_end[0] = p_descriptor->i_tag;
609 p_current->p_payload_end[1] = p_descriptor->i_length;
610 memcpy(p_current->p_payload_end + 2,
611 p_descriptor->p_data,
612 p_descriptor->i_length);
613
614 /* Increase length by descriptor_length + 2 */
615 p_current->p_payload_end += p_descriptor->i_length + 2;
616 p_current->i_length += p_descriptor->i_length + 2;
617
618 p_descriptor = p_descriptor->p_next;
619 }
620
621 if (p_descriptor != NULL)
622 dvbpsi_error(p_dvbpsi, "PMT generator", "unable to carry all the ES descriptors");
623
624 /* ES_info_length */
625 i_es_length = p_current->p_payload_end - p_es_start - 5;
626 p_es_start[3] = (i_es_length >> 8) | 0xf0;
627 p_es_start[4] = i_es_length;
628
629 p_es = p_es->p_next;
630 }
631
632 /* Finalization */
633 p_prev = p_result;
634 while (p_prev != NULL)
635 {
636 p_prev->i_last_number = p_current->i_number;
637 dvbpsi_BuildPSISection(p_dvbpsi, p_prev);
638 p_prev = p_prev->p_next;
639 }
640
641 return p_result;
642 }
643