[gstreamermm] Gst::BaseSink: fix refs of basesink's virtual methods return values
- From: Marcin Kolny <mkolny src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gstreamermm] Gst::BaseSink: fix refs of basesink's virtual methods return values
- Date: Mon, 29 Jun 2015 09:27:27 +0000 (UTC)
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]