Sink Writer от Media Foundation - это упрощенный API, в котором вопрос конфигурации энкодера упущен. Фундаментальная проблема здесь заключается в том, что у вас нет MFT кодировщика, и вы получаете к нему доступ через голову автора, тогда поведение кодировщиков при изменении настроек после того, как все настроено, зависит от реализации, которая в случае кодировщика зависит от конкретной реализации поставщика. и может варьироваться в зависимости от оборудования.
Более надежный вариант - напрямую управлять кодированием MFT и снабжать Sink Writer уже закодированным видео.
Ваша потенциальная уловка, чтобы заставить вещи работать с меньшими усилиями, - это также извлечь и очистить IMFTransform
кодировщика, а затем вернуть обратно типы входных / выходных носителей после того, как вы закончили с ICodecAPI
обновлением. Сдвигая типы носителей, вы предлагаете, чтобы кодировщик перенастроил внутренние компоненты, и он сделал бы это уже с вашими настройками. Обратите внимание, что это, вообще говоря, может иметь побочные проблемы.
Эта хитрость работает для некоторых параметров ICodecAPI (например, CODECAPI_AVEncCommonQualityVsSpeed) и только для кодера h.264 от Microsoft. Не влияет на CODECAPI_AVEncH264CABACEnable. Документ действительно предназначен для кодировщика Microsoft и не является универсальным API. Я использую кодеки QuickSync и NVidia. Знаете ли вы, настраиваются ли они через ICodecAPI, если я создаю MFT самостоятельно?
Поставляемые поставщиком кодировщики подпадают под требования Сертифицированный аппаратный кодировщик , поэтому они должны поддерживать значения ICodecAPI
, указанные в статье MSDN. Важно то, что не определен порядок вызовов конфигурации. Если вы сами управляете кодировщиком, вы должны выполнить настройку ICodecAPI
перед настройкой типов носителей. В сценарии Sink Writer он уже настроил типы носителей, после чего вы переходите к тонкой настройке. Следовательно, мое предложение об уловке включает в себя часть сброса существующих типов носителей. Поскольку этот трюк чувствителен к деталям реализации, я бы посоветовал получить текущие типы носителей, затем очистить их на MFT, выполнить ICodecAPI
и вернуть типы. Я предполагаю, что это должно работать в большем количестве сценариев, а не только в кодировщике MS. Все же это все еще остается ненадежным взломом.
IMO Реализация кодировщика Nvidia ужасна (наихудшая среди поставщиков), Intel лучше, но у нее все еще есть свои проблемы. Опять же, IMO, MFT предоставляются только для того, чтобы соответствовать минимальным требованиям сертификации для аппаратного кодирования видео, и по этой причине их реализация плохо согласована. Различные программные пакеты предпочитают реализовывать кодирование видео через SDK производителя, а не через интерфейс Media Foundation Transform. В одном из проектов я также пропустил идею использования MFT для кодирования и реализовал свои собственные MFT поверх SDK поставщиков.
Будет ли подход фабрики классов в этом посте работать с IMFSinkWriter
? Это позволит избежать написания слишком большого количества кода ...
Полагаю, да, это должно сработать, хотя я чувствую, что это не очень приятная работа - исправлять это таким образом. Также вам может понадобиться принять во внимание поддержку кодеров HW, потому что Sink Writer также имеет тенденцию использовать аппаратное кодирование в некоторых случаях, включая сценарий, когда ему предоставляется устройство DXGI.
Еще один вид взлома, который похож, но, возможно, немного менее навязчив (хотя в его реализации вам нужно было бы лучше понять внутреннее устройство), заключается в переопределении конкретных CLSID кодировщика поставщика в пределах области инициализации Sink Writer. Существует всего три кодера (AMD, Intel, Nvidia; хорошо, четвертый от Shanghai Zhaoxin Semiconductor, но он не очень популярен), и их CLSID известны. Если вы умно CoRegisterClassObject
, вы можете подключить MFT-инстанцирование, чтобы Media Foundation решал, какой кодировщик выбрать. Это просто еще одна идея, поэтому она может зависеть от того, что лучше всего делать, от других факторов.