[vlc-commits] splitter: add a display plugin for splitter functionality

Rémi Denis-Courmont git at videolan.org
Sat Jan 12 15:09:41 CET 2019


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Fri Dec 28 20:48:38 2018 +0200| [5c18cff8d8cdba5784ca4bdb641fb483499117ed] | committer: Rémi Denis-Courmont

splitter: add a display plugin for splitter functionality

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=5c18cff8d8cdba5784ca4bdb641fb483499117ed
---

 modules/video_output/Makefile.am |   2 +
 modules/video_output/splitter.c  | 235 +++++++++++++++++++++++++++++++++++++++
 src/libvlc-module.c              |   4 -
 3 files changed, 237 insertions(+), 4 deletions(-)

diff --git a/modules/video_output/Makefile.am b/modules/video_output/Makefile.am
index bd3363954e..6c95e621ca 100644
--- a/modules/video_output/Makefile.am
+++ b/modules/video_output/Makefile.am
@@ -513,6 +513,7 @@ libflaschen_plugin_la_SOURCES = video_output/flaschen.c
 libflaschen_plugin_la_LIBADD = $(SOCKET_LIBS)
 
 libvdummy_plugin_la_SOURCES = video_output/vdummy.c
+libvideo_splitter_plugin_la_SOURCES = video_output/splitter.c
 libvmem_plugin_la_SOURCES = video_output/vmem.c
 libwdummy_plugin_la_SOURCES = video_output/wdummy.c
 libyuv_plugin_la_SOURCES = video_output/yuv.c
@@ -521,6 +522,7 @@ libvgl_plugin_la_SOURCES = video_output/vgl.c
 vout_LTLIBRARIES += \
 	libflaschen_plugin.la \
 	libvdummy_plugin.la \
+	libvideo_splitter_plugin.la \
 	libvmem_plugin.la \
 	libwdummy_plugin.la \
 	libvgl_plugin.la \
