When rendering into a texture on one thread and rendering _from_ it on another,
we need to properly synchronize the client state. Hook onto the OpenGL fences
that MLT set to properly wait for the rendering commands to be sent to the GPU,
which fixes the jittering we'd otherwise see, due to rendering old frames still
left in the textures because the new ones are not ready yet.
m_glWidget->setImageAspectRatio(render->dar());
m_glWidget->setBackgroundColor(KdenliveSettings::window_background());
connect(render, SIGNAL(showImageSignal(QImage)), m_glWidget, SLOT(showImage(QImage)));
m_glWidget->setImageAspectRatio(render->dar());
m_glWidget->setBackgroundColor(KdenliveSettings::window_background());
connect(render, SIGNAL(showImageSignal(QImage)), m_glWidget, SLOT(showImage(QImage)));
- connect(render, SIGNAL(showImageSignal(GLuint)), m_glWidget, SLOT(showImage(GLuint)));
+ connect(render, SIGNAL(showImageSignal(Mlt::Frame*, GLuint)), m_glWidget, SLOT(showImage(Mlt::Frame*, GLuint)));
}
void Monitor::setupMenu(QMenu *goMenu, QAction *playZone, QAction *loopZone, QMenu *markerMenu, QAction *loopClip)
}
void Monitor::setupMenu(QMenu *goMenu, QAction *playZone, QAction *loopZone, QMenu *markerMenu, QAction *loopClip)
* *
***************************************************************************/
* *
***************************************************************************/
#include "renderer.h"
#include "kdenlivesettings.h"
#include "kthumb.h"
#include "renderer.h"
#include "kdenlivesettings.h"
#include "kthumb.h"
const uint8_t* image = frame->get_image(format, width, height);
const GLuint* texnum = (GLuint *)image;
if (format == mlt_image_glsl_texture) {
const uint8_t* image = frame->get_image(format, width, height);
const GLuint* texnum = (GLuint *)image;
if (format == mlt_image_glsl_texture) {
- emit showImageSignal(*texnum);
- delete frame;
+ emit showImageSignal(frame, *texnum);
} else {
QImage qimage(width, height, QImage::Format_ARGB32_Premultiplied);
memcpy(qimage.scanLine(0), image, width * height * 4);
} else {
QImage qimage(width, height, QImage::Format_ARGB32_Premultiplied);
memcpy(qimage.scanLine(0), image, width * height * 4);
#include "definitions.h"
#include "widgets/abstractmonitor.h"
#include "definitions.h"
#include "widgets/abstractmonitor.h"
#include <mlt/framework/mlt_types.h>
#include <kurl.h>
#include <mlt/framework/mlt_types.h>
#include <kurl.h>
*
* Used in Mac OS X. */
void showImageSignal(QImage);
*
* Used in Mac OS X. */
void showImageSignal(QImage);
- void showImageSignal(GLuint);
+ void showImageSignal(Mlt::Frame*, GLuint);
void showAudioSignal(const QVector<double> &);
void addClip(const KUrl &, stringMap);
void checkSeeking();
void showAudioSignal(const QVector<double> &);
void addClip(const KUrl &, stringMap);
void checkSeeking();
#include <GL/glu.h>
#endif
#include "widgets/videoglwidget.h"
#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
#ifndef GL_TEXTURE_RECTANGLE_EXT
#define GL_TEXTURE_RECTANGLE_EXT GL_TEXTURE_RECTANGLE_NV
, m_image_width(0)
, m_image_height(0)
, m_texture(0)
, 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)
{
, m_display_ratio(4.0 / 3.0)
, m_backgroundColor(Qt::gray)
{
makeCurrent();
if (m_texture)
glDeleteTextures(1, &m_texture);
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
}
QSize VideoGLWidget::minimumSizeHint() const
glEnd();
glDisable(GL_TEXTURE_RECTANGLE_EXT);
}
glEnd();
glDisable(GL_TEXTURE_RECTANGLE_EXT);
}
#ifdef Q_WS_MAC
glClear(GL_COLOR_BUFFER_BIT);
#endif
glEnable(GL_TEXTURE_2D);
#ifdef Q_WS_MAC
glClear(GL_COLOR_BUFFER_BIT);
#endif
glEnable(GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D, m_other_texture);
+ glBindTexture(GL_TEXTURE_2D, m_frame_texture);
glBegin(GL_QUADS);
glTexCoord2i(0, 0);
glVertex2i(x, y);
glBegin(GL_QUADS);
glTexCoord2i(0, 0);
glVertex2i(x, y);
makeCurrent();
if (m_texture)
glDeleteTextures(1, &m_texture);
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);
glPixelStorei(GL_UNPACK_ROW_LENGTH, m_image_width);
glGenTextures(1, &m_texture);
-void VideoGLWidget::showImage(GLuint texnum)
+void VideoGLWidget::showImage(Mlt::Frame* frame, GLuint texnum)
+ GLsync sync = (GLsync) frame->get("movit.convert.fence");
+ glClientWaitSync(sync, 0, GL_TIMEOUT_IGNORED);
if (m_texture) {
glDeleteTextures(1, &m_texture);
m_texture = 0;
}
if (m_texture) {
glDeleteTextures(1, &m_texture);
m_texture = 0;
}
- m_other_texture = texnum;
+ delete m_frame;
+ m_frame = frame;
+ m_frame_texture = texnum;
+namespace Mlt {
+class Frame;
+}
+
class VideoGLWidget : public QGLWidget
{
Q_OBJECT
class VideoGLWidget : public QGLWidget
{
Q_OBJECT
public slots:
void showImage(const QImage &image);
public slots:
void showImage(const QImage &image);
- void showImage(GLuint);
+ void showImage(Mlt::Frame*, GLuint);
protected:
void initializeGL();
protected:
void initializeGL();
private:
int x, y, w, h;
int m_image_width, m_image_height;
private:
int x, y, w, h;
int m_image_width, m_image_height;
- GLuint m_texture, m_other_texture;
+ GLuint m_texture;
+ Mlt::Frame *m_frame;
+ GLuint m_frame_texture;
double m_display_ratio;
QColor m_backgroundColor;
Qt::WindowFlags m_baseFlags;
double m_display_ratio;
QColor m_backgroundColor;
Qt::WindowFlags m_baseFlags;