I'm trying to capture video from a WebCam using SharpDX.MediaFoundation (4.2.0). I'm able to render the default media type, but I want to be able to select between the different available formats of the device.
I can enumerate the device sources but I'm unable to get information about the video media types.
var attributes = new MediaAttributes(1);
attributes.Set(CaptureDeviceAttributeKeys.SourceType.Guid, CaptureDeviceAttributeKeys.SourceTypeVideoCapture.Guid);
var mediaSource = MediaFactory.EnumDeviceSources(attributes)[0].ActivateObject<MediaSource>();
mediaSource.CreatePresentationDescriptor(out var presentationDescriptor);
for (int d = 0; d < presentationDescriptor.StreamDescriptorCount; d++)
{
presentationDescriptor.GetStreamDescriptorByIndex(d, out var isSelected, out var streamDescriptor);
for (int i = 0; i < streamDescriptor.MediaTypeHandler.MediaTypeCount; i++)
{
var type = streamDescriptor.MediaTypeHandler.GetMediaTypeByIndex(i);
if (type.MajorType == MediaTypeGuids.Video)
{
var v = type.QueryInterface<VideoMediaType>();
// contains always empty values
var x = v.VideoFormat;
}
}
}
QueryInterface was not working. so I tried
new VideoMediaType(type.NativePointer)
But the result is the same.
Additionally I tried the same with a SourceReader
var reader = new SourceReader(mediaSource);
var mediaTypeIndex = 0;
using (var mt = reader.GetNativeMediaType(0, mediaTypeIndex))
{
if (mt.MajorType == MediaTypeGuids.Video)
{
//var vmt = new VideoMediaType(mt.NativePointer);
var v = mt.QueryInterface<VideoMediaType>();
var x = v.VideoFormat;
}
}
Same result. Any advises?
You should cast to SharpDX
MediaType
instead as it corresponds to IMFMediaType, but you already have it in mt variable anyway. It's IMFMediaType
that describes the video and audio media types provided by sources. VideoMediaType
or IMFVideoMediaType
is not guaranteed to be available.
You should be able to access different properties of the video media type contained in mt
by using it like this:
using (var mt = reader.GetNativeMediaType(0, mediaTypeIndex))
{
UnpackLong(mt.Get(MediaTypeAttributeKeys.FrameSize), out var width, out var height);
}
//Gets two integers from a long.
private void UnpackLong(long value, out int left, out int right)
{
left = (int)(value >> 32);
right = (int)(value & 0xffffffffL);
}
Check the SharpDX
interfaces here (search for IMFMediaType
).