Skip to content

Commit 0fe2349

Browse files
authored
Merge pull request #20 from AMWA-TV/feature-gstreamer-plugins
Feature gstreamer plugins
2 parents 2e7b06e + a386723 commit 0fe2349

File tree

22 files changed

+2563
-30
lines changed

22 files changed

+2563
-30
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,3 +127,9 @@ Open `cpp/demos/ossrf-nmos-api/config/nmos_config.json` and adjust the following
127127
## Build Container and Code simultaneously
128128

129129
./scripts/build-inside-container.sh
130+
131+
## GStreamer Plugins
132+
133+
We have also developed GStreamer plugins (nmossender, nmosvideoreceiver, and nmosaudioreceiver) that integrate NMOS registration and control with the sending and receiving of raw ST2110 audio/video streams.
134+
135+
For detailed instructions on building, installing, and using these plugins (including examples of gst-launch-1.0 pipelines), please see the [Plugins Guide](/cpp/libs/gst_nmos_plugins/).
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"node": {
3+
"id": "8968180c-0418-4422-bea1-f0c642389637",
4+
"configuration": {
5+
"label": "BISECT OSSRF Node Receiver",
6+
"description": "BISECT OSSRF node receiver",
7+
"host_addresses": [
8+
"192.168.1.1"
9+
],
10+
"interfaces": [
11+
{
12+
"chassis_id": "c9-94-02-f7-3e-eb",
13+
"name": "wlp1s0",
14+
"port_id": "00-e0-4c-68-01-8d"
15+
}
16+
],
17+
"clocks": [
18+
{
19+
"name": "clk0",
20+
"ref_type": "ptp",
21+
"traceable": false,
22+
"version": "IEEE1588-2008",
23+
"gmid": "00-20-fc-ff-fe-35-9c-26",
24+
"locked": true
25+
}
26+
],
27+
"registry_address": "192.168.1.1",
28+
"registry_version": "v1.3",
29+
"registration_port": 8010,
30+
"system_address": "192.168.1.1",
31+
"system_version": "v1.0",
32+
"system_port": 8010,
33+
"http_port": 5114
34+
}
35+
}
36+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"node": {
3+
"id": "d5504cd1-fe68-489d-99d4-20d3f075f062",
4+
"configuration": {
5+
"label": "BISECT OSSRF Node Sender",
6+
"description": "BISECT OSSRF node sender",
7+
"host_addresses": [
8+
"192.168.1.1"
9+
],
10+
"interfaces": [
11+
{
12+
"chassis_id": "c8-94-02-f7-3e-eb",
13+
"name": "wlp1s0",
14+
"port_id": "01-e0-4c-68-01-8d"
15+
}
16+
],
17+
"clocks": [
18+
{
19+
"name": "clk0",
20+
"ref_type": "ptp",
21+
"traceable": false,
22+
"version": "IEEE1588-2008",
23+
"gmid": "00-20-fc-ff-fe-35-9c-25",
24+
"locked": true
25+
}
26+
],
27+
"registry_address": "192.168.1.1",
28+
"registry_version": "v1.3",
29+
"registration_port": 8010,
30+
"system_address": "192.168.1.1",
31+
"system_version": "v1.0",
32+
"system_port": 8010,
33+
"http_port": 6114
34+
}
35+
}
36+
}

