IMediaSample, возвращенный Sample Grabber, имеет неожиданный размер буфера
Я работал над библиотекой захвата аудио / видео для Windows, используя Media Foundation. Однако я столкнулся с проблемой, описанной в этом посте для некоторых веб-камер на Windows 8.1. Поэтому я решил использовать другую реализацию, использующую Directshow, для поддержки в моем приложении веб-камер, драйверы для которых еще не обновлены.
Библиотека работает довольно хорошо, но я заметил проблему с некоторыми веб-камерами, для которых возвращаемый образец (IMediaSample) не имеет ожидаемого размера в соответствии с форматом, который был установлен перед запуском камеры.
Например, у меня есть случай, когда набор форматов имеет подтип MEDIASUBTYPE_RGB24 (3 байта на пиксель), а размер кадра составляет 640x480. BiSizeImage (от BITMAPINFOHEADER) хорошо 640*480*3 = 921600 при применении формата. Метод IAMStreamConfig::SetFormat() успешно применяет формат.
hr = pStreamConfig->SetFormat(pmt);
Я также установил формат Sample Grabber Interface следующим образом:
hr = pSampleGrabberInterface->SetMediaType(pmt);
Я применил формат перед запуском графика.
Однако в обратном вызове (ISampleGrabberCB::SampleCB) я получаю выборку размером 230400 (которая может быть буфером для кадра размером 320x240 (320*240*3=230400)).
HRESULT MyClass::SampleCB(double sampleTime, IMediaSample *pSample)
{
unsigned char* pBuffer= 0;
HRESULT hr = pSample->GetPointer((unsigned char**) &pBuffer);
if(SUCCEEDED(hr) {
long bufSize = pSample->GetSize();
//bufSize = 230400
}
}
Я попытался исследовать тип мультимедиа, возвращенный с помощью метода IMediaSample::GetMediaType(), но тип мультимедиа равен NULL, что означает, согласно документации метода GetMediaType, что тип мультимедиа не изменился (так что, я думаю, он все еще тип мультимедиа, который я успешно применил, используя функцию IAMStreamConfig::SetFormat()).
HRESULT hr = pSample->GetMediaType(&pType);
if(SUCCEEDED(hr)) {
if(pType==NULL) {
//it enters here => the media type has not changed!
}
}
Почему размер буфера выборки не соответствует ожидаемому в этом случае? Как я могу решить эту проблему?
Заранее спасибо!
1 ответ
Пример обратного вызова Grabber всегда будет возвращать "правильный" размер с точки зрения его соответствия фактическому размеру данных и форматам, используемым в потоковом конвейере.
Если вы видите несоответствие, это означает, что топология графа фильтра отличается от ожидаемой. Вам необходимо просмотреть график (особенно с помощью удаленного подключения с помощью GraphEdit), проверить типы носителей и выяснить, почему он был построен неправильно. Например, вы можете применять интересующий вас формат после подключения контактов, что слишком поздно.
Смотрите также: