[gstreamermm] C++11: use rvalue references for transfer-full function parameters



commit ee1bffe298950e565226807748b08d24f0e9ce7f
Author: Marcin Kolny <marcin kolny gmail com>
Date:   Sat Aug 22 11:26:09 2015 +0000

    C++11: use rvalue references for transfer-full function parameters
    
    This commit breaks the API. But version 1.6 of gstreamermm enables C++11
    flag in compilers, so it's good time to change API slightly. Since
    version 1.6 gstreamermm's API will be marked as 'stable'.
    
        * gstreamer/src/allocator.ccg:
        * gstreamer/src/allocator.hg:
        * gstreamer/src/buffer.ccg:
        * gstreamer/src/buffer.hg:
        * gstreamer/src/bus.ccg:
        * gstreamer/src/bus.hg:
        * gstreamer/src/caps.ccg:
        * gstreamer/src/caps.hg:
        * gstreamer/src/pad.ccg:
        * gstreamer/src/pad.hg: use rvalues for some function parameters.
        * tests/plugins/foo.h:
        * tests/regression/test-regression-seekonstartup.cc:
        * tests/test-allocator.cc:
        * tests/test-buffer.cc:
        * tests/test-bus.cc:
        * tests/test-caps.cc:
        * tests/test-pad.cc: update tests.
        * tools/m4/convert_gst.m4: add rvalues conversion definitions.

 gstreamer/src/allocator.ccg                       |   17 +----
 gstreamer/src/allocator.hg                        |    9 +--
 gstreamer/src/buffer.ccg                          |   42 ++++---------
 gstreamer/src/buffer.hg                           |   70 +++------------------
 gstreamer/src/bus.ccg                             |    7 --
 gstreamer/src/bus.hg                              |   12 +---
 gstreamer/src/caps.ccg                            |   29 ++++-----
 gstreamer/src/caps.hg                             |   19 +-----
 gstreamer/src/pad.ccg                             |   30 ---------
 gstreamer/src/pad.hg                              |   69 ++-------------------
 tests/plugins/foo.h                               |    2 +-
 tests/regression/test-regression-seekonstartup.cc |    3 +-
 tests/test-allocator.cc                           |    8 +-
 tests/test-buffer.cc                              |   31 +++++++++-
 tests/test-bus.cc                                 |    3 +-
 tests/test-caps.cc                                |    4 +-
 tests/test-pad.cc                                 |   20 ++++++
 tools/m4/convert_gst.m4                           |    5 ++
 18 files changed, 111 insertions(+), 269 deletions(-)
---
diff --git a/gstreamer/src/allocator.ccg b/gstreamer/src/allocator.ccg
index 8dee06c..5cd861d 100644
--- a/gstreamer/src/allocator.ccg
+++ b/gstreamer/src/allocator.ccg
@@ -52,15 +52,6 @@ void Allocator::set_default()
   gst_allocator_set_default(gobj());
 }
 
-void Allocator::free(Glib::RefPtr<Gst::Memory>& memory)
-{
-  GstMemory* memory_gobj = memory->gobj();
-  memory->reference();
-  memory.reset();
-
-  gst_allocator_free(gobj(), memory_gobj);
-}
-
 void Allocator_Class::free_vfunc_callback(GstAllocator* self, GstMemory* memory)
 {
   Glib::ObjectBase *const obj_base = static_cast<Glib::ObjectBase*>(
@@ -82,7 +73,7 @@ void Allocator_Class::free_vfunc_callback(GstAllocator* self, GstMemory* memory)
       #endif //GLIBMM_EXCEPTIONS_ENABLED
         // Call the virtual member method, which derived classes might override.
        Glib::RefPtr<Gst::Memory> mem = Glib::wrap(memory);
-        obj->free_vfunc(mem);
+        obj->free_vfunc(std::move(mem));
         return;
       #ifdef GLIBMM_EXCEPTIONS_ENABLED
       }
@@ -106,7 +97,7 @@ void Allocator_Class::free_vfunc_callback(GstAllocator* self, GstMemory* memory)
 
 }
 
