gl/examples: move to -bad

- fix all the compiler errors
- give them their own gl directory
This commit is contained in:
Matthew Waters 2014-04-29 16:38:55 +10:00
parent 967982a0b5
commit 294da02a2f
114 changed files with 9739 additions and 28 deletions

View file

@ -235,6 +235,65 @@ fi
AM_CONDITIONAL(HAVE_GTK, test "x$HAVE_GTK" = "xyes")
dnl GTK is optional and used in examples
HAVE_GTK3=NO
if test "x$BUILD_EXAMPLES" = "xyes"; then
PKG_CHECK_MODULES(GTK3, gtk+-3.0 >= 3.4, HAVE_GTK3=yes, HAVE_GTK3=no)
if test "x$HAVE_GTK3" = "xyes"; then
HAVE_GTK=yes
GTK_VERSION=`$PKG_CONFIG --variable=gtk_binary_version gtk+-3.0`
AC_SUBST(GTK_VERSION)
GTK_PREFIX=`$PKG_CONFIG --variable=prefix gdk-pixbuf-2.0`
AC_SUBST(GTK_BASE_DIR)
fi
fi
AC_SUBST(GTK3_LIBS)
AC_SUBST(GTK3_CFLAGS)
AC_SUBST(HAVE_GTK3)
AM_CONDITIONAL(HAVE_GTK3, test "x$HAVE_GTK3" = "xyes")
dnl clutter is optional and used in examples
HAVE_CLUTTER=no
HAVE_CLUTTER_X11=no
HAVE_CLUTTER_GLX=no
if test "x$BUILD_EXAMPLES" = "xyes"; then
PKG_CHECK_MODULES(CLUTTER, clutter-1.0 >= 1.8, HAVE_CLUTTER=yes, HAVE_CLUTTER=no)
AC_SUBST(CLUTTER_LIBS)
AC_SUBST(CLUTTER_CFLAGS)
AC_SUBST(HAVE_CLUTTER)
PKG_CHECK_MODULES(CLUTTER_GLX, clutter-glx-1.0 >= 1.8, HAVE_CLUTTER_GLX=yes, HAVE_CLUTTER_GLX=no)
AC_SUBST(CLUTTER_GLX_LIBS)
AC_SUBST(CLUTTER_GLX_CFLAGS)
AC_SUBST(HAVE_CLUTTER_GLX)
PKG_CHECK_MODULES(CLUTTER_X11, clutter-x11-1.0 >= 1.8, HAVE_CLUTTER_X11=yes, HAVE_CLUTTER_X11=no)
AC_SUBST(CLUTTER_X11_LIBS)
AC_SUBST(CLUTTER_X11_CFLAGS)
AC_SUBST(HAVE_CLUTTER_X11)
fi
AM_CONDITIONAL(HAVE_CLUTTER, test "x$HAVE_CLUTTER" = "xyes")
AM_CONDITIONAL(HAVE_CLUTTER_GLX, test "x$HAVE_CLUTTER_GLX" = "xyes")
AM_CONDITIONAL(HAVE_CLUTTER_X11, test "x$HAVE_CLUTTER_X11" = "xyes")
dnl used in the gl/clutteractor example
if test "x$BUILD_EXAMPLES" = "xyes"; then
PKG_CHECK_MODULES(XCOMPOSITE, xcomposite, HAVE_XCOMPOSITE=yes, HAVE_XCOMPOSITE=no)
AC_SUBST(XCOMPOSITE_CFLAGS)
AC_SUBST(XCOMPOSITE_LIBS)
fi
AM_CONDITIONAL(HAVE_XCOMPOSITE, test "x$HAVE_XCOMPOSITE" = "xyes")
dnl sdl is optional and used in examples
HAVE_SDL=NO
if test "x$BUILD_EXAMPLES" = "xyes"; then
PKG_CHECK_MODULES(SDL, sdl >= 1.2.0, HAVE_SDL=yes, HAVE_SDL=no)
AC_SUBST(SDL_LIBS)
AC_SUBST(SDL_CFLAGS)
AC_SUBST(SDL_CLUTTER)
fi
AM_CONDITIONAL(HAVE_SDL, test "x$HAVE_SDL" = "xyes")
dnl Needed for GtkBuilder to autoconnect signals
PKG_CHECK_MODULES(GMODULE_EXPORT, gmodule-export-2.0, HAVE_GMODULE_EXPORT=yes, HAVE_GMODULE_EXPORT=no)
@ -3161,6 +3220,23 @@ tests/files/Makefile
tests/examples/Makefile
tests/examples/camerabin2/Makefile
tests/examples/directfb/Makefile
tests/examples/gl/Makefile
tests/examples/gl/cocoa/Makefile
tests/examples/gl/cocoa/videooverlay/Makefile
tests/examples/gl/clutter/Makefile
tests/examples/gl/generic/Makefile
tests/examples/gl/generic/cube/Makefile
tests/examples/gl/generic/cubeyuv/Makefile
tests/examples/gl/generic/doublecube/Makefile
tests/examples/gl/generic/recordgraphic/Makefile
tests/examples/gl/gtk/Makefile
tests/examples/gl/gtk/gtkvideooverlay/Makefile
tests/examples/gl/gtk/filternovideooverlay/Makefile
tests/examples/gl/gtk/filtervideooverlay/Makefile
tests/examples/gl/gtk/fxtest/Makefile
tests/examples/gl/gtk/switchvideooverlay/Makefile
tests/examples/gl/qt/Makefile
tests/examples/gl/sdl/Makefile
tests/examples/mpegts/Makefile
tests/examples/mxf/Makefile
tests/examples/opencv/Makefile

View file

@ -18,7 +18,13 @@ endif
OPENCV_EXAMPLES=opencv
SUBDIRS= mpegts $(DIRECTFB_DIR) $(GTK_EXAMPLES) $(OPENCV_EXAMPLES)
DIST_SUBDIRS= mpegts camerabin2 directfb mxf opencv uvch264
if USE_OPENGL
GL_DIR=gl
else
GL_DIR=
endif
SUBDIRS= mpegts $(DIRECTFB_DIR) $(GTK_EXAMPLES) $(OPENCV_EXAMPLES) $(GL_DIR)
DIST_SUBDIRS= mpegts camerabin2 directfb mxf opencv uvch264 gl
include $(top_srcdir)/common/parallel-subdirs.mak

View file

@ -0,0 +1,26 @@
SUBDIRS =
if USE_OPENGL
if HAVE_WINDOW_COCOA
SUBDIRS += cocoa
else
SUBDIRS += generic qt
#if HAVE_CLUTTER
#SUBDIRS += clutter
#endif
if HAVE_SDL
SUBDIRS += sdl
endif
if HAVE_GTK3
SUBDIRS += gtk
endif
endif
endif

3
tests/examples/gl/clutter/.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
clutteractor
clutteractortee
cluttershare

View file

@ -0,0 +1,45 @@
noinst_PROGRAMS = ##
#works on win32 and X
if HAVE_CLUTTER
noinst_PROGRAMS += cluttershare
cluttershare_SOURCES = cluttershare.c
cluttershare_CFLAGS=$(GST_PLUGINS_GL_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) \
$(GST_CFLAGS) $(GL_CFLAGS) $(CLUTTER_CFLAGS)
cluttershare_LDADD=$(CLUTTER_LIBS) $(GST_PLUGINS_BASE_LIBS) \
$(GST_LIBS) $(GL_LIBS) \
-lgstvideo-$(GST_API_VERSION) $(top_builddir)/gst-libs/gst/gl/libgstgl-@GST_API_VERSION@.la
endif
if HAVE_CLUTTER_GLX
if HAVE_CLUTTER_X11
if HAVE_XCOMPOSITE
noinst_PROGRAMS += clutteractor clutteractortee
clutteractor_SOURCES = clutteractor.c
clutteractor_CFLAGS=$(GST_PLUGINS_GL_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) \
$(GL_CFLAGS) $(CLUTTER_CFLAGS) \
$(CLUTTER_GLX_CFLAGS) $(CLUTTER_X11_CFLAGS) $(XCOMPOSITE_CFLAGS)
clutteractor_LDADD=$(CLUTTER_LIBS) $(CLUTTER_GLX_LIBS) $(CLUTTER_X11_LIBS) \
$(GST_PLUGINS_GL_LIBS) $(GST_PLUGINS_BASE_LIBS) $(GST_LIBS) \
$(GL_LIBS) $(XCOMPOSITE_LIBS) -lgstvideo-$(GST_API_VERSION)
clutteractortee_SOURCES = clutteractortee.c
clutteractortee_CFLAGS=$(GST_PLUGINS_GL_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) \
$(GL_CFLAGS) $(CLUTTER_CFLAGS) \
$(CLUTTER_GLX_CFLAGS) $(CLUTTER_X11_CFLAGS) $(XCOMPOSITE_CFLAGS)
clutteractortee_LDADD=$(CLUTTER_LIBS) $(CLUTTER_GLX_LIBS) $(CLUTTER_X11_LIBS) \
$(GST_PLUGINS_GL_LIBS) $(GST_PLUGINS_BASE_LIBS) $(GST_LIBS) \
$(GL_LIBS) $(XCOMPOSITE_LIBS) -lgstvideo-$(GST_API_VERSION)
endif
endif
endif

View file

@ -24,6 +24,9 @@
#include <GL/gl.h>
#define CLUTTER_VERSION_MIN_REQUIRED CLUTTER_VERSION_1_8
#define CLUTTER_VERSION_MAX_ALLOWED CLUTTER_VERSION_1_10
#define COGL_VERSION_MIN_REQUIRED COGL_VERSION_1_16
#define COGL_VERSION_MAX_ALLOWED COGL_VERSION_1_18
#include <clutter/clutter.h>
#ifndef WIN32
#include <clutter/x11/clutter-x11.h>
@ -41,7 +44,7 @@
*/
/* rotation */
void
static void
on_new_frame (ClutterTimeline * timeline, gint msecs, gpointer data)
{
ClutterActor *rect_actor = CLUTTER_ACTOR (data);
@ -60,7 +63,7 @@ on_new_frame (ClutterTimeline * timeline, gint msecs, gpointer data)
/* clutter scene */
ClutterActor *
static ClutterActor *
setup_stage (ClutterStage * stage)
{
ClutterTimeline *timeline = NULL;
@ -98,7 +101,7 @@ setup_stage (ClutterStage * stage)
}
/* put a gst gl buffer in the texture actor */
gboolean
static gboolean
update_texture_actor (gpointer data)
{
ClutterTexture *texture_actor = (ClutterTexture *) data;
@ -167,7 +170,7 @@ update_texture_actor (gpointer data)
/* fakesink handoff callback */
void
static void
on_gst_buffer (GstElement * element, GstBuffer * buf, GstPad * pad,
ClutterActor * texture_actor)
{
@ -193,7 +196,7 @@ on_gst_buffer (GstElement * element, GstBuffer * buf, GstPad * pad,
}
/* gst bus signal watch callback */
void
static void
end_stream_cb (GstBus * bus, GstMessage * msg, gpointer data)
{
switch (GST_MESSAGE_TYPE (msg)) {

View file

@ -0,0 +1,76 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_project_file>
<FileVersion major="1" minor="6" />
<Project>
<Option title="cluttershare" />
<Option pch_mode="2" />
<Option compiler="gcc" />
<Build>
<Target title="Debug">
<Option output="bin\Debug\cluttershare" prefix_auto="1" extension_auto="1" />
<Option object_output="obj\Debug\" />
<Option type="1" />
<Option compiler="gcc" />
<Compiler>
<Add option="-g" />
</Compiler>
</Target>
<Target title="Release">
<Option output="bin\Release\cluttershare" prefix_auto="1" extension_auto="1" />
<Option object_output="obj\Release\" />
<Option type="1" />
<Option compiler="gcc" />
<Compiler>
<Add option="-O2" />
</Compiler>
<Linker>
<Add option="-s" />
</Linker>
</Target>
</Build>
<Compiler>
<Add option="-Wall" />
<Add option="-ansi" />
<Add option="-std=c89" />
<Add option="-DWIN32" />
<Add directory="..\..\..\..\clutter\include\clutter-0.8" />
<Add directory="C:\gstreamer\include\glib-2.0" />
<Add directory="C:\gstreamer\lib\glib-2.0\include" />
<Add directory="C:\gstreamer\include\gstreamer-1.0" />
<Add directory="C:\gstreamer\include\pango-1.0" />
<Add directory="C:\gstreamer\include\cairo" />
<Add directory="C:\gstreamer\include\libxml2" />
<Add directory="C:\gstreamer\include" />
</Compiler>
<Linker>
<Add library="clutter-win32-0.8" />
<Add library="gio-2.0" />
<Add library="gthread-2.0" />
<Add library="gobject-2.0" />
<Add library="gstreamer-1.0" />
<Add library="gmodule-2.0" />
<Add library="gstvideo-1.0" />
<Add library="glib-2.0" />
<Add library="pangocairo-1.0" />
<Add library="pangowin32-1.0" />
<Add library="pango-1.0" />
<Add library="gdk_pixbuf-2.0" />
<Add library="cairo" />
<Add library="glu32" />
<Add library="opengl32" />
<Add library="gdi32" />
<Add library="winmm" />
<Add directory="..\..\..\..\clutter\lib" />
<Add directory="C:\gstreamer\lib" />
<Add directory="C:\gstreamer\bin" />
<Add directory="..\..\..\..\gtk+\lib" />
</Linker>
<Unit filename="cluttershare.c">
<Option compilerVar="CC" />
</Unit>
<Extensions>
<code_completion />
<debugger />
</Extensions>
</Project>
</CodeBlocks_project_file>

View file

@ -0,0 +1,4 @@
if HAVE_WINDOW_COCOA
SUBDIRS = videooverlay
endif

View file

@ -0,0 +1,9 @@
--- Description of the Cocoa examples ---
- videooverlay:
Show how to use the videooverlay interface through Cocoa.
For now, the source is videotestsrc. (not yet a video file)
--- How to build the Cocoa examples on GNUstep environnements ---
make clean all -f GNUmakefile.gnustep

View file

@ -0,0 +1 @@
videooverlay

View file

@ -0,0 +1,14 @@
if HAVE_WINDOW_COCOA
noinst_PROGRAMS = videooverlay
videooverlay_SOURCES = main.m
videooverlay_OBJCFLAGS=$(GST_PLUGINS_GL_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) \
$(GL_CFLAGS) -I/usr/local/include/gstreamer-${GST_API_VERSION} ${GL_OBJCFLAGS}
videooverlay_LDADD=$(GST_PLUGINS_GL_LIBS) $(GST_PLUGINS_BASE_LIBS) $(GST_LIBS) \
$(GL_LIBS) -lgstvideo-$(GST_API_VERSION)
videooverlay_LIBTOOLFLAGS = --tag=OBJC
endif

View file

@ -0,0 +1,240 @@
#include <Cocoa/Cocoa.h>
#include <gst/gst.h>
#include <gst/video/videooverlay.h>
/* ============================================================= */
/* */
/* MainWindow */
/* */
/* ============================================================= */
@interface MainWindow: NSWindow {
GMainLoop *m_loop;
GstElement *m_pipeline;
gboolean m_isClosed;
}
- (id) initWithContentRect:(NSRect) contentRect Loop:(GMainLoop*)loop Pipeline:(GstElement*)pipeline;
- (GMainLoop*) loop;
- (GstElement*) pipeline;
- (gboolean) isClosed;
@end
@implementation MainWindow
- (id) initWithContentRect:(NSRect)contentRect Loop:(GMainLoop*)loop Pipeline:(GstElement*)pipeline
{
m_loop = loop;
m_pipeline = pipeline;
m_isClosed = FALSE;
self = [super initWithContentRect: contentRect
styleMask: (NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask | NSMiniaturizableWindowMask)
backing: NSBackingStoreBuffered defer: NO screen: nil];
[self setReleasedWhenClosed:NO];
[NSApp setDelegate:self];
[self setTitle:@"gst-plugins-gl implements videooverlay interface"];
return self;
}
- (GMainLoop*) loop {
return m_loop;
}
- (GstElement*) pipeline {
return m_pipeline;
}
- (gboolean) isClosed {
return m_isClosed;
}
- (void) customClose {
m_isClosed = TRUE;
}
- (BOOL) windowShouldClose:(id)sender {
gst_element_send_event (m_pipeline, gst_event_new_eos ());
return YES;
}
- (void) applicationDidFinishLaunching: (NSNotification *) not {
[self makeMainWindow];
[self center];
[self orderFront:self];
}
- (BOOL) applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)app {
return NO;
}
@end
/* ============================================================= */
/* */
/* gstreamer callbacks */
/* */
/* ============================================================= */
static GstBusSyncReply create_window (GstBus* bus, GstMessage* message, MainWindow* window)
{
// ignore anything but 'prepare-window-handle' element messages
if (GST_MESSAGE_TYPE (message) != GST_MESSAGE_ELEMENT)
return GST_BUS_PASS;
if (!gst_is_video_overlay_prepare_window_handle_message (message))
return GST_BUS_PASS;
g_print ("setting window handle %lud\n", (gulong) window);
gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY (GST_MESSAGE_SRC (message)), (guintptr) window);
gst_message_unref (message);
return GST_BUS_DROP;
}
static void end_stream_cb(GstBus* bus, GstMessage* message, MainWindow* window)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
g_print ("end of stream\n");
gst_element_set_state ([window pipeline], GST_STATE_NULL);
gst_object_unref ([window pipeline]);
g_main_loop_quit ([window loop]);
[window performSelectorOnMainThread:@selector(customClose) withObject:nil waitUntilDone:YES];
[pool release];
}
static gpointer thread_func (MainWindow* window)
{
#ifdef GNUSTEP
GSRegisterCurrentThread();
#endif
g_main_loop_run ([window loop]);
#ifdef GNUSTEP
GSUnregisterCurrentThread();
#endif
return NULL;
}
/* ============================================================= */
/* */
/* application */
/* */
/* ============================================================= */
int main(int argc, char **argv)
{
int width = 640;
int height = 480;
GMainLoop *loop = NULL;
GstElement *pipeline = NULL;
GstElement *videosrc = NULL;
GstElement *videosink = NULL;
GstCaps *caps=NULL;
gboolean ok=FALSE;
GstBus *bus=NULL;
GThread *loop_thread=NULL;
NSAutoreleasePool *pool=nil;
NSRect rect;
MainWindow *window=nil;
#ifdef GNUSTEP
GstState state;
#endif
g_print("app created\n");
gst_init (&argc, &argv);
loop = g_main_loop_new (NULL, FALSE);
pipeline = gst_pipeline_new ("pipeline");
videosrc = gst_element_factory_make ("videotestsrc", "videotestsrc");
videosink = gst_element_factory_make ("glimagesink", "glimagesink");
g_object_set(G_OBJECT(videosrc), "num-buffers", 500, NULL);
gst_bin_add_many (GST_BIN (pipeline), videosrc, videosink, NULL);
caps = gst_caps_new_simple("video/x-raw",
"width", G_TYPE_INT, width,
"height", G_TYPE_INT, height,
"framerate", GST_TYPE_FRACTION, 25, 1,
"format", G_TYPE_STRING, "I420",
NULL);
ok = gst_element_link_filtered(videosrc, videosink, caps);
gst_caps_unref(caps);
if (!ok)
g_warning("could not link videosrc to videosink\n");
#ifdef GNUSTEP
gst_element_set_state (pipeline, GST_STATE_PAUSED);
state = GST_STATE_PAUSED;
gst_element_get_state (pipeline, &state, &state, GST_CLOCK_TIME_NONE);
g_print("pipeline paused\n");
GSRegisterCurrentThread();
#endif
pool = [[NSAutoreleasePool alloc] init];
#ifndef GNUSTEP
[NSApplication sharedApplication];
#endif
rect.origin.x = 0; rect.origin.y = 0;
rect.size.width = width; rect.size.height = height;
window = [[MainWindow alloc] initWithContentRect:rect Loop:loop Pipeline:pipeline];
bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
gst_bus_add_signal_watch (bus);
g_signal_connect(bus, "message::error", G_CALLBACK(end_stream_cb), window);
g_signal_connect(bus, "message::warning", G_CALLBACK(end_stream_cb), window);
g_signal_connect(bus, "message::eos", G_CALLBACK(end_stream_cb), window);
gst_bus_set_sync_handler (bus, (GstBusSyncHandler) create_window, window, NULL);
gst_object_unref (bus);
loop_thread = g_thread_new (NULL,
(GThreadFunc) thread_func, window);
gst_element_set_state (pipeline, GST_STATE_PLAYING);
[window orderFront:window];
#ifndef GNUSTEP
while (![window isClosed]) {
NSEvent *event = [NSApp nextEventMatchingMask:NSAnyEventMask
untilDate:[NSDate dateWithTimeIntervalSinceNow:1]
inMode:NSDefaultRunLoopMode dequeue:YES];
if (event)
[NSApp sendEvent:event];
}
#endif
g_thread_join (loop_thread);
[window release];
[pool release];
#ifdef GNUSTEP
GSUnregisterCurrentThread();
#endif
return 0;
}

View file

@ -0,0 +1,2 @@
SUBDIRS = cube cubeyuv doublecube recordgraphic

View file

@ -0,0 +1,21 @@
--- Description of the generic (no GUI) examples ---
- cube:
Show how to have a graphic FPS greater than the input video frame rate.
The source is the videotestsrc rgb.
- cubeyuv:
Show how to have a graphic FPS greater than the input video frame rate.
The source is a local video file needed in argument.
The colorspace conversion is maded by the glupload element.
- doublecube:
A local video source is displayed into two renderers.
The first one is a normal 2D screen, the second is a 3D cube.
We can visually check that the video is displayed at the same speed
in the two renderers.
- recordgraphic:
Show how to use the glfilterapp to define the draw callback in a gstreamer client code.
The scene is recorded into an avi file using mpeg4 encoder.
The colorspace conversion is made by the gldownload element.

View file

@ -0,0 +1 @@
cube

View file

@ -0,0 +1,8 @@
noinst_PROGRAMS = cube
cube_SOURCES = main.cpp
cube_CXXFLAGS=$(GST_PLUGINS_GL_CFLAGS) $(GST_CXXFLAGS) $(GL_CFLAGS)
cube_LDADD=$(GST_PLUGINS_GL_LIBS) $(GST_LIBS) $(GL_LIBS)

View file

@ -0,0 +1,202 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9,00"
Name="cube"
ProjectGUID="{DA41FBFF-E1DE-4DA1-BB96-C56C63D5CDBE}"
RootNamespace="cube"
Keyword="Win32Proj"
TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="&quot;C:\gstreamer\include\glib-2.0&quot;;&quot;C:\gstreamer\lib\glib-2.0\include&quot;;&quot;C:\gstreamer\include\gstreamer-1.0&quot;;C:\gstreamer\include\libxml2;C:\gstreamer\include"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="gstreamer-1.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib opengl32.lib glu32.lib"
LinkIncremental="2"
AdditionalLibraryDirectories="C:\gstreamer\lib"
GenerateDebugInformation="true"
SubSystem="1"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;C:\gstreamer\include\glib-2.0&quot;;&quot;C:\gstreamer\lib\glib-2.0\include&quot;;&quot;C:\gstreamer\include\gstreamer-1.0&quot;;C:\gstreamer\include\libxml2;C:\gstreamer\include"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="gstreamer-1.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib opengl32.lib glu32.lib"
LinkIncremental="1"
AdditionalLibraryDirectories="C:\gstreamer\lib"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\main.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View file

@ -0,0 +1,248 @@
/*
* GStreamer
* Copyright (C) 2008-2009 Julien Isorce <julien.isorce@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <GL/gl.h>
#include <GL/glu.h>
#if __WIN32__ || _WIN32
# include <GL/glext.h>
#endif
#include <gst/gst.h>
#include <iostream>
#include <string>
static gboolean bus_call (GstBus *bus, GstMessage *msg, gpointer data)
{
GMainLoop *loop = (GMainLoop*)data;
switch (GST_MESSAGE_TYPE (msg))
{
case GST_MESSAGE_EOS:
g_print ("End-of-stream\n");
g_main_loop_quit (loop);
break;
case GST_MESSAGE_ERROR:
{
gchar *debug = NULL;
GError *err = NULL;
gst_message_parse_error (msg, &err, &debug);
g_print ("Error: %s\n", err->message);
g_error_free (err);
if (debug)
{
g_print ("Debug deails: %s\n", debug);
g_free (debug);
}
g_main_loop_quit (loop);
break;
}
default:
break;
}
return TRUE;
}
//client reshape callback
static void reshapeCallback (GLuint width, GLuint height, gpointer data)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45, (gfloat)width/(gfloat)height, 0.1, 100);
glMatrixMode(GL_MODELVIEW);
}
//client draw callback
static gboolean drawCallback (GLuint texture, GLuint width, GLuint height, gpointer data)
{
static GLfloat xrot = 0;
static GLfloat yrot = 0;
static GLfloat zrot = 0;
static GTimeVal current_time;
static glong last_sec = current_time.tv_sec;
static gint nbFrames = 0;
g_get_current_time (&current_time);
nbFrames++ ;
if ((current_time.tv_sec - last_sec) >= 1)
{
std::cout << "GRPHIC FPS = " << nbFrames << std::endl;
nbFrames = 0;
last_sec = current_time.tv_sec;
}
glEnable(GL_DEPTH_TEST);
glEnable (GL_TEXTURE_2D);
glBindTexture (GL_TEXTURE_2D, texture);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0f,0.0f,-5.0f);
glRotatef(xrot,1.0f,0.0f,0.0f);
glRotatef(yrot,0.0f,1.0f,0.0f);
glRotatef(zrot,0.0f,0.0f,1.0f);
glBegin(GL_QUADS);
// Front Face
glTexCoord2f((gfloat)width, 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((gfloat)width, (gfloat)height); glVertex3f(-1.0f, 1.0f, 1.0f);
// Back Face
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((gfloat)width, (gfloat)height); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f((gfloat)width, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
// Top Face
glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f((gfloat)width, 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);
// Bottom Face
glTexCoord2f((gfloat)width, 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((gfloat)width,(gfloat)height); glVertex3f(-1.0f, -1.0f, 1.0f);
// Right face
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((gfloat)width, (gfloat)height); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f((gfloat)width, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
// Left Face
glTexCoord2f((gfloat)width, 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((gfloat)width, (gfloat)height); glVertex3f(-1.0f, 1.0f, -1.0f);
glEnd();
xrot+=0.3f;
yrot+=0.2f;
zrot+=0.4f;
//return TRUE causes a postRedisplay
return TRUE;
}
//gst-launch-1.0 videotestsrc num_buffers=400 ! video/x-raw, width=320, height=240 !
//glgraphicmaker ! glfiltercube ! video/x-raw, width=800, height=600 ! glimagesink
gint main (gint argc, gchar *argv[])
{
GstStateChangeReturn ret;
GstElement *pipeline, *videosrc, *glimagesink;
GMainLoop *loop;
GstBus *bus;
/* initialization */
gst_init (&argc, &argv);
loop = g_main_loop_new (NULL, FALSE);
/* create elements */
pipeline = gst_pipeline_new ("pipeline");
/* watch for messages on the pipeline's bus (note that this will only
* work like this when a GLib main loop is running) */
bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
gst_bus_add_watch (bus, bus_call, loop);
gst_object_unref (bus);
/* create elements */
videosrc = gst_element_factory_make ("videotestsrc", "videotestsrc0");
glimagesink = gst_element_factory_make ("glimagesink", "glimagesink0");
if (!videosrc || !glimagesink)
{
g_print ("one element could not be found \n");
return -1;
}
/* change video source caps */
GstCaps *caps = gst_caps_new_simple("video/x-raw",
"format", G_TYPE_STRING, "RGB",
"width", G_TYPE_INT, 320,
"height", G_TYPE_INT, 240,
"framerate", GST_TYPE_FRACTION, 25, 1,
NULL) ;
/* configure elements */
g_object_set(G_OBJECT(videosrc), "num-buffers", 400, NULL);
g_object_set(G_OBJECT(glimagesink), "client-reshape-callback", reshapeCallback, NULL);
g_object_set(G_OBJECT(glimagesink), "client-draw-callback", drawCallback, NULL);
g_object_set(G_OBJECT(glimagesink), "client-data", NULL, NULL);
/* add elements */
gst_bin_add_many (GST_BIN (pipeline), videosrc, glimagesink, NULL);
/* link elements */
gboolean link_ok = gst_element_link_filtered(videosrc, glimagesink, caps) ;
gst_caps_unref(caps) ;
if(!link_ok)
{
g_warning("Failed to link videosrc to glimagesink!\n") ;
return -1 ;
}
/* run */
ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
if (ret == GST_STATE_CHANGE_FAILURE)
{
g_print ("Failed to start up pipeline!\n");
/* check if there is an error message with details on the bus */
GstMessage* msg = gst_bus_poll (bus, GST_MESSAGE_ERROR, 0);
if (msg)
{
GError *err = NULL;
gst_message_parse_error (msg, &err, NULL);
g_print ("ERROR: %s\n", err->message);
g_error_free (err);
gst_message_unref (msg);
}
return -1;
}
g_main_loop_run (loop);
/* clean up */
gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref (pipeline);
return 0;
}

View file

@ -0,0 +1 @@
cubeyuv

View file

@ -0,0 +1,8 @@
noinst_PROGRAMS = cubeyuv
cubeyuv_SOURCES = main.cpp
cubeyuv_CXXFLAGS=$(GST_PLUGINS_GL_CFLAGS) $(GST_CXXFLAGS) $(GL_CFLAGS)
cubeyuv_LDADD=$(GST_PLUGINS_GL_LIBS) $(GST_LIBS) $(GL_LIBS)

View file

@ -0,0 +1,202 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9,00"
Name="cubeyuv"
ProjectGUID="{6C94B86A-8E34-4163-840A-BFD5C80B1F2E}"
RootNamespace="cubeyuv"
Keyword="Win32Proj"
TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="&quot;C:\gstreamer\include\glib-2.0&quot;;&quot;C:\gstreamer\lib\glib-2.0\include&quot;;&quot;C:\gstreamer\include\gstreamer-1.0&quot;;C:\gstreamer\include\libxml2;C:\gstreamer\include"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="gstreamer-1.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib opengl32.lib glu32.lib"
LinkIncremental="2"
AdditionalLibraryDirectories="C:\gstreamer\lib"
GenerateDebugInformation="true"
SubSystem="1"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;C:\gstreamer\include\glib-2.0&quot;;&quot;C:\gstreamer\lib\glib-2.0\include&quot;;&quot;C:\gstreamer\include\gstreamer-1.0&quot;;C:\gstreamer\include\libxml2;C:\gstreamer\include"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="gstreamer-1.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib opengl32.lib glu32.lib"
LinkIncremental="1"
AdditionalLibraryDirectories="C:\gstreamer\lib"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\main.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View file

@ -0,0 +1,325 @@
/*
* GStreamer
* Copyright (C) 2008-2009 Julien Isorce <julien.isorce@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <GL/gl.h>
#include <GL/glu.h>
#if __WIN32__ || _WIN32
# include <GL/glext.h>
#endif
#include <gst/gst.h>
#include <iostream>
#include <sstream>
#include <string>
static gboolean bus_call (GstBus *bus, GstMessage *msg, gpointer data)
{
GMainLoop *loop = (GMainLoop*)data;
switch (GST_MESSAGE_TYPE (msg))
{
case GST_MESSAGE_EOS:
g_print ("End-of-stream\n");
g_main_loop_quit (loop);
break;
case GST_MESSAGE_ERROR:
{
gchar *debug = NULL;
GError *err = NULL;
gst_message_parse_error (msg, &err, &debug);
g_print ("Error: %s\n", err->message);
g_error_free (err);
if (debug)
{
g_print ("Debug deails: %s\n", debug);
g_free (debug);
}
g_main_loop_quit (loop);
break;
}
default:
break;
}
return TRUE;
}
//display video framerate
static void identityCallback (GstElement *src, GstBuffer *buffer, GstElement* textoverlay)
{
static GstClockTime last_timestamp = 0;
static gint nbFrames = 0 ;
//display estimated video FPS
nbFrames++ ;
if (GST_BUFFER_TIMESTAMP(buffer) - last_timestamp >= 1000000000)
{
std::ostringstream oss ;
oss << "video framerate = " << nbFrames ;
std::string s(oss.str()) ;
g_object_set(G_OBJECT(textoverlay), "text", s.c_str(), NULL);
last_timestamp = GST_BUFFER_TIMESTAMP(buffer) ;
nbFrames = 0 ;
}
}
//client reshape callback
static void reshapeCallback (GLuint width, GLuint height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45, (gfloat)width/(gfloat)height, 0.1, 100);
glMatrixMode(GL_MODELVIEW);
}
//client draw callback
static gboolean drawCallback (GLuint texture, GLuint width, GLuint height)
{
static GLfloat xrot = 0;
static GLfloat yrot = 0;
static GLfloat zrot = 0;
static GTimeVal current_time;
static glong last_sec = current_time.tv_sec;
static gint nbFrames = 0;
g_get_current_time (&current_time);
nbFrames++ ;
if ((current_time.tv_sec - last_sec) >= 1)
{
std::cout << "GRPHIC FPS = " << nbFrames << std::endl;
nbFrames = 0;
last_sec = current_time.tv_sec;
}
glEnable(GL_DEPTH_TEST);
glEnable (GL_TEXTURE_2D);
glBindTexture (GL_TEXTURE_2D, texture);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0f,0.0f,-5.0f);
glRotatef(xrot,1.0f,0.0f,0.0f);
glRotatef(yrot,0.0f,1.0f,0.0f);
glRotatef(zrot,0.0f,0.0f,1.0f);
glBegin(GL_QUADS);
// Front Face
glTexCoord2f((gfloat)width, 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((gfloat)width, (gfloat)height); glVertex3f(-1.0f, 1.0f, 1.0f);
// Back Face
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((gfloat)width, (gfloat)height); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f((gfloat)width, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
// Top Face
glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f((gfloat)width, 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);
// Bottom Face
glTexCoord2f((gfloat)width, 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((gfloat)width,(gfloat)height); glVertex3f(-1.0f, -1.0f, 1.0f);
// Right face
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((gfloat)width, (gfloat)height); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f((gfloat)width, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
// Left Face
glTexCoord2f((gfloat)width, 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((gfloat)width, (gfloat)height); glVertex3f(-1.0f, 1.0f, -1.0f);
glEnd();
xrot+=0.03f;
yrot+=0.02f;
zrot+=0.04f;
//return TRUE causes a postRedisplay
//so you have to return FALSE to synchronise to have a graphic FPS
//equals to the input video frame rate
//Usually, we will not always return TRUE (or FALSE)
//For example, if you want a fixed graphic FPS equals to 60
//then you have to use the timeclock to return TRUE or FALSE
//in order to increase or decrease the FPS in real time
//to reach the 60.
return TRUE;
}
static void cb_new_pad (GstElement* decodebin, GstPad* pad, GstElement* identity)
{
GstPad* identity_pad = gst_element_get_static_pad (identity, "sink");
//only link once
if (GST_PAD_IS_LINKED (identity_pad))
{
gst_object_unref (identity_pad);
return;
}
GstCaps* caps = gst_pad_get_current_caps (pad);
GstStructure* str = gst_caps_get_structure (caps, 0);
if (!g_strrstr (gst_structure_get_name (str), "video"))
{
gst_caps_unref (caps);
gst_object_unref (identity_pad);
return;
}
gst_caps_unref (caps);
GstPadLinkReturn ret = gst_pad_link (pad, identity_pad);
if (ret != GST_PAD_LINK_OK)
g_warning ("Failed to link with decodebin!\n");
}
gint main (gint argc, gchar *argv[])
{
if (argc != 2)
{
g_warning ("usage: cubeyuv.exe videolocation\n");
return -1;
}
std::string video_location(argv[1]);
/* initialization */
gst_init (&argc, &argv);
GMainLoop* loop = g_main_loop_new (NULL, FALSE);
/* create elements */
GstElement* pipeline = gst_pipeline_new ("pipeline");
/* watch for messages on the pipeline's bus (note that this will only
* work like this when a GLib main loop is running) */
GstBus* bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
gst_bus_add_watch (bus, bus_call, loop);
gst_object_unref (bus);
/* create elements */
GstElement* videosrc = gst_element_factory_make ("filesrc", "filesrc0");
GstElement* decodebin = gst_element_factory_make ("decodebin", "decodebin");
GstElement* identity = gst_element_factory_make ("identity", "identity0");
GstElement* textoverlay = gst_element_factory_make ("textoverlay", "textoverlay0");
GstElement* glcolorscale = gst_element_factory_make ("glcolorscale", "glcolorscale0");
GstElement* glimagesink = gst_element_factory_make ("glimagesink", "glimagesink0");
if (!videosrc || !decodebin || !identity || !textoverlay ||
!glcolorscale || !glimagesink)
{
g_print ("one element could not be found \n");
return -1;
}
GstCaps *outcaps = gst_caps_new_simple("video/x-raw",
"width", G_TYPE_INT, 640,
"height", G_TYPE_INT, 480,
NULL);
/* configure elements */
g_object_set(G_OBJECT(videosrc), "num-buffers", 800, NULL);
g_object_set(G_OBJECT(videosrc), "location", video_location.c_str(), NULL);
g_signal_connect(identity, "handoff", G_CALLBACK(identityCallback), textoverlay) ;
g_object_set(G_OBJECT(textoverlay), "font_desc", "Ahafoni CLM Bold 30", NULL);
g_object_set(G_OBJECT(glimagesink), "client-reshape-callback", reshapeCallback, NULL);
g_object_set(G_OBJECT(glimagesink), "client-draw-callback", drawCallback, NULL);
/* add elements */
gst_bin_add_many (GST_BIN (pipeline), videosrc, decodebin, identity,
textoverlay, glcolorscale, glimagesink, NULL);
/* link elements */
gst_element_link_pads (videosrc, "src", decodebin, "sink");
g_signal_connect (decodebin, "pad-added", G_CALLBACK (cb_new_pad), identity);
if (!gst_element_link_pads(identity, "src", textoverlay, "video_sink"))
{
g_print ("Failed to link identity to textoverlay!\n");
return -1;
}
gst_element_link (textoverlay, glcolorscale);
gboolean link_ok = gst_element_link_filtered(glcolorscale, glimagesink, outcaps) ;
gst_caps_unref(outcaps) ;
if(!link_ok)
{
g_warning("Failed to link textoverlay to glimagesink!\n") ;
return -1 ;
}
/* run */
GstStateChangeReturn ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
if (ret == GST_STATE_CHANGE_FAILURE)
{
g_print ("Failed to start up pipeline!\n");
/* check if there is an error message with details on the bus */
GstMessage* msg = gst_bus_poll (bus, GST_MESSAGE_ERROR, 0);
if (msg)
{
GError *err = NULL;
gst_message_parse_error (msg, &err, NULL);
g_print ("ERROR: %s\n", err->message);
g_error_free (err);
gst_message_unref (msg);
}
return -1;
}
g_main_loop_run (loop);
/* clean up */
gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref (pipeline);
return 0;
}

View file

@ -0,0 +1 @@
doublecube

View file

@ -0,0 +1,8 @@
noinst_PROGRAMS = doublecube
doublecube_SOURCES = main.cpp
doublecube_CXXFLAGS=$(GST_PLUGINS_GL_CFLAGS) $(GST_CXXFLAGS) $(GL_CFLAGS)
doublecube_LDADD=$(GST_PLUGINS_GL_LIBS) $(GST_LIBS) $(GL_LIBS)

View file

@ -0,0 +1,202 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9,00"
Name="doublecube"
ProjectGUID="{4EC968E0-5B6C-418A-8A75-F390D56DFFE8}"
RootNamespace="doublecube"
Keyword="Win32Proj"
TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="&quot;C:\gstreamer\include\glib-2.0&quot;;&quot;C:\gstreamer\lib\glib-2.0\include&quot;;&quot;C:\gstreamer\include\gstreamer-1.0&quot;;C:\gstreamer\include\libxml2;C:\gstreamer\include"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="gstreamer-1.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib opengl32.lib glu32.lib"
LinkIncremental="2"
AdditionalLibraryDirectories="C:\gstreamer\lib"
GenerateDebugInformation="true"
SubSystem="1"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;C:\gstreamer\include\glib-2.0&quot;;&quot;C:\gstreamer\lib\glib-2.0\include&quot;;&quot;C:\gstreamer\include\gstreamer-1.0&quot;;C:\gstreamer\include\libxml2;C:\gstreamer\include"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="gstreamer-1.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib opengl32.lib glu32.lib"
LinkIncremental="1"
AdditionalLibraryDirectories="C:\gstreamer\lib"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\main.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View file

@ -0,0 +1,368 @@
/*
* GStreamer
* Copyright (C) 2008-2009 Julien Isorce <julien.isorce@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <GL/gl.h>
#include <GL/glu.h>
#if __WIN32__ || _WIN32
# include <GL/glext.h>
#endif
#include <gst/gst.h>
#include <iostream>
#include <sstream>
#include <string>
static gboolean bus_call (GstBus *bus, GstMessage *msg, gpointer data)
{
GMainLoop *loop = (GMainLoop*)data;
switch (GST_MESSAGE_TYPE (msg))
{
case GST_MESSAGE_EOS:
g_print ("End-of-stream\n");
g_main_loop_quit (loop);
break;
case GST_MESSAGE_ERROR:
{
gchar *debug = NULL;
GError *err = NULL;
gst_message_parse_error (msg, &err, &debug);
g_print ("Error: %s\n", err->message);
g_error_free (err);
if (debug)
{
g_print ("Debug details: %s\n", debug);
g_free (debug);
}
g_main_loop_quit (loop);
break;
}
default:
break;
}
return TRUE;
}
//display video framerate
static GstPadProbeReturn textoverlay_sink_pad_probe_cb (GstPad *pad, GstPadProbeInfo *info, GstElement* textoverlay)
{
static GstClockTime last_timestamp = 0;
static gint nbFrames = 0 ;
//display estimated video FPS
nbFrames++ ;
if (GST_BUFFER_TIMESTAMP(info->data) - last_timestamp >= 1000000000)
{
std::ostringstream oss ;
oss << "video framerate = " << nbFrames ;
std::string s(oss.str()) ;
g_object_set(G_OBJECT(textoverlay), "text", s.c_str(), NULL);
last_timestamp = GST_BUFFER_TIMESTAMP(info->data) ;
nbFrames = 0 ;
}
return GST_PAD_PROBE_OK;
}
//client reshape callback
static void reshapeCallback (GLuint width, GLuint height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45, (gfloat)width/(gfloat)height, 0.1, 100);
glMatrixMode(GL_MODELVIEW);
}
//client draw callback
static gboolean drawCallback (GLuint texture, GLuint width, GLuint height)
{
static GLfloat xrot = 0;
static GLfloat yrot = 0;
static GLfloat zrot = 0;
static GTimeVal current_time;
static glong last_sec = current_time.tv_sec;
static gint nbFrames = 0;
g_get_current_time (&current_time);
nbFrames++ ;
if ((current_time.tv_sec - last_sec) >= 1)
{
std::cout << "GRAPHIC FPS of the scene which contains the custom cube) = " << nbFrames << std::endl;
nbFrames = 0;
last_sec = current_time.tv_sec;
}
glEnable(GL_DEPTH_TEST);
glEnable (GL_TEXTURE_2D);
glBindTexture (GL_TEXTURE_2D, texture);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0f,0.0f,-5.0f);
glRotatef(xrot,1.0f,0.0f,0.0f);
glRotatef(yrot,0.0f,1.0f,0.0f);
glRotatef(zrot,0.0f,0.0f,1.0f);
glBegin(GL_QUADS);
// Front Face
glTexCoord2f((gfloat)width, 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((gfloat)width, (gfloat)height); glVertex3f(-1.0f, 1.0f, 1.0f);
// Back Face
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((gfloat)width, (gfloat)height); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f((gfloat)width, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
// Top Face
glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f((gfloat)width, 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);
// Bottom Face
glTexCoord2f((gfloat)width, 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((gfloat)width,(gfloat)height); glVertex3f(-1.0f, -1.0f, 1.0f);
// Right face
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((gfloat)width, (gfloat)height); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f((gfloat)width, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
// Left Face
glTexCoord2f((gfloat)width, 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((gfloat)width, (gfloat)height); glVertex3f(-1.0f, 1.0f, -1.0f);
glEnd();
xrot+=0.03f;
yrot+=0.02f;
zrot+=0.04f;
//return TRUE causes a postRedisplay
//so you have to return FALSE to synchronise to have a graphic FPS
//equals to the input video frame rate
//Usually, we will not always return TRUE (or FALSE)
//For example, if you want a fixed graphic FPS equals to 60
//then you have to use the timeclock to return TRUE or FALSE
//in order to increase or decrease the FPS in real time
//to reach the 60.
return TRUE;
}
static void cb_new_pad (GstElement* decodebin, GstPad* pad, GstElement* element)
{
GstPad* element_pad = gst_element_get_static_pad (element, "sink");
//only link once
if (!element_pad || GST_PAD_IS_LINKED (element_pad))
{
gst_object_unref (element_pad);
return;
}
GstCaps* caps = gst_pad_get_current_caps (pad);
GstStructure* str = gst_caps_get_structure (caps, 0);
GstCaps* caps2 = gst_pad_query_caps (element_pad, NULL);
gst_caps_unref (caps2);
if (!g_strrstr (gst_structure_get_name (str), "video"))
{
gst_caps_unref (caps);
gst_object_unref (element_pad);
return;
}
gst_caps_unref (caps);
GstPadLinkReturn ret = gst_pad_link (pad, element_pad);
if (ret != GST_PAD_LINK_OK)
g_warning ("Failed to link with decodebin %d!\n", ret);
gst_object_unref (element_pad);
}
gint main (gint argc, gchar *argv[])
{
if (argc != 2)
{
g_warning ("usage: doublecube.exe videolocation\n");
return -1;
}
std::string video_location(argv[1]);
/* initialization */
gst_init (&argc, &argv);
GMainLoop* loop = g_main_loop_new (NULL, FALSE);
/* create elements */
GstElement* pipeline = gst_pipeline_new ("pipeline");
/* watch for messages on the pipeline's bus (note that this will only
* work like this when a GLib main loop is running) */
GstBus* bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
gst_bus_add_watch (bus, bus_call, loop);
gst_object_unref (bus);
/* create elements */
GstElement* videosrc = gst_element_factory_make ("filesrc", "filesrc0");
GstElement* decodebin = gst_element_factory_make ("decodebin", "decodebin0");
GstElement* videoconvert = gst_element_factory_make ("videoscale", "videoconvert0");
GstElement* textoverlay = gst_element_factory_make ("textoverlay", "textoverlay0"); //textoverlay required I420
GstElement* tee = gst_element_factory_make ("tee", "tee0");
GstElement* queue0 = gst_element_factory_make ("queue", "queue0");
GstElement* glimagesink0 = gst_element_factory_make ("glimagesink", "glimagesink0");
GstElement* queue1 = gst_element_factory_make ("queue", "queue1");
GstElement* glfiltercube = gst_element_factory_make ("glfiltercube", "glfiltercube");
GstElement* glimagesink1 = gst_element_factory_make ("glimagesink", "glimagesink1");
GstElement* queue2 = gst_element_factory_make ("queue", "queue2");
GstElement* glimagesink2 = gst_element_factory_make ("glimagesink", "glimagesink2");
if (!videosrc || !decodebin || !videoconvert || !textoverlay || !tee ||
!queue0 || !glimagesink0 ||
!queue1 || !glfiltercube || !glimagesink1 ||
!queue2 || !glimagesink2)
{
g_warning ("one element could not be found \n");
return -1;
}
GstCaps* cubecaps = gst_caps_new_simple("video/x-raw",
"width", G_TYPE_INT, 600,
"height", G_TYPE_INT, 400,
NULL);
/* configure elements */
g_object_set(G_OBJECT(videosrc), "num-buffers", 1000, NULL);
g_object_set(G_OBJECT(videosrc), "location", video_location.c_str(), NULL);
g_object_set(G_OBJECT(textoverlay), "font_desc", "Ahafoni CLM Bold 30", NULL);
g_object_set(G_OBJECT(glimagesink0), "client-reshape-callback", reshapeCallback, NULL);
g_object_set(G_OBJECT(glimagesink0), "client-draw-callback", drawCallback, NULL);
/* add elements */
gst_bin_add_many (GST_BIN (pipeline), videosrc, decodebin, videoconvert, textoverlay, tee,
queue0, glimagesink0,
queue1, glfiltercube, glimagesink1,
queue2, glimagesink2, NULL);
GstPad* textoverlay_sink_pad = gst_element_get_static_pad (textoverlay, "video_sink");
gst_pad_add_probe (textoverlay_sink_pad, GST_PAD_PROBE_TYPE_BUFFER,
(GstPadProbeCallback) textoverlay_sink_pad_probe_cb, (gpointer)textoverlay, NULL);
gst_object_unref (textoverlay_sink_pad);
if (!gst_element_link_many(videoconvert, textoverlay, tee, NULL))
{
g_print ("Failed to link videoconvert to tee!\n");
return -1;
}
if (!gst_element_link(videosrc, decodebin))
{
g_print ("Failed to link videosrc to decodebin!\n");
return -1;
}
g_signal_connect (decodebin, "pad-added", G_CALLBACK (cb_new_pad), videoconvert);
if (!gst_element_link_many(tee, queue0, NULL))
{
g_warning ("Failed to link one or more elements bettween tee and queue0!\n");
return -1;
}
gboolean link_ok = gst_element_link_filtered(queue0, glimagesink0, cubecaps) ;
gst_caps_unref(cubecaps) ;
if(!link_ok)
{
g_warning("Failed to link queue0 to glimagesink0!\n") ;
return -1 ;
}
if (!gst_element_link_many(tee, queue1, glfiltercube, glimagesink1, NULL))
{
g_warning ("Failed to link one or more elements bettween tee and glimagesink1!\n");
return -1;
}
if (!gst_element_link_many(tee, queue2, glimagesink2, NULL))
{
g_warning ("Failed to link one or more elements bettween tee and glimagesink2!\n");
return -1;
}
/* run */
GstStateChangeReturn ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
if (ret == GST_STATE_CHANGE_FAILURE)
{
g_print ("Failed to start up pipeline!\n");
/* check if there is an error message with details on the bus */
GstMessage* msg = gst_bus_poll (bus, GST_MESSAGE_ERROR, 0);
if (msg)
{
GError *err = NULL;
gst_message_parse_error (msg, &err, NULL);
g_print ("ERROR: %s\n", err->message);
g_error_free (err);
gst_message_unref (msg);
}
return -1;
}
g_main_loop_run (loop);
/* clean up */
gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref (pipeline);
return 0;
}

View file

@ -0,0 +1,38 @@

Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cube", "cube\cube.vcproj", "{DA41FBFF-E1DE-4DA1-BB96-C56C63D5CDBE}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cubeyuv", "cubeyuv\cubeyuv.vcproj", "{6C94B86A-8E34-4163-840A-BFD5C80B1F2E}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doublecube", "doublecube\doublecube.vcproj", "{4EC968E0-5B6C-418A-8A75-F390D56DFFE8}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "recordgraphic", "recordgraphic\recordgraphic.vcproj", "{E9A5E91B-5F8B-4322-9531-00CCFCB29A2D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{DA41FBFF-E1DE-4DA1-BB96-C56C63D5CDBE}.Debug|Win32.ActiveCfg = Debug|Win32
{DA41FBFF-E1DE-4DA1-BB96-C56C63D5CDBE}.Debug|Win32.Build.0 = Debug|Win32
{DA41FBFF-E1DE-4DA1-BB96-C56C63D5CDBE}.Release|Win32.ActiveCfg = Release|Win32
{DA41FBFF-E1DE-4DA1-BB96-C56C63D5CDBE}.Release|Win32.Build.0 = Release|Win32
{6C94B86A-8E34-4163-840A-BFD5C80B1F2E}.Debug|Win32.ActiveCfg = Debug|Win32
{6C94B86A-8E34-4163-840A-BFD5C80B1F2E}.Debug|Win32.Build.0 = Debug|Win32
{6C94B86A-8E34-4163-840A-BFD5C80B1F2E}.Release|Win32.ActiveCfg = Release|Win32
{6C94B86A-8E34-4163-840A-BFD5C80B1F2E}.Release|Win32.Build.0 = Release|Win32
{4EC968E0-5B6C-418A-8A75-F390D56DFFE8}.Debug|Win32.ActiveCfg = Debug|Win32
{4EC968E0-5B6C-418A-8A75-F390D56DFFE8}.Debug|Win32.Build.0 = Debug|Win32
{4EC968E0-5B6C-418A-8A75-F390D56DFFE8}.Release|Win32.ActiveCfg = Release|Win32
{4EC968E0-5B6C-418A-8A75-F390D56DFFE8}.Release|Win32.Build.0 = Release|Win32
{E9A5E91B-5F8B-4322-9531-00CCFCB29A2D}.Debug|Win32.ActiveCfg = Debug|Win32
{E9A5E91B-5F8B-4322-9531-00CCFCB29A2D}.Debug|Win32.Build.0 = Debug|Win32
{E9A5E91B-5F8B-4322-9531-00CCFCB29A2D}.Release|Win32.ActiveCfg = Release|Win32
{E9A5E91B-5F8B-4322-9531-00CCFCB29A2D}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View file

@ -0,0 +1 @@
recordgraphic

View file

@ -0,0 +1,8 @@
noinst_PROGRAMS = recordgraphic
recordgraphic_SOURCES = main.cpp
recordgraphic_CXXFLAGS=$(GST_PLUGINS_GL_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(GST_CXXFLAGS) $(GL_CFLAGS)
recordgraphic_LDADD=$(GST_PLUGINS_GL_LIBS) $(GST_PLUGINS_BASE_LIBS) -lgstvideo-@GST_API_VERSION@ $(GST_LIBS) $(GL_LIBS)

View file

@ -0,0 +1,278 @@
/*
* GStreamer
* Copyright (C) 2008-2009 Julien Isorce <julien.isorce@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <GL/gl.h>
#include <GL/glu.h>
#if __WIN32__ || _WIN32
# include <GL/glext.h>
#endif
#include <gst/gst.h>
#include <gst/video/video.h>
#include <iostream>
#include <string>
static gboolean bus_call (GstBus *bus, GstMessage *msg, gpointer data)
{
GMainLoop *loop = (GMainLoop*)data;
switch (GST_MESSAGE_TYPE (msg))
{
case GST_MESSAGE_EOS:
g_print ("End-of-stream\n");
g_main_loop_quit (loop);
break;
case GST_MESSAGE_ERROR:
{
gchar *debug = NULL;
GError *err = NULL;
gst_message_parse_error (msg, &err, &debug);
g_print ("Error: %s\n", err->message);
g_error_free (err);
if (debug)
{
g_print ("Debug details: %s\n", debug);
g_free (debug);
}
g_main_loop_quit (loop);
break;
}
default:
break;
}
return TRUE;
}
//client reshape callback
static void reshapeCallback (GLuint width, GLuint height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45, (gfloat)width/(gfloat)height, 0.1, 100);
glMatrixMode(GL_MODELVIEW);
}
//client draw callback
static gboolean drawCallback (GLuint width, GLuint height, GLuint texture, gpointer data)
{
static GLfloat xrot = 0;
static GLfloat yrot = 0;
static GLfloat zrot = 0;
static GTimeVal current_time;
static glong last_sec = current_time.tv_sec;
static gint nbFrames = 0;
g_get_current_time (&current_time);
nbFrames++ ;
if ((current_time.tv_sec - last_sec) >= 1)
{
std::cout << "GRPHIC FPS = " << nbFrames << std::endl;
nbFrames = 0;
last_sec = current_time.tv_sec;
}
glEnable(GL_DEPTH_TEST);
glEnable (GL_TEXTURE_2D);
glBindTexture (GL_TEXTURE_2D, texture);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0f,0.0f,-5.0f);
glRotatef(xrot,1.0f,0.0f,0.0f);
glRotatef(yrot,0.0f,1.0f,0.0f);
glRotatef(zrot,0.0f,0.0f,1.0f);
//cube
glBegin(GL_QUADS);
// Front Face
glTexCoord2f((gfloat)width, 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((gfloat)width, (gfloat)height); glVertex3f(-1.0f, 1.0f, 1.0f);
// Back Face
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((gfloat)width, (gfloat)height); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f((gfloat)width, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
// Top Face
glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f((gfloat)width, 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);
// Bottom Face
glTexCoord2f((gfloat)width, 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((gfloat)width,(gfloat)height); glVertex3f(-1.0f, -1.0f, 1.0f);
// Right face
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((gfloat)width, (gfloat)height); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f((gfloat)width, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
// Left Face
glTexCoord2f((gfloat)width, 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((gfloat)width, (gfloat)height); glVertex3f(-1.0f, 1.0f, -1.0f);
glEnd();
xrot+=0.3f;
yrot+=0.2f;
zrot+=0.4f;
//return TRUE causes a postRedisplay
return FALSE;
}
//equivalent command line:
//gst-launch-1.0 videotestsrc num_buffers=400 ! gleffects effect=0 !
//avenc_mpeg4 ! avimux ! filesink location="record.avi"
// or
//gst-launch-1.0 videotestsrc num_buffers=400 ! gleffects effect=0 ! "video/x-raw, width=320, height=240" ! glfiltercube ! "video/x-raw, width=720, height=576" !
//avenc_mpeg4 ! avimux ! filesink location="record.avi"
gint main (gint argc, gchar *argv[])
{
GstStateChangeReturn ret;
GstElement *pipeline, *videosrc, *glfilterapp, *avenc_mpeg4, *avimux, *filesink;
GMainLoop *loop;
GstBus *bus;
/* initialization */
gst_init (&argc, &argv);
loop = g_main_loop_new (NULL, FALSE);
/* create elements */
pipeline = gst_pipeline_new ("pipeline");
/* watch for messages on the pipeline's bus (note that this will only
* work like this when a GLib main loop is running) */
bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
gst_bus_add_watch (bus, bus_call, loop);
gst_object_unref (bus);
/* create elements */
videosrc = gst_element_factory_make ("videotestsrc", "videotestsrc0");
glfilterapp = gst_element_factory_make ("glfilterapp", "glfilterapp0");
avenc_mpeg4 = gst_element_factory_make ("avenc_mpeg4", "avenc_mpeg40");
avimux = gst_element_factory_make ("avimux", "avimux0");
filesink = gst_element_factory_make ("filesink", "filesink0");
if (!videosrc || !glfilterapp || !avenc_mpeg4 || !avimux || !filesink)
{
g_print ("one element could not be found \n");
return -1;
}
/* change video source caps */
GstCaps *caps = gst_caps_new_simple("video/x-raw",
"format", G_TYPE_STRING, "UYVY",
"width", G_TYPE_INT, 320,
"height", G_TYPE_INT, 240,
"framerate", GST_TYPE_FRACTION, 25, 1,
NULL);
/* change video source caps */
GstCaps *outcaps = gst_caps_new_simple("video/x-raw",
"width", G_TYPE_INT, 640,
"height", G_TYPE_INT, 480,
NULL);
/* configure elements */
g_object_set(G_OBJECT(videosrc), "num-buffers", 400, NULL);
g_object_set(G_OBJECT(glfilterapp), "client-reshape-callback", reshapeCallback, NULL);
g_object_set(G_OBJECT(glfilterapp), "client-draw-callback", drawCallback, NULL);
g_object_set(G_OBJECT(glfilterapp), "client-data", NULL, NULL);
g_object_set(G_OBJECT(filesink), "location", "record.avi", NULL);
/* add elements */
gst_bin_add_many (GST_BIN (pipeline), videosrc, glfilterapp,
avenc_mpeg4, avimux, filesink, NULL);
/* link elements */
gboolean link_ok = gst_element_link_filtered(videosrc, glfilterapp, caps) ;
gst_caps_unref(caps) ;
if(!link_ok)
{
g_warning("Failed to link videosrc to glfilterapp!\n") ;
return -1 ;
}
link_ok = gst_element_link_filtered(glfilterapp, avenc_mpeg4, outcaps) ;
gst_caps_unref(outcaps) ;
if(!link_ok)
{
g_warning("Failed to link glfilterapp to avenc_mpeg4!\n") ;
return -1 ;
}
if (!gst_element_link_many(avenc_mpeg4, avimux, filesink, NULL))
{
g_print ("Failed to link one or more elements!\n");
return -1;
}
/* run */
ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
if (ret == GST_STATE_CHANGE_FAILURE)
{
g_print ("Failed to start up pipeline!\n");
/* check if there is an error message with details on the bus */
GstMessage* msg = gst_bus_poll (bus, GST_MESSAGE_ERROR, 0);
if (msg)
{
GError *err = NULL;
gst_message_parse_error (msg, &err, NULL);
g_print ("ERROR: %s\n", err->message);
g_error_free (err);
gst_message_unref (msg);
}
return -1;
}
g_main_loop_run (loop);
/* clean up */
gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref (pipeline);
return 0;
}

View file

@ -0,0 +1,202 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9,00"
Name="recordgraphic"
ProjectGUID="{E9A5E91B-5F8B-4322-9531-00CCFCB29A2D}"
RootNamespace="recordgraphic"
Keyword="Win32Proj"
TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="&quot;C:\gstreamer\include\glib-2.0&quot;;&quot;C:\gstreamer\lib\glib-2.0\include&quot;;&quot;C:\gstreamer\include\gstreamer-1.0&quot;;C:\gstreamer\include\libxml2;C:\gstreamer\include"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="gstreamer-1.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib opengl32.lib glu32.lib"
LinkIncremental="2"
AdditionalLibraryDirectories="C:\gstreamer\lib"
GenerateDebugInformation="true"
SubSystem="1"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;C:\gstreamer\include\glib-2.0&quot;;&quot;C:\gstreamer\lib\glib-2.0\include&quot;;&quot;C:\gstreamer\include\gstreamer-1.0&quot;;C:\gstreamer\include\libxml2;C:\gstreamer\include"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="gstreamer-1.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib opengl32.lib glu32.lib"
LinkIncremental="1"
AdditionalLibraryDirectories="C:\gstreamer\lib"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\main.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View file

@ -0,0 +1,12 @@
SUBDIRS = . gtkvideooverlay filternovideooverlay filtervideooverlay fxtest switchvideooverlay
noinst_LTLIBRARIES = libgstgtkhelper.la
libgstgtkhelper_la_SOURCES = gstgtk.c gstgtk.h
libgstgtkhelper_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) $(GTK3_CFLAGS)
if HAVE_WINDOW_COCOA
libgstgtkhelper_la_CFLAGS += -x objective-c
endif

View file

@ -0,0 +1,27 @@
--- Description of the GTK examples ---
- gtkvideooverlay:
Show how to use the videooverlay interface through GTK.
It's possible to switch bettween GST_STATE through four buttons.
-filternovideooverlay:
A more complex pipeline is switched bettween the GST states
without using the videooverlay interface.
-filtervideooverlay:
A more complex pipeline is switched bettween the GST states.
using the videooverlay interface.
-fxtest:
switch bettween effects of the gleffects filter.
-pixbufdrop:
drag and drop a png file and overlay it using alpha channel.
It uses gloverlay filter.
-switchvideooverlay:
change the videooverlay window while the stream is playing.
--- How to build the GTK examples ---
Using autotools or using tests/examples/gtk/gtk.sln

View file

@ -0,0 +1 @@
filternovideooverlay

View file

@ -0,0 +1,18 @@
noinst_PROGRAMS = filternovideooverlay
filternovideooverlay_SOURCES = main.cpp
filternovideooverlay_CXXFLAGS= \
-I$(top_srcdir)/gst-libs \
-I$(top_builddir)/gst-libs \
$(GST_PLUGINS_BASE_CFLAGS) \
$(GST_CXXFLAGS) \
$(GL_CFLAGS) \
$(GTK3_CFLAGS)
filternovideooverlay_LDADD= \
$(GTK3_LIBS) \
$(GST_PLUGINS_BASE_LIBS) \
$(GST_LIBS) \
$(GL_LIBS)

View file

@ -0,0 +1,202 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9,00"
Name="filternovideooverlay"
ProjectGUID="{F41F3034-3E0B-4630-8D1E-35E14C606863}"
RootNamespace="filternovideooverlay"
Keyword="Win32Proj"
TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="&quot;C:\gstreamer\include\glib-2.0&quot;;&quot;C:\gstreamer\lib\glib-2.0\include&quot;;&quot;..\..\..\..\..\gtk+\include\gtk-2.0&quot;;&quot;..\..\..\..\..\gtk+\lib\gtk-2.0\include&quot;;&quot;C:\gstreamer\include\gstreamer-1.0&quot;;C:\gstreamer\include\cairo;&quot;C:\gstreamer\include\pango-1.0&quot;;&quot;..\..\..\..\..\atk\include\atk-1.0&quot;;C:\gstreamer\include\libxml2;C:\gstreamer\include"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="gstvideo-1.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib gtk-win32-2.0.lib gdk-win32-2.0.lib"
LinkIncremental="2"
AdditionalLibraryDirectories="C:\gstreamer\lib;&quot;..\..\..\..\..\gtk+\lib&quot;"
GenerateDebugInformation="true"
SubSystem="1"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;C:\gstreamer\include\glib-2.0&quot;;&quot;C:\gstreamer\lib\glib-2.0\include&quot;;&quot;..\..\..\..\..\gtk+\include\gtk-2.0&quot;;&quot;..\..\..\..\..\gtk+\lib\gtk-2.0\include&quot;;&quot;C:\gstreamer\include\gstreamer-1.0&quot;;C:\gstreamer\include\cairo;&quot;C:\gstreamer\include\pango-1.0&quot;;&quot;..\..\..\..\..\atk\include\atk-1.0&quot;;C:\gstreamer\include\libxml2;C:\gstreamer\include"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="gstreamer-1.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib gtk-win32-2.0.lib gdk-win32-2.0.lib"
LinkIncremental="1"
AdditionalLibraryDirectories="C:\gstreamer\lib;&quot;..\..\..\..\..\gtk+\lib&quot;"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\main.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View file

