3

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、サンプル サイズには影響しません。

この質問には同じ問題があるようですが、解決策はそれを修正していません。

インターレースを変更できない理由と、ビデオフレームを適切にデコードしてサンプルから画像データを取得する方法について何か助けはありますか?

よろしくお願いします。

4

1 に答える 1

3

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 属性を指定する必要はありません。

于 2017-04-20T16:13:51.993 に答える