簡體   English   中英

Media Foundation 設置視頻隔行和解碼

[英]Media Foundation set video interlacing and decode

我有一個 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也不會影響樣本大小。

這個問題似乎有同樣的問題,但解決方案沒有解決它。

關於為什么我無法更改隔行掃描以及如何正確解碼視頻幀並從樣本中獲取圖像數據的任何幫助?

提前謝謝了。

為了使 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 屬性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM