1 /*****************************************************************************
2 * sis.c: SIS decoder/generator
3 *----------------------------------------------------------------------------
4 * Copyright (C) 2010-2011 VideoLAN
5 * $Id:$
6 *
7 * Authors: Jean-Paul Saman <jpsaman@videolan.org>
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 *
23 *----------------------------------------------------------------------------
24 *
25 *****************************************************************************/
26
27 #include "config.h"
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <stdbool.h>
32 #include <string.h>
33
34 #if defined(HAVE_INTTYPES_H)
35 #include <inttypes.h>
36 #elif defined(HAVE_STDINT_H)
37 #include <stdint.h>
38 #endif
39
40 #include <assert.h>
41
42 #include "../dvbpsi.h"
43 #include "../dvbpsi_private.h"
44 #include "../psi.h"
45 #include "../descriptor.h"
46 #include "../demux.h"
47
48 #include "sis.h"
49 #include "sis_private.h"
50
51 /*****************************************************************************
52 * dvbpsi_sis_attach
53 *****************************************************************************
54 * Initialize a SIS subtable decoder.
55 *****************************************************************************/
dvbpsi_sis_attach(dvbpsi_t * p_dvbpsi,uint8_t i_table_id,uint16_t i_extension,dvbpsi_sis_callback pf_callback,void * p_cb_data)56 bool dvbpsi_sis_attach(dvbpsi_t *p_dvbpsi, uint8_t i_table_id, uint16_t i_extension,
57 dvbpsi_sis_callback pf_callback, void* p_cb_data)
58 {
59 assert(p_dvbpsi);
60 assert(p_dvbpsi->p_decoder);
61
62 dvbpsi_demux_t* p_demux = (dvbpsi_demux_t*)p_dvbpsi->p_decoder;
63
64 i_extension = 0;
65
66 if (dvbpsi_demuxGetSubDec(p_demux, i_table_id, i_extension))
67 {
68 dvbpsi_error(p_dvbpsi, "SIS decoder",
69 "Already a decoder for (table_id == 0x%02x,"
70 "extension == 0x%02x)",
71 i_table_id, i_extension);
72 return false;
73 }
74
75 dvbpsi_sis_decoder_t* p_sis_decoder;
76 p_sis_decoder = (dvbpsi_sis_decoder_t*) dvbpsi_decoder_new(NULL,
77 0, true, sizeof(dvbpsi_sis_decoder_t));
78 if (p_sis_decoder == NULL)
79 return false;
80
81 /* subtable decoder configuration */
82 dvbpsi_demux_subdec_t* p_subdec;
83 p_subdec = dvbpsi_NewDemuxSubDecoder(i_table_id, i_extension, dvbpsi_sis_detach,
84 dvbpsi_sis_sections_gather, DVBPSI_DECODER(p_sis_decoder));
85 if (p_subdec == NULL)
86 {
87 dvbpsi_decoder_delete(DVBPSI_DECODER(p_sis_decoder));
88 return false;
89 }
90
91 /* Attach the subtable decoder to the demux */
92 dvbpsi_AttachDemuxSubDecoder(p_demux, p_subdec);
93
94 /* SIS decoder information */
95 p_sis_decoder->pf_sis_callback = pf_callback;
96 p_sis_decoder->p_cb_data = p_cb_data;
97 p_sis_decoder->p_building_sis = NULL;
98
99 return true;
100 }
101
102 /*****************************************************************************
103 * dvbpsi_sis_detach
104 *****************************************************************************
105 * Close a SIS decoder.
106 *****************************************************************************/
dvbpsi_sis_detach(dvbpsi_t * p_dvbpsi,uint8_t i_table_id,uint16_t i_extension)107 void dvbpsi_sis_detach(dvbpsi_t *p_dvbpsi, uint8_t i_table_id, uint16_t i_extension)
108 {
109 assert(p_dvbpsi);
110 assert(p_dvbpsi->p_decoder);
111
112 dvbpsi_demux_t *p_demux = (dvbpsi_demux_t *) p_dvbpsi->p_decoder;
113
114 i_extension = 0;
115 dvbpsi_demux_subdec_t* p_subdec;
116 p_subdec = dvbpsi_demuxGetSubDec(p_demux, i_table_id, i_extension);
117 if (p_subdec == NULL)
118 {
119 dvbpsi_error(p_dvbpsi, "SIS Decoder",
120 "No such SIS decoder (table_id == 0x%02x,"
121 "extension == 0x%02x)",
122 i_table_id, i_extension);
123 return;
124 }
125
126 assert(p_subdec->p_decoder);
127
128 dvbpsi_sis_decoder_t* p_sis_decoder;
129 p_sis_decoder = (dvbpsi_sis_decoder_t*)p_subdec->p_decoder;
130 if (p_sis_decoder->p_building_sis)
131 dvbpsi_sis_delete(p_sis_decoder->p_building_sis);
132 p_sis_decoder->p_building_sis = NULL;
133
134 dvbpsi_DetachDemuxSubDecoder(p_demux, p_subdec);
135 dvbpsi_DeleteDemuxSubDecoder(p_subdec);
136 }
137
138 /*****************************************************************************
139 * dvbpsi_sis_init
140 *****************************************************************************
141 * Initialize a pre-allocated dvbpsi_sis_t structure.
142 *****************************************************************************/
dvbpsi_sis_init(dvbpsi_sis_t * p_sis,uint8_t i_table_id,uint16_t i_extension,uint8_t i_version,bool b_current_next,uint8_t i_protocol_version)143 void dvbpsi_sis_init(dvbpsi_sis_t *p_sis, uint8_t i_table_id, uint16_t i_extension,
144 uint8_t i_version, bool b_current_next, uint8_t i_protocol_version)
145 {
146 p_sis->i_table_id = i_table_id;
147 p_sis->i_extension = i_extension;
148
149 p_sis->i_version = i_version;
150 p_sis->b_current_next = b_current_next;
151
152 assert(i_protocol_version == 0);
153 p_sis->i_protocol_version = 0; /* must be 0 */
154
155 /* encryption */
156 p_sis->b_encrypted_packet = false;
157 p_sis->i_encryption_algorithm = 0;
158
159 p_sis->i_pts_adjustment = (uint64_t)0;
160 p_sis->cw_index = 0;
161
162 /* splice command */
163 p_sis->i_splice_command_length = 0;
164 p_sis->i_splice_command_type = 0x00;
165
166 /* FIXME: splice_info_section comes here */
167
168 /* descriptors */
169 p_sis->i_descriptors_length = 0;
170 p_sis->p_first_descriptor = NULL;
171
172 /* FIXME: alignment stuffing */
173
174 p_sis->i_ecrc = 0;
175 }
176
177 /*****************************************************************************
178 * dvbpsi_sis_new
179 *****************************************************************************
180 * Allocate and Initialize a new dvbpsi_sis_t structure.
181 *****************************************************************************/
dvbpsi_sis_new(uint8_t i_table_id,uint16_t i_extension,uint8_t i_version,bool b_current_next,uint8_t i_protocol_version)182 dvbpsi_sis_t* dvbpsi_sis_new(uint8_t i_table_id, uint16_t i_extension, uint8_t i_version,
183 bool b_current_next, uint8_t i_protocol_version)
184 {
185 dvbpsi_sis_t* p_sis = (dvbpsi_sis_t*)malloc(sizeof(dvbpsi_sis_t));
186 if (p_sis != NULL)
187 dvbpsi_sis_init(p_sis, i_table_id, i_extension, i_version,
188 b_current_next, i_protocol_version);
189 return p_sis;
190 }
191
192 /*****************************************************************************
193 * dvbpsi_sis_empty
194 *****************************************************************************
195 * Clean a dvbpsi_sis_t structure.
196 *****************************************************************************/
dvbpsi_sis_empty(dvbpsi_sis_t * p_sis)197 void dvbpsi_sis_empty(dvbpsi_sis_t* p_sis)
198 {
199 /* FIXME: free splice_command_sections */
200
201 dvbpsi_DeleteDescriptors(p_sis->p_first_descriptor);
202 p_sis->p_first_descriptor = NULL;
203
204 /* FIXME: free alignment stuffing */
205 }
206
207 /*****************************************************************************
208 * dvbpsi_sis_delete
209 *****************************************************************************
210 * Clean and Delete a dvbpsi_sis_t structure.
211 *****************************************************************************/
dvbpsi_sis_delete(dvbpsi_sis_t * p_sis)212 void dvbpsi_sis_delete(dvbpsi_sis_t *p_sis)
213 {
214 if (p_sis)
215 dvbpsi_sis_empty(p_sis);
216 free(p_sis);
217 }
218
219 /*****************************************************************************
220 * dvbpsi_sis_descriptor_add
221 *****************************************************************************
222 * Add a descriptor in the SIS service description.
223 *****************************************************************************/
dvbpsi_sis_descriptor_add(dvbpsi_sis_t * p_sis,uint8_t i_tag,uint8_t i_length,uint8_t * p_data)224 dvbpsi_descriptor_t *dvbpsi_sis_descriptor_add(dvbpsi_sis_t *p_sis,
225 uint8_t i_tag, uint8_t i_length,
226 uint8_t *p_data)
227 {
228 dvbpsi_descriptor_t * p_descriptor;
229 p_descriptor = dvbpsi_NewDescriptor(i_tag, i_length, p_data);
230 if (p_descriptor == NULL)
231 return NULL;
232
233 p_sis->p_first_descriptor = dvbpsi_AddDescriptor(p_sis->p_first_descriptor,
234 p_descriptor);
235 assert(p_sis->p_first_descriptor);
236 if (p_sis->p_first_descriptor == NULL)
237 return NULL;
238
239 return p_descriptor;
240 }
241
242 /* */
dvbpsi_ReInitSIS(dvbpsi_sis_decoder_t * p_decoder,const bool b_force)243 static void dvbpsi_ReInitSIS(dvbpsi_sis_decoder_t* p_decoder, const bool b_force)
244 {
245 assert(p_decoder);
246
247 dvbpsi_decoder_reset(DVBPSI_DECODER(p_decoder), b_force);
248
249 /* Force redecoding */
250 if (b_force)
251 {
252 /* Free structures */
253 if (p_decoder->p_building_sis)
254 dvbpsi_sis_delete(p_decoder->p_building_sis);
255 }
256 p_decoder->p_building_sis = NULL;
257 }
258
dvbpsi_CheckSIS(dvbpsi_t * p_dvbpsi,dvbpsi_sis_decoder_t * p_sis_decoder,dvbpsi_psi_section_t * p_section)259 static bool dvbpsi_CheckSIS(dvbpsi_t *p_dvbpsi, dvbpsi_sis_decoder_t* p_sis_decoder,
260 dvbpsi_psi_section_t *p_section)
261 {
262 bool b_reinit = false;
263 assert(p_dvbpsi);
264 assert(p_sis_decoder);
265
266 if (p_sis_decoder->p_building_sis->i_protocol_version != 0)
267 {
268 dvbpsi_error(p_dvbpsi, "SIS decoder",
269 "'protocol_version' differs"
270 " while no discontinuity has occured");
271 b_reinit = true;
272 }
273 else if (p_sis_decoder->p_building_sis->i_extension != p_section->i_extension)
274 {
275 dvbpsi_error(p_dvbpsi, "SIS decoder",
276 "'transport_stream_id' differs"
277 " whereas no discontinuity has occured");
278 b_reinit = true;
279 }
280 else if (p_sis_decoder->p_building_sis->i_version != p_section->i_version)
281 {
282 /* version_number */
283 dvbpsi_error(p_dvbpsi, "SIS decoder",
284 "'version_number' differs"
285 " whereas no discontinuity has occured");
286 b_reinit = true;
287 }
288 else if (p_sis_decoder->i_last_section_number != p_section->i_last_number)
289 {
290 /* last_section_number */
291 dvbpsi_error(p_dvbpsi, "SIS decoder",
292 "'last_section_number' differs"
293 " whereas no discontinuity has occured");
294 b_reinit = true;
295 }
296
297 return b_reinit;
298 }
299
dvbpsi_AddSectionSIS(dvbpsi_t * p_dvbpsi,dvbpsi_sis_decoder_t * p_sis_decoder,dvbpsi_psi_section_t * p_section)300 static bool dvbpsi_AddSectionSIS(dvbpsi_t *p_dvbpsi, dvbpsi_sis_decoder_t *p_sis_decoder,
301 dvbpsi_psi_section_t* p_section)
302 {
303 assert(p_dvbpsi);
304 assert(p_sis_decoder);
305 assert(p_section);
306
307 /* Initialize the structures if it's the first section received */
308 if (!p_sis_decoder->p_building_sis)
309 {
310 p_sis_decoder->p_building_sis = dvbpsi_sis_new(
311 p_section->i_table_id, p_section->i_extension,
312 p_section->i_version, p_section->b_current_next, 0);
313 if (p_sis_decoder->p_building_sis == NULL)
314 return false;
315 p_sis_decoder->i_last_section_number = p_section->i_last_number;
316 }
317
318 /* Add to linked list of sections */
319 if (dvbpsi_decoder_psi_section_add(DVBPSI_DECODER(p_sis_decoder), p_section))
320 dvbpsi_debug(p_dvbpsi, "SDT decoder", "overwrite section number %d",
321 p_section->i_number);
322
323 return true;
324 }
325
326 /*****************************************************************************
327 * dvbpsi_sis_sections_gather
328 *****************************************************************************
329 * Callback for the subtable demultiplexor.
330 *****************************************************************************/
dvbpsi_sis_sections_gather(dvbpsi_t * p_dvbpsi,dvbpsi_decoder_t * p_decoder,dvbpsi_psi_section_t * p_section)331 void dvbpsi_sis_sections_gather(dvbpsi_t *p_dvbpsi,
332 dvbpsi_decoder_t *p_decoder,
333 dvbpsi_psi_section_t * p_section)
334 {
335 assert(p_dvbpsi);
336 assert(p_dvbpsi->p_decoder);
337
338 if (!dvbpsi_CheckPSISection(p_dvbpsi, p_section, 0xFC, "SIS decoder"))
339 {
340 dvbpsi_DeletePSISections(p_section);
341 return;
342 }
343
344 /* */
345 dvbpsi_demux_t *p_demux = (dvbpsi_demux_t *) p_dvbpsi->p_decoder;
346 dvbpsi_sis_decoder_t * p_sis_decoder = (dvbpsi_sis_decoder_t*)p_decoder;
347
348 if (p_section->b_private_indicator)
349 {
350 /* Invalid private_syntax_indicator */
351 dvbpsi_error(p_dvbpsi, "SIS decoder",
352 "invalid private section (private_syntax_indicator != false)");
353 dvbpsi_DeletePSISections(p_section);
354 return;
355 }
356
357 /* TS discontinuity check */
358 if (p_demux->b_discontinuity)
359 {
360 dvbpsi_ReInitSIS(p_sis_decoder, true);
361 p_sis_decoder->b_discontinuity = false;
362 p_demux->b_discontinuity = false;
363 }
364 else
365 {
366 /* Perform a few sanity checks */
367 if (p_sis_decoder->p_building_sis)
368 {
369 if (dvbpsi_CheckSIS(p_dvbpsi, p_sis_decoder, p_section))
370 dvbpsi_ReInitSIS(p_sis_decoder, true);
371 }
372 else
373 {
374 if( (p_sis_decoder->b_current_valid)
375 && (p_sis_decoder->current_sis.i_version == p_section->i_version)
376 && (p_sis_decoder->current_sis.b_current_next == p_section->b_current_next))
377 {
378 /* Don't decode since this version is already decoded */
379 dvbpsi_debug(p_dvbpsi, "SIT decoder",
380 "ignoring already decoded section %d",
381 p_section->i_number);
382 dvbpsi_DeletePSISections(p_section);
383 return;
384 }
385 }
386 }
387
388 /* Add section to SIS */
389 if (!dvbpsi_AddSectionSIS(p_dvbpsi, p_sis_decoder, p_section))
390 {
391 dvbpsi_error(p_dvbpsi, "SIS decoder", "failed decoding section %d",
392 p_section->i_number);
393 dvbpsi_DeletePSISections(p_section);
394 return;
395 }
396
397 /* Check if we have all the sections */
398 if (dvbpsi_decoder_psi_sections_completed(DVBPSI_DECODER(p_sis_decoder)))
399 {
400 assert(p_sis_decoder->pf_sis_callback);
401
402 /* Save the current information */
403 p_sis_decoder->current_sis = *p_sis_decoder->p_building_sis;
404 p_sis_decoder->b_current_valid = true;
405 /* Decode the sections */
406 dvbpsi_sis_sections_decode(p_dvbpsi, p_sis_decoder->p_building_sis,
407 p_sis_decoder->p_sections);
408 /* signal the new SDT */
409 p_sis_decoder->pf_sis_callback(p_sis_decoder->p_cb_data,
410 p_sis_decoder->p_building_sis);
411 /* Delete sections and Reinitialize the structures */
412 dvbpsi_ReInitSIS(p_sis_decoder, false);
413 assert(p_sis_decoder->p_sections == NULL);
414 }
415 }
416
417 /*****************************************************************************
418 * dvbpsi_sis_sections_decode
419 *****************************************************************************
420 * SIS decoder.
421 *****************************************************************************/
dvbpsi_sis_sections_decode(dvbpsi_t * p_dvbpsi,dvbpsi_sis_t * p_sis,dvbpsi_psi_section_t * p_section)422 void dvbpsi_sis_sections_decode(dvbpsi_t* p_dvbpsi, dvbpsi_sis_t* p_sis,
423 dvbpsi_psi_section_t* p_section)
424 {
425 uint8_t *p_byte, *p_end;
426
427 while (p_section)
428 {
429 for (p_byte = p_section->p_payload_start + 3;
430 p_byte < p_section->p_payload_end; )
431 {
432 p_sis->i_protocol_version = p_byte[3];
433 p_sis->b_encrypted_packet = ((p_byte[4] & 0x80) == 0x80);
434 /* NOTE: cannot handle encrypted packet */
435 assert(p_sis->b_encrypted_packet);
436 p_sis->i_encryption_algorithm = ((p_byte[4] & 0x7E) >> 1);
437 p_sis->i_pts_adjustment = ((((uint64_t)p_byte[4] & 0x01) << 32) |
438 ((uint64_t)p_byte[5] << 24) |
439 ((uint64_t)p_byte[6] << 16) |
440 ((uint64_t)p_byte[7] << 8) |
441 (uint64_t)p_byte[8]);
442 p_sis->cw_index = p_byte[9];
443 p_sis->i_splice_command_length = ((p_byte[11] & 0x0F) << 8) | p_byte[12];
444 p_sis->i_splice_command_type = p_byte[13];
445
446 uint32_t i_splice_command_length = p_sis->i_splice_command_length;
447 if (p_sis->i_splice_command_length == 0xfff)
448 {
449 /* FIXME: size 0xfff of splice_command_section is undefined */
450 assert(p_sis->i_splice_command_length != 0xfff);
451 }
452
453 /* FIXME: handle splice_command_sections */
454 switch(p_sis->i_splice_command_type)
455 {
456 case 0x00: /* splice_null */
457 case 0x04: /* splice_schedule */
458 case 0x05: /* splice_insert */
459 case 0x06: /* time_signal */
460 case 0x07: /* bandwidth_reservation */
461 break;
462 default:
463 dvbpsi_error(p_dvbpsi, "SIS decoder", "invalid SIS Command found");
464 break;
465 }
466
467 /* Service descriptors */
468 uint8_t *p_desc = p_byte + 13 + i_splice_command_length;
469 p_sis->i_descriptors_length = (p_desc[0] << 8) | p_desc[1];
470
471 p_desc += 1;
472 p_end = p_desc + p_sis->i_descriptors_length;
473 if (p_end > p_section->p_payload_end) break;
474
475 while (p_desc + 2 <= p_end)
476 {
477 uint8_t i_tag = p_desc[0];
478 uint8_t i_length = p_desc[1];
479 if ((i_length <= 254) &&
480 (i_length + 2 <= p_end - p_desc))
481 dvbpsi_sis_descriptor_add(p_sis, i_tag, i_length, p_desc + 2);
482 p_desc += 2 + i_length;
483 }
484
485 if (p_sis->b_encrypted_packet)
486 {
487 /* FIXME: Currently ignored */
488 /* Calculate crc32 over decoded
489 * p_sis->i_splice_command_type till p_sis->i_ecrc,
490 * the result should be exactly p_sis->i_ecrc and indicates
491 * a successfull decryption.
492 */
493 p_desc += 4; /* E CRC 32 */
494 }
495
496 /* point to next section */
497 p_byte = p_desc + 4 /* CRC 32 */;
498 }
499
500 p_section = p_section->p_next;
501 }
502 }
503
504 /*****************************************************************************
505 * dvbpsi_sis_sections_generate
506 *****************************************************************************
507 * Generate SIS sections based on the dvbpsi_sis_t structure.
508 *****************************************************************************/
dvbpsi_sis_sections_generate(dvbpsi_t * p_dvbpsi,dvbpsi_sis_t * p_sis)509 dvbpsi_psi_section_t *dvbpsi_sis_sections_generate(dvbpsi_t *p_dvbpsi, dvbpsi_sis_t* p_sis)
510 {
511 dvbpsi_psi_section_t * p_current = dvbpsi_NewPSISection(1024);
512
513 p_current->i_table_id = 0xFC;
514 p_current->b_syntax_indicator = false;
515 p_current->b_private_indicator = false;
516 p_current->i_length = 3; /* header + CRC_32 */
517
518 /* FIXME: looks weird */
519 p_current->p_payload_end += 2; /* just after the header */
520 p_current->p_payload_start = p_current->p_data + 3;
521
522 p_current->p_data[3] = p_sis->i_protocol_version;
523 p_current->p_data[4] = p_sis->b_encrypted_packet ? 0x80 : 0x0;
524 /* NOTE: cannot handle encrypted packet */
525 assert(p_sis->b_encrypted_packet);
526 p_current->p_data[4] |= ((p_sis->i_encryption_algorithm << 1) & 0x7E);
527
528 p_current->p_data[4] |= ((p_sis->i_pts_adjustment & 0x00800) >> 32);
529 p_current->p_data[5] = (p_sis->i_pts_adjustment >> 24);
530 p_current->p_data[6] = (p_sis->i_pts_adjustment >> 16);
531 p_current->p_data[7] = (p_sis->i_pts_adjustment >> 8);
532 p_current->p_data[8] = p_sis->i_pts_adjustment;
533
534 p_current->p_data[9] = p_sis->cw_index;
535 p_current->p_data[11] = 0x00;
536 p_current->p_data[11]|= ((p_sis->i_splice_command_length >> 8) & 0x0F);
537 p_current->p_data[12] = (uint8_t) (p_sis->i_splice_command_length & 0xFF);
538 p_current->p_data[13] = p_sis->i_splice_command_type;
539
540 uint32_t i_desc_start = 13 + p_sis->i_splice_command_length;
541 if (p_sis->i_splice_command_length == 0xfff)
542 {
543 /* FIXME: size 0xfff of splice_command_section is undefined */
544 assert(p_sis->i_splice_command_length != 0xfff);
545 }
546
547 /* FIXME: handle splice_command_sections */
548
549 /* Service descriptors */
550 p_current->p_data[i_desc_start] = (p_sis->i_descriptors_length >> 8);
551 p_current->p_data[i_desc_start+1] = (uint8_t)(p_sis->i_descriptors_length & 0xFF);
552
553 p_current->p_payload_end += (i_desc_start + 1);
554
555 uint32_t i_desc_length = 0;
556
557 dvbpsi_descriptor_t * p_descriptor = p_sis->p_first_descriptor;
558 while ((p_descriptor != NULL) && (p_current->i_length <= 1018))
559 {
560 i_desc_length += p_descriptor->i_length + 2;
561 p_descriptor = p_descriptor->p_next;
562
563 /* p_payload_end is where the descriptor begins */
564 p_current->p_payload_end[0] = p_descriptor->i_tag;
565 p_current->p_payload_end[1] = p_descriptor->i_length;
566 memcpy(p_current->p_payload_end + 2, p_descriptor->p_data, p_descriptor->i_length);
567 /* Increase length by descriptor_length + 2 */
568 p_current->p_payload_end += p_descriptor->i_length + 2;
569 p_current->i_length += p_descriptor->i_length + 2;
570
571 }
572 /* Coding error if this condition is not met */
573 assert( i_desc_length == p_sis->i_descriptors_length);
574
575 /* Finalization */
576 dvbpsi_BuildPSISection(p_dvbpsi, p_current);
577 return p_current;
578 }
579