gnomemm r1444 - in gstreamermm/trunk: . examples/ogg_player gstreamer/src



Author: jaalburqu
Date: Mon Apr  7 23:26:37 2008
New Revision: 1444
URL: http://svn.gnome.org/viewvc/gnomemm?rev=1444&view=rev

Log:
2008-04-07  Josà Alburquerque  <jaalburqu svn gnome org>

	* gstreamer/src/pad.ccg:
	* gstreamer/src/pad.hg: Added add_{data,buffer,event}_probe() methods
	which accepts a slot (SlotData) to be called whenever data, an event,
	or a buffer passes through the pad.  Filed bug #526814 requesting
	enhancement to allow a disconnect callback to be called when "probes"
	are disconnected so that slot copies can be easily deleted on
	disconnections.

	Found that the "have-data" signal does not work on its own (connecting
	to it never calls slot) because C API doesn't transmit signal unless
	one of the add_*_probe() methods is used (see gst_pad_add_data_probe()
	implementation in gstutils.c) so unwrapped the signal to disallow
	possible confusion and let developers use add_*_probe() methods which
	will work.

	* examples/ogg_player/main.cc: Modified example to exemplify use
	Gst::Pad::add_data_probe() method

Modified:
   gstreamermm/trunk/ChangeLog
   gstreamermm/trunk/examples/ogg_player/main.cc
   gstreamermm/trunk/gstreamer/src/pad.ccg
   gstreamermm/trunk/gstreamer/src/pad.hg

Modified: gstreamermm/trunk/examples/ogg_player/main.cc
==============================================================================
--- gstreamermm/trunk/examples/ogg_player/main.cc	(original)
+++ gstreamermm/trunk/examples/ogg_player/main.cc	Mon Apr  7 23:26:37 2008
@@ -27,6 +27,7 @@
 Glib::RefPtr<Glib::MainLoop> mainloop;
 Glib::RefPtr<Gst::Pipeline> pipeline;
 Glib::RefPtr<Gst::Element> decoder;
+gulong data_probe_id;
 
 bool print_stream_position(void)
 {
@@ -103,6 +104,15 @@
   newPad->link(sinkPad);
 }
 
+bool on_sink_pad_have_data(const Glib::RefPtr<Gst::Pad>& pad,
+        const Glib::RefPtr<Gst::MiniObject>& data)
+{
+    std::cout << "Sink pad '" << pad->get_name() << "' has received data;";
+    std::cout << " will now remove sink data probe id: " << data_probe_id << std::endl;
+    pad->remove_data_probe(data_probe_id);
+    return true;
+}
+
 int main(int argc, char* argv[])
 {
   // check input arguments
@@ -148,6 +158,11 @@
     return -1;
   }
 
+    data_probe_id = sink->get_pad("sink")->add_data_probe(
+            sigc::ptr_fun(&on_sink_pad_have_data));
+    std::cout << "sink data probe id = " << data_probe_id << std::endl;
+
+
   // Set filename property on the file source. Also add a message handler:
   source->set_property("location", std::string(argv[1]));
 

Modified: gstreamermm/trunk/gstreamer/src/pad.ccg
==============================================================================
--- gstreamermm/trunk/gstreamer/src/pad.ccg	(original)
+++ gstreamermm/trunk/gstreamer/src/pad.ccg	Mon Apr  7 23:26:37 2008
@@ -31,11 +31,53 @@
 {
   Gst::Pad::SlotBlock * the_slot = static_cast<Gst::Pad::SlotBlock*>(data);
 
-  Glib::RefPtr<Gst::Pad> cpp_pad = Glib::wrap(pad, true);
-  (*the_slot)(cpp_pad, blocked);
+  #ifdef GLIBMM_EXCEPTIONS_ENABLED
+  try
+  {
+  #endif //GLIBMM_EXCEPTIONS_ENABLED
+    (*the_slot)(Glib::wrap(pad), blocked);
+    delete the_slot;
+  #ifdef GLIBMM_EXCEPTIONS_ENABLED
+  }
+  catch(...)
+  {
+    Glib::exception_handlers_invoke();
+  }
+
+  #endif //GLIBMM_EXCEPTIONS_ENABLED
+
+  //Delete once excuting slot
   delete the_slot;
 }
 
+static bool Pad_Data_gstreamermm_callback(GstPad* pad, GstMiniObject* mini_obj, void* data)
+{
+  Gst::Pad::SlotData* the_slot = static_cast<Gst::Pad::SlotData*>(data);
+
+  #ifdef GLIBMM_EXCEPTIONS_ENABLED
+  try
+  {
+  #endif //GLIBMM_EXCEPTIONS_ENABLED
+    return (*the_slot)(Glib::wrap(pad, true), Gst::wrap(mini_obj, true));
+  #ifdef GLIBMM_EXCEPTIONS_ENABLED
+  }
+  catch(...)
+  {
+    Glib::exception_handlers_invoke();
+  }
+
+  return TRUE; // Keep data
+  #endif //GLIBMM_EXCEPTIONS_ENABLED
+}
+
+static void Pad_Data_gstreamermm_callback_disconnect(void* data, GClosure* closure)
+{
+  Gst::Pad::SlotData* the_slot = static_cast<Gst::Pad::SlotData*>(data);
+
+  if (the_slot)
+    delete the_slot;
+}
+
 namespace Gst
 {
 
@@ -128,4 +170,28 @@
   return bool(gst_pad_set_blocked_async(GST_PAD(gobj()), gboolean(blocked), &Pad_Block_gstreamermm_callback, slot_copy));
 }
 
