Bug 1022008: Support max-fs & max-fr in SDP for H.264; clean up video codec fmtp generation r=ehugg
authorRandell Jesup <rjesup@jesup.org>
Tue, 01 Jul 2014 04:19:32 -0400
changeset 191631 b5b7809e827217b419781cfb2bc5820d5718c00a
parent 191630 fc6859ffcd20163626d0f32f5681422421da0d33
child 191632 3dc373826e2a167498d06e2ad277b56ae80cc665
push id45629
push userrjesup@wgate.com
push dateTue, 01 Jul 2014 08:20:53 +0000
treeherdermozilla-inbound@b5b7809e8272 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehugg
bugs1022008
milestone33.0a1
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
Bug 1022008: Support max-fs & max-fr in SDP for H.264; clean up video codec fmtp generation r=ehugg
media/webrtc/signaling/src/media/VcmSIPCCBinding.cpp
media/webrtc/signaling/src/sipcc/core/gsm/gsm_sdp.c
media/webrtc/signaling/src/sipcc/include/vcm.h
media/webrtc/signaling/src/sipcc/stub/vcm_stub.c
--- a/media/webrtc/signaling/src/media/VcmSIPCCBinding.cpp
+++ b/media/webrtc/signaling/src/media/VcmSIPCCBinding.cpp
@@ -2798,16 +2798,27 @@ int vcmGetVideoCodecList(int request_typ
  */
 int vcmGetVideoMaxSupportedPacketizationMode()
 {
   // We support mode 1 packetization in webrtc
   return 1;
 }
 
 /**
+ * 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
+  return 0x42E00C;
+}
+
+/**
  *  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
  *
  *  @return  void
  *
@@ -3039,72 +3050,16 @@ cc_boolean vcmCheckAttribs(cc_uint32_t m
         return TRUE;
 
     default:
         return FALSE;
     }
 }
 
 /**
- * Add Video attributes in the offer/answer SDP
- *
- * This method is called for video codecs only. This method should populate the
- * Video SDP attributes using the SDP helper API
- *
- * @param [in] sdp_p - opaque SDP pointer to be used via SDP helper APIs
- * @param [in] level - Parameter to be used with SDP helper APIs
- * @param [in] media_type - codec for which the SDP attributes are to be populated
- * @param [in] payload_number - RTP payload type used for the SDP
- * @param [in] isOffer - cc_boolean indicating we are encoding an offer or an aswer
- *
- * @return void
- */
-void vcmPopulateAttribs(void *sdp_p, int level, cc_uint32_t media_type,
-                          cc_uint16_t payload_number, cc_boolean isOffer)
-{
-    CSFLogDebug( logTag, "vcmPopulateAttribs(): media=%d PT=%d, isOffer=%d", media_type, payload_number, isOffer);
-    uint16_t a_inst;//, a_inst2, a_inst3, a_inst4;
-    int profile;
-    char profile_level_id[MAX_SPROP_LEN];
-
-    switch (media_type)
-    {
-    case RTP_H264_P0:
-    case RTP_H264_P1:
-
-        if ( ccsdpAddNewAttr(sdp_p, level, 0, SDP_ATTR_FMTP, &a_inst) != SDP_SUCCESS ) return;
-
-        (void) ccsdpAttrSetFmtpPayloadType(sdp_p, level, 0, a_inst, payload_number);
-
-        if (media_type == RTP_H264_P1) {
-          (void) ccsdpAttrSetFmtpPackMode(sdp_p, level, 0, a_inst, 1 /*packetization_mode*/);
-        }
-        //(void) sdp_attr_set_fmtp_parameter_sets(sdp_p, level, 0, a_inst, "J0KAFJWgUH5A,KM4H8n==");    // NAL units 27 42 80 14 95 a0 50 7e 40 28 ce 07 f2
-
-        //profile = 0x42E000 + H264ToSDPLevel( vt_GetClientProfileLevel() );
-        profile = 0x42E00C;
-        csf_sprintf(profile_level_id, MAX_SPROP_LEN, "%X", profile);
-        (void) ccsdpAttrSetFmtpProfileLevelId(sdp_p, level, 0, a_inst, profile_level_id);
-
-        //(void) sdp_attr_set_fmtp_max_mbps(sdp_p, level, 0, a_inst, max_mbps);
-        //(void) sdp_attr_set_fmtp_max_fs(sdp_p, level, 0, a_inst, max_fs);
-        //(void) sdp_attr_set_fmtp_max_cpb(sdp_p, level, 0, a_inst, max_cpb);
-        //(void) sdp_attr_set_fmtp_max_dpb(sdp_p, level, 0, a_inst, max_dpb);
-        //(void) sdp_attr_set_fmtp_max_br(sdp_p, level, 0, a_inst, max_br);
-        //(void) sdp_add_new_bw_line(sdp_p, level, &a_inst);
-        //(void) sdp_set_bw(sdp_p, level, a_inst, SDP_BW_MODIFIER_TIAS, tias_bw);
-
-        break;
-
-    default:
-        break;
-    }
-}
-
-/**
  * Send a DTMF digit
  *
  * This method is called for sending a DTMF tone for the specified duration
  *
  * @param [in] digit - the DTMF digit that needs to be played out.
  * @param [in] duration - duration of the tone
  * @param [in] direction - direction in which the tone needs to be played.
  *
--- a/media/webrtc/signaling/src/sipcc/core/gsm/gsm_sdp.c
+++ b/media/webrtc/signaling/src/sipcc/core/gsm/gsm_sdp.c
@@ -1132,16 +1132,17 @@ gsmsdp_set_2543_hold_sdp (fsmdef_dcb_t *
  *                  RTP_AVT.
  *
  */
 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;
 
     switch (media_type) {
         case RTP_H263:
         case RTP_H264_P0:
         case RTP_H264_P1:
@@ -1165,53 +1166,83 @@ gsmsdp_set_video_media_attributes (uint3
                                              RTPMAP_VIDEO_CLOCKRATE);
             break;
         case RTP_H264_P0:
         case RTP_H264_P1:
             (void) sdp_attr_set_rtpmap_encname(sdp_p, level, 0, a_inst,
                                                SIPSDP_ATTR_ENCNAME_H264);
             (void) sdp_attr_set_rtpmap_clockrate(sdp_p, level, 0, a_inst,
                                              RTPMAP_VIDEO_CLOCKRATE);
+            // we know we haven't added it yet
+            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;
+            {
+                char buffer[32];
+                uint32_t profile_level_id = vcmGetVideoH264ProfileLevelID();
+                snprintf(buffer, sizeof(buffer), "0x%x", profile_level_id);
+                (void) sdp_attr_set_fmtp_profile_level_id(sdp_p, level, 0, a_inst,
+                                                          buffer);
+            }
+            if (media_type == RTP_H264_P1) {
+                (void) sdp_attr_set_fmtp_pack_mode(sdp_p, level, 0, a_inst,
+                                                   1);
+            }
+            // TODO: other parameters we may want/need to set for H.264
+        //(void) sdp_attr_set_fmtp_max_mbps(sdp_p, level, 0, a_inst, max_mbps);
+        //(void) sdp_attr_set_fmtp_max_fs(sdp_p, level, 0, a_inst, max_fs);
+        //(void) sdp_attr_set_fmtp_max_cpb(sdp_p, level, 0, a_inst, max_cpb);
+        //(void) sdp_attr_set_fmtp_max_dpb(sdp_p, level, 0, a_inst, max_dpb);
+        //(void) sdp_attr_set_fmtp_max_br(sdp_p, level, 0, a_inst, max_br);
+        //(void) sdp_add_new_bw_line(sdp_p, level, &a_inst);
+        //(void) sdp_set_bw(sdp_p, level, a_inst, SDP_BW_MODIFIER_TIAS, tias_bw);
             break;
         case RTP_VP8:
             (void) sdp_attr_set_rtpmap_encname(sdp_p, level, 0, a_inst,
                                                SIPSDP_ATTR_ENCNAME_VP8);
             (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:
+        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 (sdp_add_new_attr(sdp_p, level, 0, SDP_ATTR_FMTP, &a_inst)
-                    != SDP_SUCCESS) {
-                    GSM_ERR_MSG("Failed to add attribute");
-                    return;
+                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);
                 }
             }
-
             break;
         }
