mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-27 02:30:35 +00:00
examples: port GL/Qt examples to Qt5
Update the GL Qt integration examples for Qt5 changes and for GstGL signal signature changes.
This commit is contained in:
parent
ca476f03a8
commit
491513adf6
16 changed files with 110 additions and 139 deletions
2
tests/examples/gl/qt/.gitignore
vendored
Normal file
2
tests/examples/gl/qt/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
GeneratedFiles/
|
||||||
|
debug/
|
|
@ -1,22 +1,23 @@
|
||||||
--- Description of the Qt examples ---
|
--- Description of the Qt examples ---
|
||||||
|
|
||||||
|
- videooverlay:
|
||||||
|
Show how to use the videooverlay interface through Qt.
|
||||||
|
The video is displayed as normal 2D scene.
|
||||||
|
The window is dynamically resized to have the same size as the original video.
|
||||||
|
|
||||||
- mousevideooverlay:
|
- mousevideooverlay:
|
||||||
Show how to use the videooverlay interface through Qt.
|
Show how to use the videooverlay interface through Qt.
|
||||||
The cube is rotating when moving the mouse (+ click maintained)
|
The cube is rotating when moving the mouse (+ click maintained)
|
||||||
|
|
||||||
- qglvideooverlay:
|
- qglwidgetvideooverlay:
|
||||||
Show how to use the videooverlay interface through Qt.
|
Show how to use the videooverlay interface through Qt.
|
||||||
The cube is rotating automatically into a QGLWidget
|
The cube is rotating automatically into a QGLWidget
|
||||||
|
|
||||||
- videovdieooverlay:
|
|
||||||
Show how to use the videooverlay interface through Qt.
|
|
||||||
The video is displayed as normal 2D scene.
|
|
||||||
The window is dynamically resized to have the same size as the original video.
|
|
||||||
|
|
||||||
--- How to build the Qt examples ---
|
--- How to build the Qt examples ---
|
||||||
|
|
||||||
sudo apt-get install g++
|
sudo apt-get install g++ libqt5-dev
|
||||||
sudo apt-get install libqt4-dev
|
|
||||||
cd qglvideooverlay
|
cd qglvideooverlay
|
||||||
qmake
|
qmake
|
||||||
make
|
make
|
||||||
|
|
|
@ -18,7 +18,8 @@
|
||||||
* Boston, MA 02110-1301, USA.
|
* Boston, MA 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <QGuiApplication>
|
#include <QtGui/QApplication>
|
||||||
|
#include <QtGui/QFileDialog>
|
||||||
#include "qrenderer.h"
|
#include "qrenderer.h"
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
|
@ -26,13 +27,13 @@ int main(int argc, char *argv[])
|
||||||
QApplication a(argc, argv);
|
QApplication a(argc, argv);
|
||||||
a.connect(&a, SIGNAL(lastWindowClosed()), &a, SLOT(quit()));
|
a.connect(&a, SIGNAL(lastWindowClosed()), &a, SLOT(quit()));
|
||||||
|
|
||||||
QString videolcoation = QFileDialog::getOpenFileName(0, "Select a video file",
|
QString videolocation = QFileDialog::getOpenFileName(0, "Select a video file",
|
||||||
".", "Format (*.avi *.mkv *.ogg *.asf *.mov)");
|
".", "Format (*.avi *.mkv *.ogg *.asf *.mov)");
|
||||||
|
|
||||||
if (videolcoation.isEmpty())
|
if (videolocation.isEmpty())
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
QRenderer w(videolcoation);
|
QRenderer w(videolocation);
|
||||||
w.setWindowTitle("glimagesink implements the gstvideooverlay interface");
|
w.setWindowTitle("glimagesink implements the gstvideooverlay interface");
|
||||||
|
|
||||||
return a.exec();
|
return a.exec();
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
TEMPLATE = app
|
TEMPLATE = app
|
||||||
TARGET = mousevideooverlay
|
TARGET = mousevideooverlay
|
||||||
DESTDIR = ./debug
|
DESTDIR = ./debug
|
||||||
CONFIG += debug gui widget
|
QT += gui widgets opengl
|
||||||
DEFINES += UNICODE
|
CONFIG += debug link_pkgconfig compile_libtool
|
||||||
|
DEFINES += UNICODE QT_THREAD_SUPPORT QT_CORE_LIB QT_GUI_LIB
|
||||||
|
PKGCONFIG = gstreamer-1.0 gstreamer-video-1.0
|
||||||
|
|
||||||
win32 {
|
win32 {
|
||||||
DEFINES += WIN32
|
DEFINES += WIN32
|
||||||
|
@ -28,20 +30,8 @@ LIBS += -L"C:/gstreamer/lib" \
|
||||||
unix {
|
unix {
|
||||||
DEFINES += UNIX
|
DEFINES += UNIX
|
||||||
INCLUDEPATH += GeneratedFiles \
|
INCLUDEPATH += GeneratedFiles \
|
||||||
GeneratedFiles/Debug \
|
GeneratedFiles/Debug
|
||||||
/usr/include/gstreamer-1.0 \
|
LIBS += -lGLU -lGL
|
||||||
/usr/local/include/gstreamer-1.0 \
|
|
||||||
/usr/include/glib-2.0 \
|
|
||||||
/usr/lib/glib-2.0/include \
|
|
||||||
/usr/include/libxml2
|
|
||||||
LIBS += -lgstreamer-video \
|
|
||||||
-lgstvideo-1.0 \
|
|
||||||
-lglib-2.0 \
|
|
||||||
-lgmodule-2.0 \
|
|
||||||
-lgobject-2.0 \
|
|
||||||
-lgthread-2.0 \
|
|
||||||
-lGLU \
|
|
||||||
-lGL
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DEPENDPATH += .
|
DEPENDPATH += .
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
#include <gst/video/videooverlay.h>
|
#include <gst/video/videooverlay.h>
|
||||||
#include <GL/gl.h>
|
#include <GL/gl.h>
|
||||||
|
#include <GL/glu.h>
|
||||||
#include "pipeline.h"
|
#include "pipeline.h"
|
||||||
|
|
||||||
Pipeline::Pipeline(const WId id, const QString videoLocation):
|
Pipeline::Pipeline(const WId id, const QString videoLocation):
|
||||||
|
@ -39,7 +40,7 @@ Pipeline::~Pipeline()
|
||||||
|
|
||||||
void Pipeline::create()
|
void Pipeline::create()
|
||||||
{
|
{
|
||||||
qDebug("Loading video: %s", m_videoLocation.toAscii().data());
|
qDebug("Loading video: %s", m_videoLocation.toLatin1().data());
|
||||||
|
|
||||||
gst_init (NULL, NULL);
|
gst_init (NULL, NULL);
|
||||||
|
|
||||||
|
@ -50,7 +51,7 @@ void Pipeline::create()
|
||||||
|
|
||||||
m_bus = gst_pipeline_get_bus (GST_PIPELINE (m_pipeline));
|
m_bus = gst_pipeline_get_bus (GST_PIPELINE (m_pipeline));
|
||||||
gst_bus_add_watch (m_bus, (GstBusFunc) bus_call, this);
|
gst_bus_add_watch (m_bus, (GstBusFunc) bus_call, this);
|
||||||
gst_bus_set_sync_handler (m_bus, (GstBusSyncHandler) create_window, this);
|
gst_bus_set_sync_handler (m_bus, (GstBusSyncHandler) create_window, this, NULL);
|
||||||
gst_object_unref (m_bus);
|
gst_object_unref (m_bus);
|
||||||
|
|
||||||
GstElement* videosrc = gst_element_factory_make ("filesrc", "filesrc0");
|
GstElement* videosrc = gst_element_factory_make ("filesrc", "filesrc0");
|
||||||
|
@ -64,7 +65,7 @@ void Pipeline::create()
|
||||||
}
|
}
|
||||||
|
|
||||||
g_object_set(G_OBJECT(videosrc), "num-buffers", 800, NULL);
|
g_object_set(G_OBJECT(videosrc), "num-buffers", 800, NULL);
|
||||||
g_object_set(G_OBJECT(videosrc), "location", m_videoLocation.toAscii().data(), NULL);
|
g_object_set(G_OBJECT(videosrc), "location", m_videoLocation.toLatin1().data(), NULL);
|
||||||
g_signal_connect(G_OBJECT(m_glimagesink), "client-reshape", G_CALLBACK (reshapeCallback), NULL);
|
g_signal_connect(G_OBJECT(m_glimagesink), "client-reshape", G_CALLBACK (reshapeCallback), NULL);
|
||||||
g_signal_connect(G_OBJECT(m_glimagesink), "client-draw", G_CALLBACK (drawCallback), NULL);
|
g_signal_connect(G_OBJECT(m_glimagesink), "client-draw", G_CALLBACK (drawCallback), NULL);
|
||||||
|
|
||||||
|
@ -72,7 +73,7 @@ void Pipeline::create()
|
||||||
|
|
||||||
gst_element_link_pads (videosrc, "src", decodebin, "sink");
|
gst_element_link_pads (videosrc, "src", decodebin, "sink");
|
||||||
|
|
||||||
g_signal_connect (decodebin, "new-decoded-pad", G_CALLBACK (cb_new_pad), this);
|
g_signal_connect (decodebin, "pad-added", G_CALLBACK (cb_new_pad), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pipeline::start()
|
void Pipeline::start()
|
||||||
|
@ -159,7 +160,7 @@ float Pipeline::m_yrot = 0;
|
||||||
float Pipeline::m_zrot = 0;
|
float Pipeline::m_zrot = 0;
|
||||||
|
|
||||||
//client reshape callback
|
//client reshape callback
|
||||||
gboolean Pipeline::reshapeCallback (void *sink, guint width, guint height, gpointer data)
|
gboolean Pipeline::reshapeCallback (void *sink, void *context, guint width, guint height, gpointer data)
|
||||||
{
|
{
|
||||||
glViewport(0, 0, width, height);
|
glViewport(0, 0, width, height);
|
||||||
glMatrixMode(GL_PROJECTION);
|
glMatrixMode(GL_PROJECTION);
|
||||||
|
@ -171,7 +172,7 @@ gboolean Pipeline::reshapeCallback (void *sink, guint width, guint height, gpoin
|
||||||
}
|
}
|
||||||
|
|
||||||
//client draw callback
|
//client draw callback
|
||||||
gboolean Pipeline::drawCallback (void *sink, uint texture, uint width, uint height, gpointer data)
|
gboolean Pipeline::drawCallback (void *sink, void *context, uint texture, uint width, uint height, gpointer data)
|
||||||
{
|
{
|
||||||
static GTimeVal current_time;
|
static GTimeVal current_time;
|
||||||
static glong last_sec = current_time.tv_sec;
|
static glong last_sec = current_time.tv_sec;
|
||||||
|
@ -182,7 +183,7 @@ gboolean Pipeline::drawCallback (void *sink, uint texture, uint width, uint heig
|
||||||
|
|
||||||
if ((current_time.tv_sec - last_sec) >= 1)
|
if ((current_time.tv_sec - last_sec) >= 1)
|
||||||
{
|
{
|
||||||
qDebug ("GRPHIC FPS = %d", nbFrames);
|
qDebug ("GRAPHIC FPS = %d", nbFrames);
|
||||||
nbFrames = 0;
|
nbFrames = 0;
|
||||||
last_sec = current_time.tv_sec;
|
last_sec = current_time.tv_sec;
|
||||||
}
|
}
|
||||||
|
@ -209,39 +210,39 @@ gboolean Pipeline::drawCallback (void *sink, uint texture, uint width, uint heig
|
||||||
|
|
||||||
glBegin(GL_QUADS);
|
glBegin(GL_QUADS);
|
||||||
// Front Face
|
// Front Face
|
||||||
glTexCoord2f((gfloat)width, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
|
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
|
||||||
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
|
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
|
||||||
glTexCoord2f(0.0f, (gfloat)height); glVertex3f( 1.0f, 1.0f, 1.0f);
|
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
|
||||||
glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f(-1.0f, 1.0f, 1.0f);
|
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
|
||||||
// Back Face
|
// Back Face
|
||||||
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
|
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
|
||||||
glTexCoord2f(0.0f, (gfloat)height); glVertex3f(-1.0f, 1.0f, -1.0f);
|
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
|
||||||
glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f( 1.0f, 1.0f, -1.0f);
|
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
|
||||||
glTexCoord2f((gfloat)width, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
|
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
|
||||||
// Top Face
|
// Top Face
|
||||||
glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f(-1.0f, 1.0f, -1.0f);
|
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
|
||||||
glTexCoord2f((gfloat)width, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
|
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
|
||||||
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
|
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
|
||||||
glTexCoord2f(0.0f, (gfloat)height); glVertex3f( 1.0f, 1.0f, -1.0f);
|
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
|
||||||
// Bottom Face
|
// Bottom Face
|
||||||
glTexCoord2f((gfloat)width, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
|
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
|
||||||
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
|
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
|
||||||
glTexCoord2f(0.0f, (gfloat)height); glVertex3f( 1.0f, -1.0f, 1.0f);
|
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
|
||||||
glTexCoord2f((gfloat)width,(gfloat)height); glVertex3f(-1.0f, -1.0f, 1.0f);
|
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
|
||||||
// Right face
|
// Right face
|
||||||
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
|
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
|
||||||
glTexCoord2f(0.0f, (gfloat)height); glVertex3f( 1.0f, 1.0f, -1.0f);
|
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
|
||||||
glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f( 1.0f, 1.0f, 1.0f);
|
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
|
||||||
glTexCoord2f((gfloat)width, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
|
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
|
||||||
// Left Face
|
// Left Face
|
||||||
glTexCoord2f((gfloat)width, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
|
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
|
||||||
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
|
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
|
||||||
glTexCoord2f(0.0f, (gfloat)height); glVertex3f(-1.0f, 1.0f, 1.0f);
|
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
|
||||||
glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f(-1.0f, 1.0f, -1.0f);
|
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
|
||||||
glEnd();
|
glEnd();
|
||||||
|
|
||||||
//return TRUE causes a postRedisplay
|
//return TRUE causes a postRedisplay
|
||||||
return FALSE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean Pipeline::bus_call (GstBus *bus, GstMessage *msg, Pipeline* p)
|
gboolean Pipeline::bus_call (GstBus *bus, GstMessage *msg, Pipeline* p)
|
||||||
|
@ -274,10 +275,10 @@ gboolean Pipeline::bus_call (GstBus *bus, GstMessage *msg, Pipeline* p)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pipeline::cb_new_pad (GstElement* decodebin, GstPad* pad, gboolean last, Pipeline* p)
|
void Pipeline::cb_new_pad (GstElement* decodebin, GstPad* pad, Pipeline* p)
|
||||||
{
|
{
|
||||||
GstElement* glimagesink = p->getVideoSink();
|
GstElement* glimagesink = p->getVideoSink();
|
||||||
GstPad* glpad = gst_element_get_pad (glimagesink, "sink");
|
GstPad* glpad = gst_element_get_static_pad (glimagesink, "sink");
|
||||||
|
|
||||||
//only link once
|
//only link once
|
||||||
if (GST_PAD_IS_LINKED (glpad))
|
if (GST_PAD_IS_LINKED (glpad))
|
||||||
|
@ -286,7 +287,7 @@ void Pipeline::cb_new_pad (GstElement* decodebin, GstPad* pad, gboolean last, Pi
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
GstCaps* caps = gst_pad_get_caps (pad);
|
GstCaps* caps = gst_pad_get_current_caps (pad);
|
||||||
GstStructure* str = gst_caps_get_structure (caps, 0);
|
GstStructure* str = gst_caps_get_structure (caps, 0);
|
||||||
if (!g_strrstr (gst_structure_get_name (str), "video"))
|
if (!g_strrstr (gst_structure_get_name (str), "video"))
|
||||||
{
|
{
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#define PIPELINE_H
|
#define PIPELINE_H
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include <QtGui>
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
//#include <QtCore/private/qeventdispatcher_glib_p.h>
|
//#include <QtCore/private/qeventdispatcher_glib_p.h>
|
||||||
|
|
||||||
|
@ -60,10 +61,10 @@ private:
|
||||||
void doExpose() const;
|
void doExpose() const;
|
||||||
void doRotate();
|
void doRotate();
|
||||||
|
|
||||||
static gboolean reshapeCallback (void *sink, guint width, guint height, gpointer data);
|
static gboolean reshapeCallback (void *sink, void *context, guint width, guint height, gpointer data);
|
||||||
static gboolean drawCallback (void *sink, guint texture, guint width, guint height, gpointer data);
|
static gboolean drawCallback (void *sink, void *context, guint texture, guint width, guint height, gpointer data);
|
||||||
static gboolean bus_call (GstBus *bus, GstMessage *msg, Pipeline* p);
|
static gboolean bus_call (GstBus *bus, GstMessage *msg, Pipeline* p);
|
||||||
static void cb_new_pad (GstElement* decodebin, GstPad* pad, gboolean last, Pipeline* p);
|
static void cb_new_pad (GstElement* decodebin, GstPad* pad, Pipeline* p);
|
||||||
static gboolean cb_expose (gpointer data);
|
static gboolean cb_expose (gpointer data);
|
||||||
static gboolean cb_rotate (gpointer data);
|
static gboolean cb_rotate (gpointer data);
|
||||||
static GstBusSyncReply create_window (GstBus* bus, GstMessage* message, const Pipeline* pipeline);
|
static GstBusSyncReply create_window (GstBus* bus, GstMessage* message, const Pipeline* pipeline);
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
|
|
||||||
#include "qrenderer.h"
|
#include "qrenderer.h"
|
||||||
|
|
||||||
QRenderer::QRenderer(const QString videoLocation, QWidget *parent, Qt::WFlags flags)
|
QRenderer::QRenderer(const QString videoLocation, QWidget *parent, Qt::WindowFlags flags)
|
||||||
: QWidget(parent, flags),
|
: QWidget(parent, flags),
|
||||||
m_gt(winId(), videoLocation)
|
m_gt(winId(), videoLocation)
|
||||||
{
|
{
|
||||||
|
|
|
@ -30,7 +30,7 @@ class QRenderer : public QWidget
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QRenderer(const QString videoLocation, QWidget *parent = 0, Qt::WFlags flags = 0);
|
QRenderer(const QString videoLocation, QWidget *parent = 0, Qt::WindowFlags flags = 0);
|
||||||
~QRenderer();
|
~QRenderer();
|
||||||
void paintEvent(QPaintEvent* event);
|
void paintEvent(QPaintEvent* event);
|
||||||
void mouseMoveEvent(QMouseEvent* event);
|
void mouseMoveEvent(QMouseEvent* event);
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <QtGui/QApplication>
|
#include <QtGui/QApplication>
|
||||||
|
#include <QtGui/QFileDialog>
|
||||||
#include "qglrenderer.h"
|
#include "qglrenderer.h"
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
|
@ -26,13 +27,13 @@ int main(int argc, char *argv[])
|
||||||
QApplication a(argc, argv);
|
QApplication a(argc, argv);
|
||||||
a.connect(&a, SIGNAL(lastWindowClosed()), &a, SLOT(quit()));
|
a.connect(&a, SIGNAL(lastWindowClosed()), &a, SLOT(quit()));
|
||||||
|
|
||||||
QString videolcoation = QFileDialog::getOpenFileName(0, "Select a video file",
|
QString videolocation = QFileDialog::getOpenFileName(0, "Select a video file",
|
||||||
".", "Format (*.avi *.mkv *.ogg *.asf *.mov)");
|
".", "Format (*.avi *.mkv *.ogg *.asf *.mov)");
|
||||||
|
|
||||||
if (videolcoation.isEmpty())
|
if (videolocation.isEmpty())
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
QGLRenderer w(videolcoation);
|
QGLRenderer w(videolocation);
|
||||||
w.setWindowTitle("glimagesink implements the gstvideooverlay interface");
|
w.setWindowTitle("glimagesink implements the gstvideooverlay interface");
|
||||||
|
|
||||||
return a.exec();
|
return a.exec();
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
#include <gst/video/videooverlay.h>
|
#include <gst/video/videooverlay.h>
|
||||||
#include <GL/gl.h>
|
#include <GL/gl.h>
|
||||||
|
#include <GL/glu.h>
|
||||||
#include "pipeline.h"
|
#include "pipeline.h"
|
||||||
|
|
||||||
Pipeline::Pipeline(const WId id, const QString videoLocation):
|
Pipeline::Pipeline(const WId id, const QString videoLocation):
|
||||||
|
@ -40,7 +41,7 @@ Pipeline::~Pipeline()
|
||||||
|
|
||||||
void Pipeline::create()
|
void Pipeline::create()
|
||||||
{
|
{
|
||||||
qDebug("Loading video: %s", m_videoLocation.toAscii().data());
|
qDebug("Loading video: %s", m_videoLocation.toLatin1().data());
|
||||||
|
|
||||||
gst_init (NULL, NULL);
|
gst_init (NULL, NULL);
|
||||||
|
|
||||||
|
@ -51,12 +52,12 @@ void Pipeline::create()
|
||||||
|
|
||||||
m_bus = gst_pipeline_get_bus (GST_PIPELINE (m_pipeline));
|
m_bus = gst_pipeline_get_bus (GST_PIPELINE (m_pipeline));
|
||||||
gst_bus_add_watch (m_bus, (GstBusFunc) bus_call, this);
|
gst_bus_add_watch (m_bus, (GstBusFunc) bus_call, this);
|
||||||
gst_bus_set_sync_handler (m_bus, (GstBusSyncHandler) create_window, this);
|
gst_bus_set_sync_handler (m_bus, (GstBusSyncHandler) create_window, this, NULL);
|
||||||
gst_object_unref (m_bus);
|
gst_object_unref (m_bus);
|
||||||
|
|
||||||
GstElement* videosrc = gst_element_factory_make ("filesrc", "filesrc0");
|
GstElement* videosrc = gst_element_factory_make ("filesrc", "filesrc0");
|
||||||
GstElement* decodebin = gst_element_factory_make ("decodebin", "decodebin0");
|
GstElement* decodebin = gst_element_factory_make ("decodebin", "decodebin0");
|
||||||
m_glupload = gst_element_factory_make ("glupload", "glupload0");
|
m_glupload = gst_element_factory_make ("glcolorscale", NULL);
|
||||||
m_glimagesink = gst_element_factory_make ("glimagesink", "sink0");
|
m_glimagesink = gst_element_factory_make ("glimagesink", "sink0");
|
||||||
|
|
||||||
if (!videosrc || !decodebin || !m_glupload || !m_glimagesink )
|
if (!videosrc || !decodebin || !m_glupload || !m_glimagesink )
|
||||||
|
@ -71,9 +72,9 @@ void Pipeline::create()
|
||||||
NULL) ;
|
NULL) ;
|
||||||
|
|
||||||
g_object_set(G_OBJECT(videosrc), "num-buffers", 800, NULL);
|
g_object_set(G_OBJECT(videosrc), "num-buffers", 800, NULL);
|
||||||
g_object_set(G_OBJECT(videosrc), "location", m_videoLocation.toAscii().data(), NULL);
|
g_object_set(G_OBJECT(videosrc), "location", m_videoLocation.toLatin1().data(), NULL);
|
||||||
g_object_set(G_OBJECT(m_glimagesink), "client-reshape-callback", reshapeCallback, NULL);
|
g_signal_connect_object (G_OBJECT(m_glimagesink), "client-reshape", (GCallback) reshapeCallback, NULL, G_CONNECT_AFTER);
|
||||||
g_object_set(G_OBJECT(m_glimagesink), "client-draw-callback", drawCallback, NULL);
|
g_signal_connect_object (G_OBJECT(m_glimagesink), "client-draw", (GCallback) drawCallback, NULL, G_CONNECT_AFTER);
|
||||||
|
|
||||||
gst_bin_add_many (GST_BIN (m_pipeline), videosrc, decodebin, m_glupload, m_glimagesink, NULL);
|
gst_bin_add_many (GST_BIN (m_pipeline), videosrc, decodebin, m_glupload, m_glimagesink, NULL);
|
||||||
|
|
||||||
|
@ -87,7 +88,7 @@ void Pipeline::create()
|
||||||
|
|
||||||
gst_element_link_pads (videosrc, "src", decodebin, "sink");
|
gst_element_link_pads (videosrc, "src", decodebin, "sink");
|
||||||
|
|
||||||
g_signal_connect (decodebin, "new-decoded-pad", G_CALLBACK (cb_new_pad), this);
|
g_signal_connect (decodebin, "pad-added", G_CALLBACK (cb_new_pad), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pipeline::start()
|
void Pipeline::start()
|
||||||
|
@ -156,7 +157,7 @@ void Pipeline::exposeRequested()
|
||||||
//-----------------------------------------------------------------------
|
//-----------------------------------------------------------------------
|
||||||
|
|
||||||
//client reshape callback
|
//client reshape callback
|
||||||
gboolean Pipeline::reshapeCallback (void *sink, guint width, guint height, gpointer data)
|
gboolean Pipeline::reshapeCallback (void *sink, void *context, guint width, guint height, gpointer data)
|
||||||
{
|
{
|
||||||
glViewport(0, 0, width, height);
|
glViewport(0, 0, width, height);
|
||||||
glMatrixMode(GL_PROJECTION);
|
glMatrixMode(GL_PROJECTION);
|
||||||
|
@ -168,7 +169,7 @@ gboolean Pipeline::reshapeCallback (void *sink, guint width, guint height, gpoin
|
||||||
}
|
}
|
||||||
|
|
||||||
//client draw callback
|
//client draw callback
|
||||||
gboolean Pipeline::drawCallback (void *sink, guint texture, guint width, guint height, gpointer data)
|
gboolean Pipeline::drawCallback (void *sink, void *context, guint texture, guint width, guint height, gpointer data)
|
||||||
{
|
{
|
||||||
static GLfloat xrot = 0;
|
static GLfloat xrot = 0;
|
||||||
static GLfloat yrot = 0;
|
static GLfloat yrot = 0;
|
||||||
|
@ -209,35 +210,35 @@ gboolean Pipeline::drawCallback (void *sink, guint texture, guint width, guint h
|
||||||
|
|
||||||
glBegin(GL_QUADS);
|
glBegin(GL_QUADS);
|
||||||
// Front Face
|
// Front Face
|
||||||
glTexCoord2f((gfloat)width, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
|
glTexCoord2f(1.0, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
|
||||||
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
|
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
|
||||||
glTexCoord2f(0.0f, (gfloat)height); glVertex3f( 1.0f, 1.0f, 1.0f);
|
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
|
||||||
glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f(-1.0f, 1.0f, 1.0f);
|
glTexCoord2f(1.0, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
|
||||||
// Back Face
|
// Back Face
|
||||||
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
|
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
|
||||||
glTexCoord2f(0.0f, (gfloat)height); glVertex3f(-1.0f, 1.0f, -1.0f);
|
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
|
||||||
glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f( 1.0f, 1.0f, -1.0f);
|
glTexCoord2f(1.0, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
|
||||||
glTexCoord2f((gfloat)width, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
|
glTexCoord2f(1.0, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
|
||||||
// Top Face
|
// Top Face
|
||||||
glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f(-1.0f, 1.0f, -1.0f);
|
glTexCoord2f(1.0, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
|
||||||
glTexCoord2f((gfloat)width, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
|
glTexCoord2f(1.0, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
|
||||||
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
|
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
|
||||||
glTexCoord2f(0.0f, (gfloat)height); glVertex3f( 1.0f, 1.0f, -1.0f);
|
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
|
||||||
// Bottom Face
|
// Bottom Face
|
||||||
glTexCoord2f((gfloat)width, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
|
glTexCoord2f(1.0, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
|
||||||
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
|
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
|
||||||
glTexCoord2f(0.0f, (gfloat)height); glVertex3f( 1.0f, -1.0f, 1.0f);
|
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
|
||||||
glTexCoord2f((gfloat)width,(gfloat)height); glVertex3f(-1.0f, -1.0f, 1.0f);
|
glTexCoord2f(1.0,1.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
|
||||||
// Right face
|
// Right face
|
||||||
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
|
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
|
||||||
glTexCoord2f(0.0f, (gfloat)height); glVertex3f( 1.0f, 1.0f, -1.0f);
|
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
|
||||||
glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f( 1.0f, 1.0f, 1.0f);
|
glTexCoord2f(1.0, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
|
||||||
glTexCoord2f((gfloat)width, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
|
glTexCoord2f(1.0, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
|
||||||
// Left Face
|
// Left Face
|
||||||
glTexCoord2f((gfloat)width, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
|
glTexCoord2f(1.0, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
|
||||||
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
|
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
|
||||||
glTexCoord2f(0.0f, (gfloat)height); glVertex3f(-1.0f, 1.0f, 1.0f);
|
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
|
||||||
glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f(-1.0f, 1.0f, -1.0f);
|
glTexCoord2f(1.0, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
|
||||||
glEnd();
|
glEnd();
|
||||||
|
|
||||||
xrot+=0.03f;
|
xrot+=0.03f;
|
||||||
|
@ -278,10 +279,10 @@ gboolean Pipeline::bus_call (GstBus *bus, GstMessage *msg, Pipeline* p)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pipeline::cb_new_pad (GstElement* decodebin, GstPad* pad, gboolean last, Pipeline* p)
|
void Pipeline::cb_new_pad (GstElement* decodebin, GstPad* pad, Pipeline* p)
|
||||||
{
|
{
|
||||||
GstElement* glupload = p->getVideoSink();
|
GstElement* glupload = p->getVideoSink();
|
||||||
GstPad* glpad = gst_element_get_pad (glupload, "sink");
|
GstPad* glpad = gst_element_get_static_pad (glupload, "sink");
|
||||||
|
|
||||||
//only link once
|
//only link once
|
||||||
if (GST_PAD_IS_LINKED (glpad))
|
if (GST_PAD_IS_LINKED (glpad))
|
||||||
|
@ -290,7 +291,7 @@ void Pipeline::cb_new_pad (GstElement* decodebin, GstPad* pad, gboolean last, Pi
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
GstCaps* caps = gst_pad_get_caps (pad);
|
GstCaps* caps = gst_pad_get_current_caps (pad);
|
||||||
GstStructure* str = gst_caps_get_structure (caps, 0);
|
GstStructure* str = gst_caps_get_structure (caps, 0);
|
||||||
if (!g_strrstr (gst_structure_get_name (str), "video"))
|
if (!g_strrstr (gst_structure_get_name (str), "video"))
|
||||||
{
|
{
|
||||||
|
|
|
@ -59,10 +59,10 @@ private:
|
||||||
WId winId() const { return m_winId; }
|
WId winId() const { return m_winId; }
|
||||||
void doExpose() const;
|
void doExpose() const;
|
||||||
|
|
||||||
static gboolean reshapeCallback (void *sink, guint width, guint height, gpointer data);
|
static gboolean reshapeCallback (void *sink, void *context, guint width, guint height, gpointer data);
|
||||||
static gboolean drawCallback (void *sink, guint texture, guint width, guint height, gpointer data);
|
static gboolean drawCallback (void *sink, void *context, guint texture, guint width, guint height, gpointer data);
|
||||||
static gboolean bus_call (GstBus *bus, GstMessage *msg, Pipeline* p);
|
static gboolean bus_call (GstBus *bus, GstMessage *msg, Pipeline* p);
|
||||||
static void cb_new_pad (GstElement* decodebin, GstPad* pad, gboolean last, Pipeline* p);
|
static void cb_new_pad (GstElement* decodebin, GstPad* pad, Pipeline* p);
|
||||||
static gboolean cb_expose (gpointer data);
|
static gboolean cb_expose (gpointer data);
|
||||||
static GstBusSyncReply create_window (GstBus* bus, GstMessage* message, const Pipeline* pipeline);
|
static GstBusSyncReply create_window (GstBus* bus, GstMessage* message, const Pipeline* pipeline);
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,7 +3,10 @@ TARGET = qglwidgetvideooverlay
|
||||||
DESTDIR = ./debug
|
DESTDIR = ./debug
|
||||||
QT += opengl
|
QT += opengl
|
||||||
CONFIG += debug
|
CONFIG += debug
|
||||||
|
CONFIG += link_pkgconfig
|
||||||
|
CONFIG+= compile_libtool
|
||||||
DEFINES += UNICODE QT_THREAD_SUPPORT QT_CORE_LIB QT_GUI_LIB
|
DEFINES += UNICODE QT_THREAD_SUPPORT QT_CORE_LIB QT_GUI_LIB
|
||||||
|
PKGCONFIG = gstreamer-1.0 gstreamer-video-1.0
|
||||||
|
|
||||||
win32 {
|
win32 {
|
||||||
DEFINES += WIN32
|
DEFINES += WIN32
|
||||||
|
@ -29,18 +32,8 @@ LIBS += -L"C:/gstreamer/lib" \
|
||||||
unix {
|
unix {
|
||||||
DEFINES += UNIX
|
DEFINES += UNIX
|
||||||
INCLUDEPATH += GeneratedFiles \
|
INCLUDEPATH += GeneratedFiles \
|
||||||
GeneratedFiles/Debug \
|
GeneratedFiles/Debug
|
||||||
/usr/include/gstreamer-1.0 \
|
LIBS += \
|
||||||
/usr/local/include/gstreamer-1.0 \
|
|
||||||
/usr/include/glib-2.0 \
|
|
||||||
/usr/lib/glib-2.0/include \
|
|
||||||
/usr/include/libxml2
|
|
||||||
LIBS += -lgstreamer-1.0 \
|
|
||||||
-lgstvideo-1.0 \
|
|
||||||
-lglib-2.0 \
|
|
||||||
-lgmodule-2.0 \
|
|
||||||
-lgobject-2.0 \
|
|
||||||
-lgthread-2.0 \
|
|
||||||
-lGLU \
|
-lGLU \
|
||||||
-lGL
|
-lGL
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,8 @@
|
||||||
#include "qglrenderer.h"
|
#include "qglrenderer.h"
|
||||||
#include "pipeline.h"
|
#include "pipeline.h"
|
||||||
|
|
||||||
|
#include <GL/glx.h>
|
||||||
|
|
||||||
#if defined(Q_WS_MAC)
|
#if defined(Q_WS_MAC)
|
||||||
extern void *qt_current_nsopengl_context();
|
extern void *qt_current_nsopengl_context();
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -6,6 +6,8 @@ QT += opengl
|
||||||
# the console on Windows
|
# the console on Windows
|
||||||
# CONFIG += console
|
# CONFIG += console
|
||||||
DEFINES += UNICODE QT_THREAD_SUPPORT QT_CORE_LIB QT_GUI_LIB
|
DEFINES += UNICODE QT_THREAD_SUPPORT QT_CORE_LIB QT_GUI_LIB
|
||||||
|
CONFIG += link_pkgconfig compile_libtool
|
||||||
|
PKGCONFIG=gstreamer-1.0 gstreamer-video-1.0 gstreamer-gl-1.0
|
||||||
|
|
||||||
win32 {
|
win32 {
|
||||||
DEFINES += WIN32
|
DEFINES += WIN32
|
||||||
|
@ -30,21 +32,8 @@ LIBS += -L"C:/gstreamer/lib" \
|
||||||
}
|
}
|
||||||
unix:!mac {
|
unix:!mac {
|
||||||
DEFINES += UNIX
|
DEFINES += UNIX
|
||||||
INCLUDEPATH += /home/matt/Projects/jhbuild/native/usr/include/gstreamer-1.0 \
|
LIBS += \
|
||||||
/home/matt/Projects/jhbuild/native/usr/include/glib-2.0 \
|
|
||||||
/home/matt/Projects/jhbuild/native/usr/lib/glib-2.0/include \
|
|
||||||
/usr/include/gstreamer-1.0 \
|
|
||||||
/usr/local/include/gstreamer-1.0 \
|
|
||||||
/usr/include/glib-2.0 \
|
|
||||||
/usr/lib/glib-2.0/include \
|
|
||||||
/usr/include/libxml2
|
|
||||||
LIBS += -L/home/matt/Projects/jhbuild/native/usr/lib \
|
|
||||||
-lgstreamer-1.0 \
|
|
||||||
-lgstvideo-1.0 \
|
-lgstvideo-1.0 \
|
||||||
-lglib-2.0 \
|
|
||||||
-lgmodule-2.0 \
|
|
||||||
-lgobject-2.0 \
|
|
||||||
-lgthread-2.0 \
|
|
||||||
-lgstgl-1.0 \
|
-lgstgl-1.0 \
|
||||||
-lGLU \
|
-lGLU \
|
||||||
-lGL
|
-lGL
|
||||||
|
|
Binary file not shown.
|
@ -1,9 +1,10 @@
|
||||||
TEMPLATE = app
|
TEMPLATE = app
|
||||||
TARGET = videooverlay
|
TARGET = videooverlay
|
||||||
DESTDIR = ./Debug
|
DESTDIR = ./debug
|
||||||
CONFIG += debug
|
CONFIG += debug link_pkgconfig compile_libtool
|
||||||
DEFINES += UNICODE QT_THREAD_SUPPORT QT_CORE_LIB QT_GUI_LIB
|
DEFINES += UNICODE QT_THREAD_SUPPORT QT_CORE_LIB QT_GUI_LIB
|
||||||
QT += gui widgets
|
QT += gui widgets
|
||||||
|
PKGCONFIG=gstreamer-1.0 gstreamer-video-1.0
|
||||||
|
|
||||||
win32 {
|
win32 {
|
||||||
DEFINES += WIN32
|
DEFINES += WIN32
|
||||||
|
@ -27,20 +28,8 @@ LIBS += -L"C:/gstreamer/bin" \
|
||||||
unix {
|
unix {
|
||||||
DEFINES += UNIX
|
DEFINES += UNIX
|
||||||
INCLUDEPATH += GeneratedFiles \
|
INCLUDEPATH += GeneratedFiles \
|
||||||
GeneratedFiles/Debug \
|
GeneratedFiles/Debug
|
||||||
/usr/include/gstreamer-1.0 \
|
LIBS += -lGLU -lGL
|
||||||
/usr/local/include/gstreamer-1.0 \
|
|
||||||
/usr/include/glib-2.0 \
|
|
||||||
/usr/lib/glib-2.0/include \
|
|
||||||
/usr/include/libxml2
|
|
||||||
LIBS += -lgstreamer-1.0 \
|
|
||||||
-lgstvideo-1.0 \
|
|
||||||
-lglib-2.0 \
|
|
||||||
-lgmodule-2.0 \
|
|
||||||
-lgobject-2.0 \
|
|
||||||
-lgthread-2.0 \
|
|
||||||
-lGLU \
|
|
||||||
-lGL
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DEPENDPATH += .
|
DEPENDPATH += .
|
Loading…
Reference in a new issue