Microsoft DirectX 9.0 |
The Video Mixing Renderer (VMR) supports hardware-accelerated deinterlacing, which improves rendering quality for interlaced video. The exact features that are available depend on the underlying hardware. The application can query for the hardware deinterlacing capabilities and set deinterlacing preferences through the IVMRDeinterlaceControl interface (VMR-7) or IVMRDeinterlaceControl9 interface (VMR-9). Deinterlacing is performed on a per-stream basis.
Note This section describes the IVMRDeinterlaceControl9 methods, but the VMR-7 versions are almost identical.
To get the deinterlacing capabilities for a video stream, do the following:
The following code shows these steps:
VMR9VideoDesc VideoDesc;
DWORD dwNumModes = 0;
// Fill in the VideoDesc structure (not shown).
hr = pDeinterlace->GetNumberOfDeinterlaceModes(&VideoDesc,
&dwNumModes, NULL);
if (SUCCEEDED(hr) && (dwNumModes != 0))
{
// Allocate an array for the GUIDs that identify the modes.
GUID *pModes = new GUID[dwNumModes];
if (pModes)
{
// Fill the array.
hr = pDeinterlace->GetNumberOfDeinterlaceModes(&VideoDesc,
&dwNumModes, pModes);
if (SUCCEEDED(hr))
{
// Loop through each item and get the capabilities.
for (int i = 0; i < dwNumModes; i++)
{
VMR9DeinterlaceCaps Caps;
hr = pDeinterlace->GetDeinterlaceModeCaps(pModes + i,
&VideoDesc, &Caps);
if (SUCCEEDED(hr))
{
// Examine the Caps structure.
}
}
}
delete [] pModes;
}
}
Now the application can set the deinterlacing mode for the stream, using the following methods:
The method reference pages give more information.
Using the VMR9VideoDesc Structure
In the procedure given previously, the first step is to fill in a VMR9VideoDesc structure with a description of the video stream. Start by getting the media type of the video stream. You can do this by calling IPin::ConnectionMediaType on the VMR filter's input pin. Then confirm whether the video stream is interlaced. Only VIDEOINFOHEADER2 formats can be interlaced. If the format type is FORMAT_VideoInfo, it must be a progressive frame. If the format type is FORMAT_VideoInfo2, check the dwInterlaceFlags field for the AMINTERLACE_IsInterlaced flag. The presence of this flag indicates the video is interlaced.
Assume that the variable pBMI is a pointer to the BITMAPINFOHEADER structure in the format block. Set the following values in the VMR9VideoDesc structure:
sizeof(VMR9VideoDesc)
.pBMI->biWidth
.abs(pBMI->biHeight)
.Average time per frame | Frame rate (fps) | Numerator | Denominator |
166833 | 59.94 (NTSC) | 60000 | 1001 |
333667 | 29.97 (NTSC) | 30000 | 1001 |
417188 | 23.97 (NTSC) | 24000 | 1001 |
200000 | 50.00 (PAL) | 50 | 1 |
400000 | 25.00 (PAL) | 25 | 1 |
416667 | 24.00 (Film) | 24 | 1 |
pBMI->biCompression
.The following helper function converts AMINTERLACE_X flags to VMR9_SampleFormat values:
#define IsInterlaced(x) ((x) & AMINTERLACE_IsInterlaced)
#define IsSingleField(x) ((x) & AMINTERLACE_1FieldPerSample)
#define IsField1First(x) ((x) & AMINTERLACE_Field1First)
VMR9_SampleFormat ConvertInterlaceFlags(DWORD dwInterlaceFlags)
{
if (IsInterlaced(dwInterlaceFlags)) {
if (IsSingleField(dwInterlaceFlags)) {
if (IsField1First(dwInterlaceFlags)) {
return VMR9_SampleFieldSingleEven;
}
else {
return VMR9_SampleFieldSingleOdd;
}
}
else {
if (IsField1First(dwInterlaceFlags)) {
return VMR9_SampleFieldInterleavedEvenFirst;
}
else {
return VMR9_SampleFieldInterleavedOddFirst;
}
}
}
else {
return VMR9_SampleProgressiveFrame; // Not interlaced.
}
}