Bug 1137472: Basic VP9 signaling/pipeline/conduit support r=bwc
authorRandell Jesup <rjesup@jesup.org>
Tue, 03 Mar 2015 01:31:33 -0500
changeset 246943 942cffff9feaccdefcd52c50384052b0222f93ce
parent 246942 29c8632b348e9f0a55c76f28665228ec3e319026
child 246944 b429cedbba79ae6405bb0253e227438733d7ebce
push id884
push userdburns@mozilla.com
push dateTue, 03 Mar 2015 15:29:12 +0000
reviewersbwc
bugs1137472
milestone39.0a1
Bug 1137472: Basic VP9 signaling/pipeline/conduit support r=bwc
media/webrtc/signaling/src/jsep/JsepCodecDescription.h
media/webrtc/signaling/src/jsep/JsepSessionImpl.cpp
media/webrtc/signaling/src/media-conduit/VideoConduit.cpp
media/webrtc/signaling/src/peerconnection/MediaPipelineFactory.cpp
media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
media/webrtc/signaling/src/sdp/SdpAttribute.h
media/webrtc/signaling/src/sdp/SipccSdpAttributeList.cpp
media/webrtc/signaling/src/sdp/SipccSdpMediaSection.cpp
media/webrtc/signaling/src/sdp/sipcc/ccsdp.c
media/webrtc/signaling/src/sdp/sipcc/ccsdp.h
media/webrtc/signaling/src/sdp/sipcc/sdp_access.c
--- a/media/webrtc/signaling/src/jsep/JsepCodecDescription.h
+++ b/media/webrtc/signaling/src/jsep/JsepCodecDescription.h
@@ -286,17 +286,18 @@ struct JsepVideoCodecDescription : publi
       params->max_fs = mMaxFs;
       params->max_cpb = mMaxCpb;
       params->max_dpb = mMaxDpb;
       params->max_br = mMaxBr;
       strncpy(params->sprop_parameter_sets,
               mSpropParameterSets.c_str(),
               sizeof(params->sprop_parameter_sets) - 1);
       fmtp.PushEntry(mDefaultPt, "", mozilla::Move(params));
-    } else if (mName == "VP8") {
+    } else if (mName == "VP8" || mName == "VP9") {
+      // VP8 and VP9 share the same SDP parameters thus far
       UniquePtr<SdpFmtpAttributeList::VP8Parameters> params =
           MakeUnique<SdpFmtpAttributeList::VP8Parameters>();
 
       params->max_fs = mMaxFs;
       params->max_fr = mMaxFr;
       fmtp.PushEntry(mDefaultPt, "", mozilla::Move(params));
     }
   }
