<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[270187] trunk/Source/WebCore</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/270187">270187</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2020-11-27 02:21:44 -0800 (Fri, 27 Nov 2020)</dd>
</dl>

<h3>Log Message</h3>
<pre>[GStreamer] refactor video encoder with WebKit style
https://bugs.webkit.org/show_bug.cgi?id=218748

Patch by Víctor Manuel Jáquez Leal <vjaquez@igalia.com> on 2020-11-27
Reviewed by Philippe Normand.

Apply WebKit code style to GStreamerVideoEncoder

No new tests required since it's a refactor.

* platform/mediastream/libwebrtc/GStreamerVideoEncoder.cpp:
(Encoders::singleton): Instead of an array with the available encoders, a singleton map is
used, with better memory handling.
(Encoders::registerEncoder): static method to register a possible encoder to handle
(Encoders::definition): getter
(webrtcVideoEncoderGetProperty): renamed
(webrtcVideoEncoderSetBitrate): renamed
(webrtcVideoEncoderSetFormat): Use getter for static pads; GRefPtr for memory handling;
don't call gst_ghost_pad_set_target() inside a g_assert since it can be disabled.
(webrtcVideoEncoderSetProperty): renamed
(setupX264enc): renamed
(setupOpenh264enc): renamed
(setupOmxh264enc): renamed
(setBitrateKbitPerSec): renamed
(setBitrateBitPerSec): renamed
(webrtc_video_encoder_class_init): renamed
(webrtc_video_encoder_init): renamed
* platform/mediastream/libwebrtc/GStreamerVideoEncoder.h: use G_DECLARE_FINAL_TYPE macro and
change the name of the glib type to WEBRTC_TYPE_VIDEO_ENCODER
* platform/mediastream/libwebrtc/GStreamerVideoEncoderFactory.cpp: remove unused macro
(WebCore::GStreamerVideoEncoderFactory::GStreamerVideoEncoderFactory): Don't register the
element as primary, but none.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreamlibwebrtcGStreamerVideoEncodercpp">trunk/Source/WebCore/platform/mediastream/libwebrtc/GStreamerVideoEncoder.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreamlibwebrtcGStreamerVideoEncoderh">trunk/Source/WebCore/platform/mediastream/libwebrtc/GStreamerVideoEncoder.h</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreamlibwebrtcGStreamerVideoEncoderFactorycpp">trunk/Source/WebCore/platform/mediastream/libwebrtc/GStreamerVideoEncoderFactory.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (270186 => 270187)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog   2020-11-27 10:02:08 UTC (rev 270186)
+++ trunk/Source/WebCore/ChangeLog      2020-11-27 10:21:44 UTC (rev 270187)
</span><span class="lines">@@ -1,3 +1,37 @@
</span><ins>+2020-11-27  Víctor Manuel Jáquez Leal  <vjaquez@igalia.com>
+
+        [GStreamer] refactor video encoder with WebKit style
+        https://bugs.webkit.org/show_bug.cgi?id=218748
+
+        Reviewed by Philippe Normand.
+
+        Apply WebKit code style to GStreamerVideoEncoder
+
+        No new tests required since it's a refactor.
+
+        * platform/mediastream/libwebrtc/GStreamerVideoEncoder.cpp:
+        (Encoders::singleton): Instead of an array with the available encoders, a singleton map is
+        used, with better memory handling.
+        (Encoders::registerEncoder): static method to register a possible encoder to handle
+        (Encoders::definition): getter
+        (webrtcVideoEncoderGetProperty): renamed
+        (webrtcVideoEncoderSetBitrate): renamed
+        (webrtcVideoEncoderSetFormat): Use getter for static pads; GRefPtr for memory handling;
+        don't call gst_ghost_pad_set_target() inside a g_assert since it can be disabled.
+        (webrtcVideoEncoderSetProperty): renamed
+        (setupX264enc): renamed
+        (setupOpenh264enc): renamed
+        (setupOmxh264enc): renamed
+        (setBitrateKbitPerSec): renamed
+        (setBitrateBitPerSec): renamed
+        (webrtc_video_encoder_class_init): renamed
+        (webrtc_video_encoder_init): renamed
+        * platform/mediastream/libwebrtc/GStreamerVideoEncoder.h: use G_DECLARE_FINAL_TYPE macro and
+        change the name of the glib type to WEBRTC_TYPE_VIDEO_ENCODER
+        * platform/mediastream/libwebrtc/GStreamerVideoEncoderFactory.cpp: remove unused macro
+        (WebCore::GStreamerVideoEncoderFactory::GStreamerVideoEncoderFactory): Don't register the
+        element as primary, but none.
+
</ins><span class="cx"> 2020-11-27  Kimmo Kinnunen  <kkinnunen@apple.com>
</span><span class="cx"> 
</span><span class="cx">         GraphicsContextGL should have robust multivalue setters
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreamlibwebrtcGStreamerVideoEncodercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/libwebrtc/GStreamerVideoEncoder.cpp (270186 => 270187)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -1,6 +1,6 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2018 Metrological Group B.V.
- * Copyright (C) 2018 Igalia S.L. All rights reserved.
</del><ins>+ * Copyright (C) 2018-2020 Metrological Group B.V.
+ * Copyright (C) 2018-2020 Igalia S.L. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * This library is free software; you can redistribute it and/or
</span><span class="cx">  * modify it under the terms of the GNU Library General Public
</span><span class="lines">@@ -22,344 +22,281 @@
</span><span class="cx">  * that element in the future */
</span><span class="cx"> 
</span><span class="cx"> #include "config.h"
</span><ins>+#include "GStreamerVideoEncoder.h"
</ins><span class="cx"> 
</span><span class="cx"> #if ENABLE(VIDEO) && ENABLE(MEDIA_STREAM) && USE(LIBWEBRTC) && USE(GSTREAMER)
</span><del>-#include "GStreamerVideoEncoder.h"
</del><ins>+#include "GRefPtrGStreamer.h"
+#include <wtf/StdMap.h>
</ins><span class="cx"> 
</span><del>-GST_DEBUG_CATEGORY (gst_webrtcenc_debug);
-#define GST_CAT_DEFAULT gst_webrtcenc_debug
</del><ins>+GST_DEBUG_CATEGORY (webrtc_venc_debug);
+#define GST_CAT_DEFAULT webrtc_venc_debug
</ins><span class="cx"> 
</span><span class="cx"> #define KBIT_TO_BIT 1024
</span><span class="cx"> 
</span><del>-static GstStaticPadTemplate sinkTemplate = GST_STATIC_PAD_TEMPLATE ("sink",
-    GST_PAD_SINK,
-    GST_PAD_ALWAYS,
-    GST_STATIC_CAPS ("video/x-raw(ANY);"));
</del><ins>+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"));
</ins><span class="cx"> 
</span><del>-static GstStaticPadTemplate srcTemplate = GST_STATIC_PAD_TEMPLATE ("src",
-    GST_PAD_SRC,
-    GST_PAD_ALWAYS,
-    GST_STATIC_CAPS ("video/x-h264;video/x-vp8"));
</del><ins>+typedef void (*SetBitrateFunc) (GObject * encoder, const gchar * propname,  gint bitrate);
+typedef void (*SetupFunc) (WebrtcVideoEncoder * self);
</ins><span class="cx"> 
</span><del>-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;
</del><ins>+struct EncoderDefinition {
+    GRefPtr<GstCaps> caps;
+    const gchar* name;
+    const gchar* parserName;
+    GRefPtr<GstCaps> encodedFormat;
+    SetBitrateFunc setBitrate;
+    SetupFunc setupEncoder;
+    const gchar* bitratePropertyName;
+    const gchar* keyframeIntervalPropertyName;
+};
</ins><span class="cx"> 
</span><del>-typedef enum
-{
-  ENCODER_NONE = 0,
-  ENCODER_X264,
-  ENCODER_OPENH264,
-  ENCODER_OMXH264,
-  ENCODER_VP8,
-  ENCODER_LAST,
-} EncoderId;
</del><ins>+enum EncoderId { None, X264, OpenH264, OmxH264, Vp8 };
</ins><span class="cx"> 
</span><del>-EncoderDefinition encoders[ENCODER_LAST] = { { } };
</del><ins>+class Encoders {
+public:
+    static StdMap<EncoderId, EncoderDefinition>& singleton()
+    {
+        static StdMap<EncoderId, EncoderDefinition> encoders;
+        return encoders;
+    }
</ins><span class="cx"> 
</span><del>-typedef struct
-{
-  EncoderId encoderId;
-  GstElement *encoder;
-  GstElement *parser;
-  GstElement *capsfilter;
-  guint bitrate;
-} GstWebrtcVideoEncoderPrivate;
</del><ins>+    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);
</ins><span class="cx"> 
</span><del>-/*  *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* */
</del><ins>+        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,
+        }));
+    }
</ins><span class="cx"> 
</span><del>-enum
-{
-  PROP_0,
-  PROP_FORMAT,
-  PROP_ENCODER,
-  PROP_BITRATE,
-  PROP_KEYFRAME_INTERVAL,
-  N_PROPS
</del><ins>+    static const EncoderDefinition& definition(EncoderId id) {
+        ASSERT(id != None);
+        return singleton()[id];
+    }
</ins><span class="cx"> };
</span><span class="cx"> 
</span><del>-static void
-gst_webrtc_video_encoder_finalize (GObject * object)
-{
-  G_OBJECT_CLASS (gst_webrtc_video_encoder_parent_class)->finalize (object);
-}
</del><ins>+struct _WebrtcVideoEncoder {
+    GstBin parent;
</ins><span class="cx"> 
</span><del>-static void
-gst_webrtc_video_encoder_get_property (GObject * object,
-    guint prop_id, GValue * value, GParamSpec * pspec)
</del><ins>+    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)
</ins><span class="cx"> {
</span><del>-  GstWebrtcVideoEncoder *self = GST_WEBRTC_VIDEO_ENCODER (object);
-  GstWebrtcVideoEncoderPrivate *priv = PRIV (self);
</del><ins>+    WebrtcVideoEncoder* self = WEBRTC_VIDEO_ENCODER(object);
</ins><span class="cx"> 
</span><del>-  switch (prop_id) {
</del><ins>+    switch (prop_id) {
</ins><span class="cx">     case PROP_FORMAT:
</span><del>-      if (priv->encoderId != ENCODER_NONE)
-        g_value_set_boxed (value, encoders[priv->encoderId].caps);
-      else
-        g_value_set_boxed (value, NULL);
-      break;
</del><ins>+        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;
</ins><span class="cx">     case PROP_ENCODER:
</span><del>-      g_value_set_object (value, priv->encoder);
-      break;
</del><ins>+        g_value_set_object(value, self->encoder);
+        break;
</ins><span class="cx">     case PROP_BITRATE:
</span><del>-      g_value_set_uint (value, priv->bitrate);
-      break;
</del><ins>+        g_value_set_uint(value, self->bitrate);
+        break;
</ins><span class="cx">     case PROP_KEYFRAME_INTERVAL:
</span><del>-      if (priv->encoder)
-        g_object_get_property (G_OBJECT (priv->encoder),
-            encoders[priv->encoderId].keyframe_interval_propname, value);
-      break;
</del><ins>+        if (self->encoder) {
+            auto &encoder = Encoders::definition(self->encoderId);
+            g_object_get_property(G_OBJECT(self->encoder), encoder.keyframeIntervalPropertyName, value);
+        }
+        break;
</ins><span class="cx">     default:
</span><del>-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
</del><ins>+        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+        break;
</ins><span class="cx">   }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void
-gst_webrtc_video_encoder_set_bitrate (GstWebrtcVideoEncoder * self,
-    guint bitrate)
</del><ins>+static void webrtcVideoEncoderSetBitrate(WebrtcVideoEncoder* self, guint bitrate)
</ins><span class="cx"> {
</span><del>-  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);
-  }
</del><ins>+    self->bitrate = bitrate;
+    if (self->encoder) {
+        auto &encoder = Encoders::definition(self->encoderId);
+        encoder.setBitrate(G_OBJECT(self->encoder), encoder.bitratePropertyName, self->bitrate);
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void
-gst_webrtc_video_encoder_set_format (GstWebrtcVideoEncoder * self,
-    const GstCaps * caps)
</del><ins>+static void webrtcVideoEncoderSetFormat(WebrtcVideoEncoder* self, const GstCaps* caps)
</ins><span class="cx"> {
</span><del>-  gint i;
-  GstWebrtcVideoEncoderPrivate *priv = PRIV (self);
-  g_return_if_fail (priv->encoderId == ENCODER_NONE);
-  g_return_if_fail (caps);
</del><ins>+    g_return_if_fail(self->encoderId == None);
+    g_return_if_fail(caps);
</ins><span class="cx"> 
</span><del>-  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);
</del><ins>+    for (const auto &pair : Encoders::singleton()) {
+        const auto &encoder = pair.second;
+        GstElement* capsfilter = nullptr;
</ins><span class="cx"> 
</span><del>-      if (encoders[i].parser_name)
-        priv->parser = gst_element_factory_make (encoders[i].parser_name, NULL);
</del><ins>+        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);
</ins><span class="cx"> 
</span><del>-      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);
-      }
</del><ins>+            if (encoder.parserName)
+                self->parser = gst_element_factory_make(encoder.parserName, nullptr);
</ins><span class="cx"> 
</span><del>-      gst_bin_add (GST_BIN (self), priv->encoder);
</del><ins>+            encoder.setupEncoder(self);
+            if (encoder.encodedFormat.get()) {
+                capsfilter = gst_element_factory_make("capsfilter", nullptr);
+                g_object_set(capsfilter, "caps", encoder.encodedFormat.get(), nullptr);
+            }
</ins><span class="cx"> 
</span><del>-      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);
</del><ins>+            gst_bin_add(GST_BIN(self), self->encoder);
</ins><span class="cx"> 
</span><del>-      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");
-      }
</del><ins>+            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());
</ins><span class="cx"> 
</span><del>-      if (priv->capsfilter) {
-        GstPad *tmppad2 = gst_element_get_static_pad (priv->capsfilter, "sink");
</del><ins>+            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"));
+            }
</ins><span class="cx"> 
</span><del>-        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);
-      }
</del><ins>+            if (capsfilter) {
+                GRefPtr<GstPad> tmppad2 = adoptGRef(gst_element_get_static_pad(capsfilter, "sink"));
</ins><span class="cx"> 
</span><del>-      g_assert (gst_ghost_pad_set_target (GST_GHOST_PAD (GST_ELEMENT
-                  (self)->srcpads->data), tmppad));
-      gst_object_unref (tmppad);
</del><ins>+                gst_bin_add(GST_BIN(self), capsfilter);
+                gst_pad_link(tmppad.get(), tmppad2.get());
+                tmppad = adoptGRef(gst_element_get_static_pad(capsfilter, "src"));
+            }
</ins><span class="cx"> 
</span><del>-      gst_webrtc_video_encoder_set_bitrate (self, priv->bitrate);
-      return;
</del><ins>+            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;
+        }
</ins><span class="cx">     }
</span><del>-  }
</del><span class="cx"> 
</span><del>-  GST_ERROR ("No encoder found for format %" GST_PTR_FORMAT, caps);
</del><ins>+    GST_ERROR("No encoder found for format %" GST_PTR_FORMAT, caps);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void
-gst_webrtc_video_encoder_set_property (GObject * object,
-    guint prop_id, const GValue * value, GParamSpec * pspec)
</del><ins>+static void webrtcVideoEncoderSetProperty(GObject* object, guint prop_id, const GValue* value, GParamSpec* pspec)
</ins><span class="cx"> {
</span><del>-  GstWebrtcVideoEncoder *self = GST_WEBRTC_VIDEO_ENCODER (object);
-  GstWebrtcVideoEncoderPrivate *priv = PRIV (self);
</del><ins>+    WebrtcVideoEncoder* self = WEBRTC_VIDEO_ENCODER(object);
</ins><span class="cx"> 
</span><del>-  switch (prop_id) {
</del><ins>+    switch (prop_id) {
</ins><span class="cx">     case PROP_FORMAT:
</span><del>-      gst_webrtc_video_encoder_set_format (self, gst_value_get_caps (value));
-      break;
</del><ins>+        webrtcVideoEncoderSetFormat(self, gst_value_get_caps(value));
+        break;
</ins><span class="cx">     case PROP_BITRATE:
</span><del>-      gst_webrtc_video_encoder_set_bitrate (self, g_value_get_uint (value));
-      break;
</del><ins>+        webrtcVideoEncoderSetBitrate(self, g_value_get_uint(value));
+        break;
</ins><span class="cx">     case PROP_KEYFRAME_INTERVAL:
</span><del>-      if (priv->encoder)
-        g_object_set (priv->encoder,
-            encoders[priv->encoderId].keyframe_interval_propname,
-            g_value_get_uint (value), NULL);
-
-      break;
</del><ins>+        if (self->encoder) {
+            auto &encoder = Encoders::definition(self->encoderId);
+            g_object_set(self->encoder, encoder.keyframeIntervalPropertyName, g_value_get_uint(value), nullptr);
+        }
+        break;
</ins><span class="cx">     default:
</span><del>-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-  }
</del><ins>+        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+        break;
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-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)
</del><ins>+static void setupX264enc(WebrtcVideoEncoder* self)
</ins><span class="cx"> {
</span><del>-  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;
</del><ins>+    gst_util_set_object_arg(G_OBJECT (self->encoder), "tune", "zerolatency");
+    g_object_set(self->parser, "config-interval", 1, nullptr);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void
-setup_x264enc (GstWebrtcVideoEncoder * self)
</del><ins>+static void setupOpenh264enc(WebrtcVideoEncoder* self)
</ins><span class="cx"> {
</span><del>-  gst_util_set_object_arg (G_OBJECT (PRIV (self)->encoder), "tune",
-      "zerolatency");
-  g_object_set (PRIV (self)->parser, "config-interval", 1, NULL);
</del><ins>+    g_object_set (self->parser, "config-interval", 1, nullptr);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void
-setup_openh264enc (GstWebrtcVideoEncoder * self)
</del><ins>+static void setupOmxh264enc(WebrtcVideoEncoder* self)
</ins><span class="cx"> {
</span><del>-  g_object_set (PRIV (self)->parser, "config-interval", 1, NULL);
</del><ins>+  gst_util_set_object_arg(G_OBJECT(self->encoder), "control-rate", "variable");
+  g_object_set(self->parser, "config-interval", 1, nullptr);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void
-setup_omxh264enc (GstWebrtcVideoEncoder * self)
</del><ins>+static void setBitrateKbitPerSec(GObject* encoder, const gchar* prop_name, gint bitrate)
</ins><span class="cx"> {
</span><del>-  gst_util_set_object_arg (G_OBJECT (PRIV (self)->encoder), "control-rate",
-      "variable");
-  g_object_set (PRIV (self)->parser, "config-interval", 1, NULL);
</del><ins>+  g_object_set(encoder, prop_name, bitrate, nullptr);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-
-static void
-set_bitrate_kbit_per_sec (GObject * encoder, const gchar * prop_name,
-    gint bitrate)
</del><ins>+static void setBitrateBitPerSec(GObject* encoder, const gchar* prop_name, gint bitrate)
</ins><span class="cx"> {
</span><del>-  g_object_set (encoder, prop_name, bitrate, NULL);
</del><ins>+  g_object_set(encoder, prop_name, bitrate * KBIT_TO_BIT, nullptr);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void
-set_bitrate_bit_per_sec (GObject * encoder, const gchar * prop_name,
-    gint bitrate)
</del><ins>+static void webrtc_video_encoder_class_init(WebrtcVideoEncoderClass* klass)
</ins><span class="cx"> {
</span><del>-  g_object_set (encoder, prop_name, bitrate * KBIT_TO_BIT, NULL);
-}
</del><ins>+    GObjectClass* object_class = G_OBJECT_CLASS (klass);
</ins><span class="cx"> 
</span><del>-static void
-gst_webrtc_video_encoder_class_init (GstWebrtcVideoEncoderClass * klass)
-{
-  GObjectClass *object_class = G_OBJECT_CLASS (klass);
</del><ins>+    GST_DEBUG_CATEGORY_INIT (webrtc_venc_debug, "webrtcencoder", 0, "Video encoder for WebRTC");
</ins><span class="cx"> 
</span><del>-  GST_DEBUG_CATEGORY_INIT (gst_webrtcenc_debug, "webrtcencoder", 0,
-      "Video encoder for WebRTC");
</del><ins>+    object_class->get_property = webrtcVideoEncoderGetProperty;
+    object_class->set_property = webrtcVideoEncoderSetProperty;
</ins><span class="cx"> 
</span><del>-  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;
</del><ins>+    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)));
</ins><span class="cx"> 
</span><del>-  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)));
</del><ins>+    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)));
</ins><span class="cx"> 
</span><del>-  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)));
</del><ins>+    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)));
</ins><span class="cx"> 
</span><del>-  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)));
</del><ins>+    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)));
</ins><span class="cx"> 
</span><del>-  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=baseline",
-      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=baseline",
-      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=baseline",
-      setup_openh264enc, "bitrate", set_bitrate_bit_per_sec, "gop-size");
</del><ins>+    Encoders::registerEncoder(OmxH264, "omxh264enc", "h264parse", "video/x-h264",
+        "video/x-h264,alignment=au,stream-format=byte-stream,profile=baseline",
+        setupOmxh264enc, "target-bitrate", setBitrateBitPerSec, "interval-intraframes");
+    Encoders::registerEncoder(X264, "x264enc", "h264parse", "video/x-h264",
+        "video/x-h264,alignment=au,stream-format=byte-stream,profile=baseline",
+        setupX264enc, "bitrate", setBitrateKbitPerSec, "key-int-max");
+    Encoders::registerEncoder(OpenH264, "openh264enc", "h264parse", "video/x-h264",
+        "video/x-h264,alignment=au,stream-format=byte-stream,profile=baseline",
+        setupOpenh264enc, "bitrate", setBitrateBitPerSec, "gop-size");
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void
-gst_webrtc_video_encoder_init (GstWebrtcVideoEncoder * self)
</del><ins>+static void webrtc_video_encoder_init (WebrtcVideoEncoder* self)
</ins><span class="cx"> {
</span><del>-  GstWebrtcVideoEncoderPrivate *priv = PRIV (self);
</del><ins>+    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)));
</ins><span class="cx"> 
</span><del>-  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)));
</del><ins>+    gst_element_add_pad(GST_ELEMENT(self),
+        gst_ghost_pad_new_no_target_from_template("src", gst_static_pad_template_get(&srcTemplate)));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(VIDEO) && ENABLE(MEDIA_STREAM) && USE(LIBWEBRTC) && USE(GSTREAMER)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreamlibwebrtcGStreamerVideoEncoderh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/libwebrtc/GStreamerVideoEncoder.h (270186 => 270187)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/libwebrtc/GStreamerVideoEncoder.h      2020-11-27 10:02:08 UTC (rev 270186)
+++ trunk/Source/WebCore/platform/mediastream/libwebrtc/GStreamerVideoEncoder.h 2020-11-27 10:21:44 UTC (rev 270187)
</span><span class="lines">@@ -24,13 +24,8 @@
</span><span class="cx"> 
</span><span class="cx"> G_BEGIN_DECLS
</span><span class="cx"> 
</span><del>-#define GST_TYPE_WEBRTC_VIDEO_ENCODER (gst_webrtc_video_encoder_get_type())
</del><ins>+#define WEBRTC_TYPE_VIDEO_ENCODER (webrtc_video_encoder_get_type())
</ins><span class="cx"> 
</span><del>-G_DECLARE_DERIVABLE_TYPE (GstWebrtcVideoEncoder, gst_webrtc_video_encoder, GST, WEBRTC_VIDEO_ENCODER, GstBin)
</del><ins>+G_DECLARE_FINAL_TYPE (WebrtcVideoEncoder, webrtc_video_encoder, WEBRTC, VIDEO_ENCODER, GstBin)
</ins><span class="cx"> 
</span><del>-struct _GstWebrtcVideoEncoderClass
-{
-  GstBinClass parent_class;
-};
-
</del><span class="cx"> G_END_DECLS
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreamlibwebrtcGStreamerVideoEncoderFactorycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/libwebrtc/GStreamerVideoEncoderFactory.cpp (270186 => 270187)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/libwebrtc/GStreamerVideoEncoderFactory.cpp     2020-11-27 10:02:08 UTC (rev 270186)
+++ trunk/Source/WebCore/platform/mediastream/libwebrtc/GStreamerVideoEncoderFactory.cpp        2020-11-27 10:21:44 UTC (rev 270187)
</span><span class="lines">@@ -55,8 +55,6 @@
</span><span class="cx"> GST_DEBUG_CATEGORY(webkit_webrtcenc_debug);
</span><span class="cx"> #define GST_CAT_DEFAULT webkit_webrtcenc_debug
</span><span class="cx"> 
</span><del>-#define KBIT_TO_BIT 1024
-
</del><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> class GStreamerEncodedImageBuffer : public webrtc::EncodedImageBufferInterface {
</span><span class="lines">@@ -470,7 +468,7 @@
</span><span class="cx"> 
</span><span class="cx">     std::call_once(debugRegisteredFlag, [] {
</span><span class="cx">         GST_DEBUG_CATEGORY_INIT(webkit_webrtcenc_debug, "webkitlibwebrtcvideoencoder", 0, "WebKit WebRTC video encoder");
</span><del>-        gst_element_register(nullptr, "webrtcvideoencoder", GST_RANK_PRIMARY, GST_TYPE_WEBRTC_VIDEO_ENCODER);
</del><ins>+        gst_element_register(nullptr, "webrtcvideoencoder", GST_RANK_NONE, WEBRTC_TYPE_VIDEO_ENCODER);
</ins><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>