Боротьба з втратами пакетів у відеоконференціях

Введення
Коли говорять про передачі відео по мережі, в основному мова йде про відео-кодеки і дозволі. Власне про передачу відео чути не так і багато. Тут я б хотів пролити трохи світла на проблему боротьби з втратами в мережі при передачі відео в режимі відеоконференцій. Чому втрати — це так важливо? Та тому що не можна просто так взяти і пропустити хоч один відео пакет (на відміну від аудіо), т. до. будь-який пристойний відео-кодек заснований на тому, що послідовні кадри відрізняються не сильно і досить закодувати і передати тільки різницю між кадрами. Виходить, що (майже) будь-який кадр залежить від попередніх. І картинка при втратах розвалюється (хоча деяким це навіть подобається). Чому відеоконференції? Тому що є дуже жорстке обмеження на реальний час, адже затримка у 500мс на коло (туди-назад) вже починає дратувати користувачів.
Які ж існують методи боротьби з втратами відео-пакетів?
Ми тут розглянемо найпоширеніший варіант — передача медіа за протоколом RTP — поверх UDP.

RTP і UDP
Медіа дані реального часу, як правило, передаються по протоколу RTP (RFC 3550). Тут нам важливо знати про нього три речі:
  1. Пакети пронумеровані по порядку. Так що будь-який розрив у порядковому номері (sequence number) означає втрату (хоча може означати затримку пакета — тут різниця може виявитися дуже тонкої).
  2. Крім пакетів RTP стандарт передбачає також службові пакети RTCP, з допомогою яких можна всяке (див. нижче).
  3. Як правило RTP реалізований поверх UDP. Це забезпечує швидку доставку кожного окремого пакету. Трохи більше про TCP написано нижче.
Відразу зауважу, що тут мова йде про пакетних мережах, наприклад IP. А в таких мережах дані псуються (губляться) відразу великими порціями — пакетами. Так що багато методи відновлення одиночних/нечисленних помилок в сигналі (популярні, наприклад, DVB) тут не працюють.
Ми будемо розглядати боротьбу з втратами в історичній перспективі (благо технологія відеоконференцій досить молода і ні один метод ще не застарів остаточно).

Пасивні методи
Розбиття відеопотоку на незалежні шматки
Перший успішний відео-кодек для конференції в мережі — H. 263. У ньому були добре опрацьовані основні пасивні методи боротьби з втратами. Найпростіший з них — розбити відео на шматки, які будуть незалежні один від одного. Тим самим втрата пакета з одного шматка не позначається на декодуванні інших.
Розбивати на шматки потрібно як мінімум по часу, а можна ще і по простору. Розбиття по часу полягає в періодичній (зазвичай раз в 2 з) генерації ключового кадру. Це такий кадр, який не залежить від усієї попередньої історії, а значить і кодується значно (~5-10 разів) гірше звичайного кадру. Без генерації ключових кадрів при будь-якій кількості втрат рано чи пізно картинка розвалиться.
По простору кадр теж можна розбити. Для цього в H. 263 використовуються GOBs, а у H. 264 — slices. По суті це одне і теж — шматки кадру, кодування яких не залежить один від одного. Але для правильної роботи потрібно також забезпечити для кожного слайсу незалежність від інших слайсів попередніх кадрів. Виходить, ніби кодуються паралельно кілька відеопослідовностей, з яких на виході геометрично збирається підсумкова картинка. Це, звичайно, сильно псує якість кодування (або підвищує бітрейт, що, по суті, теж саме).

Залежності між слайсами двох послідовних зображень. Помаранчевим зазначені ділянки, які могли б бути передбачені за попереднього зображення, якби не обмеження по слайсам (а значить ці ділянки могли б бути стиснуті в 5-10 разів ефективніше)
Тут важливо зауважити, що якщо генерація ключових кадрів — стандартна процедура (наприклад, перший кадр завжди ключовий), то забезпечення дійсної незалежності слайсів — досить нетривіальна задача, яка може зажадати переробки енкодера (а звідки у вас енкодери і як важко його переробити нікому не відомо).
Відновлення помилок

Приклад відновлення одного втраченого слайсу (пакета)
Якщо втрата сталася, можна спробувати максимально відновити втрачені дані з наявними (error resilience). Тут є один стандартний метод, закладені в H. 263 кодеку: втрачений GOB відновлюється за рахунок лінійної інтерполяції оточуючих GOBов. Але в загальному випадку картина більш складна і помилка декодування поширюється з кожним новим кадром (т. к. на нових кадрах можуть бути посилання на пошкоджені ділянки попереднього кадру), так що для розумного замащування зіпсованих місць прийде застосовувати витончені механізми. Загалом праці тут багато, а через 2 секунди прийде ключовий кадр і оновить всю картинку, так що гарні реалізації цього методу існують, схоже, лише уявою розробників.
Forward Error Correction
Ще один хороший метод боротьби з втратами — використовувати надлишкові дані, тобто посилати більше, ніж потрібно. Але просте дублювання тут виглядає не дуже добре рівно тому, що є методи у всіх відношеннях більш якісні. Називається це FEC (RFC 5109) і устроенно наступним чином. Вибирається група медіа (інформаційних) пакетів заданого розміру (наприклад 5), а на їх основі зізнаються кілька (приблизно стільки ж або менше) FEC пакетів. Легко домогтися, щоб FEC пакет відновлював будь пакет з інформаційної групи (parity-codes, наприклад RFC 6015). Дещо важче, але можна досягти того, щоб N FEC пакетів відновлювали N інформаційних при групових втрати (наприклад, коди Ріда-Соломона, RFC 5510). В загальному метод ефективний, часто легко реалізується, але дуже дорогий в плані каналу зв'язку.

Активні методи
Перезапросы пакетів і ключових кадрів
З розвитком відеоконференцій швидко стало ясно, що пасивними методами багато чого не доб'єшся. Почали застосовувати активні методи, які за своєю суттю очевидні — потрібно заново відправляти загублені пакети. Існує три різних перезапроса:
  1. Перезапрос пакета (NACK — negative acknowledgement). Втратили пакет — попросили його ще раз — отримали — декодировали.
  2. Запит ключового кадру (FIR — full intra-frame request). Якщо декодер розуміє, що все пішло погано і досить давно, можна відразу просити ключовий кадр, який зітре всю історію і можна буде почати декодування з чистого аркуша.
  3. Запит оновлення певної області кадру. Декодер може повідомити енкодеру, що якийсь пакет втрачено. На основі цієї інформації енкодери обчислює, як далеко поширилася помилка по кадру і оновлює тим або іншим способом пошкоджений регіон. Як це реалізувати зрозуміло тільки теоретично, практичних реалізацій я не зустрічав.
З методами начебто визначилися — а як це реалізовано на практиці. А на практиці є пакети RTCP — ось ними можна скористатися. Стандартів відправлення таких запитів як мінімум три:
  • RFC 2032. Насправді це стандарт упаковки потоку кодека H. 261 RTP пакети. Але цим стандартом передбачено і перезапросы перших двох типів. Цей стандарт застарів і замінений на RFC 4587, в якому пропонується такі пакети ігнорувати.
  • RFC 4585. Діючий стандарт. Передбачає всі три варіанти і навіть більше. На практиці використовується саме NACK і FIR.
  • RFC 5104. Теж діючий стандарт. Частково дублює RFC 4585 (але не сумісний з ним) плюс купа іншої фунциональности.
Ясно, що активні методи набагато складніше в реалізації, ніж пасивні. І не тому, що важко сформувати запит або перепослать пакет (хоча підтримка одночасно трьох стандартів дещо ускладнює питання). А тому що тут потрібно вже контролювати те, що відбувається, щоб перезапросы не були занадто ранніми (коли «втрачений» пакет просто ще не встиг дійти) або занадто пізніми (коли вже давно пора було б відобразити картинку). Ну а в разі тимчасових великих проблем в мережі пасивні методи відновлюють зв'язок протягом 2-х секунд (прихід ключового кадру), в той час як наївна реалізація перезапросов може запросто перевантажити мережу і ніколи не відновитися (приблизно так подвисало відео в скайпі кілька років тому).

Приклад зависання відео після 3х секундного розриву зв'язку при наївною реалізації перезапросов.
Але ці методи при адекватної реалізації є ще і набагато більш якісними. Немає необхідності знижувати якість за рахунок генерації ключових кадрів, розбиття на слайсы або щоб дати місце FEC пакетів. В цілому, можна домогтися дуже невеликого оверхеда по бітрейту з тим же результатом, що й у «дорогих» пасивних методів.
TCP
Стало більш-менш зрозуміло, чому не використовується протокол TCP. Це самий наївний метод перезапроса пакетів без серйозних можливостей його контролювати. До того ж у ньому передбачено тільки перезапрос пакету, а перезапрос ключового кадру в будь-якому випадку доведеться реалізовувати поверх.

Інтелектуальні методи
Ми тут стосувалися поки що тільки боротьби з втратами. А як же ширина каналу? Так — ширина каналу важлива, і проявляється вона в кінцевому підсумку тими ж втратами (плюс збільшенням часу доставки пакета). Якщо відео-кодек налаштований на бітрейт, який перевищує ширину каналу зв'язку, то намагатися боротися з втратами в цьому випадку — заняття малоосмисленное. В цьому випадку потрібно знижувати бітрейт кодека. Ось тут то вся хитрість і починається. Як визначити, який бітрейт виставити?
Основні ідеї наступні:
  • Необхідно точно і оперативно стежити за поточною ситуацією в мережі. Наприклад, через RTCP XR (RFC 3611) можна отримувати звіт про доставлених пакетах і їх затримки.
  • При погіршенні умов скидати бітрейт (що таке погіршення умов? Як швидко скидати?).
  • При нормалізації умов можна почати промацувати верхню межу бітрейта. Щоб при цьому картинка не розвалювалася, можна, наприклад, включити FEC і піднімати бітрейт. При настанні проблем FEC дозволить картинці залишитися коректною.
Загалом саме інтелектуальні методи оцінки параметрів мережі і підстроювання під них на сьогодні та визначають якість систем відеоконференції. У кожного серйозного виробника є своє пропрієтарне рішення. І саме розвиток цієї технології є основною конкурентною перевагою систем відеоконференцій на сьогоднішній день.
До речі, стандарт 3GPP TS 26.114 (один із головних стандартів для побудови промислових VoIP мереж) стверджує, що в ньому міститься опис подібного алгоритму для аудіо. Не цілком ясно, наскільки описаний алгоритм хороший, але для відео він не підходить.

Машина станів алгоритму адаптації до мережевих умов у поданні художника (3GPP TS 26.114)

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.