@@ -314,20 +315,21 @@ struct JsepVideoCodecDescription : publi
 
   virtual bool
   LoadFmtps(const SdpFmtpAttributeList::Parameters& params) MOZ_OVERRIDE
   {
     switch (params.codec_type) {
       case SdpRtpmapAttributeList::kH264:
         LoadH264Parameters(params);
         break;
+      case SdpRtpmapAttributeList::kVP9:
+        // VP8 and VP9 share the same SDP parameters thus far
       case SdpRtpmapAttributeList::kVP8:
         LoadVP8Parameters(params);
         break;
-      case SdpRtpmapAttributeList::kVP9:
       case SdpRtpmapAttributeList::kiLBC:
       case SdpRtpmapAttributeList::kiSAC:
       case SdpRtpmapAttributeList::kOpus:
       case SdpRtpmapAttributeList::kG722:
       case SdpRtpmapAttributeList::kPCMU:
       case SdpRtpmapAttributeList::kPCMA:
       case SdpRtpmapAttributeList::kOtherCodec:
         MOZ_ASSERT(false, "Invalid codec type for video");
--- a/media/webrtc/signaling/src/jsep/JsepSessionImpl.cpp
+++ b/media/webrtc/signaling/src/jsep/JsepSessionImpl.cpp
@@ -2343,16 +2343,26 @@ JsepSessionImpl::SetupDefaultCodecs()
       "VP8",
       90000
       );
   // Defaults for mandatory params
   vp8->mMaxFs = 12288;
   vp8->mMaxFr = 60;
   mCodecs.push_back(vp8);
 
+  JsepVideoCodecDescription* vp9 = new JsepVideoCodecDescription(
+      "121",
+      "VP9",
+      90000
+      );
+  // Defaults for mandatory params
+  vp9->mMaxFs = 12288;
+  vp9->mMaxFr = 60;
+  mCodecs.push_back(vp9);
+
   JsepVideoCodecDescription* h264_1 = new JsepVideoCodecDescription(
       "126",
       "H264",
       90000
       );
   h264_1->mPacketizationMode = 1;
   // Defaults for mandatory params
   h264_1->mProfileLevelId = 0x42E00D;
--- a/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp
+++ b/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp
@@ -1357,16 +1357,19 @@ WebrtcVideoConduit::CodecConfigToWebRTCC
   // to match parameters from VideoCodecConfig
   cinst.plType  = codecInfo->mType;
   if (codecInfo->mName == "H264") {
     cinst.codecType = webrtc::kVideoCodecH264;
     PL_strncpyz(cinst.plName, "H264", sizeof(cinst.plName));
   } else if (codecInfo->mName == "VP8") {
     cinst.codecType = webrtc::kVideoCodecVP8;
     PL_strncpyz(cinst.plName, "VP8", sizeof(cinst.plName));
+  } else if (codecInfo->mName == "VP9") {
+    cinst.codecType = webrtc::kVideoCodecVP9;
+    PL_strncpyz(cinst.plName, "VP9", sizeof(cinst.plName));
   } else if (codecInfo->mName == "I420") {
     cinst.codecType = webrtc::kVideoCodecI420;
     PL_strncpyz(cinst.plName, "I420", sizeof(cinst.plName));
   } else {
     cinst.codecType = webrtc::kVideoCodecUnknown;
     PL_strncpyz(cinst.plName, "Unknown", sizeof(cinst.plName));
   }
 
--- a/media/webrtc/signaling/src/peerconnection/MediaPipelineFactory.cpp
+++ b/media/webrtc/signaling/src/peerconnection/MediaPipelineFactory.cpp
@@ -780,17 +780,17 @@ MediaPipelineFactory::GetOrCreateVideoCo
 /*
  * Add external H.264 video codec.
  */
 MediaConduitErrorCode
 MediaPipelineFactory::EnsureExternalCodec(VideoSessionConduit& aConduit,
                                           VideoCodecConfig* aConfig,
                                           bool aIsSend)
 {
-  if (aConfig->mName == "VP8") {
+  if (aConfig->mName == "VP8" || aConfig->mName == "VP9") {
     return kMediaConduitNoError;
   } else if (aConfig->mName == "H264") {
     // Register H.264 codec.
     if (aIsSend) {
       VideoEncoder* encoder = nullptr;
 #ifdef MOZ_WEBRTC_OMX
       encoder =
           OMXVideoCodec::CreateEncoder(OMXVideoCodec::CodecType::CODEC_H264);
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
@@ -898,16 +898,20 @@ PeerConnectionImpl::ConfigureJsepSession
   bool softwareH264Enabled = PeerConnectionCtx::GetInstance()->gmpHasH264();
 #else
   // For unit-tests
   bool softwareH264Enabled = true;
 #endif
 
   bool h264Enabled = hardwareH264Supported || softwareH264Enabled;
 
+  bool vp9Enabled = false;
+  branch->GetBoolPref("media.peerconnection.video.vp9_enabled",
+                      &vp9Enabled);
+  
   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;
@@ -947,30 +951,35 @@ PeerConnectionImpl::ConfigureJsepSession
               // We're assuming packetization mode 0 is unsupported by
               // hardware.
               videoCodec.mEnabled = false;
             }
 
             if (hardwareH264Supported) {
               comparator.AddHardwareCodec(videoCodec.mDefaultPt);
             }
-          } else if (codec.mName == "VP8") {
+          } else if (codec.mName == "VP8" || codec.mName == "VP9") {
+            if (videoCodec.mName == "VP9" && !vp9Enabled) {
+              videoCodec.mEnabled = false;
+              break;
+            }
             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;
 
             int32_t maxFr = 0;
             branch->GetIntPref("media.navigator.video.max_fr", &maxFr);
             if (maxFr <= 0) {
               maxFr = 60; // We must specify something other than 0
             }
             videoCodec.mMaxFr = maxFr;
+
           }
         }
         break;
       case SdpMediaSection::kText:
       case SdpMediaSection::kApplication:
       case SdpMediaSection::kMessage:
         {} // Nothing to configure for these.
     }
--- a/media/webrtc/signaling/src/sdp/SdpAttribute.h
+++ b/media/webrtc/signaling/src/sdp/SdpAttribute.h
@@ -1009,16 +1009,17 @@ public:
     unsigned int profile_level_id;
     unsigned int max_mbps;
     unsigned int max_fs;
     unsigned int max_cpb;
     unsigned int max_dpb;
     unsigned int max_br;
   };
 
