1. Предпосылки
Присоединяйтесь к видеоконференцииSIPклиент, нужноMCUПолное микширование видео на сервере. а такжеowt-serverдаIntelна основе открытого исходного кодаWebRTCстриминговый сервис. MCU которого реализуетVideoMixerфункция, которая является хорошим ориентиром для завершения экрана микширования видео.
Эта статья в основном оowt-serverвнутриVideoMixerизКонвейерный процесса такжерезьбовая модельСделайте уход.
owt-server项目地址Github. ответвление кода от2019/10/24версия, адрес коммита61a95d68
2. Обзор
На картинке нижеowt-serverДиаграмма классов модуля смешанного экрана, а затем модели Pipeline и thread будут расширены на основе этой диаграммы.
основное введение:
Здесь показана только взаимосвязь между классами смешанных экранных модулей, а направление потока данных не показано (направление потока данных см. в следующем
Pipeline流程). Целое разделено на три области слева направо.
- область один: полное декодирование видео;
- область два: Полная композиция видео (Compose), наложение ника/обзора и т.д.;
- Зона три: полное кодирование видео, обратный вызов после завершения;
3. Конвейерный процесс
(1), конвейерный процесс
FrameSource --> decode --> compositorIn(Buffer) --> compose/overlay --> encode(queue) --> Destination
(2), как построить трубопровод
Для простоты чтения и понимания приведенный ниже код, за исключением
类名а также方法名Кроме того, остальные могут опускать неважные ссылки.Поддельный код.
1. Настройте ввод и вывод для VideoMixer
- каждый раз
addInput, принесет источник видеоданныхFrameSource;каждый разaddOutputПринесет экран микширования видео (весь пайплайн) и перезвонит после завершенияdest; - установить каждый
Input, будуInputс解码器,解码完成后的缓冲区(compositorIn) привязка; установить каждыйOutput, будуOutputсвязать с энкодером; - в конфигурации
Inputа такжеOutputВо время процесса, установив обратный вызов следующего функционального модуля после завершения текущего функционального модуля (например, кодирование, компоновка и т. д.) (dest), выполнить всюPipeline顺序关系создание;
2. FrameSource --> decode --> compositorIn
inline bool VideoFrameMixerImpl::addInput(owt_base::FrameSource* source ...)
{
...
owt_base::VideoFrameDecoder* decoder = new owt_base::FFmpegFrameDecoder();
CompositeIn* compositorIn = new CompositeIn(...);
source->addVideoDestination(decoder); // source -> decode
decoder->addVideoDestination(compositorIn); // decode -> compositorIn
...
}
3. compositorIn(Buffer) --> encode(queue)
В приведенном выше процессе Pipeline за композицией/наложением следует compositorIn.После взятия кадра из буфера (compositorIn) во всех входах компоновка завершается в классе, поэтому нет необходимости устанавливать обратный вызов. Вам нужен только один после микширования экранаdest(кодировать).
inline bool VideoFrameMixerImpl::addOutput(int fps, int bitrate, owt_base::FrameDestination* dest ...)
{
...
owt_base::VideoFrameEncoder* encoder = new owt_base::VCMFrameEncoder(format, profile, m_useSimulcast);
m_compositor->addOutput(fps, bitrate, encoder); // compositorIn -> encode, encoder就是compositorIn的dest
...
}
4. encode(queue) --> Destination
Или в приведенной выше функции:
inline bool VideoFrameMixerImpl::addOutput(int fps, int bitrate, owt_base::FrameDestination* dest ...)
{
...
owt_base::VideoFrameEncoder* encoder = new owt_base::VCMFrameEncoder(format, profile, m_useSimulcast);
encoder->generateStream(fps, bitrate, dest); // encode -> dest
...
}
существуетowt_base::VCMFrameEncoder::generateStreamВнутри он будет использоватьEncodeOutвведите поставитьdestСвязывание с некоторой другой информацией. существуетVCMFrameEncoderПосле завершения кодирования передайте этоEncodeOutструктура найденаdest, чтобы направить поток кода после микширования экрана за пределы модуля микширования экрана.
В-четвертых, модель потока
Весь пайплайн включает в себя 3 потока, а именно:
-
пройти черезFrameSourceОтправьте видеопоток во внешний поток модуля смешанного экрана.
- Этот поток завершит декодирование видеопотока, а декодированный YUV будет сохранен в
SoftVideoCompositor::m_inputsсередина; - m_inputs - буфер кадров всех Входов, но длина буфера каждого Входа всего 1, то есть буферизовать можно только один кадр.Если кадр не успеет смешать экран, то более поздний декодированный кадр перезапишет этот кадр ;
- Этот поток завершит декодирование видеопотока, а декодированный YUV будет сохранен в
-
существуетSoftFrameGeneratorПоток, который регулярно составляет посередине.
- После завершения смешанного экрана поместите YUV в
VCMFrameEncoderВ очереди кодирования кодирование последовательно завершается следующим потоком;
- После завершения смешанного экрана поместите YUV в
-
существуетVCMFrameEncoderПоток, в котором выполняется кодирование.
- Возвращается потоком после завершения кодирования
EncodedFrameнаверх.
- Возвращается потоком после завершения кодирования
Пять, думая о модели потока owt-сервера
Три потока в многопоточной модели выше:
- Первый является внешним и завершает декодирование. Декодирование должно выполняться немедленно, без буферизации. Буфер буфера не должен быть слишком длинным, иначе буферизованный поток кода будет бессмысленным; буфер не должен быть слишком коротким, иначе он будет перезаписан или отброшен, если он слишком короткий. Как только кодовый поток будет частично отброшен из-за буферизации, это вызовет проблемы при декодировании последующих кодовых потоков и приведет к размытию экрана. Так что правильно, что декодирование выполняется внешним потоком.
- Второй внутренний и завершает смешанный экран. Если вы считаете, что работа Pipeline слишком тяжелая, это может привести к большой задержке завершения потока, тогда этот поток также необходим.
- Третий также является внутренним и завершает кодировку. Может ли эта часть работы быть выполнена вторым потоком? В конце концов, он работает на сервере, и слишком большое количество переключений потоков также может сказаться на производительности.
На аудио- и видеосервере каждому клиенту будет соответствоватьendpointобъект для приема, обработки или пересылки аудио и видео. КаждыйendpointВидео, пересылаемое соответствующему клиенту, должно быть другим (по крайней мере, не его собственное видео), что означает, чтоendpointсоответствует одномуVideoMixer. а такжеowt-serverизVideoMixerпо крайней мере представил两个线程Завершите трубопровод,Повлияет ли такое количество потоков на производительность сервера??