summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/moz-patch-stack/0001.patch
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/libwebrtc/moz-patch-stack/0001.patch')
-rw-r--r--third_party/libwebrtc/moz-patch-stack/0001.patch1693
1 files changed, 1693 insertions, 0 deletions
diff --git a/third_party/libwebrtc/moz-patch-stack/0001.patch b/third_party/libwebrtc/moz-patch-stack/0001.patch
new file mode 100644
index 0000000000..31a12dd98b
--- /dev/null
+++ b/third_party/libwebrtc/moz-patch-stack/0001.patch
@@ -0,0 +1,1693 @@
+From: Dan Minor <dminor@mozilla.com>
+Date: Mon, 22 Jan 2018 13:31:00 -0500
+Subject: Bug 1376873 - Rollup of local modifications; r=ng
+
+MozReview-Commit-ID: 2euYzBEvuNb
+
+Differential Revision: https://phabricator.services.mozilla.com/D7425
+Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/28b57e3ba51de982a4663801a3935580114b5477
+
+Bug 1376873 - Rollup conflict fixes for audio/video code; r=pehrsons
+
+MozReview-Commit-ID: 1T8mgqdkzq3
+
+Differential Revision: https://phabricator.services.mozilla.com/D7427
+Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/93eec571640ee0810da8475ee37e417b88045574
+
+Bug 1376873 - Rollup conflict fixes for rtp_rtcp module; r=ng
+
+MozReview-Commit-ID: D09534DOVLj
+
+Differential Revision: https://phabricator.services.mozilla.com/D7428
+Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/50f89f4e45b0af87fd6aa45aed60f02f3e69b951
+
+Bug 1497552 - Remove support for 44100 Hz in dtmf_tone_generator; r=padenot
+
+Assertions in NetEqImpl::SetSampleRateAndChannels prevent us from requesting
+tones at 44100 Hz, so this code can be safely removed.
+
+Differential Revision: https://phabricator.services.mozilla.com/D12982
+Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/8ea04ec01e9905d4714aa01ade891d552c56a3a6
+
+Bug 1497577 - Remove code to detect zero size windows; r=ng
+
+This code was added by Bug 1196542 to fix a permanently failing test on our
+Windows test machines. After this landed, upstream added a check for empty
+windows in window_captuer_win.cc, so this should no longer be a problem on
+Windows. As far as I know, this was never a problem on the other platforms,
+so this code can be safely removed.
+
+Differential Revision: https://phabricator.services.mozilla.com/D13448
+Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/647ade4da0fba74a268aab079677cb47f20f036e
+
+Bug 1509994 - Move video_engine from webrtc to systemservices; r=pehrsons
+
+Historically this code was part of webrtc.org but has since been removed
+from upstream. Rather than maintaining it as a local diff against upstream,
+we should just move it to where it is used.
+
+Differential Revision: https://phabricator.services.mozilla.com/D13092
+Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/0fd399c6caabff60ac0fe53b920b7d26a9806750
+
+Bug 1497606 - Remove disable_composition_ in screen_capturer_win_gdi; r=ng
+
+This removes disable_composition_ and instead uses the value of
+composition_func_ to determine whether or not composition is
+disabled. This is what is done by upstream webrtc.org.
+
+We call options.set_disable_effects(false) in desktop_capture_impl.cc.
+
+Differential Revision: https://phabricator.services.mozilla.com/D13839
+Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/b3f5cca4be44c01024b1ef7b5d4951c7297a112a
+
+Bug 1497974 - Remove local changes to jitter_buffer.cc; r=pehrsons
+
+These modifications are made to code which we do not use and so
+can be removed.
+
+Differential Revision: https://phabricator.services.mozilla.com/D13989
+Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/2fb1dd0d8344ef24e2e0fca94725bbfaf59aa257
+
+Bug 1512459 - Remove webrtc sndio audio device; r=padenot
+
+This code is unused and can be removed.
+
+Differential Revision: https://phabricator.services.mozilla.com/D13929
+Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/fa0a179388e96b1a47eeef2fda9676812c244d3b
+
+Bug 1497650 - Remove 100 bytes added to CalcBufferSize in vp8_impl.cc; r=ng
+
+In Bug 919979 we added 100 bytes to the size returned by CalcBufferSize
+to work around an error with the calculated buffer size with small
+resolutions. I verified that this extra buffer is no longer required with
+a modified mochitest. Given the age of the bug this was working around,
+I don't think a permanent test is required to prevent regressions from
+upstream.
+
+Differential Revision: https://phabricator.services.mozilla.com/D14076
+Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/b20329b1ec0565b3b94db73e13a9c49e43c418c3
+
+Bug 1368816 - Enable VideoCaptureExternalTest Rotation gtest; r=ng
+
+This test started failing after the 57 update and started passing
+again after the 64 update, so we might as well enable it.
+
+Differential Revision: https://phabricator.services.mozilla.com/D13803
+Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/65a44b43b7b69c066abcb864076003252abc475e
+
+Bug 1497573 - Remove DesktopCapturer::Stop; r=ng
+
+Differential Revision: https://phabricator.services.mozilla.com/D14066
+Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/0d9c607f26195b7f63cca847224bcd137f73720d
+
+Bug 1497619 - Restore thread check in process_thread_impl.cc; r=ng
+
+Not not really needed.
+
+Differential Revision: https://phabricator.services.mozilla.com/D14097
+Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/923373fdf5e50d44c895141dc1db74709d6610fe
+
+Bug 1497992 - Remove VideoReceiver::Reset; r=pehrsons
+
+This ends up calling VCMReceiver::Reset() which resets the
+state of the VCMJitterBuffer. We no longer use VCMJitterBuffer,
+which is the old jitter buffer implementation, so this code
+no longer has any effect and can be removed.
+
+Differential Revision: https://phabricator.services.mozilla.com/D14185
+Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/9e526b3093ee60791cf9c436ea06b6665eb5ef74
+
+Bug 1497610 - Remove IsNewerOrSameTimestamp; r=bwc
+
+The affected functions are only used by VCMJitterBuffer, which is the older
+jitter buffer that is no longer in use. We can safely remove these
+modifications.
+
+Differential Revision: https://phabricator.services.mozilla.com/D14485
+Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/5ed0ed11b23d82ee026244a9a48e522fe38335e2
+
+Bug 1498253 - Remove mozAvSyncDelay and mozJitterBufferDelay; r=ng
+
+The value for mozAvSyncDelay has been broken since the branch 57 update
+(Bug 1341285). We added SetCurrentSyncOffset() but never called it from
+anywhere.
+
+In the future we should be getting stats from AudioReceiveStream rather than
+modifying the channel code, the delay_estimate_ms field provides almost the
+same information.
+
+Since we're attempting to get rid of moz prefixed stats, it makes sense to just
+remove this code rather than fix it. The associated telemetry code has been
+broken since Bug 1341285 as well so I think it is safe to remove.
+
+Differential Revision: https://phabricator.services.mozilla.com/D14462
+Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/80e86c169d202e724cda74bbd9535b2d5236305b
+
+Bug 1498205 - Move PlatformUIThread from rtc_base to video_engine; r=pehrsons
+
+PlatformUIThread is only used by the video_engine code, so it makes sense to
+move it there rather than maintain it as a diff against upstream webrtc.org.
+
+Differential Revision: https://phabricator.services.mozilla.com/D13531
+Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/65bf3e37a4409f3ca0350366d7be19368adfa21b
+
+Bug 1497602 - Enable DirectX screen capturer on Windows; r=pehrsons
+
+This enables support for the DirectX screen capturer. We use the default
+DesktopCaptureOptions which do not set the option to use the DirectX screen
+capturer so this change will have no effect with the current code.
+
+For what it's worth, I tested enabling the DirectX option and it worked fine on my
+system, but I don't see any reason to not follow the defaults provided by
+webrtc.org in this case.
+
+Differential Revision: https://phabricator.services.mozilla.com/D13303
+Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/eb07312cfbe868780ebed84fc83e5a5470e81fb4
+
+Bug 1439997 - Remove old mac video capture code; r=jib
+
+This code is no longer used and has been removed upstream. We can remove
+it as well.
+
+Differential Revision: https://phabricator.services.mozilla.com/D15196
+Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/e79251fa381cfc9f3425f6a746ac8d8c22046d6b
+
+Bug 1376873 - Updates to Android video capture; r=pehrsons
+
+Differential Revision: https://phabricator.services.mozilla.com/D7452
+Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/1e6d72de0587d24c20fefc142591d8b47c363f89
+
+Bug 1578073 - Move android video capture code to dom/media/systemservices; r=jib
+
+Although originally part of webrtc.org, this code has subsequently been
+removed by upstream. Moving it to under dom/media should make it clearer that
+this is code that we are maintaining and simplify future upstream merges.
+
+Differential Revision: https://phabricator.services.mozilla.com/D61850
+Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/46c21affcbc14da30abb03b10573076aee6341c0
+
+Bug 1652552 - Remove remaining application capture code; r=jib
+
+Differential Revision: https://phabricator.services.mozilla.com/D83491
+Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/26eee332d844bd3f9479d1db92d2f000255664c1
+
+Bug 1846358 - revert mozilla-specific b2g related change in generic_decoder.cc kDecoderFrameMemoryLength. r=ng,webrtc-reviewers
+
+Differential Revision: https://phabricator.services.mozilla.com/D184983
+Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/478632b0cc4982639276a4a817165ac49ca8fb6e
+
+Bug 1846875 - remove redundant divide by zero protection in libwebrtc's merge.cc r=ng,webrtc-reviewers
+
+Differential Revision: https://phabricator.services.mozilla.com/D185236
+Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/a777f43c4d9cabe80f2fc3aea6bf95c7e3e9c4c1
+
+Bug 1846590 - move SetCaptureAndroidVM declaration from libwebrtc video_capture.h to our VideoEngine.cpp r=ng,webrtc-reviewers
+
+Differential Revision: https://phabricator.services.mozilla.com/D185076
+Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/0b9ef0f6bf04851bcc8bbe9beb88362eb1659a50
+
+Bug 1847466 - remove work-around for missing v4l2_capability::bus_info in v412loopback driver. r=jesup,pehrsons,webrtc-reviewers
+
+Added in Bug 861280, but should no longer be necessary after fixes in upstream
+v4l2loopback commits (fc4c173, fe03e4f, c3b1eaa).
+https://github.com/umlaeute/v4l2loopback/commit/fc4c173
+https://github.com/umlaeute/v4l2loopback/commit/fe03e4f
+https://github.com/umlaeute/v4l2loopback/commit/c3b1eaa
+
+Differential Revision: https://phabricator.services.mozilla.com/D185518
+Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/d054dde5c370feb3ee9c9f9159b512333b3554ac
+
+Bug 1846636 - restore ScreenCapturerWinMagnifier destructor to upstream version. r=ng,webrtc-reviewers
+
+Differential Revision: https://phabricator.services.mozilla.com/D185109
+Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/b50be8861ca0a4f9e6777e9333a9e483bdb57bf9
+
+Bug 1376873 - Fix up logging in WebrtcLog.cpp; r=ng
+
+The webrtc::Trace code is removed by this update. We already had support for
+LOG (now RTC_LOG) in WebrtcLog.cpp. This removes the trace code from
+WebRtcLog.cpp and moves the aec logging code from webrtc::Trace to
+rtc::LogMessage.
+
+This also disables logging to stderr in rtc_base/logging.cc. We could disable
+it using the API, but that happens through peerconnection resulting in some
+logging occuring during getusermedia.
+
+The aec logs were testing with --disable-e10s. Rather than trying to
+work around sandboxing, I think it makes more sense to fix Bug 1404982 and
+store the logs in memory for retrieval from about:webrtc.
+
+Differential Revision: https://phabricator.services.mozilla.com/D7429
+Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/e84c60e2c9373f4d2dc24e769375a92c17c2a0ad
+
+Bug 1847818 - restore aec logging from about:webrtc. r=ng,webrtc-reviewers
+
+Differential Revision: https://phabricator.services.mozilla.com/D185709
+Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/a67a9e51d8b8597caa1511e2f3b7795e92b07068
+
+Bug 1535584 - Restore UpdateCodecFrameSize to vp9_impl.cc; r=bwc
+
+Differential Revision: https://phabricator.services.mozilla.com/D23713
+Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/0898f9cfe09273e1d86c38abdd576cdf273009f0
+
+Bug 1846850 - remove mozilla-added IsGUIThread asserts from libwebrtc. r=ng,webrtc-reviewers
+
+These were added in Bug 1060738 but no longer seem to add value based
+on crash stats.
+
+Differential Revision: https://phabricator.services.mozilla.com/D185222
+Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/5e6f94c1b7c4491bdab454e24dfdb93eb75f80ca
+
+Bug 1846858 - revert changes to libwebrtc's deprecated/session_info.cc since we don't build it. r=ng,webrtc-reviewers
+
+Differential Revision: https://phabricator.services.mozilla.com/D185224
+Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/4836114af07e38525d319b0a2f59f2fd618b7a3b
+
+Bug 1847257 - revert an unneccesary change in libwebrtc's window_capturer_x11.cc r=karlt,webrtc-reviewers
+
+This small change we've been carrying to when ProcessPendingXEvents is called
+in WindowCapturerLinux::Capture should not be necessary.
+
+Differential Revision: https://phabricator.services.mozilla.com/D185449
+Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/9633cb1dde33ecbab435012c4ae1456a4ae79a42
+
+Bug 1847984 - remove mozilla-specific null FILE* checks in apm_data_dumper.h r=ng,webrtc-reviewers
+
+Since upstream commit 4bc60452f7 ApmDataDumper::GetRawFile does a release
+assert if FILE* is null so our mozilla-specific mods to check for valid
+FILE pointers are no longer needed.
+
+Differential Revision: https://phabricator.services.mozilla.com/D185838
+Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/53ecaeda76c3613b90d3a1c3348f0d903a054821
+
+Bug 1848045 - removing mozilla output directory handling code from apm_data_dumper. r=ng,webrtc-reviewers
+
+Upstream added the capability to set the output directory in commit 4bc60452f7 so
+we can revert to using upstream's version instead of ours.
+
+Differential Revision: https://phabricator.services.mozilla.com/D185863
+Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/48217906ac982e129b5eedf07e90904396c31ed4
+
+Bug 1847833 - remove aec log output size limiting code from libwebrtc's apm_data_dumper. r=ng,webrtc-reviewers
+
+Differential Revision: https://phabricator.services.mozilla.com/D185930
+Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/7622e6dddeec583e5839b5432d436d85c356f6c3
+
+Bug 1847833 - aec_debug_size_, aec_debug_size(), set_aec_debug_size(uint32_t size) are no longer used. r=ng,webrtc-reviewers
+
+Differential Revision: https://phabricator.services.mozilla.com/D185931
+Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/525d71640bb7be400040131a5b1a16652c881a0f
+
+Bug 1850146 - remove unnecessary libwebrtc changes in jvm_android.cc. r?dbaker!
+
+After landing Bug 1826428 to remove jvm_android.cc from the build and
+giving time for that to simmer for a while with no known effects, we
+can remove our modifications.
+
+Differential Revision: https://phabricator.services.mozilla.com/D186855
+Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/fc01107426c3adebb169f19efba72a91be19f613
+---
+ api/rtp_headers.cc | 3 +-
+ api/rtp_headers.h | 17 +-
+ api/rtp_parameters.cc | 3 +-
+ call/BUILD.gn | 4 +-
+ call/video_receive_stream.h | 2 +
+ modules/audio_coding/acm2/acm_receiver.h | 12 +-
+ modules/audio_coding/neteq/dtmf_buffer.cc | 6 +-
+ modules/desktop_capture/desktop_capturer.h | 1 +
+ .../desktop_capture/fake_desktop_capturer.cc | 4 +-
+ .../linux/x11/mouse_cursor_monitor_x11.cc | 4 +-
+ .../linux/x11/screen_capturer_x11.cc | 2 +-
+ .../linux/x11/window_capturer_x11.cc | 9 +
+ .../linux/x11/window_capturer_x11.h | 4 +
+ .../desktop_capture/linux/x11/x_error_trap.cc | 68 ++++---
+ .../desktop_capture/linux/x11/x_error_trap.h | 29 ++-
+ .../win/screen_capture_utils.cc | 2 +-
+ modules/rtp_rtcp/source/rtcp_sender.cc | 2 +-
+ .../rtp_rtcp/source/rtp_header_extensions.cc | 39 ++++
+ .../rtp_rtcp/source/rtp_header_extensions.h | 15 ++
+ modules/rtp_rtcp/source/rtp_packet.cc | 4 +
+ .../rtp_rtcp/source/rtp_packet_unittest.cc | 30 +++
+ modules/rtp_rtcp/source/rtp_rtcp_config.h | 4 +
+ modules/rtp_rtcp/source/rtp_sender.cc | 4 +
+ modules/video_capture/device_info_impl.cc | 2 +-
+ modules/video_capture/device_info_impl.h | 1 +
+ .../video_capture/linux/device_info_v4l2.cc | 179 +++++++++++++++++-
+ .../video_capture/linux/device_info_v4l2.h | 18 +-
+ modules/video_capture/video_capture.h | 41 +++-
+ .../video_capture/video_capture_factory.cc | 8 -
+ modules/video_capture/video_capture_impl.cc | 34 +++-
+ modules/video_capture/video_capture_impl.h | 6 +-
+ .../codecs/vp9/libvpx_vp9_encoder.cc | 52 +++++
+ .../codecs/vp9/libvpx_vp9_encoder.h | 4 +
+ rtc_base/BUILD.gn | 6 +
+ rtc_base/logging.cc | 21 +-
+ rtc_base/logging.h | 9 +
+ test/fuzzers/rtp_packet_fuzzer.cc | 5 +
+ test/vcm_capturer.cc | 2 +-
+ webrtc.gni | 2 +-
+ 39 files changed, 573 insertions(+), 85 deletions(-)
+
+diff --git a/api/rtp_headers.cc b/api/rtp_headers.cc
+index 0573e54684..40d4690397 100644
+--- a/api/rtp_headers.cc
++++ b/api/rtp_headers.cc
+@@ -26,7 +26,8 @@ RTPHeaderExtension::RTPHeaderExtension()
+ videoRotation(kVideoRotation_0),
+ hasVideoContentType(false),
+ videoContentType(VideoContentType::UNSPECIFIED),
+- has_video_timing(false) {}
++ has_video_timing(false),
++ csrcAudioLevels() {}
+
+ RTPHeaderExtension::RTPHeaderExtension(const RTPHeaderExtension& other) =
+ default;
+diff --git a/api/rtp_headers.h b/api/rtp_headers.h
+index 5d4d4190d5..9868365f24 100644
+--- a/api/rtp_headers.h
++++ b/api/rtp_headers.h
+@@ -89,6 +89,19 @@ inline bool operator!=(const AbsoluteCaptureTime& lhs,
+ return !(lhs == rhs);
+ }
+
++enum { kRtpCsrcSize = 15 }; // RFC 3550 page 13
++
++// Audio level of CSRCs See:
++// https://tools.ietf.org/html/rfc6465
++struct CsrcAudioLevelList {
++ CsrcAudioLevelList() : numAudioLevels(0) { }
++ CsrcAudioLevelList(const CsrcAudioLevelList&) = default;
++ CsrcAudioLevelList& operator=(const CsrcAudioLevelList&) = default;
++ uint8_t numAudioLevels;
++ // arrOfAudioLevels has the same ordering as RTPHeader.arrOfCSRCs
++ uint8_t arrOfAudioLevels[kRtpCsrcSize];
++};
++
+ struct RTPHeaderExtension {
+ RTPHeaderExtension();
+ RTPHeaderExtension(const RTPHeaderExtension& other);
+@@ -144,9 +157,9 @@ struct RTPHeaderExtension {
+ std::string mid;
+
+ absl::optional<ColorSpace> color_space;
+-};
+
+-enum { kRtpCsrcSize = 15 }; // RFC 3550 page 13
++ CsrcAudioLevelList csrcAudioLevels;
++};
+
+ struct RTC_EXPORT RTPHeader {
+ RTPHeader();
+diff --git a/api/rtp_parameters.cc b/api/rtp_parameters.cc
+index 54132bcdbb..cf8b3ad3dc 100644
+--- a/api/rtp_parameters.cc
++++ b/api/rtp_parameters.cc
+@@ -151,7 +151,8 @@ bool RtpExtension::IsSupportedForAudio(absl::string_view uri) {
+ uri == webrtc::RtpExtension::kTransportSequenceNumberV2Uri ||
+ uri == webrtc::RtpExtension::kMidUri ||
+ uri == webrtc::RtpExtension::kRidUri ||
+- uri == webrtc::RtpExtension::kRepairedRidUri;
++ uri == webrtc::RtpExtension::kRepairedRidUri ||
++ uri == webrtc::RtpExtension::kCsrcAudioLevelsUri;
+ }
+
+ bool RtpExtension::IsSupportedForVideo(absl::string_view uri) {
+diff --git a/call/BUILD.gn b/call/BUILD.gn
+index 4cc42fd99f..58473dc1ea 100644
+--- a/call/BUILD.gn
++++ b/call/BUILD.gn
+@@ -20,6 +20,7 @@ rtc_library("call_interfaces") {
+ sources = [
+ "audio_receive_stream.cc",
+ "audio_receive_stream.h",
++ "audio_send_stream.cc",
+ "audio_send_stream.h",
+ "audio_state.cc",
+ "audio_state.h",
+@@ -32,9 +33,6 @@ rtc_library("call_interfaces") {
+ "syncable.cc",
+ "syncable.h",
+ ]
+- if (!build_with_mozilla) {
+- sources += [ "audio_send_stream.cc" ]
+- }
+
+ deps = [
+ ":audio_sender_interface",
+diff --git a/call/video_receive_stream.h b/call/video_receive_stream.h
+index 12f6bf60c8..542067d30c 100644
+--- a/call/video_receive_stream.h
++++ b/call/video_receive_stream.h
+@@ -206,6 +206,8 @@ class VideoReceiveStreamInterface : public MediaReceiveStreamInterface {
+ // disabled.
+ KeyFrameReqMethod keyframe_method = KeyFrameReqMethod::kPliRtcp;
+
++ bool tmmbr = false;
++
+ // See LntfConfig for description.
+ LntfConfig lntf;
+
+diff --git a/modules/audio_coding/acm2/acm_receiver.h b/modules/audio_coding/acm2/acm_receiver.h
+index 820150aede..39653be00b 100644
+--- a/modules/audio_coding/acm2/acm_receiver.h
++++ b/modules/audio_coding/acm2/acm_receiver.h
+@@ -18,6 +18,7 @@
+ #include <string>
+ #include <utility>
+ #include <vector>
++#include <atomic>
+
+ #include "absl/types/optional.h"
+ #include "api/array_view.h"
+@@ -230,12 +231,15 @@ class AcmReceiver {
+
+ mutable Mutex mutex_;
+ absl::optional<DecoderInfo> last_decoder_ RTC_GUARDED_BY(mutex_);
+- ACMResampler resampler_ RTC_GUARDED_BY(mutex_);
+- std::unique_ptr<int16_t[]> last_audio_buffer_ RTC_GUARDED_BY(mutex_);
+- CallStatistics call_stats_ RTC_GUARDED_BY(mutex_);
++ ACMResampler resampler_;
++
++ // After construction, this is only ever touched on the thread that calls
++ // AcmReceiver::GetAudio, and only modified in this method.
++ std::unique_ptr<int16_t[]> last_audio_buffer_;
++ CallStatistics call_stats_;
+ const std::unique_ptr<NetEq> neteq_; // NetEq is thread-safe; no lock needed.
+ Clock& clock_;
+- bool resampled_last_output_frame_ RTC_GUARDED_BY(mutex_);
++ std::atomic<bool> resampled_last_output_frame_;
+ };
+
+ } // namespace acm2
+diff --git a/modules/audio_coding/neteq/dtmf_buffer.cc b/modules/audio_coding/neteq/dtmf_buffer.cc
+index 9f78aca6e2..115bfcf97b 100644
+--- a/modules/audio_coding/neteq/dtmf_buffer.cc
++++ b/modules/audio_coding/neteq/dtmf_buffer.cc
+@@ -193,7 +193,11 @@ bool DtmfBuffer::Empty() const {
+ }
+
+ int DtmfBuffer::SetSampleRate(int fs_hz) {
+- if (fs_hz != 8000 && fs_hz != 16000 && fs_hz != 32000 && fs_hz != 48000) {
++ if (fs_hz != 8000 &&
++ fs_hz != 16000 &&
++ fs_hz != 32000 &&
++ fs_hz != 44100 &&
++ fs_hz != 48000) {
+ return kInvalidSampleRate;
+ }
+ max_extrapolation_samples_ = 7 * fs_hz / 100;
+diff --git a/modules/desktop_capture/desktop_capturer.h b/modules/desktop_capture/desktop_capturer.h
+index 9c7ecc78f4..2c9c419bcd 100644
+--- a/modules/desktop_capture/desktop_capturer.h
++++ b/modules/desktop_capture/desktop_capturer.h
+@@ -82,6 +82,7 @@ class RTC_EXPORT DesktopCapturer {
+ struct Source {
+ // The unique id to represent a Source of current DesktopCapturer.
+ SourceId id;
++ pid_t pid;
+
+ // Title of the window or screen in UTF-8 encoding, maybe empty. This field
+ // should not be used to identify a source.
+diff --git a/modules/desktop_capture/fake_desktop_capturer.cc b/modules/desktop_capture/fake_desktop_capturer.cc
+index f9d9dbd2c4..67149bfcb9 100644
+--- a/modules/desktop_capture/fake_desktop_capturer.cc
++++ b/modules/desktop_capture/fake_desktop_capturer.cc
+@@ -72,8 +72,8 @@ void FakeDesktopCapturer::SetSharedMemoryFactory(
+ }
+
+ bool FakeDesktopCapturer::GetSourceList(DesktopCapturer::SourceList* sources) {
+- sources->push_back({kWindowId, "A-Fake-DesktopCapturer-Window"});
+- sources->push_back({kScreenId});
++ sources->push_back({kWindowId, 1, "A-Fake-DesktopCapturer-Window"});
++ sources->push_back({kScreenId, 1});
+ return true;
+ }
+
+diff --git a/modules/desktop_capture/linux/x11/mouse_cursor_monitor_x11.cc b/modules/desktop_capture/linux/x11/mouse_cursor_monitor_x11.cc
+index d9c7635c1d..d4b85af6bd 100644
+--- a/modules/desktop_capture/linux/x11/mouse_cursor_monitor_x11.cc
++++ b/modules/desktop_capture/linux/x11/mouse_cursor_monitor_x11.cc
+@@ -38,6 +38,7 @@ namespace {
+ // searches up the list of the windows to find the root child that corresponds
+ // to `window`.
+ Window GetTopLevelWindow(Display* display, Window window) {
++ webrtc::XErrorTrap error_trap(display);
+ while (true) {
+ // If the window is in WithdrawnState then look at all of its children.
+ ::Window root, parent;
+@@ -104,7 +105,7 @@ MouseCursorMonitorX11::~MouseCursorMonitorX11() {
+ }
+
+ void MouseCursorMonitorX11::Init(Callback* callback, Mode mode) {
+- // Init can be called only once per instance of MouseCursorMonitor.
++ // Init can be called only if not started
+ RTC_DCHECK(!callback_);
+ RTC_DCHECK(callback);
+
+@@ -116,6 +117,7 @@ void MouseCursorMonitorX11::Init(Callback* callback, Mode mode) {
+
+ if (have_xfixes_) {
+ // Register for changes to the cursor shape.
++ XErrorTrap error_trap(display());
+ XFixesSelectCursorInput(display(), window_, XFixesDisplayCursorNotifyMask);
+ x_display_->AddEventHandler(xfixes_event_base_ + XFixesCursorNotify, this);
+
+diff --git a/modules/desktop_capture/linux/x11/screen_capturer_x11.cc b/modules/desktop_capture/linux/x11/screen_capturer_x11.cc
+index d5dcd7af86..fa6334e8ba 100644
+--- a/modules/desktop_capture/linux/x11/screen_capturer_x11.cc
++++ b/modules/desktop_capture/linux/x11/screen_capturer_x11.cc
+@@ -302,7 +302,7 @@ bool ScreenCapturerX11::GetSourceList(SourceList* sources) {
+ char* monitor_title = XGetAtomName(display(), m.name);
+
+ // Note name is an X11 Atom used to id the monitor.
+- sources->push_back({static_cast<SourceId>(m.name), monitor_title});
++ sources->push_back({static_cast<SourceId>(m.name), 0, monitor_title});
+ XFree(monitor_title);
+ }
+
+diff --git a/modules/desktop_capture/linux/x11/window_capturer_x11.cc b/modules/desktop_capture/linux/x11/window_capturer_x11.cc
+index b55f7e8fa9..2b1392ced0 100644
+--- a/modules/desktop_capture/linux/x11/window_capturer_x11.cc
++++ b/modules/desktop_capture/linux/x11/window_capturer_x11.cc
+@@ -57,6 +57,7 @@ bool WindowCapturerX11::GetSourceList(SourceList* sources) {
+ return GetWindowList(&atom_cache_, [this, sources](::Window window) {
+ Source w;
+ w.id = window;
++ w.pid = (pid_t)GetWindowProcessID(window);
+ if (this->GetWindowTitle(window, &w.title)) {
+ sources->push_back(w);
+ }
+@@ -237,6 +238,14 @@ bool WindowCapturerX11::GetWindowTitle(::Window window, std::string* title) {
+ return result;
+ }
+
++int WindowCapturerX11::GetWindowProcessID(::Window window) {
++ // Get _NET_WM_PID property of the window.
++ Atom process_atom = XInternAtom(display(), "_NET_WM_PID", True);
++ XWindowProperty<uint32_t> process_id(display(), window, process_atom);
++
++ return process_id.is_valid() ? *process_id.data() : 0;
++}
++
+ // static
+ std::unique_ptr<DesktopCapturer> WindowCapturerX11::CreateRawWindowCapturer(
+ const DesktopCaptureOptions& options) {
+diff --git a/modules/desktop_capture/linux/x11/window_capturer_x11.h b/modules/desktop_capture/linux/x11/window_capturer_x11.h
+index ac591c272e..cfd29eca66 100644
+--- a/modules/desktop_capture/linux/x11/window_capturer_x11.h
++++ b/modules/desktop_capture/linux/x11/window_capturer_x11.h
+@@ -22,6 +22,7 @@
+ #include "modules/desktop_capture/desktop_capturer.h"
+ #include "modules/desktop_capture/desktop_geometry.h"
+ #include "modules/desktop_capture/linux/x11/shared_x_display.h"
++#include "modules/desktop_capture/linux/x11/x_window_property.h"
+ #include "modules/desktop_capture/linux/x11/window_finder_x11.h"
+ #include "modules/desktop_capture/linux/x11/x_atom_cache.h"
+ #include "modules/desktop_capture/linux/x11/x_server_pixel_buffer.h"
+@@ -57,6 +58,9 @@ class WindowCapturerX11 : public DesktopCapturer,
+ // Returns window title for the specified X `window`.
+ bool GetWindowTitle(::Window window, std::string* title);
+
++ // Returns the id of the owning process.
++ int GetWindowProcessID(::Window window);
++
+ Callback* callback_ = nullptr;
+
+ rtc::scoped_refptr<SharedXDisplay> x_display_;
+diff --git a/modules/desktop_capture/linux/x11/x_error_trap.cc b/modules/desktop_capture/linux/x11/x_error_trap.cc
+index 24c2065111..3314dd286c 100644
+--- a/modules/desktop_capture/linux/x11/x_error_trap.cc
++++ b/modules/desktop_capture/linux/x11/x_error_trap.cc
+@@ -12,48 +12,58 @@
+
+ #include <stddef.h>
+
+-#include <atomic>
++#include <limits>
+
+ #include "rtc_base/checks.h"
+
+-namespace webrtc {
+-
+-namespace {
+-
+-static int g_last_xserver_error_code = 0;
+-static std::atomic<Display*> g_display_for_error_handler = nullptr;
+
+-Mutex* AcquireMutex() {
+- static Mutex* mutex = new Mutex();
+- return mutex;
+-}
++namespace webrtc {
+
+-int XServerErrorHandler(Display* display, XErrorEvent* error_event) {
+- RTC_DCHECK_EQ(display, g_display_for_error_handler.load());
+- g_last_xserver_error_code = error_event->error_code;
+- return 0;
++Bool XErrorTrap::XServerErrorHandler(Display* display, xReply* rep,
++ char* /* buf */, int /* len */,
++ XPointer data) {
++ XErrorTrap* self = reinterpret_cast<XErrorTrap*>(data);
++ if (rep->generic.type != X_Error ||
++ // Overflow-safe last_request_read <= last_ignored_request_ for skipping
++ // async replies from requests before XErrorTrap was created.
++ self->last_ignored_request_ - display->last_request_read <
++ std::numeric_limits<unsigned long>::max() >> 1)
++ return False;
++ self->last_xserver_error_code_ = rep->error.errorCode;
++ return True;
+ }
+
+-} // namespace
+-
+-XErrorTrap::XErrorTrap(Display* display) : mutex_lock_(AcquireMutex()) {
+- // We don't expect this class to be used in a nested fashion so therefore
+- // g_display_for_error_handler should never be valid here.
+- RTC_DCHECK(!g_display_for_error_handler.load());
+- RTC_DCHECK(display);
+- g_display_for_error_handler.store(display);
+- g_last_xserver_error_code = 0;
+- original_error_handler_ = XSetErrorHandler(&XServerErrorHandler);
++XErrorTrap::XErrorTrap(Display* display)
++ : display_(display),
++ last_xserver_error_code_(0),
++ enabled_(true) {
++ // Use async_handlers instead of XSetErrorHandler(). async_handlers can
++ // remain in place and then be safely removed at the right time even if a
++ // handler change happens concurrently on another thread. async_handlers
++ // are processed first and so can prevent errors reaching the global
++ // XSetErrorHandler handler. They also will not see errors from or affect
++ // handling of errors on other Displays, which may be processed on other
++ // threads.
++ LockDisplay(display);
++ async_handler_.next = display->async_handlers;
++ async_handler_.handler = XServerErrorHandler;
++ async_handler_.data = reinterpret_cast<XPointer>(this);
++ display->async_handlers = &async_handler_;
++ last_ignored_request_ = display->request;
++ UnlockDisplay(display);
+ }
+
+ int XErrorTrap::GetLastErrorAndDisable() {
+- g_display_for_error_handler.store(nullptr);
+- XSetErrorHandler(original_error_handler_);
+- return g_last_xserver_error_code;
++ assert(enabled_);
++ enabled_ = false;
++ LockDisplay(display_);
++ DeqAsyncHandler(display_, &async_handler_);
++ UnlockDisplay(display_);
++ return last_xserver_error_code_;
+ }
+
+ XErrorTrap::~XErrorTrap() {
+- if (g_display_for_error_handler.load() != nullptr)
++ if (enabled_)
+ GetLastErrorAndDisable();
+ }
+
+diff --git a/modules/desktop_capture/linux/x11/x_error_trap.h b/modules/desktop_capture/linux/x11/x_error_trap.h
+index 1f21ab969c..df7e86bf03 100644
+--- a/modules/desktop_capture/linux/x11/x_error_trap.h
++++ b/modules/desktop_capture/linux/x11/x_error_trap.h
+@@ -11,30 +11,39 @@
+ #ifndef MODULES_DESKTOP_CAPTURE_LINUX_X11_X_ERROR_TRAP_H_
+ #define MODULES_DESKTOP_CAPTURE_LINUX_X11_X_ERROR_TRAP_H_
+
+-#include <X11/Xlib.h>
+-
+-#include "rtc_base/synchronization/mutex.h"
++#include <X11/Xlibint.h>
++#undef max // Xlibint.h defines this and it breaks std::max
++#undef min // Xlibint.h defines this and it breaks std::min
+
+ namespace webrtc {
+
+-// Helper class that registers an X Window error handler. Caller can use
++// Helper class that registers X Window error handler. Caller can use
+ // GetLastErrorAndDisable() to get the last error that was caught, if any.
++// An XErrorTrap may be constructed on any thread, but errors are collected
++// from all threads and so |display| should be used only on one thread.
++// Other Displays are unaffected.
+ class XErrorTrap {
+ public:
+ explicit XErrorTrap(Display* display);
++ ~XErrorTrap();
+
+ XErrorTrap(const XErrorTrap&) = delete;
+ XErrorTrap& operator=(const XErrorTrap&) = delete;
+
+- ~XErrorTrap();
+-
+- // Returns the last error if one was caught, otherwise 0. Also unregisters the
+- // error handler and replaces it with `original_error_handler_`.
++ // Returns last error and removes unregisters the error handler.
++ // Must not be called more than once.
+ int GetLastErrorAndDisable();
+
+ private:
+- MutexLock mutex_lock_;
+- XErrorHandler original_error_handler_ = nullptr;
++ static Bool XServerErrorHandler(Display* display, xReply* rep,
++ char* /* buf */, int /* len */,
++ XPointer data);
++
++ _XAsyncHandler async_handler_;
++ Display* display_;
++ unsigned long last_ignored_request_;
++ int last_xserver_error_code_;
++ bool enabled_;
+ };
+
+ } // namespace webrtc
+diff --git a/modules/desktop_capture/win/screen_capture_utils.cc b/modules/desktop_capture/win/screen_capture_utils.cc
+index 3745e9cba5..f68cfb94c1 100644
+--- a/modules/desktop_capture/win/screen_capture_utils.cc
++++ b/modules/desktop_capture/win/screen_capture_utils.cc
+@@ -52,7 +52,7 @@ bool GetScreenList(DesktopCapturer::SourceList* screens,
+ continue;
+ }
+
+- screens->push_back({device_index, std::string()});
++ screens->push_back({device_index, 0, std::string()});
+ if (device_names) {
+ device_names->push_back(rtc::ToUtf8(device.DeviceName));
+ }
+diff --git a/modules/rtp_rtcp/source/rtcp_sender.cc b/modules/rtp_rtcp/source/rtcp_sender.cc
+index de68885519..099b0be1a3 100644
+--- a/modules/rtp_rtcp/source/rtcp_sender.cc
++++ b/modules/rtp_rtcp/source/rtcp_sender.cc
+@@ -200,7 +200,7 @@ void RTCPSender::SetRTCPStatus(RtcpMode new_method) {
+ next_time_to_send_rtcp_ = absl::nullopt;
+ } else if (method_ == RtcpMode::kOff) {
+ // When switching on, reschedule the next packet
+- SetNextRtcpSendEvaluationDuration(report_interval_ / 2);
++ SetNextRtcpSendEvaluationDuration(RTCP_INTERVAL_RAPID_SYNC_MS / 2);
+ }
+ method_ = new_method;
+ }
+diff --git a/modules/rtp_rtcp/source/rtp_header_extensions.cc b/modules/rtp_rtcp/source/rtp_header_extensions.cc
+index e42a84bd06..b86a7d775c 100644
+--- a/modules/rtp_rtcp/source/rtp_header_extensions.cc
++++ b/modules/rtp_rtcp/source/rtp_header_extensions.cc
+@@ -423,6 +423,45 @@ bool PlayoutDelayLimits::Write(rtc::ArrayView<uint8_t> data,
+ return true;
+ }
+
++// CSRCAudioLevel
++// Sample Audio Level Encoding Using the One-Byte Header Format
++// Note that the range of len is 1 to 15 which is encoded as 0 to 14
++// 0 1 2 3
++// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
++// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++// | ID | len=2 |0| level 1 |0| level 2 |0| level 3 |
++// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++
++
++constexpr RTPExtensionType CsrcAudioLevel::kId;
++constexpr const char* CsrcAudioLevel::kUri;
++
++bool CsrcAudioLevel::Parse(rtc::ArrayView<const uint8_t> data,
++ CsrcAudioLevelList* csrcAudioLevels) {
++ if (data.size() < 1 || data.size() > kRtpCsrcSize)
++ return false;
++ csrcAudioLevels->numAudioLevels = data.size();
++ for(uint8_t i = 0; i < csrcAudioLevels->numAudioLevels; i++) {
++ // Ensure range is 0 to 127 inclusive
++ csrcAudioLevels->arrOfAudioLevels[i] = 0x7f & data[i];
++ }
++ return true;
++}
++
++size_t CsrcAudioLevel::ValueSize(const CsrcAudioLevelList& csrcAudioLevels) {
++ return csrcAudioLevels.numAudioLevels;
++}
++
++bool CsrcAudioLevel::Write(rtc::ArrayView<uint8_t> data,
++ const CsrcAudioLevelList& csrcAudioLevels) {
++ RTC_DCHECK_GE(csrcAudioLevels.numAudioLevels, 0);
++ for(uint8_t i = 0; i < csrcAudioLevels.numAudioLevels; i++) {
++ data[i] = csrcAudioLevels.arrOfAudioLevels[i] & 0x7f;
++ }
++ // This extension if used must have at least one audio level
++ return csrcAudioLevels.numAudioLevels;
++}
++
+ // Video Content Type.
+ //
+ // E.g. default video or screenshare.
+diff --git a/modules/rtp_rtcp/source/rtp_header_extensions.h b/modules/rtp_rtcp/source/rtp_header_extensions.h
+index 739d4765d0..fff7db0294 100644
+--- a/modules/rtp_rtcp/source/rtp_header_extensions.h
++++ b/modules/rtp_rtcp/source/rtp_header_extensions.h
+@@ -298,6 +298,21 @@ class ColorSpaceExtension {
+ static size_t WriteLuminance(uint8_t* data, float f, int denominator);
+ };
+
++class CsrcAudioLevel {
++ public:
++ static constexpr RTPExtensionType kId = kRtpExtensionCsrcAudioLevel;
++ static constexpr absl::string_view Uri() {
++ return RtpExtension::kCsrcAudioLevelsUri;
++ }
++ static constexpr const char* kUri =
++ "urn:ietf:params:rtp-hdrext:csrc-audio-level";
++
++ static bool Parse(rtc::ArrayView<const uint8_t> data,
++ CsrcAudioLevelList* csrcAudioLevels);
++ static size_t ValueSize(const CsrcAudioLevelList& csrcAudioLevels);
++ static bool Write(rtc::ArrayView<uint8_t> data, const CsrcAudioLevelList& csrcAudioLevels);
++};
++
+ // Base extension class for RTP header extensions which are strings.
+ // Subclasses must defined kId and kUri static constexpr members.
+ class BaseRtpStringExtension {
+diff --git a/modules/rtp_rtcp/source/rtp_packet.cc b/modules/rtp_rtcp/source/rtp_packet.cc
+index 2a95a3a816..b152cdbd9e 100644
+--- a/modules/rtp_rtcp/source/rtp_packet.cc
++++ b/modules/rtp_rtcp/source/rtp_packet.cc
+@@ -205,6 +205,10 @@ void RtpPacket::ZeroMutableExtensions() {
+ // Non-mutable extension. Don't change it.
+ break;
+ }
++ case RTPExtensionType::kRtpExtensionCsrcAudioLevel: {
++ // TODO: This is a Mozilla addition, we need to add a handler for this.
++ RTC_CHECK(false);
++ }
+ }
+ }
+ }
+diff --git a/modules/rtp_rtcp/source/rtp_packet_unittest.cc b/modules/rtp_rtcp/source/rtp_packet_unittest.cc
+index a1d1c9d4df..b3a9452df9 100644
+--- a/modules/rtp_rtcp/source/rtp_packet_unittest.cc
++++ b/modules/rtp_rtcp/source/rtp_packet_unittest.cc
+@@ -123,6 +123,18 @@ constexpr uint8_t kPacketWithMid[] = {
+ 0xbe, 0xde, 0x00, 0x01,
+ 0xb2, 'm', 'i', 'd'};
+
++constexpr uint8_t kCsrcAudioLevelExtensionId = 0xc;
++constexpr uint8_t kCsrcAudioLevelsSize = 4;
++constexpr uint8_t kCsrcAudioLevels[] = {0x7f, 0x00, 0x10, 0x08};
++constexpr uint8_t kPacketWithCsrcAudioLevels[] = {
++ 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
++ 0x65, 0x43, 0x12, 0x78,
++ 0x12, 0x34, 0x56, 0x78,
++ 0xbe, 0xde, 0x00, 0x02,
++ (kCsrcAudioLevelExtensionId << 4) | (kCsrcAudioLevelsSize - 1),
++ 0x7f, 0x00, 0x10,
++ 0x08, 0x00, 0x00, 0x00};
++
+ constexpr uint32_t kCsrcs[] = {0x34567890, 0x32435465};
+ constexpr uint8_t kPayload[] = {'p', 'a', 'y', 'l', 'o', 'a', 'd'};
+ constexpr uint8_t kPacketPaddingSize = 8;
+@@ -397,6 +409,24 @@ TEST(RtpPacketTest, FailsToSetUnregisteredExtension) {
+ EXPECT_EQ(packet.GetExtension<TransportSequenceNumber>(), absl::nullopt);
+ }
+
++TEST(RtpPacketTest, CreateWithDynamicSizedExtensionCsrcAudioLevel) {
++ RtpPacketToSend::ExtensionManager extensions;
++ extensions.Register<CsrcAudioLevel>(kCsrcAudioLevelExtensionId);
++ RtpPacketToSend packet(&extensions);
++ packet.SetPayloadType(kPayloadType);
++ packet.SetSequenceNumber(kSeqNum);
++ packet.SetTimestamp(kTimestamp);
++ packet.SetSsrc(kSsrc);
++ CsrcAudioLevelList levels;
++ levels.numAudioLevels = kCsrcAudioLevelsSize;
++ for (uint8_t i = 0; i < kCsrcAudioLevelsSize; i++) {
++ levels.arrOfAudioLevels[i] = kCsrcAudioLevels[i];
++ }
++ packet.SetExtension<CsrcAudioLevel>(levels);
++ EXPECT_THAT(kPacketWithCsrcAudioLevels,
++ ElementsAreArray(packet.data(), packet.size()));
++}
++
+ TEST(RtpPacketTest, SetReservedExtensionsAfterPayload) {
+ const size_t kPayloadSize = 4;
+ RtpPacketToSend::ExtensionManager extensions;
+diff --git a/modules/rtp_rtcp/source/rtp_rtcp_config.h b/modules/rtp_rtcp/source/rtp_rtcp_config.h
+index 0b87d6d065..d69ae9420b 100644
+--- a/modules/rtp_rtcp/source/rtp_rtcp_config.h
++++ b/modules/rtp_rtcp/source/rtp_rtcp_config.h
+@@ -11,11 +11,15 @@
+ #ifndef MODULES_RTP_RTCP_SOURCE_RTP_RTCP_CONFIG_H_
+ #define MODULES_RTP_RTCP_SOURCE_RTP_RTCP_CONFIG_H_
+
++#include "api/units/time_delta.h"
++
+ // Configuration file for RTP utilities (RTPSender, RTPReceiver ...)
+ namespace webrtc {
+ constexpr int kDefaultMaxReorderingThreshold = 50; // In sequence numbers.
+ constexpr int kRtcpMaxNackFields = 253;
+
++constexpr TimeDelta RTCP_INTERVAL_RAPID_SYNC_MS =
++ TimeDelta::Millis(100); // RFX 6051
+ constexpr int RTCP_MAX_REPORT_BLOCKS = 31; // RFC 3550 page 37
+ } // namespace webrtc
+
+diff --git a/modules/rtp_rtcp/source/rtp_sender.cc b/modules/rtp_rtcp/source/rtp_sender.cc
+index d899b4f44e..f4ba024444 100644
+--- a/modules/rtp_rtcp/source/rtp_sender.cc
++++ b/modules/rtp_rtcp/source/rtp_sender.cc
+@@ -128,6 +128,10 @@ bool IsNonVolatile(RTPExtensionType type) {
+ case kRtpExtensionNumberOfExtensions:
+ RTC_DCHECK_NOTREACHED();
+ return false;
++ case kRtpExtensionCsrcAudioLevel:
++ // TODO: Mozilla implement for CsrcAudioLevel
++ RTC_CHECK(false);
++ return false;
+ }
+ RTC_CHECK_NOTREACHED();
+ }
+diff --git a/modules/video_capture/device_info_impl.cc b/modules/video_capture/device_info_impl.cc
+index ff32a78580..7cccdb51a7 100644
+--- a/modules/video_capture/device_info_impl.cc
++++ b/modules/video_capture/device_info_impl.cc
+@@ -65,7 +65,7 @@ int32_t DeviceInfoImpl::GetCapability(const char* deviceUniqueIdUTF8,
+
+ // Make sure the number is valid
+ if (deviceCapabilityNumber >= (unsigned int)_captureCapabilities.size()) {
+- RTC_LOG(LS_ERROR) << "Invalid deviceCapabilityNumber "
++ RTC_LOG(LS_ERROR) << deviceUniqueIdUTF8 << " Invalid deviceCapabilityNumber "
+ << deviceCapabilityNumber << ">= number of capabilities ("
+ << _captureCapabilities.size() << ").";
+ return -1;
+diff --git a/modules/video_capture/device_info_impl.h b/modules/video_capture/device_info_impl.h
+index 546265049c..8acbef6d69 100644
+--- a/modules/video_capture/device_info_impl.h
++++ b/modules/video_capture/device_info_impl.h
+@@ -42,6 +42,7 @@ class DeviceInfoImpl : public VideoCaptureModule::DeviceInfo {
+ /* Initialize this object*/
+
+ virtual int32_t Init() = 0;
++ int32_t Refresh() override { return 0; }
+ /*
+ * Fills the member variable _captureCapabilities with capabilities for the
+ * given device name.
+diff --git a/modules/video_capture/linux/device_info_v4l2.cc b/modules/video_capture/linux/device_info_v4l2.cc
+index a472e41a41..7397a10625 100644
+--- a/modules/video_capture/linux/device_info_v4l2.cc
++++ b/modules/video_capture/linux/device_info_v4l2.cc
+@@ -45,15 +45,187 @@
+ #define V4L2_PIX_FMT_RGBA32 v4l2_fourcc('A', 'B', '2', '4')
+ #endif
+
++#ifdef WEBRTC_LINUX
++#define EVENT_SIZE ( sizeof (struct inotify_event) )
++#define BUF_LEN ( 1024 * ( EVENT_SIZE + 16 ) )
++#endif
++
+ namespace webrtc {
+ namespace videocapturemodule {
+-DeviceInfoV4l2::DeviceInfoV4l2() : DeviceInfoImpl() {}
++#ifdef WEBRTC_LINUX
++void DeviceInfoV4l2::HandleEvent(inotify_event* event, int fd)
++{
++ if (event->mask & IN_CREATE) {
++ if (fd == _fd_v4l || fd == _fd_snd) {
++ DeviceChange();
++ } else if ((event->mask & IN_ISDIR) && (fd == _fd_dev)) {
++ if (_wd_v4l < 0) {
++ // Sometimes inotify_add_watch failed if we call it immediately after receiving this event
++ // Adding 5ms delay to let file system settle down
++ usleep(5*1000);
++ _wd_v4l = inotify_add_watch(_fd_v4l, "/dev/v4l/by-path/", IN_CREATE | IN_DELETE | IN_DELETE_SELF);
++ if (_wd_v4l >= 0) {
++ DeviceChange();
++ }
++ }
++ if (_wd_snd < 0) {
++ usleep(5*1000);
++ _wd_snd = inotify_add_watch(_fd_snd, "/dev/snd/by-path/", IN_CREATE | IN_DELETE | IN_DELETE_SELF);
++ if (_wd_snd >= 0) {
++ DeviceChange();
++ }
++ }
++ }
++ } else if (event->mask & IN_DELETE) {
++ if (fd == _fd_v4l || fd == _fd_snd) {
++ DeviceChange();
++ }
++ } else if (event->mask & IN_DELETE_SELF) {
++ if (fd == _fd_v4l) {
++ inotify_rm_watch(_fd_v4l, _wd_v4l);
++ _wd_v4l = -1;
++ } else if (fd == _fd_snd) {
++ inotify_rm_watch(_fd_snd, _wd_snd);
++ _wd_snd = -1;
++ } else {
++ assert(false);
++ }
++ }
++}
++
++int DeviceInfoV4l2::EventCheck(int fd)
++{
++ struct timeval timeout;
++ fd_set rfds;
++
++ timeout.tv_sec = 0;
++ timeout.tv_usec = 100000;
++
++ FD_ZERO(&rfds);
++ FD_SET(fd, &rfds);
++
++ return select(fd+1, &rfds, NULL, NULL, &timeout);
++}
++
++int DeviceInfoV4l2::HandleEvents(int fd)
++{
++ char buffer[BUF_LEN];
++
++ ssize_t r = read(fd, buffer, BUF_LEN);
++
++ if (r <= 0) {
++ return r;
++ }
++
++ ssize_t buffer_i = 0;
++ inotify_event* pevent;
++ size_t eventSize;
++ int count = 0;
++
++ while (buffer_i < r)
++ {
++ pevent = (inotify_event *) (&buffer[buffer_i]);
++ eventSize = sizeof(inotify_event) + pevent->len;
++ char event[sizeof(inotify_event) + FILENAME_MAX + 1] // null-terminated
++ __attribute__ ((aligned(__alignof__(struct inotify_event))));
++
++ memcpy(event, pevent, eventSize);
++
++ HandleEvent((inotify_event*)(event), fd);
++
++ buffer_i += eventSize;
++ count++;
++ }
++
++ return count;
++}
++
++int DeviceInfoV4l2::ProcessInotifyEvents()
++{
++ while (!_isShutdown) {
++ if (EventCheck(_fd_dev) > 0) {
++ if (HandleEvents(_fd_dev) < 0) {
++ break;
++ }
++ }
++ if (EventCheck(_fd_v4l) > 0) {
++ if (HandleEvents(_fd_v4l) < 0) {
++ break;
++ }
++ }
++ if (EventCheck(_fd_snd) > 0) {
++ if (HandleEvents(_fd_snd) < 0) {
++ break;
++ }
++ }
++ }
++ return 0;
++}
++
++void DeviceInfoV4l2::InotifyEventThread(void* obj)
++{
++ static_cast<DeviceInfoLinux*> (obj)->InotifyProcess();
++}
++
++void DeviceInfoV4l2::InotifyProcess()
++{
++ _fd_v4l = inotify_init();
++ _fd_snd = inotify_init();
++ _fd_dev = inotify_init();
++ if (_fd_v4l >= 0 && _fd_snd >= 0 && _fd_dev >= 0) {
++ _wd_v4l = inotify_add_watch(_fd_v4l, "/dev/v4l/by-path/", IN_CREATE | IN_DELETE | IN_DELETE_SELF);
++ _wd_snd = inotify_add_watch(_fd_snd, "/dev/snd/by-path/", IN_CREATE | IN_DELETE | IN_DELETE_SELF);
++ _wd_dev = inotify_add_watch(_fd_dev, "/dev/", IN_CREATE);
++ ProcessInotifyEvents();
++
++ if (_wd_v4l >= 0) {
++ inotify_rm_watch(_fd_v4l, _wd_v4l);
++ }
++
++ if (_wd_snd >= 0) {
++ inotify_rm_watch(_fd_snd, _wd_snd);
++ }
++
++ if (_wd_dev >= 0) {
++ inotify_rm_watch(_fd_dev, _wd_dev);
++ }
++
++ close(_fd_v4l);
++ close(_fd_snd);
++ close(_fd_dev);
++ }
++}
++#endif
++
++DeviceInfoV4l2::DeviceInfoV4l2() : DeviceInfoImpl()
++#ifdef WEBRTC_LINUX
++ , _inotifyEventThread(new rtc::PlatformThread(
++ InotifyEventThread, this, "InotifyEventThread"))
++ , _isShutdown(false)
++#endif
++{
++#ifdef WEBRTC_LINUX
++ if (_inotifyEventThread)
++ {
++ _inotifyEventThread->Start();
++ }
++}
++#endif
+
+ int32_t DeviceInfoV4l2::Init() {
+ return 0;
+ }
+
+-DeviceInfoV4l2::~DeviceInfoV4l2() {}
++DeviceInfoV4l2::~DeviceInfoV4l2() {
++#ifdef WEBRTC_LINUX
++ _isShutdown = true;
++
++ if (_inotifyEventThread) {
++ _inotifyEventThread->Stop();
++ _inotifyEventThread = nullptr;
++ }
++#endif
++}
+
+ uint32_t DeviceInfoV4l2::NumberOfDevices() {
+ uint32_t count = 0;
+@@ -86,7 +258,8 @@ int32_t DeviceInfoV4l2::GetDeviceName(uint32_t deviceNumber,
+ char* deviceUniqueIdUTF8,
+ uint32_t deviceUniqueIdUTF8Length,
+ char* /*productUniqueIdUTF8*/,
+- uint32_t /*productUniqueIdUTF8Length*/) {
++ uint32_t /*productUniqueIdUTF8Length*/,
++ pid_t* /*pid*/) {
+ // Travel through /dev/video [0-63]
+ uint32_t count = 0;
+ char device[20];
+diff --git a/modules/video_capture/linux/device_info_v4l2.h b/modules/video_capture/linux/device_info_v4l2.h
+index fb95a6020d..95432a509d 100644
+--- a/modules/video_capture/linux/device_info_v4l2.h
++++ b/modules/video_capture/linux/device_info_v4l2.h
+@@ -15,6 +15,9 @@
+
+ #include "modules/video_capture/device_info_impl.h"
+
++#include "rtc_base/platform_thread.h"
++#include <sys/inotify.h>
++
+ namespace webrtc {
+ namespace videocapturemodule {
+ class DeviceInfoV4l2 : public DeviceInfoImpl {
+@@ -28,7 +31,8 @@ class DeviceInfoV4l2 : public DeviceInfoImpl {
+ char* deviceUniqueIdUTF8,
+ uint32_t deviceUniqueIdUTF8Length,
+ char* productUniqueIdUTF8 = 0,
+- uint32_t productUniqueIdUTF8Length = 0) override;
++ uint32_t productUniqueIdUTF8Length = 0,
++ pid_t* pid=0) override;
+ /*
+ * Fills the membervariable _captureCapabilities with capabilites for the
+ * given device name.
+@@ -45,6 +49,18 @@ class DeviceInfoV4l2 : public DeviceInfoImpl {
+
+ private:
+ bool IsDeviceNameMatches(const char* name, const char* deviceUniqueIdUTF8);
++
++#ifdef WEBRTC_LINUX
++ void HandleEvent(inotify_event* event, int fd);
++ int EventCheck(int fd);
++ int HandleEvents(int fd);
++ int ProcessInotifyEvents();
++ std::unique_ptr<rtc::PlatformThread> _inotifyEventThread;
++ static void InotifyEventThread(void*);
++ void InotifyProcess();
++ int _fd_v4l, _fd_dev, _wd_v4l, _wd_dev; /* accessed on InotifyEventThread thread */
++ std::atomic<bool> _isShutdown;
++#endif
+ };
+ } // namespace videocapturemodule
+ } // namespace webrtc
+diff --git a/modules/video_capture/video_capture.h b/modules/video_capture/video_capture.h
+index eddc31414a..e207598d68 100644
+--- a/modules/video_capture/video_capture.h
++++ b/modules/video_capture/video_capture.h
+@@ -15,15 +15,44 @@
+ #include "api/video/video_sink_interface.h"
+ #include "modules/video_capture/raw_video_sink_interface.h"
+ #include "modules/video_capture/video_capture_defines.h"
++#include <set>
++
++#if defined(ANDROID)
++#include <jni.h>
++#endif
+
+ namespace webrtc {
+
++class VideoInputFeedBack
++{
++public:
++ virtual void OnDeviceChange() = 0;
++protected:
++ virtual ~VideoInputFeedBack(){}
++};
++
+ class VideoCaptureModule : public rtc::RefCountInterface {
+ public:
+ // Interface for receiving information about available camera devices.
+ class DeviceInfo {
+ public:
+ virtual uint32_t NumberOfDevices() = 0;
++ virtual int32_t Refresh() = 0;
++ virtual void DeviceChange() {
++ for (auto inputCallBack : _inputCallBacks) {
++ inputCallBack->OnDeviceChange();
++ }
++ }
++ virtual void RegisterVideoInputFeedBack(VideoInputFeedBack* callBack) {
++ _inputCallBacks.insert(callBack);
++ }
++
++ virtual void DeRegisterVideoInputFeedBack(VideoInputFeedBack* callBack) {
++ auto it = _inputCallBacks.find(callBack);
++ if (it != _inputCallBacks.end()) {
++ _inputCallBacks.erase(it);
++ }
++ }
+
+ // Returns the available capture devices.
+ // deviceNumber - Index of capture device.
+@@ -38,7 +67,8 @@ class VideoCaptureModule : public rtc::RefCountInterface {
+ char* deviceUniqueIdUTF8,
+ uint32_t deviceUniqueIdUTF8Length,
+ char* productUniqueIdUTF8 = 0,
+- uint32_t productUniqueIdUTF8Length = 0) = 0;
++ uint32_t productUniqueIdUTF8Length = 0,
++ pid_t* pid = 0) = 0;
+
+ // Returns the number of capabilities this device.
+ virtual int32_t NumberOfCapabilities(const char* deviceUniqueIdUTF8) = 0;
+@@ -70,6 +100,8 @@ class VideoCaptureModule : public rtc::RefCountInterface {
+ uint32_t positionY) = 0;
+
+ virtual ~DeviceInfo() {}
++ private:
++ std::set<VideoInputFeedBack*> _inputCallBacks;
+ };
+
+ // Register capture data callback
+@@ -79,11 +111,16 @@ class VideoCaptureModule : public rtc::RefCountInterface {
+ RawVideoSinkInterface* dataCallback) = 0;
+
+ // Remove capture data callback
+- virtual void DeRegisterCaptureDataCallback() = 0;
++ virtual void DeRegisterCaptureDataCallback(
++ rtc::VideoSinkInterface<VideoFrame> *dataCallback) = 0;
+
+ // Start capture device
+ virtual int32_t StartCapture(const VideoCaptureCapability& capability) = 0;
+
++ virtual int32_t StopCaptureIfAllClientsClose() = 0;
++
++ virtual bool FocusOnSelectedSource() { return false; }
++
+ virtual int32_t StopCapture() = 0;
+
+ // Returns the name of the device used by this module.
+diff --git a/modules/video_capture/video_capture_factory.cc b/modules/video_capture/video_capture_factory.cc
+index 563ef5abd2..e085ac2df8 100644
+--- a/modules/video_capture/video_capture_factory.cc
++++ b/modules/video_capture/video_capture_factory.cc
+@@ -16,11 +16,7 @@ namespace webrtc {
+
+ rtc::scoped_refptr<VideoCaptureModule> VideoCaptureFactory::Create(
+ const char* deviceUniqueIdUTF8) {
+-#if defined(WEBRTC_ANDROID) || defined(WEBRTC_MAC)
+- return nullptr;
+-#else
+ return videocapturemodule::VideoCaptureImpl::Create(deviceUniqueIdUTF8);
+-#endif
+ }
+
+ rtc::scoped_refptr<VideoCaptureModule> VideoCaptureFactory::Create(
+@@ -37,11 +33,7 @@ rtc::scoped_refptr<VideoCaptureModule> VideoCaptureFactory::Create(
+ }
+
+ VideoCaptureModule::DeviceInfo* VideoCaptureFactory::CreateDeviceInfo() {
+-#if defined(WEBRTC_ANDROID) || defined(WEBRTC_MAC)
+- return nullptr;
+-#else
+ return videocapturemodule::VideoCaptureImpl::CreateDeviceInfo();
+-#endif
+ }
+
+ VideoCaptureModule::DeviceInfo* VideoCaptureFactory::CreateDeviceInfo(
+diff --git a/modules/video_capture/video_capture_impl.cc b/modules/video_capture/video_capture_impl.cc
+index 428253bf23..66fd0a0ebe 100644
+--- a/modules/video_capture/video_capture_impl.cc
++++ b/modules/video_capture/video_capture_impl.cc
+@@ -77,7 +77,6 @@ VideoCaptureImpl::VideoCaptureImpl()
+ _requestedCapability(),
+ _lastProcessTimeNanos(rtc::TimeNanos()),
+ _lastFrameRateCallbackTimeNanos(rtc::TimeNanos()),
+- _dataCallBack(NULL),
+ _rawDataCallBack(NULL),
+ _lastProcessFrameTimeNanos(rtc::TimeNanos()),
+ _rotateFrame(kVideoRotation_0),
+@@ -91,7 +90,6 @@ VideoCaptureImpl::VideoCaptureImpl()
+
+ VideoCaptureImpl::~VideoCaptureImpl() {
+ RTC_DCHECK_RUN_ON(&api_checker_);
+- DeRegisterCaptureDataCallback();
+ if (_deviceUniqueId)
+ delete[] _deviceUniqueId;
+ }
+@@ -100,28 +98,41 @@ void VideoCaptureImpl::RegisterCaptureDataCallback(
+ rtc::VideoSinkInterface<VideoFrame>* dataCallBack) {
+ MutexLock lock(&api_lock_);
+ RTC_DCHECK(!_rawDataCallBack);
+- _dataCallBack = dataCallBack;
++ _dataCallBacks.insert(dataCallBack);
+ }
+
+ void VideoCaptureImpl::RegisterCaptureDataCallback(
+ RawVideoSinkInterface* dataCallBack) {
+ MutexLock lock(&api_lock_);
+- RTC_DCHECK(!_dataCallBack);
++ RTC_DCHECK(_dataCallBacks.empty());
+ _rawDataCallBack = dataCallBack;
+ }
+
+-void VideoCaptureImpl::DeRegisterCaptureDataCallback() {
++void VideoCaptureImpl::DeRegisterCaptureDataCallback(
++ rtc::VideoSinkInterface<VideoFrame>* dataCallBack) {
+ MutexLock lock(&api_lock_);
+- _dataCallBack = NULL;
++ auto it = _dataCallBacks.find(dataCallBack);
++ if (it != _dataCallBacks.end()) {
++ _dataCallBacks.erase(it);
++ }
+ _rawDataCallBack = NULL;
+ }
++
++int32_t VideoCaptureImpl::StopCaptureIfAllClientsClose() {
++ if (_dataCallBacks.empty()) {
++ return StopCapture();
++ } else {
++ return 0;
++ }
++}
++
+ int32_t VideoCaptureImpl::DeliverCapturedFrame(VideoFrame& captureFrame) {
+ RTC_CHECK_RUNS_SERIALIZED(&capture_checker_);
+
+ UpdateFrameCount(); // frame count used for local frame rate callback.
+
+- if (_dataCallBack) {
+- _dataCallBack->OnFrame(captureFrame);
++ for (auto dataCallBack : _dataCallBacks) {
++ dataCallBack->OnFrame(captureFrame);
+ }
+
+ return 0;
+@@ -229,6 +240,13 @@ int32_t VideoCaptureImpl::IncomingFrame(uint8_t* videoFrame,
+ .build();
+ captureFrame.set_ntp_time_ms(captureTime);
+
++ // This is one ugly hack to let CamerasParent know what rotation
++ // the frame was captured at. Note that this goes against the intended
++ // meaning of rotation of the frame (how to rotate it before rendering).
++ // We do this so CamerasChild can scale to the proper dimensions
++ // later on in the pipe.
++ captureFrame.set_rotation(_rotateFrame);
++
+ DeliverCapturedFrame(captureFrame);
+
+ return 0;
+diff --git a/modules/video_capture/video_capture_impl.h b/modules/video_capture/video_capture_impl.h
+index 5ec1fd4a83..e46e050609 100644
+--- a/modules/video_capture/video_capture_impl.h
++++ b/modules/video_capture/video_capture_impl.h
+@@ -64,8 +64,10 @@ class RTC_EXPORT VideoCaptureImpl : public VideoCaptureModule {
+ rtc::VideoSinkInterface<VideoFrame>* dataCallback) override;
+ virtual void RegisterCaptureDataCallback(
+ RawVideoSinkInterface* dataCallback) override;
+- void DeRegisterCaptureDataCallback() override;
++ void DeRegisterCaptureDataCallback(
++ rtc::VideoSinkInterface<VideoFrame>* dataCallback) override;
+
++ int32_t StopCaptureIfAllClientsClose() override;
+ int32_t SetCaptureRotation(VideoRotation rotation) override;
+ bool SetApplyRotation(bool enable) override;
+ bool GetApplyRotation() override;
+@@ -115,7 +117,7 @@ class RTC_EXPORT VideoCaptureImpl : public VideoCaptureModule {
+ // last time the frame rate callback function was called.
+ int64_t _lastFrameRateCallbackTimeNanos RTC_GUARDED_BY(capture_checker_);
+
+- rtc::VideoSinkInterface<VideoFrame>* _dataCallBack RTC_GUARDED_BY(api_lock_);
++ std::set<rtc::VideoSinkInterface<VideoFrame>*> _dataCallBacks RTC_GUARDED_BY(api_lock_);
+ RawVideoSinkInterface* _rawDataCallBack RTC_GUARDED_BY(api_lock_);
+
+ int64_t _lastProcessFrameTimeNanos RTC_GUARDED_BY(capture_checker_);
+diff --git a/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc b/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc
+index e26169fd3d..5330eb7e8c 100644
+--- a/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc
++++ b/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc
+@@ -256,6 +256,7 @@ LibvpxVp9Encoder::LibvpxVp9Encoder(const cricket::VideoCodec& codec,
+ first_frame_in_picture_(true),
+ ss_info_needed_(false),
+ force_all_active_layers_(false),
++ num_cores_(0),
+ is_flexible_mode_(false),
+ variable_framerate_experiment_(ParseVariableFramerateConfig(trials)),
+ variable_framerate_controller_(
+@@ -579,6 +580,7 @@ int LibvpxVp9Encoder::InitEncode(const VideoCodec* inst,
+
+ force_key_frame_ = true;
+ pics_since_key_ = 0;
++ num_cores_ = settings.number_of_cores;
+
+ scalability_mode_ = inst->GetScalabilityMode();
+ if (scalability_mode_.has_value()) {
+@@ -1151,6 +1153,14 @@ int LibvpxVp9Encoder::Encode(const VideoFrame& input_image,
+ config_changed_ = false;
+ }
+
++ if (input_image.width() != codec_.width ||
++ input_image.height() != codec_.height) {
++ int ret = UpdateCodecFrameSize(input_image);
++ if (ret < 0) {
++ return ret;
++ }
++ }
++
+ RTC_DCHECK_EQ(input_image.width(), raw_->d_w);
+ RTC_DCHECK_EQ(input_image.height(), raw_->d_h);
+
+@@ -1273,6 +1283,48 @@ int LibvpxVp9Encoder::Encode(const VideoFrame& input_image,
+ return WEBRTC_VIDEO_CODEC_OK;
+ }
+
++int LibvpxVp9Encoder::UpdateCodecFrameSize(
++ const VideoFrame& input_image) {
++ RTC_LOG(LS_INFO) << "Reconfiging VP from " <<
++ codec_.width << "x" << codec_.height << " to " <<
++ input_image.width() << "x" << input_image.height();
++ // Preserve latest bitrate/framerate setting
++ // TODO: Mozilla - see below, we need to save more state here.
++ //uint32_t old_bitrate_kbit = config_->rc_target_bitrate;
++ //uint32_t old_framerate = codec_.maxFramerate;
++
++ codec_.width = input_image.width();
++ codec_.height = input_image.height();
++
++ vpx_img_free(raw_);
++ raw_ = vpx_img_wrap(NULL, VPX_IMG_FMT_I420, codec_.width, codec_.height,
++ 1, NULL);
++ // Update encoder context for new frame size.
++ config_->g_w = codec_.width;
++ config_->g_h = codec_.height;
++
++ // Determine number of threads based on the image size and #cores.
++ config_->g_threads = NumberOfThreads(codec_.width, codec_.height,
++ num_cores_);
++
++ // NOTE: We would like to do this the same way vp8 does it
++ // (with vpx_codec_enc_config_set()), but that causes asserts
++ // in AQ 3 (cyclic); and in AQ 0 it works, but on a resize to smaller
++ // than 1/2 x 1/2 original it asserts in convolve(). Given these
++ // bugs in trying to do it the "right" way, we basically re-do
++ // the initialization.
++ vpx_codec_destroy(encoder_); // clean up old state
++ int result = InitAndSetControlSettings(&codec_);
++ if (result == WEBRTC_VIDEO_CODEC_OK) {
++ // TODO: Mozilla rates have become much more complicated, we need to store
++ // more state or find another way of doing this.
++ //return SetRates(old_bitrate_kbit, old_framerate);
++ RTC_CHECK(false);
++ return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
++ }
++ return result;
++}
++
+ bool LibvpxVp9Encoder::PopulateCodecSpecific(CodecSpecificInfo* codec_specific,
+ absl::optional<int>* spatial_idx,
+ absl::optional<int>* temporal_idx,
+diff --git a/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.h b/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.h
+index 0474e7bc17..1953923f81 100644
+--- a/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.h
++++ b/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.h
+@@ -67,6 +67,9 @@ class LibvpxVp9Encoder : public VP9Encoder {
+ // Call encoder initialize function and set control settings.
+ int InitAndSetControlSettings(const VideoCodec* inst);
+
++ // Update frame size for codec.
++ int UpdateCodecFrameSize(const VideoFrame& input_image);
++
+ bool PopulateCodecSpecific(CodecSpecificInfo* codec_specific,
+ absl::optional<int>* spatial_idx,
+ absl::optional<int>* temporal_idx,
+@@ -148,6 +151,7 @@ class LibvpxVp9Encoder : public VP9Encoder {
+ VideoBitrateAllocation current_bitrate_allocation_;
+ bool ss_info_needed_;
+ bool force_all_active_layers_;
++ uint8_t num_cores_;
+
+ std::unique_ptr<ScalableVideoController> svc_controller_;
+ absl::optional<ScalabilityMode> scalability_mode_;
+diff --git a/rtc_base/BUILD.gn b/rtc_base/BUILD.gn
+index 6abae807fe..99d8e48e39 100644
+--- a/rtc_base/BUILD.gn
++++ b/rtc_base/BUILD.gn
+@@ -458,6 +458,12 @@ rtc_library("logging") {
+ "//third_party/abseil-cpp/absl/types:optional",
+ ]
+
++ # Added to allow including apm_data_dumper.h in rtc_base/logging.cc
++ # for Mozilla controlling aec logging from about:webrtc.
++ if (build_with_mozilla) {
++ configs += [ "../modules/audio_processing:apm_debug_dump" ]
++ }
++
+ if (build_with_chromium) {
+ # Dependency on chromium's logging (in //base).
+ deps += [ "//base" ]
+diff --git a/rtc_base/logging.cc b/rtc_base/logging.cc
+index 61a3c667ba..ad2303735e 100644
+--- a/rtc_base/logging.cc
++++ b/rtc_base/logging.cc
+@@ -44,6 +44,7 @@ static const int kMaxLogLineSize = 1024 - 60;
+ #include "absl/base/attributes.h"
+ #include "absl/strings/string_view.h"
+ #include "api/units/timestamp.h"
++#include "modules/audio_processing/logging/apm_data_dumper.h"
+ #include "rtc_base/checks.h"
+ #include "rtc_base/platform_thread_types.h"
+ #include "rtc_base/string_encode.h"
+@@ -54,6 +55,24 @@ static const int kMaxLogLineSize = 1024 - 60;
+ #include "rtc_base/time_utils.h"
+
+ namespace rtc {
++
++bool LogMessage::aec_debug_ = false;
++std::string LogMessage::aec_filename_base_;
++
++void LogMessage::set_aec_debug(bool enable) {
++ aec_debug_ = enable;
++ webrtc::ApmDataDumper::SetActivated(aec_debug_);
++}
++
++std::string LogMessage::aec_debug_filename() {
++ return aec_filename_base_;
++}
++
++void LogMessage::set_aec_debug_filename(const char* filename) {
++ aec_filename_base_ = filename;
++ webrtc::ApmDataDumper::SetOutputDirectory(aec_filename_base_);
++}
++
+ namespace {
+
+ // By default, release builds don't log, debug builds at info level
+@@ -114,7 +133,7 @@ std::string LogLineRef::DefaultLogLine() const {
+ // LogMessage
+ /////////////////////////////////////////////////////////////////////////////
+
+-bool LogMessage::log_to_stderr_ = true;
++bool LogMessage::log_to_stderr_ = false;
+
+ // The list of logging streams currently configured.
+ // Note: we explicitly do not clean this up, because of the uncertain ordering
+diff --git a/rtc_base/logging.h b/rtc_base/logging.h
+index b171cfe11e..df7f173f58 100644
+--- a/rtc_base/logging.h
++++ b/rtc_base/logging.h
+@@ -581,6 +581,12 @@ class LogMessage {
+ }
+ #endif // RTC_LOG_ENABLED()
+
++ // Enable dumping of AEC inputs and outputs. Can be changed in mid-call
++ static void set_aec_debug(bool enable);
++ static bool aec_debug() { return aec_debug_; }
++ static std::string aec_debug_filename();
++ static void set_aec_debug_filename(const char* filename);
++
+ private:
+ friend class LogMessageForTesting;
+
+@@ -636,6 +642,9 @@ class LogMessage {
+
+ // The stringbuilder that buffers the formatted message before output
+ rtc::StringBuilder print_stream_;
++
++ static bool aec_debug_;
++ static std::string aec_filename_base_;
+ };
+
+ //////////////////////////////////////////////////////////////////////
+diff --git a/test/fuzzers/rtp_packet_fuzzer.cc b/test/fuzzers/rtp_packet_fuzzer.cc
+index 60afb986de..0e10a8fa3a 100644
+--- a/test/fuzzers/rtp_packet_fuzzer.cc
++++ b/test/fuzzers/rtp_packet_fuzzer.cc
+@@ -164,6 +164,11 @@ void FuzzOneInput(const uint8_t* data, size_t size) {
+ // This extension requires state to read and so complicated that
+ // deserves own fuzzer.
+ break;
++ case kRtpExtensionCsrcAudioLevel: {
++ CsrcAudioLevelList levels;
++ packet.GetExtension<CsrcAudioLevel>(&levels);
++ break;
++ }
+ }
+ }
+
+diff --git a/test/vcm_capturer.cc b/test/vcm_capturer.cc
+index 0a9226ef6f..620c1c02f3 100644
+--- a/test/vcm_capturer.cc
++++ b/test/vcm_capturer.cc
+@@ -83,7 +83,7 @@ void VcmCapturer::Destroy() {
+ return;
+
+ vcm_->StopCapture();
+- vcm_->DeRegisterCaptureDataCallback();
++ vcm_->DeRegisterCaptureDataCallback(this);
+ // Release reference to VCM.
+ vcm_ = nullptr;
+ }
+diff --git a/webrtc.gni b/webrtc.gni
+index 173d66c791..912b9b4ef0 100644
+--- a/webrtc.gni
++++ b/webrtc.gni
+@@ -126,7 +126,7 @@ declare_args() {
+
+ # Selects whether debug dumps for the audio processing module
+ # should be generated.
+- apm_debug_dump = false
++ apm_debug_dump = build_with_mozilla
+
+ # Selects whether the audio processing module should be excluded.
+ rtc_exclude_audio_processing_module = false