Backed out 4 changesets (bug 1506884) for mochitest failures CLOSED TREE
authorNoemi Erli <nerli@mozilla.com>
Wed, 27 Mar 2019 21:40:55 +0200
changeset 466427 a0084ecbf6719531544190109d9a59ffa6747fe2
parent 466426 f11d78387bd9227235089a4135c97ce480903378
child 466428 bf00743b877bb5848b5e7f97851813cb26c3e37b
push id35768
push useropoprus@mozilla.com
push dateThu, 28 Mar 2019 09:55:54 +0000
treeherdermozilla-central@c045dd97faf2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1506884
milestone68.0a1
backs outc1e32495cfa21fd094896d0c12201c06a33120a8
0182d6543001d10fc7504518df4a487c444d1e7a
5837db3740b54ff6e34d90ee0da41fe909022e06
1584d9804aa189196f47e504f27c3a133fca2d47
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out 4 changesets (bug 1506884) for mochitest failures CLOSED TREE Backed out changeset c1e32495cfa2 (bug 1506884) Backed out changeset 0182d6543001 (bug 1506884) Backed out changeset 5837db3740b5 (bug 1506884) Backed out changeset 1584d9804aa1 (bug 1506884)
media/webrtc/signaling/gtest/audioconduit_unittests.cpp
media/webrtc/signaling/gtest/mediaconduit_unittests.cpp
media/webrtc/signaling/gtest/mediapipeline_unittest.cpp
media/webrtc/signaling/src/media-conduit/AudioConduit.cpp
media/webrtc/signaling/src/media-conduit/AudioConduit.h
media/webrtc/signaling/src/media-conduit/VideoConduit.h
modules/libpref/init/all.js
--- a/media/webrtc/signaling/gtest/audioconduit_unittests.cpp
+++ b/media/webrtc/signaling/gtest/audioconduit_unittests.cpp
@@ -73,18 +73,16 @@ class AudioConduitTest : public ::testin
  public:
   AudioConduitTest() : mCall(new MockCall()) {
     mAudioConduit = new AudioConduitWithMockChannelProxy(
         WebRtcCallWrapper::Create(UniquePtr<MockCall>(mCall)),
         GetCurrentThreadEventTarget());
     mAudioConduit->Init();
   }
 
