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())
for (int i = 0; i < MAXRECEIVERS; i++) { if (receiver[i] && (CheckAny || receiver[i]->priority >= 0)) //return true;
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:
- The above patch with only the Receiving() change.
- 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