How to change the packet handling part into different threads?



  • Hi,

    I want to create a buffer to hold coming data,the "ReadyRead" slot is responsible for recieving.
    After i recieve the packet,I want to play the packet which is in audio format.
    The playing part is also implemented inside "ReadyRead" function.
    The thing is when I play the packet,the "ReadyRead" blocked,did not recieve packet anymore,
    which will cause the packet recieving delay.And the audio quality is very bad.
    how can make the recieving and playing synchronously?

    below is the "ReadyRead" function.

    void CDS::readyRead()
    {
    QByteArray temp_buffer;
    unsigned char* data;
    QHostAddress sender;
    quint16 senderPort;
    CIncomingRTPPktLink *temp;

    temp_buffer.resize(socket->pendingDatagramSize());
    
    int rtn = socket->readDatagram(temp_buffer.data(), temp_buffer.size(),
            &sender, &senderPort);
    //QString res(temp_buffer);
    //qDebug() << "CDS:Response =>" << res;
    
    
    // Special handling of padding to take care of encrypted content.
    // In case of SRTP the padding length field is also encrypted, thus
    // it gives a wrong length. Check and clear padding bit before
    // creating the RTPPacket. Will be set and re-computed after a possible
    // SRTP decryption.
    data = (unsigned char*)temp_buffer.data();
    quint8 padSet = (*data & 0x20);
    if (padSet) {
        *data = *data & ~0x20;          // clear padding bit
    }
    
    // add packet to quene
    buffer.append(temp_buffer);
    
    if (buffer.length()<=buffer_size)
    {
        //  build a packet.
        CIncomingRTPPkt* packet =
            new CIncomingRTPPkt((unsigned char*)buffer.data()+p_buffer,rtn);
    
        // Generic header validity check.
        if ( !packet->isHeaderValid() ) {
            delete packet;
            return;
        }
    
        // Move to next packet
        p_buffer+=rtn;
    
        // Build packet link
        CIncomingRTPPktLink* packetLink =
            new     CIncomingRTPPktLink(packet,NULL,NULL);
    
        // Build packet quene
        quene->insertRecvPacket(packetLink);
     }
    else
    {
    
        temp = quene->getFirst();
        while(temp != NULL)
        {
            //qDebug() << "temp null";
            playAudio(CODEC_ID_MP3,(uint8_t*)temp->getPacket()->getPayload()
                       ,temp->getPacket()->getPayloadSize()-4);
            temp = temp->getNext();
        }
    
        quene->reset();
        buffer.clear();
        p_buffer = 0;
    
    }
    

    }


  • Moderators

    Well you already know what you need to do to fix it. You need separate threads to handle socket and audio playing. If you have a GUI of some sort I highly recommend a thread for the socket and a thread for the audio player portion. Leaving your main thread for your GUI.

    To do threads in Qt, check into QThread (http://doc.qt.io/qt-5/qthread.html).

    Here is a brief example of moving a QObject onto it's own thread:

    YourController::YourController(QObject *parent) : QObject(parent)
    {
       auto socket = new YourSocket();
       socket->moveToThread(&worker_);
       connect(&worker_, SIGNAL(finished()), socket, SLOT(deleteLater());
       connect(socket, SIGNAL(readyRead()), this, SLOT(handleRead()));
       worker_.start();
    }
    
    YourController::~YourController()
    {
       worker_.quit();
       worker_.wait();
    }
    

    That was rough code out of my head so it may not be right, but that plus other online examples should get you where you need to go with Qt threads.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.