[gstreamermm] Gst::BaseSink: fix refs of basesink's virtual methods return values



commit b51a438c9e7c054e3e1f2e8142bf52d2712b3af6
Author: Michał Wróbel <michal wrobel flytronic pl>
Date:   Sun Jun 28 00:56:36 2015 +0200

    Gst::BaseSink: fix refs of basesink's virtual methods return values
    
    This is https://bugzilla.gnome.org/show_bug.cgi?id=751601 in progress.
    
        * gstreamer/src/basesink.hg: fix virtual methods: get_caps_vfunc and
          fixate_vfunc.
        * tests/Makefile.am:
        * tests/plugins/derivedfromappsink.h
        * tests/plugins/test-plugin-appsink.cc:
        * tests/plugins/test-plugin-derivedfromappsink.cc: add some test for
          appsink class.

 gstreamer/src/basesink.hg                       |    6 +-
 tests/Makefile.am                               |    2 +
 tests/plugins/derivedfromappsink.h              |   30 ++++++
 tests/plugins/test-plugin-appsink.cc            |   70 +++++++++++---
 tests/plugins/test-plugin-derivedfromappsink.cc |  120 +++++++++++++++++++++++
 5 files changed, 211 insertions(+), 17 deletions(-)
---
diff --git a/gstreamer/src/basesink.hg b/gstreamer/src/basesink.hg
index c862c8f..0b7d2c8 100644
--- a/gstreamer/src/basesink.hg
+++ b/gstreamer/src/basesink.hg
@@ -234,11 +234,11 @@ public:
 
 
 #m4 _CONVERSION(`Glib::RefPtr<Gst::Caps>', `GstCaps*', `Glib::unwrap($3)')
+#m4 _CONVERSION(`GstCaps*', `const Glib::RefPtr<Gst::Caps>&', `Glib::wrap($3, true)')
   /** Called to get sink pad caps from the subclass.
    */
-  _WRAP_VFUNC(Glib::RefPtr<Gst::Caps> get_caps(Glib::RefPtr<Gst::Caps> caps) const, "get_caps")
+  _WRAP_VFUNC(Glib::RefPtr<Gst::Caps> get_caps(const Glib::RefPtr<Gst::Caps>& caps) const, "get_caps", 
refreturn_ctype)
 
-#m4 _CONVERSION(`GstCaps*', `const Glib::RefPtr<Gst::Caps>&', `Glib::wrap($3, true)')
   /** Notify subclass of changed caps.
    */
   _WRAP_VFUNC(bool set_caps(const Glib::RefPtr<Gst::Caps>& caps), "set_caps", return_value true)
@@ -295,7 +295,7 @@ public:
    * have ideas about what should be the default values for the caps you
    * support.
    */
-  _WRAP_VFUNC(Glib::RefPtr<Gst::Caps> fixate(const Glib::RefPtr<Gst::Caps>& caps), "fixate")
+  _WRAP_VFUNC(Glib::RefPtr<Gst::Caps> fixate(const Glib::RefPtr<Gst::Caps>& caps), "fixate", refreturn_ctype)
 
   /** Clear the previous unlock request. Subclasses should clear any state they
    * set during unlock_vfunc(), such as clearing command queues.
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 52f5d1e..4cdc224 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -43,6 +43,7 @@ check_PROGRAMS =                                \
                                                 \
         test-plugin-appsink                     \
         test-plugin-appsrc                      \
+        test-plugin-derivedfromappsink          \
         test-plugin-derivedfromappsrc           \
         test-plugin-derivedfrombasetransform    \
         test-plugin-pushsrc                     \
@@ -81,6 +82,7 @@ test_urihandler_SOURCES                         = test-urihandler.cc
 
 test_plugin_appsink_SOURCES                     = plugins/test-plugin-appsink.cc                     
$(TEST_MAIN_SOURCE)
 test_plugin_appsrc_SOURCES                      = plugins/test-plugin-appsrc.cc                      
$(TEST_MAIN_SOURCE)
+test_plugin_derivedfromappsink_SOURCES          = plugins/test-plugin-derivedfromappsink.cc          
$(TEST_MAIN_SOURCE)
 test_plugin_derivedfromappsrc_SOURCES           = plugins/test-plugin-derivedfromappsrc.cc           
$(TEST_MAIN_SOURCE)
 test_plugin_derivedfrombasetransform_SOURCES    = plugins/test-plugin-derivedfrombasetransform.cc    
$(TEST_MAIN_SOURCE)
 test_plugin_pushsrc_SOURCES                     = plugins/test-plugin-pushsrc.cc                     
$(TEST_MAIN_SOURCE)
diff --git a/tests/plugins/derivedfromappsink.h b/tests/plugins/derivedfromappsink.h
new file mode 100644
index 0000000..0941cdd
--- /dev/null
+++ b/tests/plugins/derivedfromappsink.h
@@ -0,0 +1,30 @@
+#ifndef TEST_DERIVEDFROMAPPSINK_H_
+#define TEST_DERIVEDFROMAPPSINK_H_
+
+#include <gst/app/gstappsink.h>
+#include <gstreamermm.h>
+#include <gstreamermm/private/appsink_p.h>
+#include <assert.h>
+
+class DerivedFromAppSink : public Gst::AppSink
+{
+public:
+    static void base_init(Gst::ElementClass<DerivedFromAppSink> *klass)
+    {
+        klass->set_metadata("derivedfromappsink_longname",
+                "derivedfromappsink_classification", "derivedfromappsink_detail_description", 
"derivedfromappsink_detail_author");
+    }
+
+    explicit DerivedFromAppSink(GstAppSink *gobj)
+        : Glib::ObjectBase(typeid (DerivedFromAppSink)), // type must be registered before use
+          Gst::AppSink(gobj)
+    {
+    }
+
+    static bool register_element(Glib::RefPtr<Gst::Plugin> plugin)
+    {
+        return Gst::ElementFactory::register_element(plugin, "derivedfromappsink", 10, 
Gst::register_mm_type<DerivedFromAppSink>("derivedfromappsink"));
+    }
+};
+
+#endif /* TEST_DERIVEDFROMAPPSINK_H_ */
diff --git a/tests/plugins/test-plugin-appsink.cc b/tests/plugins/test-plugin-appsink.cc
index 374fa14..eb0c0dc 100644
--- a/tests/plugins/test-plugin-appsink.cc
+++ b/tests/plugins/test-plugin-appsink.cc
@@ -24,8 +24,8 @@ protected:
     {
         pipeline = Gst::Pipeline::create();
 
-        source = ElementFactory::create_element("appsrc", "source");
         sink = ElementFactory::create_element("appsink", "sink");
+        source = ElementFactory::create_element("appsrc", "source");
 
         ASSERT_TRUE(sink);
         ASSERT_TRUE(source);
@@ -35,28 +35,75 @@ protected:
     }
 };
 
+TEST_F(AppSinkPluginTest, CorrectCreatedAppSinkElement)
+{
+    RefPtr<AppSink> source = AppSink::create("sink");
+    ASSERT_TRUE(source);
+
+    RefPtr<Element> source_element = ElementFactory::create_element("appsink", "source");
+    ASSERT_TRUE(source_element);
+
+    source = source.cast_dynamic(source_element);
+    ASSERT_TRUE(source);
+}
+
 TEST_F(AppSinkPluginTest, CreatePipelineWithAppsink)
 {
     CreatePipelineWithElements();
 }
 
+TEST_F(AppSinkPluginTest, SinkPadQueryCapsShouldReturnProperCapsObjects)
+{
+    CreatePipelineWithElements();
+
+    RefPtr<BaseSink> basesink;
+    basesink = basesink.cast_dynamic(sink);
+    ASSERT_TRUE(basesink);
+
+    RefPtr<Pad> sink_pad = basesink->get_sink_pad();
+    ASSERT_TRUE(sink_pad);
+    ASSERT_TRUE(GST_IS_PAD(sink_pad->gobj()));
+    RefPtr<Caps> caps = sink_pad->query_caps(Caps::create_any());
+    ASSERT_TRUE(caps);
+    ASSERT_TRUE(caps->gobj());
+    ASSERT_TRUE(GST_IS_CAPS(caps->gobj()));
+    RefPtr<Caps> template_caps = Glib::wrap(gst_pad_get_pad_template_caps(sink_pad->gobj()), false);
+
+    sink_pad.reset();
+    basesink.reset();
+    sink.reset();
+    pipeline.reset();
+
+    // query_caps may return just another ref to template_caps
+    if (caps == template_caps)
+    {
+        // ...but template_caps might be just another ref to static caps with some higher unknown refcount
+        //EXPECT_EQ(2, caps->get_refcount());
+    }
+    else
+    {
+        EXPECT_EQ(1, caps->get_refcount());
+    }
+}
+
 TEST_F(AppSinkPluginTest, UseAppSinkDuringDataFlowInPipeline)
 {
     CreatePipelineWithElements();
+
     RefPtr<AppSink> appsink = appsink.cast_static(sink);
     RefPtr<AppSrc> appsrc = appsrc.cast_static(source);
 
-    pipeline->set_state(STATE_PLAYING);
+    EXPECT_EQ(STATE_CHANGE_ASYNC, pipeline->set_state(STATE_PLAYING));
 
     std::string data = "hello world";
     RefPtr<Buffer> buf = Buffer::create(data.length() + 1);
-
+    ASSERT_TRUE(buf);
     RefPtr<MapInfo> map_info(new MapInfo());
-    buf->map(map_info, MAP_WRITE);
+    ASSERT_TRUE(buf->map(map_info, MAP_WRITE));
     strcpy((char *)map_info->get_data(), data.c_str());
     buf->unmap(map_info);
 
-    appsrc->push_buffer(buf);
+    EXPECT_EQ(FLOW_OK, appsrc->push_buffer(buf));
 
     RefPtr<Buffer> buf_out;
     RefPtr<Sample> sample = appsink->pull_sample();
@@ -64,17 +111,12 @@ TEST_F(AppSinkPluginTest, UseAppSinkDuringDataFlowInPipeline)
     buf_out = sample->get_buffer();
     ASSERT_TRUE(buf_out);
 
-    ASSERT_TRUE(buf_out->memcmp(0, data.c_str(), data.length()) == 0);
+    EXPECT_TRUE(buf_out->memcmp(0, data.c_str(), data.length()) == 0);
 
-    appsrc->end_of_stream();
+    EXPECT_EQ(FLOW_OK, appsrc->end_of_stream());
 
     RefPtr<Message> msg = pipeline->get_bus()->poll((MessageType)(MESSAGE_EOS | MESSAGE_ERROR) , 1*SECOND);
     ASSERT_TRUE(msg);
-    ASSERT_EQ(MESSAGE_EOS, msg->get_message_type());
-
-    pipeline->set_state(STATE_NULL);
+    EXPECT_EQ(MESSAGE_EOS, msg->get_message_type());
+    EXPECT_EQ(STATE_CHANGE_SUCCESS, pipeline->set_state(STATE_NULL));
 }
-
-
-
-
diff --git a/tests/plugins/test-plugin-derivedfromappsink.cc b/tests/plugins/test-plugin-derivedfromappsink.cc
new file mode 100644
index 0000000..87263ca
--- /dev/null
+++ b/tests/plugins/test-plugin-derivedfromappsink.cc
@@ -0,0 +1,120 @@
+#include <gtest/gtest.h>
+#include <gstreamermm.h>
+#include <gstreamermm/appsrc.h>
+#include <gstreamermm/appsink.h>
+
+#include "derivedfromappsink.h"
+
+using namespace Gst;
+using Glib::RefPtr;
+
+class DerivedFromAppSinkPluginTest : public ::testing::Test
+{
+protected:
+    RefPtr<Element> source;
+    RefPtr<Element> sink;
+    RefPtr<Pipeline> pipeline;
+
+    void CreatePipelineWithElements()
+    {
+        pipeline = Gst::Pipeline::create();
+
+        sink = ElementFactory::create_element("derivedfromappsink", "sink");
+        source = ElementFactory::create_element("appsrc", "source");
+
+        ASSERT_TRUE(sink);
+        ASSERT_TRUE(source);
+
+        ASSERT_NO_THROW(pipeline->add(source)->add(sink));
+        ASSERT_NO_THROW(source->link(sink));
+    }
+
+    virtual void SetUp()
+    {
+        Plugin::register_static(GST_VERSION_MAJOR, GST_VERSION_MINOR, "derivedfromappsink",
+            "derivedfromappsink is an example of C++ element derived from Gst::AppSink",
+            sigc::ptr_fun(&DerivedFromAppSink::register_element), "0.123",
+            "LGPL", "source?", "package?", "http://example.com";);
+    }
+};
+
+TEST_F(DerivedFromAppSinkPluginTest, CreateRegisteredElement)
+{
+    RefPtr<Element> sink_element = ElementFactory::create_element("derivedfromappsink", "source");
+
+    ASSERT_TRUE(sink_element);
+}
+
+TEST_F(DerivedFromAppSinkPluginTest, CreatePipelineWithRegisteredElement)
+{
+    CreatePipelineWithElements();
+}
+
+TEST_F(DerivedFromAppSinkPluginTest, SinkPadQueryCapsShouldReturnProperCapsObjects)
+{
+    CreatePipelineWithElements();
+
+    RefPtr<BaseSink> basesink;
+    basesink = basesink.cast_dynamic(sink);
+    ASSERT_TRUE(basesink);
+
+    RefPtr<Pad> sink_pad = basesink->get_sink_pad();
+    ASSERT_TRUE(sink_pad);
+    ASSERT_TRUE(GST_IS_PAD(sink_pad->gobj()));
+    RefPtr<Caps> caps = sink_pad->query_caps(Caps::create_any());
+    ASSERT_TRUE(caps);
+    ASSERT_TRUE(caps->gobj());
+    ASSERT_TRUE(GST_IS_CAPS(caps->gobj()));
+    RefPtr<Caps> template_caps = Glib::wrap(gst_pad_get_pad_template_caps(sink_pad->gobj()), false);
+
+    sink_pad.reset();
+    basesink.reset();
+    sink.reset();
+    pipeline.reset();
+
+    // query_caps may return just another ref to template_caps
+    if (caps == template_caps)
+    {
+        // ...but template_caps might be just another ref to static caps with some higher unknown refcount
+        //EXPECT_EQ(2, caps->get_refcount());
+    }
+    else
+    {
+        EXPECT_EQ(1, caps->get_refcount());
+    }
+}
+
+TEST_F(DerivedFromAppSinkPluginTest, UseAppSinkDuringDataFlowInPipeline)
+{
+    CreatePipelineWithElements();
+
+    RefPtr<AppSink> appsink = appsink.cast_static(sink);
+    RefPtr<AppSrc> appsrc = appsrc.cast_static(source);
+
+    EXPECT_EQ(STATE_CHANGE_ASYNC, pipeline->set_state(STATE_PLAYING));
+
+    std::string data = "hello world";
+    RefPtr<Buffer> buf = Buffer::create(data.length() + 1);
+    ASSERT_TRUE(buf);
+    RefPtr<MapInfo> map_info(new MapInfo());
+    ASSERT_TRUE(buf->map(map_info, MAP_WRITE));
+    strcpy((char *)map_info->get_data(), data.c_str());
+    buf->unmap(map_info);
+
+    EXPECT_EQ(FLOW_OK, appsrc->push_buffer(buf));
+
+    RefPtr<Buffer> buf_out;
+    RefPtr<Sample> sample = appsink->pull_sample();
+    ASSERT_TRUE(sample);
+    buf_out = sample->get_buffer();
+    ASSERT_TRUE(buf_out);
+
+    EXPECT_TRUE(buf_out->memcmp(0, data.c_str(), data.length()) == 0);
+
+    EXPECT_EQ(FLOW_OK, appsrc->end_of_stream());
+
+    RefPtr<Message> msg = pipeline->get_bus()->poll((MessageType)(MESSAGE_EOS | MESSAGE_ERROR) , 1*SECOND);
+    ASSERT_TRUE(msg);
+    EXPECT_EQ(MESSAGE_EOS, msg->get_message_type());
+    EXPECT_EQ(STATE_CHANGE_SUCCESS, pipeline->set_state(STATE_NULL));
+}


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