Question

I am in the process of developing a forwarder application for VLC and have run into the following problem:

The forwarder is supposed to receive a UDP stream and forward it to another middleware, which will then put the packets on a time triggered network. My issue lies with the irregularity of the packets sent by VLC. The target network processes the messages in a periodic manner, causing it to drop frames, once VLC starts sending many packets in quick succession (usually during scene changes for example). I need to enforce a sporadic behaviour for these bursts of data, so they may arrive as they please, but get forwarded with a minimum interrival time.

So far, my forwarder works as follows:

I put the whole thing in a QThread and connect the readyRead() signal to my receivePacket() slot which handles reception, processing and sending the data again by calling a second function sendPacket()

My first (naive) idea was to simply have the thread sleep for, say, 100 microseconds after each QUdpSocket::writeDatagram call, but this seems like a bad approach, since I will be suspending the whole thread and thus (I am not sure about this) lose packets from VLC which arrive during that time.

Another solution I thought of was creating a singleshot Qtimer, which would delay the writeDatagram() call. But here, I am not sure what will happen if another packet arrives and triggers the receivePacket() slot again and thus overwriting the message I am trying to delay sending.

Is there an easy way to solve this problem? The only way I could imagine possible would be to introduce an internal buffer to the sender, but this sounds like a lot of work and since I am on a deadline, I would like to avoid that.

Thank you in advance!

Was it helpful?

Solution

As far as i understood, the sendPacket() method gets called to fast/often. This means you will need to create a buffer, but thats quite easy (if run in multiples threads for receivePacket and sendPacket, also add a QMutex::lock()/unlock() before/after accessing buffer)

In Class.h:

QTimer *timer;  // Timer for periodically calling a sendPacket
QList<MyPacketClass*> buffer; // List containing the packets to be sent

In Class.cpp Constructor create the timer with connection:

timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(slotSendPacket()));
timer->start(1000); // Every second

In receivePacket() just add the data to the list:

buffer.append(new MyPacketClass(data));

In class.cpp create a socket for connection and poping data from the list:

void SomeClass::slotSendPacket()
{
  if(buffer.size() > 0)
  {
    sendPacket(buffer.takeAt(0));
  }
}

In method sendPacket(MyPacketClass* inData) free the allocated memory:

Do_whatever_needs_to_be_done_and_sent(); // Here is writeDatagram();
delete inData; // Free the memory for Packetclass
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top