sis.c   sis.c 
/************************************************************************** *** /************************************************************************** ***
* sis.c: SIS decoder/generator * sis.c: SIS decoder/generator
*------------------------------------------------------------------------- --- *------------------------------------------------------------------------- ---
* Copyright (C) 2010 VideoLAN * Copyright (C) 2010-2011 VideoLAN
* $Id:$ * $Id:$
* *
* Authors: Jean-Paul Saman <jpsaman@videolan.org> * Authors: Jean-Paul Saman <jpsaman@videolan.org>
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either * License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version. * version 2.1 of the License, or (at your option) any later version.
* *
* This library is distributed in the hope that it will be useful, * This library is distributed in the hope that it will be useful,
skipping to change at line 31 skipping to change at line 31
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-130 1 USA * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-130 1 USA
* *
*------------------------------------------------------------------------- --- *------------------------------------------------------------------------- ---
* *
************************************************************************** ***/ ************************************************************************** ***/
#include "config.h" #include "config.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdbool.h>
#include <string.h> #include <string.h>
#if defined(HAVE_INTTYPES_H) #if defined(HAVE_INTTYPES_H)
#include <inttypes.h> #include <inttypes.h>
#elif defined(HAVE_STDINT_H) #elif defined(HAVE_STDINT_H)
#include <stdint.h> #include <stdint.h>
#endif #endif
#include <assert.h> #include <assert.h>
#include "../dvbpsi.h" #include "../dvbpsi.h"
#include "../dvbpsi_private.h" #include "../dvbpsi_private.h"
#include "../psi.h" #include "../psi.h"
#include "../descriptor.h" #include "../descriptor.h"
#include "../demux.h" #include "../demux.h"
#include "sis.h" #include "sis.h"
#include "sis_private.h" #include "sis_private.h"
/************************************************************************** *** /************************************************************************** ***
* dvbpsi_AttachSIS * dvbpsi_sis_attach
************************************************************************** *** ************************************************************************** ***
* Initialize a SIS subtable decoder. * Initialize a SIS subtable decoder.
************************************************************************** ***/ ************************************************************************** ***/
int dvbpsi_AttachSIS(dvbpsi_decoder_t *p_psi_decoder, uint8_t i_table_id, bool dvbpsi_sis_attach(dvbpsi_t *p_dvbpsi, uint8_t i_table_id, uint16_t i_e
uint16_t i_extension, dvbpsi_sis_callback pf_callback, xtension,
void* p_cb_data) dvbpsi_sis_callback pf_callback, void* p_cb_data)
{ {
dvbpsi_demux_t* p_demux = (dvbpsi_demux_t*)p_psi_decoder->p_private_dec assert(p_dvbpsi);
oder; assert(p_dvbpsi->p_decoder);
dvbpsi_demux_subdec_t* p_subdec;
dvbpsi_sis_decoder_t* p_sis_decoder; dvbpsi_demux_t* p_demux = (dvbpsi_demux_t*)p_dvbpsi->p_decoder;
i_extension = 0; i_extension = 0;
if (dvbpsi_demuxGetSubDec(p_demux, i_table_id, i_extension)) if (dvbpsi_demuxGetSubDec(p_demux, i_table_id, i_extension))
{ {
DVBPSI_ERROR_ARG("SIS decoder", dvbpsi_error(p_dvbpsi, "SIS decoder",
"Already a decoder for (table_id == 0x%02x," "Already a decoder for (table_id == 0x%02x,"
"extension == 0x%02x)", "extension == 0x%02x)",
i_table_id, i_extension); i_table_id, i_extension);
return false;
return 1;
} }
p_subdec = (dvbpsi_demux_subdec_t*)malloc(sizeof(dvbpsi_demux_subdec_t) dvbpsi_sis_decoder_t* p_sis_decoder;
); p_sis_decoder = (dvbpsi_sis_decoder_t*) dvbpsi_decoder_new(NULL,
if (p_subdec == NULL) 0, true, sizeof(dvbpsi_sis_dec
{ oder_t));
return 1;
}
p_sis_decoder = (dvbpsi_sis_decoder_t*)malloc(sizeof(dvbpsi_sis_decoder
_t));
if (p_sis_decoder == NULL) if (p_sis_decoder == NULL)
{ return false;
free(p_subdec);
return 1;
}
/* subtable decoder configuration */ /* subtable decoder configuration */
p_subdec->pf_callback = &dvbpsi_GatherSISSections; dvbpsi_demux_subdec_t* p_subdec;
p_subdec->p_cb_data = p_sis_decoder; p_subdec = dvbpsi_NewDemuxSubDecoder(i_table_id, i_extension, dvbpsi_si
p_subdec->i_id = (uint32_t)i_table_id << 16 | (uint32_t)i_extension; s_detach,
p_subdec->pf_detach = dvbpsi_DetachSIS; dvbpsi_sis_sections_gather, DVBPSI
_DECODER(p_sis_decoder));
if (p_subdec == NULL)
{
dvbpsi_decoder_delete(DVBPSI_DECODER(p_sis_decoder));
return false;
}
/* Attach the subtable decoder to the demux */ /* Attach the subtable decoder to the demux */
p_subdec->p_next = p_demux->p_first_subdec; dvbpsi_AttachDemuxSubDecoder(p_demux, p_subdec);
p_demux->p_first_subdec = p_subdec;
/* SIS decoder information */ /* SIS decoder information */
p_sis_decoder->pf_callback = pf_callback; p_sis_decoder->pf_sis_callback = pf_callback;
p_sis_decoder->p_cb_data = p_cb_data; p_sis_decoder->p_cb_data = p_cb_data;
p_sis_decoder->p_building_sis = NULL;
return 0; return true;
} }
/************************************************************************** *** /************************************************************************** ***
* dvbpsi_DetachSIS * dvbpsi_sis_detach
************************************************************************** *** ************************************************************************** ***
* Close a SIS decoder. * Close a SIS decoder.
************************************************************************** ***/ ************************************************************************** ***/
void dvbpsi_DetachSIS(dvbpsi_demux_t * p_demux, uint8_t i_table_id, void dvbpsi_sis_detach(dvbpsi_t *p_dvbpsi, uint8_t i_table_id, uint16_t i_e
uint16_t i_extension) xtension)
{ {
dvbpsi_demux_subdec_t* p_subdec; assert(p_dvbpsi);
dvbpsi_demux_subdec_t** pp_prev_subdec; assert(p_dvbpsi->p_decoder);
dvbpsi_sis_decoder_t* p_sis_decoder;
i_extension = 0; dvbpsi_demux_t *p_demux = (dvbpsi_demux_t *) p_dvbpsi->p_decoder;
i_extension = 0;
dvbpsi_demux_subdec_t* p_subdec;
p_subdec = dvbpsi_demuxGetSubDec(p_demux, i_table_id, i_extension); p_subdec = dvbpsi_demuxGetSubDec(p_demux, i_table_id, i_extension);
if (p_demux == NULL) if (p_demux == NULL)
{ {
DVBPSI_ERROR_ARG("SIS Decoder", dvbpsi_error(p_dvbpsi, "SIS Decoder",
"No such SIS decoder (table_id == 0x%02x," "No such SIS decoder (table_id == 0x%02x,"
"extension == 0x%02x)", "extension == 0x%02x)",
i_table_id, i_extension); i_table_id, i_extension);
return; return;
} }
p_sis_decoder = (dvbpsi_sis_decoder_t*)p_subdec->p_cb_data; assert(p_subdec->p_decoder);
free(p_subdec->p_cb_data);
pp_prev_subdec = &p_demux->p_first_subdec; dvbpsi_sis_decoder_t* p_sis_decoder;
while(*pp_prev_subdec != p_subdec) p_sis_decoder = (dvbpsi_sis_decoder_t*)p_subdec->p_decoder;
pp_prev_subdec = &(*pp_prev_subdec)->p_next; if (p_sis_decoder->p_building_sis)
dvbpsi_sis_delete(p_sis_decoder->p_building_sis);
p_sis_decoder->p_building_sis = NULL;
*pp_prev_subdec = p_subdec->p_next; dvbpsi_DetachDemuxSubDecoder(p_demux, p_subdec);
free(p_subdec); dvbpsi_DeleteDemuxSubDecoder(p_subdec);
} }
/************************************************************************** *** /************************************************************************** ***
* dvbpsi_InitSIS * dvbpsi_sis_init
************************************************************************** *** ************************************************************************** ***
* Initialize a pre-allocated dvbpsi_sis_t structure. * Initialize a pre-allocated dvbpsi_sis_t structure.
************************************************************************** ***/ ************************************************************************** ***/
void dvbpsi_InitSIS(dvbpsi_sis_t *p_sis, uint8_t i_protocol_version) void dvbpsi_sis_init(dvbpsi_sis_t *p_sis, uint8_t i_table_id, uint16_t i_ex
tension,
uint8_t i_version, bool b_current_next, uint8_t i_prot
ocol_version)
{ {
p_sis->i_table_id = i_table_id;
p_sis->i_extension = i_extension;
p_sis->i_version = i_version;
p_sis->b_current_next = b_current_next;
assert(i_protocol_version == 0); assert(i_protocol_version == 0);
p_sis->i_protocol_version = 0; /* must be 0 */ p_sis->i_protocol_version = 0; /* must be 0 */
/* encryption */ /* encryption */
p_sis->b_encrypted_packet = 0; p_sis->b_encrypted_packet = false;
p_sis->i_encryption_algorithm = 0; p_sis->i_encryption_algorithm = 0;
p_sis->i_pts_adjustment = (uint64_t)0; p_sis->i_pts_adjustment = (uint64_t)0;
p_sis->cw_index = 0; p_sis->cw_index = 0;
/* splice command */ /* splice command */
p_sis->i_splice_command_length = 0; p_sis->i_splice_command_length = 0;
p_sis->i_splice_command_type = 0x00; p_sis->i_splice_command_type = 0x00;
/* FIXME: splice_info_section comes here */ /* FIXME: splice_info_section comes here */
skipping to change at line 174 skipping to change at line 178
/* descriptors */ /* descriptors */
p_sis->i_descriptors_length = 0; p_sis->i_descriptors_length = 0;
p_sis->p_first_descriptor = NULL; p_sis->p_first_descriptor = NULL;
/* FIXME: alignment stuffing */ /* FIXME: alignment stuffing */
p_sis->i_ecrc = 0; p_sis->i_ecrc = 0;
} }
/************************************************************************** *** /************************************************************************** ***
* dvbpsi_EmptySIS * dvbpsi_sis_new
**************************************************************************
***
* Allocate and Initialize a new dvbpsi_sis_t structure.
**************************************************************************
***/
dvbpsi_sis_t* dvbpsi_sis_new(uint8_t i_table_id, uint16_t i_extension, uint
8_t i_version,
bool b_current_next, uint8_t i_protocol_versio
n)
{
dvbpsi_sis_t* p_sis = (dvbpsi_sis_t*)malloc(sizeof(dvbpsi_sis_t));
if (p_sis != NULL)
dvbpsi_sis_init(p_sis, i_table_id, i_extension, i_version,
b_current_next, i_protocol_version);
return p_sis;
}
/**************************************************************************
***
* dvbpsi_sis_empty
************************************************************************** *** ************************************************************************** ***
* Clean a dvbpsi_sis_t structure. * Clean a dvbpsi_sis_t structure.
************************************************************************** ***/ ************************************************************************** ***/
void dvbpsi_EmptySIS(dvbpsi_sis_t* p_sis) void dvbpsi_sis_empty(dvbpsi_sis_t* p_sis)
{ {
/* FIXME: free splice_command_sections */ /* FIXME: free splice_command_sections */
dvbpsi_DeleteDescriptors(p_sis->p_first_descriptor); dvbpsi_DeleteDescriptors(p_sis->p_first_descriptor);
p_sis->p_first_descriptor = NULL; p_sis->p_first_descriptor = NULL;
/* FIXME: free alignment stuffing */ /* FIXME: free alignment stuffing */
} }
/************************************************************************** *** /************************************************************************** ***
* dvbpsi_SISAddDescriptor * dvbpsi_sis_delete
**************************************************************************
***
* Clean and Delete a dvbpsi_sis_t structure.
**************************************************************************
***/
void dvbpsi_sis_delete(dvbpsi_sis_t *p_sis)
{
if (p_sis)
dvbpsi_sis_empty(p_sis);
free(p_sis);
}
/**************************************************************************
***
* dvbpsi_sis_descriptor_add
************************************************************************** *** ************************************************************************** ***
* Add a descriptor in the SIS service description. * Add a descriptor in the SIS service description.
************************************************************************** ***/ ************************************************************************** ***/
dvbpsi_descriptor_t *dvbpsi_SISAddDescriptor( dvbpsi_sis_t *p_sis, dvbpsi_descriptor_t *dvbpsi_sis_descriptor_add(dvbpsi_sis_t *p_sis,
uint8_t i_tag, uint8_t i_leng uint8_t i_tag, uint8_t i_lengt
th, h,
uint8_t *p_data) uint8_t *p_data)
{ {
dvbpsi_descriptor_t * p_descriptor; dvbpsi_descriptor_t * p_descriptor;
p_descriptor = dvbpsi_NewDescriptor(i_tag, i_length, p_data); p_descriptor = dvbpsi_NewDescriptor(i_tag, i_length, p_data);
if (p_descriptor) if (p_descriptor == NULL)
return NULL;
p_sis->p_first_descriptor = dvbpsi_AddDescriptor(p_sis->p_first_descrip
tor,
p_descriptor);
assert(p_sis->p_first_descriptor);
if (p_sis->p_first_descriptor == NULL)
return NULL;
return p_descriptor;
}
/* */
static void dvbpsi_ReInitSIS(dvbpsi_sis_decoder_t* p_decoder, const bool b_
force)
{
assert(p_decoder);
dvbpsi_decoder_reset(DVBPSI_DECODER(p_decoder), b_force);
/* Force redecoding */
if (b_force)
{ {
if (p_sis->p_first_descriptor == NULL) /* Free structures */
{ if (p_decoder->p_building_sis)
p_sis->p_first_descriptor = p_descriptor; dvbpsi_sis_delete(p_decoder->p_building_sis);
}
else
{
dvbpsi_descriptor_t * p_last_descriptor = p_sis->p_first_descri
ptor;
while (p_last_descriptor->p_next != NULL)
p_last_descriptor = p_last_descriptor->p_next;
p_last_descriptor->p_next = p_descriptor;
}
} }
p_decoder->p_building_sis = NULL;
}
return p_descriptor; static bool dvbpsi_CheckSIS(dvbpsi_t *p_dvbpsi, dvbpsi_sis_decoder_t* p_sis
_decoder,
dvbpsi_psi_section_t *p_section)
{
bool b_reinit = false;
assert(p_dvbpsi);
assert(p_sis_decoder);
if (p_sis_decoder->p_building_sis->i_protocol_version != 0)
{
dvbpsi_error(p_dvbpsi, "SIS decoder",
"'protocol_version' differs"
" while no discontinuity has occured");
b_reinit = true;
}
else if (p_sis_decoder->p_building_sis->i_extension != p_section->i_ext
ension)
{
dvbpsi_error(p_dvbpsi, "SIS decoder",
"'transport_stream_id' differs"
" whereas no discontinuity has occured");
b_reinit = true;
}
else if (p_sis_decoder->p_building_sis->i_version != p_section->i_versi
on)
{
/* version_number */
dvbpsi_error(p_dvbpsi, "SIS decoder",
"'version_number' differs"
" whereas no discontinuity has occured");
b_reinit = true;
}
else if (p_sis_decoder->i_last_section_number != p_section->i_last_numb
er)
{
/* last_section_number */
dvbpsi_error(p_dvbpsi, "SIS decoder",
"'last_section_number' differs"
" whereas no discontinuity has occured");
b_reinit = true;
}
return b_reinit;
}
static bool dvbpsi_AddSectionSIS(dvbpsi_t *p_dvbpsi, dvbpsi_sis_decoder_t *
p_sis_decoder,
dvbpsi_psi_section_t* p_section)
{
assert(p_dvbpsi);
assert(p_sis_decoder);
assert(p_section);
/* Initialize the structures if it's the first section received */
if (!p_sis_decoder->p_building_sis)
{
p_sis_decoder->p_building_sis = dvbpsi_sis_new(
p_section->i_table_id, p_section->i_extension,
p_section->i_version, p_section->b_current_next
, 0);
if (p_sis_decoder->p_building_sis == NULL)
return false;
p_sis_decoder->i_last_section_number = p_section->i_last_number;
}
/* Add to linked list of sections */
if (dvbpsi_decoder_psi_section_add(DVBPSI_DECODER(p_sis_decoder), p_sec
tion))
dvbpsi_debug(p_dvbpsi, "SDT decoder", "overwrite section number %d"
,
p_section->i_number);
return true;
} }
/************************************************************************** *** /************************************************************************** ***
* dvbpsi_GatherSISSections * dvbpsi_sis_sections_gather
************************************************************************** *** ************************************************************************** ***
* Callback for the subtable demultiplexor. * Callback for the subtable demultiplexor.
************************************************************************** ***/ ************************************************************************** ***/
void dvbpsi_GatherSISSections(dvbpsi_decoder_t * p_psi_decoder, void dvbpsi_sis_sections_gather(dvbpsi_t *p_dvbpsi,
void * p_private_decoder, dvbpsi_decoder_t *p_decoder,
dvbpsi_psi_section_t * p_section) dvbpsi_psi_section_t * p_section)
{ {
dvbpsi_sis_decoder_t * p_sis_decoder assert(p_dvbpsi);
= (dvbpsi_sis_decoder_t*)p_private_decoder; assert(p_dvbpsi->p_decoder);
int b_append = 1;
int b_reinit = 0;
DVBPSI_DEBUG_ARG("SIS decoder",
"Table version %2d, " "i_table_id %2d, " "i_extension
%5d, "
"section %3d up to %3d, " "current %1d",
p_section->i_version, p_section->i_table_id,
p_section->i_extension,
p_section->i_number, p_section->i_last_number,
p_section->b_current_next);
if (p_section->i_table_id != 0xFC) if (!dvbpsi_CheckPSISection(p_dvbpsi, p_section, 0xFC, "SIS decoder"))
{ {
/* Invalid table_id value */ dvbpsi_DeletePSISections(p_section);
DVBPSI_ERROR_ARG("SIS decoder", return;
"invalid section (table_id == 0x%02x)",
p_section->i_table_id);
b_append = 0;
} }
if (p_section->b_syntax_indicator != 0) /* */
{ dvbpsi_demux_t *p_demux = (dvbpsi_demux_t *) p_dvbpsi->p_decoder;
/* Invalid section_syntax_indicator */ dvbpsi_sis_decoder_t * p_sis_decoder = (dvbpsi_sis_decoder_t*)p_decoder
DVBPSI_ERROR("SIS decoder", ;
"invalid section (section_syntax_indicator != 0)");
b_append = 0;
}
if (p_section->b_private_indicator != 0) if (p_section->b_private_indicator)
{ {
/* Invalid private_syntax_indicator */ /* Invalid private_syntax_indicator */
DVBPSI_ERROR("SIS decoder", dvbpsi_error(p_dvbpsi, "SIS decoder",
"invalid private section (private_syntax_indicator != "invalid private section (private_syntax_indicator !=
0)"); false)");
b_append = 0; dvbpsi_DeletePSISections(p_section);
return;
} }
/* Now if b_append is true then we have a valid SIS section */ /* TS discontinuity check */
if (b_append) if (p_demux->b_discontinuity)
{ {
/* TS discontinuity check */ dvbpsi_ReInitSIS(p_sis_decoder, true);
if (p_psi_decoder->b_discontinuity) p_sis_decoder->b_discontinuity = false;
p_demux->b_discontinuity = false;
}
else
{
/* Perform a few sanity checks */
if (p_sis_decoder->p_building_sis)
{ {
b_reinit = 1; if (dvbpsi_CheckSIS(p_dvbpsi, p_sis_decoder, p_section))
p_psi_decoder->b_discontinuity = 0; dvbpsi_ReInitSIS(p_sis_decoder, true);
} }
else else
{ {
/* Perform a few sanity checks */ if( (p_sis_decoder->b_current_valid)
if (p_sis_decoder->p_building_sis) && (p_sis_decoder->current_sis.i_version == p_section->i_v
{ ersion)
if (p_sis_decoder->p_building_sis->i_protocol_version != 0) && (p_sis_decoder->current_sis.b_current_next == p_section
{ ->b_current_next))
/* transport_stream_id */ {
DVBPSI_ERROR("SIS decoder", /* Don't decode since this version is already decoded */
"'protocol_version' differs");\ dvbpsi_debug(p_dvbpsi, "SIT decoder",
b_reinit = 1; "ignoring already decoded section %d",
} p_section->i_number);
} dvbpsi_DeletePSISections(p_section);
else return;
{ }
if (p_sis_decoder->b_current_valid)
{
/* Don't decode since this version is already decoded *
/
b_append = 0;
}
}
} }
} }
/* Reinit the decoder if wanted */ /* Add section to SIS */
if (b_reinit) if (!dvbpsi_AddSectionSIS(p_dvbpsi, p_sis_decoder, p_section))
{ {
/* Force redecoding */ dvbpsi_error(p_dvbpsi, "SIS decoder", "failed decoding section %d",
p_sis_decoder->b_current_valid = 0; p_section->i_number);
dvbpsi_DeletePSISections(p_section);
/* Free structures */ return;
if (p_sis_decoder->p_building_sis)
{
free(p_sis_decoder->p_building_sis);
p_sis_decoder->p_building_sis = NULL;
}
} }
/* Append the section to the list if wanted */ /* Check if we have all the sections */
if (b_append) if (dvbpsi_decoder_psi_sections_completed(DVBPSI_DECODER(p_sis_decoder)
{ ))
/* Initialize the structures if it's the first section received */
if (!p_sis_decoder->p_building_sis)
{
p_sis_decoder->p_building_sis =
(dvbpsi_sis_t*)malloc(sizeof(dvbpsi_sis_t))
;
// FIXME: potiential crash on OUT OF MEMORY
dvbpsi_InitSIS(p_sis_decoder->p_building_sis, 0);
}
}
else
{ {
dvbpsi_DeletePSISections(p_section); assert(p_sis_decoder->pf_sis_callback);
/* Save the current information */
p_sis_decoder->current_sis = *p_sis_decoder->p_building_sis;
p_sis_decoder->b_current_valid = true;
/* Decode the sections */
dvbpsi_sis_sections_decode(p_dvbpsi, p_sis_decoder->p_building_sis,
p_sis_decoder->p_sections);
/* Delete the sections */
dvbpsi_DeletePSISections(p_sis_decoder->p_sections);
p_sis_decoder->p_sections = NULL;
/* signal the new SDT */
p_sis_decoder->pf_sis_callback(p_sis_decoder->p_cb_data,
p_sis_decoder->p_building_sis);
/* Reinitialize the structures */
dvbpsi_ReInitSIS(p_sis_decoder, false);
} }
} }
/************************************************************************** *** /************************************************************************** ***
* dvbpsi_DecodeSISSection * dvbpsi_sis_sections_decode
************************************************************************** *** ************************************************************************** ***
* SIS decoder. * SIS decoder.
************************************************************************** ***/ ************************************************************************** ***/
void dvbpsi_DecodeSISSections(dvbpsi_sis_t* p_sis, void dvbpsi_sis_sections_decode(dvbpsi_t* p_dvbpsi, dvbpsi_sis_t* p_sis,
dvbpsi_psi_section_t* p_section) dvbpsi_psi_section_t* p_section)
{ {
uint8_t *p_byte, *p_end; uint8_t *p_byte, *p_end;
while (p_section) while (p_section)
{ {
for (p_byte = p_section->p_payload_start + 3; for (p_byte = p_section->p_payload_start + 3;
p_byte < p_section->p_payload_end; ) p_byte < p_section->p_payload_end; )
{ {
p_sis->i_protocol_version = p_byte[3]; p_sis->i_protocol_version = p_byte[3];
p_sis->b_encrypted_packet = ((p_byte[4] & 0x80)>>8); p_sis->b_encrypted_packet = ((p_byte[4] & 0x80)>>8);
/* NOTE: cannot handle encrypted packet */ /* NOTE: cannot handle encrypted packet */
assert(p_sis->b_encrypted_packet == 1); assert(p_sis->b_encrypted_packet);
p_sis->i_encryption_algorithm = ((p_byte[4] & 0x7E) >> 1); p_sis->i_encryption_algorithm = ((p_byte[4] & 0x7E) >> 1);
p_sis->i_pts_adjustment = ((((uint64_t)p_byte[4] & 0x01) << 32) | p_sis->i_pts_adjustment = ((((uint64_t)p_byte[4] & 0x01) << 32) |
((uint64_t)p_byte[5] << 24) | ((uint64_t)p_byte[5] << 24) |
((uint64_t)p_byte[6] << 16) | ((uint64_t)p_byte[6] << 16) |
((uint64_t)p_byte[7] << 8) | ((uint64_t)p_byte[7] << 8) |
(uint64_t)p_byte[8]); (uint64_t)p_byte[8]);
p_sis->cw_index = p_byte[9]; p_sis->cw_index = p_byte[9];
p_sis->i_splice_command_length = ((p_byte[11] & 0x0F) << 8) | p _byte[12]; p_sis->i_splice_command_length = ((p_byte[11] & 0x0F) << 8) | p _byte[12];
p_sis->i_splice_command_type = p_byte[13]; p_sis->i_splice_command_type = p_byte[13];
uint32_t i_splice_command_length = p_sis->i_splice_command_leng th; uint32_t i_splice_command_length = p_sis->i_splice_command_leng th;
if (p_sis->i_splice_command_length == 0xfff) if (p_sis->i_splice_command_length == 0xfff)
{ {
/* FIXME: size 0xfff of splice_command_section is undefined */ /* FIXME: size 0xfff of splice_command_section is undefined */
assert(p_sis->i_splice_command_length != 0xfff); assert(p_sis->i_splice_command_length != 0xfff);
} }
/* FIXME: handle splice_command_sections */ /* FIXME: handle splice_command_sections */
switch(p_sis->i_splice_command_type)
{
case 0x00: /* splice_null */
case 0x04: /* splice_schedule */
case 0x05: /* splice_insert */
case 0x06: /* time_signal */
case 0x07: /* bandwidth_reservation */
break;
default:
dvbpsi_error(p_dvbpsi, "SIS decoder", "invalid SIS Comm
and found");
break;
}
/* Service descriptors */ /* Service descriptors */
uint8_t *p_desc = p_byte + 13 + i_splice_command_length; uint8_t *p_desc = p_byte + 13 + i_splice_command_length;
p_sis->i_descriptors_length = (p_desc[0] << 8) | p_desc[1]; p_sis->i_descriptors_length = (p_desc[0] << 8) | p_desc[1];
p_desc += 1; p_desc += 1;
p_end = p_desc + p_sis->i_descriptors_length; p_end = p_desc + p_sis->i_descriptors_length;
if (p_end > p_section->p_payload_end) break; if (p_end > p_section->p_payload_end) break;
while (p_desc + 2 <= p_end) while (p_desc + 2 <= p_end)
{ {
uint8_t i_tag = p_desc[0]; uint8_t i_tag = p_desc[0];
uint8_t i_length = p_desc[1]; uint8_t i_length = p_desc[1];
if ((i_length <= 254) && if ((i_length <= 254) &&
(i_length + 2 <= p_end - p_desc)) (i_length + 2 <= p_end - p_desc))
dvbpsi_SISAddDescriptor(p_sis, i_tag, i_length, p_desc + 2); dvbpsi_sis_descriptor_add(p_sis, i_tag, i_length, p_des c + 2);
p_desc += 2 + i_length; p_desc += 2 + i_length;
} }
if (p_sis->b_encrypted_packet == 1) if (p_sis->b_encrypted_packet)
{ {
/* FIXME: Currently ignored */ /* FIXME: Currently ignored */
/* Calculate crc32 over decoded /* Calculate crc32 over decoded
* p_sis->i_splice_command_type till p_sis->i_ecrc, * p_sis->i_splice_command_type till p_sis->i_ecrc,
* the result should be exactly p_sis->i_ecrc and indicates * the result should be exactly p_sis->i_ecrc and indicates
* a successfull decryption. * a successfull decryption.
*/ */
p_desc += 4; /* E CRC 32 */ p_desc += 4; /* E CRC 32 */
} }
/* point to next section */ /* point to next section */
p_byte = p_desc + 4 /* CRC 32 */; p_byte = p_desc + 4 /* CRC 32 */;
} }
p_section = p_section->p_next; p_section = p_section->p_next;
} }
} }
/************************************************************************** *** /************************************************************************** ***
* dvbpsi_GenSISSections * dvbpsi_sis_sections_generate
************************************************************************** *** ************************************************************************** ***
* Generate SIS sections based on the dvbpsi_sis_t structure. * Generate SIS sections based on the dvbpsi_sis_t structure.
************************************************************************** ***/ ************************************************************************** ***/
dvbpsi_psi_section_t *dvbpsi_GenSISSections(dvbpsi_sis_t* p_sis) dvbpsi_psi_section_t *dvbpsi_sis_sections_generate(dvbpsi_t *p_dvbpsi, dvbp si_sis_t* p_sis)
{ {
dvbpsi_psi_section_t * p_current = dvbpsi_NewPSISection(1024); dvbpsi_psi_section_t * p_current = dvbpsi_NewPSISection(1024);
p_current->i_table_id = 0xFC; p_current->i_table_id = 0xFC;
p_current->b_syntax_indicator = 0; p_current->b_syntax_indicator = false;
p_current->b_private_indicator = 0; p_current->b_private_indicator = false;
p_current->i_length = 3; /* header + CRC_32 */ p_current->i_length = 3; /* header + CRC_32 */
/* FIXME: looks weird */ /* FIXME: looks weird */
p_current->p_payload_end += 2; /* just after the header * / p_current->p_payload_end += 2; /* just after the header * /
p_current->p_payload_start = p_current->p_data + 3; p_current->p_payload_start = p_current->p_data + 3;
p_current->p_data[3] = p_sis->i_protocol_version; p_current->p_data[3] = p_sis->i_protocol_version;
p_current->p_data[4] = p_sis->b_encrypted_packet ? 0x80 : 0x0; p_current->p_data[4] = p_sis->b_encrypted_packet ? 0x80 : 0x0;
/* NOTE: cannot handle encrypted packet */ /* NOTE: cannot handle encrypted packet */
assert(p_sis->b_encrypted_packet == 1); assert(p_sis->b_encrypted_packet);
p_current->p_data[4] |= ((p_sis->i_encryption_algorithm << 1) & 0x7E); p_current->p_data[4] |= ((p_sis->i_encryption_algorithm << 1) & 0x7E);
p_current->p_data[4] |= ((p_sis->i_pts_adjustment & 0x00800) >> 32); p_current->p_data[4] |= ((p_sis->i_pts_adjustment & 0x00800) >> 32);
p_current->p_data[5] = (p_sis->i_pts_adjustment >> 24); p_current->p_data[5] = (p_sis->i_pts_adjustment >> 24);
p_current->p_data[6] = (p_sis->i_pts_adjustment >> 16); p_current->p_data[6] = (p_sis->i_pts_adjustment >> 16);
p_current->p_data[7] = (p_sis->i_pts_adjustment >> 8); p_current->p_data[7] = (p_sis->i_pts_adjustment >> 8);
p_current->p_data[8] = p_sis->i_pts_adjustment; p_current->p_data[8] = p_sis->i_pts_adjustment;
p_current->p_data[9] = p_sis->cw_index; p_current->p_data[9] = p_sis->cw_index;
p_current->p_data[11] = 0x00; p_current->p_data[11] = 0x00;
skipping to change at line 476 skipping to change at line 578
memcpy(p_current->p_payload_end + 2, p_descriptor->p_data, p_descri ptor->i_length); memcpy(p_current->p_payload_end + 2, p_descriptor->p_data, p_descri ptor->i_length);
/* Increase length by descriptor_length + 2 */ /* Increase length by descriptor_length + 2 */
p_current->p_payload_end += p_descriptor->i_length + 2; p_current->p_payload_end += p_descriptor->i_length + 2;
p_current->i_length += p_descriptor->i_length + 2; p_current->i_length += p_descriptor->i_length + 2;
} }
/* Coding error if this condition is not met */ /* Coding error if this condition is not met */
assert( i_desc_length == p_sis->i_descriptors_length); assert( i_desc_length == p_sis->i_descriptors_length);
/* Finalization */ /* Finalization */
dvbpsi_BuildPSISection(p_current); dvbpsi_BuildPSISection(p_dvbpsi, p_current);
return p_current; return p_current;
} }
 End of changes. 64 change blocks. 
171 lines changed or deleted 296 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/