2016-08-16 3 views
0

У меня есть IMFSampleGrabberSinkCallback в приложении Media Foundation, в котором я создаю активатор для использования MFCreateSampleGrabberSinkActivate. Функция получает только частично заполненный тип носителя. В рамках обратного вызова выборки захвата выполняется кодер NVENC (я знаю, что для NVENC есть готовые преобразования, но программное обеспечение не работает в Windows 10). Чтобы использовать кодировщик, мне нужно иметь полный тип носителя, который после разрешения топологии (в основном, размер кадров, который не известен при создании образца захвата).Определите разрешенный тип ввода IMFSampleGrabberSinkCallback

Кажется, нет очевидного способа получить эту информацию в IMFSampleGrabberSinkCallback, поэтому идея будет получать полную топологию из сеанса после получения MF_TOPOSTATUS_READY.

Первый вопрос: Это единственный способ получить полный тип, который получит граббер, или я что-то пропустил?

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

Второй вопрос: Какой был бы лучший способ сделать это? Для меня, похоже, нет способа получить мой IMFSampleGabberSinkCallback из узла топологии.

Я бы решил, используя идентификатор узла topo, но я не уверен, будет ли это работать в любом случае. В документации IMFTopologyNode::GetTopoNodeID указано, что

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

Для меня это не ясно, будет ли ID будет быть использован повторно, или его может быть повторно .

Третий вопрос: ли он гарантировал, что, если я получить топо идентификатор узла узла я вставляю IMFActivate, полученный из MFCreateSampleGrabberSinkActivate (и до тех пор, пока я не изменить идентификатор вручную IMFTopologyNode::SetTopoNodeID, тот же самый идентификатор будет использоваться для любой последующей топологии, созданной в процессе разрешения топологии

Спасибо заранее, Кристофа

Редактировать: вопрос не о том, как получить NVENC работать и решать его тип входа, но -й Ключевыми вопросами являются (1), гарантируются ли идентификаторы topo во время процесса разрешения и (2) есть ли лучший способ сделать это, чем следующее (что подвержено действию пользователей, которые активно изменяют идентификатор topo) : Во-первых, я создаю активатор для моего обратного вызова grabber. Как только я добавил узел, содержащий активатор в качестве объекта в топологию, я получаю его идентификатор. Когда сессия сообщает, что топология готова, я извлекаю узел с сохраненным ранее идентификатором, получаю его объект, запрашиваю его интерфейс IMFStreamSink, извлекает его IMFMediaTypeHandler, получает текущий тип носителя и получает фактический размер кадра и частоту кадров для NVENC. Но: Это работает только в том случае, если идентификатор не может меняться и не изменяется.

Я добыл этапы разрешения топологии из моего тестового кода:

Topology resolution stages

Топология распознаватель обнаруживает, что требуется преобразование цвета и добавляет синее преобразование с учетом этого. Возвращаясь к вопросам: в этом случае они будут (1) гарантировано ли, что идентификатор красного узла не может измениться во время разрешения, и (2) есть ли альтернативный способ реализовать это, что не поддается кому-либо используя IMFTopologyNode::SetTopoNodeID на красном узле.

+0

Привет, Можете ли вы сообщить правильную причину использования 'IMFSampleGrabberSinkCallback'? Это общие интерфейсы для захвата образцов. Его можно использовать для захвата декодированных изображений UNCOMPRESSED или для сжатых данных - например, JPEG-кадров из MJPG. Вы проверили документацию NVENC? –

+0

Я знаю, что есть «IMFTransform» от NVENC, но это работает только в Windows 10+. Мне нужно запустить Windows 7+. Кроме того, код работает отлично, используя размер жесткого кода. Мне просто нужен способ динамического получения типа медиа. – Christoph

+0

Какой тип MediaType вам нужен? Сжатый или несжатый? - У вас есть кодер NVENC - ему нужен два типа медиа? –

ответ

0

Из моего опыта Идентификатор узла топологии выглядит как результат хеш-функции. Я думаю, что генератор ИД имеет сложный алгоритм и не может гарантировать константу от одного сеанса к другому, но идентификатор стабилен во время текущего сеанса. Возможно, вы можете попробовать другой способ - ваш написал - «добавили узел, содержащий активатор, как объект в топологию», но что вы делаете с оригинальным указателем на «активатор для моего обратного вызова грабежа»? IMFTopologyNode::SetObject увеличивает значение IUnknown. Я думаю, что вы отпустите оригинальный указатель aктивировать, но вы можете сохранить указатель на «активаторе для моего обратного вызова граббера». В этом случае нет необходимости - «Я извлекаю узел с сохраненным ранее идентификатором, получаю его объект». После разрешения топологии вы УЖЕ можете иметь указатель на активатор с полным разрешенным MediaType и запросить его интерфейс IMFStreamSink, получить его IMFMediaTypeHandler без сохранения идентификатора узла топологии. Активатор - это прокси, но для объекта IMFMediaSink, который получен путем звонка IMFActivate::ActivateObject с IID_IMFMediaSink. В то время как он называется впервые с разрешения топологии, он создает объект с интерфейсом IMFMediaSink (который создает IMFStreamSink с внутренним внутренним пространством) в активаторе, но следующий вызов будет возвращать ссылку - ссылка активатора KEEPS по разрешенному адресу IMFMediaSink - согласно MSDN MFActivate::ActivateObject - «После первый вызов ActivateObject, последующие вызовы возвращают указатель на тот же экземпляр, пока клиент не вызовет ShutdownObject или IMFActivate::DetachObject. " Это означает, что после разрешения топологии код Microsoft НЕ ОТКЛЮЧАЕТ объект или выключает его - только закрытие сеанса выполняет ShutdownObject или IMFActivate::DetachObject.

Привет

Смежные вопросы