-    GSM_DEBUG("gsmsdp_set_video_media_attributes- populate attribs %d", payload_number );
-
-        vcmPopulateAttribs(cc_sdp_p, level, media_type, payload_number, FALSE);
-
         break;
 
         default:
             break;
     }
 }
 
 /*
--- a/media/webrtc/signaling/src/sipcc/include/vcm.h
+++ b/media/webrtc/signaling/src/sipcc/include/vcm.h
@@ -883,16 +883,22 @@ int vcmGetVideoCodecList(int request_typ
 /**
  * Get max supported H.264 video packetization mode.
  * @return maximum supported video packetization mode for H.264. Value returned
  * must be 0 or 1. Value 2 is not supported yet.
  */
 int vcmGetVideoMaxSupportedPacketizationMode();
 
 /**
+ * Get supported H.264 profile-level-id
+ * @return supported profile-level-id value
+ */
+uint32_t vcmGetVideoH264ProfileLevelID();
+
+/**
  * Get the rx/tx stream statistics associated with the call.
  * The rx/tx stats are defined as comma seperated string as follows.
  * Rx_stats:
  *   snprintf(rx_stats, CC_KFACTOR_STAT_LEN,
  *               "Dur=%d,Pkt=%d,Oct=%d,LatePkt=%d,LostPkt=%d,AvgJit=%d,VQMetrics=\"%s\"",
  *               duration, numberOfPackageReceived, numberOfByteReceived, numberOfLatePackage, numberOfPackageLost, averageJitter, qualityMatrics);
  * Tx_stats:
  *   snprintf(tx_stats, CC_KFACTOR_STAT_LEN, "Dur=%d,Pkt=%d,Oct=%d",
--- a/media/webrtc/signaling/src/sipcc/stub/vcm_stub.c
+++ b/media/webrtc/signaling/src/sipcc/stub/vcm_stub.c
@@ -486,38 +486,16 @@ void vcmSetRtcpDscp(cc_groupid_t group_i
  */
 
 boolean vcmCheckAttribs(uint32_t media_type, void *sdp_p, int level, void **rcapptr)
 {
     return TRUE;
 }
 
 /**
- * Add Video attributes in the offer/answer SDP
- *
- * This method is called for video codecs only. This method should populate the
- * Video SDP attributes using the SDP helper API
- *
- * @param [in] sdp_p - opaque SDP pointer to be used via SDP helper APIs
- * @param [in] level - Parameter to be used with SDP helper APIs
- * @param [in] media_type - codec for which the SDP attributes are to be populated
- * @param [in] payload_number - RTP payload type used for the SDP
- * @param [in] isOffer - boolean indicating we are encoding an offer or an aswer
- *
- * @return void
- */
-
-
-void vcmPopulateAttribs(void *sdp_p, int level, uint32_t media_type,
-                          uint16_t payload_number, boolean isOffer)
-{
-    return;
-}
-
-/**
  * Send a DTMF digit
  *
  * This method is called for sending a DTMF tone for the specified duration
  *
  * @param [in] digit - the DTMF digit that needs to be played out.
  * @param [in] duration - duration of the tone
  * @param [in] direction - direction in which the tone needs to be played.
  *