Цветовой формат скрытого потока камеры IMFTransform, IMFTransform::ProcessOutput возвращает данные стоп-кадра
Я очень новичок в Windows Media Foundation API. Я пытаюсь создать программу, которая может отображать и управлять потоком видео с камеры.
Я использую Media Foundation для чтения видеопотока, поддерживаемый цветовой формат NV12
поэтому мне пришлось преобразовать его в RGB
или же ARGB
создать объект текстуры OpenGL.
Я пытался сделать это, используя чистый код C++ на стороне процессора, но производительность очень плохая. Тогда я попытался использовать IMFTranform
чтобы сделать преобразование цветов, производительность очень хорошая, но у меня возникла странная проблема.IMFTransform::Process
возвращается S_OK
, но я продолжаю получать остановленное изображение. Пиксель конечного изображения не обновляется в реальном времени, он замораживается для многих кадров, а время замораживания становится все длиннее и длиннее. Если я использую чистый код C++ для преобразования цветов, то все работает нормально.
Вот мой код, https://gist.github.com/zhiqiang-li/16d1a6a1b00e8fb39847c8ca323b5604. Пожалуйста, дайте мне знать, что вы думаете, я делаю не так.
1 ответ
Вы пытались позволить SourceReader выполнить преобразование за вас:
hr = mAttributes->SetUINT32(MF_READWRITE_DISABLE_CONVERTERS, FALSE);
По умолчанию считыватель источника и приемник могут выполнять некоторые преобразования формата в несжатых аудио- и видеопотоках. Чтобы отключить это поведение, установите для этого атрибута значение ИСТИНА, когда вы создаете средство чтения или записи приемника.
По умолчанию это FALSE, поэтому вам не нужно явно устанавливать этот атрибут.
Затем:
hr = mSourceReader->SetCurrentMediaType((DWORD)MF_SOURCE_READER_FIRST_VIDEO_STREAM, NULL, mediaType);
с:
mOutputMediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_NV12);
Также рассчитайте размер изображения в соответствии с форматом NV12 (MF_MT_FRAME_SIZE). Не устанавливайте MF_MT_DEFAULT_STRIDE, SourceReader сделает это за вас.
Таким образом, идея состоит в том, чтобы получить формат NV12 из SourceReader, даже если источник захвата предоставляет формат RGB32. SourceReader обычно может это сделать.