Simulcast и SVC: как SFU обслуживает разнородную аудиторию

Автор: Николай СапуновОбновлено: август 202628 мин чтения
Содержание статьи +

Коротко

Selective Forwarding Unit пересылает медиа подписчикам без перекодирования – как есть. Это означает, что без дополнительных мер каждый подписчик получит один и тот же закодированный поток: такой подход работает в идеальных условиях, например, в зале с одинаковыми ноутбуками и гигабитным соединением, но в реальности он бесполезен. Ведь один зритель может смотреть с телефона по LTE, а другой – за десктопом с гигабитным Ethernet.

Simulcast решает эту проблему так: publisher отправляет несколько независимых закодированных копий одного и того же видео в разных разрешениях и битрейтах, а сервер выбирает для каждого подписчика наиболее подходящую версию в каждый момент времени. Scalable Video Coding (SVC) решает ту же задачу иначе: использует один поток с вложенными временными и пространственными слоями, любой префикс которого можно декодировать в полноценное изображение.

К 2026 году simulcast стал стандартом по умолчанию для VP8 и H.264 во всех браузерах, а SVC – стандартом по умолчанию для VP9 и AV1 в Chromium. Обе технологии сосуществуют внутри каждого современного SFU, включая мульти-кодековый simulcast от LiveKit, где один publisher обслуживает подписчиков с разными требованиями к качеству в рамках одной комнаты.

Зачем это знать

Если вы запускаете WebRTC-продукт с более чем пятью участниками в комнате, выбор между simulcast и SVC лежит в основе каждой жалобы на качество, каждого счёта за нагрузку на CPU устройства publisher, каждого тикета «почему у мобильного зрителя стрим десктопа с 4K-таблицей выглядит как мыло» и каждой измеримой строки в счёте за TURN. Решение не абстрактное: оно определяет, как работает ваш конвейер кодирования, как обрабатывается пересылка RTP в SFU, как ведут себя декодеры подписчиков и что вы можете запустить в Safari, а что работает только в Chromium. В этой статье – архитектура, стандарты, цифры и продакшен-реальность 2026 года для пяти основных SFU, чтобы, когда инженер скажет «давайте перейдём на AV1 SVC», вы точно понимали, что получаете и от чего отказываетесь.

Задача, возникающая из-за разнородной аудитории

Представьте видеозвонок с двенадцатью участниками. Трое подключены за столом по гигабитной оптике, четверо – через гостиничный Wi-Fi, скорость которого колеблется от 3 до 30 Мбит/с, двое – на смартфонах, перемещаясь между вышками, один смотрит конференцию на Smart TV через браузер и ненадёжный mesh-роутер, а ещё двое – это ИИ-агенты в датацентре, которым можно передать поток любого качества. Каждый участник (publisher) отправляет свой видеопоток в Selective Forwarding Unit – сервер, который не декодирует и не перекодирует медиа: он анализирует заголовки пакетов и пересылает нужные пакеты нужным подписчикам. (Контекст по топологиям – в SFU, MCU и Mesh.) Если бы каждый publisher отправлял только один поток с фиксированным битрейтом, SFU был бы вынужден пересылать его всем подписчикам без изменений. Высококачественный поток, отличный для десктопа, перегрузил бы LTE-канал смартфона и вызвал бы неконтролируемый congestion-эффект; а низкокачественный поток, подходящий для смартфона, на десктопе выглядел бы как размытый прямоугольник.

Это и есть проблема разнородной аудитории. Каждый реальный WebRTC-продукт сталкивается с ней с самого первого дня. Два решения, которые WebRTC-экосистема действительно предлагает в 2026 году – simulcast и SVC, – и почти ни один продукт не выбирает одно в ущерб другому: оба сосуществуют внутри одного сервера, часто даже в одной комнате.

Рисунок 1. Форма задачи. Один publisher; много подписчиков с очень разной сетевой и экранной реальностью. Задача SFU – передать каждому подписчику ту версию, с которой он реально сможет работать.

Simulcast простыми словами

