From b68767ca06e733a00d9293a774e8b455088b6dc6 Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Fri, 13 Nov 2020 16:32:45 -0300 Subject: [PATCH] encoding: Implement encodebin2 with an ON_REQUEST src pad Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/issues/304 --- docs/plugins/gst_plugins_cache.json | 41 ++++++++++++++++ gst/encoding/gstencodebasebin.c | 55 +++++++++++++++++----- gst/encoding/gstencodebasebin.h | 10 ++-- gst/encoding/gstencodebin2.c | 73 +++++++++++++++++++++++++++++ gst/encoding/gstencodebin2.h | 25 ++++++++++ gst/encoding/meson.build | 1 + gst/encoding/plugin.c | 4 ++ 7 files changed, 192 insertions(+), 17 deletions(-) create mode 100644 gst/encoding/gstencodebin2.c create mode 100644 gst/encoding/gstencodebin2.h diff --git a/docs/plugins/gst_plugins_cache.json b/docs/plugins/gst_plugins_cache.json index 6834396320..8184f7fd84 100644 --- a/docs/plugins/gst_plugins_cache.json +++ b/docs/plugins/gst_plugins_cache.json @@ -2120,6 +2120,47 @@ } } }, + "encodebin2": { + "author": "Edward Hervey ", + "description": "Convenience encoding/muxing element", + "hierarchy": [ + "GstEncodeBin2", + "GstEncodeBaseBin", + "GstBin", + "GstElement", + "GstObject", + "GInitiallyUnowned", + "GObject" + ], + "interfaces": [ + "GstChildProxy" + ], + "klass": "Generic/Bin/Encoder", + "long-name": "Encoder Bin", + "pad-templates": { + "audio_%%u": { + "caps": "ANY", + "direction": "sink", + "presence": "request" + }, + "private_%%u": { + "caps": "ANY", + "direction": "sink", + "presence": "request" + }, + "src_%%u": { + "caps": "ANY", + "direction": "src", + "presence": "sometimes" + }, + "video_%%u": { + "caps": "ANY", + "direction": "sink", + "presence": "request" + } + }, + "rank": "none" + }, "streamcombiner": { "author": "Edward Hervey ", "description": "Recombines streams split by the streamsplitter element", diff --git a/gst/encoding/gstencodebasebin.c b/gst/encoding/gstencodebasebin.c index 6763279568..956e809cd3 100644 --- a/gst/encoding/gstencodebasebin.c +++ b/gst/encoding/gstencodebasebin.c @@ -2,6 +2,7 @@ * Copyright (C) 2009 Edward Hervey * (C) 2009 Nokia Corporation * (C) 2016 Jan Schmidt + * (C) 2020 Thibault saunier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -273,6 +274,8 @@ gst_encode_base_bin_class_init (GstEncodeBaseBinClass * klass) gobject_klass = (GObjectClass *) klass; gstelement_klass = (GstElementClass *) klass; + GST_DEBUG_CATEGORY_INIT (gst_encode_base_bin_debug, "encodebasebin", 0, + "base encodebin"); gobject_klass->dispose = gst_encode_base_bin_dispose; gobject_klass->set_property = gst_encode_base_bin_set_property; gobject_klass->get_property = gst_encode_base_bin_get_property; @@ -2018,7 +2021,7 @@ create_elements_and_pads (GstEncodeBaseBin * ebin) gst_encoding_profile_get_name (ebin->profile)); if (GST_IS_ENCODING_CONTAINER_PROFILE (ebin->profile)) { - /* 1. Get the compatible muxer */ + /* Get the compatible muxer */ muxer = _get_muxer (ebin); if (G_UNLIKELY (muxer == NULL)) goto no_muxer; @@ -2027,19 +2030,38 @@ create_elements_and_pads (GstEncodeBaseBin * ebin) ebin->muxer = muxer; gst_bin_add ((GstBin *) ebin, muxer); - /* 2. Ghost the muxer source pad */ - - /* FIXME : We should figure out if it's a static/request/dyamic pad, + /* If the subclass exposes a static sourcepad, ghost the muxer + * output, otherwise expose the muxer srcpad if it has one, + * do not expose any srcpad if we are dealing with a muxing sink. */ + /* FIXME : We should figure out if it's a static/request/dynamic pad, * but for the time being let's assume it's a static pad :) */ muxerpad = gst_element_get_static_pad (muxer, "src"); - if (G_UNLIKELY (muxerpad == NULL)) - goto no_muxer_pad; + if (ebin->srcpad) { + if (G_UNLIKELY (muxerpad == NULL)) + goto no_muxer_pad; + if (!gst_ghost_pad_set_target (GST_GHOST_PAD (ebin->srcpad), muxerpad)) + goto no_muxer_ghost_pad; - if (!gst_ghost_pad_set_target (GST_GHOST_PAD (ebin->srcpad), muxerpad)) - goto no_muxer_ghost_pad; + gst_object_unref (muxerpad); + } else if (muxerpad) { + GstPadTemplate *template = + gst_element_get_pad_template (GST_ELEMENT (ebin), "src_%u"); + gchar *name; + GstPad *pad; - gst_object_unref (muxerpad); - /* 3. Activate fixed presence streams */ + GST_OBJECT_LOCK (ebin); + name = g_strdup_printf ("src_%u", GST_ELEMENT (ebin)->numsrcpads); + GST_OBJECT_UNLOCK (ebin); + + pad = gst_ghost_pad_new_from_template (name, muxerpad, template); + g_free (name); + if (!pad) + goto no_muxer_ghost_pad; + + gst_element_add_pad (GST_ELEMENT (ebin), pad); + } + + /* Activate fixed presence streams */ profiles = gst_encoding_container_profile_get_profiles (GST_ENCODING_CONTAINER_PROFILE (ebin->profile)); @@ -2290,6 +2312,8 @@ stream_group_remove (GstEncodeBaseBin * ebin, StreamGroup * sgroup) static void gst_encode_base_bin_tear_down_profile (GstEncodeBaseBin * ebin) { + GstElement *element = GST_ELEMENT (ebin); + if (G_UNLIKELY (ebin->profile == NULL)) return; @@ -2299,8 +2323,10 @@ gst_encode_base_bin_tear_down_profile (GstEncodeBaseBin * ebin) while (ebin->streams) stream_group_remove (ebin, (StreamGroup *) ebin->streams->data); - /* Set ghostpad target to NULL */ - gst_ghost_pad_set_target (GST_GHOST_PAD (ebin->srcpad), NULL); + if (ebin->srcpad) { + /* Set ghostpad target to NULL */ + gst_ghost_pad_set_target (GST_GHOST_PAD (ebin->srcpad), NULL); + } /* Remove muxer if present */ if (ebin->muxer) { @@ -2309,6 +2335,11 @@ gst_encode_base_bin_tear_down_profile (GstEncodeBaseBin * ebin) ebin->muxer = NULL; } + if (!element->srcpads) { + while (element->srcpads) + gst_element_remove_pad (element, element->srcpads->data); + } + /* free/clear profile */ gst_encoding_profile_unref (ebin->profile); ebin->profile = NULL; diff --git a/gst/encoding/gstencodebasebin.h b/gst/encoding/gstencodebasebin.h index d8a44576e6..708e5ce5b3 100644 --- a/gst/encoding/gstencodebasebin.h +++ b/gst/encoding/gstencodebasebin.h @@ -1,6 +1,8 @@ /* GStreamer encoding bin * Copyright (C) 2009 Edward Hervey * (C) 2009 Nokia Corporation + * (C) 2016 Jan Schmidt + * (C) 2020 Thibault saunier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -18,8 +20,7 @@ * Boston, MA 02110-1301, USA. */ -#ifndef __GST_ENCODEBIN_H__ -#define __GST_ENCODEBIN_H__ +#pragma once #include #include @@ -29,6 +30,7 @@ #define GST_ENCODE_BASE_BIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ENCODE_BASE_BIN,GstEncodeBinClass)) #define GST_IS_ENCODE_BASE_BIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ENCODE_BASE_BIN)) #define GST_IS_ENCODE_BASE_BIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ENCODE_BASE_BIN)) +#define GST_ENCODE_BASE_BIN_GET_CLASS(klass) (G_TYPE_INSTANCE_GET_CLASS ((klass), GST_TYPE_ENCODE_BASE_BIN, GstEncodeBaseBinClass)) typedef struct _GstEncodeBaseBin GstEncodeBaseBin; typedef struct _GstEncodeBaseBinClass GstEncodeBaseBinClass; @@ -90,6 +92,4 @@ struct _GstEncodeBaseBinClass }; GType gst_encode_base_bin_get_type(void); -G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstEncodeBaseBin, gst_object_unref) - -#endif /* __GST_ENCODEBIN_H__ */ +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstEncodeBaseBin, gst_object_unref) \ No newline at end of file diff --git a/gst/encoding/gstencodebin2.c b/gst/encoding/gstencodebin2.c new file mode 100644 index 0000000000..ebd3a082fe --- /dev/null +++ b/gst/encoding/gstencodebin2.c @@ -0,0 +1,73 @@ +/* GStreamer encoding bin + * Copyright (C) 2016 Jan Schmidt + * (C) 2020 Thibault saunier + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include "gstencodebasebin.h" +#include "gstencodebin2.h" + +/** + * SECTION:element-encodebin2 + * + * Encodebin2 is an updated version of #encodebin which has a request srcpad + * instead of having an always source pad. This makes the element more flexible + * and allows supporting muxing sinks for example. + * + * Based on the profile that was set (via the #GstEncodeBaseBin:profile + * property), EncodeBin will internally select and configure the required + * elements (encoders, muxers, but also audio and video converters) so that you + * can provide it raw or pre-encoded streams of data in input and have your + * encoded/muxed/converted stream in output. + * + * Since: 1.20 + */ + +enum +{ + PROP_0, +}; + +static GstStaticPadTemplate muxer_src_template = +GST_STATIC_PAD_TEMPLATE ("src_%u", GST_PAD_SRC, GST_PAD_SOMETIMES, + GST_STATIC_CAPS_ANY); + +struct _GstEncodeBin2 +{ + GstEncodeBaseBin parent; +}; + +G_DEFINE_TYPE (GstEncodeBin2, gst_encode_bin2, GST_TYPE_ENCODE_BASE_BIN); + +static void +gst_encode_bin2_class_init (GstEncodeBin2Class * klass) +{ + GstElementClass *gstelement_klass = (GstElementClass *) klass; + + gst_element_class_add_static_pad_template (gstelement_klass, + &muxer_src_template); +} + +static void +gst_encode_bin2_init (GstEncodeBin2 * encode_bin) +{ +} diff --git a/gst/encoding/gstencodebin2.h b/gst/encoding/gstencodebin2.h new file mode 100644 index 0000000000..774ca8965d --- /dev/null +++ b/gst/encoding/gstencodebin2.h @@ -0,0 +1,25 @@ +/* GStreamer splitmux encoding bin + * Copyright (C) 2009 Edward Hervey + * (C) 2009 Nokia Corporation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#pragma once + +#include "gstencodebasebin.h" + +G_DECLARE_FINAL_TYPE (GstEncodeBin2, gst_encode_bin2, GST, ENCODE_BIN2, GstEncodeBaseBin); \ No newline at end of file diff --git a/gst/encoding/meson.build b/gst/encoding/meson.build index fc21669d52..09ea83c388 100644 --- a/gst/encoding/meson.build +++ b/gst/encoding/meson.build @@ -1,6 +1,7 @@ encoding_sources = [ 'gstencodebasebin.c', 'gstencodebin.c', + 'gstencodebin2.c', 'gstsmartencoder.c', 'gststreamcombiner.c', 'gststreamsplitter.c', diff --git a/gst/encoding/plugin.c b/gst/encoding/plugin.c index 56d1b988f7..ee2e0bf266 100644 --- a/gst/encoding/plugin.c +++ b/gst/encoding/plugin.c @@ -27,6 +27,7 @@ #include #include "gstencodebin.h" +#include "gstencodebin2.h" static gboolean plugin_init (GstPlugin * plugin) @@ -43,6 +44,9 @@ plugin_init (GstPlugin * plugin) res = gst_element_register (plugin, "encodebin", GST_RANK_NONE, gst_encode_bin_get_type ()); + res |= gst_element_register (plugin, "encodebin2", GST_RANK_NONE, + gst_encode_bin2_get_type ()); + return res; }