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