@ -0,0 +1,180 @@
/*
* GStreamer
* Copyright (C) 2008-2009 Julien Isorce <julien.isorce@gmail.com>
* Copyright (C) 2014 Matthew Waters <ystreet00@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <gst/gst.h>
#include <gtk/gtk.h>
#include <gdk/gdk.h>
static void end_stream_cb(GstBus* bus, GstMessage* message, GstElement* pipeline)
{
g_print("End of stream\n");
gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref(pipeline);
gtk_main_quit();
}
static void button_state_null_cb(GtkWidget* widget, GstElement* pipeline)
{
gst_element_set_state (pipeline, GST_STATE_NULL);
g_print ("GST_STATE_NULL\n");
}
static void button_state_ready_cb(GtkWidget* widget, GstElement* pipeline)
{
gst_element_set_state (pipeline, GST_STATE_READY);
g_print ("GST_STATE_READY\n");
}
static void button_state_paused_cb(GtkWidget* widget, GstElement* pipeline)
{
gst_element_set_state (pipeline, GST_STATE_PAUSED);
g_print ("GST_STATE_PAUSED\n");
}
static void button_state_playing_cb(GtkWidget* widget, GstElement* pipeline)
{
gst_element_set_state (pipeline, GST_STATE_PLAYING);
g_print ("GST_STATE_PLAYING\n");
}
static gchar* slider_fps_cb (GtkScale* scale, gdouble value, GstElement* pipeline)
{
//change the video frame rate dynamically
return g_strdup_printf ("video framerate: %0.*g", gtk_scale_get_digits (scale), value);
}
gint main (gint argc, gchar *argv[])
{
gtk_init (&argc, &argv);
gst_init (&argc, &argv);
GstElement* pipeline = gst_pipeline_new ("pipeline");
//window to control the states
GtkWidget* window_control = gtk_window_new (GTK_WINDOW_TOPLEVEL);
GdkGeometry geometry;
geometry.min_width = 1;
geometry.min_height = 1;
geometry.max_width = -1;
geometry.max_height = -1;
gtk_window_set_geometry_hints (GTK_WINDOW (window_control), window_control, &geometry, GDK_HINT_MIN_SIZE);
gtk_window_set_resizable (GTK_WINDOW (window_control), FALSE);
gtk_window_move (GTK_WINDOW (window_control), 10, 10);
GtkWidget* table = gtk_grid_new ();
gtk_container_add (GTK_CONTAINER (window_control), table);
//control state null
GtkWidget* button_state_null = gtk_button_new_with_label ("GST_STATE_NULL");
g_signal_connect (G_OBJECT (button_state_null), "clicked",
G_CALLBACK (button_state_null_cb), pipeline);
gtk_grid_attach (GTK_GRID (table), button_state_null, 0, 0, 1, 1);
gtk_widget_show (button_state_null);
//control state ready
GtkWidget* button_state_ready = gtk_button_new_with_label ("GST_STATE_READY");
g_signal_connect (G_OBJECT (button_state_ready), "clicked",
G_CALLBACK (button_state_ready_cb), pipeline);
gtk_grid_attach (GTK_GRID (table), button_state_ready, 0, 1, 1, 1);
gtk_widget_show (button_state_ready);
//control state paused
GtkWidget* button_state_paused = gtk_button_new_with_label ("GST_STATE_PAUSED");
g_signal_connect (G_OBJECT (button_state_paused), "clicked",
G_CALLBACK (button_state_paused_cb), pipeline);
gtk_grid_attach (GTK_GRID (table), button_state_paused, 0, 2, 1, 1);
gtk_widget_show (button_state_paused);
//control state playing
GtkWidget* button_state_playing = gtk_button_new_with_label ("GST_STATE_PLAYING");
g_signal_connect (G_OBJECT (button_state_playing), "clicked",
G_CALLBACK (button_state_playing_cb), pipeline);
gtk_grid_attach (GTK_GRID (table), button_state_playing, 0, 3, 1, 1);
gtk_widget_show (button_state_playing);
//change framerate
GtkWidget* slider_fps = gtk_scale_new_with_range (GTK_ORIENTATION_VERTICAL,
1, 30, 2);
g_signal_connect (G_OBJECT (slider_fps), "format-value",
G_CALLBACK (slider_fps_cb), pipeline);
gtk_grid_attach (GTK_GRID (table), slider_fps, 1, 0, 1, 3);
gtk_widget_show (slider_fps);
gtk_widget_show (table);
gtk_widget_show (window_control);
GstElement* videosrc = gst_element_factory_make ("videotestsrc", "videotestsrc");
GstElement* glfilterlaplacian = gst_element_factory_make ("glfilterblur", "glfilterblur");
GstElement* glfiltercube = gst_element_factory_make ("glfiltercube", "glfiltercube");
GstElement* videosink = gst_element_factory_make ("glimagesink", "glimagesink");
GstCaps *caps = gst_caps_new_simple("video/x-raw",
"width", G_TYPE_INT, 640,
"height", G_TYPE_INT, 480,
"framerate", GST_TYPE_FRACTION, 25, 1,
"format", G_TYPE_STRING, "YV12",
NULL) ;
gst_bin_add_many (GST_BIN (pipeline), videosrc, glfiltercube, glfilterlaplacian, videosink, NULL);
gboolean link_ok = gst_element_link_filtered(videosrc, glfiltercube, caps) ;
gst_caps_unref(caps) ;
if(!link_ok)
{
g_warning("Failed to link videosrc to glfiltercube!\n") ;
return -1;
}
if(!gst_element_link_many(glfiltercube, glfilterlaplacian, videosink, NULL))
{
g_warning("Failed to link glfiltercube to videosink!\n") ;
return -1;
}
//set window id on this event
GstBus* bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
gst_bus_add_signal_watch (bus);
g_signal_connect(bus, "message::error", G_CALLBACK(end_stream_cb), pipeline);
g_signal_connect(bus, "message::warning", G_CALLBACK(end_stream_cb), pipeline);
g_signal_connect(bus, "message::eos", G_CALLBACK(end_stream_cb), pipeline);
gst_object_unref (bus);
//start
GstStateChangeReturn ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
if (ret == GST_STATE_CHANGE_FAILURE)
{
g_print ("Failed to start up pipeline!\n");
return -1;
}
gtk_main();
return 0;
}

View file

@ -0,0 +1 @@
filtervideooverlay

View file

@ -0,0 +1,10 @@
noinst_PROGRAMS = filtervideooverlay
filtervideooverlay_SOURCES = main.cpp
filtervideooverlay_CXXFLAGS=$(GST_PLUGINS_GL_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(GST_CXXFLAGS) \
$(GL_CFLAGS) $(GTK3_CFLAGS)
filtervideooverlay_LDADD=../libgstgtkhelper.la \
$(GTK3_LIBS) $(GST_PLUGINS_GL_LIBS) $(GST_PLUGINS_BASE_LIBS) $(GST_LIBS) \
$(GL_LIBS) -lgstvideo-$(GST_API_VERSION)

View file

@ -0,0 +1,210 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9,00"
Name="filtervideooverlay"
ProjectGUID="{F9CC027E-CC9F-4B34-AA8F-58852EC32CD0}"
RootNamespace="filtervideooverlay"
Keyword="Win32Proj"
TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="&quot;C:\gstreamer\include\glib-2.0&quot;;&quot;C:\gstreamer\lib\glib-2.0\include&quot;;&quot;..\..\..\..\..\gtk+\include\gtk-2.0&quot;;&quot;..\..\..\..\..\gtk+\lib\gtk-2.0\include&quot;;&quot;C:\gstreamer\include\gstreamer-1.0&quot;;C:\gstreamer\include\cairo;&quot;C:\gstreamer\include\pango-1.0&quot;;&quot;..\..\..\..\..\atk\include\atk-1.0&quot;;C:\gstreamer\include\libxml2;C:\gstreamer\include"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="gstreamer-1.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib gtk-win32-2.0.lib gdk-win32-2.0.lib"
LinkIncremental="2"
AdditionalLibraryDirectories="C:\gstreamer\lib;&quot;..\..\..\..\..\gtk+\lib&quot;"
GenerateDebugInformation="true"
SubSystem="1"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;C:\gstreamer\include\glib-2.0&quot;;&quot;C:\gstreamer\lib\glib-2.0\include&quot;;&quot;..\..\..\..\..\gtk+\include\gtk-2.0&quot;;&quot;..\..\..\..\..\gtk+\lib\gtk-2.0\include&quot;;&quot;C:\gstreamer\include\gstreamer-1.0&quot;;C:\gstreamer\include\cairo;&quot;C:\gstreamer\include\pango-1.0&quot;;&quot;..\..\..\..\..\atk\include\atk-1.0&quot;;C:\gstreamer\include\libxml2;C:\gstreamer\include"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="gstreamer-1.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib gtk-win32-2.0.lib gdk-win32-2.0.lib"
LinkIncremental="1"
AdditionalLibraryDirectories="C:\gstreamer\lib;&quot;..\..\..\..\..\gtk+\lib&quot;"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath="..\gstgtk.c"
>
</File>
<File
RelativePath=".\main.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath="..\gstgtk.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View file

@ -0,0 +1,245 @@
/*
* GStreamer
* Copyright (C) 2008-2009 Julien Isorce <julien.isorce@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <gst/gst.h>
#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include "../gstgtk.h"
static GstBusSyncReply create_window (GstBus* bus, GstMessage* message, GtkWidget* widget)
{
// ignore anything but 'prepare-window-handle' element messages
if (GST_MESSAGE_TYPE (message) != GST_MESSAGE_ELEMENT)
return GST_BUS_PASS;
if (!gst_is_video_overlay_prepare_window_handle_message (message))
return GST_BUS_PASS;
g_print ("setting window handle %p\n", widget);
gst_video_overlay_set_gtk_window (GST_VIDEO_OVERLAY (GST_MESSAGE_SRC (message)), widget);
gst_message_unref (message);
return GST_BUS_DROP;
}
static void end_stream_cb(GstBus* bus, GstMessage* message, GstElement* pipeline)
{
g_print("End of stream\n");
gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref(pipeline);
gtk_main_quit();
}
static gboolean expose_cb(GtkWidget* widget, cairo_t *cr, GstElement* videosink)
{
gst_video_overlay_expose (GST_VIDEO_OVERLAY (videosink));
return FALSE;
}
static void destroy_cb(GtkWidget* widget, GdkEvent* event, GstElement* pipeline)
{
g_print("Close\n");
gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref(pipeline);
gtk_main_quit();
}
static void button_state_null_cb(GtkWidget* widget, GstElement* pipeline)
{
gst_element_set_state (pipeline, GST_STATE_NULL);
g_print ("GST_STATE_NULL\n");
}
static void button_state_ready_cb(GtkWidget* widget, GstElement* pipeline)
{
gst_element_set_state (pipeline, GST_STATE_READY);
g_print ("GST_STATE_READY\n");
}
static void button_state_paused_cb(GtkWidget* widget, GstElement* pipeline)
{
gst_element_set_state (pipeline, GST_STATE_PAUSED);
g_print ("GST_STATE_PAUSED\n");
}
static void button_state_playing_cb(GtkWidget* widget, GstElement* pipeline)
{
gst_element_set_state (pipeline, GST_STATE_PLAYING);
g_print ("GST_STATE_PLAYING\n");
}
static gchar* slider_fps_cb (GtkScale* scale, gdouble value, GstElement* pipeline)
{
//change the video frame rate dynamically
return g_strdup_printf ("video framerate: %0.*g", gtk_scale_get_digits (scale), value);
}
gint main (gint argc, gchar *argv[])
{
gtk_init (&argc, &argv);
gst_init (&argc, &argv);
GstElement* pipeline = gst_pipeline_new ("pipeline");
//window that contains an area where the video is drawn
GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_widget_set_size_request (window, 640, 480);
gtk_window_move (GTK_WINDOW (window), 300, 10);
gtk_window_set_title (GTK_WINDOW (window), "glimagesink implement the gstvideooverlay interface");
GdkGeometry geometry;
geometry.min_width = 1;
geometry.min_height = 1;
geometry.max_width = -1;
geometry.max_height = -1;
gtk_window_set_geometry_hints (GTK_WINDOW (window), window, &geometry, GDK_HINT_MIN_SIZE);
//window to control the states
GtkWidget* window_control = gtk_window_new (GTK_WINDOW_TOPLEVEL);
geometry.min_width = 1;
geometry.min_height = 1;
geometry.max_width = -1;
geometry.max_height = -1;
gtk_window_set_geometry_hints (GTK_WINDOW (window_control), window_control, &geometry, GDK_HINT_MIN_SIZE);
gtk_window_set_resizable (GTK_WINDOW (window_control), FALSE);
gtk_window_move (GTK_WINDOW (window_control), 10, 10);
GtkWidget* grid = gtk_grid_new ();
gtk_container_add (GTK_CONTAINER (window_control), grid);
//control state null
GtkWidget* button_state_null = gtk_button_new_with_label ("GST_STATE_NULL");
g_signal_connect (G_OBJECT (button_state_null), "clicked",
G_CALLBACK (button_state_null_cb), pipeline);
gtk_grid_attach (GTK_GRID (grid), button_state_null, 0, 1, 1, 1);
gtk_widget_show (button_state_null);
//control state ready
GtkWidget* button_state_ready = gtk_button_new_with_label ("GST_STATE_READY");
g_signal_connect (G_OBJECT (button_state_ready), "clicked",
G_CALLBACK (button_state_ready_cb), pipeline);
gtk_grid_attach (GTK_GRID (grid), button_state_ready, 0, 2, 1, 1);
gtk_widget_show (button_state_ready);
//control state paused
GtkWidget* button_state_paused = gtk_button_new_with_label ("GST_STATE_PAUSED");
g_signal_connect (G_OBJECT (button_state_paused), "clicked",
G_CALLBACK (button_state_paused_cb), pipeline);
gtk_grid_attach (GTK_GRID (grid), button_state_paused, 0, 3, 1, 1);
gtk_widget_show (button_state_paused);
//control state playing
GtkWidget* button_state_playing = gtk_button_new_with_label ("GST_STATE_PLAYING");
g_signal_connect (G_OBJECT (button_state_playing), "clicked",
G_CALLBACK (button_state_playing_cb), pipeline);
gtk_grid_attach (GTK_GRID (grid), button_state_playing, 0, 4, 1, 1);
gtk_widget_show (button_state_playing);
//change framerate
GtkWidget* slider_fps = gtk_scale_new_with_range (GTK_ORIENTATION_VERTICAL, 1, 30, 2);
g_signal_connect (G_OBJECT (slider_fps), "format-value",
G_CALLBACK (slider_fps_cb), pipeline);
gtk_grid_attach (GTK_GRID (grid), slider_fps, 1, 0, 1, 5);
gtk_widget_show (slider_fps);
gtk_widget_show (grid);
gtk_widget_show (window_control);
//configure the pipeline
g_signal_connect(G_OBJECT(window), "delete-event", G_CALLBACK(destroy_cb), pipeline);
GstElement* videosrc = gst_element_factory_make ("videotestsrc", "videotestsrc");
GstElement* glfiltercube = gst_element_factory_make ("glfiltercube", "glfiltercube");
GstElement* glfilterlaplacian = gst_element_factory_make ("glfilterlaplacian", "glfilterlaplacian");
GstElement* videosink = gst_element_factory_make ("glimagesink", "glimagesink");
GstCaps *caps = gst_caps_new_simple("video/x-raw",
"width", G_TYPE_INT, 640,
"height", G_TYPE_INT, 480,
"framerate", GST_TYPE_FRACTION, 25, 1,
"format", G_TYPE_STRING, "AYUV",
NULL) ;
gst_bin_add_many (GST_BIN (pipeline), videosrc, glfiltercube, glfilterlaplacian, videosink, NULL);
gboolean link_ok = gst_element_link_filtered(videosrc, glfiltercube, caps) ;
gst_caps_unref(caps) ;
if(!link_ok)
{
g_warning("Failed to link videosrc to glfiltercube!\n") ;
return -1;
}
if(!gst_element_link_many(glfiltercube, glfilterlaplacian, videosink, NULL))
{
g_warning("Failed to link glfiltercube to videosink!\n") ;
return -1;
}
//area where the video is drawn
GtkWidget* area = gtk_drawing_area_new();
gtk_container_add (GTK_CONTAINER (window), area);
gtk_widget_realize(area);
//set window id on this event
GstBus* bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
gst_bus_set_sync_handler (bus, (GstBusSyncHandler) create_window, area, NULL);
gst_bus_add_signal_watch (bus);
g_signal_connect(bus, "message::error", G_CALLBACK(end_stream_cb), pipeline);
g_signal_connect(bus, "message::warning", G_CALLBACK(end_stream_cb), pipeline);
g_signal_connect(bus, "message::eos", G_CALLBACK(end_stream_cb), pipeline);
gst_object_unref (bus);
//needed when being in GST_STATE_READY, GST_STATE_PAUSED
//or resizing/obscuring the window
g_signal_connect(area, "draw", G_CALLBACK(expose_cb), videosink);
//start
GstStateChangeReturn ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
if (ret == GST_STATE_CHANGE_FAILURE)
{
g_print ("Failed to start up pipeline!\n");
return -1;
}
gtk_widget_show_all (window);
gtk_main();
return 0;
}

View file

@ -0,0 +1,2 @@
fxtest
pixbufdrop

View file

@ -0,0 +1,18 @@
noinst_PROGRAMS = fxtest
noinst_PROGRAMS += pixbufdrop
fxtest_SOURCES = fxtest.c
fxtest_CFLAGS=$(GST_PLUGINS_GL_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) \
$(GL_CFLAGS) $(GTK3_CFLAGS)
fxtest_LDADD=../libgstgtkhelper.la \
$(GTK3_LIBS) $(GST_PLUGINS_GL_LIBS) $(GST_PLUGINS_BASE_LIBS) $(GST_LIBS) \
$(GL_LIBS) -lgstvideo-$(GST_API_VERSION)
pixbufdrop_SOURCES = pixbufdrop.c
pixbufdrop_CFLAGS=$(GST_PLUGINS_GL_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) \
$(GL_CFLAGS) $(GTK3_CFLAGS)
pixbufdrop_LDADD=../libgstgtkhelper.la \
$(GTK3_LIBS) $(GST_PLUGINS_GL_LIBS) $(GST_PLUGINS_BASE_LIBS) $(GST_LIBS) \
$(GL_LIBS) -lgstvideo-$(GST_API_VERSION)

View file

@ -57,7 +57,7 @@ destroy_cb (GtkWidget * widget, GdkEvent * event, GstElement * pipeline)
gtk_main_quit ();
}
gboolean
static gboolean
apply_fx (GtkWidget * widget, gpointer data)
{
gchar *fx;
@ -77,7 +77,7 @@ apply_fx (GtkWidget * widget, gpointer data)
return FALSE;
}
gboolean
static gboolean
play_cb (GtkWidget * widget, gpointer data)
{
g_message ("playing");
@ -85,7 +85,7 @@ play_cb (GtkWidget * widget, gpointer data)
return FALSE;
}
gboolean
static gboolean
null_cb (GtkWidget * widget, gpointer data)
{
g_message ("nulling");
@ -93,7 +93,7 @@ null_cb (GtkWidget * widget, gpointer data)
return FALSE;
}
gboolean
static gboolean
ready_cb (GtkWidget * widget, gpointer data)
{
g_message ("readying");
@ -101,7 +101,7 @@ ready_cb (GtkWidget * widget, gpointer data)
return FALSE;
}
gboolean
static gboolean
pause_cb (GtkWidget * widget, gpointer data)
{
g_message ("pausing");

View file

@ -0,0 +1,210 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9,00"
Name="fxtest"
ProjectGUID="{59075FDD-68CD-4F1A-948B-46D142800798}"
RootNamespace="fxtest"
Keyword="Win32Proj"
TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="&quot;C:\gstreamer\include\glib-2.0&quot;;&quot;C:\gstreamer\lib\glib-2.0\include&quot;;&quot;..\..\..\..\..\gtk+\include\gtk-2.0&quot;;&quot;..\..\..\..\..\gtk+\lib\gtk-2.0\include&quot;;&quot;C:\gstreamer\include\gstreamer-1.0&quot;;C:\gstreamer\include\cairo;&quot;C:\gstreamer\include\pango-1.0&quot;;&quot;..\..\..\..\..\atk\include\atk-1.0&quot;;C:\gstreamer\include\libxml2;C:\gstreamer\include"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="gstreamer-1.0.lib gstvideo-1.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib gtk-win32-2.0.lib gdk-win32-2.0.lib"
LinkIncremental="2"
AdditionalLibraryDirectories="C:\gstreamer\lib;&quot;..\..\..\..\..\gtk+\lib&quot;"
GenerateDebugInformation="true"
SubSystem="1"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;C:\gstreamer\include\glib-2.0&quot;;&quot;C:\gstreamer\lib\glib-2.0\include&quot;;&quot;..\..\..\..\..\gtk+\include\gtk-2.0&quot;;&quot;..\..\..\..\..\gtk+\lib\gtk-2.0\include&quot;;&quot;C:\gstreamer\include\gstreamer-1.0&quot;;C:\gstreamer\include\cairo;&quot;C:\gstreamer\include\pango-1.0&quot;;&quot;..\..\..\..\..\atk\include\atk-1.0&quot;;C:\gstreamer\include\libxml2;C:\gstreamer\include"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="gstreamer-1.0.lib gstvideo-1.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib gtk-win32-2.0.lib gdk-win32-2.0.lib"
LinkIncremental="1"
AdditionalLibraryDirectories="C:\gstreamer\lib;&quot;..\..\..\..\..\gtk+\lib&quot;"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\fxtest.c"
>
</File>
<File
RelativePath="..\gstgtk.c"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath="..\gstgtk.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View file

@ -89,7 +89,7 @@ destroy_cb (GtkWidget * widget, GdkEvent * event, GstElement * pipeline)
gtk_main_quit ();
}
gboolean
static gboolean
play_cb (GtkWidget * widget, gpointer data)
{
g_message ("playing");
@ -97,7 +97,7 @@ play_cb (GtkWidget * widget, gpointer data)
return FALSE;
}
gboolean
static gboolean
null_cb (GtkWidget * widget, gpointer data)
{
g_message ("nulling");
@ -105,7 +105,7 @@ null_cb (GtkWidget * widget, gpointer data)
return FALSE;
}
gboolean
static gboolean
ready_cb (GtkWidget * widget, gpointer data)
{
g_message ("readying");
@ -113,7 +113,7 @@ ready_cb (GtkWidget * widget, gpointer data)
return FALSE;
}
gboolean
static gboolean
pause_cb (GtkWidget * widget, gpointer data)
{
g_message ("pausing");
@ -158,7 +158,7 @@ on_drag_data_received (GtkWidget * widget,
gdk_pixbuf_format_get_name (format));
#endif
userdata->nick = "location";
userdata->nick = (gchar *) "location";
userdata->value = g_strdup (filename);
userdata->data = data;
saveddelay = delay;

View file

@ -24,13 +24,14 @@
#include <gst/gl/gl.h>
#include "gstgtk.h"
#if GST_GL_HAVE_WINDOW_WIN32 && GDK_WINDOWING_WIN32
#if GST_GL_HAVE_WINDOW_WIN32 && defined(GDK_WINDOWING_WIN32)
#include <gdk/gdkwin32.h>
#endif
#if GST_GL_HAVE_WINDOW_X11 && GDK_WINDOWING_X11
#if GST_GL_HAVE_WINDOW_X11 && defined(GDK_WINDOWING_X11)
#include <gdk/gdkx.h>
#include <gdk/x11/gdkx11display.h>
#endif
#if GST_GL_HAVE_WINDOW_COCOA && GDK_WINDOWING_QUARTZ
#if GST_GL_HAVE_WINDOW_COCOA && defined(GDK_WINDOWING_QUARTZ)
#include <gdk/gdkquartz.h>
#endif
@ -46,21 +47,21 @@ gst_video_overlay_set_gtk_window (GstVideoOverlay * videooverlay,
window = gtk_widget_get_window (widget);
display = gdk_window_get_display (window);
#if GST_GL_HAVE_WINDOW_WIN32 && GDK_WINDOWING_WIN32
#if GST_GL_HAVE_WINDOW_WIN32 && defined(GDK_WINDOWING_WIN32)
if (GDK_IS_WIN32_DISPLAY (display) && (!user_choice
|| g_strcmp0 (user_choice, "win32") == 0)) {
gst_video_overlay_set_window_handle (videooverlay,
(guintptr) GDK_WINDOW_HWND (window));
} else
#endif
#if GST_GL_HAVE_WINDOW_COCOA && GDK_WINDOWING_QUARTZ
#if GST_GL_HAVE_WINDOW_COCOA && defined(GDK_WINDOWING_QUARTZ)
if (GDK_IS_QUARTZ_DISPLAY (display) && (!user_choice
|| g_strcmp0 (user_choice, "cocoa") == 0)) {
gst_video_overlay_set_window_handle (videooverlay, (guintptr)
gdk_quartz_window_get_nswindow (window));
} else
#endif
#if GST_GL_HAVE_WINDOW_X11 && GDK_WINDOWING_X11
#if GST_GL_HAVE_WINDOW_X11 && defined(GDK_WINDOWING_X11)
if (GDK_IS_X11_DISPLAY (display) && (!user_choice
|| g_strcmp0 (user_choice, "x11") == 0)) {
gst_video_overlay_set_window_handle (videooverlay, GDK_WINDOW_XID (window));

View file

@ -0,0 +1,34 @@
/*
* GStreamer
* Copyright (C) 2009 David A. Schleef <ds@schleef.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef __GST_GTK_H__
#define __GST_GTK_H__
#include <gst/video/videooverlay.h>
#include <gtk/gtk.h>
G_BEGIN_DECLS
void gst_video_overlay_set_gtk_window (GstVideoOverlay *videooverlay, GtkWidget *window);
G_END_DECLS
#endif

View file

@ -0,0 +1,50 @@

Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "filtervideooverlay", "filtervideooverlay\filtervideooverlay.vcproj", "{F9CC027E-CC9F-4B34-AA8F-58852EC32CD0}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtkvideooverlay", "gtkvideooverlay\gtkvideooverlay.vcproj", "{E83070C2-58E4-48AE-AEB3-A4580EDE1212}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fxtest", "fxtest\fxtest.vcproj", "{59075FDD-68CD-4F1A-948B-46D142800798}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pixbufdrop", "pixbufdrop\pixbufdrop.vcproj", "{09F68B62-1D4C-4C24-A6AD-AA76A9F3237C}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "filternovideooverlay", "filternovideooverlay\filternovideooverlay.vcproj", "{F41F3034-3E0B-4630-8D1E-35E14C606863}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "switchvideooverlay", "switchvideooverlay\switchvideooverlay.vcproj", "{BA78B4B4-3268-483E-9676-911E29FD2C69}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{F9CC027E-CC9F-4B34-AA8F-58852EC32CD0}.Debug|Win32.ActiveCfg = Debug|Win32
{F9CC027E-CC9F-4B34-AA8F-58852EC32CD0}.Debug|Win32.Build.0 = Debug|Win32
{F9CC027E-CC9F-4B34-AA8F-58852EC32CD0}.Release|Win32.ActiveCfg = Release|Win32
{F9CC027E-CC9F-4B34-AA8F-58852EC32CD0}.Release|Win32.Build.0 = Release|Win32
{E83070C2-58E4-48AE-AEB3-A4580EDE1212}.Debug|Win32.ActiveCfg = Debug|Win32
{E83070C2-58E4-48AE-AEB3-A4580EDE1212}.Debug|Win32.Build.0 = Debug|Win32
{E83070C2-58E4-48AE-AEB3-A4580EDE1212}.Release|Win32.ActiveCfg = Release|Win32
{E83070C2-58E4-48AE-AEB3-A4580EDE1212}.Release|Win32.Build.0 = Release|Win32
{59075FDD-68CD-4F1A-948B-46D142800798}.Debug|Win32.ActiveCfg = Debug|Win32
{59075FDD-68CD-4F1A-948B-46D142800798}.Debug|Win32.Build.0 = Debug|Win32
{59075FDD-68CD-4F1A-948B-46D142800798}.Release|Win32.ActiveCfg = Release|Win32
{59075FDD-68CD-4F1A-948B-46D142800798}.Release|Win32.Build.0 = Release|Win32
{09F68B62-1D4C-4C24-A6AD-AA76A9F3237C}.Debug|Win32.ActiveCfg = Debug|Win32
{09F68B62-1D4C-4C24-A6AD-AA76A9F3237C}.Debug|Win32.Build.0 = Debug|Win32
{09F68B62-1D4C-4C24-A6AD-AA76A9F3237C}.Release|Win32.ActiveCfg = Release|Win32
{09F68B62-1D4C-4C24-A6AD-AA76A9F3237C}.Release|Win32.Build.0 = Release|Win32
{F41F3034-3E0B-4630-8D1E-35E14C606863}.Debug|Win32.ActiveCfg = Debug|Win32
{F41F3034-3E0B-4630-8D1E-35E14C606863}.Debug|Win32.Build.0 = Debug|Win32
{F41F3034-3E0B-4630-8D1E-35E14C606863}.Release|Win32.ActiveCfg = Release|Win32
{F41F3034-3E0B-4630-8D1E-35E14C606863}.Release|Win32.Build.0 = Release|Win32
{BA78B4B4-3268-483E-9676-911E29FD2C69}.Debug|Win32.ActiveCfg = Debug|Win32
{BA78B4B4-3268-483E-9676-911E29FD2C69}.Debug|Win32.Build.0 = Debug|Win32
{BA78B4B4-3268-483E-9676-911E29FD2C69}.Release|Win32.ActiveCfg = Release|Win32
{BA78B4B4-3268-483E-9676-911E29FD2C69}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View file

@ -0,0 +1 @@
gtkvideooverlay

View file

@ -0,0 +1,10 @@
noinst_PROGRAMS = gtkvideooverlay
gtkvideooverlay_SOURCES = main.cpp
gtkvideooverlay_CXXFLAGS=$(GST_PLUGINS_GL_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(GST_CXXFLAGS) \
$(GL_CFLAGS) $(GTK3_CFLAGS)
gtkvideooverlay_LDADD=../libgstgtkhelper.la \
$(GTK3_LIBS) $(GST_PLUGINS_GL_LIBS) $(GST_PLUGINS_BASE_LIBS) $(GST_LIBS) \
$(GL_LIBS) -lgstvideo-$(GST_API_VERSION)

View file

@ -0,0 +1,210 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9,00"
Name="gtkvideooverlay"
ProjectGUID="{E83070C2-58E4-48AE-AEB3-A4580EDE1212}"
RootNamespace="filtervideooverlay"
Keyword="Win32Proj"
TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="&quot;C:\gstreamer\include\glib-2.0&quot;;&quot;C:\gstreamer\lib\glib-2.0\include&quot;;&quot;..\..\..\..\..\gtk+\include\gtk-2.0&quot;;&quot;..\..\..\..\..\gtk+\lib\gtk-2.0\include&quot;;&quot;C:\gstreamer\include\gstreamer-1.0&quot;;C:\gstreamer\include\cairo;&quot;C:\gstreamer\include\pango-1.0&quot;;&quot;..\..\..\..\..\atk\include\atk-1.0&quot;;C:\gstreamer\include\libxml2;C:\gstreamer\include"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="gstreamer-1.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib gtk-win32-2.0.lib gdk-win32-2.0.lib"
LinkIncremental="2"
AdditionalLibraryDirectories="C:\gstreamer\lib;&quot;..\..\..\..\..\gtk+\lib&quot;"
GenerateDebugInformation="true"
SubSystem="1"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;C:\gstreamer\include\glib-2.0&quot;;&quot;C:\gstreamer\lib\glib-2.0\include&quot;;&quot;..\..\..\..\..\gtk+\include\gtk-2.0&quot;;&quot;..\..\..\..\..\gtk+\lib\gtk-2.0\include&quot;;&quot;C:\gstreamer\include\gstreamer-1.0&quot;;C:\gstreamer\include\cairo;&quot;C:\gstreamer\include\pango-1.0&quot;;&quot;..\..\..\..\..\atk\include\atk-1.0&quot;;C:\gstreamer\include\libxml2;C:\gstreamer\include"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="gstreamer-1.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib gtk-win32-2.0.lib gdk-win32-2.0.lib"
LinkIncremental="1"
AdditionalLibraryDirectories="C:\gstreamer\lib;&quot;..\..\..\..\..\gtk+\lib&quot;"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath="..\gstgtk.c"
>
</File>
<File
RelativePath=".\main.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath="..\gstgtk.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View file

@ -0,0 +1,230 @@
/*
* GStreamer
* Copyright (C) 2008-2009 Julien Isorce <julien.isorce@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <gst/gst.h>
#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include "../gstgtk.h"
static GstBusSyncReply create_window (GstBus* bus, GstMessage* message, GtkWidget* widget)
{
// ignore anything but 'prepare-window-handle' element messages
if (GST_MESSAGE_TYPE (message) != GST_MESSAGE_ELEMENT)
return GST_BUS_PASS;
if (!gst_is_video_overlay_prepare_window_handle_message (message))
return GST_BUS_PASS;
g_print ("setting window handle\n");
//do not call gdk_window_ensure_native for the first time here because
//we are in a different thread than the main thread
//(and the main thread the onne)
gst_video_overlay_set_gtk_window (GST_VIDEO_OVERLAY (GST_MESSAGE_SRC (message)), widget);
gst_message_unref (message);
return GST_BUS_DROP;
}
static void end_stream_cb(GstBus* bus, GstMessage* message, GstElement* pipeline)
{
g_print("End of stream\n");
gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref(pipeline);
gtk_main_quit();
}
static gboolean draw_cb(GtkWidget* widget, cairo_t *cr, GstElement* videosink)
{
g_print ("draw_cb\n");
gst_video_overlay_expose (GST_VIDEO_OVERLAY (videosink));
return FALSE;
}
static void destroy_cb(GtkWidget* widget, GdkEvent* event, GstElement* pipeline)
{
g_print("Close\n");
gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref(pipeline);
gtk_main_quit();
}
static void button_state_null_cb(GtkWidget* widget, GstElement* pipeline)
{
gst_element_set_state (pipeline, GST_STATE_NULL);
g_print ("GST_STATE_NULL\n");
}
static void button_state_ready_cb(GtkWidget* widget, GstElement* pipeline)
{
gst_element_set_state (pipeline, GST_STATE_READY);
g_print ("GST_STATE_READY\n");
}
static void button_state_paused_cb(GtkWidget* widget, GstElement* pipeline)
{
gst_element_set_state (pipeline, GST_STATE_PAUSED);
g_print ("GST_STATE_PAUSED\n");
}
static void button_state_playing_cb(GtkWidget* widget, GstElement* pipeline)
{
gst_element_set_state (pipeline, GST_STATE_PLAYING);
g_print ("GST_STATE_PLAYING\n");
}
static gchar* slider_fps_cb (GtkScale* scale, gdouble value, GstElement* pipeline)
{
//change the video frame rate dynamically
return g_strdup_printf ("video framerate: %0.*g", gtk_scale_get_digits (scale), value);
}
gint main (gint argc, gchar *argv[])
{
GtkWidget *area;
gst_init (&argc, &argv);
gtk_init (&argc, &argv);
GstElement* pipeline = gst_pipeline_new ("pipeline");
GstElement* videosrc = gst_element_factory_make ("videotestsrc", "videotestsrc");
GstElement* videosink = gst_element_factory_make ("glimagesink", "glimagesink");
gst_bin_add_many (GST_BIN (pipeline), videosrc, videosink, NULL);
gboolean link_ok = gst_element_link_many(videosrc, videosink, NULL) ;
if(!link_ok)
{
g_warning("Failed to link an element!\n") ;
return -1;
}
//set window id on this event
GstBus* bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
gst_bus_add_signal_watch (bus);
g_signal_connect(bus, "message::error", G_CALLBACK(end_stream_cb), pipeline);
g_signal_connect(bus, "message::warning", G_CALLBACK(end_stream_cb), pipeline);
g_signal_connect(bus, "message::eos", G_CALLBACK(end_stream_cb), pipeline);
gst_element_set_state(pipeline, GST_STATE_READY);
area = gtk_drawing_area_new();
gst_bus_set_sync_handler (bus, (GstBusSyncHandler) create_window, area, NULL);
gst_object_unref (bus);
//window that contains an area where the video is drawn
GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_widget_set_size_request (window, 640, 480);
gtk_window_move (GTK_WINDOW (window), 300, 10);
gtk_window_set_title (GTK_WINDOW (window), "glimagesink implement the gstvideooverlay interface");
GdkGeometry geometry;
geometry.min_width = 1;
geometry.min_height = 1;
geometry.max_width = -1;
geometry.max_height = -1;
gtk_window_set_geometry_hints (GTK_WINDOW (window), window, &geometry, GDK_HINT_MIN_SIZE);
//window to control the states
GtkWidget* window_control = gtk_window_new (GTK_WINDOW_TOPLEVEL);
geometry.min_width = 1;
geometry.min_height = 1;
geometry.max_width = -1;
geometry.max_height = -1;
gtk_window_set_geometry_hints (GTK_WINDOW (window_control), window_control, &geometry, GDK_HINT_MIN_SIZE);
gtk_window_set_resizable (GTK_WINDOW (window_control), FALSE);
gtk_window_move (GTK_WINDOW (window_control), 10, 10);
GtkWidget* table = gtk_grid_new ();
gtk_container_add (GTK_CONTAINER (window_control), table);
//control state null
GtkWidget* button_state_null = gtk_button_new_with_label ("GST_STATE_NULL");
g_signal_connect (G_OBJECT (button_state_null), "clicked",
G_CALLBACK (button_state_null_cb), pipeline);
gtk_grid_attach (GTK_GRID (table), button_state_null, 0, 0, 1, 1);
gtk_widget_show (button_state_null);
//control state ready
GtkWidget* button_state_ready = gtk_button_new_with_label ("GST_STATE_READY");
g_signal_connect (G_OBJECT (button_state_ready), "clicked",
G_CALLBACK (button_state_ready_cb), pipeline);
gtk_grid_attach (GTK_GRID (table), button_state_ready, 0, 1, 1, 1);
gtk_widget_show (button_state_ready);
//control state paused
GtkWidget* button_state_paused = gtk_button_new_with_label ("GST_STATE_PAUSED");
g_signal_connect (G_OBJECT (button_state_paused), "clicked",
G_CALLBACK (button_state_paused_cb), pipeline);
gtk_grid_attach (GTK_GRID (table), button_state_paused, 0, 2, 1, 1);
gtk_widget_show (button_state_paused);
//control state playing
GtkWidget* button_state_playing = gtk_button_new_with_label ("GST_STATE_PLAYING");
g_signal_connect (G_OBJECT (button_state_playing), "clicked",
G_CALLBACK (button_state_playing_cb), pipeline);
gtk_grid_attach (GTK_GRID (table), button_state_playing, 0, 3, 1, 1);
gtk_widget_show (button_state_playing);
//change framerate
GtkWidget* slider_fps = gtk_scale_new_with_range (GTK_ORIENTATION_VERTICAL,
1, 30, 2);
g_signal_connect (G_OBJECT (slider_fps), "format-value",
G_CALLBACK (slider_fps_cb), pipeline);
gtk_grid_attach (GTK_GRID (table), slider_fps, 1, 0, 1, 4);
gtk_widget_show (slider_fps);
gtk_widget_show (table);
gtk_widget_show (window_control);
//configure the pipeline
g_signal_connect(G_OBJECT(window), "delete-event", G_CALLBACK(destroy_cb), pipeline);
//area where the video is drawn
gtk_container_add (GTK_CONTAINER (window), area);
gtk_widget_realize(area);
//needed when being in GST_STATE_READY, GST_STATE_PAUSED
//or resizing/obscuring the window
g_signal_connect(area, "draw", G_CALLBACK(draw_cb), videosink);
gtk_widget_show_all (window);
gst_element_set_state(pipeline, GST_STATE_PLAYING);
gtk_main();
return 0;
}

View file

@ -0,0 +1,210 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9,00"
Name="pixbufdrop"
ProjectGUID="{09F68B62-1D4C-4C24-A6AD-AA76A9F3237C}"
RootNamespace="pixbufdrop"
Keyword="Win32Proj"
TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="&quot;C:\gstreamer\include\glib-2.0&quot;;&quot;C:\gstreamer\lib\glib-2.0\include&quot;;&quot;..\..\..\..\..\gtk+\include\gtk-2.0&quot;;&quot;..\..\..\..\..\gtk+\lib\gtk-2.0\include&quot;;&quot;C:\gstreamer\include\gstreamer-1.0&quot;;C:\gstreamer\include\cairo;&quot;C:\gstreamer\include\pango-1.0&quot;;&quot;..\..\..\..\..\atk\include\atk-1.0&quot;;C:\gstreamer\include\libxml2;C:\gstreamer\include"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="gstreamer-1.0.lib gstvideo-1.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib gtk-win32-2.0.lib gdk-win32-2.0.lib gdk_pixbuf-2.0.lib"
LinkIncremental="2"
AdditionalLibraryDirectories="C:\gstreamer\lib;&quot;..\..\..\..\..\gtk+\lib&quot;"
GenerateDebugInformation="true"
SubSystem="1"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;C:\gstreamer\include\glib-2.0&quot;;&quot;C:\gstreamer\lib\glib-2.0\include&quot;;&quot;..\..\..\..\..\gtk+\include\gtk-2.0&quot;;&quot;..\..\..\..\..\gtk+\lib\gtk-2.0\include&quot;;&quot;C:\gstreamer\include\gstreamer-1.0&quot;;C:\gstreamer\include\cairo;&quot;C:\gstreamer\include\pango-1.0&quot;;&quot;..\..\..\..\..\atk\include\atk-1.0&quot;;C:\gstreamer\include\libxml2;C:\gstreamer\include"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="gstreamer-1.0.lib gstvideo-1.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib gtk-win32-2.0.lib gdk-win32-2.0.lib gdk_pixbuf-2.0.lib"
LinkIncremental="1"
AdditionalLibraryDirectories="C:\gstreamer\lib;&quot;..\..\..\..\..\gtk+\lib&quot;"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath="..\gstgtk.c"
>
</File>
<File
RelativePath="..\fxtest\pixbufdrop.c"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath="..\gstgtk.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View file

@ -0,0 +1 @@
switchvideooverlay

View file

@ -0,0 +1,10 @@
noinst_PROGRAMS = switchvideooverlay
switchvideooverlay_SOURCES = main.cpp
switchvideooverlay_CXXFLAGS=$(GST_PLUGINS_GL_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(GST_CXXFLAGS) \
$(GL_CFLAGS) $(GTK3_CFLAGS)
switchvideooverlay_LDADD=../libgstgtkhelper.la \
$(GTK3_LIBS) $(GST_PLUGINS_GL_LIBS) $(GST_PLUGINS_BASE_LIBS) $(GST_LIBS) \
$(GL_LIBS) -lgstvideo-$(GST_API_VERSION)

View file

@ -0,0 +1,246 @@
/*
* GStreamer
* Copyright (C) 2008-2009 Julien Isorce <julien.isorce@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <gst/gst.h>
#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include "../gstgtk.h"
static GstBusSyncReply create_window (GstBus* bus, GstMessage* message, GtkWidget* widget)
{
// ignore anything but 'prepare-window-handle' element messages
if (GST_MESSAGE_TYPE (message) != GST_MESSAGE_ELEMENT)
return GST_BUS_PASS;
if (!gst_is_video_overlay_prepare_window_handle_message (message))
return GST_BUS_PASS;
g_print ("setting window handle %p\n", widget);
gst_video_overlay_set_gtk_window (GST_VIDEO_OVERLAY (GST_MESSAGE_SRC (message)), widget);
gst_message_unref (message);
return GST_BUS_DROP;
}
static void end_stream_cb(GstBus* bus, GstMessage* message, GstElement* pipeline)
{
g_print("End of stream\n");
gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref(pipeline);
gtk_main_quit();
}
static gboolean expose_cb(GtkWidget* widget, cairo_t *cr, GstElement* videosink)
{
g_print ("expose %p\n", widget);
g_print ("event mask: 0x%x, button_press 0x%x\n", gtk_widget_get_events (widget), GDK_BUTTON_PRESS_MASK);
gst_video_overlay_expose (GST_VIDEO_OVERLAY (videosink));
return FALSE;
}
static gboolean on_click_drawing_area(GtkWidget* widget, GdkEventButton* event, GstElement* videosink)
{
g_print ("switch the drawing area %p\n", widget);
gst_video_overlay_set_gtk_window (GST_VIDEO_OVERLAY (videosink), widget);
gst_video_overlay_expose (GST_VIDEO_OVERLAY (videosink));
return FALSE;
}
static void destroy_cb(GtkWidget* widget, GdkEvent* event, GstElement* pipeline)
{
g_print("Close\n");
gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref(pipeline);
gtk_main_quit();
}
static void button_state_null_cb(GtkWidget* widget, GstElement* pipeline)
{
gst_element_set_state (pipeline, GST_STATE_NULL);
g_print ("GST_STATE_NULL\n");
}
static void button_state_ready_cb(GtkWidget* widget, GstElement* pipeline)
{
gst_element_set_state (pipeline, GST_STATE_READY);
g_print ("GST_STATE_READY\n");
}
static void button_state_paused_cb(GtkWidget* widget, GstElement* pipeline)
{
gst_element_set_state (pipeline, GST_STATE_PAUSED);
g_print ("GST_STATE_PAUSED\n");
}
static void button_state_playing_cb(GtkWidget* widget, GstElement* pipeline)
{
gst_element_set_state (pipeline, GST_STATE_PLAYING);
g_print ("GST_STATE_PLAYING\n");
}
static void area_realize_cb(GtkWidget* widget, gpointer data)
{
g_print ("realize %p\n", widget);
if (!gdk_window_ensure_native (gtk_widget_get_window (widget)))
g_error ("Failed to create native window!");
//avoid flickering when resizing or obscuring the main window
gtk_widget_set_app_paintable(widget, TRUE);
gtk_widget_set_double_buffered(widget, FALSE);
}
gint main (gint argc, gchar *argv[])
{
gtk_init (&argc, &argv);
gst_init (&argc, &argv);
GstElement* pipeline = gst_pipeline_new ("pipeline");
//window that contains several ares where the video is drawn
GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_widget_set_size_request (window, 640, 240);
gtk_window_move (GTK_WINDOW (window), 300, 10);
gtk_window_set_title (GTK_WINDOW (window), "click on left, right or outside the main window to switch the drawing area");
GdkGeometry geometry;
geometry.min_width = 1;
geometry.min_height = 1;
geometry.max_width = -1;
geometry.max_height = -1;
gtk_window_set_geometry_hints (GTK_WINDOW (window), window, &geometry, GDK_HINT_MIN_SIZE);
//window to control the states
GtkWidget* window_control = gtk_window_new (GTK_WINDOW_TOPLEVEL);
geometry.min_width = 1;
geometry.min_height = 1;
geometry.max_width = -1;
geometry.max_height = -1;
gtk_window_set_geometry_hints (GTK_WINDOW (window_control), window_control, &geometry, GDK_HINT_MIN_SIZE);
gtk_window_set_resizable (GTK_WINDOW (window_control), FALSE);
gtk_window_move (GTK_WINDOW (window_control), 10, 10);
GtkWidget* table = gtk_grid_new ();
gtk_container_add (GTK_CONTAINER (window_control), table);
//control state null
GtkWidget* button_state_null = gtk_button_new_with_label ("GST_STATE_NULL");
g_signal_connect (G_OBJECT (button_state_null), "clicked",
G_CALLBACK (button_state_null_cb), pipeline);
gtk_grid_attach (GTK_GRID (table), button_state_null, 0, 0, 1, 1);
gtk_widget_show (button_state_null);
//control state ready
GtkWidget* button_state_ready = gtk_button_new_with_label ("GST_STATE_READY");
g_signal_connect (G_OBJECT (button_state_ready), "clicked",
G_CALLBACK (button_state_ready_cb), pipeline);
gtk_grid_attach (GTK_GRID (table), button_state_ready, 0, 1, 1, 1);
gtk_widget_show (button_state_ready);
//control state paused
GtkWidget* button_state_paused = gtk_button_new_with_label ("GST_STATE_PAUSED");
g_signal_connect (G_OBJECT (button_state_paused), "clicked",
G_CALLBACK (button_state_paused_cb), pipeline);
gtk_grid_attach (GTK_GRID (table), button_state_paused, 0, 2, 1, 1);
gtk_widget_show (button_state_paused);
//control state playing
GtkWidget* button_state_playing = gtk_button_new_with_label ("GST_STATE_PLAYING");
g_signal_connect (G_OBJECT (button_state_playing), "clicked",
G_CALLBACK (button_state_playing_cb), pipeline);
gtk_grid_attach (GTK_GRID (table), button_state_playing, 0, 3, 1, 1);
gtk_widget_show (button_state_playing);
gtk_widget_show (table);
gtk_widget_show (window_control);
//configure the pipeline
g_signal_connect(G_OBJECT(window), "delete-event", G_CALLBACK(destroy_cb), pipeline);
GstElement* videosrc = gst_element_factory_make ("videotestsrc", "videotestsrc");
GstElement* videosink = gst_element_factory_make ("glimagesink", "glimagesink");
gst_bin_add_many (GST_BIN (pipeline), videosrc, videosink, NULL);
gboolean link_ok = gst_element_link_many(videosrc, videosink, NULL);
if(!link_ok)
{
g_warning("Failed to link videosrc to videosink!\n") ;
return -1;
}
//areas where the video is drawn
GtkWidget* table_areas = gtk_grid_new ();
gtk_container_add (GTK_CONTAINER (window), table_areas);
GtkWidget* area_top_left = gtk_drawing_area_new();
gtk_widget_add_events(area_top_left, GDK_BUTTON_PRESS_MASK);
gtk_widget_set_size_request (area_top_left, 320, 240);
gtk_grid_attach (GTK_GRID (table_areas), area_top_left, 0, 0, 1, 1);
GtkWidget* area_top_right = gtk_drawing_area_new();
gtk_widget_add_events(area_top_right, GDK_BUTTON_PRESS_MASK);
gtk_widget_set_size_request (area_top_right, 320, 240);
gtk_grid_attach (GTK_GRID (table_areas), area_top_right, 1, 0, 1, 1);
//set window id on this event
g_signal_connect(area_top_left, "realize", G_CALLBACK(area_realize_cb), NULL);
g_signal_connect(area_top_right, "realize", G_CALLBACK(area_realize_cb), NULL);
gtk_widget_realize(area_top_left);
gtk_widget_realize(area_top_right);
GstBus* bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
gst_bus_set_sync_handler (bus, (GstBusSyncHandler) create_window, area_top_right, NULL);
gst_bus_add_signal_watch (bus);
g_signal_connect(bus, "message::error", G_CALLBACK(end_stream_cb), pipeline);
g_signal_connect(bus, "message::warning", G_CALLBACK(end_stream_cb), pipeline);
g_signal_connect(bus, "message::eos", G_CALLBACK(end_stream_cb), pipeline);
gst_object_unref (bus);
//needed when being in GST_STATE_READY, GST_STATE_PAUSED
//or resizing/obscuring the window
g_signal_connect(area_top_left, "draw", G_CALLBACK(expose_cb), videosink);
g_signal_connect(area_top_right, "draw", G_CALLBACK(expose_cb), videosink);
//switch the drawing area
g_signal_connect(area_top_left, "button-press-event", G_CALLBACK(on_click_drawing_area), videosink);
g_signal_connect(area_top_right, "button-press-event", G_CALLBACK(on_click_drawing_area), videosink);
gtk_widget_show_all (window);
gst_element_set_state(pipeline, GST_STATE_PLAYING);
gtk_main();
return 0;
}

View file

@ -0,0 +1,210 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9,00"
Name="switchvideooverlay"
ProjectGUID="{BA78B4B4-3268-483E-9676-911E29FD2C69}"
RootNamespace="filtervideooverlay"
Keyword="Win32Proj"
TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="&quot;C:\gstreamer\include\glib-2.0&quot;;&quot;C:\gstreamer\lib\glib-2.0\include&quot;;&quot;..\..\..\..\..\gtk+\include\gtk-2.0&quot;;&quot;..\..\..\..\..\gtk+\lib\gtk-2.0\include&quot;;&quot;C:\gstreamer\include\gstreamer-1.0&quot;;C:\gstreamer\include\cairo;&quot;C:\gstreamer\include\pango-1.0&quot;;&quot;..\..\..\..\..\atk\include\atk-1.0&quot;;C:\gstreamer\include\libxml2;C:\gstreamer\include"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="gstreamer-1.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib gtk-win32-2.0.lib gdk-win32-2.0.lib"
LinkIncremental="2"
AdditionalLibraryDirectories="C:\gstreamer\lib;&quot;..\..\..\..\..\gtk+\lib&quot;"
GenerateDebugInformation="true"
SubSystem="1"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;C:\gstreamer\include\glib-2.0&quot;;&quot;C:\gstreamer\lib\glib-2.0\include&quot;;&quot;..\..\..\..\..\gtk+\include\gtk-2.0&quot;;&quot;..\..\..\..\..\gtk+\lib\gtk-2.0\include&quot;;&quot;C:\gstreamer\include\gstreamer-1.0&quot;;C:\gstreamer\include\cairo;&quot;C:\gstreamer\include\pango-1.0&quot;;&quot;..\..\..\..\..\atk\include\atk-1.0&quot;;C:\gstreamer\include\libxml2;C:\gstreamer\include"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="gstreamer-1.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib gtk-win32-2.0.lib gdk-win32-2.0.lib"
LinkIncremental="1"
AdditionalLibraryDirectories="C:\gstreamer\lib;&quot;..\..\..\..\..\gtk+\lib&quot;"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath="..\gstgtk.c"
>
</File>
<File
RelativePath=".\main.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath="..\gstgtk.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View file

@ -0,0 +1,2 @@
#SUBDIRS = videooverlay qglwidgetvideooverlay mousevideooverlay

View file

@ -0,0 +1,23 @@
--- Description of the Qt examples ---
- mousevideooverlay:
Show how to use the videooverlay interface through Qt.
The cube is rotating when moving the mouse (+ click maintained)
- qglvideooverlay:
Show how to use the videooverlay interface through Qt.
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 ---
sudo apt-get install g++
sudo apt-get install libqt4-dev
cd qglvideooverlay
qmake
make
./debug/qglvideooverlay

View file

@ -0,0 +1,67 @@
/*
* GStreamer
* Copyright (C) 2008-2009 Julien Isorce <julien.isorce@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "gstthread.h"
GstThread::GstThread(const WId winId, const QString videoLocation, QObject *parent):
QThread(parent),
m_winId(winId),
m_videoLocation(videoLocation)
{
}
GstThread::~GstThread()
{
}
void GstThread::exposeRequested()
{
m_pipeline->exposeRequested();
}
void GstThread::onMouseMove()
{
m_pipeline->rotateRequested();
}
void GstThread::show()
{
emit showRequested();
}
void GstThread::stop()
{
m_pipeline->stop();
}
void GstThread::run()
{
m_pipeline = new Pipeline(m_winId, m_videoLocation);
connect(m_pipeline, SIGNAL(showRequested()), this, SLOT(show()));
m_pipeline->start(); //it runs the gmainloop on win32
#ifndef WIN32
//works like the gmainloop on linux (GstEvent are handled)
connect(m_pipeline, SIGNAL(stopRequested()), this, SLOT(quit()));
exec();
#endif
m_pipeline->unconfigure();
}

View file

@ -0,0 +1,56 @@
/*
* GStreamer
* Copyright (C) 2008-2009 Julien Isorce <julien.isorce@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef GSTTHREAD_H
#define GSTTHREAD_H
#include <QtGui>
#include <QtCore/QThread>
#include "pipeline.h"
class GstThread : public QThread
{
Q_OBJECT
public:
GstThread(const WId winId, const QString videoLocation, QObject *parent = 0);
~GstThread();
public slots:
void exposeRequested();
void onMouseMove();
void show();
void stop();
signals:
void showRequested();
protected:
void run();
private:
const WId m_winId;
const QString m_videoLocation;
Pipeline* m_pipeline;
};
#endif

View file

@ -0,0 +1,39 @@
/*
* GStreamer
* Copyright (C) 2008-2009 Julien Isorce <julien.isorce@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <QGuiApplication>
#include "qrenderer.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
a.connect(&a, SIGNAL(lastWindowClosed()), &a, SLOT(quit()));
QString videolcoation = QFileDialog::getOpenFileName(0, "Select a video file",
".", "Format (*.avi *.mkv *.ogg *.asf *.mov)");
if (videolcoation.isEmpty())
return -1;
QRenderer w(videolcoation);
w.setWindowTitle("glimagesink implements the gstvideooverlay interface");
return a.exec();
}

View file

@ -0,0 +1,10 @@
#Header files
HEADERS += ./gstthread.h \
./pipeline.h \
./qrenderer.h
#Source files
SOURCES += ./gstthread.cpp \
./main.cpp \
./pipeline.cpp \
./qrenderer.cpp

View file

@ -0,0 +1,54 @@
TEMPLATE = app
TARGET = mousevideooverlay
DESTDIR = ./debug
CONFIG += debug gui widget
DEFINES += UNICODE
win32 {
DEFINES += WIN32
INCLUDEPATH += ./GeneratedFiles \
./GeneratedFiles/Debug \
C:/gstreamer/include \
C:/gstreamer/include/libxml2 \
C:/gstreamer/include/glib-2.0 \
C:/gstreamer/lib/glib-2.0/include \
C:/gstreamer/include/gstreamer-1.0
LIBS += -L"C:/gstreamer/lib" \
-L"C:/gstreamer/bin" \
-lgstreamer-1.0 \
-lgstvideo-1.0 \
-lglib-2.0 \
-lgmodule-2.0 \
-lgobject-2.0 \
-lgthread-2.0 \
-lopengl32 \
-lglu32
}
unix {
DEFINES += UNIX
INCLUDEPATH += GeneratedFiles \
GeneratedFiles/Debug \
/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 += -lgstreamer-video \
-lgstvideo-1.0 \
-lglib-2.0 \
-lgmodule-2.0 \
-lgobject-2.0 \
-lgthread-2.0 \
-lGLU \
-lGL
}
DEPENDPATH += .
MOC_DIR += ./GeneratedFiles/debug
OBJECTS_DIR += debug
UI_DIR += ./GeneratedFiles
RCC_DIR += ./GeneratedFiles
#Include file(s)
include(mousevideooverlay.pri)

View file

@ -0,0 +1,26 @@

Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mousevideooverlay", "mousevideooverlay.vcproj", "{E94F8CAA-628F-4872-8E73-AD56D34899CB}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{E94F8CAA-628F-4872-8E73-AD56D34899CB}.Debug|Win32.ActiveCfg = Debug|Win32
{E94F8CAA-628F-4872-8E73-AD56D34899CB}.Debug|Win32.Build.0 = Debug|Win32
{E94F8CAA-628F-4872-8E73-AD56D34899CB}.Release|Win32.ActiveCfg = Release|Win32
{E94F8CAA-628F-4872-8E73-AD56D34899CB}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(Qt) = preSolution
Integration = True
EndGlobalSection
GlobalSection(Qt) = preSolution
Integration = True
EndGlobalSection
EndGlobal

View file

@ -0,0 +1,321 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9,00"
Name="mousevideooverlay"
ProjectGUID="{E94F8CAA-628F-4872-8E73-AD56D34899CB}"
RootNamespace="mousevideooverlay"
Keyword="Qt4VSv1.0"
TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=".\GeneratedFiles;&quot;$(QTDIR)\include&quot;;&quot;.\GeneratedFiles\$(ConfigurationName)&quot;;&quot;$(QTDIR)\include\QtCore&quot;;&quot;$(QTDIR)\include\QtGui&quot;;C:\gstreamer\include;&quot;C:\gstreamer\include\glib-2.0&quot;;&quot;C:\gstreamer\lib\glib-2.0\include&quot;;C:\gstreamer\include\libxml2;&quot;C:\gstreamer\include\gstreamer-1.0&quot;"
PreprocessorDefinitions="UNICODE,WIN32,QT_THREAD_SUPPORT,QT_NO_DEBUG,NDEBUG,QT_CORE_LIB,QT_GUI_LIB"
RuntimeLibrary="2"
TreatWChar_tAsBuiltInType="false"
DebugInformationFormat="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="qtmain.lib QtCore4.lib QtGui4.lib gstreamer-1.0.lib gstvideo-1.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib opengl32.lib glu32.lib"
OutputFile="$(OutDir)\$(ProjectName).exe"
AdditionalLibraryDirectories="&quot;$(QTDIR)\lib&quot;;C:\gstreamer\lib"
GenerateDebugInformation="false"
SubSystem="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=".\GeneratedFiles;&quot;$(QTDIR)\include&quot;;&quot;.\GeneratedFiles\$(ConfigurationName)&quot;;&quot;$(QTDIR)\include\QtCore&quot;;&quot;$(QTDIR)\include\QtGui&quot;;C:\gstreamer\include;&quot;C:\gstreamer\include\glib-2.0&quot;;&quot;C:\gstreamer\lib\glib-2.0\include&quot;;C:\gstreamer\include\libxml2;&quot;C:\gstreamer\include\gstreamer-1.0&quot;"
PreprocessorDefinitions="UNICODE,WIN32,QT_THREAD_SUPPORT,QT_CORE_LIB,QT_GUI_LIB"
RuntimeLibrary="3"
TreatWChar_tAsBuiltInType="false"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="qtmaind.lib QtCored4.lib QtGuid4.lib gstreamer-1.0.lib gstvideo-1.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib opengl32.lib glu32.lib"
OutputFile="$(OutDir)\$(ProjectName).exe"
AdditionalLibraryDirectories="&quot;$(QTDIR)\lib&quot;;C:\gstreamer\lib"
GenerateDebugInformation="true"
SubSystem="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;cxx;c;def"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\gstthread.cpp"
>
</File>
<File
RelativePath=".\main.cpp"
>
</File>
<File
RelativePath=".\pipeline.cpp"
>
</File>
<File
RelativePath=".\qrenderer.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\gstthread.h"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCustomBuildTool"
Description="Moc&apos;ing gstthread.h..."
CommandLine="&quot;$(QTDIR)\bin\moc.exe&quot; -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -I&quot;.\GeneratedFiles\.&quot; -I&quot;$(QTDIR)\include\.&quot; -I&quot;.\GeneratedFiles\$(ConfigurationName)\.&quot; -I&quot;$(QTDIR)\include\QtCore\.&quot; -I&quot;$(QTDIR)\include\QtGui\.&quot; -I&quot;C:\gstreamer\include\.&quot; -I&quot;C:\gstreamer\include\glib-2.0\.&quot; -I&quot;C:\gstreamer\lib\glib-2.0\include\.&quot; -I&quot;C:\gstreamer\include\libxml2\.&quot; -I&quot;C:\gstreamer\include\gstreamer-1.0\.&quot; &quot;.\gstthread.h&quot; -o &quot;.\GeneratedFiles\$(ConfigurationName)\moc_gstthread.cpp&quot;&#x0D;&#x0A;"
AdditionalDependencies="&quot;$(QTDIR)\bin\moc.exe&quot;;.\gstthread.h"
Outputs="&quot;.\GeneratedFiles\$(ConfigurationName)\moc_gstthread.cpp&quot;"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCustomBuildTool"
Description="Moc&apos;ing gstthread.h..."
CommandLine="&quot;$(QTDIR)\bin\moc.exe&quot; -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_CORE_LIB -DQT_GUI_LIB -I&quot;.\GeneratedFiles\.&quot; -I&quot;$(QTDIR)\include\.&quot; -I&quot;.\GeneratedFiles\$(ConfigurationName)\.&quot; -I&quot;$(QTDIR)\include\QtCore\.&quot; -I&quot;$(QTDIR)\include\QtGui\.&quot; -I&quot;C:\gstreamer\include\.&quot; -I&quot;C:\gstreamer\include\glib-2.0\.&quot; -I&quot;C:\gstreamer\lib\glib-2.0\include\.&quot; -I&quot;C:\gstreamer\include\libxml2\.&quot; -I&quot;C:\gstreamer\include\gstreamer-1.0\.&quot; &quot;.\gstthread.h&quot; -o &quot;.\GeneratedFiles\$(ConfigurationName)\moc_gstthread.cpp&quot;&#x0D;&#x0A;"
AdditionalDependencies="&quot;$(QTDIR)\bin\moc.exe&quot;;.\gstthread.h"
Outputs="&quot;.\GeneratedFiles\$(ConfigurationName)\moc_gstthread.cpp&quot;"
/>
</FileConfiguration>
</File>
<File
RelativePath=".\pipeline.h"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCustomBuildTool"
Description="Moc&apos;ing pipeline.h..."
CommandLine="&quot;$(QTDIR)\bin\moc.exe&quot; -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -I&quot;.\GeneratedFiles\.&quot; -I&quot;$(QTDIR)\include\.&quot; -I&quot;.\GeneratedFiles\$(ConfigurationName)\.&quot; -I&quot;$(QTDIR)\include\QtCore\.&quot; -I&quot;$(QTDIR)\include\QtGui\.&quot; -I&quot;C:\gstreamer\include\.&quot; -I&quot;C:\gstreamer\include\glib-2.0\.&quot; -I&quot;C:\gstreamer\lib\glib-2.0\include\.&quot; -I&quot;C:\gstreamer\include\libxml2\.&quot; -I&quot;C:\gstreamer\include\gstreamer-1.0\.&quot; &quot;.\pipeline.h&quot; -o &quot;.\GeneratedFiles\$(ConfigurationName)\moc_pipeline.cpp&quot;&#x0D;&#x0A;"
AdditionalDependencies="&quot;$(QTDIR)\bin\moc.exe&quot;;.\pipeline.h"
Outputs="&quot;.\GeneratedFiles\$(ConfigurationName)\moc_pipeline.cpp&quot;"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCustomBuildTool"
Description="Moc&apos;ing pipeline.h..."
CommandLine="&quot;$(QTDIR)\bin\moc.exe&quot; -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_CORE_LIB -DQT_GUI_LIB -I&quot;.\GeneratedFiles\.&quot; -I&quot;$(QTDIR)\include\.&quot; -I&quot;.\GeneratedFiles\$(ConfigurationName)\.&quot; -I&quot;$(QTDIR)\include\QtCore\.&quot; -I&quot;$(QTDIR)\include\QtGui\.&quot; -I&quot;C:\gstreamer\include\.&quot; -I&quot;C:\gstreamer\include\glib-2.0\.&quot; -I&quot;C:\gstreamer\lib\glib-2.0\include\.&quot; -I&quot;C:\gstreamer\include\libxml2\.&quot; -I&quot;C:\gstreamer\include\gstreamer-1.0\.&quot; &quot;.\pipeline.h&quot; -o &quot;.\GeneratedFiles\$(ConfigurationName)\moc_pipeline.cpp&quot;&#x0D;&#x0A;"
AdditionalDependencies="&quot;$(QTDIR)\bin\moc.exe&quot;;.\pipeline.h"
Outputs="&quot;.\GeneratedFiles\$(ConfigurationName)\moc_pipeline.cpp&quot;"
/>
</FileConfiguration>
</File>
<File
RelativePath=".\qrenderer.h"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCustomBuildTool"
Description="Moc&apos;ing qrenderer.h..."
CommandLine="&quot;$(QTDIR)\bin\moc.exe&quot; -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -I&quot;.\GeneratedFiles\.&quot; -I&quot;$(QTDIR)\include\.&quot; -I&quot;.\GeneratedFiles\$(ConfigurationName)\.&quot; -I&quot;$(QTDIR)\include\QtCore\.&quot; -I&quot;$(QTDIR)\include\QtGui\.&quot; -I&quot;C:\gstreamer\include\.&quot; -I&quot;C:\gstreamer\include\glib-2.0\.&quot; -I&quot;C:\gstreamer\lib\glib-2.0\include\.&quot; -I&quot;C:\gstreamer\include\libxml2\.&quot; -I&quot;C:\gstreamer\include\gstreamer-1.0\.&quot; &quot;.\qrenderer.h&quot; -o &quot;.\GeneratedFiles\$(ConfigurationName)\moc_qrenderer.cpp&quot;&#x0D;&#x0A;"
AdditionalDependencies="&quot;$(QTDIR)\bin\moc.exe&quot;;.\qrenderer.h"
Outputs="&quot;.\GeneratedFiles\$(ConfigurationName)\moc_qrenderer.cpp&quot;"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCustomBuildTool"
Description="Moc&apos;ing qrenderer.h..."
CommandLine="&quot;$(QTDIR)\bin\moc.exe&quot; -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_CORE_LIB -DQT_GUI_LIB -I&quot;.\GeneratedFiles\.&quot; -I&quot;$(QTDIR)\include\.&quot; -I&quot;.\GeneratedFiles\$(ConfigurationName)\.&quot; -I&quot;$(QTDIR)\include\QtCore\.&quot; -I&quot;$(QTDIR)\include\QtGui\.&quot; -I&quot;C:\gstreamer\include\.&quot; -I&quot;C:\gstreamer\include\glib-2.0\.&quot; -I&quot;C:\gstreamer\lib\glib-2.0\include\.&quot; -I&quot;C:\gstreamer\include\libxml2\.&quot; -I&quot;C:\gstreamer\include\gstreamer-1.0\.&quot; &quot;.\qrenderer.h&quot; -o &quot;.\GeneratedFiles\$(ConfigurationName)\moc_qrenderer.cpp&quot;&#x0D;&#x0A;"
AdditionalDependencies="&quot;$(QTDIR)\bin\moc.exe&quot;;.\qrenderer.h"
Outputs="&quot;.\GeneratedFiles\$(ConfigurationName)\moc_qrenderer.cpp&quot;"
/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Form Files"
Filter="ui"
UniqueIdentifier="{99349809-55BA-4b9d-BF79-8FDBB0286EB3}"
>
</Filter>
<Filter
Name="Resource Files"
Filter="qrc;*"
UniqueIdentifier="{D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E}"
ParseFiles="false"
>
</Filter>
<Filter
Name="Generated Files"
Filter="moc;h;cpp"
UniqueIdentifier="{71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11}"
SourceControlFiles="false"
>
<File
RelativePath=".\generatedfiles\debug\moc_gstthread.cpp"
>
</File>
<File
RelativePath=".\generatedfiles\debug\moc_pipeline.cpp"
>
</File>
<File
RelativePath=".\generatedfiles\debug\moc_qrenderer.cpp"
>
</File>
</Filter>
</Files>
<Globals>
<Global
Name="MocDir"
Value=".\GeneratedFiles\$(ConfigurationName)"
/>
<Global
Name="QtVersion"
Value="qt-4.3.0"
/>
<Global
Name="RccDir"
Value=".\GeneratedFiles"
/>
<Global
Name="UicDir"
Value=".\GeneratedFiles"
/>
</Globals>
</VisualStudioProject>

View file

@ -0,0 +1,334 @@
/*
* GStreamer
* Copyright (C) 2008-2009 Julien Isorce <julien.isorce@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <gst/video/videooverlay.h>
#include <GL/gl.h>
#include "pipeline.h"
Pipeline::Pipeline(const WId id, const QString videoLocation):
m_winId(id),
m_videoLocation(videoLocation),
m_loop(NULL),
m_bus(NULL),
m_pipeline(NULL),
m_glimagesink(NULL)
{
create();
}
Pipeline::~Pipeline()
{
}
void Pipeline::create()
{
qDebug("Loading video: %s", m_videoLocation.toAscii().data());
gst_init (NULL, NULL);
#ifdef WIN32
m_loop = g_main_loop_new (NULL, FALSE);
#endif
m_pipeline = gst_pipeline_new ("pipeline");
m_bus = gst_pipeline_get_bus (GST_PIPELINE (m_pipeline));
gst_bus_add_watch (m_bus, (GstBusFunc) bus_call, this);
gst_bus_set_sync_handler (m_bus, (GstBusSyncHandler) create_window, this);
gst_object_unref (m_bus);
GstElement* videosrc = gst_element_factory_make ("filesrc", "filesrc0");
GstElement* decodebin = gst_element_factory_make ("decodebin", "decodebin0");
m_glimagesink = gst_element_factory_make ("glimagesink", "sink0");
if (!videosrc || !decodebin || !m_glimagesink )
{
qDebug ("one element could not be found");
return;
}
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(m_glimagesink), "client-reshape-callback", reshapeCallback, NULL);
g_object_set(G_OBJECT(m_glimagesink), "client-draw-callback", drawCallback, NULL);
gst_bin_add_many (GST_BIN (m_pipeline), videosrc, decodebin, m_glimagesink, NULL);
gst_element_link_pads (videosrc, "src", decodebin, "sink");
g_signal_connect (decodebin, "new-decoded-pad", G_CALLBACK (cb_new_pad), this);
}
void Pipeline::start()
{
GstStateChangeReturn ret = gst_element_set_state (m_pipeline, GST_STATE_PLAYING);
if (ret == GST_STATE_CHANGE_FAILURE)
{
qDebug ("Failed to start up pipeline!");
/* check if there is an error message with details on the bus */
GstMessage* msg = gst_bus_poll (m_bus, GST_MESSAGE_ERROR, 0);
if (msg)
{
GError *err = NULL;
gst_message_parse_error (msg, &err, NULL);
qDebug ("ERROR: %s", err->message);
g_error_free (err);
gst_message_unref (msg);
}
return;
}
#ifdef WIN32
g_main_loop_run(m_loop);
#endif
}
//we don't want a thread safe stop in this example
void Pipeline::stop()
{
#ifdef WIN32
g_main_loop_quit(m_loop);
#else
emit stopRequested();
#endif
}
void Pipeline::unconfigure() const
{
gst_element_set_state (m_pipeline, GST_STATE_NULL);
gst_object_unref (m_pipeline);
}
void Pipeline::show()
{
emit showRequested();
}
//redraw the current frame in the drawable
void Pipeline::doExpose() const
{
if (m_pipeline && m_glimagesink)
gst_video_overlay_expose (GST_VIDEO_OVERLAY (m_glimagesink));
}
//post message to g_main_loop in order to call expose
//in the gt thread
void Pipeline::exposeRequested()
{
g_idle_add(cb_expose, this);
}
//rotate the cube
void Pipeline::doRotate()
{
m_xrot += 3.0f;
m_yrot += 2.0f;
m_zrot += 4.0f;
}
//post message to g_main_loop in order to call rotate
//in the gt thread
void Pipeline::rotateRequested()
{
g_idle_add(cb_rotate, this);
}
//-----------------------------------------------------------------------
//----------------------------- static members --------------------------
//-----------------------------------------------------------------------
float Pipeline::m_xrot = 0;
float Pipeline::m_yrot = 0;
float Pipeline::m_zrot = 0;
//client reshape callback
void Pipeline::reshapeCallback (uint width, uint height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45, (gfloat)width/(gfloat)height, 0.1, 100);
glMatrixMode(GL_MODELVIEW);
}
//client draw callback
gboolean Pipeline::drawCallback (uint texture, uint width, uint height)
{
static GTimeVal current_time;
static glong last_sec = current_time.tv_sec;
static gint nbFrames = 0;
g_get_current_time (&current_time);
nbFrames++ ;
if ((current_time.tv_sec - last_sec) >= 1)
{
qDebug ("GRPHIC FPS = %d", nbFrames);
nbFrames = 0;
last_sec = current_time.tv_sec;
}
glEnable(GL_DEPTH_TEST);
glEnable (GL_TEXTURE_2D);
glBindTexture (GL_TEXTURE_2D, texture);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0f,0.0f,-5.0f);
glRotatef(m_xrot,1.0f,0.0f,0.0f);
glRotatef(m_yrot,0.0f,1.0f,0.0f);
glRotatef(m_zrot,0.0f,0.0f,1.0f);
glBegin(GL_QUADS);
// Front Face
glTexCoord2f((gfloat)width, 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((gfloat)width, (gfloat)height); glVertex3f(-1.0f, 1.0f, 1.0f);
// Back Face
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((gfloat)width, (gfloat)height); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f((gfloat)width, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
// Top Face
glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f((gfloat)width, 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);
// Bottom Face
glTexCoord2f((gfloat)width, 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((gfloat)width,(gfloat)height); glVertex3f(-1.0f, -1.0f, 1.0f);
// Right face
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((gfloat)width, (gfloat)height); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f((gfloat)width, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
// Left Face
glTexCoord2f((gfloat)width, 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((gfloat)width, (gfloat)height); glVertex3f(-1.0f, 1.0f, -1.0f);
glEnd();
//return TRUE causes a postRedisplay
return FALSE;
}
gboolean Pipeline::bus_call (GstBus *bus, GstMessage *msg, Pipeline* p)
{
switch (GST_MESSAGE_TYPE (msg))
{
case GST_MESSAGE_EOS:
qDebug ("End-of-stream");
p->stop();
break;
case GST_MESSAGE_ERROR:
{
gchar *debug = NULL;
GError *err = NULL;
gst_message_parse_error (msg, &err, &debug);
qDebug ("Error: %s", err->message);
g_error_free (err);
if (debug)
{
qDebug ("Debug deails: %s", debug);
g_free (debug);
}
p->stop();
break;
}
default:
break;
}
return TRUE;
}
void Pipeline::cb_new_pad (GstElement* decodebin, GstPad* pad, gboolean last, Pipeline* p)
{
GstElement* glimagesink = p->getVideoSink();
GstPad* glpad = gst_element_get_pad (glimagesink, "sink");
//only link once
if (GST_PAD_IS_LINKED (glpad))
{
gst_object_unref (glpad);
return;
}
GstCaps* caps = gst_pad_get_caps (pad);
GstStructure* str = gst_caps_get_structure (caps, 0);
if (!g_strrstr (gst_structure_get_name (str), "video"))
{
gst_caps_unref (caps);
gst_object_unref (glpad);
return;
}
gst_caps_unref (caps);
GstPadLinkReturn ret = gst_pad_link (pad, glpad);
if (ret != GST_PAD_LINK_OK)
g_warning ("Failed to link with decodebin!\n");
p->show();
}
gboolean Pipeline::cb_expose (gpointer data)
{
((Pipeline*)data)->doExpose();
return FALSE;
}
gboolean Pipeline::cb_rotate (gpointer data)
{
((Pipeline*)data)->doRotate();
return FALSE;
}
GstBusSyncReply Pipeline::create_window (GstBus* bus, GstMessage* message, const Pipeline* p)
{
// ignore anything but 'prepare-window-handle' element messages
if (GST_MESSAGE_TYPE (message) != GST_MESSAGE_ELEMENT)
return GST_BUS_PASS;
if (!gst_is_video_overlay_prepare_window_handle_message (message))
return GST_BUS_PASS;
qDebug ("setting window handle");
//Passing 0 as the window_handle will tell the overlay to stop using that window and create an internal one.
//In the directdrawsink's gst_video_overlay_set_window_handle implementation, window_handle (parameter 2) is casted to HWND before it used.
gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY (GST_MESSAGE_SRC (message)), (guintptr)p->winId());
gst_message_unref (message);
return GST_BUS_DROP;
}

View file

@ -0,0 +1,72 @@
/*
* GStreamer
* Copyright (C) 2008-2009 Julien Isorce <julien.isorce@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef PIPELINE_H
#define PIPELINE_H
#include <QObject>
#include <gst/gst.h>
//#include <QtCore/private/qeventdispatcher_glib_p.h>
class Pipeline : public QObject
{
Q_OBJECT
public:
Pipeline(const WId windId, const QString videoLocation);
~Pipeline();
void start();
void exposeRequested();
void rotateRequested();
void stop();
void unconfigure() const;
void show();
GstElement* getVideoSink() { return m_glimagesink; } ;
signals:
void showRequested();
void stopRequested();
private:
const WId m_winId;
const QString m_videoLocation;
GMainLoop* m_loop;
GstBus* m_bus;
GstElement* m_pipeline;
GstElement* m_glimagesink;
static float m_xrot;
static float m_yrot;
static float m_zrot;
void create();
WId winId() const { return m_winId; }
void doExpose() const;
void doRotate();
static void reshapeCallback (uint width, uint height);
static gboolean drawCallback (uint texture, uint width, uint height);
static gboolean bus_call (GstBus *bus, GstMessage *msg, Pipeline* p);
static void cb_new_pad (GstElement* decodebin, GstPad* pad, gboolean last, Pipeline* p);
static gboolean cb_expose (gpointer data);
static gboolean cb_rotate (gpointer data);
static GstBusSyncReply create_window (GstBus* bus, GstMessage* message, const Pipeline* pipeline);
};
#endif

View file

@ -0,0 +1,58 @@
/*
* GStreamer
* Copyright (C) 2008-2009 Julien Isorce <julien.isorce@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "qrenderer.h"
QRenderer::QRenderer(const QString videoLocation, QWidget *parent, Qt::WFlags flags)
: QWidget(parent, flags),
m_gt(winId(), videoLocation)
{
setAttribute(Qt::WA_NoSystemBackground);
setVisible(false);
move(20, 10);
resize(640, 480);
QObject::connect(&m_gt, SIGNAL(finished()), this, SLOT(close()));
QObject::connect(this, SIGNAL(exposeRequested()), &m_gt, SLOT(exposeRequested()));
QObject::connect(this, SIGNAL(closeRequested()), &m_gt, SLOT(stop()), Qt::DirectConnection);
QObject::connect(&m_gt, SIGNAL(showRequested()), this, SLOT(show()));
QObject::connect(this, SIGNAL(mouseMoved()), &m_gt, SLOT(onMouseMove()));
m_gt.start();
}
QRenderer::~QRenderer()
{
}
void QRenderer::paintEvent(QPaintEvent* event)
{
emit exposeRequested();
}
void QRenderer::mouseMoveEvent(QMouseEvent* event)
{
emit mouseMoved();
}
void QRenderer::closeEvent(QCloseEvent* event)
{
emit closeRequested();
m_gt.wait();
}

View file

@ -0,0 +1,48 @@
/*
* GStreamer
* Copyright (C) 2008-2009 Julien Isorce <julien.isorce@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef QRENDERER_H
#define QRENDERER_H
#include <QWidget>
#include <QString>
#include "gstthread.h"
class QRenderer : public QWidget
{
Q_OBJECT
public:
QRenderer(const QString videoLocation, QWidget *parent = 0, Qt::WFlags flags = 0);
~QRenderer();
void paintEvent(QPaintEvent* event);
void mouseMoveEvent(QMouseEvent* event);
void closeEvent (QCloseEvent* event);
signals:
void exposeRequested();
void closeRequested();
void mouseMoved();
private:
GstThread m_gt;
};
#endif // QRENDERER_H

View file

@ -0,0 +1,62 @@
/*
* GStreamer
* Copyright (C) 2008-2009 Julien Isorce <julien.isorce@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "gstthread.h"
GstThread::GstThread(const WId winId, const QString videoLocation, QObject *parent):
QThread(parent),
m_winId(winId),
m_videoLocation(videoLocation)
{
}
GstThread::~GstThread()
{
}
void GstThread::exposeRequested()
{
m_pipeline->exposeRequested();
}
void GstThread::show()
{
emit showRequested();
}
void GstThread::stop()
{
m_pipeline->stop();
}
void GstThread::run()
{
m_pipeline = new Pipeline(m_winId, m_videoLocation);
connect(m_pipeline, SIGNAL(showRequested()), this, SLOT(show()));
m_pipeline->start(); //it runs the gmainloop on win32
#ifndef WIN32
//works like the gmainloop on linux (GstEvent are handled)
connect(m_pipeline, SIGNAL(stopRequested()), this, SLOT(quit()));
exec();
#endif
m_pipeline->unconfigure();
}

View file

@ -0,0 +1,55 @@
/*
* GStreamer
* Copyright (C) 2008-2009 Julien Isorce <julien.isorce@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef GSTTHREAD_H
#define GSTTHREAD_H
#include <QtGui>
#include <QtCore/QThread>
#include "pipeline.h"
class GstThread : public QThread
{
Q_OBJECT
public:
GstThread(const WId winId, const QString videoLocation, QObject *parent = 0);
~GstThread();
public slots:
void exposeRequested();
void show();
void stop();
signals:
void showRequested();
protected:
void run();
private:
const WId m_winId;
const QString m_videoLocation;
Pipeline* m_pipeline;
};
#endif

View file

@ -0,0 +1,39 @@
/*
* GStreamer
* Copyright (C) 2008-2009 Julien Isorce <julien.isorce@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <QtGui/QApplication>
#include "qglrenderer.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
a.connect(&a, SIGNAL(lastWindowClosed()), &a, SLOT(quit()));
QString videolcoation = QFileDialog::getOpenFileName(0, "Select a video file",
".", "Format (*.avi *.mkv *.ogg *.asf *.mov)");
if (videolcoation.isEmpty())
return -1;
QGLRenderer w(videolcoation);
w.setWindowTitle("glimagesink implements the gstvideooverlay interface");
return a.exec();
}

View file

@ -0,0 +1,332 @@
/*
* GStreamer
* Copyright (C) 2008-2009 Julien Isorce <julien.isorce@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <gst/video/videooverlay.h>
#include <GL/gl.h>
#include "pipeline.h"
Pipeline::Pipeline(const WId id, const QString videoLocation):
m_winId(id),
m_videoLocation(videoLocation),
m_loop(NULL),
m_bus(NULL),
m_pipeline(NULL),
m_glupload(NULL),
m_glimagesink(NULL)
{
create();
}
Pipeline::~Pipeline()
{
}
void Pipeline::create()
{
qDebug("Loading video: %s", m_videoLocation.toAscii().data());
gst_init (NULL, NULL);
#ifdef WIN32
m_loop = g_main_loop_new (NULL, FALSE);
#endif
m_pipeline = gst_pipeline_new ("pipeline");
m_bus = gst_pipeline_get_bus (GST_PIPELINE (m_pipeline));
gst_bus_add_watch (m_bus, (GstBusFunc) bus_call, this);
gst_bus_set_sync_handler (m_bus, (GstBusSyncHandler) create_window, this);
gst_object_unref (m_bus);
GstElement* videosrc = gst_element_factory_make ("filesrc", "filesrc0");
GstElement* decodebin = gst_element_factory_make ("decodebin", "decodebin0");
m_glupload = gst_element_factory_make ("glupload", "glupload0");
m_glimagesink = gst_element_factory_make ("glimagesink", "sink0");
if (!videosrc || !decodebin || !m_glupload || !m_glimagesink )
{
qDebug ("one element could not be found");
return;
}
GstCaps *outcaps = gst_caps_new_simple("video/x-raw",
"width", G_TYPE_INT, 800,
"height", G_TYPE_INT, 600,
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(m_glimagesink), "client-reshape-callback", reshapeCallback, NULL);
g_object_set(G_OBJECT(m_glimagesink), "client-draw-callback", drawCallback, NULL);
gst_bin_add_many (GST_BIN (m_pipeline), videosrc, decodebin, m_glupload, m_glimagesink, NULL);
gboolean link_ok = gst_element_link_filtered(m_glupload, m_glimagesink, outcaps) ;
gst_caps_unref(outcaps) ;
if(!link_ok)
{
qDebug("Failed to link glupload to glimagesink!\n") ;
return;
}
gst_element_link_pads (videosrc, "src", decodebin, "sink");
g_signal_connect (decodebin, "new-decoded-pad", G_CALLBACK (cb_new_pad), this);
}
void Pipeline::start()
{
GstStateChangeReturn ret = gst_element_set_state (m_pipeline, GST_STATE_PLAYING);
if (ret == GST_STATE_CHANGE_FAILURE)
{
qDebug ("Failed to start up pipeline!");
/* check if there is an error message with details on the bus */
GstMessage* msg = gst_bus_poll (m_bus, GST_MESSAGE_ERROR, 0);
if (msg)
{
GError *err = NULL;
gst_message_parse_error (msg, &err, NULL);
qDebug ("ERROR: %s", err->message);
g_error_free (err);
gst_message_unref (msg);
}
return;
}
#ifdef WIN32
g_main_loop_run(m_loop);
#endif
}
//we don't want a thread safe stop in this example
void Pipeline::stop()
{
#ifdef WIN32
g_main_loop_quit(m_loop);
#else
emit stopRequested();
#endif
}
void Pipeline::unconfigure() const
{
gst_element_set_state (m_pipeline, GST_STATE_NULL);
gst_object_unref (m_pipeline);
}
void Pipeline::show()
{
emit showRequested();
}
//redraw the current frame in the drawable
void Pipeline::doExpose() const
{
if (m_pipeline && m_glimagesink)
gst_video_overlay_expose (GST_VIDEO_OVERLAY (m_glimagesink));
}
//post message to g_main_loop in order to call expose
//in the gt thread
void Pipeline::exposeRequested()
{
g_idle_add(cb_expose, this);
}
//-----------------------------------------------------------------------
//----------------------------- static members --------------------------
//-----------------------------------------------------------------------
//client reshape callback
void Pipeline::reshapeCallback (uint width, uint height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45, (gfloat)width/(gfloat)height, 0.1, 100);
glMatrixMode(GL_MODELVIEW);
}
//client draw callback
gboolean Pipeline::drawCallback (uint texture, uint width, uint height)
{
static GLfloat xrot = 0;
static GLfloat yrot = 0;
static GLfloat zrot = 0;
static GTimeVal current_time;
static glong last_sec = current_time.tv_sec;
static gint nbFrames = 0;
g_get_current_time (&current_time);
nbFrames++ ;
if ((current_time.tv_sec - last_sec) >= 1)
{
qDebug ("GRPHIC FPS = %d", nbFrames);
nbFrames = 0;
last_sec = current_time.tv_sec;
}
glEnable(GL_DEPTH_TEST);
glEnable (GL_TEXTURE_2D);
glBindTexture (GL_TEXTURE_2D, texture);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0f,0.0f,-5.0f);
glRotatef(xrot,1.0f,0.0f,0.0f);
glRotatef(yrot,0.0f,1.0f,0.0f);
glRotatef(zrot,0.0f,0.0f,1.0f);
glBegin(GL_QUADS);
// Front Face
glTexCoord2f((gfloat)width, 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((gfloat)width, (gfloat)height); glVertex3f(-1.0f, 1.0f, 1.0f);
// Back Face
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((gfloat)width, (gfloat)height); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f((gfloat)width, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
// Top Face
glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f((gfloat)width, 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);
// Bottom Face
glTexCoord2f((gfloat)width, 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((gfloat)width,(gfloat)height); glVertex3f(-1.0f, -1.0f, 1.0f);
// Right face
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((gfloat)width, (gfloat)height); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f((gfloat)width, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
// Left Face
glTexCoord2f((gfloat)width, 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((gfloat)width, (gfloat)height); glVertex3f(-1.0f, 1.0f, -1.0f);
glEnd();
xrot+=0.03f;
yrot+=0.02f;
zrot+=0.04f;
//return TRUE causes a postRedisplay
return TRUE;
}
gboolean Pipeline::bus_call (GstBus *bus, GstMessage *msg, Pipeline* p)
{
switch (GST_MESSAGE_TYPE (msg))
{
case GST_MESSAGE_EOS:
qDebug ("End-of-stream");
p->stop();
break;
case GST_MESSAGE_ERROR:
{
gchar *debug = NULL;
GError *err = NULL;
gst_message_parse_error (msg, &err, &debug);
qDebug ("Error: %s", err->message);
g_error_free (err);
if (debug)
{
qDebug ("Debug deails: %s", debug);
g_free (debug);
}
p->stop();
break;
}
default:
break;
}
return TRUE;
}
void Pipeline::cb_new_pad (GstElement* decodebin, GstPad* pad, gboolean last, Pipeline* p)
{
GstElement* glupload = p->getVideoSink();
GstPad* glpad = gst_element_get_pad (glupload, "sink");
//only link once
if (GST_PAD_IS_LINKED (glpad))
{
gst_object_unref (glpad);
return;
}
GstCaps* caps = gst_pad_get_caps (pad);
GstStructure* str = gst_caps_get_structure (caps, 0);
if (!g_strrstr (gst_structure_get_name (str), "video"))
{
gst_caps_unref (caps);
gst_object_unref (glpad);
return;
}
gst_caps_unref (caps);
GstPadLinkReturn ret = gst_pad_link (pad, glpad);
if (ret != GST_PAD_LINK_OK)
g_warning ("Failed to link with decodebin!\n");
p->show();
}
gboolean Pipeline::cb_expose (gpointer data)
{
((Pipeline*)data)->doExpose();
return FALSE;
}
GstBusSyncReply Pipeline::create_window (GstBus* bus, GstMessage* message, const Pipeline* p)
{
// ignore anything but 'prepare-window-handle' element messages
if (GST_MESSAGE_TYPE (message) != GST_MESSAGE_ELEMENT)
return GST_BUS_PASS;
if (!gst_is_video_overlay_prepare_window_handle_message (message))
return GST_BUS_PASS;
qDebug ("setting window handle");
//Passing 0 as the window_handle will tell the overlay to stop using that window and create an internal one.
//In the directdrawsink's gst_video_overlay_set_window_handle implementation, window_handle (parameter 2) is casted to HWND before it used.
gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY (GST_MESSAGE_SRC (message)), (guintptr)p->winId());
gst_message_unref (message);
return GST_BUS_DROP;
}

View file

@ -0,0 +1,70 @@
/*
* GStreamer
* Copyright (C) 2008-2009 Julien Isorce <julien.isorce@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef PIPELINE_H
#define PIPELINE_H
#include <QtGui>
#include <gst/gst.h>
//#include <QtCore/private/qeventdispatcher_glib_p.h>
class Pipeline : public QObject
{
Q_OBJECT
public:
Pipeline(const WId windId, const QString videoLocation);
~Pipeline();
void start();
void exposeRequested();
void stop();
void unconfigure() const;
void show();
GstElement* getVideoSink() { return m_glupload; } ;
signals:
void showRequested();
void stopRequested();
private:
const WId m_winId;
const QString m_videoLocation;
GMainLoop* m_loop;
GstBus* m_bus;
GstElement* m_pipeline;
GstElement* m_glupload;
GstElement* m_glimagesink;
static float m_xrot;
static float m_yrot;
static float m_zrot;
void create();
WId winId() const { return m_winId; }
void doExpose() const;
static void reshapeCallback (uint width, uint height);
static gboolean drawCallback (uint texture, uint width, uint height);
static gboolean bus_call (GstBus *bus, GstMessage *msg, Pipeline* p);
static void cb_new_pad (GstElement* decodebin, GstPad* pad, gboolean last, Pipeline* p);
static gboolean cb_expose (gpointer data);
static GstBusSyncReply create_window (GstBus* bus, GstMessage* message, const Pipeline* pipeline);
};
#endif

View file

@ -0,0 +1,52 @@
/*
* GStreamer
* Copyright (C) 2008-2009 Julien Isorce <julien.isorce@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "qglrenderer.h"
QGLRenderer::QGLRenderer(const QString videoLocation, QWidget *parent)
: QGLWidget(parent),
m_gt(winId(), videoLocation)
{
setAttribute(Qt::WA_NoSystemBackground);
setVisible(false);
move(20, 10);
resize(640, 480);
QObject::connect(&m_gt, SIGNAL(finished()), this, SLOT(close()));
QObject::connect(this, SIGNAL(exposeRequested()), &m_gt, SLOT(exposeRequested()));
QObject::connect(this, SIGNAL(closeRequested()), &m_gt, SLOT(stop()), Qt::DirectConnection);
QObject::connect(&m_gt, SIGNAL(showRequested()), this, SLOT(show()));
m_gt.start();
}
QGLRenderer::~QGLRenderer()
{
}
void QGLRenderer::paintEvent(QPaintEvent* event)
{
emit exposeRequested();
}
void QGLRenderer::closeEvent(QCloseEvent* event)
{
emit closeRequested();
m_gt.wait();
}

View file

@ -0,0 +1,45 @@
/*
* GStreamer
* Copyright (C) 2008-2009 Julien Isorce <julien.isorce@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef QGLRENDERER_H
#define QGLRENDERER_H
#include <QGLWidget>
#include "gstthread.h"
class QGLRenderer : public QGLWidget
{
Q_OBJECT
public:
QGLRenderer(const QString videoLocation, QWidget *parent = 0);
~QGLRenderer();
void paintEvent(QPaintEvent* event);
void closeEvent (QCloseEvent* event);
signals:
void exposeRequested();
void closeRequested();
private:
GstThread m_gt;
};
#endif // QGLRENDERER_H

View file

@ -0,0 +1,10 @@
#Header files
HEADERS += ./gstthread.h \
./pipeline.h \
./qglrenderer.h
#Source files
SOURCES += ./gstthread.cpp \
./main.cpp \
./pipeline.cpp \
./qglrenderer.cpp

View file

@ -0,0 +1,55 @@
TEMPLATE = app
TARGET = qglwidgetvideooverlay
DESTDIR = ./debug
QT += opengl
CONFIG += debug
DEFINES += UNICODE QT_THREAD_SUPPORT QT_CORE_LIB QT_GUI_LIB
win32 {
DEFINES += WIN32
INCLUDEPATH += ./GeneratedFiles \
./GeneratedFiles/Debug \
C:/gstreamer/include \
C:/gstreamer/include/libxml2 \
C:/gstreamer/include/glib-2.0 \
C:/gstreamer/lib/glib-2.0/include \
C:/gstreamer/include/gstreamer-1.0
LIBS += -L"C:/gstreamer/lib" \
-L"C:/gstreamer/bin" \
-lgstreamer-1.0 \
-lgstvideo-1.0 \
-lglib-2.0 \
-lgmodule-2.0 \
-lgobject-2.0 \
-lgthread-2.0 \
-lopengl32 \
-lglu32
}
unix {
DEFINES += UNIX
INCLUDEPATH += GeneratedFiles \
GeneratedFiles/Debug \
/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 += -lgstreamer-1.0 \
-lgstvideo-1.0 \
-lglib-2.0 \
-lgmodule-2.0 \
-lgobject-2.0 \
-lgthread-2.0 \
-lGLU \
-lGL
}
DEPENDPATH += .
MOC_DIR += ./GeneratedFiles/debug
OBJECTS_DIR += debug
UI_DIR += ./GeneratedFiles
RCC_DIR += ./GeneratedFiles
#Include file(s)
include(qglwidgetvideooverlay.pri)

View file

@ -0,0 +1,26 @@

Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qglwidgetvideooverlay", "qglwidgetvideooverlay.vcproj", "{F40D2D98-281E-465F-B63F-2D473E1C2616}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{F40D2D98-281E-465F-B63F-2D473E1C2616}.Debug|Win32.ActiveCfg = Debug|Win32
{F40D2D98-281E-465F-B63F-2D473E1C2616}.Debug|Win32.Build.0 = Debug|Win32
{F40D2D98-281E-465F-B63F-2D473E1C2616}.Release|Win32.ActiveCfg = Release|Win32
{F40D2D98-281E-465F-B63F-2D473E1C2616}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(Qt) = preSolution
Integration = True
EndGlobalSection
GlobalSection(Qt) = preSolution
Integration = True
EndGlobalSection
EndGlobal

View file

@ -0,0 +1,320 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9,00"
Name="qglwidgetvideooverlay"
ProjectGUID="{F40D2D98-281E-465F-B63F-2D473E1C2616}"
Keyword="Qt4VSv1.0"
TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=".\GeneratedFiles;&quot;$(QTDIR)\include&quot;;&quot;.\GeneratedFiles\$(ConfigurationName)&quot;;&quot;$(QTDIR)\include\QtCore&quot;;&quot;$(QTDIR)\include\QtGui&quot;;&quot;$(QTDIR)\include\QtOpenGL&quot;;C:\gstreamer\include;&quot;C:\gstreamer\include\glib-2.0&quot;;&quot;C:\gstreamer\lib\glib-2.0\include&quot;;C:\gstreamer\include\libxml2;&quot;C:\gstreamer\include\gstreamer-1.0&quot;"
PreprocessorDefinitions="UNICODE,WIN32,QT_THREAD_SUPPORT,QT_NO_DEBUG,NDEBUG,QT_CORE_LIB,QT_GUI_LIB,QT_OPENGL_LIB"
RuntimeLibrary="2"
TreatWChar_tAsBuiltInType="false"
DebugInformationFormat="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="qtmain.lib QtCore4.lib QtGui4.lib QtOpenGL4.lib opengl32.lib glu32.lib gstreamer-1.0.lib gstvideo-1.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib"
OutputFile="$(OutDir)\$(ProjectName).exe"
AdditionalLibraryDirectories="&quot;$(QTDIR)\lib&quot;;C:\gstreamer\lib"
GenerateDebugInformation="false"
SubSystem="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=".\GeneratedFiles;&quot;$(QTDIR)\include&quot;;&quot;.\GeneratedFiles\$(ConfigurationName)&quot;;&quot;$(QTDIR)\include\QtCore&quot;;&quot;$(QTDIR)\include\QtGui&quot;;&quot;$(QTDIR)\include\QtOpenGL&quot;;C:\gstreamer\include;&quot;C:\gstreamer\include\glib-2.0&quot;;&quot;C:\gstreamer\lib\glib-2.0\include&quot;;C:\gstreamer\include\libxml2;&quot;C:\gstreamer\include\gstreamer-1.0&quot;"
PreprocessorDefinitions="UNICODE,WIN32,QT_THREAD_SUPPORT,QT_CORE_LIB,QT_GUI_LIB,QT_OPENGL_LIB"
RuntimeLibrary="3"
TreatWChar_tAsBuiltInType="false"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="qtmaind.lib QtCored4.lib QtGuid4.lib QtOpenGLd4.lib opengl32.lib glu32.lib gstreamer-1.0.lib gstvideo-1.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib"
OutputFile="$(OutDir)\$(ProjectName).exe"
AdditionalLibraryDirectories="&quot;$(QTDIR)\lib&quot;;C:\gstreamer\lib"
GenerateDebugInformation="true"
SubSystem="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;cxx;c;def"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\gstthread.cpp"
>
</File>
<File
RelativePath=".\main.cpp"
>
</File>
<File
RelativePath=".\pipeline.cpp"
>
</File>
<File
RelativePath=".\qglrenderer.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\gstthread.h"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCustomBuildTool"
Description="Moc&apos;ing gstthread.h..."
CommandLine="&quot;$(QTDIR)\bin\moc.exe&quot; -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_OPENGL_LIB -I&quot;.\GeneratedFiles\.&quot; -I&quot;$(QTDIR)\include\.&quot; -I&quot;.\GeneratedFiles\$(ConfigurationName)\.&quot; -I&quot;$(QTDIR)\include\QtCore\.&quot; -I&quot;$(QTDIR)\include\QtGui\.&quot; -I&quot;$(QTDIR)\include\QtOpenGL\.&quot; -I&quot;C:\gstreamer\include\.&quot; -I&quot;C:\gstreamer\include\glib-2.0\.&quot; -I&quot;C:\gstreamer\lib\glib-2.0\include\.&quot; -I&quot;C:\gstreamer\include\libxml2\.&quot; -I&quot;C:\gstreamer\include\gstreamer-1.0\.&quot; &quot;.\gstthread.h&quot; -o &quot;.\GeneratedFiles\$(ConfigurationName)\moc_gstthread.cpp&quot;&#x0D;&#x0A;"
AdditionalDependencies="&quot;$(QTDIR)\bin\moc.exe&quot;;.\gstthread.h"
Outputs="&quot;.\GeneratedFiles\$(ConfigurationName)\moc_gstthread.cpp&quot;"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCustomBuildTool"
Description="Moc&apos;ing gstthread.h..."
CommandLine="&quot;$(QTDIR)\bin\moc.exe&quot; -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_CORE_LIB -DQT_GUI_LIB -DQT_OPENGL_LIB -I&quot;.\GeneratedFiles\.&quot; -I&quot;$(QTDIR)\include\.&quot; -I&quot;.\GeneratedFiles\$(ConfigurationName)\.&quot; -I&quot;$(QTDIR)\include\QtCore\.&quot; -I&quot;$(QTDIR)\include\QtGui\.&quot; -I&quot;$(QTDIR)\include\QtOpenGL\.&quot; -I&quot;C:\gstreamer\include\.&quot; -I&quot;C:\gstreamer\include\glib-2.0\.&quot; -I&quot;C:\gstreamer\lib\glib-2.0\include\.&quot; -I&quot;C:\gstreamer\include\libxml2\.&quot; -I&quot;C:\gstreamer\include\gstreamer-1.0\.&quot; &quot;.\gstthread.h&quot; -o &quot;.\GeneratedFiles\$(ConfigurationName)\moc_gstthread.cpp&quot;&#x0D;&#x0A;"
AdditionalDependencies="&quot;$(QTDIR)\bin\moc.exe&quot;;.\gstthread.h"
Outputs="&quot;.\GeneratedFiles\$(ConfigurationName)\moc_gstthread.cpp&quot;"
/>
</FileConfiguration>
</File>
<File
RelativePath=".\pipeline.h"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCustomBuildTool"
Description="Moc&apos;ing pipeline.h..."
CommandLine="&quot;$(QTDIR)\bin\moc.exe&quot; -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_OPENGL_LIB -I&quot;.\GeneratedFiles\.&quot; -I&quot;$(QTDIR)\include\.&quot; -I&quot;.\GeneratedFiles\$(ConfigurationName)\.&quot; -I&quot;$(QTDIR)\include\QtCore\.&quot; -I&quot;$(QTDIR)\include\QtGui\.&quot; -I&quot;$(QTDIR)\include\QtOpenGL\.&quot; -I&quot;C:\gstreamer\include\.&quot; -I&quot;C:\gstreamer\include\glib-2.0\.&quot; -I&quot;C:\gstreamer\lib\glib-2.0\include\.&quot; -I&quot;C:\gstreamer\include\libxml2\.&quot; -I&quot;C:\gstreamer\include\gstreamer-1,0\.&quot; &quot;.\pipeline.h&quot; -o &quot;.\GeneratedFiles\$(ConfigurationName)\moc_pipeline.cpp&quot;&#x0D;&#x0A;"
AdditionalDependencies="&quot;$(QTDIR)\bin\moc.exe&quot;;.\pipeline.h"
Outputs="&quot;.\GeneratedFiles\$(ConfigurationName)\moc_pipeline.cpp&quot;"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCustomBuildTool"
Description="Moc&apos;ing pipeline.h..."
CommandLine="&quot;$(QTDIR)\bin\moc.exe&quot; -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_CORE_LIB -DQT_GUI_LIB -DQT_OPENGL_LIB -I&quot;.\GeneratedFiles\.&quot; -I&quot;$(QTDIR)\include\.&quot; -I&quot;.\GeneratedFiles\$(ConfigurationName)\.&quot; -I&quot;$(QTDIR)\include\QtCore\.&quot; -I&quot;$(QTDIR)\include\QtGui\.&quot; -I&quot;$(QTDIR)\include\QtOpenGL\.&quot; -I&quot;C:\gstreamer\include\.&quot; -I&quot;C:\gstreamer\include\glib-2.0\.&quot; -I&quot;C:\gstreamer\lib\glib-2.0\include\.&quot; -I&quot;C:\gstreamer\include\libxml2\.&quot; -I&quot;C:\gstreamer\include\gstreamer-1,0\.&quot; &quot;.\pipeline.h&quot; -o &quot;.\GeneratedFiles\$(ConfigurationName)\moc_pipeline.cpp&quot;&#x0D;&#x0A;"
AdditionalDependencies="&quot;$(QTDIR)\bin\moc.exe&quot;;.\pipeline.h"
Outputs="&quot;.\GeneratedFiles\$(ConfigurationName)\moc_pipeline.cpp&quot;"
/>
</FileConfiguration>
</File>
<File
RelativePath=".\qglrenderer.h"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCustomBuildTool"
Description="Moc&apos;ing qglrenderer.h..."
CommandLine="&quot;$(QTDIR)\bin\moc.exe&quot; -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_OPENGL_LIB -I&quot;.\GeneratedFiles\.&quot; -I&quot;$(QTDIR)\include\.&quot; -I&quot;.\GeneratedFiles\$(ConfigurationName)\.&quot; -I&quot;$(QTDIR)\include\QtCore\.&quot; -I&quot;$(QTDIR)\include\QtGui\.&quot; -I&quot;$(QTDIR)\include\QtOpenGL\.&quot; -I&quot;C:\gstreamer\include\.&quot; -I&quot;C:\gstreamer\include\glib-2.0\.&quot; -I&quot;C:\gstreamer\lib\glib-2.0\include\.&quot; -I&quot;C:\gstreamer\include\libxml2\.&quot; -I&quot;C:\gstreamer\include\gstreamer-1.0\.&quot; &quot;.\qglrenderer.h&quot; -o &quot;.\GeneratedFiles\$(ConfigurationName)\moc_qglrenderer.cpp&quot;&#x0D;&#x0A;"
AdditionalDependencies="&quot;$(QTDIR)\bin\moc.exe&quot;;.\qglrenderer.h"
Outputs="&quot;.\GeneratedFiles\$(ConfigurationName)\moc_qglrenderer.cpp&quot;"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCustomBuildTool"
Description="Moc&apos;ing qglrenderer.h..."
CommandLine="&quot;$(QTDIR)\bin\moc.exe&quot; -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_CORE_LIB -DQT_GUI_LIB -DQT_OPENGL_LIB -I&quot;.\GeneratedFiles\.&quot; -I&quot;$(QTDIR)\include\.&quot; -I&quot;.\GeneratedFiles\$(ConfigurationName)\.&quot; -I&quot;$(QTDIR)\include\QtCore\.&quot; -I&quot;$(QTDIR)\include\QtGui\.&quot; -I&quot;$(QTDIR)\include\QtOpenGL\.&quot; -I&quot;C:\gstreamer\include\.&quot; -I&quot;C:\gstreamer\include\glib-2.0\.&quot; -I&quot;C:\gstreamer\lib\glib-2.0\include\.&quot; -I&quot;C:\gstreamer\include\libxml2\.&quot; -I&quot;C:\gstreamer\include\gstreamer-1.0\.&quot; &quot;.\qglrenderer.h&quot; -o &quot;.\GeneratedFiles\$(ConfigurationName)\moc_qglrenderer.cpp&quot;&#x0D;&#x0A;"
AdditionalDependencies="&quot;$(QTDIR)\bin\moc.exe&quot;;.\qglrenderer.h"
Outputs="&quot;.\GeneratedFiles\$(ConfigurationName)\moc_qglrenderer.cpp&quot;"
/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Form Files"
Filter="ui"
UniqueIdentifier="{99349809-55BA-4b9d-BF79-8FDBB0286EB3}"
>
</Filter>
<Filter
Name="Resource Files"
Filter="qrc;*"
UniqueIdentifier="{D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E}"
ParseFiles="false"
>
</Filter>
<Filter
Name="Generated Files"
Filter="moc;h;cpp"
UniqueIdentifier="{71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11}"
SourceControlFiles="false"
>
<File
RelativePath=".\generatedfiles\debug\moc_gstthread.cpp"
>
</File>
<File
RelativePath=".\generatedfiles\debug\moc_pipeline.cpp"
>
</File>
<File
RelativePath=".\generatedfiles\debug\moc_qglrenderer.cpp"
>
</File>
</Filter>
</Files>
<Globals>
<Global
Name="MocDir"
Value=".\GeneratedFiles\$(ConfigurationName)"
/>
<Global
Name="QtVersion"
Value="qt-4.3.0"
/>
<Global
Name="RccDir"
Value=".\GeneratedFiles"
/>
<Global
Name="UicDir"
Value=".\GeneratedFiles"
/>
</Globals>
</VisualStudioProject>

View file

@ -0,0 +1,77 @@
/*
* GStreamer
* Copyright (C) 2009 Andrey Nechypurenko <andreynech@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef __ASYNCQUEUE_H
#define __ASYNCQUEUE_H
#include <QMutex>
#include <QWaitCondition>
#include <QList>
/**
* This is the thread safe implementation of the Queue. It can be
* used in classical producers/consumers multithreaded scenario. The
* template parameter is the class which can be put/get to/from the
* queue.
*/
template<class T>
class AsyncQueue
{
public:
AsyncQueue() : waitingReaders(0) {}
int size()
{
QMutexLocker locker(&mutex);
return this->buffer.size();
}
void put(const T& item)
{
QMutexLocker locker(&mutex);
this->buffer.push_back(item);
if(this->waitingReaders)
this->bufferIsNotEmpty.wakeOne();
}
T get()
{
QMutexLocker locker(&mutex);
while(this->buffer.size() == 0)
{
++(this->waitingReaders);
this->bufferIsNotEmpty.wait(&mutex);
--(this->waitingReaders);
}
T item = this->buffer.front();
this->buffer.pop_front();
return item;
}
private:
typedef QList<T> Container;
QMutex mutex;
QWaitCondition bufferIsNotEmpty;
Container buffer;
short waitingReaders;
};
#endif // __ASYNCQUEUE_H

View file

@ -0,0 +1,29 @@
This example illustrates how to integrate Gstreamer GL plugin with
Qt. In particular it uses glupload with fakesink elements to create
texture with decoded video frame. This texture is shared with
QGLWidget derived class, which paints a cube with video texture on
each face.
To compile the example, include and library paths might be adjusted in
.pro file according to your installation of the gstreamer and
corresponding development files. Most probably, the adjustments will
be necessary on Windows.
To run the example simply start executable file after compilation. If
there is no command line arguments provided, then videotestsrc element
will be used to generate video. The following pipeline will be created
in this case:
videotestsrc ! video/x-raw, width=640, height=480, framerate=(fraction)30/1 ! glupload ! fakesink sync=1
It is also possible to provide the video file name as a first command
line parameter, i.e. ./qglwtextureshare myvideo.ogv . In this case,
the following pipeline will be executed:
filesrc location=myvideo.ogv ! decodebin2 ! glupload ! fakesink sync=1
I would appreciate any feedback and improvement suggestions for this
example.
Have fun :-)
Andrey Nechypurenko (andreynech@gmail.com)

View file

@ -0,0 +1,26 @@
/*
* GStreamer
* Copyright (C) 2010 Julien Isorce <julien.isorce@gmail.com>
* Copyright (C) 2010 Nuno Santos <nunosantos@imaginando.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#import <Cocoa/Cocoa.h>
void *qt_current_nsopengl_context()
{
return [NSOpenGLContext currentContext];
}

View file

@ -0,0 +1,65 @@
/*
* GStreamer
* Copyright (C) 2009 Julien Isorce <julien.isorce@gmail.com>
* Copyright (C) 2009 Andrey Nechypurenko <andreynech@gmail.com>
* Copyright (C) 2010 Nuno Santos <nunosantos@imaginando.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef __GLCONTEXTID_H
#define __GLCONTEXTID_H
#include <gst/gl/gstglconfig.h>
#if defined(GST_GL_HAVE_PLATFORM_WGL)
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <Wingdi.h>
#include <GL/gl.h>
#elif defined (GST_GL_HAVE_PLATFORM_COCOA)
#include <OpenGL/OpenGL.h>
class NSOpenGLContext;
#else
#include <X11/Xlib.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glx.h>
#endif
#if defined(GST_GL_HAVE_PLATFORM_WGL)
typedef struct _tagGLContextID
{
HGLRC contextId;
HDC dc;
} GLContextID;
#elif defined(GST_GL_HAVE_PLATFORM_COCOA)
typedef struct _tagGLContextID
{
NSOpenGLContext* contextId;
} GLContextID;
#elif defined(GST_GL_HAVE_PLATFORM_GLX)
typedef struct _tagGLContextID
{
GLXContext contextId;
Display *display;
Window wnd;
} GLContextID;
#endif
#endif // __GLCONTEXTID_H

View file

@ -0,0 +1,66 @@
/*
* GStreamer
* Copyright (C) 2009 Julien Isorce <julien.isorce@gmail.com>
* Copyright (C) 2009 Andrey Nechypurenko <andreynech@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "pipeline.h"
#include "gstthread.h"
GstThread::GstThread(GstGLContext *context,
const QString &videoLocation,
const char *renderer_slot,
QObject *parent):
QThread(parent),
m_videoLocation(videoLocation)
{
this->context = context;
m_pipeline = new Pipeline(this->context, m_videoLocation, this);
QObject::connect(m_pipeline, SIGNAL(newFrameReady()), this->parent(), renderer_slot, Qt::QueuedConnection);
}
GstThread::~GstThread()
{
}
void GstThread::stop()
{
if(m_pipeline)
m_pipeline->stop();
}
void GstThread::run()
{
qDebug("Starting gst pipeline");
m_pipeline->start(); //it runs the gmainloop on win32
#ifndef Q_WS_WIN
//works like the gmainloop on linux (GstEvent are handled)
connect(m_pipeline, SIGNAL(stopRequested()), this, SLOT(quit()));
exec();
#endif
m_pipeline->unconfigure();
m_pipeline = NULL;
// This is not a memory leak. Pipeline will be deleted
// when the parent object (this) will be destroyed.
// We set m_pipeline to NULL to prevent further attempts
// to stop already stopped pipeline
}

View file

@ -0,0 +1,59 @@
/*
* GStreamer
* Copyright (C) 2009 Julien Isorce <julien.isorce@gmail.com>
* Copyright (C) 2009 Andrey Nechypurenko <andreynech@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef GSTTHREAD_H
#define GSTTHREAD_H
#include <QThread>
#include <gst/gl/gstglcontext.h>
#include "glcontextid.h"
class Pipeline;
class GstThread : public QThread
{
Q_OBJECT
public:
GstThread(GstGLContext *context,
const QString &videoLocation,
const char *renderer_slot,
QObject *parent = 0);
~GstThread();
Pipeline *getPipeline() {return this->m_pipeline;}
public Q_SLOTS:
void stop();
protected:
void run();
private:
GstGLContext *context;
const QString m_videoLocation;
Pipeline* m_pipeline;
};
#endif

View file

@ -0,0 +1,36 @@
/*
* GStreamer
* Copyright (C) 2009 Julien Isorce <julien.isorce@gmail.com>
* Copyright (C) 2009 Andrey Nechypurenko <andreynech@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <QApplication>
#include "qglrenderer.h"
int
main(int argc, char *argv[])
{
QApplication a(argc, argv);
a.connect(&a, SIGNAL(lastWindowClosed()), &a, SLOT(quit()));
QGLRenderer w(argc > 1 ? argv[1] : "");
w.setWindowTitle("Texture sharing example");
w.show();
return a.exec();
}

View file

@ -0,0 +1,109 @@
/****************************************************************************
** Meta object code from reading C++ file 'gstthread.h'
**
** Created by: The Qt Meta Object Compiler version 67 (Qt 5.2.1)
**
** WARNING! All changes made in this file will be lost!
*****************************************************************************/
#include "gstthread.h"
#include <QtCore/qbytearray.h>
#include <QtCore/qmetatype.h>
#if !defined(Q_MOC_OUTPUT_REVISION)
#error "The header file 'gstthread.h' doesn't include <QObject>."
#elif Q_MOC_OUTPUT_REVISION != 67
#error "This file was generated using the moc from 5.2.1. It"
#error "cannot be used with the include files from this version of Qt."
#error "(The moc has changed too much.)"
#endif
QT_BEGIN_MOC_NAMESPACE
struct qt_meta_stringdata_GstThread_t {
QByteArrayData data[3];
char stringdata[17];
};
#define QT_MOC_LITERAL(idx, ofs, len) \
Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
offsetof(qt_meta_stringdata_GstThread_t, stringdata) + ofs \
- idx * sizeof(QByteArrayData) \
)
static const qt_meta_stringdata_GstThread_t qt_meta_stringdata_GstThread = {
{
QT_MOC_LITERAL(0, 0, 9),
QT_MOC_LITERAL(1, 10, 4),
QT_MOC_LITERAL(2, 15, 0)
},
"GstThread\0stop\0\0"
};
#undef QT_MOC_LITERAL
static const uint qt_meta_data_GstThread[] = {
// content:
7, // revision
0, // classname
0, 0, // classinfo
1, 14, // methods
0, 0, // properties
0, 0, // enums/sets
0, 0, // constructors
0, // flags
0, // signalCount
// slots: name, argc, parameters, tag, flags
1, 0, 19, 2, 0x0a,
// slots: parameters
QMetaType::Void,
0 // eod
};
void GstThread::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
GstThread *_t = static_cast<GstThread *>(_o);
switch (_id) {
case 0: _t->stop(); break;
default: ;
}
}
Q_UNUSED(_a);
}
const QMetaObject GstThread::staticMetaObject = {
{ &QThread::staticMetaObject, qt_meta_stringdata_GstThread.data,
qt_meta_data_GstThread, qt_static_metacall, 0, 0}
};
const QMetaObject *GstThread::metaObject() const
{
return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
}
void *GstThread::qt_metacast(const char *_clname)
{
if (!_clname) return 0;
if (!strcmp(_clname, qt_meta_stringdata_GstThread.stringdata))
return static_cast<void*>(const_cast< GstThread*>(this));
return QThread::qt_metacast(_clname);
}
int GstThread::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
_id = QThread::qt_metacall(_c, _id, _a);
if (_id < 0)
return _id;
if (_c == QMetaObject::InvokeMetaMethod) {
if (_id < 1)
qt_static_metacall(this, _c, _id, _a);
_id -= 1;
} else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
if (_id < 1)
*reinterpret_cast<int*>(_a[0]) = -1;
_id -= 1;
}
return _id;
}
QT_END_MOC_NAMESPACE

