Dxsnap 第一次打开后无法正确显示视频
Dxsnap not displaying the video properly after first time open
我正在使用 DirectShowLib-2005 - DxSnap 示例来显示和捕获图像来自网络摄像头。
这个例子一切正常。
但是当我尝试将它与我的应用程序合并时(我试图从我的主窗体调用该窗体)它是第一次工作。一旦我关闭并打开捕获 window,它就无法正确显示视频。
但是图像的捕获始终完美无缺。
public partial class frmMain : Form
{
public frmMain()
{
InitializeComponent();
}
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
private static void Main()
{
Application.Run(new frmMain());
}
private void button1_Click(object sender, EventArgs e)
{
frmdxSnap frmdxSnap = new frmdxSnap();
frmdxSnap.ShowDialog(this);
}
}
重启电脑后还是一样
我没有更改 DxSnap 表单中的任何内容。
虽然 DxSnap
是一个很好的介绍性示例,但它削减了几个角落,使提到的工件成为可能。问题是以下行中的假设:
m_stride = m_videoWidth * (videoInfoHeader.BmiHeader.BitCount / 8);
实际步幅可能不同,这是众所周知的视频硬件效果,表明步幅增加。当您从 Sample Grabber 缓冲区复制图像时,将步幅重新计算为 BufferLen / m_videoHeight
会更准确(参见下面的代码片段;另请注意那里的断言——可能您忽略了它或 运行 发布版本).简单地检查当前的媒体类型并从那里获得进展会更好。
您可能没有遇到第一个视频管道实例的问题,因为它可能使用视频覆盖和不同的代码路径。对于像 640、1024 等对齐良好的帧大小(宽度),您可能完全没有问题。
/// <summary> buffer callback, COULD BE FROM FOREIGN THREAD. </summary>
int ISampleGrabberCB.BufferCB( double SampleTime, IntPtr pBuffer, int BufferLen )
{
// Note that we depend on only being called once per call to Click. Otherwise
// a second call can overwrite the previous image.
Debug.Assert(BufferLen == Math.Abs(m_stride) * m_videoHeight, "Incorrect buffer length");
if (m_WantOne)
{
m_WantOne = false;
Debug.Assert(m_ipBuffer != IntPtr.Zero, "Unitialized buffer");
// Save the buffer
CopyMemory(m_ipBuffer, pBuffer, BufferLen);
////////////////////////////////////////////
// HOTFIX: Let's have the stride re-computed for the case it was changed dynamically or otherwise
m_stride = BufferLen / m_videoHeight;
////////////////////////////////////////////
// Picture is ready.
m_PictureReady.Set();
}
return 0;
}
我正在使用 DirectShowLib-2005 - DxSnap 示例来显示和捕获图像来自网络摄像头。
这个例子一切正常。
但是当我尝试将它与我的应用程序合并时(我试图从我的主窗体调用该窗体)它是第一次工作。一旦我关闭并打开捕获 window,它就无法正确显示视频。
但是图像的捕获始终完美无缺。
public partial class frmMain : Form
{
public frmMain()
{
InitializeComponent();
}
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
private static void Main()
{
Application.Run(new frmMain());
}
private void button1_Click(object sender, EventArgs e)
{
frmdxSnap frmdxSnap = new frmdxSnap();
frmdxSnap.ShowDialog(this);
}
}
重启电脑后还是一样
我没有更改 DxSnap 表单中的任何内容。
虽然 DxSnap
是一个很好的介绍性示例,但它削减了几个角落,使提到的工件成为可能。问题是以下行中的假设:
m_stride = m_videoWidth * (videoInfoHeader.BmiHeader.BitCount / 8);
实际步幅可能不同,这是众所周知的视频硬件效果,表明步幅增加。当您从 Sample Grabber 缓冲区复制图像时,将步幅重新计算为 BufferLen / m_videoHeight
会更准确(参见下面的代码片段;另请注意那里的断言——可能您忽略了它或 运行 发布版本).简单地检查当前的媒体类型并从那里获得进展会更好。
您可能没有遇到第一个视频管道实例的问题,因为它可能使用视频覆盖和不同的代码路径。对于像 640、1024 等对齐良好的帧大小(宽度),您可能完全没有问题。
/// <summary> buffer callback, COULD BE FROM FOREIGN THREAD. </summary>
int ISampleGrabberCB.BufferCB( double SampleTime, IntPtr pBuffer, int BufferLen )
{
// Note that we depend on only being called once per call to Click. Otherwise
// a second call can overwrite the previous image.
Debug.Assert(BufferLen == Math.Abs(m_stride) * m_videoHeight, "Incorrect buffer length");
if (m_WantOne)
{
m_WantOne = false;
Debug.Assert(m_ipBuffer != IntPtr.Zero, "Unitialized buffer");
// Save the buffer
CopyMemory(m_ipBuffer, pBuffer, BufferLen);
////////////////////////////////////////////
// HOTFIX: Let's have the stride re-computed for the case it was changed dynamically or otherwise
m_stride = BufferLen / m_videoHeight;
////////////////////////////////////////////
// Picture is ready.
m_PictureReady.Set();
}
return 0;
}