From 035662ca52f2bf23175ff194e3f216e5d95fd142 Mon Sep 17 00:00:00 2001 From: Saul Pablo Labajo Izquierdo Date: Thu, 17 Oct 2024 11:18:50 +0000 Subject: [PATCH 01/24] module videosampler --- server/module-extras/video-sampler/AUTHORS | 4 + .../video-sampler/CMakeLists.txt | 91 ++++ .../video-sampler/cmake/FindGRPC.cmake | 126 +++++ .../video-sampler/config.h.cmake | 22 + .../video-sampler/debian/changelog | 0 .../video-sampler/debian/control | 56 ++ .../video-sampler/debian/copyright | 10 + .../module-extras/video-sampler/debian/docs | 1 + .../debian/kurento-module-chroma-dev.install | 5 + .../debian/kurento-module-chroma.install | 3 + .../module-extras/video-sampler/debian/rules | 9 + .../video-sampler/hooks/pre-commit.hook | 118 ++++ .../video-sampler/src/CMakeLists.txt | 2 + .../src/gst-plugins/CMakeLists.txt | 1 + .../gst-plugins/videosampler/CMakeLists.txt | 33 ++ .../videosampler/kmsvideosampler.c | 504 ++++++++++++++++++ .../videosampler/kmsvideosampler.h | 83 +++ .../gst-plugins/videosampler/videosampler.c | 39 ++ .../video-sampler/src/server/CMakeLists.txt | 37 ++ .../objects/VideoSamplerImpl.cpp | 209 ++++++++ .../objects/VideoSamplerImpl.hpp | 118 ++++ .../src/server/interface/package.json | 8 + .../src/server/interface/pom.xml | 31 ++ .../videosampler.VideoSampler.kmd.json | 90 ++++ .../server/interface/videosampler.kmd.json | 14 + .../src/server/proto/CMakeLists.txt | 30 ++ .../proto/videoSampler/sampleImage.proto | 15 + .../video-sampler/tests/CMakeLists.txt | 1 + .../video-sampler/tests/server/CMakeLists.txt | 46 ++ .../tests/server/videosampler.cpp | 318 +++++++++++ 30 files changed, 2024 insertions(+) create mode 100644 server/module-extras/video-sampler/AUTHORS create mode 100644 server/module-extras/video-sampler/CMakeLists.txt create mode 100644 server/module-extras/video-sampler/cmake/FindGRPC.cmake create mode 100644 server/module-extras/video-sampler/config.h.cmake create mode 100644 server/module-extras/video-sampler/debian/changelog create mode 100644 server/module-extras/video-sampler/debian/control create mode 100644 server/module-extras/video-sampler/debian/copyright create mode 100644 server/module-extras/video-sampler/debian/docs create mode 100644 server/module-extras/video-sampler/debian/kurento-module-chroma-dev.install create mode 100644 server/module-extras/video-sampler/debian/kurento-module-chroma.install create mode 100755 server/module-extras/video-sampler/debian/rules create mode 100755 server/module-extras/video-sampler/hooks/pre-commit.hook create mode 100644 server/module-extras/video-sampler/src/CMakeLists.txt create mode 100644 server/module-extras/video-sampler/src/gst-plugins/CMakeLists.txt create mode 100644 server/module-extras/video-sampler/src/gst-plugins/videosampler/CMakeLists.txt create mode 100644 server/module-extras/video-sampler/src/gst-plugins/videosampler/kmsvideosampler.c create mode 100644 server/module-extras/video-sampler/src/gst-plugins/videosampler/kmsvideosampler.h create mode 100644 server/module-extras/video-sampler/src/gst-plugins/videosampler/videosampler.c create mode 100644 server/module-extras/video-sampler/src/server/CMakeLists.txt create mode 100644 server/module-extras/video-sampler/src/server/implementation/objects/VideoSamplerImpl.cpp create mode 100644 server/module-extras/video-sampler/src/server/implementation/objects/VideoSamplerImpl.hpp create mode 100644 server/module-extras/video-sampler/src/server/interface/package.json create mode 100644 server/module-extras/video-sampler/src/server/interface/pom.xml create mode 100644 server/module-extras/video-sampler/src/server/interface/videosampler.VideoSampler.kmd.json create mode 100644 server/module-extras/video-sampler/src/server/interface/videosampler.kmd.json create mode 100644 server/module-extras/video-sampler/src/server/proto/CMakeLists.txt create mode 100644 server/module-extras/video-sampler/src/server/proto/videoSampler/sampleImage.proto create mode 100644 server/module-extras/video-sampler/tests/CMakeLists.txt create mode 100644 server/module-extras/video-sampler/tests/server/CMakeLists.txt create mode 100644 server/module-extras/video-sampler/tests/server/videosampler.cpp diff --git a/server/module-extras/video-sampler/AUTHORS b/server/module-extras/video-sampler/AUTHORS new file mode 100644 index 0000000000..bb4c3b761d --- /dev/null +++ b/server/module-extras/video-sampler/AUTHORS @@ -0,0 +1,4 @@ +Jose Antonio Santos Cadenas +Miguel París Díaz +Santiago Carot-Nemesio +David Fernandez diff --git a/server/module-extras/video-sampler/CMakeLists.txt b/server/module-extras/video-sampler/CMakeLists.txt new file mode 100644 index 0000000000..5bcc9d507d --- /dev/null +++ b/server/module-extras/video-sampler/CMakeLists.txt @@ -0,0 +1,91 @@ +cmake_minimum_required(VERSION 3.5) + +project("kurento-module-videosampler") +message(STATUS "CMake project: ${PROJECT_NAME}") + +include(GNUInstallDirs) # CMAKE_INSTALL_* + +# Test configuration +set(GENERATE_TESTS FALSE CACHE BOOL "Always build tests: add `make check_build` to normal `make` calls") +set(DISABLE_TESTS FALSE CACHE BOOL "Enable running `make check` during the building process") +set(TEST_FILES_LOCATION "https://raw.githubusercontent.com/Kurento/test-files/main" CACHE STRING "Root URI with test files (e.g. http:// or file://)") +set(VALGRIND_NUM_CALLERS 20 CACHE STRING "Valgrind option: maximum number of entries shown in stack traces") +enable_testing() + +find_package(KurentoUtils) +if(NOT KurentoUtils_FOUND) + message(FATAL_ERROR "KurentoUtils not found; please install package 'kurento-cmake-utils'") +endif() + +message("If CodeGenerator is not found, you need to install 'kurento-module-core' from the Kurento repository") +include(CodeGenerator) +get_values_from_model(PREFIX VALUE MODELS ${CMAKE_CURRENT_SOURCE_DIR}/src/server/interface KEYS version) + +include(KurentoGitHelpers) +install_git_hook(pre-commit ${CMAKE_CURRENT_SOURCE_DIR}/hooks/pre-commit.hook) +get_git_version(PROJECT_VERSION ${VALUE_VERSION}) +message(STATUS "Project version: ${PROJECT_NAME}-${PROJECT_VERSION}") + +# Compiler flags +include(CommonBuildFlags) +common_buildflags_set() +#common_buildflags_print() + +# Development: Add here exceptions to the "Warnings are Errors" rule. +# Also, DOCUMENT WHY and always remove them as soon as the problem is fixed. +# For example: +#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-error=unused-function") +#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-error=unused-variable") + +# FIXME Disable error from deprecated "soup_session_sync_new" in libsoup +# (Since Ubuntu 18.04) +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-error=deprecated-declarations") + +# FIXME Disable error when macros __TIME__, __DATE__ or __TIMESTAMP__ are encountered +include(CheckCXXCompilerFlag) +CHECK_CXX_COMPILER_FLAG("-Wno-error=date-time" HAS_WARNING_DATE_TIME) +if(HAS_WARNING_DATE_TIME) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=date-time") +endif() + +# Generate file "config.h" +set(VERSION "${PROJECT_VERSION}") +set(PACKAGE "${PROJECT_NAME}") +set(GETTEXT_PACKAGE "${PROJECT_NAME}") +set(MANUAL_CHECK OFF CACHE BOOL "Tests will generate files") +set(KURENTO_MODULES_SO_DIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/${KURENTO_MODULES_DIR_INSTALL_PREFIX}") +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h) +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DHAVE_CONFIG_H") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DHAVE_CONFIG_H") +include_directories(${CMAKE_CURRENT_BINARY_DIR}) + +set(GST_REQUIRED ^1.0.0) + +find_package(PkgConfig) +pkg_check_modules(GSTREAMER REQUIRED gstreamer-1.0>=${GST_REQUIRED}) +pkg_check_modules(GSTREAMER_BASE REQUIRED gstreamer-base-1.0>=${GST_REQUIRED}) +pkg_check_modules(GSTREAMER_VIDEO REQUIRED gstreamer-video-1.0>=${GST_REQUIRED}) +pkg_check_modules(GSTREAMER_CHECK REQUIRED gstreamer-check-1.0>=${GST_REQUIRED}) + +pkg_check_modules(PROTOBUF REQUIRED protobuf) +pkg_check_modules(GRPC REQUIRED grpc) +pkg_check_modules(GRPC++ REQUIRED grpc++) + +# Cmake find modules +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake") + +find_package(Protobuf REQUIRED) +find_package(GRPC REQUIRED) + +# GRPC and Protocol Buffers libraries location +list(APPEND CMAKE_PREFIX_PATH "/opt/grpc" "/opt/protobuf") + + + +include(GenericFind) +generic_find(LIBNAME KMSCORE VERSION ^7.0.0 REQUIRED) + +set(CMAKE_INSTALL_GST_PLUGINS_DIR ${CMAKE_INSTALL_LIBDIR}/gstreamer-1.0) + +add_subdirectory(src) +add_subdirectory(tests) diff --git a/server/module-extras/video-sampler/cmake/FindGRPC.cmake b/server/module-extras/video-sampler/cmake/FindGRPC.cmake new file mode 100644 index 0000000000..513e57fc02 --- /dev/null +++ b/server/module-extras/video-sampler/cmake/FindGRPC.cmake @@ -0,0 +1,126 @@ +# +# Locate and configure the gRPC library +# +# Adds the following targets: +# +# gRPC::grpc - gRPC library +# gRPC::grpc++ - gRPC C++ library +# gRPC::grpc++_reflection - gRPC C++ reflection library +# gRPC::grpc_cpp_plugin - C++ generator plugin for Protocol Buffers +# + +# +# Generates C++ sources from the .proto files +# +# grpc_generate_cpp ( [...]) +# +# SRCS - variable to define with autogenerated source files +# HDRS - variable to define with autogenerated header files +# DEST - directory where the source files will be created +# ARGN - .proto files +# +function(GRPC_GENERATE_CPP SRCS HDRS DEST) + if(NOT ARGN) + message(SEND_ERROR "Error: GRPC_GENERATE_CPP() called without any proto files") + return() + endif() + + if(GRPC_GENERATE_CPP_APPEND_PATH) + # Create an include path for each file specified + foreach(FIL ${ARGN}) + get_filename_component(ABS_FIL ${FIL} ABSOLUTE) + get_filename_component(ABS_PATH ${ABS_FIL} PATH) + list(FIND _protobuf_include_path ${ABS_PATH} _contains_already) + if(${_contains_already} EQUAL -1) + list(APPEND _protobuf_include_path -I ${ABS_PATH}) + endif() + endforeach() + else() + set(_protobuf_include_path -I ${CMAKE_CURRENT_SOURCE_DIR}) + endif() + + if(DEFINED PROTOBUF_IMPORT_DIRS) + foreach(DIR ${PROTOBUF_IMPORT_DIRS}) + get_filename_component(ABS_PATH ${DIR} ABSOLUTE) + list(FIND _protobuf_include_path ${ABS_PATH} _contains_already) + if(${_contains_already} EQUAL -1) + list(APPEND _protobuf_include_path -I ${ABS_PATH}) + endif() + endforeach() + endif() + + set(${SRCS}) + set(${HDRS}) + foreach(FIL ${ARGN}) + get_filename_component(ABS_FIL ${FIL} ABSOLUTE) + get_filename_component(FIL_WE ${FIL} NAME_WE) + + list(APPEND ${SRCS} "${DEST}/${FIL_WE}.grpc.pb.cc") + list(APPEND ${HDRS} "${DEST}/${FIL_WE}.grpc.pb.h") + + add_custom_command( + OUTPUT "${DEST}/${FIL_WE}.grpc.pb.cc" + "${DEST}/${FIL_WE}.grpc.pb.h" + COMMAND protobuf::protoc + ARGS --grpc_out ${DEST} ${_protobuf_include_path} --plugin=protoc-gen-grpc=${GRPC_CPP_PLUGIN} ${ABS_FIL} + DEPENDS ${ABS_FIL} protobuf::protoc gRPC::grpc_cpp_plugin + COMMENT "Running C++ gRPC compiler on ${FIL}" + VERBATIM ) + endforeach() + + set_source_files_properties(${${SRCS}} ${${HDRS}} PROPERTIES GENERATED TRUE) + set(${SRCS} ${${SRCS}} PARENT_SCOPE) + set(${HDRS} ${${HDRS}} PARENT_SCOPE) +endfunction() + +# By default have GRPC_GENERATE_CPP macro pass -I to protoc +# for each directory where a proto file is referenced. +if(NOT DEFINED GRPC_GENERATE_CPP_APPEND_PATH) + set(GRPC_GENERATE_CPP_APPEND_PATH TRUE) +endif() + +# Find gRPC include directory +find_path(GRPC_INCLUDE_DIR grpc/grpc.h) +mark_as_advanced(GRPC_INCLUDE_DIR) + +# Find gRPC library +find_library(GRPC_LIBRARY NAMES grpc) +mark_as_advanced(GRPC_LIBRARY) +add_library(gRPC::grpc UNKNOWN IMPORTED) +set_target_properties(gRPC::grpc PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES ${GRPC_INCLUDE_DIR} + INTERFACE_LINK_LIBRARIES "-lpthread;-ldl" + IMPORTED_LOCATION ${GRPC_LIBRARY} +) + +# Find gRPC C++ library +find_library(GRPC_GRPC++_LIBRARY NAMES grpc++) +mark_as_advanced(GRPC_GRPC++_LIBRARY) +add_library(gRPC::grpc++ UNKNOWN IMPORTED) +set_target_properties(gRPC::grpc++ PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES ${GRPC_INCLUDE_DIR} + INTERFACE_LINK_LIBRARIES gRPC::grpc + IMPORTED_LOCATION ${GRPC_GRPC++_LIBRARY} +) + +# Find gRPC C++ reflection library +find_library(GRPC_GRPC++_REFLECTION_LIBRARY NAMES grpc++_reflection) +mark_as_advanced(GRPC_GRPC++_REFLECTION_LIBRARY) +add_library(gRPC::grpc++_reflection UNKNOWN IMPORTED) +set_target_properties(gRPC::grpc++_reflection PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES ${GRPC_INCLUDE_DIR} + INTERFACE_LINK_LIBRARIES gRPC::grpc++ + IMPORTED_LOCATION ${GRPC_GRPC++_REFLECTION_LIBRARY} +) + +# Find gRPC CPP generator +find_program(GRPC_CPP_PLUGIN NAMES grpc_cpp_plugin) +mark_as_advanced(GRPC_CPP_PLUGIN) +add_executable(gRPC::grpc_cpp_plugin IMPORTED) +set_target_properties(gRPC::grpc_cpp_plugin PROPERTIES + IMPORTED_LOCATION ${GRPC_CPP_PLUGIN} +) + +include(${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(gRPC DEFAULT_MSG + GRPC_LIBRARY GRPC_INCLUDE_DIR GRPC_GRPC++_REFLECTION_LIBRARY GRPC_CPP_PLUGIN) \ No newline at end of file diff --git a/server/module-extras/video-sampler/config.h.cmake b/server/module-extras/video-sampler/config.h.cmake new file mode 100644 index 0000000000..0ba0dac0cd --- /dev/null +++ b/server/module-extras/video-sampler/config.h.cmake @@ -0,0 +1,22 @@ +#ifndef __KURENTO_MODULE_CHROMA_CONFIG_H__ +#define __KURENTO_MODULE_CHROMA_CONFIG_H__ + +/* Version */ +#cmakedefine VERSION "@VERSION@" + +/* Package name */ +#cmakedefine PACKAGE "@PACKAGE@" + +/* The gettext domain name */ +#cmakedefine GETTEXT_PACKAGE "@GETTEXT_PACKAGE@" + +/* Tests will generate files for manual check if this macro is defined */ +#cmakedefine MANUAL_CHECK + +/* Root URI with test files (e.g. http:// or file://) */ +#cmakedefine TEST_FILES_LOCATION "@TEST_FILES_LOCATION@" + +/* Library installation directory */ +#cmakedefine KURENTO_MODULES_SO_DIR "@KURENTO_MODULES_SO_DIR@" + +#endif /* __KURENTO_MODULE_CHROMA_CONFIG_H__ */ diff --git a/server/module-extras/video-sampler/debian/changelog b/server/module-extras/video-sampler/debian/changelog new file mode 100644 index 0000000000..e69de29bb2 diff --git a/server/module-extras/video-sampler/debian/control b/server/module-extras/video-sampler/debian/control new file mode 100644 index 0000000000..699e144870 --- /dev/null +++ b/server/module-extras/video-sampler/debian/control @@ -0,0 +1,56 @@ +Source: kurento-module-videosampler +Maintainer: Kurento +Priority: optional +Build-Depends: + cmake, + debhelper-compat (= 13), + gstreamer1.0-plugins-bad, + gstreamer1.0-plugins-base, + gstreamer1.0-plugins-good, + kurento-module-core-dev (>= 7.1.1), + kurento-module-elements-dev (>= 7.1.1), + kurento-module-filters-dev (>= 7.1.1), + pkg-config, + protobuf-compilter +Standards-Version: 4.5.1 +Homepage: https://kurento.openvidu.io/ +Vcs-Browser: https://github.com/Kurento/kurento +Vcs-Git: https://github.com/Kurento/kurento.git +Rules-Requires-Root: no + +Package: kurento-module-chroma +Architecture: any +Section: libs +Depends: + ${misc:Depends}, + ${shlibs:Depends}, + gstreamer1.0-plugins-bad, + gstreamer1.0-plugins-base, + gstreamer1.0-plugins-good, + kurento-module-core (>= 7.1.1), + kurento-module-elements (>= 7.1.1), + kurento-module-filters (>= 7.1.1), +Breaks: + kms-chroma-6.0, + kms-chroma, +Replaces: + kms-chroma-6.0, + kms-chroma, +Description: Kurento Chroma filter + +Package: kurento-module-chroma-dev +Architecture: any +Section: libdevel +Depends: + ${misc:Depends}, + kurento-module-chroma (= ${binary:Version}), + kurento-module-core-dev, + kurento-module-elements-dev, + kurento-module-filters-dev, +Breaks: + kms-chroma-6.0-dev, + kms-chroma-dev, +Replaces: + kms-chroma-6.0-dev, + kms-chroma-dev, +Description: Kurento Chroma filter - Development files diff --git a/server/module-extras/video-sampler/debian/copyright b/server/module-extras/video-sampler/debian/copyright new file mode 100644 index 0000000000..a665595a16 --- /dev/null +++ b/server/module-extras/video-sampler/debian/copyright @@ -0,0 +1,10 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: kurento-module-chroma +Upstream-Contact: Kurento +Source: https://github.com/Kurento/kurento + +Files: * +Copyright: 2023 Kurento +License: Apache-2.0 + On Debian systems, the full text of the Apache-2.0 license + can be found in the file '/usr/share/common-licenses/Apache-2.0' diff --git a/server/module-extras/video-sampler/debian/docs b/server/module-extras/video-sampler/debian/docs new file mode 100644 index 0000000000..b43bf86b50 --- /dev/null +++ b/server/module-extras/video-sampler/debian/docs @@ -0,0 +1 @@ +README.md diff --git a/server/module-extras/video-sampler/debian/kurento-module-chroma-dev.install b/server/module-extras/video-sampler/debian/kurento-module-chroma-dev.install new file mode 100644 index 0000000000..57a6101aa5 --- /dev/null +++ b/server/module-extras/video-sampler/debian/kurento-module-chroma-dev.install @@ -0,0 +1,5 @@ +usr/include/kurento/modules/*/*.hpp +usr/lib/*/*.so +usr/lib/*/pkgconfig/*.pc +usr/share/cmake/Kurento/*.cmake +usr/share/kurento/modules/*.kmd.json diff --git a/server/module-extras/video-sampler/debian/kurento-module-chroma.install b/server/module-extras/video-sampler/debian/kurento-module-chroma.install new file mode 100644 index 0000000000..d3c8aba1f0 --- /dev/null +++ b/server/module-extras/video-sampler/debian/kurento-module-chroma.install @@ -0,0 +1,3 @@ +usr/lib/*/gstreamer-*/lib*.so +usr/lib/*/kurento/*/*.so +usr/lib/*/lib*.so.* diff --git a/server/module-extras/video-sampler/debian/rules b/server/module-extras/video-sampler/debian/rules new file mode 100755 index 0000000000..7e6c4f5a59 --- /dev/null +++ b/server/module-extras/video-sampler/debian/rules @@ -0,0 +1,9 @@ +#!/usr/bin/make -f + +#export DH_VERBOSE=1 + +%: + dh $@ + +override_dh_auto_configure: + dh_auto_configure -- -DGENERATE_TESTS=TRUE diff --git a/server/module-extras/video-sampler/hooks/pre-commit.hook b/server/module-extras/video-sampler/hooks/pre-commit.hook new file mode 100755 index 0000000000..80bc8de0d2 --- /dev/null +++ b/server/module-extras/video-sampler/hooks/pre-commit.hook @@ -0,0 +1,118 @@ +#!/bin/bash +# +# Check that the code follows a consistant code style +# + +# Check for existence of indent, and error out if not present. +# On some *bsd systems the binary seems to be called gnunindent, +# so check for that first. + +version=`gnuindent --version 2>/dev/null` +if test "x$version" = "x"; then + version=`indent --version 2>/dev/null` + if test "x$version" = "x"; then + echo "Kurento git pre-commit hook:" + echo "Did not find GNU indent, please install it before continuing." + exit 1 + fi + INDENT=indent +else + INDENT=gnuindent +fi + +case `$INDENT --version` in + GNU*) + ;; + default) + echo "Kurento git pre-commit hook:" + echo "Did not find GNU indent, please install it before continuing." + echo "(Found $INDENT, but it doesn't seem to be GNU indent)" + exit 1 + ;; +esac + +INDENT_PARAMETERS="--braces-on-if-line\ + --case-brace-indentation0\ + --case-indentation2\ + --braces-after-struct-decl-line\ + --line-length80\ + --no-tabs\ + --cuddle-else\ + --dont-line-up-parentheses\ + --continuation-indentation4\ + --tab-size8\ + --indent-level2\ + --leave-preprocessor-space\ + --swallow-optional-blank-lines\ + --blank-lines-after-declarations\ + --blank-lines-after-procedures" + +function version { + echo "$@" | awk -F. '{ printf("%d%03d%03d\n", $1,$2,$3); }'; +} + +ASTYLE_VERSION=$(astyle --version 2>&1) + +VERSION=$(echo ${ASTYLE_VERSION##* }) + +if [ $(version $VERSION) -eq 0 ]; then + echo "Kurento git pre-commit hook:" + echo "Did not find astyle, please install it before continuing." + exit 1 +fi + +ASTYLE_PARAMS="--style=linux\ + --indent=spaces=2\ + --indent-preprocessor\ + --min-conditional-indent=2\ + --break-blocks\ + --pad-oper\ + --pad-paren-out\ + --convert-tabs\ + --align-pointer=name\ + --lineend=linux\ + --break-blocks\ + --max-code-length=80\ + --add-brackets" + +if [ $(version $VERSION) -ge $(version "2.02") ]; then + ASTYLE_PARAMS="$ASTYLE_PARAMS --align-reference=name" +fi + +echo "--Checking style--" +for file in `git diff-index --cached --name-only HEAD --diff-filter=ACMR| grep "\.\(c\(pp\)\?\|\(hpp\)\)$"` ; do + # nf is the temporary checkout. This makes sure we check against the + # revision in the index (and not the checked out version). + nf=`git checkout-index --temp ${file} | cut -f 1` + newfile=`mktemp /tmp/${nf}.XXXXXX` || exit 1 + if [ "$(echo "$file" | grep -e "\.\(\(cpp\)\|\(hpp\)\)$")" ]; then + astyle ${ASTYLE_PARAMS} < ${nf} > ${newfile} 2>> /dev/null + FIX_COMMAND="astyle ${ASTYLE_PARAMS} $file; git add $file; git commit" + else + $INDENT ${INDENT_PARAMETERS} \ + $nf -o $newfile 2>> /dev/null + # FIXME: Call indent twice as it tends to do line-breaks + # different for every second call. + $INDENT ${INDENT_PARAMETERS} \ + $newfile 2>> /dev/null + + FIX_COMMAND="$INDENT ${INDENT_PARAMETERS} $file; git add $file; git commit" + fi + diff -u -p "${nf}" "${newfile}" + r=$? + rm "${newfile}" + rm "${nf}" + if [ $r != 0 ] ; then +echo "=================================================================================================" +echo " Code style error in: $file " +echo " " +echo " Please fix before committing. Don't forget to run git add before trying to commit again. " +echo " If the whole file is to be committed, this should work (run from the top-level directory): " +echo " " +echo " $FIX_COMMAND" +echo " " +echo "=================================================================================================" + exit 1 + fi +done +echo "--Checking style pass--" diff --git a/server/module-extras/video-sampler/src/CMakeLists.txt b/server/module-extras/video-sampler/src/CMakeLists.txt new file mode 100644 index 0000000000..6b0969ad86 --- /dev/null +++ b/server/module-extras/video-sampler/src/CMakeLists.txt @@ -0,0 +1,2 @@ +add_subdirectory(server) +add_subdirectory(gst-plugins) diff --git a/server/module-extras/video-sampler/src/gst-plugins/CMakeLists.txt b/server/module-extras/video-sampler/src/gst-plugins/CMakeLists.txt new file mode 100644 index 0000000000..de8c785ca6 --- /dev/null +++ b/server/module-extras/video-sampler/src/gst-plugins/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(videosampler) diff --git a/server/module-extras/video-sampler/src/gst-plugins/videosampler/CMakeLists.txt b/server/module-extras/video-sampler/src/gst-plugins/videosampler/CMakeLists.txt new file mode 100644 index 0000000000..f86f95d266 --- /dev/null +++ b/server/module-extras/video-sampler/src/gst-plugins/videosampler/CMakeLists.txt @@ -0,0 +1,33 @@ +set(VIDEOSAMPLER_SOURCES + videosampler.c + kmsvideosampler.c + kmsvideosampler.h +) + +add_library(videosampler MODULE ${VIDEOSAMPLER_SOURCES}) +if(SANITIZERS_ENABLED) + add_sanitizers(chroma) +endif() + +target_include_directories(videosampler SYSTEM + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${KMSCORE_INCLUDE_DIRS} + ${KmsGstCommons_INCLUDE_DIRS} + ${GSTREAMER_INCLUDE_DIRS} + ${GSTREAMER_VIDEO_INCLUDE_DIRS} +) + +target_link_libraries(videosampler + PRIVATE + ${KmsGstCommons_LIBRARIES} + ${GSTREAMER_LIBRARIES} + ${GSTREAMER_VIDEO_LIBRARIES} +) + +install( + TARGETS videosampler + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_GST_PLUGINS_DIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} +) diff --git a/server/module-extras/video-sampler/src/gst-plugins/videosampler/kmsvideosampler.c b/server/module-extras/video-sampler/src/gst-plugins/videosampler/kmsvideosampler.c new file mode 100644 index 0000000000..1a3d59c636 --- /dev/null +++ b/server/module-extras/video-sampler/src/gst-plugins/videosampler/kmsvideosampler.c @@ -0,0 +1,504 @@ +/* + * (C) Copyright 2023 Kurento (https://kurento.openvidu.io/) + * + * 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. + */ +#define _XOPEN_SOURCE 500 + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "kmsvideosampler.h" + +#include + +#include +#include + +#define MAX_FRAMES_STORED "50" +#define VIDEO_LEG_BIN " capsfilter caps=\"video/x-raw\" ! agnosticbin ! capsfilter name=\"video\" caps=\"%s\" ! tee name=t ! queue leaky=1 max-size-buffers=2 t. ! queue leaky=1 max-size-buffers="MAX_FRAMES_STORED" ! agnosticbin ! capsfilter name=\"encoder\" caps=\"%s\" ! appsink async=false sync=false emit-signals=true name=\"sink\"" + +#define PLUGIN_NAME "videosampler" + +GST_DEBUG_CATEGORY_STATIC (kms_videosampler_debug_category); +#define GST_CAT_DEFAULT kms_videosampler_debug_category + + +#define KMS_VIDEOSAMPLER_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((obj), KMS_TYPE_VIDEOSAMPLER, KmsVideoSamplerPrivate)) + +struct _KmsVideoSamplerPrivate { + gulong frame_period; + gulong height; + gulong width; + gchar* encoding; + gboolean finished; + + gulong appsink_signal; + + GstElement *video_leg; +}; + +/* Object properties */ +enum +{ + PROP_0, + PROP_FRAME_PERIOD, + PROP_HEIGHT, + PROP_WIDTH, + PROP_IMAGE_ENCODING, + N_PROPERTIES +}; + +static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, }; + + +enum { + FRAME_SAMPLE, + N_SIGNALS +}; + +static guint my_class_signals[N_SIGNALS]; + +/* class initialization */ + +G_DEFINE_TYPE_WITH_CODE (KmsVideoSampler, + kms_videosampler, + KMS_TYPE_ELEMENT, + GST_DEBUG_CATEGORY_INIT (kms_videosampler_debug_category, + PLUGIN_NAME, + 0, + "debug category for video sampler element")); + + +static void +kms_videosampler_connect_passthrough (KmsVideoSampler * self, + KmsElementPadType type, GstElement * agnosticbin) +{ + GstPad *target = gst_element_get_static_pad (agnosticbin, "sink"); + + kms_element_connect_sink_target (KMS_ELEMENT (self), target, type); + gst_object_unref (target); +} + +gboolean +send_buffer (GstBuffer ** buffer, guint idx, gpointer data) +{ + KmsVideoSampler *self = KMS_VIDEOSAMPLER (data); + GstMapInfo map; + + if (gst_buffer_map(*buffer, &map, GST_MAP_READ)) { + GByteArray *byte_array = g_byte_array_new(); + + g_byte_array_append (byte_array, map.data, map.size); + g_signal_emit(self, my_class_signals[FRAME_SAMPLE], 0, byte_array); + g_byte_array_unref(byte_array); + gst_buffer_unmap(*buffer, &map); + } + return TRUE; +} + +static GstFlowReturn +kms_videosampler_handle_sample (GstElement * appsink, gpointer data) +{ + GstSample *sample; + KmsVideoSampler *self = KMS_VIDEOSAMPLER (data); + + KMS_VIDEOSAMPLER_LOCK(self); + if (self->priv->finished) { + KMS_VIDEOSAMPLER_UNLOCK(self); + return GST_FLOW_OK; + } + g_signal_emit_by_name (appsink, "pull-sample", &sample); + if (sample != NULL) { + GstBuffer *buff = gst_sample_get_buffer (sample); + + if (buff != NULL) { + send_buffer (&buff, 0, self); + } else { + GstBufferList *buffer_list = gst_sample_get_buffer_list (sample); + + if (buffer_list != NULL) { + gst_buffer_list_foreach (buffer_list, send_buffer, self); + } + } + gst_sample_unref (sample); + } + KMS_VIDEOSAMPLER_UNLOCK(self); + + return GST_FLOW_OK; +} + +static gulong +kms_videosampler_connect_appsink (KmsVideoSampler *self) +{ + GstElement *appsink; + gulong signal_id; + + if (self->priv->video_leg == NULL) { + return 0; + } + + appsink = gst_bin_get_by_name (GST_BIN(self->priv->video_leg), "sink"); + signal_id = g_signal_connect (G_OBJECT (appsink), "new-sample", + G_CALLBACK (kms_videosampler_handle_sample), self); + + return signal_id; +} + +static gchar* +kms_video_sampler_calculate_framerate (KmsVideoSampler *self) +{ + if (self->priv->frame_period > 0) { + gchar* fr_str; + gfloat period = self->priv->frame_period; + gfloat freq = 1000.0 / period; // frame_period is measured in miliseconds + guint freq_uint = roundf (freq * 100.0); + + // Ensure no frequency less than 0 is allowed + if (freq_uint <= 0) { + freq_uint = 0; + } + fr_str = g_strdup_printf ("%d/100", freq_uint); + return fr_str; + } else { + return NULL; + } +} + +static gchar* +kms_video_sampler_calculate_video_caps (KmsVideoSampler *self) +{ + gchar *framerate_str = NULL; + GString *caps; + gchar *caps_str; + + framerate_str = kms_video_sampler_calculate_framerate (self); + caps = g_string_new ("video/x-raw"); + if (framerate_str != NULL) { + g_string_append (caps, ",framerate="); + g_string_append (caps, framerate_str); + g_free (framerate_str); + } + if (self->priv->height > 0) { + gchar *number = g_strdup_printf ("%ld", self->priv->height); + g_string_append (caps, ",height="); + g_string_append (caps, number); + g_free (number); + } + if (self->priv->width > 0) { + gchar *number = g_strdup_printf ("%ld", self->priv->width); + g_string_append (caps, ",width="); + g_string_append (caps, number); + g_free (number); + } + caps_str = g_strdup_printf ("%s", caps->str); + g_string_free (caps, TRUE); + return caps_str; +} + +static gchar* +kms_video_sampler_calculate_encoder (KmsVideoSampler *self) +{ + gchar* encoder; + + if (self->priv->encoding == NULL) { + encoder = g_strdup_printf("%s", "video/x-raw"); + }else if (g_str_equal (self->priv->encoding, "PNG")){ + encoder = g_strdup_printf("%s", "image/png"); + } else if (g_str_equal (self->priv->encoding, "JPEG")){ + encoder = g_strdup_printf("%s", "image/jpeg"); + } else if (g_str_equal (self->priv->encoding, "BMP")){ + encoder = g_strdup_printf("%s", "image/bmp"); + } else if (g_str_equal (self->priv->encoding, "PBM")){ + encoder = g_strdup_printf("%s", "image/pbm"); + } else if (g_str_equal (self->priv->encoding, "PPM")){ + encoder = g_strdup_printf("%s", "image/ppm"); + } else { + encoder = g_strdup_printf("%s", "video/x-raw"); + } + + return encoder; +} + + + +static gchar* +kms_videosampler_create_description (KmsVideoSampler *self) +{ + gchar* video_caps = kms_video_sampler_calculate_video_caps (self); + gchar* encoder_class = kms_video_sampler_calculate_encoder (self); + gchar* description; + + description = g_strdup_printf (VIDEO_LEG_BIN, video_caps, encoder_class); + g_free (video_caps); + g_free (encoder_class); + return description; +} + + + +static void +kms_videosampler_connect_video_leg (KmsVideoSampler *self) +{ + gchar *description = kms_videosampler_create_description (self); + GError *error= NULL; + GstElement *output; + + output = kms_element_get_video_agnosticbin (KMS_ELEMENT (self)); + self->priv->video_leg = gst_parse_bin_from_description (description, TRUE, &error); + if (error != NULL) { + GST_WARNING_OBJECT (self, "Cannot create video leg, no video will be provided"); + kms_videosampler_connect_passthrough (self, KMS_ELEMENT_PAD_TYPE_VIDEO, output); + self->priv->video_leg = NULL; + } else { + gst_bin_add (GST_BIN (self), gst_object_ref(self->priv->video_leg)); + gst_element_sync_state_with_parent (self->priv->video_leg); + gst_element_link (self->priv->video_leg, output); + kms_videosampler_connect_passthrough (self, KMS_ELEMENT_PAD_TYPE_VIDEO, + self->priv->video_leg); + } + g_free (description); +} + +static void +kms_videosampler_init (KmsVideoSampler *self) +{ + self->priv = KMS_VIDEOSAMPLER_GET_PRIVATE (self); + + self->priv->frame_period = 0; + self->priv->height = 0; + self->priv->width = 0; + self->priv->encoding = NULL; + self->priv->video_leg = NULL; + self->priv->finished = FALSE; + + g_mutex_init (&self->mutex); + + kms_videosampler_connect_passthrough (self, KMS_ELEMENT_PAD_TYPE_AUDIO, + kms_element_get_audio_agnosticbin (KMS_ELEMENT (self))); + + kms_videosampler_connect_video_leg (self); + self->priv->appsink_signal = kms_videosampler_connect_appsink (self); +} + +static void +kms_videosampler_update_video_caps (KmsVideoSampler *self) +{ + gchar* video_caps = kms_video_sampler_calculate_video_caps (self); + GstElement *capsfilter = gst_bin_get_by_name (GST_BIN(self->priv->video_leg), "video"); + GstCaps *caps = gst_caps_from_string(video_caps); + + g_object_set (capsfilter, "caps", caps, NULL); + gst_caps_unref (caps); + gst_object_unref (capsfilter); + g_free (video_caps); +} + +static void +kms_videosampler_update_frame_period (KmsVideoSampler *self) +{ + kms_videosampler_update_video_caps(self); +} + +static void +kms_videosampler_update_height (KmsVideoSampler *self) +{ + kms_videosampler_update_video_caps(self); +} + +static void +kms_videosampler_update_width (KmsVideoSampler *self) +{ + kms_videosampler_update_video_caps(self); +} + +static void +kms_videosampler_update_image_encoding (KmsVideoSampler *self) +{ + gchar* encoder_class = kms_video_sampler_calculate_encoder (self); + GstElement *capsfilter = gst_bin_get_by_name (GST_BIN(self->priv->video_leg), "encoder"); + GstCaps *caps = gst_caps_from_string(encoder_class); + + g_object_set (capsfilter, "caps", caps, NULL); + gst_caps_unref (caps); + gst_object_unref (capsfilter); + g_free (encoder_class); +} + + +static void +kms_videosampler_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + KmsVideoSampler *self = KMS_VIDEOSAMPLER (object); + gint v; + + KMS_ELEMENT_LOCK (KMS_ELEMENT (self)); + switch (property_id) { + case PROP_FRAME_PERIOD: + v = g_value_get_int (value); + if (self->priv->frame_period != v) { + self->priv->frame_period = v; + kms_videosampler_update_frame_period (self); + } + break; + case PROP_HEIGHT: + v = g_value_get_int (value); + if (self->priv->height != v) { + self->priv->height = v; + kms_videosampler_update_height (self); + } + break; + case PROP_WIDTH: + v = g_value_get_int (value); + if (self->priv->width != v) { + self->priv->width = v; + kms_videosampler_update_width (self); + } + break; + case PROP_IMAGE_ENCODING: + { + gchar *enc; + + enc = g_value_dup_string (value); + if (enc != NULL) { + if ((self->priv->encoding == NULL) || (!g_str_equal(enc, self->priv->encoding))) { + self->priv->encoding = enc; + kms_videosampler_update_image_encoding (self); + } else { + g_free(enc); + } + } + } + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } + KMS_ELEMENT_UNLOCK(KMS_ELEMENT (self)); +} + +static void +kms_videosampler_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + KmsVideoSampler *self = KMS_VIDEOSAMPLER (object); + + KMS_ELEMENT_LOCK (KMS_ELEMENT (self)); + switch (property_id) { + case PROP_FRAME_PERIOD: + g_value_set_int (value, self->priv->frame_period); + break; + case PROP_HEIGHT: + g_value_set_int (value, self->priv->height); + break; + case PROP_WIDTH: + g_value_set_int (value, self->priv->width); + break; + case PROP_IMAGE_ENCODING: + g_value_set_string (value, self->priv->encoding); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } + KMS_ELEMENT_UNLOCK (KMS_ELEMENT (self)); +} + + +void +kms_videosampler_finalize (GObject * object) +{ + KmsVideoSampler *self = KMS_VIDEOSAMPLER (object); + GstElement *appsink; + + + + GST_DEBUG_OBJECT (self, "finalize"); + + /* clean up object here */ + KMS_VIDEOSAMPLER_LOCK (self); + self->priv->finished = TRUE; + if (self->priv->video_leg != NULL) { + if (self->priv->appsink_signal != 0) { + appsink = gst_bin_get_by_name (GST_BIN(self->priv->video_leg), "sink"); + g_signal_handler_disconnect (appsink, self->priv->appsink_signal); + gst_object_unref (appsink); + } + } + KMS_VIDEOSAMPLER_UNLOCK (self); + if (self->priv->encoding != NULL) { + g_free (self->priv->encoding); + self->priv->encoding = NULL; + } + if (self->priv->video_leg != NULL) { + gst_object_unref (self->priv->video_leg); + self->priv->video_leg = NULL; + } + + G_OBJECT_CLASS (kms_videosampler_parent_class)->finalize (object); +} + +static void +kms_videosampler_class_init (KmsVideoSamplerClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gst_element_class_set_static_metadata (GST_ELEMENT_CLASS (klass), + "video sampler element", "Video/Filter", + "Retrieves frames from video stream with a certaing period", + "Saúl Labajo "); + + gobject_class->set_property = kms_videosampler_set_property; + gobject_class->get_property = kms_videosampler_get_property; + gobject_class->finalize = kms_videosampler_finalize; + + obj_properties[PROP_FRAME_PERIOD] = g_param_spec_int ("frame-period", "frame-period", + "Period in millilseconds between consecutive frames", 0, G_MAXINT, 0, G_PARAM_READWRITE); + obj_properties[PROP_HEIGHT] = g_param_spec_int ("height", "height", + "Height of generated images", 0, G_MAXINT, 0, G_PARAM_READWRITE); + obj_properties[PROP_WIDTH] = g_param_spec_int ("width", "width", + "WIdth of generated images", 0, G_MAXINT, 0, G_PARAM_READWRITE); + obj_properties[PROP_IMAGE_ENCODING] = g_param_spec_string ("image-encoding", "image-encoding", + "Encoding used on generated images", NULL, + G_PARAM_READWRITE | GST_PARAM_MUTABLE_READY); + + g_object_class_install_properties (gobject_class, + N_PROPERTIES, obj_properties); + + my_class_signals[FRAME_SAMPLE] = g_signal_new( + "frame-sample", + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, + NULL, + g_cclosure_marshal_VOID__BOXED, + G_TYPE_NONE, + 1, + G_TYPE_BYTE_ARRAY + ); + + g_type_class_add_private (klass, sizeof (KmsVideoSamplerPrivate)); +} + +gboolean +kms_videosampler_plugin_init (GstPlugin *plugin) +{ + return gst_element_register (plugin, PLUGIN_NAME, GST_RANK_NONE, + KMS_TYPE_VIDEOSAMPLER); +} diff --git a/server/module-extras/video-sampler/src/gst-plugins/videosampler/kmsvideosampler.h b/server/module-extras/video-sampler/src/gst-plugins/videosampler/kmsvideosampler.h new file mode 100644 index 0000000000..fff6fb2e3f --- /dev/null +++ b/server/module-extras/video-sampler/src/gst-plugins/videosampler/kmsvideosampler.h @@ -0,0 +1,83 @@ +/* + * (C) Copyright 2013 Kurento (http://kurento.org/) + * + * 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. + * + */ + +#ifndef _KMS_VIDEOSAMPLER_H_ +#define _KMS_VIDEOSAMPLER_H_ + +#include + +G_BEGIN_DECLS +#define KMS_TYPE_VIDEOSAMPLER (kms_videosampler_get_type()) +#define KMS_VIDEOSAMPLER(obj) ( \ + G_TYPE_CHECK_INSTANCE_CAST( \ + (obj), \ + KMS_TYPE_VIDEOSAMPLER, \ + KmsVideoSampler \ + ) \ +) +#define KMS_VIDEOSAMPLER_CLASS(klass) ( \ + G_TYPE_CHECK_CLASS_CAST( \ + (klass), \ + KMS_TYPE_VIDEOSAMPLER, \ + KmsVideoSamplerClass \ + ) \ +) +#define KMS_IS_VIDEOSAMPLER(obj) ( \ + G_TYPE_CHECK_INSTANCE_TYPE( \ + (obj), \ + KMS_TYPE_VIDEOSAMPLER \ + ) \ +) +#define KMS_IS_VIDEOSAMPLER_CLASS(klass) ( \ + G_TYPE_CHECK_CLASS_TYPE( \ + (klass), \ + KMS_TYPE_VIDEOSAMPLER \ + ) \ +) + +#define KMS_VIDEOSAMPLER_CAST(obj) ((KmsVideoSampler*)(obj)) + +#define KMS_VIDEOSAMPLER_LOCK(elem) \ + (g_mutex_lock (&KMS_VIDEOSAMPLER_CAST ((elem))->mutex)) +#define KMS_VIDEOSAMPLER_UNLOCK(elem) \ + (g_mutex_unlock (&KMS_VIDEOSAMPLER_CAST ((elem))->mutex)) + + + +typedef struct _KmsVideoSampler KmsVideoSampler; +typedef struct _KmsVideoSamplerClass KmsVideoSamplerClass; +typedef struct _KmsVideoSamplerPrivate KmsVideoSamplerPrivate; + +struct _KmsVideoSampler +{ + KmsElement parent; + KmsVideoSamplerPrivate *priv; + GMutex mutex; +}; + +struct _KmsVideoSamplerClass +{ + KmsElementClass parent_class; +}; + +GType kms_videosampler_get_type (void); + +gboolean kms_videosampler_plugin_init (GstPlugin * plugin); + +G_END_DECLS + +#endif /* _KMS_VIDEOSAMPLER_H_ */ diff --git a/server/module-extras/video-sampler/src/gst-plugins/videosampler/videosampler.c b/server/module-extras/video-sampler/src/gst-plugins/videosampler/videosampler.c new file mode 100644 index 0000000000..4d22e5dfc3 --- /dev/null +++ b/server/module-extras/video-sampler/src/gst-plugins/videosampler/videosampler.c @@ -0,0 +1,39 @@ +/* + * (C) Copyright 2013 Kurento (http://kurento.org/) + * + * 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 +#include + +#include "kmsvideosampler.h" + +static gboolean +init (GstPlugin *plugin) +{ + if (!kms_videosampler_plugin_init (plugin)) + return FALSE; + + return TRUE; +} + +GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, + GST_VERSION_MINOR, + videosampler, + "Kurento VideoSampler filter", + init, + VERSION, + GST_LICENSE_UNKNOWN, + "Kurento", + "https://kurento.openvidu.io/") diff --git a/server/module-extras/video-sampler/src/server/CMakeLists.txt b/server/module-extras/video-sampler/src/server/CMakeLists.txt new file mode 100644 index 0000000000..1e0fb6fee7 --- /dev/null +++ b/server/module-extras/video-sampler/src/server/CMakeLists.txt @@ -0,0 +1,37 @@ +set(PROTO_FILES + proto/videoSampler/sampleImage.proto +) + + +set(PROTO_SRC_DIR ${CMAKE_CURRENT_BINARY_DIR}/proto-src) +file(MAKE_DIRECTORY ${PROTO_SRC_DIR}) +include_directories(${PROTO_SRC_DIR}) + +protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS ${PROTO_FILES}) +grpc_generate_cpp(GRPC_SRCS GRPC_HDRS ${PROTO_SRC_DIR} ${PROTO_FILES}) + + +include(CodeGenerator) + +generate_code( + MODELS ${CMAKE_CURRENT_SOURCE_DIR}/interface + SERVER_IMPL_LIB_EXTRA_SOURCES + ${PROTO_SRCS} + ${GRPC_SRCS} + SERVER_IMPL_LIB_EXTRA_INCLUDE_DIRS + ${CMAKE_CURRENT_BINARY_DIR}/.. + ${CMAKE_CURRENT_BINARY_DIR} + ${PROTO_SRC_DIR} + ${VIDEOSAMPLER_PROTO_INCLUDE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/implementation + SERVER_IMPL_LIB_EXTRA_LIBRARIES + ${VIDEOSAMPLER_PROTO_LIB_DIR} + gRPC::grpc++_reflection + gRPC::grpc++ + gRPC::grpc + protobuf::libprotobuf + MODULE_EXTRA_INCLUDE_DIRS + ${PROTO_SRC_DIR} + SERVER_STUB_DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/implementation/objects +) + diff --git a/server/module-extras/video-sampler/src/server/implementation/objects/VideoSamplerImpl.cpp b/server/module-extras/video-sampler/src/server/implementation/objects/VideoSamplerImpl.cpp new file mode 100644 index 0000000000..051c57fe22 --- /dev/null +++ b/server/module-extras/video-sampler/src/server/implementation/objects/VideoSamplerImpl.cpp @@ -0,0 +1,209 @@ +/* + * (C) Copyright 2016 Kurento (http://kurento.org/) + * + * 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 +#include "MediaPipeline.hpp" +#include "MediaPipelineImpl.hpp" +#include +#include "VideoSamplerImpl.hpp" +#include +#include + +#include +#include + + + +#define GST_CAT_DEFAULT kurento_video_sampler_impl +GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); +#define GST_DEFAULT_NAME "KurentoVideoSamplerImpl" + +#define FACTORY_NAME "videosampler" + +using grpc::Channel; +using grpc::ClientContext; +using grpc::Status; +using videoSampler::SampleImage; +using videoSampler::Empty; +using videoSampler::ImageDeliver; + + + +class VideoSamplerGRPC: public kurento::module::videosampler::VideoSamplerImpl +{ + public: + VideoSamplerGRPC (const boost::property_tree::ptree &config, + std::shared_ptr mediaPipeline, + int framePeriod, + std::shared_ptr imageDeliveryMethod, + int height, + int width, + std::shared_ptr imageEncoding, + std::string endpointUrl); + + bool send_frame_data (guint8* data, guint len); + void sendImageDeliveredEvent (bool delivered); + + ~VideoSamplerGRPC (); + + + private: + std::shared_ptr imageDeliverStub; + gulong frameSampleId = 0; + + +}; + +static void +kms_videosampler_handle_sample(gpointer obj, GByteArray *byte_array, VideoSamplerGRPC *self) +{ + if (byte_array->len > 0) { + bool delivered = self->send_frame_data(byte_array->data, byte_array->len); + self->sendImageDeliveredEvent(delivered); + } +} + +VideoSamplerGRPC::VideoSamplerGRPC (const boost::property_tree::ptree &config, + std::shared_ptr mediaPipeline, + int framePeriod, + std::shared_ptr imageDeliveryMethod, + int height, + int width, + std::shared_ptr imageEncoding, + std::string endpointUrl): VideoSamplerImpl (config, mediaPipeline, framePeriod, imageDeliveryMethod, height, width, imageEncoding, endpointUrl) +{ + imageDeliverStub = nullptr; + g_object_set(element, "frame-period", msFramePeriod, + "height", height, + "width", width, + "image-encoding", encoding->getString().c_str(), + NULL); + if (getEndpointUrl() != "") { + std::shared_ptr channel = grpc::CreateChannel (getEndpointUrl(),grpc::InsecureChannelCredentials()); + + if (channel != nullptr) { + imageDeliverStub = ImageDeliver::NewStub(channel); + + // Once the channel is established, we connect the signal + frameSampleId = g_signal_connect (G_OBJECT (element), "frame-sample", + G_CALLBACK (kms_videosampler_handle_sample), this); + } + } +} + + +bool +VideoSamplerGRPC::send_frame_data (guint8 *data, guint len) +{ + SampleImage request; + Empty reply; + ClientContext context; + Status status; + + request.set_codec (getEncodingStr()); + request.set_data (data, len); + + status = imageDeliverStub->deliverImage(&context, request, &reply); + + // Act upon its status. + if (!status.ok()) { + GST_WARNING_OBJECT (this, "Could not deliver image to gRPC, error %d, %s", status.error_code(), status.error_message().c_str()); + return false; + } + return true; +} + +void +VideoSamplerGRPC::sendImageDeliveredEvent (bool delivered) +{ + try { + kurento::module::videosampler::SampleImageDelivered event (shared_from_this (), kurento::module::videosampler::SampleImageDelivered::getName (), delivered); + sigcSignalEmit(signalSampleImageDelivered, event); + } catch (const std::bad_weak_ptr &e) { + // shared_from_this() + GST_ERROR_OBJECT (this, "BUG creating %s: %s", kurento::module::videosampler::SampleImageDelivered::getName ().c_str (), + e.what ()); + } +} + +VideoSamplerGRPC::~VideoSamplerGRPC () +{ + if (frameSampleId != 0L) { + g_signal_handler_disconnect (element, frameSampleId); + frameSampleId = 0L; + } +} + + + + + +namespace kurento +{ +namespace module +{ +namespace videosampler +{ + +VideoSamplerImpl::VideoSamplerImpl (const boost::property_tree::ptree &config, + std::shared_ptr mediaPipeline, + int framePeriod, + std::shared_ptr imageDeliveryMethod, + int h, + int w, + std::shared_ptr imageEncoding, + std::string url) : + MediaElementImpl (config, + std::dynamic_pointer_cast (mediaPipeline), + FACTORY_NAME ), + encoding(imageEncoding), + delivery(imageDeliveryMethod), + endpointUrl (url), + width(w), + height(h), + msFramePeriod(framePeriod) + +{ +} + + +MediaObjectImpl * +VideoSamplerImplFactory::createObject (const boost::property_tree::ptree &conf, + std::shared_ptr mediaPipeline, + int framePeriod, + std::shared_ptr imageDeliveryMethod, + int height, + int width, + std::shared_ptr imageEncoding, + const std::string &endpointUrl) const +{ + return new VideoSamplerGRPC (conf, mediaPipeline, framePeriod, imageDeliveryMethod, height, width, imageEncoding, endpointUrl); +} + + + +VideoSamplerImpl::StaticConstructor VideoSamplerImpl::staticConstructor; + +VideoSamplerImpl::StaticConstructor::StaticConstructor() +{ + GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, GST_DEFAULT_NAME, 0, + GST_DEFAULT_NAME); +} + +} /* videosampler */ +} /* module */ +} /* kurento */ diff --git a/server/module-extras/video-sampler/src/server/implementation/objects/VideoSamplerImpl.hpp b/server/module-extras/video-sampler/src/server/implementation/objects/VideoSamplerImpl.hpp new file mode 100644 index 0000000000..cb9057a064 --- /dev/null +++ b/server/module-extras/video-sampler/src/server/implementation/objects/VideoSamplerImpl.hpp @@ -0,0 +1,118 @@ +/* + * (C) Copyright 2016 Kurento (http://kurento.org/) + * + * 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. + * + */ + +#ifndef __VIDEO_SAMPLER_IMPL_HPP__ +#define __VIDEO_SAMPLER_IMPL_HPP__ + +#include "MediaElementImpl.hpp" +#include "VideoSampler.hpp" +#include +#include +#include +#include + + +namespace kurento +{ +namespace module +{ +namespace videosampler +{ +class VideoSamplerImpl; +} /* videosampler */ +} /* module */ +} /* kurento */ + +namespace kurento +{ +void Serialize (std::shared_ptr + &object, JsonSerializer &serializer); +} /* kurento */ + + +namespace kurento +{ +class MediaPipelineImpl; +} /* kurento */ + +namespace kurento +{ +namespace module +{ +namespace videosampler +{ + +class VideoSamplerImpl : public MediaElementImpl, public virtual VideoSampler +{ + +public: + + VideoSamplerImpl (const boost::property_tree::ptree &config, + std::shared_ptr mediaPipeline, + int framePeriod, + std::shared_ptr imageDeliveryMethod, + int height, + int width, + std::shared_ptr imageEncoding, + std::string endpointUrl); + + sigc::signal signalSampleImageDelivered; + + std::string getEncodingStr () { return encoding->getString(); } + std::string getEndpointUrl () { return endpointUrl; } + + + /* Next methods are automatically implemented by code generator */ + virtual bool connect (const std::string &eventType, + std::shared_ptr handler); + virtual void invoke (std::shared_ptr obj, + const std::string &methodName, const Json::Value ¶ms, + Json::Value &response); + + virtual void Serialize (JsonSerializer &serializer); + +protected: + void imageDelivered (); + + std::shared_ptr encoding; + std::shared_ptr delivery; + std::string endpointUrl; + int width; + int height; + int msFramePeriod; + + +private: + + gulong handlerImageDelivered = 0; + + + class StaticConstructor + { + public: + StaticConstructor(); + }; + + static StaticConstructor staticConstructor; + +}; + +} /* videosampler */ +} /* module */ +} /* kurento */ + +#endif /* __VIDEO_SAMPLER_IMPL_HPP__ */ diff --git a/server/module-extras/video-sampler/src/server/interface/package.json b/server/module-extras/video-sampler/src/server/interface/package.json new file mode 100644 index 0000000000..91436f72d2 --- /dev/null +++ b/server/module-extras/video-sampler/src/server/interface/package.json @@ -0,0 +1,8 @@ +{ + "license": "ALv2", + "homepage": "https://kurento.openvidu.io/", + "author": "Kurento (https://kurento.openvidu.io/)", + "bugs": { + "email": "kurento@openvidu.io" + } +} diff --git a/server/module-extras/video-sampler/src/server/interface/pom.xml b/server/module-extras/video-sampler/src/server/interface/pom.xml new file mode 100644 index 0000000000..2990d1e51e --- /dev/null +++ b/server/module-extras/video-sampler/src/server/interface/pom.xml @@ -0,0 +1,31 @@ + + 4.0.0 + + Kurento Video sampler module + https://kurento.openvidu.io/ + + + + Apache 2.0 + http://www.apache.org/licenses/LICENSE-2.0 + repo + + + + + + kurento.org + Kurento Community + Kurento + https://kurento.openvidu.io/ + + + + + https://github.com/Kurento/kurento + scm:git:https://github.com/Kurento/kurento.git + scm:git:ssh://github.com/Kurento/kurento.git + + + diff --git a/server/module-extras/video-sampler/src/server/interface/videosampler.VideoSampler.kmd.json b/server/module-extras/video-sampler/src/server/interface/videosampler.VideoSampler.kmd.json new file mode 100644 index 0000000000..06819aaa2d --- /dev/null +++ b/server/module-extras/video-sampler/src/server/interface/videosampler.VideoSampler.kmd.json @@ -0,0 +1,90 @@ +{ + "remoteClasses": [ + { + "name": "VideoSampler", + "extends": "MediaElement", + "doc": "VideoSampler interface. This type of :rom:cls:`Filter` samples at a configured rate frames from its video source and delivers it using gRPC to a configured destination.", + "constructor": { + "doc": "Create a :rom:cls:`VideoSampler`", + "params": [ + { + "name": "mediaPipeline", + "doc": "the :rom:cls:`MediaPipeline` to which the filter belongs", + "type": "MediaPipeline" + }, + { + "name": "framePeriod", + "doc": "Milliseconds between sampled images", + "type": "int" + }, + { + "name": "imageDeliveryMethod", + "doc": "Method used for image delivery, currently only gRPC supported", + "type": "ImageDelivery", + "optional": true, + "defaultValue": "NONE" + }, + { + "name": "height", + "doc": "Height of the sampled images, 0 to keep original", + "type": "int", + "optional": true, + "defaultValue": 0 + }, + { + "name": "width", + "doc": "Width of the sampled images, 0 to keep original", + "type": "int", + "optional": true, + "defaultValue": 0 + }, + { + "name": "imageEncoding", + "doc": "Encoding of the delivered images", + "type": "ImageEncoding", + "optional": true, + "defaultValue": "PNG" + }, + { + "name": "endpointUrl", + "doc": "gRPC endpoint where images wil be delivered.Set to empty string or invalir endpoint url to not send sampled imaged", + "type": "String", + "optional": true, + "defaultValue": "" + } + ] + }, + "events": [ + "SampleImageDelivered" + ] + } + ], + "events": [ + { + "properties": [ + { + "name": "delivered", + "doc": "Flag indicating if the image coudl be delivered or not", + "type": "boolean" + } + ], + "name": "SampleImageDelivered", + "extends": "Media", + "doc": "Notifies that a sample image has been delivered" + } + ], + "complexTypes": [ + { + "name": "ImageEncoding", + "typeFormat": "ENUM", + "values": [ "PNG", "JPEG", "BMP", "PBM", "PPM"], + "doc": "Enumerated representing different image encodings that may be used for image delivery" + }, + { + "name": "ImageDelivery", + "typeFormat": "ENUM", + "values": [ "NONE", "GRPC"], + "doc": "Enumerated representing different image delivery methods" + } + ] +} diff --git a/server/module-extras/video-sampler/src/server/interface/videosampler.kmd.json b/server/module-extras/video-sampler/src/server/interface/videosampler.kmd.json new file mode 100644 index 0000000000..0a03eb5602 --- /dev/null +++ b/server/module-extras/video-sampler/src/server/interface/videosampler.kmd.json @@ -0,0 +1,14 @@ +{ + "name": "videosampler", + "version": "7.1.1-dev", + "kurentoVersion": "^7.1.0", + "code": { + "api": { + "js": { + "nodeName": "kurento-module-videosampler", + "npmDescription": "JavaScript Client API for Kurento Media Server", + "npmGit": "https://github.com/Kurento/kurento-module-videosampler-js.git" + } + } + } +} diff --git a/server/module-extras/video-sampler/src/server/proto/CMakeLists.txt b/server/module-extras/video-sampler/src/server/proto/CMakeLists.txt new file mode 100644 index 0000000000..e2d7e21eaa --- /dev/null +++ b/server/module-extras/video-sampler/src/server/proto/CMakeLists.txt @@ -0,0 +1,30 @@ +# +# Protobuf/Grpc source files +# +set(PROTO_FILES + videoSampler/sampleImage.proto +) + +# +# Add Library target with protobuf sources +# +#add_library(videoSampler ${PROTO_FILES}) +#target_link_libraries(videoSampler +# PUBLIC +# protobuf::libprotobuf +# gRPC::grpc +# gRPC::grpc++ +#) +#target_include_directories(videoSampler PUBLIC ${CMAKE_CURRENT_BINARY_DIR}) + +# +# Compile protobuf and grpc files in myproto target to cpp +# +#get_target_property(grpc_cpp_plugin_location gRPC::grpc_cpp_plugin LOCATION) +#protobuf_generate(TARGET videoSampler LANGUAGE cpp) +#protobuf_generate(TARGET videoSampler LANGUAGE grpc GENERATE_EXTENSIONS .grpc.pb.h .grpc.pb.cpp PLUGIN "protoc-gen-grpc=${grpc_cpp_plugin_location}") + + +set(PROTO_SRC_DIR ${CMAKE_CURRENT_BINARY_DIR}/proto-src) +file(MAKE_DIRECTORY ${PROTO_SRC_DIR}) +include_directories(${PROTO_SRC_DIR}) diff --git a/server/module-extras/video-sampler/src/server/proto/videoSampler/sampleImage.proto b/server/module-extras/video-sampler/src/server/proto/videoSampler/sampleImage.proto new file mode 100644 index 0000000000..d584311d0d --- /dev/null +++ b/server/module-extras/video-sampler/src/server/proto/videoSampler/sampleImage.proto @@ -0,0 +1,15 @@ +syntax = "proto3"; + +package videoSampler; + +service ImageDeliver { + rpc deliverImage (SampleImage) returns (Empty) {} +} + +message SampleImage { + string codec = 1; + bytes data = 2; + string timestamp = 3; +} + +message Empty { } \ No newline at end of file diff --git a/server/module-extras/video-sampler/tests/CMakeLists.txt b/server/module-extras/video-sampler/tests/CMakeLists.txt new file mode 100644 index 0000000000..9a84b352a6 --- /dev/null +++ b/server/module-extras/video-sampler/tests/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(server) diff --git a/server/module-extras/video-sampler/tests/server/CMakeLists.txt b/server/module-extras/video-sampler/tests/server/CMakeLists.txt new file mode 100644 index 0000000000..1344a70533 --- /dev/null +++ b/server/module-extras/video-sampler/tests/server/CMakeLists.txt @@ -0,0 +1,46 @@ +set(TEST_VARIABLES + "GST_PLUGIN_PATH=$ENV{GST_PLUGIN_PATH}:${CMAKE_BINARY_DIR}:${CMAKE_BINARY_DIR}/src" + "KURENTO_MODULES_PATH=${CMAKE_BINARY_DIR}:${CMAKE_BINARY_DIR}/src:$ENV{KURENTO_MODULES_PATH}" + "GST_DEBUG=2,KurentoModule*:4" +) +set(VALGRIND_TEST_VARIABLES + "${TEST_VARIABLES}" + "DEBUG_MEDIASET=TRUE" +) +list(APPEND SUPPRESSIONS + "${CMAKE_CURRENT_SOURCE_DIR}/valgrind.supp") + +if (Boost_FOUND) + include_directories(${Boost_INCLUDE_DIRS}) + + message("Boost VERSION: ${Boost_VERSION}") + message("Boost INCLUDE_DIRS: ${Boost_INCLUDE_DIRS}") + message("Boost Boost_LIBRARY_DIRS: ${Boost_LIBRARY_DIRS}") + message("Boost LIBRARIES: ${Boost_SYSTEM_LIBRARY}") +endif () + +add_test_program(test_videosampler videosampler.cpp ) +set_property(TARGET test_videosampler + PROPERTY INCLUDE_DIRECTORIES + ${KmsJsonRpc_INCLUDE_DIRS} + ${sigc++-2.0_INCLUDE_DIRS} + ${CMAKE_CURRENT_SOURCE_DIR}/../../src/server/implementation/objects + ${CMAKE_CURRENT_SOURCE_DIR}/../../src/server/implementation + ${CMAKE_CURRENT_SOURCE_DIR}/../../src/server/interface + ${CMAKE_CURRENT_BINARY_DIR}/../../src/server/interface/generated-cpp + ${CMAKE_CURRENT_BINARY_DIR}/../../src/server/implementation/generated-cpp + ${CMAKE_CURRENT_BINARY_DIR}/../../src/server/proto-src + ${CMAKE_CURRENT_BINARY_DIR}/../../src/server + ${KMSCORE_INCLUDE_DIRS} + ${KMSELEMENTS_INCLUDE_DIRS} + ${gstreamer-1.0_INCLUDE_DIRS} +) +target_link_libraries(test_videosampler + ${LIBRARY_NAME}impl + ${KMSCORE_LIBRARIES} + ${KMSELEMENTS_LIBRARIES} + ${Boost_FILESYSTEM_LIBRARY} + ${Boost_SYSTEM_LIBRARY} +) + + diff --git a/server/module-extras/video-sampler/tests/server/videosampler.cpp b/server/module-extras/video-sampler/tests/server/videosampler.cpp new file mode 100644 index 0000000000..a9e6196e11 --- /dev/null +++ b/server/module-extras/video-sampler/tests/server/videosampler.cpp @@ -0,0 +1,318 @@ +#define BOOST_TEST_STATIC_LINK +#define BOOST_TEST_PROTECTED_VIRTUAL + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include + +#include +#include + + + +#define TEST_ENDPOINT "0.0.0.0:50051" + +kurento::ModuleManager moduleManager; + +namespace kurento +{ + ModuleManager& getModuleManager (); +} + + +kurento::ModuleManager& kurento::getModuleManager () +{ + return moduleManager; +} + + + +using namespace kurento; +using namespace kurento::module::videosampler; +using namespace boost::unit_test; +using namespace grpc; +using namespace videoSampler; + +boost::property_tree::ptree config; + +struct GF { + GF(); + ~GF(); +}; + +BOOST_GLOBAL_FIXTURE (GF); + +GF::GF() +{ + boost::property_tree::ptree ac, audioCodecs, vc, videoCodecs; + gst_init(nullptr, nullptr); + moduleManager.loadModulesFromDirectories ("../../src/server:./:../../../.."); + + config.add ("configPath", "../../../tests" ); + config.add ("modules.kurento.SdpEndpoint.numAudioMedias", 1); + config.add ("modules.kurento.SdpEndpoint.numVideoMedias", 1); + + ac.put ("name", "opus/48000/2"); + audioCodecs.push_back (std::make_pair ("", ac) ); + config.add_child ("modules.kurento.SdpEndpoint.audioCodecs", audioCodecs); + + vc.put ("name", "H264/90000"); + videoCodecs.push_back (std::make_pair ("", vc) ); + config.add_child ("modules.kurento.SdpEndpoint.videoCodecs", videoCodecs); +} + +GF::~GF() +{ + sleep (3); + MediaSet::deleteMediaSet(); +} + +static void +dumpPipeline (std::shared_ptr pipeline, std::string fileName) +{ + std::string pipelineDot; + std::shared_ptr details (new GstreamerDotDetails ("SHOW_ALL")); + + pipelineDot = pipeline->getGstreamerDot (details); + std::ofstream out(fileName); + + out << pipelineDot; + out.close (); + +} + +void +dumpPipeline (std::string pipelineId, std::string fileName) +{ + std::shared_ptr pipeline = std::dynamic_pointer_cast (MediaSet::getMediaSet ()->getMediaObject (pipelineId)); + dumpPipeline (pipeline, fileName); + +// MediaSet::getMediaSet ()->release (pipelineId); +} + +static void +checkPipelineEmpty (std::string pipelineId) +{ + std::shared_ptr pipeline = std::dynamic_pointer_cast (MediaSet::getMediaSet ()->getMediaObject (pipelineId)); + std::vector > elements = pipeline->getChildren (); + std::stringstream strStream; + + for (auto & elem : elements) { + BOOST_TEST_MESSAGE ("Still Media Element alive"); + BOOST_TEST_MESSAGE (elem->getId ()); + } + + if (!elements.empty ()) { + BOOST_TEST_MESSAGE ("It should not remain any media element"); + } else { + BOOST_TEST_MESSAGE ("Media pipeline empty"); + } + + strStream << pipelineId << "_final.dot"; + dumpPipeline (pipeline, strStream.str ()); + + //MediaSet::getMediaSet ()->release (pipeline->getId ()); +} + +static std::string +createPipeline () +{ + return moduleManager.getFactory ("MediaPipeline")->createObject ( + config, "", + Json::Value() )->getId(); +} + +static void +releasePipeline (std::string pipelineId) +{ + MediaSet::getMediaSet ()->release (pipelineId); +} + +class ImageDeliverImpl final : public ImageDeliver::Service { + public: + Status deliverImage(ServerContext* context, const SampleImage* request, Empty* response) + { + BOOST_TEST_MESSAGE ("Received image"); + std::string codec = request->codec(); + std::string data = request->data(); + + return ::grpc::Status::OK; + } + + std::unique_ptr server; +}; + + +static void +grpcServer (ImageDeliverImpl *service) +{ + std::string server_address(TEST_ENDPOINT); + + ServerBuilder builder; + // Listen on the given address without any authentication mechanism. + builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); + // Register "service" as the instance through which we'll communicate with + // clients. In this case it corresponds to an *synchronous* service. + builder.RegisterService(service); + // Finally assemble the server. + service->server = builder.BuildAndStart(); + //std::cout << "Server listening on " << server_address << std::endl; + + // Wait for the server to shutdown. Note that some other thread must be + // responsible for shutting down the server for this call to ever return. + service->server->Wait(); + +} + + +static std::shared_ptr +createVideoSampler (std::string mediaPipelineId) +{ + std::shared_ptr videosampler; + Json::Value constructorParams; + + constructorParams ["mediaPipeline"] = mediaPipelineId; + constructorParams ["framePeriod"] = 1000; + constructorParams ["imageDeliveryMethod"] = "GRPC"; + constructorParams ["height"] = 480; + constructorParams ["imageEncoding"] = "JPEG"; + constructorParams ["endpointUrl"] = TEST_ENDPOINT; + + + videosampler = moduleManager.getFactory ("VideoSampler")->createObject ( + config, "", + constructorParams ); + + return std::dynamic_pointer_cast (videosampler); +} + +static void +releaseVideoSampler (std::shared_ptr subscriber) +{ + std::string id = std::dynamic_pointer_cast (subscriber)->getId(); + + subscriber.reset(); + MediaSet::getMediaSet ()->release (id); +} + +static std::shared_ptr createTestSrc(std::string mediaPipelineId) { + std::shared_ptr src = std::dynamic_pointer_cast + (MediaSet::getMediaSet()->ref (new MediaElementImpl ( + boost::property_tree::ptree(), + MediaSet::getMediaSet()->getMediaObject (mediaPipelineId), + "dummysrc") ) ); + + g_object_set (src->getGstreamerElement(), "audio", TRUE, "video", TRUE, NULL); + + return std::dynamic_pointer_cast (src); +} + +static void +releaseTestElement (std::shared_ptr &ep) +{ + std::string id = ep->getId(); + + ep.reset(); + MediaSet::getMediaSet ()->release (id); +} + + + +static std::shared_ptr +createPassThrough (std::string mediaPipelineId) +{ + std::shared_ptr pt; + Json::Value constructorParams; + + constructorParams ["mediaPipeline"] = mediaPipelineId; + + pt = moduleManager.getFactory ("PassThrough")->createObject ( + config, "", + constructorParams ); + + return std::dynamic_pointer_cast (pt); +} + +static void +releasePassTrhough (std::shared_ptr &ep) +{ + std::string id = ep->getId(); + + ep.reset(); + MediaSet::getMediaSet ()->release (id); +} + + +static void +test_videosampler () +{ + std::atomic media_state_changed (false); + std::condition_variable cv; + std::mutex mtx; + std::unique_lock lck (mtx); + + std::string pipelineId = createPipeline (); + + std::shared_ptr videosampler = createVideoSampler (pipelineId); + std::shared_ptr passthrough = createPassThrough (pipelineId); + std::shared_ptr src = createTestSrc(pipelineId); + + ImageDeliverImpl service; + std::thread serverThread (grpcServer, &service); + int count = 5; + + if (videosampler == nullptr) { + BOOST_ERROR ("Could not create videosampler"); + } else { + BOOST_TEST_MESSAGE ("VideoSampler created"); + src->connect(videosampler); + std::dynamic_pointer_cast(videosampler)->connect(passthrough); + + sigc::connection conn = videosampler->signalSampleImageDelivered.connect([&] (SampleImageDelivered event) { + count--; + if (count <= 0) { + service.server->Shutdown(); + } + }); + sleep(1); + dumpPipeline (pipelineId, "videosampler.dot"); + serverThread.join (); + dumpPipeline (pipelineId, "videosampler2.dot"); + + videosampler->disconnect (passthrough); + src->disconnect(videosampler); + + releasePassTrhough (passthrough); + releaseVideoSampler (videosampler); + releaseTestElement (src); + } + + checkPipelineEmpty (pipelineId); + releasePipeline (pipelineId); +} + + +test_suite * +init_unit_test_suite ( int , char *[] ) +{ + test_suite *test = BOOST_TEST_SUITE ( "videosampler" ); + + test->add (BOOST_TEST_CASE ( &test_videosampler ), 0, /* timeout */ 15000); + + return test; +} \ No newline at end of file From 003f29f9a689c9405681613f4c1d94756ad50b69 Mon Sep 17 00:00:00 2001 From: Saul Pablo Labajo Izquierdo Date: Fri, 18 Oct 2024 11:05:15 +0000 Subject: [PATCH 02/24] add timestamp to grpc request --- .../objects/VideoSamplerImpl.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/server/module-extras/video-sampler/src/server/implementation/objects/VideoSamplerImpl.cpp b/server/module-extras/video-sampler/src/server/implementation/objects/VideoSamplerImpl.cpp index 051c57fe22..b4f865a339 100644 --- a/server/module-extras/video-sampler/src/server/implementation/objects/VideoSamplerImpl.cpp +++ b/server/module-extras/video-sampler/src/server/implementation/objects/VideoSamplerImpl.cpp @@ -105,6 +105,24 @@ VideoSamplerGRPC::VideoSamplerGRPC (const boost::property_tree::ptree &config, } } +static std::string +epochToString() { + // Obtener el tiempo actual en formato epoch + auto now = std::chrono::system_clock::now(); + std::time_t epoch_time = std::chrono::system_clock::to_time_t(now); + + // Convertir el tiempo epoch a una cadena de caracteres + std::stringstream ss; + ss << std::ctime(&epoch_time); + + // Eliminar el carácter de nueva línea al final de la cadena + std::string time_str = ss.str(); + if (!time_str.empty() && time_str.back() == '\n') { + time_str.pop_back(); + } + + return time_str; +} bool VideoSamplerGRPC::send_frame_data (guint8 *data, guint len) @@ -116,6 +134,7 @@ VideoSamplerGRPC::send_frame_data (guint8 *data, guint len) request.set_codec (getEncodingStr()); request.set_data (data, len); + request.set_timestamp (epochToString()); status = imageDeliverStub->deliverImage(&context, request, &reply); From b18c3507ce66a66f7bb7bfec27cbfb57403019c0 Mon Sep 17 00:00:00 2001 From: Saul Pablo Labajo Izquierdo Date: Fri, 18 Oct 2024 11:05:55 +0000 Subject: [PATCH 03/24] write grpc received frmaes to file in tests --- .../video-sampler/tests/server/videosampler.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/server/module-extras/video-sampler/tests/server/videosampler.cpp b/server/module-extras/video-sampler/tests/server/videosampler.cpp index a9e6196e11..0f39641a00 100644 --- a/server/module-extras/video-sampler/tests/server/videosampler.cpp +++ b/server/module-extras/video-sampler/tests/server/videosampler.cpp @@ -61,7 +61,7 @@ GF::GF() { boost::property_tree::ptree ac, audioCodecs, vc, videoCodecs; gst_init(nullptr, nullptr); - moduleManager.loadModulesFromDirectories ("../../src/server:./:../../../.."); + moduleManager.loadModulesFromDirectories ("../../src/server:./:../../../../module-core"); config.add ("configPath", "../../../tests" ); config.add ("modules.kurento.SdpEndpoint.numAudioMedias", 1); @@ -150,7 +150,18 @@ class ImageDeliverImpl final : public ImageDeliver::Service { BOOST_TEST_MESSAGE ("Received image"); std::string codec = request->codec(); std::string data = request->data(); - + std::string timestamp = request->timestamp(); + + std::ofstream file("./"+timestamp+".jpg", std::ios::out | std::ios::binary); + if (!file) { + BOOST_ERROR ("No se pudo abrir el fichero para escribir."); + } else { + // Escribir el array de bytes en el fichero + file.write(data.data(), data.length()); + + // Cerrar el fichero + file.close(); + } return ::grpc::Status::OK; } From a09398b3f2ff1121aac2e87c68ea96c78a66c85c Mon Sep 17 00:00:00 2001 From: Saul Pablo Labajo Izquierdo Date: Fri, 18 Oct 2024 11:06:45 +0000 Subject: [PATCH 04/24] optimize pipeline --- .../videosampler/kmsvideosampler.c | 170 ++++++++++++++---- 1 file changed, 134 insertions(+), 36 deletions(-) diff --git a/server/module-extras/video-sampler/src/gst-plugins/videosampler/kmsvideosampler.c b/server/module-extras/video-sampler/src/gst-plugins/videosampler/kmsvideosampler.c index 1a3d59c636..8b36aedc0c 100644 --- a/server/module-extras/video-sampler/src/gst-plugins/videosampler/kmsvideosampler.c +++ b/server/module-extras/video-sampler/src/gst-plugins/videosampler/kmsvideosampler.c @@ -27,7 +27,7 @@ #include #define MAX_FRAMES_STORED "50" -#define VIDEO_LEG_BIN " capsfilter caps=\"video/x-raw\" ! agnosticbin ! capsfilter name=\"video\" caps=\"%s\" ! tee name=t ! queue leaky=1 max-size-buffers=2 t. ! queue leaky=1 max-size-buffers="MAX_FRAMES_STORED" ! agnosticbin ! capsfilter name=\"encoder\" caps=\"%s\" ! appsink async=false sync=false emit-signals=true name=\"sink\"" +#define VIDEO_LEG_BIN " capsfilter name=\"input-caps\" caps=\"video/x-raw\" ! agnosticbin ! capsfilter name=\"video\" caps=\"%s\" ! tee name=t ! queue leaky=1 max-size-buffers=2 t. ! queue leaky=1 max-size-buffers="MAX_FRAMES_STORED" ! agnosticbin ! capsfilter name=\"encoder\" caps=\"%s\" ! appsink async=false sync=false emit-signals=true name=\"sink\"" #define PLUGIN_NAME "videosampler" @@ -158,11 +158,11 @@ kms_videosampler_connect_appsink (KmsVideoSampler *self) } static gchar* -kms_video_sampler_calculate_framerate (KmsVideoSampler *self) +calculate_framerate (gulong frame_period) { - if (self->priv->frame_period > 0) { + if (frame_period > 0) { gchar* fr_str; - gfloat period = self->priv->frame_period; + gfloat period = frame_period; gfloat freq = 1000.0 / period; // frame_period is measured in miliseconds guint freq_uint = roundf (freq * 100.0); @@ -178,27 +178,27 @@ kms_video_sampler_calculate_framerate (KmsVideoSampler *self) } static gchar* -kms_video_sampler_calculate_video_caps (KmsVideoSampler *self) +calculate_video_caps_for_output (gint width, gint height, gulong frame_period) { gchar *framerate_str = NULL; GString *caps; gchar *caps_str; - framerate_str = kms_video_sampler_calculate_framerate (self); + framerate_str = calculate_framerate (frame_period); caps = g_string_new ("video/x-raw"); if (framerate_str != NULL) { g_string_append (caps, ",framerate="); g_string_append (caps, framerate_str); g_free (framerate_str); } - if (self->priv->height > 0) { - gchar *number = g_strdup_printf ("%ld", self->priv->height); + if (height > 0) { + gchar *number = g_strdup_printf ("%d", height); g_string_append (caps, ",height="); g_string_append (caps, number); g_free (number); } - if (self->priv->width > 0) { - gchar *number = g_strdup_printf ("%ld", self->priv->width); + if (width > 0) { + gchar *number = g_strdup_printf ("%d", width); g_string_append (caps, ",width="); g_string_append (caps, number); g_free (number); @@ -209,21 +209,21 @@ kms_video_sampler_calculate_video_caps (KmsVideoSampler *self) } static gchar* -kms_video_sampler_calculate_encoder (KmsVideoSampler *self) +calculate_encoder (gchar *encoding) { gchar* encoder; - if (self->priv->encoding == NULL) { + if (encoding == NULL) { encoder = g_strdup_printf("%s", "video/x-raw"); - }else if (g_str_equal (self->priv->encoding, "PNG")){ + }else if (g_str_equal (encoding, "PNG")){ encoder = g_strdup_printf("%s", "image/png"); - } else if (g_str_equal (self->priv->encoding, "JPEG")){ + } else if (g_str_equal (encoding, "JPEG")){ encoder = g_strdup_printf("%s", "image/jpeg"); - } else if (g_str_equal (self->priv->encoding, "BMP")){ + } else if (g_str_equal (encoding, "BMP")){ encoder = g_strdup_printf("%s", "image/bmp"); - } else if (g_str_equal (self->priv->encoding, "PBM")){ + } else if (g_str_equal (encoding, "PBM")){ encoder = g_strdup_printf("%s", "image/pbm"); - } else if (g_str_equal (self->priv->encoding, "PPM")){ + } else if (g_str_equal (encoding, "PPM")){ encoder = g_strdup_printf("%s", "image/ppm"); } else { encoder = g_strdup_printf("%s", "video/x-raw"); @@ -237,8 +237,8 @@ kms_video_sampler_calculate_encoder (KmsVideoSampler *self) static gchar* kms_videosampler_create_description (KmsVideoSampler *self) { - gchar* video_caps = kms_video_sampler_calculate_video_caps (self); - gchar* encoder_class = kms_video_sampler_calculate_encoder (self); + gchar* video_caps = calculate_video_caps_for_output (self->priv->width, self->priv->height, self->priv->frame_period); + gchar* encoder_class = calculate_encoder (self->priv->encoding); gchar* description; description = g_strdup_printf (VIDEO_LEG_BIN, video_caps, encoder_class); @@ -247,7 +247,112 @@ kms_videosampler_create_description (KmsVideoSampler *self) return description; } +static void +kms_videosampler_update_video_caps_for_output (KmsVideoSampler *self, gint width, gint height, gulong frame_period) +{ + gchar* video_caps = calculate_video_caps_for_output (width, height, frame_period); + GstElement *capsfilter = gst_bin_get_by_name (GST_BIN(self->priv->video_leg), "video"); + GstCaps *caps = gst_caps_from_string(video_caps); + + g_object_set (capsfilter, "caps", caps, NULL); + gst_caps_unref (caps); + gst_object_unref (capsfilter); + g_free (video_caps); +} + +static void +kms_videosampler_set_output_resolution_preserving_aspect_ratio (KmsVideoSampler *self, gint orig_width, gint orig_height) +{ + if (self->priv->height > 0) { + // We need to calculate width for aspect ratio preservation + gint calculated_width; + + calculated_width = orig_width * self->priv->height / orig_height; + kms_videosampler_update_video_caps_for_output(self, calculated_width, self->priv->height, self->priv->frame_period); + } else if (self->priv->width > 0) { + // We need to calculate width for aspect ratio preservation + gint calculated_height; + + calculated_height = orig_height * self->priv->width / orig_width; + kms_videosampler_update_video_caps_for_output(self, self->priv->width, calculated_height, self->priv->frame_period); + } +} + +static gchar* +calculate_video_caps_for_input (gint width, gint height) +{ + GString *caps; + gchar *caps_str; + + caps = g_string_new ("video/x-raw"); + if (height > 0) { + gchar *number = g_strdup_printf ("%d", height); + g_string_append (caps, ",height="); + g_string_append (caps, number); + g_free (number); + } + if (width > 0) { + gchar *number = g_strdup_printf ("%d", width); + g_string_append (caps, ",width="); + g_string_append (caps, number); + g_free (number); + } + caps_str = g_strdup_printf ("%s", caps->str); + g_string_free (caps, TRUE); + return caps_str; +} + +static void +kms_videosampler_set_input_resolution (KmsVideoSampler *self, gint orig_width, gint orig_height) +{ + if (self->priv->video_leg != NULL) { + GstElement *input_caps; + + input_caps = gst_bin_get_by_name (GST_BIN(self->priv->video_leg), "input-caps"); + if (input_caps != NULL) { + gchar *caps_str = calculate_video_caps_for_input (orig_width, orig_height); + GstCaps *caps = gst_caps_from_string(caps_str); + + g_object_set (input_caps, "caps", caps, NULL); + gst_caps_unref (caps); + g_free (caps_str); + gst_object_unref (input_caps); + } + } +} + +static GstPadProbeReturn +kms_videosampler_resolution_change (GstPad *pad, GstPadProbeInfo *info, gpointer user_data) +{ + KmsVideoSampler *self = (KmsVideoSampler*) user_data; + GstEvent *event; + + // If no aspect ratio preservation is needed no action taken + if ((self->priv->height == 0) && (self->priv->width == 0)) { + return GST_PAD_PROBE_OK; + } + + event = gst_pad_probe_info_get_event (info); + if (GST_EVENT_TYPE(event) == GST_EVENT_CAPS) { + GstCaps *caps; + GstStructure *structure; + gint width, height; + + gst_event_parse_caps(event, &caps); + structure = gst_caps_get_structure(caps, 0); + + if (gst_structure_get_int(structure, "width", &width) && gst_structure_get_int(structure, "height", &height)) { + if (!((self->priv->height > 0) && (self->priv->width > 0))) { + // We have definitive souorce resolution, set the output resolution + kms_videosampler_set_output_resolution_preserving_aspect_ratio (self, width, height); + } + kms_videosampler_set_input_resolution (self, width, height); + } + } + + return GST_PAD_PROBE_OK; +} static void kms_videosampler_connect_video_leg (KmsVideoSampler *self) @@ -255,6 +360,7 @@ kms_videosampler_connect_video_leg (KmsVideoSampler *self) gchar *description = kms_videosampler_create_description (self); GError *error= NULL; GstElement *output; + GstPad *sinkpad; output = kms_element_get_video_agnosticbin (KMS_ELEMENT (self)); self->priv->video_leg = gst_parse_bin_from_description (description, TRUE, &error); @@ -268,6 +374,11 @@ kms_videosampler_connect_video_leg (KmsVideoSampler *self) gst_element_link (self->priv->video_leg, output); kms_videosampler_connect_passthrough (self, KMS_ELEMENT_PAD_TYPE_VIDEO, self->priv->video_leg); + + // Add probe to dynamically calculate resolutions in case neede to respect aspect ratio + sinkpad = gst_element_get_static_pad(self->priv->video_leg, "sink"); + gst_pad_add_probe(sinkpad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, (GstPadProbeCallback)kms_videosampler_resolution_change, (gpointer) self, NULL); + gst_object_unref (sinkpad); } g_free (description); } @@ -293,41 +404,28 @@ kms_videosampler_init (KmsVideoSampler *self) self->priv->appsink_signal = kms_videosampler_connect_appsink (self); } -static void -kms_videosampler_update_video_caps (KmsVideoSampler *self) -{ - gchar* video_caps = kms_video_sampler_calculate_video_caps (self); - GstElement *capsfilter = gst_bin_get_by_name (GST_BIN(self->priv->video_leg), "video"); - GstCaps *caps = gst_caps_from_string(video_caps); - - g_object_set (capsfilter, "caps", caps, NULL); - gst_caps_unref (caps); - gst_object_unref (capsfilter); - g_free (video_caps); -} - static void kms_videosampler_update_frame_period (KmsVideoSampler *self) { - kms_videosampler_update_video_caps(self); + kms_videosampler_update_video_caps_for_output(self, self->priv->width, self->priv->height, self->priv->frame_period); } static void kms_videosampler_update_height (KmsVideoSampler *self) { - kms_videosampler_update_video_caps(self); + kms_videosampler_update_video_caps_for_output(self, self->priv->width, self->priv->height, self->priv->frame_period); } static void kms_videosampler_update_width (KmsVideoSampler *self) { - kms_videosampler_update_video_caps(self); + kms_videosampler_update_video_caps_for_output(self, self->priv->width, self->priv->height, self->priv->frame_period); } static void kms_videosampler_update_image_encoding (KmsVideoSampler *self) { - gchar* encoder_class = kms_video_sampler_calculate_encoder (self); + gchar* encoder_class = calculate_encoder (self->priv->encoding); GstElement *capsfilter = gst_bin_get_by_name (GST_BIN(self->priv->video_leg), "encoder"); GstCaps *caps = gst_caps_from_string(encoder_class); From bee40601307c376959dbfebcc1660e58d5bfb1a8 Mon Sep 17 00:00:00 2001 From: Saul Pablo Labajo Izquierdo Date: Fri, 18 Oct 2024 11:07:09 +0000 Subject: [PATCH 05/24] remove fix GST_DEBUG --- server/module-extras/video-sampler/tests/server/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/server/module-extras/video-sampler/tests/server/CMakeLists.txt b/server/module-extras/video-sampler/tests/server/CMakeLists.txt index 1344a70533..a80a865474 100644 --- a/server/module-extras/video-sampler/tests/server/CMakeLists.txt +++ b/server/module-extras/video-sampler/tests/server/CMakeLists.txt @@ -1,7 +1,6 @@ set(TEST_VARIABLES "GST_PLUGIN_PATH=$ENV{GST_PLUGIN_PATH}:${CMAKE_BINARY_DIR}:${CMAKE_BINARY_DIR}/src" "KURENTO_MODULES_PATH=${CMAKE_BINARY_DIR}:${CMAKE_BINARY_DIR}/src:$ENV{KURENTO_MODULES_PATH}" - "GST_DEBUG=2,KurentoModule*:4" ) set(VALGRIND_TEST_VARIABLES "${TEST_VARIABLES}" From 9f97dd5326330372decad75e87d2aa0cd9766b38 Mon Sep 17 00:00:00 2001 From: Saul Pablo Labajo Izquierdo Date: Fri, 18 Oct 2024 11:07:44 +0000 Subject: [PATCH 06/24] initial changelog --- server/module-extras/video-sampler/debian/changelog | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/server/module-extras/video-sampler/debian/changelog b/server/module-extras/video-sampler/debian/changelog index e69de29bb2..5cabfb9955 100644 --- a/server/module-extras/video-sampler/debian/changelog +++ b/server/module-extras/video-sampler/debian/changelog @@ -0,0 +1,5 @@ +video-sample (0.0.1~rc1) testing; urgency=medium + + * Initial release. + + -- Saúl Labajo Thu, 17 Oct 20244 12:38:25 +0200 From 709d65be51ce2abf90af443f0168b9b2de4007e0 Mon Sep 17 00:00:00 2001 From: Saul Pablo Labajo Izquierdo Date: Fri, 18 Oct 2024 11:14:39 +0000 Subject: [PATCH 07/24] fix dependencies --- server/module-extras/video-sampler/debian/control | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/server/module-extras/video-sampler/debian/control b/server/module-extras/video-sampler/debian/control index 699e144870..ed75e6589e 100644 --- a/server/module-extras/video-sampler/debian/control +++ b/server/module-extras/video-sampler/debian/control @@ -11,14 +11,16 @@ Build-Depends: kurento-module-elements-dev (>= 7.1.1), kurento-module-filters-dev (>= 7.1.1), pkg-config, - protobuf-compilter + protobuf-compiler-grpc, + libgrpc-dev, + libgrpc++-dev Standards-Version: 4.5.1 Homepage: https://kurento.openvidu.io/ Vcs-Browser: https://github.com/Kurento/kurento Vcs-Git: https://github.com/Kurento/kurento.git Rules-Requires-Root: no -Package: kurento-module-chroma +Package: kurento-module-videosampler Architecture: any Section: libs Depends: @@ -30,6 +32,9 @@ Depends: kurento-module-core (>= 7.1.1), kurento-module-elements (>= 7.1.1), kurento-module-filters (>= 7.1.1), + libgrpc++1.51t64 + libgrpc29t64 + libprotobuf32t64 Breaks: kms-chroma-6.0, kms-chroma, From 43ecebe7559ce8ddcc3dca6a77dee28b1d068fd9 Mon Sep 17 00:00:00 2001 From: Saul Pablo Labajo Izquierdo Date: Fri, 18 Oct 2024 14:11:36 +0000 Subject: [PATCH 08/24] videosampler module --- .github/workflows/server.parent.yaml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.github/workflows/server.parent.yaml b/.github/workflows/server.parent.yaml index 0a030a48e2..60f590699c 100644 --- a/.github/workflows/server.parent.yaml +++ b/.github/workflows/server.parent.yaml @@ -195,6 +195,17 @@ jobs: runnerGroup: ${{ inputs.runnerGroup }} directory: "server/module-examples/datachannelexample/" + module-videosampler: + needs: ["module-core"] + uses: "./.github/workflows/server-buildpackage.child.yaml" + with: + jobDistros: "${{ inputs.jobDistros }}" + jobGitName: "${{ inputs.jobGitName }}" + jobGitNameFallback: "${{ inputs.jobGitNameFallback }}" + jobRelease: ${{ inputs.jobRelease }} + runnerGroup: ${{ inputs.runnerGroup }} + directory: "server/module-extras/video-sampler/" + deploy-deb: needs: ["media-server", "module-chroma", "module-datachannelexample"] uses: "./.github/workflows/server-deploy-debian.child.yaml" From 07a02d0aa41803175df06ea59ff0f21a906a30c3 Mon Sep 17 00:00:00 2001 From: Saul Pablo Labajo Izquierdo Date: Mon, 21 Oct 2024 16:15:54 +0000 Subject: [PATCH 09/24] fix artifact generation --- server/module-extras/video-sampler/README.md | 6 ++++++ .../video-sampler/debian/changelog | 2 +- .../video-sampler/debian/control | 21 +++++++------------ ...> kurento-module-videosampler-dev.install} | 1 + ...ll => kurento-module-videosampler.install} | 0 .../video-sampler/tests/server/CMakeLists.txt | 2 ++ 6 files changed, 18 insertions(+), 14 deletions(-) create mode 100644 server/module-extras/video-sampler/README.md rename server/module-extras/video-sampler/debian/{kurento-module-chroma-dev.install => kurento-module-videosampler-dev.install} (91%) rename server/module-extras/video-sampler/debian/{kurento-module-chroma.install => kurento-module-videosampler.install} (100%) diff --git a/server/module-extras/video-sampler/README.md b/server/module-extras/video-sampler/README.md new file mode 100644 index 0000000000..f70d260717 --- /dev/null +++ b/server/module-extras/video-sampler/README.md @@ -0,0 +1,6 @@ +kurento-module-videosampler +===================== + +Video sampler element for Kurento Media Server. + + diff --git a/server/module-extras/video-sampler/debian/changelog b/server/module-extras/video-sampler/debian/changelog index 5cabfb9955..7026ff76bf 100644 --- a/server/module-extras/video-sampler/debian/changelog +++ b/server/module-extras/video-sampler/debian/changelog @@ -1,4 +1,4 @@ -video-sample (0.0.1~rc1) testing; urgency=medium +video-sample (7.1.1-dev) testing; urgency=medium * Initial release. diff --git a/server/module-extras/video-sampler/debian/control b/server/module-extras/video-sampler/debian/control index ed75e6589e..aaaf428ff6 100644 --- a/server/module-extras/video-sampler/debian/control +++ b/server/module-extras/video-sampler/debian/control @@ -13,7 +13,8 @@ Build-Depends: pkg-config, protobuf-compiler-grpc, libgrpc-dev, - libgrpc++-dev + libgrpc++-dev, + libprotobuf-dev Standards-Version: 4.5.1 Homepage: https://kurento.openvidu.io/ Vcs-Browser: https://github.com/Kurento/kurento @@ -32,8 +33,8 @@ Depends: kurento-module-core (>= 7.1.1), kurento-module-elements (>= 7.1.1), kurento-module-filters (>= 7.1.1), - libgrpc++1.51t64 - libgrpc29t64 + libgrpc++1.51t64, + libgrpc29t64, libprotobuf32t64 Breaks: kms-chroma-6.0, @@ -41,21 +42,15 @@ Breaks: Replaces: kms-chroma-6.0, kms-chroma, -Description: Kurento Chroma filter +Description: Kurento Video sampler element -Package: kurento-module-chroma-dev +Package: kurento-module-videosampler-dev Architecture: any Section: libdevel Depends: ${misc:Depends}, - kurento-module-chroma (= ${binary:Version}), + kurento-module-videosampler (= ${binary:Version}), kurento-module-core-dev, kurento-module-elements-dev, kurento-module-filters-dev, -Breaks: - kms-chroma-6.0-dev, - kms-chroma-dev, -Replaces: - kms-chroma-6.0-dev, - kms-chroma-dev, -Description: Kurento Chroma filter - Development files +Description: Kurento video sampler element - Development files diff --git a/server/module-extras/video-sampler/debian/kurento-module-chroma-dev.install b/server/module-extras/video-sampler/debian/kurento-module-videosampler-dev.install similarity index 91% rename from server/module-extras/video-sampler/debian/kurento-module-chroma-dev.install rename to server/module-extras/video-sampler/debian/kurento-module-videosampler-dev.install index 57a6101aa5..6e72e8e226 100644 --- a/server/module-extras/video-sampler/debian/kurento-module-chroma-dev.install +++ b/server/module-extras/video-sampler/debian/kurento-module-videosampler-dev.install @@ -1,5 +1,6 @@ usr/include/kurento/modules/*/*.hpp usr/lib/*/*.so +usr/lib/*/*.a usr/lib/*/pkgconfig/*.pc usr/share/cmake/Kurento/*.cmake usr/share/kurento/modules/*.kmd.json diff --git a/server/module-extras/video-sampler/debian/kurento-module-chroma.install b/server/module-extras/video-sampler/debian/kurento-module-videosampler.install similarity index 100% rename from server/module-extras/video-sampler/debian/kurento-module-chroma.install rename to server/module-extras/video-sampler/debian/kurento-module-videosampler.install diff --git a/server/module-extras/video-sampler/tests/server/CMakeLists.txt b/server/module-extras/video-sampler/tests/server/CMakeLists.txt index a80a865474..acc7c999c8 100644 --- a/server/module-extras/video-sampler/tests/server/CMakeLists.txt +++ b/server/module-extras/video-sampler/tests/server/CMakeLists.txt @@ -1,6 +1,8 @@ +include(TestHelpers) set(TEST_VARIABLES "GST_PLUGIN_PATH=$ENV{GST_PLUGIN_PATH}:${CMAKE_BINARY_DIR}:${CMAKE_BINARY_DIR}/src" "KURENTO_MODULES_PATH=${CMAKE_BINARY_DIR}:${CMAKE_BINARY_DIR}/src:$ENV{KURENTO_MODULES_PATH}" + "CK_DEFAULT_TIMEOUT=50" ) set(VALGRIND_TEST_VARIABLES "${TEST_VARIABLES}" From 758ee525c839a35212421eb6a42b0504917191dc Mon Sep 17 00:00:00 2001 From: Saul Pablo Labajo Izquierdo Date: Tue, 22 Oct 2024 09:28:35 +0000 Subject: [PATCH 10/24] fix debian package --- server/module-extras/video-sampler/debian/control | 6 ------ 1 file changed, 6 deletions(-) diff --git a/server/module-extras/video-sampler/debian/control b/server/module-extras/video-sampler/debian/control index aaaf428ff6..944bf7ce31 100644 --- a/server/module-extras/video-sampler/debian/control +++ b/server/module-extras/video-sampler/debian/control @@ -8,8 +8,6 @@ Build-Depends: gstreamer1.0-plugins-base, gstreamer1.0-plugins-good, kurento-module-core-dev (>= 7.1.1), - kurento-module-elements-dev (>= 7.1.1), - kurento-module-filters-dev (>= 7.1.1), pkg-config, protobuf-compiler-grpc, libgrpc-dev, @@ -31,8 +29,6 @@ Depends: gstreamer1.0-plugins-base, gstreamer1.0-plugins-good, kurento-module-core (>= 7.1.1), - kurento-module-elements (>= 7.1.1), - kurento-module-filters (>= 7.1.1), libgrpc++1.51t64, libgrpc29t64, libprotobuf32t64 @@ -51,6 +47,4 @@ Depends: ${misc:Depends}, kurento-module-videosampler (= ${binary:Version}), kurento-module-core-dev, - kurento-module-elements-dev, - kurento-module-filters-dev, Description: Kurento video sampler element - Development files From 892b14994db26374be3845a501315d1046573ffa Mon Sep 17 00:00:00 2001 From: Saul Pablo Labajo Izquierdo Date: Tue, 22 Oct 2024 09:43:09 +0000 Subject: [PATCH 11/24] fix debian package name --- server/module-extras/video-sampler/debian/changelog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/module-extras/video-sampler/debian/changelog b/server/module-extras/video-sampler/debian/changelog index 7026ff76bf..4de7633b44 100644 --- a/server/module-extras/video-sampler/debian/changelog +++ b/server/module-extras/video-sampler/debian/changelog @@ -1,4 +1,4 @@ -video-sample (7.1.1-dev) testing; urgency=medium +kurento-module-videosampler (7.1.1-dev) testing; urgency=medium * Initial release. From 80f70d7ca3afd2725140512360f7f5f7386cbdad Mon Sep 17 00:00:00 2001 From: Saul Pablo Labajo Izquierdo Date: Tue, 22 Oct 2024 09:55:46 +0000 Subject: [PATCH 12/24] fix auto dependencies --- server/module-extras/video-sampler/debian/control | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/server/module-extras/video-sampler/debian/control b/server/module-extras/video-sampler/debian/control index 944bf7ce31..aaaf428ff6 100644 --- a/server/module-extras/video-sampler/debian/control +++ b/server/module-extras/video-sampler/debian/control @@ -8,6 +8,8 @@ Build-Depends: gstreamer1.0-plugins-base, gstreamer1.0-plugins-good, kurento-module-core-dev (>= 7.1.1), + kurento-module-elements-dev (>= 7.1.1), + kurento-module-filters-dev (>= 7.1.1), pkg-config, protobuf-compiler-grpc, libgrpc-dev, @@ -29,6 +31,8 @@ Depends: gstreamer1.0-plugins-base, gstreamer1.0-plugins-good, kurento-module-core (>= 7.1.1), + kurento-module-elements (>= 7.1.1), + kurento-module-filters (>= 7.1.1), libgrpc++1.51t64, libgrpc29t64, libprotobuf32t64 @@ -47,4 +51,6 @@ Depends: ${misc:Depends}, kurento-module-videosampler (= ${binary:Version}), kurento-module-core-dev, + kurento-module-elements-dev, + kurento-module-filters-dev, Description: Kurento video sampler element - Development files From 665537769d356161d83e6a42da1dfe62bc1ffb53 Mon Sep 17 00:00:00 2001 From: Saul Pablo Labajo Izquierdo Date: Tue, 22 Oct 2024 09:57:06 +0000 Subject: [PATCH 13/24] fix workflow order --- .github/workflows/server.parent.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/server.parent.yaml b/.github/workflows/server.parent.yaml index 60f590699c..bba0dc9e52 100644 --- a/.github/workflows/server.parent.yaml +++ b/.github/workflows/server.parent.yaml @@ -196,7 +196,7 @@ jobs: directory: "server/module-examples/datachannelexample/" module-videosampler: - needs: ["module-core"] + needs: ["module-filters"] uses: "./.github/workflows/server-buildpackage.child.yaml" with: jobDistros: "${{ inputs.jobDistros }}" From 935ed77a8ff989301e0a93c8425107ce9cd8ef15 Mon Sep 17 00:00:00 2001 From: Saul Pablo Labajo Izquierdo Date: Tue, 22 Oct 2024 17:00:13 +0000 Subject: [PATCH 14/24] Add module-extras to build process --- .../workflows/server-deploy-docker.child.yaml | 11 ++ .github/workflows/server.parent.yaml | 2 +- docker/kurento-media-server-extras/Dockerfile | 73 +++++++++++ docker/kurento-media-server-extras/README.md | 120 ++++++++++++++++++ .../kurento-media-server-extras/version.yml | 2 + 5 files changed, 207 insertions(+), 1 deletion(-) create mode 100644 docker/kurento-media-server-extras/Dockerfile create mode 100644 docker/kurento-media-server-extras/README.md create mode 100644 docker/kurento-media-server-extras/version.yml diff --git a/.github/workflows/server-deploy-docker.child.yaml b/.github/workflows/server-deploy-docker.child.yaml index 18f7d14965..d6598af084 100644 --- a/.github/workflows/server-deploy-docker.child.yaml +++ b/.github/workflows/server-deploy-docker.child.yaml @@ -87,6 +87,17 @@ jobs: working-directory: "docker/kurento-media-server/" run: "ci_job_deploy_docker.sh" + - name: "Run job script (modules extras)" + env: + JOB_DISTRO: "${{ matrix.jobDistro }}" + JOB_RELEASE: "${{ inputs.jobRelease }}" + JOB_DEPLOY_NAME: "${{ inputs.jobDeployName }}" + PACKAGES_PATH: "${{ steps.copy-artifacts.outputs.download-path }}" + KURENTO_DOCKERHUB_USERNAME: "${{ secrets.KURENTO_DOCKERHUB_USERNAME }}" + KURENTO_DOCKERHUB_TOKEN: "${{ secrets.KURENTO_DOCKERHUB_TOKEN }}" + working-directory: "docker/kurento-media-server-extras/" + run: "ci_job_deploy_docker.sh" + - name: "Run job script (AddressSanitizer)" if: ${{ inputs.buildAsan }} env: diff --git a/.github/workflows/server.parent.yaml b/.github/workflows/server.parent.yaml index bba0dc9e52..5963db7db1 100644 --- a/.github/workflows/server.parent.yaml +++ b/.github/workflows/server.parent.yaml @@ -207,7 +207,7 @@ jobs: directory: "server/module-extras/video-sampler/" deploy-deb: - needs: ["media-server", "module-chroma", "module-datachannelexample"] + needs: ["media-server", "module-chroma", "module-datachannelexample", "module-videosampler"] uses: "./.github/workflows/server-deploy-debian.child.yaml" with: jobDistros: "${{ inputs.jobDistros }}" diff --git a/docker/kurento-media-server-extras/Dockerfile b/docker/kurento-media-server-extras/Dockerfile new file mode 100644 index 0000000000..1d2c8dfa1f --- /dev/null +++ b/docker/kurento-media-server-extras/Dockerfile @@ -0,0 +1,73 @@ +# ==================== +# Kurento Media Server (modules extras) +# ==================== +# +# This Docker image is used to run an instance of Kurento Media Server with modules-extras packages added +# +# +# +# Build Command +# ============= +# +# Run: +# +# docker build [Args...] --tag kurento/kurento-media-server-extras:latest . +# +# +# +# Build Arguments +# --------------- +# +# --build-arg KMS_VERSION= +# +# is like "7.0.0". +# Alternatively, "dev" is used to build a nightly version of Kurento. +# +# Optional. Default: "dev". +# +# --build-arg APT_ARGS= +# +# is a string with arguments that will be passed to all +# executions of `apt-get`. +# +# Example: To Use an Apt package proxy +# Doc: http://manpages.ubuntu.com/manpages/man1/apt-transport-http.1.html#options +# +# APT_ARGS='-o Acquire::http::Proxy=http://user:pass@host:port/' +# +# Optional. Default: None. +# +# +# +# Run Command +# =========== +# +# Run: +# +# docker run --name kurento --network host kurento/kurento-media-server-extras:latest +# +# Then, you can follow the logs with the `docker logs` command: +# +# docker logs --follow kms >"kms-$(date '+%Y%m%dT%H%M%S').log" 2>&1 + +FROM kurento-media-server:${KMS_VERSION} + +LABEL maintainer="Saúl Pablo Labajo Izquierdo " + +# Configure environment: +# Run apt-get/dpkg without interactive dialogue. +ARG DEBIAN_FRONTEND=noninteractive +# Set the default locale for all commands. +ENV LANG="C.UTF-8" + +# Install extra modules. +# These might not be all available, so install separately and allow errors. +RUN \ +apt-get $APT_ARGS update \ +&& for PACKAGE in \ + kurento-module-videosampler ; \ +do \ + apt-get $APT_ARGS install --no-install-recommends --yes "$PACKAGE" || true ; \ +done \ +&& rm -rf /var/lib/apt/lists/* + diff --git a/docker/kurento-media-server-extras/README.md b/docker/kurento-media-server-extras/README.md new file mode 100644 index 0000000000..d7f358a494 --- /dev/null +++ b/docker/kurento-media-server-extras/README.md @@ -0,0 +1,120 @@ +[![Kurento logo](https://secure.gravatar.com/avatar/21a2a12c56b2a91c8918d5779f1778bf?s=120)](https://kurento.openvidu.io/) + + + +# Kurento Media Server + +| [Homepage](https://kurento.openvidu.io/) | [Documentation](https://kurento.openvidu.io/documentation) | [![Docker Pulls](https://img.shields.io/docker/pulls/kurento/kurento-media-server?color=blue&label=Docker&logo=docker&logoColor=blue)](https://hub.docker.com/r/kurento/kurento-media-server) | +| --- | --- | --- | +| [![GitHub commits](https://img.shields.io/github/commits-difference/Kurento/kurento?base=eabf6de352fb927df91baa2ec26794dac8c64d78&head=HEAD&label=Commits&logo=github)](https://github.com/Kurento/kurento/graphs/commit-activity) | [![GitHub contributors](https://img.shields.io/github/contributors/Kurento/kurento?label=Contributors&logo=github)](https://github.com/Kurento/kurento/graphs/contributors) | [![Stack Exchange questions](https://img.shields.io/stackexchange/stackoverflow/t/kurento?color=orange&label=Stack%20Overflow&logo=stackoverflow&logoColor=orange)](https://stackoverflow.com/questions/tagged/kurento) | + +Image source: [Dockerfile](https://github.com/Kurento/kurento/blob/main/docker/kurento-media-server/Dockerfile). + +This Docker image can be used to run Kurento Media Server on **x86** platforms. It cannot be used on other architectures, such as ARM. + +Usage instructions are detailed in the [Kurento Media Server documentation](https://doc-kurento.readthedocs.io/) page: + +* [Running Kurento Media Server](https://doc-kurento.readthedocs.io/en/latest/user/installation.html#installation-docker). +* [Configuration parameters](https://doc-kurento.readthedocs.io/en/latest/user/configuration.html). + + + +## About Kurento + +Kurento is an open source software project providing a platform suitable for creating modular applications with advanced real-time communication capabilities. To know more about Kurento, please visit the project website: https://kurento.openvidu.io/. + +All source code belonging to the Kurento project can be found in the [Kurento GitHub organization page](https://github.com/Kurento). + + + +## FIWARE Platform + +| [![FIWARE Chapter](https://nexus.lab.fiware.org/repository/raw/public/badges/chapters/media-streams.svg)](https://www.fiware.org/developers/catalogue/) | [![FIWARE Member Status](https://nexus.lab.fiware.org/static/badges/statuses/kurento.svg)](https://www.fiware.org/developers/catalogue/) | :mortar_board: [FIWARE Academy](https://fiware-academy.readthedocs.io/en/latest/processing/kurento) | +| --- | --- | --- | + +The Kurento project is part of [FIWARE]. For more information check the FIWARE documentation for [Real-Time Media Stream Processing](https://fiwaretourguide.readthedocs.io/en/latest/processing/kurento/introduction/). + +Kurento has been rated within [FIWARE] as follows: + +- **Version Tested:** + ![](https://img.shields.io/badge/dynamic/json.svg?label=Version&url=https://fiware.github.io/catalogue/json/kurento.json&query=$.version&colorB=blue) +- **Documentation:** + ![ ](https://img.shields.io/badge/dynamic/json.svg?label=Completeness&url=https://fiware.github.io/catalogue/json/kurento.json&query=$.docCompleteness&colorB=blue) + ![ ](https://img.shields.io/badge/dynamic/json.svg?label=Usability&url=https://fiware.github.io/catalogue/json/kurento.json&query=$.docSoundness&colorB=blue) +- **Responsiveness:** + ![ ](https://img.shields.io/badge/dynamic/json.svg?label=Time%20to%20Respond&url=https://fiware.github.io/catalogue/json/kurento.json&query=$.timeToCharge&colorB=blue) + ![ ](https://img.shields.io/badge/dynamic/json.svg?label=Time%20to%20Fix&url=https://fiware.github.io/catalogue/json/kurento.json&query=$.timeToFix&colorB=blue) +- **FIWARE Testing:** + ![ ](https://img.shields.io/badge/dynamic/json.svg?label=Tests%20Passed&url=https://fiware.github.io/catalogue/json/kurento.json&query=$.failureRate&colorB=blue) + ![ ](https://img.shields.io/badge/dynamic/json.svg?label=Scalability&url=https://fiware.github.io/catalogue/json/kurento.json&query=$.scalability&colorB=blue) + ![ ](https://img.shields.io/badge/dynamic/json.svg?label=Performance&url=https://fiware.github.io/catalogue/json/kurento.json&query=$.performance&colorB=blue) + ![ ](https://img.shields.io/badge/dynamic/json.svg?label=Stability&url=https://fiware.github.io/catalogue/json/kurento.json&query=$.stability&colorB=blue) + +Kurento is also part of the [NUBOMEDIA](https://nubomedia.readthedocs.io/en/latest/) research initiative. + +The Open API specification, also known as [Kurento Protocol](https://doc-kurento.readthedocs.io/en/latest/features/kurento_protocol.html), is available at [Stream-oriented Open API](http://docs.streamoriented.apiary.io/). + +[FIWARE]: https://www.fiware.org/ + + + +## Documentation + +Kurento provides detailed [documentation](https://kurento.openvidu.io/documentation) including tutorials, installation and development guides. + + + +## Useful Links + +Usage: + +* [Installation Guide](https://doc-kurento.readthedocs.io/en/latest/user/installation.html) +* [Docker Image](https://hub.docker.com/r/kurento/kurento-media-server) +* [Contribution Guide](https://doc-kurento.readthedocs.io/en/latest/project/contributing.html) +* [Developer Guide](https://doc-kurento.readthedocs.io/en/latest/dev/dev_guide.html) + +Issues: + +* [Bug Tracker](https://github.com/Kurento/kurento/issues) +* [Support](https://doc-kurento.readthedocs.io/en/latest/user/support.html) + +News: + +* [Kurento Blog](https://kurento.openvidu.io/blog) +* [Community Discussion](https://groups.google.com/g/kurento) + +Training: + +* [Kurento tutorials](https://doc-kurento.readthedocs.io/en/latest/user/tutorials.html) + + + +## Testing + +Kurento has a full set of different tests mainly focused in the integrated and system tests, more specifically e2e tests that anyone can run to assess different parts of Kurento, namely functional, stability, tutorials, and API. + +In order to assess properly Kurento from a final user perspective, a rich suite of E2E tests has been designed and implemented. To that aim, the Kurento Testing Framework (KTF) has been created. KTF is a part of the Kurento project aimed to carry out end-to-end (E2E) tests for Kurento. KTF has been implemented on the top of two well-known open-source testing frameworks: JUnit and Selenium. + +If you want to know more about the Kurento Testing Framework and how to run all the available tests for Kurento you will find more information in [Kurento developers documentation > Testing](https://doc-kurento.readthedocs.io/en/latest/dev/testing.html). + + + +## License + +[![License badge](https://img.shields.io/github/license/Kurento/kurento?label=License&logo=apache)](https://www.apache.org/licenses/LICENSE-2.0) + +``` +Copyright 2023 Kurento + +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. +``` diff --git a/docker/kurento-media-server-extras/version.yml b/docker/kurento-media-server-extras/version.yml new file mode 100644 index 0000000000..76b0d7e60d --- /dev/null +++ b/docker/kurento-media-server-extras/version.yml @@ -0,0 +1,2 @@ +image: + name: kurento/kurento-media-server-extras From 63e5452397092e8d304c0062827273e5050e1abf Mon Sep 17 00:00:00 2001 From: Saul Pablo Labajo Izquierdo Date: Tue, 22 Oct 2024 20:39:40 +0000 Subject: [PATCH 15/24] temporary fix for testing --- ci-scripts/ci_job_deploy_docker.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-scripts/ci_job_deploy_docker.sh b/ci-scripts/ci_job_deploy_docker.sh index 46c28dd34d..24194af154 100755 --- a/ci-scripts/ci_job_deploy_docker.sh +++ b/ci-scripts/ci_job_deploy_docker.sh @@ -108,7 +108,7 @@ else fi # Run the Docker image builder -export PUSH_IMAGES="yes" +export PUSH_IMAGES="no" BUILD_ARGS="" BUILD_ARGS+=" UBUNTU_CODENAME=$JOB_DISTRO" BUILD_ARGS+=" KMS_VERSION=$DOCKER_KMS_VERSION" From ca64e73a611c32e943637232af991220f059441d Mon Sep 17 00:00:00 2001 From: Saul Pablo Labajo Izquierdo Date: Wed, 23 Oct 2024 08:37:58 +0000 Subject: [PATCH 16/24] fix dockerfile --- docker/kurento-media-server-extras/Dockerfile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docker/kurento-media-server-extras/Dockerfile b/docker/kurento-media-server-extras/Dockerfile index 1d2c8dfa1f..a9b22bf138 100644 --- a/docker/kurento-media-server-extras/Dockerfile +++ b/docker/kurento-media-server-extras/Dockerfile @@ -50,6 +50,11 @@ # # docker logs --follow kms >"kms-$(date '+%Y%m%dT%H%M%S').log" 2>&1 + +# Global arguments for FROM. +ARG KMS_VERSION="latest" + + FROM kurento-media-server:${KMS_VERSION} LABEL maintainer="Saúl Pablo Labajo Izquierdo " From d6923b7bf56e8b617dc3c3b9fedb35b9b3c4f742 Mon Sep 17 00:00:00 2001 From: Saul Pablo Labajo Izquierdo Date: Wed, 23 Oct 2024 08:54:11 +0000 Subject: [PATCH 17/24] add extras to client generation --- .devcontainer/Dockerfile | 60 ++++++++++++++++++++++ .devcontainer/devcontainer.json | 58 +++++++++++++++++++++ .devcontainer/repo_cfg | 2 + .github/workflows/clients-java.parent.yaml | 10 ++++ 4 files changed, 130 insertions(+) create mode 100644 .devcontainer/Dockerfile create mode 100644 .devcontainer/devcontainer.json create mode 100644 .devcontainer/repo_cfg diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 0000000000..9041afc546 --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,60 @@ +ARG VARIANT="noble" +FROM mcr.microsoft.com/devcontainers/base:${VARIANT} +#FROM mcr.microsoft.com/vscode/devcontainers/base:0-${VARIANT} + +ENV DEBIAN_FRONTEND=noninteractive + +# [Optional] Uncomment this section to install additional OS packages. +# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ +# && apt-get -y install --no-install-recommends +RUN apt update && apt install -y --no-install-recommends \ + build-essential \ + ca-certificates \ + cmake \ + git \ + gnupg \ + gdb + +#RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 5AFA7A83 + +#COPY repo_cfg /tmp + +#RUN bash -c "source /etc/upstream-release/lsb-release 2>/dev/null || source /etc/lsb-release " +#RUN tee "/etc/apt/sources.list.d/kurento.list" >/dev/null < /tmp/repo_cfg \ +# && rm /tmp/repo_cfg && apt update + +#RUN apt install -y --no-install-recommends \ +# kurento-media-server-dev + +RUN apt update && apt install -y --no-install-recommends \ + maven pkg-config libjsoncpp-dev libboost-dev libboost-test-dev libboost-filesystem-dev libboost-system-dev libboost-thread-dev gstreamer1.0-x libgstreamer1.0-0 libgstreamer1.0-dev libvpx-dev \ + gstreamer1.0-libav gstreamer1.0-nice gstreamer1.0-plugins-ugly gstreamer1.0-plugins-bad \ + gstreamer1.0-plugins-good gstreamer1.0-tools libgstreamer-gl1.0-0 libgstreamer-opencv1.0-0 libgstreamer-plugins-bad1.0-0 libgstreamer-plugins-bad1.0-dev libgstreamer-plugins-base1.0-0 libgstreamer-plugins-base1.0-dev libgstreamer-plugins-good1.0-0 libgstreamer-plugins-good1.0-dev \ + libsigc++-2.0-dev libglibmm-2.4-dev libsoup2.4-dev libsoup2.4-1 libnice-dev libnice10 libboost-program-options-dev libboost-log-dev libevent-dev libevent-2.1-7 libevent-core-2.1-7 libevent-extra-2.1-7 libevent-openssl-2.1-7 libevent-pthreads-2.1-7 \ + libwebsocketpp-dev ffmpeg + +RUN apt install -y devscripts git-buildpackage equivs + +RUN wget https://download.java.net/java/GA/jdk22.0.1/c7ec1332f7bb44aeba2eb341ae18aca4/8/GPL/openjdk-22.0.1_linux-x64_bin.tar.gz + +RUN tar xvf openjdk-22.0.1_linux-x64_bin.tar.gz + +RUN mv jdk-22.0.1 /usr/lib/jvm + +RUN update-alternatives --install /usr/bin/javac javac /usr/lib/jvm/jdk-22.0.1/bin/javac 2211 +RUN update-alternatives --install /usr/bin/java java /usr/lib/jvm/jdk-22.0.1/bin/java 2211 + +RUN rm openjdk-22.0.1_linux-x64_bin.tar.gz + +RUN curl -sL https://deb.nodesource.com/setup_18.x | bash - + +RUN apt install -y nodejs + +RUN node --dns-result-order=ipv4first /usr/bin/npm install -g bower + + +# Ensure sudo group users are not +# asked for a password when using +# sudo command by ammending sudoers file +RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> \ +/etc/sudoers \ No newline at end of file diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000000..128449d9ad --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,58 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/ubuntu +{ + "name": "Ubuntu", + // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile + //"image": "mcr.microsoft.com/devcontainers/base:focal", + "build": { + "dockerfile": "Dockerfile", + // Update 'VARIANT' to pick an Ubuntu version: hirsute, focal, bionic + // Use hirsute or bionic on local arm64/Apple Silicon. + "args": { "VARIANT": "noble" } + }, + + "features": { + "ghcr.io/devcontainers-contrib/features/actions-runner:1": { + "version": "latest", + "dotnetVersion": "latest" + } + }, + + + // Add the IDs of extensions you want installed when the container is created. + "extensions": [ + "tintinweb.graphviz-interactive-preview", + "shd101wyy.markdown-preview-enhanced", + "vscjava.vscode-java-pack", + "vscjava.vscode-maven", + "ms-vscode.cpptools-themes", + "ms-azuretools.vscode-docker", + "ms-vscode.cpptools", + "twxs.cmake", + "ms-vscode.cmake-tools", + "mhutchie.git-graph", + "austin.code-gnu-global", + "fabiospampinato.vscode-git-history", + "ms-vscode.cpptools-extension-pack" + ], + + + "mounts": [ + "source=${localEnv:HOME}/.ssh,target=/home/ubuntu/.ssh,type=bind,consistency=cached" + ] + + // Features to add to the dev container. More info: https://containers.dev/features. + // "features": {}, + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [], + + // Use 'postCreateCommand' to run commands after the container is created. + // "postCreateCommand": "uname -a", + + // Configure tool-specific properties. + // "customizations": {}, + + // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. + "remoteUser": "ubuntu" +} diff --git a/.devcontainer/repo_cfg b/.devcontainer/repo_cfg new file mode 100644 index 0000000000..694a789eb1 --- /dev/null +++ b/.devcontainer/repo_cfg @@ -0,0 +1,2 @@ +# Kurento Media Server - Nightly packages +deb [arch=amd64] http://ubuntu.openvidu.io/7.0.0 focal main diff --git a/.github/workflows/clients-java.parent.yaml b/.github/workflows/clients-java.parent.yaml index 2c8df2bf8f..a2b3c08429 100644 --- a/.github/workflows/clients-java.parent.yaml +++ b/.github/workflows/clients-java.parent.yaml @@ -108,6 +108,16 @@ jobs: runnerGroup: ${{ inputs.runnerGroup }} secrets: inherit + module-videosampler: + needs: ["client"] + uses: "./.github/workflows/clients-java.child.yaml" + with: + directory: "server/module-extras/video-sampler/" + genModuleEnable: true + genModuleServerVersion: "${{ inputs.jobServerVersion }}" + runnerGroup: ${{ inputs.runnerGroup }} + secrets: inherit + # Unavailable since Kurento 7.0.0 #module-markerdetector: # needs: ["client"] From f2e3a7e51e7d9b51eceb79539fca6ead23c083b1 Mon Sep 17 00:00:00 2001 From: Saul Pablo Labajo Izquierdo Date: Wed, 23 Oct 2024 10:36:17 +0000 Subject: [PATCH 18/24] fix extras image tag --- ci-scripts/container_build.sh | 2 ++ docker/kurento-media-server-extras/Dockerfile | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/ci-scripts/container_build.sh b/ci-scripts/container_build.sh index b22287a52b..635d0bb0eb 100755 --- a/ci-scripts/container_build.sh +++ b/ci-scripts/container_build.sh @@ -66,6 +66,8 @@ set -o xtrace # Avoid illegal chars in tag name TAG=$(echo $TAG | tr '/' '_') +KMS_VERSION_TAG=$(echo $KMS_VERSION | tr '/' '_') +BUILD_ARGS+=" KMS_VERSION_TAG=$KMS_VERSION_TAG" [[ -z "${PUSH_IMAGES:-}" ]] && PUSH_IMAGES="no" [[ -z "${TAG_COMMIT:-}" ]] && TAG_COMMIT="yes" diff --git a/docker/kurento-media-server-extras/Dockerfile b/docker/kurento-media-server-extras/Dockerfile index a9b22bf138..2ff8826267 100644 --- a/docker/kurento-media-server-extras/Dockerfile +++ b/docker/kurento-media-server-extras/Dockerfile @@ -52,10 +52,10 @@ # Global arguments for FROM. -ARG KMS_VERSION="latest" +ARG KMS_VERSION_TAG="latest" -FROM kurento-media-server:${KMS_VERSION} +FROM kurento-media-server:${KMS_VERSION_TAG} LABEL maintainer="Saúl Pablo Labajo Izquierdo " From c9948d8feaa6345bcba8a506d445242a33537dca Mon Sep 17 00:00:00 2001 From: Saul Pablo Labajo Izquierdo Date: Wed, 23 Oct 2024 14:23:43 +0000 Subject: [PATCH 19/24] revert temporal fix --- ci-scripts/ci_job_deploy_docker.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-scripts/ci_job_deploy_docker.sh b/ci-scripts/ci_job_deploy_docker.sh index 24194af154..46c28dd34d 100755 --- a/ci-scripts/ci_job_deploy_docker.sh +++ b/ci-scripts/ci_job_deploy_docker.sh @@ -108,7 +108,7 @@ else fi # Run the Docker image builder -export PUSH_IMAGES="no" +export PUSH_IMAGES="yes" BUILD_ARGS="" BUILD_ARGS+=" UBUNTU_CODENAME=$JOB_DISTRO" BUILD_ARGS+=" KMS_VERSION=$DOCKER_KMS_VERSION" From 6b4757c186b0eb8491d8f4cd47a63a9c236c9d2f Mon Sep 17 00:00:00 2001 From: Saul Pablo Labajo Izquierdo Date: Wed, 23 Oct 2024 14:24:06 +0000 Subject: [PATCH 20/24] add javascript module extras generation --- .github/workflows/clients-javascript.parent.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/clients-javascript.parent.yaml b/.github/workflows/clients-javascript.parent.yaml index 064f9271d8..36b3b9506e 100644 --- a/.github/workflows/clients-javascript.parent.yaml +++ b/.github/workflows/clients-javascript.parent.yaml @@ -98,6 +98,16 @@ jobs: runnerGroup: ${{ inputs.runnerGroup }} secrets: inherit + module-videosampler: + uses: "./.github/workflows/clients-javascript.child.yaml" + with: + jobRelease: ${{ inputs.jobRelease }} + directory: "server/module-extras/video-sampler/" + genModuleEnable: true + genModuleServerVersion: "${{ inputs.jobServerVersion }}" + runnerGroup: ${{ inputs.runnerGroup }} + secrets: inherit + #module-markerdetector: # needs: ["client"] From 70e8129962bb74e6fac4fb4cec16ddae1360e4b1 Mon Sep 17 00:00:00 2001 From: Saul Pablo Labajo Izquierdo Date: Wed, 23 Oct 2024 14:41:08 +0000 Subject: [PATCH 21/24] fix tag generation --- ci-scripts/ci_job_deploy_docker.sh | 2 ++ ci-scripts/container_build.sh | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ci-scripts/ci_job_deploy_docker.sh b/ci-scripts/ci_job_deploy_docker.sh index 46c28dd34d..f5a5389358 100755 --- a/ci-scripts/ci_job_deploy_docker.sh +++ b/ci-scripts/ci_job_deploy_docker.sh @@ -112,6 +112,8 @@ export PUSH_IMAGES="yes" BUILD_ARGS="" BUILD_ARGS+=" UBUNTU_CODENAME=$JOB_DISTRO" BUILD_ARGS+=" KMS_VERSION=$DOCKER_KMS_VERSION" +KMS_VERSION_TAG=$(echo $DOCKER_KMS_VERSION | tr '/' '_') +BUILD_ARGS+=" KMS_VERSION_TAG=$KMS_VERSION_TAG" export BUILD_ARGS export TAG_COMMIT="no" if [[ "$JOB_RELEASE" == "true" ]]; then diff --git a/ci-scripts/container_build.sh b/ci-scripts/container_build.sh index 635d0bb0eb..b22287a52b 100755 --- a/ci-scripts/container_build.sh +++ b/ci-scripts/container_build.sh @@ -66,8 +66,6 @@ set -o xtrace # Avoid illegal chars in tag name TAG=$(echo $TAG | tr '/' '_') -KMS_VERSION_TAG=$(echo $KMS_VERSION | tr '/' '_') -BUILD_ARGS+=" KMS_VERSION_TAG=$KMS_VERSION_TAG" [[ -z "${PUSH_IMAGES:-}" ]] && PUSH_IMAGES="no" [[ -z "${TAG_COMMIT:-}" ]] && TAG_COMMIT="yes" From 2cf3005e6f9e210c6bb0a5fd3320cdd11f64fe43 Mon Sep 17 00:00:00 2001 From: Saul Pablo Labajo Izquierdo Date: Wed, 23 Oct 2024 18:48:07 +0000 Subject: [PATCH 22/24] fix base image name --- docker/kurento-media-server-extras/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/kurento-media-server-extras/Dockerfile b/docker/kurento-media-server-extras/Dockerfile index 2ff8826267..00c061edc9 100644 --- a/docker/kurento-media-server-extras/Dockerfile +++ b/docker/kurento-media-server-extras/Dockerfile @@ -55,7 +55,7 @@ ARG KMS_VERSION_TAG="latest" -FROM kurento-media-server:${KMS_VERSION_TAG} +FROM kurento/kurento-media-server:${KMS_VERSION_TAG} LABEL maintainer="Saúl Pablo Labajo Izquierdo " From d7081a08e357113674051bb3b37749cca0efec0d Mon Sep 17 00:00:00 2001 From: Saul Pablo Labajo Izquierdo Date: Thu, 24 Oct 2024 14:26:03 +0000 Subject: [PATCH 23/24] update docs --- .../videosampler.VideoSampler.kmd.json | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/server/module-extras/video-sampler/src/server/interface/videosampler.VideoSampler.kmd.json b/server/module-extras/video-sampler/src/server/interface/videosampler.VideoSampler.kmd.json index 06819aaa2d..b148fd746b 100644 --- a/server/module-extras/video-sampler/src/server/interface/videosampler.VideoSampler.kmd.json +++ b/server/module-extras/video-sampler/src/server/interface/videosampler.VideoSampler.kmd.json @@ -3,7 +3,26 @@ { "name": "VideoSampler", "extends": "MediaElement", - "doc": "VideoSampler interface. This type of :rom:cls:`Filter` samples at a configured rate frames from its video source and delivers it using gRPC to a configured destination.", + "doc": "VideoSampler interface. This type of :rom:cls:`Filter` samples at a configured rate frames from its video source and delivers it using gRPC to a configured destination. + The specification of the GRPC service that should receive images is as follows: +

