├── .gitignore ├── AUTHORS ├── CHANGELOG.md ├── CMakeLists.txt ├── LICENSE ├── NOTICE ├── README.md ├── config.h.cmake ├── debian ├── changelog ├── compat ├── control ├── copyright ├── docs ├── kms-filters-dev.install ├── kms-filters.install ├── rules └── source │ └── format ├── hooks └── pre-commit.hook ├── src ├── CMakeLists.txt ├── gst-plugins │ ├── CMakeLists.txt │ ├── facedetector │ │ ├── CMakeLists.txt │ │ ├── classifier.cpp │ │ ├── classifier.h │ │ ├── facedetector.c │ │ ├── kmsfacedetector.c │ │ └── kmsfacedetector.h │ ├── faceoverlay │ │ ├── CMakeLists.txt │ │ ├── faceoverlay.c │ │ ├── kmsfaceoverlay.c │ │ └── kmsfaceoverlay.h │ ├── imageoverlay │ │ ├── CMakeLists.txt │ │ ├── imageoverlay.c │ │ ├── kmsimageoverlay.c │ │ └── kmsimageoverlay.h │ ├── logooverlay │ │ ├── CMakeLists.txt │ │ ├── kmslogooverlay.c │ │ ├── kmslogooverlay.h │ │ └── logooverlay.c │ ├── movementdetector │ │ ├── CMakeLists.txt │ │ ├── kmsmovementdetector.c │ │ ├── kmsmovementdetector.h │ │ └── movementdetector.c │ └── opencvfilter │ │ ├── CMakeLists.txt │ │ ├── kmsopencvfilter.cpp │ │ ├── kmsopencvfilter.h │ │ └── opencvfilter.c └── server │ ├── CMakeLists.txt │ ├── implementation │ └── objects │ │ ├── FaceOverlayFilterImpl.cpp │ │ ├── FaceOverlayFilterImpl.hpp │ │ ├── GStreamerFilterImpl.cpp │ │ ├── GStreamerFilterImpl.hpp │ │ ├── ImageOverlayFilterImpl.cpp │ │ ├── ImageOverlayFilterImpl.hpp │ │ ├── OpenCVFilterImpl.cpp │ │ ├── OpenCVFilterImpl.hpp │ │ ├── OpenCVProcess.hpp │ │ ├── ZBarFilterImpl.cpp │ │ └── ZBarFilterImpl.hpp │ └── interface │ ├── filters.FaceOverlayFilter.kmd.json │ ├── filters.GStreamerFilter.kmd.json │ ├── filters.ImageOverlayFilter.kmd.json │ ├── filters.OpenCVFilter.kmd.json │ ├── filters.ZBarFilter.kmd.json │ ├── filters.kmd.json │ ├── package.json │ └── pom.xml └── tests ├── CMakeLists.txt ├── check ├── CMakeLists.txt ├── element │ ├── CMakeLists.txt │ ├── faceoverlay.c │ ├── logooverlay.c │ └── movementdetector.c ├── kmscheck.h ├── kmstestutils.c ├── kmstestutils.h ├── memory_leaks.sh └── valgrind.supp └── server ├── CMakeLists.txt └── constructors.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *kdev4 3 | .idea 4 | build 5 | obj-x86_64-linux-gnu 6 | .excludes 7 | CMakeLists.txt.user 8 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Jose Antonio Santos Cadenas 2 | Miguel París Díaz 3 | Santiago Carot-Nemesio 4 | David Fernandez 5 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this project will be documented in this file. 3 | 4 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) 5 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 6 | 7 | ## 6.10.0 - 2019-04-03 8 | 9 | Starting from 6.10.0, all of these Kurento Media Server sub-projects 10 | 11 | - kurento-module-creator 12 | - kms-cmake-utils 13 | - kms-core 14 | - kms-elements 15 | - kms-filters 16 | - kms-jsonrpc 17 | - kurento-media-server 18 | 19 | have their ChangeLogs unified in [kurento-media-server/CHANGELOG](https://github.com/Kurento/kurento-media-server/blob/master/CHANGELOG.md). 20 | 21 | 22 | ## [6.8.0] - 2018-09-26 23 | 24 | ### Added 25 | - Logging: Add support for libsoup debug logging 26 | - GStreamerFilters: Add setElementProperty() for real time updating of properties. Supported types: 27 | - Int 28 | - Float 29 | - Double 30 | - Enum 31 | 32 | ### Changed 33 | - API: Review documentation, update links 34 | 35 | ### Fixed 36 | - clang-tidy fixes 37 | 38 | ## [6.7.1] - 2018-03-21 39 | 40 | ### Changed 41 | - Push version to 6.7.1. 42 | 43 | ## [6.7.0] - 2018-01-24 44 | 45 | ### Changed 46 | - CMake: Compile and link as Position Independent Code (`-fPIC`). 47 | - Add more verbose logging in some areas that required it. 48 | - Debian: Align all version numbers of KMS-related modules. 49 | - Debian: Remove version numbers from package names. 50 | - Debian: Configure builds to use parallel compilation jobs. 51 | 52 | ## [6.6.2] - 2017-07-24 53 | 54 | ### Changed 55 | - Old ChangeLog.md moved to the new format in this CHANGELOG.md file. 56 | - CMake: Full review of all CMakeLists.txt files to tidy up and homogenize code style and compiler flags. 57 | - CMake: Position Independent Code flags (`-fPIC`) were scattered around projects, and are now removed. Instead, the more CMake-idiomatic variable "CMAKE_POSITION_INDEPENDENT_CODE" is used. 58 | - CMake: All projects now compile with `-std=c11|-std=c++11 -Wall -Werror -pthread`. 59 | - CMake: Debug builds now compile with `-g -O0` (while default CMake used `-O1` for Debug builds). 60 | - CMake: include() and import() commands were moved to the code areas where they are actually required. 61 | 62 | ## [6.6.1] - 2016-09-30 63 | 64 | ### Changed 65 | - Improve compilation process. 66 | - CMake: Rename library testutils to filtertestutils. 67 | - CMake: Rename constructor test to filters_constructors. 68 | - CMake: Avoid using global cmake directories. 69 | - CMake: Avoid the use of global include directories. 70 | 71 | ## [6.6.0] - 2016-09-09 72 | 73 | ## [6.5.0] - 2016-05-27 74 | 75 | ### Changed 76 | - Changed license to Apache 2.0. 77 | - Updated documentation. 78 | - Test: Update and activate filter tests. 79 | - Logooverlay: Add test for kmslogooverlay filter. 80 | 81 | ## [6.4.0] - 2016-02-24 82 | 83 | ## [6.3.0] - 2019-01-19 84 | 85 | ## 6.2.0 - 2015-11-25 86 | 87 | ### Added 88 | - OpenCvFilter: Now exceptions raised in OpenCV code are sent to the client as errors. 89 | 90 | ### Changed 91 | - Update GStreamer version to 1.7. 92 | - GStreamerFilter: Improve command parser using `gst-launch` parser. 93 | - KmsOpencvFilter: Convert KurentoExceptions into bus messages. 94 | 95 | [6.8.0]: https://github.com/Kurento/kms-filters/compare/6.7.1...6.8.0 96 | [6.7.1]: https://github.com/Kurento/kms-filters/compare/6.7.0...6.7.1 97 | [6.7.0]: https://github.com/Kurento/kms-filters/compare/6.6.2...6.7.0 98 | [6.6.2]: https://github.com/Kurento/kms-filters/compare/6.6.1...6.6.2 99 | [6.6.1]: https://github.com/Kurento/kms-filters/compare/6.6.0...6.6.1 100 | [6.6.0]: https://github.com/Kurento/kms-filters/compare/6.5.0...6.6.0 101 | [6.5.0]: https://github.com/Kurento/kms-filters/compare/6.4.0...6.5.0 102 | [6.4.0]: https://github.com/Kurento/kms-filters/compare/6.3.0...6.4.0 103 | [6.3.0]: https://github.com/Kurento/kms-filters/compare/6.2.0...6.3.0 104 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8) 2 | 3 | project("kms-filters") 4 | message(STATUS "CMake project: ${PROJECT_NAME}") 5 | 6 | # Test configuration 7 | set(GENERATE_TESTS FALSE CACHE BOOL "Always build tests: add `make check_build` to normal `make` calls") 8 | set(DISABLE_TESTS FALSE CACHE BOOL "Enable running `make check` during the building process") 9 | set(VALGRIND_NUM_CALLERS 20 CACHE STRING "Valgrind option: maximum number of entries shown in stack traces") 10 | 11 | message("If KurentoHelpers is not found, you need to install 'kms-cmake-utils' from the Kurento repository") 12 | find_package(KurentoHelpers REQUIRED) 13 | 14 | message("If CodeGenerator is not found, you need to install 'kms-core' from the Kurento repository") 15 | include(CodeGenerator) 16 | get_values_from_model(PREFIX VALUE MODELS ${CMAKE_CURRENT_SOURCE_DIR}/src/server/interface KEYS version) 17 | 18 | include(KurentoGitHelpers) 19 | install_git_hook(pre-commit ${CMAKE_CURRENT_SOURCE_DIR}/hooks/pre-commit.hook) 20 | get_git_version(PROJECT_VERSION ${VALUE_VERSION}) 21 | message(STATUS "Project version: ${PROJECT_NAME}-${PROJECT_VERSION}") 22 | 23 | # Compiler flags 24 | include(CommonBuildFlags) 25 | common_buildflags_set() 26 | #common_buildflags_print() 27 | 28 | # Development: Add here exceptions to the "Warnings are Errors" rule. 29 | # Also, DOCUMENT WHY and always remove them as soon as the problem is fixed. 30 | # For example: 31 | #set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-error=unused-function") 32 | #set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-error=unused-variable") 33 | 34 | # FIXME Disable error when macros __TIME__, __DATE__ or __TIMESTAMP__ are encountered 35 | include(CheckCXXCompilerFlag) 36 | CHECK_CXX_COMPILER_FLAG("-Wno-error=date-time" HAS_WARNING_DATE_TIME) 37 | if(HAS_WARNING_DATE_TIME) 38 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=date-time") 39 | endif() 40 | 41 | # Generate file "config.h" 42 | set(VERSION ${PROJECT_VERSION}) 43 | set(PACKAGE ${PROJECT_NAME}) 44 | set(GETTEXT_PACKAGE "kms-filters") 45 | set(MANUAL_CHECK OFF CACHE BOOL "Tests will generate files") 46 | set(BINARY_LOCATION "http://files.openvidu.io/" CACHE STRING "Storage with test files (as an URI, http:// or file:///)") 47 | include(GNUInstallDirs) 48 | set(KURENTO_MODULES_SO_DIR ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/${KURENTO_MODULES_DIR_INSTALL_PREFIX}) 49 | configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h) 50 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DHAVE_CONFIG_H") 51 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DHAVE_CONFIG_H") 52 | 53 | set(GST_REQUIRED ^1.5.0) 54 | set(GLIB_REQUIRED ^2.38) 55 | set(OPENCV_REQUIRED <4.0.0) 56 | set(LIBSOUP_REQUIRED ^2.40) 57 | 58 | include(GenericFind) 59 | generic_find(LIBNAME gstreamer-1.5 VERSION ${GST_REQUIRED} REQUIRED) 60 | generic_find(LIBNAME gstreamer-base-1.5 VERSION ${GST_REQUIRED} REQUIRED) 61 | generic_find(LIBNAME gstreamer-video-1.5 VERSION ${GST_REQUIRED} REQUIRED) 62 | generic_find(LIBNAME gstreamer-check-1.5 VERSION ${GST_REQUIRED}) 63 | generic_find(LIBNAME opencv VERSION ${OPENCV_REQUIRED} REQUIRED) 64 | generic_find(LIBNAME libsoup-2.4 VERSION ${LIBSOUP_REQUIRED} REQUIRED) 65 | 66 | set(CMAKE_INSTALL_GST_PLUGINS_DIR ${CMAKE_INSTALL_LIBDIR}/gstreamer-1.5) 67 | 68 | enable_testing() 69 | 70 | add_subdirectory(src) 71 | add_subdirectory(tests) 72 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | (C) Copyright 2016 Kurento (https://kurento.openvidu.io/) 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![License badge](https://img.shields.io/badge/license-Apache2-orange.svg)](http://www.apache.org/licenses/LICENSE-2.0) 2 | [![Documentation badge](https://readthedocs.org/projects/fiware-orion/badge/?version=latest)](https://doc-kurento.readthedocs.io) 3 | [![Docker badge](https://img.shields.io/docker/pulls/fiware/orion.svg)](https://hub.docker.com/r/fiware/stream-oriented-kurento/) 4 | [![Support badge]( https://img.shields.io/badge/support-sof-yellowgreen.svg)](https://stackoverflow.com/questions/tagged/kurento) 5 | 6 | [![][KurentoImage]][Kurento] 7 | 8 | Copyright 2018 [Kurento]. Licensed under [Apache 2.0 License]. 9 | 10 | [Kurento]: https://kurento.openvidu.io/ 11 | [KurentoImage]: https://secure.gravatar.com/avatar/21a2a12c56b2a91c8918d5779f1778bf?s=120 12 | [Apache 2.0 License]: http://www.apache.org/licenses/LICENSE-2.0 13 | 14 | 15 | 16 | kms-filters 17 | =========== 18 | 19 | Filter elements for Kurento Media Server. 20 | 21 | The kms-filters project contains **filter elements** for the Kurento Media Server. 22 | 23 | 24 | 25 | About Kurento 26 | ============= 27 | 28 | Kurento is an open source software project providing a platform suitable for creating modular applications with advanced real-time communication capabilities. For knowing more about Kurento, please visit the Kurento project website: https://kurento.openvidu.io/. 29 | 30 | Kurento is part of [FIWARE]. For further information on the relationship of FIWARE and Kurento check the [Kurento FIWARE Catalog Entry]. Kurento is also part of the [NUBOMEDIA] research initiative. 31 | 32 | [FIWARE]: http://www.fiware.org 33 | [Kurento FIWARE Catalog Entry]: http://catalogue.fiware.org/enablers/stream-oriented-kurento 34 | [NUBOMEDIA]: http://www.nubomedia.eu 35 | 36 | 37 | 38 | Documentation 39 | ------------- 40 | 41 | The Kurento project provides detailed [documentation] including tutorials, installation and development guides. The [Open API specification], also known as *Kurento Protocol*, is available on [apiary.io]. 42 | 43 | [documentation]: https://kurento.openvidu.io/documentation 44 | [Open API specification]: http://kurento.github.io/doc-kurento/ 45 | [apiary.io]: http://docs.streamoriented.apiary.io/ 46 | 47 | 48 | 49 | Useful Links 50 | ------------ 51 | 52 | Usage: 53 | 54 | * [Installation Guide](https://doc-kurento.readthedocs.io/en/latest/user/installation.html) 55 | * [Compilation Guide](https://doc-kurento.readthedocs.io/en/latest/dev/dev_guide.html#developing-kms) 56 | * [Contribution Guide](https://doc-kurento.readthedocs.io/en/latest/project/contribute.html) 57 | 58 | Issues: 59 | 60 | * [Bug Tracker](https://github.com/Kurento/bugtracker/issues) 61 | * [Support](https://doc-kurento.readthedocs.io/en/latest/user/support.html) 62 | 63 | News: 64 | 65 | * [Kurento Blog](https://kurento.openvidu.io/blog) 66 | * [Google Groups](https://groups.google.com/forum/#!forum/kurento) 67 | 68 | 69 | 70 | Source 71 | ------ 72 | 73 | All source code belonging to the Kurento project can be found in the [Kurento GitHub organization page]. 74 | 75 | [Kurento GitHub organization page]: https://github.com/Kurento 76 | 77 | 78 | 79 | Licensing and distribution 80 | -------------------------- 81 | 82 | Copyright 2018 Kurento 83 | 84 | Licensed under the Apache License, Version 2.0 (the "License"); 85 | you may not use this file except in compliance with the License. 86 | You may obtain a copy of the License at 87 | 88 | http://www.apache.org/licenses/LICENSE-2.0 89 | 90 | Unless required by applicable law or agreed to in writing, software 91 | distributed under the License is distributed on an "AS IS" BASIS, 92 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 93 | See the License for the specific language governing permissions and 94 | limitations under the License. 95 | -------------------------------------------------------------------------------- /config.h.cmake: -------------------------------------------------------------------------------- 1 | #ifndef __KMS_ELEMENTS_CONFIG_H__ 2 | #define __KMS_ELEMENTS_CONFIG_H__ 3 | 4 | /* Version */ 5 | #cmakedefine VERSION "@VERSION@" 6 | 7 | /* Package name */ 8 | #cmakedefine PACKAGE "@PACKAGE@" 9 | 10 | /* The gettext domain name */ 11 | #cmakedefine GETTEXT_PACKAGE "@GETTEXT_PACKAGE@" 12 | 13 | /* Tests will generate files for manual check if this macro is defined */ 14 | #cmakedefine MANUAL_CHECK 15 | 16 | /* Binary files directory */ 17 | #cmakedefine BINARY_LOCATION "@BINARY_LOCATION@" 18 | 19 | /* Library installation directory */ 20 | #cmakedefine KURENTO_MODULES_SO_DIR "@KURENTO_MODULES_SO_DIR@" 21 | 22 | #endif /* __KMS_ELEMENTS_CONFIG_H__ */ 23 | -------------------------------------------------------------------------------- /debian/changelog: -------------------------------------------------------------------------------- 1 | kms-filters (6.18.1-0kurento1) UNRELEASED; urgency=medium 2 | 3 | [ Kurento ] 4 | * UNRELEASED 5 | 6 | -- Juan Navarro Tue, 20 Sep 2022 17:15:32 +0200 7 | 8 | kms-filters (6.18.0-0kurento1) testing; urgency=medium 9 | 10 | [ Kurento ] 11 | * Prepare release 6.18.0-0kurento1 12 | 13 | -- Juan Navarro Wed, 14 Sep 2022 14:04:32 +0000 14 | 15 | kms-filters (6.17.0-0kurento1) testing; urgency=medium 16 | 17 | * Prepare release 6.17.0-0kurento1 18 | * debian: install ca-certificates for HTTPS access in OpenCV filters 19 | 20 | -- Juan Navarro Wed, 30 Mar 2022 13:59:41 +0200 21 | 22 | kms-filters (6.16.0-0kurento1) testing; urgency=medium 23 | 24 | * Prepare release 6.16.0-0kurento1 25 | * Update all dependency versions to 6.15.1 26 | 27 | -- Juan Navarro Fri, 26 Feb 2021 12:01:39 +0100 28 | 29 | kms-filters (6.15.0-0kurento1) testing; urgency=medium 30 | 31 | * Prepare release 6.15.0-0kurento1 32 | * debian: update versions of Kurento dependencies 33 | 34 | -- Juan Navarro Tue, 03 Nov 2020 18:04:23 +0100 35 | 36 | kms-filters (6.14.0-0kurento1) testing; urgency=medium 37 | 38 | * Prepare release 6.14.0-0kurento1 39 | 40 | -- Juan Navarro Tue, 16 Jun 2020 17:48:05 +0200 41 | 42 | kms-filters (6.13.0-0kurento1) testing; urgency=medium 43 | 44 | * Prepare release 6.13.0-0kurento1 45 | * debian/control: Add build-essential to Build-Depends 46 | 47 | -- Juan Navarro Tue, 17 Dec 2019 13:37:55 +0100 48 | 49 | kms-filters (6.12.0-0kurento1) testing; urgency=medium 50 | 51 | * Prepare release 6.12.0-0kurento1 52 | 53 | -- Juan Navarro Mon, 14 Oct 2019 19:12:35 +0200 54 | 55 | kms-filters (6.11.0-0kurento1) testing; urgency=medium 56 | 57 | * Prepare release 6.11.0-0kurento1 58 | * debian/control: Add deps needed for building and testing 59 | 60 | -- Juan Navarro Fri, 19 Jul 2019 19:47:55 +0200 61 | 62 | kms-filters (6.10.0-0kurento1) testing; urgency=medium 63 | 64 | * Prepare release 6.10.0 65 | * debian: Review for 18.04 build 66 | 67 | -- Juan Navarro Thu, 04 Apr 2019 10:32:32 +0200 68 | 69 | kms-filters (6.9.0) testing; urgency=medium 70 | 71 | 72 | -- Juan Navarro Mon, 10 Dec 2018 17:49:35 +0100 73 | 74 | kms-filters (6.8.0) testing; urgency=medium 75 | 76 | * Remove 'override_dh_auto_test' from debian/rules 77 | * Prepare release 6.8.0 78 | 79 | -- Juan Navarro Moreno Wed, 26 Sep 2018 11:30:00 +0200 80 | 81 | kms-filters (6.7.1) testing; urgency=medium 82 | 83 | [ Juan Navarro Moreno ] 84 | * Prepare release 6.7.1 85 | 86 | -- Juan Navarro Moreno Wed, 21 Mar 2018 16:20:32 +0100 87 | 88 | kms-filters (6.7.0) testing; urgency=medium 89 | 90 | [ Juan Navarro Moreno ] 91 | * Remove version numbers from package names 92 | * Align all version numbers of KMS-related modules 93 | * Updates to debian/control: 94 | - Maintainer: Kurento 95 | - Standards-Version: 4.0.0 96 | - Homepage: www.kurento.org (let server redirect to HTTPS if available) 97 | - Vcs-Git: https://github.com/Kurento/*.git (use secure URL) 98 | - Section: libs|libdevel|devel|debug|video (set appropriate one for 99 | each binary package) 100 | - Description: Review description text 101 | * Updates to debian/copyright: 102 | - Refer to '/usr/share/common-licenses/Apache-2.0' rather than 103 | quoting the license text. 104 | * Updates to debian/docs: 105 | - Added file CHANGELOG.md 106 | * Prepare release 6.7.0 107 | 108 | -- Juan Navarro Moreno Wed, 25 Jan 2018 13:05:00 +0100 109 | 110 | kms-filters-6.0 (6.6.2) testing; urgency=medium 111 | 112 | [ Juan Navarro Moreno ] 113 | 114 | * Changed 115 | - Old ChangeLog.md moved to the new format in this CHANGELOG.md file. 116 | - CMake: Full review of all CMakeLists.txt files to tidy up and homogenize 117 | code style and compiler flags. 118 | - CMake: Position Independent Code flags ("-fPIC") were scattered around 119 | projects, and are now removed. Instead, the more CMake-idiomatic variable 120 | "CMAKE_POSITION_INDEPENDENT_CODE" is used. 121 | - CMake: All projects now compile with 122 | "[-std=c11|-std=c++11] -Wall -Werror -pthread". 123 | - CMake: Debug builds now compile with "-g -O0" (while default CMake used 124 | "-O1" for Debug builds). 125 | - CMake: include() and import() commands were moved to the code areas where 126 | they are actually required. 127 | 128 | -- Juan Navarro Moreno Fri, 24 Jul 2017 11:00:00 +0200 129 | 130 | kms-filters-6.0 (6.6.1) testing; urgency=medium 131 | 132 | [ Jose Antonio Santos Cadenas ] 133 | * Prepare for next development iteration 134 | * CMake: Add missing link library 135 | * CMake: Rename library testutils to filtertestutils 136 | * CMake: Rename constructor test to filters_constructors 137 | * CMake: Avoid using global cmake directories 138 | * constructors: Add more paths to look for modules 139 | * CMake: Avoid the use of global include directories 140 | * Fix compilation with clang 141 | * Prepare release 6.6.1 142 | 143 | [ Jose Antonio Santos ] 144 | 145 | -- Jose Antonio Santos Cadenas Fri, 30 Sep 2016 12:51:25 +0200 146 | 147 | kms-filters-6.0 (6.6.0) testing; urgency=medium 148 | 149 | [ Jose Antonio Santos Cadenas ] 150 | * Prepare for next development iteration 151 | * ChangeLog.md: Prepare release notes for 6.6.0 152 | * Prepare release 6.6.0 153 | 154 | [ Jose Antonio Santos ] 155 | 156 | -- Jose Antonio Santos Cadenas Fri, 09 Sep 2016 17:08:18 +0200 157 | 158 | kms-filters-6.0 (6.5.0) testing; urgency=medium 159 | 160 | [ Jose Antonio Santos Cadenas ] 161 | * Prepare for next development iteration 162 | 163 | [ David Fernandez ] 164 | * test: Update and activate filter tests 165 | * logooverlay: Add test for kmslogooverlay filter 166 | 167 | [ Raúl Benítez Mejías ] 168 | * Add badges into all README.md 169 | 170 | [ Jose Antonio Santos Cadenas ] 171 | * CMake: Disable error date time 172 | * Fix style 173 | * Change license to Apache 2.0 174 | * Prepare release 6.5.0 175 | 176 | [ Jose Antonio Santos ] 177 | 178 | -- Jose Antonio Santos Cadenas Fri, 27 May 2016 17:42:26 +0200 179 | 180 | kms-filters-6.0 (6.4.1~20160510170902.5.22d9f69.xenial) testing; urgency=medium 181 | 182 | Generating new package version 183 | 184 | -- Jose Antonio Santos Cadenas Tue, 10 May 2016 17:09:02 +0200 185 | 186 | kms-filters-6.0 (6.4.0) testing; urgency=medium 187 | 188 | [ Jose Antonio Santos Cadenas ] 189 | * Prepare for next development iteration 190 | * Add build configuration 191 | 192 | [ David Fernandez ] 193 | * debian/rules: Execute test in debian package generation 194 | 195 | [ Jose Antonio Santos Cadenas ] 196 | * Prepare release 6.4.0 197 | 198 | [ José Antonio Santos Cadenas ] 199 | 200 | -- Jose Antonio Santos Cadenas Wed, 24 Feb 2016 17:16:14 +0100 201 | 202 | kms-filters-6.0 (6.3.0) testing; urgency=medium 203 | 204 | [ Jose Antonio Santos Cadenas ] 205 | * Prepare for next development iteration 206 | * Prepare release 6.3.0 207 | 208 | [ José Antonio Santos Cadenas ] 209 | 210 | -- Jose Antonio Santos Cadenas Tue, 19 Jan 2016 17:09:08 +0100 211 | 212 | kms-filters-6.0 (6.2.0) testing; urgency=medium 213 | 214 | [ Jose Antonio Santos Cadenas ] 215 | * Prepare for next development iteration 216 | * CMakeLists: Fix gstreamer version 217 | 218 | [ David Fernandez ] 219 | * kmsopencvfilter: Convert KurentoExceptions in bus messages 220 | 221 | [ Jose Antonio Santos Cadenas ] 222 | * GStreamerFilter: user gst_parse_launch to generate element 223 | * pre-commit-hook: Fix to work newer versions of astyle 224 | * pre-commit.hook: Do not print git add and git commit in fix command 225 | * Prepare release 6.2.0 226 | 227 | [ José Antonio Santos Cadenas ] 228 | 229 | -- Jose Antonio Santos Cadenas Wed, 25 Nov 2015 12:41:36 +0100 230 | 231 | kms-filters-6.0 (6.1.1) testing; urgency=medium 232 | 233 | [ Jose Antonio Santos Cadenas ] 234 | * Prepare for next development iteration 235 | 236 | [ Boni Garcia ] 237 | * Updated README.md according to FIWARE guidelines 238 | * Added links to readthedocs.org and apiary.io in README 239 | * Fixed broken links in README 240 | 241 | [ Jose Antonio Santos Cadenas ] 242 | * Prepare release 6.1.1 243 | 244 | [ José Antonio Santos Cadenas ] 245 | 246 | -- Jose Antonio Santos Cadenas Thu, 01 Oct 2015 19:58:44 +0200 247 | 248 | kms-filters-6.0 (6.1.0) testing; urgency=medium 249 | 250 | [ Jose Antonio Santos Cadenas ] 251 | * Prepare for next development iteration 252 | * Prepare release 6.1.0 253 | 254 | [ José Antonio Santos Cadenas ] 255 | 256 | -- Jose Antonio Santos Cadenas Tue, 01 Sep 2015 15:57:30 +0200 257 | 258 | kms-filters-6.0 (6.0.0) testing; urgency=medium 259 | 260 | [ Jose Antonio Santos Cadenas ] 261 | * Prepare for next development iteration 262 | * Fix build dependencies for tests 263 | * Add support for different cmake vesions 264 | * Update .gitreview to work with new repo 265 | * Prepare for 6.0 development iteration 266 | 267 | [ David Fernandez ] 268 | * Adapt events code to KmsEvent 269 | * kmsimageoverlay: Protect set and get properties with locks 270 | * [ImageOverlayFilter] Add new filter to allow overlay images over a video 271 | * ZBarFilter: Move signal logic to postConstructor function 272 | * Update gstreamer dependencies 273 | * kmsimageoverlay: Progress event to parent 274 | * kmslogooverlay: Not show image if it is NULL 275 | * ImageOverlayFilter: Add keepAspectRatio and center parameters 276 | 277 | [ Jesús Leganés Combarro "piranna ] 278 | * Use correct SPDX licence string 279 | 280 | [ David Fernandez ] 281 | * GStreamerFilter: Add property to get the command of the filter 282 | 283 | [ Jose Antonio Santos Cadenas ] 284 | * Prepare release 6.0.0 285 | 286 | [ José Antonio Santos Cadenas ] 287 | 288 | -- Jose Antonio Santos Cadenas Tue, 14 Jul 2015 19:26:45 +0200 289 | 290 | kms-filters-6.0 (6.0.0~0) testing; urgency=medium 291 | 292 | * Pre release of version 6.0.0 293 | 294 | -- Jose Antonio Santos Cadenas Wed, 11 Feb 2015 12:24:49 +0100 295 | 296 | kms-filters (5.1.0) testing; urgency=medium 297 | 298 | [ Jose Antonio Santos Cadenas ] 299 | * Prepare for next development iteration 300 | * Change version to 5.1.0 301 | 302 | [ Jesús Leganés Combarro "piranna ] 303 | * Removed bower.json since now it's being generated 304 | 305 | [ Jose Antonio Santos Cadenas ] 306 | * Update dependencies 307 | * Prepare release 5.1.0 308 | 309 | [ José Antonio Santos Cadenas ] 310 | 311 | -- Jose Antonio Santos Cadenas Sat, 24 Jan 2015 09:02:33 +0100 312 | 313 | kms-filters (5.0.4) testing; urgency=medium 314 | 315 | [ Jose Antonio Santos Cadenas ] 316 | * Prepare for next developmen iteration 317 | * Update kms-elements dependencies dependencies 318 | * Add opencv to generated pkg-config 319 | 320 | [ David Fernandez ] 321 | * OpenCVProcess: Add getSharedPtr function 322 | 323 | [ Jose Antonio Santos Cadenas ] 324 | * Fix compilation of gst-plugins 325 | * Install generated FindKMSFILTERS.cmake 326 | * Start using generic_find to look for dependencies 327 | * Prepare release 5.0.4 328 | 329 | [ José Antonio Santos Cadenas ] 330 | 331 | -- Jose Antonio Santos Cadenas Tue, 07 Oct 2014 07:37:05 +0200 332 | 333 | kms-filters (5.0.3) testing; urgency=medium 334 | 335 | [ Jose Antonio Santos Cadenas ] 336 | * Prepare for next development iteration 337 | * Update dependencies 338 | * Prepare release 5.0.3 339 | 340 | [ José Antonio Santos Cadenas ] 341 | 342 | -- Jose Antonio Santos Cadenas Mon, 22 Sep 2014 11:14:02 +0200 343 | 344 | kms-filters (5.0.2) testing; urgency=medium 345 | 346 | [ Jose Antonio Santos Cadenas ] 347 | * Prepare for next development iteration 348 | * debian/control: Update dependencies 349 | * Prepare release 5.0.2 350 | 351 | [ José Antonio Santos Cadenas ] 352 | 353 | -- Jose Antonio Santos Cadenas Sat, 20 Sep 2014 23:13:19 +0200 354 | 355 | kms-filters (5.0.1) trusty; urgency=medium 356 | 357 | * Release 5.0.1 358 | 359 | -- Jose Antonio Santos Cadenas Fri, 19 Sep 2014 15:31:17 +0200 360 | 361 | kms-filters (5.0.0~rc1) testing; urgency=medium 362 | 363 | * Initial release. 364 | 365 | -- Jose Antonio Santos Cadenas Thu, 24 Jul 2014 22:00:30 +0200 366 | -------------------------------------------------------------------------------- /debian/compat: -------------------------------------------------------------------------------- 1 | 9 2 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: kms-filters 2 | Priority: optional 3 | Maintainer: Kurento 4 | Build-Depends: debhelper (>= 9), 5 | build-essential, 6 | cmake, 7 | gstreamer1.5-plugins-bad, 8 | gstreamer1.5-plugins-good, 9 | kms-cmake-utils (>= 6.18.1), 10 | kms-core-dev (>= 6.18.1), 11 | kms-elements-dev (>= 6.18.1), 12 | kurento-module-creator (>= 6.18.1), 13 | libboost-filesystem-dev, 14 | libboost-system-dev, 15 | libglibmm-2.4-dev, 16 | libgstreamer-plugins-base1.5-dev, 17 | libopencv-dev, 18 | libsigc++-2.0-dev, 19 | libsoup2.4-dev 20 | Standards-Version: 4.0.0 21 | Vcs-Git: https://github.com/Kurento/kms-filters.git 22 | Vcs-Browser: https://github.com/Kurento/kms-filters 23 | Homepage: https://kurento.openvidu.io/ 24 | 25 | Package: kms-filters 26 | Architecture: any 27 | Section: libs 28 | Depends: ${shlibs:Depends}, ${misc:Depends}, 29 | ca-certificates, 30 | kms-elements (>= 6.18.1), 31 | opencv-data 32 | Breaks: kms-filters-6.0 33 | Replaces: kms-filters-6.0 34 | Description: Kurento Filters module 35 | Kurento Filters module - Binary libraries. 36 | 37 | Package: kms-filters-dev 38 | Architecture: any 39 | Section: libdevel 40 | Depends: kms-filters (= ${binary:Version}), 41 | kms-cmake-utils (>= 6.18.1), 42 | kms-core-dev (>= 6.18.1), 43 | kms-elements-dev (>= 6.18.1), 44 | kurento-module-creator (>= 6.18.1), 45 | libboost-filesystem-dev, 46 | libboost-system-dev, 47 | libglibmm-2.4-dev, 48 | libgstreamer-plugins-base1.5-dev, 49 | libopencv-dev, 50 | libsigc++-2.0-dev, 51 | libsoup2.4-dev 52 | Breaks: kms-filters-6.0-dev 53 | Replaces: kms-filters-6.0-dev 54 | Description: Kurento Filters module 55 | Kurento Filters module - Development files. 56 | 57 | Package: kms-filters-dbg 58 | Architecture: any 59 | Section: debug 60 | Depends: kms-filters (= ${binary:Version}) 61 | Breaks: kms-filters-6.0-dbg 62 | Replaces: kms-filters-6.0-dbg 63 | Description: Kurento Filters module 64 | Kurento Filters module - Debugging symbols. 65 | -------------------------------------------------------------------------------- /debian/copyright: -------------------------------------------------------------------------------- 1 | Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Upstream-Name: Kurento Filters 3 | Upstream-Contact: Kurento 4 | Source: https://github.com/Kurento/kms-filters 5 | 6 | Files: * 7 | Copyright: 2018, Kurento (https://kurento.openvidu.io/) 8 | License: Apache-2.0 9 | On Debian systems, the full text of the Apache-2.0 license 10 | can be found in the file '/usr/share/common-licenses/Apache-2.0' 11 | -------------------------------------------------------------------------------- /debian/docs: -------------------------------------------------------------------------------- 1 | README.md 2 | CHANGELOG.md 3 | -------------------------------------------------------------------------------- /debian/kms-filters-dev.install: -------------------------------------------------------------------------------- 1 | usr/include/kurento/modules/*/*.hpp 2 | usr/lib/*/*.so 3 | usr/lib/*/pkgconfig/*.pc 4 | usr/share/kurento/modules/*.kmd.json 5 | usr/share/cmake-*/Modules/* 6 | -------------------------------------------------------------------------------- /debian/kms-filters.install: -------------------------------------------------------------------------------- 1 | usr/lib/*/lib*.so.* 2 | usr/lib/*/gstreamer-1.5/lib*.so 3 | usr/lib/*/kurento/*/*.so 4 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | 3 | # Uncomment this to enable verbose mode. 4 | #export DH_VERBOSE=1 5 | 6 | %: 7 | dh $@ --parallel 8 | 9 | override_dh_auto_configure: 10 | dh_auto_configure -- -DGENERATE_TESTS=TRUE 11 | 12 | .PHONY: override_dh_strip 13 | 14 | override_dh_strip: 15 | dh_strip --dbg-package=kms-filters-dbg 16 | -------------------------------------------------------------------------------- /debian/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (native) 2 | -------------------------------------------------------------------------------- /hooks/pre-commit.hook: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Check that the code follows a consistant code style 4 | # 5 | 6 | # Check for existence of indent, and error out if not present. 7 | # On some *bsd systems the binary seems to be called gnunindent, 8 | # so check for that first. 9 | 10 | version=`gnuindent --version 2>/dev/null` 11 | if test "x$version" = "x"; then 12 | version=`indent --version 2>/dev/null` 13 | if test "x$version" = "x"; then 14 | echo "Kurento git pre-commit hook:" 15 | echo "Did not find GNU indent, please install it before continuing." 16 | exit 1 17 | fi 18 | INDENT=indent 19 | else 20 | INDENT=gnuindent 21 | fi 22 | 23 | case `$INDENT --version` in 24 | GNU*) 25 | ;; 26 | default) 27 | echo "Kurento git pre-commit hook:" 28 | echo "Did not find GNU indent, please install it before continuing." 29 | echo "(Found $INDENT, but it doesn't seem to be GNU indent)" 30 | exit 1 31 | ;; 32 | esac 33 | 34 | INDENT_PARAMETERS="--braces-on-if-line\ 35 | --case-brace-indentation0\ 36 | --case-indentation2\ 37 | --braces-after-struct-decl-line\ 38 | --line-length80\ 39 | --no-tabs\ 40 | --cuddle-else\ 41 | --dont-line-up-parentheses\ 42 | --continuation-indentation4\ 43 | --tab-size8\ 44 | --indent-level2\ 45 | --leave-preprocessor-space\ 46 | --swallow-optional-blank-lines\ 47 | --blank-lines-after-declarations\ 48 | --blank-lines-after-procedures" 49 | 50 | function version { 51 | echo "$@" | awk -F. '{ printf("%d%03d%03d\n", $1,$2,$3); }'; 52 | } 53 | 54 | ASTYLE_VERSION=$(astyle --version 2>&1) 55 | 56 | VERSION=$(echo ${ASTYLE_VERSION##* }) 57 | 58 | if [ $(version $VERSION) -eq 0 ]; then 59 | echo "Kurento git pre-commit hook:" 60 | echo "Did not find astyle, please install it before continuing." 61 | exit 1 62 | fi 63 | 64 | ASTYLE_PARAMS="--style=linux\ 65 | --indent=spaces=2\ 66 | --indent-preprocessor\ 67 | --min-conditional-indent=2\ 68 | --break-blocks\ 69 | --pad-oper\ 70 | --pad-paren-out\ 71 | --convert-tabs\ 72 | --align-pointer=name\ 73 | --lineend=linux\ 74 | --break-blocks\ 75 | --max-code-length=80\ 76 | --add-brackets" 77 | 78 | if [ $(version $VERSION) -ge $(version "2.02") ]; then 79 | ASTYLE_PARAMS="$ASTYLE_PARAMS --align-reference=name" 80 | fi 81 | 82 | echo "--Checking style--" 83 | for file in `git diff-index --cached --name-only HEAD --diff-filter=ACMR| grep "\.\(c\(pp\)\?\|\(hpp\)\)$"` ; do 84 | # nf is the temporary checkout. This makes sure we check against the 85 | # revision in the index (and not the checked out version). 86 | nf=`git checkout-index --temp ${file} | cut -f 1` 87 | newfile=`mktemp /tmp/${nf}.XXXXXX` || exit 1 88 | if [ "$(echo "$file" | grep -e "\.\(\(cpp\)\|\(hpp\)\)$")" ]; then 89 | astyle ${ASTYLE_PARAMS} < ${nf} > ${newfile} 2>> /dev/null 90 | FIX_COMMAND="astyle ${ASTYLE_PARAMS} $file" 91 | else 92 | $INDENT ${INDENT_PARAMETERS} \ 93 | $nf -o $newfile 2>> /dev/null 94 | # FIXME: Call indent twice as it tends to do line-breaks 95 | # different for every second call. 96 | $INDENT ${INDENT_PARAMETERS} \ 97 | $newfile 2>> /dev/null 98 | 99 | FIX_COMMAND="$INDENT ${INDENT_PARAMETERS} $file" 100 | fi 101 | a=$(<${newfile}) 102 | printf '%s\n' "$a" > ${newfile} 103 | diff -u -p "${nf}" "${newfile}" 104 | r=$? 105 | rm "${newfile}" 106 | rm "${nf}" 107 | if [ $r != 0 ] ; then 108 | echo "=================================================================================================" 109 | echo " Code style error in: $file " 110 | echo " " 111 | echo " Please fix before committing. Don't forget to run git add before trying to commit again. " 112 | echo " If the whole file is to be committed, this should work (run from the top-level directory): " 113 | echo " " 114 | echo " $FIX_COMMAND" 115 | echo " " 116 | echo "=================================================================================================" 117 | exit 1 118 | fi 119 | done 120 | echo "--Checking style pass--" 121 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(server) 2 | add_subdirectory(gst-plugins) 3 | -------------------------------------------------------------------------------- /src/gst-plugins/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(facedetector) 2 | add_subdirectory(faceoverlay) 3 | add_subdirectory(imageoverlay) 4 | add_subdirectory(movementdetector) 5 | add_subdirectory(opencvfilter) 6 | add_subdirectory(logooverlay) 7 | -------------------------------------------------------------------------------- /src/gst-plugins/facedetector/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(FACEDETECTOR_SOURCES 2 | facedetector.c 3 | kmsfacedetector.c kmsfacedetector.h 4 | classifier.h classifier.cpp 5 | ) 6 | 7 | add_library(facedetector MODULE ${FACEDETECTOR_SOURCES}) 8 | if(SANITIZERS_ENABLED) 9 | add_sanitizers(facedetector) 10 | endif() 11 | 12 | target_link_libraries(facedetector 13 | ${gstreamer-1.5_LIBRARIES} 14 | ${gstreamer-video-1.5_LIBRARIES} 15 | ${opencv_LIBRARIES} 16 | ${SOUP_LIBRARIES} 17 | ) 18 | 19 | set_property(TARGET facedetector 20 | PROPERTY INCLUDE_DIRECTORIES 21 | ${CMAKE_CURRENT_BINARY_DIR}/../../.. 22 | ${gstreamer-1.5_INCLUDE_DIRS} 23 | ${opencv_INCLUDE_DIRS} 24 | ) 25 | 26 | install( 27 | TARGETS facedetector 28 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 29 | LIBRARY DESTINATION ${CMAKE_INSTALL_GST_PLUGINS_DIR} 30 | ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} 31 | ) 32 | -------------------------------------------------------------------------------- /src/gst-plugins/facedetector/classifier.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright 2013 Kurento (http://kurento.org/) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | #include "classifier.h" 19 | 20 | #define FACE_CASCADE "/usr/share/opencv/lbpcascades/lbpcascade_frontalface.xml" 21 | 22 | #include 23 | #include 24 | 25 | using namespace cv; 26 | class Classifier 27 | { 28 | public: 29 | Classifier (); 30 | ~Classifier() = default; 31 | 32 | CascadeClassifier face_cascade; 33 | }; 34 | 35 | Classifier::Classifier() 36 | { 37 | face_cascade.load ( FACE_CASCADE ); 38 | } 39 | 40 | static Classifier lbpClassifier = Classifier (); 41 | 42 | void classify_image (IplImage *img, CvSeq *facesList) 43 | { 44 | std::vector faces; 45 | Mat frame (cv::cvarrToMat(img)); 46 | Mat frame_gray; 47 | 48 | cvtColor ( frame, frame_gray, COLOR_BGR2GRAY ); 49 | equalizeHist ( frame_gray, frame_gray ); 50 | 51 | lbpClassifier.face_cascade.detectMultiScale ( frame_gray, faces, 1.2, 3, 0, 52 | Size (frame.cols / 20, frame.rows / 20), 53 | Size (frame.cols / 2, frame.rows / 2) ); 54 | 55 | for (auto &face : faces) { 56 | CvRect aux = cvRect(face.x, face.y, face.width, face.height); 57 | cvSeqPush (facesList, &aux); 58 | } 59 | 60 | faces.clear(); 61 | } 62 | -------------------------------------------------------------------------------- /src/gst-plugins/facedetector/classifier.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright 2013 Kurento (http://kurento.org/) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | #ifndef __CLASSIFIER_H__ 19 | #define __CLASSIFIER_H__ 20 | 21 | #include 22 | 23 | #include 24 | 25 | G_BEGIN_DECLS 26 | 27 | void classify_image (IplImage* img, CvSeq* facesList); 28 | 29 | G_END_DECLS 30 | 31 | #endif /* __CLASSIFIER_H__ */ 32 | -------------------------------------------------------------------------------- /src/gst-plugins/facedetector/facedetector.c: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright 2013 Kurento (http://kurento.org/) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | #include 18 | #include 19 | 20 | #include "kmsfacedetector.h" 21 | 22 | static gboolean 23 | init (GstPlugin * plugin) 24 | { 25 | if (!kms_face_detector_plugin_init (plugin)) 26 | return FALSE; 27 | 28 | return TRUE; 29 | } 30 | 31 | GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, 32 | GST_VERSION_MINOR, 33 | kmsfacedetector, 34 | "Kurento facedetector filter", 35 | init, VERSION, GST_LICENSE_UNKNOWN, "Kurento", "https://kurento.openvidu.io/") 36 | -------------------------------------------------------------------------------- /src/gst-plugins/facedetector/kmsfacedetector.c: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright 2013 Kurento (http://kurento.org/) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | #ifdef HAVE_CONFIG_H 18 | #include "config.h" 19 | #endif 20 | 21 | #include "kmsfacedetector.h" 22 | #include "classifier.h" 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | 30 | #define GREEN CV_RGB (0, 255, 0) 31 | 32 | #define PLUGIN_NAME "facedetector" 33 | 34 | #define HAAR_CASCADES_DIR_OPENCV_PREFIX "/usr/share/opencv/haarcascades/" 35 | 36 | #define FACE_HAAR_FILE "haarcascade_frontalface_default.xml" 37 | 38 | #define MIN_FPS 5 39 | #define MIN_TIME ((float)(1.0/7.0)) 40 | 41 | #define MAX_WIDTH 320 42 | 43 | GST_DEBUG_CATEGORY_STATIC (kms_face_detector_debug_category); 44 | #define GST_CAT_DEFAULT kms_face_detector_debug_category 45 | 46 | #define KMS_FACE_DETECTOR_GET_PRIVATE(obj) ( \ 47 | G_TYPE_INSTANCE_GET_PRIVATE ( \ 48 | (obj), \ 49 | KMS_TYPE_FACE_DETECTOR, \ 50 | KmsFaceDetectorPrivate \ 51 | ) \ 52 | ) 53 | 54 | struct _KmsFaceDetectorPrivate 55 | { 56 | IplImage *cvImage; 57 | IplImage *cvResizedImage; 58 | gdouble resize_factor; 59 | 60 | gboolean show_debug_info; 61 | const char *images_path; 62 | gint throw_frames; 63 | gboolean qos_control; 64 | gboolean haar_detector; 65 | GMutex mutex; 66 | 67 | CvHaarClassifierCascade *pCascadeFace; 68 | CvMemStorage *pStorageFace; 69 | CvSeq *pFaceRectSeq; 70 | }; 71 | 72 | enum 73 | { 74 | PROP_0, 75 | PROP_SHOW_DEBUG_INFO, 76 | PROP_FILTER_VERSION 77 | }; 78 | 79 | /* pad templates */ 80 | 81 | #define VIDEO_SRC_CAPS \ 82 | GST_VIDEO_CAPS_MAKE("{ BGR }") 83 | 84 | #define VIDEO_SINK_CAPS \ 85 | GST_VIDEO_CAPS_MAKE("{ BGR }") 86 | 87 | /* class initialization */ 88 | 89 | G_DEFINE_TYPE_WITH_CODE (KmsFaceDetector, kms_face_detector, 90 | GST_TYPE_VIDEO_FILTER, 91 | GST_DEBUG_CATEGORY_INIT (kms_face_detector_debug_category, PLUGIN_NAME, 92 | 0, "debug category for facedetector element")); 93 | 94 | static void 95 | kms_face_detector_initialize_classifiers (KmsFaceDetector * facedetector) 96 | { 97 | GST_DEBUG ("Loading classifier: %s", 98 | HAAR_CASCADES_DIR_OPENCV_PREFIX FACE_HAAR_FILE); 99 | 100 | facedetector->priv->pCascadeFace = (CvHaarClassifierCascade *) 101 | cvLoad ((HAAR_CASCADES_DIR_OPENCV_PREFIX FACE_HAAR_FILE), 0, 0, 0); 102 | 103 | if (facedetector->priv->pCascadeFace == NULL) { 104 | GST_ERROR ("Failed loading classifier: %s", 105 | HAAR_CASCADES_DIR_OPENCV_PREFIX FACE_HAAR_FILE); 106 | } 107 | } 108 | 109 | static void 110 | kms_face_detector_set_property (GObject * object, guint property_id, 111 | const GValue * value, GParamSpec * pspec) 112 | { 113 | KmsFaceDetector *facedetector = KMS_FACE_DETECTOR (object); 114 | 115 | switch (property_id) { 116 | case PROP_SHOW_DEBUG_INFO: 117 | facedetector->priv->show_debug_info = g_value_get_boolean (value); 118 | break; 119 | case PROP_FILTER_VERSION: 120 | facedetector->priv->haar_detector = g_value_get_boolean (value); 121 | break; 122 | default: 123 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); 124 | break; 125 | } 126 | } 127 | 128 | static void 129 | kms_face_detector_get_property (GObject * object, guint property_id, 130 | GValue * value, GParamSpec * pspec) 131 | { 132 | KmsFaceDetector *facedetector = KMS_FACE_DETECTOR (object); 133 | 134 | switch (property_id) { 135 | case PROP_SHOW_DEBUG_INFO: 136 | g_value_set_boolean (value, facedetector->priv->show_debug_info); 137 | break; 138 | case PROP_FILTER_VERSION: 139 | g_value_set_boolean (value, facedetector->priv->haar_detector); 140 | break; 141 | default: 142 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); 143 | break; 144 | } 145 | } 146 | 147 | static void 148 | kms_face_detector_initialize_images (KmsFaceDetector * facedetector, 149 | GstVideoFrame * frame) 150 | { 151 | if (facedetector->priv->cvImage == NULL) { 152 | int target_width = 153 | frame->info.width <= MAX_WIDTH ? frame->info.width : MAX_WIDTH; 154 | 155 | facedetector->priv->resize_factor = frame->info.width / target_width; 156 | 157 | facedetector->priv->cvImage = 158 | cvCreateImageHeader (cvSize (frame->info.width, frame->info.height), 159 | IPL_DEPTH_8U, 3); 160 | 161 | facedetector->priv->cvResizedImage = 162 | cvCreateImage (cvSize (target_width, 163 | frame->info.height / facedetector->priv->resize_factor), 164 | IPL_DEPTH_8U, 3); 165 | } else if ((facedetector->priv->cvImage->width != frame->info.width) 166 | || (facedetector->priv->cvImage->height != frame->info.height)) { 167 | int target_width = 168 | frame->info.width <= MAX_WIDTH ? frame->info.width : MAX_WIDTH; 169 | 170 | facedetector->priv->resize_factor = frame->info.width / target_width; 171 | 172 | cvReleaseImageHeader (&facedetector->priv->cvImage); 173 | cvReleaseImage (&facedetector->priv->cvResizedImage); 174 | 175 | facedetector->priv->cvImage = 176 | cvCreateImageHeader (cvSize (frame->info.width, frame->info.height), 177 | IPL_DEPTH_8U, 3); 178 | 179 | facedetector->priv->cvResizedImage = 180 | cvCreateImage (cvSize (target_width, 181 | frame->info.height / facedetector->priv->resize_factor), 182 | IPL_DEPTH_8U, 3); 183 | } 184 | } 185 | 186 | static void 187 | kms_face_detector_send_event (KmsFaceDetector * facedetector, 188 | GstVideoFrame * frame) 189 | { 190 | GstStructure *faces; 191 | GstStructure *timestamp; 192 | GstEvent *e; 193 | gint i; 194 | 195 | faces = gst_structure_new_empty ("faces"); 196 | 197 | timestamp = gst_structure_new ("time", 198 | "pts", G_TYPE_UINT64, GST_BUFFER_PTS (frame->buffer), 199 | "dts", G_TYPE_UINT64, GST_BUFFER_DTS (frame->buffer), NULL); 200 | gst_structure_set (faces, "timestamp", GST_TYPE_STRUCTURE, timestamp, NULL); 201 | gst_structure_free (timestamp); 202 | 203 | for (i = 0; 204 | i < 205 | (facedetector->priv->pFaceRectSeq ? facedetector->priv-> 206 | pFaceRectSeq->total : 0); i++) { 207 | CvRect *r; 208 | GstStructure *face; 209 | gchar *id = NULL; 210 | 211 | r = (CvRect *) cvGetSeqElem (facedetector->priv->pFaceRectSeq, i); 212 | face = gst_structure_new ("face", 213 | "x", G_TYPE_UINT, (guint) (r->x * facedetector->priv->resize_factor), 214 | "y", G_TYPE_UINT, (guint) (r->y * facedetector->priv->resize_factor), 215 | "width", G_TYPE_UINT, 216 | (guint) (r->width * facedetector->priv->resize_factor), "height", 217 | G_TYPE_UINT, (guint) (r->height * facedetector->priv->resize_factor), 218 | NULL); 219 | 220 | id = g_strdup_printf ("%d", i); 221 | gst_structure_set (faces, id, GST_TYPE_STRUCTURE, face, NULL); 222 | gst_structure_free (face); 223 | g_free (id); 224 | } 225 | 226 | /* post a faces detected event to src pad */ 227 | e = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, faces); 228 | gst_pad_push_event (facedetector->base.element.srcpad, e); 229 | } 230 | 231 | static GstFlowReturn 232 | kms_face_detector_transform_frame_ip (GstVideoFilter * filter, 233 | GstVideoFrame * frame) 234 | { 235 | KmsFaceDetector *facedetector = KMS_FACE_DETECTOR (filter); 236 | GstMapInfo info; 237 | 238 | if ((facedetector->priv->haar_detector) 239 | && (facedetector->priv->pCascadeFace == NULL)) { 240 | return GST_FLOW_OK; 241 | } 242 | 243 | kms_face_detector_initialize_images (facedetector, frame); 244 | gst_buffer_map (frame->buffer, &info, GST_MAP_READ); 245 | 246 | facedetector->priv->cvImage->imageData = (char *) info.data; 247 | cvResize (facedetector->priv->cvImage, facedetector->priv->cvResizedImage, 248 | CV_INTER_LINEAR); 249 | 250 | g_mutex_lock (&facedetector->priv->mutex); 251 | 252 | if (facedetector->priv->qos_control) { 253 | facedetector->priv->throw_frames++; 254 | GST_DEBUG ("Filter is too slow. Frame dropped %d", 255 | facedetector->priv->throw_frames); 256 | g_mutex_unlock (&facedetector->priv->mutex); 257 | goto send; 258 | } 259 | 260 | g_mutex_unlock (&facedetector->priv->mutex); 261 | 262 | cvClearSeq (facedetector->priv->pFaceRectSeq); 263 | cvClearMemStorage (facedetector->priv->pStorageFace); 264 | if (facedetector->priv->haar_detector) { 265 | facedetector->priv->pFaceRectSeq = 266 | cvHaarDetectObjects (facedetector->priv->cvResizedImage, 267 | facedetector->priv->pCascadeFace, facedetector->priv->pStorageFace, 1.2, 268 | 3, CV_HAAR_DO_CANNY_PRUNING, 269 | cvSize (facedetector->priv->cvResizedImage->width / 20, 270 | facedetector->priv->cvResizedImage->height / 20), 271 | cvSize (facedetector->priv->cvResizedImage->width / 2, 272 | facedetector->priv->cvResizedImage->height / 2)); 273 | 274 | } else { 275 | classify_image (facedetector->priv->cvResizedImage, 276 | facedetector->priv->pFaceRectSeq); 277 | } 278 | 279 | send: 280 | if (facedetector->priv->pFaceRectSeq->total != 0) { 281 | kms_face_detector_send_event (facedetector, frame); 282 | } 283 | 284 | gst_buffer_unmap (frame->buffer, &info); 285 | 286 | return GST_FLOW_OK; 287 | } 288 | 289 | static void 290 | kms_face_detector_finalize (GObject * object) 291 | { 292 | KmsFaceDetector *facedetector = KMS_FACE_DETECTOR (object); 293 | 294 | cvReleaseImageHeader (&facedetector->priv->cvImage); 295 | cvReleaseImage (&facedetector->priv->cvResizedImage); 296 | 297 | if (facedetector->priv->pStorageFace != NULL) 298 | cvClearMemStorage (facedetector->priv->pStorageFace); 299 | if (facedetector->priv->pFaceRectSeq != NULL) 300 | cvClearSeq (facedetector->priv->pFaceRectSeq); 301 | 302 | cvReleaseMemStorage (&facedetector->priv->pStorageFace); 303 | cvReleaseHaarClassifierCascade (&facedetector->priv->pCascadeFace); 304 | 305 | g_mutex_clear (&facedetector->priv->mutex); 306 | 307 | G_OBJECT_CLASS (kms_face_detector_parent_class)->finalize (object); 308 | } 309 | 310 | static void 311 | kms_face_detector_init (KmsFaceDetector * facedetector) 312 | { 313 | facedetector->priv = KMS_FACE_DETECTOR_GET_PRIVATE (facedetector); 314 | 315 | facedetector->priv->pCascadeFace = NULL; 316 | facedetector->priv->pStorageFace = cvCreateMemStorage (0); 317 | facedetector->priv->pFaceRectSeq = 318 | cvCreateSeq (0, sizeof (CvSeq), sizeof (CvRect), 319 | facedetector->priv->pStorageFace); 320 | facedetector->priv->show_debug_info = FALSE; 321 | facedetector->priv->qos_control = FALSE; 322 | facedetector->priv->throw_frames = 0; 323 | facedetector->priv->haar_detector = TRUE; 324 | facedetector->priv->cvImage = NULL; 325 | facedetector->priv->cvResizedImage = NULL; 326 | g_mutex_init (&facedetector->priv->mutex); 327 | 328 | kms_face_detector_initialize_classifiers (facedetector); 329 | } 330 | 331 | static gboolean 332 | kms_face_detector_src_eventfunc (GstBaseTransform * trans, GstEvent * event) 333 | { 334 | KmsFaceDetector *facedetector = KMS_FACE_DETECTOR (trans); 335 | 336 | switch (GST_EVENT_TYPE (event)) { 337 | case GST_EVENT_QOS: 338 | { 339 | gdouble proportion; 340 | GstClockTimeDiff diff; 341 | GstClockTime timestamp; 342 | GstQOSType type; 343 | gfloat difference; 344 | 345 | gst_event_parse_qos (event, &type, &proportion, &diff, ×tamp); 346 | gst_base_transform_update_qos (trans, proportion, diff, timestamp); 347 | difference = (((gfloat) (gint) diff) / (gfloat) GST_SECOND); 348 | 349 | g_mutex_lock (&facedetector->priv->mutex); 350 | 351 | if (difference > MIN_TIME) { 352 | if (facedetector->priv->throw_frames <= MIN_FPS) { 353 | facedetector->priv->qos_control = TRUE; 354 | } else { 355 | facedetector->priv->qos_control = FALSE; 356 | facedetector->priv->throw_frames = 0; 357 | } 358 | } else { 359 | facedetector->priv->qos_control = FALSE; 360 | facedetector->priv->throw_frames = 0; 361 | } 362 | 363 | g_mutex_unlock (&facedetector->priv->mutex); 364 | 365 | break; 366 | } 367 | default: 368 | break; 369 | } 370 | 371 | return gst_pad_push_event (trans->sinkpad, event); 372 | } 373 | 374 | static void 375 | kms_face_detector_class_init (KmsFaceDetectorClass * klass) 376 | { 377 | GObjectClass *gobject_class = G_OBJECT_CLASS (klass); 378 | GstVideoFilterClass *video_filter_class = GST_VIDEO_FILTER_CLASS (klass); 379 | 380 | GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, PLUGIN_NAME, 0, PLUGIN_NAME); 381 | 382 | /* Setting up pads and setting metadata should be moved to 383 | base_class_init if you intend to subclass this class. */ 384 | gst_element_class_add_pad_template (GST_ELEMENT_CLASS (klass), 385 | gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, 386 | gst_caps_from_string (VIDEO_SRC_CAPS))); 387 | gst_element_class_add_pad_template (GST_ELEMENT_CLASS (klass), 388 | gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, 389 | gst_caps_from_string (VIDEO_SINK_CAPS))); 390 | 391 | gst_element_class_set_static_metadata (GST_ELEMENT_CLASS (klass), 392 | "Face Detector element", "Video/Filter", 393 | "Detect faces in an image", "David Fernandez "); 394 | 395 | gobject_class->set_property = kms_face_detector_set_property; 396 | gobject_class->get_property = kms_face_detector_get_property; 397 | gobject_class->finalize = kms_face_detector_finalize; 398 | 399 | video_filter_class->transform_frame_ip = 400 | GST_DEBUG_FUNCPTR (kms_face_detector_transform_frame_ip); 401 | 402 | /* Properties initialization */ 403 | g_object_class_install_property (gobject_class, PROP_SHOW_DEBUG_INFO, 404 | g_param_spec_boolean ("show-debug-region", "show debug region", 405 | "show evaluation regions over the image", FALSE, G_PARAM_READWRITE)); 406 | 407 | g_object_class_install_property (gobject_class, PROP_FILTER_VERSION, 408 | g_param_spec_boolean ("filter-version", "filter version", 409 | "True means filter based on haar detector. False filter based on lbp", 410 | TRUE, G_PARAM_READWRITE)); 411 | 412 | klass->base_facedetector_class.parent_class.src_event = 413 | GST_DEBUG_FUNCPTR (kms_face_detector_src_eventfunc); 414 | 415 | g_type_class_add_private (klass, sizeof (KmsFaceDetectorPrivate)); 416 | } 417 | 418 | gboolean 419 | kms_face_detector_plugin_init (GstPlugin * plugin) 420 | { 421 | return gst_element_register (plugin, PLUGIN_NAME, GST_RANK_NONE, 422 | KMS_TYPE_FACE_DETECTOR); 423 | } 424 | -------------------------------------------------------------------------------- /src/gst-plugins/facedetector/kmsfacedetector.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright 2013 Kurento (http://kurento.org/) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | #ifndef _KMS_FACE_DETECTOR_H_ 19 | #define _KMS_FACE_DETECTOR_H_ 20 | 21 | #include "opencv2/core/version.hpp" 22 | #if CV_MAJOR_VERSION == 3 23 | #include 24 | #endif 25 | #include 26 | #include 27 | 28 | G_BEGIN_DECLS 29 | 30 | #define KMS_TYPE_FACE_DETECTOR (kms_face_detector_get_type()) 31 | #define KMS_FACE_DETECTOR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),KMS_TYPE_FACE_DETECTOR,KmsFaceDetector)) 32 | #define KMS_FACE_DETECTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),KMS_TYPE_FACE_DETECTOR,KmsFaceDetectorClass)) 33 | #define KMS_IS_FACE_DETECTOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),KMS_TYPE_FACE_DETECTOR)) 34 | #define KMS_IS_FACE_DETECTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),KMS_TYPE_FACE_DETECTOR)) 35 | 36 | typedef struct _KmsFaceDetector KmsFaceDetector; 37 | typedef struct _KmsFaceDetectorClass KmsFaceDetectorClass; 38 | typedef struct _KmsFaceDetectorPrivate KmsFaceDetectorPrivate; 39 | 40 | struct _KmsFaceDetector 41 | { 42 | GstVideoFilter base; 43 | 44 | KmsFaceDetectorPrivate *priv; 45 | }; 46 | 47 | struct _KmsFaceDetectorClass 48 | { 49 | GstVideoFilterClass base_facedetector_class; 50 | }; 51 | 52 | GType kms_face_detector_get_type (void); 53 | 54 | gboolean kms_face_detector_plugin_init (GstPlugin * plugin); 55 | 56 | G_END_DECLS 57 | 58 | #endif /* _KMS_FACE_DETECTOR_H_ */ 59 | -------------------------------------------------------------------------------- /src/gst-plugins/faceoverlay/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(FACEOVERLAY_SOURCES 2 | faceoverlay.c 3 | kmsfaceoverlay.c kmsfaceoverlay.h 4 | ) 5 | 6 | add_library(faceoverlay MODULE ${FACEOVERLAY_SOURCES}) 7 | if(SANITIZERS_ENABLED) 8 | add_sanitizers(faceoverlay) 9 | endif() 10 | 11 | add_dependencies(faceoverlay imageoverlay facedetector) 12 | 13 | target_link_libraries(faceoverlay 14 | ${gstreamer-1.5_LIBRARIES} 15 | ${gstreamer-video-1.5_LIBRARIES} 16 | ${opencv_LIBRARIES} 17 | ) 18 | 19 | set_property(TARGET faceoverlay 20 | PROPERTY INCLUDE_DIRECTORIES 21 | ${CMAKE_CURRENT_BINARY_DIR}/../../.. 22 | ${gstreamer-1.5_INCLUDE_DIRS} 23 | ${opencv_INCLUDE_DIRS} 24 | ) 25 | 26 | install( 27 | TARGETS faceoverlay 28 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 29 | LIBRARY DESTINATION ${CMAKE_INSTALL_GST_PLUGINS_DIR} 30 | ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} 31 | ) 32 | -------------------------------------------------------------------------------- /src/gst-plugins/faceoverlay/faceoverlay.c: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright 2013 Kurento (http://kurento.org/) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | #include 18 | #include 19 | 20 | #include "kmsfaceoverlay.h" 21 | 22 | static gboolean 23 | init (GstPlugin * plugin) 24 | { 25 | if (!kms_face_overlay_plugin_init (plugin)) 26 | return FALSE; 27 | 28 | return TRUE; 29 | } 30 | 31 | GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, 32 | GST_VERSION_MINOR, 33 | kmsfaceoverlay, 34 | "Kurento faceoverlay filter", 35 | init, VERSION, GST_LICENSE_UNKNOWN, "Kurento", "https://kurento.openvidu.io/") 36 | -------------------------------------------------------------------------------- /src/gst-plugins/faceoverlay/kmsfaceoverlay.c: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright 2013 Kurento (http://kurento.org/) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | #ifdef HAVE_CONFIG_H 18 | #include "config.h" 19 | #endif 20 | 21 | #include "kmsfaceoverlay.h" 22 | 23 | #include 24 | 25 | #define PLUGIN_NAME "faceoverlay" 26 | 27 | GST_DEBUG_CATEGORY_STATIC (kms_face_overlay_debug_category); 28 | #define GST_CAT_DEFAULT kms_face_overlay_debug_category 29 | 30 | #define KMS_FACE_OVERLAY_GET_PRIVATE(obj) ( \ 31 | G_TYPE_INSTANCE_GET_PRIVATE ( \ 32 | (obj), \ 33 | KMS_TYPE_FACE_OVERLAY, \ 34 | KmsFaceOverlayPrivate \ 35 | ) \ 36 | ) 37 | 38 | enum 39 | { 40 | PROP_0, 41 | PROP_SHOW_DEBUG_INFO, 42 | PROP_IMAGE_TO_OVERLAY 43 | }; 44 | 45 | /* pad templates */ 46 | 47 | #define VIDEO_SRC_CAPS \ 48 | GST_VIDEO_CAPS_MAKE("{ BGR }") 49 | 50 | #define VIDEO_SINK_CAPS \ 51 | GST_VIDEO_CAPS_MAKE("{ BGR }") 52 | 53 | /* the capabilities of the inputs and outputs. */ 54 | static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", 55 | GST_PAD_SINK, 56 | GST_PAD_ALWAYS, 57 | GST_STATIC_CAPS (VIDEO_SRC_CAPS) 58 | ); 59 | 60 | static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src", 61 | GST_PAD_SRC, 62 | GST_PAD_REQUEST, 63 | GST_STATIC_CAPS (VIDEO_SRC_CAPS) 64 | ); 65 | 66 | struct _KmsFaceOverlayPrivate 67 | { 68 | GstElement *face_detector; 69 | GstElement *image_overlay; 70 | GstPad *src, *sink; 71 | }; 72 | 73 | /* class initialization */ 74 | 75 | G_DEFINE_TYPE_WITH_CODE (KmsFaceOverlay, kms_face_overlay, 76 | GST_TYPE_BIN, 77 | GST_DEBUG_CATEGORY_INIT (kms_face_overlay_debug_category, PLUGIN_NAME, 78 | 0, "debug category for faceoverlay element")); 79 | 80 | static void 81 | kms_face_overlay_set_property (GObject * object, guint property_id, 82 | const GValue * value, GParamSpec * pspec) 83 | { 84 | KmsFaceOverlay *faceoverlay = KMS_FACE_OVERLAY (object); 85 | 86 | faceoverlay->priv = KMS_FACE_OVERLAY_GET_PRIVATE (faceoverlay); 87 | 88 | switch (property_id) { 89 | case PROP_SHOW_DEBUG_INFO: 90 | faceoverlay->show_debug_info = g_value_get_boolean (value); 91 | break; 92 | case PROP_IMAGE_TO_OVERLAY: 93 | g_object_set (faceoverlay->priv->image_overlay, "image-to-overlay", 94 | g_value_get_boxed (value), NULL); 95 | break; 96 | default: 97 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); 98 | break; 99 | } 100 | } 101 | 102 | static void 103 | kms_face_overlay_get_property (GObject * object, guint property_id, 104 | GValue * value, GParamSpec * pspec) 105 | { 106 | KmsFaceOverlay *faceoverlay = KMS_FACE_OVERLAY (object); 107 | 108 | faceoverlay->priv = KMS_FACE_OVERLAY_GET_PRIVATE (faceoverlay); 109 | 110 | switch (property_id) { 111 | case PROP_SHOW_DEBUG_INFO: 112 | g_value_set_boolean (value, faceoverlay->show_debug_info); 113 | break; 114 | case PROP_IMAGE_TO_OVERLAY: 115 | { 116 | GstStructure *aux; 117 | 118 | g_object_get (G_OBJECT (faceoverlay->priv->image_overlay), 119 | "image-to-overlay", &aux, NULL); 120 | g_value_set_boxed (value, aux); 121 | gst_structure_free (aux); 122 | break; 123 | } 124 | default: 125 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); 126 | break; 127 | } 128 | } 129 | 130 | static void 131 | kms_face_overlay_init (KmsFaceOverlay * faceoverlay) 132 | { 133 | GstPadTemplate *templ; 134 | GstPad *target; 135 | 136 | faceoverlay->priv = KMS_FACE_OVERLAY_GET_PRIVATE (faceoverlay); 137 | 138 | faceoverlay->priv->face_detector = 139 | gst_element_factory_make ("facedetector", NULL); 140 | gst_bin_add (GST_BIN (faceoverlay), faceoverlay->priv->face_detector); 141 | 142 | faceoverlay->priv->image_overlay = 143 | gst_element_factory_make ("imageoverlay", NULL); 144 | gst_bin_add (GST_BIN (faceoverlay), faceoverlay->priv->image_overlay); 145 | 146 | target = 147 | gst_element_get_static_pad (faceoverlay->priv->face_detector, "sink"); 148 | templ = gst_static_pad_template_get (&sink_factory); 149 | faceoverlay->priv->sink = 150 | gst_ghost_pad_new_from_template ("sink", target, templ); 151 | g_object_unref (templ); 152 | g_object_unref (target); 153 | gst_element_add_pad (GST_ELEMENT (faceoverlay), faceoverlay->priv->sink); 154 | 155 | target = gst_element_get_static_pad (faceoverlay->priv->image_overlay, "src"); 156 | templ = gst_static_pad_template_get (&src_factory); 157 | faceoverlay->priv->src = 158 | gst_ghost_pad_new_from_template ("src", target, templ); 159 | g_object_unref (templ); 160 | g_object_unref (target); 161 | gst_element_add_pad (GST_ELEMENT (faceoverlay), faceoverlay->priv->src); 162 | 163 | gst_element_link (faceoverlay->priv->face_detector, 164 | faceoverlay->priv->image_overlay); 165 | } 166 | 167 | static void 168 | kms_face_overlay_class_init (KmsFaceOverlayClass * klass) 169 | { 170 | GObjectClass *gobject_class = G_OBJECT_CLASS (klass); 171 | 172 | GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, PLUGIN_NAME, 0, PLUGIN_NAME); 173 | 174 | /* Setting up pads and setting metadata should be moved to 175 | base_class_init if you intend to subclass this class. */ 176 | gst_element_class_add_pad_template (GST_ELEMENT_CLASS (klass), 177 | gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, 178 | gst_caps_from_string (VIDEO_SRC_CAPS))); 179 | gst_element_class_add_pad_template (GST_ELEMENT_CLASS (klass), 180 | gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, 181 | gst_caps_from_string (VIDEO_SINK_CAPS))); 182 | 183 | gst_element_class_set_static_metadata (GST_ELEMENT_CLASS (klass), 184 | "Face Overlay element", "Video/Filter", 185 | "Detect faces in an image", "David Fernandez "); 186 | 187 | gobject_class->set_property = kms_face_overlay_set_property; 188 | gobject_class->get_property = kms_face_overlay_get_property; 189 | 190 | /* Properties initialization */ 191 | g_object_class_install_property (gobject_class, PROP_SHOW_DEBUG_INFO, 192 | g_param_spec_boolean ("show-debug-region", "show debug region", 193 | "show evaluation regions over the image", FALSE, G_PARAM_READWRITE)); 194 | 195 | g_object_class_install_property (gobject_class, PROP_IMAGE_TO_OVERLAY, 196 | g_param_spec_boxed ("image-to-overlay", "image to overlay", 197 | "set the url of the image to overlay the faces", 198 | GST_TYPE_STRUCTURE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); 199 | 200 | g_type_class_add_private (klass, sizeof (KmsFaceOverlayPrivate)); 201 | } 202 | 203 | gboolean 204 | kms_face_overlay_plugin_init (GstPlugin * plugin) 205 | { 206 | return gst_element_register (plugin, PLUGIN_NAME, GST_RANK_NONE, 207 | KMS_TYPE_FACE_OVERLAY); 208 | } 209 | -------------------------------------------------------------------------------- /src/gst-plugins/faceoverlay/kmsfaceoverlay.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright 2013 Kurento (http://kurento.org/) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | #ifndef _KMS_FACE_OVERLAY_H_ 19 | #define _KMS_FACE_OVERLAY_H_ 20 | 21 | #include 22 | 23 | G_BEGIN_DECLS 24 | 25 | #define KMS_TYPE_FACE_OVERLAY (kms_face_overlay_get_type()) 26 | #define KMS_FACE_OVERLAY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),KMS_TYPE_FACE_OVERLAY,KmsFaceOverlay)) 27 | #define KMS_FACE_OVERLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),KMS_TYPE_FACE_OVERLAY,KmsFaceOverlayClass)) 28 | #define KMS_IS_FACE_OVERLAY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),KMS_TYPE_FACE_OVERLAY)) 29 | #define KMS_IS_FACE_OVERLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),KMS_TYPE_FACE_OVERLAY)) 30 | 31 | typedef struct _KmsFaceOverlay KmsFaceOverlay; 32 | typedef struct _KmsFaceOverlayClass KmsFaceOverlayClass; 33 | typedef struct _KmsFaceOverlayPrivate KmsFaceOverlayPrivate; 34 | 35 | struct _KmsFaceOverlay 36 | { 37 | GstBin parent; 38 | 39 | /*< private > */ 40 | KmsFaceOverlayPrivate *priv; 41 | 42 | gboolean show_debug_info; 43 | }; 44 | 45 | struct _KmsFaceOverlayClass 46 | { 47 | GstBinClass base_faceoverlay_class; 48 | }; 49 | 50 | GType kms_face_overlay_get_type (void); 51 | 52 | gboolean kms_face_overlay_plugin_init (GstPlugin * plugin); 53 | 54 | G_END_DECLS 55 | 56 | #endif /* _KMS_FACE_OVERLAY_H_ */ 57 | -------------------------------------------------------------------------------- /src/gst-plugins/imageoverlay/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(IMAGEOVERLAY_SOURCES 2 | imageoverlay.c 3 | kmsimageoverlay.c kmsimageoverlay.h 4 | ) 5 | 6 | add_library(imageoverlay MODULE ${IMAGEOVERLAY_SOURCES}) 7 | if(SANITIZERS_ENABLED) 8 | add_sanitizers(imageoverlay) 9 | endif() 10 | 11 | target_link_libraries(imageoverlay 12 | ${gstreamer-1.5_LIBRARIES} 13 | ${gstreamer-video-1.5_LIBRARIES} 14 | ${opencv_LIBRARIES} 15 | ${libsoup-2.4_LIBRARIES} 16 | ) 17 | 18 | set_property(TARGET imageoverlay 19 | PROPERTY INCLUDE_DIRECTORIES 20 | ${CMAKE_CURRENT_BINARY_DIR}/../../.. 21 | ${gstreamer-1.5_INCLUDE_DIRS} 22 | ${opencv_INCLUDE_DIRS} 23 | ${libsoup-2.4_INCLUDE_DIRS} 24 | ) 25 | 26 | install( 27 | TARGETS imageoverlay 28 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 29 | LIBRARY DESTINATION ${CMAKE_INSTALL_GST_PLUGINS_DIR} 30 | ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} 31 | ) 32 | -------------------------------------------------------------------------------- /src/gst-plugins/imageoverlay/imageoverlay.c: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright 2013 Kurento (http://kurento.org/) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | #include 18 | #include 19 | 20 | #include "kmsimageoverlay.h" 21 | 22 | static gboolean 23 | init (GstPlugin * plugin) 24 | { 25 | if (!kms_image_overlay_plugin_init (plugin)) 26 | return FALSE; 27 | 28 | return TRUE; 29 | } 30 | 31 | GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, 32 | GST_VERSION_MINOR, 33 | kmsimageoverlay, 34 | "Kurento imageoverlay filter", 35 | init, VERSION, GST_LICENSE_UNKNOWN, "Kurento", "https://kurento.openvidu.io/") 36 | -------------------------------------------------------------------------------- /src/gst-plugins/imageoverlay/kmsimageoverlay.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright 2013 Kurento (http://kurento.org/) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | #ifndef _KMS_IMAGE_OVERLAY_H_ 19 | #define _KMS_IMAGE_OVERLAY_H_ 20 | 21 | #include "opencv2/core/version.hpp" 22 | #if CV_MAJOR_VERSION == 3 23 | #include 24 | #endif 25 | #include 26 | 27 | G_BEGIN_DECLS 28 | 29 | #define KMS_TYPE_IMAGE_OVERLAY (kms_image_overlay_get_type()) 30 | #define KMS_IMAGE_OVERLAY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),KMS_TYPE_IMAGE_OVERLAY,KmsImageOverlay)) 31 | #define KMS_IMAGE_OVERLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),KMS_TYPE_IMAGE_OVERLAY,KmsImageOverlayClass)) 32 | #define KMS_IS_IMAGE_OVERLAY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),KMS_TYPE_IMAGE_OVERLAY)) 33 | #define KMS_IS_IMAGE_OVERLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),KMS_TYPE_IMAGE_OVERLAY)) 34 | 35 | typedef struct _KmsImageOverlay KmsImageOverlay; 36 | typedef struct _KmsImageOverlayClass KmsImageOverlayClass; 37 | typedef struct _KmsImageOverlayPrivate KmsImageOverlayPrivate; 38 | 39 | struct _KmsImageOverlay 40 | { 41 | GstVideoFilter base; 42 | KmsImageOverlayPrivate *priv; 43 | }; 44 | 45 | struct _KmsImageOverlayClass 46 | { 47 | GstVideoFilterClass base_facedetector_class; 48 | }; 49 | 50 | GType kms_image_overlay_get_type (void); 51 | 52 | gboolean kms_image_overlay_plugin_init (GstPlugin * plugin); 53 | 54 | G_END_DECLS 55 | 56 | #endif /* _KMS_IMAGE_OVERLAY_H_ */ 57 | -------------------------------------------------------------------------------- /src/gst-plugins/logooverlay/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(LOGOOVERLAY_SOURCES 2 | logooverlay.c 3 | kmslogooverlay.c kmslogooverlay.h 4 | ) 5 | 6 | add_library(logooverlay MODULE ${LOGOOVERLAY_SOURCES}) 7 | if(SANITIZERS_ENABLED) 8 | add_sanitizers(logooverlay) 9 | endif() 10 | 11 | target_link_libraries(logooverlay 12 | ${gstreamer-1.5_LIBRARIES} 13 | ${gstreamer-video-1.5_LIBRARIES} 14 | ${opencv_LIBRARIES} 15 | ${libsoup-2.4_LIBRARIES} 16 | ) 17 | 18 | set_property(TARGET logooverlay 19 | PROPERTY INCLUDE_DIRECTORIES 20 | ${CMAKE_CURRENT_BINARY_DIR}/../../.. 21 | ${gstreamer-1.5_INCLUDE_DIRS} 22 | ${opencv_INCLUDE_DIRS} 23 | ${libsoup-2.4_INCLUDE_DIRS} 24 | ) 25 | 26 | install( 27 | TARGETS logooverlay 28 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 29 | LIBRARY DESTINATION ${CMAKE_INSTALL_GST_PLUGINS_DIR} 30 | ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} 31 | ) 32 | -------------------------------------------------------------------------------- /src/gst-plugins/logooverlay/kmslogooverlay.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright 2013 Kurento (http://kurento.org/) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | #ifndef _KMS_LOGO_OVERLAY_H_ 19 | #define _KMS_LOGO_OVERLAY_H_ 20 | 21 | #include "opencv2/core/version.hpp" 22 | #if CV_MAJOR_VERSION == 3 23 | #include 24 | #endif 25 | #include 26 | 27 | G_BEGIN_DECLS 28 | 29 | #define KMS_TYPE_LOGO_OVERLAY (kms_logo_overlay_get_type()) 30 | #define KMS_LOGO_OVERLAY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),KMS_TYPE_LOGO_OVERLAY,KmsLogoOverlay)) 31 | #define KMS_LOGO_OVERLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),KMS_TYPE_LOGO_OVERLAY,KmsLogoOverlayClass)) 32 | #define KMS_IS_LOGO_OVERLAY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),KMS_TYPE_LOGO_OVERLAY)) 33 | #define KMS_IS_LOGO_OVERLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),KMS_TYPE_LOGO_OVERLAY)) 34 | 35 | typedef struct _KmsLogoOverlay KmsLogoOverlay; 36 | typedef struct _KmsLogoOverlayClass KmsLogoOverlayClass; 37 | typedef struct _KmsLogoOverlayPrivate KmsLogoOverlayPrivate; 38 | 39 | struct _KmsLogoOverlay 40 | { 41 | GstVideoFilter base; 42 | KmsLogoOverlayPrivate *priv; 43 | }; 44 | 45 | struct _KmsLogoOverlayClass 46 | { 47 | GstVideoFilterClass base_facedetector_class; 48 | }; 49 | 50 | GType kms_logo_overlay_get_type (void); 51 | 52 | gboolean kms_logo_overlay_plugin_init (GstPlugin * plugin); 53 | 54 | G_END_DECLS 55 | 56 | #endif /* _KMS_LOGO_OVERLAY_H_ */ 57 | -------------------------------------------------------------------------------- /src/gst-plugins/logooverlay/logooverlay.c: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright 2013 Kurento (http://kurento.org/) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | #include 18 | #include 19 | 20 | #include "kmslogooverlay.h" 21 | 22 | static gboolean 23 | init (GstPlugin * plugin) 24 | { 25 | if (!kms_logo_overlay_plugin_init (plugin)) 26 | return FALSE; 27 | 28 | return TRUE; 29 | } 30 | 31 | GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, 32 | GST_VERSION_MINOR, 33 | kmslogooverlay, 34 | "Kurento logooverlay filter", 35 | init, VERSION, GST_LICENSE_UNKNOWN, "Kurento", "https://kurento.openvidu.io/") 36 | -------------------------------------------------------------------------------- /src/gst-plugins/movementdetector/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(MOVEMENTDETECTOR_SOURCES 2 | movementdetector.c 3 | kmsmovementdetector.c kmsmovementdetector.h 4 | ) 5 | 6 | add_library(movementdetector MODULE ${MOVEMENTDETECTOR_SOURCES}) 7 | if(SANITIZERS_ENABLED) 8 | add_sanitizers(movementdetector) 9 | endif() 10 | 11 | target_link_libraries(movementdetector 12 | ${gstreamer-1.5_LIBRARIES} 13 | ${gstreamer-video-1.5_LIBRARIES} 14 | ${opencv_LIBRARIES} 15 | ) 16 | 17 | set_property(TARGET movementdetector 18 | PROPERTY INCLUDE_DIRECTORIES 19 | ${CMAKE_CURRENT_BINARY_DIR}/../../.. 20 | ${gstreamer-1.5_INCLUDE_DIRS} 21 | ${opencv_INCLUDE_DIRS} 22 | ) 23 | 24 | install( 25 | TARGETS movementdetector 26 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 27 | LIBRARY DESTINATION ${CMAKE_INSTALL_GST_PLUGINS_DIR} 28 | ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} 29 | ) 30 | -------------------------------------------------------------------------------- /src/gst-plugins/movementdetector/kmsmovementdetector.c: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright 2013 Kurento (http://kurento.org/) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | #ifdef HAVE_CONFIG_H 18 | #include "config.h" 19 | #endif 20 | 21 | #include 22 | #include 23 | #include 24 | #include "kmsmovementdetector.h" 25 | #include 26 | 27 | #define PLUGIN_NAME "movementdetector" 28 | 29 | GST_DEBUG_CATEGORY_STATIC (kms_movement_detector_debug_category); 30 | #define GST_CAT_DEFAULT kms_movement_detector_debug_category 31 | 32 | /* pad templates */ 33 | 34 | #define VIDEO_SRC_CAPS \ 35 | GST_VIDEO_CAPS_MAKE("{ BGR }") 36 | 37 | #define VIDEO_SINK_CAPS \ 38 | GST_VIDEO_CAPS_MAKE("{ BGR }") 39 | 40 | /* class initialization */ 41 | 42 | G_DEFINE_TYPE_WITH_CODE (KmsMovementDetector, kms_movement_detector, 43 | GST_TYPE_VIDEO_FILTER, 44 | GST_DEBUG_CATEGORY_INIT (kms_movement_detector_debug_category, PLUGIN_NAME, 45 | 0, "debug category for movementdetector element")); 46 | 47 | void 48 | kms_movement_detector_dispose (GObject * object) 49 | { 50 | KmsMovementDetector *movementdetector = KMS_MOVEMENT_DETECTOR (object); 51 | 52 | GST_DEBUG_OBJECT (movementdetector, "dispose"); 53 | 54 | /* clean up as possible. may be called multiple times */ 55 | 56 | G_OBJECT_CLASS (kms_movement_detector_parent_class)->dispose (object); 57 | } 58 | 59 | void 60 | kms_movement_detector_finalize (GObject * object) 61 | { 62 | KmsMovementDetector *movementdetector = KMS_MOVEMENT_DETECTOR (object); 63 | 64 | GST_DEBUG_OBJECT (movementdetector, "finalize"); 65 | 66 | /* clean up object here */ 67 | if (movementdetector->img != NULL) { 68 | cvReleaseImage (&movementdetector->img); 69 | movementdetector->img = NULL; 70 | } 71 | if (movementdetector->imgOldBW != NULL) { 72 | cvReleaseImage (&movementdetector->imgOldBW); 73 | movementdetector->imgOldBW = NULL; 74 | } 75 | 76 | G_OBJECT_CLASS (kms_movement_detector_parent_class)->finalize (object); 77 | } 78 | 79 | static gboolean 80 | kms_movement_detector_start (GstBaseTransform * trans) 81 | { 82 | KmsMovementDetector *movementdetector = KMS_MOVEMENT_DETECTOR (trans); 83 | 84 | GST_DEBUG_OBJECT (movementdetector, "start"); 85 | 86 | return TRUE; 87 | } 88 | 89 | static gboolean 90 | kms_movement_detector_stop (GstBaseTransform * trans) 91 | { 92 | KmsMovementDetector *movementdetector = KMS_MOVEMENT_DETECTOR (trans); 93 | 94 | GST_DEBUG_OBJECT (movementdetector, "stop"); 95 | 96 | return TRUE; 97 | } 98 | 99 | static gboolean 100 | kms_movement_detector_set_info (GstVideoFilter * filter, GstCaps * incaps, 101 | GstVideoInfo * in_info, GstCaps * outcaps, GstVideoInfo * out_info) 102 | { 103 | KmsMovementDetector *movementdetector = KMS_MOVEMENT_DETECTOR (filter); 104 | 105 | GST_DEBUG_OBJECT (movementdetector, "set_info"); 106 | 107 | return TRUE; 108 | } 109 | 110 | static gboolean 111 | kms_movement_detector_initialize_images (KmsMovementDetector * movementdetector, 112 | GstVideoFrame * frame) 113 | { 114 | if (movementdetector->imgOldBW == NULL) { 115 | movementdetector->img = 116 | cvCreateImage (cvSize (frame->info.width, frame->info.height), 117 | IPL_DEPTH_8U, 3); 118 | return TRUE; 119 | } else if ((movementdetector->imgOldBW->width != frame->info.width) 120 | || (movementdetector->imgOldBW->height != frame->info.height)) { 121 | cvReleaseImage (&movementdetector->imgOldBW); 122 | movementdetector->img = 123 | cvCreateImage (cvSize (frame->info.width, frame->info.height), 124 | IPL_DEPTH_8U, 3); 125 | return TRUE; 126 | } 127 | 128 | return FALSE; 129 | } 130 | 131 | static GstFlowReturn 132 | kms_movement_detector_transform_frame_ip (GstVideoFilter * filter, 133 | GstVideoFrame * frame) 134 | { 135 | KmsMovementDetector *movementdetector = KMS_MOVEMENT_DETECTOR (filter); 136 | GstMapInfo info; 137 | IplImage *imgBW, *imgDiff; 138 | CvMemStorage *mem; 139 | CvSeq *contours = 0; 140 | gboolean imagesChanged; 141 | 142 | //checking image sizes 143 | imagesChanged = 144 | kms_movement_detector_initialize_images (movementdetector, frame); 145 | 146 | //get current frame 147 | gst_buffer_map (frame->buffer, &info, GST_MAP_READ); 148 | movementdetector->img->imageData = (char *) info.data; 149 | imgBW = cvCreateImage (cvGetSize (movementdetector->img), 150 | movementdetector->img->depth, 1); 151 | 152 | cvCvtColor (movementdetector->img, imgBW, CV_BGR2GRAY); 153 | if (imagesChanged) { 154 | movementdetector->imgOldBW = imgBW; 155 | goto end; 156 | } 157 | //image difference 158 | imgDiff = cvCreateImage (cvGetSize (movementdetector->img), 159 | movementdetector->img->depth, 1); 160 | 161 | cvSub (movementdetector->imgOldBW, imgBW, imgDiff, NULL); 162 | cvThreshold (imgDiff, imgDiff, 125, 255, CV_THRESH_OTSU); 163 | cvErode (imgDiff, imgDiff, NULL, 1); 164 | cvDilate (imgDiff, imgDiff, NULL, 1); 165 | 166 | mem = cvCreateMemStorage (0); 167 | cvFindContours (imgDiff, mem, &contours, sizeof (CvContour), CV_RETR_CCOMP, 168 | CV_CHAIN_APPROX_NONE, cvPoint (0, 0)); 169 | 170 | for (; contours != 0; contours = contours->h_next) { 171 | CvRect rect = cvBoundingRect (contours, 0); 172 | 173 | cvRectangle (movementdetector->img, cvPoint (rect.x, rect.y), 174 | cvPoint (rect.x + rect.width, rect.y + rect.width), cvScalar (255, 0, 0, 175 | 0), 2, 8, 0); 176 | 177 | } 178 | 179 | cvReleaseImage (&movementdetector->imgOldBW); 180 | movementdetector->imgOldBW = imgBW; 181 | 182 | cvReleaseImage (&imgDiff); 183 | cvReleaseMemStorage (&mem); 184 | 185 | end: 186 | gst_buffer_unmap (frame->buffer, &info); 187 | return GST_FLOW_OK; 188 | } 189 | 190 | static void 191 | kms_movement_detector_class_init (KmsMovementDetectorClass * klass) 192 | { 193 | GObjectClass *gobject_class = G_OBJECT_CLASS (klass); 194 | GstBaseTransformClass *base_transform_class = 195 | GST_BASE_TRANSFORM_CLASS (klass); 196 | GstVideoFilterClass *video_filter_class = GST_VIDEO_FILTER_CLASS (klass); 197 | 198 | /* Setting up pads and setting metadata should be moved to 199 | base_class_init if you intend to subclass this class. */ 200 | gst_element_class_add_pad_template (GST_ELEMENT_CLASS (klass), 201 | gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, 202 | gst_caps_from_string (VIDEO_SRC_CAPS))); 203 | gst_element_class_add_pad_template (GST_ELEMENT_CLASS (klass), 204 | gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, 205 | gst_caps_from_string (VIDEO_SINK_CAPS))); 206 | 207 | gst_element_class_set_static_metadata (GST_ELEMENT_CLASS (klass), 208 | "Movement detector element", "Video/Filter", 209 | "It detects movement of the objects and it raises events with its position", 210 | "David Fernandez "); 211 | 212 | gobject_class->dispose = kms_movement_detector_dispose; 213 | gobject_class->finalize = kms_movement_detector_finalize; 214 | base_transform_class->start = GST_DEBUG_FUNCPTR (kms_movement_detector_start); 215 | base_transform_class->stop = GST_DEBUG_FUNCPTR (kms_movement_detector_stop); 216 | video_filter_class->set_info = 217 | GST_DEBUG_FUNCPTR (kms_movement_detector_set_info); 218 | video_filter_class->transform_frame_ip = 219 | GST_DEBUG_FUNCPTR (kms_movement_detector_transform_frame_ip); 220 | } 221 | 222 | static void 223 | kms_movement_detector_init (KmsMovementDetector * movementdetector) 224 | { 225 | movementdetector->imgOldBW = NULL; 226 | movementdetector->img = NULL; 227 | } 228 | 229 | gboolean 230 | kms_movement_detector_plugin_init (GstPlugin * plugin) 231 | { 232 | return gst_element_register (plugin, PLUGIN_NAME, GST_RANK_NONE, 233 | KMS_TYPE_MOVEMENT_DETECTOR); 234 | } 235 | -------------------------------------------------------------------------------- /src/gst-plugins/movementdetector/kmsmovementdetector.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright 2013 Kurento (http://kurento.org/) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | #ifndef _KMS_MOVEMENT_DETECTOR_H_ 19 | #define _KMS_MOVEMENT_DETECTOR_H_ 20 | 21 | #include 22 | #include 23 | 24 | #include "opencv2/core/version.hpp" 25 | #if CV_MAJOR_VERSION == 3 26 | #include 27 | #endif 28 | #include 29 | #include 30 | 31 | G_BEGIN_DECLS 32 | #define KMS_TYPE_MOVEMENT_DETECTOR (kms_movement_detector_get_type()) 33 | #define KMS_MOVEMENT_DETECTOR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),KMS_TYPE_MOVEMENT_DETECTOR,KmsMovementDetector)) 34 | #define KMS_MOVEMENT_DETECTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),KMS_TYPE_MOVEMENT_DETECTOR,KmsMovementDetectorClass)) 35 | #define KMS_IS_MOVEMENT_DETECTOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),KMS_TYPE_MOVEMENT_DETECTOR)) 36 | #define KMS_IS_MOVEMENT_DETECTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),KMS_TYPE_MOVEMENT_DETECTOR)) 37 | typedef struct _KmsMovementDetector KmsMovementDetector; 38 | typedef struct _KmsMovementDetectorClass KmsMovementDetectorClass; 39 | 40 | struct _KmsMovementDetector { 41 | GstVideoFilter parent; 42 | IplImage* img; 43 | IplImage* imgOldBW; 44 | }; 45 | 46 | struct _KmsMovementDetectorClass { 47 | GstVideoFilterClass base_movementdetector_class; 48 | }; 49 | 50 | GType kms_movement_detector_get_type (void); 51 | 52 | gboolean kms_movement_detector_plugin_init (GstPlugin * plugin); 53 | 54 | G_END_DECLS 55 | #endif 56 | -------------------------------------------------------------------------------- /src/gst-plugins/movementdetector/movementdetector.c: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright 2013 Kurento (http://kurento.org/) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | #include 18 | #include 19 | 20 | #include "kmsmovementdetector.h" 21 | 22 | static gboolean 23 | init (GstPlugin * plugin) 24 | { 25 | if (!kms_movement_detector_plugin_init (plugin)) 26 | return FALSE; 27 | 28 | return TRUE; 29 | } 30 | 31 | GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, 32 | GST_VERSION_MINOR, 33 | kmsmovementdetector, 34 | "Kurento movement filter", 35 | init, VERSION, GST_LICENSE_UNKNOWN, "Kurento", "https://kurento.openvidu.io/") 36 | -------------------------------------------------------------------------------- /src/gst-plugins/opencvfilter/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(OPENCV_FILTER_SOURCES 2 | opencvfilter.c 3 | kmsopencvfilter.cpp kmsopencvfilter.h 4 | ) 5 | 6 | add_library(opencvfilter MODULE ${OPENCV_FILTER_SOURCES}) 7 | if(SANITIZERS_ENABLED) 8 | add_sanitizers(opencvfilter) 9 | endif() 10 | 11 | target_link_libraries(opencvfilter 12 | ${gstreamer-1.5_LIBRARIES} 13 | ${gstreamer-video-1.5_LIBRARIES} 14 | ${opencv_LIBRARIES} 15 | kmsfiltersimpl 16 | ) 17 | 18 | set_property(TARGET opencvfilter 19 | PROPERTY INCLUDE_DIRECTORIES 20 | ${CMAKE_CURRENT_BINARY_DIR}/../../.. 21 | ${CMAKE_CURRENT_SOURCE_DIR}/../../server/implementation/objects/ 22 | ${gstreamer-1.5_INCLUDE_DIRS} 23 | ${opencv_INCLUDE_DIRS} 24 | ${KMSCORE_INCLUDE_DIRS} 25 | ) 26 | 27 | install( 28 | TARGETS opencvfilter 29 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 30 | LIBRARY DESTINATION ${CMAKE_INSTALL_GST_PLUGINS_DIR} 31 | ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} 32 | ) 33 | -------------------------------------------------------------------------------- /src/gst-plugins/opencvfilter/kmsopencvfilter.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright 2014 Kurento (http://kurento.org/) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | #ifdef HAVE_CONFIG_H 19 | #include "config.h" 20 | #endif 21 | 22 | #include "kmsopencvfilter.h" 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include "OpenCVProcess.hpp" 31 | #include 32 | 33 | #define PLUGIN_NAME "opencvfilter" 34 | 35 | using namespace cv; 36 | 37 | #define KMS_OPENCV_FILTER_LOCK(opencv_filter) \ 38 | (g_rec_mutex_lock (&( (KmsOpenCVFilter *) (opencv_filter))->priv->mutex)) 39 | 40 | #define KMS_OPENCV_FILTER_UNLOCK(opencv_filter) \ 41 | (g_rec_mutex_unlock (&( (KmsOpenCVFilter *) (opencv_filter))->priv->mutex)) 42 | 43 | GST_DEBUG_CATEGORY_STATIC (kms_opencv_filter_debug_category); 44 | #define GST_CAT_DEFAULT kms_opencv_filter_debug_category 45 | 46 | #define KMS_OPENCV_FILTER_GET_PRIVATE(obj) ( \ 47 | G_TYPE_INSTANCE_GET_PRIVATE ( \ 48 | (obj), \ 49 | KMS_TYPE_OPENCV_FILTER, \ 50 | KmsOpenCVFilterPrivate \ 51 | ) \ 52 | ) 53 | 54 | enum { 55 | PROP_0, 56 | PROP_TARGET_OBJECT, 57 | N_PROPERTIES 58 | }; 59 | 60 | struct _KmsOpenCVFilterPrivate { 61 | GRecMutex mutex; 62 | Mat *cv_image; 63 | kurento::OpenCVProcess *object; 64 | }; 65 | 66 | /* pad templates */ 67 | 68 | #define VIDEO_SRC_CAPS \ 69 | GST_VIDEO_CAPS_MAKE("{ BGRA }") 70 | 71 | #define VIDEO_SINK_CAPS \ 72 | GST_VIDEO_CAPS_MAKE("{ BGRA }") 73 | 74 | /* class initialization */ 75 | 76 | G_DEFINE_TYPE_WITH_CODE (KmsOpenCVFilter, kms_opencv_filter, 77 | GST_TYPE_VIDEO_FILTER, 78 | GST_DEBUG_CATEGORY_INIT (kms_opencv_filter_debug_category, 79 | PLUGIN_NAME, 0, 80 | "debug category for opencv_filter element") ); 81 | 82 | static void 83 | kms_opencv_filter_set_property (GObject *object, guint property_id, 84 | const GValue *value, GParamSpec *pspec) 85 | { 86 | KmsOpenCVFilter *opencv_filter = KMS_OPENCV_FILTER (object); 87 | 88 | KMS_OPENCV_FILTER_LOCK (opencv_filter); 89 | 90 | switch (property_id) { 91 | case PROP_TARGET_OBJECT: 92 | try { 93 | opencv_filter->priv->object = dynamic_cast ( ( 94 | kurento::OpenCVProcess *) g_value_get_pointer (value) ); 95 | } catch (std::bad_cast &e) { 96 | opencv_filter->priv->object = nullptr; 97 | GST_ERROR ( "Object type not valid"); 98 | } 99 | 100 | break; 101 | 102 | default: 103 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); 104 | break; 105 | } 106 | 107 | KMS_OPENCV_FILTER_UNLOCK (opencv_filter); 108 | } 109 | 110 | static void 111 | kms_opencv_filter_get_property (GObject *object, guint property_id, 112 | GValue *value, GParamSpec *pspec) 113 | { 114 | KmsOpenCVFilter *opencv_filter = KMS_OPENCV_FILTER (object); 115 | 116 | KMS_OPENCV_FILTER_LOCK (opencv_filter); 117 | 118 | switch (property_id) { 119 | case PROP_TARGET_OBJECT: 120 | g_value_set_pointer (value, (gpointer) opencv_filter->priv->object); 121 | break; 122 | 123 | default: 124 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); 125 | break; 126 | } 127 | 128 | KMS_OPENCV_FILTER_UNLOCK (opencv_filter); 129 | } 130 | 131 | static void 132 | kms_opencv_filter_initialize_images (KmsOpenCVFilter *opencv_filter, 133 | GstVideoFrame *frame, GstMapInfo &info) 134 | { 135 | if (opencv_filter->priv->cv_image == nullptr) { 136 | 137 | opencv_filter->priv->cv_image = new Mat (frame->info.height, 138 | frame->info.width, CV_8UC4, info.data); 139 | 140 | } else if ( (opencv_filter->priv->cv_image->cols != frame->info.width) 141 | || (opencv_filter->priv->cv_image->rows != frame->info.height) ) { 142 | 143 | delete opencv_filter->priv->cv_image; 144 | 145 | opencv_filter->priv->cv_image = new Mat (frame->info.height, 146 | frame->info.width, CV_8UC4, info.data); 147 | 148 | } else { 149 | opencv_filter->priv->cv_image->data = info.data; 150 | } 151 | } 152 | 153 | static GstFlowReturn 154 | kms_opencv_filter_transform_frame_ip (GstVideoFilter *filter, 155 | GstVideoFrame *frame) 156 | { 157 | KmsOpenCVFilter *opencv_filter = KMS_OPENCV_FILTER (filter); 158 | GstMapInfo info{}; 159 | 160 | if (opencv_filter->priv->object == nullptr) { 161 | return GST_FLOW_OK; 162 | } 163 | 164 | gst_buffer_map (frame->buffer, &info, GST_MAP_READ); 165 | 166 | kms_opencv_filter_initialize_images (opencv_filter, frame, info); 167 | 168 | try { 169 | opencv_filter->priv->object->process (* (opencv_filter->priv->cv_image) ); 170 | } catch (kurento::KurentoException &e) { 171 | GstMessage *message; 172 | GError *err = g_error_new (g_quark_from_string (e.getType ().c_str () ), 173 | e.getCode (), "%s", GST_ELEMENT_NAME (opencv_filter) ); 174 | 175 | message = gst_message_new_error (GST_OBJECT (opencv_filter), 176 | err, e.getMessage ().c_str () ); 177 | 178 | gst_element_post_message (GST_ELEMENT (opencv_filter), 179 | message); 180 | 181 | g_clear_error (&err); 182 | } catch (...) { 183 | GstMessage *message; 184 | GError *err = g_error_new (g_quark_from_string ("UNDEFINED_EXCEPTION"), 185 | 0, "%s", GST_ELEMENT_NAME (opencv_filter) ); 186 | 187 | message = gst_message_new_error (GST_OBJECT (opencv_filter), 188 | err, "Undefined filter error"); 189 | 190 | gst_element_post_message (GST_ELEMENT (opencv_filter), 191 | message); 192 | 193 | g_clear_error (&err); 194 | } 195 | 196 | gst_buffer_unmap (frame->buffer, &info); 197 | return GST_FLOW_OK; 198 | } 199 | 200 | static void 201 | kms_opencv_filter_dispose (GObject *object) 202 | { 203 | } 204 | 205 | static void 206 | kms_opencv_filter_finalize (GObject *object) 207 | { 208 | KmsOpenCVFilter *opencv_filter = KMS_OPENCV_FILTER (object); 209 | 210 | if (opencv_filter->priv->cv_image != nullptr) { 211 | delete opencv_filter->priv->cv_image; 212 | } 213 | 214 | g_rec_mutex_clear (&opencv_filter->priv->mutex); 215 | } 216 | 217 | static void 218 | kms_opencv_filter_init (KmsOpenCVFilter * 219 | opencv_filter) 220 | { 221 | opencv_filter->priv = KMS_OPENCV_FILTER_GET_PRIVATE (opencv_filter); 222 | g_rec_mutex_init (&opencv_filter->priv->mutex); 223 | } 224 | 225 | static void 226 | kms_opencv_filter_class_init (KmsOpenCVFilterClass *klass) 227 | { 228 | GObjectClass *gobject_class = G_OBJECT_CLASS (klass); 229 | GstVideoFilterClass *video_filter_class = GST_VIDEO_FILTER_CLASS (klass); 230 | 231 | GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, PLUGIN_NAME, 0, PLUGIN_NAME); 232 | 233 | gst_element_class_add_pad_template (GST_ELEMENT_CLASS (klass), 234 | gst_pad_template_new ("src", GST_PAD_SRC, 235 | GST_PAD_ALWAYS, 236 | gst_caps_from_string (VIDEO_SRC_CAPS) ) ); 237 | gst_element_class_add_pad_template (GST_ELEMENT_CLASS (klass), 238 | gst_pad_template_new ("sink", GST_PAD_SINK, 239 | GST_PAD_ALWAYS, 240 | gst_caps_from_string (VIDEO_SINK_CAPS) ) ); 241 | 242 | gst_element_class_set_static_metadata (GST_ELEMENT_CLASS (klass), 243 | "generic opencv element", "Video/Filter", 244 | "Create a generic opencv filter to process images", 245 | "David Fernandez "); 246 | 247 | gobject_class->set_property = kms_opencv_filter_set_property; 248 | gobject_class->get_property = kms_opencv_filter_get_property; 249 | gobject_class->dispose = kms_opencv_filter_dispose; 250 | gobject_class->finalize = kms_opencv_filter_finalize; 251 | 252 | g_object_class_install_property (gobject_class, PROP_TARGET_OBJECT, 253 | g_param_spec_pointer ("target-object", "target object", 254 | "Reference to target object", 255 | (GParamFlags) G_PARAM_READWRITE) ); 256 | 257 | video_filter_class->transform_frame_ip = 258 | GST_DEBUG_FUNCPTR (kms_opencv_filter_transform_frame_ip); 259 | 260 | /* Properties initialization */ 261 | g_type_class_add_private (klass, sizeof (KmsOpenCVFilterPrivate) ); 262 | } 263 | 264 | gboolean 265 | kms_opencv_filter_plugin_init (GstPlugin *plugin) 266 | { 267 | return gst_element_register (plugin, PLUGIN_NAME, GST_RANK_NONE, 268 | KMS_TYPE_OPENCV_FILTER); 269 | } 270 | -------------------------------------------------------------------------------- /src/gst-plugins/opencvfilter/kmsopencvfilter.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright 2014 Kurento (http://kurento.org/) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | #ifndef _KMS_OPENCV_FILTER_H_ 19 | #define _KMS_OPENCV_FILTER_H_ 20 | 21 | #include 22 | 23 | G_BEGIN_DECLS 24 | #define KMS_TYPE_OPENCV_FILTER (kms_opencv_filter_get_type()) 25 | #define KMS_OPENCV_FILTER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),KMS_TYPE_OPENCV_FILTER,KmsOpenCVFilter)) 26 | #define KMS_OPENCV_FILTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),KMS_TYPE_OPENCV_FILTER,KmsOpenCVFilterClass)) 27 | #define KMS_IS_OPENCV_FILTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),KMS_TYPE_OPENCV_FILTER)) 28 | #define KMS_IS_OPENCV_FILTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),KMS_TYPE_OPENCV_FILTER)) 29 | typedef struct _KmsOpenCVFilter KmsOpenCVFilter; 30 | typedef struct _KmsOpenCVFilterClass KmsOpenCVFilterClass; 31 | typedef struct _KmsOpenCVFilterPrivate KmsOpenCVFilterPrivate; 32 | 33 | struct _KmsOpenCVFilter 34 | { 35 | GstVideoFilter base; 36 | KmsOpenCVFilterPrivate *priv; 37 | }; 38 | 39 | struct _KmsOpenCVFilterClass 40 | { 41 | GstVideoFilterClass base_opencv_filter_class; 42 | }; 43 | 44 | GType kms_opencv_filter_get_type (void); 45 | 46 | gboolean kms_opencv_filter_plugin_init (GstPlugin * plugin); 47 | 48 | G_END_DECLS 49 | #endif /* _KMS_OPENCV_FILTER_H_ */ 50 | -------------------------------------------------------------------------------- /src/gst-plugins/opencvfilter/opencvfilter.c: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright 2013 Kurento (http://kurento.org/) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | #ifdef HAVE_CONFIG_H 18 | #include "config.h" 19 | #endif 20 | 21 | #include 22 | 23 | #include "kmsopencvfilter.h" 24 | 25 | static gboolean 26 | init (GstPlugin * plugin) 27 | { 28 | if (!kms_opencv_filter_plugin_init (plugin)) 29 | return FALSE; 30 | 31 | return TRUE; 32 | } 33 | 34 | GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, 35 | GST_VERSION_MINOR, 36 | kmsopencvfilter, 37 | "Kurento generic opencv filter", 38 | init, VERSION, GST_LICENSE_UNKNOWN, "Kurento", "https://kurento.openvidu.io/") 39 | -------------------------------------------------------------------------------- /src/server/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8) 2 | 3 | set(KMS_FILTERS_IMPL_HEADERS 4 | implementation/objects/OpenCVProcess.hpp 5 | ) 6 | 7 | include(CodeGenerator) 8 | generate_code( 9 | MODELS ${CMAKE_CURRENT_SOURCE_DIR}/interface 10 | SERVER_IMPL_LIB_EXTRA_HEADERS ${KMS_FILTERS_IMPL_HEADERS} 11 | SERVER_IMPL_LIB_EXTRA_INCLUDE_DIRS ${opencv_INCLUDE_DIRS} 12 | SERVER_IMPL_LIB_EXTRA_LIBRARIES ${opencv_LIBRARIES} 13 | SERVER_STUB_DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/implementation/objects 14 | SERVER_IMPL_LIB_PKGCONFIG_EXTRA_REQUIRES "opencv" 15 | SERVER_IMPL_LIB_FIND_CMAKE_EXTRA_LIBRARIES "opencv" 16 | ) 17 | -------------------------------------------------------------------------------- /src/server/implementation/objects/FaceOverlayFilterImpl.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright 2016 Kurento (http://kurento.org/) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | #include 19 | #include "MediaPipeline.hpp" 20 | #include 21 | #include "FaceOverlayFilterImpl.hpp" 22 | #include 23 | #include 24 | #include 25 | 26 | #define GST_CAT_DEFAULT kurento_face_overlay_filter_impl 27 | GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); 28 | #define GST_DEFAULT_NAME "KurentoFaceOverlayFilterImpl" 29 | 30 | namespace kurento 31 | { 32 | 33 | FaceOverlayFilterImpl::FaceOverlayFilterImpl (const boost::property_tree::ptree 34 | &conf, std::shared_ptr 35 | mediaPipeline) : FilterImpl ( conf, 36 | std::dynamic_pointer_cast ( mediaPipeline) ) 37 | { 38 | g_object_set (element, "filter-factory", "faceoverlay", NULL); 39 | 40 | g_object_get (G_OBJECT (element), "filter", &faceOverlay, NULL); 41 | 42 | if (faceOverlay == nullptr) { 43 | throw KurentoException (MEDIA_OBJECT_NOT_AVAILABLE, 44 | "Media Object not available"); 45 | } 46 | 47 | g_object_unref (faceOverlay); 48 | } 49 | 50 | void FaceOverlayFilterImpl::unsetOverlayedImage () 51 | { 52 | GstStructure *imageSt; 53 | imageSt = gst_structure_new ("image", 54 | "offsetXPercent", G_TYPE_DOUBLE, 0.0, 55 | "offsetYPercent", G_TYPE_DOUBLE, 0.0, 56 | "widthPercent", G_TYPE_DOUBLE, 0.0, 57 | "heightPercent", G_TYPE_DOUBLE, 0.0, 58 | "url", G_TYPE_STRING, NULL, 59 | NULL); 60 | g_object_set (G_OBJECT (faceOverlay), "image-to-overlay", imageSt, NULL); 61 | gst_structure_free (imageSt); 62 | } 63 | 64 | void FaceOverlayFilterImpl::setOverlayedImage (const std::string &uri, 65 | float offsetXPercent, float offsetYPercent, float widthPercent, 66 | float heightPercent) 67 | { 68 | GstStructure *imageSt; 69 | imageSt = gst_structure_new ("image", 70 | "offsetXPercent", G_TYPE_DOUBLE, double (offsetXPercent), 71 | "offsetYPercent", G_TYPE_DOUBLE, double (offsetYPercent), 72 | "widthPercent", G_TYPE_DOUBLE, double (widthPercent), 73 | "heightPercent", G_TYPE_DOUBLE, double (heightPercent), 74 | "url", G_TYPE_STRING, uri.c_str(), 75 | NULL); 76 | g_object_set (G_OBJECT (faceOverlay), "image-to-overlay", imageSt, NULL); 77 | gst_structure_free (imageSt); 78 | } 79 | 80 | MediaObjectImpl * 81 | FaceOverlayFilterImplFactory::createObject (const boost::property_tree::ptree 82 | &conf, std::shared_ptr 83 | mediaPipeline) const 84 | { 85 | return new FaceOverlayFilterImpl (conf, mediaPipeline); 86 | } 87 | 88 | FaceOverlayFilterImpl::StaticConstructor 89 | FaceOverlayFilterImpl::staticConstructor; 90 | 91 | FaceOverlayFilterImpl::StaticConstructor::StaticConstructor() 92 | { 93 | GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, GST_DEFAULT_NAME, 0, 94 | GST_DEFAULT_NAME); 95 | } 96 | 97 | } /* kurento */ 98 | -------------------------------------------------------------------------------- /src/server/implementation/objects/FaceOverlayFilterImpl.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright 2016 Kurento (http://kurento.org/) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | #ifndef __FACE_OVERLAY_FILTER_IMPL_HPP__ 19 | #define __FACE_OVERLAY_FILTER_IMPL_HPP__ 20 | 21 | #include "FilterImpl.hpp" 22 | #include "FaceOverlayFilter.hpp" 23 | #include 24 | 25 | namespace kurento 26 | { 27 | 28 | class MediaPipeline; 29 | class FaceOverlayFilterImpl; 30 | 31 | void Serialize (std::shared_ptr &object, 32 | JsonSerializer &serializer); 33 | 34 | class FaceOverlayFilterImpl : public FilterImpl, 35 | public virtual FaceOverlayFilter 36 | { 37 | 38 | public: 39 | 40 | FaceOverlayFilterImpl (const boost::property_tree::ptree &conf, 41 | std::shared_ptr mediaPipeline); 42 | 43 | virtual ~FaceOverlayFilterImpl () {}; 44 | 45 | void unsetOverlayedImage (); 46 | void setOverlayedImage (const std::string &uri, float offsetXPercent, 47 | float offsetYPercent, float widthPercent, float heightPercent); 48 | 49 | /* Next methods are automatically implemented by code generator */ 50 | using FilterImpl::connect; 51 | virtual bool connect (const std::string &eventType, 52 | std::shared_ptr handler); 53 | 54 | virtual void invoke (std::shared_ptr obj, 55 | const std::string &methodName, const Json::Value ¶ms, 56 | Json::Value &response); 57 | 58 | virtual void Serialize (JsonSerializer &serializer); 59 | 60 | private: 61 | GstElement *faceOverlay = NULL; 62 | 63 | class StaticConstructor 64 | { 65 | public: 66 | StaticConstructor(); 67 | }; 68 | 69 | static StaticConstructor staticConstructor; 70 | 71 | }; 72 | 73 | } /* kurento */ 74 | 75 | #endif /* __FACE_OVERLAY_FILTER_IMPL_HPP__ */ 76 | -------------------------------------------------------------------------------- /src/server/implementation/objects/GStreamerFilterImpl.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright 2016 Kurento (http://kurento.org/) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | #include 19 | #include "MediaPipeline.hpp" 20 | #include "FilterType.hpp" 21 | #include 22 | #include "GStreamerFilterImpl.hpp" 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #define GST_CAT_DEFAULT kurento_gstreamer_filter_impl 34 | GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); 35 | #define GST_DEFAULT_NAME "KurentoGStreamerFilterImpl" 36 | 37 | namespace kurento 38 | { 39 | 40 | static void string2enum (const GValue *src_value, GValue *dst_value); 41 | 42 | GStreamerFilterImpl::GStreamerFilterImpl (const boost::property_tree::ptree 43 | &conf, std::shared_ptr 44 | mediaPipeline, const std::string &command, 45 | std::shared_ptr filterType) : FilterImpl (conf, 46 | std::dynamic_pointer_cast ( mediaPipeline) ) 47 | { 48 | GstElement *filter, *filter_check; 49 | GError *error = nullptr; 50 | 51 | this->cmd = command; 52 | 53 | GST_DEBUG ("Command %s", command.c_str() ); 54 | 55 | switch (filterType->getValue() ) { 56 | case FilterType::VIDEO: 57 | g_object_set (element, "type", 2, NULL); 58 | break; 59 | 60 | case FilterType::AUDIO: 61 | g_object_set (element, "type", 1, NULL); 62 | break; 63 | 64 | case FilterType::AUTODETECT: 65 | g_object_set (element, "type", 0, NULL); 66 | break; 67 | 68 | default: 69 | break; 70 | } 71 | 72 | filter = gst_parse_launch (command.c_str(), &error); 73 | 74 | if (filter == nullptr || error != nullptr) { 75 | std::string error_str = "GStreamer element cannot be created"; 76 | 77 | if (filter) { 78 | g_object_unref (filter); 79 | } 80 | 81 | if (error != nullptr) { 82 | if (error->message != nullptr) { 83 | error_str += ": " + std::string (error->message); 84 | } 85 | 86 | g_error_free (error); 87 | } 88 | 89 | throw KurentoException (MARSHALL_ERROR, error_str); 90 | } else if (GST_IS_BIN (filter) ) { 91 | g_object_unref (filter); 92 | 93 | throw KurentoException (MARSHALL_ERROR, 94 | "Given command is not valid, only one element can be created"); 95 | } 96 | 97 | g_object_set (element, "filter", filter, NULL); 98 | 99 | g_object_get (element, "filter", &filter_check, NULL); 100 | 101 | if (filter_check != filter) { 102 | g_object_unref (filter); 103 | g_object_unref (filter_check); 104 | 105 | throw KurentoException (MARSHALL_ERROR, 106 | "Given command is not valid, pad templates don't match"); 107 | } 108 | 109 | g_object_unref (filter); 110 | g_object_unref (filter_check); 111 | 112 | // No ref held; will be released by the pipeline 113 | gstElement = filter; 114 | 115 | // Used by method setElementProperty() when the property is an enum 116 | g_value_register_transform_func (G_TYPE_STRING, G_TYPE_ENUM, string2enum); 117 | } 118 | 119 | MediaObjectImpl * 120 | GStreamerFilterImplFactory::createObject (const boost::property_tree::ptree 121 | &conf, std::shared_ptr 122 | mediaPipeline, const std::string &command, 123 | std::shared_ptr filterType) const 124 | { 125 | return new GStreamerFilterImpl (conf, mediaPipeline, command, filterType); 126 | } 127 | 128 | std::string GStreamerFilterImpl::getCommand () 129 | { 130 | return this->cmd; 131 | } 132 | 133 | static void 134 | string2enum (const GValue *src_value, GValue *dst_value) 135 | { 136 | // Find and set the requested enum value among all possible ones 137 | // 138 | // See: 139 | // - https://developer.gnome.org/gobject/stable/gobject-Enumeration-and-Flag-Types.html 140 | // - https://developer.gnome.org/gobject/stable/gobject-Generic-values.html 141 | // - https://developer.gnome.org/gobject/stable/gobject-Standard-Parameter-and-Value-Types.html 142 | 143 | const gchar *src_string = g_value_get_string (src_value); 144 | 145 | const GType enum_type = G_VALUE_TYPE (dst_value); 146 | const GEnumClass *enum_class = G_ENUM_CLASS (g_type_class_ref (enum_type)); 147 | const GEnumValue *enum_values = enum_class->values; 148 | gboolean found = FALSE; 149 | 150 | for (guint i = 0; i < enum_class->n_values; ++i) { 151 | if (g_strcmp0 (src_string, enum_values[i].value_nick) == 0) { 152 | found = TRUE; 153 | g_value_set_enum (dst_value, enum_values[i].value); 154 | break; 155 | } 156 | } 157 | 158 | if (!found) { 159 | gchar *message = g_strdup_printf ("Invalid value for enum %s", 160 | G_VALUE_TYPE_NAME(dst_value)); 161 | throw std::invalid_argument(message); 162 | g_free (message); 163 | } 164 | } 165 | 166 | void GStreamerFilterImpl::setElementProperty(const std::string &propertyName, 167 | const std::string &propertyValue) 168 | { 169 | // Get the property _type_ from the GStreamer element 170 | const char* property_name = propertyName.c_str(); 171 | GParamSpec *pspec = g_object_class_find_property ( 172 | G_OBJECT_GET_CLASS (gstElement), property_name); 173 | if (pspec == NULL) { 174 | std::ostringstream oss; 175 | oss << "No property named '" << property_name << "' in object '" 176 | << GST_ELEMENT_NAME (gstElement) << "'"; 177 | std::string message = oss.str(); 178 | 179 | GST_WARNING ("%s", message.c_str()); 180 | throw KurentoException (MARSHALL_ERROR, message); 181 | } 182 | 183 | // Convert the input string to the correct value type 184 | GValue value = G_VALUE_INIT; 185 | g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE(pspec)); 186 | 187 | if (G_IS_PARAM_SPEC_INT (pspec)) { 188 | gint converted = 0; 189 | try { 190 | converted = std::stoi (propertyValue); 191 | } 192 | catch (std::exception &ex) { 193 | std::ostringstream oss; 194 | oss << "Cannot convert '" << propertyValue << "' to int: " << ex.what(); 195 | std::string message = oss.str(); 196 | 197 | GST_WARNING ("%s", message.c_str()); 198 | throw KurentoException (MARSHALL_ERROR, message); 199 | } 200 | g_value_set_int (&value, converted); 201 | } 202 | else if (G_IS_PARAM_SPEC_FLOAT (pspec)) { 203 | gfloat converted = 0.0f; 204 | try { 205 | converted = std::stof (propertyValue); 206 | } 207 | catch (std::exception &ex) { 208 | std::ostringstream oss; 209 | oss << "Cannot convert '" << propertyValue << "' to float: " << ex.what(); 210 | std::string message = oss.str(); 211 | 212 | GST_WARNING ("%s", message.c_str()); 213 | throw KurentoException (MARSHALL_ERROR, message); 214 | } 215 | g_value_set_float (&value, converted); 216 | } 217 | else if (G_IS_PARAM_SPEC_DOUBLE (pspec)) { 218 | gdouble converted = 0.0; 219 | try { 220 | converted = std::stod (propertyValue); 221 | } 222 | catch (std::exception &ex) { 223 | std::ostringstream oss; 224 | oss << "Cannot convert '" << propertyValue << "' to double: " << ex.what(); 225 | std::string message = oss.str(); 226 | 227 | GST_WARNING ("%s", message.c_str()); 228 | throw KurentoException (MARSHALL_ERROR, message); 229 | } 230 | g_value_set_double (&value, converted); 231 | } 232 | else if (G_IS_PARAM_SPEC_ENUM (pspec)) { 233 | // Source type: string 234 | GValue src_value = G_VALUE_INIT; 235 | g_value_init (&src_value, G_TYPE_STRING); 236 | g_value_set_static_string (&src_value, propertyValue.c_str()); 237 | 238 | // Destination type: enum 239 | try { 240 | g_value_transform (&src_value, &value); 241 | } 242 | catch (std::exception &ex) { 243 | std::ostringstream oss; 244 | oss << "Cannot convert '" << propertyValue << "' to enum: " << ex.what(); 245 | std::string message = oss.str(); 246 | 247 | GST_WARNING ("%s", message.c_str()); 248 | throw KurentoException (MARSHALL_ERROR, message); 249 | } 250 | } 251 | else if (G_IS_PARAM_SPEC_STRING (pspec)) { 252 | g_value_set_static_string (&value, propertyValue.c_str()); 253 | } 254 | // else if (...) { Add here whatever types are needed } 255 | else { 256 | std::ostringstream oss; 257 | oss << "Property type not implemented: " << G_PARAM_SPEC_TYPE_NAME (pspec); 258 | std::string message = oss.str(); 259 | 260 | GST_WARNING ("%s", message.c_str()); 261 | throw KurentoException (NOT_IMPLEMENTED, message); 262 | } 263 | 264 | g_object_set_property (G_OBJECT (gstElement), property_name, &value); 265 | g_value_unset (&value); 266 | } 267 | 268 | GStreamerFilterImpl::StaticConstructor GStreamerFilterImpl::staticConstructor; 269 | 270 | GStreamerFilterImpl::StaticConstructor::StaticConstructor() 271 | { 272 | GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, GST_DEFAULT_NAME, 0, 273 | GST_DEFAULT_NAME); 274 | } 275 | 276 | } /* kurento */ 277 | -------------------------------------------------------------------------------- /src/server/implementation/objects/GStreamerFilterImpl.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright 2016 Kurento (http://kurento.org/) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | #ifndef __GSTREAMER_FILTER_IMPL_HPP__ 19 | #define __GSTREAMER_FILTER_IMPL_HPP__ 20 | 21 | #include "FilterImpl.hpp" 22 | #include "GStreamerFilter.hpp" 23 | #include 24 | 25 | namespace kurento 26 | { 27 | 28 | class MediaPipeline; 29 | class FilterType; 30 | class GStreamerFilterImpl; 31 | 32 | void Serialize (std::shared_ptr &object, 33 | JsonSerializer &serializer); 34 | 35 | class GStreamerFilterImpl : public FilterImpl, public virtual GStreamerFilter 36 | { 37 | 38 | public: 39 | 40 | GStreamerFilterImpl (const boost::property_tree::ptree &conf, 41 | std::shared_ptr mediaPipeline, 42 | const std::string &command, std::shared_ptr filterType); 43 | 44 | virtual ~GStreamerFilterImpl () {}; 45 | 46 | virtual std::string getCommand () override; 47 | 48 | virtual void setElementProperty (const std::string &propertyName, 49 | const std::string &propertyValue) override; 50 | 51 | /* Next methods are automatically implemented by code generator */ 52 | using FilterImpl::connect; 53 | virtual bool connect (const std::string &eventType, 54 | std::shared_ptr handler) override; 55 | 56 | virtual void invoke (std::shared_ptr obj, 57 | const std::string &methodName, const Json::Value ¶ms, 58 | Json::Value &response) override; 59 | 60 | virtual void Serialize (JsonSerializer &serializer) override; 61 | 62 | private: 63 | GstElement *gstElement = NULL; 64 | std::string cmd; 65 | 66 | class StaticConstructor 67 | { 68 | public: 69 | StaticConstructor(); 70 | }; 71 | 72 | static StaticConstructor staticConstructor; 73 | 74 | }; 75 | 76 | } /* kurento */ 77 | 78 | #endif /* __GSTREAMER_FILTER_IMPL_HPP__ */ 79 | -------------------------------------------------------------------------------- /src/server/implementation/objects/ImageOverlayFilterImpl.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright 2016 Kurento (http://kurento.org/) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | #include 19 | #include "MediaPipeline.hpp" 20 | #include "MediaPipelineImpl.hpp" 21 | #include 22 | #include "ImageOverlayFilterImpl.hpp" 23 | #include 24 | #include 25 | 26 | #define GST_CAT_DEFAULT kurento_image_overlay_filter_impl 27 | GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); 28 | #define GST_DEFAULT_NAME "KurentoImageOverlayFilterImpl" 29 | 30 | #define IMAGES_TO_OVERLAY "images-to-overlay" 31 | 32 | namespace kurento 33 | { 34 | 35 | ImageOverlayFilterImpl::ImageOverlayFilterImpl (const 36 | boost::property_tree::ptree &config, 37 | std::shared_ptr mediaPipeline) : 38 | FilterImpl (config, std::dynamic_pointer_cast 39 | ( mediaPipeline) ) 40 | { 41 | g_object_set (element, "filter-factory", "logooverlay", NULL); 42 | 43 | g_object_get (G_OBJECT (element), "filter", &imageOverlay, NULL); 44 | 45 | if (imageOverlay == nullptr) { 46 | throw KurentoException (MEDIA_OBJECT_NOT_AVAILABLE, 47 | "Media Object not available"); 48 | } 49 | 50 | gst_object_unref (imageOverlay); 51 | } 52 | 53 | void ImageOverlayFilterImpl::removeImage (const std::string &id) 54 | { 55 | GstStructure *imagesLayout; 56 | gint len; 57 | 58 | /* The function obtains the actual window list */ 59 | g_object_get (G_OBJECT (imageOverlay), IMAGES_TO_OVERLAY, &imagesLayout, 60 | NULL); 61 | len = gst_structure_n_fields (imagesLayout); 62 | 63 | if (len == 0) { 64 | GST_WARNING ("There are no images in the layout"); 65 | return; 66 | } 67 | 68 | for (int i = 0; i < len; i++) { 69 | const gchar *name; 70 | name = gst_structure_nth_field_name (imagesLayout, i); 71 | 72 | if (strcmp (id.c_str (), name) == 0) { 73 | /* this image will be removed */ 74 | gst_structure_remove_field (imagesLayout, name); 75 | break; 76 | } 77 | } 78 | 79 | /* Set the buttons layout list without the window with id = id */ 80 | g_object_set (G_OBJECT (imageOverlay), IMAGES_TO_OVERLAY, imagesLayout, NULL); 81 | 82 | gst_structure_free (imagesLayout); 83 | } 84 | 85 | void ImageOverlayFilterImpl::addImage (const std::string &id, 86 | const std::string &uri, float offsetXPercent, float offsetYPercent, 87 | float widthPercent, float heightPercent, 88 | bool keepAspectRatio, bool center) 89 | { 90 | GstStructure *imagesLayout, *imageSt; 91 | 92 | imageSt = gst_structure_new ("image_position", 93 | "id", G_TYPE_STRING, id.c_str (), 94 | "uri", G_TYPE_STRING, uri.c_str (), 95 | "offsetXPercent", G_TYPE_FLOAT, float (offsetXPercent), 96 | "offsetYPercent", G_TYPE_FLOAT, float (offsetYPercent), 97 | "widthPercent", G_TYPE_FLOAT, float (widthPercent), 98 | "heightPercent", G_TYPE_FLOAT, float (heightPercent), 99 | "keepAspectRatio", G_TYPE_BOOLEAN, keepAspectRatio, 100 | "center", G_TYPE_BOOLEAN, center, 101 | NULL); 102 | 103 | /* The function obtains the actual window list */ 104 | g_object_get (G_OBJECT (imageOverlay), IMAGES_TO_OVERLAY, &imagesLayout, 105 | NULL); 106 | gst_structure_set (imagesLayout, 107 | id.c_str(), GST_TYPE_STRUCTURE, 108 | imageSt, NULL); 109 | 110 | g_object_set (G_OBJECT (imageOverlay), IMAGES_TO_OVERLAY, imagesLayout, NULL); 111 | 112 | gst_structure_free (imagesLayout); 113 | gst_structure_free (imageSt); 114 | } 115 | 116 | MediaObjectImpl * 117 | ImageOverlayFilterImplFactory::createObject (const boost::property_tree::ptree 118 | &config, std::shared_ptr mediaPipeline) const 119 | { 120 | return new ImageOverlayFilterImpl (config, mediaPipeline); 121 | } 122 | 123 | ImageOverlayFilterImpl::StaticConstructor 124 | ImageOverlayFilterImpl::staticConstructor; 125 | 126 | ImageOverlayFilterImpl::StaticConstructor::StaticConstructor() 127 | { 128 | GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, GST_DEFAULT_NAME, 0, 129 | GST_DEFAULT_NAME); 130 | } 131 | 132 | } /* kurento */ 133 | -------------------------------------------------------------------------------- /src/server/implementation/objects/ImageOverlayFilterImpl.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright 2016 Kurento (http://kurento.org/) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | #ifndef __IMAGE_OVERLAY_FILTER_IMPL_HPP__ 19 | #define __IMAGE_OVERLAY_FILTER_IMPL_HPP__ 20 | 21 | #include "FilterImpl.hpp" 22 | #include "ImageOverlayFilter.hpp" 23 | #include 24 | #include 25 | 26 | namespace kurento 27 | { 28 | class ImageOverlayFilterImpl; 29 | } /* kurento */ 30 | 31 | namespace kurento 32 | { 33 | void Serialize (std::shared_ptr &object, 34 | JsonSerializer &serializer); 35 | } /* kurento */ 36 | 37 | namespace kurento 38 | { 39 | class MediaPipelineImpl; 40 | } /* kurento */ 41 | 42 | namespace kurento 43 | { 44 | 45 | class ImageOverlayFilterImpl : public FilterImpl, 46 | public virtual ImageOverlayFilter 47 | { 48 | 49 | public: 50 | 51 | ImageOverlayFilterImpl (const boost::property_tree::ptree &config, 52 | std::shared_ptr mediaPipeline); 53 | 54 | virtual ~ImageOverlayFilterImpl () {}; 55 | 56 | void removeImage (const std::string &id); 57 | void addImage (const std::string &id, const std::string &uri, 58 | float offsetXPercent, float offsetYPercent, float widthPercent, 59 | float heightPercent, bool keepAspectRatio, bool center); 60 | 61 | /* Next methods are automatically implemented by code generator */ 62 | using FilterImpl::connect; 63 | virtual bool connect (const std::string &eventType, 64 | std::shared_ptr handler); 65 | virtual void invoke (std::shared_ptr obj, 66 | const std::string &methodName, const Json::Value ¶ms, 67 | Json::Value &response); 68 | 69 | virtual void Serialize (JsonSerializer &serializer); 70 | 71 | private: 72 | GstElement *imageOverlay{}; 73 | 74 | class StaticConstructor 75 | { 76 | public: 77 | StaticConstructor(); 78 | }; 79 | 80 | static StaticConstructor staticConstructor; 81 | 82 | }; 83 | 84 | } /* kurento */ 85 | 86 | #endif /* __IMAGE_OVERLAY_FILTER_IMPL_HPP__ */ 87 | -------------------------------------------------------------------------------- /src/server/implementation/objects/OpenCVFilterImpl.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright 2016 Kurento (http://kurento.org/) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | #include 19 | #include "MediaPipeline.hpp" 20 | #include "MediaPipelineImpl.hpp" 21 | #include 22 | #include "OpenCVFilterImpl.hpp" 23 | #include 24 | #include 25 | #include 26 | 27 | #define GST_CAT_DEFAULT kurento_open_cvfilter_impl 28 | GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); 29 | #define GST_DEFAULT_NAME "KurentoOpenCVFilterImpl" 30 | 31 | namespace kurento 32 | { 33 | 34 | OpenCVFilterImpl::OpenCVFilterImpl (const boost::property_tree::ptree &conf, 35 | std::shared_ptr 36 | mediaPipeline) : FilterImpl (conf, std::dynamic_pointer_cast 37 | (mediaPipeline) ) 38 | { 39 | g_object_set (element, "filter-factory", "opencvfilter", NULL); 40 | 41 | g_object_get (G_OBJECT (element), "filter", &opencvfilter, NULL); 42 | 43 | if (opencvfilter == nullptr) { 44 | throw KurentoException (MEDIA_OBJECT_NOT_AVAILABLE, 45 | "Media Object not available"); 46 | } 47 | 48 | g_object_set (opencvfilter, "target-object", 49 | static_cast (this), NULL); 50 | 51 | g_object_unref (opencvfilter); 52 | } 53 | 54 | OpenCVFilterImpl::StaticConstructor OpenCVFilterImpl::staticConstructor; 55 | 56 | OpenCVFilterImpl::StaticConstructor::StaticConstructor() 57 | { 58 | GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, GST_DEFAULT_NAME, 0, 59 | GST_DEFAULT_NAME); 60 | } 61 | 62 | } /* kurento */ 63 | -------------------------------------------------------------------------------- /src/server/implementation/objects/OpenCVFilterImpl.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright 2016 Kurento (http://kurento.org/) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | #ifndef __OPEN_CVFILTER_IMPL_HPP__ 19 | #define __OPEN_CVFILTER_IMPL_HPP__ 20 | 21 | #include "FilterImpl.hpp" 22 | #include "OpenCVFilter.hpp" 23 | #include 24 | #include "OpenCVProcess.hpp" 25 | 26 | namespace kurento 27 | { 28 | 29 | class MediaPipeline; 30 | class OpenCVFilterImpl; 31 | 32 | void Serialize (std::shared_ptr &object, 33 | JsonSerializer &serializer); 34 | 35 | class OpenCVFilterImpl : public FilterImpl, public virtual OpenCVFilter, 36 | public virtual OpenCVProcess 37 | { 38 | 39 | public: 40 | 41 | OpenCVFilterImpl (const boost::property_tree::ptree &conf, 42 | std::shared_ptr mediaPipeline); 43 | 44 | virtual ~OpenCVFilterImpl () {}; 45 | 46 | /* Next methods are automatically implemented by code generator */ 47 | using FilterImpl::connect; 48 | virtual bool connect (const std::string &eventType, 49 | std::shared_ptr handler); 50 | 51 | virtual void invoke (std::shared_ptr obj, 52 | const std::string &methodName, const Json::Value ¶ms, 53 | Json::Value &response); 54 | 55 | virtual void Serialize (JsonSerializer &serializer); 56 | 57 | private: 58 | GstElement *opencvfilter{}; 59 | 60 | class StaticConstructor 61 | { 62 | public: 63 | StaticConstructor(); 64 | }; 65 | 66 | static StaticConstructor staticConstructor; 67 | 68 | }; 69 | 70 | } /* kurento */ 71 | 72 | #endif /* __OPEN_CVFILTER_IMPL_HPP__ */ 73 | -------------------------------------------------------------------------------- /src/server/implementation/objects/OpenCVProcess.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright 2016 Kurento (http://kurento.org/) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | #ifndef __OPEN_CV_PROCESS_HPP__ 18 | #define __OPEN_CV_PROCESS_HPP__ 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | namespace kurento 25 | { 26 | class OpenCVProcess 27 | { 28 | public: 29 | virtual void process (cv::Mat &mat) = 0; 30 | protected: 31 | std::shared_ptr getSharedPtr() 32 | { 33 | try { 34 | return dynamic_cast (this)->shared_from_this(); 35 | } catch (...) { 36 | return std::shared_ptr (); 37 | } 38 | } 39 | }; 40 | } /* kurento */ 41 | 42 | #endif /* __OPEN_CV_PROCESS_HPP__ */ 43 | -------------------------------------------------------------------------------- /src/server/implementation/objects/ZBarFilterImpl.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright 2016 Kurento (http://kurento.org/) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | #include 19 | #include "MediaPipeline.hpp" 20 | #include "MediaPipelineImpl.hpp" 21 | #include 22 | #include "ZBarFilterImpl.hpp" 23 | #include 24 | #include 25 | #include 26 | #include "SignalHandler.hpp" 27 | 28 | #define GST_CAT_DEFAULT kurento_zbar_filter_impl 29 | GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); 30 | #define GST_DEFAULT_NAME "KurentoZBarFilterImpl" 31 | 32 | namespace kurento 33 | { 34 | void ZBarFilterImpl::busMessage (GstMessage *message) 35 | { 36 | 37 | if (GST_MESSAGE_SRC (message) == GST_OBJECT (zbar) && 38 | GST_MESSAGE_TYPE (message) == GST_MESSAGE_ELEMENT) { 39 | const GstStructure *st; 40 | guint64 ts; 41 | gchar *type, *symbol; 42 | 43 | st = gst_message_get_structure (message); 44 | 45 | if (g_strcmp0 (gst_structure_get_name (st), "barcode") != 0) { 46 | return; 47 | } 48 | 49 | if (!gst_structure_get (st, "timestamp", G_TYPE_UINT64, &ts, 50 | "type", G_TYPE_STRING, &type, "symbol", 51 | G_TYPE_STRING, &symbol, NULL) ) { 52 | return; 53 | } 54 | 55 | std::string symbolStr (symbol); 56 | std::string typeStr (type); 57 | 58 | g_free (type); 59 | g_free (symbol); 60 | 61 | barcodeDetected (ts, typeStr, symbolStr); 62 | } 63 | } 64 | 65 | void ZBarFilterImpl::postConstructor () 66 | { 67 | GstBus *bus; 68 | std::shared_ptr pipe; 69 | 70 | FilterImpl::postConstructor (); 71 | 72 | pipe = std::dynamic_pointer_cast (getMediaPipeline() ); 73 | 74 | bus = gst_pipeline_get_bus (GST_PIPELINE (pipe->getPipeline() ) ); 75 | 76 | bus_handler_id = register_signal_handler (G_OBJECT (bus), 77 | "message", 78 | std::function 79 | (std::bind (&ZBarFilterImpl::busMessage, this, 80 | std::placeholders::_2) ), 81 | std::dynamic_pointer_cast 82 | (shared_from_this() ) ); 83 | g_object_unref (bus); 84 | } 85 | 86 | ZBarFilterImpl::ZBarFilterImpl (const boost::property_tree::ptree &conf, 87 | std::shared_ptr mediaPipeline) : 88 | FilterImpl (conf, std::dynamic_pointer_cast ( mediaPipeline) ) 89 | { 90 | g_object_set (element, "filter-factory", "zbar", NULL); 91 | g_object_get (G_OBJECT (element), "filter", &zbar, NULL); 92 | 93 | if (zbar == nullptr) { 94 | throw KurentoException (MEDIA_OBJECT_NOT_FOUND, "ZBarFilter plugin not available: zbar"); 95 | } 96 | 97 | g_object_set (G_OBJECT (zbar), "qos", FALSE, NULL); 98 | 99 | bus_handler_id = 0; 100 | // There is no need to reference zbar becase its live cycle is the same as the filter live cycle 101 | g_object_unref (zbar); 102 | } 103 | 104 | void 105 | ZBarFilterImpl::barcodeDetected (guint64 ts, std::string &type, 106 | std::string &symbol) 107 | { 108 | if (lastSymbol != symbol || lastType != type || 109 | lastTs == G_GUINT64_CONSTANT (0) || ( (ts - lastTs) >= GST_SECOND) ) { 110 | // TODO: Hold a lock here to avoid race conditions 111 | 112 | lastSymbol = symbol; 113 | lastType = type; 114 | lastTs = ts; 115 | 116 | try { 117 | CodeFound event (shared_from_this (), CodeFound::getName (), type, 118 | symbol); 119 | sigcSignalEmit(signalCodeFound, event); 120 | } catch (const std::bad_weak_ptr &e) { 121 | // shared_from_this() 122 | GST_ERROR ("BUG creating %s: %s", CodeFound::getName ().c_str (), 123 | e.what ()); 124 | } 125 | } 126 | } 127 | 128 | MediaObjectImpl * 129 | ZBarFilterImplFactory::createObject (const boost::property_tree::ptree &conf, 130 | std::shared_ptr 131 | mediaPipeline) const 132 | { 133 | return new ZBarFilterImpl (conf, mediaPipeline); 134 | } 135 | 136 | ZBarFilterImpl::~ZBarFilterImpl() 137 | { 138 | std::shared_ptr pipe; 139 | 140 | if (bus_handler_id > 0) { 141 | pipe = std::dynamic_pointer_cast (getMediaPipeline() ); 142 | GstBus *bus = gst_pipeline_get_bus (GST_PIPELINE (pipe->getPipeline() ) ); 143 | unregister_signal_handler (bus, bus_handler_id); 144 | g_object_unref (bus); 145 | } 146 | } 147 | 148 | ZBarFilterImpl::StaticConstructor ZBarFilterImpl::staticConstructor; 149 | 150 | ZBarFilterImpl::StaticConstructor::StaticConstructor() 151 | { 152 | GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, GST_DEFAULT_NAME, 0, 153 | GST_DEFAULT_NAME); 154 | } 155 | 156 | } /* kurento */ 157 | -------------------------------------------------------------------------------- /src/server/implementation/objects/ZBarFilterImpl.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright 2016 Kurento (http://kurento.org/) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | #ifndef __ZBAR_FILTER_IMPL_HPP__ 19 | #define __ZBAR_FILTER_IMPL_HPP__ 20 | 21 | #include "FilterImpl.hpp" 22 | #include "ZBarFilter.hpp" 23 | #include 24 | 25 | namespace kurento 26 | { 27 | 28 | class MediaPipeline; 29 | class ZBarFilterImpl; 30 | 31 | void Serialize (std::shared_ptr &object, 32 | JsonSerializer &serializer); 33 | 34 | class ZBarFilterImpl : public FilterImpl, public virtual ZBarFilter 35 | { 36 | 37 | public: 38 | 39 | ZBarFilterImpl (const boost::property_tree::ptree &conf, 40 | std::shared_ptr mediaPipeline); 41 | 42 | virtual ~ZBarFilterImpl (); 43 | 44 | /* Next methods are automatically implemented by code generator */ 45 | using FilterImpl::connect; 46 | virtual bool connect (const std::string &eventType, 47 | std::shared_ptr handler); 48 | 49 | sigc::signal signalCodeFound; 50 | 51 | virtual void invoke (std::shared_ptr obj, 52 | const std::string &methodName, const Json::Value ¶ms, 53 | Json::Value &response); 54 | 55 | virtual void Serialize (JsonSerializer &serializer); 56 | 57 | protected: 58 | virtual void postConstructor (); 59 | 60 | private: 61 | GstElement *zbar{}; 62 | gulong bus_handler_id; 63 | 64 | guint64 lastTs = G_GUINT64_CONSTANT (0); 65 | std::string lastType; 66 | std::string lastSymbol; 67 | 68 | void busMessage (GstMessage *message); 69 | 70 | void barcodeDetected (guint64 ts, std::string &type, std::string &symbol); 71 | 72 | class StaticConstructor 73 | { 74 | public: 75 | StaticConstructor(); 76 | }; 77 | 78 | static StaticConstructor staticConstructor; 79 | 80 | }; 81 | 82 | } /* kurento */ 83 | 84 | #endif /* __ZBAR_FILTER_IMPL_HPP__ */ 85 | -------------------------------------------------------------------------------- /src/server/interface/filters.FaceOverlayFilter.kmd.json: -------------------------------------------------------------------------------- 1 | { 2 | "remoteClasses": [ 3 | { 4 | "name": "FaceOverlayFilter", 5 | "extends": "Filter", 6 | "doc": "FaceOverlayFilter interface. This type of :rom:cls:`Filter` detects faces in a video feed. The face is then overlaid with an image.", 7 | "constructor": { 8 | "doc": "FaceOverlayFilter interface. This type of :rom:cls:`Filter` detects faces in a video feed. The face is then overlaid with an image.", 9 | "params": [ 10 | { 11 | "name": "mediaPipeline", 12 | "doc": "pipeline to which this :rom:cls:`Filter` belons", 13 | "type": "MediaPipeline" 14 | } 15 | ] 16 | }, 17 | "methods": [ 18 | { 19 | "name": "unsetOverlayedImage", 20 | "doc": "Clear the image to be shown over each detected face. Stops overlaying the faces.", 21 | "params": [] 22 | }, 23 | { 24 | "name": "setOverlayedImage", 25 | "doc": "Sets the image to use as overlay on the detected faces.", 26 | "params": [ 27 | { 28 | "name": "uri", 29 | "doc": "URI where the image is located", 30 | "type": "String" 31 | }, 32 | { 33 | "name": "offsetXPercent", 34 | "doc": "the offset applied to the image, from the X coordinate of the detected face upper right corner. A positive value indicates right displacement, while a negative value moves the overlaid image to the left. This offset is specified as a percentage of the face width.\n\nFor example, to cover the detected face with the overlaid image, the parameter has to be ``0.0``. Values of ``1.0`` or ``-1.0`` indicate that the image upper right corner will be at the face´s X coord, +- the face´s width.\n\n.. note::\n\n The parameter name is misleading, the value is not a percent but a ratio", 35 | "type": "float" 36 | }, 37 | { 38 | "name": "offsetYPercent", 39 | "doc": "the offset applied to the image, from the Y coordinate of the detected face upper right corner. A positive value indicates up displacement, while a negative value moves the overlaid image down. This offset is specified as a percentage of the face width.\n\nFor example, to cover the detected face with the overlaid image, the parameter has to be ``0.0``. Values of ``1.0`` or ``-1.0`` indicate that the image upper right corner will be at the face´s Y coord, +- the face´s width.\n\n.. note::\n\n The parameter name is misleading, the value is not a percent but a ratio", 40 | "type": "float" 41 | }, 42 | { 43 | "name": "widthPercent", 44 | "doc": "proportional width of the overlaid image, relative to the width of the detected face. A value of 1.0 implies that the overlaid image will have the same width as the detected face. Values greater than 1.0 are allowed, while negative values are forbidden.\n\n.. note::\n\n The parameter name is misleading, the value is not a percent but a ratio", 45 | "type": "float" 46 | }, 47 | { 48 | "name": "heightPercent", 49 | "doc": "proportional height of the overlaid image, relative to the height of the detected face. A value of 1.0 implies that the overlaid image will have the same height as the detected face. Values greater than 1.0 are allowed, while negative values are forbidden.\n\n.. note::\n\n The parameter name is misleading, the value is not a percent but a ratio", 50 | "type": "float" 51 | } 52 | ] 53 | } 54 | ] 55 | } 56 | ] 57 | } 58 | -------------------------------------------------------------------------------- /src/server/interface/filters.GStreamerFilter.kmd.json: -------------------------------------------------------------------------------- 1 | { 2 | "remoteClasses": [ 3 | { 4 | "name": "GStreamerFilter", 5 | "extends": "Filter", 6 | "doc": "A generic filter that allows injecting a single GStreamer element. 7 |