cpp/demos/ossrf-nmos-api/main.cpp

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -61,43 +61,45 @@ namespace
6161
{
6262
if(i == 1)
6363
{
64-
auto receiver_activation_callback = [r = (*it).dump(), &gst_receiver_uptr](
65-
const std::optional<std::string>& sdp, bool master_enable) {
66-
if(sdp.has_value())
67-
{
68-
fmt::print("nmos_receiver_callback: {} {}\n", master_enable, sdp.value());
69-
auto plugin = ossrf::gst::plugins::create_gst_receiver_plugin(r, sdp.value());
70-
if(plugin.has_value())
64+
auto receiver_activation_callback =
65+
[r = (*it).dump(), &gst_receiver_uptr](const std::optional<std::string>& sdp,
66+
bool master_enable, const nlohmann::json&) {
67+
if(sdp.has_value())
7168
{
72-
gst_receiver_uptr.reset(plugin.value().release());
69+
fmt::print("nmos_receiver_callback: {} {}\n", master_enable, sdp.value());
70+
auto plugin = ossrf::gst::plugins::create_gst_receiver_plugin(r, sdp.value());
71+
if(plugin.has_value())
72+
{
73+
gst_receiver_uptr.reset(plugin.value().release());
74+
return;
75+
}
76+
fmt::print("failed creating receiver\n");
7377
return;
7478
}
75-
fmt::print("failed creating receiver\n");
76-
return;
77-
}
78-
fmt::print("nmos_receiver_callback: {} no sdp\n", master_enable);
79-
};
79+
fmt::print("nmos_receiver_callback: {} no sdp\n", master_enable);
80+
};
8081
BST_CHECK(nmos_client->add_receiver(device_id, (*it).dump(), receiver_activation_callback));
8182
receiver_info_config = (*it).dump();
8283
}
8384
else if(i == 2)
8485
{
85-
auto receiver_activation_callback = [r = (*it).dump(), &gst_receiver_uptr_2](
86-
const std::optional<std::string>& sdp, bool master_enable) {
87-
if(sdp.has_value())
88-
{
89-
fmt::print("nmos_receiver_callback: {} {}\n", master_enable, sdp.value());
90-
auto plugin = ossrf::gst::plugins::create_gst_receiver_plugin(r, sdp.value());
91-
if(plugin.has_value())
86+
auto receiver_activation_callback =
87+
[r = (*it).dump(), &gst_receiver_uptr_2](const std::optional<std::string>& sdp,
88+
bool master_enable, const nlohmann::json&) {
89+
if(sdp.has_value())
9290
{
93-
gst_receiver_uptr_2.reset(plugin.value().release());
91+
fmt::print("nmos_receiver_callback: {} {}\n", master_enable, sdp.value());
92+
auto plugin = ossrf::gst::plugins::create_gst_receiver_plugin(r, sdp.value());
93+
if(plugin.has_value())
94+
{
95+
gst_receiver_uptr_2.reset(plugin.value().release());
96+
return;
97+
}
98+
fmt::print("failed creating receiver\n");
9499
return;
95100
}
96-
fmt::print("failed creating receiver\n");
97-
return;
98-
}
99-
fmt::print("nmos_receiver_callback: {} no sdp\n", master_enable);
100-
};
101+
fmt::print("nmos_receiver_callback: {} no sdp\n", master_enable);
102+
};
101103
BST_CHECK(nmos_client->add_receiver(device_id, (*it).dump(), receiver_activation_callback));
102104
}
103105
i++;

cpp/libs/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ add_subdirectory(bisect_expected)
22
add_subdirectory(bisect_nmoscpp)
33
add_subdirectory(bisect_sdp)
44
add_subdirectory(bisect_gst)
5+
add_subdirectory(gst_nmos_plugins)
56
add_subdirectory(ossrf_nmos_api)
67
add_subdirectory(ossrf_gstreamer_api)
78
add_subdirectory(bisect_json)

cpp/libs/bisect_nmoscpp/lib/include/bisect/nmoscpp/configuration.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ namespace bisect::nmoscpp
107107
nmos::rational exact_framerate;
108108
std::string chroma_sub_sampling;
109109
nmos::interlace_mode structure;
110+
int depth = 0;
110111
};
111112

112113
struct audio_sender_info_t
@@ -156,5 +157,5 @@ namespace bisect::nmoscpp
156157
std::function<void(bool master_enable, const nlohmann::json& transport_params)>;
157158

158159
using receiver_activation_callback_t =
159-
std::function<void(const std::optional<std::string>& sdp, const bool master_enable)>;
160+
std::function<void(const std::optional<std::string>& sdp, const bool master_enable, const nlohmann::json& transport_params)>;
160161
} // namespace bisect::nmoscpp

