Поделиться через


Использование взаимного исключения для потоков ASF

Содержимое ASF может содержать несколько потоков, которые являются взаимоисключающими. Эти потоки нельзя считывать одновременно, но одновременно считывается только один из них. Например, файл может содержать набор потоков, включающих одно и то же содержимое, закодированное по другой скорости. Используемый поток определяется пропускной способностью, доступной приложению, который передает содержимое. Объект взаимного исключения ASF, являющийся частью объекта заголовка, сохраняет сведения о группе взаимоисключающих потоков.

В Media Foundation объект взаимное исключение, предоставляющий интерфейс МВФASFMutualExclusion существует для каждого объекта взаимного исключения ASF. Объект профиля содержит ссылку на все объекты взаимного исключения.

Объект взаимного исключения хранит сведения о группе взаимоисключающих потоков в виде записей. Объект взаимного исключения может содержать несколько записей, которые можно использовать для создания сложных сценариев. Каждая запись содержит один или несколько потоков, которые не могут сосуществовать с потоками в другой записи, поддерживаемой объектом взаимного исключения, в зависимости от типа взаимного исключения, например скорости битов.

Типичным примером сложного взаимного исключения является файл, содержащий три аудиопотока одного и того же содержимого с различными скоростями в каждом из трех языков. Одновременно должен воспроизводиться только один из девяти потоков, но есть два типа, по которым они являются взаимоисключающими: язык и скорость передачи.

В этом примере девяти потокам назначены следующие номера:

1 - Язык 1, битрейт 1 2 - Язык 1, битрейт 2 3 - Язык 1, битрейт 3 4 - Язык 2, битрейт 1 5 - Язык 2, битрейт 2 6 - Язык 2, битрейт 3 7 - Язык 3, битрейт 1 8 - Язык 3, битрейт 2 9 - Язык 3, битрейт 3

Этот сценарий можно реализовать с помощью следующих четырех объектов взаимного исключения:

  • Первый объект взаимного исключения включает потоки 1, 2 и 3, взаимоисключающие по скорости. Каждый поток имеет собственную запись.
  • Второй объект взаимного исключения включает потоки 4, 5 и 6, взаимоисключающие по скорости. Каждый поток имеет собственную запись.
  • Третий объект взаимного исключения включает 7, 8 и 9, которые взаимоисключаются по битрейту. Каждый поток имеет собственную запись.
  • Четвертый объект взаимного исключения содержит три записи, в том числе потоки 1, 2 и 3; второй, включая потоки 4, 5 и 6; и третье, включая потоки 7, 8 и 9. Эти записи являются взаимоисключающими по языку.

При воспроизведении файла, созданного таким образом, приложение потоковой передачи сначала выбирает язык, так как он меньше шансов измениться в середине презентации, а затем выбирает скорость передачи.

Создание и настройка объектов взаимного исключения

В следующем списке приводится сводка процесса настройки объекта взаимного исключения:

  1. Создайте объект взаимного исключения.
  2. Задайте тип взаимного исключения.
  3. Настройте объект взаимного исключения, добавив записи и связанные потоки.
  4. Добавьте объект взаимного исключения в профиль.

Создание и настройка объекта взаимного исключения

  1. Вызовите IMFASFProfile::CreateMutualExclusion для создания пустого объекта взаимного исключения.

  2. Вызовите IMFASFMutualExclusion::SetType, чтобы установить критерий взаимного исключения потока.

    Потоки могут быть взаимоисключающими по языку, скорости передачи, презентации и пользовательским критериям. Тип представлен в виде GUID. Список этих констант см. в разделе идентификаторы GUID типа взаимоисключения ASF.

  3. Вызовите IMFASFMutualExclusion::AddRecord, чтобы добавить запись в объект взаимного исключения.

    Этот метод добавляет пустую запись и назначает его индекс записи, начиная с нуля.

  4. Вызовите IMFASFMutualExclusion::AddStreamForRecord, чтобы добавить номер потока к записи, указанной индексом записи.

    Каждая запись включает один или несколько потоков. Каждый поток в записи является взаимоисключающим из всех потоков в каждой другой записи. Чтобы получить количество потоков в записи, вызовите IMFASFMutualExclusion::GetStreamsForRecord, указав индекс записи.

    Чтобы удалить поток из записи, вызовите МВФASFMutualExclusion::RemoveStreamFromRecord и укажите индекс записи и номер потока.

  5. Вызовите IMFASFProfile::AddMutualExclusion, чтобы добавить настроенный объект взаимного исключения в профиль.

Перечисление объектов взаимного исключения в профиле

Если функция ASFProfile::AddMutualExclusion выполняется успешно, она назначает индекс указанному объекту, начиная с нуля.

Чтобы перечислить объекты взаимного исключения, связанные с профилем, вызовите IMFASFProfile::GetMutualExclusionCount и пройдите по списку, вызвав МВФASFProfile::GetMutualExclusion. Индексы взаимных исключений являются последовательными и располагаются в диапазоне от 0 до значения, на единицу меньшего, чем количество потоков, полученных с помощью GetMutualExclusionCount.

Объект взаимного исключения удаляется из профиля путем вызова IMFASFProfile::RemoveMutualExclusion. Профиль переназначает индексы взаимных исключений, чтобы они были последовательными, начиная с нуля. Это перезаписывает ранее сохраненные индексы, которые больше не являются допустимыми после вызова этого метода. Это освобождает связанные записи о потоках взаимоисключения.

Удаление записей в объекте взаимного исключения

Чтобы удалить запись из объекта взаимного исключения, вызовите IMFASFMutualExclusion::RemoveRecord. Если этот метод выполнен успешно, объект взаимного исключения индексирует оставшиеся записи таким образом, чтобы они были последовательными, начиная с нуля. Приложение должно перечислить записи, чтобы обеспечить правильный индекс для каждой записи. Для этого вызовите IMFASFMutualExclusion::GetRecordCount и пройдите по записям, вызвав IMFASFMutualExclusion::GetStreamsForRecord.

Удаление записи с наибольшим индексом не влияет на другие индексы.

Изменение объекта взаимного исключения

Чтобы изменить конфигурацию объекта взаимного исключения в профиле, приложение должно заменить существующий объект взаимного исключения другим объектом, содержащим новые параметры.

Изменение конфигурации объекта взаимного исключения в профиле

  1. Перечислите объекты взаимного исключения в профиле, чтобы получить объект, который необходимо изменить.

  2. Вызовите IMFASFMutualExclusion::Clone, чтобы клонировать объект взаимоисключения.

  3. Настройте клонированные объекты по мере необходимости.

  4. Вызовите IMFASFProfile::RemoveMutualExclusion, чтобы удалить старый объект взаимного исключения из профиля.

  5. Вызовите IMFASFProfile::AddMutualExclusion, чтобы добавить обновленный объект взаимного исключения в профиль.

Профиль ASF