2014-01-20 2 views
0

Media Foundation 샘플의 샘플 프로젝트 MFCaptureToFile을 사용하여 Firewire를 사용하여 레거시 인터레이스 비디오를 캡처하고 H.264 인코더를 사용하여 MP4 파일로 인코딩했습니다. . 출력 H.264 영상이 프로그레시브가되도록 MF를 구성하고 싶습니다. 할 수 있습니까?Media Foundation : 인터레이스 된 원본 그림과 점진적 출력 그림

내가 이해할 수 있듯이 ICodecAPI의 AVEncVideoOutputScanType 속성을 eAVEncVideoOutputScan_Progressive로 설정해야합니다. IMFSinkWriter에서 ICodecAPI를 얻으려면 어떻게해야합니까? GetServiceForStream 메서드를 사용합니까? 시도했지만, 두 번째 매개 변수에 GUID_NULL을 사용하고 세 번째 매개 변수에 IID_ICodecAPI를 사용하면 E_NOINTERFACE가 표시됩니다.

답변

1

출력 미디어 유형에서 MF_MT_INTERLACE_MODEMFVideoInterlace_Progressive으로 설정 했습니까? 설정하면 ICodecAPI에 관해서는

IMFMediaType *pMediaTypeOut; 
... 
pMediaTypeOut->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive); 

, 여기 싱크 작가의 인터페이스를 조회 MSDN에서 slighty를 수정 인코딩 예이며,이 작업을 수행하지만, 슬프게도 SetValue(CODECAPI_AVEncVideoOutputScanType,...)의 반환은 E_NOTIMPL, 그래서 확인 출력 미디어 유형의 값이 작업을 수행합니다.

#include <Windows.h> 


#include <mfapi.h> 
#include <Mfidl.h> 
#include <mfreadwrite.h> 
#include <icodecapi.h> 
#include <codecapi.h> 

#pragma comment(lib, "Mfuuid.lib") 
#pragma comment(lib, "Mfplat.lib") 
#pragma comment(lib, "Mfreadwrite.lib") 

const UINT32 VIDEO_WIDTH = 640; 
const UINT32 VIDEO_HEIGHT = 480; 
const UINT32 VIDEO_FPS = 25; 
const UINT32 VIDEO_BIT_RATE = 800000; 
const GUID VIDEO_ENCODING_FORMAT = MFVideoFormat_H264; 
const GUID VIDEO_INPUT_FORMAT = MFVideoFormat_RGB32; 
const UINT32 VIDEO_PELS = VIDEO_WIDTH * VIDEO_HEIGHT; 
const UINT32 VIDEO_FRAME_COUNT = 20 * VIDEO_FPS; 

