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.