[patch] Add CAT support
Johann Hanne <[email protected]>
| Newsgroups | gmane.comp.video.videolan.libdvbpsi.devel |
|---|---|
| Message-ID | <200708241047.57409.jhml__7483.83356626636$1187948868$gmane$org@gmx.net> |
Hi all, the attached patch adds support for decoding and generating the conditional access tables in mpeg2 transport streams. It has mostly been copy&paste work from the pmt code, so credits go to Arnaud de Bossoreille de Ribou as it was mostly his work. Please apply. Cheers, Johann _______________________________________________ libdvbpsi-devel mailing list [email protected] http://mailman.videolan.org/listinfo/libdvbpsi-devel
libdvbpsi4-0.1.6pre-svn144-cat.diff
(text/x-diff, 27.9 KB)
diff -uNr libdvbpsi4-0.1.6pre-svn144/src/Makefile.am libdvbpsi4-0.1.6pre-svn144-cat/src/Makefile.am
--- libdvbpsi4-0.1.6pre-svn144/src/Makefile.am 2007-08-22 09:47:02.000000000 +0200
+++ libdvbpsi4-0.1.6pre-svn144-cat/src/Makefile.am 2007-08-23 18:24:50.000000000 +0200
@@ -15,6 +15,7 @@
pkginclude_HEADERS = dvbpsi.h psi.h descriptor.h demux.h \
tables/pat.h tables/pmt.h tables/sdt.h tables/eit.h \
+ tables/cat.h \
descriptors/dr_02.h \
descriptors/dr_03.h \
descriptors/dr_04.h \
@@ -67,5 +68,6 @@
tables_src = tables/pat.c tables/pat_private.h \
tables/pmt.c tables/pmt_private.h \
tables/sdt.c tables/sdt_private.h \
- tables/eit.c tables/eit_private.h
+ tables/eit.c tables/eit_private.h \
+ tables/cat.c tables/cat_private.h
diff -uNr libdvbpsi4-0.1.6pre-svn144/src/tables/cat.c libdvbpsi4-0.1.6pre-svn144-cat/src/tables/cat.c
--- libdvbpsi4-0.1.6pre-svn144/src/tables/cat.c 1970-01-01 01:00:00.000000000 +0100
+++ libdvbpsi4-0.1.6pre-svn144-cat/src/tables/cat.c 2007-08-23 22:56:42.000000000 +0200
@@ -0,0 +1,462 @@
+/*****************************************************************************
+ * cat.c: CAT decoder/generator
+ *----------------------------------------------------------------------------
+ * (c)2001-2002 VideoLAN
+ * $Id: cat.c 108 2005-04-19 12:33:21Z gbazin $
+ *
+ * Authors: Johann Hanne
+ * heavily based on pmt.c which was written by
+ * Arnaud de Bossoreille de Ribou <[email protected]>
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *----------------------------------------------------------------------------
+ *
+ *****************************************************************************/
+
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if defined(HAVE_INTTYPES_H)
+#include <inttypes.h>
+#elif defined(HAVE_STDINT_H)
+#include <stdint.h>
+#endif
+
+#include "../dvbpsi.h"
+#include "../dvbpsi_private.h"
+#include "../psi.h"
+#include "../descriptor.h"
+#include "cat.h"
+#include "cat_private.h"
+
+
+/*****************************************************************************
+ * dvbpsi_AttachCAT
+ *****************************************************************************
+ * Initialize a CAT decoder and return a handle on it.
+ *****************************************************************************/
+dvbpsi_handle dvbpsi_AttachCAT(dvbpsi_cat_callback pf_callback,
+ void* p_cb_data)
+{
+ dvbpsi_handle h_dvbpsi = (dvbpsi_decoder_t*)malloc(sizeof(dvbpsi_decoder_t));
+ dvbpsi_cat_decoder_t* p_cat_decoder;
+ unsigned int i;
+
+ if(h_dvbpsi == NULL)
+ return NULL;
+
+ p_cat_decoder = (dvbpsi_cat_decoder_t*)malloc(sizeof(dvbpsi_cat_decoder_t));
+
+ if(p_cat_decoder == NULL)
+ {
+ free(h_dvbpsi);
+ return NULL;
+ }
+
+ /* PSI decoder configuration */
+ h_dvbpsi->pf_callback = &dvbpsi_GatherCATSections;
+ h_dvbpsi->p_private_decoder = p_cat_decoder;
+ h_dvbpsi->i_section_max_size = 1024;
+ /* PSI decoder initial state */
+ h_dvbpsi->i_continuity_counter = 31;
+ h_dvbpsi->b_discontinuity = 1;
+ h_dvbpsi->p_current_section = NULL;
+
+ /* CAT decoder configuration */
+ p_cat_decoder->pf_callback = pf_callback;
+ p_cat_decoder->p_cb_data = p_cb_data;
+ /* CAT decoder initial state */
+ p_cat_decoder->b_current_valid = 0;
+ p_cat_decoder->p_building_cat = NULL;
+ for(i = 0; i <= 255; i++)
+ p_cat_decoder->ap_sections[i] = NULL;
+
+ return h_dvbpsi;
+}
+
+
+/*****************************************************************************
+ * dvbpsi_DetachCAT
+ *****************************************************************************
+ * Close a CAT decoder. The handle isn't valid any more.
+ *****************************************************************************/
+void dvbpsi_DetachCAT(dvbpsi_handle h_dvbpsi)
+{
+ dvbpsi_cat_decoder_t* p_cat_decoder
+ = (dvbpsi_cat_decoder_t*)h_dvbpsi->p_private_decoder;
+ unsigned int i;
+
+ free(p_cat_decoder->p_building_cat);
+
+ for(i = 0; i <= 255; i++)
+ {
+ if(p_cat_decoder->ap_sections[i])
+ free(p_cat_decoder->ap_sections[i]);
+ }
+
+ free(h_dvbpsi->p_private_decoder);
+ if(h_dvbpsi->p_current_section)
+ dvbpsi_DeletePSISections(h_dvbpsi->p_current_section);
+ free(h_dvbpsi);
+}
+
+
+/*****************************************************************************
+ * dvbpsi_InitCAT
+ *****************************************************************************
+ * Initialize a pre-allocated dvbpsi_cat_t structure.
+ *****************************************************************************/
+void dvbpsi_InitCAT(dvbpsi_cat_t* p_cat,
+ uint8_t i_version, int b_current_next)
+{
+ p_cat->i_version = i_version;
+ p_cat->b_current_next = b_current_next;
+ p_cat->p_first_descriptor = NULL;
+}
+
+
+/*****************************************************************************
+ * dvbpsi_EmptyCAT
+ *****************************************************************************
+ * Clean a dvbpsi_cat_t structure.
+ *****************************************************************************/
+void dvbpsi_EmptyCAT(dvbpsi_cat_t* p_cat)
+{
+ dvbpsi_DeleteDescriptors(p_cat->p_first_descriptor);
+
+ p_cat->p_first_descriptor = NULL;
+}
+
+
+/*****************************************************************************
+ * dvbpsi_CATAddDescriptor
+ *****************************************************************************
+ * Add a descriptor in the CAT.
+ *****************************************************************************/
+dvbpsi_descriptor_t* dvbpsi_CATAddDescriptor(dvbpsi_cat_t* p_cat,
+ 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_cat->p_first_descriptor == NULL)
+ {
+ p_cat->p_first_descriptor = p_descriptor;
+ }
+ else
+ {
+ dvbpsi_descriptor_t* p_last_descriptor = p_cat->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_GatherCATSections
+ *****************************************************************************
+ * Callback for the PSI decoder.
+ *****************************************************************************/
+void dvbpsi_GatherCATSections(dvbpsi_decoder_t* p_decoder,
+ dvbpsi_psi_section_t* p_section)
+{
+ dvbpsi_cat_decoder_t* p_cat_decoder
+ = (dvbpsi_cat_decoder_t*)p_decoder->p_private_decoder;
+ int b_append = 1;
+ int b_reinit = 0;
+ unsigned int i;
+
+ DVBPSI_DEBUG_ARG("CAT decoder",
+ "Table version %2d, " "i_extension %5d, "
+ "section %3d up to %3d, " "current %1d",
+ p_section->i_version, p_section->i_extension,
+ p_section->i_number, p_section->i_last_number,
+ p_section->b_current_next);
+
+ if(p_section->i_table_id != 0x01)
+ {
+ /* Invalid table_id value */
+ DVBPSI_ERROR_ARG("CAT decoder",
+ "invalid section (table_id == 0x%02x)",
+ p_section->i_table_id);
+ b_append = 0;
+ }
+
+ if(b_append && !p_section->b_syntax_indicator)
+ {
+ /* Invalid section_syntax_indicator */
+ DVBPSI_ERROR("CAT decoder",
+ "invalid section (section_syntax_indicator == 0)");
+ b_append = 0;
+ }
+
+ if(b_append)
+ {
+ /* TS discontinuity check */
+ if(p_decoder->b_discontinuity)
+ {
+ b_reinit = 1;
+ p_decoder->b_discontinuity = 0;
+ }
+ else
+ {
+ /* Perform some few sanity checks */
+ if(p_cat_decoder->p_building_cat)
+ {
+ if(p_cat_decoder->p_building_cat->i_version != p_section->i_version)
+ {
+ /* version_number */
+ DVBPSI_ERROR("CAT decoder",
+ "'version_number' differs"
+ " whereas no discontinuity has occured");
+ b_reinit = 1;
+ }
+ else if(p_cat_decoder->i_last_section_number
+ != p_section->i_last_number)
+ {
+ /* last_section_number */
+ DVBPSI_ERROR("CAT decoder",
+ "'last_section_number' differs"
+ " whereas no discontinuity has occured");
+ b_reinit = 1;
+ }
+ }
+ else
+ {
+ if( (p_cat_decoder->b_current_valid)
+ && (p_cat_decoder->current_cat.i_version == p_section->i_version))
+ {
+ /* Signal a new CAT if the previous one wasn't active */
+ if( (!p_cat_decoder->current_cat.b_current_next)
+ && (p_section->b_current_next))
+ {
+ dvbpsi_cat_t* p_cat = (dvbpsi_cat_t*)malloc(sizeof(dvbpsi_cat_t));
+
+ p_cat_decoder->current_cat.b_current_next = 1;
+ *p_cat = p_cat_decoder->current_cat;
+ p_cat_decoder->pf_callback(p_cat_decoder->p_cb_data, p_cat);
+ }
+
+ /* Don't decode since this version is already decoded */
+ b_append = 0;
+ }
+ }
+ }
+ }
+
+ /* Reinit the decoder if wanted */
+ if(b_reinit)
+ {
+ /* Force redecoding */
+ p_cat_decoder->b_current_valid = 0;
+ /* Free structures */
+ if(p_cat_decoder->p_building_cat)
+ {
+ free(p_cat_decoder->p_building_cat);
+ p_cat_decoder->p_building_cat = NULL;
+ }
+ /* Clear the section array */
+ for(i = 0; i <= 255; i++)
+ {
+ if(p_cat_decoder->ap_sections[i] != NULL)
+ {
+ dvbpsi_DeletePSISections(p_cat_decoder->ap_sections[i]);
+ p_cat_decoder->ap_sections[i] = NULL;
+ }
+ }
+ }
+
+ /* Append the section to the list if wanted */
+ if(b_append)
+ {
+ int b_complete;
+
+ /* Initialize the structures if it's the first section received */
+ if(!p_cat_decoder->p_building_cat)
+ {
+ p_cat_decoder->p_building_cat =
+ (dvbpsi_cat_t*)malloc(sizeof(dvbpsi_cat_t));
+ dvbpsi_InitCAT(p_cat_decoder->p_building_cat,
+ p_section->i_version,
+ p_section->b_current_next);
+ p_cat_decoder->i_last_section_number = p_section->i_last_number;
+ }
+
+ /* Fill the section array */
+ if(p_cat_decoder->ap_sections[p_section->i_number] != NULL)
+ {
+ DVBPSI_DEBUG_ARG("CAT decoder", "overwrite section number %d",
+ p_section->i_number);
+ dvbpsi_DeletePSISections(p_cat_decoder->ap_sections[p_section->i_number]);
+ }
+ p_cat_decoder->ap_sections[p_section->i_number] = p_section;
+
+ /* Check if we have all the sections */
+ b_complete = 0;
+ for(i = 0; i <= p_cat_decoder->i_last_section_number; i++)
+ {
+ if(!p_cat_decoder->ap_sections[i])
+ break;
+
+ if(i == p_cat_decoder->i_last_section_number)
+ b_complete = 1;
+ }
+
+ if(b_complete)
+ {
+ /* Save the current information */
+ p_cat_decoder->current_cat = *p_cat_decoder->p_building_cat;
+ p_cat_decoder->b_current_valid = 1;
+ /* Chain the sections */
+ if(p_cat_decoder->i_last_section_number)
+ {
+ for(i = 0; i <= p_cat_decoder->i_last_section_number - 1; i++)
+ p_cat_decoder->ap_sections[i]->p_next =
+ p_cat_decoder->ap_sections[i + 1];
+ }
+ /* Decode the sections */
+ dvbpsi_DecodeCATSections(p_cat_decoder->p_building_cat,
+ p_cat_decoder->ap_sections[0]);
+ /* Delete the sections */
+ dvbpsi_DeletePSISections(p_cat_decoder->ap_sections[0]);
+ /* signal the new CAT */
+ p_cat_decoder->pf_callback(p_cat_decoder->p_cb_data,
+ p_cat_decoder->p_building_cat);
+ /* Reinitialize the structures */
+ p_cat_decoder->p_building_cat = NULL;
+ for(i = 0; i <= p_cat_decoder->i_last_section_number; i++)
+ p_cat_decoder->ap_sections[i] = NULL;
+ }
+ }
+ else
+ {
+ dvbpsi_DeletePSISections(p_section);
+ }
+}
+
+
+/*****************************************************************************
+ * dvbpsi_DecodeCATSections
+ *****************************************************************************
+ * CAT decoder.
+ *****************************************************************************/
+void dvbpsi_DecodeCATSections(dvbpsi_cat_t* p_cat,
+ dvbpsi_psi_section_t* p_section)
+{
+ uint8_t* p_byte, * p_end;
+
+ while(p_section)
+ {
+ /* CAT descriptors */
+ p_byte = p_section->p_payload_start;
+ while(p_byte + 5 <= p_section->p_payload_end)
+ {
+ uint8_t i_tag = p_byte[0];
+ uint8_t i_length = p_byte[1];
+ if(i_length + 2 <= p_section->p_payload_end - p_byte)
+ dvbpsi_CATAddDescriptor(p_cat, i_tag, i_length, p_byte + 2);
+ p_byte += 2 + i_length;
+ }
+
+ p_section = p_section->p_next;
+ }
+}
+
+
+/*****************************************************************************
+ * dvbpsi_GenCATSections
+ *****************************************************************************
+ * Generate CAT sections based on the dvbpsi_cat_t structure.
+ *****************************************************************************/
+dvbpsi_psi_section_t* dvbpsi_GenCATSections(dvbpsi_cat_t* p_cat)
+{
+ dvbpsi_psi_section_t* p_result = dvbpsi_NewPSISection(1024);
+ dvbpsi_psi_section_t* p_current = p_result;
+ dvbpsi_psi_section_t* p_prev;
+ dvbpsi_descriptor_t* p_descriptor = p_cat->p_first_descriptor;
+
+ p_current->i_table_id = 0x01;
+ p_current->b_syntax_indicator = 1;
+ p_current->b_private_indicator = 0;
+ p_current->i_length = 9; /* header + CRC_32 */
+ p_current->i_extension = 0; /* Not used in the CAT */
+ p_current->i_version = p_cat->i_version;
+ p_current->b_current_next = p_cat->b_current_next;
+ p_current->i_number = 0;
+ p_current->p_payload_end += 8; /* just after the header */
+ p_current->p_payload_start = p_current->p_data + 8;
+
+ /* CAT descriptors */
+ while(p_descriptor != NULL)
+ {
+ /* New section if needed */
+ /* written_data_length + descriptor_length + 2 > 1024 - CRC_32_length */
+ if( (p_current->p_payload_end - p_current->p_data)
+ + p_descriptor->i_length > 1018)
+ {
+ p_prev = p_current;
+ p_current = dvbpsi_NewPSISection(1024);
+ p_prev->p_next = p_current;
+
+ p_current->i_table_id = 0x01;
+ p_current->b_syntax_indicator = 1;
+ p_current->b_private_indicator = 0;
+ p_current->i_length = 9; /* header + CRC_32 */
+ p_current->i_extension = 0; /* Not used in the CAT */
+ p_current->i_version = p_cat->i_version;
+ p_current->b_current_next = p_cat->b_current_next;
+ p_current->i_number = p_prev->i_number + 1;
+ p_current->p_payload_end += 8; /* just after the header */
+ p_current->p_payload_start = p_current->p_data + 8;
+ }
+
+ /* p_payload_end is where the descriptor begins */
+ p_current->p_payload_end[0] = p_descriptor->i_tag;
+ p_current->p_payload_end[1] = p_descriptor->i_length;
+ memcpy(p_current->p_payload_end + 2,
+ p_descriptor->p_data,
+ p_descriptor->i_length);
+
+ /* Increase length by descriptor_length + 2 */
+ p_current->p_payload_end += p_descriptor->i_length + 2;
+ p_current->i_length += p_descriptor->i_length + 2;
+
+ p_descriptor = p_descriptor->p_next;
+ }
+
+ /* Finalization */
+ p_prev = p_result;
+ while(p_prev != NULL)
+ {
+ p_prev->i_last_number = p_current->i_number;
+ dvbpsi_BuildPSISection(p_prev);
+ p_prev = p_prev->p_next;
+ }
+
+ return p_result;
+}
+
diff -uNr libdvbpsi4-0.1.6pre-svn144/src/tables/cat.h libdvbpsi4-0.1.6pre-svn144-cat/src/tables/cat.h
--- libdvbpsi4-0.1.6pre-svn144/src/tables/cat.h 1970-01-01 01:00:00.000000000 +0100
+++ libdvbpsi4-0.1.6pre-svn144-cat/src/tables/cat.h 2007-08-23 22:58:56.000000000 +0200
@@ -0,0 +1,208 @@
+/*****************************************************************************
+ * cat.h
+ * (c)2001-2002 VideoLAN
+ * $Id: cat.h 103 2005-01-21 14:34:51Z massiot $
+ *
+ * Authors: Johann Hanne
+ * heavily based on pmt.h which was written by
+ * Arnaud de Bossoreille de Ribou <[email protected]>
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *****************************************************************************/
+
+/*!
+ * \file <cat.h>
+ * \author Arnaud de Bossoreille de Ribou <[email protected]>
+ * \brief Application interface for the CAT decoder and the CAT generator.
+ *
+ * Application interface for the CAT decoder and the CAT generator. New
+ * decoded CAT tables are sent by callback to the application. If a table
+ * wasn't active (b_current_next == 0) and the next is the same but active
+ * (b_current_next == 1) then the two lists are empty and should be
+ * caught from the previous structure.
+ */
+
+#ifndef _DVBPSI_CAT_H_
+#define _DVBPSI_CAT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*****************************************************************************
+ * dvbpsi_cat_t
+ *****************************************************************************/
+/*!
+ * \struct dvbpsi_cat_s
+ * \brief CAT structure.
+ *
+ * This structure is used to store a decoded CAT.
+ * (ISO/IEC 13818-1 section 2.4.4.6).
+ */
+/*!
+ * \typedef struct dvbpsi_cat_s dvbpsi_cat_t
+ * \brief dvbpsi_cat_t type definition.
+ */
+typedef struct dvbpsi_cat_s
+{
+ uint8_t i_version; /*!< version_number */
+ int b_current_next; /*!< current_next_indicator */
+
+ dvbpsi_descriptor_t * p_first_descriptor; /*!< descriptor list */
+
+} dvbpsi_cat_t;
+
+
+/*****************************************************************************
+ * dvbpsi_cat_callback
+ *****************************************************************************/
+/*!
+ * \typedef void (* dvbpsi_cat_callback)(void* p_cb_data,
+ dvbpsi_cat_t* p_new_cat)
+ * \brief Callback type definition.
+ */
+typedef void (* dvbpsi_cat_callback)(void* p_cb_data, dvbpsi_cat_t* p_new_cat);
+
+
+/*****************************************************************************
+ * dvbpsi_AttachCAT
+ *****************************************************************************/
+/*!
+ * \fn dvbpsi_handle dvbpsi_AttachCAT(dvbpsi_cat_callback pf_callback,
+ void* p_cb_data)
+ * \brief Creation and initialization of a CAT decoder.
+ * \param pf_callback function to call back on new CAT
+ * \param p_cb_data private data given in argument to the callback
+ * \return a pointer to the decoder for future calls.
+ */
+dvbpsi_handle dvbpsi_AttachCAT(dvbpsi_cat_callback pf_callback,
+ void* p_cb_data);
+
+
+/*****************************************************************************
+ * dvbpsi_DetachCAT
+ *****************************************************************************/
+/*!
+ * \fn void dvbpsi_DetachCAT(dvbpsi_handle h_dvbpsi)
+ * \brief Destroy a CAT decoder.
+ * \param h_dvbpsi handle to the decoder
+ * \return nothing.
+ *
+ * The handle isn't valid any more.
+ */
+void dvbpsi_DetachCAT(dvbpsi_handle h_dvbpsi);
+
+
+/*****************************************************************************
+ * dvbpsi_InitCAT/dvbpsi_NewCAT
+ *****************************************************************************/
+/*!
+ * \fn void dvbpsi_InitCAT(dvbpsi_cat_t* p_cat,
+ uint8_t i_version, int b_current_next)
+ * \brief Initialize a user-allocated dvbpsi_cat_t structure.
+ * \param p_cat pointer to the CAT structure
+ * \param i_version CAT version
+ * \param b_current_next current next indicator
+ * \return nothing.
+ */
+void dvbpsi_InitCAT(dvbpsi_cat_t* p_cat,
+ uint8_t i_version, int b_current_next);
+
+/*!
+ * \def dvbpsi_NewCAT(p_cat,
+ i_version, b_current_next)
+ * \brief Allocate and initialize a new dvbpsi_cat_t structure.
+ * \param p_cat pointer to the CAT structure
+ * \param i_version CAT version
+ * \param b_current_next current next indicator
+ * \return nothing.
+ */
+#define dvbpsi_NewCAT(p_cat, \
+ i_version, b_current_next) \
+do { \
+ p_cat = (dvbpsi_cat_t*)malloc(sizeof(dvbpsi_cat_t)); \
+ if(p_cat != NULL) \
+ dvbpsi_InitCAT(p_cat, i_version, b_current_next); \
+} while(0);
+
+
+/*****************************************************************************
+ * dvbpsi_EmptyCAT/dvbpsi_DeleteCAT
+ *****************************************************************************/
+/*!
+ * \fn void dvbpsi_EmptyCAT(dvbpsi_cat_t* p_cat)
+ * \brief Clean a dvbpsi_cat_t structure.
+ * \param p_cat pointer to the CAT structure
+ * \return nothing.
+ */
+void dvbpsi_EmptyCAT(dvbpsi_cat_t* p_cat);
+
+/*!
+ * \def dvbpsi_DeleteCAT(p_cat)
+ * \brief Clean and free a dvbpsi_cat_t structure.
+ * \param p_cat pointer to the CAT structure
+ * \return nothing.
+ */
+#define dvbpsi_DeleteCAT(p_cat) \
+do { \
+ dvbpsi_EmptyCAT(p_cat); \
+ free(p_cat); \
+} while(0);
+
+
+/*****************************************************************************
+ * dvbpsi_CATAddDescriptor
+ *****************************************************************************/
+/*!
+ * \fn dvbpsi_descriptor_t* dvbpsi_CATAddDescriptor(dvbpsi_cat_t* p_cat,
+ uint8_t i_tag,
+ uint8_t i_length,
+ uint8_t* p_data)
+ * \brief Add a descriptor in the CAT.
+ * \param p_cat pointer to the CAT structure
+ * \param i_tag descriptor's tag
+ * \param i_length descriptor's length
+ * \param p_data descriptor's data
+ * \return a pointer to the added descriptor.
+ */
+dvbpsi_descriptor_t* dvbpsi_CATAddDescriptor(dvbpsi_cat_t* p_cat,
+ uint8_t i_tag, uint8_t i_length,
+ uint8_t* p_data);
+
+
+/*****************************************************************************
+ * dvbpsi_GenCATSections
+ *****************************************************************************/
+/*!
+ * \fn dvbpsi_psi_section_t* dvbpsi_GenCATSections(dvbpsi_cat_t* p_cat)
+ * \brief CAT generator
+ * \param p_cat CAT structure
+ * \return a pointer to the list of generated PSI sections.
+ *
+ * Generate CAT sections based on the dvbpsi_cat_t structure.
+ */
+dvbpsi_psi_section_t* dvbpsi_GenCATSections(dvbpsi_cat_t* p_cat);
+
+
+#ifdef __cplusplus
+};
+#endif
+
+#else
+#error "Multiple inclusions of cat.h"
+#endif
+
diff -uNr libdvbpsi4-0.1.6pre-svn144/src/tables/cat_private.h libdvbpsi4-0.1.6pre-svn144-cat/src/tables/cat_private.h
--- libdvbpsi4-0.1.6pre-svn144/src/tables/cat_private.h 1970-01-01 01:00:00.000000000 +0100
+++ libdvbpsi4-0.1.6pre-svn144-cat/src/tables/cat_private.h 2007-08-23 18:54:47.000000000 +0200
@@ -0,0 +1,74 @@
+/*****************************************************************************
+ * cat_private.h: private CAT structures
+ *----------------------------------------------------------------------------
+ * (c)2001-2002 VideoLAN
+ * $Id: cat_private.h 88 2004-02-24 14:31:18Z sam $
+ *
+ * Authors: Johann Hanne
+ * heavily based on pmt_private.h which was written by
+ * Arnaud de Bossoreille de Ribou <[email protected]>
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *----------------------------------------------------------------------------
+ *
+ *****************************************************************************/
+
+#ifndef _DVBPSI_CAT_PRIVATE_H_
+#define _DVBPSI_CAT_PRIVATE_H_
+
+/*****************************************************************************
+ * dvbpsi_cat_decoder_t
+ *****************************************************************************
+ * CAT decoder.
+ *****************************************************************************/
+typedef struct dvbpsi_cat_decoder_s
+{
+ dvbpsi_cat_callback pf_callback;
+ void * p_cb_data;
+
+ dvbpsi_cat_t current_cat;
+ dvbpsi_cat_t * p_building_cat;
+
+ int b_current_valid;
+
+ uint8_t i_last_section_number;
+ dvbpsi_psi_section_t * ap_sections [256];
+
+} dvbpsi_cat_decoder_t;
+
+
+/*****************************************************************************
+ * dvbpsi_GatherCATSections
+ *****************************************************************************
+ * Callback for the PSI decoder.
+ *****************************************************************************/
+void dvbpsi_GatherCATSections(dvbpsi_decoder_t* p_decoder,
+ dvbpsi_psi_section_t* p_section);
+
+
+/*****************************************************************************
+ * dvbpsi_DecodeCATSections
+ *****************************************************************************
+ * CAT decoder.
+ *****************************************************************************/
+void dvbpsi_DecodeCATSections(dvbpsi_cat_t* p_cat,
+ dvbpsi_psi_section_t* p_section);
+
+
+#else
+#error "Multiple inclusions of cat_private.h"
+#endif
+