Re: gstmm add element to pipeline test



José Alburquerque wrote:
My question is: When these functions are wrapped, should similar names be used for the methods (eg. Gst::Bus::add_signal_watch() for gst_bus_add_signal_watch)?

-Jose

Hi. For now I decided to keep the names consistent with C just to wrap the functionality. I tested what I wrapped with two versions of the ogg player I submitted a few days ago. I'm not sure about the name I chose for the slot typedef and the parameter order of the methods so I'm hoping you can take a look and critique what might be wrong. To that end, I'm including the patch (bus-message-02.diff) and the two versions of the player.

The issue I pointed out about the Bus not being destroyed left me a bit inquisitive so I tested again (by using a custom destructor for Gst::Bus) and I found that for the signal version of the ogg player, the bus is destroyed, however if the last line before the return in main() ("bus->remove_signal_watch()") is removed, the bus is not destroyed. The bus is not destroyed for the slot version of the player. To test use the "bus-message-custom-destructor.diff". I get the feeling that this is not something to be concerned about, but I wanted to point it out in case it is an issue. Thanks.

-Jose
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 95)
+++ ChangeLog	(working copy)
@@ -1,3 +1,19 @@
+2007-12-05  José Alburquerque  <jaalburquerque yahoo com>
+
+	* gst/src/bus.ccg: added add_watch() method functionality
+	* gst/src/bus.hg: added typedef SlotWatch, wrapped methods
+	add_signal_watch(), add_signal_watch_full(), and
+	remove_signal_watch() and wrapped signals message() and sync_message()
+	* gst/src/gst_signals.defs: sync-message and message had wrong
+	parameter type (GstMessage instead of GstMessage*)
+	* gst/src/message.hg: changed get_type() to be public
+	* tests/Makefile.am: modified to include test-create-bin
+	* tests/test-create-bin.cc: added this test to create a bin and add
+	elements to it (to "catch" errors as API changes)
+	* tests/test-link-elements.cc: Removed a blank line
+	* tools/m4/convert_gst.m4: Added conversion from GstMessageType to
+	Gst::MessageType (for Gst::Message::get_type())
+
 2007-12-03  Murray Cumming  <murrayc murrayc com>
 
 	* gst/src/element.ccg: get_compatible_pad((): Clarify 
Index: gst/src/gst_signals.defs
===================================================================
--- gst/src/gst_signals.defs	(revision 95)
+++ gst/src/gst_signals.defs	(working copy)
@@ -5,7 +5,7 @@
   (return-type "void")
   (when "last")
   (parameters
-    '("GstMessage" "p0")
+    '("GstMessage*" "p0")
   )
 )
 
@@ -14,7 +14,7 @@
   (return-type "void")
   (when "last")
   (parameters
-    '("GstMessage" "p0")
+    '("GstMessage*" "p0")
   )
 )
 
Index: gst/src/message.hg
===================================================================
--- gst/src/message.hg	(revision 95)
+++ gst/src/message.hg	(working copy)
@@ -138,9 +138,11 @@
       _CLASS_OPAQUE_REFCOUNTED(Message, GstMessage, NONE, gst_message_ref, gst_message_unref)
       _IGNORE(gst_message_ref, gst_message_unref)
 
-      MessageType get_type();
       const Structure& get_structure();
 
+    public:
+      _MEMBER_GET(type, type, MessageType, GstMessageType)
+
     protected: 
 
       GstMessage * cobj_;
Index: gst/src/bus.ccg
===================================================================
--- gst/src/bus.ccg	(revision 95)
+++ gst/src/bus.ccg	(working copy)
@@ -1,4 +1,29 @@
 
+static gboolean SignalProxy_Watch_glib_callback(GstBus* bus, GstMessage* message, void* data)
+{
+  Gst::Bus::SlotWatch* the_slot = static_cast<Gst::Bus::SlotWatch*>(data);
+
+  #ifdef GLIBMM_EXCEPTIONS_ENABLED
+  try
+  {
+  #endif //GLIBMM_EXCEPTIONS_ENABLED
+    return (*the_slot)(Glib::wrap(bus, true), Glib::wrap(message, true));
+  #ifdef GLIBMM_EXCEPTIONS_ENABLED
+  }
+  catch(...)
+  {
+    Glib::exception_handlers_invoke();
+  }
+
+  return 0; // arbitrary value
+  #endif //GLIBMM_EXCEPTIONS_ENABLED
+}
+
+static void SignalProxy_Watch_glib_callback_destroy(void* data)
+{
+  delete static_cast<Gst::Bus::SlotWatch*>(data);
+}
+
 namespace Gst
 {
 
@@ -8,4 +33,14 @@
   return Glib::wrap(bus, false);
 }
 
+void Bus::add_watch(const SlotWatch& slot, int priority) {
+  //Create a copy of the slot. A pointer to this will be passed through the callback's data parameter.
+  //It will be deleted when SignalProxy_Watch_glib_callback_destroy() is called.
+  SlotWatch* slot_copy = new SlotWatch(slot);
+  gst_bus_add_watch_full(gobj(), priority,
+        &SignalProxy_Watch_glib_callback, slot_copy,
+        &SignalProxy_Watch_glib_callback_destroy);
+
+}
+
 } //namespace Gst
Index: gst/src/bus.hg
===================================================================
--- gst/src/bus.hg	(revision 95)
+++ gst/src/bus.hg	(working copy)
@@ -15,7 +15,6 @@
   _CLASS_GOBJECT(Bus, GstBus, GST_BUS, Object, GstObject)
 
 protected:
-
   _CTOR_DEFAULT()
 
 public:
@@ -32,12 +31,19 @@
 
   _WRAP_METHOD(void set_flushing(gboolean flushing), gst_bus_set_flushing)
 
+  typedef sigc::slot<bool, const Glib::RefPtr<Bus>&, const Glib::RefPtr<Message>& > SlotWatch;
+  void add_watch(const SlotWatch& slot, int priority = G_PRIORITY_DEFAULT);
+
   _WRAP_METHOD(void disable_sync_message_emission(), gst_bus_disable_sync_message_emission)
   _WRAP_METHOD(void enable_sync_message_emission(), gst_bus_enable_sync_message_emission)
 
+  _WRAP_METHOD(void add_signal_watch(), gst_bus_add_signal_watch)
+  _WRAP_METHOD(void add_signal_watch_full(int priority), gst_bus_add_signal_watch_full)
+  _WRAP_METHOD(void remove_signal_watch(), gst_bus_remove_signal_watch)
+
 #m4 _CONVERSION(`GstMessage*',`const Glib::RefPtr<Message>&', `Glib::wrap($3, true)')
-  //TODO: _WRAP_SIGNAL(void message(const Glib::RefPtr<Message>& message), "message")
-  //TODO: _WRAP_SIGNAL(void sync_message(const Glib::RefPtr<Message>& message), "sync-message")
+  _WRAP_SIGNAL(void message(const Glib::RefPtr<Message>& message), "message")
+  _WRAP_SIGNAL(void sync_message(const Glib::RefPtr<Message>& message), "sync-message")
 };
 
 } //namespace Gst
Index: tools/m4/convert_gst.m4
===================================================================
--- tools/m4/convert_gst.m4	(revision 95)
+++ tools/m4/convert_gst.m4	(working copy)
@@ -55,6 +55,7 @@
 _CONVERSION(`const gint64&',`gint64',`$3')
 _CONVERSION(`gint64&',`gint64*',`&($3)')
 _CONVERSION(`const double&',`gdouble',`$3')
+_CONVERSION(`GstMessageType',`MessageType',`MessageType($3)')
 
 _CONV_ENUM(Gst,State)
 _CONV_ENUM(Gst,StateChangeReturn)
Index: tests/test-link-elements.cc
===================================================================
--- tests/test-link-elements.cc	(revision 95)
+++ tests/test-link-elements.cc	(working copy)
@@ -8,7 +8,6 @@
   Glib::RefPtr<Gst::Pipeline> pipeline;
   Glib::RefPtr<Gst::Element> source, filter, sink;
 
-
   pipeline = Gst::Pipeline::create("my-pipeline");
 
   source = Gst::Element::create("fakesrc", "source");
Index: tests/Makefile.am
===================================================================
--- tests/Makefile.am	(revision 95)
+++ tests/Makefile.am	(working copy)
@@ -2,7 +2,7 @@
 
 LDADD=$(top_builddir)/gst/gstmm/libgstmm-1.0.la
 
-noinst_PROGRAMS = test-create-element test-pipeline-add-element test-link-elements
+noinst_PROGRAMS = test-create-element test-pipeline-add-element test-link-elements test-create-bin
 
 test_create_element_SOURCES=test-create-element.cc
 test_create_element_LDFLAGS= GSTMM_LIBS@
@@ -13,6 +13,9 @@
 test_link_elements_SOURCES=test-link-elements.cc
 test_link_elements_LDFLAGS= GSTMM_LIBS@
 
+test_create_bin_SOURCES=test-create-bin.cc
+test_create_bin_LDFLAGS= GSTMM_LIBS@
+
 #runtestbasic runtestlangs \
 #runtestsearch runtestmimetypes \
 #runtestgetbuffer
Index: tests/test-create-bin.cc
===================================================================
--- tests/test-create-bin.cc	(revision 0)
+++ tests/test-create-bin.cc	(revision 0)
@@ -0,0 +1,26 @@
+#include <gstmm.h>
+#include <iostream>
+
+int main (int argc, char* argv[])
+{
+  Gst::init(argc, argv);
+
+  Glib::RefPtr<Gst::Pipeline> pipeline;
+  Glib::RefPtr<Gst::Bin> bin;
+  Glib::RefPtr<Gst::Element> source, sink;
+
+  pipeline = Gst::Pipeline::create("my-pipeline");
+  bin = Gst::Bin::create("my-bin");
+
+  source = Gst::Element::create("fakesrc", "source");
+  sink = Gst::Element::create("fakesink", "sink");
+
+  bin->add(source)->add(sink);
+
+  pipeline->add(bin);
+  source->link(sink);
+
+  std::cout << "Successfully added elements '" << source->get_name() <<
+    "' and '" << sink->get_name() << "' to bin '" <<
+      bin->get_name() << "'." << std::endl;
+}
#include <iostream>
#include <gstmm.h>

using namespace Glib;
using namespace Gst;
using namespace std;

void bus_message_received(const RefPtr<Message>& message,
RefPtr<MainLoop> mainLoop)
{
  switch (message->get_type()) {
    case MESSAGE_EOS:
      cout << "End of stream" << endl;
      mainLoop->quit();
      break;
    case MESSAGE_ERROR:
      cerr << "Error." << endl;
      mainLoop->quit();
      break;
    default:
      break;
  }
}

void parser_pad_added(const RefPtr<Pad>& newPad, RefPtr<Element> decoder)
{
  cout << "Dynamic pad created, linking parser/decoder." << endl;
  RefPtr<Pad> sinkPad = decoder->get_pad("sink");
  newPad->link(sinkPad);
}

int main(int argc, char* argv[]) {
  if (argc != 2) {
    cout << "Usage: " << argv[0] << " <Ogg/Vorbis filename>" << endl;
    return -1;
  }

  Gst::init(argc, argv);
  RefPtr<MainLoop> mainLoop = Glib::MainLoop::create();

  /* create elements */
  RefPtr<Pipeline> pipeline = Gst::Pipeline::create("audio-player");
  RefPtr<Element> source = Gst::Element::create("filesrc", "file-source");
  RefPtr<Element> parser = Gst::Element::create("oggdemux", "ogg-parser");
  RefPtr<Element> decoder = Gst::Element::create("vorbisdec", "vorbis-decoder");
  RefPtr<Element> conv = Gst::Element::create("audioconvert", "converter");
  RefPtr<Element> sink = Gst::Element::create("alsasink", "alsa-output");

  if (!pipeline || !source || !parser || !decoder || !conv || !sink) {
    cerr << "One element could not be created." << endl;
    return -1;
  }

  /* set filename property on the file source. Also add a message
   * handler. */
  source->set_property("location", (string) argv[1]);

  RefPtr<Bus> bus = pipeline->get_bus();
  bus->add_signal_watch();
  bus->signal_message().connect(sigc::bind< RefPtr<MainLoop> >(
    sigc::ptr_fun(&bus_message_received), mainLoop) );

  /* put all elements in a bin */
  pipeline->add(source)->add(parser)->add(decoder)->add(conv)->add(sink);

  /* link together - note that we cannot link the parser and
   * decoder yet, becuse the parser uses dynamic pads. For that,
   * we set a pad-added signal handler. */
  source->link(parser);
  decoder->link(conv)->link(sink);

  parser->signal_pad_added().connect(sigc::bind< RefPtr<Element> >(
    sigc::ptr_fun(&parser_pad_added), decoder) );

  /* Now set to playing and iterate. */
  cout << "Setting to PLAYING." << endl;
  pipeline->set_state(STATE_PLAYING);
  cout << "Running." << endl;
  mainLoop->run();

  /* clean up nicely */
  cout << "Returned, stopping playback." << endl;
  pipeline->set_state(STATE_NULL);

  bus->remove_signal_watch();

  return 0;
}
#include <iostream>
#include <gstmm.h>

using namespace Glib;
using namespace Gst;
using namespace std;

bool process_bus_message(const RefPtr<Bus>& bus, const RefPtr<Message>& message,
RefPtr<MainLoop> mainLoop)
{
  switch (message->get_type()) {
    case MESSAGE_EOS:
      cout << "End of stream" << endl;
      mainLoop->quit();
      break;
    case MESSAGE_ERROR:
      cerr << "Error." << endl;
      mainLoop->quit();
      break;
    default:
      break;
  }
  return true;
}

void parser_pad_added(const RefPtr<Pad>& newPad, RefPtr<Element> decoder)
{
  cout << "Dynamic pad created, linking parser/decoder." << endl;
  RefPtr<Pad> sinkPad = decoder->get_pad("sink");
  newPad->link(sinkPad);
}

int main(int argc, char* argv[]) {
  if (argc != 2) {
    cout << "Usage: " << argv[0] << " <Ogg/Vorbis filename>" << endl;
    return -1;
  }

  Gst::init(argc, argv);
  RefPtr<MainLoop> mainLoop = Glib::MainLoop::create();

  /* create elements */
  RefPtr<Pipeline> pipeline = Gst::Pipeline::create("audio-player");
  RefPtr<Element> source = Gst::Element::create("filesrc", "file-source");
  RefPtr<Element> parser = Gst::Element::create("oggdemux", "ogg-parser");
  RefPtr<Element> decoder = Gst::Element::create("vorbisdec", "vorbis-decoder");
  RefPtr<Element> conv = Gst::Element::create("audioconvert", "converter");
  RefPtr<Element> sink = Gst::Element::create("alsasink", "alsa-output");

  if (!pipeline || !source || !parser || !decoder || !conv || !sink) {
    cerr << "One element could not be created." << endl;
    return -1;
  }

  /* set filename property on the file source. Also add a message
   * handler. */
  source->set_property("location", (string) argv[1]);

  RefPtr<Bus> bus = pipeline->get_bus();
  Bus::SlotWatch slot(sigc::bind< RefPtr<MainLoop> >( sigc::ptr_fun(&process_bus_message), mainLoop) );
  bus->add_watch(slot);

  /* put all elements in a bin */
  pipeline->add(source)->add(parser)->add(decoder)->add(conv)->add(sink);

  /* link together - note that we cannot link the parser and
   * decoder yet, becuse the parser uses dynamic pads. For that,
   * we set a pad-added signal handler. */
  source->link(parser);
  decoder->link(conv)->link(sink);

  parser->signal_pad_added().connect(sigc::bind< RefPtr<Element> >(
    sigc::ptr_fun(&parser_pad_added), decoder) );

  /* Now set to playing and iterate. */
  cout << "Setting to PLAYING." << endl;
  pipeline->set_state(STATE_PLAYING);
  cout << "Running." << endl;
  mainLoop->run();

  /* clean up nicely */
  cout << "Returned, stopping playback." << endl;
  pipeline->set_state(STATE_NULL);

  return 0;
}
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 95)
+++ ChangeLog	(working copy)
@@ -1,3 +1,19 @@
+2007-12-05  José Alburquerque  <jaalburquerque yahoo com>
+
+	* gst/src/bus.ccg: added add_watch() method functionality
+	* gst/src/bus.hg: added typedef SlotWatch, wrapped methods
+	add_signal_watch(), add_signal_watch_full(), and
+	remove_signal_watch() and wrapped signals message() and sync_message()
+	* gst/src/gst_signals.defs: sync-message and message had wrong
+	parameter type (GstMessage instead of GstMessage*)
+	* gst/src/message.hg: changed get_type() to be public
+	* tests/Makefile.am: modified to include test-create-bin
+	* tests/test-create-bin.cc: added this test to create a bin and add
+	elements to it (to "catch" errors as API changes)
+	* tests/test-link-elements.cc: Removed a blank line
+	* tools/m4/convert_gst.m4: Added conversion from GstMessageType to
+	Gst::MessageType (for Gst::Message::get_type())
+
 2007-12-03  Murray Cumming  <murrayc murrayc com>
 
 	* gst/src/element.ccg: get_compatible_pad((): Clarify 
Index: gst/src/gst_signals.defs
===================================================================
--- gst/src/gst_signals.defs	(revision 95)
+++ gst/src/gst_signals.defs	(working copy)
@@ -5,7 +5,7 @@
   (return-type "void")
   (when "last")
   (parameters
-    '("GstMessage" "p0")
+    '("GstMessage*" "p0")
   )
 )
 
@@ -14,7 +14,7 @@
   (return-type "void")
   (when "last")
   (parameters
-    '("GstMessage" "p0")
+    '("GstMessage*" "p0")
   )
 )
 
Index: gst/src/message.hg
===================================================================
--- gst/src/message.hg	(revision 95)
+++ gst/src/message.hg	(working copy)
@@ -138,9 +138,11 @@
       _CLASS_OPAQUE_REFCOUNTED(Message, GstMessage, NONE, gst_message_ref, gst_message_unref)
       _IGNORE(gst_message_ref, gst_message_unref)
 
-      MessageType get_type();
       const Structure& get_structure();
 
+    public:
+      _MEMBER_GET(type, type, MessageType, GstMessageType)
+
     protected: 
 
       GstMessage * cobj_;
Index: gst/src/bus.ccg
===================================================================
--- gst/src/bus.ccg	(revision 95)
+++ gst/src/bus.ccg	(working copy)
@@ -1,4 +1,29 @@
 
+static gboolean SignalProxy_Watch_glib_callback(GstBus* bus, GstMessage* message, void* data)
+{
+  Gst::Bus::SlotWatch* the_slot = static_cast<Gst::Bus::SlotWatch*>(data);
+
+  #ifdef GLIBMM_EXCEPTIONS_ENABLED
+  try
+  {
+  #endif //GLIBMM_EXCEPTIONS_ENABLED
+    return (*the_slot)(Glib::wrap(bus, true), Glib::wrap(message, true));
+  #ifdef GLIBMM_EXCEPTIONS_ENABLED
+  }
+  catch(...)
+  {
+    Glib::exception_handlers_invoke();
+  }
+
+  return 0; // arbitrary value
+  #endif //GLIBMM_EXCEPTIONS_ENABLED
+}
+
+static void SignalProxy_Watch_glib_callback_destroy(void* data)
+{
+  delete static_cast<Gst::Bus::SlotWatch*>(data);
+}
+
 namespace Gst
 {
 
@@ -8,4 +33,18 @@
   return Glib::wrap(bus, false);
 }
 
+void Bus::add_watch(const SlotWatch& slot, int priority) {
+  //Create a copy of the slot. A pointer to this will be passed through the callback's data parameter.
+  //It will be deleted when SignalProxy_Watch_glib_callback_destroy() is called.
+  SlotWatch* slot_copy = new SlotWatch(slot);
+  gst_bus_add_watch_full(gobj(), priority,
+        &SignalProxy_Watch_glib_callback, slot_copy,
+        &SignalProxy_Watch_glib_callback_destroy);
+
+}
+
+Bus::~Bus() {
+  gst_bus_disable_sync_message_emission(gobj());
+}
+
 } //namespace Gst
Index: gst/src/bus.hg
===================================================================
--- gst/src/bus.hg	(revision 95)
+++ gst/src/bus.hg	(working copy)
@@ -13,9 +13,9 @@
 class Bus : public Object
 {
   _CLASS_GOBJECT(Bus, GstBus, GST_BUS, Object, GstObject)
+  _CUSTOM_DTOR
 
 protected:
-
   _CTOR_DEFAULT()
 
 public:
@@ -32,12 +32,19 @@
 
   _WRAP_METHOD(void set_flushing(gboolean flushing), gst_bus_set_flushing)
 
+  typedef sigc::slot<bool, const Glib::RefPtr<Bus>&, const Glib::RefPtr<Message>& > SlotWatch;
+  void add_watch(const SlotWatch& slot, int priority = G_PRIORITY_DEFAULT);
+
   _WRAP_METHOD(void disable_sync_message_emission(), gst_bus_disable_sync_message_emission)
   _WRAP_METHOD(void enable_sync_message_emission(), gst_bus_enable_sync_message_emission)
 
+  _WRAP_METHOD(void add_signal_watch(), gst_bus_add_signal_watch)
+  _WRAP_METHOD(void add_signal_watch_full(int priority), gst_bus_add_signal_watch_full)
+  _WRAP_METHOD(void remove_signal_watch(), gst_bus_remove_signal_watch)
+
 #m4 _CONVERSION(`GstMessage*',`const Glib::RefPtr<Message>&', `Glib::wrap($3, true)')
-  //TODO: _WRAP_SIGNAL(void message(const Glib::RefPtr<Message>& message), "message")
-  //TODO: _WRAP_SIGNAL(void sync_message(const Glib::RefPtr<Message>& message), "sync-message")
+  _WRAP_SIGNAL(void message(const Glib::RefPtr<Message>& message), "message")
+  _WRAP_SIGNAL(void sync_message(const Glib::RefPtr<Message>& message), "sync-message")
 };
 
 } //namespace Gst
Index: tools/m4/convert_gst.m4
===================================================================
--- tools/m4/convert_gst.m4	(revision 95)
+++ tools/m4/convert_gst.m4	(working copy)
@@ -55,6 +55,7 @@
 _CONVERSION(`const gint64&',`gint64',`$3')
 _CONVERSION(`gint64&',`gint64*',`&($3)')
 _CONVERSION(`const double&',`gdouble',`$3')
+_CONVERSION(`GstMessageType',`MessageType',`MessageType($3)')
 
 _CONV_ENUM(Gst,State)
 _CONV_ENUM(Gst,StateChangeReturn)
Index: tests/test-link-elements.cc
===================================================================
--- tests/test-link-elements.cc	(revision 95)
+++ tests/test-link-elements.cc	(working copy)
@@ -8,7 +8,6 @@
   Glib::RefPtr<Gst::Pipeline> pipeline;
   Glib::RefPtr<Gst::Element> source, filter, sink;
 
-
   pipeline = Gst::Pipeline::create("my-pipeline");
 
   source = Gst::Element::create("fakesrc", "source");
Index: tests/Makefile.am
===================================================================
--- tests/Makefile.am	(revision 95)
+++ tests/Makefile.am	(working copy)
@@ -2,7 +2,7 @@
 
 LDADD=$(top_builddir)/gst/gstmm/libgstmm-1.0.la
 
-noinst_PROGRAMS = test-create-element test-pipeline-add-element test-link-elements
+noinst_PROGRAMS = test-create-element test-pipeline-add-element test-link-elements test-create-bin
 
 test_create_element_SOURCES=test-create-element.cc
 test_create_element_LDFLAGS= GSTMM_LIBS@
@@ -13,6 +13,9 @@
 test_link_elements_SOURCES=test-link-elements.cc
 test_link_elements_LDFLAGS= GSTMM_LIBS@
 
+test_create_bin_SOURCES=test-create-bin.cc
+test_create_bin_LDFLAGS= GSTMM_LIBS@
+
 #runtestbasic runtestlangs \
 #runtestsearch runtestmimetypes \
 #runtestgetbuffer
Index: tests/test-create-bin.cc
===================================================================
--- tests/test-create-bin.cc	(revision 0)
+++ tests/test-create-bin.cc	(revision 0)
@@ -0,0 +1,26 @@
+#include <gstmm.h>
+#include <iostream>
+
+int main (int argc, char* argv[])
+{
+  Gst::init(argc, argv);
+
+  Glib::RefPtr<Gst::Pipeline> pipeline;
+  Glib::RefPtr<Gst::Bin> bin;
+  Glib::RefPtr<Gst::Element> source, sink;
+
+  pipeline = Gst::Pipeline::create("my-pipeline");
+  bin = Gst::Bin::create("my-bin");
+
+  source = Gst::Element::create("fakesrc", "source");
+  sink = Gst::Element::create("fakesink", "sink");
+
+  bin->add(source)->add(sink);
+
+  pipeline->add(bin);
+  source->link(sink);
+
+  std::cout << "Successfully added elements '" << source->get_name() <<
+    "' and '" << sink->get_name() << "' to bin '" <<
+      bin->get_name() << "'." << std::endl;
+}


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