Changeset 201728 in webkit


Ignore:
Timestamp:
Jun 6, 2016 2:40:58 PM (8 years ago)
Author:
adam.bergkvist@ericsson.com
Message:

WebRTC: Update MediaEndpointPeerConnection::createOffer() to use the transceiver set
https://bugs.webkit.org/show_bug.cgi?id=158203

Reviewed by Eric Carlson.

Source/WebCore:

Create an SDP offer based on the RTCPeerConnection object's set of RTCRtpTransceiver objects
(instead of RTCRtpSender objects).

Updated existing test: fast/mediastream/RTCPeerConnection-inspect-offer.html

  • Modules/mediastream/MediaEndpointPeerConnection.cpp:

(WebCore::matchTransceiver):
(WebCore::matchTransceiverByMid):
(WebCore::MediaEndpointPeerConnection::createOfferTask):

  • Modules/mediastream/MediaEndpointPeerConnection.h:
  • Modules/mediastream/PeerConnectionBackend.h:

Remove getSenders() which is replaced by getTransceivers().

  • Modules/mediastream/RTCPeerConnection.h:
  • Modules/mediastream/SDPProcessor.cpp:

(WebCore::configurationFromJSON):
(WebCore::configurationToJSON):

  • Modules/mediastream/sdp.js:

(SDP.parse):
(SDP.generate):
Add support for mid attribute.

  • platform/mediastream/PeerMediaDescription.h:

(WebCore::PeerMediaDescription::mid):
(WebCore::PeerMediaDescription::setMid):
(WebCore::PeerMediaDescription::clone):

LayoutTests:

Updated existing test.

  • fast/mediastream/RTCPeerConnection-inspect-offer-expected.txt:
  • fast/mediastream/RTCPeerConnection-inspect-offer.html:

Add verification of mid attribute [1] (corresponds to the RTCRtpTransceiver mid attribute).
[1] https://tools.ietf.org/html/rfc5888

  • fast/mediastream/resources/sdp-utils.js: Added.

(printComparableSessionDescription):
(verified):
(match):
Move the printComparableSessionDescription function to a separate file
to make it usable in other (future) tests.

Location:
trunk
Files:
1 added
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r201727 r201728  
     12016-06-06  Adam Bergkvist  <adam.bergkvist@ericsson.com>
     2
     3        WebRTC: Update MediaEndpointPeerConnection::createOffer() to use the transceiver set
     4        https://bugs.webkit.org/show_bug.cgi?id=158203
     5
     6        Reviewed by Eric Carlson.
     7
     8        Updated existing test.
     9
     10        * fast/mediastream/RTCPeerConnection-inspect-offer-expected.txt:
     11        * fast/mediastream/RTCPeerConnection-inspect-offer.html:
     12        Add verification of mid attribute [1] (corresponds to the RTCRtpTransceiver mid attribute).
     13        [1] https://tools.ietf.org/html/rfc5888
     14        * fast/mediastream/resources/sdp-utils.js: Added.
     15        (printComparableSessionDescription):
     16        (verified):
     17        (match):
     18        Move the printComparableSessionDescription function to a separate file
     19        to make it usable in other (future) tests.
     20
    1212016-06-06  Antoine Quint  <graouts@apple.com>
    222
  • trunk/LayoutTests/fast/mediastream/RTCPeerConnection-inspect-offer-expected.txt

    r197702 r201728  
    1616a=rtcp-mux
    1717a=sendrecv
     18a=mid:{mid:OK}
    1819a=rtpmap:111 OPUS/48000/2
    1920a=rtpmap:8 PCMA/8000
     
    3940a=rtcp-mux
    4041a=sendrecv
     42a=mid:{mid:OK}
    4143a=rtpmap:111 OPUS/48000/2
    4244a=rtpmap:8 PCMA/8000
     
    5254a=rtcp-mux
    5355a=sendrecv
     56a=mid:{mid:OK}
    5457a=rtpmap:103 H264/90000
    5558a=rtpmap:100 VP8/90000
  • trunk/LayoutTests/fast/mediastream/RTCPeerConnection-inspect-offer.html

    r197702 r201728  
    33    <head>
    44        <script src="../../resources/js-test-pre.js"></script>
     5        <script src="./resources/sdp-utils.js"></script>
    56    </head>
    67    <body>
     
    5253            });
    5354
    54             // Variable fields (e.g. generated ids) are verified and replaced with predictable
    55             // lables. The result can be compared with a predefined expected output.
    56             function printComparableSessionDescription(sessionDescription, mdescVariables) {
    57                 debug("=== RTCSessionDescription ===");
    58                 debug("type: " + sessionDescription.type + ", sdp:");
    59 
    60                 var sdp = sessionDescription.sdp;
    61 
    62                 var regexp = {
    63                     "oline": "^o=(-) ([\\d]+) .*$",
    64                     "msidsemantic": "^a=msid-semantic: *WMS .*$",
    65                     "mline": "^m=.*$",
    66                     "cname": "^a=ssrc:(\\d+) cname:([\\w+/\\-@\\.\\{\\}]+).*$",
    67                     "msid": "^a=(ssrc:\\d+ )?msid:([\\w+/\\-=]+) +([\\w+/\\-=]+).*$",
    68                     "iceufrag": "^a=ice-ufrag:([\\w+/]*).*$",
    69                     "icepwd": "^a=ice-pwd:([\\w+/]*=*).*$",
    70                 };
    71 
    72                 var mdescIndex = -1;
    73                 sdp.split("\r\n").forEach(function (line) {
    74                     if (match(line, regexp.mline)) {
    75                         // Media block ("header" line)
    76                         mdescIndex++;
    77                     } else if (mdescIndex < 0) {
    78                         // Session block
    79                         var oline;
    80 
    81                         if (oline = match(line, regexp.oline))
    82                             line = line.replace(oline[2], verified("session-id"));
    83                         else if (match(line, regexp.msidsemantic)) {
    84                             mdescVariables.forEach(function (variables) {
    85                                 line = line.replace(variables.streamId, verified("media-stream-id"));
    86                             });
    87                         }
    88                     } else {
    89                         // Media block (content lines)
    90                         var cname;
    91                         var msid;
    92                         var iceufrag;
    93                         var icepwd;
    94 
    95                         if (cname = match(line, regexp.cname)) {
    96                             line = line.replace(cname[1], verified("ssrc"));
    97                             line = line.replace(cname[2], verified("cname"));
    98 
    99                         } else if (msid = match(line, regexp.msid)) {
    100                             if (msid[1])
    101                                 line = line.replace(msid[1], verified("ssrc"));
    102 
    103                             var variables = mdescVariables[mdescIndex];
    104 
    105                             var mediaStreamId = msid[2];
    106                             var streamIdVerified = verified("media-stream-id", mediaStreamId != variables.streamId);
    107                             line = line.replace(mediaStreamId, streamIdVerified);
    108 
    109                             var mediaStreamTrackId = msid[3];
    110                             var trackIdVerified = verified("media-stream-track-id", mediaStreamTrackId != variables.trackId);
    111                             line = line.replace(mediaStreamTrackId, trackIdVerified);
    112 
    113                         } else if (iceufrag = match(line, regexp.iceufrag))
    114                             line = line.replace(iceufrag[1], verified("ice-ufrag"));
    115                         else if (icepwd = match(line, regexp.icepwd))
    116                             line = line.replace(icepwd[1], verified("ice-password"));
    117                     }
    118 
    119                     if (line)
    120                         debug(line);
    121                 });
    122 
    123                 debug("===");
    124                 debug("");
    125             }
    126 
    127             function verified(name, isFailure) {
    128                 return "{" + name + ":" + (isFailure ? "FAILED" : "OK") + "}";
    129             }
    130 
    131             function match(data, pattern) {
    132                 return data.match(new RegExp(pattern));
    133             }
    134 
    13555            window.jsTestIsAsync = true;
    13656            window.successfullyParsed = true;
  • trunk/Source/WebCore/ChangeLog

    r201724 r201728  
     12016-06-06  Adam Bergkvist  <adam.bergkvist@ericsson.com>
     2
     3        WebRTC: Update MediaEndpointPeerConnection::createOffer() to use the transceiver set
     4        https://bugs.webkit.org/show_bug.cgi?id=158203
     5
     6        Reviewed by Eric Carlson.
     7
     8        Create an SDP offer based on the RTCPeerConnection object's set of RTCRtpTransceiver objects
     9        (instead of RTCRtpSender objects).
     10
     11        Updated existing test: fast/mediastream/RTCPeerConnection-inspect-offer.html
     12
     13        * Modules/mediastream/MediaEndpointPeerConnection.cpp:
     14        (WebCore::matchTransceiver):
     15        (WebCore::matchTransceiverByMid):
     16        (WebCore::MediaEndpointPeerConnection::createOfferTask):
     17        * Modules/mediastream/MediaEndpointPeerConnection.h:
     18        * Modules/mediastream/PeerConnectionBackend.h:
     19        Remove getSenders() which is replaced by getTransceivers().
     20        * Modules/mediastream/RTCPeerConnection.h:
     21        * Modules/mediastream/SDPProcessor.cpp:
     22        (WebCore::configurationFromJSON):
     23        (WebCore::configurationToJSON):
     24        * Modules/mediastream/sdp.js:
     25        (SDP.parse):
     26        (SDP.generate):
     27        Add support for mid attribute.
     28        * platform/mediastream/PeerMediaDescription.h:
     29        (WebCore::PeerMediaDescription::mid):
     30        (WebCore::PeerMediaDescription::setMid):
     31        (WebCore::PeerMediaDescription::clone):
     32
    1332016-06-06  George Ruan  <gruan@apple.com>
    234
  • trunk/Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.cpp

    r201673 r201728  
    4646
    4747using namespace PeerConnection;
     48using namespace PeerConnectionStates;
    4849
    4950static std::unique_ptr<PeerConnectionBackend> createMediaEndpointPeerConnection(PeerConnectionBackendClient* client)
     
    9697}
    9798
     99static RTCRtpTransceiver* matchTransceiver(const RtpTransceiverVector& transceivers, const std::function<bool(RTCRtpTransceiver&)>& matchFunction)
     100{
     101    for (auto& transceiver : transceivers) {
     102        if (matchFunction(*transceiver))
     103            return transceiver.get();
     104    }
     105    return nullptr;
     106}
     107
     108static RTCRtpTransceiver* matchTransceiverByMid(const RtpTransceiverVector& transceivers, const String& mid)
     109{
     110    return matchTransceiver(transceivers, [&mid] (RTCRtpTransceiver& current) {
     111        return current.mid() == mid;
     112    });
     113}
     114
    98115void MediaEndpointPeerConnection::runTask(NoncopyableFunction<void ()>&& task)
    99116{
     
    129146    ASSERT(!m_dtlsFingerprint.isEmpty());
    130147
     148    if (m_client->internalSignalingState() == SignalingState::Closed)
     149        return;
     150
    131151    RefPtr<MediaEndpointSessionConfiguration> configurationSnapshot = MediaEndpointSessionConfiguration::create();
    132152
    133     configurationSnapshot->setSessionVersion(m_sdpSessionVersion++);
    134 
    135     RtpSenderVector senders = RtpSenderVector(m_client->getSenders());
    136 
    137     // Add media descriptions for senders.
    138     for (auto& sender : senders) {
     153    configurationSnapshot->setSessionVersion(m_sdpOfferSessionVersion++);
     154
     155    auto transceivers = RtpTransceiverVector(m_client->getTransceivers());
     156
     157    // Remove any transceiver objects from transceivers that can be matched to an existing media description.
     158    for (auto& mediaDescription : configurationSnapshot->mediaDescriptions()) {
     159        if (!mediaDescription->port()) {
     160            // This media description should be recycled.
     161            continue;
     162        }
     163
     164        RTCRtpTransceiver* transceiver = matchTransceiverByMid(transceivers, mediaDescription->mid());
     165        if (!transceiver)
     166            continue;
     167
     168        mediaDescription->setMode(transceiver->directionString());
     169        if (transceiver->hasSendingDirection()) {
     170            RTCRtpSender& sender = *transceiver->sender();
     171
     172            mediaDescription->setMediaStreamId(sender.mediaStreamIds()[0]);
     173            mediaDescription->setMediaStreamTrackId(sender.trackId());
     174        }
     175
     176        transceivers.removeFirst(transceiver);
     177    }
     178
     179    // Add media descriptions for remaining transceivers.
     180    for (auto& transceiver : transceivers) {
    139181        RefPtr<PeerMediaDescription> mediaDescription = PeerMediaDescription::create();
    140         MediaStreamTrack& track = *sender->track();
    141 
    142         mediaDescription->setMediaStreamId(sender->mediaStreamIds()[0]);
    143         mediaDescription->setMediaStreamTrackId(track.id());
    144         mediaDescription->setType(track.kind());
    145         mediaDescription->setPayloads(track.kind() == "audio" ? m_defaultAudioPayloads : m_defaultVideoPayloads);
     182        RTCRtpSender& sender = *transceiver->sender();
     183
     184        mediaDescription->setMode(transceiver->directionString());
     185        mediaDescription->setMid(transceiver->provisionalMid());
     186        mediaDescription->setMediaStreamId(sender.mediaStreamIds()[0]);
     187        mediaDescription->setType(sender.trackKind());
     188        mediaDescription->setPayloads(sender.trackKind() == "audio" ? m_defaultAudioPayloads : m_defaultVideoPayloads);
    146189        mediaDescription->setDtlsFingerprintHashFunction(m_dtlsFingerprintFunction);
    147190        mediaDescription->setDtlsFingerprint(m_dtlsFingerprint);
     
    151194        mediaDescription->setIcePassword(m_icePassword);
    152195
     196        if (sender.track())
     197            mediaDescription->setMediaStreamTrackId(sender.trackId());
     198
    153199        configurationSnapshot->addMediaDescription(WTFMove(mediaDescription));
    154200    }
  • trunk/Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.h

    r201673 r201728  
    4747
    4848typedef Vector<RefPtr<RTCRtpSender>> RtpSenderVector;
     49typedef Vector<RefPtr<RTCRtpTransceiver>> RtpTransceiverVector;
    4950
    5051class MediaEndpointPeerConnection : public PeerConnectionBackend, public MediaEndpointClient {
     
    106107    String m_dtlsFingerprint;
    107108    String m_dtlsFingerprintFunction;
    108     unsigned m_sdpSessionVersion { 0 };
     109    unsigned m_sdpOfferSessionVersion { 0 };
    109110};
    110111
  • trunk/Source/WebCore/Modules/mediastream/PeerConnectionBackend.h

    r201601 r201728  
    6363public:
    6464    virtual const Vector<RefPtr<RTCRtpTransceiver>>& getTransceivers() const = 0;
    65     virtual const Vector<RefPtr<RTCRtpSender>>& getSenders() const = 0;
    6665    virtual void fireEvent(Event&) = 0;
    6766
  • trunk/Source/WebCore/Modules/mediastream/RTCPeerConnection.h

    r201601 r201728  
    6464    ~RTCPeerConnection();
    6565
    66     const Vector<RefPtr<RTCRtpSender>>& getSenders() const override { return m_transceiverSet->getSenders(); }
     66    const Vector<RefPtr<RTCRtpSender>>& getSenders() const { return m_transceiverSet->getSenders(); }
    6767    const Vector<RefPtr<RTCRtpReceiver>>& getReceivers() const { return m_transceiverSet->getReceivers(); }
    6868    const Vector<RefPtr<RTCRtpTransceiver>>& getTransceivers() const override { return m_transceiverSet->list(); }
  • trunk/Source/WebCore/Modules/mediastream/SDPProcessor.cpp

    r199619 r201728  
    7171STRING_FUNCTION(mediaStreamId)
    7272STRING_FUNCTION(mediaStreamTrackId)
     73STRING_FUNCTION(mid)
    7374STRING_FUNCTION(mode)
    7475STRING_FUNCTION(mux)
     
    212213            mediaDescription->setMode(stringValue);
    213214
     215        if (mediaDescriptionObject->getString(midString(), stringValue))
     216            mediaDescription->setMid(stringValue);
     217
    214218        RefPtr<InspectorArray> payloadsArray = InspectorArray::create();
    215219        mediaDescriptionObject->getArray(payloadsString(), payloadsArray);
     
    354358        mediaDescriptionObject->setString(addressString(), mediaDescription->address());
    355359        mediaDescriptionObject->setString(modeString(), mediaDescription->mode());
     360        mediaDescriptionObject->setString(midString(), mediaDescription->mid());
    356361
    357362        RefPtr<InspectorArray> payloadsArray = InspectorArray::create();
  • trunk/Source/WebCore/Modules/mediastream/sdp.js

    r197702 r201728  
    4141        "mblock": "^m=(audio|video|application) ([\\d]+) ([A-Z/]+)([\\d ]*)$\\r?\\n",
    4242        "mode": "^a=(sendrecv|sendonly|recvonly|inactive).*$",
     43        "mid": "^a=mid:([!#$%&'*+-.\\w]*).*$",
    4344        "rtpmap": "^a=rtpmap:${type} ([\\w\\-]+)/([\\d]+)/?([\\d]+)?.*$",
    44         "fmtp": "^a=fmtp:${type} ([\\w\\-=;]+).*$",
     45        "fmtp": "^a=fmtp:${type} ([\\w\\-=; ]+).*$",
    4546        "param": "([\\w\\-]+)=([\\w\\-]+);?",
    4647        "nack": "^a=rtcp-fb:${type} nack$",
     
    7879            "${rtcpMuxLine}" +
    7980            "a=${mode}\r\n" +
     81            "${midLine}" +
    8082            "${rtpMapLines}" +
    8183            "${fmtpLines}" +
     
    9496        "rtcp": "a=rtcp:${port}${[ ]netType}${[ ]addressType}${[ ]address}\r\n",
    9597        "rtcpMux": "a=rtcp-mux\r\n",
     98        "mid": "a=mid:${mid}\r\n",
    9699
    97100        "rtpMap": "a=rtpmap:${type} ${encodingName}/${clockRate}${[/]channels}\r\n",
     
    202205            if (mode)
    203206                mediaDescription.mode = mode[1];
     207
     208            var mid = match(mblock, regexps.mid, "m", sblock);
     209            if (mid)
     210                mediaDescription.mid = mid[1];
    204211
    205212            var payloadTypes = [];
     
    406413            var mblock = fillTemplate(templates.mblock, mediaDescription);
    407414
     415            var midInfo = {"midLine": ""};
     416            if (mediaDescription.mid)
     417                midInfo.midLine = fillTemplate(templates.mid, mediaDescription);
     418            mblock = fillTemplate(mblock, midInfo);
     419
    408420            var payloadInfo = {"rtpMapLines": "", "fmtpLines": "", "nackLines": "",
    409421                "nackpliLines": "", "ccmfirLines": "", "ericScreamLines": ""};
  • trunk/Source/WebCore/platform/mediastream/PeerMediaDescription.h

    r198492 r201728  
    6262    void setMode(const String& mode) { m_mode = mode; }
    6363
     64    const String& mid() const { return m_mid; }
     65    void setMid(const String& mid) { m_mid = mid; }
     66
    6467    const Vector<RefPtr<MediaPayload>>& payloads() const { return m_payloads; }
    6568    void addPayload(RefPtr<MediaPayload>&& payload) { m_payloads.append(WTFMove(payload)); }
     
    118121        copy->m_address = String(m_address);
    119122        copy->m_mode = String(m_mode);
     123        copy->m_mid = String(m_mid);
    120124
    121125        for (auto& payload : m_payloads)
     
    154158    String m_address { "0.0.0.0" };
    155159    String m_mode { "sendrecv" };
     160    String m_mid;
    156161
    157162    Vector<RefPtr<MediaPayload>> m_payloads;
Note: See TracChangeset for help on using the changeset viewer.