Commit 71126f5c authored by Jean-Paul Saman's avatar Jean-Paul Saman

PAT: implement as chained decoder

parent a856c423
...@@ -42,10 +42,12 @@ ...@@ -42,10 +42,12 @@
#ifdef DVBPSI_DIST #ifdef DVBPSI_DIST
#include "../src/dvbpsi.h" #include "../src/dvbpsi.h"
#include "../src/psi.h" #include "../src/psi.h"
#include "../src/chain.h"
#include "../src/tables/pat.h" #include "../src/tables/pat.h"
#else #else
#include <dvbpsi/dvbpsi.h> #include <dvbpsi/dvbpsi.h>
#include <dvbpsi/psi.h> #include <dvbpsi/psi.h>
#include <dvbpsi/chain.h>
#include <dvbpsi/pat.h> #include <dvbpsi/pat.h>
#endif #endif
...@@ -96,6 +98,21 @@ static void DumpPAT(void* p_zero, dvbpsi_pat_t* p_pat) ...@@ -96,6 +98,21 @@ static void DumpPAT(void* p_zero, dvbpsi_pat_t* p_pat)
dvbpsi_pat_delete(p_pat); dvbpsi_pat_delete(p_pat);
} }
/*****************************************************************************
* AttachPAT
*****************************************************************************/
static void AttachPAT(dvbpsi_t *p_dvbpsi, uint8_t i_table_id, uint16_t i_extension,
void *p_zero)
{
if (!dvbpsi_pat_attach(p_dvbpsi, i_table_id, i_extension, DumpPAT, NULL))
fprintf(stderr, "Failed to attach PAT decoder\n");
}
static void DetachPAT(dvbpsi_t *p_dvbpsi, uint8_t i_table_id, uint16_t i_extension)
{
dvbpsi_pat_detach(p_dvbpsi, i_table_id, i_extension);
}
static void message(dvbpsi_t *handle, const dvbpsi_msg_level_t level, const char* msg) static void message(dvbpsi_t *handle, const dvbpsi_msg_level_t level, const char* msg)
{ {
switch(level) switch(level)
...@@ -115,22 +132,23 @@ static void message(dvbpsi_t *handle, const dvbpsi_msg_level_t level, const char ...@@ -115,22 +132,23 @@ static void message(dvbpsi_t *handle, const dvbpsi_msg_level_t level, const char
int main(int i_argc, char* pa_argv[]) int main(int i_argc, char* pa_argv[])
{ {
int i_fd; int i_fd;
int ret = 1;
uint8_t data[188]; uint8_t data[188];
dvbpsi_t *p_dvbpsi; dvbpsi_t *p_dvbpsi;
bool b_ok; bool b_ok;
if (i_argc != 2) if (i_argc != 2)
return 1; return ret;
i_fd = open(pa_argv[1], 0); i_fd = open(pa_argv[1], 0);
if (i_fd < 0) if (i_fd < 0)
return 1; return ret;
p_dvbpsi = dvbpsi_new(&message, DVBPSI_MSG_DEBUG); p_dvbpsi = dvbpsi_new(&message, DVBPSI_MSG_DEBUG);
if (p_dvbpsi == NULL) if (p_dvbpsi == NULL)
goto out; goto out;
if (!dvbpsi_pat_attach(p_dvbpsi, DumpPAT, NULL)) if (!dvbpsi_decoder_chain_new(p_dvbpsi, AttachPAT, DetachPAT, NULL))
goto out; goto out;
b_ok = ReadPacket(i_fd, data); b_ok = ReadPacket(i_fd, data);
...@@ -143,14 +161,15 @@ int main(int i_argc, char* pa_argv[]) ...@@ -143,14 +161,15 @@ int main(int i_argc, char* pa_argv[])
b_ok = ReadPacket(i_fd, data); b_ok = ReadPacket(i_fd, data);
} }
ret = 0;
out: out:
if (p_dvbpsi) if (p_dvbpsi)
{ {
dvbpsi_pat_detach(p_dvbpsi); if (!dvbpsi_decoder_chain_delete(p_dvbpsi))
ret = 1;
dvbpsi_delete(p_dvbpsi); dvbpsi_delete(p_dvbpsi);
} }
close(i_fd); close(i_fd);
return ret;
return 0;
} }
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
#include "../dvbpsi.h" #include "../dvbpsi.h"
#include "../dvbpsi_private.h" #include "../dvbpsi_private.h"
#include "../psi.h" #include "../psi.h"
#include "../chain.h"
#include "pat.h" #include "pat.h"
#include "pat_private.h" #include "pat_private.h"
...@@ -50,13 +51,21 @@ ...@@ -50,13 +51,21 @@
***************************************************************************** *****************************************************************************
* Initialize a PAT decoder and return a handle on it. * Initialize a PAT decoder and return a handle on it.
*****************************************************************************/ *****************************************************************************/
bool dvbpsi_pat_attach(dvbpsi_t *p_dvbpsi, dvbpsi_pat_callback pf_callback, bool dvbpsi_pat_attach(dvbpsi_t *p_dvbpsi, uint8_t i_table_id, uint16_t i_extension,
void* p_cb_data) dvbpsi_pat_callback pf_callback, void* p_cb_data)
{ {
assert(p_dvbpsi); assert(p_dvbpsi);
assert(p_dvbpsi->p_decoder == NULL);
/* PSI decoder configuration and initial state */ /* PSI decoder configuration and initial state */
dvbpsi_decoder_t* p_dec = dvbpsi_decoder_chain_get(p_dvbpsi, i_table_id, i_extension);
if (p_dec != NULL)
{
dvbpsi_error(p_dvbpsi, "PAT decoder",
"Already a decoder for (table_id == 0x%02x,"
"extension == 0x%02x)",
i_table_id, i_extension);
return false;
}
dvbpsi_pat_decoder_t *p_pat_decoder; dvbpsi_pat_decoder_t *p_pat_decoder;
p_pat_decoder = (dvbpsi_pat_decoder_t*) dvbpsi_decoder_new(&dvbpsi_pat_sections_gather, p_pat_decoder = (dvbpsi_pat_decoder_t*) dvbpsi_decoder_new(&dvbpsi_pat_sections_gather,
1024, true, sizeof(dvbpsi_pat_decoder_t)); 1024, true, sizeof(dvbpsi_pat_decoder_t));
...@@ -68,7 +77,16 @@ bool dvbpsi_pat_attach(dvbpsi_t *p_dvbpsi, dvbpsi_pat_callback pf_callback, ...@@ -68,7 +77,16 @@ bool dvbpsi_pat_attach(dvbpsi_t *p_dvbpsi, dvbpsi_pat_callback pf_callback,
p_pat_decoder->p_cb_data = p_cb_data; p_pat_decoder->p_cb_data = p_cb_data;
p_pat_decoder->p_building_pat = NULL; p_pat_decoder->p_building_pat = NULL;
p_dvbpsi->p_decoder = DVBPSI_DECODER(p_pat_decoder); p_pat_decoder->i_table_id = i_table_id;
p_pat_decoder->i_extension = i_extension;
/* Add pat decoder to decoder chain */
if (!dvbpsi_decoder_chain_add(p_dvbpsi, DVBPSI_DECODER(p_pat_decoder)))
{
dvbpsi_decoder_delete(DVBPSI_DECODER(p_pat_decoder));
return false;
}
return true; return true;
} }
...@@ -77,18 +95,36 @@ bool dvbpsi_pat_attach(dvbpsi_t *p_dvbpsi, dvbpsi_pat_callback pf_callback, ...@@ -77,18 +95,36 @@ bool dvbpsi_pat_attach(dvbpsi_t *p_dvbpsi, dvbpsi_pat_callback pf_callback,
***************************************************************************** *****************************************************************************
* Close a PAT decoder. The handle isn't valid any more. * Close a PAT decoder. The handle isn't valid any more.
*****************************************************************************/ *****************************************************************************/
void dvbpsi_pat_detach(dvbpsi_t *p_dvbpsi) void dvbpsi_pat_detach(dvbpsi_t *p_dvbpsi, uint8_t i_table_id, uint16_t i_extension)
{ {
assert(p_dvbpsi); assert(p_dvbpsi);
assert(p_dvbpsi->p_decoder);
dvbpsi_pat_decoder_t* p_pat_decoder = (dvbpsi_pat_decoder_t*)p_dvbpsi->p_decoder; dvbpsi_pat_decoder_t *p_pat_decoder =
(dvbpsi_pat_decoder_t*) dvbpsi_decoder_chain_get(p_dvbpsi, i_table_id, i_extension);
if (!p_pat_decoder)
{
dvbpsi_error(p_dvbpsi, "PAT Decoder",
"No such PAT decoder (table_id == 0x%02x,"
"extension == 0x%02x)",
i_table_id, i_extension);
return;
}
/* Remove table decoder from chain */
if (!dvbpsi_decoder_chain_remove(p_dvbpsi, DVBPSI_DECODER(p_pat_decoder)))
{
dvbpsi_error(p_dvbpsi, "PAT Decoder",
"Failed to remove"
"extension == 0x%02x)",
i_table_id, i_extension);
return;
}
if (p_pat_decoder->p_building_pat) if (p_pat_decoder->p_building_pat)
dvbpsi_pat_delete(p_pat_decoder->p_building_pat); dvbpsi_pat_delete(p_pat_decoder->p_building_pat);
p_pat_decoder->p_building_pat = NULL; p_pat_decoder->p_building_pat = NULL;
dvbpsi_decoder_delete(DVBPSI_DECODER(p_pat_decoder));
dvbpsi_decoder_delete(p_dvbpsi->p_decoder); p_pat_decoder = NULL;
p_dvbpsi->p_decoder = NULL;
} }
/***************************************************************************** /*****************************************************************************
...@@ -204,13 +240,10 @@ static void dvbpsi_ReInitPAT(dvbpsi_pat_decoder_t* p_decoder, const bool b_force ...@@ -204,13 +240,10 @@ static void dvbpsi_ReInitPAT(dvbpsi_pat_decoder_t* p_decoder, const bool b_force
p_decoder->p_building_pat = NULL; p_decoder->p_building_pat = NULL;
} }
static bool dvbpsi_CheckPAT(dvbpsi_t *p_dvbpsi, dvbpsi_psi_section_t *p_section) static bool dvbpsi_CheckPAT(dvbpsi_t *p_dvbpsi, dvbpsi_pat_decoder_t* p_pat_decoder,
dvbpsi_psi_section_t *p_section)
{ {
bool b_reinit = false; bool b_reinit = false;
assert(p_dvbpsi->p_decoder);
dvbpsi_pat_decoder_t* p_pat_decoder;
p_pat_decoder = (dvbpsi_pat_decoder_t *)p_dvbpsi->p_decoder;
/* Perform a few sanity checks */ /* Perform a few sanity checks */
if (p_pat_decoder->p_building_pat->i_ts_id != p_section->i_extension) if (p_pat_decoder->p_building_pat->i_ts_id != p_section->i_extension)
...@@ -273,10 +306,8 @@ static bool dvbpsi_AddSectionPAT(dvbpsi_t *p_dvbpsi, dvbpsi_pat_decoder_t *p_pat ...@@ -273,10 +306,8 @@ static bool dvbpsi_AddSectionPAT(dvbpsi_t *p_dvbpsi, dvbpsi_pat_decoder_t *p_pat
*****************************************************************************/ *****************************************************************************/
void dvbpsi_pat_sections_gather(dvbpsi_t* p_dvbpsi, dvbpsi_psi_section_t* p_section) void dvbpsi_pat_sections_gather(dvbpsi_t* p_dvbpsi, dvbpsi_psi_section_t* p_section)
{ {
dvbpsi_pat_decoder_t* p_pat_decoder;
assert(p_dvbpsi); assert(p_dvbpsi);
assert(p_dvbpsi->p_decoder);
if (!dvbpsi_CheckPSISection(p_dvbpsi, p_section, 0x00, "PAT decoder")) if (!dvbpsi_CheckPSISection(p_dvbpsi, p_section, 0x00, "PAT decoder"))
{ {
...@@ -285,9 +316,15 @@ void dvbpsi_pat_sections_gather(dvbpsi_t* p_dvbpsi, dvbpsi_psi_section_t* p_sect ...@@ -285,9 +316,15 @@ void dvbpsi_pat_sections_gather(dvbpsi_t* p_dvbpsi, dvbpsi_psi_section_t* p_sect
} }
/* Now we have a valid PAT section */ /* Now we have a valid PAT section */
p_pat_decoder = (dvbpsi_pat_decoder_t *)p_dvbpsi->p_decoder; dvbpsi_decoder_t *p_dec = dvbpsi_decoder_chain_get(p_dvbpsi, p_section->i_table_id, p_section->i_extension);
if (!p_dec)
{
dvbpsi_DeletePSISections(p_section);
return;
}
/* TS discontinuity check */ /* TS discontinuity check */
dvbpsi_pat_decoder_t *p_pat_decoder = (dvbpsi_pat_decoder_t *)p_dec;
if (p_pat_decoder->b_discontinuity) if (p_pat_decoder->b_discontinuity)
{ {
dvbpsi_ReInitPAT(p_pat_decoder, true); dvbpsi_ReInitPAT(p_pat_decoder, true);
...@@ -297,7 +334,7 @@ void dvbpsi_pat_sections_gather(dvbpsi_t* p_dvbpsi, dvbpsi_psi_section_t* p_sect ...@@ -297,7 +334,7 @@ void dvbpsi_pat_sections_gather(dvbpsi_t* p_dvbpsi, dvbpsi_psi_section_t* p_sect
{ {
if (p_pat_decoder->p_building_pat) if (p_pat_decoder->p_building_pat)
{ {
if (dvbpsi_CheckPAT(p_dvbpsi, p_section)) if (dvbpsi_CheckPAT(p_dvbpsi, p_pat_decoder, p_section))
dvbpsi_ReInitPAT(p_pat_decoder, true); dvbpsi_ReInitPAT(p_pat_decoder, true);
} }
else else
......
...@@ -101,28 +101,33 @@ typedef void (* dvbpsi_pat_callback)(void* p_cb_data, dvbpsi_pat_t* p_new_pat); ...@@ -101,28 +101,33 @@ typedef void (* dvbpsi_pat_callback)(void* p_cb_data, dvbpsi_pat_t* p_new_pat);
* dvbpsi_pat_attach * dvbpsi_pat_attach
*****************************************************************************/ *****************************************************************************/
/*! /*!
* \fn bool dvbpsi_pat_attach(dvbpsi_t *p_dvbpsi, dvbpsi_pat_callback pf_callback, void* p_cb_data) * \fn bool dvbpsi_pat_attach(dvbpsi_t *p_dvbpsi, uint8_t i_table_id, uint16_t i_extension,
* dvbpsi_pat_callback pf_callback, void* p_cb_data)
* \brief Creation and initialization of a PAT decoder. The decoder will be attached to 'p_dvbpsi' argument. * \brief Creation and initialization of a PAT decoder. The decoder will be attached to 'p_dvbpsi' argument.
* \param p_dvbpsi handle to dvbpsi with attached decoder * \param p_dvbpsi handle to dvbpsi with attached decoder
* \param i_table_id Table ID
* \param i_extension Table ID extension
* \param pf_callback function to call back on new PAT * \param pf_callback function to call back on new PAT
* \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 true on success, false on failure * \return true on success, false on failure
*/ */
bool dvbpsi_pat_attach(dvbpsi_t *p_dvbpsi, dvbpsi_pat_callback pf_callback, bool dvbpsi_pat_attach(dvbpsi_t *p_dvbpsi, uint8_t i_table_id, uint16_t i_extension,
void* p_cb_data); dvbpsi_pat_callback pf_callback, void* p_cb_data);
/***************************************************************************** /*****************************************************************************
* dvbpsi_pat_detach * dvbpsi_pat_detach
*****************************************************************************/ *****************************************************************************/
/*! /*!
* \fn void dvbpsi_pat_detach(dvbpsi_t *p_dvbpsi) * \fn void dvbpsi_pat_detach(dvbpsi_t *p_dvbpsi, uint8_t i_table_id, uint16_t i_extension)
* \brief Destroy a PAT decoder. * \brief Destroy a PAT decoder.
* \param p_dvbpsi pointer to dvbpsi_t handle * \param p_dvbpsi pointer to dvbpsi_t handle
* \param i_table_id Table ID
* \param i_extension Table ID extension
* \return nothing. * \return nothing.
* *
* The handle isn't valid any more. * The handle isn't valid any more.
*/ */
void dvbpsi_pat_detach(dvbpsi_t *p_dvbpsi); void dvbpsi_pat_detach(dvbpsi_t *p_dvbpsi, uint8_t i_table_id, uint16_t i_extension);
/***************************************************************************** /*****************************************************************************
* dvbpsi_pat_init/dvbpsi_pat_new * dvbpsi_pat_init/dvbpsi_pat_new
......
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