While DxSnap is a good introductory sample, it cuts a pair of angles making artifacts like the ones mentioned possible. The problem is assuming this in the following line:
m_stride = m_videoWidth * (videoInfoHeader.BmiHeader.BitCount / 8);
The actual step may be different, and this is a well-known effect of video equipment that offers great success. When you copy an image from the Sample Grabber buffer, it would be more accurate to list the step as BufferLen / m_videoHeight (see the code snippet below, and also note the statement there - perhaps you ignore it or run release builds). It would be even better to just check the current media type and get from there.
You may not have a problem with the first instance of the video pipeline, as it may use the video overlay and a different code path. You may not have a problem with well-aligned frame sizes (widths) such as 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 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; }
source share