Bug 1441260 - unify API for setting extmaps in AudioConduit draft
authorNico Grunbaum
Mon, 26 Feb 2018 20:59:01 -0800
changeset 761144 90839219c91dc0d376a7fc04777a15c0e350807b
parent 760935 ee326c976eebdca48128054022c443d3993e12b0
push id100886
push userna-g@nostrum.com
push dateWed, 28 Feb 2018 19:36:15 +0000
bugs1441260
milestone60.0a1
Bug 1441260 - unify API for setting extmaps in AudioConduit MozReview-Commit-ID: 8PmvQyk32WW
media/webrtc/signaling/src/media-conduit/AudioConduit.cpp
media/webrtc/signaling/src/media-conduit/AudioConduit.h
media/webrtc/signaling/src/media-conduit/MediaConduitInterface.h
media/webrtc/signaling/src/media-conduit/VideoConduit.cpp
media/webrtc/signaling/src/media-conduit/VideoConduit.h
media/webrtc/signaling/src/peerconnection/TransceiverImpl.cpp
media/webrtc/signaling/src/peerconnection/TransceiverImpl.h
--- a/media/webrtc/signaling/src/media-conduit/AudioConduit.cpp
+++ b/media/webrtc/signaling/src/media-conduit/AudioConduit.cpp
@@ -37,16 +37,17 @@ static const char* acLogTag ="WebrtcAudi
 #ifdef LOGTAG
 #undef LOGTAG
 #endif
 #define LOGTAG acLogTag
 
 // 32 bytes is what WebRTC CodecInst expects
 const unsigned int WebrtcAudioConduit::CODEC_PLNAME_SIZE = 32;
 
+using LocalDirection = MediaSessionConduitLocalDirection;
 /**
  * Factory Method for AudioConduit
  */
 RefPtr<AudioSessionConduit> AudioSessionConduit::Create()
 {
   CSFLogDebug(LOGTAG,  "%s ", __FUNCTION__);
   NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
 
@@ -607,63 +608,70 @@ WebrtcAudioConduit::ConfigureRecvMediaCo
     return condError;
   }
 
   DumpCodecDB();
   return kMediaConduitNoError;
 }
 
 MediaConduitErrorCode
