mirror of
https://github.com/leandromoreira/digital_video_introduction.git
synced 2026-01-08 22:18:10 -05:00
Russian translation
Table of contents
Basic terminology - colors
Ways to encode an image
Basic terminology first draft complete
Started redundancy removal
Fixed contents links/titles so far
Redundancy removal progress
Chroma subsampling progress
Chroma subsampling
Correct chroma subsampling contents link
Frame types
Temporal redundancy (inter prediction) progress
Redundancy removal first draft 🎉
Codec start
History progress
generic codec progress
Generic codec progress
Codec progress
Finalized text, first draft :)
Spellcheck pass 1
Spellcheck pass halfway
Finalized spellcheck
Fixed titles, added russian link
This commit is contained in:
862
README-ru.md
Normal file
862
README-ru.md
Normal file
@@ -0,0 +1,862 @@
|
||||
[🇨🇳](/README-cn.md "Simplified Chinese")
|
||||
[🇯🇵](/README-ja.md "Japanese")
|
||||
[🇮🇹](/README-it.md "Italian")
|
||||
[🇰🇷](/README-ko.md "Korean")
|
||||
[🇷🇺](/README-ru.md "Russian")
|
||||
|
||||
[](https://img.shields.io/badge/license-BSD--3--Clause-blue.svg)
|
||||
|
||||
# Интро
|
||||
Нежное интро к видео технологии, предназначено для программистов и инженеров, хотя информация тут изучаема **любому** заинтересованному. Эта идея родилась во время [мини-семинара для новичков в области видео технологий](https://docs.google.com/presentation/d/17Z31kEkl_NGJ0M66reqr9_uTG6tI5EDDVXpdPKVuIrs/edit#slide=id.p).
|
||||
|
||||
Цель представить концепции цифрового видео **простыми терминами, схемами и практикой**. Не стесняйтесь добавлять свои исправления и предложения для улучшения документа.
|
||||
|
||||
**Практические разделы** требуют чтобы у вас был установлен **docker** и клонирован этот репо.
|
||||
|
||||
```bash
|
||||
git clone https://github.com/leandromoreira/digital_video_introduction.git
|
||||
cd digital_video_introduction
|
||||
./setup.sh
|
||||
```
|
||||
|
||||
> **ПРЕДУПРЕЖДЕНИЕ**: когда вы видите команду `./s/ffmpeg` или `./s/mediainfo`, это означает, что мы запускаем **контейнерную версию** этой программы, которая уже включает в себя все необходимые требования.
|
||||
|
||||
Все **практические упражнения выполняются из клонированной папки**. Для **примеров jupyter** вы должны запустить сервер `./s/start_jupyter.sh`, и посетить URL в браузере.
|
||||
|
||||
# Changelog
|
||||
|
||||
* added DRM system
|
||||
* released version 1.0.0
|
||||
* added simplified Chinese translation
|
||||
|
||||
# Индекс
|
||||
|
||||
- [Интро](#интро)
|
||||
- [Индекс](#индекс)
|
||||
- [Основные термины](#основные-термины)
|
||||
* [Другие способы кодирования цветного изображения](#другие-способы-кодирование-изображений)
|
||||
* [Практика: экспериментируем цветами и изображениями](#практика-експерементируем-цветами-и-изображениями)
|
||||
* [DVD это DAR 4:3](#dvd-это-dar-43)
|
||||
* [Практика: Рассмотр свойсвтва видео](#практика-рассмотр-свойсвтва-видео)
|
||||
- [Удаление избыточности](#удаление-избыточности)
|
||||
* [Цвета, яркость и глаза](#цвета-яркость-и-глаза)
|
||||
+ [Модель цвета](#модель-цвета)
|
||||
+ [Преобразование между YCbCr и RGB](#преобразование-между-ycbcr-и-rgb)
|
||||
+ [Цветовая дискретизация](#цветовая-дискретизация)
|
||||
+ [Практика: Проверка гистограммы YCbCr](#практика-проверка-гистограммы-ycbcr)
|
||||
* [Типы кадров](#типы-кадров)
|
||||
+ [I кадр (интра, ключевой кадр)](#i-кадр-интра-ключевой-кадр)
|
||||
+ [P кадр (предсказанный)](#p-кадр-предсказанный)
|
||||
- [Практика: Видео с единым I-кадром](#практика-видео-с-единым-i-кадром)
|
||||
+ [B кадр (двунаправленного предсказания)](#b-кадр-двунаправленного-предсказания)
|
||||
- [Практика: Сравнивание видео с Б-кадрами](#практика-сравнивание-видео-с-б-кадрами)
|
||||
+ [Конспект](#конспект)
|
||||
* [Временная избыточность (меж предсказание)](#временная-избыточность-меж-предсказание)
|
||||
- [Практика: Обзор векторов движения](#практика-обзор-векторов-движения)
|
||||
* [Пространственная избыточность (внутреннее предсказание)](#пространственная-избыточность-внутреннее-предсказание)
|
||||
- [Практика: проверка внутренних предсказаний](#практика-проверка-внутренних-предсказаний)
|
||||
- [Как действует видео кодек?](#как-действует-видео-кодек)
|
||||
* [Что? Почему? Как?](#что-почему-как)
|
||||
* [История](#история)
|
||||
+ [Рождение AV1](#рождение-av1)
|
||||
* [Общий кодек](#общий-кодек)
|
||||
* [1-й шаг - разделение изображения](#1-й-шаг---разделение-изображения)
|
||||
+ [Практика: Проверка разделов](#практика-проверка-разделов)
|
||||
* [2-й шаг - предсказания](#2-й-шаг---предсказания)
|
||||
* [3-й шаг - трансформация](#3-й-шаг---трансформация)
|
||||
+ [Практика: выбрасывание разных коэффициентов](#практика-выбрасывание-разных-коэффициентов)
|
||||
* [4-й шаг - квантование](#4-й-шаг---квантование)
|
||||
+ [Практика: квантование](#практика-квантование)
|
||||
* [5-й шаг - энтропийное кодирование](#5-й-шаг---энтропийное-кодирование)
|
||||
+ [VLC-кодирование](#vlc-кодирование)
|
||||
+ [Арифметическое кодирование](#арифметическое-кодирование)
|
||||
+ [Практика: CABAC vs CAVLC](#практика-cabac-vs-cavlc)
|
||||
* [6-й шаг - формат битового потока](#6-й-шаг---формат-битового-потока)
|
||||
+ [H.264 битовый поток](#h264-битовый-поток)
|
||||
+ [Практика: Проверка битовога потока H.264](#практика-проверка-битовога-потока-h264)
|
||||
* [Обзор](#oбзор)
|
||||
* [Как H.265 обеспечивает лучшую степень сжатия чем H.264?](#как-h265-обеспечивает-лучшую-степень-сжатия-чем-h264)
|
||||
- [Онлайн трансляция](#онлайн-трансляция)
|
||||
* [Общая архитектура](#общая-архитектура)
|
||||
* [Прогрессивная загрузка и адаптивная передача](#прогрессивная-загрузка-и-адаптивная-передача)
|
||||
* [Защита контента](#защита-контента)
|
||||
- [Как использовать jupyter](#как-использовать-jupyter)
|
||||
- [Конференции](#конференции)
|
||||
- [Ссылки](#ссылки)
|
||||
|
||||
# Основные термины
|
||||
|
||||
**Изображение** можно представлять в форме **2Д матрицы**. Если мы думаем о **цветах**, то можно экстраполировать это представление в **3Д матрицу**, где **добавочные измерения** показывают **цветную информацию**.
|
||||
|
||||
Если мы представляем эти цвета [первичными цветами (красный, зеленый, синий)](https://en.wikipedia.org/wiki/Primary_color), мы определяем три уровня, один для **красного**, один для **зеленого**, и последний для **синего**.
|
||||
|
||||

|
||||
|
||||
Мы назовем каждую точку на этой матрицы **пикселем** (элемент изображения). Один пиксел отражает **интенсивность** (обычно числовое значение) данного цвета. Например, **красный пиксель** имеет 0 зеленого, 0 синего, и максимально красного. **Розовый пиксель** состоит из комбинации трех цветов - **Красный=255, Зеленый=192, Синиий=203**.
|
||||
|
||||
> #### Другие способы кодирование изображений
|
||||
> Существует множество моделий которые описовают как расппределяються цвета на изображение. Например, в место трех битов, как для модели RGB (Красный, Зеленый, Синий) мы можем изпользовать только один бит. Ето использует меньше памяати но так же дает меньшые количество цветов.
|
||||
|
||||
>
|
||||
> 
|
||||
|
||||
На изображение снизу, первый снимок отражает все цветовые каналы. Остальные снимки только отражают красный, зеленый и синий канал.
|
||||
|
||||

|
||||
|
||||
Мы видим что **красный канал** будет самым ярким (белые части второго лица), и способствует главному оттенку в картинке. **Синего** мало, и видно в четвертой картинке, что он **сконцентрирован в глазах и одежды** Марио. Так же видно, что все каналы мало способствуют усам, самым темным частям картинки.
|
||||
|
||||
У каждого канала определённое количество битов, так называема **битовая глубина**. Если у нас **8 битов** (между 0 и 255и) для каждого цвета, то битовая глубина у изображений RGB (8 бит * 3 цвета) в размере **24 бита**, то есть 2^24 разных цвета.
|
||||
|
||||
> **Хорошо знать** [как озпбражения переводятся с настоящего мира в биты](http://www.cambridgeincolour.com/tutorials/camera-sensors.htm).
|
||||
|
||||
Другая характеристика изображений это **разрешение**, то есть количество пикселей в одном измерение. Обычно оно показывается в формате ширина х высота, как на **4х4** картинке снизу.
|
||||
|
||||

|
||||
|
||||
> #### Практика: експерементируем цветами и изображениями
|
||||
> Можно [играца с цветами в картинках](/image_as_3d_array.ipynb) используя [jupyter](#how-to-use-jupyter) (python, numpy, matplotlib и т.д).
|
||||
>
|
||||
> Так же можшно понять [как фильтры, (обострение, размытость...) работают](/filters_are_easy.ipynb).
|
||||
|
||||
Еще качество с которым мы встречаемся пре работе с видео и изображениями это **соотношение сторон (AR)** которое просто описывает пропорции ширины сравнительно с высотой изображения или пикселя.
|
||||
|
||||
Когда луди говорят что изображение или фильм **16х9**, они называют цифры **DAR (Соотношение сторон дисплея)**. Так же и бывает **PAR (Соотношение сторон пикселя)**
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
> #### DVD это DAR 4:3
|
||||
>
|
||||
> Хоть у DVD разрешение 704х480, формат все равно соблюдает DAR 4:3 потому что у него PAR 10:11 (703x10/480x11)
|
||||
|
||||
И конечно, "видео" мы определяем как **последствие *n*-кадров** во **времени**, что можно обозначить как дополнительное измерение поверху размера и цвета, где *п* это количество кадров в секунду (FPS).
|
||||
|
||||

|
||||
|
||||
**битрейт** это сколько нужно битов что бы показать секунду видео.
|
||||
|
||||
> битрейт = ширина * высота * битовая глубина * кадры в секунду
|
||||
|
||||
Например, видео которое 30 FPS, 24 бита на пиксел, с разрешением 480х240 использует **82,944,000 битов в секунду** или 82 мегабита/с (30*480х240х24) без компрессии/снижения качества.
|
||||
|
||||
Когда **бит рейт** постоянный то его называют постоянным битрейтом (**CBR**), когда он меняется со временем тогда это переменный битрейт (**VBR**).
|
||||
|
||||
> Этот график показывает ограниченный VBR, который не тратит слишком много битов на черные кадры.
|
||||
>
|
||||
> 
|
||||
|
||||
Раньше, инженеры придумали технику, что бы увеличить воспринятый FPS в два раза при этом **не увеличения битрейт**. Эта техника называется **чересстрочное видео**, где пол изображения посылается в одном "кадре" и другая половина в следующем "кадре".
|
||||
|
||||
Сегодня экраны обычно представляют видео техникой **прогрессивного скана**. Это способ показывания, хранения и перевода изображений в котором все линии каждого кадра нарисованы одна за другой.
|
||||
|
||||

|
||||
|
||||
Теперь у нас есть представление того как xраница **изображение** в цифровом формате, как его **цвета** расположены, сколько **битов в секунду** мы используем что бы показывать видео, если это постоянный битрейт (CBR) или переменный битрейт (VBR), и как это связано с **разрешением** при данной **чистоте кадра**. Так же мы более знакомы с терминами наподобие **чересстрочное видео**, PAR, и т.д.
|
||||
|
||||
> #### Практика: Рассмотр свойсвтва видео
|
||||
> Вам возможно [увидеть оговоринные свойства с помощью ffmpeg или mediainfo.](https://github.com/leandromoreira/introduction_video_technology/blob/master/encoding_pratical_examples.md#inspect-stream)
|
||||
|
||||
# Удаление избыточности
|
||||
|
||||
Быстро становиться очевидно что работать с видео без компрессии практически не возможно; **один час видео** разрешение 720p, с частотой кадра 30fps занимает **278GB памяти<sup>*</sup>**. Алгоритмы компрессии без потерь, наподобие DEFLATE (используется в PKZIP, Gzip, PNG) **не сжимают видео достаточно** нам надо искать другие способы сжатья видео.
|
||||
|
||||
> <sup>*</sup> Эту цифру мы получаем умнажая 1280 х 720 х 24 х 30 х 3600 (ширина, высота, витовая глубина, чистота кадра и время в секундах).
|
||||
|
||||
Для этого мы можем использовать **характеристики нашего зрения**. Мы разбираем яркость лучше, чем цвета. Так же более заметные **повторы частей изображения во времени**.
|
||||
|
||||
## Цвета, яркость и глаза
|
||||
|
||||
Наши глаза более чувствительны к [яркости чем к цветам](http://vanseodesign.com/web-design/color-luminance/), проверти для себя на этом изображение:
|
||||
|
||||

|
||||
|
||||
Если вам не видно, что цвета **квадрата А и Б одинаковые** у картинки с лева, то у вас все в порядке, наш мозг настроен **уделять больше внимания на яркость/темноту чем на цвет**. С право вы видите что цвета и в правду одинаковы.
|
||||
|
||||
> **Упрощенное обьяснение функций глаз**
|
||||
> Глаз [сложный орган](http://www.biologymad.com/nervoussystem/eyenotes.htm), составлин из многих частей, хотя нас интересует шишочные и палочные клетки. Глаз состоит из порядка [120 милион палочных клеток и 6 милион шишочныч клеток](https://en.wikipedia.org/wiki/Photoreceptor_cell).
|
||||
>
|
||||
> **Упращая дальше**, давайте посмотрим как цвет и яркость действуют на глаза. **[Палочные клетки](https://en.wikipedia.org/wiki/Rod_cell) по большенству отвецтвенны за восприятие яркости**. **[Шишичные клетки](https://en.wikipedia.org/wiki/Cone_cell) отвецтвенны за восприятие цвета**. Есты три типа шишки, каждая со своей окраской: [S-шишки (Синий), M-шишки (Зеленый) и L-cones (Красный)](https://upload.wikimedia.org/wikipedia/commons/1/1e/Cones_SMJ2_E.svg).
|
||||
>
|
||||
> Потому что у нас больше палочных клеток (яркость) чем шишочных (цвет), мы делаем вывод что мы обробатываем больше яркостной информации.
|
||||
>
|
||||
> 
|
||||
>
|
||||
> **Функции контрастной чувствительности**
|
||||
>
|
||||
> Есть много теорий описывая функции человеческое зрение. Одна из них называется "Функции контрастной чувствительности". Они описывают сколько изминения в цвете может произойти перед тем как наблюдающий его замечает. Функции измеряют не только чуствительность к черно белому, нo так же и яркость при цветах. Експерименты раз за разом показывают что мы более чуствительны к яркости чем к цветам.
|
||||
|
||||
Зная что мы чувствительны к яркости, мы можем попытаться использовать этот факт.
|
||||
|
||||
### Модель цвета
|
||||
|
||||
В начале мы изучали как [распределять цвет на изображениях](#основные-термины) используя **модель RGB**. Существуют другие модели - например, **YCbCr**<sup>*</sup> делит luma/лума (яркость) от chrominance/хроминанц (цветность).
|
||||
|
||||
> <sup>*</sup> есть другие модели которые так же разделяют между яркостью и цветом.
|
||||
|
||||
В этой модели **Y** канал яркости. Так же есть два канала цвета, **Cb** (синяя chroma/хрома) и **Cr** (красная chroma/хрома). Формат [YCbCr](https://en.wikipedia.org/wiki/YCbCr) возможно получить от RGB, и так же можно получить RGB от YCbCr. С помощью YCbCr мы можем составлять изображения в полном цвете:
|
||||
|
||||

|
||||
|
||||
### Преобразование между YCbCr и RGB
|
||||
|
||||
Некоторые из вас может спрашивать, как можно показывать **все цвета без зеленого**?
|
||||
|
||||
Что бы понять ответ, давайте посмотрим как мы переводим цветовую модель RGB на YCbCr. Мы будем использовать коэффициенты из стандарта **[BT.601](https://en.wikipedia.org/wiki/Rec._601)**, который был создан **[группой ITU-R<sup>*</sup>](https://en.wikipedia.org/wiki/ITU-R)**. Первый шаг в этом процессе это **высчитать яркость (luma)** и заменить цифры RGB, используя константы рекомендованные группой ITU.
|
||||
|
||||
```
|
||||
Y = 0.299R + 0.587G + 0.114B
|
||||
```
|
||||
|
||||
После яркости, мы можем **получить цвета** (chroma синий и красный):
|
||||
|
||||
```
|
||||
Cb = 0.564(B - Y)
|
||||
Cr = 0.713(R - Y)
|
||||
```
|
||||
|
||||
Можно **перевести этот результат обратно**, и даже **получить зеленый используя YCbCr**
|
||||
|
||||
```
|
||||
R = Y + 1.402Cr
|
||||
B = Y + 1.772Cb
|
||||
G = Y - 0.344Cb - 0.714Cr
|
||||
```
|
||||
|
||||
> <sup>*</sup> Цыфровым видео правят группы и стандарты. Группы определяют стандарты, на пример [что такое 4К? Какую чистоту кадра использоватъ? Решение? Цветную модель?](https://en.wikipedia.org/wiki/Rec._2020).
|
||||
|
||||
Обычно, **дисплеи** работают только в режиме модели **RGB**, расположенные каким то образом. Некоторые из них показаны тут:
|
||||
|
||||

|
||||
|
||||
### Цветовая дискретизация
|
||||
|
||||
Когда изображение представлено компонентами яркости и цвета, мы можем воспользоваться чувствительностью глаза к яркости, что бы уменьшить количество информации. **Цветовая дискретизация** техника кодированья изображений с **разрешением для цвета меньше чем для яркости**.
|
||||
|
||||

|
||||
|
||||
Так как же уменьшается разрешение цвета?! Существуют схемы которые описывают, как получить цвет от разных разрешений для одного изображение (`конечный цвет = Y + Cb + Cr`).
|
||||
|
||||
Эти схемы называются системами дискретизации, обычно показаны соотношением трех чисел - `a:x:y` которое определяет разрешение цвета по отношению к `a * 2` блоку пикселей яркости.
|
||||
|
||||
* `a` горизонтальная ширина (обычно 4)
|
||||
* `x` количество образцов цвета в первом ряду
|
||||
* `y` количество изменений цвета между первым и вторым рядом
|
||||
|
||||
> В этой схеме есть изклучение, 4:1:0, где выберается только один цвет для каждего `4 x 4` блока разрешения яркости.
|
||||
|
||||
В современных кодеках обычно используются форматы: **4:4:4** *(Без дискретизации)*, **4:2:2, 4:1:1, 4:2:0, 4:1:0 и 3:1:1**.
|
||||
|
||||
> Вы можете участовать в [разговорах о цветовой подборке тут](https://github.com/leandromoreira/digital_video_introduction/issues?q=YCbCr).
|
||||
|
||||
> **Подборка YCbCr 4:2:0**
|
||||
>
|
||||
> Тут видно как сливается цветовая информация с яркостной в режшиме YCbCr 4:2:0. Заметите, что мы только используем 12 битов на пиксель.
|
||||
>
|
||||
> 
|
||||
|
||||
Тут показано изображение кодированное главными типами дискретизации. Первый ряд финальный YCbCr; на втором, видно разрешение цветных каналов. Качество изображения нормальное, при этом памяти используется на много меньше.
|
||||
|
||||

|
||||
|
||||
Ранее мы вычислили что нам надо [278GB памяти что бы сохранить час 720p/30fps видео](#удаление-избыточности). Используя режим **YCbCr 4:2:0** мы можем **убрать половину размера до 139GB**<sup>*</sup>, хотя это все равно далеко от идеала.
|
||||
|
||||
> <sup>*</sup> это число можно получить умнажая ширину, высоту, биты на пиксел, и чистоту кадра. Раньше мы пользовались 24 битами, теперь нам только надо 12.
|
||||
|
||||
<br/>
|
||||
|
||||
> ### Практика: Проверка гистограммы YCbCr
|
||||
> Возможно проверить [гистограмму YCbCr с помошью ffmpeg.](/encoding_pratical_examples.md#generates-yuv-histogram). У этого изображение выше концентрация синего, что видно на [гистограмме](https://en.wikipedia.org/wiki/Histogram).
|
||||
>
|
||||
> 
|
||||
|
||||
### Цвет, лума, яркость, гамма
|
||||
|
||||
Отличное видео для тех кто хотят приобрести глубже понятие лумы, яркости, гаммы, и цвета.
|
||||
[](http://www.youtube.com/watch?v=Ymt47wXUDEU)
|
||||
|
||||
## Типы кадров
|
||||
|
||||
Теперь мы можем сосредоточиться на удаление **избыточности во времени**. С начала, нам надо установить основные термины - скажем, что мы работаем с фильмом 30FPS, и первые 4 кадра выглядят так:
|
||||
|
||||
  
|
||||

|
||||
|
||||
Мы видим много повторений между кадрами, например у синего фона который не меняется на кадрах 0 - 3. Что бы начать решать эту проблему, мы можем абстрактно классифицировать их как 3 разных типа кадра.
|
||||
|
||||
### I кадр (интра, ключевой кадр)
|
||||
|
||||
I кадр, (ссылка, ключевой кадр, внутренний) **независимый кадр**. Что бы его нарисовать не нужно дополнительной информации, и он похож на фотографию. Первый кадр обычно I кадр, но мы видем как I кадры регулярно вставляют среди других типов кадра.
|
||||
|
||||

|
||||
|
||||
### P кадр (предсказанный)
|
||||
|
||||
P-кадр пользуется фактом, что почти всегда можно нарисовать изображение **с помощью пре ведущего кадра**. Например, во втором кадре, шар поменял расположение - все остальное осталось одинаковым. Мы можем построить **первый кадр используя только разницу между двумя кадрами**.
|
||||
|
||||
 <- 
|
||||
|
||||
> #### Практика: Видео с единым I-кадром
|
||||
|
||||
> Если P-кадры используют меньше памяти, то почему бы нам не закодировать целое [видео одним I-кадром и оставить все последующие кадры как P-кадры?](/encoding_pratical_examples.md#1-i-frame-and-the-rest-p-frames)
|
||||
>
|
||||
> После кодировки этого видео, начните смотреть его и попробуйте перескочить к пожемму времини. Станит заметно что эта функция длица **долгое време**. **P-кадрам нужны ссылочные кадры** (например I-кадр) что бы их нарисовать.
|
||||
>
|
||||
> Так же можно закодировать видео с одним I-кадром а потом попробовать [закодировать его вставляя I-кадр каждие две секунды](/encoding_pratical_examples.md#1-i-frames-per-second-vs-05-i-frames-per-second), сравнивая размера в конце.
|
||||
|
||||
### B кадр (двунаправленного предсказания)
|
||||
|
||||
Так же можно ссы лаца на будущие кадры, как и пре ведущие, метод который экономит еще больше памяти - как раз это и делают B-кадры.
|
||||
|
||||
 <-  -> 
|
||||
|
||||
> #### Практика: Сравнивание видео с Б-кадрами
|
||||
> Вы можете составить две версии видео, одну с B-кадрами и другую [вообще без B-кадров](/encoding_pratical_examples.md#no-b-frames-at-all). Обратите внимание на размер файла и качество видео.
|
||||
|
||||
### Конспект
|
||||
|
||||
Эти кадры используются для **более эффективной компрессии**. Мы уведем как это происходит в следующем отделе, на не теперешний момент нам достаточно помнить что **I-кадр дорогой, P-кадр дешевле и B-кадр самый дешевый**.
|
||||
|
||||

|
||||
|
||||
## Временная избыточность (меж предсказание)
|
||||
|
||||
Давайте посмотрим как мы и можем понизить количество **повторов во времени**. Такого типа избыточности можно достичь техниками **меж предсказания**.
|
||||
|
||||
По попробуем **потратить меньше битов** кодируя кадры 0 и 1.
|
||||
|
||||

|
||||
|
||||
Один подход это просто **вычитать разницу между кадром 1 и 0**, и мы получим все что надо что бы **закодировать остаток**.
|
||||
|
||||

|
||||
|
||||
Не плохо, но есть еще **лучше метод**, который использует еще меньше битов. С начала, давай разрежем `кадр 0` на серию разделов, после чего мы можем попытаться соответствовать разделы с `кадра 0` до `кадра 1`, действие наподобие **оценки двежения**.
|
||||
|
||||
> ### Википедиа - компенсация движению блока
|
||||
> **Компенсаци движению блока** делит текущий кадр на отдлеьные разделы, после чего векторы компенсации движения **показывают от куда эти блоки появились** (распостраненная ошыбка идея того что, разделив преведущий кадр на отдельные разделы, векторы показывают куда эти разделы двигаются). Исходные разделы обычно перекрывают друг друга в исходном кадре. Некотороя компрессия видео текущий кадр из кусков разных ранее переданных кадров.
|
||||
|
||||

|
||||
|
||||
Мы можем предсказать что шарик сдвинулся от `x=0, y=25` до `x=6, y=26`, и что **х** и **y** числа это **векторы движения**. Что бы сэкономить на битах дальше, мы можем **закодировать только разницу в векторах движения** между последним положением блока и предсказанным, так что финальный вектор движения получается `x=6 (6-0), y=1 (26-25)`.
|
||||
|
||||
> При настоящем использование этой техники, шар был бы разделен на `n` разделов. Процесс при этом остается одинаковым.
|
||||
|
||||
> Обьекты на кадре **могут двигатся 3Dобразно**, шар может стать меньше когда он уходит в фон. Впольне возможно (и нормально) что мы не сможем найти идеальнoe совпадение для раздела которму мы ищим совпадение. Вот изображение сравняя наше предскозание с настоящим кадром.
|
||||
|
||||

|
||||
|
||||
Все равно, видно что когда мы используем **предсказание движения** информации которую нам **надо кодировать меньше** чем если мы бы использовали технику делта кадров.
|
||||
|
||||

|
||||
|
||||
> ### Как выглядет настоящая компенсация движения
|
||||
> Обычно эта техника используется для всех разделов, и обычно один шар как в преведущих кадрах будет разделен на несколько разделов.
|
||||
> 
|
||||
> Ссылка: https://web.stanford.edu/class/ee398a/handouts/lectures/EE398a_MotionEstimation_2012.pdf
|
||||
|
||||
Вы можете [экспериментировать этими техниками в jupyter](/frame_difference_vs_motion_estimation_plus_residual.ipynb).
|
||||
|
||||
> #### Практика: Обзор векторов движения
|
||||
> Мы можем [создать видео с внешним предсказанием (векторами движения) с помощью ffmpeg.](/encoding_pratical_examples.md#generate-debug-video)
|
||||
>
|
||||
>  с помощью ffmpeg")
|
||||
>
|
||||
> Так же можно использовать [Intel Video Pro Analyzer](https://software.intel.com/en-us/intel-video-pro-analyzer) (програма платная, но есть бесплатная, пробная версия, которая ограничивает пользу на первые 10 кадров).
|
||||
>
|
||||
> 
|
||||
|
||||
## Пространственная избыточность (внутреннее предсказание)
|
||||
|
||||
Если мы проанализируем **каждый кадр** в видео, мы увидим что есть **много областей, которые имеют отношение друг к другу**.
|
||||
|
||||

|
||||
|
||||
Давайте пройдемся по примеру. Эта сцена в основном состоит из синего и белого.
|
||||
|
||||

|
||||
|
||||
Это `I-кадр`, и мы **не можем использовать предыдущие кадры** для прогнозирования - при этом, мы все еще можем сжать его. Мы закодируем информацию в красном разделе. Если мы **посмотрим на его соседей**, мы можем понять что существует **тренд цветов вокруг него**.
|
||||
|
||||

|
||||
|
||||
Мы **предскажем**, что в кадре будут **распространятся цвета по вертикали**, то есть цвета пикселей о которых мы не знаем в этой области **будут содержать цвета соседей**.
|
||||
|
||||

|
||||
|
||||
Наше **предсказание может быть неверным**, по этому нам надо применить этот метод (**внутреннее предсказание**), а затем **вычесть реальные числа цветов**, что дает нам остаточный раздел и дает нам более сжимаемою матрицу по сравнению с оригиналом.
|
||||
|
||||

|
||||
|
||||
> #### Практика: проверка внутренних предсказаний
|
||||
> Вы можете [зделать видео с макро разделами и их предскозаниями в ffmpeg.](/encoding_pratical_examples.md#generate-debug-video) Пожалуйста проверите документацию ffmpeg что бы понять [значение каждего блока цвета](https://trac.ffmpeg.org/wiki/Debug/MacroblocksAndMotionVectors#AnalyzingMacroblockTypes).
|
||||
>
|
||||
>  с ffmpeg")
|
||||
>
|
||||
> Так же можно использовать [Intel Video Pro Analyzer](https://software.intel.com/en-us/intel-video-pro-analyzer) (програма платная, но есть бесплатная, пробная версия, которая ограничивает пользу на первые 10 кадров).
|
||||
>
|
||||
> 
|
||||
|
||||
# Как действует видео кодек?
|
||||
|
||||
## Что? Почему? Как?
|
||||
|
||||
**Что такое видео кодек?** Это система, программная или физическая, которая сжимает или разжимает цифровое видео. **За чем?** Обществу, и в свою очередь рынку нужно видео высокого качества при ограниченном объёме передачи или хранения информации. Помните когда мы [высчитали нужный объем передачи](#основные-термины) для видео у которого 30 кадров в секунду, с битовой глубинной 24 бита и разрешение 480х240? Это было **82.944mbps** без компрессии. Только так можно передавать HD/FullHD/4K видео к телевизору или по интернету. **Как?** Мы проведём поверхностный обзор главный техники здесь.
|
||||
|
||||
> **Кодек или контейнер?**
|
||||
>
|
||||
> Очень часто путается цыфровой видео кодек и [цыфровой видео контейнер](https://en.wikipedia.org/wiki/Digital_container_format). **Контейнер** можно представлять как оберток который содержит метаданные о видео (и возможно о звуке). **Сжатое видео** можно представить как его дoставочное содержaние.
|
||||
>
|
||||
> Обычно, расширение файла указывает тип контейнера. Например, файл `video.mp4` скорее всяго контейнер **[MPEG-4 Part 14](https://en.wikipedia.org/wiki/MPEG-4_Part_14)**, а файл с названием `video.mkv` скорее всяго контейнер **[matroska](https://en.wikipedia.org/wiki/Matroska)**. Что бы быть уверенным, можно использовать [ffmpeg или mediainfo](/encoding_pratical_examples.md#inspect-stream).
|
||||
|
||||
## История
|
||||
|
||||
Прежде чем мы углубимся во механизмы универсального кодека, давайте посмотрим в прошлое, чтобы немного лучше понять некоторые старые видеокодеки.
|
||||
|
||||
Видео кодек [H.261](https://en.wikipedia.org/wiki/H.261) официально родился в 1990, и был устроен работать при **обмене информации скоростью 64 kbit/s**. Уже используют методы на подобие цветовой десктирезации, макро блоки е т.д. В 1995 году, выпустили кодек **H.263** - этот стандарт прожил до 2001ого, время на протяжение которого над ним постоянно работали и улучшали.
|
||||
|
||||
|
||||
В 2003 году была завершена первая версия **H.264 / AVC**. В том же году компания под названием **TrueMotion** выпустила свой видеокодек **без лицензионных отчислений** для сжатия видео с потерями под названием **VP3**. В 2008 году **Google купил** эту компанию, выпустив **VP8** в том же году. В декабре 2012 года Google выпустил **VP9**, и он **поддерживается примерно на ¾ из всех браузеров** (включая мобильные устройства).
|
||||
|
||||
|
||||
**[AV1](https://en.wikipedia.org/wiki/AOMedia_Video_1)** - это новый **бесплатный кодек**, с открытым кодом, который разрабатывается [Альянсом открытых медиа (AOMedia)](http://aomedia.org/), в которую входят **компании: Google, Mozilla, Microsoft, Amazon, Netflix, AMD, ARM, NVidia, Intel и Cisco** и другие. **Первая версия** 0.1.0 эталонного кодека **была опубликована 7 апреля 2016 года**.
|
||||
|
||||

|
||||
> #### Рождение AV1
|
||||
>
|
||||
> В начале 2015 года Google работали над [VP10](https://en.wikipedia.org/wiki/VP9#Successor:_from_VP10_to_AV1), Xiph (Mozilla) работали над [Daala](https://xiph.org/daala/) и Cisco открыли свой бесплатный видеокодек под названием [Thor](https://tools.ietf.org/html/draft-fuldseth-netvc-thor-03).
|
||||
>
|
||||
> Затем MPEG LA объявили годовые ограничения для HEVC (H.265) и сtoймость использованья в 8 раз выше, чем H.264. Вскоре они снова изменили правила:
|
||||
> * **нет годового лимита**,
|
||||
> * **плата за контент**, (0,5% от выручки) и
|
||||
> * **Плата за единицу продукции примерно в 10 раз выше, чем h264**.
|
||||
>
|
||||
> [Альянс для открытых медиа](http://aomedia.org/about-us/) был создан производителями оборудованья (Intel, AMD, ARM, Nvidia, Cisco), контент доставчиками (Google, Netflix, Amazon) создателями враузеров (Google, Mozilla) и другими.
|
||||
>
|
||||
> У компаний была общая цель - бесплатный видео кодек, результат чаго является AV1, у которого [патентная лицензия на много проще](http://aomedia.org/license/patent/). **Тимоти Б. Терриберри** сделал потрясающую презентацию, которая является источником этого раздела, о [концепции AV1, модели лицензии и ее текущем состоянии](https://www.youtube.com/watch?v=lzPaldsmJbk ).
|
||||
>
|
||||
> Вы будете удивлены, узнав что возможно **проанализировать кодек AV1 через браузер**: http://aomanalyzer.org/
|
||||
>
|
||||
>
|
||||
>
|
||||
> PS: Если вы хотите узнать больше об истории кодеков, взгляните на [патенты для сжатия видео](https://www.vcodex.com/video-compression-patents/).
|
||||
|
||||
## Общий кодек
|
||||
|
||||
Сейчас мы попытаемся описать **основные механизмы универсального видеокодека**, концепций которые полезны и используются в современных кодеках, на примере VP9, AV1 и HEVC. Это будут упрощенные схемы, хотя иногда мы будем использовать реальные примеры (в основном по отношению к H.264) для демонстрации техники.
|
||||
|
||||
## 1-й шаг - разделение изображения
|
||||
|
||||
Первым шагом действия кодека является **разделение кадра** на несколько **разделов, подразделов** и т.д.
|
||||
|
||||

|
||||
|
||||
**Зачем?** Есть много причин - разделяя картинку, мы можем точнее обрабатывать прогнозы, используя маленькие разделы для маленьких движущихся частей видео и большие разделы для статического фона.
|
||||
|
||||
Обычно кодеки **организуют эти разделы** в срезы (или фрагменты), макро (или блоки схемы кодирования) и множество подразделов. Максимальный размер этих разделов варьируется, HEVC устанавливает 64x64, в то время как AVC использует 16x16, но подразделы могут достигать размеров 4x4.
|
||||
|
||||
Вы помните **разные типы кадров**? Возможно **применить эти идеи и к блокам**, поэтому у нас могут быть I-Slice, B-Slice, I-Macroblock и т.д.
|
||||
|
||||
> ### Практика: проверка разделов
|
||||
> Мы можем использовать [Intel Video Pro Analyzer](https://software.intel.com/en-us/intel-video-pro-analyzer) (программа платная, хотя есть бестплатная версия где можно проанализировать первых десять кадров). Вот [разделы VP9](/encoding_pratical_examples.md#transcoding).
|
||||
>
|
||||
> 
|
||||
|
||||
## 2-й шаг - предсказания
|
||||
|
||||
Как только у нас есть разделы, мы можем использовать их для предсказаний. Для [меж кадрового предсказания](#временная-избыточность-меж-предскозание) нам нужно **использовать векторы движения и остаток**, а для [внутрикадрового предсказания](#пространственная-избыточность-внутреннее-предсказание) мы будем **использовать предсказанное направление и остаток**.
|
||||
|
||||
## 3-й шаг - трансформация
|
||||
|
||||
После того как мы получим остаточный блок (`предсказанный раздел - реальный раздел`), мы можем **трансформировать его** образом которым даст нам знать, какие **пиксели мы можем выбросить**, сохраняя при этом **общее качество**. Есть некоторые трансформации которые тут нам помогут.
|
||||
|
||||
Хотя есть [другие трансформации](https://en.wikipedia.org/wiki/List_of_Fourier-related_transforms#Discrete_transforms), мы более подробно рассмотрим дискретную косинусную трансформацию, ДСТ (DCT). Основные функции [**DCT**](https://en.wikipedia.org/wiki/Discrete_cosine_transform):
|
||||
|
||||
* **Переводит блоки пикселей** в **блоки одинакового размера частотных коэффициентов**.
|
||||
* **Сжимает** энергию, облегчая устранение пространственной избыточности.
|
||||
* Является **обратимым процессом**, например, вы можете вернуться к пикселям.
|
||||
|
||||
> 2 февраля 2017 г. Синтра Р. Дж. И Байер Ф. М. опубликовали свою статью [ДСТ-подобное преобразование для сжатия изображений требует только 14 дополнений](https://arxiv.org/abs/1702.00817).
|
||||
|
||||
Не беспокойтесь, если вы не поняли преимуществ каждого пункта, мы попытаемся провести несколько экспериментов, чтобы понять процесс подробнее.
|
||||
|
||||
Давайте возьмем следующий **блок пикселей** (8x8):
|
||||
|
||||

|
||||
|
||||
Который рендерится как изображение (8x8):
|
||||
|
||||

|
||||
|
||||
Когда мы **применяем ДСТ** к этому блоку пикселей, мы получаем **блок коэффициентов** (8x8):
|
||||
|
||||

|
||||
|
||||
И если мы отрендерим этот блок коэффициентов, мы получим это изображение:
|
||||
|
||||

|
||||
|
||||
Как видно, это не похоже на исходное изображение, и похоже, что **первый коэффициент** очень отличается от всех остальных. Этот первый коэффициент известен как коэффициент DC, представляя себе **все выборки** во входном массиве, что-то **наподобие среднего числа**.
|
||||
|
||||
Этот блок коэффициентов обладает интересным свойством, заключающимся в том, что он отделяет высокочастотные компоненты от низкочастотных.
|
||||
|
||||

|
||||
|
||||
На изображении **большая часть энергии** будет сосредоточена на [**более низких частотах**](https://web.archive.org/web/20150129171151/https://www.iem.thm.de/telekom-labour/zinke/mk/mpeg2beg/whatisit.htm), поэтому если мы трансформируем изображение в его частотные компоненты и **отбросим более высокие частотные коэффициенты**, мы можем **уменьшить объем данных** необходимо описать изображение, не жертвуя качеством сижком сильно.
|
||||
|
||||
> частота означает, насколько быстро меняется сигнал
|
||||
|
||||
Давайте попробуем применить знания, которые мы получили в тесте, трансформируя исходное изображение в его частоту (блок коэффициентов), используя ДСТ, а затем отбрасывая часть наименее важных коэффициентов.
|
||||
|
||||
Сначала мы конвертируем его в **частотную область**.
|
||||
|
||||

|
||||
|
||||
Далее мы отбрасываем часть (67%) коэффициентов, в основном нижнюю правую часть.
|
||||
|
||||

|
||||
|
||||
Наконец, мы восстанавливаем изображение из этого отброшенного блока коэффициентов (помните, оно должно быть обратимым) и сравниваем его с оригиналом.
|
||||
|
||||

|
||||
|
||||
Как видно, оно похоже на исходное изображение, но в нем есть много отличий от оригинала. Мы **выбросили 67,1875%** и все же смогли получить хотя бы что-то похожее на оригинал. Мы могли бы более разумно отбросить коэффициенты, чтобы получить лучшее качество изображения, но это следующая тема.
|
||||
|
||||
> **Каждый коэффициент формируется с использованием всех пикселей**
|
||||
>
|
||||
> Важно отметить, что каждый коэффициент не отображается напрямую на один пиксель, а представляет собой взвешенную сумму всех пикселей. Этот удивительный график показывает, как рассчитывается первый и второй коэффициент с использованием весов, уникальных для каждого индекса.
|
||||
>
|
||||
>
|
||||
>
|
||||
> Источник: https://web.archive.org/web/20150129171151/https://www.iem.thm.de/telekom-labor/zinke/mk/mpeg2beg/whatisit.htm
|
||||
>
|
||||
> Вы также можете попытаться [визуализировать ДСТ, взглянув на это изображение](/dct_better_explained.ipynb). Например, вот создается [символ "A"](https://en.wikipedia.org/wiki/Discrete_cosine_transform#Example_of_IDCT) с помощю каждого веса коэффициента.
|
||||
>
|
||||
>! [] (https://upload.wikimedia.org/wikipedia/commons/5/5e/Idct-animation.gif)
|
||||
|
||||
|
||||
|
||||
|
||||
<br/>
|
||||
|
||||
> ### Практика: выбрасывание разных коэффициентов
|
||||
> Вы можете поигратся с [ДСТ трансформациями тут](/uniform_quantization_experience.ipynb).
|
||||
|
||||
## 4-й шаг - квантование
|
||||
|
||||
Когда мы выбрасываем коэффициенты, на последнем шаге (трансформация) мы делали некоторую форму квантования. На этом этапе мы решили потерять информацию или, проще говоря, мы **квантовали коэффициенты для достижения сжатия**.
|
||||
|
||||
Как мы можем квантовать блок коэффициентов? Одним простым методом было бы равномерное квантование, где мы берем блок, **делим его на одно значение** (10) и округляем это значение.
|
||||
|
||||

|
||||
|
||||
Как мы можем **обратить** (переквантовать) этот блок коэффициентов? Мы можем **умножить одним и тем же значением** (10), которым мы разделили.
|
||||
|
||||

|
||||
|
||||
Этот **подход не лучший**, потому что он не учитывает важность каждого коэффициента. Мы могли бы использовать **матрицу квантователей** вместо одного значения, эта матрица может использовать свойство ДСТ, квантовая больше нижнего правого и меньше верхнего левого, [JPEG использует аналогичный подход](https://www.hdm-stuttgart.de/~maucher/Python/MMCodecs/html/jpegUpToQuant.html). Вы можете проверить [исходный код, чтобы увидеть эту матрицу](https://github.com/google/guetzli/blob/master/guetzli/jpeg_data.h#L40).
|
||||
|
||||
> ### Практока: квантование
|
||||
> Вы можете поиграть с [квантованием] (/ dct_experiences.ipynb).
|
||||
|
||||
## 5-й шаг - энтропийное кодирование
|
||||
|
||||
После того как мы квантовали данные (блоки изображения / фрагменты / кадры), мы все еще можем сжимать их без потерь. Существует много способов (алгоритмов) сжатия данных. Мы собираемся кратко познакомиться с некоторыми из них, для более глубокого понимания вы можете прочитать удивительную книгу [Понимание сжатия: сжатие данных для современных разработчиков](https://www.amazon.com/Understanding-Compression-Data-Modern-Developers/dp/1491961538/).
|
||||
|
||||
### VLC кодирование:
|
||||
|
||||
Предположим, у нас есть поток символов: **a**, **e**, **r** и **t**, и их вероятность (от 0 до 1) представлена этой таблицей.
|
||||
|
||||
| | a | e | r | t |
|
||||
|-------------|-----|-----|------|-----|
|
||||
| вероятность | 0.3 | 0.3 | 0.2 | 0.2 |
|
||||
|
||||
Мы можем присвоить уникальные коды (предпочтительно маленькие) наиболее вероятным, а более крупные коды наименее вероятным.
|
||||
|
||||
| | a | e | r | t |
|
||||
|-------------|-----|-----|------|-----|
|
||||
| вероятность | 0.3 | 0.3 | 0.2 | 0.2 |
|
||||
| код | 0 | 10 | 110 | 1110 |
|
||||
|
||||
Давайте сожмем поток **eat**, предполагая что мы потратим 8 битов на каждый символ, то в общей сложности мы тратим **24 бита** без какого-либо сжатия. Но в случае замены каждого символа на его код мы можем сэкономить место.
|
||||
|
||||
Первый шаг заключается в кодировании символа **e**, который равен `10`, второй символ **а** добавляется что бы получить `[10][0]` и, наконец, третий символ **t**, который делает наш окончательный сжатый поток битов равным `[10][0][1110]` или `1001110`, которому нужно только **7 битов** (т.е 3.4 раза меньше места, чем оригинальный поток).
|
||||
|
||||
Обратите внимание, что каждый код должен иметь уникальный префикс код [Хаффман может помочь вам найти эти номера](https://en.wikipedia.org/wiki/Huffman_coding). Хотя у этого метода есть проблемы, есть [видеокодеки, которые все еще предлагают](https://en.wikipedia.org/wiki/Context-adaptive_variable-length_coding) его, и это алгоритм для многих приложений, который требует сжатия.
|
||||
|
||||
Кодер и декодер **должны знать** таблицу символов с ее кодом, поэтому вам также необходимо отправлять таблицу.
|
||||
|
||||
### Арифметическое кодирование:
|
||||
|
||||
Давай скажем что у нас есть поток символов: **a**, **e**, **r**, **s**, **t** и их вероятность показана на таблице:
|
||||
|
||||
| | a | e | r | s | t |
|
||||
|-------------|-----|-----|------|------|-----|
|
||||
| вероятность | 0.3 | 0.3 | 0.15 | 0.05 | 0.2 |
|
||||
|
||||
Зная об этой таблице, мы можем построить области со всеми возможными символами, отсортированные теми которые появляются чаще всего.
|
||||
|
||||

|
||||
|
||||
Теперь давайте закодируем поток **eat**, мы выбираем первый символ **a**, который находится в новом поддиапазоне **0.3 до 0.6** (но не включен), и мы берем этот поддиапазон и снова разделяем его, используя те же пропорции, которые использовались ранее, но в этом новом диапазоне.
|
||||
|
||||

|
||||
|
||||
Давайте продолжим кодировать наш поток **eat**, мы выберем второй символ **a**, который находится в новом поддиапазоне **0.3 до 0.39**, а затем мы берем наш последний символ **t**, повторяя процесс что бы получить последний поддиапазон **0.354 до 0.372**.
|
||||
|
||||

|
||||
|
||||
Нам просто нужно выбрать число в последнем поддиапазоне **0.354 до 0.372**, давайте выберем **0.36**, но мы можем выбрать любое число в этом поддиапазоне. С **только** этим номером мы сможем восстановить наш оригинальный поток **eat**. Если подумать об этом, мы как бы нарисовали линию в пределах диапазонов для кодирования нашего потока.
|
||||
|
||||

|
||||
|
||||
**Обратный процесс** (т.е. декодирование) одинаково прост, с нашим числом **0,36** и нашим исходным диапазоном мы можем запустить тот же процесс, но теперь используя это число, чтобы показать поток, закодированный за этим номером.
|
||||
|
||||
С первым диапазоном мы заметили что наше число соответствует срезу, поэтому это наш первый символ, теперь мы снова разбиваем этот поддиапазон, выполняя тот же процесс что и раньше, и мы можем заметить, что **0.36** соответствует символу **a** и после того, как мы повторим процесс, мы подходим к последнему символу **t** (формируя наш оригинальный кодированный поток *eat*).
|
||||
|
||||
Кодер и декодер **должны знать** таблицу вероятностей символов, поэтому вам необходимо отправлять таблицу.
|
||||
|
||||
Не плохо, правда? Люди чертовски умны, чтобы придумать такое решение, некоторые [видеокодеки используют](https://en.wikipedia.org/wiki/Context-adaptive_binary_arithmetic_coding) эту технику (или, по крайней мере, предлагают ее в качестве опции).
|
||||
|
||||
Идея состоит в том, чтобы сжать без потерь квантованный поток битов, наверняка в этой статье отсутствуют тонны деталей, причин, компромиссов и т. Д. Но [вы должны узнать больше](https://www.amazon.com/Understanding-Compression-Data-Modern-Developers/dp/1491961538/) в качестве разработчика. Более новые кодеки пытаются использовать различные [алгоритмы энтропийного кодирования, наподобие ANS.](https://en.wikipedia.org/wiki/Asymmetric_Numeral_Systems)
|
||||
|
||||
> ### Практика: CABAC vs CAVLC
|
||||
> Вы можете [создать два потока, один с CABAC and другой с CAVLC](https://github.com/leandromoreira/introduction_video_technology/blob/master/encoding_pratical_examples.md#cabac-vs-cavlc) and **сравнить время** занятое для их создание, а так же **конечный размер файла**.
|
||||
|
||||
## 6-й шаг - формат битового потока
|
||||
|
||||
После того, как мы выполнили все эти шаги, нам нужно **упаковать сжатые кадры и контекст к этим шагам**. Нам необходимо сообщить декодеру **о решениях, принятых кодером**, например битовая глубина, цветовое пространство, разрешение, информация о предсказаниях (векторы движения, направление внутреннего предсказания), профиль, уровень, частота кадров, тип кадра, номер кадра и многое другое.
|
||||
|
||||
Мы поверхностно изучим поток битов H.264. Наш первый шаг - [создать минимальный битовый поток H.264 <sup>*</sup>](/encoding_pratical_examples.md#generate-a-single-frame-h264-bitstream), что мы можем сделать это с помощью нашего собственного репозитория и [ffmpeg](http://ffmpeg.org/).
|
||||
|
||||
```
|
||||
./s/ffmpeg -i /files/i/minimal.png -pix_fmt yuv420p /files/v/minimal_yuv420.h264
|
||||
```
|
||||
|
||||
> <sup>*</sup> ffmpeg по умолчанию добавляет все параметры кодирования в виде **SEI NAL** - вскоре мы определим, что такое NAL.
|
||||
|
||||
Эта команда сгенерирует необработанный поток битов h264 с **одиночным кадром**, 64x64, с цветовым пространством yuv420 и с использованием следующего изображения в качестве кадра.
|
||||
|
||||
>
|
||||
|
||||
### H.264 битовый поток
|
||||
|
||||
Стандарт AVC (H.264) определяет, что информация будет отправляться в **макро кадрах** (в смысле сети), называемых **[NAL](https://en.wikipedia.org/wiki/Network_Abstraction_Layer)** (Сетевой Уровень Aбстракции). Основной целью NAL является обеспечение "дружественного к сети" представления видео, этот стандарт должен работать на телевизорах (на основе потоков), в Интернете (на основе пакетов) и т.д.
|
||||
|
||||

|
||||
|
||||
Существует **[маркер синхронизации](https://en.wikipedia.org/wiki/Frame_synchronization)** для определения границ единиц NAL. Каждый маркер синхронизации содержит значение `0x00 0x00 0x01`, за исключением самого первого, который является` 0x00 0x00 0x00 0x01`. Если мы запустим **hexdump** в сгенерированном потоке битов h264, мы сможем идентифицировать как минимум три NAL в начале файла.
|
||||
|
||||

|
||||
|
||||
Как мы уже говорили, декодеру надо знать не только данные изображения, но также детали видео, фрейма, цвета, используемые параметры и другие. **Первый байт** каждого NAL определяет его категорию и **тип**.
|
||||
|
||||
| NAL type id | Description |
|
||||
|--- |---|
|
||||
| 0 | Undefined |
|
||||
| 1 | Coded slice of a non-IDR picture |
|
||||
| 2 | Coded slice data partition A |
|
||||
| 3 | Coded slice data partition B |
|
||||
| 4 | Coded slice data partition C |
|
||||
| 5 | **IDR** Coded slice of an IDR picture |
|
||||
| 6 | **SEI** Supplemental enhancement information |
|
||||
| 7 | **SPS** Sequence parameter set |
|
||||
| 8 | **PPS** Picture parameter set |
|
||||
| 9 | Access unit delimiter |
|
||||
| 10 | End of sequence |
|
||||
| 11 | End of stream |
|
||||
| ... | ... |
|
||||
|
||||
Обычно первый NAL битового потока представляет собой **SPS**, этот тип NAL отвечает за информирование общих переменных кодирования, таких как **профиль**, **уровень**, **разрешение** и другие.
|
||||
|
||||
Если мы пропустим первый маркер синхронизации, мы можем декодировать **первый байт**, чтобы узнать, какой **тип NAL** является первым.
|
||||
|
||||
Например, первый байт после маркера синхронизации равен `01100111`, где первый бит (`0`) находится в поле **forbidden_zero_bit**, следующие 2 бита (`11`) сообщают нам поле **nal_ref_idc** который указывает если этот является NAL опорным полем или нет, а остальные 5 битов (`00111`) информируют нас о поле **nal_unit_type**, в данном случае это **SPS** (7) единица NAL.
|
||||
|
||||
Второй байт (`binary = 01100100, hex = 0x64, dec = 100`) SPS NAL - это поле **profile_idc**, которое показывает профиль, который использовал кодировщик, в этом случае мы использовали **[ограниченный высокий профиль](https://en.wikipedia.org/wiki/H.264/MPEG-4_AVC#Profiles)**, это высокий профиль без поддержки B (двунаправленных) срезов.
|
||||
|
||||

|
||||
|
||||
Когда мы читаем спецификацию потока битов H.264 для SPS NAL, мы найдем много значений, например, **parameter name**, **category** и **description**, давайте посмотрим на `pic_width_in_mbs_minus_1` и поля `pic_height_in_map_units_minus_1`.
|
||||
|
||||
| Parameter name | Category | Description |
|
||||
|--- |---|---|
|
||||
| pic_width_in_mbs_minus_1 | 0 | ue(v) |
|
||||
| pic_height_in_map_units_minus_1 | 0 | ue(v) |
|
||||
|
||||
> **ue(v)**: целое число без знака [Exp-Golomb-кодированный](https://pythonhosted.org/bitstring/exp-golomb.html)
|
||||
|
||||
Если мы немного посчитаем значения этих полей, мы получим **разрешение**. Мы можем представить `1920 x 1080`, используя `pic_width_in_mbs_minus_1` со значением `119 ((119 + 1) * macroblock_size = 120 * 16 = 1920)`, опять же экономя место, вместо того, чтобы кодировать `1920`, как мы это сделали с `119`.
|
||||
|
||||
Если мы продолжим проверять наше созданное видео в двоичном виде (например: `xxd -b -c 11 v/minimal_yuv420.h264`), мы можем перейти к последнему NAL, который является самим кадром.
|
||||
|
||||

|
||||
|
||||
Мы можем видеть его первые 6 байтовых значений: `01100101 10001000 10000100 00000000 00100001 11111111`. Поскольку мы уже знаем, что первый байт говорит нам о том, что это за тип NAL, в данном случае (`00101`) это **IDR Slice (5)**, и мы можем проверить его:
|
||||
|
||||

|
||||
|
||||
Используя информацию спецификации, мы можем декодировать, какой тип слайса (**slice_type**), номер кадра (**frame_num**) среди других важных полей.
|
||||
|
||||
Чтобы получить значения некоторых полей (`ue (v), me (v), se (v) или te (v)`)), нам нужно декодировать его, используя специальный декодер под названием [Exponential-Golomb](https://pythonhosted.org/bitstring/exp-golomb.html), этот метод **очень эффективен для кодирования значений переменных**, главным образом, когда существует много значений по умолчанию.
|
||||
|
||||
> Значения **slice_type** и **frame_num** этого видео равны 7 (I срез) и 0 (первый кадр).
|
||||
|
||||
Мы можем видеть **поток битов как протокол**, и если вы хотите или вам надо узнать больше об этом потоке битов, обратитесь к [спецификации МСЭ H.264](http://www.itu.int/rec/T-REC-H.264-201610-I) Вот макросхема, которая показывает, где находятся данные изображения (сжатые YUV).
|
||||
|
||||

|
||||
|
||||
Мы можем исследовать другие битовые потоки, такие как [битовый поток VP9](https://storage.googleapis.com/downloads.webmproject.org/docs/vp9/vp9-bitstream-specification-v0.6-20160331-draft.pdf), [H.265 (HEVC)](http://handle.itu.int/11.1002/1000/11885-en?locatt=format:pdf) или даже наш **новый лучший друг** [**AV1** поток битов](https://medium.com/@mbebenita/av1-bitstream-analyzer-d25f1c27072b#.d5a89oxz8
|
||||
), [они все похожи? Нет](http://www.gpac-licensing.com/2016/07/12/vp9-av1-bitstream-format/), но как только вы выучите один, вы легко сможете понять другие.
|
||||
|
||||
> ### Практика: Проверка битовога потока H.264
|
||||
> Мы можем [создать однокадровое видео](https://github.com/leandromoreira/introduction_video_technology/blob/master/encoding_pratical_examples.md#generate-a-single-frame-video) и использовать [mediainfo](https://en.wikipedia.org/wiki/MediaInfo) для проверки потока битов H.264. Вы даже можете увидеть [исходный код, который анализирует битовый поток h264 (AVC)](https://github.com/MediaArea/MediaInfoLib/blob/master/Source/MediaInfo/Video/File_Avc.cpp).
|
||||
>
|
||||
> 
|
||||
>
|
||||
> Мы также можем использовать [Intel Video Pro Analyzer](https://software.intel.com/en-us/intel-video-pro-analyzer), который платный, хотя существует бесплатная пробная версия, которая ограничивает вас только первые 10 кадров (которых для учебных целей должно быть достаточно).
|
||||
>
|
||||
> 
|
||||
|
||||
## Обзор
|
||||
|
||||
Мы заметим, что многие из **современных кодеков используют ту же модель, которую мы изучили**. Можно посмотреть на блок-схему видеокодека Thor и увидеть что она содержит все шаги, которые мы изучали. Идея состоит в том, что теперь вы в состоянии лучше понять инновации и документы в этой области.
|
||||
|
||||

|
||||
|
||||
Ранее мы рассчитывали, что нам потребуется [139 ГБ дискового пространства для хранения видеофайла одного часа в длинне при разрешении 720p и 30 к/с](#цветовая-субдискретизация). С помощю методов которые описаны здесь, такие как **меж и внутреннее предсказание, трансформации, квантование, энтропийное кодирование и другие**, то же видео воспринимаемого качества можно сжать до **только 367.82 МБ**.
|
||||
|
||||
> Мы решили использовать **0.031 бит на пиксель** на основе примера видео, представленного здесь.
|
||||
|
||||
## Как H.265 обеспечивает лучшую степень сжатия чем H.264?
|
||||
|
||||
Зная больше о том, как работают кодеки, легко понять как новые кодеки способны обеспечивать более высокое разрешение с меньшим количеством битов.
|
||||
|
||||
Мы сравним AVC и HEVC, помня что это почти всегда компромисс между большим количеством циклов ЦП (сложность) и степенью сжатия.
|
||||
|
||||
HEVC имеет больше количество **разделов** (и **подразделов**), которые так же и больше в размере чем AVC, больше **направлений внутреннего предсказания**, **улучшенное энтропийное кодирование** и более, все эти улучшения дали H.265 способность сжимать на 50% больше, чем H.264.
|
||||
|
||||

|
||||
|
||||
# Онлайн трансляция
|
||||
## Общая архитектура
|
||||
|
||||
! [общая архитектура](/i/general_architecture.png "общая архитектура")
|
||||
|
||||
[TODO]
|
||||
|
||||
## Прогрессивная загрузка и адаптивная передача
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
[TODO]
|
||||
|
||||
## Защита контента
|
||||
|
||||
Мы можем использовать **простую систему токенов** для защиты контента. Запрос видео без токена будет запрещен CDN-ом, в то время как пользователь с действительным токеном может воспроизводить контент. Он работает почти так же, как и большинство систем веб-аутентификации.
|
||||
|
||||

|
||||
|
||||
Использую эту систему токенов позволяет пользователю загружать видео и распространять его. Затем можно использовать систему **DRM (управление цифровыми правами)**, чтобы избежать этого.
|
||||
|
||||

|
||||
|
||||
В реальных производственных системах люди часто используют оба метода для обеспечения авторизации и аутентификации.
|
||||
|
||||
### DRM
|
||||
#### Основные системы
|
||||
|
||||
* FPS - [**FairPlay Streaming**](https://developer.apple.com/streaming/fps/)
|
||||
* PR - [**PlayReady**](https://www.microsoft.com/playready/)
|
||||
* WV - [**Widevine**](http://www.widevine.com/)
|
||||
|
||||
|
||||
#### Какой?
|
||||
|
||||
DRM зто система цифровых прав, это способ **обеспечить защиту авторских прав на цифровых материалов** - например, цифровое видео и аудио. Хотя он используется во многих местах [он не является общепринятым](https://en.wikipedia.org/wiki/Digital_rights_management#DRM-free_works).
|
||||
|
||||
#### Зачем?
|
||||
|
||||
Создатель контента (в основном, студии) хотят защитить свою интеллектуальную собственность от копирования, чтобы предотвратить несанкционированное распространение цифрового контента.
|
||||
|
||||
#### Как?
|
||||
|
||||
Мы собираемся описать абстрактную и общую форму DRM в очень упрощенном виде.
|
||||
|
||||
Учитывая **контент C1** (т.е. потоковое видео hls или dash), с **проигрывателем P1** (т.е. shaka-clappr, exo-player или ios) в **устройстве D1** (т.е. смартфоне , Телевизор, планшет или настольный компьютер / ноутбук) с использованием **DRM системы DRM1** (widevine, playready или FairPlay).
|
||||
|
||||
Контент C1 зашифрован с помощью **симметричного ключа K1** от системы DRM1, генерируя **зашифрованный контент C'1**.
|
||||
|
||||

|
||||
|
||||
Проигрыватель P1 устройства D1 имеет два ключа (асимметричные): **закрытый ключ PRK1** (этот ключ защищен <sup>1</sup> и известен только **D1**) и **открытый ключ PUK1**.
|
||||
|
||||
> ** <sup> 1 </ sup> защищен **: эта защита может быть ** с помощью аппаратного обеспечения **, например, этот ключ может храниться в специальном (только для чтения) чипе, который работает как [черный box] (https://en.wikipedia.org/wiki/Black_box), чтобы обеспечить расшифровку, или ** с помощью программного обеспечения ** (менее безопасно), система DRM предоставляет средства, чтобы узнать, какой тип защиты имеет данное устройство.
|
||||
|
||||
|
||||
Когда ** игрок P1 хочет воспроизвести ** контент ** C'1 **, он должен иметь дело с ** DRM-системой DRM1 **, предоставив свой открытый ключ ** PUK1 **. DRM-система DRM1 возвращает ** ключ K1 в зашифрованном виде ** с открытым ключом клиента ** PUK1 **. Теоретически, этот ответ - это то, что ** только D1 способен расшифровать **.
|
||||
|
||||
`K1P1D1 = enc (K1, PUK1)`
|
||||
|
||||
**P1** использует свою локальную систему DRM (это может быть [SOC](https://en.wikipedia.org/wiki/System_on_a_chip), специализированное аппаратное или программное обеспечение), эта система **может дешифровать** контент, и используя свой закрытый ключ PRK1, может расшифровать **симметричный ключ K1 от K1P1D1** и **воспроизвести C'1**. В лучшем случае ключи не выставляются через ОЗУ.
|
||||
|
||||
``,
|
||||
K1 = dec (K1P1D1, PRK1)
|
||||
|
||||
P1.play (dec (C'1, K1))
|
||||
``,
|
||||
|
||||

|
||||
|
||||
# Как использовать Jupyter
|
||||
|
||||
Убедитесь, что у вас установлен **docker** и просто запустите `./s/ start_jupyter.sh` и следуйте инструкциям на терминале.
|
||||
|
||||
# Конференции
|
||||
|
||||
* [DEMUXED](https://demuxed.com/) - вы можете [проверить последние 2 презентации.](Https://www.youtube.com/channel/UCIc_DkRxo9UgUSTvWVNCmpA).
|
||||
|
||||
# Ссылки
|
||||
|
||||
Здесь самый богатый контент, вся информация которую мы видели в этом тексте, была извлечена, основана или вдохновлена. Вы можете углубить свои знания с помощью этих удивительных ссылок, книг, видео и т. д.
|
||||
|
||||
Онлайн курсы и учебные пособия:
|
||||
|
||||
* https://www.coursera.org/learn/digital/
|
||||
* https://people.xiph.org/~tterribe/pubs/lca2012/auckland/intro_to_video1.pdf
|
||||
* https://xiph.org/video/vid1.shtml
|
||||
* https://xiph.org/video/vid2.shtml
|
||||
* http://slhck.info/ffmpeg-encoding-course
|
||||
* http://www.cambridgeincolour.com/tutorials/camera-sensors.htm
|
||||
* http://www.slideshare.net/vcodex/a-short-history-of-video-coding
|
||||
* http://www.slideshare.net/vcodex/introduction-to-video-compression-13394338
|
||||
* https://developer.android.com/guide/topics/media/media-formats.html
|
||||
* http://www.slideshare.net/MadhawaKasun/audio-compression-23398426
|
||||
* http://inst.eecs.berkeley.edu/~ee290t/sp04/lectures/02-Motion_Compensation_girod.pdf
|
||||
|
||||
Books:
|
||||
|
||||
* https://www.amazon.com/Understanding-Compression-Data-Modern-Developers/dp/1491961538/ref=sr_1_1?s=books&ie=UTF8&qid=1486395327&sr=1-1
|
||||
* https://www.amazon.com/H-264-Advanced-Video-Compression-Standard/dp/0470516925
|
||||
* https://www.amazon.com/Practical-Guide-Video-Audio-Compression/dp/0240806301/ref=sr_1_3?s=books&ie=UTF8&qid=1486396914&sr=1-3&keywords=A+PRACTICAL+GUIDE+TO+VIDEO+AUDIO
|
||||
* https://www.amazon.com/Video-Encoding-Numbers-Eliminate-Guesswork/dp/0998453005/ref=sr_1_1?s=books&ie=UTF8&qid=1486396940&sr=1-1&keywords=jan+ozer
|
||||
|
||||
Onboarding material:
|
||||
|
||||
* https://github.com/Eyevinn/streaming-onboarding
|
||||
* https://howvideo.works/
|
||||
* https://www.aws.training/Details/eLearning?id=17775
|
||||
* https://www.aws.training/Details/eLearning?id=17887
|
||||
* https://www.aws.training/Details/Video?id=24750
|
||||
|
||||
Bitstream Specifications:
|
||||
|
||||
* http://www.itu.int/rec/T-REC-H.264-201610-I
|
||||
* http://www.itu.int/ITU-T/recommendations/rec.aspx?rec=12904&lang=en
|
||||
* https://storage.googleapis.com/downloads.webmproject.org/docs/vp9/vp9-bitstream-specification-v0.6-20160331-draft.pdf
|
||||
* http://iphome.hhi.de/wiegand/assets/pdfs/2012_12_IEEE-HEVC-Overview.pdf
|
||||
* http://phenix.int-evry.fr/jct/doc_end_user/current_document.php?id=7243
|
||||
* http://gentlelogic.blogspot.com.br/2011/11/
|
||||
Reference in New Issue
Block a user