/***************************************************************************** * dvbpsi_pat_detach ***************************************************************************** * Close a PAT decoder. The handle isn't valid any more. *****************************************************************************/ void dvbpsi_pat_detach(dvbpsi_t *p_dvbpsi, uint8_t i_table_id, uint16_t i_extension) { assert(p_dvbpsi); 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) dvbpsi_pat_delete(p_pat_decoder->p_building_pat); p_pat_decoder->p_building_pat = NULL; dvbpsi_decoder_delete(DVBPSI_DECODER(p_pat_decoder)); p_pat_decoder = NULL; }
static bool dvbpsi_AddSectionPMT( dvbpsi_t *p_dvbpsi, dvbpsi_pmt_decoder_t *p_pmt_decoder, dvbpsi_psi_section_t* p_section ) { assert( p_dvbpsi ); assert( p_pmt_decoder ); assert( p_section ); /* Initialize the structures if it's the first section received */ if ( p_pmt_decoder->p_building_pmt == NULL ) { p_pmt_decoder->p_building_pmt = dvbpsi_pmt_new( p_pmt_decoder->i_program_number, p_section->i_version, p_section->b_current_next, ( (uint16_t) (p_section->p_payload_start[0] & 0x1f) << 8)//0x02 | p_section->p_payload_start[1] );// 0xb0 if ( p_pmt_decoder->p_building_pmt == NULL ) return(false); p_pmt_decoder->i_last_section_number = p_section->i_last_number; } /* Add to linked list of sections */ if ( dvbpsi_decoder_psi_section_add( DVBPSI_DECODER( p_pmt_decoder ), p_section ) ) dvbpsi_debug( p_dvbpsi, "PMT decoder", "overwrite section number %d", p_section->i_number ); return(true); }
static bool dvbpsi_AddSectionTOT(dvbpsi_t *p_dvbpsi, dvbpsi_tot_decoder_t *p_tot_decoder, dvbpsi_psi_section_t* p_section) { assert(p_dvbpsi); assert(p_tot_decoder); assert(p_section); /* Initialize the structures if it's the first section received */ if (!p_tot_decoder->p_building_tot) { p_tot_decoder->p_building_tot = dvbpsi_tot_new( p_section->i_table_id, p_section->i_extension, p_section->i_version, p_section->b_current_next, ((uint64_t)p_section->p_payload_start[0] << 32) | ((uint64_t)p_section->p_payload_start[1] << 24) | ((uint64_t)p_section->p_payload_start[2] << 16) | ((uint64_t)p_section->p_payload_start[3] << 8) | (uint64_t)p_section->p_payload_start[4]); if (p_tot_decoder->p_building_tot == NULL) return false; p_tot_decoder->i_last_section_number = p_section->i_last_number; } /* Add to linked list of sections */ if (dvbpsi_decoder_psi_section_add(DVBPSI_DECODER(p_tot_decoder), p_section)) dvbpsi_debug(p_dvbpsi, "TOT decoder", "overwrite section number %d", p_section->i_number); return true; }
static bool dvbpsi_AddSectionETT(dvbpsi_t *p_dvbpsi, dvbpsi_atsc_ett_decoder_t *p_decoder, dvbpsi_psi_section_t* p_section) { assert(p_dvbpsi); assert(p_decoder); assert(p_section); /* Initialize the structures if it's the first section received */ if (!p_decoder->p_building_ett) { uint32_t i_etm_id = ((uint32_t)p_section->p_payload_start[1] << 24) | ((uint32_t)p_section->p_payload_start[2] << 16) | ((uint32_t)p_section->p_payload_start[3] << 8) | ((uint32_t)p_section->p_payload_start[4] << 0); p_decoder->p_building_ett = dvbpsi_atsc_NewETT(p_section->i_table_id, p_section->i_extension, p_section->i_version, p_section->p_payload_start[0], i_etm_id, p_section->b_current_next); if (!p_decoder->p_building_ett) return false; p_decoder->i_last_section_number = p_section->i_last_number; } /* Add to linked list of sections */ if (dvbpsi_decoder_psi_section_add(DVBPSI_DECODER(p_decoder), p_section)) dvbpsi_debug(p_dvbpsi, "ATSC ETT decoder", "overwrite section number %d", p_section->i_number); return true; }
static bool dvbpsi_AddSectionCAT(dvbpsi_t *p_dvbpsi, dvbpsi_cat_decoder_t *p_decoder, dvbpsi_psi_section_t* p_section) { assert(p_dvbpsi); assert(p_decoder); assert(p_section); /* Initialize the structures if it's the first section received */ if (p_decoder->p_building_cat == NULL) { p_decoder->p_building_cat = dvbpsi_cat_new(p_section->i_version, p_section->b_current_next); if (p_decoder->p_building_cat == NULL) return false; p_decoder->i_last_section_number = p_section->i_last_number; } /* Add to linked list of sections */ if (dvbpsi_decoder_psi_section_add(DVBPSI_DECODER(p_decoder), p_section)) dvbpsi_debug(p_dvbpsi, "CAT decoder", "overwrite section number %d", p_section->i_number); return true; }
/***************************************************************************** * dvbpsi_nit_attach ***************************************************************************** * Initialize a NIT subtable decoder. *****************************************************************************/ bool dvbpsi_nit_attach(dvbpsi_t* p_dvbpsi, uint8_t i_table_id, uint16_t i_extension, dvbpsi_nit_callback pf_callback, void* p_cb_data) { assert(p_dvbpsi); assert(p_dvbpsi->p_decoder); dvbpsi_demux_t* p_demux = (dvbpsi_demux_t*)p_dvbpsi->p_decoder; if (dvbpsi_demuxGetSubDec(p_demux, i_table_id, i_extension)) { dvbpsi_error(p_dvbpsi, "NIT decoder", "Already a decoder for (table_id == 0x%02x," "extension == 0x%02x)", i_table_id, i_extension); return false; } dvbpsi_nit_decoder_t* p_nit_decoder; p_nit_decoder = (dvbpsi_nit_decoder_t*) dvbpsi_decoder_new(NULL, 0, true, sizeof(dvbpsi_nit_decoder_t)); if (p_nit_decoder == NULL) return false; /* subtable decoder configuration */ dvbpsi_demux_subdec_t* p_subdec; p_subdec = dvbpsi_NewDemuxSubDecoder(i_table_id, i_extension, dvbpsi_nit_detach, dvbpsi_nit_sections_gather, DVBPSI_DECODER(p_nit_decoder)); if (p_subdec == NULL) { dvbpsi_decoder_delete(DVBPSI_DECODER(p_nit_decoder)); return false; } /* Attach the subtable decoder to the demux */ dvbpsi_AttachDemuxSubDecoder(p_demux, p_subdec); /* NIT decoder information */ p_nit_decoder->i_network_id = i_extension; p_nit_decoder->pf_nit_callback = pf_callback; p_nit_decoder->p_cb_data = p_cb_data; p_nit_decoder->p_building_nit = NULL; return true; }
/***************************************************************************** * dvbpsi_atsc_AttachETT ***************************************************************************** * Initialize a ETT decoder and return a handle on it. *****************************************************************************/ bool dvbpsi_atsc_AttachETT(dvbpsi_t * p_dvbpsi, uint8_t i_table_id, uint16_t i_extension, dvbpsi_atsc_ett_callback pf_callback, void* p_cb_data) { assert(p_dvbpsi); assert(p_dvbpsi->p_decoder); dvbpsi_demux_t* p_demux = (dvbpsi_demux_t*)p_dvbpsi->p_decoder; if (dvbpsi_demuxGetSubDec(p_demux, i_table_id, i_extension)) { dvbpsi_error(p_dvbpsi, "ATSC ETT decoder", "Already a decoder for (table_id == 0x%02x extension == 0x%04x)", i_table_id, i_extension); return false; } dvbpsi_atsc_ett_decoder_t* p_ett_decoder; p_ett_decoder = (dvbpsi_atsc_ett_decoder_t*) dvbpsi_decoder_new(NULL, 0, true, sizeof(dvbpsi_atsc_ett_decoder_t)); if (p_ett_decoder == NULL) return false; /* PSI decoder configuration */ dvbpsi_demux_subdec_t* p_subdec; p_subdec = dvbpsi_NewDemuxSubDecoder(i_table_id, i_extension, dvbpsi_atsc_DetachETT, dvbpsi_atsc_GatherETTSections, DVBPSI_DECODER(p_ett_decoder)); if (p_subdec == NULL) { dvbpsi_decoder_delete(DVBPSI_DECODER(p_ett_decoder)); return false; } /* Attach the subtable decoder to the demux */ dvbpsi_AttachDemuxSubDecoder(p_demux, p_subdec); /* ETT decoder information */ p_ett_decoder->pf_ett_callback = pf_callback; p_ett_decoder->p_cb_data = p_cb_data; p_ett_decoder->p_building_ett = NULL; return true; }
/***************************************************************************** * dvbpsi_pat_attach ***************************************************************************** * Initialize a PAT decoder and return a handle on it. *****************************************************************************/ bool dvbpsi_pat_attach(dvbpsi_t *p_dvbpsi, uint8_t i_table_id, uint16_t i_extension, dvbpsi_pat_callback pf_callback, void* p_priv) { assert(p_dvbpsi); /* 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; p_pat_decoder = (dvbpsi_pat_decoder_t*) dvbpsi_decoder_new(&dvbpsi_pat_sections_gather, 1024, true, sizeof(dvbpsi_pat_decoder_t)); if (p_pat_decoder == NULL) return false; /* PAT decoder information */ p_pat_decoder->pf_pat_callback = pf_callback; p_pat_decoder->p_priv = p_priv; p_pat_decoder->p_building_pat = NULL; 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; }
static void dvbpsi_ReInitCAT(dvbpsi_cat_decoder_t* p_decoder, const bool b_force) { assert(p_decoder); dvbpsi_decoder_reset(DVBPSI_DECODER(p_decoder), b_force); /* Force redecoding */ if (b_force) { /* Free structures */ if (p_decoder->p_building_cat) dvbpsi_cat_delete(p_decoder->p_building_cat); } p_decoder->p_building_cat = NULL; }
/***************************************************************************** * dvbpsi_cat_attach ***************************************************************************** * Initialize a CAT decoder and return a handle on it. *****************************************************************************/ bool dvbpsi_cat_attach(dvbpsi_t *p_dvbpsi, dvbpsi_cat_callback pf_callback, void* p_cb_data) { assert(p_dvbpsi); assert(p_dvbpsi->p_decoder == NULL); dvbpsi_cat_decoder_t* p_cat_decoder; p_cat_decoder = (dvbpsi_cat_decoder_t*) dvbpsi_decoder_new(&dvbpsi_cat_sections_gather, 1024, true, sizeof(dvbpsi_cat_decoder_t)); if (p_cat_decoder == NULL) return false; /* CAT decoder configuration */ p_cat_decoder->pf_cat_callback = pf_callback; p_cat_decoder->p_cb_data = p_cb_data; p_cat_decoder->p_building_cat = NULL; p_dvbpsi->p_decoder = DVBPSI_DECODER(p_cat_decoder); return true; }
/***************************************************************************** * dvbpsi_pat_attach ***************************************************************************** * Initialize a PAT decoder and return a handle on it. *****************************************************************************/ bool dvbpsi_pat_attach( dvbpsi_t *p_dvbpsi, dvbpsi_pat_callback pf_callback, void* p_cb_data ) { assert( p_dvbpsi ); assert( p_dvbpsi->p_decoder == NULL ); /* PSI decoder configuration and initial state */ dvbpsi_pat_decoder_t *p_pat_decoder; p_pat_decoder = (dvbpsi_pat_decoder_t *) dvbpsi_decoder_new( &dvbpsi_pat_sections_gather, 4096, true, sizeof(dvbpsi_pat_decoder_t) ); if ( p_pat_decoder == NULL ) return(false); /* PAT decoder information */ p_pat_decoder->pf_pat_callback = pf_callback; p_pat_decoder->p_cb_data = p_cb_data; p_pat_decoder->p_building_pat = NULL; p_dvbpsi->p_decoder = DVBPSI_DECODER( p_pat_decoder ); return(true); }
/***************************************************************************** * dvbpsi_pmt_attach ***************************************************************************** * Initialize a PMT decoder and return a handle on it. *****************************************************************************/ bool dvbpsi_pmt_attach( dvbpsi_t *p_dvbpsi, uint16_t i_program_number, dvbpsi_pmt_callback pf_callback, void* p_cb_data ) { assert( p_dvbpsi ); assert( p_dvbpsi->p_decoder == NULL ); dvbpsi_pmt_decoder_t* p_pmt_decoder; p_pmt_decoder = (dvbpsi_pmt_decoder_t *) dvbpsi_decoder_new( &dvbpsi_pmt_sections_gather, 4096, true, sizeof(dvbpsi_pmt_decoder_t) ); if ( p_pmt_decoder == NULL ) return(false); p_dvbpsi->p_decoder = DVBPSI_DECODER( p_pmt_decoder ); /* PMT decoder configuration */ p_pmt_decoder->i_program_number = i_program_number; p_pmt_decoder->pf_pmt_callback = pf_callback; p_pmt_decoder->p_cb_data = p_cb_data; p_pmt_decoder->p_building_pmt = NULL; return(true); }
/***************************************************************************** * dvbpsi_sis_sections_gather ***************************************************************************** * Callback for the subtable demultiplexor. *****************************************************************************/ void dvbpsi_sis_sections_gather(dvbpsi_t *p_dvbpsi, dvbpsi_decoder_t *p_decoder, dvbpsi_psi_section_t * p_section) { assert(p_dvbpsi); assert(p_dvbpsi->p_decoder); if (!dvbpsi_CheckPSISection(p_dvbpsi, p_section, 0xFC, "SIS decoder")) { dvbpsi_DeletePSISections(p_section); return; } /* */ dvbpsi_demux_t *p_demux = (dvbpsi_demux_t *) p_dvbpsi->p_decoder; dvbpsi_sis_decoder_t * p_sis_decoder = (dvbpsi_sis_decoder_t*)p_decoder; if (p_section->b_private_indicator) { /* Invalid private_syntax_indicator */ dvbpsi_error(p_dvbpsi, "SIS decoder", "invalid private section (private_syntax_indicator != false)"); dvbpsi_DeletePSISections(p_section); return; } /* TS discontinuity check */ if (p_demux->b_discontinuity) { dvbpsi_ReInitSIS(p_sis_decoder, true); p_sis_decoder->b_discontinuity = false; p_demux->b_discontinuity = false; } else { /* Perform a few sanity checks */ if (p_sis_decoder->p_building_sis) { if (dvbpsi_CheckSIS(p_dvbpsi, p_sis_decoder, p_section)) dvbpsi_ReInitSIS(p_sis_decoder, true); } else { if( (p_sis_decoder->b_current_valid) && (p_sis_decoder->current_sis.i_version == p_section->i_version) && (p_sis_decoder->current_sis.b_current_next == p_section->b_current_next)) { /* Don't decode since this version is already decoded */ dvbpsi_debug(p_dvbpsi, "SIT decoder", "ignoring already decoded section %d", p_section->i_number); dvbpsi_DeletePSISections(p_section); return; } } } /* Add section to SIS */ if (!dvbpsi_AddSectionSIS(p_dvbpsi, p_sis_decoder, p_section)) { dvbpsi_error(p_dvbpsi, "SIS decoder", "failed decoding section %d", p_section->i_number); dvbpsi_DeletePSISections(p_section); return; } /* Check if we have all the sections */ if (dvbpsi_decoder_psi_sections_completed(DVBPSI_DECODER(p_sis_decoder))) { assert(p_sis_decoder->pf_sis_callback); /* Save the current information */ p_sis_decoder->current_sis = *p_sis_decoder->p_building_sis; p_sis_decoder->b_current_valid = true; /* Decode the sections */ dvbpsi_sis_sections_decode(p_dvbpsi, p_sis_decoder->p_building_sis, p_sis_decoder->p_sections); /* Delete the sections */ dvbpsi_DeletePSISections(p_sis_decoder->p_sections); p_sis_decoder->p_sections = NULL; /* signal the new SDT */ p_sis_decoder->pf_sis_callback(p_sis_decoder->p_cb_data, p_sis_decoder->p_building_sis); /* Reinitialize the structures */ dvbpsi_ReInitSIS(p_sis_decoder, false); } }
/***************************************************************************** * dvbpsi_cat_sections_gather ***************************************************************************** * Callback for the PSI decoder. *****************************************************************************/ void dvbpsi_cat_sections_gather(dvbpsi_t *p_dvbpsi, dvbpsi_psi_section_t* p_section) { assert(p_dvbpsi); assert(p_dvbpsi->p_decoder); if (!dvbpsi_CheckPSISection(p_dvbpsi, p_section, 0x01, "CAT decoder")) { dvbpsi_DeletePSISections(p_section); return; } /* */ dvbpsi_cat_decoder_t* p_cat_decoder = (dvbpsi_cat_decoder_t*)p_dvbpsi->p_decoder; /* TS discontinuity check */ if (p_cat_decoder->b_discontinuity) { dvbpsi_ReInitCAT(p_cat_decoder, true); p_cat_decoder->b_discontinuity = false; } else { /* Perform some few sanity checks */ if (p_cat_decoder->p_building_cat) { if (dvbpsi_CheckCAT(p_dvbpsi, p_section)) dvbpsi_ReInitCAT(p_cat_decoder, true); } else { if ( (p_cat_decoder->b_current_valid) && (p_cat_decoder->current_cat.i_version == p_section->i_version) && (p_cat_decoder->current_cat.b_current_next == p_section->b_current_next)) { /* Don't decode since this version is already decoded */ dvbpsi_debug(p_dvbpsi, "CAT decoder", "ignoring already decoded section %d", p_section->i_number); dvbpsi_DeletePSISections(p_section); return; } } } /* Add section to CAT */ if (!dvbpsi_AddSectionCAT(p_dvbpsi, p_cat_decoder, p_section)) { dvbpsi_error(p_dvbpsi, "CAT decoder", "failed decoding section %d", p_section->i_number); dvbpsi_DeletePSISections(p_section); return; } /* Check if we have all the sections */ if (dvbpsi_decoder_psi_sections_completed(DVBPSI_DECODER(p_cat_decoder))) { assert(p_cat_decoder->pf_cat_callback); /* Save the current information */ p_cat_decoder->current_cat = *p_cat_decoder->p_building_cat; p_cat_decoder->b_current_valid = true; /* Decode the sections */ dvbpsi_cat_sections_decode(p_cat_decoder->p_building_cat, p_cat_decoder->p_sections); /* signal the new CAT */ p_cat_decoder->pf_cat_callback(p_cat_decoder->p_cb_data, p_cat_decoder->p_building_cat); /* Delete sections and Reinitialize the structures */ dvbpsi_ReInitCAT(p_cat_decoder, false); assert(p_cat_decoder->p_sections == NULL); } }
/***************************************************************************** * dvbpsi_nit_sections_gather ***************************************************************************** * Callback for the PSI decoder. *****************************************************************************/ void dvbpsi_nit_sections_gather(dvbpsi_t *p_dvbpsi, dvbpsi_decoder_t *p_private_decoder, dvbpsi_psi_section_t *p_section) { assert(p_dvbpsi); const uint8_t i_table_id = ((p_section->i_table_id == 0x40) || (p_section->i_table_id == 0x41)) ? p_section->i_table_id : 0x40; if (!dvbpsi_CheckPSISection(p_dvbpsi, p_section, i_table_id, "NIT decoder")) { dvbpsi_DeletePSISections(p_section); return; } /* */ dvbpsi_nit_decoder_t* p_nit_decoder = (dvbpsi_nit_decoder_t*)p_private_decoder; /* We have a valid NIT section */ if (p_nit_decoder->i_network_id != p_section->i_extension) { /* Invalid program_number */ dvbpsi_error(p_dvbpsi, "NIT decoder", "'network_id' don't match"); dvbpsi_DeletePSISections(p_section); return; } /* TS discontinuity check */ if (p_nit_decoder->b_discontinuity) { dvbpsi_ReInitNIT(p_nit_decoder, true); p_nit_decoder->b_discontinuity = false; } else { /* Perform some few sanity checks */ if (p_nit_decoder->p_building_nit) { if (dvbpsi_CheckNIT(p_dvbpsi, p_nit_decoder, p_section)) dvbpsi_ReInitNIT(p_nit_decoder, true); } else { if ( (p_nit_decoder->b_current_valid) && (p_nit_decoder->current_nit.i_version == p_section->i_version) && (p_nit_decoder->current_nit.b_current_next == p_section->b_current_next)) { /* Don't decode since this version is already decoded */ dvbpsi_debug(p_dvbpsi, "NIT decoder", "ignoring already decoded section %d", p_section->i_number); dvbpsi_DeletePSISections(p_section); return;; } } } /* Add section to NIT */ if (!dvbpsi_AddSectionNIT(p_dvbpsi, p_nit_decoder, p_section)) { dvbpsi_error(p_dvbpsi, "NIT decoder", "failed decoding section %d", p_section->i_number); dvbpsi_DeletePSISections(p_section); return; } /* Check if we have all the sections */ if (dvbpsi_decoder_psi_sections_completed(DVBPSI_DECODER(p_nit_decoder))) { assert(p_nit_decoder->pf_nit_callback); /* Save the current information */ p_nit_decoder->current_nit = *p_nit_decoder->p_building_nit; p_nit_decoder->b_current_valid = true; /* Decode the sections */ dvbpsi_nit_sections_decode(p_nit_decoder->p_building_nit, p_nit_decoder->p_sections); /* signal the new NIT */ p_nit_decoder->pf_nit_callback(p_nit_decoder->p_cb_data, p_nit_decoder->p_building_nit); /* Delete sections and Reinitialize the structures */ dvbpsi_ReInitNIT(p_nit_decoder, false); assert(p_nit_decoder->p_sections == NULL); } }
/***************************************************************************** * dvbpsi_atsc_GatherETTSections ***************************************************************************** * Callback for the PSI decoder. *****************************************************************************/ static void dvbpsi_atsc_GatherETTSections(dvbpsi_t* p_dvbpsi, dvbpsi_decoder_t *p_decoder, dvbpsi_psi_section_t* p_section) { assert(p_dvbpsi); assert(p_dvbpsi->p_decoder); if (!dvbpsi_CheckPSISection(p_dvbpsi, p_section, 0xCC, "ATSC ETT decoder")) { dvbpsi_DeletePSISections(p_section); return; } /* We have a valid ETT section */ dvbpsi_demux_t *p_demux = (dvbpsi_demux_t *) p_dvbpsi->p_decoder; dvbpsi_atsc_ett_decoder_t* p_ett_decoder = (dvbpsi_atsc_ett_decoder_t*)p_decoder; if (!p_ett_decoder) { dvbpsi_error(p_dvbpsi, "ATSC ETT decoder", "No decoder specified"); dvbpsi_DeletePSISections(p_section); return; } /* TS discontinuity check */ if (p_demux->b_discontinuity) { dvbpsi_ReInitETT(p_ett_decoder, true); p_ett_decoder->b_discontinuity = false; p_demux->b_discontinuity = false; } else { /* Perform a few sanity checks */ if (p_ett_decoder->p_building_ett) { if (dvbpsi_CheckETT(p_dvbpsi, p_ett_decoder, p_section)) dvbpsi_ReInitETT(p_ett_decoder, true); } else { if ( (p_ett_decoder->b_current_valid) && (p_ett_decoder->current_ett.i_version == p_section->i_version) && (p_ett_decoder->current_ett.b_current_next == p_section->b_current_next)) { /* Don't decode since this version is already decoded */ dvbpsi_debug(p_dvbpsi, "ATSC ETT decoder", "ignoring already decoded section %d", p_section->i_number); dvbpsi_DeletePSISections(p_section); return; } } } /* Add section to ETT */ if (!dvbpsi_AddSectionETT(p_dvbpsi, p_ett_decoder, p_section)) { dvbpsi_error(p_dvbpsi, "ATSC ETT decoder", "failed decoding section %d", p_section->i_number); dvbpsi_DeletePSISections(p_section); return; } /* Check if we have all the sections */ if (dvbpsi_decoder_psi_sections_completed(DVBPSI_DECODER(p_ett_decoder))) { assert(p_ett_decoder->pf_ett_callback); /* Save the current information */ p_ett_decoder->current_ett = *p_ett_decoder->p_building_ett; p_ett_decoder->b_current_valid = true; /* Decode the sections */ dvbpsi_atsc_DecodeETTSections(p_ett_decoder->p_building_ett, p_ett_decoder->p_sections); /* signal the new ETT */ p_ett_decoder->pf_ett_callback(p_ett_decoder->p_cb_data, p_ett_decoder->p_building_ett); /* Delete sections and Reinitialize the structures */ dvbpsi_ReInitETT(p_ett_decoder, false); assert(p_ett_decoder->p_sections == NULL); } }
void dvbpsi_pmt_sections_gather( dvbpsi_t *p_dvbpsi, dvbpsi_psi_section_t* p_section ) { assert( p_dvbpsi ); assert( p_dvbpsi->p_decoder ); /* ¼ì²étable_id */ if ( !dvbpsi_CheckPSISection( p_dvbpsi, p_section, 0x02, "PMT decoder" ) ) { dvbpsi_DeletePSISections( p_section ); return; } /* */ dvbpsi_pmt_decoder_t* p_pmt_decoder = (dvbpsi_pmt_decoder_t *) p_dvbpsi->p_decoder; assert( p_pmt_decoder ); /* We have a valid PMT section */ /* ½ÚÄ¿ºÅ¼ì²é*/ if ( p_pmt_decoder->i_program_number != p_section->i_extension ) { /* Invalid program_number */ dvbpsi_debug( p_dvbpsi, "PMT decoder", "ignoring section %d not belonging to 'program_number' %d", p_section->i_extension, p_pmt_decoder->i_program_number ); dvbpsi_DeletePSISections( p_section ); return; } /* TS discontinuity check */ if ( p_pmt_decoder->b_discontinuity ) { dvbpsi_ReInitPMT( p_pmt_decoder, true ); p_pmt_decoder->b_discontinuity = false; }else { /* Perform some few sanity checks */ if ( p_pmt_decoder->p_building_pmt ) { if ( dvbpsi_CheckPMT( p_dvbpsi, p_section ) ) dvbpsi_ReInitPMT( p_pmt_decoder, true ); }else { if ( (p_pmt_decoder->b_current_valid) && (p_pmt_decoder->current_pmt.i_version == p_section->i_version) && (p_pmt_decoder->current_pmt.b_current_next == p_section->b_current_next) ) { /* Don't decode since this version is already decoded */ dvbpsi_debug( p_dvbpsi, "PMT decoder", "ignoring already decoded section %d", p_section->i_number ); dvbpsi_DeletePSISections( p_section ); return; } } } /* Add section to PMT */ if ( !dvbpsi_AddSectionPMT( p_dvbpsi, p_pmt_decoder, p_section ) ) { dvbpsi_error( p_dvbpsi, "PMT decoder", "failed decoding section %d", p_section->i_number ); dvbpsi_DeletePSISections( p_section ); return; } if ( dvbpsi_decoder_psi_sections_completed( DVBPSI_DECODER( p_pmt_decoder ) ) ) { assert( p_pmt_decoder->pf_pmt_callback ); /* Save the current information */ p_pmt_decoder->current_pmt = *p_pmt_decoder->p_building_pmt; p_pmt_decoder->b_current_valid = true; /* Decode the sections */ dvbpsi_pmt_sections_decode( p_pmt_decoder->p_building_pmt, p_pmt_decoder->p_sections ); /* signal the new PMT */ p_pmt_decoder->pf_pmt_callback( p_pmt_decoder->p_cb_data, p_pmt_decoder->p_building_pmt ); /* Delete sections and Reinitialize the structures */ dvbpsi_ReInitPMT( p_pmt_decoder, false ); assert( p_pmt_decoder->p_sections == NULL ); } }
/***************************************************************************** * dvbpsi_tot_sections_gather ***************************************************************************** * Callback for the PSI decoder. *****************************************************************************/ void dvbpsi_tot_sections_gather(dvbpsi_t* p_dvbpsi, dvbpsi_decoder_t* p_decoder, dvbpsi_psi_section_t* p_section) { assert(p_dvbpsi); assert(p_dvbpsi->p_decoder); const uint8_t i_table_id = ((p_section->i_table_id == 0x70 || /* TDT */ p_section->i_table_id == 0x73)) ? /* TOT */ p_section->i_table_id : 0x70; if (!dvbpsi_CheckPSISection(p_dvbpsi, p_section, i_table_id, "TDT/TOT decoder")) { dvbpsi_DeletePSISections(p_section); return; } /* Valid TDT/TOT section */ dvbpsi_tot_decoder_t* p_tot_decoder = (dvbpsi_tot_decoder_t*)p_decoder; /* TS discontinuity check */ if (p_tot_decoder->b_discontinuity) { /* We don't care about discontinuities with the TDT/TOT as it only consists of one section anyway */ //dvbpsi_ReInitTOT(p_tot_decoder, true); p_tot_decoder->b_discontinuity = false; } else { /* Perform a few sanity checks */ if (p_tot_decoder->p_building_tot) { if (dvbpsi_CheckTOT(p_dvbpsi, p_tot_decoder, p_section)) dvbpsi_ReInitTOT(p_tot_decoder, true); } #if 0 /* FIXME: Check TDT/TOT table definition for how the version numbering works for this table */ else { if( (p_tot_decoder->b_current_valid) && (p_tot_decoder->current_tot.i_version == p_section->i_version) && (p_tot_decoder->current_tot.b_current_next == p_section->b_current_next)) { /* Don't decode since this version is already decoded */ dvbpsi_debug(p_dvbpsi, "TOT decoder", "ignoring already decoded section %d", p_section->i_number); dvbpsi_DeletePSISections(p_section); return; } } #endif } /* Add section to TOT */ if (!dvbpsi_AddSectionTOT(p_dvbpsi, p_tot_decoder, p_section)) { dvbpsi_error(p_dvbpsi, "TOT decoder", "failed decoding section %d", p_section->i_number); dvbpsi_DeletePSISections(p_section); return; } /* Check if we have all the sections */ if (dvbpsi_decoder_psi_sections_completed(DVBPSI_DECODER(p_tot_decoder))) { assert(p_tot_decoder->pf_tot_callback); /* Save the current information */ p_tot_decoder->current_tot = *p_tot_decoder->p_building_tot; p_tot_decoder->b_current_valid = true; /* Decode the sections */ dvbpsi_tot_sections_decode(p_dvbpsi, p_tot_decoder->p_building_tot, p_tot_decoder->p_sections); /* Delete the sections */ dvbpsi_DeletePSISections(p_tot_decoder->p_sections); p_tot_decoder->p_sections = NULL; /* signal the new TOT */ p_tot_decoder->pf_tot_callback(p_tot_decoder->p_cb_data, p_tot_decoder->p_building_tot); /* Reinitialize the structures */ dvbpsi_ReInitTOT(p_tot_decoder, false); } }
/***************************************************************************** * dvbpsi_pat_sections_gather ***************************************************************************** * Callback for the PSI decoder. *****************************************************************************/ void dvbpsi_pat_sections_gather(dvbpsi_t* p_dvbpsi, dvbpsi_psi_section_t* p_section) { assert(p_dvbpsi); if (!dvbpsi_CheckPSISection(p_dvbpsi, p_section, 0x00, "PAT decoder")) { dvbpsi_DeletePSISections(p_section); return; } /* Now we have a valid PAT section */ 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 */ dvbpsi_pat_decoder_t *p_pat_decoder = (dvbpsi_pat_decoder_t *)p_dec; if (p_pat_decoder->b_discontinuity) { dvbpsi_ReInitPAT(p_pat_decoder, true); p_pat_decoder->b_discontinuity = false; } else { if (p_pat_decoder->p_building_pat) { if (dvbpsi_CheckPAT(p_dvbpsi, p_pat_decoder, p_section)) dvbpsi_ReInitPAT(p_pat_decoder, true); } else { if( (p_pat_decoder->b_current_valid) && (p_pat_decoder->current_pat.i_version == p_section->i_version) && (p_pat_decoder->current_pat.b_current_next == p_section->b_current_next)) { /* Don't decode since this version is already decoded */ dvbpsi_debug(p_dvbpsi, "PAT decoder", "ignoring already decoded section %d", p_section->i_number); dvbpsi_DeletePSISections(p_section); return; } } } /* Add section to PAT */ if (!dvbpsi_AddSectionPAT(p_dvbpsi, p_pat_decoder, p_section)) { dvbpsi_error(p_dvbpsi, "PAT decoder", "failed decoding section %d", p_section->i_number); dvbpsi_DeletePSISections(p_section); return; } /* Check if we have all the sections */ if (dvbpsi_decoder_psi_sections_completed(DVBPSI_DECODER(p_pat_decoder))) { assert(p_pat_decoder->pf_pat_callback); /* Save the current information */ p_pat_decoder->current_pat = *p_pat_decoder->p_building_pat; /* Decode the sections */ if (dvbpsi_pat_sections_decode(p_pat_decoder->p_building_pat, p_pat_decoder->p_sections)) p_pat_decoder->b_current_valid = true; /* signal the new PAT */ if (p_pat_decoder->b_current_valid) p_pat_decoder->pf_pat_callback(p_pat_decoder->p_priv, p_pat_decoder->p_building_pat); /* Delete sectioins and Reinitialize the structures */ dvbpsi_ReInitPAT(p_pat_decoder, !p_pat_decoder->b_current_valid); assert(p_pat_decoder->p_sections == NULL); } }
/***************************************************************************** * dvbpsi_atsc_GatherEITSections ***************************************************************************** * Callback for the subtable demultiplexor. *****************************************************************************/ static void dvbpsi_atsc_GatherEITSections(dvbpsi_t * p_dvbpsi, dvbpsi_decoder_t *p_decoder, dvbpsi_psi_section_t * p_section) { assert(p_dvbpsi); assert(p_dvbpsi->p_decoder); if (!dvbpsi_CheckPSISection(p_dvbpsi, p_section, 0xCB, "ATSC EIT decoder")) { dvbpsi_DeletePSISections(p_section); return; } /* We have a valid EIT section */ dvbpsi_demux_t *p_demux = (dvbpsi_demux_t *) p_dvbpsi->p_decoder; dvbpsi_atsc_eit_decoder_t *p_eit_decoder = (dvbpsi_atsc_eit_decoder_t*)p_decoder; if (!p_eit_decoder) { dvbpsi_error(p_dvbpsi, "ATSC EIT decoder", "No decoder specified"); dvbpsi_DeletePSISections(p_section); return; } /* TS discontinuity check */ if (p_demux->b_discontinuity) { dvbpsi_ReInitEIT(p_eit_decoder, true); p_eit_decoder->b_discontinuity = false; p_demux->b_discontinuity = false; } else { /* Perform a few sanity checks */ if (p_eit_decoder->p_building_eit) { if (dvbpsi_CheckEIT(p_dvbpsi, p_eit_decoder, p_section)) dvbpsi_ReInitEIT(p_eit_decoder, true); } else { if ( (p_eit_decoder->b_current_valid) && (p_eit_decoder->current_eit.i_version == p_section->i_version) && (p_eit_decoder->current_eit.b_current_next == p_section->b_current_next)) { /* Don't decode since this version is already decoded */ dvbpsi_debug(p_dvbpsi, "ATSC EIT decoder", "ignoring already decoded section %d", p_section->i_number); dvbpsi_DeletePSISections(p_section); return; } #if 0 if ((p_eit_decoder->b_current_valid) && (p_eit_decoder->current_eit.i_version == p_section->i_version)) { /* Signal a new EIT if the previous one wasn't active */ if ((!p_eit_decoder->current_eit.b_current_next) && (p_section->b_current_next)) { dvbpsi_atsc_eit_t * p_eit = (dvbpsi_atsc_eit_t*)malloc(sizeof(dvbpsi_atsc_eit_t)); if (p_eit) { p_eit_decoder->current_eit.b_current_next = true; *p_eit = p_eit_decoder->current_eit; p_eit_decoder->pf_eit_callback(p_eit_decoder->p_cb_data, p_eit); } else dvbpsi_error(p_dvbpsi, "ATSC EIT decoder", "Could not signal new ATSC EIT."); } } dvbpsi_DeletePSISections(p_section); return; #endif } } /* Add section to EIT */ if (!dvbpsi_AddSectionEIT(p_dvbpsi, p_eit_decoder, p_section)) { dvbpsi_error(p_dvbpsi, "ATSC EIT decoder", "failed decoding section %d", p_section->i_number); dvbpsi_DeletePSISections(p_section); return; } /* Check if we have all the sections */ if (dvbpsi_decoder_psi_sections_completed(DVBPSI_DECODER(p_eit_decoder))) { assert(p_eit_decoder->pf_eit_callback); /* Save the current information */ p_eit_decoder->current_eit = *p_eit_decoder->p_building_eit; p_eit_decoder->b_current_valid = true; /* Decode the sections */ dvbpsi_atsc_DecodeEITSections(p_eit_decoder->p_building_eit, p_eit_decoder->p_sections); /* Delete the sections */ dvbpsi_DeletePSISections(p_eit_decoder->p_sections); p_eit_decoder->p_sections = NULL; /* signal the new EIT */ p_eit_decoder->pf_eit_callback(p_eit_decoder->p_cb_data, p_eit_decoder->p_building_eit); /* Reinitialize the structures */ dvbpsi_ReInitEIT(p_eit_decoder, false); } }