讀取現有檔案的 ASF 標頭物件
ASF ContentInfo 物件會儲存代表媒體檔案之 ASF 標頭物件的資訊。 需要填入的 ContentInfo 物件,才能讀取和剖析現有的 ASF 檔案。
藉由呼叫 MFCreateASFContentInfo 函式建立 ContentInfo 物件之後,應用程式必須使用要讀取之 ASF 檔案的標頭資訊初始化它。 若要填入物件,請呼叫 IMFASFContentInfo::P arseHeader。
ParseHeader 需要包含 ASF 檔案之 Header 物件的媒體緩衝區。 其中一個選項是使用 Header 物件填滿媒體緩衝區,以建立檔案的位元組資料流程,然後將位元組資料流程的前 30 個位元組資料讀取到媒體緩衝區。 然後,您可以將 Header 物件的前 24 個位元組傳遞至 IMFASFContentInfo::GetHeaderSize 方法,以取得大小。 取得大小之後,您可以在媒體緩衝區中讀取整個 Header 物件,並將其傳遞至 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 函式來釋放介面指標。
相關主題