+ + syntax = "proto3"; + + package videoSampler; + + service ImageDeliver { + rpc deliverImage (SampleImage) returns (Empty) {} + } + + message SampleImage { + string codec = 1; + bytes data = 2; + string timestamp = 3; + } + + message Empty { } + ", "constructor": { "doc": "Create a :rom:cls:`VideoSampler`", "params": [ From 77e53913166772025ef4b8c60b1e8929a81055a6 Mon Sep 17 00:00:00 2001 From: Saul Pablo Labajo Izquierdo Date: Tue, 14 Jan 2025 12:27:55 +0000 Subject: [PATCH 24/24] docker image creation script --- .../Dockerfile | 227 ----------- .../Dockerfile | 373 ++++++++++++++++++ .../README.md | 0 .../create_image.sh | 15 + .../entrypoint.sh | 0 .../extended_entrypoint.sh | 0 .../getmyip.sh | 0 .../healthchecker.sh | 0 .../tracedump_eu.sh | 0 .../tracedump_gdb.sh | 0 .../version.yml | 0 11 files changed, 388 insertions(+), 227 deletions(-) delete mode 100644 docker/kurento-media-server_deb_packages/Dockerfile create mode 100644 docker/kurento-media-server_local_image/Dockerfile rename docker/{kurento-media-server_deb_packages => kurento-media-server_local_image}/README.md (100%) create mode 100755 docker/kurento-media-server_local_image/create_image.sh rename docker/{kurento-media-server_deb_packages => kurento-media-server_local_image}/entrypoint.sh (100%) rename docker/{kurento-media-server_deb_packages => kurento-media-server_local_image}/extended_entrypoint.sh (100%) rename docker/{kurento-media-server_deb_packages => kurento-media-server_local_image}/getmyip.sh (100%) rename docker/{kurento-media-server_deb_packages => kurento-media-server_local_image}/healthchecker.sh (100%) rename docker/{kurento-media-server_deb_packages => kurento-media-server_local_image}/tracedump_eu.sh (100%) rename docker/{kurento-media-server_deb_packages => kurento-media-server_local_image}/tracedump_gdb.sh (100%) rename docker/{kurento-media-server_deb_packages => kurento-media-server_local_image}/version.yml (100%) diff --git a/docker/kurento-media-server_deb_packages/Dockerfile b/docker/kurento-media-server_deb_packages/Dockerfile deleted file mode 100644 index 914912f320..0000000000 --- a/docker/kurento-media-server_deb_packages/Dockerfile +++ /dev/null @@ -1,227 +0,0 @@ -# ==================== -# Kurento Media Server -# ==================== -# -# This Docker image is used to run an instance of Kurento Media Server. -# -# -# -# Build Command -# ============= -# -# Run: -# -# docker build [Args...] --tag kurento/kurento-media-server:latest . -# -# -# -# Build Arguments -# --------------- -# -# --build-arg UBUNTU_CODENAME= -# -# is like "focal". -# -# Optional. Default: "focal". -# -# --build-arg KMS_VERSION= -# -# is like "7.0.0". -# Alternatively, "dev" is used to build a nightly version of Kurento. -# -# Optional. Default: "dev". -# -# --build-arg APT_ARGS= -# -# is a string with arguments that will be passed to all -# executions of `apt-get`. -# -# Example: To Use an Apt package proxy -# Doc: http://manpages.ubuntu.com/manpages/man1/apt-transport-http.1.html#options -# -# APT_ARGS='-o Acquire::http::Proxy=http://user:pass@host:port/' -# -# Optional. Default: None. -# -# -# -# Run Command -# =========== -# -# Run: -# -# docker run --name kurento --network host kurento/kurento-media-server:latest -# -# Then, you can follow the logs with the `docker logs` command: -# -# docker logs --follow kms >"kms-$(date '+%Y%m%dT%H%M%S').log" 2>&1 - - - -# Global arguments for FROM. -ARG UBUNTU_CODENAME="noble" - - - -# Stage: Base system configuration -# ================================ - -FROM ubuntu:${UBUNTU_CODENAME} AS ubuntu_base - -ARG APT_ARGS="" - - - -# Stage: Install and prepare -# ========================== - -FROM ubuntu_base - -LABEL maintainer="Saúl Pablo Labajo Izquierdo " - -ARG UBUNTU_CODENAME - -ARG KMS_VERSION="dev" - -# Configure environment: -# Run apt-get/dpkg without interactive dialogue. -ARG DEBIAN_FRONTEND=noninteractive -# Set the default locale for all commands. -ENV LANG="C.UTF-8" - -# Copy .deb artifacts for deploying -RUN mkdir /kurento-deb - -COPY gst-plugin-rtp_0.12.4-1_amd64.deb /kurento-deb/gst-plugin-rtp_0.12.4-1_amd64.deb -COPY kurento-cmake-utils_7.1.0-1kurento1_all.deb /kurento-deb/ -COPY kurento-jsonrpc_7.1.0-1kurento1_amd64.deb /kurento-deb/ -COPY kurento-jsonrpc-dbgsym_7.1.0-1kurento1_amd64.ddeb /kurento-deb/ -COPY kurento-module-creator_7.1.0-1kurento1_all.deb /kurento-deb/ -COPY kurento-module-core_7.1.0-1kurento1_amd64.deb /kurento-deb/ -COPY kurento-module-core-dbgsym_7.1.0-1kurento1_amd64.ddeb /kurento-deb/ -COPY kurento-module-elements_7.1.0-1kurento1_amd64.deb /kurento-deb/ -COPY kurento-module-elements-dbgsym_7.1.0-1kurento1_amd64.ddeb /kurento-deb/ -COPY kurento-module-filters_7.1.0-1kurento1_amd64.deb /kurento-deb/ -COPY kurento-module-filters-dbgsym_7.1.0-1kurento1_amd64.ddeb /kurento-deb/ -COPY kurento-module-chroma_7.1.0-1kurento1_amd64.deb /kurento-deb/ -COPY kurento-module-chroma-dbgsym_7.1.0-1kurento1_amd64.ddeb /kurento-deb/ -COPY kurento-module-gstreamer-example_7.1.0-1kurento1_amd64.deb /kurento-deb/ -COPY kurento-module-gstreamer-example-dbgsym_7.1.0-1kurento1_amd64.ddeb /kurento-deb/ -COPY kurento-module-opencv-example_7.1.0-1kurento1_amd64.deb /kurento-deb/ -COPY kurento-module-opencv-example-dbgsym_7.1.0-1kurento1_amd64.ddeb /kurento-deb/ -COPY kurento-module-datachannelexample_7.1.0-1kurento1_amd64.deb /kurento-deb/ -COPY kurento-module-datachannelexample-dbgsym_7.1.0-1kurento1_amd64.ddeb /kurento-deb/ -COPY kurento-module-platedetector_7.1.0-1kurento1_amd64.deb /kurento-deb/ -COPY kurento-module-platedetector-dbgsym_7.1.0-1kurento1_amd64.ddeb /kurento-deb/ -COPY kurento-module-pointerdetector_7.1.0-1kurento1_amd64.deb /kurento-deb/ -COPY kurento-module-pointerdetector-dbgsym_7.1.0-1kurento1_amd64.ddeb /kurento-deb/ -COPY kurento-media-server_7.1.0-1kurento1_amd64.deb /kurento-deb/ -COPY kurento-media-server-dbgsym_7.1.0-1kurento1_amd64.ddeb /kurento-deb/ -COPY kurento-dbg_7.1.0-1kurento1_amd64.deb /kurento-deb/ - - -# For debugging purposes -COPY tracedump_gdb.sh / -COPY tracedump_eu.sh / -COPY extended_entrypoint.sh / - - -# Install tools: -# * ca-certificates: For HTTPS requests (e.g. with PlayerEndpoint). -# * curl: For `healthchecker.sh`. -# * dnsutils: For `dig` in `getmyip.sh`. -# * gnupg: For `apt-key adv` (Since Ubuntu 18.04). -# * nano: Not required but useful for edits while troubleshooting. -RUN \ -apt-get $APT_ARGS update && apt-get $APT_ARGS install --no-install-recommends --yes \ - ca-certificates \ - curl \ - dnsutils \ - gnupg \ - nano \ -&& rm -rf /var/lib/apt/lists/* - -# Install Gstreamer rust rtp plugins for AV1 support -RUN apt install --yes /kurento-deb/gst-plugin-rtp_0.12.4-1_amd64.deb - -# Install Kurento Media Server. -#RUN apt install /kurento-deb/kurento-cmake-utils_7.1.0-1kurento1_all.deb -RUN apt-get update - -RUN apt install --yes /kurento-deb/kurento-jsonrpc_7.1.0-1kurento1_amd64.deb -RUN apt install --yes /kurento-deb/kurento-jsonrpc-dbgsym_7.1.0-1kurento1_amd64.ddeb -RUN apt install --yes /kurento-deb/kurento-module-creator_7.1.0-1kurento1_all.deb -RUN apt install --yes /kurento-deb/kurento-module-core_7.1.0-1kurento1_amd64.deb -RUN apt install --yes /kurento-deb/kurento-module-core-dbgsym_7.1.0-1kurento1_amd64.ddeb -RUN apt install --yes /kurento-deb/kurento-module-elements_7.1.0-1kurento1_amd64.deb -RUN apt install --yes /kurento-deb/kurento-module-elements-dbgsym_7.1.0-1kurento1_amd64.ddeb -RUN apt install --yes /kurento-deb/kurento-module-filters_7.1.0-1kurento1_amd64.deb -RUN apt install --yes /kurento-deb/kurento-module-filters-dbgsym_7.1.0-1kurento1_amd64.ddeb -RUN apt install --yes /kurento-deb/kurento-media-server_7.1.0-1kurento1_amd64.deb -RUN apt install --yes /kurento-deb/kurento-media-server-dbgsym_7.1.0-1kurento1_amd64.ddeb - - -# Install additional modules. -# These might not be all available, so install separately and allow errors. -RUN apt install --yes /kurento-deb/kurento-module-chroma_7.1.0-1kurento1_amd64.deb -RUN apt install --yes /kurento-deb/kurento-module-chroma-dbgsym_7.1.0-1kurento1_amd64.ddeb -RUN apt install --yes /kurento-deb/kurento-module-gstreamer-example_7.1.0-1kurento1_amd64.deb -RUN apt install --yes /kurento-deb/kurento-module-gstreamer-example-dbgsym_7.1.0-1kurento1_amd64.ddeb -RUN apt install --yes /kurento-deb/kurento-module-opencv-example_7.1.0-1kurento1_amd64.deb -RUN apt install --yes /kurento-deb/kurento-module-opencv-example-dbgsym_7.1.0-1kurento1_amd64.ddeb -RUN apt install --yes /kurento-deb/kurento-module-datachannelexample_7.1.0-1kurento1_amd64.deb -RUN apt install --yes /kurento-deb/kurento-module-datachannelexample-dbgsym_7.1.0-1kurento1_amd64.ddeb -RUN apt install --yes /kurento-deb/kurento-module-platedetector_7.1.0-1kurento1_amd64.deb -RUN apt install --yes /kurento-deb/kurento-module-platedetector-dbgsym_7.1.0-1kurento1_amd64.ddeb -RUN apt install --yes /kurento-deb/kurento-module-pointerdetector_7.1.0-1kurento1_amd64.deb -RUN apt install --yes /kurento-deb/kurento-module-pointerdetector-dbgsym_7.1.0-1kurento1_amd64.ddeb - - -# Install additional tools that are indirectly used by some GStreamer plugins: -# * gstreamer-tools: Allows running the command `gst-inspect`. -# Useful for troubleshooting and debugging installed GStreamer plugins. -# * gstreamer-x: Video rendering plugins for X11 and Pango. -# Needed by some overlay elements like "textoverlay". -RUN \ -apt-get $APT_ARGS update && apt-get $APT_ARGS install --no-install-recommends --yes \ - gstreamer1.0-tools \ - gstreamer1.0-x \ -&& rm -rf /var/lib/apt/lists/* - -# Add Ubuntu debug repository key for apt-get. -RUN \ -apt-get $APT_ARGS update && apt-get $APT_ARGS install --no-install-recommends --yes \ - ubuntu-dbgsym-keyring \ -|| apt-key adv \ - --keyserver hkp://keyserver.ubuntu.com:80 \ - --recv-keys F2EDC64DC5AEE1F6B9C621F0C8CAB6595FDFF622 \ -&& rm -rf /var/lib/apt/lists/* - -# Add Ubuntu debug repository line for apt-get. -RUN \ -echo "deb http://ddebs.ubuntu.com $UBUNTU_CODENAME main restricted universe multiverse" >/etc/apt/sources.list.d/ddebs.list \ -&& echo "deb http://ddebs.ubuntu.com ${UBUNTU_CODENAME}-updates main restricted universe multiverse" >>/etc/apt/sources.list.d/ddebs.list - -# for debugging purposes -RUN apt clean && apt update && apt install --no-install-recommends --yes \ - gdb elfutils - - -# Install debug packages. -# The debug packages repository fails very often due to bad server state. -# Try to update, and only if it works install debug symbols. -#RUN apt-get update -#RUN apt install --yes /kurento-deb/kurento-dbg_7.0.2-1kurento1.24.04.deb - -RUN rm -rf /kurento-deb - -# Expose default Kurento RPC control port. -EXPOSE 8888 - -COPY entrypoint.sh / -COPY getmyip.sh / -COPY healthchecker.sh / - -HEALTHCHECK --start-period=15s --interval=30s --timeout=3s --retries=1 CMD /healthchecker.sh - -ENTRYPOINT ["/extended_entrypoint.sh"] diff --git a/docker/kurento-media-server_local_image/Dockerfile b/docker/kurento-media-server_local_image/Dockerfile new file mode 100644 index 0000000000..2cb956c418 --- /dev/null +++ b/docker/kurento-media-server_local_image/Dockerfile @@ -0,0 +1,373 @@ +# ==================== +# Kurento Media Server +# ==================== +# +# This Docker image is used to run an instance of Kurento Media Server. +# +# +# +# Build Command +# ============= +# +# Run: +# +# docker build [Args...] --tag kurento/kurento-media-server:latest . +# +# +# +# Build Arguments +# --------------- +# +# --build-arg UBUNTU_CODENAME= +# +# is like "focal". +# +# Optional. Default: "focal". +# +# --build-arg KMS_VERSION= +# +# is like "7.0.0". +# Alternatively, "dev" is used to build a nightly version of Kurento. +# +# Optional. Default: "dev". +# +# --build-arg APT_ARGS= +# +# is a string with arguments that will be passed to all +# executions of `apt-get`. +# +# Example: To Use an Apt package proxy +# Doc: http://manpages.ubuntu.com/manpages/man1/apt-transport-http.1.html#options +# +# APT_ARGS='-o Acquire::http::Proxy=http://user:pass@host:port/' +# +# Optional. Default: None. +# +# +# +# Run Command +# =========== +# +# Run: +# +# docker run --name kurento --network host kurento/kurento-media-server:latest +# +# Then, you can follow the logs with the `docker logs` command: +# +# docker logs --follow kms >"kms-$(date '+%Y%m%dT%H%M%S').log" 2>&1 + + + +# Global arguments for FROM. +ARG UBUNTU_CODENAME="noble" + +ARG KMS_VERSION="7.1.2" + + +# Stage: Kurento Compiling environment configuration +# ================================ + +FROM ubuntu:${UBUNTU_CODENAME} AS compile_env + +ENV DEBIAN_FRONTEND=noninteractive + +# [Optional] Uncomment this section to install additional OS packages. +# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ +# && apt-get -y install --no-install-recommends +RUN apt update && apt install -y --no-install-recommends \ + build-essential \ + ca-certificates \ + cmake \ + git \ + gnupg \ + gdb + +RUN apt update && apt install -y --no-install-recommends \ + maven pkg-config libjsoncpp-dev libboost-dev libboost-test-dev libboost-filesystem-dev libboost-system-dev libboost-thread-dev gstreamer1.0-x libgstreamer1.0-0 libgstreamer1.0-dev libvpx-dev \ + gstreamer1.0-libav gstreamer1.0-nice gstreamer1.0-plugins-ugly gstreamer1.0-plugins-bad \ + gstreamer1.0-plugins-good gstreamer1.0-tools libgstreamer-gl1.0-0 libgstreamer-opencv1.0-0 libgstreamer-plugins-bad1.0-0 libgstreamer-plugins-bad1.0-dev libgstreamer-plugins-base1.0-0 libgstreamer-plugins-base1.0-dev libgstreamer-plugins-good1.0-0 libgstreamer-plugins-good1.0-dev \ + libsigc++-2.0-dev libglibmm-2.4-dev libsoup2.4-dev libsoup2.4-1 libnice-dev libnice10 libboost-program-options-dev libboost-log-dev libevent-dev libevent-2.1-7 libevent-core-2.1-7 libevent-extra-2.1-7 libevent-openssl-2.1-7 libevent-pthreads-2.1-7 \ + libwebsocketpp-dev ffmpeg + +RUN apt install -y devscripts git-buildpackage equivs + +RUN wget https://download.java.net/java/GA/jdk22.0.1/c7ec1332f7bb44aeba2eb341ae18aca4/8/GPL/openjdk-22.0.1_linux-x64_bin.tar.gz + +RUN tar xvf openjdk-22.0.1_linux-x64_bin.tar.gz + +RUN mv jdk-22.0.1 /usr/lib/jvm + +RUN update-alternatives --install /usr/bin/javac javac /usr/lib/jvm/jdk-22.0.1/bin/javac 2211 +RUN update-alternatives --install /usr/bin/java java /usr/lib/jvm/jdk-22.0.1/bin/java 2211 + +RUN rm openjdk-22.0.1_linux-x64_bin.tar.gz + +# Stage: GStreamer-Rust Compiling environment configuration +# ================================ + +FROM compile_env AS compile_gst_rust + + +RUN apt update && apt install -y curl git build-essential pkg-config libssl-dev + +COPY --from=sources ./server/gst-plugins-rs/debian.diff / + +RUN \ +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y + +ENV \ +PATH=$PATH:/root/.cargo/bin + +RUN \ +rustup update + +# Install Rust cargo-deb +RUN \ + cargo install cargo-deb \ + && cargo install cargo-c + +RUN cd / && git clone https://github.com/GStreamer/gst-plugins-rs.git && \ + cd gst-plugins-rs && \ + git checkout 0.12.7 && \ + git apply /debian.diff && \ + cargo build --package gst-plugin-rtp --release && \ + mkdir -p /build/deb-source && \ + cp -a ./target/release/* /build/deb-source && \ + cargo deb --separate-debug-symbols -v --no-build --package=gst-plugin-rtp + + +FROM compile_env AS compile_kurento + +COPY --from=sources ./server /server +COPY --from=sources ./ci-scripts /ci-scripts + +RUN cd /server/cmake-utils && \ + /ci-scripts/kurento-buildpackage.sh --release && \ + apt install ./kurento-cmake-utils_7.1.2-1kurento1_all.deb && \ + cd .. + +RUN cd /server/jsonrpc && \ + /ci-scripts/kurento-buildpackage.sh --release && \ + apt install ./kurento-jsonrpc_7.1.2-1kurento1_amd64.deb && \ + apt install ./kurento-jsonrpc-dev_7.1.2-1kurento1_amd64.deb && \ + cd .. + +RUN cd /server/module-creator && \ + /ci-scripts/kurento-buildpackage.sh --release && \ + apt install ./kurento-module-creator_7.1.2-1kurento1_all.deb && \ + cd .. + +COPY --from=compile_gst_rust /gst-plugins-rs/target/debian/gst-plugin-rtp_0.12.7-1_amd64.deb /gst-plugin-rtp_0.12.7-1_amd64.deb +RUN apt install /gst-plugin-rtp_0.12.7-1_amd64.deb + +RUN cd /server/module-core && \ + /ci-scripts/kurento-buildpackage.sh --release && \ + apt install ./kurento-module-core_7.1.2-1kurento1_amd64.deb && \ + apt install ./kurento-module-core-dev_7.1.2-1kurento1_amd64.deb && \ + cd .. + +RUN cd /server/module-elements && \ + /ci-scripts/kurento-buildpackage.sh --release && \ + apt install ./kurento-module-elements_7.1.2-1kurento1_amd64.deb && \ + apt install ./kurento-module-elements-dev_7.1.2-1kurento1_amd64.deb && \ + cd .. + +RUN cd /server/module-filters && \ + /ci-scripts/kurento-buildpackage.sh --release && \ + apt install ./kurento-module-filters_7.1.2-1kurento1_amd64.deb && \ + apt install ./kurento-module-filters-dev_7.1.2-1kurento1_amd64.deb && \ + cd .. + +RUN cd /server/module-examples/chroma && \ + /ci-scripts/kurento-buildpackage.sh --release && \ + cd .. + +RUN cd /server/module-examples/gstreamer-example && \ + /ci-scripts/kurento-buildpackage.sh --release && \ + cd .. + +RUN cd /server/module-examples/opencv-example && \ + /ci-scripts/kurento-buildpackage.sh --release && \ + cd .. + +RUN cd /server/module-examples/datachannelexample && \ + /ci-scripts/kurento-buildpackage.sh --release && \ + cd .. + +RUN cd /server/module-examples/platedetector && \ + /ci-scripts/kurento-buildpackage.sh --release && \ + cd .. + +RUN cd /server/module-examples/pointerdetector && \ + /ci-scripts/kurento-buildpackage.sh --release && \ + cd ../.. + +RUN cd /server/media-server && \ + /ci-scripts/kurento-buildpackage.sh --release && \ + cd ../.. + + + +# Stage: Base system configuration +# ================================ + +FROM ubuntu:${UBUNTU_CODENAME} AS ubuntu_base + +ARG APT_ARGS="" + + + +# Stage: Install and prepare +# ========================== + +FROM ubuntu_base + +LABEL maintainer="Saúl Pablo Labajo Izquierdo " + +ARG UBUNTU_CODENAME + +ARG KMS_VERSION="dev" + +# Configure environment: +# Run apt-get/dpkg without interactive dialogue. +ARG DEBIAN_FRONTEND=noninteractive +# Set the default locale for all commands. +ENV LANG="C.UTF-8" + +# Copy .deb artifacts for deploying +RUN mkdir /kurento-deb + +COPY --from=compile_gst_rust /gst-plugins-rs/target/debian/gst-plugin-rtp_0.12.7-1_amd64.deb /kurento-deb/gst-plugin-rtp_0.12.7-1_amd64.deb +COPY --from=compile_kurento /server/cmake-utils/kurento-cmake-utils_7.1.2-1kurento1_all.deb /kurento-deb/ +COPY --from=compile_kurento /server/jsonrpc/kurento-jsonrpc_7.1.2-1kurento1_amd64.deb /kurento-deb/ +COPY --from=compile_kurento /server/jsonrpc/kurento-jsonrpc-dbgsym_7.1.2-1kurento1_amd64.ddeb /kurento-deb/ +COPY --from=compile_kurento /server/module-creator/kurento-module-creator_7.1.2-1kurento1_all.deb /kurento-deb/ +COPY --from=compile_kurento /server/module-core/kurento-module-core_7.1.2-1kurento1_amd64.deb /kurento-deb/ +COPY --from=compile_kurento /server/module-core/kurento-module-core-dbgsym_7.1.2-1kurento1_amd64.ddeb /kurento-deb/ +COPY --from=compile_kurento /server/module-elements/kurento-module-elements_7.1.2-1kurento1_amd64.deb /kurento-deb/ +COPY --from=compile_kurento /server/module-elements/kurento-module-elements-dbgsym_7.1.2-1kurento1_amd64.ddeb /kurento-deb/ +COPY --from=compile_kurento /server/module-filters/kurento-module-filters_7.1.2-1kurento1_amd64.deb /kurento-deb/ +COPY --from=compile_kurento /server/module-filters/kurento-module-filters-dbgsym_7.1.2-1kurento1_amd64.ddeb /kurento-deb/ +COPY --from=compile_kurento /server/module-examples/chroma/kurento-module-chroma_7.1.2-1kurento1_amd64.deb /kurento-deb/ +COPY --from=compile_kurento /server/module-examples/chroma/kurento-module-chroma-dbgsym_7.1.2-1kurento1_amd64.ddeb /kurento-deb/ +COPY --from=compile_kurento /server/module-examples/gstreamer-example/kurento-module-gstreamer-example_7.1.2-1kurento1_amd64.deb /kurento-deb/ +COPY --from=compile_kurento /server/module-examples/gstreamer-example/kurento-module-gstreamer-example-dbgsym_7.1.2-1kurento1_amd64.ddeb /kurento-deb/ +COPY --from=compile_kurento /server/module-examples/opencv-example/kurento-module-opencv-example_7.1.2-1kurento1_amd64.deb /kurento-deb/ +COPY --from=compile_kurento /server/module-examples/opencv-example/kurento-module-opencv-example-dbgsym_7.1.2-1kurento1_amd64.ddeb /kurento-deb/ +COPY --from=compile_kurento /server/module-examples/datachannelexample/kurento-module-datachannelexample_7.1.2-1kurento1_amd64.deb /kurento-deb/ +COPY --from=compile_kurento /server/module-examples/datachannelexample/kurento-module-datachannelexample-dbgsym_7.1.2-1kurento1_amd64.ddeb /kurento-deb/ +COPY --from=compile_kurento /server/module-examples/platedetector/kurento-module-platedetector_7.1.2-1kurento1_amd64.deb /kurento-deb/ +COPY --from=compile_kurento /server/module-examples/platedetector/kurento-module-platedetector-dbgsym_7.1.2-1kurento1_amd64.ddeb /kurento-deb/ +COPY --from=compile_kurento /server/module-examples/pointerdetector/kurento-module-pointerdetector_7.1.2-1kurento1_amd64.deb /kurento-deb/ +COPY --from=compile_kurento /server/module-examples/pointerdetector/kurento-module-pointerdetector-dbgsym_7.1.2-1kurento1_amd64.ddeb /kurento-deb/ +COPY --from=compile_kurento /server/media-server/kurento-media-server_7.1.2-1kurento1_amd64.deb /kurento-deb/ +COPY --from=compile_kurento /server/media-server/kurento-media-server-dbgsym_7.1.2-1kurento1_amd64.ddeb /kurento-deb/ +COPY --from=compile_kurento /server/media-server/kurento-dbg_7.1.2-1kurento1_amd64.deb /kurento-deb/ + + +# For debugging purposes +COPY tracedump_gdb.sh / +COPY tracedump_eu.sh / +COPY extended_entrypoint.sh / + + +# Install tools: +# * ca-certificates: For HTTPS requests (e.g. with PlayerEndpoint). +# * curl: For `healthchecker.sh`. +# * dnsutils: For `dig` in `getmyip.sh`. +# * gnupg: For `apt-key adv` (Since Ubuntu 18.04). +# * nano: Not required but useful for edits while troubleshooting. +RUN \ +apt-get $APT_ARGS update && apt-get $APT_ARGS install --no-install-recommends --yes \ + ca-certificates \ + curl \ + dnsutils \ + gnupg \ + nano \ +&& rm -rf /var/lib/apt/lists/* + +# Install Kurento Media Server. +#RUN apt install /kurento-deb/kurento-cmake-utils_7.1.2-1kurento1_all.deb +RUN apt-get update + +RUN apt install --yes /kurento-deb/kurento-jsonrpc_7.1.2-1kurento1_amd64.deb +RUN apt install --yes /kurento-deb/kurento-jsonrpc-dbgsym_7.1.2-1kurento1_amd64.ddeb +RUN apt install --yes /kurento-deb/kurento-module-creator_7.1.2-1kurento1_all.deb +RUN apt install --yes /kurento-deb/kurento-module-core_7.1.2-1kurento1_amd64.deb +RUN apt install --yes /kurento-deb/kurento-module-core-dbgsym_7.1.2-1kurento1_amd64.ddeb +RUN apt install --yes /kurento-deb/kurento-module-elements_7.1.2-1kurento1_amd64.deb +RUN apt install --yes /kurento-deb/kurento-module-elements-dbgsym_7.1.2-1kurento1_amd64.ddeb +RUN apt install --yes /kurento-deb/kurento-module-filters_7.1.2-1kurento1_amd64.deb +RUN apt install --yes /kurento-deb/kurento-module-filters-dbgsym_7.1.2-1kurento1_amd64.ddeb +RUN apt install --yes /kurento-deb/kurento-media-server_7.1.2-1kurento1_amd64.deb +RUN apt install --yes /kurento-deb/kurento-media-server-dbgsym_7.1.2-1kurento1_amd64.ddeb + + +# Install additional modules. +# These might not be all available, so install separately and allow errors. +RUN apt install --yes /kurento-deb/kurento-module-chroma_7.1.2-1kurento1_amd64.deb +RUN apt install --yes /kurento-deb/kurento-module-chroma-dbgsym_7.1.2-1kurento1_amd64.ddeb +RUN apt install --yes /kurento-deb/kurento-module-gstreamer-example_7.1.2-1kurento1_amd64.deb +RUN apt install --yes /kurento-deb/kurento-module-gstreamer-example-dbgsym_7.1.2-1kurento1_amd64.ddeb +RUN apt install --yes /kurento-deb/kurento-module-opencv-example_7.1.2-1kurento1_amd64.deb +RUN apt install --yes /kurento-deb/kurento-module-opencv-example-dbgsym_7.1.2-1kurento1_amd64.ddeb +RUN apt install --yes /kurento-deb/kurento-module-datachannelexample_7.1.2-1kurento1_amd64.deb +RUN apt install --yes /kurento-deb/kurento-module-datachannelexample-dbgsym_7.1.2-1kurento1_amd64.ddeb +RUN apt install --yes /kurento-deb/kurento-module-platedetector_7.1.2-1kurento1_amd64.deb +RUN apt install --yes /kurento-deb/kurento-module-platedetector-dbgsym_7.1.2-1kurento1_amd64.ddeb +RUN apt install --yes /kurento-deb/kurento-module-pointerdetector_7.1.2-1kurento1_amd64.deb +RUN apt install --yes /kurento-deb/kurento-module-pointerdetector-dbgsym_7.1.2-1kurento1_amd64.ddeb + + +# Install additional tools that are indirectly used by some GStreamer plugins: +# * gstreamer-tools: Allows running the command `gst-inspect`. +# Useful for troubleshooting and debugging installed GStreamer plugins. +# * gstreamer-x: Video rendering plugins for X11 and Pango. +# Needed by some overlay elements like "textoverlay". +RUN \ +apt-get $APT_ARGS update && apt-get $APT_ARGS install --no-install-recommends --yes \ + gstreamer1.0-tools \ + gstreamer1.0-x \ +&& rm -rf /var/lib/apt/lists/* + +# Install Gstreamer rust rtp plugins for AV1 support +RUN apt install --yes /kurento-deb/gst-plugin-rtp_0.12.7-1_amd64.deb + + +# Add Ubuntu debug repository key for apt-get. +RUN \ +apt-get $APT_ARGS update && apt-get $APT_ARGS install --no-install-recommends --yes \ + ubuntu-dbgsym-keyring \ +|| apt-key adv \ + --keyserver hkp://keyserver.ubuntu.com:80 \ + --recv-keys F2EDC64DC5AEE1F6B9C621F0C8CAB6595FDFF622 \ +&& rm -rf /var/lib/apt/lists/* + +# Add Ubuntu debug repository line for apt-get. +RUN \ +echo "deb http://ddebs.ubuntu.com $UBUNTU_CODENAME main restricted universe multiverse" >/etc/apt/sources.list.d/ddebs.list \ +&& echo "deb http://ddebs.ubuntu.com ${UBUNTU_CODENAME}-updates main restricted universe multiverse" >>/etc/apt/sources.list.d/ddebs.list + +# for debugging purposes +RUN apt clean && apt update && apt install --no-install-recommends --yes \ + gdb elfutils + + +# Install debug packages. +# The debug packages repository fails very often due to bad server state. +# Try to update, and only if it works install debug symbols. +#RUN apt-get update +#RUN apt install --yes /kurento-deb/kurento-dbg_7.0.2-1kurento1.24.04.deb + +RUN rm -rf /kurento-deb + +# Expose default Kurento RPC control port. +EXPOSE 8888 + +COPY entrypoint.sh / +COPY getmyip.sh / +COPY healthchecker.sh / + +HEALTHCHECK --start-period=15s --interval=30s --timeout=3s --retries=1 CMD /healthchecker.sh + +ENTRYPOINT ["/extended_entrypoint.sh"] diff --git a/docker/kurento-media-server_deb_packages/README.md b/docker/kurento-media-server_local_image/README.md similarity index 100% rename from docker/kurento-media-server_deb_packages/README.md rename to docker/kurento-media-server_local_image/README.md diff --git a/docker/kurento-media-server_local_image/create_image.sh b/docker/kurento-media-server_local_image/create_image.sh new file mode 100755 index 0000000000..2c4c3904f6 --- /dev/null +++ b/docker/kurento-media-server_local_image/create_image.sh @@ -0,0 +1,15 @@ +#!/bin/bash +#=============================================================================== +# +# FILE: create_image.sh +# +# USAGE: ./create_image.sh +# +# DESCRIPTION: Kurento Media Server docker image creation script +# +#=============================================================================== + +KMS_VERSION=7.1.2-dev +KMS_VERSION_BUILD_ARG=$(echo $KMS_VERSION | sed 's/-dev$//') + +docker build --build-context sources=../../ --build-arg KMS_VERSION=$KMS_VERSION_BULD_ARG -t kurento/kurento-media-server:$KMS_VERSION . \ No newline at end of file diff --git a/docker/kurento-media-server_deb_packages/entrypoint.sh b/docker/kurento-media-server_local_image/entrypoint.sh similarity index 100% rename from docker/kurento-media-server_deb_packages/entrypoint.sh rename to docker/kurento-media-server_local_image/entrypoint.sh diff --git a/docker/kurento-media-server_deb_packages/extended_entrypoint.sh b/docker/kurento-media-server_local_image/extended_entrypoint.sh similarity index 100% rename from docker/kurento-media-server_deb_packages/extended_entrypoint.sh rename to docker/kurento-media-server_local_image/extended_entrypoint.sh diff --git a/docker/kurento-media-server_deb_packages/getmyip.sh b/docker/kurento-media-server_local_image/getmyip.sh similarity index 100% rename from docker/kurento-media-server_deb_packages/getmyip.sh rename to docker/kurento-media-server_local_image/getmyip.sh diff --git a/docker/kurento-media-server_deb_packages/healthchecker.sh b/docker/kurento-media-server_local_image/healthchecker.sh similarity index 100% rename from docker/kurento-media-server_deb_packages/healthchecker.sh rename to docker/kurento-media-server_local_image/healthchecker.sh diff --git a/docker/kurento-media-server_deb_packages/tracedump_eu.sh b/docker/kurento-media-server_local_image/tracedump_eu.sh similarity index 100% rename from docker/kurento-media-server_deb_packages/tracedump_eu.sh rename to docker/kurento-media-server_local_image/tracedump_eu.sh diff --git a/docker/kurento-media-server_deb_packages/tracedump_gdb.sh b/docker/kurento-media-server_local_image/tracedump_gdb.sh similarity index 100% rename from docker/kurento-media-server_deb_packages/tracedump_gdb.sh rename to docker/kurento-media-server_local_image/tracedump_gdb.sh diff --git a/docker/kurento-media-server_deb_packages/version.yml b/docker/kurento-media-server_local_image/version.yml similarity index 100% rename from docker/kurento-media-server_deb_packages/version.yml rename to docker/kurento-media-server_local_image/version.yml