Files
ersatztv/ErsatzTV/Controllers/Api/Requests/CreateFFmpegProfileRequest.cs
T
timothyandtimothy ed8b602445
Build ErsatzTV Image / CI toolchain image resolves (push) Successful in 11s
Build ErsatzTV Image / Delimiter ban (release path) (push) Successful in 25s
Build ErsatzTV Image / Build & test (.NET) (push) Successful in 9m9s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (push) Successful in 6m41s
Build ErsatzTV Image / Functional E2E (curl + UI contracts) (push) Successful in 6m23s
Build ErsatzTV Image / API docs in sync (OpenAPI + endpoint index) (push) Skipped
Build ErsatzTV Image / Formatting (changed .cs conform to .editorconfig) (push) Skipped
Build ErsatzTV Image / Build & push image (amd64) (push) Successful in 6m23s
feat(735): bound the numeric FFmpeg profile fields with a 422, and expose readrate pacing (#847)
Co-authored-by: Timothy <timothy@noreply.gitea.tblindustries.be>
2026-08-26 22:05:38 +00:00

91 lines
3.0 KiB
C#

using System.ComponentModel;
using ErsatzTV.Application.FFmpegProfiles;
using ErsatzTV.Core.Domain;
using ErsatzTV.Core.FFmpeg;
namespace ErsatzTV.Controllers.Api.Requests;
public record CreateFFmpegProfileRequest(
string Name,
int ThreadCount,
bool NormalizeAudio,
bool NormalizeVideo,
HardwareAccelerationKind HardwareAcceleration,
string VaapiDisplay,
VaapiDriver VaapiDriver,
string VaapiDevice,
[property: Description(
"Extra surfaces in the QSV upload pool. Must be at least 64 when set; a smaller pool "
+ "leaves no headroom for frames in flight and the transcode writes nothing at all. On update, a "
+ "value equal to the one already stored is accepted unchanged, so a profile written before this "
+ "validation existed stays editable.")]
int? QsvExtraHardwareFrames,
int ResolutionId,
ScalingBehavior ScalingBehavior,
FilterMode PadMode,
FFmpegProfileVideoFormat VideoFormat,
string VideoProfile,
string VideoPreset,
bool AllowBFrames,
FFmpegProfileBitDepth BitDepth,
int VideoBitrate,
int VideoBufferSize,
FFmpegProfileTonemapAlgorithm TonemapAlgorithm,
FFmpegProfileAudioFormat AudioFormat,
int AudioBitrate,
int AudioBufferSize,
NormalizeLoudnessMode NormalizeLoudnessMode,
double? TargetLoudness,
int AudioChannels,
int AudioSampleRate,
bool NormalizeFramerate,
bool NormalizeColors,
bool DeinterlaceVideo,
bool? QsvPreferNativeDecoder = null,
[property: Description(
"Realtime pacing multiplier for the input. Unset keeps the built-in pacing "
+ "(1.05, or 1.0 for a stream copy). Must be between 1.0 and 2.0 when set.")]
double? ReadRate = null,
[property: Description(
"Rate a lagging realtime input may read at until it is level again. Unset keeps the "
+ "built-in 6.0. Must be between 1.0 and 10.0, and GREATER than the read rate — equal is "
+ "zero headroom, which is functionally no catchup.")]
double? ReadRateCatchup = null)
{
public CreateFFmpegProfile ToCommand() =>
new(
Name,
ThreadCount,
NormalizeAudio,
NormalizeVideo,
HardwareAcceleration,
VaapiDisplay,
VaapiDriver,
VaapiDevice,
QsvExtraHardwareFrames,
ResolutionId,
ScalingBehavior,
PadMode,
VideoFormat,
VideoProfile,
VideoPreset,
AllowBFrames,
BitDepth,
VideoBitrate,
VideoBufferSize,
TonemapAlgorithm,
AudioFormat,
AudioBitrate,
AudioBufferSize,
NormalizeLoudnessMode,
TargetLoudness,
AudioChannels,
AudioSampleRate,
NormalizeFramerate,
NormalizeColors,
DeinterlaceVideo,
QsvPreferNativeDecoder ?? true,
ReadRate,
ReadRateCatchup);
}