Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nmos receiver plugin #18

Merged
merged 4 commits into from
Jan 31, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions cpp/demos/config/nmos_plugin_node_config_receiver.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"node": {
"id": "8968180c-0418-4422-bea1-f0c642389637",
"configuration": {
"label": "BISECT OSSRF Node Receiver",
"description": "BISECT OSSRF node receiver",
"host_addresses": [
"192.168.1.36"
],
"interfaces": [
{
"chassis_id": "c9-94-02-f7-3e-eb",
"name": "wlp1s0",
"port_id": "00-e0-4c-68-01-8d"
}
],
"clocks": [
{
"name": "clk0",
"ref_type": "ptp",
"traceable": false,
"version": "IEEE1588-2008",
"gmid": "00-20-fc-ff-fe-35-9c-26",
"locked": true
}
],
"registry_address": "192.168.1.36",
"registry_version": "v1.3",
"registration_port": 8010,
"system_address": "192.168.1.36",
"system_version": "v1.0",
"system_port": 8010,
"http_port": 5114
}
},
"device": {},
"receivers": [],
"senders": []
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@
"node": {
"id": "d5504cd1-fe68-489d-99d4-20d3f075f062",
"configuration": {
"label": "BISECT OSSRF Node2",
"description": "BISECT OSSRF node2",
"label": "BISECT OSSRF Node Sender",
"description": "BISECT OSSRF node sender",
"host_addresses": [
"192.168.1.120"
"192.168.1.36"
],
"interfaces": [
{
"chassis_id": "c8-94-02-f7-3e-eb",
"name": "wlp1s0",
"port_id": "00-e0-4c-68-01-8d"
"port_id": "01-e0-4c-68-01-8d"
}
],
"clocks": [
Expand All @@ -24,13 +24,13 @@
"locked": true
}
],
"registry_address": "192.168.1.120",
"registry_address": "192.168.1.36",
"registry_version": "v1.3",
"registration_port": 8010,
"system_address": "192.168.1.120",
"system_address": "192.168.1.36",
"system_version": "v1.0",
"system_port": 8010,
"http_port": 5113
"http_port": 6114
}
},
"device": {},
Expand Down
2 changes: 1 addition & 1 deletion cpp/libs/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ add_subdirectory(bisect_expected)
add_subdirectory(bisect_nmoscpp)
add_subdirectory(bisect_sdp)
add_subdirectory(bisect_gst)
add_subdirectory(gst_nmos_sender_plugin)
add_subdirectory(gst_nmos_plugins)
add_subdirectory(ossrf_nmos_api)
add_subdirectory(ossrf_gstreamer_api)
add_subdirectory(bisect_json)
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ namespace bisect::nmoscpp
nmos::rational exact_framerate;
std::string chroma_sub_sampling;
nmos::interlace_mode structure;
int depth = 0;
};

struct audio_sender_info_t
Expand Down
3 changes: 2 additions & 1 deletion cpp/libs/bisect_sdp/lib/src/reader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ namespace
.exact_framerate = nmos::rational(params.exactframerate.numerator(), params.exactframerate.denominator()),
.chroma_sub_sampling = "YCbCr-4:2:2",
.structure = params.interlace ? nmos::interlace_modes::interlaced_tff : nmos::interlace_modes::progressive,
.depth = static_cast<int>(params.depth),
};
}
} // namespace
Expand Down Expand Up @@ -196,4 +197,4 @@ expected<sdp_settings_t> bisect::sdp::parse_sdp(const std::string& sdp)
{
BST_FAIL("error parsing SDP: {}", ex.what());
}
}
}
99 changes: 99 additions & 0 deletions cpp/libs/gst_nmos_plugins/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
cmake_minimum_required(VERSION 3.16)
project(gst_nmos_plugins LANGUAGES CXX)

find_package(nlohmann_json REQUIRED)
find_package(PkgConfig REQUIRED)

# Locate GLib package
pkg_check_modules(GLIB REQUIRED glib-2.0)

# Locate GStreamer packages
pkg_search_module(GSTREAMER REQUIRED gstreamer-1.0>=1.4)
pkg_search_module(GSTREAMER_APP REQUIRED gstreamer-app-1.0>=1.4)
pkg_search_module(GSTREAMER_AUDIO REQUIRED gstreamer-audio-1.0>=1.4)
pkg_search_module(GSTREAMER_VIDEO REQUIRED gstreamer-video-1.0>=1.4)

# Include the parent directory of gst_nmos_plugins
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..)

# Utils library (shared across plugins)
add_library(utils STATIC src/utils.cpp)

# Enable -fPIC for utils
set_target_properties(utils PROPERTIES POSITION_INDEPENDENT_CODE ON)