-  ~AudioConduitTest() { mAudioConduit->DeleteStreams(); }
-
   MockCall* mCall;
   RefPtr<AudioConduitWithMockChannelProxy> mAudioConduit;
 };
 
 TEST_F(AudioConduitTest, TestConfigureSendMediaCodec) {
   MediaConduitErrorCode ec;
 
   // defaults
--- a/media/webrtc/signaling/gtest/mediaconduit_unittests.cpp
+++ b/media/webrtc/signaling/gtest/mediaconduit_unittests.cpp
@@ -269,30 +269,17 @@ void AudioSendAndReceive::GenerateAndRea
  *  when it has RTP/RTCP frame to transmit.
  *  For everty RTP/RTCP frame we receive, we pass it back
  *  to the conduit for eventual decoding and rendering.
  */
 class WebrtcMediaTransport : public mozilla::TransportInterface {
  public:
   WebrtcMediaTransport() : numPkts(0), mAudio(false), mVideo(false) {}
 
-  ~WebrtcMediaTransport() {
-    if (mAudioSession) {
-      mAudioSession->DeleteStreams();
-    }
-    if (mOtherAudioSession) {
-      mOtherAudioSession->DeleteStreams();
-    }
-    if (mVideoSession) {
-      mVideoSession->DeleteStreams();
-    }
-    if (mOtherVideoSession) {
-      mOtherVideoSession->DeleteStreams();
-    }
-  }
+  ~WebrtcMediaTransport() {}
 
   virtual nsresult SendRtpPacket(const uint8_t* data, size_t len) {
     ++numPkts;
 
     if (mAudio) {
       mOtherAudioSession->ReceivedRTPPacket(data, len, SSRC);
     } else {
       mOtherVideoSession->ReceivedRTPPacket(data, len, SSRC);
--- a/media/webrtc/signaling/gtest/mediapipeline_unittest.cpp
+++ b/media/webrtc/signaling/gtest/mediapipeline_unittest.cpp
@@ -262,25 +262,18 @@ class TestAgent {
     MOZ_MTLOG(ML_DEBUG, "Stopping");
 
     if (audio_pipeline_) audio_pipeline_->Stop();
   }
 
   void Shutdown_s() { transport_->Shutdown(); }
 
   void Shutdown() {
-    if (audio_pipeline_) {
-      audio_pipeline_->Shutdown_m();
-    }
-    if (audio_stream_track_) {
-      audio_stream_track_->Stop();
-    }
-    if (audio_conduit_) {
-      audio_conduit_->DeleteStreams();
-    }
+    if (audio_pipeline_) audio_pipeline_->Shutdown_m();
+    if (audio_stream_track_) audio_stream_track_->Stop();
 
     mozilla::SyncRunnable::DispatchToThread(
         test_utils->sts_target(), WrapRunnable(this, &TestAgent::Shutdown_s));
   }
 
   uint32_t GetRemoteSSRC() {
     uint32_t res = 0;
     audio_conduit_->GetRemoteSSRC(&res);
--- a/media/webrtc/signaling/src/media-conduit/AudioConduit.cpp
+++ b/media/webrtc/signaling/src/media-conduit/AudioConduit.cpp
@@ -70,25 +70,25 @@ RefPtr<AudioSessionConduit> AudioSession
 /**
  * Destruction defines for our super-classes
  */
 WebrtcAudioConduit::~WebrtcAudioConduit() {
   CSFLogDebug(LOGTAG, "%s ", __FUNCTION__);
   MOZ_ASSERT(NS_IsMainThread());
 
   MutexAutoLock lock(mMutex);
+  DeleteSendStream();
+  DeleteRecvStream();
+
   DeleteChannels();
 
   // We don't Terminate() the VoEBase here, because the Call (owned by
   // PeerConnectionMedia) actually owns the (shared) VoEBase/VoiceEngine
   // here
   mPtrVoEBase = nullptr;
-
-  MOZ_ASSERT(!mSendStream && !mRecvStream,
-             "Call DeleteStreams prior to ~WebrtcAudioConduit.");
 }
 
 bool WebrtcAudioConduit::SetLocalSSRCs(
     const std::vector<unsigned int>& aSSRCs) {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aSSRCs.size() == 1,
              "WebrtcAudioConduit::SetLocalSSRCs accepts exactly 1 ssrc.");
 
@@ -359,16 +359,28 @@ MediaConduitErrorCode WebrtcAudioConduit
 
   if (!CodecConfigToWebRTCCodec(codecConfig, mSendStreamConfig)) {
     CSFLogError(LOGTAG, "%s CodecConfig to WebRTC Codec Failed ", __FUNCTION__);
     return kMediaConduitMalformedArgument;
   }
 
   mDtmfEnabled = codecConfig->mDtmfEnabled;
 
+  // TEMPORARY - see bug 694814 comment 2
+  nsresult rv;
+  nsCOMPtr<nsIPrefService> prefs =
+      do_GetService("@mozilla.org/preferences-service;1", &rv);
+  if (NS_SUCCEEDED(rv)) {
+    nsCOMPtr<nsIPrefBranch> branch = do_QueryInterface(prefs);
+
+    if (branch) {
+      branch->GetIntPref("media.peerconnection.capture_delay", &mCaptureDelay);
+    }
+  }
+
   condError = StartTransmitting();
   if (condError != kMediaConduitNoError) {
     return condError;
   }
 
   return kMediaConduitNoError;
 }
 
@@ -554,16 +566,17 @@ MediaConduitErrorCode WebrtcAudioConduit
   }
 
   // if transmission is not started .. conduit cannot insert frames
   if (!mEngineTransmitting) {
     CSFLogError(LOGTAG, "%s Engine not transmitting ", __FUNCTION__);
     return kMediaConduitSessionNotInited;
   }
 
+  capture_delay = mCaptureDelay;
   // Insert the samples
   mPtrVoEBase->audio_transport()->PushCaptureData(
       mSendChannel, audio_data,
       sizeof(audio_data[0]) * 8,  // bits
       samplingFreqHz, channels, lengthSamples);
   // we should be good here
   return kMediaConduitNoError;
 }
@@ -918,55 +931,51 @@ MediaConduitErrorCode WebrtcAudioConduit
     CSFLogError(LOGTAG, "%s Channel Unsupported ", __FUNCTION__);
     return kMediaConduitMalformedArgument;
   }
 
   return kMediaConduitNoError;
 }
 
 void WebrtcAudioConduit::DeleteSendStream() {
-  MOZ_ASSERT(NS_IsMainThread());
   mMutex.AssertCurrentThreadOwns();
   if (mSendStream) {
     mSendStream->Stop();
     mEngineTransmitting = false;
     mCall->Call()->DestroyAudioSendStream(mSendStream);
     mSendStream = nullptr;
   }
   // Destroying the stream unregisters the transport
   mSendChannelProxy->RegisterTransport(nullptr);
 }
 
 MediaConduitErrorCode WebrtcAudioConduit::CreateSendStream() {
-  MOZ_ASSERT(NS_IsMainThread());
   mMutex.AssertCurrentThreadOwns();
 
   mSendStream = mCall->Call()->CreateAudioSendStream(mSendStreamConfig);
   if (!mSendStream) {
     return kMediaConduitUnknownError;
   }
 
   return kMediaConduitNoError;
 }
 
 void WebrtcAudioConduit::DeleteRecvStream() {
-  MOZ_ASSERT(NS_IsMainThread());
   mMutex.AssertCurrentThreadOwns();
   if (mRecvStream) {
     mRecvStream->Stop();
     mEngineReceiving = false;
     mCall->Call()->DestroyAudioReceiveStream(mRecvStream);
     mRecvStream = nullptr;
   }
   // Destroying the stream unregisters the transport
   mRecvChannelProxy->RegisterTransport(nullptr);
 }
 
 MediaConduitErrorCode WebrtcAudioConduit::CreateRecvStream() {
-  MOZ_ASSERT(NS_IsMainThread());
   mMutex.AssertCurrentThreadOwns();
 
   mRecvStreamConfig.rtcp_send_transport = this;
   mRecvStream = mCall->Call()->CreateAudioReceiveStream(mRecvStreamConfig);
   if (!mRecvStream) {
     return kMediaConduitUnknownError;
   }
 
@@ -1020,24 +1029,16 @@ MediaConduitErrorCode WebrtcAudioConduit
   if (status != webrtc::PacketReceiver::DELIVERY_OK) {
     CSFLogError(LOGTAG, "%s DeliverPacket Failed, %d", __FUNCTION__, status);
     return kMediaConduitRTPProcessingFailed;
   }
 
   return kMediaConduitNoError;
 }
 