View file

@ -0,0 +1,140 @@
/****************************************************************************
** Meta object code from reading C++ file 'pipeline.h'
**
** Created by: The Qt Meta Object Compiler version 67 (Qt 5.2.1)
**
** WARNING! All changes made in this file will be lost!
*****************************************************************************/
#include "pipeline.h"
#include <QtCore/qbytearray.h>
#include <QtCore/qmetatype.h>
#if !defined(Q_MOC_OUTPUT_REVISION)
#error "The header file 'pipeline.h' doesn't include <QObject>."
#elif Q_MOC_OUTPUT_REVISION != 67
#error "This file was generated using the moc from 5.2.1. It"
#error "cannot be used with the include files from this version of Qt."
#error "(The moc has changed too much.)"
#endif
QT_BEGIN_MOC_NAMESPACE
struct qt_meta_stringdata_Pipeline_t {
QByteArrayData data[4];
char stringdata[39];
};
#define QT_MOC_LITERAL(idx, ofs, len) \
Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
offsetof(qt_meta_stringdata_Pipeline_t, stringdata) + ofs \
- idx * sizeof(QByteArrayData) \
)
static const qt_meta_stringdata_Pipeline_t qt_meta_stringdata_Pipeline = {
{
QT_MOC_LITERAL(0, 0, 8),
QT_MOC_LITERAL(1, 9, 13),
QT_MOC_LITERAL(2, 23, 0),
QT_MOC_LITERAL(3, 24, 13)
},
"Pipeline\0newFrameReady\0\0stopRequested\0"
};
#undef QT_MOC_LITERAL
static const uint qt_meta_data_Pipeline[] = {
// content:
7, // revision
0, // classname
0, 0, // classinfo
2, 14, // methods
0, 0, // properties
0, 0, // enums/sets
0, 0, // constructors
0, // flags
2, // signalCount
// signals: name, argc, parameters, tag, flags
1, 0, 24, 2, 0x06,
3, 0, 25, 2, 0x06,
// signals: parameters
QMetaType::Void,
QMetaType::Void,
0 // eod
};
void Pipeline::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
Pipeline *_t = static_cast<Pipeline *>(_o);
switch (_id) {
case 0: _t->newFrameReady(); break;
case 1: _t->stopRequested(); break;
default: ;
}
} else if (_c == QMetaObject::IndexOfMethod) {
int *result = reinterpret_cast<int *>(_a[0]);
void **func = reinterpret_cast<void **>(_a[1]);
{
typedef void (Pipeline::*_t)();
if (*reinterpret_cast<_t *>(func) == static_cast<_t>(&Pipeline::newFrameReady)) {
*result = 0;
}
}
{
typedef void (Pipeline::*_t)();
if (*reinterpret_cast<_t *>(func) == static_cast<_t>(&Pipeline::stopRequested)) {
*result = 1;
}
}
}
Q_UNUSED(_a);
}
const QMetaObject Pipeline::staticMetaObject = {
{ &QObject::staticMetaObject, qt_meta_stringdata_Pipeline.data,
qt_meta_data_Pipeline, qt_static_metacall, 0, 0}
};
const QMetaObject *Pipeline::metaObject() const
{
return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
}
void *Pipeline::qt_metacast(const char *_clname)
{
if (!_clname) return 0;
if (!strcmp(_clname, qt_meta_stringdata_Pipeline.stringdata))
return static_cast<void*>(const_cast< Pipeline*>(this));
return QObject::qt_metacast(_clname);
}
int Pipeline::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
_id = QObject::qt_metacall(_c, _id, _a);
if (_id < 0)
return _id;
if (_c == QMetaObject::InvokeMetaMethod) {
if (_id < 2)
qt_static_metacall(this, _c, _id, _a);
_id -= 2;
} else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
if (_id < 2)
*reinterpret_cast<int*>(_a[0]) = -1;
_id -= 2;
}
return _id;
}
// SIGNAL 0
void Pipeline::newFrameReady()
{
QMetaObject::activate(this, &staticMetaObject, 0, 0);
}
// SIGNAL 1
void Pipeline::stopRequested()
{
QMetaObject::activate(this, &staticMetaObject, 1, 0);
}
QT_END_MOC_NAMESPACE

View file

@ -0,0 +1,132 @@
/****************************************************************************
** Meta object code from reading C++ file 'qglrenderer.h'
**
** Created by: The Qt Meta Object Compiler version 67 (Qt 5.2.1)
**
** WARNING! All changes made in this file will be lost!
*****************************************************************************/
#include "qglrenderer.h"
#include <QtCore/qbytearray.h>
#include <QtCore/qmetatype.h>
#if !defined(Q_MOC_OUTPUT_REVISION)
#error "The header file 'qglrenderer.h' doesn't include <QObject>."
#elif Q_MOC_OUTPUT_REVISION != 67
#error "This file was generated using the moc from 5.2.1. It"
#error "cannot be used with the include files from this version of Qt."
#error "(The moc has changed too much.)"
#endif
QT_BEGIN_MOC_NAMESPACE
struct qt_meta_stringdata_QGLRenderer_t {
QByteArrayData data[4];
char stringdata[38];
};
#define QT_MOC_LITERAL(idx, ofs, len) \
Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
offsetof(qt_meta_stringdata_QGLRenderer_t, stringdata) + ofs \
- idx * sizeof(QByteArrayData) \
)
static const qt_meta_stringdata_QGLRenderer_t qt_meta_stringdata_QGLRenderer = {
{
QT_MOC_LITERAL(0, 0, 11),
QT_MOC_LITERAL(1, 12, 14),
QT_MOC_LITERAL(2, 27, 0),
QT_MOC_LITERAL(3, 28, 8)
},
"QGLRenderer\0closeRequested\0\0newFrame\0"
};
#undef QT_MOC_LITERAL
static const uint qt_meta_data_QGLRenderer[] = {
// content:
7, // revision
0, // classname
0, 0, // classinfo
2, 14, // methods
0, 0, // properties
0, 0, // enums/sets
0, 0, // constructors
0, // flags
1, // signalCount
// signals: name, argc, parameters, tag, flags
1, 0, 24, 2, 0x06,
// slots: name, argc, parameters, tag, flags
3, 0, 25, 2, 0x0a,
// signals: parameters
QMetaType::Void,
// slots: parameters
QMetaType::Void,
0 // eod
};
void QGLRenderer::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
QGLRenderer *_t = static_cast<QGLRenderer *>(_o);
switch (_id) {
case 0: _t->closeRequested(); break;
case 1: _t->newFrame(); break;
default: ;
}
} else if (_c == QMetaObject::IndexOfMethod) {
int *result = reinterpret_cast<int *>(_a[0]);
void **func = reinterpret_cast<void **>(_a[1]);
{
typedef void (QGLRenderer::*_t)();
if (*reinterpret_cast<_t *>(func) == static_cast<_t>(&QGLRenderer::closeRequested)) {
*result = 0;
}
}
}
Q_UNUSED(_a);
}
const QMetaObject QGLRenderer::staticMetaObject = {
{ &QGLWidget::staticMetaObject, qt_meta_stringdata_QGLRenderer.data,
qt_meta_data_QGLRenderer, qt_static_metacall, 0, 0}
};
const QMetaObject *QGLRenderer::metaObject() const
{
return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
}
void *QGLRenderer::qt_metacast(const char *_clname)
{
if (!_clname) return 0;
if (!strcmp(_clname, qt_meta_stringdata_QGLRenderer.stringdata))
return static_cast<void*>(const_cast< QGLRenderer*>(this));
return QGLWidget::qt_metacast(_clname);
}
int QGLRenderer::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
_id = QGLWidget::qt_metacall(_c, _id, _a);
if (_id < 0)
return _id;
if (_c == QMetaObject::InvokeMetaMethod) {
if (_id < 2)
qt_static_metacall(this, _c, _id, _a);
_id -= 2;
} else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
if (_id < 2)
*reinterpret_cast<int*>(_a[0]) = -1;
_id -= 2;
}
return _id;
}
// SIGNAL 0
void QGLRenderer::closeRequested()
{
QMetaObject::activate(this, &staticMetaObject, 0, 0);
}
QT_END_MOC_NAMESPACE

View file

@ -0,0 +1,222 @@
/*
* GStreamer
* Copyright (C) 2009 Julien Isorce <julien.isorce@gmail.com>
* Copyright (C) 2009 Andrey Nechypurenko <andreynech@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "pipeline.h"
Pipeline::Pipeline(GstGLContext *context,
const QString &videoLocation,
QObject *parent)
: QObject(parent),
m_videoLocation(videoLocation),
m_loop(NULL),
m_bus(NULL),
m_pipeline(NULL)
{
this->context = context;
this->configure();
}
Pipeline::~Pipeline()
{
}
void
Pipeline::configure()
{
gst_init (NULL, NULL);
#ifdef Q_WS_WIN
m_loop = g_main_loop_new (NULL, FALSE);
#endif
if(m_videoLocation.isEmpty())
{
qDebug("No video file specified. Using video test source.");
m_pipeline =
GST_PIPELINE (gst_parse_launch
("videotestsrc ! "
"video/x-raw, width=640, height=480, "
"framerate=(fraction)30/1 ! "
"gleffects effect=5 ! fakesink sync=1",
NULL));
}
else
{
QByteArray ba = m_videoLocation.toLocal8Bit();
qDebug("Loading video: %s", ba.data());
gchar *pipeline = g_strdup_printf ("filesrc location='%s' ! "
"decodebin ! gleffects effect=5 ! "
"fakesink sync=1", ba.data());
m_pipeline = GST_PIPELINE (gst_parse_launch (pipeline, NULL));
g_free (pipeline);
}
m_bus = gst_pipeline_get_bus(GST_PIPELINE(m_pipeline));
gst_bus_add_watch(m_bus, (GstBusFunc) bus_call, this);
gst_object_unref(m_bus);
/* Retrieve the last gl element */
GstElement *gl_element = gst_bin_get_by_name(GST_BIN(m_pipeline), "gleffects0");
if(!gl_element)
{
qDebug ("gl element could not be found");
return;
}
g_object_set(G_OBJECT (gl_element), "other-context",
this->context, NULL);
gst_object_unref(gl_element);
gst_element_set_state(GST_ELEMENT(this->m_pipeline), GST_STATE_PAUSED);
GstState state = GST_STATE_PAUSED;
if(gst_element_get_state(GST_ELEMENT(this->m_pipeline),
&state, NULL, GST_CLOCK_TIME_NONE)
!= GST_STATE_CHANGE_SUCCESS)
{
qDebug("failed to pause pipeline");
return;
}
}
void
Pipeline::start()
{
// set a callback to retrieve the gst gl textures
GstElement *fakesink = gst_bin_get_by_name(GST_BIN(this->m_pipeline),
"fakesink0");
g_object_set(G_OBJECT (fakesink), "signal-handoffs", TRUE, NULL);
g_signal_connect(fakesink, "handoff", G_CALLBACK (on_gst_buffer), this);
gst_object_unref(fakesink);
GstStateChangeReturn ret =
gst_element_set_state(GST_ELEMENT(this->m_pipeline), GST_STATE_PLAYING);
if (ret == GST_STATE_CHANGE_FAILURE)
{
qDebug("Failed to start up pipeline!");
/* check if there is an error message with details on the bus */
GstMessage* msg = gst_bus_poll(this->m_bus, GST_MESSAGE_ERROR, 0);
if (msg)
{
GError *err = NULL;
gst_message_parse_error (msg, &err, NULL);
qDebug ("ERROR: %s", err->message);
g_error_free (err);
gst_message_unref (msg);
}
return;
}
#ifdef Q_WS_WIN
g_main_loop_run(m_loop);
#endif
}
/* fakesink handoff callback */
void
Pipeline::on_gst_buffer(GstElement * element,
GstBuffer * buf,
GstPad * pad,
Pipeline* p)
{
Q_UNUSED(pad)
Q_UNUSED(element)
/* ref then push buffer to use it in qt */
gst_buffer_ref(buf);
p->queue_input_buf.put(buf);
if (p->queue_input_buf.size() > 3)
p->notifyNewFrame();
/* pop then unref buffer we have finished to use in qt */
if (p->queue_output_buf.size() > 3)
{
GstBuffer *buf_old = (p->queue_output_buf.get());
if (buf_old)
gst_buffer_unref(buf_old);
}
}
void
Pipeline::stop()
{
#ifdef Q_WS_WIN
g_main_loop_quit(m_loop);
#else
emit stopRequested();
#endif
}
void
Pipeline::unconfigure()
{
gst_element_set_state(GST_ELEMENT(this->m_pipeline), GST_STATE_NULL);
GstBuffer *buf;
while(this->queue_input_buf.size())
{
buf = (GstBuffer*)(this->queue_input_buf.get());
gst_buffer_unref(buf);
}
while(this->queue_output_buf.size())
{
buf = (GstBuffer*)(this->queue_output_buf.get());
gst_buffer_unref(buf);
}
gst_object_unref(m_pipeline);
}
gboolean
Pipeline::bus_call(GstBus *bus, GstMessage *msg, Pipeline* p)
{
Q_UNUSED(bus)
switch(GST_MESSAGE_TYPE(msg))
{
case GST_MESSAGE_EOS:
qDebug("End-of-stream received. Stopping.");
p->stop();
break;
case GST_MESSAGE_ERROR:
{
gchar *debug = NULL;
GError *err = NULL;
gst_message_parse_error(msg, &err, &debug);
qDebug("Error: %s", err->message);
g_error_free (err);
if(debug)
{
qDebug("Debug deails: %s", debug);
g_free(debug);
}
p->stop();
break;
}
default:
break;
}
return TRUE;
}

