Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Problem sending unsigned char array with QUdpSocket
Forum Updated to NodeBB v4.3 + New Features

Problem sending unsigned char array with QUdpSocket

Scheduled Pinned Locked Moved General and Desktop
13 Posts 2 Posters 4.4k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • Z Offline
    Z Offline
    zcybercomputing
    wrote on last edited by
    #4

    [quote author="SGaist" date="1413583323"]Hi and welcome to devnet,
    In make_udp_packet, if your new_datagram.size() is over DGRAM_SIZE, you just put the old value in your datagram_buffer, but you don't do anything to keep the pktBuffer, why ?[/quote]

    new_datagram begins in the initialize as being cleared. Thus, new_datagram.size() <DGRAM_SIZE to start out with. In the second if statement, new_datagram is cleared again. Because the size if pktBuffer is allways 188 bytes, and DGRAM_SIZE is calculated from that, there should not be any condition that causes new_datagram.size() to be larger then DGRAM_SIZE.

    Not sure what the best way to post it would be, but the wireshark capture of the packets is weird. Occasionally, a packet will get sent with a proper address destination and sender field parsed by wireshark. Most of the packets either have that field empty, but some have the PMT in the destination field. The PMT is a field in my MPEG-TS packets. The packets comming in via pktBuffer should be valid, because they worked fine using the old winsock code. I didn't like the while loop wait "clocks" in that code though. They had performance inconsistencies.

    1 Reply Last reply
    0
    • Z Offline
      Z Offline
      zcybercomputing
      wrote on last edited by
      #5

      Any help on this?

       I tried using memmove to assemble the datagram instead of appending, and get the same results.  If I create a qbytearray of size DGRAM_SIZE full of zeros and use that as my datagram, I get a proper address source and destination fields, but when filling it with my packet information derived from unsigned char array packets, the address fields do not show up properly in wireshark for most of the datagrams.  
       I can pick up the stream in VLC, and pieces of the picture decode, but it looks like a stream with a huge amount of packet loss.  My thoughts are that it is not seeing any of the datagrams that lack the correct destination address.  Is this a bug in QUdpSocket, or is it just an issue with my conversion from unsigned char to QByteArray?
      
       This is a very frustrating issue.
      
      1 Reply Last reply
      0
      • Z Offline
        Z Offline
        zcybercomputing
        wrote on last edited by
        #6
         I have determined that null packets generated in my program pass fine via QUdpSocket, but packets read from a file cause a problem.  I would like to be able to connect the udp streaming code to the rest of the program without rewriting the whole thing, so I am not sure if I really want to change to using the qt file readers.
         Because of this, I created a test program to send out 50 packets from the file, or 50 null packets as a demo.  This demonstrates that somehow the contents of the packet can mess up the structure of the resulting UDP packet.  I think this may constitute a bug.  This happens both when using fread and QFile to input the file.
        

        zip file with the whole project including .pro file. (if using a shadow build, copy the .ts file to your build dir)
        http://goo.gl/AJHV4W

        mainwindow.h
        @
        #ifndef MAINWINDOW_H
        #define MAINWINDOW_H
        #include "stream.h"
        #include <QMainWindow>

        namespace Ui {
        class MainWindow;
        }

        class MainWindow : public QMainWindow
        {
        Q_OBJECT

        public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();

        private slots:
        void on_pushButton_clicked();
        void on_pushButton_2_clicked();

        void on_pushButton_3_clicked();
        

        private:
        Ui::MainWindow *ui;
        stream *stream_video;
        int packets_read;
        #define K_BIT_RATE 2742 // 5000 4400 In kbps //2875
        #define VLC_OUTPUT_FILE "vlcOutputFile.ts"
        unsigned char pkt[PKT_SIZE];
        unsigned char nullPkt[PKT_SIZE];
        QHostAddress stream_addr;
        qint16 stream_port = 1234;
        };
        #endif // MAINWINDOW_H

        @
        mainwindow.cpp
        @
        #include "mainwindow.h"
        #include "ui_mainwindow.h"

        MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
        {
        ui->setupUi(this);
        nullPkt[0] = 0x47;
        nullPkt[1] = 0x1f;
        nullPkt[2] = 0xff;
        nullPkt[3] = 0x10;
        for (int i=4; i <= 187; i++) {
        nullPkt[i] = 0xff; // Fill nullPkt[ ]; 0..187
        }
        stream_addr.setAddress("239.0.0.225");
        stream_video = new stream(stream_addr, stream_port, K_BIT_RATE,this);
        }

        MainWindow::~MainWindow()
        {
        delete ui;
        }
        bool running;
        void MainWindow::on_pushButton_clicked()
        {

        FILE *origFile;
        origFile  = fopen &#40;VLC_OUTPUT_FILE, "rb"&#41;;
        for(int i=0;i<50*7;i++)
        {
        packets_read = fread(pkt, PKT_SIZE, 1, origFile);
        stream_video->make_udp_packet(pkt,K_BIT_RATE,7);
        }
        

        }

        void MainWindow::on_pushButton_2_clicked()
        {
        for(int i=0;i<50*7;i++)
        {
        stream_video->make_udp_packet(nullPkt,K_BIT_RATE,7);
        }

        }

        void MainWindow::on_pushButton_3_clicked()
        {
        char packet[PKT_SIZE];

        QFile file&#40;VLC_OUTPUT_FILE&#41;;
        if (!file.open(QIODevice::ReadOnly))
        {
            qDebug("File not opened");
        }
        else
            for(int i=0;i<50*7;i++)
            {
                qDebug("reading file");
                packets_read  = file.read(packet,PKT_SIZE);
                qDebug("sending packet");
                 stream_video->make_udp_packet(reinterpret_cast<unsigned char*>(packet),K_BIT_RATE,7);
                qDebug("here");
            }
        

        }

        @

        1 Reply Last reply
        0
        • Z Offline
          Z Offline
          zcybercomputing
          wrote on last edited by
          #7

          After fighting this for a long time today, I decided it must be a bug and filed a bug report. I then went about implementing winsock. First, I converted from QByteArray back to a char to send out winsock, but it had the problem also. After eliminating QByteArray all together, it works!!!!

          You can see the code over on the "bug" report.

          https://bugreports.qt-project.org/browse/QTBUG-42046

          I would still appreciate comment from someone who knows more then me as to what I actually did wrong, or if there is a bug in QByteArray.

          1 Reply Last reply
          0
          • Z Offline
            Z Offline
            zcybercomputing
            wrote on last edited by
            #8

            Ok, looks like I had a case of using pointers when I shouldn't have. The problem is now resolved by forcing a deep copy. I was also under the impression that the UDP packets should have an appearance in wireshark that wasn't accurate.

            1 Reply Last reply
            0
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #9

              Can you elaborate on your need for a deep copy ?

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply
              0
              • Z Offline
                Z Offline
                zcybercomputing
                wrote on last edited by
                #10

                [quote author="SGaist" date="1414020162"]Can you elaborate on your need for a deep copy ?[/quote]

                stream::make_udp_packet() gets called for every transport stream packet. Since there are 7 of those in each datagram, the variable that is used to store the packets must be a copy instead of a pointer. If it is a pointer, like the code above, then the previous packet gets overwritten and every datagram will be the same collection of 7 copies of the same .ts packet.

                QByteArray can operate as a deep copy, or by pointer reference.  When I first implemented it, I unknowingly used the pointer reference.  Because I made a wrong assumption of how the packets should look in wireshark, I went on a tangent of thinking there was a problem with QUdpSocket.
                
                My code now works, I just discovered that I need to send datagrams between 2-3 ms apart.  This means I have to re implement my program to use something other then QTimer.  That will have to wait until I figure out how to patch ffmpeg to enable decode on TV sets.  (the eventual destination for these packets)  After that, ffmpeg will probably handle all of this, unless it has to much overhead.
                
                1 Reply Last reply
                0
                • SGaistS Offline
                  SGaistS Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on last edited by
                  #11

                  Unless I'm mistaken you could also use gstreamer or libVLC which might provide what you need

                  Interested in AI ? www.idiap.ch
                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                  1 Reply Last reply
                  0
                  • Z Offline
                    Z Offline
                    zcybercomputing
                    wrote on last edited by
                    #12

                    We are currently using libvlc, but both libvlc and ffmpeg do not implement pcr correctly for the TV. VLC is not willing to take the patch, and ffmpeg is used as the streaming engine for another program I would like to use. Currently each packet has to be modified in our program to make it work. This is why I am now researching how best to incorporate the correct pcr in ffmpeg.

                    1 Reply Last reply
                    0
                    • SGaistS Offline
                      SGaistS Offline
                      SGaist
                      Lifetime Qt Champion
                      wrote on last edited by
                      #13

                      I see, good luck !

                      Interested in AI ? www.idiap.ch
                      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                      1 Reply Last reply
                      0

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved