|
|
@ -80,12 +80,11 @@ public class NvidiaPipelineBuilder : SoftwarePipelineBuilder |
|
|
|
}; |
|
|
|
}; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected override void SetDecoder( |
|
|
|
protected override Option<IDecoder> SetDecoder( |
|
|
|
VideoInputFile videoInputFile, |
|
|
|
VideoInputFile videoInputFile, |
|
|
|
VideoStream videoStream, |
|
|
|
VideoStream videoStream, |
|
|
|
FFmpegState ffmpegState, |
|
|
|
FFmpegState ffmpegState, |
|
|
|
PipelineContext context, |
|
|
|
PipelineContext context) |
|
|
|
ICollection<IPipelineStep> pipelineSteps) |
|
|
|
|
|
|
|
{ |
|
|
|
{ |
|
|
|
Option<IDecoder> maybeDecoder = (ffmpegState.DecoderHardwareAccelerationMode, videoStream.Codec) switch |
|
|
|
Option<IDecoder> maybeDecoder = (ffmpegState.DecoderHardwareAccelerationMode, videoStream.Codec) switch |
|
|
|
{ |
|
|
|
{ |
|
|
@ -105,7 +104,10 @@ public class NvidiaPipelineBuilder : SoftwarePipelineBuilder |
|
|
|
foreach (IDecoder decoder in maybeDecoder) |
|
|
|
foreach (IDecoder decoder in maybeDecoder) |
|
|
|
{ |
|
|
|
{ |
|
|
|
videoInputFile.AddOption(decoder); |
|
|
|
videoInputFile.AddOption(decoder); |
|
|
|
|
|
|
|
return Some(decoder); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return None; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected override FilterChain SetVideoFilters( |
|
|
|
protected override FilterChain SetVideoFilters( |
|
|
@ -114,6 +116,7 @@ public class NvidiaPipelineBuilder : SoftwarePipelineBuilder |
|
|
|
Option<WatermarkInputFile> watermarkInputFile, |
|
|
|
Option<WatermarkInputFile> watermarkInputFile, |
|
|
|
Option<SubtitleInputFile> subtitleInputFile, |
|
|
|
Option<SubtitleInputFile> subtitleInputFile, |
|
|
|
PipelineContext context, |
|
|
|
PipelineContext context, |
|
|
|
|
|
|
|
Option<IDecoder> maybeDecoder, |
|
|
|
FFmpegState ffmpegState, |
|
|
|
FFmpegState ffmpegState, |
|
|
|
FrameState desiredState, |
|
|
|
FrameState desiredState, |
|
|
|
string fontsFolder, |
|
|
|
string fontsFolder, |
|
|
@ -132,11 +135,13 @@ public class NvidiaPipelineBuilder : SoftwarePipelineBuilder |
|
|
|
: videoStream.PixelFormat, |
|
|
|
: videoStream.PixelFormat, |
|
|
|
|
|
|
|
|
|
|
|
IsAnamorphic = videoStream.IsAnamorphic, |
|
|
|
IsAnamorphic = videoStream.IsAnamorphic, |
|
|
|
FrameDataLocation = ffmpegState.DecoderHardwareAccelerationMode == HardwareAccelerationMode.Nvenc |
|
|
|
|
|
|
|
? FrameDataLocation.Hardware |
|
|
|
|
|
|
|
: FrameDataLocation.Software |
|
|
|
|
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
foreach (IDecoder decoder in maybeDecoder) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
currentState = decoder.NextState(currentState); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// if (context.HasSubtitleOverlay || context.HasWatermark)
|
|
|
|
// if (context.HasSubtitleOverlay || context.HasWatermark)
|
|
|
|
// {
|
|
|
|
// {
|
|
|
|
// IPixelFormat pixelFormat = desiredState.PixelFormat.IfNone(
|
|
|
|
// IPixelFormat pixelFormat = desiredState.PixelFormat.IfNone(
|
|
|
@ -275,7 +280,7 @@ public class NvidiaPipelineBuilder : SoftwarePipelineBuilder |
|
|
|
|
|
|
|
|
|
|
|
if (!videoStream.ColorParams.IsBt709) |
|
|
|
if (!videoStream.ColorParams.IsBt709) |
|
|
|
{ |
|
|
|
{ |
|
|
|
_logger.LogDebug("Adding colorspace filter"); |
|
|
|
// _logger.LogDebug("Adding colorspace filter");
|
|
|
|
var colorspace = new ColorspaceFilter(currentState, videoStream, format, false); |
|
|
|
var colorspace = new ColorspaceFilter(currentState, videoStream, format, false); |
|
|
|
|
|
|
|
|
|
|
|
currentState = colorspace.NextState(currentState); |
|
|
|
currentState = colorspace.NextState(currentState); |
|
|
@ -292,12 +297,20 @@ public class NvidiaPipelineBuilder : SoftwarePipelineBuilder |
|
|
|
_logger.LogDebug( |
|
|
|
_logger.LogDebug( |
|
|
|
"HasSubtitleOverlay || HasWatermark && FrameDataLocation == FrameDataLocation.Hardware"); |
|
|
|
"HasSubtitleOverlay || HasWatermark && FrameDataLocation == FrameDataLocation.Hardware"); |
|
|
|
|
|
|
|
|
|
|
|
var hardwareDownload = new CudaHardwareDownloadFilter(currentState.PixelFormat); |
|
|
|
var hardwareDownload = new CudaHardwareDownloadFilter(currentState.PixelFormat, None); |
|
|
|
currentState = hardwareDownload.NextState(currentState); |
|
|
|
currentState = hardwareDownload.NextState(currentState); |
|
|
|
result.Add(hardwareDownload); |
|
|
|
result.Add(hardwareDownload); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (currentState.FrameDataLocation == FrameDataLocation.Hardware && |
|
|
|
|
|
|
|
ffmpegState.EncoderHardwareAccelerationMode == HardwareAccelerationMode.None) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
var hardwareDownload = new CudaHardwareDownloadFilter(currentState.PixelFormat, Some(format)); |
|
|
|
|
|
|
|
currentState = hardwareDownload.NextState(currentState); |
|
|
|
|
|
|
|
result.Add(hardwareDownload); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (currentState.PixelFormat.Map(f => f.FFmpegName) != format.FFmpegName) |
|
|
|
if (currentState.PixelFormat.Map(f => f.FFmpegName) != format.FFmpegName) |
|
|
|
{ |
|
|
|
{ |
|
|
|
_logger.LogDebug( |
|
|
|
_logger.LogDebug( |
|
|
@ -332,14 +345,6 @@ public class NvidiaPipelineBuilder : SoftwarePipelineBuilder |
|
|
|
pipelineSteps.Add(new PixelFormatOutputOption(format)); |
|
|
|
pipelineSteps.Add(new PixelFormatOutputOption(format)); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (currentState.FrameDataLocation == FrameDataLocation.Hardware && |
|
|
|
|
|
|
|
ffmpegState.EncoderHardwareAccelerationMode == HardwareAccelerationMode.None) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
var hardwareDownload = new CudaHardwareDownloadFilter(Some(format)); |
|
|
|
|
|
|
|
currentState = hardwareDownload.NextState(currentState); |
|
|
|
|
|
|
|
result.Add(hardwareDownload); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return result; |
|
|
|
return result; |
|
|
@ -398,6 +403,8 @@ public class NvidiaPipelineBuilder : SoftwarePipelineBuilder |
|
|
|
videoStream.SquarePixelFrameSize(currentState.PaddedSize), |
|
|
|
videoStream.SquarePixelFrameSize(currentState.PaddedSize), |
|
|
|
_logger); |
|
|
|
_logger); |
|
|
|
watermarkOverlayFilterSteps.Add(watermarkFilter); |
|
|
|
watermarkOverlayFilterSteps.Add(watermarkFilter); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
currentState = watermarkFilter.NextState(currentState); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return currentState; |
|
|
|
return currentState; |
|
|
@ -473,7 +480,7 @@ public class NvidiaPipelineBuilder : SoftwarePipelineBuilder |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (currentState.FrameDataLocation == FrameDataLocation.Hardware) |
|
|
|
if (currentState.FrameDataLocation == FrameDataLocation.Hardware) |
|
|
|
{ |
|
|
|
{ |
|
|
|
var cudaDownload = new CudaHardwareDownloadFilter(currentState.PixelFormat); |
|
|
|
var cudaDownload = new CudaHardwareDownloadFilter(currentState.PixelFormat, None); |
|
|
|
currentState = cudaDownload.NextState(currentState); |
|
|
|
currentState = cudaDownload.NextState(currentState); |
|
|
|
videoInputFile.FilterSteps.Add(cudaDownload); |
|
|
|
videoInputFile.FilterSteps.Add(cudaDownload); |
|
|
|
} |
|
|
|
} |
|
|
@ -527,11 +534,19 @@ public class NvidiaPipelineBuilder : SoftwarePipelineBuilder |
|
|
|
{ |
|
|
|
{ |
|
|
|
IPipelineFilterStep scaleStep; |
|
|
|
IPipelineFilterStep scaleStep; |
|
|
|
|
|
|
|
|
|
|
|
if (currentState.ScaledSize != desiredState.ScaledSize && ffmpegState is |
|
|
|
bool needsToScale = currentState.ScaledSize != desiredState.ScaledSize; |
|
|
|
{ |
|
|
|
if (!needsToScale) |
|
|
|
DecoderHardwareAccelerationMode: HardwareAccelerationMode.None, |
|
|
|
{ |
|
|
|
EncoderHardwareAccelerationMode: HardwareAccelerationMode.None |
|
|
|
return currentState; |
|
|
|
} && context is { HasWatermark: false, HasSubtitleOverlay: false, ShouldDeinterlace: false }) |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool decodedToSoftware = ffmpegState.DecoderHardwareAccelerationMode == HardwareAccelerationMode.None; |
|
|
|
|
|
|
|
bool softwareEncoder = ffmpegState.EncoderHardwareAccelerationMode == HardwareAccelerationMode.None; |
|
|
|
|
|
|
|
bool noHardwareFilters = context is |
|
|
|
|
|
|
|
{ HasWatermark: false, HasSubtitleOverlay: false, ShouldDeinterlace: false }; |
|
|
|
|
|
|
|
bool needsToPad = currentState.PaddedSize != desiredState.PaddedSize; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (decodedToSoftware && (needsToPad || noHardwareFilters && softwareEncoder)) |
|
|
|
{ |
|
|
|
{ |
|
|
|
scaleStep = new ScaleFilter( |
|
|
|
scaleStep = new ScaleFilter( |
|
|
|
currentState, |
|
|
|
currentState, |
|
|
|