Шаг 3C. Реализация метода CheckTransform
[Функция, связанная с этой страницей DirectShow, является устаревшей функцией. Он был заменен MediaPlayer, IMFMediaEngine, и аудио/ видео захвата в Media Foundation. Эти функции оптимизированы для Windows 10 и Windows 11. Корпорация Майкрософт настоятельно рекомендует использовать в новом коде MediaPlayer, IMFMediaEngine и аудио/видеозахват в Media Foundation вместо DirectShow, когда это возможно. Корпорация Майкрософт предлагает переписать существующий код, в котором используются устаревшие API, чтобы по возможности использовать новые API.]
Это шаг 3C руководства Написание фильтров преобразования.
Примечание
Этот шаг не требуется для фильтров, производных от CTransInPlaceFilter.
Метод CTransformFilter::CheckTransform проверяет, совместим ли предлагаемый тип выходных данных с текущим типом входных данных. Метод также вызывается, если входной контакт повторно подключается после подключения выходного контакта.
В следующем примере проверяется, имеет ли формат видео RLE8; размеры изображения соответствуют формату входных данных; и записи палитры совпадают. Он также отклоняет исходные и целевые прямоугольники, которые не соответствуют размеру изображения.
HRESULT CRleFilter::CheckTransform(
const CMediaType *mtIn, const CMediaType *mtOut)
{
// Check the major type.
if (mtOut->majortype != MEDIATYPE_Video)
{
return VFW_E_TYPE_NOT_ACCEPTED;
}
// Check the subtype and format type.
FOURCCMap fccMap = FCC('MRLE');
if (mtOut->subtype != static_cast<GUID>(fccMap))
{
return VFW_E_TYPE_NOT_ACCEPTED;
}
if ((mtOut->formattype != FORMAT_VideoInfo) ||
(mtOut->cbFormat < sizeof(VIDEOINFOHEADER)))
{
return VFW_E_TYPE_NOT_ACCEPTED;
}
// Compare the bitmap information against the input type.
ASSERT(mtIn->formattype == FORMAT_VideoInfo);
BITMAPINFOHEADER *pBmiOut = HEADER(mtOut->pbFormat);
BITMAPINFOHEADER *pBmiIn = HEADER(mtIn->pbFormat);
if ((pBmiOut->biPlanes != 1) ||
(pBmiOut->biBitCount != 8) ||
(pBmiOut->biCompression != BI_RLE8) ||
(pBmiOut->biWidth != pBmiIn->biWidth) ||
(pBmiOut->biHeight != pBmiIn->biHeight))
{
return VFW_E_TYPE_NOT_ACCEPTED;
}
// Compare source and target rectangles.
RECT rcImg;
SetRect(&rcImg, 0, 0, pBmiIn->biWidth, pBmiIn->biHeight);
RECT *prcSrc = &((VIDEOINFOHEADER*)(mtIn->pbFormat))->rcSource;
RECT *prcTarget = &((VIDEOINFOHEADER*)(mtOut->pbFormat))->rcTarget;
if (!IsRectEmpty(prcSrc) && !EqualRect(prcSrc, &rcImg))
{
return VFW_E_INVALIDMEDIATYPE;
}
if (!IsRectEmpty(prcTarget) && !EqualRect(prcTarget, &rcImg))
{
return VFW_E_INVALIDMEDIATYPE;
}
// Check the palette table.
if (pBmiOut->biClrUsed != pBmiIn->biClrUsed)
{
return VFW_E_TYPE_NOT_ACCEPTED;
}
DWORD cbPalette = pBmiOut->biClrUsed * sizeof(RGBQUAD);
if (mtOut->cbFormat < sizeof(VIDEOINFOHEADER) + cbPalette)
{
return VFW_E_TYPE_NOT_ACCEPTED;
}
if (0 != memcmp(pBmiOut + 1, pBmiIn + 1, cbPalette))
{
return VFW_E_TYPE_NOT_ACCEPTED;
}
// Everything is good.
return S_OK;
}
Закрепление повторных подключений
Приложения могут отключать и повторно подключать контакты. Предположим, что приложение подключает оба контакта, отключает входной контакт, а затем повторно подключает входной контакт, используя новый размер изображения. В этом случае CheckTransform завершается сбоем, так как размеры изображения больше не совпадают. Такое поведение является разумным, хотя фильтр также может попытаться повторно подключить выходной контакт с новым типом мультимедиа.
Далее. Шаг 4. Задайте свойства распределителя.
Связанные темы
Обратная связь
https://aka.ms/ContentUserFeedback.
Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по