Я работаю над переводом библиотеки захвата из DirectShow в MediaFoundation. Библиотека захвата, казалось, работала довольно хорошо, но я столкнулся с проблемой встроенной веб-камеры на планшете под управлением Windows 8 32 бит.
При перечислении формата захвата (как описано в Документация Media Foundation), Я получил следующий поддерживаемый формат для камеры:
Затем я установил формат захвата, в данном случае — индекс 5, используя следующую функцию, как описано в примере:
hr = pHandler->SetCurrentMediaType(pType);
Эта функция выполнена без ошибок. Таким образом, камера должна быть настроена на съемку в формате YUY2 с разрешением 640 * 480.
в onReadSample обратный вызов, Я должен получить образец с буфером размера:
640 * 480 * sizeof(unsigned char) * 2 = 614400 //YUY2 is encoded on 2 bytes
Тем не менее, я получил образец с буфером размером 169344. Ниже приведена часть функции обратного вызова.
HRESULT SourceReader::OnReadSample(
HRESULT hrStatus,
DWORD dwStreamIndex,
DWORD dwStreamFlags,
LONGLONG llTimeStamp,
IMFSample *pSample // Can be NULL
)
{
EnterCriticalSection(&m_critsec);
if (pSample)
{
DWORD expectedBufferSize = 640*480*1*2; // = 614400 (hard code for the example)
IMFMediaBuffer* buffer = NULL;
hr = pSample->ConvertToContiguousBuffer(&buffer);
if (FAILED(hr))
{
//...
goto done;
}
DWORD byteLength = 0;
BYTE* pixels = NULL;
hr = buffer->Lock(&pixels, NULL, &byteLength);
//byteLength is 169344 instead of 614400
if (byteLength > 0 && byteLength == expectedBufferSize)
{
//do someting with the image, but never comes here because byteLength is wrong
}
//...
Любой совет, почему я получаю образец размером 169344?
заранее спасибо
Спасибо Mgetz за ваш ответ.
Я проверил значение MF_MT_INTERLACE_MODE типа мультимедиа, и оказалось, что видеопоток содержит прогрессивные кадры. Значение MF_MT_INTERLACE_MODE возвращает MFVideoInterlace_Progressive.
hr = pHandler->SetCurrentMediaType(m_pType);
if(FAILED(hr)){
//
}
else
{
//get info about interlacing
UINT32 interlaceFormat = MFVideoInterlace_Unknown;
m_pType->GetUINT32(MF_MT_INTERLACE_MODE, &interlaceFormat);
//...
Так что видео поток не чересстрочный. Я снова проверил в onReadSample значение MFSampleExtension_Interlaced, чтобы увидеть, является ли образец чересстрочным или нет, и кажется, что образец чересстрочный.
if (pSample && m_bCapture)
{
//check if interlaced
UINT32 isSampleInterlaced = 0;
pSample->GetUINT32(MFSampleExtension_Interlaced, &isSampleInterlaced);
if(isSampleInterlaced)
{
//enters here
}
Как это возможно, что поток является прогрессивным и что выборка чересстрочная? Я дважды проверил значение MF_MT_INTERLACE_MODE в обратном вызове onReadSample, и оно все еще дает мне значение MFT_INPUT_STREAM_WHOLE_SAMPLES.
Что касается вашего первого предложения, я не смог принудительно установить флаг MFT_INPUT_STREAM_WHOLE_SAMPLES во входном потоке.
заранее спасибо
Я все еще сталкиваюсь с проблемой, и сейчас я исследую различные доступные потоки.
Согласно документации, каждый медиа-источник предоставляет дескриптор представления, из которого мы можем получить доступные потоки. Чтобы получить дескриптор презентации, нам нужно позвонить:
HRESULT hr = pSource->CreatePresentationDescriptor(&pPD);
Затем я запрашиваю доступные потоки, используя функцию IMFPresentationDescriptor :: GetStreamDescriptorCount:
DWORD nbrStream;
pPD->GetStreamDescriptorCount(&nbrStream);
При запросе этой информации на фронтальной веб-камере на планшете ACER под управлением Windows 8 я обнаружил, что доступны три потока. Я зациклился на этих потоках, запросил их MediaTypeHandler и проверил MajorType. Три потока имеют основной тип: MFMediaType_Video, поэтому все потоки являются видеопотоками. При перечислении типа мультимедиа, доступного в разных потоках, я понял, что все потоки поддерживают захват в разрешении 640×480. (некоторые потоки имеют больше доступных типов мультимедиа).
Я проверил, чтобы выбрать каждый из различных потоков и соответствующий тип формата (фреймворк не вернул никакой ошибки), но я все еще не получаю правильный пример в функции обратного вызова …
Любой совет, чтобы прогрессировать в этом вопросе?
Наконец-то нашел проблему: мне пришлось напрямую установить тип носителя на читателе источника, используя SourceReader-> SetCurrentMediaType (..). Это сделало трюк!
Спасибо за вашу помощь!
Не зная, что такое дескриптор входного медиа-типа, мы можем только спекулировать, но наиболее вероятный ответ — вы говорите, что можете обрабатывать поток, хотя MFT_INPUT_STREAM_WHOLE_SAMPLES
не установлен на входном потоке.
Следующая наиболее вероятная причина переплетение в этом случае каждый кадр будет полным, но не полным разрешением, которое вы предполагаете. Независимо от того, вы должны проверить ВЕСЬ дескриптор медиа-типа до его принятия.
Наконец-то нашел проблему: мне пришлось напрямую установить тип носителя на читателе источника, используя SourceReader-> SetCurrentMediaType (..). Это сделало трюк!
Спасибо за вашу помощь!