Захват SDI с карты DekTec¶
Sapsan принимает сигнал с SDI-порта карты DekTec. Захватывает карту не сам сервер, а отдельный процесс dektec_ingest — по одному на порт; sapsan его запускает, надзирает за ним и читает готовые кадры.
Граница процессов здесь не деталь реализации, а требование: отказ вендорного SDK, слинкованного в медиасервер, уносит не один стрим, а весь сервер. Граница стоит одного процесса на порт, а взамен ни SDK, ни C++-шима в сборке sapsan нет.
Что нужно на машине¶
- Карта DekTec и её драйвер. Проверено на DTA-2178 (HD и 12G вплоть до 3840×2160p50) и DTA-2174B (HD).
- Пакет
dektec-bridge— он ставитdektec_ingestиdektec_probeвPATH. Без него вход отказывает с причинойproducer_unavailableи называет искомый исполняемый файл, а не молчит до таймаута. - Лицензия с поддержкой SDI.
Каталог для сокета (/run/sapsan/sdi) сервер заводит себе сам; юнит systemd отдаёт под это /run/sapsan через RuntimeDirectory. Отдельных параметров развёртывания у входа нет.
Настройка¶
streams:
- name: tv1
inputs:
- dektec:
serial: 2174223653
port: 1
pixel_format: v210
audio:
- channels: [1, 2]
lang: rus
- channels: [5, 6]
lang: eng
| Параметр | Описание |
|---|---|
serial |
серийный номер карты. Карта адресуется именно им, а не индексом в системе: индекс меняется при перестановке карт и при смене порядка загрузки драйвера |
port |
номер порта карты, с единицы |
pixel_format |
uyvy422 (8 бит, умолчание) или v210 (10 бит) |
audio |
карта звуковых дорожек, см. ниже. Пустой список — умолчание продьюсера: одна стереодорожка PCM из первой пары |
ad_marks |
дорожка сырых меток SCTE-104 из VANC; включена по умолчанию |
peer_timeout_ms |
сколько ждать кадров, прежде чем признать источник мёртвым; он же окно тишины сокета. По умолчанию 30 000; ноль означает умолчание, а не «ждать вечно» |
Единица владения — пара «серийный номер и порт»: эксклюзивность драйвера действует на порту. Два стрима на одну такую пару конфигурация отклоняет и называет занявший порт стрим; разные порты одной карты работают независимо и координации не требуют.
Сырое видео играть нечем: HLS, DASH и архив останутся пустыми, пока в стриме нет кодированных дорожек. Чтобы получить их, включите транскодер.
Звуковые дорожки¶
Позиция дорожки в списке audio — её номер в стриме (a1, a2, …). Каждая дорожка собирается из перечисленных SDI-аудиоканалов, а порядок каналов в списке и есть раскладка каналов дорожки.
| Поле | Описание |
|---|---|
channels |
номера SDI-аудиоканалов, с единицы, не больше 16 (восемь эмбеддированных пар — предел SDI) |
sample_type |
pcm (умолчание) или smpte337 |
lang |
язык дорожки по ISO 639-2 |
Язык объявляется, а не выводится: SDI языковых дескрипторов не несёт, и знает язык только тот, кто раскладывал программы по парам. Вид звука тоже объявляется и по данным не распознаётся — пара, в которой сегодня AC-3, а завтра тишина, не должна менять состав дорожек стрима.
Радиопрограммы в соседних парах становятся дорожками того же стрима, и слушать их можно селектором дорожек на выдаче. Отдельными стримами они не становятся: своего имени, своей глубины хранения и своей статистики у дорожки нет.
Несжатый звук приходит планарным 32-битным (s32p) и декодируется по объявленному числу каналов. Дорожка шире стерео принимается и декодируется честно, но кодер сводит её в стерео — это существующая граница транскодера. Целиком многоканальный звук доезжает только в обёртке SMPTE 337, где битовый поток никто не трогает.
AC-3 и E-AC-3 через SMPTE 337¶
Дорожка, объявленная sample_type: smpte337, приезжает готовыми кадрами ac3 или eac3: обёртку снимает продьюсер, sapsan звук не декодирует и не переупаковывает. Поддерживается единственный вариант — SMPTE 337, закодированный в двух каналах: такая дорожка обязана объявлять ровно два канала, иначе конфигурация отклоняется.
audio:
- channels: [1, 2]
lang: rus
- channels: [3, 4]
sample_type: smpte337
lang: rus
Паузы сжатой дорожки — тишина между пакетами — законны: вход не синтезирует тишину и не считает паузу ошибкой.
Вспомогательные данные VANC¶
Вход разбирает мешок VANC каждого кадра и разводит его содержимое:
- Телетекст и субтитры OP-47 — в общий тракт closed captions, тем же путём, что OP-47 из ST 2110.
- Строки телетекста VBI — туда же, но с SD-источника: в SD телетекст едет строкой гашения, а не пакетом ANC. Собирается той же функцией, что и OP-47.
- SCTE-104 — отдельной прикладной дорожкой, сырыми пакетами со штампом несущего кадра. Вход их не разбирает и в SCTE-35 не преобразует.
- CDP (CEA-608/708) — разбирается и считается счётчиком, но дорожкой не публикуется: носитель closed captions в тракте — SEI кодированного выхода, и вставка туда пока не сделана. Счётчик существует затем, чтобы «closed captions в сигнале нет» и «closed captions некуда отдать» не выглядели снаружи одинаково.
- Прочие пары DID/SDID — считаются счётчиком, лог ими не засоряется.
Дорожка меток существует с первого кадра пустой. Появись она по приходу первой метки — упаковка переинициализировалась бы ровно в начале рекламного блока; так же устроен MPEG-TS, где PID меток объявлен в таблице задолго до первого сообщения.
Отказы и восстановление¶
Живость источника, переключение на резерв и бэкофф ретраев у входа общие со всеми остальными протоколами — своей супервизии он не заводит. Собственных наблюдения два: тишина сокета и устойчивое «сигнала нет» на кадрах.
| Причина | Что случилось | Что делать |
|---|---|---|
no_signal |
на порту нет детектируемого сигнала | проверить кабель и источник |
device_busy |
драйвер отказал в порте | сперва проверить направление порта, затем свой зависший процесс, и лишь потом искать чужого держателя |
producer_unavailable |
dektec_ingest не найден или не запускается |
поставить пакет dektec-bridge |
device_error |
продьюсер вышел ненулевым кодом без отдельного значения: неизвестный серийный номер, порт без нужной способности, отказ настройки устройства | стадию называет стартовое событие в логе |
producer_stuck |
процесс не завершается ни по закрытию stdin, ни по SIGKILL |
признак заклинившей карты; разбираться на хосте |
producer_killed |
продьюсера убил кто-то извне sapsan — OOM-killer, systemd, человек | выяснить, кто завершил процесс, а не чинить стрим |
protocol_error |
датаграммы идут, но ни одна не разбирается | версии dektec-bridge и sapsan разъехались, выкатывать их надо вместе |
Неустранимых отказов здесь нет: после любой из них вход пробует подняться снова, с растущим интервалом между попытками. Сервер, стартовавший раньше драйвера карты, поднимется сам, как только драйвер появится; занятый порт освободится, переставленная карта найдётся.
Два случая ошибками не считаются. Смена видеостандарта — штатный рестарт продьюсера: тракт переинициализируется под новое самоописание кадров, счётчик ошибок не растёт. Одиночный плохой кадр — «опоздал» или «дубль» — стрим не рвёт.
Отдельно стоит потеря сигнала на лету. Продьюсер при этом не выходит: он продолжает выдавать кадры по расписанию, повторяя последний кадр и тишину, и для проверки живости источник с оборванным кабелем выглядит идеально здоровым. Поэтому вход, увидев на кадрах устойчивый уровень «сигнала нет», перестаёт отдавать кадры в тракт — иначе стоп-кадр уходил бы в эфир, пока кто-нибудь не вмешается. Дальше работает общая машинерия: источник признаётся мёртвым, резерв подхватывает, ретрай поднимает захват заново.
Счётчики¶
Главный вопрос статистики этого входа — где именно деградация, и три диагноза различаются арифметикой:
| Наблюдение | Диагноз |
|---|---|
| рвутся номера датаграмм | транспорт: очередь продьюсера или сокет |
| номера целы, рвётся pts видео | линия |
| процесс вышел с кодом | продьюсер |
В снапшоте API v4 у входа едут три величины: sdi_line_state (текущее состояние линии), sdi_producer_restarts_total (рестарты продьюсера) и sdi_boundary_loss_total (датаграммы, не доехавшие между процессами). Рядом — failure_cause: текущая причина отказа из таблицы выше, которая исчезает, как только отказ устранён, в отличие от кумулятивных errors_*.
В метриках Prometheus те же величины идут под префиксом stream_input_sdi_, а с ними — материал для разбора инцидента: обрезанные и неразобранные датаграммы, испорченные ссылки на кадры, неизвестные пары VANC, счётчики CDP и пер-причинная разбивка самого продьюсера. Диагностическая пара, ради которой оба счёта живут рядом: sdi_producer_datagram_dropped_total против sdi_boundary_loss_total — сошлись, значит потеряно в очереди продьюсера; наш счётчик больше, значит на самом сокете.
Расширенная детализация открывается опцией расширенных счётчиков, см. Статистику.
Чего вход не делает¶
- Не выдаёт сигнал в карту. Вход только принимает; обратное направление — SDI-выход — в sapsan пока не сделано.
- Не декодирует AC-3 и Dolby E в PCM.
- Не преобразует SCTE-104 в SCTE-35 и меток в TS/HLS/DASH не выдаёт.
- Не публикует дорожку closed captions CEA-608/708.
- Не работает с картами не-DekTec.
- Не наблюдает здоровье карты: температуру, обороты и раскладку портов снимает отдельный процесс
dektec_probe, а показывает их система управления — в инсталляциях с mcaster это раздел «Карты захвата».
Что дальше¶
- Транскодирование — сырое видео с карты играбельным не является
- Резервные источники
- Запись в архив