# Corresponding FFmpeg sources for Thaluna

These materials accompany the Windows Full, Demo and diagnostic distributions.
The source code is available whether or not Thaluna's demo allowance is exhausted.
No API key, account or application launch is needed to read or use it.

FFmpeg is copyright its contributors and is distributed under LGPL-2.1-or-later.
Read `COPYING.LGPLv2.1` and `COPYING.GPLv2`; each archive also retains its upstream
copyright and license files. Dependencies and build tools retain their own
licenses. Qt provisioning scripts are offered under their upstream LGPL-3.0
option; the Qt archive contains the full LGPLv3 and GPLv3 texts.

## Inventory and provenance

`manifest.json` records the immutable upstream source URLs, SHA-256 checksums,
binary checksums, exact OpenCV commits, Qt configuration and PySide6 wheel.
`SHA256SUMS` is provided for command-line source integrity checks.

| Binary group | Included sources |
| --- | --- |
| `opencv_videoio_ffmpeg4100_64.dll` | FFmpeg n4.4.4, libvpx v1.14.0, AOM v3.9.0, OpenH264 v1.8.0 API headers, OpenCV wrapper/build scripts and complete pinned OpenCV tree |
| `opencv_videoio_ffmpeg4120_64.dll` | FFmpeg n4.4.6, libvpx v1.15.2, AOM v3.12.1, OpenH264 v1.8.0 API headers, OpenCV wrapper/build scripts and complete pinned OpenCV tree |
| Qt / PySide6 6.9.2 FFmpeg DLLs | FFmpeg n7.1.1 and Qt 6.9.2 provisioning/build scripts |

The two OpenCV DLLs were compared with the Git blobs in OpenCV's official
binary repository. Their corresponding `*_src` commits explicitly identify those
binary commits. Every supplied source blob was checked against that repository.
The Qt FFmpeg DLLs were compared byte-for-byte with the official
`pyside6_addons-6.9.2-cp39-abi3-win_amd64.whl`, whose SHA-256 was checked against
PyPI. The Qt FFmpeg source archive also matches the SHA-1 recorded by Qt's build
script. These are upstream provenance checks, not a claim of a locally reproduced,
byte-identical compiler build.

Thaluna did not modify the distributed FFmpeg binaries or their sources.
`changes.diff` is therefore empty. Original build scripts may generate or adjust
build files; those scripts are included unchanged.

## Building the Qt FFmpeg libraries

Extract `archives/qt-6.9.2/FFmpeg-n7.1.1.tar.gz` and
`archives/qt-6.9.2/qt5-provisioning-v6.9.2.tar.gz` into a working directory.
In the Qt archive, read:

- `coin/provisioning/common/windows/install-ffmpeg.ps1`
- `coin/provisioning/common/shared/ffmpeg_config_options.txt`
- `coin/provisioning/common/windows/helpers.ps1`

The Windows x64 MSVC configuration below was read from the distributed
`avcodec-61.dll` and matches the Qt provisioning recipe:

```sh
mkdir -p build/msvc
cd build/msvc
../../configure --prefix=installed --disable-programs --disable-doc --disable-debug --enable-network --disable-lzma --enable-pic --disable-vulkan --disable-v4l2-m2m --disable-decoder=truemotion1 --toolchain=msvc --enable-shared --disable-static
make install -j
```

Run this in an MSYS2 shell inheriting the x64 Visual Studio compiler environment;
the build needs the MSVC toolchain, GNU make and an assembler supported by FFmpeg.
The upstream Qt scripts document how Qt prepares that environment. Do not run
the entire CI provisioning script blindly: it installs for several platforms and
changes machine-level environment variables. The x64 MSVC function is the
relevant part. Neither `--enable-gpl` nor `--enable-nonfree` is used.

## Building an OpenCV FFmpeg wrapper

Use a Linux build environment with Docker, as specified by OpenCV's supplied
scripts. Select one matching archive directory, `opencv-4100` or `opencv-4120`.
The following shell commands assume `SOURCES` is its absolute path and `work`
is a new empty working directory:

```sh
mkdir -p work/opencv work/build/ffmpeg work/build/libvpx work/build/aom work/build/openh264
tar -xJf "$SOURCES/opencv_ffmpeg.tar.xz" -C work
tar -xzf "$SOURCES"/opencv-full-*.tar.gz --strip-components=1 -C work/opencv
tar -xJf "$SOURCES"/build/ffmpeg/ffmpeg-src-*.tar.xz -C work/build/ffmpeg
tar -xJf "$SOURCES"/build/libvpx/libvpx-src-*.tar.xz -C work/build/libvpx
tar -xJf "$SOURCES"/build/aom/aom-src-*.tar.xz -C work/build/aom
tar -xJf "$SOURCES"/build/openh264/openh264-api-headers-*.tar.xz -C work/build/openh264
cd work
BUILD_SKIP_DOWNLOAD_SOURCES=1 ./ffmpeg/build_via_docker.sh
```

The source archives contain no enclosing directory except for the explicitly
handled full OpenCV archive. OpenCV's `ffmpeg/docker/Dockerfile` lists the required
Linux/MinGW packages, and `ffmpeg/make_mingw.sh` plus
`ffmpeg/build_videoio_plugin.sh` contain the complete build and link commands.
The Docker image requires network access to install build tools. Using
`BUILD_SKIP_DOWNLOAD_SOURCES=1` keeps the build on the supplied source versions.

FFmpeg is statically incorporated into the wrapper DLL; Thaluna loads that
replaceable DLL. OpenH264 is a dynamic loader plus API headers here, not a bundled
Cisco codec implementation. AOM and libvpx sources and license notices are included.
The x64 output is `ffmpeg/opencv_videoio_ffmpeg_64.dll`. Install it with the
appropriate versioned filename from the inventory above. Preserve the same ABI.

## Installing replacement libraries

Close all Thaluna processes and back up the application directory. Replace the
Qt FFmpeg DLLs in `_internal/PySide6/` or the relevant OpenCV wrapper in
`_internal/cv2/`, then restart Thaluna. See the top-level `FFMPEG_NOTICE.md` for
the detailed replacement and LGPL rights notice. Developer release checks do
not run in the application and do not prevent user-modified libraries from loading.

## Maintaining a Thaluna source checkout

Large source archives are restored from the pinned manifest when absent:

```bat
venv\Scripts\python.exe _tools\maintenance\ffmpeg_compliance.py --fetch
venv\Scripts\python.exe _tools\maintenance\ffmpeg_compliance.py --dist dist\Thaluna
venv\Scripts\python.exe _tools\maintenance\ffmpeg_compliance.py --dist dist\Thaluna_Demo
```

The build and publish scripts refuse a mismatched binary/source inventory.
After updating Qt, PySide6 or OpenCV, identify and verify the new upstream
binaries and corresponding sources before updating the manifest. Do not simply
replace checksum values to bypass a failed check.
