fix(ffmpeg): align transcode pipelines with ffmpeg 8 #56

Merged
timothy merged 1 commits from issue9-ffmpeg8 into main 2026-07-01 19:51:14 +02:00
6 changed files with 63 additions and 18 deletions
@@ -0,0 +1,38 @@
using ErsatzTV.FFmpeg.Capabilities;
using ErsatzTV.FFmpeg.GlobalOption.HardwareAcceleration;
using NUnit.Framework;
using Shouldly;
using static LanguageExt.Prelude;
namespace ErsatzTV.FFmpeg.Tests.GlobalOption.HardwareAcceleration;
[TestFixture]
public class QsvHardwareAccelerationOptionTests
{
[Test]
public void GlobalOptions_WithDevice_ShouldDeriveQsvDeviceFromVaapiDevice()
{
var option = new QsvHardwareAccelerationOption("/dev/dri/renderD128", FFmpegCapability.Software);
option.GlobalOptions.ShouldBe(
[
"-init_hw_device", "vaapi=va:/dev/dri/renderD128",
"-init_hw_device", "qsv=hw@va",
"-filter_hw_device", "hw"
]);
}
[Test]
public void GlobalOptions_WithHardwareDecode_ShouldEnableQsvHwaccel()
{
var option = new QsvHardwareAccelerationOption(None, FFmpegCapability.Hardware);
option.GlobalOptions.ShouldBe(
[
"-hwaccel", "qsv",
"-hwaccel_output_format", "qsv",
"-init_hw_device", "qsv=hw",
"-filter_hw_device", "hw"
]);
}
}
@@ -16,8 +16,6 @@ public class QsvHardwareAccelerationOption(Option<string> device, FFmpegCapabili
{
get
{
string[] initDevices = ["-init_hw_device", "qsv=hw", "-filter_hw_device", "hw"];
var result = new List<string>
{
"-hwaccel", "qsv",
@@ -29,18 +27,26 @@ public class QsvHardwareAccelerationOption(Option<string> device, FFmpegCapabili
result.Clear();
}
if (OperatingSystem.IsLinux())
var deviceConfigured = false;
foreach (string qsvDevice in device)
{
foreach (string qsvDevice in device)
if (!string.IsNullOrWhiteSpace(qsvDevice))
{
if (!string.IsNullOrWhiteSpace(qsvDevice))
{
result.AddRange(new[] { "-qsv_device", qsvDevice });
}
result.AddRange(
[
"-init_hw_device", $"vaapi=va:{qsvDevice}",
"-init_hw_device", "qsv=hw@va"
]);
deviceConfigured = true;
}
}
result.AddRange(initDevices);
if (!deviceConfigured)
{
result.AddRange(["-init_hw_device", "qsv=hw"]);
}
result.AddRange(["-filter_hw_device", "hw"]);
return result.ToArray();
}
+2 -2
View File
@@ -1,6 +1,6 @@
FROM mcr.microsoft.com/dotnet/aspnet:10.0-noble-amd64 AS dotnet-runtime
FROM --platform=linux/amd64 192.168.1.95:3000/timothy/ersatztv-ffmpeg:7.1.1 AS runtime-base
FROM --platform=linux/amd64 192.168.1.95:3000/timothy/ersatztv-ffmpeg:8.1.2 AS runtime-base
COPY --from=dotnet-runtime /usr/share/dotnet /usr/share/dotnet
RUN apt-get update && \
apt-get install -y --no-install-recommends python3 python3-pip && \
@@ -40,7 +40,7 @@ COPY ErsatzTV.Infrastructure/*.csproj ./ErsatzTV.Infrastructure/
COPY ErsatzTV.Infrastructure.Sqlite/*.csproj ./ErsatzTV.Infrastructure.Sqlite/
COPY ErsatzTV.Infrastructure.MySql/*.csproj ./ErsatzTV.Infrastructure.MySql/
COPY ErsatzTV.Scanner/*.csproj ./ErsatzTV.Scanner/
RUN dotnet restore -r linux-x64 ErsatzTV/
RUN dotnet restore -r linux-x64 ErsatzTV/ErsatzTV.csproj
# copy everything else and build app
COPY ErsatzTV/. ./ErsatzTV/
+4 -3
View File
@@ -1,14 +1,15 @@
FROM ghcr.io/ersatztv/ersatztv-ffmpeg:7.1.1
FROM 192.168.1.95:3000/timothy/ersatztv-ffmpeg:8.1.2
RUN apt-get update && apt-get install -y ca-certificates gnupg mkvtoolnix && \
curl -L https://dot.net/v1/dotnet-install.sh -o dotnet-install.sh && \
chmod +x ./dotnet-install.sh && \
./dotnet-install.sh --channel 9.0
./dotnet-install.sh --channel 10.0
ENV DOTNET_ROOT="/root/.dotnet"
ENV PATH="$PATH:$DOTNET_ROOT:$DOTNET_ROOT/tools"
WORKDIR /source
# copy csproj and restore as distinct layers
COPY *.sln .
COPY Directory.Build.props Directory.Build.targets Directory.Packages.props global.json .editorconfig ./
COPY artwork/* ./artwork/
COPY ErsatzTV/*.csproj ./ErsatzTV/
COPY ErsatzTV.Application/*.csproj ./ErsatzTV.Application/
@@ -20,7 +21,7 @@ COPY ErsatzTV.Infrastructure.Sqlite/*.csproj ./ErsatzTV.Infrastructure.Sqlite/
COPY ErsatzTV.Infrastructure.MySql/*.csproj ./ErsatzTV.Infrastructure.MySql/
COPY ErsatzTV.Scanner/*.csproj ./ErsatzTV.Scanner/
COPY ErsatzTV.Scanner.Tests/*.csproj ./ErsatzTV.Scanner.Tests/
RUN dotnet restore -r linux-x64 ErsatzTV/
RUN dotnet restore -r linux-x64 ErsatzTV/ErsatzTV.csproj
# copy everything else and build app
COPY ErsatzTV/. ./ErsatzTV/
+3 -3
View File
@@ -75,9 +75,9 @@ the image build.
## Dockerfile notes (`docker/Dockerfile`)
- Base image: **`192.168.1.95:3000/timothy/ersatztv-ffmpeg:7.1.1`** (our Gitea fork of
the archived `ghcr.io/ersatztv/ersatztv-ffmpeg`). FFmpeg 8 upgrade is backlogged:
base image → ersatztv-ffmpeg#4, app-side compat → ersatztv#9.
- Base image: **`192.168.1.95:3000/timothy/ersatztv-ffmpeg:8.1.2`** (our Gitea fork of
the archived `ghcr.io/ersatztv/ersatztv-ffmpeg`). FFmpeg 8 base image work landed in
ersatztv-ffmpeg#4; app-side compatibility work landed in ersatztv#9.
- Copies `Directory.Build.props`, `Directory.Build.targets`, `Directory.Packages.props`,
`global.json`, `.editorconfig` before `dotnet restore` so the image build uses the same
MSBuild config, central package versions, SDK pin, and analyzer severities as local/CI
+1 -1
View File
@@ -24,7 +24,7 @@ We diverge freely from upstream's final state. There is no upstream to merge fro
### Docker Base Images
- .NET SDK/runtime images (`mcr.microsoft.com/dotnet/sdk:10.0-noble-amd64`) — update when .NET patches ship.
- FFmpeg image: forked separately at [timothy/ersatztv-ffmpeg](http://192.168.1.95:3000/timothy/ersatztv-ffmpeg). Currently `192.168.1.95:3000/timothy/ersatztv-ffmpeg:7.1.1`. The main Dockerfile still references the upstream `ghcr.io` image and needs updating.
- FFmpeg image: forked separately at [timothy/ersatztv-ffmpeg](http://192.168.1.95:3000/timothy/ersatztv-ffmpeg). Currently `192.168.1.95:3000/timothy/ersatztv-ffmpeg:8.1.2`.
### CVE Response