Значение QVideoFrame::planeCount() и QVideoFrame::bytesPerLine
Возвращает количество самолетов в видеокадре. Это значение действительно только тогда, когда данные кадра отображаются
Возвращает количество байтов в строке сканирования.
Я не очень хорошо понимаю эти утверждения, может кто-нибудь объяснить подробно?
С моей веб-камеры я получаю данные ниже, после использования QVideoFrame::map
width=640
height=480
pixelFormat=Format_RGB32
bytesPerLine=2560
mappedBytes=122880
planeCount=1
1 ответ
Строка сканирования - это одна строка видеоизображения. (Термин "линия сканирования" был введен во времена, когда общепринятым методом было то, что катодный луч сканировал поверхность экранной трубки линия за линией - линия сканирования).
Если bytesPerLine
делится на width
(bytesPerLine
/ width
= 2560/640 = 4), это дает байтов на пиксель.
Если вычисленные байты на пиксель не являются целочисленным значением, то линия выравнивается по определенному кратному (обычно 4). Свернутый пример, чтобы проиллюстрировать это:
width=458
pixelFormat=Format_RGB24
bytesPerLine=1376 (a multiple of 4)
1376/458 = 3.0043668122270742358078602620087 (согласно моему калькулятору Windows)
458 * 3 = 1374 → Есть 2 байта, чтобы заполнить строку до следующего кратного 4 (байты не используются, должны игнорироваться).
В примере с OP это не проблема - формат пикселя сам по себе имеет размер, соответствующий выравниванию строки.
Итак, 4 байта соответствуют pixelFormat
в котором говорится Format_RGB32
имея в виду:
Кадр сохраняется с использованием 32-битного формата RGB (0xffRRGGBB). Это эквивалентно QImage:: Format_RGB32.
как 32 бита = 4 байта.
Количество самолетов немного сложнее. Я погуглил себя и нашел одно- и многоплоскостные API:
Некоторые устройства требуют, чтобы данные для каждого входного или выходного видеокадра помещались в непрерывные буферы памяти. В таких случаях один видеокадр должен быть адресован с использованием более одного адреса памяти, то есть одного указателя на "плоскость". Плоскость - это суббуфер текущего кадра.
В случае OP существует 1 плоскость - цветовые компоненты пикселя сохраняются последовательно (упаковываются).
Другой пример, где количество самолетов> 1: QVideoFrame::Format_YUV420P
Кадр сохраняется с использованием 8-разрядного для каждого компонента плоского формата YUV с подвыборкой плоскостей U и V по горизонтали и вертикали, то есть высота и ширина плоскостей U и V равны половине ширины плоскости Y.
Это означает, что цветовые компоненты пикселя не упакованы вместе (как в Format_RGB32
) но каждая плоскость хранит только один цветовой компонент одного пикселя. Чтобы восстановить пиксель, соответствующие компоненты цвета должны быть считаны с каждой плоскости и объединены соответственно.
В случае, когда есть несколько плоскостей, 2- й вид bytesPerLine()
должен быть использован:
int QVideoFrame::bytesPerLine(int plane) const
Возвращает количество байтов в строке сканирования плоскости.
В случае вышеуказанного QVideoFrame::Format_YUV420P
: Компоненты U и V подвыборки по горизонтали и вертикали. Т.е. чтобы получить пиксель при (x, y) = (123, 72), компоненты должны быть прочитаны:
- Компонент Y со смещением
72 * getBytesPerLine(0) + 123
- U компонент в смещении
72 / 2 * getBytesPerLine(1) + 123 / 2
- V компонент в смещении
72 / 2 * getBytesPerLine(2) + 123 / 2
,