public void TestAttachments() { var mkvPath = GenerateTempMkvFilePath(); var config = new DeviceConfiguration { CameraFps = FrameRate.Fifteen, ColorFormat = ImageFormat.ColorNV12, ColorResolution = ColorResolution.R720p, DepthMode = DepthMode.NarrowView2x2Binned, }; var deviceTimestamp0 = Microseconds64.FromMilliseconds(1.0); var deviceTimestamp1 = Microseconds64.FromMilliseconds(7.7); var attachment1Name = "\ud182\ud0b5\ud181\ud182 \ud0ba\ud0be\ud0b4\ud0b8\ud180\ud0be\ud0b2\ud0ba\ud0b8"; var attachment1Data = new byte[] { 1, 255, 0, 8, 7, 254, 128, 3, 127, 65, 179 }; var attachment2Name = "another_attachment.file"; var attachment2Data = new byte[] { 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200, 210, 220, 230, 240, 250 }; using (var recorder = new Recorder(mkvPath, null, config)) { recorder.AddAttachment(attachment1Name, attachment1Data); recorder.AddAttachment(attachment2Name, attachment2Data); recorder.WriteHeader(); WriteTestCaptures(recorder, deviceTimestamp0, deviceTimestamp1); } using (var playback = new Playback(mkvPath)) { Assert.IsTrue(playback.TryGetAttachment(attachment1Name, out var data1)); AssertAreEqual(attachment1Data, data1); Assert.IsTrue(playback.TryGetAttachment(attachment2Name, out var data2)); AssertAreEqual(attachment2Data, data2); Assert.IsFalse(playback.TryGetAttachment("some_unknown_attachment_name", out var tmp)); Assert.IsNull(tmp); } File.Delete(mkvPath); }
private void ImageExtractLoop() { Stopwatch sw = new Stopwatch(); int frameCountProduced = 0; sw.Start(); // bool isFrist = true; // TimeSpan initialDiff = new TimeSpan(0,0,0,0,0); while (true) { Capture capture = null; bool isSucceeded; try { isSucceeded = camera.TryGetCapture(out capture, K4AdotNet.Timeout.FromSeconds(0.1)); } catch { isSucceeded = false; capture?.Dispose(); } if (isSucceeded) { frameCountProduced++; //var deviceTime = capture.ColorImage.DeviceTimestamp.ToTimeSpan(); //var systemTime = capture.ColorImage.SystemTimestamp.ToTimeSpan(); //var diff = deviceTime - systemTime + initialDiff; //if (isFrist) { // isFrist = false; // initialDiff = -diff; //} // Debug.WriteLine("{0,12} \"deviceTime - systemTime\" {1,10}", field.ToString(), diff.TotalMilliseconds.ToString()); capture.ColorImage.DeviceTimestamp = Microseconds64.FromMilliseconds(capture.ColorImage.SystemTimestamp.TotalMilliseconds); if (Globals.getInstance().isRecording) { if (threadVideoRecording == null) { threadVideoRecording = new Thread(() => VideoRecordingLoop()); threadVideoRecording.Priority = ThreadPriority.BelowNormal; threadVideoRecording.Start(); } mutVideoRecord.WaitOne(); qVideoBufferToRecord.Enqueue(capture); mutVideoRecord.ReleaseMutex(); } else { mutVideoDisplay.WaitOne(); qVideoBufferToDisplay.Enqueue(capture); mutVideoDisplay.ReleaseMutex(); } } else { Thread.Sleep(30); } if (sw.Elapsed > TimeSpan.FromSeconds(2)) { fpsProduced = (double)frameCountProduced / sw.Elapsed.TotalSeconds; frameCountProduced = 0; sw.Restart(); } if (isDisposing) { break; } } }
public void TestCustomSubtitleTracks() { var mkvPath = GenerateTempMkvFilePath(); var config = new DeviceConfiguration { CameraFps = FrameRate.Five, ColorFormat = ImageFormat.ColorNV12, ColorResolution = ColorResolution.R720p, DepthMode = DepthMode.Off, }; var deviceTimestamp0 = Microseconds64.FromMilliseconds(0); var deviceTimestamp1 = Microseconds64.FromMilliseconds(20); var track1Name = "TEST_TRACK_NAME"; var track1CodecId = "S_CUSTOM_SUBTITLE_CODEC"; var track1CodecContext = new byte[] { 0, 1, 2, 3 }; var track1Settings = new RecordSubtitleSettings { HighFreqData = false }; var track2Name = "ANOTHER_CUSTOM_TRACK"; var track2CodecId = "S_XYZ_CODEC"; var track2CodecContext = new byte[] { 255, 254, 253 }; var track2Settings = new RecordSubtitleSettings { HighFreqData = true }; using (var recorder = new Recorder(mkvPath, null, config)) { var track1 = recorder.CustomTracks.AddCustomSubtitleTrack(track1Name, track1CodecId, track1CodecContext, track1Settings); Assert.AreEqual(track1Name, track1.Name); Assert.AreEqual(track1CodecId, track1.CodecId); Assert.AreSame(track1CodecContext, track1.CodecContext); var track2 = recorder.CustomTracks.AddCustomSubtitleTrack(track2Name, track2CodecId, track2CodecContext, track2Settings); Assert.AreEqual(track2Name, track2.Name); Assert.AreEqual(track2CodecId, track2.CodecId); Assert.AreSame(track2CodecContext, track2.CodecContext); recorder.WriteHeader(); WriteTestCaptures(recorder, deviceTimestamp0, deviceTimestamp1); track1.WriteData(deviceTimestamp0, new byte[] { 10 }); track1.WriteData(deviceTimestamp0 + 200, new byte[] { 12 }); track1.WriteData(deviceTimestamp0 + 400, new byte[] { 14 }); track1.WriteData(deviceTimestamp0 + 600, new byte[] { 16 }); track1.WriteData(deviceTimestamp0 + 800, new byte[] { 18 }); track1.WriteData(deviceTimestamp1, new byte[] { 20 }); track1.WriteData(deviceTimestamp1 + 200, new byte[] { 22 }); track1.WriteData(deviceTimestamp1 + 400, new byte[] { 24 }); track1.WriteData(deviceTimestamp1 + 600, new byte[] { 26 }); track1.WriteData(deviceTimestamp1 + 800, new byte[] { 28 }); track2.WriteData(deviceTimestamp0, new byte[] { 2, 0 }); track2.WriteData(deviceTimestamp1, new byte[] { 2, 1 }); } using (var playback = new Playback(mkvPath)) { var builtInTrackCount = GetBuiltInTrackCount(config); var trackCount = builtInTrackCount + 2; Assert.AreEqual(trackCount, playback.Tracks.Count); Assert.AreEqual(builtInTrackCount, playback.Tracks.Count(t => t.IsBuiltIn)); Assert.AreEqual(2, playback.Tracks.Count(t => !t.IsBuiltIn)); Assert.IsTrue(playback.Tracks.Exists(track1Name)); Assert.IsTrue(playback.Tracks.Exists(track2Name)); Assert.IsFalse(playback.Tracks.Exists("SOME_UNKNOWN_TRACK_NAME")); var track1 = playback.Tracks[track1Name]; Assert.IsNotNull(track1); Assert.AreEqual(track1Name, track1.Name); Assert.AreEqual(track1CodecId, track1.CodecId); AssertAreEqual(track1CodecContext, track1.CodecContext); Assert.IsFalse(track1.IsBuiltIn); var track2 = playback.Tracks[track2Name]; Assert.IsNotNull(track2); Assert.AreEqual(track2Name, track2.Name); Assert.AreEqual(track2CodecId, track2.CodecId); AssertAreEqual(track2CodecContext, track2.CodecContext); Assert.IsFalse(track2.IsBuiltIn); Assert.IsNull(playback.Tracks["SOME_UNKNOWN_TRACK_NAME"]); // Reading of track 1 Assert.IsFalse(track1.TryGetPreviousDataBlock(out var dataBlock)); Assert.IsNull(dataBlock); // forward for (var i = 0; i < 10; i += 2) { Assert.IsTrue(track1.TryGetNextDataBlock(out dataBlock)); Assert.IsNotNull(dataBlock); Assert.AreEqual(deviceTimestamp0.ValueUsec + i * 100, dataBlock.DeviceTimestamp.ValueUsec); Assert.AreEqual(1, dataBlock.SizeBytes); Assert.AreEqual(10 + i, Marshal.ReadByte(dataBlock.Buffer)); dataBlock.Dispose(); } for (var i = 0; i < 10; i += 2) { Assert.IsTrue(track1.TryGetNextDataBlock(out dataBlock)); Assert.IsNotNull(dataBlock); Assert.AreEqual(deviceTimestamp1.ValueUsec + i * 100, dataBlock.DeviceTimestamp.ValueUsec); Assert.AreEqual(1, dataBlock.SizeBytes); Assert.AreEqual(20 + i, Marshal.ReadByte(dataBlock.Buffer)); dataBlock.Dispose(); } // eof Assert.IsFalse(track1.TryGetNextDataBlock(out dataBlock)); Assert.IsNull(dataBlock); // Reading of track 2 Assert.IsFalse(track2.TryGetPreviousDataBlock(out dataBlock)); Assert.IsNull(dataBlock); // forward Assert.IsTrue(track2.TryGetNextDataBlock(out dataBlock)); Assert.IsNotNull(dataBlock); Assert.AreEqual(deviceTimestamp0, dataBlock.DeviceTimestamp); Assert.AreEqual(2, dataBlock.SizeBytes); Assert.AreEqual(2, Marshal.ReadByte(dataBlock.Buffer, 0)); Assert.AreEqual(0, Marshal.ReadByte(dataBlock.Buffer, 1)); dataBlock.Dispose(); Assert.IsTrue(track2.TryGetNextDataBlock(out dataBlock)); Assert.IsNotNull(dataBlock); Assert.AreEqual(deviceTimestamp1, dataBlock.DeviceTimestamp); Assert.AreEqual(2, dataBlock.SizeBytes); Assert.AreEqual(2, Marshal.ReadByte(dataBlock.Buffer, 0)); Assert.AreEqual(1, Marshal.ReadByte(dataBlock.Buffer, 1)); dataBlock.Dispose(); // eof Assert.IsFalse(track2.TryGetNextDataBlock(out dataBlock)); Assert.IsNull(dataBlock); // backward Assert.IsTrue(track2.TryGetPreviousDataBlock(out dataBlock)); Assert.IsNotNull(dataBlock); Assert.AreEqual(deviceTimestamp1, dataBlock.DeviceTimestamp); Assert.AreEqual(2, dataBlock.SizeBytes); Assert.AreEqual(2, Marshal.ReadByte(dataBlock.Buffer, 0)); Assert.AreEqual(1, Marshal.ReadByte(dataBlock.Buffer, 1)); dataBlock.Dispose(); Assert.IsTrue(track2.TryGetPreviousDataBlock(out dataBlock)); Assert.IsNotNull(dataBlock); Assert.AreEqual(deviceTimestamp0, dataBlock.DeviceTimestamp); Assert.AreEqual(2, dataBlock.SizeBytes); Assert.AreEqual(2, Marshal.ReadByte(dataBlock.Buffer, 0)); Assert.AreEqual(0, Marshal.ReadByte(dataBlock.Buffer, 1)); dataBlock.Dispose(); // eof Assert.IsFalse(track2.TryGetPreviousDataBlock(out dataBlock)); Assert.IsNull(dataBlock); } File.Delete(mkvPath); }
public void TestCustomVideoTracks() { var mkvPath = GenerateTempMkvFilePath(); var config = new DeviceConfiguration { CameraFps = FrameRate.Five, ColorFormat = ImageFormat.ColorNV12, ColorResolution = ColorResolution.R720p, DepthMode = DepthMode.NarrowView2x2Binned, }; var deviceTimestamp0 = Microseconds64.FromMilliseconds(0); var deviceTimestamp1 = Microseconds64.FromMilliseconds(20); var track1Name = "TEST_TRACK_NAME"; var track1CodecId = "V_CUSTOM_VIDEO_CODEC"; var track1CodecContext = new byte[] { 255, 254, 253, 0, 1, 2, 3, 4, 8, 16, 32, 64, 128 }; var track1Settings = new RecordVideoSettings { Width = 2, Height = 4, FrameRate = 5 }; var track2Name = "ANOTHER_CUSTOM_TRACK"; var track2CodecId = "V_XYZ_CODEC"; var track2CodecContext = new byte[] { 20, 19, 8, 27, 22, 29, 59 }; var track2Settings = new RecordVideoSettings { Width = 20, Height = 40, FrameRate = 4 }; using (var recorder = new Recorder(mkvPath, null, config)) { var track1 = recorder.CustomTracks.AddVideoTrack(track1Name, track1CodecId, track1CodecContext, track1Settings); Assert.AreEqual(track1Name, track1.Name); Assert.AreEqual(track1CodecId, track1.CodecId); Assert.AreSame(track1CodecContext, track1.CodecContext); var track2 = recorder.CustomTracks.AddVideoTrack(track2Name, track2CodecId, track2CodecContext, track2Settings); Assert.AreEqual(track2Name, track2.Name); Assert.AreEqual(track2CodecId, track2.CodecId); Assert.AreSame(track2CodecContext, track2.CodecContext); recorder.WriteHeader(); WriteTestCaptures(recorder, deviceTimestamp0, deviceTimestamp1); track1.WriteData(deviceTimestamp0, new byte[] { 1, 0 }); track1.WriteData(deviceTimestamp1, new byte[] { 1, 1 }); track2.WriteData(deviceTimestamp0, new byte[] { 2, 0 }); track2.WriteData(deviceTimestamp1, new byte[] { 2, 1 }); } using (var playback = new Playback(mkvPath)) { var builtInTrackCount = GetBuiltInTrackCount(config); var trackCount = builtInTrackCount + 2; Assert.AreEqual(trackCount, playback.Tracks.Count); Assert.AreEqual(builtInTrackCount, playback.Tracks.Count(t => t.IsBuiltIn)); Assert.AreEqual(2, playback.Tracks.Count(t => !t.IsBuiltIn)); Assert.IsTrue(playback.Tracks.Exists(track1Name)); Assert.IsTrue(playback.Tracks.Exists(track2Name)); Assert.IsFalse(playback.Tracks.Exists("SOME_UNKNOWN_TRACK_NAME")); var track1 = playback.Tracks[track1Name]; Assert.IsNotNull(track1); Assert.AreEqual(track1Name, track1.Name); Assert.AreEqual(track1CodecId, track1.CodecId); AssertAreEqual(track1CodecContext, track1.CodecContext); Assert.AreEqual(track1Settings, track1.VideoSettings); Assert.IsFalse(track1.IsBuiltIn); var track2 = playback.Tracks[track2Name]; Assert.IsNotNull(track2); Assert.AreEqual(track2Name, track2.Name); Assert.AreEqual(track2CodecId, track2.CodecId); AssertAreEqual(track2CodecContext, track2.CodecContext); Assert.AreEqual(track2Settings, track2.VideoSettings); Assert.IsFalse(track2.IsBuiltIn); Assert.IsNull(playback.Tracks["SOME_UNKNOWN_TRACK_NAME"]); // Reading of track 1 Assert.IsFalse(track1.TryGetPreviousDataBlock(out var dataBlock)); Assert.IsNull(dataBlock); // forward Assert.IsTrue(track1.TryGetNextDataBlock(out dataBlock)); Assert.IsNotNull(dataBlock); Assert.AreEqual(deviceTimestamp0, dataBlock.DeviceTimestamp); Assert.AreEqual(2, dataBlock.SizeBytes); Assert.AreEqual(1, Marshal.ReadByte(dataBlock.Buffer, 0)); Assert.AreEqual(0, Marshal.ReadByte(dataBlock.Buffer, 1)); dataBlock.Dispose(); Assert.IsTrue(track1.TryGetNextDataBlock(out dataBlock)); Assert.IsNotNull(dataBlock); Assert.AreEqual(deviceTimestamp1, dataBlock.DeviceTimestamp); Assert.AreEqual(2, dataBlock.SizeBytes); Assert.AreEqual(1, Marshal.ReadByte(dataBlock.Buffer, 0)); Assert.AreEqual(1, Marshal.ReadByte(dataBlock.Buffer, 1)); dataBlock.Dispose(); // eof Assert.IsFalse(track1.TryGetNextDataBlock(out dataBlock)); Assert.IsNull(dataBlock); // backward Assert.IsTrue(track1.TryGetPreviousDataBlock(out dataBlock)); Assert.IsNotNull(dataBlock); Assert.AreEqual(deviceTimestamp1, dataBlock.DeviceTimestamp); Assert.AreEqual(2, dataBlock.SizeBytes); Assert.AreEqual(1, Marshal.ReadByte(dataBlock.Buffer, 0)); Assert.AreEqual(1, Marshal.ReadByte(dataBlock.Buffer, 1)); dataBlock.Dispose(); Assert.IsTrue(track1.TryGetPreviousDataBlock(out dataBlock)); Assert.IsNotNull(dataBlock); Assert.AreEqual(deviceTimestamp0, dataBlock.DeviceTimestamp); Assert.AreEqual(2, dataBlock.SizeBytes); Assert.AreEqual(1, Marshal.ReadByte(dataBlock.Buffer, 0)); Assert.AreEqual(0, Marshal.ReadByte(dataBlock.Buffer, 1)); dataBlock.Dispose(); // eof Assert.IsFalse(track1.TryGetPreviousDataBlock(out dataBlock)); Assert.IsNull(dataBlock); // Reading of track 2 Assert.IsFalse(track2.TryGetPreviousDataBlock(out dataBlock)); Assert.IsNull(dataBlock); // forward Assert.IsTrue(track2.TryGetNextDataBlock(out dataBlock)); Assert.IsNotNull(dataBlock); Assert.AreEqual(deviceTimestamp0, dataBlock.DeviceTimestamp); Assert.AreEqual(2, dataBlock.SizeBytes); Assert.AreEqual(2, Marshal.ReadByte(dataBlock.Buffer, 0)); Assert.AreEqual(0, Marshal.ReadByte(dataBlock.Buffer, 1)); dataBlock.Dispose(); Assert.IsTrue(track2.TryGetNextDataBlock(out dataBlock)); Assert.IsNotNull(dataBlock); Assert.AreEqual(deviceTimestamp1, dataBlock.DeviceTimestamp); Assert.AreEqual(2, dataBlock.SizeBytes); Assert.AreEqual(2, Marshal.ReadByte(dataBlock.Buffer, 0)); Assert.AreEqual(1, Marshal.ReadByte(dataBlock.Buffer, 1)); dataBlock.Dispose(); // eof Assert.IsFalse(track2.TryGetNextDataBlock(out dataBlock)); Assert.IsNull(dataBlock); // backward Assert.IsTrue(track2.TryGetPreviousDataBlock(out dataBlock)); Assert.IsNotNull(dataBlock); Assert.AreEqual(deviceTimestamp1, dataBlock.DeviceTimestamp); Assert.AreEqual(2, dataBlock.SizeBytes); Assert.AreEqual(2, Marshal.ReadByte(dataBlock.Buffer, 0)); Assert.AreEqual(1, Marshal.ReadByte(dataBlock.Buffer, 1)); dataBlock.Dispose(); Assert.IsTrue(track2.TryGetPreviousDataBlock(out dataBlock)); Assert.IsNotNull(dataBlock); Assert.AreEqual(deviceTimestamp0, dataBlock.DeviceTimestamp); Assert.AreEqual(2, dataBlock.SizeBytes); Assert.AreEqual(2, Marshal.ReadByte(dataBlock.Buffer, 0)); Assert.AreEqual(0, Marshal.ReadByte(dataBlock.Buffer, 1)); dataBlock.Dispose(); // eof Assert.IsFalse(track2.TryGetPreviousDataBlock(out dataBlock)); Assert.IsNull(dataBlock); } File.Delete(mkvPath); }
public void TestBasicScenario() { var mkvPath = GenerateTempMkvFilePath(); var config = new DeviceConfiguration { CameraFps = FrameRate.Thirty, ColorFormat = ImageFormat.ColorNV12, ColorResolution = ColorResolution.R720p, DepthMode = DepthMode.NarrowView2x2Binned, SubordinateDelayOffMaster = Microseconds32.FromSeconds(0.00001), WiredSyncMode = WiredSyncMode.Subordinate, DepthDelayOffColor = Microseconds32.FromMilliseconds(-0.005), }; var deviceTimestamp0 = Microseconds64.FromMilliseconds(1.0); var deviceTimestamp1 = Microseconds64.FromMilliseconds(4.4); var deviceTimestamp2 = Microseconds64.FromMilliseconds(7.7); using (var recorder = new Recorder(mkvPath, null, config)) { Assert.IsFalse(recorder.IsDisposed); Assert.AreEqual(mkvPath, recorder.FilePath); Assert.AreEqual(0, recorder.CustomTracks.Count); recorder.WriteHeader(); WriteTestCaptures(recorder, deviceTimestamp0, deviceTimestamp1, deviceTimestamp2); } using (var playback = new Playback(mkvPath)) { Assert.IsFalse(playback.IsDisposed); Assert.AreEqual(mkvPath, playback.FilePath); var trackCount = GetBuiltInTrackCount(config); Assert.AreEqual(trackCount, playback.Tracks.Count); Assert.AreEqual(trackCount, playback.Tracks.Count(t => t.IsBuiltIn)); Assert.AreEqual(0, playback.Tracks.Count(t => !t.IsBuiltIn)); playback.GetRecordConfiguration(out var recordConfig); Assert.AreEqual(config.CameraFps, recordConfig.CameraFps); Assert.AreEqual(config.ColorFormat, recordConfig.ColorFormat); Assert.AreEqual(config.ColorResolution, recordConfig.ColorResolution); Assert.AreEqual(config.ColorResolution != ColorResolution.Off, recordConfig.ColorTrackEnabled); Assert.AreEqual(config.DepthDelayOffColor, recordConfig.DepthDelayOffColor); Assert.AreEqual(config.DepthMode, recordConfig.DepthMode); Assert.AreEqual(config.DepthMode.HasDepth(), recordConfig.DepthTrackEnabled); Assert.IsFalse(recordConfig.ImuTrackEnabled); Assert.AreEqual(config.DepthMode.HasPassiveIR(), recordConfig.IRTrackEnabled); var startTimestamp = GetStartTimestamp(config, deviceTimestamp0); Assert.AreEqual(startTimestamp.ValueUsec, recordConfig.StartTimeOffset.ValueUsec); Assert.AreEqual(config.SubordinateDelayOffMaster, recordConfig.SubordinateDelayOffMaster); Assert.AreEqual(config.WiredSyncMode, recordConfig.WiredSyncMode); var length = playback.RecordLength; var endTimestamp = GetEndTimestamp(config, deviceTimestamp2); Assert.AreEqual(endTimestamp.ValueUsec - startTimestamp.ValueUsec, length.ValueUsec); // Try play backward from start Assert.IsFalse(playback.TryGetPreviousCapture(out var capture)); Assert.IsNull(capture); // Play forward Assert.IsTrue(playback.TryGetNextCapture(out capture)); Assert.IsNotNull(capture); CheckCapture(capture, config, deviceTimestamp0); capture.Dispose(); Assert.IsTrue(playback.TryGetNextCapture(out capture)); Assert.IsNotNull(capture); CheckCapture(capture, config, deviceTimestamp1); capture.Dispose(); Assert.IsTrue(playback.TryGetNextCapture(out capture)); Assert.IsNotNull(capture); CheckCapture(capture, config, deviceTimestamp2); capture.Dispose(); // EoF Assert.IsFalse(playback.TryGetNextCapture(out capture)); Assert.IsNull(capture); // Play backward Assert.IsTrue(playback.TryGetPreviousCapture(out capture)); Assert.IsNotNull(capture); CheckCapture(capture, config, deviceTimestamp2); capture.Dispose(); Assert.IsTrue(playback.TryGetPreviousCapture(out capture)); Assert.IsNotNull(capture); CheckCapture(capture, config, deviceTimestamp1); capture.Dispose(); Assert.IsTrue(playback.TryGetPreviousCapture(out capture)); Assert.IsNotNull(capture); CheckCapture(capture, config, deviceTimestamp0); capture.Dispose(); // EoF Assert.IsFalse(playback.TryGetPreviousCapture(out capture)); Assert.IsNull(capture); // Seek to end Assert.IsTrue(playback.TrySeekTimestamp(Microseconds64.Zero, PlaybackSeekOrigin.End)); Assert.IsFalse(playback.TryGetNextCapture(out capture)); Assert.IsNull(capture); Assert.IsTrue(playback.TryGetPreviousCapture(out capture)); Assert.IsNotNull(capture); CheckCapture(capture, config, deviceTimestamp2); capture.Dispose(); // Seek to start Assert.IsTrue(playback.TrySeekTimestamp(Microseconds64.Zero, PlaybackSeekOrigin.Begin)); Assert.IsFalse(playback.TryGetPreviousCapture(out capture)); Assert.IsNull(capture); Assert.IsTrue(playback.TryGetNextCapture(out capture)); Assert.IsNotNull(capture); CheckCapture(capture, config, deviceTimestamp0); capture.Dispose(); // Seek to device timestamp var ts = GetStartTimestamp(config, deviceTimestamp1); Assert.IsTrue(playback.TrySeekTimestamp(ts, PlaybackSeekOrigin.DeviceTime)); Assert.IsTrue(playback.TryGetNextCapture(out capture)); Assert.IsNotNull(capture); CheckCapture(capture, config, deviceTimestamp1); capture.Dispose(); } File.Delete(mkvPath); }