IBasicVideoEffect обрабатывает только от 3 до 8 первых кадров

Я создал простое тестовое приложение UWP с одной MainPage, которая имеет MediaPlayer:

public sealed partial class MainPage
{
    public MainPage()
    {
        InitializeComponent();
        Loaded += MainPage_Loaded;
    }

    private void MainPage_Loaded(object sender, RoutedEventArgs e)
    {
        var mediaPlayer = new MediaPlayer
        {
            Source = MediaSource.CreateFromUri(new Uri("ms-appx:///Assets/preview.mp4")),
            AutoPlay = true
        };
        mediaPlayer.AddVideoEffect(typeof(VideoEffect).FullName, true, null);
    }
}

и компонент WinRT с унаследованным классом IBasicVideoEffect, который уведомляет меня, сколько кадров было обработано:

public sealed class VideoEffect : IBasicVideoEffect
{
    public IReadOnlyList<VideoEncodingProperties> SupportedEncodingProperties => new List<VideoEncodingProperties>();

    public bool IsReadOnly => false;

    public MediaMemoryTypes SupportedMemoryTypes => MediaMemoryTypes.Gpu;

    public void SetProperties(IPropertySet configuration) { }

    public bool TimeIndependent => false;

    public void Close(MediaEffectClosedReason reason) { }

    public void DiscardQueuedFrames() { }

    private int _frameCounter;

    public void ProcessFrame(ProcessVideoFrameContext context)
    {
        _frameCounter++;
        Debug.WriteLine("Frame #" + _frameCounter);
    }

    public void SetEncodingProperties(VideoEncodingProperties encodingProperties, IDirect3DDevice device)
    {
        Debug.WriteLine("SetEncodingProperties");
    }
}

Если я запустлю его - будут обработаны только 3 кадра, независимо от того, какой видео файл будет.

Если я установлю точку останова с шагом _frameCounter, мне удастся нажать F5 на 8 кадров.

Почему и как я могу получить все кадры для обработки?

Я могу решить эту проблему, используя MediaClip и MediaComposition, как говорят многие примеры, но в этом случае кадры обрабатываются процессором, а не видеопроцессором GPU, что не является моей целью.

1 ответ

Решение

Проблема в том, что вы играете в MediaPlayer, не отображая его в XAML. Таким образом, только первые несколько кадров были обработаны, так как мультимедийные данные не отображаются на интерфейсе пользователя, нет необходимости обрабатывать другие кадры.

Сделать ваш VideoEffect для работы, вы можете использовать элемент управления MediaPlayerElement с методом MediaPlayerElement.SetMediaPlayer для визуализации медиа.

XAML:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <MediaPlayerElement x:Name="mediaPlayerElement" />
</Grid>

Код-за:

private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
    var mediaPlayer = new MediaPlayer
    {
        Source = MediaSource.CreateFromUri(new Uri("ms-appx:///Assets/preview.mp4")),
        AutoPlay = true
    };
    mediaPlayer.AddVideoEffect(typeof(VideoEffect).FullName, true, null);

    mediaPlayerElement.SetMediaPlayer(mediaPlayer);
}

После этого вы увидите _frameCounter увеличивается во время воспроизведения медиа.

С MediaPlayer вы должны добавить эффект перед установкой источника.

effect.AddVideoEffect(_player);
_player.Source = MediaSource.CreateFromMediaStreamSource(source);
Другие вопросы по тегам