Commit 6441136a authored by Jean-Paul Saman's avatar Jean-Paul Saman

PMT: implement as chained decoder

parent 71126f5c
...@@ -43,12 +43,14 @@ ...@@ -43,12 +43,14 @@
#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/descriptor.h" #include "../src/descriptor.h"
#include "../src/tables/pmt.h" #include "../src/tables/pmt.h"
#include "../src/descriptors/dr.h" #include "../src/descriptors/dr.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/descriptor.h> #include <dvbpsi/descriptor.h>
#include <dvbpsi/pmt.h> #include <dvbpsi/pmt.h>
#include <dvbpsi/dr.h> #include <dvbpsi/dr.h>
...@@ -211,7 +213,6 @@ static void DumpDescriptors(const char* str, dvbpsi_descriptor_t* p_descriptor) ...@@ -211,7 +213,6 @@ static void DumpDescriptors(const char* str, dvbpsi_descriptor_t* p_descriptor)
} }
}; };
/***************************************************************************** /*****************************************************************************
* DumpPMT * DumpPMT
*****************************************************************************/ *****************************************************************************/
...@@ -258,17 +259,18 @@ static void message(dvbpsi_t *handle, const dvbpsi_msg_level_t level, const char ...@@ -258,17 +259,18 @@ 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;
uint16_t i_program_number, i_pmt_pid; uint16_t i_program_number, i_pmt_pid;
if (i_argc != 4) if (i_argc != 4)
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;
i_program_number = atoi(pa_argv[2]); i_program_number = atoi(pa_argv[2]);
i_pmt_pid = atoi(pa_argv[3]); i_pmt_pid = atoi(pa_argv[3]);
...@@ -276,8 +278,7 @@ int main(int i_argc, char* pa_argv[]) ...@@ -276,8 +278,7 @@ int main(int i_argc, char* pa_argv[])
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_pmt_attach(p_dvbpsi, 0x02, 0x0, i_program_number, DumpPMT, NULL))
if (!dvbpsi_pmt_attach(p_dvbpsi, i_program_number, DumpPMT, NULL))
goto out; goto out;
b_ok = ReadPacket(i_fd, data); b_ok = ReadPacket(i_fd, data);
...@@ -290,14 +291,16 @@ int main(int i_argc, char* pa_argv[]) ...@@ -290,14 +291,16 @@ 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_pmt_detach(p_dvbpsi); dvbpsi_pmt_detach(p_dvbpsi, 0x02, 0x0);
dvbpsi_delete(p_dvbpsi); dvbpsi_delete(p_dvbpsi);
} }
close(i_fd); close(i_fd);
return 0; return ret;
} }
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,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 "../descriptor.h" #include "../descriptor.h"
#include "pmt.h" #include "pmt.h"
#include "pmt_private.h" #include "pmt_private.h"
...@@ -52,11 +53,20 @@ ...@@ -52,11 +53,20 @@
***************************************************************************** *****************************************************************************
* Initialize a PMT decoder and return a handle on it. * Initialize a PMT decoder and return a handle on it.
*****************************************************************************/ *****************************************************************************/
bool dvbpsi_pmt_attach(dvbpsi_t *p_dvbpsi, uint16_t i_program_number, bool dvbpsi_pmt_attach(dvbpsi_t *p_dvbpsi, uint8_t i_table_id, uint16_t i_extension,
dvbpsi_pmt_callback pf_callback, void* p_cb_data) uint16_t i_program_number, dvbpsi_pmt_callback pf_callback, void* p_cb_data)
{ {
assert(p_dvbpsi); assert(p_dvbpsi);
assert(p_dvbpsi->p_decoder == NULL);
dvbpsi_decoder_t* p_dec = dvbpsi_decoder_chain_get(p_dvbpsi, i_table_id, i_extension);
if (p_dec != NULL)
{
dvbpsi_error(p_dvbpsi, "PMT decoder",
"Already a decoder for (table_id == 0x%02x,"
"extension == 0x%02x)",
i_table_id, i_extension);
return false;
}
dvbpsi_pmt_decoder_t* p_pmt_decoder; dvbpsi_pmt_decoder_t* p_pmt_decoder;
p_pmt_decoder = (dvbpsi_pmt_decoder_t*) dvbpsi_decoder_new(&dvbpsi_pmt_sections_gather, p_pmt_decoder = (dvbpsi_pmt_decoder_t*) dvbpsi_decoder_new(&dvbpsi_pmt_sections_gather,
...@@ -64,14 +74,22 @@ bool dvbpsi_pmt_attach(dvbpsi_t *p_dvbpsi, uint16_t i_program_number, ...@@ -64,14 +74,22 @@ bool dvbpsi_pmt_attach(dvbpsi_t *p_dvbpsi, uint16_t i_program_number,
if (p_pmt_decoder == NULL) if (p_pmt_decoder == NULL)
return false; return false;
p_dvbpsi->p_decoder = DVBPSI_DECODER(p_pmt_decoder);
/* PMT decoder configuration */ /* PMT decoder configuration */
p_pmt_decoder->i_program_number = i_program_number; p_pmt_decoder->i_program_number = i_program_number;
p_pmt_decoder->pf_pmt_callback = pf_callback; p_pmt_decoder->pf_pmt_callback = pf_callback;
p_pmt_decoder->p_cb_data = p_cb_data; p_pmt_decoder->p_cb_data = p_cb_data;
p_pmt_decoder->p_building_pmt = NULL; p_pmt_decoder->p_building_pmt = NULL;
p_pmt_decoder->i_table_id = i_table_id;
p_pmt_decoder->i_extension = i_extension;
/* Add pmt decoder to decoder chain */
if (!dvbpsi_decoder_chain_add(p_dvbpsi, DVBPSI_DECODER(p_pmt_decoder)))
{
dvbpsi_decoder_delete(DVBPSI_DECODER(p_pmt_decoder));
return false;
}
return true; return true;
} }
...@@ -80,19 +98,36 @@ bool dvbpsi_pmt_attach(dvbpsi_t *p_dvbpsi, uint16_t i_program_number, ...@@ -80,19 +98,36 @@ bool dvbpsi_pmt_attach(dvbpsi_t *p_dvbpsi, uint16_t i_program_number,
***************************************************************************** *****************************************************************************
* Close a PMT decoder. The handle isn't valid any more. * Close a PMT decoder. The handle isn't valid any more.
*****************************************************************************/ *****************************************************************************/
void dvbpsi_pmt_detach(dvbpsi_t *p_dvbpsi) void dvbpsi_pmt_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_pmt_decoder_t* p_pmt_decoder; dvbpsi_pmt_decoder_t *p_pmt_decoder =
p_pmt_decoder = (dvbpsi_pmt_decoder_t*)p_dvbpsi->p_decoder; (dvbpsi_pmt_decoder_t*) dvbpsi_decoder_chain_get(p_dvbpsi, i_table_id, i_extension);
if (!p_pmt_decoder)
{
dvbpsi_error(p_dvbpsi, "PMT Decoder",
"No such PMT 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_pmt_decoder)))
{
dvbpsi_error(p_dvbpsi, "PMT Decoder",
"Failed to remove"
"extension == 0x%02x)",
i_table_id, i_extension);
return;
}
if (p_pmt_decoder->p_building_pmt) if (p_pmt_decoder->p_building_pmt)
dvbpsi_pmt_delete(p_pmt_decoder->p_building_pmt); dvbpsi_pmt_delete(p_pmt_decoder->p_building_pmt);
p_pmt_decoder->p_building_pmt = NULL; p_pmt_decoder->p_building_pmt = NULL;
dvbpsi_decoder_delete(DVBPSI_DECODER(p_pmt_decoder));
dvbpsi_decoder_delete(p_dvbpsi->p_decoder); p_pmt_decoder = NULL;
p_dvbpsi->p_decoder = NULL;
} }
/***************************************************************************** /*****************************************************************************
...@@ -258,13 +293,10 @@ static void dvbpsi_ReInitPMT(dvbpsi_pmt_decoder_t* p_decoder, const bool b_force ...@@ -258,13 +293,10 @@ static void dvbpsi_ReInitPMT(dvbpsi_pmt_decoder_t* p_decoder, const bool b_force
p_decoder->p_building_pmt = NULL; p_decoder->p_building_pmt = NULL;
} }
static bool dvbpsi_CheckPMT(dvbpsi_t *p_dvbpsi, dvbpsi_psi_section_t *p_section) static bool dvbpsi_CheckPMT(dvbpsi_t *p_dvbpsi, dvbpsi_pmt_decoder_t* p_pmt_decoder,
dvbpsi_psi_section_t *p_section)
{ {
bool b_reinit = false; bool b_reinit = false;
assert(p_dvbpsi->p_decoder);
dvbpsi_pmt_decoder_t* p_pmt_decoder;
p_pmt_decoder = (dvbpsi_pmt_decoder_t *)p_dvbpsi->p_decoder;
if (p_pmt_decoder->p_building_pmt->i_version != p_section->i_version) if (p_pmt_decoder->p_building_pmt->i_version != p_section->i_version)
{ {
...@@ -322,7 +354,6 @@ static bool dvbpsi_AddSectionPMT(dvbpsi_t *p_dvbpsi, dvbpsi_pmt_decoder_t *p_pmt ...@@ -322,7 +354,6 @@ static bool dvbpsi_AddSectionPMT(dvbpsi_t *p_dvbpsi, dvbpsi_pmt_decoder_t *p_pmt
void dvbpsi_pmt_sections_gather(dvbpsi_t *p_dvbpsi, dvbpsi_psi_section_t* p_section) void dvbpsi_pmt_sections_gather(dvbpsi_t *p_dvbpsi, dvbpsi_psi_section_t* p_section)
{ {
assert(p_dvbpsi); assert(p_dvbpsi);
assert(p_dvbpsi->p_decoder);
if (!dvbpsi_CheckPSISection(p_dvbpsi, p_section, 0x02, "PMT decoder")) if (!dvbpsi_CheckPSISection(p_dvbpsi, p_section, 0x02, "PMT decoder"))
{ {
...@@ -331,10 +362,15 @@ void dvbpsi_pmt_sections_gather(dvbpsi_t *p_dvbpsi, dvbpsi_psi_section_t* p_sect ...@@ -331,10 +362,15 @@ void dvbpsi_pmt_sections_gather(dvbpsi_t *p_dvbpsi, dvbpsi_psi_section_t* p_sect
} }
/* */ /* */
dvbpsi_pmt_decoder_t* p_pmt_decoder = (dvbpsi_pmt_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);
assert(p_pmt_decoder); if (!p_dec)
{
dvbpsi_DeletePSISections(p_section);
return;
}
/* We have a valid PMT section */ /* We have a valid PMT section */
dvbpsi_pmt_decoder_t* p_pmt_decoder = (dvbpsi_pmt_decoder_t*) p_dec;
if (p_pmt_decoder->i_program_number != p_section->i_extension) if (p_pmt_decoder->i_program_number != p_section->i_extension)
{ {
/* Invalid program_number */ /* Invalid program_number */
...@@ -355,7 +391,7 @@ void dvbpsi_pmt_sections_gather(dvbpsi_t *p_dvbpsi, dvbpsi_psi_section_t* p_sect ...@@ -355,7 +391,7 @@ void dvbpsi_pmt_sections_gather(dvbpsi_t *p_dvbpsi, dvbpsi_psi_section_t* p_sect
/* Perform some few sanity checks */ /* Perform some few sanity checks */
if (p_pmt_decoder->p_building_pmt) if (p_pmt_decoder->p_building_pmt)
{ {
if (dvbpsi_CheckPMT(p_dvbpsi, p_section)) if (dvbpsi_CheckPMT(p_dvbpsi, p_pmt_decoder, p_section))
dvbpsi_ReInitPMT(p_pmt_decoder, true); dvbpsi_ReInitPMT(p_pmt_decoder, true);
} }
else else
......
...@@ -107,32 +107,39 @@ typedef void (* dvbpsi_pmt_callback)(void* p_cb_data, dvbpsi_pmt_t* p_new_pmt); ...@@ -107,32 +107,39 @@ typedef void (* dvbpsi_pmt_callback)(void* p_cb_data, dvbpsi_pmt_t* p_new_pmt);
*****************************************************************************/ *****************************************************************************/
/*! /*!
* \fn bool dvbpsi_pmt_attach(dvbpsi_t *p_dvbpsi, * \fn bool dvbpsi_pmt_attach(dvbpsi_t *p_dvbpsi,
uint16_t i_program_number, * uint8_t i_table_id,
dvbpsi_pmt_callback pf_callback, * uint16_t i_extension,
void* p_cb_data) uint16_t i_program_number,
dvbpsi_pmt_callback pf_callback,
void* p_cb_data)
* \brief Creates and initialization of a PMT decoder and attaches it to dvbpsi_t * \brief Creates and initialization of a PMT decoder and attaches it to dvbpsi_t
* handle * handle
* \param p_dvbpsi handle * \param p_dvbpsi handle
* \param i_table_id Table ID
* \param i_extension Table ID extension
* \param i_program_number program number * \param i_program_number program number
* \param pf_callback function to call back on new PMT * \param pf_callback function to call back on new PMT
* \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_pmt_attach(dvbpsi_t *p_dvbpsi, uint16_t i_program_number, bool dvbpsi_pmt_attach(dvbpsi_t *p_dvbpsi, uint8_t i_table_id, uint16_t i_extension,
dvbpsi_pmt_callback pf_callback, void* p_cb_data); uint16_t i_program_number,
dvbpsi_pmt_callback pf_callback, void* p_cb_data);
/***************************************************************************** /*****************************************************************************
* dvbpsi_pmt_detach * dvbpsi_pmt_detach
*****************************************************************************/ *****************************************************************************/
/*! /*!
* \fn void dvbpsi_pmt_detach(dvbpsi_t *p_dvbpsi) * \fn void dvbpsi_pmt_detach(dvbpsi_t *p_dvbpsi, uint8_t i_table_id, uint16_t i_extension)
* \brief Destroy a PMT decoder. * \brief Destroy a PMT decoder.
* \param p_dvbpsi handle * \param p_dvbpsi 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_pmt_detach(dvbpsi_t *p_dvbpsi); void dvbpsi_pmt_detach(dvbpsi_t *p_dvbpsi, uint8_t i_table_id, uint16_t i_extension);
/***************************************************************************** /*****************************************************************************
* dvbpsi_pmt_init/dvbpsi_pmt_new * dvbpsi_pmt_init/dvbpsi_pmt_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