프로필 및 기타 파일 속성 구성(QASF)
다음 항목에서는 ASF 파일 만들기와 관련된 다양한 작업을 수행하는 방법을 설명합니다.
프로필 만들기(QASF)
사용자 지정 프로필을 만들려면 Windows Media Format SDK를 직접 사용하여 WMCreateProfileManager 함수를 사용하여 프로필 관리자 개체를 만듭니다. 다음으로, 프로필을 만들고 IConfigASFWriter::ConfigureFilterUsingProfile 메서드를 사용하여 WM ASF 기록기에 전달합니다. Windows Media Audio 및 Video 9 시리즈 코덱을 사용하는 프로필로 필터를 구성하는 유일한 방법입니다. 이러한 코덱의 이전 버전에 대한 시스템 프로필은 IConfigASFWriter::ConfigureFilterUsingProfileGuid 메서드를 사용하여 추가할 수 있습니다.
메타데이터 추가(QASF)
파일에 메타데이터를 추가하려면 WM ASF 기록기에서 IBaseFilter 인터페이스에서 QueryInterface를 호출하여 IWMHeaderInfo 인터페이스를 검색합니다. 필터에 프로필이 제공된 후 IWMHeaderInfo 인터페이스 메서드를 사용하여 메타데이터를 작성합니다.
파일 인덱싱(QASF)
WM ASF 기록기는 기본적으로 임시로 인덱싱된 파일을 만듭니다. 프레임 인덱싱된 파일을 만들려면 IConfigAsfWriter::SetIndexMode 메서드를 사용하여 모든 인덱싱을 사용하지 않도록 설정한 다음 파일을 만듭니다. 완료되면 Windows Media Format SDK를 직접 사용하여 파일에 대한 프레임 기반 인덱스 만들기를 수행합니다.
Two-Pass 인코딩 수행(QASF)
2단계 인코딩은 버전 8 이상 Windows Media 코덱에서만 지원됩니다. IConfigAsfWriter2::SetParam을 호출하고 dwParam 매개 변수에 AM_CONFIGASFWRITER_PARAM_MULTIPASS 지정하고 dwParam1 매개 변수에서 TRUE를 지정하여 WM ASF 기록기를 전처리 모드로 전환합니다.
그런 다음 필터 그래프를 실행합니다. 모든 전처리 패스가 완료되면(일반적으로 하나의 전처리 패스만 수행됨) 애플리케이션은 필터에서 EC_PREPROCESS_COMPLETE 이벤트를 받습니다. 이 이벤트가 수신되면 IMediaSeeking::SetPositions 를 사용하여 스트림 포인터를 다시 시작 부분으로 다시 설정하고 필터 그래프를 다시 실행합니다. 마지막 패스(일반적으로 두 번째 패스) 후에 애플리케이션은 인코딩 프로세스가 완료되었다는 것을 나타내는 EC_COMPLETE 이벤트를 받게 됩니다. EC_PREPROCESS_COMPLETE 이벤트가 수신되기 전에 전처리 패스가 취소되면 IConfigAsfWriter2::ResetMultiPassState를 호출하여 다른 전처리 실행을 시도하기 전에 필터를 다시 설정합니다.
필터를 전처리 모드에서 완전히 해제하려면 IConfigAsfWriter::SetParam(AM_CONFIGASFWRITER_PARAM_MULTIPASS, FALSE)을 호출해야 합니다.
중요
인코딩에 사용할 프로필을 기반으로 전처리 모드를 사용하도록 설정하는 것은 애플리케이션의 책임입니다. 일부 프로필에는 2단계 인코딩이 필요합니다. 이러한 프로필을 사용하여 파일을 인코딩하려고 하고 AM_CONFIGASFWRITER_PARAM_MULTIPASS TRUE로 설정하지 않으면 EC_USERABORT 오류가 발생합니다. 지정된 프로필에 2단계 인코딩이 필요한지 여부를 확인하는 방법에 대한 자세한 내용은 Two-Pass 인코딩 사용 또는 가변 비트 전송률 스트림 작성을 참조하세요.
런타임에 버퍼 속성 가져오기 및 설정(QASF)
예를 들어 파일을 작성할 때 키 프레임 삽입을 강제하려는 경우 애플리케이션은 런타임에 Windows Media 버퍼에 대한 정보를 얻거나 설정해야 할 수 있습니다. WM ASF 판독기 및 WM ASF 기록기 필터는 모두 애플리케이션이 파일 읽기 또는 파일 작성 중에 각 개별 미디어 버퍼의 INSSBuffer3 인터페이스에 액세스할 수 있도록 하는 콜백 메커니즘을 지원합니다. 애플리케이션은 이 인터페이스를 사용하여 특정 샘플을 키 프레임 또는 클린포인트로 지정하고, SMPTE 시간 코드를 설정하거나, 인터레이스 설정을 지정하거나, 모든 유형의 프라이빗 데이터를 스트림에 추가할 수 있습니다.
IAMWMBufferPass 인터페이스를 사용하여 비디오 스트림을 처리하는 핀에서 콜백을 등록합니다. 핀이 IAMWMBufferPassCallback::Notify 메서드를 호출할 때 버퍼의 타임스탬프를 검사하고 적절한 경우 INSSBuffer3::SetProperty 를 호출하여 버퍼의 WM_SampleExtensionGUID_OutputCleanPoint 속성을 TRUE로 설정합니다.
QASF(비사각형 픽셀 지원)
WM ASF 기록기는 픽셀 가로 세로 비율 정보를 출력하는 DV 디코더와 같은 업스트림 필터에 연결합니다. WM ASF 기록기는 이 정보를 파일의 모든 샘플에 대한 데이터 단위 확장으로 작성합니다.
WM ASF 판독기가 파일 헤더 또는 샘플의 데이터 단위 확장에서 픽셀 가로 세로 비율 정보를 발견하면 출력 핀에서 VIDEOINFOHEADER2 미디어 형식을 첫 번째 선택 항목으로 제공합니다. 비디오 사각형의 가로 세로 비율을 설명하는 구조체의 dwPictAspectRatioX 및 dwPictAspectRatioY 멤버는 픽셀 가로 세로 비율을 고려하여 올바르게 조정됩니다.
인터레이스 형식 유지 관리
텔레비전 또는 DV 카메라에서 인터레이스된 비디오를 캡처하는 경우 인코딩된 파일이 텔레비전 또는 다른 인터레이스 디스플레이 장치에서 재생될 것으로 예상되는 경우 원래 비디오를 독립 필드로 유지할 수 있습니다. (컴퓨터 모니터는 점진적 검사 디바이스입니다.) 비디오를 디인터레이스한 다음 TV에서 재생을 위해 다시 설치하면 일부 데이터 손실이 발생합니다. ASF 파일에서 인터레이싱 정보는 앞에서 설명한 IAMWMBufferPassCallback 메서드를 사용하여 애플리케이션이 각 샘플에 적용되는 데이터 단위 확장으로 저장됩니다. 원래 인터레이스 설정을 유지하는 파일을 인코딩하려면 다음 단계를 수행합니다.
- IAMWMBufferPassCallback을 지원하는 클래스를 구현하고 각 샘플의 인터레이스 플래그를 설정하는 Notify 함수를 작성합니다. 이 함수는 각 샘플을 처리하기 전에 WM ASF 기록기에서 호출됩니다.
// Set to WM_CT_TOP_FIELD_FIRST if that is your format.
BYTE flag = WM_CT_INTERLACED | WM_CT_BOTTOM_FIELD_FIRST;
HRESULT hr = pNSSBuffer3->SetProperty(WM_SampleExtensionGUID_ContentType, (void*) &flag, WM_SampleExtension_ContentType_Size);
- 프로필을 필터에 전달하기 전에 프로필에서 데이터 단위 확장을 설정합니다.
hr = pWMStreamConfig2->AddDataUnitExtension( WM_SampleExtensionGUID_ContentType, WM_SampleExtension_ContentType_Size, NULL, 0 );
- 프로필을 사용하여 필터를 구성한 후 WM ASF 기록기에서 IWMWriterAdvanced2 인터페이스를 가져오고 SetInputSettings 메서드를 호출합니다 .
// Must do this first.
hr = pConfigAsfWriter2->ConfigureFilterUsingProfile(pProfile);
CComPtr<IServiceProvider> pProvider;
CComPtr<IWMWriterAdvanced2> pWMWA2;
hr = pConfigAsfWriter2->QueryInterface( __uuidof(IServiceProvider),
(void**)&pProvider);
if (SUCCEEDED(hr))
{
hr = pProvider->QueryService(IID_IWMWriterAdvanced2,
IID_IWMWriterAdvanced2,
(void**)&pWMWA2);
}
BOOL pValue = TRUE;
// Set the first parameter to your actual input number.
hr = pWMWA2->SetInputSetting(0, g_wszInterlacedCoding,
WMT_TYPE_BOOL, (BYTE*) &pValue, sizeof(WMT_TYPE_BOOL));