Bug 1043515 - Add max-br and max-mbps H.264 SDP fmtp parameters; update supported h264 level. r=ehugg, a=lmandel
authorRandell Jesup <rjesup@jesup.org>
Sun, 27 Jul 2014 19:59:46 -0400
changeset 216238 fafb35ae78924b1102ead13ef8f575244e9a7361
parent 216237 3cb4eb9b4d3a65ff1a9d496851050ecf3ba89e25
child 216239 f7a26b0d0de524c8e80a5b6f90d58369bfaa1230
push id3857
push userraliiev@mozilla.com
push dateTue, 02 Sep 2014 16:39:23 +0000
treeherdermozilla-beta@5638b907b505 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehugg, lmandel
bugs1043515
milestone33.0a2
Bug 1043515 - Add max-br and max-mbps H.264 SDP fmtp parameters; update supported h264 level. r=ehugg, a=lmandel
media/webrtc/signaling/src/media/VcmSIPCCBinding.cpp
media/webrtc/signaling/src/sipcc/core/common/prot_configmgr.c
media/webrtc/signaling/src/sipcc/core/common/prot_configmgr.h
media/webrtc/signaling/src/sipcc/core/gsm/gsm_sdp.c
media/webrtc/signaling/src/sipcc/include/vcm.h
modules/libpref/src/init/all.js
--- a/media/webrtc/signaling/src/media/VcmSIPCCBinding.cpp
+++ b/media/webrtc/signaling/src/media/VcmSIPCCBinding.cpp
@@ -2868,17 +2868,24 @@ int vcmGetH264SupportedPacketizationMode
 /**
  * Get supported H.264 profile-level-id
  * @return supported profile-level-id value
  */
 uint32_t vcmGetVideoH264ProfileLevelID()
 {
   // constrained baseline level 1.2
   // XXX make variable based on openh264 and OMX support
+#ifdef MOZ_WEBRTC_OMX
+  // Max resolution CIF; we should include max-mbps
   return 0x42E00C;
+#else
+  // XXX See bug 1043515 - we may want to support a higher profile than
+  // 1.3, depending on hardware(?)
+  return 0x42E00D;
+#endif
 }
 
 /**
  *  MEDIA control received from far end on signaling path
  *
  *  @param call_handle - call_handle of the call
  *  @param to_encoder - the control request received
  *        Only FAST_PICTURE_UPDATE is supported
@@ -3363,51 +3370,76 @@ int vcmDisableRtcpComponent(const char *
   mozilla::SyncRunnable::DispatchToThread(VcmSIPCCBinding::getMainThread(),
       WrapRunnableNMRet(&vcmDisableRtcpComponent_m,
                         peerconnection,
                         level,
                         &ret));
   return ret;
 }
 
-static short vcmGetVideoMaxFs_m(uint16_t codec,
-                                int32_t *max_fs) {
+static short vcmGetVideoPref_m(uint16_t codec,
+                               const char *pref,
+                               int32_t *ret) {
   nsCOMPtr<nsIPrefBranch> branch = VcmSIPCCBinding::getPrefBranch();
-  if (branch && NS_SUCCEEDED(branch->GetIntPref("media.navigator.video.max_fs",
-                                                max_fs))) {
+  if (branch && NS_SUCCEEDED(branch->GetIntPref(pref, ret))) {
     return 0;
   }
   return VCM_ERROR;
 }
 
 short vcmGetVideoMaxFs(uint16_t codec,
                        int32_t *max_fs) {
   short ret;
 
   mozilla::SyncRunnable::DispatchToThread(VcmSIPCCBinding::getMainThread(),
-      WrapRunnableNMRet(&vcmGetVideoMaxFs_m,
+      WrapRunnableNMRet(&vcmGetVideoPref_m,
                         codec,
+                        "media.navigator.video.max_fs",
                         max_fs,
                         &ret));
   return ret;
 }
 
-static short vcmGetVideoMaxFr_m(uint16_t codec,
-                                int32_t *max_fr) {
-  nsCOMPtr<nsIPrefBranch> branch = VcmSIPCCBinding::getPrefBranch();
-  if (branch && NS_SUCCEEDED(branch->GetIntPref("media.navigator.video.max_fr",
-                                                max_fr))) {
-    return 0;
-  }
-  return VCM_ERROR;
-}
-
 short vcmGetVideoMaxFr(uint16_t codec,
                        int32_t *max_fr) {
   short ret;
 
   mozilla::SyncRunnable::DispatchToThread(VcmSIPCCBinding::getMainThread(),
-      WrapRunnableNMRet(&vcmGetVideoMaxFr_m,
+      WrapRunnableNMRet(&vcmGetVideoPref_m,
                         codec,
+                        "media.navigator.video.max_fr",
                         max_fr,
                         &ret));
   return ret;
 }
+
+short vcmGetVideoMaxBr(uint16_t codec,
+                       int32_t *max_br) {
+  short ret;
+
+  mozilla::SyncRunnable::DispatchToThread(VcmSIPCCBinding::getMainThread(),
+      WrapRunnableNMRet(&vcmGetVideoPref_m,
+                        codec,
+                        "media.navigator.video.h264.max_br",
+                        max_br,
+                        &ret));
+  return ret;
+}
+
+short vcmGetVideoMaxMbps(uint16_t codec,
+                       int32_t *max_mbps) {
+  short ret;
+
+  mozilla::SyncRunnable::DispatchToThread(VcmSIPCCBinding::getMainThread(),
+      WrapRunnableNMRet(&vcmGetVideoPref_m,
+                        codec,
+                        "media.navigator.video.h264.max_mbps",
+                        max_mbps,
+                        &ret));
+  if (ret == VCM_ERROR) {
+#ifdef MOZ_WEBRTC_OMX
+    // Level 1.2; but let's allow CIF@30 or QVGA@30+ by default
+    *max_mbps = 11880;
+    ret = 0;
+#endif
+  }
+  return ret;
+}
--- a/media/webrtc/signaling/src/sipcc/core/common/prot_configmgr.c
+++ b/media/webrtc/signaling/src/sipcc/core/common/prot_configmgr.c
@@ -588,16 +588,38 @@ config_get_video_max_fr(const rtp_ptype 
   uint32_t max_fr;
 
   if(vcmGetVideoMaxFr(codec, (int32_t *) &max_fr) == 0) {
     return max_fr;
   }
   return 0;
 }
 
+uint32_t
+config_get_video_max_mbps(const rtp_ptype codec)
+{
+  uint32_t max_mbps;
+
+  if(vcmGetVideoMaxMbps(codec, (int32_t *) &max_mbps) == 0) {
+    return max_mbps;
+  }
+  return 0;
+}
+
+uint32_t
+config_get_video_max_br(const rtp_ptype codec)
+{
+  uint32_t max_br;
+
+  if(vcmGetVideoMaxBr(codec, (int32_t *) &max_br) == 0) {
+    return max_br;
+  }
+  return 0;
+}
+
 uint16_t
 sip_config_video_add_codecs (rtp_ptype aSupportedCodecs[],
                              uint16_t supportedCodecsLen,
                              uint16_t codec_mask)
 {
   uint16_t count = 0;
 
   // All things being equal, prefer VP8 > H.264 p1 > H.264 p0 -> H.263
--- a/media/webrtc/signaling/src/sipcc/core/common/prot_configmgr.h
+++ b/media/webrtc/signaling/src/sipcc/core/common/prot_configmgr.h
@@ -289,10 +289,12 @@ line_t sip_config_local_line_get(void);
 void sip_config_get_display_name(line_t line, char *buffer, int buffer_len);
 line_t sip_config_get_line_by_called_number(line_t start_line, const char *called_number);
 int sip_minimum_config_check(void);
 void config_set_codec_table(int codec_mask);
 int sip_config_get_keepalive_expires();
 rtp_ptype sip_config_preferred_codec(void);
 uint32_t config_get_video_max_fs(const rtp_ptype codec);
 uint32_t config_get_video_max_fr(const rtp_ptype codec);
+uint32_t config_get_video_max_mbps(const rtp_ptype codec);
+uint32_t config_get_video_max_br(const rtp_ptype codec);
 
 #endif /* PROT_CONFIGMGR_H_ */
