Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi WindowHandle vom Aktiven Renderer (https://www.delphipraxis.net/197875-windowhandle-vom-aktiven-renderer.html)

EWeiss 13. Sep 2018 14:27

WindowHandle vom Aktiven Renderer
 
Ich mache folgendes..

Delphi-Quellcode:
function TEVMRPlayer.GetWindowHandle: HWND;
var
  pPin: IPIN;
  VideoRenderer: IBaseFilter;
  Overlay: IOverlay;
  HR: HRESULT;
begin

  Result := 0;

  GraphBuilder.FindFilterByName(PWideChar(FVideoRenderer.VMRFilter), VideoRenderer);
  if Assigned(VideoRenderer) then
  begin
    HR := VideoRenderer.FindPin(nil, pPin);

    if (SUCCEEDED(HR)) then
    begin
      pPin.QueryInterface(IID_IOverlay, Overlay);
      Overlay.GetWindowHandle(Result);
    end;
  end;
end;
FVideoRenderer.FilterName ist in dem Fall "madVR"
VideoRenderer liefert einen Zeiger ist also nicht Nil.

aber trotzdem kracht es hier
Delphi-Quellcode:
VideoRenderer.FindPin(nil, pPin);


verstehe nicht warum.. jemand eine Idee?

gruss

KodeZwerg 13. Sep 2018 14:36

AW: WindowHandle vom Aktiven Renderer
 
https://stackoverflow.com/questions/...he-id-returned

Ich hoffe das hilft Dir.

EWeiss 13. Sep 2018 14:50

AW: WindowHandle vom Aktiven Renderer
 
Zitat:

Zitat von KodeZwerg (Beitrag 1413127)

Leider nicht.
Andere Version.. das gleiche.

Delphi-Quellcode:
function TEVMRPlayer.GetWindowHandle: HWND;
var
  pPin: IPin;
  VideoRenderer: IBaseFilter;
  Overlay: IOverlay;
  HR: HRESULT;
begin

  Result := 0;
  pPin := nil;

//  GraphBuilder.FindFilterByName(PWideChar(FVideoRenderer.VMRFilter), VideoRenderer);
//  if Assigned(VideoRenderer) then
//  begin
    HR := FVideoRenderer.VMRFilter.FindPin(nil, pPin);

    if (SUCCEEDED(HR)) then
    begin
      pPin.QueryInterface(IID_IOverlay, Overlay);
      Overlay.GetWindowHandle(Result);
    end;
//  end;
end;
HR Fails bei EVRBaseFilter.. und kracht bei madVRFilter
Der sinn des ganzen ich benötige das WindowHandle des aktiven Rendere um ein Window drüberzulegen ohne jetzt extra ein zusätzliches Overlay zu generieren.

ERROR = "Ein Object oder Name wurde nicht gefunden."
madVRFilter ist valid.. Welches Object oder Name sollte dann da nicht gefunden werden?

gruss

EWeiss 14. Sep 2018 06:20

AW: WindowHandle vom Aktiven Renderer
 
Hat sich erledigt.
Ein einfaches WindowFromPoint tut's auch.
Wollte es wieder mal zu professional machen.. na was soll's

Trotzdem seltsam das es nicht funktioniert hat.

gruss

TiGü 14. Sep 2018 08:38

AW: WindowHandle vom Aktiven Renderer
 
Zitat:

Zitat von EWeiss (Beitrag 1413123)
aber trotzdem kracht es hier
Delphi-Quellcode:
VideoRenderer.FindPin(nil, pPin);
verstehe nicht warum.. jemand eine Idee?

Auch wenn für dich das Thema schon abgeschlossen ist, hier noch die Erklärung:
Die offizielle Dokumention sagt, dass der erste Parameter einen String(-Zeiger) enthalten muss, der den Pin identifiziert (https://docs.microsoft.com/en-us/win...filter-findpin).
Wenn du da jetzt nil übergibst, versucht die implementierende Methode FindPin auf den Speicherbereich zuzugreifen -> es kracht!

Im von Zwerg verlinkten SO-Beitrag ist ein Beispiel für das Enummerieren der Pins der übergebenen IBaseFilter-Instanz.
Baue dir einen ähnlichen Code mit ein und lasse dir per OutputDebugString ausgeben, wie die korrekten Namen sind.

EWeiss 14. Sep 2018 08:58

AW: WindowHandle vom Aktiven Renderer
 
Zitat:

Baue dir einen ähnlichen Code mit ein und lasse dir per OutputDebugString ausgeben, wie die korrekten Namen sind.
Habe ich versucht und bekomme auch den Pin.
Nur es kracht trotzdem ;)

Delphi-Quellcode:
function FindConnectedPin(pFilter: IBaseFilter; PinDir: PIN_DIRECTION; var ppPin: IPin): HRESULT;
var
  pEnum: IEnumPins;
  pPin: IPin;
  hr: HRESULT;
  bFound: BOOL;
  bIsConnected: BOOL;

begin
  ppPin := nil;

  pEnum := nil;
  pPin := nil;

  hr := pFilter.EnumPins(pEnum);
  if (FAILED(hr)) then
  begin
    result := hr;
    exit;
  end;

  bFound := FALSE;
  while (pEnum.Next(1, pPin, nil) = S_OK) do
  begin
    hr := IsPinConnected(pPin, bIsConnected);
    if (SUCCEEDED(hr)) then
    begin
      if (bIsConnected) then
        hr := IsPinDirection(pPin, PinDir, bFound);
    end;

    if (FAILED(hr)) then
    begin
      pPin := nil;
      break;
    end;
    if (bFound) then
    begin
      ppPin := pPin;
      break;
    end;

    pPin := nil;
  end;

  pEnum := nil;

  if (not bFound) then
    hr := VFW_E_NOT_FOUND;

  result := hr;
end;
Delphi-Quellcode:
FindConnectedPin(FVideoRenderer.VMRFilter, PINDIR_INPUT, pPin);


Delphi-Quellcode:
pPin.QueryInterface(IID_IOverlay, Overlay);

Overlay ist Nil trotz gefundenen Pin und dann kracht es natürlich. (wenn nicht abgesichert)

gruss

TiGü 14. Sep 2018 09:19

AW: WindowHandle vom Aktiven Renderer
 
Zitat:

Zitat von EWeiss (Beitrag 1413173)
Delphi-Quellcode:
pPin.QueryInterface(IID_IOverlay, Overlay);

Overlay ist Nil trotz gefundenen Pin und dann kracht es natürlich. (wenn nicht abgesichert)

Aufgrund welcher Quelle gehst du davon aus, dass die Instanz des Pins das IOverlay-Interface implementiert?

EWeiss 14. Sep 2018 09:35

AW: WindowHandle vom Aktiven Renderer
 
Zitat:

Zitat von TiGü (Beitrag 1413174)
Zitat:

Zitat von EWeiss (Beitrag 1413173)
Delphi-Quellcode:
pPin.QueryInterface(IID_IOverlay, Overlay);

Overlay ist Nil trotz gefundenen Pin und dann kracht es natürlich. (wenn nicht abgesichert)

Aufgrund welcher Quelle gehst du davon aus, dass die Instanz des Pins das IOverlay-Interface implementiert?

Davon das ich weis das MadVr es tut.
Sonst könnte ich ja kein Overlay in Fenster anzeigen oder liege ich da falsch?
Notfalls könnte ich das Overlay Interface bei der Initialisierung von Mad und den anderen Filtern noch hinzufügen.

gruss

TiGü 14. Sep 2018 09:41

AW: WindowHandle vom Aktiven Renderer
 
Zitat:

Zitat von EWeiss (Beitrag 1413175)
Zitat:

Zitat von TiGü (Beitrag 1413174)
Zitat:

Zitat von EWeiss (Beitrag 1413173)
Delphi-Quellcode:
pPin.QueryInterface(IID_IOverlay, Overlay);

Overlay ist Nil trotz gefundenen Pin und dann kracht es natürlich. (wenn nicht abgesichert)

Aufgrund welcher Quelle gehst du davon aus, dass die Instanz des Pins das IOverlay-Interface implementiert?

Davon das ich weis das MadVr es tut.
Sonst könnte ich ja kein Overlay in Fenster anzeigen oder liege ich da falsch?
Notfalls könnte ich das Overlay Interface bei der Initialisierung von Mad und den anderen Filtern noch hinzufügen.

Du könntest natürlich auch die Dokumentation der MSDN lesen:
https://docs.microsoft.com/en-us/win...trmif-ioverlay

In der Mitte des Textes (5. Absatz) findest du die Antwort auf die Frage:
"Wer implementiert das IOverlay und wem kann ich demzufolge per QueryInterface fragen?"

Spoiler: Es ist NICHT eine IPin-Instanz.

EWeiss 14. Sep 2018 09:43

AW: WindowHandle vom Aktiven Renderer
 
Zitat:

Zitat von TiGü (Beitrag 1413176)
Zitat:

Zitat von EWeiss (Beitrag 1413175)
Zitat:

Zitat von TiGü (Beitrag 1413174)
Zitat:

Zitat von EWeiss (Beitrag 1413173)
Delphi-Quellcode:
pPin.QueryInterface(IID_IOverlay, Overlay);

Overlay ist Nil trotz gefundenen Pin und dann kracht es natürlich. (wenn nicht abgesichert)

Aufgrund welcher Quelle gehst du davon aus, dass die Instanz des Pins das IOverlay-Interface implementiert?

Davon das ich weis das MadVr es tut.
Sonst könnte ich ja kein Overlay in Fenster anzeigen oder liege ich da falsch?
Notfalls könnte ich das Overlay Interface bei der Initialisierung von Mad und den anderen Filtern noch hinzufügen.

Du könntest natürlich auch die Dokumentation der MSDN lesen:
https://docs.microsoft.com/en-us/win...trmif-ioverlay

In der Mitte des Textes (5. Absatz) findest du die Antwort auf die Frage:
"Wer implementiert das IOverlay und wem kann ich demzufolge per QueryInterface fragen?"

Spoiler: Es ist NICHT eine IPin-Instanz.

Ok werde ich mal tun.. Danke!

gruss

EWeiss 14. Sep 2018 14:10

AW: WindowHandle vom Aktiven Renderer
 
Bekomme das mit dem Pin nicht geregelt.. destotrotz habe ich das was ich wollte.
Beim Klick auf das Video Window wird ein Overlay gezeichnet welches den aktiven Status anzeigt.
Das Bitmap wir ein\aus gezoomt inklusive Layered Alpha.

Pause und Play abhängig vom aktuellen Status.
Spielerei.. habe das mal bei einem WebPlayer gesehen. (So muss ich nicht den Play oder Pause Button suchen)
Ja, ja doppelt gemoppelt. ;)

