Building VLC
Introduction
Just note on building VLC on Windows
Getting Started
Install MSYS from https://www.msys2.org/
The code is here https://code.videolan.org/videolan/vlc/-/tree/3.0.21
In the MSYS window pacman -S vim
Add this to your .bashrc because otherwise it uses the compiler
export PATH=/usr/bin:/mingw64/bin:$PATH
And a code fix Replace at line 78 of modules/video_output/win32/d3d11_quad.c
ID3D11DeviceContext_PSSetShaderResources(d3d_dev->d3dcontext, 0, quad->resourceCount, reset);
With
ID3D11ShaderResourceView *srv_reset[D3D11_MAX_SHADER_VIEW] = { 0 };
ID3D11DeviceContext_PSSetShaderResources(d3d_dev->d3dcontext, 0, quad->resourceCount, srv_reset);
Here is a patch
$ diff -u vlc_copy/modules/video_output/win32/d3d11_quad.c \
vlc/modules/video_output/win32/d3d11_quad.c
--- vlc_copy/modules/video_output/win32/d3d11_quad.c 2026-01-11 15:24:50.756296900 +1300
+++ vlc/modules/video_output/win32/d3d11_quad.c 2026-01-11 16:49:22.334933000 +1300
@@ -75,7 +75,10 @@
/* force unbinding the input texture, otherwise we get:
* OMSetRenderTargets: Resource being set to OM RenderTarget slot 0 is still bound on input! */
ID3D11RenderTargetView *reset[D3D11_MAX_SHADER_VIEW] = { 0 };
- ID3D11DeviceContext_PSSetShaderResources(d3d_dev->d3dcontext, 0, quad->resourceCount, reset);
+ // Broken
+ // ID3D11DeviceContext_PSSetShaderResources(d3d_dev->d3dcontext, 0, quad->resourceCount, reset);
+ ID3D11ShaderResourceView * const *srv_reset = (ID3D11ShaderResourceView * const *)reset;
+ ID3D11DeviceContext_PSSetShaderResources(d3d_dev->d3dcontext, 0, quad->resourceCount, srv_reset);
}
static bool AllocQuadVertices(vlc_object_t *o, d3d11_device_t *d3d_dev, d3d_quad_t *quad)
In the MSYS window
export CC=x86_64-w64-mingw32-gcc export CXX=x86_64-w64-mingw32-g++ export PKG_CONFIG_PATH=/mingw64/lib/pkgconfig
In the MSYS window
pacman -Syu pacman -S gcc pacman -S make pacman -S autoconf automake libtool pacman -S pkgconf pacman -S git pacman -S python pacman -S bison flex pacman -S lua
In mingw
pacman -Syu pacman -S mingw-w64-x86_64-gcc pacman -S mingw-w64-x86_64-pkgconf pacman -S mingw-w64-x86_64-ffmpeg pacman -S mingw-w64-x86_64-lua
In msys check code out
git clone https://code.videolan.org/videolan/vlc.git cd vlc git tag -l "3.0.2*" git checkout 3.0.21
In msys bootstrap
./bootstrap
In mingw configure
./configure --host=x86_64-w64-mingw32 \ --disable-qt \ --disable-skins2 \ --disable-dbus \ --disable-macosx \ --disable-smbclient \ --disable-nfs \ --disable-vnc \ --disable-bluray \ --disable-dvdread \ --disable-dvdnav \ --disable-chromaprint \ --disable-a52 \ --disable-twolame \ --disable-avcodec \ --disable-swscale \ --disable-postproc \ --disable-libmpeg2 \ --disable-mad \ --disable-mod \ --disable-libass \ --disable-x26410b \ --disable-x264 \ --disable-x265 \ --disable-vpx \ --disable-theora \ --disable-ogg \ --disable-vorbis \ --disable-flac \ --disable-soxr \ --disable-svgdec \ --disable-ncurses \ --disable-gnutls \ --disable-svg
--disable-taglib \ --disable-faad \ --disable-fdkaac \ --disable-gme \ --disable-sid \ --disable-vcd \ --disable-live555 \ --disable-lua
Check the compiler with
grep 'CC=' config.log
It should say
COLLECT_GCC=C:\msys64\mingw64\bin\x86_64-w64-mingw32-gcc.exe COLLECT_GCC=C:\msys64\mingw64\bin\x86_64-w64-mingw32-g++.exe COLLECT_GCC=C:\msys64\mingw64\bin\x86_64-w64-mingw32-gcc.exe ac_cv_prog_BUILDCC=c99 ac_cv_prog_CC=x86_64-w64-mingw32-gcc ac_cv_prog_YACC='bison -y' BUILDCC='c99' CC='x86_64-w64-mingw32-gcc' RCC= YACC='bison -y' ac_ct_CC=
If it says CC='gcc' it is configured wrong
In mingw
make -j$(nproc)
Making a Plugin
Make a directory under modules. I decided first to make one call nothing
mkdir modules/nothing
Make the code for it in modules/nothing/nothing.c
/**
* @file Nothing.c
* @brief Nothing world interface VLC module example
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
/* VLC core API headers */
#include <vlc_common.h>
#include <vlc_plugin.h>
#include <vlc_interface.h>
/* Internal state for an instance of the module */
struct intf_sys_t
{
char *who;
};
/**
* Starts our example interface.
*/
static int Open(vlc_object_t *obj)
{
intf_thread_t *intf = (intf_thread_t *)obj;
/* Allocate internal state */
intf_sys_t *sys = malloc(sizeof (*sys));
if (unlikely(sys == NULL))
return VLC_ENOMEM;
intf->p_sys = sys;
/* Read settings */
char *who = var_InheritString(intf, "Nothing-who");
if (who == NULL)
{
msg_Err(intf, "Nobody to say Nothing to!");
goto error;
}
sys->who = who;
msg_Info(intf, "Nothing %s!", who);
return VLC_SUCCESS;
error:
free(sys);
return VLC_EGENERIC;
}
/**
* Stops the interface.
*/
static void Close(vlc_object_t *obj)
{
intf_thread_t *intf = (intf_thread_t *)obj;
intf_sys_t *sys = intf->p_sys;
msg_Info(intf, "Good bye %s!", sys->who);
/* Free internal state */
free(sys->who);
free(sys);
}
/* Module descriptor */
vlc_module_begin()
set_shortname(N_("Nothing"))
set_description(N_("Nothing interface"))
set_capability("interface", 100)
set_callbacks(Open, Close)
set_category(CAT_INTERFACE)
add_string("Nothing-who", "world", "Target", "Whom to say Nothing to.", false)
vlc_module_end ()
Add to modules automake in modules/Makefile.am
nothingdir = $(pluginsdir)/nothing
libnothing_plugin_la_SOURCES = nothing/nothing.c
libnothing_plugin_la_CFLAGS = $(AM_CFLAGS) $(nothing_CFLAGS)
libnothing_plugin_la_LDFLAGS = $(AM_LDFLAGS) -rpath '$(nothingdir)'
libnothing_plugin_la_LIBADD = $(nothing_LIBS)
nothing_LTLIBRARIES = libnothing_plugin.laNot sure if needed but I did change the modules/Makefile.am to add my module
noinst_LTLIBRARIES =
check_LTLIBRARIES =
pkglib_LTLIBRARIES =
noinst_HEADERS =
check_PROGRAMS =
EXTRA_DIST =
EXTRA_SUBDIRS = \
hw/mmal
SUBDIRS = .
DIST_SUBDIRS = . $(EXTRA_SUBDIRS)
if HAVE_MMAL
SUBDIRS += hw/mmal
endif
TESTS =
dist_noinst_SCRIPTS = list.sh module.rc.in
dist_noinst_DATA = MODULES_LIST
EXTRA_LTLIBRARIES =
include common.am
include access/Makefile.am
include access/http/Makefile.am
include access/rtp/Makefile.am
include arm_neon/Makefile.am
...
include nothing/Makefile.am
if ENABLE_SOUT
include access_output/Makefile.am
include mux/Makefile.am
include stream_out/Makefile.am
endifTesting was the challenge. You have to
Make a plugins directory on windows
mkdir C:\Program Files\VideoLAN\VLC\plugins\nothing
Copy from msys to windows
copy C:\msys64\home\iwiseman\dev\vlc\modules\.libs C:\Program Files\VideoLAN\VLC\plugins\nothing\
Rebuild plugin cache
vlc-cache-gen "C:\Program Files\VideoLAN\VLC\plugins"
Run from cmd and exit vlc
"C:\Program Files\VideoLAN\VLC\vlc.exe" --extraintf=nothing --Nothing-who=world -vvv >log.txt 2>&1
Look in log.txt and you will see
[00000250158131d0] main interface debug: removing module "win32" [00000250158fecf0] main interface debug: removing module "hotkeys" [00000250158f15b0] main interface debug: removing module "nothing" [00000250158f15b0] nothing interface: Good bye world! [0000025015812e30] main playlist debug: destroying [00000250158cbe30] main playlist export debug: saving media library to file C:\Users\iwise\AppData\Roaming\vlc\ml.xspf.tmp32432 [00000250158cbe30] main playlist export debug: looking for playlist export module matching "export-xspf": 4 candidates [00000250158cbe30] main playlist export debug: using playlist export module "export" [00000250158cbe30] main playlist export debug: removing module "export" [0000025015812e30] main playlist debug: deleting item `Media Library' [0000025015812e30] main playlist debug: deleting item `Playlist' [0000025015814f50] main keystore debug: removing module "memory"
Cross Compiling to Windows
The plan is to build a Windows compatible binary from Linux using Geta. So first off I will try and build it on Linux and move to a Geta Action once I prove it can be down so. Install mingw-w64 for linux. I am using my insomnia plugin in my repo at https://git.bibble.co.nz/bibble235/insomnia
sudo apt install mingw-w64
Download the SDK
wget https://download.videolan.org/vlc/3.0.21/win64/vlc-3.0.21-win64.7z
Unzip
7z x vlc-3.0.21-win64.7z
And build
export BASE_DIR=`pwd`
x86_64-w64-mingw32-gcc -shared \
-I ${BASE_DIR}/vlc-3.0.21/sdk/include/vlc/plugins \
-I ${BASE_DIR}/vlc-3.0.21/sdk/include \
-L ${BASE_DIR}/vlc-3.0.21/sdk/lib \
-D MODULE_STRING=\"insomnia\" \
-D__PLUGIN__ \
-D'N_(x)=x' \
-o libinsomnia_plugin.dll insomnia/insomnia.c \
-lvlccore -lvlc
And that is it.