8 | The current implementation of GStreamerFilter only allows single elements to 9 | be injected; one cannot indicate more than one at the same time; use several 10 | GStreamerFilters if you need to inject more than one element into the 11 | pipeline. 12 |

13 |

14 | Note that usage of some popular GStreamer elements requires installation of 15 | additional packages. For example, overlay elements such as 16 | timeoverlay or textoverlay require installation of the 17 | gstreamer1.5-x package, which will also install the 18 | Pango rendering library. 19 |

20 | ", 21 | "constructor": { 22 | "doc": "Create a :rom:cls:`GStreamerFilter`.", 23 | "params": [ 24 | { 25 | "name": "mediaPipeline", 26 | "doc": "the :rom:cls:`MediaPipeline` to which the filter belongs", 27 | "type": "MediaPipeline" 28 | }, 29 | { 30 | "name": "command", 31 | "doc": "String used to instantiate the GStreamer element, as in gst-launch (https://gstreamer.freedesktop.org/documentation/tools/gst-launch.html).", 32 | "type": "String" 33 | }, 34 | { 35 | "name": "filterType", 36 | "doc": "Sets the filter as Audio, Video, or Autodetect.", 37 | "type": "FilterType", 38 | "optional": true, 39 | "defaultValue": "AUTODETECT" 40 | } 41 | ] 42 | }, 43 | "properties": [ 44 | { 45 | "name": "command", 46 | "doc": "String used to instantiate the GStreamer element, as in gst-launch (https://gstreamer.freedesktop.org/documentation/tools/gst-launch.html).", 47 | "type": "String", 48 | "readOnly": true 49 | } 50 | ], 51 | "methods": [ 52 | { 53 | "name": "setElementProperty", 54 | "doc": "Provide a value to one of the GStreamer element's properties.", 55 | "params": [ 56 | { 57 | "name": "propertyName", 58 | "doc": "Name of the property that needs to be modified in the GStreamer element.", 59 | "type": "String" 60 | }, 61 | { 62 | "name": "propertyValue", 63 | "doc": "Value that must be assigned to the property.", 64 | "type": "String" 65 | } 66 | ] 67 | } 68 | ] 69 | } 70 | ] 71 | } 72 | -------------------------------------------------------------------------------- /src/server/interface/filters.ImageOverlayFilter.kmd.json: -------------------------------------------------------------------------------- 1 | { 2 | "remoteClasses": [ 3 | { 4 | "name": "ImageOverlayFilter", 5 | "extends": "Filter", 6 | "doc": "ImageOverlayFilter interface. This type of :rom:cls:`Filter` draws an image in a configured position over a video feed.", 7 | "constructor": { 8 | "doc": "ImageOverlayFilter interface. This type of :rom:cls:`Filter` draws an image in a configured position over a video feed.", 9 | "params": [ 10 | { 11 | "name": "mediaPipeline", 12 | "doc": "pipeline to which this :rom:cls:`Filter` belongs", 13 | "type": "MediaPipeline" 14 | } 15 | ] 16 | }, 17 | "methods": [ 18 | { 19 | "name": "removeImage", 20 | "doc": "Remove the image with the given ID.", 21 | "params": [ 22 | { 23 | "name": "id", 24 | "doc": "Image ID to be removed", 25 | "type": "String" 26 | } 27 | ] 28 | }, 29 | { 30 | "name": "addImage", 31 | "doc": "Add an image to be used as overlay.", 32 | "params": [ 33 | { 34 | "name": "id", 35 | "doc": "image ID", 36 | "type": "String" 37 | }, 38 | { 39 | "name": "uri", 40 | "doc": "URI where the image is located", 41 | "type": "String" 42 | }, 43 | { 44 | "name": "offsetXPercent", 45 | "doc": "Percentage relative to the image width to calculate the X coordinate of the position (left upper corner) [0..1]", 46 | "type": "float" 47 | }, 48 | { 49 | "name": "offsetYPercent", 50 | "doc": "Percentage relative to the image height to calculate the Y coordinate of the position (left upper corner) [0..1]", 51 | "type": "float" 52 | }, 53 | { 54 | "name": "widthPercent", 55 | "doc": "Proportional width of the overlaid image, relative to the width of the video [0..1].", 56 | "type": "float" 57 | }, 58 | { 59 | "name": "heightPercent", 60 | "doc": "Proportional height of the overlaid image, relative to the height of the video [0..1].", 61 | "type": "float" 62 | }, 63 | { 64 | "name": "keepAspectRatio", 65 | "doc": "Keep the aspect ratio of the original image.", 66 | "type": "boolean" 67 | }, 68 | { 69 | "name": "center", 70 | "doc": "If the image doesn't fit in the dimensions, the image will be center into the region defined by height and width.", 71 | "type": "boolean" 72 | } 73 | ] 74 | } 75 | ] 76 | } 77 | ] 78 | } 79 | -------------------------------------------------------------------------------- /src/server/interface/filters.OpenCVFilter.kmd.json: -------------------------------------------------------------------------------- 1 | { 2 | "remoteClasses": [ 3 | { 4 | "name": "OpenCVFilter", 5 | "extends": "Filter", 6 | "doc": "Generic OpenCV Filter", 7 | "abstract" : true 8 | } 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /src/server/interface/filters.ZBarFilter.kmd.json: -------------------------------------------------------------------------------- 1 | { 2 | "remoteClasses": [ 3 | { 4 | "name": "ZBarFilter", 5 | "extends": "Filter", 6 | "doc": "This filter detects QR codes in a video feed. When a code is found, the filter raises a :rom:evnt:`CodeFound` event.", 7 | "constructor": { 8 | "doc": "Builder for the :rom:cls:`ZBarFilter`.", 9 | "params": [ 10 | { 11 | "name": "mediaPipeline", 12 | "doc": "the :rom:cls:`MediaPipeline` to which the filter belongs", 13 | "type": "MediaPipeline" 14 | } 15 | ] 16 | }, 17 | "events": [ 18 | "CodeFound" 19 | ] 20 | } 21 | ], 22 | "events": [ 23 | { 24 | "properties": [ 25 | { 26 | "name": "codeType", 27 | "doc": "type of QR code found", 28 | "type": "String" 29 | }, 30 | { 31 | "name": "value", 32 | "doc": "value contained in the QR code", 33 | "type": "String" 34 | } 35 | ], 36 | "extends": "Media", 37 | "name": "CodeFound", 38 | "doc": "Event raised by a :rom:cls:`ZBarFilter` when a code is found in the data being streamed." 39 | } 40 | ] 41 | } 42 | -------------------------------------------------------------------------------- /src/server/interface/filters.kmd.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "filters", 3 | "version": "6.18.1-dev", 4 | "kurentoVersion": "^6.18.1-dev", 5 | "code": { 6 | "kmd": { 7 | "java": { 8 | "mavenGroupId": "org.kurento", 9 | "mavenArtifactId": "kms-api-filters" 10 | } 11 | }, 12 | "api": { 13 | "java": { 14 | "packageName": "org.kurento.client", 15 | "mavenGroupId": "org.kurento", 16 | "mavenArtifactId": "kurento-client" 17 | }, 18 | "js": { 19 | "nodeName": "kurento-client-filters", 20 | "npmDescription": "JavaScript Client API for Kurento Media Server", 21 | "npmGit": "https://github.com/Kurento/kurento-client-filters-js.git" 22 | } 23 | }, 24 | "implementation": { 25 | "cppNamespace": "kurento" 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/server/interface/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "license": "ALv2", 3 | "homepage": "https://kurento.openvidu.io/", 4 | "author": "Kurento (https://kurento.openvidu.io/)", 5 | "bugs": { 6 | "email": "kurento@googlegroups.com" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/server/interface/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | Kurento Media Server filters module 6 | https://kurento.openvidu.io/ 7 | 8 | 9 | 10 | Apache 2.0 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | repo 13 | 14 | 15 | 16 | 17 | 18 | kurento.org 19 | Kurento Community 20 | Kurento 21 | https://kurento.openvidu.io/ 22 | 23 | 24 | 25 | 26 | https://github.com/Kurento/kms-filters 27 | scm:git:https://github.com/Kurento/kms-filters.git 28 | scm:git:ssh://github.com/Kurento/kms-filters.git 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include (TestHelpers) 2 | 3 | add_subdirectory(server) 4 | 5 | if (${gstreamer-check-1.5_FOUND}) 6 | add_subdirectory(check) 7 | endif () 8 | -------------------------------------------------------------------------------- /tests/check/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Disable error when functions are unused. This allows commenting out calls to 2 | # `tcase_add_test()` to skip running certain tests during a debug session. 3 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-error=unused-function") 4 | 5 | set(KMS_TEST_UTILS_SOURCES 6 | kmstestutils.h kmstestutils.c 7 | ) 8 | 9 | add_library(kmsfilterstestutils ${KMS_TEST_UTILS_SOURCES}) 10 | if(SANITIZERS_ENABLED) 11 | add_sanitizers(kmsfilterstestutils) 12 | endif() 13 | 14 | target_link_libraries(kmsfilterstestutils 15 | ${gstreamer-1.5_LIBRARIES} 16 | ${gstreamer-base-1.5_LIBRARIES} 17 | ${gstreamer-sdp-1.5_LIBRARIES} 18 | ${gstreamer-pbutils-1.5_LIBRARIES} 19 | ) 20 | set_property(TARGET kmsfilterstestutils 21 | PROPERTY INCLUDE_DIRECTORIES 22 | ${gstreamer-1.5_INCLUDE_DIRS} 23 | ) 24 | 25 | include(TestHelpers) 26 | set(TEST_VARIABLES 27 | "GST_PLUGIN_PATH=${CMAKE_BINARY_DIR}" 28 | # HTTP requests have 60s timeout for the worst case, plus allow some time for 29 | # processing the tests 30 | "CK_DEFAULT_TIMEOUT=120" 31 | ) 32 | list(APPEND SUPPRESSIONS 33 | "${CMAKE_CURRENT_SOURCE_DIR}/valgrind.supp") 34 | 35 | add_subdirectory(element) 36 | -------------------------------------------------------------------------------- /tests/check/element/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(SUPRESSIONS "${CMAKE_CURRENT_SOURCE_DIR}/../valgrind.supp") 2 | 3 | add_test_program(test_faceoverlay faceoverlay.c) 4 | add_dependencies(test_faceoverlay faceoverlay) 5 | target_include_directories(test_faceoverlay PRIVATE 6 | ${KMSCORE_INCLUDE_DIRS} 7 | ${gstreamer-1.5_INCLUDE_DIRS} 8 | ${gstreamer-check-1.5_INCLUDE_DIRS} 9 | ${CMAKE_CURRENT_BINARY_DIR}/../../.. 10 | ${CMAKE_CURRENT_SOURCE_DIR}/.. 11 | "${CMAKE_CURRENT_SOURCE_DIR}/../../../src/gst-plugins" 12 | ) 13 | target_link_libraries(test_faceoverlay 14 | ${gstreamer-1.0_LIBRARIES} 15 | ${gstreamer-check-1.5_LIBRARIES} 16 | kmsfilterstestutils 17 | ) 18 | 19 | add_test_program(test_movementdetector movementdetector.c) 20 | add_dependencies(test_movementdetector movementdetector) 21 | target_include_directories(test_movementdetector PRIVATE 22 | ${KMSCORE_INCLUDE_DIRS} 23 | ${gstreamer-1.5_INCLUDE_DIRS} 24 | ${gstreamer-check-1.5_INCLUDE_DIRS} 25 | ${CMAKE_CURRENT_BINARY_DIR}/../../.. 26 | ${CMAKE_CURRENT_SOURCE_DIR}/.. 27 | "${CMAKE_CURRENT_SOURCE_DIR}/../../../src/gst-plugins" 28 | ) 29 | target_link_libraries(test_movementdetector 30 | ${gstreamer-1.5_LIBRARIES} 31 | ${gstreamer-check-1.5_LIBRARIES} 32 | kmsfilterstestutils 33 | ) 34 | 35 | add_test_program(test_logooverlay logooverlay.c) 36 | add_dependencies(test_logooverlay logooverlay) 37 | target_include_directories(test_logooverlay PRIVATE 38 | ${KMSCORE_INCLUDE_DIRS} 39 | ${gstreamer-1.5_INCLUDE_DIRS} 40 | ${gstreamer-check-1.5_INCLUDE_DIRS} 41 | ${CMAKE_CURRENT_BINARY_DIR}/../../.. 42 | ${CMAKE_CURRENT_SOURCE_DIR}/.. 43 | "${CMAKE_CURRENT_SOURCE_DIR}/../../../src/gst-plugins" 44 | ) 45 | target_link_libraries(test_logooverlay 46 | ${gstreamer-1.5_LIBRARIES} 47 | ${gstreamer-check-1.5_LIBRARIES} 48 | kmsfilterstestutils 49 | ) 50 | -------------------------------------------------------------------------------- /tests/check/element/faceoverlay.c: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright 2014 Kurento (http://kurento.org/) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | #ifdef HAVE_CONFIG_H 18 | #include "config.h" 19 | #endif 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | 28 | #define IMG_PATH BINARY_LOCATION "/img/mario-wings.png" 29 | #define VIDEO_PATH BINARY_LOCATION "/video/format/small.webm" 30 | 31 | #define KMS_VIDEO_PREFIX "video_src_" 32 | #define KMS_AUDIO_PREFIX "audio_src_" 33 | #define KMS_ELEMENT_PAD_TYPE_AUDIO 1 34 | #define KMS_ELEMENT_PAD_TYPE_VIDEO 2 35 | 36 | // DEBUG LOGGING: 37 | //export SOUP_DEBUG=1 38 | //export GST_DEBUG="3,check:5,playerendpoint:5,faceoverlay:7,imageoverlay:7" 39 | 40 | GMainLoop *loop; 41 | GstElement *player, *pipeline, *filter, *fakesink_audio, *fakesink_video; 42 | 43 | GST_START_TEST (set_properties) 44 | { 45 | GstElement *faceoverlay; 46 | GstStructure *imageSt; 47 | 48 | faceoverlay = gst_element_factory_make ("faceoverlay", NULL); 49 | 50 | //set face 51 | imageSt = gst_structure_new ("image", 52 | "offsetXPercent", G_TYPE_DOUBLE, -0.35, 53 | "offsetYPercent", G_TYPE_DOUBLE, -1.2, 54 | "widthPercent", G_TYPE_DOUBLE, 1.6, 55 | "heightPercent", G_TYPE_DOUBLE, 1.6, 56 | "url", G_TYPE_STRING, IMG_PATH, NULL); 57 | g_object_set (G_OBJECT (faceoverlay), "image-to-overlay", imageSt, NULL); 58 | gst_structure_free (imageSt); 59 | 60 | //set face 61 | imageSt = gst_structure_new ("image", 62 | "offsetXPercent", G_TYPE_DOUBLE, -0.35, 63 | "offsetYPercent", G_TYPE_DOUBLE, -1.2, 64 | "widthPercent", G_TYPE_DOUBLE, 1.6, 65 | "heightPercent", G_TYPE_DOUBLE, 1.6, 66 | "url", G_TYPE_STRING, IMG_PATH, NULL); 67 | g_object_set (G_OBJECT (faceoverlay), "image-to-overlay", imageSt, NULL); 68 | gst_structure_free (imageSt); 69 | 70 | //unset face 71 | imageSt = gst_structure_new ("image", 72 | "offsetXPercent", G_TYPE_DOUBLE, 0.0, 73 | "offsetYPercent", G_TYPE_DOUBLE, 0.0, 74 | "widthPercent", G_TYPE_DOUBLE, 0.0, 75 | "heightPercent", G_TYPE_DOUBLE, 0.0, "url", G_TYPE_STRING, NULL, NULL); 76 | g_object_set (G_OBJECT (faceoverlay), "image-to-overlay", imageSt, NULL); 77 | gst_structure_free (imageSt); 78 | 79 | //set face 80 | imageSt = gst_structure_new ("image", 81 | "offsetXPercent", G_TYPE_DOUBLE, -0.35, 82 | "offsetYPercent", G_TYPE_DOUBLE, -1.2, 83 | "widthPercent", G_TYPE_DOUBLE, 1.6, 84 | "heightPercent", G_TYPE_DOUBLE, 1.6, 85 | "url", G_TYPE_STRING, IMG_PATH, NULL); 86 | g_object_set (G_OBJECT (faceoverlay), "image-to-overlay", imageSt, NULL); 87 | gst_structure_free (imageSt); 88 | 89 | g_object_unref (faceoverlay); 90 | } 91 | 92 | GST_END_TEST static void 93 | bus_msg_cb (GstBus * bus, GstMessage * msg, gpointer pipeline) 94 | { 95 | switch (GST_MESSAGE_TYPE (msg)) { 96 | case GST_MESSAGE_ERROR: { 97 | GError *err = NULL; 98 | gchar *dbg_info = NULL; 99 | 100 | gst_message_parse_error (msg, &err, &dbg_info); 101 | GST_ERROR ("Pipeline '%s': Bus error %d: %s", GST_ELEMENT_NAME (pipeline), 102 | err->code, GST_STR_NULL (err->message)); 103 | GST_ERROR ("Debugging info: %s", GST_STR_NULL (dbg_info)); 104 | g_error_free (err); 105 | g_free (dbg_info); 106 | 107 | GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (pipeline), 108 | GST_DEBUG_GRAPH_SHOW_ALL, "bus_error"); 109 | 110 | fail ("Pipeline '%s': Bus error", GST_ELEMENT_NAME (pipeline)); 111 | 112 | break; 113 | } 114 | case GST_MESSAGE_WARNING: { 115 | GError *err = NULL; 116 | gchar *dbg_info = NULL; 117 | 118 | gst_message_parse_error (msg, &err, &dbg_info); 119 | GST_WARNING ("Pipeline '%s': Bus warning %d: %s", 120 | GST_ELEMENT_NAME (pipeline), err->code, GST_STR_NULL (err->message)); 121 | GST_WARNING ("Debugging info: %s", GST_STR_NULL (dbg_info)); 122 | g_error_free (err); 123 | g_free (dbg_info); 124 | 125 | GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (pipeline), 126 | GST_DEBUG_GRAPH_SHOW_ALL, "bus_warning"); 127 | 128 | fail ("Pipeline '%s': Bus warning", GST_ELEMENT_NAME (pipeline)); 129 | 130 | break; 131 | } 132 | case GST_MESSAGE_EOS: { 133 | GST_DEBUG ("Pipeline '%s': Bus event: EOS (%s)", 134 | GST_ELEMENT_NAME (pipeline), GST_OBJECT_NAME (msg->src)); 135 | 136 | g_main_loop_quit (loop); 137 | 138 | break; 139 | } 140 | default: 141 | break; 142 | } 143 | } 144 | 145 | static void 146 | connect_sink_on_srcpad_added (GstElement * playerep, GstPad * new_pad, 147 | gpointer user_data) 148 | { 149 | gchar *padname; 150 | gboolean ret; 151 | 152 | GST_INFO_OBJECT (playerep, "Pad added %" GST_PTR_FORMAT, new_pad); 153 | padname = gst_pad_get_name (new_pad); 154 | fail_if (padname == NULL); 155 | 156 | if (g_str_has_prefix (padname, KMS_VIDEO_PREFIX)) { 157 | ret = gst_element_link_pads (playerep, padname, filter, "sink"); 158 | fail_if (ret == FALSE); 159 | ret = gst_element_link (filter, fakesink_video); 160 | fail_if (ret == FALSE); 161 | } else if (g_str_has_prefix (padname, KMS_AUDIO_PREFIX)) { 162 | ret = gst_element_link_pads (playerep, padname, fakesink_audio, "sink"); 163 | fail_if (ret == FALSE); 164 | } 165 | g_free (padname); 166 | } 167 | 168 | static gboolean 169 | quit_main_loop_idle (gpointer data) 170 | { 171 | GMainLoop *loop = data; 172 | 173 | GST_DEBUG ("Test finished exiting main loop"); 174 | g_main_loop_quit (loop); 175 | return FALSE; 176 | } 177 | 178 | static void 179 | player_eos (GstElement * player, GMainLoop * loop) 180 | { 181 | GST_DEBUG ("Eos received"); 182 | g_idle_add (quit_main_loop_idle, loop); 183 | } 184 | 185 | GST_START_TEST (player_with_filter) 186 | { 187 | guint bus_watch_id; 188 | GstBus *bus; 189 | GstStructure *imageSt; 190 | gchar *padname; 191 | 192 | loop = g_main_loop_new (NULL, FALSE); 193 | pipeline = gst_pipeline_new ("pipeline_live_stream"); 194 | g_object_set (G_OBJECT (pipeline), "async-handling", TRUE, NULL); 195 | player = gst_element_factory_make ("playerendpoint", NULL); 196 | filter = gst_element_factory_make ("faceoverlay", NULL); 197 | fakesink_audio = gst_element_factory_make ("fakesink", NULL); 198 | fakesink_video = gst_element_factory_make ("fakesink", NULL); 199 | bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); 200 | 201 | bus_watch_id = gst_bus_add_watch (bus, gst_bus_async_signal_func, NULL); 202 | g_signal_connect (bus, "message", G_CALLBACK (bus_msg_cb), pipeline); 203 | g_object_unref (bus); 204 | 205 | g_object_set (G_OBJECT (player), "uri", VIDEO_PATH, NULL); 206 | 207 | gst_element_link (filter, fakesink_video); 208 | imageSt = gst_structure_new ("image", 209 | "offsetXPercent", G_TYPE_DOUBLE, -0.35, 210 | "offsetYPercent", G_TYPE_DOUBLE, -1.2, 211 | "widthPercent", G_TYPE_DOUBLE, 1.6, 212 | "heightPercent", G_TYPE_DOUBLE, 1.6, 213 | "url", G_TYPE_STRING, IMG_PATH, NULL); 214 | g_object_set (G_OBJECT (filter), "image-to-overlay", imageSt, NULL); 215 | gst_structure_free (imageSt); 216 | 217 | gst_element_set_state (pipeline, GST_STATE_PLAYING); 218 | 219 | gst_bin_add_many (GST_BIN (pipeline), filter, fakesink_audio, fakesink_video, 220 | player, NULL); 221 | gst_element_set_state (filter, GST_STATE_PLAYING); 222 | gst_element_set_state (fakesink_audio, GST_STATE_PLAYING); 223 | gst_element_set_state (fakesink_video, GST_STATE_PLAYING); 224 | 225 | g_signal_connect (G_OBJECT (player), "eos", G_CALLBACK (player_eos), loop); 226 | g_signal_connect (player, "pad-added", 227 | G_CALLBACK (connect_sink_on_srcpad_added), loop); 228 | 229 | /* request audio src pad using action */ 230 | g_signal_emit_by_name (player, "request-new-pad", 231 | KMS_ELEMENT_PAD_TYPE_AUDIO, NULL, GST_PAD_SRC, &padname); 232 | fail_if (padname == NULL); 233 | GST_DEBUG ("Requested pad %s", padname); 234 | g_free (padname); 235 | 236 | /* request video src pad using action */ 237 | g_signal_emit_by_name (player, "request-new-pad", 238 | KMS_ELEMENT_PAD_TYPE_VIDEO, NULL, GST_PAD_SRC, &padname); 239 | fail_if (padname == NULL); 240 | 241 | GST_DEBUG ("Requested pad %s", padname); 242 | g_free (padname); 243 | 244 | gst_element_set_state (player, GST_STATE_PLAYING); 245 | 246 | /* Set player to start state */ 247 | g_object_set (G_OBJECT (player), "state", KMS_URI_ENDPOINT_STATE_START, NULL); 248 | 249 | g_main_loop_run (loop); 250 | 251 | gst_element_set_state (pipeline, GST_STATE_NULL); 252 | gst_object_unref (GST_OBJECT (pipeline)); 253 | g_source_remove (bus_watch_id); 254 | g_main_loop_unref (loop); 255 | } 256 | 257 | GST_END_TEST static Suite * 258 | faceoverlay_suite (void) 259 | { 260 | Suite *s = suite_create ("faceoverlay"); 261 | TCase *tc_chain = tcase_create ("element"); 262 | 263 | suite_add_tcase (s, tc_chain); 264 | tcase_add_test (tc_chain, set_properties); 265 | tcase_add_test (tc_chain, player_with_filter); 266 | 267 | return s; 268 | } 269 | 270 | GST_CHECK_MAIN (faceoverlay); 271 | -------------------------------------------------------------------------------- /tests/check/element/logooverlay.c: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright 2016 Kurento (http://kurento.org/) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | #ifdef HAVE_CONFIG_H 18 | #include "config.h" 19 | #endif 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | 28 | #define IMG_PATH BINARY_LOCATION "/img/mario-wings.png" 29 | #define VIDEO_PATH BINARY_LOCATION "/video/format/small.webm" 30 | 31 | #define IMAGES_TO_OVERLAY "images-to-overlay" 32 | 33 | #define KMS_VIDEO_PREFIX "video_src_" 34 | #define KMS_AUDIO_PREFIX "audio_src_" 35 | #define KMS_ELEMENT_PAD_TYPE_AUDIO 1 36 | #define KMS_ELEMENT_PAD_TYPE_VIDEO 2 37 | 38 | GMainLoop *loop; 39 | GstElement *player, *pipeline, *filter, *fakesink_audio, *fakesink_video; 40 | GstClockID clock_id; 41 | 42 | GstStructure * 43 | generate_logo_structure () 44 | { 45 | GstStructure *imageSt; 46 | 47 | imageSt = gst_structure_new ("image_position", 48 | "id", G_TYPE_STRING, "image", 49 | "uri", G_TYPE_STRING, IMG_PATH, 50 | "offsetXPercent", G_TYPE_FLOAT, 0.2, 51 | "offsetYPercent", G_TYPE_FLOAT, 0.2, 52 | "widthPercent", G_TYPE_FLOAT, 0.2, 53 | "heightPercent", G_TYPE_FLOAT, 0.2, 54 | "keepAspectRatio", G_TYPE_BOOLEAN, TRUE, 55 | "center", G_TYPE_BOOLEAN, TRUE, NULL); 56 | 57 | return imageSt; 58 | } 59 | 60 | GST_START_TEST (set_properties) 61 | { 62 | GstElement *logooverlay; 63 | GstStructure *imageSt; 64 | 65 | logooverlay = gst_element_factory_make ("logooverlay", NULL); 66 | 67 | imageSt = generate_logo_structure (); 68 | 69 | //set images 70 | g_object_set (G_OBJECT (logooverlay), IMAGES_TO_OVERLAY, imageSt, NULL); 71 | g_object_set (G_OBJECT (logooverlay), IMAGES_TO_OVERLAY, imageSt, NULL); 72 | 73 | //unset images 74 | g_object_set (G_OBJECT (logooverlay), IMAGES_TO_OVERLAY, NULL, NULL); 75 | 76 | //set images 77 | g_object_set (G_OBJECT (logooverlay), IMAGES_TO_OVERLAY, imageSt, NULL); 78 | 79 | gst_structure_free (imageSt); 80 | g_object_unref (logooverlay); 81 | } 82 | GST_END_TEST 83 | 84 | static void 85 | bus_msg_cb (GstBus * bus, GstMessage * msg, gpointer pipeline) 86 | { 87 | switch (GST_MESSAGE_TYPE (msg)) { 88 | case GST_MESSAGE_ERROR: { 89 | GError *err = NULL; 90 | gchar *dbg_info = NULL; 91 | 92 | gst_message_parse_error (msg, &err, &dbg_info); 93 | GST_ERROR ("Pipeline '%s': Bus error %d: %s", GST_ELEMENT_NAME (pipeline), 94 | err->code, GST_STR_NULL (err->message)); 95 | GST_ERROR ("Debugging info: %s", GST_STR_NULL (dbg_info)); 96 | g_error_free (err); 97 | g_free (dbg_info); 98 | 99 | GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (pipeline), 100 | GST_DEBUG_GRAPH_SHOW_ALL, "bus_error"); 101 | 102 | fail ("Pipeline '%s': Bus error", GST_ELEMENT_NAME (pipeline)); 103 | 104 | break; 105 | } 106 | case GST_MESSAGE_WARNING: { 107 | GError *err = NULL; 108 | gchar *dbg_info = NULL; 109 | 110 | gst_message_parse_error (msg, &err, &dbg_info); 111 | GST_WARNING ("Pipeline '%s': Bus warning %d: %s", 112 | GST_ELEMENT_NAME (pipeline), err->code, GST_STR_NULL (err->message)); 113 | GST_WARNING ("Debugging info: %s", GST_STR_NULL (dbg_info)); 114 | g_error_free (err); 115 | g_free (dbg_info); 116 | 117 | GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (pipeline), 118 | GST_DEBUG_GRAPH_SHOW_ALL, "bus_warning"); 119 | 120 | fail ("Pipeline '%s': Bus warning", GST_ELEMENT_NAME (pipeline)); 121 | 122 | break; 123 | } 124 | case GST_MESSAGE_EOS: { 125 | GST_DEBUG ("Pipeline '%s': Bus event: EOS (%s)", 126 | GST_ELEMENT_NAME (pipeline), GST_OBJECT_NAME (msg->src)); 127 | 128 | g_main_loop_quit (loop); 129 | 130 | break; 131 | } 132 | default: 133 | break; 134 | } 135 | } 136 | 137 | static void 138 | connect_sink_on_srcpad_added (GstElement * playerep, GstPad * new_pad, 139 | gpointer user_data) 140 | { 141 | gchar *padname; 142 | gboolean ret; 143 | 144 | GST_INFO_OBJECT (playerep, "Pad added %" GST_PTR_FORMAT, new_pad); 145 | padname = gst_pad_get_name (new_pad); 146 | fail_if (padname == NULL); 147 | 148 | if (g_str_has_prefix (padname, KMS_VIDEO_PREFIX)) { 149 | ret = gst_element_link_pads (playerep, padname, filter, "sink"); 150 | fail_if (ret == FALSE); 151 | ret = gst_element_link (filter, fakesink_video); 152 | fail_if (ret == FALSE); 153 | } else if (g_str_has_prefix (padname, KMS_AUDIO_PREFIX)) { 154 | ret = gst_element_link_pads (playerep, padname, fakesink_audio, "sink"); 155 | fail_if (ret == FALSE); 156 | } 157 | g_free (padname); 158 | } 159 | 160 | static gboolean 161 | quit_main_loop_idle (gpointer data) 162 | { 163 | GMainLoop *loop = data; 164 | 165 | GST_DEBUG ("Test finished exiting main loop"); 166 | g_main_loop_quit (loop); 167 | return FALSE; 168 | } 169 | 170 | static void 171 | player_eos (GstElement * player, GMainLoop * loop) 172 | { 173 | GST_DEBUG ("Eos received"); 174 | g_idle_add (quit_main_loop_idle, loop); 175 | } 176 | 177 | GST_START_TEST (player_with_filter) 178 | { 179 | guint bus_watch_id; 180 | GstBus *bus; 181 | GstStructure *imageSt; 182 | gchar *padname; 183 | 184 | loop = g_main_loop_new (NULL, FALSE); 185 | pipeline = gst_pipeline_new ("pipeline_live_stream"); 186 | g_object_set (G_OBJECT (pipeline), "async-handling", TRUE, NULL); 187 | player = gst_element_factory_make ("playerendpoint", NULL); 188 | filter = gst_element_factory_make ("logooverlay", NULL); 189 | fakesink_audio = gst_element_factory_make ("fakesink", NULL); 190 | fakesink_video = gst_element_factory_make ("fakesink", NULL); 191 | bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); 192 | 193 | bus_watch_id = gst_bus_add_watch (bus, gst_bus_async_signal_func, NULL); 194 | g_signal_connect (bus, "message", G_CALLBACK (bus_msg_cb), pipeline); 195 | g_object_unref (bus); 196 | 197 | g_object_set (G_OBJECT (player), "uri", VIDEO_PATH, NULL); 198 | 199 | gst_element_link (filter, fakesink_video); 200 | 201 | imageSt = generate_logo_structure (); 202 | g_object_set (G_OBJECT (filter), IMAGES_TO_OVERLAY, imageSt, NULL); 203 | gst_structure_free (imageSt); 204 | 205 | gst_element_set_state (pipeline, GST_STATE_PLAYING); 206 | 207 | gst_bin_add_many (GST_BIN (pipeline), filter, fakesink_audio, fakesink_video, 208 | player, NULL); 209 | gst_element_set_state (filter, GST_STATE_PLAYING); 210 | gst_element_set_state (fakesink_audio, GST_STATE_PLAYING); 211 | gst_element_set_state (fakesink_video, GST_STATE_PLAYING); 212 | 213 | g_signal_connect (G_OBJECT (player), "eos", G_CALLBACK (player_eos), loop); 214 | g_signal_connect (player, "pad-added", 215 | G_CALLBACK (connect_sink_on_srcpad_added), loop); 216 | 217 | /* request audio src pad using action */ 218 | g_signal_emit_by_name (player, "request-new-pad", 219 | KMS_ELEMENT_PAD_TYPE_AUDIO, NULL, GST_PAD_SRC, &padname); 220 | fail_if (padname == NULL); 221 | GST_DEBUG ("Requested pad %s", padname); 222 | g_free (padname); 223 | 224 | /* request video src pad using action */ 225 | g_signal_emit_by_name (player, "request-new-pad", 226 | KMS_ELEMENT_PAD_TYPE_VIDEO, NULL, GST_PAD_SRC, &padname); 227 | fail_if (padname == NULL); 228 | 229 | GST_DEBUG ("Requested pad %s", padname); 230 | g_free (padname); 231 | 232 | gst_element_set_state (player, GST_STATE_PLAYING); 233 | 234 | /* Set player to start state */ 235 | g_object_set (G_OBJECT (player), "state", KMS_URI_ENDPOINT_STATE_START, NULL); 236 | 237 | g_main_loop_run (loop); 238 | 239 | gst_element_set_state (pipeline, GST_STATE_NULL); 240 | gst_object_unref (GST_OBJECT (pipeline)); 241 | g_source_remove (bus_watch_id); 242 | g_main_loop_unref (loop); 243 | } 244 | 245 | GST_END_TEST gboolean 246 | change_structure (GstClock * clock, 247 | GstClockTime time, GstClockID id, gpointer user_data) 248 | { 249 | GstStructure *imageSt; 250 | 251 | imageSt = generate_logo_structure (); 252 | g_object_set (G_OBJECT (filter), IMAGES_TO_OVERLAY, imageSt, NULL); 253 | gst_structure_free (imageSt); 254 | 255 | return TRUE; 256 | } 257 | 258 | static void 259 | player_eos_schedule (GstElement * player, GMainLoop * loop) 260 | { 261 | GST_DEBUG ("Eos received"); 262 | gst_clock_id_unschedule (clock_id); 263 | gst_clock_id_unref (clock_id); 264 | 265 | g_idle_add (quit_main_loop_idle, loop); 266 | } 267 | 268 | GST_START_TEST (player_with_filter_many_changes) 269 | { 270 | guint bus_watch_id; 271 | GstBus *bus; 272 | GstStructure *imageSt; 273 | gchar *padname; 274 | GstClock *clk; 275 | GstClockTime init_time; 276 | 277 | clk = gst_system_clock_obtain (); 278 | fail_if (clk == NULL); 279 | 280 | init_time = gst_clock_get_time (clk); 281 | clock_id = gst_clock_new_periodic_id (clk, init_time, GST_SECOND); 282 | g_object_unref (clk); 283 | 284 | loop = g_main_loop_new (NULL, FALSE); 285 | pipeline = gst_pipeline_new ("pipeline_live_stream"); 286 | g_object_set (G_OBJECT (pipeline), "async-handling", TRUE, NULL); 287 | player = gst_element_factory_make ("playerendpoint", NULL); 288 | filter = gst_element_factory_make ("logooverlay", NULL); 289 | fakesink_audio = gst_element_factory_make ("fakesink", NULL); 290 | fakesink_video = gst_element_factory_make ("fakesink", NULL); 291 | bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); 292 | 293 | bus_watch_id = gst_bus_add_watch (bus, gst_bus_async_signal_func, NULL); 294 | g_signal_connect (bus, "message", G_CALLBACK (bus_msg_cb), pipeline); 295 | g_object_unref (bus); 296 | 297 | g_object_set (G_OBJECT (player), "uri", VIDEO_PATH, NULL); 298 | 299 | gst_element_link (filter, fakesink_video); 300 | 301 | imageSt = generate_logo_structure (); 302 | g_object_set (G_OBJECT (filter), IMAGES_TO_OVERLAY, imageSt, NULL); 303 | gst_structure_free (imageSt); 304 | 305 | gst_element_set_state (pipeline, GST_STATE_PLAYING); 306 | 307 | gst_bin_add_many (GST_BIN (pipeline), filter, fakesink_audio, fakesink_video, 308 | player, NULL); 309 | gst_element_set_state (filter, GST_STATE_PLAYING); 310 | gst_element_set_state (fakesink_audio, GST_STATE_PLAYING); 311 | gst_element_set_state (fakesink_video, GST_STATE_PLAYING); 312 | 313 | g_signal_connect (G_OBJECT (player), "eos", G_CALLBACK (player_eos_schedule), 314 | loop); 315 | g_signal_connect (player, "pad-added", 316 | G_CALLBACK (connect_sink_on_srcpad_added), loop); 317 | 318 | /* request audio src pad using action */ 319 | g_signal_emit_by_name (player, "request-new-pad", 320 | KMS_ELEMENT_PAD_TYPE_AUDIO, NULL, GST_PAD_SRC, &padname); 321 | fail_if (padname == NULL); 322 | GST_DEBUG ("Requested pad %s", padname); 323 | g_free (padname); 324 | 325 | /* request video src pad using action */ 326 | g_signal_emit_by_name (player, "request-new-pad", 327 | KMS_ELEMENT_PAD_TYPE_VIDEO, NULL, GST_PAD_SRC, &padname); 328 | fail_if (padname == NULL); 329 | 330 | GST_DEBUG ("Requested pad %s", padname); 331 | g_free (padname); 332 | 333 | gst_clock_id_wait_async (clock_id, change_structure, NULL, NULL); 334 | 335 | gst_element_set_state (player, GST_STATE_PLAYING); 336 | 337 | /* Set player to start state */ 338 | g_object_set (G_OBJECT (player), "state", KMS_URI_ENDPOINT_STATE_START, NULL); 339 | 340 | g_main_loop_run (loop); 341 | 342 | gst_element_set_state (pipeline, GST_STATE_NULL); 343 | gst_object_unref (GST_OBJECT (pipeline)); 344 | g_source_remove (bus_watch_id); 345 | g_main_loop_unref (loop); 346 | } 347 | 348 | GST_END_TEST static Suite * 349 | logooverlay_suite (void) 350 | { 351 | Suite *s = suite_create ("logooverlay"); 352 | TCase *tc_chain = tcase_create ("element"); 353 | 354 | suite_add_tcase (s, tc_chain); 355 | tcase_add_test (tc_chain, set_properties); 356 | tcase_add_test (tc_chain, player_with_filter); 357 | tcase_add_test (tc_chain, player_with_filter_many_changes); 358 | 359 | return s; 360 | } 361 | 362 | GST_CHECK_MAIN (logooverlay); 363 | -------------------------------------------------------------------------------- /tests/check/element/movementdetector.c: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright 2014 Kurento (http://kurento.org/) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | #ifdef HAVE_CONFIG_H 18 | #include "config.h" 19 | #endif 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | 28 | #define VIDEO_PATH BINARY_LOCATION "/video/format/small.webm" 29 | #define KMS_VIDEO_PREFIX "video_src_" 30 | #define KMS_AUDIO_PREFIX "audio_src_" 31 | #define KMS_ELEMENT_PAD_TYPE_AUDIO 1 32 | #define KMS_ELEMENT_PAD_TYPE_VIDEO 2 33 | 34 | GMainLoop *loop; 35 | GstElement *player, *pipeline, *filter, *fakesink_audio, *fakesink_video; 36 | 37 | static void 38 | bus_msg_cb (GstBus * bus, GstMessage * msg, gpointer pipeline) 39 | { 40 | switch (GST_MESSAGE_TYPE (msg)) { 41 | case GST_MESSAGE_ERROR: { 42 | GError *err = NULL; 43 | gchar *dbg_info = NULL; 44 | 45 | gst_message_parse_error (msg, &err, &dbg_info); 46 | GST_ERROR ("Pipeline '%s': Bus error %d: %s", GST_ELEMENT_NAME (pipeline), 47 | err->code, GST_STR_NULL (err->message)); 48 | GST_ERROR ("Debugging info: %s", GST_STR_NULL (dbg_info)); 49 | g_error_free (err); 50 | g_free (dbg_info); 51 | 52 | GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (pipeline), 53 | GST_DEBUG_GRAPH_SHOW_ALL, "bus_error"); 54 | 55 | fail ("Pipeline '%s': Bus error", GST_ELEMENT_NAME (pipeline)); 56 | 57 | break; 58 | } 59 | case GST_MESSAGE_WARNING: { 60 | GError *err = NULL; 61 | gchar *dbg_info = NULL; 62 | 63 | gst_message_parse_error (msg, &err, &dbg_info); 64 | GST_WARNING ("Pipeline '%s': Bus warning %d: %s", 65 | GST_ELEMENT_NAME (pipeline), err->code, GST_STR_NULL (err->message)); 66 | GST_WARNING ("Debugging info: %s", GST_STR_NULL (dbg_info)); 67 | g_error_free (err); 68 | g_free (dbg_info); 69 | 70 | GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (pipeline), 71 | GST_DEBUG_GRAPH_SHOW_ALL, "bus_warning"); 72 | 73 | fail ("Pipeline '%s': Bus warning", GST_ELEMENT_NAME (pipeline)); 74 | 75 | break; 76 | } 77 | case GST_MESSAGE_EOS: { 78 | GST_DEBUG ("Pipeline '%s': Bus event: EOS (%s)", 79 | GST_ELEMENT_NAME (pipeline), GST_OBJECT_NAME (msg->src)); 80 | 81 | g_main_loop_quit (loop); 82 | 83 | break; 84 | } 85 | default: 86 | break; 87 | } 88 | } 89 | 90 | static void 91 | connect_sink_on_srcpad_added (GstElement * playerep, GstPad * new_pad, 92 | gpointer user_data) 93 | { 94 | gchar *padname; 95 | gboolean ret; 96 | 97 | GST_INFO_OBJECT (playerep, "Pad added %" GST_PTR_FORMAT, new_pad); 98 | padname = gst_pad_get_name (new_pad); 99 | fail_if (padname == NULL); 100 | 101 | if (g_str_has_prefix (padname, KMS_VIDEO_PREFIX)) { 102 | ret = gst_element_link_pads (playerep, padname, filter, "sink"); 103 | fail_if (ret == FALSE); 104 | ret = gst_element_link (filter, fakesink_video); 105 | fail_if (ret == FALSE); 106 | } else if (g_str_has_prefix (padname, KMS_AUDIO_PREFIX)) { 107 | ret = gst_element_link_pads (playerep, padname, fakesink_audio, "sink"); 108 | fail_if (ret == FALSE); 109 | } 110 | g_free (padname); 111 | } 112 | 113 | static gboolean 114 | quit_main_loop_idle (gpointer data) 115 | { 116 | GMainLoop *loop = data; 117 | 118 | GST_DEBUG ("Test finished exiting main loop"); 119 | g_main_loop_quit (loop); 120 | return FALSE; 121 | } 122 | 123 | static void 124 | player_eos (GstElement * player, GMainLoop * loop) 125 | { 126 | GST_DEBUG ("Eos received"); 127 | g_idle_add (quit_main_loop_idle, loop); 128 | } 129 | 130 | GST_START_TEST (player_with_filter) 131 | { 132 | guint bus_watch_id; 133 | GstBus *bus; 134 | gchar *padname; 135 | 136 | loop = g_main_loop_new (NULL, FALSE); 137 | pipeline = gst_pipeline_new ("pipeline_live_stream"); 138 | g_object_set (G_OBJECT (pipeline), "async-handling", TRUE, NULL); 139 | player = gst_element_factory_make ("playerendpoint", NULL); 140 | filter = gst_element_factory_make ("movementdetector", NULL); 141 | fakesink_audio = gst_element_factory_make ("fakesink", NULL); 142 | fakesink_video = gst_element_factory_make ("fakesink", NULL); 143 | bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); 144 | 145 | bus_watch_id = gst_bus_add_watch (bus, gst_bus_async_signal_func, NULL); 146 | g_signal_connect (bus, "message", G_CALLBACK (bus_msg_cb), pipeline); 147 | g_object_unref (bus); 148 | 149 | g_object_set (G_OBJECT (player), "uri", VIDEO_PATH, NULL); 150 | 151 | gst_element_set_state (pipeline, GST_STATE_PLAYING); 152 | 153 | gst_bin_add_many (GST_BIN (pipeline), filter, fakesink_audio, fakesink_video, 154 | player, NULL); 155 | gst_element_set_state (filter, GST_STATE_PLAYING); 156 | gst_element_set_state (fakesink_audio, GST_STATE_PLAYING); 157 | gst_element_set_state (fakesink_video, GST_STATE_PLAYING); 158 | 159 | g_signal_connect (G_OBJECT (player), "eos", G_CALLBACK (player_eos), loop); 160 | g_signal_connect (player, "pad-added", 161 | G_CALLBACK (connect_sink_on_srcpad_added), loop); 162 | 163 | /* request audio src pad using action */ 164 | g_signal_emit_by_name (player, "request-new-pad", 165 | KMS_ELEMENT_PAD_TYPE_AUDIO, NULL, GST_PAD_SRC, &padname); 166 | fail_if (padname == NULL); 167 | 168 | GST_DEBUG ("Requested pad %s", padname); 169 | g_free (padname); 170 | 171 | /* request video src pad using action */ 172 | g_signal_emit_by_name (player, "request-new-pad", 173 | KMS_ELEMENT_PAD_TYPE_VIDEO, NULL, GST_PAD_SRC, &padname); 174 | fail_if (padname == NULL); 175 | 176 | GST_DEBUG ("Requested pad %s", padname); 177 | g_free (padname); 178 | 179 | gst_element_set_state (player, GST_STATE_PLAYING); 180 | 181 | /* Set player to start state */ 182 | g_object_set (G_OBJECT (player), "state", KMS_URI_ENDPOINT_STATE_START, NULL); 183 | 184 | g_main_loop_run (loop); 185 | 186 | gst_element_set_state (pipeline, GST_STATE_NULL); 187 | gst_object_unref (GST_OBJECT (pipeline)); 188 | g_source_remove (bus_watch_id); 189 | g_main_loop_unref (loop); 190 | } 191 | 192 | GST_END_TEST static Suite * 193 | movementdetector_suite (void) 194 | { 195 | Suite *s = suite_create ("movementdetector"); 196 | TCase *tc_chain = tcase_create ("element"); 197 | 198 | suite_add_tcase (s, tc_chain); 199 | tcase_add_test (tc_chain, player_with_filter); 200 | 201 | return s; 202 | } 203 | 204 | GST_CHECK_MAIN (movementdetector); 205 | -------------------------------------------------------------------------------- /tests/check/kmscheck.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright 2013 Kurento (http://kurento.org/) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | #include 19 | 20 | #define KMS_CHECK_MAIN(name) \ 21 | int main (int argc, char **argv) \ 22 | { \ 23 | Suite *s; \ 24 | int ret; \ 25 | gst_check_init (&argc, &argv); \ 26 | s = name ## _suite (); \ 27 | ret = gst_check_run_suite (s, # name, __FILE__); \ 28 | gst_deinit (); \ 29 | return ret; \ 30 | } 31 | 32 | #define KMS_END_TEST GST_LOG ("cleaning up tasks"); \ 33 | gst_task_cleanup_all (); \ 34 | gst_deinit (); \ 35 | END_TEST 36 | -------------------------------------------------------------------------------- /tests/check/kmstestutils.c: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright 2013 Kurento (http://kurento.org/) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | #include "kmstestutils.h" 18 | 19 | #define GST_CAT_DEFAULT kms_utils 20 | GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); 21 | #define GST_DEFAULT_NAME "kms_utils" 22 | 23 | #define KEY_DATA_PROPERTY "kms-test-utils-prop" 24 | 25 | struct tmp_data 26 | { 27 | GRecMutex rmutex; 28 | gchar *src_pad_name; 29 | GstElement *sink; 30 | gchar *sink_pad_name; 31 | gulong handler; 32 | }; 33 | 34 | static void 35 | destroy_tmp_data (gpointer data, GClosure * closure) 36 | { 37 | struct tmp_data *tmp = data; 38 | 39 | if (tmp->sink != NULL) 40 | gst_object_unref (tmp->sink); 41 | 42 | if (tmp->src_pad_name != NULL) 43 | g_free (tmp->src_pad_name); 44 | 45 | if (tmp->sink_pad_name != NULL) 46 | g_free (tmp->sink_pad_name); 47 | 48 | g_rec_mutex_clear (&tmp->rmutex); 49 | 50 | g_slice_free (struct tmp_data, tmp); 51 | } 52 | 53 | static struct tmp_data * 54 | create_tmp_data (const gchar * src_pad_name, GstElement * sink, 55 | const gchar * sink_pad_name) 56 | { 57 | struct tmp_data *tmp; 58 | 59 | tmp = g_slice_new0 (struct tmp_data); 60 | 61 | g_rec_mutex_init (&tmp->rmutex); 62 | tmp->src_pad_name = g_strdup (src_pad_name); 63 | tmp->sink = gst_object_ref (sink); 64 | tmp->sink_pad_name = g_strdup (sink_pad_name); 65 | tmp->handler = 0L; 66 | 67 | return tmp; 68 | } 69 | 70 | static void 71 | connect_to_sink (GstElement * sink, const gchar * sinkname, GstPad * srcpad) 72 | { 73 | GstPad *sinkpad; 74 | 75 | GST_DEBUG ("Getting pad %s from %" GST_PTR_FORMAT, sinkname, sink); 76 | sinkpad = gst_element_get_static_pad (sink, sinkname); 77 | 78 | if (sinkpad == NULL) 79 | sinkpad = gst_element_get_request_pad (sink, sinkname); 80 | 81 | if (sinkpad == NULL) { 82 | GST_ERROR ("Can not get sink pad."); 83 | return; 84 | } 85 | 86 | if (gst_pad_is_linked (sinkpad)) { 87 | GST_ERROR ("Pad %" GST_PTR_FORMAT " is already linked.", sinkpad); 88 | goto end; 89 | } 90 | 91 | if (gst_pad_link (srcpad, sinkpad) != GST_PAD_LINK_OK) 92 | GST_ERROR ("Can not link pad %" GST_PTR_FORMAT " to %" GST_PTR_FORMAT, 93 | srcpad, sinkpad); 94 | else 95 | GST_DEBUG ("Connected %" GST_PTR_FORMAT " to %" GST_PTR_FORMAT, 96 | srcpad, sinkpad); 97 | 98 | end: 99 | g_object_unref (sinkpad); 100 | } 101 | 102 | static void 103 | agnosticbin_added_cb (GstElement * element, gpointer data) 104 | { 105 | struct tmp_data *tmp = data; 106 | GstPad *pad; 107 | 108 | g_rec_mutex_lock (&tmp->rmutex); 109 | 110 | if (tmp->handler == 0L) { 111 | goto end; 112 | } 113 | 114 | pad = gst_element_get_request_pad (element, tmp->src_pad_name); 115 | if (pad == NULL) { 116 | goto end; 117 | } 118 | 119 | GST_DEBUG_OBJECT (element, "Connecting pad %s", tmp->src_pad_name); 120 | 121 | connect_to_sink (tmp->sink, tmp->sink_pad_name, pad); 122 | gst_object_unref (pad); 123 | g_signal_handler_disconnect (element, tmp->handler); 124 | tmp->handler = 0L; 125 | 126 | end: 127 | g_rec_mutex_unlock (&tmp->rmutex); 128 | } 129 | 130 | void 131 | kms_element_link_pads (GstElement * src, const gchar * src_pad_name, 132 | GstElement * sink, const gchar * sink_pad_name) 133 | { 134 | GstPad *pad; 135 | 136 | pad = gst_element_get_request_pad (src, src_pad_name); 137 | if (pad == NULL) { 138 | struct tmp_data *tmp; 139 | 140 | GST_DEBUG ("Put connection off until agnostic bin is created for pad %s", 141 | src_pad_name); 142 | tmp = create_tmp_data (src_pad_name, sink, sink_pad_name); 143 | tmp->handler = g_signal_connect_data (src, "agnosticbin-added", 144 | G_CALLBACK (agnosticbin_added_cb), tmp, destroy_tmp_data, 145 | (GConnectFlags) 0); 146 | } else { 147 | connect_to_sink (sink, sink_pad_name, pad); 148 | g_object_unref (pad); 149 | } 150 | } 151 | 152 | static void init_debug (void) __attribute__ ((constructor)); 153 | 154 | static void 155 | init_debug (void) 156 | { 157 | GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, GST_DEFAULT_NAME, 0, 158 | GST_DEFAULT_NAME); 159 | } 160 | -------------------------------------------------------------------------------- /tests/check/kmstestutils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright 2013 Kurento (http://kurento.org/) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | #ifndef __KMS_TEST_UTILS_H__ 18 | #define __KMS_TEST_UTILS_H__ 19 | 20 | #include "gst/gst.h" 21 | 22 | void kms_element_link_pads (GstElement * src, const gchar * src_pad_name, 23 | GstElement * sink, const gchar * sink_pad_name); 24 | 25 | #endif /* __KMS_TEST_UTILS_H__ */ -------------------------------------------------------------------------------- /tests/check/memory_leaks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | pushd . > /dev/null 4 | SCRIPT_PATH=$(dirname `which $0`) 5 | cd $SCRIPT_PATH 6 | SCRIPT_PATH="`pwd`" 7 | popd /dev/null 8 | 9 | LOGS_DIR=$SCRIPT_PATH/memory_leaks 10 | 11 | export GST_TRACE=live 12 | 13 | function process_logs { 14 | DIR=$1 15 | make check 16 | mkdir -p $DIR 17 | pushd $LOGS_DIR 18 | for f in *.log; do 19 | cat $f | grep "GstClockEntry\|GstMiniObject\|GstObject" > $DIR/$f 20 | done 21 | popd 22 | } 23 | 24 | export ITERATIONS=1 25 | DIR_A=$LOGS_DIR/$ITERATIONS"_it" 26 | process_logs $DIR_A 27 | 28 | export ITERATIONS=2 29 | DIR_B=$LOGS_DIR/$ITERATIONS"_it" 30 | process_logs $DIR_B 31 | 32 | MEMORY_LEAKS="NO" 33 | pushd $DIR_A 34 | for f in *.log; do 35 | DIFF=$(diff $f $DIR_B/$f) 36 | if [ $? -ne 0 ]; then 37 | echo "Memory leaks in $f"; 38 | MEMORY_LEAKS="YES" 39 | else 40 | echo "$f OK"; 41 | fi 42 | done 43 | popd 44 | 45 | if [ $MEMORY_LEAKS == "YES" ]; then 46 | exit -1 47 | fi 48 | 49 | echo "Memory leaks not detected" 50 | -------------------------------------------------------------------------------- /tests/check/valgrind.supp: -------------------------------------------------------------------------------- 1 | # G_DEBUG=gc-friendly G_SLICE=always-malloc valgrind -v --leak-check=yes --log-file=valgrind.log --xml-file=valgrind.xml --xml=yes --suppressions=../valgrind.supp sever/kurento 2 | { 3 | Glib type register static 4 | Memcheck:Leak 5 | ... 6 | fun:g_type_register_static 7 | ... 8 | } 9 | { 10 | Glib type interface static registration 11 | Memcheck:Leak 12 | ... 13 | fun:g_type_add_interface_static 14 | ... 15 | } 16 | { 17 | Glib type register fundamental 18 | Memcheck:Leak 19 | ... 20 | fun:g_type_register_fundamental 21 | ... 22 | } 23 | { 24 | Glib type class ref 25 | Memcheck:Leak 26 | ... 27 | fun:g_type_class_ref 28 | ... 29 | } 30 | { 31 | Glib init ctor 32 | Memcheck:Leak 33 | ... 34 | fun:gobject_init_ctor 35 | ... 36 | } 37 | { 38 | Quark from static string 39 | Memcheck:Leak 40 | ... 41 | fun:g_quark_from_static_string 42 | ... 43 | } 44 | { 45 | Static pad Template 46 | Memcheck:Leak 47 | ... 48 | fun:gst_static_pad_template_get 49 | ... 50 | } 51 | { 52 | Gstreamer load plugin 53 | Memcheck:Leak 54 | ... 55 | fun:gst_plugin_feature_load 56 | ... 57 | } 58 | { 59 | Gstreamer load plugin file 60 | Memcheck:Leak 61 | ... 62 | fun:gst_plugin_load_file 63 | ... 64 | } 65 | { 66 | Gstreamer statuc_caps_get 67 | Memcheck:Leak 68 | ... 69 | fun:gst_static_caps_get 70 | ... 71 | } 72 | { 73 | Glib dns lookup 74 | Memcheck:Param 75 | sendmsg(mmsg[0].msg_hdr) 76 | fun:sendmmsg 77 | fun:__libc_res_nsend 78 | fun:__libc_res_nquery 79 | ... 80 | } 81 | { 82 | Lib orc program_new_from_static 83 | Memcheck:Leak 84 | ... 85 | fun:orc_program_new_from_static_bytecode 86 | ... 87 | } 88 | -------------------------------------------------------------------------------- /tests/server/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(TEST_VARIABLES 2 | "GST_PLUGIN_PATH=${CMAKE_BINARY_DIR}" 3 | ) 4 | 5 | add_test_program(test_filters_constructors constructors.cpp) 6 | if(TARGET ${LIBRARY_NAME}module) 7 | add_dependencies(test_filters_constructors ${LIBRARY_NAME}module) 8 | endif() 9 | add_dependencies(test_filters_constructors 10 | facedetector 11 | faceoverlay 12 | imageoverlay 13 | movementdetector 14 | opencvfilter 15 | ) 16 | set_property(TARGET test_filters_constructors 17 | PROPERTY INCLUDE_DIRECTORIES 18 | ${CMAKE_CURRENT_BINARY_DIR}/../.. 19 | ${JSONRPC_INCLUDE_DIRS} 20 | ${SIGCPP_INCLUDE_DIRS} 21 | ${CMAKE_CURRENT_SOURCE_DIR}/../../src/server/implementation/objects 22 | ${CMAKE_CURRENT_SOURCE_DIR}/../../src/server/implementation 23 | ${CMAKE_CURRENT_SOURCE_DIR}/../../src/server/interface 24 | ${CMAKE_CURRENT_BINARY_DIR}/../../src/server/interface/generated-cpp 25 | ${CMAKE_CURRENT_BINARY_DIR}/../../src/server/implementation/generated-cpp 26 | ${KMSFILTERS_DEPENDENCIES_INCLUDE_DIRS} 27 | ) 28 | target_link_libraries(test_filters_constructors 29 | ${LIBRARY_NAME}impl 30 | ${KMSCORE_LIBRARIES} 31 | ${GLIBMM_LIBRARIES} 32 | ) 33 | -------------------------------------------------------------------------------- /tests/server/constructors.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright 2014 Kurento (http://kurento.org/) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | boost::property_tree::ptree config; 31 | 32 | void 33 | testFaceOverlay (kurento::ModuleManager &moduleManager, 34 | std::shared_ptr mediaPipeline) 35 | { 36 | kurento::JsonSerializer w (true); 37 | 38 | w.SerializeNVP (mediaPipeline); 39 | 40 | std::shared_ptr object = 41 | moduleManager.getFactory ("FaceOverlayFilter")->createObject (config, "", 42 | w.JsonValue); 43 | kurento::MediaSet::getMediaSet()->release (object); 44 | } 45 | 46 | void 47 | testGStreamerFilter (kurento::ModuleManager &moduleManager, 48 | std::shared_ptr mediaPipeline) 49 | { 50 | kurento::JsonSerializer w (true); 51 | std::string command ("capsfilter " 52 | "caps=video/x-raw,pixel-aspect-ratio=(fraction)1/1,width=(int)640,framerate=(fraction)4/1"); 53 | std::shared_ptr filter (new kurento::FilterType ( 54 | kurento::FilterType::VIDEO) ); 55 | 56 | w.SerializeNVP (mediaPipeline); 57 | w.SerializeNVP (command); 58 | w.SerializeNVP (filter); 59 | 60 | std::shared_ptr object = 61 | moduleManager.getFactory ("GStreamerFilter")->createObject (config, "", 62 | w.JsonValue); 63 | 64 | kurento::MediaSet::getMediaSet()->release (object); 65 | } 66 | 67 | void 68 | testZBarFilter (kurento::ModuleManager &moduleManager, 69 | std::shared_ptr mediaPipeline) 70 | { 71 | kurento::JsonSerializer w (true); 72 | 73 | w.SerializeNVP (mediaPipeline); 74 | 75 | std::shared_ptr object = 76 | moduleManager.getFactory ("ZBarFilter")->createObject (config, "", w.JsonValue); 77 | kurento::MediaSet::getMediaSet()->release (object); 78 | } 79 | 80 | int 81 | main (int argc, char **argv) 82 | { 83 | std::shared_ptr mediaPipeline; 84 | std::shared_ptr factory; 85 | 86 | gst_init (&argc, &argv); 87 | 88 | kurento::ModuleManager moduleManager; 89 | 90 | moduleManager.loadModulesFromDirectories ("../../src/server:../../.."); 91 | 92 | mediaPipeline = moduleManager.getFactory ("MediaPipeline")->createObject ( 93 | config, "", 94 | Json::Value() ); 95 | 96 | moduleManager.loadModule ("../../src/server/libkmsfiltersmodule.so"); 97 | 98 | testFaceOverlay (moduleManager, mediaPipeline); 99 | testGStreamerFilter (moduleManager, mediaPipeline); 100 | testZBarFilter (moduleManager, mediaPipeline); 101 | 102 | kurento::MediaSet::getMediaSet()->release (mediaPipeline); 103 | 104 | return 0; 105 | } 106 | --------------------------------------------------------------------------------