Modified: trunk/Source/WebCore/platform/mediastream/libwebrtc/GStreamerVideoEncoder.cpp (270186 => 270187)
--- trunk/Source/WebCore/platform/mediastream/libwebrtc/GStreamerVideoEncoder.cpp 2020-11-27 10:02:08 UTC (rev 270186)
+++ trunk/Source/WebCore/platform/mediastream/libwebrtc/GStreamerVideoEncoder.cpp 2020-11-27 10:21:44 UTC (rev 270187)
@@ -1,6 +1,6 @@
/*
- * Copyright (C) 2018 Metrological Group B.V.
- * Copyright (C) 2018 Igalia S.L. All rights reserved.
+ * Copyright (C) 2018-2020 Metrological Group B.V.
+ * Copyright (C) 2018-2020 Igalia S.L. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -22,344 +22,281 @@
* that element in the future */
#include "config.h"
+#include "GStreamerVideoEncoder.h"
#if ENABLE(VIDEO) && ENABLE(MEDIA_STREAM) && USE(LIBWEBRTC) && USE(GSTREAMER)
-#include "GStreamerVideoEncoder.h"
+#include "GRefPtrGStreamer.h"
+#include <wtf/StdMap.h>
-GST_DEBUG_CATEGORY (gst_webrtcenc_debug);
-#define GST_CAT_DEFAULT gst_webrtcenc_debug
+GST_DEBUG_CATEGORY (webrtc_venc_debug);
+#define GST_CAT_DEFAULT webrtc_venc_debug
#define KBIT_TO_BIT 1024
-static GstStaticPadTemplate sinkTemplate = GST_STATIC_PAD_TEMPLATE ("sink",
- GST_PAD_SINK,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("video/x-raw(ANY);"));
+static GstStaticPadTemplate sinkTemplate =
+ GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, GST_STATIC_CAPS ("video/x-raw(ANY);"));
+static GstStaticPadTemplate srcTemplate =
+ GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS, GST_STATIC_CAPS ("video/x-h264;video/x-vp8"));
-static GstStaticPadTemplate srcTemplate = GST_STATIC_PAD_TEMPLATE ("src",
- GST_PAD_SRC,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("video/x-h264;video/x-vp8"));
+typedef void (*SetBitrateFunc) (GObject * encoder, const gchar * propname, gint bitrate);
+typedef void (*SetupFunc) (WebrtcVideoEncoder * self);
-typedef void (*SetBitrateFunc) (GObject * encoder, const gchar * propname,
- gint bitrate);
-typedef void (*SetupFunc) (GstWebrtcVideoEncoder * self);
-typedef struct
-{
- gboolean avalaible;
- GstCaps *caps;
- const gchar *name;
- const gchar *parser_name;
- GstCaps *encoded_format;
- SetBitrateFunc setBitrate;
- SetupFunc setupEncoder;
- const gchar *bitrate_propname;
- const gchar *keyframe_interval_propname;
-} EncoderDefinition;
+struct EncoderDefinition {
+ GRefPtr<GstCaps> caps;
+ const gchar* name;
+ const gchar* parserName;
+ GRefPtr<GstCaps> encodedFormat;
+ SetBitrateFunc setBitrate;
+ SetupFunc setupEncoder;
+ const gchar* bitratePropertyName;
+ const gchar* keyframeIntervalPropertyName;
+};
-typedef enum
-{
- ENCODER_NONE = 0,
- ENCODER_X264,
- ENCODER_OPENH264,
- ENCODER_OMXH264,
- ENCODER_VP8,
- ENCODER_LAST,
-} EncoderId;
+enum EncoderId { None, X264, OpenH264, OmxH264, Vp8 };
-EncoderDefinition encoders[ENCODER_LAST] = { { } };
+class Encoders {
+public:
+ static StdMap<EncoderId, EncoderDefinition>& singleton()
+ {
+ static StdMap<EncoderId, EncoderDefinition> encoders;
+ return encoders;
+ }
-typedef struct
-{
- EncoderId encoderId;
- GstElement *encoder;
- GstElement *parser;
- GstElement *capsfilter;
- guint bitrate;
-} GstWebrtcVideoEncoderPrivate;
+ static void registerEncoder(EncoderId id, const gchar* name, const gchar* parser_name, const gchar* caps, const gchar* encoded_format,
+ SetupFunc setupEncoder, const gchar* bitrate_propname, SetBitrateFunc setBitrate, const gchar* keyframe_interval_propname)
+ {
+ GstPluginFeature *feature = gst_registry_lookup_feature(gst_registry_get(), name);
+ if (!feature)
+ return;
+ gst_object_unref(feature);
-/* *INDENT-OFF* */
-G_DEFINE_TYPE_WITH_PRIVATE (GstWebrtcVideoEncoder, gst_webrtc_video_encoder,
- GST_TYPE_BIN)
-#define PRIV(self) ((GstWebrtcVideoEncoderPrivate*)gst_webrtc_video_encoder_get_instance_private(self))
-/* *INDENT-ON* */
+ singleton().emplace(std::make_pair(id, (EncoderDefinition) {
+ .caps = adoptGRef(gst_caps_from_string(caps)),
+ .name = name,
+ .parserName = parser_name,
+ .encodedFormat = (encoded_format) ? adoptGRef(gst_caps_from_string(encoded_format)) : nullptr,
+ .setBitrate = setBitrate,
+ .setupEncoder = setupEncoder,
+ .bitratePropertyName = bitrate_propname,
+ .keyframeIntervalPropertyName = keyframe_interval_propname,
+ }));
+ }
-enum
-{
- PROP_0,
- PROP_FORMAT,
- PROP_ENCODER,
- PROP_BITRATE,
- PROP_KEYFRAME_INTERVAL,
- N_PROPS
+ static const EncoderDefinition& definition(EncoderId id) {
+ ASSERT(id != None);
+ return singleton()[id];
+ }
};
-static void
-gst_webrtc_video_encoder_finalize (GObject * object)
-{
- G_OBJECT_CLASS (gst_webrtc_video_encoder_parent_class)->finalize (object);
-}
+struct _WebrtcVideoEncoder {
+ GstBin parent;
-static void
-gst_webrtc_video_encoder_get_property (GObject * object,
- guint prop_id, GValue * value, GParamSpec * pspec)
+ EncoderId encoderId;
+ GstElement* encoder;
+ GstElement* parser;
+ guint bitrate;
+};
+
+G_DEFINE_TYPE(WebrtcVideoEncoder, webrtc_video_encoder, GST_TYPE_BIN);
+
+enum {
+ PROP_FORMAT = 1,
+ PROP_ENCODER,
+ PROP_BITRATE,
+ PROP_KEYFRAME_INTERVAL,
+ N_PROPS
+};
+
+static void webrtcVideoEncoderGetProperty(GObject* object, guint prop_id, GValue* value, GParamSpec* pspec)
{
- GstWebrtcVideoEncoder *self = GST_WEBRTC_VIDEO_ENCODER (object);
- GstWebrtcVideoEncoderPrivate *priv = PRIV (self);
+ WebrtcVideoEncoder* self = WEBRTC_VIDEO_ENCODER(object);
- switch (prop_id) {
+ switch (prop_id) {
case PROP_FORMAT:
- if (priv->encoderId != ENCODER_NONE)
- g_value_set_boxed (value, encoders[priv->encoderId].caps);
- else
- g_value_set_boxed (value, NULL);
- break;
+ if (self->encoderId != None) {
+ auto &encoder = Encoders::definition(self->encoderId);
+ g_value_set_boxed(value, encoder.caps.get());
+ } else
+ g_value_set_boxed(value, nullptr);
+ break;
case PROP_ENCODER:
- g_value_set_object (value, priv->encoder);
- break;
+ g_value_set_object(value, self->encoder);
+ break;
case PROP_BITRATE:
- g_value_set_uint (value, priv->bitrate);
- break;
+ g_value_set_uint(value, self->bitrate);
+ break;
case PROP_KEYFRAME_INTERVAL:
- if (priv->encoder)
- g_object_get_property (G_OBJECT (priv->encoder),
- encoders[priv->encoderId].keyframe_interval_propname, value);
- break;
+ if (self->encoder) {
+ auto &encoder = Encoders::definition(self->encoderId);
+ g_object_get_property(G_OBJECT(self->encoder), encoder.keyframeIntervalPropertyName, value);
+ }
+ break;
default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
}
}
-static void
-gst_webrtc_video_encoder_set_bitrate (GstWebrtcVideoEncoder * self,
- guint bitrate)
+static void webrtcVideoEncoderSetBitrate(WebrtcVideoEncoder* self, guint bitrate)
{
- GstWebrtcVideoEncoderPrivate *priv = PRIV (self);
-
- priv->bitrate = bitrate;
- if (priv->encoder) {
- encoders[priv->encoderId].setBitrate (G_OBJECT (priv->encoder),
- encoders[priv->encoderId].bitrate_propname, priv->bitrate);
- }
+ self->bitrate = bitrate;
+ if (self->encoder) {
+ auto &encoder = Encoders::definition(self->encoderId);
+ encoder.setBitrate(G_OBJECT(self->encoder), encoder.bitratePropertyName, self->bitrate);
+ }
}
-static void
-gst_webrtc_video_encoder_set_format (GstWebrtcVideoEncoder * self,
- const GstCaps * caps)
+static void webrtcVideoEncoderSetFormat(WebrtcVideoEncoder* self, const GstCaps* caps)
{
- gint i;
- GstWebrtcVideoEncoderPrivate *priv = PRIV (self);
- g_return_if_fail (priv->encoderId == ENCODER_NONE);
- g_return_if_fail (caps);
+ g_return_if_fail(self->encoderId == None);
+ g_return_if_fail(caps);
- for (i = 1; i < ENCODER_LAST; i++) {
- if (encoders[i].avalaible
- && gst_caps_can_intersect (encoders[i].caps, caps)) {
- GstPad *tmppad;
- priv->encoderId = (EncoderId) i;
- priv->encoder = gst_element_factory_make (encoders[i].name, NULL);
+ for (const auto &pair : Encoders::singleton()) {
+ const auto &encoder = pair.second;
+ GstElement* capsfilter = nullptr;
- if (encoders[i].parser_name)
- priv->parser = gst_element_factory_make (encoders[i].parser_name, NULL);
+ if (gst_caps_can_intersect(encoder.caps.get(), caps)) {
+ GRefPtr<GstPad> tmppad;
+ self->encoderId = pair.first;
+ self->encoder = gst_element_factory_make(encoder.name, nullptr);
- encoders[priv->encoderId].setupEncoder (self);
- if (encoders[i].encoded_format) {
- priv->capsfilter = gst_element_factory_make ("capsfilter", NULL);
- g_object_set (priv->capsfilter, "caps", encoders[i].encoded_format,
- NULL);
- }
+ if (encoder.parserName)
+ self->parser = gst_element_factory_make(encoder.parserName, nullptr);
- gst_bin_add (GST_BIN (self), priv->encoder);
+ encoder.setupEncoder(self);
+ if (encoder.encodedFormat.get()) {
+ capsfilter = gst_element_factory_make("capsfilter", nullptr);
+ g_object_set(capsfilter, "caps", encoder.encodedFormat.get(), nullptr);
+ }
- tmppad = gst_element_get_static_pad (priv->encoder, "sink");
- gst_ghost_pad_set_target (GST_GHOST_PAD (GST_ELEMENT (self)->
- sinkpads->data), tmppad);
- gst_object_unref (tmppad);
+ gst_bin_add(GST_BIN(self), self->encoder);
- tmppad = gst_element_get_static_pad (priv->encoder, "src");
- if (priv->parser) {
- gst_bin_add (GST_BIN (self), priv->parser);
- gst_element_link (priv->encoder, priv->parser);
- gst_object_unref (tmppad);
- tmppad = gst_element_get_static_pad (priv->parser, "src");
- }
+ tmppad = adoptGRef(gst_element_get_static_pad(self->encoder, "sink"));
+ GRefPtr<GstPad> sinkpad = adoptGRef(gst_element_get_static_pad(GST_ELEMENT(self), "sink"));
+ gst_ghost_pad_set_target(GST_GHOST_PAD(sinkpad.get()), tmppad.get());
- if (priv->capsfilter) {
- GstPad *tmppad2 = gst_element_get_static_pad (priv->capsfilter, "sink");
+ tmppad = adoptGRef(gst_element_get_static_pad(self->encoder, "src"));
+ if (self->parser) {
+ gst_bin_add(GST_BIN(self), self->parser);
+ gst_element_link(self->encoder, self->parser);
+ tmppad = adoptGRef(gst_element_get_static_pad(self->parser, "src"));
+ }
- gst_bin_add (GST_BIN (self), priv->capsfilter);
- gst_pad_link (tmppad, tmppad2);
- gst_object_unref (tmppad);
- tmppad = gst_element_get_static_pad (priv->capsfilter, "src");
- gst_object_unref (tmppad2);
- }
+ if (capsfilter) {
+ GRefPtr<GstPad> tmppad2 = adoptGRef(gst_element_get_static_pad(capsfilter, "sink"));
- g_assert (gst_ghost_pad_set_target (GST_GHOST_PAD (GST_ELEMENT
- (self)->srcpads->data), tmppad));
- gst_object_unref (tmppad);
+ gst_bin_add(GST_BIN(self), capsfilter);
+ gst_pad_link(tmppad.get(), tmppad2.get());
+ tmppad = adoptGRef(gst_element_get_static_pad(capsfilter, "src"));
+ }
- gst_webrtc_video_encoder_set_bitrate (self, priv->bitrate);
- return;
+ GRefPtr<GstPad> srcpad = adoptGRef(gst_element_get_static_pad(GST_ELEMENT (self), "src"));
+ gboolean ret = gst_ghost_pad_set_target(GST_GHOST_PAD(srcpad.get()), tmppad.get());
+
+ RELEASE_ASSERT(ret);
+
+ webrtcVideoEncoderSetBitrate(self, self->bitrate);
+ return;
+ }
}
- }
- GST_ERROR ("No encoder found for format %" GST_PTR_FORMAT, caps);
+ GST_ERROR("No encoder found for format %" GST_PTR_FORMAT, caps);
}
-static void
-gst_webrtc_video_encoder_set_property (GObject * object,
- guint prop_id, const GValue * value, GParamSpec * pspec)
+static void webrtcVideoEncoderSetProperty(GObject* object, guint prop_id, const GValue* value, GParamSpec* pspec)
{
- GstWebrtcVideoEncoder *self = GST_WEBRTC_VIDEO_ENCODER (object);
- GstWebrtcVideoEncoderPrivate *priv = PRIV (self);
+ WebrtcVideoEncoder* self = WEBRTC_VIDEO_ENCODER(object);
- switch (prop_id) {
+ switch (prop_id) {
case PROP_FORMAT:
- gst_webrtc_video_encoder_set_format (self, gst_value_get_caps (value));
- break;
+ webrtcVideoEncoderSetFormat(self, gst_value_get_caps(value));
+ break;
case PROP_BITRATE:
- gst_webrtc_video_encoder_set_bitrate (self, g_value_get_uint (value));
- break;
+ webrtcVideoEncoderSetBitrate(self, g_value_get_uint(value));
+ break;
case PROP_KEYFRAME_INTERVAL:
- if (priv->encoder)
- g_object_set (priv->encoder,
- encoders[priv->encoderId].keyframe_interval_propname,
- g_value_get_uint (value), NULL);
-
- break;
+ if (self->encoder) {
+ auto &encoder = Encoders::definition(self->encoderId);
+ g_object_set(self->encoder, encoder.keyframeIntervalPropertyName, g_value_get_uint(value), nullptr);
+ }
+ break;
default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- }
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
}
-static void
-register_known_encoder (EncoderId encId, const gchar * name,
- const gchar * parser_name, const gchar * caps, const gchar * encoded_format,
- SetupFunc setupEncoder, const gchar * bitrate_propname,
- SetBitrateFunc setBitrate, const gchar * keyframe_interval_propname)
+static void setupX264enc(WebrtcVideoEncoder* self)
{
- GstPluginFeature *feature =
- gst_registry_lookup_feature (gst_registry_get (), name);
- if (!feature) {
- GST_WARNING ("Could not find %s", name);
- encoders[encId].avalaible = FALSE;
-
- return;
- }
- gst_object_unref (feature);
-
- encoders[encId].avalaible = TRUE;
- encoders[encId].name = name;
- encoders[encId].parser_name = parser_name;
- encoders[encId].caps = gst_caps_from_string (caps);
- if (encoded_format)
- encoders[encId].encoded_format = gst_caps_from_string (encoded_format);
- else
- encoders[encId].encoded_format = NULL;
- encoders[encId].setupEncoder = setupEncoder;
- encoders[encId].bitrate_propname = bitrate_propname;
- encoders[encId].setBitrate = setBitrate;
- encoders[encId].keyframe_interval_propname = keyframe_interval_propname;
+ gst_util_set_object_arg(G_OBJECT (self->encoder), "tune", "zerolatency");
+ g_object_set(self->parser, "config-interval", 1, nullptr);
}
-static void
-setup_x264enc (GstWebrtcVideoEncoder * self)
+static void setupOpenh264enc(WebrtcVideoEncoder* self)
{
- gst_util_set_object_arg (G_OBJECT (PRIV (self)->encoder), "tune",
- "zerolatency");
- g_object_set (PRIV (self)->parser, "config-interval", 1, NULL);
+ g_object_set (self->parser, "config-interval", 1, nullptr);
}
-static void
-setup_openh264enc (GstWebrtcVideoEncoder * self)
+static void setupOmxh264enc(WebrtcVideoEncoder* self)
{
- g_object_set (PRIV (self)->parser, "config-interval", 1, NULL);
+ gst_util_set_object_arg(G_OBJECT(self->encoder), "control-rate", "variable");
+ g_object_set(self->parser, "config-interval", 1, nullptr);
}
-static void
-setup_omxh264enc (GstWebrtcVideoEncoder * self)
+static void setBitrateKbitPerSec(GObject* encoder, const gchar* prop_name, gint bitrate)
{
- gst_util_set_object_arg (G_OBJECT (PRIV (self)->encoder), "control-rate",
- "variable");
- g_object_set (PRIV (self)->parser, "config-interval", 1, NULL);
+ g_object_set(encoder, prop_name, bitrate, nullptr);
}
-
-static void
-set_bitrate_kbit_per_sec (GObject * encoder, const gchar * prop_name,
- gint bitrate)
+static void setBitrateBitPerSec(GObject* encoder, const gchar* prop_name, gint bitrate)
{
- g_object_set (encoder, prop_name, bitrate, NULL);
+ g_object_set(encoder, prop_name, bitrate * KBIT_TO_BIT, nullptr);
}
-static void
-set_bitrate_bit_per_sec (GObject * encoder, const gchar * prop_name,
- gint bitrate)
+static void webrtc_video_encoder_class_init(WebrtcVideoEncoderClass* klass)
{
- g_object_set (encoder, prop_name, bitrate * KBIT_TO_BIT, NULL);
-}
+ GObjectClass* object_class = G_OBJECT_CLASS (klass);
-static void
-gst_webrtc_video_encoder_class_init (GstWebrtcVideoEncoderClass * klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GST_DEBUG_CATEGORY_INIT (webrtc_venc_debug, "webrtcencoder", 0, "Video encoder for WebRTC");
- GST_DEBUG_CATEGORY_INIT (gst_webrtcenc_debug, "webrtcencoder", 0,
- "Video encoder for WebRTC");
+ object_class->get_property = webrtcVideoEncoderGetProperty;
+ object_class->set_property = webrtcVideoEncoderSetProperty;
- object_class->finalize = gst_webrtc_video_encoder_finalize;
- object_class->get_property = gst_webrtc_video_encoder_get_property;
- object_class->set_property = gst_webrtc_video_encoder_set_property;
+ g_object_class_install_property(object_class, PROP_FORMAT,
+ g_param_spec_boxed("format", "Format as caps", "Set the caps of the format to be used.", GST_TYPE_CAPS,
+ static_cast<GParamFlags>(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
- g_object_class_install_property (object_class, PROP_FORMAT,
- g_param_spec_boxed ("format", "Format as caps",
- "Set the caps of the format to be used.",
- GST_TYPE_CAPS,
- (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
+ g_object_class_install_property(object_class, PROP_ENCODER,
+ g_param_spec_object("encoder", "The actual encoder element", "The encoder element", GST_TYPE_ELEMENT,
+ static_cast<GParamFlags>(G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)));
- g_object_class_install_property (object_class, PROP_ENCODER,
- g_param_spec_object ("encoder", "The actual encoder element",
- "The encoder element", GST_TYPE_ELEMENT,
- (GParamFlags) (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)));
+ g_object_class_install_property(object_class, PROP_BITRATE,
+ g_param_spec_uint("bitrate", "Bitrate", "The bitrate in kbit per second", 0, G_MAXINT, 2048,
+ static_cast<GParamFlags>(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT)));
- g_object_class_install_property (object_class, PROP_BITRATE,
- g_param_spec_uint ("bitrate", "Bitrate",
- "The bitrate in kbit per second", 0, G_MAXINT, 2048,
- (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
- G_PARAM_CONSTRUCT)));
+ g_object_class_install_property(object_class, PROP_KEYFRAME_INTERVAL,
+ g_param_spec_uint("keyframe-interval", "Keyframe interval", "The interval between keyframes", 0, G_MAXINT, 0,
+ static_cast<GParamFlags>(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT)));
- g_object_class_install_property (object_class, PROP_KEYFRAME_INTERVAL,
- g_param_spec_uint ("keyframe-interval", "Keyframe interval",
- "The interval between keyframes", 0, G_MAXINT, 0,
- (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
- G_PARAM_CONSTRUCT)));
-
- register_known_encoder (ENCODER_OMXH264, "omxh264enc", "h264parse",
- "video/x-h264",
- "video/x-h264,alignment=au,stream-format=byte-stream,profile=""
- setup_omxh264enc, "target-bitrate", set_bitrate_bit_per_sec, "interval-intraframes");
- register_known_encoder (ENCODER_X264, "x264enc", "h264parse", "video/x-h264",
- "video/x-h264,alignment=au,stream-format=byte-stream,profile=""
- setup_x264enc, "bitrate", set_bitrate_kbit_per_sec, "key-int-max");
- register_known_encoder (ENCODER_OPENH264, "openh264enc", "h264parse",
- "video/x-h264",
- "video/x-h264,alignment=au,stream-format=byte-stream,profile=""
- setup_openh264enc, "bitrate", set_bitrate_bit_per_sec, "gop-size");
+ Encoders::registerEncoder(OmxH264, "omxh264enc", "h264parse", "video/x-h264",
+ "video/x-h264,alignment=au,stream-format=byte-stream,profile=""
+ setupOmxh264enc, "target-bitrate", setBitrateBitPerSec, "interval-intraframes");
+ Encoders::registerEncoder(X264, "x264enc", "h264parse", "video/x-h264",
+ "video/x-h264,alignment=au,stream-format=byte-stream,profile=""
+ setupX264enc, "bitrate", setBitrateKbitPerSec, "key-int-max");
+ Encoders::registerEncoder(OpenH264, "openh264enc", "h264parse", "video/x-h264",
+ "video/x-h264,alignment=au,stream-format=byte-stream,profile=""
+ setupOpenh264enc, "bitrate", setBitrateBitPerSec, "gop-size");
}
-static void
-gst_webrtc_video_encoder_init (GstWebrtcVideoEncoder * self)
+static void webrtc_video_encoder_init (WebrtcVideoEncoder* self)
{
- GstWebrtcVideoEncoderPrivate *priv = PRIV (self);
+ self->encoderId = None;
+ gst_element_add_pad(GST_ELEMENT(self),
+ gst_ghost_pad_new_no_target_from_template("sink", gst_static_pad_template_get(&sinkTemplate)));
- priv->encoderId = ENCODER_NONE;
- gst_element_add_pad (GST_ELEMENT (self),
- gst_ghost_pad_new_no_target_from_template ("sink",
- gst_static_pad_template_get (&sinkTemplate)));
-
- gst_element_add_pad (GST_ELEMENT (self),
- gst_ghost_pad_new_no_target_from_template ("src",
- gst_static_pad_template_get (&srcTemplate)));
+ gst_element_add_pad(GST_ELEMENT(self),
+ gst_ghost_pad_new_no_target_from_template("src", gst_static_pad_template_get(&srcTemplate)));
}
#endif // ENABLE(VIDEO) && ENABLE(MEDIA_STREAM) && USE(LIBWEBRTC) && USE(GSTREAMER)