2017-04-19 34 views
1

私はMOVファイルを持っていますので、デコードしてすべてのフレームを別々の画像にします。Media Foundationはビデオのインターレースとデコードを設定します

だから私は、次のように圧縮されていないメディアタイプを設定してみてください:

// 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_MODEMFVideoInterlace_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; 

をそして私はサンプルのため、かなり異なるサイズを取得:

その後、Iループのすべてのサンプルを通って、その大きさを見て31bytesから18000bytesにします。 フォーマットをMFVideoFormat_RGB32に変更しても、サンプルサイズには影響しません。

This質問に同じ問題があるようですが、解決策は解決していません。

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

事前に感謝します。 SourceReaderは、あなたがこのようにそれを作成する必要がRGBにサンプルを変換するためには

+1

m_pReader-> GetCurrentMediaType(MF_SOURCE_READER_FIRST_VIDEO_STREAM、&pFileVideoMediaType);の代わりにGetNativeMediaTypeを最初に呼び出すようにしてください。また、各サンプルがインターレースされているかどうかを確認しましたか?pSample-> GetUINT32(MFSampleExtension_Interlaced、&isSampleInterlaced); – VuVirt

+1

ConfigureDecoder関数は、https://msdn.microsoft.com/en-us/library/windows/desktop/dd389281(v=vs.85).aspx#setting_output_formatsで確認できます。また、ReadSampleを呼び出すときに、受信ステータスフラグでMF_SOURCE_READERF_CURRENTMEDIATYPECHANGEDを​​チェックして、タイプが変更されているかどうかを確認することもできます。 – VuVirt

+0

@VuVirt、ご意見ありがとうございます。ネイティブメディアタイプを取得しても何も変更されませんでした。サンプルがインターレースであることを確認すると、エラーが発生しました。メディアタイプの変更はありませんでした。あなたの心には何か他に何かありますか?あなたが私のコードを見て分のカップルを見つけることができる場合:https://github.com/mbaros100/Media-Foundation-video-decoder。ご助力ありがとうございます。 – mbaros

答えて

1

:MF_SOURCE_READERF_CURRENTMEDIATYPECHANGEDが発生したとき

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(); 

後で、サイクルから壊すべきではありません。今度は同じサイズのサンプルをすべて持っていきます。 それ以外の場合は、MFVideoFormat_NV12サブタイプを使用できます。したがって、リーダーを作成するときにMF_SOURCE_READER_ENABLE_VIDEO_PROCESSING属性を指定する必要はありません。 注:MF_SOURCE_READER_ENABLE_VIDEO_PROCESSINGは、Windows 8以上でのみサポートされています。

+0

私のために働いた。どうもありがとうございました。 – mbaros

+0

もう1つ質問があります。いくつかのファイルでは、正確に一致する画像の高さ*幅* 4のバッファサイズがあり、データは正しいものでした。他のいくつかのファイルでは、高さ*幅* 4よりもバッファサイズが大きくなっています。この追加データは何のためのものなのか分かりますか? – mbaros

+0

VuVirt、私はあなたの答えをhttp://stackoverflow.com/questions/43014780/extarct-rgb32-byte-data-from-imfsample/43027190#43027190に見ました。これはとても良いです。私は私のIMFSampleを2Dデータにロックしようとしましたが、エラーが発生しました。 2Dでサンプルデータを正しくロックしてアクセスする方法を示すコードを共有することもできますか?事前に感謝 – mbaros

関連する問題