Skip to content

Commit f0de4f2

Browse files
authored
Merge pull request #73 from OpenNetLab/dev
2 parents f5422b2 + 5aae8be commit f0de4f2

File tree

16 files changed

+413
-24
lines changed

16 files changed

+413
-24
lines changed

Makefile

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ output_dir := out/Default
55
target_dir := target
66
target_lib_dir := $(target_dir)/lib
77
target_bin_dir := $(target_dir)/bin
8+
target_pylib_dir := $(target_dir)/pylib
89

910
compile_docker := alphartc-compile
1011
release_docker := alphartc
@@ -37,7 +38,8 @@ peerconnection_serverless:
3738
make docker-$@ \
3839
output_dir=$(output_dir) \
3940
target_lib_dir=$(target_lib_dir) \
40-
target_bin_dir=$(target_bin_dir)
41+
target_bin_dir=$(target_bin_dir) \
42+
target_pylib_dir=$(target_pylib_dir)
4143

4244
# Docker internal command
4345

@@ -51,8 +53,14 @@ docker-app: docker-peerconnection_serverless
5153

5254
docker-peerconnection_serverless:
5355
ninja -C $(output_dir) peerconnection_serverless
56+
5457
mkdir -p $(target_lib_dir)
5558
cp modules/third_party/onnxinfer/lib/*.so $(target_lib_dir)
5659
cp modules/third_party/onnxinfer/lib/*.so.* $(target_lib_dir)
60+
5761
mkdir -p $(target_bin_dir)
58-
cp $(output_dir)/peerconnection_serverless $(target_bin_dir)
62+
cp $(output_dir)/peerconnection_serverless $(target_bin_dir)/peerconnection_serverless.origin
63+
cp examples/peerconnection/serverless/peerconnection_serverless $(target_bin_dir)
64+
65+
mkdir -p $(target_pylib_dir)
66+
cp modules/third_party/cmdinfer/*.py $(target_pylib_dir)/

README.md

Lines changed: 51 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,12 @@
3939

4040
AlphaRTC is a fork of Google's WebRTC project using ML-based bandwidth estimation, delivered by the OpenNetLab team. By equipping WebRTC with a more accurate bandwidth estimator, our mission is to eventually increase the quality of transmission.
4141

42-
AlphaRTC replaces Google Congestion Control (GCC) with ONNXInfer, an ML-powered bandwidth estimator, which takes in an ONNX model to make bandwidth estimation more accurate. ONNXInfer is proudly powered by Microsoft's [ONNXRuntime](https://github.com/microsoft/onnxruntime).
42+
AlphaRTC replaces Google Congestion Control (GCC) with two customized congestion control interfaces, PyInfer and ONNXInfer. The PyInfer provides an opportunity to load external bandwidth estimator written by Python. The external bandwidth estimator could be based on ML framework, like PyTorch or TensorFlow, or a pure Python algorithm without any dependencies. And the ONNXInfer is an ML-powered bandwidth estimator, which takes in an ONNX model to make bandwidth estimation more accurate. ONNXInfer is proudly powered by Microsoft's [ONNXRuntime](https://github.com/microsoft/onnxruntime).
4343

4444
## Environment
4545

46+
**We recommend you directly fetch the pre-provided Docker images from [Github release](https://github.com/OpenNetLab/AlphaRTC/releases/latest/download/alphartc.tar.gz)**
47+
4648
Ubuntu 18.04 is the only officially supported distro at this moment. For other distros, you may be able to compile your own binary, or use our pre-provided Docker images.
4749

4850
## Compilation
@@ -107,7 +109,7 @@ Note: all commands below work for both Linux (sh) and Windows (pwsh), unless oth
107109
gn gen out/Default
108110
```
109111

110-
5. Comile
112+
5. Compile
111113
```shell
112114
ninja -C out/Default peerconnection_serverless
113115
```
@@ -151,9 +153,6 @@ This section describes required fields for the json configuration file.
151153

152154
- **bwe_feedback_duration**: The duration the receiver sends its estimated target rate every time(*in millisecond*)
153155

154-
- **onnx**
155-
- **onnx_model_path**: The path of the [onnx](https://www.onnxruntime.ai/) model
156-
157156
- **video_source**
158157
- **video_disabled**:
159158
- **enabled**: If set to `true`, the client will not take any video source as input
@@ -188,11 +187,57 @@ This section describes required fields for the json configuration file.
188187
- **fps**: Frames per second of the output video file
189188
- **file_path**: The file path of the output video file in YUV format
190189

190+
#### Use PyInfer or ONNXInfer
191+
192+
##### PyInfer
193+
194+
The default bandwidth estimator is PyInfer, You should implement your Python class named `Estimator` with required methods `report_states` and `get_estimated_bandwidth` in Python file `BandwidthEstimator.py ` and put this file in your workspace.
195+
There is an example of Estimator with fixed estimated bandwidth 1Mbps. Here is an example [BandwidthEstimator.py](examples/peerconnection/serverless/corpus/BandwidthEstimator.py).
196+
197+
```python
198+
class Estimator(object):
199+
def report_states(self, stats: dict):
200+
'''
201+
stats is a dict with the following items
202+
{
203+
"send_time_ms": uint,
204+
"arrival_time_ms": uint,
205+
"payload_type": int,
206+
"sequence_number": uint,
207+
"ssrc": int,
208+
"padding_length": uint,
209+
"header_length": uint,
210+
"payload_size": uint
211+
}
212+
'''
213+
pass
214+
215+
def get_estimated_bandwidth(self)->int:
216+
return int(1e6) # 1Mbps
217+
218+
```
219+
220+
##### ONNXInfer
221+
222+
If you want to use the ONNXInfer as the bandwidth estimator, you should specify the path of onnx model in the config file. Here is an example configuration [receiver.json](examples/peerconnection/serverless/corpus/receiver.json)
223+
224+
- **onnx**
225+
- **onnx_model_path**: The path of the [onnx](https://www.onnxruntime.ai/) model
226+
227+
191228
#### Run peerconnection_serverless
192229
- Dockerized environment
193230

194231
To better demonstrate the usage of peerconnection_serverless, we provide an all-inclusive corpus in `examples/peerconnection/serverless/corpus`. You can use the following commands to execute a tiny example. After these commands terminates, you will get `outvideo.yuv` and `outaudio.wav`.
195-
232+
233+
234+
PyInfer:
235+
```shell
236+
sudo docker run -d --rm -v `pwd`/examples/peerconnection/serverless/corpus:/app -w /app --name alphartc alphartc peerconnection_serverless receiver_pyinfer.json
237+
sudo docker exec alphartc peerconnection_serverless sender_pyinfer.json
238+
```
239+
240+
ONNXInfer:
196241
``` shell
197242
sudo docker run -d --rm -v `pwd`/examples/peerconnection/serverless/corpus:/app -w /app --name alphartc alphartc peerconnection_serverless receiver.json
198243
sudo docker exec alphartc peerconnection_serverless sender.json

api/alphacc_config.cc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,10 @@ bool ParseAlphaCCConfig(const std::string& file_path) {
6868
RETURN_ON_FAIL(
6969
GetInt(top, "bwe_feedback_duration", &config->bwe_feedback_duration_ms));
7070

71-
RETURN_ON_FAIL(GetValue(top, "onnx", &second));
72-
RETURN_ON_FAIL(
73-
GetString(second, "onnx_model_path", &config->onnx_model_path));
74-
second.clear();
71+
if (GetValue(top, "onnx", &second)) {
72+
GetString(second, "onnx_model_path", &config->onnx_model_path);
73+
second.clear();
74+
}
7575

7676
bool enabled = false;
7777
RETURN_ON_FAIL(GetValue(top, "video_source", &second));

azure-pipelines.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,28 @@ steps:
3333
- script: docker run -d --rm -v `pwd`/examples/peerconnection/serverless/corpus:/app -w /app --name alphartc alphartc peerconnection_serverless receiver.json
3434
&& docker exec alphartc peerconnection_serverless sender.json
3535
displayName: 'run example'
36+
37+
- script: docker run -d --rm -v `pwd`/examples/peerconnection/serverless/corpus:/app -w /app --name alphartc_pyinfer alphartc peerconnection_serverless receiver_pyinfer.json
38+
&& docker exec alphartc_pyinfer peerconnection_serverless sender_pyinfer.json
39+
displayName: 'run pyinfer example'
40+
41+
- script: docker save alphartc | gzip > alphartc.tar.gz
42+
displayName: "Export alphartc docker image"
43+
44+
- publish: $(System.DefaultWorkingDirectory)/alphartc.tar.gz
45+
continueOnError: true
46+
artifact: alphartc.tar.gz
47+
displayName: "Archive AlphaRTC Peerconnection"
48+
49+
- task: GitHubRelease@0
50+
inputs:
51+
gitHubConnection: 'Pterosaur (1)'
52+
repositoryName: '$(Build.Repository.Name)'
53+
action: 'create'
54+
tagSource: manual
55+
tag: $(Build.BuildNumber)
56+
title: alphartc
57+
assets: '$(System.DefaultWorkingDirectory)/alphartc.tar.gz'
58+
changeLogCompareToRelease: 'lastFullRelease'
59+
changeLogType: 'commitBased'
60+
displayName: "Release target"

dockers/Dockerfile.release

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
FROM ubuntu:18.04
22

33
RUN apt-get update && apt-get install -y \
4-
libx11-6 libgomp1
4+
libx11-6 libgomp1 python3
55

66
COPY lib /usr/lib/
77

88
COPY bin /usr/bin/
99

10+
COPY pylib /usr/lib/python3/dist-packages/
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
2+
class Estimator(object):
3+
def report_states(self, stats: dict):
4+
'''
5+
stats is a dict with the following items
6+
{
7+
"send_time_ms": uint,
8+
"arrival_time_ms": uint,
9+
"payload_type": int,
10+
"sequence_number": uint,
11+
"ssrc": int,
12+
"padding_length": uint,
13+
"header_length": uint,
14+
"payload_size": uint
15+
}
16+
'''
17+
pass
18+
19+
def get_estimated_bandwidth(self)->int:
20+
return int(1e6) # 1Mbps
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
{
2+
"serverless_connection": {
3+
"autoclose": 20,
4+
"sender": {
5+
"enabled": false
6+
},
7+
"receiver": {
8+
"enabled": true,
9+
"listening_ip": "0.0.0.0",
10+
"listening_port": 8000
11+
}
12+
},
13+
"bwe_feedback_duration": 200,
14+
"video_source": {
15+
"video_disabled": {
16+
"enabled": true
17+
},
18+
"webcam": {
19+
"enabled": false
20+
},
21+
"video_file": {
22+
"enabled": false,
23+
"height": 240,
24+
"width": 320,
25+
"fps": 10,
26+
"file_path": "testmedia/test.yuv"
27+
}
28+
},
29+
"audio_source": {
30+
"microphone": {
31+
"enabled": false
32+
},
33+
"audio_file": {
34+
"enabled": true,
35+
"file_path": "testmedia/test.wav"
36+
}
37+
},
38+
"save_to_file": {
39+
"enabled": true,
40+
"audio": {
41+
"file_path": "outaudio.wav"
42+
},
43+
"video": {
44+
"width": 320,
45+
"height": 240,
46+
"fps": 10,
47+
"file_path": "outvideo.yuv"
48+
}
49+
},
50+
"logging": {
51+
"enabled": true,
52+
"log_output_path": "webrtc.log"
53+
}
54+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
{
2+
"serverless_connection": {
3+
"autoclose": 20,
4+
"sender": {
5+
"enabled": true,
6+
"dest_ip": "0.0.0.0",
7+
"dest_port": 8000
8+
},
9+
"receiver": {
10+
"enabled": false
11+
}
12+
},
13+
"bwe_feedback_duration": 200,
14+
"video_source": {
15+
"video_disabled": {
16+
"enabled": false
17+
},
18+
"webcam": {
19+
"enabled": false
20+
},
21+
"video_file": {
22+
"enabled": true,
23+
"height": 240,
24+
"width": 320,
25+
"fps": 10,
26+
"file_path": "testmedia/test.yuv"
27+
}
28+
},
29+
"audio_source": {
30+
"microphone": {
31+
"enabled": false
32+
},
33+
"audio_file": {
34+
"enabled": true,
35+
"file_path": "testmedia/test.wav"
36+
}
37+
},
38+
"save_to_file": {
39+
"enabled": false
40+
},
41+
"logging": {
42+
"enabled": false
43+
}
44+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#!/usr/bin/env python3
2+
# -*- coding: utf-8 -*-
3+
4+
import sys
5+
import os
6+
import subprocess
7+
import traceback
8+
import json
9+
10+
sys.path.append(os.getcwd())
11+
12+
import cmdinfer
13+
14+
15+
def main():
16+
app = subprocess.Popen(
17+
["peerconnection_serverless.origin"] + sys.argv[1:],
18+
bufsize=1,
19+
stdin=subprocess.PIPE,
20+
stdout=subprocess.PIPE,
21+
stderr=subprocess.STDOUT)
22+
try:
23+
cmdinfer.main(app.stdout, app.stdin)
24+
app.wait()
25+
except:
26+
app.terminate()
27+
app.wait()
28+
error_message = traceback.format_exc()
29+
error_message = "\n{}".format(error_message)
30+
sys.stderr.write(error_message)
31+
if len(sys.argv[1:]) == 0:
32+
return
33+
config_file = sys.argv[1]
34+
config_file = json.load(open(config_file, "r"))
35+
if "logging" not in config_file:
36+
return
37+
if "enabled" not in config_file["logging"] or not config_file["logging"]["enabled"]:
38+
return
39+
with open(config_file["logging"]["log_output_path"], "a") as log_file:
40+
log_file.write(error_message)
41+
42+
43+
if __name__ == "__main__":
44+
main()

modules/remote_bitrate_estimator/BUILD.gn

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ rtc_library("remote_bitrate_estimator") {
6262
"../../system_wrappers:metrics",
6363
"//third_party/abseil-cpp/absl/strings",
6464
"//third_party/abseil-cpp/absl/types:optional",
65-
"//modules/third_party/statcollect:stat_collect"
65+
"//modules/third_party/statcollect:stat_collect",
66+
"//modules/third_party/cmdinfer:cmdinfer"
6667
]
6768

6869
if (is_linux) {

0 commit comments

Comments
 (0)