Hello I still try to write a Plugin which a background receiving of data.
For example I have 3 devices.
I want the last device to receive data only from "Transponder A" with "PID X". This should be a very high prio.
The user should tune as he likes. Now I want to receive "Transponder B" with "PID Y", but with a low Prio. So the user don't observe it. The low prio receiver should be detached if a user need the device. The Problem is that the user action don't detach the receiver. How can I implement it?
Patrick
So I have written this code: #define PRIORECEIVER 59 struct sReceiverID{ cDevice *device; cPTSReceiver *receiver; int originalNetworkId; int transportStreamId; int serviceId; int vpid; };
/** * Start listening for PTS values on the given service. * * Step1. create the channel for the values * Step2. get next free receiver position in array * Step3. test if allready a receiver is listen to the values, if exist return * Step4. test if allready a receiver is listen on same transponder. if exist create a new receiver and add to same device. return * Step5. test if static device can receive data. If it could, create a device and add to static device and return * Step6. test all other devices and add the first fit device. return * Step7. return with false. No device can handel a receiver with this valuse. */ bool ctuner::addPTSStream(int originalNetworkId, int transportStreamId, int serviceId){
//DEBUG /* for (int b=0;b<MAXRECEIVERS;b++){ if (receiverID[b].originalNetworkId){ dsyslog("receiverID[%d].",b); dsyslog(" %d) ONID: %d",b,receiverID[b].originalNetworkId); dsyslog(" %d) TSID: %d",b,receiverID[b].transportStreamId); dsyslog(" %d) SID: %d \n",b,receiverID[b].serviceId); dsyslog(" lisen on device[%d]",receiverID[b].device->DeviceNumber()); } }; */ //DEBUG END
//create the fitting channel for the originalNetworkId, transportStreamId and serviceId cChannel *channel = GetChannelBy_ONID_TID_SID(originalNetworkId,transportStreamId,serviceId);
if(!channel)return false;//can't read channel from file else{ // dsyslog("channels with originalNetworkId = %d, transportStreamId = %d and serviceId = %d was found and has VPID=%d",originalNetworkId,transportStreamId,serviceId,channel->Vpid()); }
//create a receiver for the VPID cPTSReceiver *receiver = NULL; int a; for (a=0;((receiverID[a].receiver!=NULL) && (a<MAXRECEIVERS));a++){}; if (receiverID[a].receiver){ esyslog("MAXRECEIVER reached"); return false;//max receivers was reached }
//check if already a receiver is set to the originalNetworkId, transportStreamId and serviceId. // if a receiver with the same originalNetworkId, transportStreamId and serviceId were found, // no new receiver was needed. for(int i=0;i < MAXRECEIVER;i++){ if ((receiverID[i].originalNetworkId == originalNetworkId) && (receiverID[i].transportStreamId == transportStreamId) && (receiverID[i].serviceId == serviceId)){ //there is already a receiver set to this IDs //dsyslog("There is already a receiver listen to the IDS: %d, %d ,%d",originalNetworkId, transportStreamId, serviceId); return true;//not need to attach new receiver } }//no receiver found for this IDs lets create a new receiver
//dsyslog("VPID from channel is: %d",channel->Vpid()), receiver = new cPTSReceiver(channel->Vpid()); if(!receiver){ dsyslog("receiver failed"); return false; } receiverID[a].receiver = receiver; receiverID[a].originalNetworkId =0;//will be set later receiverID[a].transportStreamId =0;//will be set later receiverID[a].serviceId =serviceId; receiverID[a].device = NULL;//will be set later if device was known receiverID[a].vpid = channel->Vpid(); //dsyslog("new PTSReceiver was created for VPID=%d",channel->Vpid());
// If a receiver with the same originalNetworkId and transportStreamId // were found, the device of this receiver is tuned to the same originalNetworkId, transportStreamId // the new receiver need, so I can attach the new receiver to the same device for(int i=0;i < MAXRECEIVER;i++){ if ((receiverID[i].originalNetworkId == originalNetworkId) && (receiverID[i].transportStreamId == transportStreamId)){ //there is already a receiver on the same transponder //dsyslog("There is already a receiver on the same transponder IDS: %d, %d, added ",originalNetworkId, transportStreamId); if (!receiverID[i].device->AttachReceiver(receiver)){ esyslog("ERROR could not attach receiver to same transponder. reason unknown"); delete receiver; receiverID[a].receiver = NULL; receiverID[a].originalNetworkId = 0; receiverID[a].transportStreamId = 0; receiverID[a].serviceId = 0; receiverID[a].device = NULL; receiverID[a].vpid = 0; return false;//could not attach receiver, reason unknown } receiverID[a].device = receiverID[i].device; receiverID[a].originalNetworkId =originalNetworkId; receiverID[a].transportStreamId =transportStreamId; dsyslog("added to device[%d]",receiverID[a].device->DeviceNumber()); return true;//new receiver was added to same device } }
//not I need to test all other devices to receive the data
cDevice *device;
//check the last device first, because it is static tuned on a transponder and will not change device = cDevice::GetDevice(cDevice::NumDevices()-2);//TODO in case of xine the last one is the xine device so use -2 else -1 if(device->ProvidesChannel(channel,PRIORECEIVER)){ //dsyslog(" static device can receive PTSStream"); device->SwitchChannel(channel,false); if (!device->AttachReceiver(receiver)){ esyslog("ERROR could not attach receiver to static device."); }else{ receiverID[a].device = device; receiverID[a].originalNetworkId =originalNetworkId; receiverID[a].transportStreamId =transportStreamId; dsyslog("added to device[%d]",receiverID[a].device->DeviceNumber()); return true;//successful added } } else { //dsyslog(" static device can't receive PTSStream"); }
//check all other devices if the receiver can be added for (int i= cDevice::NumDevices()-2; i>=0 ;i--){ device = cDevice::GetDevice(i); if(device->ProvidesChannel(channel,PRIORECEIVER)){ //dsyslog(" device[%d] can receive PTSStream",i); device->SwitchChannel(channel,false); if (!device->AttachReceiver(receiver)){ esyslog("ERROR could not attach receiver to device[%d].",i); }else{ // dsyslog("successful added receiver to device[%d]",i); receiverID[a].originalNetworkId =originalNetworkId; receiverID[a].transportStreamId =transportStreamId;
receiverID[a].device = device; dsyslog("added to device[%d]",receiverID[a].device->DeviceNumber()); return true;//successful added } } else{ // dsyslog(" device[%d] can't receive PTSStream",i);
} }
//no device can handel the originalNetworkId, transportStreamId and serviceId // so clean up and exit with false // dsyslog("no device found for VPID=%d",receiverID[a].vpid); delete receiver; receiverID[a].receiver = NULL; //not needed but make it clean receiverID[a].originalNetworkId =0; receiverID[a].transportStreamId =0; receiverID[a].serviceId =0; receiverID[a].receiver = NULL; receiverID[a].vpid = 0; return false;
}
By the way... -how to realize that a receiver was detached? -how to ask if ANY cDevice can ProvidesChannel?
I know if I create a receiver with prio -1 vdr can detach it if vdr needs the device.
My Problem is: If I create a receiver with prio -1 then vdr can detach it. Thats OK. But if I want to know if a device can handle my new receiver(on an defined channel) then cDevice->ProvideChannel() show me allways that the first device can handle my receiver. Thats because my first receiver has prio -1.
If I create my receiver with prio 1 then cDevice->ProvideChannel() tells me that the device is used. Thats better but in this case vdr don't detach my receiver.
It would be nice if vdr can detach all receiver with prio <50.
Patrick
Patrick(gmx) schrieb:
Hello I still try to write a Plugin which a background receiving of data.
For example I have 3 devices.
I want the last device to receive data only from "Transponder A" with "PID X". This should be a very high prio.
The user should tune as he likes. Now I want to receive "Transponder B" with "PID Y", but with a low Prio. So the user don't observe it. The low prio receiver should be detached if a user need the device. The Problem is that the user action don't detach the receiver. How can I implement it?
Patrick
So I have written this code:
--------
Patrick Fischer wrote:
By the way... -how to realize that a receiver was detached? -how to ask if ANY cDevice can ProvidesChannel?
I know if I create a receiver with prio -1 vdr can detach it if vdr needs the device.
My Problem is: If I create a receiver with prio -1 then vdr can detach it. Thats OK. But if I want to know if a device can handle my new receiver(on an defined channel) then cDevice->ProvideChannel() show me allways that the first device can handle my receiver. Thats because my first receiver has prio -1.
If I create my receiver with prio 1 then cDevice->ProvideChannel() tells me that the device is used. Thats better but in this case vdr don't detach my receiver.
Calling ProvidesChannel(-1) tells you whether the device can pricipally provide this channel, no matter what receivers it currently has attached to it. Why don't you just skip your first device if you already know that you don't want to use that one?
It would be nice if vdr can detach all receiver with prio <50.
What would that be good for?
Klaus
Klaus Schmidinger schrieb:
Patrick Fischer wrote:
By the way... -how to realize that a receiver was detached? -how to ask if ANY cDevice can ProvidesChannel?
I know if I create a receiver with prio -1 vdr can detach it if vdr needs the device.
My Problem is: If I create a receiver with prio -1 then vdr can detach it. Thats OK. But if I want to know if a device can handle my new receiver(on an defined channel) then cDevice->ProvideChannel() show me allways that the first device can handle my receiver. Thats because my first receiver has prio -1.
If I create my receiver with prio 1 then cDevice->ProvideChannel() tells me that the device is used. Thats better but in this case vdr don't detach my receiver.
Calling ProvidesChannel(-1) tells you whether the device can pricipally provide this channel, no matter what receivers it currently has attached to it. Why don't you just skip your first device if you already know that you don't want to use that one?
It would be nice if vdr can detach all receiver with prio <50.
What would that be good for?
Klaus
-I want always receive Channel X -The user should switch if he want to -And I want to allot some receiver for some channels(vpids) But this needs some management.
It's difficult to explane, but I try:
//some defines: Userreceiver(int channel) : the user want to see or record some channel myreceiver(int channel, int vpid) : I want to receive some data from channel staticreceiver(int channel, int vpid): this receiver should always receive the vpid from channel
Same Transponder {1,2,3,4}{5,6,7,8}{9,10,11,12}{13,14,15,16} ******** Getting started: Device 0: Userreceiver(4) Device 1: Device 2: staticreceiver(14,42) ------ ->Add new myreceiver(5,213): can be attached to Device 1
Device 0: Userreceiver(4) Device 1: myreceiver(5,11) Device 2: staticreceiver(14,42) ------ ->Add new myreceiver(2,113): can be attached to Device 0
Device 0: Userreceiver(4),myreceiver(2,113) Device 1: myreceiver(5,11) Device 2: staticreceiver(14,42) ------ ->Add new myreceiver(7,413): can be attached to Device 1
Device 0: Userreceiver(4),myreceiver(2,113) Device 1: myreceiver(5,11),myreceiver(7,413) Device 2: staticreceiver(14,42) ------ ->Add new myreceiver(16,515): can be attached to Device 2
Device 0: Userreceiver(4),myreceiver(2,113) Device 1: myreceiver(5,11),myreceiver(7,413) Device 2: staticreceiver(14,42),myreceiver(16,515) ------ ->User want to switch to Channel(11): myreceiver(2,113) must be detached
Device 0: Userreceiver(11) Device 1: myreceiver(5,11),myreceiver(7,413) Device 2: staticreceiver(14,42),myreceiver(16,515) ------
If I want to add a new myreceiver, the i must find a device where to attach it. How I do that?: I ask each device if it can handle it. ->Add new myreceiver(16,515){ for all devices if(cDevice->ProvideChannel(16)) attach myreceiver(16,515) }
so I can find: device0 , device1, device2 or nodevice
If I use prio-1 the always device0 will be found. If I use prio>0 then the user can't switch to other channels if a myreceiver is also attached to device0,device1, device2.
maybe I don't understand the prio management of vdr. device0->attachReceiver(myreceiver,Prio10) if(device0->ProvideChannel(channel1,11)) device0->switchToChannel(channel1): that ought detach myreceiver!
wouldn't it be good if the switchToChannel can have a prio? Maybe 50.
I hope you understand what I mean. My English is not very good.
Patrick
Patrick Fischer wrote:
Klaus Schmidinger schrieb:
Patrick Fischer wrote:
By the way... -how to realize that a receiver was detached? -how to ask if ANY cDevice can ProvidesChannel?
I know if I create a receiver with prio -1 vdr can detach it if vdr needs the device.
My Problem is: If I create a receiver with prio -1 then vdr can detach it. Thats OK. But if I want to know if a device can handle my new receiver(on an defined channel) then cDevice->ProvideChannel() show me allways that the first device can handle my receiver. Thats because my first receiver has prio -1.
If I create my receiver with prio 1 then cDevice->ProvideChannel() tells me that the device is used. Thats better but in this case vdr don't detach my receiver.
Calling ProvidesChannel(-1) tells you whether the device can pricipally provide this channel, no matter what receivers it currently has attached to it. Why don't you just skip your first device if you already know that you don't want to use that one?
It would be nice if vdr can detach all receiver with prio <50.
What would that be good for?
Klaus
-I want always receive Channel X -The user should switch if he want to -And I want to allot some receiver for some channels(vpids) But this needs some management.
It's difficult to explane, but I try:
//some defines: Userreceiver(int channel) : the user want to see or record some channel myreceiver(int channel, int vpid) : I want to receive some data from channel staticreceiver(int channel, int vpid): this receiver should always receive the vpid from channel
Same Transponder {1,2,3,4}{5,6,7,8}{9,10,11,12}{13,14,15,16}
Getting started: Device 0: Userreceiver(4) Device 1: Device 2: staticreceiver(14,42)
->Add new myreceiver(5,213): can be attached to Device 1
Device 0: Userreceiver(4) Device 1: myreceiver(5,11) Device 2: staticreceiver(14,42)
->Add new myreceiver(2,113): can be attached to Device 0
Device 0: Userreceiver(4),myreceiver(2,113) Device 1: myreceiver(5,11) Device 2: staticreceiver(14,42)
->Add new myreceiver(7,413): can be attached to Device 1
Device 0: Userreceiver(4),myreceiver(2,113) Device 1: myreceiver(5,11),myreceiver(7,413) Device 2: staticreceiver(14,42)
->Add new myreceiver(16,515): can be attached to Device 2
Device 0: Userreceiver(4),myreceiver(2,113) Device 1: myreceiver(5,11),myreceiver(7,413) Device 2: staticreceiver(14,42),myreceiver(16,515)
->User want to switch to Channel(11): myreceiver(2,113) must be detached
Device 0: Userreceiver(11) Device 1: myreceiver(5,11),myreceiver(7,413) Device 2: staticreceiver(14,42),myreceiver(16,515)
If I want to add a new myreceiver, the i must find a device where to attach it. How I do that?: I ask each device if it can handle it. ->Add new myreceiver(16,515){ for all devices if(cDevice->ProvideChannel(16)) attach myreceiver(16,515) }
so I can find: device0 , device1, device2 or nodevice
If I use prio-1 the always device0 will be found. If I use prio>0 then the user can't switch to other channels if a myreceiver is also attached to device0,device1, device2.
maybe I don't understand the prio management of vdr. device0->attachReceiver(myreceiver,Prio10) if(device0->ProvideChannel(channel1,11)) device0->switchToChannel(channel1): that ought detach myreceiver!
wouldn't it be good if the switchToChannel can have a prio? Maybe 50.
Wouldn't it be enough to simply give your receiver a priority of -2 (anything less than -1 would do)? That way any recording and even a Transfer Mode (which uses priority -1) could detach your receiver.
Klaus
Hello Klaus,
Wouldn't it be enough to simply give your receiver a priority of -2 (anything less than -1 would do)? That way any recording and even a Transfer Mode (which uses priority -1) could detach your receiver.
Klaus
I didn't knew that I can use values less then -1 If I understand right, this should work:
PRIORECEIVER= -2 PRIOSWITCHCHANNEL= -3 receiver = new MyReceiver(PRIORECEIVER); :FOR ALL DEVICES device = cDevice::GetDevice(SomeDevice); if(device->ProvidesChannel(channel,PRIOSWITCHCHANNEL)){ device->SwitchChannel(channel,false); if (!device->AttachReceiver(receiver)){ esyslog("ERROR could not attach receiver to device."); } }
now I have replaced this with:
PRIORECEIVER= -2 PRIOSWITCHCHANNEL= -3 receiver = new MyReceiver(PRIORECEIVER); device = cDevice::GetDevice(channel, PRIOCHANGECHANNEL); if(device){ device->SwitchChannel(channel,false); if (!device->AttachReceiver(receiver)){ esyslog("ERROR could not attach receiver to device."); } }else{ dsyslog("no device can handle the channel"); }
In this case device->ProvidesChannel(channel,PRIOSWITCHCHANNEL) is always true If I use PRIORECEIVER= 11 PRIOSWITCHCHANNEL= 10 It works, but useraction will not detach myreceiver.
If I'm looking in dvbdevice.c ProvidesChannel:
bool cDvbDevice::ProvidesChannel(const cChannel *Channel, int Priority, bool *NeedsDetachReceivers) const { bool result = false; bool hasPriority = Priority < 0 || Priority > this->Priority(); ....
if (ProvidesSource(Channel->Source()) && ProvidesCa(Channel)) { result = hasPriority; if (Priority >= 0 && Receiving(true)) { ............. } ........ return result; }
So if I call this Function with a value < 0 and the device can ProvideSource and ProvideCa it will always return true. There is no check for other receiver(and the prio of them) are attached.
Should I try to reexplane my Problem?
Patrick
Hello Klaus,
Wouldn't it be enough to simply give your receiver a priority of -2 (anything less than -1 would do)? That way any recording and even a Transfer Mode (which uses priority -1) could detach your receiver.
Klaus
now I have rewritten all my code. It seems to work.
this function finds a device which can provide a receiver without detach any receiver. (independent of the prio)
bool needdetach = false; bool found = false; for (int i=0; (i < (cDevice::NumDevices()-1) && !found);i++){ device = cDevice::GetDevice(i); if(device->ProvidesChannel(channel,PRIOCHANGECHANNEL,&needdetach) && !needdetach){ //device can Provide Channel and no receiver has to detach found = true; }else{ device = NULL; } } if(device){ device->SwitchChannel(channel,false); device->AttachReceiver(receiver); }
on the found device i can add myreceiver with Prio -2
additional I observe all myreceiver. If I want to add a new myreceiver to a device I will look at my local List, if I have already added a receiver to the transponder. If I found one I will add my receiver to the same device.
But now I need to recognize if vdr has detached my receiver. So I have used void cMyReciver::Activate(bool On) to recognize if it will detach. The Problem is, that it will only be detached if vdr will shutdown.
Patrick
Patrick Fischer schrieb:
Hello Klaus,
Wouldn't it be enough to simply give your receiver a priority of -2 (anything less than -1 would do)? That way any recording and even a Transfer Mode (which uses priority -1) could detach your receiver.
Klaus
now I have rewritten all my code. It seems to work.
this function finds a device which can provide a receiver without detach any receiver. (independent of the prio)
bool needdetach = false; bool found = false; for (int i=0; (i < (cDevice::NumDevices()-1) && !found);i++){ device = cDevice::GetDevice(i); if(device->ProvidesChannel(channel,PRIOCHANGECHANNEL,&needdetach) && !needdetach){ //device can Provide Channel and no receiver has to detach found = true; }else{ device = NULL; } } if(device){ device->SwitchChannel(channel,false); device->AttachReceiver(receiver); }
on the found device i can add myreceiver with Prio -2
additional I observe all myreceiver. If I want to add a new myreceiver to a device I will look at my local List, if I have already added a receiver to the transponder. If I found one I will add my receiver to the same device.
But now I need to recognize if vdr has detached my receiver. So I have used void cMyReciver::Activate(bool On) to recognize if it will detach. The Problem is, that it will only be detached if vdr will shutdown.
::Please read my last 2 Posts::
I have insert a detachAll() (without PID!!) to the cDevice. An insert a calling into cDvbDevice::SetChannelDevice so all receivers will be detached if a user switch the channel. There are two problems: -vdr will detachAll if the backgroundScanner(EITScanner??) do his job. -it is not necessary to detachAll if the User switch to a channel on same transponder
By the way, I don't understand why a receiver will not detached if the channel+PID don't exist anymore. Isn't that the case why I use Prios < -1?
I hope anybody can tell me some ideas.
I move in a circle...
Patrick
next try.... I have still some problems with the detach of a receiver.
So I have written a small demo Plugin to show my Problem. The demo is a Plugin that only create and attach a receiver to the first device at the startup time. If the Plugin will be stopped, it will delete the receiver.
There are some debug output Infos for create, destroy, attach and detach the receiver
I get this log if I start, wait an stop the Plugin:
Jan 3 13:50:40 localhost vdr[9343]: VDR version 1.3.37 started ..... Jan 3 13:50:40 localhost vdr[9343]: initializing plugin: receivertest (0.0.1): Enter description for 'receivertest' plugin ..... Jan 3 13:50:40 localhost vdr[9343]: starting plugin: receivertest Jan 3 13:50:40 localhost vdr[9343]: switching to channel 5 ..... Jan 3 13:50:40 localhost vdr[9343]: should add Receiver to Channel 5 on Device 0 with Vpid 545 Jan 3 13:50:40 localhost vdr[9343]: created a new receiver for ZDF with prio -1 Jan 3 13:50:40 localhost vdr[9343]: Attach receiver to ZDF ..... Jan 3 13:50:40 localhost vdr[9343]: switching to channel 5 ..... Jan 3 13:50:40 localhost vdr[9343]: receiving data from channelname=ZDF Jan 3 13:50:41 localhost last message repeated 2205 times ..... Jan 3 13:53:52 localhost vdr[9343]: caught signal 15 Jan 3 13:53:52 localhost vdr[9343]: stopping plugin: receivertest Jan 3 13:53:52 localhost vdr[9343]: destroy Receiver for Channel ZDF Jan 3 13:53:52 localhost vdr[9343]: Detach receiver from ZDF ..... Jan 3 13:53:52 localhost vdr[9343]: deleting plugin: receivertest ..... Jan 3 13:53:52 localhost vdr[9343]: exiting
And now I got the Problem, if i switch the channel from ZDF to VOX (same VPID) I get the data from VOX not from ZDF: (cutted) Jan 3 13:50:40 localhost vdr[9343]: switching to channel 5 Jan 3 13:50:40 localhost vdr[9343]: should add Receiver to Channel 5 on Device 0 with Vpid 545 Jan 3 13:50:40 localhost vdr[9343]: created a new receiver for ZDF with prio -1 Jan 3 13:50:40 localhost vdr[9343]: Attach receiver to ZDF Jan 3 13:50:40 localhost vdr[9343]: switching to channel 5 Jan 3 13:50:40 localhost vdr[9343]: receiving data from channelname=ZDF Jan 3 13:50:41 localhost last message repeated 2205 times Jan 3 13:50:43 localhost vdr[9343]: switching to channel 13 //VOX same VPID Jan 3 13:50:43 localhost vdr[9343]: receiving data from channelname=ZDF Jan 3 13:50:43 localhost last message repeated 2205 times
The best way would be if VDR would detach the receiver if the original VPID can't be received anymore. cDevice *cDevice::GetDevice(const cChannel *Channel, int Priority, bool *NeedsDetachReceivers) can return if the Receiver need to be detached. But VDR didn't use this Info.
My demo Plugin will be attached to this email. Please read it. I have written over a hour at the demo and this mail! :-(
Greetings Patrick
I have written a quick and dirty patch to build my requested function. It is too dirty to use it. It only work in the case you use always the transfermode.
But now I can show how it should work.
--- vdr-1.3.37_orig/device.c 2005-11-26 13:56:09.000000000 +0100 +++ vdr-1.3.37/device.c 2006-01-03 16:54:18.000000000 +0100 @@ -588,7 +588,23 @@ // use the card that actually can receive it and transfer data from there:
if (NeedsTransferMode) { - cDevice *CaDevice = GetDevice(Channel, 0); + bool ntd; + cDevice *CaDevice = GetDevice(Channel, 0, &ntd); + if (ntd){//detach all receivers from device + dsyslog("need to detach all receivers from device"); + for (int i = 0; i < MAXRECEIVERS; i++) { + // CaDevice->receiver[i]->Detach(); + if (CaDevice->receiver[i]){ + dsyslog("%d will be detached",i); + CaDevice->receiver[i]->Detach(); + //CaDevice->receiver[i]->Activate(false); + //CaDevice->receiver[i] = NULL; + //CaDevice->receiver[i]->device = NULL; + //for (int n = 0; n < CaDevice->receiver[i]->numPids; n++) + // DelPid(CaDevice->receiver[i]->pids[n]); + } + } + } 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()!