[WebRTC][GStreamer] Build and use the openh264 based encoder if present on the system
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 31 Mar 2021 11:11:17 +0000 (11:11 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 31 Mar 2021 11:11:17 +0000 (11:11 +0000)
https://bugs.webkit.org/show_bug.cgi?id=202538

Patch by Thibault Saunier  <tsaunier@igalia.com> and Philippe Normand <pnormand@igalia.com> on 2021-03-31
Reviewed by Xabier Rodriguez-Calvar and Adrian Perez de Castro.

Source/ThirdParty/libwebrtc:

In WPE/GTK we would like to have the libwebrtc openh264 encoder enabled if libopenh264 is
present on the host (eg not vendored).

* CMakeLists.txt:
* Source/webrtc/modules/video_coding/codecs/h264/h264.cc:
* Source/webrtc/modules/video_coding/codecs/h264/h264_encoder_impl.cc:
* Source/webrtc/modules/video_coding/codecs/h264/h264_encoder_impl.h:

Source/WebCore:

Enable the openh264 encoder if it is available, it would be preferred over existing
GStreamer H.264 encoders in such case.

* platform/mediastream/libwebrtc/GStreamerVideoEncoderFactory.cpp:
(WebCore::GStreamerVideoEncoder::AddCodecIfSupported):
(WebCore::GStreamerVideoEncoderFactory::CreateVideoEncoder):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@275275 268f45cc-cd09-0410-ab3c-d52691b4dbfc

14 files changed:
Source/CMakeLists.txt
Source/ThirdParty/libwebrtc/CMakeLists.txt
Source/ThirdParty/libwebrtc/ChangeLog
Source/ThirdParty/libwebrtc/LibWebRTCWebKitMacros.h.in [new file with mode: 0644]
Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/codecs/h264/h264.cc
Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/codecs/h264/h264_encoder_impl.cc
Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/codecs/h264/h264_encoder_impl.h
Source/ThirdParty/libwebrtc/cmake/FindOpenh264.cmake [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/platform/mediastream/libwebrtc/GStreamerVideoCommon.cpp
Source/WebCore/platform/mediastream/libwebrtc/GStreamerVideoCommon.h
Source/WebCore/platform/mediastream/libwebrtc/GStreamerVideoDecoderFactory.cpp
Source/WebCore/platform/mediastream/libwebrtc/GStreamerVideoEncoderFactory.cpp
Source/cmake/GStreamerChecks.cmake

index 8d96ce262ef39f03a3fd0f59b66c63c5366b2cf5..3676b0b98f3d25149b5cf68cfe62cac85d46e194 100644 (file)
@@ -27,6 +27,7 @@ endif ()
 
 if (USE_LIBWEBRTC)
     add_subdirectory(ThirdParty/libwebrtc)
+    include_directories(${CMAKE_CURRENT_BINARY_DIR}/ThirdParty/libwebrtc)
 endif ()
 
 if (ENABLE_WEBINSPECTORUI)
index cc007616a999989c8e1c4134bd3888678c0abf03..c0635b461303828cc32df00c37d7a02f97a47802 100644 (file)
@@ -1417,6 +1417,19 @@ if (WTF_CPU_X86_64 OR WTF_CPU_X86)
     )
 endif()
 
+
+find_package(Openh264)
+if (NOT Openh264_FOUND)
+    message(WARNING "openh264 is not found, not building support.")
+    set(WEBKIT_LIBWEBRTC_OPENH264_ENCODER 0)
+else()
+    list(APPEND webrtc_SOURCES
+        Source/webrtc/modules/video_coding/codecs/h264/h264_encoder_impl.cc
+    )
+    set(WEBKIT_LIBWEBRTC_OPENH264_ENCODER 1)
+endif ()
+configure_file(LibWebRTCWebKitMacros.h.in LibWebRTCWebKitMacros.h @ONLY)
+
 add_library(webrtc STATIC ${webrtc_SOURCES})
 
 target_compile_options(webrtc PRIVATE
@@ -1463,6 +1476,7 @@ target_compile_definitions(webrtc PRIVATE
   WEBRTC_OPUS_SUPPORT_120MS_PTIME=0
   WEBRTC_OPUS_VARIABLE_COMPLEXITY=0
   WEBRTC_USE_BUILTIN_OPUS=1
+  WEBRTC_USE_H264=1
   WEBRTC_POSIX
   WEBRTC_USE_BUILTIN_ISAC_FIX=1
   WEBRTC_USE_BUILTIN_ISAC_FLOAT=0
@@ -1516,6 +1530,8 @@ target_link_libraries(webrtc ${LIBEVENT_LIBRARY})
 
 target_link_libraries(webrtc ${LIBOPUS_LIBRARY})
 
+target_link_libraries(webrtc ${Openh264_LIBRARY})
+
 # libsrtp package compilation
 set(libsrtp_SOURCES
     Source/third_party/libsrtp/crypto/cipher/aes_gcm_ossl.c
index 24e6e7cbc32a125bc2e6b4b7cd443098e9c57f33..20c9eb19010506f97dbc7ae7eb4975569efd6e7a 100644 (file)
@@ -1,3 +1,18 @@
+2021-03-31  Thibault Saunier  <tsaunier@igalia.com> and Philippe Normand  <pnormand@igalia.com>
+
+        [WebRTC][GStreamer] Build and use the openh264 based encoder if present on the system
+        https://bugs.webkit.org/show_bug.cgi?id=202538
+
+        Reviewed by Xabier Rodriguez-Calvar and Adrian Perez de Castro.
+
+        In WPE/GTK we would like to have the libwebrtc openh264 encoder enabled if libopenh264 is
+        present on the host (eg not vendored).
+
+        * CMakeLists.txt:
+        * Source/webrtc/modules/video_coding/codecs/h264/h264.cc:
+        * Source/webrtc/modules/video_coding/codecs/h264/h264_encoder_impl.cc:
+        * Source/webrtc/modules/video_coding/codecs/h264/h264_encoder_impl.h:
+
 2021-03-26  Jessie Berlin  <jberlin@webkit.org>
 
         Update the BEFORE/SINCE, SYSTEM_VERSION_PREFIX, and MACOSX_DEPLOYMENT_TARGET flags
diff --git a/Source/ThirdParty/libwebrtc/LibWebRTCWebKitMacros.h.in b/Source/ThirdParty/libwebrtc/LibWebRTCWebKitMacros.h.in
new file mode 100644 (file)
index 0000000..8d7732a
--- /dev/null
@@ -0,0 +1 @@
+#cmakedefine01 WEBKIT_LIBWEBRTC_OPENH264_ENCODER
index be5b031e88b84d092aad87639cc4c9415176944b..a0660fbfe673dee9c38e1cd880f0b8d6ee9a1d42 100644 (file)
@@ -19,7 +19,9 @@
 #include "media/base/media_constants.h"
 
 #if defined(WEBRTC_USE_H264)
+#if !defined(WEBRTC_WEBKIT_BUILD)
 #include "modules/video_coding/codecs/h264/h264_decoder_impl.h"
+#endif
 #include "modules/video_coding/codecs/h264/h264_encoder_impl.h"
 #endif
 
@@ -103,7 +105,7 @@ bool H264Encoder::IsSupported() {
 
 std::unique_ptr<H264Decoder> H264Decoder::Create() {
   RTC_DCHECK(H264Decoder::IsSupported());
-#if defined(WEBRTC_USE_H264)
+#if defined(WEBRTC_USE_H264) && !defined(WEBRTC_WEBKIT_BUILD)
   RTC_CHECK(g_rtc_use_h264);
   RTC_LOG(LS_INFO) << "Creating H264DecoderImpl.";
   return std::make_unique<H264DecoderImpl>();
index b869abeb36ffcb4167185118186296dc4c93e7e3..4795efe19ec373114bb2c21f447d0b2db0a3450d 100644 (file)
 #include "system_wrappers/include/metrics.h"
 #include "third_party/libyuv/include/libyuv/convert.h"
 #include "third_party/libyuv/include/libyuv/scale.h"
+
+#ifdef WEBRTC_WEBKIT_BUILD
+#include "wels/codec_api.h"
+#include "wels/codec_app_def.h"
+#include "wels/codec_def.h"
+#include "wels/codec_ver.h"
+#else
 #include "third_party/openh264/src/codec/api/svc/codec_api.h"
 #include "third_party/openh264/src/codec/api/svc/codec_app_def.h"
 #include "third_party/openh264/src/codec/api/svc/codec_def.h"
 #include "third_party/openh264/src/codec/api/svc/codec_ver.h"
+#endif
 
 namespace webrtc {
 
index 2a78b143115ce9486006eb573e1f9df56355aa8b..32decc6d19c2a25cb08a84aad3b0f65aaddda2ac 100644 (file)
 #include "common_video/h264/h264_bitstream_parser.h"
 #include "modules/video_coding/codecs/h264/include/h264.h"
 #include "modules/video_coding/utility/quality_scaler.h"
+
+#ifdef WEBRTC_WEBKIT_BUILD
+#include "wels/codec_app_def.h"
+#else
 #include "third_party/openh264/src/codec/api/svc/codec_app_def.h"
+#endif
 
 class ISVCEncoder;
 
diff --git a/Source/ThirdParty/libwebrtc/cmake/FindOpenh264.cmake b/Source/ThirdParty/libwebrtc/cmake/FindOpenh264.cmake
new file mode 100644 (file)
index 0000000..7b55433
--- /dev/null
@@ -0,0 +1,105 @@
+# Copyright (C) 2020 Sony Interactive Entertainment Inc.
+# Copyright (C) 2021 Igalia S.L.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+#[=======================================================================[.rst:
+FindOpenh264
+--------------
+
+Find Openh264 headers and libraries.
+
+Imported Targets
+^^^^^^^^^^^^^^^^
+
+``Openh264::libopenh264``
+  The libopenh264 library, if found.
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This will define the following variables in your project:
+
+``Openh264_FOUND``
+  true if (the requested version of) Openh264 is available.
+``Openh264_VERSION``
+  the version of Openh264.
+``Openh264_LIBRARIES``
+  the libraries to link against to use Openh264.
+``Openh264_INCLUDE_DIRS``
+  where to find the Openh264 headers.
+
+#]=======================================================================]
+
+find_package(PkgConfig QUIET)
+pkg_check_modules(PC_Openh264 QUIET openh264)
+set(Openh264_VERSION ${PC_Openh264_VERSION})
+
+find_path(Openh264_INCLUDE_DIR
+    NAMES wels/codec_api.h
+    HINTS ${PC_Openh264_INCLUDEDIR} ${PC_Openh264_INCLUDE_DIRS}
+)
+
+find_library(Openh264_LIBRARY
+    NAMES ${Openh264_NAMES} openh264
+    HINTS ${PC_Openh264_LIBDIR} ${PC_Openh264_LIBRARY_DIRS}
+)
+
+if (Openh264_INCLUDE_DIR AND NOT Openh264_VERSION)
+    if (EXISTS "${Openh264_INCLUDE_DIR}/wels/codec_ver.h")
+        file(READ "${Openh264_INCLUDE_DIR}/wels/codec_ver.h" Openh264_VERSION_CONTENT)
+
+        string(REGEX MATCH "#[ \t]*define[ \t]+OPENH264_MAJOR[ \t]+\\(([0-9]+)\\)" _dummy "${Openh264_VERSION_CONTENT}")
+        set(Openh264_VERSION_MAJOR "${CMAKE_MATCH_1}")
+
+        string(REGEX MATCH "#[ \t]*define[ \t]+OPENH264_MINOR[ \t]+\\(([0-9]+)\\)" _dummy "${Openh264_VERSION_CONTENT}")
+        set(Openh264_VERSION_MINOR "${CMAKE_MATCH_1}")
+
+        string(REGEX MATCH "#[ \t]*define[ \t]+OPENH264_REVISION[ \t]+\\(([0-9]+)\\)" _dummy "${Openh264_VERSION_CONTENT}")
+        set(Openh264_VERSION_REVISION "${CMAKE_MATCH_1}")
+
+        set(Openh264_VERSION "${Openh264_VERSION_MAJOR}.${Openh264_VERSION_MINOR}.${Openh264_VERSION_REVISION}")
+    endif ()
+endif ()
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Openh264
+    FOUND_VAR Openh264_FOUND
+    REQUIRED_VARS Openh264_LIBRARY Openh264_INCLUDE_DIR
+    VERSION_VAR Openh264_VERSION
+)
+
+if (Openh264_LIBRARY AND NOT TARGET Openh264::libopenh264)
+    add_library(Openh264::libopenh264 UNKNOWN IMPORTED GLOBAL)
+    set_target_properties(Openh264::libopenh264 PROPERTIES
+        IMPORTED_LOCATION "${Openh264_LIBRARY}"
+        INTERFACE_COMPILE_OPTIONS "${Openh264_COMPILE_OPTIONS}"
+        INTERFACE_INCLUDE_DIRECTORIES "${Openh264_INCLUDE_DIR}"
+    )
+endif ()
+
+mark_as_advanced(Openh264_INCLUDE_DIR Openh264_LIBRARY)
+
+if (Openh264_FOUND)
+    set(Openh264_LIBRARIES ${Openh264_LIBRARY})
+    set(Openh264_INCLUDE_DIRS ${Openh264_INCLUDE_DIR})
+endif ()
index 61d7dedee66b49600bfbdd70a542dc0ec940daf0..b78045faf47cc8a89ab06bc323ab4fd9650e8f30 100644 (file)
@@ -1,3 +1,17 @@
+2021-03-31  Thibault Saunier  <tsaunier@igalia.com> and Philippe Normand  <pnormand@igalia.com>
+
+        [WebRTC][GStreamer] Build and use the openh264 based encoder if present on the system
+        https://bugs.webkit.org/show_bug.cgi?id=202538
+
+        Reviewed by Xabier Rodriguez-Calvar and Adrian Perez de Castro.
+
+        Enable the openh264 encoder if it is available, it would be preferred over existing
+        GStreamer H.264 encoders in such case.
+
+        * platform/mediastream/libwebrtc/GStreamerVideoEncoderFactory.cpp:
+        (WebCore::GStreamerVideoEncoder::AddCodecIfSupported):
+        (WebCore::GStreamerVideoEncoderFactory::CreateVideoEncoder):
+
 2021-03-30  Antoine Quint  <graouts@webkit.org>
 
         Computed style for a border-radius corner should never be 0px when the provided width isn't 0px
index bcd943a1518244f80865db23c6b3078b75776002..5463dbb56173eb74bfe54a8969bd4fff9834417b 100644 (file)
@@ -39,7 +39,7 @@ static webrtc::SdpVideoFormat createH264Format(webrtc::H264::Profile profile, we
             { cricket::kH264FmtpPacketizationMode, packetizationMode } });
 }
 
-std::vector<webrtc::SdpVideoFormat> gstreamerSupportedH264Codecs()
+std::vector<webrtc::SdpVideoFormat> supportedH264Formats()
 {
     // @TODO Create from encoder src pad caps template
     //
index 6e5a071ccb834a82e0a15f59e0743e81a760ddba..b65f17b80a2d4b924bb2b84a2d4141a92c1666f8 100644 (file)
@@ -28,7 +28,7 @@
 
 namespace WebCore {
 
-std::vector<webrtc::SdpVideoFormat> gstreamerSupportedH264Codecs();
+std::vector<webrtc::SdpVideoFormat> supportedH264Formats();
 
 } // namespace WebCore
 
index 908be50513ce1587d6dfe5c53ca658a0aa140f9a..39c7b5dd342fa0d3b9d8efe427f18ddac8b1a7d6 100644 (file)
@@ -362,7 +362,7 @@ public:
 
     std::vector<webrtc::SdpVideoFormat> ConfigureSupportedDecoder() final
     {
-        return gstreamerSupportedH264Codecs();
+        return supportedH264Formats();
     }
 };
 
index 66224ed1dd38170f7726deeb435a854c2f0e807f..d679dc179c22840c4f61aae0132ced72886ae4b6 100644 (file)
@@ -26,6 +26,7 @@
 #include "GStreamerVideoCommon.h"
 #include "GStreamerVideoEncoder.h"
 #include "GStreamerVideoFrameLibWebRTC.h"
+#include "LibWebRTCWebKitMacros.h"
 #include "webrtc/common_video/h264/h264_common.h"
 #include "webrtc/modules/video_coding/codecs/h264/include/h264.h"
 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h"
@@ -374,7 +375,7 @@ public:
 
     std::vector<webrtc::SdpVideoFormat> ConfigureSupportedCodec() final
     {
-        return gstreamerSupportedH264Codecs();
+        return supportedH264Formats();
     }
 
     const gchar* Caps() final { return "video/x-h264"; }
@@ -432,8 +433,15 @@ std::unique_ptr<webrtc::VideoEncoder> GStreamerVideoEncoderFactory::CreateVideoE
         return makeUniqueWithoutFastMallocCheck<webrtc::LibvpxVp8Encoder>(webrtc::LibvpxInterface::CreateEncoder(), webrtc::VP8Encoder::Settings());
     }
 
-    if (format.name == cricket::kH264CodecName)
+    if (format.name == cricket::kH264CodecName) {
+#if WEBKIT_LIBWEBRTC_OPENH264_ENCODER
+        GST_INFO("Using OpenH264 libwebrtc encoder.");
+        return webrtc::H264Encoder::Create(cricket::VideoCodec(format));
+#else
+        GST_INFO("Using H264 GStreamer encoder.");
         return makeUnique<GStreamerH264Encoder>(format);
+#endif
+    }
 
     return nullptr;
 }
@@ -456,7 +464,14 @@ std::vector<webrtc::SdpVideoFormat> GStreamerVideoEncoderFactory::GetSupportedFo
     std::vector<webrtc::SdpVideoFormat> supportedCodecs;
 
     supportedCodecs.push_back(webrtc::SdpVideoFormat(cricket::kVp8CodecName));
+
+    // If OpenH264 is present, prefer it over the GStreamer encoders (x264enc, usually).
+#if WEBKIT_LIBWEBRTC_OPENH264_ENCODER
+    auto formats = supportedH264Formats();
+    supportedCodecs.insert(supportedCodecs.end(), formats.begin(), formats.end());
+#else
     GStreamerH264Encoder().AddCodecIfSupported(supportedCodecs);
+#endif
 
     return supportedCodecs;
 }
index a61b8a88676cb22300dc4a632490681465cdc60d..77e95845e9913a5978dad10cfc430093b43c7aa3 100644 (file)
@@ -54,8 +54,6 @@ endif ()
 
 if (ENABLE_MEDIA_STREAM AND ENABLE_WEB_RTC)
     SET_AND_EXPOSE_TO_BUILD(USE_LIBWEBRTC TRUE)
-    SET_AND_EXPOSE_TO_BUILD(WEBRTC_WEBKIT_BUILD TRUE)
 else ()
     SET_AND_EXPOSE_TO_BUILD(USE_LIBWEBRTC FALSE)
-    SET_AND_EXPOSE_TO_BUILD(WEBRTC_WEBKIT_BUILD FALSE)
 endif ()