[PATCH] Priority of transfer-mode should not be -1

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Anssi Hannula wrote:
> Klaus Schmidinger wrote:
>> Anssi Hannula wrote:
>>
>>> Klaus Schmidinger wrote:
>>>
>>>> Anssi Hannula wrote:
>>>
>>>>> diff -Nurp -x '*~' vdr-1.4.0/device.c vdr-1.4.0-fix/device.c
>>>>> --- vdr-1.4.0/device.c    2006-04-14 17:34:43.000000000 +0300
>>>>> +++ vdr-1.4.0-fix/device.c    2006-05-12 06:31:20.000000000 +0300
>>>>> @@ -627,7 +627,7 @@ eSetChannelResult cDevice::SetChannel(co
>>>>>    // use the card that actually can receive it and transfer data from
>>>>> there:
>>>>>  
>>>>>    if (NeedsTransferMode) {
>>>>> -     cDevice *CaDevice = GetDevice(Channel, 0, &NeedsDetachReceivers);
>>>>> +     cDevice *CaDevice = GetDevice(Channel, Setup.PrimaryLimit,
>>>>> &NeedsDetachReceivers);
>>>>>       if (CaDevice && CanReplay()) {
>>>>>          cStatus::MsgChannelSwitch(this, 0); // only report status if
>>>>> we are actually going to switch the channel
>>>>>          if (CaDevice->SetChannel(Channel, false) == scrOk) { //
>>>>> calling SetChannel() directly, not SwitchChannel()!
>>>>> @@ -1158,7 +1158,7 @@ int cDevice::Ca(void) const
>>>>>  
>>>>>  int cDevice::Priority(void) const
>>>>>  {
>>>>> -  int priority = IsPrimaryDevice() ? Setup.PrimaryLimit - 1 :
>>>>> DEFAULTPRIORITY;
>>>>> +  int priority = ActualDevice() == this ? Setup.PrimaryLimit - 1 :
>>>>> DEFAULTPRIORITY;
>>>>>    for (int i = 0; i < MAXRECEIVERS; i++) {
>>>>>        if (receiver[i])
>>>>>           priority = max(receiver[i]->priority, priority);
>>>>> @@ -1183,6 +1183,8 @@ int cDevice::ProvidesCa(const cChannel *
>>>>>  
>>>>>  bool cDevice::Receiving(bool CheckAny) const
>>>>>  {
>>>>> +  if (this == cTransferControl::ReceiverDevice())
>>>>> +      return true;
>>>>>    for (int i = 0; i < MAXRECEIVERS; i++) {
>>>>>        if (receiver[i] && (CheckAny || receiver[i]->priority >= 0)) //
>>>>> cReceiver with priority < 0 doesn't count
>>>>>           return true;
>>>>
>>>> I'm afraid this patch has a nasty side effect.
>>>>
>>>> Asssume the following scenario:
>>>>
>>>> - two devices, primary is 1
>>>> - all channels are available on both devices, except for channels
>>>>   10, 11 and 12 which can only be received by device 2
>>>> - channels 10 and 11 are on the same transponder, channel 12 is on a
>>>> different one
>>>> - switch directly to channel 10 -> transfer mode starts
>>>> - press "Up" to switch to channel 11, but that channel is skipped and
>>>>   it switches to channel 12
>>>>
>>>> So I guess I can't accept this patch.
>>>
>>> Thank you for taking a look.
>>>
>>> However, I don't see why there is such a problem in the above scenario:
>>>
>>> - let's consider PrimaryLimit is 0 (the default)
>>> - SwitchChannel() gets called (device.c line 581)
>>> - PrimaryDevice()->ProvidesChannel() returns false (line 591)
>>> - GetDevice() is called (line 281)
>>> - for the device 1 ProvidesChannel() returns false (line 288)
>>> - ProvidesChannel() is called for device 2 (dvbdevice.c line 767)
>>> - Priority = 0, this->Priority() = -1, so hasPriority = true
>>> - ProvidesChannel() result = true is set in line 785
>>> - ProvidesChannel() return true and ndr = false (device.c line 288)
>>> - (device[i]->Receiving() && !ndr) evaluates true (line 290)
>>> - pri = 0 so device 2 is selected
>>> - SwitchChannel() calls another SwitchChannel (line 601)
>>> - SwitchChannel() calls SetChannel (line 568)
>>> - and so on
>>>
>>> Hopefully I'll have time to test this scenario later today.
>>
>> Well, just try it - it did behave here as described.
> 
> Well, I tried it in the following scenario:
> - two devices, primary is 1
> - all channels available on device 2 only
> - channels 1 and 2 are on the same transponder, 3 and 4 on a different one
> - manually switch to channel 1
> - press up -> vdr switches to 2
> - up again -> vdr switches to 3
> - up again -> vdr switches to 4
> 
> It works ok.
> Do you have PrimaryLimit != 0? As it turns out, there is indeed a bug in

Well, I normally have PrimaryLimit=0, but I've set it to 10 for testing.
Sorry, forgot to mention that.

> the patch which appears when PrimaryLimit is something else than 0 and
> affects the channelup & channeldown.
> If you do, try one of the following:
> 1. The above patch with only the Receiving() change.
> 2. The above patch fully and additionally Priority of GetDevice() call
> in device.c line 591 changed from 0 to Setup.PrimaryLimit.
> 3. PrimaryLimit = 0

Sorry, it's late today - but see below, maybe this is all no longer
a problem, anyway ;-)

>> Looking back at your original posting, I believe the actual problem that
>> triggered all this was that streamdev would interrupt live viewing in
>> Transfer Mode, right?
> 
> Yes.
> 
>> Well, what if streamdev, when selecting the device
>> to use, could avoid the ActualDevice()?
>>
>> To test this (without modifying the cDevice API) you could introduce a
>>
>> bool AvoidActualDevice = false;
>>
>> right before
>>
>> cDevice *cDevice::GetDevice(const cChannel *Channel, int Priority, bool
>> *NeedsDetachReceivers)
>>
>> and inside that function check that variable, and if it is true and the
>> checked device is the ActualDevice(), continue the 'for' loop:
> 
> I think it would be much better to fix this bug (VDR doesn't prefer free
> devices over transfer-moded) rather than add this kind of workaround.

VDR does prefer free devices over ones used for Transfer Mode:

Device *cDevice::GetDevice(const cChannel *Channel, int Priority, bool *NeedsDetachReceivers)
{
   ...
          else if (!device[i]->Receiving() && device[i] != ActualDevice())
             pri = 3; // free and not the actual device
          else if (!device[i]->Receiving() && !device[i]->IsPrimaryDevice())
             pri = 4; // free and not the primary device
   ...
}

Hmm, come to think of it: could it be that your original problem
no longer exists since VDR 1.3.46?

2006-04-09: Version 1.3.46

...
- Now avoiding the 'actual' device when starting a recording, so that a Transfer
   Mode for live tv isn't interrupted.


Klaus


[Index of Archives]     [Linux Media]     [Asterisk]     [DCCP]     [Netdev]     [Xorg]     [Util Linux NG]     [Xfree86]     [Big List of Linux Books]     [Fedora Users]     [Fedora Women]     [ALSA Devel]     [Linux USB]

  Powered by Linux