Media Foundation onReadSample неверный размер возвращаемого образца

Я работаю над переводом библиотеки захвата из DirectShow в MediaFoundation. Библиотека захвата, казалось, работала довольно хорошо, но я столкнулся с проблемой встроенной веб-камеры на планшете под управлением Windows 8 32 бит.

При перечислении формата захвата (как описано в Документация Media Foundation), Я получил следующий поддерживаемый формат для камеры:

  • 0: MFVideoFormat_NV12, разрешение: 448×252, частота кадров: 30000×1001
  • 1: MFVideoFormat_YUY2, разрешение: 448×252, частота кадров: 30000×1001
  • 2: MFVideoFormat_NV12, разрешение: 640×360, частота кадров: 30000×1001
  • 3: MFVideoFormat_YUY2, разрешение: 640×360, частота кадров: 30000×1001
  • 4: MFVideoFormat_NV12, разрешение: 640×480, частота кадров: 30000×1001
  • 5: MFVideoFormat_YUY2, разрешение: 640×480, частота кадров: 30000×1001

Затем я установил формат захвата, в данном случае — индекс 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 (..). Это сделало трюк!

Спасибо за вашу помощь!

3

Решение

Не зная, что такое дескриптор входного медиа-типа, мы можем только спекулировать, но наиболее вероятный ответ — вы говорите, что можете обрабатывать поток, хотя MFT_INPUT_STREAM_WHOLE_SAMPLES не установлен на входном потоке.

Следующая наиболее вероятная причина переплетение в этом случае каждый кадр будет полным, но не полным разрешением, которое вы предполагаете. Независимо от того, вы должны проверить ВЕСЬ дескриптор медиа-типа до его принятия.

1

Другие решения

Наконец-то нашел проблему: мне пришлось напрямую установить тип носителя на читателе источника, используя SourceReader-> SetCurrentMediaType (..). Это сделало трюк!

Спасибо за вашу помощь!

1

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector