Media Foundation установил чересстрочную развертку и декодирование видео

У меня есть файл MOV, и я хочу декодировать его и иметь все кадры как отдельные изображения.

Поэтому я пытаюсь настроить несжатый тип носителя следующим образом:

// configure the source reader
IMFSourceReader* m_pReader;
MFCreateSourceReaderFromURL(filePath, NULL, &m_pReader);

// get the compressed media type
IMFMediaType* pFileVideoMediaType;
m_pReader->GetCurrentMediaType(MF_SOURCE_READER_FIRST_VIDEO_STREAM, &pFileVideoMediaType);

// create new media type for uncompressed type
IMFMediaType* pTypeUncomp;
MFCreateMediaType(&pTypeUncomp);

// copy all settings from compressed to uncompressed type
pFileVideoMediaType->CopyAllItems(pTypeUncomp);

// set the uncompressed video attributes
pTypeUncomp->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_RGB8);
pTypeUncomp->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
pTypeUncomp->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive);

// set the new uncompressed type to source reader
m_pReader->SetCurrentMediaType(MF_SOURCE_READER_FIRST_VIDEO_STREAM, 0, pTypeUncomp);

// get the full uncompressed media type
m_pReader->GetCurrentMediaType(MF_SOURCE_READER_FIRST_VIDEO_STREAM, &pTypeUncomp);

Я заметил, что даже я явно установил MF_MT_INTERLACE_MODE в MFVideoInterlace_Progressive окончательная конфигурация все еще настроена со старым режимом MFVideoInterlace_MixedInterlaceOrProgressive,

После этого я перебираю все образцы и проверяю их размер:

IMFSample* videoSample = nullptr;
IMFMediaBuffer* mbuffer = nullptr;
LONGLONG llTimeStamp;
DWORD streamIndex, flags;

m_pReader->ReadSample(
MF_SOURCE_READER_FIRST_VIDEO_STREAM,
0,                               // Flags.
&streamIndex,                    // Receives the actual stream index.
&flags,                          // Receives status flags.
&llTimeStamp,                    // Receives the time stamp.
&videoSample)                    // Receives the sample or NULL.

videoSample->ConvertToContiguousBuffer(&mbuffer);

BYTE* videoData = nullptr;
DWORD sampleBufferLength = 0;

mbuffer->Lock(&videoData, nullptr, &sampleBufferLength);
cout << sampleBufferLength << endl;

И я получаю совершенно разные размеры для образцов: от 31 байта до 18000 байтов.
Даже меняя формат на MFVideoFormat_RGB32 не меняет влияет на размеры выборки.

это Вопрос, похоже, имеет ту же проблему, но решение не устраняет ее.

Любая помощь, почему я не могу изменить чересстрочную развертку и как правильно декодировать видеокадры и получать данные изображений из образцов?

Спасибо заранее.

1

Решение

Для того чтобы SourceReader конвертировал сэмплы в RGB, вам нужно создать его следующим образом:

IMFAttributes* pAttr = NULL;
MFCreateAttributes(&pAttr, 1);
pAttr->SetUINT32(MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, TRUE);
pAttr->SetUINT32(MF_SOURCE_READER_ENABLE_VIDEO_PROCESSING, TRUE);

IMFSourceReader* m_pReader;
throwIfFailed(MFCreateSourceReaderFromURL(filePath, pAttr, &m_pReader), Can't create source reader from url");
pAttr->Release();

Позже вы не должны выходить из цикла, когда происходит MF_SOURCE_READERF_CURRENTMEDIATYPECHANGED. Теперь у вас будут все образцы с одинаковым размером.
В противном случае вы можете использовать подтип MFVideoFormat_NV12, и тогда вам не нужно будет указывать атрибут MF_SOURCE_READER_ENABLE_VIDEO_PROCESSING при создании читателя.
Примечание. MF_SOURCE_READER_ENABLE_VIDEO_PROCESSING поддерживается только в Windows 8 и выше.

1

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

Других решений пока нет …

По вопросам рекламы [email protected]