gruss

TiGü 14. Sep 2018 14:40

AW: WindowHandle vom Aktiven Renderer
 
Doku nicht gelesen?
Du musst die IBaseFilter-Instanz nach dem IOverlay fragen, nicht die IPin-Instanz.

EWeiss 14. Sep 2018 14:44

AW: WindowHandle vom Aktiven Renderer
 
Zitat:

Zitat von TiGü (Beitrag 1413194)
Doku nicht gelesen?
Du musst die IBaseFilter-Instanz nach dem IOverlay fragen, nicht die IPin-Instanz.

Hast du es nicht gesehen?
Delphi-Quellcode:
HR := FVideoRenderer.VMRFilter.FindPin(nil, pPin);


Nur ich weis nicht was ich bei Nil einfügen soll.
Das kann ja sonst was sein. 'Video Renderer' funktioniert nicht.. FVideoRenderer.FilterName genauso wenig.
Alles schon versucht.

So wie ich gelesen habe verwenden alle die IPin-Instanz um das Overlay zu erfragen.
Siehe!



gruss

TiGü 14. Sep 2018 14:47

AW: WindowHandle vom Aktiven Renderer
 
Emil, wenn du nicht in der Lage bist, längere englische Texte zu lesen, obwohl ich dir schon den Link und den passenden Absatz mitteilte, dann musst du das schreiben.
8 von 10 Fragen von dir wären hinfällig, wenn du die offizielle Dokumention der verwendeten Frameworks studieren würdest.

