Re: gstmm add element to pipeline test
- From: José Alburquerque <jaalburquerque cox net>
- To: Murray Cumming <murrayc murrayc com>
- Cc: gtkmm-list gnome org
- Subject: Re: gstmm add element to pipeline test
- Date: Wed, 05 Dec 2007 23:47:43 -0500
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]