Videos abspielen mit DirectX

Die Seite wird erstellt Emma Nagel
 
WEITER LESEN
Videos abspielen mit DirectX
●   DirectShow!
      → Sowohl für Videos als auch für Musik geeignet (Kap.5)

●   Anwendungsgebiete:

      → Intros bei allen Arten von Spielen
      → Zwischensequenzen
      → Video als Spielelement
      → Realistische Oberflächen
            - Wasser
            - Blinkende Computerbildschirme
            - Bewegender Schleim an Wänden
●   Universelle Lösung:
       → Video auf einer Textur abspielen!

●   DirectShow basiert auf Filtern
       → Ein Filter kann Daten liefern, ein anderer ein Video in Bild
       und Ton aufteilen, ein Weiterer dekomprimieren usw.
          → Filtergraph!

●   DirectShow-Video-Renderer (Filter für Videodarstellung) ist
    leider ungeeignet, da er nur im Fenstermodus arbeitet.
       → Ein eigener Video-Renderer ist nötig
       → Microsoft stellt Basisklassen zur Verfügung für die
       Erstellung eigener Filter
          → Basisklasse: CBaseVideoRenderer
●
    Die Klasse tbVideoRenderer
    → Variablen:
       –   Zeiger auf die Textur, auf der das Video abgespielt wird:
           PDIRECT3DTEXTURE9 m_pTexture
       –   Eine zweite Textur (m_pBuffer) als Back-Buffer
       –   BOOL-Variable m_bDirty, zur Angleichung der
           Videoframe Berechnung auf die Spielframerate
       –   D3DSURFACE_DESC m_TexDesc zur Speicherung der
           Größe, des Formats und dem Verwendungszweck der
           Textur
       –   VIDEOINFO m_VideoInfo zur Speicherung von
           Informationen über das Video
               → BITMAPHEADER enthält z.B. biWidth und biHeight
               zur Beschreibung der Breite und Höhe
CheckMediaType
●   Erste Methode für den eigenen Filter, zur Überprüfung des
    Datenformats
      → Das passende Datenformat wird gesucht
      → CheckMediaType erhält als Parameter einen Zeiger auf
      eine CmediaType-Instanz, welche genaue Informationen
      über das zu testende Datenformat liefert
      → CheckMediaType liefert dann S_OK zurück, wenn das
      Format in Ordnung ist, sonst E_INVALIDARG
●   Wenn CheckMediaType ein Datenformat genehmigt hat, wird
    SetMediaType aufgerufen
      → Auch hier erhält man einen Zeiger auf eine CmediaType-
      Instanz, die das gewählte Format beinhaltet.
●   Speichern der Videoinformationen
      → Die Informationen werden in
      tbVideoRenderer::SetMediaType abgefragt und in
      m_VideoInfo gespeichert
      → Videobreite und Höhe wird separat in zwei
      lokalen Variablen gespeichert, da diese Angaben
      häufig gebraucht werden
Erstellen der Texturen
●   Methode CreateTexture der IDirect3DDevice9-Schnittstelle
Erstellen der Texturen
●   Größe
    → Normalerweise z.B. 128x128 oder 256x256, Videos
    messen allerdings eher 640x480 Pixel.
    → Echtzeitverkleinerung zwar möglich, aber zu aufwändig
●   Textur muss angepasst werden, dabei gibt es 2 Beschränkungen:
    1. Breite und Höhe müssen 2er Potenzen sein
       → Aufgehoben durch D3DPTEXTURECAPS_NONPOW2CONDITIONAL in
       der D3DCAPS9-Struktur im Element TextureCaps.
    2. Texturen müssen quadratisch sein, Breite und Höhe also identisch
       → Festgelegt durch D3DPTEXTURECAPS_SQUAREONLY
●   Bei keiner Beschränkung ist jede Texturgröße erlaubt, sonst muss
    der Wert auf den nächst höheren möglichen angebhoben werden.
Erstellen der Textur
●   Auf dynamische Textur prüfen
    → Schnellerer Zugriff möglich
    → D3DCAPS9::Caps2 D3DCAPS2_DYNAMICTEXTURES
         - Verwendungszweck somit D3DUASGE_DYNAMIC oder 0
         - Speicherklasse steht auch automatisch fest

●   Oberflächenformat
      - D3DFMT_X8R8G8B8 und D3DFMT_A8R8G8B8 (32 Bits)
      - D3DFMT_R8G8B8 (24 Bits)
      - D3DFMT_R5G6B5, D3DFMT_X1R5G5B5, D3DFMT_A1R5G5B5 (16 Bits)
●   Video auf Texturgröße bringen
       → Der tbVideoRenderer-Klasse eine tbVector2 Variable
    hinzufügen
       → Die Texturkoordinaten der rechten unteren Ecke des Videos auf
       der Textur speichern
          → Die anderen 3 Ecken ergeben sich daraus automatisch
             - Links oben (0, 0)
             - Rechts oben (vBottomRight.x, 0)
             - Links unten (0, vBottomRight.y)

●   DoRenderSample
       → Methode in tbVideoRenderer, die nach jedem vom
       Videodecoder verarbeiteten Sample aufgerufen wird
       → Mit dem Zeiger ImediaSample wird auf Bilddaten zugegriffen
       → DoRenderSample sperrt dann die Textur und kopiert die
       Videodaten hinein
●   Sperren der Textur, ermitteln des Speicherbereichs
    → Methode Idirect3DTexure9::Lockrect
       → Beinhaltet einen Zeiger namens pBits auf den Speicherbereich,
       der die Daten der Textur beinhaltet
    → Anordnung der Daten einer Textur:
       → Von oben nach unten, von rechts nach links
       → Zeilenabstand muss ermittelt werden (um wie viel Bytes
       muss der Zeiger erhöht werden für den Zeilensprung)
            → Zeilenabstand = Pitch, gespeichert im Element DWORD Pitch der
            D3DLOCKED_RECT-Struktur
        –

●   Die Videodaten sind allerdings von unten nach oben
    angeordnet!
       → Zeilenweises kopieren der Videodaten auf die Textur
       notwendig!
●   Der Video-Renderer-Filter ist damit implementiert

     → Um ein Video abspielen zu können, muss der Filter
    aber noch in den Filtergraphen eingebaut werden, damit er
    von DirectShow angesprochen werden kann:
●   Die TriBase Engine besitzt für all dies eine Klasse:
    → tbVideo
       → Nahezu identisch mit der Klasse tbMusic, besitzt aber
       einen eigenen Filter
       → Zum Abspielen eines Videos muss lediglich eine neue
       Instanz der Klasse angefertigt werden, dann Init aufrufen
       und mit Play das Video starten
       → Auch diverse Einstellungen, wie das Verändern der
       Abspielgeschwindigkeit und Lautstärke/Balance sind möglich
●   tbVideo ermöglicht auch, Videos direkt komplett in den Speicher
    zu laden und abzuspielen
       → DirectShow lädt das Video nicht im Voraus
          → Abspielen von Festplatte oder CDRom ist aber oft sehr langsam
    → Zur Nutzung dieser Funktion, einfach die entsprechende BOOL
    Variable in tbVideo::Init auf TRUE setzen
Vielen Dank!
Sie können auch lesen