+  // Also used for VP9 since they share parameters
   class VP8Parameters : public Parameters
   {
   public:
     VP8Parameters()
         : Parameters(SdpRtpmapAttributeList::kVP8), max_fs(0), max_fr(0)
     {
     }
 
--- a/media/webrtc/signaling/src/sdp/SipccSdpAttributeList.cpp
+++ b/media/webrtc/signaling/src/sdp/SipccSdpAttributeList.cpp
@@ -354,16 +354,18 @@ SipccSdpAttributeList::GetCodecType(rtp_
       return SdpRtpmapAttributeList::kG722;
     case RTP_H264_P0:
     case RTP_H264_P1:
       return SdpRtpmapAttributeList::kH264;
     case RTP_OPUS:
       return SdpRtpmapAttributeList::kOpus;
     case RTP_VP8:
       return SdpRtpmapAttributeList::kVP8;
+    case RTP_VP9:
+      return SdpRtpmapAttributeList::kVP9;
     case RTP_NONE:
     // Happens when sipcc doesn't know how to translate to the enum
     case RTP_CELP:
     case RTP_G726:
     case RTP_GSM:
     case RTP_G723:
     case RTP_DVI4:
     case RTP_DVI4_II:
@@ -640,16 +642,17 @@ SipccSdpAttributeList::LoadFmtp(sdp_t* s
         h264Parameters->max_mbps = fmtp->max_mbps;
         h264Parameters->max_fs = fmtp->max_fs;
         h264Parameters->max_cpb = fmtp->max_cpb;
         h264Parameters->max_dpb = fmtp->max_dpb;
         h264Parameters->max_br = fmtp->max_br;
 
         parameters.reset(h264Parameters);
       } break;
+      case RTP_VP9:
       case RTP_VP8: {
         SdpFmtpAttributeList::VP8Parameters* vp8Parameters(
             new SdpFmtpAttributeList::VP8Parameters);
 
         vp8Parameters->max_fs = fmtp->max_fs;
         vp8Parameters->max_fr = fmtp->max_fr;
 
         parameters.reset(vp8Parameters);
--- a/media/webrtc/signaling/src/sdp/SipccSdpMediaSection.cpp
+++ b/media/webrtc/signaling/src/sdp/SipccSdpMediaSection.cpp
@@ -277,16 +277,18 @@ SipccSdpMediaSection::AddCodec(const std
   } else if (name == "G722") {
     codec = SdpRtpmapAttributeList::kG722;
   } else if (name == "PCMU") {
     codec = SdpRtpmapAttributeList::kPCMU;
   } else if (name == "PCMA") {
     codec = SdpRtpmapAttributeList::kPCMA;
   } else if (name == "VP8") {
     codec = SdpRtpmapAttributeList::kVP8;
+  } else if (name == "VP9") {
+    codec = SdpRtpmapAttributeList::kVP9;
   } else if (name == "H264") {
     codec = SdpRtpmapAttributeList::kH264;
   }
 
   rtpmap->PushEntry(pt, codec, name, clockrate, channels);
   mAttributeList.SetAttribute(rtpmap);
 }
 
--- a/media/webrtc/signaling/src/sdp/sipcc/ccsdp.c
+++ b/media/webrtc/signaling/src/sdp/sipcc/ccsdp.c
@@ -321,14 +321,15 @@ const char * ccsdpCodecName(rtp_ptype pt
     case RTP_H264_P0:    return "H264_P0";
     case RTP_H264_P1:    return "H264_P1";
     case RTP_AVT:        return "AVT";
     case RTP_L16:        return "L16";
     case RTP_H263:       return "H263";
     case RTP_ILBC:       return "iLBC";
     case RTP_OPUS:       return "OPUS";
     case RTP_VP8:        return "VP8";
+    case RTP_VP9:        return "VP9";
     case RTP_I420:       return "I420";
     /* case RTP_ISAC:       return "ISAC"; */
   }
   return "UNKNOWN";
 }
 
--- a/media/webrtc/signaling/src/sdp/sipcc/ccsdp.h
+++ b/media/webrtc/signaling/src/sdp/sipcc/ccsdp.h
@@ -75,16 +75,17 @@ typedef enum rtp_ptype_
     RTP_H264_P0      = 97,
     RTP_H264_P1      = 126,
     RTP_AVT          = 101,
     RTP_L16          = 102,
     RTP_H263         = 103,
     RTP_ILBC         = 116, /* used only to make an offer */
     RTP_OPUS         = 109,
     RTP_VP8          = 120,
+    RTP_VP9          = 121,
     RTP_I420         = 124,
     RTP_ISAC         = 124
 } rtp_ptype;
 
 /**
  * IANA-registered static payload types for the RTP/AVP profile.
  * See http://www.iana.org/assignments/rtp-parameters/rtp-parameters.xml
  */
