Commit 387b7cf5 authored by Jean-Paul Saman's avatar Jean-Paul Saman

ATSC VCT table: forward port

- indentation cleanup
- Gather fucnction cleanup
- API cleanup
parent 7e6453a4
/* /*
Copyright (C) 2006 Adam Charrett Copyright (C) 2006-2012 Adam Charrett
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
...@@ -24,37 +24,47 @@ Decode PSIP Virtual Channel Table. ...@@ -24,37 +24,47 @@ Decode PSIP Virtual Channel Table.
#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)
#include <inttypes.h>
#elif defined(HAVE_STDINT_H)
#include <stdint.h> #include <stdint.h>
#endif
#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 "atsc_vct.h" #include "atsc_vct.h"
typedef struct dvbpsi_atsc_vct_decoder_s typedef struct dvbpsi_atsc_vct_decoder_s
{ {
dvbpsi_atsc_vct_callback pf_callback; DVBPSI_DECODER_COMMON
void * p_cb_data;
dvbpsi_atsc_vct_callback pf_vct_callback;
void * p_cb_data;
dvbpsi_atsc_vct_t current_vct; dvbpsi_atsc_vct_t current_vct;
dvbpsi_atsc_vct_t * p_building_vct; dvbpsi_atsc_vct_t * p_building_vct;
int b_current_valid; bool b_current_valid;
uint8_t i_last_section_number; uint8_t i_last_section_number;
dvbpsi_psi_section_t * ap_sections [256]; dvbpsi_psi_section_t * ap_sections [256];
} dvbpsi_atsc_vct_decoder_t; } dvbpsi_atsc_vct_decoder_t;
dvbpsi_descriptor_t *dvbpsi_atsc_VCTAddDescriptor( static dvbpsi_descriptor_t *dvbpsi_atsc_VCTAddDescriptor(
dvbpsi_atsc_vct_t *p_vct, dvbpsi_atsc_vct_t *p_vct,
uint8_t i_tag, uint8_t i_length, uint8_t i_tag, uint8_t i_length,
uint8_t *p_data); uint8_t *p_data);
dvbpsi_atsc_vct_channel_t *dvbpsi_atsc_VCTAddChannel(dvbpsi_atsc_vct_t* p_vct, static dvbpsi_atsc_vct_channel_t *dvbpsi_atsc_VCTAddChannel(dvbpsi_atsc_vct_t* p_vct,
uint8_t *p_short_name, uint8_t *p_short_name,
uint16_t i_major_number, uint16_t i_major_number,
uint16_t i_minor_number, uint16_t i_minor_number,
...@@ -71,16 +81,15 @@ dvbpsi_atsc_vct_channel_t *dvbpsi_atsc_VCTAddChannel(dvbpsi_atsc_vct_t* p_vct, ...@@ -71,16 +81,15 @@ dvbpsi_atsc_vct_channel_t *dvbpsi_atsc_VCTAddChannel(dvbpsi_atsc_vct_t* p_vct,
uint8_t i_service_type, uint8_t i_service_type,
uint16_t i_source_id); uint16_t i_source_id);
dvbpsi_descriptor_t *dvbpsi_atsc_VCTChannelAddDescriptor( static dvbpsi_descriptor_t *dvbpsi_atsc_VCTChannelAddDescriptor(
dvbpsi_atsc_vct_channel_t *p_table, dvbpsi_atsc_vct_channel_t *p_table,
uint8_t i_tag, uint8_t i_length, uint8_t i_tag, uint8_t i_length,
uint8_t *p_data); uint8_t *p_data);
void dvbpsi_atsc_GatherVCTSections(dvbpsi_decoder_t * p_psi_decoder, static void dvbpsi_atsc_GatherVCTSections(dvbpsi_t * p_dvbpsi,
void * p_private_decoder, void * p_private_decoder, dvbpsi_psi_section_t * p_section);
dvbpsi_psi_section_t * p_section);
void dvbpsi_atsc_DecodeVCTSections(dvbpsi_atsc_vct_t* p_vct, static void dvbpsi_atsc_DecodeVCTSections(dvbpsi_atsc_vct_t* p_vct,
dvbpsi_psi_section_t* p_section); dvbpsi_psi_section_t* p_section);
/***************************************************************************** /*****************************************************************************
...@@ -88,105 +97,118 @@ void dvbpsi_atsc_DecodeVCTSections(dvbpsi_atsc_vct_t* p_vct, ...@@ -88,105 +97,118 @@ void dvbpsi_atsc_DecodeVCTSections(dvbpsi_atsc_vct_t* p_vct,
***************************************************************************** *****************************************************************************
* Initialize a VCT subtable decoder. * Initialize a VCT subtable decoder.
*****************************************************************************/ *****************************************************************************/
int dvbpsi_atsc_AttachVCT(dvbpsi_decoder_t * p_psi_decoder, uint8_t i_table_id, uint16_t i_extension, bool dvbpsi_atsc_AttachVCT(dvbpsi_t *p_dvbpsi, uint8_t i_table_id, uint16_t i_extension,
dvbpsi_atsc_vct_callback pf_callback, void* p_cb_data) dvbpsi_atsc_vct_callback pf_callback, void* p_cb_data)
{ {
dvbpsi_demux_t* p_demux = (dvbpsi_demux_t*)p_psi_decoder->p_private_decoder; assert(p_dvbpsi);
dvbpsi_demux_subdec_t* p_subdec; assert(p_dvbpsi->p_private);
dvbpsi_atsc_vct_decoder_t* p_vct_decoder;
unsigned int i; dvbpsi_demux_t* p_demux = (dvbpsi_demux_t*)p_dvbpsi->p_private;
dvbpsi_demux_subdec_t* p_subdec;
if(dvbpsi_demuxGetSubDec(p_demux, i_table_id, i_extension)) dvbpsi_atsc_vct_decoder_t* p_vct_decoder;
{
DVBPSI_ERROR_ARG("VCT decoder", if (dvbpsi_demuxGetSubDec(p_demux, i_table_id, i_extension))
"Already a decoder for (table_id == 0x%02x extension == 0x%04x)", {
dvbpsi_error(p_dvbpsi, "VCT decoder",
"Already a decoder for (table_id == 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*)calloc(1, sizeof(dvbpsi_demux_subdec_t));
} if (p_subdec == NULL)
return false;
p_subdec = (dvbpsi_demux_subdec_t*)malloc(sizeof(dvbpsi_demux_subdec_t)); p_vct_decoder = (dvbpsi_atsc_vct_decoder_t*)calloc(1, sizeof(dvbpsi_atsc_vct_decoder_t));
if(p_subdec == NULL) if (p_vct_decoder == NULL)
{ {
return 1; free(p_subdec);
} return false;
}
p_vct_decoder = (dvbpsi_atsc_vct_decoder_t*)malloc(sizeof(dvbpsi_atsc_vct_decoder_t)); /* subtable decoder configuration */
if(p_vct_decoder == NULL) p_subdec->pf_callback = &dvbpsi_atsc_GatherVCTSections;
{ p_subdec->p_cb_data = p_vct_decoder;
free(p_subdec); p_subdec->i_id = ((uint32_t)i_table_id << 16) | i_extension;
return 1; p_subdec->pf_detach = dvbpsi_atsc_DetachVCT;
}
/* subtable decoder configuration */
p_subdec->pf_callback = &dvbpsi_atsc_GatherVCTSections;
p_subdec->p_cb_data = p_vct_decoder;
p_subdec->i_id = ((uint32_t)i_table_id << 16) | i_extension;
p_subdec->pf_detach = dvbpsi_atsc_DetachVCT;
/* Attach the subtable decoder to the demux */
p_subdec->p_next = p_demux->p_first_subdec;
p_demux->p_first_subdec = p_subdec;
/* VCT decoder information */
p_vct_decoder->pf_callback = pf_callback;
p_vct_decoder->p_cb_data = p_cb_data;
/* VCT decoder initial state */
p_vct_decoder->b_current_valid = 0;
p_vct_decoder->p_building_vct = NULL;
for(i = 0; i <= 255; i++)
p_vct_decoder->ap_sections[i] = NULL;
return 0;
}
/* Attach the subtable decoder to the demux */
p_subdec->p_next = p_demux->p_first_subdec;
p_demux->p_first_subdec = p_subdec;
/* VCT decoder information */
p_vct_decoder->pf_vct_callback = pf_callback;
p_vct_decoder->p_cb_data = p_cb_data;
/* VCT decoder initial state */
p_vct_decoder->b_current_valid = false;
p_vct_decoder->p_building_vct = NULL;
for(unsigned int i = 0; i < 256; i++)
p_vct_decoder->ap_sections[i] = NULL;
return true;
}
/***************************************************************************** /*****************************************************************************
* dvbpsi_atsc_DetachVCT * dvbpsi_atsc_DetachVCT
***************************************************************************** *****************************************************************************
* Close a VCT decoder. * Close a VCT decoder.
*****************************************************************************/ *****************************************************************************/
void dvbpsi_atsc_DetachVCT(dvbpsi_demux_t * p_demux, uint8_t i_table_id, uint16_t i_extension) void dvbpsi_atsc_DetachVCT(dvbpsi_t *p_dvbpsi, uint8_t i_table_id, uint16_t i_extension)
{ {
dvbpsi_demux_subdec_t* p_subdec; assert(p_dvbpsi);
dvbpsi_demux_subdec_t** pp_prev_subdec; assert(p_dvbpsi->p_private);
dvbpsi_atsc_vct_decoder_t* p_vct_decoder;
unsigned int i;
p_subdec = dvbpsi_demuxGetSubDec(p_demux, i_table_id, i_extension);
if(p_subdec == NULL)
{
DVBPSI_ERROR_ARG("VCT Decoder",
"No such VCT decoder (table_id == 0x%02x,"
"extension == 0x%04x)",
i_table_id, i_extension);
return;
}
p_vct_decoder = (dvbpsi_atsc_vct_decoder_t*)p_subdec->p_cb_data; dvbpsi_demux_t *p_demux = (dvbpsi_demux_t *) p_dvbpsi->p_private;
if(!p_vct_decoder) dvbpsi_demux_subdec_t* p_subdec;
return; dvbpsi_demux_subdec_t** pp_prev_subdec;
dvbpsi_atsc_vct_decoder_t* p_vct_decoder;
if (p_vct_decoder->p_building_vct) p_subdec = dvbpsi_demuxGetSubDec(p_demux, i_table_id, i_extension);
{ if(p_subdec == NULL)
{
dvbpsi_error(p_dvbpsi, "VCT Decoder",
"No such VCT decoder (table_id == 0x%02x,"
"extension == 0x%04x)",
i_table_id, i_extension);
return;
}
p_vct_decoder = (dvbpsi_atsc_vct_decoder_t*)p_subdec->p_cb_data;
if(!p_vct_decoder)
return;
free(p_vct_decoder->p_building_vct); free(p_vct_decoder->p_building_vct);
}
for(i = 0; i <= 255; i++) for(unsigned int i = 0; i < 256; i++)
{ {
if(p_vct_decoder->ap_sections[i]) if (p_vct_decoder->ap_sections[i])
dvbpsi_DeletePSISections(p_vct_decoder->ap_sections[i]); dvbpsi_DeletePSISections(p_vct_decoder->ap_sections[i]);
} }
free(p_subdec->p_cb_data);
free(p_subdec->p_cb_data); pp_prev_subdec = &p_demux->p_first_subdec;
while(*pp_prev_subdec != p_subdec)
pp_prev_subdec = &(*pp_prev_subdec)->p_next;
pp_prev_subdec = &p_demux->p_first_subdec; *pp_prev_subdec = p_subdec->p_next;
while(*pp_prev_subdec != p_subdec) free(p_subdec);
pp_prev_subdec = &(*pp_prev_subdec)->p_next; p_subdec = NULL;
}
*pp_prev_subdec = p_subdec->p_next; /*****************************************************************************
free(p_subdec); * dvbpsi_atsc_NewVCT
*****************************************************************************
* Allocate a new dvbpsi_atsc_vct_t structure and initialize it.
*****************************************************************************/
dvbpsi_atsc_vct_t *dvbpsi_atsc_NewVCT(uint8_t i_protocol, uint16_t i_ts_id,
bool b_cable_vct, uint8_t i_version, bool b_current_next)
{
dvbpsi_atsc_vct_t *p_vct = (dvbpsi_atsc_vct_t*)malloc(sizeof(dvbpsi_atsc_vct_t));
if (p_vct != NULL)
dvbpsi_atsc_InitVCT(p_vct, i_protocol, i_ts_id, b_cable_vct,
i_version, b_current_next);
return p_vct;
} }
/***************************************************************************** /*****************************************************************************
...@@ -194,19 +216,20 @@ void dvbpsi_atsc_DetachVCT(dvbpsi_demux_t * p_demux, uint8_t i_table_id, uint16_ ...@@ -194,19 +216,20 @@ void dvbpsi_atsc_DetachVCT(dvbpsi_demux_t * p_demux, uint8_t i_table_id, uint16_
***************************************************************************** *****************************************************************************
* Initialize a pre-allocated dvbpsi_atsc_vct_t structure. * Initialize a pre-allocated dvbpsi_atsc_vct_t structure.
*****************************************************************************/ *****************************************************************************/
void dvbpsi_atsc_InitVCT(dvbpsi_atsc_vct_t* p_vct,uint8_t i_version, int b_current_next, void dvbpsi_atsc_InitVCT(dvbpsi_atsc_vct_t* p_vct, uint8_t i_protocol,
uint8_t i_protocol, uint16_t i_ts_id, int b_cable_vct) uint16_t i_ts_id, bool b_cable_vct,
uint8_t i_version, bool b_current_next)
{ {
p_vct->i_version = i_version; assert(p_vct);
p_vct->b_current_next = b_current_next; p_vct->i_version = i_version;
p_vct->i_protocol = i_protocol; p_vct->b_current_next = b_current_next;
p_vct->i_ts_id = i_ts_id; p_vct->i_protocol = i_protocol;
p_vct->b_cable_vct = b_cable_vct; p_vct->i_ts_id = i_ts_id;
p_vct->p_first_channel = NULL; p_vct->b_cable_vct = b_cable_vct;
p_vct->p_first_descriptor = NULL; p_vct->p_first_channel = NULL;
p_vct->p_first_descriptor = NULL;
} }
/***************************************************************************** /*****************************************************************************
* dvbpsi_atsc_EmptyVCT * dvbpsi_atsc_EmptyVCT
***************************************************************************** *****************************************************************************
...@@ -214,18 +237,30 @@ void dvbpsi_atsc_InitVCT(dvbpsi_atsc_vct_t* p_vct,uint8_t i_version, int b_curre ...@@ -214,18 +237,30 @@ void dvbpsi_atsc_InitVCT(dvbpsi_atsc_vct_t* p_vct,uint8_t i_version, int b_curre
*****************************************************************************/ *****************************************************************************/
void dvbpsi_atsc_EmptyVCT(dvbpsi_atsc_vct_t* p_vct) void dvbpsi_atsc_EmptyVCT(dvbpsi_atsc_vct_t* p_vct)
{ {
dvbpsi_atsc_vct_channel_t* p_channel = p_vct->p_first_channel; dvbpsi_atsc_vct_channel_t* p_channel = p_vct->p_first_channel;
dvbpsi_DeleteDescriptors(p_vct->p_first_descriptor);
while(p_channel != NULL) p_vct->p_first_descriptor = NULL;
{
dvbpsi_atsc_vct_channel_t* p_tmp = p_channel->p_next; while(p_channel != NULL)
dvbpsi_DeleteDescriptors(p_channel->p_first_descriptor); {
free(p_channel); dvbpsi_atsc_vct_channel_t* p_tmp = p_channel->p_next;
p_channel = p_tmp; dvbpsi_DeleteDescriptors(p_channel->p_first_descriptor);
} free(p_channel);
dvbpsi_DeleteDescriptors(p_vct->p_first_descriptor); p_channel = p_tmp;
p_vct->p_first_channel = NULL; }
p_vct->p_first_descriptor = NULL; p_vct->p_first_channel = NULL;
}
/*****************************************************************************
* dvbpsi_atsc_DeleteVCT
*****************************************************************************
* Empty and Delere a dvbpsi_atsc_vct_t structure.
*****************************************************************************/
void dvbpsi_atsc_DeleteVCT(dvbpsi_atsc_vct_t *p_vct)
{
if (p_vct)
dvbpsi_atsc_EmptyVCT(p_vct);
free(p_vct);
} }
/***************************************************************************** /*****************************************************************************
...@@ -233,36 +268,36 @@ void dvbpsi_atsc_EmptyVCT(dvbpsi_atsc_vct_t* p_vct) ...@@ -233,36 +268,36 @@ void dvbpsi_atsc_EmptyVCT(dvbpsi_atsc_vct_t* p_vct)
***************************************************************************** *****************************************************************************
* Add a descriptor to the VCT table. * Add a descriptor to the VCT table.
*****************************************************************************/ *****************************************************************************/
dvbpsi_descriptor_t *dvbpsi_atsc_VCTAddDescriptor( static dvbpsi_descriptor_t *dvbpsi_atsc_VCTAddDescriptor(dvbpsi_atsc_vct_t *p_vct,
dvbpsi_atsc_vct_t *p_vct,
uint8_t i_tag, uint8_t i_length, uint8_t i_tag, uint8_t i_length,
uint8_t *p_data) uint8_t *p_data)
{ {
dvbpsi_descriptor_t * p_descriptor dvbpsi_descriptor_t * p_descriptor
= dvbpsi_NewDescriptor(i_tag, i_length, p_data); = dvbpsi_NewDescriptor(i_tag, i_length, p_data);
if(p_descriptor) if(p_descriptor)
{
if(p_vct->p_first_descriptor == NULL)
{ {
p_vct->p_first_descriptor = p_descriptor; if(p_vct->p_first_descriptor == NULL)
} {
else p_vct->p_first_descriptor = p_descriptor;
{ }
dvbpsi_descriptor_t * p_last_descriptor = p_vct->p_first_descriptor; else
while(p_last_descriptor->p_next != NULL) {
p_last_descriptor = p_last_descriptor->p_next; dvbpsi_descriptor_t * p_last_descriptor = p_vct->p_first_descriptor;
p_last_descriptor->p_next = p_descriptor; while(p_last_descriptor->p_next != NULL)
p_last_descriptor = p_last_descriptor->p_next;
p_last_descriptor->p_next = p_descriptor;
}
} }
}
return p_descriptor; return p_descriptor;
} }
/***************************************************************************** /*****************************************************************************
* dvbpsi_atsc_VCTAddChannel * dvbpsi_atsc_VCTAddChannel
***************************************************************************** *****************************************************************************
* Add a Channel description at the end of the VCT. * Add a Channel description at the end of the VCT.
*****************************************************************************/ *****************************************************************************/
dvbpsi_atsc_vct_channel_t *dvbpsi_atsc_VCTAddChannel(dvbpsi_atsc_vct_t* p_vct, static dvbpsi_atsc_vct_channel_t *dvbpsi_atsc_VCTAddChannel(dvbpsi_atsc_vct_t* p_vct,
uint8_t *p_short_name, uint8_t *p_short_name,
uint16_t i_major_number, uint16_t i_major_number,
uint16_t i_minor_number, uint16_t i_minor_number,
...@@ -279,43 +314,43 @@ dvbpsi_atsc_vct_channel_t *dvbpsi_atsc_VCTAddChannel(dvbpsi_atsc_vct_t* p_vct, ...@@ -279,43 +314,43 @@ dvbpsi_atsc_vct_channel_t *dvbpsi_atsc_VCTAddChannel(dvbpsi_atsc_vct_t* p_vct,
uint8_t i_service_type, uint8_t i_service_type,
uint16_t i_source_id) uint16_t i_source_id)
{ {
dvbpsi_atsc_vct_channel_t * p_channel dvbpsi_atsc_vct_channel_t * p_channel
= (dvbpsi_atsc_vct_channel_t*)malloc(sizeof(dvbpsi_atsc_vct_channel_t)); = (dvbpsi_atsc_vct_channel_t*)malloc(sizeof(dvbpsi_atsc_vct_channel_t));
if(p_channel) if(p_channel)
{
memcpy(p_channel->i_short_name, p_short_name, sizeof(uint16_t) * 7);
p_channel->i_major_number = i_major_number;
p_channel->i_minor_number = i_minor_number;
p_channel->i_modulation = i_modulation;
p_channel->i_carrier_freq = i_carrier_freq;
p_channel->i_channel_tsid = i_channel_tsid;
p_channel->i_program_number = i_program_number;
p_channel->i_etm_location = i_etm_location;
p_channel->b_access_controlled = b_access_controlled;
p_channel->b_path_select = b_path_select;
p_channel->b_out_of_band = b_out_of_band;
p_channel->b_hidden = b_hidden;
p_channel->b_hide_guide = b_hide_guide;
p_channel->i_service_type = i_service_type;
p_channel->i_source_id = i_source_id;
p_channel->p_first_descriptor = NULL;
p_channel->p_next = NULL;
if(p_vct->p_first_channel== NULL)
{
p_vct->p_first_channel = p_channel;
}
else
{ {
dvbpsi_atsc_vct_channel_t * p_last_channel = p_vct->p_first_channel; memcpy(p_channel->i_short_name, p_short_name, sizeof(uint16_t) * 7);
while(p_last_channel->p_next != NULL) p_channel->i_major_number = i_major_number;
p_last_channel = p_last_channel->p_next; p_channel->i_minor_number = i_minor_number;
p_last_channel->p_next = p_channel; p_channel->i_modulation = i_modulation;
p_channel->i_carrier_freq = i_carrier_freq;
p_channel->i_channel_tsid = i_channel_tsid;
p_channel->i_program_number = i_program_number;
p_channel->i_etm_location = i_etm_location;
p_channel->b_access_controlled = b_access_controlled;
p_channel->b_path_select = b_path_select;
p_channel->b_out_of_band = b_out_of_band;
p_channel->b_hidden = b_hidden;
p_channel->b_hide_guide = b_hide_guide;
p_channel->i_service_type = i_service_type;
p_channel->i_source_id = i_source_id;
p_channel->p_first_descriptor = NULL;
p_channel->p_next = NULL;
if(p_vct->p_first_channel== NULL)
{
p_vct->p_first_channel = p_channel;
}
else
{
dvbpsi_atsc_vct_channel_t * p_last_channel = p_vct->p_first_channel;
while(p_last_channel->p_next != NULL)
p_last_channel = p_last_channel->p_next;
p_last_channel->p_next = p_channel;
}
} }
}
return p_channel; return p_channel;
} }
/***************************************************************************** /*****************************************************************************
...@@ -323,29 +358,29 @@ dvbpsi_atsc_vct_channel_t *dvbpsi_atsc_VCTAddChannel(dvbpsi_atsc_vct_t* p_vct, ...@@ -323,29 +358,29 @@ dvbpsi_atsc_vct_channel_t *dvbpsi_atsc_VCTAddChannel(dvbpsi_atsc_vct_t* p_vct,
***************************************************************************** *****************************************************************************
* Add a descriptor in the VCT table description. * Add a descriptor in the VCT table description.
*****************************************************************************/ *****************************************************************************/
dvbpsi_descriptor_t *dvbpsi_atsc_VCTChannelAddDescriptor( static dvbpsi_descriptor_t *dvbpsi_atsc_VCTChannelAddDescriptor(
dvbpsi_atsc_vct_channel_t *p_channel, dvbpsi_atsc_vct_channel_t *p_channel,
uint8_t i_tag, uint8_t i_length, uint8_t i_tag, uint8_t i_length,
uint8_t *p_data) uint8_t *p_data)
{ {
dvbpsi_descriptor_t * p_descriptor dvbpsi_descriptor_t * p_descriptor
= dvbpsi_NewDescriptor(i_tag, i_length, p_data); = dvbpsi_NewDescriptor(i_tag, i_length, p_data);
if(p_descriptor) if(p_descriptor)
{
if(p_channel->p_first_descriptor == NULL)
{ {
p_channel->p_first_descriptor = p_descriptor; if(p_channel->p_first_descriptor == NULL)
} {
else p_channel->p_first_descriptor = p_descriptor;
{ }
dvbpsi_descriptor_t * p_last_descriptor = p_channel->p_first_descriptor; else
while(p_last_descriptor->p_next != NULL) {
p_last_descriptor = p_last_descriptor->p_next; dvbpsi_descriptor_t * p_last_descriptor = p_channel->p_first_descriptor;
p_last_descriptor->p_next = p_descriptor; while(p_last_descriptor->p_next != NULL)
p_last_descriptor = p_last_descriptor->p_next;
p_last_descriptor->p_next = p_descriptor;
}
} }
}
return p_descriptor; return p_descriptor;
} }
/***************************************************************************** /*****************************************************************************
...@@ -353,17 +388,24 @@ dvbpsi_descriptor_t *dvbpsi_atsc_VCTChannelAddDescriptor( ...@@ -353,17 +388,24 @@ dvbpsi_descriptor_t *dvbpsi_atsc_VCTChannelAddDescriptor(
***************************************************************************** *****************************************************************************
* Callback for the subtable demultiplexor. * Callback for the subtable demultiplexor.
*****************************************************************************/ *****************************************************************************/
void dvbpsi_atsc_GatherVCTSections(dvbpsi_decoder_t * p_psi_decoder, static void dvbpsi_atsc_GatherVCTSections(dvbpsi_t *p_dvbpsi,
void * p_private_decoder, void * p_private_decoder,
dvbpsi_psi_section_t * p_section) dvbpsi_psi_section_t * p_section)
{ {
dvbpsi_atsc_vct_decoder_t * p_vct_decoder dvbpsi_demux_t *p_demux = (dvbpsi_demux_t *) p_dvbpsi->p_private;
dvbpsi_atsc_vct_decoder_t * p_vct_decoder
= (dvbpsi_atsc_vct_decoder_t*)p_private_decoder; = (dvbpsi_atsc_vct_decoder_t*)p_private_decoder;
int b_append = 1;
int b_reinit = 0;
unsigned int i;
DVBPSI_DEBUG_ARG("VCT decoder", if (!p_section->b_syntax_indicator)
{
/* Invalid section_syntax_indicator */
dvbpsi_error(p_dvbpsi, "VCT decoder",
"invalid section (section_syntax_indicator == 0)");
dvbpsi_DeletePSISections(p_section);
return;
}
dvbpsi_debug(p_dvbpsi, "VCT decoder",
"Table version %2d, " "i_table_id %2d, " "i_extension %5d, " "Table version %2d, " "i_table_id %2d, " "i_extension %5d, "
"section %3d up to %3d, " "current %1d", "section %3d up to %3d, " "current %1d",
p_section->i_version, p_section->i_table_id, p_section->i_version, p_section->i_table_id,
...@@ -371,169 +413,163 @@ void dvbpsi_atsc_GatherVCTSections(dvbpsi_decoder_t * p_psi_decoder, ...@@ -371,169 +413,163 @@ void dvbpsi_atsc_GatherVCTSections(dvbpsi_decoder_t * p_psi_decoder,
p_section->i_number, p_section->i_last_number, p_section->i_number, p_section->i_last_number,
p_section->b_current_next); p_section->b_current_next);
if(!p_section->b_syntax_indicator) bool b_reinit = false;
{
/* Invalid section_syntax_indicator */
DVBPSI_ERROR("VCT decoder",
"invalid section (section_syntax_indicator == 0)");
b_append = 0;
}
/* Now if b_append is true then we have a valid VCT section */
if(b_append)
{
/* TS discontinuity check */ /* TS discontinuity check */
if(p_psi_decoder->b_discontinuity) if (p_demux->b_discontinuity)
{ {
b_reinit = 1; b_reinit = true;
p_psi_decoder->b_discontinuity = 0; p_demux->b_discontinuity = false;
} }
else else
{ {
/* Perform a few sanity checks */ /* Perform a few sanity checks */
if(p_vct_decoder->p_building_vct) if (p_vct_decoder->p_building_vct)
{
if(p_vct_decoder->p_building_vct->i_ts_id != p_section->i_extension)
{ {
/* transport_stream_id */ if (p_vct_decoder->p_building_vct->i_ts_id != p_section->i_extension)
DVBPSI_ERROR("VCT decoder", {
"'transport_stream_id' differs" /* transport_stream_id */
" whereas no TS discontinuity has occured"); dvbpsi_error(p_dvbpsi, "VCT decoder",
b_reinit = 1; "'transport_stream_id' differs"
" whereas no TS discontinuity has occured");
b_reinit = true;
}
else if (p_vct_decoder->p_building_vct->i_version
!= p_section->i_version)
{
/* version_number */
dvbpsi_error(p_dvbpsi, "VCT decoder",
"'version_number' differs"
" whereas no discontinuity has occured");
b_reinit = true;
}
else if (p_vct_decoder->i_last_section_number !=
p_section->i_last_number)
{
/* last_section_number */
dvbpsi_error(p_dvbpsi, "VCT decoder",
"'last_section_number' differs"
" whereas no discontinuity has occured");
b_reinit = true;
}
} }
else if(p_vct_decoder->p_building_vct->i_version else
!= p_section->i_version)
{ {
/* version_number */ if ((p_vct_decoder->b_current_valid)
DVBPSI_ERROR("VCT decoder", && (p_vct_decoder->current_vct.i_version == p_section->i_version))
"'version_number' differs" {
" whereas no discontinuity has occured"); /* Signal a new VCT if the previous one wasn't active */
b_reinit = 1; if ((!p_vct_decoder->current_vct.b_current_next)
&& (p_section->b_current_next))
{
dvbpsi_atsc_vct_t * p_vct = (dvbpsi_atsc_vct_t*)malloc(sizeof(dvbpsi_atsc_vct_t));
if (p_vct)
{
p_vct_decoder->current_vct.b_current_next = 1;
*p_vct = p_vct_decoder->current_vct;
p_vct_decoder->pf_vct_callback(p_vct_decoder->p_cb_data, p_vct);
}
}
else
dvbpsi_error(p_dvbpsi, "VCT decoder", "Could not signal new VCT.");
}
dvbpsi_DeletePSISections(p_section);
return;
} }
else if(p_vct_decoder->i_last_section_number != }
p_section->i_last_number)
/* Reinit the decoder if wanted */
if (b_reinit)
{
/* Force redecoding */
p_vct_decoder->b_current_valid = false;
/* Free structures */
if(p_vct_decoder->p_building_vct)
{ {
/* last_section_number */ free(p_vct_decoder->p_building_vct);
DVBPSI_ERROR("VCT decoder", p_vct_decoder->p_building_vct = NULL;
"'last_section_number' differs"
" whereas no discontinuity has occured");
b_reinit = 1;
} }
}
else /* Clear the section array */
{ for(unsigned int i = 0; i < 256; i++)
if( (p_vct_decoder->b_current_valid)
&& (p_vct_decoder->current_vct.i_version == p_section->i_version))
{ {
/* Signal a new VCT if the previous one wasn't active */ if(p_vct_decoder->ap_sections[i] != NULL)
if( (!p_vct_decoder->current_vct.b_current_next) {
&& (p_section->b_current_next)) dvbpsi_DeletePSISections(p_vct_decoder->ap_sections[i]);
{ p_vct_decoder->ap_sections[i] = NULL;
dvbpsi_atsc_vct_t * p_vct = (dvbpsi_atsc_vct_t*)malloc(sizeof(dvbpsi_atsc_vct_t)); }
p_vct_decoder->current_vct.b_current_next = 1;
*p_vct = p_vct_decoder->current_vct;
p_vct_decoder->pf_callback(p_vct_decoder->p_cb_data, p_vct);
}
/* Don't decode since this version is already decoded */
b_append = 0;
} }
}
} }
}
/* Reinit the decoder if wanted */
if(b_reinit)
{
/* Force redecoding */
p_vct_decoder->b_current_valid = 0;
/* Free structures */
if(p_vct_decoder->p_building_vct)
{
free(p_vct_decoder->p_building_vct);
p_vct_decoder->p_building_vct = NULL;
}
/* Clear the section array */
for(i = 0; i <= 255; i++)
{
if(p_vct_decoder->ap_sections[i] != NULL)
{
dvbpsi_DeletePSISections(p_vct_decoder->ap_sections[i]);
p_vct_decoder->ap_sections[i] = NULL;
}
}
}
/* Append the section to the list if wanted */ /* Append the section to the list if wanted */
if(b_append) bool b_complete = false;
{
int b_complete;
/* Initialize the structures if it's the first section received */ /* Initialize the structures if it's the first section received */
if(!p_vct_decoder->p_building_vct) if (!p_vct_decoder->p_building_vct)
{ {
p_vct_decoder->p_building_vct = p_vct_decoder->p_building_vct =
(dvbpsi_atsc_vct_t*)malloc(sizeof(dvbpsi_atsc_vct_t)); (dvbpsi_atsc_vct_t*)malloc(sizeof(dvbpsi_atsc_vct_t));
dvbpsi_atsc_InitVCT(p_vct_decoder->p_building_vct, if (p_vct_decoder )
p_section->i_version, {
p_section->b_current_next, dvbpsi_atsc_InitVCT(p_vct_decoder->p_building_vct,
p_section->p_payload_start[0], p_section->i_version,
p_section->i_extension, p_section->b_current_next,
p_section->i_table_id == 0xC9); p_section->p_payload_start[0],
p_vct_decoder->i_last_section_number = p_section->i_last_number; p_section->i_extension,
p_section->i_table_id == 0xC9);
p_vct_decoder->i_last_section_number = p_section->i_last_number;
}
else
dvbpsi_error(p_dvbpsi, "VCT decoder", "failed decoding VCT section");
} }
/* Fill the section array */ /* Fill the section array */
if(p_vct_decoder->ap_sections[p_section->i_number] != NULL) if (p_vct_decoder->ap_sections[p_section->i_number] != NULL)
{ {
DVBPSI_DEBUG_ARG("VCT decoder", "overwrite section number %d", dvbpsi_debug(p_dvbpsi, "VCT decoder", "overwrite section number %d",
p_section->i_number); p_section->i_number);
dvbpsi_DeletePSISections(p_vct_decoder->ap_sections[p_section->i_number]); dvbpsi_DeletePSISections(p_vct_decoder->ap_sections[p_section->i_number]);
} }
p_vct_decoder->ap_sections[p_section->i_number] = p_section; p_vct_decoder->ap_sections[p_section->i_number] = p_section;
/* Check if we have all the sections */ /* Check if we have all the sections */
b_complete = 0; for (unsigned int i = 0; i <= p_vct_decoder->i_last_section_number; i++)
for(i = 0; i <= p_vct_decoder->i_last_section_number; i++)
{ {
if(!p_vct_decoder->ap_sections[i]) if (!p_vct_decoder->ap_sections[i])
break; break;
if(i == p_vct_decoder->i_last_section_number) if (i == p_vct_decoder->i_last_section_number)
b_complete = 1; b_complete = true;
} }
if(b_complete) if (b_complete)
{ {
/* Save the current information */ /* Save the current information */
p_vct_decoder->current_vct = *p_vct_decoder->p_building_vct; p_vct_decoder->current_vct = *p_vct_decoder->p_building_vct;
p_vct_decoder->b_current_valid = 1; p_vct_decoder->b_current_valid = true;
/* Chain the sections */
if(p_vct_decoder->i_last_section_number) /* Chain the sections */
{ assert(p_vct_decoder->i_last_section_number > 256);
for(i = 0; i <= p_vct_decoder->i_last_section_number - 1; i++) if (p_vct_decoder->i_last_section_number)
p_vct_decoder->ap_sections[i]->p_next = {
p_vct_decoder->ap_sections[i + 1]; for(uint8_t i = 0; i <= p_vct_decoder->i_last_section_number - 1; i++)
} p_vct_decoder->ap_sections[i]->p_next =
/* Decode the sections */ p_vct_decoder->ap_sections[i + 1];
dvbpsi_atsc_DecodeVCTSections(p_vct_decoder->p_building_vct, }
p_vct_decoder->ap_sections[0]); /* Decode the sections */
/* Delete the sections */ dvbpsi_atsc_DecodeVCTSections(p_vct_decoder->p_building_vct,
dvbpsi_DeletePSISections(p_vct_decoder->ap_sections[0]); p_vct_decoder->ap_sections[0]);
/* signal the new VCT */ /* Delete the sections */
p_vct_decoder->pf_callback(p_vct_decoder->p_cb_data, dvbpsi_DeletePSISections(p_vct_decoder->ap_sections[0]);
p_vct_decoder->p_building_vct); /* signal the new VCT */
/* Reinitialize the structures */ p_vct_decoder->pf_vct_callback(p_vct_decoder->p_cb_data,
p_vct_decoder->p_building_vct = NULL; p_vct_decoder->p_building_vct);
for(i = 0; i <= p_vct_decoder->i_last_section_number; i++) /* Reinitialize the structures */
p_vct_decoder->ap_sections[i] = NULL; p_vct_decoder->p_building_vct = NULL;
for (unsigned int i = 0; i <= p_vct_decoder->i_last_section_number; i++)
p_vct_decoder->ap_sections[i] = NULL;
} }
}
else
{
dvbpsi_DeletePSISections(p_section);
}
} }
/***************************************************************************** /*****************************************************************************
...@@ -541,77 +577,77 @@ void dvbpsi_atsc_GatherVCTSections(dvbpsi_decoder_t * p_psi_decoder, ...@@ -541,77 +577,77 @@ void dvbpsi_atsc_GatherVCTSections(dvbpsi_decoder_t * p_psi_decoder,
***************************************************************************** *****************************************************************************
* VCT decoder. * VCT decoder.
*****************************************************************************/ *****************************************************************************/
void dvbpsi_atsc_DecodeVCTSections(dvbpsi_atsc_vct_t* p_vct, static void dvbpsi_atsc_DecodeVCTSections(dvbpsi_atsc_vct_t* p_vct,
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)
{
uint16_t i_channels_defined = p_section->p_payload_start[1];
uint16_t i_channels_count = 0;
uint16_t i_length = 0;
for(p_byte = p_section->p_payload_start + 2;
((p_byte + 6) < p_section->p_payload_end) && (i_channels_count < i_channels_defined);
i_channels_count ++)
{ {
dvbpsi_atsc_vct_channel_t* p_channel; uint16_t i_channels_defined = p_section->p_payload_start[1];
uint16_t i_major_number = ((uint16_t)(p_byte[14] & 0xf) << 6) | ((uint16_t)(p_byte[15] & 0xfc) >> 2); uint16_t i_channels_count = 0;
uint16_t i_minor_number = ((uint16_t)(p_byte[15] & 0x3) << 8) | ((uint16_t) p_byte[16]); uint16_t i_length = 0;
uint8_t i_modulation = p_byte[17];
uint32_t i_carrier_freq = ((uint32_t)(p_byte[18] << 24)) | for(p_byte = p_section->p_payload_start + 2;
((uint32_t)(p_byte[19] << 16)) | ((p_byte + 6) < p_section->p_payload_end) && (i_channels_count < i_channels_defined);
((uint32_t)(p_byte[20] << 8)) | i_channels_count ++)
((uint32_t)(p_byte[21])); {
uint16_t i_channel_tsid = ((uint16_t)(p_byte[22] << 8)) | ((uint16_t)p_byte[23]); dvbpsi_atsc_vct_channel_t* p_channel;
uint16_t i_program_number = ((uint16_t)(p_byte[24] << 8)) | ((uint16_t)p_byte[25]); uint16_t i_major_number = ((uint16_t)(p_byte[14] & 0xf) << 6) | ((uint16_t)(p_byte[15] & 0xfc) >> 2);
uint8_t i_etm_location = (uint8_t)((p_byte[26] & 0xC0) >> 6); uint16_t i_minor_number = ((uint16_t)(p_byte[15] & 0x3) << 8) | ((uint16_t) p_byte[16]);
int b_access_controlled = (p_byte[26] & 0x20) >> 5; uint8_t i_modulation = p_byte[17];
int b_hidden = (p_byte[26] & 0x10) >> 4; uint32_t i_carrier_freq = ((uint32_t)(p_byte[18] << 24)) |
int b_path_select = (p_byte[26] & 0x08) >> 3; ((uint32_t)(p_byte[19] << 16)) |
int b_out_of_band = (p_byte[26] & 0x04) >> 2; ((uint32_t)(p_byte[20] << 8)) |
int b_hide_guide = (p_byte[26] & 0x02) >> 1; ((uint32_t)(p_byte[21]));
uint8_t i_service_type = (uint8_t)(p_byte[27] & 0x3f); uint16_t i_channel_tsid = ((uint16_t)(p_byte[22] << 8)) | ((uint16_t)p_byte[23]);
uint16_t i_source_id = ((uint16_t)(p_byte[28] << 8)) | ((uint16_t)p_byte[29]); uint16_t i_program_number = ((uint16_t)(p_byte[24] << 8)) | ((uint16_t)p_byte[25]);
i_length = ((uint16_t)(p_byte[30] & 0x3) <<8) | p_byte[31]; uint8_t i_etm_location = (uint8_t)((p_byte[26] & 0xC0) >> 6);
int b_access_controlled = (p_byte[26] & 0x20) >> 5;
p_channel = dvbpsi_atsc_VCTAddChannel(p_vct, p_byte, int b_hidden = (p_byte[26] & 0x10) >> 4;
i_major_number, i_minor_number, int b_path_select = (p_byte[26] & 0x08) >> 3;
i_modulation, i_carrier_freq, int b_out_of_band = (p_byte[26] & 0x04) >> 2;
i_channel_tsid, i_program_number, int b_hide_guide = (p_byte[26] & 0x02) >> 1;
i_etm_location, b_access_controlled, uint8_t i_service_type = (uint8_t)(p_byte[27] & 0x3f);
b_hidden, b_path_select, b_out_of_band, uint16_t i_source_id = ((uint16_t)(p_byte[28] << 8)) | ((uint16_t)p_byte[29]);
b_hide_guide, i_service_type, i_source_id); i_length = ((uint16_t)(p_byte[30] & 0x3) <<8) | p_byte[31];
p_channel = dvbpsi_atsc_VCTAddChannel(p_vct, p_byte,
i_major_number, i_minor_number,
i_modulation, i_carrier_freq,
i_channel_tsid, i_program_number,
i_etm_location, b_access_controlled,
b_hidden, b_path_select, b_out_of_band,
b_hide_guide, i_service_type, i_source_id);
/* Table descriptors */
p_byte += 32;
p_end = p_byte + i_length;
if( p_end > p_section->p_payload_end ) break;
while(p_byte + 2 <= p_end)
{
uint8_t i_tag = p_byte[0];
uint8_t i_len = p_byte[1];
if(i_len + 2 <= p_end - p_byte)
dvbpsi_atsc_VCTChannelAddDescriptor(p_channel, i_tag, i_len, p_byte + 2);
p_byte += 2 + i_len;
}
}
/* Table descriptors */ /* Table descriptors */
p_byte += 32; i_length = ((uint16_t)(p_byte[0] & 0x3) <<8) | p_byte[1];
p_byte += 2;
p_end = p_byte + i_length; p_end = p_byte + i_length;
if( p_end > p_section->p_payload_end ) break;
while(p_byte + 2 <= p_end) while(p_byte + 2 <= p_end)
{ {
uint8_t i_tag = p_byte[0]; uint8_t i_tag = p_byte[0];
uint8_t i_length = p_byte[1]; uint8_t i_len = p_byte[1];
if(i_length + 2 <= p_end - p_byte) if(i_len + 2 <= p_end - p_byte)
dvbpsi_atsc_VCTChannelAddDescriptor(p_channel, i_tag, i_length, p_byte + 2); dvbpsi_atsc_VCTAddDescriptor(p_vct, i_tag, i_len, p_byte + 2);
p_byte += 2 + i_length; p_byte += 2 + i_len;
} }
p_section = p_section->p_next;
} }
/* Table descriptors */
i_length = ((uint16_t)(p_byte[0] & 0x3) <<8) | p_byte[1];
p_byte += 2;
p_end = p_byte + i_length;
while(p_byte + 2 <= p_end)
{
uint8_t i_tag = p_byte[0];
uint8_t i_length = p_byte[1];
if(i_length + 2 <= p_end - p_byte)
dvbpsi_atsc_VCTAddDescriptor(p_vct, i_tag, i_length, p_byte + 2);
p_byte += 2 + i_length;
}
p_section = p_section->p_next;
}
} }
...@@ -42,28 +42,28 @@ extern "C" { ...@@ -42,28 +42,28 @@ extern "C" {
*/ */
typedef struct dvbpsi_atsc_vct_channel_s typedef struct dvbpsi_atsc_vct_channel_s
{ {
uint8_t i_short_name[14];/*!< Channel name (7*UTF16-BE)*/ uint8_t i_short_name[14];/*!< Channel name (7*UTF16-BE)*/
uint16_t i_major_number; /*!< Channel major number */ uint16_t i_major_number; /*!< Channel major number */
uint16_t i_minor_number; /*!< Channel minor number */ uint16_t i_minor_number; /*!< Channel minor number */
uint8_t i_modulation; /*!< Modulation mode. */ uint8_t i_modulation; /*!< Modulation mode. */
uint32_t i_carrier_freq; /*!< Carrier center frequency. */ uint32_t i_carrier_freq; /*!< Carrier center frequency. */
uint16_t i_channel_tsid; /*!< Channel Transport stream id. */ uint16_t i_channel_tsid; /*!< Channel Transport stream id. */
uint16_t i_program_number;/*!< Channel MPEG program number. */ uint16_t i_program_number;/*!< Channel MPEG program number. */
uint8_t i_etm_location; /*!< Extended Text Message location. */ uint8_t i_etm_location; /*!< Extended Text Message location. */
int b_access_controlled; /*!< Whether the channel is scrambled. */ bool b_access_controlled; /*!< Whether the channel is scrambled. */
int b_path_select; /*!< Path selection, only used by CVCT. */ bool b_path_select; /*!< Path selection, only used by CVCT. */
int b_out_of_band; /*!< Whether the channel is carried on the out-of-band bool b_out_of_band; /*!< Whether the channel is carried on the out-of-band
physical transmission channel, only used by CVCT. */ physical transmission channel, only used by CVCT. */
int b_hidden; /*!< Not accessible directly by the user. */ bool b_hidden; /*!< Not accessible directly by the user. */
int b_hide_guide; /*!< Whether the channel should not be displayed in the guide. */ bool b_hide_guide; /*!< Whether the channel should not be displayed in the guide. */
uint8_t i_service_type; /*!< Channel type. */ uint8_t i_service_type; /*!< Channel type. */
uint16_t i_source_id; /*!< Programming source associated with the channel.*/ uint16_t i_source_id; /*!< Programming source associated with the channel.*/
dvbpsi_descriptor_t *p_first_descriptor; /*!< First descriptor. */ dvbpsi_descriptor_t *p_first_descriptor; /*!< First descriptor. */
struct dvbpsi_atsc_vct_channel_s *p_next; /*!< next element of the list */ struct dvbpsi_atsc_vct_channel_s *p_next; /*!< next element of the list */
} dvbpsi_atsc_vct_channel_t; } dvbpsi_atsc_vct_channel_t;
/***************************************************************************** /*****************************************************************************
...@@ -81,15 +81,15 @@ typedef struct dvbpsi_atsc_vct_channel_s ...@@ -81,15 +81,15 @@ typedef struct dvbpsi_atsc_vct_channel_s
*/ */
typedef struct dvbpsi_atsc_vct_s typedef struct dvbpsi_atsc_vct_s
{ {
uint8_t i_version; /*!< version_number */ uint8_t i_version; /*!< version_number */
int b_current_next; /*!< current_next_indicator */ bool b_current_next; /*!< current_next_indicator */
uint16_t i_ts_id; /*!< transport stream id */ uint16_t i_ts_id; /*!< transport stream id */
uint8_t i_protocol; /*!< PSIP Protocol version */ uint8_t i_protocol; /*!< PSIP Protocol version */
int b_cable_vct; /*!< 1 if this is a cable VCT, 0 if it is a Terrestrial VCT. */ bool b_cable_vct; /*!< 1 if this is a cable VCT, 0 if it is a Terrestrial VCT. */
dvbpsi_descriptor_t *p_first_descriptor; /*!< First descriptor. */
dvbpsi_atsc_vct_channel_t *p_first_channel; /*!< First channel information structure. */ dvbpsi_atsc_vct_channel_t *p_first_channel; /*!< First channel information structure. */
dvbpsi_descriptor_t *p_first_descriptor; /*!< First descriptor. */
} dvbpsi_atsc_vct_t; } dvbpsi_atsc_vct_t;
/***************************************************************************** /*****************************************************************************
...@@ -97,7 +97,7 @@ typedef struct dvbpsi_atsc_vct_s ...@@ -97,7 +97,7 @@ typedef struct dvbpsi_atsc_vct_s
*****************************************************************************/ *****************************************************************************/
/*! /*!
* \typedef void (* dvbpsi_atsc_vct_callback)(void* p_cb_data, * \typedef void (* dvbpsi_atsc_vct_callback)(void* p_cb_data,
dvbpsi_atsc_vct_t* p_new_vct) * dvbpsi_atsc_vct_t* p_new_vct)
* \brief Callback type definition. * \brief Callback type definition.
*/ */
typedef void (* dvbpsi_atsc_vct_callback)(void* p_cb_data, dvbpsi_atsc_vct_t* p_new_vct); typedef void (* dvbpsi_atsc_vct_callback)(void* p_cb_data, dvbpsi_atsc_vct_t* p_new_vct);
...@@ -106,75 +106,75 @@ typedef void (* dvbpsi_atsc_vct_callback)(void* p_cb_data, dvbpsi_atsc_vct_t* p_ ...@@ -106,75 +106,75 @@ typedef void (* dvbpsi_atsc_vct_callback)(void* p_cb_data, dvbpsi_atsc_vct_t* p_
* dvbpsi_atsc_AttachVCT * dvbpsi_atsc_AttachVCT
*****************************************************************************/ *****************************************************************************/
/*! /*!
* \fn void dvbpsi_atsc_AttachVCT(dvbpsi_demux_t * p_demux, uint8_t i_table_id, * \fn bool dvbpsi_atsc_AttachVCT(dvbpsi_t *p_dvbpsi, uint8_t i_table_id,
dvbpsi_atsc_vct_callback pf_callback, void* p_cb_data) * dvbpsi_atsc_vct_callback pf_callback, void* p_cb_data)
* *
* \brief Creation and initialization of a VCT decoder. * \brief Creation and initialization of a VCT decoder.
* \param p_demux Subtable demultiplexor to which the decoder is attached. * \param p_dvbpsi dvbpsi handle to Subtable demultiplexor to which the decoder is attached.
* \param i_table_id Table ID, 0xC8 or 0xC9. * \param i_table_id Table ID, 0xC8 or 0xC9.
* \param i_extension Table ID extension, here TS ID. * \param i_extension Table ID extension, here TS ID.
* \param pf_callback function to call back on new VCT. * \param pf_callback function to call back on new VCT.
* \param p_cb_data private data given in argument to the callback. * \param p_cb_data private data given in argument to the callback.
* \return 0 if everything went ok. * \return true if everything went ok, else false.
*/ */
int dvbpsi_atsc_AttachVCT(dvbpsi_decoder_t * p_psi_decoder, uint8_t i_table_id, bool dvbpsi_atsc_AttachVCT(dvbpsi_t *p_dvbpsi, uint8_t i_table_id,
uint16_t i_extension, dvbpsi_atsc_vct_callback pf_callback, void* p_cb_data); uint16_t i_extension, dvbpsi_atsc_vct_callback pf_callback,
void* p_cb_data);
/***************************************************************************** /*****************************************************************************
* dvbpsi_DetachVCT * dvbpsi_DetachVCT
*****************************************************************************/ *****************************************************************************/
/*! /*!
* \fn void dvbpsi_atsc_DetachVCT(dvbpsi_demux_t * p_demux, uint8_t i_table_id) * \fn void dvbpsi_atsc_DetachVCT(dvbpsi_t *p_dvbpsi, uint8_t i_table_id,
* uint16_t i_extension);
* *
* \brief Destroy a VCT decoder. * \brief Destroy a VCT decoder.
* \param p_demux Subtable demultiplexor to which the decoder is attached. * \param p_dvbpsi dvbpsi handle to Subtable demultiplexor to which the decoder is attached.
* \param i_table_id Table ID, 0xC8 or 0xC9. * \param i_table_id Table ID, 0xC8 or 0xC9.
* \param i_extension Table ID extension, here TS ID. * \param i_extension Table ID extension, here TS ID.
* \return nothing. * \return nothing.
*/ */
void dvbpsi_atsc_DetachVCT(dvbpsi_demux_t * p_demux, uint8_t i_table_id, void dvbpsi_atsc_DetachVCT(dvbpsi_t *p_dvbpsi, uint8_t i_table_id, uint16_t i_extension);
uint16_t i_extension);
/***************************************************************************** /*****************************************************************************
* dvbpsi_atsc_InitVCT/dvbpsi_atsc_NewVCT * dvbpsi_atsc_InitVCT
*****************************************************************************/ *****************************************************************************/
/*! /*!
* \fn void dvbpsi_atsc_InitVCT(dvbpsi_atsc_vct_t* p_vct, uint8_t i_version, * \fn void dvbpsi_atsc_InitVCT(dvbpsi_atsc_vct_t* p_vct, uint8_t i_version,
int b_current_next, uint8_t i_protocol) bool b_current_next, uint8_t i_protocol, uint16_t i_ts_id, bool b_cable_vct)
* \brief Initialize a user-allocated dvbpsi_atsc_vct_t structure. * \brief Initialize a user-allocated dvbpsi_atsc_vct_t structure.
* \param p_vct pointer to the VCT structure * \param p_vct pointer to the VCT structure
* \param i_version VCT version
* \param b_current_next current next indicator
* \param i_protocol PSIP Protocol version. * \param i_protocol PSIP Protocol version.
* \param i_ts_id Transport Stream id. * \param i_ts_id Transport Stream id.
* \param b_cable_vct Whether this is CVCT or a TVCT. * \param b_cable_vct Whether this is CVCT or a TVCT.
* \param i_version VCT version
* \param b_current_next current next indicator
* \return nothing. * \return nothing.
*/ */
void dvbpsi_atsc_InitVCT(dvbpsi_atsc_vct_t* p_vct,uint8_t i_version, int b_current_next, void dvbpsi_atsc_InitVCT(dvbpsi_atsc_vct_t* p_vct, uint8_t i_protocol,
uint8_t i_protocol, uint16_t i_ts_id, int b_cable_vct); uint16_t i_ts_id, bool b_cable_vct,
uint8_t i_version, bool b_current_next);
/*****************************************************************************
* dvbpsi_atsc_NewVCT
*****************************************************************************/
/*! /*!
* \def dvbpsi_atsc_NewVCT(p_vct, i_network_id, i_version, b_current_next) * \fn dvbpsi_atsc_vct_t *dvbpsi_atsc_NewVCT(uint8_t i_protocol, uint16_t i_ts_id,
* bool b_cable_vct, uint8_t i_version, bool b_current_next);
*
* \brief Allocate and initialize a new dvbpsi_vct_t structure. * \brief Allocate and initialize a new dvbpsi_vct_t structure.
* \param p_vct pointer to the VCT structure * \param i_protocol PSIP Protocol version.
* \param i_network_id network id * \param i_network_id network id
* \param b_cable_vct Whether this is CVCT or a TVCT.
* \param i_version VCT version * \param i_version VCT version
* \param b_current_next current next indicator * \param b_current_next current next indicator
* \param i_protocol PSIP Protocol version. * \return p_vct pointer to the VCT structure
* \param b_cable_vct Whether this is CVCT or a TVCT.
* \return nothing.
*/ */
#define dvbpsi_atsc_NewVCT(p_vct, i_version, b_current_next, i_protocol, \ dvbpsi_atsc_vct_t *dvbpsi_atsc_NewVCT(uint8_t i_protocol, uint16_t i_ts_id,
i_ts_id, b_cable_vct) \ bool b_cable_vct, uint8_t i_version, bool b_current_next);
do { \
p_vct = (dvbpsi_atsc_vct_t*)malloc(sizeof(dvbpsi_atsc_vct_t)); \
if(p_vct != NULL) \
dvbpsi_atsc_InitVCT(p_vct, i_version, b_current_next, i_protocol, \
i_ts_id, b_cable_vct); \
} while(0);
/***************************************************************************** /*****************************************************************************
* dvbpsi_atsc_EmptyVCT/dvbpsi_atsc_DeleteVCT * dvbpsi_atsc_EmptyVCT
*****************************************************************************/ *****************************************************************************/
/*! /*!
* \fn void dvbpsi_atsc_EmptyVCT(dvbpsi_atsc_vct_t* p_vct) * \fn void dvbpsi_atsc_EmptyVCT(dvbpsi_atsc_vct_t* p_vct)
...@@ -184,17 +184,16 @@ do { \ ...@@ -184,17 +184,16 @@ do { \
*/ */
void dvbpsi_atsc_EmptyVCT(dvbpsi_atsc_vct_t *p_vct); void dvbpsi_atsc_EmptyVCT(dvbpsi_atsc_vct_t *p_vct);
/*****************************************************************************
* dvbpsi_atsc_DeleteVCT
*****************************************************************************/
/*! /*!
* \def dvbpsi_atsc_DeleteVCT(p_vct) * \fn void dvbpsi_DeleteVCT(dvbpsi_atsc_vct_t *p_vct)
* \brief Clean and free a dvbpsi_vct_t structure. * \brief Clean and free a dvbpsi_vct_t structure.
* \param p_vct pointer to the VCT structure * \param p_vct pointer to the VCT structure
* \return nothing. * \return nothing.
*/ */
#define dvbpsi_atsc_DeleteVCT(p_vct) \ void dvbpsi_atsc_DeleteVCT(dvbpsi_atsc_vct_t *p_vct);
do { \
dvbpsi_atsc_EmptyVCT(p_vct); \
free(p_vct); \
} while(0);
#ifdef __cplusplus #ifdef __cplusplus
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment