Signed-off-by: Carlos Rafael Giani <d...@pseudoterminal.org>
---
 Makefile.am         |   2 +-
 gst-decoder.c       |  20 ++++++++-
 gst-video-appsink.c | 126 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 gst-video-appsink.h |  31 +++++++++++++
 kmscube.c           |   2 +
 5 files changed, 178 insertions(+), 3 deletions(-)
 create mode 100644 gst-video-appsink.c
 create mode 100644 gst-video-appsink.h

diff --git a/Makefile.am b/Makefile.am
index a36087d..0407e89 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -57,5 +57,5 @@ kmscube_SOURCES = \
 if ENABLE_GST
 kmscube_LDADD += $(GST_LIBS)
 kmscube_CFLAGS += $(GST_CFLAGS)
-kmscube_SOURCES += cube-video.c gst-decoder.c
+kmscube_SOURCES += cube-video.c gst-decoder.c gst-video-appsink.c
 endif
diff --git a/gst-decoder.c b/gst-decoder.c
index 768aa1b..188fe4b 100644
--- a/gst-decoder.c
+++ b/gst-decoder.c
@@ -246,9 +246,25 @@ video_init(const struct egl *egl, const struct gbm *gbm, 
const char *filename)
        dec->gbm = gbm;
        dec->egl = egl;
 
-       /* Setup pipeline: */
+       /* Setup pipeline. Note that we use video_appsink here, not appsink.
+        * video_appsink is an appsink subclass that adds the videometa to
+        * the allocation query's list of metas supported by the sink.
+        *
+        * In some cases, sinks that do not declare videometa as supported
+        * can trigger unexpected behavior when used with video decoders.
+        * For example, with the v4l2videoNdec decoder, if the sink did not
+        * declare videometa as supported, and if the decoder detects that
+        * video frames have padding rows/columns (for example, a 1920x1088
+        * frame whose last 8 rows are padding rows), then it will perform
+        * an internal CPU-based copy that does not have these padding pixels.
+        *
+        * To avoid such CPU-based copies, make sure the sink declares
+        * videometa as supported. This has the side benefit that the code
+        * inside buffer_to_image() can also make use of the videmeta
+        * information.
+        */
        static const char *pipeline =
-               "filesrc name=\"src\" ! decodebin name=\"decode\" ! video/x-raw 
! appsink sync=false name=\"sink\"";
+               "filesrc name=\"src\" ! decodebin name=\"decode\" ! video/x-raw 
! video_appsink name=\"sink\"";
        dec->pipeline = gst_parse_launch(pipeline, NULL);
 
        dec->sink = gst_bin_get_by_name(GST_BIN(dec->pipeline), "sink");
diff --git a/gst-video-appsink.c b/gst-video-appsink.c
new file mode 100644
index 0000000..34e5931
--- /dev/null
+++ b/gst-video-appsink.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2017 Carlos Rafael Giani <d...@pseudoterminal.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include <gst/gst.h>
+#include <gst/app/app.h>
+#include <gst/video/video.h>
+#include "gst-video-appsink.h"
+
+
+typedef struct _GstVideoAppsink GstVideoAppsink;
+typedef struct _GstVideoAppsinkClass GstVideoAppsinkClass;
+
+
+#define GST_TYPE_VIDEO_APPSINK             (gst_video_appsink_get_type())
+#define GST_VIDEO_APPSINK(obj)             (G_TYPE_CHECK_INSTANCE_CAST((obj), 
GST_TYPE_VIDEO_APPSINK,GstVideoAppsink))
+#define GST_VIDEO_APPSINK_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST((klass), 
GST_TYPE_VIDEO_APPSINK, GstVideoAppsinkClass))
+#define GST_IS_VIDEO_APPSINK(obj)          (G_TYPE_CHECK_INSTANCE_TYPE((obj), 
GST_TYPE_VIDEO_APPSINK))
+#define GST_IS_VIDEO_APPSINK_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE((klass), 
GST_TYPE_VIDEO_APPSINK))
+
+
+struct _GstVideoAppsink
+{
+       GstAppSink parent;
+};
+
+
+struct _GstVideoAppsinkClass
+{
+       GstAppSinkClass parent_class;
+};
+
+
+GType gst_video_appsink_get_type(void);
+
+
+static gboolean gst_video_appsink_sink_propose_allocation (GstBaseSink *bsink, 
GstQuery *query);
+
+
+G_DEFINE_TYPE(GstVideoAppsink, gst_video_appsink, GST_TYPE_APP_SINK);
+
+
+static void
+gst_video_appsink_class_init(GstVideoAppsinkClass *klass)
+{
+       GstElementClass *element_class = GST_ELEMENT_CLASS(klass);
+       GstBaseSinkClass *base_sink_class = GST_BASE_SINK_CLASS(klass);
+
+       base_sink_class->propose_allocation =
+               GST_DEBUG_FUNCPTR(gst_video_appsink_sink_propose_allocation);
+
+       gst_element_class_set_static_metadata(
+               element_class,
+               "video appsink",
+               "Video/Sink",
+               "Appsink subclass for video streams (adds video meta)",
+               "Carlos Rafael Giani <d...@pseudoterminal.org>"
+       );
+}
+
+
+static void
+gst_video_appsink_init(GstVideoAppsink *video_appsink)
+{
+       (void)video_appsink;
+}
+
+
+static gboolean
+gst_video_appsink_sink_propose_allocation (GstBaseSink *bsink, GstQuery *query)
+{
+       (void)bsink;
+
+       gst_query_parse_allocation(query, NULL, NULL);
+
+       gst_query_add_allocation_meta(query, GST_VIDEO_META_API_TYPE, NULL);
+
+       return TRUE;
+}
+
+
+
+
+static gboolean
+init_internal_video_appsink_plugin(GstPlugin *plugin)
+{
+       gst_element_register(plugin, "video_appsink", GST_RANK_NONE, 
gst_video_appsink_get_type());
+       return TRUE;
+}
+
+
+void
+register_gst_video_appsink(void)
+{
+       gst_plugin_register_static(
+               GST_VERSION_MAJOR,
+               GST_VERSION_MINOR,
+               "internal video appsink plugin",
+               "internal video appsink plugin",
+               init_internal_video_appsink_plugin,
+               "1.0",
+               "BSD",
+               "kmscube",
+               "kmscube",
+               "kmscube"
+       );
+}
diff --git a/gst-video-appsink.h b/gst-video-appsink.h
new file mode 100644
index 0000000..d47484a
--- /dev/null
+++ b/gst-video-appsink.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2017 Carlos Rafael Giani <d...@pseudoterminal.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _GST_VIDEO_APPSINK_H
+#define _GST_VIDEO_APPSINK_H
+
+
+void register_gst_video_appsink(void);
+
+
+#endif /* _GST_VIDEO_APPSINK_H */
diff --git a/kmscube.c b/kmscube.c
index 2d55b97..ace73e9 100644
--- a/kmscube.c
+++ b/kmscube.c
@@ -33,6 +33,7 @@
 
 #ifdef HAVE_GST
 #include <gst/gst.h>
+#include "gst-video-appsink.h"
 GST_DEBUG_CATEGORY(kmscube_debug);
 #endif
 
@@ -79,6 +80,7 @@ int main(int argc, char *argv[])
 #ifdef HAVE_GST
        gst_init(&argc, &argv);
        GST_DEBUG_CATEGORY_INIT(kmscube_debug, "kmscube", 0, "kmscube video 
pipeline");
+       register_gst_video_appsink();
 #endif
 
        while ((opt = getopt_long_only(argc, argv, shortopts, longopts, NULL)) 
!= -1) {
-- 
2.7.4

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to