Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
ASF-splitter- objekt är en WMContainer-lagerkomponent som parsar ASF-dataobjektet i en ASF-fil (Advanced Systems Format).
Innan datapaket skickas till splittern måste programmet initiera, konfigurera och välja strömmar på splittern för att förbereda det för parsningsprocessen. För information, se Skapa ASF-avdelningsobjektet och Konfigurera ASF-avdelningsobjektet.
De metoder som krävs för att parsa ASF-dataobjektet är:
- IMFASFSplitter::ParseData som startar parsningsprocessen genom att pusha bufferten som innehåller datapaket till splittern.
- IMFASFSplitter::GetNextSample som samlar in strömexempel som genererades från bufferten som skickades till splittern.
Hitta dataförskjutningen
Innan du påbörjar parsningsprocessen måste programmet hitta dataobjektet i ASF-filen. Det finns två sätt att få förskjutningen av dataobjektet från början av filen:
Innan du har initierat ContentInfo-objektet kan du anropa metoden IMFASFContentInfo::GetHeaderSize. Den här metoden kräver en buffert som innehåller de första 30 byteen i ASF-huvudet. Den returnerar storleken på hela huvud som anger förskjutningen till det första datapaketet. Det här värdet innehåller även huvudstorleken för dataobjektet på 50 byte.
När du har initierat ContentInfo-objektet kan du hämta presentationsbeskrivningen genom att anropa IMFASFContentInfo::GeneratePresentationDescriptoroch sedan fråga presentationsbeskrivningen för attributet MF_PD_ASF_DATA_START_OFFSET. Värdet för det här attributet är sidhuvudstorleken.
Not
Attributet MF_PD_ASF_DATA_LENGTH i presentationsbeskrivningen anger längden på ASF-dataobjektet.
I båda fallen är det returnerade värdet storleken på rubrikobjektet plus storleken på rubrikavsnittet i dataobjektet. Därför är det resulterande värdet förskjutningen till början av datapaketen i ASF-dataobjektet. När du börjar skicka data till splittern måste data börja vid offsetet från början av ASF-filen.
Förskjutningsvärdet skickas som en parameter till ParseData som startar parsningsprocessen.
Dataobjektet är indelat i datapaket. Varje datapaket innehåller ett datapakethuvud som tillhandahåller paketparsinginformation och nyttolastdata – faktiska digitala mediedata. I ett sökscenario kanske applikationen vill att splittern ska börja tolka vid ett visst datapaket. För att göra detta kan du använda ASF-indexeraren, som används för att hämta förskjutningen. Indexeraren returnerar ett förskjutningsvärde som börjar vid paketgränsen. Om du inte använder indexeraren kontrollerar du att förskjutningen börjar i början av datapaketrubriken. Om en ogiltig förskjutning skickas till splittern, till exempel att värdet inte pekar vid paketgränsen, lyckas anropen till ParseHeader och GetNextSample, men GetNextSample hämtar inga prover och NULL mottas i pSample-parametern.
Om splittern har konfigurerats för att parsa i omvänd riktning börjar splittern alltid parsa i slutet av mediebufferten som skickas till ParseData. För omvänd parsning i anropet till ParseDataskickar du därför förskjutningen i parametern cbLength, som anger längden på data och anger cbBufferOffset till noll.
Generera exempel för ASF-datapaket
Ett program startar parsningsprocessen genom att skicka datapaketen till splittern. Indata till splittern är en serie mediebuffertar som innehåller hela eller fragment av dataobjektet. Utdata från splittern är en serie mediaexempel som innehåller paketdata.
Om du vill skicka indata till splittern skapar du en mediebuffert och fyller den med data från avsnittet Dataobjekt i ASF-filen. (Mer information om mediebuffertar finns i Mediebuffertar.) Skicka sedan mediebufferten till metoden IMFASFSplitter::P arseData. Du kan också ange:
- Förskjutningen till bufferten där splittern ska börja parsa. Om förskjutningen är noll börjar parsningen i början av bufferten. Information om hur du ställer in dataförskjutningen finns i avsnittet "Att hitta dataförskjutning" i detta ämne.
- Mängden data som ska parsas. Om det här värdet är noll parsar splittern tills den når slutet av bufferten, enligt vad som anges av metoden IMFMediaBuffer::GetCurrentLength.
Splittern genererar medieexempel genom att referera till data i mediebuffertarna. Klienten kan hämta utdataexemplet genom att anropa IMFASFSplitter::GetNextSample i en loop tills det inte finns några fler data att parsa. Om GetNextSample- returnerar flaggan ASF_STATUSFLAGS_INCOMPLETE i parametern pdwStatusFlags innebär det att det finns fler exempel att hämta och programmet kan anropa GetNextSample igen. Annars, anropa ParseData för att mata in mer data till splittern. För de genererade exemplen anger splittern följande information:
- Delningsfunktionen anger en tidsstämpel för alla exempel som genereras. Exempeltiden representerar presentationstiden och inkluderar inte förregistreringstiden. Programmet kan anropa IMFSample::GetSampleTime för att få presentationstiden i 100 nanosekunder.
- Om en paus inträffar under exempelgenereringen anger delningsfunktionen attributet MFSampleExtension_Discontinuity i det första exemplet efter diskontinuiteten. Avbrott orsakas vanligtvis av borttagna paket på en nätverksanslutning, skadade fildata eller att en splitter byter från en källström till en annan.
- För video kontrollerar splittern om provet innehåller en nyckelram. Om den gör det, anger splittern attributet MFSampleExtension_CleanPoint på provet.
Om splittern parsar datapaket som tas emot från en medieserver är det möjligt att paketlängden är variabel. I det här fallet måste klienten anropa ParseData för varje paket och ange attributet MFASFSPLITTER_PACKET_BOUNDARY för varje buffert som skickas till delningsfunktionen. Det här attributet anger för splittern om mediebufferten innehåller början av ett ASF-paket. Ange attributet till TRUE om bufferten innehåller början av ett nytt paket. Om bufferten innehåller en fortsättning på föregående paket anger du attributet till FALSE. Buffertarna kan inte sträcka sig över flera paket.
Innan du skickar nya mediebuffertar till splittern måste programmet anropa IMFASFSplitter::Flush. Den här metoden återställer splittern och rensar alla ofullständiga bildrutor som väntar på att bli slutförda. Detta är användbart i ett sökscenario där förskjutningen finns på en annan plats.
Exempel
I följande kodexempel visas hur du parsar datapaket. Det här exemplet parsar från början av dataobjektet till slutet av dataströmmen och visar information om de exempel som innehåller nyckelramar. Ett fullständigt exempel som använder den här koden finns i Självstudie: Läsa en ASF-fil.
// Parse the video stream and display information about the video samples.
//
// The current read position of the byte stream must be at the start of the ASF
// Data Object.
HRESULT DisplayKeyFrames(IMFByteStream *pStream, IMFASFSplitter *pSplitter)
{
const DWORD cbReadSize = 2048; // Read size (arbitrary value)
IMFMediaBuffer *pBuffer = NULL;
IMFSample *pSample = NULL;
HRESULT hr = S_OK;
while (SUCCEEDED(hr))
{
// The parser must get a newly allocated buffer each time.
hr = MFCreateMemoryBuffer(cbReadSize, &pBuffer);
if (FAILED(hr))
{
break;
}
// Read data into the buffer.
hr = ReadFromByteStream(pStream, pBuffer, cbReadSize);
if (FAILED(hr))
{
break;
}
// Get the amound of data that was read.
DWORD cbData;
hr = pBuffer->GetCurrentLength(&cbData);
if (FAILED(hr))
{
break;
}
if (cbData == 0)
{
break; // End of file.
}
// Send the data to the ASF splitter.
hr = pSplitter->ParseData(pBuffer, 0, 0);
SafeRelease(&pBuffer);
if (FAILED(hr))
{
break;
}
// Pull samples from the splitter.
DWORD parsingStatus = 0;
do
{
WORD streamID;
hr = pSplitter->GetNextSample(&parsingStatus, &streamID, &pSample);
if (FAILED(hr))
{
break;
}
if (pSample == NULL)
{
// No samples yet. Parse more data.
break;
}
if (IsRandomAccessPoint(pSample))
{
DisplayKeyFrame(pSample);
}
SafeRelease(&pSample);
} while (parsingStatus & ASF_STATUSFLAGS_INCOMPLETE);
}
SafeRelease(&pSample);
SafeRelease(&pBuffer);
return hr;
}
Relaterade ämnen