2017-04-19 4 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; 

을 그리고 샘플에 대한 매우 다른 크기 얻을 :

그 후, 나는 루프의 모든 샘플을 통해 자신의 크기를 보면 31bytes에서 18000bytes에 있습니다. 형식을 MFVideoFormat_RGB32으로 변경해도 샘플 크기에 영향을주지 않습니다.

This 질문에 동일한 문제가있는 것 같지만 해결책으로 해결할 수 없습니다.

인터레이스를 변경할 수없는 이유와 비디오 프레임을 올바르게 디코딩하고 샘플에서 이미지 데이터를 가져 오는 방법에 대한 도움이 필요합니까?

미리 감사드립니다. SourceReader을하기 위해

+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

는이처럼 만들 필요가 RGB로 샘플을 변환 : 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

한 가지 더 물어 보겠습니다. 일부 파일의 경우 정확하게 이미지 높이 * 너비 * 4와 일치하는 버퍼 크기를 가지며 데이터가 정확합니다. 다른 파일의 경우 높이 * 너비 * 4보다 큰 버퍼 크기가 있습니다. 이 추가 데이터가 무엇인지 알고 계십니까? – mbaros

+0

VuVirt, http://stackoverflow.com/questions/43014780/extarct-rgb32-byte-data-from-imfsample/43027190#43027190에 대한 귀하의 답변을 보았습니다. 매우 좋습니다. 내가 말했듯이 내 IMFSample을 2D 데이터에 고정하려고 시도했지만 오류가 발생했습니다. 또한 2D로 샘플 데이터를 올바르게 잠그고 액세스하는 방법을 보여주는 코드를 공유 할 수 있습니까? 미리 감사드립니다 – mbaros

관련 문제