FernetMenta / vdr-plugin-vnsiserver

VDR plugin to handle XBMC clients.
GNU General Public License v2.0
16 stars 33 forks source link

Retune fixes #73

Closed glenvt18 closed 7 years ago

glenvt18 commented 7 years ago

This PR fixes two issues with re-tune:

  1. When a higher priority recording or streaming task is about to zap to another transponder on the device from which VNSI is currently streaming, it detaches all receivers from the device, which, in turn, triggers re-tune. Since VDR has no synchronization mechanism for zapping (GetDevice()->SwitchChannel()->AttachReceiver() chain), a race occurs. The result is usually that the recording calls an emergency exit after not receiving TS packets for 30 seconds. To reproduce this, start streaming a channel, then start recording (or another VNSI streaming with a higher priority) of a channel from another transponder. VDR should restart in 30 seconds. The proposed solution is to disable re-tune in such cases. Even if (when) VDR had zapping synchronization, re-tuning after the device has been switched to another transponder by a higher priority task wouldn't be practical anyway. To detect whether to re-tune or not, a helper dummy receiver is attached to the device. If this dummy receiver is detached, re-tuning should be disabled.
  2. DisableScrambleTimeout option only works for clients with priority < 0 (after 9a8fef72 it's not possible anymore). For CAMs like dvbapi, re-tuning after scrambling timeout has expired doesn't help because the channel is then being marked 'checked' (blacklisted) for 15 seconds. To reproduce this, add a delay > 3 seconds to the CAM, or switch it off, and, after some time, switch it on. Solution: 'uncheck' before zapping (GetDevice() call).
FernetMenta commented 7 years ago

thanks for contributing. some questions:

DisableScrambleTimeout option only works for clients with priority < 0

where do you see this relationship? why does it not work for prio 0 and higher?

glenvt18 commented 7 years ago

It's in device.c:

for (int i = 0; i < MAXRECEIVERS; i++) {
    if (receiver[i] && receiver[i]->WantsPid(Pid)) {
       if (DetachReceivers && cs && (!cs->IsActivating() || receiver[i]->Priority() >= LIVEPRIORITY)) {
          dsyslog("detaching receiver - won't decrypt channel %s with CAM %d", *receiver[i]->ChannelID().ToString(), CamSlotNumber);
          ChannelCamRelations.SetChecked(receiver[i]->ChannelID(), CamSlotNumber);
          Detach(receiver[i]);
          }
       else
          receiver[i]->Receive(b, TS_SIZE);
       if (DescramblingOk)
          ChannelCamRelations.SetDecrypt(receiver[i]->ChannelID(), CamSlotNumber);
       }
    }

LIVEPRIORITY is 0. You've added cs->StartActivation(), so cs->IsActivating() is true. But, if receiver[i]->Priority() >= LIVEPRIORITY, Detach() is inevitable. Notice SetChecked() call above Detach(). That's 'blacklisting'. ClrChecked() is the opposite. In practice, after a channel has been blacklisted (scrambling timeout expired), it is not possible to decrypt at all. But with ClrChecked() a series of re-tunes (usually 2 are enough) allows to zap successfully. A better solution would be to have a virtual function int cCamSlot::ScramblingTimeout() instead of using hard-coded 3 sec value. In this case, CAM implementations, which don't need slot enumeration, could return 0. But, for now, all we can do is this workaround.

BTW. I've installed kodi-pvr-vdr-vnsi 2.6.5-1 which was built 2016-09-18 from ppa:team-xbmc/unstable. This addon uses protocol 9 and always transmits priority=-1 regardless of the KODI setting. Is it a bug? So, when I set priority=5, it is transmitted as -1, and then, finally, converted to 0. That's why I added priority logging :-)

EDIT. There used to be a bug when cLiveReceiver::channelID was not explicitly initialized (it was zero-filled). It had a nice side effect that SetChecked() was called on a fake channel and a series of instant re-tunes was possible. It could be seen as "won't decrypt channel 0-0-0 with..." log message, and everything worked fine.

FernetMenta commented 7 years ago

Right, that's the reason I handled deactivation of scramble timeout differently in my first version but somehow seem to forgot it :)

FernetMenta commented 7 years ago

I will investigate the issue with priority.