Is there a way to decrease CPU consumption while playing multiple MediaPlayers instances?

152 Views Asked by At

I need to play 15 light videos simultaneously using MediaPlayer and Composition API.

So I created a simple UWP app:

public sealed partial class MainPage
{
    public MainPage()
    {
        InitializeComponent();
        Loaded += MainPage_Loaded;
    }
    private void MainPage_Loaded(object sender, RoutedEventArgs e)
    {
        var compositor = ElementCompositionPreview.GetElementVisual(MainGrid).Compositor;
        var container = compositor.CreateContainerVisual();
        var k = 0;
        for (int i = 0; i < 3; i++)
        {
            for (int j = 0; j < 5; j++, k++)
            {
                var mediaPlayer = new MediaPlayer
                {
                    Source = new MediaPlaybackItem(MediaSource.CreateFromUri(new Uri($"ms-appx:///Assets/{k}.mp4"))),
                    AutoPlay = true,
                    IsMuted = true,
                    IsLoopingEnabled = true,
                    RealTimePlayback = true
                };
                mediaPlayer.SetSurfaceSize(new Size(512, 512));

                var surfaceBrush = compositor.CreateSurfaceBrush(mediaPlayer.GetSurface(compositor).CompositionSurface);

                var sprite = compositor.CreateSpriteVisual();
                sprite.Size = new Vector2(512, 512);
                sprite.Offset = new Vector3(512 * j, 512 * i, 0);
                sprite.Brush = surfaceBrush;

                container.Children.InsertAtTop(sprite);
            }
        }

        ElementCompositionPreview.SetElementChildVisual(MainGrid, container);
    }
}

CPU rises to 25% and GPU about 30%. (CPU - i7 4770, GPU - nVidia GTX 970)

Shouldn't GPU take all the work and is there a way to calm down CPU? Or is there another way to play many videos in UWP with light CPU usage?

All videos are 512x512px 60fps h264 *.mp4 about 10MB each.

Tried to use 15 VLC instances - the result 100% of CPU. Also tried a lot of different codecs - no use.

[EDIT]

I run my app with Concurrency Vizualizer and found out that 98% goes to synchronization events though hardware GPU decoder is not overloaded. Is there a way to decrease those events?

enter image description here

[EDIT] I've just saved 10% of CPU by replacing all video to RAM and my app stopped to read SSD:

    var file = await StorageFile.GetFileFromApplicationUriAsync(new Uri($"ms-appx:///Assets/{k}.mp4"));
    var reference = RandomAccessStreamReference.CreateFromFile(file);

Now i'm thinking how to avoid RAM and pass my videos directly to GPU memory.

Is it possible?

0

There are 0 best solutions below