[vlc-commits] [Git][videolan/vlc][master] 3 commits: deinterlace: fail on unknown mode
Romain Vimont
gitlab at videolan.org
Tue Jun 8 15:00:41 UTC 2021
Romain Vimont pushed to branch master at VideoLAN / VLC
Commits:
a5b4903d by Romain Vimont at 2021-06-08T14:36:51+00:00
deinterlace: fail on unknown mode
This will allow to try an alternate deinterlace filter (for example
an OpenGL filter).
- - - - -
4de0b416 by Romain Vimont at 2021-06-08T14:36:51+00:00
deinterlace: add --deinterlace-filter option
The option --deinterlace-mode selects the deinterlace algorithm to use,
but the same algorithm might be implemented by several modules, for
example a CPU version and an OpenGL version.
For that purpose, add a separate option to select the module(s) to use.
The default value is "deinterlace".
To select the blend deinterlace algorithm:
--deinterlace-mode=blend
or equivalently ("deinterlace" is the default filter):
--deinterlace-filter=deinterlace --deinterlace-mode=blend
To run the OpenGL version (the mode is "auto"):
--deinterlace-filter=glblend
The module glblend only implements the "blend" algorithm, it can be
passed explicitly:
--deinterlace-filter=glblend --deinterlace-mode=blend
To pass a list a modules, executed in order until one works:
--deinterlace-filter=glblend,deinterlace --deinterlace-mode=blend
- - - - -
8ef60b3b by Romain Vimont at 2021-06-08T14:36:51+00:00
opengl: add blend deinterlace filter
- - - - -
6 changed files:
- modules/video_filter/Makefile.am
- modules/video_filter/deinterlace/deinterlace.c
- + modules/video_filter/deinterlace/glblend.c
- src/libvlc-module.c
- src/video_output/interlacing.c
- src/video_output/video_output.c
Changes:
=====================================
modules/video_filter/Makefile.am
=====================================
@@ -188,6 +188,25 @@ endif
libdeinterlace_plugin_la_LIBADD = libdeinterlace_common.la
video_filter_LTLIBRARIES += libdeinterlace_plugin.la
+libglblend_plugin_la_SOURCES = video_filter/deinterlace/glblend.c
+libglblend_plugin_la_CFLAGS = $(AM_CFLAGS)
+if HAVE_GL
+libglblend_plugin_la_LIBADD = libvlc_opengl.la
+video_filter_LTLIBRARIES += libglblend_plugin.la
+endif
+
+if HAVE_IOS
+libglblend_plugin_la_LIBADD = libvlc_opengles.la
+libglblend_plugin_la_CFLAGS += -DUSE_OPENGL_ES2=1
+video_filter_LTLIBRARIES += libglblend_plugin.la
+endif
+
+if HAVE_ANDROID
+libglblend_plugin_la_LIBADD = libvlc_opengles.la
+libglblend_plugin_la_CFLAGS += -DUSE_OPENGL_ES2=1
+video_filter_LTLIBRARIES += libglblend_plugin.la
+endif
+
libopencv_wrapper_plugin_la_SOURCES = video_filter/opencv_wrapper.c
libopencv_wrapper_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) $(OPENCV_CFLAGS)
libopencv_wrapper_plugin_la_LIBADD = $(OPENCV_LIBS)
=====================================
modules/video_filter/deinterlace/deinterlace.c
=====================================
@@ -373,7 +373,7 @@ static struct filter_mode_t filter_mode [] = {
* @param mode Desired method. See mode_list for available choices.
* @see mode_list
*/
-static void SetFilterMethod( filter_t *p_filter, const char *mode, bool pack )
+static int SetFilterMethod( filter_t *p_filter, const char *mode, bool pack )
{
filter_sys_t *p_sys = p_filter->p_sys;
@@ -388,25 +388,23 @@ static void SetFilterMethod( filter_t *p_filter, const char *mode, bool pack )
{
msg_Err( p_filter, "unknown or incompatible deinterlace mode \"%s\""
" for packed format", mode );
- SetFilterMethod( p_filter, "blend", pack );
- return;
+ return SetFilterMethod( p_filter, "blend", pack );
}
if( p_sys->chroma->pixel_size > 1 && !filter_mode[i].b_high_bit_depth )
{
msg_Err( p_filter, "unknown or incompatible deinterlace mode \"%s\""
" for high depth format", mode );
- SetFilterMethod( p_filter, "blend", pack );
- return;
+ return SetFilterMethod( p_filter, "blend", pack );
}
msg_Dbg( p_filter, "using %s deinterlace method", mode );
p_sys->context.settings = filter_mode[i].settings;
p_sys->context.pf_render_ordered = filter_mode[i].pf_render_ordered;
- return;
+ return VLC_SUCCESS;
}
}
- msg_Err( p_filter, "unknown deinterlace mode \"%s\"", mode );
+ return VLC_EGENERIC;
}
/**
@@ -541,7 +539,13 @@ notsupp:
config_ChainParse( p_filter, FILTER_CFG_PREFIX, ppsz_filter_options,
p_filter->p_cfg );
char *psz_mode = var_InheritString( p_filter, FILTER_CFG_PREFIX "mode" );
- SetFilterMethod( p_filter, psz_mode, packed );
+ int ret = SetFilterMethod( p_filter, psz_mode, packed );
+ if (ret != VLC_SUCCESS)
+ {
+ free(psz_mode);
+ free(p_sys);
+ return ret;
+ }
IVTCClearState( p_filter );
=====================================
modules/video_filter/deinterlace/glblend.c
=====================================
@@ -0,0 +1,238 @@
+/*****************************************************************************
+ * glblend.c
+ *****************************************************************************
+ * Copyright (C) 2021 VLC authors and VideoLAN
+ *
+ * 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 <vlc_common.h>
+#include <vlc_picture.h>
+#include <vlc_plugin.h>
+#include <vlc_modules.h>
+#include <vlc_opengl.h>
+#include <vlc_filter.h>
+
+#include "video_output/opengl/filter.h"
+#include "video_output/opengl/gl_api.h"
+#include "video_output/opengl/gl_common.h"
+#include "video_output/opengl/gl_util.h"
+
+struct sys {
+ GLuint program_id;
+
+ GLuint vbo;
+
+ struct {
+ GLint vertex_pos;
+ GLint height;
+ } loc;
+};
+
+static int
+Draw(struct vlc_gl_filter *filter, const struct vlc_gl_input_meta *meta)
+{
+ struct sys *sys = filter->sys;
+
+ const opengl_vtable_t *vt = &filter->api->vt;
+
+ vt->UseProgram(sys->program_id);
+
+ struct vlc_gl_sampler *sampler = vlc_gl_filter_GetSampler(filter);
+ vlc_gl_sampler_Load(sampler);
+
+ vt->BindBuffer(GL_ARRAY_BUFFER, sys->vbo);
+ vt->EnableVertexAttribArray(sys->loc.vertex_pos);
+ vt->VertexAttribPointer(sys->loc.vertex_pos, 2, GL_FLOAT, GL_FALSE, 0,
+ (const void *) 0);
+
+ GLsizei height = sampler->tex_heights[meta->plane];
+ vt->Uniform1f(sys->loc.height, height);
+
+ vt->Clear(GL_COLOR_BUFFER_BIT);
+ vt->DrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+
+ return VLC_SUCCESS;
+}
+
+static void
+Close(struct vlc_gl_filter *filter)
+{
+ struct sys *sys = filter->sys;
+
+ const opengl_vtable_t *vt = &filter->api->vt;
+ vt->DeleteProgram(sys->program_id);
+ vt->DeleteBuffers(1, &sys->vbo);
+
+ free(sys);
+}
+
+static int
+Open(struct vlc_gl_filter *filter, const config_chain_t *config,
+ struct vlc_gl_tex_size *size_out)
+{
+ (void) config;
+ (void) size_out;
+
+ struct sys *sys = filter->sys = malloc(sizeof(*sys));
+ if (!sys)
+ return VLC_EGENERIC;
+
+ static const struct vlc_gl_filter_ops ops = {
+ .draw = Draw,
+ .close = Close,
+ };
+ filter->ops = &ops;
+ filter->config.filter_planes = true;
+
+ struct vlc_gl_sampler *sampler = vlc_gl_filter_GetSampler(filter);
+
+ static const char *const VERTEX_SHADER =
+ "attribute vec2 vertex_pos;\n"
+ "varying vec2 tex_coords;\n"
+ "varying vec2 tex_coords_up;\n"
+ "uniform float height;\n"
+ "void main() {\n"
+ " gl_Position = vec4(vertex_pos, 0.0, 1.0);\n"
+ " tex_coords = vec2((vertex_pos.x + 1.0) / 2.0,\n"
+ " (vertex_pos.y + 1.0) / 2.0);\n"
+ " tex_coords_up = vec2(tex_coords.x,\n"
+ " tex_coords.y + 1.0 / height);\n"
+ "}\n";
+
+ static const char *const FRAGMENT_SHADER =
+ "varying vec2 tex_coords;\n"
+ "varying vec2 tex_coords_up;\n"
+ "void main() {\n"
+ " vec4 pix = vlc_texture(tex_coords);\n"
+ " vec4 pix_up = vlc_texture(tex_coords_up);\n"
+ " gl_FragColor = (pix + pix_up) / 2.0;\n"
+ "}\n";
+
+ const char *shader_version;
+ const char *shader_precision;
+ if (filter->api->is_gles)
+ {
+ shader_version = "#version 100\n";
+ shader_precision = "precision highp float;\n";
+ }
+ else
+ {
+ shader_version = "#version 120\n";
+ shader_precision = "";
+ }
+
+ const char *extensions = sampler->shader.extensions
+ ? sampler->shader.extensions : "";
+
+ const opengl_vtable_t *vt = &filter->api->vt;
+
+ const char *vertex_shader[] = { shader_version, VERTEX_SHADER };
+ const char *fragment_shader[] = {
+ shader_version,
+ extensions,
+ shader_precision,
+ sampler->shader.body,
+ FRAGMENT_SHADER,
+ };
+
+ GLuint program_id =
+ vlc_gl_BuildProgram(VLC_OBJECT(filter), vt,
+ ARRAY_SIZE(vertex_shader), vertex_shader,
+ ARRAY_SIZE(fragment_shader), fragment_shader);
+
+ if (!program_id)
+ goto error;
+
+ vlc_gl_sampler_FetchLocations(sampler, program_id);
+
+ sys->program_id = program_id;
+
+ sys->loc.vertex_pos = vt->GetAttribLocation(program_id, "vertex_pos");
+ assert(sys->loc.vertex_pos != -1);
+
+ sys->loc.height = vt->GetUniformLocation(program_id, "height");
+ assert(sys->loc.height != -1);
+
+ vt->GenBuffers(1, &sys->vbo);
+
+ static const GLfloat vertex_pos[] = {
+ -1, 1,
+ -1, -1,
+ 1, 1,
+ 1, -1,
+ };
+
+ vt->BindBuffer(GL_ARRAY_BUFFER, sys->vbo);
+ vt->BufferData(GL_ARRAY_BUFFER, sizeof(vertex_pos), vertex_pos,
+ GL_STATIC_DRAW);
+
+ vt->BindBuffer(GL_ARRAY_BUFFER, 0);
+
+ return VLC_SUCCESS;
+
+error:
+ free(sys);
+ return VLC_EGENERIC;
+}
+
+static int OpenVideoFilter(vlc_object_t *obj)
+{
+ filter_t *filter = (filter_t*)obj;
+
+ char *mode = var_InheritString(obj, "deinterlace-mode");
+ bool is_supported = !mode
+ || !strcmp(mode, "auto")
+ || !strcmp(mode, "blend");
+ free(mode);
+
+ if (!is_supported)
+ return VLC_EGENERIC;
+
+ const config_chain_t *prev_chain = filter->p_cfg;
+ var_Create(filter, "opengl-filter", VLC_VAR_STRING);
+ var_SetString(filter, "opengl-filter", "glblend");
+
+ filter->p_cfg = NULL;
+ module_t *module = module_need(obj, "video filter", "opengl", true);
+ filter->p_cfg = prev_chain;
+
+ var_Destroy(filter, "opengl-filter");
+
+ if (module == NULL)
+ return VLC_EGENERIC;
+
+ return VLC_SUCCESS;
+}
+
+vlc_module_begin()
+ set_shortname("blend")
+ set_description("OpenGL blend deinterlace filter")
+ set_category(CAT_VIDEO)
+ set_subcategory(SUBCAT_VIDEO_VFILTER)
+
+ set_capability("video filter", 0)
+ set_callback(OpenVideoFilter)
+ add_shortcut("glblend")
+
+ add_submodule()
+ set_capability("opengl filter", 0)
+ set_callback(Open)
+ add_shortcut("glblend")
+vlc_module_end()
=====================================
src/libvlc-module.c
=====================================
@@ -373,6 +373,9 @@ static const char * const ppsz_deinterlace_mode_text[] = {
N_("Film NTSC (IVTC)")
};
+#define DEINTERLACE_FILTER_TEXT N_("Deinterlace filter")
+#define DEINTERLACE_FILTER_LONGTEXT N_("Deinterlace module to use.")
+
static const int pi_pos_values[] = { 0, 1, 2, 4, 8, 5, 6, 9, 10 };
static const char *const ppsz_pos_descriptions[] =
{ N_("Center"), N_("Left"), N_("Right"), N_("Top"), N_("Bottom"),
@@ -1715,6 +1718,9 @@ vlc_module_begin ()
DEINTERLACE_MODE_TEXT, DEINTERLACE_MODE_LONGTEXT )
change_string_list( ppsz_deinterlace_mode, ppsz_deinterlace_mode_text )
change_safe()
+ add_string( "deinterlace-filter", "deinterlace",
+ DEINTERLACE_FILTER_TEXT, DEINTERLACE_FILTER_LONGTEXT )
+ change_safe()
set_subcategory( SUBCAT_VIDEO_VOUT )
add_module("vout", "vout display", NULL, VOUT_TEXT, VOUT_LONGTEXT)
=====================================
src/video_output/interlacing.c
=====================================
@@ -73,6 +73,7 @@ static int DeinterlaceCallback(vlc_object_t *object, char const *cmd,
const bool is_needed = var_GetBool(vout, "deinterlace-needed");
if (!mode || !DeinterlaceIsModeValid(mode))
{
+ msg_Err(vout, "unknown deinterlace mode %s", mode);
free(mode);
return VLC_EGENERIC;
}
=====================================
src/video_output/video_output.c
=====================================
@@ -859,7 +859,9 @@ static void ThreadChangeFilters(vout_thread_sys_t *vout)
if (likely(e))
{
- free(config_ChainCreate(&e->name, &e->cfg, "deinterlace"));
+ char *filter = var_InheritString(&vout->obj, "deinterlace-filter");
+ free(config_ChainCreate(&e->name, &e->cfg, filter));
+ free(filter);
vlc_array_append_or_abort(&array_static, e);
}
}
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/62bf14a8563855aeb77441083e38824cddedaf30...8ef60b3b62adc5bd7cb2281e9d676dd938d66663
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/62bf14a8563855aeb77441083e38824cddedaf30...8ef60b3b62adc5bd7cb2281e9d676dd938d66663
You're receiving this email because of your account on code.videolan.org.
More information about the vlc-commits
mailing list