public VideoFrame(Mat image, VideoFrameContext metadata) { Image = image; Metadata = metadata; }
private async Task StartCaptureAsync(TimeSpan publicationInterval, ChannelWriter <VideoFrame> writer, CancellationToken cancellationToken) { using var reader = this.InitCapture(); var width = reader.FrameWidth; var height = reader.FrameHeight; int frameCount = 0; int delayMs = (int)(500.0 / this.Fps); int errorCount = 0; using Mat imageBuffer = new Mat(); Mat publishedImage; var nextpublicationTime = DateTime.Now; while (!cancellationToken.IsCancellationRequested && !_stopping) { var startTime = DateTime.Now; // Grab single frame. var timestamp = DateTime.Now; bool success = reader.Read(imageBuffer); frameCount++; var endTime = DateTime.Now; LogTrace("Producer: frame-grab took {0} ms", (endTime - startTime).Milliseconds); if (!success || imageBuffer.Empty()) { // If we've reached the end of the video, stop here. if (IsContinuous) { errorCount++; // If failed on live camera, try again. _logger.LogWarning("Producer: null frame from live camera, continue! ({0} errors)", errorCount); if (errorCount < 5) { _logger.LogWarning("Error in capture, retry"); continue; } else { _logger.LogWarning("Errorcount exceeded, restarting videocapture"); break; } } else { _logger.LogWarning("Producer: null frame from video file, stop!"); _stopping = true; // Break out of the loop to make sure we don't try grabbing more // frames. break; } } else if (timestamp > nextpublicationTime) { LogTrace("Producer: create frame to publish:"); nextpublicationTime = timestamp + publicationInterval; publishedImage = PreprocessImage(imageBuffer); // Package the image for submission. VideoFrameContext meta = new VideoFrameContext(timestamp, frameCount, this.Info); VideoFrame vframe = new VideoFrame(publishedImage, meta); LogTrace("Producer: do publishing"); var writeResult = writer.TryWrite(vframe); } //Thread.Sleep(delayMs); await Task.Delay(delayMs, cancellationToken).ConfigureAwait(false); } }