Title: [238557] trunk/Source
Revision
238557
Author
[email protected]
Date
2018-11-27 09:34:28 -0800 (Tue, 27 Nov 2018)

Log Message

[GStreamer][WebRTC] Use LibWebRTC provided vp8 decoders and encoders
https://bugs.webkit.org/show_bug.cgi?id=191861

Source/ThirdParty/libwebrtc:

Patch by Thibault Saunier <[email protected]> on 2018-11-27
Reviewed by Philippe Normand.

* CMakeLists.txt: Build LibVPX vp8 encoder and decoders.

Source/WebCore:

The GStreamer implementations are less feature full and less tested, now that Apple
also use the LibWebRTC provided implementations it makes a lot of sense for us to
do the same.

Basically everything related to temporal scalability is not implemented in GStreamer.

We should make sure to use GStreamer elements on low powered platforms and for
accelerated encoders and decoders.

Patch by Thibault Saunier <[email protected]> on 2018-11-27
Reviewed by Philippe Normand.

This is mostly refactoring, no new test required.

* platform/graphics/gstreamer/GStreamerCommon.h: Added GstMappedFrame similar to GstMappedBuffer but for video frames.
(WebCore::GstMappedFrame::GstMappedFrame):
(WebCore::GstMappedFrame::get):
(WebCore::GstMappedFrame::ComponentData):
(WebCore::GstMappedFrame::ComponentStride):
(WebCore::GstMappedFrame::info):
(WebCore::GstMappedFrame::width):
(WebCore::GstMappedFrame::height):
(WebCore::GstMappedFrame::format):
(WebCore::GstMappedFrame::~GstMappedFrame):
(WebCore::GstMappedFrame::operator bool const):
* platform/graphics/gstreamer/GUniquePtrGStreamer.h:
* platform/mediastream/gstreamer/GStreamerVideoFrameLibWebRTC.cpp:
(WebCore::GStreamerVideoFrameLibWebRTC::ToI420): Implemented support for converting frame formats with the GstVideoConverter API
* platform/mediastream/libwebrtc/GStreamerVideoDecoderFactory.cpp:
(WebCore::GStreamerVideoDecoder::GstDecoderFactory):
(WebCore::GStreamerVideoDecoder::HasGstDecoder):
(WebCore::VP8Decoder::Create): Creates a `webrtc::LibvpxVp8Decoder()` if GStreamer decoder would be the LibVPX based one.
(WebCore::GStreamerVideoDecoderFactory::CreateVideoDecoder):
* platform/mediastream/libwebrtc/GStreamerVideoEncoder.cpp:
(gst_webrtc_video_encoder_class_init):
* platform/mediastream/libwebrtc/GStreamerVideoEncoderFactory.cpp: Stop using vp8enc and use LibWebRTC based implementation
(WebCore::GStreamerH264Encoder::GStreamerH264Encoder): Renamed H264Encoder to GStreamerH264Encoder to be more coherent with what is done in LibVPX
(WebCore::GStreamerVP8Encoder::GStreamerVP8Encoder): Renamed VP8Encoder to GStreamerVP8Encoder to be more coherent with what is done in LibVPX
(WebCore::GStreamerVideoEncoderFactory::CreateVideoEncoder):
(WebCore::GStreamerVideoEncoderFactory::GetSupportedFormats const):

Modified Paths

Diff

Modified: trunk/Source/ThirdParty/libwebrtc/CMakeLists.txt (238556 => 238557)


--- trunk/Source/ThirdParty/libwebrtc/CMakeLists.txt	2018-11-27 17:28:23 UTC (rev 238556)
+++ trunk/Source/ThirdParty/libwebrtc/CMakeLists.txt	2018-11-27 17:34:28 UTC (rev 238557)
@@ -1050,6 +1050,11 @@
     Source/webrtc/modules/video_coding/codecs/i420/i420.cc
     Source/webrtc/modules/video_coding/codecs/vp8/default_temporal_layers.cc
     Source/webrtc/modules/video_coding/codecs/vp8/screenshare_layers.cc
+    Source/webrtc/modules/video_coding/codecs/vp8/vp8_temporal_layers.cc
+    Source/webrtc/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.cc
+    Source/webrtc/modules/video_coding/codecs/vp8/libvpx_interface.cc
+    Source/webrtc/modules/video_coding/codecs/vp8/temporal_layers_checker.cc
+    Source/webrtc/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc
     Source/webrtc/modules/video_coding/codecs/vp9/svc_config.cc
     Source/webrtc/modules/video_coding/codecs/vp9/svc_rate_allocator.cc
     Source/webrtc/modules/video_coding/decoder_database.cc

Modified: trunk/Source/ThirdParty/libwebrtc/ChangeLog (238556 => 238557)


--- trunk/Source/ThirdParty/libwebrtc/ChangeLog	2018-11-27 17:28:23 UTC (rev 238556)
+++ trunk/Source/ThirdParty/libwebrtc/ChangeLog	2018-11-27 17:34:28 UTC (rev 238557)
@@ -1,3 +1,12 @@
+2018-11-27  Thibault Saunier  <[email protected]>
+
+        [GStreamer][WebRTC] Use LibWebRTC provided vp8 decoders and encoders
+        https://bugs.webkit.org/show_bug.cgi?id=191861
+
+        Reviewed by Philippe Normand.
+
+        * CMakeLists.txt: Build LibVPX vp8 encoder and decoders.
+
 2018-11-14  Youenn Fablet  <[email protected]>
 
         Convert libwebrtc error types to DOM exceptions

Modified: trunk/Source/WebCore/ChangeLog (238556 => 238557)


--- trunk/Source/WebCore/ChangeLog	2018-11-27 17:28:23 UTC (rev 238556)
+++ trunk/Source/WebCore/ChangeLog	2018-11-27 17:34:28 UTC (rev 238557)
@@ -1,3 +1,48 @@
+2018-11-27  Thibault Saunier  <[email protected]>
+
+        [GStreamer][WebRTC] Use LibWebRTC provided vp8 decoders and encoders
+        https://bugs.webkit.org/show_bug.cgi?id=191861
+
+        The GStreamer implementations are less feature full and less tested, now that Apple
+        also use the LibWebRTC provided implementations it makes a lot of sense for us to
+        do the same.
+
+        Basically everything related to temporal scalability is not implemented in GStreamer.
+
+        We should make sure to use GStreamer elements on low powered platforms and for
+        accelerated encoders and decoders.
+
+        Reviewed by Philippe Normand.
+
+        This is mostly refactoring, no new test required.
+
+        * platform/graphics/gstreamer/GStreamerCommon.h: Added GstMappedFrame similar to GstMappedBuffer but for video frames.
+        (WebCore::GstMappedFrame::GstMappedFrame):
+        (WebCore::GstMappedFrame::get):
+        (WebCore::GstMappedFrame::ComponentData):
+        (WebCore::GstMappedFrame::ComponentStride):
+        (WebCore::GstMappedFrame::info):
+        (WebCore::GstMappedFrame::width):
+        (WebCore::GstMappedFrame::height):
+        (WebCore::GstMappedFrame::format):
+        (WebCore::GstMappedFrame::~GstMappedFrame):
+        (WebCore::GstMappedFrame::operator bool const):
+        * platform/graphics/gstreamer/GUniquePtrGStreamer.h:
+        * platform/mediastream/gstreamer/GStreamerVideoFrameLibWebRTC.cpp:
+        (WebCore::GStreamerVideoFrameLibWebRTC::ToI420): Implemented support for converting frame formats with the GstVideoConverter API
+        * platform/mediastream/libwebrtc/GStreamerVideoDecoderFactory.cpp:
+        (WebCore::GStreamerVideoDecoder::GstDecoderFactory):
+        (WebCore::GStreamerVideoDecoder::HasGstDecoder):
+        (WebCore::VP8Decoder::Create): Creates a `webrtc::LibvpxVp8Decoder()` if GStreamer decoder would be the LibVPX based one.
+        (WebCore::GStreamerVideoDecoderFactory::CreateVideoDecoder):
+        * platform/mediastream/libwebrtc/GStreamerVideoEncoder.cpp:
+        (gst_webrtc_video_encoder_class_init):
+        * platform/mediastream/libwebrtc/GStreamerVideoEncoderFactory.cpp: Stop using vp8enc and use LibWebRTC based implementation
+        (WebCore::GStreamerH264Encoder::GStreamerH264Encoder): Renamed H264Encoder to GStreamerH264Encoder to be more coherent with what is done in LibVPX
+        (WebCore::GStreamerVP8Encoder::GStreamerVP8Encoder): Renamed VP8Encoder to GStreamerVP8Encoder to be more coherent with what is done in LibVPX
+        (WebCore::GStreamerVideoEncoderFactory::CreateVideoEncoder):
+        (WebCore::GStreamerVideoEncoderFactory::GetSupportedFormats const):
+
 2018-11-27  Javier Fernandez  <[email protected]>
 
         [css-grid] align-self center and position sticky don't work together

