]> git.sesse.net Git - kdenlive/blobdiff - src/widgets/videoglwidget.cpp
Add an fps counter for debugging.
[kdenlive] / src / widgets / videoglwidget.cpp
index 375f2d6b916a5a9b443ed3ab13fb8a9515219d33..83aae6376e2b024b529757af43db51f78d7c6509 100644 (file)
 #include <GL/glu.h>
 #endif
 #include "widgets/videoglwidget.h"
+extern "C" {
+GLAPI GLenum APIENTRY glClientWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout);
+}
+#include <mlt++/Mlt.h>
 
 #ifndef GL_TEXTURE_RECTANGLE_EXT
 #define GL_TEXTURE_RECTANGLE_EXT GL_TEXTURE_RECTANGLE_NV
 #endif
 
-VideoGLWidget::VideoGLWidget(QWidget *parent)
-    : QGLWidget(parent)
+VideoGLWidget::VideoGLWidget(QWidget *parent, QGLWidget *share)
+    : QGLWidget(parent, share)
     , x(0)
     , y(0)
     , w(width())
@@ -40,6 +44,8 @@ VideoGLWidget::VideoGLWidget(QWidget *parent)
     , m_image_width(0)
     , m_image_height(0)
     , m_texture(0)
+    , m_frame(NULL)
+    , m_frame_texture(0)
     , m_display_ratio(4.0 / 3.0)
     , m_backgroundColor(Qt::gray)
 {  
@@ -52,6 +58,7 @@ VideoGLWidget::~VideoGLWidget()
     makeCurrent();
     if (m_texture)
         glDeleteTextures(1, &m_texture);
+    // m_frame will be cleaned up when the profile is closed by Render.
 }
 
 QSize VideoGLWidget::minimumSizeHint() const
@@ -146,6 +153,24 @@ void VideoGLWidget::paintGL()
         glEnd();
         glDisable(GL_TEXTURE_RECTANGLE_EXT);
     }
+    if (m_frame_texture) {
+#ifdef Q_WS_MAC
+               glClear(GL_COLOR_BUFFER_BIT);
+#endif
+        glEnable(GL_TEXTURE_2D);
+        glBindTexture(GL_TEXTURE_2D, m_frame_texture);
+        glBegin(GL_QUADS);
+        glTexCoord2i(0, 0);
+        glVertex2i(x, y);
+        glTexCoord2i(1, 0);
+        glVertex2i(x + w, y);
+        glTexCoord2i(1, 1);
+        glVertex2i(x + w, y + h);
+        glTexCoord2i(0, 1);
+        glVertex2i(x, y + h);
+        glEnd();
+        glDisable(GL_TEXTURE_2D);
+    }
 }
 
 void VideoGLWidget::showImage(const QImage &image)
@@ -155,6 +180,9 @@ void VideoGLWidget::showImage(const QImage &image)
     makeCurrent();
     if (m_texture)
         glDeleteTextures(1, &m_texture);
+    delete m_frame;
+    m_frame = NULL;
+    m_frame_texture = 0;
 
     glPixelStorei(GL_UNPACK_ROW_LENGTH, m_image_width);
     glGenTextures(1, &m_texture);
@@ -166,6 +194,49 @@ void VideoGLWidget::showImage(const QImage &image)
     updateGL();
 }
 
+void VideoGLWidget::showImage(Mlt::Frame* frame, GLuint texnum)
+{
+    static bool first = true;
+    static timespec start, now;
+    static int frameno = 0;
+
+    if (first) {
+        clock_gettime(CLOCK_MONOTONIC, &start);
+        first = false;
+    }
+
+    ++frameno;
+
+    clock_gettime(CLOCK_MONOTONIC, &now);
+    double elapsed = now.tv_sec - start.tv_sec +
+        1e-9 * (now.tv_nsec - start.tv_nsec);
+    printf("%d frames in %.3f seconds = %.1f fps (%.1f ms/frame)\n",
+        frameno, elapsed, frameno / elapsed,
+        1e3 * elapsed / frameno);
+
+    // Reset every 100 frames, so that local variations in frame times
+    // (especially for the first few frames, when the shaders are
+    // compiled etc.) don't make it hard to measure for the entire
+    // remaining duration of the program.
+    if (frameno == 100) {
+        frameno = 0;
+        start = now;
+    }
+
+    makeCurrent();
+    GLsync sync = (GLsync) frame->get("movit.convert.fence");
+    glClientWaitSync(sync, 0, GL_TIMEOUT_IGNORED);
+    if (m_texture) {
+        glDeleteTextures(1, &m_texture);
+        m_texture = 0;
+    }
+    delete m_frame;
+    m_frame = frame;
+    m_frame_texture = texnum;
+
+    updateGL();
+}
+
 void VideoGLWidget::mouseDoubleClickEvent(QMouseEvent * event)
 {
     // TODO: disable screensaver?