Всем привет! Я — Алексей Лыков, основатель Playkey. В 2021 году мы стали частью команды VK Play Cloud. Расскажу про cloud gaming, немного компаний в мире делают подобные сервисы. Мы передовики в России, в мире – пока нет.
Остановлюсь подробнее на проблеме latency, где найти наши заветные миллисекунды, причём тут качество cloud gaming и как мы работаем над его улучшением.
![](https://habrastorage.org/getpro/habr/upload_files/12a/cb6/fd2/12acb6fd27311ec66dc854127d841817.jpg)
Немного истории
![](https://habrastorage.org/getpro/habr/upload_files/7ea/cf6/c53/7eacf6c53cdcdc20348538dc96bbdbbf.jpeg)
В 2013 году мы работали над сервисом Playkey, я стал его основателем. Два года мы пилили прототип. Первый сделали за два месяца, можно было уже поиграть. Потом много лет его усовершенствовали.
В 2015 году у нас был первый коммерческий запуск, мы запускали простые игрушки на одной машине, несколько экземпляров. Всё это работало плохо и ужасно. Потом у нас была большая смена бизнес-модели, мы стали запускать топовые игрушки.
В 2021 году в июне Playkey стал частью команды MY.GAMES Cloud. В сентябре 2022 года сервис был переименован в VK Play Cloud.
Cloud gaming
Кратко о cloud gaming: на клиентское приложение, машину, ставят тонкий клиент — это Windows, Mac, веб-браузер, смарт-ТВ или андроид платформа. Подойдёт любой девайс, воспроизводящий видео. Получается сервер с несколькими видеокартами виртуальной машины, с пробросами в каждую. Мы создаём полноценный игровой компьютер в Облаке. Есть шеринг ресурсов и видеокарты, но он тоже изолирован для каждой виртуальной машины.
Пользователь на девайсе запускает клиент, отправляет управление через Интернет на сервер. На нём запускается любая мощная игрушка, которая не заработает дома по разным причинам. Например, в смарт-ТВ нельзя запустить Warface. Дальше рендерится картинка, упаковывается видеопоток, и этот сигнал идёт обратно. Таким образом, пользователь видит картинку.
Всё это должно работать быстро. Ведь, так себе вариант, нажать кнопочку и увидеть, что вы стреляете из автомата через одну секунду.
![](https://habrastorage.org/getpro/habr/upload_files/16e/471/b0a/16e471b0ac071777c0b361db9dec8f6d.jpeg)
Если из этой схемы исключить сервер и Интернет, то получится локальный компьютер. Если исключить Интернет, то будет локальная сеть, по ней всё работает отлично. Большие проблемы в сервис VKPlay CLoud вносит Интернет. Там есть задержки, пинг, сети несовершенны, происходят потери пакетов, лаги. Всё это влияет на экспириенс наших пользователей. Что с этим делать?
VKPlay CLoud – это работающий проект, многие разработчики сомневаются можно ли так играть. Наши пользователи доказали, что играть можно. Они подписываются, платят и пользуются сервисом, им так удобнее, интереснее и проще. Понятно, что он не нужен киберспортсменам и профессиональным геймерам или разработчикам с мощными компьютерами, которые могут поставить у себя любую современную игрушку.
С VKPlay CLoud можно сэкономить, не покупать видеокарту за 100 000, а играть на любом слабом или старом ноутбуке. Даже те, кто сидит на MacBook, могут играть в любую современную игрушку. Потратить 10 часов, пройти какую-то игру, пользоваться сервисом и получать удовольствие.
Типы сервисов передачи видео
![](https://habrastorage.org/getpro/habr/upload_files/92d/b84/580/92db84580e6bd47c116df0a4652c77aa.jpeg)
Видеостриминг делится на три категории сервиса. Это видеохостинги, где нужно скачать видеофайл и смотреть его на Ютубе, Рутубе или ВК Видео. Здесь latency в целом не критична, не так страшна. То есть, не страшно, если видео воспроизведется после 1 секунды с момента нажатия на кнопку и закэшироваться локально.
В видеоконференциях latency более критична. Можно разговаривать с человеком и видеть его через полсекунды. Это тоже не страшно, потому что нет абсолютного интерактива.
В cloud gaming интерактив очень важен. Вы нажали кнопочку «вперед», и хотите чтобы ваш персонаж пошёл на экране, а это полный цикл от отправки управления на сервер и обратно. При задержке latency больше 50-70 миллисекунд, начинается резкое падение и недовольство пользователей по поводу cloud gaming сервиса.
Что влияет на Latency
![](https://habrastorage.org/getpro/habr/upload_files/0ac/e5a/930/0ace5a93020e0f0585f60e49cccca0f9.jpeg)
Покажу общую схему. Задержки есть везде, банально управление. Например, беспроводной gamepad – это лишние 5 миллисекунд по блютуз. Дальше идёт передача в клиентское приложение. Оно отправляет через сеть, где происходит задержка сетевая, первая в одну сторону. Дальше это управление попадает на сервер и в игровой процесс, где тоже есть latency. Происходит видео рендеринг, в зависимости от количества ФПС, которые выдаёт игра. Это может быть 30, 60 и 120 ФПС. В супер нагруженных игрушках, даже на мощных видеокартах бывает 30-40 ФПС. Это значит, что межкадровый интервал 20-30 миллисекунд, от чего и все задержки.
Дальше нужно видео закодировать. Это тоже время, плюс еще сколько-то миллисекунд. Аппаратные работают быстрее, софтверные – чуть медленнее, но универсальнее. Всё это отправляется по сети и передается так, чтобы видео с битрейтом 20-30 мегабит/с не потерялось. После видео декодируется на клиенте через аппаратные декодеры, рендерится и показывается пользователю, при этом на каждом шаге есть задержки.
В cloud gaming мы стараемся их минимизировать на каждом этапе, как мы это делаем, расскажу далее. Итак, у нас запускается игра на сервере.
Как минимизировать задержки
Ищем заветные миллисекунды
![](https://habrastorage.org/getpro/habr/upload_files/74f/66a/bc3/74f66abc34b5de37d23cc93215b28eb4.jpeg)
На схеме два способа захватить картинку на Windows. Для примера взял именно Windows, 95% всех игр запускается на ней и только 5% на Linux, при этом мы поддерживаем обе операционные системы. В Windows есть Windows API, он позволяет захватить окно операционной системы, получить эту картинку, скопировать себе в буфер и дальше отправить на декодер. Этот способ универсальный. Он захватывает все изображения винды, работает во вне операционной системы с любой игрой. Но происходят задержки при синхронизации захвата и рендеринга игры.
Второй способ — shared capture. Мы инжектимся в игровой процесс без задержки, без синхронизации игры и рендеринга. Когда игра зарендерила видеокадр, то мы инджектнемся в этот момент, захватываем картинку и сразу отправляем на энкодер. В этом варианте задержки не возникает. Это, около 60-ти кадров в секунду с межкадровым интервалом 16 миллисекунд. Потери позволяют нам сэкономить, но способ не универсален и работает только для некоторых игр. Когда инжектишься в игру, она считает вас ботами.
Когда-то, мы этим способом подключили игру, там был такой античит EasyAntiCheat. В какой-то момент античитерская система начала банить аккаунты наших пользователей. Они негодовали и обратились в нашу поддержку. Мы договорились с античитом, что они добавят нас в белый список и пользователей разбанили. Этот способ не универсален, но дает небольшую экономию.
![](https://habrastorage.org/getpro/habr/upload_files/1c7/cd9/d1a/1c7cd9d1a6d0ffda7038f6cd1a1d3ba0.jpeg)
Еще одно место сэкономить заветные миллисекунды - найти решение в рассинхронизация видео и аудио. Когда вы смотрите Ютуб, видео и аудио синхронизированы, звук и картинка поступают одновременно. С cloud gaming это не так важно, главное доставить любые данные до клиента. И видеопоток шире — 30 мегабит/с, аудиопоток — 128 килобит/с. Пользователь слышит аудио и ощущает, что он в игре. Небольшая рассинхронизация на это не влияет. 5-10 миллисекунд задержки видеопотока не страшны.
Как еще оптимизироваться
![](https://habrastorage.org/getpro/habr/upload_files/6df/c64/5d5/6dfc645d509738bfd1feb9c0b714aa44.jpeg)
Захват управления на устройстве разными способами. Поскольку запросы здесь синхронные, приходится спрашивать управление, это приводит к нагрузкам. Чем чаще спрашиваешь, тем больше нагрузка. Важно понимать, мы работаем на клиентских устройствах, которые слабые сами по себе. В парке у тестировщиков есть компьютеры 2010 года. Шайтан-машина — это тест, когда происходит запуск даже на очень древнем компьютере. Там любая нагрузка создает проблемы при захвате. Это всё должно работать в синхроне с рендерингом, декодингом, захватом и управлением.
Устройства с проводным подключением к интернету работают быстрее. Работа по проводу Интернета дает чуть большую скорость, потому что нет проблем с вай-фай. Мы советуем это нашим пользователям, зачастую они приходят и говорят, у нас задержка, что-то лагает, что-то не так.
Лагает — это любимая фраза под которой большое количество разных проблем. Не только с большой герцовкой. Значит, будет выше ВПС, использование аппаратного кодирования. Это очевидно, но тоже добавляет миллисекунды.
Еще совет — не нагружать сто процентов систему как на клиенте, так и на сервере. Есть требовательные игрушки. Если на них выставить 4К или full HD разрешение, супер ультра настройки по максимуму, то сервер загружается на сто процентов. Он начинает подлагивать, и нашему приложению может просто не хватать ресурсов.
Поэтому у нас есть целая команда, которая настраивает игры и делает предустановки на наших серверах. У нас есть сервера с разными конфигурациями. Всего их около 10, в первую очередь конфигурации по видеокарте, потому что это основное, что важно для cloud gaming. В зависимости от тарифа они предустанавливают и делают настройки оптимальные для пользователей. Ещё они подстраиваются в процессе игры в зависимости от клиентского устройства.
Про качество
Немножко расскажу про качество и почему оно здесь. Есть такое знаменитое: быстро, качественно, недорого. Недорого я убрал, тут оно не так важно.
![](https://habrastorage.org/getpro/habr/upload_files/7ed/0ef/d8d/7ed0efd8d0e051ab4cf99e5da98ee859.jpeg)
Мы делаем всё быстро — нам надо как можно скорее доставить картинку для пользователя, потому что потеря в качестве не так критична. Она важна, но быстрота доставки и задержки гораздо важнее. Пользователю нужно увидеть картинку. Может быть, она будет хуже разрешением, размытая, с лагом в какое-то мгновение, но чтобы продолжить играть, важно быстро увидеть изображение и принять что-то с него.
Про кодеки
![](https://habrastorage.org/getpro/habr/upload_files/087/146/f2b/087146f2b9fa735c4d880731c4a8e949.jpeg)
Кодеков много. Самый популярный h.264, H.265 и серия VP. Что же в нашем случае? Поскольку мы позиционируемся играть на слабых, древних устройствах, у нас есть клиентские аппараты, не поддерживающие что-то выше h.264 кодека. Еще нам важно на сервере иметь аппаратный кодек. Современные карты h.265, h.264 поддерживают, а VP9 нет. Они используют транскодеры для ВК Видео, самописные вещи для видеокарт или всё-таки h.265 как аппаратный кодек.
Это тоже важно, если брать какое-нибудь смарт-ТВ на процессоре Амлоджик, который может не поддерживать h.265. То же самое с современными приставками цифрового телевидения у наших провайдеров. В текущей статистике примерно 20% — кодек h.265-й. Опять же это всё в сторону оптимизации. Про VP9 совсем ничего. Аппаратных поддержек на сервере еще вообще нет. Я имею в виду видеокарты, аппаратно захватывающие изображение и кодирующие его. Если мы будем использовать Software, то на сервере кодирование ВП9 может занять 300 миллисекунд. Это уже значит, что пользователь увидит свою картинку через это время и десятки кадров, что неприемлемо. Поэтому используем 264-й.
Немножко теории кратко.
![](https://habrastorage.org/getpro/habr/upload_files/156/7ef/de7/1567efde79dc08037f8d604ac9568eac.jpeg)
Видеопоток разделяется на кадры, которые делятся на три типа:
I-кадры — базовые, от них следуют все остальные, изображение меняется нечасто;
P-кадры — наследуются от базовых, поддерживают от них большие и средние изменения;
B-кадры — могут ссылаться на все предыдущие и ещё на будущие кадры.
Вещь в кодеке классная. Дает большую экономию в битрейте на видеопоток. Но в cloud gaming, B-кадры не применимы. Если мы будем ссылаться на будущие кадры, которых еще нет, они будут неактуальны. Зачем нам ждать следующий кадр, когда мы можем отправить это? Поэтому возникает проблема, что без B-кадров мы делаем только P-кадры. Требуется большой битрейт в cloud gaming.
Когда мы говорим: «пользователю надо 30 мегабит для full HD», они удивляются, почему так много. Потому что нельзя сделать двухпроходное кодирование, ссылочные кадры, которые уменьшили бы битрейт видео. Поэтому для cloud gaming нужен хороший Интернет-канал – как минимум 30 мегабит.
Про слайсы
![](https://habrastorage.org/getpro/habr/upload_files/0c5/f14/857/0c5f14857c63c6d0b49e3eb65e4fe682.jpeg)
Есть такие вещи как слайсы внутри кодека. Их суть в том, что изображение делится на части. Каждая может быть отправлена отдельно. Почему это важно? Когда мы передаем видео через Интернет, все части делятся на пакеты. Если у нас в процессе что-то потеряется, может разрушиться весь кадр или его часть. В случае, если разрушится часть кадра, мы можем показать часть предыдущего. Пользователь немного заметит изменения, но не так сильно, как если бы у него развалился весь кадр.
Опять же параметр кодека. Хоть и есть стандарты, позволяющие это использовать, как в 264. Но так может случиться, что в аппаратных кодека, в какой-нибудь донгл Андроид китайской приставки просто не поддерживается количество слайсов.
Есть такое понятие, как ссылочные кадры. Их используют при декодинге.
![](https://habrastorage.org/getpro/habr/upload_files/686/40f/a58/68640fa581b4d4a95a17cb08c7b2489d.jpeg)
Например, в h.264 коде есть по стандарту 16 ссылочных кадров, в h.265 – 8. Сложно сказать, почему они так сделали. h.265 считается лучше, но для cloud gaming эффективнее работает h.264, потому что мы можем использовать 16 кадров. Это помогает нам в случае потерь Сети восстановить больше информации и качественную картинку.
У нас был SmartTV на процессоре AmLogic, как чёрный ящик. Мы не знали, что происходит в аппаратном декодере, просто отправляли ему видео, и он начинал рушиться. Мы сталкивались с проблемами где-то 2 месяца, пока не выяснили, что он просто не поддерживал стандарт 16 ссылочных кадров, а поддерживал только один. А у нас картинка рассыпалась. В итоге мы связались с AmLogic и разработчиками процессора. Там идёт реализация под Android библиотеки для аппаратного кодера, они это поправили. На одном из SmartTV телевизоров в России можно хорошо играть в cloud gaming.
Некоторые, особенно старые видеокадры не всё поддерживают. Эволюция идёт, но кто-то играет на старых видеокартах, и мы тоже вынуждены это поддерживать. Мы позиционируемся на том, что играть можно на любом слабом компьютере. За 8 лет мы собрали белый и чёрный списки видеокарт, для которых выставили те или иные настройки. То есть, мы планомерно выстраиваем работу, чтобы улучшать качество по всем нашим пользователям, клиентским девайсам.
Про нестабильность канала
Сеть создаёт одну из самых больших проблем для нас. В первую очередь, это потеря пакетов.
![](https://habrastorage.org/getpro/habr/upload_files/a7b/22b/247/a7b22b2479f4db16ce02a9e9d8a56ed3.jpeg)
Если что-то не дошло до клиентского устройства, у нас возникает разрушение картинки. Бороться с этим сложно, поскольку у нас UDP трафик, досылать нет смысла. Если это 60FPS и один из кадров выпал, то пока мы сообщим об этом, всё станет неактуальным и прилетит уже новый кадр. Поэтому в cloud Gaming есть проблемы. С плохой сетью разваливается картинка. У меня есть видео на Ютубе, где идёт игровой процесс в cloud gaming и тут жена включает микроволновку, и вся картинка разваливается. Потому что микроволновка работает на радиоволнах, вай-фай всё перебивает, картинка разбивается.
Самый сложный вопрос — как это объяснить пользователю. В обучении мы указываем, что не нужно использовать вай-фай, провод лучше. Если нет возможности, то пользуйтесь хотя бы 5GHz wifi, он более надежный. Но под пользователей, в целом, всё равно, поэтому пытаемся как-то подстроиться.
Скачки пинга тоже для качества сети по Wifi актуальны. Когда не происходят потери, а просто буферы накапливаются на сетевом оборудовании, и потом данные выплескиваются в Сеть. У пользователя возникает скачок пинга. Это актуально для Wi-fi, но лаг может возникнуть для любого сетевого оборудования, а у пользователя рассыпается картинка или ломается что-то. Вот они и приходят к нам в сервис с такими проблемами.
Что мы тут делаем? Во-первых, подстраиваемся под ширину канала.
![](https://habrastorage.org/getpro/habr/upload_files/996/fee/d1b/996feed1b0997dc696801e3c21c4335a.jpeg)
Проблема первая - узнать реальную ширину канала у пользователя, хоть и на видеосервисах придумывают как это делать. Просто заменяют битрейт, кэшируют, смотрят как скачалось, с какой скоростью, какое видео закешировалось. Для нас это не так. Мы работаем в реальном времени, начинаем с какого-то базового алгоритма битрейта. Смотрим, что потерялось, выстраиваем актуальный битрейт. Продвинутый пользователь может сам выставить это всё руками.
Мы написали патент, тут участвует не только битрейт, используем много разных способов, как это всё детектировать в реальном времени, а не оффлайн. Обычно пользователи к нам приходят и говорят: «я спидтест запустил, у меня 100 мегабит/с». Но по факту, от нашего сервера, где он стоит до клиента, это реал-тайм, это видео. Поэтому реальность спидтеста немножко не соответствует картине, который в реальном времени можно продавить через канал пользователя.
Какими еще способами мы боремся с потерями? Есть кадры, всё строится от базового I кадра. Он самый массивный, в нём содержится больше всех информации, то есть стартовый кадр. Остальное только изменения. Есть способы, как сглаживать этот битрейт. При этом немного увеличивается общий трафик, или если мы битрейт выравниваем, то через сеть продвигается большее количество данных, таким образом минимизируется вероятность того, что на сети что-то потеряется. Мы назвали это распределенной отправкой данных. Например, можно 1 Мегабит отправить разом в Сеть, и он где-то на оборудовании потеряется. А можно пять раз по 200 килобит сделать, и оно потеряется с меньшей вероятностью. На каком-то коммутаторе в этот момент может быть перегрузка, но в следующую секунду её может и не быть.
У нас большая история с избыточностью, в описанном патенте, она тоже используется. Идея в том, что мы вместе с видеоданными можем добавлять дополнительные данные, которые восстанавливают картинку на клиенте. Это была очень старая история, еще с радиосвязи тянется, когда радио вещали по всей стране. Там добавляли избыточные данные, так называемые коды Рида-Соломона. Или какие-то более простые алгоритмы. Приходя на клиент, разбирались эти данные. Там была избыточность, которая позволяла что-то восстановить, если вдруг в радио были помехи.
![](https://habrastorage.org/getpro/habr/upload_files/91e/a5b/9a9/91ea5b9a93732962e7b4eb2242fa9819.jpeg)
Мы используем то же самое. Адаптируем объем избыточности в зависимости от того, какой канал у пользователя и его реальные потери. Подстраиваем это всё в динамике. На графике я показывал, что у пользователя устаканивается качество через 2-3 минуты, и он может играть с лучшим качеством. Если сеть идеальная, мы просто отключаем избыточность, если плохая, то добавляем её. При увеличенных потерях, мы уменьшаем битрейт. Бывает, нельзя совсем ничего сделать. Тут мы говорим пользователю: «извини, надо что-то с Сетью делать».
Устройства для Cloud Gaming
![](https://habrastorage.org/getpro/habr/upload_files/4bf/7b0/bcc/4bf7b0bcc671a8ababd8040b2ecbdd52.jpeg)
Мы запускаем облачные игры на разных устройствах, приходится под каждое новое устройство подстраиваться. Где-то есть кодеки, а где-то их нет, где-то производительность большая, а есть приставки и даже часы, подключающиеся к ТВ экрану и тоже можно играть. Это может быть мобильный телефон, где Android разных версий, процессоры разных вендоров, которые могли не всё реализовать, Смарт-ТВ и так далее.
Проблема, что мы поддерживаем кучу устройств, накладываем очень много ограничений. В динамике мы многое подстраиваем, чтобы дать пользователю максимально эффективное качество потока.
Итоги
![](https://habrastorage.org/getpro/habr/upload_files/d65/74e/fab/d6574efab8dfaa394ba1f4204ba17e9d.jpeg)
Cloud gaming очень требователен к задержкам. Оптимизацию надо делать на всех точках пути трафика к пользователю. Наверное, все это делают в своих сервисах и фокусируются на этом. Мы фокус делаем на задержках, не забывая о качестве. Основная проблема в cloud gaming – нестабильная сеть. В 95% случаях, это домашняя сеть, где некачественный, дешевый роутер, где кто-то скачивает торренты и параллельно смотрит видео или включена микроволновка. И всё это создаёт проблемы, и пользователь тут не виноват. Это мы, как-то должны подстроиться под эти обстоятельства и помочь пользователю получать качественный сервис. Поддержка устройств на любых девайсах – слабых, мощных, проводных, беспроводных – требует от нас много ручной работы, исследований и большой сбор данных.
Хоть в VKPlay Cloud всегда будет куда развиваться, но уже сейчас сотни тысяч пользователей ежемесячно пользуются сервисом и мы даём возможность получить им максимально качественный сервис.