[gstreamermm] Event, Message, Query: Have create() methods return derived types.



commit dda1548634dc4bbc0d9fdb8a0fdc68f3371d86c5
Author: Josà Alburquerque <jaalburqu svn gnome org>
Date:   Thu Sep 13 00:09:12 2012 -0400

    Event, Message, Query: Have create() methods return derived types.
    
    	* gstreamer/src/event.{ccg,hg}:
    	* gstreamer/src/message.{ccg,hg}:
    	* gstreamer/src/query.{ccg,hg}: Modify the create() methods of all the
    	Event, Message and Query derived classes so that the methods return
    	a reference pointer to the derived type and not to the base type.  Add
    	protected templated inline wrap() methods to the base types (Event,
    	Message and Query) which convert a derived type wrapped as a reference
    	pointer to the  base type to a reference pointer to the derived type
    	using a reference pointer dynamic cast and use the methods in the
    	derived classes create() methods for the conversions.
    
    	* tests/test-event-wrap.cc:
    	* tests/test-message-wrap.cc:
    	* tests/test-query-wrap.cc: Modify the event, message and query
    	wrapping tests to create an Event, Message and Query to ensure that
    	the new create() methods work.
    
    	Bug #683580 (kangaba yandex ru)

 ChangeLog                  |   23 +++++++
 gstreamer/src/event.ccg    |   62 +++++++++--------
 gstreamer/src/event.hg     |   45 +++++++++----
 gstreamer/src/message.ccg  |  154 +++++++++++++++++++++++++++-----------------
 gstreamer/src/message.hg   |  107 ++++++++++++++++++++++--------
 gstreamer/src/query.ccg    |   40 ++++++------
 gstreamer/src/query.hg     |   36 ++++++++---
 tests/test-event-wrap.cc   |   15 ++++
 tests/test-message-wrap.cc |    8 ++
 tests/test-query-wrap.cc   |   12 ++++
 10 files changed, 343 insertions(+), 159 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index eb5d694..978c1f3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,26 @@
+2012-09-12  Josà Alburquerque  <jaalburquerque gmail com>
+
+	Event, Message, Query: Have create() methods return derived types.
+
+	* gstreamer/src/event.{ccg,hg}:
+	* gstreamer/src/message.{ccg,hg}:
+	* gstreamer/src/query.{ccg,hg}: Modify the create() methods of all the
+	Event, Message and Query derived classes so that the methods return
+	a reference pointer to the derived type and not to the base type.  Add
+	protected templated inline wrap() methods to the base types (Event,
+	Message and Query) which convert a derived type wrapped as a reference
+	pointer to the  base type to a reference pointer to the derived type
+	using a reference pointer dynamic cast and use the methods in the
+	derived classes create() methods for the conversions.
+
+	* tests/test-event-wrap.cc:
+	* tests/test-message-wrap.cc:
+	* tests/test-query-wrap.cc: Modify the event, message and query
+	wrapping tests to create an Event, Message and Query to ensure that
+	the new create() methods work.
+
+	Bug #683580 (kangaba yandex ru)
+
 2012-09-11  Josà Alburquerque  <jaalburquerque gmail com>
 
 	MiniObject derived classes: Correct wrapper memory leak.
