Commit 925cbbc6 authored by Jean-Paul Saman's avatar Jean-Paul Saman

chained decoders: implement demuxing support.

parent c3a03feb
...@@ -43,6 +43,91 @@ ...@@ -43,6 +43,91 @@
#include "psi.h" #include "psi.h"
#include "chain.h" #include "chain.h"
/*****************************************************************************
* dvbpsi_decoder_chain_demux
*****************************************************************************
* Sends a PSI section to the right subtable decoder
*****************************************************************************/
static void dvbpsi_decoder_chain_demux(dvbpsi_t *p_dvbpsi, dvbpsi_psi_section_t *p_section)
{
assert(p_dvbpsi);
assert(p_dvbpsi->p_decoder);
dvbpsi_decoder_t *p_table = NULL;
dvbpsi_decoder_t *p_demux = (dvbpsi_decoder_t *)p_dvbpsi->p_decoder;
if (p_demux == NULL) {
dvbpsi_DeletePSISections(p_section);
return;
}
p_table = dvbpsi_decoder_chain_get(p_dvbpsi, p_section->i_table_id, p_section->i_extension);
if (p_table == NULL) {
if (p_demux->pf_new)
p_demux->pf_new(p_dvbpsi, p_section->i_table_id, p_section->i_extension, p_demux->p_priv);
}
/* Check if new table created */
dvbpsi_decoder_t *p_subtable;
p_subtable = dvbpsi_decoder_chain_get(p_dvbpsi, p_section->i_table_id, p_section->i_extension);
if (p_subtable)
p_subtable->pf_gather(p_dvbpsi, p_section);
else
dvbpsi_DeletePSISections(p_section);
}
/*****************************************************************************
* dvbpsi_decoder_chain_new
*****************************************************************************
* Create chain decoder
*****************************************************************************/
bool dvbpsi_decoder_chain_new(dvbpsi_t *p_dvbpsi, dvbpsi_callback_new_t pf_new,
dvbpsi_callback_del_t pf_del, void *p_data)
{
if (p_dvbpsi->p_decoder) {
dvbpsi_error(p_dvbpsi, "chain", "cannot initialize decoder chain");
return false;
}
/* FIXME: We need an alternative for dvbpsi_Demux() !!!*/
dvbpsi_decoder_t *p_chain = (dvbpsi_decoder_t *)dvbpsi_decoder_new(&dvbpsi_decoder_chain_demux,
4096, true,
sizeof(dvbpsi_decoder_t));
if (!p_chain)
return false;
p_chain->pf_new = pf_new;
p_chain->pf_del = pf_del;
p_chain->p_priv = p_data;
/* Remomber decoder */
p_dvbpsi->p_decoder = DVBPSI_DECODER(p_chain);
return true;
}
/*****************************************************************************
* dvbpsi_decoder_chain_delete
*****************************************************************************
* Remove all decoders from list and free all resources.
*****************************************************************************/
bool dvbpsi_decoder_chain_delete(dvbpsi_t *p_dvbpsi)
{
dvbpsi_decoder_t *p = p_dvbpsi->p_decoder;
if (!p) return false;
while (p) {
dvbpsi_decoder_t *p_dec = p;
p = p_dec->p_next;
if (p_dec->pf_del)
p_dec->pf_del(p_dvbpsi, p_dec->i_table_id, p_dec->i_extension);
/* FIXME: p->pf_del() calls eventually the dvbpsi_XXX_detach() function
* which walks the list again. This is a waste of time and needs improvement
* on the mechanism on how to create/delete and attach/detach a subtable decoder.
*/
dvbpsi_decoder_delete(p_dec);
}
p_dvbpsi->p_decoder = NULL;
return true;
}
/***************************************************************************** /*****************************************************************************
* dvbpsi_decoder_chain_add * dvbpsi_decoder_chain_add
...@@ -130,4 +215,3 @@ dvbpsi_decoder_t *dvbpsi_decoder_chain_get(dvbpsi_t *p_dvbpsi, const uint16_t ta ...@@ -130,4 +215,3 @@ dvbpsi_decoder_t *dvbpsi_decoder_chain_get(dvbpsi_t *p_dvbpsi, const uint16_t ta
dvbpsi_error(p_dvbpsi, "chain", "decoder not found"); dvbpsi_error(p_dvbpsi, "chain", "decoder not found");
return NULL; return NULL;
} }
...@@ -39,6 +39,37 @@ ...@@ -39,6 +39,37 @@
extern "C" { extern "C" {
#endif #endif
/*****************************************************************************
* dvbpsi_decoder_chain_new
*****************************************************************************/
/*!
* \fn bool dvbpsi_decoder_chain_new(dvbpsi_t *p_dvbpsi, dvbpsi_callback_new_t *pf_new,
dvbpsi_callback_del_t *pf_del, void *p_data)
* \brief dvbpsi_decoder_chain_new creates a decoder for demuxing PSI tables and subtables.
* \param p_dvbpsi pointer to dvbpsi_t handle
* \param pf_new callback function for calling the specific PSI table/subtable attach function
* \param pf_del callback function for calling the specific PSI table/subtable detach function
* \param p_data pointer to data that must be passed to PSI table/subtable its
* dvbpsi_xxx_attach() function
* \return true on success, false on failure
*/
bool dvbpsi_decoder_chain_new(dvbpsi_t *p_dvbpsi, dvbpsi_callback_new_t pf_new,
dvbpsi_callback_del_t pf_del, void *p_data);
/*****************************************************************************
* dvbpsi_decoder_chain_delete
*****************************************************************************/
/*!
* \fn bool dvbpsi_decoder_chain_delete(dvbpsi_t *p_dvbpsi)
* \brief dvbpsi_decoder_chain_delete walks the chain of PSI (sub-)table decoders
* and removes them from the chain before calling its pf_detach callback. The pointers
* to the PSI (sub-)table decoders are no longer valid after this function has been called.
* Nor is the decoder chain list valid.
* \param p_dvbpsi pointer to dvbpsi_t handle
* \return true on success, false on failure
*/
bool dvbpsi_decoder_chain_delete(dvbpsi_t *p_dvbpsi);
/***************************************************************************** /*****************************************************************************
* dvbpsi_decoder_chain_add * dvbpsi_decoder_chain_add
*****************************************************************************/ *****************************************************************************/
......
...@@ -87,6 +87,10 @@ void *dvbpsi_decoder_new(dvbpsi_callback_gather_t pf_gather, ...@@ -87,6 +87,10 @@ void *dvbpsi_decoder_new(dvbpsi_callback_gather_t pf_gather,
memcpy(&p_decoder->i_magic[0], "psi", 3); memcpy(&p_decoder->i_magic[0], "psi", 3);
p_decoder->pf_gather = pf_gather; p_decoder->pf_gather = pf_gather;
p_decoder->pf_new = NULL;
p_decoder->pf_del = NULL;
p_decoder->p_priv = NULL;
p_decoder->p_current_section = NULL; p_decoder->p_current_section = NULL;
p_decoder->i_section_max_size = i_section_max_size; p_decoder->i_section_max_size = i_section_max_size;
p_decoder->b_discontinuity = b_discontinuity; p_decoder->b_discontinuity = b_discontinuity;
...@@ -225,6 +229,7 @@ out: ...@@ -225,6 +229,7 @@ out:
void dvbpsi_decoder_delete(dvbpsi_decoder_t *p_decoder) void dvbpsi_decoder_delete(dvbpsi_decoder_t *p_decoder)
{ {
assert(p_decoder); assert(p_decoder);
assert(p_decoder->p_priv == NULL);
if (p_decoder->p_sections) if (p_decoder->p_sections)
{ {
......
...@@ -219,6 +219,31 @@ typedef struct dvbpsi_psi_section_s dvbpsi_psi_section_t; ...@@ -219,6 +219,31 @@ typedef struct dvbpsi_psi_section_s dvbpsi_psi_section_t;
typedef void (* dvbpsi_callback_gather_t)(dvbpsi_t *p_dvbpsi, /*!< pointer to dvbpsi handle */ typedef void (* dvbpsi_callback_gather_t)(dvbpsi_t *p_dvbpsi, /*!< pointer to dvbpsi handle */
dvbpsi_psi_section_t* p_section); /*!< pointer to psi section */ dvbpsi_psi_section_t* p_section); /*!< pointer to psi section */
/*****************************************************************************
* dvbpsi_callback_new_t
*****************************************************************************/
/*!
* \typedef void (*dvbpsi_callback_new_t)(dvbpsi_t *p_dvbpsi,
* uint8_t i_table_id, uint16_t i_extension, void *p_data);
* \brief Callback used in case of a new PSI table is detected.
*/
typedef void (*dvbpsi_callback_new_t)(dvbpsi_t *p_dvbpsi, /*!< pointer to dvbpsi handle */
uint8_t i_table_id, /*!< table id to attach */
uint16_t i_extension,/*!< table extention to attach */
void *p_data); /*!< pointer to callback data */
/*****************************************************************************
* dvbpsi_callback_del_t
*****************************************************************************/
/*!
* \typedef void (*dvbpsi_callback_del_t)(dvbpsi_t *p_dvbpsi,
* uint8_t i_table_id, uint16_t i_extension);
* \brief Callback used to delete PSI table.
*/
typedef void (*dvbpsi_callback_del_t)(dvbpsi_t *p_dvbpsi, /*!< pointer to dvbpsi handle */
uint8_t i_table_id, /*!< table id to attach */
uint16_t i_extension);/*!< table extention to attach */
/***************************************************************************** /*****************************************************************************
* DVBPSI_DECODER_COMMON * DVBPSI_DECODER_COMMON
*****************************************************************************/ *****************************************************************************/
...@@ -248,6 +273,11 @@ typedef void (* dvbpsi_callback_gather_t)(dvbpsi_t *p_dvbpsi, /*!< pointer to d ...@@ -248,6 +273,11 @@ typedef void (* dvbpsi_callback_gather_t)(dvbpsi_t *p_dvbpsi, /*!< pointer to d
/* since version 2.0.0 */ \ /* since version 2.0.0 */ \
uint16_t i_table_id; /*!< PSI table id */ \ uint16_t i_table_id; /*!< PSI table id */ \
uint16_t i_extension; /*!< PSI subtable id */ \ uint16_t i_extension; /*!< PSI subtable id */ \
/* Subtables creation and deletion Callbacks */ \
dvbpsi_callback_new_t pf_new; /*!< Add new PSI table */ \
dvbpsi_callback_del_t pf_del; /*!< Del PSI table */ \
void *p_priv; /*!< Private decoder data */ \
/* pointer to next decoder in list */ \
dvbpsi_decoder_t *p_next; /*!< Pointer to next decoder the list */ dvbpsi_decoder_t *p_next; /*!< Pointer to next decoder the list */
/**@}*/ /**@}*/
......
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