Напоминание: базовая модель работы FFMPEG

В этом разделе мы кратко вспомним внутреннюю структуру обработки медиаданных в FFMPEG — не с позиции перекодирования файлов, как это было в курсе «Компьютерная графика», а с акцентом на сетевые видеосистемы. Эта модель — фундамент для понимания, как FFMPEG работает с потоковым видео, где возникает задержка и почему обработка сетевых источников отличается от работы с локальными файлами.
Общая схема обработки медиапотока
В основе FFMPEG лежит конвейерная (пайплайновая) архитектура, в которой данные последовательно проходят несколько этапов обработки. Упрощённо её можно представить так:
input(s) → демультиплексор → декодеры → фильтры → кодеры → мультиплексор → output(s)
Рассмотрим каждый этап подробно, с акцентом на сетевое применение.
1. Вход (input)
На этом этапе FFMPEG получает исходный медиапоток. Важно понимать, что для FFMPEG не имеет принципиального значения, откуда приходят данные — с диска или из сети.
- Файловый ввод:
input.mp4,video.mkvи т.п. - Сетевой ввод:
rtsp://cam1/stream,rtmp://server/live/stream,srt://192.168.1.10:1234,udp://239.1.1.1:1234
💡 Ключевая мысль: с точки зрения формата и структуры данных — это одно и то же. FFMPEG видит поток байт, из которого нужно извлечь медиаданные. Различается только способ получения этих байт: через файловую систему или через сетевой сокет.
Например, команда:
ffmpeg -i rtsp://192.168.1.10:554/stream -c copy output.mp4
работает так же, как:
ffmpeg -i local_video.mp4 -c copy output.mp4
— с той лишь разницей, что в первом случае данные приходят по сети, а во втором — с диска.
2. Демультиплексор (Demuxer)
Демультиплексор отвечает за разделение потока на отдельные компоненты: видео, аудио, субтитры и т.д. Он анализирует контейнер (формат файла или потока) — например, MP4, MKV, FLV, MPEG-TS, RTSP/RTP.
- Для
rtsp://...демультиплексор распознаёт RTP-пакеты, извлекает NAL-юниты H.264 и временные метки. - Для
input.mp4он читает атомыmoov,mdatи извлекает треки.
⚠️ Важно: демультиплексору нужно достаточно данных, чтобы понять структуру потока. В случае с сетевым входом это может потребовать буферизации первых пакетов. Это уже источник начальной задержки.
3. Декодеры (Decoders)
На этом этапе сжатые данные (например, H.264, AAC) преобразуются в «сырой» формат, пригодный для обработки:
- Видео: из H.264 → в YUV (например,
yuv420p) - Аудио: из AAC → в PCM (например,
s16le)
Каждый поток (видео, аудио) проходит через свой декодер. Если в команде указано -c copy, этот этап пропускается — данные передаются без декодирования.
🔍 Пример:
При работе с IP-камерой, которая передаёт H.264 в контейнере RTSP/RTP, FFMPEG может либо:
- декодировать H.264 → YUV → (фильтры) → (перекодировать) → H.264,
- или пропустить декодирование, если используется
-c copy.
4. Фильтры (Filters)
Это этап обработки «сырого» медиа. FFMPEG поддерживает богатую систему фильтров (filtergraph), включая:
- Масштабирование (
scale=1280:720) - Наложение картинки (
overlay) - Добавление текста (
drawtext) - Деинтерлейсинг, шумоподавление, поворот и т.д.
⚠️ Каждый фильтр — потенциальный источник задержки, потому что:
- Ему может потребоваться накопить несколько кадров (например, для шумоподавления или стабилизации).
- Фильтры работают синхронно: обработка одного кадра блокирует следующий, пока не завершится.
💡 Пример:
Фильтрhqdn3d(высококачественное шумоподавление) использует буферы для анализа соседних кадров. Это добавляет задержку в 2–3 кадра.
5. Кодеры (Encoders)
На этом этапе «сырое» видео или аудио снова сжимается — уже в нужный формат на выходе.
- Например: YUV → H.264 с помощью
libx264 - Или: PCM → AAC с помощью
libfdk_aac
Кодирование — один из самых ресурсоёмких и буфероёмких этапов. Особенно если используются сложные настройки: длинный GOP, look-ahead, B-кадры.
🔍 Пример:
При трансляции в RTMP часто используется:-c:v libx264 -preset veryfast -tune zerolatencyЭти параметры уменьшают задержку, но увеличивают нагрузку на CPU.
6. Мультиплексор (Muxer)
Мультиплексор «упаковывает» закодированные потоки в выходной контейнер (формат). Например:
- H.264 + AAC → FLV (для RTMP)
- H.264 + AAC → MPEG-TS (для SRT или UDP)
- H.264 + AAC → MP4/MKV (для записи)
⚠️ Мультиплексор также буферизует данные, особенно если:
- Нужно дождаться ключевого кадра (I-frame) для начала записи.
- Формат требует метаданных в начале файла (например,
moovв MP4).
7. Выход (output)
Финальный этап — отправка данных:
- В файл:
output.mp4 - В сеть:
rtmp://...,srt://...,udp://...
Как и на входе, сеть требует буферизации:
- Для TCP — буферы сокета
- Для UDP/RTP — буферы джиттера (jitter buffer)
- Для SRT — встроенный механизм компенсации потерь и задержки
Где возникают буферы и задержка?
Задержка (латентность) в FFMPEG — это сумма задержек на каждом этапе. Ниже приведена таблица с основными источниками:
| Этап | Источник задержки | Примеры |
|---|---|---|
| Вход (input) | Сетевой буфер, ожидание пакетов | -rtbufsize, TCP receive buffer |
| Демультиплексор | Ожидание I-кадра, анализ формата | Первая пауза при запуске RTSP |
| Декодер | Внутренние буферы декодера (B-кадры) | H.264 с B-кадрами → +2–3 кадра |
| Фильтры | Накопление кадров для обработки | hqdn3d, deinterlace, overlay |
| Кодер | Look-ahead, GOP, VBV-буфер | -g 60, -bf 2, -bufsize 2M |
| Мультиплексор | Буферизация перед записью/отправкой | FLV: ждёт первый I-кадр |
| Выход | Сетевой буфер, jitter buffer | SRT latency=120, UDP-джиттер |
📌 Пример:
При приёме RTSP с IP-камеры и отправке в RTMP с транскодированием и фильтрами:
- Вход: 50–100 мс (TCP-джиттер)
- Демультиплексор: 50 мс (ожидание I-кадра)
- Декодер: 33 мс (один B-кадр при 30 fps)
- Фильтр масштабирования: 33 мс
- Кодер: 100 мс (look-ahead + GOP)
- Мультиплексор: 50 мс
- Выход: 50 мс (RTMP-буфер)
Итого: ~366 мс задержки — без учёта сети и клиентского плеера.
Почему «живой» поток отличается от локального файла?
| Характеристика | Локальный файл | Сетевой поток |
|---|---|---|
| Доступ к данным | Полный, мгновенный | Постепенный, с задержкой |
| Стабильность | Нет потерь пакетов | Возможны потери, джиттер |
| Синхронизация | Точная (все кадры на месте) | Требуется выравнивание (PTS/DTS) |
| Буферизация | Минимальная | Обязательная (для стабильности) |
| Перемотка | Возможна | Недоступна (в режиме реального времени) |
| Задержка | Практически нулевая | Суммарная, накапливается на каждом этапе |
💡 Пример:
При запускеffplay rtsp://cam/streamвы можете заметить, что:
- Первые 1–2 секунды — чёрный экран (демультиплексор ждёт I-кадр),
- Затем изображение «подпрыгивает» — это выравниваются временные метки,
- После этого идёт плавное воспроизведение, но с задержкой в 500-1000 мс, часто больше.
::: warn FFMPEG (и FFPLAY) при воспроизведении RTSP-потоков делает очень заметную задержку. Секунда -- это ещё хороший случай, может быть и две. Действительно быстрое отображение RTSP получается у GStreamer, с которым мы познакомимся в следующей лекции.
:::
Практическое значение схемы
Эта модель не просто теория — она нужна для настройки и оптимизации:
- Чтобы уменьшить задержку, вы должны понимать, где она возникает.
- Чтобы выбрать режим работы (
-c copyvs транскодирование), нужно знать, что происходит на каждом этапе. - Чтобы диагностировать проблемы, вы смотрите логи и определяете, на каком этапе происходит сбой.
🔧 Совет:
Всегда начинайте с-c copy, если возможно. Это исключает декодирование и кодирование — два самых тяжёлых и буфероёмких этапа.
Итог
FFMPEG — это универсальный конвейер обработки медиаданных, где:
- Файловый и сетевой ввод с точки зрения формата — эквивалентны.
- Задержка — это сумма буферов на каждом этапе: вход, демультиплексор, декодер, фильтры, кодер, мультиплексор, выход.
- Работа с «живым» потоком требует буферизации, синхронизации и устойчивости к потерям — в отличие от локальных файлов.
🎯 Важно: Эта схема будет использоваться далее при разборе протоколов (RTSP, RTMP, SRT), транскодирования, мультивью и настройки низкой задержки. Понимание пайплайна — ключ к эффективной работе с FFMPEG в сетевых видеосистемах.