From bc1c7e8b67771bb9ff982e4e013d0f327b1babb3 Mon Sep 17 00:00:00 2001 From: LufeBisect Date: Mon, 16 Dec 2024 11:28:08 +0000 Subject: [PATCH] All functions translated and created new json test files All functions translated and created new json test files --- .../ossrf-nmos-api/config/nmos_config.json | 20 +-- .../config/nmos_receiver_config.json | 14 ++ .../config/nmos_sender_config.json | 25 +++ cpp/libs/CMakeLists.txt | 2 + .../gst_nmos_sender_plugin/CMakeLists.txt | 10 +- .../gst_nmos_sender_plugin.c | 21 ++- cpp/libs/ossrf_c_nmos_api/CMakeLists.txt | 43 +++++ .../ossrf_c_nmos_api/ossrf_c_nmos_api.cpp | 162 ++++++++++++++++++ cpp/libs/ossrf_c_nmos_api/ossrf_c_nmos_api.h | 23 +++ 9 files changed, 307 insertions(+), 13 deletions(-) create mode 100644 cpp/demos/ossrf-nmos-api/config/nmos_receiver_config.json create mode 100644 cpp/demos/ossrf-nmos-api/config/nmos_sender_config.json create mode 100644 cpp/libs/ossrf_c_nmos_api/CMakeLists.txt create mode 100644 cpp/libs/ossrf_c_nmos_api/ossrf_c_nmos_api.cpp create mode 100644 cpp/libs/ossrf_c_nmos_api/ossrf_c_nmos_api.h diff --git a/cpp/demos/ossrf-nmos-api/config/nmos_config.json b/cpp/demos/ossrf-nmos-api/config/nmos_config.json index 0933c39..6a86aec 100644 --- a/cpp/demos/ossrf-nmos-api/config/nmos_config.json +++ b/cpp/demos/ossrf-nmos-api/config/nmos_config.json @@ -5,7 +5,7 @@ "label": "BISECT OSSRF Node", "description": "BISECT OSSRF node", "host_addresses": [ - "192.168.1.85" + "192.168.88.92" ], "interfaces": [ { @@ -24,10 +24,10 @@ "locked": true } ], - "registry_address": "192.168.1.85", + "registry_address": "192.168.88.92", "registry_version": "v1.3", "registration_port": 8010, - "system_address": "192.168.1.85", + "system_address": "192.168.88.92", "system_version": "v1.0", "system_port": 8010 } @@ -44,7 +44,7 @@ "description": "BISECT OSSRF receiver video", "network": { "primary": { - "interface_address": "192.168.1.85", + "interface_address": "192.168.88.92", "interface_name": "wlp1s0" } }, @@ -58,7 +58,7 @@ "description": "BISECT OSSRF receiver audio", "network": { "primary": { - "interface_address": "192.168.1.85", + "interface_address": "192.168.88.92", "interface_name": "wlp1s0" } }, @@ -74,9 +74,9 @@ "description": "BISECT OSSRF sender video", "network": { "primary": { - "source_address": "192.168.1.85", + "source_address": "192.168.88.92", "interface_name": "wlp1s0", - "destination_address": "239.10.10.10", + "destination_address": "192.168.88.92", "destination_port": 5004 } }, @@ -99,9 +99,9 @@ "description": "BISECT OSSRF sender audio", "network": { "primary": { - "source_address": "192.168.1.85", + "source_address": "192.168.88.92", "interface_name": "wlp1s0", - "destination_address": "239.10.10.11", + "destination_address": "192.168.88.92", "destination_port": 5005 } }, @@ -114,4 +114,4 @@ } } ] -} +} \ No newline at end of file diff --git a/cpp/demos/ossrf-nmos-api/config/nmos_receiver_config.json b/cpp/demos/ossrf-nmos-api/config/nmos_receiver_config.json new file mode 100644 index 0000000..f8375ab --- /dev/null +++ b/cpp/demos/ossrf-nmos-api/config/nmos_receiver_config.json @@ -0,0 +1,14 @@ + { + "id": "db9f46cf-2414-4e25-b6c6-2078159857f9", + "label": "BISECT OSSRF receiver video", + "description": "BISECT OSSRF receiver video", + "network": { + "primary": { + "interface_address": "192.168.88.92", + "interface_name": "wlp1s0" + } + }, + "capabilities": [ + "video/raw" + ] + } \ No newline at end of file diff --git a/cpp/demos/ossrf-nmos-api/config/nmos_sender_config.json b/cpp/demos/ossrf-nmos-api/config/nmos_sender_config.json new file mode 100644 index 0000000..fb0a3fc --- /dev/null +++ b/cpp/demos/ossrf-nmos-api/config/nmos_sender_config.json @@ -0,0 +1,25 @@ + { + "id": "e543a2c1-d6a2-47f5-8d14-296bb6714ef2", + "label": "BISECT OSSRF sender video", + "description": "BISECT OSSRF sender video", + "network": { + "primary": { + "source_address": "192.168.88.92", + "interface_name": "wlp1s0", + "destination_address": "192.168.88.92", + "destination_port": 5004 + } + }, + "payload_type": 97, + "media_type": "video/raw", + "media": { + "width": 640, + "height": 480, + "frame_rate": { + "num": 50, + "den": 1 + }, + "sampling": "YCbCr-4:2:2", + "structure": "progressive" + } + } \ No newline at end of file diff --git a/cpp/libs/CMakeLists.txt b/cpp/libs/CMakeLists.txt index c5298e1..f5bf0ec 100644 --- a/cpp/libs/CMakeLists.txt +++ b/cpp/libs/CMakeLists.txt @@ -2,6 +2,8 @@ add_subdirectory(bisect_expected) add_subdirectory(bisect_nmoscpp) add_subdirectory(bisect_sdp) add_subdirectory(bisect_gst) +add_subdirectory(gst_nmos_sender_plugin) add_subdirectory(ossrf_nmos_api) +add_subdirectory(ossrf_c_nmos_api) add_subdirectory(ossrf_gstreamer_api) add_subdirectory(bisect_json) diff --git a/cpp/libs/gst_nmos_sender_plugin/CMakeLists.txt b/cpp/libs/gst_nmos_sender_plugin/CMakeLists.txt index 084c37a..82b3670 100644 --- a/cpp/libs/gst_nmos_sender_plugin/CMakeLists.txt +++ b/cpp/libs/gst_nmos_sender_plugin/CMakeLists.txt @@ -1,6 +1,9 @@ cmake_minimum_required(VERSION 3.16) project(gst_nmos_sender_plugin LANGUAGES C) +# Define the path to the ossrf_c_nmos_api directory +set(OSSRF_C_NMOS_API_PATH "../ossrf_c_nmos_api/") + # Find required GStreamer packages find_package(PkgConfig REQUIRED) pkg_search_module(GSTREAMER REQUIRED gstreamer-1.0>=1.4) @@ -15,7 +18,7 @@ file(GLOB_RECURSE ${PROJECT_NAME}_source_files *.c *.h) add_library(${PROJECT_NAME} MODULE ${${PROJECT_NAME}_source_files}) # Include directories -target_include_directories(${PROJECT_NAME} PRIVATE ${GSTREAMER_INCLUDE_DIRS}) +target_include_directories(${PROJECT_NAME} PRIVATE ${GSTREAMER_INCLUDE_DIRS} ${OSSRF_C_NMOS_API_PATH}) # Link GStreamer libraries target_compile_options(${PROJECT_NAME} PRIVATE ${GSTREAMER_CFLAGS_OTHER}) @@ -23,7 +26,8 @@ target_link_libraries(${PROJECT_NAME} PRIVATE ${GSTREAMER_LIBRARIES} ${GSTREAMER_APP_LIBRARIES} ${GSTREAMER_AUDIO_LIBRARIES} - ${GSTREAMER_VIDEO_LIBRARIES}) + ${GSTREAMER_VIDEO_LIBRARIES} + ossrf::ossrf_c_nmos_api) # Specify the output directory and the library name set_target_properties(${PROJECT_NAME} PROPERTIES @@ -31,6 +35,8 @@ set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME "gstnmossender" # Custom .so name ) +add_library(ossrf::${PROJECT_NAME} ALIAS ${PROJECT_NAME}) + # Install the plugin to the system's GStreamer plugin directory install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION ~/.local/lib/gstreamer-1.0) diff --git a/cpp/libs/gst_nmos_sender_plugin/gst_nmos_sender_plugin.c b/cpp/libs/gst_nmos_sender_plugin/gst_nmos_sender_plugin.c index 63e2bad..ae4ad02 100644 --- a/cpp/libs/gst_nmos_sender_plugin/gst_nmos_sender_plugin.c +++ b/cpp/libs/gst_nmos_sender_plugin/gst_nmos_sender_plugin.c @@ -22,6 +22,7 @@ #include #include +#include GST_DEBUG_CATEGORY_STATIC(gst_nmossender_debug_category); #define GST_CAT_DEFAULT gst_nmossender_debug_category @@ -44,7 +45,7 @@ typedef struct _GstNmossenderClass } GstNmossenderClass; G_DEFINE_TYPE_WITH_CODE(GstNmossender, gst_nmossender, GST_TYPE_BIN, - GST_DEBUG_CATEGORY_INIT(gst_nmossender_debug_category, "nmossender", 0, "NMOS Sender Plugin")); + GST_DEBUG_CATEGORY_INIT(gst_nmossender_debug_category, "nmossender", 0, "NMOS Sender Plugin")) /* Pad template */ static GstStaticPadTemplate sink_template = @@ -80,6 +81,24 @@ static void gst_nmossender_init(GstNmossender* self) return; } + // Example of using the nmos_client_create function + const char* config_location = + "/home/nmos/repos/nmos-sender-receiver-framework/cpp/demos/ossrf-nmos-api/config/nmos_config.json"; + + nmos_client_t* client = nmos_client_create(config_location); + if(client) + { + nmos_client_add_device(client, config_location); + nmos_client_add_sender(client); + nmos_client_add_receiver(client); + nmos_client_remove_sender(client); + nmos_client_remove_receiver(client); + } + else + { + // Handle error + } + /* Configure udpsink properties */ g_object_set(G_OBJECT(self->udpsink), "host", "127.0.0.1", "port", 9999, NULL); diff --git a/cpp/libs/ossrf_c_nmos_api/CMakeLists.txt b/cpp/libs/ossrf_c_nmos_api/CMakeLists.txt new file mode 100644 index 0000000..78c1b71 --- /dev/null +++ b/cpp/libs/ossrf_c_nmos_api/CMakeLists.txt @@ -0,0 +1,43 @@ +cmake_minimum_required(VERSION 3.16) +project(ossrf_c_nmos_api LANGUAGES CXX C) + +find_package(nlohmann_json REQUIRED) + +file(GLOB_RECURSE ${PROJECT_NAME}_source_files *.cpp *.h) + +add_library(${PROJECT_NAME} STATIC ${${PROJECT_NAME}_source_files}) + +target_link_libraries( + ${PROJECT_NAME} + PRIVATE project_options project_warnings + PUBLIC + bisect::project_warnings + bisect::expected + bisect::bisect_nmoscpp + bisect::bisect_json + nlohmann_json::nlohmann_json + ossrf::ossrf_nmos_api +) + +set_target_properties( + ${PROJECT_NAME} + PROPERTIES CXX_EXTENSIONS NO + POSITION_INDEPENDENT_CODE ON) + +target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_23) + +target_include_directories( + ${PROJECT_NAME} + PUBLIC $ + $ + $ + PRIVATE src) + +add_library(ossrf::${PROJECT_NAME} ALIAS ${PROJECT_NAME}) + +install(TARGETS ${PROJECT_NAME}) +install(DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/include" # source directory + DESTINATION "." # target directory + FILES_MATCHING # install only matched files + PATTERN "*.h" # select header files +) diff --git a/cpp/libs/ossrf_c_nmos_api/ossrf_c_nmos_api.cpp b/cpp/libs/ossrf_c_nmos_api/ossrf_c_nmos_api.cpp new file mode 100644 index 0000000..54ff65b --- /dev/null +++ b/cpp/libs/ossrf_c_nmos_api/ossrf_c_nmos_api.cpp @@ -0,0 +1,162 @@ +#include "ossrf_c_nmos_api.h" +#include "ossrf/nmos/api/nmos_client.h" +#include +#include +#include "bisect/nmoscpp/configuration.h" +#include "bisect/expected/macros.h" +#include "bisect/expected.h" +#include "bisect/json.h" + +using namespace bisect; +using json = nlohmann::json; + +struct nmos_client +{ + std::unique_ptr client; + std::string device_id; + std::unique_ptr sender_callback; + std::unique_ptr receiver_callback; + std::string sender_info_config; + std::string receiver_info_config; +}; + +expected load_configuration_from_file(std::string_view config_file) +{ + std::ifstream ifs(config_file.data()); + BST_ENFORCE(ifs.is_open(), "Failed opening file {}", config_file); + std::ostringstream buffer; + buffer << ifs.rdbuf(); + return parse_json(buffer.str()); +} + +nmos_client_t* nmos_client_create(const char* node_configuration_location) +{ + if(!node_configuration_location) + { + return nullptr; + } + + const auto configuration_result = load_configuration_from_file(node_configuration_location); + if(!configuration_result.has_value()) + { + return nullptr; + } + + const json& configuration = configuration_result.value(); + + auto node_result = find(configuration, "node"); + if(!node_result.has_value()) + { + return nullptr; + } + + const json& node = node_result.value(); + + auto node_id_result = find(node, "id"); + auto node_config_result = find(node, "configuration"); + + if(node_id_result.has_value() && node_config_result.has_value()) + { + const std::string node_id = node_id_result.value(); + const std::string node_configuration = node_config_result.value().dump(); + + auto result = ossrf::nmos_client_t::create(node_id, node_configuration); + if(!result.has_value()) + { + return nullptr; + } + + // wrap result in C compatible structure + nmos_client_t* wrapper = new nmos_client_t; + wrapper->client = std::move(*result); + return wrapper; + } + + return nullptr; +} + +int nmos_client_add_device(nmos_client_t* wrapper, const char* node_configuration_location) +{ + if(!wrapper || !node_configuration_location) + { + return -1; + } + + const auto configuration_result = load_configuration_from_file(node_configuration_location); + if(!configuration_result.has_value()) + { + return -1; + } + + const json& configuration = configuration_result.value(); + + auto device_result = find(configuration, "device"); + if(!device_result.has_value()) + { + return -1; + } + + const json& device = device_result.value(); + + auto device_id_result = find(device, "id"); + if(!device_id_result.has_value()) + { + return -1; + } + + const std::string device_id = device_id_result.value(); + const std::string device_config = device.dump(); + + auto result = wrapper->client->add_device(device_config); + if(!result.has_value()) + { + return -1; + } + + wrapper->device_id = device_id; + + return 0; +} + +int nmos_client_add_sender(nmos_client_t* wrapper) +{ + auto sender_activation_callback = [](bool master_enabled, const nlohmann::json& transport_params) { + fmt::print("nmos_sender_callback: {} {}\n", master_enabled, transport_params.dump()); + }; + // FIX ME: Gonna be hardcoded for now + const auto sender_config = load_configuration_from_file( + "/home/nmos/repos/nmos-sender-receiver-framework/cpp/demos/ossrf-nmos-api/config/nmos_sender_config.json"); + + wrapper->client->add_sender(wrapper->device_id, sender_config.value().dump(), sender_activation_callback); + wrapper->sender_info_config = sender_config.value().dump(); + + return 0; +} + +int nmos_client_add_receiver(nmos_client_t* wrapper) +{ + auto receiver_activation_callback = [](const std::optional& sdp, bool master_enable) { + fmt::print("nmos_receiver_callback: {} no sdp\n", master_enable); + }; + // FIX ME: Gonna be hardcoded for now + const auto receiver_config = load_configuration_from_file( + "/home/nmos/repos/nmos-sender-receiver-framework/cpp/demos/ossrf-nmos-api/config/nmos_receiver_config.json"); + wrapper->client->add_receiver(wrapper->device_id, receiver_config.value().dump(), receiver_activation_callback); + wrapper->receiver_info_config = receiver_config.value().dump(); + + return 0; +} + +int nmos_client_remove_sender(nmos_client_t* wrapper) +{ + // FIX ME: Error catching + wrapper->client->remove_sender(wrapper->device_id, wrapper->sender_info_config); + return 0; +} + +int nmos_client_remove_receiver(nmos_client_t* wrapper) +{ + // FIX ME: Error catching + wrapper->client->remove_receiver(wrapper->device_id, wrapper->receiver_info_config); + return 0; +} \ No newline at end of file diff --git a/cpp/libs/ossrf_c_nmos_api/ossrf_c_nmos_api.h b/cpp/libs/ossrf_c_nmos_api/ossrf_c_nmos_api.h new file mode 100644 index 0000000..1dbed19 --- /dev/null +++ b/cpp/libs/ossrf_c_nmos_api/ossrf_c_nmos_api.h @@ -0,0 +1,23 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct nmos_client nmos_client_t; + +nmos_client_t* nmos_client_create(const char* node_configuration_location); + +int nmos_client_add_device(nmos_client_t* client, const char* node_configuration_location); + +int nmos_client_add_sender(nmos_client_t* client); + +int nmos_client_add_receiver(nmos_client_t* client); + +int nmos_client_remove_sender(nmos_client_t* client); + +int nmos_client_remove_receiver(nmos_client_t* client); + +#ifdef __cplusplus +} +#endif