diff --git a/CHANGELOG.md b/CHANGELOG.md index 45f0271c6..87a19ab0a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,38 @@ # Changelog All notable changes to this project will be documented in this file. -The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) -and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [6.8.1] - 2018-10-23 + +### Fixed +- GStreamerFilter: Allow using the 'textoverlay' filter. + +## [6.8.0] - 2018-09-26 + +### Added +- Hub, HubPort: Add support for DATA streams + +### Changed +- Use kms_utils_element_factory_make() for better element names in debug graphs +- ModuleManager: Review startup logging messages + +### Fixed +- Agnosticbin: Send TRANSCODING signals only once +- [#144](https://github.com/Kurento/bugtracker/issues/144) AgnosticBin: FIXME Reconfigure pipeline +- BaseRtpSession: Fix memory leaks +- MediaSet: Fix unreleased memory on object unref + +## [6.7.2] - 2018-05-11 + +### Added +- KmsBaseRtpEndpoint: New property "offer-dir", which allows to specify the SDP Offer direction when it gets generated by KMS. +- KmsBaseRtpEndpoint: Don't reduce RTCP interval if REMB is not used. + +### Fixed +- All: Apply multiple fixes suggested by *clang-tidy*. +- [#241](https://github.com/Kurento/bugtracker/issues/241) (Add 'a=setup' to SDP Offers). ## [6.7.1] - 2018-03-21 @@ -17,7 +47,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [6.7.0] - 2018-01-24 ### Changed -- CMake: Compile and link as Position Independent Code ('-fPIC'). +- CMake: Compile and link as Position Independent Code (`fPIC`). - Add more verbose logging in some areas that required it. - Debian: Align all version numbers of KMS-related modules. - Debian: Remove version numbers from package names. @@ -25,17 +55,17 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Fixed - Reset stats after RTP source gets reconnected. The RTP sources assume a starting point of 0, so KMS must also adjust its own status after a reconnection. -- Fix [#197](https://github.com/Kurento/bugtracker/issues/197) (Composite Hub making audio choppy) with [#9](https://github.com/Kurento/kms-core/pull/9) (fix composite: kmsenctreebin.c use max-size-time instead of max-size-buffers), by @ruddell (Jon Ruddell). +- [#197](https://github.com/Kurento/bugtracker/issues/197) (Composite Hub making audio choppy) with [PR#9](https://github.com/Kurento/kms-core/pull/9) (kmsenctreebin.c use max-size-time instead of max-size-buffers), by [@ruddell](https://github.com/ruddell) (Jon Ruddell). ## [6.6.3] - 2017-08-10 ### Changed -- Prevent frames from building up in the buffer if the CPU falls behind, by @kc7bfi (David Robison). +- [PR#7](https://github.com/Kurento/kms-core/pull/7) (Prevent frames from building up in the buffer if the CPU falls behind), by [@kc7bfi](https://github.com/kc7bfi) (David Robison). ## [6.6.2] - 2017-07-24 ### Added -- REMB: Add "COMEDIA"/automatic port discovery. [Documentation](http://doc-kurento.readthedocs.io/en/latest/features/nat_traversal.html#rtp-without-ice). +- REMB: Add "COMEDIA"/automatic port discovery. [Documentation](https://doc-kurento.readthedocs.io/en/latest/features/nat_traversal.html#rtp-without-ice). - REMB: Enable for RTP connections. Previously, it would only work for WebRTC. ### Changed @@ -50,7 +80,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Fixed - Bugfix: Out of bound access on SDP medias. -- Use format macros to fix compiler errors on 32bit systems, by @fancycode (Joachim Bauch). +- [PR#5](https://github.com/Kurento/kms-core/pull/5) (Use format macros to fix compiler errors on 32bit systems), by [@fancycode](https://github.com/fancycode) (Joachim Bauch). - When a non incremental PTS is discovered in an input stream, the internal DTS gets updated with the new PTS value. ## [6.6.1] - 2016-09-30 @@ -160,6 +190,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - MediaElement: Fix error notification mechanisms. Errors where not raising in most cases. - Improvements in format negotiations between elements, this fixes problems in RecorderEndpoint and Composite. +[6.8.1]: https://github.com/Kurento/kms-core/compare/6.8.0...6.8.1 +[6.8.0]: https://github.com/Kurento/kms-core/compare/6.7.2...6.8.0 +[6.7.2]: https://github.com/Kurento/kms-core/compare/6.7.1...6.7.2 [6.7.1]: https://github.com/Kurento/kms-core/compare/6.7.0...6.7.1 [6.7.0]: https://github.com/Kurento/kms-core/compare/6.6.3...6.7.0 [6.6.3]: https://github.com/Kurento/kms-core/compare/6.6.2...6.6.3 diff --git a/CMakeLists.txt b/CMakeLists.txt index a910b4509..0c36dcffe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,19 +24,10 @@ message(STATUS "Project version: ${PROJECT_NAME}-${PROJECT_VERSION}") # Compiler flags include(CommonBuildFlags) common_buildflags_set() +#common_buildflags_print() -#message("CMAKE_C_FLAGS: ${CMAKE_C_FLAGS}") -#message("CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}") -#message("CMAKE_STATIC_LINKER_FLAGS: ${CMAKE_STATIC_LINKER_FLAGS}") -#message("CMAKE_SHARED_LINKER_FLAGS: ${CMAKE_SHARED_LINKER_FLAGS}") -#message("CMAKE_MODULE_LINKER_FLAGS: ${CMAKE_MODULE_LINKER_FLAGS}") -#message("CMAKE_EXE_LINKER_FLAGS: ${CMAKE_EXE_LINKER_FLAGS}") -#message("CMAKE_C_FLAGS_DEBUG: ${CMAKE_C_FLAGS_DEBUG}") -#message("CMAKE_CXX_FLAGS_DEBUG: ${CMAKE_CXX_FLAGS_DEBUG}") -#message("CMAKE_STATIC_LINKER_FLAGS_DEBUG: ${CMAKE_STATIC_LINKER_FLAGS_DEBUG}") -#message("CMAKE_SHARED_LINKER_FLAGS_DEBUG: ${CMAKE_SHARED_LINKER_FLAGS_DEBUG}") -#message("CMAKE_MODULE_LINKER_FLAGS_DEBUG: ${CMAKE_MODULE_LINKER_FLAGS_DEBUG}") -#message("CMAKE_EXE_LINKER_FLAGS_DEBUG: ${CMAKE_EXE_LINKER_FLAGS_DEBUG}") +# Development: Exceptions to "Warnings are Errors" rule +#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-error=unused-function") # FIXME Disable error when macros __TIME__, __DATE__ or __TIMESTAMP__ are encountered include(CheckCXXCompilerFlag) @@ -45,6 +36,9 @@ if(HAS_WARNING_DATE_TIME) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=date-time") endif() +# Development +#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-error=unused-function") + # Decide between std::regex or boost::regex include(CheckCXXSourceCompiles) set(CMAKE_REQUIRED_FLAGS ${CMAKE_CXX_FLAGS}) diff --git a/debian/changelog b/debian/changelog index b943fdac8..a5e9f1023 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,30 @@ +kms-core (6.8.1) testing; urgency=medium + + * Prepare release 6.8.1 + + -- Juan Navarro Moreno Tue, 23 Oct 2018 16:23:46 +0200 + +kms-core (6.8.0) testing; urgency=medium + + * debian/rules: Remove 'override_dh_auto_test' + * Prepare release 6.8.0 + + -- Juan Navarro Moreno Wed, 26 Sep 2018 11:30:00 +0200 + +kms-core (6.7.3) testing; urgency=medium + + [ Juan Navarro Moreno ] + * Prepare release 6.7.2 + + -- Juan Navarro Moreno Fri, 27 Jul 2018 10:20:30 +0100 + +kms-core (6.7.2) testing; urgency=medium + + [ Juan Navarro Moreno ] + * Prepare release 6.7.2 + + -- Juan Navarro Moreno Fri, 11 May 2018 10:20:30 +0100 + kms-core (6.7.1) testing; urgency=medium [ Juan Navarro Moreno ] diff --git a/debian/rules b/debian/rules index 17da1ec3d..abd65c6be 100755 --- a/debian/rules +++ b/debian/rules @@ -14,6 +14,3 @@ override_dh_auto_configure: override_dh_strip: dh_strip --dbg-package=kms-core-dbg - -override_dh_auto_test: - dh_auto_build -- check ARGS=-j10 diff --git a/src/gst-plugins/commons/constants.h b/src/gst-plugins/commons/constants.h index fc2b388a4..b6967eb83 100644 --- a/src/gst-plugins/commons/constants.h +++ b/src/gst-plugins/commons/constants.h @@ -17,8 +17,6 @@ #ifndef __KMS_CONSTANTS_H__ #define __KMS_CONSTANTS_H__ -G_BEGIN_DECLS - #define SDP_MEDIA_RTCP_FB "rtcp-fb" #define SDP_MEDIA_RTCP_FB_NACK "nack" #define SDP_MEDIA_RTCP_FB_CCM "ccm" @@ -35,8 +33,6 @@ G_BEGIN_DECLS #define SDP_MEDIA_RTP_AVP_PROTO "RTP/AVP" #define SDP_MEDIA_RTP_SAVPF_PROTO "RTP/SAVPF" -#define RTCP_MUX "rtcp-mux" - #define RTCP_MIN_INTERVAL 500 /* ms */ #define REMB_MAX_INTERVAL 200 /* ms */ #define RTP_RTX_SIZE 512 /* packets */ @@ -77,5 +73,4 @@ G_BEGIN_DECLS #define OPUS_ENCONDING_NAME "OPUS" #define VP8_ENCONDING_NAME "VP8" -G_END_DECLS #endif /* __KMS_CONSTANTS_H__ */ diff --git a/src/gst-plugins/commons/kmsbasehub.c b/src/gst-plugins/commons/kmsbasehub.c index b9ba17a81..37708b7e7 100644 --- a/src/gst-plugins/commons/kmsbasehub.c +++ b/src/gst-plugins/commons/kmsbasehub.c @@ -19,6 +19,7 @@ #endif #include "kmsbasehub.h" +#include "constants.h" #include "kmsagnosticcaps.h" #include "kms-core-marshal.h" #include "kmshubport.h" @@ -44,42 +45,56 @@ GST_DEBUG_CATEGORY_STATIC (kms_base_hub_debug_category); #define AUDIO_SINK_PAD_PREFIX "audio_sink_" #define VIDEO_SINK_PAD_PREFIX "video_sink_" -#define AUDIO_SRC_PAD_PREFIX "audio_src_" -#define VIDEO_SRC_PAD_PREFIX "video_src_" +#define DATA_SINK_PAD_PREFIX "data_sink_" #define AUDIO_SINK_PAD_NAME AUDIO_SINK_PAD_PREFIX "%u" #define VIDEO_SINK_PAD_NAME VIDEO_SINK_PAD_PREFIX "%u" +#define DATA_SINK_PAD_NAME DATA_SINK_PAD_PREFIX "%u" + +#define AUDIO_SRC_PAD_PREFIX "audio_src_" +#define VIDEO_SRC_PAD_PREFIX "video_src_" +#define DATA_SRC_PAD_PREFIX "data_src_" +#define LENGTH_AUDIO_SRC_PAD_PREFIX 10 // sizeof("audio_src_") +#define LENGTH_VIDEO_SRC_PAD_PREFIX 10 // sizeof("video_src_") +#define LENGTH_DATA_SRC_PAD_PREFIX 9 // sizeof("data_src_") #define AUDIO_SRC_PAD_NAME AUDIO_SRC_PAD_PREFIX "%u" #define VIDEO_SRC_PAD_NAME VIDEO_SRC_PAD_PREFIX "%u" -#define LENGTH_VIDEO_SRC_PAD_PREFIX 10 //sizeof("video_src_") -#define LENGTH_AUDIO_SRC_PAD_PREFIX 10 //sizeof("audio_src_") +#define DATA_SRC_PAD_NAME DATA_SRC_PAD_PREFIX "%u" static GstStaticPadTemplate audio_sink_factory = GST_STATIC_PAD_TEMPLATE (AUDIO_SINK_PAD_NAME, GST_PAD_SINK, GST_PAD_SOMETIMES, - GST_STATIC_CAPS (KMS_AGNOSTIC_AUDIO_CAPS) - ); + GST_STATIC_CAPS (KMS_AGNOSTIC_AUDIO_CAPS)); static GstStaticPadTemplate video_sink_factory = GST_STATIC_PAD_TEMPLATE (VIDEO_SINK_PAD_NAME, GST_PAD_SINK, GST_PAD_SOMETIMES, - GST_STATIC_CAPS (KMS_AGNOSTIC_VIDEO_CAPS) - ); + GST_STATIC_CAPS (KMS_AGNOSTIC_VIDEO_CAPS)); + +static GstStaticPadTemplate data_sink_factory = +GST_STATIC_PAD_TEMPLATE (DATA_SINK_PAD_NAME, + GST_PAD_SINK, + GST_PAD_SOMETIMES, + GST_STATIC_CAPS (KMS_AGNOSTIC_DATA_CAPS)); static GstStaticPadTemplate audio_src_factory = GST_STATIC_PAD_TEMPLATE (AUDIO_SRC_PAD_NAME, GST_PAD_SRC, GST_PAD_SOMETIMES, - GST_STATIC_CAPS (KMS_AGNOSTIC_AUDIO_CAPS) - ); + GST_STATIC_CAPS (KMS_AGNOSTIC_AUDIO_CAPS)); static GstStaticPadTemplate video_src_factory = GST_STATIC_PAD_TEMPLATE (VIDEO_SRC_PAD_NAME, GST_PAD_SRC, GST_PAD_SOMETIMES, - GST_STATIC_CAPS (KMS_AGNOSTIC_VIDEO_CAPS) - ); + GST_STATIC_CAPS (KMS_AGNOSTIC_VIDEO_CAPS)); + +static GstStaticPadTemplate data_src_factory = +GST_STATIC_PAD_TEMPLATE (DATA_SRC_PAD_NAME, + GST_PAD_SRC, + GST_PAD_SOMETIMES, + GST_STATIC_CAPS (KMS_AGNOSTIC_DATA_CAPS)); enum { @@ -108,6 +123,7 @@ struct _KmsBaseHubPortData gint id; GstPad *audio_sink_target; GstPad *video_sink_target; + GstPad *data_sink_target; }; /* class initialization */ @@ -167,95 +183,142 @@ kms_base_hub_port_data_destroy (gpointer data) g_clear_object (&port_data->audio_sink_target); g_clear_object (&port_data->video_sink_target); + g_clear_object (&port_data->data_sink_target); g_clear_object (&port_data->port); g_slice_free (KmsBaseHubPortData, data); } gboolean -kms_base_hub_link_video_src (KmsBaseHub * hub, gint id, +kms_base_hub_link_audio_sink (KmsBaseHub * self, gint id, + GstElement * internal_element, const gchar * pad_name, + gboolean remove_on_unlink) +{ + g_return_val_if_fail (KMS_IS_BASE_HUB (self), FALSE); + + return + KMS_BASE_HUB_CLASS (G_OBJECT_GET_CLASS (self))->link_audio_sink (self, + id, internal_element, pad_name, remove_on_unlink); +} + +gboolean +kms_base_hub_link_video_sink (KmsBaseHub * self, gint id, + GstElement * internal_element, const gchar * pad_name, + gboolean remove_on_unlink) +{ + g_return_val_if_fail (KMS_IS_BASE_HUB (self), FALSE); + + return + KMS_BASE_HUB_CLASS (G_OBJECT_GET_CLASS (self))->link_video_sink (self, + id, internal_element, pad_name, remove_on_unlink); +} + +gboolean +kms_base_hub_link_data_sink (KmsBaseHub * self, gint id, GstElement * internal_element, const gchar * pad_name, gboolean remove_on_unlink) { - g_return_val_if_fail (KMS_IS_BASE_HUB (hub), FALSE); + g_return_val_if_fail (KMS_IS_BASE_HUB (self), FALSE); return - KMS_BASE_HUB_CLASS (G_OBJECT_GET_CLASS (hub))->link_video_src (hub, + KMS_BASE_HUB_CLASS (G_OBJECT_GET_CLASS (self))->link_data_sink (self, id, internal_element, pad_name, remove_on_unlink); } gboolean -kms_base_hub_link_audio_src (KmsBaseHub * hub, gint id, +kms_base_hub_link_audio_src (KmsBaseHub * self, gint id, GstElement * internal_element, const gchar * pad_name, gboolean remove_on_unlink) { - g_return_val_if_fail (KMS_IS_BASE_HUB (hub), FALSE); + g_return_val_if_fail (KMS_IS_BASE_HUB (self), FALSE); return - KMS_BASE_HUB_CLASS (G_OBJECT_GET_CLASS (hub))->link_audio_src (hub, + KMS_BASE_HUB_CLASS (G_OBJECT_GET_CLASS (self))->link_audio_src (self, id, internal_element, pad_name, remove_on_unlink); } gboolean -kms_base_hub_link_video_sink (KmsBaseHub * hub, gint id, +kms_base_hub_link_video_src (KmsBaseHub * self, gint id, GstElement * internal_element, const gchar * pad_name, gboolean remove_on_unlink) { - g_return_val_if_fail (KMS_IS_BASE_HUB (hub), FALSE); + g_return_val_if_fail (KMS_IS_BASE_HUB (self), FALSE); return - KMS_BASE_HUB_CLASS (G_OBJECT_GET_CLASS (hub))->link_video_sink (hub, + KMS_BASE_HUB_CLASS (G_OBJECT_GET_CLASS (self))->link_video_src (self, id, internal_element, pad_name, remove_on_unlink); } gboolean -kms_base_hub_link_audio_sink (KmsBaseHub * hub, gint id, +kms_base_hub_link_data_src (KmsBaseHub * self, gint id, GstElement * internal_element, const gchar * pad_name, gboolean remove_on_unlink) { - g_return_val_if_fail (KMS_IS_BASE_HUB (hub), FALSE); + g_return_val_if_fail (KMS_IS_BASE_HUB (self), FALSE); return - KMS_BASE_HUB_CLASS (G_OBJECT_GET_CLASS (hub))->link_audio_sink (hub, + KMS_BASE_HUB_CLASS (G_OBJECT_GET_CLASS (self))->link_data_src (self, id, internal_element, pad_name, remove_on_unlink); } gboolean -kms_base_hub_unlink_video_src (KmsBaseHub * hub, gint id) +kms_base_hub_unlink_audio_sink (KmsBaseHub * self, gint id) { - g_return_val_if_fail (KMS_IS_BASE_HUB (hub), FALSE); + g_return_val_if_fail (KMS_IS_BASE_HUB (self), FALSE); return - KMS_BASE_HUB_CLASS (G_OBJECT_GET_CLASS (hub))->unlink_video_src (hub, id); + KMS_BASE_HUB_CLASS (G_OBJECT_GET_CLASS (self))->unlink_audio_sink + (self, id); } gboolean -kms_base_hub_unlink_audio_src (KmsBaseHub * hub, gint id) +kms_base_hub_unlink_video_sink (KmsBaseHub * self, gint id) { - g_return_val_if_fail (KMS_IS_BASE_HUB (hub), FALSE); + g_return_val_if_fail (KMS_IS_BASE_HUB (self), FALSE); return - KMS_BASE_HUB_CLASS (G_OBJECT_GET_CLASS (hub))->unlink_audio_src (hub, id); + KMS_BASE_HUB_CLASS (G_OBJECT_GET_CLASS (self))->unlink_video_sink + (self, id); } gboolean -kms_base_hub_unlink_video_sink (KmsBaseHub * hub, gint id) +kms_base_hub_unlink_data_sink (KmsBaseHub * self, gint id) { - g_return_val_if_fail (KMS_IS_BASE_HUB (hub), FALSE); + g_return_val_if_fail (KMS_IS_BASE_HUB (self), FALSE); return - KMS_BASE_HUB_CLASS (G_OBJECT_GET_CLASS (hub))->unlink_video_sink - (hub, id); + KMS_BASE_HUB_CLASS (G_OBJECT_GET_CLASS (self))->unlink_data_sink + (self, id); } gboolean -kms_base_hub_unlink_audio_sink (KmsBaseHub * hub, gint id) +kms_base_hub_unlink_audio_src (KmsBaseHub * self, gint id) { - g_return_val_if_fail (KMS_IS_BASE_HUB (hub), FALSE); + g_return_val_if_fail (KMS_IS_BASE_HUB (self), FALSE); return - KMS_BASE_HUB_CLASS (G_OBJECT_GET_CLASS (hub))->unlink_audio_sink - (hub, id); + KMS_BASE_HUB_CLASS (G_OBJECT_GET_CLASS (self))->unlink_audio_src (self, + id); +} + +gboolean +kms_base_hub_unlink_video_src (KmsBaseHub * self, gint id) +{ + g_return_val_if_fail (KMS_IS_BASE_HUB (self), FALSE); + + return + KMS_BASE_HUB_CLASS (G_OBJECT_GET_CLASS (self))->unlink_video_src (self, + id); +} + +gboolean +kms_base_hub_unlink_data_src (KmsBaseHub * self, gint id) +{ + g_return_val_if_fail (KMS_IS_BASE_HUB (self), FALSE); + + return + KMS_BASE_HUB_CLASS (G_OBJECT_GET_CLASS (self))->unlink_data_src (self, + id); } static void @@ -282,12 +345,12 @@ kms_base_hub_unlink_pad (KmsBaseHub * hub, const gchar * gp_name) } static gboolean -kms_base_hub_unlink_video_src_default (KmsBaseHub * hub, gint id) +kms_base_hub_unlink_audio_sink_default (KmsBaseHub * self, gint id) { gboolean ret; - gchar *gp_name = g_strdup_printf (VIDEO_SRC_PAD_PREFIX "%d", id); + gchar *gp_name = g_strdup_printf (AUDIO_SINK_PAD_PREFIX "%d", id); - ret = kms_base_hub_unlink_pad (hub, gp_name); + ret = kms_base_hub_unlink_pad (self, gp_name); g_free (gp_name); @@ -295,12 +358,38 @@ kms_base_hub_unlink_video_src_default (KmsBaseHub * hub, gint id) } static gboolean -kms_base_hub_unlink_audio_src_default (KmsBaseHub * hub, gint id) +kms_base_hub_unlink_video_sink_default (KmsBaseHub * self, gint id) +{ + gboolean ret; + gchar *gp_name = g_strdup_printf (VIDEO_SINK_PAD_PREFIX "%d", id); + + ret = kms_base_hub_unlink_pad (self, gp_name); + + g_free (gp_name); + + return ret; +} + +static gboolean +kms_base_hub_unlink_data_sink_default (KmsBaseHub * self, gint id) +{ + gboolean ret; + gchar *gp_name = g_strdup_printf (DATA_SINK_PAD_PREFIX "%d", id); + + ret = kms_base_hub_unlink_pad (self, gp_name); + + g_free (gp_name); + + return ret; +} + +static gboolean +kms_base_hub_unlink_audio_src_default (KmsBaseHub * self, gint id) { gboolean ret; gchar *gp_name = g_strdup_printf (AUDIO_SRC_PAD_PREFIX "%d", id); - ret = kms_base_hub_unlink_pad (hub, gp_name); + ret = kms_base_hub_unlink_pad (self, gp_name); g_free (gp_name); @@ -308,12 +397,12 @@ kms_base_hub_unlink_audio_src_default (KmsBaseHub * hub, gint id) } static gboolean -kms_base_hub_unlink_video_sink_default (KmsBaseHub * hub, gint id) +kms_base_hub_unlink_video_src_default (KmsBaseHub * self, gint id) { gboolean ret; - gchar *gp_name = g_strdup_printf (VIDEO_SINK_PAD_PREFIX "%d", id); + gchar *gp_name = g_strdup_printf (VIDEO_SRC_PAD_PREFIX "%d", id); - ret = kms_base_hub_unlink_pad (hub, gp_name); + ret = kms_base_hub_unlink_pad (self, gp_name); g_free (gp_name); @@ -321,12 +410,12 @@ kms_base_hub_unlink_video_sink_default (KmsBaseHub * hub, gint id) } static gboolean -kms_base_hub_unlink_audio_sink_default (KmsBaseHub * hub, gint id) +kms_base_hub_unlink_data_src_default (KmsBaseHub * self, gint id) { gboolean ret; - gchar *gp_name = g_strdup_printf (AUDIO_SINK_PAD_PREFIX "%d", id); + gchar *gp_name = g_strdup_printf (DATA_SRC_PAD_PREFIX "%d", id); - ret = kms_base_hub_unlink_pad (hub, gp_name); + ret = kms_base_hub_unlink_pad (self, gp_name); g_free (gp_name); @@ -361,100 +450,6 @@ remove_target_cb (GstPad * pad, GstPad * peer, gpointer data) gst_ghost_pad_set_target (GST_GHOST_PAD (pad), NULL); } -static gboolean -kms_base_hub_link_src_pad (KmsBaseHub * hub, const gchar * gp_name, - const gchar * template_name, GstElement * internal_element, - const gchar * pad_name, gboolean remove_on_unlink) -{ - GstPad *gp, *target; - gboolean ret; - - if (GST_OBJECT_PARENT (internal_element) != GST_OBJECT (hub)) { - GST_ERROR_OBJECT (hub, "Cannot link %" GST_PTR_FORMAT " wrong hierarchy", - internal_element); - return FALSE; - } - - target = gst_element_get_static_pad (internal_element, pad_name); - if (target == NULL) { - target = gst_element_get_request_pad (internal_element, pad_name); - - if (target != NULL && remove_on_unlink) { - g_signal_connect (G_OBJECT (target), "unlinked", - G_CALLBACK (remove_unlinked_pad), NULL); - } - } - - if (target == NULL) { - GST_ERROR_OBJECT (hub, "Cannot get target pad"); - return FALSE; - } - - gp = gst_element_get_static_pad (GST_ELEMENT (hub), gp_name); - - if (gp == NULL) { - GstPadTemplate *templ; - - templ = - gst_element_class_get_pad_template (GST_ELEMENT_CLASS - (G_OBJECT_GET_CLASS (hub)), template_name); - gp = gst_ghost_pad_new_no_target_from_template (gp_name, templ); - g_signal_connect_object (gp, "linked", G_CALLBACK (set_target_cb), target, - 0); - g_signal_connect (gp, "unlinked", G_CALLBACK (remove_target_cb), NULL); - - if (GST_STATE (hub) >= GST_STATE_PAUSED - || GST_STATE_PENDING (hub) >= GST_STATE_PAUSED - || GST_STATE_TARGET (hub) >= GST_STATE_PAUSED) { - gst_pad_set_active (gp, TRUE); - } - - ret = gst_element_add_pad (GST_ELEMENT (hub), gp); - if (!ret) { - g_object_unref (gp); - } - } else { - ret = set_target (gp, target); - g_object_unref (gp); - } - - g_object_unref (target); - - return ret; -} - -static gboolean -kms_base_hub_link_audio_src_default (KmsBaseHub * hub, gint id, - GstElement * internal_element, const gchar * pad_name, - gboolean remove_on_unlink) -{ - gchar *gp_name = g_strdup_printf (AUDIO_SRC_PAD_PREFIX "%d", id); - gboolean ret; - - ret = - kms_base_hub_link_src_pad (hub, gp_name, AUDIO_SRC_PAD_NAME, - internal_element, pad_name, remove_on_unlink); - g_free (gp_name); - - return ret; -} - -static gboolean -kms_base_hub_link_video_src_default (KmsBaseHub * hub, gint id, - GstElement * internal_element, const gchar * pad_name, - gboolean remove_on_unlink) -{ - gchar *gp_name = g_strdup_printf (VIDEO_SRC_PAD_PREFIX "%d", id); - gboolean ret; - - ret = - kms_base_hub_link_src_pad (hub, gp_name, VIDEO_SRC_PAD_NAME, - internal_element, pad_name, remove_on_unlink); - g_free (gp_name); - - return ret; -} - static gboolean kms_base_hub_create_and_link_ghost_pad (KmsBaseHub * hub, GstPad * src_pad, const gchar * gp_name, const gchar * gp_template_name, @@ -555,6 +550,8 @@ kms_base_hub_link_sink_pad (KmsBaseHub * hub, gint id, port_data->id, port_data->audio_sink_target); GST_DEBUG_OBJECT (hub, "Video target pad for port %d: %" GST_PTR_FORMAT, port_data->id, port_data->video_sink_target); + GST_DEBUG_OBJECT (hub, "Data target pad for port %d: %" GST_PTR_FORMAT, + port_data->id, port_data->data_sink_target); end: @@ -566,14 +563,32 @@ kms_base_hub_link_sink_pad (KmsBaseHub * hub, gint id, } static gboolean -kms_base_hub_link_video_sink_default (KmsBaseHub * hub, gint id, +kms_base_hub_link_audio_sink_default (KmsBaseHub * self, gint id, + GstElement * internal_element, const gchar * pad_name, + gboolean remove_on_unlink) +{ + gboolean ret; + gchar *gp_name = g_strdup_printf (AUDIO_SINK_PAD_PREFIX "%d", id); + + ret = kms_base_hub_link_sink_pad (self, id, gp_name, AUDIO_SINK_PAD_NAME, + internal_element, pad_name, HUB_AUDIO_SRC_PAD, + G_STRUCT_OFFSET (KmsBaseHubPortData, audio_sink_target), + remove_on_unlink); + + g_free (gp_name); + + return ret; +} + +static gboolean +kms_base_hub_link_video_sink_default (KmsBaseHub * self, gint id, GstElement * internal_element, const gchar * pad_name, gboolean remove_on_unlink) { gboolean ret; gchar *gp_name = g_strdup_printf (VIDEO_SINK_PAD_PREFIX "%d", id); - ret = kms_base_hub_link_sink_pad (hub, id, gp_name, VIDEO_SINK_PAD_NAME, + ret = kms_base_hub_link_sink_pad (self, id, gp_name, VIDEO_SINK_PAD_NAME, internal_element, pad_name, HUB_VIDEO_SRC_PAD, G_STRUCT_OFFSET (KmsBaseHubPortData, video_sink_target), remove_on_unlink); @@ -584,16 +599,16 @@ kms_base_hub_link_video_sink_default (KmsBaseHub * hub, gint id, } static gboolean -kms_base_hub_link_audio_sink_default (KmsBaseHub * hub, gint id, +kms_base_hub_link_data_sink_default (KmsBaseHub * self, gint id, GstElement * internal_element, const gchar * pad_name, gboolean remove_on_unlink) { gboolean ret; - gchar *gp_name = g_strdup_printf (AUDIO_SINK_PAD_PREFIX "%d", id); + gchar *gp_name = g_strdup_printf (DATA_SINK_PAD_PREFIX "%d", id); - ret = kms_base_hub_link_sink_pad (hub, id, gp_name, AUDIO_SINK_PAD_NAME, - internal_element, pad_name, HUB_AUDIO_SRC_PAD, - G_STRUCT_OFFSET (KmsBaseHubPortData, audio_sink_target), + ret = kms_base_hub_link_sink_pad (self, id, gp_name, DATA_SINK_PAD_NAME, + internal_element, pad_name, HUB_DATA_SRC_PAD, + G_STRUCT_OFFSET (KmsBaseHubPortData, data_sink_target), remove_on_unlink); g_free (gp_name); @@ -601,6 +616,116 @@ kms_base_hub_link_audio_sink_default (KmsBaseHub * hub, gint id, return ret; } +static gboolean +kms_base_hub_link_src_pad (KmsBaseHub * self, const gchar * gp_name, + const gchar * template_name, GstElement * internal_element, + const gchar * pad_name, gboolean remove_on_unlink) +{ + GstPad *gp, *target; + gboolean ret; + + if (GST_OBJECT_PARENT (internal_element) != GST_OBJECT (self)) { + GST_ERROR_OBJECT (self, "Cannot link %" GST_PTR_FORMAT " wrong hierarchy", + internal_element); + return FALSE; + } + + target = gst_element_get_static_pad (internal_element, pad_name); + if (target == NULL) { + target = gst_element_get_request_pad (internal_element, pad_name); + + if (target != NULL && remove_on_unlink) { + g_signal_connect (G_OBJECT (target), "unlinked", + G_CALLBACK (remove_unlinked_pad), NULL); + } + } + + if (target == NULL) { + GST_ERROR_OBJECT (self, "Cannot get target pad"); + return FALSE; + } + + gp = gst_element_get_static_pad (GST_ELEMENT (self), gp_name); + + if (gp == NULL) { + GstPadTemplate *templ; + + templ = + gst_element_class_get_pad_template (GST_ELEMENT_CLASS + (G_OBJECT_GET_CLASS (self)), template_name); + gp = gst_ghost_pad_new_no_target_from_template (gp_name, templ); + g_signal_connect_object (gp, "linked", G_CALLBACK (set_target_cb), target, + 0); + g_signal_connect (gp, "unlinked", G_CALLBACK (remove_target_cb), NULL); + + if (GST_STATE (self) >= GST_STATE_PAUSED + || GST_STATE_PENDING (self) >= GST_STATE_PAUSED + || GST_STATE_TARGET (self) >= GST_STATE_PAUSED) { + gst_pad_set_active (gp, TRUE); + } + + ret = gst_element_add_pad (GST_ELEMENT (self), gp); + if (!ret) { + g_object_unref (gp); + } + } else { + ret = set_target (gp, target); + g_object_unref (gp); + } + + g_object_unref (target); + + return ret; +} + +static gboolean +kms_base_hub_link_audio_src_default (KmsBaseHub * self, gint id, + GstElement * internal_element, const gchar * pad_name, + gboolean remove_on_unlink) +{ + gchar *gp_name = g_strdup_printf (AUDIO_SRC_PAD_PREFIX "%d", id); + gboolean ret; + + ret = + kms_base_hub_link_src_pad (self, gp_name, AUDIO_SRC_PAD_NAME, + internal_element, pad_name, remove_on_unlink); + g_free (gp_name); + + return ret; +} + +static gboolean +kms_base_hub_link_video_src_default (KmsBaseHub * self, gint id, + GstElement * internal_element, const gchar * pad_name, + gboolean remove_on_unlink) +{ + gchar *gp_name = g_strdup_printf (VIDEO_SRC_PAD_PREFIX "%d", id); + gboolean ret; + + ret = + kms_base_hub_link_src_pad (self, gp_name, VIDEO_SRC_PAD_NAME, + internal_element, pad_name, remove_on_unlink); + g_free (gp_name); + + return ret; +} + +static gboolean +kms_base_hub_link_data_src_default (KmsBaseHub * self, gint id, + GstElement * internal_element, const gchar * pad_name, + gboolean remove_on_unlink) +{ + gchar *gp_name = g_strdup_printf (DATA_SRC_PAD_PREFIX "%d", id); + gboolean ret; + + ret = + kms_base_hub_link_src_pad (self, gp_name, DATA_SRC_PAD_NAME, + internal_element, pad_name, remove_on_unlink); + g_free (gp_name); + + return ret; +} + static void kms_base_hub_remove_port_pad (KmsBaseHub * hub, gint id, const gchar * pad_prefix) @@ -622,22 +747,22 @@ kms_base_hub_remove_port_pad (KmsBaseHub * hub, gint id, static void kms_base_hub_remove_port_pads (KmsBaseHub * hub, gint id) { - kms_base_hub_remove_port_pad (hub, id, AUDIO_SRC_PAD_PREFIX); kms_base_hub_remove_port_pad (hub, id, AUDIO_SINK_PAD_PREFIX); - kms_base_hub_remove_port_pad (hub, id, VIDEO_SRC_PAD_PREFIX); + kms_base_hub_remove_port_pad (hub, id, AUDIO_SRC_PAD_PREFIX); kms_base_hub_remove_port_pad (hub, id, VIDEO_SINK_PAD_PREFIX); + kms_base_hub_remove_port_pad (hub, id, VIDEO_SRC_PAD_PREFIX); } static void -kms_base_hub_unhandle_port (KmsBaseHub * hub, gint id) +kms_base_hub_unhandle_port (KmsBaseHub * self, gint id) { KmsBaseHubPortData *port_data; - GST_DEBUG_OBJECT (hub, "Unhandle port %" G_GINT32_FORMAT, id); + GST_DEBUG_OBJECT (self, "Unhandle port %" G_GINT32_FORMAT, id); - KMS_BASE_HUB_LOCK (hub); + KMS_BASE_HUB_LOCK (self); - port_data = (KmsBaseHubPortData *) g_hash_table_lookup (hub->priv->ports, + port_data = (KmsBaseHubPortData *) g_hash_table_lookup (self->priv->ports, &id); if (port_data == NULL) { @@ -647,12 +772,12 @@ kms_base_hub_unhandle_port (KmsBaseHub * hub, gint id) GST_DEBUG ("Removing element: %" GST_PTR_FORMAT, port_data->port); kms_hub_port_unhandled (KMS_HUB_PORT (port_data->port)); - kms_base_hub_remove_port_pads (hub, id); + kms_base_hub_remove_port_pads (self, id); - g_hash_table_remove (hub->priv->ports, &id); + g_hash_table_remove (self->priv->ports, &id); end: - KMS_BASE_HUB_UNLOCK (hub); + KMS_BASE_HUB_UNLOCK (self); } static gint * @@ -667,13 +792,13 @@ kms_base_hub_generate_port_id (KmsBaseHub * hub) } static void -hub_pad_added (KmsBaseHub * hub, GstPad * pad, gpointer data) +kms_base_hub_pad_added (KmsBaseHub * self, GstPad * pad, gpointer data) { if (gst_pad_get_direction (pad) != GST_PAD_SRC) { return; } - KMS_BASE_HUB_LOCK (hub); + KMS_BASE_HUB_LOCK (self); if (g_str_has_prefix (GST_OBJECT_NAME (pad), VIDEO_SRC_PAD_PREFIX)) { KmsBaseHubPortData *port; @@ -682,24 +807,37 @@ hub_pad_added (KmsBaseHub * hub, GstPad * pad, gpointer data) pad_name = GST_OBJECT_NAME (pad); id = g_ascii_strtoll (pad_name + LENGTH_VIDEO_SRC_PAD_PREFIX, NULL, 10); - port = g_hash_table_lookup (hub->priv->ports, &id); + port = g_hash_table_lookup (self->priv->ports, &id); - gst_element_link_pads (GST_ELEMENT (hub), GST_OBJECT_NAME (pad), - port->port, "hub_video_sink"); - } else if (g_str_has_prefix (GST_OBJECT_NAME (pad), AUDIO_SRC_PAD_PREFIX)) { + gst_element_link_pads (GST_ELEMENT (self), GST_OBJECT_NAME (pad), + port->port, HUB_VIDEO_SINK_PAD); + } + else if (g_str_has_prefix (GST_OBJECT_NAME (pad), AUDIO_SRC_PAD_PREFIX)) { KmsBaseHubPortData *port; gint64 id; const gchar *pad_name; pad_name = GST_OBJECT_NAME (pad); id = g_ascii_strtoll (pad_name + LENGTH_AUDIO_SRC_PAD_PREFIX, NULL, 10); - port = g_hash_table_lookup (hub->priv->ports, &id); + port = g_hash_table_lookup (self->priv->ports, &id); - gst_element_link_pads (GST_ELEMENT (hub), GST_OBJECT_NAME (pad), - port->port, "hub_audio_sink"); + gst_element_link_pads (GST_ELEMENT (self), GST_OBJECT_NAME (pad), + port->port, HUB_AUDIO_SINK_PAD); } + else if (g_str_has_prefix (GST_OBJECT_NAME (pad), DATA_SRC_PAD_PREFIX)) { + KmsBaseHubPortData *port; + gint64 id; + const gchar *pad_name; - KMS_BASE_HUB_UNLOCK (hub); + pad_name = GST_OBJECT_NAME (pad); + id = g_ascii_strtoll (pad_name + LENGTH_DATA_SRC_PAD_PREFIX, NULL, 10); + port = g_hash_table_lookup (self->priv->ports, &id); + + gst_element_link_pads (GST_ELEMENT (self), GST_OBJECT_NAME (pad), + port->port, HUB_DATA_SINK_PAD); + } + + KMS_BASE_HUB_UNLOCK (self); } static void @@ -714,7 +852,7 @@ endpoint_pad_added (GstElement * endpoint, GstPad * pad, KMS_BASE_HUB_LOCK (port_data->hub); if (port_data->video_sink_target != NULL - && g_strstr_len (GST_OBJECT_NAME (pad), -1, "video")) { + && g_strstr_len (GST_OBJECT_NAME (pad), -1, VIDEO_STREAM_NAME)) { gchar *gp_name = g_strdup_printf (VIDEO_SINK_PAD_PREFIX "%d", port_data->id); @@ -724,9 +862,11 @@ endpoint_pad_added (GstElement * endpoint, GstPad * pad, kms_base_hub_create_and_link_ghost_pad (port_data->hub, pad, gp_name, VIDEO_SINK_PAD_NAME, port_data->video_sink_target); + g_free (gp_name); - } else if (port_data->video_sink_target != NULL - && g_strstr_len (GST_OBJECT_NAME (pad), -1, "audio")) { + } + else if (port_data->audio_sink_target != NULL + && g_strstr_len (GST_OBJECT_NAME (pad), -1, AUDIO_STREAM_NAME)) { gchar *gp_name = g_strdup_printf (AUDIO_SINK_PAD_PREFIX "%d", port_data->id); @@ -736,6 +876,21 @@ endpoint_pad_added (GstElement * endpoint, GstPad * pad, kms_base_hub_create_and_link_ghost_pad (port_data->hub, pad, gp_name, AUDIO_SINK_PAD_NAME, port_data->audio_sink_target); + + g_free (gp_name); + } + else if (port_data->data_sink_target != NULL + && g_strstr_len (GST_OBJECT_NAME (pad), -1, DATA_STREAM_NAME)) { + gchar *gp_name = g_strdup_printf (DATA_SINK_PAD_PREFIX "%d", + port_data->id); + + GST_DEBUG_OBJECT (port_data->hub, + "Connect %" GST_PTR_FORMAT " to %" GST_PTR_FORMAT, pad, + port_data->data_sink_target); + + kms_base_hub_create_and_link_ghost_pad (port_data->hub, pad, gp_name, + DATA_SINK_PAD_NAME, port_data->data_sink_target); + g_free (gp_name); } @@ -743,36 +898,36 @@ endpoint_pad_added (GstElement * endpoint, GstPad * pad, } static gint -kms_base_hub_handle_port (KmsBaseHub * hub, GstElement * hub_port) +kms_base_hub_handle_port (KmsBaseHub * self, GstElement * hub_port) { KmsBaseHubPortData *port_data; gint *id; if (!KMS_IS_HUB_PORT (hub_port)) { - GST_INFO_OBJECT (hub, "Invalid HubPort: %" GST_PTR_FORMAT, hub_port); + GST_INFO_OBJECT (self, "Invalid HubPort: %" GST_PTR_FORMAT, hub_port); return -1; } - if (GST_OBJECT_PARENT (hub) == NULL || - GST_OBJECT_PARENT (hub) != GST_OBJECT_PARENT (hub_port)) { - GST_ERROR_OBJECT (hub, "Hub and HubPort do not have the same parent"); + if (GST_OBJECT_PARENT (self) == NULL || + GST_OBJECT_PARENT (self) != GST_OBJECT_PARENT (hub_port)) { + GST_ERROR_OBJECT (self, "Hub and HubPort do not have the same parent"); return -1; } - GST_DEBUG_OBJECT (hub, "Handle port: %" GST_PTR_FORMAT, hub_port); + GST_DEBUG_OBJECT (self, "Handle HubPort: %" GST_PTR_FORMAT, hub_port); - id = kms_base_hub_generate_port_id (hub); + id = kms_base_hub_generate_port_id (self); - GST_DEBUG_OBJECT (hub, "Adding new port %d", *id); - port_data = kms_base_hub_port_data_create (hub, hub_port, *id); + GST_DEBUG_OBJECT (self, "Adding new HubPort, id: %d", *id); + port_data = kms_base_hub_port_data_create (self, hub_port, *id); port_data->signal_id = g_signal_connect (G_OBJECT (hub_port), "pad-added", G_CALLBACK (endpoint_pad_added), port_data); - KMS_BASE_HUB_LOCK (hub); - g_hash_table_insert (hub->priv->ports, id, port_data); - KMS_BASE_HUB_UNLOCK (hub); + KMS_BASE_HUB_LOCK (self); + g_hash_table_insert (self->priv->ports, id, port_data); + KMS_BASE_HUB_UNLOCK (self); return *id; } @@ -821,35 +976,48 @@ kms_base_hub_class_init (KmsBaseHubClass * klass) klass->handle_port = GST_DEBUG_FUNCPTR (kms_base_hub_handle_port); klass->unhandle_port = GST_DEBUG_FUNCPTR (kms_base_hub_unhandle_port); - klass->link_video_src = - GST_DEBUG_FUNCPTR (kms_base_hub_link_video_src_default); - klass->link_audio_src = - GST_DEBUG_FUNCPTR (kms_base_hub_link_audio_src_default); - klass->link_video_sink = - GST_DEBUG_FUNCPTR (kms_base_hub_link_video_sink_default); klass->link_audio_sink = GST_DEBUG_FUNCPTR (kms_base_hub_link_audio_sink_default); + klass->link_video_sink = + GST_DEBUG_FUNCPTR (kms_base_hub_link_video_sink_default); + klass->link_data_sink = + GST_DEBUG_FUNCPTR (kms_base_hub_link_data_sink_default); + klass->link_audio_src = + GST_DEBUG_FUNCPTR (kms_base_hub_link_audio_src_default); + klass->link_video_src = + GST_DEBUG_FUNCPTR (kms_base_hub_link_video_src_default); + klass->link_data_src = + GST_DEBUG_FUNCPTR (kms_base_hub_link_data_src_default); - klass->unlink_video_src = - GST_DEBUG_FUNCPTR (kms_base_hub_unlink_video_src_default); - klass->unlink_audio_src = - GST_DEBUG_FUNCPTR (kms_base_hub_unlink_audio_src_default); - klass->unlink_video_sink = - GST_DEBUG_FUNCPTR (kms_base_hub_unlink_video_sink_default); klass->unlink_audio_sink = GST_DEBUG_FUNCPTR (kms_base_hub_unlink_audio_sink_default); + klass->unlink_video_sink = + GST_DEBUG_FUNCPTR (kms_base_hub_unlink_video_sink_default); + klass->unlink_data_sink = + GST_DEBUG_FUNCPTR (kms_base_hub_unlink_data_sink_default); + klass->unlink_audio_src = + GST_DEBUG_FUNCPTR (kms_base_hub_unlink_audio_src_default); + klass->unlink_video_src = + GST_DEBUG_FUNCPTR (kms_base_hub_unlink_video_src_default); + klass->unlink_data_src = + GST_DEBUG_FUNCPTR (kms_base_hub_unlink_data_src_default); gobject_class->dispose = GST_DEBUG_FUNCPTR (kms_base_hub_dispose); gobject_class->finalize = GST_DEBUG_FUNCPTR (kms_base_hub_finalize); + gst_element_class_add_pad_template (gstelement_class, + gst_static_pad_template_get (&audio_sink_factory)); + gst_element_class_add_pad_template (gstelement_class, + gst_static_pad_template_get (&video_sink_factory)); + gst_element_class_add_pad_template (gstelement_class, + gst_static_pad_template_get (&data_sink_factory)); + gst_element_class_add_pad_template (gstelement_class, gst_static_pad_template_get (&audio_src_factory)); gst_element_class_add_pad_template (gstelement_class, gst_static_pad_template_get (&video_src_factory)); gst_element_class_add_pad_template (gstelement_class, - gst_static_pad_template_get (&audio_sink_factory)); - gst_element_class_add_pad_template (gstelement_class, - gst_static_pad_template_get (&video_sink_factory)); + gst_static_pad_template_get (&data_src_factory)); /* Signals initialization */ kms_base_hub_signals[SIGNAL_HANDLE_PORT] = @@ -882,5 +1050,5 @@ kms_base_hub_init (KmsBaseHub * self) release_gint, kms_base_hub_port_data_destroy); self->priv->pad_added_id = g_signal_connect (G_OBJECT (self), - "pad-added", G_CALLBACK (hub_pad_added), NULL); + "pad-added", G_CALLBACK (kms_base_hub_pad_added), NULL); } diff --git a/src/gst-plugins/commons/kmsbasehub.h b/src/gst-plugins/commons/kmsbasehub.h index 208bebb4d..e1bbfc8e9 100644 --- a/src/gst-plugins/commons/kmsbasehub.h +++ b/src/gst-plugins/commons/kmsbasehub.h @@ -66,42 +66,62 @@ struct _KmsBaseHubClass void (*unhandle_port) (KmsBaseHub * self, gint port_id); /* Virtual methods */ - gboolean (*link_video_src) (KmsBaseHub * mixer, gint id, + gboolean (*link_audio_sink) (KmsBaseHub * self, gint id, GstElement * internal_element, const gchar * pad_name, gboolean remove_on_unlink); - gboolean (*link_audio_src) (KmsBaseHub * mixer, gint id, + gboolean (*link_video_sink) (KmsBaseHub * self, gint id, GstElement * internal_element, const gchar * pad_name, gboolean remove_on_unlink); - gboolean (*link_video_sink) (KmsBaseHub * mixer, gint id, + gboolean (*link_data_sink) (KmsBaseHub * self, gint id, GstElement * internal_element, const gchar * pad_name, gboolean remove_on_unlink); - gboolean (*link_audio_sink) (KmsBaseHub * mixer, gint id, + + gboolean (*link_audio_src) (KmsBaseHub * self, gint id, + GstElement * internal_element, const gchar * pad_name, + gboolean remove_on_unlink); + gboolean (*link_video_src) (KmsBaseHub * self, gint id, GstElement * internal_element, const gchar * pad_name, gboolean remove_on_unlink); + gboolean (*link_data_src) (KmsBaseHub * self, gint id, + GstElement * internal_element, const gchar * pad_name, + gboolean remove_on_unlink); + + gboolean (*unlink_audio_sink) (KmsBaseHub * self, gint id); + gboolean (*unlink_video_sink) (KmsBaseHub * self, gint id); + gboolean (*unlink_data_sink) (KmsBaseHub * self, gint id); - gboolean (*unlink_video_src) (KmsBaseHub * mixer, gint id); - gboolean (*unlink_audio_src) (KmsBaseHub * mixer, gint id); - gboolean (*unlink_video_sink) (KmsBaseHub * mixer, gint id); - gboolean (*unlink_audio_sink) (KmsBaseHub * mixer, gint id); + gboolean (*unlink_audio_src) (KmsBaseHub * self, gint id); + gboolean (*unlink_video_src) (KmsBaseHub * self, gint id); + gboolean (*unlink_data_src) (KmsBaseHub * self, gint id); }; -gboolean kms_base_hub_link_video_src (KmsBaseHub * mixer, gint id, +gboolean kms_base_hub_link_audio_sink (KmsBaseHub * self, gint id, GstElement * internal_element, const gchar * pad_name, gboolean remove_on_unlink); -gboolean kms_base_hub_link_audio_src (KmsBaseHub * mixer, gint id, +gboolean kms_base_hub_link_video_sink (KmsBaseHub * self, gint id, GstElement * internal_element, const gchar * pad_name, gboolean remove_on_unlink); -gboolean kms_base_hub_link_video_sink (KmsBaseHub * mixer, gint id, +gboolean kms_base_hub_link_data_sink (KmsBaseHub * self, gint id, GstElement * internal_element, const gchar * pad_name, gboolean remove_on_unlink); -gboolean kms_base_hub_link_audio_sink (KmsBaseHub * mixer, gint id, + +gboolean kms_base_hub_link_audio_src (KmsBaseHub * self, gint id, + GstElement * internal_element, const gchar * pad_name, + gboolean remove_on_unlink); +gboolean kms_base_hub_link_video_src (KmsBaseHub * self, gint id, GstElement * internal_element, const gchar * pad_name, gboolean remove_on_unlink); +gboolean kms_base_hub_link_data_src (KmsBaseHub * self, gint id, + GstElement * internal_element, const gchar * pad_name, + gboolean remove_on_unlink); + +gboolean kms_base_hub_unlink_audio_sink (KmsBaseHub * self, gint id); +gboolean kms_base_hub_unlink_video_sink (KmsBaseHub * self, gint id); +gboolean kms_base_hub_unlink_data_sink (KmsBaseHub * self, gint id); -gboolean kms_base_hub_unlink_video_src (KmsBaseHub * mixer, gint id); -gboolean kms_base_hub_unlink_audio_src (KmsBaseHub * mixer, gint id); -gboolean kms_base_hub_unlink_video_sink (KmsBaseHub * mixer, gint id); -gboolean kms_base_hub_unlink_audio_sink (KmsBaseHub * mixer, gint id); +gboolean kms_base_hub_unlink_audio_src (KmsBaseHub * self, gint id); +gboolean kms_base_hub_unlink_video_src (KmsBaseHub * self, gint id); +gboolean kms_base_hub_unlink_data_src (KmsBaseHub * self, gint id); GType kms_base_hub_get_type (void); diff --git a/src/gst-plugins/commons/kmsbasertpendpoint.c b/src/gst-plugins/commons/kmsbasertpendpoint.c index 93a0d7367..512fcc833 100644 --- a/src/gst-plugins/commons/kmsbasertpendpoint.c +++ b/src/gst-plugins/commons/kmsbasertpendpoint.c @@ -29,6 +29,7 @@ #include "kms-core-enumtypes.h" #include "kms-core-marshal.h" #include "sdp_utils.h" +#include "sdpagent/kmssdpmediadirext.h" #include "sdpagent/kmssdpulpfecext.h" #include "sdpagent/kmssdpredundantext.h" #include "sdpagent/kmssdprtpavpfmediahandler.h" @@ -75,6 +76,8 @@ G_DEFINE_TYPE_WITH_CODE (KmsBaseRtpEndpoint, kms_base_rtp_endpoint, #define JB_INITIAL_LATENCY 0 #define JB_READY_AUDIO_LATENCY 100 #define JB_READY_VIDEO_LATENCY 500 +#define RTCP_FB_CCM_FIR SDP_MEDIA_RTCP_FB_CCM " " SDP_MEDIA_RTCP_FB_FIR +#define RTCP_FB_NACK_PLI SDP_MEDIA_RTCP_FB_NACK " " SDP_MEDIA_RTCP_FB_PLI #define DEFAULT_MIN_PORT 1 #define DEFAULT_MAX_PORT G_MAXUINT16 @@ -208,6 +211,7 @@ struct _KmsBaseRtpEndpointPrivate GstElement *rtpbin; KmsMediaState media_state; + GstSDPDirection offer_dir; gboolean support_fec; gboolean rtcp_mux; @@ -261,13 +265,14 @@ enum static guint obj_signals[LAST_SIGNAL] = { 0 }; +#define DEFAULT_OFFER_DIR GST_SDP_DIRECTION_SENDRECV #define DEFAULT_RTCP_MUX FALSE #define DEFAULT_RTCP_NACK FALSE #define DEFAULT_RTCP_REMB FALSE #define DEFAULT_TARGET_BITRATE 0 #define MIN_VIDEO_RECV_BW_DEFAULT 0 -#define MIN_VIDEO_SEND_BW_DEFAULT 100 -#define MAX_VIDEO_SEND_BW_DEFAULT 500 +#define MIN_VIDEO_SEND_BW_DEFAULT 100 // kbps +#define MAX_VIDEO_SEND_BW_DEFAULT 500 // kbps enum { @@ -284,6 +289,7 @@ enum PROP_MIN_PORT, PROP_MAX_PORT, PROP_SUPPORT_FEC, + PROP_OFFER_DIR, PROP_LAST }; @@ -492,6 +498,36 @@ kms_base_rtp_endpoint_config_rtp_hdr_ext (KmsBaseRtpEndpoint * self, /* Media handler management begin */ +static GstSDPDirection +on_offer_media_direction (KmsSdpMediaDirectionExt * ext, + KmsBaseRtpEndpoint * self) +{ + GstSDPDirection offer_dir; + + g_object_get (self, "offer-dir", &offer_dir, NULL); + + return offer_dir; +} + +static GstSDPDirection +on_answer_media_direction (KmsSdpMediaDirectionExt * ext, + GstSDPDirection dir, KmsBaseRtpEndpoint * self) +{ + // RFC3264 6.1 + switch (dir) { + case GST_SDP_DIRECTION_SENDONLY: + return GST_SDP_DIRECTION_RECVONLY; + case GST_SDP_DIRECTION_RECVONLY: + return GST_SDP_DIRECTION_SENDONLY; + case GST_SDP_DIRECTION_SENDRECV: + return GST_SDP_DIRECTION_SENDRECV; + case GST_SDP_DIRECTION_INACTIVE: + return GST_SDP_DIRECTION_INACTIVE; + default: + return GST_SDP_DIRECTION_SENDRECV; + } +} + static gboolean on_offered_ulp_fec_cb (KmsSdpUlpFecExt * ext, guint pt, guint clock_rate, gpointer user_data) @@ -518,10 +554,25 @@ static void kms_base_rtp_configure_extensions (KmsBaseRtpEndpoint * self, const gchar * media, KmsSdpMediaHandler * handler) { + KmsSdpMediaDirectionExt *mediadirext; KmsSdpUlpFecExt *ulpfecext; KmsSdpRedundantExt *redext; ExtData *edata; + mediadirext = kms_sdp_media_direction_ext_new (); + + g_signal_connect (mediadirext, "on-offer-media-direction", + G_CALLBACK (on_offer_media_direction), self); + g_signal_connect (mediadirext, "on-answer-media-direction", + G_CALLBACK (on_answer_media_direction), self); + + kms_sdp_media_handler_add_media_extension (handler, + KMS_I_SDP_MEDIA_EXTENSION (mediadirext)); + + if (!self->priv->support_fec) { + return; + } + edata = ext_data_new (); kms_list_append (self->priv->prot_medias, g_strdup (media), edata); @@ -579,9 +630,7 @@ kms_base_rtp_create_media_handler (KmsBaseSdpEndpoint * base_sdp, err = NULL; } - if (self->priv->support_fec) { - kms_base_rtp_configure_extensions (self, media, *handler); - } + kms_base_rtp_configure_extensions (self, media, *handler); } /* Media handler management end */ @@ -693,7 +742,7 @@ kms_base_rtp_endpoint_is_video_rtcp_nack (KmsBaseRtpEndpoint * self) /* Configure media SDP begin */ static GObject * kms_base_rtp_endpoint_create_rtp_session (KmsBaseRtpEndpoint * self, - guint session_id, const gchar * rtpbin_pad_name, guint rtp_profile, + guint session_id, const gchar * rtpbin_pad_name, GstRTPProfile rtp_profile, GstSDPDirection direction) { GstElement *rtpbin = self->priv->rtpbin; @@ -727,13 +776,12 @@ kms_base_rtp_endpoint_create_rtp_session (KmsBaseRtpEndpoint * self, KMS_ELEMENT_UNLOCK (self); - g_object_set (rtpsession, "rtcp-min-interval", - RTCP_MIN_INTERVAL * GST_MSECOND, "rtp-profile", rtp_profile, NULL); + g_object_set (rtpsession, "rtp-profile", rtp_profile, NULL); return rtpsession; } -static guint +static GstRTPProfile kms_base_rtp_endpoint_media_proto_to_rtp_profile (KmsBaseRtpEndpoint * self, const gchar * proto) { @@ -1014,12 +1062,16 @@ kms_base_rtp_endpoint_create_remb_manager (KmsBaseRtpEndpoint *self, GObject *rtpsession = kms_base_rtp_endpoint_get_internal_session ( KMS_BASE_RTP_ENDPOINT(self), VIDEO_RTP_SESSION); - if (!rtpsession) { - GST_WARNING_OBJECT (self, - "Abort: No RTP Session with ID %u", VIDEO_RTP_SESSION); + if (rtpsession == NULL) { return; } + // Decrease minimum interval between RTCP packets, + // for better reaction times in case of bad network + GST_INFO_OBJECT (self, "REMB: Set RTCP min interval to 500ms"); + g_object_set (rtpsession, "rtcp-min-interval", + RTCP_MIN_INTERVAL * GST_MSECOND, NULL); + g_object_get (self, "max-video-recv-bandwidth", &max_recv_bw, NULL); self->priv->rl = kms_remb_local_create (rtpsession, self->priv->min_video_recv_bw, @@ -1537,17 +1589,17 @@ complete_caps_with_fb (GstCaps * caps, const GstSDPMedia * media, for (a = 0;; a++) { const gchar *attr; - attr = gst_sdp_media_get_attribute_val_n (media, RTCP_FB, a); + attr = gst_sdp_media_get_attribute_val_n (media, SDP_MEDIA_RTCP_FB, a); if (attr == NULL) { break; } - if (sdp_utils_rtcp_fb_attr_check_type (attr, payload, RTCP_FB_FIR)) { + if (sdp_utils_rtcp_fb_attr_check_type (attr, payload, RTCP_FB_CCM_FIR)) { fir = TRUE; continue; } - if (sdp_utils_rtcp_fb_attr_check_type (attr, payload, RTCP_FB_PLI)) { + if (sdp_utils_rtcp_fb_attr_check_type (attr, payload, RTCP_FB_NACK_PLI)) { pli = TRUE; continue; } @@ -1898,8 +1950,6 @@ static GstPadProbeReturn kms_base_rtp_endpoint_sync_rtcp_probe (GstPad * pad, GstPadProbeInfo * info, KmsRtpSynchronizer * sync) { - return GST_PAD_PROBE_OK; - if (GST_PAD_PROBE_INFO_TYPE (info) & GST_PAD_PROBE_TYPE_BUFFER) { GstBuffer *buffer = GST_PAD_PROBE_INFO_BUFFER (info); @@ -2375,6 +2425,9 @@ kms_base_rtp_endpoint_set_property (GObject * object, guint property_id, self->priv->max_port = v; break; } + case PROP_OFFER_DIR: + self->priv->offer_dir = g_value_get_enum (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; @@ -2415,6 +2468,9 @@ kms_base_rtp_endpoint_get_property (GObject * object, guint property_id, case PROP_MEDIA_STATE: g_value_set_enum (value, self->priv->media_state); break; + case PROP_OFFER_DIR: + g_value_set_enum (value, self->priv->offer_dir); + break; case PROP_REMB_PARAMS: if (self->priv->rl != NULL) { GstStructure *params = gst_structure_new_empty ("remb-params"); @@ -2823,6 +2879,11 @@ kms_base_rtp_endpoint_class_init (KmsBaseRtpEndpointClass * klass) KMS_TYPE_MEDIA_STATE, KMS_MEDIA_STATE_DISCONNECTED, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (object_class, PROP_OFFER_DIR, + g_param_spec_enum ("offer-dir", "Offer direction", "Offer direction", + KMS_TYPE_SDP_DIRECTION, DEFAULT_OFFER_DIR, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (object_class, PROP_RTCP_MUX, g_param_spec_boolean ("rtcp-mux", "RTCP mux", "RTCP mux", DEFAULT_RTCP_MUX, @@ -3356,6 +3417,8 @@ kms_base_rtp_endpoint_init (KmsBaseRtpEndpoint * self) self->priv->min_port = DEFAULT_MIN_PORT; self->priv->max_port = DEFAULT_MAX_PORT; + + self->priv->offer_dir = DEFAULT_OFFER_DIR; } GObject * @@ -3363,12 +3426,15 @@ kms_base_rtp_endpoint_get_internal_session (KmsBaseRtpEndpoint *self, guint session_id) { GstElement *rtpbin = self->priv->rtpbin; // GstRtpBin* - GObject *rtpsession; // RTPSession* from GstRtpBin->GstRtpSession - g_signal_emit_by_name (rtpbin, "get-internal-session", session_id, &rtpsession); - if (!rtpsession) { - GST_ERROR_OBJECT (self, "GstRtpBin lacks internal RTPSession"); - return NULL; + GObject *rtpsession = NULL; // RTPSession* from GstRtpBin->GstRtpSession + + g_signal_emit_by_name (rtpbin, "get-internal-session", session_id, + &rtpsession); + if (rtpsession == NULL) { + GST_WARNING_OBJECT (self, "GstRtpBin: No RTP session, id: %u", + session_id); } + return rtpsession; } diff --git a/src/gst-plugins/commons/kmsbasertpsession.c b/src/gst-plugins/commons/kmsbasertpsession.c index 6c18ff83c..de31facf2 100644 --- a/src/gst-plugins/commons/kmsbasertpsession.c +++ b/src/gst-plugins/commons/kmsbasertpsession.c @@ -212,6 +212,8 @@ kms_base_rtp_session_e2e_latency_cb (GstPad * pad, KmsMediaType type, stat = (StreamE2EAvgStat *) value; stat->avg = KMS_STATS_CALCULATE_LATENCY_AVG (t, stat->avg); } + + g_free (name); } static void diff --git a/src/gst-plugins/commons/kmselement.c b/src/gst-plugins/commons/kmselement.c index 9a76761f5..f81ce7bfa 100644 --- a/src/gst-plugins/commons/kmselement.c +++ b/src/gst-plugins/commons/kmselement.c @@ -1009,7 +1009,7 @@ kms_element_connect_sink_target_full (KmsElement * self, GstPad * target, g_timeout_add_seconds (self->priv->keyframe_interval, kms_utils_force_keyframe, pad); } - kms_utils_manage_gaps (pad); + kms_utils_pad_monitor_gaps (pad); } gst_pad_set_query_function (pad, kms_element_pad_query); diff --git a/src/gst-plugins/commons/kmsenctreebin.c b/src/gst-plugins/commons/kmsenctreebin.c index 86c1b5864..d80276abf 100644 --- a/src/gst-plugins/commons/kmsenctreebin.c +++ b/src/gst-plugins/commons/kmsenctreebin.c @@ -291,7 +291,7 @@ kms_enc_tree_bin_set_target_bitrate (KmsEncTreeBin * self) return; } - GST_DEBUG_OBJECT (self->priv->enc, "Setting encoding bitrate to: %d", + GST_DEBUG_OBJECT (self->priv->enc, "Set target encoding bitrate: %d bps", target_bitrate); switch (self->priv->enc_type) { @@ -301,8 +301,6 @@ kms_enc_tree_bin_set_target_bitrate (KmsEncTreeBin * self) g_object_get (self->priv->enc, "target-bitrate", &last_br, NULL); if (last_br / 1000 != target_bitrate / 1000) { - GST_DEBUG_OBJECT (self->priv->enc, "Set bitrate: %" G_GUINT32_FORMAT, - target_bitrate); g_object_set (self->priv->enc, "target-bitrate", target_bitrate, NULL); } break; @@ -313,8 +311,6 @@ kms_enc_tree_bin_set_target_bitrate (KmsEncTreeBin * self) g_object_get (self->priv->enc, "bitrate", &last_br, NULL); if (last_br != new_br) { - GST_DEBUG_OBJECT (self->priv->enc, "Set bitrate: %" G_GUINT32_FORMAT, - target_bitrate); g_object_set (self->priv->enc, "bitrate", new_br, NULL); } break; @@ -325,13 +321,11 @@ kms_enc_tree_bin_set_target_bitrate (KmsEncTreeBin * self) g_object_get (self->priv->enc, "bitrate", &last_br, NULL); if (last_br / 1000 != new_br / 1000) { - GST_DEBUG_OBJECT (self->priv->enc, "Set bitrate: %" G_GUINT32_FORMAT, - target_bitrate); g_object_set (self->priv->enc, "bitrate", new_br, NULL); } } default: - GST_DEBUG ("Not setting bitrate, encoder not supported"); + GST_DEBUG ("Skip setting bitrate, encoder not supported"); break; } } @@ -481,7 +475,7 @@ kms_enc_tree_bin_configure (KmsEncTreeBin * self, const GstCaps * caps, rate = kms_utils_create_rate_for_caps (caps); convert = kms_utils_create_convert_for_caps (caps); mediator = kms_utils_create_mediator_element (caps); - queue = gst_element_factory_make ("queue", NULL); + queue = kms_utils_element_factory_make ("queue", "enctreebin_"); g_object_set (queue, "leaky", 2, "max-size-time", LEAKY_TIME, NULL); if (rate) { @@ -503,7 +497,7 @@ kms_enc_tree_bin_configure (KmsEncTreeBin * self, const GstCaps * caps, GstCaps *filter_caps = gst_caps_from_string ("video/x-raw,format=I420"); GstPad *sink; - capsfilter = gst_element_factory_make ("capsfilter", NULL); + capsfilter = kms_utils_element_factory_make ("capsfilter", "enctreebin_"); sink = gst_element_get_static_pad (capsfilter, "sink"); gst_pad_add_probe (sink, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, check_caps_probe, NULL, NULL); diff --git a/src/gst-plugins/commons/kmshubport.c b/src/gst-plugins/commons/kmshubport.c index 260f82257..60a45b6f1 100644 --- a/src/gst-plugins/commons/kmshubport.c +++ b/src/gst-plugins/commons/kmshubport.c @@ -25,13 +25,13 @@ #define PLUGIN_NAME "hubport" #define KEY_ELEM_DATA "kms-hub-elem-data" -G_DEFINE_QUARK (KEY_ELEM_DATA, key_elem_data); +G_DEFINE_QUARK (KEY_ELEM_DATA, key_elem_data) #define KEY_TYPE_DATA "kms-hub-type-data" -G_DEFINE_QUARK (KEY_TYPE_DATA, key_type_data); +G_DEFINE_QUARK (KEY_TYPE_DATA, key_type_data) #define KEY_PAD_DATA "kms-hub-pad-data" -G_DEFINE_QUARK (KEY_PAD_DATA, key_pad_data); +G_DEFINE_QUARK (KEY_PAD_DATA, key_pad_data) GST_DEBUG_CATEGORY_STATIC (kms_hub_port_debug_category); #define GST_CAT_DEFAULT kms_hub_port_debug_category @@ -46,8 +46,7 @@ GST_DEBUG_CATEGORY_STATIC (kms_hub_port_debug_category); struct _KmsHubPortPrivate { - GstPad *audio_internal; - GstPad *vieo_internal; + void *dummy; }; /* Pad templates */ @@ -55,29 +54,37 @@ static GstStaticPadTemplate hub_audio_sink_factory = GST_STATIC_PAD_TEMPLATE (HUB_AUDIO_SINK_PAD, GST_PAD_SINK, GST_PAD_REQUEST, - GST_STATIC_CAPS (KMS_AGNOSTIC_AUDIO_CAPS) - ); + GST_STATIC_CAPS (KMS_AGNOSTIC_AUDIO_CAPS)); static GstStaticPadTemplate hub_video_sink_factory = GST_STATIC_PAD_TEMPLATE (HUB_VIDEO_SINK_PAD, GST_PAD_SINK, GST_PAD_REQUEST, - GST_STATIC_CAPS (KMS_AGNOSTIC_VIDEO_CAPS) - ); + GST_STATIC_CAPS (KMS_AGNOSTIC_VIDEO_CAPS)); + +static GstStaticPadTemplate hub_data_sink_factory = +GST_STATIC_PAD_TEMPLATE (HUB_DATA_SINK_PAD, + GST_PAD_SINK, + GST_PAD_REQUEST, + GST_STATIC_CAPS (KMS_AGNOSTIC_DATA_CAPS)); static GstStaticPadTemplate hub_audio_src_factory = GST_STATIC_PAD_TEMPLATE (HUB_AUDIO_SRC_PAD, GST_PAD_SRC, GST_PAD_SOMETIMES, - GST_STATIC_CAPS (KMS_AGNOSTIC_AUDIO_CAPS) - ); + GST_STATIC_CAPS (KMS_AGNOSTIC_AUDIO_CAPS)); static GstStaticPadTemplate hub_video_src_factory = GST_STATIC_PAD_TEMPLATE (HUB_VIDEO_SRC_PAD, GST_PAD_SRC, GST_PAD_SOMETIMES, - GST_STATIC_CAPS (KMS_AGNOSTIC_VIDEO_CAPS) - ); + GST_STATIC_CAPS (KMS_AGNOSTIC_VIDEO_CAPS)); + +static GstStaticPadTemplate hub_data_src_factory = +GST_STATIC_PAD_TEMPLATE (HUB_DATA_SRC_PAD, + GST_PAD_SRC, + GST_PAD_SOMETIMES, + GST_STATIC_CAPS (KMS_AGNOSTIC_DATA_CAPS)); /* class initialization */ @@ -89,13 +96,13 @@ G_DEFINE_TYPE_WITH_CODE (KmsHubPort, kms_hub_port, static GstPad * kms_hub_port_generate_sink_pad (GstElement * element, GstPadTemplate * templ, const gchar * name, const GstCaps * caps, - GstElement * agnosticbin) + GstElement * output) { - GstPad *agnostic_pad, *pad; + GstPad *output_pad, *pad; - agnostic_pad = gst_element_get_static_pad (agnosticbin, "sink"); - pad = gst_ghost_pad_new_from_template (name, agnostic_pad, templ); - g_object_unref (agnostic_pad); + output_pad = gst_element_get_static_pad (output, "sink"); + pad = gst_ghost_pad_new_from_template (name, output_pad, templ); + g_object_unref (output_pad); if (GST_STATE (element) >= GST_STATE_PAUSED || GST_STATE_PENDING (element) >= GST_STATE_PAUSED @@ -116,7 +123,7 @@ static GstPad * kms_hub_port_request_new_pad (GstElement * element, GstPadTemplate * templ, const gchar * name, const GstCaps * caps) { - GstElement *agnosticbin = NULL; + GstElement *output = NULL; if (templ == gst_element_class_get_pad_template (GST_ELEMENT_CLASS (G_OBJECT_GET_CLASS @@ -128,8 +135,9 @@ kms_hub_port_request_new_pad (GstElement * element, return NULL; } - agnosticbin = kms_element_get_audio_agnosticbin (KMS_ELEMENT (element)); - } else if (templ == + output = kms_element_get_audio_agnosticbin (KMS_ELEMENT (element)); + } + else if (templ == gst_element_class_get_pad_template (GST_ELEMENT_CLASS (G_OBJECT_GET_CLASS (element)), HUB_VIDEO_SINK_PAD)) { if (g_strcmp0 (name, HUB_VIDEO_SINK_PAD) != 0) { @@ -138,16 +146,26 @@ kms_hub_port_request_new_pad (GstElement * element, return NULL; } - agnosticbin = kms_element_get_video_agnosticbin (KMS_ELEMENT (element)); + output = kms_element_get_video_agnosticbin (KMS_ELEMENT (element)); + } + else if (templ == + gst_element_class_get_pad_template (GST_ELEMENT_CLASS (G_OBJECT_GET_CLASS + (element)), HUB_DATA_SINK_PAD)) { + if (g_strcmp0 (name, HUB_DATA_SINK_PAD) != 0) { + GST_ERROR_OBJECT (element, + "Invalid pad name %s for template %" GST_PTR_FORMAT, name, templ); + return NULL; + } + + output = kms_element_get_data_tee (KMS_ELEMENT (element)); } - if (agnosticbin == NULL) { + if (output == NULL) { GST_WARNING_OBJECT (element, "No agnosticbin got for template %" GST_PTR_FORMAT, templ); return NULL; } else { - return kms_hub_port_generate_sink_pad (element, templ, name, caps, - agnosticbin); + return kms_hub_port_generate_sink_pad (element, templ, name, caps, output); } } @@ -156,7 +174,19 @@ kms_hub_port_internal_src_unhandled (KmsHubPort * self, GstPad * pad) { GstPad *sink = g_object_get_qdata (G_OBJECT (pad), key_pad_data_quark ()); - g_return_if_fail (sink); + if (sink == NULL) { + // Classes that derive from BaseHub should link their internal elements + // to all possible source pad types: audio, video, data. + // Data pads are new and optional, so they might not be linked and the sink + // here will be NULL. Audio and video pads are mandatory, so the sink here + // should not be NULL. + GstCaps *caps = gst_pad_query_caps (pad, NULL); + if (!kms_utils_caps_is_data (caps)) { + GST_ERROR_OBJECT (self, "Derived class is missing links for some SRCs"); + g_return_if_fail (sink); + } + return; + } kms_element_remove_sink (KMS_ELEMENT (self), sink); @@ -166,7 +196,7 @@ kms_hub_port_internal_src_unhandled (KmsHubPort * self, GstPad * pad) void kms_hub_port_unhandled (KmsHubPort * self) { - GstPad *video_src, *audio_src; + GstPad *video_src, *audio_src, *data_src; g_return_if_fail (self); @@ -179,6 +209,11 @@ kms_hub_port_unhandled (KmsHubPort * self) gst_element_get_static_pad (GST_ELEMENT (self), HUB_AUDIO_SRC_PAD); kms_hub_port_internal_src_unhandled (self, audio_src); g_object_unref (audio_src); + + data_src = + gst_element_get_static_pad (GST_ELEMENT (self), HUB_DATA_SRC_PAD); + kms_hub_port_internal_src_unhandled (self, data_src); + g_object_unref (data_src); } static void @@ -197,6 +232,7 @@ kms_hub_port_internal_src_pad_linked (GstPad * pad, GstPad * peer, target = gst_element_get_static_pad (capsfilter, "sink"); if (!target) { + GST_WARNING_OBJECT (pad, "No sink in capsfilter"); goto end; } @@ -271,14 +307,19 @@ kms_hub_port_class_init (KmsHubPortClass * klass) gstelement_class->request_new_pad = GST_DEBUG_FUNCPTR (kms_hub_port_request_new_pad); + gst_element_class_add_pad_template (gstelement_class, + gst_static_pad_template_get (&hub_audio_sink_factory)); + gst_element_class_add_pad_template (gstelement_class, + gst_static_pad_template_get (&hub_video_sink_factory)); + gst_element_class_add_pad_template (gstelement_class, + gst_static_pad_template_get (&hub_data_sink_factory)); + gst_element_class_add_pad_template (gstelement_class, gst_static_pad_template_get (&hub_audio_src_factory)); gst_element_class_add_pad_template (gstelement_class, gst_static_pad_template_get (&hub_video_src_factory)); gst_element_class_add_pad_template (gstelement_class, - gst_static_pad_template_get (&hub_audio_sink_factory)); - gst_element_class_add_pad_template (gstelement_class, - gst_static_pad_template_get (&hub_video_sink_factory)); + gst_static_pad_template_get (&hub_data_src_factory)); /* Registers a private structure for the instantiatable type */ g_type_class_add_private (klass, sizeof (KmsHubPortPrivate)); @@ -303,6 +344,11 @@ kms_hub_port_init (KmsHubPort * self) kms_hub_port_start_media_type (kmselement, KMS_ELEMENT_PAD_TYPE_AUDIO, templ, HUB_AUDIO_SRC_PAD); g_object_unref (templ); + + templ = gst_static_pad_template_get (&hub_data_src_factory); + kms_hub_port_start_media_type (kmselement, KMS_ELEMENT_PAD_TYPE_DATA, templ, + HUB_DATA_SRC_PAD); + g_object_unref (templ); } gboolean diff --git a/src/gst-plugins/commons/kmshubport.h b/src/gst-plugins/commons/kmshubport.h index c688eb8d2..90d690f96 100644 --- a/src/gst-plugins/commons/kmshubport.h +++ b/src/gst-plugins/commons/kmshubport.h @@ -21,8 +21,11 @@ #define HUB_AUDIO_SINK_PAD "hub_audio_sink" #define HUB_VIDEO_SINK_PAD "hub_video_sink" +#define HUB_DATA_SINK_PAD "hub_data_sink" + #define HUB_AUDIO_SRC_PAD "hub_audio_src" #define HUB_VIDEO_SRC_PAD "hub_video_src" +#define HUB_DATA_SRC_PAD "hub_data_src" G_BEGIN_DECLS #define KMS_TYPE_HUB_PORT kms_hub_port_get_type() diff --git a/src/gst-plugins/commons/kmsparsetreebin.c b/src/gst-plugins/commons/kmsparsetreebin.c index bef6a8f29..ba70da6d0 100644 --- a/src/gst-plugins/commons/kmsparsetreebin.c +++ b/src/gst-plugins/commons/kmsparsetreebin.c @@ -72,7 +72,7 @@ create_parser_for_caps (const GstCaps * caps) if (parser_factory != NULL) { parser = gst_element_factory_create (parser_factory, NULL); } else { - parser = gst_element_factory_make ("capsfilter", NULL); + parser = kms_utils_element_factory_make ("capsfilter", "parsetreebin_"); } gst_plugin_feature_list_free (filtered_list); @@ -167,7 +167,7 @@ kms_parse_tree_bin_configure (KmsParseTreeBin * self, const GstCaps * caps) kms_tree_bin_set_input_element (tree_bin, self->priv->parser); output_tee = kms_tree_bin_get_output_tee (tree_bin); - if (!kms_utils_caps_are_raw (caps) && kms_utils_caps_are_video (caps)) { + if (!kms_utils_caps_is_raw (caps) && kms_utils_caps_is_video (caps)) { GstPad *sink = gst_element_get_static_pad (output_tee, "sink"); gst_pad_add_probe (sink, diff --git a/src/gst-plugins/commons/kmsremb.c b/src/gst-plugins/commons/kmsremb.c index a902c630c..1e06af90b 100644 --- a/src/gst-plugins/commons/kmsremb.c +++ b/src/gst-plugins/commons/kmsremb.c @@ -693,12 +693,13 @@ send_remb_event (KmsRembRemote * rm, guint bitrate, guint ssrc) br = MIN (br, max); } + // Custom "bitrate" upstream event that tells the encoder to set a new br GST_DEBUG_OBJECT (KMS_REMB_BASE (rm)->rtpsess, - "'on-feedback-rtcp' send upstream event" - ", bitrate: %" G_GUINT32_FORMAT + "'on-feedback-rtcp' send bitrate event" ", ssrc: %" G_GUINT32_FORMAT - ", range [%" G_GUINT32_FORMAT ", %" G_GUINT32_FORMAT "]" - ", event bitrate: %" G_GUINT32_FORMAT, bitrate, ssrc, min, max, br); + ", target br: %" G_GUINT32_FORMAT + ", valid range: [%" G_GUINT32_FORMAT ", %" G_GUINT32_FORMAT "]" + ", new br: %" G_GUINT32_FORMAT, ssrc, bitrate, min, max, br); event = kms_utils_remb_event_upstream_new (br, ssrc); gst_pad_push_event (rm->pad_event, event); diff --git a/src/gst-plugins/commons/kmssdpsession.c b/src/gst-plugins/commons/kmssdpsession.c index 13bc963ad..85733b7a7 100644 --- a/src/gst-plugins/commons/kmssdpsession.c +++ b/src/gst-plugins/commons/kmssdpsession.c @@ -199,7 +199,7 @@ kms_sdp_session_get_local_sdp (KmsSdpSession * self) { GstSDPMessage *sdp = NULL; - GST_DEBUG_OBJECT (self, "Get local SDP"); + GST_LOG_OBJECT (self, "Get local SDP"); if (self->local_sdp != NULL) { gst_sdp_message_copy (self->local_sdp, &sdp); @@ -213,7 +213,7 @@ kms_sdp_session_get_remote_sdp (KmsSdpSession * self) { GstSDPMessage *sdp = NULL; - GST_DEBUG_OBJECT (self, "Get remote SDP"); + GST_LOG_OBJECT (self, "Get remote SDP"); if (self->remote_sdp != NULL) { gst_sdp_message_copy (self->remote_sdp, &sdp); @@ -249,7 +249,7 @@ kms_sdp_session_finalize (GObject * object) { KmsSdpSession *self = KMS_SDP_SESSION (object); - GST_DEBUG_OBJECT (self, "finalize"); + GST_LOG_OBJECT (self, "finalize"); if (self->local_sdp != NULL) { gst_sdp_message_free (self->local_sdp); diff --git a/src/gst-plugins/commons/kmstreebin.c b/src/gst-plugins/commons/kmstreebin.c index e4bcdffb1..907b6d2a3 100644 --- a/src/gst-plugins/commons/kmstreebin.c +++ b/src/gst-plugins/commons/kmstreebin.c @@ -180,8 +180,9 @@ kms_tree_bin_init (KmsTreeBin * self) g_mutex_init (&self->priv->input_caps_mutex); - self->priv->output_tee = gst_element_factory_make ("tee", NULL); - fakesink = gst_element_factory_make ("fakesink", NULL); + self->priv->output_tee = kms_utils_element_factory_make ("tee", "treebin_"); + fakesink = kms_utils_element_factory_make ("fakesink", "treebin_"); + g_object_set (fakesink, "async", FALSE, "sync", FALSE, NULL); sink = gst_element_get_static_pad (self->priv->output_tee, "sink"); diff --git a/src/gst-plugins/commons/kmsutils.c b/src/gst-plugins/commons/kmsutils.c index f6f7cd41c..8d1f578b4 100644 --- a/src/gst-plugins/commons/kmsutils.c +++ b/src/gst-plugins/commons/kmsutils.c @@ -107,12 +107,43 @@ gst_element_sync_state_with_parent_target_state (GstElement * element) return TRUE; } +/* ---- GstBin ---- */ + +void +kms_utils_bin_remove (GstBin * bin, GstElement * element) +{ + GST_DEBUG ("Remove %" GST_PTR_FORMAT " from %" GST_PTR_FORMAT, element, bin); + + if (!gst_element_set_locked_state (element, TRUE)) { + GST_ERROR ("Cannot lock element %" GST_PTR_FORMAT, element); + } + + gst_element_set_state (element, GST_STATE_NULL); + + // gst_bin_remove() unlinks all pads and unrefs the object + gst_bin_remove (bin, element); +} + +/* ---- GstElement ---- */ + +GstElement* kms_utils_element_factory_make (const gchar *factoryname, + const gchar *name_prefix) +{ + GstElement* element = gst_element_factory_make (factoryname, NULL); + gchar *old_name = GST_ELEMENT_NAME (element); + GST_ELEMENT_NAME (element) = g_strconcat (name_prefix, old_name, NULL); + g_free (old_name); + return element; +} + /* Caps begin */ static GstStaticCaps static_audio_caps = GST_STATIC_CAPS (KMS_AGNOSTIC_AUDIO_CAPS); static GstStaticCaps static_video_caps = GST_STATIC_CAPS (KMS_AGNOSTIC_VIDEO_CAPS); +static GstStaticCaps static_data_caps = + GST_STATIC_CAPS (KMS_AGNOSTIC_DATA_CAPS); static GstStaticCaps static_rtp_caps = GST_STATIC_CAPS (KMS_AGNOSTIC_RTP_CAPS); static GstStaticCaps static_raw_caps = @@ -137,22 +168,28 @@ caps_can_intersect_with_static (const GstCaps * caps, } gboolean -kms_utils_caps_are_audio (const GstCaps * caps) +kms_utils_caps_is_audio (const GstCaps * caps) { return caps_can_intersect_with_static (caps, &static_audio_caps); } gboolean -kms_utils_caps_are_video (const GstCaps * caps) +kms_utils_caps_is_video (const GstCaps * caps) { return caps_can_intersect_with_static (caps, &static_video_caps); } gboolean -kms_utils_caps_are_raw (const GstCaps * caps) +kms_utils_caps_is_data (const GstCaps * caps) +{ + return caps_can_intersect_with_static (caps, &static_data_caps); +} + +gboolean +kms_utils_caps_is_rtp (const GstCaps * caps) { gboolean ret; - GstCaps *raw_caps = gst_static_caps_get (&static_raw_caps); + GstCaps *raw_caps = gst_static_caps_get (&static_rtp_caps); ret = gst_caps_is_always_compatible (caps, raw_caps); @@ -162,10 +199,10 @@ kms_utils_caps_are_raw (const GstCaps * caps) } gboolean -kms_utils_caps_are_rtp (const GstCaps * caps) +kms_utils_caps_is_raw (const GstCaps * caps) { gboolean ret; - GstCaps *raw_caps = gst_static_caps_get (&static_rtp_caps); + GstCaps *raw_caps = gst_static_caps_get (&static_raw_caps); ret = gst_caps_is_always_compatible (caps, raw_caps); @@ -179,7 +216,7 @@ kms_utils_caps_are_rtp (const GstCaps * caps) GstElement * kms_utils_create_convert_for_caps (const GstCaps * caps) { - if (kms_utils_caps_are_audio (caps)) { + if (kms_utils_caps_is_audio (caps)) { return gst_element_factory_make ("audioconvert", NULL); } else { return gst_element_factory_make ("videoconvert", NULL); @@ -189,7 +226,7 @@ kms_utils_create_convert_for_caps (const GstCaps * caps) GstElement * kms_utils_create_mediator_element (const GstCaps * caps) { - if (kms_utils_caps_are_audio (caps)) { + if (kms_utils_caps_is_audio (caps)) { return gst_element_factory_make ("audioresample", NULL); } else { return gst_element_factory_make ("videoscale", NULL); @@ -201,7 +238,7 @@ kms_utils_create_rate_for_caps (const GstCaps * caps) { GstElement *rate = NULL; - if (kms_utils_caps_are_video (caps)) { + if (kms_utils_caps_is_video (caps)) { rate = gst_element_factory_make ("videorate", NULL); g_object_set (G_OBJECT (rate), "average-period", GST_MSECOND * 200, "skip-to-first", TRUE, "drop-only", TRUE, NULL); @@ -456,10 +493,13 @@ gap_detection_probe (GstPad * pad, GstPadProbeInfo * info, gpointer data) } void -kms_utils_manage_gaps (GstPad * pad) +kms_utils_pad_monitor_gaps (GstPad * pad) { + GST_INFO_OBJECT (pad, "Add probe: Detect stream gaps"); + gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BUFFER, discont_detection_probe, NULL, NULL); + gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, gap_detection_probe, NULL, NULL); } diff --git a/src/gst-plugins/commons/kmsutils.h b/src/gst-plugins/commons/kmsutils.h index 7e403662b..8ae93fee3 100644 --- a/src/gst-plugins/commons/kmsutils.h +++ b/src/gst-plugins/commons/kmsutils.h @@ -36,12 +36,28 @@ gboolean kms_is_valid_uri (const gchar * url); gboolean gst_element_sync_state_with_parent_target_state (GstElement * element); -/* Caps */ -gboolean kms_utils_caps_are_audio (const GstCaps * caps); -gboolean kms_utils_caps_are_video (const GstCaps * caps); -gboolean kms_utils_caps_are_rtp (const GstCaps * caps); +/* ---- GstBin ---- */ + +/* + * Remove a GstElement from a GstBin, with proper state changes. + */ +void kms_utils_bin_remove (GstBin * bin, GstElement * element); + +/* ---- GstElement ---- */ -gboolean kms_utils_caps_are_raw (const GstCaps * caps); +/* + * Make a new GstElement with an unique name as generated by + * gst_element_factory_make(), but with the given prefix. + */ +GstElement* kms_utils_element_factory_make (const gchar *factoryname, + const gchar *name_prefix); + +/* Caps */ +gboolean kms_utils_caps_is_audio (const GstCaps * caps); +gboolean kms_utils_caps_is_video (const GstCaps * caps); +gboolean kms_utils_caps_is_data (const GstCaps * caps); +gboolean kms_utils_caps_is_rtp (const GstCaps * caps); +gboolean kms_utils_caps_is_raw (const GstCaps * caps); GstElement * kms_utils_create_convert_for_caps (const GstCaps * caps); GstElement * kms_utils_create_mediator_element (const GstCaps * caps); @@ -54,7 +70,7 @@ KmsMediaType kms_utils_convert_element_pad_type (KmsElementPadType pad_type); /* keyframe management */ void kms_utils_drop_until_keyframe (GstPad *pad, gboolean all_headers); -void kms_utils_manage_gaps (GstPad *pad); +void kms_utils_pad_monitor_gaps (GstPad *pad); void kms_utils_control_key_frames_request_duplicates (GstPad *pad); /* Pad blocked action */ diff --git a/src/gst-plugins/commons/sdp_utils.c b/src/gst-plugins/commons/sdp_utils.c index 0a6d9c369..5e540e760 100644 --- a/src/gst-plugins/commons/sdp_utils.c +++ b/src/gst-plugins/commons/sdp_utils.c @@ -29,6 +29,7 @@ GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); static gchar *directions[] = { SENDONLY_STR, RECVONLY_STR, SENDRECV_STR, INACTIVE_STR, NULL }; +#define EXT_MAP "extmap" #define RTPMAP "rtpmap" #define FMTP "fmtp" @@ -625,12 +626,13 @@ sdp_utils_media_has_remb (const GstSDPMedia * media) for (a = 0;; a++) { const gchar *attr; - attr = gst_sdp_media_get_attribute_val_n (media, RTCP_FB, a); + attr = gst_sdp_media_get_attribute_val_n (media, SDP_MEDIA_RTCP_FB, a); if (attr == NULL) { break; } - if (sdp_utils_rtcp_fb_attr_check_type (attr, payload, RTCP_FB_REMB)) { + if (sdp_utils_rtcp_fb_attr_check_type (attr, payload, + SDP_MEDIA_RTCP_FB_GOOG_REMB)) { return TRUE; } } @@ -651,12 +653,13 @@ sdp_utils_media_has_rtcp_nack (const GstSDPMedia * media) for (a = 0;; a++) { const gchar *attr; - attr = gst_sdp_media_get_attribute_val_n (media, RTCP_FB, a); + attr = gst_sdp_media_get_attribute_val_n (media, SDP_MEDIA_RTCP_FB, a); if (attr == NULL) { break; } - if (sdp_utils_rtcp_fb_attr_check_type (attr, payload, RTCP_FB_NACK)) { + if (sdp_utils_rtcp_fb_attr_check_type (attr, payload, + SDP_MEDIA_RTCP_FB_NACK)) { return TRUE; } } diff --git a/src/gst-plugins/commons/sdp_utils.h b/src/gst-plugins/commons/sdp_utils.h index c1bd7345e..f7df47e83 100644 --- a/src/gst-plugins/commons/sdp_utils.h +++ b/src/gst-plugins/commons/sdp_utils.h @@ -26,14 +26,6 @@ #define SENDRECV_STR "sendrecv" #define INACTIVE_STR "inactive" -#define RTCP_FB "rtcp-fb" -#define RTCP_FB_FIR "ccm fir" -#define RTCP_FB_NACK "nack" -#define RTCP_FB_PLI "nack pli" -#define RTCP_FB_REMB "goog-remb" - -#define EXT_MAP "extmap" - typedef gboolean (*GstSDPMediaFunc) (const GstSDPMedia *media, gpointer user_data); typedef gboolean (*GstSDPIntersectMediaFunc) (const GstSDPAttribute *attr, gpointer user_data); diff --git a/src/gst-plugins/commons/sdpagent/kmssdpmediadirext.h b/src/gst-plugins/commons/sdpagent/kmssdpmediadirext.h index 0bb2f6a70..00dd39f93 100644 --- a/src/gst-plugins/commons/sdpagent/kmssdpmediadirext.h +++ b/src/gst-plugins/commons/sdpagent/kmssdpmediadirext.h @@ -20,7 +20,7 @@ #include -#include +#include G_BEGIN_DECLS diff --git a/src/gst-plugins/commons/sdpagent/kmssdprtpavpfmediahandler.c b/src/gst-plugins/commons/sdpagent/kmssdprtpavpfmediahandler.c index 38d0e4f13..c48373a2f 100644 --- a/src/gst-plugins/commons/sdpagent/kmssdprtpavpfmediahandler.c +++ b/src/gst-plugins/commons/sdpagent/kmssdprtpavpfmediahandler.c @@ -567,14 +567,14 @@ kms_sdp_rtp_avpf_media_handler_class_init (KmsSdpRtpAvpfMediaHandlerClass * kms_sdp_rtp_avpf_media_handler_add_answer_attributes_impl; g_object_class_install_property (gobject_class, PROP_NACK, - g_param_spec_boolean ("nack", "Nack", - "Wheter rtcp-fb-nack-param if supproted or not", + g_param_spec_boolean (SDP_MEDIA_RTCP_FB_NACK, "Nack", + "Whether rtcp-fb-nack-param if supproted or not", DEFAULT_SDP_MEDIA_RTP_AVPF_NACK, G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (gobject_class, PROP_GOOG_REMB, - g_param_spec_boolean ("goog-remb", "goog-remb", - "Wheter receiver estimated maximum bitrate is supported", + g_param_spec_boolean (SDP_MEDIA_RTCP_FB_GOOG_REMB, "Google-REMB", + "Whether Google's Receiver Estimated Maximum Bitrate is supported", DEFAULT_SDP_MEDIA_RTP_GOOG_REMB, G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); diff --git a/src/gst-plugins/commons/sdpagent/kmssdprtpavpmediahandler.c b/src/gst-plugins/commons/sdpagent/kmssdprtpavpmediahandler.c index 72ebe3195..4eea470d3 100644 --- a/src/gst-plugins/commons/sdpagent/kmssdprtpavpmediahandler.c +++ b/src/gst-plugins/commons/sdpagent/kmssdprtpavpmediahandler.c @@ -778,6 +778,17 @@ kms_sdp_rtp_avp_media_handler_init_new_offer (KmsSdpMediaHandler * handler, g_set_error_literal (error, KMS_SDP_AGENT_ERROR, SDP_AGENT_UNEXPECTED_ERROR, "Can not set port"); ret = FALSE; + goto end; + } + + // RFC 5763 says: + // > The endpoint that is the offerer MUST use the setup attribute + // > value of setup:actpass + if (gst_sdp_media_add_attribute (offer, "setup", "actpass") != GST_SDP_OK) { + g_set_error_literal (error, KMS_SDP_AGENT_ERROR, SDP_AGENT_UNEXPECTED_ERROR, + "Can not set attribute 'setup:actpass'"); + ret = FALSE; + goto end; } end: diff --git a/src/gst-plugins/commons/sdpagent/kmssdpsctpmediahandler.c b/src/gst-plugins/commons/sdpagent/kmssdpsctpmediahandler.c index 4392b7f70..cffed195b 100644 --- a/src/gst-plugins/commons/sdpagent/kmssdpsctpmediahandler.c +++ b/src/gst-plugins/commons/sdpagent/kmssdpsctpmediahandler.c @@ -407,8 +407,9 @@ kms_sdp_sctp_media_handler_init_offer (KmsSdpMediaHandler * handler, if (gst_sdp_media_add_attribute (offer, "setup", "actpass") != GST_SDP_OK) { g_set_error_literal (error, KMS_SDP_AGENT_ERROR, SDP_AGENT_UNEXPECTED_ERROR, - "Can not to set attribute 'setup:actpass'"); + "Can not set attribute 'setup:actpass'"); ret = FALSE; + goto end; } end: diff --git a/src/gst-plugins/kmsagnosticbin.c b/src/gst-plugins/kmsagnosticbin.c index 7a46fddf6..7743031f5 100644 --- a/src/gst-plugins/kmsagnosticbin.c +++ b/src/gst-plugins/kmsagnosticbin.c @@ -86,6 +86,7 @@ struct _KmsAgnosticBin2Private GRecMutex thread_mutex; GstElement *input_tee; + GstElement *input_fakesink; GstCaps *input_caps; GstBin *input_bin; GstCaps *input_bin_src_caps; @@ -103,6 +104,7 @@ struct _KmsAgnosticBin2Private GstStructure *codec_config; gboolean bitrate_unlimited; gboolean no_keyframe_interval; + gboolean transcoding_enabled; }; enum @@ -215,7 +217,7 @@ remove_on_unlinked_blocked (GstPad * pad, GstPadProbeInfo * info, gpointer elem) return GST_PAD_PROBE_REMOVE; } - GST_DEBUG_OBJECT (pad, "Unlinking pad"); + GST_LOG_OBJECT (pad, "Unlinking pad"); GST_OBJECT_LOCK (pad); if (g_object_get_qdata (G_OBJECT (pad), unlinking_data_quark ())) { @@ -351,7 +353,7 @@ link_element_to_tee (GstElement * tee, GstElement * element) static GstPadProbeReturn remove_target_pad_block (GstPad * pad, GstPadProbeInfo * info, gpointer gp) { - GST_DEBUG_OBJECT (pad, "Drop"); + GST_LOG_OBJECT (pad, "Drop"); return GST_PAD_PROBE_DROP; } @@ -363,7 +365,7 @@ remove_target_pad (GstPad * pad) // from the tee GstPad *target = gst_ghost_pad_get_target (GST_GHOST_PAD (pad)); - GST_DEBUG_OBJECT (pad, "Removing target pad"); + GST_LOG_OBJECT (pad, "Removing target pad"); if (target == NULL) { return; @@ -418,7 +420,7 @@ static void kms_agnostic_bin2_link_to_tee (KmsAgnosticBin2 * self, GstPad * pad, GstElement * tee, GstCaps * caps) { - GstElement *queue = gst_element_factory_make ("queue", NULL); + GstElement *queue = kms_utils_element_factory_make ("queue", "agnosticbin_"); GstPad *target; GstProxyPad *proxy; @@ -426,7 +428,7 @@ kms_agnostic_bin2_link_to_tee (KmsAgnosticBin2 * self, GstPad * pad, gst_element_sync_state_with_parent (queue); if (!(gst_caps_is_any (caps) || gst_caps_is_empty (caps)) - && kms_utils_caps_are_raw (caps)) { + && kms_utils_caps_is_raw (caps)) { GstElement *convert = kms_utils_create_convert_for_caps (caps); GstElement *rate = kms_utils_create_rate_for_caps (caps); GstElement *mediator = kms_utils_create_mediator_element (caps); @@ -482,15 +484,15 @@ check_bin (KmsTreeBin * tree_bin, const GstCaps * caps) GstPad *tee_sink = gst_element_get_static_pad (output_tee, "sink"); GstCaps *current_caps = kms_tree_bin_get_input_caps (tree_bin); - GST_TRACE_OBJECT (tree_bin, - "Check compatibility for bin: %" GST_PTR_FORMAT, tree_bin); + GST_DEBUG_OBJECT (tree_bin, + "Check compatibility for bin: %" GST_PTR_FORMAT " ...", tree_bin); if (current_caps == NULL) { current_caps = gst_pad_get_allowed_caps (tee_sink); - GST_TRACE_OBJECT (tree_bin, "Allowed caps are: %" GST_PTR_FORMAT, + GST_DEBUG_OBJECT (tree_bin, "... Allowed caps are: %" GST_PTR_FORMAT, current_caps); } else { - GST_TRACE_OBJECT (tree_bin, "Current caps are: %" GST_PTR_FORMAT, + GST_DEBUG_OBJECT (tree_bin, "... Current caps are: %" GST_PTR_FORMAT, current_caps); } @@ -549,9 +551,9 @@ kms_agnostic_bin2_get_raw_caps (const GstCaps * caps) { GstCaps *raw_caps = NULL; - if (kms_utils_caps_are_audio (caps)) { + if (kms_utils_caps_is_audio (caps)) { raw_caps = gst_static_caps_get (&static_raw_audio_caps); - } else if (kms_utils_caps_are_video (caps)) { + } else if (kms_utils_caps_is_video (caps)) { raw_caps = gst_static_caps_get (&static_raw_video_caps); } @@ -591,7 +593,7 @@ kms_agnostic_bin2_get_or_create_dec_bin (KmsAgnosticBin2 * self, GstCaps * caps) { GstCaps *raw_caps; - if (kms_utils_caps_are_raw (self->priv->input_caps) + if (kms_utils_caps_is_raw (self->priv->input_caps) || gst_caps_is_empty (caps) || gst_caps_is_any (caps)) { return self->priv->input_bin; } @@ -662,7 +664,7 @@ kms_agnostic_bin2_create_bin_for_caps (KmsAgnosticBin2 * self, GstCaps * caps) KmsEncTreeBin *enc_bin; GstElement *input_element, *output_tee; - if (kms_utils_caps_are_rtp (caps)) { + if (kms_utils_caps_is_rtp (caps)) { return kms_agnostic_bin2_create_rtp_pay_bin (self, caps); } @@ -671,7 +673,7 @@ kms_agnostic_bin2_create_bin_for_caps (KmsAgnosticBin2 * self, GstCaps * caps) return NULL; } - if (kms_utils_caps_are_raw (caps)) { + if (kms_utils_caps_is_raw (caps)) { return dec_bin; } @@ -702,32 +704,41 @@ kms_agnostic_bin2_find_or_create_bin_for_caps (KmsAgnosticBin2 * self, GstBin *bin; KmsMediaType type; - if (kms_utils_caps_are_audio (caps)) { + if (kms_utils_caps_is_audio (caps)) { type = KMS_MEDIA_TYPE_AUDIO; } else { type = KMS_MEDIA_TYPE_VIDEO; } - // Caps shown here are those expected by the receiving side - GST_INFO_OBJECT (self, "Find bin for caps: %" GST_PTR_FORMAT, caps); + GST_DEBUG_OBJECT (self, "Find TreeBin with output caps: %" GST_PTR_FORMAT, caps); bin = kms_agnostic_bin2_find_bin_for_caps (self, caps); if (bin == NULL) { - GST_INFO_OBJECT (self, "Bin not found! Connection requires transcoding"); - bin = kms_agnostic_bin2_create_bin_for_caps (self, caps); - GST_INFO_OBJECT (self, "Created bin: %" GST_PTR_FORMAT, bin); - - g_signal_emit (GST_BIN (self), - kms_agnostic_bin2_signals[SIGNAL_MEDIA_TRANSCODING], 0, TRUE, type); - GST_INFO_OBJECT (self, "TRANSCODING is ACTIVE for this media"); - } else { - GST_INFO_OBJECT (self, "Bin found! Connection doesn't require transcoding"); + GST_DEBUG_OBJECT (self, "TreeBin not found! Connection requires transcoding"); - g_signal_emit (GST_BIN (self), - kms_agnostic_bin2_signals[SIGNAL_MEDIA_TRANSCODING], 0, FALSE, type); - GST_INFO_OBJECT (self, "TRANSCODING is INACTIVE for this media"); + bin = kms_agnostic_bin2_create_bin_for_caps (self, caps); + GST_LOG_OBJECT (self, "Created TreeBin: %" GST_PTR_FORMAT, bin); + + if (!self->priv->transcoding_enabled) { + // Only signal "transcoding enabled" once + g_signal_emit (GST_BIN (self), + kms_agnostic_bin2_signals[SIGNAL_MEDIA_TRANSCODING], 0, TRUE, type); + GST_INFO_OBJECT (self, "TRANSCODING is ACTIVE for this media"); + self->priv->transcoding_enabled = TRUE; + } + } + else { + GST_DEBUG_OBJECT (self, "TreeBin found! Reuse it"); + + if (!self->priv->transcoding_enabled) { + // Only signal "transcoding disabled" if we didn't really create a + // previous EncTreeBin + g_signal_emit (GST_BIN (self), + kms_agnostic_bin2_signals[SIGNAL_MEDIA_TRANSCODING], 0, FALSE, type); + GST_INFO_OBJECT (self, "TRANSCODING is INACTIVE for this media"); + } } return bin; @@ -743,31 +754,37 @@ kms_agnostic_bin2_find_or_create_bin_for_caps (KmsAgnosticBin2 * self, static void kms_agnostic_bin2_link_pad (KmsAgnosticBin2 * self, GstPad * pad, GstPad * peer) { - GstCaps *caps; + GstCaps *pad_caps, *peer_caps; GstBin *bin; - GST_INFO_OBJECT (self, "Linking: %" GST_PTR_FORMAT + GST_LOG_OBJECT (self, "Linking: %" GST_PTR_FORMAT " to %" GST_PTR_FORMAT, pad, peer); - caps = gst_pad_query_caps (peer, NULL); + pad_caps = gst_pad_query_caps (pad, NULL); + if (pad_caps != NULL) { + GST_INFO_OBJECT (self, "Current output caps: %" GST_PTR_FORMAT, pad_caps); + gst_caps_unref (pad_caps); + } - if (caps == NULL) { + peer_caps = gst_pad_query_caps (peer, NULL); + if (peer_caps == NULL) { goto end; } - GST_INFO_OBJECT (self, "Query caps are: %" GST_PTR_FORMAT, caps); - bin = kms_agnostic_bin2_find_or_create_bin_for_caps (self, caps); + GST_INFO_OBJECT (self, "Downstream input caps: %" GST_PTR_FORMAT, peer_caps); + + bin = kms_agnostic_bin2_find_or_create_bin_for_caps (self, peer_caps); if (bin != NULL) { GstElement *tee = kms_tree_bin_get_output_tee (KMS_TREE_BIN (bin)); - if (!kms_utils_caps_are_rtp (caps)) { + if (!kms_utils_caps_is_rtp (peer_caps)) { kms_utils_drop_until_keyframe (pad, TRUE); } - kms_agnostic_bin2_link_to_tee (self, pad, tee, caps); + kms_agnostic_bin2_link_to_tee (self, pad, tee, peer_caps); } - gst_caps_unref (caps); + gst_caps_unref (peer_caps); end: g_object_unref (peer); @@ -793,7 +810,7 @@ kms_agnostic_bin2_process_pad (KmsAgnosticBin2 * self, GstPad * pad) return FALSE; } - GST_DEBUG_OBJECT (self, "Processing pad: %" GST_PTR_FORMAT, pad); + GST_LOG_OBJECT (self, "Processing pad: %" GST_PTR_FORMAT, pad); if (pad == NULL) { return FALSE; @@ -814,7 +831,7 @@ kms_agnostic_bin2_process_pad (KmsAgnosticBin2 * self, GstPad * pad) gst_caps_unref (caps); if (accepted) { - GST_DEBUG_OBJECT (self, "No need to reconfigure pad %" GST_PTR_FORMAT, + GST_LOG_OBJECT (self, "No need to reconfigure pad %" GST_PTR_FORMAT, pad); g_object_unref (target); g_object_unref (peer); @@ -856,7 +873,7 @@ input_bin_src_caps_probe (GstPad * pad, GstPadProbeInfo * info, gpointer bin) return GST_PAD_PROBE_OK; } - GST_TRACE_OBJECT (self, "Event in parser pad: %" GST_PTR_FORMAT, event); + GST_LOG_OBJECT (self, "Event in parser pad: %" GST_PTR_FORMAT, event); if (GST_EVENT_TYPE (event) != GST_EVENT_CAPS) { return GST_PAD_PROBE_OK; @@ -885,7 +902,7 @@ input_bin_src_caps_probe (GstPad * pad, GstPadProbeInfo * info, gpointer bin) static void remove_bin (gpointer key, gpointer value, gpointer agnosticbin) { - GST_DEBUG_OBJECT (agnosticbin, "Removing %" GST_PTR_FORMAT, value); + GST_LOG_OBJECT (agnosticbin, "Removing %" GST_PTR_FORMAT, value); gst_bin_remove (GST_BIN (agnosticbin), value); gst_element_set_state (value, GST_STATE_NULL); } @@ -922,7 +939,7 @@ kms_agnostic_bin2_configure_input (KmsAgnosticBin2 * self, const GstCaps * caps) self->priv->started = FALSE; - GST_DEBUG ("Removing old treebins"); + GST_LOG_OBJECT (self, "Removing old treebins"); g_hash_table_foreach (self->priv->bins, remove_bin, self); g_hash_table_remove_all (self->priv->bins); @@ -942,10 +959,11 @@ kms_agnostic_bin2_sink_caps_probe (GstPad * pad, GstPadProbeInfo * info, return GST_PAD_PROBE_OK; } - GST_TRACE_OBJECT (pad, "Event: %" GST_PTR_FORMAT, event); - self = KMS_AGNOSTIC_BIN2 (user_data); + GST_LOG_OBJECT (pad, "Self: %s, event: %" GST_PTR_FORMAT, + GST_ELEMENT_NAME (self), event); + gst_event_parse_caps (event, &new_caps); if (new_caps == NULL) { @@ -958,12 +976,10 @@ kms_agnostic_bin2_sink_caps_probe (GstPad * pad, GstPadProbeInfo * info, self->priv->input_caps = gst_caps_copy (new_caps); KMS_AGNOSTIC_BIN2_UNLOCK (self); - GST_TRACE_OBJECT (self, "New caps event: %" GST_PTR_FORMAT, event); - if (current_caps != NULL) { GstStructure *st; - GST_TRACE_OBJECT (self, "Current caps: %" GST_PTR_FORMAT, current_caps); + GST_DEBUG_OBJECT (self, "Current caps: %" GST_PTR_FORMAT, current_caps); st = gst_caps_get_structure (current_caps, 0); // Remove famerate, width, height, streamheader that make unecessary @@ -972,12 +988,15 @@ kms_agnostic_bin2_sink_caps_probe (GstPad * pad, GstPadProbeInfo * info, gst_structure_remove_fields (st, "width", "height", "framerate", "streamheader", "codec_data", NULL); - if (!gst_caps_can_intersect (new_caps, current_caps) && - !kms_utils_caps_are_raw (current_caps) - && !kms_utils_caps_are_raw (new_caps)) { - GST_DEBUG_OBJECT (self, "Caps differ caps: %" GST_PTR_FORMAT, new_caps); + if (!gst_caps_can_intersect (new_caps, current_caps) + && !kms_utils_caps_is_raw (current_caps) + && !kms_utils_caps_is_raw (new_caps)) { + GST_DEBUG_OBJECT (self, "Set new caps: %" GST_PTR_FORMAT, new_caps); kms_agnostic_bin2_configure_input (self, new_caps); } + else { + GST_DEBUG_OBJECT (self, "No need to set new caps"); + } gst_caps_unref (current_caps); } else { @@ -1024,7 +1043,7 @@ static void kms_agnostic_bin2_src_unlinked (GstPad * pad, GstPad * peer, KmsAgnosticBin2 * self) { - GST_DEBUG_OBJECT (pad, "Unlinked"); + GST_LOG_OBJECT (pad, "Unlinked"); KMS_AGNOSTIC_BIN2_LOCK (self); GST_OBJECT_FLAG_UNSET (pad, KMS_AGNOSTIC_PAD_STARTED); remove_target_pad (pad); @@ -1076,7 +1095,7 @@ kms_agnostic_bin2_dispose (GObject * object) { KmsAgnosticBin2 *self = KMS_AGNOSTIC_BIN2 (object); - GST_DEBUG_OBJECT (object, "dispose"); + GST_LOG_OBJECT (object, "dispose"); KMS_AGNOSTIC_BIN2_LOCK (self); g_thread_pool_free (self->priv->remove_pool, FALSE, FALSE); @@ -1107,7 +1126,7 @@ kms_agnostic_bin2_finalize (GObject * object) { KmsAgnosticBin2 *self = KMS_AGNOSTIC_BIN2 (object); - GST_DEBUG_OBJECT (object, "finalize"); + GST_LOG_OBJECT (object, "finalize"); g_rec_mutex_clear (&self->priv->thread_mutex); @@ -1186,7 +1205,7 @@ kms_agnostic_bin2_set_property (GObject * object, guint property_id, GST_WARNING_OBJECT (self, "Setting max-bitrate less than min-bitrate"); } self->priv->max_bitrate = v; - GST_DEBUG ("max_bitrate configured %d", self->priv->max_bitrate); + GST_DEBUG_OBJECT (self, "max_bitrate configured %d", self->priv->max_bitrate); kms_agnostic_bin_set_encoders_bitrate (self); KMS_AGNOSTIC_BIN2_UNLOCK (self); break; @@ -1347,17 +1366,54 @@ check_ret_error (GstPad * pad, GstFlowReturn ret) case GST_FLOW_OK: case GST_FLOW_FLUSHING: break; - case GST_FLOW_ERROR: + case GST_FLOW_ERROR: { + + KmsAgnosticBin2 *self = + KMS_AGNOSTIC_BIN2 (gst_pad_get_parent_element (pad)); + + gchar *fakesink_message; + g_object_get (self->priv->input_fakesink, "last-message", + &fakesink_message, NULL); + GST_FIXME_OBJECT (pad, "Handling flow error, fakesink message: %s", + fakesink_message); + g_free (fakesink_message); + + GST_FIXME_OBJECT (pad, "REPLACE FAKESINK"); + GstElement *fakesink = self->priv->input_fakesink; + kms_utils_bin_remove (GST_BIN (self), fakesink); + fakesink = kms_utils_element_factory_make ("fakesink", "agnosticbin_"); + self->priv->input_fakesink = fakesink; + g_object_set (fakesink, "async", FALSE, "sync", FALSE, + "silent", FALSE, + NULL); + + gst_bin_add (GST_BIN (self), fakesink); + gst_element_sync_state_with_parent (fakesink); + gst_element_link (self->priv->input_tee, fakesink); + + // fakesink setup + GstPad *sink = gst_element_get_static_pad (fakesink, "sink"); + gst_pad_add_probe (sink, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, + kms_agnostic_bin2_sink_caps_probe, self, NULL); + g_object_unref (sink); + + GST_FIXME_OBJECT (pad, "RECONFIGURE INPUT TREEBIN"); + kms_agnostic_bin2_configure_input (self, self->priv->input_caps); + + // TODO: We should notify this as an error to remote client + GST_FIXME_OBJECT (pad, "Ignoring flow error"); + ret = GST_FLOW_OK; + break; + } case GST_FLOW_NOT_NEGOTIATED: case GST_FLOW_NOT_LINKED: // TODO: We should notify this as an error to remote client - GST_WARNING_OBJECT (pad, "Ignoring flow returned %s", + GST_WARNING_OBJECT (pad, "Ignoring flow status: %s", gst_flow_get_name (ret)); ret = GST_FLOW_OK; break; - default: - GST_WARNING_OBJECT (pad, "Flow returned %s", gst_flow_get_name (ret)); + GST_WARNING_OBJECT (pad, "Flow status: %s", gst_flow_get_name (ret)); break; } @@ -1395,11 +1451,14 @@ kms_agnostic_bin2_init (KmsAgnosticBin2 * self) self->priv = KMS_AGNOSTIC_BIN2_GET_PRIVATE (self); - tee = gst_element_factory_make ("tee", NULL); + tee = kms_utils_element_factory_make ("tee", "agnosticbin_"); self->priv->input_tee = tee; - fakesink = gst_element_factory_make ("fakesink", NULL); - g_object_set (fakesink, "async", FALSE, "sync", FALSE, NULL); + fakesink = kms_utils_element_factory_make ("fakesink", "agnosticbin_"); + self->priv->input_fakesink = fakesink; + g_object_set (fakesink, "async", FALSE, "sync", FALSE, + "silent", FALSE, // FIXME used to print log in check_ret_error() + NULL); gst_bin_add_many (GST_BIN (self), tee, fakesink, NULL); gst_element_link_many (tee, fakesink, NULL); @@ -1411,7 +1470,7 @@ kms_agnostic_bin2_init (KmsAgnosticBin2 * self) gst_pad_set_chain_function (self->priv->sink, kms_agnostic_bin2_sink_chain); gst_pad_set_chain_list_function (self->priv->sink, kms_agnostic_bin2_sink_chain_list); - kms_utils_manage_gaps (self->priv->sink); + kms_utils_pad_monitor_gaps (self->priv->sink); g_object_unref (templ); g_object_unref (target); @@ -1431,6 +1490,7 @@ kms_agnostic_bin2_init (KmsAgnosticBin2 * self) self->priv->min_bitrate = MIN_BITRATE_DEFAULT; self->priv->max_bitrate = MAX_BITRATE_DEFAULT; self->priv->bitrate_unlimited = FALSE; + self->priv->transcoding_enabled = FALSE; } gboolean diff --git a/src/gst-plugins/kmsdummysink.c b/src/gst-plugins/kmsdummysink.c index 770b1c2ad..c3b4f1db8 100644 --- a/src/gst-plugins/kmsdummysink.c +++ b/src/gst-plugins/kmsdummysink.c @@ -294,6 +294,7 @@ kms_dummy_sink_release_requested_sink_pad (KmsElement * obj, GstPad * pad) kms_element_remove_sink_by_type_full (obj, dummy->type, dummy->description); g_hash_table_remove (self->priv->sinks, padname); + g_free (padname); return TRUE; } diff --git a/src/gst-plugins/kmsfilterelement.c b/src/gst-plugins/kmsfilterelement.c index 09e41d46e..b0126d753 100644 --- a/src/gst-plugins/kmsfilterelement.c +++ b/src/gst-plugins/kmsfilterelement.c @@ -141,6 +141,12 @@ kms_filter_element_set_filter (KmsFilterElement * self, GstElement * filter) } sink = gst_element_get_static_pad (filter, "sink"); + + if (sink == NULL) { + // Provides compatibility with 'textoverlay' + sink = gst_element_get_static_pad (filter, "video_sink"); + } + src = gst_element_get_static_pad (filter, "src"); if (sink == NULL || src == NULL) { diff --git a/src/server/implementation/DotGraph.cpp b/src/server/implementation/DotGraph.cpp index 492458b3f..c7d02171c 100644 --- a/src/server/implementation/DotGraph.cpp +++ b/src/server/implementation/DotGraph.cpp @@ -16,7 +16,7 @@ */ #include "DotGraph.hpp" -#include +#include namespace kurento { diff --git a/src/server/implementation/Factory.hpp b/src/server/implementation/Factory.hpp index e110b80fa..5d31326f7 100644 --- a/src/server/implementation/Factory.hpp +++ b/src/server/implementation/Factory.hpp @@ -41,8 +41,9 @@ class Factory virtual std::string getName() const = 0; protected: - virtual MediaObjectImpl *createObjectPointer (const boost::property_tree::ptree - &conf, const Json::Value ¶ms) const = 0; + virtual MediaObjectImpl *createObjectPointer ( + const boost::property_tree::ptree &conf, + const Json::Value ¶ms) const = 0; }; } /* kurento */ diff --git a/src/server/implementation/MediaSet.cpp b/src/server/implementation/MediaSet.cpp index 90d0dcddd..23314d442 100644 --- a/src/server/implementation/MediaSet.cpp +++ b/src/server/implementation/MediaSet.cpp @@ -25,6 +25,7 @@ #include /* This is included to avoid problems with slots and lamdas */ +#include #include #include @@ -127,7 +128,7 @@ void MediaSet::doGarbageCollection () sessionInUse[it.first] = false; lock.unlock(); } else { - GST_WARNING ("Session timeout: %s", it.first.c_str() ); + GST_WARNING ("Remove inactive session: %s", it.first.c_str() ); unrefSession (it.first); } } @@ -137,8 +138,7 @@ MediaSet::MediaSet() { terminated = false; - workers = std::shared_ptr (new WorkerPool ( - MEDIASET_THREADS_DEFAULT) ); + workers = std::make_shared(MEDIASET_THREADS_DEFAULT); thread = std::thread ( [&] () { std::unique_lock lock (recMutex); @@ -165,8 +165,8 @@ MediaSet::~MediaSet () { std::unique_lock lock (recMutex); - if (!objectsMap.empty() ) { - GST_DEBUG ("Still %zu object/s alive", objectsMap.size() ); + if (objectsMap.size() > 1) { + GST_WARNING ("Still %zu object/s alive", objectsMap.size()); } terminated = true; @@ -226,7 +226,7 @@ MediaSet::ref (MediaObjectImpl *mediaObjectPtr) std::unique_lock lock (recMutex); std::shared_ptr mediaObject; - if (mediaObjectPtr == NULL) { + if (mediaObjectPtr == nullptr) { throw KurentoException (MEDIA_OBJECT_NOT_FOUND, "Invalid object"); } @@ -433,6 +433,7 @@ MediaSet::unref (const std::string &sessionId, } childrenMap.erase (mediaObject->getId() ); + reverseSessionMap.erase (mediaObject->getId() ); } auto eventIt = eventHandler.find (sessionId); diff --git a/src/server/implementation/MediaSet.hpp b/src/server/implementation/MediaSet.hpp index e7f01af84..cda5578cb 100644 --- a/src/server/implementation/MediaSet.hpp +++ b/src/server/implementation/MediaSet.hpp @@ -107,23 +107,53 @@ class MediaSet std::recursive_mutex recMutex; std::condition_variable_any waitCond; - std::atomic terminated; + std::atomic terminated{}; std::shared_ptr serverManager; - std::map> objectsMap; - - std::map>> - childrenMap; - - std::map>> - sessionMap; - - std::map sessionInUse; - std::map>>> - eventHandler; - - std::map> reverseSessionMap; + std::map< + std::string, + std::weak_ptr + > objectsMap; + + std::map< + std::string, // Parent Object ID + std::map< + std::string, // Child Object ID + std::shared_ptr + > + > childrenMap; + + std::map< + std::string, // Session ID + std::map< + std::string, // Object ID + std::shared_ptr + > + > sessionMap; + + std::map< + std::string, // Object ID + std::unordered_set< + std::string // Session ID + > + > reverseSessionMap; + + std::map< + std::string, // Session ID + bool + > sessionInUse; + + std::map< + std::string, // Session ID + std::map< + std::string, // Object ID + std::map< + std::string, // Subscription ID + std::shared_ptr + > + > + > eventHandler; std::shared_ptr workers; diff --git a/src/server/implementation/ModuleManager.cpp b/src/server/implementation/ModuleManager.cpp index 2694549e1..37d2613e5 100644 --- a/src/server/implementation/ModuleManager.cpp +++ b/src/server/implementation/ModuleManager.cpp @@ -20,6 +20,7 @@ #include #include +#include #include #include @@ -39,13 +40,14 @@ int ModuleManager::loadModule (std::string modulePath) { const kurento::FactoryRegistrar *registrar; - void *registrarFactory, *getVersion = NULL, *getName = NULL, - *getDescriptor = NULL, *getGenerationTime = NULL; + void *registrarFactory, *getVersion = nullptr, *getName = nullptr, + *getDescriptor = nullptr, + *getGenerationTime = nullptr; std::string moduleFileName; std::string moduleName; std::string moduleVersion; std::string generationTime; - const char *moduleDescriptor = NULL; + const char *moduleDescriptor = nullptr; boost::filesystem::path path (modulePath); @@ -65,7 +67,7 @@ ModuleManager::loadModule (std::string modulePath) } if (!module.get_symbol ("getFactoryRegistrar", registrarFactory) ) { - GST_WARNING ("Symbol 'getFactoryRegistrar' not found in library %s", + GST_DEBUG ("Symbol 'getFactoryRegistrar' not found in library %s", moduleFileName.c_str() ); return -1; } @@ -128,9 +130,8 @@ ModuleManager::loadModule (std::string modulePath) generationTime = ( (GetGenerationTimeFunc) getGenerationTime) (); } - loadedModules[moduleFileName] = std::shared_ptr (new ModuleData ( - moduleName, moduleVersion, generationTime, - moduleDescriptor, factories) ); + loadedModules[moduleFileName] = std::make_shared( + moduleName, moduleVersion, generationTime, moduleDescriptor, factories); GST_INFO ("Loaded module: %s, version: %s, date: %s", moduleName.c_str(), moduleVersion.c_str(), generationTime.c_str() ); @@ -154,12 +155,11 @@ std::list split (const std::string &s, char delim) void ModuleManager::loadModules (std::string dirPath) { - GST_INFO ("Looking for modules, path: %s", dirPath.c_str() ); + GST_DEBUG ("Looking for modules, path: %s", dirPath.c_str() ); boost::filesystem::path dir (dirPath); if (!boost::filesystem::is_directory (dir) ) { - GST_WARNING ("Unable to load modules from: %s, it is not a directory", - dirPath.c_str() ); + GST_INFO ("Skip invalid path: %s", dirPath.c_str() ); return; } diff --git a/src/server/implementation/UUIDGenerator.cpp b/src/server/implementation/UUIDGenerator.cpp index 12eac2817..ebfbce4ef 100644 --- a/src/server/implementation/UUIDGenerator.cpp +++ b/src/server/implementation/UUIDGenerator.cpp @@ -30,7 +30,7 @@ class RandomGenerator { boost::uuids::basic_random_generator gen; boost::mt19937 ran; - pid_t pid; + pid_t pid{}; public: RandomGenerator () : gen (&ran) diff --git a/src/server/implementation/WorkerPool.cpp b/src/server/implementation/WorkerPool.cpp index af4c6dff2..63388fc59 100644 --- a/src/server/implementation/WorkerPool.cpp +++ b/src/server/implementation/WorkerPool.cpp @@ -19,6 +19,7 @@ #include "WorkerPool.hpp" #include +#include #define GST_CAT_DEFAULT kurento_worker_pool GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); @@ -54,18 +55,17 @@ WorkerPool::WorkerPool (int threads) /* Prepare watcher */ watcher_service = boost::shared_ptr< boost::asio::io_service > ( new boost::asio::io_service () ); - watcher_work = std::shared_ptr< boost::asio::io_service::work > - ( new boost::asio::io_service::work (*watcher_service) ); + watcher_work = + std::make_shared(*watcher_service); watcher = std::thread (std::bind (&workerThreadLoop, watcher_service) ); /* Prepare pool of threads */ io_service = boost::shared_ptr< boost::asio::io_service > ( new boost::asio::io_service () ); - work = std::shared_ptr< boost::asio::io_service::work > - ( new boost::asio::io_service::work (*io_service) ); + work = std::make_shared(*io_service); for (int i = 0; i < threads; i++) { - workers.push_back (std::thread (std::bind (&workerThreadLoop, io_service) ) ); + workers.emplace_back(std::bind(&workerThreadLoop, io_service)); } } @@ -94,18 +94,18 @@ WorkerPool::~WorkerPool() GST_ERROR ("Error detaching: %s", e.what() ); } - for (uint i = 0; i < workers.size (); i++) { + for (auto &worker : workers) { try { - if (std::this_thread::get_id() != workers[i].get_id() ) { - workers[i].join(); + if (std::this_thread::get_id() != worker.get_id()) { + worker.join(); } } catch (std::system_error &e) { GST_ERROR ("Error joining: %s", e.what() ); } try { - if (workers[i].joinable() ) { - workers[i].detach(); + if (worker.joinable()) { + worker.detach(); } } catch (std::system_error &e) { GST_ERROR ("Error detaching: %s", e.what() ); @@ -132,7 +132,7 @@ WorkerPool::checkWorkers () { std::shared_ptr> alive; - alive = std::shared_ptr> ( new std::atomic (false) ); + alive = std::make_shared>(false); io_service->post (std::bind (&async_worker_test, alive) ); @@ -157,7 +157,7 @@ WorkerPool::checkWorkers () std::unique_lock lock (mutex); if (!terminated) { - workers.push_back (std::thread (std::bind (&workerThreadLoop, io_service) ) ); + workers.emplace_back(std::bind(&workerThreadLoop, io_service)); } }); } diff --git a/src/server/implementation/objects/BaseRtpEndpointImpl.cpp b/src/server/implementation/objects/BaseRtpEndpointImpl.cpp index 8070c3eaa..762de0ebc 100644 --- a/src/server/implementation/objects/BaseRtpEndpointImpl.cpp +++ b/src/server/implementation/objects/BaseRtpEndpointImpl.cpp @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #include @@ -234,15 +234,15 @@ BaseRtpEndpointImpl::getMediaState () { current_media_state = std::make_shared (MediaState::DISCONNECTED); - for (auto it = mediaFlowInStates.begin(); it != mediaFlowInStates.end(); ++it) { - if (it->second->getValue() == MediaFlowState::FLOWING) { + for (auto &mediaFlowInState : mediaFlowInStates) { + if (mediaFlowInState.second->getValue() == MediaFlowState::FLOWING) { current_media_state = std::make_shared (MediaState::CONNECTED); goto end; } } - for (auto it = mediaFlowOutStates.begin(); it != mediaFlowOutStates.end(); ++it) { - if (it->second->getValue() == MediaFlowState::FLOWING) { + for (auto &mediaFlowOutState : mediaFlowOutStates) { + if (mediaFlowOutState.second->getValue() == MediaFlowState::FLOWING) { current_media_state = std::make_shared (MediaState::CONNECTED); goto end; } @@ -268,7 +268,7 @@ BaseRtpEndpointImpl::getRembParams () g_object_get (G_OBJECT (element), REMB_PARAMS, ¶ms, NULL); - if (params == NULL) { + if (params == nullptr) { return ret; } @@ -583,11 +583,11 @@ setDeprecatedProperties (std::shared_ptr eStats) std::vector> inStats = eStats->getE2ELatency(); - for (unsigned i = 0; i < inStats.size(); i++) { - if (inStats[i]->getName() == "sink_audio_default") { - eStats->setAudioE2ELatency (inStats[i]->getAvg() ); - } else if (inStats[i]->getName() == "sink_video_default") { - eStats->setVideoE2ELatency (inStats[i]->getAvg() ); + for (auto &inStat : inStats) { + if (inStat->getName() == "sink_audio_default") { + eStats->setAudioE2ELatency(inStat->getAvg()); + } else if (inStat->getName() == "sink_video_default") { + eStats->setVideoE2ELatency(inStat->getAvg()); } } } @@ -629,13 +629,13 @@ BaseRtpEndpointImpl::fillStatsReport (std::map e_stats = kms_utils_get_structure_by_name (stats, KMS_MEDIA_ELEMENT_FIELD); - if (e_stats != NULL) { + if (e_stats != nullptr) { collectEndpointStats (report, getId (), e_stats, timestamp); } rtc_stats = kms_utils_get_structure_by_name (stats, KMS_RTC_STATISTICS_FIELD); - if (rtc_stats != NULL) { + if (rtc_stats != nullptr) { collectRTCStats (report, timestamp, rtc_stats ); } diff --git a/src/server/implementation/objects/HubImpl.cpp b/src/server/implementation/objects/HubImpl.cpp index a699e1fa3..19dd2671f 100644 --- a/src/server/implementation/objects/HubImpl.cpp +++ b/src/server/implementation/objects/HubImpl.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #define GST_CAT_DEFAULT kurento_hub_impl GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); @@ -37,9 +38,9 @@ std::string HubImpl::getGstreamerDot ( std::string HubImpl::getGstreamerDot() { - return generateDotGraph (GST_BIN (element), - std::shared_ptr (new GstreamerDotDetails ( - GstreamerDotDetails::SHOW_VERBOSE) ) ); + return generateDotGraph( + GST_BIN(element), + std::make_shared(GstreamerDotDetails::SHOW_VERBOSE)); } HubImpl::HubImpl (const boost::property_tree::ptree &config, @@ -50,7 +51,7 @@ HubImpl::HubImpl (const boost::property_tree::ptree &config, pipe = std::dynamic_pointer_cast (getMediaPipeline() ); - element = gst_element_factory_make (factoryName.c_str(), NULL); + element = gst_element_factory_make(factoryName.c_str(), nullptr); g_object_ref (element); pipe->addElement (element); diff --git a/src/server/implementation/objects/HubPortImpl.hpp b/src/server/implementation/objects/HubPortImpl.hpp index c5e857b9d..fcd051dc9 100644 --- a/src/server/implementation/objects/HubPortImpl.hpp +++ b/src/server/implementation/objects/HubPortImpl.hpp @@ -57,8 +57,7 @@ class HubPortImpl : public MediaElementImpl, public virtual HubPort virtual void Serialize (JsonSerializer &serializer) override; private: - - int handlerId; + int handlerId{}; class StaticConstructor { diff --git a/src/server/implementation/objects/MediaElementImpl.cpp b/src/server/implementation/objects/MediaElementImpl.cpp index 313fc1fbd..4ab03f3d4 100644 --- a/src/server/implementation/objects/MediaElementImpl.cpp +++ b/src/server/implementation/objects/MediaElementImpl.cpp @@ -36,6 +36,7 @@ #include "ElementStats.hpp" #include "kmsstats.h" #include +#include #define GST_CAT_DEFAULT kurento_media_element_impl GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); @@ -69,14 +70,14 @@ class ElementConnectionDataInternal this->type = type; this->sourceDescription = sourceDescription; this->sinkDescription = sinkDescription; - this->sourcePadName = NULL; + this->sourcePadName = nullptr; setSinkPadName (); } ~ElementConnectionDataInternal() { - if (sourcePadName != NULL) { - free (sourcePadName); + if (sourcePadName != nullptr) { + g_free (sourcePadName); } } @@ -87,7 +88,7 @@ class ElementConnectionDataInternal this->type = data->getType(); this->sourceDescription = data->getSourceDescription(); this->sinkDescription = data->getSinkDescription(); - this->sourcePadName = NULL; + this->sourcePadName = nullptr; setSinkPadName (); } @@ -113,11 +114,11 @@ class ElementConnectionDataInternal void setSourcePadName (gchar *padName) { - if (this->sourcePadName != NULL) { + if (this->sourcePadName != nullptr) { GST_WARNING ("Resetting padName for connection"); if (this->sourcePadName != padName) { - free (this->sourcePadName); + g_free (this->sourcePadName); } } @@ -159,7 +160,7 @@ class ElementConnectionDataInternal std::shared_ptr sinkLocked = getSink (); if (!sinkLocked) { - return NULL; + return nullptr; } return gst_element_get_static_pad (sinkLocked->getGstreamerElement (), @@ -170,8 +171,8 @@ class ElementConnectionDataInternal { std::shared_ptr sourceLocked = getSource (); - if (!sourceLocked || sourcePadName == NULL) { - return NULL; + if (!sourceLocked || sourcePadName == nullptr) { + return nullptr; } return gst_element_get_static_pad (sourceLocked->getGstreamerElement (), @@ -222,72 +223,66 @@ convertMediaType (std::shared_ptr mediaType) throw KurentoException (UNSUPPORTED_MEDIA_TYPE, "Usupported media type"); } -static bool -check_parent_element (GstObject *src, GstObject *elem) +void +processBusMessage (GstBus *bus, GstMessage *msg, MediaElementImpl *self) { - GstObject *parent = GST_OBJECT_PARENT ( src); - - if (src == elem) { - return true; + GstDebugLevel log_level = GST_LEVEL_NONE; + GError *err = NULL; + gchar *dbg_info = NULL; + + switch (GST_MESSAGE_TYPE (msg)) { + case GST_MESSAGE_ERROR: + log_level = GST_LEVEL_ERROR; + gst_message_parse_error (msg, &err, &dbg_info); + break; + case GST_MESSAGE_WARNING: + log_level = GST_LEVEL_WARNING; + gst_message_parse_warning (msg, &err, &dbg_info); + break; + default: + return; + break; } - while (parent != NULL) { - if ( parent == elem ) { - return true; - } + GstElement *parent = self->element; + gint err_code = 0; + gchar *err_msg = NULL; - parent = GST_OBJECT_PARENT (parent); + if (!gst_object_has_as_ancestor (msg->src, GST_OBJECT (parent))) { + return; } - return false; -} - -void -_media_element_impl_bus_message (GstBus *bus, GstMessage *message, - gpointer data) -{ - if (message->type == GST_MESSAGE_ERROR) { - GError *err = NULL; - gchar *debug = NULL; - MediaElementImpl *elem = reinterpret_cast (data); - - if (elem == NULL) { - return; - } - - if (!check_parent_element (message->src, GST_OBJECT (elem->element) ) ) { - return; - } - - GST_ERROR ("MediaElement error: %" GST_PTR_FORMAT, message); - gst_message_parse_error (message, &err, &debug); - std::string errorMessage; + if (err != NULL) { + err_code = err->code; + err_msg = err->message; + } - if (err) { - errorMessage = std::string (err->message); - } + GST_CAT_LEVEL_LOG (GST_CAT_DEFAULT, log_level, NULL, + "Error code %d: '%s', element: %s, parent: %s", err_code, + (err_msg ? err_msg : "(None)"), GST_MESSAGE_SRC_NAME (msg), + GST_ELEMENT_NAME (parent)); - if (debug != NULL) { - errorMessage += " -> " + std::string (debug); - } + GST_CAT_LEVEL_LOG (GST_CAT_DEFAULT, log_level, NULL, + "Debugging info: %s", (dbg_info ? dbg_info : "(None)")); - try { - gint code = 0; + std::string errorMessage (err_msg); + if (dbg_info) { + errorMessage += " (" + std::string (dbg_info) + ")"; + } - if (err) { - code = err->code; - } + try { + gint code = err_code; + Error error (self->shared_from_this(), errorMessage, code, + "UNEXPECTED_ELEMENT_ERROR"); - Error error (elem->shared_from_this(), errorMessage , code, - "UNEXPECTED_ELEMENT_ERROR"); + self->signalError (error); + } catch (std::bad_weak_ptr &e) { + } - elem->signalError (error); - } catch (std::bad_weak_ptr &e) { - } + g_error_free (err); + g_free (dbg_info); - g_error_free (err); - g_free (debug); - } + return; } void @@ -317,13 +312,13 @@ _media_element_pad_added (GstElement *elem, GstPad *pad, gpointer data) std::string description; if (g_str_has_prefix (GST_OBJECT_NAME (pad), "audio_") ) { - type = std::shared_ptr (new MediaType (MediaType::AUDIO) ); + type = std::make_shared(MediaType::AUDIO); description = std::string (GST_OBJECT_NAME (pad) + sizeof ("audio_src") ); } else if (g_str_has_prefix (GST_OBJECT_NAME (pad), "video_") ) { - type = std::shared_ptr (new MediaType (MediaType::VIDEO) ); + type = std::make_shared(MediaType::VIDEO); description = std::string (GST_OBJECT_NAME (pad) + sizeof ("video_src") ); } else { - type = std::shared_ptr (new MediaType (MediaType::DATA) ); + type = std::make_shared(MediaType::DATA); description = std::string (GST_OBJECT_NAME (pad) + sizeof ("data_src") ); } @@ -365,13 +360,13 @@ _media_element_pad_added (GstElement *elem, GstPad *pad, gpointer data) std::string description; if (g_str_has_prefix (GST_OBJECT_NAME (pad), "sink_audio_") ) { - type = std::shared_ptr (new MediaType (MediaType::AUDIO) ); + type = std::make_shared(MediaType::AUDIO); description = std::string (GST_OBJECT_NAME (pad) + sizeof ("sink_audio") ); } else if (g_str_has_prefix (GST_OBJECT_NAME (pad), "sink_video_") ) { - type = std::shared_ptr (new MediaType (MediaType::VIDEO) ); + type = std::make_shared(MediaType::VIDEO); description = std::string (GST_OBJECT_NAME (pad) + sizeof ("sink_video") ); } else { - type = std::shared_ptr (new MediaType (MediaType::DATA) ); + type = std::make_shared(MediaType::DATA); description = std::string (GST_OBJECT_NAME (pad) + sizeof ("sink_data") ); } @@ -570,16 +565,16 @@ MediaElementImpl::MediaElementImpl (const boost::property_tree::ptree &config, pipe = std::dynamic_pointer_cast (getMediaPipeline() ); - element = gst_element_factory_make (factoryName.c_str(), NULL); + element = gst_element_factory_make(factoryName.c_str(), nullptr); - if (element == NULL) { + if (element == nullptr) { throw KurentoException (MEDIA_OBJECT_NOT_AVAILABLE, "Cannot create gstreamer element: " + factoryName); } bus = gst_pipeline_get_bus (GST_PIPELINE (pipe->getPipeline () ) ); handlerId = g_signal_connect (bus, "message", - G_CALLBACK (_media_element_impl_bus_message), this); + G_CALLBACK (processBusMessage), this); padAddedHandlerId = g_signal_connect (element, "pad_added", @@ -830,12 +825,11 @@ std::vector> void MediaElementImpl::connect (std::shared_ptr sink) { // Until mediaDescriptions are really used, we just connect audio an video - connect (sink, std::shared_ptr (new MediaType (MediaType::AUDIO) ), - DEFAULT, DEFAULT); - connect (sink, std::shared_ptr (new MediaType (MediaType::VIDEO) ), - DEFAULT, DEFAULT); - connect (sink, std::shared_ptr (new MediaType (MediaType::DATA) ), - DEFAULT, DEFAULT); + connect(sink, std::make_shared(MediaType::AUDIO), DEFAULT, + DEFAULT); + connect(sink, std::make_shared(MediaType::VIDEO), DEFAULT, + DEFAULT); + connect(sink, std::make_shared(MediaType::DATA), DEFAULT, DEFAULT); } void MediaElementImpl::connect (std::shared_ptr sink, @@ -904,7 +898,7 @@ void MediaElementImpl::connect (std::shared_ptr sink, sourceMediaDescription.c_str (), GST_PAD_SRC, &padName, NULL); - if (padName == NULL) { + if (padName == nullptr) { throw KurentoException (CONNECT_ERROR, "Element: '" + getName() + "'does note provide a connection for " + mediaType->getString () + "-" + @@ -932,7 +926,7 @@ void MediaElementImpl::performConnection (std::shared_ptr data) { - GstPad *src = NULL, *sink = NULL; + GstPad *src = nullptr, *sink = nullptr; src = data->getSourcePad (); @@ -973,12 +967,12 @@ MediaElementImpl::performConnection (std::shared_ptr void MediaElementImpl::disconnect (std::shared_ptr sink) { // Until mediaDescriptions are really used, we just disconnect audio an video - disconnect (sink, std::shared_ptr (new MediaType ( - MediaType::AUDIO) ), DEFAULT, DEFAULT); - disconnect (sink, std::shared_ptr (new MediaType ( - MediaType::VIDEO) ), DEFAULT, DEFAULT); - disconnect (sink, std::shared_ptr (new MediaType ( - MediaType::DATA) ), DEFAULT, DEFAULT); + disconnect(sink, std::make_shared(MediaType::AUDIO), DEFAULT, + DEFAULT); + disconnect(sink, std::make_shared(MediaType::VIDEO), DEFAULT, + DEFAULT); + disconnect(sink, std::make_shared(MediaType::DATA), DEFAULT, + DEFAULT); } void MediaElementImpl::disconnect (std::shared_ptr sink, @@ -1053,7 +1047,7 @@ void MediaElementImpl::setAudioFormat (std::shared_ptr caps) std::shared_ptr codec; std::stringstream sstm; std::string str_caps; - GstCaps *c = NULL; + GstCaps *c = nullptr; codec = caps->getCodec(); @@ -1088,7 +1082,7 @@ void MediaElementImpl::setVideoFormat (std::shared_ptr caps) std::shared_ptr fraction; std::stringstream sstm; std::string str_caps; - GstCaps *c = NULL; + GstCaps *c = nullptr; codec = caps->getCodec(); fraction = caps->getFramerate(); @@ -1134,9 +1128,9 @@ std::string MediaElementImpl::getGstreamerDot ( std::string MediaElementImpl::getGstreamerDot() { - return generateDotGraph (GST_BIN (element), - std::shared_ptr (new GstreamerDotDetails ( - GstreamerDotDetails::SHOW_VERBOSE) ) ); + return generateDotGraph( + GST_BIN(element), + std::make_shared(GstreamerDotDetails::SHOW_VERBOSE)); } void MediaElementImpl::setOutputBitrate (int bitrate) @@ -1223,7 +1217,7 @@ std::map > g_signal_emit_by_name (getGstreamerElement(), "stats", selector, &stats); - fillStatsReport (statsReport, stats, time (NULL) ); + fillStatsReport(statsReport, stats, time(nullptr)); gst_structure_free (stats); @@ -1233,13 +1227,13 @@ std::map > std::map > MediaElementImpl::getStats () { - return generateStats (NULL); + return generateStats(nullptr); } std::map > MediaElementImpl::getStats (std::shared_ptr mediaType) { - const gchar *selector = NULL; + const gchar *selector = nullptr; switch (mediaType->getValue () ) { case MediaType::AUDIO: @@ -1315,11 +1309,11 @@ setDeprecatedProperties (std::shared_ptr eStats) std::vector> inStats = eStats->getInputLatency(); - for (unsigned i = 0; i < inStats.size(); i++) { - if (inStats[i]->getName() == "sink_audio_default") { - eStats->setInputAudioLatency (inStats[i]->getAvg() ); - } else if (inStats[i]->getName() == "sink_video_default") { - eStats->setInputVideoLatency (inStats[i]->getAvg() ); + for (auto &inStat : inStats) { + if (inStat->getName() == "sink_audio_default") { + eStats->setInputAudioLatency(inStat->getAvg()); + } else if (inStat->getName() == "sink_video_default") { + eStats->setInputVideoLatency(inStat->getAvg()); } } } @@ -1335,7 +1329,7 @@ MediaElementImpl::fillStatsReport (std::map value = gst_structure_get_value (stats, KMS_MEDIA_ELEMENT_FIELD); - if (value == NULL) { + if (value == nullptr) { /* No element stats available */ return; } diff --git a/src/server/implementation/objects/MediaElementImpl.hpp b/src/server/implementation/objects/MediaElementImpl.hpp index 259347766..ea81798b3 100644 --- a/src/server/implementation/objects/MediaElementImpl.hpp +++ b/src/server/implementation/objects/MediaElementImpl.hpp @@ -216,8 +216,9 @@ class MediaElementImpl : public MediaObjectImpl, public virtual MediaElement static StaticConstructor staticConstructor; - friend void _media_element_impl_bus_message (GstBus *bus, GstMessage *message, - gpointer data); + friend void processBusMessage (GstBus *bus, GstMessage *msg, + MediaElementImpl *self); + friend void _media_element_pad_added (GstElement *elem, GstPad *pad, gpointer data); }; diff --git a/src/server/implementation/objects/MediaObjectImpl.cpp b/src/server/implementation/objects/MediaObjectImpl.cpp index ce09a9985..edfe2d332 100644 --- a/src/server/implementation/objects/MediaObjectImpl.cpp +++ b/src/server/implementation/objects/MediaObjectImpl.cpp @@ -40,7 +40,7 @@ MediaObjectImpl::MediaObjectImpl (const boost::property_tree::ptree &config, { this->parent = parent; - creationTime = time (NULL); + creationTime = time(nullptr); initialId = createId(); this->sendTagsInEvents = false; } diff --git a/src/server/implementation/objects/MediaObjectImpl.hpp b/src/server/implementation/objects/MediaObjectImpl.hpp index 75d727d0b..50059a8bf 100644 --- a/src/server/implementation/objects/MediaObjectImpl.hpp +++ b/src/server/implementation/objects/MediaObjectImpl.hpp @@ -127,7 +127,7 @@ class MediaObjectImpl : public virtual MediaObject } catch (KurentoException &e) { GST_WARNING ("Posible error deserializing %s from config", key.c_str() ); } catch (std::exception &e) { - GST_WARNING ("Unknown error getting%s from config", key.c_str() ); + GST_WARNING ("Unknown error getting '%s' from config", key.c_str() ); } return defaultValue; diff --git a/src/server/implementation/objects/MediaPipelineImpl.cpp b/src/server/implementation/objects/MediaPipelineImpl.cpp index 42f82242b..d170bd341 100644 --- a/src/server/implementation/objects/MediaPipelineImpl.cpp +++ b/src/server/implementation/objects/MediaPipelineImpl.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include "kmselement.h" #define GST_CAT_DEFAULT kurento_media_pipeline_impl @@ -33,23 +34,42 @@ namespace kurento { void -MediaPipelineImpl::log_bus_issue(GstBin *bin, GstMessage *msg, - gboolean is_error) +MediaPipelineImpl::processBusMessage (GstMessage *msg) { - GstDebugLevel log_level = is_error ? GST_LEVEL_ERROR : GST_LEVEL_WARNING; - + GstDebugLevel log_level = GST_LEVEL_NONE; GError *err = NULL; gchar *dbg_info = NULL; - gst_message_parse_error (msg, &err, &dbg_info); - gint err_code = (err ? err->code : -1); - gchar *err_msg = (err ? g_strdup (err->message) : g_strdup ("None")); + switch (GST_MESSAGE_TYPE (msg)) { + case GST_MESSAGE_ERROR: + log_level = GST_LEVEL_ERROR; + gst_message_parse_error (msg, &err, &dbg_info); + break; + case GST_MESSAGE_WARNING: + log_level = GST_LEVEL_WARNING; + gst_message_parse_warning (msg, &err, &dbg_info); + break; + default: + return; + break; + } + + GstElement *parent = this->pipeline; + gint err_code = 0; + gchar *err_msg = NULL; + + if (err != NULL) { + err_code = err->code; + err_msg = err->message; + } GST_CAT_LEVEL_LOG (GST_CAT_DEFAULT, log_level, NULL, - "Element '%s' bus code %d: %s", GST_OBJECT_NAME (msg->src), err_code, - err_msg); + "Error code %d: '%s', element: %s, parent: %s", err_code, + (err_msg ? err_msg : "(None)"), GST_MESSAGE_SRC_NAME (msg), + GST_ELEMENT_NAME (parent)); + GST_CAT_LEVEL_LOG (GST_CAT_DEFAULT, log_level, NULL, - "Debugging info: %s", ((dbg_info) ? dbg_info : "None")); + "Debugging info: %s", (dbg_info ? dbg_info : "(None)")); std::string errorMessage (err_msg); if (dbg_info) { @@ -66,27 +86,14 @@ MediaPipelineImpl::log_bus_issue(GstBin *bin, GstMessage *msg, } gchar *dot_name = g_strdup_printf ("%s_bus_%d", GST_DEFAULT_NAME, err_code); - GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (bin, GST_DEBUG_GRAPH_SHOW_ALL, dot_name); + GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (parent), GST_DEBUG_GRAPH_SHOW_ALL, + dot_name); g_free(dot_name); g_error_free (err); g_free (dbg_info); - g_free (err_msg); -} -void -MediaPipelineImpl::busMessage (GstMessage *message) -{ - switch (GST_MESSAGE_TYPE (message)) { - case GST_MESSAGE_ERROR: - log_bus_issue (GST_BIN (pipeline), message, TRUE); - break; - case GST_MESSAGE_WARNING: - log_bus_issue (GST_BIN (pipeline), message, FALSE); - break; - default: - break; - } + return; } void MediaPipelineImpl::postConstructor () @@ -99,7 +106,7 @@ void MediaPipelineImpl::postConstructor () gst_bus_add_signal_watch (bus); busMessageHandler = register_signal_handler (G_OBJECT (bus), "message", std::function (std::bind ( - &MediaPipelineImpl::busMessage, this, + &MediaPipelineImpl::processBusMessage, this, std::placeholders::_2) ), std::dynamic_pointer_cast (shared_from_this() ) ); @@ -111,9 +118,9 @@ MediaPipelineImpl::MediaPipelineImpl (const boost::property_tree::ptree &config) { GstClock *clock; - pipeline = gst_pipeline_new (NULL); + pipeline = gst_pipeline_new(nullptr); - if (pipeline == NULL) { + if (pipeline == nullptr) { throw KurentoException (MEDIA_OBJECT_NOT_AVAILABLE, "Cannot create gstreamer pipeline"); } @@ -150,9 +157,9 @@ std::string MediaPipelineImpl::getGstreamerDot ( std::string MediaPipelineImpl::getGstreamerDot() { - return generateDotGraph (GST_BIN (pipeline), - std::shared_ptr (new GstreamerDotDetails ( - GstreamerDotDetails::SHOW_VERBOSE) ) ); + return generateDotGraph( + GST_BIN(pipeline), + std::make_shared(GstreamerDotDetails::SHOW_VERBOSE)); } bool diff --git a/src/server/implementation/objects/MediaPipelineImpl.hpp b/src/server/implementation/objects/MediaPipelineImpl.hpp index 09a73a4d6..2c2d5b516 100644 --- a/src/server/implementation/objects/MediaPipelineImpl.hpp +++ b/src/server/implementation/objects/MediaPipelineImpl.hpp @@ -22,6 +22,7 @@ #include #include #include +#include namespace kurento { @@ -75,8 +76,7 @@ class MediaPipelineImpl : public MediaObjectImpl, public virtual MediaPipeline std::recursive_mutex recMutex; bool latencyStats = false; - void log_bus_issue (GstBin * bin, GstMessage * msg, gboolean is_error); - void busMessage (GstMessage *message); + void processBusMessage (GstMessage *msg); class StaticConstructor { diff --git a/src/server/implementation/objects/SdpEndpointImpl.cpp b/src/server/implementation/objects/SdpEndpointImpl.cpp index 5d149252e..5b0339f7e 100644 --- a/src/server/implementation/objects/SdpEndpointImpl.cpp +++ b/src/server/implementation/objects/SdpEndpointImpl.cpp @@ -41,7 +41,7 @@ static GstSDPMessage * str_to_sdp (const std::string &sdpStr) { GstSDPResult result; - GstSDPMessage *sdp = NULL; + GstSDPMessage *sdp = nullptr; result = gst_sdp_message_new (&sdp); @@ -58,7 +58,7 @@ str_to_sdp (const std::string &sdpStr) throw KurentoException (SDP_PARSE_ERROR, "Error parsing SDP"); } - if (gst_sdp_message_get_version (sdp) == NULL) { + if (gst_sdp_message_get_version(sdp) == nullptr) { gst_sdp_message_free (sdp); throw KurentoException (SDP_PARSE_ERROR, "Invalid SDP"); } @@ -74,7 +74,7 @@ sdp_to_str (std::string &_return, const GstSDPMessage *sdp) sdpGchar = gst_sdp_message_as_text (sdp); _return.clear (); _return.append (sdpGchar); - free (sdpGchar); + g_free (sdpGchar); } static void @@ -97,7 +97,7 @@ void SdpEndpointImpl::postConstructor () g_signal_emit_by_name (element, "create-session", &sess_id); - if (sess_id == NULL) { + if (sess_id == nullptr) { throw KurentoException (SDP_END_POINT_CANNOT_CREATE_SESSON, "Cannot create session"); } @@ -193,7 +193,7 @@ void SdpEndpointImpl::setMaxAudioRecvBandwidth (int maxAudioRecvBandwidth) std::string SdpEndpointImpl::generateOffer () { - GstSDPMessage *offer = NULL; + GstSDPMessage *offer = nullptr; std::string offerStr; bool expected = false; @@ -205,7 +205,7 @@ std::string SdpEndpointImpl::generateOffer () g_signal_emit_by_name (element, "generate-offer", sessId.c_str (), &offer); - if (offer == NULL) { + if (offer == nullptr) { offerInProcess = false; throw KurentoException (SDP_END_POINT_GENERATE_OFFER_ERROR, "Error generating offer"); @@ -220,7 +220,7 @@ std::string SdpEndpointImpl::generateOffer () std::string SdpEndpointImpl::processOffer (const std::string &offer) { - GstSDPMessage *offerSdp = NULL, *result = NULL; + GstSDPMessage *offerSdp = nullptr, *result = nullptr; std::string offerSdpStr; bool expected = false; @@ -240,7 +240,7 @@ std::string SdpEndpointImpl::processOffer (const std::string &offer) &result); gst_sdp_message_free (offerSdp); - if (result == NULL) { + if (result == nullptr) { offerInProcess = false; throw KurentoException (SDP_END_POINT_PROCESS_OFFER_ERROR, "Error processing offer"); @@ -298,12 +298,12 @@ std::string SdpEndpointImpl::processAnswer (const std::string &answer) std::string SdpEndpointImpl::getLocalSessionDescriptor () { - GstSDPMessage *localSdp = NULL; + GstSDPMessage *localSdp = nullptr; std::string localSdpStr; g_signal_emit_by_name (element, "get-local-sdp", sessId.c_str (), &localSdp); - if (localSdp == NULL) { + if (localSdp == nullptr) { throw KurentoException (SDP_END_POINT_NO_LOCAL_SDP_ERROR, "No local SDP"); } @@ -315,12 +315,12 @@ std::string SdpEndpointImpl::getLocalSessionDescriptor () std::string SdpEndpointImpl::getRemoteSessionDescriptor () { - GstSDPMessage *remoteSdp = NULL; + GstSDPMessage *remoteSdp = nullptr; std::string remoteSdpStr; g_signal_emit_by_name (element, "get-remote-sdp", sessId.c_str (), &remoteSdp); - if (remoteSdp == NULL) { + if (remoteSdp == nullptr) { throw KurentoException (SDP_END_POINT_NO_REMOTE_SDP_ERROR, "No remote SDP"); } diff --git a/src/server/implementation/objects/SdpEndpointImpl.hpp b/src/server/implementation/objects/SdpEndpointImpl.hpp index 5eaff8e44..b47bb3830 100644 --- a/src/server/implementation/objects/SdpEndpointImpl.hpp +++ b/src/server/implementation/objects/SdpEndpointImpl.hpp @@ -70,9 +70,9 @@ class SdpEndpointImpl : public SessionEndpointImpl, public virtual SdpEndpoint private: static std::mutex sdpMutex; - std::atomic_bool offerInProcess; - std::atomic_bool waitingAnswer; - std::atomic_bool answerProcessed; + std::atomic_bool offerInProcess{}; + std::atomic_bool waitingAnswer{}; + std::atomic_bool answerProcessed{}; class StaticConstructor { diff --git a/src/server/implementation/objects/UriEndpointImpl.cpp b/src/server/implementation/objects/UriEndpointImpl.cpp index 85cfdf734..8d8338a71 100644 --- a/src/server/implementation/objects/UriEndpointImpl.cpp +++ b/src/server/implementation/objects/UriEndpointImpl.cpp @@ -162,7 +162,7 @@ UriEndpointImpl::~UriEndpointImpl () void UriEndpointImpl::pause () { - GError *error = NULL; + GError *error = nullptr; if (!kms_uri_endpoint_set_state (KMS_URI_ENDPOINT (getGstreamerElement() ), KMS_URI_ENDPOINT_STATE_PAUSE, &error) ) { @@ -173,7 +173,7 @@ void UriEndpointImpl::pause () void UriEndpointImpl::stop () { - GError *error = NULL; + GError *error = nullptr; if (!kms_uri_endpoint_set_state (KMS_URI_ENDPOINT (getGstreamerElement() ), KMS_URI_ENDPOINT_STATE_STOP, &error) ) { @@ -185,7 +185,7 @@ void UriEndpointImpl::stop () void UriEndpointImpl::start () { - GError *error = NULL; + GError *error = nullptr; if (!kms_uri_endpoint_set_state (KMS_URI_ENDPOINT (getGstreamerElement() ), KMS_URI_ENDPOINT_STATE_START, &error) ) { diff --git a/src/server/implementation/objects/UriEndpointImpl.hpp b/src/server/implementation/objects/UriEndpointImpl.hpp index e51d48003..08e9fc029 100644 --- a/src/server/implementation/objects/UriEndpointImpl.hpp +++ b/src/server/implementation/objects/UriEndpointImpl.hpp @@ -70,7 +70,7 @@ class UriEndpointImpl : public EndpointImpl, public virtual UriEndpoint std::string uri; std::string absolute_uri; - gulong stateChangedHandlerId; + gulong stateChangedHandlerId{}; std::shared_ptr state; void checkUri (); diff --git a/src/server/interface/core.kmd.json b/src/server/interface/core.kmd.json index 63d5b679a..2237605d6 100644 --- a/src/server/interface/core.kmd.json +++ b/src/server/interface/core.kmd.json @@ -1,6 +1,6 @@ { "name": "core", - "version": "6.7.1", + "version": "6.8.1", "code": { "kmd": { "java": { @@ -16,7 +16,7 @@ }, "js": { "nodeName": "kurento-client-core", - "npmDescription": "Base classes for kurento media server api", + "npmDescription": "JavaScript Client API for Kurento Media Server", "npmGit": "Kurento/kurento-client-core-js" } }, diff --git a/src/server/interface/package.json b/src/server/interface/package.json index 12b0d4e46..0423a59df 100644 --- a/src/server/interface/package.json +++ b/src/server/interface/package.json @@ -1,8 +1,49 @@ { - "license": "ALv2", - "homepage": "http://www.kurento.com", - "author": "Kurento (http://kurento.org)", + "keywords": [ + "kurento", + "mcu", + "sfu", + "rpc", + "mediaserver", + "pipe", + "audio", + "video", + "media", + "recording", + "stream", + "streaming", + "videoconference", + "broadcast", + "multicast", + "client", + "server", + "browser", + "chrome", + "edge", + "firefox", + "safari", + "webrtc", + "datachannel", + "sdp", + "ice", + "stun", + "turn", + "h264", + "h.264", + "opus", + "vp8", + "rtp", + "srtp", + "rtsp" + ], + "homepage": "https://www.kurento.org", + "license": "Apache-2.0", + "author": "Kurento (https://www.kurento.org)", + "contributors": [ + "Kurento Community (https://www.kurento.org)" + ], "bugs": { + "url": "https://github.com/Kurento/bugtracker/issues", "email": "kurento@googlegroups.com" } } diff --git a/tests/check/CMakeLists.txt b/tests/check/CMakeLists.txt index 484b72aed..29a5b98b9 100644 --- a/tests/check/CMakeLists.txt +++ b/tests/check/CMakeLists.txt @@ -15,7 +15,8 @@ set(VALGRIND_TEST_VARIABLES "${TEST_VARIABLES}" "CK_DEFAULT_TIMEOUT=1000" ) -set(SUPPRESSIONS "${CMAKE_CURRENT_SOURCE_DIR}/valgrind.supp") +list(APPEND SUPPRESSIONS + "${CMAKE_CURRENT_SOURCE_DIR}/valgrind.supp") add_subdirectory(element) add_subdirectory(general) diff --git a/tests/server/CMakeLists.txt b/tests/server/CMakeLists.txt index 5e49e69ca..8695fb292 100644 --- a/tests/server/CMakeLists.txt +++ b/tests/server/CMakeLists.txt @@ -5,7 +5,8 @@ set(TEST_VARIABLES set(VALGRIND_TEST_VARIABLES "DEBUG_MEDIASET=1" ) -set(SUPPRESSIONS "${CMAKE_CURRENT_SOURCE_DIR}/valgrind.supp") +list(APPEND SUPPRESSIONS + "${CMAKE_CURRENT_SOURCE_DIR}/valgrind.supp") add_test_program(test_module_manager moduleManager.cpp) if(TARGET ${LIBRARY_NAME}module) diff --git a/tests/server/complexType.cpp b/tests/server/complexType.cpp index d9702f3d1..35c799e10 100644 --- a/tests/server/complexType.cpp +++ b/tests/server/complexType.cpp @@ -34,9 +34,7 @@ struct GF { BOOST_GLOBAL_FIXTURE (GF) -GF::GF() -{ -} +GF::GF() = default; GF::~GF() { @@ -50,7 +48,7 @@ BOOST_AUTO_TEST_CASE (complex_type) std::shared_ptr mediaPipelineFactory; std::shared_ptr mediaPipeline; - gst_init (NULL, NULL); + gst_init(nullptr, nullptr); std::string moduleName = "../../src/server/libkmscoremodule.so"; diff --git a/tests/server/mediaElement.cpp b/tests/server/mediaElement.cpp index 3377a2ba7..cf6c14f63 100644 --- a/tests/server/mediaElement.cpp +++ b/tests/server/mediaElement.cpp @@ -41,7 +41,7 @@ BOOST_GLOBAL_FIXTURE (GF) GF::GF() { - gst_init (NULL, NULL); + gst_init(nullptr, nullptr); moduleManager.loadModulesFromDirectories ("../../src/server"); } diff --git a/tests/server/mediaObject.cpp b/tests/server/mediaObject.cpp index a88f22b01..8c1bad3a8 100644 --- a/tests/server/mediaObject.cpp +++ b/tests/server/mediaObject.cpp @@ -42,7 +42,7 @@ BOOST_GLOBAL_FIXTURE (GF) GF::GF() { - gst_init (NULL, NULL); + gst_init(nullptr, nullptr); moduleManager.loadModulesFromDirectories ("../../src/server"); } @@ -200,7 +200,7 @@ BOOST_AUTO_TEST_CASE (creation_time) std::shared_ptr pipe = std::dynamic_pointer_cast (MediaSet::getMediaSet()->getMediaObject ( mediaPipelineId) ); - time_t now = time (NULL); + time_t now = time(nullptr); BOOST_CHECK (pipe->getCreationTime() <= mediaElement->getCreationTime() ); BOOST_CHECK (pipe->getCreationTime() <= now); diff --git a/tests/server/mediaSet.cpp b/tests/server/mediaSet.cpp index 52cd52333..5f5ac6b33 100644 --- a/tests/server/mediaSet.cpp +++ b/tests/server/mediaSet.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include @@ -44,11 +45,11 @@ BOOST_GLOBAL_FIXTURE (InitTests) InitTests::InitTests() { - gst_init (NULL, NULL); + gst_init(nullptr, nullptr); - moduleManager = std::shared_ptr (new ModuleManager() ); + moduleManager = std::make_shared(); - gst_init (NULL, NULL); + gst_init(nullptr, nullptr); std::string moduleName = "../../src/server/libkmscoremodule.so"; @@ -80,18 +81,17 @@ F::F () factories.push_back (factIt.first); } - modules.push_back (std::shared_ptr (new ModuleInfo ( - moduleIt.second->getVersion(), moduleIt.second->getName(), - moduleIt.second->getGenerationTime(), factories) ) ); + modules.push_back(std::make_shared( + moduleIt.second->getVersion(), moduleIt.second->getName(), + moduleIt.second->getGenerationTime(), factories)); } std::shared_ptr type (new ServerType (ServerType::KMS) ); std::vector capabilities; - capabilities.push_back ("transactions"); + capabilities.emplace_back("transactions"); - std::shared_ptr serverInfo = std::shared_ptr - (new ServerInfo ("", modules, - type, capabilities) ); + std::shared_ptr serverInfo = + std::make_shared("", modules, type, capabilities); serverManager = std::dynamic_pointer_cast (MediaSet::getMediaSet ()->ref (new ServerManagerImpl ( diff --git a/tests/server/moduleManager.cpp b/tests/server/moduleManager.cpp index e92b2cc7d..be7bd1e66 100644 --- a/tests/server/moduleManager.cpp +++ b/tests/server/moduleManager.cpp @@ -36,9 +36,7 @@ struct GF { BOOST_GLOBAL_FIXTURE (GF) -GF::GF() -{ -} +GF::GF() = default; GF::~GF() { @@ -51,7 +49,7 @@ BOOST_AUTO_TEST_CASE (load_modules) std::shared_ptr mediaPipelineFactory; std::shared_ptr mediaPipeline; - gst_init (NULL, NULL); + gst_init(nullptr, nullptr); std::string moduleName = "../../src/server/libkmscoremodule.so"; diff --git a/tests/server/rtpEndpoint.cpp b/tests/server/rtpEndpoint.cpp index d79357a47..b28ca99ab 100644 --- a/tests/server/rtpEndpoint.cpp +++ b/tests/server/rtpEndpoint.cpp @@ -45,7 +45,7 @@ BOOST_GLOBAL_FIXTURE (GF) GF::GF() { - gst_init (NULL, NULL); + gst_init(nullptr, nullptr); moduleManager.loadModulesFromDirectories ("../../src/server:../../.."); } diff --git a/tests/server/sdpEndpoint.cpp b/tests/server/sdpEndpoint.cpp index 0145d4486..7c891cb39 100644 --- a/tests/server/sdpEndpoint.cpp +++ b/tests/server/sdpEndpoint.cpp @@ -41,17 +41,14 @@ struct GF { class SdpEndpointFactory : public Factory { public: - std::string getName() const - { - return "SdpEndpointFactory"; - } + std::string getName () const override { return "SdpEndpointFactory"; } protected: - MediaObjectImpl *createObjectPointer (const boost::property_tree::ptree - &conf, const Json::Value ¶ms) const + MediaObjectImpl *createObjectPointer (const boost::property_tree::ptree &conf, + const Json::Value ¶ms) const override { std::string mediaPipelineId = params["mediaPipeline"].asString (); - bool useIpv6 = false;; + bool useIpv6 = false; if (params.isMember ("useIpv6") ) { Json::Value useIpv6Param = params["useIpv6"]; @@ -72,7 +69,7 @@ BOOST_GLOBAL_FIXTURE (GF) GF::GF() { - gst_init (NULL, NULL); + gst_init(nullptr, nullptr); moduleManager.loadModulesFromDirectories ("../../src/server"); } diff --git a/tests/server/uriEndpoint.cpp b/tests/server/uriEndpoint.cpp index 907cf3ccd..6a114ad50 100644 --- a/tests/server/uriEndpoint.cpp +++ b/tests/server/uriEndpoint.cpp @@ -41,14 +41,11 @@ struct GF { class UriEndpointFactory : public Factory { public: - std::string getName() const - { - return "UriEndpointFactory"; - } + std::string getName () const override { return "UriEndpointFactory"; } protected: - MediaObjectImpl *createObjectPointer (const boost::property_tree::ptree - &conf, const Json::Value ¶ms) const + MediaObjectImpl *createObjectPointer (const boost::property_tree::ptree &conf, + const Json::Value ¶ms) const override { std::string mediaPipelineId = params["mediaPipeline"].asString (); std::string uri = params["uri"].asString (); @@ -64,7 +61,7 @@ BOOST_GLOBAL_FIXTURE (GF) GF::GF() { - gst_init (NULL, NULL); + gst_init(nullptr, nullptr); moduleManager.loadModulesFromDirectories ("../../src/server"); }