-WebrtcAudioConduit::EnableAudioLevelExtension(bool aEnabled,
-                                              uint8_t aId,
-                                              bool aDirectionIsSend,
-                                              bool aLevelIsSsrc)
+WebrtcAudioConduit::SetLocalRTPExtensions(LocalDirection aDirection,
+                                          const RtpExtList& extensions)
 {
-  CSFLogDebug(LOGTAG,  "%s %d %d %d", __FUNCTION__, aEnabled, aId,
-              aDirectionIsSend);
-
-  bool ret;
-  if (aDirectionIsSend) {
-    if (!aLevelIsSsrc) {
-      CSFLogError(LOGTAG,
-                  "%s SetSendAudioLevelIndicationStatus Failed"
-                  " can not send CSRC audio levels.", __FUNCTION__);
-      return kMediaConduitMalformedArgument;
+  CSFLogDebug(LOGTAG, "%s direction: %s", __FUNCTION__,
+              MediaSessionConduit::LocalDirectionToString(aDirection).c_str());
+  bool isSend = aDirection == LocalDirection::kSend;
+  constexpr bool kEnableExt = true;
+  constexpr bool kSsrcLevel = true;
+  constexpr bool kCsrcLevel = false;
+  for(const auto& extension : extensions) {
+    int ret = 0;
+    // ssrc-audio-level RTP header extension
+    if (extension.uri == webrtc::RtpExtension::kAudioLevelUri) {
+      if (isSend) {
+        ret = mPtrVoERTP_RTCP->SetSendAudioLevelIndicationStatus(mChannel,
+                                                                 kEnableExt,
+                                                                 extension.id);
+      } else {
+        ret = mPtrRTP->SetReceiveAudioLevelIndicationStatus(mChannel,
+                                                            kEnableExt,
+                                                            extension.id,
+                                                            kSsrcLevel);
+      }
     }
-    ret = mPtrVoERTP_RTCP->SetSendAudioLevelIndicationStatus(mChannel,
-                                                             aEnabled,
-                                                             aId) == -1;
-  } else {
-    ret = mPtrRTP->SetReceiveAudioLevelIndicationStatus(mChannel,
-                                                        aEnabled,
-                                                        aId,
-                                                        aLevelIsSsrc) == -1;
-  }
-  if (ret) {
-    CSFLogError(LOGTAG, "%s SetSendAudioLevelIndicationStatus Failed", __FUNCTION__);
-    return kMediaConduitUnknownError;
+    // csrc-audio-level RTP header extension
+    if (extension.uri == webrtc::RtpExtension::kCsrcAudioLevelUri) {
+      if (isSend) {
+        CSFLogError(LOGTAG, "%s SetSendAudioLevelIndicationStatus Failed"
+                    " can not send CSRC audio levels.", __FUNCTION__);
+        return kMediaConduitMalformedArgument;
+      }
+      ret = mPtrRTP->SetReceiveAudioLevelIndicationStatus(mChannel,
+                                                          kEnableExt,
+                                                          extension.id,
+                                                          kCsrcLevel);
+    }
+    // MID RTP header extension
+    if (aDirection == LocalDirection::kSend &&
+        extension.uri == webrtc::RtpExtension::kMIdUri) {
+      ret = mPtrVoERTP_RTCP->SetSendMIDStatus(mChannel, kEnableExt,
+                                              extension.id);
+    }
+    // Handle errors
+    if (ret == -1) {
+      CSFLogError(LOGTAG, "Failed %s setting extension %s with id %d",
+                  __FUNCTION__, extension.uri.c_str(),
+                  static_cast<int>(extension.id));
+      return kMediaConduitUnknownError;
+    }
   }
   return kMediaConduitNoError;
 }
 
 MediaConduitErrorCode
-WebrtcAudioConduit::EnableMIDExtension(bool enabled, uint8_t id)
-{
-  CSFLogDebug(LOGTAG,  "%s %d %d ", __FUNCTION__, enabled, id);
-
-  if (mPtrVoERTP_RTCP->SetSendMIDStatus(mChannel, enabled, id) == -1)
-  {
-    CSFLogError(LOGTAG, "%s SetSendMIDStatus Failed", __FUNCTION__);
-    return kMediaConduitUnknownError;
-  }
-
-  return kMediaConduitNoError;
-}
-
-MediaConduitErrorCode
 WebrtcAudioConduit::SendAudioFrame(const int16_t audio_data[],
                                    int32_t lengthSamples, // per channel
                                    int32_t samplingFreqHz,
                                    uint32_t channels,
                                    int32_t capture_delay)
 {
   CSFLogDebug(LOGTAG,  "%s ", __FUNCTION__);
   // Following checks need to be performed
--- a/media/webrtc/signaling/src/media-conduit/AudioConduit.h
+++ b/media/webrtc/signaling/src/media-conduit/AudioConduit.h
@@ -92,22 +92,18 @@ public:
    *          On failure, audio engine transmit functionality is disabled.
    * NOTE: This API can be invoked multiple time. Invoking this API may involve restarting
    *        transmission sub-system on the engine.
    */
   virtual MediaConduitErrorCode ConfigureRecvMediaCodecs(
     const std::vector<AudioCodecConfig* >& codecConfigList) override;
 
   MediaConduitErrorCode
-  EnableAudioLevelExtension(bool aEnabled,
-                            uint8_t aId,
-                            bool aDirectionIsSend,
-                            bool aLevelIsSsrc = true) override;
-
-  virtual MediaConduitErrorCode EnableMIDExtension(bool enabled, uint8_t id) override;
+  SetLocalRTPExtensions(MediaSessionConduitLocalDirection aDirection,
+                        const RtpExtList& extensions) override;
 
   /**
    * Register External Transport to this Conduit. RTP and RTCP frames from the VoiceEngine
    * shall be passed to the registered transport for transporting externally.
    */
   virtual MediaConduitErrorCode SetTransmitterTransport(RefPtr<TransportInterface> aTransport) override;
 
   virtual MediaConduitErrorCode SetReceiverTransport(RefPtr<TransportInterface> aTransport) override;
--- a/media/webrtc/signaling/src/media-conduit/MediaConduitInterface.h
+++ b/media/webrtc/signaling/src/media-conduit/MediaConduitInterface.h
@@ -29,16 +29,21 @@
 #include <vector>
 
 namespace webrtc {
 class VideoFrame;
 }
 
 namespace mozilla {
 
+enum class MediaSessionConduitLocalDirection : int {
+  kSend,
+  kRecv
+};
+
 using RtpExtList = std::vector<webrtc::RtpExtension>;
 
 // Wrap the webrtc.org Call class adding mozilla add/ref support.
 class WebRtcCallWrapper : public RefCounted<WebRtcCallWrapper>
 {
 public:
   typedef webrtc::Call::Config Config;
 
@@ -177,16 +182,22 @@ public:
 class MediaSessionConduit
 {
 protected:
   virtual ~MediaSessionConduit() {}
 
 public:
   enum Type { AUDIO, VIDEO } ;
 
+  static std::string
+  LocalDirectionToString(const MediaSessionConduitLocalDirection aDirection) {
+    return aDirection == MediaSessionConduitLocalDirection::kSend ?
+                            "send" : "receive";
+  }
+
   virtual Type type() const = 0;
 
   /**
    * Function triggered on Incoming RTP packet from the remote
    * endpoint by the transport implementation.
    * @param data : RTP Packet (audio/video) to be processed
    * @param len  : Length of the media packet
    * Obtained packets are passed to the Media-Engine for further
@@ -236,25 +247,27 @@ public:
   /* Sets the local SSRCs
    * @return true iff the local ssrcs == aSSRCs upon return
    * Note: this is an ordered list and {a,b,c} != {b,a,c}
    */
   virtual bool SetLocalSSRCs(const std::vector<unsigned int>& aSSRCs) = 0;
   virtual std::vector<unsigned int> GetLocalSSRCs() const = 0;
 
   /**
-  * Adds negotiated RTP extensions
-  * XXX Move to MediaSessionConduit
+  * Adds negotiated RTP header extensions to the the conduit. Unknown extensions
+  * are ignored.
+  * @param aDirection the local direction to set the RTP header extensions for
+  * @param aExtensions the RTP header extensions to set
+  * @return if all extensions were set it returns a success code,
+  *         if an extension fails to set it may immediately return an error code
+  * TODO webrtc.org 64 update: make return type void again
   */
-  virtual void
-  SetLocalRTPExtensions(bool aIsSend, const RtpExtList& extensions) = 0;
-  /**
-  * Returns the negotiated RTP extensions
-  */
-  virtual RtpExtList GetLocalRTPExtensions(bool aIsSend) const = 0;
+  virtual MediaConduitErrorCode
+  SetLocalRTPExtensions(MediaSessionConduitLocalDirection aDirection,
+                        const RtpExtList& aExtensions) = 0;
 
   virtual bool GetRemoteSSRC(unsigned int* ssrc) = 0;
   virtual bool SetRemoteSSRC(unsigned int ssrc) = 0;
   virtual bool SetLocalCNAME(const char* cname) = 0;
 
   virtual bool SetLocalMID(const std::string& mid) = 0;
 
   /**
@@ -352,22 +365,19 @@ public:
                           mUsingNackBasic(false),
                           mUsingTmmbr(false),
                           mUsingFEC(false) {}
 
   virtual ~VideoSessionConduit() {}
 
   Type type() const override { return VIDEO; }
 
-  void
-  SetLocalRTPExtensions(bool aIsSend,
+  MediaConduitErrorCode
+  SetLocalRTPExtensions(MediaSessionConduitLocalDirection aDirection,
                         const RtpExtList& extensions) override = 0;
-
-  RtpExtList GetLocalRTPExtensions(bool aIsSend) const override = 0;
-
   /**
    * Function to attach Renderer end-point of the Media-Video conduit.
    * @param aRenderer : Reference to the concrete Video renderer implementation
    * Note: Multiple invocations of this API shall remove an existing renderer
    * and attaches the new to the Conduit.
    */
   virtual MediaConduitErrorCode AttachRenderer(RefPtr<mozilla::VideoRenderer> aRenderer) = 0;
   virtual void DetachRenderer() = 0;
@@ -456,22 +466,19 @@ public:
    *         of failure
    */
   static RefPtr<AudioSessionConduit> Create();
 
   virtual ~AudioSessionConduit() {}
 
   Type type() const override { return AUDIO; }
 
-  void
-  SetLocalRTPExtensions(bool aIsSend,
-                        const RtpExtList& extensions) override {};
-
-  RtpExtList
-  GetLocalRTPExtensions(bool aIsSend) const override {return RtpExtList();}
+  MediaConduitErrorCode
+  SetLocalRTPExtensions(MediaSessionConduitLocalDirection aDirection,
+                        const RtpExtList& extensions) override = 0;
   /**
    * Function to deliver externally captured audio sample for encoding and transport
    * @param audioData [in]: Pointer to array containing a frame of audio
    * @param lengthSamples [in]: Length of audio frame in samples in multiple of 10 milliseconds
   *                             Ex: Frame length is 160, 320, 440 for 16, 32, 44 kHz sampling rates
                                     respectively.
                                     audioData[] is lengthSamples in size
                                     say, for 16kz sampling rate, audioData[] should contain 160
@@ -526,31 +533,16 @@ public:
 
    /**
     * Function to configure list of receive codecs for the audio session
     * @param sendSessionConfig: CodecConfiguration
     * NOTE: See VideoConduit for more information
     */
   virtual MediaConduitErrorCode ConfigureRecvMediaCodecs(
                                 const std::vector<AudioCodecConfig* >& recvCodecConfigList) = 0;
-   /**
-    * Function to enable the audio level extension
-    * @param aEnabled: enable extension
-    * @param aId: the RTP extension header ID to use
-    * @param aDirectionIsSend: indicates whether to set the extension on the
-    *                          sender or the receiver side
-    * returns an error if the extension could not be set
-    */
-  virtual MediaConduitErrorCode
-  EnableAudioLevelExtension(bool aEnabled,
-                            uint8_t aId,
-                            bool aDirectionIsSend,
-                            bool aLevelIsSsrc = true) = 0;
-  virtual MediaConduitErrorCode
-  EnableMIDExtension(bool enabled, uint8_t id) = 0;
 
   virtual bool SetDtmfPayloadType(unsigned char type, int freq) = 0;
 
   virtual bool InsertDTMFTone(int channel, int eventCode, bool outOfBand,
                               int lengthMs, int attenuationDb) = 0;
 
   virtual void GetRtpSources(const int64_t aTimeNow,
                              nsTArray<dom::RTCRtpSourceEntry>& outSources) = 0;
--- a/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp
+++ b/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp
@@ -71,16 +71,18 @@
 namespace mozilla {
 
 static const char* vcLogTag = "WebrtcVideoSessionConduit";
 #ifdef LOGTAG
 #undef LOGTAG
 #endif
 #define LOGTAG vcLogTag
 
+using LocalDirection = MediaSessionConduitLocalDirection;
+
 static const int kNullPayloadType = -1;
 static const char* kUlpFecPayloadName = "ulpfec";
 static const char* kRedPayloadName = "red";
 
 // Convert (SI) kilobits/sec to (SI) bits/sec
 #define KBPS(kbps) kbps * 1000
 const uint32_t WebrtcVideoConduit::kDefaultMinBitrate_bps =  KBPS(200);
 const uint32_t WebrtcVideoConduit::kDefaultStartBitrate_bps = KBPS(300);
@@ -315,30 +317,25 @@ WebrtcVideoConduit::~WebrtcVideoConduit(
     mVideoStatsTimer->Cancel();
   }
 
   // Release AudioConduit first by dropping reference on MainThread, where it expects to be
   SyncTo(nullptr);
   Destroy();
 }
 
-void
-WebrtcVideoConduit::SetLocalRTPExtensions(bool aIsSend,
-                                          const RtpExtList & aExtensions)
+MediaConduitErrorCode
+WebrtcVideoConduit::SetLocalRTPExtensions(LocalDirection aDirection,
+                                          const RtpExtList& aExtensions)
 {
-  auto& extList = aIsSend ? mSendStreamConfig.rtp.extensions :
-                  mRecvStreamConfig.rtp.extensions;
+  auto& extList = aDirection == LocalDirection::kSend ?
+                                    mSendStreamConfig.rtp.extensions :
+                                    mRecvStreamConfig.rtp.extensions;
   extList = aExtensions;
-}
-
-RtpExtList
-WebrtcVideoConduit::GetLocalRTPExtensions(bool aIsSend) const
-{
-  return aIsSend ? mSendStreamConfig.rtp.extensions :
-                   mRecvStreamConfig.rtp.extensions;
+  return kMediaConduitNoError;
 }
 
 bool WebrtcVideoConduit::SetLocalSSRCs(const std::vector<unsigned int> & aSSRCs)
 {
   // Special case: the local SSRCs are the same - do nothing.
   if (mSendStreamConfig.rtp.ssrcs == aSSRCs) {
     return true;
   }
--- a/media/webrtc/signaling/src/media-conduit/VideoConduit.h
+++ b/media/webrtc/signaling/src/media-conduit/VideoConduit.h
@@ -73,23 +73,19 @@ public:
   /* Default start a.k.a. target bitrate for video streams. */
   static const uint32_t kDefaultStartBitrate_bps;
   /* Default maximum bitrate for video streams. */
   static const uint32_t kDefaultMaxBitrate_bps;
 
   //VoiceEngine defined constant for Payload Name Size.
   static const unsigned int CODEC_PLNAME_SIZE;
 
-  /**
-  * Add rtp extensions to the the VideoSendStream
-  */
-  void
-  SetLocalRTPExtensions(bool aIsSend, const RtpExtList& extensions) override;
-
-  RtpExtList GetLocalRTPExtensions(bool aIsSend) const override;
+  MediaConduitErrorCode
+  SetLocalRTPExtensions(MediaSessionConduitLocalDirection aDirection,
+                        const RtpExtList& aExtensions) override;
 
   /**
    * Set up A/V sync between this (incoming) VideoConduit and an audio conduit.
    */
   void SyncTo(WebrtcAudioConduit *aConduit);
 
   /**
    * Function to attach Renderer end-point for the Media-Video conduit.
--- a/media/webrtc/signaling/src/peerconnection/TransceiverImpl.cpp
+++ b/media/webrtc/signaling/src/peerconnection/TransceiverImpl.cpp
@@ -27,16 +27,18 @@
 #include "mozilla/dom/RTCRtpSenderBinding.h"
 #include "mozilla/dom/RTCRtpTransceiverBinding.h"
 #include "mozilla/dom/TransceiverImplBinding.h"
 
 namespace mozilla {
 
 MOZ_MTLOG_MODULE("transceiverimpl")
 
+using LocalDirection = MediaSessionConduitLocalDirection;
+
 TransceiverImpl::TransceiverImpl(
     const std::string& aPCHandle,
     JsepTransceiver* aJsepTransceiver,
     nsIEventTarget* aMainThread,
     nsIEventTarget* aStsThread,
     dom::MediaStreamTrack* aReceiveTrack,
     dom::MediaStreamTrack* aSendTrack,
     WebRtcCallWrapper* aCallWrapper) :
@@ -722,46 +724,17 @@ TransceiverImpl::UpdateAudioConduit()
 
     auto error = conduit->ConfigureRecvMediaCodecs(configs.values);
 
     if (error) {
       MOZ_MTLOG(ML_ERROR, mPCHandle << "[" << mMid << "]: " << __FUNCTION__ <<
                           " ConfigureRecvMediaCodecs failed: " << error);
       return NS_ERROR_FAILURE;
     }
-
-    const SdpExtmapAttributeList::Extmap* audioLevelExt =
-        details.GetExt(webrtc::RtpExtension::kAudioLevelUri);
-    if (audioLevelExt) {
-      MOZ_MTLOG(ML_DEBUG, "Calling EnableAudioLevelExtension");
-      error = conduit->EnableAudioLevelExtension(true,
-                                                 audioLevelExt->entry,
-                                                 false);
-
-      if (error) {
-        MOZ_MTLOG(ML_ERROR, mPCHandle << "[" << mMid << "]: " << __FUNCTION__ <<
-                            " EnableAudioLevelExtension failed: " << error);
-        return NS_ERROR_FAILURE;
-      }
-    }
-
-    const SdpExtmapAttributeList::Extmap* csrcAudioLevelExt =
-        details.GetExt(webrtc::RtpExtension::kCsrcAudioLevelUri);
-    if (csrcAudioLevelExt) {
-      MOZ_MTLOG(ML_DEBUG, "Calling EnableAudioLevelExtension for CSRCs");
-      error = conduit->EnableAudioLevelExtension(true,
-                                                 csrcAudioLevelExt->entry,
-                                                 false,
-                                                 false);
-      if (error) {
-        MOZ_MTLOG(ML_ERROR, mPCHandle << "[" << mMid << "]: " << __FUNCTION__ <<
-                  " EnableAudioLevelExtension for CSRCs failed: " << error);
-        return NS_ERROR_FAILURE;
-      }
-    }
+    UpdateConduitRtpExtmap(details, LocalDirection::kRecv);
   }
 
   if (mJsepTransceiver->mSendTrack.GetNegotiatedDetails() &&
       mJsepTransceiver->mSendTrack.GetActive()) {
     const auto& details(*mJsepTransceiver->mSendTrack.GetNegotiatedDetails());
     PtrVector<AudioCodecConfig> configs;
     nsresult rv = NegotiatedDetailsToAudioCodecConfigs(details, &configs);
 
@@ -782,46 +755,17 @@ TransceiverImpl::UpdateAudioConduit()
     }
 
     auto error = conduit->ConfigureSendMediaCodec(configs.values[0]);
     if (error) {
       MOZ_MTLOG(ML_ERROR, mPCHandle << "[" << mMid << "]: " << __FUNCTION__ <<
                           " ConfigureSendMediaCodec failed: " << error);
       return NS_ERROR_FAILURE;
     }
-
-    // Should these be genericized like they are in the video conduit case?
-    const SdpExtmapAttributeList::Extmap* audioLevelExt =
-        details.GetExt(webrtc::RtpExtension::kAudioLevelUri);
-
-    if (audioLevelExt) {
-      MOZ_MTLOG(ML_DEBUG, "Calling EnableAudioLevelExtension");
-      error = conduit->EnableAudioLevelExtension(true,
-                                                 audioLevelExt->entry,
-                                                 true);
-
-      if (error) {
-        MOZ_MTLOG(ML_ERROR, mPCHandle << "[" << mMid << "]: " << __FUNCTION__ <<
-                            " EnableAudioLevelExtension failed: " << error);
-        return NS_ERROR_FAILURE;
-      }
-    }
-
-    const SdpExtmapAttributeList::Extmap* midExt =
-        details.GetExt(webrtc::RtpExtension::kMIdUri);
-
-    if (midExt) {
-      MOZ_MTLOG(ML_DEBUG, "Calling EnableMIDExtension");
-      error = conduit->EnableMIDExtension(true, midExt->entry);
-
-      if (error) {
-        MOZ_MTLOG(ML_ERROR, "EnableMIDExtension failed: " << error);
-        return NS_ERROR_FAILURE;
-      }
-    }
+    UpdateConduitRtpExtmap(details, LocalDirection::kSend);
   }
 
   return NS_OK;
 }
 
 static nsresult
 JsepCodecDescToVideoCodecConfig(const JsepCodecDescription& aCodec,
                                 VideoCodecConfig** aConfig)
@@ -918,17 +862,17 @@ TransceiverImpl::UpdateVideoConduit()
               mJsepTransceiver->mRecvTrack.GetSsrcs().front());
     conduit->SetRemoteSSRC(mJsepTransceiver->mRecvTrack.GetSsrcs().front());
   }
 
   if (mJsepTransceiver->mRecvTrack.GetNegotiatedDetails() &&
       mJsepTransceiver->mRecvTrack.GetActive()) {
     const auto& details(*mJsepTransceiver->mRecvTrack.GetNegotiatedDetails());
 
-    UpdateVideoExtmap(details, false);
+    UpdateConduitRtpExtmap(details, LocalDirection::kRecv);
 
     PtrVector<VideoCodecConfig> configs;
     nsresult rv = NegotiatedDetailsToVideoCodecConfigs(details, &configs);
 
     if (NS_FAILED(rv)) {
       MOZ_MTLOG(ML_ERROR, mPCHandle << "[" << mMid << "]: " << __FUNCTION__ <<
                           " Failed to convert JsepCodecDescriptions to "
                           "VideoCodecConfigs (recv).");
@@ -947,17 +891,17 @@ TransceiverImpl::UpdateVideoConduit()
   // It is possible for SDP to signal that there is a send track, but there not
   // actually be a send track, according to the specification; all that needs to
   // happen is for the transceiver to be configured to send...
   if (mJsepTransceiver->mSendTrack.GetNegotiatedDetails() &&
       mJsepTransceiver->mSendTrack.GetActive() &&
       mSendTrack) {
     const auto& details(*mJsepTransceiver->mSendTrack.GetNegotiatedDetails());
 
-    UpdateVideoExtmap(details, true);
+    UpdateConduitRtpExtmap(details, LocalDirection::kSend);
 
     nsresult rv = ConfigureVideoCodecMode(*conduit);
     if (NS_FAILED(rv)) {
       return rv;
     }
 
     PtrVector<VideoCodecConfig> configs;
     rv = NegotiatedDetailsToVideoCodecConfigs(details, &configs);
@@ -1015,32 +959,32 @@ TransceiverImpl::ConfigureVideoCodecMode
                         " ConfigureCodecMode failed: " << error);
     return NS_ERROR_FAILURE;
   }
 
   return NS_OK;
 }
 
 void
-TransceiverImpl::UpdateVideoExtmap(const JsepTrackNegotiatedDetails& aDetails,
-                                   bool aSending)
+TransceiverImpl::UpdateConduitRtpExtmap(const JsepTrackNegotiatedDetails& aDetails,
+                                        const LocalDirection aDirection)
 {
   std::vector<webrtc::RtpExtension> extmaps;
   // @@NG read extmap from track
   aDetails.ForEachRTPHeaderExtension(
     [&extmaps](const SdpExtmapAttributeList::Extmap& extmap)
   {
     extmaps.emplace_back(extmap.extensionname, extmap.entry);
   });
 
   RefPtr<VideoSessionConduit> conduit = static_cast<VideoSessionConduit*>(
       mConduit.get());
 
   if (!extmaps.empty()) {
-    conduit->SetLocalRTPExtensions(aSending, extmaps);
+    conduit->SetLocalRTPExtensions(aDirection, extmaps);
   }
 }
 
 void
 TransceiverImpl::Stop()
 {
   mTransmitPipeline->Stop();
   mTransmitPipeline->DetachMedia();
--- a/media/webrtc/signaling/src/peerconnection/TransceiverImpl.h
+++ b/media/webrtc/signaling/src/peerconnection/TransceiverImpl.h
@@ -16,18 +16,20 @@
 #include "signaling/src/jsep/JsepTransceiver.h"
 
 class nsIPrincipal;
 
 namespace mozilla {
 class PeerIdentity;
 class PeerConnectionMedia;
 class JsepTransceiver;
+enum class MediaSessionConduitLocalDirection : int;
 class MediaSessionConduit;
 class VideoSessionConduit;
+class AudioSessionConduit;
 class MediaPipelineReceive;
 class MediaPipelineTransmit;
 class MediaPipeline;
 class MediaPipelineFilter;
 class WebRtcCallWrapper;
 class JsepTrackNegotiatedDetails;
 
 namespace dom {
@@ -127,19 +129,18 @@ public:
 
 private:
   virtual ~TransceiverImpl();
   void InitAudio();
   void InitVideo();
   nsresult UpdateAudioConduit();
   nsresult UpdateVideoConduit();
   nsresult ConfigureVideoCodecMode(VideoSessionConduit& aConduit);
-  // This will eventually update audio extmap too
-  void UpdateVideoExtmap(const JsepTrackNegotiatedDetails& aDetails,
-                         bool aSending);
+  void UpdateConduitRtpExtmap(const JsepTrackNegotiatedDetails& aDetails,
+                              const MediaSessionConduitLocalDirection aDir);
   void Stop();
 
   const std::string mPCHandle;
   RefPtr<JsepTransceiver> mJsepTransceiver;
   std::string mMid;
   bool mHaveStartedReceiving;
   bool mHaveSetupTransport;
   nsCOMPtr<nsIEventTarget> mMainThread;