Building VLC

From bibbleWiki
Jump to navigation Jump to search

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.la

Not 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
endif

Testing 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.