From 3e72da3eb1260166a3d1709f6dd71db8b3a97625 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Tue, 12 Jan 2016 17:03:16 -0500 Subject: build: drop gstreamer support --- Makefile.am | 4 - cogl-gst/Makefile.am | 107 -- cogl-gst/cogl-gst-1.0.pc.in | 13 - cogl-gst/cogl-gst-2.0-experimental.pc.in | 13 - cogl-gst/cogl-gst-plugin.c | 57 - cogl-gst/cogl-gst-video-sink.c | 1743 ------------------------------ cogl-gst/cogl-gst-video-sink.h | 533 --------- cogl-gst/cogl-gst.h | 35 - cogl-gst/cogl-gst.pc.in | 13 - configure.ac | 50 - 10 files changed, 2568 deletions(-) delete mode 100644 cogl-gst/Makefile.am delete mode 100644 cogl-gst/cogl-gst-1.0.pc.in delete mode 100644 cogl-gst/cogl-gst-2.0-experimental.pc.in delete mode 100644 cogl-gst/cogl-gst-plugin.c delete mode 100644 cogl-gst/cogl-gst-video-sink.c delete mode 100644 cogl-gst/cogl-gst-video-sink.h delete mode 100644 cogl-gst/cogl-gst.h delete mode 100644 cogl-gst/cogl-gst.pc.in diff --git a/Makefile.am b/Makefile.am index dfe2234f..9080fbe3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -14,10 +14,6 @@ if BUILD_COGL_GLES2 SUBDIRS += cogl-gles2 endif -if BUILD_COGL_GST -SUBDIRS += cogl-gst -endif - SUBDIRS += po build ACLOCAL_AMFLAGS = -I build/autotools ${ACLOCAL_FLAGS} diff --git a/cogl-gst/Makefile.am b/cogl-gst/Makefile.am deleted file mode 100644 index 0395e29c..00000000 --- a/cogl-gst/Makefile.am +++ /dev/null @@ -1,107 +0,0 @@ -include $(top_srcdir)/build/autotools/Makefile.am.silent - -NULL = - -CLEANFILES = -DISTCLEANFILES = - -EXTRA_DIST = - -source_c = \ - cogl-gst-video-sink.c \ - $(NULL) - -source_h = \ - cogl-gst.h \ - cogl-gst-video-sink.h \ - $(NULL) - -lib_LTLIBRARIES = libcogl-gst.la - -libcogl_gst_la_SOURCES = $(source_c) $(source_h) -libcogl_gst_la_CFLAGS = $(COGL_DEP_CFLAGS) $(COGL_GST_DEP_CFLAGS) $(COGL_EXTRA_CFLAGS) $(MAINTAINER_CFLAGS) -libcogl_gst_la_LIBADD = $(top_builddir)/cogl/libcogl.la -libcogl_gst_la_LIBADD += $(COGL_DEP_LIBS) $(COGL_GST_DEP_LIBS) $(COGL_EXTRA_LDFLAGS) -libcogl_gst_la_LDFLAGS = \ - -export-dynamic \ - -export-symbols-regex "^cogl_gst_.*" \ - -no-undefined \ - -version-info @COGL_LT_CURRENT@:@COGL_LT_REVISION@:@COGL_LT_AGE@ \ - -rpath $(libdir) - -AM_CPPFLAGS = \ - -DCOGL_COMPILATION \ - -DG_LOG_DOMAIN=\"CoglGst\" \ - -I$(top_srcdir)/cogl \ - -I$(top_builddir)/cogl \ - -I$(top_srcdir)/cogl/winsys \ - -I$(top_srcdir) \ - -I$(top_builddir) - -cogl_gstheadersdir = $(includedir)/cogl/cogl-gst -cogl_gstheaders_HEADERS = $(source_h) - -plugin_source_c = \ - cogl-gst-plugin.c \ - $(NULL) - -libgstcogl_la_SOURCES = \ - $(plugin_source_c) \ - $(NULL) - -plugin_LTLIBRARIES = libgstcogl.la - -libgstcogl_la_CFLAGS = $(COGL_DEP_CFLAGS) $(COGL_GST_DEP_CFLAGS) $(COGL_EXTRA_CFLAGS) $(MAINTAINER_CFLAGS) -libgstcogl_la_LIBADD = \ - $(top_builddir)/cogl/libcogl.la \ - $(builddir)/libcogl-gst.la -libgstcogl_la_LIBADD += $(COGL_DEP_LIBS) $(COGL_GST_DEP_LIBS) $(COGL_EXTRA_LDFLAGS) -libgstcogl_la_LDFLAGS = \ - -avoid-version -no-undefined \ - $(NULL) - -pc_files = cogl-gst-1.0.pc \ - cogl-gst-2.0-experimental.pc - -pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = $(pc_files) - -EXTRA_DIST += cogl-gst.pc.in -DISTCLEANFILES += $(pc_files) - --include $(INTROSPECTION_MAKEFILE) - -INTROSPECTION_GIRS = - -if HAVE_INTROSPECTION -INTROSPECTION_COMPILER_ARGS=--includedir=$(top_builddir)/cogl - -CoglGst-2.0.gir: libcogl-gst.la Makefile - -CoglGst_2_0_gir_NAMESPACE = CoglGst -CoglGst_2_0_gir_VERSION = 2.0 -CoglGst_2_0_gir_LIBS = $(top_builddir)/cogl/libcogl.la libcogl-gst.la -CoglGst_2_0_gir_FILES = $(source_h) $(source_c) -CoglGst_2_0_gir_CFLAGS = $(AM_CPPFLAGS) $(COGL_GST_DEP_CFLAGS) -CoglGst_2_0_gir_INCLUDES = GObject-2.0 Gst-1.0 GstBase-1.0 -CoglGst_2_0_gir_EXPORT_PACKAGES = cogl-gst-2.0-experimental -CoglGst_2_0_gir_SCANNERFLAGS = \ - --warn-all \ - --identifier-prefix=CoglGst \ - --symbol-prefix=cogl_gst \ - --c-include='cogl-gst/cogl-gst.h' \ - --c-include="gst/gst.h" \ - --include-uninstalled=$(top_builddir)/cogl/Cogl-2.0.gir \ - --pkg gstreamer-1.0 \ - --add-init-section="gst_init(NULL, NULL);" - -INTROSPECTION_GIRS += CoglGst-2.0.gir - -girdir = $(datadir)/gir-1.0 -gir_DATA = $(INTROSPECTION_GIRS) - -typelibdir = $(libdir)/girepository-1.0 -typelib_DATA = $(INTROSPECTION_GIRS:.gir=.typelib) - -CLEANFILES += $(gir_DATA) $(typelib_DATA) -endif diff --git a/cogl-gst/cogl-gst-1.0.pc.in b/cogl-gst/cogl-gst-1.0.pc.in deleted file mode 100644 index b3189ca0..00000000 --- a/cogl-gst/cogl-gst-1.0.pc.in +++ /dev/null @@ -1,13 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ -apiversion=1.0 -requires=@COGL_PKG_REQUIRES@ cogl-1.0 - -Name: Cogl -Description: A GStreamer integration library for Cogl -Version: @COGL_1_VERSION@ -Libs: -L${libdir} -lcogl-gst -Cflags: -I${includedir}/cogl -Requires: ${requires} diff --git a/cogl-gst/cogl-gst-2.0-experimental.pc.in b/cogl-gst/cogl-gst-2.0-experimental.pc.in deleted file mode 100644 index 3a82751d..00000000 --- a/cogl-gst/cogl-gst-2.0-experimental.pc.in +++ /dev/null @@ -1,13 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ -apiversion=@COGL_API_VERSION@ -requires=@COGL_PKG_REQUIRES@ cogl-2.0-experimental - -Name: Cogl -Description: A GStreamer integration library for Cogl -Version: @COGL_1_VERSION@ -Libs: -L${libdir} -lcogl-gst -Cflags: -I${includedir}/cogl -Requires: ${requires} diff --git a/cogl-gst/cogl-gst-plugin.c b/cogl-gst/cogl-gst-plugin.c deleted file mode 100644 index 20b1e59a..00000000 --- a/cogl-gst/cogl-gst-plugin.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007, 2008 OpenedHand - * Copyright (C) 2009, 2010, 2013 Intel Corporation - * - * 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, sublicense, 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 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 - * NONINFRINGEMENT. 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. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include "cogl-gst-video-sink.h" - -#define PACKAGE "CoglGst" - -static CoglBool -_plugin_init (GstPlugin *coglgstvideosink) -{ - return gst_element_register (coglgstvideosink, - "coglsink", - GST_RANK_PRIMARY, - COGL_GST_TYPE_VIDEO_SINK); -} - -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, - GST_VERSION_MINOR, - cogl, - "Sends video data from GStreamer to a Cogl pipeline", - _plugin_init, - COGL_VERSION_STRING, - "MIT/X11", - PACKAGE, - "http://cogl3d.org/") diff --git a/cogl-gst/cogl-gst-video-sink.c b/cogl-gst/cogl-gst-video-sink.c deleted file mode 100644 index eaa3e122..00000000 --- a/cogl-gst/cogl-gst-video-sink.c +++ /dev/null @@ -1,1743 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007, 2008 OpenedHand - * Copyright (C) 2009, 2010, 2013 Intel Corporation - * - * 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, sublicense, 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 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 - * NONINFRINGEMENT. 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 "config.h" - -#include -#include -#include -#include -#include - -#include "cogl-gtype-private.h" - -/* We just need the public Cogl api for cogl-gst but we first need to - * undef COGL_COMPILATION to avoid getting an error that normally - * checks cogl.h isn't used internally. */ -#undef COGL_COMPILATION -#include - -#include "cogl-gst-video-sink.h" - -#define COGL_GST_DEFAULT_PRIORITY G_PRIORITY_HIGH_IDLE - -#define BASE_SINK_CAPS "{ AYUV," \ - "YV12," \ - "I420," \ - "RGBA," \ - "BGRA," \ - "RGB," \ - "BGR," \ - "NV12 }" - -#define SINK_CAPS GST_VIDEO_CAPS_MAKE (BASE_SINK_CAPS) - -#define COGL_GST_PARAM_STATIC \ - (G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB) - -#define COGL_GST_PARAM_READABLE \ - (G_PARAM_READABLE | COGL_GST_PARAM_STATIC) - -#define COGL_GST_PARAM_WRITABLE \ - (G_PARAM_WRITABLE | COGL_GST_PARAM_STATIC) - -#define COGL_GST_PARAM_READWRITE \ - (G_PARAM_READABLE | G_PARAM_WRITABLE | COGL_GST_PARAM_STATIC) - -static GstStaticPadTemplate sinktemplate_all = - GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS (SINK_CAPS)); - -G_DEFINE_TYPE (CoglGstVideoSink, cogl_gst_video_sink, GST_TYPE_BASE_SINK); - -enum -{ - PROP_0, - PROP_UPDATE_PRIORITY -}; - -enum -{ - PIPELINE_READY_SIGNAL, - NEW_FRAME_SIGNAL, - - LAST_SIGNAL -}; - -static guint video_sink_signals[LAST_SIGNAL] = { 0, }; - -typedef enum -{ - COGL_GST_NOFORMAT, - COGL_GST_RGB32, - COGL_GST_RGB24, - COGL_GST_AYUV, - COGL_GST_YV12, - COGL_GST_SURFACE, - COGL_GST_I420, - COGL_GST_NV12 -} CoglGstVideoFormat; - -typedef enum -{ - COGL_GST_RENDERER_NEEDS_GLSL = (1 << 0), - COGL_GST_RENDERER_NEEDS_TEXTURE_RG = (1 << 1) -} CoglGstRendererFlag; - -/* We want to cache the snippets instead of recreating a new one every - * time we initialise a pipeline so that if we end up recreating the - * same pipeline again then Cogl will be able to use the pipeline - * cache to avoid linking a redundant identical shader program */ -typedef struct -{ - CoglSnippet *vertex_snippet; - CoglSnippet *fragment_snippet; - CoglSnippet *default_sample_snippet; - int start_position; -} SnippetCacheEntry; - -typedef struct -{ - GQueue entries; -} SnippetCache; - -typedef struct _CoglGstSource -{ - GSource source; - CoglGstVideoSink *sink; - GMutex buffer_lock; - GstBuffer *buffer; - CoglBool has_new_caps; -} CoglGstSource; - -typedef void (CoglGstRendererPaint) (CoglGstVideoSink *); -typedef void (CoglGstRendererPostPaint) (CoglGstVideoSink *); - -typedef struct _CoglGstRenderer -{ - const char *name; - CoglGstVideoFormat format; - int flags; - GstStaticCaps caps; - int n_layers; - void (*setup_pipeline) (CoglGstVideoSink *sink, - CoglPipeline *pipeline); - CoglBool (*upload) (CoglGstVideoSink *sink, - GstBuffer *buffer); -} CoglGstRenderer; - -struct _CoglGstVideoSinkPrivate -{ - CoglContext *ctx; - CoglPipeline *pipeline; - CoglTexture *frame[3]; - CoglBool frame_dirty; - CoglGstVideoFormat format; - CoglBool bgr; - CoglGstSource *source; - GSList *renderers; - GstCaps *caps; - CoglGstRenderer *renderer; - GstFlowReturn flow_return; - int custom_start; - int free_layer; - CoglBool default_sample; - GstVideoInfo info; -}; - -/* GTypes */ - -static gpointer -cogl_gst_rectangle_copy (gpointer src) -{ - if (G_LIKELY (src)) - { - CoglGstRectangle *new = g_slice_new (CoglGstRectangle); - memcpy (new, src, sizeof (CoglGstRectangle)); - return new; - } - else - return NULL; -} - -static void -cogl_gst_rectangle_free (gpointer ptr) -{ - g_slice_free (CoglGstRectangle, ptr); -} - -COGL_GTYPE_DEFINE_BOXED (GstRectangle, - gst_rectangle, - cogl_gst_rectangle_copy, - cogl_gst_rectangle_free); - -/**/ - -static void -cogl_gst_source_finalize (GSource *source) -{ - CoglGstSource *gst_source = (CoglGstSource *) source; - - g_mutex_lock (&gst_source->buffer_lock); - if (gst_source->buffer) - gst_buffer_unref (gst_source->buffer); - gst_source->buffer = NULL; - g_mutex_unlock (&gst_source->buffer_lock); - g_mutex_clear (&gst_source->buffer_lock); -} - -int -cogl_gst_video_sink_get_free_layer (CoglGstVideoSink *sink) -{ - return sink->priv->free_layer; -} - -void -cogl_gst_video_sink_attach_frame (CoglGstVideoSink *sink, - CoglPipeline *pln) -{ - CoglGstVideoSinkPrivate *priv = sink->priv; - int i; - - for (i = 0; i < G_N_ELEMENTS (priv->frame); i++) - if (priv->frame[i] != NULL) - cogl_pipeline_set_layer_texture (pln, i + priv->custom_start, - priv->frame[i]); -} - -static CoglBool -cogl_gst_source_prepare (GSource *source, - int *timeout) -{ - CoglGstSource *gst_source = (CoglGstSource *) source; - - *timeout = -1; - - return gst_source->buffer != NULL; -} - -static CoglBool -cogl_gst_source_check (GSource *source) -{ - CoglGstSource *gst_source = (CoglGstSource *) source; - - return gst_source->buffer != NULL; -} - -static void -cogl_gst_video_sink_set_priority (CoglGstVideoSink *sink, - int priority) -{ - if (sink->priv->source) - g_source_set_priority ((GSource *) sink->priv->source, priority); -} - -static void -dirty_default_pipeline (CoglGstVideoSink *sink) -{ - CoglGstVideoSinkPrivate *priv = sink->priv; - - if (priv->pipeline) - { - cogl_object_unref (priv->pipeline); - priv->pipeline = NULL; - } -} - -void -cogl_gst_video_sink_set_first_layer (CoglGstVideoSink *sink, - int first_layer) -{ - g_return_if_fail (COGL_GST_IS_VIDEO_SINK (sink)); - - if (first_layer != sink->priv->custom_start) - { - sink->priv->custom_start = first_layer; - dirty_default_pipeline (sink); - - if (sink->priv->renderer) - sink->priv->free_layer = (sink->priv->custom_start + - sink->priv->renderer->n_layers); - } -} - -void -cogl_gst_video_sink_set_default_sample (CoglGstVideoSink *sink, - CoglBool default_sample) -{ - g_return_if_fail (COGL_GST_IS_VIDEO_SINK (sink)); - - if (default_sample != sink->priv->default_sample) - { - sink->priv->default_sample = default_sample; - dirty_default_pipeline (sink); - } -} - -void -cogl_gst_video_sink_setup_pipeline (CoglGstVideoSink *sink, - CoglPipeline *pipeline) -{ - g_return_if_fail (COGL_GST_IS_VIDEO_SINK (sink)); - - if (sink->priv->renderer) - sink->priv->renderer->setup_pipeline (sink, pipeline); -} - -static SnippetCacheEntry * -get_cache_entry (CoglGstVideoSink *sink, - SnippetCache *cache) -{ - CoglGstVideoSinkPrivate *priv = sink->priv; - GList *l; - - for (l = cache->entries.head; l; l = l->next) - { - SnippetCacheEntry *entry = l->data; - - if (entry->start_position == priv->custom_start) - return entry; - } - - return NULL; -} - -static SnippetCacheEntry * -add_cache_entry (CoglGstVideoSink *sink, - SnippetCache *cache, - const char *decl) -{ - CoglGstVideoSinkPrivate *priv = sink->priv; - SnippetCacheEntry *entry = g_slice_new (SnippetCacheEntry); - char *default_source; - - entry->start_position = priv->custom_start; - - entry->vertex_snippet = - cogl_snippet_new (COGL_SNIPPET_HOOK_VERTEX_GLOBALS, - decl, - NULL /* post */); - entry->fragment_snippet = - cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT_GLOBALS, - decl, - NULL /* post */); - - default_source = - g_strdup_printf (" cogl_layer *= cogl_gst_sample_video%i " - "(cogl_tex_coord%i_in.st);\n", - priv->custom_start, - priv->custom_start); - entry->default_sample_snippet = - cogl_snippet_new (COGL_SNIPPET_HOOK_LAYER_FRAGMENT, - NULL, /* declarations */ - default_source); - g_free (default_source); - - g_queue_push_head (&cache->entries, entry); - - return entry; -} - -static void -setup_pipeline_from_cache_entry (CoglGstVideoSink *sink, - CoglPipeline *pipeline, - SnippetCacheEntry *cache_entry, - int n_layers) -{ - CoglGstVideoSinkPrivate *priv = sink->priv; - - if (cache_entry) - { - int i; - - /* The global sampling function gets added to both the fragment - * and vertex stages. The hope is that the GLSL compiler will - * easily remove the dead code if it's not actually used */ - cogl_pipeline_add_snippet (pipeline, cache_entry->vertex_snippet); - cogl_pipeline_add_snippet (pipeline, cache_entry->fragment_snippet); - - /* Set all of the layers to just directly copy from the previous - * layer so that it won't redundantly generate code to sample - * the intermediate textures */ - for (i = 0; i < n_layers; i++) - cogl_pipeline_set_layer_combine (pipeline, - priv->custom_start + i, - "RGBA=REPLACE(PREVIOUS)", - NULL); - - if (priv->default_sample) - cogl_pipeline_add_layer_snippet (pipeline, - priv->custom_start + n_layers - 1, - cache_entry->default_sample_snippet); - } - - priv->frame_dirty = TRUE; -} - -CoglPipeline * -cogl_gst_video_sink_get_pipeline (CoglGstVideoSink *vt) -{ - CoglGstVideoSinkPrivate *priv; - - g_return_val_if_fail (COGL_GST_IS_VIDEO_SINK (vt), NULL); - - priv = vt->priv; - - if (priv->pipeline == NULL) - { - priv->pipeline = cogl_pipeline_new (priv->ctx); - cogl_gst_video_sink_setup_pipeline (vt, priv->pipeline); - cogl_gst_video_sink_attach_frame (vt, priv->pipeline); - priv->frame_dirty = FALSE; - } - else if (priv->frame_dirty) - { - CoglPipeline *pipeline = cogl_pipeline_copy (priv->pipeline); - cogl_object_unref (priv->pipeline); - priv->pipeline = pipeline; - - cogl_gst_video_sink_attach_frame (vt, pipeline); - priv->frame_dirty = FALSE; - } - - return priv->pipeline; -} - -static void -clear_frame_textures (CoglGstVideoSink *sink) -{ - CoglGstVideoSinkPrivate *priv = sink->priv; - int i; - - for (i = 0; i < G_N_ELEMENTS (priv->frame); i++) - { - if (priv->frame[i] == NULL) - break; - else - cogl_object_unref (priv->frame[i]); - } - - memset (priv->frame, 0, sizeof (priv->frame)); - - priv->frame_dirty = TRUE; -} - -static inline CoglBool -is_pot (unsigned int number) -{ - /* Make sure there is only one bit set */ - return (number & (number - 1)) == 0; -} - -/* This first tries to upload the texture to a CoglTexture2D, but - * if that's not possible it falls back to a CoglTexture2DSliced. - * - * Auto-mipmapping of any uploaded texture is disabled - */ -static CoglTexture * -video_texture_new_from_data (CoglContext *ctx, - int width, - int height, - CoglPixelFormat format, - int rowstride, - const uint8_t *data) -{ - CoglBitmap *bitmap; - CoglTexture *tex; - CoglError *internal_error = NULL; - - bitmap = cogl_bitmap_new_for_data (ctx, - width, height, - format, - rowstride, - (uint8_t *) data); - - if ((is_pot (cogl_bitmap_get_width (bitmap)) && - is_pot (cogl_bitmap_get_height (bitmap))) || - cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT_BASIC)) - { - tex = cogl_texture_2d_new_from_bitmap (bitmap); - - cogl_texture_set_premultiplied (tex, FALSE); - - if (!cogl_texture_allocate (tex, &internal_error)) - { - cogl_error_free (internal_error); - internal_error = NULL; - cogl_object_unref (tex); - tex = NULL; - } - } - else - tex = NULL; - - if (!tex) - { - /* Otherwise create a sliced texture */ - tex = cogl_texture_2d_sliced_new_from_bitmap (bitmap, - -1); /* no maximum waste */ - - cogl_texture_set_premultiplied (tex, FALSE); - - cogl_texture_allocate (tex, NULL); - } - - cogl_object_unref (bitmap); - - return tex; -} - -static void -cogl_gst_rgb24_glsl_setup_pipeline (CoglGstVideoSink *sink, - CoglPipeline *pipeline) -{ - CoglGstVideoSinkPrivate *priv = sink->priv; - static SnippetCache snippet_cache; - SnippetCacheEntry *entry = get_cache_entry (sink, &snippet_cache); - - if (entry == NULL) - { - char *source; - - source = - g_strdup_printf ("vec4\n" - "cogl_gst_sample_video%i (vec2 UV)\n" - "{\n" - " return texture2D (cogl_sampler%i, UV);\n" - "}\n", - priv->custom_start, - priv->custom_start); - - entry = add_cache_entry (sink, &snippet_cache, source); - g_free (source); - } - - setup_pipeline_from_cache_entry (sink, pipeline, entry, 1); -} - -static void -cogl_gst_rgb24_setup_pipeline (CoglGstVideoSink *sink, - CoglPipeline *pipeline) -{ - setup_pipeline_from_cache_entry (sink, pipeline, NULL, 1); -} - -static CoglBool -cogl_gst_rgb24_upload (CoglGstVideoSink *sink, - GstBuffer *buffer) -{ - CoglGstVideoSinkPrivate *priv = sink->priv; - CoglPixelFormat format; - GstVideoFrame frame; - - if (priv->bgr) - format = COGL_PIXEL_FORMAT_BGR_888; - else - format = COGL_PIXEL_FORMAT_RGB_888; - - if (!gst_video_frame_map (&frame, &priv->info, buffer, GST_MAP_READ)) - goto map_fail; - - clear_frame_textures (sink); - - priv->frame[0] = video_texture_new_from_data (priv->ctx, priv->info.width, - priv->info.height, - format, - priv->info.stride[0], - frame.data[0]); - - gst_video_frame_unmap (&frame); - - return TRUE; - -map_fail: - { - GST_ERROR_OBJECT (sink, "Could not map incoming video frame"); - return FALSE; - } -} - -static CoglGstRenderer rgb24_glsl_renderer = -{ - "RGB 24", - COGL_GST_RGB24, - COGL_GST_RENDERER_NEEDS_GLSL, - GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ RGB, BGR }")), - 1, /* n_layers */ - cogl_gst_rgb24_glsl_setup_pipeline, - cogl_gst_rgb24_upload, -}; - -static CoglGstRenderer rgb24_renderer = -{ - "RGB 24", - COGL_GST_RGB24, - 0, - GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ RGB, BGR }")), - 1, /* n_layers */ - cogl_gst_rgb24_setup_pipeline, - cogl_gst_rgb24_upload, -}; - -static void -cogl_gst_rgb32_glsl_setup_pipeline (CoglGstVideoSink *sink, - CoglPipeline *pipeline) -{ - CoglGstVideoSinkPrivate *priv = sink->priv; - static SnippetCache snippet_cache; - SnippetCacheEntry *entry = get_cache_entry (sink, &snippet_cache); - - if (entry == NULL) - { - char *source; - - source = - g_strdup_printf ("vec4\n" - "cogl_gst_sample_video%i (vec2 UV)\n" - "{\n" - " vec4 color = texture2D (cogl_sampler%i, UV);\n" - /* Premultiply the color */ - " color.rgb *= color.a;\n" - " return color;\n" - "}\n", - priv->custom_start, - priv->custom_start); - - entry = add_cache_entry (sink, &snippet_cache, source); - g_free (source); - } - - setup_pipeline_from_cache_entry (sink, pipeline, entry, 1); -} - -static void -cogl_gst_rgb32_setup_pipeline (CoglGstVideoSink *sink, - CoglPipeline *pipeline) -{ - CoglGstVideoSinkPrivate *priv = sink->priv; - char *layer_combine; - - setup_pipeline_from_cache_entry (sink, pipeline, NULL, 1); - - /* Premultiply the texture using the a special layer combine */ - layer_combine = g_strdup_printf ("RGB=MODULATE(PREVIOUS, TEXTURE_%i[A])\n" - "A=REPLACE(PREVIOUS[A])", - priv->custom_start); - cogl_pipeline_set_layer_combine (pipeline, - priv->custom_start + 1, - layer_combine, - NULL); - g_free(layer_combine); -} - -static CoglBool -cogl_gst_rgb32_upload (CoglGstVideoSink *sink, - GstBuffer *buffer) -{ - CoglGstVideoSinkPrivate *priv = sink->priv; - CoglPixelFormat format; - GstVideoFrame frame; - - if (priv->bgr) - format = COGL_PIXEL_FORMAT_BGRA_8888; - else - format = COGL_PIXEL_FORMAT_RGBA_8888; - - if (!gst_video_frame_map (&frame, &priv->info, buffer, GST_MAP_READ)) - goto map_fail; - - clear_frame_textures (sink); - - priv->frame[0] = video_texture_new_from_data (priv->ctx, priv->info.width, - priv->info.height, - format, - priv->info.stride[0], - frame.data[0]); - - gst_video_frame_unmap (&frame); - - return TRUE; - -map_fail: - { - GST_ERROR_OBJECT (sink, "Could not map incoming video frame"); - return FALSE; - } -} - -static CoglGstRenderer rgb32_glsl_renderer = -{ - "RGB 32", - COGL_GST_RGB32, - COGL_GST_RENDERER_NEEDS_GLSL, - GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ RGBA, BGRA }")), - 1, /* n_layers */ - cogl_gst_rgb32_glsl_setup_pipeline, - cogl_gst_rgb32_upload, -}; - -static CoglGstRenderer rgb32_renderer = -{ - "RGB 32", - COGL_GST_RGB32, - 0, - GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ RGBA, BGRA }")), - 2, /* n_layers */ - cogl_gst_rgb32_setup_pipeline, - cogl_gst_rgb32_upload, -}; - -static CoglBool -cogl_gst_yv12_upload (CoglGstVideoSink *sink, - GstBuffer *buffer) -{ - CoglGstVideoSinkPrivate *priv = sink->priv; - CoglPixelFormat format = COGL_PIXEL_FORMAT_A_8; - GstVideoFrame frame; - - if (!gst_video_frame_map (&frame, &priv->info, buffer, GST_MAP_READ)) - goto map_fail; - - clear_frame_textures (sink); - - priv->frame[0] = - video_texture_new_from_data (priv->ctx, - GST_VIDEO_INFO_COMP_WIDTH (&priv->info, 0), - GST_VIDEO_INFO_COMP_HEIGHT (&priv->info, 0), - format, - priv->info.stride[0], frame.data[0]); - - priv->frame[2] = - video_texture_new_from_data (priv->ctx, - GST_VIDEO_INFO_COMP_WIDTH (&priv->info, 1), - GST_VIDEO_INFO_COMP_HEIGHT (&priv->info, 1), - format, - priv->info.stride[1], frame.data[1]); - - priv->frame[1] = - video_texture_new_from_data (priv->ctx, - GST_VIDEO_INFO_COMP_WIDTH (&priv->info, 2), - GST_VIDEO_INFO_COMP_HEIGHT (&priv->info, 2), - format, - priv->info.stride[2], frame.data[2]); - - gst_video_frame_unmap (&frame); - - return TRUE; - -map_fail: - { - GST_ERROR_OBJECT (sink, "Could not map incoming video frame"); - return FALSE; - } -} - -static CoglBool -cogl_gst_i420_upload (CoglGstVideoSink *sink, - GstBuffer *buffer) -{ - CoglGstVideoSinkPrivate *priv = sink->priv; - CoglPixelFormat format = COGL_PIXEL_FORMAT_A_8; - GstVideoFrame frame; - - if (!gst_video_frame_map (&frame, &priv->info, buffer, GST_MAP_READ)) - goto map_fail; - - clear_frame_textures (sink); - - priv->frame[0] = - video_texture_new_from_data (priv->ctx, - GST_VIDEO_INFO_COMP_WIDTH (&priv->info, 0), - GST_VIDEO_INFO_COMP_HEIGHT (&priv->info, 0), - format, - priv->info.stride[0], frame.data[0]); - - priv->frame[1] = - video_texture_new_from_data (priv->ctx, - GST_VIDEO_INFO_COMP_WIDTH (&priv->info, 1), - GST_VIDEO_INFO_COMP_HEIGHT (&priv->info, 1), - format, - priv->info.stride[1], frame.data[1]); - - priv->frame[2] = - video_texture_new_from_data (priv->ctx, - GST_VIDEO_INFO_COMP_WIDTH (&priv->info, 2), - GST_VIDEO_INFO_COMP_HEIGHT (&priv->info, 2), - format, - priv->info.stride[2], frame.data[2]); - - gst_video_frame_unmap (&frame); - - return TRUE; - -map_fail: - { - GST_ERROR_OBJECT (sink, "Could not map incoming video frame"); - return FALSE; - } -} - -static void -cogl_gst_yv12_glsl_setup_pipeline (CoglGstVideoSink *sink, - CoglPipeline *pipeline) -{ - CoglGstVideoSinkPrivate *priv = sink->priv; - static SnippetCache snippet_cache; - SnippetCacheEntry *entry; - - entry = get_cache_entry (sink, &snippet_cache); - - if (entry == NULL) - { - char *source; - - source = - g_strdup_printf ("vec4\n" - "cogl_gst_sample_video%i (vec2 UV)\n" - "{\n" - " float y = 1.1640625 * " - "(texture2D (cogl_sampler%i, UV).a - 0.0625);\n" - " float u = texture2D (cogl_sampler%i, UV).a - 0.5;\n" - " float v = texture2D (cogl_sampler%i, UV).a - 0.5;\n" - " vec4 color;\n" - " color.r = y + 1.59765625 * v;\n" - " color.g = y - 0.390625 * u - 0.8125 * v;\n" - " color.b = y + 2.015625 * u;\n" - " color.a = 1.0;\n" - " return color;\n" - "}\n", - priv->custom_start, - priv->custom_start, - priv->custom_start + 1, - priv->custom_start + 2); - - entry = add_cache_entry (sink, &snippet_cache, source); - g_free (source); - } - - setup_pipeline_from_cache_entry (sink, pipeline, entry, 3); -} - -static CoglGstRenderer yv12_glsl_renderer = -{ - "YV12 glsl", - COGL_GST_YV12, - COGL_GST_RENDERER_NEEDS_GLSL, - GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("YV12")), - 3, /* n_layers */ - cogl_gst_yv12_glsl_setup_pipeline, - cogl_gst_yv12_upload, -}; - -static CoglGstRenderer i420_glsl_renderer = -{ - "I420 glsl", - COGL_GST_I420, - COGL_GST_RENDERER_NEEDS_GLSL, - GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("I420")), - 3, /* n_layers */ - cogl_gst_yv12_glsl_setup_pipeline, - cogl_gst_i420_upload, -}; - -static void -cogl_gst_ayuv_glsl_setup_pipeline (CoglGstVideoSink *sink, - CoglPipeline *pipeline) -{ - CoglGstVideoSinkPrivate *priv = sink->priv; - static SnippetCache snippet_cache; - SnippetCacheEntry *entry; - - entry = get_cache_entry (sink, &snippet_cache); - - if (entry == NULL) - { - char *source; - - source - = g_strdup_printf ("vec4\n" - "cogl_gst_sample_video%i (vec2 UV)\n" - "{\n" - " vec4 color = texture2D (cogl_sampler%i, UV);\n" - " float y = 1.1640625 * (color.g - 0.0625);\n" - " float u = color.b - 0.5;\n" - " float v = color.a - 0.5;\n" - " color.a = color.r;\n" - " color.r = y + 1.59765625 * v;\n" - " color.g = y - 0.390625 * u - 0.8125 * v;\n" - " color.b = y + 2.015625 * u;\n" - /* Premultiply the color */ - " color.rgb *= color.a;\n" - " return color;\n" - "}\n", priv->custom_start, - priv->custom_start); - - entry = add_cache_entry (sink, &snippet_cache, source); - g_free (source); - } - - setup_pipeline_from_cache_entry (sink, pipeline, entry, 1); -} - -static CoglBool -cogl_gst_ayuv_upload (CoglGstVideoSink *sink, - GstBuffer *buffer) -{ - CoglGstVideoSinkPrivate *priv = sink->priv; - CoglPixelFormat format = COGL_PIXEL_FORMAT_RGBA_8888; - GstVideoFrame frame; - - if (!gst_video_frame_map (&frame, &priv->info, buffer, GST_MAP_READ)) - goto map_fail; - - clear_frame_textures (sink); - - priv->frame[0] = video_texture_new_from_data (priv->ctx, priv->info.width, - priv->info.height, - format, - priv->info.stride[0], - frame.data[0]); - - gst_video_frame_unmap (&frame); - - return TRUE; - -map_fail: - { - GST_ERROR_OBJECT (sink, "Could not map incoming video frame"); - return FALSE; - } -} - -static CoglGstRenderer ayuv_glsl_renderer = -{ - "AYUV glsl", - COGL_GST_AYUV, - COGL_GST_RENDERER_NEEDS_GLSL, - GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("AYUV")), - 1, /* n_layers */ - cogl_gst_ayuv_glsl_setup_pipeline, - cogl_gst_ayuv_upload, -}; - -static void -cogl_gst_nv12_glsl_setup_pipeline (CoglGstVideoSink *sink, - CoglPipeline *pipeline) -{ - CoglGstVideoSinkPrivate *priv = sink->priv; - static SnippetCache snippet_cache; - SnippetCacheEntry *entry; - - entry = get_cache_entry (sink, &snippet_cache); - - if (entry == NULL) - { - char *source; - - source = - g_strdup_printf ("vec4\n" - "cogl_gst_sample_video%i (vec2 UV)\n" - "{\n" - " vec4 color;\n" - " float y = 1.1640625 *\n" - " (texture2D (cogl_sampler%i, UV).a -\n" - " 0.0625);\n" - " vec2 uv = texture2D (cogl_sampler%i, UV).rg;\n" - " uv -= 0.5;\n" - " float u = uv.x;\n" - " float v = uv.y;\n" - " color.r = y + 1.59765625 * v;\n" - " color.g = y - 0.390625 * u - 0.8125 * v;\n" - " color.b = y + 2.015625 * u;\n" - " color.a = 1.0;\n" - " return color;\n" - "}\n", - priv->custom_start, - priv->custom_start, - priv->custom_start + 1); - - entry = add_cache_entry (sink, &snippet_cache, source); - g_free (source); - } - - setup_pipeline_from_cache_entry (sink, pipeline, entry, 2); -} - -static CoglBool -cogl_gst_nv12_upload (CoglGstVideoSink *sink, - GstBuffer *buffer) -{ - CoglGstVideoSinkPrivate *priv = sink->priv; - GstVideoFrame frame; - - if (!gst_video_frame_map (&frame, &priv->info, buffer, GST_MAP_READ)) - goto map_fail; - - clear_frame_textures (sink); - - priv->frame[0] = - video_texture_new_from_data (priv->ctx, - GST_VIDEO_INFO_COMP_WIDTH (&priv->info, 0), - GST_VIDEO_INFO_COMP_HEIGHT (&priv->info, 0), - COGL_PIXEL_FORMAT_A_8, - priv->info.stride[0], - frame.data[0]); - - priv->frame[1] = - video_texture_new_from_data (priv->ctx, - GST_VIDEO_INFO_COMP_WIDTH (&priv->info, 1), - GST_VIDEO_INFO_COMP_HEIGHT (&priv->info, 1), - COGL_PIXEL_FORMAT_RG_88, - priv->info.stride[1], - frame.data[1]); - - gst_video_frame_unmap (&frame); - - return TRUE; - - map_fail: - { - GST_ERROR_OBJECT (sink, "Could not map incoming video frame"); - return FALSE; - } -} - -static CoglGstRenderer nv12_glsl_renderer = -{ - "NV12 glsl", - COGL_GST_NV12, - COGL_GST_RENDERER_NEEDS_GLSL | COGL_GST_RENDERER_NEEDS_TEXTURE_RG, - GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES ("memory:SystemMemory", - "NV12")), - 2, /* n_layers */ - cogl_gst_nv12_glsl_setup_pipeline, - cogl_gst_nv12_upload, -}; - -static GSList* -cogl_gst_build_renderers_list (CoglContext *ctx) -{ - GSList *list = NULL; - CoglGstRendererFlag flags = 0; - int i; - static CoglGstRenderer *const renderers[] = - { - /* These are in increasing order of priority so that the - * priv->renderers will be in decreasing order. That way the GLSL - * renderers will be preferred if they are available */ - &rgb24_renderer, - &rgb32_renderer, - &rgb24_glsl_renderer, - &rgb32_glsl_renderer, - &yv12_glsl_renderer, - &i420_glsl_renderer, - &ayuv_glsl_renderer, - &nv12_glsl_renderer, - NULL - }; - - if (cogl_has_feature (ctx, COGL_FEATURE_ID_GLSL)) - flags |= COGL_GST_RENDERER_NEEDS_GLSL; - - if (cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_RG)) - flags |= COGL_GST_RENDERER_NEEDS_TEXTURE_RG; - - for (i = 0; renderers[i]; i++) - if ((renderers[i]->flags & flags) == renderers[i]->flags) - list = g_slist_prepend (list, renderers[i]); - - return list; -} - -static void -append_cap (gpointer data, - gpointer user_data) -{ - CoglGstRenderer *renderer = (CoglGstRenderer *) data; - GstCaps *caps = (GstCaps *) user_data; - GstCaps *writable_caps; - writable_caps = - gst_caps_make_writable (gst_static_caps_get (&renderer->caps)); - gst_caps_append (caps, writable_caps); -} - -static GstCaps * -cogl_gst_build_caps (GSList *renderers) -{ - GstCaps *caps; - - caps = gst_caps_new_empty (); - - g_slist_foreach (renderers, append_cap, caps); - - return caps; -} - -void -cogl_gst_video_sink_set_context (CoglGstVideoSink *vt, - CoglContext *ctx) -{ - CoglGstVideoSinkPrivate *priv = vt->priv; - - if (ctx) - ctx = cogl_object_ref (ctx); - - if (priv->ctx) - { - cogl_object_unref (priv->ctx); - g_slist_free (priv->renderers); - priv->renderers = NULL; - if (priv->caps) - { - gst_caps_unref (priv->caps); - priv->caps = NULL; - } - } - - if (ctx) - { - priv->ctx = ctx; - priv->renderers = cogl_gst_build_renderers_list (priv->ctx); - priv->caps = cogl_gst_build_caps (priv->renderers); - } -} - -static CoglGstRenderer * -cogl_gst_find_renderer_by_format (CoglGstVideoSink *sink, - CoglGstVideoFormat format) -{ - CoglGstVideoSinkPrivate *priv = sink->priv; - CoglGstRenderer *renderer = NULL; - GSList *element; - - /* The renderers list is in decreasing order of priority so we'll - * pick the first one that matches */ - for (element = priv->renderers; element; element = g_slist_next (element)) - { - CoglGstRenderer *candidate = (CoglGstRenderer *) element->data; - if (candidate->format == format) - { - renderer = candidate; - break; - } - } - - return renderer; -} - -static GstCaps * -cogl_gst_video_sink_get_caps (GstBaseSink *bsink, - GstCaps *filter) -{ - CoglGstVideoSink *sink; - sink = COGL_GST_VIDEO_SINK (bsink); - - if (sink->priv->caps == NULL) - return NULL; - else - return gst_caps_ref (sink->priv->caps); -} - -static CoglBool -cogl_gst_video_sink_parse_caps (GstCaps *caps, - CoglGstVideoSink *sink, - CoglBool save) -{ - CoglGstVideoSinkPrivate *priv = sink->priv; - GstCaps *intersection; - GstVideoInfo vinfo; - CoglGstVideoFormat format; - CoglBool bgr = FALSE; - CoglGstRenderer *renderer; - - intersection = gst_caps_intersect (priv->caps, caps); - if (gst_caps_is_empty (intersection)) - goto no_intersection; - - gst_caps_unref (intersection); - - if (!gst_video_info_from_caps (&vinfo, caps)) - goto unknown_format; - - switch (vinfo.finfo->format) - { - case GST_VIDEO_FORMAT_YV12: - format = COGL_GST_YV12; - break; - case GST_VIDEO_FORMAT_I420: - format = COGL_GST_I420; - break; - case GST_VIDEO_FORMAT_AYUV: - format = COGL_GST_AYUV; - bgr = FALSE; - break; - case GST_VIDEO_FORMAT_NV12: - format = COGL_GST_NV12; - break; - case GST_VIDEO_FORMAT_RGB: - format = COGL_GST_RGB24; - bgr = FALSE; - break; - case GST_VIDEO_FORMAT_BGR: - format = COGL_GST_RGB24; - bgr = TRUE; - break; - case GST_VIDEO_FORMAT_RGBA: - format = COGL_GST_RGB32; - bgr = FALSE; - break; - case GST_VIDEO_FORMAT_BGRA: - format = COGL_GST_RGB32; - bgr = TRUE; - break; - default: - goto unhandled_format; - } - - renderer = cogl_gst_find_renderer_by_format (sink, format); - - if (G_UNLIKELY (renderer == NULL)) - goto no_suitable_renderer; - - GST_INFO_OBJECT (sink, "found the %s renderer", renderer->name); - - if (save) - { - priv->info = vinfo; - - priv->format = format; - priv->bgr = bgr; - - priv->renderer = renderer; - } - - return TRUE; - - -no_intersection: - { - GST_WARNING_OBJECT (sink, - "Incompatible caps, don't intersect with %" GST_PTR_FORMAT, priv->caps); - return FALSE; - } - -unknown_format: - { - GST_WARNING_OBJECT (sink, "Could not figure format of input caps"); - return FALSE; - } - -unhandled_format: - { - GST_ERROR_OBJECT (sink, "Provided caps aren't supported by clutter-gst"); - return FALSE; - } - -no_suitable_renderer: - { - GST_ERROR_OBJECT (sink, "could not find a suitable renderer"); - return FALSE; - } -} - -static CoglBool -cogl_gst_video_sink_set_caps (GstBaseSink *bsink, - GstCaps *caps) -{ - CoglGstVideoSink *sink; - CoglGstVideoSinkPrivate *priv; - - sink = COGL_GST_VIDEO_SINK (bsink); - priv = sink->priv; - - if (!cogl_gst_video_sink_parse_caps (caps, sink, FALSE)) - return FALSE; - - g_mutex_lock (&priv->source->buffer_lock); - priv->source->has_new_caps = TRUE; - g_mutex_unlock (&priv->source->buffer_lock); - - return TRUE; -} - -static CoglBool -cogl_gst_source_dispatch (GSource *source, - GSourceFunc callback, - void *user_data) -{ - CoglGstSource *gst_source= (CoglGstSource*) source; - CoglGstVideoSinkPrivate *priv = gst_source->sink->priv; - GstBuffer *buffer; - gboolean pipeline_ready = FALSE; - - g_mutex_lock (&gst_source->buffer_lock); - - if (G_UNLIKELY (gst_source->has_new_caps)) - { - GstCaps *caps = - gst_pad_get_current_caps (GST_BASE_SINK_PAD ((GST_BASE_SINK - (gst_source->sink)))); - - if (!cogl_gst_video_sink_parse_caps (caps, gst_source->sink, TRUE)) - goto negotiation_fail; - - gst_source->has_new_caps = FALSE; - priv->free_layer = priv->custom_start + priv->renderer->n_layers; - - dirty_default_pipeline (gst_source->sink); - - /* We are now in a state where we could generate the pipeline if - * the application requests it so we can emit the signal. - * However we'll actually generate the pipeline lazily only if - * the application actually asks for it. */ - pipeline_ready = TRUE; - } - - buffer = gst_source->buffer; - gst_source->buffer = NULL; - - g_mutex_unlock (&gst_source->buffer_lock); - - if (buffer) - { - if (!priv->renderer->upload (gst_source->sink, buffer)) - goto fail_upload; - - gst_buffer_unref (buffer); - } - else - GST_WARNING_OBJECT (gst_source->sink, "No buffers available for display"); - - if (G_UNLIKELY (pipeline_ready)) - g_signal_emit (gst_source->sink, - video_sink_signals[PIPELINE_READY_SIGNAL], - 0 /* detail */); - g_signal_emit (gst_source->sink, - video_sink_signals[NEW_FRAME_SIGNAL], 0, - NULL); - - return TRUE; - - -negotiation_fail: - { - GST_WARNING_OBJECT (gst_source->sink, - "Failed to handle caps. Stopping GSource"); - priv->flow_return = GST_FLOW_NOT_NEGOTIATED; - g_mutex_unlock (&gst_source->buffer_lock); - - return FALSE; - } - -fail_upload: - { - GST_WARNING_OBJECT (gst_source->sink, "Failed to upload buffer"); - priv->flow_return = GST_FLOW_ERROR; - gst_buffer_unref (buffer); - return FALSE; - } -} - -static GSourceFuncs gst_source_funcs = -{ - cogl_gst_source_prepare, - cogl_gst_source_check, - cogl_gst_source_dispatch, - cogl_gst_source_finalize -}; - -static CoglGstSource * -cogl_gst_source_new (CoglGstVideoSink *sink) -{ - GSource *source; - CoglGstSource *gst_source; - - source = g_source_new (&gst_source_funcs, sizeof (CoglGstSource)); - gst_source = (CoglGstSource *) source; - - g_source_set_can_recurse (source, TRUE); - g_source_set_priority (source, COGL_GST_DEFAULT_PRIORITY); - - gst_source->sink = sink; - g_mutex_init (&gst_source->buffer_lock); - gst_source->buffer = NULL; - - return gst_source; -} - -static void -cogl_gst_video_sink_init (CoglGstVideoSink *sink) -{ - CoglGstVideoSinkPrivate *priv; - - sink->priv = priv = G_TYPE_INSTANCE_GET_PRIVATE (sink, - COGL_GST_TYPE_VIDEO_SINK, - CoglGstVideoSinkPrivate); - priv->custom_start = 0; - priv->default_sample = TRUE; -} - -static GstFlowReturn -_cogl_gst_video_sink_render (GstBaseSink *bsink, - GstBuffer *buffer) -{ - CoglGstVideoSink *sink = COGL_GST_VIDEO_SINK (bsink); - CoglGstVideoSinkPrivate *priv = sink->priv; - CoglGstSource *gst_source = priv->source; - - g_mutex_lock (&gst_source->buffer_lock); - - if (G_UNLIKELY (priv->flow_return != GST_FLOW_OK)) - goto dispatch_flow_ret; - - if (gst_source->buffer) - gst_buffer_unref (gst_source->buffer); - - gst_source->buffer = gst_buffer_ref (buffer); - g_mutex_unlock (&gst_source->buffer_lock); - - g_main_context_wakeup (NULL); - - return GST_FLOW_OK; - - dispatch_flow_ret: - { - g_mutex_unlock (&gst_source->buffer_lock); - return priv->flow_return; - } -} - -static void -cogl_gst_video_sink_dispose (GObject *object) -{ - CoglGstVideoSink *self; - CoglGstVideoSinkPrivate *priv; - - self = COGL_GST_VIDEO_SINK (object); - priv = self->priv; - - clear_frame_textures (self); - - if (priv->pipeline) - { - cogl_object_unref (priv->pipeline); - priv->pipeline = NULL; - } - - if (priv->caps) - { - gst_caps_unref (priv->caps); - priv->caps = NULL; - } - - G_OBJECT_CLASS (cogl_gst_video_sink_parent_class)->dispose (object); -} - -static void -cogl_gst_video_sink_finalize (GObject *object) -{ - CoglGstVideoSink *self = COGL_GST_VIDEO_SINK (object); - - cogl_gst_video_sink_set_context (self, NULL); - - G_OBJECT_CLASS (cogl_gst_video_sink_parent_class)->finalize (object); -} - -static CoglBool -cogl_gst_video_sink_start (GstBaseSink *base_sink) -{ - CoglGstVideoSink *sink = COGL_GST_VIDEO_SINK (base_sink); - CoglGstVideoSinkPrivate *priv = sink->priv; - - priv->source = cogl_gst_source_new (sink); - g_source_attach ((GSource *) priv->source, NULL); - priv->flow_return = GST_FLOW_OK; - return TRUE; -} - -static void -cogl_gst_video_sink_set_property (GObject *object, - unsigned int prop_id, - const GValue *value, - GParamSpec *pspec) -{ - CoglGstVideoSink *sink = COGL_GST_VIDEO_SINK (object); - - switch (prop_id) - { - case PROP_UPDATE_PRIORITY: - cogl_gst_video_sink_set_priority (sink, g_value_get_int (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -cogl_gst_video_sink_get_property (GObject *object, - unsigned int prop_id, - GValue *value, - GParamSpec *pspec) -{ - CoglGstVideoSink *sink = COGL_GST_VIDEO_SINK (object); - CoglGstVideoSinkPrivate *priv = sink->priv; - - switch (prop_id) - { - case PROP_UPDATE_PRIORITY: - g_value_set_int (value, g_source_get_priority ((GSource *) priv->source)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static CoglBool -cogl_gst_video_sink_stop (GstBaseSink *base_sink) -{ - CoglGstVideoSink *sink = COGL_GST_VIDEO_SINK (base_sink); - CoglGstVideoSinkPrivate *priv = sink->priv; - - if (priv->source) - { - GSource *source = (GSource *) priv->source; - g_source_destroy (source); - g_source_unref (source); - priv->source = NULL; - } - - return TRUE; -} - -static void -cogl_gst_video_sink_class_init (CoglGstVideoSinkClass *klass) -{ - GObjectClass *go_class = G_OBJECT_CLASS (klass); - GstBaseSinkClass *gb_class = GST_BASE_SINK_CLASS (klass); - GstElementClass *ge_class = GST_ELEMENT_CLASS (klass); - GstPadTemplate *pad_template; - GParamSpec *pspec; - - g_type_class_add_private (klass, sizeof (CoglGstVideoSinkPrivate)); - go_class->set_property = cogl_gst_video_sink_set_property; - go_class->get_property = cogl_gst_video_sink_get_property; - go_class->dispose = cogl_gst_video_sink_dispose; - go_class->finalize = cogl_gst_video_sink_finalize; - - pad_template = gst_static_pad_template_get (&sinktemplate_all); - gst_element_class_add_pad_template (ge_class, pad_template); - - gst_element_class_set_metadata (ge_class, - "Cogl video sink", "Sink/Video", - "Sends video data from GStreamer to a " - "Cogl pipeline", - "Jonathan Matthew , " - "Matthew Allum , " - "Plamena Manolova " - ""); - - gb_class->render = _cogl_gst_video_sink_render; - gb_class->preroll = _cogl_gst_video_sink_render; - gb_class->start = cogl_gst_video_sink_start; - gb_class->stop = cogl_gst_video_sink_stop; - gb_class->set_caps = cogl_gst_video_sink_set_caps; - gb_class->get_caps = cogl_gst_video_sink_get_caps; - - pspec = g_param_spec_int ("update-priority", - "Update Priority", - "Priority of video updates in the thread", - -G_MAXINT, G_MAXINT, - COGL_GST_DEFAULT_PRIORITY, - COGL_GST_PARAM_READWRITE); - - g_object_class_install_property (go_class, PROP_UPDATE_PRIORITY, pspec); - - video_sink_signals[PIPELINE_READY_SIGNAL] = - g_signal_new ("pipeline-ready", - COGL_GST_TYPE_VIDEO_SINK, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (CoglGstVideoSinkClass, pipeline_ready), - NULL, /* accumulator */ - NULL, /* accu_data */ - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, - 0 /* n_params */); - - video_sink_signals[NEW_FRAME_SIGNAL] = - g_signal_new ("new-frame", - COGL_GST_TYPE_VIDEO_SINK, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (CoglGstVideoSinkClass, new_frame), - NULL, /* accumulator */ - NULL, /* accu_data */ - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, - 0 /* n_params */); -} - -CoglGstVideoSink * -cogl_gst_video_sink_new (CoglContext *ctx) -{ - CoglGstVideoSink *sink = g_object_new (COGL_GST_TYPE_VIDEO_SINK, NULL); - cogl_gst_video_sink_set_context (sink, ctx); - - return sink; -} - -float -cogl_gst_video_sink_get_aspect (CoglGstVideoSink *vt) -{ - GstVideoInfo *info; - - g_return_val_if_fail (COGL_GST_IS_VIDEO_SINK (vt), 0.); - - info = &vt->priv->info; - return ((float)info->width * (float)info->par_n) / - ((float)info->height * (float)info->par_d); -} - -float -cogl_gst_video_sink_get_width_for_height (CoglGstVideoSink *vt, - float height) -{ - float aspect; - - g_return_val_if_fail (COGL_GST_IS_VIDEO_SINK (vt), 0.); - - aspect = cogl_gst_video_sink_get_aspect (vt); - return height * aspect; -} - -float -cogl_gst_video_sink_get_height_for_width (CoglGstVideoSink *vt, - float width) -{ - float aspect; - - g_return_val_if_fail (COGL_GST_IS_VIDEO_SINK (vt), 0.); - - aspect = cogl_gst_video_sink_get_aspect (vt); - return width / aspect; -} - -void -cogl_gst_video_sink_fit_size (CoglGstVideoSink *vt, - const CoglGstRectangle *available, - CoglGstRectangle *output) -{ - g_return_if_fail (COGL_GST_IS_VIDEO_SINK (vt)); - g_return_if_fail (available != NULL); - g_return_if_fail (output != NULL); - - if (available->height == 0.0f) - { - output->x = available->x; - output->y = available->y; - output->width = output->height = 0; - } - else - { - float available_aspect = available->width / available->height; - float video_aspect = cogl_gst_video_sink_get_aspect (vt); - - if (video_aspect > available_aspect) - { - output->width = available->width; - output->height = available->width / video_aspect; - output->x = available->x; - output->y = available->y + (available->height - output->height) / 2; - } - else - { - output->width = available->height * video_aspect; - output->height = available->height; - output->x = available->x + (available->width - output->width) / 2; - output->y = available->y; - } - } -} - -void -cogl_gst_video_sink_get_natural_size (CoglGstVideoSink *vt, - float *width, - float *height) -{ - GstVideoInfo *info; - - g_return_if_fail (COGL_GST_IS_VIDEO_SINK (vt)); - - info = &vt->priv->info; - - if (info->par_n > info->par_d) - { - /* To display the video at the right aspect ratio then in this - * case the pixels need to be stretched horizontally and so we - * use the unscaled height as our reference. - */ - - if (height) - *height = info->height; - if (width) - *width = cogl_gst_video_sink_get_width_for_height (vt, info->height); - } - else - { - if (width) - *width = info->width; - if (height) - *height = cogl_gst_video_sink_get_height_for_width (vt, info->width); - } -} - -float -cogl_gst_video_sink_get_natural_width (CoglGstVideoSink *vt) -{ - float width; - cogl_gst_video_sink_get_natural_size (vt, &width, NULL); - return width; -} - -float -cogl_gst_video_sink_get_natural_height (CoglGstVideoSink *vt) -{ - float height; - cogl_gst_video_sink_get_natural_size (vt, NULL, &height); - return height; -} - -CoglBool -cogl_gst_video_sink_is_ready (CoglGstVideoSink *sink) -{ - return !!sink->priv->renderer; -} diff --git a/cogl-gst/cogl-gst-video-sink.h b/cogl-gst/cogl-gst-video-sink.h deleted file mode 100644 index 12a6480d..00000000 --- a/cogl-gst/cogl-gst-video-sink.h +++ /dev/null @@ -1,533 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007, 2008 OpenedHand - * Copyright (C) 2009, 2010, 2013 Intel Corporation - * - * 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, sublicense, 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 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 - * NONINFRINGEMENT. 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 __COGL_GST_VIDEO_SINK_H__ -#define __COGL_GST_VIDEO_SINK_H__ -#include -#include - -/* We just need the public Cogl api for cogl-gst but we first need to - * undef COGL_COMPILATION to avoid getting an error that normally - * checks cogl.h isn't used internally. */ -#ifdef COGL_COMPILATION -#undef COGL_COMPILATION -#endif - -#include - -#include - -/** - * SECTION:cogl-gst-video-sink - * @short_description: A video sink for integrating a GStreamer - * pipeline with a Cogl pipeline. - * - * #CoglGstVideoSink is a subclass of #GstBaseSink which can be used to - * create a #CoglPipeline for rendering the frames of the video. - * - * To create a basic video player, an application can create a - * #GstPipeline as normal using gst_pipeline_new() and set the - * sink on it to one created with cogl_gst_video_sink_new(). The - * application can then listen for the #CoglGstVideoSink::new-frame - * signal which will be emitted whenever there are new textures ready - * for rendering. For simple rendering, the application can just call - * cogl_gst_video_sink_get_pipeline() in the signal handler and use - * the returned pipeline to paint the new frame. - * - * An application is also free to do more advanced rendering by - * customizing the pipeline. In that case it should listen for the - * #CoglGstVideoSink::pipeline-ready signal which will be emitted as - * soon as the sink has determined enough information about the video - * to know how it should be rendered. In the handler for this signal, - * the application can either make modifications to a copy of the - * pipeline returned by cogl_gst_video_sink_get_pipeline() or it can - * create its own pipeline from scratch and ask the sink to configure - * it with cogl_gst_video_sink_setup_pipeline(). If a custom pipeline - * is created using one of these methods then the application should - * call cogl_gst_video_sink_attach_frame() on the pipeline before - * rendering in order to update the textures on the pipeline's layers. - * - * If the %COGL_FEATURE_ID_GLSL feature is available then the pipeline - * used by the sink will have a shader snippet with a function in it - * called cogl_gst_sample_video0 which takes a single vec2 argument. - * This can be used by custom snippets set the by the application to - * sample from the video. The vec2 argument represents the normalised - * coordinates within the video. The function returns a vec4 - * containing a pre-multiplied RGBA color of the pixel within the - * video. - * - * Since: 1.16 - */ - -G_BEGIN_DECLS - -#define COGL_GST_GTYPE_DECLARE_TYPE(name) \ - GType cogl_gst_ ## name ## _get_gtype (void) - - -#define COGL_GST_TYPE_VIDEO_SINK cogl_gst_video_sink_get_type() - -#define COGL_GST_VIDEO_SINK(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ - COGL_GST_TYPE_VIDEO_SINK, CoglGstVideoSink)) - -#define COGL_GST_VIDEO_SINK_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), \ - COGL_GST_TYPE_VIDEO_SINK, CoglGstVideoSinkClass)) - -#define COGL_GST_IS_VIDEO_SINK(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ - COGL_GST_TYPE_VIDEO_SINK)) - -#define COGL_GST_IS_VIDEO_SINK_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), \ - COGL_GST_TYPE_VIDEO_SINK)) - -#define COGL_GST_VIDEO_SINK_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), \ - COGL_GST_TYPE_VIDEO_SINK, CoglGstVideoSinkClass)) - -typedef struct _CoglGstVideoSink CoglGstVideoSink; -typedef struct _CoglGstVideoSinkClass CoglGstVideoSinkClass; -typedef struct _CoglGstVideoSinkPrivate CoglGstVideoSinkPrivate; - -/** - * CoglGstVideoSink: - * - * The #CoglGstVideoSink structure contains only private data and - * should be accessed using the provided API. - * - * Since: 1.16 - */ -struct _CoglGstVideoSink -{ - /*< private >*/ - GstBaseSink parent; - CoglGstVideoSinkPrivate *priv; -}; - -/** - * CoglGstVideoSinkClass: - * @new_frame: handler for the #CoglGstVideoSink::new-frame signal - * @pipeline_ready: handler for the #CoglGstVideoSink::pipeline-ready signal - * - * Since: 1.16 - */ - -/** - * CoglGstVideoSink::new-frame: - * @sink: the #CoglGstVideoSink - * - * The sink will emit this signal whenever there are new textures - * available for a new frame of the video. After this signal is - * emitted, an application can call cogl_gst_video_sink_get_pipeline() - * to get a pipeline suitable for rendering the frame. If the - * application is using a custom pipeline it can alternatively call - * cogl_gst_video_sink_attach_frame() to attach the textures. - * - * Since: 1.16 - */ - -/** - * CoglGstVideoSink::pipeline-ready: - * @sink: the #CoglGstVideoSink - * - * The sink will emit this signal as soon as it has gathered enough - * information from the video to configure a pipeline. If the - * application wants to do some customized rendering, it can setup its - * pipeline after this signal is emitted. The application's pipeline - * will typically either be a copy of the one returned by - * cogl_gst_video_sink_get_pipeline() or it can be a completely custom - * pipeline which is setup using cogl_gst_video_sink_setup_pipeline(). - * - * Note that it is an error to call either of those functions before - * this signal is emitted. The #CoglGstVideoSink::new-frame signal - * will only be emitted after the pipeline is ready so the application - * could also create its pipeline in the handler for that. - * - * Since: 1.16 - */ - -struct _CoglGstVideoSinkClass -{ - /*< private >*/ - GstBaseSinkClass parent_class; - - /*< public >*/ - void (* new_frame) (CoglGstVideoSink *sink); - void (* pipeline_ready) (CoglGstVideoSink *sink); - - /*< private >*/ - void *_padding_dummy[8]; -}; - -GType -cogl_gst_video_sink_get_type (void) G_GNUC_CONST; - -/** - * cogl_gst_video_sink_new: - * @ctx: The #CoglContext - * - * Creates a new #CoglGstVideoSink which will create resources for use - * with the given context. - * - * Return value: (transfer full): a new #CoglGstVideoSink - * Since: 1.16 - */ -CoglGstVideoSink * -cogl_gst_video_sink_new (CoglContext *ctx); - -/** - * cogl_gst_video_sink_is_ready: - * @sink: The #CoglGstVideoSink - * - * Returns whether the pipeline is ready and so - * cogl_gst_video_sink_get_pipeline() and - * cogl_gst_video_sink_setup_pipeline() can be called without causing error. - * - * Note: Normally an application will wait until the - * #CoglGstVideoSink::pipeline-ready signal is emitted instead of - * polling the ready status with this api, but sometimes when a sink - * is passed between components that didn't have an opportunity to - * connect a signal handler this can be useful. - * - * Return value: %TRUE if the sink is ready, else %FALSE - * Since: 1.16 - */ -CoglBool -cogl_gst_video_sink_is_ready (CoglGstVideoSink *sink); - -/** - * cogl_gst_video_sink_get_pipeline: - * @vt: The #CoglGstVideoSink - * - * Returns a pipeline suitable for rendering the current frame of the - * given video sink. The pipeline will already have the textures for - * the frame attached. For simple rendering, an application will - * typically call this function immediately before it paints the - * video. It can then just paint a rectangle using the returned - * pipeline. - * - * An application is free to make a copy of this - * pipeline and modify it for custom rendering. - * - * Note: it is considered an error to call this function before the - * #CoglGstVideoSink::pipeline-ready signal is emitted. - * - * Return value: (transfer none): the pipeline for rendering the - * current frame - * Since: 1.16 - */ -CoglPipeline * -cogl_gst_video_sink_get_pipeline (CoglGstVideoSink *vt); - -/** - * cogl_gst_video_sink_set_context: - * @vt: The #CoglGstVideoSink - * @ctx: The #CoglContext for the sink to use - * - * Sets the #CoglContext that the video sink should use for creating - * any resources. This function would normally only be used if the - * sink was constructed via gst_element_factory_make() instead of - * cogl_gst_video_sink_new(). - * - * Since: 1.16 - */ -void -cogl_gst_video_sink_set_context (CoglGstVideoSink *vt, - CoglContext *ctx); - -/** - * cogl_gst_video_sink_get_free_layer: - * @sink: The #CoglGstVideoSink - * - * This can be used when doing specialised rendering of the video by - * customizing the pipeline. #CoglGstVideoSink may use up to three - * private layers on the pipeline in order to attach the textures of - * the video frame. This function will return the index of the next - * available unused layer after the sink's internal layers. This can - * be used by the application to add additional layers, for example to - * blend in another color in the fragment processing. - * - * Return value: the index of the next available layer after the - * sink's internal layers. - * Since: 1.16 - */ -int -cogl_gst_video_sink_get_free_layer (CoglGstVideoSink *sink); - -/** - * cogl_gst_video_sink_attach_frame: - * @sink: The #CoglGstVideoSink - * @pln: A #CoglPipeline - * - * Updates the given pipeline with the textures for the current frame. - * This can be used if the application wants to customize the - * rendering using its own pipeline. Typically this would be called in - * response to the #CoglGstVideoSink::new-frame signal which is - * emitted whenever the new textures are available. The application - * would then make a copy of its template pipeline and call this to - * set the textures. - * - * Since: 1.16 - */ -void -cogl_gst_video_sink_attach_frame (CoglGstVideoSink *sink, - CoglPipeline *pln); - -/** - * cogl_gst_video_sink_set_first_layer: - * @sink: The #CoglGstVideoSink - * @first_layer: The new first layer - * - * Sets the index of the first layer that the sink will use for its - * rendering. This is useful if the application wants to have custom - * layers that appear before the layers added by the sink. In that - * case by default the sink's layers will be modulated with the result - * of the application's layers that come before @first_layer. - * - * Note that if this function is called then the name of the function - * to call in the shader snippets to sample the video will also - * change. For example, if @first_layer is three then the function - * will be cogl_gst_sample_video3. - * - * Since: 1.16 - */ -void -cogl_gst_video_sink_set_first_layer (CoglGstVideoSink *sink, - int first_layer); - -/** - * cogl_gst_video_sink_set_default_sample: - * @sink: The #CoglGstVideoSink - * @default_sample: Whether to add the default sampling - * - * By default the pipeline generated by - * cogl_gst_video_sink_setup_pipeline() and - * cogl_gst_video_sink_get_pipeline() will have a layer with a shader - * snippet that automatically samples the video. If the application - * wants to sample the video in a completely custom way using its own - * shader snippet it can set @default_sample to %FALSE to avoid this - * default snippet being added. In that case the application's snippet - * can call cogl_gst_sample_video0 to sample the texture itself. - * - * Since: 1.16 - */ -void -cogl_gst_video_sink_set_default_sample (CoglGstVideoSink *sink, - CoglBool default_sample); - -/** - * cogl_gst_video_sink_setup_pipeline: - * @sink: The #CoglGstVideoSink - * @pipeline: A #CoglPipeline - * - * Configures the given pipeline so that will be able to render the - * video for the @sink. This should only be used if the application - * wants to perform some custom rendering using its own pipeline. - * Typically an application will call this in response to the - * #CoglGstVideoSink::pipeline-ready signal. - * - * Note: it is considered an error to call this function before the - * #CoglGstVideoSink::pipeline-ready signal is emitted. - * - * Since: 1.16 - */ -void -cogl_gst_video_sink_setup_pipeline (CoglGstVideoSink *sink, - CoglPipeline *pipeline); - -/** - * cogl_gst_video_sink_get_aspect: - * @sink: A #CoglGstVideoSink - * - * Returns a width-for-height aspect ratio that lets you calculate a - * suitable width for displaying your video based on a given height by - * multiplying your chosen height by the returned aspect ratio. - * - * This aspect ratio is calculated based on the underlying size of the - * video buffers and the current pixel-aspect-ratio. - * - * Return value: a width-for-height aspect ratio - * - * Since: 1.16 - * Stability: unstable - */ -float -cogl_gst_video_sink_get_aspect (CoglGstVideoSink *sink); - -/** - * cogl_gst_video_sink_get_width_for_height: - * @sink: A #CoglGstVideoSink - * @height: A specific output @height - * - * Calculates a suitable output width for a specific output @height - * that will maintain the video's aspect ratio. - * - * Return value: An output width for the given output @height. - * - * Since: 1.16 - * Stability: unstable - */ -float -cogl_gst_video_sink_get_width_for_height (CoglGstVideoSink *sink, - float height); - -/** - * cogl_gst_video_sink_get_height_for_width: - * @sink: A #CoglGstVideoSink - * @width: A specific output @width - * - * Calculates a suitable output height for a specific output @width - * that will maintain the video's aspect ratio. - * - * Return value: An output height for the given output @width. - * - * Since: 1.16 - * Stability: unstable - */ -float -cogl_gst_video_sink_get_height_for_width (CoglGstVideoSink *sink, - float width); - -/** - * cogl_gst_video_sink_get_natural_size: - * @sink: A #CoglGstVideoSink - * @width: (out): return location for the video's natural width - * @height: (out): return location for the video's natural height - * - * Considering the real resolution of the video as well as the aspect - * ratio of pixel data that may need to be stretched when being displayed; - * this function calculates what the natural size of the underlying - * video source is. - * - * The natural size has the correct aspect ratio for displaying the - * video and is the minimum size where downscaling is not required. - * - * This natural size is calculated assuming that the video will - * be displayed on square pixels. - * - * Since: 1.18 - * Stability: unstable - */ -void -cogl_gst_video_sink_get_natural_size (CoglGstVideoSink *sink, - float *width, - float *height); - -/** - * cogl_gst_video_sink_get_natural_width: - * @sink: A #CoglGstVideoSink - * - * Considering the real resolution of the video as well as the aspect - * ratio of pixel data that may need to be stretched when being displayed; - * this function calculates what the natural size of the underlying - * video source is, and returns its width. - * - * The natural size has the correct aspect ratio for displaying the - * video and is the minimum size where downscaling is not required. - * - * This natural size is calculated assuming that the video will - * be displayed on square pixels. - * - * Return value: The video's natural width - * - * Since: 1.18 - * Stability: unstable - */ -float -cogl_gst_video_sink_get_natural_width (CoglGstVideoSink *sink); - -/** - * cogl_gst_video_sink_get_natural_height: - * @sink: A #CoglGstVideoSink - * - * Considering the real resolution of the video as well as the aspect - * ratio of pixel data that may need to be stretched when being displayed; - * this function calculates what the natural size of the underlying - * video source is, and returns its height. - * - * The natural size has the correct aspect ratio for displaying the - * video and is the minimum size where downscaling is not required. - * - * This natural size is calculated assuming that the video will - * be displayed on square pixels. - * - * Return value: The video's natural height - * - * Since: 1.18 - * Stability: unstable - */ -float -cogl_gst_video_sink_get_natural_height (CoglGstVideoSink *sink); - -/** - * CoglGstRectangle: - * @x: The X coordinate of the top left of the rectangle - * @y: The Y coordinate of the top left of the rectangle - * @width: The width of the rectangle - * @height: The height of the rectangle - * - * Describes a rectangle that can be used for video output. - */ -typedef struct _CoglGstRectangle -{ - float x; - float y; - float width; - float height; -} CoglGstRectangle; - -COGL_GST_GTYPE_DECLARE_TYPE (rectangle); - -/** - * cogl_gst_video_sink_fit_size: - * @sink: A #CoglGstVideoSink - * @available: (in): The space available for video output - * @output: (inout): The return location for the calculated output position - * - * Calculates a suitable @output rectangle that can fit inside the - * @available space while maintaining the aspect ratio of the current - * video. - * - * Applications would typically use this api for "letterboxing" by - * using this api to position a video inside a fixed screen space and - * filling the remaining space with black borders. - * - * Since: 1.16 - * Stability: unstable - */ -void -cogl_gst_video_sink_fit_size (CoglGstVideoSink *sink, - const CoglGstRectangle *available, - CoglGstRectangle *output); - -G_END_DECLS - -#endif diff --git a/cogl-gst/cogl-gst.h b/cogl-gst/cogl-gst.h deleted file mode 100644 index ea14865e..00000000 --- a/cogl-gst/cogl-gst.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007, 2008 OpenedHand - * Copyright (C) 2009, 2010, 2013 Intel Corporation - * - * 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, sublicense, 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 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 - * NONINFRINGEMENT. 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 __COGL_GST_H__ -#define __COGL_GST_H__ - -#include - -#endif diff --git a/cogl-gst/cogl-gst.pc.in b/cogl-gst/cogl-gst.pc.in deleted file mode 100644 index f47e847f..00000000 --- a/cogl-gst/cogl-gst.pc.in +++ /dev/null @@ -1,13 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ -apiversion=@COGL_API_VERSION@ -requires=@COGL_PKG_REQUIRES@ @COGL_GST_PKG_REQUIRES@ - -Name: Cogl -Description: A gstreamer integration library for Cogl -Version: @COGL_VERSION@ -Libs: -L${libdir} -lcogl-gst -Cflags: -I${includedir}/cogl -DCOGL_ENABLE_EXPERIMENTAL_2_0_API -Requires: ${requires} diff --git a/configure.ac b/configure.ac index 83460ff4..4f3cc224 100644 --- a/configure.ac +++ b/configure.ac @@ -443,43 +443,6 @@ AS_IF([test "x$enable_cogl_pango" = "xyes"], ] ) -dnl ============================================================ -dnl Should cogl-gst be built? -dnl ============================================================ - -AS_IF([test "x$enable_glib" != "xyes"], - [ - AS_IF([test "x$enable_cogl_gst" = "xyes"], - AC_MSG_ERROR([--enable-cogl-gst conflicts with --disable-glib])) - enable_cogl_gst=no - ] -) - -AC_ARG_ENABLE( - [cogl-gst], - [AC_HELP_STRING([--enable-cogl-gst=@<:@no/yes@:>@], [Enable gstreamer support @<:@default=no@:>@])], - [], - enable_cogl_gst=no -) -AS_IF([test "x$enable_cogl_gst" = "xyes"], - [ - COGL_GST_PKG_REQUIRES="$COGL_GST_PKG_REQUIRES gstreamer-1.0 gstreamer-fft-1.0 \ - gstreamer-audio-1.0 gstreamer-base-1.0 \ - gstreamer-video-1.0 gstreamer-plugins-base-1.0 \ - gstreamer-tag-1.0 gstreamer-controller-1.0" - - GST_MAJORMINOR=1.0 - - dnl define location of gstreamer plugin directory - plugindir="\$(libdir)/gstreamer-$GST_MAJORMINOR" - AC_SUBST(plugindir) - - dnl For the gtk doc generation - GSTREAMER_PREFIX="`$PKG_CONFIG --variable=prefix gstreamer-1.0`" - AC_SUBST(GSTREAMER_PREFIX) - ] -) - dnl ============================================================ dnl Should cogl-path be built? dnl ============================================================ @@ -970,15 +933,6 @@ AM_CONDITIONAL([BUILD_COGL_PANGO], [test "x$enable_cogl_pango" = "xyes"]) AM_CONDITIONAL([BUILD_COGL_PATH], [test "x$enable_cogl_path" = "xyes"]) -AC_SUBST(COGL_GST_PKG_REQUIRES) - -AS_IF([test "x$enable_cogl_gst" = "xyes"], - [PKG_CHECK_MODULES(COGL_GST_DEP, [$COGL_GST_PKG_REQUIRES])] -) -AM_CONDITIONAL([BUILD_COGL_GST], [test "x$enable_cogl_gst" = "xyes"]) - - - dnl ================================================================ dnl Misc program dependencies. dnl ================================================================ @@ -1134,9 +1088,6 @@ cogl-pango/cogl-pango.rc cogl-path/Makefile cogl-path/cogl-path-1.0.pc cogl-path/cogl-path-2.0-experimental.pc -cogl-gst/Makefile -cogl-gst/cogl-gst-1.0.pc -cogl-gst/cogl-gst-2.0-experimental.pc cogl-gles2/Makefile cogl-gles2/cogl-gles2-1.0.pc cogl-gles2/cogl-gles2-2.0-experimental.pc @@ -1175,7 +1126,6 @@ fi echo " Build libcogl-gles2 GLES 2.0 frontend api: ${enable_cogl_gles2}" echo " Image backend: ${COGL_IMAGE_BACKEND}" echo " Cogl Pango: ${enable_cogl_pango}" -echo " Cogl Gstreamer: ${enable_cogl_gst}" echo " Cogl Path: ${enable_cogl_path}" # Compiler/Debug related flags -- cgit v1.2.1