首次打开后,Dxsnap无法正确显示视频

时间:2016-02-15 10:17:48

标签: c# video directshow directshow.net

我正在使用 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);
    }
}

Video Display Error

即使重新启动电脑,它仍然是相同的 我没有改变DxSnap表格中的任何内容。

1 个答案:

答案 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;
}