diff --git a/gstreamer/src/event.ccg b/gstreamer/src/event.ccg
index 5539fbf..9363424 100644
--- a/gstreamer/src/event.ccg
+++ b/gstreamer/src/event.ccg
@@ -32,7 +32,7 @@ extern "C"
 {
 
 static void Event_gstreamermm_callback_destroy(void* data,
-  GstMiniObject* where_the_object_was)
+  GstMiniObject* /* where_the_object_was */)
 {
   // This works for any of the Gst::Event derived classes because none of
   // them have member variables so in essence they are all the same size.
@@ -91,43 +91,43 @@ EventFlushStart::EventFlushStart(GstEvent* castitem) :
 Event(castitem)
 {}
 
-Glib::RefPtr<Gst::Event> EventFlushStart::create()
+Glib::RefPtr<Gst::EventFlushStart> EventFlushStart::create()
 {
   GstEvent* event = gst_event_new_flush_start();
-  return Gst::Event::wrap(event, false);
+  return Gst::Event::wrap<EventFlushStart>(event, false);
 }
 
 EventFlushStop::EventFlushStop(GstEvent* castitem) :
 Event(castitem)
 {}
 
-Glib::RefPtr<Gst::Event> EventFlushStop::create()
+Glib::RefPtr<Gst::EventFlushStop> EventFlushStop::create()
 {
   GstEvent* event = gst_event_new_flush_stop();
-  return Gst::Event::wrap(event, false);
+  return Gst::Event::wrap<EventFlushStop>(event, false);
 }
 
 EventEos::EventEos(GstEvent* castitem) :
 Event(castitem)
 {}
 
-Glib::RefPtr<Gst::Event> EventEos::create()
+Glib::RefPtr<Gst::EventEos> EventEos::create()
 {
   GstEvent* event = gst_event_new_eos();
-  return Gst::Event::wrap(event, false);
+  return Gst::Event::wrap<EventEos>(event, false);
 }
 
 EventNewSegment::EventNewSegment(GstEvent* castitem) :
 Event(castitem)
 {}
 
-Glib::RefPtr<Gst::Event> EventNewSegment::create(bool update, double rate,
-  Format format, gint64 start, gint64 stop, gint64 position,
-  double applied_rate)
+Glib::RefPtr<Gst::EventNewSegment>
+  EventNewSegment::create(bool update, double rate, Format format,
+  gint64 start, gint64 stop, gint64 position, double applied_rate)
 {
   GstEvent* event = gst_event_new_new_segment_full(update, rate, applied_rate,
     GstFormat(format), start, stop, position);
-  return Gst::Event::wrap(event, false);
+  return Gst::Event::wrap<EventNewSegment>(event, false);
 }
 
 void EventNewSegment::parse(bool& update, double& rate, Format& format,
@@ -192,12 +192,12 @@ EventTag::EventTag(GstEvent* castitem) :
 Event(castitem)
 {}
 
-Glib::RefPtr<Gst::Event> EventTag::create(const Gst::TagList& taglist)
+Glib::RefPtr<Gst::EventTag> EventTag::create(const Gst::TagList& taglist)
 {
   //We create a copy because gst_event_new_tag() takes ownership:
   GstTagList* c_taglist = gst_tag_list_copy(taglist.gobj());
   GstEvent* event = gst_event_new_tag(c_taglist);
-  return Gst::Event::wrap(event, false);
+  return Gst::Event::wrap<EventTag>(event, false);
 }
 
 Gst::TagList EventTag::parse() const
@@ -211,12 +211,13 @@ EventBufferSize::EventBufferSize(GstEvent* castitem) :
 Event(castitem)
 {}
 
-Glib::RefPtr<Gst::Event> EventBufferSize::create(Format format, gint64 minsize,
-  gint64 maxsize, bool async)
+Glib::RefPtr<Gst::EventBufferSize>
+  EventBufferSize::create(Format format, gint64 minsize, gint64 maxsize,
+  bool async)
 {
   GstEvent* event = gst_event_new_buffer_size(GstFormat(format), minsize,
     maxsize, async);
-  return Gst::Event::wrap(event, false);
+  return Gst::Event::wrap<EventBufferSize>(event, false);
 }
 
 void EventBufferSize::parse(Format& format, gint64& minsize, gint64& maxsize,
@@ -263,12 +264,12 @@ EventQos::EventQos(GstEvent* castitem) :
 Event(castitem)
 {}
 
-Glib::RefPtr<Gst::Event> EventQos::create(double proportion,
+Glib::RefPtr<Gst::EventQos> EventQos::create(double proportion,
   ClockTimeDiff diff, ClockTime timestamp)
 {
   GstEvent* event = gst_event_new_qos(proportion, GstClockTimeDiff(diff),
     GstClockTime(timestamp));
-  return Gst::Event::wrap(event, false);
+  return Gst::Event::wrap<EventQos>(event, false);
 }
 
 void EventQos::parse(double& proportion, ClockTimeDiff& diff,
@@ -303,7 +304,7 @@ EventSeek::EventSeek(GstEvent* castitem) :
 Event(castitem)
 {}
 
-Glib::RefPtr<Gst::Event> EventSeek::create(double rate, Format format,
+Glib::RefPtr<Gst::EventSeek> EventSeek::create(double rate, Format format,
   SeekFlags flags, SeekType start_type, gint64 start, SeekType stop_type,
   gint64 stop)
 {
@@ -311,7 +312,7 @@ Glib::RefPtr<Gst::Event> EventSeek::create(double rate, Format format,
     GstSeekFlags(flags), GstSeekType(start_type), start,
     GstSeekType(stop_type), stop);
 
-  return Gst::Event::wrap(event, false);
+  return Gst::Event::wrap<EventSeek>(event, false);
 }
 
 void EventSeek::parse(double& rate, Format& format, SeekFlags& flags,
@@ -382,22 +383,23 @@ EventNavigation::EventNavigation(GstEvent* castitem) :
 Event(castitem)
 {}
 
-Glib::RefPtr<Gst::Event> EventNavigation::create(Gst::Structure& structure)
+Glib::RefPtr<Gst::EventNavigation>
+  EventNavigation::create(Gst::Structure& structure)
 {
   // Make copy because event takes ownership of structure:
   GstStructure* copy = gst_structure_copy(structure.gobj());
   GstEvent* event = gst_event_new_navigation(copy);
-  return Gst::Event::wrap(event, false);
+  return Gst::Event::wrap<EventNavigation>(event, false);
 }
 
 EventLatency::EventLatency(GstEvent* castitem) :
 Event(castitem)
 {}
 
-Glib::RefPtr<Gst::Event> EventLatency::create(ClockTime time)
+Glib::RefPtr<Gst::EventLatency> EventLatency::create(ClockTime time)
 {
   GstEvent* event = gst_event_new_latency(GstClockTime(time));
-  return Gst::Event::wrap(event, false);
+  return Gst::Event::wrap<EventLatency>(event, false);
 }
 
 ClockTime EventLatency::parse() const
@@ -411,12 +413,13 @@ EventStep::EventStep(GstEvent* castitem) :
 Event(castitem)
 {}
 
-Glib::RefPtr<Gst::Event> EventStep::create(Gst::Format format, guint64 amount,
-  double rate, bool flush, bool intermediate)
+Glib::RefPtr<Gst::EventStep>
+  EventStep::create(Gst::Format format, guint64 amount, double rate,
+  bool flush, bool intermediate)
 {
   GstEvent* event = gst_event_new_step(static_cast<GstFormat>(format),
     amount, rate, flush, intermediate);
-  return Gst::Event::wrap(event, false);
+  return Gst::Event::wrap<EventStep>(event, false);
 }
 
 void EventStep::parse(Gst::Format& format, guint64& amount, double& rate,
@@ -473,10 +476,11 @@ EventSinkMessage::EventSinkMessage(GstEvent* castitem) :
 Event(castitem)
 {}
 
-Glib::RefPtr<Gst::Event> EventSinkMessage::create(const Glib::RefPtr<Gst::Message>& msg)
+Glib::RefPtr<Gst::EventSinkMessage>
+  EventSinkMessage::create(const Glib::RefPtr<Gst::Message>& msg)
 {
   GstEvent* event = gst_event_new_sink_message(msg->gobj());
-  return Gst::Event::wrap(event, false);
+  return Gst::Event::wrap<EventSinkMessage>(event, false);
 }
 
 Glib::RefPtr<Gst::Message> EventSinkMessage::parse()
diff --git a/gstreamer/src/event.hg b/gstreamer/src/event.hg
index ff0cf66..89ac1a1 100644
--- a/gstreamer/src/event.hg
+++ b/gstreamer/src/event.hg
@@ -187,6 +187,13 @@ protected:
   static void finalize_vfunc_callback(GstMiniObject* self);
   _POP()
 #m4end
+
+protected:
+  // This method is used in the create() methods to convert a wrapped GstEvent
+  // to one of the more specific Gst::Event types.
+  template <class EventType>
+    static inline Glib::RefPtr<EventType> wrap(GstEvent* event,
+    bool take_copy = false);
 };
 
 //TODO: Modify create methods of derived Event classes to return
@@ -219,7 +226,7 @@ public:
    *
    * @return A new flush start event.
    */
-  static Glib::RefPtr<Gst::Event> create();
+  static Glib::RefPtr<Gst::EventFlushStart> create();
 };
 
 /**  A flush stop event.  See create() for more details.
@@ -242,7 +249,7 @@ public:
    *
    * @return A new flush stop event.
    */
-  static Glib::RefPtr<Gst::Event> create();
+  static Glib::RefPtr<Gst::EventFlushStop> create();
 };
 
 /** An end of stream event. See create() for more details.
@@ -266,7 +273,7 @@ public:
    *
    * @return The new EOS event. 
    */
-  static Glib::RefPtr<Gst::Event> create();
+  static Glib::RefPtr<Gst::EventEos> create();
 };
 
 /** A new segment event.  See create() for more details.
@@ -316,7 +323,7 @@ public:
    *
    * Since 0.10.6
    */
-  static Glib::RefPtr<Gst::Event> create(bool update, double rate,
+  static Glib::RefPtr<Gst::EventNewSegment> create(bool update, double rate,
     Format format, gint64 strat, gint64 stop, gint64 position,
     double applied_rate = 1.0);
 
@@ -426,7 +433,7 @@ public:
    * @param taglist Metadata list.
    * @return A new Gst::Event.
    */
-  static Glib::RefPtr<Gst::Event> create(const Gst::TagList& taglist);
+  static Glib::RefPtr<Gst::EventTag> create(const Gst::TagList& taglist);
 
   /** Parses a tag event and stores the results in the given taglist location.
    * @return Metadata list.
@@ -453,8 +460,8 @@ public:
    * @param async Thread behavior.
    * @return A new Gst::EventBufferSize.
    */
-  static Glib::RefPtr<Gst::Event> create(Format format, gint64 minsize,
-    gint64 maxsize, bool async);
+  static Glib::RefPtr<Gst::EventBufferSize>
+    create(Format format, gint64 minsize, gint64 maxsize, bool async);
 
   /** Get the format, minsize, maxsize and async-flag in the buffersize event.
    *
@@ -536,7 +543,7 @@ public:
    * @param timestamp The timestamp of the buffer.
    * @return A new QOS event.
    */
-  static Glib::RefPtr<Gst::Event> create(double proportion,
+  static Glib::RefPtr<Gst::EventQos> create(double proportion,
     ClockTimeDiff diff, ClockTime timestamp);
 
   /** Get the proportion, diff and timestamp in the qos event. See create() for
@@ -617,7 +624,7 @@ public:
    * @param stop The value of the new stop position.
    * @return A new seek event.
    */
-  static Glib::RefPtr<Gst::Event> create(double rate, Format format,
+  static Glib::RefPtr<Gst::EventSeek> create(double rate, Format format,
     SeekFlags flags, SeekType start_type, gint64 start, SeekType stop_type,
     gint64 stop);
 
@@ -686,7 +693,7 @@ public:
    * @param structure Description of the event.
    * @return A new Gst::EventNavigation.
    */
-  static Glib::RefPtr<Gst::Event> create(Gst::Structure& structure);
+  static Glib::RefPtr<Gst::EventNavigation> create(Gst::Structure& structure);
 };
 
 /** A latency event.  See create() for more details.
@@ -708,7 +715,7 @@ public:
    *
    * Since 0.10.12.
    */
-  static Glib::RefPtr<Gst::Event> create(ClockTime latency);
+  static Glib::RefPtr<Gst::EventLatency> create(ClockTime latency);
 
   /** Get the latency in the latency event.
    *
@@ -748,8 +755,8 @@ public:
    *
    * Since 0.10.24.
    */
-  static Glib::RefPtr<Gst::Event> create(Gst::Format format, guint64 amount,
-    double rate, bool flush, bool intermediate);
+  static Glib::RefPtr<Gst::EventStep> create(Gst::Format format,
+    guint64 amount, double rate, bool flush, bool intermediate);
 
   /** Parse the step event.
    *
@@ -803,7 +810,8 @@ public:
    * @param msg The message to be posted.
    * @return A new Gst::EventSinkMessage.
    */
-  static Glib::RefPtr<Gst::Event> create(const Glib::RefPtr<Gst::Message>& message);
+  static Glib::RefPtr<Gst::EventSinkMessage>
+    create(const Glib::RefPtr<Gst::Message>& message);
 
   /** Parse the sink-message event.
    * @return the sink-messge's event message.
@@ -817,4 +825,13 @@ public:
   Glib::RefPtr<const Gst::Message> parse() const;
 };
 
+/****************************** Gst::Event **************************/
+
+template <class EventType>
+  Glib::RefPtr<EventType> Event::wrap(GstEvent* event, bool take_copy)
+{
+  Glib::RefPtr<Gst::Event> result = wrap(event, take_copy);
+  return Glib::RefPtr<EventType>::cast_dynamic(result);
+}
+
 } //namespace Gst
diff --git a/gstreamer/src/message.ccg b/gstreamer/src/message.ccg
index 706403c..486fba6 100644
--- a/gstreamer/src/message.ccg
+++ b/gstreamer/src/message.ccg
@@ -72,21 +72,24 @@ MessageEos::MessageEos(GstMessage* castitem)
 : Message(castitem)
 {}
 
-Glib::RefPtr<Gst::Message> MessageEos::create(const Glib::RefPtr<Gst::Object>& src)
+Glib::RefPtr<Gst::MessageEos>
+  MessageEos::create(const Glib::RefPtr<Gst::Object>& src)
 {
   GstMessage* message = gst_message_new_eos(Glib::unwrap(src));
-  return Gst::Message::wrap(message, false);
+  return Gst::Message::wrap<MessageEos>(message, false);
 }
 
 MessageError::MessageError(GstMessage* castitem)
 : Message(castitem)
 {}
 
-Glib::RefPtr<Gst::Message> MessageError::create(const Glib::RefPtr<Gst::Object>& src, Glib::Error& error, const std::string& debug)
+Glib::RefPtr<Gst::MessageError>
+  MessageError::create(const Glib::RefPtr<Gst::Object>& src,
+  Glib::Error& error, const std::string& debug)
 {
   GstMessage* message = gst_message_new_error(Glib::unwrap(src), error.gobj(),
     reinterpret_cast<const gchar*>(debug.c_str()));
-  return Gst::Message::wrap(message, false);
+  return Gst::Message::wrap<MessageError>(message, false);
 }
 
 void MessageError::parse(Glib::Error& error, std::string& debug) const
@@ -132,11 +135,13 @@ MessageWarning::MessageWarning(GstMessage* castitem)
 : Message(castitem)
 {}
 
-Glib::RefPtr<Gst::Message> MessageWarning::create(const Glib::RefPtr<Gst::Object>& src, Glib::Error& error, const std::string& debug)
+Glib::RefPtr<Gst::MessageWarning>
+  MessageWarning::create(const Glib::RefPtr<Gst::Object>& src,
+  Glib::Error& error, const std::string& debug)
 {
   GstMessage* message = gst_message_new_warning(Glib::unwrap(src),
     error.gobj(), reinterpret_cast<const gchar*>(debug.c_str()));
-  return Gst::Message::wrap(message, false);
+  return Gst::Message::wrap<MessageWarning>(message, false);
 }
 
 void MessageWarning::parse(Glib::Error& error, std::string& debug) const
@@ -183,11 +188,13 @@ MessageInfo::MessageInfo(GstMessage* castitem)
 : Message(castitem)
 {}
 
-Glib::RefPtr<Gst::Message> MessageInfo::create(const Glib::RefPtr<Gst::Object>& src, Glib::Error& error, const std::string& debug)
+Glib::RefPtr<Gst::MessageInfo>
+  MessageInfo::create(const Glib::RefPtr<Gst::Object>& src,
+  Glib::Error& error, const std::string& debug)
 {
   GstMessage* message = gst_message_new_info(Glib::unwrap(src), error.gobj(),
     reinterpret_cast<const gchar*>(debug.c_str()));
-  return Gst::Message::wrap(message, false);
+  return Gst::Message::wrap<MessageInfo>(message, false);
 }
 
 
@@ -234,17 +241,17 @@ MessageTag::MessageTag(GstMessage* castitem)
 : Message(castitem)
 {}
 
-Glib::RefPtr<Gst::Message>
+Glib::RefPtr<Gst::MessageTag>
   MessageTag::create(const Glib::RefPtr<Gst::Object>& src,
   const Gst::TagList& taglist)
 {
   //We create a copy because gst_message_new_tag() takes ownership:
   GstTagList* c_taglist = gst_tag_list_copy(taglist.gobj());
   GstMessage* message = gst_message_new_tag(Glib::unwrap(src), c_taglist);
-  return Gst::Message::wrap(message, false);
+  return Gst::Message::wrap<MessageTag>(message, false);
 }
 
-Glib::RefPtr<Gst::Message>
+Glib::RefPtr<Gst::MessageTag>
   MessageTag::create(const Glib::RefPtr<Gst::Object>& src,
   const Glib::RefPtr<Gst::Pad>& pad, const Gst::TagList& taglist)
 {
@@ -252,7 +259,7 @@ Glib::RefPtr<Gst::Message>
   GstTagList* c_taglist = gst_tag_list_copy(taglist.gobj());
   GstMessage* message = gst_message_new_tag_full(Glib::unwrap(src),
     Glib::unwrap(pad), c_taglist);
-  return Gst::Message::wrap(message, false);
+  return Gst::Message::wrap<MessageTag>(message, false);
 }
 
 void MessageTag::parse(Glib::RefPtr<Gst::Pad>& pad, Gst::TagList& tag_list)
@@ -288,10 +295,11 @@ MessageBuffering::MessageBuffering(GstMessage* castitem)
 : Message(castitem)
 {}
 
-Glib::RefPtr<Gst::Message> MessageBuffering::create(const Glib::RefPtr<Gst::Object>& src, int percent)
+Glib::RefPtr<Gst::MessageBuffering>
+  MessageBuffering::create(const Glib::RefPtr<Gst::Object>& src, int percent)
 {
   GstMessage* message = gst_message_new_buffering(Glib::unwrap(src), percent);
-  return Gst::Message::wrap(message, false);
+  return Gst::Message::wrap<MessageBuffering>(message, false);
 }
 
 int MessageBuffering::parse() const
@@ -356,12 +364,14 @@ MessageStateChanged::MessageStateChanged(GstMessage* castitem)
 : Message(castitem)
 {}
 
-Glib::RefPtr<Gst::Message> MessageStateChanged::create(const Glib::RefPtr<Gst::Object>& src, State oldstate, State newstate, State pending)
+Glib::RefPtr<Gst::MessageStateChanged>
+  MessageStateChanged::create(const Glib::RefPtr<Gst::Object>& src,
+  State oldstate, State newstate, State pending)
 {
   GstMessage* message = gst_message_new_state_changed(Glib::unwrap(src),
     static_cast<GstState>(oldstate), static_cast<GstState>(newstate),
     static_cast<GstState>(pending));
-  return Gst::Message::wrap(message, false);
+  return Gst::Message::wrap<MessageStateChanged>(message, false);
 }
 
 void MessageStateChanged::parse(State& oldstate, State& newstate,
@@ -403,18 +413,18 @@ MessageStateDirty::MessageStateDirty(GstMessage* castitem)
 : Message(castitem)
 {}
 
-Glib::RefPtr<Gst::Message>
+Glib::RefPtr<Gst::MessageStateDirty>
   MessageStateDirty::create(const Glib::RefPtr<Gst::Object>& src)
 {
   GstMessage* message = gst_message_new_state_dirty(Glib::unwrap(src));
-  return Gst::Message::wrap(message, false);
+  return Gst::Message::wrap<MessageStateDirty>(message, false);
 }
 
 MessageStepDone::MessageStepDone(GstMessage* castitem)
 : Message(castitem)
 {}
 
-Glib::RefPtr<Gst::Message>
+Glib::RefPtr<Gst::MessageStepDone>
   MessageStepDone::create(const Glib::RefPtr<Gst::Object>& src,
   Gst::Format format, guint64 amount, double rate, bool flush,
   bool intermediate, guint64 duration, bool eos)
@@ -422,7 +432,7 @@ Glib::RefPtr<Gst::Message>
   GstMessage* message = gst_message_new_step_done(Glib::unwrap(src),
     static_cast<GstFormat>(format), amount, rate, flush, intermediate,
     duration, eos);
-  return Gst::Message::wrap(message, false);
+  return Gst::Message::wrap<MessageStepDone>(message, false);
 }
 
 void MessageStepDone::parse(Gst::Format& format, guint64& amount, double& rate,
@@ -502,11 +512,13 @@ MessageClockProvide::MessageClockProvide(GstMessage* castitem)
 : Message(castitem)
 {}
 
-Glib::RefPtr<Gst::Message> MessageClockProvide::create(const Glib::RefPtr<Gst::Object>& src, const Glib::RefPtr<Gst::Clock>& clock, bool ready)
+Glib::RefPtr<Gst::MessageClockProvide>
+  MessageClockProvide::create(const Glib::RefPtr<Gst::Object>& src,
+  const Glib::RefPtr<Gst::Clock>& clock, bool ready)
 {
   GstMessage* message = gst_message_new_clock_provide(Glib::unwrap(src),
     Glib::unwrap(clock), ready);
-  return Gst::Message::wrap(message, false);
+  return Gst::Message::wrap<MessageClockProvide>(message, false);
 }
 
 void MessageClockProvide::parse(Glib::RefPtr<Gst::Clock>& clock, bool& ready) const
@@ -543,11 +555,13 @@ MessageClockLost::MessageClockLost(GstMessage* castitem)
 : Message(castitem)
 {}
 
-Glib::RefPtr<Gst::Message> MessageClockLost::create(const Glib::RefPtr<Gst::Object>& src, const Glib::RefPtr<Gst::Clock>& clock)
+Glib::RefPtr<Gst::MessageClockLost>
+  MessageClockLost::create(const Glib::RefPtr<Gst::Object>& src,
+  const Glib::RefPtr<Gst::Clock>& clock)
 {
   GstMessage* message = gst_message_new_clock_lost(Glib::unwrap(src),
     Glib::unwrap(clock));
-  return Gst::Message::wrap(message, false);
+  return Gst::Message::wrap<MessageClockLost>(message, false);
 }
 
 Glib::RefPtr<Gst::Clock> MessageClockLost::parse()
@@ -566,11 +580,13 @@ MessageNewClock::MessageNewClock(GstMessage* castitem)
 : Message(castitem)
 {}
 
-Glib::RefPtr<Gst::Message> MessageNewClock::create(const Glib::RefPtr<Gst::Object>& src, const Glib::RefPtr<Gst::Clock>& clock)
+Glib::RefPtr<Gst::MessageNewClock>
+  MessageNewClock::create(const Glib::RefPtr<Gst::Object>& src,
+  const Glib::RefPtr<Gst::Clock>& clock)
 {
   GstMessage* message = gst_message_new_new_clock(Glib::unwrap(src),
     Glib::unwrap(clock));
-  return Gst::Message::wrap(message, false);
+  return Gst::Message::wrap<MessageNewClock>(message, false);
 }
 
 Glib::RefPtr<Gst::Clock> MessageNewClock::parse()
@@ -589,66 +605,77 @@ MessageApplication::MessageApplication(GstMessage* castitem)
 : Message(castitem)
 {}
 
-Glib::RefPtr<Gst::Message> MessageApplication::create(const Glib::RefPtr<Gst::Object>& src, Gst::Structure& structure)
+Glib::RefPtr<Gst::MessageApplication>
+  MessageApplication::create(const Glib::RefPtr<Gst::Object>& src,
+  Gst::Structure& structure)
 {
   GstStructure* copy_struct = gst_structure_copy(structure.gobj());
   GstMessage* message = gst_message_new_application(Glib::unwrap(src),
     copy_struct);
-  return Gst::Message::wrap(message, false);
+  return Gst::Message::wrap<MessageApplication>(message, false);
 }
 
-Glib::RefPtr<Gst::Message> MessageApplication::create(const Glib::RefPtr<Gst::Object>& src)
+Glib::RefPtr<Gst::MessageApplication>
+  MessageApplication::create(const Glib::RefPtr<Gst::Object>& src)
 {
   GstMessage* message = gst_message_new_application(Glib::unwrap(src), 0);
-  return Gst::Message::wrap(message, false);
+  return Gst::Message::wrap<MessageApplication>(message, false);
 }
 
 MessageElement::MessageElement(GstMessage* castitem)
 : Message(castitem)
 {}
 
-Glib::RefPtr<Gst::Message> MessageElement::create(const Glib::RefPtr<Gst::Object>& src, Gst::Structure& structure)
+Glib::RefPtr<Gst::MessageElement>
+  MessageElement::create(const Glib::RefPtr<Gst::Object>& src,
+  Gst::Structure& structure)
 {
   GstStructure* copy_struct = gst_structure_copy(structure.gobj());
   GstMessage* message = gst_message_new_element(Glib::unwrap(src),
     copy_struct);
-  return Gst::Message::wrap(message, false);
+  return Gst::Message::wrap<MessageElement>(message, false);
 }
 
-Glib::RefPtr<Gst::Message> MessageElement::create(const Glib::RefPtr<Gst::Object>& src)
+Glib::RefPtr<Gst::MessageElement>
+  MessageElement::create(const Glib::RefPtr<Gst::Object>& src)
 {
   GstMessage* message = gst_message_new_element(Glib::unwrap(src), 0);
-  return Gst::Message::wrap(message, false);
+  return Gst::Message::wrap<MessageElement>(message, false);
 }
 
 MessageCustom::MessageCustom(GstMessage* castitem)
 : Message(castitem)
 {}
 
-Glib::RefPtr<Gst::Message> MessageCustom::create(MessageType type, const Glib::RefPtr<Gst::Object>& src, Gst::Structure& structure)
+Glib::RefPtr<Gst::MessageCustom>
+  MessageCustom::create(MessageType type, const Glib::RefPtr<Gst::Object>& src,
+  Gst::Structure& structure)
 {
   GstStructure* copy_struct = gst_structure_copy(structure.gobj());
   GstMessage* message = gst_message_new_custom(GstMessageType(type),
     Glib::unwrap(src), copy_struct);
-  return Gst::Message::wrap(message, false);
+  return Gst::Message::wrap<MessageCustom>(message, false);
 }
 
-Glib::RefPtr<Gst::Message> MessageCustom::create(MessageType type, const Glib::RefPtr<Gst::Object>& src)
+Glib::RefPtr<Gst::MessageCustom>
+  MessageCustom::create(MessageType type, const Glib::RefPtr<Gst::Object>& src)
 {
   GstMessage* message = gst_message_new_custom(GstMessageType(type),
     Glib::unwrap(src), 0);
-  return Gst::Message::wrap(message, false);
+  return Gst::Message::wrap<MessageCustom>(message, false);
 }
 
 MessageSegmentStart::MessageSegmentStart(GstMessage* castitem)
 : Message(castitem)
 {}
 
-Glib::RefPtr<Gst::Message> MessageSegmentStart::create(const Glib::RefPtr<Gst::Object>& src, Format format, gint64 position)
+Glib::RefPtr<Gst::MessageSegmentStart>
+  MessageSegmentStart::create(const Glib::RefPtr<Gst::Object>& src,
+  Format format, gint64 position)
 {
   GstMessage* message = gst_message_new_segment_start(Glib::unwrap(src),
     static_cast<GstFormat>(format), position);
-  return Gst::Message::wrap(message, false);
+  return Gst::Message::wrap<MessageSegmentStart>(message, false);
 }
 
 void MessageSegmentStart::parse(Format& format, gint64& position) const
@@ -677,11 +704,13 @@ MessageSegmentDone::MessageSegmentDone(GstMessage* castitem)
 : Message(castitem)
 {}
 
-Glib::RefPtr<Gst::Message> MessageSegmentDone::create(const Glib::RefPtr<Gst::Object>& src, Format format, gint64 position)
+Glib::RefPtr<Gst::MessageSegmentDone>
+  MessageSegmentDone::create(const Glib::RefPtr<Gst::Object>& src,
+  Format format, gint64 position)
 {
   GstMessage* message = gst_message_new_segment_done(Glib::unwrap(src),
     static_cast<GstFormat>(format), position);
-  return Gst::Message::wrap(message, false);
+  return Gst::Message::wrap<MessageSegmentDone>(message, false);
 }
 
 void MessageSegmentDone::parse(Format& format, gint64& position) const
@@ -710,11 +739,13 @@ MessageDuration::MessageDuration(GstMessage* castitem)
 : Message(castitem)
 {}
 
-Glib::RefPtr<Gst::Message> MessageDuration::create(const Glib::RefPtr<Gst::Object>& src, Format format, gint64 duration)
+Glib::RefPtr<Gst::MessageDuration>
+  MessageDuration::create(const Glib::RefPtr<Gst::Object>& src, Format format,
+  gint64 duration)
 {
   GstMessage* message = gst_message_new_duration(Glib::unwrap(src),
     static_cast<GstFormat>(format), duration);
-  return Gst::Message::wrap(message, false);
+  return Gst::Message::wrap<MessageDuration>(message, false);
 }
 
 void MessageDuration::parse(Format& format, gint64& duration) const
@@ -742,21 +773,24 @@ MessageLatency::MessageLatency(GstMessage* castitem)
 : Message(castitem)
 {}
 
-Glib::RefPtr<Gst::Message> MessageLatency::create(const Glib::RefPtr<Gst::Object>& src)
+Glib::RefPtr<Gst::MessageLatency>
+  MessageLatency::create(const Glib::RefPtr<Gst::Object>& src)
 {
   GstMessage* message = gst_message_new_latency(Glib::unwrap(src));
-  return Gst::Message::wrap(message, false);
+  return Gst::Message::wrap<MessageLatency>(message, false);
 }
 
 MessageAsyncStart::MessageAsyncStart(GstMessage* castitem)
 : Message(castitem)
 {}
 
-Glib::RefPtr<Gst::Message> MessageAsyncStart::create(const Glib::RefPtr<Gst::Object>& src, bool new_base_time)
+Glib::RefPtr<Gst::MessageAsyncStart>
+  MessageAsyncStart::create(const Glib::RefPtr<Gst::Object>& src,
+  bool new_base_time)
 {
   GstMessage* message = gst_message_new_async_start(Glib::unwrap(src),
     new_base_time);
-  return Gst::Message::wrap(message, false);
+  return Gst::Message::wrap<MessageAsyncStart>(message, false);
 }
 
 bool MessageAsyncStart::parse() const
@@ -771,24 +805,25 @@ MessageAsyncDone::MessageAsyncDone(GstMessage* castitem)
 : Message(castitem)
 {}
 
-Glib::RefPtr<Gst::Message> MessageAsyncDone::create(const Glib::RefPtr<Gst::Object>& src)
+Glib::RefPtr<Gst::MessageAsyncDone>
+  MessageAsyncDone::create(const Glib::RefPtr<Gst::Object>& src)
 {
   GstMessage* message = gst_message_new_async_done(Glib::unwrap(src));
-  return Gst::Message::wrap(message, false);
+  return Gst::Message::wrap<MessageAsyncDone>(message, false);
 }
 
 MessageStepStart::MessageStepStart(GstMessage* castitem)
 : Message(castitem)
 {}
 
-Glib::RefPtr<Gst::Message>
+Glib::RefPtr<Gst::MessageStepStart>
   MessageStepStart::create(const Glib::RefPtr<Gst::Object>& src,
   bool active, Gst::Format format, guint64 amount, double rate, bool flush,
   bool intermediate)
 {
   GstMessage* message = gst_message_new_step_start(Glib::unwrap(src),
     active, static_cast<GstFormat>(format), amount, rate, flush, intermediate);
-  return Gst::Message::wrap(message, false);
+  return Gst::Message::wrap<MessageStepStart>(message, false);
 }
 
 void MessageStepStart::parse(bool& active, Gst::Format& format,
@@ -859,14 +894,14 @@ MessageStructureChange::MessageStructureChange(GstMessage* castitem)
 : Message(castitem)
 {}
 
-Glib::RefPtr<Gst::Message>
+Glib::RefPtr<Gst::MessageStructureChange>
   MessageStructureChange::create(const Glib::RefPtr<Gst::Object>& src,
   Gst::StructureChangeType type, const Glib::RefPtr<Gst::Element>& owner,
   bool busy)
 {
   GstMessage* message = gst_message_new_structure_change(Glib::unwrap(src),
     static_cast<GstStructureChangeType>(type), Glib::unwrap(owner), busy);
-  return Gst::Message::wrap(message, false);
+  return Gst::Message::wrap<MessageStructureChange>(message, false);
 }
 
 void MessageStructureChange::parse(Gst::StructureChangeType& type,
@@ -908,13 +943,13 @@ MessageRequestState::MessageRequestState(GstMessage* castitem)
 : Message(castitem)
 {}
 
-Glib::RefPtr<Gst::Message>
+Glib::RefPtr<Gst::MessageRequestState>
   MessageRequestState::create(const Glib::RefPtr<Gst::Object>& src,
   Gst::State state)
 {
   GstMessage* message = gst_message_new_request_state(Glib::unwrap(src),
     static_cast<GstState>(state));
-  return Gst::Message::wrap(message, false);
+  return Gst::Message::wrap<MessageRequestState>(message, false);
 }
 
 Gst::State MessageRequestState::parse() const
@@ -929,13 +964,13 @@ MessageStreamStatus::MessageStreamStatus(GstMessage* castitem)
 : Message(castitem)
 {}
 
-Glib::RefPtr<Gst::Message>
+Glib::RefPtr<Gst::MessageStreamStatus>
   MessageStreamStatus::create(const Glib::RefPtr<Gst::Object>& src,
   Gst::StreamStatusType type, const Glib::RefPtr<Gst::Element>& owner)
 {
   GstMessage* message = gst_message_new_stream_status(Glib::unwrap(src),
     static_cast<GstStreamStatusType>(type), Glib::unwrap(owner));
-  return Gst::Message::wrap(message, false);
+  return Gst::Message::wrap<MessageStreamStatus>(message, false);
 }
 
 void MessageStreamStatus::set_object(const Glib::RefPtr<Gst::Object>& object)
@@ -1106,7 +1141,8 @@ Glib::RefPtr<Gst::Message> Message::wrap(GstMessage* message, bool take_copy)
   result = Glib::RefPtr<Gst::Message>(wrapper);
 
   // Ensure that the wrapper is freed when the message (mini object) is freed.
-  gst_mini_object_weak_ref(GST_MINI_OBJECT(message), &Message_gstreamermm_callback_destroy, wrapper);
+  gst_mini_object_weak_ref(GST_MINI_OBJECT(message),
+    &Message_gstreamermm_callback_destroy, wrapper);
 
   if(take_copy)
     result->reference();
diff --git a/gstreamer/src/message.hg b/gstreamer/src/message.hg
index 9253c6d..b4a1bac 100644
--- a/gstreamer/src/message.hg
+++ b/gstreamer/src/message.hg
@@ -129,6 +129,13 @@ protected:
   static void finalize_vfunc_callback(GstMiniObject* self);
   _POP()
 #m4end
+
+protected:
+  // This method is used in the create() methods to convert a wrapped
+  // GstMessage to one of the more specific Gst::Message types.
+  template <class MessageType>
+    static inline Glib::RefPtr<MessageType> wrap(GstMessage* message,
+    bool take_copy = false);
 };
 
 //TODO: Modify create methods of derived Message classes to return
@@ -152,7 +159,8 @@ public:
    * @param src The object originating the message.
    * @return The new eos message. MT safe. 
    */
-  static Glib::RefPtr<Gst::Message> create(const Glib::RefPtr<Gst::Object>& src);
+  static Glib::RefPtr<Gst::MessageEos>
+    create(const Glib::RefPtr<Gst::Object>& src);
 };
 
 /** An error message.
@@ -173,7 +181,9 @@ public:
    * @param debug A debugging string for something or other.
    * @return The new error message. MT safe. 
    */
-  static Glib::RefPtr<Gst::Message> create(const Glib::RefPtr<Gst::Object>& src, Glib::Error& error, const std::string& debug);
+  static Glib::RefPtr<Gst::MessageError>
+    create(const Glib::RefPtr<Gst::Object>& src,
+    Glib::Error& error, const std::string& debug);
 
   /** Extracts the Glib::Error and debug string from the Gst::MessageError.
    *
@@ -218,7 +228,9 @@ public:
    * @param debug A debugging string for something or other.
    * @return The new warning message. MT safe. 
    */
-  static Glib::RefPtr<Gst::Message> create(const Glib::RefPtr<Gst::Object>& src, Glib::Error& error, const std::string& debug);
+  static Glib::RefPtr<Gst::MessageWarning>
+    create(const Glib::RefPtr<Gst::Object>& src, Glib::Error& error,
+    const std::string& debug);
 
   /** Extracts the Glib::Error and debug string from the Gst::MessageWarning.
    *
@@ -264,7 +276,9 @@ public:
    *
    * Since 0.10.12 MT safe.
    */
-  static Glib::RefPtr<Gst::Message> create(const Glib::RefPtr<Gst::Object>& src, Glib::Error& error, const std::string& debug);
+  static Glib::RefPtr<Gst::MessageInfo>
+    create(const Glib::RefPtr<Gst::Object>& src,
+    Glib::Error& error, const std::string& debug);
 
   /** Extracts the Glib::Error and debug string from the Gst::MessageInfo.
    *
@@ -308,7 +322,7 @@ public:
    * @param tag_list The tag list for the message.
    * @return The new tag message. MT safe.
    */
-  static Glib::RefPtr<Gst::Message>
+  static Glib::RefPtr<Gst::MessageTag>
     create(const Glib::RefPtr<Gst::Object>& src, const Gst::TagList& taglist);
 
   /** Create a new tag message. The taglist will be copied.  The message is
@@ -321,7 +335,7 @@ public:
    * 
    * Since 0.10.24.
    */
-  static Glib::RefPtr<Gst::Message>
+  static Glib::RefPtr<Gst::MessageTag>
     create(const Glib::RefPtr<Gst::Object>& src,
     const Glib::RefPtr<Gst::Pad>& pad, const Gst::TagList& taglist);
 
@@ -383,7 +397,8 @@ public:
    *
    * Since 0.10.11 MT safe.
    */
-  static Glib::RefPtr<Gst::Message> create(const Glib::RefPtr<Gst::Object>& src, int percent);
+  static Glib::RefPtr<Gst::MessageBuffering>
+    create(const Glib::RefPtr<Gst::Object>& src, int percent);
 
   /** Extracts and returns the buffering percent from the
    * Gst::MessageBuffering.
@@ -459,7 +474,9 @@ public:
    * @param pending The pending (target) state.
    * @return The new state change message. MT safe.
    */
-  static Glib::RefPtr<Gst::Message> create(const Glib::RefPtr<Gst::Object>& src, State oldstate, State newstate, State pending);
+  static Glib::RefPtr<Gst::MessageStateChanged>
+    create(const Glib::RefPtr<Gst::Object>& src, State oldstate,
+    State newstate, State pending);
 
   /** Extracts the old, new and pending states from the
    * Gst::MessageStateChanged.
@@ -513,7 +530,8 @@ public:
    * @param src The object originating the message.
    * @return The new state dirty message. MT safe.
    */
-  static Glib::RefPtr<Gst::Message> create(const Glib::RefPtr<Gst::Object>& src);
+  static Glib::RefPtr<Gst::MessageStateDirty>
+    create(const Glib::RefPtr<Gst::Object>& src);
 };
 
 /** A step done message.
@@ -543,7 +561,7 @@ public:
    *
    * Since 0.10.24.
    */
-  static Glib::RefPtr<Gst::Message>
+  static Glib::RefPtr<Gst::MessageStepDone>
     create(const Glib::RefPtr<Gst::Object>& src, Gst::Format format,
     guint64 amount, double rate, bool flush, bool intermediate,
     guint64 duration, bool eos);
@@ -621,7 +639,9 @@ public:
    * @param ready true if the sender can provide a clock.
    * @return The new provide clock message. MT safe.
    */
-  static Glib::RefPtr<Gst::Message> create(const Glib::RefPtr<Gst::Object>& src, const Glib::RefPtr<Gst::Clock>& clock, bool ready);
+  static Glib::RefPtr<Gst::MessageClockProvide>
+    create(const Glib::RefPtr<Gst::Object>& src,
+    const Glib::RefPtr<Gst::Clock>& clock, bool ready);
 
   /** Extracts the clock and ready flag from the Gst::MessageClockProvide. The
    * clock object returned remains valid until the message is freed.
@@ -678,7 +698,9 @@ public:
    * @param clock The clock that was lost.
    * @return The new clock lost message. MT safe. 
    */
-  static Glib::RefPtr<Gst::Message> create(const Glib::RefPtr<Gst::Object>& src, const Glib::RefPtr<Gst::Clock>& clock);
+  static Glib::RefPtr<Gst::MessageClockLost>
+    create(const Glib::RefPtr<Gst::Object>& src,
+    const Glib::RefPtr<Gst::Clock>& clock);
 
   /** Extracts and returns the lost clock from the Gst::MessageClockLost. The
    * clock object returned remains valid until the message is freed.
@@ -713,7 +735,9 @@ public:
    * @param clock The new selected clock.
    * @return The new new clock message. MT safe.
    */
-  static Glib::RefPtr<Gst::Message> create(const Glib::RefPtr<Gst::Object>& src, const Glib::RefPtr<Gst::Clock>& clock);
+  static Glib::RefPtr<Gst::MessageNewClock>
+    create(const Glib::RefPtr<Gst::Object>& src,
+    const Glib::RefPtr<Gst::Clock>& clock);
 
   /** Extracts and returns the new clock from the Gst::MessageNewClock. The
    * clock object returned remains valid until the message is freed.
@@ -751,7 +775,8 @@ public:
    * copied.
    * @return The new application message. MT safe.
    */
-  static Glib::RefPtr<Gst::Message> create(const Glib::RefPtr<Gst::Object>& src, Gst::Structure& structure);
+  static Glib::RefPtr<Gst::MessageApplication>
+    create(const Glib::RefPtr<Gst::Object>& src, Gst::Structure& structure);
 
   /** Create a new application-typed message (no Gst::Structure is needed).
    * GStreamer will never create these messages; they are a gift from us to
@@ -760,7 +785,8 @@ public:
    * @param src The object originating the message.
    * @return The new application message. MT safe.
    */
-  static Glib::RefPtr<Gst::Message> create(const Glib::RefPtr<Gst::Object>& src);
+  static Glib::RefPtr<Gst::MessageApplication>
+    create(const Glib::RefPtr<Gst::Object>& src);
 };
 
 /** An element specific message.
@@ -781,7 +807,8 @@ public:
    * copy of the structure.
    * @return The new element message. MT safe.
    */
-  static Glib::RefPtr<Gst::Message> create(const Glib::RefPtr<Gst::Object>& src, Gst::Structure& structure);
+  static Glib::RefPtr<Gst::MessageElement>
+    create(const Glib::RefPtr<Gst::Object>& src, Gst::Structure& structure);
 
   /** Create a new element-specific message. This is meant as a generic way of
    * allowing one-way communication from an element to an application, for
@@ -792,7 +819,8 @@ public:
    * @param src The object originating the message.
    * @return The new element message. MT safe.
    */
-  static Glib::RefPtr<Gst::Message> create(const Glib::RefPtr<Gst::Object>& src);
+  static Glib::RefPtr<Gst::MessageElement>
+    create(const Glib::RefPtr<Gst::Object>& src);
 };
 
 /** A custom message.
@@ -812,7 +840,9 @@ public:
    * a copy of the structure.
    * @return The new message. MT safe.
    */
-  static Glib::RefPtr<Gst::Message> create(MessageType type, const Glib::RefPtr<Gst::Object>& src, Gst::Structure& structure);
+  static Glib::RefPtr<Gst::MessageCustom>
+    create(MessageType type, const Glib::RefPtr<Gst::Object>& src,
+    Gst::Structure& structure);
 
   /** Create a new custom-typed message. This can be used for anything not
    * handled by other message-specific functions to pass a message to the app.
@@ -822,7 +852,8 @@ public:
    * @param src The object originating the message.
    * @return The new message. MT safe.
    */
-  static Glib::RefPtr<Gst::Message> create(MessageType type, const Glib::RefPtr<Gst::Object>& src);
+  static Glib::RefPtr<Gst::MessageCustom>
+    create(MessageType type, const Glib::RefPtr<Gst::Object>& src);
 };
 
 /** A segment start message.
@@ -843,7 +874,9 @@ public:
    * @param position The position of the segment being played.
    * @return The new segment start message. MT safe.
    */
-  static Glib::RefPtr<Gst::Message> create(const Glib::RefPtr<Gst::Object>& src, Format format, gint64 position);
+  static Glib::RefPtr<Gst::MessageSegmentStart>
+    create(const Glib::RefPtr<Gst::Object>& src, Format format,
+    gint64 position);
 
   /** Extracts the position and format from the segment start message.
    *
@@ -890,7 +923,9 @@ public:
    * @param position The position of the segment being done.
    * @return The new segment done message. MT safe.
    */
-  static Glib::RefPtr<Gst::Message> create(const Glib::RefPtr<Gst::Object>& src, Format format, gint64 position);
+  static Glib::RefPtr<Gst::MessageSegmentDone>
+    create(const Glib::RefPtr<Gst::Object>& src, Format format,
+    gint64 position);
 
   /** Extracts the position and format from the segment done message.
    *
@@ -940,7 +975,9 @@ public:
    * @param duration The new duration.  
    * @return The new duration message. MT safe.
    */
-  static Glib::RefPtr<Gst::Message> create(const Glib::RefPtr<Gst::Object>& src, Format format, gint64 duration);
+  static Glib::RefPtr<Gst::MessageDuration>
+    create(const Glib::RefPtr<Gst::Object>& src, Format format,
+    gint64 duration);
 
   /** Extracts the duration and format from the duration message. The duration
    * might be Gst::CLOCK_TIME_NONE, which indicates that the duration has
@@ -993,7 +1030,8 @@ public:
    *
    * Since 0.10.12.
    */
-  static Glib::RefPtr<Gst::Message> create(const Glib::RefPtr<Gst::Object>& src);
+  static Glib::RefPtr<Gst::MessageLatency>
+    create(const Glib::RefPtr<Gst::Object>& src);
 };
 
 /** An asynchronous start message.
@@ -1014,7 +1052,8 @@ public:
    *
    * Since 0.10.13 
    */
-  static Glib::RefPtr<Gst::Message> create(const Glib::RefPtr<Gst::Object>& src, bool new_base_time);
+  static Glib::RefPtr<Gst::MessageAsyncStart>
+    create(const Glib::RefPtr<Gst::Object>& src, bool new_base_time);
 
   /** Extract and return the boolean new_base_time from the async_start
    * message.
@@ -1043,7 +1082,8 @@ public:
    * @param src The object originating the message.  
    * @return The new async_done message. MT safe.
    */
-  static Glib::RefPtr<Gst::Message> create(const Glib::RefPtr<Gst::Object>& src);
+  static Glib::RefPtr<Gst::MessageAsyncDone>
+    create(const Glib::RefPtr<Gst::Object>& src);
 };
 
 /** A step start message.
@@ -1076,7 +1116,7 @@ public:
    *
    * Since 0.10.24.
    */
-  static Glib::RefPtr<Gst::Message>
+  static Glib::RefPtr<Gst::MessageStepStart>
     create(const Glib::RefPtr<Gst::Object>& src, bool active,
     Gst::Format format, guint64 amount, double rate, bool flush,
     bool intermediate);
@@ -1151,7 +1191,7 @@ public:
    *
    * Since 0.10.22.
    */
-  static Glib::RefPtr<Gst::Message>
+  static Glib::RefPtr<Gst::MessageStructureChange>
     create(const Glib::RefPtr<Gst::Object>& src,
     Gst::StructureChangeType type, const Glib::RefPtr<Gst::Element>& owner,
     bool busy);
@@ -1216,7 +1256,7 @@ public:
    *
    * Since 0.10.23.
    */
-  static Glib::RefPtr<Gst::Message>
+  static Glib::RefPtr<Gst::MessageRequestState>
     create(const Glib::RefPtr<Gst::Object>& src, Gst::State state);
 
   /** Extract the requested state from the request_state message.
@@ -1244,7 +1284,7 @@ public:
    * @param owner The owner element of @a src.  
    * @return The new stream status message. MT safe.
    */
-  static Glib::RefPtr<Gst::Message>
+  static Glib::RefPtr<Gst::MessageStreamStatus>
     create(const Glib::RefPtr<Gst::Object>& src, Gst::StreamStatusType type,
     const Glib::RefPtr<Gst::Element>& owner);
 
@@ -1301,4 +1341,13 @@ public:
   Glib::RefPtr<Gst::Element> parse_owner() const;
 };
 
+/****************************** Gst::Message **************************/
+
+template <class MessageType>
+  Glib::RefPtr<MessageType> Message::wrap(GstMessage* message, bool take_copy)
+{
+  Glib::RefPtr<Gst::Message> result = wrap(message, take_copy);
+  return Glib::RefPtr<MessageType>::cast_dynamic(result);
+}
+
 } //namespace Gst
diff --git a/gstreamer/src/query.ccg b/gstreamer/src/query.ccg
index 70ab67a..c0532d4 100644
--- a/gstreamer/src/query.ccg
+++ b/gstreamer/src/query.ccg
@@ -30,7 +30,7 @@ extern "C"
 {
 
 static void Query_gstreamermm_callback_destroy(void* data,
-  GstMiniObject* where_the_object_was)
+  GstMiniObject* /* where_the_object_was */)
 {
   // This works for any of the Gst::Query derived classes because none of
   // them have member variables so in essence they are all the same size.
@@ -100,24 +100,26 @@ QueryApplication::QueryApplication(GstQuery* castitem) :
 Query(castitem)
 {}
 
-Glib::RefPtr<Gst::Query> QueryApplication::create(QueryType type, Gst::Structure& structure)
+Glib::RefPtr<Gst::QueryApplication>
+  QueryApplication::create(QueryType type, Gst::Structure& structure)
 {
   // Create copy because query takes ownership of structure:
   GstStructure* copy_struct = gst_structure_copy(structure.gobj());
   GstQuery* query = gst_query_new_application(GstQueryType(type),
     copy_struct); 
-  return Gst::Query::wrap(query);
+  return Gst::Query::wrap<QueryApplication>(query);
 }
 
 QueryConvert::QueryConvert(GstQuery* castitem) :
 Query(castitem)
 {}
 
-Glib::RefPtr<Gst::Query> QueryConvert::create(Format src_format, gint64 value, Format dest_format)
+Glib::RefPtr<Gst::QueryConvert>
+  QueryConvert::create(Format src_format, gint64 value, Format dest_format)
 {
   GstQuery* query = gst_query_new_convert(GstFormat(src_format), value,
     GstFormat(dest_format));
-  return Gst::Query::wrap(query);
+  return Gst::Query::wrap<QueryConvert>(query);
 }
 
 void QueryConvert::set(Format src_format, gint64 src_value, Format dest_format, gint64 dest_value)
@@ -174,10 +176,10 @@ QueryPosition::QueryPosition(GstQuery* castitem) :
 Query(castitem)
 {}
 
-Glib::RefPtr<Gst::Query> QueryPosition::create(Format format)
+Glib::RefPtr<Gst::QueryPosition> QueryPosition::create(Format format)
 {
   GstQuery* query = gst_query_new_position(GstFormat(format));
-  return Gst::Query::wrap(query);
+  return Gst::Query::wrap<QueryPosition>(query);
 }
 
 void QueryPosition::set(Format format, gint64 position)
@@ -210,10 +212,10 @@ QueryDuration::QueryDuration(GstQuery* castitem) :
 Query(castitem)
 {}
 
-Glib::RefPtr<Gst::Query> QueryDuration::create(Format format)
+Glib::RefPtr<Gst::QueryDuration> QueryDuration::create(Format format)
 {
   GstQuery* query = gst_query_new_duration(GstFormat(format));
-  return Gst::Query::wrap(query);
+  return Gst::Query::wrap<QueryDuration>(query);
 }
 
 void QueryDuration::set(Format format, gint64 duration)
@@ -246,10 +248,10 @@ QueryLatency::QueryLatency(GstQuery* castitem) :
 Query(castitem)
 {}
 
-Glib::RefPtr<Gst::Query> QueryLatency::create()
+Glib::RefPtr<Gst::QueryLatency> QueryLatency::create()
 {
   GstQuery* query = gst_query_new_latency();
-  return Gst::Query::wrap(query);
+  return Gst::Query::wrap<QueryLatency>(query);
 }
 
 void QueryLatency::set(bool live, ClockTime min_latency, ClockTime max_latency)
@@ -293,10 +295,10 @@ QuerySeeking::QuerySeeking(GstQuery* castitem) :
 Query(castitem)
 {}
 
-Glib::RefPtr<Gst::Query> QuerySeeking::create(Format format)
+Glib::RefPtr<Gst::QuerySeeking> QuerySeeking::create(Format format)
 {
   GstQuery* query = gst_query_new_seeking(GstFormat(format));
-  return Gst::Query::wrap(query);
+  return Gst::Query::wrap<QuerySeeking>(query);
 }
 
 void QuerySeeking::set(Format format, bool seekable, gint64 segment_start, gint64 segment_end)
@@ -349,10 +351,10 @@ QueryFormats::QueryFormats(GstQuery* castitem) :
 Query(castitem)
 {}
 
-Glib::RefPtr<Gst::Query> QueryFormats::create()
+Glib::RefPtr<Gst::QueryFormats> QueryFormats::create()
 {
   GstQuery* query = gst_query_new_formats();
-  return Gst::Query::wrap(query);
+  return Gst::Query::wrap<QueryFormats>(query);
 }
 
 void QueryFormats::set(const Glib::ArrayHandle<Format>& formats)
@@ -386,10 +388,10 @@ QuerySegment::QuerySegment(GstQuery* castitem) :
 Query(castitem)
 {}
 
-Glib::RefPtr<Gst::Query> QuerySegment::create(Format format)
+Glib::RefPtr<Gst::QuerySegment> QuerySegment::create(Format format)
 {
   GstQuery* query = gst_query_new_segment(GstFormat(format));
-  return Gst::Query::wrap(query);
+  return Gst::Query::wrap<QuerySegment>(query);
 }
 
 void QuerySegment::set(double rate, Format format, gint64 start_value, gint64 stop_value)
@@ -440,10 +442,10 @@ QueryBuffering::QueryBuffering(GstQuery* castitem) :
 Query(castitem)
 {}
 
-Glib::RefPtr<Gst::Query> QueryBuffering::create(Format format)
+Glib::RefPtr<Gst::QueryBuffering> QueryBuffering::create(Format format)
 {
   GstQuery* query = gst_query_new_buffering(GstFormat(format));
-  return Gst::Query::wrap(query);
+  return Gst::Query::wrap<QueryBuffering>(query);
 }
 
 void QueryBuffering::set(bool busy, int percent)
diff --git a/gstreamer/src/query.hg b/gstreamer/src/query.hg
index 6be1806..7f3ff44 100644
--- a/gstreamer/src/query.hg
+++ b/gstreamer/src/query.hg
@@ -171,6 +171,13 @@ protected:
   static void finalize_vfunc_callback(GstMiniObject* self);
   _POP()
 #m4end
+
+protected:
+  // This method is used in the create() methods to convert a wrapped GstQuery
+  // to one of the more specific Gst::Query types.
+  template <class QueryType>
+    static inline Glib::RefPtr<QueryType> wrap(GstQuery* query,
+    bool take_copy = false);
 };
 
 //TODO: Modify create methods of derived Query classes to return
@@ -194,7 +201,8 @@ public:
    * @param structure A structure for the query.
    * @return The new Gst::QueryApplication.
    */
-  static Glib::RefPtr<Gst::Query> create(QueryType type, Gst::Structure& structure);
+  static Glib::RefPtr<Gst::QueryApplication>
+    create(QueryType type, Gst::Structure& structure);
 };
 
 /** A convert query object.  See create() for more details.
@@ -211,7 +219,8 @@ public:
    * @param dest_format The target Gst::Format.
    * @return The new Gst::QueryConvert.
    */
-  static Glib::RefPtr<Gst::Query> create(Format src_format, gint64 value, Format dest_format);
+  static Glib::RefPtr<Gst::QueryConvert>
+    create(Format src_format, gint64 value, Format dest_format);
 
   /** Answer a convert query by setting the requested values.
    * @param src_format The source Gst::Format.
@@ -274,7 +283,7 @@ public:
    * @param format The default Gst::Format for the new query.
    * @return The new Gst::QueryPosition.
    */
-  static Glib::RefPtr<Gst::Query> create(Format format);
+  static Glib::RefPtr<Gst::QueryPosition> create(Format format);
 
   /** Answer a position query by setting the requested value in the given
    * format.
@@ -314,7 +323,7 @@ public:
    * @param format The Gst::Format for this duration query.
    * @return The new Gst::QueryDuration.
    */
-  static Glib::RefPtr<Gst::Query> create(Format format);
+  static Glib::RefPtr<Gst::QueryDuration> create(Format format);
 
   /** Answer a duration query by setting the requested value in the given
    * format.
@@ -354,7 +363,7 @@ public:
    * elements in the pipeline.
    * @return The new Gst::QueryLatency.
    */
-  static Glib::RefPtr<Gst::Query> create();
+  static Glib::RefPtr<Gst::QueryLatency> create();
 
   /** Answer a latency query by setting the requested values in the given
    * format.
@@ -400,7 +409,7 @@ public:
    * @param format The default Gst::Format for the new query.
    * @return The new Gst::QuerySeeking.
    */
-  static Glib::RefPtr<Gst::Query> create(Format format);
+  static Glib::RefPtr<Gst::QuerySeeking> create(Format format);
 
   /** Set the seeking query result fields in query.
    * @param format The format to set for @a the segment_start and
@@ -452,7 +461,7 @@ public:
   /** Constructs a new query object for querying formats of the stream.
    * @return The new Gst::QueryFormats.
    */
-  static Glib::RefPtr<Gst::Query> create();
+  static Glib::RefPtr<Gst::QueryFormats> create();
 
   /** Set the formats query result fields. All the formats in the array are
    * used.
@@ -495,7 +504,7 @@ public:
    * @param format The Gst::Format for the new query.
    * @return The new Gst::QuerySegment.
    */
-  static Glib::RefPtr<Gst::Query> create(Format format);
+  static Glib::RefPtr<Gst::QuerySegment> create(Format format);
 
   /** Answer a segment query by setting the requested values. The normal
    * playback segment of a pipeline is 0 to duration at the default rate of
@@ -564,7 +573,7 @@ public:
    * @param format The default Gst::Format for the new query.
    * @return The new Gst::QueryBuffering.
    */
-  static Glib::RefPtr<Gst::Query> create(Format format);
+  static Glib::RefPtr<Gst::QueryBuffering> create(Format format);
 
   /** Set the percentage of buffered data. This is a value between 0 and 100.
    * The @a busy indicator is true when the buffering is in progress.
@@ -672,4 +681,13 @@ public:
   gint64 parse_total_time() const;
 };
 
+/****************************** Gst::Query **************************/
+
+template <class QueryType>
+  Glib::RefPtr<QueryType> Query::wrap(GstQuery* query, bool take_copy)
+{
+  Glib::RefPtr<Gst::Query> result = wrap(query, take_copy);
+  return Glib::RefPtr<QueryType>::cast_dynamic(result);
+}
+
 } //namespace Gst
diff --git a/tests/test-event-wrap.cc b/tests/test-event-wrap.cc
index e18bd11..2ca1136 100644
--- a/tests/test-event-wrap.cc
+++ b/tests/test-event-wrap.cc
@@ -38,5 +38,20 @@ int main(int argc, char** argv)
   if(structure)
     std::cout << "Event structure name: '" << structure.get_name() << "'" << std::endl;
 
+  // Test the creation of an event.
+  Glib::RefPtr<Gst::EventFlushStart> flush_start =
+    Gst::EventFlushStart::create();
+
+  if(!flush_start)
+  {
+    std::cout << "The custom flush start event could not be created" <<
+      std::endl;
+  }
+  else
+  {
+    std::cout << "The custom flush start event was successfully created" <<
+      std::endl;
+  }
+
   return 0;
 }
diff --git a/tests/test-message-wrap.cc b/tests/test-message-wrap.cc
index a528638..2244784 100644
--- a/tests/test-message-wrap.cc
+++ b/tests/test-message-wrap.cc
@@ -42,5 +42,13 @@ int main(int argc, char** argv)
   if(structure)
     std::cout << "Message structure name: '" << structure.get_name() << "'" << std::endl;
 
+  // Test the creation of a message.
+  Glib::RefPtr<Gst::Bin> bin = Glib::wrap(GST_BIN(cobject));
+  Glib::RefPtr<Gst::MessageEos> eos = Gst::MessageEos::create(bin);
+  if(!eos)
+    std::cout << "The custom eos message could not be created" << std::endl;
+  else
+    std::cout << "The custom eos message was successfully created" << std::endl;
+
   return 0;
 }
diff --git a/tests/test-query-wrap.cc b/tests/test-query-wrap.cc
index c60e622..3dc17c8 100644
--- a/tests/test-query-wrap.cc
+++ b/tests/test-query-wrap.cc
@@ -38,5 +38,17 @@ int main(int argc, char** argv)
   if(structure)
     std::cout << "Query structure name: '" << structure.get_name() << "'" << std::endl;
 
+  // Test the creation of a query.
+  Glib::RefPtr<Gst::QueryLatency> latency = Gst::QueryLatency::create();
+  if(!latency)
+  {
+    std::cout << "The custom latency query could not be created" << std::endl;
+  }
+  else
+  {
+    std::cout << "The custom latency query was successfully created" <<
+      std::endl;
+  }
+
   return 0;
 }



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