View file

@ -0,0 +1,70 @@
/*
* GStreamer
* Copyright (C) 2009 Julien Isorce <julien.isorce@gmail.com>
* Copyright (C) 2009 Andrey Nechypurenko <andreynech@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef PIPELINE_H
#define PIPELINE_H
#include <QObject>
#include <gst/gl/gstglcontext.h>
#include "glcontextid.h"
#include "AsyncQueue.h"
class Pipeline : public QObject
{
Q_OBJECT
public:
Pipeline(GstGLContext *context,
const QString &videoLocation,
QObject *parent);
~Pipeline();
void configure();
void start();
void notifyNewFrame() {emit newFrameReady();}
void stop();
void unconfigure();
AsyncQueue<GstBuffer*> queue_input_buf;
AsyncQueue<GstBuffer*> queue_output_buf;
Q_SIGNALS:
void newFrameReady();
void stopRequested();
private:
GstGLContext *context;
const QString m_videoLocation;
GMainLoop* m_loop;
GstBus* m_bus;
GstPipeline* m_pipeline;
static float m_xrot;
static float m_yrot;
static float m_zrot;
static void on_gst_buffer(GstElement * element, GstBuffer * buf, GstPad * pad, Pipeline* p);
static gboolean bus_call (GstBus *bus, GstMessage *msg, Pipeline* p);
};
#endif

View file

@ -0,0 +1,231 @@
/*
* GStreamer
* Copyright (C) 2009 Julien Isorce <julien.isorce@gmail.com>
* Copyright (C) 2009 Andrey Nechypurenko <andreynech@gmail.com>
* Copyright (C) 2010 Nuno Santos <nunosantos@imaginando.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <QGLWidget>
#include <QApplication>
#include <QCloseEvent>
#include <gst/video/video.h>
#include <gst/gl/gstglmemory.h>
#include "gstthread.h"
#include "qglrenderer.h"
#include "pipeline.h"
#if defined(Q_WS_MAC)
extern void *qt_current_nsopengl_context();
#endif
QGLRenderer::QGLRenderer(const QString &videoLocation,
QWidget *parent)
: QGLWidget(parent),
videoLoc(videoLocation),
gst_thread(NULL),
closing(false),
frame(NULL)
{
move(20, 10);
resize(640, 480);
}
QGLRenderer::~QGLRenderer()
{
}
void
QGLRenderer::initializeGL()
{
GstGLContext *context;
GstGLDisplay *display;
display = gst_gl_display_new ();
/* FIXME: Allow the choice at runtime */
#if defined(GST_GL_HAVE_PLATFORM_WGL)
context = gst_gl_context_new_wrapped (display, (guintptr) wglGetCurrentContext (), GST_GL_PLATFORM_WGL, GST_GL_API_OPENGL);
#elif defined (GST_GL_HAVE_PLATFORM_COCOA)
context = gst_gl_context_new_wrapped (display, (guintptr) qt_current_nsopengl_context(), GST_GL_PLATFORM_COCOA, GST_GL_API_OPENGL);
#elif defined(GST_GL_HAVE_PLATFORM_GLX)
context = gst_gl_context_new_wrapped (display, (guintptr) glXGetCurrentContext (), GST_GL_PLATFORM_GLX, GST_GL_API_OPENGL);
#endif
gst_object_unref (display);
// We need to unset Qt context before initializing gst-gl plugin.
// Otherwise the attempt to share gst-gl context with Qt will fail.
this->doneCurrent();
this->gst_thread =
new GstThread(context, this->videoLoc, SLOT(newFrame()), this);
this->makeCurrent();
QObject::connect(this->gst_thread, SIGNAL(finished()),
this, SLOT(close()));
QObject::connect(this, SIGNAL(closeRequested()),
this->gst_thread, SLOT(stop()), Qt::QueuedConnection);
qglClearColor(QApplication::palette().color(QPalette::Active,
QPalette::Window));
//glShadeModel(GL_FLAT);
//glEnable(GL_DEPTH_TEST);
//glEnable(GL_CULL_FACE);
glEnable(GL_TEXTURE_2D); // Enable Texture Mapping
this->gst_thread->start();
}
void
QGLRenderer::resizeGL(int width, int height)
{
// Reset The Current Viewport And Perspective Transformation
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, (GLfloat)width/(GLfloat)height, 0.1f, 100.0f);
glMatrixMode(GL_MODELVIEW);
}
void
QGLRenderer::newFrame()
{
Pipeline *pipeline = this->gst_thread->getPipeline();
if(!pipeline)
return;
/* frame is initialized as null */
if (this->frame)
pipeline->queue_output_buf.put(this->frame);
this->frame = pipeline->queue_input_buf.get();
/* direct call to paintGL (no queued) */
this->updateGL();
}
void
QGLRenderer::paintGL()
{
static GLfloat xrot = 0;
static GLfloat yrot = 0;
static GLfloat zrot = 0;
if (this->frame)
{
guint tex_id;
GstMemory *mem;
GstVideoInfo v_info;
GstVideoFrame v_frame;
GstVideoMeta *v_meta;
mem = gst_buffer_peek_memory (this->frame, 0);
v_meta = gst_buffer_get_video_meta (this->frame);
if (gst_is_gl_memory (mem)) {
gst_video_info_set_format (&v_info, v_meta->format, v_meta->width,
v_meta->height);
gst_video_frame_map (&v_frame, &v_info, this->frame,
(GstMapFlags) (GST_MAP_READ | GST_MAP_GL));
tex_id = *(guint *) v_frame.data[0];
}
glEnable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, tex_id);
if(glGetError () != GL_NO_ERROR)
{
qDebug ("failed to bind texture that comes from gst-gl");
emit closeRequested();
return;
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
GL_CLAMP_TO_EDGE);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0f,0.0f,-5.0f);
glRotatef(xrot,1.0f,0.0f,0.0f);
glRotatef(yrot,0.0f,1.0f,0.0f);
glRotatef(zrot,0.0f,0.0f,1.0f);
glBegin(GL_QUADS);
// Front Face
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, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
// Back Face
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
// Top Face
glTexCoord2f(1.0f, 1.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, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
// Bottom Face
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, 1.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
// Right face
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
// Left Face
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, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glEnd();
xrot+=0.3f;
yrot+=0.2f;
zrot+=0.4f;
glBindTexture(GL_TEXTURE_2D, 0);
}
}
void
QGLRenderer::closeEvent(QCloseEvent* event)
{
if(this->closing == false)
{
this->closing = true;
emit closeRequested();
event->ignore();
}
}

View file

@ -0,0 +1,60 @@
/*
* GStreamer
* Copyright (C) 2009 Julien Isorce <julien.isorce@gmail.com>
* Copyright (C) 2009 Andrey Nechypurenko <andreynech@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef QGLRENDERER_H
#define QGLRENDERER_H
#include <QGLWidget>
#include <gst/gl/gstglcontext.h>
class GstThread;
class QGLRenderer : public QGLWidget
{
Q_OBJECT
public:
QGLRenderer(const QString &videoLocation, QWidget *parent = 0);
~QGLRenderer();
void closeEvent(QCloseEvent* event);
Q_SIGNALS:
void closeRequested();
public Q_SLOTS:
void newFrame();
protected:
virtual void initializeGL();
virtual void resizeGL(int width, int height);
virtual void paintGL();
private:
QString videoLoc;
GstThread *gst_thread;
bool closing;
GstBuffer *frame;
};
#endif // QGLRENDERER_H

Binary file not shown.

View file

@ -0,0 +1,83 @@
TEMPLATE = app
TARGET = qglwtextureshare
QT += opengl
# Add console to the CONFIG to see debug messages printed in
# the console on Windows
# CONFIG += console
DEFINES += UNICODE QT_THREAD_SUPPORT QT_CORE_LIB QT_GUI_LIB
win32 {
DEFINES += WIN32
INCLUDEPATH += \
C:/gstreamer/include \
C:/gstreamer/include/libxml2 \
C:/gstreamer/include/glib-2.0 \
C:/gstreamer/lib/glib-2.0/include \
C:/gstreamer/include/gstreamer-1.0
LIBS += -L"C:/gstreamer/lib" \
-L"C:/gstreamer/bin" \
-lgstreamer-1.0 \
-lgstvideo-1.0 \
-lglib-2.0 \
-lgmodule-2.0 \
-lgobject-2.0 \
-lgthread-2.0 \
-lgstvideo-1.0 \
-lopengl32 \
-lglu32
}
unix:!mac {
DEFINES += UNIX
INCLUDEPATH += /home/matt/Projects/jhbuild/native/usr/include/gstreamer-1.0 \
/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 \
-lglib-2.0 \
-lgmodule-2.0 \
-lgobject-2.0 \
-lgthread-2.0 \
-lgstgl-1.0 \
-lGLU \
-lGL
}
mac {
DEFINES += MACOSX
INCLUDEPATH += /opt/local/include/ \
/opt/local/include/gstreamer-1.0/ \
/opt/local/include/glib-2.0/ \
/opt/local/lib/glib-2.0/include \
/opt/local/include/libxml2
LIBS += -L/opt/local/lib \
-lgstreamer-1.0 \
-lgstapp-1.0 \
-lgstvideo-1.0 \
-lglib-2.0 \
-lgobject-2.0 \
-lcxcore \
-lcvaux \
-lcv
OBJECTIVE_SOURCES += cocoa_utils.mm
LIBS += -framework AppKit
}
DEPENDPATH += .
# Header files
HEADERS += gstthread.h \
pipeline.h \
qglrenderer.h \
AsyncQueue.h \
glcontextid.h
# Source files
SOURCES += gstthread.cpp \
main.cpp \
pipeline.cpp \
qglrenderer.cpp

Some files were not shown because too many files have changed in this diff Show more