MediaClip is not rendered with custom IBasicVideoEffect

315 views Asked by At

I am trying to apply saturation video effect implemented with IBasicVideoEffect according to https://github.com/aarononeal/media-contrib example.

When I add VideoEffectDefinition to MediaClip, preview video is set, but nothing is rendered. (video disappears)

private void AddSaturationEffectButton_Click(object sender, RoutedEventArgs e)
{
    var clip = _composition.Clips[0];
    clip.VideoEffectDefinitions.Add(new VideoEffectDefinition(typeof(SaturationVideoEffect).FullName));

    SetupMediaStreamSource();
}

SaturationVideoEffect is implemented in separated Windows Runtime Component (Universal Windows) project.

using System;
using System.Collections.Generic;
using Windows.Foundation.Collections;
using Windows.Graphics.DirectX.Direct3D11;
using Windows.Media.Effects;
using Windows.Media.MediaProperties;
using Microsoft.Graphics.Canvas;
using Microsoft.Graphics.Canvas.Effects;

namespace VideoEffectsLibrary
{
    public sealed class SaturationVideoEffect : IBasicVideoEffect
    {
        private VideoEncodingProperties _currentEncodingProperties;
        private CanvasDevice _canvasDevice;
        private IPropertySet _configuration;

        private float Saturation
        {
            get
            {
                if (_configuration != null && _configuration.ContainsKey("Saturation"))
                    return (float)_configuration["Saturation"];
                else
                    return 0.5f;
            }
            set
            {
                _configuration["Saturation"] = value;
            }
        }

        public void ProcessFrame(ProcessVideoFrameContext context)
        {
            using (CanvasBitmap inputBitmap = CanvasBitmap.CreateFromDirect3D11Surface(_canvasDevice, context.InputFrame.Direct3DSurface))
            using (CanvasRenderTarget renderTarget = CanvasRenderTarget.CreateFromDirect3D11Surface(_canvasDevice, context.OutputFrame.Direct3DSurface))
            using (CanvasDrawingSession ds = renderTarget.CreateDrawingSession())
            {
                var saturation = new SaturationEffect()
                {
                    Source = inputBitmap,
                    Saturation = this.Saturation
                };
                ds.DrawImage(saturation);
            }
        }

        public void SetEncodingProperties(VideoEncodingProperties encodingProperties, IDirect3DDevice device)
        {
            _currentEncodingProperties = encodingProperties;
            _canvasDevice = CanvasDevice.CreateFromDirect3D11Device(device);
            CanvasDevice.DebugLevel = CanvasDebugLevel.Error;
        }

        public void SetProperties(IPropertySet configuration)
        {
            _configuration = configuration;
        }

        public bool IsReadOnly { get { return false; } }
        public MediaMemoryTypes SupportedMemoryTypes { get { return MediaMemoryTypes.Gpu; } }
        public bool TimeIndependent { get { return false; } }

        public IReadOnlyList<VideoEncodingProperties> SupportedEncodingProperties
        {
            get
            {
                return new List<VideoEncodingProperties>()
                {
                    // NOTE: Specifying width and height is only necessary due to bug in media pipeline when
                    // effect is being used with Media Capture. 
                    // This can be changed to "0, 0" in a future release of FBL_IMPRESSIVE. 
                    VideoEncodingProperties.CreateUncompressed(MediaEncodingSubtypes.Argb32, 800, 600)
                };
            }
        }

        public void Close(MediaEffectClosedReason reason)
        {
            // Clean up devices
            if (_canvasDevice != null)
                _canvasDevice.Dispose();
        }

        public void DiscardQueuedFrames()
        {
            // No cached frames to discard
        }
    }
}

How can I make this effect run properly? Thanks for help.

0

There are 0 answers