Modified: trunk/Source/WebCore/platform/mediastream/libwebrtc/GStreamerVideoEncoder.cpp (274148 => 274149)
--- trunk/Source/WebCore/platform/mediastream/libwebrtc/GStreamerVideoEncoder.cpp 2021-03-09 16:21:29 UTC (rev 274148)
+++ trunk/Source/WebCore/platform/mediastream/libwebrtc/GStreamerVideoEncoder.cpp 2021-03-09 16:53:16 UTC (rev 274149)
@@ -18,38 +18,37 @@
* Boston, MA 02110-1301, USA.
*/
-/* NOTE: This file respects GStreamer coding style as we might want to upstream
- * that element in the future */
-
#include "config.h"
#include "GStreamerVideoEncoder.h"
#if ENABLE(VIDEO) && ENABLE(MEDIA_STREAM) && USE(LIBWEBRTC) && USE(GSTREAMER)
-#include "GRefPtrGStreamer.h"
+
+#include "GStreamerCommon.h"
#include <wtf/StdMap.h>
+#include <wtf/glib/WTFGType.h>
-GST_DEBUG_CATEGORY (webrtc_venc_debug);
+using namespace WebCore;
+
+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 srcTemplate =
- GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS, GST_STATIC_CAPS ("video/x-h264;video/x-vp8"));
+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"));
-typedef void (*SetBitrateFunc) (GObject * encoder, const gchar * propname, gint bitrate);
-typedef void (*SetupFunc) (WebrtcVideoEncoder * self);
+using SetBitrateFunc = Function<void(GObject* encoder, const char* propertyName, int bitrate)>;
+using SetupFunc = Function<void(WebKitWebrtcVideoEncoder*)>;
struct EncoderDefinition {
GRefPtr<GstCaps> caps;
- const gchar* name;
- const gchar* parserName;
+ const char* name;
+ const char* parserName;
GRefPtr<GstCaps> encodedFormat;
SetBitrateFunc setBitrate;
SetupFunc setupEncoder;
- const gchar* bitratePropertyName;
- const gchar* keyframeIntervalPropertyName;
+ const char* bitratePropertyName;
+ const char* keyframeIntervalPropertyName;
};
enum EncoderId { None, X264, OpenH264, OmxH264, Vp8 };
@@ -62,140 +61,147 @@
return encoders;
}
- 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)
+ static void registerEncoder(EncoderId id, const char* name, const char* parserName, const char* caps, const char* encodedFormat,
+ SetupFunc&& setupEncoder, const char* bitratePropertyName, SetBitrateFunc&& setBitrate, const char* keyframeIntervalPropertyName)
{
- GstPluginFeature *feature = gst_registry_lookup_feature(gst_registry_get(), name);
+ auto feature = adoptGRef(gst_registry_lookup_feature(gst_registry_get(), name));
if (!feature)
return;
- gst_object_unref(feature);
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,
+ .parserName = parserName,
+ .encodedFormat = encodedFormat ? adoptGRef(gst_caps_from_string(encodedFormat)) : nullptr,
+ .setBitrate = WTFMove(setBitrate),
+ .setupEncoder = WTFMove(setupEncoder),
+ .bitratePropertyName = bitratePropertyName,
+ .keyframeIntervalPropertyName = keyframeIntervalPropertyName,
}));
}
- static const EncoderDefinition& definition(EncoderId id) {
- ASSERT(id != None);
+ static Optional<EncoderDefinition&> definition(EncoderId id)
+ {
+ if (id == None)
+ return { };
return singleton()[id];
}
};
-struct _WebrtcVideoEncoder {
- GstBin parent;
-
+struct _WebKitWebrtcVideoEncoderPrivate {
EncoderId encoderId;
- GstElement* encoder;
- GstElement* parser;
- guint bitrate;
+ GRefPtr<GstElement> encoder;
+ GRefPtr<GstElement> parser;
+ unsigned bitrate;
};
-G_DEFINE_TYPE(WebrtcVideoEncoder, webrtc_video_encoder, GST_TYPE_BIN);
+#define webkit_webrtc_video_encoder_parent_class parent_class
+WEBKIT_DEFINE_TYPE_WITH_CODE(WebKitWebrtcVideoEncoder, webkit_webrtc_video_encoder, GST_TYPE_BIN,
+ GST_DEBUG_CATEGORY_INIT(webrtc_venc_debug, "webrtcencoder", 0, "Video encoder for WebRTC"))
enum {
- PROP_FORMAT = 1,
- PROP_ENCODER,
- PROP_BITRATE,
- PROP_KEYFRAME_INTERVAL,
- N_PROPS
+ PROP_FORMAT = 1,
+ PROP_ENCODER,
+ PROP_BITRATE,
+ PROP_KEYFRAME_INTERVAL,
+ N_PROPS
};
static void webrtcVideoEncoderGetProperty(GObject* object, guint prop_id, GValue* value, GParamSpec* pspec)
{
- WebrtcVideoEncoder* self = WEBRTC_VIDEO_ENCODER(object);
+ auto* self = WEBKIT_WEBRTC_VIDEO_ENCODER(object);
+ auto* priv = self->priv;
switch (prop_id) {
case PROP_FORMAT:
- if (self->encoderId != None) {
- auto &encoder = Encoders::definition(self->encoderId);
- g_value_set_boxed(value, encoder.caps.get());
- } else
+ if (priv->encoderId != None) {
+ auto encoder = Encoders::definition(priv->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, self->encoder);
+ g_value_set_object(value, priv->encoder.get());
break;
case PROP_BITRATE:
- g_value_set_uint(value, self->bitrate);
+ g_value_set_uint(value, priv->bitrate);
break;
case PROP_KEYFRAME_INTERVAL:
- if (self->encoder) {
- auto &encoder = Encoders::definition(self->encoderId);
- g_object_get_property(G_OBJECT(self->encoder), encoder.keyframeIntervalPropertyName, value);
+ if (priv->encoder) {
+ auto encoder = Encoders::definition(priv->encoderId);
+ g_object_get_property(G_OBJECT(priv->encoder.get()), encoder->keyframeIntervalPropertyName, value);
}
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
- }
+ }
}
-static void webrtcVideoEncoderSetBitrate(WebrtcVideoEncoder* self, guint bitrate)
+static void webrtcVideoEncoderSetBitrate(WebKitWebrtcVideoEncoder* self, guint bitrate)
{
- self->bitrate = bitrate;
- if (self->encoder) {
- auto &encoder = Encoders::definition(self->encoderId);
- encoder.setBitrate(G_OBJECT(self->encoder), encoder.bitratePropertyName, self->bitrate);
+ auto* priv = self->priv;
+ priv->bitrate = bitrate;
+
+ if (priv->encoderId != None) {
+ auto encoder = Encoders::definition(priv->encoderId);
+ encoder->setBitrate(G_OBJECT(priv->encoder.get()), encoder->bitratePropertyName, priv->bitrate);
}
}
-static void webrtcVideoEncoderSetFormat(WebrtcVideoEncoder* self, const GstCaps* caps)
+static void webrtcVideoEncoderSetEncoder(WebKitWebrtcVideoEncoder* self, GRefPtr<GstElement>&& encoderElement, EncoderId encoderId)
{
- g_return_if_fail(self->encoderId == None);
- g_return_if_fail(caps);
+ auto* priv = self->priv;
+ priv->encoderId = encoderId;
+ priv->encoder = WTFMove(encoderElement);
- for (const auto &pair : Encoders::singleton()) {
- const auto &encoder = pair.second;
- GstElement* capsfilter = nullptr;
+ auto encoder = Encoders::definition(encoderId);
+ ASSERT(encoder);
+ if (encoder->parserName)
+ priv->parser = gst_element_factory_make(encoder->parserName, nullptr);
- 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);
+ encoder->setupEncoder(self);
- if (encoder.parserName)
- self->parser = gst_element_factory_make(encoder.parserName, nullptr);
+ gst_bin_add(GST_BIN_CAST(self), priv->encoder.get());
- encoder.setupEncoder(self);
- if (encoder.encodedFormat.get()) {
- capsfilter = gst_element_factory_make("capsfilter", nullptr);
- g_object_set(capsfilter, "caps", encoder.encodedFormat.get(), nullptr);
- }
+ auto sinkPadTarget = adoptGRef(gst_element_get_static_pad(priv->encoder.get(), "sink"));
+ auto sinkPad = adoptGRef(gst_element_get_static_pad(GST_ELEMENT_CAST(self), "sink"));
+ gst_ghost_pad_set_target(GST_GHOST_PAD(sinkPad.get()), sinkPadTarget.get());
- gst_bin_add(GST_BIN(self), self->encoder);
+ GRefPtr<GstPad> srcPadTarget;
+ if (priv->parser) {
+ gst_bin_add(GST_BIN_CAST(self), priv->parser.get());
+ gst_element_link(priv->encoder.get(), priv->parser.get());
+ srcPadTarget = adoptGRef(gst_element_get_static_pad(priv->parser.get(), "src"));
+ } else
+ srcPadTarget = adoptGRef(gst_element_get_static_pad(priv->encoder.get(), "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 (encoder->encodedFormat) {
+ auto* capsfilter = gst_element_factory_make("capsfilter", nullptr);
+ g_object_set(capsfilter, "caps", encoder->encodedFormat.get(), nullptr);
- 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_CAST(self), capsfilter);
+ auto sinkPad = adoptGRef(gst_element_get_static_pad(capsfilter, "sink"));
+ gst_pad_link(srcPadTarget.get(), sinkPad.get());
+ srcPadTarget = adoptGRef(gst_element_get_static_pad(capsfilter, "src"));
+ }
- if (capsfilter) {
- GRefPtr<GstPad> tmppad2 = adoptGRef(gst_element_get_static_pad(capsfilter, "sink"));
+ auto srcPad = adoptGRef(gst_element_get_static_pad(GST_ELEMENT_CAST(self), "src"));
+ gst_ghost_pad_set_target(GST_GHOST_PAD(srcPad.get()), srcPadTarget.get());
- gst_bin_add(GST_BIN(self), capsfilter);
- gst_pad_link(tmppad.get(), tmppad2.get());
- tmppad = adoptGRef(gst_element_get_static_pad(capsfilter, "src"));
- }
+ webrtcVideoEncoderSetBitrate(self, priv->bitrate);
+}
- 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());
+static void webrtcVideoEncoderSetFormat(WebKitWebrtcVideoEncoder* self, const GstCaps* caps)
+{
+ if (!caps)
+ return;
- RELEASE_ASSERT(ret);
-
- webrtcVideoEncoderSetBitrate(self, self->bitrate);
+ for (const auto& pair : Encoders::singleton()) {
+ const auto& encoder = pair.second;
+ if (gst_caps_can_intersect(encoder.caps.get(), caps)) {
+ GRefPtr<GstElement> element = gst_element_factory_make(encoder.name, nullptr);
+ webrtcVideoEncoderSetEncoder(self, WTFMove(element), pair.first);
return;
}
}
@@ -205,7 +211,8 @@
static void webrtcVideoEncoderSetProperty(GObject* object, guint prop_id, const GValue* value, GParamSpec* pspec)
{
- WebrtcVideoEncoder* self = WEBRTC_VIDEO_ENCODER(object);
+ auto* self = WEBKIT_WEBRTC_VIDEO_ENCODER(object);
+ auto* priv = self->priv;
switch (prop_id) {
case PROP_FORMAT:
@@ -215,9 +222,9 @@
webrtcVideoEncoderSetBitrate(self, g_value_get_uint(value));
break;
case PROP_KEYFRAME_INTERVAL:
- if (self->encoder) {
- auto &encoder = Encoders::definition(self->encoderId);
- g_object_set(self->encoder, encoder.keyframeIntervalPropertyName, g_value_get_uint(value), nullptr);
+ if (priv->encoder) {
+ auto encoder = Encoders::definition(priv->encoderId);
+ g_object_set(priv->encoder.get(), encoder->keyframeIntervalPropertyName, g_value_get_uint(value), nullptr);
}
break;
default:
@@ -226,77 +233,58 @@
}
}
-static void setupX264enc(WebrtcVideoEncoder* self)
+static void setBitrateKbitPerSec(GObject* encoder, const char* propertyName, int bitrate)
{
- gst_util_set_object_arg(G_OBJECT (self->encoder), "tune", "zerolatency");
- g_object_set(self->parser, "config-interval", 1, nullptr);
+ g_object_set(encoder, propertyName, bitrate, nullptr);
}
-static void setupOpenh264enc(WebrtcVideoEncoder* self)
+static void setBitrateBitPerSec(GObject* encoder, const char* propertyName, int bitrate)
{
- g_object_set (self->parser, "config-interval", 1, nullptr);
+ g_object_set(encoder, propertyName, bitrate * KBIT_TO_BIT, nullptr);
}
-static void setupOmxh264enc(WebrtcVideoEncoder* self)
+static void webrtcVideoEncoderConstructed(GObject* encoder)
{
- gst_util_set_object_arg(G_OBJECT(self->encoder), "control-rate", "variable");
- g_object_set(self->parser, "config-interval", 1, nullptr);
+ auto* self = WEBKIT_WEBRTC_VIDEO_ENCODER(encoder);
+ self->priv->encoderId = None;
+ gst_element_add_pad(GST_ELEMENT_CAST(self), webkitGstGhostPadFromStaticTemplate(&sinkTemplate, "sink", nullptr));
+ gst_element_add_pad(GST_ELEMENT_CAST(self), webkitGstGhostPadFromStaticTemplate(&srcTemplate, "src", nullptr));
}
-static void setBitrateKbitPerSec(GObject* encoder, const gchar* prop_name, gint bitrate)
+static void webkit_webrtc_video_encoder_class_init(WebKitWebrtcVideoEncoderClass* klass)
{
- g_object_set(encoder, prop_name, bitrate, nullptr);
-}
+ GObjectClass* objectClass = G_OBJECT_CLASS(klass);
+ objectClass->constructed = webrtcVideoEncoderConstructed;
+ objectClass->get_property = webrtcVideoEncoderGetProperty;
+ objectClass->set_property = webrtcVideoEncoderSetProperty;
-static void setBitrateBitPerSec(GObject* encoder, const gchar* prop_name, gint bitrate)
-{
- g_object_set(encoder, prop_name, bitrate * KBIT_TO_BIT, nullptr);
-}
+ g_object_class_install_property(objectClass, PROP_FORMAT, g_param_spec_boxed("format", "Format as caps", "Set the caps of the format to be used.", GST_TYPE_CAPS, WEBKIT_PARAM_READWRITE));
-static void webrtc_video_encoder_class_init(WebrtcVideoEncoderClass* klass)
-{
- GObjectClass* object_class = G_OBJECT_CLASS (klass);
+ g_object_class_install_property(objectClass, PROP_ENCODER, g_param_spec_object("encoder", "The actual encoder element", "The encoder element", GST_TYPE_ELEMENT, WEBKIT_PARAM_READABLE));
- GST_DEBUG_CATEGORY_INIT (webrtc_venc_debug, "webrtcencoder", 0, "Video encoder for WebRTC");
-
- object_class->get_property = webrtcVideoEncoderGetProperty;
- object_class->set_property = webrtcVideoEncoderSetProperty;
-
- 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_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_BITRATE,
- g_param_spec_uint("bitrate", "Bitrate", "The bitrate in kbit per second", 0, G_MAXINT, 2048,
+ g_object_class_install_property(objectClass, 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_KEYFRAME_INTERVAL,
- g_param_spec_uint("keyframe-interval", "Keyframe interval", "The interval between keyframes", 0, G_MAXINT, 0,
+ g_object_class_install_property(objectClass, 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)));
Encoders::registerEncoder(OmxH264, "omxh264enc", "h264parse", "video/x-h264",
"video/x-h264,alignment=au,stream-format=byte-stream,profile=""
- setupOmxh264enc, "target-bitrate", setBitrateBitPerSec, "interval-intraframes");
+ [](WebKitWebrtcVideoEncoder* self) {
+ gst_util_set_object_arg(G_OBJECT(self->priv->encoder.get()), "control-rate", "variable");
+ g_object_set(self->priv->parser.get(), "config-interval", 1, nullptr);
+ }, "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");
+ [](WebKitWebrtcVideoEncoder* self) {
+ gst_util_set_object_arg(G_OBJECT(self->priv->encoder.get()), "tune", "zerolatency");
+ g_object_set(self->priv->parser.get(), "config-interval", 1, nullptr);
+ }, "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");
+ [](WebKitWebrtcVideoEncoder* self) {
+ g_object_set(self->priv->parser.get(), "config-interval", 1, nullptr);
+ }, "bitrate", setBitrateBitPerSec, "gop-size");
}
-static void webrtc_video_encoder_init (WebrtcVideoEncoder* 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)));
-
- 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)
Modified: trunk/Tools/Scripts/webkitpy/style/checker.py (274148 => 274149)
--- trunk/Tools/Scripts/webkitpy/style/checker.py 2021-03-09 16:21:29 UTC (rev 274148)
+++ trunk/Tools/Scripts/webkitpy/style/checker.py 2021-03-09 16:53:16 UTC (rev 274149)
@@ -232,6 +232,8 @@
os.path.join('Source', 'WebCore', 'platform', 'audio', 'gstreamer', 'WebKitWebAudioSourceGStreamer.cpp'),
os.path.join('Source', 'WebCore', 'platform', 'mediastream', 'gstreamer', 'GStreamerMediaStreamSource.h'),
os.path.join('Source', 'WebCore', 'platform', 'mediastream', 'gstreamer', 'GStreamerMediaStreamSource.cpp'),
+ os.path.join('Source', 'WebCore', 'platform', 'mediastream', 'libwebrtc', 'GStreamerVideoEncoder.h'),
+ os.path.join('Source', 'WebCore', 'platform', 'mediastream', 'libwebrtc', 'GStreamerVideoEncoder.cpp'),
os.path.join('Source', 'WebCore', 'platform', 'network', 'soup', 'ProxyResolverSoup.cpp'),
os.path.join('Source', 'WebCore', 'platform', 'network', 'soup', 'ProxyResolverSoup.h'),
os.path.join('Source', 'WebCore', 'platform', 'network', 'soup', 'WebKitFormDataInputStream.cpp'),
@@ -263,19 +265,6 @@
"-whitespace/declaration",
"-whitespace/indent"]),
- ([ # Files following GStreamer coding style (for a simpler upstreaming process for example)
- os.path.join('Source', 'WebCore', 'platform', 'mediastream', 'libwebrtc', 'GStreamerVideoEncoder.cpp'),
- os.path.join('Source', 'WebCore', 'platform', 'mediastream', 'libwebrtc', 'GStreamerVideoEncoder.h'),
- ],
- ["-whitespace/indent",
- "-whitespace/declaration",
- "-whitespace/parens",
- "-readability/null",
- "-whitespace/braces",
- "-readability/naming/underscores",
- "-readability/enum_casing",
- ]),
-
([ # Files following using WebRTC optionnal type
os.path.join('Source', 'WebCore', 'platform', 'mediastream', 'libwebrtc', 'GStreamerVideoDecoderFactory.cpp'),
],