cpp/libs/bisect_sdp/lib/src/reader.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ namespace
145145
.exact_framerate = nmos::rational(params.exactframerate.numerator(), params.exactframerate.denominator()),
146146
.chroma_sub_sampling = "YCbCr-4:2:2",
147147
.structure = params.interlace ? nmos::interlace_modes::interlaced_tff : nmos::interlace_modes::progressive,
148+
.depth = static_cast<int>(params.depth),
148149
};
149150
}
150151
} // namespace
@@ -196,4 +197,4 @@ expected<sdp_settings_t> bisect::sdp::parse_sdp(const std::string& sdp)
196197
{
197198
BST_FAIL("error parsing SDP: {}", ex.what());
198199
}
199-
}
200+
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
cmake_minimum_required(VERSION 3.16)
2+
project(gst_nmos_plugins LANGUAGES CXX)
3+
4+
find_package(nlohmann_json REQUIRED)
5+
find_package(PkgConfig REQUIRED)
6+
7+
# Locate GLib package
8+
pkg_check_modules(GLIB REQUIRED glib-2.0)
9+
10+
# Locate GStreamer packages
11+
pkg_search_module(GSTREAMER REQUIRED gstreamer-1.0>=1.4)
12+
pkg_search_module(GSTREAMER_APP REQUIRED gstreamer-app-1.0>=1.4)
13+
pkg_search_module(GSTREAMER_AUDIO REQUIRED gstreamer-audio-1.0>=1.4)
14+
pkg_search_module(GSTREAMER_VIDEO REQUIRED gstreamer-video-1.0>=1.4)
15+
16+
# Include the parent directory of gst_nmos_plugins
17+
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..)
18+
19+
# Utils library (shared across plugins)
20+
add_library(utils STATIC src/utils.cpp)
21+
22+
# Enable -fPIC for utils
23+
set_target_properties(utils PROPERTIES POSITION_INDEPENDENT_CODE ON)
24+
25+
target_include_directories(utils
26+
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/..
27+
PRIVATE ${GLIB_INCLUDE_DIRS}
28+
PRIVATE ${GSTREAMER_INCLUDE_DIRS}
29+
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../bisect
30+
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../ossrf
31+
)
32+
target_link_libraries(utils
33+
PUBLIC nlohmann_json::nlohmann_json
34+
PRIVATE ${GLIB_LIBRARIES}
35+
PRIVATE ${GSTREAMER_LIBRARIES}
36+
PRIVATE ${GSTREAMER_APP_LIBRARIES}
37+
PRIVATE ${GSTREAMER_AUDIO_LIBRARIES}
38+
PRIVATE ${GSTREAMER_VIDEO_LIBRARIES}
39+
PRIVATE bisect::project_warnings
40+
PRIVATE bisect::expected
41+
PRIVATE bisect::bisect_nmoscpp
42+
PRIVATE bisect::bisect_json
43+
PRIVATE ossrf::ossrf_nmos_api
44+
)
45+
46+
# Function to create a plugin target
47+
function(create_plugin plugin_name plugin_sources output_name)
48+
add_library(${plugin_name} MODULE ${plugin_sources})
49+
target_include_directories(${plugin_name}
50+
PRIVATE ${GSTREAMER_INCLUDE_DIRS}
51+
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/..
52+
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
53+
)
54+
target_link_libraries(${plugin_name}
55+
PRIVATE
56+
${GSTREAMER_LIBRARIES}
57+
${GSTREAMER_APP_LIBRARIES}
58+
${GSTREAMER_AUDIO_LIBRARIES}
59+
${GSTREAMER_VIDEO_LIBRARIES}
60+
utils
61+
PUBLIC
62+
bisect::project_warnings
63+
bisect::expected
64+
bisect::bisect_nmoscpp
65+
bisect::bisect_json
66+
nlohmann_json::nlohmann_json
67+
ossrf::ossrf_nmos_api
68+
${GLIB_LIBRARIES}
69+
)
70+
set_target_properties(${plugin_name} PROPERTIES
71+
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/plugins
72+
OUTPUT_NAME ${output_name}
73+
)
74+
add_library(ossrf::${plugin_name} ALIAS ${plugin_name})
75+
install(TARGETS ${plugin_name}
76+
LIBRARY DESTINATION ~/.local/lib/gstreamer-1.0
77+
)
78+
endfunction()
79+
80+
# Plugin: Video Receiver
81+
create_plugin(
82+
gst_nmos_video_receiver_plugin
83+
src/gst_nmos_video_receiver_plugin.cpp
84+
"gstnmosvideoreceiver"
85+
)
86+
87+
# Plugin: Audio Receiver
88+
create_plugin(
89+
gst_nmos_audio_receiver_plugin
90+
src/gst_nmos_audio_receiver_plugin.cpp
91+
"gstnmosaudioreceiver"
92+
)
93+
94+
# Plugin: Sender
95+
create_plugin(
96+
gst_nmos_sender_plugin
97+
src/gst_nmos_sender_plugin.cpp
98+
"gstnmossender"
99+
)

0 commit comments

Comments
 (0)