#frame-rate #ms-media-foundation #webcam-capture
#частота кадров #ms-media-foundation #веб-камера-захват
Вопрос:
Я видел другие вопросы, но у меня почему-то не получается. Среда: Windows 10 MediaFoundation / SourceReader в асинхронном режиме., веб-камера Logitech C922 1080p pro.
Проблема:
-
Я пытаюсь прочитать веб-камеру с помощью media foundation в асинхронном режиме с помощью sourcereader. Меня
::OnReadSample()
вызывают с частотой 60-65 мс вместо ожидаемых 33,33 мс для 30 кадров в секунду. -
Проверено
hr = m_pReader->GetCurrentMediaType(
(DWORD)MF_SOURCE_READER_FIRST_VIDEO_STREAM,
amp;pType
);
и атрибуты печати для pType, которые MF_MT_FRAME_RATE
равны 30 x 1. Оба MIN
и MAX RANGE
также равны 30 x 1.
- Также проверено в
::OnReadSample()
обратном вызове, что тип среды такой же. Для streamflags не заданMF_SOURCE_READERF_CURRENTMEDIATYPECHANGED
бит. Таким образом, currentmediatype внутренне не изменился.
hr = m_pReader->GetCurrentMediaType(
(DWORD)MF_SOURCE_READER_FIRST_VIDEO_STREAM,
amp;pt
);
- Я установил fps даже с помощью
https://learn.microsoft.com/en-us/windows/win32/medfound/how-to-set-the-video-capture-frame-rate точная функция на странице выше, но все равно она вызывается каждые 64 мсек или около того.
Ниже приведен снимокpType
используемого.
MF_MT_FRAME_SIZE 640 x 480
MF_MT_AVG_BITRATE 147456000
MF_MT_YUV_MATRIX 2
MF_MT_MAJOR_TYPE MFMediaType_Video
MF_MT_VIDEO_LIGHTING 3
MF_MT_DEFAULT_STRIDE 1280
MF_MT_VIDEO_CHROMA_SITING 6
MF_MT_AM_FORMAT_TYPE {F72A76A0-EB0A-11D0-ACE4-0000C0CC16BA}
MF_MT_FIXED_SIZE_SAMPLES 1
MF_MT_VIDEO_NOMINAL_RANGE 2
MF_MT_FRAME_RATE 30 x 1
MF_MT_PIXEL_ASPECT_RATIO 1 x 1
MF_MT_ALL_SAMPLES_INDEPENDENT 1
MF_MT_FRAME_RATE_RANGE_MIN 30 x 1
MF_MT_SAMPLE_SIZE 614400
MF_MT_VIDEO_PRIMARIES 2
MF_MT_INTERLACE_MODE 2
MF_MT_FRAME_RATE_RANGE_MAX 30 x 1
MF_MT_SUBTYPE MFVideoFormat_YUY2
Пожалуйста, предложите, чего может не хватать в таком случае. Я как бы получаю 15 кадров в секунду вместо запрашиваемых 30 кадров в секунду. Я перечислил типы носителей устройства, и оно поддерживает 30 кадров в секунду.
Заранее спасибо.
Комментарии:
1. В условиях низкой освещенности камера может выдавать меньше кадров. Попробуйте указать его на какое-нибудь светлое место, чтобы исключить это для начала.
2. @RomanR. Большое спасибо. Вы правы. Действительно, это была проблема. Когда я тестировал в ярком освещенном солнцем месте, я получал действительно кадры каждые 32-33 мс. Это было мое ожидание.. Есть идеи, как заставить получать 30 кадров в секунду даже в условиях низкой освещенности?
3. Я не думаю, что вы можете заблокировать затвор / экспозицию на таком устройстве. Вам нужна специализированная камера, где такая возможность существует. То, что вы видите, — это увеличенная экспозиция, которая делает невозможным полную частоту кадров. Когда вы добавляете свет и настраиваете камеру для сокращения времени экспозиции отдельных кадров, оно может составлять полные 30.
Ответ №1:
Вероятно, это связано с тем, что вы устанавливаете скорректированный тип носителя IMFSourceReader
вместо обработчика для IMFMediaSource
.
Ниже приведен фрагмент из полного рабочего примера. Обратите внимание, что заданный тип носителя включен pSourceMediaTypeHandler
, а не pVideoReader
включен. Смотрите Пример исходного кода для объявлений переменных и т. Д.
// ----- Set up webcam video source. -----
CHECK_HR(GetVideoSourceFromDevice(WEBCAM_DEVICE_INDEX, amp;pVideoSource, amp;pVideoReader),
"Failed to get webcam video source.");
CHECK_HR(pVideoReader->SetStreamSelection((DWORD)MF_SOURCE_READER_FIRST_VIDEO_STREAM, TRUE),
"Failed to set the first video stream on the source reader.");
CHECK_HR(pVideoSource->CreatePresentationDescriptor(amp;pSourcePresentationDescriptor),
"Failed to create the presentation descriptor from the media source.");
CHECK_HR(pSourcePresentationDescriptor->GetStreamDescriptorByIndex(0, amp;fSelected, amp;pSourceStreamDescriptor),
"Failed to get source stream descriptor from presentation descriptor.");
CHECK_HR(pSourceStreamDescriptor->GetMediaTypeHandler(amp;pSourceMediaTypeHandler),
"Failed to get source media type handler.");
DWORD srcMediaTypeCount = 0;
CHECK_HR(pSourceMediaTypeHandler->GetMediaTypeCount(amp;srcMediaTypeCount),
"Failed to get source media type count.");
// ----- Attempt to set the desired media type on the webcam source. -----
CHECK_HR(MFCreateMediaType(amp;pWebcamSourceType), "Failed to create webcam output media type.");
CHECK_HR(FindMatchingVideoType(pSourceMediaTypeHandler, WEBCAM_PIXEL_FORMAT, VIDEO_WIDTH, VIDEO_HEIGHT, VIDEO_FRAME_RATE, pWebcamSourceType),
"No matching webcam media type was found.");
// This check is not necessary if the media type was from the list of supported types.
// It is useful if the media type is constructed manually. It is left here for demonstration purposes.
CHECK_HR(pSourceMediaTypeHandler->IsMediaTypeSupported(pWebcamSourceType, amp;pWebCamMatchingType), "Webcam does not support requested options.");
if (pWebCamMatchingType != NULL) {
// If IsMediaTypeSupported supplied us with the closest matching media type use that.
CHECK_HR(pSourceMediaTypeHandler->SetCurrentMediaType(pWebCamMatchingType), "Failed to set media type on source.");
}
else {
// If IsMediaTypeSupported did not supply us a new type the typ checked must have been good enough use that.
CHECK_HR(pSourceMediaTypeHandler->SetCurrentMediaType(pWebcamSourceType), "Failed to set media type on source.");
}
CHECK_HR(pSourceMediaTypeHandler->GetCurrentMediaType(amp;pVideoSourceOutputType),
"Error retrieving current media type from first video stream.");
std::cout << "Webcam media type:" << std::endl;
std::cout << GetMediaTypeDescription(pVideoSourceOutputType) << std::endl << std::endl;
Я использовал этот пример, чтобы подтвердить, что мне удалось установить частоту кадров на моем Logitech C920 на 5 кадров в секунду и получить правильную частоту дискретизации в цикле чтения исходного кода.
Attempting to convert sample, sample duration 2000000, sample time 863168227222, evr timestamp 0.
Attempting to convert sample, sample duration 2000000, sample time 863170145312, evr timestamp 2000000.
Attempting to convert sample, sample duration 2000000, sample time 863172227244, evr timestamp 4000000.
Attempting to convert sample, sample duration 2000000, sample time 863174144901, evr timestamp 6000000.
Attempting to convert sample, sample duration 2000000, sample time 863176225938, evr timestamp 8000000.
Attempting to convert sample, sample duration 2000000, sample time 863178147388, evr timestamp 10000000.
Attempting to convert sample, sample duration 2000000, sample time 863180225543, evr timestamp 12000000.
Комментарии:
1. спасибо за ваш ответ. пожалуйста, попробуйте увеличить частоту кадров в секунду, скажем, 30 кадров в секунду, и соблюдайте то же самое. Как римский. R указал, что мой тот же код без каких-либо изменений выдает 15 кадров в секунду в условиях низкой освещенности и 30 кадров в секунду при хорошем освещении. Таким образом, похоже, что веб-камера не имеет постоянного fps, но также зависит от условий освещения. Спасибо