Modified: trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.h (238556 => 238557)


--- trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.h	2018-11-27 17:28:23 UTC (rev 238556)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.h	2018-11-27 17:34:28 UTC (rev 238557)
@@ -135,9 +135,92 @@
     return a.size() == gst_buffer_get_size(nonConstB) && !gst_buffer_memcmp(nonConstB, 0, a.data(), a.size());
 }
 
+class GstMappedFrame {
+    WTF_MAKE_NONCOPYABLE(GstMappedFrame);
+public:
+
+    GstMappedFrame(GstBuffer* buffer, GstVideoInfo info, GstMapFlags flags)
+    {
+        m_isValid = gst_video_frame_map(&m_frame, &info, buffer, flags);
+    }
+
+    GstMappedFrame(GRefPtr<GstSample> sample, GstMapFlags flags)
+    {
+        GstVideoInfo info;
+
+        if (!gst_video_info_from_caps(&info, gst_sample_get_caps(sample.get()))) {
+            m_isValid = false;
+            return;
+        }
+
+        m_isValid = gst_video_frame_map(&m_frame, &info, gst_sample_get_buffer(sample.get()), flags);
+    }
+
+    GstVideoFrame* get()
+    {
+        if (!m_isValid) {
+            GST_INFO("Invalid frame, returning NULL");
+
+            return nullptr;
+        }
+
+        return &m_frame;
+    }
+
+    uint8_t* ComponentData(int comp)
+    {
+        return GST_VIDEO_FRAME_COMP_DATA(&m_frame, comp);
+    }
+
+    int ComponentStride(int stride)
+    {
+        return GST_VIDEO_FRAME_COMP_STRIDE(&m_frame, stride);
+    }
+
+    GstVideoInfo* info()
+    {
+        if (!m_isValid) {
+            GST_INFO("Invalid frame, returning NULL");
+
+            return nullptr;
+        }
+
+        return &m_frame.info;
+    }
+
+    int width()
+    {
+        return m_isValid ? GST_VIDEO_FRAME_WIDTH(&m_frame) : -1;
+    }
+
+    int height()
+    {
+        return m_isValid ? GST_VIDEO_FRAME_HEIGHT(&m_frame) : -1;
+    }
+
+    int format()
+    {
+        return m_isValid ? GST_VIDEO_FRAME_FORMAT(&m_frame) : GST_VIDEO_FORMAT_UNKNOWN;
+    }
+
+    ~GstMappedFrame()
+    {
+        if (m_isValid)
+            gst_video_frame_unmap(&m_frame);
+        m_isValid = false;
+    }
+
+    explicit operator bool() const { return m_isValid; }
+
+private:
+    GstVideoFrame m_frame;
+    bool m_isValid { false };
+};
+
+
 bool gstRegistryHasElementForMediaType(GList* elementFactories, const char* capsString);
