Skip to content
This repository was archived by the owner on Oct 23, 2024. It is now read-only.

Commit 73d7ef3

Browse files
authored
Share transport feedback processor and bandwidth estimation in same call (#1051)
* Add send side bitrate estimation in video sender * Export estimated bitrate interface on addon layer * Share transport feedback processor and bandwidth estimation among publications/subscriptions in same call. Add bandwidth estimation and send bitrate addon API. * Fix error when destroy transport controller send * Address some comments
1 parent cad8142 commit 73d7ef3

18 files changed

+361
-64
lines changed
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Copyright (C) <2021> Intel Corporation
2+
//
3+
// SPDX-License-Identifier: Apache-2.0
4+
5+
#ifndef BUILDING_NODE_EXTENSION
6+
#define BUILDING_NODE_EXTENSION
7+
#endif
8+
9+
#include "CallBaseWrapper.h"
10+
11+
using namespace v8;
12+
13+
Nan::Persistent<Function> CallBase::constructor;
14+
15+
CallBase::CallBase() {};
16+
CallBase::~CallBase() {};
17+
18+
NAN_MODULE_INIT(CallBase::Init) {
19+
// Prepare constructor template
20+
Local<FunctionTemplate> tpl = Nan::New<FunctionTemplate>(New);
21+
tpl->SetClassName(Nan::New("CallBase").ToLocalChecked());
22+
tpl->InstanceTemplate()->SetInternalFieldCount(1);
23+
24+
// Prototype
25+
Nan::SetPrototypeMethod(tpl, "close", close);
26+
27+
constructor.Reset(tpl->GetFunction());
28+
Nan::Set(target, Nan::New("CallBase").ToLocalChecked(),
29+
Nan::GetFunction(tpl).ToLocalChecked());
30+
}
31+
32+
NAN_METHOD(CallBase::New) {
33+
if (info.IsConstructCall()) {
34+
CallBase* obj = new CallBase();
35+
obj->rtcAdapter.reset(rtc_adapter::RtcAdapterFactory::CreateRtcAdapter());
36+
37+
obj->Wrap(info.This());
38+
info.GetReturnValue().Set(info.This());
39+
} else {
40+
// Not construct call
41+
}
42+
}
43+
44+
NAN_METHOD(CallBase::close) {
45+
CallBase* obj = Nan::ObjectWrap::Unwrap<CallBase>(info.Holder());
46+
obj->rtcAdapter.reset();
47+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright (C) <2021> Intel Corporation
2+
//
3+
// SPDX-License-Identifier: Apache-2.0
4+
5+
#ifndef CALLBASEWRAPPER_H
6+
#define CALLBASEWRAPPER_H
7+
8+
#include <RtcAdapter.h>
9+
#include <nan.h>
10+
11+
/*
12+
* Wrapper class of RtcAdapter for call
13+
*/
14+
class CallBase : public Nan::ObjectWrap {
15+
public:
16+
static NAN_MODULE_INIT(Init);
17+
18+
std::shared_ptr<rtc_adapter::RtcAdapter> rtcAdapter;
19+
private:
20+
CallBase();
21+
~CallBase();
22+
23+
static NAN_METHOD(New);
24+
static NAN_METHOD(close);
25+
26+
static Nan::Persistent<v8::Function> constructor;
27+
};
28+
29+
#endif

source/agent/webrtc/rtcFrame/VideoFrameConstructorWrapper.cc

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#endif
88

99
#include "VideoFrameConstructorWrapper.h"
10+
#include "CallBaseWrapper.h"
1011

1112
using namespace v8;
1213

@@ -42,11 +43,11 @@ NAN_METHOD(VideoFrameConstructor::New) {
4243
if (info.IsConstructCall()) {
4344
VideoFrameConstructor* obj = new VideoFrameConstructor();
4445
int transportccExt = (info.Length() >= 2) ? info[1]->IntegerValue(Nan::GetCurrentContext()).ToChecked() : -1;
45-
VideoFrameConstructor* base_wrapper = (info.Length() == 3)
46-
? Nan::ObjectWrap::Unwrap<VideoFrameConstructor>(Nan::To<v8::Object>(info[2]).ToLocalChecked())
46+
CallBase* baseWrapper = (info.Length() == 3)
47+
? Nan::ObjectWrap::Unwrap<CallBase>(Nan::To<v8::Object>(info[2]).ToLocalChecked())
4748
: nullptr;
48-
if (base_wrapper) {
49-
obj->me = new owt_base::VideoFrameConstructor(base_wrapper->me, obj, transportccExt);
49+
if (baseWrapper) {
50+
obj->me = new owt_base::VideoFrameConstructor(baseWrapper->rtcAdapter, obj, transportccExt);
5051
} else if (transportccExt > 0) {
5152
obj->me = new owt_base::VideoFrameConstructor(obj, transportccExt);
5253
} else {
@@ -179,7 +180,8 @@ NAN_MODULE_INIT(VideoFrameSource::Init) {
179180

180181
NAN_METHOD(VideoFrameSource::New) {
181182
if (info.Length() == 1) {
182-
VideoFrameConstructor* parent = Nan::ObjectWrap::Unwrap<VideoFrameConstructor>(info[0]->ToObject());
183+
VideoFrameConstructor* parent = Nan::ObjectWrap::Unwrap<VideoFrameConstructor>(
184+
info[0]->ToObject(Nan::GetCurrentContext()).ToLocalChecked());
183185
VideoFrameSource* obj = new VideoFrameSource();
184186
obj->me = parent->me;
185187
obj->src = obj->me;

source/agent/webrtc/rtcFrame/VideoFramePacketizerWrapper.cc

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#define BUILDING_NODE_EXTENSION
77
#endif
88

9+
#include "CallBaseWrapper.h"
910
#include "MediaWrapper.h"
1011
#include "VideoFramePacketizerWrapper.h"
1112
#include "WebRtcConnection.h"
@@ -29,6 +30,9 @@ void VideoFramePacketizer::Init(v8::Local<v8::Object> exports) {
2930
NODE_SET_PROTOTYPE_METHOD(tpl, "unbindTransport", unbindTransport);
3031
NODE_SET_PROTOTYPE_METHOD(tpl, "enable", enable);
3132
NODE_SET_PROTOTYPE_METHOD(tpl, "ssrc", getSsrc);
33+
NODE_SET_PROTOTYPE_METHOD(tpl, "getTotalBitrateBps", getTotalBitrate);
34+
NODE_SET_PROTOTYPE_METHOD(tpl, "getRetransmitBitrateBps", getRetransmitBitrate);
35+
NODE_SET_PROTOTYPE_METHOD(tpl, "getEstimatedBandwidthBps", getEstimatedBandwidth);
3236

3337
constructor.Reset(isolate, tpl->GetFunction());
3438
exports->Set(String::NewFromUtf8(isolate, "VideoFramePacketizer"), tpl->GetFunction());
@@ -40,15 +44,25 @@ void VideoFramePacketizer::New(const FunctionCallbackInfo<Value>& args) {
4044

4145
bool supportRED = (args[0]->ToBoolean(Nan::GetCurrentContext()).ToLocalChecked())->BooleanValue();
4246
bool supportULPFEC = (args[1]->ToBoolean(Nan::GetCurrentContext()).ToLocalChecked())->BooleanValue();
43-
int transportccExt = (args.Length() == 3) ? args[2]->IntegerValue(Nan::GetCurrentContext()).ToChecked() : -1;
47+
int transportccExt = (args.Length() >= 3) ? args[2]->IntegerValue(Nan::GetCurrentContext()).ToChecked() : -1;
4448
std::string mid;
4549
int midExtId = -1;
4650
if (args.Length() >= 5) {
4751
v8::String::Utf8Value param4(isolate, Nan::To<v8::String>(args[3]).ToLocalChecked());
4852
mid = std::string(*param4);
4953
midExtId = args[4]->IntegerValue(Nan::GetCurrentContext()).ToChecked();
5054
}
51-
bool selfRequestKeyframe = (args.Length() == 6) ? (args[5]->ToBoolean(Nan::GetCurrentContext()).ToLocalChecked())->BooleanValue() : false;
55+
bool selfRequestKeyframe = (args.Length() >= 6)
56+
? (args[5]->ToBoolean(Nan::GetCurrentContext()).ToLocalChecked())->BooleanValue()
57+
: false;
58+
59+
CallBase* baseWrapper = (args.Length() >= 7)
60+
? Nan::ObjectWrap::Unwrap<CallBase>(Nan::To<v8::Object>(args[6]).ToLocalChecked())
61+
: nullptr;
62+
63+
bool enableBandwidthEstimation = (args.Length() >= 8)
64+
? (args[7]->ToBoolean(Nan::GetCurrentContext()).ToLocalChecked())->BooleanValue()
65+
: false;
5266

5367
VideoFramePacketizer* obj = new VideoFramePacketizer();
5468
owt_base::VideoFramePacketizer::Config config;
@@ -57,6 +71,10 @@ void VideoFramePacketizer::New(const FunctionCallbackInfo<Value>& args) {
5771
config.transportccExt = transportccExt;
5872
config.mid = mid;
5973
config.midExtId = midExtId;
74+
config.enableBandwidthEstimation = enableBandwidthEstimation;
75+
if (baseWrapper) {
76+
config.rtcAdapter = baseWrapper->rtcAdapter;
77+
}
6078

6179
if (transportccExt > 0) {
6280
config.enableTransportcc = true;
@@ -129,3 +147,35 @@ void VideoFramePacketizer::getSsrc(const v8::FunctionCallbackInfo<v8::Value>& ar
129147
args.GetReturnValue().Set(Number::New(isolate, ssrc));
130148
}
131149

150+
void VideoFramePacketizer::getTotalBitrate(const v8::FunctionCallbackInfo<v8::Value>& args) {
151+
Isolate* isolate = Isolate::GetCurrent();
152+
HandleScope scope(isolate);
153+
154+
VideoFramePacketizer* obj = ObjectWrap::Unwrap<VideoFramePacketizer>(args.Holder());
155+
owt_base::VideoFramePacketizer* me = obj->me;
156+
157+
uint32_t bitrate = me->getTotalBitrate();
158+
args.GetReturnValue().Set(Number::New(isolate, bitrate));
159+
}
160+
161+
void VideoFramePacketizer::getRetransmitBitrate(const v8::FunctionCallbackInfo<v8::Value>& args) {
162+
Isolate* isolate = Isolate::GetCurrent();
163+
HandleScope scope(isolate);
164+
165+
VideoFramePacketizer* obj = ObjectWrap::Unwrap<VideoFramePacketizer>(args.Holder());
166+
owt_base::VideoFramePacketizer* me = obj->me;
167+
168+
uint32_t bitrate = me->getRetransmitBitrate();
169+
args.GetReturnValue().Set(Number::New(isolate, bitrate));
170+
}
171+
172+
void VideoFramePacketizer::getEstimatedBandwidth(const v8::FunctionCallbackInfo<v8::Value>& args) {
173+
Isolate* isolate = Isolate::GetCurrent();
174+
HandleScope scope(isolate);
175+
176+
VideoFramePacketizer* obj = ObjectWrap::Unwrap<VideoFramePacketizer>(args.Holder());
177+
owt_base::VideoFramePacketizer* me = obj->me;
178+
179+
uint32_t bitrate = me->getEstimatedBandwidth();
180+
args.GetReturnValue().Set(Number::New(isolate, bitrate));
181+
}

source/agent/webrtc/rtcFrame/VideoFramePacketizerWrapper.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ class VideoFramePacketizer : public FrameDestination {
3131

3232
static void enable(const v8::FunctionCallbackInfo<v8::Value>& args);
3333
static void getSsrc(const v8::FunctionCallbackInfo<v8::Value>& args);
34+
35+
static void getTotalBitrate(const v8::FunctionCallbackInfo<v8::Value>& args);
36+
static void getRetransmitBitrate(const v8::FunctionCallbackInfo<v8::Value>& args);
37+
static void getEstimatedBandwidth(const v8::FunctionCallbackInfo<v8::Value>& args);
3438
};
3539

3640
#endif

source/agent/webrtc/rtcFrame/addon.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#include "AudioFrameConstructorWrapper.h"
66
#include "AudioFramePacketizerWrapper.h"
7+
#include "CallBaseWrapper.h"
78
#include "VideoFrameConstructorWrapper.h"
89
#include "VideoFramePacketizerWrapper.h"
910

@@ -16,6 +17,7 @@ void InitAll(Handle<Object> exports) {
1617
AudioFramePacketizer::Init(exports);
1718
VideoFrameConstructor::Init(exports);
1819
VideoFramePacketizer::Init(exports);
20+
CallBase::Init(exports);
1921
}
2022

2123
NODE_MODULE(addon, InitAll)

source/agent/webrtc/rtcFrame/binding.gyp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
'AudioFramePacketizerWrapper.cc',
1717
'VideoFrameConstructorWrapper.cc',
1818
'VideoFramePacketizerWrapper.cc',
19+
'CallBaseWrapper.cc',
1920
'addon.cc',
2021
],
2122
'dependencies': ['librtcadapter'],

source/agent/webrtc/wrtcConnection.js

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ const {
1010
AudioFrameConstructor,
1111
AudioFramePacketizer,
1212
VideoFrameConstructor,
13-
VideoFramePacketizer
13+
VideoFramePacketizer,
14+
CallBase,
1415
} = require('../rtcFrame/build/Release/rtcFrame.node');
1516

1617
const logger = require('../logger').logger;
@@ -61,14 +62,8 @@ class WrtcStream extends EventEmitter {
6162
wrtc.setAudioSsrc(id, audio.ssrc);
6263
}
6364
if (video) {
64-
if (!wrtc.callBase) {
65-
this.videoFrameConstructor = new VideoFrameConstructor(
66-
this._onMediaUpdate.bind(this), video.transportcc);
67-
wrtc.callBase = this.videoFrameConstructor;
68-
} else {
69-
this.videoFrameConstructor = new VideoFrameConstructor(
70-
this._onMediaUpdate.bind(this), video.transportcc, wrtc.callBase);
71-
}
65+
this.videoFrameConstructor = new VideoFrameConstructor(
66+
this._onMediaUpdate.bind(this), video.transportcc, wrtc.callBase);
7267
this.videoFrameConstructor.bindTransport(wrtc.getMediaStream(id));
7368
wrtc.setVideoSsrcList(id, video.ssrcs);
7469
}
@@ -84,8 +79,10 @@ class WrtcStream extends EventEmitter {
8479
}
8580
}
8681
if (video) {
82+
let enableBWE = false;
8783
this.videoFramePacketizer = new VideoFramePacketizer(
88-
video.red, video.ulpfec, video.transportcc, video.mid, video.midExtId);
84+
video.red, video.ulpfec, video.transportcc, video.mid,
85+
video.midExtId, false, wrtc.callBase, enableBWE);
8986
this.videoFramePacketizer.bindTransport(wrtc.getMediaStream(id));
9087
}
9188
}
@@ -123,9 +120,6 @@ class WrtcStream extends EventEmitter {
123120
}
124121
if (this.videoFrameConstructor) {
125122
// TODO: seperate call and frame constructor in node wrapper
126-
if (this.wrtc.callBase === this.videoFrameConstructor) {
127-
this.wrtc.callBase = null;
128-
}
129123
this.videoFrameConstructor.close();
130124
}
131125
}
@@ -604,6 +598,7 @@ module.exports = function (spec, on_status, on_track) {
604598
track.close();
605599
});
606600
}
601+
wrtc.callBase.close();
607602
wrtc.wrtc.stop();
608603
wrtc.close();
609604
wrtc = undefined;
@@ -638,6 +633,7 @@ module.exports = function (spec, on_status, on_track) {
638633
}
639634
});
640635
wrtc = new Connection(wrtcId, threadPool, ioThreadPool, { ipAddresses });
636+
wrtc.callBase = new CallBase();
641637
// wrtc.addMediaStream(wrtcId, {label: ''}, direction === 'in');
642638

643639
initWebRtcConnection(wrtc);

source/core/owt_base/VideoFrameConstructor.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ VideoFrameConstructor::VideoFrameConstructor(VideoInfoListener* vil, uint32_t tr
2929
}
3030

3131
VideoFrameConstructor::VideoFrameConstructor(
32-
VideoFrameConstructor* base,
32+
std::shared_ptr<rtc_adapter::RtcAdapter> rtcAdapter,
3333
VideoInfoListener* vil, uint32_t transportccExtId)
3434
: m_enabled(true)
3535
, m_ssrc(0)
@@ -39,10 +39,10 @@ VideoFrameConstructor::VideoFrameConstructor(
3939
, m_videoReceive(nullptr)
4040
{
4141
m_config.transport_cc = transportccExtId;
42-
assert(base);
42+
assert(rtcAdapter.get());
4343
m_feedbackTimer = SharedJobTimer::GetSharedFrequencyTimer(1);
4444
m_feedbackTimer->addListener(this);
45-
m_rtcAdapter = base->m_rtcAdapter;
45+
m_rtcAdapter = rtcAdapter;
4646
}
4747

4848
VideoFrameConstructor::~VideoFrameConstructor()

source/core/owt_base/VideoFrameConstructor.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@ class VideoFrameConstructor : public erizo::MediaSink,
4343
};
4444

4545
VideoFrameConstructor(VideoInfoListener*, uint32_t transportccExtId = 0);
46-
VideoFrameConstructor(VideoFrameConstructor*, VideoInfoListener*, uint32_t transportccExtId = 0);
46+
VideoFrameConstructor(std::shared_ptr<rtc_adapter::RtcAdapter>,
47+
VideoInfoListener*,
48+
uint32_t transportccExtId = 0);
4749
virtual ~VideoFrameConstructor();
4850

4951
void bindTransport(erizo::MediaSource* source, erizo::FeedbackSink* fbSink);

0 commit comments

Comments
 (0)