/***************************************************************************** * dvbpsi_tot_detach ***************************************************************************** * Close a TDT/TOT decoder. *****************************************************************************/ void dvbpsi_tot_detach(dvbpsi_t* p_dvbpsi, uint8_t i_table_id, uint16_t i_extension) { assert(p_dvbpsi); assert(p_dvbpsi->p_decoder); dvbpsi_demux_t *p_demux = (dvbpsi_demux_t *)p_dvbpsi->p_decoder; dvbpsi_demux_subdec_t* p_subdec; i_extension = 0; /* NOTE: force to 0 when handling TDT/TOT */ p_subdec = dvbpsi_demuxGetSubDec(p_demux, i_table_id, i_extension); if (p_demux == NULL) { dvbpsi_error(p_dvbpsi, "TDT/TOT Decoder", "No such TDT/TOT decoder (table_id == 0x%02x," "extension == 0x%02x)", i_table_id, i_extension); return; } assert(p_subdec->p_decoder); dvbpsi_tot_decoder_t* p_tot_decoder; p_tot_decoder = (dvbpsi_tot_decoder_t*)p_subdec->p_decoder; if (p_tot_decoder->p_building_tot) dvbpsi_tot_delete(p_tot_decoder->p_building_tot); p_tot_decoder->p_building_tot = NULL; dvbpsi_DetachDemuxSubDecoder(p_demux, p_subdec); dvbpsi_DeleteDemuxSubDecoder(p_subdec); }
/***************************************************************************** * dvbpsi_atsc_DetachETT ***************************************************************************** * Close a ETT decoder. The handle isn't valid any more. *****************************************************************************/ void dvbpsi_atsc_DetachETT(dvbpsi_t *p_dvbpsi, uint8_t i_table_id, uint16_t i_extension) { assert(p_dvbpsi); assert(p_dvbpsi->p_decoder); dvbpsi_demux_t *p_demux = (dvbpsi_demux_t *) p_dvbpsi->p_decoder; dvbpsi_demux_subdec_t* p_subdec; p_subdec = dvbpsi_demuxGetSubDec(p_demux, i_table_id, i_extension); if (p_subdec == NULL) { dvbpsi_error(p_dvbpsi, "ATSC ETT Decoder", "No such ETT decoder (table_id == 0x%02x," "extension == 0x%04x)", i_table_id, i_extension); return; } dvbpsi_atsc_ett_decoder_t* p_ett_decoder; p_ett_decoder = (dvbpsi_atsc_ett_decoder_t*)p_subdec->p_decoder; if (!p_ett_decoder) return; if (p_ett_decoder->p_building_ett) dvbpsi_atsc_DeleteETT(p_ett_decoder->p_building_ett); p_ett_decoder->p_building_ett = NULL; dvbpsi_DetachDemuxSubDecoder(p_demux, p_subdec); dvbpsi_DeleteDemuxSubDecoder(p_subdec); }
/***************************************************************************** * dvbpsi_nit_detach ***************************************************************************** * Close a NIT decoder. *****************************************************************************/ void dvbpsi_nit_detach(dvbpsi_t * p_dvbpsi, uint8_t i_table_id, uint16_t i_extension) { dvbpsi_demux_t *p_demux = (dvbpsi_demux_t *) p_dvbpsi->p_decoder; dvbpsi_demux_subdec_t* p_subdec; p_subdec = dvbpsi_demuxGetSubDec(p_demux, i_table_id, i_extension); if (p_subdec == NULL) { dvbpsi_error(p_dvbpsi, "NIT Decoder", "No such NIT decoder (table_id == 0x%02x," "extension == 0x%02x)", i_table_id, i_extension); return; } dvbpsi_nit_decoder_t* p_nit_decoder; p_nit_decoder = (dvbpsi_nit_decoder_t*)p_subdec->p_decoder; if (p_nit_decoder->p_building_nit) dvbpsi_nit_delete(p_nit_decoder->p_building_nit); p_nit_decoder->p_building_nit = NULL; /* Free demux sub table decoder */ dvbpsi_DetachDemuxSubDecoder(p_demux, p_subdec); dvbpsi_DeleteDemuxSubDecoder(p_subdec); }
/***************************************************************************** * dvbpsi_sis_detach ***************************************************************************** * Close a SIS decoder. *****************************************************************************/ void dvbpsi_sis_detach(dvbpsi_t *p_dvbpsi, uint8_t i_table_id, uint16_t i_extension) { assert(p_dvbpsi); assert(p_dvbpsi->p_decoder); dvbpsi_demux_t *p_demux = (dvbpsi_demux_t *) p_dvbpsi->p_decoder; i_extension = 0; dvbpsi_demux_subdec_t* p_subdec; p_subdec = dvbpsi_demuxGetSubDec(p_demux, i_table_id, i_extension); if (p_demux == NULL) { dvbpsi_error(p_dvbpsi, "SIS Decoder", "No such SIS decoder (table_id == 0x%02x," "extension == 0x%02x)", i_table_id, i_extension); return; } assert(p_subdec->p_decoder); dvbpsi_sis_decoder_t* p_sis_decoder; p_sis_decoder = (dvbpsi_sis_decoder_t*)p_subdec->p_decoder; if (p_sis_decoder->p_building_sis) dvbpsi_sis_delete(p_sis_decoder->p_building_sis); p_sis_decoder->p_building_sis = NULL; dvbpsi_DetachDemuxSubDecoder(p_demux, p_subdec); dvbpsi_DeleteDemuxSubDecoder(p_subdec); }
/***************************************************************************** * dvbpsi_AttachNIT ***************************************************************************** * Initialize a NIT subtable decoder. *****************************************************************************/ int dvbpsi_AttachNIT(dvbpsi_decoder_t * p_psi_decoder, uint8_t i_table_id, uint16_t i_extension, dvbpsi_nit_callback pf_callback, void* p_cb_data) { dvbpsi_demux_t* p_demux = (dvbpsi_demux_t*)p_psi_decoder->p_private_decoder; dvbpsi_demux_subdec_t* p_subdec; dvbpsi_nit_decoder_t* p_nit_decoder; unsigned int i; if(dvbpsi_demuxGetSubDec(p_demux, i_table_id, i_extension)) { DVBPSI_ERROR_ARG("NIT decoder", "Already a decoder for (table_id == 0x%02x," "extension == 0x%02x)", i_table_id, i_extension); return 1; } p_subdec = (dvbpsi_demux_subdec_t*)malloc(sizeof(dvbpsi_demux_subdec_t)); if(p_subdec == NULL) { return 1; } p_nit_decoder = (dvbpsi_nit_decoder_t*)malloc(sizeof(dvbpsi_nit_decoder_t)); if(p_nit_decoder == NULL) { free(p_subdec); return 1; } /* subtable decoder configuration */ p_subdec->pf_callback = &dvbpsi_GatherNITSections; p_subdec->p_cb_data = p_nit_decoder; p_subdec->i_id = (uint32_t)i_table_id << 16 | (uint32_t)i_extension; p_subdec->pf_detach = dvbpsi_DetachNIT; /* Attach the subtable decoder to the demux */ p_subdec->p_next = p_demux->p_first_subdec; p_demux->p_first_subdec = p_subdec; /* NIT decoder information */ p_nit_decoder->i_network_id = i_extension; p_nit_decoder->pf_callback = pf_callback; p_nit_decoder->p_cb_data = p_cb_data; /* NIT decoder initial state */ p_nit_decoder->b_current_valid = 0; p_nit_decoder->p_building_nit = NULL; for(i = 0; i <= 255; i++) p_nit_decoder->ap_sections[i] = NULL; return 0; }
/***************************************************************************** * dvbpsi_AttachVCT ***************************************************************************** * Initialize a VCT subtable decoder. *****************************************************************************/ bool dvbpsi_AttachVCT(dvbpsi_t *p_dvbpsi, uint8_t i_table_id, uint16_t i_extension, dvbpsi_vct_callback pf_callback, void* p_cb_data) { assert(p_dvbpsi); assert(p_dvbpsi->p_private); dvbpsi_demux_t* p_demux = (dvbpsi_demux_t*)p_dvbpsi->p_private; dvbpsi_demux_subdec_t* p_subdec; dvbpsi_vct_decoder_t* p_vct_decoder; if (dvbpsi_demuxGetSubDec(p_demux, i_table_id, i_extension)) { dvbpsi_error(p_dvbpsi, "VCT decoder", "Already a decoder for (table_id == 0x%02x," "extension == 0x%02x)", i_table_id, i_extension); return false; } p_subdec = (dvbpsi_demux_subdec_t*)calloc(1, sizeof(dvbpsi_demux_subdec_t)); if(p_subdec == NULL) return false; p_vct_decoder = (dvbpsi_vct_decoder_t*)calloc(1, sizeof(dvbpsi_vct_decoder_t)); if (p_vct_decoder == NULL) { free(p_subdec); return false; } /* subtable decoder configuration */ p_subdec->pf_callback = &dvbpsi_GatherVCTSections; p_subdec->p_cb_data = p_vct_decoder; p_subdec->i_id = (uint32_t)i_table_id << 16 | (uint32_t)i_extension; p_subdec->pf_detach = &dvbpsi_DetachVCT; /* Attach the subtable decoder to the demux */ p_subdec->p_next = p_demux->p_first_subdec; p_demux->p_first_subdec = p_subdec; /* vct decoder information */ p_vct_decoder->pf_vct_callback = pf_callback; p_vct_decoder->p_cb_data = p_cb_data; /* vct decoder initial state */ p_vct_decoder->b_current_valid = false; p_vct_decoder->p_building_vct = NULL; for (unsigned int i = 0; i <= 255; i++) p_vct_decoder->ap_sections[i] = NULL; 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_DetachVCT ***************************************************************************** * Close a VCT decoder. The handle isn't valid any more. *****************************************************************************/ void dvbpsi_DetachVCT(dvbpsi_t *p_dvbpsi, uint8_t i_table_id, uint16_t i_extension) { assert(p_dvbpsi); assert(p_dvbpsi->p_private); dvbpsi_demux_t *p_demux = (dvbpsi_demux_t *) p_dvbpsi->p_private; dvbpsi_demux_subdec_t* p_subdec; dvbpsi_demux_subdec_t** pp_prev_subdec; dvbpsi_vct_decoder_t* p_vct_decoder; p_subdec = dvbpsi_demuxGetSubDec(p_demux, i_table_id, i_extension); if (p_subdec == NULL) { dvbpsi_error(p_dvbpsi, "VCT Decoder", "No such VCT decoder (table_id == 0x%02x," "extension == 0x%02x)", i_table_id, i_extension); return; } p_vct_decoder = (dvbpsi_vct_decoder_t*)p_subdec->p_cb_data; free(p_vct_decoder->p_building_vct); for (unsigned int i = 0; i <= 255; i++) { if (p_vct_decoder->ap_sections[i]) { dvbpsi_DeletePSISections(p_vct_decoder->ap_sections[i]); p_vct_decoder->ap_sections[i] = NULL; } } free(p_subdec->p_cb_data); pp_prev_subdec = &p_demux->p_first_subdec; while(*pp_prev_subdec != p_subdec) pp_prev_subdec = &(*pp_prev_subdec)->p_next; *pp_prev_subdec = p_subdec->p_next; free(p_subdec); p_subdec = NULL; }
/***************************************************************************** * dvbpsi_DetachNIT ***************************************************************************** * Close a NIT decoder. *****************************************************************************/ void dvbpsi_DetachNIT(dvbpsi_demux_t * p_demux, uint8_t i_table_id, uint16_t i_extension) { dvbpsi_demux_subdec_t* p_subdec; dvbpsi_demux_subdec_t** pp_prev_subdec; dvbpsi_nit_decoder_t* p_nit_decoder; unsigned int i; p_subdec = dvbpsi_demuxGetSubDec(p_demux, i_table_id, i_extension); if(p_demux == NULL) { DVBPSI_ERROR_ARG("NIT Decoder", "No such NIT decoder (table_id == 0x%02x," "extension == 0x%02x)", i_table_id, i_extension); return; } p_nit_decoder = (dvbpsi_nit_decoder_t*)p_subdec->p_cb_data; free(p_nit_decoder->p_building_nit); for(i = 0; i <= 255; i++) { if(p_nit_decoder->ap_sections[i]) dvbpsi_DeletePSISections(p_nit_decoder->ap_sections[i]); } free(p_subdec->p_cb_data); pp_prev_subdec = &p_demux->p_first_subdec; while(*pp_prev_subdec != p_subdec) pp_prev_subdec = &(*pp_prev_subdec)->p_next; *pp_prev_subdec = p_subdec->p_next; free(p_subdec); }