Frames get lost while recording with Accord.NET (C# & WPF)

Viewed 410

We've got a problem with recording videos with Accord.NET Version 3.8.2-alpha using the .NETFramework version v4.7.2. We use this elder Version of Accord.NET because there are more options for video recording than in the latest.
In every high resolution record with the following code the video is losing some frames and it starts to stutter (it seems like there is no consistent frequency of the lags). Furthermore we use Windows 10 - Version 20H2. We tried this code in "Any CPU" and "x86" Debug Mode in Visual Studio.
We attempted recording with 30 fps and figured out that the framesPerSecond_1 variable only receives 24 frames. After this we tried to set this value manually on 30 and we run into the same problem. In additon we want to record 10 seconds but the recorded video lasts about 15-20 seconds (strangely enough the explorer displays in properties that it would only last 10 seconds). So the video is running in slow motion too. It might also be interesting to know that there are no performance issues because the CPU and RAM never reach their limits even if we record with two cameras at the same time.
The Code by the way throws no errors and looks like the following:

using Accord.Video;
using Accord.Video.DirectShow;
using Accord.Video.FFMPEG;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace VideoRecord
{
    /// <summary>
    /// Interaction Logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private VideoCaptureDevice videoCaptureDevice;
        private VideoFileWriter videoFileWriter;
        private DateTime? _firstFrameTime = null;
        private bool recording = false;
        private readonly object balanceLock = new object();

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            //Get connected video devices
            FilterInfoCollection devices = new FilterInfoCollection(FilterCategory.VideoInputDevice);

            //Our testing webcam
            videoCaptureDevice = new VideoCaptureDevice(devices[3].MonikerString);

            //Register new frame method
            videoCaptureDevice.NewFrame += new NewFrameEventHandler(showPreview);
            videoCaptureDevice.Start();

            //Setting properties for the file
            videoFileWriter = new VideoFileWriter();

            int width = 1920;
            int height = 1080;

            int temp_1 = videoCaptureDevice.FramesReceived;
            Thread.Sleep(1000);
            int framesPerSecond_1 = videoCaptureDevice.FramesReceived;

            int bitRate_1 = width*height*framesPerSecond_1;


            videoFileWriter.BitRate = bitRate_1;
            videoFileWriter.Width = width;
            videoFileWriter.Height = height;
            videoFileWriter.FrameRate = framesPerSecond_1;
            videoFileWriter.VideoCodec = VideoCodec.H264;

            //Tried to use the following lines because of an other forum
            //videoFileWriter.VideoOptions["preset"] = "ultrafast";
            //videoFileWriter.VideoOptions["tune"] = "zerolatency";
            videoFileWriter.VideoOptions["x264opts"] = "no-mbtree:sliced-threads:sync-lookahead=0";

            //Open the folder where the video should get stored and start recording
            videoFileWriter.Open("C:\\Storage\\videos\\"+DateTime.Now.Ticks+".mp4");
            recording = true;

            //Record for 10 seconds
            Thread.Sleep(10000);

            //Stop recording
            videoCaptureDevice.SignalToStop();
            videoCaptureDevice.WaitForStop();

            videoFileWriter.Close();
            videoFileWriter.Flush();
            videoFileWriter.Dispose();

            recording = false;
            _firstFrameTime = DateTime.Now;
        }

        private void showPreview(object sender, Accord.Video.NewFrameEventArgs eventArgs)
        {

            try
            {
                //Get the image from the camera
                Bitmap img = eventArgs.Frame;

                //Get the timestamp between every frame
                var frameTimestamp = _firstFrameTime - DateTime.Now;
                if (recording)
                {
                    //We don't know if "lock" helps but we tried it
                    lock (balanceLock)
                    {
                        //Record the video if the button is clicked
                        videoFileWriter.WriteVideoFrame(img, (TimeSpan)frameTimestamp);
                    }
                }
            }
            catch (Exception ex)
            {
            }
        }
    }
}

Does anyone know a solution?
Thank you in advance!

0 Answers
Related