AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Multimedia Delphi VMR9 custom allocator-presenter
Thema durchsuchen
Ansicht
Themen-Optionen

VMR9 custom allocator-presenter

Ein Thema von TERWI · begonnen am 17. Jan 2018 · letzter Beitrag vom 19. Jan 2018
Antwort Antwort
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.073 Beiträge
 
Delphi 10.4 Sydney
 
#1

AW: VMR9 custom allocator-presenter

  Alt 18. Jan 2018, 10:51
Zitat:
Direct3D und DirectShow
Direct3D hat damit weniger bis gar nichts zu tun.
https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx
Einfach mal zählen, wie oft der Begriff "Direct3D" vorkommt, danke!
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#2

AW: VMR9 custom allocator-presenter

  Alt 18. Jan 2018, 13:08
Zitat:
Direct3D und DirectShow
Direct3D hat damit weniger bis gar nichts zu tun.
https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx
Einfach mal zählen, wie oft der Begriff "Direct3D" vorkommt, danke!
Ja und was hat das mit Videos zu tun ?
Ich benötige es nicht einmal. Einfach mal zählen wie oft das in Zusammenhang mit Videos zum tragen kommt. danke

EDIT:
Sorry.. Bin jetzt von meiner Anwendung.
Natürlich verwendet meine DLL es.

gruss

Geändert von EWeiss (18. Jan 2018 um 15:13 Uhr)
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.073 Beiträge
 
Delphi 10.4 Sydney
 
#3

AW: VMR9 custom allocator-presenter

  Alt 18. Jan 2018, 13:43
Zitat:
Direct3D und DirectShow
Direct3D hat damit weniger bis gar nichts zu tun.
https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx
Einfach mal zählen, wie oft der Begriff "Direct3D" vorkommt, danke!
Ja und was hat das mit Videos zu tun ?
Ich benötige es nicht einmal. Einfach mal zählen wie oft das in Zusammenhang mit Videos zum tragen kommt. danke

gruss
Emil, wenn du nichts beizutragen hast, dann lass es doch einfach.
Es geht hier nicht darum was du willst oder kannst oder brauchst!
Ist doch völlig egal, ob irgendwelche ABC- oder XYZ-Filter in deinen Player dir die Details vorenthalten.
Mit irgendeiner API werden die ja auf die Grafikkarte zugreifen (GDI, GDI+, Direct3D9, Direct3D10/11/12, DirectDraw, Direct2D, OpenGL, Vulkan).

Es geht hier um DirectShow und die Implementierung eines eigenen Allocator-Presenter für einen Video Mixing Renderer 9 (VMR-9) Filter.
Der verwendet nun mal halt ein D3D9-Device und entsprechende D3D9-Surface nebst D3D9-Texturen.
Siehe entsprechend den Codeauszügen von Terwi (Variablen: FD3DDev, FD3D, surface, texture, ...).
  Mit Zitat antworten Zitat
Benutzerbild von TERWI
TERWI

Registriert seit: 29. Mär 2008
Ort: D-49626
381 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: VMR9 custom allocator-presenter

  Alt 18. Jan 2018, 13:15
Zitat:
wenn du uns ein minimales Beispielprojekt sowie entsprechende Videodateien zur Verfügung stellst.
Kann ich gerne machen. Das beeinhaltet dann allerdings die Vorraussetzung der Installation des DSPack's (bekannt ?) und die Verwendung der darin enthaltenen Klassen TFilterGraph und TVideoWindow, wenn man die benannte Demo (aus dem DSPack) '\DEMOS\D6-D7\VMR\VMR9ALLOCATOR\PlayFile' zum laufen bekommen will.
Daraus mal "eben schnell was extrahieren" geht z 100% in die Hose, weil sehr komplex und sehr verflochten....
Im Prinzip ist die Demo allerdings identisch mit der MS-WIN7-SDK Demo '\multimedia\directshow\vmr9\vmr9allocator' und betriff im wesentlichen die Dateien 'Allocator.cpp/.pas' und 'PlaneScene.cpp/.pas'.

Laufen tut die Demo mit jedem x-beliegiegen Video - wenn man wie EWeiss anmerkte, die LAV-Filter verwendet. Der LAVSplitterSource-Filter frisst fast alles. Ich habs hier mit div. .AVI, .MPG und .TS probiert.

Das Prinzip, so wie ich es bisher herausgebrezelt habe:
Das VideoWindow muss explizit zur Nutzung von VMR9 im Renderless-Mode gesetzt werden. Dazu muss man noch eine TAllocator-Klasse an's Window übergeben.
Der VMR9 ruft dann bei jedem Frame die Funktion "PresentImage" und hilfsweise die Funktion "PresentHelper" auf. Siehe hier auszugsweise im org. DSPack-File 'Allocator-pas':
Delphi-Quellcode:
function TAllocator.PresentImage(dwUserID: DWORD;
  lpPresInfo: PVMR9PresentationInfo): HResult;
var
  hr: HRESULT;
  AMonitor: HMONITOR;
  function FailRet(hr: HResult): boolean;
  begin
    PresentImage := hr;
    Result := Failed(hr);
  end;
begin
  FObjectLock.Enter;
  try
    // if we are in the middle of the display change
    if NeedToHandleDisplayChange then
    begin
        // NOTE: this piece of code is left as a user exercise.
        // The D3DDevice here needs to be switched
        // to the device that is using another adapter
    end;

    hr := PresentHelper(lpPresInfo);

    // IMPORTANT: device can be lost when user changes the resolution
    // or when (s)he presses Ctrl + Alt + Delete.
    // We need to restore our video memory after that
    if (hr = D3DERR_DEVICELOST) then
    begin
      if (FD3DDev.TestCooperativeLevel = D3DERR_DEVICENOTRESET) then
      begin
        DeleteSurfaces;
        if FailRet(CreateDevice) then exit;
        AMonitor := FD3D.GetAdapterMonitor(D3DADAPTER_DEFAULT);
        if FailRet(FlpIVMRSurfAllocNotify.ChangeD3DDevice(FD3DDev, AMonitor)) then exit;
      end;
      hr := S_OK;
    end;
    result := hr;
  finally
    FObjectLock.Leave;
  end;
end;

function TAllocator.PresentHelper(
  lpPresInfo: PVMR9PresentationInfo): HRESULT;
var
  surface: IDirect3DSurface9;
  texture: IDirect3DTexture9;
  function FailRet(hr: HResult): boolean;
  begin
    PresentHelper := hr;
    Result := Failed(hr);
  end;
begin
  // parameter validation
  if (lpPresInfo = nil) then
  begin
    result := E_POINTER;
    exit;
  end else
  if (lpPresInfo.lpSurf = nil) then
  begin
    result := E_POINTER;
    exit;
  end;

  FObjectLock.Enter;
  try
    FD3DDev.SetRenderTarget(0, FrenderTarget);
    // if we created a private texture
    // blt the decoded image onto the texture.
    if(FprivateTexture <> nil) then
    begin
      if FailRet(FprivateTexture.GetSurfaceLevel(0 , surface)) then exit;

      // copy the full surface onto the texture's surface
      if FailRet(FD3DDev.StretchRect(lpPresInfo.lpSurf, nil,
                           surface, nil,
                           D3DTEXF_NONE)) then exit;

      if FailRet(Fscene.DrawScene(FD3DDev, FprivateTexture)) then exit;
    end
    else // this is the case where we have got the textures allocated by VMR
         // all we need to do is to get them from the surface
    begin
      if FailRet(lpPresInfo.lpSurf.GetContainer(IID_IDirect3DTexture9, Pointer(texture))) then exit;
      if FailRet(Fscene.DrawScene(FD3DDev, texture)) then exit;
    end;
    if FailRet(FD3DDev.Present(nil, nil, 0, nil)) then exit;
// result := hr;
  finally
    Pointer(texture) := nil;
    FObjectLock.leave;
  end;
end;
Letztendlich wird im File 'PlaneScene.pas' (Auszug) die Funktion "DrawScene" aufgerufen und dort YXZ-Werte in Matrizen und Transformationen "verwurstet", was die Drehung der "Video-Scheibe" veranlasst ..... die ich gerne da raus hätte !
Delphi-Quellcode:
function TPlaneScene.DrawScene(d3ddev: IDirect3DDevice9;
  texture: IDirect3DTexture9): HRESULT;
  function FailRet(hr: HResult): boolean;
  begin
    DrawScene := hr;
    Result := Failed(hr);
  end;
var
  dwCurrentTime: DWord;
  difference: Int64;
  x, y, z: Single;
  mask0, mask3: DWord;
  pData: Pointer;
begin
  if ((d3ddev = nil) or (texture = nil)) then
  begin
    Result := E_POINTER;
    Exit;
  end;

  if( FvertexBuffer = nil) then
  begin
    Result := D3DERR_INVALIDCALL;
    Exit;
  end;

  // get the difference in time
  dwCurrentTime := GetTickCount;
  difference := Ftime - dwCurrentTime;

  // figure out the rotation of the plane
  x := -cos(difference / 2000);
  y := cos(difference / 2000);
  z := sin(difference / 2000);

  // update the two rotating vertices with the new position
  Fvertices[0].position := MakePosition(x, y, z); // top left
  Fvertices[3].position := MakePosition(-x, -y, -z); // bottom right

  // Adjust the color so the blue is always on the bottom.
  // As the corner approaches the bottom, get rid of all the other
  // colors besides blue
  mask0 := Trunc((255 * (( y + 1) / 2)));
  mask3 := Trunc((255 * ((-y + 1) / 2)));
  Fvertices[0].color := $ff0000ff or (mask0 shl 16) or (mask0 shl 8);
  Fvertices[3].color := $ff0000ff or (mask3 shl 16) or (mask3 shl 8);

  // write the new vertex information into the buffer
  if FailRet(FvertexBuffer.Lock(0, sizeof(pData), pData, 0)) then exit;
  move(Fvertices, pData^ , sizeof(Fvertices));
  if FailRet(FvertexBuffer.Unlock) then exit;

  // clear the scene so we don't have any articats left
  d3ddev.Clear(0, nil, D3DCLEAR_TARGET, D3DCOLOR_XRGB(255,255,255), 1.0, 0);

  if FailRet(d3ddev.BeginScene) then exit;
  if FailRet(d3ddev.SetTexture(0, texture)) then exit;

  if FailRet(d3ddev.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE)) then exit;
  if FailRet(d3ddev.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE)) then exit;
  if FailRet(d3ddev.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE)) then exit;
  if FailRet(d3ddev.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE)) then exit;

  if FailRet(d3ddev.SetStreamSource(0, FvertexBuffer, 0, sizeof(TCustomVertex))) then exit; //set next source ( NEW )
  if FailRet(d3ddev.SetFVF(D3DFVF_CUSTOMVERTEX)) then exit;
  if FailRet(d3ddev.DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2)) then exit; //draw quad
  if FailRet(d3ddev.SetTexture(0, nil)) then exit;
  if FailRet(d3ddev.EndScene) then exit;
end;
Hier endet leider mein mathematisches & delphianotisches Knoff-Hoff.
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.073 Beiträge
 
Delphi 10.4 Sydney
 
#5

AW: VMR9 custom allocator-presenter

  Alt 18. Jan 2018, 13:48
Delphi-Quellcode:
function TPlaneScene.DrawScene(d3ddev: IDirect3DDevice9;
  texture: IDirect3DTexture9): HRESULT;
  function FailRet(hr: HResult): boolean;
  begin
    DrawScene := hr;
    Result := Failed(hr);
  end;