-void WebrtcAudioConduit::DeleteStreams() {
-  MOZ_ASSERT(NS_IsMainThread());
-
-  MutexAutoLock lock(mMutex);
-  DeleteSendStream();
-  DeleteRecvStream();
-}
-
 MediaConduitErrorCode WebrtcAudioConduit::CreateChannels() {
   MOZ_ASSERT(NS_IsMainThread());
 
   if ((mRecvChannel = mPtrVoEBase->CreateChannel()) == -1) {
     CSFLogError(LOGTAG, "%s VoiceEngine Channel creation failed", __FUNCTION__);
     return kMediaConduitChannelError;
   }
   mRecvStreamConfig.voe_channel_id = mRecvChannel;
@@ -1069,17 +1070,16 @@ MediaConduitErrorCode WebrtcAudioConduit
   mSendChannelProxy->SetRtpPacketObserver(this);
   mSendChannelProxy->RegisterTransport(this);
 
   return kMediaConduitNoError;
 }
 
 void WebrtcAudioConduit::DeleteChannels() {
   MOZ_ASSERT(NS_IsMainThread());
-  mMutex.AssertCurrentThreadOwns();
 
   if (mSendChannel != -1) {
     mSendChannelProxy = nullptr;
     mPtrVoEBase->DeleteChannel(mSendChannel);
     mSendChannel = -1;
   }
 
   if (mRecvChannel != -1) {
--- a/media/webrtc/signaling/src/media-conduit/AudioConduit.h
+++ b/media/webrtc/signaling/src/media-conduit/AudioConduit.h
@@ -165,37 +165,39 @@ class WebrtcAudioConduit : public AudioS
    * AudioConduit registers itself as ExternalTransport to the VoiceEngine
    */
   bool SendRtcp(const uint8_t* data, size_t len) override;
 
   uint64_t CodecPluginID() override { return 0; }
   void SetPCHandle(const std::string& aPCHandle) override {}
   MediaConduitErrorCode DeliverPacket(const void* data, int len) override;
 
-  void DeleteStreams() override;
+  void DeleteStreams() override {}
 
   WebrtcAudioConduit(RefPtr<WebRtcCallWrapper> aCall,
                      nsCOMPtr<nsIEventTarget> aStsThread)
-      : mTransportMonitor("WebrtcAudioConduit"),
+      : mFakeAudioDevice(new webrtc::FakeAudioDeviceModule()),
+        mTransportMonitor("WebrtcAudioConduit"),
         mTransmitterTransport(nullptr),
         mReceiverTransport(nullptr),
         mCall(aCall),
         mRecvStreamConfig(),
         mRecvStream(nullptr),
         mSendStreamConfig(
             this)  // 'this' is stored but not  dereferenced in the constructor.
         ,
         mSendStream(nullptr),
         mRecvSSRC(0),
         mEngineTransmitting(false),
         mEngineReceiving(false),
         mRecvChannel(-1),
         mSendChannel(-1),
         mDtmfEnabled(false),
         mMutex("WebrtcAudioConduit::mMutex"),
+        mCaptureDelay(150),
         mStsThread(aStsThread) {}
 
   virtual ~WebrtcAudioConduit();
 
   virtual MediaConduitErrorCode Init();
 
   int GetRecvChannel() { return mRecvChannel; }
   webrtc::VoiceEngine* GetVoiceEngine() {
@@ -245,26 +247,17 @@ class WebrtcAudioConduit : public AudioS
   void InsertAudioLevelForContributingSource(uint32_t aSource,
                                              int64_t aTimestamp, bool aHasLevel,
                                              uint8_t aLevel);
 
   bool IsSamplingFreqSupported(int freq) const override;
 
  protected:
   // These are protected so they can be accessed by unit tests
-
-  // Written only on main thread. Accessed from audio thread.
-  // Accessed from mStsThread during stats calls.
-  // This is safe, provided audio and stats calls stop before we
-  // destroy the AudioConduit.
   std::unique_ptr<webrtc::voe::ChannelProxy> mRecvChannelProxy = nullptr;
-
-  // Written only on main thread. Accessed from mStsThread during stats calls.
-  // This is safe, provided stats calls stop before we destroy the
-  // AudioConduit.
   std::unique_ptr<webrtc::voe::ChannelProxy> mSendChannelProxy = nullptr;
 
  private:
   WebrtcAudioConduit(const WebrtcAudioConduit& other) = delete;
   void operator=(const WebrtcAudioConduit& other) = delete;
 
   // Function to convert between WebRTC and Conduit codec structures
   bool CodecConfigToWebRTCCodec(const AudioCodecConfig* codecInfo,
@@ -283,73 +276,60 @@ class WebrtcAudioConduit : public AudioS
   void DeleteRecvStream();
 
   bool RecreateSendStreamIfExists();
   bool RecreateRecvStreamIfExists();
 
   MediaConduitErrorCode CreateChannels();
   virtual void DeleteChannels();
 
+  UniquePtr<webrtc::FakeAudioDeviceModule> mFakeAudioDevice;
   mozilla::ReentrantMonitor mTransportMonitor;
-
-  // Accessed on any thread under mTransportMonitor.
   RefPtr<TransportInterface> mTransmitterTransport;
-
-  // Accessed on any thread under mTransportMonitor.
   RefPtr<TransportInterface> mReceiverTransport;
-
-  // Accessed from main thread and audio threads. Used to create and destroy
-  // channels and to send audio data. Access to channels is protected by
-  // locking in channel.cc.
   ScopedCustomReleasePtr<webrtc::VoEBase> mPtrVoEBase;
 
-  // Const so can be accessed on any thread. Most methods are called on
-  // main thread.
   const RefPtr<WebRtcCallWrapper> mCall;
-
-  // Written only on main thread. Guarded by mMutex, except for reads on main.
   webrtc::AudioReceiveStream::Config mRecvStreamConfig;
-
-  // Written only on main thread. Guarded by mMutex, except for reads on main.
   webrtc::AudioReceiveStream* mRecvStream;
-
-  // Written only on main thread. Guarded by mMutex, except for reads on main.
   webrtc::AudioSendStream::Config mSendStreamConfig;
-
-  // Written only on main thread. Guarded by mMutex, except for reads on main.
   webrtc::AudioSendStream* mSendStream;
 
   // accessed on creation, and when receiving packets
   Atomic<uint32_t> mRecvSSRC;  // this can change during a stream!
-
-  // Accessed only on mStsThread.
   RtpPacketQueue mRtpPacketQueue;
 
   // engine states of our interets
   mozilla::Atomic<bool>
       mEngineTransmitting;  // If true => VoiceEngine Send-subsystem is up
   mozilla::Atomic<bool>
       mEngineReceiving;  // If true => VoiceEngine Receive-subsystem is up
                          // and playout is enabled
-
-  // Accessed only on main thread.
-  int mRecvChannel;
+  // Keep track of each inserted RTP block and the time it was inserted
+  // so we can estimate the clock time for a specific TimeStamp coming out
+  // (for when we send data to MediaStreamTracks).  Blocks are aged out as
+  // needed.
+  struct Processing {
+    TimeStamp mTimeStamp;
+    uint32_t mRTPTimeStamp;  // RTP timestamps received
+  };
+  AutoTArray<Processing, 8> mProcessing;
 
-  // Accessed on main thread and from audio thread.
+  int mRecvChannel;
   int mSendChannel;
-
-  // Accessed only on main thread.
   bool mDtmfEnabled;
 
   Mutex mMutex;
+  nsAutoPtr<AudioCodecConfig> mCurSendCodecConfig;
 
-  // Accessed from audio thread.
+  // Current "capture" delay (really output plus input delay)
+  int32_t mCaptureDelay;
+
   webrtc::AudioFrame mAudioFrame;  // for output pulls
 
-  // Accessed from both main and mStsThread. Uses locks internally.
   RtpSourceObserver mRtpSourceObserver;
 
   // Socket transport service thread. Any thread.
   const nsCOMPtr<nsIEventTarget> mStsThread;
 };
 
 }  // namespace mozilla
 
--- a/media/webrtc/signaling/src/media-conduit/VideoConduit.h
+++ b/media/webrtc/signaling/src/media-conduit/VideoConduit.h
@@ -586,17 +586,16 @@ class WebrtcVideoConduit
 
   // Accessed only on mStsThread.
   bool mWaitingForInitialSsrc = true;
 
   // Accessed during configuration/signaling (main),
   // and when receiving packets (sts).
   Atomic<uint32_t> mRecvSSRC;  // this can change during a stream!
 
-  // Accessed only on mStsThread.
   RtpPacketQueue mRtpPacketQueue;
 
   // The lifetime of these codecs are maintained by the VideoConduit instance.
   // They are passed to the webrtc::VideoSendStream or VideoReceiveStream,
   // on construction.
   std::unique_ptr<webrtc::VideoEncoder> mEncoder;  // only one encoder for now
   std::vector<std::unique_ptr<webrtc::VideoDecoder>> mDecoders;
   // Main thread only
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -523,18 +523,29 @@ pref("media.getusermedia.aec_enabled", t
 pref("media.getusermedia.noise_enabled", true);
 #endif
 pref("media.getusermedia.use_aec_mobile", false);
 pref("media.getusermedia.aec", 1); // kModerateSuppression
 pref("media.getusermedia.aec_extended_filter", true);
 pref("media.getusermedia.noise", 1); // kModerate
 pref("media.getusermedia.agc_enabled", true);
 pref("media.getusermedia.agc", 1); // kAdaptiveDigital
+// capture_delay: Adjustments for OS-specific input delay (lower bound)
+// playout_delay: Adjustments for OS-specific AudioStream+cubeb+output delay (lower bound)
 // full_duplex: enable cubeb full-duplex capture/playback
 pref("media.navigator.audio.full_duplex", true);
+#if defined(XP_MACOSX)
+pref("media.peerconnection.capture_delay", 50);
+#elif defined(XP_WIN)
+pref("media.peerconnection.capture_delay", 50);
+#elif defined(ANDROID)
+pref("media.peerconnection.capture_delay", 100);
+#else
+pref("media.peerconnection.capture_delay", 70);
+#endif
 #endif
 
 pref("dom.webaudio.enabled", true);
 
 // Exposes the navigator.webdriver attribute.
 pref("dom.webdriver.enabled", true);
 
 #if !defined(ANDROID)