Capabilities of Camera

Mar 27, 2012 at 11:31 AM

Hello,

I want to set DesiredPixelWidth, DesiredPixelHeight (and maybe FPS) programmatically to the best values supported by the camera. So I need a way to find out, what is supported by camera.

So far I figured out by debugging that SetVideoCaptureParameters knows the correct values of the camera but sets new values. I tried to duplicate this routine and modified it to retrieve the current values, but I am not able to call it before SetVideoCaptureParameters is called, because it's too complicated for me to setup a correct CaptureGraphBuilder2 object.

Can anybody give me some hints, how I can get these camera capabilities?

 

TIA

Michael

Jan 28, 2013 at 6:37 AM

I ended up doing this, but it would be much better, if there would be a method in WPF MediaKit:

 

		static public bool GetMaxVideoSize(DsDevice dsDevice, bool UseYuv, bool EnableSampleGrabbing, out int Width, out int Height, out int FPS)
		{
			if(dsDevice == _OldDsDevice)
			{
				Width = _OldWidth;
				Height = _OldHeight;
				FPS = _OldFPS;
				return true;
			}

			/* Clean up any messes left behind */
			Width = 320;
			Height = 240;
			FPS = 15;
			IGraphBuilder graph = null;
			IBaseFilter captureDevice = null;
			ICaptureGraphBuilder2 graphBuilder = null;
			bool bRet = false;

			try
			{
				/* Create a new graph */
				graph = (IGraphBuilder)new FilterGraphNoThread();

				/* Create a capture graph builder to help with rendering a capture graph */
				graphBuilder = (ICaptureGraphBuilder2)new CaptureGraphBuilder2();

				/* Set our filter graph to the capture graph */
				int hr = graphBuilder.SetFiltergraph(graph);
				DsError.ThrowExceptionForHR(hr);

				captureDevice = AddFilterByDevice(graph, dsDevice);

				/* If we have a null capture device, we have an issue */
				if(captureDevice != null)
				{
					if(UseYuv && !EnableSampleGrabbing)
					{
						bRet = GetMaxVideoSize(graphBuilder, captureDevice, MediaSubType.YUY2, out Width, out Height, out FPS);
					}
					else
						bRet = GetMaxVideoSize(graphBuilder, captureDevice, Guid.Empty, out Width, out Height, out FPS);
				}
				else
				{
					throw new Exception(string.Format("Capture device not found or could not be created"));
				}
			}
			catch(Exception /*ex*/)
			{
				/* Something got fuct up */
			}
			finally
			{
				if(captureDevice != null)
				{
					Marshal.ReleaseComObject(captureDevice);
				}
				if(graph != null)
				{
					Marshal.ReleaseComObject(graph);
				}
				if(graphBuilder != null)
				{
					Marshal.ReleaseComObject(graphBuilder);
				}
			}

			if(bRet)
			{
				_OldDsDevice = dsDevice;
				_OldWidth = Width;
				_OldHeight = Height;
				_OldFPS = FPS;
			}

			return bRet;
		}

		static private bool GetMaxVideoSize(ICaptureGraphBuilder2 capGraph, IBaseFilter captureFilter, Guid mediaSubType, out int Width, out int Height, out int FPS)
		{
			Width = 320;
			Height = 240;
			FPS = 15;

			bool bRet = false;

			/* The stream config interface */
			object streamConfig;

			/* Get the stream's configuration interface */
			int hr = capGraph.FindInterface(PinCategory.Capture,
											MediaType.Video,
											captureFilter,
											typeof(IAMStreamConfig).GUID,
											out streamConfig);

			DsError.ThrowExceptionForHR(hr);

			var videoStreamConfig = streamConfig as IAMStreamConfig;

			/* If QueryInterface fails... */
			if(videoStreamConfig == null)
			{
				//throw new Exception("Failed to get IAMStreamConfig");
				return bRet;
			}

			int iCount = 0, iSize = 0;
			videoStreamConfig.GetNumberOfCapabilities(out iCount, out iSize);

			IntPtr TaskMemPointer = Marshal.AllocCoTaskMem(iSize);


			AMMediaType pmtConfig = null;
			for(int iFormat = 0; iFormat < iCount; iFormat++)
			{
				IntPtr ptr = IntPtr.Zero;

				videoStreamConfig.GetStreamCaps(iFormat, out pmtConfig, TaskMemPointer);

				var videoInfo = (VideoInfoHeader)Marshal.PtrToStructure(pmtConfig.formatPtr, typeof(VideoInfoHeader));

				if(videoInfo.BmiHeader.Width > Width)
				{
					const long DSHOW_ONE_SECOND_UNIT = 10000000;
					Width = videoInfo.BmiHeader.Width;
					Height = videoInfo.BmiHeader.Height;
					FPS = (int)(DSHOW_ONE_SECOND_UNIT / videoInfo.AvgTimePerFrame);	// hab keine andere Moeglichkeit gefunden
					bRet = true;
				}

			}

			/* Free memory */
			Marshal.FreeCoTaskMem(TaskMemPointer);
			DsUtils.FreeAMMediaType(pmtConfig);

			return bRet;
		}

		private static IBaseFilter AddFilterByDevice(IGraphBuilder graphBuilder, DsDevice device)
		{
			if(graphBuilder == null)
				throw new ArgumentNullException("graphBuilder");

			var filterGraph = graphBuilder as IFilterGraph2;

			if(filterGraph == null)
				return null;

			IBaseFilter filter = null;
			if(device != null)
			{
				int hr = filterGraph.AddSourceFilterForMoniker(device.Mon, null, device.Name, out filter);
				DsError.ThrowExceptionForHR(hr);
			}
			return filter;
		}