gnomemm r1665 - in gstreamermm/trunk: . gstreamer gstreamer/src gstreamerbase gstreamerbase/src tests tools/m4
- From: jaalburqu svn gnome org
- To: svn-commits-list gnome org
- Subject: gnomemm r1665 - in gstreamermm/trunk: . gstreamer gstreamer/src gstreamerbase gstreamerbase/src tests tools/m4
- Date: Fri, 8 Aug 2008 21:31:39 +0000 (UTC)
Author: jaalburqu
Date: Fri Aug 8 21:31:39 2008
New Revision: 1665
URL: http://svn.gnome.org/viewvc/gnomemm?rev=1665&view=rev
Log:
2008-08-08 Josà Alburquerque <jaalburqu svn gnome org>
* gstreamer/src/iterator.ccg:
* gstreamer/src/iterator.hg: First cut at implementing Gst::Iterator.
* gstreamer/gstreamermm.h:
* gstreamer/src/Makefile_list_of_hg.am_fragment: Re-added
Gst::Iterator after first cut at implementing it.
* gstreamer/src/bin.hg:
* tools/m4/convert_gst.m4: Wrapped iterate_elements() (makes use of
Gst::Iterator).
* tests/Makefile.am:
* tests/test-iterator.cc: Added Gst::Iterator test. Still need to
test further and refine Iterator class implementations where possible.
* gstreamerbase/gstreamerbasemm.h: Added audioclock.h.
* gstreamerbase/src/audioclock.ccg:
* gstreamer/src/element.hg: Typos.
Added:
gstreamermm/trunk/tests/test-iterator.cc
Modified:
gstreamermm/trunk/ChangeLog
gstreamermm/trunk/gstreamer/gstreamermm.h
gstreamermm/trunk/gstreamer/src/Makefile_list_of_hg.am_fragment
gstreamermm/trunk/gstreamer/src/bin.hg
gstreamermm/trunk/gstreamer/src/element.hg
gstreamermm/trunk/gstreamer/src/iterator.ccg
gstreamermm/trunk/gstreamer/src/iterator.hg
gstreamermm/trunk/gstreamerbase/gstreamerbasemm.h
gstreamermm/trunk/gstreamerbase/src/audioclock.ccg
gstreamermm/trunk/tests/Makefile.am
gstreamermm/trunk/tools/m4/convert_gst.m4
Modified: gstreamermm/trunk/gstreamer/gstreamermm.h
==============================================================================
--- gstreamermm/trunk/gstreamer/gstreamermm.h (original)
+++ gstreamermm/trunk/gstreamer/gstreamermm.h Fri Aug 8 21:31:39 2008
@@ -19,7 +19,7 @@
#include <gstreamermm/index.h>
#include <gstreamermm/indexfactory.h>
#include <gstreamermm/interface.h>
-//TODO: #include <gstreamermm/iterator.h> (when wrapping of GstIterator is done)
+#include <gstreamermm/iterator.h>
#include <gstreamermm/message.h>
#include <gstreamermm/object.h>
#include <gstreamermm/pad.h>
Modified: gstreamermm/trunk/gstreamer/src/Makefile_list_of_hg.am_fragment
==============================================================================
--- gstreamermm/trunk/gstreamer/src/Makefile_list_of_hg.am_fragment (original)
+++ gstreamermm/trunk/gstreamer/src/Makefile_list_of_hg.am_fragment Fri Aug 8 21:31:39 2008
@@ -6,7 +6,7 @@
files_win32_hg =
files_general_hg = bin.hg buffer.hg bus.hg caps.hg childproxy.hg clock.hg \
element.hg elementfactory.hg enums.hg error.hg event.hg filter.hg \
- format.hg index.hg indexfactory.hg interface.hg \
+ format.hg index.hg indexfactory.hg interface.hg iterator.hg \
message.hg pad.hg padtemplate.hg parse.hg pipeline.hg \
plugin.hg pluginfeature.hg query.hg registry.hg segment.hg \
structure.hg systemclock.hg tagsetter.hg task.hg urihandler.hg \
Modified: gstreamermm/trunk/gstreamer/src/bin.hg
==============================================================================
--- gstreamermm/trunk/gstreamer/src/bin.hg (original)
+++ gstreamermm/trunk/gstreamer/src/bin.hg Fri Aug 8 21:31:39 2008
@@ -22,6 +22,7 @@
#include <gstreamermm/element.h>
#include <gstreamermm/childproxy.h>
#include <gstreamermm/pad.h>
+#include <gstreamermm/iterator.h>
#include <stdexcept> //Because add() throws std::runtime_error.
_DEFS(gstreamermm,gst)
@@ -186,9 +187,9 @@
_WRAP_METHOD(Glib::RefPtr<Pad> find_unconnected_pad(PadDirection dir), gst_bin_find_unconnected_pad)
_WRAP_METHOD(Glib::RefPtr<const Pad> find_unconnected_pad(PadDirection dir) const, gst_bin_find_unconnected_pad)
+ _WRAP_METHOD(Iterator<Element> iterate_elements(), gst_bin_iterate_elements)
/* TODO:
-GstIterator* gst_bin_iterate_elements (GstBin *bin);
GstIterator* gst_bin_iterate_sorted (GstBin *bin);
GstIterator* gst_bin_iterate_recurse (GstBin *bin);
Modified: gstreamermm/trunk/gstreamer/src/element.hg
==============================================================================
--- gstreamermm/trunk/gstreamer/src/element.hg (original)
+++ gstreamermm/trunk/gstreamer/src/element.hg Fri Aug 8 21:31:39 2008
@@ -336,28 +336,29 @@
* underlying gobject implements.
* Gst::ElementInterfaced is a templated class which, in conjunction with
* Gst::Interface::cast(), is used to cast a Gst::Element obtained by
- * Gst::ElementFactory::create() into underlying GStreamer interfaces that the
- * element may implement. A 'filesrc' element, for example, implements the
- * Gst::URIHandler interface (which is not reflected in a Gst::Element obtained
- * from a Gst::ElementFactory). To use the Gst::URIHandler methods with a
- * 'filesrc' element obtained from a Gst::ElementFactory, one would do the
- * following:
+ * Gst::ElementFactory::create_element() into underlying GStreamer interfaces
+ * that the element may implement. A 'filesrc' element, for example,
+ * implements the Gst::URIHandler interface (which is not reflected in a
+ * Gst::Element obtained from a Gst::ElementFactory). To use the
+ * Gst::URIHandler methods with a 'filesrc' element obtained from a
+ * Gst::ElementFactory, one would do the following:
* @code
* ...
- * Glib::RefPtr<Gst::Element> element = Gst::ElementFactory::create("filesrc",
- * "source");
+ * Glib::RefPtr<Gst::Element> element =
+ * Gst::ElementFactory::create_element("filesrc", "source");
*
* Glib::RefPtr< Gst::ElementInterfaced<Gst::URIHandler> > handler =
* Gst::Interface::cast<Gst::URIHandler>(element);
*
- * if(handler)
+ * if (handler)
* {
* std::cout << "element '" << element->get_name() <<
* "' implements URIHandler interface." << std::endl;
*
+ * // Use uri handler interface methods:
+ *
* handler->set_uri("file:///tmp/media.file");
*
- * // Use uri handler interface method
* std::cout << handler->get_name() << " uri = '" << handler->get_uri() <<
* "'." << std::endl;
* }
Modified: gstreamermm/trunk/gstreamer/src/iterator.ccg
==============================================================================
--- gstreamermm/trunk/gstreamer/src/iterator.ccg (original)
+++ gstreamermm/trunk/gstreamer/src/iterator.ccg Fri Aug 8 21:31:39 2008
@@ -24,10 +24,13 @@
namespace Gst
{
-GstIterator*
-Iterator::cobj()
+ConcurrentUpdateException::ConcurrentUpdateException()
+: std::runtime_error(what())
+{}
+
+const char* ConcurrentUpdateException::what() const throw()
{
- return cobj_;
+ return "Concurrent update of iterator elements. Please resync iterator.";
}
} //namespace Gst
Modified: gstreamermm/trunk/gstreamer/src/iterator.hg
==============================================================================
--- gstreamermm/trunk/gstreamer/src/iterator.hg (original)
+++ gstreamermm/trunk/gstreamer/src/iterator.hg Fri Aug 8 21:31:39 2008
@@ -20,6 +20,7 @@
*/
#include <gst/gstiterator.h>
+#include <stdexcept>
_DEFS(gstreamermm,gst)
@@ -29,19 +30,289 @@
_WRAP_ENUM(IteratorItem, GstIteratorItem)
_WRAP_ENUM(IteratorResult, GstIteratorResult)
-class Iterator
+/** Exception thrown by Gst::IteratorBase<> increment operators when the
+ * elements are updated after element processing is underway by the iterator.
+ */
+class ConcurrentUpdateException : std::runtime_error
{
public:
+ ConcurrentUpdateException();
+ virtual const char* what() const throw();
+};
- _CLASS_GENERIC(Iterator, GstIterator)
-
- GstIterator* cobj();
- Iterator(GstIterator*);
+/** Gst::IteratorBase â Base class for classes that retrieve multiple elements
+ * in a thread safe way.
+ *
+ * Classes derived from Gst::IteratorBase are used to retrieve multiple objects
+ * from another object in a thread safe way.
+ *
+ * Various GStreamer objects provide access to their internal structures using
+ * an iterator.
+ */
+template <class CppType>
+class IteratorBase
+{
+public:
+ /** Frees the underlying C instance if a destroy value of true was used to
+ * wrap it.
+ */
+ virtual ~IteratorBase();
+
+ /** Move to the next iterator item.
+ *
+ * @return The result of the iteration. Please note that a return of
+ * Gst::ITERATOR_DONE means that the iterator is on the last item. MT safe.
+ */
+ IteratorResult next();
+
+ /** Resync the iterator. This function is mostly called after next() returns
+ * Gst::ITERATOR_RESYNC. In essence, the iterator is reset to the first item
+ * because a concurrent update of the iterator's list of element occurred
+ * while element processing was underway which means a call to this method is
+ * necessary.
+ */
+ void resync();
+
+ /** Tells if iterator is at start of list (not on first item, but just
+ * before it).
+ *
+ * @return true if iterator is at start of list, false otherwise.
+ */
+ bool is_start() const;
+
+ /** Tells if iterator is on the last element.
+ *
+ * @return true if iterator is at end of list, false otherwise.
+ */
+ bool is_last() const;
+
+ /** Tells whether the iterator is valid and can be dereferenced.
+ */
+ operator bool() const;
+
+ ///Provides access to the underlying C GObject.
+ GstIterator* cobj() { return cobject_; };
+
+ ///Provides access to the underlying C GObject.
+ const GstIterator* cobj() const { return cobject_; };
+
+protected:
+ /// Default constructor.
+ IteratorBase();
+
+ /** Copy constructor. Please note that copying and assigning merely shares
+ * the underlying C object. Operations on the copy are also performed in the
+ * underlying C object of the original and if the original is destroyed, the
+ * copy is invalid.
+ */
+ IteratorBase(const IteratorBase<CppType>&);
+
+ /** Construct an IteratorBase from an underlying C object.
+ * @param castitem The underlying C object.
+ * @param destroy Whether to destroy underlying C object along with the
+ * wrapper.
+ */
+ IteratorBase(GstIterator* castitem, bool destroy=true);
+
+ /** Assignment operator. It replaces the contents of this iterator with the
+ * contents of the new one freeing the underlying C object if a destroy value
+ * of true was used when wrapping it. Please note that copying and assigning
+ * merely shares the underlying C object. Operations on the copy are also
+ * performed in the underlying C object of the original and if the original
+ * is destroyed, the copy is invalid.
+ */
+ IteratorBase<CppType>& operator=(const IteratorBase<CppType>& other);
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+ gpointer current; // The current element the iterator is referencing.
+ IteratorResult current_result; // The current result of a next() call.
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
private:
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+ GstIterator* cobject_; // The underlying C object.
+ bool destroy; // Whether to destroy C object with the wrapper.
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
- GstIterator* cobj_;
+private:
+ void swap(IteratorBase<CppType>& other);
+};
+/** Gst::Iterator â Class that retrieve multiple elements in a thread safe way.
+ * Gst::Iterator iterates specifically through elements that are reference
+ * counted and therefore dereferencing the elements of the iterator yields a
+ * Glib::RefPtr<> to the C++ element type.
+ */
+template <class CppType>
+class Iterator : public IteratorBase<CppType>
+{
+public:
+ /** Creates a Gst::Iterator wrapper for a GstIterator object. The underlying
+ * @a castitem will be freed with the Gst::Iterator destruction.
+ *
+ * @param castitem The C instance to wrap.
+ * @param destroy Whether to destroy the underlying C object with the
+ * wrapper.
+ */
+ Iterator(GstIterator* castitem, bool destroy=true);
+
+ /** Dereference this iterator and obtain the underlying Glib::RefPtr<>.
+ */
+ Glib::RefPtr<CppType> operator*() const;
+
+ /** Prefix auto-increment operator. It advances to the next item in the
+ * iterator. It is faster than the postfix operator.
+ * @throw Gst::ConcurrentUpdateException.
+ * @throw std::runtime_error (when Gst::ITERATOR_ERROR is encountered).
+ */
+ Iterator<CppType>& operator++();
+
+ /** Postfix auto-increment operator. It advances to the next item in the
+ * iterator.
+ * @throw Gst::ConcurrentUpdateException.
+ * @throw std::runtime_error (when Gst::ITERATOR_ERROR is encountered).
+ */
+ Iterator<CppType> operator++(int);
};
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+
+/***************** Gst::IteratorBase<CppType> ************************/
+
+template<class CppType>
+IteratorResult IteratorBase<CppType>::next()
+{
+ current_result = (Gst::IteratorResult) gst_iterator_next(cobj(), ¤t);
+ return current_result;
+}
+
+template<class CppType>
+void IteratorBase<CppType>::resync()
+{
+ gst_iterator_resync(cobj());
+ current = 0;
+ current_result = Gst::ITERATOR_OK;
+}
+
+template<class CppType>
+bool IteratorBase<CppType>::is_start() const
+{
+ return (current == 0 && current_result == Gst::ITERATOR_OK);
+}
+
+template<class CppType>
+bool IteratorBase<CppType>::is_last() const
+{
+ return (current != 0 && current_result == Gst::ITERATOR_DONE);
+}
+
+template<class CppType>
+IteratorBase<CppType>::operator bool() const
+{
+ return (current != 0);
+}
+template<class CppType>
+IteratorBase<CppType>::IteratorBase()
+: cobject_(0),
+ destroy(true),
+ current(0),
+ current_result(Gst::ITERATOR_OK)
+{}
+
+template<class CppType>
+IteratorBase<CppType>::IteratorBase(const IteratorBase<CppType>& other)
+ : cobject_(const_cast<GstIterator*>(other.cobj())),
+ destroy((other.cobj()) ? false : true),
+ current(other.current),
+ current_result(other.current_result)
+{}
+
+template<class CppType>
+IteratorBase<CppType>::IteratorBase(GstIterator* castitem, bool destroy)
+: cobject_(castitem),
+ destroy(destroy),
+ current(0),
+ current_result(Gst::ITERATOR_OK)
+{}
+
+template<class CppType>
+IteratorBase<CppType>& IteratorBase<CppType>::operator=(const IteratorBase<CppType>& other)
+{
+ IteratorBase temp(other);
+ swap(temp);
+ return *this;
+}
+
+template<class CppType>
+void IteratorBase<CppType>::swap(IteratorBase<CppType>& other)
+{
+ GstIterator *const temp_obj = cobject_;
+ cobject_ = other.cobject_;
+ other.cobject_ = temp_obj;
+
+ const bool temp_destroy = destroy;
+ destroy = other.destroy;
+ other.destroy = temp_destroy;
+
+ gpointer const temp_current = current;
+ current = other.current;
+ other.current = temp_current;
+
+ const IteratorResult temp_result = current_result;
+ current_result = other.current_result;
+ other.current_result = temp_result;
+}
+
+//virtual
+template<class CppType>
+IteratorBase<CppType>::~IteratorBase()
+{
+ if (destroy && cobject_)
+ {
+ gst_iterator_free(cobject_);
+ cobject_ = 0;
+ }
+}
+
+/******************* Gst::Iterator<CppType> **************************/
+
+template <class CppType>
+Iterator<CppType>::Iterator(GstIterator* castitem, bool destroy)
+ : IteratorBase<CppType>(castitem, destroy)
+{}
+
+template <class CppType>
+Glib::RefPtr<CppType> Iterator<CppType>::operator*() const
+{
+ typedef typename CppType::BaseObjectType CType;
+
+ if (this->current)
+ return Glib::wrap((CType*)(this->current));
+ else
+ return Glib::RefPtr<CppType>(0);
+}
+
+template<class CppType>
+Iterator<CppType>& Iterator<CppType>::operator++()
+{
+ const IteratorResult result = this->next();
+
+ if (result == Gst::ITERATOR_RESYNC)
+ throw ConcurrentUpdateException();
+ else if (result == Gst::ITERATOR_ERROR)
+ throw std::runtime_error("Iterator increment error.");
+
+ return *this;
+}
+
+template<class CppType>
+Iterator<CppType> Iterator<CppType>::operator++(int)
+{
+ Iterator<CppType> original = *this;
+ ++(*this);
+ return original;
+}
+
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
+
} //namespace Gst
Modified: gstreamermm/trunk/gstreamerbase/gstreamerbasemm.h
==============================================================================
--- gstreamermm/trunk/gstreamerbase/gstreamerbasemm.h (original)
+++ gstreamermm/trunk/gstreamerbase/gstreamerbasemm.h Fri Aug 8 21:31:39 2008
@@ -5,6 +5,7 @@
#include <gstreamerbasemm/init.h>
#include <gstreamerbasemm/wrap_init.h>
+#include <gstreamerbasemm/audioclock.h>
#include <gstreamerbasemm/colorbalance.h>
#include <gstreamerbasemm/colorbalancechannel.h>
#include <gstreamerbasemm/xoverlay.h>
Modified: gstreamermm/trunk/gstreamerbase/src/audioclock.ccg
==============================================================================
--- gstreamermm/trunk/gstreamerbase/src/audioclock.ccg (original)
+++ gstreamermm/trunk/gstreamerbase/src/audioclock.ccg Fri Aug 8 21:31:39 2008
@@ -53,8 +53,7 @@
//The following lines are taken verbatim from gst_audio_clock_new() after the
//call to g_object_new() because it seems that bug #545782 will not be
- //accepted.
-
+ //accepted:
gobj()->func = &AudioClock_GetTime_gstreamermm_callback;
gobj()->user_data = &slot;
}
Modified: gstreamermm/trunk/tests/Makefile.am
==============================================================================
--- gstreamermm/trunk/tests/Makefile.am (original)
+++ gstreamermm/trunk/tests/Makefile.am Fri Aug 8 21:31:39 2008
@@ -10,7 +10,7 @@
test-structure test-caps-structures test-interface \
test-create-bus test-taglist test-tagsetter \
test-init-check test-init test-init-check-noargs \
- test-init-noargs
+ test-init-noargs test-iterator
#TODO: Add test-pad to tests when bug #539108 is fixed.
@@ -73,3 +73,6 @@
test_init_noargs_SOURCES=test-init-noargs.cc
test_init_noargs_LDFLAGS= GSTREAMERMM_LIBS@
+
+test_iterator_SOURCES=test-iterator.cc
+test_iterator_LDFLAGS= GSTREAMERMM_LIBS@
Added: gstreamermm/trunk/tests/test-iterator.cc
==============================================================================
--- (empty file)
+++ gstreamermm/trunk/tests/test-iterator.cc Fri Aug 8 21:31:39 2008
@@ -0,0 +1,71 @@
+// -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+
+/* gstreamermm - a C++ wrapper for gstreamer
+ *
+ * Copyright 2008 The gstreamermm Development Team
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <gstreamermm.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::ElementFactory::create_element("fakesrc", "source");
+ sink = Gst::ElementFactory::create_element("fakesink", "sink");
+
+ bin->add(source)->add(sink);
+
+ pipeline->add(bin);
+ source->link(sink);
+
+ std::cout << "The following elements have been added to bin '" <<
+ bin->get_name() << "'." << std::endl;
+
+ int iterations = 0;
+ Gst::Iterator<Gst::Element> elements = bin->iterate_elements();
+
+ try
+ {
+ for ( ; !elements.is_last(); ++elements)
+ {
+ if (elements)
+ std::cout << (*elements)->get_name() << std::endl;
+
+ iterations++;
+ }
+ ++elements;
+ }
+ catch (std::runtime_error& e)
+ {
+ std::cout << "Runtime error while iterating through \"" <<
+ bin->get_name() << "'s\" elements." << std::endl;
+ }
+
+ std::cout << "The loop iterated " << iterations << " to print bin '" <<
+ bin->get_name() << "' elements." << std::endl;
+
+ return 0;
+}
Modified: gstreamermm/trunk/tools/m4/convert_gst.m4
==============================================================================
--- gstreamermm/trunk/tools/m4/convert_gst.m4 (original)
+++ gstreamermm/trunk/tools/m4/convert_gst.m4 Fri Aug 8 21:31:39 2008
@@ -95,6 +95,9 @@
#IndexFactory
_CONVERSION(`GstIndexFactory*',`Glib::RefPtr<IndexFactory>',`Glib::wrap($3)')
+#
+#Iterator
+_CONVERSION(`GstIterator*',`Iterator<Element>',`Iterator<Element>::Iterator($3)')
#Message
_CONVERSION(`GstMessage*',`Glib::RefPtr<Message>',`Gst::Message::wrap($3)')
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]