📄 atsc_mgt.c
字号:
/*
Copyright (C) 2006 Adam Charrett
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
mgt.c
Decode PSIP Master Guide Table.
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include "dvbpsi.h"
#include "dvbpsi_private.h"
#include "psi.h"
#include "descriptor.h"
#include "demux.h"
#include "atsc/mgt.h"
#include "objects.h"
typedef struct dvbpsi_atsc_mgt_decoder_s
{
dvbpsi_atsc_mgt_callback pf_callback;
void * p_cb_data;
dvbpsi_atsc_mgt_t current_mgt;
dvbpsi_atsc_mgt_t * p_building_mgt;
int b_current_valid;
uint8_t i_last_section_number;
dvbpsi_psi_section_t * ap_sections [256];
} dvbpsi_atsc_mgt_decoder_t;
dvbpsi_descriptor_t *dvbpsi_atsc_MGTAddDescriptor(
dvbpsi_atsc_mgt_t *p_mgt,
uint8_t i_tag, uint8_t i_length,
uint8_t *p_data);
dvbpsi_atsc_mgt_table_t *dvbpsi_atsc_MGTAddTable(dvbpsi_atsc_mgt_t* p_mgt,
uint16_t i_type,
uint16_t i_pid,
uint8_t i_version,
uint32_t i_number_bytes);
dvbpsi_descriptor_t *dvbpsi_atsc_MGTTableAddDescriptor(
dvbpsi_atsc_mgt_table_t *p_table,
uint8_t i_tag, uint8_t i_length,
uint8_t *p_data);
void dvbpsi_atsc_GatherMGTSections(dvbpsi_decoder_t * p_psi_decoder,
void * p_private_decoder,
dvbpsi_psi_section_t * p_section);
void dvbpsi_atsc_DecodeMGTSections(dvbpsi_atsc_mgt_t* p_mgt,
dvbpsi_psi_section_t* p_section);
/*****************************************************************************
* dvbpsi_atsc_AttachMGT
*****************************************************************************
* Initialize a MGT subtable decoder.
*****************************************************************************/
int dvbpsi_atsc_AttachMGT(dvbpsi_decoder_t * p_psi_decoder, uint8_t i_table_id,
dvbpsi_atsc_mgt_callback pf_callback, void* p_cb_data)
{
dvbpsi_demux_t* p_demux = (dvbpsi_demux_t*)p_psi_decoder->p_private_decoder;
dvbpsi_demux_subdec_t* p_subdec;
dvbpsi_atsc_mgt_decoder_t* p_mgt_decoder;
unsigned int i;
if(dvbpsi_demuxGetSubDec(p_demux, i_table_id, 0))
{
DVBPSI_ERROR_ARG("MGT decoder",
"Already a decoder for (table_id == 0x%02x)",
i_table_id);
return 1;
}
p_subdec = (dvbpsi_demux_subdec_t*)malloc(sizeof(dvbpsi_demux_subdec_t));
if(p_subdec == NULL)
{
return 1;
}
p_mgt_decoder = (dvbpsi_atsc_mgt_decoder_t*)malloc(sizeof(dvbpsi_atsc_mgt_decoder_t));
if(p_mgt_decoder == NULL)
{
free(p_subdec);
return 1;
}
/* subtable decoder configuration */
p_subdec->pf_callback = &dvbpsi_atsc_GatherMGTSections;
p_subdec->p_cb_data = p_mgt_decoder;
p_subdec->i_id = (uint32_t)i_table_id << 16;
p_subdec->pf_detach = dvbpsi_atsc_DetachMGT;
/* Attach the subtable decoder to the demux */
p_subdec->p_next = p_demux->p_first_subdec;
p_demux->p_first_subdec = p_subdec;
/* MGT decoder information */
p_mgt_decoder->pf_callback = pf_callback;
p_mgt_decoder->p_cb_data = p_cb_data;
/* MGT decoder initial state */
p_mgt_decoder->b_current_valid = 0;
p_mgt_decoder->p_building_mgt = NULL;
for(i = 0; i <= 255; i++)
p_mgt_decoder->ap_sections[i] = NULL;
return 0;
}
/*****************************************************************************
* dvbpsi_atsc_DetachMGT
*****************************************************************************
* Close a MGT decoder.
*****************************************************************************/
void dvbpsi_atsc_DetachMGT(dvbpsi_demux_t * p_demux, uint8_t i_table_id, uint16_t i_extension)
{
dvbpsi_demux_subdec_t* p_subdec;
dvbpsi_demux_subdec_t** pp_prev_subdec;
dvbpsi_atsc_mgt_decoder_t* p_mgt_decoder;
unsigned int i;
p_subdec = dvbpsi_demuxGetSubDec(p_demux, i_table_id, 0);
if(p_demux == NULL)
{
DVBPSI_ERROR_ARG("MGT Decoder",
"No such MGT decoder (table_id == 0x%02x,"
"extension == 0x00)",
i_table_id);
return;
}
p_mgt_decoder = (dvbpsi_atsc_mgt_decoder_t*)p_subdec->p_cb_data;
if (p_mgt_decoder->p_building_mgt)
{
ObjectRefDec(p_mgt_decoder->p_building_mgt);
}
for(i = 0; i <= 255; i++)
{
if(p_mgt_decoder->ap_sections[i])
dvbpsi_DeletePSISections(p_mgt_decoder->ap_sections[i]);
}
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_subdec->p_next;
free(p_subdec);
}
/*****************************************************************************
* dvbpsi_InitMGT
*****************************************************************************
* Initialize a pre-allocated dvbpsi_atsc_mgt_t structure.
*****************************************************************************/
void dvbpsi_atsc_InitMGT(dvbpsi_atsc_mgt_t* p_mgt,uint8_t i_version, int b_current_next,
uint8_t i_protocol)
{
p_mgt->i_version = i_version;
p_mgt->b_current_next = b_current_next;
p_mgt->i_protocol = i_protocol;
p_mgt->p_first_table = NULL;
p_mgt->p_first_descriptor = NULL;
}
/*****************************************************************************
* dvbpsi_EmptyMGT
*****************************************************************************
* Clean a dvbpsi_atsc_mgt_t structure.
*****************************************************************************/
void dvbpsi_atsc_EmptyMGT(dvbpsi_atsc_mgt_t* p_mgt)
{
dvbpsi_atsc_mgt_table_t* p_table = p_mgt->p_first_table;
while(p_table != NULL)
{
dvbpsi_atsc_mgt_table_t* p_tmp = p_table->p_next;
dvbpsi_DeleteDescriptors(p_table->p_first_descriptor);
free(p_table);
p_table = p_tmp;
}
dvbpsi_DeleteDescriptors(p_mgt->p_first_descriptor);
p_mgt->p_first_table = NULL;
p_mgt->p_first_descriptor = NULL;
}
/*****************************************************************************
* dvbpsi_atsc_MGTAddDescriptor
*****************************************************************************
* Add a descriptor to the MGT table.
*****************************************************************************/
dvbpsi_descriptor_t *dvbpsi_atsc_MGTAddDescriptor(
dvbpsi_atsc_mgt_t *p_mgt,
uint8_t i_tag, uint8_t i_length,
uint8_t *p_data)
{
dvbpsi_descriptor_t * p_descriptor
= dvbpsi_NewDescriptor(i_tag, i_length, p_data);
if(p_descriptor)
{
if(p_mgt->p_first_descriptor == NULL)
{
p_mgt->p_first_descriptor = p_descriptor;
}
else
{
dvbpsi_descriptor_t * p_last_descriptor = p_mgt->p_first_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;
}
/*****************************************************************************
* dvbpsi_atsc_MGTAddTable
*****************************************************************************
* Add a table description at the end of the MGT.
*****************************************************************************/
dvbpsi_atsc_mgt_table_t *dvbpsi_atsc_MGTAddTable(dvbpsi_atsc_mgt_t* p_mgt,
uint16_t i_type,
uint16_t i_pid,
uint8_t i_version,
uint32_t i_number_bytes)
{
dvbpsi_atsc_mgt_table_t * p_table
= (dvbpsi_atsc_mgt_table_t*)malloc(sizeof(dvbpsi_atsc_mgt_table_t));
if(p_table)
{
p_table->i_type = i_type;
p_table->i_pid = i_pid;
p_table->i_version = i_version;
p_table->i_number_bytes = i_number_bytes;
p_table->p_first_descriptor = NULL;
p_table->p_next = NULL;
if(p_mgt->p_first_table == NULL)
{
p_mgt->p_first_table = p_table;
}
else
{
dvbpsi_atsc_mgt_table_t * p_last_table = p_mgt->p_first_table;
while(p_last_table->p_next != NULL)
p_last_table = p_last_table->p_next;
p_last_table->p_next = p_table;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -