Оцифровка телевизионного сигнала платами на основе Bt848/Bt878
Серия микросхем Brooktree (Rockwell Semiconductor, Conexant) Bt848/Bt878 используется для оцифровки непрерывного телевизионного сигнала, обработки цифрового видеосигнала, аналогового и цифрового аудиосигнала в составе PCI плат видеозахвата и ТВ тюнеров большинства производителей. Оборудование изучалось не с целью написания драйверов video4linux, а чтобы понять почему получается такое низкое качество видеозахвата ;)
Аналоговое видео обрабатывается всеми микросхемами семейства примерно одинаково.
Микросхемы 848A и 849A могут вводить через GPIO видео с цифровой камеры - CCIR 656, SMPTE-125, ByteStream. Они также могут обходиться одним внешним генератором частоты для NTSC и PAL/SECAM (используется встроенная схема PLL для преобразования опорной частоты).
Микросхема Bt878 имеет мультиплексор 3:1 для ввода аналогового звука (TV, FM, MIC) и его оцифровки, а также интерфейс цифрового аудио с последующей передачей по шине PCI через отдельный DMA канал.
Микросхема Bt879 дополнительно имеет DBX стереодекодер и декодер стерео передач FM радио.
Устройство подключается к шине PCI 2.1 (32 бита, 33.3 MHz, +5 V, INTA) в режиме bus master и использует каналы DMA для прямой передачи в ОП или видеобуфер графического контроллера (Bt878/Bt879 имеют дополнительный DMA канал для передачи звука).
Vendor ID = 0x109E Device ID = 0x350 (Bt848/Bt848A) Device ID = 0x351 (Bt849A) Device ID = 0x36E (Bt878) Device ID = 0x36F (Bt879)
Аналоговое видео может подаваться на 1 из 4 входов мультиплексора (3 для Bt848) композитного видео ("тюльпан") в стандартах NTSC/PAL/SECAM (о наличии нескольких различных модификаций SECAM разаработчики не знали, о наличии двух опорных частот цветности они узнали к моменту разработки Bt878, но на практике явно не успели использовать). Возможно автоматическое различение NTSC и PAL/SECAM (по числу строк в кадре) для выбора генератора частоты, но не для настройки регистров. На один из входов может подаваться сигнал яркости (Y) от S-Video, в этом случае композитный сигнал цветности (C, UV) подается на отдельный вход. Для оцифровки сигнала цветности используется отдельный АЦП.
Оцифровка производится с использованием внешнего генератора сигнала на частоте CLKx2 = 8*Fsc (28.64 MHz для NTSC и 35.47 MHz для PAL) с неуказанной разрядностью (судя по разрядности VBI - всего 8 бит). Оцифрованный сигнал пропускается через низкочастотный фильтр и прорежается до CLKx1 (14.32 MHz или 17.73 MHz). Все дальнейшие алгоритмы (фильтрация, демодуляция) производятся в цифровом виде.
Композитный сигнал (уже оцифрованный!)
- разделяется на сигналы яркости и цветностей (в S-Video сигналы разделены на входе)
- применяется отключаемый фильтр полосы цветности для сигнала яркости (режет все частоты выше 3 MHz)
- сигналы цветности демодулируются и фильтруются от высоких частот
- применяется отключаемый комбинационный фильтр для значений U и V
- настраивается тон (HUE, только для NTSC)
- контраст (умножение значений яркости, 512 значений от 0 до 236.57%, где 216 = 100%, для v4l вроде бы надо установить 27648, но в результате получается смещение вниз)
- насыщенность (отдельные коэффициенты для умножения U и V значений, 512 значений от 0 до 201.18% (U), от 0 до 283.89% (V), 254 = 100% (U), 180 = 100 % (V))
- яркость (смещение сигнала яркости, ±50%, цифровое)
В одном месте сказано, что значения регистров насыщенности для U и V определяют коэффициенты для умножения исходных значений U и V, в другом месте - регистры определяют коэффициенты для добавления. Судя по результатам - гребенчатый вид гистограммы - происходит умножение. video4linux определяет единый коэффициент умножения для U и V. Чтобы иметь 100% U его надо установить равным 32512. Коэффициент расчета множителя для V в драйвере bttv неверен - 201/237 вместо 180/254, так что получить 100% V не удастся никак (исправлено в серии 0.8, но когда она будет в поставке неизвестно; я backport-ировал, пользы не заметил ;). Последовательность настройки контраста и яркости в документации не упоминается.
Имеется автоматический (отключаемый) контроль уровня сигналов цветности по контрольным сигналам (встраиваются в строчный гасящий импульс), ±6 dB (вычисленный коэффициент - от 0.5 до 2 - используется для умножения U и V). Имеется автоматический (отключаемый) контроль наличия цвета в изображении (при отсутствии цвета U и V обнуляются). Возможно приравнять к черному сигнал с яркостью ниже определенного уровня (8, 16, 32). Выходные значения яркости могут быть в общепринятом ограниченном диапазоне (16-253) или полном (0-255). Выходные значения цветности в интервале от 2 до 253. На практике у меня получились следующие значения:
- SVHS
- Y': 16-253
- Cb: 27-228 (существенные доли: 110-152, гребенка)
- Cr: 50-218 (существенные доли: 118-150, гребенка)
- ТВ сигнал
- Y': 16-253
- Cb: 2-253 (существенные доли: 2-164, гребенка)
- Cr: 22-253 (существенные доли: 102-232)
Для того, чтобы получить фиксированное число пикселов из строки переменной длины (входной сигнал с VCR имеет вариации между сигналами горизонтальной синхронизации в несколько микросекунд) используется алгоритм UltraLock, который интерполирует переменное число отсчетов на частоте CLKx1 в требуемое число отсчетов (определяется коэффициентом масштабирования по горизонтали).
Аппаратное масштабирование производится по горизонтали (с интерполяцией, яркость по 6 точкам, цветность - по двум) и по вертикали (яркость по 2 точкам, цветность просто усредняется). Ходят слухи, что масштабирование по вертикали искажает цвета - буфер маловат для хранения нескольких строк. По-моему, масштабировать по вертикали с помощью этого устройства вообще не стоит (даже если масштабировать 2:1, то все равно замучаешься с бороться с эффектами черезстрочной развертки).
По стандарту в строке (NTSC - 63.5 мкс, PAL - 64 мкс) помещается 910 (NTSC) или 1135 (PAL) пикселов для частоты CLKx1. При этом активная часть строки содержит 754 (NTSC) или 922 (PAL/SECAM) отсчета. Для квадратных пикселей их д.б. в строке 780 или 944 (12.27 MHz или 14.75 MHz), в активной части строки - 640 (NTSC) или 768 (PAL/SECAM). Коэффициент масштабирования задается как целое число (привожу значения только для PAL) отдельно для четных и нечетных полей
[(1135/число-отсчетов-на-всю-строку)-1]*4096 (правильный метод) или [(922/число-пикселов-в-активной-части-строки)-1]*4096 (приближенный метод)
Целочисленность приводит к небольшой ошибке округления. Эти методы расчета приводят к слегка различающимся результатам (828.7 для первого метода и 821.3 для второго. В действительности, для получения пикселов CCIR 601 и квадратных пикселов полного разрешения PAL/SECAM требуется установить
PAL CCIR 601 (720x576) -> HSCALE = 0x0504 PAL кв. пиксели (768x576) -> HSCALE = 0x033C
При фирменных расчетах предполагается, что при квадратных пикселах полная строка будет составлять 944 отсчета, однако 768*1135/922 = 945.4. Длина строки PAL - 64 мкс, активная часть - 51.95 мкс, при частоте оцифровки 17734475 получается 1134 отсчета на всю строку и 921 на активную часть.
В драйвере bttv почему-то используется 924 вместо рекомендуемых 922, а целочисленное преобразование числа пикселов в активной части в число отсчетов на всю строку, что приводит к слегка другому числу. Я поменял 924 на 923 - так получается правильный коэффициент для квадратных пикселов. На практике оказалось, что ширину захвата можно устанавливать с шагом 16 до 864.
Ultralock и масштабирование - это единый процесс, причем он происходит после настройки яркости, контраста и насыщенности. К сожалению, масштабирование U и V происходит очень грубо (по 2 точкам), что приводит к гребенчатому виду гистограммы, причем характер гребенки зависит как от насыщенности, так и от суммарного коэффициента масштабирования по горизонтали.
Обрезание кадра задается регистрами начала (относительно синхроимпульса с учетом предварительного масштабирования) и продолжительности активной области (пикселов после масштабирования) по горизонтали и вертикали. Полная строка имеет 1135 отсчетов, активная (видео) часть - 922 отсчета с задержкой 186 и хвостом в 27 отсчетов.
HDELAY = [(186/922)*число-пикселов-в-активной-части-строки] & 0x3FE
Задержка по вертикали задается в половинках строк. Задержку рекомендуется делать четной, чтобы избежать обмена четных и нечетных полей. Длительность по вертикали задается в строках до масштабирования. Коэффициенты обрезания задаются отдельно для четных и нечетных полей.
Далее производится децимация по времени.
После всех этих преобразований данные получаются в формате packed 4:2:2 YCrCb (YUY2 или UYVY после byte swap, в каждом байте хранится 4 бита Y, 2 бита U, 2 бита V: в последовательные 4 байта помещаются 2 отсчета яркости и по одному отсчету Cr и Cb для первой точки).
Чип может самостоятельно разделять кадр на поля и посылать их в отдельные области памяти (отдельные каналы DMA) в упакованном (packed) или плоском (planar) формате. В последнем случае Y, Cr и Cb пересылаются в отдельные области памяти.
Возможны следующие преобразования форматов (задаются отдельно для четных и нечетных полей, дополнительно возможен byte swap):
- 422 packed (YUY2 - Y0Cb0Y1Cr0Y2Cb2Y3Cr2, после обмена байтов UYVY)
- 422 packed -> 444 (усреднение соседних цветов) -> RGB (м.б. гаммакоррекция (PAL:2.8, NTSC: 2.2), B0G0R0B1G1R1)
- 422 packed -> 411 packed (BtYUV, Cb0Y0Cr0Y1Cb4Y2Cr4Y3Y4Y5Y6Y7)
- 422 packed -> 411 packed -> 411 planar (FIFO1: Y0Y1Y2Y3Y4Y5Y6Y7Y8Y9Y10Y11Y12Y13Y14Y15; FIFO2: Cb0Cb4Cb8Cb12; FIFO3: Cr0Cr4Cr8Cr12)
- 422 packed -> 411 packed -> 411 planar -> YUV9 planar (прореживается с помощью DMA)
- 422 packed -> 422 planar (FIFO1: Y0Y1Y2Y3Y4Y5Y6Y7; FIFO2: Cb0Cb2Cb4Cb6; FIFO3: Cr0Cr2Cr4Cr6)
- 422 packed -> 422 planar -> 420 planar (YUV12, прореживается с помощью DMA)
Для планарных форматов HACTIVE д.б. кратен 16.
Форматы YUV12 и YUV9 получаются простым прореживанием значений цветности, поэтому необходимо использовать при захвате комбинационный фильтр цветности.
При расчете требуемой скорости обработки при разрешении 768x576 (PAL RGB32 до 44 МБ/сек) необходимо учитывать, что пиковая скорость больше, так как активная часть кадра занимает меньше 1/25 секунды (надо вычесть холостой ход строки и кадра). Получается более 44 МБ/сек для RGB24. К тому же из строки можно сделать до 922 пикселей (у меня не получилось более 880 пикселов, в SECAM при ширине уже в 800 пикселов справа появляется зеленая полоса - не хватает места под цвета предыдущей строки!).
Буферизация пересылки достигается с использованием трех FIFO буферов. Размер FIFO (слово 36 бит: 32 бита данных и 4 бита состояния):
- 70x36 bit
- 35x36 bit
- 35x36 bit
Состояния слова FIFO:
- начало пакетированных данных
- начало планарных данных
- начало строки
- данные
- конец строки
- конец четного поля
- конец нечетного поля
Максимальная задержка PCI шины до переполнения FIFO - 17 мкс для режима PAL 768x576x25 YUV 4:2:2.
DMA контроллер управляется RISC программой, которую создает драйвер устройства (отдельные программы для четного и нечетного полей). Команды содержат флажки начала и конца строки, которые должны соответствовать битам состояния обрабатываемого слова FIFO. Имеются следующие команды:
- WRITE (адреса и счетчик байт для FIFO1)
- WRITE123 (3 адреса и счетчика для всех FIFO)
- WRITE1S23 (адрес и счетчик для FIFO1, счетчики децимации для FIFO2 и FIFO3)
- WRITEC (продолжить запись с текущего адреса)
- SKIP (выкинуть указанное число байт из FIFO1)
- SKIP123
- SYNC (пропустить все данные из FIFO до указанного состояния)
- JUMP (безусловный переход)
Интерфейс I2C (master, 99.2 kHz) позволяет управлять ТВ и FM тюнерами, расположенными на той же карте.
Интерфейс JTAG упрощает тестирование.
24-битный GPIO можно использовать для ввода или вывода потока цифрового видео или сигналов ИК пульта ДУ.
Захват VBI (Vertical Blanking Interval, телетекст) возможны в режимах Line Output Mode (строки 7-23 и 319-335 для PAL) и Frame Output Mode (вся активная видеообласть включая сигналы гашения и горизонтальной синхронизации). Оцифровка с частотой 8*Fsc (35.47 MHz для PAL), 8 бит. В принципе, так можно оцифровать весь сигнал и извлечь из него изображение программно, если хватит скорости процессора (сами разработчики рекомендуют этот метод для достижения "высокого качества").
Звуковое FIFO имеет размер 36x35 (2 16-битных отсчета или 4 8-битных и 4 бита состояния: начало пакетированных данных, начало строки, данные, конец строки, конец строки, конец нечетного поля).
Цифровой аудиовход - последовательный поток бит до 3.072 MHz, левый и правый канал по 16 бит. Пакетный цифровой аудиовход - 1 MB/s.
Почему-то изготовители плат на Bt878 не любят пользоваться возможностями микросхемы по обработке звука.
В качестве примера рассмотрим попавшую мне в руки плату AVerMedia TVPhone98/VCR (M168-V 0405AAL2, SECAM-D). На плате обнаружены:
- кварц 4.0016 DF
- кварц 28.618 DB (NTSC)
- тюнер ТВ и FM Philips FM 1256/PH hm (3139 147 13921L)
- микросхема микширования звука и обработки сигнала ДУ PIC 16C54C
- микросхема обработки изображения Conexant Bt878KHF (25878-12 CA9084.2)
- микросхема непонятного назначения CSI 24WC02J 9942B (говорят, что это I2C EEPROM)
- микросхема непонятного назначения TLHAANTO 74HC49520 C7064ME (HRn9840)
Оцифровка звука не замечена, вместо нее сделан проходной кабель на звуковую плату. Генератор частоты для NTSC, преобразование частоты для PAL с помощью PLL.
Приемник сигналов ДУ можно использовать в любом приложении с помощью Lirc.
Для работы с устройством используется драйвер bttv в стандарте video4linux (v4l) или video4linux2 (v4l2). Red Hat Linux 7.2 (ядро 2.4.9) содержит версию 0.7.72, Red Hat Linux 8.0 (ядро 2.4.18) содержит версию 0.7.91. Имеются версии: 0.7.104 (ничего существенного для меня) и 0.9.5 (v4l2). Если в версии 0.7.72 тюнер неправильно опознавался (Philips PAL, вместо Philips SECAM), но работал, то в 0.7.91 автораспознается чеерез eeprom правильно, но не работает вообще. Приходится вручную указывать параметры модулей в /etc/modules.conf:
alias char-major-81 bttv # bttv options # gbufsize=0x105000 // 924*576*2, а то буферов иногда не хватает # card=41 // номер см. bttv.h; можно не указывать, если распознается само # combfiltr=1 // обязательно при захвате в формате YUV 4:2:0 (т.е. почти всегда) # lumafiltr=1 // использовать при композитном видеосигнале # chroma_agc=1 // использовать, если S-Video имеет несогласованные уровни options bttv gbuffers=30 gbufsize=0x105000 combfiltr=1 # номер тюнера см. tuner.h options tuner type=5 # список микросхем можно получить: modinfo tvaudio options tvaudio pic16c54=1 # I2C module options alias char-major-89 i2c-dev
Драйвер обеспечивает следующие устройства v4l (SUBCAPTURE так и появился)
/dev/video0
Interface name: BT878(AVerMedia TVPhone 98)
frame size from 48x32 to 924x576
signal sources: 3
audio subdevices: 4
flags:
CAPTURE
TUNER
OVERLAY
CLIPPING
FRAMERAM
SCALES
attached units (major, minor):
video: 81, 0
vbi: 81, 224
radio: 81, 64
audio: 81, -1
teletext: 81, -1
input source 0 capability
source name: Television
tuners: 1
flags: 3
TUNER (1)
AUDIO (2)
type: 1
TV (1)
norm: 0
PAL
/dev/vbi0
Interface name: bttv vbi
frame size from 0x0 to 0x0
signal sources: 0
audio subdevices: 0
flags:
TUNER
TELETEXT
/dev/radio0
Interface name: BT878(AVerMedia TVPhone 98)
frame size from 0x0 to 0x0
signal sources: 1
audio subdevices: 1
flags:
TUNER
tuner 0 capability
tuner name: Radio
freq range: 65.000000 - 108.000000 MHz
/dev/vtx обрабатывается через другой API
В дополнение к v4l обеспечиваются следующие ioctl:
- BTTV_FIELDNR
- BTTV_PLLSET
- BTTV_BURST_ON
- BTTV_BURST_OFF
- BTTV_VERSION
videodev (Device registrar for Video4Linux drivers, используется bttv)
tuner, параметры:
debug
type
addr
tv_range
radio_range
pal
tvaudio (audio decoder + audio/video mux driver), параметры:
debug
pic16c54=1
...
bttv (bttv - v4l driver module for bt848/878 based cards), параметры
radio (default 0, карта поддерживает радио)
bigendian (byte order of the framebuffer, default is native endian)
fieldnr (0, считает поля и генерирует прерывания)
bttv_verbose (verbose startup messages, default is 1 (yes))
bttv_gpio (log gpio changes, default is 0 (no))
bttv_debug (0)
irq_debug (0)
gbuffers (2, число буферов - до 64, v4l API предусматривает только 32!)
gbufsize (2129920, чтобы влез кадр 924x576 RGB32, default is 0x208000)
combfilter (обязательно, если захват в режиме 4:2:0)
lumafilter (желательно, если ввод с VHS)
chroma_agc (enables the AGC of chroma signal, default is 0 (no))
adc_crush (enables the luminance ADC crush, default is 1 (yes))
video_nr (младший номер устройства)
radio_nr (младший номер устройства)
vbi_nr (младший номер устройства)
no_overlay
card (int, идентификатор карты)
pll (частота кристала: 0, 28, 35)
tuner (specify installed tuner type)
automute (mute audio on bad/missing video signal, default is 1 (yes))
autoload (automatically load i2c modules like tuner.o, default is 1 (yes))
gpiomask
audioall
audiomux
Также используются модули управления шиной i2c: i2c-core, i2c-proc, i2c-dev, i2c-algo-bit, eeprom (параметры этих модулей менять не советую).
Выдержка из журнала загрузки:
Linux video capture interface: v1.00 bttv: driver version 0.7.91 loaded bttv: using 30 buffers with 1044k (31320k total) for capture bttv: Host bridge is Intel Corp. 82845 845 (Brookdale) Chipset Host Bridge bttv: Bt8xx card found (0). PCI: Found IRQ 12 for device 02:01.0 PCI: Sharing IRQ 12 with 02:01.1 bttv0: Bt878 (rev 2) at 02:01.0, irq: 12, latency: 64, memory: 0xe0000000 bttv0: detected: AVerMedia TVPhone98 [card=41], PCI subsystem ID is 1461:0003 bttv0: using: BT878(AVerMedia TVPhone 98) [card=41,autodetected] i2c-dev.o: Registered 'bt848 #0' as minor 0 i2c-core.o: adapter bt848 #0 registered as adapter 0. bttv0: Avermedia eeprom[0x4871]: tuner=3 radio:yes remote control:yes bttv0: i2c: checking for MSP34xx @ 0x80... not found bttv0: i2c: checking for TDA9875 @ 0xb0... not found bttv0: i2c: checking for TDA7432 @ 0x8a... not found tvaudio: TV audio decoder + audio/video mux driver tvaudio: known chips: tda9840,tda9873h,tda9874h/a,tda9850,tda9855,tea6300, tea6420,tda8425,pic16c54 (PV951) i2c-core.o: driver generic i2c audio driver registered. i2c-core.o: driver i2c TV tuner driver registered. tuner: probing bt848 #0 i2c adapter [id=0x10005] tuner: chip found @ 0xc2 bttv0: i2c attach [client=Philips SECAM,ok] i2c-core.o: client [Philips SECAM] registered to adapter [bt848 #0](pos. 1). bttv0: registered device video0 bttv0: registered device vbi0 bttv0: registered device radio0 bttv0: PLL: 28636363 => 35468950 ... ok
По какому-то недоразумению, в драйвере bttv используются неверные коэффициенты для подсчета числа активных пикселов (924 вместо 922) и пересчета насыщенности V из U (201L/237 вместо 180L/254). При желании их можно поправить (невооруженным взглядом разница незаметна).
Процедура сборки модуля:
- изменить исходные тексты
- make menuconfig (сразу выйти с сохранением)
- make modules
- rmmod bttv (сначала выгрузить зависимые модули)
- положить bttv.o в директорию модулей текущего ядра
- возможно, что загружать модуль придется с ключом -f
Исправления в bttv-driver.c (0.7.91):
строки 442-
/* before bog
{ 35468950,
924, 576, 1135, 0x7f, 0x72, (BT848_IFORM_PAL_BDGHI|BT848_IFORM_XT1),
1135, 186, 924, 0x20, 255},
*/
{ 35468950,
922, 576, 1135, 0x7f, 0x72, (BT848_IFORM_PAL_BDGHI|BT848_IFORM_XT1),
1135, 186, 922, 0x20, 255},
строки 464-
/* before bog
{ 35468950,
924, 576, 1135, 0x7f, 0xb0, (BT848_IFORM_SECAM|BT848_IFORM_XT1),
1135, 186, 922, 0x20, 255},
*/
{ 35468950,
922, 576, 1135, 0x7f, 0xb0, (BT848_IFORM_SECAM|BT848_IFORM_XT1),
1135, 186, 922, 0x20, 255},
строка 1618
/* before bog bt848_sat_v(btv, ((p.colour>>7)*201L)/237); */
bt848_sat_v(btv, ((p.colour>>7)*180L)/254);
Источник: www.bog.pp.ru
