Skip to content
Closed
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
4 changes: 4 additions & 0 deletions applications/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ add_holohub_application(deltacast_transmitter DEPENDS
OPERATORS deltacast_videomaster
)

add_holohub_application(deltacast_receiver DEPENDS
OPERATORS deltacast_videomaster
)

add_holohub_application(depth_anything_v2)

add_subdirectory(distributed)
Expand Down
19 changes: 19 additions & 0 deletions applications/deltacast_receiver/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# SPDX-FileCopyrightText: Copyright (c) 2022-2025 DELTACAST.TV. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

cmake_minimum_required(VERSION 3.20)
project(deltacast_receiver_apps LANGUAGES NONE)

add_subdirectory(cpp)
25 changes: 25 additions & 0 deletions applications/deltacast_receiver/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Deltacast Videomaster Receiver

This application demonstrates the use of videomaster_source to receive and display video streams from a Deltacast capture card using Holoviz for visualization.

## Requirements

This application uses the DELTACAST.TV capture card for input stream. Contact [DELTACAST.TV](https://www.deltacast.tv/) for more details on how to access the SDK and setup your environment.

## Build Instructions

See instructions from the top level README on how to build this application.
Note that this application requires to provide the VideoMaster_SDK_DIR if it is not located in a default location on the system.
This can be done with the following command, from the top level Holohub source directory:

```bash
./holohub build --local deltacast_receiver --configure-args="-DVideoMaster_SDK_DIR=<Path to VideoMasterSDK>"
```

## Run Instructions

From the build directory, run the command:

```bash
./applications/deltacast_receiver/cpp/deltacast_receiver
```
40 changes: 40 additions & 0 deletions applications/deltacast_receiver/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# SPDX-FileCopyrightText: Copyright (c) 2022-2025 DELTACAST.TV. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
cmake_minimum_required(VERSION 3.20)
project(deltacast_receiver CXX)

find_package(holoscan 1.0 REQUIRED CONFIG
PATHS "/opt/nvidia/holoscan" "/workspace/holoscan-sdk/install")

# CPP Application
add_executable(deltacast_receiver
main.cpp
)

target_link_libraries(deltacast_receiver
PRIVATE
holoscan::core
holoscan::ops::format_converter
holoscan::ops::holoviz
holoscan::videomaster
)

# Copy config file
add_custom_target(deltacast_receiver_yaml
COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/deltacast_receiver.yaml" ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS "deltacast_receiver.yaml"
BYPRODUCTS "deltacast_receiver.yaml"
)
add_dependencies(deltacast_receiver deltacast_receiver_yaml)
48 changes: 48 additions & 0 deletions applications/deltacast_receiver/cpp/deltacast_receiver.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
%YAML 1.2
# SPDX-FileCopyrightText: Copyright (c) 2022-2025 DELTACAST.TV. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
---
extensions:
- lib/gxf_extensions/libgxf_videomaster.so

deltacast:
width: 1920
height: 1080
progressive: true
framerate: 30
board: 0
input: 0
rdma: false

format_converter:
in_dtype: "rgb888"
alpha_value: 255
out_dtype: "rgba8888"
out_channel_order: [2,1,0,3]

drop_alpha_channel_converter:
in_dtype: "rgba8888"
out_dtype: "rgb888"
resize_height: 270
resize_width: 480

holoviz:
tensors:
- name: ""
type: color
opacity: 1.0
priority: 0
width: 480
height: 270
130 changes: 130 additions & 0 deletions applications/deltacast_receiver/cpp/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2022-2025 DELTACAST.TV. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include <holoscan/holoscan.hpp>
#include <holoscan/operators/format_converter/format_converter.hpp>
#include <holoscan/operators/holoviz/holoviz.hpp>
#include <videomaster_source.hpp>

#include <getopt.h>

class App : public holoscan::Application {
public:
/** Compose function */
void compose() override {
using namespace holoscan;

uint32_t width = from_config("deltacast.width").as<uint32_t>();
uint32_t height = from_config("deltacast.height").as<uint32_t>();
bool use_rdma = from_config("deltacast.rdma").as<bool>();
uint64_t source_block_size = width * height * 4 * 4;
uint64_t source_num_blocks = use_rdma ? 3 : 4;

// Create the VideoMaster source operator (receiver) with explicit arguments
auto source = make_operator<ops::VideoMasterSourceOp>(
"deltacast_source",
Arg("rdma") = use_rdma,
Arg("board") = from_config("deltacast.board").as<uint32_t>(),
Arg("input") = from_config("deltacast.input").as<uint32_t>(),
Arg("width") = width,
Arg("height") = height,
Arg("progressive") = from_config("deltacast.progressive").as<bool>(),
Arg("framerate") = from_config("deltacast.framerate").as<uint32_t>(),
Arg("pool") = make_resource<UnboundedAllocator>("pool"));

// Format converter to prepare for visualization
auto format_converter =
make_operator<ops::FormatConverterOp>("format_converter",
from_config("format_converter"),
Arg("pool") = make_resource<BlockMemoryPool>(
"converter_pool", 1, source_block_size,
source_num_blocks));

auto drop_alpha_channel_converter = make_operator<ops::FormatConverterOp>(
"drop_alpha_channel_converter",
from_config("drop_alpha_channel_converter"),
Arg("pool") =
make_resource<BlockMemoryPool>("pool", 1, source_block_size, source_num_blocks));
auto visualizer = make_operator<ops::HolovizOp>(
"holoviz",
from_config("holoviz"),
Arg("allocator") = make_resource<UnboundedAllocator>("holoviz_allocator"));

// Connect the pipeline: source -> format_converter -> holoviz
add_flow(source, drop_alpha_channel_converter);
add_flow(drop_alpha_channel_converter, format_converter);
add_flow(format_converter, visualizer, {{"", "receivers"}});
}
};

/** Helper function to parse the command line arguments */
bool parse_arguments(int argc, char** argv, std::string& config_name) {
static struct option long_options[] = {
{"config", required_argument, 0, 'c' },
{"help", no_argument, 0, 'h' },
{0, 0, 0, 0 }
};

while (int c = getopt_long(argc, argv, "c:h",
long_options, NULL)) {
if (c == -1 || c == '?') break;

switch (c) {
case 'c':
config_name = optarg;
break;
case 'h':
std::cout << "Usage: " << argv[0] << " [options] [config_file]\n";
std::cout << "Options:\n";
std::cout << " -c, --config <file> Configuration file path\n";
std::cout << " -h, --help Show this help message\n";
std::cout << "\nExample:\n";
std::cout << " " << argv[0] << " deltacast_receiver.yaml\n";
return false;
default:
std::cout << "Unknown arguments returned: " << c << std::endl;
return false;
}
}

if (optind < argc) {
config_name = argv[optind++];
}
return true;
}

int main(int argc, char** argv) {
auto app = holoscan::make_application<App>();

// Parse the arguments
std::string config_name = "";
if (!parse_arguments(argc, argv, config_name)) {
return 1;
}

if (config_name != "") {
app->config(config_name);
} else {
auto config_path = std::filesystem::canonical(argv[0]).parent_path();
config_path += "/deltacast_receiver.yaml";
app->config(config_path);
}

app->run();

return 0;
}
43 changes: 43 additions & 0 deletions applications/deltacast_receiver/cpp/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"application": {
"name": "Deltacast Videomaster Receiver",
"authors": [
{
"name": "Laurent Radoux",
"affiliation": "DELTACAST"
},
{
"name": "Pierre PERICK",
"affiliation": "DELTACAST"
}
],
"language": "C++",
"version": "1.0",
"changelog": {
"1.0": "Initial Release - Simplified receiver application for video display without AI processing"
},
"holoscan_sdk": {
"minimum_required_version": "0.5.0",
"tested_versions": [
"3.6.0"
]
},
"videomaster_sdk": {
"minimum_required_version": "6.26.0",
"tested_versions": [
"6.32.0"
]
},
"platforms": [
"x86_64",
"aarch64"
],
"tags": ["Healthcare AI", "Video", "Deltacast", "Receiver", "Display", "Holoviz", "RDMA", "GPUDirect"],
"ranking": 2,
"requirements": {},
"run": {
"command": "<holohub_app_bin>/deltacast_receiver",
"workdir": "holohub_bin"
}
}
}
44 changes: 44 additions & 0 deletions applications/deltacast_receiver/python/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# SPDX-FileCopyrightText: Copyright (c) 2022-2025 DELTACAST.TV. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Add testing
if(BUILD_TESTING)
# To get the environment path
find_package(holoscan 1.0 REQUIRED CONFIG PATHS "/opt/nvidia/holoscan" "/workspace/holoscan-sdk/install")

# Add test
add_test(NAME deltacast_receiver_python_test
COMMAND python3 ${CMAKE_CURRENT_SOURCE_DIR}/deltacast_receiver.py
--config ${CMAKE_CURRENT_SOURCE_DIR}/deltacast_receiver.yaml
WORKING_DIRECTORY ${CMAKE_BINARY_DIR})

set_property(TEST deltacast_receiver_python_test PROPERTY ENVIRONMENT
"PYTHONPATH=${GXF_LIB_DIR}/../python/lib:${CMAKE_BINARY_DIR}/python/lib")

set_tests_properties(deltacast_receiver_python_test PROPERTIES
PASS_REGULAR_EXPRESSION "Running the graph;"
FAIL_REGULAR_EXPRESSION "[^a-z]Error;ERROR;Failed")
endif()

# Install application and dependencies into the install/ directory for packaging
install(
FILES deltacast_receiver.py
DESTINATION bin/deltacast_receiver/python
)

install(
FILES deltacast_receiver.yaml
DESTINATION bin/deltacast_receiver/python
)
Loading
Loading