Zitat:

This interface (IOverlay - Anmerkung der Redaktion) is implemented on the Microsoft® DirectShow® video renderer filter. It can also be implemented on replacement video renderer filters if desired.

EWeiss 14. Sep 2018 14:53

AW: WindowHandle vom Aktiven Renderer
 
Siehe mein Edit der Link!
Hier der part falls du nicht schauen willst.

Zitat:

So, you can find the GetWindowHandle method in the IOverlay interface on the input pin (!) of the Video Renderer Filter
Code:
IGraphBuilder m_pFilterGraph;
IOverlay m_pOverlay;
// here you should create a filter graph and render your video file
...
hr = m_pFilterGraph->Render(...);
...
// getting IOverlay interface.
IBaseFilter *pFilter= NULL;
IPin *pin = NULL;
if (SUCCEEDED(m_pFilterGraph->FindFilterByName(L"Video Renderer",
    &pFilter))) {
  if (SUCCEEDED(pFilter->FindPin(L"VMR Input0", &pin))) {
    if (SUCCEEDED(pin->QueryInterface(IID_IOverlay,
        (void **)&m_pOverlay))){
      pin->Release();
      pFilter->Release();
    }
  } else {
    pFilter->Release();
  }
}
Und genau das tue ich!

gruss

TiGü 14. Sep 2018 14:58

AW: WindowHandle vom Aktiven Renderer
 
Zitat:

