FF-1553 - aborting if more than 10 packet errors are detected

This commit is contained in:
John Andrews
2024-05-20 17:33:51 +12:00
parent 4ffb743577
commit 9b31e54272
5 changed files with 87 additions and 34 deletions

Binary file not shown.

Binary file not shown.

View File

@@ -22,6 +22,7 @@ public class FFMpegEncoder
private Process process;
DateTime startedAt;
private string? AbortReason;
public FFMpegEncoder(string ffMpegExe, ILogger logger)
{
@@ -39,7 +40,7 @@ public class FFMpegEncoder
/// <param name="dontAddOutputFile">if the output file should not be added to the arguments</param>
/// <param name="strictness">the strictness to use</param>
/// <returns>the result and output of the encode</returns>
public (bool successs, string output) Encode(string input, string output, List<string> arguments, bool dontAddInputFile = false, bool dontAddOutputFile = false, string strictness = "-2")
public (bool successs, string output, string? abortReason) Encode(string input, string output, List<string> arguments, bool dontAddInputFile = false, bool dontAddOutputFile = false, string strictness = "-2")
{
arguments ??= new List<string> ();
if (string.IsNullOrWhiteSpace(strictness))
@@ -74,7 +75,17 @@ public class FFMpegEncoder
var task = ExecuteShellCommand(ffMpegExe, arguments, 0);
task.Wait();
Logger.ILog("Exit Code: " + task.Result.ExitCode);
return (task.Result.ExitCode == 0, task.Result.Output); // exitcode 0 means it was successful
return (task.Result.ExitCode == 0, task.Result.Output, task.Result.AbortReason); // exitcode 0 means it was successful
}
/// <summary>
/// Aborts the file process
/// </summary>
/// <param name="reason">the reason for the abort</param>
private void Abort(string reason)
{
this.AbortReason = reason;
Cancel();
}
internal void Cancel()
@@ -236,6 +247,9 @@ public class FFMpegEncoder
}
process = null;
if (this.AbortReason != null)
result.AbortReason = this.AbortReason;
return result;
}
@@ -270,10 +284,21 @@ public class FFMpegEncoder
}
}
private int PacketErrorCount = 0;
private void CheckOutputLine(string line)
{
if (line.Contains("Skipping NAL unit"))
return; // just slightly ignore these
if (line.Contains("Error submitting a packet to the muxer"))
{
if (++PacketErrorCount > 10)
{
// Abort
Abort("Error submitting a packet to the muxer");
}
}
if (rgxTime.IsMatch(line))
{
@@ -315,12 +340,30 @@ public class FFMpegEncoder
return Task.FromResult<bool>(true);
});
}
/// <summary>
/// Represents the result of a process execution.
/// </summary>
public struct ProcessResult
{
/// <summary>
/// Indicates whether the process completed successfully.
/// </summary>
public bool Completed;
/// <summary>
/// The exit code of the process, if available.
/// </summary>
public int? ExitCode;
/// <summary>
/// The standard output of the process.
/// </summary>
public string Output;
/// <summary>
/// The reason for process abortion, if the process was aborted.
/// </summary>
public string AbortReason;
}
}

View File

@@ -287,8 +287,6 @@ public class FfmpegBuilderExecutor: FfmpegBuilderNode
}
}
startArgs.AddRange(["-c:s", "webvtt"]);
foreach (var file in model.InputFiles)
{
startArgs.Add("-i");

View File

@@ -92,36 +92,48 @@ namespace FileFlows.VideoNodes
}
else if (success.successs == false)
{
// look for known error messages
var lines = success.output.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries)
.ToArray();
if (lines.Count() >= 50) {
lines = lines.TakeLast(50).ToArray();
if (string.IsNullOrWhiteSpace(success.abortReason) == false)
{
args.FailureReason = success.abortReason;
}
else
{
// look for known error messages
var lines = success.output
.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries)
.ToArray();
string line;
if (HasLine(lines, "is not supported by the bitstream filter", out line))
{
// get that line, more efficiently that twice
int codecIndex = line.IndexOf("Codec", StringComparison.InvariantCulture);
if (codecIndex > 0)
line = line[codecIndex..];
int periodIndex = line.IndexOf(".", StringComparison.InvariantCulture);
if (periodIndex > 0)
line = line[..periodIndex];
args.FailureReason = line;
}
else if (HasLine(lines, "codec not currently supported in container", out line))
{
if (line.Contains("codec ttf")) // add more as i see them
args.FailureReason = "Subtitle codec not currently supported in container";
else // generic
args.FailureReason = "Codec not currently supported in container";
}
else if (HasLine(lines, "encoding with ProRes Proxy/LT/422/422 HQ (apco, apcs, apcn, ap4h) profile, need YUV422P10 input", out line))
{
args.FailureReason = "Encoding with ProRes Proxy/LT/422/422 HQ (apco, apcs, apcn, ap4h) profile, need YUV422P10 input";
if (lines.Count() >= 50)
{
lines = lines.TakeLast(50).ToArray();
}
string line;
if (HasLine(lines, "is not supported by the bitstream filter", out line))
{
// get that line, more efficiently that twice
int codecIndex = line.IndexOf("Codec", StringComparison.InvariantCulture);
if (codecIndex > 0)
line = line[codecIndex..];
int periodIndex = line.IndexOf(".", StringComparison.InvariantCulture);
if (periodIndex > 0)
line = line[..periodIndex];
args.FailureReason = line;
}
else if (HasLine(lines, "codec not currently supported in container", out line))
{
if (line.Contains("codec ttf")) // add more as i see them
args.FailureReason = "Subtitle codec not currently supported in container";
else // generic
args.FailureReason = "Codec not currently supported in container";
}
else if (HasLine(lines,
"encoding with ProRes Proxy/LT/422/422 HQ (apco, apcs, apcn, ap4h) profile, need YUV422P10 input",
out line))
{
args.FailureReason =
"Encoding with ProRes Proxy/LT/422/422 HQ (apco, apcs, apcn, ap4h) profile, need YUV422P10 input";
}
}
}
Encoder.AtTime -= AtTimeEvent;