Исходный и целевой прямоугольники в отрисовщиках видео
[Функция, связанная с этой страницей DirectShow, является устаревшей функцией. Он был заменен MediaPlayer, IMFMediaEngine, и аудио/ видео захвата в Media Foundation. Эти функции оптимизированы для Windows 10 и Windows 11. Корпорация Майкрософт настоятельно рекомендует использовать в новом коде MediaPlayer, IMFMediaEngine и аудио/видеозахват в Media Foundation вместо DirectShow, когда это возможно. Корпорация Майкрософт предлагает переписать существующий код, в котором используются устаревшие API, чтобы по возможности использовать новые API.]
Существует три размера в структурах форматов VIDEOINFO, VIDEOINFOHEADER и VIDEOINFOHEADER2 типов видеофайлов. В этой статье объясняется, что это такое и как они работают.
Во-первых, в элементе bmiHeader этих структур есть размер. Элемент bmiHeader является структурой BITMAPINFOHEADER с собственными элементами ширины и высоты , bmiHeader.biWidth и bmiHeader.biHeight.
Во-вторых, в элементе rcSource этих структур есть прямоугольник; и, наконец, в элементе rcTarget этих структур есть прямоугольник.
Предположим, что у вас есть два фильтра, A и B, и что эти фильтры соединены друг с другом (A слева или вышестоящий и B справа или внизу) с определенным типом видеофайла.
Буферы, проходящие между фильтрами A и B, имеют размер (bmiHeader.biWidth, bmiHeader.biHeight). Фильтр A должен принимать часть входного видео, определяемого rcSource , и растягивать это видео, чтобы заполнить часть буфера rcTarget . Используемая часть входного видео зависит от того, как rcSource сравнивается с размером (biWidth, biHeight) типа мультимедиа, с которым изначально связаны фильтры A и B. Если rcSource пуст, фильтр A использует весь входной видео. Если параметр rcTarget пуст, фильтр A заполняет весь выходной буфер.
Например, предположим, что фильтр A получает видеоданные 160 x 120 пикселей. Предположим также, что фильтр A подключен к фильтру B со следующим типом носителя.
- (biWidth, biHeight): 320, 240
- rcSource: (0, 0, 0, 0)
- rcTarget: (0, 0, 0, 0)
Это означает, что фильтр A растягивает получаемое видео на 2 в направлениях x и y и заполняет выходной буфер размером 320 x 240.
В качестве другого примера предположим, что фильтр A получает видеоданные 160 x 120 и что он подключен к фильтру B со следующим типом мультимедиа.
- (biWidth, biHeight): 320, 240
- rcSource: (0, 0, 160, 240)
- rcTarget: (0, 0, 0, 0)
Член rcSource соответствует размеру подключенного буфера 320, 240. Потому что указанный rcSource (0, 0, 160, 240) — левая половина буфера. Фильтр A принимает левую половину входного видео или часть (0, 0, 80, 120) и растягивает видео до размера (320, 240) (на 4 в направлении x и на 2 в направлении y) и заполняет выходной буфер 320 x 240.
Теперь предположим, что фильтр A вызывает CBaseAllocator::GetBuffer, а возвращенный пример мультимедиа имеет присоединенный к нему тип мультимедиа, который означает, что фильтрУ Б требуется фильтр A для предоставления видео другого размера или вида, чем он предоставлял ранее. Предположим, что новый тип носителя:
- (biWidth, biHeight): 640, 480
- rcSource: (0, 0, 160, 120)
- rcTarget: (0, 0, 80, 60)
Это означает, что образец мультимедиа имеет буфер размером 640 x 480. Член rcSource относится к исходному типу подключенного носителя (320, 240), а не к новому типу мультимедиа (640, 480), поэтому rcSource указывает, что будет использоваться левый верхний угол (25 %) входного видео. Эта часть входного видео размещается в левом верхнем углу (80, 60) пикселей выходного буфера 640 x 480, как указано в rcTarget (0, 0, 80, 60). Так как фильтр A получает видео размером 160 x 120, левый верхний угол входного видео представляет собой часть (80, 60) с тем же размером выходного растрового изображения, и растяжение не требуется.
Фильтр A не помещает данные в другие пиксели выходного буфера и оставляет эти биты нетронутыми. Член rcSource ограничен значениями biWidth и biHeight исходного типа подключенного носителя между фильтрами A и B, а rcTarget ограничен новыми значениями biWidth и biHeight примера мультимедиа. В предыдущем примере rcSource не может выйти за границы (0, 0, 320, 240), а rcTarget не может выйти за границы (0, 0, 640, 480).