-void connectSimpleBusMessageCallback(GstElement *pipeline);
-void disconnectSimpleBusMessageCallback(GstElement *pipeline);
+void connectSimpleBusMessageCallback(GstElement* pipeline);
+void disconnectSimpleBusMessageCallback(GstElement* pipeline);
 
 }
 

Modified: trunk/Source/WebCore/platform/graphics/gstreamer/GUniquePtrGStreamer.h (238556 => 238557)


--- trunk/Source/WebCore/platform/graphics/gstreamer/GUniquePtrGStreamer.h	2018-11-27 17:28:23 UTC (rev 238556)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/GUniquePtrGStreamer.h	2018-11-27 17:34:28 UTC (rev 238557)
@@ -26,6 +26,7 @@
 #include <gst/gstsegment.h>
 #include <gst/gststructure.h>
 #include <gst/pbutils/install-plugins.h>
+#include <gst/video/video.h>
 #include <wtf/glib/GUniquePtr.h>
 
 namespace WTF {
@@ -36,6 +37,7 @@
 WTF_DEFINE_GPTR_DELETER(GstSegment, gst_segment_free)
 WTF_DEFINE_GPTR_DELETER(GstFlowCombiner, gst_flow_combiner_free)
 WTF_DEFINE_GPTR_DELETER(GstByteReader, gst_byte_reader_free)
+WTF_DEFINE_GPTR_DELETER(GstVideoConverter, gst_video_converter_free)
 
 }
 

Modified: trunk/Source/WebCore/platform/mediastream/gstreamer/GStreamerVideoFrameLibWebRTC.cpp (238556 => 238557)


--- trunk/Source/WebCore/platform/mediastream/gstreamer/GStreamerVideoFrameLibWebRTC.cpp	2018-11-27 17:28:23 UTC (rev 238556)
+++ trunk/Source/WebCore/platform/mediastream/gstreamer/GStreamerVideoFrameLibWebRTC.cpp	2018-11-27 17:34:28 UTC (rev 238557)
@@ -21,6 +21,8 @@
 #if USE(GSTREAMER) && USE(LIBWEBRTC)
 #include "GStreamerVideoFrameLibWebRTC.h"
 
+#include <thread>
+
 namespace WebCore {
 
 const GRefPtr<GstSample> GStreamerSampleFromLibWebRTCVideoFrame(const webrtc::VideoFrame& frame)
@@ -90,37 +92,55 @@
 
 rtc::scoped_refptr<webrtc::I420BufferInterface> GStreamerVideoFrameLibWebRTC::ToI420()
 {
-    GstVideoInfo info;
-    GstVideoFrame frame;
+    GstMappedFrame inFrame(m_sample, GST_MAP_READ);
 
-    if (!gst_video_info_from_caps(&info, gst_sample_get_caps(m_sample.get())))
-        ASSERT_NOT_REACHED();
+    if (!inFrame) {
+        GST_WARNING("Could not map frame");
 
-    if (GST_VIDEO_INFO_FORMAT(&info) != GST_VIDEO_FORMAT_I420)
         return nullptr;
+    }
 
-    gst_video_frame_map(&frame, &info, gst_sample_get_buffer(m_sample.get()), GST_MAP_READ);
-
-    auto newBuffer = m_bufferPool.CreateBuffer(GST_VIDEO_FRAME_WIDTH(&frame),
-        GST_VIDEO_FRAME_HEIGHT(&frame));
-
+    auto newBuffer = m_bufferPool.CreateBuffer(inFrame.width(), inFrame.height());
     ASSERT(newBuffer);
     if (!newBuffer) {
-        gst_video_frame_unmap(&frame);
         GST_WARNING("RealtimeOutgoingVideoSourceGStreamer::videoSampleAvailable unable to allocate buffer for conversion to YUV");
         return nullptr;
     }
 
+    if (inFrame.format() != GST_VIDEO_FORMAT_I420) {
+        GstVideoInfo outInfo;
+
+        gst_video_info_set_format(&outInfo, GST_VIDEO_FORMAT_I420, inFrame.width(),
+            inFrame.height());
+        auto info = inFrame.info();
+        outInfo.fps_n = info->fps_n;
+        outInfo.fps_d = info->fps_d;
+
+        GRefPtr<GstBuffer> buffer = adoptGRef(gst_buffer_new_wrapped_full(GST_MEMORY_FLAG_NO_SHARE, newBuffer->MutableDataY(),
+            outInfo.size, 0, outInfo.size, nullptr, nullptr));
+
+        GstMappedFrame outFrame(buffer.get(), outInfo, GST_MAP_WRITE);
+
+        GUniquePtr<GstVideoConverter> videoConverter(gst_video_converter_new(inFrame.info(),
+            &outInfo, gst_structure_new("GstVideoConvertConfig",
+            GST_VIDEO_CONVERTER_OPT_THREADS, G_TYPE_UINT, std::thread::hardware_concurrency() || 1 , nullptr)));
+
+        ASSERT(videoConverter);
+
+        gst_video_converter_frame(videoConverter.get(), inFrame.get(), outFrame.get());
+
+        return newBuffer;
+    }
+
     newBuffer->Copy(
-        GST_VIDEO_FRAME_WIDTH(&frame),
-        GST_VIDEO_FRAME_HEIGHT(&frame),
-        GST_VIDEO_FRAME_COMP_DATA(&frame, 0),
-        GST_VIDEO_FRAME_COMP_STRIDE(&frame, 0),
-        GST_VIDEO_FRAME_COMP_DATA(&frame, 1),
-        GST_VIDEO_FRAME_COMP_STRIDE(&frame, 1),
-        GST_VIDEO_FRAME_COMP_DATA(&frame, 2),
-        GST_VIDEO_FRAME_COMP_STRIDE(&frame, 2));
-    gst_video_frame_unmap(&frame);
+        inFrame.width(),
+        inFrame.height(),
+        inFrame.ComponentData(0),
+        inFrame.ComponentStride(0),
+        inFrame.ComponentData(1),
+        inFrame.ComponentStride(1),
+        inFrame.ComponentData(2),
+        inFrame.ComponentStride(2));
 
     return newBuffer;
 }

Modified: trunk/Source/WebCore/platform/mediastream/libwebrtc/GStreamerVideoDecoderFactory.cpp (238556 => 238557)


--- trunk/Source/WebCore/platform/mediastream/libwebrtc/GStreamerVideoDecoderFactory.cpp	2018-11-27 17:28:23 UTC (rev 238556)
+++ trunk/Source/WebCore/platform/mediastream/libwebrtc/GStreamerVideoDecoderFactory.cpp	2018-11-27 17:34:28 UTC (rev 238557)
@@ -29,6 +29,7 @@
 #include "webrtc/media/base/codec.h"
 #include "webrtc/modules/video_coding/codecs/h264/include/h264.h"
 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h"
+#include "webrtc/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.h"
 #include "webrtc/modules/video_coding/include/video_codec_interface.h"
 #include <gst/app/gstappsink.h>
 #include <gst/app/gstappsrc.h>
@@ -214,21 +215,28 @@
         return webrtc::SdpVideoFormat(Name());
     }
 
-    bool HasGstDecoder()
+    static GRefPtr<GstElementFactory> GstDecoderFactory(const char *capsStr)
     {
-
         auto all_decoders = gst_element_factory_list_get_elements(GST_ELEMENT_FACTORY_TYPE_DECODER,
             GST_RANK_MARGINAL);
-        auto caps = adoptGRef(gst_caps_from_string(Caps()));
+        auto caps = adoptGRef(gst_caps_from_string(capsStr));
         auto decoders = gst_element_factory_list_filter(all_decoders,
             caps.get(), GST_PAD_SINK, FALSE);
 
         gst_plugin_feature_list_free(all_decoders);
+        GRefPtr<GstElementFactory> res;
+        if (decoders)
+            res = GST_ELEMENT_FACTORY(decoders->data);
         gst_plugin_feature_list_free(decoders);
 
-        return decoders != nullptr;
+        return res;
     }
 
+    bool HasGstDecoder()
+    {
+        return GstDecoderFactory(Caps());
+    }
+
     GstFlowReturn newSampleCallback(GstElement* sink)
     {
         auto sample = gst_app_sink_pull_sample(GST_APP_SINK(sink));
@@ -343,16 +351,28 @@
     const gchar* Caps() final { return "video/x-vp8"; }
     const gchar* Name() final { return cricket::kVp8CodecName; }
     webrtc::VideoCodecType CodecType() final { return webrtc::kVideoCodecVP8; }
+    static std::unique_ptr<webrtc::VideoDecoder> Create()
+    {
+        auto factory = GstDecoderFactory("video/x-vp8");
+
+        if (factory && !g_strcmp0(GST_OBJECT_NAME(GST_OBJECT(factory.get())), "vp8dec")) {
+            GST_INFO("Our best GStreamer VP8 decoder is vp8dec, better use the one from LibWebRTC");
+
+            return std::unique_ptr<webrtc::VideoDecoder>(new webrtc::LibvpxVp8Decoder());
+        }
+
+        return std::unique_ptr<webrtc::VideoDecoder>(new VP8Decoder());
+    }
 };
 
 std::unique_ptr<webrtc::VideoDecoder> GStreamerVideoDecoderFactory::CreateVideoDecoder(const webrtc::SdpVideoFormat& format)
 {
-    GStreamerVideoDecoder* dec;
+    webrtc::VideoDecoder* dec;
 
     if (format.name == cricket::kH264CodecName)
         dec = new H264Decoder();
     else if (format.name == cricket::kVp8CodecName)
-        dec = new VP8Decoder();
+        return VP8Decoder::Create();
     else {
         GST_ERROR("Could not create decoder for %s", format.name.c_str());
 

Modified: trunk/Source/WebCore/platform/mediastream/libwebrtc/GStreamerVideoEncoder.cpp (238556 => 238557)


--- trunk/Source/WebCore/platform/mediastream/libwebrtc/GStreamerVideoEncoder.cpp	2018-11-27 17:28:23 UTC (rev 238556)
+++ trunk/Source/WebCore/platform/mediastream/libwebrtc/GStreamerVideoEncoder.cpp	2018-11-27 17:34:28 UTC (rev 238557)
@@ -278,12 +278,6 @@
 }
 
 static void
-setup_vp8enc (GObject * encoder)
-{
-  gst_preset_load_preset (GST_PRESET (encoder), "Profile Realtime");
-}
-
-static void
 setup_openh264enc (GObject *)
 {
 }
@@ -296,13 +290,6 @@
 }
 
 static void
-set_bitrate_bit_per_sec (GObject * encoder, const gchar * prop_name,
-    gint bitrate)
-{
-  g_object_set (encoder, prop_name, bitrate * KBIT_TO_BIT, NULL);
-}
-
-static void
 gst_webrtc_video_encoder_class_init (GstWebrtcVideoEncoderClass * klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
@@ -344,9 +331,6 @@
       "video/x-h264",
       "video/x-h264,alignment=au,stream-format=byte-stream,profile=""
       setup_openh264enc, "bitrate", set_bitrate_kbit_per_sec, "gop-size");
-  register_known_encoder (ENCODER_VP8, "vp8enc", NULL, "video/x-vp8", NULL,
-      setup_vp8enc, "target-bitrate", set_bitrate_bit_per_sec,
-      "keyframe-max-dist");
 }
 
 static void

Modified: trunk/Source/WebCore/platform/mediastream/libwebrtc/GStreamerVideoEncoderFactory.cpp (238556 => 238557)


