# теория · шаг 3 из 8
I, P, B и GOP: показ, декодирование и задержка
Коротко
Порядок кадров на экране не обязан совпадать с порядком их декодирования. В классической рассматриваемой схеме I-кадр независим, P использует прежнюю опору, B может использовать опоры по обе стороны во времени показа. Сначала нужно восстановить все зависимости. GOP объединяет кадры в группы; ограничение зависимостей группы помогает доступу и восстановлению после ошибок. Более длинные зависимости могут экономить биты, но увеличивают требования к памяти, задержке и началу произвольного просмотра.
Если построишь допустимый порядок I0,B1,B2,P3 и объяснишь буфер, задержку и нагрузку канала, переходи к «Теперь сам».
Как думаешь, можно ли показать B1 до получения P3
Время показа идёт как I0,B1,B2,P3. Для B1 и B2 нужны изображения I0 и P3.
Кадр P3 показывается позже, но декодировать его нужно раньше этих B.
Иначе половина предсказания ещё неизвестна.
Это не нарушение причинности передачи. Кодировщик буферизует вход, вычисляет нужные опоры и отправляет данные в подходящем порядке. Получатель тоже хранит уже декодированные, но ещё не показанные картинки. За возможность использовать будущую по показу опору платят задержкой и памятью.
На что это похоже
Страницы учебника читаются по порядку, но иллюстрацию на первой странице могут приготовить после таблицы, которая будет напечатана на четвёртой. Порядок приготовления зависит от исходных данных, порядок публикации - от требуемого рассказа. Нужен буфер для готовых, но ещё не опубликованных частей.
В видео роли похожи: порядок показа задаёт хронологию, граф зависимостей - порядок вычислений. Из нескольких допустимых вычислительных порядков можно выбирать по памяти и ресурсам. Один топологический порядок не обязан быть единственным и не обязательно оптимален по каждому критерию.
Механизм: тип кадра и граф опор
I означает независимо кодируемое изображение в рассматриваемой классической модели. P допускает межкадровое предсказание из опор прошлого. B допускает предсказание с двух направлений времени показа; конкретный блок может использовать одну опору, две или независимый режим. В простой схеме MPEG-1/2 эти B не используются как опоры для других кадров. Это ограничение нельзя переносить на все более поздние стандарты и режимы.
GOP, группа изображений, задаёт структуру таких зависимостей вокруг опорных кадров. Для нашего закрытого примера все необходимые опоры находятся внутри группы. В иных схемах зависимость может пересекать границу группы: одного обнаружения буквы I недостаточно, чтобы обещать чистый вход во все последующие кадры без чтения других данных.
Граф направлен от опоры к зависимому кадру. Допустимый порядок декодирования -
топологический: все родители уже готовы. Для показа I0,B1,B2,P3
с опорами B на I0,P3 можно декодировать I0,P3,B1,B2.
B1 и B2 независимы друг от друга, поэтому их можно поменять местами,
если иначе согласованы сроки показа и хранение. В программе выбираем готовый кадр
с наименьшим номером показа, чтобы результат был воспроизводимым.
Правило
Различай время показа, порядок декодирования и время прибытия данных. Сначала восстанавливаются опоры, затем зависимые картинки; для показа используется исходная временная последовательность. Произвольный доступ требует доступной точки входа и её зависимостей, а не только смещения на байт с желаемым кадром.
В системной упаковке временные метки показа и декодирования могут различаться: часто их называют PTS и DTS. Конкретная шкала и сигнализация определяются форматом. Нельзя измерять всю задержку фильма только разностью этих меток: добавляются захват, поиск кодировщика, передача, очереди и вывод устройства.
Разбор: граф из семи кадров
deps = {0: [], 1: [0, 3], 2: [0, 3], 3: [0],
4: [3, 6], 5: [3, 6], 6: [3]}
decoded, order = set(), []
while len(decoded) < len(deps):
ready = [v for v, parents in deps.items()
if v not in decoded and all(p in decoded for p in parents)]
if not ready:
raise ValueError("цикл зависимостей")
v = min(ready)
decoded.add(v)
order.append(v)
print("показ:", sorted(deps))
print("декодирование:", order)
rate = 30
print("опора 3 относительно B1, мс:", round((3 - 1) * 1000 / rate))
arrival_kbit, service_kbit = 100, 2000 / 25
queue = 0
for frame in range(25):
queue = max(0, queue + arrival_kbit - service_kbit)
print("очередь через секунду, кбит:", int(queue))
# Данные нужны для будущих предсказаний и для отложенного показа.
for count in range(len(order)):
known = set(order[:count + 1])
pending = set(deps) - known
refs = {p for v in pending for p in deps[v] if p in known}
print("после", order[count], "ещё нужные опоры:", sorted(refs))
показ: [0, 1, 2, 3, 4, 5, 6]
декодирование: [0, 3, 1, 2, 6, 4, 5]
опора 3 относительно B1, мс: 67
очередь через секунду, кбит: 500
после 0 ещё нужные опоры: [0]
после 3 ещё нужные опоры: [0, 3]
после 1 ещё нужные опоры: [0, 3]
после 2 ещё нужные опоры: [3]
после 6 ещё нужные опоры: [3, 6]
после 4 ещё нужные опоры: [3, 6]
после 5 ещё нужные опоры: []
Показ идёт по номерам 0…6, декодирование получилось 0,3,1,2,6,4,5.
После 3 уже известны обе опоры первых B. После 6 готовы обе опоры следующих.
Строки «ещё нужные опоры» считают только необходимость будущих предсказаний.
Кадр 6 после последней строки может всё ещё ждать своего показа:
исчезновение из этого списка не означает автоматическое освобождение памяти.
Обычно картинку нельзя освободить, пока она ещё нужна хотя бы для одной роли: будущая опора или отложенный показ. Точная реализация буфера зависит от стандарта и расписания. Топологическая готовность позволяет часть работы распараллелить, но не разрешает показывать поздний кадр вместо ещё не готового раннего без изменения видео.
Разбор: кадры помещаются по времени, но не по битрейту
При 30 кадрах/с опора P3 имеет время показа на 2/30 секунды позже B1,
то есть примерно на 67 мс. Это пример зависимости от будущего, не полная задержка системы.
Если кадры в среднем занимают 100 кбит при 25 кадрах/с,
появляется 2500 кбит/с данных. Канал обслуживает только 2000 кбит/с:
без изменения потока очередь растёт на 500 кбит каждую секунду.
Даже если средняя скорость помещается в канал, отдельный большой I-кадр может временно заполнить буфер. Поэтому кодировщик управляет бюджетом и распределением битов, а транспорт хранит временные метки и границы. Повысить квантование в сложном участке - один из способов уложиться в бюджет, но заметность этого решения нужно оценивать отдельно.
Для обратного показа зависимую цепь обычно сначала декодируют в допустимом прямом порядке, а затем читают восстановленные картинки в обратном. Например, цепь I0→P1→P2→P3 нельзя точно восстановить, начав с P3 без опор. Нужен и проход от точки входа, и буфер результата; независимые кадры упрощают доступ.
Частота кадров измеряет число показываемых картинок за секунду, битрейт - скорость кодированных данных. При выборе режима задай ограничения задержки, памяти, доступа и качества, затем измерь типовые и трудные входы. Для живой камеры будущая опора, захватываемая на 67 мс позже текущего кадра, не укладывается в общий бюджет задержки 20 мс после его захвата. Меньший файл не даёт ещё не снятую картинку. У заранее записанного материала нет этого ограничения захвата: там отдельно считают чтение, передачу и подготовку опоры.
Что ломается без этого
Для поиска нужного кадра переходят к его байтам, игнорируя отсутствующие опоры. Или после потери одного опорного кадра продолжают считать все зависимые кадры неповреждёнными. Ошибка опоры может распространяться дальше по графу. Независимое обновление ограничивает распространение, но требует дополнительных битов.
При аудиовизуальном показе важна общая временная шкала. Если декодер не успел к сроку картинки, произвольное замедление видеоряда разойдётся со звуком. Система может пропустить допустимые для пропуска кадры или поменять режим, но пропуск необходимой опоры нельзя считать равным пропуску независимого B в нашей простой модели.
Зачем это в работе
Монтажу нужны удобные точки доступа, видеосвязи малая задержка, а заранее подготовленному фильму может быть важнее экономия битов. Одинаковый набор преобразований способен дать разные ответы на эти требования за счёт структуры опор, режима группы и политики буфера. Нужно измерять скорость и задержку отдельно: быстрый декодер не отменяет ожидания данных будущей опоры.
Теперь сам
Показ I0,B1,P2, B1 использует I0,P2, P2 использует I0.
Назови допустимый порядок декодирования. При 25 кадрах/с насколько
позже B1 во времени показа находится P2? Означает ли это всю задержку приложения?
Ответ. Порядок I0,P2,B1. Разница времени показа 1/25 секунды,
40 мс. Полная задержка включает остальные этапы и очереди,
поэтому из одной разности номеров кадров она не определяется.
Главное
Кадры образуют граф вычислительных зависимостей поверх временного порядка показа. Экономия на предсказании оплачивается ожиданием опор, буфером и ограничениями доступа; эти расходы нужно учитывать при выборе структуры потока.
Комментарии
Пока нет комментариев. Будь первым!
Оставить комментарий