Simulcast – более простая из двух идей. Вместо того чтобы просить кодировщик publisher создать один поток, вы просите его сгенерировать несколько – обычно три – в разных разрешениях и битрейтах, но из одного и того же кадра камеры. Типичная конфигурация: 180p при скорости около 150 кбит/с, 360p – около 500 кбит/с и 720p – около 1500 кбит/с. Каждый из этих потоков – полностью независимое, автономное видео: поток 180p представляет собой полноценное видео, которое может быть декодировано любым совместимым декодером без использования других, и то же самое верно для 360p и 720p. Publisher загружает все три потока на SFU в рамках одной RTP-сессии. SFU обнаруживает три потока, помеченных идентификаторами, указывающими, что они являются альтернативными версиями одного и того же медиаисточника.

Когда подписчик заходит, SFU определяет, какой из трёх потоков ему пересылать. Принятие решения происходит непрерывно и основывается на трёх сигналах: оценке пропускной способности со стороны приёмника, запрошенном приложением слое (поскольку приложение может запросить «самый низкий слой», когда тайл подписчика свёрнут в превью), а также собственных данных SFU о реально производимых потоках. При улучшении сети подписчика SFU выполняет апгрейд – начинает пересылать пакеты более высокого потока, исключая нижний из рассмотрения. При ухудшении сети SFU выполняет даунгрейд – переключается на пересылку нижнего потока и прекращает передачу верхнего.

Механизм нормативно описан в RFC 8853 (январь 2021), Using Simulcast in Session Description Protocol (SDP) and RTP Sessions. RFC 8853 определяет, как объявлять поддержку simulcast в обмене SDP offer/answer (через медиа-атрибут a=simulcast) и как идентифицировать различные RTP-потоки одного и того же медиаисточника на уровне RTP (с помощью дескриптора источника RtpStreamId; при этом использование расширения заголовка RTP является рекомендованным, но не обязательным – SHOULD-реализация). Документ подготовлен рабочей группой IETF MMUSIC; смежный RFC 8852 определяет сам формат RtpStreamId.

Цена simulcast измеряется в CPU, памяти и аплинке

Платит publisher. Кодировщик publisher параллельно выполняет три независимых кодирования одной и той же камеры. Стоимость по CPU сублинейная, поскольку уменьшенные по разрешению входные данные кодируются дешевле, а многие кодеки переиспользуют motion-оценку между разрешениями – но она всё равно остаётся значительной: типичные коэффициенты – от 1,5 до 2,5 по сравнению с одним потоком, в зависимости от кодека, набора разрешений и наличия аппаратного ускорения. То же касается и памяти. Аплинк-канал загружен суммарно тремя потоками: если кодировать 180p на 150 kbps, 360p на 500 kbps и 720p на 1500 kbps, publisher передаёт примерно 2150 kbps на эту камеру против 1500 kbps при одном 720p – то есть на 43% больше данных по сети, чтобы дать SFU свободу выбора.

Арифметика вслух. Один поток 720p при 1500 kbps потребляет 1500 kbps аплинка. Трёхуровневый simulcast – 150 + 500 + 1500 kbps – в сумме составляет 2150 kbps. Отношение 2150 ÷ 1500 = 1,43. Publisher платит на 43% больше, чем стоит аплинк, чтобы SFU мог переключать качество для каждого подписчика.

Стоимость для подписчика – нулевая. Каждый подписчик получает ровно один поток – тот, который выбрал SFU, – и декодирует его как обычный RTP-видеопоток. Декодер подписчика при этом не меняется по сравнению с обработкой одного потока. В этом и заключается главный плюс simulcast: вся сложность сосредоточена на стороне издателя и сервера. Подписчик – обычно более многочисленная сторона – остаётся полностью нетронутым.

Где simulcast буксует

CPU и аплинк у publisher – очевидные затраты. Менее очевидные возникают при оптимизации. Три независимых кодирования означают три независимых цикла управления битрейтом, три расписания keyframe’ов и три момента «длинного хвоста», когда keyframe одного потока попадает ровно посередине обновления другого. Затраты на переключение качества невелики, но не нулевые: когда SFU решает перевести подписчика с 360p на 720p, его декодеру нужен keyframe в 720p, чтобы начать обработку, и SFU либо ждёт следующего планового keyframe’а 720p, либо отправляет PLI (Picture Loss Indication) – RTCP-сообщение обратной связи к publisher с просьбой отправить keyframe немедленно. PLI к publisher вызывает дополнительный keyframe во всех simulcast-слоях, что на короткое время увеличивает объём передаваемых данных. Подбор интервала keyframe’ов с учётом баланса между задержкой переключения и эффективностью использования полосы – одна из стандартных эксплуатационных задач при использовании simulcast.

