Bug 1112682: Prefer hardware codecs. r=jesup
authorByron Campen [:bwc] <docfaraday@gmail.com>
Fri, 02 Jan 2015 11:51:00 -0800
changeset 236135 e672c279ff312b2f42897ac0cef9701247c5ef8a
parent 236134 bceadf54fee87aebcd295cd7bf1320d5976e0b27
child 236136 704c1330fdf1b63579b404cb7499196fe52bb0aa
child 236147 3cb89f063d086ae784631c5958b45c56fb798192
push id389
push usermartin.thomson@gmail.com
push dateFri, 09 Jan 2015 23:59:51 +0000
reviewersjesup
bugs1112682
milestone37.0a1
Bug 1112682: Prefer hardware codecs. r=jesup
media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
@@ -749,34 +749,48 @@ PeerConnectionImpl::Initialize(PeerConne
     return res;
   }
 
   return NS_OK;
 }
 
 class CompareCodecPriority {
   public:
-    explicit CompareCodecPriority(int32_t preferredCodec) {
+    void SetPreferredCodec(int32_t preferredCodec) {
       // This pref really ought to be a string, preferably something like
       // "H264" or "VP8" instead of a payload type.
       // Bug 1101259.
       std::ostringstream os;
       os << preferredCodec;
       mPreferredCodec = os.str();
     }
 
+    void AddHardwareCodec(const std::string& codec) {
+      mHardwareCodecs.insert(codec);
+    }
+
     bool operator()(JsepCodecDescription* lhs,
                     JsepCodecDescription* rhs) const {
-      return !mPreferredCodec.empty() &&
-             lhs->mDefaultPt == mPreferredCodec &&
-             rhs->mDefaultPt != mPreferredCodec;
+      if (!mPreferredCodec.empty() &&
+          lhs->mDefaultPt == mPreferredCodec &&
+          rhs->mDefaultPt != mPreferredCodec) {
+        return true;
+      }
+
+      if (mHardwareCodecs.count(lhs->mDefaultPt) &&
+          !mHardwareCodecs.count(rhs->mDefaultPt)) {
+        return true;
+      }
+
+      return false;
     }
 
   private:
     std::string mPreferredCodec;
+    std::set<std::string> mHardwareCodecs;
 };
 
 nsresult
 PeerConnectionImpl::ConfigureJsepSessionCodecs() {
   nsresult res;
   nsCOMPtr<nsIPrefService> prefs =
     do_GetService("@mozilla.org/preferences-service;1", &res);
 
@@ -830,17 +844,20 @@ PeerConnectionImpl::ConfigureJsepSession
   bool softwareH264Enabled = PeerConnectionCtx::GetInstance()->gmpHasH264();
 #else
   // For unit-tests
   bool softwareH264Enabled = true;
 #endif
 
   bool h264Enabled = hardwareH264Supported || softwareH264Enabled;
 
-  auto codecs = mJsepSession->Codecs();
+  auto& codecs = mJsepSession->Codecs();
+
+  // We use this to sort the list of codecs once everything is configured
+  CompareCodecPriority comparator;
 
   // Set parameters
   for (auto i = codecs.begin(); i != codecs.end(); ++i) {
     auto &codec = **i;
     switch (codec.mType) {
       case SdpMediaSection::kAudio:
         // Nothing to configure here, for now.
         break;
@@ -872,16 +889,20 @@ PeerConnectionImpl::ConfigureJsepSession
             // Might disable it, but we set up other params anyway
             videoCodec.mEnabled = h264Enabled;
 
             if (videoCodec.mPacketizationMode == 0 && !softwareH264Enabled) {
               // We're assuming packetization mode 0 is unsupported by
               // hardware.
               videoCodec.mEnabled = false;
             }
+
+            if (hardwareH264Supported) {
+              comparator.AddHardwareCodec(videoCodec.mDefaultPt);
+            }
           } else if (codec.mName == "VP8") {
             int32_t maxFs = 0;
             branch->GetIntPref("media.navigator.video.max_fs", &maxFs);
             if (maxFs <= 0) {
               maxFs = 12288; // We must specify something other than 0
             }
             videoCodec.mMaxFs = maxFs;
 
@@ -902,20 +923,21 @@ PeerConnectionImpl::ConfigureJsepSession
   }
 
   // Sort by priority
   int32_t preferredCodec = 0;
   branch->GetIntPref("media.navigator.video.preferred_codec",
                      &preferredCodec);
 
   if (preferredCodec) {
-    CompareCodecPriority comparator(preferredCodec);
-    std::stable_sort(codecs.begin(), codecs.end(), comparator);
+    comparator.SetPreferredCodec(preferredCodec);
   }
 
+  std::stable_sort(codecs.begin(), codecs.end(), comparator);
+
   return NS_OK;
 }
 
 RefPtr<DtlsIdentity> const
 PeerConnectionImpl::GetIdentity() const
 {
   PC_AUTO_ENTER_API_CALL_NO_CHECK();
   return mIdentity;