Чтение объекта заголовка ASF существующего файла
Объект ASF ContentInfo хранит сведения, представляющие объекты заголовка ASF файла мультимедиа. Для чтения и анализа существующего ФАЙЛА ASF требуется заполненный объект ContentInfo.
После создания объекта ContentInfo путем вызова функции MFCreateASFContentInfo приложение должно инициализировать его с информацией о заголовке из файла ASF, который должен быть прочитан. Чтобы заполнить объект, вызовите IMFASFContentInfo::P arseHeader.
Для ParseHeader требуется буфер мультимедиа, содержащий объект заголовка файла ASF. Один из вариантов — заполнить буфер мультимедиа объектом заголовка, чтобы создать поток байтов для файла, а затем прочитать первые 30 байт данных из потока байтов в буфер мультимедиа. Затем можно получить размер, передав первые 24 байта объекта header методу IMFASFContentInfo::GetHeaderSize . Получив размер, вы можете прочитать весь объект заголовка в буфере мультимедиа и передать его в ParseHeader. Метод начинает синтаксический анализ со смещения от начала буфера мультимедиа, указанного в параметре cbOffsetWithinHeader .
В следующем примере кода создается и инициализируется объект ContentInfo для чтения существующего ФАЙЛА ASF, содержащегося в потоке байтов. Во-первых, мы определим вспомогающую функцию, которая считывает данные из байтового потока и выделяет буфер мультимедиа для хранения данных:
// Read the ASF Header Object from a byte stream and return a pointer to the
// populated ASF ContentInfo object.
//
// The current read position of the byte stream must be at the start of the
// ASF Header Object.
HRESULT CreateContentInfo(IMFByteStream *pStream,
IMFASFContentInfo **ppContentInfo)
{
const DWORD MIN_ASF_HEADER_SIZE = 30;
QWORD cbHeader = 0;
DWORD cbBuffer = 0;
IMFASFContentInfo *pContentInfo = NULL;
IMFMediaBuffer *pBuffer = NULL;
// Create the ASF ContentInfo object.
HRESULT hr = MFCreateASFContentInfo(&pContentInfo);
// Read the first 30 bytes to find the total header size.
if (SUCCEEDED(hr))
{
hr = MFCreateMemoryBuffer(MIN_ASF_HEADER_SIZE, &pBuffer);
}
if (SUCCEEDED(hr))
{
hr = ReadFromByteStream(pStream, pBuffer,MIN_ASF_HEADER_SIZE);
}
if (SUCCEEDED(hr))
{
hr = pContentInfo->GetHeaderSize(pBuffer, &cbHeader);
}
// Pass the first 30 bytes to the ContentInfo object.
if (SUCCEEDED(hr))
{
hr = pContentInfo->ParseHeader(pBuffer, 0);
}
SafeRelease(&pBuffer);
if (SUCCEEDED(hr))
{
cbBuffer = (DWORD)(cbHeader - MIN_ASF_HEADER_SIZE);
hr = MFCreateMemoryBuffer(cbBuffer, &pBuffer);
}
// Read the rest of the header and finish parsing the header.
if (SUCCEEDED(hr))
{
hr = ReadFromByteStream(pStream, pBuffer, cbBuffer);
}
if (SUCCEEDED(hr))
{
hr = pContentInfo->ParseHeader(pBuffer, MIN_ASF_HEADER_SIZE);
}
if (SUCCEEDED(hr))
{
// Return the pointer to the caller.
*ppContentInfo = pContentInfo;
(*ppContentInfo)->AddRef();
}
SafeRelease(&pBuffer);
SafeRelease(&pContentInfo);
return hr;
}
Следующий пример считывает объект заголовка ASF из потока байтов и заполняет объект ASF ContentInfo.
// Read the ASF Header Object from a byte stream and return a pointer to the
// populated ASF ContentInfo object.
//
// The current read position of the byte stream must be at the start of the
// ASF Header Object.
HRESULT CreateContentInfo(IMFByteStream *pStream,
IMFASFContentInfo **ppContentInfo)
{
const DWORD MIN_ASF_HEADER_SIZE = 30;
QWORD cbHeader = 0;
DWORD cbBuffer = 0;
IMFASFContentInfo *pContentInfo = NULL;
IMFMediaBuffer *pBuffer = NULL;
// Create the ASF ContentInfo object.
HRESULT hr = MFCreateASFContentInfo(&pContentInfo);
// Read the first 30 bytes to find the total header size.
if (SUCCEEDED(hr))
{
hr = MFCreateMemoryBuffer(MIN_ASF_HEADER_SIZE, &pBuffer);
}
if (SUCCEEDED(hr))
{
hr = ReadFromByteStream(pStream, pBuffer,MIN_ASF_HEADER_SIZE);
}
if (SUCCEEDED(hr))
{
hr = pContentInfo->GetHeaderSize(pBuffer, &cbHeader);
}
// Pass the first 30 bytes to the ContentInfo object.
if (SUCCEEDED(hr))
{
hr = pContentInfo->ParseHeader(pBuffer, 0);
}
SafeRelease(&pBuffer);
if (SUCCEEDED(hr))
{
cbBuffer = (DWORD)(cbHeader - MIN_ASF_HEADER_SIZE);
hr = MFCreateMemoryBuffer(cbBuffer, &pBuffer);
}
// Read the rest of the header and finish parsing the header.
if (SUCCEEDED(hr))
{
hr = ReadFromByteStream(pStream, pBuffer, cbBuffer);
}
if (SUCCEEDED(hr))
{
hr = pContentInfo->ParseHeader(pBuffer, MIN_ASF_HEADER_SIZE);
}
if (SUCCEEDED(hr))
{
// Return the pointer to the caller.
*ppContentInfo = pContentInfo;
(*ppContentInfo)->AddRef();
}
SafeRelease(&pBuffer);
SafeRelease(&pContentInfo);
return hr;
}
Примечание
В этих примерах функция SafeRelease используется для освобождения указателей интерфейса.
Связанные темы