Кратко

  • RFC 9628 задаёт два способа описания межкадровой зависимости VP9: flexible mode передаёт до трёх смещений P_DIFF вместе с предсказанным изображением, non-flexible mode объявляет повторяющуюся Picture Group в данных SS.
  • Picture ID, номера слоёв, ссылки, B, E и RTP Marker описывают заявленную отправителем структуру. Они не доказывают получение всех фрагментов, сохранность опорных изображений, корректность скрытого состояния кодека или вывод на экран.
  • Полная квитанция связывает контекст SDP, эпоху режима и структуры, покрытие RTP, фактическое замыкание ссылок, проверку bitstream, результат decoder и playout.

После сбоя команда нашла аккуратную последовательность Picture ID. Каждую ссылку можно было вычислить. SFU удалил только разрешённые слои. В отчёте зависимость считалась замкнутой.

Не хватало одного узла — того, который действительно лежал в памяти декодера.

RFC 9628 делает важную часть VP9 наблюдаемой поверх RTP. Формат сообщает временные и пространственные слои, границы frames и структуру ссылок. Но отправитель описывает модель, а не удалённое состояние. Сеть, selective forwarder, decoder и приложение добавляют собственные события, которых в payload descriptor нет.

Flexible mode сообщает ссылки здесь и сейчас

При F=1 Picture ID обязателен. Если picture использует межкадровое предсказание, в descriptor присутствует от одного до трёх P_DIFF. Значение вычитается из текущего PID по модулю семи- или пятнадцатибитного пространства. Нулевое смещение запрещено.

Такая схема допускает меняющуюся временную иерархию: encoder не связан заранее опубликованным циклом. Получатель или middlebox видит заявленные ссылки конкретного picture прямо в его пакетах.

Однако ссылка не переносит сам опорный материал. Нужный picture мог потеряться, быть законно отброшен или уже исчезнуть из буфера. Внутри текущего frame тоже может отсутствовать RTP-фрагмент. Математически правильный P_DIFF указывает точный адрес, по которому у receiver ничего нет.

Поэтому необходимо сравнивать два графа: объявленный отправителем и доступный декодеру. Первый не является проекцией второго.

Non-flexible mode зависит от общей истории

При F=0 данные Scalability Structure могут описать повторяющуюся Picture Group. Для каждой позиции задаются TID, признак switching up и относительные ссылки. PID key picture соответствует первой позиции, следующие PID проходят группу по модулю N_G.

TL0PICIDX отдельно считает pictures базового временного слоя. На TID=0 он увеличивается, а в верхних слоях указывает зависимую базу. Восьмибитное поле оборачивается после 255.

Экономия заголовка требует общей памяти о режиме. Наблюдатель, подключившийся в середине, может не видеть действующий SS. Перезапущенный SFU может получать текущие packets, но утратить key-picture anchor. Даже с одной таблицей две стороны способны разойтись в фазе группы.

Стандарт ограничивает изменения: F меняется только на первом пакете key picture, а новая SS начинается на разрешённой границе прежней группы. Для расследования это должна быть явная эпоха: hash структуры, вводящий пакет, anchor PID, N_G и вычисленная позиция. Текущая таблица без её начала не позволяет воспроизвести смысл.

Picture ID повторяется и может законно иметь пробелы

PID бывает семи- или пятнадцатибитным, начинается со случайного числа, оборачивается и может менять ширину. При расширении значение дополняется нулями, при сужении усекается. Receiver не вправе считать ширину постоянной.

Все spatial frames одного picture имеют общий PID. Picture с show_frame=0, которое обновляет reference buffer, но не выводится, всё равно получает отдельный номер. Счётчик относится к кодированному picture, а не к увиденному кадру.

Middlebox может удалять pictures в рамках структуры, поэтому входной ряд PID не обязан быть сплошным. Пробел может быть политикой, а не потерей. Сплошной ряд, в свою очередь, не показывает потерю одного RTP packet внутри frame.

Надёжный ключ включает session, SSRC, timestamp, ширину и значение PID, эпоху режима, слой и место наблюдения. Без этих координат короткий номер после wrap совпадёт с другим событием.

Конец frame не подтверждает его середину

Первый пакет VP9 frame несёт B=1, последний — E=1. RTP Marker устанавливается на последнем пакете frame верхнего spatial layer, завершая всё picture. Если forwarder убирает верхние слои, он переносит Marker на последний packet оставленного целевого слоя.

Это границы сборки, а не доказательство покрытия. E может прийти после пропущенного sequence number. Marker может быть виден, когда нижний слой, обязательный при D=1, повреждён. Корректно переписанный Marker не восстанавливает утраченную временную reference.

Формат не даёт более мелкого доступа к части VP9 frame. Для утверждения о полноте нужны sequence coverage от B до E, общий timestamp, правильный порядок spatial layers и верный Marker после rewrite. Наличие последней страницы не доказывает, что книга собрана целиком.

Граф не показывает всё состояние VP9

Кроме reference frames, codec переносит между frames таблицы вероятностей для entropy и tree coding. error_resilient_mode сбрасывает это дополнительное состояние. В scalable stream encoder обязан учитывать, что законно удаляемый frame не может оставлять обязательную скрытую память для последующих frames.

Здесь заканчивается достаточность header-анализатора. P_DIFF могут замкнуться, фаза PG может совпасть, а payload всё ещё зависит от отсутствующей таблицы. Спецификация bitstream VP9 определяет внутренние правила; работающий decoder сообщает отдельный результат.

Проверка descriptor, проверка bitstream и декодирование — последовательные органы доказательства. Если первый объявляет успех за всех, источник ошибки исчезает.

Layer fields разрешают только узкие выводы

TID и SID называют временной и пространственный слои. D сообщает зависимость от непосредственно нижнего spatial frame в том же picture. U отмечает switching-up point: будущие верхние временные слои не будут ссылаться на некоторые старые верхние pictures. Z говорит, что более высокие spatial layers не зависят от текущего frame и подходящий receiver может его отбросить.

U=1 не доказывает доставку точки переключения. Z=1 не доказывает, что discard соответствует выбранному качеству. SID=2 не является абсолютным разрешением. D=0 исключает одну пространственную связь, но не временные ссылки.

SFU должен сохранять собственную квитанцию решения: целевой layer, правило, forward/drop, Marker rewrite и причину congestion. Иначе после события остаётся только поле, которое разрешало действие, но не само действие.

RPSI переносит свидетельство к decoder, но не к экрану

RPSI может содержать PID корректно декодированного golden или altref frame либо предпочитаемую reference после потери. Это сильнее, чем чтение sender descriptor: утверждение появляется на принимающей стороне после decode.

Но оно не означает, что все spatial frames picture доступны, приложение выбрало результат для playout или изображение показано вовремя. FIR просит полный refresh состояния, LRR — ограниченный layer refresh. Возможность пройти цепочку ссылок не превращает request или acknowledgment в визуальную квитанцию.

Статья о RFC 9627 рассматривает путь от команды к восстановлению. Здесь граница проходит от VP9 dependency contract через реальный reference buffer к decoder и отображению.

SDP задаёт словарь до первого PID

VP9 использует dynamic payload type и clock 90 kHz. profile-id симметричен в offer/answer; при отсутствии подразумевается Profile 0. max-fr и max-fs объявляют возможности receiver, но не измеряют последующий stream.

Для pre-encoded media или selective forwarding подходящий вариант может отсутствовать, и стандарт допускает отклонение. Принятый offer не доказывает, что каждый frame вписался в capability или был decoded.

Квитанция начинается с offer, answer, mapping, profile, capability, SSRC и renegotiation. Descriptor, разобранный по старой SDP-эпохе, может быть безупречен по форме и ошибочен по смыслу.

Источники