+gulong Pad::add_data_probe(const SlotData& slot)
+{
+  SlotData* slot_copy = new SlotData(slot);
+
+  //return gst_pad_add_data_probe_full(gobj(), G_CALLBACK (Pad_Data_gstreamermm_callback), slot_copy, &Pad_Data_gstreamermm_callback_disconnect);
+  return gst_pad_add_data_probe(gobj(), G_CALLBACK (Pad_Data_gstreamermm_callback), slot_copy);
+}
+
+gulong Pad::add_buffer_probe(const SlotData& slot)
+{
+  SlotData* slot_copy = new SlotData(slot);
+
+  //return gst_pad_add_buffer_probe_full(gobj(), G_CALLBACK (Pad_Data_gstreamermm_callback), slot_copy, &Pad_Data_gstreamermm_callback_disconnect);
+  return gst_pad_add_buffer_probe(gobj(), G_CALLBACK (Pad_Data_gstreamermm_callback), slot_copy);
+}
+
+gulong Pad::add_event_probe(const SlotData& slot)
+{
+  SlotData* slot_copy = new SlotData(slot);
+
+  //return gst_pad_add_event_probe_full(gobj(), G_CALLBACK (Pad_Data_gstreamermm_callback), slot_copy, &Pad_Data_gstreamermm_callback_disconnect);
+  return gst_pad_add_event_probe(gobj(), G_CALLBACK (Pad_Data_gstreamermm_callback), slot_copy);
+}
+
 } //namespace Gst

Modified: gstreamermm/trunk/gstreamer/src/pad.hg
==============================================================================
--- gstreamermm/trunk/gstreamer/src/pad.hg	(original)
+++ gstreamermm/trunk/gstreamer/src/pad.hg	Mon Apr  7 23:26:37 2008
@@ -59,6 +59,14 @@
    */
   typedef sigc::slot<void, const Glib::RefPtr<Pad>&, bool> SlotBlock;
 
+  /** For example,
+   * bool on_have_data(const Glib::RefPtr<Pad>& pad, const
+   * Glib::RefPtr<MiniObjec>& data);
+   * The on_have_data method should return TRUE to keep the data in the
+   * pipeline, FALSE to drop it (throw it away)
+   */
+  typedef sigc::slot< bool, const Glib::RefPtr<Pad>&, const Glib::RefPtr<MiniObject>& > SlotData;
+
   _WRAP_CREATE(const Glib::ustring& name, PadDirection dir)
   _WRAP_CREATE(const Glib::RefPtr<PadTemplate>& pad_template, const Glib::ustring& name)
 
@@ -111,6 +119,46 @@
   _WRAP_METHOD(bool is_blocked() const, gst_pad_is_blocked)
   _WRAP_METHOD(bool is_blocking() const, gst_pad_is_blocking)
 
+  /** Adds a "data probe" to a pad. The slot will be called whenever data
+   * passes through a pad. In this case data means both events and buffers. The
+   * probe will be called with the data as an argument. Note that the data will
+   * have a reference count greater than 1, so it will be immutable -- you must
+   * not change it.
+   *
+   * For source pads, the probe will be called after the blocking function, if
+   * any (see set_blocked_async()), but before looking up the peer to chain to.
+   * For sink pads, the probe function will be called before configuring the
+   * sink with new caps, if any, and before calling the pad's chain function.
+   *
+   * Your data probe should return TRUE to let the data continue to flow, or
+   * FALSE to drop it. Dropping data is rarely useful, but occasionally comes
+   * in handy with events.
+   *
+   * To remove a probe, use the appropriate function, such as
+   * remove_data_probe().
+   *
+   * @param slot The slot to call when data is passed over pad (note: slot is
+   * not copied because it is connected to a signal)
+   * @return The handler id which may be used to remove the connection later.
+   */
+  gulong add_data_probe(const SlotData& slot);
+
+  /** Adds a probe that will be called for all buffers passing through a pad.
+   * See add_data_probe() for more information.
+   *
+   * @param slot The slot to call when buffers are passed over pad
+   * @return The handler id
+   */
+  gulong add_buffer_probe(const SlotData& slot);
+
+  /** Adds a probe that will be called for all events passing through a pad.
+   * See add_data_probe() for more information.
+   *
+   * @param slot The slot to call when events are passed over pad
+   * @return The handler id
+   */
+  gulong add_event_probe(const SlotData& slot);
+
   _WRAP_METHOD(void remove_data_probe(guint handler_id), gst_pad_remove_data_probe)
   _WRAP_METHOD(void remove_buffer_probe(guint handler_id), gst_pad_remove_buffer_probe)
   _WRAP_METHOD(void remove_event_probe(guint handler_id), gst_pad_remove_event_probe)
@@ -192,11 +240,6 @@
 	  gst_pad_set_fixatecaps_function,gst_pad_set_chain_function,
 	  gst_pad_set_internal_link_function, gst_pad_get_pad_template_caps)
 
-#m4 _CONVERSION(`GstMiniObject*',`const Glib::RefPtr<MiniObject>&',`wrap($3, false)')
-
-#m4 _CONVERSION(`const Glib::RefPtr<Gst::MiniObject>&',`GstMiniObject*',`Gst::unwrap($3)')
-#m4 _CONVERSION(`GstMiniObject*',`const Glib::RefPtr<Gst::MiniObject>&',`Gst::wrap($3)')
-  _WRAP_SIGNAL(bool have_data(const Glib::RefPtr<Gst::MiniObject>& mini_obj), "have-data")
 
 #m4 _CONVERSION(`GstPad*',`const Glib::RefPtr<Pad>&',`Glib::wrap($3, true)')
   _WRAP_SIGNAL(void linked(const Glib::RefPtr<Pad>& peer_pad), "linked")



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]