robvdpol / RaceControl

Race Control is a standalone, open source F1TV client for Windows, written in C# on the .NET platform.
GNU General Public License v3.0
1.19k stars 95 forks source link

[BUG] Internal player stutters above approx 12 streams #455

Open JJWatMyself opened 2 years ago

JJWatMyself commented 2 years ago

Describe the bug Internal player stutters above approx 12 streams, similar to closed bug#158

To Reproduce Steps to reproduce the behavior:

  1. Open more than 12 streams using internal player
  2. If open more streams, audio and video simultaneously stutter, across all streams. Gets progressively worse as more streams are opened. e.g. 21 streams. CPU, GPU, RAM, network have average usage Expected behavior I would expect stuttering to occur when system performance is constrained, but not when CPU and GPU are always less than 50%.

Desktop (please complete the following information):

F1TV account

Layout that I am testing with```

{
  "Instances": [
    {
      "Top": 0.0,
      "Left": 0.0,
      "Width": 640.0,
      "Height": 360.0,
      "FullScreen": false,
      "ResizeMode": 0,
      "VideoQuality": 2,
      "Topmost": false,
      "IsMuted": true,
      "Volume": 100,
      "Zoom": 0,
      "AspectRatio": "Keep",
      "AudioDevice": "Default",
      "AudioTrack": "teamradio",
      "ChannelName": "Yuki Tsunoda"
    },
    {
      "Top": 0.0,
      "Left": 640.0,
      "Width": 640.0,
      "Height": 360.0,
      "FullScreen": false,
      "ResizeMode": 0,
      "VideoQuality": 2,
      "Topmost": false,
      "IsMuted": true,
      "Volume": 100,
      "Zoom": 0,
      "AspectRatio": "Keep",
      "AudioDevice": "Default",
      "AudioTrack": "teamradio",
      "ChannelName": "Sebastian Vettel"
    },
    {
      "Top": 0.0,
      "Left": 1280.0,
      "Width": 1280.0,
      "Height": 720.0,
      "FullScreen": false,
      "ResizeMode": 0,
      "VideoQuality": 2,
      "Topmost": false,
      "IsMuted": true,
      "Volume": 100,
      "Zoom": 0,
      "AspectRatio": "Keep",
      "AudioDevice": "Default",
      "AudioTrack": "eng",
      "ChannelName": "DATA"
    },
    {
      "Top": 0.0,
      "Left": 2560.0,
      "Width": 640.0,
      "Height": 360.0,
      "FullScreen": false,
      "ResizeMode": 0,
      "VideoQuality": 2,
      "Topmost": false,
      "IsMuted": true,
      "Volume": 100,
      "Zoom": 0,
      "AspectRatio": "Keep",
      "AudioDevice": "Default",
      "AudioTrack": "teamradio",
      "ChannelName": "Valtteri Bottas"
    },
    {
      "Top": 0.0,
      "Left": 3200.0,
      "Width": 640.0,
      "Height": 360.0,
      "FullScreen": false,
      "ResizeMode": 0,
      "VideoQuality": 2,
      "Topmost": false,
      "IsMuted": true,
      "Volume": 100,
      "Zoom": 0,
      "AspectRatio": "Keep",
      "AudioDevice": "Default",
      "AudioTrack": "teamradio",
      "ChannelName": "Lando Norris"
    },
    {
      "Top": 360.0,
      "Left": 0.0,
      "Width": 640.0,
      "Height": 360.0,
      "FullScreen": false,
      "ResizeMode": 0,
      "VideoQuality": 2,
      "Topmost": false,
      "IsMuted": true,
      "Volume": 100,
      "Zoom": 0,
      "AspectRatio": "Keep",
      "AudioDevice": "Default",
      "AudioTrack": "teamradio",
      "ChannelName": "Pierre Gasly"
    },
    {
      "Top": 360.0,
      "Left": 640.0,
      "Width": 640.0,
      "Height": 360.0,
      "FullScreen": false,
      "ResizeMode": 0,
      "VideoQuality": 2,
      "Topmost": false,
      "IsMuted": true,
      "Volume": 100,
      "Zoom": 0,
      "AspectRatio": "Keep",
      "AudioDevice": "Default",
      "AudioTrack": "teamradio",
      "ChannelName": "Lance Stroll"
    },
    {
      "Top": 360.0,
      "Left": 2560.0,
      "Width": 640.0,
      "Height": 360.0,
      "FullScreen": false,
      "ResizeMode": 0,
      "VideoQuality": 2,
      "Topmost": false,
      "IsMuted": true,
      "Volume": 100,
      "Zoom": 0,
      "AspectRatio": "Keep",
      "AudioDevice": "Default",
      "AudioTrack": "teamradio",
      "ChannelName": "Guanyu Zhou"
    },
    {
      "Top": 360.0,
      "Left": 3200.0,
      "Width": 640.0,
      "Height": 360.0,
      "FullScreen": false,
      "ResizeMode": 0,
      "VideoQuality": 2,
      "Topmost": false,
      "IsMuted": true,
      "Volume": 100,
      "Zoom": 0,
      "AspectRatio": "Keep",
      "AudioDevice": "Default",
      "AudioTrack": "teamradio",
      "ChannelName": "Daniel Ricciardo"
    },
    {
      "Top": 720.0,
      "Left": 0.0,
      "Width": 1280.0,
      "Height": 720.0,
      "FullScreen": false,
      "ResizeMode": 0,
      "VideoQuality": 1,
      "Topmost": false,
      "IsMuted": false,
      "Volume": 100,
      "Zoom": 0,
      "AspectRatio": "Keep",
      "AudioDevice": "Default",
      "AudioTrack": "teamradio",
      "ChannelName": "Lewis Hamilton"
    },
    {
      "Top": 720.0,
      "Left": 1280.0,
      "Width": 1280.0,
      "Height": 720.0,
      "FullScreen": false,
      "ResizeMode": 0,
      "VideoQuality": 0,
      "Topmost": false,
      "IsMuted": false,
      "Volume": 50,
      "Zoom": 0,
      "AspectRatio": "Keep",
      "AudioDevice": "Default",
      "AudioTrack": "eng",
      "ChannelName": "INTERNATIONAL"
    },
    {
      "Top": 720.0,
      "Left": 2560.0,
      "Width": 1280.0,
      "Height": 720.0,
      "FullScreen": false,
      "ResizeMode": 0,
      "VideoQuality": 1,
      "Topmost": false,
      "IsMuted": true,
      "Volume": 100,
      "Zoom": 0,
      "AspectRatio": "Keep",
      "AudioDevice": "Default",
      "AudioTrack": "teamradio",
      "ChannelName": "George Russell"
    },
    {
      "Top": 1440.0,
      "Left": 0.0,
      "Width": 640.0,
      "Height": 360.0,
      "FullScreen": false,
      "ResizeMode": 0,
      "VideoQuality": 2,
      "Topmost": false,
      "IsMuted": true,
      "Volume": 100,
      "Zoom": 0,
      "AspectRatio": "Keep",
      "AudioDevice": "Default",
      "AudioTrack": "teamradio",
      "ChannelName": "Max Verstappen"
    },
    {
      "Top": 1440.0,
      "Left": 640.0,
      "Width": 640.0,
      "Height": 360.0,
      "FullScreen": false,
      "ResizeMode": 0,
      "VideoQuality": 2,
      "Topmost": false,
      "IsMuted": true,
      "Volume": 100,
      "Zoom": 0,
      "AspectRatio": "Keep",
      "AudioDevice": "Default",
      "AudioTrack": "teamradio",
      "ChannelName": "Charles Leclerc"
    },
    {
      "Top": 1440.0,
      "Left": 1280.0,
      "Width": 1280.0,
      "Height": 720.0,
      "FullScreen": false,
      "ResizeMode": 0,
      "VideoQuality": 2,
      "Topmost": false,
      "IsMuted": true,
      "Volume": 100,
      "Zoom": 0,
      "AspectRatio": "Keep",
      "AudioDevice": "Default",
      "AudioTrack": "eng",
      "ChannelName": "TRACKER"
    },
    {
      "Top": 1440.0,
      "Left": 2560.0,
      "Width": 640.0,
      "Height": 360.0,
      "FullScreen": false,
      "ResizeMode": 0,
      "VideoQuality": 2,
      "Topmost": false,
      "IsMuted": true,
      "Volume": 100,
      "Zoom": 0,
      "AspectRatio": "Keep",
      "AudioDevice": "Default",
      "AudioTrack": "teamradio",
      "ChannelName": "Esteban Ocon"
    },
    {
      "Top": 1440.0,
      "Left": 3200.0,
      "Width": 640.0,
      "Height": 360.0,
      "FullScreen": false,
      "ResizeMode": 0,
      "VideoQuality": 2,
      "Topmost": false,
      "IsMuted": true,
      "Volume": 100,
      "Zoom": 0,
      "AspectRatio": "Keep",
      "AudioDevice": "Default",
      "AudioTrack": "teamradio",
      "ChannelName": "Kevin Magnussen"
    },
    {
      "Top": 1800.0,
      "Left": 0.0,
      "Width": 640.0,
      "Height": 360.0,
      "FullScreen": false,
      "ResizeMode": 0,
      "VideoQuality": 2,
      "Topmost": false,
      "IsMuted": true,
      "Volume": 100,
      "Zoom": 0,
      "AspectRatio": "Keep",
      "AudioDevice": "Default",
      "AudioTrack": "teamradio",
      "ChannelName": "Sergio Perez"
    },
    {
      "Top": 1800.0,
      "Left": 640.0,
      "Width": 640.0,
      "Height": 360.0,
      "FullScreen": false,
      "ResizeMode": 0,
      "VideoQuality": 2,
      "Topmost": false,
      "IsMuted": true,
      "Volume": 100,
      "Zoom": 0,
      "AspectRatio": "Keep",
      "AudioDevice": "Default",
      "AudioTrack": "teamradio",
      "ChannelName": "Carlos Sainz"
    },
    {
      "Top": 1800.0,
      "Left": 2560.0,
      "Width": 640.0,
      "Height": 360.0,
      "FullScreen": false,
      "ResizeMode": 0,
      "VideoQuality": 2,
      "Topmost": false,
      "IsMuted": true,
      "Volume": 100,
      "Zoom": 0,
      "AspectRatio": "Keep",
      "AudioDevice": "Default",
      "AudioTrack": "teamradio",
      "ChannelName": "Fernando Alonso"
    },
    {
      "Top": 1800.0,
      "Left": 3200.0,
      "Width": 640.0,
      "Height": 360.0,
      "FullScreen": false,
      "ResizeMode": 0,
      "VideoQuality": 2,
      "Topmost": false,
      "IsMuted": true,
      "Volume": 100,
      "Zoom": 0,
      "AspectRatio": "Keep",
      "AudioDevice": "Default",
      "AudioTrack": "teamradio",
      "ChannelName": "Mick Schumacher"
    }
  ]
}
SuRGeoNix commented 2 years ago

Hi @JJWatMyself, can you confirm that other players (vlc/mpv) can handle this and it is indeed an issue with the internal player?

JJWatMyself commented 2 years ago

I did some more testing last night after posting.

@SuRGeoNix mpv is quite a bit worse than the internal player and mpv seems to ignore the video quality attribute in the xml. So internal player seems to be the better of the two for many streams.

It appears there is an overall stuttering in the OS when this issue is reproduced, e.g. moving mouse around the screen will see a simultaneous stuttering of the video, audio and mouse, Not exactly sure where the constraint is that would be causing and continuing to analyze.

I have also tested reducing the video quality to 3 (Potato) on all streams, eliminating audio on all but 2 streams, and the problem persists. So think this is a parallel processing type issue.```


{
  "Instances": [
    {
      "Top": 0.0,
      "Left": 0.0,
      "Width": 640.0,
      "Height": 360.0,
      "FullScreen": false,
      "ResizeMode": 0,
      "VideoQuality": 3,
      "Topmost": false,
      "IsMuted": true,
      "Volume": 100,
      "Zoom": 0,
      "AspectRatio": "Keep",
      "AudioDevice": "Default",
      "ChannelName": "Yuki Tsunoda"
    },
    {
      "Top": 0.0,
      "Left": 640.0,
      "Width": 640.0,
      "Height": 360.0,
      "FullScreen": false,
      "ResizeMode": 0,
      "VideoQuality": 3,
      "Topmost": false,
      "IsMuted": true,
      "Volume": 100,
      "Zoom": 0,
      "AspectRatio": "Keep",
      "AudioDevice": "Default",
      "ChannelName": "Sebastian Vettel"
    },
    {
      "Top": 0.0,
      "Left": 1280.0,
      "Width": 1280.0,
      "Height": 720.0,
      "FullScreen": false,
      "ResizeMode": 0,
      "VideoQuality": 3,
      "Topmost": false,
      "IsMuted": true,
      "Volume": 100,
      "Zoom": 0,
      "AspectRatio": "Keep",
      "AudioDevice": "Default",
      "ChannelName": "DATA"
    },
    {
      "Top": 0.0,
      "Left": 2560.0,
      "Width": 640.0,
      "Height": 360.0,
      "FullScreen": false,
      "ResizeMode": 0,
      "VideoQuality": 3,
      "Topmost": false,
      "IsMuted": true,
      "Volume": 100,
      "Zoom": 0,
      "AspectRatio": "Keep",
      "AudioDevice": "Default",
      "ChannelName": "Valtteri Bottas"
    },
    {
      "Top": 0.0,
      "Left": 3200.0,
      "Width": 640.0,
      "Height": 360.0,
      "FullScreen": false,
      "ResizeMode": 0,
      "VideoQuality": 3,
      "Topmost": false,
      "IsMuted": true,
      "Volume": 100,
      "Zoom": 0,
      "AspectRatio": "Keep",
      "AudioDevice": "Default",
      "ChannelName": "Lando Norris"
    },
    {
      "Top": 360.0,
      "Left": 0.0,
      "Width": 640.0,
      "Height": 360.0,
      "FullScreen": false,
      "ResizeMode": 0,
      "VideoQuality": 3,
      "Topmost": false,
      "IsMuted": true,
      "Volume": 100,
      "Zoom": 0,
      "AspectRatio": "Keep",
      "AudioDevice": "Default",
      "ChannelName": "Pierre Gasly"
    },
    {
      "Top": 360.0,
      "Left": 640.0,
      "Width": 640.0,
      "Height": 360.0,
      "FullScreen": false,
      "ResizeMode": 0,
      "VideoQuality": 3,
      "Topmost": false,
      "IsMuted": true,
      "Volume": 100,
      "Zoom": 0,
      "AspectRatio": "Keep",
      "AudioDevice": "Default",
      "ChannelName": "Lance Stroll"
    },
    {
      "Top": 360.0,
      "Left": 2560.0,
      "Width": 640.0,
      "Height": 360.0,
      "FullScreen": false,
      "ResizeMode": 0,
      "VideoQuality": 3,
      "Topmost": false,
      "IsMuted": true,
      "Volume": 100,
      "Zoom": 0,
      "AspectRatio": "Keep",
      "AudioDevice": "Default",
      "ChannelName": "Guanyu Zhou"
    },
    {
      "Top": 360.0,
      "Left": 3200.0,
      "Width": 640.0,
      "Height": 360.0,
      "FullScreen": false,
      "ResizeMode": 0,
      "VideoQuality": 3,
      "Topmost": false,
      "IsMuted": true,
      "Volume": 100,
      "Zoom": 0,
      "AspectRatio": "Keep",
      "AudioDevice": "Default",
      "ChannelName": "Daniel Ricciardo"
    },
    {
      "Top": 720.0,
      "Left": 0.0,
      "Width": 1280.0,
      "Height": 720.0,
      "FullScreen": false,
      "ResizeMode": 0,
      "VideoQuality": 3,
      "Topmost": false,
      "IsMuted": false,
      "Volume": 100,
      "Zoom": 0,
      "AspectRatio": "Keep",
      "AudioDevice": "Default",
      "AudioTrack": "teamradio",
      "ChannelName": "Lewis Hamilton"
    },
    {
      "Top": 720.0,
      "Left": 1280.0,
      "Width": 1280.0,
      "Height": 720.0,
      "FullScreen": false,
      "ResizeMode": 0,
      "VideoQuality": 3,
      "Topmost": false,
      "IsMuted": false,
      "Volume": 50,
      "Zoom": 0,
      "AspectRatio": "Keep",
      "AudioDevice": "Default",
      "AudioTrack": "eng",
      "ChannelName": "INTERNATIONAL"
    },
    {
      "Top": 720.0,
      "Left": 2560.0,
      "Width": 1280.0,
      "Height": 720.0,
      "FullScreen": false,
      "ResizeMode": 0,
      "VideoQuality": 3,
      "Topmost": false,
      "IsMuted": true,
      "Volume": 100,
      "Zoom": 0,
      "AspectRatio": "Keep",
      "AudioDevice": "Default",
      "ChannelName": "George Russell"
    },
    {
      "Top": 1440.0,
      "Left": 0.0,
      "Width": 640.0,
      "Height": 360.0,
      "FullScreen": false,
      "ResizeMode": 0,
      "VideoQuality": 3,
      "Topmost": false,
      "IsMuted": true,
      "Volume": 100,
      "Zoom": 0,
      "AspectRatio": "Keep",
      "AudioDevice": "Default",
      "ChannelName": "Max Verstappen"
    },
    {
      "Top": 1440.0,
      "Left": 640.0,
      "Width": 640.0,
      "Height": 360.0,
      "FullScreen": false,
      "ResizeMode": 0,
      "VideoQuality": 3,
      "Topmost": false,
      "IsMuted": true,
      "Volume": 100,
      "Zoom": 0,
      "AspectRatio": "Keep",
      "AudioDevice": "Default",
      "ChannelName": "Charles Leclerc"
    },
    {
      "Top": 1440.0,
      "Left": 1280.0,
      "Width": 1280.0,
      "Height": 720.0,
      "FullScreen": false,
      "ResizeMode": 0,
      "VideoQuality": 3,
      "Topmost": false,
      "IsMuted": true,
      "Volume": 100,
      "Zoom": 0,
      "AspectRatio": "Keep",
      "AudioDevice": "Default",
      "ChannelName": "TRACKER"
    },
    {
      "Top": 1440.0,
      "Left": 2560.0,
      "Width": 640.0,
      "Height": 360.0,
      "FullScreen": false,
      "ResizeMode": 0,
      "VideoQuality": 3,
      "Topmost": false,
      "IsMuted": true,
      "Volume": 100,
      "Zoom": 0,
      "AspectRatio": "Keep",
      "AudioDevice": "Default",
      "ChannelName": "Esteban Ocon"
    },
    {
      "Top": 1440.0,
      "Left": 3200.0,
      "Width": 640.0,
      "Height": 360.0,
      "FullScreen": false,
      "ResizeMode": 0,
      "VideoQuality": 3,
      "Topmost": false,
      "IsMuted": true,
      "Volume": 100,
      "Zoom": 0,
      "AspectRatio": "Keep",
      "AudioDevice": "Default",
      "ChannelName": "Kevin Magnussen"
    },
    {
      "Top": 1800.0,
      "Left": 0.0,
      "Width": 640.0,
      "Height": 360.0,
      "FullScreen": false,
      "ResizeMode": 0,
      "VideoQuality": 3,
      "Topmost": false,
      "IsMuted": true,
      "Volume": 100,
      "Zoom": 0,
      "AspectRatio": "Keep",
      "AudioDevice": "Default",
      "ChannelName": "Sergio Perez"
    },
    {
      "Top": 1800.0,
      "Left": 640.0,
      "Width": 640.0,
      "Height": 360.0,
      "FullScreen": false,
      "ResizeMode": 0,
      "VideoQuality": 3,
      "Topmost": false,
      "IsMuted": true,
      "Volume": 100,
      "Zoom": 0,
      "AspectRatio": "Keep",
      "AudioDevice": "Default",
      "ChannelName": "Carlos Sainz"
    },
    {
      "Top": 1800.0,
      "Left": 2560.0,
      "Width": 640.0,
      "Height": 360.0,
      "FullScreen": false,
      "ResizeMode": 0,
      "VideoQuality": 3,
      "Topmost": false,
      "IsMuted": true,
      "Volume": 100,
      "Zoom": 0,
      "AspectRatio": "Keep",
      "AudioDevice": "Default",
      "ChannelName": "Fernando Alonso"
    },
    {
      "Top": 1800.0,
      "Left": 3200.0,
      "Width": 640.0,
      "Height": 360.0,
      "FullScreen": false,
      "ResizeMode": 0,
      "VideoQuality": 3,
      "Topmost": false,
      "IsMuted": true,
      "Volume": 100,
      "Zoom": 0,
      "AspectRatio": "Keep",
      "AudioDevice": "Default",
      "ChannelName": "Mick Schumacher"
    }
  ]
}
SuRGeoNix commented 2 years ago

This is very possible a thread pool issue. @robvdpol should consider increasing or exposing a config for the .NET's thread pool. This is what I do on my sample flyleaf version:-

ThreadPool.GetMinThreads(out int workers, out int ports);
ThreadPool.SetMinThreads(workers + 6, ports + 6);