private async Task ParseInputStream(IBoundedQueue <MutableByteImage> queue, IBoundedQueue <byte[]> chunksQueue, int width, int height, ChunkedSimpleMemoryStream memoryStream) { int count = 0; while (true) { try { var item = await chunksQueue.DequeueOrDefault(); if (item == default) { break; } _logger.NotifyFillstate(++count, "ParsedImages"); _logger.NotifyFillstate(chunksQueue.Count, "ChunkedQueue"); await queue.Enqueue(_factory.FromBytes(width, height, item)); } catch (Exception e) { _logger.LogException(e); } } if (memoryStream.HasUnwrittenData) { _logger.WriteLine("Unwritten data exists after finishing parsings." + " This indicates a severe issue with frame splitting", Verbosity.Warning); } }
public async Task Produce(ConcurrentQueue <MutableByteImage> queue) { try { FFMpegOptions.Configure(new FFMpegOptions { RootDirectory = _arguments.PathToFfmpeg }); var result = await FFProbe.AnalyseAsync(_arguments.InputFiles.First()).ConfigureAwait(false); var width = result.PrimaryVideoStream.Width; var height = result.PrimaryVideoStream.Height; var bpp = Image.GetPixelFormatSize(System.Drawing.Imaging.PixelFormat.Format24bppRgb) / 8; var pixelsPerFrame = width * height; var frameSizeInBytes = pixelsPerFrame * bpp; _logger.WriteLine("Input from ffmpeg currently only supports rgb24-convertable input", Verbosity.Warning); var chunksQueue = new ConcurrentQueue <byte[]>(); using var memoryStream = new ChunkedMemoryStream(frameSizeInBytes, chunksQueue); // new MemoryStream(frameSizeInBytes); StreamPipeSink sink = new StreamPipeSink(memoryStream); var args = FFMpegArguments .FromInputFiles(_arguments.InputFiles) .UsingMultithreading(true) .ForceFormat("rawvideo") .ForcePixelFormat("bgr24") .OutputToPipe(sink) .NotifyOnProgress( percent => _logger.NotifyFillstate(Convert.ToInt32(percent), "InputVideoParsing"), TimeSpan.FromSeconds(1)); var produceTask = args.ProcessAsynchronously(true).ContinueWith((_) => parsingFinished.Cancel()); var consumeTask = ParseInputStream(queue, chunksQueue, width, height, frameSizeInBytes, memoryStream); await Task.WhenAll(produceTask, consumeTask); // await Task.WhenAny(produceTask, consumeTask).ConfigureAwait(false); } catch (Exception e) { } async Task ParseInputStream(ConcurrentQueue <MutableByteImage> queue, ConcurrentQueue <byte[]> chunksQueue, int width, int height, int frameSizeInBytes, ChunkedMemoryStream memoryStream) { int count = 0; while (true) //while ((memoryStream.HasUnwrittenData || chunksQueue.Count > 0) && !parsingFinished.IsCancellationRequested) { try { var foo = await chunksQueue.TryDequeueOrWait(parsingFinished); if (foo.cancelled) { break; } _logger.NotifyFillstate(++count, "ParsedImages"); _logger.NotifyFillstate(chunksQueue.Count, "ChunkedQueue"); queue.Enqueue(_factory.FromBytes(width, height, foo.item)); } catch (Exception e) { _logger.LogException(e); } await queue.WaitForBufferSpace(24); } Console.WriteLine(memoryStream.HasUnwrittenData); } }