Browse Source

fix: remove green line workarounds; etv's ffmpeg 8.1.2 fixes

pull/2953/head
Jason Dove 1 week ago
parent
commit
c086f9b56c
No known key found for this signature in database
  1. 2
      .github/workflows/artifacts.yml
  2. 2
      CHANGELOG.md
  3. 34
      ErsatzTV.FFmpeg/OutputOption/AmdCropMetadataWorkaroundFilter.cs
  4. 35
      ErsatzTV.FFmpeg/OutputOption/NvidiaGreenLineWorkaroundFilter.cs
  5. 11
      ErsatzTV.FFmpeg/Pipeline/NvidiaPipelineBuilder.cs
  6. 9
      ErsatzTV.FFmpeg/Pipeline/VaapiPipelineBuilder.cs

2
.github/workflows/artifacts.yml

@ -311,7 +311,7 @@ jobs:
uses: suisei-cn/actions-download-file@v1.3.0 uses: suisei-cn/actions-download-file@v1.3.0
id: downloadffmpeg id: downloadffmpeg
with: with:
url: "https://github.com/ErsatzTV/ErsatzTV-ffmpeg/releases/download/8.1.2/ffmpeg-n8.1.2-win64-gpl-8.1.zip" url: "https://github.com/ErsatzTV/ErsatzTV-ffmpeg/releases/download/8.1.2/ffmpeg-n8.1.2-etv-g82f576a8-win64-gpl-8.1.zip"
target: ffmpeg/ target: ffmpeg/
- name: Package artifacts - name: Package artifacts

2
CHANGELOG.md

@ -17,6 +17,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Always randomize start points for all collections the first time they are used - Always randomize start points for all collections the first time they are used
- Previously, only collections scheduled during the first day of a playout build had their start points randomized - Previously, only collections scheduled during the first day of a playout build had their start points randomized
- Allow multiple ETV instances when multiple config folders are used - Allow multiple ETV instances when multiple config folders are used
- Fix green line sometimes seen with NVIDIA and AMD/VAAPI encoding
- Both bugs were in ffmpeg and ETV's patched ffmpeg 8.1.2 is required for the fixes
## [26.6.0] - 2026-07-09 ## [26.6.0] - 2026-07-09
### Added ### Added

34
ErsatzTV.FFmpeg/OutputOption/AmdCropMetadataWorkaroundFilter.cs

@ -1,34 +0,0 @@
using ErsatzTV.FFmpeg.Format;
namespace ErsatzTV.FFmpeg.OutputOption;
public class AmdCropMetadataWorkaroundFilter(string videoFormat, FrameSize frameSize) : OutputOption
{
public override string[] OutputOptions
{
get
{
if (videoFormat is not VideoFormat.Hevc)
{
return [];
}
int cropPixels = frameSize.Height switch
{
1080 => 8,
_ => 0
};
if (cropPixels == 0)
{
return [];
}
return
[
"-bsf:v",
$"{videoFormat}_metadata=crop_bottom={cropPixels}"
];
}
}
}

35
ErsatzTV.FFmpeg/OutputOption/NvidiaGreenLineWorkaroundFilter.cs

@ -1,35 +0,0 @@
using ErsatzTV.FFmpeg.Format;
namespace ErsatzTV.FFmpeg.OutputOption;
public class NvidiaGreenLineWorkaroundFilter(string videoFormat, FrameSize frameSize) : OutputOption
{
public override string[] OutputOptions
{
get
{
if (videoFormat is not VideoFormat.H264)
{
return [];
}
int cropPixels = frameSize.Height switch
{
1080 => 8,
720 => 16,
_ => 0
};
if (cropPixels == 0)
{
return [];
}
return
[
"-bsf:v",
$"{videoFormat}_metadata=crop_bottom={cropPixels}"
];
}
}
}

11
ErsatzTV.FFmpeg/Pipeline/NvidiaPipelineBuilder.cs

@ -353,17 +353,6 @@ public class NvidiaPipelineBuilder : SoftwarePipelineBuilder
context, context,
pipelineSteps); pipelineSteps);
if (ffmpegState.DecoderHardwareAccelerationMode is HardwareAccelerationMode.Nvenc &&
ffmpegState.EncoderHardwareAccelerationMode is HardwareAccelerationMode.Nvenc &&
(videoStream.FrameSize == desiredState.ScaledSize || (context is { HasSubtitleOverlay: true, HasGraphicsEngine: true } && desiredState.PaddedSize == desiredState.ScaledSize)) &&
(context.HasSubtitleOverlay || context.HasGraphicsEngine || context.HasWatermark))
{
pipelineSteps.Add(
new NvidiaGreenLineWorkaroundFilter(
desiredState.VideoFormat,
desiredState.CroppedSize.IfNone(desiredState.PaddedSize)));
}
// unknown color params can *change* during transcoding, // unknown color params can *change* during transcoding,
// which can cause ffmpeg to insert an autoscale filter that // which can cause ffmpeg to insert an autoscale filter that
// cannot accept hardware frames. // cannot accept hardware frames.

9
ErsatzTV.FFmpeg/Pipeline/VaapiPipelineBuilder.cs

@ -291,15 +291,6 @@ public class VaapiPipelineBuilder : SoftwarePipelineBuilder
currentState, currentState,
pipelineSteps); pipelineSteps);
if (ffmpegState.VaapiDriver == "radeonsi" &&
ffmpegState.EncoderHardwareAccelerationMode is HardwareAccelerationMode.Vaapi)
{
pipelineSteps.Add(
new AmdCropMetadataWorkaroundFilter(
desiredState.VideoFormat,
desiredState.CroppedSize.IfNone(desiredState.PaddedSize)));
}
return new FilterChain( return new FilterChain(
videoInputFile.FilterSteps, videoInputFile.FilterSteps,
watermarkInputFile.Map(wm => wm.FilterSteps).IfNone([]), watermarkInputFile.Map(wm => wm.FilterSteps).IfNone([]),

Loading…
Cancel
Save