diff options
author | Matthew Waters <ystreet00@gmail.com> | 2014-04-29 16:38:55 +1000 |
---|---|---|
committer | Matthew Waters <ystreet00@gmail.com> | 2014-04-29 16:40:08 +1000 |
commit | 294da02a2f85438b942eb90c279a5f05169f1ae0 (patch) | |
tree | 2c4263695ce3472e69a05185e6033cb642a96ca5 /tests | |
parent | 967982a0b5362d500081d3353667e089b996641b (diff) | |
download | gstreamer-plugins-bad-294da02a2f85438b942eb90c279a5f05169f1ae0.tar.gz |
gl/examples: move to -bad
- fix all the compiler errors
- give them their own gl directory
Diffstat (limited to 'tests')
113 files changed, 9663 insertions, 28 deletions
diff --git a/tests/examples/Makefile.am b/tests/examples/Makefile.am index 43513994a..7429f754e 100644 --- a/tests/examples/Makefile.am +++ b/tests/examples/Makefile.am @@ -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 diff --git a/tests/examples/gl/Makefile.am b/tests/examples/gl/Makefile.am new file mode 100644 index 000000000..8d7d9f774 --- /dev/null +++ b/tests/examples/gl/Makefile.am @@ -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 diff --git a/tests/examples/gl/clutter/.gitignore b/tests/examples/gl/clutter/.gitignore new file mode 100644 index 000000000..9b1eb5393 --- /dev/null +++ b/tests/examples/gl/clutter/.gitignore @@ -0,0 +1,3 @@ +clutteractor +clutteractortee +cluttershare diff --git a/tests/examples/gl/clutter/Makefile.am b/tests/examples/gl/clutter/Makefile.am new file mode 100644 index 000000000..0383a6a2f --- /dev/null +++ b/tests/examples/gl/clutter/Makefile.am @@ -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 diff --git a/tests/examples/clutter/clutteractor.c b/tests/examples/gl/clutter/clutteractor.c index 44c97ba7c..44c97ba7c 100644 --- a/tests/examples/clutter/clutteractor.c +++ b/tests/examples/gl/clutter/clutteractor.c diff --git a/tests/examples/clutter/clutteractortee.c b/tests/examples/gl/clutter/clutteractortee.c index a46f32383..a46f32383 100644 --- a/tests/examples/clutter/clutteractortee.c +++ b/tests/examples/gl/clutter/clutteractortee.c diff --git a/tests/examples/clutter/cluttershare.c b/tests/examples/gl/clutter/cluttershare.c index 9e2719bf0..d3f1b1e10 100644 --- a/tests/examples/clutter/cluttershare.c +++ b/tests/examples/gl/clutter/cluttershare.c @@ -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)) { diff --git a/tests/examples/gl/clutter/cluttershare.cbp b/tests/examples/gl/clutter/cluttershare.cbp new file mode 100644 index 000000000..cb4907e6d --- /dev/null +++ b/tests/examples/gl/clutter/cluttershare.cbp @@ -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> diff --git a/tests/examples/gl/cocoa/Makefile.am b/tests/examples/gl/cocoa/Makefile.am new file mode 100755 index 000000000..716aa30e5 --- /dev/null +++ b/tests/examples/gl/cocoa/Makefile.am @@ -0,0 +1,4 @@ + +if HAVE_WINDOW_COCOA +SUBDIRS = videooverlay +endif diff --git a/tests/examples/gl/cocoa/README b/tests/examples/gl/cocoa/README new file mode 100644 index 000000000..74fe337ba --- /dev/null +++ b/tests/examples/gl/cocoa/README @@ -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 diff --git a/tests/examples/gl/cocoa/videooverlay/.gitignore b/tests/examples/gl/cocoa/videooverlay/.gitignore new file mode 100644 index 000000000..c5ee310fb --- /dev/null +++ b/tests/examples/gl/cocoa/videooverlay/.gitignore @@ -0,0 +1 @@ +videooverlay diff --git a/tests/examples/gl/cocoa/videooverlay/Makefile.am b/tests/examples/gl/cocoa/videooverlay/Makefile.am new file mode 100755 index 000000000..47dac610c --- /dev/null +++ b/tests/examples/gl/cocoa/videooverlay/Makefile.am @@ -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 diff --git a/tests/examples/gl/cocoa/videooverlay/main.m b/tests/examples/gl/cocoa/videooverlay/main.m new file mode 100755 index 000000000..8f959fe0b --- /dev/null +++ b/tests/examples/gl/cocoa/videooverlay/main.m @@ -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; +} diff --git a/tests/examples/gl/generic/Makefile.am b/tests/examples/gl/generic/Makefile.am new file mode 100644 index 000000000..a334e12e3 --- /dev/null +++ b/tests/examples/gl/generic/Makefile.am @@ -0,0 +1,2 @@ + +SUBDIRS = cube cubeyuv doublecube recordgraphic diff --git a/tests/examples/gl/generic/README b/tests/examples/gl/generic/README new file mode 100644 index 000000000..a91d6bffe --- /dev/null +++ b/tests/examples/gl/generic/README @@ -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. diff --git a/tests/examples/gl/generic/cube/.gitignore b/tests/examples/gl/generic/cube/.gitignore new file mode 100644 index 000000000..3c088ddc8 --- /dev/null +++ b/tests/examples/gl/generic/cube/.gitignore @@ -0,0 +1 @@ +cube diff --git a/tests/examples/gl/generic/cube/Makefile.am b/tests/examples/gl/generic/cube/Makefile.am new file mode 100644 index 000000000..41a5e2c63 --- /dev/null +++ b/tests/examples/gl/generic/cube/Makefile.am @@ -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) + diff --git a/tests/examples/gl/generic/cube/cube.vcproj b/tests/examples/gl/generic/cube/cube.vcproj new file mode 100644 index 000000000..aefb6ad54 --- /dev/null +++ b/tests/examples/gl/generic/cube/cube.vcproj @@ -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=""C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";"C:\gstreamer\include\gstreamer-1.0";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=""C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";"C:\gstreamer\include\gstreamer-1.0";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> diff --git a/tests/examples/gl/generic/cube/main.cpp b/tests/examples/gl/generic/cube/main.cpp new file mode 100644 index 000000000..b3b167cf7 --- /dev/null +++ b/tests/examples/gl/generic/cube/main.cpp @@ -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 (¤t_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; + +} diff --git a/tests/examples/gl/generic/cubeyuv/.gitignore b/tests/examples/gl/generic/cubeyuv/.gitignore new file mode 100644 index 000000000..bd5c0cee3 --- /dev/null +++ b/tests/examples/gl/generic/cubeyuv/.gitignore @@ -0,0 +1 @@ +cubeyuv diff --git a/tests/examples/gl/generic/cubeyuv/Makefile.am b/tests/examples/gl/generic/cubeyuv/Makefile.am new file mode 100644 index 000000000..0fe4fcda9 --- /dev/null +++ b/tests/examples/gl/generic/cubeyuv/Makefile.am @@ -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) + diff --git a/tests/examples/gl/generic/cubeyuv/cubeyuv.vcproj b/tests/examples/gl/generic/cubeyuv/cubeyuv.vcproj new file mode 100644 index 000000000..1d2085932 --- /dev/null +++ b/tests/examples/gl/generic/cubeyuv/cubeyuv.vcproj @@ -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=""C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";"C:\gstreamer\include\gstreamer-1.0";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=""C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";"C:\gstreamer\include\gstreamer-1.0";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> diff --git a/tests/examples/gl/generic/cubeyuv/main.cpp b/tests/examples/gl/generic/cubeyuv/main.cpp new file mode 100644 index 000000000..6e17b6ad0 --- /dev/null +++ b/tests/examples/gl/generic/cubeyuv/main.cpp @@ -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 (¤t_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; + +} + diff --git a/tests/examples/gl/generic/doublecube/.gitignore b/tests/examples/gl/generic/doublecube/.gitignore new file mode 100644 index 000000000..e9f4f133b --- /dev/null +++ b/tests/examples/gl/generic/doublecube/.gitignore @@ -0,0 +1 @@ +doublecube diff --git a/tests/examples/gl/generic/doublecube/Makefile.am b/tests/examples/gl/generic/doublecube/Makefile.am new file mode 100644 index 000000000..7a9184bb2 --- /dev/null +++ b/tests/examples/gl/generic/doublecube/Makefile.am @@ -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) + diff --git a/tests/examples/gl/generic/doublecube/doublecube.vcproj b/tests/examples/gl/generic/doublecube/doublecube.vcproj new file mode 100644 index 000000000..db0364b78 --- /dev/null +++ b/tests/examples/gl/generic/doublecube/doublecube.vcproj @@ -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=""C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";"C:\gstreamer\include\gstreamer-1.0";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=""C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";"C:\gstreamer\include\gstreamer-1.0";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> diff --git a/tests/examples/gl/generic/doublecube/main.cpp b/tests/examples/gl/generic/doublecube/main.cpp new file mode 100644 index 000000000..4f283362e --- /dev/null +++ b/tests/examples/gl/generic/doublecube/main.cpp @@ -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 (¤t_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; + +} + diff --git a/tests/examples/gl/generic/generic.sln b/tests/examples/gl/generic/generic.sln new file mode 100644 index 000000000..22e86f64e --- /dev/null +++ b/tests/examples/gl/generic/generic.sln @@ -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 diff --git a/tests/examples/gl/generic/recordgraphic/.gitignore b/tests/examples/gl/generic/recordgraphic/.gitignore new file mode 100644 index 000000000..8127d8360 --- /dev/null +++ b/tests/examples/gl/generic/recordgraphic/.gitignore @@ -0,0 +1 @@ +recordgraphic diff --git a/tests/examples/gl/generic/recordgraphic/Makefile.am b/tests/examples/gl/generic/recordgraphic/Makefile.am new file mode 100644 index 000000000..4ee21ac3b --- /dev/null +++ b/tests/examples/gl/generic/recordgraphic/Makefile.am @@ -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) + diff --git a/tests/examples/gl/generic/recordgraphic/main.cpp b/tests/examples/gl/generic/recordgraphic/main.cpp new file mode 100644 index 000000000..fd0ceb0c8 --- /dev/null +++ b/tests/examples/gl/generic/recordgraphic/main.cpp @@ -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 (¤t_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; + +} diff --git a/tests/examples/gl/generic/recordgraphic/recordgraphic.vcproj b/tests/examples/gl/generic/recordgraphic/recordgraphic.vcproj new file mode 100644 index 000000000..66df375c2 --- /dev/null +++ b/tests/examples/gl/generic/recordgraphic/recordgraphic.vcproj @@ -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=""C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";"C:\gstreamer\include\gstreamer-1.0";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=""C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";"C:\gstreamer\include\gstreamer-1.0";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> diff --git a/tests/examples/gl/gtk/Makefile.am b/tests/examples/gl/gtk/Makefile.am new file mode 100644 index 000000000..c64cd4a38 --- /dev/null +++ b/tests/examples/gl/gtk/Makefile.am @@ -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 + diff --git a/tests/examples/gl/gtk/README b/tests/examples/gl/gtk/README new file mode 100644 index 000000000..76595c6bf --- /dev/null +++ b/tests/examples/gl/gtk/README @@ -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 diff --git a/tests/examples/gl/gtk/filternovideooverlay/.gitignore b/tests/examples/gl/gtk/filternovideooverlay/.gitignore new file mode 100644 index 000000000..f6e41625b --- /dev/null +++ b/tests/examples/gl/gtk/filternovideooverlay/.gitignore @@ -0,0 +1 @@ +filternovideooverlay diff --git a/tests/examples/gl/gtk/filternovideooverlay/Makefile.am b/tests/examples/gl/gtk/filternovideooverlay/Makefile.am new file mode 100644 index 000000000..61526c544 --- /dev/null +++ b/tests/examples/gl/gtk/filternovideooverlay/Makefile.am @@ -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) + diff --git a/tests/examples/gl/gtk/filternovideooverlay/filternovideooverlay.vcproj b/tests/examples/gl/gtk/filternovideooverlay/filternovideooverlay.vcproj new file mode 100644 index 000000000..473587bc1 --- /dev/null +++ b/tests/examples/gl/gtk/filternovideooverlay/filternovideooverlay.vcproj @@ -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=""C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";"..\..\..\..\..\gtk+\include\gtk-2.0";"..\..\..\..\..\gtk+\lib\gtk-2.0\include";"C:\gstreamer\include\gstreamer-1.0";C:\gstreamer\include\cairo;"C:\gstreamer\include\pango-1.0";"..\..\..\..\..\atk\include\atk-1.0";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;"..\..\..\..\..\gtk+\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=""C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";"..\..\..\..\..\gtk+\include\gtk-2.0";"..\..\..\..\..\gtk+\lib\gtk-2.0\include";"C:\gstreamer\include\gstreamer-1.0";C:\gstreamer\include\cairo;"C:\gstreamer\include\pango-1.0";"..\..\..\..\..\atk\include\atk-1.0";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;"..\..\..\..\..\gtk+\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> diff --git a/tests/examples/gl/gtk/filternovideooverlay/main.cpp b/tests/examples/gl/gtk/filternovideooverlay/main.cpp new file mode 100644 index 000000000..5b9257cda --- /dev/null +++ b/tests/examples/gl/gtk/filternovideooverlay/main.cpp @@ -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; +} + diff --git a/tests/examples/gl/gtk/filtervideooverlay/.gitignore b/tests/examples/gl/gtk/filtervideooverlay/.gitignore new file mode 100644 index 000000000..c5e1611f6 --- /dev/null +++ b/tests/examples/gl/gtk/filtervideooverlay/.gitignore @@ -0,0 +1 @@ +filtervideooverlay diff --git a/tests/examples/gl/gtk/filtervideooverlay/Makefile.am b/tests/examples/gl/gtk/filtervideooverlay/Makefile.am new file mode 100644 index 000000000..4d7f129c2 --- /dev/null +++ b/tests/examples/gl/gtk/filtervideooverlay/Makefile.am @@ -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) + diff --git a/tests/examples/gl/gtk/filtervideooverlay/filtervideooverlay.vcproj b/tests/examples/gl/gtk/filtervideooverlay/filtervideooverlay.vcproj new file mode 100644 index 000000000..564daa9da --- /dev/null +++ b/tests/examples/gl/gtk/filtervideooverlay/filtervideooverlay.vcproj @@ -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=""C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";"..\..\..\..\..\gtk+\include\gtk-2.0";"..\..\..\..\..\gtk+\lib\gtk-2.0\include";"C:\gstreamer\include\gstreamer-1.0";C:\gstreamer\include\cairo;"C:\gstreamer\include\pango-1.0";"..\..\..\..\..\atk\include\atk-1.0";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;"..\..\..\..\..\gtk+\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=""C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";"..\..\..\..\..\gtk+\include\gtk-2.0";"..\..\..\..\..\gtk+\lib\gtk-2.0\include";"C:\gstreamer\include\gstreamer-1.0";C:\gstreamer\include\cairo;"C:\gstreamer\include\pango-1.0";"..\..\..\..\..\atk\include\atk-1.0";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;"..\..\..\..\..\gtk+\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="..\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> diff --git a/tests/examples/gl/gtk/filtervideooverlay/main.cpp b/tests/examples/gl/gtk/filtervideooverlay/main.cpp new file mode 100644 index 000000000..8ca402d8b --- /dev/null +++ b/tests/examples/gl/gtk/filtervideooverlay/main.cpp @@ -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; +} + diff --git a/tests/examples/gl/gtk/fxtest/.gitignore b/tests/examples/gl/gtk/fxtest/.gitignore new file mode 100644 index 000000000..c35569775 --- /dev/null +++ b/tests/examples/gl/gtk/fxtest/.gitignore @@ -0,0 +1,2 @@ +fxtest +pixbufdrop diff --git a/tests/examples/gl/gtk/fxtest/Makefile.am b/tests/examples/gl/gtk/fxtest/Makefile.am new file mode 100644 index 000000000..c5e5d1ae2 --- /dev/null +++ b/tests/examples/gl/gtk/fxtest/Makefile.am @@ -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) diff --git a/tests/examples/gtk/fxtest/fxtest.c b/tests/examples/gl/gtk/fxtest/fxtest.c index 7ff5d71d4..a9b41c192 100644 --- a/tests/examples/gtk/fxtest/fxtest.c +++ b/tests/examples/gl/gtk/fxtest/fxtest.c @@ -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"); diff --git a/tests/examples/gl/gtk/fxtest/fxtest.vcproj b/tests/examples/gl/gtk/fxtest/fxtest.vcproj new file mode 100644 index 000000000..05a2de02e --- /dev/null +++ b/tests/examples/gl/gtk/fxtest/fxtest.vcproj @@ -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=""C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";"..\..\..\..\..\gtk+\include\gtk-2.0";"..\..\..\..\..\gtk+\lib\gtk-2.0\include";"C:\gstreamer\include\gstreamer-1.0";C:\gstreamer\include\cairo;"C:\gstreamer\include\pango-1.0";"..\..\..\..\..\atk\include\atk-1.0";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;"..\..\..\..\..\gtk+\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=""C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";"..\..\..\..\..\gtk+\include\gtk-2.0";"..\..\..\..\..\gtk+\lib\gtk-2.0\include";"C:\gstreamer\include\gstreamer-1.0";C:\gstreamer\include\cairo;"C:\gstreamer\include\pango-1.0";"..\..\..\..\..\atk\include\atk-1.0";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;"..\..\..\..\..\gtk+\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=".\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> diff --git a/tests/examples/gtk/fxtest/pixbufdrop.c b/tests/examples/gl/gtk/fxtest/pixbufdrop.c index 7422e8afc..4b26c3eb0 100644 --- a/tests/examples/gtk/fxtest/pixbufdrop.c +++ b/tests/examples/gl/gtk/fxtest/pixbufdrop.c @@ -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; diff --git a/tests/examples/gtk/gstgtk.c b/tests/examples/gl/gtk/gstgtk.c index 3d0d15ae2..b13304c89 100644 --- a/tests/examples/gtk/gstgtk.c +++ b/tests/examples/gl/gtk/gstgtk.c @@ -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)); diff --git a/tests/examples/gl/gtk/gstgtk.h b/tests/examples/gl/gtk/gstgtk.h new file mode 100644 index 000000000..4ef147f55 --- /dev/null +++ b/tests/examples/gl/gtk/gstgtk.h @@ -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 + diff --git a/tests/examples/gl/gtk/gtk.sln b/tests/examples/gl/gtk/gtk.sln new file mode 100644 index 000000000..5bf66dcfe --- /dev/null +++ b/tests/examples/gl/gtk/gtk.sln @@ -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 diff --git a/tests/examples/gl/gtk/gtkvideooverlay/.gitignore b/tests/examples/gl/gtk/gtkvideooverlay/.gitignore new file mode 100644 index 000000000..e4c3e3ffe --- /dev/null +++ b/tests/examples/gl/gtk/gtkvideooverlay/.gitignore @@ -0,0 +1 @@ +gtkvideooverlay diff --git a/tests/examples/gl/gtk/gtkvideooverlay/Makefile.am b/tests/examples/gl/gtk/gtkvideooverlay/Makefile.am new file mode 100644 index 000000000..c9dba8aa7 --- /dev/null +++ b/tests/examples/gl/gtk/gtkvideooverlay/Makefile.am @@ -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) + diff --git a/tests/examples/gl/gtk/gtkvideooverlay/gtkvideooverlay.vcproj b/tests/examples/gl/gtk/gtkvideooverlay/gtkvideooverlay.vcproj new file mode 100644 index 000000000..f818fc649 --- /dev/null +++ b/tests/examples/gl/gtk/gtkvideooverlay/gtkvideooverlay.vcproj @@ -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=""C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";"..\..\..\..\..\gtk+\include\gtk-2.0";"..\..\..\..\..\gtk+\lib\gtk-2.0\include";"C:\gstreamer\include\gstreamer-1.0";C:\gstreamer\include\cairo;"C:\gstreamer\include\pango-1.0";"..\..\..\..\..\atk\include\atk-1.0";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;"..\..\..\..\..\gtk+\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=""C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";"..\..\..\..\..\gtk+\include\gtk-2.0";"..\..\..\..\..\gtk+\lib\gtk-2.0\include";"C:\gstreamer\include\gstreamer-1.0";C:\gstreamer\include\cairo;"C:\gstreamer\include\pango-1.0";"..\..\..\..\..\atk\include\atk-1.0";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;"..\..\..\..\..\gtk+\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="..\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> diff --git a/tests/examples/gl/gtk/gtkvideooverlay/main.cpp b/tests/examples/gl/gtk/gtkvideooverlay/main.cpp new file mode 100644 index 000000000..7024cfca3 --- /dev/null +++ b/tests/examples/gl/gtk/gtkvideooverlay/main.cpp @@ -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; +} + diff --git a/tests/examples/gl/gtk/pixbufdrop/pixbufdrop.vcproj b/tests/examples/gl/gtk/pixbufdrop/pixbufdrop.vcproj new file mode 100644 index 000000000..d38ecc71f --- /dev/null +++ b/tests/examples/gl/gtk/pixbufdrop/pixbufdrop.vcproj @@ -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=""C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";"..\..\..\..\..\gtk+\include\gtk-2.0";"..\..\..\..\..\gtk+\lib\gtk-2.0\include";"C:\gstreamer\include\gstreamer-1.0";C:\gstreamer\include\cairo;"C:\gstreamer\include\pango-1.0";"..\..\..\..\..\atk\include\atk-1.0";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;"..\..\..\..\..\gtk+\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=""C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";"..\..\..\..\..\gtk+\include\gtk-2.0";"..\..\..\..\..\gtk+\lib\gtk-2.0\include";"C:\gstreamer\include\gstreamer-1.0";C:\gstreamer\include\cairo;"C:\gstreamer\include\pango-1.0";"..\..\..\..\..\atk\include\atk-1.0";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;"..\..\..\..\..\gtk+\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="..\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> diff --git a/tests/examples/gl/gtk/switchvideooverlay/.gitignore b/tests/examples/gl/gtk/switchvideooverlay/.gitignore new file mode 100644 index 000000000..64c6de420 --- /dev/null +++ b/tests/examples/gl/gtk/switchvideooverlay/.gitignore @@ -0,0 +1 @@ +switchvideooverlay diff --git a/tests/examples/gl/gtk/switchvideooverlay/Makefile.am b/tests/examples/gl/gtk/switchvideooverlay/Makefile.am new file mode 100644 index 000000000..12e25e75c --- /dev/null +++ b/tests/examples/gl/gtk/switchvideooverlay/Makefile.am @@ -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) + diff --git a/tests/examples/gl/gtk/switchvideooverlay/main.cpp b/tests/examples/gl/gtk/switchvideooverlay/main.cpp new file mode 100644 index 000000000..440d5ce5a --- /dev/null +++ b/tests/examples/gl/gtk/switchvideooverlay/main.cpp @@ -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; +} + diff --git a/tests/examples/gl/gtk/switchvideooverlay/switchvideooverlay.vcproj b/tests/examples/gl/gtk/switchvideooverlay/switchvideooverlay.vcproj new file mode 100644 index 000000000..8e48bbe58 --- /dev/null +++ b/tests/examples/gl/gtk/switchvideooverlay/switchvideooverlay.vcproj @@ -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=""C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";"..\..\..\..\..\gtk+\include\gtk-2.0";"..\..\..\..\..\gtk+\lib\gtk-2.0\include";"C:\gstreamer\include\gstreamer-1.0";C:\gstreamer\include\cairo;"C:\gstreamer\include\pango-1.0";"..\..\..\..\..\atk\include\atk-1.0";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;"..\..\..\..\..\gtk+\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=""C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";"..\..\..\..\..\gtk+\include\gtk-2.0";"..\..\..\..\..\gtk+\lib\gtk-2.0\include";"C:\gstreamer\include\gstreamer-1.0";C:\gstreamer\include\cairo;"C:\gstreamer\include\pango-1.0";"..\..\..\..\..\atk\include\atk-1.0";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;"..\..\..\..\..\gtk+\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="..\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> diff --git a/tests/examples/gl/qt/Makefile.am b/tests/examples/gl/qt/Makefile.am new file mode 100644 index 000000000..629415b29 --- /dev/null +++ b/tests/examples/gl/qt/Makefile.am @@ -0,0 +1,2 @@ + +#SUBDIRS = videooverlay qglwidgetvideooverlay mousevideooverlay diff --git a/tests/examples/gl/qt/README b/tests/examples/gl/qt/README new file mode 100644 index 000000000..aa843d639 --- /dev/null +++ b/tests/examples/gl/qt/README @@ -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 diff --git a/tests/examples/gl/qt/mousevideooverlay/gstthread.cpp b/tests/examples/gl/qt/mousevideooverlay/gstthread.cpp new file mode 100644 index 000000000..ce14a4715 --- /dev/null +++ b/tests/examples/gl/qt/mousevideooverlay/gstthread.cpp @@ -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(); +} diff --git a/tests/examples/gl/qt/mousevideooverlay/gstthread.h b/tests/examples/gl/qt/mousevideooverlay/gstthread.h new file mode 100644 index 000000000..74f1322c7 --- /dev/null +++ b/tests/examples/gl/qt/mousevideooverlay/gstthread.h @@ -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 diff --git a/tests/examples/gl/qt/mousevideooverlay/main.cpp b/tests/examples/gl/qt/mousevideooverlay/main.cpp new file mode 100644 index 000000000..0cec1b97f --- /dev/null +++ b/tests/examples/gl/qt/mousevideooverlay/main.cpp @@ -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(); +} diff --git a/tests/examples/gl/qt/mousevideooverlay/mousevideooverlay.pri b/tests/examples/gl/qt/mousevideooverlay/mousevideooverlay.pri new file mode 100644 index 000000000..75b23cdd7 --- /dev/null +++ b/tests/examples/gl/qt/mousevideooverlay/mousevideooverlay.pri @@ -0,0 +1,10 @@ +#Header files +HEADERS += ./gstthread.h \ + ./pipeline.h \ + ./qrenderer.h + +#Source files +SOURCES += ./gstthread.cpp \ + ./main.cpp \ + ./pipeline.cpp \ + ./qrenderer.cpp diff --git a/tests/examples/gl/qt/mousevideooverlay/mousevideooverlay.pro b/tests/examples/gl/qt/mousevideooverlay/mousevideooverlay.pro new file mode 100644 index 000000000..efd69cd09 --- /dev/null +++ b/tests/examples/gl/qt/mousevideooverlay/mousevideooverlay.pro @@ -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) diff --git a/tests/examples/gl/qt/mousevideooverlay/mousevideooverlay.sln b/tests/examples/gl/qt/mousevideooverlay/mousevideooverlay.sln new file mode 100644 index 000000000..8d310d810 --- /dev/null +++ b/tests/examples/gl/qt/mousevideooverlay/mousevideooverlay.sln @@ -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 diff --git a/tests/examples/gl/qt/mousevideooverlay/mousevideooverlay.vcproj b/tests/examples/gl/qt/mousevideooverlay/mousevideooverlay.vcproj new file mode 100644 index 000000000..e4b7b180e --- /dev/null +++ b/tests/examples/gl/qt/mousevideooverlay/mousevideooverlay.vcproj @@ -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;"$(QTDIR)\include";".\GeneratedFiles\$(ConfigurationName)";"$(QTDIR)\include\QtCore";"$(QTDIR)\include\QtGui";C:\gstreamer\include;"C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";C:\gstreamer\include\libxml2;"C:\gstreamer\include\gstreamer-1.0"" + 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=""$(QTDIR)\lib";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;"$(QTDIR)\include";".\GeneratedFiles\$(ConfigurationName)";"$(QTDIR)\include\QtCore";"$(QTDIR)\include\QtGui";C:\gstreamer\include;"C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";C:\gstreamer\include\libxml2;"C:\gstreamer\include\gstreamer-1.0"" + 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=""$(QTDIR)\lib";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'ing gstthread.h..." + CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -I".\GeneratedFiles\." -I"$(QTDIR)\include\." -I".\GeneratedFiles\$(ConfigurationName)\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"C:\gstreamer\include\." -I"C:\gstreamer\include\glib-2.0\." -I"C:\gstreamer\lib\glib-2.0\include\." -I"C:\gstreamer\include\libxml2\." -I"C:\gstreamer\include\gstreamer-1.0\." ".\gstthread.h" -o ".\GeneratedFiles\$(ConfigurationName)\moc_gstthread.cpp"
" + AdditionalDependencies=""$(QTDIR)\bin\moc.exe";.\gstthread.h" + Outputs="".\GeneratedFiles\$(ConfigurationName)\moc_gstthread.cpp"" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Moc'ing gstthread.h..." + CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_CORE_LIB -DQT_GUI_LIB -I".\GeneratedFiles\." -I"$(QTDIR)\include\." -I".\GeneratedFiles\$(ConfigurationName)\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"C:\gstreamer\include\." -I"C:\gstreamer\include\glib-2.0\." -I"C:\gstreamer\lib\glib-2.0\include\." -I"C:\gstreamer\include\libxml2\." -I"C:\gstreamer\include\gstreamer-1.0\." ".\gstthread.h" -o ".\GeneratedFiles\$(ConfigurationName)\moc_gstthread.cpp"
" + AdditionalDependencies=""$(QTDIR)\bin\moc.exe";.\gstthread.h" + Outputs="".\GeneratedFiles\$(ConfigurationName)\moc_gstthread.cpp"" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\pipeline.h" + > + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Moc'ing pipeline.h..." + CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -I".\GeneratedFiles\." -I"$(QTDIR)\include\." -I".\GeneratedFiles\$(ConfigurationName)\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"C:\gstreamer\include\." -I"C:\gstreamer\include\glib-2.0\." -I"C:\gstreamer\lib\glib-2.0\include\." -I"C:\gstreamer\include\libxml2\." -I"C:\gstreamer\include\gstreamer-1.0\." ".\pipeline.h" -o ".\GeneratedFiles\$(ConfigurationName)\moc_pipeline.cpp"
" + AdditionalDependencies=""$(QTDIR)\bin\moc.exe";.\pipeline.h" + Outputs="".\GeneratedFiles\$(ConfigurationName)\moc_pipeline.cpp"" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Moc'ing pipeline.h..." + CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_CORE_LIB -DQT_GUI_LIB -I".\GeneratedFiles\." -I"$(QTDIR)\include\." -I".\GeneratedFiles\$(ConfigurationName)\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"C:\gstreamer\include\." -I"C:\gstreamer\include\glib-2.0\." -I"C:\gstreamer\lib\glib-2.0\include\." -I"C:\gstreamer\include\libxml2\." -I"C:\gstreamer\include\gstreamer-1.0\." ".\pipeline.h" -o ".\GeneratedFiles\$(ConfigurationName)\moc_pipeline.cpp"
" + AdditionalDependencies=""$(QTDIR)\bin\moc.exe";.\pipeline.h" + Outputs="".\GeneratedFiles\$(ConfigurationName)\moc_pipeline.cpp"" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\qrenderer.h" + > + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Moc'ing qrenderer.h..." + CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -I".\GeneratedFiles\." -I"$(QTDIR)\include\." -I".\GeneratedFiles\$(ConfigurationName)\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"C:\gstreamer\include\." -I"C:\gstreamer\include\glib-2.0\." -I"C:\gstreamer\lib\glib-2.0\include\." -I"C:\gstreamer\include\libxml2\." -I"C:\gstreamer\include\gstreamer-1.0\." ".\qrenderer.h" -o ".\GeneratedFiles\$(ConfigurationName)\moc_qrenderer.cpp"
" + AdditionalDependencies=""$(QTDIR)\bin\moc.exe";.\qrenderer.h" + Outputs="".\GeneratedFiles\$(ConfigurationName)\moc_qrenderer.cpp"" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Moc'ing qrenderer.h..." + CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_CORE_LIB -DQT_GUI_LIB -I".\GeneratedFiles\." -I"$(QTDIR)\include\." -I".\GeneratedFiles\$(ConfigurationName)\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"C:\gstreamer\include\." -I"C:\gstreamer\include\glib-2.0\." -I"C:\gstreamer\lib\glib-2.0\include\." -I"C:\gstreamer\include\libxml2\." -I"C:\gstreamer\include\gstreamer-1.0\." ".\qrenderer.h" -o ".\GeneratedFiles\$(ConfigurationName)\moc_qrenderer.cpp"
" + AdditionalDependencies=""$(QTDIR)\bin\moc.exe";.\qrenderer.h" + Outputs="".\GeneratedFiles\$(ConfigurationName)\moc_qrenderer.cpp"" + /> + </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> diff --git a/tests/examples/gl/qt/mousevideooverlay/pipeline.cpp b/tests/examples/gl/qt/mousevideooverlay/pipeline.cpp new file mode 100644 index 000000000..9f8cc7622 --- /dev/null +++ b/tests/examples/gl/qt/mousevideooverlay/pipeline.cpp @@ -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 (¤t_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; +} diff --git a/tests/examples/gl/qt/mousevideooverlay/pipeline.h b/tests/examples/gl/qt/mousevideooverlay/pipeline.h new file mode 100644 index 000000000..5cdadaf5f --- /dev/null +++ b/tests/examples/gl/qt/mousevideooverlay/pipeline.h @@ -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 diff --git a/tests/examples/gl/qt/mousevideooverlay/qrenderer.cpp b/tests/examples/gl/qt/mousevideooverlay/qrenderer.cpp new file mode 100644 index 000000000..54e94fc31 --- /dev/null +++ b/tests/examples/gl/qt/mousevideooverlay/qrenderer.cpp @@ -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(); +} diff --git a/tests/examples/gl/qt/mousevideooverlay/qrenderer.h b/tests/examples/gl/qt/mousevideooverlay/qrenderer.h new file mode 100644 index 000000000..771876d43 --- /dev/null +++ b/tests/examples/gl/qt/mousevideooverlay/qrenderer.h @@ -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 diff --git a/tests/examples/gl/qt/qglwidgetvideooverlay/gstthread.cpp b/tests/examples/gl/qt/qglwidgetvideooverlay/gstthread.cpp new file mode 100644 index 000000000..a31f8d634 --- /dev/null +++ b/tests/examples/gl/qt/qglwidgetvideooverlay/gstthread.cpp @@ -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(); +} diff --git a/tests/examples/gl/qt/qglwidgetvideooverlay/gstthread.h b/tests/examples/gl/qt/qglwidgetvideooverlay/gstthread.h new file mode 100644 index 000000000..676b9870d --- /dev/null +++ b/tests/examples/gl/qt/qglwidgetvideooverlay/gstthread.h @@ -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 diff --git a/tests/examples/gl/qt/qglwidgetvideooverlay/main.cpp b/tests/examples/gl/qt/qglwidgetvideooverlay/main.cpp new file mode 100644 index 000000000..fa54a6b27 --- /dev/null +++ b/tests/examples/gl/qt/qglwidgetvideooverlay/main.cpp @@ -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(); +} diff --git a/tests/examples/gl/qt/qglwidgetvideooverlay/pipeline.cpp b/tests/examples/gl/qt/qglwidgetvideooverlay/pipeline.cpp new file mode 100644 index 000000000..617524a66 --- /dev/null +++ b/tests/examples/gl/qt/qglwidgetvideooverlay/pipeline.cpp @@ -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 (¤t_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; +} diff --git a/tests/examples/gl/qt/qglwidgetvideooverlay/pipeline.h b/tests/examples/gl/qt/qglwidgetvideooverlay/pipeline.h new file mode 100644 index 000000000..51c48fc20 --- /dev/null +++ b/tests/examples/gl/qt/qglwidgetvideooverlay/pipeline.h @@ -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 diff --git a/tests/examples/gl/qt/qglwidgetvideooverlay/qglrenderer.cpp b/tests/examples/gl/qt/qglwidgetvideooverlay/qglrenderer.cpp new file mode 100644 index 000000000..a54625efd --- /dev/null +++ b/tests/examples/gl/qt/qglwidgetvideooverlay/qglrenderer.cpp @@ -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(); +} diff --git a/tests/examples/gl/qt/qglwidgetvideooverlay/qglrenderer.h b/tests/examples/gl/qt/qglwidgetvideooverlay/qglrenderer.h new file mode 100644 index 000000000..aaf0d029e --- /dev/null +++ b/tests/examples/gl/qt/qglwidgetvideooverlay/qglrenderer.h @@ -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 diff --git a/tests/examples/gl/qt/qglwidgetvideooverlay/qglwidgetvideooverlay.pri b/tests/examples/gl/qt/qglwidgetvideooverlay/qglwidgetvideooverlay.pri new file mode 100644 index 000000000..772d1d4ec --- /dev/null +++ b/tests/examples/gl/qt/qglwidgetvideooverlay/qglwidgetvideooverlay.pri @@ -0,0 +1,10 @@ +#Header files +HEADERS += ./gstthread.h \ + ./pipeline.h \ + ./qglrenderer.h + +#Source files +SOURCES += ./gstthread.cpp \ + ./main.cpp \ + ./pipeline.cpp \ + ./qglrenderer.cpp diff --git a/tests/examples/gl/qt/qglwidgetvideooverlay/qglwidgetvideooverlay.pro b/tests/examples/gl/qt/qglwidgetvideooverlay/qglwidgetvideooverlay.pro new file mode 100644 index 000000000..2fa56e871 --- /dev/null +++ b/tests/examples/gl/qt/qglwidgetvideooverlay/qglwidgetvideooverlay.pro @@ -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) diff --git a/tests/examples/gl/qt/qglwidgetvideooverlay/qglwidgetvideooverlay.sln b/tests/examples/gl/qt/qglwidgetvideooverlay/qglwidgetvideooverlay.sln new file mode 100644 index 000000000..3842be042 --- /dev/null +++ b/tests/examples/gl/qt/qglwidgetvideooverlay/qglwidgetvideooverlay.sln @@ -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 diff --git a/tests/examples/gl/qt/qglwidgetvideooverlay/qglwidgetvideooverlay.vcproj b/tests/examples/gl/qt/qglwidgetvideooverlay/qglwidgetvideooverlay.vcproj new file mode 100644 index 000000000..4abca4b06 --- /dev/null +++ b/tests/examples/gl/qt/qglwidgetvideooverlay/qglwidgetvideooverlay.vcproj @@ -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;"$(QTDIR)\include";".\GeneratedFiles\$(ConfigurationName)";"$(QTDIR)\include\QtCore";"$(QTDIR)\include\QtGui";"$(QTDIR)\include\QtOpenGL";C:\gstreamer\include;"C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";C:\gstreamer\include\libxml2;"C:\gstreamer\include\gstreamer-1.0"" + 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=""$(QTDIR)\lib";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;"$(QTDIR)\include";".\GeneratedFiles\$(ConfigurationName)";"$(QTDIR)\include\QtCore";"$(QTDIR)\include\QtGui";"$(QTDIR)\include\QtOpenGL";C:\gstreamer\include;"C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";C:\gstreamer\include\libxml2;"C:\gstreamer\include\gstreamer-1.0"" + 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=""$(QTDIR)\lib";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'ing gstthread.h..." + CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_OPENGL_LIB -I".\GeneratedFiles\." -I"$(QTDIR)\include\." -I".\GeneratedFiles\$(ConfigurationName)\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"$(QTDIR)\include\QtOpenGL\." -I"C:\gstreamer\include\." -I"C:\gstreamer\include\glib-2.0\." -I"C:\gstreamer\lib\glib-2.0\include\." -I"C:\gstreamer\include\libxml2\." -I"C:\gstreamer\include\gstreamer-1.0\." ".\gstthread.h" -o ".\GeneratedFiles\$(ConfigurationName)\moc_gstthread.cpp"
" + AdditionalDependencies=""$(QTDIR)\bin\moc.exe";.\gstthread.h" + Outputs="".\GeneratedFiles\$(ConfigurationName)\moc_gstthread.cpp"" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Moc'ing gstthread.h..." + CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_CORE_LIB -DQT_GUI_LIB -DQT_OPENGL_LIB -I".\GeneratedFiles\." -I"$(QTDIR)\include\." -I".\GeneratedFiles\$(ConfigurationName)\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"$(QTDIR)\include\QtOpenGL\." -I"C:\gstreamer\include\." -I"C:\gstreamer\include\glib-2.0\." -I"C:\gstreamer\lib\glib-2.0\include\." -I"C:\gstreamer\include\libxml2\." -I"C:\gstreamer\include\gstreamer-1.0\." ".\gstthread.h" -o ".\GeneratedFiles\$(ConfigurationName)\moc_gstthread.cpp"
" + AdditionalDependencies=""$(QTDIR)\bin\moc.exe";.\gstthread.h" + Outputs="".\GeneratedFiles\$(ConfigurationName)\moc_gstthread.cpp"" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\pipeline.h" + > + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Moc'ing pipeline.h..." + CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_OPENGL_LIB -I".\GeneratedFiles\." -I"$(QTDIR)\include\." -I".\GeneratedFiles\$(ConfigurationName)\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"$(QTDIR)\include\QtOpenGL\." -I"C:\gstreamer\include\." -I"C:\gstreamer\include\glib-2.0\." -I"C:\gstreamer\lib\glib-2.0\include\." -I"C:\gstreamer\include\libxml2\." -I"C:\gstreamer\include\gstreamer-1,0\." ".\pipeline.h" -o ".\GeneratedFiles\$(ConfigurationName)\moc_pipeline.cpp"
" + AdditionalDependencies=""$(QTDIR)\bin\moc.exe";.\pipeline.h" + Outputs="".\GeneratedFiles\$(ConfigurationName)\moc_pipeline.cpp"" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Moc'ing pipeline.h..." + CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_CORE_LIB -DQT_GUI_LIB -DQT_OPENGL_LIB -I".\GeneratedFiles\." -I"$(QTDIR)\include\." -I".\GeneratedFiles\$(ConfigurationName)\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"$(QTDIR)\include\QtOpenGL\." -I"C:\gstreamer\include\." -I"C:\gstreamer\include\glib-2.0\." -I"C:\gstreamer\lib\glib-2.0\include\." -I"C:\gstreamer\include\libxml2\." -I"C:\gstreamer\include\gstreamer-1,0\." ".\pipeline.h" -o ".\GeneratedFiles\$(ConfigurationName)\moc_pipeline.cpp"
" + AdditionalDependencies=""$(QTDIR)\bin\moc.exe";.\pipeline.h" + Outputs="".\GeneratedFiles\$(ConfigurationName)\moc_pipeline.cpp"" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\qglrenderer.h" + > + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Moc'ing qglrenderer.h..." + CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_OPENGL_LIB -I".\GeneratedFiles\." -I"$(QTDIR)\include\." -I".\GeneratedFiles\$(ConfigurationName)\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"$(QTDIR)\include\QtOpenGL\." -I"C:\gstreamer\include\." -I"C:\gstreamer\include\glib-2.0\." -I"C:\gstreamer\lib\glib-2.0\include\." -I"C:\gstreamer\include\libxml2\." -I"C:\gstreamer\include\gstreamer-1.0\." ".\qglrenderer.h" -o ".\GeneratedFiles\$(ConfigurationName)\moc_qglrenderer.cpp"
" + AdditionalDependencies=""$(QTDIR)\bin\moc.exe";.\qglrenderer.h" + Outputs="".\GeneratedFiles\$(ConfigurationName)\moc_qglrenderer.cpp"" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Moc'ing qglrenderer.h..." + CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_CORE_LIB -DQT_GUI_LIB -DQT_OPENGL_LIB -I".\GeneratedFiles\." -I"$(QTDIR)\include\." -I".\GeneratedFiles\$(ConfigurationName)\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"$(QTDIR)\include\QtOpenGL\." -I"C:\gstreamer\include\." -I"C:\gstreamer\include\glib-2.0\." -I"C:\gstreamer\lib\glib-2.0\include\." -I"C:\gstreamer\include\libxml2\." -I"C:\gstreamer\include\gstreamer-1.0\." ".\qglrenderer.h" -o ".\GeneratedFiles\$(ConfigurationName)\moc_qglrenderer.cpp"
" + AdditionalDependencies=""$(QTDIR)\bin\moc.exe";.\qglrenderer.h" + Outputs="".\GeneratedFiles\$(ConfigurationName)\moc_qglrenderer.cpp"" + /> + </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> diff --git a/tests/examples/gl/qt/qglwtextureshare/AsyncQueue.h b/tests/examples/gl/qt/qglwtextureshare/AsyncQueue.h new file mode 100644 index 000000000..4582bcbbe --- /dev/null +++ b/tests/examples/gl/qt/qglwtextureshare/AsyncQueue.h @@ -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 diff --git a/tests/examples/gl/qt/qglwtextureshare/README b/tests/examples/gl/qt/qglwtextureshare/README new file mode 100644 index 000000000..305847cb4 --- /dev/null +++ b/tests/examples/gl/qt/qglwtextureshare/README @@ -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) diff --git a/tests/examples/gl/qt/qglwtextureshare/cocoa_utils.mm b/tests/examples/gl/qt/qglwtextureshare/cocoa_utils.mm new file mode 100644 index 000000000..9b1e78b15 --- /dev/null +++ b/tests/examples/gl/qt/qglwtextureshare/cocoa_utils.mm @@ -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]; +} diff --git a/tests/examples/gl/qt/qglwtextureshare/glcontextid.h b/tests/examples/gl/qt/qglwtextureshare/glcontextid.h new file mode 100644 index 000000000..c6a240c61 --- /dev/null +++ b/tests/examples/gl/qt/qglwtextureshare/glcontextid.h @@ -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 + diff --git a/tests/examples/gl/qt/qglwtextureshare/gstthread.cpp b/tests/examples/gl/qt/qglwtextureshare/gstthread.cpp new file mode 100644 index 000000000..2a1ff6979 --- /dev/null +++ b/tests/examples/gl/qt/qglwtextureshare/gstthread.cpp @@ -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 +} diff --git a/tests/examples/gl/qt/qglwtextureshare/gstthread.h b/tests/examples/gl/qt/qglwtextureshare/gstthread.h new file mode 100644 index 000000000..918859ee0 --- /dev/null +++ b/tests/examples/gl/qt/qglwtextureshare/gstthread.h @@ -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 diff --git a/tests/examples/gl/qt/qglwtextureshare/main.cpp b/tests/examples/gl/qt/qglwtextureshare/main.cpp new file mode 100644 index 000000000..f2eb2f11f --- /dev/null +++ b/tests/examples/gl/qt/qglwtextureshare/main.cpp @@ -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(); +} + diff --git a/tests/examples/gl/qt/qglwtextureshare/moc_gstthread.cpp b/tests/examples/gl/qt/qglwtextureshare/moc_gstthread.cpp new file mode 100644 index 000000000..1787e3845 --- /dev/null +++ b/tests/examples/gl/qt/qglwtextureshare/moc_gstthread.cpp @@ -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 diff --git a/tests/examples/gl/qt/qglwtextureshare/moc_pipeline.cpp b/tests/examples/gl/qt/qglwtextureshare/moc_pipeline.cpp new file mode 100644 index 000000000..fdf0cf744 --- /dev/null +++ b/tests/examples/gl/qt/qglwtextureshare/moc_pipeline.cpp @@ -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 diff --git a/tests/examples/gl/qt/qglwtextureshare/moc_qglrenderer.cpp b/tests/examples/gl/qt/qglwtextureshare/moc_qglrenderer.cpp new file mode 100644 index 000000000..5a11b7165 --- /dev/null +++ b/tests/examples/gl/qt/qglwtextureshare/moc_qglrenderer.cpp @@ -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 diff --git a/tests/examples/gl/qt/qglwtextureshare/pipeline.cpp b/tests/examples/gl/qt/qglwtextureshare/pipeline.cpp new file mode 100644 index 000000000..a7dd4901f --- /dev/null +++ b/tests/examples/gl/qt/qglwtextureshare/pipeline.cpp @@ -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; +} diff --git a/tests/examples/gl/qt/qglwtextureshare/pipeline.h b/tests/examples/gl/qt/qglwtextureshare/pipeline.h new file mode 100644 index 000000000..5e59f1a04 --- /dev/null +++ b/tests/examples/gl/qt/qglwtextureshare/pipeline.h @@ -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 diff --git a/tests/examples/gl/qt/qglwtextureshare/qglrenderer.cpp b/tests/examples/gl/qt/qglwtextureshare/qglrenderer.cpp new file mode 100644 index 000000000..303e4f110 --- /dev/null +++ b/tests/examples/gl/qt/qglwtextureshare/qglrenderer.cpp @@ -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(); + } +} diff --git a/tests/examples/gl/qt/qglwtextureshare/qglrenderer.h b/tests/examples/gl/qt/qglwtextureshare/qglrenderer.h new file mode 100644 index 000000000..0bf354ba5 --- /dev/null +++ b/tests/examples/gl/qt/qglwtextureshare/qglrenderer.h @@ -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 diff --git a/tests/examples/gl/qt/qglwtextureshare/qglwtextureshare b/tests/examples/gl/qt/qglwtextureshare/qglwtextureshare Binary files differnew file mode 100755 index 000000000..c32aedf5b --- /dev/null +++ b/tests/examples/gl/qt/qglwtextureshare/qglwtextureshare diff --git a/tests/examples/gl/qt/qglwtextureshare/qglwtextureshare.pro b/tests/examples/gl/qt/qglwtextureshare/qglwtextureshare.pro new file mode 100644 index 000000000..13014ac11 --- /dev/null +++ b/tests/examples/gl/qt/qglwtextureshare/qglwtextureshare.pro @@ -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 diff --git a/tests/examples/gl/qt/videooverlay/Debug/videooverlay b/tests/examples/gl/qt/videooverlay/Debug/videooverlay Binary files differnew file mode 100755 index 000000000..3651f2b64 --- /dev/null +++ b/tests/examples/gl/qt/videooverlay/Debug/videooverlay diff --git a/tests/examples/gl/qt/videooverlay/GeneratedFiles/debug/moc_gstthread.cpp b/tests/examples/gl/qt/videooverlay/GeneratedFiles/debug/moc_gstthread.cpp new file mode 100644 index 000000000..79823067f --- /dev/null +++ b/tests/examples/gl/qt/videooverlay/GeneratedFiles/debug/moc_gstthread.cpp @@ -0,0 +1,143 @@ +/**************************************************************************** +** 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[8]; + char stringdata[69]; +}; +#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, 15), +QT_MOC_LITERAL(2, 26, 0), +QT_MOC_LITERAL(3, 27, 5), +QT_MOC_LITERAL(4, 33, 6), +QT_MOC_LITERAL(5, 40, 15), +QT_MOC_LITERAL(6, 56, 6), +QT_MOC_LITERAL(7, 63, 4) + }, + "GstThread\0resizeRequested\0\0width\0" + "height\0exposeRequested\0resize\0stop\0" +}; +#undef QT_MOC_LITERAL + +static const uint qt_meta_data_GstThread[] = { + + // content: + 7, // revision + 0, // classname + 0, 0, // classinfo + 4, 14, // methods + 0, 0, // properties + 0, 0, // enums/sets + 0, 0, // constructors + 0, // flags + 1, // signalCount + + // signals: name, argc, parameters, tag, flags + 1, 2, 34, 2, 0x06, + + // slots: name, argc, parameters, tag, flags + 5, 0, 39, 2, 0x0a, + 6, 2, 40, 2, 0x0a, + 7, 0, 45, 2, 0x0a, + + // signals: parameters + QMetaType::Void, QMetaType::Int, QMetaType::Int, 3, 4, + + // slots: parameters + QMetaType::Void, + QMetaType::Void, QMetaType::Int, QMetaType::Int, 3, 4, + 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->resizeRequested((*reinterpret_cast< int(*)>(_a[1])),(*reinterpret_cast< int(*)>(_a[2]))); break; + case 1: _t->exposeRequested(); break; + case 2: _t->resize((*reinterpret_cast< int(*)>(_a[1])),(*reinterpret_cast< int(*)>(_a[2]))); break; + case 3: _t->stop(); break; + default: ; + } + } else if (_c == QMetaObject::IndexOfMethod) { + int *result = reinterpret_cast<int *>(_a[0]); + void **func = reinterpret_cast<void **>(_a[1]); + { + typedef void (GstThread::*_t)(int , int ); + if (*reinterpret_cast<_t *>(func) == static_cast<_t>(&GstThread::resizeRequested)) { + *result = 0; + } + } + } +} + +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 < 4) + qt_static_metacall(this, _c, _id, _a); + _id -= 4; + } else if (_c == QMetaObject::RegisterMethodArgumentMetaType) { + if (_id < 4) + *reinterpret_cast<int*>(_a[0]) = -1; + _id -= 4; + } + return _id; +} + +// SIGNAL 0 +void GstThread::resizeRequested(int _t1, int _t2) +{ + void *_a[] = { 0, const_cast<void*>(reinterpret_cast<const void*>(&_t1)), const_cast<void*>(reinterpret_cast<const void*>(&_t2)) }; + QMetaObject::activate(this, &staticMetaObject, 0, _a); +} +QT_END_MOC_NAMESPACE diff --git a/tests/examples/gl/qt/videooverlay/GeneratedFiles/debug/moc_pipeline.cpp b/tests/examples/gl/qt/videooverlay/GeneratedFiles/debug/moc_pipeline.cpp new file mode 100644 index 000000000..dff3f77aa --- /dev/null +++ b/tests/examples/gl/qt/videooverlay/GeneratedFiles/debug/moc_pipeline.cpp @@ -0,0 +1,143 @@ +/**************************************************************************** +** 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[6]; + char stringdata[54]; +}; +#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, 15), +QT_MOC_LITERAL(2, 25, 0), +QT_MOC_LITERAL(3, 26, 5), +QT_MOC_LITERAL(4, 32, 6), +QT_MOC_LITERAL(5, 39, 13) + }, + "Pipeline\0resizeRequested\0\0width\0height\0" + "stopRequested\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, 2, 24, 2, 0x06, + 5, 0, 29, 2, 0x06, + + // signals: parameters + QMetaType::Void, QMetaType::Int, QMetaType::Int, 3, 4, + 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->resizeRequested((*reinterpret_cast< int(*)>(_a[1])),(*reinterpret_cast< int(*)>(_a[2]))); 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)(int , int ); + if (*reinterpret_cast<_t *>(func) == static_cast<_t>(&Pipeline::resizeRequested)) { + *result = 0; + } + } + { + typedef void (Pipeline::*_t)(); + if (*reinterpret_cast<_t *>(func) == static_cast<_t>(&Pipeline::stopRequested)) { + *result = 1; + } + } + } +} + +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::resizeRequested(int _t1, int _t2) +{ + void *_a[] = { 0, const_cast<void*>(reinterpret_cast<const void*>(&_t1)), const_cast<void*>(reinterpret_cast<const void*>(&_t2)) }; + QMetaObject::activate(this, &staticMetaObject, 0, _a); +} + +// SIGNAL 1 +void Pipeline::stopRequested() +{ + QMetaObject::activate(this, &staticMetaObject, 1, 0); +} +QT_END_MOC_NAMESPACE diff --git a/tests/examples/gl/qt/videooverlay/GeneratedFiles/debug/moc_qrenderer.cpp b/tests/examples/gl/qt/videooverlay/GeneratedFiles/debug/moc_qrenderer.cpp new file mode 100644 index 000000000..007373ba7 --- /dev/null +++ b/tests/examples/gl/qt/videooverlay/GeneratedFiles/debug/moc_qrenderer.cpp @@ -0,0 +1,150 @@ +/**************************************************************************** +** Meta object code from reading C++ file 'qrenderer.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 "../../qrenderer.h" +#include <QtCore/qbytearray.h> +#include <QtCore/qmetatype.h> +#if !defined(Q_MOC_OUTPUT_REVISION) +#error "The header file 'qrenderer.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_QRenderer_t { + QByteArrayData data[7]; + char stringdata[72]; +}; +#define QT_MOC_LITERAL(idx, ofs, len) \ + Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \ + offsetof(qt_meta_stringdata_QRenderer_t, stringdata) + ofs \ + - idx * sizeof(QByteArrayData) \ + ) +static const qt_meta_stringdata_QRenderer_t qt_meta_stringdata_QRenderer = { + { +QT_MOC_LITERAL(0, 0, 9), +QT_MOC_LITERAL(1, 10, 15), +QT_MOC_LITERAL(2, 26, 0), +QT_MOC_LITERAL(3, 27, 14), +QT_MOC_LITERAL(4, 42, 15), +QT_MOC_LITERAL(5, 58, 5), +QT_MOC_LITERAL(6, 64, 6) + }, + "QRenderer\0exposeRequested\0\0closeRequested\0" + "resizeRequested\0width\0height\0" +}; +#undef QT_MOC_LITERAL + +static const uint qt_meta_data_QRenderer[] = { + + // content: + 7, // revision + 0, // classname + 0, 0, // classinfo + 3, 14, // methods + 0, 0, // properties + 0, 0, // enums/sets + 0, 0, // constructors + 0, // flags + 2, // signalCount + + // signals: name, argc, parameters, tag, flags + 1, 0, 29, 2, 0x06, + 3, 0, 30, 2, 0x06, + + // slots: name, argc, parameters, tag, flags + 4, 2, 31, 2, 0x0a, + + // signals: parameters + QMetaType::Void, + QMetaType::Void, + + // slots: parameters + QMetaType::Void, QMetaType::Int, QMetaType::Int, 5, 6, + + 0 // eod +}; + +void QRenderer::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) +{ + if (_c == QMetaObject::InvokeMetaMethod) { + QRenderer *_t = static_cast<QRenderer *>(_o); + switch (_id) { + case 0: _t->exposeRequested(); break; + case 1: _t->closeRequested(); break; + case 2: _t->resizeRequested((*reinterpret_cast< int(*)>(_a[1])),(*reinterpret_cast< int(*)>(_a[2]))); break; + default: ; + } + } else if (_c == QMetaObject::IndexOfMethod) { + int *result = reinterpret_cast<int *>(_a[0]); + void **func = reinterpret_cast<void **>(_a[1]); + { + typedef void (QRenderer::*_t)(); + if (*reinterpret_cast<_t *>(func) == static_cast<_t>(&QRenderer::exposeRequested)) { + *result = 0; + } + } + { + typedef void (QRenderer::*_t)(); + if (*reinterpret_cast<_t *>(func) == static_cast<_t>(&QRenderer::closeRequested)) { + *result = 1; + } + } + } +} + +const QMetaObject QRenderer::staticMetaObject = { + { &QWidget::staticMetaObject, qt_meta_stringdata_QRenderer.data, + qt_meta_data_QRenderer, qt_static_metacall, 0, 0} +}; + + +const QMetaObject *QRenderer::metaObject() const +{ + return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject; +} + +void *QRenderer::qt_metacast(const char *_clname) +{ + if (!_clname) return 0; + if (!strcmp(_clname, qt_meta_stringdata_QRenderer.stringdata)) + return static_cast<void*>(const_cast< QRenderer*>(this)); + return QWidget::qt_metacast(_clname); +} + +int QRenderer::qt_metacall(QMetaObject::Call _c, int _id, void **_a) +{ + _id = QWidget::qt_metacall(_c, _id, _a); + if (_id < 0) + return _id; + if (_c == QMetaObject::InvokeMetaMethod) { + if (_id < 3) + qt_static_metacall(this, _c, _id, _a); + _id -= 3; + } else if (_c == QMetaObject::RegisterMethodArgumentMetaType) { + if (_id < 3) + *reinterpret_cast<int*>(_a[0]) = -1; + _id -= 3; + } + return _id; +} + +// SIGNAL 0 +void QRenderer::exposeRequested() +{ + QMetaObject::activate(this, &staticMetaObject, 0, 0); +} + +// SIGNAL 1 +void QRenderer::closeRequested() +{ + QMetaObject::activate(this, &staticMetaObject, 1, 0); +} +QT_END_MOC_NAMESPACE diff --git a/tests/examples/gl/qt/videooverlay/videooverlay.cpp b/tests/examples/gl/qt/videooverlay/videooverlay.cpp new file mode 100644 index 000000000..9a95e906b --- /dev/null +++ b/tests/examples/gl/qt/videooverlay/videooverlay.cpp @@ -0,0 +1,80 @@ +/* GStreamer + * Copyright (C) <2010> Stefan Kost <ensonic@users.sf.net> + * + * qt-xoverlay: demonstrate overlay handling using qt + * + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <glib.h> +#include <gst/gst.h> +#include <gst/video/videooverlay.h> + +#include <QApplication> +#include <QTimer> +#include <QWidget> + +int main(int argc, char *argv[]) +{ + gst_init (&argc, &argv); + QApplication app(argc, argv); + app.setQuitOnLastWindowClosed(true); + + /* prepare the pipeline */ + + GstElement *pipeline = gst_pipeline_new ("xvoverlay"); + GstElement *src = gst_element_factory_make ("videotestsrc", NULL); + GstElement *sink = gst_element_factory_make ("glimagesink", NULL); + + if (sink == NULL) + g_error ("Couldn't create glimagesink."); + + gst_bin_add_many (GST_BIN (pipeline), src, sink, NULL); + gst_element_link (src, sink); + + /* prepare the ui */ + + QWidget window; + window.resize(320, 240); + window.setWindowTitle("GstVideoOverlay Qt demo"); + window.show(); + + WId xwinid = window.winId(); + gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY (sink), xwinid); + + /* run the pipeline */ + + GstStateChangeReturn sret = gst_element_set_state (pipeline, + GST_STATE_PLAYING); + if (sret == GST_STATE_CHANGE_FAILURE) { + gst_element_set_state (pipeline, GST_STATE_NULL); + gst_object_unref (pipeline); + /* Exit application */ + QTimer::singleShot(0, QApplication::activeWindow(), SLOT(quit())); + } + + int ret = app.exec(); + + window.hide(); + gst_element_set_state (pipeline, GST_STATE_NULL); + gst_object_unref (pipeline); + + return ret; +} diff --git a/tests/examples/gl/qt/videooverlay/videooverlay.pri b/tests/examples/gl/qt/videooverlay/videooverlay.pri new file mode 100644 index 000000000..0a53a9024 --- /dev/null +++ b/tests/examples/gl/qt/videooverlay/videooverlay.pri @@ -0,0 +1,4 @@ +#Header files + +#Source files +SOURCES += videooverlay.cpp diff --git a/tests/examples/gl/qt/videooverlay/videooverlay.sln b/tests/examples/gl/qt/videooverlay/videooverlay.sln new file mode 100644 index 000000000..f56635778 --- /dev/null +++ b/tests/examples/gl/qt/videooverlay/videooverlay.sln @@ -0,0 +1,26 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "videooverlay", "videooverlay.vcproj", "{7B8654F9-23A9-4C88-A751-6BBE09ED4CAF}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {7B8654F9-23A9-4C88-A751-6BBE09ED4CAF}.Debug|Win32.ActiveCfg = Debug|Win32 + {7B8654F9-23A9-4C88-A751-6BBE09ED4CAF}.Debug|Win32.Build.0 = Debug|Win32 + {7B8654F9-23A9-4C88-A751-6BBE09ED4CAF}.Release|Win32.ActiveCfg = Release|Win32 + {7B8654F9-23A9-4C88-A751-6BBE09ED4CAF}.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 diff --git a/tests/examples/gl/qt/videooverlay/videooverlay.vcproj b/tests/examples/gl/qt/videooverlay/videooverlay.vcproj new file mode 100644 index 000000000..557f68abd --- /dev/null +++ b/tests/examples/gl/qt/videooverlay/videooverlay.vcproj @@ -0,0 +1,320 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="videooverlay" + ProjectGUID="{7B8654F9-23A9-4C88-A751-6BBE09ED4CAF}" + 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;"$(QTDIR)\include";".\GeneratedFiles\$(ConfigurationName)";"$(QTDIR)\include\QtCore";"$(QTDIR)\include\QtGui";C:\gstreamer\include;"C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";C:\gstreamer\include\libxml2;"C:\gstreamer\include\gstreamer-1.0"" + 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" + OutputFile="$(OutDir)\$(ProjectName).exe" + AdditionalLibraryDirectories=""$(QTDIR)\lib";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;"$(QTDIR)\include";".\GeneratedFiles\$(ConfigurationName)";"$(QTDIR)\include\QtCore";"$(QTDIR)\include\QtGui";C:\gstreamer\include;"C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";C:\gstreamer\include\libxml2;"C:\gstreamer\include\gstreamer-1.0"" + 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" + OutputFile="$(OutDir)\$(ProjectName).exe" + AdditionalLibraryDirectories=""$(QTDIR)\lib";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'ing gstthread.h..." + CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -I".\GeneratedFiles\." -I"$(QTDIR)\include\." -I".\GeneratedFiles\$(ConfigurationName)\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"C:\gstreamer\include\." -I"C:\gstreamer\include\glib-2.0\." -I"C:\gstreamer\lib\glib-2.0\include\." -I"C:\gstreamer\include\libxml2\." -I"C:\gstreamer\include\gstreamer-1.0\." ".\gstthread.h" -o ".\GeneratedFiles\$(ConfigurationName)\moc_gstthread.cpp"
" + AdditionalDependencies=""$(QTDIR)\bin\moc.exe";.\gstthread.h" + Outputs="".\GeneratedFiles\$(ConfigurationName)\moc_gstthread.cpp"" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Moc'ing gstthread.h..." + CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_CORE_LIB -DQT_GUI_LIB -I".\GeneratedFiles\." -I"$(QTDIR)\include\." -I".\GeneratedFiles\$(ConfigurationName)\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"C:\gstreamer\include\." -I"C:\gstreamer\include\glib-2.0\." -I"C:\gstreamer\lib\glib-2.0\include\." -I"C:\gstreamer\include\libxml2\." -I"C:\gstreamer\include\gstreamer-1.0\." ".\gstthread.h" -o ".\GeneratedFiles\$(ConfigurationName)\moc_gstthread.cpp"
" + AdditionalDependencies=""$(QTDIR)\bin\moc.exe";.\gstthread.h" + Outputs="".\GeneratedFiles\$(ConfigurationName)\moc_gstthread.cpp"" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\pipeline.h" + > + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Moc'ing pipeline.h..." + CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -I".\GeneratedFiles\." -I"$(QTDIR)\include\." -I".\GeneratedFiles\$(ConfigurationName)\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"C:\gstreamer\include\." -I"C:\gstreamer\include\glib-2.0\." -I"C:\gstreamer\lib\glib-2.0\include\." -I"C:\gstreamer\include\libxml2\." -I"C:\gstreamer\include\gstreamer-1.0\." ".\pipeline.h" -o ".\GeneratedFiles\$(ConfigurationName)\moc_pipeline.cpp"
" + AdditionalDependencies=""$(QTDIR)\bin\moc.exe";.\pipeline.h" + Outputs="".\GeneratedFiles\$(ConfigurationName)\moc_pipeline.cpp"" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Moc'ing pipeline.h..." + CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_CORE_LIB -DQT_GUI_LIB -I".\GeneratedFiles\." -I"$(QTDIR)\include\." -I".\GeneratedFiles\$(ConfigurationName)\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"C:\gstreamer\include\." -I"C:\gstreamer\include\glib-2.0\." -I"C:\gstreamer\lib\glib-2.0\include\." -I"C:\gstreamer\include\libxml2\." -I"C:\gstreamer\include\gstreamer-1.0\." ".\pipeline.h" -o ".\GeneratedFiles\$(ConfigurationName)\moc_pipeline.cpp"
" + AdditionalDependencies=""$(QTDIR)\bin\moc.exe";.\pipeline.h" + Outputs="".\GeneratedFiles\$(ConfigurationName)\moc_pipeline.cpp"" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\qrenderer.h" + > + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Moc'ing qrenderer.h..." + CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -I".\GeneratedFiles\." -I"$(QTDIR)\include\." -I".\GeneratedFiles\$(ConfigurationName)\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"C:\gstreamer\include\." -I"C:\gstreamer\include\glib-2.0\." -I"C:\gstreamer\lib\glib-2.0\include\." -I"C:\gstreamer\include\libxml2\." -I"C:\gstreamer\include\gstreamer-1.0\." ".\qrenderer.h" -o ".\GeneratedFiles\$(ConfigurationName)\moc_qrenderer.cpp"
" + AdditionalDependencies=""$(QTDIR)\bin\moc.exe";.\qrenderer.h" + Outputs="".\GeneratedFiles\$(ConfigurationName)\moc_qrenderer.cpp"" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Moc'ing qrenderer.h..." + CommandLine=""$(QTDIR)\bin\moc.exe" -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_CORE_LIB -DQT_GUI_LIB -I".\GeneratedFiles\." -I"$(QTDIR)\include\." -I".\GeneratedFiles\$(ConfigurationName)\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -I"C:\gstreamer\include\." -I"C:\gstreamer\include\glib-2.0\." -I"C:\gstreamer\lib\glib-2.0\include\." -I"C:\gstreamer\include\libxml2\." -I"C:\gstreamer\include\gstreamer-1.0\." ".\qrenderer.h" -o ".\GeneratedFiles\$(ConfigurationName)\moc_qrenderer.cpp"
" + AdditionalDependencies=""$(QTDIR)\bin\moc.exe";.\qrenderer.h" + Outputs="".\GeneratedFiles\$(ConfigurationName)\moc_qrenderer.cpp"" + /> + </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> diff --git a/tests/examples/gl/qt/videooverlay/videovideooverlay.pro b/tests/examples/gl/qt/videooverlay/videovideooverlay.pro new file mode 100644 index 000000000..173b8c6c8 --- /dev/null +++ b/tests/examples/gl/qt/videooverlay/videovideooverlay.pro @@ -0,0 +1,53 @@ +TEMPLATE = app +TARGET = videooverlay +DESTDIR = ./Debug +CONFIG += debug +DEFINES += UNICODE QT_THREAD_SUPPORT QT_CORE_LIB QT_GUI_LIB +QT += gui widgets + +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/bin" \ + -L"C:/gstreamer/lib" \ + -lgstreamer-1.0 \ + -lgstvideo-1.0 \ + -lglib-2.0 \ + -lgmodule-2.0 \ + -lgobject-2.0 \ + -lgthread-2.0 +} + +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(videooverlay.pri) diff --git a/tests/examples/gl/sdl/.gitignore b/tests/examples/gl/sdl/.gitignore new file mode 100644 index 000000000..b958bef2d --- /dev/null +++ b/tests/examples/gl/sdl/.gitignore @@ -0,0 +1 @@ +sdlshare diff --git a/tests/examples/gl/sdl/Makefile.am b/tests/examples/gl/sdl/Makefile.am new file mode 100644 index 000000000..9e0c8c5b8 --- /dev/null +++ b/tests/examples/gl/sdl/Makefile.am @@ -0,0 +1,15 @@ +noinst_PROGRAMS = ## + +#works on win32 and X +if HAVE_SDL + +noinst_PROGRAMS += sdlshare + +sdlshare_SOURCES = sdlshare.c + +sdlshare_CFLAGS=$(GST_PLUGINS_GL_CFLAGS) $(GST_CFLAGS) \ + $(GL_CFLAGS) $(SDL_CFLAGS) +sdlshare_LDADD=$(GST_PLUGINS_GL_LIBS) $(GST_LIBS) \ + $(GL_LIBS) $(SDL_LIBS) + +endif diff --git a/tests/examples/gl/sdl/sdl.sln b/tests/examples/gl/sdl/sdl.sln new file mode 100644 index 000000000..0ecdd0057 --- /dev/null +++ b/tests/examples/gl/sdl/sdl.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sdlshare", "sdlshare.vcproj", "{2C29F5A2-5982-428A-8068-9A5788FD2277}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2C29F5A2-5982-428A-8068-9A5788FD2277}.Debug|Win32.ActiveCfg = Debug|Win32 + {2C29F5A2-5982-428A-8068-9A5788FD2277}.Debug|Win32.Build.0 = Debug|Win32 + {2C29F5A2-5982-428A-8068-9A5788FD2277}.Release|Win32.ActiveCfg = Release|Win32 + {2C29F5A2-5982-428A-8068-9A5788FD2277}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/tests/examples/sdl/sdlshare.c b/tests/examples/gl/sdl/sdlshare.c index eb30fdaaf..f54daf3a3 100644 --- a/tests/examples/sdl/sdlshare.c +++ b/tests/examples/gl/sdl/sdlshare.c @@ -58,7 +58,7 @@ float rtri = 0.0f; float rquad = 0.0f; /* A general OpenGL initialization function. Sets all of the initial parameters. */ -void +static void InitGL (int Width, int Height) // We call this right after our OpenGL window is created. { glViewport (0, 0, Width, Height); @@ -77,7 +77,7 @@ InitGL (int Width, int Height) // We call this right after our OpenGL window is } /* The main drawing function. */ -void +static void DrawGLScene (GstGLBuffer * gst_gl_buf) { GLuint texture = gst_gl_buf->texture; @@ -134,7 +134,7 @@ DrawGLScene (GstGLBuffer * gst_gl_buf) SDL_GL_SwapBuffers (); } -gboolean +static gboolean update_sdl_scene (void *fk) { GstElement *fakesink = (GstElement *) fk; @@ -169,7 +169,7 @@ update_sdl_scene (void *fk) } /* fakesink handoff callback */ -void +static void on_gst_buffer (GstElement * fakesink, GstBuffer * buf, GstPad * pad, gpointer data) { @@ -196,7 +196,7 @@ on_gst_buffer (GstElement * fakesink, GstBuffer * buf, GstPad * pad, } /* gst bus signal watch callback */ -void +static void end_stream_cb (GstBus * bus, GstMessage * msg, GMainLoop * loop) { switch (GST_MESSAGE_TYPE (msg)) { diff --git a/tests/examples/gl/sdl/sdlshare.vcproj b/tests/examples/gl/sdl/sdlshare.vcproj new file mode 100644 index 000000000..760b349b1 --- /dev/null +++ b/tests/examples/gl/sdl/sdlshare.vcproj @@ -0,0 +1,199 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="sdlshare" + ProjectGUID="{2C29F5A2-5982-428A-8068-9A5788FD2277}" + RootNamespace="sdlshare" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <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=""C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";C:\gstreamer\include\libxml2;"C:\gstreamer\include\gstreamer-1.0";C:\gstreamer\include" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + WarningLevel="3" + 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 sdl.lib sdlmain.lib opengl32.lib glu32.lib" + LinkIncremental="2" + AdditionalLibraryDirectories="C:\gstreamer\lib" + GenerateDebugInformation="true" + SubSystem="1" + 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" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories=""C:\gstreamer\include\glib-2.0";"C:\gstreamer\lib\glib-2.0\include";C:\gstreamer\include\libxml2;"C:\gstreamer\include\gstreamer-1.0";C:\gstreamer\include" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="2" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + 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 sdl.lib sdlmain.lib opengl32.lib glu32.lib" + LinkIncremental="1" + AdditionalLibraryDirectories="C:\gstreamer\lib" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + 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=".\sdlshare.c" + > + </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> |