Sdílet prostřednictvím


Podpora dynamických změn formátu v kodekech AVStream

Když dojde ke změně dynamického formátu ve spuštěném datovém proudu médií, systémem dodaný modul Devproxy vyjedná se zachytávacím pinem a určí, zda bude nový formát přijatelný.

K následující sekvenci událostí dochází, když změna dynamického formátu pochází ze zdroje médií:

  1. Ovladač obdrží KSPROPERTY_CONNECTION_PROPOSEDATAFORMAT požadavek, který určí, jestli vstupní špendlík KS podporuje nový typ média. Ovladače musí tuto vlastnost podporovat.

  2. Pokud vstupní kolík podporuje nový typ média, měl by obslužný program KSPROPERTY_CONNECTION_PROPOSEDATAFORMAT vrátit STATUS_SUCCESS. Ovladač pak určí, jestli může stream obnovit pomocí navrhovaného vstupu společně s aktuálně vybranými typy výstupních médií. Pokud ano, stream se obnoví.

  3. Pokud vstupní pin nepodporuje nově navržený formát média, měla by obslužná rutina KSPROPERTY_CONNECTION_PROPOSEDATAFORMAT vrátit chybu. HW MFT pak převyjednává typ média s připojenou komponentou.

  4. Pokud vstupní kolík podporuje nový typ vstupu média, ale filtr KS vyžaduje jiný výstupní typ média, ovladač by měl vygenerovat KSEVENT_DYNAMIC_FORMAT_CHANGE událost, jak je popsáno dále v tomto tématu, aby o změně typu média hw MFT informoval.

  5. Když HW MFT obdrží oznámení KSEVENT, přepne výstupní pin z KSSTATE_RUN na KSSTATE_STOP.

  6. HW MFT poté dotáže ovladač na dostupné typy médií, což se přeloží na volání obslužné rutiny průniku ovladače AVStrMiniIntersectHandlerEx. Ovladač by měl hlásit upřednostňované typy výstupních médií v pořadí podle preference.

  7. Uživatel v uživatelském režimu vybere typ média a nastaví nový typ média na výstupním kolíku HW MFT. Výsledkem je volání obslužné rutiny AVStrMiniPinSetDataFormat ovladače. Pokud ovladač přijme formát vrácením STATUS_SUCCESS, streamování se obnoví s novým typem média. Pokud volání selže, komponenty zahrnuté ve změně formátu musí znovu zařadit typ média.

  8. HW MFT zkontroluje, jestli nedošlo ke změně připojeného média. Pokud se nezmění, nastaví vybraný typ média na špendlíku a umístí ho do KSSTATE_RUN. Pokud dojde ke změně připojeného média, HW MFT zničí konektor a znovu jej vytvoří s nově vybraným typem média a médiem. MFT pak vloží pin do KSSTATE_RUN.

  9. Streamování se obnoví.

V některých situacích nemusí zdroj médií rozpoznat změnu formátu. Dekodér MPEG2 by například musel dekódovat každý paket, aby zjistil jakoukoli změnu formátu.

Pokud ovladač v takovém případě zjistí změnu formátu, měl by hardwarový ovladač vygenerovat dynamickou změnu formátu KSEVENT. HW MFT pak dotazuje pin pro jeho podporované typy médií. Špendlík by měl vrátit upřednostňované typy médií v pořadí podle preference. HW MFT pak následuje posloupnost událostí popsaných v krocích 4 až 9 předchozí části.

Pokud ovladač nemůže takovou změnu formátu zpracovat, měl by vrátit chybu streamování, která se pak rozšíří do MF.

Následující příklad kódu ukazuje, jak definovat novou změnu dynamického formátu pomocí KSEVENT:

// {162AC456-83D7-4239-96DF-C75FFA138BC6}
#define STATIC_KSEVENTSETID_DynamicFormatChange\
    0x162ac456, 0x83d7, 0x4239, 0x96, 0xdf, 0xc7, 0x5f, 0xfa, 0x13, 0x8b, 0xc6 DEFINE_GUIDSTRUCT("162AC456-83D7-4239-96DF-C75FFA138BC6", KSEVENTSETID_ DynamicFormatChange);
#define KSEVENTSETID_DynamicFormatChange DEFINE_GUIDNAMED(KSEVENTSETID_ DynamicFormatChange)

typedef enum {
KSEVENT_DYNAMIC_FORMAT_CHANGE = 0
};

DEFINE_KSEVENT_TABLE(DynamicFormatChangeEventTable) {
    DEFINE_KSEVENT_ITEM
    (
        KSEVENT_DYNAMIC_FORMAT_CHANGE,
        sizeof(KSEVENTDATA),
        0,   
        NULL,
        NULL,
        NULL
    )
};

KSEVENT_SET PinEventTable[] =
{
    DEFINE_KSEVENT_SET
    (
        &KSEVENTSETID_DynamicFormatChange,
        SIZEOF_ARRAY(DynamicFormatChangeEventTable),
        DynamicFormatChangeEventTable
    )
};

Každý pin by měl tuto událost zpřístupnit v jeho popisu. Událost je typu KSEVENTF_EVENT_HANDLE.

Než ovladač vygeneruje tuto událost, měl by nastavit upřednostňované typy médií pro špendlík KS na základě aktuálně vybraného typu vstupního média. Můžete to provést pomocí funkce _KsEdit na popisovači pinu.

Aby se událost vygenerovala, ovladače by měly volat KsGenerateEvents.