diff --git a/modules/video_output/splitter.c b/modules/video_output/splitter.c
new file mode 100644
index 0000000000..24b0e98ba8
--- /dev/null
+++ b/modules/video_output/splitter.c
@@ -0,0 +1,235 @@
+/**
+ * @file splitter.c
+ * @brief Video splitter video output module for VLC media player
+ */
+/*****************************************************************************
+ * Copyright © 2009 Laurent Aimar
+ * Copyright © 2009-2018 Rémi Denis-Courmont
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+
+#include <vlc_common.h>
+#include <vlc_modules.h>
+#include <vlc_plugin.h>
+#include <vlc_vout_display.h>
+#include <vlc_video_splitter.h>
+
+struct vout_display_sys_t {
+    video_splitter_t splitter;
+
+    picture_t **pictures;
+    vout_display_t **displays;
+};
+
+static void vlc_vidsplit_Prepare(vout_display_t *vd, picture_t *pic,
+                                 subpicture_t *subpic, vlc_tick_t date)
+{
+    vout_display_sys_t *sys = vd->sys;
+
+    picture_Hold(pic);
+    (void) subpic;
+
+    if (video_splitter_Filter(&sys->splitter, sys->pictures, pic)) {
+        for (int i = 0; i < sys->splitter.i_output; i++)
+            sys->pictures[i] = NULL;
+        return;
+    }
+
+    for (int i = 0; i < sys->splitter.i_output; i++)
+        sys->pictures[i] = vout_display_Prepare(sys->displays[i],
+                                                sys->pictures[i], NULL, date);
+}
+
+static void vlc_vidsplit_Display(vout_display_t *vd, picture_t *picture)
+{
+    vout_display_sys_t *sys = vd->sys;
+
+    for (int i = 0; i < sys->splitter.i_output; i++)
+        if (sys->pictures[i] != NULL)
+            vout_display_Display(sys->displays[i], sys->pictures[i]);
+
+    (void) picture;
+}
+
+static int vlc_vidsplit_Control(vout_display_t *vd, int query, va_list args)
+{
+    (void)vd; (void)query; (void)args;
+    return VLC_EGENERIC;
+}
+
+static void vlc_vidsplit_display_Event(vout_display_t *p, int id, va_list ap)
+{
+    (void) p; (void) id; (void) ap;
+}
+
+static void vlc_vidsplit_Close(vout_display_t *vd)
+{
+    vout_display_sys_t *sys = vd->sys;
+    int n = sys->splitter.i_output;
+
+    for (int i = 0; i < n; i++) {
+        vout_window_t *wnd = sys->displays[i]->cfg->window;
+
+        vout_display_Delete(sys->displays[i]);
+        vout_window_Disable(wnd);
+        vout_window_Delete(wnd);
+    }
+
+    module_unneed(&sys->splitter, sys->splitter.p_module);
+    video_format_Clean(&sys->splitter.fmt);
+    vlc_object_release(&sys->splitter);
+}
+
+static void vlc_vidsplit_window_Resized(vout_window_t *wnd,
+                                        unsigned width, unsigned height)
+{
+    (void) wnd; (void) width; (void) height;
+}
+
+static const struct vout_window_callbacks vlc_vidsplit_window_cbs =
+{
+    .resized = vlc_vidsplit_window_Resized,
+};
+
+static vout_window_t *video_splitter_CreateWindow(vlc_object_t *obj,
+    const vout_display_cfg_t *restrict vdcfg,
+    const video_format_t *restrict source)
+{
+    vout_window_cfg_t cfg = {
+        .is_decorated = true,
+    };
+    vout_window_owner_t owner = {
+        .cbs = &vlc_vidsplit_window_cbs,
+    };
+
+    vout_display_GetDefaultDisplaySize(&cfg.width, &cfg.height, source,
+                                       vdcfg);
+
+    vout_window_t *window = vout_window_New(obj, NULL, &owner);
+    if (window != NULL) {
+        if (vout_window_Enable(window, &cfg)) {
+            vout_window_Delete(window);
+            window = NULL;
+        }
+    }
+    return window;
+}
+
+static vout_display_t *vlc_vidsplit_CreateDisplay(vlc_object_t *obj,
+    const video_format_t *restrict source,
+    const vout_display_cfg_t *restrict cfg,
+    const char *name)
+{
+    vout_display_owner_t owner = {
+        .event = vlc_vidsplit_display_Event,
+    };
+    return vout_display_New(obj, source, cfg, name, &owner);
+}
+
+static int vlc_vidsplit_Open(vout_display_t *vd,
+                             const vout_display_cfg_t *cfg,
+                             video_format_t *fmtp, vlc_video_context *ctx)
+{
+    vlc_object_t *obj = VLC_OBJECT(vd);
+
+    if (vout_display_cfg_IsWindowed(cfg))
+        return VLC_EGENERIC;
+
+    char *name = var_InheritString(obj, "video-splitter");
+    if (name == NULL)
+        return VLC_EGENERIC;
+
+    vout_display_sys_t *sys = vlc_object_create(obj, sizeof (*sys));
+    if (unlikely(sys == NULL)) {
+        free(name);
+        return VLC_ENOMEM;
+    }
+    vd->sys = sys;
+
+    video_splitter_t *splitter = &sys->splitter;
+
+    video_format_Copy(&splitter->fmt, &vd->source);
+
+    splitter->p_module = module_need(splitter, "video splitter", name, true);
+    free(name);
+    if (splitter->p_module == NULL) {
+        video_format_Clean(&splitter->fmt);
+        vlc_object_release(splitter);
+        return VLC_EGENERIC;
+    }
+
+    sys->pictures = vlc_obj_malloc(obj, splitter->i_output
+                                        * sizeof (*sys->pictures));
+    sys->displays = vlc_obj_malloc(obj, splitter->i_output
+                                        * sizeof (*sys->displays));
+    if (unlikely(sys->pictures == NULL || sys->displays == NULL)) {
+        splitter->i_output = 0;
+        vlc_vidsplit_Close(vd);
+        return VLC_ENOMEM;
+    }
+
+    for (int i = 0; i < splitter->i_output; i++) {
+        const video_splitter_output_t *output = &splitter->p_output[i];
+        vout_display_cfg_t vdcfg = {
+            .display = { 0, 0, { 1, 1 } },
+            .align = { 0, 0 } /* TODO */,
+            .is_display_filled = true,
+            .zoom = { 1, 1 },
+        };
+        const char *modname = output->psz_module;
+
+        vdcfg.window = video_splitter_CreateWindow(obj, &vdcfg, &output->fmt);
+        if (vdcfg.window == NULL) {
+            splitter->i_output = i;
+            vlc_vidsplit_Close(vd);
+            return VLC_EGENERIC;
+        }
+
+        sys->displays[i] = vlc_vidsplit_CreateDisplay(obj, &output->fmt,
+                                                      &vdcfg, modname);
+        if (sys->displays[i] == NULL) {
+            vout_window_Disable(vdcfg.window);
+            vout_window_Delete(vdcfg.window);
+            splitter->i_output = i;
+            vlc_vidsplit_Close(vd);
+            return VLC_EGENERIC;
+        }
+    }
+
+    vd->prepare = vlc_vidsplit_Prepare;
+    vd->display = vlc_vidsplit_Display;
+    vd->control = vlc_vidsplit_Control;
+    (void) cfg; (void) fmtp; (void) ctx;
+    return VLC_SUCCESS;
+}
+
+vlc_module_begin()
+    set_shortname(N_("Splitter"))
+    set_description(N_("Video splitter display plugin"))
+    set_category(CAT_VIDEO)
+    set_subcategory(SUBCAT_VIDEO_VOUT)
+    set_capability("vout display", 0)
+    set_callbacks(vlc_vidsplit_Open, vlc_vidsplit_Close)
+    add_module("video-splitter", "video splitter", NULL,
+               N_("Video splitter module"), N_("Video splitter module"))
+vlc_module_end()
diff --git a/src/libvlc-module.c b/src/libvlc-module.c
index a4fdd60c50..29cb8df8cb 100644
--- a/src/libvlc-module.c
+++ b/src/libvlc-module.c
@@ -1690,10 +1690,6 @@ vlc_module_begin ()
     add_module_list("video-filter", "video filter", NULL,
                     VIDEO_FILTER_TEXT, VIDEO_FILTER_LONGTEXT)
 
-    set_subcategory( SUBCAT_VIDEO_SPLITTER )
-    add_module_list("video-splitter", "video splitter", NULL,
-                    VIDEO_SPLITTER_TEXT, VIDEO_SPLITTER_LONGTEXT)
-    add_obsolete_string( "vout-filter" ) /* since 2.0.0 */
 #if 0
     add_string( "pixel-ratio", "1", PIXEL_RATIO_TEXT, PIXEL_RATIO_TEXT )
 #endif



More information about the vlc-commits mailing list