Simulcast также даёт грубую настройку качества. При трёх слоях у вас – три варианта для подписчика. Если нужна более плавная адаптация между ними, её нет: кодировщик генерирует ровно три потока. SVC, следующий раздел, как раз устраняет это ограничение.

Рисунок 2. Стоимость simulcast по пропускной способности и нагрузке на CPU для publisher. Подписчик получает один поток; publisher несёт «налог за многократное кодирование».

SVC простыми словами

Scalable Video Coding – это другой подход к той же задаче. Вместо того чтобы просить кодировщик создать N независимых потоков, вы просите его сгенерировать один поток, организованный во вложенные слои. Базовый слой представляет собой полную, декодируемую, но низкокачественную версию видео. Слои-расширения, добавленные к базовому, позволяют повысить качество изображения. Любой префикс слоёв – от «только базовый» до «все» – сам по себе является валидным потоком, который можно декодировать в корректное видео. Кодировщик использует зависимости между слоями в области движения и частотной области так, чтобы суммарная битовая стоимость «базовый + расширения» была близка (но не равна) стоимости прямого кодирования высококачественной версии.

Слои бывают двухмерными, иногда – трёхмерными. Временные слои разделяют частоту кадров: базовый временной слой – 7,5 fps, плюс один слой-расширение до 15 fps и ещё один – до 30 fps. Пространственные слои делят разрешение: базовый пространственный слой – 180p, плюс расширение до 360p и ещё одно – до 720p. Некоторые кодеки поддерживают также слои по качеству (SNR) – при одинаковом разрешении и частоте кадров, но разной степени детализации. W3C Scalable Video Coding (SVC) Extension for WebRTC стандартизирует компактную систему обозначений: LxTy означает x пространственных и y временных слоёв. L1T3 – один пространственный слой с тремя временными, то есть чисто временной SVC, доступен в любом кодеке WebRTC, включая VP8 и H.264. L3T3 – три пространственных и три временных слоя, то есть полный spatial+temporal SVC, поддерживается только в VP9 и AV1.

Когда SFU получает SVC-поток, он пересылает только те пакеты, которые относятся к слоям, необходимым подписчику. Поскольку кодировщик помечает каждый пакет своим слоем – через заголовок, специфичный для формата полезной нагрузки (VP9 payload descriptor для VP9, AV1 Dependency Descriptor для AV1), – SFU может принимать решение о каждом пакете отдельно: отбросить или переслать. Декодер подписчика собирает полученные пакеты в корректное изображение с разрешением и частотой кадров, соответствующими пересланным слоям.

Цена SVC – в сложности кодировщика и поддержке кодеков

CPU-потребление у SVC ниже, чем у simulcast, потому что используется только одно кодирование, хотя кодировщик выполняет более сложную задачу: он поддерживает reference-ссылки между слоями и помечает каждый выходной пакет, указывая, к какому слою он относится. Эмпирически SVC-кодирование при том же качестве и разрешении требует примерно 1,1–1,4× вычислительных ресурсов по сравнению с одиночным кодированием – что заметно меньше, чем 1,5–2,5× у трёхуровневого simulcast. Потребление аплинк-полосы также ниже: благодаря слоевым зависимостям суммарный размер потока «180p + 360p + 720p» при SVC-доставке составляет примерно на 10–25% меньше, чем при передаче тех же трёх потоков в simulcast, поскольку расширительные слои передают только различия, а не полные копии кадров.

Стоимость для подписчика по сути остаётся нулевой. Декодер подписчика получает частичный поток – только те слои, которые SFU выбрал для пересылки, – и обрабатывает его как обычное видео. Декодер должен поддерживать SVC-профиль кодека, однако любой современный декодер VP9 и AV1 с этим справляется.

