Generera nya ASF-datapaket
ASF multiplexer är en WMContainer-lagerkomponent som fungerar med ASF-dataobjektet och ger ett program möjlighet att generera ASF-datapaket för en ström som matchar kraven som definieras i ContentInfo-objektet.
Multiplexern har en indata och en utdata. Den tar emot ett dataströmexempel som innehåller digitala mediedata och genererar ett eller flera datapaket som kan skrivas till en ASF-container.
I följande lista sammanfattas processen för att generera ASF-datapaket:
- Skicka indata till multiplexern i IMFASFMultiplexer::P rocessSample.
- Samla in datapaketen genom att anropa IMFASFMultiplexer::GetNextPacket i en loop tills alla fullständiga paket har hämtats.
- När indata har konverterats till fullständiga paket kan det finnas väntande data i multiplexern, som inte hämtades av GetNextPacket. Anropa IMFASFMultiplexer::Flush för att paketera de väntande proverna och samla in dem från multiplexern genom att anropa GetNextPacket igen.
- Uppdatera de associerade ASF-huvudobjekten genom att anropa IMFASFMultiplexer::End för att återspegla ändringar som gjorts av multiplexern under datapaketgenereringen.
Följande diagram illustrerar generering av datapaket för en ASF-fil via multiplexern.
Skapa ASF-datapaket
När du har skapat och initierat multiplexern enligt beskrivningen i Create the Multiplexer Objectanropar du IMFASFMultiplexer::P rocessSample för att skicka indata till multiplexern för bearbetning till datapaket. Angivna indata måste finnas i ett medieexempel (IMFSample-gränssnitt) som kan ha en eller flera mediebuffertar (IMFMediaBuffer gränssnitt) som innehåller data för en ström. Vid ASF-till-ASF-omkodning kan indatamedieexemplet genereras från splittern som skapar paketerade strömexempel. Mer information finns i ASF Splitter.
Innan du anropar ProcessSamplekontrollerar du att tidsstämpeln för indatamedieexemplet är en giltig presentationstid. annars misslyckas ProcessSample och returnerar MF_E_NO_SAMPLE_TIMESTAMP-koden.
Multiplexern kan acceptera indata som komprimerade eller okomprimerade medieexempel via ProcessSample-. Multiplexern tilldelar sändningstider till dessa exempel beroende på bandbreddsanvändningen för dataströmmen. Under den här processen kontrollerar multiplexern parametrarna för läckande bucketar (bithastighet och buffertfönsteranvändning) och kan avvisa exempel som inte följer dessa värden. Indatamedieexemplet kan misslyckas med bandbreddskontrollen av någon av följande orsaker:
- Om indatamedieexemplet kom sent eftersom den senast tilldelade sändningstiden är större än tidsstämpeln för det här medieexemplet. ProcessSample misslyckas och returnerar MF_E_LATE_SAMPLE felkoden.
- Om tidsstämpeln för indatamedieexemplet är tidigare än den tilldelade sändningstiden (detta indikerar buffertöverskridande). Multiplexern kan ignorera den här situationen om den är konfigurerad för att justera bithastigheten genom att ange flaggan MFASF_MULTIPLEXER_AUTOADJUST_BITRATE under multiplexerinitiering. För mer information, se "Multiplexerinitiering och läckagehinkinställningar" i Skapa multiplexerobjektet. Om den här flaggan inte har angetts och multiplexern stöter på bandbreddsöverskridning misslyckas ProcessSample och returnerar felkoden MF_E_BANDWIDTH_OVERRUN.
När multiplexern har tilldelat sändningstiden läggs indatamedieexemplet till i skicka-fönstret– en lista över indatamedieexempel ordnade efter sändningstider och redo att bearbetas till datapaket. Under konstruktionen av datapaket parsas indatamedieexemplet och relevanta data skrivs till ett datapaket som nyttolast. Ett fullständigt datapaket kan innehålla data från ett eller flera indatamedieexempel.
När nya indatamedieexempel tas emot i sändningsfönstret läggs de till i en kö tills det finns tillräckligt med medieexempel för att bilda ett komplett paket. Data i mediebuffertar som ingår i indatamedieexemplet kopieras inte till det genererade datapaketet. Datapaketet innehåller referenser till indatamediebuffertarna tills indatamedieexemplet har paketerats helt och hela paketet har samlats in från multiplexern.
När ett fullständigt datapaket är tillgängligt kan det hämtas genom att anropa IMFASFMultiplexer::GetNextPacket. Om du anropar ProcessSample- medan det finns fullständiga paket redo för hämtning misslyckas det och returnerar felkoden MF_E_NOTACCEPTING. Detta indikerar att multiplexern inte kan acceptera fler indata och du måste anropa GetNextPacket för att hämta de väntande paketen. Helst bör varje ProcessSample--anrop följas av en eller flera GetNextPacket--anrop för att hämta hela datapaketen. Det kan krävas mer än ett indatamedieexempel för att skapa ett fullständigt datapaket. Omvänt kan data i ett indatamedieexempel sträcka sig över flera paket. Därför ger inte alla anrop till ProcessSample utdatamedieexempel.
Om indatamedieexemplet innehåller en nyckelram som anges av attributet MFSampleExtension_CleanPoint kopierar multiplexern attributet till paketet.
Hämta ASF-datapaket
Om du vill samla in utdatamedieexempel för ett fullständigt datapaket som genereras av multiplexern anropar du IMFASFMultiplexer::GetNextPacket i en loop tills det inte finns några fler utdatamedieexempel kvar för paketet. Följande visar en lista över lyckade fall:
- Om det finns ett fullständigt datapaket tillgängligt tar GetNextPacket emot flaggan ASF_STATUS_FLAGS_INCOMPLETE i parametern pdwStatusFlags. parametern ppIPacket tar emot en pekare till det första datapaketet. Du måste anropa den här metoden så länge den får denna flagga. Med varje iteration pekar ppIPacket på nästa paket i kön.
- Om det bara finns ett datapaket pekar ppIPacket på det och flaggan ASF_STATUS_FLAGS_INCOMPLETE tas inte emot i pdwStatusFlags.
- GetNextPacket kan lyckas utan att ge några datapaket om multiplexern fortfarande håller på att paketera och lägga till datapaket. I det här fallet pekar ppIPacket på NULL. Om du vill fortsätta måste du ge multiplexern fler indatamedieexempel genom att anropa ProcessSample.
Följande exempelkod visar en funktion som genererar datapaket med hjälp av multiplexern. Innehållet i det genererade datapaketet skrivs till databyteströmmen som allokeras av anroparen.
//-------------------------------------------------------------------
// GenerateASFDataPackets
//
// Gets data packets from the mux. This function is called after
// calling IMFASFMultiplexer::ProcessSample.
//-------------------------------------------------------------------
HRESULT GenerateASFDataPackets(
IMFASFMultiplexer *pMux,
IMFByteStream *pDataStream
)
{
HRESULT hr = S_OK;
IMFSample *pOutputSample = NULL;
IMFMediaBuffer *pDataPacketBuffer = NULL;
DWORD dwMuxStatus = ASF_STATUSFLAGS_INCOMPLETE;
while (dwMuxStatus & ASF_STATUSFLAGS_INCOMPLETE)
{
hr = pMux->GetNextPacket(&dwMuxStatus, &pOutputSample);
if (FAILED(hr))
{
break;
}
if (pOutputSample)
{
//Convert to contiguous buffer
hr = pOutputSample->ConvertToContiguousBuffer(&pDataPacketBuffer);
if (FAILED(hr))
{
break;
}
//Write buffer to byte stream
hr = WriteBufferToByteStream(pDataStream, pDataPacketBuffer, NULL);
if (FAILED(hr))
{
break;
}
}
SafeRelease(&pDataPacketBuffer);
SafeRelease(&pOutputSample);
}
SafeRelease(&pOutputSample);
SafeRelease(&pDataPacketBuffer);
return hr;
}
Funktionen WriteBufferToByteStream
visas i ämnet IMFByteStream::Write.
Om du vill se ett komplett program som använder det här kodexemplet kan du läsa Självstudie: Kopiera ASF-strömmar från en fil till en annan.
Publicera Packet-Generation-anrop
För att se till att det inte finns några fullständiga datapaket som väntar i multiplexern anropar du IMFASFMultiplexer::Flush. Detta tvingar multiplexern att paketera alla mediasampel som är under bearbetning. Programmet kan samla in dessa paket i form av medieexempel via GetNextPacket i en loop tills det inte finns några fler paket kvar att hämta.
När alla medieexempel har genererats anropar du IMFASFMultiplexer::End för att uppdatera ASF-huvudobjektet som är associerat med dessa datapaket. Huvudobjektet anges genom att skicka ContentInfo-objektet som användes för att initiera multiplexern. Det här anropet uppdaterar olika rubrikobjekt så att de återspeglar ändringar som gjorts av multiplexern under genereringen av datapaket. Den här informationen omfattar antal paket, sändningstid, uppspelningstid och strömnummer för alla strömmar. Den totala sidhuvudstorleken uppdateras också.
Du måste se till att End anropas när alla datapaket har hämtats. Om det finns paket som väntar i multiplexern misslyckas End och returnerar felkoden MF_E_FLUSH_NEEDED. I det här fallet hämtar du det väntande paketet genom att anropa Flush och GetNextPacket i en loop.
Anmärkning
När du har anropat Endför VBR-kodning måste du ange kodningsstatistiken i ContentInfo-objektets kodningsegenskaper. Information om den här processen finns i "Konfigurera ContentInfo-objektet med kodarinställningar" i Ange egenskaper i ContentInfo-objektet. I följande lista visas de specifika egenskaper som ska anges:
- MFPKEY_RAVG är den genomsnittliga bithastigheten för VBR-innehållet.
- MFPKEY_BAVG är buffertfönstret för den genomsnittliga bithastigheten.
- MFPKEY_RMAX är den högsta bithastigheten för VBR-innehållet.
- MFPKEY_BMAX är det högsta buffertfönstret.
Relaterade ämnen