VFW off



  • Hi,

    seit 1992 hat sich das VFW (VideoForWindows) als einfache und immer funktionierende Schnittstelle insbesondere für USB-Cams erwiesen.

    Unter Windows 10 liefern alle Programme die das verwenden einen schwarzes Bild.

    Über DirectShow mit dem Interface IVMRWindowlessControl9 ist jedoch eine Kamera -Ansprechung möglich, obschon sich das Interface bereits auch
    auf der Kippe befindet, jedoch funktioniert das Interface unter XP
    sowie unter W10.

    Im gange ist ein weiteres Interface mit abstruser Com Hierarchie, niemand möchte damit etwas zu tun haben, es ist ja eine Zumutung genannt :
    MFP -CreateMediaPlayer usw. Dies funktiniert jedoch nicht unter XP oder
    Vista und ist scheinbar teil des Mediaplayers.

    Also bleibt im Moment nur das DirectShow Interface, hier das Problem:

    Man kann einen Property Dialog für jede Schnittstelle abfragen, wenn es einen gibt kann dieser zb. für die Standard Optionen hervorgebracht werden:

    Pseudo:

    CAUUID caGUID;
    	IUnknown *pFilterUnk;
    	ISpecifyPropertyPages *pProp;
    	HRESULT hr = m_pDF->QueryInterface(IID_ISpecifyPropertyPages, (void **)&pProp);
    	if (FAILED(hr))
    		return;
    
    	FILTER_INFO FilterInfo;
    	hr = m_pDF->QueryFilterInfo(&FilterInfo);
    	if (SUCCEEDED(hr))
    	{
    		hr = m_pDF->QueryInterface(IID_IUnknown, (void **)&pFilterUnk);
    		if (SUCCEEDED(hr))
    		{
    			pProp->GetPages(&caGUID);
    			pProp->Release();
    
    			OleCreatePropertyFrame(
    				0,                      // Parent window
    				0, 0,                   // Reserved
    				FilterInfo.achName,     // Caption for the dialog box
    				1,                      // Number of objects (just the filter)
    				&pFilterUnk,            // Array of object pointers. 
    				caGUID.cElems,          // Number of property pages
    				caGUID.pElems,          // Array of property page CLSIDs
    				0,                      // Locale identifier
    				0, NULL                 // Reserved
    				);
    
    			// Clean up.
    			pFilterUnk->Release();
    			FilterInfo.pGraph->Release();
    			CoTaskMemFree(caGUID.pElems);
    		}
    	}
    

    Das funktioniert, m_pDF ist ein smartpointer auf IID_IGraphBuilder.

    Will man nun aber die Auflösung verändern, muss man über IID_IAMStreamConfig die Propertyfähigkeit erlangen, dieser wird über den aktiven IPin ausgelöst.

    Außerdem muss das Capturing Run() angehalten werden um Einstellungen an der Auflösung zu verändern.

    Das war schon unter VFW zur Laufzeit möglich, ein Rückschritt. Außerdem erreicht das Interface nicht die Bildrate die mit VFW möglich war.

    Jedenfalls kann man den Dialog für die Kameraauflösungen wie folgt hervorbringen:

    Pseudo:

    Stop();
    
    	CAUUID caGUID;
    	IUnknown *pFilterUnk;
    	ISpecifyPropertyPages *pProp;
    	IAMStreamConfig *pConfig;
    
    	FILTER_INFO FilterInfo;
    	HRESULT hr = m_pDF->QueryFilterInfo(&FilterInfo);
    	if (SUCCEEDED(hr))
    	{
    		hr = m_pCamOutPin->QueryInterface(IID_IAMStreamConfig, (void **)&pConfig);
    		if (SUCCEEDED(hr))
    		{
    			hr = pConfig->QueryInterface(IID_ISpecifyPropertyPages, (void **)&pProp);
    			if (SUCCEEDED(hr))
    			{
    				hr = pProp->QueryInterface(IID_IUnknown, (void **)&pFilterUnk);
    				if (SUCCEEDED(hr))
    				{
    					hr = pProp->GetPages(&caGUID);
    					pProp->Release();
    
    					if (SUCCEEDED(hr))
    					{
    						OleCreatePropertyFrame(
    							0,                      // Parent window
    							0, 0,                   // Reserved
    							FilterInfo.achName,     // Caption for the dialog box
    							1,                      // Number of objects (just the filter)
    							(IUnknown **)&pFilterUnk,            // Array of object pointers. 
    							caGUID.cElems,          // Number of property pages
    							caGUID.pElems,          // Array of property page CLSIDs
    							0,                      // Locale identifier
    							0, NULL                 // Reserved
    							);
    
    						CoTaskMemFree(caGUID.pElems);
    						pFilterUnk->Release();
    						pConfig->Release();
    						FilterInfo.pGraph->Release();
    
    						GetCamFormat();//actualize DIB Section to new Format
    					}
    				}
    			}
    		}
    	}
    
    	Start();
    

    Das funktioniert einmal wunderbar auch ggf. mehrmals, aber zumeist liefert
    der zweite oder dritte Versuch die Auflösung zu verändern im eröffneten
    DX-Dialog die Fehlermeldung: mit einer MessageBox:

    "Error Connecting" "This Format is currently not available"

    Alle Resourcen wurden via Release ja wieder zurückgegeben, hat jemand Hinweise
    welches Scenario funktioniert ?

    Danke
    Gruß Karsten



  • Bevor der exotische Format-Dialog aufgerufen wird, muss nebst Stop
    auch die Verbindung zum Capture Interface getrennt werden:

    m_pGB->Disconnect(m_pCamOutPin);

    Nun kann in dem Dialog fröhlich zwischen den Formaten gewechselt werden.

    Schlussendlich muss der ganze Sülz wieder aufgeschaltet werden.
    (Wer sich die Scheiße ausgedacht hat, wird noch schlimmeres hervorbringen)

    Wieder aufschalten der getrennten Filter:

    HRESULT CVidDS::Initialize(HWND hWnd)
    {
    	IBaseFilter* pVmr = NULL;
    
    	// Create the VMR and add it to the filter graph.
    	HRESULT hr = CoCreateInstance(CLSID_VideoMixingRenderer, NULL,CLSCTX_INPROC, IID_IBaseFilter, (void**)&pVmr);
    
    	if (SUCCEEDED(hr))
    	{
    		hr = m_pGB->AddFilter(pVmr, L"Video Mixing Renderer");
    		if (SUCCEEDED(hr))
    		{
    			// Set the rendering mode and number of streams.  
    			IVMRFilterConfig* pConfig;
    
    			hr = pVmr->QueryInterface(IID_IVMRFilterConfig, (void**)&pConfig);
    			if (SUCCEEDED(hr))
    			{
    				pConfig->SetRenderingMode(VMRMode_Windowless);
    				pConfig->Release();
    			}
    
    			hr = pVmr->QueryInterface(IID_IVMRWindowlessControl, (void**)&m_pWC);
    			if (SUCCEEDED(hr))
    			{
    				m_pWC->SetVideoClippingWindow(hWnd);
    
    			}
    		}
    		pVmr->Release();
    	}
    
    	return hr;
    }
    

    Lieber würde ich das Zeug mit hexwerten Poken als diesen
    abstrakten Irrweg zu beleuchten.

    Grüße und Erfolg
    K.



  • Natürlich kann man statt dem Property-Dialog der Camera die Einstellungen
    (Capabilities) auch selbst enummerieren und in einem eigenen Dialog anzeigen.
    Das sollte auch ohne den Stream anzuhalten gehen ...

    Mit einiger Sicherheit wurde auch bei VFW die Verbindung kurz unterbrochen.

    Du verwendest den "alten" Video Mixing Renderer extra ? Es gibt neuere Version
    (WMR9 ..) mit mehr Funktionalität.

    Ich stimme allerdings zu, das die lange Liste COM-Aufrufe keine besonders entwicklerfreundliche Idee ist.

    Schlimmer finde ich auch, das ständig neue Konzepte rauskommen, die dann
    aber immer nur mit dem neuesten Windows laufen. Wenn man kein .NET will wird
    es zunehmend schwerer ...



  • Hi,

    auch selbst enummerieren und in einem eigenen Dialog anzeigen.
    Naja jedes neue Detail macht Aufwand und Arbeit, man möchte natürlich
    konformes, bestehendes nutzen.

    Mit einiger Sicherheit wurde auch bei VFW die Verbindung kurz unterbrochen.
    Na eigentlich nicht, betrifft auch nur die Auflösung, man muss halt für diesen
    Dialog die Verbindung trennen, damit der Dialog eine eigene herstellen kann.

    Du verwendest den "alten" Video Mixing Renderer extra
    Ja alt ist immer gut, und auf XP läuft das auch noch. WindowsXP wird noch für
    viele Jahre im z.B. Maschinenbau wirken.

    Ich stimme allerdings zu, das die lange Liste COM-Aufrufe keine besonders >>entwicklerfreundliche Idee ist.
    Das ist ein Krampf, auch das erstellen von Com Objekten, ist eine Fussellei.
    Ich habe noch keinen gesehen der das Konzept gerne verwendet.

    Schlimmer finde ich auch, das ständig neue Konzepte rauskommen, die dann
    aber immer nur mit dem neuesten Windows laufen. Wenn man kein .NET will wird
    es zunehmend schwerer ...
    Also als c/asm Entwickler hatte man immer die Fußarbeit, aber man erstellt auch Kernfunktionen, Elemente die mit anderen Sprachmitteln nie möglich sein werden. Und auch früher gab es bereits Basic Programmierer 🙂

    Grüße und Erfolg
    K.



  • Achromat schrieb:

    Du verwendest den "alten" Video Mixing Renderer extra
    Ja alt ist immer gut, und auf XP läuft das auch noch. WindowsXP wird noch für
    viele Jahre im z.B. Maschinenbau wirken.

    CLSID_VideoMixingRenderer ist der VMR7. Auf XP läuft auch der VMR9 wunderbar.

    Achromat schrieb:

    Das ist ein Krampf, auch das erstellen von Com Objekten, ist eine Fussellei.
    Ich habe noch keinen gesehen der das Konzept gerne verwendet.

    Gerne verwenden ist sicher übertrieben. Man kann sich aber halbwegs gut damit arrangieren. Wenn man gewillt ist etwas Hirnschmalz zu investieren um Code-Duplication zu vermeiden fallen dabei automatisch diverse Hilfsklassen/-templates/-funktionen raus.
    Dann kann man halbwegs angenehm mit DirectShow arbeiten - zumindest was das etwas fummelige COM-Drumherum angeht.
    Was sicherlich schade ist, ist dass MS keine fertigen, einfach zu verwendenden C++ Wrapper für die ganzen COM Sachen anbietet. Bzw. es auch kaum Community-Projekte dafür gibt. Für C# gibt es da überraschenderweise viel mehr -- obwohl der Umgang mit bestimmten Aspekten von COM Komponenten in C# auch nicht gerade einfach ist.



  • hustbaer schrieb:

    Achromat schrieb:

    Du verwendest den "alten" Video Mixing Renderer extra
    Ja alt ist immer gut, und auf XP läuft das auch noch. WindowsXP wird noch für
    viele Jahre im z.B. Maschinenbau wirken.

    CLSID_VideoMixingRenderer ist der VMR7. Auf XP läuft auch der VMR9 wunderbar.

    So ist es. Allerdings ist der Programmieraufwand etwas höher, da VMR9 nicht
    automatisch verwendet wird.



  • hustbaer schrieb:

    Was sicherlich schade ist, ist dass MS keine fertigen, einfach zu verwendenden C++ Wrapper für die ganzen COM Sachen anbietet. Bzw. es auch kaum Community-Projekte dafür gibt. Für C# gibt es da überraschenderweise viel mehr -- obwohl der Umgang mit bestimmten Aspekten von COM Komponenten in C# auch nicht gerade einfach ist.

    Wieso obwohl ?

    1. Ist M$ sehr daran interessiert .NET zu pushen
    2. Gerade weil es der (einfache) C# Programmierer nie hinbekommen
    würde muss es geliefert werden.



  • Hmja, OK.

    Es gibt da Kräfte die stärker in Richtung "Wrapper wird umgesetzt" drücken, je schwieriger der Umgang mit der ungewrappten API ist. z.B. weil ein Wrapper umso nützlicher wird je schwieriger die original API ist, und man umso leichter Leute findet die etwas umsetzen je nützlicher es ist.

    Es gibt allerdings auch Kräfte die stärker in Richtung "Wrapper wird nicht umgesetzt" drücken, je schwieriger der Umgang mit der ungewrappten API ist. z.B. dass es umso schwieriger wird Leute zu finden die etwas umsetzen je schwieriger es umzusetzen ist 😉

    Die erste Kraft, und dass die vielleicht sogar stärker ist als die zweite, habe ich erst nicht wirklich bedacht. Daher "obwohl".


Anmelden zum Antworten