将数据类型为 YUY2 的 IMFMediaBuffer 数据转换为 RGB24 或 RGB32
我正在使用 MediaFoundation APIS 从网络摄像头读取帧。
IMFMediaType mediatype = null;
Hresult hr= mSourceReaderAsync.GetNativeMediaType((int)MF_SOURCE_READER.FirstAudioStream, i, out mediatype);
仅返回 YUY2 媒体类型。所以我得到 ReadSample 的输出给出 YUY2 帧。我需要将 YUY2 转换为 RGB24 或 BitmapSource 以在 WPF 窗口中显示。 这是我的 OnRead 回调方法
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;
}
,现在它引发异常:{“找不到适合完成此操作的成像组件。”}
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."}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为你可以使用 Media Foundation Transform 在类型之间进行转换。你可以通过 snarfle 参考来自 MF.net 的示例
在此处输入链接说明
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
您有多种转换帧的选项。
我会在您的场景中推荐 MFT。也许尝试设置 DirectX 或 OpenGL 进行显示;对于更高的分辨率,使用 BitmapSources 的解决方案可能会很慢。
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.