I brought the web camera to the screen, via put_Owner ((OAHWND) HWND), how can I catch it when Windows starts to redraw the frame? My code 1 Initialized the control graphs, etc.

HRESULT hr(0); hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IFilterGraph2, (void**)&graph); if (hr < 0) return -1; hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, (void**)&capture); if (hr < 0) return -1; hr = graph->QueryInterface(IID_IMediaControl, (void**)&control); if (hr < 0) return -1; hr = graph->QueryInterface(IID_IVideoWindow, (void **)&pVidWin); if (hr < 0) return -1; 

Next stuck filter

 HRESULT hr(0); VARIANT name; LONGLONG start = MAXLONGLONG, stop = MAXLONGLONG; unsigned long dev_count(0); ICreateDevEnum* dev_enum(nullptr); IEnumMoniker* enum_moniker(nullptr); IMoniker* moniker(nullptr); IPropertyBag* pbag(nullptr); hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void**)&dev_enum); if (hr < 0) return -1; if (hr < 0) return -1; hr = dev_enum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &enum_moniker, NULL); if (hr < 0) return -1; num_devices = 0; if (enum_moniker != nullptr) enum_moniker->Next(MAX_DEVICES, &moniker, &dev_count); for (unsigned int i = 0; i < dev_count; i++) { hr = moniker[i].BindToStorage(0, 0, IID_IPropertyBag, (void**)&pbag); if (hr >= 0) { VariantInit(&name); hr = pbag->Read(L"Description", &name, 0); if (hr < 0) hr = pbag->Read(L"FriendlyName", &name, 0); if (hr >= 0) { VideoDevice* dev = devices + num_devices++; BSTR ptr = name.bstrVal; for (int c = 0; *ptr; c++, ptr++) { dev->filtername[c] = *ptr; dev->friendlyname[c] = *ptr & 0xFF; } hr = graph->AddSourceFilterForMoniker(moniker + i, 0, dev->filtername, &dev->filter); if (hr != S_OK) num_devices--; } VariantClear(&name); hr = pbag->Release(); if (hr < 0) return -1; } hr = moniker[i].Release(); if (hr < 0) return -1; } return 0; 

And the rendering itself

 HRESULT hr(0); LONGLONG start = MAXLONGLONG, stop = MAXLONGLONG; bool was_playing = playing; if (!dev->filter) return -1; if (playing) Stop(); if (current) { hr = graph->RemoveFilter(current->filter); hr = graph->RemoveFilter(samplegrabberfilter); hr = graph->RemoveFilter(compressor); hr = graph->AddFilter(samplegrabberfilter, L"Sample Grabber"); hr = graph->AddFilter(current->filter, current->filtername); hr = graph->AddFilter(compressor, L"compressor"); } start = 0; current = dev; #ifdef SHOW_DEBUG_RENDERER hr = capture->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, current->filter, compressor, 0); if (hr < 0) return -1; if (hr != S_OK) { SetSampleGrabber(); hr = capture->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, current->filter, 0, samplegrabberfilter); } hr = pVidWin->put_Owner((OAHWND)hWndWin_); hr = pVidWin->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS); hr = pVidWin->put_Left(RplaceVideo.left); hr = pVidWin->put_Top(RplaceVideo.top); hr = pVidWin->put_Width(RplaceVideo.right - RplaceVideo.left); hr = pVidWin->put_Height(RplaceVideo.bottom - RplaceVideo.top); #else hr = capture->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, current->filter, samplegrabberfilter, nullrenderer); #endif hr = capture->ControlStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, current->filter, &start, &stop, 1, 2); if (hr < 0) return -1; if (was_playing) Start(); return 0; hr = control->Run(); 

The translation of the picture from the web camera to the dialog box began.

  • If on wiapi then probably WM_PAINT ? - NewView 3:54 pm
  • @NewView K, WM_PAINT regret will be called only at the beginning, on the first frame, no further, I need to update other components simultaneously with the direct show, but then I have to know when direct updates the frame - nikki
  • one
    For the sake of curiosity, show the code how it works for you .. There are still a lot of events, see the spy program for what happens to the events in your particular window, and catch them in the future. If there is a lot of code, throw on any git or something like that. Spyware Pro: docs.microsoft.com/en-us/visualstudio/debugger/… - NewView am
  • @NewView I changed my question by adding code, most importantly by direct, tried to catch events with the IMediaEventEx class, but without success - nikki
  • one
    @NewView Messages analyze meaningless, since DirectShow does not use them for graphics rendering (maximum, for notification of the completion of playback). Since DirectShow uses DirectX for rendering, image redrawing is very common and the number of generated messages would be too large. Updating something in sync with DirectX looks like a pretty bad idea, purely for performance reasons. Most likely, the answer is "Write your own filter renderer." - MSDN.WhiteKnight

0