Fixed process hang on pipe images format mismatch

Former-commit-id: fe646752d3
This commit is contained in:
Maxim Bagryantsev 2021-03-15 20:35:19 +03:00
parent 6602c87022
commit ba8904429d
5 changed files with 103 additions and 4 deletions

View file

@ -21,7 +21,7 @@ public static IEnumerable<IVideoFrame> CreateBitmaps(int count, PixelFormat fmt,
}
}
private static BitmapVideoFrameWrapper CreateVideoFrame(int index, PixelFormat fmt, int w, int h, float scaleNoise, float offset)
public static BitmapVideoFrameWrapper CreateVideoFrame(int index, PixelFormat fmt, int w, int h, float scaleNoise, float offset)
{
var bitmap = new Bitmap(w, h, fmt);

View file

@ -87,6 +87,92 @@ public void Video_ToMP4_Args_Pipe(System.Drawing.Imaging.PixelFormat pixelFormat
Assert.IsTrue(success);
}
[TestMethod, Timeout(10000)]
public void Video_ToMP4_Args_Pipe_DifferentImageSizes()
{
using var outputFile = new TemporaryFile($"out{VideoType.Mp4.Extension}");
var frames = new List<IVideoFrame>
{
BitmapSource.CreateVideoFrame(0, System.Drawing.Imaging.PixelFormat.Format24bppRgb, 255, 255, 1, 0),
BitmapSource.CreateVideoFrame(0, System.Drawing.Imaging.PixelFormat.Format24bppRgb, 256, 256, 1, 0)
};
var videoFramesSource = new RawVideoPipeSource(frames);
var ex = Assert.ThrowsException<FFMpegException>(() => FFMpegArguments
.FromPipeInput(videoFramesSource)
.OutputToFile(outputFile, false, opt => opt
.WithVideoCodec(VideoCodec.LibX264))
.ProcessSynchronously());
Assert.IsInstanceOfType(ex.GetBaseException(), typeof(FFMpegStreamFormatException));
}
[TestMethod, Timeout(10000)]
public async Task Video_ToMP4_Args_Pipe_DifferentImageSizes_Async()
{
using var outputFile = new TemporaryFile($"out{VideoType.Mp4.Extension}");
var frames = new List<IVideoFrame>
{
BitmapSource.CreateVideoFrame(0, System.Drawing.Imaging.PixelFormat.Format24bppRgb, 255, 255, 1, 0),
BitmapSource.CreateVideoFrame(0, System.Drawing.Imaging.PixelFormat.Format24bppRgb, 256, 256, 1, 0)
};
var videoFramesSource = new RawVideoPipeSource(frames);
var ex = await Assert.ThrowsExceptionAsync<FFMpegException>(() => FFMpegArguments
.FromPipeInput(videoFramesSource)
.OutputToFile(outputFile, false, opt => opt
.WithVideoCodec(VideoCodec.LibX264))
.ProcessAsynchronously());
Assert.IsInstanceOfType(ex.GetBaseException(), typeof(FFMpegStreamFormatException));
}
[TestMethod, Timeout(10000)]
public void Video_ToMP4_Args_Pipe_DifferentPixelFormats()
{
using var outputFile = new TemporaryFile($"out{VideoType.Mp4.Extension}");
var frames = new List<IVideoFrame>
{
BitmapSource.CreateVideoFrame(0, System.Drawing.Imaging.PixelFormat.Format24bppRgb, 255, 255, 1, 0),
BitmapSource.CreateVideoFrame(0, System.Drawing.Imaging.PixelFormat.Format32bppRgb, 255, 255, 1, 0)
};
var videoFramesSource = new RawVideoPipeSource(frames);
var ex = Assert.ThrowsException<FFMpegException>(() => FFMpegArguments
.FromPipeInput(videoFramesSource)
.OutputToFile(outputFile, false, opt => opt
.WithVideoCodec(VideoCodec.LibX264))
.ProcessSynchronously());
Assert.IsInstanceOfType(ex.GetBaseException(), typeof(FFMpegStreamFormatException));
}
[TestMethod, Timeout(10000)]
public async Task Video_ToMP4_Args_Pipe_DifferentPixelFormats_Async()
{
using var outputFile = new TemporaryFile($"out{VideoType.Mp4.Extension}");
var frames = new List<IVideoFrame>
{
BitmapSource.CreateVideoFrame(0, System.Drawing.Imaging.PixelFormat.Format24bppRgb, 255, 255, 1, 0),
BitmapSource.CreateVideoFrame(0, System.Drawing.Imaging.PixelFormat.Format32bppRgb, 255, 255, 1, 0)
};
var videoFramesSource = new RawVideoPipeSource(frames);
var ex = await Assert.ThrowsExceptionAsync<FFMpegException>(() => FFMpegArguments
.FromPipeInput(videoFramesSource)
.OutputToFile(outputFile, false, opt => opt
.WithVideoCodec(VideoCodec.LibX264))
.ProcessAsynchronously());
Assert.IsInstanceOfType(ex.GetBaseException(), typeof(FFMpegStreamFormatException));
}
[TestMethod, Timeout(10000)]
public void Video_ToMP4_Args_StreamPipe()
{
@ -114,6 +200,8 @@ await FFMpegArguments
.ProcessAsynchronously();
});
}
[TestMethod, Timeout(10000)]
public void Video_StreamFile_OutputToMemoryStream()
{

View file

@ -42,12 +42,15 @@ public async Task During(CancellationToken cancellationToken = default)
{
await ProcessDataAsync(cancellationToken);
Debug.WriteLine($"Disconnecting NamedPipeServerStream on {GetType().Name}");
Pipe?.Disconnect();
}
catch (TaskCanceledException)
{
Debug.WriteLine($"ProcessDataAsync on {GetType().Name} cancelled");
}
finally
{
Pipe?.Disconnect();
}
}
protected abstract Task ProcessDataAsync(CancellationToken token);

View file

@ -49,4 +49,12 @@ public FFMpegArgumentException(string? message = null, Exception? innerException
{
}
}
public class FFMpegStreamFormatException : FFMpegException
{
public FFMpegStreamFormatException(FFMpegExceptionType type, string message, Exception? innerException = null)
: base(type, message, innerException)
{
}
}
}

View file

@ -64,7 +64,7 @@ public async Task WriteAsync(System.IO.Stream outputStream, CancellationToken ca
private void CheckFrameAndThrow(IVideoFrame frame)
{
if (frame.Width != Width || frame.Height != Height || frame.Format != StreamFormat)
throw new FFMpegException(FFMpegExceptionType.Operation, "Video frame is not the same format as created raw video stream\r\n" +
throw new FFMpegStreamFormatException(FFMpegExceptionType.Operation, "Video frame is not the same format as created raw video stream\r\n" +
$"Frame format: {frame.Width}x{frame.Height} pix_fmt: {frame.Format}\r\n" +
$"Stream format: {Width}x{Height} pix_fmt: {StreamFormat}");
}