From bd172e54691114446730fe71acedbbc3d6d525e7 Mon Sep 17 00:00:00 2001 From: Vinayak Y B <89510107+Vinayak-YB@users.noreply.github.com> Date: Tue, 4 Jul 2023 18:06:19 +0530 Subject: [PATCH] Removing gstreamer dependency from aprapipes (#253) * initial commit * builder files changed to remove gstreamer * Removing gst based modules, other gstreamer files * small yml file fix --------- Co-authored-by: Vinayak Bhustali --- .github/workflows/CI-Linux-ARM64.yml | 1 - .github/workflows/CI-Win-CUDA.yml | 1 - .github/workflows/CI-Win-NoCUDA.yml | 2 - .../workflows/build-test-lin-container.yml | 12 - .github/workflows/build-test-lin-wsl.yml | 16 - .github/workflows/build-test-lin.yml | 13 - .github/workflows/build-test-win.yml | 12 - .gitmodules | 3 - base/CMakeLists.txt | 108 -- base/include/GstOnvifRtspSink.h | 83 -- base/include/GstWebRTCSink.h | 53 - base/src/GstOnvifRtspSink.cpp | 418 ------ base/src/GstWebRTCSink.cpp | 1133 ----------------- base/test/gstrtsponvifsink_tests.cpp | 237 ---- base/test/gstwebrtcsink_tests.cpp | 58 - base/vcpkg.json | 15 - base/webRTCcomponents/README_WebRTCSetup.md | 16 - base/webRTCcomponents/go.mod | 29 - base/webRTCcomponents/go.sum | 69 - .../goSignallingServer/main.go | 209 --- base/webRTCcomponents/index.html | 36 - base/webRTCcomponents/webrtc.js | 309 ----- thirdparty/build_gstreamer.bat | 31 - thirdparty/build_gstreamer.sh | 20 - thirdparty/gst-build | 1 - 25 files changed, 2885 deletions(-) delete mode 100644 base/include/GstOnvifRtspSink.h delete mode 100644 base/include/GstWebRTCSink.h delete mode 100644 base/src/GstOnvifRtspSink.cpp delete mode 100644 base/src/GstWebRTCSink.cpp delete mode 100644 base/test/gstrtsponvifsink_tests.cpp delete mode 100644 base/test/gstwebrtcsink_tests.cpp delete mode 100644 base/webRTCcomponents/README_WebRTCSetup.md delete mode 100644 base/webRTCcomponents/go.mod delete mode 100644 base/webRTCcomponents/go.sum delete mode 100644 base/webRTCcomponents/goSignallingServer/main.go delete mode 100644 base/webRTCcomponents/index.html delete mode 100644 base/webRTCcomponents/webrtc.js delete mode 100644 thirdparty/build_gstreamer.bat delete mode 100644 thirdparty/build_gstreamer.sh delete mode 160000 thirdparty/gst-build diff --git a/.github/workflows/CI-Linux-ARM64.yml b/.github/workflows/CI-Linux-ARM64.yml index b243d838d..438ef51a2 100644 --- a/.github/workflows/CI-Linux-ARM64.yml +++ b/.github/workflows/CI-Linux-ARM64.yml @@ -18,7 +18,6 @@ jobs: is-selfhosted: true cuda: 'ON' prep-cmd: 'echo skipping builder prep as I can not sudo' - is-build-gst: false cache-path: './none' cmake-conf-cmd: 'export VCPKG_FORCE_SYSTEM_BINARIES=1 && cmake -B . -DENABLE_ARM64=ON ../base' nProc: 6 diff --git a/.github/workflows/CI-Win-CUDA.yml b/.github/workflows/CI-Win-CUDA.yml index b23dc2ac8..19cdf2d8f 100644 --- a/.github/workflows/CI-Win-CUDA.yml +++ b/.github/workflows/CI-Win-CUDA.yml @@ -17,7 +17,6 @@ jobs: flav: 'Windows-cuda' cuda: 'ON' is-selfhosted: true - is-build-gst: false # part of vcpkg on windows nProc: 8 nTestTimeoutMins: 20 win-cuda-publish: diff --git a/.github/workflows/CI-Win-NoCUDA.yml b/.github/workflows/CI-Win-NoCUDA.yml index 64b8117ac..68afe1f43 100644 --- a/.github/workflows/CI-Win-NoCUDA.yml +++ b/.github/workflows/CI-Win-NoCUDA.yml @@ -17,7 +17,6 @@ jobs: flav: 'Win-nocuda' cuda: 'OFF' is-selfhosted: false - is-build-gst: false # part of vcpkg on windows is-prep-phase: true nProc: 3 win-nocuda-build-test: @@ -28,7 +27,6 @@ jobs: flav: 'Win-nocuda' is-selfhosted: false cuda: 'OFF' - is-build-gst: false # part of vcpkg on windows is-prep-phase: false nProc: 3 win-nocuda-publish: diff --git a/.github/workflows/build-test-lin-container.yml b/.github/workflows/build-test-lin-container.yml index 1dcb57ca4..ff11e42a6 100644 --- a/.github/workflows/build-test-lin-container.yml +++ b/.github/workflows/build-test-lin-container.yml @@ -48,11 +48,6 @@ on: description: 'this workflow is called for a prep phase: it will split vcpkg install into 2 portions to cache and save' default: false required: false - is-build-gst: - type: boolean - description: 'should we build GStreamer? we dont build on windows and ARM_Linux.' - default: true - required: false cache-path: type: string description: 'the folder which needs to be cached e.g. .cache/vcpkg' @@ -77,7 +72,6 @@ jobs: build: env: TEST_EXE: build/aprapipesut - LD_LIB_PATH: '${{github.workspace}}/thirdparty/gst-build/gst-build-1.16/outInstall/lib/x86_64-linux-gnu:${{github.workspace}}/thirdparty/Video_Codec_SDK_10.0.26/Lib/linux/stubs/x86_64:/usr/local/cuda-10.2/compat/:/usr/local/cuda/lib64:${LD_LIBRARY_PATH-}' CMAKE_TC_FILE: '../vcpkg/scripts/buildsystems/vcpkg.cmake' # Note: naming this variable as CMAKE_TOOLCHAIN_FILE can cause havoc!!! container: ghcr.io/kumaakh/aprapipes-build-x86-ubutu18.04-cuda:latest defaults: @@ -136,7 +130,6 @@ jobs: run: | cp -R /root/.cache /github/home/ || true ls ${{ inputs.cache-path }} || true - ls thirdparty/gst-build/gst-build-1.16/outInstall || true continue-on-error: true - name: Cache dependencies for fast cloud build @@ -145,15 +138,10 @@ jobs: with: path: | ${{ inputs.cache-path }} - ./thirdparty/gst-build/gst-build-1.16/outInstall/ ./thirdparty/libmp4/build key: ${{ inputs.flav }}-4-${{ hashFiles( 'base/vcpkg.json', 'vcpkg/baseline.json', 'submodule_ver.txt') }} restore-keys: ${{ inputs.flav }}- - - name: Build Gstreamer On Linux_x64 when it is not cached - if: ${{ inputs.is-build-gst && steps.cache-all.outputs.cache-hit != 'true'}} - working-directory: ${{github.workspace}}/thirdparty - run: sh ./build_gstreamer.sh - name: Build libmp4 when it is not cached if: ${{ steps.cache-all.outputs.cache-hit != 'true' }} diff --git a/.github/workflows/build-test-lin-wsl.yml b/.github/workflows/build-test-lin-wsl.yml index 6af60c04b..4b7df4215 100644 --- a/.github/workflows/build-test-lin-wsl.yml +++ b/.github/workflows/build-test-lin-wsl.yml @@ -48,11 +48,6 @@ on: description: 'this workflow is called for a prep phase: it will split vcpkg install into 2 portions to cache and save' default: false required: false - is-build-gst: - type: boolean - description: 'should we build GStreamer? we dont build on windows and ARM_Linux.' - default: true - required: false cache-path: type: string description: 'the folder which needs to be cached e.g. .cache/vcpkg' @@ -77,7 +72,6 @@ jobs: build: env: TEST_EXE: build/aprapipesut - LD_LIB_PATH: './thirdparty/gst-build/gst-build-1.16/outInstall/lib/x86_64-linux-gnu:./thirdparty/Video_Codec_SDK_10.0.26/Lib/linux/stubs/x86_64:/usr/local/cuda-10.2/compat/:/usr/local/cuda/lib64:${LD_LIBRARY_PATH-}' CMAKE_TC_FILE: '../vcpkg/scripts/buildsystems/vcpkg.cmake' # Note: naming this variable as CMAKE_TOOLCHAIN_FILE can cause havoc!!! runs-on: ${{ inputs.runner }} steps: @@ -139,7 +133,6 @@ jobs: run: | cp -R /root/.cache /github/home/ || true ls ${{ inputs.cache-path }} || true - ls thirdparty/gst-build/gst-build-1.16/outInstall || true continue-on-error: true - name: Cache dependencies for fast cloud build @@ -148,7 +141,6 @@ jobs: with: path: | ${{ inputs.cache-path }} - ./thirdparty/gst-build/gst-build-1.16/outInstall/ ./thirdparty/libmp4/build key: ${{ inputs.flav }}-4-${{ hashFiles( 'base/vcpkg.json', 'vcpkg/baseline.json', 'submodule_ver.txt') }} restore-keys: ${{ inputs.flav }}- @@ -156,17 +148,9 @@ jobs: - name: On WSL prep the thirdparty build scripts working-directory: ${{github.workspace}}/thirdparty run: | - (dos2unix ./build_gstreamer.sh) || true - chmod a+x ./build_gstreamer.sh (dos2unix libmp4/build.cmd) || true chmod a+x libmp4/build.cmd shell: wsl-bash {0} - - - name: Build Gstreamer On Linux_x64 when it is not cached - if: ${{ inputs.is-build-gst && steps.cache-all.outputs.cache-hit != 'true'}} - working-directory: ${{github.workspace}}/thirdparty - run: sh ./build_gstreamer.sh - shell: wsl-bash {0} - name: Build libmp4 when it is not cached if: ${{ steps.cache-all.outputs.cache-hit != 'true' }} diff --git a/.github/workflows/build-test-lin.yml b/.github/workflows/build-test-lin.yml index d1b6e030d..378395282 100644 --- a/.github/workflows/build-test-lin.yml +++ b/.github/workflows/build-test-lin.yml @@ -48,11 +48,6 @@ on: description: 'this workflow is called for a prep phase: it will split vcpkg install into 2 portions to cache and save' default: false required: false - is-build-gst: - type: boolean - description: 'should we build GStreamer? we dont build on windows and ARM_Linux.' - default: true - required: false cache-path: type: string description: 'the folder which needs to be cached e.g. .cache/vcpkg' @@ -77,7 +72,6 @@ jobs: build: env: TEST_EXE: build/aprapipesut - LD_LIB_PATH: '${{github.workspace}}/thirdparty/gst-build/gst-build-1.16/outInstall/lib/x86_64-linux-gnu:${{github.workspace}}/thirdparty/Video_Codec_SDK_10.0.26/Lib/linux/stubs/x86_64:/usr/local/cuda-10.2/compat/:/usr/local/cuda/lib64:${LD_LIBRARY_PATH-}' CMAKE_TC_FILE: '../vcpkg/scripts/buildsystems/vcpkg.cmake' # Note: naming this variable as CMAKE_TOOLCHAIN_FILE can cause havoc!!! runs-on: ${{ inputs.runner }} steps: @@ -132,7 +126,6 @@ jobs: run: | cp -R /root/.cache /github/home/ || true ls ${{ inputs.cache-path }} || true - ls thirdparty/gst-build/gst-build-1.16/outInstall || true continue-on-error: true - name: Cache dependencies for fast cloud build @@ -141,15 +134,9 @@ jobs: with: path: | ${{ inputs.cache-path }} - ./thirdparty/gst-build/gst-build-1.16/outInstall/ ./thirdparty/libmp4/build key: ${{ inputs.flav }}-4-${{ hashFiles( 'base/vcpkg.json', 'vcpkg/baseline.json', 'submodule_ver.txt') }} restore-keys: ${{ inputs.flav }}- - - - name: Build Gstreamer On Linux_x64 when it is not cached - if: ${{ inputs.is-build-gst && steps.cache-all.outputs.cache-hit != 'true'}} - working-directory: ${{github.workspace}}/thirdparty - run: sh ./build_gstreamer.sh - name: Build libmp4 when it is not cached if: ${{ steps.cache-all.outputs.cache-hit != 'true' }} diff --git a/.github/workflows/build-test-win.yml b/.github/workflows/build-test-win.yml index cc0742257..2bee05ebb 100644 --- a/.github/workflows/build-test-win.yml +++ b/.github/workflows/build-test-win.yml @@ -48,11 +48,6 @@ on: description: 'this workflow is called for a prep phase: it will split vcpkg install into 2 portions to cache and save' default: false required: false - is-build-gst: - type: boolean - description: 'should we build GStreamer? we dont build on windows and ARM_Linux.' - default: true - required: false cache-path: type: string description: 'the folder which needs to be cached e.g. .cache/vcpkg' @@ -134,7 +129,6 @@ jobs: run: | cp -R /root/.cache /github/home/ || true ls ${{ inputs.cache-path }} || true - ls thirdparty/gst-build/gst-build-1.16/outInstall || true continue-on-error: true - name: Cache dependencies for fast cloud build @@ -143,15 +137,9 @@ jobs: with: path: | ${{ inputs.cache-path }} - ${{ github.workspace }}/thirdparty/gst-build/gst-build-1.16/outInstall/ ${{ github.workspace }}/thirdparty/libmp4/build/Release/mp4lib.lib key: ${{ inputs.flav }}-3-${{ hashFiles( 'base/vcpkg.json', 'vcpkg/baseline.json', 'submodule_ver.txt') }} restore-keys: ${{ inputs.flav }}- - - - name: Build Gstreamer On Linux_x64 when it is not cached - if: ${{ inputs.is-build-gst && steps.cache-all.outputs.cache-hit != 'true'}} - working-directory: ${{github.workspace}}/thirdparty - run: sh ./build_gstreamer.sh - name: Build libmp4 when it is not cached if: ${{ steps.cache-all.outputs.cache-hit != 'true' }} diff --git a/.gitmodules b/.gitmodules index 1aa7a88b5..a076b053a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,9 +1,6 @@ [submodule "vcpkg"] path = vcpkg url = https://github.com/Apra-Labs/vcpkg -[submodule "thirdparty/gst-build"] - path = thirdparty/gst-build - url = https://gitlab.freedesktop.org/gstreamer/gst-build.git [submodule "thirdparty/libmp4"] path = thirdparty/libmp4 url = https://github.com/Apra-Labs/libmp4.git diff --git a/base/CMakeLists.txt b/base/CMakeLists.txt index 623cd36b7..05a38c996 100755 --- a/base/CMakeLists.txt +++ b/base/CMakeLists.txt @@ -4,11 +4,6 @@ OPTION(ENABLE_LINUX "Use this switch to enable LINUX" ON) OPTION(ENABLE_CUDA "Use this switch to enable CUDA" ON) OPTION(ENABLE_ARM64 "Use this switch to enable ARM64" OFF) OPTION(ENABLE_WINDOWS "Use this switch to enable WINDOWS" OFF) -OPTION(ENABLE_GST "Use this switch to integrate Gstreamer" ON) - -IF(ENABLE_ARM64) #no GST build for ARM64 yet - set(ENABLE_GST OFF) -ENDIF(ENABLE_ARM64) set(VCPKG_INSTALL_OPTIONS "--clean-after-build") IF(ENABLE_CUDA) @@ -41,10 +36,6 @@ project(APRAPIPES) set ( LIBMP4_LIB_DIR "../thirdparty/libmp4/build/") set ( LIBMP4_INC_DIR "../thirdparty/libmp4/include/") -IF(ENABLE_LINUX AND ENABLE_GST) - # no gst on arm64 yet, linux:x64 uses a non-vcpk build of gst - set(ENV{PKG_CONFIG_PATH} "${CMAKE_SOURCE_DIR}/../thirdparty/gst-build/gst-build-1.16/outInstall/lib/x86_64-linux-gnu/pkgconfig/") -ENDIF(ENABLE_LINUX AND ENABLE_GST) IF(ENABLE_WINDOWS) set (LIBMP4_LIB_DIR "${CMAKE_SOURCE_DIR}/../thirdparty/libmp4/build/${CMAKE_BUILD_TYPE}") @@ -57,28 +48,6 @@ message(STATUS ${LIBMP4_INC_DIR} ">>>>>> LIBMP4_INC_DIR") list(APPEND CMAKE_PREFIX_PATH ${LIBMP4_LIB_DIR}) find_library(LIBMP4_LIB NAMES mp4lib.lib libmp4lib.a REQUIRED) find_package(PkgConfig REQUIRED) - -IF(ENABLE_GST) - pkg_check_modules(gstreamer-1.0 REQUIRED IMPORTED_TARGET GLOBAL gstreamer-1.0) - pkg_check_modules(gobject-2.0 REQUIRED IMPORTED_TARGET GLOBAL gobject-2.0) - pkg_check_modules(glib-2.0 REQUIRED IMPORTED_TARGET GLOBAL glib-2.0) - pkg_check_modules(gio-2.0 REQUIRED IMPORTED_TARGET GLOBAL gio-2.0) - pkg_check_modules(gstreamer-rtp-1.0 REQUIRED IMPORTED_TARGET GLOBAL gstreamer-rtp-1.0) - pkg_check_modules(gstreamer-rtsp-1.0 REQUIRED IMPORTED_TARGET GLOBAL gstreamer-rtsp-1.0) - pkg_check_modules(gstreamer-rtsp-server-1.0 REQUIRED IMPORTED_TARGET GLOBAL gstreamer-rtsp-server-1.0) - pkg_check_modules(gstreamer-app-1.0 REQUIRED IMPORTED_TARGET GLOBAL gstreamer-app-1.0) - pkg_check_modules(gstreamer-net-1.0 REQUIRED IMPORTED_TARGET GLOBAL gstreamer-net-1.0) - pkg_check_modules(gstreamer-webrtc-1.0 REQUIRED IMPORTED_TARGET GLOBAL gstreamer-webrtc-1.0) - pkg_check_modules(libpcre REQUIRED IMPORTED_TARGET GLOBAL libpcre) - pkg_check_modules(gthread-2.0 REQUIRED IMPORTED_TARGET GLOBAL gthread-2.0) - pkg_check_modules(gmodule-2.0 REQUIRED IMPORTED_TARGET GLOBAL gmodule-2.0) - pkg_check_modules(gstreamer-base-1.0 REQUIRED IMPORTED_TARGET GLOBAL gstreamer-base-1.0) - IF(NOT ENABLE_WINDOWS) - pkg_check_modules(json-glib-1.0 REQUIRED IMPORTED_TARGET GLOBAL json-glib-1.0) - pkg_check_modules(libsoup-2.4 REQUIRED IMPORTED_TARGET GLOBAL libsoup-2.4) - ENDIF(NOT ENABLE_WINDOWS) - -ENDIF(ENABLE_GST) find_package(Boost COMPONENTS system thread filesystem serialization log chrono unit_test_framework REQUIRED) @@ -315,16 +284,6 @@ SET(IP_FILES ) -IF(ENABLE_GST) - IF(NOT ENABLE_WINDOWS) - list(APPEND IP_FILES - src/GstWebRTCSink.cpp - ) - ENDIF(NOT ENABLE_WINDOWS) - list(APPEND IP_FILES - src/GstOnvifRtspSink.cpp - ) -ENDIF(ENABLE_GST) SET(IP_FILES_H include/HistogramOverlay.h @@ -349,16 +308,6 @@ SET(IP_FILES_H ) -IF(ENABLE_GST) - IF(NOT ENABLE_WINDOWS) - list(APPEND IP_FILES - include/GstWebRTCSink.h - ) - ENDIF(NOT ENABLE_WINDOWS) - list(APPEND IP_FILES - include/GstOnvifRtspSink.h - ) -ENDIF(ENABLE_GST) SET(CUDA_CORE_FILES src/apra_cudamalloc_allocator.cu @@ -495,7 +444,6 @@ ENDIF(ENABLE_CUDA) message(STATUS "-------------Printing Soure file list-----------------${SOURCE}") add_library(aprapipes STATIC ${SOURCE}) -message(STATUS "-------------Printing Include folder-----------------${gstreamer-1.0_INCLUDE_DIRS}") target_include_directories ( aprapipes PRIVATE ${JETSON_MULTIMEDIA_LIB_INCLUDE} ${FFMPEG_INCLUDE_DIRS} @@ -505,32 +453,6 @@ ${LIBMP4_INC_DIR} ${NVCODEC_INCLUDE_DIR} ) -IF(ENABLE_GST) - target_include_directories ( aprapipes PRIVATE - ${gstreamer-app-1.0_INCLUDE_DIRS} - ${gstreamer-base-1.0_INCLUDE_DIRS} - ${gstreamer-1.0_INCLUDE_DIRS} - ${gstreamer-rtsp-server-1.0_INCLUDE_DIRS} - ${gstreamer-webrtc-1.0_INCLUDE_DIRS} - ${libpcre_INCLUDE_DIRS} - ${glib-2.0_INCLUDE_DIRS} - ${gstreamer-rtsp-1.0_INCLUDE_DIRS} - ${gstreamer-rtp-1.0_INCLUDE_DIRS} - ${gstreamer-net-1.0_INCLUDE_DIRS} - ${gio-2.0_INCLUDE_DIRS} - ${gmodule-2.0_INCLUDE_DIRS} - ${gthread-2.0_INCLUDE_DIRS} - ${gobject-2.0_INCLUDE_DIRS} - ) - IF(NOT ENABLE_WINDOWS) - target_include_directories( aprapipes PRIVATE - ${gstreamer-webrtc-1.0_INCLUDE_DIRS} - ${json-glib-1.0_INCLUDE_DIRS} - ${libsoup-2.4_INCLUDE_DIRS} - ) - ENDIF(NOT ENABLE_WINDOWS) -ENDIF(ENABLE_GST) - # aprapipes Unit Tests @@ -635,34 +557,6 @@ IF(ENABLE_LINUX) ) ENDIF(ENABLE_LINUX) -IF(ENABLE_GST) - SET(GST_LIBS - PkgConfig::gstreamer-app-1.0 - PkgConfig::gstreamer-base-1.0 - PkgConfig::gstreamer-1.0 - PkgConfig::gstreamer-rtsp-server-1.0 - PkgConfig::libpcre - PkgConfig::glib-2.0 - PkgConfig::gstreamer-rtsp-1.0 - PkgConfig::gstreamer-rtp-1.0 - PkgConfig::gstreamer-net-1.0 - ) - list(APPEND UT_FILES - test/gstrtsponvifsink_tests.cpp - ) - - IF(NOT ENABLE_WINDOWS) - list(APPEND GST_LIBS - PkgConfig::gstreamer-webrtc-1.0 - PkgConfig::json-glib-1.0 - PkgConfig::libsoup-2.4 - ) - list(APPEND UT_FILES - test/gstwebrtcsink_tests.cpp - ) - ENDIF(NOT ENABLE_WINDOWS) -ENDIF(ENABLE_GST) - add_executable(aprapipesut ${UT_FILES}) @@ -690,7 +584,6 @@ target_link_libraries(aprapipesut ${NVCODEC_LIB} ${NVJPEGLIB_L4T} ${CURSES_LIBRARIES} - ${GST_LIBS} ZXing::Core ZXing::ZXing BZip2::BZip2 @@ -701,7 +594,6 @@ target_link_libraries(aprapipesut ) IF(ENABLE_WINDOWS) - #file(GLOB RUNTIME_DLLS ../thirdparty/gst-build/gst-build-1.16/outInstall/bin/*.dll) file(COPY ${RUNTIME_DLLS} DESTINATION Debug/) file(COPY ${RUNTIME_DLLS} DESTINATION Release/) IF(GHA) diff --git a/base/include/GstOnvifRtspSink.h b/base/include/GstOnvifRtspSink.h deleted file mode 100644 index ab6fc536b..000000000 --- a/base/include/GstOnvifRtspSink.h +++ /dev/null @@ -1,83 +0,0 @@ -#pragma once - -#include "Module.h" -#include - -class GStreamerOnvifRTSPSinkProps : public ModuleProps -{ -public: - struct User - { - std::string username; - std::string password; - - size_t getSerializeSize() - { - return sizeof(username) + sizeof(password) + username.length() + password.length(); - } - - private: - friend class boost::serialization::access; - - template - void serialize(Archive &ar, const unsigned int version) - { - ar &username &password; - } - }; - GStreamerOnvifRTSPSinkProps(uint32_t _width = 1920, uint32_t _height = 1080, int _bitrate = 204800, int _goplength = 30, std::string _h264Profile = "baseline", std::string _port = "8554", std::string _htdigestPath = "./data/onvif_users.htdigest", std::string _realm = "Onvif_service", std::string _unicastAddress = "0.0.0.0", std::string _mountPoint = "/rgbcamera", std::vector _userList = {{"admin", "7ABCDE"}}) : ModuleProps(), width(_width), height(_height), bitrate(_bitrate), goplength(_goplength), h264Profile(_h264Profile), port(_port), htdigestPath(_htdigestPath), unicastAddress(_unicastAddress), realm(_realm), mountPoint(_mountPoint), userList(_userList) {} - // port, authpaths, rtspLinkInitial - uint32_t width; - uint32_t height; - std::vector userList; - int bitrate; - int goplength; - std::string h264Profile; - std::string port; - std::string htdigestPath; - std::string realm; - std::string unicastAddress; - std::string mountPoint; - size_t getSerializeSize() - { - size_t totalUserListSize = 0; - - for (User &user : userList) - { - totalUserListSize += user.getSerializeSize(); - } - return totalUserListSize + ModuleProps::getSerializeSize() + sizeof(width) + sizeof(height) + sizeof(userList) + sizeof(bitrate) + sizeof(goplength) + sizeof(h264Profile) + h264Profile.length() + sizeof(port) + port.length() + sizeof(htdigestPath) + htdigestPath.length() + sizeof(realm) + realm.length() + sizeof(unicastAddress) + unicastAddress.length() + sizeof(mountPoint) + mountPoint.length(); - } - -private: - friend class boost::serialization::access; - - template - void serialize(Archive &ar, const unsigned int version) - { - ar &boost::serialization::base_object(*this); - ar &width &height &userList &bitrate &goplength &h264Profile &port &htdigestPath &realm &unicastAddress &mountPoint; - } -}; - -class GStreamerOnvifRTSPSink : public Module -{ - -public: - GStreamerOnvifRTSPSink(GStreamerOnvifRTSPSinkProps props); - virtual ~GStreamerOnvifRTSPSink(); - bool init(); - bool term(); - class Detail; - boost::shared_ptr mDetail; - void setProps(GStreamerOnvifRTSPSinkProps &props); - GStreamerOnvifRTSPSinkProps getProps(); - -protected: - bool process(frame_container &frames); - bool processSOS(frame_sp &frame); - bool validateInputPins(); - bool shouldTriggerSOS(); - bool processEOS(string &pinId); - bool handlePropsChange(frame_sp &frame); -}; \ No newline at end of file diff --git a/base/include/GstWebRTCSink.h b/base/include/GstWebRTCSink.h deleted file mode 100644 index 4c8a7b113..000000000 --- a/base/include/GstWebRTCSink.h +++ /dev/null @@ -1,53 +0,0 @@ -#pragma once - -#include "Module.h" - -class GStreamerWebRTCSinkProps : public ModuleProps -{ -public: - GStreamerWebRTCSinkProps(uint32_t _width = 640, uint32_t _height = 480, int _bitrate = 2048, int _goplength = 1, std::string _h264Profile = "high", std::string _peerId = "" , std::string _signallingSrvEndpoint="") : ModuleProps(), width(_width), height(_height), bitrate(_bitrate), goplength(_goplength), h264Profile(_h264Profile), peerId(_peerId), signallingSrvEndpoint(_signallingSrvEndpoint) {} - - uint32_t width; - uint32_t height; - int bitrate; - int goplength; - std::string h264Profile; - std::string peerId; - std::string signallingSrvEndpoint; - size_t getSerializeSize() - { - return ModuleProps::getSerializeSize() + sizeof(width) + sizeof(height) + sizeof(bitrate) + sizeof(goplength) + sizeof(h264Profile) + h264Profile.length() + sizeof(peerId) + peerId.length() + sizeof(signallingSrvEndpoint) + signallingSrvEndpoint.length(); - } - -private: - friend class boost::serialization::access; - - template - void serialize(Archive &ar, const unsigned int version) - { - ar &boost::serialization::base_object(*this); - ar &width &height &bitrate &goplength &h264Profile &peerId &signallingSrvEndpoint; - } -}; - -class GStreamerWebRTCSink : public Module -{ - -public: - GStreamerWebRTCSink(GStreamerWebRTCSinkProps props); - virtual ~GStreamerWebRTCSink(); - bool init(); - bool term(); - class Detail; - boost::shared_ptr mDetail; - void setProps(GStreamerWebRTCSinkProps &props); - GStreamerWebRTCSinkProps getProps(); - -protected: - bool process(frame_container &frames); - bool processSOS(frame_sp &frame); - bool validateInputPins(); - bool shouldTriggerSOS(); - bool processEOS(string &pinId); - bool handlePropsChange(frame_sp &frame); -}; diff --git a/base/src/GstOnvifRtspSink.cpp b/base/src/GstOnvifRtspSink.cpp deleted file mode 100644 index 0c4a14667..000000000 --- a/base/src/GstOnvifRtspSink.cpp +++ /dev/null @@ -1,418 +0,0 @@ -#include "GstOnvifRtspSink.h" -#include "FrameMetadata.h" -#include "H264Metadata.h" - -#include "Frame.h" -#include "Logger.h" -#include "Utils.h" -#include "AIPExceptions.h" - -#include -#include -#include -#include -#include - -void media_configure(GstRTSPMediaFactory *factory, GstRTSPMedia *media, gpointer user_data); - -void start_feed(GstElement *pipeline, guint size, gpointer user_data); - -void read_data(void *user_data); - -void stop_feed(GstElement *pipeline, void *user_data); - -struct GSTContext -{ -public: - GstElement *element; - GstElement *appsrc; - guint sourceid; - GstClockTime timestamp; -}; - -class GStreamerOnvifRTSPSink::Detail -{ -public: - Detail(GStreamerOnvifRTSPSinkProps &_props, std::function _step) : mProps(_props), mStep(_step), ctx(nullptr) - { - } - - ~Detail() - { - } - - void setMetadata(framemetadata_sp &metadata) - { - frameType = metadata->getFrameType(); - if (frameType == FrameMetadata::H264_DATA) - { - auto inputH264Metadata = FrameMetadataFactory::downcast(metadata); - width = inputH264Metadata->getWidth(); - height = inputH264Metadata->getHeight(); - } - else if (frameType == FrameMetadata::RAW_IMAGE_PLANAR) - { - auto inputRawMetadata = FrameMetadataFactory::downcast(metadata); - width = mProps.width; - height = mProps.height; - } - else if (frameType == FrameMetadata::RAW_IMAGE) - { - auto inputRawMetadata = FrameMetadataFactory::downcast(metadata); - width = inputRawMetadata->getWidth(); - height = inputRawMetadata->getHeight(); - } - } - - void setProps(GStreamerOnvifRTSPSinkProps &props) - { - mProps = props; - } - - GStreamerOnvifRTSPSinkProps getProps() - { - return mProps; - } - - gboolean read_data_actual(GSTContext *ctx) - { - GstMapInfo map; - GstFlowReturn gstret; - buffer = gst_buffer_new_allocate(NULL, frame->size(), NULL); - gst_buffer_map(buffer, &map, GST_MAP_WRITE); - - map.size = frame->size(); - memcpy(map.data, frame->data(), frame->size()); - GST_BUFFER_PTS(buffer) = ctx->timestamp; - GST_BUFFER_DURATION(buffer) = gst_util_uint64_scale_int(1, GST_SECOND, mProps.fps); - ctx->timestamp += GST_BUFFER_DURATION(buffer); - - if (frame->size() > 0) - { - gstret = gst_app_src_push_buffer((GstAppSrc *)ctx->appsrc, buffer); - if (gstret != GST_FLOW_OK) - { - g_source_remove(ctx->sourceid); - ctx->sourceid = 0; - return false; - } - } - else - { - printf("\n failed to read\n"); - return false; - } - - gst_buffer_unmap(buffer, &map); - - return true; - } - - void media_configure_helper(GstRTSPMediaFactory *factory, GstRTSPMedia *media) - { - - ctx = g_new0(GSTContext, 1); - - ctx->element = gst_rtsp_media_get_element(media); - - ctx->appsrc = gst_bin_get_by_name_recurse_up(GST_BIN(ctx->element), - "gstsrc"); - - gst_util_set_object_arg(G_OBJECT(ctx->appsrc), "format", "time"); - g_object_set(G_OBJECT(ctx->appsrc), "format", GST_FORMAT_TIME, NULL); - - if (frameType == FrameMetadata::H264_DATA) - { - g_object_set(G_OBJECT(ctx->appsrc), "caps", - gst_caps_new_simple("video/x-h264", - "format", G_TYPE_STRING, "I420", - "width", G_TYPE_INT, (gint)mProps.width, - "height", G_TYPE_INT, (gint)mProps.height, - "framerate", GST_TYPE_FRACTION, 0, 1, NULL), - NULL); - } - else if (frameType == FrameMetadata::RAW_IMAGE_PLANAR) - { - g_object_set(G_OBJECT(ctx->appsrc), "caps", - gst_caps_new_simple("video/x-raw", - "format", G_TYPE_STRING, "I420", - "width", G_TYPE_INT, (gint)mProps.width, - "height", G_TYPE_INT, (gint)mProps.height, - "framerate", GST_TYPE_FRACTION, 0, 1, NULL), - NULL); - } - - else if (frameType == FrameMetadata::RAW_IMAGE) - { - g_object_set(G_OBJECT(ctx->appsrc), "caps", - gst_caps_new_simple("video/x-raw", - "format", G_TYPE_STRING, "RGB", - "width", G_TYPE_INT, (gint)mProps.width, - "height", G_TYPE_INT, (gint)mProps.height, - "framerate", GST_TYPE_FRACTION, mProps.fps, 1, NULL), - NULL); - } - - g_object_set_data_full(G_OBJECT(media), "my-extra-data", ctx, - (GDestroyNotify)g_free); - - g_signal_connect(ctx->appsrc, "need-data", G_CALLBACK(start_feed), this); - g_signal_connect(ctx->appsrc, "enough-data", G_CALLBACK(stop_feed), this); - } - - bool gstreamerMainThread(GMainLoop *loop) - { - - gst_init(0, NULL); - - loop = g_main_loop_new(NULL, FALSE); - - server = gst_rtsp_onvif_server_new(); - - mounts = gst_rtsp_server_get_mount_points(server); - - factory = gst_rtsp_media_factory_new(); - - if (frameType == FrameMetadata::H264_DATA) - { - gst_rtsp_media_factory_set_launch(factory, "(appsrc is-live=TRUE block=TRUE name=gstsrc min-latency=0 ! video/x-h264,stream-format=byte-stream ! queue ! h264parse ! rtph264pay name=pay0 pt=96 )"); - } - - else if (frameType == FrameMetadata::RAW_IMAGE_PLANAR) - { - sprintf(pipelineDescription, "(appsrc is-live=TRUE name=gstsrc ! x264enc tune=zerolatency speed-preset=superfast bitrate=%d key-int-max=%d ! video/x-h264, stream-format=byte-stream , profile=%s ! queue ! h264parse ! rtph264pay name=pay0 pt=96 )", mProps.bitrate, mProps.goplength, mProps.h264Profile.c_str()); - gst_rtsp_media_factory_set_launch(factory, pipelineDescription); - } - - else if (frameType == FrameMetadata::RAW_IMAGE) - { - sprintf(pipelineDescription, "(appsrc is-live=TRUE block=TRUE name=gstsrc min-latency=0 ! videoconvert ! video/x-raw, format=I420 ! x264enc tune=zerolatency speed-preset=superfast bitrate=%d key-int-max=%d ! video/x-h264, stream-format=byte-stream, profile=%s ! rtph264pay name=pay0 pt=96 )", mProps.bitrate, mProps.goplength, mProps.h264Profile.c_str()); - gst_rtsp_media_factory_set_launch(factory, pipelineDescription); - } - - g_signal_connect(factory, "media-configure", (GCallback)media_configure, this); - - gst_rtsp_mount_points_add_factory(mounts, mProps.mountPoint.c_str(), factory); - - gst_rtsp_media_factory_set_shared(factory, true); - - gst_rtsp_media_factory_add_role(factory, "user", - GST_RTSP_PERM_MEDIA_FACTORY_ACCESS, G_TYPE_BOOLEAN, TRUE, - GST_RTSP_PERM_MEDIA_FACTORY_CONSTRUCT, G_TYPE_BOOLEAN, TRUE, NULL); - - g_object_unref(mounts); - - auth = gst_rtsp_auth_new(); - - gst_rtsp_auth_set_supported_methods(auth, GST_RTSP_AUTH_DIGEST); - - if (!mProps.htdigestPath.empty()) - { - token = - gst_rtsp_token_new(GST_RTSP_TOKEN_MEDIA_FACTORY_ROLE, G_TYPE_STRING, - "user", NULL); - - if (!gst_rtsp_auth_parse_htdigest(auth, mProps.htdigestPath.c_str(), token)) - { - g_printerr("Could not parse htdigest at %s\n", mProps.htdigestPath.c_str()); - gst_rtsp_token_unref(token); - goto failed; - } - - gst_rtsp_token_unref(token); - } - - if (!mProps.realm.empty()) - gst_rtsp_auth_set_realm(auth, mProps.realm.c_str()); - - gst_rtsp_server_set_auth(server, auth); - gst_rtsp_server_set_address(server, mProps.unicastAddress.c_str()); - gst_rtsp_server_set_service(server, mProps.port.c_str()); - g_object_unref(auth); - - if (gst_rtsp_server_attach(server, NULL) == 0) - goto failed; - - if (!mProps.htdigestPath.empty()) - g_print("use this to connect : ffplay rtsp://admin:7ABCDE@%s:%d%s\n", mProps.unicastAddress.c_str(), gst_rtsp_server_get_bound_port(server), mProps.mountPoint.c_str()); - - g_main_loop_run(loop); - - failed: - { - g_print("failed to attach the server\n"); - return false; - } - - return true; - } - -public: - GStreamerOnvifRTSPSinkProps mProps; - GstBuffer *buffer; - GSTContext *ctx; - GMainLoop *loop; - GstRTSPServer *server; - GstRTSPMountPoints *mounts; - GstRTSPMediaFactory *factory; - GstRTSPAuth *auth; - GstRTSPToken *token; - frame_sp frame; - int width = 0; - int height; - char pipelineDescription[10000]; - FrameMetadata::FrameType frameType; - std::function mStep; - std::thread gstThread; -}; - -void media_configure(GstRTSPMediaFactory *factory, GstRTSPMedia *media, gpointer user_data) -{ - auto detail = static_cast(user_data); - detail->media_configure_helper(factory, media); - return; -} - -void start_feed(GstElement *pipeline, guint size, void *user_data) -{ - auto detail = static_cast(user_data); - if (detail->ctx->sourceid == 0) - { - detail->ctx->sourceid = g_idle_add((GSourceFunc)read_data, user_data); - } - return; -} - -void read_data(void *user_data) -{ - auto detail = static_cast(user_data); - detail->mStep(); - return; -} - -void stop_feed(GstElement *pipeline, void *user_data) -{ - auto detail = static_cast(user_data); - if (detail->ctx->sourceid != 0) - { - g_source_remove(detail->ctx->sourceid); - detail->ctx->sourceid = 0; - } - return; -} - -GStreamerOnvifRTSPSink::GStreamerOnvifRTSPSink(GStreamerOnvifRTSPSinkProps props) : Module(SINK, "GStreamerOnvifRTSPSink", props) -{ - mDetail.reset(new Detail(props, [&]() -> void - { Module::step(); })); -} - -GStreamerOnvifRTSPSink::~GStreamerOnvifRTSPSink() {} - -bool GStreamerOnvifRTSPSink::init() -{ - if (!Module::init()) - { - return false; - } - - framemetadata_sp metadata = getFirstInputMetadata(); - mDetail->setMetadata(metadata); - - mDetail->gstThread = std::thread(&GStreamerOnvifRTSPSink::Detail::gstreamerMainThread, mDetail.get(), mDetail->loop); - - return true; -} - -bool GStreamerOnvifRTSPSink::term() -{ - - g_main_loop_quit(mDetail->loop); - mDetail->gstThread.join(); - gst_deinit(); - return Module::term(); -} - -bool GStreamerOnvifRTSPSink::validateInputPins() -{ - if (getNumberOfInputPins() != 1) - { - LOG_ERROR << "<" << getId() << ">::validateInputPins size is expected to be 1. Actual<" << getNumberOfInputPins() << ">"; - return false; - } - - framemetadata_sp metadata = getFirstInputMetadata(); - - FrameMetadata::FrameType frameType = metadata->getFrameType(); - if (frameType != FrameMetadata::H264_DATA && frameType != FrameMetadata::RAW_IMAGE_PLANAR && frameType != FrameMetadata::RAW_IMAGE) - { - LOG_ERROR << "<" << getId() << ">::validateInputPins input frameType is expected to be H264 or RAW or RAW_PLANAR. Actual<" << frameType << ">"; - return false; - } - return true; -} - -bool GStreamerOnvifRTSPSink::process(frame_container &frames) -{ - mDetail->frame = frames.cbegin()->second; - mDetail->read_data_actual(mDetail->ctx); - return true; -} - -bool GStreamerOnvifRTSPSink::processSOS(frame_sp &frame) -{ - return true; -} - -bool GStreamerOnvifRTSPSink::shouldTriggerSOS() -{ - return mDetail->width == 0; -} - -bool GStreamerOnvifRTSPSink::processEOS(string &pinId) -{ - return false; -} - -GStreamerOnvifRTSPSinkProps GStreamerOnvifRTSPSink::getProps() -{ - auto mProps = mDetail->getProps(); - fillProps(mProps); - - return mProps; -} - -void GStreamerOnvifRTSPSink::setProps(GStreamerOnvifRTSPSinkProps &mProps) -{ - Module::addPropsToQueue(mProps); -} - -bool GStreamerOnvifRTSPSink::handlePropsChange(frame_sp &frame) -{ - GStreamerOnvifRTSPSinkProps mProps; - bool ret = Module::handlePropsChange(frame, mProps); - mDetail->setProps(mProps); - - GstRTSPAuth *newauth = gst_rtsp_auth_new(); - gst_rtsp_auth_set_supported_methods(newauth, GST_RTSP_AUTH_DIGEST); - gst_rtsp_auth_set_realm(newauth, mDetail->mProps.realm.c_str()); - - GstRTSPToken *token = gst_rtsp_token_new(GST_RTSP_TOKEN_MEDIA_FACTORY_ROLE, - G_TYPE_STRING, - "user", NULL); - - for (const auto &user : mDetail->mProps.userList) - { - gst_rtsp_auth_add_digest(newauth, user.username.c_str(), user.password.c_str(), token); - - } - gst_rtsp_token_unref(token); - gst_rtsp_server_set_auth(mDetail->server, newauth); - if (mDetail->auth) - g_object_unref(mDetail->auth); - mDetail->auth = newauth; - - sendEOS(); - - return ret; -} diff --git a/base/src/GstWebRTCSink.cpp b/base/src/GstWebRTCSink.cpp deleted file mode 100644 index 7ed04be5b..000000000 --- a/base/src/GstWebRTCSink.cpp +++ /dev/null @@ -1,1133 +0,0 @@ -#include "GstWebRTCSink.h" -#include "FrameMetadata.h" -#include "H264Metadata.h" - -#include "Frame.h" -#include "Logger.h" -#include "Utils.h" -#include "AIPExceptions.h" - -#include -#include -#include - -#include - -#define GST_USE_UNSTABLE_API -#include - -/* For signalling */ -#include -#include - -#include -#include - -#ifndef __KMS_AGNOSTIC_CAPS_H__ -#define __KMS_AGNOSTIC_CAPS_H__ - -#define KMS_AGNOSTIC_RAW_AUDIO_CAPS \ - "audio/x-raw;" - -#define KMS_AGNOSTIC_RAW_VIDEO_CAPS \ - "video/x-raw;" - -#define KMS_AGNOSTIC_RAW_CAPS \ - KMS_AGNOSTIC_RAW_AUDIO_CAPS \ - KMS_AGNOSTIC_RAW_VIDEO_CAPS - -#define KMS_AGNOSTIC_RTP_AUDIO_CAPS \ - "application/x-rtp,media=audio;" - -#define KMS_AGNOSTIC_RTP_VIDEO_CAPS \ - "application/x-rtp,media=video;" - -#define KMS_AGNOSTIC_RTP_CAPS \ - KMS_AGNOSTIC_RTP_AUDIO_CAPS \ - KMS_AGNOSTIC_RTP_VIDEO_CAPS - -#define KMS_AGNOSTIC_FORMATS_AUDIO_CAPS \ - "audio/x-sbc;" \ - "audio/x-mulaw;" \ - "audio/x-flac;" \ - "audio/x-alaw;" \ - "audio/x-speex;" \ - "audio/x-ac3;" \ - "audio/x-alac;" \ - "audio/mpeg,mpegversion=1,layer=2;" \ - "audio/x-nellymoser;" \ - "audio/x-gst_ff-sonic;" \ - "audio/x-gst_ff-sonicls;" \ - "audio/x-wma,wmaversion=1;" \ - "audio/x-wma,wmaversion=2;" \ - "audio/x-dpcm,layout=roq;" \ - "audio/x-adpcm,layout=adx;" \ - "audio/x-adpcm,layout=g726;" \ - "audio/x-adpcm,layout=quicktime;" \ - "audio/x-adpcm,layout=dvi;" \ - "audio/x-adpcm,layout=microsoft;" \ - "audio/x-adpcm,layout=swf;" \ - "audio/x-adpcm,layout=yamaha;" \ - "audio/mpeg,mpegversion=4;" \ - "audio/mpeg,mpegversion=1,layer=3;" \ - "audio/x-celt;" \ - "audio/mpeg,mpegversion=[2, 4];" \ - "audio/x-vorbis;" \ - "audio/x-opus;" \ - "audio/AMR,rate=[8000, 16000],channels=1;" \ - "audio/x-gsm;" - -#define KMS_AGNOSTIC_NO_RTP_AUDIO_CAPS \ - KMS_AGNOSTIC_RAW_AUDIO_CAPS \ - KMS_AGNOSTIC_FORMATS_AUDIO_CAPS - -#define KMS_AGNOSTIC_AUDIO_CAPS \ - KMS_AGNOSTIC_NO_RTP_AUDIO_CAPS \ - KMS_AGNOSTIC_RTP_AUDIO_CAPS - -#define KMS_AGNOSTIC_FORMATS_VIDEO_CAPS \ - "video/x-dirac;" \ - "image/png;" \ - "image/jpeg;" \ - "video/x-smoke;" \ - "video/x-asus,asusversion=1;" \ - "video/x-asus,asusversion=2;" \ - "image/bmp;" \ - "video/x-dnxhd;" \ - "video/x-dv;" \ - "video/x-ffv,ffvversion=1;" \ - "video/x-gst_ff-ffvhuff;" \ - "video/x-flash-screen;" \ - "video/x-flash-video,flvversion=1;" \ - "video/x-h261;" \ - "video/x-h263,variant=itu,h263version=h263;" \ - "video/x-h263,variant=itu,h263version=h263p;" \ - "video/x-huffyuv;" \ - "image/jpeg;" \ - "image/jpeg;" \ - "video/mpeg,mpegversion=1;" \ - "video/mpeg,mpegversion=2;" \ - "video/mpeg,mpegversion=4;" \ - "video/x-msmpeg,msmpegversion=41;" \ - "video/x-msmpeg,msmpegversion=42;" \ - "video/x-msmpeg,msmpegversion=43;" \ - "video/x-gst_ff-pam;" \ - "image/pbm;" \ - "video/x-gst_ff-pgm;" \ - "video/x-gst_ff-pgmyuv;" \ - "image/png;" \ - "image/ppm;" \ - "video/x-rle,layout=quicktime;" \ - "video/x-gst_ff-roqvideo;" \ - "video/x-pn-realvideo,rmversion=1;" \ - "video/x-pn-realvideo,rmversion=2;" \ - "video/x-gst_ff-snow;" \ - "video/x-svq,svqversion=1;" \ - "video/x-wmv,wmvversion=1;" \ - "video/x-wmv,wmvversion=2;" \ - "video/x-gst_ff-zmbv;" \ - "video/x-theora;" \ - "video/x-h264;" \ - "video/x-gst_ff-libxvid;" \ - "video/x-h264;" \ - "video/x-xvid;" \ - "video/mpeg,mpegversion=[1, 2];" \ - "video/x-theora;" \ - "video/x-vp8;" \ - "application/x-yuv4mpeg,y4mversion=2;" - -#define KMS_AGNOSTIC_NO_RTP_VIDEO_CAPS \ - KMS_AGNOSTIC_RAW_VIDEO_CAPS \ - KMS_AGNOSTIC_FORMATS_VIDEO_CAPS - -#define KMS_AGNOSTIC_VIDEO_CAPS \ - KMS_AGNOSTIC_NO_RTP_VIDEO_CAPS \ - KMS_AGNOSTIC_RTP_VIDEO_CAPS - -#define KMS_AGNOSTIC_DATA_CAPS \ - "application/data;" - -#define KMS_AGNOSTIC_CAPS \ - KMS_AGNOSTIC_AUDIO_CAPS \ - KMS_AGNOSTIC_VIDEO_CAPS - -#define KMS_AGNOSTIC_NO_RTP_CAPS \ - KMS_AGNOSTIC_NO_RTP_AUDIO_CAPS \ - KMS_AGNOSTIC_NO_RTP_VIDEO_CAPS - -#endif /* __KMS_AGNOSTIC_CAPS_H__ */ - -#define STUN_SERVER " stun-server=stun://stun.l.google.com:19302 " -#define RTP_CAPS_OPUS "application/x-rtp,media=audio,encoding-name=OPUS,payload=" -#define RTP_CAPS_VP8 "application/x-rtp,media=video,encoding-name=VP8,payload=" - -enum AppState -{ - APP_STATE_UNKNOWN = 0, - APP_STATE_ERROR = 1, /* generic error */ - SERVER_CONNECTING = 1000, - SERVER_CONNECTION_ERROR, - SERVER_CONNECTED, /* Ready to register */ - SERVER_REGISTERING = 2000, - SERVER_REGISTRATION_ERROR, - SERVER_REGISTERED, /* Ready to call a peer */ - SERVER_CLOSED, /* server connection closed by us or the server */ - PEER_CONNECTING = 3000, - PEER_CONNECTION_ERROR, - PEER_CONNECTED, - PEER_CALL_NEGOTIATING = 4000, - PEER_CALL_STARTED, - PEER_CALL_STOPPING, - PEER_CALL_STOPPED, - PEER_CALL_ERROR, -}; - -void startFeed(GstElement *pipeline, guint size, gpointer user_data); - -void readData(void *user_data); - -void on_incoming_decodebin_stream(GstElement *decodebin, GstPad *pad, - void *userdata); - -void uridecodebin_element_added(GstBin *bin, - GstElement *element, gpointer data); - -void on_negotiation_needed(GstElement *element, gpointer userdata); - -void send_ice_candidate_message(GstElement *webrtc G_GNUC_UNUSED, guint mlineindex, - gchar *candidate, gpointer userdata); - -void on_server_closed(SoupWebsocketConnection *conn G_GNUC_UNUSED, - gpointer userdata); - -void on_server_connected(SoupSession *session, GAsyncResult *res, - gpointer userdata); - -void on_server_message(SoupWebsocketConnection *conn, SoupWebsocketDataType type, - GBytes *message, gpointer userdata); - -void on_incoming_stream(GstElement *webrtc, GstPad *pad, gpointer userdata); - -void on_offer_created(GstPromise *promise, gpointer user_data); - -void stopFeed(GstElement *pipeline, void *user_data); - -struct GSTContext -{ -public: - GstElement *element; - GstElement *appsrc; - guint sourceid; - GstClockTime timestamp; -}; - -class GStreamerWebRTCSink::Detail -{ -public: - Detail(GStreamerWebRTCSinkProps &_props, std::function _step) : mProps(_props), mStep(_step), ctx(nullptr) - { - } - - ~Detail() - { - } - - void setMetadata(framemetadata_sp &metadata) - { - self = this; - frameType = metadata->getFrameType(); - - auto inputRawMetadata = FrameMetadataFactory::downcast(metadata); - width = inputRawMetadata->getWidth(); - height = inputRawMetadata->getHeight(); - - } - - void setProps(GStreamerWebRTCSinkProps &props) - { - mProps = props; - } - - GStreamerWebRTCSinkProps getProps() - { - return mProps; - } - - gboolean readData_actual(GSTContext *ctx) - { - GstMapInfo map; - GstFlowReturn gstret; - buffer = gst_buffer_new_allocate(NULL, frame->size(), NULL); - gst_buffer_map(buffer, &map, GST_MAP_WRITE); - - map.size = frame->size(); - memcpy(map.data, frame->data(), frame->size()); - GST_BUFFER_PTS(buffer) = ctx->timestamp; - GST_BUFFER_DURATION(buffer) = gst_util_uint64_scale_int(1, GST_SECOND, mProps.fps); - ctx->timestamp += GST_BUFFER_DURATION(buffer); - - if (frame->size() > 0) - { - gstret = gst_app_src_push_buffer((GstAppSrc *)ctx->appsrc, buffer); - if (gstret != GST_FLOW_OK) - { - printf("push buffer returned %d \n", gstret); - return false; - } - } - else - { - printf("\n failed to read\n"); - return false; - } - - gst_buffer_unmap(buffer, &map); - - return true; - } - - gboolean cleanup_and_quit_loop(const gchar *msg, enum AppState state) - { - if (msg) - g_printerr("%s\n", msg); - if (state > 0) - app_state = state; - - if (ws_conn) - { - if (soup_websocket_connection_get_state(ws_conn) == - SOUP_WEBSOCKET_STATE_OPEN) - /* This will call us again */ - soup_websocket_connection_close(ws_conn, 1000, ""); - else - g_object_unref(ws_conn); - } - - /* To allow usage as a GSourceFunc */ - return G_SOURCE_REMOVE; - } - - gchar *get_string_from_json_object(JsonObject *object) - { - JsonNode *root; - JsonGenerator *generator; - gchar *text; - - /* Make it the root node */ - root = json_node_init_object(json_node_alloc(), object); - generator = json_generator_new(); - json_generator_set_root(generator, root); - text = json_generator_to_data(generator, NULL); - - /* Release everything */ - g_object_unref(generator); - json_node_free(root); - return text; - } - void handle_media_stream(GstPad *pad, GstElement *pipe, const char *convert_name, - const char *sink_name) - { - GstPad *qpad; - GstElement *q, *conv, *resample, *sink; - GstPadLinkReturn ret; - - g_print("Trying to handle stream with %s ! %s", convert_name, sink_name); - - q = gst_element_factory_make("queue", NULL); - g_assert_nonnull(q); - conv = gst_element_factory_make(convert_name, NULL); - g_assert_nonnull(conv); - sink = gst_element_factory_make(sink_name, NULL); - g_assert_nonnull(sink); - - if (g_strcmp0(convert_name, "audioconvert") == 0) - { - /* Might also need to resample, so add it just in case. - * Will be a no-op if it's not required. */ - resample = gst_element_factory_make("audioresample", NULL); - g_assert_nonnull(resample); - gst_bin_add_many(GST_BIN(pipe), q, conv, resample, sink, NULL); - gst_element_sync_state_with_parent(q); - gst_element_sync_state_with_parent(conv); - gst_element_sync_state_with_parent(resample); - gst_element_sync_state_with_parent(sink); - gst_element_link_many(q, conv, resample, sink, NULL); - } - else - { - gst_bin_add_many(GST_BIN(pipe), q, conv, sink, NULL); - gst_element_sync_state_with_parent(q); - gst_element_sync_state_with_parent(conv); - gst_element_sync_state_with_parent(sink); - gst_element_link_many(q, conv, sink, NULL); - } - - qpad = gst_element_get_static_pad(q, "sink"); - - ret = gst_pad_link(pad, qpad); - g_assert_cmphex(ret, ==, GST_PAD_LINK_OK); - } - - void on_incoming_decodebin_stream_helper(GstElement *decodebin, GstPad *pad, - GstElement *pipe) - { - GstCaps *caps; - const gchar *name; - - if (!gst_pad_has_current_caps(pad)) - { - g_printerr("Pad '%s' has no caps, can't do anything, ignoring\n", - GST_PAD_NAME(pad)); - return; - } - - caps = gst_pad_get_current_caps(pad); - name = gst_structure_get_name(gst_caps_get_structure(caps, 0)); - - if (g_str_has_prefix(name, "video")) - { - handle_media_stream(pad, pipe, "videoconvert", "autovideosink"); - } - else if (g_str_has_prefix(name, "audio")) - { - handle_media_stream(pad, pipe, "audioconvert", "autoaudiosink"); - } - else - { - g_printerr("Unknown pad %s, ignoring", GST_PAD_NAME(pad)); - } - } - - void on_incoming_stream_helper(GstElement *webrtc, GstPad *pad, GstElement *pipe) - { - GstElement *decodebin; - - if (GST_PAD_DIRECTION(pad) != GST_PAD_SRC) - return; - - decodebin = gst_element_factory_make("decodebin", NULL); - - g_signal_connect(decodebin, "pad-added", - G_CALLBACK(on_incoming_decodebin_stream), this); - gst_bin_add(GST_BIN(pipe), decodebin); - gst_element_sync_state_with_parent(decodebin); - gst_element_link(webrtc, decodebin); - } - - void send_ice_candidate_message_helper(GstElement *webrtc G_GNUC_UNUSED, guint mlineindex, - gchar *candidate) - { - gchar *text; - JsonObject *ice, *msg; - - if (app_state < PEER_CALL_NEGOTIATING) - { - cleanup_and_quit_loop("Can't send ICE, not in call", APP_STATE_ERROR); - return; - } - - ice = json_object_new(); - json_object_set_string_member(ice, "candidate", candidate); - json_object_set_int_member(ice, "sdpMLineIndex", mlineindex); - msg = json_object_new(); - json_object_set_object_member(msg, "ice", ice); - text = get_string_from_json_object(msg); - json_object_unref(msg); - - soup_websocket_connection_send_text(ws_conn, text); - g_free(text); - } - - void send_sdp_offer(GstWebRTCSessionDescription *offer) - { - gchar *text; - JsonObject *msg, *sdp; - - if (app_state < PEER_CALL_NEGOTIATING) - { - cleanup_and_quit_loop("Can't send offer, not in call", APP_STATE_ERROR); - return; - } - - text = gst_sdp_message_as_text(offer->sdp); - g_print("Sending offer:\n%s\n", text); - - sdp = json_object_new(); - json_object_set_string_member(sdp, "type", "offer"); - json_object_set_string_member(sdp, "sdp", text); - g_free(text); - - msg = json_object_new(); - json_object_set_object_member(msg, "sdp", sdp); - text = get_string_from_json_object(msg); - json_object_unref(msg); - - soup_websocket_connection_send_text(ws_conn, text); - g_free(text); - } - - void on_offer_created_helper(GstPromise *promise) - { - GstWebRTCSessionDescription *offer = NULL; - const GstStructure *reply; - - g_assert_cmphex(app_state, ==, PEER_CALL_NEGOTIATING); - - g_assert_cmphex(gst_promise_wait(promise), ==, GST_PROMISE_RESULT_REPLIED); - reply = gst_promise_get_reply(promise); - gst_structure_get(reply, "offer", - GST_TYPE_WEBRTC_SESSION_DESCRIPTION, &offer, NULL); - gst_promise_unref(promise); - - promise = gst_promise_new(); - g_signal_emit_by_name(webrtc1, "set-local-description", offer, promise); - gst_promise_interrupt(promise); - gst_promise_unref(promise); - - /* Send offer to peer */ - send_sdp_offer(offer); - gst_webrtc_session_description_free(offer); - } - - void on_negotiation_needed_helper(GstElement *element, gpointer user_data) - { - GstPromise *promise; - - app_state = PEER_CALL_NEGOTIATING; - promise = gst_promise_new_with_change_func(on_offer_created, user_data, NULL); - g_signal_emit_by_name(webrtc1, "create-offer", NULL, promise); - } - - void - uridecodebin_element_added_helper(GstBin *bin, - GstElement *element) - { - if (g_strcmp0(gst_plugin_feature_get_name(GST_PLUGIN_FEATURE(gst_element_get_factory(element))), "rtspsrc") == 0) - { - g_print("Added latency 100 ms to rtspsrc\n"); - g_object_set(G_OBJECT(element), "latency", 0, - "drop-on-latency", TRUE, NULL); - } - } - - gboolean - start_pipeline(void) - { - GstStateChangeReturn ret; - GError *error = NULL; - - LOG_INFO << "Configured raw frames pipeline."; - pipe = gst_parse_launch("appsrc is-live=TRUE block=TRUE name=gstsrc min-latency=0 ! videoconvert ! video/x-raw, format=I420 ! x264enc tune=zerolatency speed-preset=superfast ! rtph264pay ! queue ! application/x-rtp,media=video,encoding-name=H264,payload=96 ! webrtcbin name=sendrecv", &error); - - if (error) - { - g_printerr("Failed to parse launch: %s\n", error->message); - g_error_free(error); - goto err; - } - - ctx = g_new0(GSTContext, 1); - - // ctx->appsrc = gst_bin_get_by_name_recurse_up(GST_BIN(ctx->element), - // "gstsrc"); - ctx->appsrc = gst_bin_get_by_name(GST_BIN(pipe), - "gstsrc"); - - gst_util_set_object_arg(G_OBJECT(ctx->appsrc), "format", "time"); - g_object_set(G_OBJECT(ctx->appsrc), "format", GST_FORMAT_TIME, NULL); - - - g_object_set(G_OBJECT(ctx->appsrc), "caps", - gst_caps_new_simple("video/x-raw", - "format", G_TYPE_STRING, "RGB", - "width", G_TYPE_INT, (gint)mProps.width, - "height", G_TYPE_INT, (gint)mProps.height, - "framerate", GST_TYPE_FRACTION, mProps.fps, 1, NULL), - NULL); - - g_signal_connect(ctx->appsrc, "need-data", G_CALLBACK(startFeed), self); - g_signal_connect(ctx->appsrc, "enough-data", G_CALLBACK(stopFeed), self); - - GstCaps *deco_caps; - deco_caps = gst_caps_from_string(KMS_AGNOSTIC_NO_RTP_CAPS); - - gst_caps_unref(deco_caps); - - webrtc1 = gst_bin_get_by_name(GST_BIN(pipe), "sendrecv"); - g_assert_nonnull(webrtc1); - - /* This is the gstwebrtc entry point where we create the offer and so on. It - * will be called when the pipeline goes to PLAYING. */ - g_signal_connect(webrtc1, "on-negotiation-needed", - G_CALLBACK(on_negotiation_needed), this); - /* We need to transmit this ICE candidate to the browser via the websockets - * signalling server. Incoming ice candidates from the browser need to be - * added by us too, see on_server_message() */ - g_signal_connect(webrtc1, "on-ice-candidate", - G_CALLBACK(send_ice_candidate_message), this); - /* Incoming streams will be exposed via this signal */ - g_signal_connect(webrtc1, "pad-added", G_CALLBACK(on_incoming_stream), - this); - /* Lifetime is the same as the pipeline itself */ - gst_object_unref(webrtc1); - - g_print("Starting pipeline\n"); - ret = gst_element_set_state(GST_ELEMENT(pipe), GST_STATE_PLAYING); - if (ret == GST_STATE_CHANGE_FAILURE) - goto err; - - g_print("Started pipeline\n"); - return TRUE; - - err: - if (pipe) - g_clear_object(&pipe); - if (webrtc1) - webrtc1 = NULL; - return FALSE; - } - - gboolean - setup_call(void) - { - gchar *msg; - - if (soup_websocket_connection_get_state(ws_conn) != - SOUP_WEBSOCKET_STATE_OPEN) - return FALSE; - - if (!mProps.peerId.c_str()) - return FALSE; - - g_print("Setting up signalling server call with %s\n", mProps.peerId.c_str()); - app_state = PEER_CONNECTING; - msg = g_strdup_printf("SESSION %s", mProps.peerId.c_str()); - // soup_websocket_connection_send_text(ws_conn, msg); - g_free(msg); - return TRUE; - } - - gboolean - register_with_server(void) - { - gchar *hello; - gint32 our_id; - - if (soup_websocket_connection_get_state(ws_conn) != - SOUP_WEBSOCKET_STATE_OPEN) - return FALSE; - - our_id = g_random_int_range(666, 666); - g_print("Registering id %i with server\n", our_id); - app_state = SERVER_REGISTERING; - - /* Register with the server with a random integer id. Reply will be received - * by on_server_message() */ - hello = g_strdup_printf("HELLO %i", our_id); - soup_websocket_connection_send_text(ws_conn, hello); - g_free(hello); - - return TRUE; - } - - void - on_server_closed_helper(SoupWebsocketConnection *conn G_GNUC_UNUSED) - { - app_state = SERVER_CLOSED; - cleanup_and_quit_loop("Server connection closed", APP_STATE_UNKNOWN); - connect_to_websocket_server_async(); - return; - } - - void - on_server_message_helper(SoupWebsocketConnection *conn, SoupWebsocketDataType type, - GBytes *message) - { - gsize size; - gchar *text, *data; - - switch (type) - { - case SOUP_WEBSOCKET_DATA_BINARY: - g_printerr("Received unknown binary message, ignoring\n"); - g_bytes_unref(message); - return; - case SOUP_WEBSOCKET_DATA_TEXT: - data = static_cast(g_bytes_unref_to_data(message, &size)); - /* Convert to NULL-terminated string */ - text = g_strndup(data, size); - g_free(data); - break; - default: - g_assert_not_reached(); - } - - /* Server has accepted our registration, we are ready to send commands */ - if (g_strcmp0(text, "HELLO") == 0) - { - if (app_state != SERVER_REGISTERING) - { - cleanup_and_quit_loop("ERROR: Received HELLO when not registering", - APP_STATE_ERROR); - goto out; - } - app_state = SERVER_REGISTERED; - g_print("Registered with server\n"); - /* Ask signalling server to connect us with a specific peer */ - if (!setup_call()) - { - cleanup_and_quit_loop("ERROR: Failed to setup call", PEER_CALL_ERROR); - goto out; - } - /* Call has been setup by the server, now we can start negotiation */ - } - else if (g_strcmp0(text, "SESSION_OK") == 0) - { - if (app_state != PEER_CONNECTING) - { - cleanup_and_quit_loop("ERROR: Received SESSION_OK when not calling", - PEER_CONNECTION_ERROR); - goto out; - } - - app_state = PEER_CONNECTED; - /* Start negotiation (exchange SDP and ICE candidates) */ - LOG_INFO << "Going to start pipeline"; - if (!start_pipeline()) - cleanup_and_quit_loop("ERROR: failed to start pipeline", - PEER_CALL_ERROR); - /* Handle errors */ - } - else if (g_str_has_prefix(text, "ERROR")) - { - switch (app_state) - { - case SERVER_CONNECTING: - app_state = SERVER_CONNECTION_ERROR; - break; - case SERVER_REGISTERING: - app_state = SERVER_REGISTRATION_ERROR; - break; - case PEER_CONNECTING: - app_state = PEER_CONNECTION_ERROR; - break; - case PEER_CONNECTED: - case PEER_CALL_NEGOTIATING: - app_state = PEER_CALL_ERROR; - default: - app_state = APP_STATE_ERROR; - } - cleanup_and_quit_loop(text, APP_STATE_UNKNOWN); - /* Look for JSON messages containing SDP and ICE candidates */ - } - else - { - JsonNode *root; - JsonObject *object, *child; - JsonParser *parser = json_parser_new(); - if (!json_parser_load_from_data(parser, text, -1, NULL)) - { - g_printerr("Unknown message '%s', ignoring", text); - g_object_unref(parser); - goto out; - } - - root = json_parser_get_root(parser); - if (!JSON_NODE_HOLDS_OBJECT(root)) - { - g_printerr("Unknown json message '%s', ignoring", text); - g_object_unref(parser); - goto out; - } - - object = json_node_get_object(root); - /* Check type of JSON message */ - if (json_object_has_member(object, "sdp")) - { - int ret; - GstSDPMessage *sdp; - const gchar *text, *sdptype; - GstWebRTCSessionDescription *answer; - - g_assert_cmphex(app_state, ==, PEER_CALL_NEGOTIATING); - - child = json_object_get_object_member(object, "sdp"); - - if (!json_object_has_member(child, "type")) - { - cleanup_and_quit_loop("ERROR: received SDP without 'type'", - PEER_CALL_ERROR); - goto out; - } - - sdptype = json_object_get_string_member(child, "type"); - /* In this example, we always create the offer and receive one answer. - * See tests/examples/webrtcbidirectional.c in gst-plugins-bad for how to - * handle offers from peers and reply with answers using webrtcbin. */ - g_assert_cmpstr(sdptype, ==, "answer"); - - text = json_object_get_string_member(child, "sdp"); - - g_print("Received answer:\n%s\n", text); - - ret = gst_sdp_message_new(&sdp); - g_assert_cmphex(ret, ==, GST_SDP_OK); - - ret = gst_sdp_message_parse_buffer((guint8 *)text, strlen(text), sdp); - g_assert_cmphex(ret, ==, GST_SDP_OK); - - answer = gst_webrtc_session_description_new(GST_WEBRTC_SDP_TYPE_ANSWER, - sdp); - g_assert_nonnull(answer); - - /* Set remote description on our pipeline */ - { - GstPromise *promise = gst_promise_new(); - g_signal_emit_by_name(webrtc1, "set-remote-description", answer, - promise); - gst_promise_interrupt(promise); - gst_promise_unref(promise); - } - - app_state = PEER_CALL_STARTED; - } - else if (json_object_has_member(object, "ice")) - { - const gchar *candidate; - gint sdpmlineindex; - - child = json_object_get_object_member(object, "ice"); - candidate = json_object_get_string_member(child, "candidate"); - sdpmlineindex = json_object_get_int_member(child, "sdpMLineIndex"); - - /* Add ice candidate sent by remote peer */ - g_signal_emit_by_name(webrtc1, "add-ice-candidate", sdpmlineindex, - candidate); - } - else - { - g_printerr("Ignoring unknown JSON message:\n%s\n", text); - } - g_object_unref(parser); - } - - out: - g_free(text); - } - - void - on_server_connected_helper(SoupSession *session, GAsyncResult *res, - SoupMessage *msg) - { - GError *error = NULL; - - ws_conn = soup_session_websocket_connect_finish(session, res, &error); - if (error) - { - cleanup_and_quit_loop(error->message, SERVER_CONNECTION_ERROR); - g_error_free(error); - return; - } - - g_assert_nonnull(ws_conn); - - app_state = SERVER_CONNECTED; - g_print("Connected to signalling server\n"); - - g_signal_connect(ws_conn, "closed", G_CALLBACK(on_server_closed), this); - g_signal_connect(ws_conn, "message", G_CALLBACK(on_server_message), this); - - /* Register with the server so it knows about us and can accept commands */ - register_with_server(); - } - - void - connect_to_websocket_server_async(void) - { - SoupLogger *logger; - SoupSession *session; - const char *https_aliases[] = {"wss", NULL}; - - session = soup_session_new_with_options(SOUP_SESSION_SSL_STRICT, !disable_ssl, - SOUP_SESSION_SSL_USE_SYSTEM_CA_FILE, TRUE, - //SOUP_SESSION_SSL_CA_FILE, "/etc/ssl/certs/ca-bundle.crt", - SOUP_SESSION_HTTPS_ALIASES, https_aliases, NULL); - - logger = soup_logger_new(SOUP_LOGGER_LOG_BODY, -1); - soup_session_add_feature(session, SOUP_SESSION_FEATURE(logger)); - g_object_unref(logger); - - message = soup_message_new(SOUP_METHOD_GET, server_url); - - g_print("Connecting to server...\n"); - - /* Once connected, we will register */ - soup_session_websocket_connect_async(session, message, NULL, NULL, NULL, - (GAsyncReadyCallback)on_server_connected, this); - app_state = SERVER_CONNECTING; - } - - gboolean - check_plugins(void) - { - int i; - gboolean ret; - GstPlugin *plugin; - GstRegistry *registry; - const gchar *needed[] = {"opus", "vpx", "nice", "webrtc", "dtls", "srtp", - "rtpmanager", "videotestsrc", "audiotestsrc", NULL}; - - registry = gst_registry_get(); - ret = TRUE; - for (i = 0; i < g_strv_length((gchar **)needed); i++) - { - plugin = gst_registry_find_plugin(registry, needed[i]); - if (!plugin) - { - g_print("Required gstreamer plugin '%s' not found\n", needed[i]); - ret = FALSE; - continue; - } - gst_object_unref(plugin); - } - return ret; - } - - bool gstreamerMainThread(GMainLoop *loop) - { - - gst_init(0, NULL); - - loop = g_main_loop_new(NULL, FALSE); - - { - GstUri *uri = gst_uri_from_string(server_url); - if (g_strcmp0("localhost", gst_uri_get_host(uri)) == 0 || - g_strcmp0("127.0.0.1", gst_uri_get_host(uri)) == 0) - disable_ssl = TRUE; - gst_uri_unref(uri); - } - - connect_to_websocket_server_async(); - g_print("Reached after server close."); - g_main_loop_run(loop); - g_main_loop_unref(loop); - - return true; - } - -public: - GStreamerWebRTCSinkProps mProps; - GstBuffer *buffer; - GSTContext *ctx; - GMainLoop *loop; - SoupMessage *message; - GstElement *pipe, *webrtc1; - SoupWebsocketConnection *ws_conn = NULL; - enum AppState app_state = APP_STATE_UNKNOWN; - const gchar *server_url = "ws://127.0.0.1:8083/signalling"; - gboolean disable_ssl = FALSE; - frame_sp frame; - int width = 0; - int height; - char desc[10000]; - FrameMetadata::FrameType frameType; - std::function mStep; - Detail *self; - std::thread t1; -}; - -void startFeed(GstElement *pipeline, guint size, void *user_data) -{ - auto detail = static_cast(user_data); - if (detail->ctx->sourceid == 0) - { - detail->ctx->sourceid = g_idle_add((GSourceFunc)readData, user_data); - } - return; -} - -void on_incoming_decodebin_stream(GstElement *decodebin, GstPad *pad, - void *userdata) -{ - auto detail = static_cast(userdata); - detail->on_incoming_decodebin_stream_helper(decodebin, pad, detail->pipe); - return; -} - -void on_offer_created(GstPromise *promise, gpointer userdata) -{ - auto detail = static_cast(userdata); - detail->on_offer_created_helper(promise); - return; -} - -void on_negotiation_needed(GstElement *element, gpointer userdata) -{ - auto detail = static_cast(userdata); - detail->on_negotiation_needed_helper(element, userdata); - return; -} - -void send_ice_candidate_message(GstElement *webrtc G_GNUC_UNUSED, guint mlineindex, - gchar *candidate, gpointer userdata) -{ - auto detail = static_cast(userdata); - detail->send_ice_candidate_message_helper(webrtc, mlineindex, candidate); - return; -} - -void on_incoming_stream(GstElement *webrtc, GstPad *pad, gpointer userdata) -{ - auto detail = static_cast(userdata); - detail->on_incoming_stream_helper(webrtc, pad, detail->pipe); - return; -} - -void uridecodebin_element_added(GstBin *bin, - GstElement *element, gpointer userdata) -{ - auto detail = static_cast(userdata); - detail->uridecodebin_element_added_helper(bin, element); - return; -} - -void on_server_closed(SoupWebsocketConnection *conn G_GNUC_UNUSED, - gpointer userdata) -{ - auto detail = static_cast(userdata); - detail->on_server_closed_helper(conn); - return; -} - -void on_server_connected(SoupSession *session, GAsyncResult *res, - gpointer userdata) -{ - auto detail = static_cast(userdata); - detail->on_server_connected_helper(session, res, detail->message); - return; -} - -void on_server_message(SoupWebsocketConnection *conn, SoupWebsocketDataType type, - GBytes *message, gpointer userdata) -{ - auto detail = static_cast(userdata); - detail->on_server_message_helper(conn, type, message); - return; -} - -void readData(void *user_data) -{ - auto detail = static_cast(user_data); - detail->mStep(); - return; -} - -void stopFeed(GstElement *pipeline, void *user_data) -{ - auto detail = static_cast(user_data); - if (detail->ctx->sourceid != 0) - { - g_source_remove(detail->ctx->sourceid); - detail->ctx->sourceid = 0; - } - return; -} - -GStreamerWebRTCSink::GStreamerWebRTCSink(GStreamerWebRTCSinkProps props) : Module(SINK, "GStreamerWebRTCSink", props) -{ - mDetail.reset(new Detail(props, [&]() -> void - { Module::step(); })); -} - -GStreamerWebRTCSink::~GStreamerWebRTCSink() {} - -bool GStreamerWebRTCSink::init() -{ - if (!Module::init()) - { - return false; - } - - framemetadata_sp metadata = getFirstInputMetadata(); - mDetail->setMetadata(metadata); - - mDetail->t1 = std::thread(&GStreamerWebRTCSink::Detail::gstreamerMainThread, mDetail.get(), mDetail->loop); - - return true; -} - -bool GStreamerWebRTCSink::term() -{ - - g_main_loop_quit(mDetail->loop); - mDetail->t1.join(); - gst_deinit(); - return Module::term(); -} - -bool GStreamerWebRTCSink::validateInputPins() -{ - if (getNumberOfInputPins() != 1) - { - LOG_ERROR << "<" << getId() << ">::validateInputPins size is expected to be 1. Actual<" << getNumberOfInputPins() << ">"; - return false; - } - - framemetadata_sp metadata = getFirstInputMetadata(); - - FrameMetadata::FrameType frameType = metadata->getFrameType(); - LOG_INFO << "FrameType is " << frameType; - if (frameType != FrameMetadata::RAW_IMAGE) - { - LOG_ERROR << "<" << getId() << ">::validateInputPins input frameType is expected to be RAW. Actual<" << frameType << ">"; - return false; - } - return true; -} - -bool GStreamerWebRTCSink::process(frame_container &frames) -{ - mDetail->frame = frames.cbegin()->second; - mDetail->readData_actual(mDetail->ctx); - return true; -} - -bool GStreamerWebRTCSink::processSOS(frame_sp &frame) -{ - return true; -} - -bool GStreamerWebRTCSink::shouldTriggerSOS() -{ - return mDetail->width == 0; -} - -bool GStreamerWebRTCSink::processEOS(string &pinId) -{ - return false; -} - -GStreamerWebRTCSinkProps GStreamerWebRTCSink::getProps() -{ - auto mProps = mDetail->getProps(); - fillProps(mProps); - - return mProps; -} - -void GStreamerWebRTCSink::setProps(GStreamerWebRTCSinkProps &mProps) -{ - Module::addPropsToQueue(mProps); -} - -bool GStreamerWebRTCSink::handlePropsChange(frame_sp &frame) -{ - GStreamerWebRTCSinkProps mProps; - bool ret = Module::handlePropsChange(frame, mProps); - mDetail->setProps(mProps); - - sendEOS(); - - return ret; -} diff --git a/base/test/gstrtsponvifsink_tests.cpp b/base/test/gstrtsponvifsink_tests.cpp deleted file mode 100644 index 5caf60108..000000000 --- a/base/test/gstrtsponvifsink_tests.cpp +++ /dev/null @@ -1,237 +0,0 @@ -#include -//#include -#include "FileReaderModule.h" -#include "FrameMetadata.h" -#include "Frame.h" -#include "Logger.h" -#include "AIPExceptions.h" -#include "GstOnvifRtspSink.h" -#include "PipeLine.h" -#include "H264Metadata.h" -#include "WebCamSource.h" -#include "StatSink.h" -// #include "EventSource.h" -// #include "RedisDBReader.h" -#include "FileReaderModule.h" -#include "FrameMetadataFactory.h" - -BOOST_AUTO_TEST_SUITE(gstrtsponvifsink_tests) - -BOOST_AUTO_TEST_CASE(gstrtspservertest, *boost::unit_test::disabled()) -{ - - LoggerProps logprops; - logprops.logLevel = boost::log::trivial::severity_level::info; - Logger::initLogger(logprops); - - auto width = 640; - auto height = 360; - - FileReaderModuleProps fileReaderProps("./data/h264_frames/Raw_YUV420_640x360_????.h264"); - fileReaderProps.fps = 1000; - fileReaderProps.qlen = 1; - fileReaderProps.quePushStrategyType = QuePushStrategy::NON_BLOCKING_ANY; - fileReaderProps.readLoop = true; - auto fileReader = boost::shared_ptr(new FileReaderModule(fileReaderProps)); - - auto metadata = framemetadata_sp(new H264Metadata(width, height)); - fileReader->addOutputPin(metadata); - - GStreamerOnvifRTSPSinkProps gstOnvifRTSPSinkProps; - gstOnvifRTSPSinkProps.frameFetchStrategy = ModuleProps::FrameFetchStrategy::PULL; - gstOnvifRTSPSinkProps.fps = 30; - auto sink = boost::shared_ptr(new GStreamerOnvifRTSPSink(gstOnvifRTSPSinkProps)); - fileReader->setNext(sink); - - PipeLine p("test"); - p.appendModule(fileReader); - BOOST_TEST(p.init()); - - p.run_all_threaded(); - boost::this_thread::sleep_for(boost::chrono::seconds(100000)); - LOG_INFO << "profiling done - stopping the pipeline"; - p.stop(); - p.term(); - boost::this_thread::sleep_for(boost::chrono::seconds(1)); - LOG_INFO << "profiling done - wait_for_all the pipeline"; - - p.wait_for_all(); -} - -BOOST_AUTO_TEST_CASE(gstrtspservertestrawyuv, *boost::unit_test::disabled()) -{ - - LoggerProps logprops; - logprops.logLevel = boost::log::trivial::severity_level::info; - Logger::initLogger(logprops); - - auto width = 640; - auto height = 360; - - FileReaderModuleProps fileReaderProps("./data/Raw_YUV420_640x360/Image???_YUV420.raw"); - fileReaderProps.fps = 1000; - fileReaderProps.readLoop = true; - auto fileReader = boost::shared_ptr(new FileReaderModule(fileReaderProps)); - auto metadata = framemetadata_sp(new RawImagePlanarMetadata(width, height, ImageMetadata::ImageType::YUV420, size_t(0), CV_8U, FrameMetadata::MemType::HOST)); - fileReader->addOutputPin(metadata); - - GStreamerOnvifRTSPSinkProps gstOnvifRTSPSinkProps; - gstOnvifRTSPSinkProps.frameFetchStrategy = ModuleProps::FrameFetchStrategy::PULL; - gstOnvifRTSPSinkProps.fps = 30; - gstOnvifRTSPSinkProps.width = width; - gstOnvifRTSPSinkProps.height = height; - auto sink = boost::shared_ptr(new GStreamerOnvifRTSPSink(gstOnvifRTSPSinkProps)); - fileReader->setNext(sink); - - PipeLine p("test"); - p.appendModule(fileReader); - BOOST_TEST(p.init()); - - p.run_all_threaded(); - boost::this_thread::sleep_for(boost::chrono::seconds(10000000)); - LOG_INFO << "profiling done - stopping the pipeline"; - // p.stop(); - p.term(); - p.wait_for_all(); -} - -BOOST_AUTO_TEST_CASE(gstrtspservertestrawrgbwcs, *boost::unit_test::disabled()) -{ - - LoggerProps logprops; - logprops.logLevel = boost::log::trivial::severity_level::info; - Logger::initLogger(logprops); - - auto width = 640; - auto height = 480; - - WebCamSourceProps webCamSourceprops(-1, width, height); - webCamSourceprops.qlen = 1; - webCamSourceprops.quePushStrategyType = QuePushStrategy::NON_BLOCKING_ANY; - webCamSourceprops.logHealth = true; - webCamSourceprops.logHealthFrequency = 30; - auto source = boost::shared_ptr(new WebCamSource(webCamSourceprops)); - - GStreamerOnvifRTSPSinkProps gstOnvifRTSPSinkProps; - gstOnvifRTSPSinkProps.frameFetchStrategy = ModuleProps::FrameFetchStrategy::PULL; - gstOnvifRTSPSinkProps.fps = 30; - gstOnvifRTSPSinkProps.goplength = 1; - gstOnvifRTSPSinkProps.width = width; - gstOnvifRTSPSinkProps.height = height; - gstOnvifRTSPSinkProps.qlen = 1; - gstOnvifRTSPSinkProps.bitrate = 2048; - gstOnvifRTSPSinkProps.logHealth = true; - gstOnvifRTSPSinkProps.logHealthFrequency = 30; - gstOnvifRTSPSinkProps.quePushStrategyType = QuePushStrategy::NON_BLOCKING_ANY; - auto sink = boost::shared_ptr(new GStreamerOnvifRTSPSink(gstOnvifRTSPSinkProps)); - source->setNext(sink); - - PipeLine p("test"); - p.appendModule(source); - BOOST_TEST(p.init()); - - p.run_all_threaded(); - boost::this_thread::sleep_for(boost::chrono::seconds(100000)); - LOG_INFO << "profiling done - stopping the pipeline"; - p.stop(); - p.term(); - p.wait_for_all(); - boost::this_thread::sleep_for(boost::chrono::seconds(100000)); -} - -// BOOST_AUTO_TEST_CASE(gstrtspservertestwithuserupdates, *boost::unit_test::disabled()) -// { - -// LoggerProps logprops; -// logprops.logLevel = boost::log::trivial::severity_level::info; -// Logger::initLogger(logprops); - - -// auto width = 640; -// auto height = 360; - -// FileReaderModuleProps fileReaderProps("./data/h264_frames/Raw_YUV420_640x360_????.h264"); -// fileReaderProps.fps = 1000; -// fileReaderProps.readLoop = true; -// auto fileReader = boost::shared_ptr(new FileReaderModule(fileReaderProps)); - -// auto metadata = framemetadata_sp(new H264Metadata(width, height)); -// fileReader->addOutputPin(metadata); -// sw::redis::ConnectionOptions connection_options; -// connection_options.type = sw::redis::ConnectionType::UNIX; -// connection_options.path = "/run/redis/redis.sock"; -// connection_options.db = 1; -// connection_options.socket_timeout = std::chrono::milliseconds(1000); -// sw::redis::Redis redis(connection_options); - -// auto redisReader = boost::shared_ptr(new RedisDBReader()); -// std::string port = redisReader->getValueByKeyName(redis, "onvif.device.network.Ports.RTSPPort"); -// GStreamerOnvifRTSPSinkProps gstOnvifRTSPSinkProps; -// gstOnvifRTSPSinkProps.frameFetchStrategy = ModuleProps::FrameFetchStrategy::PULL; -// gstOnvifRTSPSinkProps.fps = 30; -// if (!port.empty()) -// { -// LOG_INFO << "Port fetched from redis is " << port; -// gstOnvifRTSPSinkProps.port = port; -// } -// auto sink = boost::shared_ptr(new GStreamerOnvifRTSPSink(gstOnvifRTSPSinkProps)); -// fileReader->setNext(sink); - - -// //initially read from DB and set props -// auto eventSource = boost::shared_ptr(new EventSource()); - -// eventSource->listenKey("__keyspace@1__:onvif.users.User*", [&]() -> void -// { -// auto userList = redisReader->getUsersList(redis); -// gstOnvifRTSPSinkProps.userList = userList; -// sink->setProps(gstOnvifRTSPSinkProps); -// LOG_INFO << "userList Fetched on callback"; -// }); - -// eventSource->listenKey("__keyspace@1__:onvif.media.VideoSourceConfiguration*", [&]() -> void -// { LOG_INFO << "Hello"; }); - -// PipeLine p("test"); -// p.appendModule(fileReader); -// BOOST_TEST(p.init()); -// std::thread t1 = std::thread(&EventSource::callbackWatcher, eventSource.get(), std::ref(redis)); -// p.run_all_threaded(); -// boost::this_thread::sleep_for(boost::chrono::seconds(10000)); -// LOG_INFO << "profiling done - stopping the pipeline"; -// p.stop(); -// p.term(); -// t1.join(); -// p.wait_for_all(); -// } - -BOOST_AUTO_TEST_CASE(propsSerialzationTest) -{ - GStreamerOnvifRTSPSinkProps props, propsResult; - props.height = 320; - props.width = 120; - GStreamerOnvifRTSPSinkProps::User user; - user.username = "Hello world"; - user.password = "Hello world"; - for (int i = 0; i < 5; i++) - { - props.userList.push_back(user); - } - - size_t size = props.getSerializeSize(); - - void *buffer = malloc(size); - - Utils::serialize(props, buffer, size); - Utils::deSerialize(propsResult, buffer, size); - - BOOST_TEST(props.height == propsResult.height); - BOOST_TEST(props.width == propsResult.width); - for (int i = 0; i < 5; i++) - { - BOOST_TEST(props.userList[i].username.compare(propsResult.userList[i].username) == 0); - BOOST_TEST(props.userList[i].password.compare(propsResult.userList[i].password) == 0); - } -} - -BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file diff --git a/base/test/gstwebrtcsink_tests.cpp b/base/test/gstwebrtcsink_tests.cpp deleted file mode 100644 index 9a14fa6e1..000000000 --- a/base/test/gstwebrtcsink_tests.cpp +++ /dev/null @@ -1,58 +0,0 @@ -#include -#include "FileReaderModule.h" -#include "FrameMetadata.h" -#include "Frame.h" -#include "Logger.h" -#include "AIPExceptions.h" -#include "GstWebRTCSink.h" -#include "PipeLine.h" -#include "H264Metadata.h" -#include "WebCamSource.h" -#include "StatSink.h" -#include "FileReaderModule.h" -#include "FrameMetadataFactory.h" - - -BOOST_AUTO_TEST_SUITE(gstwebrtcsink_tests) - -BOOST_AUTO_TEST_CASE(gstwebrtctestrawrgbwcs, *boost::unit_test::disabled()) -{ - LoggerProps logprops; - logprops.logLevel = boost::log::trivial::severity_level::info; - Logger::initLogger(logprops); - - auto width = 640; - auto height = 480; - - WebCamSourceProps webCamSourceprops(-1, width, height); - webCamSourceprops.qlen = 1; - webCamSourceprops.fps = 30; - webCamSourceprops.quePushStrategyType = QuePushStrategy::NON_BLOCKING_ANY; - auto source = boost::shared_ptr(new WebCamSource(webCamSourceprops)); - - GStreamerWebRTCSinkProps _props; - _props.frameFetchStrategy = ModuleProps::FrameFetchStrategy::PULL; - _props.fps = 30; - _props.goplength = 1; - _props.width = width; - _props.height = height; - _props.qlen = 1; - _props.peerId = "1001"; - _props.quePushStrategyType = QuePushStrategy::NON_BLOCKING_ANY; - auto sink = boost::shared_ptr(new GStreamerWebRTCSink(_props)); - source->setNext(sink); - - PipeLine p("test"); - p.appendModule(source); - BOOST_TEST(p.init()); - - p.run_all_threaded(); - boost::this_thread::sleep_for(boost::chrono::seconds(100000)); - LOG_INFO << "profiling done - stopping the pipeline"; - p.stop(); - p.term(); - p.wait_for_all(); - boost::this_thread::sleep_for(boost::chrono::seconds(100000)); -} - -BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file diff --git a/base/vcpkg.json b/base/vcpkg.json index 628003ff3..7a15be350 100644 --- a/base/vcpkg.json +++ b/base/vcpkg.json @@ -59,21 +59,6 @@ { "name": "redis-plus-plus", "platform": "!arm64" - }, - { - "name": "gstreamer", - "features": [ - "plugins-good", - "plugins-bad", - "plugins-ugly" - ], - "platform": "!linux", - "$reason": "current vcpkg system does not build gstreamer for linux, we build our own" - }, - { - "name": "gst-rtsp-server", - "platform": "!linux", - "$reason": "current vcpkg system does not build gstreamer for linux, we build our own" } ] } \ No newline at end of file diff --git a/base/webRTCcomponents/README_WebRTCSetup.md b/base/webRTCcomponents/README_WebRTCSetup.md deleted file mode 100644 index 7af042f54..000000000 --- a/base/webRTCcomponents/README_WebRTCSetup.md +++ /dev/null @@ -1,16 +0,0 @@ -## Installing golang and setting up the signalling server. - -1. Install [golang](https://golang.org/doc/install) as per your operating system. -2. ```cd base/webRTCcomponents``` -3. ```go mod tidy``` to tidy up the mod ```go.mod``` and ```go.sum``` file and download dependencies. -4. ```cd goSignallingServer``` and to run the webRTCSignalling server ```go run .```. -5. Let the server run as process in some terminal. - -## Running the webrtc demo - -1. Connect a webcam device. -2. Make sure your LD_LIBRARY_PATH contains the outInstall/lib/x86_64-linux-gnu folder. -3. Run the test gstwebrtcsink_tests/gstwebrtctestrawrgbwcs. -4. The pipeline shall connect to the signalling server. -5. Open ```index.html``` and enter pipeline's peer id ```666``` to establish connection. -6. The video coming from the webRTCSink should play. \ No newline at end of file diff --git a/base/webRTCcomponents/go.mod b/base/webRTCcomponents/go.mod deleted file mode 100644 index dc988b393..000000000 --- a/base/webRTCcomponents/go.mod +++ /dev/null @@ -1,29 +0,0 @@ -module goSignallingServer - -go 1.17 - -require ( - github.com/gin-gonic/autotls v0.0.3 - github.com/gin-gonic/gin v1.7.7 - github.com/gorilla/websocket v1.4.2 - github.com/sirupsen/logrus v1.8.1 -) - -require ( - github.com/gin-contrib/sse v0.1.0 // indirect - github.com/go-playground/locales v0.13.0 // indirect - github.com/go-playground/universal-translator v0.17.0 // indirect - github.com/go-playground/validator/v10 v10.4.1 // indirect - github.com/golang/protobuf v1.3.3 // indirect - github.com/json-iterator/go v1.1.9 // indirect - github.com/leodido/go-urn v1.2.0 // indirect - github.com/mattn/go-isatty v0.0.12 // indirect - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.1 // indirect - github.com/ugorji/go/codec v1.1.7 // indirect - golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a // indirect - golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 // indirect - golang.org/x/sys v0.0.0-20200116001909-b77594299b42 // indirect - golang.org/x/text v0.3.2 // indirect - gopkg.in/yaml.v2 v2.2.8 // indirect -) diff --git a/base/webRTCcomponents/go.sum b/base/webRTCcomponents/go.sum deleted file mode 100644 index 526feb76b..000000000 --- a/base/webRTCcomponents/go.sum +++ /dev/null @@ -1,69 +0,0 @@ -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= -github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/autotls v0.0.3 h1:/kVAtMOz7qmohg93VMTb0SqB0g7wQm6ujPS8BsNeDC8= -github.com/gin-gonic/autotls v0.0.3/go.mod h1:GThKJ63OxN5tZl+YkxOVVaqm9qYiwi8kk9z0dbSCe5M= -github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= -github.com/gin-gonic/gin v1.7.7 h1:3DoBmSbJbZAWqXJC3SLjAPfutPJJRN1U5pALB7EeTTs= -github.com/gin-gonic/gin v1.7.7/go.mod h1:axIBovoeJpVj8S3BwE0uPMTeReE4+AfFtqpqaZ1qq1U= -github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= -github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= -github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= -github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= -github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= -github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= -github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE= -github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= -github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= -github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns= -github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= -github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= -github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= -github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= -github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= -github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= -github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM= -golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42 h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/base/webRTCcomponents/goSignallingServer/main.go b/base/webRTCcomponents/goSignallingServer/main.go deleted file mode 100644 index b8b21e363..000000000 --- a/base/webRTCcomponents/goSignallingServer/main.go +++ /dev/null @@ -1,209 +0,0 @@ -package main - -import ( - "net/http" - "bytes" - "os" - "errors" - "net" - "strings" - - "github.com/gin-gonic/gin" - "github.com/gorilla/websocket" - "github.com/sirupsen/logrus" -) - -//Message resp struct -// type Message struct { -// Status int `json:"status"` -// Payload interface{} `json:"payload"` -// } - - -func main() { - HTTPAPIServer() -} -//HTTPAPIServer start http server routes - just for upgrading http to ws -func HTTPAPIServer() { - var public *gin.Engine - gin.SetMode(gin.ReleaseMode) - public = gin.New() - - public.Use(CrossOrigin()) - //WebRTCSignalling - public.GET("/signalling", func(c *gin.Context) { - WebRTCSignallingServer(c.Writer, c.Request) - }) - logrus.Printf("Running webrtc signalling server on localhost:8083/signalling") - err := public.Run("localhost:8083") - if err != nil { - logrus.Println(err.Error()) - os.Exit(1) - } -} -func CrossOrigin() gin.HandlerFunc { - return func(c *gin.Context) { - c.Writer.Header().Set("Access-Control-Allow-Origin", "*") - c.Writer.Header().Set("Access-Control-Allow-Credentials", "true") - c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With") - c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT, DELETE") - if c.Request.Method == "OPTIONS" { - c.AbortWithStatus(204) - return - } - c.Next() - } -} -//Signalling server logic starts here -type Peer struct { - PeerID string - Conn *websocket.Conn - Status string -} - -var peers = make(map[string]Peer) -var sessions = make(map[string]string) - -var wsupgrader = websocket.Upgrader{ - ReadBufferSize: 1024, - WriteBufferSize: 1024, -} - -var ( - newline = []byte{'\n'} - space = []byte{' '} -) - -func helloPeer(conn *websocket.Conn) string { - raddr := conn.RemoteAddr() - msgType, hello, err := conn.ReadMessage() - logrus.Printf("%d is the message type", msgType) - if err != nil { - if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseAbnormalClosure) { - logrus.Printf("error: %v", err) - } - } - hello = bytes.TrimSpace(bytes.Replace(hello, newline, space, -1)) - helloSplit := strings.Split(string(hello), " ") - if len(helloSplit) != 2 { - conn.Close() - logrus.Printf("Invalid protocol from %s", raddr) - } - if helloSplit[0] != "HELLO" { - conn.Close() - logrus.Printf("Invalid hello from %s", raddr) - } - if _, ok := peers[helloSplit[1]]; ok { - conn.Close() - logrus.Printf("Invalid uid %s, already present", helloSplit[1]) - } - conn.WriteMessage(1, []byte("HELLO")) - peerID := helloSplit[1] - return peerID -} - -func cleanUPSession(peerID string) { - if _, ok := sessions[peerID]; ok { - otherPeerID := sessions[peerID] - delete(sessions, peerID) - logrus.Printf("Cleaned up %s session", peerID) - if _, ok := sessions[otherPeerID]; ok { - delete(sessions,otherPeerID) - logrus.Printf("Also cleaned up %s session", otherPeerID) - if _, ok := peers[otherPeerID]; ok { - logrus.Printf("Closing connection to %s", otherPeerID) - peers[otherPeerID].Conn.Close() - delete(peers, otherPeerID) - } - } - } -} - -func removePeer(peerID string) { - cleanUPSession(peerID) - if _,ok := peers[peerID]; ok { - peers[peerID].Conn.Close() - delete(peers,peerID) - logrus.Printf("Disconnected from peer %s",peerID) - } -} - -func receiveMessage(conn *websocket.Conn, raddr net.Addr) string { - msg := "" - for msg == "" { - _, msgBytes, err := conn.ReadMessage() - if err != nil { - return "ConnTerminatedByClient" - } - msgBytes = bytes.TrimSpace(bytes.Replace(msgBytes, newline, space, -1)) - msg = string(msgBytes) - } - return msg -} - -func connectionHandler(peerID string, conn *websocket.Conn) { - raddr := conn.RemoteAddr() - var peerStatus string - peers[peerID] = Peer{PeerID: peerID, Conn: conn, Status: peerStatus} - logrus.Printf("Registered peer %s at %s",peerID,raddr) - for { - msg := receiveMessage(conn, raddr) - peerStatus = peers[peerID].Status - if msg == "ConnTerminatedByClient" { - return - } else if peerStatus != "" { - if peerStatus == "session" { - otherID := sessions[peerID] - logrus.Printf("%s -> %s : %s", peerID, otherID, msg) - peers[otherID].Conn.WriteMessage(1, []byte(msg)) - } else { - logrus.Printf("Unknown peer status %s", peerStatus) - } - } else if strings.Contains(msg, "SESSION") { - logrus.Printf("%s command %s", peerID, msg) - msgSplit := strings.Split(msg, " ") - calleeID := msgSplit[1] - if _, ok := peers[calleeID]; !ok { - conn.WriteMessage(1, []byte("ERROR peer "+calleeID+" not found")) - continue - } - if peerStatus != "" { - conn.WriteMessage(1, []byte("ERROR peer"+calleeID+" busy")) - continue - } - wsc := peers[calleeID].Conn - wsc.WriteMessage(1, []byte("SESSION_OK")) - logrus.Printf("Session from %s (%s) to %s (%s)", peerID, raddr, calleeID, wsc.RemoteAddr()) - tempPeer := peers[peerID] - tempPeer.Status = "session" - peers[peerID] = tempPeer - peerStatus = "session" - - sessions[peerID] = calleeID - - tempPeer = peers[calleeID] - tempPeer.Status = "session" - peers[calleeID] = tempPeer - - sessions[calleeID] = peerID - } else { - logrus.Printf("Ignoring unknown message %s from %s", msg, peerID) - } - } -} - -func WebRTCSignallingServer(w http.ResponseWriter, r *http.Request) { - wsupgrader.CheckOrigin = func(r *http.Request) bool { return true } - conn, err := wsupgrader.Upgrade(w, r, nil) - if err != nil { - logrus.Println(err) - return - } - logrus.Printf("Connected to %s", conn.RemoteAddr()) - peerId := helloPeer(conn) - conn.SetCloseHandler(func(code int, text string) error { - removePeer(peerId) - return errors.New("ClientClosedConnection") - }) - connectionHandler(peerId, conn) -} \ No newline at end of file diff --git a/base/webRTCcomponents/index.html b/base/webRTCcomponents/index.html deleted file mode 100644 index 3d7907364..000000000 --- a/base/webRTCcomponents/index.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - -
-
Status: unknown
-
-
-
- - - - - Remote offerer -
- -
Our id is unknown
-
-
-
getUserMedia constraints being used:
-
-
- - diff --git a/base/webRTCcomponents/webrtc.js b/base/webRTCcomponents/webrtc.js deleted file mode 100644 index 075971a2e..000000000 --- a/base/webRTCcomponents/webrtc.js +++ /dev/null @@ -1,309 +0,0 @@ -/* vim: set sts=4 sw=4 et : - * - * Demo Javascript app for negotiating and streaming a sendrecv webrtc stream - * with a GStreamer app. Runs only in passive mode, i.e., responds to offers - * with answers, exchanges ICE candidates, and streams. - * - * Author: Nirbheek Chauhan - */ - -// Set this to override the automatic detection in websocketServerConnect() -var ws_server; -var ws_port; -// Set this to use a specific peer id instead of a random one -var default_peer_id; -// Override with your own STUN servers if you want -var rtc_configuration = {iceServers: [{urls: "stun:stun.services.mozilla.com"}, - {urls: "stun:stun.l.google.com:19302"}]}; -// The default constraints that will be attempted. Can be overriden by the user. -var default_constraints = {video: false, audio: false}; - -var connect_attempts = 0; -var peer_connection; -var send_channel; -var ws_conn; - -function setConnectButtonState(value) { - document.getElementById("peer-connect-button").value = value; -} - -function wantRemoteOfferer() { - return document.getElementById("remote-offerer").checked; -} - -function onConnectClicked() { - if (document.getElementById("peer-connect-button").value == "Disconnect") { - resetState(); - return; - } - - var id = document.getElementById("peer-connect").value; - if (id == "") { - alert("Peer id must be filled out"); - return; - } - - ws_conn.send("SESSION " + id); - setConnectButtonState("Disconnect"); -} - -function getOurId() { - return '1000'; -} - -function resetState() { - // This will call onServerClose() - ws_conn.close(); -} - -function handleIncomingError(error) { - setError("ERROR: " + error); - resetState(); -} - -function getVideoElement() { - return document.getElementById("stream"); -} - -function setStatus(text) { - console.log(text); - var span = document.getElementById("status") - // Don't set the status if it already contains an error - if (!span.classList.contains('error')) - span.textContent = text; -} - -function setError(text) { - console.error(text); - var span = document.getElementById("status") - span.textContent = text; - span.classList.add('error'); -} - -function resetVideo() { - - // Reset the video element and stop showing the last received frame - var videoElement = getVideoElement(); - videoElement.pause(); - videoElement.src = ""; - videoElement.load(); -} - -// SDP offer received from peer, set remote description and create an answer -function onIncomingSDP(sdp) { - peer_connection.setRemoteDescription(sdp).then(() => { - setStatus("Remote SDP set"); - if (sdp.type != "offer") - return; - setStatus("Got SDP offer"); - setStatus("Got local stream, creating answer"); - peer_connection.createAnswer() - .then(onLocalDescription).catch(setError); - }).catch(setError); -} - -// Local description was set, send it to peer -function onLocalDescription(desc) { - console.log("Got local description: " + JSON.stringify(desc)); - peer_connection.setLocalDescription(desc).then(function() { - setStatus("Sending SDP " + desc.type); - sdp = {'sdp': peer_connection.localDescription} - ws_conn.send(JSON.stringify(sdp)); - setStatus("Playing stream"); - }); -} - -function generateOffer() { - peer_connection.createOffer().then(onLocalDescription).catch(setError); -} - -// ICE candidate received from peer, add it to the peer connection -function onIncomingICE(ice) { - var candidate = new RTCIceCandidate(ice); - peer_connection.addIceCandidate(candidate).catch(setError); -} - -function onServerMessage(event) { - console.log("Received " + event.data); - switch (event.data) { - case "HELLO": - setStatus("Registered with server, waiting for call"); - return; - case "SESSION_OK": - setStatus("Starting negotiation"); - if (wantRemoteOfferer()) { - ws_conn.send("OFFER_REQUEST"); - setStatus("Sent OFFER_REQUEST, waiting for offer"); - return; - } - default: - if (event.data.startsWith("ERROR")) { - handleIncomingError(event.data); - return; - } - // Handle incoming JSON SDP and ICE messages - try { - msg = JSON.parse(event.data); - } catch (e) { - if (e instanceof SyntaxError) { - handleIncomingError("Error parsing incoming JSON: " + event.data); - } else { - handleIncomingError("Unknown error parsing response: " + event.data); - } - return; - } - - // Incoming JSON signals the beginning of a call - if (!peer_connection) - createCall(msg); - - if (msg.sdp != null) { - onIncomingSDP(msg.sdp); - } else if (msg.ice != null) { - onIncomingICE(msg.ice); - } else { - handleIncomingError("Unknown incoming JSON: " + msg); - } - } -} - -function onServerClose(event) { - setStatus('Disconnected from server'); - resetVideo(); - - if (peer_connection) { - peer_connection.close(); - peer_connection = null; - } - - // Reset after a second - window.setTimeout(websocketServerConnect, 1000); -} - -function onServerError(event) { - setError("Unable to connect to server, did you add an exception for the certificate?") - // Retry after 3 seconds - window.setTimeout(websocketServerConnect, 3000); -} - -function websocketServerConnect() { - connect_attempts++; - if (connect_attempts > 3) { - setError("Too many connection attempts, aborting. Refresh page to try again"); - return; - } - // Clear errors in the status span - var span = document.getElementById("status"); - span.classList.remove('error'); - span.textContent = ''; - // Populate constraints - var textarea = document.getElementById('constraints'); - if (textarea.value == '') - textarea.value = JSON.stringify(default_constraints); - // Fetch the peer id to use - peer_id = default_peer_id || getOurId(); - ws_port = ws_port || '8443'; - if (window.location.protocol.startsWith ("file")) { - ws_server = ws_server || "127.0.0.1"; - } else if (window.location.protocol.startsWith ("http")) { - ws_server = ws_server || window.location.hostname; - } else { - throw new Error ("Don't know how to connect to the signalling server with uri" + window.location); - } - var ws_url = 'ws://127.0.0.1:8083/signalling' - setStatus("Connecting to server " + ws_url); - ws_conn = new WebSocket(ws_url); - /* When connected, immediately register with the server */ - ws_conn.addEventListener('open', (event) => { - document.getElementById("peer-id").textContent = peer_id; - ws_conn.send('HELLO 1001'); - setStatus("Registering with server"); - setConnectButtonState("Connect"); - }); - ws_conn.addEventListener('error', onServerError); - ws_conn.addEventListener('message', onServerMessage); - ws_conn.addEventListener('close', onServerClose); -} - -function onRemoteTrack(event) { - if (getVideoElement().srcObject !== event.streams[0]) { - console.log('Incoming stream'); - getVideoElement().srcObject = event.streams[0]; - } -} - -function errorUserMediaHandler() { - setError("Browser doesn't support getUserMedia!"); -} - -const handleDataChannelOpen = (event) =>{ - console.log("dataChannel.OnOpen", event); -}; - -const handleDataChannelMessageReceived = (event) =>{ - console.log("dataChannel.OnMessage:", event, event.data.type); - - setStatus("Received data channel message"); - if (typeof event.data === 'string' || event.data instanceof String) { - console.log('Incoming string message: ' + event.data); - textarea = document.getElementById("text") - textarea.value = textarea.value + '\n' + event.data - } else { - console.log('Incoming data message'); - } - send_channel.send("Hi! (from browser)"); -}; - -const handleDataChannelError = (error) =>{ - console.log("dataChannel.OnError:", error); -}; - -const handleDataChannelClose = (event) =>{ - console.log("dataChannel.OnClose", event); -}; - -function onDataChannel(event) { - setStatus("Data channel created"); - let receiveChannel = event.channel; - receiveChannel.onopen = handleDataChannelOpen; - receiveChannel.onmessage = handleDataChannelMessageReceived; - receiveChannel.onerror = handleDataChannelError; - receiveChannel.onclose = handleDataChannelClose; -} - -function createCall(msg) { - // Reset connection attempts because we connected successfully - connect_attempts = 0; - - console.log('Creating RTCPeerConnection'); - - peer_connection = new RTCPeerConnection(rtc_configuration); - send_channel = peer_connection.createDataChannel('label', null); - send_channel.onopen = handleDataChannelOpen; - send_channel.onmessage = handleDataChannelMessageReceived; - send_channel.onerror = handleDataChannelError; - send_channel.onclose = handleDataChannelClose; - peer_connection.ondatachannel = onDataChannel; - peer_connection.ontrack = onRemoteTrack; - /* Send our video/audio to the other peer */ - - if (msg != null && !msg.sdp) { - console.log("WARNING: First message wasn't an SDP message!?"); - } - - peer_connection.onicecandidate = (event) => { - // We have a candidate, send it to the remote party with the - // same uuid - if (event.candidate == null) { - console.log("ICE Candidate was null, done"); - return; - } - ws_conn.send(JSON.stringify({'ice': event.candidate})); - }; - - if (msg != null) - setStatus("Created peer connection for call, waiting for SDP"); - - setConnectButtonState("Disconnect"); - return null; -} diff --git a/thirdparty/build_gstreamer.bat b/thirdparty/build_gstreamer.bat deleted file mode 100644 index b1d006678..000000000 --- a/thirdparty/build_gstreamer.bat +++ /dev/null @@ -1,31 +0,0 @@ -for /F "tokens=*" %%A in ('"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" -latest -property installationPath') do SET VCVARSPATH="%%A\VC\Auxiliary\Build\" -pushd %VCVARSPATH% -call vcvars64.bat -popd -@echo on - -cd gst-build - -rem use on GHA to cleanup the folder -IF /I NOT "%1"=="clean" GOTO NOCLEAN -git worktree list -rmdir /s /q gst-build-1.16 -git worktree prune -git worktree list - - -:NOCLEAN -python gst-worktree.py add gst-build-1.16 origin/1.16 -cd gst-build-1.16 - -IF ERRORLEVEL 1 (echo "we can not cd into the above dir. Better to skip the build and fail" ) && ( cd..) && ( EXIT /B 1) - -git checkout 1.16.2 - -set VSLANG=1033 -meson --prefix=%cd%\outInstall builddir -Dpython=disabled -Ddevtools=disabled -meson compile -C builddir "--vs-args=/MP" -meson install -C builddir -del /S /Q builddir -del /S /Q subprojects -dir diff --git a/thirdparty/build_gstreamer.sh b/thirdparty/build_gstreamer.sh deleted file mode 100644 index e5c6acd14..000000000 --- a/thirdparty/build_gstreamer.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash -pwd -ls -cd gst-build -git worktree list - -rm -rf gst-build-1.16 || true -git worktree prune -git worktree list - -(dos2unix ./gst-worktree.py) || true - -./gst-worktree.py add gst-build-1.16 origin/1.16 -cd gst-build-1.16 -git checkout 1.16.2 -meson --prefix=${PWD}/outInstall builddir -Dpython=disabled -ninja -C builddir -meson install -C builddir -rm -rf builddir -cd ../.. diff --git a/thirdparty/gst-build b/thirdparty/gst-build deleted file mode 160000 index 7697a3f3c..000000000 --- a/thirdparty/gst-build +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 7697a3f3cd51d70c73333f095311ef1471d0fc17