Подвох – в поддержке кодеков. SVC требует кодека, который определяет семантику масштабируемости, а механизмы SDP/RTP предполагают, что обе стороны понимают эту семантику. Практическая картина на 2026 год такова:

  • VP8: поддерживается только временная масштабируемость (temporal SVC) (L1T2, L1T3). Пространственные слои отсутствуют. Поддерживается во всех браузерах, где работает VP8 – то есть во всех современных.
  • H.264: поддерживается только временная масштабируемость (temporal SVC) (L1T2, L1T3). Доступна во всех браузерах с поддержкой H.264, включая Chromium-браузеры с момента появления у них поддержки simulcast.
  • VP9: полная пространственно-временная масштабируемость (spatial+temporal SVC) до L3T3 и его вариантов L3T3_KEY. Поддерживается в Chrome, Firefox и Edge; Safari может декодировать VP9, но не кодировать – пользователи Safari не могут транслировать VP9 SVC.
  • AV1: полная пространственно-временная масштабируемость (spatial+temporal SVC), включая L3T3 и множество дополнительных режимов. Кодирование и декодирование доступны в Chromium-браузерах и Firefox (с некоторыми ограничениями); Safari поддерживает декодирование AV1 на устройствах с аппаратным ускорением AV1 (iPhone 15 Pro и новее, Mac на Apple Silicon), но кодирование AV1 пока недоступно.

Гэп в Safari – практическая стена, держащая simulcast в живых. Если в вашем продукте есть Safari-publisher'ы, на VP9 или AV1 SVC рассчитывать нельзя; падаете на simulcast в VP8 или H.264. Поэтому каждый продакшен-SFU 2026 года поддерживает и simulcast, и SVC, нередко в одной комнате.

Рисунок 3. Simulcast (слева) против SVC (справа). Simulcast – это N независимых потоков; SVC – один поток с N вложенными слоями. Логика пересылки в SFU структурно похожа; семантика кодировщика и кодека – нет.

Режимы масштабируемости на примерах

Спецификация W3C webrtc-svc определяет режим масштабируемости, который вы задаёте на стороне кодировщика. Вы передаёте строку вида "L1T3" или "L3T3_KEY" в поле encodings[i].scalabilityMode при вызове RTCRtpSender.setParameters(). Если кодировщик поддерживает запрошенный режим для указанного кодека, он настраивает граф зависимостей соответствующим образом и помечает каждый выходной пакет. Приёмнику не нужно знать, какой режим использовался – информация о принадлежности к слою содержится в payload descriptor.

Соглашение об именовании легко понять, если один раз разобраться:

  • L1T1 – один пространственный, один временной слой. Без SVC; обычное одиночное кодирование.
  • L1T2 – один пространственный, два временных слоя. Делит частоту кадров на половину и полную. SFU может передать «каждый второй кадр» загруженному подписчику и «каждый кадр» – свободному, из одного и того же входного потока.
  • L1T3 – один пространственный, три временных слоя. Делит частоту на четверть, половину и полную. Самый распространённый вариант temporal SVC в продакшене 2026 года.
  • L2T3 / L3T3 – два или три пространственных слоя, три временных. Полная поддержка spatial+temporal. Доступно только в VP9 и AV1.
  • L3T3_KEY – вариант, при котором нижние пространственные слои не зависят от верхних на ключевых кадрах, что делает переключение между слоями более плавным, но ценой небольшого увеличения объёма данных. Именно этот режим LiveKit использует по умолчанию при публикации в VP9 или AV1.

Числовой пример: временные слои и сколько полосы «съедает» подписчик в 360p

Пусть publisher кодирует 720p VP9-поток в L1T3 – один пространственный слой 720p, три временных слоя с частотами 7,5 / 15 / 30 fps. Кодировщик настроен на суммарный битрейт 1500 кбит/с при 30 кадрах в секунду. Типичное распределение битрейта в SVC выделяет примерно половину битов базовому временному слою и по четверти – каждому из расширений, то есть типичная разбивка составляет 750 / 375 / 375 кбит/с по трём слоям.

Подписчик с ограниченным мобильным соединением запрашивает «только нижний temporal-слой» – SFU передаёт только базовый слой, и подписчик декодирует видео в разрешении 720p при 7,5 кадрах в секунду, потребляя 750 кбит/с. Подписчик с качественным десктопным каналом получает все три слоя – SFU пересылает полный поток, и тот декодирует 720p при 30 кадрах в секунду, расходуя 1500 кбит/с. При этом один и тот же исходный поток от издателя (1500 кбит/с) обслуживает обоих подписчиков одновременно; меняется лишь решение SFU. В случае simulcast издатель был бы вынужден закодировать и передать два отдельных потока – один на 7,5 fps, другой на 30 fps, – чтобы предоставить SFU аналогичный выбор.

Преимущество SVC заключается в эффективности использования полосы пропускания – и оно масштабируется: каждый дополнительный слой, который SFU может передать, даёт новый вариант качества без необходимости отправлять полностью новый закодированный поток в аплинк от publisher’а. Недостаток – ограничение по поддерживаемым кодекам, уже рассмотренное выше. Это преимущество проявляется в комнатах, где кодеки, используемые publisher’ами, могут быть декодированы подписчиками.

Как SFU реально решает, какие слои пересылать

Эффективная receive-полоса подписчика – главный вход SFU. Большинство продакшен-SFU используют per-subscriber оценщик пропускной способности поверх transport-wide congestion control – TWCC RTP header extension поддерживают LiveKit, mediasoup, Janus и SFU на базе Pion. TWCC позволяет подписчику сообщать publisher (через SFU) о времени прихода каждого пакета, что подаёт данные в оценщик пропускной способности на стороне SFU. Тот выдаёт оценку в байтах в секунду, соответствующую реальной пропускной способности канала подписчика. Подробное описание оценщика приведено в работе IETF transport-wide congestion control и в реализации Google Congestion Control в libwebrtc.

Зная полосу подписчика, SFU выбирает набор слоёв, максимально эффективно её используя, но не превышая лимит. Для simulcast – пересылается самый высокий поток, средний битрейт которого укладывается в оценку полосы, с гистерезисом для предотвращения дребезга. Для SVC – пересылается наибольший возможный префикс слоёв, который помещается в доступную полосу. SFU также предоставляет приложению API для подсказок – ограничение, которое может перекрывать оценку полосы и применяется, когда тайл подписчика настолько мал, что 180p оказывается достаточным, независимо от возможностей сети. consumer.setPreferredLayers() в mediasoup и параметры подписки в LiveKit реализуют именно такой подход; SFU воспринимает их как верхний предел для слоя, который выбирает оценщик полосы.

Решение о пересылке – непрерывный процесс. Каждые 100–500 мс (в зависимости от SFU) выполняется цикл per-subscriber: пересчитывается доступная полоса пропускания, выбирается новый слой, обрабатывается PLI от подписчика (что заставляет SFU либо запросить у publisher keyframe, либо перейти на слой, где недавний keyframe уже есть). Когда тайл подписчика меняет размер – пинается участник, превью разворачивается – приложение уведомляет SFU об обновлении preferred layers, и на следующей итерации цикла учитывается новый лимит.

Распространённая ошибка: считать, что SFU «знает» экран подписчика

Частая ошибка при первом деплое – забыть, что SFU сам по себе не знает, какого размера тайл у подписчика. SFU видит полосу подписчика и его RTCP receiver reports, но не видит DOM подписчика и разрешение его экрана. Если подписчик отображает участника в превью 90×90 пикселей в сайдбаре, SFU с радостью начнёт отправлять пакеты в разрешении 720p, чтобы заполнить это превью – если приложение явно не скажет иначе. В результате получается дисбаланс: аплинк SFU к подписчику передаёт гораздо больше байтов, чем тот реально использует визуально.

Решение – передавать состояние UI подписчика: пин / превью, развёрнуто / свёрнуто, видно / скрыто за экраном – в вызов, который устанавливает preferred layer для подписки. mediasoup, LiveKit, Janus, Jitsi Videobridge и Pion – все предоставляют такой хук. Забыт этот механизм – самая частая причина, по которой счёт за WebRTC-продакшен оказывается вдвое выше необходимого.

Что пять основных SFU реально делают в 2026 году

Пять проектов, рассмотренных в Выборе SFU, поддерживают как simulcast, так и SVC, но реализуют логику выбора слоёв и API для издателя по-разному. Ниже – карта на 2026 год.

mediasoup обеспечивает полноценную поддержку simulcast и SVC для кодеков VP8, VP9, H.264 и AV1. API consumer предоставляет preferredLayers и setPreferredLayers() для выбора целевого spatial- и temporal-слоя; SFU выполняет собственный цикл оценки для каждого consumer, на основе которого выбирает фактический слой – с учётом доступной пропускной способности у consumer и доступных слоёв у producer. Поддержка AV1 SVC была реализована в C++-ядре mediasoup раньше, чем у большинства других серверов, и активно используется в продакшене у клиентов с крупномасштабными гибридными решениями на базе Pion/mediasoup.

LiveKit по умолчанию использует simulcast для publisher’ов с кодеками VP8 и H.264, а для VP9 и AV1 автоматически переключается на SVC, запрашивая L3T3_KEY как режим по умолчанию. Функция LiveKit Dynacast связывает решение о пересылке слоёв с видимостью подписчика: поток автоматически ставится на паузу, когда его никто не смотрит, а при снижении качества подписки приостанавливаются отдельные слои (в случае simulcast) или целые потоки (в случае SVC, где отдельные слои приостановить нельзя). LiveKit также поддерживает мульти-кодек simulcast: publisher может транслировать резервный кодек (VP8 simulcast) параллельно с основным (AV1 SVC), чтобы legacy-подписчики из Safari получали рабочий поток, а пользователи Chromium – пользу от AV1. В 2026 году мульти-кодек simulcast остаётся единственным архитектурным решением проблемы поддержки AV1 SVC в кросс-браузерных сценариях, позволяющим сохранить преимущества SVC для тех подписчиков, которым он доступен.

Janus реализует simulcast в плагине videoroom и добавил начальную поддержку AV1-Dependency Descriptor для SVC в 2022 году (Meetecho объединил изменения в PR #2741); с тех пор функционал дорабатывался и к 2026 году стал готов к использованию в продакшене для AV1 в режимах L1T2/L1T3, а также частично – для spatial AV1 SVC. Благодаря плагинной архитектуре Janus, логика выбора слоёв реализуется внутри janus_videoroom и настраивается индивидуально для каждого подписчика через request-API плагина.

Jitsi Videobridge реализует temporal-aware пересылку для VP8 simulcast ещё с до-Октоб-времён: мост выбирает самый низкий temporal-слой, удовлетворяющий ограничениям подписчика. Мост также поддерживает VP9 SVC; AV1 появился вместе с работой над dependency descriptor в libwebrtc, но в типичном развёртывании Jitsi Meet, по умолчанию использующем VP8 simulcast ради кросс-браузерной стабильности, AV1 пока менее протестирован в продакшене, чем VP8 simulcast.

Pion – это WebRTC-библиотека, а не SFU, но она предоставляет необходимые протокольные примитивы (расширения заголовков RTP, парсер AV1 Dependency Descriptor, сообщения обратной связи RTCP), которые требуются SFU на её основе для слой-осознанной пересылки. ion-sfu и LiveKit (построенный на Pion) реализуют сверху саму логику выбора слоёв.

Параллельно: что пишет publisher

// Simulcast на стороне publisher (работает на любом кодеке во всех браузерах)
const sender = pc.addTransceiver(track, {
  direction: 'sendonly',
  sendEncodings: [
    { rid: 'q', maxBitrate: 150_000,  scaleResolutionDownBy: 4 },   // 180p
    { rid: 'h', maxBitrate: 500_000,  scaleResolutionDownBy: 2 },   // 360p
    { rid: 'f', maxBitrate: 1_500_000, scaleResolutionDownBy: 1 },  // 720p
  ],
}).sender;

// SVC на стороне publisher (VP9 или AV1)
const sender = pc.addTransceiver(track, {
  direction: 'sendonly',
  sendEncodings: [
    { scalabilityMode: 'L3T3_KEY', maxBitrate: 1_500_000 },
  ],
}).sender;

Simulcast явно указывает три потока с параметрами rid и scale-фактором; SFU видит три отдельных потока. SVC запрашивает одно encoding с scalabilityMode; SFU воспринимает один поток с встроенными метаданными слоёв. Прикладной код для SVC проще – но ценой этого становится ограничение на поддерживаемые кодеки.

Полоса пропускания, качество и компромисс в реальном продакшене

При одинаковом целевом качестве на верхней ступени SVC потребляет меньше пропускной способности аплинка от publisher, чем simulcast – обычно на 10–25%, в зависимости от кодека и контента. При одинаковом использовании CPU publisher кодирует сопоставимый объём пикселей с несколько меньшей сложностью, чем три независимых simulcast-потока. Стоимость на стороне SFU также сопоставима: оба решения работают на уровне пересылки RTP-пакетов, и зрелый SFU обрабатывает оба формата с примерно одинаковыми затратами CPU на поток.

Вторая сторона ведомости – устойчивость. Simulcast устойчив к сбоям слоя: если на мгновение падает 720p из-за всплеска нагрузки на CPU у publisher, 360p и 180p продолжают работать, и SFU продолжает их пересылать. SVC менее устойчив к таким сбоям: если выходит из строя верхний spatial-слой, зависимые enhancement-кадры становятся недекодируемыми, и кратковременный сбой может затягиваться из-за блокировки в графе зависимостей. Вариант L3T3_KEY спроектирован специально для смягчения этой проблемы – его структура ключевых кадров (keyframe) отсоединяет нижние spatial-слои от верхних, что делает переключение между слоями более плавным, а восстановление после сбоя – быстрее.

Латентность переключения качества также различается. В случае simulcast переключение требует нового keyframe на целевом слое; в худшем сценарии SFU отправляет PLI и ждёт следующий принудительный keyframe от издателя. При SVC переключение на более низкий слой по сути бесплатное – достаточно отбросить верхние пакеты и декодировать остаток, – тогда как переход на более высокий слой требует восстановления цепочки зависимостей, что L3T3_KEY делает возможным без полного round-trip по keyframe от издателя.

Продакшен-паттерн 2026 года для большинства команд: simulcast по умолчанию, SVC там, где покрытие кодеков это позволяет, и мульти-кодек fallback ради Safari-паблишеров. Цахи Левент-Леви в Five WebRTC Predictions for 2026 отмечает, что в 2026 году AV1 ещё не станет доминирующим WebRTC-кодеком; VP8 и H.264 остаются рабочими лошадками, а AV1 SVC будет расти там, где выгода от экономии полосы оправдывает дополнительную интеграционную работу. Реалистичный выход AV1 SVC на роль умолчания для кросс-браузерных паблишеров – не ранее 2028 года, гейт – момент, когда Safari отгрузит AV1-encoder.

Где здесь Фора Софт

В нашей практике WebRTC, конференций, телемедицины и e-learning simulcast в VP8 остаётся кросс-браузерным решением по умолчанию для новых сборок – особенно в продуктах с издателями на Safari, где SVC использовать невозможно. VP9- или AV1 SVC мы применяем только в деплоях на базе Chromium, в комнатах с ИИ-агентами и в broadcast-каналах, где экономия полосы напрямую влияет на реальные затраты. Наиболее стабильным эксплуатационным преимуществом во всех этих проектах стало передачу состояния UI подписчика (закрепление, превью, скрыто) в подсказку при выборе слоёв SFU, независимо от используемой технологии публикации. Такой подход регулярно снижает исходящий трафик SFU на 30–60% в комнатах с большим количеством мелких тайлов и одинаково эффективен как для simulcast-, так и для SVC-подписчиков.

Рисунок 4. Как выбирать между simulcast и SVC по состоянию на 2026 год. Покрытие publisher'ов по браузерам – первый критерий; всё остальное можно обсудить позже.

Главное

  • Simulcast – это N независимых кодировок; SVC – одна кодировка с N вложенными слоями. По структуре пересылки SFU работает аналогично.
  • Simulcast совместим со всеми WebRTC-кодеками, включая VP8 и H.264; SVC требует VP9 или AV1 для пространственных слоёв (temporal-only SVC работает везде).
  • В обеих техниках нагрузка ложится на publisher: у simulcast она составляет 1,5–2,5× CPU, у SVC – 1,1–1,4×; затраты на стороне подписчика практически отсутствуют.
  • Ограничения Safari при кодировании VP9 и AV1 делают мульти-кодековый simulcast (simulcast в VP8 + SVC в AV1 в одной комнате) реальным решением для продакшена в 2026 году.
  • Передача состояния UI подписчика в подсказку выбора слоёв SFU – наиболее эффективная оптимизация вне зависимости от выбранной техники.

Что читать дальше

CTA

  • Поговорить с инженером стриминга – обсудить архитектуру simulcast/SVC для реального продакшена.
  • Посмотреть кейсы – конференции, телемедицина и e-learning в портфолио Фора Софт.
  • Скачать чек-лист simulcast vs SVC – одностраничный PDF: сравнение side-by-side, режимы масштабируемости по кодекам и дерево решений 2026. Скачать (PDF)

Строите такую систему?

Подберём параметры кодирования под ваш контент и посчитаем стоимость доставки до старта разработки.