From: Tim-Philipp Müller Date: Thu, 28 Feb 2013 18:54:15 +0000 (+0000) Subject: decklinksink: port to 1.0 X-Git-Tag: 1.19.3~507^2~14036 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=74ca4aeefdbd81963286b0a8d3048dc94c447f34;p=platform%2Fupstream%2Fgstreamer.git decklinksink: port to 1.0 Compiles, not tested yet. --- diff --git a/sys/decklink/Makefile.am b/sys/decklink/Makefile.am index 7fa1a49..a790d2a 100644 --- a/sys/decklink/Makefile.am +++ b/sys/decklink/Makefile.am @@ -22,8 +22,8 @@ endif libgstdecklink_la_LIBTOOLFLAGS = --tag=disable-static -# gstdecklinksink.cpp libgstdecklink_la_SOURCES = \ + gstdecklinksink.cpp \ gstdecklinksrc.cpp \ gstdecklink.cpp \ capture.cpp diff --git a/sys/decklink/gstdecklinksink.cpp b/sys/decklink/gstdecklinksink.cpp index 46a71a6..76db507 100644 --- a/sys/decklink/gstdecklinksink.cpp +++ b/sys/decklink/gstdecklinksink.cpp @@ -25,7 +25,7 @@ * * Example launch line * |[ - * gst-launch -v videotestsrc ! decklinksink + * gst-launch-1.0 -v videotestsrc ! decklinksink * ]| * */ @@ -36,91 +36,42 @@ #include #include -#include #include "gstdecklink.h" #include "gstdecklinksink.h" #include +/* FIXME: + * - handle ALLOCATION query + * - provide buffer pool with suitable strides/alignment for video + * - handle video meta + */ GST_DEBUG_CATEGORY_STATIC (gst_decklink_sink_debug_category); #define GST_CAT_DEFAULT gst_decklink_sink_debug_category -/* prototypes */ - - static void gst_decklink_sink_set_property (GObject * object, guint property_id, const GValue * value, GParamSpec * pspec); static void gst_decklink_sink_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec); -static void gst_decklink_sink_dispose (GObject * object); static void gst_decklink_sink_finalize (GObject * object); static GstStateChangeReturn gst_decklink_sink_change_state (GstElement * element, GstStateChange transition); -static GstClock *gst_decklink_sink_provide_clock (GstElement * element); -static gboolean gst_decklink_sink_set_clock (GstElement * element, - GstClock * clock); -static GstIndex *gst_decklink_sink_get_index (GstElement * element); -static void gst_decklink_sink_set_index (GstElement * element, - GstIndex * index); -static gboolean gst_decklink_sink_send_event (GstElement * element, - GstEvent * event); -static gboolean gst_decklink_sink_query (GstElement * element, - GstQuery * query); - -static GstCaps *gst_decklink_sink_videosink_getcaps (GstPad * pad); -static gboolean gst_decklink_sink_videosink_setcaps (GstPad * pad, - GstCaps * caps); -static gboolean gst_decklink_sink_videosink_acceptcaps (GstPad * pad, - GstCaps * caps); -static gboolean gst_decklink_sink_videosink_activate (GstPad * pad); -static gboolean gst_decklink_sink_videosink_activatepush (GstPad * pad, - gboolean active); -static gboolean gst_decklink_sink_videosink_activatepull (GstPad * pad, - gboolean active); -static GstPadLinkReturn gst_decklink_sink_videosink_link (GstPad * pad, - GstPad * peer); + static GstFlowReturn gst_decklink_sink_videosink_chain (GstPad * pad, - GstBuffer * buffer); -static GstFlowReturn gst_decklink_sink_videosink_chainlist (GstPad * pad, - GstBufferList * bufferlist); + GstObject * parent, GstBuffer * buffer); static gboolean gst_decklink_sink_videosink_event (GstPad * pad, - GstEvent * event); + GstObject * parent, GstEvent * event); static gboolean gst_decklink_sink_videosink_query (GstPad * pad, - GstQuery * query); -static GstFlowReturn gst_decklink_sink_videosink_bufferalloc (GstPad * pad, - guint64 offset, guint size, GstCaps * caps, GstBuffer ** buf); -static GstIterator *gst_decklink_sink_videosink_iterintlink (GstPad * pad); - - -static GstCaps *gst_decklink_sink_audiosink_getcaps (GstPad * pad); -static gboolean gst_decklink_sink_audiosink_setcaps (GstPad * pad, - GstCaps * caps); -static gboolean gst_decklink_sink_audiosink_acceptcaps (GstPad * pad, - GstCaps * caps); -static gboolean gst_decklink_sink_audiosink_activate (GstPad * pad); -static gboolean gst_decklink_sink_audiosink_activatepush (GstPad * pad, - gboolean active); -static gboolean gst_decklink_sink_audiosink_activatepull (GstPad * pad, - gboolean active); -static GstPadLinkReturn gst_decklink_sink_audiosink_link (GstPad * pad, - GstPad * peer); + GstObject * parent, GstQuery * query); + static GstFlowReturn gst_decklink_sink_audiosink_chain (GstPad * pad, - GstBuffer * buffer); -static GstFlowReturn gst_decklink_sink_audiosink_chainlist (GstPad * pad, - GstBufferList * bufferlist); + GstObject * parent, GstBuffer * buffer); static gboolean gst_decklink_sink_audiosink_event (GstPad * pad, - GstEvent * event); + GstObject * parent, GstEvent * event); static gboolean gst_decklink_sink_audiosink_query (GstPad * pad, - GstQuery * query); -static GstFlowReturn gst_decklink_sink_audiosink_bufferalloc (GstPad * pad, - guint64 offset, guint size, GstCaps * caps, GstBuffer ** buf); -static GstIterator *gst_decklink_sink_audiosink_iterintlink (GstPad * pad); - -static void -gst_decklink_sink_property_probe_interface_init (GstPropertyProbeInterface * - iface); + GstObject * parent, GstQuery * query); #ifdef _MSC_VER /* COM initialization/uninitialization thread */ @@ -142,53 +93,12 @@ static GstStaticPadTemplate gst_decklink_sink_audiosink_template = GST_STATIC_PAD_TEMPLATE ("audiosink", GST_PAD_SINK, GST_PAD_ALWAYS, - GST_STATIC_CAPS ("audio/x-raw-int,width=16,depth=16,channels=2,rate=48000") + GST_STATIC_CAPS ("audio/x-raw, format=S16LE, channels=2, rate=48000, " + "layout=interleaved") ); - -/* class initialization */ - -#define DEBUG_INIT(bla) \ - GST_DEBUG_CATEGORY_INIT (gst_decklink_sink_debug_category, "decklinksink", 0, \ - "debug category for decklinksink element"); - -static void -gst_decklink_sink_init_interfaces (GType type) -{ - static const GInterfaceInfo decklink_sink_propertyprobe_info = { - (GInterfaceInitFunc) gst_decklink_sink_property_probe_interface_init, - NULL, - NULL, - }; - - GST_DEBUG_CATEGORY_INIT (gst_decklink_sink_debug_category, "decklinksink", 0, - "debug category for decklinksink element"); - - g_type_add_interface_static (type, GST_TYPE_PROPERTY_PROBE, - &decklink_sink_propertyprobe_info); -} - - -GST_BOILERPLATE_FULL (GstDecklinkSink, gst_decklink_sink, GstElement, - GST_TYPE_ELEMENT, gst_decklink_sink_init_interfaces); - -static void -gst_decklink_sink_base_init (gpointer g_class) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); - GstPadTemplate *pad_template; - - pad_template = - gst_pad_template_new ("videosink", GST_PAD_SINK, GST_PAD_ALWAYS, - gst_decklink_mode_get_template_caps ()); - gst_element_class_add_pad_template (element_class, pad_template); - gst_object_unref (pad_template); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_decklink_sink_audiosink_template)); - - gst_element_class_set_static_metadata (element_class, "Decklink Sink", - "Video/Sink", "Decklink Sink", "David Schleef "); -} +#define parent_class gst_decklink_sink_parent_class +G_DEFINE_TYPE (GstDecklinkSink, gst_decklink_sink, GST_TYPE_ELEMENT); static void gst_decklink_sink_class_init (GstDecklinkSinkClass * klass) @@ -198,17 +108,10 @@ gst_decklink_sink_class_init (GstDecklinkSinkClass * klass) gobject_class->set_property = gst_decklink_sink_set_property; gobject_class->get_property = gst_decklink_sink_get_property; - gobject_class->dispose = gst_decklink_sink_dispose; gobject_class->finalize = gst_decklink_sink_finalize; + element_class->change_state = GST_DEBUG_FUNCPTR (gst_decklink_sink_change_state); - element_class->provide_clock = - GST_DEBUG_FUNCPTR (gst_decklink_sink_provide_clock); - element_class->set_clock = GST_DEBUG_FUNCPTR (gst_decklink_sink_set_clock); - element_class->get_index = GST_DEBUG_FUNCPTR (gst_decklink_sink_get_index); - element_class->set_index = GST_DEBUG_FUNCPTR (gst_decklink_sink_set_index); - element_class->send_event = GST_DEBUG_FUNCPTR (gst_decklink_sink_send_event); - element_class->query = GST_DEBUG_FUNCPTR (gst_decklink_sink_query); g_object_class_install_property (gobject_class, PROP_MODE, g_param_spec_enum ("mode", "Playback Mode", @@ -217,48 +120,45 @@ gst_decklink_sink_class_init (GstDecklinkSinkClass * klass) (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT))); + /* FIXME: should be device-number or so, or turned into a string */ +#if 0 g_object_class_install_property (gobject_class, PROP_DEVICE, g_param_spec_int ("device", "Device", "Capture device instance to use", 0, G_MAXINT, 0, (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT))); +#endif + + gst_element_class_add_pad_template (element_class, + gst_pad_template_new ("videosink", GST_PAD_SINK, GST_PAD_ALWAYS, + gst_decklink_mode_get_template_caps ())); + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&gst_decklink_sink_audiosink_template)); + + gst_element_class_set_static_metadata (element_class, "Decklink Sink", + "Video/Sink", "Decklink Sink", "David Schleef "); + + GST_DEBUG_CATEGORY_INIT (gst_decklink_sink_debug_category, "decklinksink", 0, + "debug category for decklinksink element"); } static void -gst_decklink_sink_init (GstDecklinkSink * decklinksink, - GstDecklinkSinkClass * decklinksink_class) +gst_decklink_sink_init (GstDecklinkSink * decklinksink) { + GstDecklinkSinkClass *decklinksink_class; + + decklinksink_class = GST_DECKLINK_SINK_GET_CLASS (decklinksink_class); decklinksink->videosinkpad = gst_pad_new_from_template (gst_element_class_get_pad_template (GST_ELEMENT_CLASS (decklinksink_class), "videosink"), "videosink"); - gst_pad_set_getcaps_function (decklinksink->videosinkpad, - GST_DEBUG_FUNCPTR (gst_decklink_sink_videosink_getcaps)); - gst_pad_set_setcaps_function (decklinksink->videosinkpad, - GST_DEBUG_FUNCPTR (gst_decklink_sink_videosink_setcaps)); - gst_pad_set_acceptcaps_function (decklinksink->videosinkpad, - GST_DEBUG_FUNCPTR (gst_decklink_sink_videosink_acceptcaps)); - gst_pad_set_activate_function (decklinksink->videosinkpad, - GST_DEBUG_FUNCPTR (gst_decklink_sink_videosink_activate)); - gst_pad_set_activatepush_function (decklinksink->videosinkpad, - GST_DEBUG_FUNCPTR (gst_decklink_sink_videosink_activatepush)); - gst_pad_set_activatepull_function (decklinksink->videosinkpad, - GST_DEBUG_FUNCPTR (gst_decklink_sink_videosink_activatepull)); - gst_pad_set_link_function (decklinksink->videosinkpad, - GST_DEBUG_FUNCPTR (gst_decklink_sink_videosink_link)); gst_pad_set_chain_function (decklinksink->videosinkpad, GST_DEBUG_FUNCPTR (gst_decklink_sink_videosink_chain)); - gst_pad_set_chain_list_function (decklinksink->videosinkpad, - GST_DEBUG_FUNCPTR (gst_decklink_sink_videosink_chainlist)); gst_pad_set_event_function (decklinksink->videosinkpad, GST_DEBUG_FUNCPTR (gst_decklink_sink_videosink_event)); gst_pad_set_query_function (decklinksink->videosinkpad, GST_DEBUG_FUNCPTR (gst_decklink_sink_videosink_query)); - gst_pad_set_bufferalloc_function (decklinksink->videosinkpad, - GST_DEBUG_FUNCPTR (gst_decklink_sink_videosink_bufferalloc)); - gst_pad_set_iterate_internal_links_function (decklinksink->videosinkpad, - GST_DEBUG_FUNCPTR (gst_decklink_sink_videosink_iterintlink)); gst_element_add_pad (GST_ELEMENT (decklinksink), decklinksink->videosinkpad); @@ -266,40 +166,20 @@ gst_decklink_sink_init (GstDecklinkSink * decklinksink, decklinksink->audiosinkpad = gst_pad_new_from_static_template (&gst_decklink_sink_audiosink_template, "audiosink"); - gst_pad_set_getcaps_function (decklinksink->audiosinkpad, - GST_DEBUG_FUNCPTR (gst_decklink_sink_audiosink_getcaps)); - gst_pad_set_setcaps_function (decklinksink->audiosinkpad, - GST_DEBUG_FUNCPTR (gst_decklink_sink_audiosink_setcaps)); - gst_pad_set_acceptcaps_function (decklinksink->audiosinkpad, - GST_DEBUG_FUNCPTR (gst_decklink_sink_audiosink_acceptcaps)); - gst_pad_set_activate_function (decklinksink->audiosinkpad, - GST_DEBUG_FUNCPTR (gst_decklink_sink_audiosink_activate)); - gst_pad_set_activatepush_function (decklinksink->audiosinkpad, - GST_DEBUG_FUNCPTR (gst_decklink_sink_audiosink_activatepush)); - gst_pad_set_activatepull_function (decklinksink->audiosinkpad, - GST_DEBUG_FUNCPTR (gst_decklink_sink_audiosink_activatepull)); - gst_pad_set_link_function (decklinksink->audiosinkpad, - GST_DEBUG_FUNCPTR (gst_decklink_sink_audiosink_link)); gst_pad_set_chain_function (decklinksink->audiosinkpad, GST_DEBUG_FUNCPTR (gst_decklink_sink_audiosink_chain)); - gst_pad_set_chain_list_function (decklinksink->audiosinkpad, - GST_DEBUG_FUNCPTR (gst_decklink_sink_audiosink_chainlist)); gst_pad_set_event_function (decklinksink->audiosinkpad, GST_DEBUG_FUNCPTR (gst_decklink_sink_audiosink_event)); gst_pad_set_query_function (decklinksink->audiosinkpad, GST_DEBUG_FUNCPTR (gst_decklink_sink_audiosink_query)); - gst_pad_set_bufferalloc_function (decklinksink->audiosinkpad, - GST_DEBUG_FUNCPTR (gst_decklink_sink_audiosink_bufferalloc)); - gst_pad_set_iterate_internal_links_function (decklinksink->audiosinkpad, - GST_DEBUG_FUNCPTR (gst_decklink_sink_audiosink_iterintlink)); gst_element_add_pad (GST_ELEMENT (decklinksink), decklinksink->audiosinkpad); - GST_OBJECT_FLAG_SET (decklinksink, GST_ELEMENT_IS_SINK); + GST_OBJECT_FLAG_SET (decklinksink, GST_ELEMENT_FLAG_SINK); - decklinksink->cond = g_cond_new (); - decklinksink->mutex = g_mutex_new (); - decklinksink->audio_mutex = g_mutex_new (); - decklinksink->audio_cond = g_cond_new (); + g_cond_init (&decklinksink->cond); + g_mutex_init (&decklinksink->mutex); + g_mutex_init (&decklinksink->audio_mutex); + g_cond_init (&decklinksink->audio_cond); decklinksink->mode = GST_DECKLINK_MODE_NTSC; decklinksink->device = 0; @@ -308,21 +188,21 @@ gst_decklink_sink_init (GstDecklinkSink * decklinksink, decklinksink->callback->decklinksink = decklinksink; #ifdef _MSC_VER - decklinksink->com_init_lock = g_mutex_new (); - decklinksink->com_deinit_lock = g_mutex_new (); - decklinksink->com_initialized = g_cond_new (); - decklinksink->com_uninitialize = g_cond_new (); - decklinksink->com_uninitialized = g_cond_new (); + g_mutex_init (&decklinksink->com_init_lock); + g_mutex_init (&decklinksink->com_deinit_lock); + g_cond_init (&decklinksink->com_initialized); + g_cond_init (&decklinksink->com_uninitialize); + g_cond_init (&decklinksink->com_uninitialized); - g_mutex_lock (decklinksink->com_init_lock); + g_mutex_lock (&decklinksink->com_init_lock); /* create the COM initialization thread */ g_thread_create ((GThreadFunc) gst_decklink_sink_com_thread, decklinksink, FALSE, NULL); /* wait until the COM thread signals that COM has been initialized */ - g_cond_wait (decklinksink->com_initialized, decklinksink->com_init_lock); - g_mutex_unlock (decklinksink->com_init_lock); + g_cond_wait (&decklinksink->com_initialized, &decklinksink->com_init_lock); + g_mutex_unlock (&decklinksink->com_init_lock); #endif /* _MSC_VER */ } @@ -411,46 +291,34 @@ gst_decklink_sink_com_thread (GstDecklinkSink * sink) #endif /* _MSC_VER */ void -gst_decklink_sink_dispose (GObject * object) -{ - g_return_if_fail (GST_IS_DECKLINK_SINK (object)); - - /* clean up as possible. may be called multiple times */ - - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -void gst_decklink_sink_finalize (GObject * object) { GstDecklinkSink *decklinksink; - g_return_if_fail (GST_IS_DECKLINK_SINK (object)); decklinksink = GST_DECKLINK_SINK (object); - /* clean up object here */ - g_cond_free (decklinksink->cond); - g_mutex_free (decklinksink->mutex); - g_cond_free (decklinksink->audio_cond); - g_mutex_free (decklinksink->audio_mutex); + g_cond_clear (&decklinksink->cond); + g_mutex_clear (&decklinksink->mutex); + g_cond_clear (&decklinksink->audio_cond); + g_mutex_clear (&decklinksink->audio_mutex); delete decklinksink->callback; #ifdef _MSC_VER /* signal the COM thread that it should uninitialize COM */ if (decklinksink->comInitialized) { - g_mutex_lock (decklinksink->com_deinit_lock); - g_cond_signal (decklinksink->com_uninitialize); - g_cond_wait (decklinksink->com_uninitialized, - decklinksink->com_deinit_lock); - g_mutex_unlock (decklinksink->com_deinit_lock); + g_mutex_lock (&decklinksink->com_deinit_lock); + g_cond_signal (&decklinksink->com_uninitialize); + g_cond_wait (&decklinksink->com_uninitialized, + &decklinksink->com_deinit_lock); + g_mutex_unlock (&decklinksink->com_deinit_lock); } - g_mutex_free (decklinksink->com_init_lock); - g_mutex_free (decklinksink->com_deinit_lock); - g_cond_free (decklinksink->com_initialized); - g_cond_free (decklinksink->com_uninitialize); - g_cond_free (decklinksink->com_uninitialized); + g_mutex_clear (&decklinksink->com_init_lock); + g_mutex_clear (&decklinksink->com_deinit_lock); + g_cond_clear (&decklinksink->com_initialized); + g_cond_clear (&decklinksink->com_uninitialize); + g_cond_clear (&decklinksink->com_uninitialized); #endif /* _MSC_VER */ G_OBJECT_CLASS (parent_class)->finalize (object); @@ -503,14 +371,14 @@ gst_decklink_sink_start (GstDecklinkSink * decklinksink) static gboolean gst_decklink_sink_force_stop (GstDecklinkSink * decklinksink) { - g_mutex_lock (decklinksink->mutex); + g_mutex_lock (&decklinksink->mutex); decklinksink->stop = TRUE; - g_cond_signal (decklinksink->cond); - g_mutex_unlock (decklinksink->mutex); + g_cond_signal (&decklinksink->cond); + g_mutex_unlock (&decklinksink->mutex); - g_mutex_lock (decklinksink->audio_mutex); - g_cond_signal (decklinksink->audio_cond); - g_mutex_unlock (decklinksink->audio_mutex); + g_mutex_lock (&decklinksink->audio_mutex); + g_cond_signal (&decklinksink->audio_cond); + g_mutex_unlock (&decklinksink->audio_mutex); return TRUE; } @@ -531,8 +399,6 @@ gst_decklink_sink_change_state (GstElement * element, GstStateChange transition) GstDecklinkSink *decklinksink; GstStateChangeReturn ret; - g_return_val_if_fail (GST_IS_DECKLINK_SINK (element), - GST_STATE_CHANGE_FAILURE); decklinksink = GST_DECKLINK_SINK (element); switch (transition) { @@ -569,170 +435,9 @@ out: return ret; } -static GstClock * -gst_decklink_sink_provide_clock (GstElement * element) -{ - - return NULL; -} - -static gboolean -gst_decklink_sink_set_clock (GstElement * element, GstClock * clock) -{ - - return GST_ELEMENT_CLASS (parent_class)->set_clock (element, clock); -} - -static GstIndex * -gst_decklink_sink_get_index (GstElement * element) -{ - - return NULL; -} - -static void -gst_decklink_sink_set_index (GstElement * element, GstIndex * index) -{ - -} - -static gboolean -gst_decklink_sink_send_event (GstElement * element, GstEvent * event) -{ - - return TRUE; -} - -static gboolean -gst_decklink_sink_query (GstElement * element, GstQuery * query) -{ - - return FALSE; -} - -static GstCaps * -gst_decklink_sink_videosink_getcaps (GstPad * pad) -{ - GstDecklinkSink *decklinksink; - GstCaps *caps; - - decklinksink = GST_DECKLINK_SINK (gst_pad_get_parent (pad)); - - GST_DEBUG_OBJECT (decklinksink, "getcaps"); - - caps = gst_decklink_mode_get_caps (decklinksink->mode); - - gst_object_unref (decklinksink); - return caps; -} - -static gboolean -gst_decklink_sink_videosink_setcaps (GstPad * pad, GstCaps * caps) -{ - GstDecklinkSink *decklinksink; - gboolean ret; - GstVideoFormat format; - int width; - int height; - - decklinksink = GST_DECKLINK_SINK (gst_pad_get_parent (pad)); - - GST_DEBUG_OBJECT (decklinksink, "setcaps"); - - ret = gst_video_format_parse_caps (caps, &format, &width, &height); - if (ret) { - if (format == GST_VIDEO_FORMAT_v210) { - decklinksink->pixel_format = bmdFormat10BitYUV; - } else { - decklinksink->pixel_format = bmdFormat8BitYUV; - } - } - - - gst_object_unref (decklinksink); - return TRUE; -} - -static gboolean -gst_decklink_sink_videosink_acceptcaps (GstPad * pad, GstCaps * caps) -{ - GstDecklinkSink *decklinksink; - - decklinksink = GST_DECKLINK_SINK (gst_pad_get_parent (pad)); - - GST_DEBUG_OBJECT (decklinksink, "acceptcaps"); - - - gst_object_unref (decklinksink); - return TRUE; -} - -static gboolean -gst_decklink_sink_videosink_activate (GstPad * pad) -{ - GstDecklinkSink *decklinksink; - gboolean ret; - - decklinksink = GST_DECKLINK_SINK (gst_pad_get_parent (pad)); - - GST_DEBUG_OBJECT (decklinksink, "activate"); - - if (gst_pad_check_pull_range (pad)) { - GST_DEBUG_OBJECT (pad, "activating pull"); - ret = gst_pad_activate_pull (pad, TRUE); - } else { - GST_DEBUG_OBJECT (pad, "activating push"); - ret = gst_pad_activate_push (pad, TRUE); - } - - gst_object_unref (decklinksink); - return ret; -} - -static gboolean -gst_decklink_sink_videosink_activatepush (GstPad * pad, gboolean active) -{ - GstDecklinkSink *decklinksink; - - decklinksink = GST_DECKLINK_SINK (gst_pad_get_parent (pad)); - - GST_DEBUG_OBJECT (decklinksink, "activatepush"); - - - gst_object_unref (decklinksink); - return TRUE; -} - -static gboolean -gst_decklink_sink_videosink_activatepull (GstPad * pad, gboolean active) -{ - GstDecklinkSink *decklinksink; - - decklinksink = GST_DECKLINK_SINK (gst_pad_get_parent (pad)); - - GST_DEBUG_OBJECT (decklinksink, "activatepull"); - - - gst_object_unref (decklinksink); - return TRUE; -} - -static GstPadLinkReturn -gst_decklink_sink_videosink_link (GstPad * pad, GstPad * peer) -{ - GstDecklinkSink *decklinksink; - - decklinksink = GST_DECKLINK_SINK (gst_pad_get_parent (pad)); - - GST_DEBUG_OBJECT (decklinksink, "link"); - - - gst_object_unref (decklinksink); - return GST_PAD_LINK_OK; -} - static GstFlowReturn -gst_decklink_sink_videosink_chain (GstPad * pad, GstBuffer * buffer) +gst_decklink_sink_videosink_chain (GstPad * pad, GstObject * parent, + GstBuffer * buffer) { GstDecklinkSink *decklinksink; IDeckLinkMutableVideoFrame *frame; @@ -740,9 +445,7 @@ gst_decklink_sink_videosink_chain (GstPad * pad, GstBuffer * buffer) GstFlowReturn ret; const GstDecklinkMode *mode; - decklinksink = GST_DECKLINK_SINK (gst_pad_get_parent (pad)); - - GST_DEBUG_OBJECT (decklinksink, "chain"); + decklinksink = GST_DECKLINK_SINK (parent); #if 0 if (!decklinksink->video_enabled) { @@ -764,17 +467,17 @@ gst_decklink_sink_videosink_chain (GstPad * pad, GstBuffer * buffer) bmdFrameFlagDefault, &frame); frame->GetBytes (&data); - memcpy (data, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer)); + gst_buffer_extract (buffer, 0, data, gst_buffer_get_size (buffer)); gst_buffer_unref (buffer); - g_mutex_lock (decklinksink->mutex); + g_mutex_lock (&decklinksink->mutex); while (decklinksink->queued_frames > 2 && !decklinksink->stop) { - g_cond_wait (decklinksink->cond, decklinksink->mutex); + g_cond_wait (&decklinksink->cond, &decklinksink->mutex); } if (!decklinksink->stop) { decklinksink->queued_frames++; } - g_mutex_unlock (decklinksink->mutex); + g_mutex_unlock (&decklinksink->mutex); if (!decklinksink->stop) { decklinksink->output->ScheduleVideoFrame (frame, @@ -793,35 +496,38 @@ gst_decklink_sink_videosink_chain (GstPad * pad, GstBuffer * buffer) frame->Release (); - gst_object_unref (decklinksink); return ret; } -static GstFlowReturn -gst_decklink_sink_videosink_chainlist (GstPad * pad, GstBufferList * bufferlist) -{ - GstDecklinkSink *decklinksink; - - decklinksink = GST_DECKLINK_SINK (gst_pad_get_parent (pad)); - - GST_DEBUG_OBJECT (decklinksink, "chainlist"); - - - gst_object_unref (decklinksink); - return GST_FLOW_OK; -} - static gboolean -gst_decklink_sink_videosink_event (GstPad * pad, GstEvent * event) +gst_decklink_sink_videosink_event (GstPad * pad, GstObject * parent, + GstEvent * event) { gboolean res; GstDecklinkSink *decklinksink; - decklinksink = GST_DECKLINK_SINK (gst_pad_get_parent (pad)); + decklinksink = GST_DECKLINK_SINK (parent); - GST_DEBUG_OBJECT (decklinksink, "event"); + GST_DEBUG_OBJECT (pad, "event: %" GST_PTR_FORMAT, event); switch (GST_EVENT_TYPE (event)) { + /* FIXME: this makes no sense, template caps don't contain v210 */ +#if 0 + case GST_EVENT_CAPS:{ + GstCaps *caps; + + gst_event_parse_caps (event, &caps); + ret = gst_video_format_parse_caps (caps, &format, &width, &height); + if (ret) { + if (format == GST_VIDEO_FORMAT_v210) { + decklinksink->pixel_format = bmdFormat10BitYUV; + } else { + decklinksink->pixel_format = bmdFormat8BitYUV; + } + } + break; + } +#endif case GST_EVENT_EOS: decklinksink->video_eos = TRUE; decklinksink->video_seqnum = gst_event_get_seqnum (event); @@ -835,227 +541,80 @@ gst_decklink_sink_videosink_event (GstPad * pad, GstEvent * event) break; default: - res = gst_pad_event_default (pad, event); + res = gst_pad_event_default (pad, parent, event); break; } - gst_object_unref (decklinksink); return res; } static gboolean -gst_decklink_sink_videosink_query (GstPad * pad, GstQuery * query) +gst_decklink_sink_videosink_query (GstPad * pad, GstObject * parent, + GstQuery * query) { gboolean res; GstDecklinkSink *decklinksink; - decklinksink = GST_DECKLINK_SINK (gst_pad_get_parent (pad)); + decklinksink = GST_DECKLINK_SINK (parent); GST_DEBUG_OBJECT (decklinksink, "query"); switch (GST_QUERY_TYPE (query)) { + case GST_QUERY_CAPS:{ + GstCaps *mode_caps, *filter, *caps; + + /* FIXME: do we change mode if incoming caps change? If yes, we + * should probably return the template caps instead */ + mode_caps = gst_decklink_mode_get_caps (decklinksink->mode); + gst_query_parse_caps (query, &filter); + caps = gst_caps_intersect (mode_caps, filter); + gst_caps_unref (mode_caps); + gst_query_set_caps_result (query, caps); + gst_caps_unref (caps); + break; + } default: - res = gst_pad_query_default (pad, query); + res = gst_pad_query_default (pad, parent, query); break; } - gst_object_unref (decklinksink); return res; } static GstFlowReturn -gst_decklink_sink_videosink_bufferalloc (GstPad * pad, guint64 offset, - guint size, GstCaps * caps, GstBuffer ** buf) -{ - GstDecklinkSink *decklinksink; - - decklinksink = GST_DECKLINK_SINK (gst_pad_get_parent (pad)); - - GST_DEBUG_OBJECT (decklinksink, "bufferalloc"); - - - *buf = gst_buffer_new_and_alloc (size); - gst_buffer_set_caps (*buf, caps); - - gst_object_unref (decklinksink); - return GST_FLOW_OK; -} - -static GstIterator * -gst_decklink_sink_videosink_iterintlink (GstPad * pad) -{ - GstDecklinkSink *decklinksink; - GstIterator *iter; - - decklinksink = GST_DECKLINK_SINK (gst_pad_get_parent (pad)); - - GST_DEBUG_OBJECT (decklinksink, "iterintlink"); - - iter = gst_pad_iterate_internal_links_default (pad); - - gst_object_unref (decklinksink); - return iter; -} - - -static GstCaps * -gst_decklink_sink_audiosink_getcaps (GstPad * pad) -{ - GstDecklinkSink *decklinksink; - GstCaps *caps; - - decklinksink = GST_DECKLINK_SINK (gst_pad_get_parent (pad)); - - GST_DEBUG_OBJECT (decklinksink, "getcaps"); - - caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad)); - - gst_object_unref (decklinksink); - return caps; -} - -static gboolean -gst_decklink_sink_audiosink_setcaps (GstPad * pad, GstCaps * caps) -{ - GstDecklinkSink *decklinksink; - - decklinksink = GST_DECKLINK_SINK (gst_pad_get_parent (pad)); - - GST_DEBUG_OBJECT (decklinksink, "setcaps"); - - gst_object_unref (decklinksink); - return TRUE; -} - -static gboolean -gst_decklink_sink_audiosink_acceptcaps (GstPad * pad, GstCaps * caps) -{ - GstDecklinkSink *decklinksink; - - decklinksink = GST_DECKLINK_SINK (gst_pad_get_parent (pad)); - - GST_DEBUG_OBJECT (decklinksink, "acceptcaps"); - - - gst_object_unref (decklinksink); - return TRUE; -} - -static gboolean -gst_decklink_sink_audiosink_activate (GstPad * pad) -{ - GstDecklinkSink *decklinksink; - gboolean ret; - - decklinksink = GST_DECKLINK_SINK (gst_pad_get_parent (pad)); - - GST_DEBUG_OBJECT (decklinksink, "activate"); - - if (gst_pad_check_pull_range (pad)) { - GST_DEBUG_OBJECT (pad, "activating pull"); - ret = gst_pad_activate_pull (pad, TRUE); - } else { - GST_DEBUG_OBJECT (pad, "activating push"); - ret = gst_pad_activate_push (pad, TRUE); - } - - gst_object_unref (decklinksink); - return ret; -} - -static gboolean -gst_decklink_sink_audiosink_activatepush (GstPad * pad, gboolean active) -{ - GstDecklinkSink *decklinksink; - - decklinksink = GST_DECKLINK_SINK (gst_pad_get_parent (pad)); - - GST_DEBUG_OBJECT (decklinksink, "activatepush"); - - - gst_object_unref (decklinksink); - return TRUE; -} - -static gboolean -gst_decklink_sink_audiosink_activatepull (GstPad * pad, gboolean active) -{ - GstDecklinkSink *decklinksink; - - decklinksink = GST_DECKLINK_SINK (gst_pad_get_parent (pad)); - - GST_DEBUG_OBJECT (decklinksink, "activatepull"); - - - gst_object_unref (decklinksink); - return TRUE; -} - -static GstPadLinkReturn -gst_decklink_sink_audiosink_link (GstPad * pad, GstPad * peer) -{ - GstDecklinkSink *decklinksink; - - decklinksink = GST_DECKLINK_SINK (gst_pad_get_parent (pad)); - - GST_DEBUG_OBJECT (decklinksink, "link"); - - - gst_object_unref (decklinksink); - return GST_PAD_LINK_OK; -} - -static GstFlowReturn -gst_decklink_sink_audiosink_chain (GstPad * pad, GstBuffer * buffer) +gst_decklink_sink_audiosink_chain (GstPad * pad, GstObject * parent, + GstBuffer * buffer) { GstDecklinkSink *decklinksink; GstFlowReturn ret; - decklinksink = GST_DECKLINK_SINK (gst_pad_get_parent (pad)); + decklinksink = GST_DECKLINK_SINK (parent); - GST_DEBUG_OBJECT (decklinksink, "chain"); + if (decklinksink->stop) + return GST_FLOW_FLUSHING; - if (decklinksink->stop) { - return GST_FLOW_WRONG_STATE; - } - - g_mutex_lock (decklinksink->audio_mutex); + g_mutex_lock (&decklinksink->audio_mutex); while (!decklinksink->stop && gst_adapter_available (decklinksink->audio_adapter) > 1600 * 4 * 2) { - g_cond_wait (decklinksink->audio_cond, decklinksink->audio_mutex); + g_cond_wait (&decklinksink->audio_cond, &decklinksink->audio_mutex); } gst_adapter_push (decklinksink->audio_adapter, buffer); - g_mutex_unlock (decklinksink->audio_mutex); - - gst_object_unref (decklinksink); + g_mutex_unlock (&decklinksink->audio_mutex); ret = GST_FLOW_OK; return ret; } -static GstFlowReturn -gst_decklink_sink_audiosink_chainlist (GstPad * pad, GstBufferList * bufferlist) -{ - GstDecklinkSink *decklinksink; - - decklinksink = GST_DECKLINK_SINK (gst_pad_get_parent (pad)); - - GST_DEBUG_OBJECT (decklinksink, "chainlist"); - - - gst_object_unref (decklinksink); - return GST_FLOW_OK; -} - static gboolean -gst_decklink_sink_audiosink_event (GstPad * pad, GstEvent * event) +gst_decklink_sink_audiosink_event (GstPad * pad, GstObject * parent, + GstEvent * event) { gboolean res; GstDecklinkSink *decklinksink; - decklinksink = GST_DECKLINK_SINK (gst_pad_get_parent (pad)); + decklinksink = GST_DECKLINK_SINK (parent); - GST_DEBUG_OBJECT (decklinksink, "event"); + GST_DEBUG_OBJECT (pad, "event: %" GST_PTR_FORMAT, event); switch (GST_EVENT_TYPE (event)) { case GST_EVENT_EOS: @@ -1063,80 +622,40 @@ gst_decklink_sink_audiosink_event (GstPad * pad, GstEvent * event) decklinksink->audio_seqnum = gst_event_get_seqnum (event); break; default: - res = gst_pad_event_default (pad, event); + res = gst_pad_event_default (pad, parent, event); break; } - gst_object_unref (decklinksink); return res; } static gboolean -gst_decklink_sink_audiosink_query (GstPad * pad, GstQuery * query) +gst_decklink_sink_audiosink_query (GstPad * pad, GstObject * parent, + GstQuery * query) { gboolean res; - GstDecklinkSink *decklinksink; - decklinksink = GST_DECKLINK_SINK (gst_pad_get_parent (pad)); - - GST_DEBUG_OBJECT (decklinksink, "query"); + GST_DEBUG_OBJECT (pad, "query: %" GST_PTR_FORMAT, query); switch (GST_QUERY_TYPE (query)) { default: - res = gst_pad_query_default (pad, query); + res = gst_pad_query_default (pad, parent, query); break; } - gst_object_unref (decklinksink); return res; } -static GstFlowReturn -gst_decklink_sink_audiosink_bufferalloc (GstPad * pad, guint64 offset, - guint size, GstCaps * caps, GstBuffer ** buf) -{ - GstDecklinkSink *decklinksink; - - decklinksink = GST_DECKLINK_SINK (gst_pad_get_parent (pad)); - - GST_DEBUG_OBJECT (decklinksink, "bufferalloc"); - - - *buf = gst_buffer_new_and_alloc (size); - gst_buffer_set_caps (*buf, caps); - - gst_object_unref (decklinksink); - return GST_FLOW_OK; -} - -static GstIterator * -gst_decklink_sink_audiosink_iterintlink (GstPad * pad) -{ - GstDecklinkSink *decklinksink; - GstIterator *iter; - - decklinksink = GST_DECKLINK_SINK (gst_pad_get_parent (pad)); - - GST_DEBUG_OBJECT (decklinksink, "iterintlink"); - - iter = gst_pad_iterate_internal_links_default (pad); - - gst_object_unref (decklinksink); - return iter; -} - - - HRESULT Output::ScheduledFrameCompleted (IDeckLinkVideoFrame * completedFrame, BMDOutputFrameCompletionResult result) { GST_DEBUG ("ScheduledFrameCompleted"); - g_mutex_lock (decklinksink->mutex); - g_cond_signal (decklinksink->cond); + g_mutex_lock (&decklinksink->mutex); + g_cond_signal (&decklinksink->cond); decklinksink->queued_frames--; - g_mutex_unlock (decklinksink->mutex); + g_mutex_unlock (&decklinksink->mutex); return S_OK; } @@ -1160,22 +679,23 @@ Output::RenderAudioSamples (bool preroll) decklinksink->output->BeginAudioPreroll (); // running = true; } else { + gconstpointer data; int n; - const guint8 *data; - g_mutex_lock (decklinksink->audio_mutex); + g_mutex_lock (&decklinksink->audio_mutex); n = gst_adapter_available (decklinksink->audio_adapter); if (n > 0) { - data = gst_adapter_peek (decklinksink->audio_adapter, n); + data = gst_adapter_map (decklinksink->audio_adapter, n); decklinksink->output->ScheduleAudioSamples ((void *) data, n / 4, 0, 0, &samplesWritten); + gst_adapter_unmap (decklinksink->audio_adapter); gst_adapter_flush (decklinksink->audio_adapter, samplesWritten * 4); GST_DEBUG ("wrote %d samples, %d available", samplesWritten, n / 4); - g_cond_signal (decklinksink->audio_cond); + g_cond_signal (&decklinksink->audio_cond); } else { if (decklinksink->audio_eos) { GstMessage *message; @@ -1185,7 +705,7 @@ Output::RenderAudioSamples (bool preroll) gst_element_post_message (GST_ELEMENT_CAST (decklinksink), message); } } - g_mutex_unlock (decklinksink->audio_mutex); + g_mutex_unlock (&decklinksink->audio_mutex); } @@ -1193,122 +713,3 @@ Output::RenderAudioSamples (bool preroll) return S_OK; } - - -static const GList * -gst_decklink_sink_probe_get_properties (GstPropertyProbe * probe) -{ - GObjectClass *klass = G_OBJECT_GET_CLASS (probe); - static GList *list = NULL; - static gsize init = 0; - - if (g_once_init_enter (&init)) { - list = g_list_append (NULL, g_object_class_find_property (klass, "device")); - - g_once_init_leave (&init, 1); - } - - return list; -} - - -static gboolean probed = FALSE; -static int n_devices; - -static void -gst_decklink_sink_class_probe_devices (GstElementClass * klass) -{ - IDeckLinkIterator *iterator; - IDeckLink *decklink; - - n_devices = 0; - iterator = CreateDeckLinkIteratorInstance (); - if (iterator) { - while (iterator->Next (&decklink) == S_OK) { - n_devices++; - } - } - - probed = TRUE; -} - -static void -gst_decklink_sink_probe_probe_property (GstPropertyProbe * probe, - guint prop_id, const GParamSpec * pspec) -{ - GstElementClass *klass = GST_ELEMENT_GET_CLASS (probe); - - switch (prop_id) { - case PROP_DEVICE: - gst_decklink_sink_class_probe_devices (klass); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec); - break; - } -} - -static gboolean -gst_decklink_sink_probe_needs_probe (GstPropertyProbe * probe, - guint prop_id, const GParamSpec * pspec) -{ - gboolean ret = FALSE; - - switch (prop_id) { - case PROP_DEVICE: - ret = !probed; - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec); - break; - } - return ret; -} - -static GValueArray * -gst_decklink_sink_class_list_devices (GstElementClass * klass) -{ - GValueArray *array; - GValue value = { - 0}; - int i; - - array = g_value_array_new (n_devices); - g_value_init (&value, G_TYPE_INT); - for (i = 0; i < n_devices; i++) { - g_value_set_int (&value, i); - g_value_array_append (array, &value); - } - g_value_unset (&value); - - return array; -} - -static GValueArray * -gst_decklink_sink_probe_get_values (GstPropertyProbe * probe, - guint prop_id, const GParamSpec * pspec) -{ - GstElementClass *klass = GST_ELEMENT_GET_CLASS (probe); - GValueArray *array = NULL; - - switch (prop_id) { - case PROP_DEVICE: - array = gst_decklink_sink_class_list_devices (klass); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec); - break; - } - - return array; -} - -static void -gst_decklink_sink_property_probe_interface_init (GstPropertyProbeInterface * - iface) -{ - iface->get_properties = gst_decklink_sink_probe_get_properties; - iface->probe_property = gst_decklink_sink_probe_probe_property; - iface->needs_probe = gst_decklink_sink_probe_needs_probe; - iface->get_values = gst_decklink_sink_probe_get_values; -} diff --git a/sys/decklink/gstdecklinksink.h b/sys/decklink/gstdecklinksink.h index c72f673..541e254 100644 --- a/sys/decklink/gstdecklinksink.h +++ b/sys/decklink/gstdecklinksink.h @@ -29,6 +29,7 @@ G_BEGIN_DECLS #define GST_TYPE_DECKLINK_SINK (gst_decklink_sink_get_type()) #define GST_DECKLINK_SINK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_DECKLINK_SINK,GstDecklinkSink)) #define GST_DECKLINK_SINK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_DECKLINK_SINK,GstDecklinkSinkClass)) +#define GST_DECKLINK_SINK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_DECKLINK_SINK, GstDecklinkSinkClass)) #define GST_IS_DECKLINK_SINK(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_DECKLINK_SINK)) #define GST_IS_DECKLINK_SINK_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_DECKLINK_SINK)) @@ -57,10 +58,10 @@ struct _GstDecklinkSink GstPad *videosinkpad; GstPad *audiosinkpad; - GMutex *mutex; - GCond *cond; - GMutex *audio_mutex; - GCond *audio_cond; + GMutex mutex; + GCond cond; + GMutex audio_mutex; + GCond audio_cond; int queued_frames; gboolean stop; gboolean video_eos; @@ -84,11 +85,11 @@ struct _GstDecklinkSink #ifdef _MSC_VER gboolean comInitialized; - GMutex *com_init_lock; - GMutex *com_deinit_lock; - GCond *com_initialized; - GCond *com_uninitialize; - GCond *com_uninitialized; + GMutex com_init_lock; + GMutex com_deinit_lock; + GCond com_initialized; + GCond com_uninitialize; + GCond com_uninitialized; #endif /* _MSC_VER */ };