Browse Source

optimize qsv h264 stream startup (#2835)

pull/2838/head
Jason Dove 5 months ago committed by GitHub
parent
commit
fd86cb55f9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 7
      ErsatzTV.Application/Streaming/HlsSessionWorker.cs
  2. 18
      ErsatzTV.Infrastructure/Metadata/LocalStatisticsProvider.cs

7
ErsatzTV.Application/Streaming/HlsSessionWorker.cs

@ -313,9 +313,6 @@ public class HlsSessionWorker : IHlsSessionWorker
var sw = Stopwatch.StartNew(); var sw = Stopwatch.StartNew();
try try
{ {
DateTimeOffset start = DateTimeOffset.Now;
DateTimeOffset finish = start.AddSeconds(8);
string playlistFileName = Path.Combine(_workingDirectory, "live.m3u8"); string playlistFileName = Path.Combine(_workingDirectory, "live.m3u8");
_logger.LogDebug("Waiting for playlist to exist"); _logger.LogDebug("Waiting for playlist to exist");
@ -326,6 +323,10 @@ public class HlsSessionWorker : IHlsSessionWorker
_logger.LogDebug("Playlist exists"); _logger.LogDebug("Playlist exists");
// start the segment-wait deadline only after the playlist file appears,
// so slow pipeline setup (e.g. h264 profile probing) doesn't consume the budget
DateTimeOffset finish = DateTimeOffset.Now.AddSeconds(8);
var segmentCount = 0; var segmentCount = 0;
int lastSegmentCount = -1; int lastSegmentCount = -1;
while (DateTimeOffset.Now < finish && segmentCount < initialSegmentCount) while (DateTimeOffset.Now < finish && segmentCount < initialSegmentCount)

18
ErsatzTV.Infrastructure/Metadata/LocalStatisticsProvider.cs

@ -359,9 +359,11 @@ public partial class LocalStatisticsProvider : ILocalStatisticsProvider
string filePath, string filePath,
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
// only scans first 30 seconds
string[] arguments = string[] arguments =
[ [
"-hide_banner", "-hide_banner",
"-t", "30",
"-i", filePath, "-i", filePath,
"-c", "copy", "-c", "copy",
"-bsf:v", "trace_headers", "-bsf:v", "trace_headers",
@ -370,6 +372,11 @@ public partial class LocalStatisticsProvider : ILocalStatisticsProvider
var uniqueProfiles = new System.Collections.Generic.HashSet<string>(); var uniqueProfiles = new System.Collections.Generic.HashSet<string>();
// cancel as soon as we find a second distinct profile_idc
using var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
try
{
CommandResult traceHeaders = await Cli.Wrap(ffmpegPath) CommandResult traceHeaders = await Cli.Wrap(ffmpegPath)
.WithArguments(arguments) .WithArguments(arguments)
.WithValidation(CommandResultValidation.None) .WithValidation(CommandResultValidation.None)
@ -380,9 +387,13 @@ public partial class LocalStatisticsProvider : ILocalStatisticsProvider
if (idx >= 0) if (idx >= 0)
{ {
uniqueProfiles.Add(line[idx..]); uniqueProfiles.Add(line[idx..]);
if (uniqueProfiles.Count > 1)
{
linkedCts.Cancel();
}
} }
})) }))
.ExecuteAsync(cancellationToken); .ExecuteAsync(linkedCts.Token);
if (traceHeaders.ExitCode != 0) if (traceHeaders.ExitCode != 0)
{ {
@ -393,6 +404,11 @@ public partial class LocalStatisticsProvider : ILocalStatisticsProvider
return Option<int>.None; return Option<int>.None;
} }
}
catch (OperationCanceledException) when (!cancellationToken.IsCancellationRequested)
{
// nothing to do here - canceled because a second profile was found
}
return uniqueProfiles.Count; return uniqueProfiles.Count;
} }

Loading…
Cancel
Save