Presentationsklocka
Den presentationsklockan är ett objekt som genererar klocktiden för en presentation. Den tid som rapporteras av presentationsklockan kallas presentationstid. Alla strömmar i en presentation synkroniseras till presentationstiden. Presentationsklockan visar följande gränssnitt.
Gränssnitt | Beskrivning |
---|---|
IMFPresentationClock | Primärt gränssnitt för att använda presentationsklockan. |
IMFRateControl | Styr klockfrekvensen. |
IMFTimer | Tillhandahåller ett timeråteranrop. |
IMFShutdown | Stänger av presentationsklockan. |
Mediamottagare använder presentationstiden för att schemalägga när exempel ska återges. När en mediemottagare tar emot ett nytt exempel hämtar den tidsstämpeln från exemplet och återger provet vid den angivna tidpunkten, eller så nära den tiden som möjligt. Eftersom alla mediemottagare i en topologi delar samma presentationsklocka synkroniseras flera strömmar (till exempel ljud och video). Mediekällor och transformeringar använder inte presentationsklockan eftersom de inte schemalägger när exempel ska levereras. I stället skapar de exempel när pipelinen begär ett nytt exempel.
Om du använder mediasessionen för uppspelning hanterar mediasessionen all information om hur du skapar presentationsklockan, väljer en tidskälla och meddelar mediemottagaren. Programmet kan använda presentationsklockan för att få den aktuella presentationstiden under uppspelningen, men annars anropas inga metoder på presentationsklockan.
Klocktid och klocktillstånd
Om du vill hämta den senaste klocktiden från presentationsklockan anropar du IMFPresentationClock::GetTime. Klocktiderna är alltid i 100 nanosekunder, så en sekund är 10 000 000 (10^7) tick. Detta motsvarar en frekvens på 10 MHz.
Presentationsklockan har tre tillstånd: Körs, pausas och stoppas.
- Om du vill köra klockan anropar du IMFPresentationClock::Start. Metoden Start anger klockans starttid. När klockan körs ökar klocktiden från starttiden, med den aktuella klockfrekvensen.
- Om du vill pausa klockan anropar du IMFPresentationClock::P ause. När klockan har pausats går klockan inte framåt och GetTime- returnerar den tid då klockan pausades.
- Om du vill stoppa klockan anropar du IMFPresentationClock::Stop. När klockan stoppas avancerar inte klocktiden och GetTime- returnerar noll.
Som standard avancerar klockan med en hastighet av 1,0, vilket innebär 1 tick per 100 nanosekunder. Om du vill ändra hastigheten med vilken klockan avancerar frågar du presentationsklockan efter gränssnittet IMFRateControl och anropar IMFRateControl::SetRate.
Objekt kan ta emot meddelanden om tillståndsändringar (inklusive hastighetsändringar) från presentationsklockan. Om du vill ta emot meddelanden implementerar du IMFClockStateSink--gränssnittet och anropar IMFPresentationClock::AddClockStateSink på presentationsklockan. Innan du stänger av anropar du IMFPresentationClock::RemoveClockStateSink för att avregistrera objektet. Mediamottagare använder den här mekanismen för att ta emot meddelanden från klockan.
Presentationstider
En mediemottagare försöker schemalägga varje exempel så att exemplet återges vid rätt tidpunkt eller så nära rätt tid som möjligt. Följande definitioner gäller:
- Presentationstid. Den tid då ett exempel ska återges. Tid ges i enheter på 100 nanosekunder.
- Medietid. Tid i förhållande till början av innehållet. Om en videofil till exempel är 10 sekunder lång, har punkten halvvägs genom filen en medietid på 5 sekunder.
- Tidstämpel. Den tid som har markerats på ett medieexempel. Om du vill hämta tidsstämpeln anropar du IMFSample::GetSampleTime. När en mediekälla skapar ett exempel anger den tidsstämpeln lika med medietiden. Mediesessionen översätter tidsstämpeln till presentationstid.
Medietid och presentationstid är som standard desamma, till exempel om en videobildruta visas 5 sekunder in i källfilen är medietiden och presentationstiden båda 5 sekunder. Om du använder Sequencer Sourceär tidsmodellen något mer komplicerad för att möjliggöra smidiga övergångar mellan segment. Mer information om sekvenserarens tidsmodell finns i Sekvenspresentationstider.
Mediekällan anger alltid tidsstämpeln lika med medietiden. Om presentationstiden inte är justerad mot medietiden konverterar Mediesessionen tidsstämplarna på medieexemplen. När mottagaren tar emot ett exempel har exemplets tidsstämpel konverterats till presentationstid. Mottagaren schemalägger exemplet mot presentationsklockans aktuella tid. (Frekvenslösa mottagare är ett undantag eftersom de ignorerar presentationsklockan.)
Om programmet söker till en ny position startar mediasessionen om presentationsklockan vid den angivna söktiden. Om programmet till exempel söker till 5-sekunderspositionen i filen startar mediasessionen klockan vid 5 sekunder. Mediekällan kan leverera exempel med en något tidigare tidsstämpel om söktiden inte hamnar på en nyckelramsgräns. Detta krävs så att avkodarna kan avkoda alla bildrutor. Mediasessionen tar bort eller trimmar exempel innan de når mediemottagaren för att matcha den begärda söktiden. Om söktiden till exempel är 5 sekunder kan det första ljudexemplet börja på 4,5 sekunder. Mediasessionen trimmar de första 0,5 sekunderna från det första avkodade ljudexemplet.
Skapa presentationsklockan
Om du vill skapa presentationsklockan anropar du MFCreatePresentationClock. Om du vill stänga av klockan frågar du efter gränssnittet IMFShutdown och anropar IMFShutdown::Shutdown. Anroparen för MFCreatePresentationClock ansvarar för att anropa Shutdown; I de flesta fall är det mediasessionen i stället för programmet.
Presentationstidskällor
Trots sitt namn implementerar presentationsklockan faktiskt inte en klocka. I stället hämtas klocktiderna från ett annat objekt, som kallas presentationstidskälla. Tidskällan kan vara ett objekt som genererar korrekta klockfästningar och exponerar IMFPresentationTimeSource- gränssnitt. Följande bild visar den här processen.
När presentationsklockan först skapas har den ingen tidskälla. Om du vill ange tidskällan anropar du IMFPresentationClock::SetTimeSource med en pekare till tidskällans IMFPresentationTimeSource--gränssnitt. En tidskälla stöder samma tillstånd som presentationsklockan (körs, pausas och stoppas) och måste implementera IMFClockStateSink-gränssnittet. Presentationsklockan använder det här gränssnittet för att meddela tidskällan när tillståndet ska ändras. På så sätt ger tidskällan klockan tick, men presentationsklockan initierar tillståndsändringar i klockan.
Vissa mediemottagare har tillgång till en korrekt klocka och exponerar därför IMFPresentationTimeSource- gränssnitt. I synnerhet kan ljudåtergivningen använda frekvensen för ljudkortet som en klocka. I ljuduppspelning är det användbart för ljudåtergivningen att fungera som tidskälla, så att videon synkroniseras med ljuduppspelningshastigheten. Detta ger vanligtvis bättre resultat än att försöka matcha ljudet med en extern klocka.
Media Foundation tillhandahåller också en presentationstidskälla baserat på systemklockan. Om du vill skapa det här objektet anropar du MFCreateSystemTimeSource. Systemtidskällan kan användas när inga mediemottagare tillhandahåller en tidskälla.
I allmänhet måste en mediemottagare använda den presentationsklocka som tillhandahålls till den, oavsett vilken tidskälla presentationsklockan använder. Den här regeln gäller även när en mediemottagare implementerar IMFPresentationTimeSource. Om presentationsklockan använder någon annan tidskälla måste mediemottagaren följa den tidskällan, inte sin egen interna klocka.
Det finns två situationer när en mediamottagare inte följer presentationsklockan:
Vissa mediemottagare är frekvenslösa. Om en mediemottagare är frekvenslös förbrukar den prover så snabbt som möjligt, utan att schemalägga dem enligt presentationsklockan. Vanligtvis skriver frekvenslösa mottagare data till en fil, så det är önskvärt att slutföra åtgärden så snabbt som möjligt. En räntelös mottagare returnerar flaggan MEDIASINK_RATELESS i sin IMFMediaSink::GetCharacteristics-metoden. När alla mottagare i en topologi är frekvenslösa skickar mediasessionen data via pipelinen så snabbt som möjligt.
Vissa mediemottagare kan inte matcha priser med en annan tidskälla än sig själva. I så fall returnerar mottagaren flaggan MEDIASINK_CANNOT_MATCH_CLOCK i sin GetCharacteristics-metod. Pipelinen kan fortfarande använda en annan tidskälla, men resultatet blir mindre än optimalt. Handfatet kommer troligen att hamna efter och orsaka problem under uppspelningen.
Relaterade ämnen