Zitat von EWeiss (Beitrag 1413204)
Und genau das tue ich!

Und, geht's?

EWeiss 14. Sep 2018 15:05

AW: WindowHandle vom Aktiven Renderer
 
Nochmal ich tue genau das!

Zitat:

So, you can find the GetWindowHandle method in the IOverlay interface on the input pin (!) of the Video Renderer Filter
Delphi-Quellcode:
FindConnectedPin(FVideoRenderer.VMRFilter, PINDIR_INPUT, pPin);


FVideoRenderer.VMRFilter = Video Renderer Filter
PINDIR_INPUT = in the IOverlay interface on the input pin

Danach ein Pin Query..
Delphi-Quellcode:
pPin.QueryInterface(IID_IOverlay, Overlay);


Und nein geht nicht..
Aber überall im Net sehe ich die selben Samples in etwas abgeänderter Form.

Link 2
Link 3
Ich könnte dir noch mehr Links zeigen aber das schenke ich mir.

Wegen diesen Problemen verwende ich jetzt WindowFromPoint und gut ist. :) 2 Zeiler und fertig!

gruss

TiGü 14. Sep 2018 16:28

AW: WindowHandle vom Aktiven Renderer
 
Tu mir doch bitte mal den gefallen und kopiere die ersten beiden Funktionen bei dir rein.
Wie du sie nutzt siehst du in einen kleinen Beispiel namens Main() am Ende. Du musst natürlich deine IGraphBuilder-Instanz reinstecken!

Delphi-Quellcode:
function FindPinInterface(
  const pFilter: IBaseFilter;
  const iid: TGUID;
  out ppUnk: IUnknown): HRESULT;
var
  pF: IBaseFilter;
  hr: HRESULT;
  pEnum: IEnumPins;
  pPin: IPin;
begin
  if not Assigned(pFilter) then
  begin
    Result := E_POINTER;
    Exit;
  end;
  hr := E_FAIL;
  pEnum := nil;

  if Failed(pFilter.EnumPins(pEnum)) then
  begin
    Result := E_FAIL;
    Exit;
  end;

  // Query every pin for the interface.
  pPin := nil;
  while (S_OK = pEnum.Next(1, pPin, nil)) do
  begin
    hr := pPin.QueryInterface(iid, ppUnk);

    if Succeeded(hr) then
    begin
      break;
    end;
  end;

  Result := hr;
end;

function FindInterfaceAnywhere(
  const pGraph: IGraphBuilder;
  const iid: TGUID;
  out ppUnk: IUnknown): HRESULT;
var
  pF: IBaseFilter;
  hr: HRESULT;
  pEnum: IEnumFilters;
begin
  if not Assigned(pGraph) then
  begin
    Result := E_POINTER;
    Exit;
  end;

  hr := E_FAIL;
  pEnum := nil;
  if Failed(pGraph.EnumFilters(pEnum)) then
  begin
    Result := E_FAIL;
    Exit;
  end;

  // Loop through every filter in the graph.
  pF := nil;
  while (S_OK = pEnum.Next(1, pF, nil)) do
  begin
    hr := pF.QueryInterface(iid, ppUnk);
    if Failed(hr) then
    begin
      // The filter does not expose the interface, but maybe one of its pins does.
      hr := FindPinInterface(pF, iid, ppUnk);
    end;

    if Succeeded(hr) then
    begin
      break;
    end;
  end;

  Result := hr;
end;

procedure Main();
var
  hr: HRESULT;
  GraphBuilder: IGraphBuilder;
  UnknownInterface: IUnknown;
  Overlay: IOverlay;
begin
  hr := CoCreateInstance(CLSID_FilterGraph, nil, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, GraphBuilder);
  if Succeeded(hr) then
  begin
    hr := FindInterfaceAnywhere(GraphBuilder, IOverlay, UnknownInterface);
    if Succeeded(hr) then
    begin
      hr := UnknownInterface.QueryInterface(IOverlay, Overlay);
      if Succeeded(hr) then
      begin
        // wuuup wuuup
      end;
    end;
  end;
end;

EWeiss 14. Sep 2018 16:32

AW: WindowHandle vom Aktiven Renderer
 
Ja danke werde ich machen.
Kann etwas dauern da ich die DLL und Abhängigkeiten dafür erst ausrichten muss.

gruss

EWeiss 14. Sep 2018 17:04

AW: WindowHandle vom Aktiven Renderer
 
Delphi-Quellcode:
function KVideo_GetActiveRenderWindowHandle: HWND stdcall;
begin
  Result := 0;
 
  if not Assigned(EVMRPlayer) then
    exit;

  if EVMRPlayer.PlayerState = psNotReady then
    exit;

  Result := EVMRPlayer.GetActiveRenderWindowHandle;
