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

Commit 9046a87

Browse files
committed
* Added documentation
Signed-off-by: Christian Berger <christian.berger@gu.se>
1 parent ddd977c commit 9046a87

File tree

2 files changed

+87
-11
lines changed

2 files changed

+87
-11
lines changed

README.md

Lines changed: 78 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,78 @@
1-
# opendlv-video-vpx-encode
2-
OpenDLV Microservice to convert an image in shared memory to a vpx frame
1+
## OpenDLV Microservice to encode images in I420 format into VP8 or VP9 for network broadcast
2+
3+
This repository provides source code to encode images in I420 format that are accessible
4+
via a shared memory area into VP8 or VP9 frames for the OpenDLV software ecosystem.
5+
6+
[![License: GPLv3](https://img.shields.io/badge/license-GPL--3-blue.svg
7+
)](https://www.gnu.org/licenses/gpl-3.0.txt)
8+
9+
10+
## Table of Contents
11+
* [Dependencies](#dependencies)
12+
* [Usage](#usage)
13+
* [Build from sources on the example of Ubuntu 16.04 LTS](#build-from-sources-on-the-example-of-ubuntu-1604-lts)
14+
* [License](#license)
15+
16+
17+
## Dependencies
18+
You need a C++14-compliant compiler to compile this project.
19+
20+
The following dependency is part of the source distribution:
21+
* [libcluon](https://github.com/chrberger/libcluon) - [![License: GPLv3](https://img.shields.io/badge/license-GPL--3-blue.svg
22+
)](https://www.gnu.org/licenses/gpl-3.0.txt)
23+
24+
The following dependencies are downloaded and installed during the Docker-ized build:
25+
* [libvpx 1.7.0](https://github.com/webmproject/libvpx/releases/tag/v1.7.0) - [![License: BSD 3-Clause](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause) - [Google Patent License Conditions](https://raw.githubusercontent.com/webmproject/libvpx/f80be22a1099b2a431c2796f529bb261064ec6b4/PATENTS)
26+
* [libyuv](https://chromium.googlesource.com/libyuv/libyuv/+/master) - [![License: BSD 3-Clause](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause) - [Google Patent License Conditions](https://chromium.googlesource.com/libyuv/libyuv/+/master/PATENTS)
27+
28+
29+
## Usage
30+
To run this microservice using `docker-compose`, you can simply add the following
31+
section to your `docker-compose.yml`:
32+
33+
```yml
34+
version: '2' # Must be present exactly once at the beginning of the docker-compose.yml file
35+
services: # Must be present exactly once at the beginning of the docker-compose.yml file
36+
video-vpx-encoder:
37+
image: chalmersrevere/opendlv-video-vpx-encoder-multi:v0.0.2
38+
restart: on-failure
39+
network_mode: "host"
40+
ipc: "host"
41+
volumes:
42+
- /tmp:/tmp
43+
command: "--cid=111 --name=video0.i420 --width=640 --height=480 --vp8"
44+
```
45+
46+
As this microservice is connecting to another video frame-providing microservice
47+
via a shared memory area using SysV IPC, the `docker-compose.yml` file specifies
48+
the use of `ipc:host`. The parameter `network_mode: "host"` is necessary to
49+
broadcast the resulting frames into an `OD4Session` for OpenDLV. The folder
50+
`/tmp` is shared into the Docker container to attach to the shared memory area.
51+
The parameters to the application are:
52+
53+
* `--cid=111`: Identifier of the OD4Session to broadcast the VP8 or VP9 frames to
54+
* `--id=2`: Optional identifier to set the senderStamp in broadcasted VP8 or VP9 frames in case of multiple instances of this microservice
55+
* `--name=XYZ`: Name of the shared memory area to attach to
56+
* `--width=W`: Width of the image in the shared memory area
57+
* `--height=H`: Height of the image in the shared memory area
58+
* `--bitrate=B`: desired bitrate (default: 800,000)
59+
* `--gop=G`: desired length of group of pictures (default: 10)
60+
* `--vp8`: use VP8 for encoding the frames
61+
* `--vp9`: use VP8 for encoding the frames
62+
63+
64+
## Build from sources on the example of Ubuntu 16.04 LTS
65+
To build this software, you need cmake, C++14 or newer, libyuv, libvpx, and make.
66+
Having these preconditions, just run `cmake` and `make` as follows:
67+
68+
```
69+
mkdir build && cd build
70+
cmake -D CMAKE_BUILD_TYPE=Release ..
71+
make && make test && make install
72+
```
73+
74+
75+
## License
76+
77+
* This project is released under the terms of the GNU GPLv3 License
78+

src/opendlv-video-vpx-encoder.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ int32_t main(int32_t argc, char **argv) {
4040
std::cerr << "Usage: " << argv[0] << " --cid=<OpenDaVINCI session> --name=<name of shared memory area> --width=<width> --height=<height> [--gop=<GOP>] [--bitrate=<bitrate>] [--verbose] [--id=<identifier in case of multiple instances]" << std::endl;
4141
std::cerr << " --vp8: use VP8 encoder" << std::endl;
4242
std::cerr << " --vp9: use VP9 encoder" << std::endl;
43-
std::cerr << " --cid: CID of the OD4Session to send h264 frames" << std::endl;
43+
std::cerr << " --cid: CID of the OD4Session to send VP8 or VP9 frames" << std::endl;
4444
std::cerr << " --id: when using several instances, this identifier is used as senderStamp" << std::endl;
4545
std::cerr << " --name: name of the shared memory area to attach" << std::endl;
4646
std::cerr << " --width: width of the frame" << std::endl;
@@ -67,22 +67,22 @@ int32_t main(int32_t argc, char **argv) {
6767

6868
std::unique_ptr<cluon::SharedMemory> sharedMemory(new cluon::SharedMemory{NAME});
6969
if (sharedMemory && sharedMemory->valid()) {
70-
std::clog << argv[0] << ": Attached to '" << sharedMemory->name() << "' (" << sharedMemory->size() << " bytes)." << std::endl;
70+
std::clog << "[opendlv-video-vpx-encoder]: Attached to '" << sharedMemory->name() << "' (" << sharedMemory->size() << " bytes)." << std::endl;
7171

7272
vpx_codec_iface_t *encoderAlgorithm{(VP8 ? &vpx_codec_vp8_cx_algo : &vpx_codec_vp9_cx_algo)};
7373

7474
vpx_image_t yuvFrame;
7575
memset(&yuvFrame, 0, sizeof(yuvFrame));
7676
if (!vpx_img_alloc(&yuvFrame, VPX_IMG_FMT_I420, WIDTH, HEIGHT, 1)) {
77-
std::cerr << argv[0] << ": Failed to allocate image." << std::endl;
77+
std::cerr << "[opendlv-video-vpx-encoder]: Failed to allocate image." << std::endl;
7878
return retCode;
7979
}
8080

8181
struct vpx_codec_enc_cfg parameters;
8282
memset(&parameters, 0, sizeof(parameters));
8383
vpx_codec_err_t result = vpx_codec_enc_config_default(encoderAlgorithm, &parameters, 0);
8484
if (result) {
85-
std::cerr << argv[0] << ": Failed to get default configuration: " << vpx_codec_err_to_string(result) << std::endl;
85+
std::cerr << "[opendlv-video-vpx-encoder]: Failed to get default configuration: " << vpx_codec_err_to_string(result) << std::endl;
8686
return retCode;
8787
}
8888

@@ -106,11 +106,11 @@ int32_t main(int32_t argc, char **argv) {
106106
memset(&codec, 0, sizeof(codec));
107107
result = vpx_codec_enc_init(&codec, encoderAlgorithm, &parameters, 0);
108108
if (result) {
109-
std::cerr << argv[0] << ": Failed to initialize encoder: " << vpx_codec_err_to_string(result) << std::endl;
109+
std::cerr << "[opendlv-video-vpx-encoder]: Failed to initialize encoder: " << vpx_codec_err_to_string(result) << std::endl;
110110
return retCode;
111111
}
112112
else {
113-
std::clog << argv[0] << ": Using " << vpx_codec_iface_name(encoderAlgorithm) << std::endl;
113+
std::clog << "[opendlv-video-vpx-encoder]: Using " << vpx_codec_iface_name(encoderAlgorithm) << std::endl;
114114
}
115115
vpx_codec_control(&codec, VP8E_SET_CPUUSED, 4);
116116

@@ -149,7 +149,7 @@ int32_t main(int32_t argc, char **argv) {
149149
int flags{ (0 == (frameCounter%GOP)) ? VPX_EFLAG_FORCE_KF : 0 };
150150
result = vpx_codec_encode(&codec, &yuvFrame, frameCounter, 1, flags, VPX_DL_REALTIME);
151151
if (result) {
152-
std::cerr << argv[0] << ": Failed to encode frame: " << vpx_codec_err_to_string(result) << std::endl;
152+
std::cerr << "[opendlv-video-vpx-encoder]: Failed to encode frame: " << vpx_codec_err_to_string(result) << std::endl;
153153
}
154154
if (VERBOSE) {
155155
after = cluon::time::now();
@@ -177,7 +177,7 @@ int32_t main(int32_t argc, char **argv) {
177177
od4.send(ir, sampleTimeStamp, ID);
178178

179179
if (VERBOSE) {
180-
std::clog << argv[0] << ": Frame size = " << totalSize << " bytes; encoding took " << cluon::time::deltaInMicroseconds(after, before) << " microseconds." << std::endl;
180+
std::clog << "[opendlv-video-vpx-encoder]: Frame size = " << totalSize << " bytes; encoding took " << cluon::time::deltaInMicroseconds(after, before) << " microseconds." << std::endl;
181181
}
182182
frameCounter++;
183183
}
@@ -189,7 +189,7 @@ int32_t main(int32_t argc, char **argv) {
189189
retCode = 0;
190190
}
191191
else {
192-
std::cerr << argv[0] << ": Failed to attach to shared memory '" << NAME << "'." << std::endl;
192+
std::cerr << "[opendlv-video-vpx-encoder]: Failed to attach to shared memory '" << NAME << "'." << std::endl;
193193
}
194194
}
195195
return retCode;

0 commit comments

Comments
 (0)