var
  dwCurrentTime: DWord;
  difference: Int64;
  x, y, z: Single;
  mask0, mask3: DWord;
  pData: Pointer;
begin
  if ((d3ddev = nil) or (texture = nil)) then
  begin
    Result := E_POINTER;
    Exit;
  end;

  if( FvertexBuffer = nil) then
  begin
    Result := D3DERR_INVALIDCALL;
    Exit;
  end;

  // get the difference in time
  dwCurrentTime := GetTickCount;
  difference := Ftime - dwCurrentTime;

  // figure out the rotation of the plane
  x := -cos(difference / 2000);
  y := cos(difference / 2000);
  z := sin(difference / 2000);

  // update the two rotating vertices with the new position
  Fvertices[0].position := MakePosition(x, y, z); // top left
  Fvertices[3].position := MakePosition(-x, -y, -z); // bottom right

  // Adjust the color so the blue is always on the bottom.
  // As the corner approaches the bottom, get rid of all the other
  // colors besides blue
  mask0 := Trunc((255 * (( y + 1) / 2)));
  mask3 := Trunc((255 * ((-y + 1) / 2)));
  Fvertices[0].color := $ff0000ff or (mask0 shl 16) or (mask0 shl 8);
  Fvertices[3].color := $ff0000ff or (mask3 shl 16) or (mask3 shl 8);

  // write the new vertex information into the buffer
  if FailRet(FvertexBuffer.Lock(0, sizeof(pData), pData, 0)) then exit;
  move(Fvertices, pData^ , sizeof(Fvertices));
  if FailRet(FvertexBuffer.Unlock) then exit;

  // clear the scene so we don't have any articats left
  d3ddev.Clear(0, nil, D3DCLEAR_TARGET, D3DCOLOR_XRGB(255,255,255), 1.0, 0);

  if FailRet(d3ddev.BeginScene) then exit;
  if FailRet(d3ddev.SetTexture(0, texture)) then exit;

  if FailRet(d3ddev.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE)) then exit;
  if FailRet(d3ddev.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE)) then exit;
  if FailRet(d3ddev.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE)) then exit;
  if FailRet(d3ddev.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE)) then exit;

  if FailRet(d3ddev.SetStreamSource(0, FvertexBuffer, 0, sizeof(TCustomVertex))) then exit; //set next source ( NEW )
  if FailRet(d3ddev.SetFVF(D3DFVF_CUSTOMVERTEX)) then exit;
  if FailRet(d3ddev.DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2)) then exit; //draw quad
  if FailRet(d3ddev.SetTexture(0, nil)) then exit;
  if FailRet(d3ddev.EndScene) then exit;
end;
Hier endet leider mein mathematisches & delphianotisches Knoff-Hoff.
Ich dachte eigentlich an ein ZIP-Archiv mit allen benötigten Projektdateien, Quelltexten und Drittanbieter-Units (ja, auch das DSPack).
So das man als Helfender einfach nur das ZIP-Archiv entpackt und das Projekt öffnet und startet.

Nichts desto trotz musst du im oben zitierten Quelltext doch bloß das Drehen verhindern.
Probiere mal testweise diese Zeile difference := Ftime - dwCurrentTime; gegen difference := 0; auszustauschen.

Ansonsten kannst du alles ab der Zeile bis zum d3ddev.Clear auskommentieren und ausprobieren.
  Mit Zitat antworten Zitat
Benutzerbild von TERWI
TERWI

Registriert seit: 29. Mär 2008
Ort: D-49626
381 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: VMR9 custom allocator-presenter

  Alt 18. Jan 2018, 14:12
Download DSPack 2.3.4
Das ist die letzte offizielle Version - es gib auch noch 'überarbeitungen'.
Auspacken, Anweisungen zur Installation in der README.HTM lesen, VCL-Komponenten installieren, notwendige Verzeichnisse zuweisen und die Demo im Unterverzeichnis starten: '\DEMOS\D6-D7\VMR\VMR9ALLOCATOR\PlayFile'
Sonst braucht es nix.

Zitat:
Nichts desto trotz musst du im oben zitierten Quelltext doch bloß das Drehen verhindern. Probiere mal testweise diese Zeile difference := Ftime - dwCurrentTime; gegen difference := 0; auszustauschen.
Das war das erste, was ich getestet habe. Ergebnis siehe 1. Post:
Zitat:
... der Inhalt "hängt irgendwie auf halb-acht" im Raum/Fenster .... Nett, aber so unbrauchbar.
  Mit Zitat antworten Zitat
Benutzerbild von TERWI
TERWI

Registriert seit: 29. Mär 2008
Ort: D-49626
381 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: VMR9 custom allocator-presenter

  Alt 18. Jan 2018, 14:36
Noch eine nachträgliche Info zum kompilieren und DirextX:
Vor etwa 1/2 Jahr hab ich noch mit XP (32bit) und Win7 (auch 32bit, testweise x64) "rumgemacht". Damit ließ sich das DSPack immer einwandfrei kompilieren.
Verwendet wurde derzeit schon D2009.

Nach "Zusammenstellung" meines neuen Power-Schleppi's ist nun Win8.1 x64 auf dem Trapez. (10.x ++ gönne ich mir wahrscheinlich erst viel später ....)

Hier meckert mir Delphi das fehlen der Datei "d3dx9d_33.dll" an.
(.... HALLO, EWeiss ! )
Zur Abhilfe muss man in der DSPack-Datei "D3DX9.pas" die Zeile 95 (je nach Version !?)
// d3dx9MicrosoftDebugDLL = 'd3dx9d_33.dll';
auskommentieren.
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#8

AW: VMR9 custom allocator-presenter

  Alt 18. Jan 2018, 14:55
Zitat:
Hier meckert mir Delphi das fehlen der Datei "d3dx9d_33.dll" an.
(.... HALLO, EWeiss ! )
Zur Abhilfe muss man in der DSPack-Datei "D3DX9.pas" die Zeile 95 (je nach Version !?)
// d3dx9MicrosoftDebugDLL = 'd3dx9d_33.dll';
auskommentieren.
Ich weis nicht was du mir sagen willst.
Das Problem ist behoben und nicht mehr relevant für mich.
Für dein Problem TIGÜ ist der Boss daher halte ich mich jetzt raus. sorry

Zum Quelltext!
Er wollte deinen Code nicht den des DSPack.

gruss

Geändert von EWeiss (18. Jan 2018 um 14:59 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von TERWI
TERWI

Registriert seit: 29. Mär 2008
Ort: D-49626
381 Beiträge
 
Delphi 11 Alexandria
 
#9

AW: VMR9 custom allocator-presenter

  Alt 18. Jan 2018, 14:59
Aussehen tut das "Video auf halb acht" übrigends so:
Siehe Anhang.
Angehängte Grafiken
Dateityp: jpg Bild1.jpg (20,6 KB, 23x aufgerufen)
  Mit Zitat antworten Zitat
Benutzerbild von TERWI
TERWI

Registriert seit: 29. Mär 2008
Ort: D-49626
381 Beiträge
 
Delphi 11 Alexandria
 
#10

AW: VMR9 custom allocator-presenter

  Alt 18. Jan 2018, 15:11
@EWeiss:
Das 'Hallo..' war nur so als solches gemeint. Hatte hier nur mal neulich gelesen, das dich eben diesen Prob mir besagter DLL genervt hat.
Mich eben auch ... war nur gut gemeint.
Zitat:
Er wollte deinen Code nicht den des DSPack.
... der Quelltext ist z. Zt. eben genau zu Testzwecken der aus dem DSPack-Demo. Siehe oben.
Wenn benanntes Prob gelöst ist, werde ich den hier sicher auch posten.
Benannt ist das Projekt schon heute: MultiGraphEngine (MGE).

Geändert von TERWI (18. Jan 2018 um 15:17 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort

 

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:38 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz