void eDVBCIInterfaces::addPMTHandler(eDVBServicePMTHandler *pmthandler) { // check if this pmthandler is already registered PMTHandlerList::iterator it = m_pmt_handlers.begin(); while (it != m_pmt_handlers.end()) { if ( *it++ == pmthandler ) return; } eServiceReferenceDVB ref; pmthandler->getServiceReference(ref); eDebug("[eDVBCIInterfaces] addPMTHandler %s", ref.toString().c_str()); m_pmt_handlers.push_back(CIPmtHandler(pmthandler)); recheckPMTHandlers(); }
void eDVBCIInterfaces::ciRemoved(eDVBCISlot *slot) { if (slot->use_count) { eDebug("[CI] Slot %d: removed... usecount %d", slot->getSlotID(), slot->use_count); for (PMTHandlerList::iterator it(m_pmt_handlers.begin()); it != m_pmt_handlers.end(); ++it) { if (it->cislot == slot) // remove the base slot it->cislot = slot->linked_next; else if (it->cislot) { eDVBCISlot *prevSlot = it->cislot, *hSlot = it->cislot->linked_next; while (hSlot) { if (hSlot == slot) { prevSlot->linked_next = slot->linked_next; break; } prevSlot = hSlot; hSlot = hSlot->linked_next; } } } if (slot->linked_next) slot->linked_next->setSource(slot->current_source); else // last CI in chain setInputSource(slot->current_tuner, eDVBCISlot::getTunerLetter(slot->current_tuner)); slot->linked_next = 0; slot->use_count=0; slot->plugged=true; slot->user_mapped=false; slot->removeService(0xFFFF); recheckPMTHandlers(); } }
void eDVBCIInterfaces::removePMTHandler(eDVBServicePMTHandler *pmthandler) { PMTHandlerList::iterator it=std::find(m_pmt_handlers.begin(),m_pmt_handlers.end(),pmthandler); if (it != m_pmt_handlers.end()) { eDVBCISlot *slot = it->cislot; eDVBCISlot *base_slot = slot; eDVBServicePMTHandler *pmthandler = it->pmthandler; m_pmt_handlers.erase(it); eServiceReferenceDVB service_to_remove; pmthandler->getServiceReference(service_to_remove); bool sameServiceExist=false; for (PMTHandlerList::iterator i=m_pmt_handlers.begin(); i != m_pmt_handlers.end(); ++i) { if (i->cislot) { eServiceReferenceDVB ref; i->pmthandler->getServiceReference(ref); if ( ref == service_to_remove ) { sameServiceExist=true; break; } } } while(slot) { eDVBCISlot *next = slot->linked_next; if (!sameServiceExist) { eDebug("[eDVBCIInterfaces] remove last pmt handler for service %s send empty capmt", service_to_remove.toString().c_str()); std::vector<uint16_t> caids; caids.push_back(0xFFFF); slot->sendCAPMT(pmthandler, caids); // send a capmt without caids to remove a running service slot->removeService(service_to_remove.getServiceID().get()); if (slot->current_tuner == -1) { // no previous tuner to go back to, signal to CI interface CI action is finished std::string finish_source; switch (m_stream_finish_mode) { case finish_use_tuner_a: { finish_source = "A"; break; } case finish_use_pvr_none: { finish_source = "PVR_NONE"; break; } case finish_use_none: { finish_source = "NONE"; break; } default: (void)0; } if(finish_source == "") { eDebug("[CI] warning: CI streaming finish mode not set, assuming \"tuner A\""); finish_source = "A"; } slot->setSource(finish_source); } } if (!--slot->use_count) { if (slot->linked_next) slot->linked_next->setSource(slot->current_source); else setInputSource(slot->current_tuner, eDVBCISlot::getTunerLetter(slot->current_tuner)); if (base_slot != slot) { eDVBCISlot *tmp = it->cislot; while(tmp->linked_next != slot) tmp = tmp->linked_next; ASSERT(tmp); if (slot->linked_next) tmp->linked_next = slot->linked_next; else tmp->linked_next = 0; } else // removed old base slot.. update ptr base_slot = slot->linked_next; slot->linked_next = 0; slot->user_mapped = false; } eDebug("[CI] (3) slot %d usecount is now %d", slot->getSlotID(), slot->use_count); slot = next; } // check if another service is waiting for the CI recheckPMTHandlers(); } }
void eDVBCIInterfaces::removePMTHandler(eDVBServicePMTHandler *pmthandler) { PMTHandlerList::iterator it=std::find(m_pmt_handlers.begin(),m_pmt_handlers.end(),pmthandler); if (it != m_pmt_handlers.end()) { eDVBCISlot *slot = it->cislot; eDVBCISlot *base_slot = slot; eDVBServicePMTHandler *pmthandler = it->pmthandler; m_pmt_handlers.erase(it); eServiceReferenceDVB service_to_remove; pmthandler->getServiceReference(service_to_remove); bool sameServiceExist=false; for (PMTHandlerList::iterator i=m_pmt_handlers.begin(); i != m_pmt_handlers.end(); ++i) { if (i->cislot) { eServiceReferenceDVB ref; i->pmthandler->getServiceReference(ref); if ( ref == service_to_remove ) { sameServiceExist=true; break; } } } while(slot) { eDVBCISlot *next = slot->linked_next; if (!sameServiceExist) { eDebug("[eDVBCIInterfaces] remove last pmt handler for service %s send empty capmt", service_to_remove.toString().c_str()); std::vector<uint16_t> caids; caids.push_back(0xFFFF); slot->sendCAPMT(pmthandler, caids); // send a capmt without caids to remove a running service slot->removeService(service_to_remove.getServiceID().get()); } if (!--slot->use_count) { if (slot->linked_next) slot->linked_next->setSource(slot->current_source); else setInputSource(slot->current_tuner, slot->current_source); if (base_slot != slot) { eDVBCISlot *tmp = it->cislot; while(tmp->linked_next != slot) tmp = tmp->linked_next; ASSERT(tmp); if (slot->linked_next) tmp->linked_next = slot->linked_next; else tmp->linked_next = 0; } else // removed old base slot.. update ptr base_slot = slot->linked_next; slot->linked_next = 0; slot->user_mapped = false; } eDebug("(3) slot %d usecount is now %d", slot->getSlotID(), slot->use_count); slot = next; } // check if another service is waiting for the CI recheckPMTHandlers(); } }