12

if I have more than one camera attached to my PC ... I want to know the best available resolutions for a specific camera ...

for example some cameras are HD or FullHD (1,280×720 pixels (720p) or 1,920×1,080 pixels (1080i/1080p)) or the most common are web cameras....

I want to know at least the best video mode that the camera work properly...(the mode that the camera made to work with)

my work is on WPF using C# (I am using Directshow)

thanks in advance

Amer Sawan
  • 2,126
  • 1
  • 22
  • 40

3 Answers3

13

This is a code that I wrote, its working perfectly for me

public static List<Point> GetAllAvailableResolution(DsDevice vidDev)
{
    try
    {
        int hr;
        int max = 0;
        int bitCount = 0;
        IBaseFilter sourceFilter = null;
        var m_FilterGraph2 = new FilterGraph() as IFilterGraph2;
        hr = m_FilterGraph2.AddSourceFilterForMoniker(vidDev.Mon, null, vidDev.Name, out sourceFilter);
        var pRaw2 = DsFindPin.ByCategory(sourceFilter, PinCategory.Capture, 0);
        var AvailableResolutions = new List<Point>();
        VideoInfoHeader v = new VideoInfoHeader();
        IEnumMediaTypes mediaTypeEnum;
        hr = pRaw2.EnumMediaTypes(out mediaTypeEnum);
        AMMediaType[] mediaTypes = new AMMediaType[1];
        IntPtr fetched = IntPtr.Zero;
        hr = mediaTypeEnum.Next(1, mediaTypes, fetched);

        while (fetched != null && mediaTypes[0] != null)
        {
            Marshal.PtrToStructure(mediaTypes[0].formatPtr, v);
            if (v.BmiHeader.Size != 0 && v.BmiHeader.BitCount != 0)
            {
                if (v.BmiHeader.BitCount > bitCount)
                {
                    AvailableResolutions.Clear();
                    max = 0;
                    bitCount = v.BmiHeader.BitCount;
                }
                AvailableResolutions.Add(new Point(v.BmiHeader.Width, v.BmiHeader.Height));
                if (v.BmiHeader.Width > max || v.BmiHeader.Height > max)
                    max = (Math.Max(v.BmiHeader.Width, v.BmiHeader.Height));
            }
            hr = mediaTypeEnum.Next(1, mediaTypes, fetched);
        }
        return AvailableResolutions;
    }

    catch (Exception ex)
    {
        Log(ex);
        return new List<Point>();
    }
}

(E.g. this can be added to VideoCaptureElement in WPF-MediaKit)

oo_dev
  • 777
  • 7
  • 20
Amer Sawan
  • 2,126
  • 1
  • 22
  • 40
9

i use this to get max frame size, just change to suit your needs ;)

private Point GetMaxFrameSize(IPin pStill)
    {
        VideoInfoHeader v;

        IAMStreamConfig videoStreamConfig = pStill as IAMStreamConfig;

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

        IntPtr TaskMemPointer = Marshal.AllocCoTaskMem(iSize);

        int iMaxHeight = 0;
        int iMaxWidth = 0;

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

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

            v = (VideoInfoHeader)Marshal.PtrToStructure(pmtConfig.formatPtr, typeof(VideoInfoHeader));
            if (v.BmiHeader.Width > iMaxWidth)
            {
                iMaxWidth = v.BmiHeader.Width;
                iMaxHeight = v.BmiHeader.Height;
            }
            DsUtils.FreeAMMediaType(pmtConfig);

        }

        Marshal.FreeCoTaskMem(TaskMemPointer);


        return new Point(iMaxWidth, iMaxHeight);
    }


    /// <summary>
    ///  Free the nested structures and release any
    ///  COM objects within an AMMediaType struct.
    /// </summary>
    public static void FreeAMMediaType(AMMediaType mediaType)
    {
        if (mediaType != null)
        {
            if (mediaType.formatSize != 0)
            {
                Marshal.FreeCoTaskMem(mediaType.formatPtr);
                mediaType.formatSize = 0;
                mediaType.formatPtr = IntPtr.Zero;
            }
            if (mediaType.unkPtr != IntPtr.Zero)
            {
                Marshal.Release(mediaType.unkPtr);
                mediaType.unkPtr = IntPtr.Zero;
            }
        }
    }
dmeglio
  • 2,830
  • 1
  • 19
  • 24
devHead
  • 794
  • 1
  • 15
  • 38
  • I couldn't find the content of DsUtils.FreeAMMediaType(...). can you guide me ? – itsho Sep 08 '12 at 20:27
  • Are you using the 2010 build? – devHead Sep 09 '12 at 14:07
  • I guess the first validation is that you do no have the DsUtils class ;) The best thing to do is just get the current build… http://directshownet.sourceforge.net/ – devHead Sep 11 '12 at 13:17
  • the older wrapper has the utilities in a different class... i cant quite remember what it was... a very old build though... if you are using the old build you will have a few changes to make setting up your graph. if you have questions feel free to ask me. – devHead Sep 11 '12 at 13:19
  • i added the FreeAMMediaType sub above (right out of the new version)...so if you are using the older wrapper you can easily add this block... (not sure if the AMMediaType structure is the same in the older version) – devHead Sep 11 '12 at 13:41
  • Old question, but, shouldn't the DsUtils.FreeAMMediaType() be in the for loop so it frees each one, not just the last? – dmeglio Jun 19 '15 at 15:43
2

According to this webpage: http://www.e-consystems.com/blog/camera/?p=651, you should use this call for getting the capabilities of this device:

g_DShowCaptureGraph.GetNumberOfCapabilities(nStream, &iCount, &iSize);
g_DShowCaptureGraph.GetStreamCaps(nStream,iFormat, &pmtConfig, (BYTE*)&scc);

They are C++, however.

Mattias Cibien
  • 296
  • 2
  • 16