Значение QVideoFrame::planeCount() и QVideoFrame::bytesPerLine

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,
Другие вопросы по тегам