Cat
Cat

Reputation: 3

Getting Camera Resolutions Using Accord.Video.DirectShow

I am evaluating the Accord.NET Framework (https://github.com/accord-net/framework/) for use in an imaging application. At the moment I have some basic requirements - capture video from a USB camera to display on the UI and view/change all camera properties.

Accord.Video.DirectShow.VideoCaptureDevice.DisplayPropertyPage works well for showing the camera properties, such as brightness, contrast, hue etc. but does not show available camera resolutions.

Accord.Video.DirectShow.VideoCaptureDevice.VideoCapabilities is returning only one resolution but I was expecting several more.

I have tried the VideoCapx (http://videocapx.com/) ActiveX control and using its ShowVideoFormatDlg method I can display a dialog which shows all available resolutions, framerates etc. I understand this is a dialog provided by the manufacturer and accessed via OLE\COM. What I am looking for is a way of accessing this via .NET, hopefully through the Accord framework.

I understand the additional resolutions might be properties of a transform filter however I am new to DirectShow and COM interfaces in .NET so I am looking for some pointers.

Upvotes: 0

Views: 1796

Answers (1)

Bafro
Bafro

Reputation: 87

I use to wrap DirectShow code for .NET. For sure with DirectShow it is possible to get, set ,and retrieve a/v source capabilities. Have You tried using IAMStreamConfig video interface to set output format on certain capture and compression filters?

I use this code to get resolutions and set it on different sources. where m_pVCap: source filter

hr = m_pBuilder->FindInterface(&PIN_CATEGORY_CAPTURE,&MEDIATYPE_Interleaved,
               m_pVCap, IID_IAMVideoCompression,(void **)&m_pVC);

    if (hr != S_OK)
        hr = m_pBuilder->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,
               m_pVCap,IID_IAMVideoCompression,(void **)&m_pVC);

    // !!! What if this interface isn't supported?
    // we use this interface to set the frame rate and get the capture size
    hr = m_pBuilder->FindInterface(&PIN_CATEGORY_CAPTURE,&MEDIATYPE_Interleaved,
               m_pVCap, IID_IAMStreamConfig, (void **)&m_pVSC);
    if (hr != NOERROR) 
    {
        hr = m_pBuilder->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, 
          m_pVCap, IID_IAMStreamConfig,(void **)&m_pVSC);
        if (hr != NOERROR) 
        {
            LogDXError(hr, false, FILELINE);
        }
     }

To get current source format

hr = m_pVSC->GetFormat(&pmt);
    // DV capture does not use a VIDEOINFOHEADER
    if (hr == NOERROR) 
    {
        if (pmt->formattype == FORMAT_VideoInfo) 
        {   
            VIDEOINFOHEADER *pvi = (VIDEOINFOHEADER *)pmt->pbFormat;

            pvi->AvgTimePerFrame = (LONGLONG)(10000000 / m_FrameRate);

            hr = m_pVSC->SetFormat(pmt);

            if (hr != NOERROR)
                (NotifyNewError) (FILELINE, "", LOG_ALL, ERR_GRAVE, false,
                    "Cannot set frame rate for capture");

            hr = m_pVSC->GetFormat(&pmt);
            pvi = (VIDEOINFOHEADER *)pmt->pbFormat;

            pvi->bmiHeader.biWidth = g_SizeOutput.cx;
            pvi->bmiHeader.biHeight = g_SizeOutput.cy;
            pvi->bmiHeader.biSizeImage = DIBSIZE(pvi->bmiHeader);

            hr = m_pVSC->SetFormat(pmt);
            if (hr != NOERROR)
            {
                char ErrTxt[MAX_ERROR_TEXT_LEN];                           
                AMGetErrorText(hr, ErrTxt,MAX_ERROR_TEXT_LEN);
                wsprintf(szError, "Error %x: %s\nCannot set frame rate (%d)for 
                   prev", hr, ErrTxt,m_FrameRate);
                (NotifyNewError)(FILELINE, "", LOG_ALL, ERR_GRAVE, false, szError);                 
             }

             DeleteMediaType(pmt);
        }

To get sources capabilities you can use:

IAMStreamConfig::GetNumberOfCapabilities and then IAMStreamConfig::GetStreamCaps

Upvotes: 2

Related Questions