Создание нового объекта заголовка ASF

Чтобы преобразовать сведения, содержащиеся в объекте ContentInfo, в двоичный формат объекта заголовка ASF, приложение должно вызвать IMFASFContentInfo::GenerateHeader. Этот вызов необходимо выполнить после создания пакетов данных, а объект ContentInfo содержит обновленные сведения. GenerateHeader возвращает указатель на буфер мультимедиа, содержащий сведения о заголовке в допустимом формате. Затем приложение может записать данные, на которые указывает буфер мультимедиа, в начале нового ASF-файла.

Запись нового объекта заголовка с помощью объекта ContentInfo

  1. Вызовите MFCreateASFContentInfo , чтобы создать пустой объект ContentInfo.

  2. Вызовите IMFASFContentInfo::SetProfile , чтобы предоставить объект профиля объекту ContentInfo. Сведения о создании профилей см. в разделе Создание профиля ASF.

  3. Вызовите IMFASFContentInfo::GenerateHeader и передайте значение NULL в параметре pIHeader и получите размер заполненного объекта ContentInfo в параметре pcbHeader . Приложение может использовать это значение для выделения памяти или буфера мультимедиа, который будет содержать объект заголовка.

    Полученный размер заголовка включает размер заполнения, который корректируется в зависимости от фактического размера объектов заголовков. Максимальный размер объектов заголовков составляет 10 МБ. Если размер превышает это значение, GenerateHeader завершается ошибкой MF_E_ASF_INVALIDDATA.

  4. Вызовите MFCreateMemoryBuffer , чтобы создать буфер мультимедиа полученного размера на шаге 3.

  5. Снова вызовите GenerateHeader , чтобы создать новый объект заголовка ASF из объекта ContentInfo в буфере мультимедиа, созданном на шаге 4.

    Длина данных в буфере мультимедиа обновляется, а новый размер возвращается в параметре pcbHeader .

  6. Запишите содержимое буфера мультимедиа в начале файла. Приложение может использовать поток байтов для выполнения операции записи. Пример кода см . в разделе IMFByteStream::Write.

Пример

В следующем примере кода показано, как создать объект ContentInfo и создать буфер мультимедиа для хранения нового объекта заголовка. Полный пример использования этого кода см. в статье Руководство. Копирование потоков ASF из одного файла в другой.

//-------------------------------------------------------------------
// WriteASFFile
//
// Writes the complete ASF file.
//-------------------------------------------------------------------

HRESULT WriteASFFile( 
    IMFASFContentInfo *pContentInfo, // ASF Content Info for the output file.
    IMFByteStream *pDataStream,      // Data stream.
    PCWSTR pszFile                   // Output file name.
    )
{
    
    IMFMediaBuffer *pHeaderBuffer = NULL;
    IMFByteStream *pWmaStream = NULL;

    DWORD cbHeaderSize = 0;
    DWORD cbWritten = 0;

    // Create output file.
    HRESULT hr = MFCreateFile(
        MF_ACCESSMODE_WRITE, 
        MF_OPENMODE_DELETE_IF_EXIST,
        MF_FILEFLAGS_NONE,
        pszFile,
        &pWmaStream
        );

    // Get the size of the ASF Header Object.
    if (SUCCEEDED(hr))
    {
        hr = pContentInfo->GenerateHeader(NULL, &cbHeaderSize);
    }

    // Create a media buffer.
    if (SUCCEEDED(hr))
    {
        hr = MFCreateMemoryBuffer(cbHeaderSize, &pHeaderBuffer);
    }

    // Populate the media buffer with the ASF Header Object.
    if (SUCCEEDED(hr))
    {
        hr = pContentInfo->GenerateHeader(pHeaderBuffer, &cbHeaderSize);
    }
 
    // Write the header contents to the byte stream for the output file.
    if (SUCCEEDED(hr))
    {
        hr = WriteBufferToByteStream(pWmaStream, pHeaderBuffer, &cbWritten);
    }

    if (SUCCEEDED(hr))
    {
        hr = pDataStream->SetCurrentPosition(0);
    }

    // Append the data stream to the file.

    if (SUCCEEDED(hr))
    {
        hr = AppendToByteStream(pDataStream, pWmaStream);
    }

    SafeRelease(&pHeaderBuffer);
    SafeRelease(&pWmaStream);

    return hr;
}

Запись объекта заголовка ASF для нового файла