Reputation: 81
I am reading a frames from my web cam using MediaFoundation APIS.
IMFMediaType mediatype = null;
Hresult hr= mSourceReaderAsync.GetNativeMediaType((int)MF_SOURCE_READER.FirstAudioStream, i, out mediatype);
returns only YUY2 media types.So i am getting the output of ReadSample gives YUY2 frame. I need to convert YUY2 to RGB24 or BitmapSource to show in WPF window. This is my OnRead callback method
public HResult OnReadSample(HResult hrStatus, int dwStreamIndex, MF_SOURCE_READER_FLAG dwStreamFlags, long llTimestamp, IMFSample pSample)
{
HResult hr = hrStatus;
IMFMediaBuffer pBuffer = null;
Stream s = null;
JpegBitmapDecoder jpgdecoder = null;
BitmapSource cameraframe = null;
lock (this)
{
try
{
if (Succeeded(hr))
{
if (pSample != null)
{
// Get the video frame buffer from the sample.
hr = pSample.GetBufferByIndex(0, out pBuffer);
}
}
if (pBuffer != null)
{
int maxlen, curlen;
pBuffer.GetMaxLength(out maxlen);
pBuffer.GetCurrentLength(out curlen);
var arr = new byte[maxlen - 1];
pBuffer.Lock(out IntPtr ptr, out int maxLen, out int curLen);
if (arr == null)
arr = new byte[maxlen - 1];
var writable = (maxlen > 0) ? true : false;
if (s == null)
s = new MemoryStream(arr, writable);
System.Runtime.InteropServices.Marshal.Copy(ptr, arr, 0, curlen);
s.Flush();
s.Seek(0, SeekOrigin.Begin);
if (jpgdecoder == null)
jpgdecoder = new JpegBitmapDecoder(s, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
var frame = jpgdecoder.Frames[0];
cameraframe = frame;
}
dispatcher.Invoke(() =>
{
OnCapture.Invoke(this, cameraframe);
});
// Request the next frame.
if (Succeeded(hr))
{
// Ask for the first sample.
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
finally
{
SafeRelease(pBuffer);
SafeRelease(pSample);
dispatcher.Invoke(() =>
{
hr = mSourceReaderAsync.ReadSample((int)MF_SOURCE_READER.FirstVideoStream, 0, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
});
}
}
return hr;
}
now it raises exception that {"No imaging component suitable to complete this operation was found."}
Upvotes: 1
Views: 770
Reputation: 332
You have several options for converting frames.
I would recommend MFTs in your scenario. Maybe try to set up DirectX or OpenGL for displaying; your solution with BitmapSources can be slow for higher resolutions.
Upvotes: 1
Reputation: 21
I think you can use Media foundation transform to convert between types.You can refer samples from MF.net by snarfle enter link description here
Upvotes: 1