end;
Delphi-Quellcode:
function TEVMRPlayer.GetActiveRenderWindowHandle: HWND;
var
  hr: HRESULT;
  UnknownInterface: IUnknown;
  Overlay: IOverlay;
begin
    Result := 0;

//  hr := CoCreateInstance(CLSID_FilterGraph, nil, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, GraphBuilder);
//  if Succeeded(hr) then
//  begin
    hr := FindInterfaceAnywhere(GraphBuilder, IOverlay, UnknownInterface);
    if Succeeded(hr) then
    begin
      hr := UnknownInterface.QueryInterface(IOverlay, Overlay);
      if Succeeded(hr) then
        Overlay.GetWindowHandle(Result);
    end else
    ReportError('Create Overlay Error', Hr);
//  end;
end;
Fehler Schnittstelle nicht unterstützt.

Delphi-Quellcode:
hr := UnknownInterface.QueryInterface(IID_IOverlay, Overlay);
Oder?
Ich verstehe auch die Herangehensweise nicht.
Der GraphBuilder hat doch nichts mit dem Aktiven Video Render Filter zu tun.

Diese sind
VMR7BaseFilter, VMR9BaseFilter, madVRFilter, EVRBaseFilter

gruss

TiGü 14. Sep 2018 17:18

AW: WindowHandle vom Aktiven Renderer
 
Versuch mach kluch!

EWeiss 14. Sep 2018 17:23

AW: WindowHandle vom Aktiven Renderer
 
Zitat:

Zitat von TiGü (Beitrag 1413219)
Versuch mach kluch!

Richtig ;)
Aus dem vorherigen Beitrag.
Zitat:

Ich verstehe auch die Herangehensweise nicht.
Der GraphBuilder hat doch nichts mit dem Aktiven Video Render Filter zu tun.

Diese sind
VMR7BaseFilter, VMR9BaseFilter, madVRFilter, EVRBaseFilter
und wird so zum GraphBuilder addiert.
Delphi-Quellcode:
hr := GraphBuilder.AddFilter(FVideoRenderer.VMRFilter, PWideChar(FVideoRenderer.FilterName));


trotzdem Danke ein versuch war es wert.

PS:
Das ist warum ich auch nicht verstehe warum das suchen des Pin fehl schlägt bzw. das Overlay Interface.
Delphi-Quellcode:
HR := FVideoRenderer.VMRFilter.FindPin(PWideChar(FVideoRenderer.FilterName), pPin);

müsste eigentlich funktionieren!
Die Namen der Filter werden korrekt zugewiesen von daher muss ich sie nicht suchen.

gruss

TiGü 17. Sep 2018 07:48

AW: WindowHandle vom Aktiven Renderer
 
Zitat:

Zitat von EWeiss (Beitrag 1413220)
PS:
Das ist warum ich auch nicht verstehe warum das suchen des Pin fehl schlägt bzw. das Overlay Interface.
Delphi-Quellcode:
HR := FVideoRenderer.VMRFilter.FindPin(PWideChar(FVideoRenderer.FilterName), pPin);

müsste eigentlich funktionieren!
Die Namen der Filter werden korrekt zugewiesen von daher muss ich sie nicht suchen.

Mal so ins Blaue gefragt:
Warum sollte der Name des aktiven Filters der gleiche sein wie der Name des Pins?
Beim Auto ist der Name des "Pins" ja auch sowas wie "Tankeinfüllstutzen" und nicht "VW Golf III".

Du kannst den Matthias Rauen auch eine Mail auf Deutsch schreiben, um zu erfahren ob sein madVRFilter das IOverlay-Interface unterstützt und wenn ja, wie man da ran kommt.

EWeiss 17. Sep 2018 08:36

AW: WindowHandle vom Aktiven Renderer
 
Ich habe die Funktion entfernt weil überflüssig.
Ich habe das Handle von daher ist das Thema erledigt.

Danke.

PS:
Zitat:

Beim Auto ist der Name des "Pins" ja auch sowas wie "Tankeinfüllstutzen" und nicht "VW Golf III".
Nun der VMRFilter Name vom FVideoRenderer.VMRFilter ist ja auch "madVRFilter" und nicht FVideoRenderer.FilterName "madVR"
das selbe bei EVR VMRFilter Name EVRBaseFilter FVideoRenderer.FilterName "EVR"
Du erkennst den Unterschied zwischen beiden Namen?
Aber wie gesagt hat sich erledigt.

gruss


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:09 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz