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


QueryAccept (внизу)

[Функция, связанная с этой страницей, DirectShow, является устаревшей функцией. Он был заменен MediaPlayer, IMFMediaEngineи аудио и видеозахват в Media Foundation. Эти функции оптимизированы для Windows 10 и Windows 11. Корпорация Майкрософт настоятельно рекомендует использовать новый код MediaPlayer, IMFMediaEngine и аудио-видеозахват в Media Foundation вместо DirectShowпо возможности. Корпорация Майкрософт предлагает, что существующий код, использующий устаревшие API, будет перезаписан для использования новых API, если это возможно.]

Этот механизм позволяет пин-коду вывода предложить новый формат для его нижнего однорангового узла. Новый формат не должен требовать большего размера буфера. Выходной закрепление выполняет следующее:

  1. Вызывает IPin::QueryAccept или IPinConnection::D ynamicQueryAccept на нижнем пин-коде, чтобы проверить, может ли другой пин-код принять новый тип носителя (см. рисунок, шаг A).

  2. Если возвращаемое значение из шага 1 S_OK, закрепление присоединяет тип носителя к следующему образцу. Для этого сначала вызывается IMemAllocator::GetBuffer для получения примера (B). Затем он вызывает IMediaSample::SetMediaType для подключения типа носителя к этому образцу (C). Подключив тип носителя к образцу, фильтр указывает, что формат изменился, начиная с этого примера.

  3. Пин-код предоставляет пример (D).

  4. Когда подчиненный фильтр получает пример, он вызывает IMediaSample::GetMediaType для получения нового типа мультимедиа.

    queryaccept (внизу)

Все закрепления поддерживают метод QueryAccept. Однако этот метод немного неоднозначный, так как возвращаемое значение S_OK не всегда гарантирует, что формат можно изменить, пока граф активен. Некоторые фильтры могут возвращать S_OK но отклонять изменение, если граф активен. Метод DynamicQueryAccept, который поддерживается некоторыми входными закреплениями, явно определяет S_OK, чтобы означать, что пин-код может изменять форматы во время активности. Если входной пин-код поддерживает интерфейс IPinConnection, следует вызывать DynamicQueryAccept, а не QueryAccept.

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

Примечание о реализации

В базовых классах DirectShow CBasePin::QueryAccept вызывает метод CheckMediaType, который также вызывается во время первоначального подключения к закреплению. В случае фильтра преобразования метод ввода CheckMediaType должен всегда проверять, подключен ли выходной пин-код, а если да, то совместим ли тип входного носителя с типом выходного носителя. Поэтому эта реализация, скорее всего, будет допустимой для QueryAccept. В противном случае необходимо переопределить QueryAccept, чтобы выполнить все необходимые дополнительные проверки. Кроме того, обратите внимание, что класс CTransformFilter инкапсулирует эту логику в методах CheckInputType и CheckTransform. С другой стороны, класс CTransInPlaceFilter всегда вызывает QueryAccept в следующем вышестоящем или нижнем фильтре.

Метод CBaseInputPin::Receive проверяет тип носителя в входящем примере, а если есть один, вызывает CheckMediaType. Однако он не обновляет элемент m_mt пин-кода, который содержит текущий тип носителя. При обработке примера фильтра необходимо проверить образец типа носителя. Если есть новый тип, возможно, потребуется сохранить его, вызвав SetMediaType на пин-коде или установив значение m_mt напрямую. С другой стороны, класс CVideoTransformFilter, предназначенный для фильтров преобразования видео, сохраняет тип мультимедиа при изменении. Дополнительные сведения см. в исходном коде для CVideoTransformFilter::Receive в библиотеке базовых классов DirectShow.

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