-void Gst::Allocator::free_vfunc(Glib::RefPtr<Gst::Memory>& memory)
+void Gst::Allocator::free_vfunc(Glib::RefPtr<Gst::Memory>&& memory)
 {
   BaseClassType *const base = static_cast<BaseClassType*>(
       g_type_class_peek_parent(G_OBJECT_GET_CLASS(gobject_))
@@ -114,9 +105,7 @@ void Gst::Allocator::free_vfunc(Glib::RefPtr<Gst::Memory>& memory)
 
   if(base && base->free)
   {
-    GstMemory* mem_gobj = memory->gobj();
-    memory->reference();
-    memory.reset();
+    GstMemory* mem_gobj = memory.release()->gobj();
     (*base->free)(gobj(), mem_gobj);
   }
 }
diff --git a/gstreamer/src/allocator.hg b/gstreamer/src/allocator.hg
index e5f523d..6bf7e03 100644
--- a/gstreamer/src/allocator.hg
+++ b/gstreamer/src/allocator.hg
@@ -87,19 +87,14 @@ public:
    */
   static Glib::RefPtr<Gst::Allocator> get_default_allocator();
 
-  /** Free @a memory that was previously allocated with alloc().
-   * @param memory The memory to free.
-   */
-  void free(Glib::RefPtr<Gst::Memory>& memory);
-  _IGNORE(gst_allocator_free)
-
+  _WRAP_METHOD(void free(Glib::RefPtr<Gst::Memory>&& memory), gst_allocator_free)
   _WRAP_METHOD(Glib::RefPtr<Gst::Memory> alloc(gsize size, Gst::AllocationParams params), 
gst_allocator_alloc)
   _WRAP_VFUNC(Glib::RefPtr<Gst::Memory> alloc(gsize size, Gst::AllocationParams params), "alloc", 
refreturn_ctype)
 
   // This vfunc is hand-coded because it takes reference to a memory.
   // In generally, arguments are passed to a function by copy, so
   // custom wrapper is necessary.
-  virtual void free_vfunc(Glib::RefPtr<Gst::Memory>& memory);
+  virtual void free_vfunc(Glib::RefPtr<Gst::Memory>&& memory);
 
 protected:
 #m4begin
diff --git a/gstreamer/src/buffer.ccg b/gstreamer/src/buffer.ccg
index 8a9a27c..38f26a6 100644
--- a/gstreamer/src/buffer.ccg
+++ b/gstreamer/src/buffer.ccg
@@ -45,40 +45,22 @@ guint64 Buffer::offset_none()
   return GST_BUFFER_OFFSET_NONE;
 }
 
-void Buffer::insert_memory(guint idx, Glib::RefPtr<Gst::Memory>& mem)
+Glib::RefPtr<Gst::Buffer> Buffer::append_region(Glib::RefPtr<Gst::Buffer>&& buf, gssize offset, gssize size)
 {
-  GstMemory *mem_gobj = mem->gobj();
-  mem->reference();
-  mem.reset();
-  gst_buffer_insert_memory(gobj(), idx, mem_gobj);
+  if (is_writable())
+  {
+    return Glib::wrap(gst_buffer_append_region(gobj(), buf.release()->gobj(), offset, size), true);
+  }
+  else
+  {
+    reference();
+    return Glib::wrap(gst_buffer_append_region(gobj(), buf.release()->gobj(), offset, size), false);
+  }
 }
 
-void Buffer::prepend_memory(Glib::RefPtr<Gst::Memory>& mem)
+Glib::RefPtr<Gst::Buffer> Buffer::append(Glib::RefPtr<Gst::Buffer>&& buf)
 {
-  insert_memory(0, mem);
-}
-
-void Buffer::append_memory(Glib::RefPtr<Gst::Memory>& mem)
-{
-  insert_memory(-1, mem);
-}
-
-void Buffer::replace_memory_range(guint idx, gint length, Glib::RefPtr<Gst::Memory>& mem)
-{
-  GstMemory *mem_gobj = mem->gobj();
-  mem->reference();
-  mem.reset();
-  gst_buffer_replace_memory_range(gobj(), idx, length, mem_gobj);
-}
-
-void Buffer::replace_memory(guint idx, Glib::RefPtr<Gst::Memory>& mem)
-{
-  replace_memory_range(idx, 1, mem);
-}
-
-void Buffer::replace_all_memory(Glib::RefPtr<Gst::Memory>& mem)
-{
-  replace_memory_range(0, -1, mem);
+  return append_region(std::move(buf), 0, -1);
 }
 
 } // namespace Gst
diff --git a/gstreamer/src/buffer.hg b/gstreamer/src/buffer.hg
index fc71cdf..0da0c7e 100644
--- a/gstreamer/src/buffer.hg
+++ b/gstreamer/src/buffer.hg
@@ -135,40 +135,19 @@ public:
 
   _WRAP_METHOD(guint n_memory() const, gst_buffer_n_memory)
 
-  /** Insert the memory block @mem to @buffer at @idx. This function takes ownership
-   * of @mem and thus doesn't increase its refcount.
-   *
-   * Only get_max_memory() can be added to a buffer. If more memory is
-   * added, existing memory blocks will automatically be merged to make room for
-   * the new memory.
-   *
-   * @param idx: the index to add the memory at, or -1 to append it to the end.
-   * @param mem: a Gst::Memory.
-   */
-  void insert_memory(guint idx, Glib::RefPtr<Gst::Memory>& mem);
-  _IGNORE(gst_buffer_insert_memory)
+  _WRAP_METHOD(void insert_memory(gint idx, Glib::RefPtr<Gst::Memory>&& mem), gst_buffer_insert_memory)
 
   _WRAP_METHOD(Glib::RefPtr<Gst::Memory> get_all_memory() const, gst_buffer_get_all_memory)
 
   _WRAP_METHOD(gsize fill(gsize offset, gconstpointer src, gsize size), gst_buffer_fill)
 
-  _WRAP_METHOD(Glib::RefPtr<Gst::Buffer> append(const Glib::RefPtr<Gst::Buffer>& buf) const, 
gst_buffer_append)
+  Glib::RefPtr<Gst::Buffer> append_region(Glib::RefPtr<Gst::Buffer>&& buf, gssize offset, gssize size);
+  _IGNORE(gst_buffer_append_region)
 
-  _WRAP_METHOD(Glib::RefPtr<Gst::Buffer> append_region(const Glib::RefPtr<Gst::Buffer>& buf, gssize offset, 
gssize size) const, gst_buffer_append_region)
+  Glib::RefPtr<Gst::Buffer> append(Glib::RefPtr<Gst::Buffer>&& buf);
+  _IGNORE(gst_buffer_append)
 
-  /** Replaces @a length memory blocks in @a buffer starting at @a idx with @a mem.
-   *
-   * If @a length is -1, all memory starting from @a idx will be removed and
-   * replaced with @a mem.
-   *
-   *  @a buffer should be writable.
-   *
-   * @param idx An index.
-   * @param length A length should not be 0.
-   * @param mem A Gst::Memory.
-   */
-  void replace_memory_range(guint idx, gint length, Glib::RefPtr<Gst::Memory>& mem);
-  _IGNORE(gst_buffer_replace_memory_range)
+  _WRAP_METHOD(void replace_memory_range(guint idx, gint length, Glib::RefPtr<Gst::Memory>&& mem), 
gst_buffer_replace_memory_range)
 
   _WRAP_METHOD(Glib::RefPtr<Gst::Memory> get_memory_range(guint idx, gint length), 
gst_buffer_get_memory_range)
 
@@ -176,27 +155,9 @@ public:
 
   _WRAP_METHOD(bool find_memory(gsize offset, gsize size, guint& idx, guint& length, gsize& skip), 
gst_buffer_find_memory)
 
-  /** Prepend the memory block @mem to @buffer. This function takes
-   * ownership of @mem and thus doesn't increase its refcount.
-   *
-   * This function is identical to insert_memory() with an index of 0.
-   * See insert_memory() for more details.
-   *
-   * @param mem: a Gst::Memory.
-   */
-   void prepend_memory(Glib::RefPtr<Gst::Memory>& mem);
-  _IGNORE(gst_buffer_prepend_memory)
+  _WRAP_METHOD(void prepend_memory(Glib::RefPtr<Gst::Memory>&& mem), gst_buffer_prepend_memory)
 
-  /** Append the memory block @mem to @buffer. This function takes
-   * ownership of @mem and thus doesn't increase its refcount.
-
-   * This function is identical to insert_memory() with an index of -1.
-   * See insert_memory() for more details.
-   *
-   * @param mem: a Gst::Memory.
-   */
-  void append_memory(Glib::RefPtr<Gst::Memory>& mem);
-  _IGNORE(gst_buffer_append_memory);
+  _WRAP_METHOD(void append_memory(Glib::RefPtr<Gst::Memory>&& mem), gst_buffer_append_memory)
 
   _WRAP_METHOD(void remove_memory(guint idx), gst_buffer_remove_memory)
 
@@ -204,20 +165,9 @@ public:
 
   _WRAP_METHOD(gsize memset(gsize offset, guint8 val, gsize size), gst_buffer_memset)
 
-  /** Replaces the memory block at index @a idx in @a buffer with @a mem.
-   *
-   * @param idx An index.
-   * @param mem A Gst::Memory.
-   */
-  void replace_memory(guint idx, Glib::RefPtr<Gst::Memory>& mem);
-  _IGNORE(gst_buffer_replace_memory)
+  _WRAP_METHOD(void replace_memory(guint idx, Glib::RefPtr<Gst::Memory>&& mem), gst_buffer_replace_memory)
 
-  /** Replaces all memory in @a buffer with @a mem.
-   *
-   * @param mem A Gst::Memory.
-   */
-  void replace_all_memory(Glib::RefPtr<Gst::Memory>& mem);
-  _IGNORE(gst_buffer_replace_all_memory)
+  _WRAP_METHOD(void replace_all_memory(Glib::RefPtr<Gst::Memory>&& mem), gst_buffer_replace_all_memory)
 
   _WRAP_METHOD(gsize extract(gsize offset, gpointer dest, gsize size), gst_buffer_extract)
 
diff --git a/gstreamer/src/bus.ccg b/gstreamer/src/bus.ccg
index 3aab995..74d3159 100644
--- a/gstreamer/src/bus.ccg
+++ b/gstreamer/src/bus.ccg
@@ -86,13 +86,6 @@ bool Bus::remove_watch(guint id)
   return g_source_remove(id);
 }
 
-bool Bus::post(Glib::RefPtr<Gst::Message>& message)
-{
-  GstMessage* msg = message->gobj();
-  message->reference(); message.reset();
-  return gst_bus_post(gobj(), msg);
-}
-
 void Bus::set_sync_handler(const SlotMessageSync& slot)
 {
   // Clear a possibly existing sync handler by calling with 0 before setting
diff --git a/gstreamer/src/bus.hg b/gstreamer/src/bus.hg
index 7edc7ee..6a7c247 100644
--- a/gstreamer/src/bus.hg
+++ b/gstreamer/src/bus.hg
@@ -111,17 +111,7 @@ public:
    */
   _WRAP_CREATE()
 
-  /** Post a message on the given bus. Ownership of the message
-   * is taken by the bus.
-   *
-   * @param message The Gst::Message to post. RefPtr is reset inside method.
-   * @return <tt>true</tt> if the message could be posted, <tt>false</tt> if the bus is flushing.
-   *
-   * MT safe.
-   */
-  bool post(Glib::RefPtr<Gst::Message>& message);
-  _IGNORE(gst_bus_post)
-
+  _WRAP_METHOD(bool post(Glib::RefPtr<Gst::Message>&& message), gst_bus_post)
   _WRAP_METHOD(bool have_pending() const, gst_bus_have_pending)
   _WRAP_METHOD(Glib::RefPtr<Gst::Message> peek(), gst_bus_peek)
   _WRAP_METHOD(Glib::RefPtr<const Gst::Message> peek() const, gst_bus_peek)
diff --git a/gstreamer/src/caps.ccg b/gstreamer/src/caps.ccg
index eab7b07..916281e 100644
--- a/gstreamer/src/caps.ccg
+++ b/gstreamer/src/caps.ccg
@@ -118,22 +118,6 @@ Caps::set_simple(const Glib::ustring& name, const char* data)
   set_simple(name, std::string(data));
 }
 
-Glib::RefPtr<Gst::Caps> Caps::merge(Glib::RefPtr<Gst::Caps>& caps)
-{
-  GstCaps *c1 = gobj(), *c2 = Glib::unwrap(caps);
-  caps->reference(); caps.reset();
-  reference();
-  return Glib::wrap(gst_caps_merge(c1, c2));
-}
-
-void Caps::append(Glib::RefPtr<Gst::Caps>& caps)
-{
-  caps->reference();
-  GstCaps *c_caps = Glib::unwrap(caps);
-  caps.reset();
-  gst_caps_append(gobj(), c_caps);
-}
-
 CapsFeatures Caps::get_features(guint index) const
 {
   GstCapsFeatures* features = gst_caps_get_features(gobj(), index);
@@ -152,6 +136,19 @@ Glib::RefPtr<Gst::Caps> Caps::truncate()
   return Glib::wrap(gst_caps_truncate(gobj()));
 }
 
+Glib::RefPtr<Gst::Caps> Caps::merge(Glib::RefPtr<Gst::Caps>&& caps)
+{
+  if (is_writable())
+  {
+    return Glib::wrap(gst_caps_merge(gobj(), caps.release()->gobj()), true);
+  }
+  else
+  {
+    reference();
+    return Glib::wrap(gst_caps_merge(gobj(), caps.release()->gobj()), false);
+  }
+}
+
 } //namespace Gst
 
 namespace Glib 
diff --git a/gstreamer/src/caps.hg b/gstreamer/src/caps.hg
index de463f3..f421509 100644
--- a/gstreamer/src/caps.hg
+++ b/gstreamer/src/caps.hg
@@ -88,24 +88,9 @@ public:
 
   _WRAP_METHOD(Glib::RefPtr<Gst::Caps> copy_nth(guint nth) const, gst_caps_copy_nth)
 
-  /** Appends the structures contained in @a caps to this object. The structures in
-   *  @a caps are not copied -- they are transferred to this object, and then @a caps is
-   * freed. If either caps is ANY, the resulting caps will be ANY.
-   * 
-   * @param caps The Gst::Caps to append.
-   */
-  void append(Glib::RefPtr<Gst::Caps>& caps);
-  _IGNORE(gst_caps_append)
+  _WRAP_METHOD(void append(Glib::RefPtr<Gst::Caps>&& caps), gst_caps_append)
 
-  /** Appends the structures contained in @a caps to an object if they are not yet
-   * expressed by this object. The structures in @a caps are not copied -- they are
-   * transferred to a writable copy of this object, and then @a caps is freed.
-   * If either caps is ANY, the resulting caps will be ANY.
-   * 
-   * @param caps The Gst::Caps to merge in.
-   * @return The merged caps.
-   */
-  Glib::RefPtr<Gst::Caps> merge(Glib::RefPtr<Gst::Caps>& caps);
+  Glib::RefPtr<Gst::Caps> merge(Glib::RefPtr<Gst::Caps>&& caps);
   _IGNORE(gst_caps_merge)
 
   /** Appends a structure to caps.
diff --git a/gstreamer/src/pad.ccg b/gstreamer/src/pad.ccg
index bd5f026..245e9b3 100644
--- a/gstreamer/src/pad.ccg
+++ b/gstreamer/src/pad.ccg
@@ -145,23 +145,6 @@ FlowReturn Pad::get_range(guint64 offset, guint size, Glib::RefPtr<Gst::Buffer>&
   return FlowReturn(result);
 }
 
-FlowReturn Pad::push(Glib::RefPtr<Gst::Buffer>& buffer)
-{
-    GstBuffer *buffer_gobj = buffer->gobj();
-    /* gst_pad_push takes ownership of given "buffer". It is recommended (for performance reasons) that the 
buffer given to gst_pad_push() has
-     * only one reference, since in other cases it will be copied whenever "make_writable" will be called.
-     */
-    buffer->reference();  //allocate additional ref for gst_pad_push()
-    buffer.reset();  //take away buffer from the caller
-    return FlowReturn(gst_pad_push(gobj(), buffer_gobj));
-}
-
-bool Pad::push_event(const Glib::RefPtr<Gst::Event>& event)
-{
-  event->reference();
-  return gst_pad_push_event(gobj(), event->gobj());
-}
-
 FlowReturn Pad::pull_range(guint64 offset, guint size, Glib::RefPtr<Gst::Buffer>& buffer)
 {
   GstBuffer* c_buffer = nullptr;
@@ -170,12 +153,6 @@ FlowReturn Pad::pull_range(guint64 offset, guint size, Glib::RefPtr<Gst::Buffer>
   return FlowReturn(result);
 }
 
-bool Pad::send_event(const Glib::RefPtr<Gst::Event>& event)
-{
-  event->reference();
-  return gst_pad_send_event(gobj(), event->gobj());
-}
-
 bool Pad::query_position(Format& format) const
 {
   return gst_pad_query_position(const_cast<GstPad*>(gobj()), (GstFormat)format, nullptr);
@@ -186,13 +163,6 @@ bool Pad::query_duration(Format& format) const
   return gst_pad_query_duration(const_cast<GstPad*>(gobj()), (GstFormat)format, nullptr);
 }
 
-FlowReturn Pad::chain(Glib::RefPtr<Gst::Buffer>& buffer)
-{
-  buffer->reference();  //hold reference for gst_pad_chain()
-  buffer.reset();       //free caller's reference
-  return FlowReturn(gst_pad_chain(gobj(), buffer->gobj()));
-}
-
 GstFlowReturn Pad::Pad_Chain_gstreamermm_callback(GstPad* pad, GstObject*, GstBuffer *buffer)
 {
   //FIXME: It's made like vfunc wrappers, but why there is no reffing of pad?
diff --git a/gstreamer/src/pad.hg b/gstreamer/src/pad.hg
index 45653ec..e8d7c22 100644
--- a/gstreamer/src/pad.hg
+++ b/gstreamer/src/pad.hg
@@ -218,39 +218,8 @@ public:
   _WRAP_METHOD(bool proxy_query_caps(const Glib::RefPtr<Gst::Query>& query), gst_pad_proxy_query_caps)
   _WRAP_METHOD(bool proxy_query_caps(const Glib::RefPtr<Gst::Query>& query) const, gst_pad_proxy_query_caps, 
constversion)
   _WRAP_METHOD(bool peer_query_accept_caps(const Glib::RefPtr<const Gst::Caps>& caps) const, 
gst_pad_peer_query_accept_caps)
-
-  // This method is written manually because an extra ref is necessary
-  /** Pushes a buffer to the peer of the pad. The pad must be a source pad,
-   * otherwise this method returns Gst::FLOW_ERROR.
-   *
-   * This function will call an installed pad block before triggering any
-   * installed pad probes.
-   *
-   * If the caps on buffer are different from the currently configured caps on
-   * pad, this function will call any installed setcaps function on pad (see
-   * the C API gst_pad_set_setcaps_function()). In case of failure to
-   * renegotiate the new format, this function returns
-   * Gst::FLOW_NOT_NEGOTIATED.
-   *
-   * The function proceeds calling chain() on the peer pad and returns the
-   * value from that function. If pad has no peer, Gst::FLOW_NOT_LINKED will
-   * be returned.
-   *
-   * @param buffer The Gst::Buffer to push.
-   * @return A Gst::FlowReturn from the peer pad. MT safe.
-   */
-  FlowReturn push(Glib::RefPtr<Gst::Buffer>& buffer);
-  _IGNORE(gst_pad_push)
-
-  // This method is written manually because an extra ref is necessary
-  /** Sends the event to the peer of the pad. This function is mainly used by
-   * elements to send events to their peer elements.
-   *
-   * @param event The GstEvent to send to the pad.
-   * @return true if the event was handled. MT safe.
-   */
-  bool push_event(const Glib::RefPtr<Gst::Event>& event);
-  _IGNORE(gst_pad_push_event)
+  _WRAP_METHOD(FlowReturn push(Glib::RefPtr<Gst::Buffer>&& buffer), gst_pad_push)
+  _WRAP_METHOD(bool push_event(Glib::RefPtr<Gst::Event>&& event), gst_pad_push_event)
 
   /** Pulls a buffer from the peer pad.  This function will first trigger the
    * pad block signal if it was installed.  This method works only on sink
@@ -276,34 +245,9 @@ public:
   _IGNORE(gst_pad_pull_range)
 
   _WRAP_METHOD(bool activate_mode(Gst::PadMode mode, bool active = true), gst_pad_activate_mode)
+  _WRAP_METHOD(bool send_event(Glib::RefPtr<Gst::Event>&& event), gst_pad_send_event)
 
-  // This method is written manually because an extra ref is necessary
-  /** Sends the event to the pad. This function can be used by applications to
-   * send events in the pipeline.
-   *
-   * If the pad is a source pad, event should be an upstream event. If the pad
-   * is a sink pad, the event should be a downstream event. For example, you
-   * would not send a Gst::EVENT_EOS on a src pad; EOS events only propagate
-   * downstream.  Furthermore, some downstream events have to be serialized
-   * with data flow, like EOS, while some can travel out-of-band, like
-   * Gst::EVENT_FLUSH_START.  If the event needs to be serialized with data
-   * flow, this function will take the pad's stream lock while calling its
-   * event function.
-   *
-   * To find out whether an event type is upstream, downstream, or downstream
-   * and serialized, see Gst::EventTypeFlags, Gst::Enums::get_flags(),
-   * is_upstream(), Gst::Event::is_downstream(), and
-   * Gst::Event::is_serialized(). Note that in practice that an application or
-   * plugin doesn't need to bother itself with this information; the core
-   * handles all necessary locks and checks.
-   *
-   * @param event The Gst::Event to send to the pad.
-   * @return true if the event was handled. 
-   */
-  bool send_event(const Glib::RefPtr<Gst::Event>& event);
-  _IGNORE(gst_pad_send_event)
-
-  _WRAP_METHOD(bool event_default(const Glib::RefPtr<Gst::Object>& parent{?}, const 
Glib::RefPtr<Gst::Event>& event), gst_pad_event_default)
+  _WRAP_METHOD(bool event_default(const Glib::RefPtr<Gst::Object>& parent{?}, Glib::RefPtr<Gst::Event>&& 
event), gst_pad_event_default)
   _WRAP_METHOD(bool query(const Glib::RefPtr<Gst::Query>& query) const, gst_pad_query)
   _WRAP_METHOD(bool peer_query(const Glib::RefPtr<Gst::Query>& query) const, gst_pad_peer_query)
   _WRAP_METHOD(Glib::RefPtr<Gst::Caps> peer_query_caps(const Glib::RefPtr<Gst::Caps>& filter) const, 
gst_pad_peer_query_caps)
@@ -335,10 +279,7 @@ public:
   _WRAP_METHOD(Gst::Iterator<const Gst::Pad> iterate_internal_links() const, gst_pad_iterate_internal_links)
   _WRAP_METHOD(Gst::Iterator<Gst::Pad> iterate_internal_links_default(const Glib::RefPtr<Gst::Object>& 
parent{?}), gst_pad_iterate_internal_links_default)
   _WRAP_METHOD(Gst::Iterator<const Gst::Pad> iterate_internal_links_default(const Glib::RefPtr<Gst::Object>& 
parent{?}) const, gst_pad_iterate_internal_links_default)
-
-  // This method is written manually because an extra ref is necessary
-  FlowReturn chain(Glib::RefPtr<Gst::Buffer>& buffer);
-  _IGNORE(gst_pad_chain)
+  _WRAP_METHOD(Gst::FlowReturn chain(Glib::RefPtr<Gst::Buffer>&& buffer), gst_pad_chain)
 
   _WRAP_METHOD(Glib::RefPtr<Gst::Caps> get_current_caps(), gst_pad_get_current_caps)
   _WRAP_METHOD(bool pause_task() , gst_pad_pause_task)
diff --git a/tests/plugins/foo.h b/tests/plugins/foo.h
index 39239fc..250cba5 100644
--- a/tests/plugins/foo.h
+++ b/tests/plugins/foo.h
@@ -39,7 +39,7 @@ public:
         std::sort(mapinfo->get_data(), mapinfo->get_data() + mapinfo->get_size());
         buf->unmap(mapinfo);
         assert(buf->gobj()->mini_object.refcount==1);
-        return srcpad->push(buf);
+        return srcpad->push(std::move(buf));
     }
 
     explicit Foo(GstElement *gobj)
diff --git a/tests/regression/test-regression-seekonstartup.cc 
b/tests/regression/test-regression-seekonstartup.cc
index c4fce91..5e0fb82 100644
--- a/tests/regression/test-regression-seekonstartup.cc
+++ b/tests/regression/test-regression-seekonstartup.cc
@@ -46,8 +46,7 @@ void dec_counter()
     if (g_atomic_int_dec_and_test (&counter))
     {
         prerolled = true;
-        Glib::RefPtr<Message> app = MessageApplication::create(pipeline, Structure("empty"));
-        bus->post(app);
+        bus->post(MessageApplication::create(pipeline, Structure("empty")));
     }
 }
 
diff --git a/tests/test-allocator.cc b/tests/test-allocator.cc
index 9f460da..bbff25b 100644
--- a/tests/test-allocator.cc
+++ b/tests/test-allocator.cc
@@ -40,7 +40,7 @@ TEST(AllocatorTest, ShouldCorrectAllocateMemory)
   EXPECT_EQ(7ul, mem->get_align());
   EXPECT_TRUE(flags & mem->get_flags());
 
-  allocator->free(mem);
+  allocator->free(std::move(mem));
 }
 
 class DerivedFromAllocator : public Gst::Allocator
@@ -62,10 +62,10 @@ public:
       return r;
     }
 
-    virtual void free_vfunc(Glib::RefPtr<Gst::Memory>& memory)
+    void free_vfunc(Glib::RefPtr<Gst::Memory>&& memory) override
     {
       memory->gobj()->allocator = the_allocator->gobj(); // pretend that it was the_allocator who allocated 
this memory
-      the_allocator->free(memory);
+      the_allocator->free(std::move(memory));
     }
 
     static Glib::RefPtr<Allocator> create()
@@ -95,7 +95,7 @@ TEST(AllocatorTest, DerivedFromAllocatorShouldReturnProperlyRefcountedWrappedGst
   EXPECT_EQ(7ul, mem->get_align());
   EXPECT_TRUE(flags & mem->get_flags());
 
-  allocator->free(mem);
+  allocator->free(std::move(mem));
 }
 
 TEST(AllocatorTest, DerivedFromAllocatorShouldReturnProperlyRefcountedGstMemory)
diff --git a/tests/test-buffer.cc b/tests/test-buffer.cc
index 7ad1c27..bc946a1 100644
--- a/tests/test-buffer.cc
+++ b/tests/test-buffer.cc
@@ -53,7 +53,7 @@ TEST(BufferTest, ShouldInsertMemoryObjectAndResetItButAllowToMakeExplicityRef)
   delete data;
   Glib::RefPtr<Buffer> buf = Buffer::create(10);
   mem2 = mem;
-  buf->insert_memory(0, mem);
+  buf->insert_memory(0, std::move(mem));
   ASSERT_FALSE(mem);
   ASSERT_EQ(2, mem2->gobj()->mini_object.refcount); // two - one handled by mem2,
                                                     //and the second by memory stored in buffer
@@ -77,7 +77,7 @@ TEST(BufferTest, ShouldResetMemoryPointerButAllowIncreaseRefcount)
   Glib::RefPtr<Memory> mem2 = mem;
   {
     Glib::RefPtr<Buffer> buf = Buffer::create(10);
-    buf->replace_memory_range(0, -1, mem);
+    buf->replace_memory_range(0, -1, std::move(mem));
   }
   ASSERT_FALSE(mem);
   ASSERT_EQ(1, mem2->gobj()->mini_object.refcount);
@@ -119,3 +119,30 @@ TEST(BufferTest, CheckBufferCopyIntoMethod)
   ASSERT_EQ(1, src->get_refcount());
   ASSERT_EQ(1, dest->get_refcount());
 }
+
+TEST(BufferTest, CheckRefcountAppendBufferToBuffer)
+{
+  Glib::RefPtr<Gst::Buffer> buf1 = Gst::Buffer::create(10);
+
+  { // buf1 not writable
+    Glib::RefPtr<Gst::Buffer> buf2 = Gst::Buffer::create(6);
+    Glib::RefPtr<Gst::Buffer> dummy = buf1;
+    Glib::RefPtr<Gst::Buffer> b = buf1->append(std::move(buf2));
+    ASSERT_FALSE(buf2);
+    ASSERT_EQ(2, buf1->get_refcount()); // dummy + buf1
+    ASSERT_EQ(1, b->get_refcount());
+    ASSERT_EQ(16u, b->get_size());
+    ASSERT_EQ(10u, buf1->get_size());
+    ASSERT_FALSE(b == buf1);
+  }
+
+  { // buf1 writable
+    Glib::RefPtr<Gst::Buffer> buf2 = Gst::Buffer::create(6);
+    Glib::RefPtr<Gst::Buffer> b = buf1->append(std::move(buf2));
+    ASSERT_FALSE(buf2);
+    ASSERT_EQ(2, buf1->get_refcount()); // b + buf1
+    ASSERT_EQ(2, b->get_refcount());
+    ASSERT_EQ(16u, b->get_size());
+    ASSERT_TRUE(b == buf1);
+  }
+}
diff --git a/tests/test-bus.cc b/tests/test-bus.cc
index f40b5ff..0ae919e 100644
--- a/tests/test-bus.cc
+++ b/tests/test-bus.cc
@@ -18,8 +18,7 @@ protected:
 
     void PostMessage()
     {
-        Glib::RefPtr<Message> m = MessageEos::create(Glib::RefPtr<Object>());
-        bool message_posted = bus->post(m);
+        bool message_posted = bus->post(MessageEos::create(Glib::RefPtr<Object>()));
         ASSERT_TRUE(message_posted);
     }
 
diff --git a/tests/test-caps.cc b/tests/test-caps.cc
index ba05d4f..873c8b2 100644
--- a/tests/test-caps.cc
+++ b/tests/test-caps.cc
@@ -84,7 +84,7 @@ TEST_F(CapsTest, AppendCapsToCaps)
     Glib::RefPtr<Caps> new_caps = Caps::create_simple("video/x-raw");
     new_caps->set_simple("width", width);
 
-    caps->append(new_caps);
+    caps->append(std::move(new_caps));
 
     CheckCaps("width", width, 1);
     CheckCaps("framerate", framerate);
@@ -117,7 +117,7 @@ TEST_F(CapsTest, MergeCaps)
 {
     Glib::RefPtr<Caps> tmp = Caps::create_from_string("video/x-raw, format=RGBA");
     Glib::RefPtr<Caps> tmp2 = Caps::create_from_string("video/x-raw, format=RGB");
-    tmp = tmp->merge(tmp2);
+    tmp = tmp->merge(std::move(tmp2));
     ASSERT_EQ(1, tmp->get_refcount());
     ASSERT_FALSE(tmp2);
 }
diff --git a/tests/test-pad.cc b/tests/test-pad.cc
index e8b8ce7..a473fd3 100644
--- a/tests/test-pad.cc
+++ b/tests/test-pad.cc
@@ -59,3 +59,23 @@ TEST_F(PadTest, PadVerifyGetPadTemplateCaps)
     }
     ASSERT_EQ(1, caps->get_refcount());
 }
+
+TEST_F(PadTest, PadPushVerifyBufferRefcount)
+{
+  Glib::RefPtr<Gst::Buffer> buffer = Gst::Buffer::create();
+  pad = Pad::create(pad_name, Gst::PAD_SRC);
+
+  ASSERT_EQ(1, buffer->get_refcount());
+  pad->push(std::move(buffer));
+  ASSERT_FALSE(buffer);
+}
+
+TEST_F(PadTest, PadEventDefault)
+{
+  Glib::RefPtr<Gst::Event> event = Gst::EventEos::create();
+  pad = Pad::create(pad_name, pad_direction);
+
+  ASSERT_EQ(1, event->get_refcount());
+  pad->event_default(std::move(event));
+  ASSERT_FALSE(event);
+}
diff --git a/tools/m4/convert_gst.m4 b/tools/m4/convert_gst.m4
index 9c3321c..a43b71d 100644
--- a/tools/m4/convert_gst.m4
+++ b/tools/m4/convert_gst.m4
@@ -94,6 +94,8 @@ _CONVERSION(`const Glib::RefPtr<const Gst::Buffer>&',`GstBuffer*', `const_cast<G
 _CONVERSION(`const Glib::RefPtr<Gst::Buffer>&',`const GstBuffer*', `Glib::unwrap($3)')
 _CONVERSION(`Glib::RefPtr<Gst::Buffer>',`GstBuffer*', `Glib::unwrap($3)')
 _CONVERSION(`GstBuffer*', `const Glib::RefPtr<Gst::Buffer>&', `Glib::wrap($3, true)')
+_CONVERSION(`Glib::RefPtr<Gst::Buffer>&&',`GstBuffer*',`($3) ? $3.release()->gobj() : nullptr')
+
 
 dnl BufferList
 _CONVERSION(`Glib::RefPtr<Gst::BufferList>',`GstBufferList*', `Glib::unwrap($3)')
@@ -115,6 +117,7 @@ _CONVERSION(`const Glib::RefPtr<Gst::Caps>&',`GstCaps*', `Glib::unwrap($3)')
 _CONVERSION(`const Glib::RefPtr<const Gst::Caps>&',`GstCaps*', `const_cast<$2>(Glib::unwrap($3))')
 _CONVERSION(`const Glib::RefPtr<Gst::Caps>&',`const GstCaps*', `Glib::unwrap($3)')
 _CONVERSION(`const Glib::RefPtr<const Gst::Caps>&',`const GstCaps*', `Glib::unwrap($3)')
+_CONVERSION(`Glib::RefPtr<Gst::Caps>&&',`GstCaps*',`($3) ? $3.release()->gobj() : nullptr')
 
 dnl CapsFeatures
 _CONVERSION(`const Gst::CapsFeatures&',`const GstCapsFeatures*',`$3.gobj()')
@@ -166,6 +169,7 @@ dnl Event
 _CONVERSION(`const Glib::RefPtr<Gst::Event>&',`GstEvent*', `Glib::unwrap($3)')
 _CONVERSION(`GstEvent*',`const Glib::RefPtr<Gst::Event>&', `Glib::wrap($3)')
 _CONVERSION(`GstEvent*',`Glib::RefPtr<Gst::Event>', `Glib::wrap($3)')
+_CONVERSION(`Glib::RefPtr<Gst::Event>&&',`GstEvent*',`($3) ? $3.release()->gobj() : nullptr')
 
 dnl Socket
 _CONVERSION(`const Glib::RefPtr<Gio::Socket>&',`GSocket*', `Glib::unwrap($3)')
@@ -194,6 +198,7 @@ _CONVERSION(`GstMemory*',`Glib::RefPtr<Gst::Memory>',`Glib::wrap($3)')
 _CONVERSION(`Glib::RefPtr<Gst::Memory>&',`GstMemory*', `Glib::unwrap($3)')
 _CONVERSION(`const Glib::RefPtr<Gst::Memory>&',`GstMemory*', `Glib::unwrap($3)')
 _CONVERSION(`Glib::RefPtr<Gst::Memory>',`GstMemory*', `Glib::unwrap($3)')
+_CONVERSION(`Glib::RefPtr<Gst::Memory>&&',`GstMemory*',`($3) ? $3.release()->gobj() : nullptr')
 
 dnl Message
 _CONVERSION(`GstMessage*',`Glib::RefPtr<Gst::Message>',`Glib::wrap($3)')


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