[vdr] receive data with low prio, so user-action can detach the receiver

Patrick(gmx) patrick_fischer at gmx.de
Mon Nov 21 10:04:39 CET 2005


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;

}




More information about the vdr mailing list