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


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

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

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

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

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

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

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 , указав индекс записи.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Профиль ASF