Browse Source

asynchronous video loading

Sonnix 6 years ago
parent
commit
9ebec4b453
7 changed files with 113 additions and 67 deletions
  1. 3 3
      callbacks_gui.cpp
  2. 64 42
      qsptextbox.cpp
  3. 2 0
      qsptextbox.h
  4. 5 5
      videoframeprocessor.cpp
  5. 2 2
      videoframeprocessor.h
  6. 28 14
      videolabel.cpp
  7. 9 1
      videolabel.h

+ 3 - 3
callbacks_gui.cpp

@@ -139,7 +139,7 @@ void QSPCallBacks::RefreshInt(QSP_BOOL isRedraw)
 	{
 		m_frame->EnableControls(false, true);
         //m_frame->Update();
-        QCoreApplication::processEvents();
+        //QCoreApplication::processEvents();
 		if (m_frame->IsQuit()) return;
 		m_frame->EnableControls(true, true);
 	}
@@ -225,7 +225,7 @@ void QSPCallBacks::Sleep(int msecs)
 	{
         QThread::msleep(50);
         //m_frame->Update();
-        QCoreApplication::processEvents();
+        //QCoreApplication::processEvents();
 		if (m_frame->IsQuit() ||
             m_frame->IsKeyPressedWhileDisabled()) //TODO: implement
 		{
@@ -237,7 +237,7 @@ void QSPCallBacks::Sleep(int msecs)
 	{
         QThread::msleep(msecs % 50);
         //m_frame->Update();
-        QCoreApplication::processEvents();
+        //QCoreApplication::processEvents();
 	}
 	m_frame->EnableControls(true, true);
     m_frame->GetGameMenu()->setEnabled(isSave);

+ 64 - 42
qsptextbox.cpp

@@ -298,22 +298,14 @@ QVariant QspTextBox::loadResource(int type, const QUrl &name)
         if(!disableVideo)
         {
             VideoLabel *videoL = new VideoLabel(m_path, new_name, this);
-            if(!videoL->videoError())
-            {
-                animations_video.insert(QString(QByteArray::fromPercentEncoding(name.toString().toUtf8())), { videoL });
-                videoL->setGeometry(0,0, videoL->getResolution().width(), videoL->getResolution().height());
-                videoL->raise();
-                videoL->show();
-                QImage image(videoL->getResolution(), QImage::Format_ARGB32);
-                image.fill(qRgba(0,0,0,0));
-
-                return QVariant(image);
-            }
-            else
-            {
-                if(videoL != 0)
-                    delete videoL;
-            }
+            connect(videoL, SIGNAL(medialLoaded()), this, SLOT(resizeAnimations()));
+            animations_video.insert(QString(QByteArray::fromPercentEncoding(name.toString().toUtf8())), { videoL });
+            videoL->setGeometry(0,0, 0, 0);
+            videoL->raise();
+            videoL->show();
+            QImage image(1,1, QImage::Format_ARGB32);
+            image.fill(qRgba(0,0,0,0));
+            return QVariant(image);
         }
         QImage image(1,1, QImage::Format_ARGB32);
         image.fill(qRgba(0,0,0,0));
@@ -339,44 +331,74 @@ void QspTextBox::keyPressEvent(QKeyEvent *event)
 
 void QspTextBox::resizeAnimations()
 {
-    if(animations_gif.count() > 0 || animations_video.count() > 0)
+    if(mutex.tryLock())
     {
-        QTextBlock bl = document()->begin();
-        QTextCursor cursor(document());
-        while(bl.isValid())
+        if(animations_gif.count() > 0 || animations_video.count() > 0)
         {
-            QTextBlock::iterator it;
-            for(it = bl.begin(); !(it.atEnd()); ++it)
+            QTextBlock bl = document()->begin();
+            QTextCursor cursor(document());
+            while(bl.isValid())
             {
-                if(it.fragment().isValid())
+                QTextBlock::iterator it;
+                for(it = bl.begin(); !(it.atEnd()); ++it)
                 {
-                    if(it.fragment().charFormat().isImageFormat())
+                    if(it.fragment().isValid())
                     {
-                        cursor.setPosition(it.fragment().position());
-                        if (animations_gif.contains(it.fragment().charFormat().toImageFormat().name()))
-                        {
-                            QRect curRect = cursorRect(cursor);
-                            if(it.fragment().charFormat().toImageFormat().width() > 0 && it.fragment().charFormat().toImageFormat().height() > 0)
-                                animations_gif[it.fragment().charFormat().toImageFormat().name()].movieLabel->setGeometry(curRect.x(),curRect.y(),it.fragment().charFormat().toImageFormat().width(),it.fragment().charFormat().toImageFormat().height());
-                            else
-                                animations_gif[it.fragment().charFormat().toImageFormat().name()].movieLabel->move(curRect.x(),curRect.y());
-                        }
-                        else
-                        if (animations_video.contains(it.fragment().charFormat().toImageFormat().name()))
+                        if(it.fragment().charFormat().isImageFormat())
                         {
-                            QRect curRect = cursorRect(cursor);
-                            if(it.fragment().charFormat().toImageFormat().width() > 0 && it.fragment().charFormat().toImageFormat().height() > 0)
-                                animations_video[it.fragment().charFormat().toImageFormat().name()].videoLabel->setGeometry(curRect.x(),curRect.y(),it.fragment().charFormat().toImageFormat().width(),it.fragment().charFormat().toImageFormat().height());
+                            cursor.setPosition(it.fragment().position());
+                            if (animations_gif.contains(it.fragment().charFormat().toImageFormat().name()))
+                            {
+                                QRect curRect = cursorRect(cursor);
+                                if(it.fragment().charFormat().toImageFormat().width() > 0 && it.fragment().charFormat().toImageFormat().height() > 0)
+                                    animations_gif[it.fragment().charFormat().toImageFormat().name()].movieLabel->setGeometry(curRect.x(),curRect.y(),it.fragment().charFormat().toImageFormat().width(),it.fragment().charFormat().toImageFormat().height());
+                                else
+                                    animations_gif[it.fragment().charFormat().toImageFormat().name()].movieLabel->move(curRect.x(),curRect.y());
+                            }
                             else
-                                animations_video[it.fragment().charFormat().toImageFormat().name()].videoLabel->move(curRect.x(),curRect.y());
+                            if (animations_video.contains(it.fragment().charFormat().toImageFormat().name()))
+                            {
+                                if(animations_video[it.fragment().charFormat().toImageFormat().name()].videoLabel != 0)
+                                {
+                                    if(animations_video[it.fragment().charFormat().toImageFormat().name()].videoLabel->hasFrame())
+                                    {
+                                        QRect curRect = cursorRect(cursor);
+                                        if(it.fragment().charFormat().toImageFormat().width() > 0 && it.fragment().charFormat().toImageFormat().height() > 0)
+                                            animations_video[it.fragment().charFormat().toImageFormat().name()].videoLabel->setGeometry(curRect.x(),curRect.y(),it.fragment().charFormat().toImageFormat().width(),it.fragment().charFormat().toImageFormat().height());
+                                        else
+                                        {
+                                            animations_video[it.fragment().charFormat().toImageFormat().name()].videoLabel->move(curRect.x(),curRect.y());
+                                            if(!animations_video[it.fragment().charFormat().toImageFormat().name()].videoLabel->resolution_set)
+                                            {
+                                                QTextImageFormat newImageFormat = it.fragment().charFormat().toImageFormat();
+                                                newImageFormat.setWidth(animations_video[it.fragment().charFormat().toImageFormat().name()].videoLabel->getResolution().width());
+                                                newImageFormat.setHeight(animations_video[it.fragment().charFormat().toImageFormat().name()].videoLabel->getResolution().height());
+                                                if (newImageFormat.isValid())
+                                                {
+                                                    QTextCursor cur(document());
+                                                    cur.setPosition(it.fragment().position());
+                                                    cur.setPosition(it.fragment().position() + it.fragment().length(), QTextCursor::KeepAnchor);
+                                                    cur.setCharFormat(newImageFormat);
+                                                    cur.setPosition(it.fragment().position());
+                                                    curRect = cursorRect(cur);
+                                                }
+                                                animations_video[it.fragment().charFormat().toImageFormat().name()].videoLabel->setGeometry(curRect.x(),curRect.y(), animations_video[it.fragment().charFormat().toImageFormat().name()].videoLabel->getResolution().width(), animations_video[it.fragment().charFormat().toImageFormat().name()].videoLabel->getResolution().height());
+                                                animations_video[it.fragment().charFormat().toImageFormat().name()].videoLabel->resolution_set = true;
+                                            }
+                                        }
+
+                                    }
+                                }
+                            }
+                            //QVariant image_data=document()->resource(QTextDocument::ImageResource, QUrl(image_name));
+                            //QImage picture=image_data.value<QImage>();
                         }
-                        //QVariant image_data=document()->resource(QTextDocument::ImageResource, QUrl(image_name));
-                        //QImage picture=image_data.value<QImage>();
                     }
                 }
+                bl = bl.next();
             }
-            bl = bl.next();
         }
+        mutex.unlock();
     }
 }
 

+ 2 - 0
qsptextbox.h

@@ -13,6 +13,7 @@
 #include <QLabel>
 #include <QMap>
 #include <QKeyEvent>
+#include <QMutex>
 
 #include "videolabel.h"
 
@@ -87,6 +88,7 @@ private:
     bool disableVideo;
     QMap<QString, animation_gif> animations_gif;
     QMap<QString, animation_video> animations_video;
+    QMutex mutex;
 
 private slots:
     void repaintAnimation();

+ 5 - 5
videoframeprocessor.cpp

@@ -7,9 +7,9 @@
 VideoFrameProcessor::VideoFrameProcessor(QObject *parent) : QAbstractVideoSurface(parent)
 {
     hasFrame = false;
-    timer.setSingleShot(true);
-    connect(&timer, SIGNAL(timeout()), this, SLOT(OnFrameTimeout()));
-    timer.start(10000);
+//    timer.setSingleShot(true);
+//    connect(&timer, SIGNAL(timeout()), this, SLOT(OnFrameTimeout()));
+//    timer.start(10000);
 }
 
 VideoFrameProcessor::~VideoFrameProcessor()
@@ -33,8 +33,8 @@ bool VideoFrameProcessor::present(const QVideoFrame &frame)
 //                        QVideoFrame::imageFormatFromPixelFormat(videoFrame.pixelFormat()));
             if(!hasFrame)
             {
-                disconnect(&timer, SIGNAL(timeout()), this, SLOT(OnFrameTimeout()));
-                timer.stop();
+                //disconnect(&timer, SIGNAL(timeout()), this, SLOT(OnFrameTimeout()));
+                //timer.stop();
                 mediaResolution = videoFrame.size();
                 hasFrame = true;
             }

+ 2 - 2
videoframeprocessor.h

@@ -9,7 +9,7 @@
 #include <QSize>
 #include <QImage>
 #include <QString>
-#include <QTimer>
+//#include <QTimer>
 
 class VideoFrameProcessor : public QAbstractVideoSurface
 {
@@ -28,7 +28,7 @@ public:
     //QImage curFrame;
     QSize mediaResolution;
     bool hasFrame;
-    QTimer timer;
+//    QTimer timer;
 private:
 
 private slots:

+ 28 - 14
videolabel.cpp

@@ -1,7 +1,7 @@
 #include "videolabel.h"
 
 #include <QUrl>
-#include <QCoreApplication>
+//#include <QCoreApplication>
 //#include <QThread>
 
 VideoLabel::VideoLabel(QString path, QString filename, QWidget *parent) : QLabel(parent)
@@ -11,27 +11,24 @@ VideoLabel::VideoLabel(QString path, QString filename, QWidget *parent) : QLabel
     setScaledContents(true);
     setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
     setAttribute(Qt::WA_TransparentForMouseEvents);
+    resolution_set = false;
+    m_medialLoaded = false;
 
     playlist.setPlaybackMode(QMediaPlaylist::PlaybackMode::Loop);
     playlist.addMedia(QUrl::fromLocalFile(m_path + m_filename));
     mediaPlayer.setPlaylist(&playlist);
     mediaPlayer.setVideoOutput(&vfp);
     mediaPlayer.play();
-    while(!vfp.hasFrame && mediaPlayer.error() != QMediaPlayer::InvalidMedia && vfp.error() == QAbstractVideoSurface::NoError)
-    {
-        QCoreApplication::processEvents();
-        //QThread::msleep(4);
-    }
+//    while(!vfp.hasFrame && mediaPlayer.error() != QMediaPlayer::InvalidMedia && vfp.error() == QAbstractVideoSurface::NoError)
+//    {
+//        QCoreApplication::processEvents();
+//        //QThread::msleep(4);
+//    }
 
-    if(mediaPlayer.error() != QMediaPlayer::InvalidMedia && vfp.error() == QAbstractVideoSurface::NoError)
-    {
+//    if(mediaPlayer.error() != QMediaPlayer::InvalidMedia && vfp.error() == QAbstractVideoSurface::NoError)
+//    {
         connect(&vfp, SIGNAL(newFrame(QImage)), this, SLOT(OnNewFrame(QImage)));
         m_videoError = false;
-    }
-    else
-    {
-        m_videoError = false;
-    }
 }
 
 VideoLabel::~VideoLabel()
@@ -39,7 +36,24 @@ VideoLabel::~VideoLabel()
 
 }
 
+bool VideoLabel::videoError()
+{
+    if(mediaPlayer.error() != QMediaPlayer::FormatError && vfp.error() == QAbstractVideoSurface::NoError)
+        return false;
+    else
+        return true;
+}
+
 void VideoLabel::OnNewFrame(QImage newVideoFrame)
 {
-    setPixmap(QPixmap::fromImage(newVideoFrame));
+    if(mutex.tryLock())
+    {
+        setPixmap(QPixmap::fromImage(newVideoFrame));
+        if(!m_medialLoaded)
+        {
+            m_medialLoaded = true;
+            emit medialLoaded();
+        }
+        mutex.unlock();
+    }
 }

+ 9 - 1
videolabel.h

@@ -8,6 +8,7 @@
 #include <QMediaPlayer>
 #include <QMediaPlaylist>
 #include <QSize>
+#include <QMutex>
 
 #include "videoframeprocessor.h"
 
@@ -15,11 +16,16 @@ class VideoLabel : public QLabel
 {
     Q_OBJECT
 
+signals:
+    void medialLoaded();
+
 public:
     explicit VideoLabel(QString path, QString filename, QWidget *parent = 0);
     ~VideoLabel();
-    bool videoError() { return m_videoError; }
+    bool videoError();
     QSize getResolution() { return vfp.mediaResolution; }
+    bool hasFrame() { return m_medialLoaded; }
+    bool resolution_set;
 
 private:
     QString m_path;
@@ -28,6 +34,8 @@ private:
     QMediaPlayer mediaPlayer;
     QMediaPlaylist playlist;
     bool m_videoError;
+    bool m_medialLoaded;
+    QMutex mutex;
 
 private slots:
     void OnNewFrame(QImage newVideoFrame);