HRESULT InitializeSinkWriter(IMFSinkWriter **ppWriter, DWORD *pStreamIndex) 
{ 
    *ppWriter = NULL; 
    *pStreamIndex = NULL; 

    IMFSinkWriter *pSinkWriter = NULL; 
    IMFMediaType *pMediaTypeOut; 
    IMFMediaType *pMediaTypeIn = NULL; 
    DWORD   streamIndex;  

    HRESULT hr = MFCreateSinkWriterFromURL(L"output.mp4", NULL, NULL, &pSinkWriter); 

    // Set the output media type. 
    if (SUCCEEDED(hr)) 
    { 
     hr = MFCreateMediaType(&pMediaTypeOut); 
    } 
    if (SUCCEEDED(hr)) 
    { 
     hr = pMediaTypeOut->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);  
    } 
    if (SUCCEEDED(hr)) 
    { 
     hr = pMediaTypeOut->SetGUID(MF_MT_SUBTYPE, VIDEO_ENCODING_FORMAT); 
    } 
    if (SUCCEEDED(hr)) 
    { 
     hr = pMediaTypeOut->SetUINT32(MF_MT_AVG_BITRATE, VIDEO_BIT_RATE); 
    } 
    if (SUCCEEDED(hr)) 
    { 
     hr = pMediaTypeOut->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive); 
    } 
    if (SUCCEEDED(hr)) 
    { 
     hr = MFSetAttributeSize(pMediaTypeOut, MF_MT_FRAME_SIZE, VIDEO_WIDTH, VIDEO_HEIGHT); 
    } 
    if (SUCCEEDED(hr)) 
    { 
     hr = MFSetAttributeRatio(pMediaTypeOut, MF_MT_FRAME_RATE, VIDEO_FPS, 1); 
    } 
    if (SUCCEEDED(hr)) 
    { 
     hr = MFSetAttributeRatio(pMediaTypeOut, MF_MT_PIXEL_ASPECT_RATIO, 1, 1); 
    } 
    if (SUCCEEDED(hr)) 
    { 
     hr = pSinkWriter->AddStream(pMediaTypeOut, &streamIndex); 
    } 

    // Set the input media type. 
    if (SUCCEEDED(hr)) 
    { 
     hr = MFCreateMediaType(&pMediaTypeIn); 
    } 
    if (SUCCEEDED(hr)) 
    { 
     hr = pMediaTypeIn->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video); 
    } 
    if (SUCCEEDED(hr)) 
    { 
     hr = pMediaTypeIn->SetGUID(MF_MT_SUBTYPE, VIDEO_INPUT_FORMAT);  
    } 
    if (SUCCEEDED(hr)) 
    { 
     hr = pMediaTypeIn->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive); 
    } 
    if (SUCCEEDED(hr)) 
    { 
     hr = MFSetAttributeSize(pMediaTypeIn, MF_MT_FRAME_SIZE, VIDEO_WIDTH, VIDEO_HEIGHT); 
    } 
    if (SUCCEEDED(hr)) 
    { 
     hr = MFSetAttributeRatio(pMediaTypeIn, MF_MT_FRAME_RATE, VIDEO_FPS, 1); 
    } 
    if (SUCCEEDED(hr)) 
    { 
     hr = MFSetAttributeRatio(pMediaTypeIn, MF_MT_PIXEL_ASPECT_RATIO, 1, 1); 
    } 
    if (SUCCEEDED(hr)) 
    { 
     hr = pSinkWriter->SetInputMediaType(streamIndex, pMediaTypeIn, NULL); 
    } 

    // Tell the sink writer to start accepting data. 
    if (SUCCEEDED(hr)) 
    { 
     hr = pSinkWriter->BeginWriting(); 
    } 

    // Return the pointer to the caller. 
    if (SUCCEEDED(hr)) 
    { 
     *ppWriter = pSinkWriter; 
     (*ppWriter)->AddRef(); 
     *pStreamIndex = streamIndex; 
    } 

    if(pSinkWriter) 
     pSinkWriter->Release(); 
    if(pMediaTypeOut) 
     pMediaTypeOut->Release(); 
    if(pMediaTypeIn) 
     pMediaTypeIn->Release(); 
    return hr; 
} 

int main(int argc, char** argv) 
{ 
    int nCodecIds[] = { 1 }; 
    ::CoInitialize(NULL); 
    ::MFStartup(MF_VERSION); 
    IMFSinkWriter* pWriter; 
    DWORD nStreamIndex; 
    HRESULT hr = InitializeSinkWriter(&pWriter, &nStreamIndex); 
    if (pWriter) 
    { 
     ICodecAPI *pCodecApi; 
     hr = pWriter->GetServiceForStream(nStreamIndex, GUID_NULL, __uuidof(ICodecAPI), (LPVOID*)&pCodecApi); 
     if(SUCCEEDED(hr)) 
     { 
      VARIANT value, currentValue; 
      VariantInit(&value); 
      value.vt = VT_UI4; 
      value.uintVal = eAVEncVideoOutputScan_Progressive; 
      hr = pCodecApi->SetValue(&CODECAPI_AVEncVideoOutputScanType, &value); 
     } 
    } 
} 
+0

단계별 디버그에 따르면 SDK의 MFCaptureToFile 샘플은 MF_MT_INTERLACE_MODE를 2 (MFVideoInterlace_Progressive)로 설정합니다. 그러나 제작 된 비디오 파일은 인터레이스되어 있으므로이 속성에 필요한 효과가 있다고 생각하지 않습니다. 디인터레이스 할 수있는 적절한 비디오 DSP를 삽입하면 작동 할 수 있습니다. – Max

+0

Intel Quick Sync Media SDK를 사용해 보시겠습니까? 그것은 H.264를위한 MFT 변환을 가지고 있고, 정확하게 기억한다면 디인터레이싱을 지원합니다. –

+0

흥미 롭습니다. 감사합니다. 감사합니다. – Max

관련 문제