target_include_directories(utils
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/..
PRIVATE ${GLIB_INCLUDE_DIRS}
PRIVATE ${GSTREAMER_INCLUDE_DIRS}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../bisect
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../ossrf
)
target_link_libraries(utils
PUBLIC nlohmann_json::nlohmann_json
PRIVATE ${GLIB_LIBRARIES}
PRIVATE ${GSTREAMER_LIBRARIES}
PRIVATE ${GSTREAMER_APP_LIBRARIES}
PRIVATE ${GSTREAMER_AUDIO_LIBRARIES}
PRIVATE ${GSTREAMER_VIDEO_LIBRARIES}
PRIVATE bisect::project_warnings
PRIVATE bisect::expected
PRIVATE bisect::bisect_nmoscpp
PRIVATE bisect::bisect_json
PRIVATE ossrf::ossrf_nmos_api
)

# Function to create a plugin target
function(create_plugin plugin_name plugin_sources output_name)
add_library(${plugin_name} MODULE ${plugin_sources})
target_include_directories(${plugin_name}
PRIVATE ${GSTREAMER_INCLUDE_DIRS}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/..
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
)
target_link_libraries(${plugin_name}
PRIVATE
${GSTREAMER_LIBRARIES}
${GSTREAMER_APP_LIBRARIES}
${GSTREAMER_AUDIO_LIBRARIES}
${GSTREAMER_VIDEO_LIBRARIES}
utils
PUBLIC
bisect::project_warnings
bisect::expected
bisect::bisect_nmoscpp
bisect::bisect_json
nlohmann_json::nlohmann_json
ossrf::ossrf_nmos_api
${GLIB_LIBRARIES}
)
set_target_properties(${plugin_name} PROPERTIES
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/plugins
OUTPUT_NAME ${output_name}
)
add_library(ossrf::${plugin_name} ALIAS ${plugin_name})
install(TARGETS ${plugin_name}
LIBRARY DESTINATION ~/.local/lib/gstreamer-1.0
)
endfunction()

# Plugin: Video Receiver
create_plugin(
gst_nmos_video_receiver_plugin
src/gst_nmos_video_receiver_plugin.cpp
"gstnmosvideoreceiver"
)

# Plugin: Audio Receiver
create_plugin(
gst_nmos_audio_receiver_plugin
src/gst_nmos_audio_receiver_plugin.cpp
"gstnmosaudioreceiver"
)

# Plugin: Sender
create_plugin(
gst_nmos_sender_plugin
src/gst_nmos_sender_plugin.cpp
"gstnmossender"
)
71 changes: 71 additions & 0 deletions cpp/libs/gst_nmos_plugins/include/element_class.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#pragma once
#include <string>
#include <glib.h>
#include <variant>
#include <gst/gst.h>
#include <nlohmann/json.hpp>

template <typename T = GstElement> class GstElementHandle
{
public:
static std::variant<GstElementHandle, std::nullptr_t> create_element(const char* factory_name,
const char* element_name = nullptr)
{
T* elem = reinterpret_cast<T*>(gst_element_factory_make(factory_name, element_name));
if(elem == nullptr)
{
return nullptr;
}
return GstElementHandle(elem);
}

static std::variant<GstElementHandle, std::nullptr_t> create_bin(const char* bin_name)
{
T* bin = reinterpret_cast<T*>(gst_bin_new(bin_name));
if(bin == nullptr)
{
return nullptr;
}
return GstElementHandle(bin);
}

GstElementHandle(const GstElementHandle&) = delete;
GstElementHandle& operator=(const GstElementHandle&) = delete;

GstElementHandle(GstElementHandle&& other) noexcept : handle_(other.handle_) { other.handle_ = nullptr; }

GstElementHandle& operator=(GstElementHandle&& other) noexcept
{
if(this != &other)
{
if(handle_ != nullptr)
{
gst_object_unref(handle_);
}
handle_ = other.handle_;
other.handle_ = nullptr;
}
return *this;
}

~GstElementHandle()
{
if(handle_)
{
gst_object_unref(handle_);
}
}

/// Destruction of this object will no longer unref the owned element.
void forget(T* new_ptr = nullptr)
{
handle_ = new_ptr;
}

T* get() const { return handle_; }

private:
explicit GstElementHandle(T* handle) : handle_(handle) {}

T* handle_ = nullptr;
};
57 changes: 57 additions & 0 deletions cpp/libs/gst_nmos_plugins/include/nmos_configuration.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#pragma once
#include <string>
#include <glib.h>

struct node_fields_t
{
std::string id;
std::string configuration_location;
};

struct device_fields_t
{
std::string id;
std::string label;
std::string description;
};

struct video_media_fields_t
{
gint width;
gint height;
gint frame_rate_num;
gint frame_rate_den;
std::string sampling;
std::string structure;
};

struct audio_media_fields_t
{
std::string format;
gint number_of_channels;
gint sampling_rate;
gint packet_time;
};

struct network_fields_t
{
std::string source_address;
std::string interface_name;
std::string destination_address;
gint destination_port;
};

struct config_fields_t
{
node_fields_t node;
device_fields_t device;
gboolean is_audio;
video_media_fields_t video_media_fields;
audio_media_fields_t audio_sender_fields;
std::string id;
std::string label;
std::string description;
network_fields_t network;
std::string interface_name;
std::string address;
};
Loading
Loading