Files
ersatztv/ErsatzTV.FFmpeg/Filter/OverlayWatermarkFilter.cs
T
Jason DoveandGitHub 245c4ec359 code analysis and cleanup (#1411)
* cleanup scanner project

* cleanup infrastructure projects

* cleanup ffmpeg project

* cleanup core project

* cleanup app project

* cleanup main project

* update dependencies

* code cleanup
2023-09-03 06:23:42 -05:00

85 lines
3.5 KiB
C#

using ErsatzTV.FFmpeg.Format;
using ErsatzTV.FFmpeg.State;
using Microsoft.Extensions.Logging;
namespace ErsatzTV.FFmpeg.Filter;
public class OverlayWatermarkFilter : BaseFilter
{
private readonly ILogger _logger;
private readonly IPixelFormat _outputPixelFormat;
private readonly FrameSize _resolution;
private readonly FrameSize _squarePixelFrameSize;
private readonly WatermarkState _watermarkState;
public OverlayWatermarkFilter(
WatermarkState watermarkState,
FrameSize resolution,
FrameSize squarePixelFrameSize,
IPixelFormat outputPixelFormat,
ILogger logger)
{
_watermarkState = watermarkState;
_resolution = resolution;
_squarePixelFrameSize = squarePixelFrameSize;
_outputPixelFormat = outputPixelFormat;
_logger = logger;
}
public override string Filter => $"overlay={Position}:format={(_outputPixelFormat.BitDepth == 10 ? '1' : '0')}";
protected string Position
{
get
{
(double horizontalMargin, double verticalMargin) = _watermarkState.PlaceWithinSourceContent
? SourceContentMargins()
: NormalMargins();
return _watermarkState.Location switch
{
// TODO: can these be pre-calculated (and used with accelerated overlay filters)
WatermarkLocation.BottomLeft => $"x={horizontalMargin}:y=H-h-{verticalMargin}",
WatermarkLocation.TopLeft => $"x={horizontalMargin}:y={verticalMargin}",
WatermarkLocation.TopRight => $"x=W-w-{horizontalMargin}:y={verticalMargin}",
WatermarkLocation.TopMiddle => $"x=(W-w)/2:y={verticalMargin}",
WatermarkLocation.RightMiddle => $"x=W-w-{horizontalMargin}:y=(H-h)/2",
WatermarkLocation.BottomMiddle => $"x=(W-w)/2:y=H-h-{verticalMargin}",
WatermarkLocation.LeftMiddle => $"x={horizontalMargin}:y=(H-h)/2",
_ => $"x=W-w-{horizontalMargin}:y=H-h-{verticalMargin}"
};
}
}
public override FrameState NextState(FrameState currentState) =>
currentState with { FrameDataLocation = FrameDataLocation.Software };
private WatermarkMargins NormalMargins()
{
double horizontalMargin = Math.Round(_watermarkState.HorizontalMarginPercent / 100.0 * _resolution.Width);
double verticalMargin = Math.Round(_watermarkState.VerticalMarginPercent / 100.0 * _resolution.Height);
return new WatermarkMargins(horizontalMargin, verticalMargin);
}
private WatermarkMargins SourceContentMargins()
{
int horizontalPadding = _resolution.Width - _squarePixelFrameSize.Width;
int verticalPadding = _resolution.Height - _squarePixelFrameSize.Height;
_logger.LogDebug("Resolution: {Width}x{Height}", _resolution.Width, _resolution.Height);
_logger.LogDebug("Square Pix: {Width}x{Height}", _squarePixelFrameSize.Width, _squarePixelFrameSize.Height);
double horizontalMargin = Math.Round(
_watermarkState.HorizontalMarginPercent / 100.0 * _squarePixelFrameSize.Width
+ horizontalPadding / 2.0);
double verticalMargin = Math.Round(
_watermarkState.VerticalMarginPercent / 100.0 * _squarePixelFrameSize.Height
+ verticalPadding / 2.0);
return new WatermarkMargins(horizontalMargin, verticalMargin);
}
private sealed record WatermarkMargins(double HorizontalMargin, double VerticalMargin);
}