Threads mit QtConcurrent



  • @makopo So bringt dir der neue Thread nix! Du startest den neuen Thread und wartest dann direkt auf die Beendigung. So kannst du das direkt im Hauptthread machen.



  • @Schlangenmensch

    Ok, danke. Tatsächlich fängt der Stream auch an zu ruckeln wenn ich waitForFinished aufrufe. Ohne Aufruf ist das nicht so und der Stream läuft einigermaßen flüssig.

    ReceiveFrame scheint dann ja nicht der beste Ort zu sein, um die empfangenen Frames an die Konvertierungsfunktion zu übergeben. Allerdings schaffe ich es auch nicht IDeckLinkVideoFrame* theFrame als Parameter an einer anderen Stelle zu übergeben, da theFrame sonst in jedem Fall immer 0 ist.

    Ich hatte es per Signal/Slot probiert, aber auch hier wird die Konvertierungsfunktion nicht aufgerufen.

    GraphicScreen::GraphicScreen(QWidget* parent) :
        QWidget(parent)
    {
        m_videoScreenHelper = new VideoScreenHelper(parent);
        QObject::connect(m_videoScreenHelper, &VideoScreenHelper::SendFrame, this, &GraphicScreen::DeckLinkToCv, Qt::QueuedConnection);
    }
    

    SendFrame sendet dabei IDeckLinkVideoFrame* theFrame an den Slot. Kann man das so umsetzten oder gibt es bessere Lösungen? Stehe da gerade echt auf dem Schlauch...

    EDIT: Sende IDeckLinkVideoFrame* theFrame nun an den Slot zur Konvertierung. Jetzt muss die Konvertierung meiner Meinung nach in einen anderen Thread ausgelagert werden?



  • DeckLinkToCv bekommt einen Zeiger als Parameter, das passt nicht. Das Frame muss am Leben erhalten werden. Also evtl. den CComPtr als Kopie übergeben.
    Ich würde spontan eher zu einem dedizierten Thread tendieren. Evtl. ein Thread, der einliest, konvertiert, und die Frames in einer Queue ablegt. Und der Hauptthread stellt sie dar oder wie auch immer.

    Kann es sein, dass du einen ziemlich langsamen Rechner hast? Wundert mich, dass das nicht in Echtzeit geht.



  • @Mechanics

    Ja, der Rechner ist ein wenig langsamer. Aber selbst wenn er das nicht wäre, würde es doch Sinn machen die Formatwandlung zwecks Perfomance in einem anderen Thread durchzuführen?
    Ich meine 25 Bilder die Sekunde nach cv::Mat konvertieren und dann auch noch die Pixelwerte auslesen lassen, dürfte doch für eine ganz gute Auslastung sorgen?



  • @makopo sagte in Threads mit QtConcurrent:

    Ich meine 25 Bilder die Sekunde nach cv::Mat konvertieren und dann auch noch die Pixelwerte auslesen lassen, dürfte doch für eine ganz gute Auslastung sorgen?

    Glaub ich eher nicht... Ich kann jetzt grad nichts mit Sicherheit behaupten. Ist schon paar Jahre her, dass ich was ähnliches gemacht habe, und ich kann mich auch nicht erinnern, was das jetzt ganz genau war und wie schnell das war. Aber so wie ich mich dran erinnere, war da auch Konvertierung nach OpenCv, dann ein bisschen Verarbeitung und paar einfache Effekte, und Ausgabe. Und das ging in Echtzeit.
    Das Einlesen/Konvertieren hatte ich aber über ffmpeg gemacht, mit Hardware-Unterstützung.



  • @Mechanics

    Okay, bin für jede Mini-Erfahrung dankbar...
    Also wenn ich die Pixelwerte für RGB von einer 300 x 200 Pixelgrafik auslesen lassen dauert das über 5 Sekunden bis jeder Pixel auf der Konsole ausgegeben wurde. Für einen 1080p25 Videostream ist das nicht ganz so cool.
    Schreit nach einem neuen Rechner, wobei ich meine mal gelesen zu haben das das auch am Compiler liegen könnte.



  • @makopo sagte in Threads mit QtConcurrent:

    bis jeder Pixel auf der Konsole ausgegeben wurde.

    Das hört sich doch eher nach dem Flaschenhals an. Was machst du da genau?



  • @makopo sagte in Threads mit QtConcurrent:

    @Mechanics

    Okay, bin für jede Mini-Erfahrung dankbar...
    Also wenn ich die Pixelwerte für RGB von einer 300 x 200 Pixelgrafik auslesen lassen dauert das über 5 Sekunden bis jeder Pixel auf der Konsole ausgegeben wurde. Für einen 1080p25 Videostream ist das nicht ganz so cool.
    Schreit nach einem neuen Rechner, wobei ich meine mal gelesen zu haben das das auch am Compiler liegen könnte.

    Das hört sich komisch an: Ich habe mal ein bisschen Bildverstehen auf 'ner 800 Mhz CPU gemacht, die in so 'n Fußballroboter eingebaut war. Da musste man ein bisschen aufpassen und hat z.B. nicht jeden Pixel verarbeitet, weil man auch noch andere Sachen machen musste, Aber 300 * 200 * 3 Werte auslesen und ausgeben über 5 Sekunden... Ist das die Ausgabe auf der Konsole? Das dauert schon mal. Wie lange dauert es, wenn du die alle, sagen wir, aufaddierst und nur einen Wert ausgibst? (Ich will die Ausgabe minimieren 😉 )

    Was für eine CPU hast du denn? Welchen Compiler benutzt du? Und, mit welchen Flags kompilierst du? Wie sieht der Code aus, mit dem du deine Messung gemacht hast?



  • @Mechanics sagte in Threads mit QtConcurrent:

    Das hört sich doch eher nach dem Flaschenhals an. Was machst du da genau?

    void GraphicScreen::ReadPixelData() {
    
        unsigned char r, g, b;
        cv::Mat frame = cv::imread("C://ImageTest/test.jpg");
    
        for (int x = 0; x < frame.rows; ++x)
        {
            cv::Vec3b* pixel = frame.ptr<cv::Vec3b>(x);
            for (int y = 0; y < frame.cols; ++y)
            {
                r = pixel[y][2];
                g = pixel[y][1];
                b = pixel[y][0];
    
                qDebug() << "R" << r  << "G" << g << "B" << b;
            }
        }
    }
    

    Das ist die Funktion mit der ich die Pixel auslese. Vielleicht ist die auch nicht besonders effizient. Und parallel läuft in meinem Programm kein anderer Prozess (also auch nicht das einlesen des Videostreams)

    @Schlangenmensch sagte in Threads mit QtConcurrent:

    Was für eine CPU hast du denn? Welchen Compiler benutzt du? Und, mit welchen Flags kompilierst du?
    CPU: i3 mit 3 GHz (ist mir ein wenig peinlich, aber der Rechner wurde mir gestellt, habe vorher ehrlich gesagt auch nicht darauf geachtet)
    Compiler: MSVC2019 C++17
    Flags: Bewusst habe ich keine Flags gesetzt. Ich habe über Qt ein makefile erstellt und in VS die Libraries eingebunden. Das war mein Setup. Laufen lassen tue ich das Programm im Debug Mode.

    Am Anfang des Projekts dachte ich ja auch das sowas theoretisch in Echtzeit funktionieren müsste. Aber dann setzt man die ersten Sachen um und merkt das es doch nicht so funktioniert wie geplant und kommt ins Zweifeln und in Erklärungsnot ^^.



  • @makopo sagte in Threads mit QtConcurrent:

    Das ist die Funktion mit der ich die Pixel auslese. Vielleicht ist die auch nicht besonders effizient.

    Lass mal das qDebug zum Test weg. Ich vermute, das braucht sehr viel mehr Zeit, als das Auslesen.



  • @makopo sagte in Threads mit QtConcurrent:

    Was für eine CPU hast du denn? Welchen Compiler benutzt du? Und, mit welchen Flags kompilierst du?

    CPU: i3 mit 3 GHz (ist mir ein wenig peinlich, aber der Rechner wurde mir gestellt, habe vorher ehrlich gesagt auch nicht darauf geachtet)
    Compiler: MSVC2019 C++17
    Flags: Bewusst habe ich keine Flags gesetzt. Ich habe über Qt ein makefile erstellt und in VS die Libraries eingebunden. Das war mein Setup. Laufen lassen tue ich das Programm im Debug Mode.

    Die CPU sollte für das bisschen ausreichen.
    Visual Studio setzt von sich aus ganz viele verschiedene Compilerflags, je nach verwendeter Konfiguration.

    Nachdem du QDebug, wie von @Mechanics vorgeschlagen, rausgenommen hast, kannst du die Konfiguration mal auf Release umstellen, kompilieren und ausführen. Das führt dazu, dass Visual Studio die Optimierungsflags setzt und ich meine auch, per Default Debugsymbole ausschaltet.

    Ich habe jetzt nicht in die Doku von qDebug geschaut, aber ich würde vermuten, dass das in der Release Konfiguration von QT aus, schon abgeschaltet wird.

    Dann ist noch interessant, wie OpenCV und QT kompiliert wurden. Da sollte man dann nämlich auch gegen die "Release" Libs linken.

    Generell gilt: Performance im Debug Build zählt nicht 😉



  • @Schlangenmensch sagte in Threads mit QtConcurrent:

    Ich habe jetzt nicht in die Doku von qDebug geschaut, aber ich würde vermuten, dass das in der Release Konfiguration von QT aus, schon abgeschaltet wird.

    Das sollte auch im Release Build funktionieren.


Log in to reply