我正在使用 DirectShowLib-2005 - DxSnap 示例来显示和捕获网络摄像头中的图像。
这个例子一切正常
但是当我尝试将它与我的应用程序合并时(我试图从我的主要表单中调用该表单),这是第一次工作。关闭并打开捕获窗口后,它无法正常显示视频
但是图像的捕获始终完美无缺。
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表格中的任何内容。
答案 0 :(得分:3)
虽然DxSnap
是一个很好的介绍性示例,但它会削减几个角落,使得所提到的工件成为可能。问题是在以下行中假设:
m_stride = m_videoWidth * (videoInfoHeader.BmiHeader.BitCount / 8);
实际步幅可能不同,视频硬件的众所周知的效果表明步幅增加。当您从Sample Grabber缓冲区复制图像时,将步幅重新计算为BufferLen / m_videoHeight
会更准确(请参阅下面的代码片段;还要注意那里的断言 - 可能是您忽略它或运行Release版本)。简单地检查当前的媒体类型并从那里获得步幅会更好。
您可能没有第一个视频管道实例的问题,因为它可能使用视频覆盖和不同的代码路径。您可能完全没有问题,具有良好对齐的帧大小(宽度),如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;
}