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

Oli*_*ham 5 c# video directshow directshow.net

我正在使用DirectShowLib-2005 - DxSnap 示例来显示和捕获来自Webcam的图像.
这个例子一切正常.
但是当我尝试将它与我的应用程序合并时(我试图从我的主要表单中调用该表单),这是第一次工作.关闭并打开捕获窗口后,它不会正确显示视频.
但是图像的捕获始终完美无缺.

 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

视频显示错误

即使在重新启动PC之后,它仍然是相同的.
我没有改变DxSnap表格中的任何内容.

Rom*_* R. 3

虽然DxSnap这是一个很好的介绍性示例,但它简化了一些工作,使上述的工件成为可能。问题在于以下行中的假设:

m_stride = m_videoWidth * (videoInfoHeader.BmiHeader.BitCount / 8);

实际的步幅可能有所不同,这是众所周知的视频硬件效果,表明步幅增加。当您从示例抓取器缓冲区复制图像时,重新计算步幅会更准确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;
}
Run Code Online (Sandbox Code Playgroud)