我有一个能够同时运行YUY和MJPG色彩空间的网络摄像头。此相机默认为YUY,我需要在DirectShow图形中更改或添加什么才能以编程方式启动MJPG中的相机?我的代码与典型的图形设置非常相似,类似于DirectShow.Net示例目录中的DxSnap示例。 文档很少见,我见过的唯一示例是显示捕获引脚属性页并通过该UI更改它,但是我的技术需要以编程方式实现。 任何帮助,指导或建议将不胜感激。 谢谢
这是我的图形构造:
/// <summary> build the capture graph for grabber. </summary>
private void SetupGraph(DsDevice dev, int iFrameRate, int iWidth, int iHeight)
{
int hr;
ISampleGrabber sampGrabber = null;
ICaptureGraphBuilder2 capGraph = null;
// Get the graphbuilder object
m_graphBuilder = (IFilterGraph2)new FilterGraph();
m_mediaCtrl = m_graphBuilder as IMediaControl;
try
{
// Get the ICaptureGraphBuilder2
capGraph = (ICaptureGraphBuilder2)new CaptureGraphBuilder2();
// Get the SampleGrabber interface
sampGrabber = (ISampleGrabber)new SampleGrabber();
// Start building the graph
hr = capGraph.SetFiltergraph(m_graphBuilder);
DsError.ThrowExceptionForHR(hr);
// Add the video device
hr = m_graphBuilder.AddSourceFilterForMoniker(dev.Mon, null, "Video input", out capFilter);
DsError.ThrowExceptionForHR(hr);
IBaseFilter baseGrabFlt = (IBaseFilter)sampGrabber;
ConfigureSampleGrabber(sampGrabber);
// Add the frame grabber to the graph
hr = m_graphBuilder.AddFilter(baseGrabFlt, "Ds.NET Grabber");
DsError.ThrowExceptionForHR(hr);
// Get list of video compressors on the system
DsDevice[] videoCompressors = DsDevice.GetDevicesOfCat(FilterCategory.VideoCompressorCategory);
IBaseFilter videoCompressorFilter = null;
string videoCompressor = "MJPEG Compressor";
foreach (DsDevice compressor in videoCompressors)
{
if (compressor.Name == videoCompressor)
{
object obj = null;
Guid bfGuid = typeof(IBaseFilter).GUID;
compressor.Mon.BindToObject(null, null, ref bfGuid, out obj);
videoCompressorFilter = obj as IBaseFilter;
break; // Found the compressor - stop looking for it
}
}
if (videoCompressorFilter != null)
{
hr = m_graphBuilder.AddFilter(videoCompressorFilter, videoCompressor);
DsError.ThrowExceptionForHR(hr);
}
// If any of the default config items are set
if (iFrameRate + iHeight + iWidth > 0)
{
SetConfigParms(capGraph, capFilter, iFrameRate, iWidth, iHeight);
}
hr = capGraph.RenderStream(PinCategory.Capture, MediaType.Video, capFilter, null, baseGrabFlt);
DsError.ThrowExceptionForHR(hr);
SaveSizeInfo(sampGrabber);
}
finally
{
if (sampGrabber != null)
{
Marshal.ReleaseComObject(sampGrabber);
sampGrabber = null;
}
if (capGraph != null)
{
Marshal.ReleaseComObject(capGraph);
capGraph = null;
}
}
}
private void SaveSizeInfo(ISampleGrabber sampGrabber)
{
int hr;
// Get the media type from the SampleGrabber
AMMediaType media = new AMMediaType();
hr = sampGrabber.GetConnectedMediaType(media);
DsError.ThrowExceptionForHR(hr);
if ((media.formatType != FormatType.VideoInfo) || (media.formatPtr == IntPtr.Zero))
{
throw new NotSupportedException("Unknown ISampleGrabber Media Format");
}
// Grab the size info
VideoInfoHeader videoInfoHeader = (VideoInfoHeader)Marshal.PtrToStructure(media.formatPtr, typeof(VideoInfoHeader));
m_videoWidth = videoInfoHeader.BmiHeader.Width;
m_videoHeight = videoInfoHeader.BmiHeader.Height;
m_stride = m_videoWidth * (videoInfoHeader.BmiHeader.BitCount / 8);
DsUtils.FreeAMMediaType(media);
media = null;
}
private void ConfigureSampleGrabber(ISampleGrabber sampGrabber)
{
AMMediaType media;
int hr;
// Set the media type to Video/RBG24
media = new AMMediaType();
media.majorType = MediaType.Video;
media.subType = MediaSubType.MJPG;
media.formatType = FormatType.VideoInfo;
hr = sampGrabber.SetMediaType(media);
DsError.ThrowExceptionForHR(hr);
DsUtils.FreeAMMediaType(media);
media = null;
// Configure the samplegrabber
hr = sampGrabber.SetCallback(this, 1);
DsError.ThrowExceptionForHR(hr);
}
帧回调函数:
void OnFrameDone()
{
try
{
int w = Width;
int h = Height;
if (((w < 32) || (h < 32)))
{
return;
}
int stride = w * 3;
lock (this)
{
GCHandle handle = GCHandle.Alloc(savedArray, GCHandleType.Pinned);
int scan0 = (int)handle.AddrOfPinnedObject();
scan0 += (h - 1) * stride;
Bitmap b = new Bitmap(w, h, -stride, PixelFormat.Format24bppRgb, (IntPtr)scan0);
//switch (FrameDirection)
//{
// case VideoDir.Portrait:
// b.RotateFlip(RotateFlipType.Rotate90FlipNone);
// break;
// case VideoDir.Landscape:
// b.RotateFlip(RotateFlipType.Rotate180FlipNone);
// b.RotateFlip(RotateFlipType.Rotate180FlipNone);
// break;
//}
if(FrameCaptureComplete != null)
FrameCaptureComplete(b);
handle.Free();
}
}
catch (Exception ex)
{
string error = ex.Message;
}
return;
}
答案 0 :(得分:1)
除非相机以非标准方式进行,否则它应在其输出引脚上显示IAMStreamConfig
接口,您可以通过在SetFormat方法中提供感兴趣的媒体类型来选择格式。完成后,继续构建图形并将引脚连接到下游。
答案 1 :(得分:1)
在所有这些试验和错误中,我的研究得出结论,我的努力并非完全失败的尝试。 Microsoft MJPEG解压缩器的工作分辨率不高于3MP,我试图以500万像素运行图形。使用能够运行500万像素的第三方MJPEG压缩器解决了我遇到的所有问题。
谢谢罗曼的帮助。