--- a/media/webrtc/signaling/src/sdp/sipcc/sdp_access.c
+++ b/media/webrtc/signaling/src/sdp/sipcc/sdp_access.c
@@ -20,16 +20,17 @@ static const char* logTag = "sdp_access"
 #define SIPSDP_ATTR_ENCNAME_G728      "G728"
 #define SIPSDP_ATTR_ENCNAME_GSM       "GSM"
 #define SIPSDP_ATTR_ENCNAME_CN        "CN"
 #define SIPSDP_ATTR_ENCNAME_G722      "G722"
 #define SIPSDP_ATTR_ENCNAME_ILBC      "iLBC"
 #define SIPSDP_ATTR_ENCNAME_H263v2    "H263-1998"
 #define SIPSDP_ATTR_ENCNAME_H264      "H264"
 #define SIPSDP_ATTR_ENCNAME_VP8       "VP8"
+#define SIPSDP_ATTR_ENCNAME_VP9       "VP9"
 #define SIPSDP_ATTR_ENCNAME_L16_256K  "L16"
 #define SIPSDP_ATTR_ENCNAME_ISAC      "ISAC"
 #define SIPSDP_ATTR_ENCNAME_OPUS      "opus"
 
 /* Function:    sdp_find_media_level
  * Description: Find and return a pointer to the specified media level,
  *              if it exists.
  *              Note: This is not an API for the application but an internal
@@ -1793,16 +1794,19 @@ rtp_ptype sdp_get_known_payload_type(voi
             } else {
               return (RTP_H264_P1);
             }
           }
         }
         if (cpr_strcasecmp(encname, SIPSDP_ATTR_ENCNAME_VP8) == 0) {
           return (RTP_VP8);
         }
+        if (cpr_strcasecmp(encname, SIPSDP_ATTR_ENCNAME_VP9) == 0) {
+          return (RTP_VP9);
+        }
       }
     }
   }
 
   return (RTP_NONE);
 }
 
 /* Function:    sdp_get_media_payload_type