--- trunk/Source/WebCore/platform/mediastream/libwebrtc/GStreamerVideoEncoderFactory.cpp	2018-11-27 17:28:23 UTC (rev 238556)
+++ trunk/Source/WebCore/platform/mediastream/libwebrtc/GStreamerVideoEncoderFactory.cpp	2018-11-27 17:34:28 UTC (rev 238557)
@@ -30,6 +30,7 @@
 #include "webrtc/media/base/codec.h"
 #include "webrtc/modules/video_coding/codecs/h264/include/h264.h"
 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h"
+#include "webrtc/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.h"
 #include "webrtc/modules/video_coding/include/video_codec_interface.h"
 #include "webrtc/modules/video_coding/utility/simulcast_utility.h"
 
@@ -410,11 +411,11 @@
     Vector<FrameData> m_framesData;
 };
 
-class H264Encoder : public GStreamerVideoEncoder {
+class GStreamerH264Encoder : public GStreamerVideoEncoder {
 public:
-    H264Encoder() { }
+    GStreamerH264Encoder() { }
 
-    H264Encoder(const webrtc::SdpVideoFormat& format)
+    GStreamerH264Encoder(const webrtc::SdpVideoFormat& format)
         : m_parser(gst_h264_nal_parser_new())
         , packetizationMode(webrtc::H264PacketizationMode::NonInterleaved)
     {
@@ -508,10 +509,10 @@
     webrtc::H264PacketizationMode packetizationMode;
 };
 
-class VP8Encoder : public GStreamerVideoEncoder {
+class GStreamerVP8Encoder : public GStreamerVideoEncoder {
 public:
-    VP8Encoder() { }
-    VP8Encoder(const webrtc::SdpVideoFormat&) { }
+    GStreamerVP8Encoder() { }
+    GStreamerVP8Encoder(const webrtc::SdpVideoFormat&) { }
     const gchar* Caps() final { return "video/x-vp8"; }
     const gchar* Name() final { return cricket::kVp8CodecName; }
     webrtc::VideoCodecType CodecType() final { return webrtc::kVideoCodecVP8; }
@@ -535,11 +536,22 @@
 
 std::unique_ptr<webrtc::VideoEncoder> GStreamerVideoEncoderFactory::CreateVideoEncoder(const webrtc::SdpVideoFormat& format)
 {
-    if (format.name == cricket::kVp8CodecName)
-        return std::make_unique<VP8Encoder>(format);
+    if (format.name == cricket::kVp8CodecName) {
+        GRefPtr<GstElement> webrtcencoder = adoptGRef(GST_ELEMENT(g_object_ref_sink(gst_element_factory_make("webrtcvideoencoder", NULL))));
+        GRefPtr<GstElement> encoder = nullptr;
 
+        g_object_set(webrtcencoder.get(), "format", adoptGRef(gst_caps_from_string("video/x-vp8")).get(), NULL);
+        g_object_get(webrtcencoder.get(), "encoder", &encoder.outPtr(), NULL);
+
+        if (encoder)
+            return std::make_unique<GStreamerVP8Encoder>(format);
+
+        GST_INFO("Using VP8 Encoder from LibWebRTC.");
+        return std::make_unique<webrtc::LibvpxVp8Encoder>();
+    }
+
     if (format.name == cricket::kH264CodecName)
-        return std::make_unique<H264Encoder>(format);
+        return std::make_unique<GStreamerH264Encoder>(format);
 
     return nullptr;
 }
@@ -558,8 +570,8 @@
 {
     std::vector<webrtc::SdpVideoFormat> supportedCodecs;
 
-    VP8Encoder().AddCodecIfSupported(&supportedCodecs);
-    H264Encoder().AddCodecIfSupported(&supportedCodecs);
+    supportedCodecs.push_back(webrtc::SdpVideoFormat(cricket::kVp8CodecName));
+    GStreamerH264Encoder().AddCodecIfSupported(&supportedCodecs);
 
     return supportedCodecs;
 }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to