/// <summary> /// Initializes a new instance of the <see cref="Irseny.Core.Sensors.VideoCapture.VideoFrame"/> class. /// </summary> /// <param name="width">Width.</param> /// <param name="height">Height.</param> /// <param name="format">Pixel format.</param> /// <param name="data">Pixel data.</param> /// <param name="metadata">Associated metadata.</param> public VideoFrame(int width, int height, RasterImagePixelFormat format, byte[] data, VideoFrameMetadata metadata) { if (width < 0 || width > 16384) { throw new ArgumentOutOfRangeException("width"); } if (height < 0 || height > 16884) { throw new ArgumentOutOfRangeException("height"); } if (data == null) { throw new ArgumentNullException("data"); } if (metadata.FrameRate < 0) { throw new ArgumentOutOfRangeException("metadata.FrameRate"); } if (metadata.FrameTime < 0) { throw new ArgumentOutOfRangeException("metadata.FrameTime"); } if (metadata.FrameTimeDeviation < 0) { throw new ArgumentOutOfRangeException("metadata.FrameTimeVariance"); } Width = width; Height = height; PixelFormat = format; PixelData = data; Metadata = metadata; }
/// <inheritdoc/> public SensorDataPacket Process(long timestamp) { lock (captureSync) { if (!Capturing) { return(null); } long startTime = rateAnalyzer.GetTimeStamp(); // TODO implrement prediction service and divide split multiple calls into grab begin/end // get image and metadata from the backend if (!VideoCaptureBackend.BeginVideoCaptureFrameGrab(videoCapture)) { return(null); } if (!VideoCaptureBackend.EndVideoCaptureFrameGrab(videoCapture)) { return(null); } long endTime = rateAnalyzer.GetTimeStamp(); if (endTime - startTime > 0) { Console.WriteLine("waited additional " + (endTime - startTime) + "ms for the next frame"); } rateAnalyzer.Tick(); int width = VideoCaptureBackend.GetVideoCaptureFrameProperty(videoFrame, VideoFrameProperty.Width); int height = VideoCaptureBackend.GetVideoCaptureFrameProperty(videoFrame, VideoFrameProperty.Height); RasterImagePixelFormat format = (RasterImagePixelFormat)VideoCaptureBackend.GetVideoCaptureFrameProperty( videoFrame, VideoFrameProperty.PixelFormat); int pixelSize = VideoFrame.GetPixelSize(format); // construct a data packet as result if (width < 0 || width >= 16384 || height < 0 || height >= 16384 || pixelSize < 1 || pixelSize > 16) { return(null); } int imageSize = width * height * pixelSize; byte[] image = new byte[imageSize]; GCHandle imageBuffer = GCHandle.Alloc(image, GCHandleType.Pinned); if (!VideoCaptureBackend.CopyVideoCaptureFrame(videoFrame, imageBuffer.AddrOfPinnedObject(), imageSize)) { imageBuffer.Free(); return(null); } imageBuffer.Free(); var metadata = new VideoFrameMetadata() { FrameRate = rateAnalyzer.AverageFrameRate, FrameTime = rateAnalyzer.AverageFrameTime, FrameTimeDeviation = rateAnalyzer.StandardFrameTimeDeviation }; var frame = new VideoFrame(width, height, format, image, metadata); // TODO generate packet id return(new SensorDataPacket(this, SensorDataType.Video, frame, 0)); } }