Выбор декодера в службах редактирования DirectShow
[Функция, связанная с этой страницей DirectShow, является устаревшей функцией. Он был заменен MediaPlayer, IMFMediaEngine, и аудио/ видео захвата в Media Foundation. Эти функции оптимизированы для Windows 10 и Windows 11. Корпорация Майкрософт настоятельно рекомендует использовать в новом коде MediaPlayer, IMFMediaEngine и аудио/видеозахват в Media Foundation вместо DirectShow, когда это возможно. Корпорация Майкрософт предлагает переписать существующий код, в котором используются устаревшие API, чтобы по возможности использовать новые API.]
[Этот API не поддерживается и может быть изменен или недоступен в будущем.]
Когда службы редактирования DirectShow (DES) отрисовывают проект редактирования видео, обработчик отрисовки автоматически выбирает необходимые декодеры. Это может произойти внутри метода IRenderEngine::ConnectFrontEnd или динамически во время отрисовки.
Пользователь может установить несколько декодеров, способных декодировать определенный файл. Если доступно несколько декодеров, DES использует алгоритм Intelligent Connect для выбора декодера.
Приложение не может напрямую указать, какой декодер следует использовать. Однако вы можете выбрать декодер косвенно с помощью интерфейса обратного вызова IAMGraphBuilderCallback . Реализуя этот интерфейс в приложении, вы можете получать уведомления во время создания графа и отклонять определенные фильтры из графа.
Начните с реализации класса, который предоставляет интерфейс IAMGraphBuilderCallback :
class GraphBuilderCB : public IAMGraphBuilderCallback
{
public:
// Method declarations (not shown).
};
Затем создайте экземпляр диспетчера фильтров Graph и зарегистрируйте класс для получения уведомлений обратного вызова:
// Declare an instance of the callback object.
GraphBuilderCB GraphCB;
// Create the Filter Graph Manager.
CComPtr<IGraphBuilder> pGraph;
hr = pGraph.CoCreateInstance(CLSID_FilterGraph);
if (FAILED(hr))
{
// Handle error (not shown).
}
// Register to receive the callbacks.
CComQIPtr<IObjectWithSite> pSite(pGraph);
if (pSite)
{
hr = pSite->SetSite((IUnknown*)&GraphCB);
}
Затем создайте обработчик отрисовки и вызовите метод IRenderEngine::SetFilterGraph с указателем на диспетчер фильтров графов. Это гарантирует, что обработчик отрисовки не создает собственный диспетчер графов фильтров, а использует экземпляр, настроенный для обратных вызовов.
CComPtr<IRenderEngine> pRender;
hr = pRender.CoCreateInstance(CLSID_RenderEngine);
if (FAILED(hr))
{
// Handle error (not shown).
}
hr = pRender->SetFilterGraph(pGraph);
При отрисовке проекта метод IAMGraphBuilderCallback::SelectedFilter приложения вызывается непосредственно перед созданием нового фильтра диспетчером фильтров Graph. Метод SelectedFilter получает указатель на интерфейс IMoniker , представляющий моникер для фильтра. Проверьте моникер и, если вы решили отклонить фильтр, верните код сбоя из метода SelectedFilter .
Трудно определить, какие моникеры представляют декодеры, и, в частности, какие моникеры представляют декодеры, которые вы хотите отклонить. Одним из решений является следующее:
Перед отрисовкой проекта используйте метод IFilterMapper2::EnumMatchingFilters , чтобы создать список фильтров, зарегистрированных как принимающее нужный тип входных данных. Для типов сжатия видео или аудио этот список должен сопоставляться с набором декодеров.
Метод EnumMatchingFilters возвращает коллекцию моникеров. Для каждого моникера в коллекции получите свойство DisplayName , как описано в разделе Использование модуля сопоставления фильтров.
Сохраните список отображаемых имен, но опустите отображаемое имя, соответствующее фильтру, который требуется использовать для декодирования. Отображаемые имена для фильтров программного обеспечения имеют следующую форму:
OLESTR("@device:sw:{CategoryGUID}\{FilterCLSID}");
where
CategoryGUID
— это GUID категории фильтра;
FilterCLSID
— идентификатор CLSID фильтра. Для МДО формат совпадает, но измените
sw
наdmo
.Теперь список содержит отображаемые имена для каждого фильтра, который выводит нужный тип мультимедиа, но не является предпочтительным фильтром.
В методе SelectedFilter получите свойство DisplayName для предлагаемого моникера и проверка его в хранимом списке. Если отображаемое имя соответствует записи в списке, отклоните этот фильтр. В противном случае примите его, возвращая S_OK.
Связанные темы