Здравствуйте.
Появилась задача организовать ввод видеопотока с камеры с помощью Media Foundation. МС Говорит что это взамен устаревшейго DirectShow.
Но что то я не могу толком въехать как тут что работает.
В целом написал код, все подключается и идут данные, но что бы я не делал данные идут в формате MFVideoFormat_YUY2/
Задаю принудительно другой формат, проверяю он стоит правильно но все равно в колбек приходит не то количетво байт.
Код огромный попробую кусками:
extern "C" __declspec(dllexport) HRESULT StartCapture(IMFMediaSource * captureDevice, DWORD FormatIndex, bool* CancelToken, OnNewFrameCompleteDelegate newFraneEvent)
{
IMFSourceReader* pReader;
IMFAttributes* pAttributes = NULL;
// Create an attribute store to specify the enumeration parameters.
HRESULT hr = MFCreateAttributes(&pAttributes, 1);
//hr = pAttributes->SetUINT32(MF_READWRITE_DISABLE_CONVERTERS, TRUE);
//hr = pAttributes->SetUINT32(MF_SOURCE_READER_ENABLE_VIDEO_PROCESSING, TRUE);
//hr = pAttributes->SetUINT32(MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, TRUE);
hr = MFCreateSourceReaderFromMediaSource(captureDevice, NULL, &pReader);
if (FAILED(hr))
return hr;
hr = SetDeviceFormat(captureDevice, FormatIndex); // тут задаю нужный мне формат по индексу от нуля
if (FAILED(hr))
return hr;
IMFMediaType* pType = NULL; // тут специально проверяю.
hr = pReader->GetCurrentMediaType((DWORD)MF_SOURCE_READER_FIRST_VIDEO_STREAM, &pType);
LogMediaType(pType, 0, NULL); // показывает что установлен именно тот что мне нужно
hr = ProcessSamples(pReader, CancelToken, newFraneEvent);
if (FAILED(hr))
return hr;
SafeRelease(&pReader);
return hr;
}
// вот такой формат, это нулевой индекс
MF_MT_MAJOR_TYPE MFMediaType_Video
MF_MT_SUBTYPE MFVideoFormat_MJPG
MF_MT_FRAME_SIZE 3040 x 1080
MF_MT_ALL_SAMPLES_INDEPENDENT 1
MF_MT_SAMPLE_SIZE 9849600 <-- особенно тут размер кадра в формате RGB
Дальше читаю семпл
hr = pReader->ReadSample(
MF_SOURCE_READER_ANY_STREAM, // Stream index.
0, // Flags.
&streamIndex, // Receives the actual stream index.
&flags, // Receives status flags.
&llTimeStamp, // Receives the time stamp.
&pSample // Receives the sample or NULL.
);
if (FAILED(hr))
break;
if (flags & MF_SOURCE_READERF_ENDOFSTREAM)
{
cout << (L"\tEnd of stream\n") << endl;
*CancelToken = true;
}
if (pSample)
{
BYTE* data;
IMFMediaBuffer* buffer;
DWORD max, current;
pSample->GetBufferByIndex(0, &buffer);
buffer->Lock(&data, &max, ¤t); << И мот тут всегда идут не те размеры кадра что я ожидаю. Тут приходит размер 6566400
а размер 6566400 соответствует формату
MF_MT_MAJOR_TYPE MFMediaType_Video
MF_MT_SUBTYPE MFVideoFormat_YUY2
MF_MT_FRAME_SIZE 3040 x 1080
MF_MT_DEFAULT_STRIDE 6080
MF_MT_ALL_SAMPLES_INDEPENDENT 1
MF_MT_FIXED_SIZE_SAMPLES 1
MF_MT_SAMPLE_SIZE 6566400
ну вот как так то??
Может кто нибудь сможет помочь?? Вроде читал что есть какие то декодеры… или трансформаторы потока… но как его настроить и куда внедрить так и не нашел примера