Компьютерные сети. 6-е изд. - Эндрю Таненбаум
Шрифт:
Интервал:
Закладка:
В интернете очень много сайтов с музыкой и видео, предоставляющих потоковый доступ к хранящимся на них медиафайлам. По сути, самый простой способ обработки таких медиафайлов — не передавать их в потоковом режиме. Намного проще рассматривать предварительно закодированный видео- или аудиофайл как очень большую веб-страницу и позволить браузеру его скачать. Эта последовательность из четырех шагов показана на илл. 7.33.
Илл. 7.33. Воспроизведение медиафайлов по интернету путем обычного скачивания
Браузер начинает действовать, когда пользователь кликает по названию фильма. На первом шаге отсылается HTTP-запрос фильма на веб-сервер, на который указывает ссылка. На втором шаге сервер получает фильм (который представляет собой обычный файл в формате MP4 или каком-нибудь другом) и отправляет его браузеру. Исходя из MIME-типа файла, браузер выбирает способ воспроизведения. На третьем шаге браузер сохраняет весь фильм на диске во временном файле и запускает медиаплеер, которому передается имя временного файла. Наконец, на четвертом шаге медиаплеер начинает читать файл и проигрывать фильм. Теоретически это мало чем отличается от доставки и отображения статической веб-страницы, разница лишь в том, что загруженный файл «отображается» с помощью медиаплеера, а не просто путем записи пикселей в монитор.
В целом это вполне корректный подход, который позволит нормально воспроизвести файл с фильмом. У вас не будет никаких проблем с передачей данных по сети в режиме реального времени, поскольку в данном случае требуется лишь скачать файл. Правда, до начала воспроизведения необходимо передать по сети всю видеозапись. Большинство клиентов не хочет ждать целый час, пока начнется воспроизведение выбранного ими «видео по запросу», поэтому нужно найти решение получше.
На помощь приходит медиаплеер для потоковой передачи. Это может быть либо компонент веб-браузера, либо внешняя программа, вызываемая браузером, когда требуется воспроизвести видео. Современные браузеры с поддержкой HTML5 имеют встроенный медиаплеер.
Медиаплеер решает пять основных задач:
1. Управление интерфейсом пользователя.
2. Обработка ошибок передачи.
3. Декомпрессия сжатых данных.
4. Устранение джиттера.
5. Дешифрование файла.
Большинство современных медиаплееров обладает привлекательным интерфейсом, иногда имитирующим внешний вид стереосистемы с блестящими кнопками, ручками, ползунками и дисплеями. Зачастую пользователь может менять внешний вид плеера, выбирая разные «лицевые панели», скины (skins). Медиаплеер должен всем этим управлять, обеспечивая взаимодействие с пользователем.
Следующие три задачи связаны друг с другом и зависят от используемых сетевых протоколов. Рассмотрим их по очереди, начиная с обработки ошибок передачи. Ее сложность зависит от того, какой транспортный протокол используется для доставки медиаданных. Это может быть протокол, основанный на TCP (такой, как HTTP) или на UDP, например протокол реального времени (Real Time Protocol, RTP). При использовании транспортного протокола на основе TCP медиаплееру не придется исправлять ошибки, ведь TCP и так обеспечивает высокую надежность за счет повторной передачи. Это упрощает (по крайней мере, для медиаплеера) обработку ошибок, но в то же время усложняет удаление джиттера на более позднем этапе, поскольку тайм-ауты и повторная передача могут приводить к нестабильным и переменным задержкам при воспроизведении фильма.
В качестве альтернативы для передачи данных можно использовать транспортный протокол на основе UDP, например RTP. Такие протоколы не производят повторную передачу данных. То есть потеря пакетов из-за перегрузки или ошибок передачи приведет к тому, что часть медиаданных не будет доставлена. Решать эту проблему приходится медиаплееру. Можно просто игнорировать ее, допуская наличие ошибок в видео и аудио. Если ошибки случаются нечасто, такой подход будет работать и ошибки будут практически не заметны. Другой подход состоит в том, чтобы использовать упреждающую коррекцию ошибок (forward error correction), в частности, путем кодирования видеофайла с некоторой долей избыточности (например, с использованием кода Хэмминга или кода Рида — Соломона). В таком случае у медиаплеера будет достаточно информации для того, чтобы исправлять ошибки самостоятельно, и ему не потребуется запрашивать повторную передачу данных или пропускать поврежденные участки фильмов.
Недостатком этого метода является то, что внесение избыточности в файл ведет к увеличению его размера. Еще один подход сводится к выборочному повтору передачи наиболее важных для воспроизведения контента частей видеопотока. Например, в случае сжатого видеоряда потеря пакета в I-кадре имеет самые серьезные последствия, поскольку ошибки декодирования, возникающие в результате такой потери, могут распространяться на целую группу изображений. С другой стороны, потери в производных кадрах (P- и B-кадрах) наносят гораздо меньший урон. Схожим образом, ценность повторной передачи также зависит от того, успеет ли заново отправленный контент поступить к моменту его воспроизведения. В результате некоторые повторные передачи намного важнее других, и одна из возможных стратегий сводится к тому, чтобы выборочно повторять передачу определенных пакетов (например, пакетов внутри I-кадра, которые придут к моменту воспроизведения). Над RTP и QUIC был надстроен ряд протоколов, обеспечивающих неравномерную защиту от потерь при потоковой передаче видео по UDP; см. работу Фимстера и др. (Feamster et al., 2000), а также Палмера и др. (Palmer et al., 2018).
Третья задача медиаплеера — декомпрессия сжатых данных; это достаточно просто, хотя и затратно с точки зрения вычислений. Сложным моментом является лишь декодирование медиаданных в том случае, когда сетевой протокол не исправляет ошибки передачи. Во многих схемах сжатия данные, полученные позже, невозможно декодировать, пока не будут декодированы предыдущие данные (поскольку более поздние данные кодируются относительно более ранних). Как вы помните, P-кадр строится на основе последнего I-кадра (и всех последующих I-кадров). Если I-кадр поврежден и его не удается декодировать, то все последующие P-кадры бесполезны. При этом медиаплеер вынужден ждать следующего I-кадра, просто пропуская несколько секунд видео.
Из-за этого кодировщик вынужден делать выбор. Если I-кадры идут вплотную, например, с интервалом в 1 с, то пауза в случае ошибки будет незначительной, но видеофайл будет крупнее, поскольку I-кадры намного больше, чем P- или B-кадры. Если I-кадры идут, скажем, с интервалом в 5 с, то видеофайл гораздо меньше, но мы получаем 5-секундную паузу при повреждении I-кадра и паузу меньшего размера при повреждении P-кадра. В силу этого, когда в качестве базового протокола применяется TCP, интервал между I-кадрами может быть намного больше, чем при RTP. Поэтому многие сайты потокового видео используют TCP, чтобы получать файлы меньшего размера с крупными интервалами между I-кадрами и меньшей полосой пропускания, необходимой для плавного воспроизведения.
Четвертой задачей является устранение джиттера, главной проблемы всех систем реального времени. Использование TCP серьезно ее усложняет, поскольку оно вносит