Maybe this should become the "hello world" of filters programming, a filter to turn video to gray scale.
The following code is my first transform filter, it only handles YUY2 input and output video type (80 lines "all included" ;-)
public class GrayFilter : Filter
{
private InputPin _inputPin; // one input pin and one output pin
private IOutputPin _outputPin;
private IMediaType _vidType; // store our video type
public GrayFilter()
: base("GrayFilter")
{
_inputPin = new InputPin("Input", this);
_inputPin.CheckMediaTypeEvent += new CheckMediaTypeEventHandler(checkMediaTypeHandler);
_outputPin = new DoGrayOutputPin("Output", this);
}
bool checkMediaTypeHandler(IInputPin p, IMediaType mt)
{
IVideoType vt = mt as IVideoType;
if (vt == null || vt.Id != MediaType.YUY2)
return false;
else
{
// return true only for yuy2 and store the video type away
_vidType = mt;
return true;
}
}
public override IEnumerable<IPin> Pins
{
get
{
yield return _inputPin;
yield return _outputPin;
}
}
IMediaSample s = sample as IMediaSample;
if (s != null)
{
// yuy2 is a packed format with 2 macro pix per uint
// just overwrite every other bytes
int length = s.Data.Length;
fixed (byte* bptr = s.Data)
{
for (int i = 1; i < length; i += 2)
bptr[i] = (byte)128;
}
}
// pass the sample along
_outputPin.Receive(this, sample);
}
// need to define our outpin type since OutputPin is abstract
public class DoGrayOutputPin : OutputPin
{
public DoGrayOutputPin(string name, IFilter owner)
: base(name, owner)
{
}
public override IEnumerable<IMediaType> OutputMediaTypes
{
get
{
GrayFilter f = Owner as GrayFilter;
// return the video type of the input pin if it's connected
if (f != null && f._inputPin.Connected != null)
yield return f._vidType;
else
yield return null;
}
}
}
}
Just add the previous class and the following changes to testapp.cs:
(after the call to _graph.AddSource(...
IFilter doGrayFilter = new GrayFilter();
_graph.Connect(filter, doGrayFilter, true);
_graph.Render(doGrayFilter);
Since this is pretty new to everyone, your comments and suggestions are welcome.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Maybe this should become the "hello world" of filters programming, a filter to turn video to gray scale.
The following code is my first transform filter, it only handles YUY2 input and output video type (80 lines "all included" ;-)
public class GrayFilter : Filter
{
private InputPin _inputPin; // one input pin and one output pin
private IOutputPin _outputPin;
private IMediaType _vidType; // store our video type
public GrayFilter()
: base("GrayFilter")
{
_inputPin = new InputPin("Input", this);
_inputPin.CheckMediaTypeEvent += new CheckMediaTypeEventHandler(checkMediaTypeHandler);
_outputPin = new DoGrayOutputPin("Output", this);
}
bool checkMediaTypeHandler(IInputPin p, IMediaType mt)
{
IVideoType vt = mt as IVideoType;
if (vt == null || vt.Id != MediaType.YUY2)
return false;
else
{
// return true only for yuy2 and store the video type away
_vidType = mt;
return true;
}
}
public override IEnumerable<IPin> Pins
{
get
{
yield return _inputPin;
yield return _outputPin;
}
}
unsafe public override void Receive(ISampleStream sender, ISample sample)
{
base.Receive(sender, sample);
IMediaSample s = sample as IMediaSample;
if (s != null)
{
// yuy2 is a packed format with 2 macro pix per uint
// just overwrite every other bytes
int length = s.Data.Length;
fixed (byte* bptr = s.Data)
{
for (int i = 1; i < length; i += 2)
bptr[i] = (byte)128;
}
}
// pass the sample along
_outputPin.Receive(this, sample);
}
// need to define our outpin type since OutputPin is abstract
public class DoGrayOutputPin : OutputPin
{
public DoGrayOutputPin(string name, IFilter owner)
: base(name, owner)
{
}
public override IEnumerable<IMediaType> OutputMediaTypes
{
get
{
GrayFilter f = Owner as GrayFilter;
// return the video type of the input pin if it's connected
if (f != null && f._inputPin.Connected != null)
yield return f._vidType;
else
yield return null;
}
}
}
}
Just add the previous class and the following changes to testapp.cs:
(after the call to _graph.AddSource(...
IFilter doGrayFilter = new GrayFilter();
_graph.Connect(filter, doGrayFilter, true);
_graph.Render(doGrayFilter);
Since this is pretty new to everyone, your comments and suggestions are welcome.