--- a/media/webrtc/signaling/src/sipcc/core/gsm/gsm_sdp.c
+++ b/media/webrtc/signaling/src/sipcc/core/gsm/gsm_sdp.c
@@ -1136,16 +1136,18 @@ static void
 gsmsdp_set_video_media_attributes (uint32_t media_type, void *cc_sdp_p, uint16_t level,
                              uint16_t payload_number)
 {
     uint16_t a_inst;
     int added_fmtp = 0;
     void *sdp_p = ((cc_sdp_t*)cc_sdp_p)->src_sdp;
     int max_fs = 0;
     int max_fr = 0;
+    int max_br = 0;
+    int max_mbps = 0;
 
     switch (media_type) {
         case RTP_H263:
         case RTP_H264_P0:
         case RTP_H264_P1:
         case RTP_VP8:
         /*
          * add a=rtpmap line
@@ -1206,42 +1208,52 @@ gsmsdp_set_video_media_attributes (uint3
             (void) sdp_attr_set_rtpmap_clockrate(sdp_p, level, 0, a_inst,
                                              RTPMAP_VIDEO_CLOCKRATE);
             break;
         }
 
         switch (media_type) {
         case RTP_H264_P0:
         case RTP_H264_P1:
+            max_br = config_get_video_max_br((rtp_ptype) media_type); // H264 only
+            max_mbps = config_get_video_max_mbps((rtp_ptype) media_type); // H264 only
+            // fall through
         case RTP_VP8:
             max_fs = config_get_video_max_fs((rtp_ptype) media_type);
             max_fr = config_get_video_max_fr((rtp_ptype) media_type);
 
-            if (max_fs || max_fr) {
+            if (max_fs || max_fr || max_br || max_mbps) {
                 if (!added_fmtp) {
                     if (sdp_add_new_attr(sdp_p, level, 0, SDP_ATTR_FMTP, &a_inst)
                         != SDP_SUCCESS) {
                         GSM_ERR_MSG("Failed to add attribute");
                         return;
                     }
                     added_fmtp = 1;
 
                     (void) sdp_attr_set_fmtp_payload_type(sdp_p, level, 0, a_inst,
                                                           payload_number);
                 }
 
                 if (max_fs) {
                     (void) sdp_attr_set_fmtp_max_fs(sdp_p, level, 0, a_inst,
                                                     max_fs);
                 }
-
                 if (max_fr) {
                     (void) sdp_attr_set_fmtp_max_fr(sdp_p, level, 0, a_inst,
                                                     max_fr);
                 }
+                if (max_br) {
+                    (void) sdp_attr_set_fmtp_max_br(sdp_p, level, 0, a_inst,
+                                                    max_br);
+                }
+                if (max_mbps) {
+                    (void) sdp_attr_set_fmtp_max_mbps(sdp_p, level, 0, a_inst,
+                                                      max_mbps);
+                }
             }
             break;
         }
         break;
 
         default:
             break;
     }
--- a/media/webrtc/signaling/src/sipcc/include/vcm.h
+++ b/media/webrtc/signaling/src/sipcc/include/vcm.h
@@ -1080,17 +1080,21 @@ int vcmOnSdpParseError(const char *peerc
  *
  * If we are doing rtcp-mux we need to disable component number 2 in the ICE
  * layer.  Otherwise we will wait for it to connect when it is unused
  */
 int vcmDisableRtcpComponent(const char *peerconnection, int level);
 
 short vcmGetVideoMaxFs(uint16_t codec, int32_t *max_fs);
 
-short vcmGetVideoMaxFr(uint16_t codec, int32_t *max_fs);
+short vcmGetVideoMaxFr(uint16_t codec, int32_t *max_fr);
+
+short vcmGetVideoMaxBr(uint16_t codec, int32_t *max_br);
+
+short vcmGetVideoMaxMbps(uint16_t codec, int32_t *max_mbps);
 
 //Using C++ for gips. This is the end of extern "C" above.
 #ifdef __cplusplus
 }
 #endif
 
 
 
--- a/modules/libpref/src/init/all.js
+++ b/modules/libpref/src/init/all.js
@@ -290,25 +290,29 @@ pref("media.webrtc.debug.aec_dump_max_si
 
 #ifdef MOZ_WIDGET_GONK
 pref("media.navigator.video.default_width",320);
 pref("media.navigator.video.default_height",240);
 pref("media.peerconnection.enabled", true);
 pref("media.peerconnection.video.enabled", true);
 pref("media.navigator.video.max_fs", 1200); // 640x480 == 1200mb
 pref("media.navigator.video.max_fr", 30);
+pref("media.navigator.video.h264.max_br", 700); // 8x10
+pref("media.navigator.video.h264.max_mbps", 11880); // CIF@30fps
 pref("media.peerconnection.video.h264_enabled", false);
 pref("media.getusermedia.aec", 4);
 #else
 pref("media.navigator.video.default_width",0);  // adaptive default
 pref("media.navigator.video.default_height",0); // adaptive default
 pref("media.peerconnection.enabled", true);
 pref("media.peerconnection.video.enabled", true);
 pref("media.navigator.video.max_fs", 0); // unrestricted
 pref("media.navigator.video.max_fr", 0); // unrestricted
+pref("media.navigator.video.h264.max_br", 0);
+pref("media.navigator.video.h264.max_mbps", 0);
 pref("media.peerconnection.video.h264_enabled", false);
 pref("media.getusermedia.aec", 1);
 #endif
 pref("media.peerconnection.video.min_bitrate", 200);
 pref("media.peerconnection.video.start_bitrate", 300);
 pref("media.peerconnection.video.max_bitrate", 2000);
 pref("media.navigator.permission.disabled", false);
 pref("media.peerconnection.default_iceservers", "[{\"url\": \"stun:stun.services.mozilla.com\"}]");