问题
I am using DirectShowLib-2005 - DxSnap example to display and capture the image from Webcam.
Everything works fine with the example.
But when i try to merge it with my application (i tried to call that form from my main form) it is working for the first time. Once i close and open the capture window, it is not displaying the video properly.
But the capturing of the image works perfectly all the time.
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);
}
}
Even after restarting the PC, its still the same.
I have not changed anything in the DxSnap form.
回答1:
While DxSnap
is a good introductory sample, it cuts a couple of corners making artifacts like mentioned possible. The problem is the assumption this in the following line:
m_stride = m_videoWidth * (videoInfoHeader.BmiHeader.BitCount / 8);
Actual stride might be different and it's a well known effect of video hardware suggesting increased strides. When you copy image from Sample Grabber buffer, it would be more accurate to re-compute stride as BufferLen / m_videoHeight
(see code snippet below; also note assertion there -- presumably you are ignoring it or running Release builds). It would be even better to simply check current media type and obtain stride from there.
You might be not having the problem with first instance of video pipeline since it might be using video overlay and different code path. You might have no issue at all with well-aligned frame sizes (widths) like 640, 1024 etc.
/// <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;
}
来源:https://stackoverflow.com/questions/35406684/dxsnap-not-displaying-the-video-properly-after-first-time-open