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;
}
_______________________________________________
vdr mailing list
vdr@linuxtv.org
http://www.linuxtv.org/cgi-bin/mailman/listinfo/vdr

Reply via email to