X-Git-Url: http://code.vuplus.com/gitweb/?p=vuplus_dvbapp;a=blobdiff_plain;f=lib%2Fdvb_ci%2Fdvbci.cpp;h=a66ce8f940da1fdc21935ae03dff6ac0cb1118ec;hp=bde394aa3111b13ef055e91e128419572eef616d;hb=HEAD;hpb=69ad5b69a69b3a9006824832afb3fa8cecb061b9 diff --git a/lib/dvb_ci/dvbci.cpp b/lib/dvb_ci/dvbci.cpp index bde394a..a66ce8f 100644 --- a/lib/dvb_ci/dvbci.cpp +++ b/lib/dvb_ci/dvbci.cpp @@ -225,7 +225,14 @@ void eDVBCIInterfaces::ciRemoved(eDVBCISlot *slot) if (slot->linked_next) slot->linked_next->setSource(slot->current_source); else // last CI in chain - setInputSource(slot->current_tuner, slot->current_source); + { + if(slot->current_tuner == 99) + slot->setSource(PVR_NONE); + else + setInputSource(slot->current_tuner, slot->current_source); + + slot->removeVtunerPid(); + } slot->linked_next = 0; slot->use_count=0; slot->plugged=true; @@ -241,6 +248,7 @@ static bool canDescrambleMultipleServices(int slotid) snprintf(configStr, 255, "config.ci.%d.canDescrambleMultipleServices", slotid); std::string str; ePythonConfigQuery::getConfigValue(configStr, str); + eDebugCI("canDescrambleMultipleServices %s", str.c_str()); if ( str == "auto" ) { std::string appname = eDVBCI_UI::getInstance()->getAppName(slotid); @@ -290,6 +298,7 @@ void eDVBCIInterfaces::recheckPMTHandlers() if (tmp) // we dont like to change tsmux for running services { eDebugCI("already assigned and running CI!\n"); + tmp->addVtunerPid(pmthandler); continue; } } @@ -297,8 +306,9 @@ void eDVBCIInterfaces::recheckPMTHandlers() if (!pmthandler->getProgramInfo(p)) { int cnt=0; - for (caidSet::reverse_iterator x(p.caids.rbegin()); x != p.caids.rend(); ++x, ++cnt) - caids.push_front(*x); + std::set set(p.caids.begin(), p.caids.end()); + for (std::set::reverse_iterator x(set.rbegin()); x != set.rend(); ++x, ++cnt) + caids.push_front(x->caid); if (service && cnt) service->m_ca = caids; } @@ -396,6 +406,7 @@ void eDVBCIInterfaces::recheckPMTHandlers() if (useThis) { + ci_it->addVtunerPid(pmthandler); // check if this CI is already assigned to this pmthandler eDVBCISlot *tmp = it->cislot; while(tmp) @@ -489,21 +500,25 @@ void eDVBCIInterfaces::recheckPMTHandlers() eDVBFrontend *fe = (eDVBFrontend*) &(*frontend); tunernum = fe->getSlotID(); } + else // no frontend, PVR + tunernum = 99; } ASSERT(tunernum != -1); data_source tuner_source = TUNER_A; switch (tunernum) { - case 0: tuner_source = TUNER_A; break; - case 1: tuner_source = TUNER_B; break; - case 2: tuner_source = TUNER_C; break; - case 3: tuner_source = TUNER_D; break; + case 0 ... 22: + tuner_source = (data_source)tunernum; + break; + case 99: tuner_source = PVR; + break; default: eDebug("try to get source for tuner %d!!\n", tunernum); break; } ci_it->current_tuner = tunernum; - setInputSource(tunernum, ci_source); + if (tunernum != 99) + setInputSource(tunernum, ci_source); ci_it->setSource(tuner_source); } else @@ -592,7 +607,14 @@ void eDVBCIInterfaces::removePMTHandler(eDVBServicePMTHandler *pmthandler) if (slot->linked_next) slot->linked_next->setSource(slot->current_source); else - setInputSource(slot->current_tuner, slot->current_source); + { + if(slot->current_tuner == 99) + slot->setSource(PVR_NONE); + else + setInputSource(slot->current_tuner, slot->current_source); + + slot->removeVtunerPid(); + } if (base_slot != slot) { @@ -633,6 +655,19 @@ void eDVBCIInterfaces::gotPMT(eDVBServicePMTHandler *pmthandler) tmp = tmp->linked_next; } } + +} + +bool eDVBCIInterfaces::isCiConnected(eDVBServicePMTHandler *pmthandler) +{ + bool ret = false; + PMTHandlerList::iterator it=std::find(m_pmt_handlers.begin(), m_pmt_handlers.end(), pmthandler); + if (it != m_pmt_handlers.end() && it->cislot) + { + ret = true; + } + + return ret; } int eDVBCIInterfaces::getMMIState(int slotid) @@ -645,10 +680,11 @@ int eDVBCIInterfaces::getMMIState(int slotid) return slot->getMMIState(); } +static const char *g_tuner_source[] = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "CI0", "CI1", "CI2", "CI3"}; + int eDVBCIInterfaces::setInputSource(int tuner_no, data_source source) { -// eDebug("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); -// eDebug("eDVBCIInterfaces::setInputSource(%d %d)", tuner_no, (int)source); + eDebugCI("[eDVBCIInterfaces] setInputSource(%d, %d)", tuner_no, (int)source); if (getNumOfSlots() > 1) // FIXME .. we force DM8000 when more than one CI Slot is avail { char buf[64]; @@ -660,34 +696,10 @@ int eDVBCIInterfaces::setInputSource(int tuner_no, data_source source) return 0; } - if (tuner_no > 3) - eDebug("setInputSource(%d, %d) failed... dm8000 just have four inputs", tuner_no, (int)source); - switch(source) { - case CI_A: - fprintf(input, "CI0"); - break; - case CI_B: - fprintf(input, "CI1"); - break; - case CI_C: - fprintf(input, "CI2"); - break; - case CI_D: - fprintf(input, "CI3"); - break; - case TUNER_A: - fprintf(input, "A"); - break; - case TUNER_B: - fprintf(input, "B"); - break; - case TUNER_C: - fprintf(input, "C"); - break; - case TUNER_D: - fprintf(input, "D"); + case TUNER_A ... CI_D: + fprintf(input, g_tuner_source[(int)source]); break; default: eDebug("setInputSource for input %d failed!!!\n", (int)source); @@ -738,7 +750,7 @@ PyObject *eDVBCIInterfaces::getDescrambleRules(int slotid) if (!slot) { char tmp[255]; - snprintf(tmp, 255, "eDVBCIInterfaces::getDescrambleRules try to get rules for CI Slot %d... but just %d slots are available", slotid, m_slots.size()); + snprintf(tmp, 255, "eDVBCIInterfaces::getDescrambleRules try to get rules for CI Slot %d... but just %zd slots are available", slotid, m_slots.size()); PyErr_SetString(PyExc_StandardError, tmp); return 0; } @@ -790,7 +802,7 @@ RESULT eDVBCIInterfaces::setDescrambleRules(int slotid, SWIG_PYOBJECT(ePyObject) if (!slot) { char tmp[255]; - snprintf(tmp, 255, "eDVBCIInterfaces::setDescrambleRules try to set rules for CI Slot %d... but just %d slots are available", slotid, m_slots.size()); + snprintf(tmp, 255, "eDVBCIInterfaces::setDescrambleRules try to set rules for CI Slot %d... but just %zd slots are available", slotid, m_slots.size()); PyErr_SetString(PyExc_StandardError, tmp); return -1; } @@ -861,7 +873,7 @@ RESULT eDVBCIInterfaces::setDescrambleRules(int slotid, SWIG_PYOBJECT(ePyObject) if (PyTuple_Size(tuple) != 2) { char buf[255]; - snprintf(buf, 255, "eDVBCIInterfaces::setDescrambleRules provider tuple has %d instead of 2 entries!!", PyTuple_Size(tuple)); + snprintf(buf, 255, "eDVBCIInterfaces::setDescrambleRules provider tuple has %zd instead of 2 entries!!", PyTuple_Size(tuple)); PyErr_SetString(PyExc_StandardError, buf); return -1; } @@ -913,7 +925,7 @@ PyObject *eDVBCIInterfaces::readCICaIds(int slotid) if (!slot) { char tmp[255]; - snprintf(tmp, 255, "eDVBCIInterfaces::readCICaIds try to get CAIds for CI Slot %d... but just %d slots are available", slotid, m_slots.size()); + snprintf(tmp, 255, "eDVBCIInterfaces::readCICaIds try to get CAIds for CI Slot %d... but just %zd slots are available", slotid, m_slots.size()); PyErr_SetString(PyExc_StandardError, tmp); } else @@ -1188,10 +1200,11 @@ int eDVBCISlot::sendCAPMT(eDVBServicePMTHandler *pmthandler, const std::vector::iterator it = running_services.find(program_number); + bool sendEmpty = caids.size() == 1 && caids[0] == 0xFFFF; if ( it != running_services.end() && (pmt_version == it->second) && - !(caids.size() == 1 && caids[0] == 0xFFFF) ) + !sendEmpty ) { eDebug("[eDVBCISlot] dont send self capmt version twice"); return -1; @@ -1216,7 +1229,7 @@ int eDVBCISlot::sendCAPMT(eDVBServicePMTHandler *pmthandler, const std::vectorsendCAPMT(raw_data + hlen, wp - hlen); running_services[program_number] = pmt_version; @@ -1269,6 +1285,7 @@ void eDVBCISlot::removeService(uint16_t program_number) int eDVBCISlot::setSource(data_source source) { current_source = source; + eDebugCI("[eDVBCISlot] setSource %d", (int)source); if (eDVBCIInterfaces::getInstance()->getNumOfSlots() > 1) // FIXME .. we force DM8000 when more than one CI Slot is avail { char buf[64]; @@ -1276,29 +1293,14 @@ int eDVBCISlot::setSource(data_source source) FILE *ci = fopen(buf, "wb"); switch(source) { - case CI_A: - fprintf(ci, "CI0"); - break; - case CI_B: - fprintf(ci, "CI1"); - break; - case CI_C: - fprintf(ci, "CI2"); - break; - case CI_D: - fprintf(ci, "CI3"); + case TUNER_A ... CI_D: + fprintf(ci, g_tuner_source[(int)source]); break; - case TUNER_A: - fprintf(ci, "A"); - break; - case TUNER_B: - fprintf(ci, "B"); + case PVR: + fprintf(ci, "PVR"); break; - case TUNER_C: - fprintf(ci, "C"); - break; - case TUNER_D: - fprintf(ci, "D"); + case PVR_NONE: + fprintf(ci, "PVR_NONE"); break; default: eDebug("CI Slot %d: setSource %d failed!!!\n", getSlotID(), (int)source); @@ -1321,7 +1323,7 @@ int eDVBCISlot::setSource(data_source source) fprintf(ci, "%s", source==TUNER_A ? "A" : "B"); // configure CI data source (TunerA, TunerB) fclose(ci); } - eDebug("CI Slot %d setSource(%d)", getSlotID(), (int)source); + eDebugCI("[eDVBCISlot] CI Slot %d setSource(%d)", getSlotID(), (int)source); return 0; } @@ -1342,4 +1344,52 @@ int eDVBCISlot::setClockRate(int rate) return -1; } +void eDVBCISlot::addVtunerPid(eDVBServicePMTHandler *pmthandler) +{ + ePtr demux; + eDVBServicePMTHandler::program p; + + bool ignore = 0; + if (!pmthandler->getDataDemux(demux)) + { + + if (!pmthandler->getProgramInfo(p)) + { + for (std::list::const_iterator i(p.caids.begin()); + i != p.caids.end(); ++i) + { + ignore = 0; + for (eSmartPtrList::iterator it(m_ecms.begin()); it != m_ecms.end(); ++it) + { + if(it->getPid() == i->capid) + { + ignore = 1; + break; + } + } + + if (i->capid >= 0 && !ignore) + { + ePtr ecm; + eDebug("PES Start CAPID = %d Caid = %d", i->capid, i->caid); + ecm = new eDVBECMParser(demux); + m_ecms.push_back(ecm); + ecm->start(i->capid); + } + } + } + } + +} + +void eDVBCISlot::removeVtunerPid(void) +{ + eDebugCI("eDVBCISlot::removeVtunerPid..."); + for (eSmartPtrList::iterator it(m_ecms.begin()); it != m_ecms.end(); ++it) + { + it->stop(); + } + m_ecms.clear(); +} + eAutoInitP0 init_eDVBCIInterfaces(eAutoInitNumbers::dvb, "CI Slots");