diff --git a/.gitignore b/.gitignore index 9ac76d8fac..452da82fa2 100644 --- a/.gitignore +++ b/.gitignore @@ -77,3 +77,7 @@ target/ src/ .gclient_entries +.gclient_previous_sync_commits +*.log +outaudio* +outvideo* diff --git a/BandwidthEstimator.py b/BandwidthEstimator.py new file mode 100644 index 0000000000..95fdc3b854 --- /dev/null +++ b/BandwidthEstimator.py @@ -0,0 +1,26 @@ + +class Estimator(object): + def __init__(self): + self.cnt = 0 + self.bandwidths = [1e6, 2e6] + + def report_states(self, stats: dict): + ''' + stats is a dict with the following items + { + "send_time_ms": uint, + "arrival_time_ms": uint, + "payload_type": int, + "sequence_number": uint, + "ssrc": int, + "padding_length": uint, + "header_length": uint, + "payload_size": uint + } + ''' + pass + + def get_estimated_bandwidth(self)->int: + bandwidth = self.bandwidths[self.cnt % len(self.bandwidths)] + self.cnt += 1 + return bandwidth diff --git a/Makefile b/Makefile index 70e88127ad..01a80827ca 100644 --- a/Makefile +++ b/Makefile @@ -22,18 +22,13 @@ all: init sync app release init: docker build dockers --build-arg UID=$(shell id -u) --build-arg GUID=$(shell id -g) -f $(build_dockerfile) -t $(compile_docker) -release: - docker build $(target_dir) -f $(release_dockerfile) -t $(release_docker) - sync: docker run $(docker_flags) $(compile_docker) \ make docker-$@ \ output_dir=$(output_dir) \ gn_flags=$(gn_flags) -app: peerconnection_serverless - -peerconnection_serverless: +app: docker run $(docker_flags) $(compile_docker) \ make docker-$@ \ output_dir=$(output_dir) \ @@ -41,6 +36,10 @@ peerconnection_serverless: target_bin_dir=$(target_bin_dir) \ target_pylib_dir=$(target_pylib_dir) +release: + docker build $(target_dir) -f $(release_dockerfile) -t $(release_docker) + + # Docker internal command docker-sync: @@ -49,9 +48,7 @@ docker-sync: rm -rf src gn gen $(output_dir) $(gn_flags) -docker-app: docker-peerconnection_serverless - -docker-peerconnection_serverless: +docker-app: ninja -C $(output_dir) peerconnection_serverless mkdir -p $(target_lib_dir) diff --git a/README.md b/README.md index 9529ed53f7..8acfa6df2a 100644 --- a/README.md +++ b/README.md @@ -35,125 +35,187 @@ -## Motivation +## AlphaRTC -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. +AlphaRTC is an evaluation framework for ML-based bandwidth estimation in real-time communications based on [WebRTC](https://webrtc.googlesource.com/), delivered by the OpenNetLab team. Our mission is to facilitate data-driven, ML-based bandwidth estimation research that learns to improve the quality of experience (QoE) in diverse use cases of real-time communications, e.g. video conferencing. -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). +Users can plug in custom bandwidth estimators with AlphaRTC's interfaces for Python-based and [ONNX](https://github.com/microsoft/onnxruntime)-based model checkpoints. By using the interfaces, the trained model checkpoint is used for bandwidth estimation instead of [GCC](https://dl.acm.org/doi/abs/10.1145/2910017.2910605)(Google Congestion Control), a default bandwidth estimation module of WebRTC. -## Environment -**We recommend you directly fetch the pre-provided Docker images from `opennetlab.azurecr.io/alphartc` or [Github release](https://github.com/OpenNetLab/AlphaRTC/releases/latest/download/alphartc.tar.gz)** +## Installation -### From docker registry -``` bash -docker pull opennetlab.azurecr.io/alphartc -docker image tag opennetlab.azurecr.io/alphartc alphartc -``` -### From github release -``` bash -wget https://github.com/OpenNetLab/AlphaRTC/releases/latest/download/alphartc.tar.gz -docker load -i alphartc.tar.gz +``` shell +# Install depot tools +git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git +export DEPOT_TOOLS_HOME=/path/to/depot_tools +# NOTE: DEPOT_TOOLS_HOME should be located at the front of the PATH +export PATH=:$DEPOT_TOOLS_HOME:$PATH + +# Fetch chromium +git config --global core.autocrlf false +git config --global core.filemode false +cd $DEPOT_TOOLS_HOME/src && sudo ./build/install-build-deps.sh + +# Get the AlphaRTC code +git clone https://github.com/OpenNetLab/AlphaRTC.git +export ALPHARTC_HOME=/path/to/AlphaRTC +export PATH=:$PATH:$ALPHARTC_HOME +export ONNX_HOME=$ALPHARTC_HOME/modules/third_party/onnxinfer +export LD_LIBRARY_PATH=$ONNX_HOME/lib:$LD_LIBRARY_PATH ``` -Ubuntu 18.04 or 20.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. - ## Compilation -### Option 1: Docker (recommended) +``` shell +# Compile AlphaRTC and peerconnection_serverless, +# the video call app that uses the custom bandwidth estimator +./onl-build.sh + +# Compile AlphaRTC and peerconnection_serverless_gcc, +# the video call app that uses GCC, the default bandwidth estimator of WebRTC +git checkout gcc +./gcc-build.sh +``` -To compile AlphaRTC, please refer to the following steps +## Evaluation -1. Prerequisites +- Evaluate the bandwidth estimation by running end-to-end video call app, `peerconnection_serverless`. It makes quick and easy testing of the bandwidth estimator, as it establishes RTC communication with a peer without the need of a signaling server. +- In case of running an app with GCC, use `peerconnection_serverless_gcc` instead of `peerconnection_serverless` following the [compilation guideline](#compilation) +- Results will be saved as `receiver-*.log` and `sender-*.log`. - Make sure Docker is installed on your system and add user to docker group. +``` shell +## Running a call with custom bandwidth estimator: +# Receiver side (Note: receiver should be running first) +python peerconnection_serverless.py receiver_360p.json +# Sender side +python peerconnection_serverless.py sender_360p.json + +## Running a call with GCC: +# Receiver side (Note: receiver should be running first) +./peerconnection_serverless_gcc receiver_360p.json +# Sender side +./peerconnection_serverless_gcc sender_360p.json +``` - ``` shell - # Install Docker - curl -fsSL get.docker.com -o get-docker.sh - sudo sh get-docker.sh - sudo usermod -aG docker ${USER} - ``` +- Check the call quality with receiver- and sender-side QoE statistics in the logs. Below are example statistics from `receiver-360p.log` and `sender-360p.log` when running a video call app with 360p video at fps=25: -2. Clone the code +``` shell +# Example receiver-side statistics +WebRTC.Video.ReceivedWidthInPixels 575 +WebRTC.Video.ReceivedHeightInPixels 323 +WebRTC.Video.MediaBitrateReceivedInKbps 1350 +WebRTC.Video.HarmonicFrameRate 24 + +# Example sender-side statistics +WebRTC.Video.SentWidthInPixels 584 +WebRTC.Video.SentHeightInPixels 329 +WebRTC.Video.MediaBitrateSentInBps periodic_samples:14, {min:434864, avg:1301272, max:1535160} +WebRTC.Video.SentFramesPerSecond periodic_samples:14, {min:25, avg:25, max:26} +``` - ``` shell - git clone https://github.com/OpenNetLab/AlphaRTC.git - ``` +## Using Docker -3. Build Docker images +### Getting the docker image - ``` shell - cd AlphaRTC - make all - ``` +- We recommend you directly fetch the pre-provided Docker images from `opennetlab.azurecr.io/alphartc` or [Github release](https://github.com/OpenNetLab/AlphaRTC/releases/latest/download/alphartc.tar.gz) +- Supported distros: Ubuntu 18.04 or 20.04 - You should then be able to see two Docker images, `alphartc` and `alphartc-compile` using `sudo docker images` -### Option 2: Compile from Scratch -If you don't want to use Docker, or have other reasons to compile from scratch (e.g., you want a native Windows build), you may use this method. +``` shell +# From docker registry: +docker pull opennetlab.azurecr.io/alphartc +docker image tag opennetlab.azurecr.io/alphartc alphartc -Note: all commands below work for both Linux (sh) and Windows (pwsh), unless otherwise specified +# From github release: +wget https://github.com/OpenNetLab/AlphaRTC/releases/latest/download/alphartc.tar.gz +docker load -i alphartc.tar.gz +``` -1. Grab essential tools +### Compilation - You may follow the guide [here](https://commondatastorage.googleapis.com/chrome-infra-docs/flat/depot_tools/docs/html/depot_tools_tutorial.html#_setting_up) to obtain a copy of `depot_tools` +``` shell +# Install Docker +curl -fsSL get.docker.com -o get-docker.sh +sudo sh get-docker.sh +sudo usermod -aG docker ${USER} -2. Clone the repo +# Get the AlphaRTC code +git clone https://github.com/OpenNetLab/AlphaRTC.git - ```shell - git clone https://github.com/OpenNetLab/AlphaRTC.git - ``` +# Build Docker images +cd AlphaRTC +make all -3. Sync the dependencies - ```shell - cd AlphaRTC - gclient sync - mv src/* . - ``` +# Should show `alphartc` and `alphartc-compile` +docker images +``` -4. Generate build rules +### Evaluation - _Windows users_: Please use __x64 Native Tools Command Prompt for VS2017__. The clang version comes with the project is 9.0.0, hence incompatible with VS2019. In addition, environmental variable `DEPOT_TOOLS_WIN_TOOLSCHAIN` has to be set to `0` and `GYP_MSVS_VERSION` has to be set to `2017`. - - ```shell - gn gen out/Default - ``` +- Since the `peerconnection_serverless` needs two peers, one sender and another receiver, spawn two instances (a receiver and a sender) in the same network and make them talk to each other. For more information on Docker networking, check [Docker Networking](https://docs.docker.com/network/network-tutorial-standalone/) -5. Compile - ```shell - ninja -C out/Default peerconnection_serverless - ``` - For Windows users, we also provide a GUI version. You may compile it via - ```shell - ninja -C out/Default peerconnection_serverless_win_gui - ``` - -## Demo +``` shell +sudo docker run -v config_files:/app/config_files alphartc peerconnection_serverless /app/config_files/config.json +``` -AlphaRTC consists of many different components. `peerconnection_serverless` is an application for demo purposes that comes with AlphaRTC. It establishes RTC communication with another peer without the need of a server. +### Using PyInfer and ONNXInfer -In order to run the application, you will need a configuration file in json format. The details are explained in the next chapter. +- **PyInfer**: Implement a Python `Estimator` class with required methods `report_states` and `get_estimated_bandwidth` in `BandwidthEstimator.py` and put this file in your workspace. +- Below is a sample skeleton `BandwidthEstimator.py` with 1Mbps fixed estimated bandwidth. -In addition to the config file, you will also need other files, such as video/audio source files and an ONNX model. +```python +class Estimator(object): + def report_states(self, stats: dict): + ''' + stats is a dict with the following items + { + "send_time_ms": uint, + "arrival_time_ms": uint, + "payload_type": int, + "sequence_number": uint, + "ssrc": int, + "padding_length": uint, + "header_length": uint, + "payload_size": uint + } + ''' + pass -To run an AlphaRTC instance, put the config files in a directory, e.g., `config_files`, then mount it to an endpoint inside `alphartc` container + def get_estimated_bandwidth(self)->int: + return int(1e6) # 1Mbps -``` shell -sudo docker run -v config_files:/app/config_files alphartc peerconnection_serverless /app/config_files/config.json ``` -Since `peerconnection_serverless` needs two peers, you may spawn two instances (a receiver and a sender) in the same network and make them talk to each other. For more information on Docker networking, check [Docker Networking](https://docs.docker.com/network/network-tutorial-standalone/) +- **ONNXInfer**: Specify the path of onnx model in the config file. Here is an example receiver-side configuration [receiver.json](examples/peerconnection/serverless/corpus/receiver.json) + + +### Evaluation +- Dockerized environment + + 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`. -### Configurations for *peerconnection_serverless* + + PyInfer: + ```shell + sudo docker run -d --rm -v `pwd`/examples/peerconnection/serverless/corpus:/app -w /app --name alphartc alphartc peerconnection_serverless receiver_pyinfer.json + sudo docker exec alphartc peerconnection_serverless sender_pyinfer.json + ``` + + ONNXInfer: + ``` shell + sudo docker run -d --rm -v `pwd`/examples/peerconnection/serverless/corpus:/app -w /app --name alphartc alphartc peerconnection_serverless receiver.json + sudo docker exec alphartc peerconnection_serverless sender.json + ``` + +## Receiver- and Sender-side Configurations This section describes required fields for the json configuration file. - **serverless_connection** - **sender** - **enabled**: If set to `true`, the client will act as sender and automatically connect to receiver when launched - - **send_to_ip**: The IP of serverless peerconnection receiver + - **send_to_ip**: The IP of serverless peerconnection receiver - **send_to_port**: The port of serverless peerconnection receiver - **receiver** - **enabled**: If set to `true`, the client will act as receiver and wait for sender to connect. @@ -199,109 +261,7 @@ This section describes required fields for the json configuration file. - **fps**: Frames per second of the output video file - **file_path**: The file path of the output video file in YUV format -#### Use PyInfer or ONNXInfer - -##### PyInfer - -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. -There is an example of Estimator with fixed estimated bandwidth 1Mbps. Here is an example [BandwidthEstimator.py](examples/peerconnection/serverless/corpus/BandwidthEstimator.py). - -```python -class Estimator(object): - def report_states(self, stats: dict): - ''' - stats is a dict with the following items - { - "send_time_ms": uint, - "arrival_time_ms": uint, - "payload_type": int, - "sequence_number": uint, - "ssrc": int, - "padding_length": uint, - "header_length": uint, - "payload_size": uint - } - ''' - pass - - def get_estimated_bandwidth(self)->int: - return int(1e6) # 1Mbps - -``` - -##### ONNXInfer - -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) - -- **onnx** - - **onnx_model_path**: The path of the [onnx](https://www.onnxruntime.ai/) model - - -#### Run peerconnection_serverless -- Dockerized environment - - 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`. - - - PyInfer: - ```shell - sudo docker run -d --rm -v `pwd`/examples/peerconnection/serverless/corpus:/app -w /app --name alphartc alphartc peerconnection_serverless receiver_pyinfer.json - sudo docker exec alphartc peerconnection_serverless sender_pyinfer.json - ``` - - ONNXInfer: - ``` shell - sudo docker run -d --rm -v `pwd`/examples/peerconnection/serverless/corpus:/app -w /app --name alphartc alphartc peerconnection_serverless receiver.json - sudo docker exec alphartc peerconnection_serverless sender.json - ``` - -- Bare metal - - If you compiled your own binary, you can also run it on your bare-metal machine. - - - Linux users: - 1. Copy the provided corpus to a new directory - - ```shell - cp -r examples/peerconnection/serverless/corpus/* /path/to/your/runtime - ``` - 2. Copy the essential dynanmic libraries and add them to searching directory - - ```shell - cp modules/third_party/onnxinfer/lib/*.so /path/to/your/dll - export LD_LIBRARY_PATH=/path/to/your/dll:$LD_LIBRARY_PATH - ``` - 3. Start the receiver and the sender - - ```shell - cd /path/to/your/runtime - /path/to/alphartc/out/Default/peerconnection ./receiver.json - /path/to/alphartc/out/Default/peerconnection ./sender.json - ``` - - Windows users: - 1. Copy the provided corpus to a new directory - - ```shell - cp -Recursive examples/peerconnection/serverless/corpus/* /path/to/your/runtime - ``` - 2. Copy the essential dynanmic libraries and add them to searching directory - - ```shell - cp modules/third_party/onnxinfer/bin/*.dll /path/to/your/dll - set PATH=/path/to/your/dll;%PATH% - ``` - 3. Start the receiver and the sender - - ```shell - cd /path/to/your/runtime - /path/to/alphartc/out/Default/peerconnection ./receiver.json - /path/to/alphartc/out/Default/peerconnection ./sender.json - ``` - -## Who Are We - -The OpenNetLab is an open-networking research community. Our members are from Microsoft Research Asia, Tsinghua Univeristy, Peking University, Nanjing University, KAIST, Seoul National University, National University of Singapore, SUSTech, Shanghai Jiaotong Univerisity. -## WebRTC +## OpenNetLab Team -You can find the Readme of the original WebRTC project [here](./README.webrtc.md) +The OpenNetLab is an open-networking research community. Our members are from Microsoft Research Asia, Tsinghua Univeristy, Peking University, Nanjing University, KAIST, Seoul National University, National University of Singapore, SUSTech, Shanghai Jiaotong Univerisity. \ No newline at end of file diff --git a/call/bitrate_allocator.cc b/call/bitrate_allocator.cc index 8e2006defa..7badb78c6e 100644 --- a/call/bitrate_allocator.cc +++ b/call/bitrate_allocator.cc @@ -40,7 +40,7 @@ const int kDefaultBitrateBps = 300000; const double kToggleFactor = 0.1; const uint32_t kMinToggleBitrateBps = 20000; -const int64_t kBweLogIntervalMs = 5000; +const int64_t kBweLogIntervalMs = 500; double MediaRatio(uint32_t allocated_bitrate, uint32_t protection_bitrate) { RTC_DCHECK_GT(allocated_bitrate, 0); @@ -391,7 +391,7 @@ void BitrateAllocator::OnNetworkEstimateChanged(TargetTransferRate msg) { // Periodically log the incoming BWE. int64_t now = msg.at_time.ms(); if (now > last_bwe_log_time_ + kBweLogIntervalMs) { - RTC_LOG(LS_INFO) << "Current BWE " << last_target_bps_; + RTC_LOG(LS_INFO) << "AlphaRTC: Current BWE " << last_target_bps_; last_bwe_log_time_ = now; } diff --git a/cmdinfer.py b/cmdinfer.py new file mode 100755 index 0000000000..6779e1e78d --- /dev/null +++ b/cmdinfer.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import sys +import json +import glob + + +RequestBandwidthCommand = "RequestBandwidth" + + +def fetch_stats(line: str)->dict: + line = line.strip() + try: + stats = json.loads(line) + return stats + except json.decoder.JSONDecodeError: + return None + + +def request_estimated_bandwidth(line: str)->bool: + line = line.strip() + if RequestBandwidthCommand == line: + return True + return False + + +def find_estimator_class(): + import BandwidthEstimator + return BandwidthEstimator.Estimator + + +def main(ifd = sys.stdin, ofd = sys.stdout): + estimator_class = find_estimator_class() + estimator = estimator_class() + while True: + line = ifd.readline() + if not line: + break + if isinstance(line, bytes): + line = line.decode("utf-8") + stats = fetch_stats(line) + if stats: + estimator.report_states(stats) + continue + request = request_estimated_bandwidth(line) + if request: + bandwidth = estimator.get_estimated_bandwidth() + ofd.write("{}\n".format(int(bandwidth)).encode("utf-8")) + ofd.flush() + continue + sys.stdout.write(line) + sys.stdout.flush() + + +if __name__ == '__main__': + main() diff --git a/dockers/Dockerfile.compile b/dockers/Dockerfile.compile index d48089f82b..4c8000e1dc 100644 --- a/dockers/Dockerfile.compile +++ b/dockers/Dockerfile.compile @@ -22,3 +22,4 @@ ENV PATH="${DEPOT_TOOLS}/:${PATH}" WORKDIR "${DOCKER_WORKDIR}/" USER ${USER} + diff --git a/modules/congestion_controller/alpha_cc/alpha_cc_network_control.cc b/modules/congestion_controller/alpha_cc/alpha_cc_network_control.cc index 3754e87495..fbb78e9353 100644 --- a/modules/congestion_controller/alpha_cc/alpha_cc_network_control.cc +++ b/modules/congestion_controller/alpha_cc/alpha_cc_network_control.cc @@ -58,6 +58,7 @@ GoogCcNetworkController::GoogCcNetworkController(NetworkControllerConfig config, ParseFieldTrial( {&safe_reset_on_route_change_, &safe_reset_acknowledged_rate_}, key_value_config_->Lookup("WebRTC-Bwe-SafeResetOnRouteChange")); + RTC_LOG(LS_INFO) << "Using AlphaRTC"; } GoogCcNetworkController::~GoogCcNetworkController() {} @@ -176,7 +177,7 @@ NetworkControlUpdate GoogCcNetworkController::OnReceiveBwe(BweMessage bwe) { update.target_rate->target_rate = bandwidth; //*-----Set pacing & padding_rate-----*// - int32_t default_pacing_rate = static_cast(bwe.pacing_rate); + int32_t default_pacing_rate = static_cast(bwe.pacing_rate); int32_t default_padding_rate = 0; // default: 0bps = 0kbps DataRate pacing_rate = DataRate::BitsPerSec(default_pacing_rate * pacing_factor_); DataRate padding_rate = DataRate::BitsPerSec(default_padding_rate); diff --git a/modules/remote_bitrate_estimator/remote_estimator_proxy.cc b/modules/remote_bitrate_estimator/remote_estimator_proxy.cc index 6955963467..26b92b7604 100644 --- a/modules/remote_bitrate_estimator/remote_estimator_proxy.cc +++ b/modules/remote_bitrate_estimator/remote_estimator_proxy.cc @@ -125,30 +125,6 @@ void RemoteEstimatorProxy::IncomingPacket(int64_t arrival_time_ms, bwe.timestamp_ms = clock_->TimeInMilliseconds(); SendbackBweEstimation(bwe); } - - // Save per-packet info locally on receiving - // ---------- Collect packet-related info into a local file ---------- - double pacing_rate = - time_to_send_bew_message ? estimation : SC_PACER_PACING_RATE_EMPTY; - double padding_rate = - time_to_send_bew_message ? estimation : SC_PACER_PADDING_RATE_EMPTY; - - // Save per-packet info locally on receiving - auto res = stats_collect_.StatsCollect( - pacing_rate, padding_rate, header.payloadType, - header.sequenceNumber, send_time_ms, header.ssrc, - header.paddingLength, header.headerLength, - arrival_time_ms, payload_size, 0); - if (res != StatCollect::SCResult::SC_SUCCESS) - { - RTC_LOG(LS_ERROR) << "Collect data failed"; - } - std::string out_data = stats_collect_.DumpData(); - if (out_data.empty()) - { - RTC_LOG(LS_ERROR) << "Save data failed"; - } - RTC_LOG(LS_INFO) << out_data; } bool RemoteEstimatorProxy::LatestEstimate(std::vector* ssrcs, diff --git a/onl-build.sh b/onl-build.sh new file mode 100755 index 0000000000..58779e9720 --- /dev/null +++ b/onl-build.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +if [ ! -d "out" ] +then + mkdir -p out/Default +fi + + +# Build AlphaRTC. +gn gen out/Default --args='is_debug=false' + +# Build AlphaRTC e2e app (peerconnection_serverless). +# (check ninja project files for peerconnection_serverless executable under ./examples/BUILD.gn) +ninja -C out/Default peerconnection_serverless +cp out/Default/peerconnection_serverless peerconnection_serverless \ No newline at end of file diff --git a/onnx-model.onnx b/onnx-model.onnx new file mode 100644 index 0000000000..49f5101c27 Binary files /dev/null and b/onnx-model.onnx differ diff --git a/peerconnection_serverless b/peerconnection_serverless new file mode 100755 index 0000000000..05916d2f16 Binary files /dev/null and b/peerconnection_serverless differ diff --git a/peerconnection_serverless.py b/peerconnection_serverless.py new file mode 100755 index 0000000000..9df33a139d --- /dev/null +++ b/peerconnection_serverless.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import sys +import os +import subprocess +import traceback +import json + +sys.path.append(os.getcwd()) + +import cmdinfer + + +def main(): + app = subprocess.Popen( + ["peerconnection_serverless"] + sys.argv[1:], + bufsize=1, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + try: + cmdinfer.main(app.stdout, app.stdin) + app.wait() + except: + app.terminate() + app.wait() + error_message = traceback.format_exc() + error_message = "\n{}".format(error_message) + sys.stderr.write(error_message) + if len(sys.argv[1:]) == 0: + return + config_file = sys.argv[1] + config_file = json.load(open(config_file, "r")) + if "logging" not in config_file: + return + if "enabled" not in config_file["logging"] or not config_file["logging"]["enabled"]: + return + with open(config_file["logging"]["log_output_path"], "a") as log_file: + log_file.write(error_message) + + +if __name__ == "__main__": + main() diff --git a/receiver_360p.json b/receiver_360p.json new file mode 100644 index 0000000000..5d2812e1ed --- /dev/null +++ b/receiver_360p.json @@ -0,0 +1,50 @@ +{ + "serverless_connection": { + "autoclose": 30, + "sender": { + "enabled": false + }, + "receiver": { + "enabled": true, + "listening_ip": "0.0.0.0", + "listening_port": 8000 + } + }, + "bwe_feedback_duration": 200, + "video_source": { + "video_disabled": { + "enabled": true + }, + "webcam": { + "enabled": false + }, + "video_file": { + "enabled": false + } + }, + "audio_source": { + "microphone": { + "enabled": false + }, + "audio_file": { + "enabled": true, + "file_path": "testmedia/test.wav" + } + }, + "save_to_file": { + "enabled": true, + "audio": { + "file_path": "outaudio.wav" + }, + "video": { + "width": 640, + "height": 360, + "fps": 25, + "file_path": "outvideo-360p.yuv" + } + }, + "logging": { + "enabled": true, + "log_output_path": "receiver-360p.log" + } +} diff --git a/receiver_720p.json b/receiver_720p.json new file mode 100644 index 0000000000..f2f624cc42 --- /dev/null +++ b/receiver_720p.json @@ -0,0 +1,50 @@ +{ + "serverless_connection": { + "autoclose": 30, + "sender": { + "enabled": false + }, + "receiver": { + "enabled": true, + "listening_ip": "0.0.0.0", + "listening_port": 8000 + } + }, + "bwe_feedback_duration": 200, + "video_source": { + "video_disabled": { + "enabled": true + }, + "webcam": { + "enabled": false + }, + "video_file": { + "enabled": false + } + }, + "audio_source": { + "microphone": { + "enabled": false + }, + "audio_file": { + "enabled": true, + "file_path": "testmedia/test.wav" + } + }, + "save_to_file": { + "enabled": true, + "audio": { + "file_path": "outaudio.wav" + }, + "video": { + "width": 1280, + "height": 720, + "fps": 25, + "file_path": "outvideo-720p.yuv" + } + }, + "logging": { + "enabled": true, + "log_output_path": "receiver-720p.log" + } +} diff --git a/sender_360p.json b/sender_360p.json new file mode 100644 index 0000000000..b9a338abae --- /dev/null +++ b/sender_360p.json @@ -0,0 +1,45 @@ +{ + "serverless_connection": { + "autoclose": 30, + "sender": { + "enabled": true, + "dest_ip": "0.0.0.0", + "dest_port": 8000 + }, + "receiver": { + "enabled": false + } + }, + "bwe_feedback_duration": 200, + "video_source": { + "video_disabled": { + "enabled": false + }, + "webcam": { + "enabled": false + }, + "video_file": { + "enabled": true, + "width": 640, + "height": 360, + "fps": 25, + "file_path": "testmedia/test-360p.yuv" + } + }, + "audio_source": { + "microphone": { + "enabled": false + }, + "audio_file": { + "enabled": true, + "file_path": "testmedia/test.wav" + } + }, + "save_to_file": { + "enabled": false + }, + "logging": { + "enabled": true, + "log_output_path": "sender-360p.log" + } +} diff --git a/sender_720p.json b/sender_720p.json new file mode 100644 index 0000000000..44aa935671 --- /dev/null +++ b/sender_720p.json @@ -0,0 +1,45 @@ +{ + "serverless_connection": { + "autoclose": 30, + "sender": { + "enabled": true, + "dest_ip": "0.0.0.0", + "dest_port": 8000 + }, + "receiver": { + "enabled": false + } + }, + "bwe_feedback_duration": 200, + "video_source": { + "video_disabled": { + "enabled": false + }, + "webcam": { + "enabled": false + }, + "video_file": { + "enabled": true, + "width": 1280, + "height": 720, + "fps": 25, + "file_path": "testmedia/test-720p.yuv" + } + }, + "audio_source": { + "microphone": { + "enabled": false + }, + "audio_file": { + "enabled": true, + "file_path": "testmedia/test.wav" + } + }, + "save_to_file": { + "enabled": false + }, + "logging": { + "enabled": true, + "log_output_path": "sender-720p.log" + } +} diff --git a/testmedia/test-360p.yuv b/testmedia/test-360p.yuv new file mode 100644 index 0000000000..4587f35132 Binary files /dev/null and b/testmedia/test-360p.yuv differ diff --git a/testmedia/test-720p.yuv b/testmedia/test-720p.yuv new file mode 100644 index 0000000000..8d0cd436be Binary files /dev/null and b/testmedia/test-720p.yuv differ diff --git a/testmedia/test.wav b/testmedia/test.wav new file mode 100644 index 0000000000..04ff11d0d8 Binary files /dev/null and b/testmedia/test.wav differ