发现阅读代码很容易忘记,所以想写文档,加深理解记忆。
一,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->


938

被折叠的 条评论
为什么被折叠?



