Megosztás a következőn keresztül:


Minták és allokátorok

[A laphoz társított funkció, DirectShowegy régi funkció. Ezt felváltotta a MediaPlayer, a IMFMediaEngineés a Audio/Video rögzítés a Media Foundation-ben. Ezek a funkciók Windows 10-hez és Windows 11-hez lettek optimalizálva. A Microsoft határozottan javasolja, hogy az új kód MediaPlayer, IMFMediaEngine és Audio/Video Capture eszközt használja a Media FoundationDirectShowhelyett, ha lehetséges. A Microsoft javasolja, hogy az örökölt API-kat használó meglévő kódot át kell írni az új API-k használatára, ha lehetséges.]

Amikor egy pin-kód médiaadatokat ad át egy másik pin-kódhoz, az nem ad át közvetlen mutatót a memóriapuffernek. Ehelyett egy olyan COM-objektumra mutat, amely kezeli a memóriát. Ez az médiamintanevű objektum elérhetővé teszi a IMediaSample felületet. A fogadó tű IMediaSample metódusok meghívásával fér hozzá a memóriapufferhez, például IMediaSample::GetPointer, IMediaSample::GetSizeés IMediaSample::GetActualDataLength.

A minták mindig lefelé haladnak, a kimeneti pin-től a bemeneti pin-ig. A leküldéses modellben a kimeneti pin-kód egy mintát ad ki IMemInputPin::Receive meghívásával a bemeneti pin-kódon. A bemeneti pin-kód szinkronizálva dolgozza fel az adatokat (vagyis teljesen a Fogadás metóduson belül), vagy aszinkron módon dolgozza fel az adatokat egy feldolgozó szálon. A bemeneti pin-kód blokkolhat a Fogadó metóduson belül, ha meg kell várnia az erőforrásokat.

Egy másik COM-objektum, az úgynevezett -kiosztófelelős a médiaminták létrehozásáért és kezeléséért. Az elosztók elérhetővé teszik a IMemAllocator felületet. Amikor egy szűrőnek üres pufferrel rendelkező médiamintára van szüksége, meghívja a IMemAllocator::GetBuffer metódust, amely egy mutatót ad vissza a mintához. Minden "pin" kapcsolat egy elosztót oszt meg. Amikor két tű csatlakozik, eldöntik, hogy melyik szűrő biztosítja a kiosztót. A tűk az elosztó tulajdonságait is beállítják, például a pufferek számát és az egyes pufferek méretét. (Részletekért lásd a Szűrők csatlakoztatása és Allokátorok tárgyalásacímű cikket.)

Az alábbi ábra a kiosztó, a médiaminták és a szűrő közötti kapcsolatokat mutatja be.

médiaminták és kiosztók

médiaminta referenciáinak száma

Egy kiosztó egy véges mintakészletet hoz létre. Egyes minták bármikor használatban lehetnek, míg mások GetBuffer hívásokhoz érhetők el. A kiosztó hivatkozásszámlálást használ a minták nyomon követéséhez. A GetBuffer metódus egy 1 hivatkozási számot tartalmazó mintát ad vissza. Ha a hivatkozási szám nullára csökken, a minta visszakerül az elosztó tárába, ahol a következő GetBuffer hívás során újra fel lehet használni. Amíg a referenciaszám nulla felett marad, a minta nem áll rendelkezésre a GetBufferszámára. Ha az elosztóhoz tartozó összes minta használatban van, a GetBuffer metódus várakozik, amíg egy minta elérhetővé nem válik.

Tegyük fel például, hogy egy bemeneti tű mintát kap. Ha szinkron módon dolgozza fel a mintát, a Fogadó metóduson belül nem növeli a referenciaszámot. Miután a fogadó megkapja a visszatérést, a kimeneti tű kiereszti a mintát, a hivatkozási szám nullára csökken, és a minta visszakerül az elosztó készletébe. Ha viszont a bemeneti tű feldolgozza a mintát egy feldolgozószálon, az növeli a referenciaszámot, mielőtt elhagyná a Fogadás metódust. A hivatkozási szám most 2. Amikor a kimeneti csatlakozó elengedi a mintát, a számláló 1-re áll; a minta még nem tér vissza a tárhoz. Miután a munkavégző szál elkészült a mintával, meghívja a Release függvényt a minta felszabadításához. Most a minta visszakerül a medencébe.

Amikor egy pin-kód mintát kap, átmásolhatja az adatokat egy másik mintába, vagy módosíthatja az eredeti mintát, és továbbíthatja azt a következő szűrőre. Elképzelhető, hogy egy minta végighalad a gráf teljes hosszán, miközben minden szűrő sorban meghívja az AddRef és Release utasításokat. Ezért a kimeneti csatlakozónak soha nem szabad ismételten felhasználnia a mintát, miután meghívja a Receive-t, mert előfordulhat, hogy egy tovább lévő szűrő használja a mintát. A kimeneti pin-kódnak mindig meg kell hívnia GetBuffer az új minta lekéréséhez.

Ez a mechanizmus csökkenti a memóriafoglalás mennyiségét, mivel a szűrők ugyanazokat a puffereket használják újra. Emellett megakadályozza, hogy a szűrők véletlenül olyan adatokon írjanak, amelyeket nem dolgoztak fel, mivel az elosztó fenntartja a rendelkezésre álló minták listáját.

A szűrő külön allokátorokat használhat a bemenethez és a kimenethez. Ezt megteheti, ha kibontja a bemeneti adatokat (például dekompresszióval). Ha a kimenet nem nagyobb, mint a bemenet, előfordulhat, hogy egy szűrő a helyén dolgozza fel az adatokat anélkül, hogy átmásolna egy új mintába. Ebben az esetben két vagy több pin-kapcsolat oszthat meg egy kiosztót.

Allokátorok foglalása és felszabadítása

Amikor egy szűrő először létrehoz egy allokátort, az allokátor nem foglalt le memóriapuffereket. Ezen a ponton a GetBuffer metódus hívásai sikertelenek lesznek. A streamelés indításakor a kimeneti tű meghívja IMemAllocator::Commit, amely elvégzi az allokátort, ezzel memóriát foglalva le. A kitűzők mostantól meghívhatják GetBuffer.

Amikor a streaming leáll, a csatlakozó meghívja a IMemAllocator::Decommitmetódust, amely felszabadítja a kiosztót. A GetBuffer minden további hívása meghiúsul, amíg a kiosztó újra le nem véglegesül. Továbbá ha a GetBuffer hívásai jelenleg le vannak tiltva, és a mintára várnak, azonnal visszaadnak egy hibakódot. A Decommit metódus a megvalósítástól függően szabadíthatja fel, vagy nem, a memóriát. A CMemAllocator osztály például megvárja, amíg a destruktormetódus felszabadítja a memóriát.

Adatáramlás a filter graphban