diff --git a/GstreamerHelper/GstreamerHelper.vcxproj b/GstreamerHelper/GstreamerHelper.vcxproj index 746f8d6a..49115475 100644 --- a/GstreamerHelper/GstreamerHelper.vcxproj +++ b/GstreamerHelper/GstreamerHelper.vcxproj @@ -168,6 +168,7 @@ + @@ -194,6 +195,7 @@ Create Create + diff --git a/GstreamerHelper/GstreamerHelper.vcxproj.filters b/GstreamerHelper/GstreamerHelper.vcxproj.filters index 342e0d36..fc78f1e9 100644 --- a/GstreamerHelper/GstreamerHelper.vcxproj.filters +++ b/GstreamerHelper/GstreamerHelper.vcxproj.filters @@ -33,6 +33,9 @@ Headerdateien + + Headerdateien + @@ -53,5 +56,8 @@ Quelldateien + + Quelldateien + \ No newline at end of file diff --git a/GstreamerHelper/GstreamerVideoStream.cpp b/GstreamerHelper/GstreamerVideoStream.cpp index 1b19240a..6bf06816 100644 --- a/GstreamerHelper/GstreamerVideoStream.cpp +++ b/GstreamerHelper/GstreamerVideoStream.cpp @@ -20,6 +20,7 @@ GstreamerVideoStream::GstreamerVideoStream(int ID) this->ID = ID; g_main_loop_new(Context, false); + Clock = vocaluxe_clock_new("external"); Loop = false; @@ -65,8 +66,9 @@ int GstreamerVideoStream::LoadVideo(const wchar_t* Filename) NULL); gst_app_sink_set_caps(Appsink, caps); - gst_app_sink_set_max_buffers(Appsink, 1); + gst_app_sink_set_max_buffers(Appsink, 5); + gst_pipeline_use_clock((GstPipeline *)Element, (GstClock*) Clock); gst_element_set_state(Element, GST_STATE_PLAYING); gst_element_set_state((GstElement*)Appsink, GST_STATE_PLAYING); gst_bus_timed_pop_filtered(Bus, -1, GST_MESSAGE_ASYNC_DONE); @@ -115,11 +117,13 @@ GstFlowReturn GstreamerVideoStream::NewBufferRecieved(GstAppSink *sink) gst_object_unref(BufferStructure); } + Mutex.lock(); Frame.buffer = Mapinfo.data; Frame.height = Height; Frame.width = Width; Frame.size = Size; Frame.videotime = VideoTime; + Mutex.unlock(); return GST_FLOW_OK; } @@ -172,6 +176,10 @@ bool GstreamerVideoStream::Skip(float Start, float Gap) void GstreamerVideoStream::SetVideoLoop(bool Loop) { + if(Loop) + gst_pipeline_auto_clock((GstPipeline *)Element); + else + gst_pipeline_use_clock((GstPipeline *)Element, (GstClock*) Clock); this->Loop = Loop; } diff --git a/GstreamerHelper/GstreamerVideoStream.h b/GstreamerHelper/GstreamerVideoStream.h index 421a7ded..bb177e2a 100644 --- a/GstreamerHelper/GstreamerVideoStream.h +++ b/GstreamerHelper/GstreamerVideoStream.h @@ -3,6 +3,7 @@ #include "gst/gst.h" #include "GstreamerVideo.h" #include "gst\app\gstappsink.h" +#include "VocaluxeClock.h" using namespace std; @@ -31,9 +32,9 @@ public: bool IsFinished(); private: - GMainLoop *MainLoop; GMainContext *Context; + VocaluxeClock *Clock; GstAppSink *Appsink; GstElement *Element; diff --git a/Output/x64/gstreamer/GstreamerHelper.dll b/Output/x64/gstreamer/GstreamerHelper.dll index a8cae009..ebbe6656 100644 Binary files a/Output/x64/gstreamer/GstreamerHelper.dll and b/Output/x64/gstreamer/GstreamerHelper.dll differ diff --git a/gstreamerhelper/VocaluxeClock.cpp b/gstreamerhelper/VocaluxeClock.cpp new file mode 100644 index 00000000..cfe7e677 --- /dev/null +++ b/gstreamerhelper/VocaluxeClock.cpp @@ -0,0 +1,81 @@ +#include "stdafx.h" +#include "VocaluxeClock.h" + +static void vocaluxe_clock_class_init (VocaluxeClockClass * klass); +static void vocaluxe_clock_init (VocaluxeClock * clock); + +static GstClockTime vocaluxe_clock_get_internal_time (GstClock * clock); + +static GstSystemClockClass *parent_class = NULL; + +GType +vocaluxe_clock_get_type (void) +{ + static GType clock_type = 0; + + if (!clock_type) { + static const GTypeInfo clock_info = { + sizeof (VocaluxeClockClass), + NULL, + NULL, + (GClassInitFunc) vocaluxe_clock_class_init, + NULL, + NULL, + sizeof (VocaluxeClock), + 4, + (GInstanceInitFunc) vocaluxe_clock_init, + NULL + }; + + clock_type = g_type_register_static (GST_TYPE_SYSTEM_CLOCK, "VocaluxeClock", + &clock_info, (GTypeFlags) 0); + } + return clock_type; +} + + +static void +vocaluxe_clock_class_init (VocaluxeClockClass * klass) +{ + GstClockClass *gstclock_class; + + gstclock_class = (GstClockClass *) klass; + + parent_class = (GstSystemClockClass*) g_type_class_peek_parent (klass); + + gstclock_class->get_internal_time = vocaluxe_clock_get_internal_time; +} + +static void +vocaluxe_clock_init (VocaluxeClock * clock) +{ + clock->last_time = 0; + GST_OBJECT_FLAG_SET (clock, GST_CLOCK_FLAG_CAN_SET_MASTER); +} + +VocaluxeClock * +vocaluxe_clock_new (const gchar * name) +{ + VocaluxeClock *_vocaluxeclock = + VOCALUXE_CLOCK (g_object_new (GST_TYPE_VOCALUXE_CLOCK, "name", name, NULL)); + + return _vocaluxeclock; +} + +static GstClockTime +vocaluxe_clock_get_internal_time (GstClock * clock) +{ + VocaluxeClock *_vocaluxeclock; + GstClockTime result; + + _vocaluxeclock = GST_VOCALUXE_CLOCK_CAST (clock); + + result = _vocaluxeclock->time * GST_SECOND; + return result; +} + +void +vocaluxe_clock_set_time (VocaluxeClock * clock, float time) +{ + clock->time = time; +} \ No newline at end of file diff --git a/gstreamerhelper/VocaluxeClock.h b/gstreamerhelper/VocaluxeClock.h new file mode 100644 index 00000000..e6377220 --- /dev/null +++ b/gstreamerhelper/VocaluxeClock.h @@ -0,0 +1,42 @@ +#pragma once + +#include +#include + +G_BEGIN_DECLS + +#define GST_TYPE_VOCALUXE_CLOCK \ + (vocaluxe_clock_get_type()) +#define VOCALUXE_CLOCK(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VOCALUXE_CLOCK,VocaluxeClock)) +#define VOCALUXE_CLOCK_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VOCALUXE_CLOCK,VocaluxeClockClass)) +#define GST_IS_VOCALUXE_CLOCK(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VOCALUXE_CLOCK)) +#define GST_IS_VOCALUXE_CLOCK_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VOCALUXE_CLOCK)) +#define GST_VOCALUXE_CLOCK_CAST(obj) \ + ((VocaluxeClock*)(obj)) + +typedef struct _VocaluxeClock VocaluxeClock; +typedef struct _VocaluxeClockClass VocaluxeClockClass; + +struct _VocaluxeClock { + GstSystemClock clock; + + GstClockTime last_time; + gfloat time; +}; + +struct _VocaluxeClockClass { + GstSystemClockClass parent_class; + + /*< private >*/ + gpointer _gst_reserved[GST_PADDING]; +}; + +GType vocaluxe_clock_get_type (void); +VocaluxeClock* vocaluxe_clock_new (const gchar *name); +void vocaluxe_clock_set_time (VocaluxeClock *clock, float time); + +} \ No newline at end of file