Mediemottagare
Media-mottagare är pipelineobjekten som tar emot mediedata. En mediemottagare är målet för en eller flera medieströmmar. Mediemottagare delas in i två allmänna kategorier:
En renderare är en mediemottagare som visar data för uppspelning. Den förbättrade videoåtergivningen (EVR) visar videoramar och ljudåtergivningen spelar upp ljudströmmar via ljudkortet eller annan ljudenhet.
En arkivmottagare är en mediemottagare som skriver data till en fil eller annan lagring.
Den största skillnaden mellan dem är att en arkivmottagare inte använder data med en fast uppspelningshastighet. I stället skriver den de data som den tar emot så snabbt som möjligt.
Media mottagare exponerar IMFMediaSink gränssnitt. Varje mediemottagare innehåller en eller flera strömmottagare. Varje strömmottagare tar emot data från en ström. Stream-mottagare exponerar IMFStreamSink- gränssnitt. Vanligtvis skapar ett program inte mediamottagare direkt. I stället skapar programmet ett eller flera aktiveringsobjekt, som mediasessionen använder för att skapa mottagaren. Alla andra åtgärder på mottagaren hanteras av mediasessionen och programmet anropar inte några metoder på mediemottagaren eller någon av strömmottagaren. Mer information om aktiveringsobjekt finns i aktiveringsobjekt.
Du bör läsa resten av det här avsnittet om du skriver en anpassad mediemottagare eller om du vill använda en mediemottagare direkt utan mediasessionen.
- Stream-mottagare
- presentationsklocka
- Stream-format
- dataflöde
- markörer
- tillståndsändringar
- Slutför
- stänga av
- Media Sink Interfaces
- Stream Sink Interfaces
- Stream Sink Events
- Relaterade ämnen
Stream-mottagare
En mediemottagare kan ha ett fast antal strömmottagare, eller så kan den ha stöd för att lägga till och ta bort strömmottagare. Om den har ett fast antal strömmottagare returnerar IMFMediaSink::GetCharacteristics-metoden MEDIASINK_FIXED_STREAMS flaggan. Annars kan du lägga till och ta bort strömmottagare. Om du vill lägga till en ny strömmottagare anropar du IMFMediaSink::AddStreamSink. Om du vill ta bort en strömmottagare anropar du IMFMediaSink::RemoveStreamSink. Flaggan MEDIASINK_FIXED_STREAMS anger att mediemottagaren inte stöder dessa två metoder. (Det kan ha stöd för något annat sätt att konfigurera antalet strömmar, till exempel genom att ange initieringsparametrar när mottagaren skapas.) Listan över strömmottagare ordnas. Om du vill räkna upp dem efter indexvärde anropar du metoden IMFMediaSink::GetStreamSinkByIndex.
Stream-mottagare har också identifierare. Stream-identifierare är unika i mediemottagaren, men behöver inte vara i följd. Beroende på mediemottagaren kan strömidentifierarna ha en viss betydelse som är relaterad till innehållet. En arkivmottagare kan till exempel skriva strömidentifierarna i filhuvudet. Annars är de godtyckliga. Om du vill hämta en strömmottagare med dess identifierare anropar du IMFMediaSink::GetStreamSinkById.
Presentationsklocka
Den hastighet med vilken en mediemottagare använder exempel styrs av presentationsklocka. Mediasessionen väljer presentationsklockan och ställer in den på mediemottagaren genom att anropa mediemottagarens IMFMediaSink::SetPresentationClock-metoden. Presentationsklockan måste ställas in på mediemottagaren innan direktuppspelningen kan börja. Varje mediemottagare kräver en presentationsklocka för att köras. Mediemottagaren använder presentationsklockan för två syften:
Ta emot meddelanden när direktuppspelningen startar eller stoppas. Mediemottagaren tar emot dessa meddelanden via IMFClockStateSink gränssnitt, som alla mediemottagare måste implementera.
För att avgöra när det ska återge exempel. När mediemottagaren tar emot ett nytt exempel hämtar den tidsstämpeln från exemplet och försöker återge exemplet vid den presentationstillfället.
Presentationsklockan härleder sina klocktider från ett annat objekt som kallas presentationstidskälla. Presentationstidskällor exponerar gränssnittet IMFPresentationTimeSource. Vissa mediamottagare har åtkomst till en korrekt klocka, så de exponerar det här gränssnittet. Det innebär att en mediemottagare kan schemalägga exempel mot en tid som tillhandahålls av den egna klockan. Mediemottagaren kan dock inte anta att så är fallet. Den måste alltid använda tiden från presentationsklockan, oavsett om presentationsklockan drivs av själva mediemottagaren eller av någon annan klocka.
Om en mediemottagare inte kan matcha priser med en annan klocka än sin egen returnerar metoden GetCharacteristics -metoden MEDIASINK_CANNOT_MATCH_CLOCK flaggan. Om den här flaggan finns och presentationsklockan använder en annan presentationstidskälla kommer mediemottagaren sannolikt att prestera dåligt. Det kan till exempel uppstå problem under uppspelningen.
En frekvenslös mottagare är en mediemottagare som ignorerar tidsstämplarna på exempel och förbrukar data så snart varje exempel kommer. En frekvenslös mediemottagare returnerar flaggan MEDIASINK_RATELESS från metoden GetCharacteristics. Den här flaggan gäller vanligtvis för arkivmottagare. Om varje mediemottagare i pipelinen är frekvenslös använder mediasessionen en speciell kurslös presentationsklocka. Den här klockan körs lika snabbt som mottagare förbrukar exempel.
Stream-format
Innan mediemottagaren kan ta emot exempel måste klienten ange medietypen på strömmottagaren. Om du vill ange medietyp anropar du strömmottagarens IMFStreamSink::GetMediaTypeHandler-metoden. Den här metoden returnerar en pekare till IMFMediaTypeHandler--gränssnittet. Använd det här gränssnittet för att hämta listan över önskade medietyper, hämta den aktuella medietypen och ange medietyp.
Om du vill hämta listan över önskade medietyper anropar du IMFMediaTypeHandler::GetMediaTypeByIndex. De önskade typerna bör ses som ett tips för klienten. Listan kan vara ofullständig eller innehålla partiella medietyper. En partiell medietyp är en typ som inte har alla attribut som behövs för att beskriva ett giltigt format. En partiell videotyp kan till exempel ange färgrymden och bitdjupet, men inte bildbredden eller höjden. En partiell ljudtyp kan ange komprimeringsformatet och exempelfrekvensen, men inte antalet ljudkanaler.
Om du vill hämta strömmottagarens aktuella medietyp anropar du IMFMediaTypeHandler::GetCurrentMediaType. När en strömmottagare först skapas kan den ha en standardmedietyp som redan har angetts, eller så kanske den inte har någon medietyp förrän klienten anger en.
Om du vill ange medietyp anropar du IMFMediaTypeHandler::SetCurrentMediaType. Vissa strömmottagare kanske inte har stöd för att ändra typen efter att har angetts. Därför är det bra att testa medietyper innan du ställer in dem. Om du vill testa om mediemottagaren accepterar en medietyp (utan att ange typen) anropar du IMFMediaTypeHandler::IsMediaTypeSupported.
Dataflöde
Mediemottagare använder en pull-modell, vilket innebär att strömmen skickar begärandedata när de behöver dem. Klienten bör svara i tid för att undvika problem.
Vissa mediamottagare stöder förregistrering. Förregistrering är processen att ge data till mediemottagaren innan presentationsklockan startar. Om en mediemottagare stöder förregistrering exponerar mediemottagaren IMFMediaSinkPreroll--gränssnittet, och metoden GetCharacteristics returnerar flaggan MEDIASINK_CAN_PREROLL. Förregistreringen säkerställer att mediemottagaren är redo att presentera det första exemplet när presentationsklockan startar. Vi rekommenderar att klienten alltid förregistrerar sig om mediemottagaren stöder den, eftersom den kan förhindra fel eller luckor under uppspelningen.
Dataflödet till en mediemottagare fungerar på följande sätt:
- Klienten anger medietyperna och presentationsklockan. Mediemottagaren registrerar sig med presentationsklockan för att ta emot meddelanden om ändringar i klocktillståndet.
- Alternativt kan klienten fråga efter IMFMediaSinkPreroll. Om mediemottagaren exponerar det här gränssnittet anropar klienten IMFMediaSinkPreroll::NotifyPreroll. Annars hoppar klienten över till steg 5.
- Varje strömmottagare skickar en eller flera MEStreamSinkRequestSample händelser. Som svar på var och en av dessa händelser hämtar klienten nästa dataexempel för dataströmmen och anropar IMFStreamSink::P rocessSample.
- När varje strömmottagare tar emot tillräckligt med förregistreringsdata skickar den en MEStreamSinkPrerolled händelse.
- Klienten anropar IMFPresentationClock::Starta för att starta presentationsklockan.
- Presentationsklockan meddelar mediemottagaren att klockan startar genom att anropa IMFClockStateSink::OnClockStart.
- För att få mer data skickar varje strömmottagare MEStreamSinkRequestSample händelser. Som svar på var och en av dessa händelser hämtar klienten nästa exempel och anropar ProcessSample. Det här steget upprepas tills presentationen slutar.
De flesta mediamottagare bearbetar exempel asynkront, så att strömmottagare kan skicka ut mer än en exempelbegäran i taget.
Under strömning kan klienten anropa IMFStreamSink::P laceMarker och IMFStreamSink::Flush när som helst. Markörer beskrivs i nästa avsnitt. Tömning gör att strömmottagaren släpper alla exempel som den har placerat i kö men inte renderats ännu.
Markörer
Markörer är ett sätt för klienten att ange specifika punkter i dataströmmen. En markör består av följande information:
- Markörtypen, definierad som medlem i MFSTREAMSINK_MARKER_TYPE uppräkning.
- Data som är associerade med markören. Innebörden av data beror på typ av markör. Vissa markörtyper har inte data.
- Valfria data för klientens egen användning.
För att placera en markör anropar klienten IMFStreamSink::P laceMarker. Strömmottagaren slutför bearbetningen av de exempel som den tog emot före PlaceMarker--anropet och skickar sedan en MEStreamSinkMarker- händelse.
De flesta mediemottagare har en kö med väntande exempel som de bearbetar asynkront. Markörhändelser måste serialiseras med exempelbearbetning, så mediemottagaren bör placera markörer i samma kö. Anta till exempel att klienten gör följande metodanrop:
- ProcessSample (exempel nr 1)
- ProcessSample (exempel 2)
- PlaceMarker (markör nr 1)
- ProcessSample (exempel nr 3)
- PlaceMarker (markör nr 2)
I det här exemplet måste strömmottagaren skicka MEStreamSinkMarker- händelse för markör nr 1 när den har bearbetat exempel nr 2 och händelsen för markör nr 2 när den har bearbetat exempel nr 3.
Om klienten tömmer en strömmottagare bearbetar strömmottagaren omedelbart alla markörer som fanns i kön. Statuskoden anges till E_ABORT för dessa händelser.
Vissa markörer innehåller information som är relevant för mediemottagaren:
- MFSTREAMSINK_MARKER_TICK: Anger att det finns en lucka i strömmen. Nästa exempel blir en diskontinuitet.
- MFSTREAMSINK_MARKER_ENDOFSEGMENT: Anger slutet på ett segment eller slutet på en dataström. Nästa exempel (om det finns något) kan vara en diskontinuitet.
- MFSTREAMSINK_MARKER_EVENT: Innehåller en händelse. Beroende på händelsetyp och implementering av mediemottagaren kan mediemottagaren hantera händelsen eller ignorera den.
Tillståndsändringar
En mediemottagare meddelas om statliga förändringar i presentationsklockan via mediemottagarens IMFClockStateSink gränssnitt. När klienten ställer in presentationsklockan anropar mediamottagaren IMFPresentationClock::AddClockStateSink registrera sig för meddelanden från klockan. I följande tabell sammanfattas hur en mediemottagare beter sig som svar på ändringar i klocktillståndet.
Ändring av klocktillstånd | Exempelbearbetning | Markörbearbetning |
---|---|---|
OnClockStart | Bearbeta exempel vars tidsstämpel är lika med eller senare än klockans starttid. | Skicka MEStreamSinkMarker- händelse när alla exempel som tagits emot innan markören har bearbetats. |
OnClockPause | Mediemottagaren kan misslyckas ProcessSample- när den är pausad. Om mediemottagaren accepterar exempel när den är pausad måste den köa dem tills klockan startas om. Bearbeta inte några köade exempel när du har pausat. |
Om det finns exempel i kö placerar du markörer i samma kö. Skicka markörhändelsen när klockan startas om. Annars skickar du markörhändelsen omedelbart. |
OnClockRestart | Bearbeta alla exempel som placerats i kö när de pausades och behandla sedan samma som OnClockStart. | Skicka MEStreamSinkMarker händelser för köade markörer (serialiserade med exempelbearbetning) och behandla sedan samma sak som OnClockStart. |
OnClockStop | Ta bort alla köade exempel. Ytterligare anrop till ProcessSample kan misslyckas. | Skicka köade markörhändelser. Vid efterföljande anrop till PlaceMarkerskickar du markörhändelsen omedelbart. |
Dessutom måste strömmottagare skicka följande händelser när de har slutfört tillståndsövergångarna:
- OnClockStart, OnClockRestart: MEStreamSinkStarted event
- OnClockPause: MEStreamSinkPaused händelse
- OnClockStop: MEStreamSinkS toppad händelse
Slutföra
Vissa mediemottagare kräver ett extra bearbetningssteg efter att det senaste exemplet har levererats. Vanligtvis gäller detta krav för arkivmottagare, som måste skriva rubriker eller index i filen. Om en mediemottagare kräver någon slutlig bearbetning exponerar den IMFFinalizableMediaSink gränssnitt.
När klienten har levererat det sista exemplet frågar klienten efter det här gränssnittet. Om mediemottagaren stöder gränssnittet anropar klienten IMFFinalizableMediaSink::BeginFinalize för att utföra den slutliga bearbetningen asynkront. Den här metoden följer den asynkrona standardmodellen Media Foundation, som beskrivs i Asynkrona återanropsmetoder. Mediemottagaren kan anta att klienten anropar BeginFinalize. Det går inte att anropa BeginFinalize kan resultera i en felaktigt redigerad fil.
Stänga
När klienten är klar med mediemottagaren anropar klienten IMFMediaSink::Shutdown. I den här metoden ska mediemottagaren bryta alla cirkulära referensantal. Vanligtvis finns det cirkelreferenser mellan mediemottagaren och strömmottagaren.
Om du använder hjälpobjektet för händelseköer för att implementera IMFMediaEventGeneratoranropar du IMFMediaEventQueue::Stäng i händelsekön. Den här metoden stänger av händelsekön och signalerar alla anropare som för närvarande väntar på en händelse.
Efter avstängningen returnerar alla metoder på mediemottagaren MF_E_SHUTDOWN, med undantag för IUnknown metoder.
Media Sink Interfaces
I följande tabell visas de standardgränssnitt som mediemottagare kan exponera via QueryInterface. Mediemottagare kan också exponera anpassade gränssnitt.
Gränssnitt | Beskrivning |
---|---|
IMFMediaSink | Det primära gränssnittet för mediemottagare. (Krävs.) |
IMFClockStateSink | Används för att meddela mediemottagaren när presentationsklockan ändras. (Krävs.) |
IMFFinalizableMediaSink | Implementera om mediemottagaren måste utföra ett sista bearbetningssteg. (Valfritt.) |
IMFGetService | Implementera om mediemottagaren exponerar några tjänstgränssnitt. (Valfritt.) |
IMFMediaEventGenerator | Implementera om mediemottagaren skickar några händelser. (Valfritt.) |
IMFMediaSinkPreroll | Implementera om mediemottagaren stöder förregistrering. (Valfritt.) |
IMFPresentationTimeSource | Implementera om mediemottagaren kan tillhandahålla en tidskälla för presentationsklockan. (Valfritt.) |
IMFQualityAdvise | Implementera om mediemottagaren kan justera uppspelningskvaliteten. (Valfritt.) |
Alternativt kan en mediemottagare implementera följande gränssnitt som en tjänst.
Tjänstgränssnitt | Beskrivning |
---|---|
IMFRateSupport | Rapporterar intervallet med uppspelningsfrekvenser som stöds. |
Mer information om tjänstgränssnitt och IMFGetServicefinns i Service Interfaces.
Stream Sink Interfaces
Stream-mottagare måste exponera följande gränssnitt via QueryInterface.
Gränssnitt | Beskrivning |
---|---|
IMFStreamSink | Det primära gränssnittet för strömmottagare. (Krävs.) |
IMFMediaEventGenerator | Köer händelser. Gränssnittet IMFStreamSink ärver det här gränssnittet. (Krävs.) |
För närvarande definieras inga tjänstgränssnitt för strömmottagare.
Stream Sink Events
I följande tabell visas de händelser som har definierats för allmänna strömmottagare. Stream-mottagare kan också skicka anpassade händelser som inte visas här.
Händelse | Beskrivning |
---|---|
MEStreamSinkFormatChanged | Dataströmmottagarens medietyp är inte längre giltig. (Valfritt.) |
MEStreamSinkMarker | En markör bearbetades. (Krävs.) |
MEStreamSinkPaused | Strömmottagaren har pausats. (Krävs.) |
MEStreamSinkPrerolled | Förregistreringen är klar. (Valfritt.) |
MEStreamSinkRateChanged | Strömmottagaren har ändrat uppspelningshastigheten. (Valfritt.) |
MEStreamSinkRequestSample | Ett nytt exempel begärs. (Krävs.) |
MEStreamSinkScrubSampleComplete | En rensningsbegäran slutfördes. (Valfritt.) |
MEStreamSinkStarted | Strömmottagaren har startat. (Krävs.) |
MEStreamSinkS toppad | Strömmottagaren har stoppats. (Krävs.) |
För närvarande definieras inga allmänna händelser för mediemottagare. Vissa mediamottagare kan skicka anpassade händelser.
Relaterade ämnen