OWT Server video_agent源码分析

发现阅读代码很容易忘记,所以想写文档,加深理解记忆。

一,VideoMixer创建过程

  • 配置限定了最多合并16个视频(input),每个input会创建一个SoftInput,它还会创建FrameConverter转换帧。
  • 创建两个generators,是根据fps创建的,一个是6到48帧,一个是15到60帧,它们会启动不同间隔的定时器。
void VideoMixer::New(const v8::FunctionCallbackInfo<v8::Value>& args) {
......
VideoMixer* obj = new VideoMixer();
obj->me = new mcu::VideoMixer(config);

VideoMixer::VideoMixer(const VideoMixerConfig& config)
: m_nextOutputIndex(0)
, m_maxInputCount(16)
{
......
m_frameMixer.reset(new VideoFrameMixerImpl(m_maxInputCount, rootSize, bgColor, true, config.crop));
}

// 创建硬件编码MsdkVideoCompositor或者软编码SoftVideoCompositor

VideoFrameMixerImpl::VideoFrameMixerImpl(uint32_t maxInput, owt_base::VideoSize rootSize, owt_base::YUVColor bgColor, bool useSimulcast, bool crop)
: m_useSimulcast(useSimulcast)
{
#ifdef ENABLE_MSDK
if (!m_compositor)
m_compositor.reset(new MsdkVideoCompositor(maxInput, rootSize, bgColor, crop));
#endif
if (!m_compositor)
m_compositor.reset(new SoftVideoCompositor(maxInput, rootSize, bgColor, crop));
}

//创建SoftInput(),  AvatarManager(), SoftFrameGenerator()

SoftVideoCompositor::SoftVideoCompositor(uint32_t maxInput, VideoSize rootSize, YUVColor bgColor, bool crop)
: m_maxInput(maxInput)
{
m_inputs.resize(m_maxInput);

for (auto& input : m_inputs) {
input.reset(new SoftInput());
}

m_avatarManager.reset(new AvatarManager(maxInput));
m_generators.resize(2);
m_generators[0].reset(new SoftFrameGenerator(this, rootSize, bgColor, crop, 60, 15));
m_generators[1].reset(new SoftFrameGenerator(this, rootSize, bgColor, crop, 48, 6));
}

CALL STACK:

我们调试下mixer的工作过程,MCU是默认模式,会使用mixer合流。 先看in的过程,也就是从webr-agent读取包,并合流的过程。

videoMixer-sw.node!mcu::SoftVideoCompositor::SoftVideoCompositor(mcu::SoftVideoCompositor * const this, uint32_t maxInput, owt_base::VideoSize rootSize, owt_base::YUVColor bgColor, bool crop) (/home/oem/git/owt-server/source/agent/video/videoMixer/SoftVideoCompositor.cpp:609)

videoMixer-sw.node!mcu::VideoFrameMixerImpl::VideoFrameMixerImpl(mcu::VideoFrameMixerImpl * const this, uint32_t maxInput, owt_base::VideoSize rootSize, owt_base::YUVColor bgColor, bool useSimulcast, bool crop) (/home/oem/git/owt-server/source/agent/video/videoMixer/VideoFrameMixerImpl.h:114)

videoMixer-sw.node!mcu::VideoMixer::VideoMixer(mcu::VideoMixer * const this, const mcu::VideoMixerConfig & config) (/home/oem/git/owt-server/source/agent/video/videoMixer/VideoMixer.cpp:68)

videoMixer-sw.node!VideoMixer::New(const v8::FunctionCallbackInfo<v8::Value> & args) (/home/oem/git/owt-server/source/agent/video/videoMixer/VideoMixerWrapper.cc:90)

第一个用户进入房间时,就会进入的构造函数:

这时还只初始化了对象,还没有开始拉流。后面就会创建InternalServer,InternalCcient对象,它包装了internalIO.node的c++对象.

5.0.x之后的master分支,对InternalIO模块进行了重写。

/home/oem/git/owt-server/dist-debug/video_agent/video/internalConnectionRouter.js
const internalIO = require('../internalIO/build/Release/internalIO');

const {InternalServer, InternalClient} = internalIO;

  constructor({protocol, minport, maxport}) {
    setSecurePromise.then(() => {
      this.internalServer = new InternalServer(


/home/oem/git/owt-server/source/agent/addons/internalIO/InternalServerWrapper.cc
NAN_METHOD(InternalServer::New) {

    InternalServer* obj = new InternalServer();
    obj->me = new owt_base::InternalServer(


/home/oem/git/owt-server/source/core/owt_base/internal/InternalServer.cpp

/home/oem/git/owt-server/dist-debug/video_agent/video/vmixer.js
    that.publish = function (stream_id, stream_type, options, callback) {
            addInput(stream_id, options.video.codec, options, options.avatar, function () {


    var addInput = function (stream_id, codec, options, avatar, on_ok, on_error) {

        if (engine) {
            var conn = router.getOrCreateRemoteSource({
                id: stream_id,
                ip: options.ip,
                port: options.port
            }


/home/oem/git/owt-server/dist-debug/video_agent/video/internalConnectionRouter.js
const internalIO = require('../internalIO/build/Release/internalIO');

const {InternalServer, InternalClient} = internalIO;

  getOrCreateRemoteSource({id, ip, port}, onStat) {
    if (!this.remoteStreams.has(id) && ip && port) {
      log.debug('RemoteSource created:', id, ip, port);
      let conn = new InternalClient(id, this.protocol, ip, port, onStat);

/home/oem/git/owt-server/source/agent/addons/internalIO/InternalClientWrapper.cc
NAN_METHOD(InternalClient::New) {

    InternalClient* obj = new InternalClient();
    obj->me = new owt_base::InternalClient(

InternalClient::InternalClient(
    const std::string& streamId,
    const std::string& protocol,
    const std::string& ip,
    unsigned int port,
    Listener* listener)
    : InternalClient(streamId, protocol, listener)
{
    if (!TransportSecret::getPassphrase().empty()) {
        m_client->enableSecure();
    }
    m_client->createConnection(ip, port);
}

/home/oem/git/owt-server/source/core/owt_base/internal/TransportClient.cpp
void TransportClient::createConnection(const std::string& ip, uint32_t port)
{
        m_sslSocket->
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值