re-use devices in transfer mode

Message ID
State New

Commit Message

Anssi Hannula April 29, 2007, 3:14 p.m. UTC
  Klaus Schmidinger wrote:
> On 04/21/07 16:26, Anssi Hannula wrote:
>> Udo Richter wrote:
>>> Anssi Hannula wrote:
>>>> However, the usual "use-already-tuned-devices" check in GetDevice() only
>>>> checks for device->Receiving(), which does not report transfer-moded
>>>> device, resulting in the new receiver being started on second device,
>>>> thus both devices being reserved for receiving data from the same
>>>> transponder.
>>> Without taking a deeper look into it right now, I think there was some
>>> trap with detecting transfer mode in case that some streams are received
>>> additionally to live mode, for example teletext with osdteletext plugin.
>>> You may want to double-check this. Changes to GetDevice tend to have
>>> strange side effects.
>> I proposed this same patch previously, but it was suggested to instead
>> of the check for transfer mode to just change the Receiving() to
>> Receiving(true). I didn't see any caveats back then, so I agreed.
>> Unfortunately, that resulted in problems with situations that you describe.
>> However, this original version of the patch does explicitely check for a
>> device in transfer-mode, and does not care about osdteletext receivers.
>> What could happen is that this would match the transfer modes whose
>> receiverdevice() is the primary device itself (some situations related
>> to the ca or ac3, I guess), thus starting the new receiver in the
>> primary device, which could cause side-effects if the card's bandwidth
>> is not wide enough. However, even without this patch, when a recording
>> is already taking place on the primary device, this rule matches and
>> another recording could be started on the primary device. I don't know
>> if we should be preventing these from happening, but if we do, I think
>> we could make the rule as
>> imp |= !device[i]->Receiving() && (device[i] !=
>> cTransferControl::ReceiverDevice() || device[i]->IsPrimaryDevice()) ||
>> ndr // prevents matching local-transfer-moded primary-device
>> or
>> imp |= !device[i]->Receiving() && device[i] !=
>> cTransferControl::ReceiverDevice() || device[i]->IsPrimaryDevice() ||
>> ndr // addidtionally prevents matching recording primary-devices
> I'm not sure about changing anything in that area in any 1.4 maintenance patch.
> If this gets changed at all, it will be in the 1.5 developer version.
> So please provide a patch for that version, possibly including all the
> thoughts that have come up in this thread.

Attached is a patch against 1.5.2. I changed it so that primary devices 
in local transfer mode are not considered for re-using (I don't know the 
best behaviour here, just trying to minimize the effects of the patch).

I.e. this patch now affects only non-primary devices:
- 2 non-primary devices, one used in transfer mode on transponder A, 
second free
- a new recording / streamdev session starts on transponder A
* Before:
The new recording starts on the free device.
* After:
The new recording starts on the already-tuned device.


diff -Nurp -x '*~' vdr-1.5.2/device.c vdr-1.5.2-f/device.c
--- vdr-1.5.2/device.c	2007-01-13 14:05:00.000000000 +0200
+++ vdr-1.5.2-f/device.c	2007-04-29 17:47:18.000000000 +0300
@@ -327,7 +327,7 @@  cDevice *cDevice::GetDevice(const cChann
              // 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() || ndr;                                                       // use receiving devices 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)