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. QVideoProbe has bad performance under windows
QtWS25 Last Chance

QVideoProbe has bad performance under windows

Scheduled Pinned Locked Moved General and Desktop
qvideoprobewindowsvideoworkaround
8 Posts 2 Posters 4.1k Views
  • 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.
  • D Offline
    D Offline
    draekster
    wrote on 3 Apr 2015, 12:00 last edited by draekster 4 Jul 2015, 11:13
    #1

    Hello!

    I'm new to Qt (and c++...) and have a problem with my project.
    I use QMediaPlayer to play a video file. This video is shown in a QGraphicsScene. There I can see the video.

    From this video I capture a QFrame with QVideoProbe and display this frame in another QGraphicsScene.

    When I run this program under Linux all works perfekt. I see the video and the frame.
    But under Windows the performance is very bad. When I have luck I see some frames and the program does not crash. But the most time the programm chrashes after a few seconds.

    Did I something wrong?

    My System Linux:
    OS: Manjaro Linux 64bit
    Compiler: GCC
    QT: 5.4.1

    My System Windows
    OS: WIndows 7 64bit
    Compiler: msvc2012
    QT: 5.4.1

    On both systems I use QTCreator.

    mainwindow.cpp

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        player = new QMediaPlayer;
        video = new QGraphicsVideoItem;
        monitor = new QImage;
        sceneVideo = new QGraphicsScene(this);
        sceneMonitor = new QGraphicsScene(this);
        videoProbe = new QVideoProbe(this);
    
        ui->graphicsViewVideo->setScene(sceneVideo);
        ui->graphicsViewMonitor->setScene(sceneMonitor);
    
        video->setSize(QSizeF(ui->graphicsViewVideo->width(), ui->graphicsViewVideo->height()));
    
        sceneVideo->addItem(video);
        player->setVideoOutput(video);
    
        qDebug() << "Frames werden abgegriffen: " << videoProbe->setSource(player);
    
        player->setMuted(true);
        time = new QTime(0,0,0,0);
    
        connect(player, &QMediaPlayer::positionChanged, this, &MainWindow::on_positionChanged);
        connect(player, &QMediaPlayer::durationChanged, this, &MainWindow::on_durationChanged);
        connect(videoProbe, SIGNAL(videoFrameProbed(QVideoFrame)), this, SLOT(on_frameCaptured(QVideoFrame)));
    }
    
    MainWindow::~MainWindow()
    {
        delete video;
        delete monitor;
        delete player;
        delete sceneVideo;
        delete ui;
    }
    
    void MainWindow::on_actionLoadVideo_triggered()
    {
        QString filename = QFileDialog::getOpenFileName(this, tr("Öffne Video"), ".",tr("Video Dateien (*.*)"));
        if (!filename.isEmpty()){
            player->setMedia(QUrl::fromLocalFile(filename));
        }
    }
    
    void MainWindow::on_videoProgress_sliderMoved(int position)
    {
        player->setPosition(position);
        ui->videoProgress->setValue(position);
    }
    
    void MainWindow::on_pushPlayPause_clicked()
    {
        if((player->state() == QMediaPlayer::StoppedState) || (player->state() == QMediaPlayer::PausedState)){
            player->play();
        }
        else{
            player->pause();
        }
    }
    
    void MainWindow::on_pushButtonStop_clicked()
    {
        player->stop();
    }
    
    void MainWindow::on_durationChanged(int dur){
        ui->videoProgress->setMaximum(dur);
        ui->labelDuration->setText(time->addMSecs(dur).toString());
    }
    
    void MainWindow::on_positionChanged(int pos){
        ui->videoProgress->setValue(pos);
        ui->labelCurrentPosition->setText(time->addMSecs(pos).toString());
    }
    
    void MainWindow::on_frameCaptured(const QVideoFrame &frame){
        QVideoFrame f(frame);
        f.map(QAbstractVideoBuffer::ReadOnly);
    
        monitor = new QImage(f.bits(), f.width(), f.height(), QVideoFrame::imageFormatFromPixelFormat(f.pixelFormat()));
    
        sceneMonitor->clear();
        sceneMonitor->addPixmap(QPixmap::fromImage(*monitor).scaled(ui->graphicsViewVideo->width(),ui->graphicsViewVideo->height(),Qt::KeepAspectRatio));
    
        f.unmap();
    }
    
    void MainWindow::resizeEvent(QResizeEvent *) {
        video->setSize(QSizeF(ui->graphicsViewVideo->width(), ui->graphicsViewVideo->height()));
        if(!QPixmap::fromImage(*monitor).isNull()){
            sceneMonitor->clear();
            sceneMonitor->addPixmap(QPixmap::fromImage(*monitor).scaled(ui->graphicsViewVideo->width(),ui->graphicsViewVideo->height(),Qt::KeepAspectRatio));
        }
    }
    

    Workaround in Post 6.

    1 Reply Last reply
    0
    • S Offline
      S Offline
      SGaist
      Lifetime Qt Champion
      wrote on 3 Apr 2015, 21:46 last edited by
      #2

      Hi and welcome to devnet,

      The performance of the Qt Multimedia backends can vary from one platform to the other.

      One thing that is sure is that you have a memory leak in on_frameCaptured. You allocate a new QImage each time it's called but you never release it. You don't need heap allocation when dealing with QImage. It's one of Qt shared classes and it uses heap allocation internally for the data part.

      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
      • D Offline
        D Offline
        draekster
        wrote on 6 Apr 2015, 13:12 last edited by
        #3

        Thank you for your reply and it seems that I solved the memory leak. (Thank you for pointing that out.)

        But I can't believe that my player is this slow...
        Is there a way to speed this thing?

        Maybe with other codecs or so? (I've tried to install other codecs... with no improvement.)
        Or do I have to enable ffmpeg or something? (I didn't find something about it.)

        1 Reply Last reply
        0
        • S Offline
          S Offline
          SGaist
          Lifetime Qt Champion
          wrote on 6 Apr 2015, 20:48 last edited by
          #4

          What format is giving you trouble ?

          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
          • D Offline
            D Offline
            draekster
            wrote on 6 Apr 2015, 21:32 last edited by
            #5

            My testfile is MP4 from my Canon camera. But I also tried it with an example WMV file from Windows.

            1 Reply Last reply
            0
            • D Offline
              D Offline
              draekster
              wrote on 7 Apr 2015, 11:10 last edited by
              #6

              Ok I found a workaround for my problem.

              The method on_frameCaptured() starts a thread now.
              This thread do some other tasks and sleeps after that for a few milliseconds. While the thread is running the method on_frameCaptured() does nothing.

              void MainWindow::on_frameCaptured(const QVideoFrame &frame){
                   if(thread is not running){
                        do something and
                        start thread
                   }
              }
              

              Another workaround is to block the signals for the videoProbe while the method is working.

              void MainWindow::on_frameCaptured(const QVideoFrame &frame){
                   videoProbe block signals
                   do something
                   videoProbe unblock signals
              }
              

              But I think in my case the thread "solution" is the better one.

              Another realy annoying problem was the format of the QImage...
              In my case Linux use QImage::Format_RGB32.
              Windows uses QImage::Format_RGB888.
              And this with the same video file...

              So I have to convert the QImages on Windows to QImage::Format_RGB32.

              The performance under Windows is still bad but i can work with that for now.

              1 Reply Last reply
              0
              • S Offline
                S Offline
                SGaist
                Lifetime Qt Champion
                wrote on 7 Apr 2015, 23:03 last edited by
                #7

                Depending on what you need to do, shouldn't you rather use a QQueue for the frames and let the thread run as fast as it can ?

                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
                • D Offline
                  D Offline
                  draekster
                  wrote on 8 Apr 2015, 17:33 last edited by
                  #8

                  I don't need every frame.
                  But thank you for the tip I will give it a try later.

                  1 Reply Last reply
                  0

                  1/8

                  3 Apr 2015, 12:00

                  • Login

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