4

By using Directshow.NET and c# I have developed an application which shows camera preview. Everything is working fine since 1 year but suddenly client complaint about black camera preview.

After some digging to issue I come to know that anti-virus program is blocking camera usages by my application. After adding my application in exclusion list of that anti-virus program makes application to work as like before.

In program I have properly thrown exception for HRESULT like below:

try
{
    //FilterGraph creation
    //CaptureGraphBuilder2 creation
    //AddSourceFilterForMoniker()
    //SampleGrabber configuration
    //VMR9 configuration

    hr = mediaControl.Run();
    DsError.ThrowExceptionForHR(hr);
}
catch(Exception ex)
{
    //logging part
}

Still there is nothing in log, even I debug that application on that particular machine but program executes successfully. So the question is, To avoid such issues how can I make sure that camera preview is actually started? Is there any way to check that stream is not blocked.

Amogh
  • 4,220
  • 9
  • 36
  • 91

3 Answers3

2

Black camera preview is not necessarily a symptom of a failure to run the graph. For example, whether this is your problem exactly or not, a filter graph esp. displaying IP camera feed might be put into running state and the video renderer would expect a frame to be received and processed respectively to the state it's display ready. However if an antivirus or a firewall blocks traffic, the video frame never reaches the renderer. The filter graph is running though and there is no failure or error.

You normally want to request some statistics from filters in your filter graph, that prove there is payload processing happening. This might include:

  • a query from source filter that it actually produces data
  • an intermediate component such as decoder capable to provide stats of processed data
  • a Sample Grabber filter in the pipeline with a callback counting samples without modification
  • a request of statistics from video renderer (such as e.g. IQualProp::get_FramesDrawn "...retrieves the number of frames actually drawn since streaming started")
  • an attempt to read back a snapshot of currently displayed video frame from video renderer

Once you see the data is being processed as the time goes, you know there is no unexpected locking happens.

Roman R.
  • 64,446
  • 5
  • 83
  • 139
  • 1
    Okay, but by this I will only able to identify whether frame is coming to renderer or not, am I correct? if yes then while digging into issue I installed VLC on machine and tried to get camera preview (Media->open capture device->capture mode 'DirectShow'), VLC is successful to show preview. But VLC is not added into exclusion list of anti-virus though it's showing preview by using DirectShow is there something to do with application to tell anti-virus to allow the use of camera or is it like VLC uses some other way? – Amogh Aug 30 '17 at 17:52
  • 1
    It is highly unlikely that antivirus bans DirectShow API. It bans certain network traffic, or specific DLLs which are being quarantined. This makes the situation importantly different for your application and for VLC. – Roman R. Aug 30 '17 at 18:11
  • I know it's long time after this answer..I have checked `IMediaEventEx.GetEvent()` I am getting `ErrorAbort` from `IEventCode`. Is this enough to detect such issues? – Amogh Sep 30 '17 at 08:43
  • `ErrorAbort` is coming from one of the filters, it encountered an error and notified the graph, the graph in turn stopped and this indeed might result in blackness. You are to identify what is causing the `ErrorAbort` – Roman R. Sep 30 '17 at 09:39
  • _a Sample Grabber filter in the pipeline with a callback counting samples without modification._ I have checked `BufferCB()`, when its blocked bufferCB didn't get called. Currently I will go by checking `IEventCode.ErrorAbort` – Amogh Oct 04 '17 at 15:50
  • Many samples around suggest using `BufferCB`, however I would suggest to use `SampleCB` whenever possible and `BufferCB` instead only for serious reasons. `SampleCB` sample counting would be accurate. – Roman R. Oct 04 '17 at 15:58
0

You can subscribe the event MediaElementBase.NewAllocatorFrame, and you can know whether the camera source filter is working.

xiaox2y2
  • 55
  • 6
0

I suggest You to Adds a DirectShow filter graph to the Running Object Table, allowing GraphEdit to "spy" on a remote filter graph. This can help to check graph connections, filter state, pin properties and correct or optimize it in order resolve issues.

After building and/or starting capture graph just call this method in order to se graph and filter state via Graphedit application.

///
/// \fn AddGraphToRot(IUnknown *pUnkGraph, DWORD *pdwRegister)
/// 
HRESULT CCapture::AddGraphToRot(IUnknown *pUnkGraph, DWORD *pdwRegister)
{
    IMoniker * pMoniker;
    IRunningObjectTable *pROT;
    WCHAR wsz[128];
    HRESULT hr;
    ULONG ret = 0;

    if (FAILED(GetRunningObjectTable(0, &pROT)))
        return E_FAIL;

    wsprintfW(wsz, L"FilterGraph %08x pid %08x", (DWORD_PTR)pUnkGraph,
        GetCurrentProcessId());

    hr = CreateItemMoniker(L"!", wsz, &pMoniker);
    if (SUCCEEDED(hr)) {
        hr = pROT->Register(0, pUnkGraph, pMoniker, pdwRegister);
        ret = pMoniker->Release();
    }   
    pROT->Release();
    return hr;
}

GraphEdit is available in the Microsoft Windows Software Development Kit (SDK) (http://go.microsoft.com/fwlink/p/?linkid=62332).

Bafro
  • 77
  • 5