On 02/09/08 18:24, Arthur Konovalov wrote:
Klaus Schmidinger wrote:
I just read your original posting again, and there you described the problem the other way round. So I also tested recording the FTA channel and then switching to the encrypted channel, but this also works fine here.
So I'm afraid I don't know what's causing this for you.
Very strange. I noticed that message "channel on available" apperars momentarily after switching to another channel. It seems like vdr not trying to decode anything. May be You can provide some lines to vdr code for debugging reason of message "channel not available"? I have interest to solve this problem ;)
Please try the attached version of cDevice::GetDevice(const cChannel *Channel, int Priority, bool LiveView), redirect stdout into a file and send me the result.
Klaus
cDevice *cDevice::GetDevice(const cChannel *Channel, int Priority, bool LiveView) { printf("\nGetDevice %d %d %d - '%s'\n", Channel->Number(), Priority, LiveView, *Channel->ToText());//XXX // Collect the current priorities of all CAM slots that can decrypt the channel: int NumCamSlots = CamSlots.Count(); int SlotPriority[NumCamSlots]; int NumUsableSlots = 0; if (Channel->Ca() >= CA_ENCRYPTED_MIN) { for (cCamSlot *CamSlot = CamSlots.First(); CamSlot; CamSlot = CamSlots.Next(CamSlot)) { SlotPriority[CamSlot->Index()] = MAXPRIORITY + 1; // assumes it can't be used if (CamSlot->ModuleStatus() == msReady) { if (CamSlot->ProvidesCa(Channel->Caids())) { if (!ChannelCamRelations.CamChecked(Channel->GetChannelID(), CamSlot->SlotNumber())) { SlotPriority[CamSlot->Index()] = CamSlot->Priority(); NumUsableSlots++; } } } } if (!NumUsableSlots) return NULL; // no CAM is able to decrypt this channel } printf("NumUsableSlots = %d\n", NumUsableSlots);//XXX
bool NeedsDetachReceivers = false; cDevice *d = NULL; cCamSlot *s = NULL;
uint32_t Impact = 0xFFFFFFFF; // we're looking for a device with the least impact for (int j = 0; j < NumCamSlots || !NumUsableSlots; j++) { printf("j = %d\n", j);//XXX if (NumUsableSlots && SlotPriority[j] > MAXPRIORITY) continue; // there is no CAM available in this slot for (int i = 0; i < numDevices; i++) { printf("i = %d\n", i);//XXX if (Channel->Ca() && Channel->Ca() <= CA_DVB_MAX && Channel->Ca() != device[i]->CardIndex() + 1) continue; // a specific card was requested, but not this one printf("A\n");//XXX if (NumUsableSlots && !CamSlots.Get(j)->Assign(device[i], true)) continue; // CAM slot can't be used with this device printf("B\n");//XXX bool ndr; if (device[i]->ProvidesChannel(Channel, Priority, &ndr)) { // this device is basicly able to do the job printf("C %d\n", ndr);//XXX if (NumUsableSlots && device[i]->CamSlot() && device[i]->CamSlot() != CamSlots.Get(j)) ndr = true; // using a different CAM slot requires detaching receivers printf("D %d\n", ndr);//XXX // Put together an integer number that reflects the "impact" using // this device would have on the overall system. Each condition is represented // by one bit in the number (or several bits, if the condition is actually // a numeric value). The sequence in which the conditions are listed corresponds // to their individual severity, where the one listed first will make the most // difference, because it results in the most significant bit of the result. uint32_t imp = 0; imp <<= 1; imp |= LiveView ? !device[i]->IsPrimaryDevice() || ndr : 0; // prefer the primary device for live viewing if we don't need to detach existing receivers imp <<= 1; imp |= !device[i]->Receiving() && (device[i] != cTransferControl::ReceiverDevice() || device[i]->IsPrimaryDevice()) || ndr; // use receiving devices if we don't need to detach existing receivers, but avoid primary device in local transfer mode imp <<= 1; imp |= device[i]->Receiving(); // avoid devices that are receiving imp <<= 1; imp |= device[i] == cTransferControl::ReceiverDevice(); // avoid the Transfer Mode receiver device imp <<= 8; imp |= min(max(device[i]->Priority() + MAXPRIORITY, 0), 0xFF); // use the device with the lowest priority (+MAXPRIORITY to assure that values -99..99 can be used) imp <<= 8; imp |= min(max((NumUsableSlots ? SlotPriority[j] : 0) + MAXPRIORITY, 0), 0xFF); // use the CAM slot with the lowest priority (+MAXPRIORITY to assure that values -99..99 can be used) imp <<= 1; imp |= ndr; // avoid devices if we need to detach existing receivers imp <<= 1; imp |= device[i]->IsPrimaryDevice(); // avoid the primary device imp <<= 1; imp |= NumUsableSlots ? 0 : device[i]->HasCi(); // avoid cards with Common Interface for FTA channels imp <<= 1; imp |= device[i]->HasDecoder(); // avoid full featured cards imp <<= 1; imp |= NumUsableSlots ? !ChannelCamRelations.CamDecrypt(Channel->GetChannelID(), j + 1) : 0; // prefer CAMs that are known to decrypt this channel printf("E %08X %08X\n", Impact, imp);//XXX if (imp < Impact) { // This device has less impact than any previous one, so we take it. Impact = imp; d = device[i]; NeedsDetachReceivers = ndr; if (NumUsableSlots) s = CamSlots.Get(j); } } } if (!NumUsableSlots) break; // no CAM necessary, so just one loop over the devices } if (d) { printf("X %d\n", d->CardIndex());//XXX if (NeedsDetachReceivers) d->DetachAllReceivers(); if (s) { if (s->Device() != d) { if (s->Device()) s->Device()->DetachAllReceivers(); if (d->CamSlot()) d->CamSlot()->Assign(NULL); s->Assign(d); } } else if (d->CamSlot() && !d->CamSlot()->IsDecrypting()) d->CamSlot()->Assign(NULL); } printf("Z\n");//XXX return d; }