这是我关于stackoverflow的第一个问题。 我使用Directshow.NET捕获网络摄像头,然后使用SlimDX渲染它。 虽然我无法正确渲染纹理。
如果我将数据从网络摄像头复制到位图并将其设置为图片框,这就是我得到的: https://www.dropbox.com/s/qxw08b89613u7gl/Bitmap.PNG (好像我的第一篇文章时我不能发布图片)
虽然如果我将数据复制到纹理并渲染它,我得到: https://www.dropbox.com/s/bvoj2qzfv80q84x/d3dTexture.PNG
这是我的相机捕捉类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using DirectShowLib;
using SlimDX;
using SlimDX.Direct3D9;
namespace SlimDXTest
{
public delegate void FrameCompleteEventHandler(ref Texture texture);
class Camera : ISampleGrabberCB, IDisposable
{
public event FrameCompleteEventHandler FrameComplete;
private object lockObject = new object();
private IMediaControl mediaControl = null;
private IMediaEvent mediaEvent = null;
private IGraphBuilder pGraph = null;
private byte[] frameData = new byte[1280 * 720 * 4];
private Device d3dDevice;
public Texture texture;
public System.Drawing.Bitmap currentBitmap = null;
private Test bitmapWindow;
public Camera(DsDevice device, Device d3dDevice)
{
bitmapWindow = new Test();
bitmapWindow.Show();
this.d3dDevice = d3dDevice;
texture = new Texture(d3dDevice, 1280, 720, 1, Usage.Dynamic, Format.A8R8G8B8, Pool.Default);
try
{
BuildGraph(device);
}
catch
{
Dispose();
throw;
}
}
private void BuildGraph(DirectShowLib.DsDevice dsDevice)
{
int hr = 0;
pGraph = new FilterGraph() as IFilterGraph2;
//graph builder
ICaptureGraphBuilder2 pBuilder = (ICaptureGraphBuilder2)new CaptureGraphBuilder2();
try
{
hr = pBuilder.SetFiltergraph(pGraph);
DsError.ThrowExceptionForHR(hr);
// Add camera
IBaseFilter camera;
//hr = pGraph.FindFilterByName(dsDevice.Name, out camera);
hr = ((IFilterGraph2)pGraph).AddSourceFilterForMoniker(dsDevice.Mon, null, dsDevice.Name, out camera);
DsError.ThrowExceptionForHR(hr);
hr = pGraph.AddFilter(camera, "camera");
DsError.ThrowExceptionForHR(hr);
// Set format for camera
AMMediaType pmt = new AMMediaType();
pmt.majorType = MediaType.Video;
pmt.subType = MediaSubType.MJPG;
pmt.formatType = FormatType.VideoInfo;
pmt.fixedSizeSamples = true;
pmt.formatSize = 88;
pmt.sampleSize = 2764800;
pmt.temporalCompression = false;
VideoInfoHeader format = new VideoInfoHeader();
format.SrcRect = new DsRect();
format.TargetRect = new DsRect();
format.BitRate = 663552000;
format.AvgTimePerFrame = 333333;
format.BmiHeader = new BitmapInfoHeader();
format.BmiHeader.Size = 40;
format.BmiHeader.Width = 1280;
format.BmiHeader.Height = 720;
format.BmiHeader.Planes = 1;
format.BmiHeader.BitCount = 24;
format.BmiHeader.Compression = 1196444237;
format.BmiHeader.ImageSize = 2764800;
pmt.formatPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(format));
Marshal.StructureToPtr(format, pmt.formatPtr, false);
hr = ((IAMStreamConfig)DsFindPin.ByCategory(camera, PinCategory.Capture, 0)).SetFormat(pmt);
//hr = ((IAMStreamConfig)GetPin(pUSB20Camera, "Capture")).SetFormat(pmt);
DsUtils.FreeAMMediaType(pmt);
DsError.ThrowExceptionForHR(hr);
//add MJPG Decompressor
IBaseFilter pMJPGDecompressor = (IBaseFilter)new MjpegDec();
hr = pGraph.AddFilter(pMJPGDecompressor, "MJPG Decompressor");
DsError.ThrowExceptionForHR(hr);
//add color space converter
IBaseFilter pColorSpaceConverter = (IBaseFilter)new Colour();
hr = pGraph.AddFilter(pColorSpaceConverter, "Color space converter");
DsError.ThrowExceptionForHR(hr);
// Connect camera and MJPEG Decomp
//hr = pGraph.ConnectDirect(GetPin(pUSB20Camera, "Capture"), GetPin(pMJPGDecompressor, "XForm In"), null);
hr = pGraph.ConnectDirect(DsFindPin.ByCategory(camera, PinCategory.Capture, 0), DsFindPin.ByName(pMJPGDecompressor, "XForm In"), null);
DsError.ThrowExceptionForHR(hr);
// Connect MJPG Decomp and color space converter
hr = pGraph.ConnectDirect(DsFindPin.ByName(pMJPGDecompressor, "XForm Out"), DsFindPin.ByName(pColorSpaceConverter, "Input"), null);
DsError.ThrowExceptionForHR(hr);
//add SampleGrabber
//IBaseFilter pSampleGrabber = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_SampleGrabber));
//hr = pGraph.AddFilter(pSampleGrabber, "SampleGrabber");
IBaseFilter sampleGrabber = new SampleGrabber() as IBaseFilter;
hr = pGraph.AddFilter(sampleGrabber, "Sample grabber");
DsError.ThrowExceptionForHR(hr);
// Configure the samplegrabber
AMMediaType pSampleGrabber_pmt = new AMMediaType();
pSampleGrabber_pmt.majorType = MediaType.Video;
pSampleGrabber_pmt.subType = MediaSubType.ARGB32;
pSampleGrabber_pmt.formatType = FormatType.VideoInfo;
pSampleGrabber_pmt.fixedSizeSamples = true;
pSampleGrabber_pmt.formatSize = 88;
pSampleGrabber_pmt.sampleSize = 3686400;
pSampleGrabber_pmt.temporalCompression = false;
VideoInfoHeader pSampleGrabber_format = new VideoInfoHeader();
pSampleGrabber_format.SrcRect = new DsRect();
pSampleGrabber_format.TargetRect = new DsRect();
pSampleGrabber_format.BitRate = 884736885;
pSampleGrabber_format.AvgTimePerFrame = 333333;
pSampleGrabber_format.BmiHeader = new BitmapInfoHeader();
pSampleGrabber_format.BmiHeader.Size = 40;
pSampleGrabber_format.BmiHeader.Width = 1280;
pSampleGrabber_format.BmiHeader.Height = 720;
pSampleGrabber_format.BmiHeader.Planes = 1;
pSampleGrabber_format.BmiHeader.BitCount = 32;
//pSampleGrabber_format.BmiHeader.Compression = 1196444237;
pSampleGrabber_format.BmiHeader.ImageSize = 3686400;
pSampleGrabber_pmt.formatPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(pSampleGrabber_format));
Marshal.StructureToPtr(pSampleGrabber_format, pSampleGrabber_pmt.formatPtr, false);
hr = ((ISampleGrabber)sampleGrabber).SetMediaType(pSampleGrabber_pmt);
DsError.ThrowExceptionForHR(hr);
//connect MJPG dec and SampleGrabber
//hr = pGraph.ConnectDirect(GetPin(pMJPGDecompressor, "XForm Out"), GetPin(pSampleGrabber, "Input"), null);
hr = pGraph.ConnectDirect(DsFindPin.ByName(pColorSpaceConverter, "XForm Out"), DsFindPin.ByName(sampleGrabber, "Input"), null);
DsError.ThrowExceptionForHR(hr);
//set callback
hr = ((ISampleGrabber)sampleGrabber).SetCallback(this, 1);
DsError.ThrowExceptionForHR(hr);
}
finally
{
// Clean this mess up!
}
}
public void StartCapture()
{
IMediaControl mediaControl = (IMediaControl)pGraph;
IMediaEvent mediaEvent = (IMediaEvent)pGraph;
int hr = mediaControl.Run();
}
public int BufferCB(double SampleTime, IntPtr pBuffer, int BufferLen)
{
lock (lockObject)
{
Marshal.Copy(pBuffer, frameData, 0, BufferLen);
var data = texture.LockRectangle(0, LockFlags.None);
data.Data.Write(frameData, 0, BufferLen);
texture.UnlockRectangle(0);
/*
Surface privateSurface = texture.GetSurfaceLevel(0);
var graphicsStream = privateSurface.LockRectangle(LockFlags.None);
graphicsStream.Data.WriteRange(pBuffer, BufferLen);
privateSurface.UnlockRectangle();
*/
currentBitmap = new System.Drawing.Bitmap(1280, 720, 1280 * 4, System.Drawing.Imaging.PixelFormat.Format32bppArgb, pBuffer);
(bitmapWindow.getPixBox()).Image = currentBitmap;
FrameComplete(ref texture);
return 0;
}
}
public int SampleCB(double SampleTime, IMediaSample pSample)
{
return 0;
}
public void Dispose()
{
throw new NotImplementedException();
}
}
}
我无法弄清问题是什么。任何帮助将不胜感激。