- Share this text:
Untitled - posted by guest on 23rd September 2020 10:26:06 PM
[🇨🇳](/README-cn.md "Simplified Chinese")
[🇯🇵](/README-ja.md "Japanese")
[🇮🇹](/README-it.md "Italian")
[🇰🇷](/README-ko.md "Korean")
[](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). Обратите внемание на размер файла и качество видео.
### Конспект
Эти кадры используются для **более ефективной компресии**. Мы увидем как это произхoдит в следующем отделе, на не теперешний момент нам достаточно помнить что **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).
## History
Прежде чем мы углубимся во механизмы универсального кодека, давайте посмотрим в прошлое, чтобы немного лучше понять некоторые старые видеокодеки.
Видео кодек [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/exploring-h264-part-2-h264-bitstream.html
* https://forum.doom9.org/showthread.php?t=167081
* https://forum.doom9.org/showthread.php?t=168947
Software:
* https://ffmpeg.org/
* https://ffmpeg.org/ffmpeg-all.html
* https://ffmpeg.org/ffprobe.html
* https://trac.ffmpeg.org/wiki/
* https://software.intel.com/en-us/intel-video-pro-analyzer
* https://medium.com/@mbebenita/av1-bitstream-analyzer-d25f1c27072b#.d5a89oxz8
Non-ITU Codecs:
* https://aomedia.googlesource.com/
* https://github.com/webmproject/libvpx/tree/master/vp9
* https://people.xiph.org/~xiphmont/demo/daala/demo1.shtml
* https://people.xiph.org/~jm/daala/revisiting/
* https://www.youtube.com/watch?v=lzPaldsmJbk
* https://fosdem.org/2017/schedule/event/om_av1/
* https://jmvalin.ca/papers/AV1_tools.pdf
Encoding Concepts:
* http://x265.org/hevc-h265/
* http://slhck.info/video/2017/03/01/rate-control.html
* http://slhck.info/video/2017/02/24/vbr-settings.html
* http://slhck.info/video/2017/02/24/crf-guide.html
* https://arxiv.org/pdf/1702.00817v1.pdf
* https://trac.ffmpeg.org/wiki/Debug/MacroblocksAndMotionVectors
* http://web.ece.ucdavis.edu/cerl/ReliableJPEG/Cung/jpeg.html
* http://www.adobe.com/devnet/adobe-media-server/articles/h264_encoding.html
* https://prezi.com/8m7thtvl4ywr/mp3-and-aac-explained/
* https://blogs.gnome.org/rbultje/2016/12/13/overview-of-the-vp9-video-codec/
* https://videoblerg.wordpress.com/2017/11/10/ffmpeg-and-how-to-use-it-wrong/
Video Sequences for Testing:
* http://bbb3d.renderfarming.net/download.html
* https://www.its.bldrdoc.gov/vqeg/video-datasets-and-organizations.aspx
Miscellaneous:
* https://github.com/Eyevinn/streaming-onboarding
* http://stackoverflow.com/a/24890903
* http://stackoverflow.com/questions/38094302/how-to-understand-header-of-h264
* http://techblog.netflix.com/2016/08/a-large-scale-comparison-of-x264-x265.html
* http://vanseodesign.com/web-design/color-luminance/
* http://www.biologymad.com/nervoussystem/eyenotes.htm
* http://www.compression.ru/video/codec_comparison/h264_2012/mpeg4_avc_h264_video_codecs_comparison.pdf
* http://www.csc.villanova.edu/~rschumey/csc4800/dct.html
* http://www.explainthatstuff.com/digitalcameras.html
* http://www.hkvstar.com
* http://www.hometheatersound.com/
* http://www.lighterra.com/papers/videoencodingh264/
* http://www.red.com/learn/red-101/video-chroma-subsampling
* http://www.slideshare.net/ManoharKuse/hevc-intra-coding
* http://www.slideshare.net/mwalendo/h264vs-hevc
* http://www.slideshare.net/rvarun7777/final-seminar-46117193
* http://www.springer.com/cda/content/document/cda_downloaddocument/9783642147029-c1.pdf
* http://www.streamingmedia.com/Articles/Editorial/Featured-Articles/A-Progress-Report-The-Alliance-for-Open-Media-and-the-AV1-Codec-110383.aspx
* http://www.streamingmediaglobal.com/Articles/ReadArticle.aspx?ArticleID=116505&PageNum=1
* http://yumichan.net/video-processing/video-compression/introduction-to-h264-nal-unit/
* https://cardinalpeak.com/blog/the-h-264-sequence-parameter-set/
* https://cardinalpeak.com/blog/worlds-smallest-h-264-encoder/
* https://codesequoia.wordpress.com/category/video/
* https://developer.apple.com/library/content/technotes/tn2224/_index.html
* https://en.wikibooks.org/wiki/MeGUI/x264_Settings
* https://en.wikipedia.org/wiki/Adaptive_bitrate_streaming
* https://en.wikipedia.org/wiki/AOMedia_Video_1
* https://en.wikipedia.org/wiki/Chroma_subsampling#/media/File:Colorcomp.jpg
* https://en.wikipedia.org/wiki/Cone_cell
* https://en.wikipedia.org/wiki/File:H.264_block_diagram_with_quality_score.jpg
* https://en.wikipedia.org/wiki/Inter_frame
* https://en.wikipedia.org/wiki/Intra-frame_coding
* https://en.wikipedia.org/wiki/Photoreceptor_cell
* https://en.wikipedia.org/wiki/Pixel_aspect_ratio
* https://en.wikipedia.org/wiki/Presentation_timestamp
* https://en.wikipedia.org/wiki/Rod_cell
* https://it.wikipedia.org/wiki/File:Pixel_geometry_01_Pengo.jpg
* https://leandromoreira.com.br/2016/10/09/how-to-measure-video-quality-perception/
* https://sites.google.com/site/linuxencoding/x264-ffmpeg-mapping
* https://softwaredevelopmentperestroika.wordpress.com/2014/02/11/image-processing-with-python-numpy-scipy-image-convolution/
* https://tools.ietf.org/html/draft-fuldseth-netvc-thor-03
* https://www.encoding.com/android/
* https://www.encoding.com/http-live-streaming-hls/
* https://web.archive.org/web/20150129171151/https://www.iem.thm.de/telekom-labor/zinke/mk/mpeg2beg/whatisit.htm
* https://www.lifewire.com/cmos-image-sensor-493271
* https://www.linkedin.com/pulse/brief-history-video-codecs-yoav-nativ
* https://www.linkedin.com/pulse/video-streaming-methodology-reema-majumdar
* https://www.vcodex.com/h264avc-intra-precition/
* https://www.youtube.com/watch?v=9vgtJJ2wwMA
* https://www.youtube.com/watch?v=LFXN9PiOGtY
* https://www.youtube.com/watch?v=Lto-ajuqW3w&list=PLzH6n4zXuckpKAj1_88VS-8Z6yn9zX_P6
* https://www.youtube.com/watch?v=LWxu4rkZBLw
* https://web.stanford.edu/class/ee398a/handouts/lectures/EE398a_MotionEstimation_2012.pdf